Skip to content

Commit 3359ac6

Browse files
committed
[AArch64] Convert comparisons with 1 and -1 to 0 if it is profitable
This relies on the fact that we can use tst and ands for comparisons as by emitComparison. Relies on #140999. Fixes: #141137
1 parent 4fff569 commit 3359ac6

File tree

5 files changed

+107
-262
lines changed

5 files changed

+107
-262
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4082,13 +4082,39 @@ static unsigned getCmpOperandFoldingProfit(SDValue Op) {
40824082
return 0;
40834083
}
40844084

4085+
// emitComparison() converts comparison with one or negative one to comparison
4086+
// with 0.
4087+
static bool shouldBeAdjustedToZero(SDValue LHS, int64_t C, ISD::CondCode CC) {
4088+
// Only works for not signed values.
4089+
if (isUnsignedIntSetCC(CC))
4090+
return false;
4091+
// Only works for ANDS and AND.
4092+
if (LHS.getOpcode() != ISD::AND && LHS.getOpcode() != AArch64ISD::ANDS)
4093+
return false;
4094+
if (C == 1 && (CC == ISD::SETLT || CC == ISD::SETGE))
4095+
return true;
4096+
if (C == -1 && (CC == ISD::SETLE || CC == ISD::SETGT))
4097+
return true;
4098+
4099+
return false;
4100+
}
4101+
40854102
static SDValue getAArch64Cmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
40864103
SDValue &AArch64cc, SelectionDAG &DAG,
40874104
const SDLoc &dl) {
40884105
if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS.getNode())) {
40894106
EVT VT = RHS.getValueType();
40904107
int64_t C = RHSC->getSExtValue();
4091-
if (!isLegalCmpImmed(C)) {
4108+
// This is a special case to better fold with emitComparison().
4109+
if (shouldBeAdjustedToZero(LHS, C, CC)) {
4110+
if (C == 1) {
4111+
CC = (CC == ISD::SETLT) ? ISD::SETLE : ISD::SETGT;
4112+
} else {
4113+
// C is -1
4114+
CC = (CC == ISD::SETLE) ? ISD::SETLT : ISD::SETGE;
4115+
}
4116+
RHS = DAG.getConstant(0, dl, VT);
4117+
} else if (!isLegalCmpImmed(C)) {
40924118
// Constant does not fit, try adjusting it by one?
40934119
switch (CC) {
40944120
default:

llvm/test/CodeGen/AArch64/fptosi-sat-scalar.ll

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@ define i1 @test_signed_i1_f32(float %f) nounwind {
2323
; CHECK-SD-LABEL: test_signed_i1_f32:
2424
; CHECK-SD: // %bb.0:
2525
; CHECK-SD-NEXT: fcvtzs w8, s0
26-
; CHECK-SD-NEXT: and w8, w8, w8, asr #31
27-
; CHECK-SD-NEXT: cmn w8, #1
28-
; CHECK-SD-NEXT: csinv w8, w8, wzr, gt
26+
; CHECK-SD-NEXT: ands w8, w8, w8, asr #31
27+
; CHECK-SD-NEXT: csinv w8, w8, wzr, ge
2928
; CHECK-SD-NEXT: and w0, w8, #0x1
3029
; CHECK-SD-NEXT: ret
3130
;
@@ -269,9 +268,8 @@ define i1 @test_signed_i1_f64(double %f) nounwind {
269268
; CHECK-SD-LABEL: test_signed_i1_f64:
270269
; CHECK-SD: // %bb.0:
271270
; CHECK-SD-NEXT: fcvtzs w8, d0
272-
; CHECK-SD-NEXT: and w8, w8, w8, asr #31
273-
; CHECK-SD-NEXT: cmn w8, #1
274-
; CHECK-SD-NEXT: csinv w8, w8, wzr, gt
271+
; CHECK-SD-NEXT: ands w8, w8, w8, asr #31
272+
; CHECK-SD-NEXT: csinv w8, w8, wzr, ge
275273
; CHECK-SD-NEXT: and w0, w8, #0x1
276274
; CHECK-SD-NEXT: ret
277275
;
@@ -520,18 +518,16 @@ define i1 @test_signed_i1_f16(half %f) nounwind {
520518
; CHECK-SD-CVT: // %bb.0:
521519
; CHECK-SD-CVT-NEXT: fcvt s0, h0
522520
; CHECK-SD-CVT-NEXT: fcvtzs w8, s0
523-
; CHECK-SD-CVT-NEXT: and w8, w8, w8, asr #31
524-
; CHECK-SD-CVT-NEXT: cmn w8, #1
525-
; CHECK-SD-CVT-NEXT: csinv w8, w8, wzr, gt
521+
; CHECK-SD-CVT-NEXT: ands w8, w8, w8, asr #31
522+
; CHECK-SD-CVT-NEXT: csinv w8, w8, wzr, ge
526523
; CHECK-SD-CVT-NEXT: and w0, w8, #0x1
527524
; CHECK-SD-CVT-NEXT: ret
528525
;
529526
; CHECK-SD-FP16-LABEL: test_signed_i1_f16:
530527
; CHECK-SD-FP16: // %bb.0:
531528
; CHECK-SD-FP16-NEXT: fcvtzs w8, h0
532-
; CHECK-SD-FP16-NEXT: and w8, w8, w8, asr #31
533-
; CHECK-SD-FP16-NEXT: cmn w8, #1
534-
; CHECK-SD-FP16-NEXT: csinv w8, w8, wzr, gt
529+
; CHECK-SD-FP16-NEXT: ands w8, w8, w8, asr #31
530+
; CHECK-SD-FP16-NEXT: csinv w8, w8, wzr, ge
535531
; CHECK-SD-FP16-NEXT: and w0, w8, #0x1
536532
; CHECK-SD-FP16-NEXT: ret
537533
;

llvm/test/CodeGen/AArch64/fptosi-sat-vector.ll

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2371,12 +2371,10 @@ define <2 x i1> @test_signed_v2f64_v2i1(<2 x double> %f) {
23712371
; CHECK-SD-NEXT: mov d1, v0.d[1]
23722372
; CHECK-SD-NEXT: fcvtzs w9, d0
23732373
; CHECK-SD-NEXT: fcvtzs w8, d1
2374-
; CHECK-SD-NEXT: and w9, w9, w9, asr #31
2375-
; CHECK-SD-NEXT: and w8, w8, w8, asr #31
2376-
; CHECK-SD-NEXT: cmn w8, #1
2377-
; CHECK-SD-NEXT: csinv w8, w8, wzr, gt
2378-
; CHECK-SD-NEXT: cmn w9, #1
2379-
; CHECK-SD-NEXT: csinv w9, w9, wzr, gt
2374+
; CHECK-SD-NEXT: ands w8, w8, w8, asr #31
2375+
; CHECK-SD-NEXT: csinv w8, w8, wzr, ge
2376+
; CHECK-SD-NEXT: ands w9, w9, w9, asr #31
2377+
; CHECK-SD-NEXT: csinv w9, w9, wzr, ge
23802378
; CHECK-SD-NEXT: fmov s0, w9
23812379
; CHECK-SD-NEXT: mov v0.s[1], w8
23822380
; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0

llvm/test/CodeGen/AArch64/logical_shifted_reg.ll

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,8 @@ define void @flag_setting() {
257257
; CHECK-NEXT: tst x9, x10, lsl #63
258258
; CHECK-NEXT: b.lt .LBB2_4
259259
; CHECK-NEXT: // %bb.2: // %test3
260-
; CHECK-NEXT: and x10, x9, x10, asr #12
261-
; CHECK-NEXT: cmp x10, #1
262-
; CHECK-NEXT: b.ge .LBB2_4
260+
; CHECK-NEXT: tst x9, x10, asr #12
261+
; CHECK-NEXT: b.gt .LBB2_4
263262
; CHECK-NEXT: // %bb.3: // %other_exit
264263
; CHECK-NEXT: str x9, [x8]
265264
; CHECK-NEXT: .LBB2_4: // %common.ret

0 commit comments

Comments
 (0)