@@ -3394,9 +3394,11 @@ static bool isLegalArithImmed(uint64_t C) {
3394
3394
// So, finally, the only LLVM-native comparisons that don't mention C and V
3395
3395
// are SETEQ and SETNE. They're the only ones we can safely use CMN for in
3396
3396
// the absence of information about op2.
3397
- static bool isCMN(SDValue Op, ISD::CondCode CC) {
3397
+ static bool isCMN(SDValue Op, SDValue CheckedVal, ISD::CondCode CC,
3398
+ SelectionDAG &DAG) {
3398
3399
return Op.getOpcode() == ISD::SUB && isNullConstant(Op.getOperand(0)) &&
3399
- (CC == ISD::SETEQ || CC == ISD::SETNE);
3400
+ (CC == ISD::SETEQ || CC == ISD::SETNE ||
3401
+ DAG.isKnownNeverZero(CheckedVal));
3400
3402
}
3401
3403
3402
3404
static SDValue emitStrictFPComparison(SDValue LHS, SDValue RHS, const SDLoc &dl,
@@ -3441,15 +3443,24 @@ static SDValue emitComparison(SDValue LHS, SDValue RHS, ISD::CondCode CC,
3441
3443
// register to WZR/XZR if it ends up being unused.
3442
3444
unsigned Opcode = AArch64ISD::SUBS;
3443
3445
3444
- if (isCMN(RHS, CC )) {
3446
+ if (isCMN(RHS, RHS.getOperand(1), CC, DAG )) {
3445
3447
// Can we combine a (CMP op1, (sub 0, op2) into a CMN instruction ?
3446
3448
Opcode = AArch64ISD::ADDS;
3447
3449
RHS = RHS.getOperand(1);
3448
- } else if (isCMN(LHS, CC )) {
3450
+ } else if (isCMN(LHS, RHS, CC, DAG )) {
3449
3451
// As we are looking for EQ/NE compares, the operands can be commuted ; can
3450
3452
// we combine a (CMP (sub 0, op1), op2) into a CMN instruction ?
3453
+ // Not swapping operands, but negation requires inversion
3454
+ CC = ISD::getSetCCSwappedOperands(CC);
3451
3455
Opcode = AArch64ISD::ADDS;
3452
3456
LHS = LHS.getOperand(1);
3457
+ } else if (isCMN(LHS, LHS.getOperand(1), CC, DAG)) {
3458
+ // As we are looking for EQ/NE compares, the operands can be commuted ; can
3459
+ // we combine a (CMP (sub 0, op1), op2) into a CMN instruction ?
3460
+ std::swap(LHS, RHS);
3461
+ CC = ISD::getSetCCSwappedOperands(CC);
3462
+ Opcode = AArch64ISD::ADDS;
3463
+ RHS = RHS.getOperand(1);
3453
3464
} else if (isNullConstant(RHS) && !isUnsignedIntSetCC(CC)) {
3454
3465
if (LHS.getOpcode() == ISD::AND) {
3455
3466
// Similarly, (CMP (and X, Y), 0) can be implemented with a TST
@@ -3549,11 +3560,22 @@ static SDValue emitConditionalComparison(SDValue LHS, SDValue RHS,
3549
3560
}
3550
3561
} else if (RHS.getOpcode() == ISD::SUB) {
3551
3562
SDValue SubOp0 = RHS.getOperand(0);
3552
- if (isNullConstant(SubOp0) && (CC == ISD::SETEQ || CC == ISD::SETNE)) {
3563
+ if (isNullConstant(SubOp0) && (CC == ISD::SETEQ || CC == ISD::SETNE ||
3564
+ DAG.isKnownNeverZero(RHS.getOperand(1)))) {
3553
3565
// See emitComparison() on why we can only do this for SETEQ and SETNE.
3554
3566
Opcode = AArch64ISD::CCMN;
3555
3567
RHS = RHS.getOperand(1);
3556
3568
}
3569
+ } else if (LHS.getOpcode() == ISD::SUB) {
3570
+ SDValue SubOp0 = RHS.getOperand(0);
3571
+ if (isNullConstant(SubOp0) && (CC == ISD::SETEQ || CC == ISD::SETNE ||
3572
+ DAG.isKnownNeverZero(LHS.getOperand(1)))) {
3573
+ // See emitComparison() on why we can only do this for SETEQ and SETNE.
3574
+ std::swap(LHS, RHS);
3575
+ CC = ISD::getSetCCSwappedOperands(CC);
3576
+ Opcode = AArch64ISD::CCMN;
3577
+ RHS = RHS.getOperand(1);
3578
+ }
3557
3579
}
3558
3580
if (Opcode == 0)
3559
3581
Opcode = AArch64ISD::CCMP;
@@ -3870,9 +3892,9 @@ static SDValue getAArch64Cmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
3870
3892
// can be turned into:
3871
3893
// cmp w12, w11, lsl #1
3872
3894
if (!isa<ConstantSDNode>(RHS) || !isLegalArithImmed(RHS->getAsZExtVal())) {
3873
- SDValue TheLHS = isCMN(LHS, CC ) ? LHS.getOperand(1) : LHS;
3874
-
3875
- if (getCmpOperandFoldingProfit(TheLHS) > getCmpOperandFoldingProfit(RHS )) {
3895
+ SDValue TheLHS = isCMN(LHS, LHS.getOperand(1), CC, DAG ) ? LHS.getOperand(1) : LHS;
3896
+ SDValue TheRHS = isCMN(RHS, RHS.getOperand(1), CC, DAG) ? RHS.getOperand(1) : RHS;
3897
+ if (getCmpOperandFoldingProfit(TheLHS) > getCmpOperandFoldingProfit(TheRHS )) {
3876
3898
std::swap(LHS, RHS);
3877
3899
CC = ISD::getSetCCSwappedOperands(CC);
3878
3900
}
0 commit comments