Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cherry pick fixes for large signed constant truncation #630

Merged
merged 3 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions llvm/lib/Analysis/ConstantFolding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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};
}

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Analysis/MemoryBuiltins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Analysis/ScalarEvolution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<ExtendOpTy>::getOverflowLimitForStep(
DeltaS, &Pred, this);
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Analysis/ValueTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8719,7 +8719,7 @@ static void setLimitForFPToI(const Instruction *I, APInt &Lower, APInt &Upper) {
if (!I->getOperand(0)->getType()->getScalarType()->isHalfTy())
return;
if (isa<FPToSIInst>(I) && BitWidth >= 17) {
Lower = APInt(BitWidth, -65504);
Lower = APInt(BitWidth, -65504, true);
Upper = APInt(BitWidth, 65505);
}

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Bitcode/Reader/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/CodeGenPrepare.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/ExpandMemCmp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
13 changes: 8 additions & 5 deletions llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1615,17 +1615,20 @@ Constant *DevirtModule::importConstant(VTableSlot Slot, ArrayRef<uint64_t> 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;
}

Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
8 changes: 4 additions & 4 deletions llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)))
Expand Down
16 changes: 8 additions & 8 deletions llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
11 changes: 6 additions & 5 deletions llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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<SCEVAddRecExpr>(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
Expand Down Expand Up @@ -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.
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/Transforms/Utils/SimplifyCFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6745,15 +6745,16 @@ static bool ReduceSwitchRange(SwitchInst *SI, IRBuilder<> &Builder,
auto *Ty = cast<IntegerType>(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);
SI->replaceUsesOfWith(SI->getCondition(), Rot);

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>(ConstantInt::get(Ty, Sub.lshr(ShiftC->getValue()))));
}
Expand Down
10 changes: 6 additions & 4 deletions llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
}

Expand Down
72 changes: 72 additions & 0 deletions llvm/test/Transforms/LoopUnroll/runtime-i128.ll
Original file line number Diff line number Diff line change
@@ -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]], -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:%.*]]
; 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"}
;.
Loading