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
5 name: shl_gep_sext_ldrwrow
9 tracksRegLiveness: true
12 machineFunctionInfo: {}
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
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))
36 RET_ReallyLR implicit $w0
39 name: shl_gep_zext_ldrwrow
43 tracksRegLiveness: true
46 machineFunctionInfo: {}
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))
70 RET_ReallyLR implicit $w0
73 name: shl_gep_anyext_ldrwrow
77 tracksRegLiveness: true
80 machineFunctionInfo: {}
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
110 regBankSelected: true
111 tracksRegLiveness: true
114 machineFunctionInfo: {}
118 ; We should be able to do the same with multiplies as with shifts.
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
142 regBankSelected: true
143 tracksRegLiveness: true
146 machineFunctionInfo: {}
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
174 regBankSelected: true
175 tracksRegLiveness: true
178 machineFunctionInfo: {}
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
206 regBankSelected: true
207 tracksRegLiveness: true
210 machineFunctionInfo: {}
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
238 regBankSelected: true
239 tracksRegLiveness: true
242 machineFunctionInfo: {}
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
270 regBankSelected: true
271 tracksRegLiveness: true
274 machineFunctionInfo: {}
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
301 regBankSelected: true
302 tracksRegLiveness: true
305 machineFunctionInfo: {}
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
333 regBankSelected: true
334 tracksRegLiveness: true
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
367 regBankSelected: true
368 tracksRegLiveness: true
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
401 regBankSelected: true
402 tracksRegLiveness: true
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
435 regBankSelected: true
436 tracksRegLiveness: true
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))
464 RET_ReallyLR implicit $w0