Skip to content

Commit 85e41fc

Browse files
committed
[AArch64] Select to CCMN when the CCMP's second operator is negative constant
CCMP/CCMN's second operator support const from 0 to 31. When the CCMP's second operator is in the range [-31, -1] we can replace it with CCMN to avoid extra mov. Fix: #57034 Reviewed By: efriedma Differential Revision: https://reviews.llvm.org/D135939
1 parent 6d252a4 commit 85e41fc

File tree

2 files changed

+23
-18
lines changed

2 files changed

+23
-18
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15458,21 +15458,32 @@ static SDValue performANDORCSELCombine(SDNode *N, SelectionDAG &DAG) {
1545815458
return SDValue();
1545915459

1546015460
SDLoc DL(N);
15461-
SDValue CCmp;
15461+
SDValue CCmp, Condition;
15462+
unsigned NZCV;
1546215463

1546315464
if (N->getOpcode() == ISD::AND) {
1546415465
AArch64CC::CondCode InvCC0 = AArch64CC::getInvertedCondCode(CC0);
15465-
SDValue Condition = DAG.getConstant(InvCC0, DL, MVT_CC);
15466-
unsigned NZCV = AArch64CC::getNZCVToSatisfyCondCode(CC1);
15467-
SDValue NZCVOp = DAG.getConstant(NZCV, DL, MVT::i32);
15468-
CCmp = DAG.getNode(AArch64ISD::CCMP, DL, MVT_CC, Cmp1.getOperand(0),
15469-
Cmp1.getOperand(1), NZCVOp, Condition, Cmp0);
15466+
Condition = DAG.getConstant(InvCC0, DL, MVT_CC);
15467+
NZCV = AArch64CC::getNZCVToSatisfyCondCode(CC1);
1547015468
} else {
15471-
SDLoc DL(N);
1547215469
AArch64CC::CondCode InvCC1 = AArch64CC::getInvertedCondCode(CC1);
15473-
SDValue Condition = DAG.getConstant(CC0, DL, MVT_CC);
15474-
unsigned NZCV = AArch64CC::getNZCVToSatisfyCondCode(InvCC1);
15475-
SDValue NZCVOp = DAG.getConstant(NZCV, DL, MVT::i32);
15470+
Condition = DAG.getConstant(CC0, DL, MVT_CC);
15471+
NZCV = AArch64CC::getNZCVToSatisfyCondCode(InvCC1);
15472+
}
15473+
15474+
SDValue NZCVOp = DAG.getConstant(NZCV, DL, MVT::i32);
15475+
15476+
auto *Op1 = dyn_cast<ConstantSDNode>(Cmp1.getOperand(1));
15477+
if (Op1 && Op1->getAPIntValue().isNegative() &&
15478+
Op1->getAPIntValue().sgt(-32)) {
15479+
// CCMP accept the constant int the range [0, 31]
15480+
// if the Op1 is a constant in the range [-31, -1], we
15481+
// can select to CCMN to avoid the extra mov
15482+
SDValue AbsOp1 =
15483+
DAG.getConstant(Op1->getAPIntValue().abs(), DL, Op1->getValueType(0));
15484+
CCmp = DAG.getNode(AArch64ISD::CCMN, DL, MVT_CC, Cmp1.getOperand(0), AbsOp1,
15485+
NZCVOp, Condition, Cmp0);
15486+
} else {
1547615487
CCmp = DAG.getNode(AArch64ISD::CCMP, DL, MVT_CC, Cmp1.getOperand(0),
1547715488
Cmp1.getOperand(1), NZCVOp, Condition, Cmp0);
1547815489
}

llvm/test/CodeGen/AArch64/arm64-ccmp.ll

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,14 +1194,11 @@ entry:
11941194
}
11951195
declare i32 @callee(i32)
11961196

1197-
; FIXME: mov w8, #-2 + ccmp w1, w8, #0, eq
1198-
; --> ccmn w1, #2, #0, eq
11991197
define i1 @cmp_and_negative_const(i32 %0, i32 %1) {
12001198
; SDISEL-LABEL: cmp_and_negative_const:
12011199
; SDISEL: ; %bb.0:
12021200
; SDISEL-NEXT: cmn w0, #1
1203-
; SDISEL-NEXT: mov w8, #-2
1204-
; SDISEL-NEXT: ccmp w1, w8, #0, eq
1201+
; SDISEL-NEXT: ccmn w1, #2, #0, eq
12051202
; SDISEL-NEXT: cset w0, eq
12061203
; SDISEL-NEXT: ret
12071204
;
@@ -1219,14 +1216,11 @@ define i1 @cmp_and_negative_const(i32 %0, i32 %1) {
12191216
ret i1 %5
12201217
}
12211218

1222-
; FIXME: mov w8, #-2 + ccmp w1, w8, #4, ne
1223-
; --> ccmn w1, #2, #4, ne
12241219
define i1 @cmp_or_negative_const(i32 %a, i32 %b) {
12251220
; SDISEL-LABEL: cmp_or_negative_const:
12261221
; SDISEL: ; %bb.0:
12271222
; SDISEL-NEXT: cmn w0, #1
1228-
; SDISEL-NEXT: mov w8, #-2
1229-
; SDISEL-NEXT: ccmp w1, w8, #4, ne
1223+
; SDISEL-NEXT: ccmn w1, #2, #4, ne
12301224
; SDISEL-NEXT: cset w0, eq
12311225
; SDISEL-NEXT: ret
12321226
;

0 commit comments

Comments
 (0)