1 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2 # RUN: llc -mtriple aarch64 -run-pass=aarch64-prelegalizer-combiner -aarch64prelegalizercombiner-only-enable-rule="load_and_mask" -verify-machineinstrs %s -o - | FileCheck %s
6 # Check that we can fold and ({any,zext,sext}load, mask) -> zextload
10 tracksRegLiveness: true
14 ; CHECK-LABEL: name: test_anyext_1
17 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
18 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
19 ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY]](p0) :: (load (s8))
20 ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s8) = G_AND [[LOAD]], [[C]]
21 ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[AND]](s8)
22 ; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32)
24 %1:_(s8) = G_CONSTANT i8 1
25 %2:_(s8) = G_LOAD %0 :: (load (s8))
26 %3:_(s8) = G_AND %2, %1
27 %4:_(s32) = G_ANYEXT %3
33 tracksRegLiveness: true
37 ; CHECK-LABEL: name: test_anyext_s16
40 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
41 ; CHECK-NEXT: [[ZEXTLOAD:%[0-9]+]]:_(s16) = G_ZEXTLOAD [[COPY]](p0) :: (load (s8))
42 ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ZEXTLOAD]](s16)
43 ; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32)
45 %1:_(s16) = G_CONSTANT i16 255
46 %2:_(s16) = G_LOAD %0 :: (load (s8))
47 %3:_(s16) = G_AND %2, %1
48 %4:_(s32) = G_ANYEXT %3
54 tracksRegLiveness: true
58 ; CHECK-LABEL: name: test_anyext_s32
61 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
62 ; CHECK-NEXT: [[ZEXTLOAD:%[0-9]+]]:_(s32) = G_ZEXTLOAD [[COPY]](p0) :: (load (s8))
63 ; CHECK-NEXT: $w0 = COPY [[ZEXTLOAD]](s32)
65 %1:_(s32) = G_CONSTANT i32 255
66 %2:_(s32) = G_LOAD %0 :: (load (s8))
67 %3:_(s32) = G_AND %2, %1
73 tracksRegLiveness: true
77 ; CHECK-LABEL: name: test_load_s32
80 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
81 ; CHECK-NEXT: [[ZEXTLOAD:%[0-9]+]]:_(s32) = G_ZEXTLOAD [[COPY]](p0) :: (load (s8), align 4)
82 ; CHECK-NEXT: $w0 = COPY [[ZEXTLOAD]](s32)
84 %1:_(s32) = G_CONSTANT i32 255
85 %2:_(s32) = G_LOAD %0 :: (load (s32))
86 %3:_(s32) = G_AND %2, %1
91 name: test_load_mask_s8_s32_atomic
92 tracksRegLiveness: true
96 ; CHECK-LABEL: name: test_load_mask_s8_s32_atomic
99 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
100 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
101 ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[COPY]](p0) :: (load seq_cst (s32))
102 ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[LOAD]], [[C]]
103 ; CHECK-NEXT: $w0 = COPY [[AND]](s32)
105 %1:_(s32) = G_CONSTANT i32 255
106 %2:_(s32) = G_LOAD %0 :: (load seq_cst (s32))
107 %3:_(s32) = G_AND %2, %1
111 # The mask is equal to the memory size.
113 name: test_load_mask_s16_s16_atomic
114 tracksRegLiveness: true
118 ; CHECK-LABEL: name: test_load_mask_s16_s16_atomic
119 ; CHECK: liveins: $x0
121 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
122 ; CHECK-NEXT: [[ZEXTLOAD:%[0-9]+]]:_(s32) = G_ZEXTLOAD [[COPY]](p0) :: (load seq_cst (s16))
123 ; CHECK-NEXT: $w0 = COPY [[ZEXTLOAD]](s32)
125 %1:_(s32) = G_CONSTANT i32 65535
126 %2:_(s32) = G_LOAD %0 :: (load seq_cst (s16))
127 %3:_(s32) = G_AND %2, %1
131 # The mask is smaller than the memory size which must be preserved, so
132 # there's little point to folding.
134 name: test_load_mask_s8_s16_atomic
135 tracksRegLiveness: true
139 ; CHECK-LABEL: name: test_load_mask_s8_s16_atomic
140 ; CHECK: liveins: $x0
142 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
143 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
144 ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[COPY]](p0) :: (load seq_cst (s16))
145 ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[LOAD]], [[C]]
146 ; CHECK-NEXT: $w0 = COPY [[AND]](s32)
148 %1:_(s32) = G_CONSTANT i32 255
149 %2:_(s32) = G_LOAD %0 :: (load seq_cst (s16))
150 %3:_(s32) = G_AND %2, %1
155 name: test_load_mask_size_equals_dst_size
156 tracksRegLiveness: true
161 ; The combine should only apply if the mask zeroes actual bits of the dst type
162 ; If it doesn't, the mask is redundant and we have other combines to fold it away
164 ; CHECK-LABEL: name: test_load_mask_size_equals_dst_size
165 ; CHECK: liveins: $x0
167 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
168 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
169 ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[COPY]](p0) :: (load (s32))
170 ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[LOAD]], [[C]]
171 ; CHECK-NEXT: $w0 = COPY [[AND]](s32)
173 %1:_(s32) = G_CONSTANT i32 4294967295
174 %2:_(s32) = G_LOAD %0 :: (load (s32))
175 %3:_(s32) = G_AND %2, %1
181 tracksRegLiveness: true
185 ; CHECK-LABEL: name: test_zext
186 ; CHECK: liveins: $x0
188 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
189 ; CHECK-NEXT: [[ZEXTLOAD:%[0-9]+]]:_(s32) = G_ZEXTLOAD [[COPY]](p0) :: (load (s8), align 2)
190 ; CHECK-NEXT: $w0 = COPY [[ZEXTLOAD]](s32)
192 %1:_(s32) = G_CONSTANT i32 255
193 %2:_(s32) = G_ZEXTLOAD %0 :: (load (s16))
194 %3:_(s32) = G_AND %2, %1
199 name: test_zext_mask_larger_memsize
200 tracksRegLiveness: true
205 ; The combine should only apply if the mask narrows the memory size.
206 ; We have another combine that folds redundant masks
208 ; CHECK-LABEL: name: test_zext_mask_larger_memsize
209 ; CHECK: liveins: $x0
211 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
212 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
213 ; CHECK-NEXT: [[ZEXTLOAD:%[0-9]+]]:_(s32) = G_ZEXTLOAD [[COPY]](p0) :: (load (s8))
214 ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ZEXTLOAD]], [[C]]
215 ; CHECK-NEXT: $w0 = COPY [[AND]](s32)
217 %1:_(s32) = G_CONSTANT i32 65535
218 %2:_(s32) = G_ZEXTLOAD %0 :: (load (s8))
219 %3:_(s32) = G_AND %2, %1
225 tracksRegLiveness: true
229 ; CHECK-LABEL: name: test_sext
230 ; CHECK: liveins: $x0
232 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
233 ; CHECK-NEXT: [[ZEXTLOAD:%[0-9]+]]:_(s32) = G_ZEXTLOAD [[COPY]](p0) :: (load (s8), align 2)
234 ; CHECK-NEXT: $w0 = COPY [[ZEXTLOAD]](s32)
236 %1:_(s32) = G_CONSTANT i32 255
237 %2:_(s32) = G_SEXTLOAD %0 :: (load (s16))
238 %3:_(s32) = G_AND %2, %1
243 name: test_sext_mask_larger_memsize
244 tracksRegLiveness: true
248 ; CHECK-LABEL: name: test_sext_mask_larger_memsize
249 ; CHECK: liveins: $x0
251 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
252 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
253 ; CHECK-NEXT: [[SEXTLOAD:%[0-9]+]]:_(s32) = G_SEXTLOAD [[COPY]](p0) :: (load (s8))
254 ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[SEXTLOAD]], [[C]]
255 ; CHECK-NEXT: $w0 = COPY [[AND]](s32)
257 %1:_(s32) = G_CONSTANT i32 65535
258 %2:_(s32) = G_SEXTLOAD %0 :: (load (s8))
259 %3:_(s32) = G_AND %2, %1
264 name: test_non_pow2_memtype
265 tracksRegLiveness: true
269 ; CHECK-LABEL: name: test_non_pow2_memtype
270 ; CHECK: liveins: $x0
272 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
273 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s24) = G_CONSTANT i24 7
274 ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s24) = G_LOAD [[COPY]](p0) :: (load (s24), align 4)
275 ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s24) = G_AND [[LOAD]], [[C]]
276 ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[AND]](s24)
277 ; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32)
279 %1:_(s24) = G_CONSTANT i24 7
280 %2:_(s24) = G_LOAD %0 :: (load (s24))
281 %3:_(s24) = G_AND %2, %1
282 %4:_(s32) = G_ANYEXT %3
289 tracksRegLiveness: true
293 ; CHECK-LABEL: name: test_no_mask
294 ; CHECK: liveins: $x0
296 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
297 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 510
298 ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[COPY]](p0) :: (load (s8))
299 ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[LOAD]], [[C]]
300 ; CHECK-NEXT: $w0 = COPY [[AND]](s32)
302 %1:_(s32) = G_CONSTANT i32 510
303 %2:_(s32) = G_LOAD %0 :: (load (s8))
304 %3:_(s32) = G_AND %2, %1
310 tracksRegLiveness: true
314 ; CHECK-LABEL: name: test_volatile
315 ; CHECK: liveins: $x0
317 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
318 ; CHECK-NEXT: [[ZEXTLOAD:%[0-9]+]]:_(s32) = G_ZEXTLOAD [[COPY]](p0) :: (volatile load (s8))
319 ; CHECK-NEXT: $w0 = COPY [[ZEXTLOAD]](s32)
321 %1:_(s32) = G_CONSTANT i32 255
322 %2:_(s32) = G_LOAD %0 :: (volatile load (s8))
323 %3:_(s32) = G_AND %2, %1
328 name: test_volatile_mask_smaller_mem
329 tracksRegLiveness: true
333 ; CHECK-LABEL: name: test_volatile_mask_smaller_mem
334 ; CHECK: liveins: $x0
336 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
337 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
338 ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[COPY]](p0) :: (volatile load (s16))
339 ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[LOAD]], [[C]]
340 ; CHECK-NEXT: $w0 = COPY [[AND]](s32)
342 %1:_(s32) = G_CONSTANT i32 255
343 %2:_(s32) = G_LOAD %0 :: (volatile load (s16))
344 %3:_(s32) = G_AND %2, %1
348 name: test_no_lookthrough_copies_multi_uses
349 tracksRegLiveness: true
353 ; CHECK-LABEL: name: test_no_lookthrough_copies_multi_uses
354 ; CHECK: liveins: $x0
356 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
357 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
358 ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[COPY]](p0) :: (load (s16))
359 ; CHECK-NEXT: %v:_(s32) = G_ASSERT_ZEXT [[LOAD]], 16
360 ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND %v, [[C]]
361 ; CHECK-NEXT: $w1 = COPY %v(s32)
362 ; CHECK-NEXT: $w0 = COPY [[AND]](s32)
364 %1:_(s32) = G_CONSTANT i32 255
365 %2:_(s32) = G_LOAD %0 :: (load (s16))
366 %v:_(s32) = G_ASSERT_ZEXT %2, 16
367 %3:_(s32) = G_AND %v, %1