From dd86bb25267f77478752db053b8e76b1f1861065 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 1 Feb 2024 16:05:29 +0100 Subject: [PATCH 1/3] [LoopUnroll] Add test for #80289 (NFC) --- .../Transforms/LoopUnroll/runtime-i128.ll | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 llvm/test/Transforms/LoopUnroll/runtime-i128.ll diff --git a/llvm/test/Transforms/LoopUnroll/runtime-i128.ll b/llvm/test/Transforms/LoopUnroll/runtime-i128.ll new file mode 100644 index 000000000000..50e09beddb37 --- /dev/null +++ b/llvm/test/Transforms/LoopUnroll/runtime-i128.ll @@ -0,0 +1,72 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 +; RUN: opt -S -passes=loop-unroll -unroll-runtime < %s | FileCheck %s + +declare void @foo() + +define void @test(i128 %n, i128 %m) { +; CHECK-LABEL: define void @test( +; CHECK-SAME: i128 [[N:%.*]], i128 [[M:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = freeze i128 [[N]] +; CHECK-NEXT: [[TMP1:%.*]] = add i128 [[TMP0]], 18446744073709551615 +; CHECK-NEXT: [[XTRAITER:%.*]] = and i128 [[TMP0]], 7 +; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i128 [[TMP1]], 7 +; CHECK-NEXT: br i1 [[TMP2]], label [[EXIT_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]] +; CHECK: entry.new: +; CHECK-NEXT: [[UNROLL_ITER:%.*]] = sub i128 [[TMP0]], [[XTRAITER]] +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[IV:%.*]] = phi i128 [ 0, [[ENTRY_NEW]] ], [ [[IV_NEXT_7:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[NITER:%.*]] = phi i128 [ 0, [[ENTRY_NEW]] ], [ [[NITER_NEXT_7:%.*]], [[LOOP]] ] +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: [[IV_NEXT_7]] = add i128 [[IV]], 8 +; CHECK-NEXT: [[NITER_NEXT_7]] = add i128 [[NITER]], 8 +; CHECK-NEXT: [[NITER_NCMP_7:%.*]] = icmp ne i128 [[NITER_NEXT_7]], [[UNROLL_ITER]] +; CHECK-NEXT: br i1 [[NITER_NCMP_7]], label [[LOOP]], label [[EXIT_UNR_LCSSA_LOOPEXIT:%.*]] +; CHECK: exit.unr-lcssa.loopexit: +; CHECK-NEXT: [[IV_UNR_PH:%.*]] = phi i128 [ [[IV_NEXT_7]], [[LOOP]] ] +; CHECK-NEXT: br label [[EXIT_UNR_LCSSA]] +; CHECK: exit.unr-lcssa: +; CHECK-NEXT: [[IV_UNR:%.*]] = phi i128 [ 0, [[ENTRY:%.*]] ], [ [[IV_UNR_PH]], [[EXIT_UNR_LCSSA_LOOPEXIT]] ] +; CHECK-NEXT: [[LCMP_MOD:%.*]] = icmp ne i128 [[XTRAITER]], 0 +; CHECK-NEXT: br i1 [[LCMP_MOD]], label [[LOOP_EPIL_PREHEADER:%.*]], label [[EXIT:%.*]] +; CHECK: loop.epil.preheader: +; CHECK-NEXT: br label [[LOOP_EPIL:%.*]] +; CHECK: loop.epil: +; CHECK-NEXT: [[IV_EPIL:%.*]] = phi i128 [ [[IV_UNR]], [[LOOP_EPIL_PREHEADER]] ], [ [[IV_NEXT_EPIL:%.*]], [[LOOP_EPIL]] ] +; CHECK-NEXT: [[EPIL_ITER:%.*]] = phi i128 [ 0, [[LOOP_EPIL_PREHEADER]] ], [ [[EPIL_ITER_NEXT:%.*]], [[LOOP_EPIL]] ] +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: [[IV_NEXT_EPIL]] = add i128 [[IV_EPIL]], 1 +; CHECK-NEXT: [[CMP_EPIL:%.*]] = icmp ne i128 [[IV_NEXT_EPIL]], [[N]] +; CHECK-NEXT: [[EPIL_ITER_NEXT]] = add i128 [[EPIL_ITER]], 1 +; CHECK-NEXT: [[EPIL_ITER_CMP:%.*]] = icmp ne i128 [[EPIL_ITER_NEXT]], [[XTRAITER]] +; CHECK-NEXT: br i1 [[EPIL_ITER_CMP]], label [[LOOP_EPIL]], label [[EXIT_EPILOG_LCSSA:%.*]], !llvm.loop [[LOOP0:![0-9]+]] +; CHECK: exit.epilog-lcssa: +; CHECK-NEXT: br label [[EXIT]] +; CHECK: exit: +; CHECK-NEXT: ret void +; +entry: + br label %loop + +loop: + %iv = phi i128 [ 0, %entry ], [ %iv.next, %loop ] + call void @foo() + %iv.next = add i128 %iv, 1 + %cmp = icmp ne i128 %iv.next, %n + br i1 %cmp, label %loop, label %exit + +exit: + ret void +} +;. +; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]]} +; CHECK: [[META1]] = !{!"llvm.loop.unroll.disable"} +;. From 007169b209ffe2e2010757426c10bfc1b6841930 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 1 Feb 2024 16:06:58 +0100 Subject: [PATCH 2/3] [LoopUnroll] Fix missing sign extension For integers larger than 64-bit, this would zero-extend a -1 value, instead of sign-extending it. Fixes https://github.com/llvm/llvm-project/issues/80289. --- llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp | 2 +- llvm/test/Transforms/LoopUnroll/runtime-i128.ll | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp index 1e22eca30d2d..d7192641e8e4 100644 --- a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp +++ b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp @@ -757,7 +757,7 @@ bool llvm::UnrollRuntimeLoopRemainder( !isGuaranteedNotToBeUndefOrPoison(TripCount, AC, PreHeaderBR, DT)) { TripCount = B.CreateFreeze(TripCount); BECount = - B.CreateAdd(TripCount, ConstantInt::get(TripCount->getType(), -1)); + B.CreateAdd(TripCount, Constant::getAllOnesValue(TripCount->getType())); } else { // If we don't need to freeze, use SCEVExpander for BECount as well, to // allow slightly better value reuse. diff --git a/llvm/test/Transforms/LoopUnroll/runtime-i128.ll b/llvm/test/Transforms/LoopUnroll/runtime-i128.ll index 50e09beddb37..4cd8e7ca5d16 100644 --- a/llvm/test/Transforms/LoopUnroll/runtime-i128.ll +++ b/llvm/test/Transforms/LoopUnroll/runtime-i128.ll @@ -8,7 +8,7 @@ define void @test(i128 %n, i128 %m) { ; CHECK-SAME: i128 [[N:%.*]], i128 [[M:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = freeze i128 [[N]] -; CHECK-NEXT: [[TMP1:%.*]] = add i128 [[TMP0]], 18446744073709551615 +; CHECK-NEXT: [[TMP1:%.*]] = add i128 [[TMP0]], -1 ; CHECK-NEXT: [[XTRAITER:%.*]] = and i128 [[TMP0]], 7 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i128 [[TMP1]], 7 ; CHECK-NEXT: br i1 [[TMP2]], label [[EXIT_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]] From 86e4253b466fed3b72945cf6990a3bbef82935fa Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 1 Feb 2024 17:27:46 +0100 Subject: [PATCH 3/3] 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. --- llvm/lib/Analysis/ConstantFolding.cpp | 5 +++-- llvm/lib/Analysis/MemoryBuiltins.cpp | 2 +- llvm/lib/Analysis/ScalarEvolution.cpp | 4 ++-- llvm/lib/Analysis/ValueTracking.cpp | 2 +- llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 2 +- llvm/lib/CodeGen/CodeGenPrepare.cpp | 2 +- llvm/lib/CodeGen/ExpandMemCmp.cpp | 2 +- llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp | 13 ++++++++----- .../Transforms/InstCombine/InstCombineCalls.cpp | 4 ++-- .../InstCombine/InstCombineCompares.cpp | 2 +- .../Transforms/InstCombine/InstCombineSelect.cpp | 8 ++++---- .../Transforms/Scalar/ConstraintElimination.cpp | 2 +- llvm/lib/Transforms/Scalar/IndVarSimplify.cpp | 16 ++++++++-------- .../lib/Transforms/Scalar/LoopStrengthReduce.cpp | 11 ++++++----- llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 5 +++-- llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp | 10 ++++++---- 16 files changed, 49 insertions(+), 41 deletions(-) diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index f0f625429c7e..9cbcaabe8fc9 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -3600,8 +3600,9 @@ ConstantFoldScalarFrexpCall(Constant *Op, Type *IntTy) { // The exponent is an "unspecified value" for inf/nan. We use zero to avoid // using undef. - Constant *Result1 = FrexpMant.isFinite() ? ConstantInt::get(IntTy, FrexpExp) - : ConstantInt::getNullValue(IntTy); + Constant *Result1 = FrexpMant.isFinite() + ? ConstantInt::getSigned(IntTy, FrexpExp) + : ConstantInt::getNullValue(IntTy); return {Result0, Result1}; } diff --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp index 53e089ba1fea..02c4b5c3b7b2 100644 --- a/llvm/lib/Analysis/MemoryBuiltins.cpp +++ b/llvm/lib/Analysis/MemoryBuiltins.cpp @@ -670,7 +670,7 @@ Value *llvm::lowerObjectSizeCall( if (!MustSucceed) return nullptr; - return ConstantInt::get(ResultType, MaxVal ? -1ULL : 0); + return ConstantInt::get(ResultType, MaxVal ? -1ULL : 0, true); } STATISTIC(ObjectVisitorArgument, diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 39ab48b4a48e..d183c51afb10 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -1455,7 +1455,7 @@ bool ScalarEvolution::proveNoWrapByVaryingStart(const SCEV *Start, APInt StartAI = StartC->getAPInt(); - for (unsigned Delta : {-2, -1, 1, 2}) { + for (int Delta : {-2, -1, 1, 2}) { const SCEV *PreStart = getConstant(StartAI - Delta); FoldingSetNodeID ID; @@ -1470,7 +1470,7 @@ bool ScalarEvolution::proveNoWrapByVaryingStart(const SCEV *Start, // Give up if we don't already have the add recurrence we need because // actually constructing an add recurrence is relatively expensive. if (PreAR && PreAR->getNoWrapFlags(WrapType)) { // proves (2) - const SCEV *DeltaS = getConstant(StartC->getType(), Delta); + const SCEV *DeltaS = getConstant(StartC->getType(), Delta, true); ICmpInst::Predicate Pred = ICmpInst::BAD_ICMP_PREDICATE; const SCEV *Limit = ExtendOpTraits::getOverflowLimitForStep( DeltaS, &Pred, this); diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 410f93b1c215..b99d539de274 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -8719,7 +8719,7 @@ static void setLimitForFPToI(const Instruction *I, APInt &Lower, APInt &Upper) { if (!I->getOperand(0)->getType()->getScalarType()->isHalfTy()) return; if (isa(I) && BitWidth >= 17) { - Lower = APInt(BitWidth, -65504); + Lower = APInt(BitWidth, -65504, true); Upper = APInt(BitWidth, 65505); } diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 3797a44c1793..13a31c4c4757 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -3023,7 +3023,7 @@ Error BitcodeReader::parseConstants() { case bitc::CST_CODE_INTEGER: // INTEGER: [intval] if (!CurTy->isIntegerTy() || Record.empty()) return error("Invalid integer const record"); - V = ConstantInt::get(CurTy, decodeSignRotatedValue(Record[0])); + V = ConstantInt::getSigned(CurTy, decodeSignRotatedValue(Record[0])); break; case bitc::CST_CODE_WIDE_INTEGER: {// WIDE_INTEGER: [n x intval] if (!CurTy->isIntegerTy() || Record.empty()) diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index b2e99ecfb48c..e919997dc13a 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -1584,7 +1584,7 @@ static bool matchUAddWithOverflowConstantEdgeCases(CmpInst *Cmp, if (Pred == ICmpInst::ICMP_EQ && match(B, m_AllOnes())) B = ConstantInt::get(B->getType(), 1); else if (Pred == ICmpInst::ICMP_NE && match(B, m_ZeroInt())) - B = ConstantInt::get(B->getType(), -1); + B = Constant::getAllOnesValue(B->getType()); else return false; diff --git a/llvm/lib/CodeGen/ExpandMemCmp.cpp b/llvm/lib/CodeGen/ExpandMemCmp.cpp index 500f31bd8e89..3a7a4d906585 100644 --- a/llvm/lib/CodeGen/ExpandMemCmp.cpp +++ b/llvm/lib/CodeGen/ExpandMemCmp.cpp @@ -537,7 +537,7 @@ void MemCmpExpansion::emitMemCmpResultBlock() { ResBlock.PhiSrc2); Value *Res = - Builder.CreateSelect(Cmp, ConstantInt::get(Builder.getInt32Ty(), -1), + Builder.CreateSelect(Cmp, Constant::getAllOnesValue(Builder.getInt32Ty()), ConstantInt::get(Builder.getInt32Ty(), 1)); PhiRes->addIncoming(Res, ResBlock.BB); diff --git a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp index d33258642365..19e50b558f59 100644 --- a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp +++ b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp @@ -1615,17 +1615,20 @@ Constant *DevirtModule::importConstant(VTableSlot Slot, ArrayRef Args, if (GV->hasMetadata(LLVMContext::MD_absolute_symbol)) return C; - auto SetAbsRange = [&](uint64_t Min, uint64_t Max) { + auto SetAbsRange = [&](const APInt &Min, const APInt &Max) { auto *MinC = ConstantAsMetadata::get(ConstantInt::get(IntPtrTy, Min)); auto *MaxC = ConstantAsMetadata::get(ConstantInt::get(IntPtrTy, Max)); GV->setMetadata(LLVMContext::MD_absolute_symbol, MDNode::get(M.getContext(), {MinC, MaxC})); }; unsigned AbsWidth = IntTy->getBitWidth(); - if (AbsWidth == IntPtrTy->getBitWidth()) - SetAbsRange(~0ull, ~0ull); // Full set. + unsigned IntPtrWidth = IntPtrTy->getBitWidth(); + if (AbsWidth == IntPtrWidth) + // Full set. + SetAbsRange(APInt::getAllOnes(IntPtrWidth), APInt::getAllOnes(IntPtrWidth)); else - SetAbsRange(0, 1ull << AbsWidth); + SetAbsRange(APInt::getZero(IntPtrWidth), + APInt::getOneBitSet(IntPtrWidth, AbsWidth)); return C; } @@ -1832,7 +1835,7 @@ bool DevirtModule::tryVirtualConstProp( } // Rewrite each call to a load from OffsetByte/OffsetBit. - Constant *ByteConst = ConstantInt::get(Int32Ty, OffsetByte); + Constant *ByteConst = ConstantInt::get(Int32Ty, OffsetByte, true); Constant *BitConst = ConstantInt::get(Int8Ty, 1ULL << OffsetBit); applyVirtualConstProp(CSByConstantArg.second, TargetsForSlot[0].Fn->getName(), ByteConst, BitConst); diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index a2be85673578..2da55f1d474d 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -306,8 +306,8 @@ Instruction *InstCombinerImpl::SimplifyAnyMemSet(AnyMemSetInst *MI) { Dest = Builder.CreateBitCast(Dest, NewDstPtrTy); // Extract the fill value and store. - const uint64_t Fill = FillC->getZExtValue()*0x0101010101010101ULL; - Constant *FillVal = ConstantInt::get(ITy, Fill); + Constant *FillVal = ConstantInt::get( + MI->getContext(), APInt::getSplat(Len * 8, FillC->getValue())); StoreInst *S = Builder.CreateStore(FillVal, Dest, MI->isVolatile()); S->copyMetadata(*MI, LLVMContext::MD_DIAssignID); for (auto *DAI : at::getAssignmentMarkers(S)) { diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index ced281d182d3..bcc73bcad364 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -305,7 +305,7 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal( DL.getTypeAllocSize(Init->getType()->getArrayElementType()); auto MaskIdx = [&](Value *Idx) { if (!GEP->isInBounds() && llvm::countr_zero(ElementSize) != 0) { - Value *Mask = ConstantInt::get(Idx->getType(), -1); + Value *Mask = Constant::getAllOnesValue(Idx->getType()); Mask = Builder.CreateLShr(Mask, llvm::countr_zero(ElementSize)); Idx = Builder.CreateAnd(Idx, Mask); } diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index 661c50062223..287065526486 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -665,11 +665,11 @@ static Value *foldSelectICmpLshrAshr(const ICmpInst *IC, Value *TrueVal, Value *X, *Y; unsigned Bitwidth = CmpRHS->getType()->getScalarSizeInBits(); if ((Pred != ICmpInst::ICMP_SGT || - !match(CmpRHS, - m_SpecificInt_ICMP(ICmpInst::ICMP_SGE, APInt(Bitwidth, -1)))) && + !match(CmpRHS, m_SpecificInt_ICMP(ICmpInst::ICMP_SGE, + APInt::getAllOnes(Bitwidth)))) && (Pred != ICmpInst::ICMP_SLT || - !match(CmpRHS, - m_SpecificInt_ICMP(ICmpInst::ICMP_SGE, APInt(Bitwidth, 0))))) + !match(CmpRHS, m_SpecificInt_ICMP(ICmpInst::ICMP_SGE, + APInt::getZero(Bitwidth))))) return nullptr; // Canonicalize so that ashr is in FalseVal. diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp index 5365bca0ab47..823f59ace776 100644 --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -746,7 +746,7 @@ void ConstraintInfo::transferToOtherSystem( addFact(CmpInst::ICMP_ULT, A, B, NumIn, NumOut, DFSInStack); break; case CmpInst::ICMP_SGT: { - if (doesHold(CmpInst::ICMP_SGE, B, ConstantInt::get(B->getType(), -1))) + if (doesHold(CmpInst::ICMP_SGE, B, Constant::getAllOnesValue(B->getType()))) addFact(CmpInst::ICMP_UGE, A, ConstantInt::get(B->getType(), 0), NumIn, NumOut, DFSInStack); if (doesHold(CmpInst::ICMP_SGE, B, ConstantInt::get(B->getType(), 0))) diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp index 40475d9563b2..abae54ce5d1c 100644 --- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -350,18 +350,18 @@ bool IndVarSimplify::handleFloatingPointIV(Loop *L, PHINode *PN) { IntegerType *Int32Ty = Type::getInt32Ty(PN->getContext()); // Insert new integer induction variable. - PHINode *NewPHI = PHINode::Create(Int32Ty, 2, PN->getName()+".int", PN); - NewPHI->addIncoming(ConstantInt::get(Int32Ty, InitValue), + PHINode *NewPHI = PHINode::Create(Int32Ty, 2, PN->getName() + ".int", PN); + NewPHI->addIncoming(ConstantInt::get(Int32Ty, InitValue, true), PN->getIncomingBlock(IncomingEdge)); - Value *NewAdd = - BinaryOperator::CreateAdd(NewPHI, ConstantInt::get(Int32Ty, IncValue), - Incr->getName()+".int", Incr); + Value *NewAdd = BinaryOperator::CreateAdd( + NewPHI, ConstantInt::get(Int32Ty, IncValue, true), + Incr->getName() + ".int", Incr); NewPHI->addIncoming(NewAdd, PN->getIncomingBlock(BackEdge)); - ICmpInst *NewCompare = new ICmpInst(TheBr, NewPred, NewAdd, - ConstantInt::get(Int32Ty, ExitValue), - Compare->getName()); + ICmpInst *NewCompare = new ICmpInst( + TheBr, NewPred, NewAdd, ConstantInt::get(Int32Ty, ExitValue, true), + Compare->getName()); // In the following deletions, PN may become dead and may be deleted. // Use a WeakTrackingVH to observe whether this happens. diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp index e208b339314f..3287b31432f2 100644 --- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -4046,7 +4046,7 @@ void LSRInstance::GenerateICmpZeroScales(LSRUse &LU, unsigned LUIdx, // Compensate for the use having MinOffset built into it. F.BaseOffset = (uint64_t)F.BaseOffset + Offset - LU.MinOffset; - const SCEV *FactorS = SE.getConstant(IntTy, Factor); + const SCEV *FactorS = SE.getConstant(IntTy, Factor, /*isSigned*/ true); // Check that multiplying with each base register doesn't overflow. for (size_t i = 0, e = F.BaseRegs.size(); i != e; ++i) { @@ -4122,7 +4122,7 @@ void LSRInstance::GenerateScales(LSRUse &LU, unsigned LUIdx, Formula Base) { for (size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i) { const SCEVAddRecExpr *AR = dyn_cast(Base.BaseRegs[i]); if (AR && (AR->getLoop() == L || LU.AllFixupsOutsideLoop)) { - const SCEV *FactorS = SE.getConstant(IntTy, Factor); + const SCEV *FactorS = SE.getConstant(IntTy, Factor, true); if (FactorS->isZero()) continue; // Divide out the factor, ignoring high bits, since we'll be @@ -4356,7 +4356,8 @@ void LSRInstance::GenerateCrossUseConstantOffsets() { const SCEV *OrigReg = WI.OrigReg; Type *IntTy = SE.getEffectiveSCEVType(OrigReg->getType()); - const SCEV *NegImmS = SE.getSCEV(ConstantInt::get(IntTy, -(uint64_t)Imm)); + const SCEV *NegImmS = + SE.getSCEV(ConstantInt::getSigned(IntTy, -(uint64_t)Imm)); unsigned BitWidth = SE.getTypeSizeInBits(IntTy); // TODO: Use a more targeted data structure. @@ -4371,8 +4372,8 @@ void LSRInstance::GenerateCrossUseConstantOffsets() { if (F.ScaledReg == OrigReg) { int64_t Offset = (uint64_t)F.BaseOffset + Imm * (uint64_t)F.Scale; // Don't create 50 + reg(-50). - if (F.referencesReg(SE.getSCEV( - ConstantInt::get(IntTy, -(uint64_t)Offset)))) + if (F.referencesReg( + SE.getSCEV(ConstantInt::getSigned(IntTy, -(uint64_t)Offset)))) continue; Formula NewF = F; NewF.BaseOffset = Offset; diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 0c114fde142a..05610c374d49 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -6745,7 +6745,8 @@ static bool ReduceSwitchRange(SwitchInst *SI, IRBuilder<> &Builder, auto *Ty = cast(SI->getCondition()->getType()); Builder.SetInsertPoint(SI); auto *ShiftC = ConstantInt::get(Ty, Shift); - auto *Sub = Builder.CreateSub(SI->getCondition(), ConstantInt::get(Ty, Base)); + auto *Sub = + Builder.CreateSub(SI->getCondition(), ConstantInt::getSigned(Ty, Base)); auto *LShr = Builder.CreateLShr(Sub, ShiftC); auto *Shl = Builder.CreateShl(Sub, Ty->getBitWidth() - Shift); auto *Rot = Builder.CreateOr(LShr, Shl); @@ -6753,7 +6754,7 @@ static bool ReduceSwitchRange(SwitchInst *SI, IRBuilder<> &Builder, for (auto Case : SI->cases()) { auto *Orig = Case.getCaseValue(); - auto Sub = Orig->getValue() - APInt(Ty->getBitWidth(), Base); + auto Sub = Orig->getValue() - APInt(Ty->getBitWidth(), Base, true); Case.setValue( cast(ConstantInt::get(Ty, Sub.lshr(ShiftC->getValue())))); } diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp index d86dd3ddeffa..04621efce3d8 100644 --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -239,7 +239,7 @@ static Value *convertStrToInt(CallInst *CI, StringRef &Str, Value *EndPtr, // Unsigned negation doesn't overflow. Result = -Result; - return ConstantInt::get(RetTy, Result); + return ConstantInt::get(RetTy, Result, AsSigned); } static bool isOnlyUsedInComparisonWithZero(Value *V) { @@ -568,7 +568,8 @@ Value *LibCallSimplifier::optimizeStrCmp(CallInst *CI, IRBuilderBase &B) { // strcmp(x, y) -> cnst (if both x and y are constant strings) if (HasStr1 && HasStr2) return ConstantInt::get(CI->getType(), - std::clamp(Str1.compare(Str2), -1, 1)); + std::clamp(Str1.compare(Str2), -1, 1), + /*isSigned*/ true); if (HasStr1 && Str1.empty()) // strcmp("", x) -> -*x return B.CreateNeg(B.CreateZExt( @@ -653,7 +654,8 @@ Value *LibCallSimplifier::optimizeStrNCmp(CallInst *CI, IRBuilderBase &B) { StringRef SubStr1 = substr(Str1, Length); StringRef SubStr2 = substr(Str2, Length); return ConstantInt::get(CI->getType(), - std::clamp(SubStr1.compare(SubStr2), -1, 1)); + std::clamp(SubStr1.compare(SubStr2), -1, 1), + /*isSigned*/ true); } if (HasStr1 && Str1.empty()) // strncmp("", x, n) -> -*x @@ -1536,7 +1538,7 @@ static Value *optimizeMemCmpVarSize(CallInst *CI, Value *LHS, Value *RHS, int IRes = UChar(LStr[Pos]) < UChar(RStr[Pos]) ? -1 : 1; Value *MaxSize = ConstantInt::get(Size->getType(), Pos); Value *Cmp = B.CreateICmp(ICmpInst::ICMP_ULE, Size, MaxSize); - Value *Res = ConstantInt::get(CI->getType(), IRes); + Value *Res = ConstantInt::get(CI->getType(), IRes, /*isSigned*/ true); return B.CreateSelect(Cmp, Zero, Res); }