1 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2 # RUN: llc -mtriple aarch64-apple-darwin -debugify-and-strip-all-safe -run-pass=aarch64-prelegalizer-combiner -global-isel -verify-machineinstrs %s -o - | FileCheck %s
4 # Check that we propagate the G_SEXT to the sources of the phi operand.
6 name: sext_icst_through_phi
7 tracksRegLiveness: true
9 ; CHECK-LABEL: name: sext_icst_through_phi
11 ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
12 ; CHECK-NEXT: liveins: $w0, $w1
14 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
15 ; CHECK-NEXT: %one:_(s32) = G_CONSTANT i32 2
16 ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(sle), [[COPY]](s32), %one
17 ; CHECK-NEXT: G_BRCOND %cmp(s1), %bb.2
18 ; CHECK-NEXT: G_BR %bb.1
21 ; CHECK-NEXT: successors: %bb.3(0x80000000)
23 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
24 ; CHECK-NEXT: G_BR %bb.3
27 ; CHECK-NEXT: successors: %bb.3(0x80000000)
29 ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 10
32 ; CHECK-NEXT: %ext:_(s64) = G_PHI [[C]](s64), %bb.1, [[C1]](s64), %bb.2
33 ; CHECK-NEXT: $x0 = COPY %ext(s64)
34 ; CHECK-NEXT: RET_ReallyLR implicit $x0
40 %zero:_(s32) = G_CONSTANT i32 0
41 %one:_(s32) = G_CONSTANT i32 2
42 %cmp:_(s1) = G_ICMP intpred(sgt), %0(s32), %one
43 G_BRCOND %cmp(s1), %bb.2
47 %cst32_4:_(s32) = G_CONSTANT i32 4
51 %cst32_10:_(s32) = G_CONSTANT i32 10
54 %phi:_(s32) = G_PHI %cst32_4(s32), %bb.2, %cst32_10(s32), %bb.3
55 %ext:_(s64) = G_SEXT %phi
57 RET_ReallyLR implicit $x0
61 # Check that we propagate the G_ZEXT to the sources of the phi operand.
63 name: zext_icst_through_phi
64 tracksRegLiveness: true
66 ; CHECK-LABEL: name: zext_icst_through_phi
68 ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
69 ; CHECK-NEXT: liveins: $w0, $w1
71 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
72 ; CHECK-NEXT: %one:_(s32) = G_CONSTANT i32 2
73 ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(sle), [[COPY]](s32), %one
74 ; CHECK-NEXT: G_BRCOND %cmp(s1), %bb.2
75 ; CHECK-NEXT: G_BR %bb.1
78 ; CHECK-NEXT: successors: %bb.3(0x80000000)
80 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
81 ; CHECK-NEXT: G_BR %bb.3
84 ; CHECK-NEXT: successors: %bb.3(0x80000000)
86 ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 10
89 ; CHECK-NEXT: %ext:_(s64) = G_PHI [[C]](s64), %bb.1, [[C1]](s64), %bb.2
90 ; CHECK-NEXT: $x0 = COPY %ext(s64)
91 ; CHECK-NEXT: RET_ReallyLR implicit $x0
97 %zero:_(s32) = G_CONSTANT i32 0
98 %one:_(s32) = G_CONSTANT i32 2
99 %cmp:_(s1) = G_ICMP intpred(sgt), %0(s32), %one
100 G_BRCOND %cmp(s1), %bb.2
104 %cst32_4:_(s32) = G_CONSTANT i32 4
108 %cst32_10:_(s32) = G_CONSTANT i32 10
111 %phi:_(s32) = G_PHI %cst32_4(s32), %bb.2, %cst32_10(s32), %bb.3
112 %ext:_(s64) = G_ZEXT %phi
114 RET_ReallyLR implicit $x0
118 # Don't handle vectors because of potential cost issues.
120 name: sext_load_through_phi_vector
121 tracksRegLiveness: true
123 ; CHECK-LABEL: name: sext_load_through_phi_vector
125 ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
126 ; CHECK-NEXT: liveins: $x0, $q0, $q1
128 ; CHECK-NEXT: %ptr:_(p0) = COPY $x0
129 ; CHECK-NEXT: %cmp:_(s1) = G_IMPLICIT_DEF
130 ; CHECK-NEXT: G_BRCOND %cmp(s1), %bb.2
131 ; CHECK-NEXT: G_BR %bb.1
134 ; CHECK-NEXT: successors: %bb.3(0x80000000)
136 ; CHECK-NEXT: %ld1:_(<4 x s32>) = G_LOAD %ptr(p0) :: (load (<4 x s32>))
137 ; CHECK-NEXT: G_BR %bb.3
140 ; CHECK-NEXT: successors: %bb.3(0x80000000)
142 ; CHECK-NEXT: %ld2:_(<4 x s32>) = G_LOAD %ptr(p0) :: (load (<4 x s32>))
145 ; CHECK-NEXT: %phi:_(<4 x s32>) = G_PHI %ld1(<4 x s32>), %bb.1, %ld2(<4 x s32>), %bb.2
146 ; CHECK-NEXT: %ext:_(<4 x s64>) = G_SEXT %phi(<4 x s32>)
147 ; CHECK-NEXT: G_STORE %ext(<4 x s64>), %ptr(p0) :: (store (<4 x s64>))
148 ; CHECK-NEXT: RET_ReallyLR
150 liveins: $x0, $q0, $q1
152 %0:_(<4 x s32>) = COPY $q0
153 %1:_(<4 x s32>) = COPY $q1
154 %ptr:_(p0) = COPY $x0
155 %cmp:_(s1) = G_IMPLICIT_DEF
156 G_BRCOND %cmp(s1), %bb.2
160 %ld1:_(<4 x s32>) = G_LOAD %ptr(p0) :: (load (<4 x s32>))
164 %ld2:_(<4 x s32>) = G_LOAD %ptr(p0) :: (load (<4 x s32>))
167 %phi:_(<4 x s32>) = G_PHI %ld1(<4 x s32>), %bb.2, %ld2(<4 x s32>), %bb.3
168 %ext:_(<4 x s64>) = G_SEXT %phi
169 G_STORE %ext(<4 x s64>), %ptr(p0) :: (store (<4 x s64>))
175 # Check that we don't propagate if the extend is used by a G_PTR_ADD, which on
176 # AArch64 has a good chance of folding in the extend.
178 name: sext_icst_through_phi_used_by_ptradd
179 tracksRegLiveness: true
181 ; CHECK-LABEL: name: sext_icst_through_phi_used_by_ptradd
183 ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
184 ; CHECK-NEXT: liveins: $w0, $w1, $x2
186 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
187 ; CHECK-NEXT: %base:_(p0) = COPY $x2
188 ; CHECK-NEXT: %one:_(s32) = G_CONSTANT i32 2
189 ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(sle), [[COPY]](s32), %one
190 ; CHECK-NEXT: G_BRCOND %cmp(s1), %bb.2
191 ; CHECK-NEXT: G_BR %bb.1
194 ; CHECK-NEXT: successors: %bb.3(0x80000000)
196 ; CHECK-NEXT: %cst32_4:_(s32) = G_CONSTANT i32 4
197 ; CHECK-NEXT: G_BR %bb.3
200 ; CHECK-NEXT: successors: %bb.3(0x80000000)
202 ; CHECK-NEXT: %cst32_10:_(s32) = G_CONSTANT i32 10
205 ; CHECK-NEXT: %phi:_(s32) = G_PHI %cst32_4(s32), %bb.1, %cst32_10(s32), %bb.2
206 ; CHECK-NEXT: %ext:_(s64) = G_SEXT %phi(s32)
207 ; CHECK-NEXT: %ptr:_(p0) = G_PTR_ADD %base, %ext(s64)
208 ; CHECK-NEXT: $x0 = COPY %ptr(p0)
209 ; CHECK-NEXT: RET_ReallyLR implicit $x0
211 liveins: $w0, $w1, $x2
215 %base:_(p0) = COPY $x2
216 %zero:_(s32) = G_CONSTANT i32 0
217 %one:_(s32) = G_CONSTANT i32 2
218 %cmp:_(s1) = G_ICMP intpred(sgt), %0(s32), %one
219 G_BRCOND %cmp(s1), %bb.2
223 %cst32_4:_(s32) = G_CONSTANT i32 4
227 %cst32_10:_(s32) = G_CONSTANT i32 10
230 %phi:_(s32) = G_PHI %cst32_4(s32), %bb.2, %cst32_10(s32), %bb.3
231 %ext:_(s64) = G_SEXT %phi
232 %ptr:_(p0) = G_PTR_ADD %base, %ext
234 RET_ReallyLR implicit $x0
238 # Same as above but we do it here because the extend has multiple users, so the
239 # it probably won't cost extra instructions if we remove it.
241 name: sext_icst_through_phi_used_by_ptradd_multiuse
242 tracksRegLiveness: true
244 ; CHECK-LABEL: name: sext_icst_through_phi_used_by_ptradd_multiuse
246 ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
247 ; CHECK-NEXT: liveins: $w0, $w1, $x2
249 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
250 ; CHECK-NEXT: %base:_(p0) = COPY $x2
251 ; CHECK-NEXT: %one:_(s32) = G_CONSTANT i32 2
252 ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(sle), [[COPY]](s32), %one
253 ; CHECK-NEXT: G_BRCOND %cmp(s1), %bb.2
254 ; CHECK-NEXT: G_BR %bb.1
257 ; CHECK-NEXT: successors: %bb.3(0x80000000)
259 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
260 ; CHECK-NEXT: G_BR %bb.3
263 ; CHECK-NEXT: successors: %bb.3(0x80000000)
265 ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 10
268 ; CHECK-NEXT: %ext:_(s64) = G_PHI [[C]](s64), %bb.1, [[C1]](s64), %bb.2
269 ; CHECK-NEXT: %ptr:_(p0) = G_PTR_ADD %base, %ext(s64)
270 ; CHECK-NEXT: $x0 = COPY %ptr(p0)
271 ; CHECK-NEXT: $x1 = COPY %ext(s64)
272 ; CHECK-NEXT: RET_ReallyLR implicit $x0
274 liveins: $w0, $w1, $x2
278 %base:_(p0) = COPY $x2
279 %zero:_(s32) = G_CONSTANT i32 0
280 %one:_(s32) = G_CONSTANT i32 2
281 %cmp:_(s1) = G_ICMP intpred(sgt), %0(s32), %one
282 G_BRCOND %cmp(s1), %bb.2
286 %cst32_4:_(s32) = G_CONSTANT i32 4
290 %cst32_10:_(s32) = G_CONSTANT i32 10
293 %phi:_(s32) = G_PHI %cst32_4(s32), %bb.2, %cst32_10(s32), %bb.3
294 %ext:_(s64) = G_SEXT %phi
295 %ptr:_(p0) = G_PTR_ADD %base, %ext
298 RET_ReallyLR implicit $x0
302 # Check we don't propagate if there are more than 2 unique incoming values in the phi.
303 # Doing so might cause too much code bloat.
305 name: zext_icst_through_phi_too_many_incoming
306 tracksRegLiveness: true
308 ; CHECK-LABEL: name: zext_icst_through_phi_too_many_incoming
310 ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
311 ; CHECK-NEXT: liveins: $w0, $w1
313 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
314 ; CHECK-NEXT: %one:_(s32) = G_CONSTANT i32 2
315 ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(sle), [[COPY]](s32), %one
316 ; CHECK-NEXT: G_BRCOND %cmp(s1), %bb.2
317 ; CHECK-NEXT: G_BR %bb.1
320 ; CHECK-NEXT: successors: %bb.3(0x40000000), %bb.4(0x40000000)
322 ; CHECK-NEXT: %cst32_4:_(s32) = G_CONSTANT i32 4
323 ; CHECK-NEXT: %cond:_(s1) = G_IMPLICIT_DEF
324 ; CHECK-NEXT: G_BRCOND %cond(s1), %bb.3
325 ; CHECK-NEXT: G_BR %bb.4
328 ; CHECK-NEXT: successors: %bb.4(0x80000000)
330 ; CHECK-NEXT: %cst32_10:_(s32) = G_CONSTANT i32 10
331 ; CHECK-NEXT: G_BR %bb.4
334 ; CHECK-NEXT: successors: %bb.4(0x80000000)
336 ; CHECK-NEXT: %cst32_42:_(s32) = G_CONSTANT i32 42
339 ; CHECK-NEXT: %phi:_(s32) = G_PHI %cst32_4(s32), %bb.1, %cst32_10(s32), %bb.2, %cst32_42(s32), %bb.3
340 ; CHECK-NEXT: %ext:_(s64) = G_ZEXT %phi(s32)
341 ; CHECK-NEXT: $x0 = COPY %ext(s64)
342 ; CHECK-NEXT: RET_ReallyLR implicit $x0
348 %zero:_(s32) = G_CONSTANT i32 0
349 %one:_(s32) = G_CONSTANT i32 2
350 %cmp:_(s1) = G_ICMP intpred(sgt), %0(s32), %one
351 G_BRCOND %cmp(s1), %bb.2
355 %cst32_4:_(s32) = G_CONSTANT i32 4
356 %cond:_(s1) = G_IMPLICIT_DEF
357 G_BRCOND %cond, %bb.5
361 %cst32_10:_(s32) = G_CONSTANT i32 10
365 %cst32_42:_(s32) = G_CONSTANT i32 42
368 %phi:_(s32) = G_PHI %cst32_4(s32), %bb.2, %cst32_10(s32), %bb.3, %cst32_42(s32), %bb.5
369 %ext:_(s64) = G_ZEXT %phi
371 RET_ReallyLR implicit $x0
375 # Check that we don't propagate if the extension would be of a non-allowed inst.
377 name: sext_add_through_phi
378 tracksRegLiveness: true
380 ; CHECK-LABEL: name: sext_add_through_phi
382 ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
383 ; CHECK-NEXT: liveins: $w0, $w1
385 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
386 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
387 ; CHECK-NEXT: %one:_(s32) = G_CONSTANT i32 2
388 ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(sle), [[COPY]](s32), %one
389 ; CHECK-NEXT: G_BRCOND %cmp(s1), %bb.2
390 ; CHECK-NEXT: G_BR %bb.1
393 ; CHECK-NEXT: successors: %bb.3(0x80000000)
395 ; CHECK-NEXT: %add:_(s32) = G_ADD [[COPY]], [[COPY1]]
396 ; CHECK-NEXT: G_BR %bb.3
399 ; CHECK-NEXT: successors: %bb.3(0x80000000)
401 ; CHECK-NEXT: %cst32_10:_(s32) = G_CONSTANT i32 10
404 ; CHECK-NEXT: %phi:_(s32) = G_PHI %add(s32), %bb.1, %cst32_10(s32), %bb.2
405 ; CHECK-NEXT: %ext:_(s64) = G_SEXT %phi(s32)
406 ; CHECK-NEXT: $x0 = COPY %ext(s64)
407 ; CHECK-NEXT: RET_ReallyLR implicit $x0
413 %zero:_(s32) = G_CONSTANT i32 0
414 %one:_(s32) = G_CONSTANT i32 2
415 %cmp:_(s1) = G_ICMP intpred(sgt), %0(s32), %one
416 G_BRCOND %cmp(s1), %bb.2
420 %add:_(s32) = G_ADD %0, %1
424 %cst32_10:_(s32) = G_CONSTANT i32 10
427 %phi:_(s32) = G_PHI %add(s32), %bb.2, %cst32_10(s32), %bb.3
428 %ext:_(s64) = G_SEXT %phi
430 RET_ReallyLR implicit $x0
434 # Same as above but allowed with a G_ANYEXT.
436 name: anyext_add_through_phi
437 tracksRegLiveness: true
439 ; CHECK-LABEL: name: anyext_add_through_phi
441 ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
442 ; CHECK-NEXT: liveins: $w0, $w1
444 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
445 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
446 ; CHECK-NEXT: %one:_(s32) = G_CONSTANT i32 2
447 ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(sle), [[COPY]](s32), %one
448 ; CHECK-NEXT: G_BRCOND %cmp(s1), %bb.2
449 ; CHECK-NEXT: G_BR %bb.1
452 ; CHECK-NEXT: successors: %bb.3(0x80000000)
454 ; CHECK-NEXT: %add:_(s32) = G_ADD [[COPY]], [[COPY1]]
455 ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT %add(s32)
456 ; CHECK-NEXT: G_BR %bb.3
459 ; CHECK-NEXT: successors: %bb.3(0x80000000)
461 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 10
464 ; CHECK-NEXT: %ext:_(s64) = G_PHI [[ANYEXT]](s64), %bb.1, [[C]](s64), %bb.2
465 ; CHECK-NEXT: $x0 = COPY %ext(s64)
466 ; CHECK-NEXT: RET_ReallyLR implicit $x0
472 %zero:_(s32) = G_CONSTANT i32 0
473 %one:_(s32) = G_CONSTANT i32 2
474 %cmp:_(s1) = G_ICMP intpred(sgt), %0(s32), %one
475 G_BRCOND %cmp(s1), %bb.2
479 %add:_(s32) = G_ADD %0, %1
483 %cst32_10:_(s32) = G_CONSTANT i32 10
486 %phi:_(s32) = G_PHI %add(s32), %bb.2, %cst32_10(s32), %bb.3
487 %ext:_(s64) = G_ANYEXT %phi
489 RET_ReallyLR implicit $x0