diff --git a/llvm/include/llvm/Transforms/Utils/SimplifyIndVar.h b/llvm/include/llvm/Transforms/Utils/SimplifyIndVar.h index bd1718dd8cad7..dbf2bdd18467d 100644 --- a/llvm/include/llvm/Transforms/Utils/SimplifyIndVar.h +++ b/llvm/include/llvm/Transforms/Utils/SimplifyIndVar.h @@ -52,12 +52,11 @@ class IVVisitor { /// where the first entry indicates that the function makes changes and the /// second entry indicates that it introduced new opportunities for loop /// unswitching. -std::pair simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, - DominatorTree *DT, LoopInfo *LI, - const TargetTransformInfo *TTI, - SmallVectorImpl &Dead, - SCEVExpander &Rewriter, - IVVisitor *V = nullptr); +std::pair +simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, DominatorTree *DT, + LoopInfo *LI, const TargetTransformInfo *TTI, + SmallVectorImpl &Dead, SCEVExpander &Rewriter, + unsigned MaxDepthOutOfLoop = 1, IVVisitor *V = nullptr); /// SimplifyLoopIVs - Simplify users of induction variables within this /// loop. This does not actually change or add IVs. diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp index dd7c89034ca09..c270841835672 100644 --- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -124,6 +124,12 @@ static cl::opt AllowIVWidening("indvars-widen-indvars", cl::Hidden, cl::init(true), cl::desc("Allow widening of indvars to eliminate s/zext")); +static cl::opt MaxDepthOutOfLoop( + "indvars-max-depth-out-of-loop", cl::Hidden, cl::init(0), + cl::desc( + "Strict upper bound for the number of successive out-of-loop blocks " + "when traversing use-def chains. 0 enables full traversal")); + namespace { class IndVarSimplify { @@ -624,8 +630,9 @@ bool IndVarSimplify::simplifyAndExtend(Loop *L, // Information about sign/zero extensions of CurrIV. IndVarSimplifyVisitor Visitor(CurrIV, SE, TTI, DT); - const auto &[C, U] = simplifyUsersOfIV(CurrIV, SE, DT, LI, TTI, DeadInsts, - Rewriter, &Visitor); + const auto &[C, U] = + simplifyUsersOfIV(CurrIV, SE, DT, LI, TTI, DeadInsts, Rewriter, + MaxDepthOutOfLoop, &Visitor); Changed |= C; RunUnswitching |= U; diff --git a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp index 74af0ef40fe7f..325633a5848c2 100644 --- a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp @@ -62,13 +62,18 @@ namespace { bool Changed = false; bool RunUnswitching = false; + // When following the def-use chains, it can go outside the loop. + // Strict upper bound on number of traversed out-of-loop blocks. + unsigned MaxDepthOutOfLoop; + public: SimplifyIndvar(Loop *Loop, ScalarEvolution *SE, DominatorTree *DT, LoopInfo *LI, const TargetTransformInfo *TTI, SCEVExpander &Rewriter, - SmallVectorImpl &Dead) + SmallVectorImpl &Dead, + unsigned MaxDepthOutOfLoop = 1) : L(Loop), LI(LI), SE(SE), DT(DT), TTI(TTI), Rewriter(Rewriter), - DeadInsts(Dead) { + DeadInsts(Dead), MaxDepthOutOfLoop(MaxDepthOutOfLoop) { assert(LI && "IV simplification requires LoopInfo"); } @@ -80,10 +85,11 @@ namespace { /// all simplifications to users of an IV. void simplifyUsers(PHINode *CurrIV, IVVisitor *V = nullptr); - void pushIVUsers(Instruction *Def, - SmallPtrSet &Simplified, - SmallVectorImpl> - &SimpleIVUsers); + void pushIVUsers( + Instruction *Def, SmallPtrSet &Simplified, + SmallVectorImpl> + &SimpleIVUsers, + unsigned OutOfLoopChainCounter); Value *foldIVUser(Instruction *UseInst, Instruction *IVOperand); @@ -514,8 +520,8 @@ bool SimplifyIndvar::eliminateTrunc(TruncInst *TI) { !DT->isReachableFromEntry(cast(U)->getParent())) continue; ICmpInst *ICI = dyn_cast(U); - if (!ICI) return false; - assert(L->contains(ICI->getParent()) && "LCSSA form broken?"); + if (!ICI) + return false; if (!(ICI->getOperand(0) == TI && L->isLoopInvariant(ICI->getOperand(1))) && !(ICI->getOperand(1) == TI && L->isLoopInvariant(ICI->getOperand(0)))) return false; @@ -548,7 +554,7 @@ bool SimplifyIndvar::eliminateTrunc(TruncInst *TI) { }; // Replace all comparisons against trunc with comparisons against IV. for (auto *ICI : ICmpUsers) { - bool IsSwapped = L->isLoopInvariant(ICI->getOperand(0)); + bool IsSwapped = ICI->getOperand(0) != TI; auto *Op1 = IsSwapped ? ICI->getOperand(0) : ICI->getOperand(1); IRBuilder<> Builder(ICI); Value *Ext = nullptr; @@ -846,7 +852,9 @@ bool SimplifyIndvar::strengthenRightShift(BinaryOperator *BO, /// Add all uses of Def to the current IV's worklist. void SimplifyIndvar::pushIVUsers( Instruction *Def, SmallPtrSet &Simplified, - SmallVectorImpl> &SimpleIVUsers) { + SmallVectorImpl> + &SimpleIVUsers, + unsigned OutOfLoopChainCounter) { for (User *U : Def->users()) { Instruction *UI = cast(U); @@ -857,16 +865,22 @@ void SimplifyIndvar::pushIVUsers( if (UI == Def) continue; - // Only change the current Loop, do not change the other parts (e.g. other - // Loops). - if (!L->contains(UI)) + // Avoid adding Defs that SCEV expand to themselves, e.g. the LoopPhis + // of the outer loops. + if (!DT->dominates(L->getHeader(), UI->getParent())) continue; // Do not push the same instruction more than once. if (!Simplified.insert(UI).second) continue; - SimpleIVUsers.push_back(std::make_pair(UI, Def)); + unsigned Counter = + L->contains(UI) + ? 0 // reset depth if we go back inside the loop. + : OutOfLoopChainCounter + (UI->getParent() != Def->getParent()); + + if (!MaxDepthOutOfLoop || Counter < MaxDepthOutOfLoop) + SimpleIVUsers.push_back(std::make_tuple(UI, Def, Counter)); } } @@ -911,17 +925,17 @@ void SimplifyIndvar::simplifyUsers(PHINode *CurrIV, IVVisitor *V) { SmallPtrSet Simplified; // Use-def pairs if IV users waiting to be processed for CurrIV. - SmallVector, 8> SimpleIVUsers; + SmallVector, 8> + SimpleIVUsers; // Push users of the current LoopPhi. In rare cases, pushIVUsers may be // called multiple times for the same LoopPhi. This is the proper thing to // do for loop header phis that use each other. - pushIVUsers(CurrIV, Simplified, SimpleIVUsers); + pushIVUsers(CurrIV, Simplified, SimpleIVUsers, 0); while (!SimpleIVUsers.empty()) { - std::pair UseOper = - SimpleIVUsers.pop_back_val(); - Instruction *UseInst = UseOper.first; + auto [UseInst, IVOperand, OutOfLoopChainCounter] = + SimpleIVUsers.pop_back_val(); // If a user of the IndVar is trivially dead, we prefer just to mark it dead // rather than try to do some complex analysis or transformation (such as @@ -945,11 +959,11 @@ void SimplifyIndvar::simplifyUsers(PHINode *CurrIV, IVVisitor *V) { if ((isa(UseInst)) || (isa(UseInst))) for (Use &U : UseInst->uses()) { Instruction *User = cast(U.getUser()); - if (replaceIVUserWithLoopInvariant(User)) + if (DT->dominates(L->getHeader(), User->getParent()) && + replaceIVUserWithLoopInvariant(User)) break; // done replacing } - Instruction *IVOperand = UseOper.second; for (unsigned N = 0; IVOperand; ++N) { assert(N <= Simplified.size() && "runaway iteration"); (void) N; @@ -963,7 +977,7 @@ void SimplifyIndvar::simplifyUsers(PHINode *CurrIV, IVVisitor *V) { continue; if (eliminateIVUser(UseInst, IVOperand)) { - pushIVUsers(IVOperand, Simplified, SimpleIVUsers); + pushIVUsers(IVOperand, Simplified, SimpleIVUsers, OutOfLoopChainCounter); continue; } @@ -971,14 +985,15 @@ void SimplifyIndvar::simplifyUsers(PHINode *CurrIV, IVVisitor *V) { if (strengthenBinaryOp(BO, IVOperand)) { // re-queue uses of the now modified binary operator and fall // through to the checks that remain. - pushIVUsers(IVOperand, Simplified, SimpleIVUsers); + pushIVUsers(IVOperand, Simplified, SimpleIVUsers, + OutOfLoopChainCounter); } } // Try to use integer induction for FPToSI of float induction directly. if (replaceFloatIVWithIntegerIV(UseInst)) { // Re-queue the potentially new direct uses of IVOperand. - pushIVUsers(IVOperand, Simplified, SimpleIVUsers); + pushIVUsers(IVOperand, Simplified, SimpleIVUsers, OutOfLoopChainCounter); continue; } @@ -988,7 +1003,7 @@ void SimplifyIndvar::simplifyUsers(PHINode *CurrIV, IVVisitor *V) { continue; } if (isSimpleIVUser(UseInst, L, SE)) { - pushIVUsers(UseInst, Simplified, SimpleIVUsers); + pushIVUsers(UseInst, Simplified, SimpleIVUsers, OutOfLoopChainCounter); } } } @@ -1002,13 +1017,13 @@ void IVVisitor::anchor() { } /// Returns a pair where the first entry indicates that the function makes /// changes and the second entry indicates that it introduced new opportunities /// for loop unswitching. -std::pair simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, - DominatorTree *DT, LoopInfo *LI, - const TargetTransformInfo *TTI, - SmallVectorImpl &Dead, - SCEVExpander &Rewriter, IVVisitor *V) { +std::pair +simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, DominatorTree *DT, + LoopInfo *LI, const TargetTransformInfo *TTI, + SmallVectorImpl &Dead, SCEVExpander &Rewriter, + unsigned MaxDepthOutOfLoop, IVVisitor *V) { SimplifyIndvar SIV(LI->getLoopFor(CurrIV->getParent()), SE, DT, LI, TTI, - Rewriter, Dead); + Rewriter, Dead, MaxDepthOutOfLoop); SIV.simplifyUsers(CurrIV, V); return {SIV.hasChanged(), SIV.runUnswitching()}; } diff --git a/llvm/test/Transforms/IndVarSimplify/X86/pr57187.ll b/llvm/test/Transforms/IndVarSimplify/X86/pr57187.ll index 620b0adaebfe5..f4aa186d87e78 100644 --- a/llvm/test/Transforms/IndVarSimplify/X86/pr57187.ll +++ b/llvm/test/Transforms/IndVarSimplify/X86/pr57187.ll @@ -9,23 +9,18 @@ define void @test(i32 %start) { ; CHECK-LABEL: @test( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[START:%.*]], -1 -; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[START]] to i64 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: backedge: ; CHECK-NEXT: br label [[LOOP]] ; CHECK: loop: -; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP1]], [[ENTRY:%.*]] ] -; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 -; CHECK-NEXT: [[INDVARS:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32 ; CHECK-NEXT: [[LOOP_EXIT_COND:%.*]] = icmp slt i32 [[TMP0]], 11 ; CHECK-NEXT: br i1 [[LOOP_EXIT_COND]], label [[EXIT:%.*]], label [[STUCK_PREHEADER:%.*]] ; CHECK: stuck.preheader: ; CHECK-NEXT: br label [[STUCK:%.*]] ; CHECK: exit: -; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[INDVARS]], [[LOOP]] ] ; CHECK-NEXT: ret void ; CHECK: stuck: -; CHECK-NEXT: br i1 false, label [[BACKEDGE]], label [[STUCK]] +; CHECK-NEXT: br i1 false, label [[BACKEDGE:%.*]], label [[STUCK]] ; entry: br label %loop diff --git a/llvm/test/Transforms/IndVarSimplify/lcssa-preservation.ll b/llvm/test/Transforms/IndVarSimplify/lcssa-preservation.ll index f00a111aa6a6d..e12b89a53204a 100644 --- a/llvm/test/Transforms/IndVarSimplify/lcssa-preservation.ll +++ b/llvm/test/Transforms/IndVarSimplify/lcssa-preservation.ll @@ -17,12 +17,10 @@ define void @PR18642(i32 %x) { ; CHECK: outer.latch: ; CHECK-NEXT: br i1 false, label [[OUTER_HEADER]], label [[EXIT_LOOPEXIT1:%.*]] ; CHECK: exit.loopexit: -; CHECK-NEXT: [[INC_LCSSA:%.*]] = phi i32 [ -2147483648, [[INNER_LATCH]] ] ; CHECK-NEXT: br label [[EXIT:%.*]] ; CHECK: exit.loopexit1: ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: -; CHECK-NEXT: [[EXIT_PHI:%.*]] = phi i32 [ [[INC_LCSSA]], [[EXIT_LOOPEXIT]] ], [ undef, [[EXIT_LOOPEXIT1]] ] ; CHECK-NEXT: ret void ; entry: diff --git a/llvm/test/Transforms/IndVarSimplify/no-iv-rewrite.ll b/llvm/test/Transforms/IndVarSimplify/no-iv-rewrite.ll index 579b8536cedf0..c5e751257ce2c 100644 --- a/llvm/test/Transforms/IndVarSimplify/no-iv-rewrite.ll +++ b/llvm/test/Transforms/IndVarSimplify/no-iv-rewrite.ll @@ -380,18 +380,13 @@ define i32 @isomorphic(i32 %init, i32 %step, i32 %lim) nounwind { ; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[INIT]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[II_NEXT]] = add i32 [[II]], [[STEP1]] ; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], [[STEP1]] -; CHECK-NEXT: [[L_STEP:%.*]] = add i32 [[J]], [[STEP]] ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[II_NEXT]], [[LIM:%.*]] ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[RETURN:%.*]] ; CHECK: return: ; CHECK-NEXT: [[I_LCSSA:%.*]] = phi i32 [ [[J]], [[LOOP]] ] ; CHECK-NEXT: [[J_NEXT_LCSSA:%.*]] = phi i32 [ [[J_NEXT]], [[LOOP]] ] -; CHECK-NEXT: [[K_NEXT_LCSSA:%.*]] = phi i32 [ [[II_NEXT]], [[LOOP]] ] -; CHECK-NEXT: [[L_STEP_LCSSA:%.*]] = phi i32 [ [[L_STEP]], [[LOOP]] ] ; CHECK-NEXT: [[L_NEXT_LCSSA:%.*]] = phi i32 [ [[J_NEXT]], [[LOOP]] ] ; CHECK-NEXT: [[SUM1:%.*]] = add i32 [[I_LCSSA]], [[J_NEXT_LCSSA]] -; CHECK-NEXT: [[SUM2:%.*]] = add i32 [[SUM1]], [[K_NEXT_LCSSA]] -; CHECK-NEXT: [[SUM3:%.*]] = add i32 [[SUM1]], [[L_STEP_LCSSA]] ; CHECK-NEXT: [[SUM4:%.*]] = add i32 [[SUM1]], [[L_NEXT_LCSSA]] ; CHECK-NEXT: ret i32 [[SUM4]] ; diff --git a/llvm/test/Transforms/IndVarSimplify/out_of_loop_eliminate_truncate.ll b/llvm/test/Transforms/IndVarSimplify/out_of_loop_eliminate_truncate.ll new file mode 100644 index 0000000000000..61ede96d0d356 --- /dev/null +++ b/llvm/test/Transforms/IndVarSimplify/out_of_loop_eliminate_truncate.ll @@ -0,0 +1,126 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt < %s -passes=indvars -S | FileCheck %s + +target datalayout = "n8:16:32:64" + +; This test is inspired by a miscompilation of llvm by itself in +; ``ValueTracking.cpp matchSimpleReccurence``. +; Because of that, the assignment ``Start = R;`` was not emitted +; although ``true`` was returned. + +define dso_local noundef zeroext i1 @matchSimpleRecurrence( +; CHECK-LABEL: define dso_local noundef zeroext i1 @matchSimpleRecurrence( +; CHECK-SAME: ptr nocapture noundef readonly [[P:%.*]], ptr nocapture noundef nonnull writeonly align 8 dereferenceable(8) [[START:%.*]], ptr nocapture noundef nonnull writeonly align 8 dereferenceable(8) [[STEP:%.*]]) local_unnamed_addr { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[FOR_BODY:.*]] +; CHECK: [[FOR_BODY]]: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], %[[FOR_INC:.*]] ], [ 0, %[[ENTRY]] ] +; CHECK-NEXT: [[CMP_NOT17:%.*]] = phi i1 [ true, %[[ENTRY]] ], [ [[CMP_NOT:%.*]], %[[FOR_INC]] ] +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[P]], i64 [[INDVARS_IV]] +; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 +; CHECK-NEXT: [[TOBOOL3_NOT:%.*]] = icmp eq ptr [[TMP0]], null +; CHECK-NEXT: br i1 [[TOBOOL3_NOT]], label %[[FOR_INC]], label %[[IF_THEN:.*]] +; CHECK: [[IF_THEN]]: +; CHECK-NEXT: [[CMP_NOT17_LCSSA:%.*]] = phi i1 [ [[CMP_NOT17]], %[[FOR_BODY]] ] +; CHECK-NEXT: [[I_016_LCSSA_WIDE:%.*]] = phi i64 [ [[INDVARS_IV]], %[[FOR_BODY]] ] +; CHECK-NEXT: [[DOTLCSSA:%.*]] = phi ptr [ [[TMP0]], %[[FOR_BODY]] ] +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[I_016_LCSSA_WIDE]], 0 +; CHECK-NEXT: [[IDXPROM1:%.*]] = zext i1 [[TMP1]] to i64 +; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds ptr, ptr [[P]], i64 [[IDXPROM1]] +; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX2]], align 8 +; CHECK-NEXT: store ptr [[TMP2]], ptr [[START]], align 8 +; CHECK-NEXT: store ptr [[DOTLCSSA]], ptr [[STEP]], align 8 +; CHECK-NEXT: br label %[[CLEANUP5:.*]] +; CHECK: [[FOR_INC]]: +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[CMP_NOT]] = icmp ne i64 [[INDVARS_IV_NEXT]], 2 +; CHECK-NEXT: br i1 [[CMP_NOT]], label %[[FOR_BODY]], label %[[CLEANUP5_LOOPEXIT:.*]] +; CHECK: [[CLEANUP5_LOOPEXIT]]: +; CHECK-NEXT: [[CMP_NOT_LCSSA:%.*]] = phi i1 [ [[CMP_NOT]], %[[FOR_INC]] ] +; CHECK-NEXT: br label %[[CLEANUP5]] +; CHECK: [[CLEANUP5]]: +; CHECK-NEXT: [[CMP_NOT14:%.*]] = phi i1 [ [[CMP_NOT17_LCSSA]], %[[IF_THEN]] ], [ [[CMP_NOT_LCSSA]], %[[CLEANUP5_LOOPEXIT]] ] +; CHECK-NEXT: ret i1 [[CMP_NOT14]] +; + ptr nocapture noundef readonly %P, + ptr nocapture noundef nonnull writeonly align 8 dereferenceable(8) %Start, + ptr nocapture noundef nonnull writeonly align 8 dereferenceable(8) %Step +) local_unnamed_addr { +entry: + br label %for.body + +for.body: ; preds = %entry, %for.inc + %cmp.not17 = phi i1 [ true, %entry ], [ %cmp.not, %for.inc ] + %i.016 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] + %idxprom = zext nneg i32 %i.016 to i64 + %arrayidx = getelementptr inbounds ptr, ptr %P, i64 %idxprom + %0 = load ptr, ptr %arrayidx, align 8 + %tobool3.not = icmp eq ptr %0, null + br i1 %tobool3.not, label %for.inc, label %if.then + +if.then: ; preds = %for.body + %tobool.not = icmp eq i32 %i.016, 0 + %idxprom1 = zext i1 %tobool.not to i64 + %arrayidx2 = getelementptr inbounds ptr, ptr %P, i64 %idxprom1 + %1 = load ptr, ptr %arrayidx2, align 8 + store ptr %1, ptr %Start, align 8 + store ptr %0, ptr %Step, align 8 + br label %cleanup5 + +for.inc: ; preds = %for.body + %inc = add nuw nsw i32 %i.016, 1 + %cmp.not = icmp ne i32 %inc, 2 + br i1 %cmp.not, label %for.body, label %cleanup5.loopexit + +cleanup5.loopexit: ; preds = %for.inc + br label %cleanup5 + +cleanup5: ; preds = %cleanup5.loopexit, %if.then + %cmp.not14 = phi i1 [ %cmp.not17, %if.then ], [ %cmp.not, %cleanup5.loopexit ] + ret i1 %cmp.not14 +} + + +define i1 @check_size_str(ptr %str, i32 %str.size, i32 %n) { +; CHECK-LABEL: define i1 @check_size_str( +; CHECK-SAME: ptr [[STR:%.*]], i32 [[STR_SIZE:%.*]], i32 [[N:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[I:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[I_INC:%.*]], %[[LOOP]] ] +; CHECK-NEXT: [[I_INC]] = add nuw nsw i64 [[I]], 1 +; CHECK-NEXT: [[STR_I:%.*]] = getelementptr i8, ptr [[STR]], i64 [[I]] +; CHECK-NEXT: [[CHAR:%.*]] = load i8, ptr [[STR_I]], align 1 +; CHECK-NEXT: [[CMP_CHAR:%.*]] = icmp eq i8 [[CHAR]], 0 +; CHECK-NEXT: [[STR_SIZE_64:%.*]] = zext i32 [[STR_SIZE]] to i64 +; CHECK-NEXT: [[CMP_I:%.*]] = icmp eq i64 [[I]], [[STR_SIZE_64]] +; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP_I]], [[CMP_CHAR]] +; CHECK-NEXT: br i1 [[OR]], label %[[EXIT:.*]], label %[[LOOP]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: [[I_LCSSA:%.*]] = phi i64 [ [[I]], %[[LOOP]] ] +; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N]] to i64 +; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i64 [[I_LCSSA]], [[ZEXT]] +; CHECK-NEXT: ret i1 [[TMP0]] +; +entry: + br label %loop + +loop: + %i = phi i64 [0, %entry], [%i.inc, %loop] + %i.inc = add nuw nsw i64 %i, 1 + + %str.i = getelementptr i8, ptr %str, i64 %i + %char = load i8, ptr %str.i, align 1 + %cmp.char = icmp eq i8 %char, 0 + + %str.size.64 = zext i32 %str.size to i64 + %cmp.i = icmp eq i64 %i, %str.size.64 + + %or = or i1 %cmp.i, %cmp.char + br i1 %or, label %exit, label %loop + +exit: + %i.32 = trunc nuw nsw i64 %i to i32 + %cmp.i.32 = icmp eq i32 %i.32, %n + ret i1 %cmp.i.32 +} diff --git a/llvm/test/Transforms/IndVarSimplify/pr25578.ll b/llvm/test/Transforms/IndVarSimplify/pr25578.ll index 380e8171798b0..3dc5639abf753 100644 --- a/llvm/test/Transforms/IndVarSimplify/pr25578.ll +++ b/llvm/test/Transforms/IndVarSimplify/pr25578.ll @@ -13,7 +13,6 @@ L1_header: ; CHECK: L2_header: ; CHECK: %[[INDVAR:.*]] = phi i64 -; CHECK: %[[TRUNC:.*]] = trunc nuw nsw i64 %[[INDVAR]] to i32 L2_header: %i = phi i32 [ 0, %L1_header ], [ %i_next, %L2_latch ] %i_prom = sext i32 %i to i64 @@ -38,7 +37,6 @@ L2_latch: L1_latch: ; CHECK: L1_latch: -; CHECK: %i_lcssa = phi i32 [ %[[TRUNC]], %L2_exiting_1 ], [ %[[TRUNC]], %L2_exiting_2 ] %i_lcssa = phi i32 [ %i, %L2_exiting_1 ], [ %i, %L2_exiting_2 ] br i1 undef, label %exit, label %L1_header diff --git a/llvm/test/Transforms/IndVarSimplify/rewrite-loop-exit-values-phi.ll b/llvm/test/Transforms/IndVarSimplify/rewrite-loop-exit-values-phi.ll index 63f3da7af46ec..8362d083bd3c6 100644 --- a/llvm/test/Transforms/IndVarSimplify/rewrite-loop-exit-values-phi.ll +++ b/llvm/test/Transforms/IndVarSimplify/rewrite-loop-exit-values-phi.ll @@ -22,16 +22,12 @@ define dso_local void @hoge() local_unnamed_addr { ; CHECK: inner.preheader: ; CHECK-NEXT: br label [[INNER:%.*]] ; CHECK: inner: -; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_NEXT:%.*]], [[INNER]] ], [ 0, [[INNER_PREHEADER]] ] ; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[J_NEXT:%.*]], [[INNER]] ], [ [[N]], [[INNER_PREHEADER]] ] -; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i64 [[I]], 1 ; CHECK-NEXT: [[J_NEXT]] = add nsw i64 [[J]], 1 ; CHECK-NEXT: store i64 undef, ptr @ptr, align 8 ; CHECK-NEXT: [[COND1:%.*]] = icmp slt i64 [[J]], [[IDX]] ; CHECK-NEXT: br i1 [[COND1]], label [[INNER]], label [[INNER_EXIT:%.*]] ; CHECK: inner_exit: -; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ [[I_NEXT]], [[INNER]] ] -; CHECK-NEXT: [[INDVAR_USE:%.*]] = add i64 [[INDVAR]], 1 ; CHECK-NEXT: br label [[LATCH]] ; CHECK: latch: ; CHECK-NEXT: [[IDX_NEXT]] = add nsw i64 [[IDX]], -1 diff --git a/llvm/test/Transforms/IndVarSimplify/rlev-add-me.ll b/llvm/test/Transforms/IndVarSimplify/rlev-add-me.ll index 9ae7d0af2a43e..22378db12ac3f 100644 --- a/llvm/test/Transforms/IndVarSimplify/rlev-add-me.ll +++ b/llvm/test/Transforms/IndVarSimplify/rlev-add-me.ll @@ -88,7 +88,7 @@ define i32 @neg_wrong_loop(i32 %n) { ; CHECK: wrong_loop: ; CHECK-NEXT: [[IV2:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV2_NEXT:%.*]], [[WRONG_LOOP]] ] ; CHECK-NEXT: [[IV2_NEXT]] = add i32 [[IV2]], 1 -; CHECK-NEXT: [[UNKNOWN:%.*]] = load volatile i32, ptr @G +; CHECK-NEXT: [[UNKNOWN:%.*]] = load volatile i32, ptr @G, align 4 ; CHECK-NEXT: [[CMP_UNK:%.*]] = icmp eq i32 [[UNKNOWN]], 0 ; CHECK-NEXT: br i1 [[CMP_UNK]], label [[HEADER_PREHEADER:%.*]], label [[WRONG_LOOP]] ; CHECK: header.preheader: @@ -108,8 +108,7 @@ define i32 @neg_wrong_loop(i32 %n) { ; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[HEADER]] ] ; CHECK-NEXT: ret i32 [[IV_LCSSA]] ; CHECK: exit2: -; CHECK-NEXT: [[EXITVAL:%.*]] = phi i32 [ [[IV2_LCSSA]], [[LATCH]] ] -; CHECK-NEXT: ret i32 [[EXITVAL]] +; CHECK-NEXT: ret i32 [[IV2_LCSSA]] ; entry: br label %wrong_loop diff --git a/llvm/test/Transforms/IndVarSimplify/scev-expander-preserve-lcssa.ll b/llvm/test/Transforms/IndVarSimplify/scev-expander-preserve-lcssa.ll index 14e06fe06b412..968d5107c0901 100644 --- a/llvm/test/Transforms/IndVarSimplify/scev-expander-preserve-lcssa.ll +++ b/llvm/test/Transforms/IndVarSimplify/scev-expander-preserve-lcssa.ll @@ -107,16 +107,14 @@ define void @test2(i16 %x) { ; CHECK-NEXT: i16 43, label [[FOR_COND]] ; CHECK-NEXT: ] ; CHECK: for.end: -; CHECK-NEXT: [[I_0_LCSSA2:%.*]] = phi i32 [ 0, [[FOR_COND]] ] -; CHECK-NEXT: [[CMP8243:%.*]] = icmp sgt i32 [[I_0_LCSSA2]], 0 -; CHECK-NEXT: br i1 [[CMP8243]], label [[FOR_BODY84_PREHEADER:%.*]], label [[RETURN]] +; CHECK-NEXT: br i1 false, label [[FOR_BODY84_PREHEADER:%.*]], label [[RETURN]] ; CHECK: for.body84.preheader: ; CHECK-NEXT: br label [[FOR_BODY84:%.*]] ; CHECK: for.body84: ; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond() ; CHECK-NEXT: br i1 [[C_2]], label [[IF_END106:%.*]], label [[RETURN_LOOPEXIT:%.*]] ; CHECK: if.end106: -; CHECK-NEXT: br i1 false, label [[FOR_BODY84]], label [[RETURN_LOOPEXIT]] +; CHECK-NEXT: br i1 true, label [[FOR_BODY84]], label [[RETURN_LOOPEXIT]] ; CHECK: return.loopexit: ; CHECK-NEXT: br label [[RETURN]] ; CHECK: return.loopexit1: @@ -228,8 +226,7 @@ define void @test4(ptr %ptr) { ; CHECK: for.body1208.lr.ph: ; CHECK-NEXT: br label [[FOR_BODY1208:%.*]] ; CHECK: for.body1208: -; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ 0, [[FOR_BODY1208_LR_PH]] ], [ [[TMP1:%.*]], [[FOR_INC1498:%.*]] ] -; CHECK-NEXT: [[M_0804:%.*]] = phi i32 [ 1, [[FOR_BODY1208_LR_PH]] ], [ [[INC1499:%.*]], [[FOR_INC1498]] ] +; CHECK-NEXT: [[M_0804:%.*]] = phi i32 [ 1, [[FOR_BODY1208_LR_PH]] ], [ [[INC1499:%.*]], [[FOR_INC1498:%.*]] ] ; CHECK-NEXT: [[IDXPROM1212:%.*]] = zext i32 [[M_0804]] to i64 ; CHECK-NEXT: [[V:%.*]] = call i32 @get.i32() ; CHECK-NEXT: [[CMP1215:%.*]] = icmp eq i32 0, [[V]] @@ -256,13 +253,9 @@ define void @test4(ptr %ptr) { ; CHECK-NEXT: [[CMP1358:%.*]] = icmp eq i32 [[V_2]], 0 ; CHECK-NEXT: br i1 [[CMP1358]], label [[IF_THEN1360:%.*]], label [[FOR_INC1498]] ; CHECK: if.then1360: -; CHECK-NEXT: [[DOTLCSSA2:%.*]] = phi i32 [ [[TMP0]], [[IF_ELSE1351]] ] -; CHECK-NEXT: [[M_0804_LCSSA1:%.*]] = phi i32 [ [[M_0804]], [[IF_ELSE1351]] ] -; CHECK-NEXT: [[CMP1392:%.*]] = icmp slt i32 [[M_0804_LCSSA1]], [[DOTLCSSA2]] ; CHECK-NEXT: unreachable ; CHECK: for.inc1498: ; CHECK-NEXT: [[INC1499]] = add nuw nsw i32 [[M_0804]], 1 -; CHECK-NEXT: [[TMP1]] = load i32, ptr [[PTR]], align 8 ; CHECK-NEXT: br label [[FOR_BODY1208]] ; CHECK: if.then1504: ; CHECK-NEXT: unreachable @@ -495,17 +488,13 @@ define void @test7(ptr %ptr) { ; CHECK: while.body: ; CHECK-NEXT: br label [[FOR_BODY1208:%.*]] ; CHECK: for.body1208: -; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ undef, [[WHILE_BODY]] ], [ [[TMP1:%.*]], [[FOR_INC1498:%.*]] ] -; CHECK-NEXT: [[M_048:%.*]] = phi i32 [ 1, [[WHILE_BODY]] ], [ [[INC1499:%.*]], [[FOR_INC1498]] ] +; CHECK-NEXT: [[M_048:%.*]] = phi i32 [ 1, [[WHILE_BODY]] ], [ [[INC1499:%.*]], [[FOR_INC1498:%.*]] ] ; CHECK-NEXT: [[IDXPROM1212:%.*]] = zext i32 [[M_048]] to i64 ; CHECK-NEXT: [[XPOS1214:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 [[IDXPROM1212]] ; CHECK-NEXT: [[V_1:%.*]] = call i32 @get.i32() ; CHECK-NEXT: [[CMP1215:%.*]] = icmp eq i32 0, [[V_1]] ; CHECK-NEXT: br i1 [[CMP1215]], label [[IF_THEN1217:%.*]], label [[IF_ELSE1351:%.*]] ; CHECK: if.then1217: -; CHECK-NEXT: [[DOTLCSSA:%.*]] = phi i32 [ [[TMP0]], [[FOR_BODY1208]] ] -; CHECK-NEXT: [[M_048_LCSSA:%.*]] = phi i32 [ [[M_048]], [[FOR_BODY1208]] ] -; CHECK-NEXT: [[CMP1249_NOT_NOT:%.*]] = icmp slt i32 [[M_048_LCSSA]], [[DOTLCSSA]] ; CHECK-NEXT: unreachable ; CHECK: if.else1351: ; CHECK-NEXT: [[CMP1358:%.*]] = icmp eq i32 0, undef @@ -526,7 +515,6 @@ define void @test7(ptr %ptr) { ; CHECK-NEXT: br label [[IF_END1824:%.*]] ; CHECK: for.inc1498: ; CHECK-NEXT: [[INC1499]] = add nuw nsw i32 [[M_048]], 1 -; CHECK-NEXT: [[TMP1]] = load i32, ptr undef, align 8 ; CHECK-NEXT: br label [[FOR_BODY1208]] ; CHECK: if.end1824: ; CHECK-NEXT: br label [[WHILE_BODY]] diff --git a/llvm/test/Transforms/IndVarSimplify/sentinel.ll b/llvm/test/Transforms/IndVarSimplify/sentinel.ll index f9ee4a61f4862..fcb010d31f8a0 100644 --- a/llvm/test/Transforms/IndVarSimplify/sentinel.ll +++ b/llvm/test/Transforms/IndVarSimplify/sentinel.ll @@ -11,7 +11,6 @@ define void @test() personality ptr @snork { ; CHECK: bb1: ; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[BB4]] ; CHECK: bb2: -; CHECK-NEXT: [[TMP3:%.*]] = phi i32 [ undef, [[BB1:%.*]] ] ; CHECK-NEXT: ret void ; CHECK: bb4: ; CHECK-NEXT: [[TMP6:%.*]] = invoke i32 @quux() [ "deopt"(i32 0, i32 0, i32 0, i32 180, i32 0, i32 25, i32 0, i32 7, ptr null, i32 7, ptr null, i32 7, ptr null, i32 3, i32 undef, i32 3, i32 undef, i32 7, ptr null, i32 3, i32 undef, i32 3, i32 undef, i32 3, i32 undef, i32 3, i32 undef, i32 4, double undef, i32 7, ptr null, i32 4, i64 undef, i32 7, ptr null, i32 0, ptr addrspace(1) undef, i32 3, i32 undef, i32 0, ptr addrspace(1) undef, i32 0, ptr addrspace(1) undef, i32 0, ptr addrspace(1) undef, i32 0, ptr addrspace(1) undef, i32 0, ptr addrspace(1) undef, i32 0, ptr addrspace(1) undef, i32 0, ptr addrspace(1) undef, i32 0, ptr addrspace(1) undef, i32 7, ptr null) ] @@ -19,7 +18,7 @@ define void @test() personality ptr @snork { ; CHECK: bb7: ; CHECK-NEXT: br label [[BB9:%.*]] ; CHECK: bb9: -; CHECK-NEXT: br i1 true, label [[BB1]], label [[BB9]] +; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB9]] ; CHECK: bb15: ; CHECK-NEXT: [[TMP16:%.*]] = landingpad { ptr, i32 } ; CHECK-NEXT: cleanup diff --git a/llvm/test/Transforms/IndVarSimplify/simplify-indvars-post-loop.ll b/llvm/test/Transforms/IndVarSimplify/simplify-indvars-post-loop.ll new file mode 100644 index 0000000000000..20da68f946345 --- /dev/null +++ b/llvm/test/Transforms/IndVarSimplify/simplify-indvars-post-loop.ll @@ -0,0 +1,112 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt < %s -S -passes=indvars --indvars-max-depth-out-of-loop=0 | FileCheck %s + +define dso_local i1 @ugt_add_rec_iv(ptr nocapture noundef readonly %s) local_unnamed_addr #0 { +; CHECK-LABEL: define dso_local i1 @ugt_add_rec_iv( +; CHECK-SAME: ptr nocapture noundef readonly [[S:%.*]]) local_unnamed_addr { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[WHILE_COND:.*]] +; CHECK: [[WHILE_COND]]: +; CHECK-NEXT: [[I_0:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[ADD:%.*]], %[[WHILE_BODY:.*]] ] +; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp ugt i64 [[I_0]], 1234 +; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[WHILE_END:.*]], label %[[WHILE_BODY]] +; CHECK: [[WHILE_BODY]]: +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[S]], i64 [[I_0]] +; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1 +; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[TMP0]], -48 +; CHECK-NEXT: [[OR_COND:%.*]] = icmp ult i8 [[TMP1]], 10 +; CHECK-NEXT: [[ADD]] = add nuw nsw i64 [[I_0]], 1 +; CHECK-NEXT: br i1 [[OR_COND]], label %[[WHILE_COND]], label %[[WHILE_END]] +; CHECK: [[WHILE_END]]: +; CHECK-NEXT: ret i1 true +; +entry: + br label %while.cond + +while.cond: ; preds = %while.body, %entry + %i.0 = phi i64 [ 0, %entry ], [ %add, %while.body ] + %exitcond.not = icmp ugt i64 %i.0, 1234 + br i1 %exitcond.not, label %while.end, label %while.body + +while.body: ; preds = %while.cond + %arrayidx = getelementptr inbounds i8, ptr %s, i64 %i.0 + %0 = load i8, ptr %arrayidx, align 1 + %1 = add i8 %0, -48 + %or.cond = icmp ult i8 %1, 10 + %add = add nuw nsw i64 %i.0, 1 + br i1 %or.cond, label %while.cond, label %while.end + +while.end: ; preds = %while.body, %while.cond + %cmp6 = icmp ule i64 %i.0, 1235 + ret i1 %cmp6 +} + +define dso_local i1 @ne_add_rec_iv(ptr nocapture noundef readonly %s) local_unnamed_addr #0 { +; CHECK-LABEL: define dso_local i1 @ne_add_rec_iv( +; CHECK-SAME: ptr nocapture noundef readonly [[S:%.*]]) local_unnamed_addr { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[WHILE_COND:.*]] +; CHECK: [[WHILE_COND]]: +; CHECK-NEXT: [[I_0:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[ADD:%.*]], %[[WHILE_BODY:.*]] ] +; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[I_0]], 1235 +; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[WHILE_END:.*]], label %[[WHILE_BODY]] +; CHECK: [[WHILE_BODY]]: +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[S]], i64 [[I_0]] +; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1 +; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[TMP0]], -48 +; CHECK-NEXT: [[OR_COND:%.*]] = icmp ult i8 [[TMP1]], 10 +; CHECK-NEXT: [[ADD]] = add nuw nsw i64 [[I_0]], 1 +; CHECK-NEXT: br i1 [[OR_COND]], label %[[WHILE_COND]], label %[[WHILE_END]] +; CHECK: [[WHILE_END]]: +; CHECK-NEXT: ret i1 true +; +entry: + br label %while.cond + +while.cond: ; preds = %while.body, %entry + %i.0 = phi i64 [ 0, %entry ], [ %add, %while.body ] + %exitcond.not = icmp eq i64 %i.0, 1235 + br i1 %exitcond.not, label %while.end, label %while.body + +while.body: ; preds = %while.cond + %arrayidx = getelementptr inbounds i8, ptr %s, i64 %i.0 + %0 = load i8, ptr %arrayidx, align 1 + %1 = add i8 %0, -48 + %or.cond = icmp ult i8 %1, 10 + %add = add nuw nsw i64 %i.0, 1 + br i1 %or.cond, label %while.cond, label %while.end + +while.end: ; preds = %while.body, %while.cond + %cmp6 = icmp ule i64 %i.0, 1235 + ret i1 %cmp6 +} + +; sanity check to verify there is no simplification of outer loop phis. +define dso_local i32 @nested_loop(i32 noundef %0, i32 noundef %1) local_unnamed_addr #0 { + %3 = icmp eq i32 %0, 0 + br i1 %3, label %18, label %4 + +4: ; preds = %2, %15 + %5 = phi i32 [ %16, %15 ], [ 0, %2 ] + %6 = phi i32 [ %13, %15 ], [ 1, %2 ] + %7 = urem i32 %5, %1 + br label %8 + +8: ; preds = %4, %8 + %9 = phi i32 [ %7, %4 ], [ %11, %8 ] + %10 = phi i32 [ %6, %4 ], [ %13, %8 ] + %11 = add i32 %9, 1 + %12 = mul i32 %11, %9 + %13 = add i32 %12, %10 + %14 = icmp ult i32 %11, %1 + br i1 %14, label %8, label %15 + +15: ; preds = %8 + %16 = add i32 %11, %5 + %17 = icmp ult i32 %16, %0 + br i1 %17, label %4, label %18 + +18: ; preds = %15, %2 + %19 = phi i32 [ 1, %2 ], [ %13, %15 ] + ret i32 %19 +} diff --git a/llvm/test/Transforms/LoopDeletion/pr53969.ll b/llvm/test/Transforms/LoopDeletion/pr53969.ll index f9b9dc3373b5e..94de823a9d8ab 100644 --- a/llvm/test/Transforms/LoopDeletion/pr53969.ll +++ b/llvm/test/Transforms/LoopDeletion/pr53969.ll @@ -31,17 +31,16 @@ define void @test() { ; CHECK: bb32: ; CHECK-NEXT: ret void ; CHECK: bb33.loopexit: -; CHECK-NEXT: [[TMP2_LCSSA9:%.*]] = phi i32 [ [[TMP2_LCSSA12]], [[BB11:%.*]] ] ; CHECK-NEXT: br label [[BB33:%.*]] ; CHECK: bb33.loopexit1: ; CHECK-NEXT: [[TMP2_LCSSA:%.*]] = phi i32 [ 11, [[BB1]] ] ; CHECK-NEXT: br label [[BB33]] ; CHECK: bb33: -; CHECK-NEXT: [[TMP210:%.*]] = phi i32 [ [[TMP2_LCSSA]], [[BB33_LOOPEXIT1]] ], [ [[TMP2_LCSSA9]], [[BB33_LOOPEXIT]] ] +; CHECK-NEXT: [[TMP210:%.*]] = phi i32 [ [[TMP2_LCSSA]], [[BB33_LOOPEXIT1]] ], [ [[TMP2_LCSSA12]], [[BB33_LOOPEXIT]] ] ; CHECK-NEXT: call void @use(i32 [[TMP210]]) ; CHECK-NEXT: ret void ; CHECK: bb34: -; CHECK-NEXT: br i1 false, label [[BB11]], label [[BB12:%.*]] +; CHECK-NEXT: br i1 false, label [[BB11:%.*]], label [[BB12:%.*]] ; CHECK: bb42: ; CHECK-NEXT: [[TMP24_LCSSA:%.*]] = phi i32 [ undef, [[BB22]] ] ; CHECK-NEXT: [[TMP18_LCSSA4:%.*]] = phi i64 [ 0, [[BB22]] ] diff --git a/llvm/test/Transforms/LoopVectorize/X86/pr54413-select-interleave-count-loop-with-cost-zero.ll b/llvm/test/Transforms/LoopVectorize/X86/pr54413-select-interleave-count-loop-with-cost-zero.ll index ecab2e6bf4aec..d65b1aa97778a 100644 --- a/llvm/test/Transforms/LoopVectorize/X86/pr54413-select-interleave-count-loop-with-cost-zero.ll +++ b/llvm/test/Transforms/LoopVectorize/X86/pr54413-select-interleave-count-loop-with-cost-zero.ll @@ -15,10 +15,8 @@ define void @pr54413(ptr %ptr.base) { ; CHECK: loop2.preheader: ; CHECK-NEXT: br label [[LOOP2:%.*]] ; CHECK: loop2: -; CHECK-NEXT: [[PTR_NEXT:%.*]] = getelementptr inbounds i64, ptr [[PTR_BASE:%.*]], i64 1 ; CHECK-NEXT: br i1 true, label [[LOOP2_EXIT:%.*]], label [[LOOP2]] ; CHECK: loop2.exit: -; CHECK-NEXT: [[PTR_NEXT_LCSSA:%.*]] = phi ptr [ [[PTR_NEXT]], [[LOOP2]] ] ; CHECK-NEXT: br label [[LOOP1_LATCH]] ; CHECK: loop1.latch: ; CHECK-NEXT: br label [[LOOP1]]