@@ -3647,6 +3647,16 @@ static bool isLegalArithImmed(uint64_t C) {
3647
3647
return IsLegal;
3648
3648
}
3649
3649
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
+
3650
3660
static bool cannotBeIntMin(SDValue CheckedVal, SelectionDAG &DAG) {
3651
3661
KnownBits KnownSrc = DAG.computeKnownBits(CheckedVal);
3652
3662
return !KnownSrc.getSignedMinValue().isMinSignedValue();
@@ -4077,52 +4087,53 @@ static SDValue getAArch64Cmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
4077
4087
const SDLoc &dl) {
4078
4088
if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS.getNode())) {
4079
4089
EVT VT = RHS.getValueType();
4080
- uint64_t C = RHSC->getZExtValue ();
4081
- if (!isLegalArithImmed (C)) {
4090
+ int64_t C = RHSC->getSExtValue ();
4091
+ if (!isLegalCmpImmed (C)) {
4082
4092
// Constant does not fit, try adjusting it by one?
4083
4093
switch (CC) {
4084
4094
default:
4085
4095
break;
4086
4096
case ISD::SETLT:
4087
4097
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))) {
4092
4100
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;
4094
4104
RHS = DAG.getConstant(C, dl, VT);
4095
4105
}
4096
4106
break;
4097
4107
case ISD::SETULT:
4098
4108
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))) {
4102
4111
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;
4104
4115
RHS = DAG.getConstant(C, dl, VT);
4105
4116
}
4106
4117
break;
4107
4118
case ISD::SETLE:
4108
4119
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))) {
4113
4122
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;
4115
4126
RHS = DAG.getConstant(C, dl, VT);
4116
4127
}
4117
4128
break;
4118
4129
case ISD::SETULE:
4119
4130
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))) {
4124
4133
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;
4126
4137
RHS = DAG.getConstant(C, dl, VT);
4127
4138
}
4128
4139
break;
@@ -4141,7 +4152,7 @@ static SDValue getAArch64Cmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
4141
4152
// can be turned into:
4142
4153
// cmp w12, w11, lsl #1
4143
4154
if (!isa<ConstantSDNode>(RHS) ||
4144
- !isLegalArithImmed (RHS->getAsAPIntVal().abs().getZExtValue ())) {
4155
+ !isLegalCmpImmed (RHS->getAsAPIntVal().getSExtValue ())) {
4145
4156
bool LHSIsCMN = isCMN(LHS, CC, DAG);
4146
4157
bool RHSIsCMN = isCMN(RHS, CC, DAG);
4147
4158
SDValue TheLHS = LHSIsCMN ? LHS.getOperand(1) : LHS;
@@ -17673,12 +17684,7 @@ bool AArch64TargetLowering::isLegalAddImmediate(int64_t Immed) const {
17673
17684
return false;
17674
17685
}
17675
17686
// 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));
17682
17688
}
17683
17689
17684
17690
bool AArch64TargetLowering::isLegalAddScalableImmediate(int64_t Imm) const {
0 commit comments