2 changes: 1 addition & 1 deletion llvm/lib/Target/ARM/MVETailPredication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ void MVETailPredication::RematerializeIterCount() {
ReplaceExitVal ReplaceExitValue = AlwaysRepl;

formLCSSARecursively(*L, *DT, LI, SE);
rewriteLoopExitValues(L, LI, TLI, SE, Rewriter, DT, ReplaceExitValue,
rewriteLoopExitValues(L, LI, TLI, SE, TTI, Rewriter, DT, ReplaceExitValue,
DeadInsts);
}

Expand Down
12 changes: 8 additions & 4 deletions llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1659,8 +1659,8 @@ bool IndVarSimplify::simplifyAndExtend(Loop *L,
// Information about sign/zero extensions of CurrIV.
IndVarSimplifyVisitor Visitor(CurrIV, SE, TTI, DT);

Changed |=
simplifyUsersOfIV(CurrIV, SE, DT, LI, DeadInsts, Rewriter, &Visitor);
Changed |= simplifyUsersOfIV(CurrIV, SE, DT, LI, TTI, DeadInsts, Rewriter,
&Visitor);

if (Visitor.WI.WidestNativeType) {
WideIVs.push_back(Visitor.WI);
Expand Down Expand Up @@ -2698,7 +2698,7 @@ bool IndVarSimplify::run(Loop *L) {
// loop into any instructions outside of the loop that use the final values
// of the current expressions.
if (ReplaceExitValue != NeverRepl) {
if (int Rewrites = rewriteLoopExitValues(L, LI, TLI, SE, Rewriter, DT,
if (int Rewrites = rewriteLoopExitValues(L, LI, TLI, SE, TTI, Rewriter, DT,
ReplaceExitValue, DeadInsts)) {
NumReplaced += Rewrites;
Changed = true;
Expand Down Expand Up @@ -2726,6 +2726,9 @@ bool IndVarSimplify::run(Loop *L) {
// If we have a trip count expression, rewrite the loop's exit condition
// using it.
if (!DisableLFTR) {
BasicBlock *PreHeader = L->getLoopPreheader();
BranchInst *PreHeaderBR = cast<BranchInst>(PreHeader->getTerminator());

SmallVector<BasicBlock*, 16> ExitingBlocks;
L->getExitingBlocks(ExitingBlocks);
for (BasicBlock *ExitingBB : ExitingBlocks) {
Expand Down Expand Up @@ -2759,7 +2762,8 @@ bool IndVarSimplify::run(Loop *L) {

// Avoid high cost expansions. Note: This heuristic is questionable in
// that our definition of "high cost" is not exactly principled.
if (Rewriter.isHighCostExpansion(ExitCount, L))
if (Rewriter.isHighCostExpansion(ExitCount, L, SCEVCheapExpansionBudget,
TTI, PreHeaderBR))
continue;

// Check preconditions for proper SCEVExpander operation. SCEV does not
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/Scalar/LoopUnrollAndJamPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ tryToUnrollAndJamLoop(Loop *L, DominatorTree &DT, LoopInfo *LI,
Loop *EpilogueOuterLoop = nullptr;
LoopUnrollResult UnrollResult = UnrollAndJamLoop(
L, UP.Count, OuterTripCount, OuterTripMultiple, UP.UnrollRemainder, LI,
&SE, &DT, &AC, &ORE, &EpilogueOuterLoop);
&SE, &DT, &AC, &TTI, &ORE, &EpilogueOuterLoop);

// Assign new loop attributes.
if (EpilogueOuterLoop) {
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1148,7 +1148,7 @@ static LoopUnrollResult tryToUnrollLoop(
{UP.Count, TripCount, UP.Force, UP.Runtime, UP.AllowExpensiveTripCount,
UseUpperBound, MaxOrZero, TripMultiple, UP.PeelCount, UP.UnrollRemainder,
ForgetAllSCEV},
LI, &SE, &DT, &AC, &ORE, PreserveLCSSA, &RemainderLoop);
LI, &SE, &DT, &AC, &TTI, &ORE, PreserveLCSSA, &RemainderLoop);
if (UnrollResult == LoopUnrollResult::Unmodified)
return LoopUnrollResult::Unmodified;

Expand Down
10 changes: 6 additions & 4 deletions llvm/lib/Transforms/Utils/LoopUnroll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,11 +203,12 @@ static bool isEpilogProfitable(Loop *L) {
/// simplify/dce pass of the instructions.
void llvm::simplifyLoopAfterUnroll(Loop *L, bool SimplifyIVs, LoopInfo *LI,
ScalarEvolution *SE, DominatorTree *DT,
AssumptionCache *AC) {
AssumptionCache *AC,
const TargetTransformInfo *TTI) {
// Simplify any new induction variables in the partially unrolled loop.
if (SE && SimplifyIVs) {
SmallVector<WeakTrackingVH, 16> DeadInsts;
simplifyLoopIVs(L, SE, DT, LI, DeadInsts);
simplifyLoopIVs(L, SE, DT, LI, TTI, DeadInsts);

// Aggressively clean up dead instructions that simplifyLoopIVs already
// identified. Any remaining should be cleaned up below.
Expand Down Expand Up @@ -282,6 +283,7 @@ void llvm::simplifyLoopAfterUnroll(Loop *L, bool SimplifyIVs, LoopInfo *LI,
LoopUnrollResult llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
ScalarEvolution *SE, DominatorTree *DT,
AssumptionCache *AC,
const TargetTransformInfo *TTI,
OptimizationRemarkEmitter *ORE,
bool PreserveLCSSA, Loop **RemainderLoop) {

Expand Down Expand Up @@ -440,7 +442,7 @@ LoopUnrollResult llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
if (RuntimeTripCount && ULO.TripMultiple % ULO.Count != 0 &&
!UnrollRuntimeLoopRemainder(L, ULO.Count, ULO.AllowExpensiveTripCount,
EpilogProfitability, ULO.UnrollRemainder,
ULO.ForgetAllSCEV, LI, SE, DT, AC,
ULO.ForgetAllSCEV, LI, SE, DT, AC, TTI,
PreserveLCSSA, RemainderLoop)) {
if (ULO.Force)
RuntimeTripCount = false;
Expand Down Expand Up @@ -902,7 +904,7 @@ LoopUnrollResult llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
// At this point, the code is well formed. We now simplify the unrolled loop,
// doing constant propagation and dead code elimination as we go.
simplifyLoopAfterUnroll(L, !CompletelyUnroll && (ULO.Count > 1 || Peeled), LI,
SE, DT, AC);
SE, DT, AC, TTI);

NumCompletelyUnrolled += CompletelyUnroll;
++NumUnrolled;
Expand Down
17 changes: 10 additions & 7 deletions llvm/lib/Transforms/Utils/LoopUnrollAndJam.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,12 @@ static void moveHeaderPhiOperandsToForeBlocks(BasicBlock *Header,
If EpilogueLoop is non-null, it receives the epilogue loop (if it was
necessary to create one and not fully unrolled).
*/
LoopUnrollResult llvm::UnrollAndJamLoop(
Loop *L, unsigned Count, unsigned TripCount, unsigned TripMultiple,
bool UnrollRemainder, LoopInfo *LI, ScalarEvolution *SE, DominatorTree *DT,
AssumptionCache *AC, OptimizationRemarkEmitter *ORE, Loop **EpilogueLoop) {
LoopUnrollResult
llvm::UnrollAndJamLoop(Loop *L, unsigned Count, unsigned TripCount,
unsigned TripMultiple, bool UnrollRemainder,
LoopInfo *LI, ScalarEvolution *SE, DominatorTree *DT,
AssumptionCache *AC, const TargetTransformInfo *TTI,
OptimizationRemarkEmitter *ORE, Loop **EpilogueLoop) {

// When we enter here we should have already checked that it is safe
BasicBlock *Header = L->getHeader();
Expand All @@ -220,7 +222,7 @@ LoopUnrollResult llvm::UnrollAndJamLoop(
if (!UnrollRuntimeLoopRemainder(L, Count, /*AllowExpensiveTripCount*/ false,
/*UseEpilogRemainder*/ true,
UnrollRemainder, /*ForgetAllSCEV*/ false,
LI, SE, DT, AC, true, EpilogueLoop)) {
LI, SE, DT, AC, TTI, true, EpilogueLoop)) {
LLVM_DEBUG(dbgs() << "Won't unroll-and-jam; remainder loop could not be "
"generated when assuming runtime trip count\n");
return LoopUnrollResult::Unmodified;
Expand Down Expand Up @@ -585,8 +587,9 @@ LoopUnrollResult llvm::UnrollAndJamLoop(
// At this point, the code is well formed. We now do a quick sweep over the
// inserted code, doing constant propagation and dead code elimination as we
// go.
simplifyLoopAfterUnroll(SubLoop, true, LI, SE, DT, AC);
simplifyLoopAfterUnroll(L, !CompletelyUnroll && Count > 1, LI, SE, DT, AC);
simplifyLoopAfterUnroll(SubLoop, true, LI, SE, DT, AC, TTI);
simplifyLoopAfterUnroll(L, !CompletelyUnroll && Count > 1, LI, SE, DT, AC,
TTI);

NumCompletelyUnrolledAndJammed += CompletelyUnroll;
++NumUnrolledAndJammed;
Expand Down
17 changes: 8 additions & 9 deletions llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -543,13 +543,11 @@ static bool canProfitablyUnrollMultiExitLoop(
/// if (extraiters != 0) jump Epil: // Omitted if unroll factor is 2.
/// EpilExit:

bool llvm::UnrollRuntimeLoopRemainder(Loop *L, unsigned Count,
bool AllowExpensiveTripCount,
bool UseEpilogRemainder,
bool UnrollRemainder, bool ForgetAllSCEV,
LoopInfo *LI, ScalarEvolution *SE,
DominatorTree *DT, AssumptionCache *AC,
bool PreserveLCSSA, Loop **ResultLoop) {
bool llvm::UnrollRuntimeLoopRemainder(
Loop *L, unsigned Count, bool AllowExpensiveTripCount,
bool UseEpilogRemainder, bool UnrollRemainder, bool ForgetAllSCEV,
LoopInfo *LI, ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC,
const TargetTransformInfo *TTI, bool PreserveLCSSA, Loop **ResultLoop) {
LLVM_DEBUG(dbgs() << "Trying runtime unrolling on Loop: \n");
LLVM_DEBUG(L->dump());
LLVM_DEBUG(UseEpilogRemainder ? dbgs() << "Using epilog remainder.\n"
Expand Down Expand Up @@ -637,7 +635,8 @@ bool llvm::UnrollRuntimeLoopRemainder(Loop *L, unsigned Count,
const DataLayout &DL = Header->getModule()->getDataLayout();
SCEVExpander Expander(*SE, DL, "loop-unroll");
if (!AllowExpensiveTripCount &&
Expander.isHighCostExpansion(TripCountSC, L, PreHeaderBR)) {
Expander.isHighCostExpansion(TripCountSC, L, SCEVCheapExpansionBudget,
TTI, PreHeaderBR)) {
LLVM_DEBUG(dbgs() << "High cost for expanding trip count scev!\n");
return false;
}
Expand Down Expand Up @@ -949,7 +948,7 @@ bool llvm::UnrollRuntimeLoopRemainder(Loop *L, unsigned Count,
/*AllowExpensiveTripCount*/ false, /*PreserveCondBr*/ true,
/*PreserveOnlyFirst*/ false, /*TripMultiple*/ 1,
/*PeelCount*/ 0, /*UnrollRemainder*/ false, ForgetAllSCEV},
LI, SE, DT, AC, /*ORE*/ nullptr, PreserveLCSSA);
LI, SE, DT, AC, TTI, /*ORE*/ nullptr, PreserveLCSSA);
}

if (ResultLoop && UnrollResult != LoopUnrollResult::FullyUnrolled)
Expand Down
23 changes: 13 additions & 10 deletions llvm/lib/Transforms/Utils/LoopUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1267,10 +1267,12 @@ static bool canLoopBeDeleted(Loop *L, SmallVector<RewritePhi, 8> &RewritePhiSet)
return true;
}

int llvm::rewriteLoopExitValues(Loop *L, LoopInfo *LI,
TargetLibraryInfo *TLI, ScalarEvolution *SE, SCEVExpander &Rewriter,
DominatorTree *DT, ReplaceExitVal ReplaceExitValue,
SmallVector<WeakTrackingVH, 16> &DeadInsts) {
int llvm::rewriteLoopExitValues(Loop *L, LoopInfo *LI, TargetLibraryInfo *TLI,
ScalarEvolution *SE,
const TargetTransformInfo *TTI,
SCEVExpander &Rewriter, DominatorTree *DT,
ReplaceExitVal ReplaceExitValue,
SmallVector<WeakTrackingVH, 16> &DeadInsts) {
// Check a pre-condition.
assert(L->isRecursivelyLCSSAForm(*DT, *LI) &&
"Indvars did not preserve LCSSA!");
Expand Down Expand Up @@ -1351,15 +1353,16 @@ int llvm::rewriteLoopExitValues(Loop *L, LoopInfo *LI,

// Computing the value outside of the loop brings no benefit if it is
// definitely used inside the loop in a way which can not be optimized
// away. Avoid doing so unless we know we have a value which computes
// the ExitValue already. TODO: This should be merged into SCEV
// expander to leverage its knowledge of existing expressions.
if (ReplaceExitValue != AlwaysRepl &&
!isa<SCEVConstant>(ExitValue) && !isa<SCEVUnknown>(ExitValue) &&
// away. Avoid doing so unless either we know we have a value
// which computes the ExitValue already, or it is cheap to do so.
// TODO: This should be merged into SCEV expander to leverage
// its knowledge of existing expressions.
bool HighCost = Rewriter.isHighCostExpansion(
ExitValue, L, SCEVCheapExpansionBudget, TTI, Inst);
if (ReplaceExitValue != AlwaysRepl && HighCost &&
hasHardUserWithinLoop(L, Inst))
continue;

bool HighCost = Rewriter.isHighCostExpansion(ExitValue, L, Inst);
Value *ExitVal = Rewriter.expandCodeFor(ExitValue, PN->getType(), Inst);

LLVM_DEBUG(dbgs() << "rewriteLoopExitValues: AfterLoopVal = "
Expand Down
23 changes: 14 additions & 9 deletions llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,19 @@ namespace {
LoopInfo *LI;
ScalarEvolution *SE;
DominatorTree *DT;
const TargetTransformInfo *TTI;
SCEVExpander &Rewriter;
SmallVectorImpl<WeakTrackingVH> &DeadInsts;

bool Changed;

public:
SimplifyIndvar(Loop *Loop, ScalarEvolution *SE, DominatorTree *DT,
LoopInfo *LI, SCEVExpander &Rewriter,
LoopInfo *LI, const TargetTransformInfo *TTI,
SCEVExpander &Rewriter,
SmallVectorImpl<WeakTrackingVH> &Dead)
: L(Loop), LI(LI), SE(SE), DT(DT), Rewriter(Rewriter), DeadInsts(Dead),
Changed(false) {
: L(Loop), LI(LI), SE(SE), DT(DT), TTI(TTI), Rewriter(Rewriter),
DeadInsts(Dead), Changed(false) {
assert(LI && "IV simplification requires LoopInfo");
}

Expand Down Expand Up @@ -667,7 +669,7 @@ bool SimplifyIndvar::replaceIVUserWithLoopInvariant(Instruction *I) {
return false;

// Do not generate something ridiculous even if S is loop invariant.
if (Rewriter.isHighCostExpansion(S, L, I))
if (Rewriter.isHighCostExpansion(S, L, SCEVCheapExpansionBudget, TTI, I))
return false;

auto *IP = GetLoopInvariantInsertPosition(L, I);
Expand Down Expand Up @@ -931,25 +933,28 @@ void IVVisitor::anchor() { }
/// Simplify instructions that use this induction variable
/// by using ScalarEvolution to analyze the IV's recurrence.
bool simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, DominatorTree *DT,
LoopInfo *LI, SmallVectorImpl<WeakTrackingVH> &Dead,
LoopInfo *LI, const TargetTransformInfo *TTI,
SmallVectorImpl<WeakTrackingVH> &Dead,
SCEVExpander &Rewriter, IVVisitor *V) {
SimplifyIndvar SIV(LI->getLoopFor(CurrIV->getParent()), SE, DT, LI, Rewriter,
Dead);
SimplifyIndvar SIV(LI->getLoopFor(CurrIV->getParent()), SE, DT, LI, TTI,
Rewriter, Dead);
SIV.simplifyUsers(CurrIV, V);
return SIV.hasChanged();
}

/// Simplify users of induction variables within this
/// loop. This does not actually change or add IVs.
bool simplifyLoopIVs(Loop *L, ScalarEvolution *SE, DominatorTree *DT,
LoopInfo *LI, SmallVectorImpl<WeakTrackingVH> &Dead) {
LoopInfo *LI, const TargetTransformInfo *TTI,
SmallVectorImpl<WeakTrackingVH> &Dead) {
SCEVExpander Rewriter(*SE, SE->getDataLayout(), "indvars");
#ifndef NDEBUG
Rewriter.setDebugType(DEBUG_TYPE);
#endif
bool Changed = false;
for (BasicBlock::iterator I = L->getHeader()->begin(); isa<PHINode>(I); ++I) {
Changed |= simplifyUsersOfIV(cast<PHINode>(I), SE, DT, LI, Dead, Rewriter);
Changed |=
simplifyUsersOfIV(cast<PHINode>(I), SE, DT, LI, TTI, Dead, Rewriter);
}
return Changed;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -indvars -S | FileCheck %s

; This tests that the IV is not recomputed outside of the loop when it is known
; to be computed by the loop and used in the loop any way. In the example below
; although a's value can be computed outside of the loop, there is no benefit
; in doing so as it has to be computed by the loop anyway.
; This tests that the IV is recomputed outside of the loop even when it is known
; to be computed by the loop and used in the loop any way, if it is cheap to do
; so. In the example below the value can be computed outside of the loop,
; and we should do so because after that IV is no longer used outside of
; the loop, which is likely beneficial for vectorization.
;
; extern void func(unsigned val);
;
Expand Down Expand Up @@ -35,8 +36,8 @@ define void @test(i32 %m) nounwind uwtable {
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186
; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]]
; CHECK: for.end:
; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ]
; CHECK-NEXT: tail call void @func(i32 [[ADD_LCSSA]])
; CHECK-NEXT: [[TMP0:%.*]] = mul i32 [[M]], 186
; CHECK-NEXT: tail call void @func(i32 [[TMP0]])
; CHECK-NEXT: ret void
;
entry:
Expand Down Expand Up @@ -69,8 +70,8 @@ define i32 @test2(i32 %m) nounwind uwtable {
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186
; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]]
; CHECK: for.end:
; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ]
; CHECK-NEXT: ret i32 [[ADD_LCSSA]]
; CHECK-NEXT: [[TMP0:%.*]] = mul i32 [[M]], 186
; CHECK-NEXT: ret i32 [[TMP0]]
;
entry:
br label %for.body
Expand Down Expand Up @@ -101,8 +102,8 @@ define void @test3(i32 %m) nounwind uwtable {
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186
; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]]
; CHECK: for.end:
; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ]
; CHECK-NEXT: tail call void @func(i32 [[ADD_LCSSA]])
; CHECK-NEXT: [[TMP0:%.*]] = mul i32 [[M]], 186
; CHECK-NEXT: tail call void @func(i32 [[TMP0]])
; CHECK-NEXT: ret void
;
entry:
Expand Down Expand Up @@ -141,8 +142,8 @@ define void @test4(i32 %m) nounwind uwtable {
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186
; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]]
; CHECK: for.end:
; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ]
; CHECK-NEXT: [[SOFT_USE:%.*]] = add i32 [[ADD_LCSSA]], 123
; CHECK-NEXT: [[TMP0:%.*]] = mul i32 [[M]], 186
; CHECK-NEXT: [[SOFT_USE:%.*]] = add i32 [[TMP0]], 123
; CHECK-NEXT: tail call void @func(i32 [[SOFT_USE]])
; CHECK-NEXT: ret void
;
Expand Down Expand Up @@ -178,8 +179,8 @@ define void @test5(i32 %m) nounwind uwtable {
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186
; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]]
; CHECK: for.end:
; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ]
; CHECK-NEXT: tail call void @func(i32 [[ADD_LCSSA]])
; CHECK-NEXT: [[TMP0:%.*]] = mul i32 [[M]], 186
; CHECK-NEXT: tail call void @func(i32 [[TMP0]])
; CHECK-NEXT: ret void
;
entry:
Expand Down Expand Up @@ -215,8 +216,8 @@ define void @test6(i32 %m, i32* %p) nounwind uwtable {
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186
; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]]
; CHECK: for.end:
; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ]
; CHECK-NEXT: tail call void @func(i32 [[ADD_LCSSA]])
; CHECK-NEXT: [[TMP0:%.*]] = mul i32 [[M]], 186
; CHECK-NEXT: tail call void @func(i32 [[TMP0]])
; CHECK-NEXT: ret void
;
entry:
Expand Down
20 changes: 12 additions & 8 deletions llvm/test/Transforms/IndVarSimplify/elim-extend.ll
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
define void @postincConstIV(i8* %base, i32 %limit) nounwind {
; CHECK-LABEL: @postincConstIV(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[LIMIT:%.*]] to i64
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[LIMIT:%.*]], 0
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i32 [[LIMIT]], i32 0
; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[SMAX]], 1
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP1]] to i64
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
Expand All @@ -19,8 +22,8 @@ define void @postincConstIV(i8* %base, i32 %limit) nounwind {
; CHECK-NEXT: store i8 0, i8* [[POSTADR]]
; CHECK-NEXT: [[POSTADRNSW:%.*]] = getelementptr inbounds i8, i8* [[BASE]], i64 [[INDVARS_IV_NEXT]]
; CHECK-NEXT: store i8 0, i8* [[POSTADRNSW]]
; CHECK-NEXT: [[COND:%.*]] = icmp sgt i64 [[TMP0]], [[INDVARS_IV]]
; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: br label [[RETURN:%.*]]
; CHECK: return:
Expand Down Expand Up @@ -113,7 +116,9 @@ define void @nestedIV(i8* %address, i32 %limit) nounwind {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LIMITDEC:%.*]] = add i32 [[LIMIT:%.*]], -1
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[LIMITDEC]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[LIMIT]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[LIMIT]], 1
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP1]], i32 [[LIMIT]], i32 1
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
; CHECK-NEXT: br label [[OUTERLOOP:%.*]]
; CHECK: outerloop:
; CHECK-NEXT: [[INDVARS_IV1:%.*]] = phi i64 [ [[INDVARS_IV_NEXT2:%.*]], [[OUTERMERGE:%.*]] ], [ 0, [[ENTRY:%.*]] ]
Expand All @@ -138,8 +143,7 @@ define void @nestedIV(i8* %address, i32 %limit) nounwind {
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[TMP0]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[INNERLOOP]], label [[INNEREXIT:%.*]]
; CHECK: innerexit:
; CHECK-NEXT: [[INNERCOUNT_LCSSA_WIDE:%.*]] = phi i64 [ [[INDVARS_IV_NEXT]], [[INNERLOOP]] ]
; CHECK-NEXT: [[TMP4:%.*]] = trunc i64 [[INNERCOUNT_LCSSA_WIDE]] to i32
; CHECK-NEXT: [[TMP4:%.*]] = trunc i64 [[TMP0]] to i32
; CHECK-NEXT: br label [[OUTERMERGE]]
; CHECK: outermerge:
; CHECK-NEXT: [[INNERCOUNT_MERGE]] = phi i32 [ [[TMP4]], [[INNEREXIT]] ], [ [[INNERCOUNT]], [[INNERPREHEADER]] ]
Expand All @@ -149,8 +153,8 @@ define void @nestedIV(i8* %address, i32 %limit) nounwind {
; CHECK-NEXT: [[ADR5:%.*]] = getelementptr i8, i8* [[ADDRESS]], i64 [[OFS5]]
; CHECK-NEXT: store i8 0, i8* [[ADR5]]
; CHECK-NEXT: [[INDVARS_IV_NEXT2]] = add nuw nsw i64 [[INDVARS_IV1]], 1
; CHECK-NEXT: [[TMP47:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT2]], [[TMP1]]
; CHECK-NEXT: br i1 [[TMP47]], label [[OUTERLOOP]], label [[RETURN:%.*]]
; CHECK-NEXT: [[EXITCOND4:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT2]], [[WIDE_TRIP_COUNT]]
; CHECK-NEXT: br i1 [[EXITCOND4]], label [[OUTERLOOP]], label [[RETURN:%.*]]
; CHECK: return:
; CHECK-NEXT: ret void
;
Expand Down
17 changes: 11 additions & 6 deletions llvm/test/Transforms/IndVarSimplify/eliminate-comparison.ll
Original file line number Diff line number Diff line change
Expand Up @@ -529,16 +529,19 @@ define void @func_17(i32* %len.ptr) {
; CHECK-NEXT: [[ENTRY_COND:%.*]] = and i1 [[ENTRY_COND_0]], [[ENTRY_COND_1]]
; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[LEAVE:%.*]]
; CHECK: loop.preheader:
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[LEN]], 0
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i32 [[LEN]], i32 0
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[SMAX]], -5
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV_2:%.*]] = phi i32 [ [[IV_2_INC:%.*]], [[BE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_INC:%.*]], [[BE:%.*]] ], [ -6, [[LOOP_PREHEADER]] ]
; CHECK-NEXT: call void @side_effect()
; CHECK-NEXT: [[IV_2_INC]] = add nuw i32 [[IV_2]], 1
; CHECK-NEXT: [[IV_INC]] = add nsw i32 [[IV]], 1
; CHECK-NEXT: br i1 true, label [[BE]], label [[LEAVE_LOOPEXIT:%.*]]
; CHECK: be:
; CHECK-NEXT: call void @side_effect()
; CHECK-NEXT: [[BE_COND:%.*]] = icmp slt i32 [[IV_2]], [[LEN]]
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[LEAVE_LOOPEXIT]]
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV_INC]], [[TMP1]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LEAVE_LOOPEXIT]]
; CHECK: leave.loopexit:
; CHECK-NEXT: br label [[LEAVE]]
; CHECK: leave:
Expand Down Expand Up @@ -685,6 +688,8 @@ define void @func_20(i32* %length.ptr) {
; CHECK-NEXT: [[LENGTH_IS_NONZERO:%.*]] = icmp ne i32 [[LENGTH]], 0
; CHECK-NEXT: br i1 [[LENGTH_IS_NONZERO]], label [[LOOP_PREHEADER:%.*]], label [[LEAVE:%.*]]
; CHECK: loop.preheader:
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[LENGTH]], 1
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i32 [[LENGTH]], i32 1
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_INC:%.*]], [[BE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
Expand All @@ -693,8 +698,8 @@ define void @func_20(i32* %length.ptr) {
; CHECK-NEXT: br i1 [[EXITCOND]], label [[BE]], label [[LEAVE_LOOPEXIT:%.*]]
; CHECK: be:
; CHECK-NEXT: call void @side_effect()
; CHECK-NEXT: [[BE_COND:%.*]] = icmp slt i32 [[IV_INC]], [[LENGTH]]
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[LEAVE_LOOPEXIT]]
; CHECK-NEXT: [[EXITCOND1:%.*]] = icmp ne i32 [[IV_INC]], [[SMAX]]
; CHECK-NEXT: br i1 [[EXITCOND1]], label [[LOOP]], label [[LEAVE_LOOPEXIT]]
; CHECK: leave.loopexit:
; CHECK-NEXT: br label [[LEAVE]]
; CHECK: leave:
Expand Down
73 changes: 48 additions & 25 deletions llvm/test/Transforms/IndVarSimplify/eliminate-trunc.ll
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,16 @@ define void @test_01(i32 %n) {
;
; CHECK-LABEL: @test_01(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 0
; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[SMAX]], 1
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP1]] to i64
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]]
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[WIDE_TRIP_COUNT]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
Expand All @@ -63,13 +66,16 @@ define void @test_02(i32 %n) {
;
; CHECK-LABEL: @test_02(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[N:%.*]], 2147483646
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 2147483646
; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[SMAX]], 1
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP1]] to i64
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 2147483646, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]]
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[WIDE_TRIP_COUNT]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
Expand Down Expand Up @@ -113,13 +119,16 @@ define void @test_04(i32 %n) {
;
; CHECK-LABEL: @test_04(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[N:%.*]], -2147483647
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 -2147483647
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[SMAX]], 1
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -2147483647, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], 1
; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]]
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP1]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
Expand Down Expand Up @@ -243,13 +252,16 @@ exit:
define void @test_02_unsigned(i32 %n) {
; CHECK-LABEL: @test_02_unsigned(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64
; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i32 [[N:%.*]], -2
; CHECK-NEXT: [[UMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 -2
; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[UMAX]], 1
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 4294967294, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV]], [[ZEXT]]
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP1]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
Expand Down Expand Up @@ -318,13 +330,16 @@ exit:
define void @test_05_unsigned(i32 %n) {
; CHECK-LABEL: @test_05_unsigned(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64
; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i32 [[N:%.*]], 1
; CHECK-NEXT: [[UMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 1
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[UMAX]], 1
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV]], [[ZEXT]]
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP1]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
Expand Down Expand Up @@ -366,14 +381,18 @@ exit:
define void @test_07(i32* %p, i32 %n) {
; CHECK-LABEL: @test_07(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 0
; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[SMAX]], 1
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP1]] to i64
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
; CHECK-NEXT: store i32 [[NARROW_IV]], i32* [[P:%.*]]
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[NARROW_IV]], [[N:%.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[WIDE_TRIP_COUNT]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
Expand Down Expand Up @@ -451,15 +470,17 @@ exit:
define void @test_10(i32 %n) {
; CHECK-LABEL: @test_10(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 100
; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP1]], 90
; CHECK-NEXT: [[UMIN:%.*]] = select i1 [[TMP2]], i64 [[TMP1]], i64 90
; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[UMIN]], -99
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -100, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT: [[TMP0:%.*]] = icmp ne i64 [[IV]], [[SEXT]]
; CHECK-NEXT: [[NEGCMP:%.*]] = icmp slt i64 [[IV]], -10
; CHECK-NEXT: [[CMP:%.*]] = and i1 [[TMP0]], [[NEGCMP]]
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[TMP3]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
Expand Down Expand Up @@ -530,13 +551,15 @@ define void @test_12(i32* %p) {
; CHECK-LABEL: @test_12(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[N:%.*]] = load i32, i32* [[P:%.*]], !range !0
; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N]] to i64
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[N]], 1
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 1
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV_NEXT]], [[ZEXT]]
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[WIDE_TRIP_COUNT]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
Expand Down
40 changes: 20 additions & 20 deletions llvm/test/Transforms/IndVarSimplify/exit_value_test2.ll
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ define i32 @_Z3fooPKcjj(i8* nocapture readonly %s, i32 %len, i32 %c) {
; CHECK-LABEL: @_Z3fooPKcjj(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[TMP:%.*]] = bitcast i32* [[A]] to i8*
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP]])
; CHECK-NEXT: [[T:%.*]] = bitcast i32* [[A]] to i8*
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[T]])
; CHECK-NEXT: store i32 -1640531527, i32* [[A]], align 4
; CHECK-NEXT: [[CMP8:%.*]] = icmp ugt i32 [[LEN:%.*]], 11
; CHECK-NEXT: br i1 [[CMP8]], label [[WHILE_BODY_LR_PH:%.*]], label [[WHILE_END:%.*]]
Expand All @@ -23,12 +23,12 @@ define i32 @_Z3fooPKcjj(i8* nocapture readonly %s, i32 %len, i32 %c) {
; CHECK: while.body:
; CHECK-NEXT: [[KEYLEN_010:%.*]] = phi i32 [ [[LEN]], [[WHILE_BODY_LR_PH]] ], [ [[SUB:%.*]], [[WHILE_BODY]] ]
; CHECK-NEXT: [[S_ADDR_09:%.*]] = phi i8* [ [[S:%.*]], [[WHILE_BODY_LR_PH]] ], [ [[ADD_PTR:%.*]], [[WHILE_BODY]] ]
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[S_ADDR_09]] to i32*
; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4
; CHECK-NEXT: [[SHL_I:%.*]] = shl i32 [[TMP2]], 1
; CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[S_ADDR_09]] to i32*
; CHECK-NEXT: [[T2:%.*]] = load i32, i32* [[T1]], align 4
; CHECK-NEXT: [[SHL_I:%.*]] = shl i32 [[T2]], 1
; CHECK-NEXT: [[AND_I:%.*]] = and i32 [[SHL_I]], 16843008
; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[A]], align 4
; CHECK-NEXT: [[SUB_I:%.*]] = add i32 [[TMP3]], [[TMP2]]
; CHECK-NEXT: [[T3:%.*]] = load i32, i32* [[A]], align 4
; CHECK-NEXT: [[SUB_I:%.*]] = add i32 [[T3]], [[T2]]
; CHECK-NEXT: [[ADD:%.*]] = sub i32 [[SUB_I]], [[AND_I]]
; CHECK-NEXT: store i32 [[ADD]], i32* [[A]], align 4
; CHECK-NEXT: [[ADD_PTR]] = getelementptr inbounds i8, i8* [[S_ADDR_09]], i64 12
Expand All @@ -41,14 +41,14 @@ define i32 @_Z3fooPKcjj(i8* nocapture readonly %s, i32 %len, i32 %c) {
; CHECK: while.end:
; CHECK-NEXT: [[KEYLEN_0_LCSSA:%.*]] = phi i32 [ [[SUB_LCSSA]], [[WHILE_COND_WHILE_END_CRIT_EDGE]] ], [ [[LEN]], [[ENTRY:%.*]] ]
; CHECK-NEXT: call void @_Z3mixRjj(i32* dereferenceable(4) [[A]], i32 [[KEYLEN_0_LCSSA]])
; CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* [[A]], align 4
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP]])
; CHECK-NEXT: ret i32 [[TMP4]]
; CHECK-NEXT: [[T4:%.*]] = load i32, i32* [[A]], align 4
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[T]])
; CHECK-NEXT: ret i32 [[T4]]
;
entry:
%a = alloca i32, align 4
%tmp = bitcast i32* %a to i8*
call void @llvm.lifetime.start.p0i8(i64 4, i8* %tmp)
%t = bitcast i32* %a to i8*
call void @llvm.lifetime.start.p0i8(i64 4, i8* %t)
store i32 -1640531527, i32* %a, align 4
%cmp8 = icmp ugt i32 %len, 11
br i1 %cmp8, label %while.body.lr.ph, label %while.end
Expand All @@ -59,12 +59,12 @@ while.body.lr.ph: ; preds = %entry
while.body: ; preds = %while.body, %while.body.lr.ph
%keylen.010 = phi i32 [ %len, %while.body.lr.ph ], [ %sub, %while.body ]
%s.addr.09 = phi i8* [ %s, %while.body.lr.ph ], [ %add.ptr, %while.body ]
%tmp1 = bitcast i8* %s.addr.09 to i32*
%tmp2 = load i32, i32* %tmp1, align 4
%shl.i = shl i32 %tmp2, 1
%t1 = bitcast i8* %s.addr.09 to i32*
%t2 = load i32, i32* %t1, align 4
%shl.i = shl i32 %t2, 1
%and.i = and i32 %shl.i, 16843008
%tmp3 = load i32, i32* %a, align 4
%sub.i = add i32 %tmp3, %tmp2
%t3 = load i32, i32* %a, align 4
%sub.i = add i32 %t3, %t2
%add = sub i32 %sub.i, %and.i
store i32 %add, i32* %a, align 4
%add.ptr = getelementptr inbounds i8, i8* %s.addr.09, i64 12
Expand All @@ -79,9 +79,9 @@ while.cond.while.end_crit_edge: ; preds = %while.body
while.end: ; preds = %while.cond.while.end_crit_edge, %entry
%keylen.0.lcssa = phi i32 [ %sub.lcssa, %while.cond.while.end_crit_edge ], [ %len, %entry ]
call void @_Z3mixRjj(i32* dereferenceable(4) %a, i32 %keylen.0.lcssa)
%tmp4 = load i32, i32* %a, align 4
call void @llvm.lifetime.end.p0i8(i64 4, i8* %tmp)
ret i32 %tmp4
%t4 = load i32, i32* %a, align 4
call void @llvm.lifetime.end.p0i8(i64 4, i8* %t)
ret i32 %t4
}

define i32 @zero_backedge_count_test(i32 %unknown_init, i32* %unknown_mem) {
Expand Down
8 changes: 5 additions & 3 deletions llvm/test/Transforms/IndVarSimplify/full_widening.ll
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
define i32 @test_01(double* %p, double %x, i32* %np, i32* %mp, i32 %k) {
; CHECK-LABEL: @test_01(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[K:%.*]] to i64
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[K:%.*]], 1
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i32 [[K]], i32 1
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV_WIDE:%.*]] = phi i64 [ [[CANONICAL_IV_NEXT_I:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
Expand All @@ -17,8 +19,8 @@ define i32 @test_01(double* %p, double %x, i32* %np, i32* %mp, i32 %k) {
; CHECK-NEXT: [[MUL:%.*]] = fmul double [[X:%.*]], [[LOAD]]
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds double, double* [[P]], i64 [[IV_WIDE]]
; CHECK-NEXT: store atomic double [[MUL]], double* [[GEP2]] unordered, align 8
; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp slt i64 [[CANONICAL_IV_NEXT_I]], [[TMP0]]
; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[CANONICAL_IV_NEXT_I]], [[WIDE_TRIP_COUNT]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret i32 0
;
Expand Down
16 changes: 10 additions & 6 deletions llvm/test/Transforms/IndVarSimplify/iv-widen.ll
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,17 @@ define void @loop_1(i32 %lim) {
; CHECK-NEXT: [[ENTRY_COND:%.*]] = icmp ne i32 [[LIM:%.*]], 0
; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[LEAVE:%.*]]
; CHECK: loop.preheader:
; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[LIM]] to i64
; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i32 [[LIM]], 2
; CHECK-NEXT: [[UMAX:%.*]] = select i1 [[TMP0]], i32 [[LIM]], i32 2
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[UMAX]] to i64
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 1, [[LOOP_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
; CHECK-NEXT: [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
; CHECK-NEXT: call void @dummy.i64(i64 [[TMP1]])
; CHECK-NEXT: [[BE_COND:%.*]] = icmp ult i64 [[INDVARS_IV_NEXT]], [[TMP0]]
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[LEAVE_LOOPEXIT:%.*]]
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LEAVE_LOOPEXIT:%.*]]
; CHECK: leave.loopexit:
; CHECK-NEXT: br label [[LEAVE]]
; CHECK: leave:
Expand Down Expand Up @@ -165,7 +167,9 @@ define void @loop_2(i32 %size, i32 %nsteps, i32 %hsize, i32* %lined, i8 %tmp1) {
; CHECK-NEXT: [[BC0:%.*]] = bitcast i32* [[LINED:%.*]] to i8*
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[SIZE]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[HSIZE:%.*]] to i64
; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[NSTEPS:%.*]] to i64
; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[NSTEPS:%.*]], 1
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP2]], i32 [[NSTEPS]], i32 1
; CHECK-NEXT: [[WIDE_TRIP_COUNT11:%.*]] = zext i32 [[SMAX]] to i64
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[INDVARS_IV7:%.*]] = phi i64 [ [[INDVARS_IV_NEXT8:%.*]], [[FOR_INC:%.*]] ], [ 0, [[ENTRY:%.*]] ]
Expand Down Expand Up @@ -200,8 +204,8 @@ define void @loop_2(i32 %size, i32 %nsteps, i32 %hsize, i32* %lined, i8 %tmp1) {
; CHECK-NEXT: br label [[FOR_INC]]
; CHECK: for.inc:
; CHECK-NEXT: [[INDVARS_IV_NEXT8]] = add nuw nsw i64 [[INDVARS_IV7]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT8]], [[TMP2]]
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]]
; CHECK-NEXT: [[EXITCOND12:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT8]], [[WIDE_TRIP_COUNT11]]
; CHECK-NEXT: br i1 [[EXITCOND12]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]]
; CHECK: for.end.loopexit:
; CHECK-NEXT: ret void
;
Expand Down
12 changes: 6 additions & 6 deletions llvm/test/Transforms/IndVarSimplify/lftr-multi-exit.ll
Original file line number Diff line number Diff line change
Expand Up @@ -128,18 +128,18 @@ exit:
define void @compound_early_exit(i32 %n, i32 %m) {
; CHECK-LABEL: @compound_early_exit(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[M:%.*]], [[N:%.*]]
; CHECK-NEXT: [[UMIN:%.*]] = select i1 [[TMP0]], i32 [[M]], i32 [[N]]
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
; CHECK-NEXT: [[EARLYCND:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
; CHECK-NEXT: [[EARLYCND2:%.*]] = icmp ult i32 [[IV]], [[M:%.*]]
; CHECK-NEXT: [[AND:%.*]] = and i1 [[EARLYCND]], [[EARLYCND2]]
; CHECK-NEXT: br i1 [[AND]], label [[LATCH]], label [[EXIT:%.*]]
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV]], [[UMIN]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LATCH]], label [[EXIT:%.*]]
; CHECK: latch:
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
; CHECK-NEXT: store volatile i32 [[IV]], i32* @A
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV_NEXT]], 1000
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT]]
; CHECK-NEXT: [[EXITCOND1:%.*]] = icmp ne i32 [[IV_NEXT]], 1000
; CHECK-NEXT: br i1 [[EXITCOND1]], label [[LOOP]], label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
Expand Down
8 changes: 5 additions & 3 deletions llvm/test/Transforms/IndVarSimplify/lftr-reuse.ll
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,15 @@ define void @unguardedloop([0 x double]* %matrix, [0 x double]* %vector,
;
; CHECK-LABEL: @unguardedloop(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[IROW:%.*]] to i64
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[IROW:%.*]], 1
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i32 [[IROW]], i32 1
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[INDVARS_IV2:%.*]] = phi i64 [ [[INDVARS_IV_NEXT3:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT: [[INDVARS_IV_NEXT3]] = add nuw nsw i64 [[INDVARS_IV2]], 1
; CHECK-NEXT: [[CMP196:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT3]], [[TMP0]]
; CHECK-NEXT: br i1 [[CMP196]], label [[LOOP]], label [[RETURN:%.*]]
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT3]], [[WIDE_TRIP_COUNT]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[RETURN:%.*]]
; CHECK: return:
; CHECK-NEXT: ret void
;
Expand Down
22 changes: 14 additions & 8 deletions llvm/test/Transforms/IndVarSimplify/loop-invariant-conditions.ll
Original file line number Diff line number Diff line change
Expand Up @@ -311,12 +311,15 @@ for.end: ; preds = %if.end, %entry
define void @test3_neg(i64 %start) {
; CHECK-LABEL: @test3_neg(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i64 [[START:%.*]], -1
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i64 [[START]], i64 -1
; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[SMAX]], 1
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[INDVARS_IV]], -1
; CHECK-NEXT: br i1 [[CMP1]], label [[LOOP]], label [[FOR_END:%.*]]
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[TMP1]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[FOR_END:%.*]]
; CHECK: for.end:
; CHECK-NEXT: ret void
;
Expand All @@ -336,16 +339,19 @@ for.end: ; preds = %if.end, %entry
define void @test4_neg(i64 %start) {
; CHECK-LABEL: @test4_neg(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i64 [[START:%.*]], 0
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i64 [[START]], i64 0
; CHECK-NEXT: [[TMP1:%.*]] = add nuw i64 [[SMAX]], 1
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25
; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]]
; CHECK: backedge:
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i64 [[INDVARS_IV]], -1
; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END]], label [[LOOP]]
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[TMP1]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END]], label [[LOOP]]
; CHECK: for.end:
; CHECK-NEXT: ret void
;
Expand Down
3 changes: 1 addition & 2 deletions llvm/test/Transforms/IndVarSimplify/lrev-existing-umin.ll
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ define void @f(i32 %length.i.88, i32 %length.i, i8* %tmp12, i32 %tmp10, i8* %tmp
; CHECK-NEXT: [[TMP23:%.*]] = icmp slt i32 [[TMP22]], [[TMP14]]
; CHECK-NEXT: br i1 [[TMP23]], label [[NOT_ZERO11]], label [[MAIN_EXIT_SELECTOR:%.*]]
; CHECK: main.exit.selector:
; CHECK-NEXT: [[TMP22_LCSSA:%.*]] = phi i32 [ [[TMP22]], [[NOT_ZERO11]] ]
; CHECK-NEXT: [[TMP24:%.*]] = icmp slt i32 [[TMP22_LCSSA]], [[LENGTH_I]]
; CHECK-NEXT: [[TMP24:%.*]] = icmp slt i32 [[TMP14]], [[LENGTH_I]]
; CHECK-NEXT: br i1 [[TMP24]], label [[NOT_ZERO11_POSTLOOP]], label [[LEAVE:%.*]]
; CHECK: leave:
; CHECK-NEXT: ret void
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/Transforms/IndVarSimplify/pr28705.ll
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ define void @foo(i32 %sub.ptr.div.i, i8* %ref.i1174) local_unnamed_addr {
; CHECK: for.body650.lr.ph:
; CHECK-NEXT: br label [[FOR_BODY650:%.*]]
; CHECK: loopexit:
; CHECK-NEXT: [[INC_I_I_LCSSA:%.*]] = phi i32 [ [[INC_I_I:%.*]], [[FOR_BODY650]] ]
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[DOTSROA_SPECULATED]], 1
; CHECK-NEXT: br label [[XZ_EXIT]]
; CHECK: XZ.exit:
; CHECK-NEXT: [[DB_SROA_9_0_LCSSA:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[INC_I_I_LCSSA]], [[LOOPEXIT:%.*]] ]
; CHECK-NEXT: [[DB_SROA_9_0_LCSSA:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[TMP0]], [[LOOPEXIT:%.*]] ]
; CHECK-NEXT: br label [[END:%.*]]
; CHECK: for.body650:
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[FOR_BODY650_LR_PH]] ], [ [[INC655:%.*]], [[FOR_BODY650]] ]
; CHECK-NEXT: [[IV2:%.*]] = phi i32 [ 1, [[FOR_BODY650_LR_PH]] ], [ [[INC_I_I]], [[FOR_BODY650]] ]
; CHECK-NEXT: [[IV2:%.*]] = phi i32 [ 1, [[FOR_BODY650_LR_PH]] ], [ [[INC_I_I:%.*]], [[FOR_BODY650]] ]
; CHECK-NEXT: [[ARRAYIDX_I_I1105:%.*]] = getelementptr inbounds i8, i8* [[REF_I1174:%.*]], i32 [[IV2]]
; CHECK-NEXT: store i8 7, i8* [[ARRAYIDX_I_I1105]], align 1
; CHECK-NEXT: [[INC_I_I]] = add nuw nsw i32 [[IV2]], 1
Expand Down
12 changes: 6 additions & 6 deletions llvm/test/Transforms/IndVarSimplify/pr39673.ll
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ define i16 @dom_argument(i16 %arg1, i16 %arg2) {
; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i16 [[L2_ADD]], 2
; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP2]], label [[LOOP2_END:%.*]]
; CHECK: loop2.end:
; CHECK-NEXT: [[K2_ADD_LCSSA:%.*]] = phi i16 [ [[K2_ADD]], [[LOOP2]] ]
; CHECK-NEXT: ret i16 [[K2_ADD_LCSSA]]
; CHECK-NEXT: [[TMP0:%.*]] = add i16 [[ARG2]], 2
; CHECK-NEXT: ret i16 [[TMP0]]
;
entry:
br label %loop1
Expand Down Expand Up @@ -121,8 +121,8 @@ define i16 @dummy_phi_outside_loop(i16 %arg) {
; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i16 [[L2_ADD]], 2
; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP2]], label [[LOOP2_END:%.*]]
; CHECK: loop2.end:
; CHECK-NEXT: [[K2_ADD_LCSSA:%.*]] = phi i16 [ [[K2_ADD]], [[LOOP2]] ]
; CHECK-NEXT: ret i16 [[K2_ADD_LCSSA]]
; CHECK-NEXT: [[TMP0:%.*]] = add i16 [[DUMMY]], 2
; CHECK-NEXT: ret i16 [[TMP0]]
;
entry:
br label %loop2.preheader
Expand Down Expand Up @@ -166,8 +166,8 @@ define i16 @neg_loop_carried(i16 %arg) {
; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i16 [[L2_ADD]], 2
; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP2]], label [[LOOP2_END:%.*]]
; CHECK: loop2.end:
; CHECK-NEXT: [[K2_ADD_LCSSA:%.*]] = phi i16 [ [[K2_ADD]], [[LOOP2]] ]
; CHECK-NEXT: ret i16 [[K2_ADD_LCSSA]]
; CHECK-NEXT: [[TMP1:%.*]] = add i16 [[TMP0]], 2
; CHECK-NEXT: ret i16 [[TMP1]]
;
entry:
br label %loop1
Expand Down
75 changes: 45 additions & 30 deletions llvm/test/Transforms/IndVarSimplify/widen-loop-comp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -24,30 +24,33 @@ define i32 @test1() {
; CHECK: for.body.lr.ph:
; CHECK-NEXT: [[TMP1:%.*]] = load i32*, i32** @ptr, align 8
; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* @e, align 4
; CHECK-NEXT: [[TMP3:%.*]] = sext i32 [[TMP2]] to i64
; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 0
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP3]], i32 [[TMP2]], i32 0
; CHECK-NEXT: [[TMP4:%.*]] = add nuw i32 [[SMAX]], 1
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP4]] to i64
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.cond:
; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_IV:%.*]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INDVARS_IV]], [[TMP3]]
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_FOR_END_LOOPEXIT_CRIT_EDGE:%.*]]
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_COND_FOR_END_LOOPEXIT_CRIT_EDGE:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[INDVARS_IV]] = phi i64 [ [[INDVARS_IV_NEXT]], [[FOR_COND:%.*]] ], [ 0, [[FOR_BODY_LR_PH]] ]
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 [[INDVARS_IV]]
; CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP4]], 0
; CHECK-NEXT: [[TMP5:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP5]], 0
; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[FOR_COND]]
; CHECK: if.then:
; CHECK-NEXT: [[I_05_LCSSA_WIDE:%.*]] = phi i64 [ [[INDVARS_IV]], [[FOR_BODY]] ]
; CHECK-NEXT: [[TMP5:%.*]] = trunc i64 [[I_05_LCSSA_WIDE]] to i32
; CHECK-NEXT: store i32 [[TMP5]], i32* @idx, align 4
; CHECK-NEXT: [[TMP6:%.*]] = trunc i64 [[I_05_LCSSA_WIDE]] to i32
; CHECK-NEXT: store i32 [[TMP6]], i32* @idx, align 4
; CHECK-NEXT: br label [[FOR_END:%.*]]
; CHECK: for.cond.for.end.loopexit_crit_edge:
; CHECK-NEXT: br label [[FOR_END_LOOPEXIT]]
; CHECK: for.end.loopexit:
; CHECK-NEXT: br label [[FOR_END]]
; CHECK: for.end:
; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* @idx, align 4
; CHECK-NEXT: ret i32 [[TMP6]]
; CHECK-NEXT: [[TMP7:%.*]] = load i32, i32* @idx, align 4
; CHECK-NEXT: ret i32 [[TMP7]]
;
entry:
store i32 -1, i32* @idx, align 4
Expand Down Expand Up @@ -96,7 +99,8 @@ define void @test2([8 x i8]* %a, i8* %b, i8 %limit) {
; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[LIMIT:%.*]] to i32
; CHECK-NEXT: br i1 undef, label [[FOR_COND1_PREHEADER_PREHEADER:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]]
; CHECK: for.cond1.preheader.us.preheader:
; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[CONV]] to i64
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[CONV]], 1
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i32 [[CONV]], i32 1
; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]]
; CHECK: for.cond1.preheader.preheader:
; CHECK-NEXT: br label [[FOR_COND1_PREHEADER:%.*]]
Expand All @@ -107,8 +111,8 @@ define void @test2([8 x i8]* %a, i8* %b, i8 %limit) {
; CHECK-NEXT: br label [[FOR_INC13_US]]
; CHECK: for.inc13.us:
; CHECK-NEXT: [[INDVARS_IV_NEXT3]] = add nuw nsw i64 [[INDVARS_IV2]], 1
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT3]], 4
; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_END_LOOPEXIT1:%.*]]
; CHECK-NEXT: [[EXITCOND4:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT3]], 4
; CHECK-NEXT: br i1 [[EXITCOND4]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_END_LOOPEXIT1:%.*]]
; CHECK: for.body4.us:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[FOR_BODY4_LR_PH_US]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY4_US:%.*]] ]
; CHECK-NEXT: [[ARRAYIDX6_US:%.*]] = getelementptr inbounds [8 x i8], [8 x i8]* [[A:%.*]], i64 [[INDVARS_IV2]], i64 [[INDVARS_IV]]
Expand All @@ -118,9 +122,10 @@ define void @test2([8 x i8]* %a, i8* %b, i8 %limit) {
; CHECK-NEXT: [[TMP2:%.*]] = load i8, i8* [[ARRAYIDX8_US]], align 1
; CHECK-NEXT: store i8 [[TMP2]], i8* [[ARRAYIDX6_US]], align 1
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ult i64 [[INDVARS_IV_NEXT]], [[TMP0]]
; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY4_US]], label [[FOR_INC13_US_LOOPEXIT:%.*]]
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT:%.*]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY4_US]], label [[FOR_INC13_US_LOOPEXIT:%.*]]
; CHECK: for.body4.lr.ph.us:
; CHECK-NEXT: [[WIDE_TRIP_COUNT]] = zext i32 [[SMAX]] to i64
; CHECK-NEXT: br label [[FOR_BODY4_US]]
; CHECK: for.cond1.preheader:
; CHECK-NEXT: br i1 false, label [[FOR_INC13:%.*]], label [[FOR_INC13]]
Expand Down Expand Up @@ -180,13 +185,15 @@ for.end:
define i32 @test3(i32* %a, i32 %b) {
; CHECK-LABEL: @test3(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[B:%.*]] to i64
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[B:%.*]], 0
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i32 [[B]], i32 0
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
; CHECK-NEXT: br label [[FOR_COND:%.*]]
; CHECK: for.cond:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT: [[SUM_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INDVARS_IV]], [[TMP0]]
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[WIDE_TRIP_COUNT]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
Expand Down Expand Up @@ -300,17 +307,20 @@ for.end:
define i32 @test6(i32* %a, i32 %b) {
; CHECK-LABEL: @test6(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[B:%.*]] to i64
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[B:%.*]], -1
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i32 [[B]], i32 -1
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[SMAX]], 1
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP1]] to i64
; CHECK-NEXT: br label [[FOR_COND:%.*]]
; CHECK: for.cond:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT: [[SUM_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i64 [[INDVARS_IV]], [[TMP0]]
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[WIDE_TRIP_COUNT]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
; CHECK-NEXT: [[ADD]] = add nsw i32 [[SUM_0]], [[TMP1]]
; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
; CHECK-NEXT: [[ADD]] = add nsw i32 [[SUM_0]], [[TMP2]]
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
; CHECK-NEXT: br label [[FOR_COND]]
; CHECK: for.end:
Expand Down Expand Up @@ -342,7 +352,10 @@ define i32 @test7(i32* %a, i32 %b) {
; CHECK-LABEL: @test7(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[B:%.*]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[B]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[B]], -1
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP1]], i32 [[B]], i32 -1
; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[SMAX]], 2
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP2]] to i64
; CHECK-NEXT: br label [[FOR_COND:%.*]]
; CHECK: for.cond:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ]
Expand All @@ -351,11 +364,11 @@ define i32 @test7(i32* %a, i32 %b) {
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
; CHECK-NEXT: [[ADD]] = add nsw i32 [[SUM_0]], [[TMP2]]
; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
; CHECK-NEXT: [[ADD]] = add nsw i32 [[SUM_0]], [[TMP3]]
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i64 [[INDVARS_IV]], [[TMP1]]
; CHECK-NEXT: br i1 [[CMP2]], label [[FOR_COND]], label [[FOR_END]]
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND]], label [[FOR_END]]
; CHECK: for.end:
; CHECK-NEXT: [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_BODY]] ], [ [[SUM_0]], [[FOR_COND]] ]
; CHECK-NEXT: ret i32 [[SUM_0_LCSSA]]
Expand Down Expand Up @@ -444,13 +457,15 @@ define i32 @test9(i32* %a, i32 %b, i32 %init) {
; CHECK-NEXT: br i1 [[E]], label [[FOR_COND_PREHEADER:%.*]], label [[LEAVE:%.*]]
; CHECK: for.cond.preheader:
; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[INIT]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[B:%.*]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[INIT]], [[B:%.*]]
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP1]], i32 [[INIT]], i32 [[B]]
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
; CHECK-NEXT: br label [[FOR_COND:%.*]]
; CHECK: for.cond:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_COND_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ]
; CHECK-NEXT: [[SUM_0:%.*]] = phi i32 [ [[ADD:%.*]], [[FOR_BODY]] ], [ 0, [[FOR_COND_PREHEADER]] ]
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INDVARS_IV]], [[TMP1]]
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[WIDE_TRIP_COUNT]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
Expand Down
74 changes: 65 additions & 9 deletions llvm/test/Transforms/LoopVectorize/X86/float-induction-x86.ll
Original file line number Diff line number Diff line change
Expand Up @@ -425,8 +425,8 @@ define double @external_use_with_fast_math(double* %a, i64 %n) {
; AUTO_VEC-NEXT: store double [[J]], double* [[TMP0]], align 8
; AUTO_VEC-NEXT: [[I_NEXT]] = add nuw nsw i64 [[I]], 1
; AUTO_VEC-NEXT: [[J_NEXT]] = fadd fast double [[J]], 3.000000e+00
; AUTO_VEC-NEXT: [[COND:%.*]] = icmp slt i64 [[I_NEXT]], [[N]]
; AUTO_VEC-NEXT: br i1 [[COND]], label [[FOR_BODY]], label [[FOR_END]], !llvm.loop !9
; AUTO_VEC-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[I_NEXT]], [[SMAX]]
; AUTO_VEC-NEXT: br i1 [[EXITCOND]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop !9
; AUTO_VEC: for.end:
; AUTO_VEC-NEXT: [[J_LCSSA:%.*]] = phi double [ [[TMP47]], [[MIDDLE_BLOCK]] ], [ [[J]], [[FOR_BODY]] ]
; AUTO_VEC-NEXT: ret double [[J_LCSSA]]
Expand All @@ -452,18 +452,74 @@ for.end:
define double @external_use_without_fast_math(double* %a, i64 %n) {
; AUTO_VEC-LABEL: @external_use_without_fast_math(
; AUTO_VEC-NEXT: entry:
; AUTO_VEC-NEXT: [[TMP0:%.*]] = icmp sgt i64 [[N:%.*]], 1
; AUTO_VEC-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i64 [[N]], i64 1
; AUTO_VEC-NEXT: [[TMP1:%.*]] = add nsw i64 [[SMAX]], -1
; AUTO_VEC-NEXT: [[XTRAITER:%.*]] = and i64 [[SMAX]], 7
; AUTO_VEC-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP1]], 7
; AUTO_VEC-NEXT: br i1 [[TMP2]], label [[FOR_END_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]]
; AUTO_VEC: entry.new:
; AUTO_VEC-NEXT: [[UNROLL_ITER:%.*]] = sub nsw i64 [[SMAX]], [[XTRAITER]]
; AUTO_VEC-NEXT: br label [[FOR_BODY:%.*]]
; AUTO_VEC: for.body:
; AUTO_VEC-NEXT: [[I:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[FOR_BODY]] ]
; AUTO_VEC-NEXT: [[J:%.*]] = phi double [ 0.000000e+00, [[ENTRY]] ], [ [[J_NEXT:%.*]], [[FOR_BODY]] ]
; AUTO_VEC-NEXT: [[I:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[I_NEXT_7:%.*]], [[FOR_BODY]] ]
; AUTO_VEC-NEXT: [[J:%.*]] = phi double [ 0.000000e+00, [[ENTRY_NEW]] ], [ [[J_NEXT_7:%.*]], [[FOR_BODY]] ]
; AUTO_VEC-NEXT: [[NITER:%.*]] = phi i64 [ [[UNROLL_ITER]], [[ENTRY_NEW]] ], [ [[NITER_NSUB_7:%.*]], [[FOR_BODY]] ]
; AUTO_VEC-NEXT: [[TMP0:%.*]] = getelementptr double, double* [[A:%.*]], i64 [[I]]
; AUTO_VEC-NEXT: store double [[J]], double* [[TMP0]], align 8
; AUTO_VEC-NEXT: [[I_NEXT]] = add nuw nsw i64 [[I]], 1
; AUTO_VEC-NEXT: [[J_NEXT]] = fadd double [[J]], 3.000000e+00
; AUTO_VEC-NEXT: [[COND:%.*]] = icmp slt i64 [[I_NEXT]], [[N:%.*]]
; AUTO_VEC-NEXT: br i1 [[COND]], label [[FOR_BODY]], label [[FOR_END:%.*]]
; AUTO_VEC-NEXT: [[I_NEXT:%.*]] = or i64 [[I]], 1
; AUTO_VEC-NEXT: [[J_NEXT:%.*]] = fadd double [[J]], 3.000000e+00
; AUTO_VEC-NEXT: [[TMP0_1:%.*]] = getelementptr double, double* [[A]], i64 [[I_NEXT]]
; AUTO_VEC-NEXT: store double [[J_NEXT]], double* [[TMP0_1]], align 8
; AUTO_VEC-NEXT: [[I_NEXT_1:%.*]] = or i64 [[I]], 2
; AUTO_VEC-NEXT: [[J_NEXT_1:%.*]] = fadd double [[J_NEXT]], 3.000000e+00
; AUTO_VEC-NEXT: [[TMP0_2:%.*]] = getelementptr double, double* [[A]], i64 [[I_NEXT_1]]
; AUTO_VEC-NEXT: store double [[J_NEXT_1]], double* [[TMP0_2]], align 8
; AUTO_VEC-NEXT: [[I_NEXT_2:%.*]] = or i64 [[I]], 3
; AUTO_VEC-NEXT: [[J_NEXT_2:%.*]] = fadd double [[J_NEXT_1]], 3.000000e+00
; AUTO_VEC-NEXT: [[TMP0_3:%.*]] = getelementptr double, double* [[A]], i64 [[I_NEXT_2]]
; AUTO_VEC-NEXT: store double [[J_NEXT_2]], double* [[TMP0_3]], align 8
; AUTO_VEC-NEXT: [[I_NEXT_3:%.*]] = or i64 [[I]], 4
; AUTO_VEC-NEXT: [[J_NEXT_3:%.*]] = fadd double [[J_NEXT_2]], 3.000000e+00
; AUTO_VEC-NEXT: [[TMP0_4:%.*]] = getelementptr double, double* [[A]], i64 [[I_NEXT_3]]
; AUTO_VEC-NEXT: store double [[J_NEXT_3]], double* [[TMP0_4]], align 8
; AUTO_VEC-NEXT: [[I_NEXT_4:%.*]] = or i64 [[I]], 5
; AUTO_VEC-NEXT: [[J_NEXT_4:%.*]] = fadd double [[J_NEXT_3]], 3.000000e+00
; AUTO_VEC-NEXT: [[TMP0_5:%.*]] = getelementptr double, double* [[A]], i64 [[I_NEXT_4]]
; AUTO_VEC-NEXT: store double [[J_NEXT_4]], double* [[TMP0_5]], align 8
; AUTO_VEC-NEXT: [[I_NEXT_5:%.*]] = or i64 [[I]], 6
; AUTO_VEC-NEXT: [[J_NEXT_5:%.*]] = fadd double [[J_NEXT_4]], 3.000000e+00
; AUTO_VEC-NEXT: [[TMP0_6:%.*]] = getelementptr double, double* [[A]], i64 [[I_NEXT_5]]
; AUTO_VEC-NEXT: store double [[J_NEXT_5]], double* [[TMP0_6]], align 8
; AUTO_VEC-NEXT: [[I_NEXT_6:%.*]] = or i64 [[I]], 7
; AUTO_VEC-NEXT: [[J_NEXT_6:%.*]] = fadd double [[J_NEXT_5]], 3.000000e+00
; AUTO_VEC-NEXT: [[TMP0_7:%.*]] = getelementptr double, double* [[A]], i64 [[I_NEXT_6]]
; AUTO_VEC-NEXT: store double [[J_NEXT_6]], double* [[TMP0_7]], align 8
; AUTO_VEC-NEXT: [[I_NEXT_7]] = add nuw nsw i64 [[I]], 8
; AUTO_VEC-NEXT: [[J_NEXT_7]] = fadd double [[J_NEXT_6]], 3.000000e+00
; AUTO_VEC-NEXT: [[NITER_NSUB_7]] = add i64 [[NITER]], -8
; AUTO_VEC-NEXT: [[NITER_NCMP_7:%.*]] = icmp eq i64 [[NITER_NSUB_7]], 0
; AUTO_VEC-NEXT: br i1 [[NITER_NCMP_7]], label [[FOR_END_UNR_LCSSA]], label [[FOR_BODY]]
; AUTO_VEC: for.end.unr-lcssa:
; AUTO_VEC-NEXT: [[J_LCSSA_PH:%.*]] = phi double [ undef, [[ENTRY:%.*]] ], [ [[J_NEXT_6]], [[FOR_BODY]] ]
; AUTO_VEC-NEXT: [[I_UNR:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[I_NEXT_7]], [[FOR_BODY]] ]
; AUTO_VEC-NEXT: [[J_UNR:%.*]] = phi double [ 0.000000e+00, [[ENTRY]] ], [ [[J_NEXT_7]], [[FOR_BODY]] ]
; AUTO_VEC-NEXT: [[LCMP_MOD:%.*]] = icmp eq i64 [[XTRAITER]], 0
; AUTO_VEC-NEXT: br i1 [[LCMP_MOD]], label [[FOR_END:%.*]], label [[FOR_BODY_EPIL:%.*]]
; AUTO_VEC: for.body.epil:
; AUTO_VEC-NEXT: [[I_EPIL:%.*]] = phi i64 [ [[I_NEXT_EPIL:%.*]], [[FOR_BODY_EPIL]] ], [ [[I_UNR]], [[FOR_END_UNR_LCSSA]] ]
; AUTO_VEC-NEXT: [[J_EPIL:%.*]] = phi double [ [[J_NEXT_EPIL:%.*]], [[FOR_BODY_EPIL]] ], [ [[J_UNR]], [[FOR_END_UNR_LCSSA]] ]
; AUTO_VEC-NEXT: [[EPIL_ITER:%.*]] = phi i64 [ [[EPIL_ITER_SUB:%.*]], [[FOR_BODY_EPIL]] ], [ [[XTRAITER]], [[FOR_END_UNR_LCSSA]] ]
; AUTO_VEC-NEXT: [[TMP0_EPIL:%.*]] = getelementptr double, double* [[A]], i64 [[I_EPIL]]
; AUTO_VEC-NEXT: store double [[J_EPIL]], double* [[TMP0_EPIL]], align 8
; AUTO_VEC-NEXT: [[I_NEXT_EPIL]] = add nuw nsw i64 [[I_EPIL]], 1
; AUTO_VEC-NEXT: [[J_NEXT_EPIL]] = fadd double [[J_EPIL]], 3.000000e+00
; AUTO_VEC-NEXT: [[EPIL_ITER_SUB]] = add i64 [[EPIL_ITER]], -1
; AUTO_VEC-NEXT: [[EPIL_ITER_CMP:%.*]] = icmp eq i64 [[EPIL_ITER_SUB]], 0
; AUTO_VEC-NEXT: br i1 [[EPIL_ITER_CMP]], label [[FOR_END]], label [[FOR_BODY_EPIL]], !llvm.loop !10
; AUTO_VEC: for.end:
; AUTO_VEC-NEXT: ret double [[J]]
; AUTO_VEC-NEXT: [[J_LCSSA:%.*]] = phi double [ [[J_LCSSA_PH]], [[FOR_END_UNR_LCSSA]] ], [ [[J_EPIL]], [[FOR_BODY_EPIL]] ]
; AUTO_VEC-NEXT: ret double [[J_LCSSA]]
;
entry:
br label %for.body
Expand Down
5 changes: 3 additions & 2 deletions llvm/unittests/Transforms/Utils/UnrollLoopTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ while.end: ; preds = %while.cond

bool PreserveLCSSA = L->isRecursivelyLCSSAForm(DT,LI);

bool ret = UnrollRuntimeLoopRemainder(L, 4, true, false, false, false, &LI,
&SE, &DT, &AC, PreserveLCSSA);
bool ret =
UnrollRuntimeLoopRemainder(L, 4, true, false, false, false, &LI, &SE, &DT,
&AC, /*TTI=*/nullptr, PreserveLCSSA);
EXPECT_FALSE(ret);
}