Skip to content

Commit 95f49c5

Browse files
committed
[APInt] Assert correct values in APInt constructor
If the uint64_t constructor is used, assert that the value is actuall a signed or unsigned N-bit integer depending on whether the isSigned flag is set. Currently, we allow values to be silently truncated, which is a constant source of subtle bugs -- a particularly common mistake is to create -1 values without setting the isSigned flag, which will work fine for all common bit widths (<= 64-bit) and miscompile for larger integers.
1 parent 62ae7d9 commit 95f49c5

33 files changed

+370
-333
lines changed

llvm/include/llvm/ADT/APFixedPoint.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,9 @@ class APFixedPoint {
160160
}
161161

162162
APFixedPoint(uint64_t Val, const FixedPointSemantics &Sema)
163-
: APFixedPoint(APInt(Sema.getWidth(), Val, Sema.isSigned()), Sema) {}
163+
: APFixedPoint(APInt(Sema.getWidth(), Val, Sema.isSigned(),
164+
/*implicitTrunc*/ true),
165+
Sema) {}
164166

165167
// Zero initialization.
166168
APFixedPoint(const FixedPointSemantics &Sema) : APFixedPoint(0, Sema) {}

llvm/include/llvm/ADT/APInt.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,26 @@ class [[nodiscard]] APInt {
106106
/// \param numBits the bit width of the constructed APInt
107107
/// \param val the initial value of the APInt
108108
/// \param isSigned how to treat signedness of val
109-
APInt(unsigned numBits, uint64_t val, bool isSigned = false)
109+
/// \param implicitTrunc allow implicit truncation of non-zero/sign bits of
110+
/// val beyond the range of numBits
111+
APInt(unsigned numBits, uint64_t val, bool isSigned = false,
112+
bool implicitTrunc = false)
110113
: BitWidth(numBits) {
114+
if (!implicitTrunc) {
115+
if (BitWidth == 0) {
116+
assert(val == 0 && "Value must be zero for 0-bit APInt");
117+
} else if (isSigned) {
118+
assert(llvm::isIntN(BitWidth, val) &&
119+
"Value is not an N-bit signed value");
120+
} else {
121+
assert(llvm::isUIntN(BitWidth, val) &&
122+
"Value is not an N-bit unsigned value");
123+
}
124+
}
111125
if (isSingleWord()) {
112126
U.VAL = val;
113-
clearUnusedBits();
127+
if (implicitTrunc || isSigned)
128+
clearUnusedBits();
114129
} else {
115130
initSlowCase(val, isSigned);
116131
}

llvm/lib/Analysis/ConstantFolding.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,8 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
889889
APInt Offset = APInt(
890890
BitWidth,
891891
DL.getIndexedOffsetInType(
892-
SrcElemTy, ArrayRef((Value *const *)Ops.data() + 1, Ops.size() - 1)));
892+
SrcElemTy, ArrayRef((Value *const *)Ops.data() + 1, Ops.size() - 1)),
893+
/*isSigned*/ true, /*implicitTrunc*/ true);
893894

894895
// If this is a GEP of a GEP, fold it all into a single GEP.
895896
while (auto *GEP = dyn_cast<GEPOperator>(Ptr)) {
@@ -3322,8 +3323,9 @@ ConstantFoldScalarFrexpCall(Constant *Op, Type *IntTy) {
33223323

33233324
// The exponent is an "unspecified value" for inf/nan. We use zero to avoid
33243325
// using undef.
3325-
Constant *Result1 = FrexpMant.isFinite() ? ConstantInt::get(IntTy, FrexpExp)
3326-
: ConstantInt::getNullValue(IntTy);
3326+
Constant *Result1 = FrexpMant.isFinite()
3327+
? ConstantInt::getSigned(IntTy, FrexpExp)
3328+
: ConstantInt::getNullValue(IntTy);
33273329
return {Result0, Result1};
33283330
}
33293331

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8701,7 +8701,7 @@ static ConstantRange getRangeForIntrinsic(const IntrinsicInst &II) {
87018701
case Intrinsic::cttz:
87028702
// Maximum of set/clear bits is the bit width.
87038703
return ConstantRange::getNonEmpty(APInt::getZero(Width),
8704-
APInt(Width, Width + 1));
8704+
APInt(Width, Width) + 1);
87058705
case Intrinsic::uadd_sat:
87068706
// uadd.sat(x, C) produces [C, UINT_MAX].
87078707
if (match(II.getOperand(0), m_APInt(C)) ||
@@ -8852,7 +8852,7 @@ static void setLimitForFPToI(const Instruction *I, APInt &Lower, APInt &Upper) {
88528852
if (!I->getOperand(0)->getType()->getScalarType()->isHalfTy())
88538853
return;
88548854
if (isa<FPToSIInst>(I) && BitWidth >= 17) {
8855-
Lower = APInt(BitWidth, -65504);
8855+
Lower = APInt(BitWidth, -65504, true);
88568856
Upper = APInt(BitWidth, 65505);
88578857
}
88588858

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3062,7 +3062,7 @@ Error BitcodeReader::parseConstants() {
30623062
case bitc::CST_CODE_INTEGER: // INTEGER: [intval]
30633063
if (!CurTy->isIntegerTy() || Record.empty())
30643064
return error("Invalid integer const record");
3065-
V = ConstantInt::get(CurTy, decodeSignRotatedValue(Record[0]));
3065+
V = ConstantInt::getSigned(CurTy, decodeSignRotatedValue(Record[0]));
30663066
break;
30673067
case bitc::CST_CODE_WIDE_INTEGER: {// WIDE_INTEGER: [n x intval]
30683068
if (!CurTy->isIntegerTy() || Record.empty())

llvm/lib/CodeGen/CodeGenPrepare.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1645,7 +1645,7 @@ static bool matchUAddWithOverflowConstantEdgeCases(CmpInst *Cmp,
16451645
if (Pred == ICmpInst::ICMP_EQ && match(B, m_AllOnes()))
16461646
B = ConstantInt::get(B->getType(), 1);
16471647
else if (Pred == ICmpInst::ICMP_NE && match(B, m_ZeroInt()))
1648-
B = ConstantInt::get(B->getType(), -1);
1648+
B = Constant::getAllOnesValue(B->getType());
16491649
else
16501650
return false;
16511651

llvm/lib/CodeGen/ExpandMemCmp.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ void MemCmpExpansion::emitMemCmpResultBlock() {
590590
ResBlock.PhiSrc2);
591591

592592
Value *Res =
593-
Builder.CreateSelect(Cmp, ConstantInt::get(Builder.getInt32Ty(), -1),
593+
Builder.CreateSelect(Cmp, Constant::getAllOnesValue(Builder.getInt32Ty()),
594594
ConstantInt::get(Builder.getInt32Ty(), 1));
595595

596596
PhiRes->addIncoming(Res, ResBlock.BB);

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1603,7 +1603,10 @@ SDValue SelectionDAG::getConstant(uint64_t Val, const SDLoc &DL, EVT VT,
16031603
assert((EltVT.getSizeInBits() >= 64 ||
16041604
(uint64_t)((int64_t)Val >> EltVT.getSizeInBits()) + 1 < 2) &&
16051605
"getConstant with a uint64_t value that doesn't fit in the type!");
1606-
return getConstant(APInt(EltVT.getSizeInBits(), Val), DL, VT, isT, isO);
1606+
// TODO: Avoid implicit trunc?
1607+
return getConstant(
1608+
APInt(EltVT.getSizeInBits(), Val, false, /*implicitTrunc*/ true), DL, VT,
1609+
isT, isO);
16071610
}
16081611

16091612
SDValue SelectionDAG::getConstant(const APInt &Val, const SDLoc &DL, EVT VT,

llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2054,7 +2054,9 @@ ScheduleDAGSDNodes *SelectionDAGISel::CreateScheduler() {
20542054
bool SelectionDAGISel::CheckAndMask(SDValue LHS, ConstantSDNode *RHS,
20552055
int64_t DesiredMaskS) const {
20562056
const APInt &ActualMask = RHS->getAPIntValue();
2057-
const APInt &DesiredMask = APInt(LHS.getValueSizeInBits(), DesiredMaskS);
2057+
// TODO: Avoid implicit trunc?
2058+
const APInt &DesiredMask = APInt(LHS.getValueSizeInBits(), DesiredMaskS,
2059+
false, /*implicitTrunc*/ true);
20582060

20592061
// If the actual mask exactly matches, success!
20602062
if (ActualMask == DesiredMask)

llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4542,7 +4542,7 @@ OpenMPIRBuilder::createTargetInit(const LocationDescription &Loc, bool IsSPMD,
45424542
Builder.CreateCall(Fn, {KernelEnvironment, KernelLaunchEnvironment});
45434543

45444544
Value *ExecUserCode = Builder.CreateICmpEQ(
4545-
ThreadKind, ConstantInt::get(ThreadKind->getType(), -1),
4545+
ThreadKind, Constant::getAllOnesValue(ThreadKind->getType()),
45464546
"exec_user_code");
45474547

45484548
// ThreadKind = __kmpc_target_init(...)

llvm/lib/FuzzMutate/OpDescriptor.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ void fuzzerop::makeConstantsWithType(Type *T, std::vector<Constant *> &Cs) {
1717
uint64_t W = IntTy->getBitWidth();
1818
Cs.push_back(ConstantInt::get(IntTy, 0));
1919
Cs.push_back(ConstantInt::get(IntTy, 1));
20-
Cs.push_back(ConstantInt::get(IntTy, 42));
20+
Cs.push_back(ConstantInt::get(
21+
IntTy, APInt(W, 42, /*isSigned*/ false, /*implicitTrunc*/ true)));
2122
Cs.push_back(ConstantInt::get(IntTy, APInt::getMaxValue(W)));
2223
Cs.push_back(ConstantInt::get(IntTy, APInt::getMinValue(W)));
2324
Cs.push_back(ConstantInt::get(IntTy, APInt::getSignedMaxValue(W)));

llvm/lib/IR/ConstantRange.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,7 +1743,7 @@ ConstantRange ConstantRange::ctlz(bool ZeroIsPoison) const {
17431743
// Zero is either safe or not in the range. The output range is composed by
17441744
// the result of countLeadingZero of the two extremes.
17451745
return getNonEmpty(APInt(getBitWidth(), getUnsignedMax().countl_zero()),
1746-
APInt(getBitWidth(), getUnsignedMin().countl_zero() + 1));
1746+
APInt(getBitWidth(), getUnsignedMin().countl_zero()) + 1);
17471747
}
17481748

17491749
static ConstantRange getUnsignedCountTrailingZerosRange(const APInt &Lower,
@@ -1802,7 +1802,7 @@ ConstantRange ConstantRange::cttz(bool ZeroIsPoison) const {
18021802
}
18031803

18041804
if (isFullSet())
1805-
return getNonEmpty(Zero, APInt(BitWidth, BitWidth + 1));
1805+
return getNonEmpty(Zero, APInt(BitWidth, BitWidth) + 1);
18061806
if (!isWrappedSet())
18071807
return getUnsignedCountTrailingZerosRange(Lower, Upper);
18081808
// The range is wrapped. We decompose it into two ranges, [0, Upper) and
@@ -1847,7 +1847,7 @@ ConstantRange ConstantRange::ctpop() const {
18471847
unsigned BitWidth = getBitWidth();
18481848
APInt Zero = APInt::getZero(BitWidth);
18491849
if (isFullSet())
1850-
return getNonEmpty(Zero, APInt(BitWidth, BitWidth + 1));
1850+
return getNonEmpty(Zero, APInt(BitWidth, BitWidth) + 1);
18511851
if (!isWrappedSet())
18521852
return getUnsignedPopCountRange(Lower, Upper);
18531853
// The range is wrapped. We decompose it into two ranges, [0, Upper) and

llvm/lib/Support/APInt.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,8 @@ APInt& APInt::operator-=(uint64_t RHS) {
234234
APInt APInt::operator*(const APInt& RHS) const {
235235
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
236236
if (isSingleWord())
237-
return APInt(BitWidth, U.VAL * RHS.U.VAL);
237+
return APInt(BitWidth, U.VAL * RHS.U.VAL, /*isSigned*/ false,
238+
/*implicitTrunc*/ true);
238239

239240
APInt Result(getMemory(getNumWords()), getBitWidth());
240241
tcMultiply(Result.U.pVal, U.pVal, RHS.U.pVal, getNumWords());
@@ -455,15 +456,17 @@ APInt APInt::extractBits(unsigned numBits, unsigned bitPosition) const {
455456
"Illegal bit extraction");
456457

457458
if (isSingleWord())
458-
return APInt(numBits, U.VAL >> bitPosition);
459+
return APInt(numBits, U.VAL >> bitPosition, /*isSigned*/ false,
460+
/*implicitTrunc*/ true);
459461

460462
unsigned loBit = whichBit(bitPosition);
461463
unsigned loWord = whichWord(bitPosition);
462464
unsigned hiWord = whichWord(bitPosition + numBits - 1);
463465

464466
// Single word result extracting bits from a single word source.
465467
if (loWord == hiWord)
466-
return APInt(numBits, U.pVal[loWord] >> loBit);
468+
return APInt(numBits, U.pVal[loWord] >> loBit, /*isSigned*/ false,
469+
/*implicitTrunc*/ true);
467470

468471
// Extracting bits that start on a source word boundary can be done
469472
// as a fast memory copy.
@@ -907,7 +910,8 @@ APInt APInt::trunc(unsigned width) const {
907910
assert(width <= BitWidth && "Invalid APInt Truncate request");
908911

909912
if (width <= APINT_BITS_PER_WORD)
910-
return APInt(width, getRawData()[0]);
913+
return APInt(width, getRawData()[0], /*isSigned*/ false,
914+
/*implicitTrunc*/ true);
911915

912916
if (width == BitWidth)
913917
return *this;
@@ -955,7 +959,7 @@ APInt APInt::sext(unsigned Width) const {
955959
assert(Width >= BitWidth && "Invalid APInt SignExtend request");
956960

957961
if (Width <= APINT_BITS_PER_WORD)
958-
return APInt(Width, SignExtend64(U.VAL, BitWidth));
962+
return APInt(Width, SignExtend64(U.VAL, BitWidth), /*isSigned*/ true);
959963

960964
if (Width == BitWidth)
961965
return *this;

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,13 +273,11 @@ Instruction *InstCombinerImpl::SimplifyAnyMemSet(AnyMemSetInst *MI) {
273273

274274
// memset(s,c,n) -> store s, c (for n=1,2,4,8)
275275
if (Len <= 8 && isPowerOf2_32((uint32_t)Len)) {
276-
Type *ITy = IntegerType::get(MI->getContext(), Len*8); // n=1 -> i8.
277-
278276
Value *Dest = MI->getDest();
279277

280278
// Extract the fill value and store.
281-
const uint64_t Fill = FillC->getZExtValue()*0x0101010101010101ULL;
282-
Constant *FillVal = ConstantInt::get(ITy, Fill);
279+
Constant *FillVal = ConstantInt::get(
280+
MI->getContext(), APInt::getSplat(Len * 8, FillC->getValue()));
283281
StoreInst *S = Builder.CreateStore(FillVal, Dest, MI->isVolatile());
284282
S->copyMetadata(*MI, LLVMContext::MD_DIAssignID);
285283
auto replaceOpForAssignmentMarkers = [FillC, FillVal](auto *DbgAssign) {

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
308308
DL.getTypeAllocSize(Init->getType()->getArrayElementType());
309309
auto MaskIdx = [&](Value *Idx) {
310310
if (!GEP->isInBounds() && llvm::countr_zero(ElementSize) != 0) {
311-
Value *Mask = ConstantInt::get(Idx->getType(), -1);
311+
Value *Mask = Constant::getAllOnesValue(Idx->getType());
312312
Mask = Builder.CreateLShr(Mask, llvm::countr_zero(ElementSize));
313313
Idx = Builder.CreateAnd(Idx, Mask);
314314
}

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -665,11 +665,11 @@ static Value *foldSelectICmpLshrAshr(const ICmpInst *IC, Value *TrueVal,
665665
Value *X, *Y;
666666
unsigned Bitwidth = CmpRHS->getType()->getScalarSizeInBits();
667667
if ((Pred != ICmpInst::ICMP_SGT ||
668-
!match(CmpRHS,
669-
m_SpecificInt_ICMP(ICmpInst::ICMP_SGE, APInt(Bitwidth, -1)))) &&
668+
!match(CmpRHS, m_SpecificInt_ICMP(ICmpInst::ICMP_SGE,
669+
APInt::getAllOnes(Bitwidth)))) &&
670670
(Pred != ICmpInst::ICMP_SLT ||
671-
!match(CmpRHS,
672-
m_SpecificInt_ICMP(ICmpInst::ICMP_SGE, APInt(Bitwidth, 0)))))
671+
!match(CmpRHS, m_SpecificInt_ICMP(ICmpInst::ICMP_SGE,
672+
APInt::getZero(Bitwidth)))))
673673
return nullptr;
674674

675675
// Canonicalize so that ashr is in FalseVal.

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -859,7 +859,7 @@ void ConstraintInfo::transferToOtherSystem(
859859
addFact(CmpInst::ICMP_ULT, A, B, NumIn, NumOut, DFSInStack);
860860
break;
861861
case CmpInst::ICMP_SGT: {
862-
if (doesHold(CmpInst::ICMP_SGE, B, ConstantInt::get(B->getType(), -1)))
862+
if (doesHold(CmpInst::ICMP_SGE, B, Constant::getAllOnesValue(B->getType())))
863863
addFact(CmpInst::ICMP_UGE, A, ConstantInt::get(B->getType(), 0), NumIn,
864864
NumOut, DFSInStack);
865865
if (IsKnownNonNegative(B))

llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4034,7 +4034,7 @@ void LSRInstance::GenerateICmpZeroScales(LSRUse &LU, unsigned LUIdx,
40344034
// Compensate for the use having MinOffset built into it.
40354035
F.BaseOffset = (uint64_t)F.BaseOffset + Offset - LU.MinOffset;
40364036

4037-
const SCEV *FactorS = SE.getConstant(IntTy, Factor);
4037+
const SCEV *FactorS = SE.getConstant(IntTy, Factor, /*isSigned*/ true);
40384038

40394039
// Check that multiplying with each base register doesn't overflow.
40404040
for (size_t i = 0, e = F.BaseRegs.size(); i != e; ++i) {
@@ -4110,7 +4110,7 @@ void LSRInstance::GenerateScales(LSRUse &LU, unsigned LUIdx, Formula Base) {
41104110
for (size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i) {
41114111
const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(Base.BaseRegs[i]);
41124112
if (AR && (AR->getLoop() == L || LU.AllFixupsOutsideLoop)) {
4113-
const SCEV *FactorS = SE.getConstant(IntTy, Factor);
4113+
const SCEV *FactorS = SE.getConstant(IntTy, Factor, true);
41144114
if (FactorS->isZero())
41154115
continue;
41164116
// Divide out the factor, ignoring high bits, since we'll be
@@ -4344,7 +4344,8 @@ void LSRInstance::GenerateCrossUseConstantOffsets() {
43444344
const SCEV *OrigReg = WI.OrigReg;
43454345

43464346
Type *IntTy = SE.getEffectiveSCEVType(OrigReg->getType());
4347-
const SCEV *NegImmS = SE.getSCEV(ConstantInt::get(IntTy, -(uint64_t)Imm));
4347+
const SCEV *NegImmS =
4348+
SE.getSCEV(ConstantInt::getSigned(IntTy, -(uint64_t)Imm));
43484349
unsigned BitWidth = SE.getTypeSizeInBits(IntTy);
43494350

43504351
// TODO: Use a more targeted data structure.
@@ -4359,8 +4360,8 @@ void LSRInstance::GenerateCrossUseConstantOffsets() {
43594360
if (F.ScaledReg == OrigReg) {
43604361
int64_t Offset = (uint64_t)F.BaseOffset + Imm * (uint64_t)F.Scale;
43614362
// Don't create 50 + reg(-50).
4362-
if (F.referencesReg(SE.getSCEV(
4363-
ConstantInt::get(IntTy, -(uint64_t)Offset))))
4363+
if (F.referencesReg(
4364+
SE.getSCEV(ConstantInt::getSigned(IntTy, -(uint64_t)Offset))))
43644365
continue;
43654366
Formula NewF = F;
43664367
NewF.BaseOffset = Offset;

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6908,15 +6908,15 @@ static bool ReduceSwitchRange(SwitchInst *SI, IRBuilder<> &Builder,
69086908
auto *Ty = cast<IntegerType>(SI->getCondition()->getType());
69096909
Builder.SetInsertPoint(SI);
69106910
Value *Sub =
6911-
Builder.CreateSub(SI->getCondition(), ConstantInt::get(Ty, Base));
6911+
Builder.CreateSub(SI->getCondition(), ConstantInt::getSigned(Ty, Base));
69126912
Value *Rot = Builder.CreateIntrinsic(
69136913
Ty, Intrinsic::fshl,
69146914
{Sub, Sub, ConstantInt::get(Ty, Ty->getBitWidth() - Shift)});
69156915
SI->replaceUsesOfWith(SI->getCondition(), Rot);
69166916

69176917
for (auto Case : SI->cases()) {
69186918
auto *Orig = Case.getCaseValue();
6919-
auto Sub = Orig->getValue() - APInt(Ty->getBitWidth(), Base);
6919+
auto Sub = Orig->getValue() - APInt(Ty->getBitWidth(), Base, true);
69206920
Case.setValue(cast<ConstantInt>(ConstantInt::get(Ty, Sub.lshr(Shift))));
69216921
}
69226922
return true;

llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ static Value *convertStrToInt(CallInst *CI, StringRef &Str, Value *EndPtr,
224224
// Unsigned negation doesn't overflow.
225225
Result = -Result;
226226

227-
return ConstantInt::get(RetTy, Result);
227+
return ConstantInt::get(RetTy, Result, AsSigned);
228228
}
229229

230230
static bool isOnlyUsedInComparisonWithZero(Value *V) {
@@ -553,7 +553,8 @@ Value *LibCallSimplifier::optimizeStrCmp(CallInst *CI, IRBuilderBase &B) {
553553
// strcmp(x, y) -> cnst (if both x and y are constant strings)
554554
if (HasStr1 && HasStr2)
555555
return ConstantInt::get(CI->getType(),
556-
std::clamp(Str1.compare(Str2), -1, 1));
556+
std::clamp(Str1.compare(Str2), -1, 1),
557+
/*isSigned*/ true);
557558

558559
if (HasStr1 && Str1.empty()) // strcmp("", x) -> -*x
559560
return B.CreateNeg(B.CreateZExt(
@@ -638,7 +639,8 @@ Value *LibCallSimplifier::optimizeStrNCmp(CallInst *CI, IRBuilderBase &B) {
638639
StringRef SubStr1 = substr(Str1, Length);
639640
StringRef SubStr2 = substr(Str2, Length);
640641
return ConstantInt::get(CI->getType(),
641-
std::clamp(SubStr1.compare(SubStr2), -1, 1));
642+
std::clamp(SubStr1.compare(SubStr2), -1, 1),
643+
/*isSigned*/ true);
642644
}
643645

644646
if (HasStr1 && Str1.empty()) // strncmp("", x, n) -> -*x
@@ -1518,7 +1520,7 @@ static Value *optimizeMemCmpVarSize(CallInst *CI, Value *LHS, Value *RHS,
15181520
int IRes = UChar(LStr[Pos]) < UChar(RStr[Pos]) ? -1 : 1;
15191521
Value *MaxSize = ConstantInt::get(Size->getType(), Pos);
15201522
Value *Cmp = B.CreateICmp(ICmpInst::ICMP_ULE, Size, MaxSize);
1521-
Value *Res = ConstantInt::get(CI->getType(), IRes);
1523+
Value *Res = ConstantInt::get(CI->getType(), IRes, /*isSigned*/ true);
15221524
return B.CreateSelect(Cmp, Zero, Res);
15231525
}
15241526

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1312,7 +1312,7 @@ void VPVectorPointerRecipe ::execute(VPTransformState &State) {
13121312
Value *RunTimeVF = getRuntimeVF(Builder, IndexTy, State.VF);
13131313
// NumElt = -Part * RunTimeVF
13141314
Value *NumElt = Builder.CreateMul(
1315-
ConstantInt::get(IndexTy, -(int64_t)Part), RunTimeVF);
1315+
ConstantInt::getSigned(IndexTy, -(int64_t)Part), RunTimeVF);
13161316
// LastLane = 1 - RunTimeVF
13171317
Value *LastLane =
13181318
Builder.CreateSub(ConstantInt::get(IndexTy, 1), RunTimeVF);

0 commit comments

Comments
 (0)