254 lines · plain
1# RUN: llc -mtriple=aarch64-linux-gnu -run-pass=prologepilog %s -o - | FileCheck %s2 3# The tests below test the allocation of 128bit callee-saves4# on the stack, specifically their offsets.5 6# Padding of GPR64-registers is needed to ensure 16 byte alignment of7# the stack pointer after the GPR64/FPR64 block (which is also needed8# for the FPR128 saves when present).9 10# This file also tests whether an emergency stack slot is allocated11# when the stack frame is over a given size, caused by a series of12# FPR128 saves. The alignment can leave a gap that can be scavenged13# for stack slot scavenging, so it is important that the stack size14# is properly estimated.15 16 17--- |18 19 ; ModuleID = '<stdin>'20 source_filename = "<stdin>"21 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"22 target triple = "aarch64-unknown-linux-gnu"23 24 ; Function Attrs: nounwind25 define aarch64_vector_pcs void @test_q10_q11_x19() nounwind { entry: unreachable }26 27 ; Function Attrs: nounwind28 define aarch64_vector_pcs void @test_q10_q11_x19_x20() nounwind { entry: unreachable }29 30 ; Function Attrs: nounwind31 define aarch64_vector_pcs void @test_q10_q11_x19_x20_x21() nounwind { entry: unreachable }32 33 ; Function Attrs: nounwind34 define aarch64_vector_pcs void @test_q8_to_q23_x19_to_x30() nounwind { entry: unreachable }35 36 ; Function Attrs: nounwind37 define aarch64_vector_pcs void @test_q8_to_q23_x19_to_x30_preinc() nounwind { entry: unreachable }38 39...40---41name: test_q10_q11_x1942tracksRegLiveness: true43body: |44 bb.0.entry:45 $x19 = IMPLICIT_DEF46 $q10 = IMPLICIT_DEF47 $q11 = IMPLICIT_DEF48 49 ; Check that the alignment gap for the 8-byte x19 is padded50 ; with another 8 bytes. The CSR region will look like this:51 ; +-------------------+52 ; |/////padding///////| (8 bytes)53 ; | X19 | (8 bytes)54 ; +-------------------+ <- SP -1655 ; | Q10, Q11 | (32 bytes)56 ; +-------------------+ <- SP -4857 58 ; CHECK-LABEL: test_q10_q11_x19{{[[:space:]]}}59 ; CHECK-DAG: $sp = frame-setup STPQpre killed $q11, killed $q10, $sp, -3 :: (store (s128) into %stack.[[Q11:[0-9]+]]), (store (s128) into %stack.[[Q10:[0-9]+]])60 ; CHECK-DAG: - { id: [[Q11]], {{.*}}, offset: -48, size: 16, alignment: 1661 ; CHECK-DAG: - { id: [[Q10]], {{.*}}, offset: -32, size: 16, alignment: 1662 ; CHECK-DAG: frame-setup STRXui killed $x19, $sp, 4 :: (store (s64) into %stack.[[X19:[0-9]+]])63 ; CHECK-DAG: - { id: [[X19]], {{.*}}, offset: -16, size: 8, alignment: 1664 65...66---67name: test_q10_q11_x19_x2068alignment: 469tracksRegLiveness: true70body: |71 bb.0.entry:72 $x19 = IMPLICIT_DEF73 $x20 = IMPLICIT_DEF74 $q10 = IMPLICIT_DEF75 $q11 = IMPLICIT_DEF76 77 ; +-------------------+78 ; | X19, X20 | (16 bytes)79 ; +-------------------+ <- SP -1680 ; | Q10, Q11 | (32 bytes)81 ; +-------------------+ <- SP -4882 83 ; CHECK-LABEL: test_q10_q11_x19_x20{{[[:space:]]}}84 ; CHECK-DAG: $sp = frame-setup STPQpre killed $q11, killed $q10, $sp, -3 :: (store (s128) into %stack.[[Q11:[0-9]+]]), (store (s128) into %stack.[[Q10:[0-9]+]])85 ; CHECK-DAG: frame-setup STPXi killed $x20, killed $x19, $sp, 4 :: (store (s64) into %stack.[[X20:[0-9]+]]), (store (s64) into %stack.[[X19:[0-9]+]])86 ; CHECK-DAG: - { id: [[Q11]], {{.*}}, offset: -48, size: 16, alignment: 1687 ; CHECK-DAG: - { id: [[Q10]], {{.*}}, offset: -32, size: 16, alignment: 1688 ; CHECK-DAG: - { id: [[X20]], {{.*}}, offset: -16, size: 8, alignment: 889 ; CHECK-DAG: - { id: [[X19]], {{.*}}, offset: -8, size: 8, alignment: 890 91...92---93name: test_q10_q11_x19_x20_x2194tracksRegLiveness: true95body: |96 bb.0.entry:97 $x19 = IMPLICIT_DEF98 $x20 = IMPLICIT_DEF99 $x21 = IMPLICIT_DEF100 $q10 = IMPLICIT_DEF101 $q11 = IMPLICIT_DEF102 103 ; Check that the alignment gap is padded with another 8 bytes.104 ; The CSR region will look like this:105 ; +-------------------+106 ; | X19, X20 | (16 bytes)107 ; +-------------------+ <- SP -16108 ; |/////padding///////| (8 bytes)109 ; | X21 | (8 bytes)110 ; +-------------------+ <- SP -32111 ; | Q10, Q11 | (32 bytes)112 ; +-------------------+ <- SP -64113 114 ; CHECK-LABEL: test_q10_q11_x19_x20_x21115 ; CHECK-DAG: $sp = frame-setup STPQpre killed $q11, killed $q10, $sp, -4 :: (store (s128) into %stack.[[Q11:[0-9]+]]), (store (s128) into %stack.[[Q10:[0-9]+]])116 ; CHECK-DAG: frame-setup STRXui killed $x21, $sp, 4 :: (store (s64) into %stack.[[X21:[0-9]+]])117 ; CHECK-DAG: frame-setup STPXi killed $x20, killed $x19, $sp, 6118 ; CHECK-DAG: - { id: [[Q11]], {{.*}}, offset: -64, size: 16, alignment: 16119 ; CHECK-DAG: - { id: [[Q10]], {{.*}}, offset: -48, size: 16, alignment: 16120 ; CHECK-DAG: - { id: [[X21]], {{.*}}, offset: -32, size: 8, alignment: 16121 122...123---124name: test_q8_to_q23_x19_to_x30125tracksRegLiveness: true126body: |127 bb.0.entry:128 $x19 = IMPLICIT_DEF129 $x20 = IMPLICIT_DEF130 $x21 = IMPLICIT_DEF131 $x22 = IMPLICIT_DEF132 $x23 = IMPLICIT_DEF133 $x24 = IMPLICIT_DEF134 $x25 = IMPLICIT_DEF135 $x26 = IMPLICIT_DEF136 $x27 = IMPLICIT_DEF137 $x28 = IMPLICIT_DEF138 $fp = IMPLICIT_DEF139 $lr = IMPLICIT_DEF140 $q8 = IMPLICIT_DEF141 $q9 = IMPLICIT_DEF142 $q10 = IMPLICIT_DEF143 $q11 = IMPLICIT_DEF144 $q12 = IMPLICIT_DEF145 $q13 = IMPLICIT_DEF146 $q14 = IMPLICIT_DEF147 $q15 = IMPLICIT_DEF148 $q16 = IMPLICIT_DEF149 $q17 = IMPLICIT_DEF150 $q18 = IMPLICIT_DEF151 $q19 = IMPLICIT_DEF152 $q20 = IMPLICIT_DEF153 $q21 = IMPLICIT_DEF154 $q22 = IMPLICIT_DEF155 $q23 = IMPLICIT_DEF156 157 ; Test with more callee saves, which triggers 'BigStack' in158 ; AArch64FrameLowering which in turn causes an emergency spill159 ; slot to be allocated. The emergency spill slot is allocated160 ; as close as possible to SP, so at SP + 0.161 ; +-------------------+162 ; | X19..X30 | (96 bytes)163 ; +-------------------+ <- SP -96164 ; | Q8..Q23 | (256 bytes)165 ; +-------------------+ <- SP -352166 ; | emergency slot | (16 bytes)167 ; +-------------------+ <- SP -368168 169 ; CHECK-LABEL: test_q8_to_q23_x19_to_x30170 ; CHECK: $sp = frame-setup SUBXri $sp, 368, 0171 ; CHECK-NEXT: frame-setup STPQi killed $q23, killed $q22, $sp, 1 :: (store (s128) into %stack.{{[0-9]+}}), (store (s128) into %stack.{{[0-9]+}})172 ; CHECK-NEXT: frame-setup STPQi killed $q21, killed $q20, $sp, 3173 ; CHECK-NEXT: frame-setup STPQi killed $q19, killed $q18, $sp, 5174 ; CHECK-NEXT: frame-setup STPQi killed $q17, killed $q16, $sp, 7175 ; CHECK-NEXT: frame-setup STPQi killed $q15, killed $q14, $sp, 9176 ; CHECK-NEXT: frame-setup STPQi killed $q13, killed $q12, $sp, 11177 ; CHECK-NEXT: frame-setup STPQi killed $q11, killed $q10, $sp, 13178 ; CHECK-NEXT: frame-setup STPQi killed $q9, killed $q8, $sp, 15179 ; CHECK-NEXT: frame-setup STPXi killed $fp, killed $lr, $sp, 34 :: (store (s64) into %stack.{{[0-9]+}}), (store (s64) into %stack.{{[0-9]+}})180 ; CHECK-NEXT: frame-setup STPXi killed $x28, killed $x27, $sp, 36181 ; CHECK-NEXT: frame-setup STPXi killed $x26, killed $x25, $sp, 38182 ; CHECK-NEXT: frame-setup STPXi killed $x24, killed $x23, $sp, 40183 ; CHECK-NEXT: frame-setup STPXi killed $x22, killed $x21, $sp, 42184 ; CHECK-NEXT: frame-setup STPXi killed $x20, killed $x19, $sp, 44185 186...187---188name: test_q8_to_q23_x19_to_x30_preinc189tracksRegLiveness: true190stack:191 - { id: 0, size: 160, alignment: 4, local-offset: 0 }192constants:193body: |194 bb.0.entry:195 $x19 = IMPLICIT_DEF196 $x20 = IMPLICIT_DEF197 $x21 = IMPLICIT_DEF198 $x22 = IMPLICIT_DEF199 $x23 = IMPLICIT_DEF200 $x24 = IMPLICIT_DEF201 $x25 = IMPLICIT_DEF202 $x26 = IMPLICIT_DEF203 $x27 = IMPLICIT_DEF204 $x28 = IMPLICIT_DEF205 $fp = IMPLICIT_DEF206 $lr = IMPLICIT_DEF207 $q8 = IMPLICIT_DEF208 $q9 = IMPLICIT_DEF209 $q10 = IMPLICIT_DEF210 $q11 = IMPLICIT_DEF211 $q12 = IMPLICIT_DEF212 $q13 = IMPLICIT_DEF213 $q14 = IMPLICIT_DEF214 $q15 = IMPLICIT_DEF215 $q16 = IMPLICIT_DEF216 $q17 = IMPLICIT_DEF217 $q18 = IMPLICIT_DEF218 $q19 = IMPLICIT_DEF219 $q20 = IMPLICIT_DEF220 $q21 = IMPLICIT_DEF221 $q22 = IMPLICIT_DEF222 $q23 = IMPLICIT_DEF223 224 ; When the total stack size >= 512, it will use the pre-increment225 ; rather than the 'sub sp, sp, <size>'.226 ; +-------------------+227 ; | X19..X30 | (96 bytes)228 ; +-------------------+ <- SP -96229 ; | Q8..Q23 | (256 bytes)230 ; +-------------------+ <- SP -352231 ; | 'obj' | (32 bytes)232 ; +-------------------+ <- SP -384233 ; | emergency slot | (16 bytes)234 ; +-------------------+ <- SP -400235 236 ; CHECK-LABEL: test_q8_to_q23_x19_to_x30_preinc237 ; CHECK: $sp = frame-setup STPQpre killed $q23, killed $q22, $sp, -22 :: (store (s128) into %stack.{{[0-9]+}}), (store (s128) into %stack.{{[0-9]+}})238 ; CHECK-NEXT: frame-setup STPQi killed $q21, killed $q20, $sp, 2239 ; CHECK-NEXT: frame-setup STPQi killed $q19, killed $q18, $sp, 4240 ; CHECK-NEXT: frame-setup STPQi killed $q17, killed $q16, $sp, 6241 ; CHECK-NEXT: frame-setup STPQi killed $q15, killed $q14, $sp, 8242 ; CHECK-NEXT: frame-setup STPQi killed $q13, killed $q12, $sp, 10243 ; CHECK-NEXT: frame-setup STPQi killed $q11, killed $q10, $sp, 12244 ; CHECK-NEXT: frame-setup STPQi killed $q9, killed $q8, $sp, 14245 ; CHECK-NEXT: frame-setup STPXi killed $fp, killed $lr, $sp, 32 :: (store (s64) into %stack.{{[0-9]+}}), (store (s64) into %stack.{{[0-9]+}})246 ; CHECK-NEXT: frame-setup STPXi killed $x28, killed $x27, $sp, 34247 ; CHECK-NEXT: frame-setup STPXi killed $x26, killed $x25, $sp, 36248 ; CHECK-NEXT: frame-setup STPXi killed $x24, killed $x23, $sp, 38249 ; CHECK-NEXT: frame-setup STPXi killed $x22, killed $x21, $sp, 40250 ; CHECK-NEXT: frame-setup STPXi killed $x20, killed $x19, $sp, 42251 ; CHECK-NEXT: $sp = frame-setup SUBXri $sp, 176, 0252 253...254