Skip to content

Commit ca2fc22

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 73d835c commit ca2fc22

33 files changed

+377
-339
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
@@ -108,11 +108,26 @@ class [[nodiscard]] APInt {
108108
/// \param numBits the bit width of the constructed APInt
109109
/// \param val the initial value of the APInt
110110
/// \param isSigned how to treat signedness of val
111-
APInt(unsigned numBits, uint64_t val, bool isSigned = false)
111+
/// \param implicitTrunc allow implicit truncation of non-zero/sign bits of
112+
/// val beyond the range of numBits
113+
APInt(unsigned numBits, uint64_t val, bool isSigned = false,
114+
bool implicitTrunc = false)
112115
: BitWidth(numBits) {
116+
if (!implicitTrunc) {
117+
if (BitWidth == 0) {
118+
assert(val == 0 && "Value must be zero for 0-bit APInt");
119+
} else if (isSigned) {
120+
assert(llvm::isIntN(BitWidth, val) &&
121+
"Value is not an N-bit signed value");
122+
} else {
123+
assert(llvm::isUIntN(BitWidth, val) &&
124+
"Value is not an N-bit unsigned value");
125+
}
126+
}
113127
if (isSingleWord()) {
114128
U.VAL = val;
115-
clearUnusedBits();
129+
if (implicitTrunc || isSigned)
130+
clearUnusedBits();
116131
} else {
117132
initSlowCase(val, isSigned);
118133
}

llvm/lib/Analysis/ConstantFolding.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -887,7 +887,8 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
887887
APInt Offset = APInt(
888888
BitWidth,
889889
DL.getIndexedOffsetInType(
890-
SrcElemTy, ArrayRef((Value *const *)Ops.data() + 1, Ops.size() - 1)));
890+
SrcElemTy, ArrayRef((Value *const *)Ops.data() + 1, Ops.size() - 1)),
891+
/*isSigned*/ true, /*implicitTrunc*/ true);
891892

892893
std::optional<ConstantRange> InRange = GEP->getInRange();
893894
if (InRange)

llvm/lib/Analysis/MemoryBuiltins.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ Value *llvm::lowerObjectSizeCall(
660660
if (!MustSucceed)
661661
return nullptr;
662662

663-
return ConstantInt::get(ResultType, MaxVal ? -1ULL : 0);
663+
return ConstantInt::get(ResultType, MaxVal ? -1ULL : 0, true);
664664
}
665665

666666
STATISTIC(ObjectVisitorArgument,

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,7 +1481,7 @@ bool ScalarEvolution::proveNoWrapByVaryingStart(const SCEV *Start,
14811481

14821482
APInt StartAI = StartC->getAPInt();
14831483

1484-
for (unsigned Delta : {-2, -1, 1, 2}) {
1484+
for (int Delta : {-2, -1, 1, 2}) {
14851485
const SCEV *PreStart = getConstant(StartAI - Delta);
14861486

14871487
FoldingSetNodeID ID;
@@ -1496,7 +1496,7 @@ bool ScalarEvolution::proveNoWrapByVaryingStart(const SCEV *Start,
14961496
// Give up if we don't already have the add recurrence we need because
14971497
// actually constructing an add recurrence is relatively expensive.
14981498
if (PreAR && PreAR->getNoWrapFlags(WrapType)) { // proves (2)
1499-
const SCEV *DeltaS = getConstant(StartC->getType(), Delta);
1499+
const SCEV *DeltaS = getConstant(StartC->getType(), Delta, true);
15001500
ICmpInst::Predicate Pred = ICmpInst::BAD_ICMP_PREDICATE;
15011501
const SCEV *Limit = ExtendOpTraits<ExtendOpTy>::getOverflowLimitForStep(
15021502
DeltaS, &Pred, this);

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9516,7 +9516,7 @@ static ConstantRange getRangeForIntrinsic(const IntrinsicInst &II) {
95169516
case Intrinsic::cttz:
95179517
// Maximum of set/clear bits is the bit width.
95189518
return ConstantRange::getNonEmpty(APInt::getZero(Width),
9519-
APInt(Width, Width + 1));
9519+
APInt(Width, Width) + 1);
95209520
case Intrinsic::uadd_sat:
95219521
// uadd.sat(x, C) produces [C, UINT_MAX].
95229522
if (match(II.getOperand(0), m_APInt(C)) ||
@@ -9671,7 +9671,7 @@ static void setLimitForFPToI(const Instruction *I, APInt &Lower, APInt &Upper) {
96719671
if (!I->getOperand(0)->getType()->getScalarType()->isHalfTy())
96729672
return;
96739673
if (isa<FPToSIInst>(I) && BitWidth >= 17) {
9674-
Lower = APInt(BitWidth, -65504);
9674+
Lower = APInt(BitWidth, -65504, true);
96759675
Upper = APInt(BitWidth, 65505);
96769676
}
96779677

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3190,7 +3190,7 @@ Error BitcodeReader::parseConstants() {
31903190
case bitc::CST_CODE_INTEGER: // INTEGER: [intval]
31913191
if (!CurTy->isIntOrIntVectorTy() || Record.empty())
31923192
return error("Invalid integer const record");
3193-
V = ConstantInt::get(CurTy, decodeSignRotatedValue(Record[0]));
3193+
V = ConstantInt::getSigned(CurTy, decodeSignRotatedValue(Record[0]));
31943194
break;
31953195
case bitc::CST_CODE_WIDE_INTEGER: {// WIDE_INTEGER: [n x intval]
31963196
if (!CurTy->isIntOrIntVectorTy() || Record.empty())

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1628,7 +1628,10 @@ SDValue SelectionDAG::getConstant(uint64_t Val, const SDLoc &DL, EVT VT,
16281628
assert((EltVT.getSizeInBits() >= 64 ||
16291629
(uint64_t)((int64_t)Val >> EltVT.getSizeInBits()) + 1 < 2) &&
16301630
"getConstant with a uint64_t value that doesn't fit in the type!");
1631-
return getConstant(APInt(EltVT.getSizeInBits(), Val), DL, VT, isT, isO);
1631+
// TODO: Avoid implicit trunc?
1632+
return getConstant(
1633+
APInt(EltVT.getSizeInBits(), Val, false, /*implicitTrunc*/ true), DL, VT,
1634+
isT, isO);
16321635
}
16331636

16341637
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
@@ -2142,7 +2142,9 @@ ScheduleDAGSDNodes *SelectionDAGISel::CreateScheduler() {
21422142
bool SelectionDAGISel::CheckAndMask(SDValue LHS, ConstantSDNode *RHS,
21432143
int64_t DesiredMaskS) const {
21442144
const APInt &ActualMask = RHS->getAPIntValue();
2145-
const APInt &DesiredMask = APInt(LHS.getValueSizeInBits(), DesiredMaskS);
2145+
// TODO: Avoid implicit trunc?
2146+
const APInt &DesiredMask = APInt(LHS.getValueSizeInBits(), DesiredMaskS,
2147+
false, /*implicitTrunc*/ true);
21462148

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

llvm/lib/FuzzMutate/OpDescriptor.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ void fuzzerop::makeConstantsWithType(Type *T, std::vector<Constant *> &Cs) {
2222
uint64_t W = IntTy->getBitWidth();
2323
Cs.push_back(ConstantInt::get(IntTy, 0));
2424
Cs.push_back(ConstantInt::get(IntTy, 1));
25-
Cs.push_back(ConstantInt::get(IntTy, 42));
25+
Cs.push_back(ConstantInt::get(
26+
IntTy, APInt(W, 42, /*isSigned*/ false, /*implicitTrunc*/ true)));
2627
Cs.push_back(ConstantInt::get(IntTy, APInt::getMaxValue(W)));
2728
Cs.push_back(ConstantInt::get(IntTy, APInt::getMinValue(W)));
2829
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
@@ -1952,7 +1952,7 @@ ConstantRange ConstantRange::ctlz(bool ZeroIsPoison) const {
19521952
// Zero is either safe or not in the range. The output range is composed by
19531953
// the result of countLeadingZero of the two extremes.
19541954
return getNonEmpty(APInt(getBitWidth(), getUnsignedMax().countl_zero()),
1955-
APInt(getBitWidth(), getUnsignedMin().countl_zero() + 1));
1955+
APInt(getBitWidth(), getUnsignedMin().countl_zero()) + 1);
19561956
}
19571957

19581958
static ConstantRange getUnsignedCountTrailingZerosRange(const APInt &Lower,
@@ -2011,7 +2011,7 @@ ConstantRange ConstantRange::cttz(bool ZeroIsPoison) const {
20112011
}
20122012

20132013
if (isFullSet())
2014-
return getNonEmpty(Zero, APInt(BitWidth, BitWidth + 1));
2014+
return getNonEmpty(Zero, APInt(BitWidth, BitWidth) + 1);
20152015
if (!isWrappedSet())
20162016
return getUnsignedCountTrailingZerosRange(Lower, Upper);
20172017
// The range is wrapped. We decompose it into two ranges, [0, Upper) and
@@ -2056,7 +2056,7 @@ ConstantRange ConstantRange::ctpop() const {
20562056
unsigned BitWidth = getBitWidth();
20572057
APInt Zero = APInt::getZero(BitWidth);
20582058
if (isFullSet())
2059-
return getNonEmpty(Zero, APInt(BitWidth, BitWidth + 1));
2059+
return getNonEmpty(Zero, APInt(BitWidth, BitWidth) + 1);
20602060
if (!isWrappedSet())
20612061
return getUnsignedPopCountRange(Lower, Upper);
20622062
// 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/IPO/WholeProgramDevirt.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1669,17 +1669,20 @@ Constant *DevirtModule::importConstant(VTableSlot Slot, ArrayRef<uint64_t> Args,
16691669
if (GV->hasMetadata(LLVMContext::MD_absolute_symbol))
16701670
return C;
16711671

1672-
auto SetAbsRange = [&](uint64_t Min, uint64_t Max) {
1672+
auto SetAbsRange = [&](const APInt &Min, const APInt &Max) {
16731673
auto *MinC = ConstantAsMetadata::get(ConstantInt::get(IntPtrTy, Min));
16741674
auto *MaxC = ConstantAsMetadata::get(ConstantInt::get(IntPtrTy, Max));
16751675
GV->setMetadata(LLVMContext::MD_absolute_symbol,
16761676
MDNode::get(M.getContext(), {MinC, MaxC}));
16771677
};
16781678
unsigned AbsWidth = IntTy->getBitWidth();
1679-
if (AbsWidth == IntPtrTy->getBitWidth())
1680-
SetAbsRange(~0ull, ~0ull); // Full set.
1679+
unsigned IntPtrWidth = IntPtrTy->getBitWidth();
1680+
if (AbsWidth == IntPtrWidth)
1681+
// Full set.
1682+
SetAbsRange(APInt::getAllOnes(IntPtrWidth), APInt::getAllOnes(IntPtrWidth));
16811683
else
1682-
SetAbsRange(0, 1ull << AbsWidth);
1684+
SetAbsRange(APInt::getZero(IntPtrWidth),
1685+
APInt::getOneBitSet(IntPtrWidth, AbsWidth));
16831686
return C;
16841687
}
16851688

@@ -1884,7 +1887,7 @@ bool DevirtModule::tryVirtualConstProp(
18841887
}
18851888

18861889
// Rewrite each call to a load from OffsetByte/OffsetBit.
1887-
Constant *ByteConst = ConstantInt::get(Int32Ty, OffsetByte);
1890+
Constant *ByteConst = ConstantInt::get(Int32Ty, OffsetByte, true);
18881891
Constant *BitConst = ConstantInt::get(Int8Ty, 1ULL << OffsetBit);
18891892
applyVirtualConstProp(CSByConstantArg.second,
18901893
TargetsForSlot[0].Fn->getName(), ByteConst, BitConst);

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

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

261261
// memset(s,c,n) -> store s, c (for n=1,2,4,8)
262262
if (Len <= 8 && isPowerOf2_32((uint32_t)Len)) {
263-
Type *ITy = IntegerType::get(MI->getContext(), Len*8); // n=1 -> i8.
264-
265263
Value *Dest = MI->getDest();
266264

267265
// Extract the fill value and store.
268-
const uint64_t Fill = FillC->getZExtValue()*0x0101010101010101ULL;
269-
Constant *FillVal = ConstantInt::get(ITy, Fill);
266+
Constant *FillVal = ConstantInt::get(
267+
MI->getContext(), APInt::getSplat(Len * 8, FillC->getValue()));
270268
StoreInst *S = Builder.CreateStore(FillVal, Dest, MI->isVolatile());
271269
S->copyMetadata(*MI, LLVMContext::MD_DIAssignID);
272270
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
@@ -312,7 +312,7 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
312312
DL.getTypeAllocSize(Init->getType()->getArrayElementType());
313313
auto MaskIdx = [&](Value *Idx) {
314314
if (!GEP->isInBounds() && llvm::countr_zero(ElementSize) != 0) {
315-
Value *Mask = ConstantInt::get(Idx->getType(), -1);
315+
Value *Mask = Constant::getAllOnesValue(Idx->getType());
316316
Mask = Builder.CreateLShr(Mask, llvm::countr_zero(ElementSize));
317317
Idx = Builder.CreateAnd(Idx, Mask);
318318
}

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -679,11 +679,11 @@ static Value *foldSelectICmpLshrAshr(const ICmpInst *IC, Value *TrueVal,
679679
Value *X, *Y;
680680
unsigned Bitwidth = CmpRHS->getType()->getScalarSizeInBits();
681681
if ((Pred != ICmpInst::ICMP_SGT ||
682-
!match(CmpRHS,
683-
m_SpecificInt_ICMP(ICmpInst::ICMP_SGE, APInt(Bitwidth, -1)))) &&
682+
!match(CmpRHS, m_SpecificInt_ICMP(ICmpInst::ICMP_SGE,
683+
APInt::getAllOnes(Bitwidth)))) &&
684684
(Pred != ICmpInst::ICMP_SLT ||
685-
!match(CmpRHS,
686-
m_SpecificInt_ICMP(ICmpInst::ICMP_SGE, APInt(Bitwidth, 0)))))
685+
!match(CmpRHS, m_SpecificInt_ICMP(ICmpInst::ICMP_SGE,
686+
APInt::getZero(Bitwidth)))))
687687
return nullptr;
688688

689689
// Canonicalize so that ashr is in FalseVal.

llvm/lib/Transforms/Scalar/IndVarSimplify.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -357,19 +357,19 @@ bool IndVarSimplify::handleFloatingPointIV(Loop *L, PHINode *PN) {
357357
// Insert new integer induction variable.
358358
PHINode *NewPHI =
359359
PHINode::Create(Int32Ty, 2, PN->getName() + ".int", PN->getIterator());
360-
NewPHI->addIncoming(ConstantInt::get(Int32Ty, InitValue),
360+
NewPHI->addIncoming(ConstantInt::getSigned(Int32Ty, InitValue),
361361
PN->getIncomingBlock(IncomingEdge));
362362
NewPHI->setDebugLoc(PN->getDebugLoc());
363363

364-
Instruction *NewAdd =
365-
BinaryOperator::CreateAdd(NewPHI, ConstantInt::get(Int32Ty, IncValue),
366-
Incr->getName() + ".int", Incr->getIterator());
364+
Instruction *NewAdd = BinaryOperator::CreateAdd(
365+
NewPHI, ConstantInt::getSigned(Int32Ty, IncValue),
366+
Incr->getName() + ".int", Incr->getIterator());
367367
NewAdd->setDebugLoc(Incr->getDebugLoc());
368368
NewPHI->addIncoming(NewAdd, PN->getIncomingBlock(BackEdge));
369369

370-
ICmpInst *NewCompare =
371-
new ICmpInst(TheBr->getIterator(), NewPred, NewAdd,
372-
ConstantInt::get(Int32Ty, ExitValue), Compare->getName());
370+
ICmpInst *NewCompare = new ICmpInst(
371+
TheBr->getIterator(), NewPred, NewAdd,
372+
ConstantInt::getSigned(Int32Ty, ExitValue), Compare->getName());
373373
NewCompare->setDebugLoc(Compare->getDebugLoc());
374374

375375
// In the following deletions, PN may become dead and may be deleted.

llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4285,7 +4285,7 @@ void LSRInstance::GenerateICmpZeroScales(LSRUse &LU, unsigned LUIdx,
42854285
// Compensate for the use having MinOffset built into it.
42864286
F.BaseOffset = F.BaseOffset.addUnsigned(Offset).subUnsigned(LU.MinOffset);
42874287

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

42904290
// Check that multiplying with each base register doesn't overflow.
42914291
for (size_t i = 0, e = F.BaseRegs.size(); i != e; ++i) {
@@ -4361,7 +4361,7 @@ void LSRInstance::GenerateScales(LSRUse &LU, unsigned LUIdx, Formula Base) {
43614361
for (size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i) {
43624362
const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(Base.BaseRegs[i]);
43634363
if (AR && (AR->getLoop() == L || LU.AllFixupsOutsideLoop)) {
4364-
const SCEV *FactorS = SE.getConstant(IntTy, Factor);
4364+
const SCEV *FactorS = SE.getConstant(IntTy, Factor, true);
43654365
if (FactorS->isZero())
43664366
continue;
43674367
// Divide out the factor, ignoring high bits, since we'll be

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7024,15 +7024,15 @@ static bool reduceSwitchRange(SwitchInst *SI, IRBuilder<> &Builder,
70247024
auto *Ty = cast<IntegerType>(SI->getCondition()->getType());
70257025
Builder.SetInsertPoint(SI);
70267026
Value *Sub =
7027-
Builder.CreateSub(SI->getCondition(), ConstantInt::get(Ty, Base));
7027+
Builder.CreateSub(SI->getCondition(), ConstantInt::getSigned(Ty, Base));
70287028
Value *Rot = Builder.CreateIntrinsic(
70297029
Ty, Intrinsic::fshl,
70307030
{Sub, Sub, ConstantInt::get(Ty, Ty->getBitWidth() - Shift)});
70317031
SI->replaceUsesOfWith(SI->getCondition(), Rot);
70327032

70337033
for (auto Case : SI->cases()) {
70347034
auto *Orig = Case.getCaseValue();
7035-
auto Sub = Orig->getValue() - APInt(Ty->getBitWidth(), Base);
7035+
auto Sub = Orig->getValue() - APInt(Ty->getBitWidth(), Base, true);
70367036
Case.setValue(cast<ConstantInt>(ConstantInt::get(Ty, Sub.lshr(Shift))));
70377037
}
70387038
return true;

llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp

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

236-
return ConstantInt::get(RetTy, Result);
236+
return ConstantInt::get(RetTy, Result, AsSigned);
237237
}
238238

239239
static bool isOnlyUsedInComparisonWithZero(Value *V) {
@@ -562,7 +562,8 @@ Value *LibCallSimplifier::optimizeStrCmp(CallInst *CI, IRBuilderBase &B) {
562562
// strcmp(x, y) -> cnst (if both x and y are constant strings)
563563
if (HasStr1 && HasStr2)
564564
return ConstantInt::get(CI->getType(),
565-
std::clamp(Str1.compare(Str2), -1, 1));
565+
std::clamp(Str1.compare(Str2), -1, 1),
566+
/*isSigned*/ true);
566567

567568
if (HasStr1 && Str1.empty()) // strcmp("", x) -> -*x
568569
return B.CreateNeg(B.CreateZExt(
@@ -647,7 +648,8 @@ Value *LibCallSimplifier::optimizeStrNCmp(CallInst *CI, IRBuilderBase &B) {
647648
StringRef SubStr1 = substr(Str1, Length);
648649
StringRef SubStr2 = substr(Str2, Length);
649650
return ConstantInt::get(CI->getType(),
650-
std::clamp(SubStr1.compare(SubStr2), -1, 1));
651+
std::clamp(SubStr1.compare(SubStr2), -1, 1),
652+
/*isSigned*/ true);
651653
}
652654

653655
if (HasStr1 && Str1.empty()) // strncmp("", x, n) -> -*x
@@ -1528,7 +1530,7 @@ static Value *optimizeMemCmpVarSize(CallInst *CI, Value *LHS, Value *RHS,
15281530
int IRes = UChar(LStr[Pos]) < UChar(RStr[Pos]) ? -1 : 1;
15291531
Value *MaxSize = ConstantInt::get(Size->getType(), Pos);
15301532
Value *Cmp = B.CreateICmp(ICmpInst::ICMP_ULE, Size, MaxSize);
1531-
Value *Res = ConstantInt::get(CI->getType(), IRes);
1533+
Value *Res = ConstantInt::get(CI->getType(), IRes, /*isSigned*/ true);
15321534
return B.CreateSelect(Cmp, Zero, Res);
15331535
}
15341536

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1606,7 +1606,7 @@ void VPVectorPointerRecipe ::execute(VPTransformState &State) {
16061606
Value *RunTimeVF = getRuntimeVF(Builder, IndexTy, State.VF);
16071607
// NumElt = -Part * RunTimeVF
16081608
Value *NumElt = Builder.CreateMul(
1609-
ConstantInt::get(IndexTy, -(int64_t)Part), RunTimeVF);
1609+
ConstantInt::getSigned(IndexTy, -(int64_t)Part), RunTimeVF);
16101610
// LastLane = 1 - RunTimeVF
16111611
Value *LastLane =
16121612
Builder.CreateSub(ConstantInt::get(IndexTy, 1), RunTimeVF);

0 commit comments

Comments
 (0)