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: [[MOVwzr:%[0-9]+]]:gpr32 = COPY $wzr
48 ; CHECK: [[MOVi32imm1:%[0-9]+]]:gpr32 = MOVi32imm 1
49 ; CHECK: $wzr = ADDSWrr [[COPY]], [[COPY1]], implicit-def $nzcv
50 ; CHECK: [[CSELWr:%[0-9]+]]:gpr32 = CSELWr [[MOVi32imm1]], [[MOVwzr]], 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: [[MOVi32imm:%[0-9]+]]:gpr32 = COPY $wzr
80 ; CHECK: [[MOVi32imm1:%[0-9]+]]:gpr32 = MOVi32imm 1
81 ; CHECK: $wzr = ADDSWrr [[COPY]], [[COPY1]], implicit-def $nzcv
82 ; CHECK: [[CSELWr:%[0-9]+]]:gpr32 = CSELWr [[MOVi32imm1]], [[MOVi32imm]], 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: [[MOVi32imm:%[0-9]+]]:gpr32 = COPY $wzr
112 ; CHECK: [[MOVi32imm1:%[0-9]+]]:gpr32 = MOVi32imm 1
113 ; CHECK: [[SUBSWrr:%[0-9]+]]:gpr32 = SUBSWrr [[MOVi32imm]], [[COPY1]], implicit-def $nzcv
114 ; CHECK: $wzr = SUBSWrr [[COPY]], [[SUBSWrr]], implicit-def $nzcv
115 ; CHECK: [[CSELWr:%[0-9]+]]:gpr32 = CSELWr [[MOVi32imm1]], [[MOVi32imm]], 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: [[MOVi32imm:%[0-9]+]]:gpr32 = COPY $wzr
145 ; CHECK: [[MOVi32imm1:%[0-9]+]]:gpr32 = MOVi32imm 1
146 ; CHECK: [[SUBSWrr:%[0-9]+]]:gpr32 = SUBSWrr [[MOVi32imm]], [[COPY]], implicit-def $nzcv
147 ; CHECK: $wzr = SUBSWrr [[SUBSWrr]], [[COPY1]], implicit-def $nzcv
148 ; CHECK: [[CSELWr:%[0-9]+]]:gpr32 = CSELWr [[MOVi32imm1]], [[MOVi32imm]], 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: [[MOVi64imm:%[0-9]+]]:gpr64 = COPY $xzr
178 ; CHECK: [[MOVi64imm1:%[0-9]+]]:gpr64 = MOVi64imm 1
179 ; CHECK: $xzr = ADDSXrr [[COPY]], [[COPY1]], implicit-def $nzcv
180 ; CHECK: [[CSELXr:%[0-9]+]]:gpr64 = CSELXr [[MOVi64imm1]], [[MOVi64imm]], 1, implicit $nzcv
181 ; CHECK: $x0 = COPY [[CSELXr]]
182 ; CHECK: RET_ReallyLR implicit $x0
183 %0:gpr(s64) = COPY $x0
184 %1:gpr(s64) = COPY $x1
185 %2:gpr(s64) = G_CONSTANT i64 0
186 %6:gpr(s64) = G_CONSTANT i64 1
187 %3:gpr(s64) = G_SUB %2, %1
188 %7:gpr(s32) = G_ICMP intpred(ne), %0(s64), %3
189 %4:gpr(s1) = G_TRUNC %7(s32)
190 %5:gpr(s64) = G_SELECT %4(s1), %6, %2
192 RET_ReallyLR implicit $x0
199 regBankSelected: true
200 tracksRegLiveness: true
205 ; CHECK-LABEL: name: cmn_s64_lhs
206 ; CHECK: liveins: $x0, $x1
207 ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0
208 ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1
209 ; CHECK: [[MOVi64imm:%[0-9]+]]:gpr64 = COPY $xzr
210 ; CHECK: [[MOVi64imm1:%[0-9]+]]:gpr64 = MOVi64imm 1
211 ; CHECK: $xzr = ADDSXrr [[COPY]], [[COPY1]], implicit-def $nzcv
212 ; CHECK: [[CSELXr:%[0-9]+]]:gpr64 = CSELXr [[MOVi64imm1]], [[MOVi64imm]], 1, implicit $nzcv
213 ; CHECK: $x0 = COPY [[CSELXr]]
214 ; CHECK: RET_ReallyLR implicit $x0
215 %0:gpr(s64) = COPY $x0
216 %1:gpr(s64) = COPY $x1
217 %2:gpr(s64) = G_CONSTANT i64 0
218 %6:gpr(s64) = G_CONSTANT i64 1
219 %3:gpr(s64) = G_SUB %2, %0
220 %7:gpr(s32) = G_ICMP intpred(ne), %3(s64), %1
221 %4:gpr(s1) = G_TRUNC %7(s32)
222 %5:gpr(s64) = G_SELECT %4(s1), %6, %2
224 RET_ReallyLR implicit $x0
231 regBankSelected: true
232 tracksRegLiveness: true
237 ; CHECK-LABEL: name: no_cmn_s64_rhs
238 ; CHECK: liveins: $x0, $x1
239 ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0
240 ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1
241 ; CHECK: [[MOVi64imm:%[0-9]+]]:gpr64 = COPY $xzr
242 ; CHECK: [[MOVi64imm1:%[0-9]+]]:gpr64 = MOVi64imm 1
243 ; CHECK: [[SUBSXrr:%[0-9]+]]:gpr64 = SUBSXrr [[MOVi64imm]], [[COPY1]], implicit-def $nzcv
244 ; CHECK: $xzr = SUBSXrr [[COPY]], [[SUBSXrr]], implicit-def $nzcv
245 ; CHECK: [[CSELXr:%[0-9]+]]:gpr64 = CSELXr [[MOVi64imm1]], [[MOVi64imm]], 11, implicit $nzcv
246 ; CHECK: $x0 = COPY [[CSELXr]]
247 ; CHECK: RET_ReallyLR implicit $x0
248 %0:gpr(s64) = COPY $x0
249 %1:gpr(s64) = COPY $x1
250 %2:gpr(s64) = G_CONSTANT i64 0
251 %6:gpr(s64) = G_CONSTANT i64 1
252 %3:gpr(s64) = G_SUB %2, %1
253 %7:gpr(s32) = G_ICMP intpred(slt), %0(s64), %3
254 %4:gpr(s1) = G_TRUNC %7(s32)
255 %5:gpr(s64) = G_SELECT %4(s1), %6, %2
257 RET_ReallyLR implicit $x0
264 regBankSelected: true
265 tracksRegLiveness: true
270 ; CHECK-LABEL: name: no_cmn_s64_lhs
271 ; CHECK: liveins: $x0, $x1
272 ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0
273 ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1
274 ; CHECK: [[MOVi64imm:%[0-9]+]]:gpr64 = COPY $xzr
275 ; CHECK: [[MOVi64imm1:%[0-9]+]]:gpr64 = MOVi64imm 1
276 ; CHECK: [[SUBSXrr:%[0-9]+]]:gpr64 = SUBSXrr [[MOVi64imm]], [[COPY]], implicit-def $nzcv
277 ; CHECK: $xzr = SUBSXrr [[SUBSXrr]], [[COPY1]], implicit-def $nzcv
278 ; CHECK: [[CSELXr:%[0-9]+]]:gpr64 = CSELXr [[MOVi64imm1]], [[MOVi64imm]], 11, implicit $nzcv
279 ; CHECK: $x0 = COPY [[CSELXr]]
280 ; CHECK: RET_ReallyLR implicit $x0
281 %0:gpr(s64) = COPY $x0
282 %1:gpr(s64) = COPY $x1
283 %2:gpr(s64) = G_CONSTANT i64 0
284 %6:gpr(s64) = G_CONSTANT i64 1
285 %3:gpr(s64) = G_SUB %2, %0
286 %7:gpr(s32) = G_ICMP intpred(slt), %3(s64), %1
287 %4:gpr(s1) = G_TRUNC %7(s32)
288 %5:gpr(s64) = G_SELECT %4(s1), %6, %2
290 RET_ReallyLR implicit $x0
297 regBankSelected: true
298 tracksRegLiveness: true
302 ; CHECK-LABEL: name: tst_s32
303 ; CHECK: liveins: $w0, $w1
304 ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w1
305 ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = COPY $wzr
306 ; CHECK: [[MOVi32imm1:%[0-9]+]]:gpr32 = MOVi32imm 1
307 ; CHECK: $wzr = ANDSWrr [[MOVi32imm]], [[COPY]], implicit-def $nzcv
308 ; CHECK: [[CSELWr:%[0-9]+]]:gpr32 = CSELWr [[MOVi32imm1]], [[MOVi32imm]], 0, implicit $nzcv
309 ; CHECK: $w0 = COPY [[CSELWr]]
310 ; CHECK: RET_ReallyLR implicit $w0
311 %0:gpr(s32) = COPY $w0
312 %1:gpr(s32) = COPY $w1
313 %2:gpr(s32) = G_CONSTANT i32 0
314 %6:gpr(s32) = G_CONSTANT i32 1
315 %3:gpr(s32) = G_AND %2, %1
316 %8:gpr(s32) = G_CONSTANT i32 0
317 %7:gpr(s32) = G_ICMP intpred(eq), %3(s32), %8
318 %4:gpr(s1) = G_TRUNC %7(s32)
319 %5:gpr(s32) = G_SELECT %4(s1), %6, %2
321 RET_ReallyLR implicit $w0
328 regBankSelected: true
329 tracksRegLiveness: true
333 ; CHECK-LABEL: name: tst_s64
334 ; CHECK: liveins: $x0, $x1
335 ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x1
336 ; CHECK: [[MOVi64imm:%[0-9]+]]:gpr64 = COPY $xzr
337 ; CHECK: [[MOVi64imm1:%[0-9]+]]:gpr64 = MOVi64imm 1
338 ; CHECK: $xzr = ANDSXrr [[MOVi64imm]], [[COPY]], implicit-def $nzcv
339 ; CHECK: [[CSELXr:%[0-9]+]]:gpr64 = CSELXr [[MOVi64imm1]], [[MOVi64imm]], 0, implicit $nzcv
340 ; CHECK: $x0 = COPY [[CSELXr]]
341 ; CHECK: RET_ReallyLR implicit $x0
342 %0:gpr(s64) = COPY $x0
343 %1:gpr(s64) = COPY $x1
344 %2:gpr(s64) = G_CONSTANT i64 0
345 %6:gpr(s64) = G_CONSTANT i64 1
346 %3:gpr(s64) = G_AND %2, %1
347 %8:gpr(s64) = G_CONSTANT i64 0
348 %7:gpr(s32) = G_ICMP intpred(eq), %3(s64), %8
349 %4:gpr(s1) = G_TRUNC %7(s32)
350 %5:gpr(s64) = G_SELECT %4(s1), %6, %2
352 RET_ReallyLR implicit $x0
356 name: no_tst_unsigned_compare
359 regBankSelected: true
360 tracksRegLiveness: true
364 ; CHECK-LABEL: name: no_tst_unsigned_compare
365 ; CHECK: liveins: $w0, $w1
366 ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w1
367 ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = COPY $wzr
368 ; CHECK: [[MOVi32imm1:%[0-9]+]]:gpr32 = MOVi32imm 1
369 ; CHECK: [[ANDWrr:%[0-9]+]]:gpr32common = ANDWrr [[MOVi32imm]], [[COPY]]
370 ; CHECK: $wzr = SUBSWri [[ANDWrr]], 0, 0, implicit-def $nzcv
371 ; CHECK: [[CSELWr:%[0-9]+]]:gpr32 = CSELWr [[MOVi32imm1]], [[MOVi32imm]], 8, implicit $nzcv
372 ; CHECK: $w0 = COPY [[CSELWr]]
373 ; CHECK: RET_ReallyLR implicit $w0
374 %0:gpr(s32) = COPY $w0
375 %1:gpr(s32) = COPY $w1
376 %2:gpr(s32) = G_CONSTANT i32 0
377 %6:gpr(s32) = G_CONSTANT i32 1
378 %3:gpr(s32) = G_AND %2, %1
379 %8:gpr(s32) = G_CONSTANT i32 0
380 %7:gpr(s32) = G_ICMP intpred(ugt), %3(s32), %8
381 %4:gpr(s1) = G_TRUNC %7(s32)
382 %5:gpr(s32) = G_SELECT %4(s1), %6, %2
384 RET_ReallyLR implicit $w0
391 regBankSelected: true
392 tracksRegLiveness: true
396 ; CHECK-LABEL: name: no_tst_nonzero
397 ; CHECK: liveins: $w0, $w1
398 ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w1
399 ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = COPY $wzr
400 ; CHECK: [[MOVi32imm1:%[0-9]+]]:gpr32 = MOVi32imm 1
401 ; CHECK: [[ANDWrr:%[0-9]+]]:gpr32common = ANDWrr [[MOVi32imm]], [[COPY]]
402 ; CHECK: $wzr = SUBSWri [[ANDWrr]], 42, 0, implicit-def $nzcv
403 ; CHECK: [[CSELWr:%[0-9]+]]:gpr32 = CSELWr [[MOVi32imm1]], [[MOVi32imm]], 8, implicit $nzcv
404 ; CHECK: $w0 = COPY [[CSELWr]]
405 ; CHECK: RET_ReallyLR implicit $w0
406 %0:gpr(s32) = COPY $w0
407 %1:gpr(s32) = COPY $w1
408 %2:gpr(s32) = G_CONSTANT i32 0
409 %6:gpr(s32) = G_CONSTANT i32 1
410 %3:gpr(s32) = G_AND %2, %1
411 %8:gpr(s32) = G_CONSTANT i32 42
412 %7:gpr(s32) = G_ICMP intpred(ugt), %3(s32), %8
413 %4:gpr(s1) = G_TRUNC %7(s32)
414 %5:gpr(s32) = G_SELECT %4(s1), %6, %2
416 RET_ReallyLR implicit $w0
423 regBankSelected: true
424 tracksRegLiveness: true
428 ; CHECK-LABEL: name: imm_tst
429 ; CHECK: liveins: $w0, $w1
430 ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w1
431 ; CHECK: $wzr = ANDSWri [[COPY]], 1, implicit-def $nzcv
432 ; CHECK: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr $wzr, $wzr, 1, implicit $nzcv
433 ; CHECK: $w0 = COPY [[CSINCWr]]
434 ; CHECK: RET_ReallyLR implicit $w0
435 %0:gpr(s32) = COPY $w0
436 %1:gpr(s32) = COPY $w1
437 %2:gpr(s32) = G_CONSTANT i32 0
438 %3:gpr(s32) = G_CONSTANT i32 1
440 ; This can be represented as a logical immediate, so we can pull it into
441 ; the ANDS. We should get ANDSWri.
442 %4:gpr(s32) = G_CONSTANT i32 3
444 %5:gpr(s32) = G_AND %1, %4
445 %6:gpr(s32) = G_ICMP intpred(eq), %5(s32), %2
447 RET_ReallyLR implicit $w0
452 name: no_imm_tst_not_logical_imm
455 regBankSelected: true
456 tracksRegLiveness: true
460 ; CHECK-LABEL: name: no_imm_tst_not_logical_imm
461 ; CHECK: liveins: $w0, $w1
462 ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w1
463 ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm -1
464 ; CHECK: $wzr = ANDSWrr [[COPY]], [[MOVi32imm]], implicit-def $nzcv
465 ; CHECK: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr $wzr, $wzr, 1, implicit $nzcv
466 ; CHECK: $w0 = COPY [[CSINCWr]]
467 ; CHECK: RET_ReallyLR implicit $w0
468 %0:gpr(s32) = COPY $w0
469 %1:gpr(s32) = COPY $w1
470 %2:gpr(s32) = G_CONSTANT i32 0
471 %3:gpr(s32) = G_CONSTANT i32 1
473 ; This immediate can't be represented as a logical immediate. We shouldn't
475 %4:gpr(s32) = G_CONSTANT i32 -1
477 %5:gpr(s32) = G_AND %1, %4
478 %6:gpr(s32) = G_ICMP intpred(eq), %5(s32), %2
480 RET_ReallyLR implicit $w0
484 name: test_physreg_copy
487 regBankSelected: true
488 tracksRegLiveness: true
492 ; CHECK-LABEL: name: test_physreg_copy
493 ; CHECK: liveins: $x0, $x1
494 ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0
495 ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1
496 ; CHECK: $xzr = SUBSXrr [[COPY]], [[COPY1]], implicit-def $nzcv
497 ; CHECK: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr $wzr, $wzr, 1, implicit $nzcv
498 ; CHECK: $w0 = COPY [[CSINCWr]]
499 ; CHECK: RET_ReallyLR implicit $x0
500 %0:gpr(s64) = COPY $x0
501 %1:gpr(s64) = COPY $x1
502 ; When we find the defs of the LHS and RHS of the compare, we walk over
503 ; copies. Make sure that we don't crash when we hit a copy from a physical
505 %7:gpr(s32) = G_ICMP intpred(eq), %0, %1
507 RET_ReallyLR implicit $x0