Skip to content

Commit f47f987

Browse files
committed
[AArch64] Check for immediates using isLegalICmpImmediate
We can catch negatives that can be encoded in cmn this way!
1 parent 7096ab4 commit f47f987

File tree

1 file changed

+34
-28
lines changed

1 file changed

+34
-28
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3647,6 +3647,16 @@ static bool isLegalArithImmed(uint64_t C) {
36473647
return IsLegal;
36483648
}
36493649

3650+
bool isLegalCmpImmed(int64_t Immed) {
3651+
if (Immed == std::numeric_limits<int64_t>::min()) {
3652+
LLVM_DEBUG(dbgs() << "Illegal add imm " << Immed
3653+
<< ": avoid UB for INT64_MIN\n");
3654+
return false;
3655+
}
3656+
// Same encoding for add/sub, just flip the sign.
3657+
return isLegalArithImmed((uint64_t)std::abs(Immed));
3658+
}
3659+
36503660
static bool cannotBeIntMin(SDValue CheckedVal, SelectionDAG &DAG) {
36513661
KnownBits KnownSrc = DAG.computeKnownBits(CheckedVal);
36523662
return !KnownSrc.getSignedMinValue().isMinSignedValue();
@@ -4077,52 +4087,53 @@ static SDValue getAArch64Cmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
40774087
const SDLoc &dl) {
40784088
if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS.getNode())) {
40794089
EVT VT = RHS.getValueType();
4080-
uint64_t C = RHSC->getZExtValue();
4081-
if (!isLegalArithImmed(C)) {
4090+
int64_t C = RHSC->getSExtValue();
4091+
if (!isLegalCmpImmed(C)) {
40824092
// Constant does not fit, try adjusting it by one?
40834093
switch (CC) {
40844094
default:
40854095
break;
40864096
case ISD::SETLT:
40874097
case ISD::SETGE:
4088-
if ((VT == MVT::i32 && C != 0x80000000 &&
4089-
isLegalArithImmed((uint32_t)(C - 1))) ||
4090-
(VT == MVT::i64 && C != 0x80000000ULL &&
4091-
isLegalArithImmed(C - 1ULL))) {
4098+
if ((VT == MVT::i32 && C != INT32_MIN && isLegalCmpImmed(C - 1)) ||
4099+
(VT == MVT::i64 && C != INT64_MIN && isLegalCmpImmed(C - 1))) {
40924100
CC = (CC == ISD::SETLT) ? ISD::SETLE : ISD::SETGT;
4093-
C = (VT == MVT::i32) ? (uint32_t)(C - 1) : C - 1;
4101+
C = C - 1;
4102+
if (VT == MVT::i32)
4103+
C &= 0xFFFFFFFF;
40944104
RHS = DAG.getConstant(C, dl, VT);
40954105
}
40964106
break;
40974107
case ISD::SETULT:
40984108
case ISD::SETUGE:
4099-
if ((VT == MVT::i32 && C != 0 &&
4100-
isLegalArithImmed((uint32_t)(C - 1))) ||
4101-
(VT == MVT::i64 && C != 0ULL && isLegalArithImmed(C - 1ULL))) {
4109+
if ((VT == MVT::i32 && C != 0 && isLegalCmpImmed(C - 1)) ||
4110+
(VT == MVT::i64 && C != 0 && isLegalCmpImmed(C - 1))) {
41024111
CC = (CC == ISD::SETULT) ? ISD::SETULE : ISD::SETUGT;
4103-
C = (VT == MVT::i32) ? (uint32_t)(C - 1) : C - 1;
4112+
C = C - 1;
4113+
if (VT == MVT::i32)
4114+
C &= 0xFFFFFFFF;
41044115
RHS = DAG.getConstant(C, dl, VT);
41054116
}
41064117
break;
41074118
case ISD::SETLE:
41084119
case ISD::SETGT:
4109-
if ((VT == MVT::i32 && C != INT32_MAX &&
4110-
isLegalArithImmed((uint32_t)(C + 1))) ||
4111-
(VT == MVT::i64 && C != INT64_MAX &&
4112-
isLegalArithImmed(C + 1ULL))) {
4120+
if ((VT == MVT::i32 && C != INT32_MAX && isLegalCmpImmed(C + 1)) ||
4121+
(VT == MVT::i64 && C != INT64_MAX && isLegalCmpImmed(C + 1))) {
41134122
CC = (CC == ISD::SETLE) ? ISD::SETLT : ISD::SETGE;
4114-
C = (VT == MVT::i32) ? (uint32_t)(C + 1) : C + 1;
4123+
C = C + 1;
4124+
if (VT == MVT::i32)
4125+
C &= 0xFFFFFFFF;
41154126
RHS = DAG.getConstant(C, dl, VT);
41164127
}
41174128
break;
41184129
case ISD::SETULE:
41194130
case ISD::SETUGT:
4120-
if ((VT == MVT::i32 && C != UINT32_MAX &&
4121-
isLegalArithImmed((uint32_t)(C + 1))) ||
4122-
(VT == MVT::i64 && C != UINT64_MAX &&
4123-
isLegalArithImmed(C + 1ULL))) {
4131+
if ((VT == MVT::i32 && C != -1 && isLegalCmpImmed(C + 1)) ||
4132+
(VT == MVT::i64 && C != -1 && isLegalCmpImmed(C + 1))) {
41244133
CC = (CC == ISD::SETULE) ? ISD::SETULT : ISD::SETUGE;
4125-
C = (VT == MVT::i32) ? (uint32_t)(C + 1) : C + 1;
4134+
C = C + 1;
4135+
if (VT == MVT::i32)
4136+
C &= 0xFFFFFFFF;
41264137
RHS = DAG.getConstant(C, dl, VT);
41274138
}
41284139
break;
@@ -4141,7 +4152,7 @@ static SDValue getAArch64Cmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
41414152
// can be turned into:
41424153
// cmp w12, w11, lsl #1
41434154
if (!isa<ConstantSDNode>(RHS) ||
4144-
!isLegalArithImmed(RHS->getAsAPIntVal().abs().getZExtValue())) {
4155+
!isLegalCmpImmed(RHS->getAsAPIntVal().getSExtValue())) {
41454156
bool LHSIsCMN = isCMN(LHS, CC, DAG);
41464157
bool RHSIsCMN = isCMN(RHS, CC, DAG);
41474158
SDValue TheLHS = LHSIsCMN ? LHS.getOperand(1) : LHS;
@@ -17673,12 +17684,7 @@ bool AArch64TargetLowering::isLegalAddImmediate(int64_t Immed) const {
1767317684
return false;
1767417685
}
1767517686
// Same encoding for add/sub, just flip the sign.
17676-
Immed = std::abs(Immed);
17677-
bool IsLegal = ((Immed >> 12) == 0 ||
17678-
((Immed & 0xfff) == 0 && Immed >> 24 == 0));
17679-
LLVM_DEBUG(dbgs() << "Is " << Immed
17680-
<< " legal add imm: " << (IsLegal ? "yes" : "no") << "\n");
17681-
return IsLegal;
17687+
return isLegalArithImmed((uint64_t)std::abs(Immed));
1768217688
}
1768317689

1768417690
bool AArch64TargetLowering::isLegalAddScalableImmediate(int64_t Imm) const {

0 commit comments

Comments
 (0)