Skip to content

Commit 27d7956

Browse files
committed
[AArch64] Use isKnownNonZero to optimize to cmn instead of cmp
1 parent 9ba051d commit 27d7956

File tree

2 files changed

+9
-8
lines changed

2 files changed

+9
-8
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3372,9 +3372,10 @@ static bool isLegalArithImmed(uint64_t C) {
33723372
// So, finally, the only LLVM-native comparisons that don't mention C and V
33733373
// are SETEQ and SETNE. They're the only ones we can safely use CMN for in
33743374
// the absence of information about op2.
3375-
static bool isCMN(SDValue Op, ISD::CondCode CC) {
3375+
static bool isCMN(SDValue Op, ISD::CondCode CC, SelectionDAG &DAG) {
33763376
return Op.getOpcode() == ISD::SUB && isNullConstant(Op.getOperand(0)) &&
3377-
(CC == ISD::SETEQ || CC == ISD::SETNE);
3377+
(CC == ISD::SETEQ || CC == ISD::SETNE ||
3378+
DAG.isKnownNeverZero(Op.getOperand(1)));
33783379
}
33793380

33803381
static SDValue emitStrictFPComparison(SDValue LHS, SDValue RHS, const SDLoc &dl,
@@ -3419,11 +3420,11 @@ static SDValue emitComparison(SDValue LHS, SDValue RHS, ISD::CondCode CC,
34193420
// register to WZR/XZR if it ends up being unused.
34203421
unsigned Opcode = AArch64ISD::SUBS;
34213422

3422-
if (isCMN(RHS, CC)) {
3423+
if (isCMN(RHS, CC, DAG)) {
34233424
// Can we combine a (CMP op1, (sub 0, op2) into a CMN instruction ?
34243425
Opcode = AArch64ISD::ADDS;
34253426
RHS = RHS.getOperand(1);
3426-
} else if (isCMN(LHS, CC)) {
3427+
} else if (isCMN(LHS, CC, DAG)) {
34273428
// As we are looking for EQ/NE compares, the operands can be commuted ; can
34283429
// we combine a (CMP (sub 0, op1), op2) into a CMN instruction ?
34293430
Opcode = AArch64ISD::ADDS;
@@ -3527,7 +3528,8 @@ static SDValue emitConditionalComparison(SDValue LHS, SDValue RHS,
35273528
}
35283529
} else if (RHS.getOpcode() == ISD::SUB) {
35293530
SDValue SubOp0 = RHS.getOperand(0);
3530-
if (isNullConstant(SubOp0) && (CC == ISD::SETEQ || CC == ISD::SETNE)) {
3531+
if (isNullConstant(SubOp0) && (CC == ISD::SETEQ || CC == ISD::SETNE ||
3532+
DAG.isKnownNeverZero(RHS.getOperand(1)))) {
35313533
// See emitComparison() on why we can only do this for SETEQ and SETNE.
35323534
Opcode = AArch64ISD::CCMN;
35333535
RHS = RHS.getOperand(1);
@@ -3848,7 +3850,7 @@ static SDValue getAArch64Cmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
38483850
// can be turned into:
38493851
// cmp w12, w11, lsl #1
38503852
if (!isa<ConstantSDNode>(RHS) || !isLegalArithImmed(RHS->getAsZExtVal())) {
3851-
SDValue TheLHS = isCMN(LHS, CC) ? LHS.getOperand(1) : LHS;
3853+
SDValue TheLHS = isCMN(LHS, CC, DAG) ? LHS.getOperand(1) : LHS;
38523854

38533855
if (getCmpOperandFoldingProfit(TheLHS) > getCmpOperandFoldingProfit(RHS)) {
38543856
std::swap(LHS, RHS);

llvm/test/CodeGen/AArch64/cmp-chains.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,7 @@ define i32 @neg_range_int_cmn(i32 %a, i32 %b, i32 %c) {
263263
; SDISEL-LABEL: neg_range_int_cmn:
264264
; SDISEL: // %bb.0:
265265
; SDISEL-NEXT: orr w8, w2, #0x1
266-
; SDISEL-NEXT: neg w8, w8
267-
; SDISEL-NEXT: cmp w8, w0
266+
; SDISEL-NEXT: cmn w8, w0
268267
; SDISEL-NEXT: ccmn w1, #3, #0, le
269268
; SDISEL-NEXT: csel w0, w1, w0, gt
270269
; SDISEL-NEXT: ret

0 commit comments

Comments
 (0)