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
4 # Verify folding operations into G_ICMP.
6 # E.g cmn/adds folding:
9 # G_ICMP intpred(something_safe) z, x
14 # Where "something_safe" is ne or eq.
25 # When we have signed comparisons.
27 # Tests whose names start with cmn_ should use ADDS for the G_ICMP. Tests whose
28 # names start with no_cmn should use SUBS. Similarly, tests whose names start
29 # with TST should use ANDS for the G_ICMP.
38 tracksRegLiveness: true
43 ; CHECK-LABEL: name: cmn_s32_rhs
44 ; CHECK: liveins: $w0, $w1
45 ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
46 ; CHECK: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1
47 ; CHECK: [[COPY2:%[0-9]+]]:gpr32 = COPY $wzr
48 ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1
49 ; CHECK: $wzr = ADDSWrr [[COPY]], [[COPY1]], implicit-def $nzcv
50 ; CHECK: [[CSELWr:%[0-9]+]]:gpr32 = CSELWr [[MOVi32imm]], [[COPY2]], 1, implicit $nzcv
51 ; CHECK: $w0 = COPY [[CSELWr]]
52 ; CHECK: RET_ReallyLR implicit $w0
53 %0:gpr(s32) = COPY $w0
54 %1:gpr(s32) = COPY $w1
55 %2:gpr(s32) = G_CONSTANT i32 0
56 %6:gpr(s32) = G_CONSTANT i32 1
57 %3:gpr(s32) = G_SUB %2, %1
58 %7:gpr(s32) = G_ICMP intpred(ne), %0(s32), %3
59 %4:gpr(s1) = G_TRUNC %7(s32)
60 %5:gpr(s32) = G_SELECT %4(s1), %6, %2
62 RET_ReallyLR implicit $w0
70 tracksRegLiveness: true
75 ; CHECK-LABEL: name: cmn_s32_lhs
76 ; CHECK: liveins: $w0, $w1
77 ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
78 ; CHECK: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1
79 ; CHECK: [[COPY2:%[0-9]+]]:gpr32 = COPY $wzr
80 ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1
81 ; CHECK: $wzr = ADDSWrr [[COPY]], [[COPY1]], implicit-def $nzcv
82 ; CHECK: [[CSELWr:%[0-9]+]]:gpr32 = CSELWr [[MOVi32imm]], [[COPY2]], 1, implicit $nzcv
83 ; CHECK: $w0 = COPY [[CSELWr]]
84 ; CHECK: RET_ReallyLR implicit $w0
85 %0:gpr(s32) = COPY $w0
86 %1:gpr(s32) = COPY $w1
87 %2:gpr(s32) = G_CONSTANT i32 0
88 %6:gpr(s32) = G_CONSTANT i32 1
89 %3:gpr(s32) = G_SUB %2, %0
90 %7:gpr(s32) = G_ICMP intpred(ne), %3(s32), %1
91 %4:gpr(s1) = G_TRUNC %7(s32)
92 %5:gpr(s32) = G_SELECT %4(s1), %6, %2
94 RET_ReallyLR implicit $w0
101 regBankSelected: true
102 tracksRegLiveness: true
107 ; CHECK-LABEL: name: no_cmn_s32_rhs
108 ; CHECK: liveins: $w0, $w1
109 ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
110 ; CHECK: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1
111 ; CHECK: [[COPY2:%[0-9]+]]:gpr32 = COPY $wzr
112 ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1
113 ; CHECK: [[SUBSWrr:%[0-9]+]]:gpr32 = SUBSWrr [[COPY2]], [[COPY1]], implicit-def $nzcv
114 ; CHECK: $wzr = SUBSWrr [[COPY]], [[SUBSWrr]], implicit-def $nzcv
115 ; CHECK: [[CSELWr:%[0-9]+]]:gpr32 = CSELWr [[MOVi32imm]], [[COPY2]], 11, implicit $nzcv
116 ; CHECK: $w0 = COPY [[CSELWr]]
117 ; CHECK: RET_ReallyLR implicit $w0
118 %0:gpr(s32) = COPY $w0
119 %1:gpr(s32) = COPY $w1
120 %2:gpr(s32) = G_CONSTANT i32 0
121 %6:gpr(s32) = G_CONSTANT i32 1
122 %3:gpr(s32) = G_SUB %2, %1
123 %7:gpr(s32) = G_ICMP intpred(slt), %0(s32), %3
124 %4:gpr(s1) = G_TRUNC %7(s32)
125 %5:gpr(s32) = G_SELECT %4(s1), %6, %2
127 RET_ReallyLR implicit $w0
134 regBankSelected: true
135 tracksRegLiveness: true
140 ; CHECK-LABEL: name: no_cmn_s32_lhs
141 ; CHECK: liveins: $w0, $w1
142 ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
143 ; CHECK: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1
144 ; CHECK: [[COPY2:%[0-9]+]]:gpr32 = COPY $wzr
145 ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1
146 ; CHECK: [[SUBSWrr:%[0-9]+]]:gpr32 = SUBSWrr [[COPY2]], [[COPY]], implicit-def $nzcv
147 ; CHECK: $wzr = SUBSWrr [[SUBSWrr]], [[COPY1]], implicit-def $nzcv
148 ; CHECK: [[CSELWr:%[0-9]+]]:gpr32 = CSELWr [[MOVi32imm]], [[COPY2]], 11, implicit $nzcv
149 ; CHECK: $w0 = COPY [[CSELWr]]
150 ; CHECK: RET_ReallyLR implicit $w0
151 %0:gpr(s32) = COPY $w0
152 %1:gpr(s32) = COPY $w1
153 %2:gpr(s32) = G_CONSTANT i32 0
154 %6:gpr(s32) = G_CONSTANT i32 1
155 %3:gpr(s32) = G_SUB %2, %0
156 %7:gpr(s32) = G_ICMP intpred(slt), %3(s32), %1
157 %4:gpr(s1) = G_TRUNC %7(s32)
158 %5:gpr(s32) = G_SELECT %4(s1), %6, %2
160 RET_ReallyLR implicit $w0
167 regBankSelected: true
168 tracksRegLiveness: true
173 ; CHECK-LABEL: name: cmn_s64_rhs
174 ; CHECK: liveins: $x0, $x1
175 ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0
176 ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1
177 ; CHECK: [[COPY2:%[0-9]+]]:gpr64 = COPY $xzr
178 ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1
179 ; CHECK: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG 0, [[MOVi32imm]], %subreg.sub_32
180 ; CHECK: $xzr = ADDSXrr [[COPY]], [[COPY1]], implicit-def $nzcv
181 ; CHECK: [[CSELXr:%[0-9]+]]:gpr64 = CSELXr [[SUBREG_TO_REG]], [[COPY2]], 1, implicit $nzcv
182 ; CHECK: $x0 = COPY [[CSELXr]]
183 ; CHECK: RET_ReallyLR implicit $x0
184 %0:gpr(s64) = COPY $x0
185 %1:gpr(s64) = COPY $x1
186 %2:gpr(s64) = G_CONSTANT i64 0
187 %6:gpr(s64) = G_CONSTANT i64 1
188 %3:gpr(s64) = G_SUB %2, %1
189 %7:gpr(s32) = G_ICMP intpred(ne), %0(s64), %3
190 %4:gpr(s1) = G_TRUNC %7(s32)
191 %5:gpr(s64) = G_SELECT %4(s1), %6, %2
193 RET_ReallyLR implicit $x0
200 regBankSelected: true
201 tracksRegLiveness: true
206 ; CHECK-LABEL: name: cmn_s64_lhs
207 ; CHECK: liveins: $x0, $x1
208 ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0
209 ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1
210 ; CHECK: [[COPY2:%[0-9]+]]:gpr64 = COPY $xzr
211 ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1
212 ; CHECK: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG 0, [[MOVi32imm]], %subreg.sub_32
213 ; CHECK: $xzr = ADDSXrr [[COPY]], [[COPY1]], implicit-def $nzcv
214 ; CHECK: [[CSELXr:%[0-9]+]]:gpr64 = CSELXr [[SUBREG_TO_REG]], [[COPY2]], 1, implicit $nzcv
215 ; CHECK: $x0 = COPY [[CSELXr]]
216 ; CHECK: RET_ReallyLR implicit $x0
217 %0:gpr(s64) = COPY $x0
218 %1:gpr(s64) = COPY $x1
219 %2:gpr(s64) = G_CONSTANT i64 0
220 %6:gpr(s64) = G_CONSTANT i64 1
221 %3:gpr(s64) = G_SUB %2, %0
222 %7:gpr(s32) = G_ICMP intpred(ne), %3(s64), %1
223 %4:gpr(s1) = G_TRUNC %7(s32)
224 %5:gpr(s64) = G_SELECT %4(s1), %6, %2
226 RET_ReallyLR implicit $x0
233 regBankSelected: true
234 tracksRegLiveness: true
239 ; CHECK-LABEL: name: no_cmn_s64_rhs
240 ; CHECK: liveins: $x0, $x1
241 ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0
242 ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1
243 ; CHECK: [[COPY2:%[0-9]+]]:gpr64 = COPY $xzr
244 ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1
245 ; CHECK: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG 0, [[MOVi32imm]], %subreg.sub_32
246 ; CHECK: [[SUBSXrr:%[0-9]+]]:gpr64 = SUBSXrr [[COPY2]], [[COPY1]], implicit-def $nzcv
247 ; CHECK: $xzr = SUBSXrr [[COPY]], [[SUBSXrr]], implicit-def $nzcv
248 ; CHECK: [[CSELXr:%[0-9]+]]:gpr64 = CSELXr [[SUBREG_TO_REG]], [[COPY2]], 11, implicit $nzcv
249 ; CHECK: $x0 = COPY [[CSELXr]]
250 ; CHECK: RET_ReallyLR implicit $x0
251 %0:gpr(s64) = COPY $x0
252 %1:gpr(s64) = COPY $x1
253 %2:gpr(s64) = G_CONSTANT i64 0
254 %6:gpr(s64) = G_CONSTANT i64 1
255 %3:gpr(s64) = G_SUB %2, %1
256 %7:gpr(s32) = G_ICMP intpred(slt), %0(s64), %3
257 %4:gpr(s1) = G_TRUNC %7(s32)
258 %5:gpr(s64) = G_SELECT %4(s1), %6, %2
260 RET_ReallyLR implicit $x0
267 regBankSelected: true
268 tracksRegLiveness: true
273 ; CHECK-LABEL: name: no_cmn_s64_lhs
274 ; CHECK: liveins: $x0, $x1
275 ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0
276 ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1
277 ; CHECK: [[COPY2:%[0-9]+]]:gpr64 = COPY $xzr
278 ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1
279 ; CHECK: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG 0, [[MOVi32imm]], %subreg.sub_32
280 ; CHECK: [[SUBSXrr:%[0-9]+]]:gpr64 = SUBSXrr [[COPY2]], [[COPY]], implicit-def $nzcv
281 ; CHECK: $xzr = SUBSXrr [[SUBSXrr]], [[COPY1]], implicit-def $nzcv
282 ; CHECK: [[CSELXr:%[0-9]+]]:gpr64 = CSELXr [[SUBREG_TO_REG]], [[COPY2]], 11, implicit $nzcv
283 ; CHECK: $x0 = COPY [[CSELXr]]
284 ; CHECK: RET_ReallyLR implicit $x0
285 %0:gpr(s64) = COPY $x0
286 %1:gpr(s64) = COPY $x1
287 %2:gpr(s64) = G_CONSTANT i64 0
288 %6:gpr(s64) = G_CONSTANT i64 1
289 %3:gpr(s64) = G_SUB %2, %0
290 %7:gpr(s32) = G_ICMP intpred(slt), %3(s64), %1
291 %4:gpr(s1) = G_TRUNC %7(s32)
292 %5:gpr(s64) = G_SELECT %4(s1), %6, %2
294 RET_ReallyLR implicit $x0
301 regBankSelected: true
302 tracksRegLiveness: true
306 ; CHECK-LABEL: name: tst_s32
307 ; CHECK: liveins: $w0, $w1
308 ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w1
309 ; CHECK: [[COPY1:%[0-9]+]]:gpr32 = COPY $wzr
310 ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1
311 ; CHECK: $wzr = ANDSWrr [[COPY1]], [[COPY]], implicit-def $nzcv
312 ; CHECK: [[CSELWr:%[0-9]+]]:gpr32 = CSELWr [[MOVi32imm]], [[COPY1]], 0, implicit $nzcv
313 ; CHECK: $w0 = COPY [[CSELWr]]
314 ; CHECK: RET_ReallyLR implicit $w0
315 %0:gpr(s32) = COPY $w0
316 %1:gpr(s32) = COPY $w1
317 %2:gpr(s32) = G_CONSTANT i32 0
318 %6:gpr(s32) = G_CONSTANT i32 1
319 %3:gpr(s32) = G_AND %2, %1
320 %8:gpr(s32) = G_CONSTANT i32 0
321 %7:gpr(s32) = G_ICMP intpred(eq), %3(s32), %8
322 %4:gpr(s1) = G_TRUNC %7(s32)
323 %5:gpr(s32) = G_SELECT %4(s1), %6, %2
325 RET_ReallyLR implicit $w0
332 regBankSelected: true
333 tracksRegLiveness: true
337 ; CHECK-LABEL: name: tst_s64
338 ; CHECK: liveins: $x0, $x1
339 ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x1
340 ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY $xzr
341 ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1
342 ; CHECK: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG 0, [[MOVi32imm]], %subreg.sub_32
343 ; CHECK: $xzr = ANDSXrr [[COPY1]], [[COPY]], implicit-def $nzcv
344 ; CHECK: [[CSELXr:%[0-9]+]]:gpr64 = CSELXr [[SUBREG_TO_REG]], [[COPY1]], 0, implicit $nzcv
345 ; CHECK: $x0 = COPY [[CSELXr]]
346 ; CHECK: RET_ReallyLR implicit $x0
347 %0:gpr(s64) = COPY $x0
348 %1:gpr(s64) = COPY $x1
349 %2:gpr(s64) = G_CONSTANT i64 0
350 %6:gpr(s64) = G_CONSTANT i64 1
351 %3:gpr(s64) = G_AND %2, %1
352 %8:gpr(s64) = G_CONSTANT i64 0
353 %7:gpr(s32) = G_ICMP intpred(eq), %3(s64), %8
354 %4:gpr(s1) = G_TRUNC %7(s32)
355 %5:gpr(s64) = G_SELECT %4(s1), %6, %2
357 RET_ReallyLR implicit $x0
361 name: no_tst_unsigned_compare
364 regBankSelected: true
365 tracksRegLiveness: true
369 ; CHECK-LABEL: name: no_tst_unsigned_compare
370 ; CHECK: liveins: $w0, $w1
371 ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w1
372 ; CHECK: [[COPY1:%[0-9]+]]:gpr32 = COPY $wzr
373 ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1
374 ; CHECK: [[ANDWrr:%[0-9]+]]:gpr32common = ANDWrr [[COPY1]], [[COPY]]
375 ; CHECK: $wzr = SUBSWri [[ANDWrr]], 0, 0, implicit-def $nzcv
376 ; CHECK: [[CSELWr:%[0-9]+]]:gpr32 = CSELWr [[MOVi32imm]], [[COPY1]], 8, implicit $nzcv
377 ; CHECK: $w0 = COPY [[CSELWr]]
378 ; CHECK: RET_ReallyLR implicit $w0
379 %0:gpr(s32) = COPY $w0
380 %1:gpr(s32) = COPY $w1
381 %2:gpr(s32) = G_CONSTANT i32 0
382 %6:gpr(s32) = G_CONSTANT i32 1
383 %3:gpr(s32) = G_AND %2, %1
384 %8:gpr(s32) = G_CONSTANT i32 0
385 %7:gpr(s32) = G_ICMP intpred(ugt), %3(s32), %8
386 %4:gpr(s1) = G_TRUNC %7(s32)
387 %5:gpr(s32) = G_SELECT %4(s1), %6, %2
389 RET_ReallyLR implicit $w0
396 regBankSelected: true
397 tracksRegLiveness: true
401 ; CHECK-LABEL: name: no_tst_nonzero
402 ; CHECK: liveins: $w0, $w1
403 ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w1
404 ; CHECK: [[COPY1:%[0-9]+]]:gpr32 = COPY $wzr
405 ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1
406 ; CHECK: [[ANDWrr:%[0-9]+]]:gpr32common = ANDWrr [[COPY1]], [[COPY]]
407 ; CHECK: $wzr = SUBSWri [[ANDWrr]], 42, 0, implicit-def $nzcv
408 ; CHECK: [[CSELWr:%[0-9]+]]:gpr32 = CSELWr [[MOVi32imm]], [[COPY1]], 8, implicit $nzcv
409 ; CHECK: $w0 = COPY [[CSELWr]]
410 ; CHECK: RET_ReallyLR implicit $w0
411 %0:gpr(s32) = COPY $w0
412 %1:gpr(s32) = COPY $w1
413 %2:gpr(s32) = G_CONSTANT i32 0
414 %6:gpr(s32) = G_CONSTANT i32 1
415 %3:gpr(s32) = G_AND %2, %1
416 %8:gpr(s32) = G_CONSTANT i32 42
417 %7:gpr(s32) = G_ICMP intpred(ugt), %3(s32), %8
418 %4:gpr(s1) = G_TRUNC %7(s32)
419 %5:gpr(s32) = G_SELECT %4(s1), %6, %2
421 RET_ReallyLR implicit $w0
428 regBankSelected: true
429 tracksRegLiveness: true
433 ; CHECK-LABEL: name: imm_tst
434 ; CHECK: liveins: $w0, $w1
435 ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w1
436 ; CHECK: $wzr = ANDSWri [[COPY]], 1, implicit-def $nzcv
437 ; CHECK: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr $wzr, $wzr, 1, implicit $nzcv
438 ; CHECK: $w0 = COPY [[CSINCWr]]
439 ; CHECK: RET_ReallyLR implicit $w0
440 %0:gpr(s32) = COPY $w0
441 %1:gpr(s32) = COPY $w1
442 %2:gpr(s32) = G_CONSTANT i32 0
443 %3:gpr(s32) = G_CONSTANT i32 1
445 ; This can be represented as a logical immediate, so we can pull it into
446 ; the ANDS. We should get ANDSWri.
447 %4:gpr(s32) = G_CONSTANT i32 3
449 %5:gpr(s32) = G_AND %1, %4
450 %6:gpr(s32) = G_ICMP intpred(eq), %5(s32), %2
452 RET_ReallyLR implicit $w0
457 name: no_imm_tst_not_logical_imm
460 regBankSelected: true
461 tracksRegLiveness: true
465 ; CHECK-LABEL: name: no_imm_tst_not_logical_imm
466 ; CHECK: liveins: $w0, $w1
467 ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w1
468 ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm -1
469 ; CHECK: $wzr = ANDSWrr [[COPY]], [[MOVi32imm]], implicit-def $nzcv
470 ; CHECK: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr $wzr, $wzr, 1, implicit $nzcv
471 ; CHECK: $w0 = COPY [[CSINCWr]]
472 ; CHECK: RET_ReallyLR implicit $w0
473 %0:gpr(s32) = COPY $w0
474 %1:gpr(s32) = COPY $w1
475 %2:gpr(s32) = G_CONSTANT i32 0
476 %3:gpr(s32) = G_CONSTANT i32 1
478 ; This immediate can't be represented as a logical immediate. We shouldn't
480 %4:gpr(s32) = G_CONSTANT i32 -1
482 %5:gpr(s32) = G_AND %1, %4
483 %6:gpr(s32) = G_ICMP intpred(eq), %5(s32), %2
485 RET_ReallyLR implicit $w0
489 name: test_physreg_copy
492 regBankSelected: true
493 tracksRegLiveness: true
497 ; CHECK-LABEL: name: test_physreg_copy
498 ; CHECK: liveins: $x0, $x1
499 ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0
500 ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1
501 ; CHECK: $xzr = SUBSXrr [[COPY]], [[COPY1]], implicit-def $nzcv
502 ; CHECK: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr $wzr, $wzr, 1, implicit $nzcv
503 ; CHECK: $w0 = COPY [[CSINCWr]]
504 ; CHECK: RET_ReallyLR implicit $x0
505 %0:gpr(s64) = COPY $x0
506 %1:gpr(s64) = COPY $x1
507 ; When we find the defs of the LHS and RHS of the compare, we walk over
508 ; copies. Make sure that we don't crash when we hit a copy from a physical
510 %7:gpr(s32) = G_ICMP intpred(eq), %0, %1
512 RET_ReallyLR implicit $x0