[MIParser] Set RegClassOrRegBank during instruction parsing
[llvm-complete.git] / test / CodeGen / AArch64 / framelayout-sve.mir
blob452ae94e24565b0871e81ac04071b1ca397ca766
1 # RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass=prologepilog %s -o - | FileCheck %s
3 # Test allocation and deallocation of SVE objects on the stack,
4 # as well as using a combination of scalable and non-scalable
5 # offsets to access the SVE on the stack.
7 # SVE objects are allocated below the (scalar) callee saves,
8 # and above spills/locals and the alignment gap, e.g.
10 #     +-------------+
11 #     | stack arg   |
12 #     +-------------+ <- SP before call
13 #     | Callee Saves|
14 #     | Frame record|       (if available)
15 #     |-------------| <- FP (if available)
16 #     |  SVE area   |
17 #     +-------------+
18 #     |/////////////| alignment gap.
19 #     |     :       |
20 #     | Stack objs  |
21 #     |     :       |
22 #     +-------------+ <- SP after call and frame-setup
24 --- |
26   define void @test_allocate_sve() nounwind { entry: unreachable }
27   define void @test_allocate_sve_gpr_callee_saves() nounwind { entry: unreachable }
28   define void @test_allocate_sve_gpr_realigned() nounwind { entry: unreachable }
29   define void @test_address_sve() nounwind { entry: unreachable }
30   define void @test_address_sve_fp() nounwind { entry: unreachable }
31   define void @test_stack_arg_sve() nounwind { entry: unreachable }
32   define void @test_address_sve_out_of_range() nounwind { entry: unreachable }
34 ...
35 # +----------+
36 # |scratchreg|  // x29 is used as scratch reg.
37 # +----------+
38 # | %fixed-  |  // scalable SVE object of n * 18 bytes, aligned to 16 bytes,
39 # |  stack.0 |  // to be materialized with 2*ADDVL (<=> 2 * n * 16bytes)
40 # +----------+
41 # | %stack.0 |  // not scalable
42 # +----------+ <- SP
44 # CHECK-LABEL: name: test_allocate_sve
45 # CHECK:       stackSize: 32
47 # CHECK:      bb.0.entry:
48 # CHECK-NEXT: $sp = frame-setup STRXpre killed $[[SCRATCH:[a-z0-9]+]], $sp, -16
49 # CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -2
50 # CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0
52 # CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 2
53 # CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 16, 0
54 # CHECK-NEXT: $sp, $[[SCRATCH]] = frame-destroy LDRXpost $sp, 16
55 # CHECK-NEXT: RET_ReallyLR
56 name:            test_allocate_sve
57 fixedStack:
58   - { id: 0, stack-id: sve-vec, size: 18, alignment: 2, offset: -18 }
59 stack:
60   - { id: 0, stack-id: default, size: 16, alignment: 8 }
61 body:             |
62   bb.0.entry:
63     RET_ReallyLR
64 ---
65 ...
66 # +----------+
67 # | x20, x21 |  // callee saves
68 # |scratchreg|  // x29 is used as scratch reg.
69 # +----------+
70 # | %fixed-  |  // scalable objects
71 # |  stack.0 |
72 # +----------+
73 # | %stack.0 |  // not scalable
74 # +----------+ <- SP
76 # CHECK-LABEL: name: test_allocate_sve_gpr_callee_saves
77 # CHECK:       stackSize: 48
79 # CHECK:      bb.0.entry:
80 # CHECK-NEXT: $sp = frame-setup STRXpre killed $[[SCRATCH:[a-z0-9]+]], $sp, -32
81 # CHECK-NEXT: frame-setup STPXi killed $x21, killed $x20, $sp, 2
82 # CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -2
83 # CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0
84 # CHECK-NEXT: $x20 = IMPLICIT_DEF
85 # CHECK-NEXT: $x21 = IMPLICIT_DEF
86 # CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 2
87 # CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 16, 0
88 # CHECK-NEXT: $x21, $x20 = frame-destroy LDPXi $sp, 2
89 # CHECK-NEXT: $sp, $[[SCRATCH]] = frame-destroy LDRXpost $sp, 32
90 # CHECK-NEXT: RET_ReallyLR
91 name:            test_allocate_sve_gpr_callee_saves
92 fixedStack:
93   - { id: 0, stack-id: sve-vec, size: 18, alignment: 2, offset: -18 }
94 stack:
95   - { id: 0, stack-id: default, size: 16, alignment: 8 }
96 body:             |
97   bb.0.entry:
98     $x20 = IMPLICIT_DEF
99     $x21 = IMPLICIT_DEF
100     RET_ReallyLR
103 # +----------+
104 # |  lr, fp  |  // frame record
105 # +----------+ <- FP
106 # | %fixed-  |  // scalable objects
107 # |  stack.0 |
108 # +----------+
109 # |//////////|  // alignment gap
110 # | %stack.0 |  // not scalable
111 # +----------+ <- SP
112 # CHECK-LABEL: name: test_allocate_sve_gpr_realigned
113 # CHECK:       stackSize: 32
115 # CHECK:      bb.0.entry:
116 # CHECK-NEXT: $sp = frame-setup STPXpre killed $fp, killed $lr, $sp, -2
117 # CHECK-NEXT: $fp = frame-setup ADDXri $sp, 0, 0
118 # CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -2
119 # CHECK-NEXT: $[[TMP:x[0-9]+]] = frame-setup SUBXri $sp, 16, 0
120 # CHECK-NEXT: $sp = ANDXri killed $[[TMP]]
121 # CHECK-NEXT: $sp = frame-destroy ADDXri $fp, 0, 0
122 # CHECK-NEXT: $sp, $fp, $lr = frame-destroy LDPXpost $sp, 2
123 # CHECK-NEXT: RET_ReallyLR
124 name:            test_allocate_sve_gpr_realigned
125 fixedStack:
126   - { id: 0, stack-id: sve-vec, size: 18, alignment: 2, offset: -18 }
127 stack:
128   - { id: 0, stack-id: default, size: 16, alignment: 32 }
129 body:             |
130   bb.0.entry:
131     RET_ReallyLR
134 # +----------+
135 # | x20, x21 |  // callee saves
136 # +----------+
137 # | %stack.0 |  // scalable @ SP + 16b + 32 scalable bytes
138 # | %stack.1 |  // scalable @ SP + 16b + 16 scalable bytes
139 # | %stack.2 |  // scalable @ SP + 16b + 14 scalable bytes
140 # +----------+
141 # | %stack.0 |  // not scalable
142 # +----------+ <- SP
144 # CHECK-LABEL: name: test_address_sve
145 # CHECK:       stackSize: 32
147 # CHECK:      bb.0.entry:
148 # CHECK-NEXT: $sp = frame-setup STRXpre killed $[[SCRATCH:[a-z0-9]+]], $sp, -16
149 # CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -3
150 # CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0
152 # CHECK-NEXT: $[[TMP:x[0-9]+]] = ADDXri $sp, 16
153 # CHECK-NEXT: STR_ZXI $z0, killed $[[TMP]], 2
154 # CHECK-NEXT: $[[TMP:x[0-9]+]] = ADDXri $sp, 16
155 # CHECK-NEXT: STR_ZXI $z1, killed $[[TMP]], 1
156 # CHECK-NEXT: $[[TMP:x[0-9]+]] = ADDXri $sp, 16
157 # CHECK-NEXT: STR_PXI $p0, killed $[[TMP]], 7
159 # CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 3
160 # CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 16, 0
161 # CHECK-NEXT: $sp, $[[SCRATCH]] = frame-destroy LDRXpost $sp, 16
162 # CHECK-NEXT: RET_ReallyLR
163 name:            test_address_sve
164 frameInfo:
165   maxAlignment:  16
166 fixedStack:
167   - { id: 0, stack-id: sve-vec, size: 16, alignment: 8, offset: -16 }
168   - { id: 1, stack-id: sve-vec, size: 16, alignment: 8, offset: -32 }
169   - { id: 2, stack-id: sve-vec, size:  2, alignment: 2, offset: -34 }
170 stack:
171   - { id: 0, stack-id: default, size: 16, alignment: 8 }
172 body:             |
173   bb.0.entry:
174     liveins: $z0, $z1, $p0
176     STR_ZXI $z0, %fixed-stack.0, 0
177     STR_ZXI $z1, %fixed-stack.1, 0
178     STR_PXI $p0, %fixed-stack.2, 0
180     RET_ReallyLR
183 # +-----------+
184 # | x20, x21  |  // callee saves
185 # |  lr, fp   |  // frame record
186 # +-----------+ <- FP
187 # | %fstack.0 |  // scalable @ FP - 16 scalable bytes
188 # | %fstack.1 |  // scalable @ FP - 32 scalable bytes
189 # | %fstack.2 |  // scalable @ FP - 34 scalable bytes
190 # +-----------+
191 # | %stack.0  |  // not scalable
192 # +-----------+ <- SP
194 # CHECK-LABEL: name: test_address_sve_fp
195 # CHECK:       stackSize: 32
197 # CHECK:      bb.0.entry:
198 # CHECK-NEXT: $sp = frame-setup STPXpre killed $fp, killed $lr, $sp, -2
199 # CHECK-NEXT: $fp = frame-setup ADDXri $sp, 0, 0
200 # CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -3
201 # CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0
203 # CHECK-NEXT: STR_ZXI $z0, $fp, -1
204 # CHECK-NEXT: STR_ZXI $z1, $fp, -2
205 # CHECK-NEXT: STR_PXI $p0, $fp, -17
207 # CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 3
208 # CHECK:      $sp = frame-destroy ADDXri $sp, 16, 0
209 # CHECK-NEXT: $sp, $fp, $lr = frame-destroy LDPXpost $sp, 2
210 # CHECK-NEXT: RET_ReallyLR
211 name:            test_address_sve_fp
212 frameInfo:
213   maxAlignment:  16
214   isFrameAddressTaken: true
215 fixedStack:
216   - { id: 0, stack-id: sve-vec, size: 16, alignment: 8, offset: -16 }
217   - { id: 1, stack-id: sve-vec, size: 16, alignment: 8, offset: -32 }
218   - { id: 2, stack-id: sve-vec, size:  2, alignment: 2, offset: -34 }
219 stack:
220   - { id: 0, stack-id: default, size: 16, alignment: 8 }
221 body:             |
222   bb.0.entry:
223     liveins: $z0, $z1, $p0
225     STR_ZXI $z0, %fixed-stack.0, 0
226     STR_ZXI $z1, %fixed-stack.1, 0
227     STR_PXI $p0, %fixed-stack.2, 0
229     RET_ReallyLR
232 # +-----------+
233 # | %fstack.1 |  // stack arg @ SP + 16 scalable bytes + 32 bytes.
234 # +-----------+
235 # |callee save|  // register saved as scratch reg.
236 # +-----------+
237 # | %fstack.1 |  // vector of 16 scalable bytes
238 # +---------- +
239 # | %stack.0  |  // not scalable, 16 bytes
240 # +-----------+ <- SP
241 # CHECK-LABEL: name: test_stack_arg_sve
242 # CHECK:       stackSize: 32
244 # CHECK:      bb.0.entry:
245 # CHECK-NEXT: $sp = frame-setup STRXpre killed $[[SCRATCH:[a-z0-9]+]], $sp, -16
246 # CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -1
247 # CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0
249 # CHECK:      $[[TMP:x[0-9]+]] = ADDVL_XXI $sp, 1
250 # CHECK-NEXT: $x0 = LDRXui killed $[[TMP]], 4
252 # CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 1
253 # CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 16, 0
254 # CHECK-NEXT: $sp, $[[SCRATCH]] = frame-destroy LDRXpost $sp, 16
255 # CHECK-NEXT: RET_ReallyLR
256 name:             test_stack_arg_sve
257 fixedStack:
258   - { id: 0, stack-id: default, size: 16, alignment: 16, offset: 0 }
259   - { id: 1, stack-id: sve-vec, size: 16, alignment: 16, offset: -16 }
260 stack:
261   - { id: 0, stack-id: default, size: 16, alignment: 16 }
262 body:             |
263   bb.0.entry:
264     liveins: $x0
266     $x0 = LDRXui %fixed-stack.0, 0
267     RET_ReallyLR
270 # Test that the address to access an SVE data vector at an offset that
271 # does not fit its immediate, is correctly materialized.
272 # +----------+
273 # |calleesave|  // register saved as scratch reg.
274 # +----------+
275 # | %stack.0 |  // one SVE data object @ SP + 256 scalable bytes.
276 # |::::::::::|
277 # |:        :|
278 # |:%stack.1:|  // Large object
279 # |:        :|
280 # |::::::::::|
281 # +----------+ <- SP
282 # CHECK-LABEL: name: test_address_sve_out_of_range
283 # CHECK:       stackSize: 16
285 # CHECK:      bb.0.entry:
286 # CHECK-NEXT: $sp = frame-setup STRXpre killed $[[SCRATCH:[a-z0-9]+]], $sp, -16
287 # CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32
288 # CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32
289 # CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32
290 # CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32
291 # CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32
292 # CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32
293 # CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32
294 # CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32
295 # CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -1
297 # CHECK-NEXT: $[[TMP2:x[0-9]+]] = ADDVL_XXI $sp, 1
298 # CHECK-NEXT: STR_ZXI $z0, killed $[[TMP2]], 255
300 # CHECK-NEXT: $[[TMP2:x[0-9]+]] = ADDPL_XXI $sp, 1
301 # CHECK-NEXT: STR_PXI $p0, killed $[[TMP2]], 255
303 # CHECK:      $sp = frame-destroy ADDVL_XXI $sp, 31
304 # CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 31
305 # CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 31
306 # CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 31
307 # CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 31
308 # CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 31
309 # CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 31
310 # CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 31
311 # CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 9
312 # CHECK-NEXT: $sp, $[[SCRATCH]] = frame-destroy LDRXpost $sp, 16
313 # CHECK-NEXT: RET_ReallyLR
314 name:            test_address_sve_out_of_range
315 frameInfo:
316   maxAlignment:  16
317 fixedStack:
318   - { id: 0, stack-id: sve-vec, size:   16, alignment: 16, offset: -16 }
319   - { id: 1, stack-id: sve-vec, size: 3584, alignment: 16, offset: -3600 }
320   - { id: 2, stack-id: sve-vec, size:  512, alignment: 16, offset: -4112 }
322 body:             |
323   bb.0.entry:
324     liveins: $z0, $p0
326     STR_ZXI $z0, %fixed-stack.0, 0
327     STR_PXI $p0, %fixed-stack.1, 0
329     RET_ReallyLR