Skip to content

Commit 971a80c

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 3162b71 commit 971a80c

File tree

5 files changed

+46
-30
lines changed

5 files changed

+46
-30
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3338,8 +3338,6 @@ static bool isLegalArithImmed(uint64_t C) {
33383338
}
33393339

33403340
bool isLegalCmpImmed(APInt C) {
3341-
if (C.isMinSignedValue())
3342-
return false;
33433341
// Works for negative immediates too, as it can be written as an ADDS
33443342
// instruction with a negated immediate.
33453343
return isLegalArithImmed(C.abs().getZExtValue());
@@ -3770,13 +3768,40 @@ static unsigned getCmpOperandFoldingProfit(SDValue Op) {
37703768
return 0;
37713769
}
37723770

3771+
// emitComparison() converts comparison with one or negative one to comparison
3772+
// with 0. Note that this only works for signed comparisons because of how ANDS
3773+
// works.
3774+
static bool shouldBeAdjustedToZero(SDValue LHS, APInt C, ISD::CondCode &CC) {
3775+
// Only works for ANDS and AND.
3776+
if (LHS.getOpcode() != ISD::AND && LHS.getOpcode() != AArch64ISD::ANDS)
3777+
return false;
3778+
3779+
if (C.isOne() && (CC == ISD::SETLT || CC == ISD::SETGE)) {
3780+
CC = (CC == ISD::SETLT) ? ISD::SETLE : ISD::SETGT;
3781+
return true;
3782+
}
3783+
3784+
if (C.isAllOnes() && (CC == ISD::SETLE || CC == ISD::SETGT)) {
3785+
CC = (CC == ISD::SETLE) ? ISD::SETLT : ISD::SETGE;
3786+
return true;
3787+
}
3788+
3789+
return false;
3790+
}
3791+
37733792
static SDValue getAArch64Cmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
37743793
SDValue &AArch64cc, SelectionDAG &DAG,
37753794
const SDLoc &dl) {
37763795
if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS.getNode())) {
37773796
EVT VT = RHS.getValueType();
37783797
APInt C = RHSC->getAPIntValue();
3779-
if (!isLegalCmpImmed(C)) {
3798+
// shouldBeAdjustedToZero is a special case to better fold with
3799+
// emitComparison().
3800+
if (shouldBeAdjustedToZero(LHS, C, CC)) {
3801+
// Adjust the constant to zero.
3802+
// CC has already been adjusted.
3803+
RHS = DAG.getConstant(0, dl, VT);
3804+
} else if (!isLegalCmpImmed(C)) {
37803805
// Constant does not fit, try adjusting it by one?
37813806
switch (CC) {
37823807
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

llvm/test/CodeGen/AArch64/tbz-tbnz.ll

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -199,16 +199,14 @@ if.end:
199199
define void @test8(i64 %val1, i64 %val2, i64 %val3) {
200200
; CHECK-SD-LABEL: test8:
201201
; CHECK-SD: // %bb.0:
202-
; CHECK-SD-NEXT: and x8, x0, x1
203-
; CHECK-SD-NEXT: cmn x8, #1
204-
; CHECK-SD-NEXT: b.gt .LBB7_3
202+
; CHECK-SD-NEXT: tst x0, x1
203+
; CHECK-SD-NEXT: b.ge .LBB7_3
205204
; CHECK-SD-NEXT: // %bb.1:
206205
; CHECK-SD-NEXT: and x8, x1, x2
207206
; CHECK-SD-NEXT: tbnz x8, #63, .LBB7_3
208207
; CHECK-SD-NEXT: // %bb.2: // %if.then2
209-
; CHECK-SD-NEXT: and x8, x0, x1, lsl #63
210-
; CHECK-SD-NEXT: cmn x8, #1
211-
; CHECK-SD-NEXT: b.le .LBB7_4
208+
; CHECK-SD-NEXT: tst x0, x1, lsl #63
209+
; CHECK-SD-NEXT: b.lt .LBB7_4
212210
; CHECK-SD-NEXT: .LBB7_3: // %if.end
213211
; CHECK-SD-NEXT: ret
214212
; CHECK-SD-NEXT: .LBB7_4: // %if.then3

0 commit comments

Comments
 (0)