1 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2 # RUN: llc -mtriple=aarch64 -run-pass=aarch64-postlegalizer-lowering -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=LOWER
3 # RUN: llc -mtriple=aarch64 -global-isel -start-before=aarch64-postlegalizer-lowering -stop-after=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=SELECT
5 # Check that we swap the order of operands on comparisons when it is likely
6 # to introduce a folding opportunity.
8 # The condition code for the compare should be changed when appropriate.
10 # TODO: emitBinOp doesn't know about selectArithExtendedRegister, so some of
11 # these cases don't hit in selection yet.
15 name: swap_sextinreg_lhs
17 tracksRegLiveness: true
22 ; LOWER-LABEL: name: swap_sextinreg_lhs
23 ; LOWER: liveins: $x0, $x1
24 ; LOWER: %reg:_(s64) = COPY $x0
25 ; LOWER: %cmp_lhs:_(s64) = G_SEXT_INREG %reg, 8
26 ; LOWER: %cmp_rhs:_(s64) = COPY $x1
27 ; LOWER: %cmp:_(s32) = G_ICMP intpred(sle), %cmp_rhs(s64), %cmp_lhs
28 ; LOWER: $w0 = COPY %cmp(s32)
29 ; LOWER: RET_ReallyLR implicit $w0
30 ; SELECT-LABEL: name: swap_sextinreg_lhs
31 ; SELECT: liveins: $x0, $x1
32 ; SELECT: %reg:gpr64all = COPY $x0
33 ; SELECT: [[COPY:%[0-9]+]]:gpr32all = COPY %reg.sub_32
34 ; SELECT: [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]]
35 ; SELECT: %cmp_rhs:gpr64sp = COPY $x1
36 ; SELECT: [[SUBSXrx:%[0-9]+]]:gpr64 = SUBSXrx %cmp_rhs, [[COPY1]], 32, implicit-def $nzcv
37 ; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 12, implicit $nzcv
38 ; SELECT: $w0 = COPY %cmp
39 ; SELECT: RET_ReallyLR implicit $w0
40 %reg:_(s64) = COPY $x0
41 %cmp_lhs:_(s64) = G_SEXT_INREG %reg, 8
42 %cmp_rhs:_(s64) = COPY $x1
43 %cmp:_(s32) = G_ICMP intpred(sge), %cmp_lhs(s64), %cmp_rhs
45 RET_ReallyLR implicit $w0
49 name: dont_swap_more_than_one_use
51 tracksRegLiveness: true
56 ; The LHS of the compare is used in an add, and a second compare. Don't
57 ; swap, since we don't gain any folding opportunities here.
59 ; LOWER-LABEL: name: dont_swap_more_than_one_use
60 ; LOWER: liveins: $x0, $x1
61 ; LOWER: %reg0:_(s64) = COPY $x0
62 ; LOWER: %cmp_lhs:_(s64) = G_SEXT_INREG %reg0, 8
63 ; LOWER: %add:_(s64) = G_ADD %cmp_lhs, %reg0
64 ; LOWER: %cmp2:_(s32) = G_ICMP intpred(sge), %cmp_lhs(s64), %add
65 ; LOWER: $w0 = COPY %cmp2(s32)
66 ; LOWER: RET_ReallyLR implicit $w0
67 ; SELECT-LABEL: name: dont_swap_more_than_one_use
68 ; SELECT: liveins: $x0, $x1
69 ; SELECT: %reg0:gpr64 = COPY $x0
70 ; SELECT: %cmp_lhs:gpr64 = SBFMXri %reg0, 0, 7
71 ; SELECT: %add:gpr64 = ADDXrr %cmp_lhs, %reg0
72 ; SELECT: [[SUBSXrr:%[0-9]+]]:gpr64 = SUBSXrr %cmp_lhs, %add, implicit-def $nzcv
73 ; SELECT: %cmp2:gpr32 = CSINCWr $wzr, $wzr, 11, implicit $nzcv
74 ; SELECT: $w0 = COPY %cmp2
75 ; SELECT: RET_ReallyLR implicit $w0
76 %reg0:_(s64) = COPY $x0
77 %cmp_lhs:_(s64) = G_SEXT_INREG %reg0, 8
78 %reg1:_(s64) = COPY $x1
79 %cmp1:_(s32) = G_ICMP intpred(sge), %cmp_lhs(s64), %reg1
81 %add:_(s64) = G_ADD %cmp_lhs(s64), %reg0
82 %cmp2:_(s32) = G_ICMP intpred(sge), %cmp_lhs(s64), %add
85 RET_ReallyLR implicit $w0
89 name: dont_swap_legal_arith_immed_on_rhs
91 tracksRegLiveness: true
95 ; Arithmetic immediates can be folded into compares. If we have one, then
96 ; don't bother changing anything.
98 ; LOWER-LABEL: name: dont_swap_legal_arith_immed_on_rhs
99 ; LOWER: liveins: $x0, $x1
100 ; LOWER: %reg:_(s64) = COPY $x0
101 ; LOWER: %cmp_lhs:_(s64) = G_SEXT_INREG %reg, 8
102 ; LOWER: %cmp_rhs:_(s64) = G_CONSTANT i64 12
103 ; LOWER: %cmp:_(s32) = G_ICMP intpred(sge), %cmp_lhs(s64), %cmp_rhs
104 ; LOWER: $w0 = COPY %cmp(s32)
105 ; LOWER: RET_ReallyLR implicit $w0
106 ; SELECT-LABEL: name: dont_swap_legal_arith_immed_on_rhs
107 ; SELECT: liveins: $x0, $x1
108 ; SELECT: %reg:gpr64 = COPY $x0
109 ; SELECT: %cmp_lhs:gpr64common = SBFMXri %reg, 0, 7
110 ; SELECT: [[SUBSXri:%[0-9]+]]:gpr64 = SUBSXri %cmp_lhs, 12, 0, implicit-def $nzcv
111 ; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 11, implicit $nzcv
112 ; SELECT: $w0 = COPY %cmp
113 ; SELECT: RET_ReallyLR implicit $w0
114 %reg:_(s64) = COPY $x0
115 %cmp_lhs:_(s64) = G_SEXT_INREG %reg, 8
116 %cmp_rhs:_(s64) = G_CONSTANT i64 12
117 %cmp:_(s32) = G_ICMP intpred(sge), %cmp_lhs(s64), %cmp_rhs
119 RET_ReallyLR implicit $w0
123 name: swap_non_arith_immed_on_rhs
125 tracksRegLiveness: true
129 ; If we have a non-arithmetic immediate on the rhs, then we can swap to get
130 ; a guaranteed folding opportunity.
132 ; LOWER-LABEL: name: swap_non_arith_immed_on_rhs
133 ; LOWER: liveins: $x0, $x1
134 ; LOWER: %reg:_(s64) = COPY $x0
135 ; LOWER: %cmp_lhs:_(s64) = G_SEXT_INREG %reg, 8
136 ; LOWER: %cmp_rhs:_(s64) = G_CONSTANT i64 1234567
137 ; LOWER: %cmp:_(s32) = G_ICMP intpred(sle), %cmp_rhs(s64), %cmp_lhs
138 ; LOWER: $w0 = COPY %cmp(s32)
139 ; LOWER: RET_ReallyLR implicit $w0
140 ; SELECT-LABEL: name: swap_non_arith_immed_on_rhs
141 ; SELECT: liveins: $x0, $x1
142 ; SELECT: %reg:gpr64all = COPY $x0
143 ; SELECT: [[COPY:%[0-9]+]]:gpr32all = COPY %reg.sub_32
144 ; SELECT: [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]]
145 ; SELECT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1234567
146 ; SELECT: %cmp_rhs:gpr64sp = SUBREG_TO_REG 0, [[MOVi32imm]], %subreg.sub_32
147 ; SELECT: [[SUBSXrx:%[0-9]+]]:gpr64 = SUBSXrx %cmp_rhs, [[COPY1]], 32, implicit-def $nzcv
148 ; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 12, implicit $nzcv
149 ; SELECT: $w0 = COPY %cmp
150 ; SELECT: RET_ReallyLR implicit $w0
151 %reg:_(s64) = COPY $x0
152 %cmp_lhs:_(s64) = G_SEXT_INREG %reg, 8
153 %cmp_rhs:_(s64) = G_CONSTANT i64 1234567
154 %cmp:_(s32) = G_ICMP intpred(sge), %cmp_lhs(s64), %cmp_rhs
156 RET_ReallyLR implicit $w0
160 name: swap_and_lhs_0xFF
162 tracksRegLiveness: true
166 ; LOWER-LABEL: name: swap_and_lhs_0xFF
167 ; LOWER: liveins: $x0, $x1
168 ; LOWER: %cmp_rhs:_(s64) = COPY $x1
169 ; LOWER: %and_lhs:_(s64) = COPY $x0
170 ; LOWER: %cst:_(s64) = G_CONSTANT i64 255
171 ; LOWER: %cmp_lhs:_(s64) = G_AND %and_lhs, %cst
172 ; LOWER: %cmp:_(s32) = G_ICMP intpred(sle), %cmp_rhs(s64), %cmp_lhs
173 ; LOWER: $w0 = COPY %cmp(s32)
174 ; LOWER: RET_ReallyLR implicit $w0
175 ; SELECT-LABEL: name: swap_and_lhs_0xFF
176 ; SELECT: liveins: $x0, $x1
177 ; SELECT: %cmp_rhs:gpr64sp = COPY $x1
178 ; SELECT: %and_lhs:gpr64all = COPY $x0
179 ; SELECT: [[COPY:%[0-9]+]]:gpr32all = COPY %and_lhs.sub_32
180 ; SELECT: [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]]
181 ; SELECT: [[SUBSXrx:%[0-9]+]]:gpr64 = SUBSXrx %cmp_rhs, [[COPY1]], 0, implicit-def $nzcv
182 ; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 12, implicit $nzcv
183 ; SELECT: $w0 = COPY %cmp
184 ; SELECT: RET_ReallyLR implicit $w0
185 %cmp_rhs:_(s64) = COPY $x1
187 %and_lhs:_(s64) = COPY $x0
188 %cst:_(s64) = G_CONSTANT i64 255
189 %cmp_lhs:_(s64) = G_AND %and_lhs, %cst(s64)
191 %cmp:_(s32) = G_ICMP intpred(sge), %cmp_lhs(s64), %cmp_rhs
193 RET_ReallyLR implicit $w0
197 name: swap_and_lhs_0xFFFF
199 tracksRegLiveness: true
203 ; LOWER-LABEL: name: swap_and_lhs_0xFFFF
204 ; LOWER: liveins: $x0, $x1
205 ; LOWER: %cmp_rhs:_(s64) = COPY $x1
206 ; LOWER: %cst:_(s64) = G_CONSTANT i64 65535
207 ; LOWER: %and_lhs:_(s64) = COPY $x0
208 ; LOWER: %cmp_lhs:_(s64) = G_AND %and_lhs, %cst
209 ; LOWER: %cmp:_(s32) = G_ICMP intpred(sle), %cmp_rhs(s64), %cmp_lhs
210 ; LOWER: $w0 = COPY %cmp(s32)
211 ; LOWER: RET_ReallyLR implicit $w0
212 ; SELECT-LABEL: name: swap_and_lhs_0xFFFF
213 ; SELECT: liveins: $x0, $x1
214 ; SELECT: %cmp_rhs:gpr64sp = COPY $x1
215 ; SELECT: %and_lhs:gpr64all = COPY $x0
216 ; SELECT: [[COPY:%[0-9]+]]:gpr32all = COPY %and_lhs.sub_32
217 ; SELECT: [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]]
218 ; SELECT: [[SUBSXrx:%[0-9]+]]:gpr64 = SUBSXrx %cmp_rhs, [[COPY1]], 8, implicit-def $nzcv
219 ; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 12, implicit $nzcv
220 ; SELECT: $w0 = COPY %cmp
221 ; SELECT: RET_ReallyLR implicit $w0
222 %cmp_rhs:_(s64) = COPY $x1
224 %cst:_(s64) = G_CONSTANT i64 65535
225 %and_lhs:_(s64) = COPY $x0
226 %cmp_lhs:_(s64) = G_AND %and_lhs, %cst(s64)
228 %cmp:_(s32) = G_ICMP intpred(sge), %cmp_lhs(s64), %cmp_rhs
230 RET_ReallyLR implicit $w0
234 name: swap_and_lhs_0xFFFFFFFF
236 tracksRegLiveness: true
240 ; LOWER-LABEL: name: swap_and_lhs_0xFFFFFFFF
241 ; LOWER: liveins: $x0, $x1
242 ; LOWER: %cmp_rhs:_(s64) = COPY $x1
243 ; LOWER: %and_lhs:_(s64) = COPY $x0
244 ; LOWER: %cst:_(s64) = G_CONSTANT i64 4294967295
245 ; LOWER: %cmp_lhs:_(s64) = G_AND %and_lhs, %cst
246 ; LOWER: %cmp:_(s32) = G_ICMP intpred(sle), %cmp_rhs(s64), %cmp_lhs
247 ; LOWER: $w0 = COPY %cmp(s32)
248 ; LOWER: RET_ReallyLR implicit $w0
249 ; SELECT-LABEL: name: swap_and_lhs_0xFFFFFFFF
250 ; SELECT: liveins: $x0, $x1
251 ; SELECT: %cmp_rhs:gpr64sp = COPY $x1
252 ; SELECT: %and_lhs:gpr64all = COPY $x0
253 ; SELECT: [[COPY:%[0-9]+]]:gpr32all = COPY %and_lhs.sub_32
254 ; SELECT: [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]]
255 ; SELECT: [[SUBSXrx:%[0-9]+]]:gpr64 = SUBSXrx %cmp_rhs, [[COPY1]], 16, implicit-def $nzcv
256 ; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 12, implicit $nzcv
257 ; SELECT: $w0 = COPY %cmp
258 ; SELECT: RET_ReallyLR implicit $w0
259 %cmp_rhs:_(s64) = COPY $x1
261 %and_lhs:_(s64) = COPY $x0
262 %cst:_(s64) = G_CONSTANT i64 4294967295
263 %cmp_lhs:_(s64) = G_AND %and_lhs, %cst(s64)
265 %cmp:_(s32) = G_ICMP intpred(sge), %cmp_lhs(s64), %cmp_rhs
267 RET_ReallyLR implicit $w0
271 name: dont_swap_and_lhs_wrong_mask
273 tracksRegLiveness: true
277 ; 7 isn't an extend mask for G_AND, so there's no folding opportunities
280 ; LOWER-LABEL: name: dont_swap_and_lhs_wrong_mask
281 ; LOWER: liveins: $x0, $x1
282 ; LOWER: %cmp_rhs:_(s64) = COPY $x1
283 ; LOWER: %and_lhs:_(s64) = COPY $x0
284 ; LOWER: %not_an_extend_mask:_(s64) = G_CONSTANT i64 7
285 ; LOWER: %cmp_lhs:_(s64) = G_AND %and_lhs, %not_an_extend_mask
286 ; LOWER: %cmp:_(s32) = G_ICMP intpred(sge), %cmp_lhs(s64), %cmp_rhs
287 ; LOWER: $w0 = COPY %cmp(s32)
288 ; LOWER: RET_ReallyLR implicit $w0
289 ; SELECT-LABEL: name: dont_swap_and_lhs_wrong_mask
290 ; SELECT: liveins: $x0, $x1
291 ; SELECT: %cmp_rhs:gpr64 = COPY $x1
292 ; SELECT: %and_lhs:gpr64 = COPY $x0
293 ; SELECT: %cmp_lhs:gpr64common = ANDXri %and_lhs, 4098
294 ; SELECT: [[SUBSXrr:%[0-9]+]]:gpr64 = SUBSXrr %cmp_lhs, %cmp_rhs, implicit-def $nzcv
295 ; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 11, implicit $nzcv
296 ; SELECT: $w0 = COPY %cmp
297 ; SELECT: RET_ReallyLR implicit $w0
298 %cmp_rhs:_(s64) = COPY $x1
300 %and_lhs:_(s64) = COPY $x0
301 %not_an_extend_mask:_(s64) = G_CONSTANT i64 7
302 %cmp_lhs:_(s64) = G_AND %and_lhs, %not_an_extend_mask(s64)
304 %cmp:_(s32) = G_ICMP intpred(sge), %cmp_lhs(s64), %cmp_rhs
306 RET_ReallyLR implicit $w0
312 tracksRegLiveness: true
317 ; LOWER-LABEL: name: swap_shl_lhs
318 ; LOWER: liveins: $x0, $x1
319 ; LOWER: %cmp_rhs:_(s64) = COPY $x1
320 ; LOWER: %shl_lhs:_(s64) = COPY $x0
321 ; LOWER: %cst:_(s64) = G_CONSTANT i64 1
322 ; LOWER: %cmp_lhs:_(s64) = G_SHL %shl_lhs, %cst(s64)
323 ; LOWER: %cmp:_(s32) = G_ICMP intpred(sgt), %cmp_rhs(s64), %cmp_lhs
324 ; LOWER: $w0 = COPY %cmp(s32)
325 ; LOWER: RET_ReallyLR implicit $w0
326 ; SELECT-LABEL: name: swap_shl_lhs
327 ; SELECT: liveins: $x0, $x1
328 ; SELECT: %cmp_rhs:gpr64 = COPY $x1
329 ; SELECT: %shl_lhs:gpr64 = COPY $x0
330 ; SELECT: [[SUBSXrs:%[0-9]+]]:gpr64 = SUBSXrs %cmp_rhs, %shl_lhs, 1, implicit-def $nzcv
331 ; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 13, implicit $nzcv
332 ; SELECT: $w0 = COPY %cmp
333 ; SELECT: RET_ReallyLR implicit $w0
334 %cmp_rhs:_(s64) = COPY $x1
336 %shl_lhs:_(s64) = COPY $x0
337 %cst:_(s64) = G_CONSTANT i64 1
338 %cmp_lhs:_(s64) = G_SHL %shl_lhs, %cst(s64)
340 %cmp:_(s32) = G_ICMP intpred(slt), %cmp_lhs(s64), %cmp_rhs
342 RET_ReallyLR implicit $w0
348 tracksRegLiveness: true
353 ; LOWER-LABEL: name: swap_ashr_lhs
354 ; LOWER: liveins: $x0, $x1
355 ; LOWER: %cmp_rhs:_(s64) = COPY $x1
356 ; LOWER: %ashr_lhs:_(s64) = COPY $x0
357 ; LOWER: %cst:_(s64) = G_CONSTANT i64 1
358 ; LOWER: %cmp_lhs:_(s64) = G_ASHR %ashr_lhs, %cst(s64)
359 ; LOWER: %cmp:_(s32) = G_ICMP intpred(sgt), %cmp_rhs(s64), %cmp_lhs
360 ; LOWER: $w0 = COPY %cmp(s32)
361 ; LOWER: RET_ReallyLR implicit $w0
362 ; SELECT-LABEL: name: swap_ashr_lhs
363 ; SELECT: liveins: $x0, $x1
364 ; SELECT: %cmp_rhs:gpr64 = COPY $x1
365 ; SELECT: %ashr_lhs:gpr64 = COPY $x0
366 ; SELECT: [[SUBSXrs:%[0-9]+]]:gpr64 = SUBSXrs %cmp_rhs, %ashr_lhs, 129, implicit-def $nzcv
367 ; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 13, implicit $nzcv
368 ; SELECT: $w0 = COPY %cmp
369 ; SELECT: RET_ReallyLR implicit $w0
370 %cmp_rhs:_(s64) = COPY $x1
372 %ashr_lhs:_(s64) = COPY $x0
373 %cst:_(s64) = G_CONSTANT i64 1
374 %cmp_lhs:_(s64) = G_ASHR %ashr_lhs, %cst(s64)
376 %cmp:_(s32) = G_ICMP intpred(slt), %cmp_lhs(s64), %cmp_rhs
378 RET_ReallyLR implicit $w0
384 tracksRegLiveness: true
389 ; LOWER-LABEL: name: swap_lshr_lhs
390 ; LOWER: liveins: $x0, $x1
391 ; LOWER: %cmp_rhs:_(s64) = COPY $x1
392 ; LOWER: %lshr_lhs:_(s64) = COPY $x0
393 ; LOWER: %cst:_(s64) = G_CONSTANT i64 1
394 ; LOWER: %cmp_lhs:_(s64) = G_LSHR %lshr_lhs, %cst(s64)
395 ; LOWER: %cmp:_(s32) = G_ICMP intpred(sgt), %cmp_rhs(s64), %cmp_lhs
396 ; LOWER: $w0 = COPY %cmp(s32)
397 ; LOWER: RET_ReallyLR implicit $w0
398 ; SELECT-LABEL: name: swap_lshr_lhs
399 ; SELECT: liveins: $x0, $x1
400 ; SELECT: %cmp_rhs:gpr64 = COPY $x1
401 ; SELECT: %lshr_lhs:gpr64 = COPY $x0
402 ; SELECT: [[SUBSXrs:%[0-9]+]]:gpr64 = SUBSXrs %cmp_rhs, %lshr_lhs, 65, implicit-def $nzcv
403 ; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 13, implicit $nzcv
404 ; SELECT: $w0 = COPY %cmp
405 ; SELECT: RET_ReallyLR implicit $w0
406 %cmp_rhs:_(s64) = COPY $x1
408 %lshr_lhs:_(s64) = COPY $x0
409 %cst:_(s64) = G_CONSTANT i64 1
410 %cmp_lhs:_(s64) = G_LSHR %lshr_lhs, %cst(s64)
412 %cmp:_(s32) = G_ICMP intpred(slt), %cmp_lhs(s64), %cmp_rhs
414 RET_ReallyLR implicit $w0
418 name: dont_swap_shift_s64_cst_too_large
420 tracksRegLiveness: true
425 ; Constant for the shift must be <= 63.
427 ; LOWER-LABEL: name: dont_swap_shift_s64_cst_too_large
428 ; LOWER: liveins: $x0, $x1
429 ; LOWER: %cmp_rhs:_(s64) = COPY $x1
430 ; LOWER: %shl_lhs:_(s64) = COPY $x0
431 ; LOWER: %too_large:_(s64) = G_CONSTANT i64 64
432 ; LOWER: %cmp_lhs:_(s64) = G_SHL %shl_lhs, %too_large(s64)
433 ; LOWER: %cmp:_(s32) = G_ICMP intpred(slt), %cmp_lhs(s64), %cmp_rhs
434 ; LOWER: $w0 = COPY %cmp(s32)
435 ; LOWER: RET_ReallyLR implicit $w0
436 ; SELECT-LABEL: name: dont_swap_shift_s64_cst_too_large
437 ; SELECT: liveins: $x0, $x1
438 ; SELECT: %cmp_rhs:gpr64 = COPY $x1
439 ; SELECT: %shl_lhs:gpr64 = COPY $x0
440 ; SELECT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 64
441 ; SELECT: %too_large:gpr64 = SUBREG_TO_REG 0, [[MOVi32imm]], %subreg.sub_32
442 ; SELECT: %cmp_lhs:gpr64 = LSLVXr %shl_lhs, %too_large
443 ; SELECT: [[SUBSXrr:%[0-9]+]]:gpr64 = SUBSXrr %cmp_lhs, %cmp_rhs, implicit-def $nzcv
444 ; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 10, implicit $nzcv
445 ; SELECT: $w0 = COPY %cmp
446 ; SELECT: RET_ReallyLR implicit $w0
447 %cmp_rhs:_(s64) = COPY $x1
449 %shl_lhs:_(s64) = COPY $x0
450 %too_large:_(s64) = G_CONSTANT i64 64
451 %cmp_lhs:_(s64) = G_SHL %shl_lhs, %too_large(s64)
453 %cmp:_(s32) = G_ICMP intpred(slt), %cmp_lhs(s64), %cmp_rhs
455 RET_ReallyLR implicit $w0
460 name: dont_swap_shift_s32_cst_too_large
462 tracksRegLiveness: true
467 ; Constant for the shift must be <= 32.
469 ; LOWER-LABEL: name: dont_swap_shift_s32_cst_too_large
470 ; LOWER: liveins: $w0, $w1
471 ; LOWER: %cmp_rhs:_(s32) = COPY $w1
472 ; LOWER: %shl_lhs:_(s32) = COPY $w0
473 ; LOWER: %cst:_(s32) = G_CONSTANT i32 32
474 ; LOWER: %cmp_lhs:_(s32) = G_SHL %shl_lhs, %cst(s32)
475 ; LOWER: %cmp:_(s32) = G_ICMP intpred(slt), %cmp_lhs(s32), %cmp_rhs
476 ; LOWER: $w0 = COPY %cmp(s32)
477 ; LOWER: RET_ReallyLR implicit $w0
478 ; SELECT-LABEL: name: dont_swap_shift_s32_cst_too_large
479 ; SELECT: liveins: $w0, $w1
480 ; SELECT: %cmp_rhs:gpr32 = COPY $w1
481 ; SELECT: %shl_lhs:gpr32 = COPY $w0
482 ; SELECT: %cst:gpr32 = MOVi32imm 32
483 ; SELECT: %cmp_lhs:gpr32 = LSLVWr %shl_lhs, %cst
484 ; SELECT: [[SUBSWrr:%[0-9]+]]:gpr32 = SUBSWrr %cmp_lhs, %cmp_rhs, implicit-def $nzcv
485 ; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 10, implicit $nzcv
486 ; SELECT: $w0 = COPY %cmp
487 ; SELECT: RET_ReallyLR implicit $w0
488 %cmp_rhs:_(s32) = COPY $w1
490 %shl_lhs:_(s32) = COPY $w0
491 %cst:_(s32) = G_CONSTANT i32 32
492 %cmp_lhs:_(s32) = G_SHL %shl_lhs, %cst(s32)
494 %cmp:_(s32) = G_ICMP intpred(slt), %cmp_lhs(s32), %cmp_rhs
496 RET_ReallyLR implicit $w0
500 name: dont_swap_cmn_lhs_no_folding_opportunities
502 tracksRegLiveness: true
507 ; No reason to swap a CMN on the LHS when it won't introduce a constant
508 ; folding opportunity. We can recognise CMNs on the LHS and RHS, so there's
509 ; nothing to gain here.
511 ; LOWER-LABEL: name: dont_swap_cmn_lhs_no_folding_opportunities
512 ; LOWER: liveins: $x0, $x1
513 ; LOWER: %cmp_rhs:_(s64) = COPY $x1
514 ; LOWER: %sub_rhs:_(s64) = COPY $x0
515 ; LOWER: %zero:_(s64) = G_CONSTANT i64 0
516 ; LOWER: %cmp_lhs:_(s64) = G_SUB %zero, %sub_rhs
517 ; LOWER: %cmp:_(s32) = G_ICMP intpred(ne), %cmp_lhs(s64), %cmp_rhs
518 ; LOWER: $w0 = COPY %cmp(s32)
519 ; LOWER: RET_ReallyLR implicit $w0
520 ; SELECT-LABEL: name: dont_swap_cmn_lhs_no_folding_opportunities
521 ; SELECT: liveins: $x0, $x1
522 ; SELECT: %cmp_rhs:gpr64 = COPY $x1
523 ; SELECT: %sub_rhs:gpr64 = COPY $x0
524 ; SELECT: [[ADDSXrr:%[0-9]+]]:gpr64 = ADDSXrr %sub_rhs, %cmp_rhs, implicit-def $nzcv
525 ; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 0, implicit $nzcv
526 ; SELECT: $w0 = COPY %cmp
527 ; SELECT: RET_ReallyLR implicit $w0
528 %cmp_rhs:_(s64) = COPY $x1
530 %sub_rhs:_(s64) = COPY $x0
531 %zero:_(s64) = G_CONSTANT i64 0
532 %cmp_lhs:_(s64) = G_SUB %zero, %sub_rhs
534 %cmp:_(s32) = G_ICMP intpred(ne), %cmp_lhs(s64), %cmp_rhs
536 RET_ReallyLR implicit $w0
542 tracksRegLiveness: true
547 ; Swap when we can see a constant folding opportunity through the sub on
551 ; LOWER-LABEL: name: swap_cmn_lhs
552 ; LOWER: liveins: $x0, $x1
553 ; LOWER: %cmp_rhs:_(s64) = COPY $x1
554 ; LOWER: %shl_lhs:_(s64) = COPY $x0
555 ; LOWER: %zero:_(s64) = G_CONSTANT i64 0
556 ; LOWER: %cst:_(s64) = G_CONSTANT i64 63
557 ; LOWER: %sub_rhs:_(s64) = G_SHL %shl_lhs, %cst(s64)
558 ; LOWER: %cmp_lhs:_(s64) = G_SUB %zero, %sub_rhs
559 ; LOWER: %cmp:_(s32) = G_ICMP intpred(ne), %cmp_rhs(s64), %cmp_lhs
560 ; LOWER: $w0 = COPY %cmp(s32)
561 ; LOWER: RET_ReallyLR implicit $w0
562 ; SELECT-LABEL: name: swap_cmn_lhs
563 ; SELECT: liveins: $x0, $x1
564 ; SELECT: %cmp_rhs:gpr64 = COPY $x1
565 ; SELECT: %shl_lhs:gpr64 = COPY $x0
566 ; SELECT: [[ADDSXrs:%[0-9]+]]:gpr64 = ADDSXrs %cmp_rhs, %shl_lhs, 63, implicit-def $nzcv
567 ; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 0, implicit $nzcv
568 ; SELECT: $w0 = COPY %cmp
569 ; SELECT: RET_ReallyLR implicit $w0
570 %cmp_rhs:_(s64) = COPY $x1
572 %shl_lhs:_(s64) = COPY $x0
573 %zero:_(s64) = G_CONSTANT i64 0
574 %cst:_(s64) = G_CONSTANT i64 63
575 %sub_rhs:_(s64) = G_SHL %shl_lhs, %cst(s64)
576 %cmp_lhs:_(s64) = G_SUB %zero, %sub_rhs
578 %cmp:_(s32) = G_ICMP intpred(ne), %cmp_lhs(s64), %cmp_rhs
580 RET_ReallyLR implicit $w0
584 name: dont_swap_cmn_lhs_when_rhs_more_profitable
586 tracksRegLiveness: true
591 ; Don't swap when the RHS's subtract offers a better constant folding
592 ; opportunity than the LHS's subtract.
594 ; In this case, the RHS has a supported extend, plus a shift with a constant
597 ; LOWER-LABEL: name: dont_swap_cmn_lhs_when_rhs_more_profitable
598 ; LOWER: liveins: $x0, $x1
599 ; LOWER: %zero:_(s64) = G_CONSTANT i64 0
600 ; LOWER: %reg0:_(s64) = COPY $x0
601 ; LOWER: %shl_cst:_(s64) = G_CONSTANT i64 63
602 ; LOWER: %shl:_(s64) = G_SHL %reg0, %shl_cst(s64)
603 ; LOWER: %cmp_lhs:_(s64) = G_SUB %zero, %shl
604 ; LOWER: %reg1:_(s64) = COPY $x1
605 ; LOWER: %sext_in_reg:_(s64) = G_SEXT_INREG %reg1, 1
606 ; LOWER: %ashr_cst:_(s64) = G_CONSTANT i64 3
607 ; LOWER: %ashr:_(s64) = G_ASHR %sext_in_reg, %ashr_cst(s64)
608 ; LOWER: %cmp_rhs:_(s64) = G_SUB %zero, %ashr
609 ; LOWER: %cmp:_(s32) = G_ICMP intpred(eq), %cmp_lhs(s64), %cmp_rhs
610 ; LOWER: $w0 = COPY %cmp(s32)
611 ; LOWER: RET_ReallyLR implicit $w0
612 ; SELECT-LABEL: name: dont_swap_cmn_lhs_when_rhs_more_profitable
613 ; SELECT: liveins: $x0, $x1
614 ; SELECT: %reg0:gpr64 = COPY $x0
615 ; SELECT: %shl:gpr64 = UBFMXri %reg0, 1, 0
616 ; SELECT: %zero:gpr64 = COPY $xzr
617 ; SELECT: %reg1:gpr64 = COPY $x1
618 ; SELECT: %sext_in_reg:gpr64 = SBFMXri %reg1, 0, 0
619 ; SELECT: %cmp_rhs:gpr64 = SUBSXrs %zero, %sext_in_reg, 131, implicit-def $nzcv
620 ; SELECT: [[ADDSXrr:%[0-9]+]]:gpr64 = ADDSXrr %shl, %cmp_rhs, implicit-def $nzcv
621 ; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 1, implicit $nzcv
622 ; SELECT: $w0 = COPY %cmp
623 ; SELECT: RET_ReallyLR implicit $w0
624 %zero:_(s64) = G_CONSTANT i64 0
626 %reg0:_(s64) = COPY $x0
627 %shl_cst:_(s64) = G_CONSTANT i64 63
628 %shl:_(s64) = G_SHL %reg0, %shl_cst(s64)
629 %cmp_lhs:_(s64) = G_SUB %zero, %shl
631 %reg1:_(s64) = COPY $x1
632 %sext_in_reg:_(s64) = G_SEXT_INREG %reg1, 1
633 %ashr_cst:_(s64) = G_CONSTANT i64 3
634 %ashr:_(s64) = G_ASHR %sext_in_reg, %ashr_cst(s64)
635 %cmp_rhs:_(s64) = G_SUB %zero, %ashr
637 %cmp:_(s32) = G_ICMP intpred(eq), %cmp_lhs(s64), %cmp_rhs
639 RET_ReallyLR implicit $w0
643 name: dont_swap_rhs_with_supported_extend
645 tracksRegLiveness: true
649 ; The RHS offers more constant folding opportunities than the LHS.
651 ; LOWER-LABEL: name: dont_swap_rhs_with_supported_extend
652 ; LOWER: liveins: $x0, $x1
653 ; LOWER: %reg0:_(s64) = COPY $x0
654 ; LOWER: %lhs_cst:_(s64) = G_CONSTANT i64 1
655 ; LOWER: %cmp_lhs:_(s64) = G_SHL %reg0, %lhs_cst(s64)
656 ; LOWER: %reg1:_(s64) = COPY $x1
657 ; LOWER: %and_mask:_(s64) = G_CONSTANT i64 255
658 ; LOWER: %and:_(s64) = G_AND %reg1, %and_mask
659 ; LOWER: %rhs_cst:_(s64) = G_CONSTANT i64 1
660 ; LOWER: %cmp_rhs:_(s64) = G_ASHR %and, %rhs_cst(s64)
661 ; LOWER: %cmp:_(s32) = G_ICMP intpred(slt), %cmp_lhs(s64), %cmp_rhs
662 ; LOWER: $w0 = COPY %cmp(s32)
663 ; LOWER: RET_ReallyLR implicit $w0
664 ; SELECT-LABEL: name: dont_swap_rhs_with_supported_extend
665 ; SELECT: liveins: $x0, $x1
666 ; SELECT: %reg0:gpr64 = COPY $x0
667 ; SELECT: %cmp_lhs:gpr64 = UBFMXri %reg0, 63, 62
668 ; SELECT: %reg1:gpr64 = COPY $x1
669 ; SELECT: %and:gpr64common = ANDXri %reg1, 4103
670 ; SELECT: [[SUBSXrs:%[0-9]+]]:gpr64 = SUBSXrs %cmp_lhs, %and, 129, implicit-def $nzcv
671 ; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 10, implicit $nzcv
672 ; SELECT: $w0 = COPY %cmp
673 ; SELECT: RET_ReallyLR implicit $w0
674 %reg0:_(s64) = COPY $x0
675 %lhs_cst:_(s64) = G_CONSTANT i64 1
676 %cmp_lhs:_(s64) = G_SHL %reg0, %lhs_cst(s64)
678 %reg1:_(s64) = COPY $x1
679 %and_mask:_(s64) = G_CONSTANT i64 255
680 %and:_(s64) = G_AND %reg1, %and_mask(s64)
681 %rhs_cst:_(s64) = G_CONSTANT i64 1
682 %cmp_rhs:_(s64) = G_ASHR %and, %rhs_cst(s64)
684 %cmp:_(s32) = G_ICMP intpred(slt), %cmp_lhs(s64), %cmp_rhs
686 RET_ReallyLR implicit $w0
691 name: swap_rhs_with_supported_extend
693 tracksRegLiveness: true
698 ; In this case, both the LHS and RHS are fed by a supported extend. However,
699 ; the LHS' shift has a constant <= 4. This makes it more profitable, so
700 ; we should swap the operands.
702 ; LOWER-LABEL: name: swap_rhs_with_supported_extend
703 ; LOWER: liveins: $x0, $x1
704 ; LOWER: %reg0:_(s64) = COPY $x0
705 ; LOWER: %and_mask:_(s64) = G_CONSTANT i64 255
706 ; LOWER: %and:_(s64) = G_AND %reg0, %and_mask
707 ; LOWER: %lhs_cst:_(s64) = G_CONSTANT i64 1
708 ; LOWER: %cmp_lhs:_(s64) = G_SHL %and, %lhs_cst(s64)
709 ; LOWER: %rhs_cst:_(s64) = G_CONSTANT i64 5
710 ; LOWER: %cmp_rhs:_(s64) = G_ASHR %and, %rhs_cst(s64)
711 ; LOWER: %cmp:_(s32) = G_ICMP intpred(slt), %cmp_rhs(s64), %cmp_lhs
712 ; LOWER: $w0 = COPY %cmp(s32)
713 ; LOWER: RET_ReallyLR implicit $w0
714 ; SELECT-LABEL: name: swap_rhs_with_supported_extend
715 ; SELECT: liveins: $x0, $x1
716 ; SELECT: %reg0:gpr64 = COPY $x0
717 ; SELECT: %and:gpr64common = ANDXri %reg0, 4103
718 ; SELECT: [[COPY:%[0-9]+]]:gpr32all = COPY %reg0.sub_32
719 ; SELECT: [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]]
720 ; SELECT: %cmp_rhs:gpr64common = SBFMXri %and, 5, 63
721 ; SELECT: [[SUBSXrx:%[0-9]+]]:gpr64 = SUBSXrx %cmp_rhs, [[COPY1]], 1, implicit-def $nzcv
722 ; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 10, implicit $nzcv
723 ; SELECT: $w0 = COPY %cmp
724 ; SELECT: RET_ReallyLR implicit $w0
725 %reg0:_(s64) = COPY $x0
726 %and_mask:_(s64) = G_CONSTANT i64 255
727 %and:_(s64) = G_AND %reg0, %and_mask(s64)
729 %lhs_cst:_(s64) = G_CONSTANT i64 1
730 %cmp_lhs:_(s64) = G_SHL %and, %lhs_cst(s64)
732 %rhs_cst:_(s64) = G_CONSTANT i64 5
733 %cmp_rhs:_(s64) = G_ASHR %and, %rhs_cst(s64)
735 %cmp:_(s32) = G_ICMP intpred(sgt), %cmp_lhs(s64), %cmp_rhs
737 RET_ReallyLR implicit $w0