[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / GlobalISel / load-wro-addressing-modes.mir
blob6a4b1248e7a4cf4ac0a4743a8940a5a069c9a9bf
1 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2 # RUN: llc -mtriple=aarch64-unknown-unknown -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
3 ...
4 ---
5 name:            shl_gep_sext_ldrwrow
6 alignment:       4
7 legalized:       true
8 regBankSelected: true
9 tracksRegLiveness: true
10 frameInfo:
11   maxAlignment:    1
12 machineFunctionInfo: {}
13 body:             |
14   bb.0:
15     liveins: $w1, $x0
17     ; We should be able to fold a shift + extend into the pattern.
18     ; In this case, we should get a roW load with two 1s, representing a shift
19     ; plus sign extend.
21     ; CHECK-LABEL: name: shl_gep_sext_ldrwrow
22     ; CHECK: liveins: $w1, $x0
23     ; CHECK: %base:gpr64sp = COPY $x0
24     ; CHECK: %foo:gpr32 = COPY $w1
25     ; CHECK: %load:gpr32 = LDRWroW %base, %foo, 1, 1 :: (load (s32))
26     ; CHECK: $w0 = COPY %load
27     ; CHECK: RET_ReallyLR implicit $w0
28     %base:gpr(p0) = COPY $x0
29     %foo:gpr(s32) = COPY $w1
30     %ext:gpr(s64) = G_SEXT %foo(s32)
31     %c:gpr(s64) = G_CONSTANT i64 2
32     %offset:gpr(s64) = G_SHL %ext, %c
33     %ptr:gpr(p0) = G_PTR_ADD %base, %offset(s64)
34     %load:gpr(s32) = G_LOAD %ptr(p0) :: (load (s32))
35     $w0 = COPY %load(s32)
36     RET_ReallyLR implicit $w0
37 ...
38 ---
39 name:            shl_gep_zext_ldrwrow
40 alignment:       4
41 legalized:       true
42 regBankSelected: true
43 tracksRegLiveness: true
44 frameInfo:
45   maxAlignment:    1
46 machineFunctionInfo: {}
47 body:             |
48   bb.0:
49     liveins: $w1, $x0
51     ; We should be able to fold a shift + extend into the pattern.
52     ; In this case, we should get a roW load with a 0 representing a zero-extend
53     ; and a 1 representing a shift.
55     ; CHECK-LABEL: name: shl_gep_zext_ldrwrow
56     ; CHECK: liveins: $w1, $x0
57     ; CHECK: %base:gpr64sp = COPY $x0
58     ; CHECK: %foo:gpr32 = COPY $w1
59     ; CHECK: %load:gpr32 = LDRWroW %base, %foo, 0, 1 :: (load (s32))
60     ; CHECK: $w0 = COPY %load
61     ; CHECK: RET_ReallyLR implicit $w0
62     %base:gpr(p0) = COPY $x0
63     %foo:gpr(s32) = COPY $w1
64     %ext:gpr(s64) = G_ZEXT %foo(s32)
65     %c:gpr(s64) = G_CONSTANT i64 2
66     %offset:gpr(s64) = G_SHL %ext, %c
67     %ptr:gpr(p0) = G_PTR_ADD %base, %offset(s64)
68     %load:gpr(s32) = G_LOAD %ptr(p0) :: (load (s32))
69     $w0 = COPY %load(s32)
70     RET_ReallyLR implicit $w0
71 ...
72 ---
73 name:            shl_gep_anyext_ldrwrow
74 alignment:       4
75 legalized:       true
76 regBankSelected: true
77 tracksRegLiveness: true
78 frameInfo:
79   maxAlignment:    1
80 machineFunctionInfo: {}
81 body:             |
82   bb.0:
83     liveins: $w1, $x0
85     ; We should be able to fold a shift + extend into the pattern.
86     ; In this case, we should get a roW load with a 0 representing a zero-extend
87     ; and a 1 representing a shift.
89     ; CHECK-LABEL: name: shl_gep_anyext_ldrwrow
90     ; CHECK: liveins: $w1, $x0
91     ; CHECK: %base:gpr64sp = COPY $x0
92     ; CHECK: %foo:gpr32 = COPY $w1
93     ; CHECK: %load:gpr32 = LDRWroW %base, %foo, 0, 1 :: (load (s32))
94     ; CHECK: $w0 = COPY %load
95     ; CHECK: RET_ReallyLR implicit $w0
96     %base:gpr(p0) = COPY $x0
97     %foo:gpr(s32) = COPY $w1
98     %ext:gpr(s64) = G_ANYEXT %foo(s32)
99     %c:gpr(s64) = G_CONSTANT i64 2
100     %offset:gpr(s64) = G_SHL %ext, %c
101     %ptr:gpr(p0) = G_PTR_ADD %base, %offset(s64)
102     %load:gpr(s32) = G_LOAD %ptr(p0) :: (load (s32))
103     $w0 = COPY %load(s32)
104     RET_ReallyLR implicit $w0
107 name:            mul_gep_sext_ldrwrow
108 alignment:       4
109 legalized:       true
110 regBankSelected: true
111 tracksRegLiveness: true
112 frameInfo:
113   maxAlignment:    1
114 machineFunctionInfo: {}
115 body:             |
116   bb.0:
118     ; We should be able to do the same with multiplies as with shifts.
120     liveins: $w1, $x0
121     ; CHECK-LABEL: name: mul_gep_sext_ldrwrow
122     ; CHECK: liveins: $w1, $x0
123     ; CHECK: %base:gpr64sp = COPY $x0
124     ; CHECK: %foo:gpr32 = COPY $w1
125     ; CHECK: %load:gpr32 = LDRWroW %base, %foo, 1, 1 :: (load (s32))
126     ; CHECK: $w0 = COPY %load
127     ; CHECK: RET_ReallyLR implicit $w0
128     %base:gpr(p0) = COPY $x0
129     %foo:gpr(s32) = COPY $w1
130     %ext:gpr(s64) = G_SEXT %foo(s32)
131     %c:gpr(s64) = G_CONSTANT i64 4
132     %offset:gpr(s64) = G_MUL %c, %ext
133     %ptr:gpr(p0) = G_PTR_ADD %base, %offset(s64)
134     %load:gpr(s32) = G_LOAD %ptr(p0) :: (load (s32))
135     $w0 = COPY %load(s32)
136     RET_ReallyLR implicit $w0
139 name:            mul_gep_zext_ldrwrow
140 alignment:       4
141 legalized:       true
142 regBankSelected: true
143 tracksRegLiveness: true
144 frameInfo:
145   maxAlignment:    1
146 machineFunctionInfo: {}
147 body:             |
148   bb.0:
149     liveins: $w1, $x0
151     ; We should be able to do the same with multiplies as with shifts.
153     ; CHECK-LABEL: name: mul_gep_zext_ldrwrow
154     ; CHECK: liveins: $w1, $x0
155     ; CHECK: %base:gpr64sp = COPY $x0
156     ; CHECK: %foo:gpr32 = COPY $w1
157     ; CHECK: %load:gpr32 = LDRWroW %base, %foo, 0, 1 :: (load (s32))
158     ; CHECK: $w0 = COPY %load
159     ; CHECK: RET_ReallyLR implicit $w0
160     %base:gpr(p0) = COPY $x0
161     %foo:gpr(s32) = COPY $w1
162     %ext:gpr(s64) = G_ZEXT %foo(s32)
163     %c:gpr(s64) = G_CONSTANT i64 4
164     %offset:gpr(s64) = G_MUL %c, %ext
165     %ptr:gpr(p0) = G_PTR_ADD %base, %offset(s64)
166     %load:gpr(s32) = G_LOAD %ptr(p0) :: (load (s32))
167     $w0 = COPY %load(s32)
168     RET_ReallyLR implicit $w0
171 name:            mul_gep_anyext_ldrwrow
172 alignment:       4
173 legalized:       true
174 regBankSelected: true
175 tracksRegLiveness: true
176 frameInfo:
177   maxAlignment:    1
178 machineFunctionInfo: {}
179 body:             |
180   bb.0:
181     liveins: $w1, $x0
183     ; We should be able to do the same with multiplies as with shifts.
185     ; CHECK-LABEL: name: mul_gep_anyext_ldrwrow
186     ; CHECK: liveins: $w1, $x0
187     ; CHECK: %base:gpr64sp = COPY $x0
188     ; CHECK: %foo:gpr32 = COPY $w1
189     ; CHECK: %load:gpr32 = LDRWroW %base, %foo, 0, 1 :: (load (s32))
190     ; CHECK: $w0 = COPY %load
191     ; CHECK: RET_ReallyLR implicit $w0
192     %base:gpr(p0) = COPY $x0
193     %foo:gpr(s32) = COPY $w1
194     %ext:gpr(s64) = G_ANYEXT %foo(s32)
195     %c:gpr(s64) = G_CONSTANT i64 4
196     %offset:gpr(s64) = G_MUL %c, %ext
197     %ptr:gpr(p0) = G_PTR_ADD %base, %offset(s64)
198     %load:gpr(s32) = G_LOAD %ptr(p0) :: (load (s32))
199     $w0 = COPY %load(s32)
200     RET_ReallyLR implicit $w0
203 name:            ldrdrow
204 alignment:       4
205 legalized:       true
206 regBankSelected: true
207 tracksRegLiveness: true
208 frameInfo:
209   maxAlignment:    1
210 machineFunctionInfo: {}
211 body:             |
212   bb.0:
213     liveins: $w1, $x0, $d0
215     ; Verify that we can select LDRDroW.
217     ; CHECK-LABEL: name: ldrdrow
218     ; CHECK: liveins: $w1, $x0, $d0
219     ; CHECK: %base:gpr64sp = COPY $x0
220     ; CHECK: %foo:gpr32 = COPY $w1
221     ; CHECK: %load:fpr64 = LDRDroW %base, %foo, 1, 1 :: (load (<2 x s32>))
222     ; CHECK: $x0 = COPY %load
223     ; CHECK: RET_ReallyLR implicit $x0
224     %base:gpr(p0) = COPY $x0
225     %foo:gpr(s32) = COPY $w1
226     %ext:gpr(s64) = G_SEXT %foo(s32)
227     %c:gpr(s64) = G_CONSTANT i64 8
228     %offset:gpr(s64) = G_MUL %c, %ext
229     %ptr:gpr(p0) = G_PTR_ADD %base, %offset(s64)
230     %load:fpr(<2 x s32>) = G_LOAD %ptr(p0) :: (load (<2 x s32>))
231     $x0 = COPY %load(<2 x s32>)
232     RET_ReallyLR implicit $x0
235 name:            ldrxrow
236 alignment:       4
237 legalized:       true
238 regBankSelected: true
239 tracksRegLiveness: true
240 frameInfo:
241   maxAlignment:    1
242 machineFunctionInfo: {}
243 body:             |
244   bb.0:
245     liveins: $w1, $x0, $d0
247     ; Verify that we can select LDRXroW.
249     ; CHECK-LABEL: name: ldrxrow
250     ; CHECK: liveins: $w1, $x0, $d0
251     ; CHECK: %base:gpr64sp = COPY $x0
252     ; CHECK: %foo:gpr32 = COPY $w1
253     ; CHECK: %load:gpr64 = LDRXroW %base, %foo, 1, 1 :: (load (s64))
254     ; CHECK: $x0 = COPY %load
255     ; CHECK: RET_ReallyLR implicit $x0
256     %base:gpr(p0) = COPY $x0
257     %foo:gpr(s32) = COPY $w1
258     %ext:gpr(s64) = G_SEXT %foo(s32)
259     %c:gpr(s64) = G_CONSTANT i64 8
260     %offset:gpr(s64) = G_MUL %c, %ext
261     %ptr:gpr(p0) = G_PTR_ADD %base, %offset(s64)
262     %load:gpr(s64) = G_LOAD %ptr(p0) :: (load (s64))
263     $x0 = COPY %load(s64)
264     RET_ReallyLR implicit $x0
267 name: ldrbbrow
268 alignment:       4
269 legalized:       true
270 regBankSelected: true
271 tracksRegLiveness: true
272 frameInfo:
273   maxAlignment:    1
274 machineFunctionInfo: {}
275 body:             |
276   bb.1.entry:
277     liveins: $x0, $w0, $w1
279     ; Verify that we can select LDRBBroW. Note that there is no shift here,
280     ; but we still fold the extend into the addressing mode.
282     ; CHECK-LABEL: name: ldrbbrow
283     ; CHECK: liveins: $x0, $w0, $w1
284     ; CHECK: %val:gpr32 = COPY $w1
285     ; CHECK: %base:gpr64sp = COPY $x0
286     ; CHECK: %load:gpr32 = LDRBBroW %base, %val, 1, 0 :: (load (s8))
287     ; CHECK: $w0 = COPY %load
288     ; CHECK: RET_ReallyLR implicit $w0
289     %val:gpr(s32) = COPY $w1
290     %base:gpr(p0) = COPY $x0
291     %ext:gpr(s64) = G_SEXT %val(s32)
292     %ptr:gpr(p0) = G_PTR_ADD %base, %ext(s64)
293     %load:gpr(s32) = G_LOAD %ptr(p0) :: (load (s8))
294     $w0 = COPY %load(s32)
295     RET_ReallyLR implicit $w0
298 name: ldrhrow
299 alignment:       4
300 legalized:       true
301 regBankSelected: true
302 tracksRegLiveness: true
303 frameInfo:
304   maxAlignment:    1
305 machineFunctionInfo: {}
306 body:             |
307   bb.1.entry:
308     liveins: $w1, $x0
310     ; Verify that we can select ldrhrow.
312     ; CHECK-LABEL: name: ldrhrow
313     ; CHECK: liveins: $w1, $x0
314     ; CHECK: %base:gpr64sp = COPY $x0
315     ; CHECK: %foo:gpr32 = COPY $w1
316     ; CHECK: %load:fpr16 = LDRHroW %base, %foo, 1, 1 :: (load (s16))
317     ; CHECK: $h0 = COPY %load
318     ; CHECK: RET_ReallyLR implicit $h0
319     %base:gpr(p0) = COPY $x0
320     %foo:gpr(s32) = COPY $w1
321     %ext:gpr(s64) = G_SEXT %foo(s32)
322     %c:gpr(s64) = G_CONSTANT i64 2
323     %offset:gpr(s64) = G_MUL %c, %ext
324     %ptr:gpr(p0) = G_PTR_ADD %base, %offset(s64)
325     %load:fpr(s16) = G_LOAD %ptr(p0) :: (load (s16))
326     $h0 = COPY %load(s16)
327     RET_ReallyLR implicit $h0
330 name:            bad_and_mask_1
331 alignment:       4
332 legalized:       true
333 regBankSelected: true
334 tracksRegLiveness: true
335 frameInfo:
336   maxAlignment:    1
337 body:             |
338   bb.0:
339     liveins: $x0
341     ; We should get a roX load here, not a roW load. We can't use the mask in
342     ; this test for an extend.
344     ; CHECK-LABEL: name: bad_and_mask_1
345     ; CHECK: liveins: $x0
346     ; CHECK: %base:gpr64sp = COPY $x0
347     ; CHECK: %imp:gpr64 = IMPLICIT_DEF
348     ; CHECK: %and:gpr64common = ANDXri %imp, 4103
349     ; CHECK: %load:gpr64 = LDRXroX %base, %and, 0, 1 :: (load (s64))
350     ; CHECK: $x1 = COPY %load
351     ; CHECK: RET_ReallyLR implicit $x1
352     %base:gpr(p0) = COPY $x0
353     %imp:gpr(s64) = G_IMPLICIT_DEF
354     %bad_mask:gpr(s64) = G_CONSTANT i64 255
355     %and:gpr(s64) = G_AND %imp, %bad_mask
356     %c:gpr(s64) = G_CONSTANT i64 8
357     %mul:gpr(s64) = G_MUL %c, %and
358     %ptr:gpr(p0) = G_PTR_ADD %base, %mul(s64)
359     %load:gpr(s64) = G_LOAD %ptr(p0) :: (load (s64))
360     $x1 = COPY %load(s64)
361     RET_ReallyLR implicit $x1
364 name:            bad_and_mask_2
365 alignment:       4
366 legalized:       true
367 regBankSelected: true
368 tracksRegLiveness: true
369 frameInfo:
370   maxAlignment:    1
371 body:             |
372   bb.0:
373     liveins: $x0
375     ; We should get a roX load here, not a roW load. We can't use the mask in
376     ; this test for an extend.
378     ; CHECK-LABEL: name: bad_and_mask_2
379     ; CHECK: liveins: $x0
380     ; CHECK: %base:gpr64sp = COPY $x0
381     ; CHECK: %imp:gpr64 = IMPLICIT_DEF
382     ; CHECK: %and:gpr64common = ANDXri %imp, 4111
383     ; CHECK: %load:gpr64 = LDRXroX %base, %and, 0, 1 :: (load (s64))
384     ; CHECK: $x1 = COPY %load
385     ; CHECK: RET_ReallyLR implicit $x1
386     %base:gpr(p0) = COPY $x0
387     %imp:gpr(s64) = G_IMPLICIT_DEF
388     %bad_mask:gpr(s64) = G_CONSTANT i64 65535
389     %and:gpr(s64) = G_AND %imp, %bad_mask
390     %c:gpr(s64) = G_CONSTANT i64 8
391     %mul:gpr(s64) = G_MUL %c, %and
392     %ptr:gpr(p0) = G_PTR_ADD %base, %mul(s64)
393     %load:gpr(s64) = G_LOAD %ptr(p0) :: (load (s64))
394     $x1 = COPY %load(s64)
395     RET_ReallyLR implicit $x1
398 name:            and_uxtw
399 alignment:       4
400 legalized:       true
401 regBankSelected: true
402 tracksRegLiveness: true
403 frameInfo:
404   maxAlignment:    1
405 body:             |
406   bb.0:
407     liveins: $x0
409     ; The mask used for the AND here is legal for producing a roW load.
411     ; CHECK-LABEL: name: and_uxtw
412     ; CHECK: liveins: $x0
413     ; CHECK: %base:gpr64sp = COPY $x0
414     ; CHECK: %imp:gpr64 = IMPLICIT_DEF
415     ; CHECK: [[COPY:%[0-9]+]]:gpr32all = COPY %imp.sub_32
416     ; CHECK: [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]]
417     ; CHECK: %load:gpr64 = LDRXroW %base, [[COPY1]], 0, 1 :: (load (s64))
418     ; CHECK: $x1 = COPY %load
419     ; CHECK: RET_ReallyLR implicit $x1
420     %base:gpr(p0) = COPY $x0
421     %imp:gpr(s64) = G_IMPLICIT_DEF
422     %mask:gpr(s64) = G_CONSTANT i64 4294967295
423     %and:gpr(s64) = G_AND %imp, %mask
424     %c:gpr(s64) = G_CONSTANT i64 8
425     %mul:gpr(s64) = G_MUL %c, %and
426     %ptr:gpr(p0) = G_PTR_ADD %base, %mul(s64)
427     %load:gpr(s64) = G_LOAD %ptr(p0) :: (load (s64))
428     $x1 = COPY %load(s64)
429     RET_ReallyLR implicit $x1
432 name:            zext_shl_LDRWroW
433 alignment:       4
434 legalized:       true
435 regBankSelected: true
436 tracksRegLiveness: true
437 liveins:
438   - { reg: '$w0' }
439   - { reg: '$x1' }
440 body:             |
441   bb.1:
442     liveins: $w0, $x1
444     ; We try to look through the G_ZEXT of the SHL here.
446     ; CHECK-LABEL: name: zext_shl_LDRWroW
447     ; CHECK: liveins: $w0, $x1
448     ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
449     ; CHECK: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1
450     ; CHECK: [[ANDWri:%[0-9]+]]:gpr32common = ANDWri [[COPY]], 7
451     ; CHECK: [[LDRWroW:%[0-9]+]]:gpr32 = LDRWroW [[COPY1]], [[ANDWri]], 0, 1 :: (load (s32))
452     ; CHECK: $w0 = COPY [[LDRWroW]]
453     ; CHECK: RET_ReallyLR implicit $w0
454     %0:gpr(s32) = COPY $w0
455     %1:gpr(p0) = COPY $x1
456     %2:gpr(s32) = G_CONSTANT i32 255
457     %3:gpr(s32) = G_AND %0, %2
458     %13:gpr(s64) = G_CONSTANT i64 2
459     %12:gpr(s32) = G_SHL %3, %13(s64)
460     %6:gpr(s64) = G_ZEXT %12(s32)
461     %7:gpr(p0) = G_PTR_ADD %1, %6(s64)
462     %9:gpr(s32) = G_LOAD %7(p0) :: (load (s32))
463     $w0 = COPY %9(s32)
464     RET_ReallyLR implicit $w0