From cfc3c627f3b04b5136f527dd1d7a7da65755a1f1 Mon Sep 17 00:00:00 2001 From: David Sherwood Date: Wed, 29 Jan 2025 11:18:22 +0000 Subject: [PATCH 1/5] [LoopVectorize] Enable vectorisation of early exit loops with live-outs This work feeds part of PR #88385, and adds support for vectorising loops with uncountable early exits and outside users of loop-defined variables. When calculating the final value from an uncountable early exit we need to calculate the vector lane that triggered the exit, and hence determine the value at the point we exited. All code for calculating the last value when exiting the loop early now lives in a new vector.early.exit block, which sits between the middle.split block and the original exit block. Doing this required the following fix: * The vplan verifier incorrectly assumed that the block containing a definition always dominates the block of the user. That's not true if you can arrive at the use block from multiple incoming blocks. This is possible for early exit loops where both the early exit and the latch jump to the same block. I've added a new ExtractFirstActive VPInstruction that extracts the first active lane of a vector, i.e. the lane of the vector predicate that triggered the exit. NOTE: The IR generated for dealing with live-outs from early exit loops is unoptimised, as opposed to normal loops. This inevitably leads to poor quality code, but this can be fixed up later. --- llvm/docs/Vectorizers.rst | 8 +- llvm/docs/vplan-early-exit.dot | 18 +- llvm/docs/vplan-early-exit.png | Bin 131943 -> 76189 bytes .../Transforms/Vectorize/LoopVectorize.cpp | 10 +- llvm/lib/Transforms/Vectorize/VPlan.cpp | 21 +- llvm/lib/Transforms/Vectorize/VPlan.h | 6 + .../Transforms/Vectorize/VPlanAnalysis.cpp | 1 + .../lib/Transforms/Vectorize/VPlanRecipes.cpp | 13 +- .../Transforms/Vectorize/VPlanTransforms.cpp | 18 +- .../Transforms/Vectorize/VPlanTransforms.h | 2 +- .../Transforms/Vectorize/VPlanVerifier.cpp | 6 +- .../AArch64/simple_early_exit.ll | 231 +++++- .../LoopVectorize/early_exit_legality.ll | 4 +- .../LoopVectorize/single_early_exit.ll | 22 +- .../single_early_exit_live_outs.ll | 783 ++++++++++++++++-- .../uncountable-early-exit-vplan.ll | 21 +- 16 files changed, 1015 insertions(+), 149 deletions(-) diff --git a/llvm/docs/Vectorizers.rst b/llvm/docs/Vectorizers.rst index f134a6df94a69..d19d03050436a 100644 --- a/llvm/docs/Vectorizers.rst +++ b/llvm/docs/Vectorizers.rst @@ -405,9 +405,11 @@ Early Exit Vectorization When vectorizing a loop with a single early exit, the loop blocks following the early exit are predicated and the vector loop will always exit via the latch. If the early exit has been taken, the vector loop's successor block -(``middle.split`` below) branches to the early exit block. Otherwise -``middle.block`` selects between the exit block from the latch or the scalar -remainder loop. +(``middle.split`` below) branches to the early exit block via an intermediate +block (``vector.early.exit`` below). This intermediate block is responsible for +calculating any exit values of loop-defined variables that are used in the +early exit block. Otherwise, ``middle.block`` selects between the exit block +from the latch or the scalar remainder loop. .. image:: vplan-early-exit.png diff --git a/llvm/docs/vplan-early-exit.dot b/llvm/docs/vplan-early-exit.dot index 63490b0cdb2e4..980fc6939b6d4 100644 --- a/llvm/docs/vplan-early-exit.dot +++ b/llvm/docs/vplan-early-exit.dot @@ -19,23 +19,27 @@ compound=true "middle.split" ] N4 -> N5 [ label=""] - N4 -> N6 [ label=""] + N4 -> N7 [ label=""] N5 [label = - "early.exit" + "vector.early.exit" ] + N5 -> N6 [ label=""] N6 [label = - "middle.block" + "early.exit" ] - N6 -> N9 [ label=""] - N6 -> N7 [ label=""] N7 [label = - "scalar.ph" + "middle.block" ] + N7 -> N10 [ label=""] N7 -> N8 [ label=""] N8 [label = - "loop.header" + "scalar.ph" ] + N8 -> N9 [ label=""] N9 [label = + "loop.header" + ] + N10 [label = "latch.exit" ] } diff --git a/llvm/docs/vplan-early-exit.png b/llvm/docs/vplan-early-exit.png index 3cd293bcdbcc822e6f7e7a6d36582fbea2cc4744..249b90c69e2b809887745ff725f7ebd074623688 100644 GIT binary patch literal 76189 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 z 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 Y57^vgI}?YYNcfW9dvH(8ZvD&u7mW{&ZU6uP literal 131943 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 { - if (!VPlanTransforms::handleUncountableEarlyExit( - *Plan, *PSE.getSE(), OrigLoop, UncountableExitingBlock, - RecipeBuilder)) { - reportVectorizationFailure( - "Some exit values in loop with uncountable exit not supported yet", - "UncountableEarlyExitLoopsUnsupportedExitValue", ORE, OrigLoop); - return nullptr; - } + VPlanTransforms::handleUncountableEarlyExit( + *Plan, *PSE.getSE(), OrigLoop, UncountableExitingBlock, RecipeBuilder); } DenseMap IVEndValues; addScalarResumePhis(RecipeBuilder, *Plan, IVEndValues); diff --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp index 35da93ee3b407..e0aa59d819650 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp @@ -500,8 +500,15 @@ void VPBasicBlock::execute(VPTransformState *State) { UnreachableInst *Terminator = State->Builder.CreateUnreachable(); // Register NewBB in its loop. In innermost loops its the same for all // BB's. - if (State->CurrentParentLoop) - State->CurrentParentLoop->addBasicBlockToLoop(NewBB, *State->LI); + Loop *ParentLoop = State->CurrentParentLoop; + // If this block has a sole successor that is an exit block then it needs + // adding to the same parent loop as the exit block. + VPBlockBase *SuccVPBB = getSingleSuccessor(); + if (SuccVPBB && State->Plan->isExitBlock(SuccVPBB)) + ParentLoop = State->LI->getLoopFor( + cast(SuccVPBB)->getIRBasicBlock()); + if (ParentLoop) + ParentLoop->addBasicBlockToLoop(NewBB, *State->LI); State->Builder.SetInsertPoint(Terminator); State->CFG.PrevBB = NewBB; @@ -949,6 +956,16 @@ void VPlan::prepareToExecute(Value *TripCountV, Value *VectorTripCountV, } } +bool VPlan::isExitBlock(VPBlockBase *VPBB) { + if (isa(VPBB) && VPBB->getNumSuccessors() == 0) { + assert(is_contained(getExitBlocks(), VPBB) && + "Expected to find VPlan block in list of exit blocks!"); + return true; + } + + return false; +} + /// Generate the code inside the preheader and body of the vectorized loop. /// Assumes a single pre-header basic-block was created for this. Introduce /// additional basic-blocks as needed, and fill them all. diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h index a1ff684b2b801..459222234bc37 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.h +++ b/llvm/lib/Transforms/Vectorize/VPlan.h @@ -1223,6 +1223,9 @@ class VPInstruction : public VPRecipeWithIRFlags, // Returns a scalar boolean value, which is true if any lane of its (only // boolean) vector operand is true. AnyOf, + // Extracts the first active lane of a vector, where the first operand is + // the predicate, and the second operand is the vector to extract. + ExtractFirstActive, }; private: @@ -3967,6 +3970,9 @@ class VPlan { /// of VPBlockShallowTraversalWrapper. auto getExitBlocks(); + /// Returns true if \p VPBB is an exit block. + bool isExitBlock(VPBlockBase *VPBB); + /// The trip count of the original loop. VPValue *getTripCount() const { assert(TripCount && "trip count needs to be set before accessing it"); diff --git a/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp b/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp index 27357ff04b5f2..71fb6d42116cf 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp @@ -78,6 +78,7 @@ Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPInstruction *R) { case VPInstruction::CanonicalIVIncrementForPart: case VPInstruction::AnyOf: return SetResultTyFromOp(); + case VPInstruction::ExtractFirstActive: case VPInstruction::ExtractFromEnd: { Type *BaseTy = inferScalarType(R->getOperand(0)); if (auto *VecTy = dyn_cast(BaseTy)) diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index 2679ed6b26b5d..31dc59762333c 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -697,7 +697,13 @@ Value *VPInstruction::generate(VPTransformState &State) { Value *A = State.get(getOperand(0)); return Builder.CreateOrReduce(A); } - + case VPInstruction::ExtractFirstActive: { + Value *Vec = State.get(getOperand(0)); + Value *Mask = State.get(getOperand(1)); + Value *Ctz = + Builder.CreateCountTrailingZeroElems(Builder.getInt64Ty(), Mask); + return Builder.CreateExtractElement(Vec, Ctz); + } default: llvm_unreachable("Unsupported opcode for instruction"); } @@ -705,6 +711,7 @@ Value *VPInstruction::generate(VPTransformState &State) { bool VPInstruction::isVectorToScalar() const { return getOpcode() == VPInstruction::ExtractFromEnd || + getOpcode() == VPInstruction::ExtractFirstActive || getOpcode() == VPInstruction::ComputeReductionResult || getOpcode() == VPInstruction::AnyOf; } @@ -769,6 +776,7 @@ bool VPInstruction::opcodeMayReadOrWriteFromMemory() const { case VPInstruction::CalculateTripCountMinusVF: case VPInstruction::CanonicalIVIncrementForPart: case VPInstruction::ExtractFromEnd: + case VPInstruction::ExtractFirstActive: case VPInstruction::FirstOrderRecurrenceSplice: case VPInstruction::LogicalAnd: case VPInstruction::Not: @@ -888,6 +896,9 @@ void VPInstruction::print(raw_ostream &O, const Twine &Indent, case VPInstruction::AnyOf: O << "any-of"; break; + case VPInstruction::ExtractFirstActive: + O << "extract-first-active"; + break; default: O << Instruction::getOpcodeName(getOpcode()); } diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp index 714250a56ff57..367bb929c1898 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp @@ -2062,7 +2062,7 @@ void VPlanTransforms::convertToConcreteRecipes(VPlan &Plan) { } } -bool VPlanTransforms::handleUncountableEarlyExit( +void VPlanTransforms::handleUncountableEarlyExit( VPlan &Plan, ScalarEvolution &SE, Loop *OrigLoop, BasicBlock *UncountableExitingBlock, VPRecipeBuilder &RecipeBuilder) { VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion(); @@ -2099,12 +2099,17 @@ bool VPlanTransforms::handleUncountableEarlyExit( Builder.createNaryOp(VPInstruction::AnyOf, {EarlyExitTakenCond}); VPBasicBlock *NewMiddle = Plan.createVPBasicBlock("middle.split"); + VPBasicBlock *VectorEarlyExitVPBB = + Plan.createVPBasicBlock("vector.early.exit"); VPBlockUtils::insertOnEdge(LoopRegion, MiddleVPBB, NewMiddle); - VPBlockUtils::connectBlocks(NewMiddle, VPEarlyExitBlock); + VPBlockUtils::connectBlocks(NewMiddle, VectorEarlyExitVPBB); NewMiddle->swapSuccessors(); + VPBlockUtils::connectBlocks(VectorEarlyExitVPBB, VPEarlyExitBlock); + // Update the exit phis in the early exit block. VPBuilder MiddleBuilder(NewMiddle); + VPBuilder EarlyExitB(VectorEarlyExitVPBB); for (VPRecipeBase &R : *VPEarlyExitBlock) { auto *ExitIRI = cast(&R); auto *ExitPhi = dyn_cast(&ExitIRI->getInstruction()); @@ -2113,9 +2118,6 @@ bool VPlanTransforms::handleUncountableEarlyExit( VPValue *IncomingFromEarlyExit = RecipeBuilder.getVPValueOrAddLiveIn( ExitPhi->getIncomingValueForBlock(UncountableExitingBlock)); - // The incoming value from the early exit must be a live-in for now. - if (!IncomingFromEarlyExit->isLiveIn()) - return false; if (OrigLoop->getUniqueExitBlock()) { // If there's a unique exit block, VPEarlyExitBlock has 2 predecessors @@ -2126,7 +2128,12 @@ bool VPlanTransforms::handleUncountableEarlyExit( ExitIRI->addOperand(IncomingFromLatch); ExitIRI->extractLastLaneOfOperand(MiddleBuilder); } + // Add the incoming value from the early exit. + if (!IncomingFromEarlyExit->isLiveIn()) + IncomingFromEarlyExit = + EarlyExitB.createNaryOp(VPInstruction::ExtractFirstActive, + {IncomingFromEarlyExit, EarlyExitTakenCond}); ExitIRI->addOperand(IncomingFromEarlyExit); } MiddleBuilder.createNaryOp(VPInstruction::BranchOnCond, {IsEarlyExitTaken}); @@ -2144,5 +2151,4 @@ bool VPlanTransforms::handleUncountableEarlyExit( Instruction::Or, {IsEarlyExitTaken, IsLatchExitTaken}); Builder.createNaryOp(VPInstruction::BranchOnCond, AnyExitTaken); LatchExitingBranch->eraseFromParent(); - return true; } diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.h b/llvm/lib/Transforms/Vectorize/VPlanTransforms.h index b31fef5d62456..a751b8b5e8dc5 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.h +++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.h @@ -130,7 +130,7 @@ struct VPlanTransforms { /// exit conditions /// * splitting the original middle block to branch to the early exit block /// if taken. - static bool handleUncountableEarlyExit(VPlan &Plan, ScalarEvolution &SE, + static void handleUncountableEarlyExit(VPlan &Plan, ScalarEvolution &SE, Loop *OrigLoop, BasicBlock *UncountableExitingBlock, VPRecipeBuilder &RecipeBuilder); diff --git a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp index 0f151c897d938..e703a2b50934b 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp @@ -222,7 +222,11 @@ bool VPlanVerifier::verifyVPBasicBlock(const VPBasicBlock *VPBB) { continue; } - if (!VPDT.dominates(VPBB, UI->getParent())) { + // Now that we support vectorising loops with uncountable early exits + // we can end up in situations where VPBB does not dominate the exit + // block. Only do the check if the user is not in a VPIRBasicBlock. + if (!isa(UI->getParent()) && + !VPDT.dominates(VPBB, UI->getParent())) { errs() << "Use before def!\n"; return false; } diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/simple_early_exit.ll b/llvm/test/Transforms/LoopVectorize/AArch64/simple_early_exit.ll index ca3a5722affe9..9c23f5ba3d12c 100644 --- a/llvm/test/Transforms/LoopVectorize/AArch64/simple_early_exit.ll +++ b/llvm/test/Transforms/LoopVectorize/AArch64/simple_early_exit.ll @@ -13,21 +13,70 @@ define i64 @same_exit_block_pre_inc_use1() #1 { ; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 4 ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) +; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64() +; CHECK-NEXT: [[TMP1:%.*]] = mul i64 [[TMP0]], 16 +; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 64, [[TMP1]] +; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; CHECK: vector.ph: +; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.vscale.i64() +; CHECK-NEXT: [[TMP3:%.*]] = mul i64 [[TMP2]], 16 +; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 64, [[TMP3]] +; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 64, [[N_MOD_VF]] +; CHECK-NEXT: [[TMP4:%.*]] = call i64 @llvm.vscale.i64() +; CHECK-NEXT: [[TMP5:%.*]] = mul i64 [[TMP4]], 16 +; CHECK-NEXT: [[INDEX_NEXT1:%.*]] = add i64 3, [[N_VEC]] +; CHECK-NEXT: [[TMP7:%.*]] = call @llvm.stepvector.nxv16i64() +; CHECK-NEXT: [[TMP8:%.*]] = mul [[TMP7]], splat (i64 1) +; CHECK-NEXT: [[INDUCTION:%.*]] = add splat (i64 3), [[TMP8]] +; CHECK-NEXT: [[TMP9:%.*]] = mul i64 1, [[TMP5]] +; CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, i64 [[TMP9]], i64 0 +; CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer ; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi [ [[INDUCTION]], [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] +; CHECK-NEXT: [[TMP10:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP11:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP10]] +; CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds i8, ptr [[TMP11]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load , ptr [[TMP12]], align 1 +; CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[TMP10]] +; CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds i8, ptr [[TMP13]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load , ptr [[TMP14]], align 1 +; CHECK-NEXT: [[TMP15:%.*]] = icmp eq [[WIDE_LOAD]], [[WIDE_LOAD2]] +; CHECK-NEXT: [[INDEX_NEXT3]] = add nuw i64 [[INDEX1]], [[TMP5]] +; CHECK-NEXT: [[TMP16:%.*]] = xor [[TMP15]], splat (i1 true) +; CHECK-NEXT: [[TMP17:%.*]] = call i1 @llvm.vector.reduce.or.nxv16i1( [[TMP16]]) +; CHECK-NEXT: [[TMP18:%.*]] = icmp eq i64 [[INDEX_NEXT3]], [[N_VEC]] +; CHECK-NEXT: [[VEC_IND_NEXT]] = add [[VEC_IND]], [[DOTSPLAT]] +; CHECK-NEXT: [[TMP19:%.*]] = or i1 [[TMP17]], [[TMP18]] +; CHECK-NEXT: br i1 [[TMP19]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP0:![0-9]+]] +; CHECK: middle.split: +; CHECK-NEXT: br i1 [[TMP17]], label [[VECTOR_EARLY_EXIT:%.*]], label [[LOOP_INC:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: [[TMP20:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.nxv16i1( [[TMP16]], i1 true) +; CHECK-NEXT: [[TMP21:%.*]] = extractelement [[VEC_IND]], i64 [[TMP20]] +; CHECK-NEXT: br label [[LOOP_END:%.*]] +; CHECK: middle.block: +; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 64, [[N_VEC]] +; CHECK-NEXT: br i1 [[CMP_N]], label [[LOOP_END]], label [[SCALAR_PH]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[INDEX2:%.*]] = phi i64 [ [[INDEX_NEXT1]], [[LOOP_INC]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: br label [[LOOP1:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC1:%.*]] ], [ [[INDEX2]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] ; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END:%.*]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC1]], label [[LOOP_END]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP3:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ 67, [[LOOP_INC1]] ], [ 67, [[LOOP_INC]] ], [ [[TMP21]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -66,19 +115,48 @@ define i64 @same_exit_block_pre_inc_use4() { ; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i64], align 8 ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) +; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; CHECK: vector.ph: ; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT2:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i64, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i64>, ptr [[TMP2]], align 1 +; CHECK-NEXT: [[TMP3:%.*]] = icmp ult <2 x i64> [[VEC_IND]], [[WIDE_LOAD]] +; CHECK-NEXT: [[INDEX_NEXT2]] = add nuw i64 [[INDEX1]], 2 +; CHECK-NEXT: [[TMP4:%.*]] = xor <2 x i1> [[TMP3]], splat (i1 true) +; CHECK-NEXT: [[TMP5:%.*]] = call i1 @llvm.vector.reduce.or.v2i1(<2 x i1> [[TMP4]]) +; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[INDEX_NEXT2]], 64 +; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2) +; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP5]], [[TMP6]] +; CHECK-NEXT: br i1 [[TMP7]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP4:![0-9]+]] +; CHECK: middle.split: +; CHECK-NEXT: br i1 [[TMP5]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: [[TMP8:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v2i1(<2 x i1> [[TMP4]], i1 true) +; CHECK-NEXT: [[TMP9:%.*]] = extractelement <2 x i64> [[VEC_IND]], i64 [[TMP8]] +; CHECK-NEXT: br label [[LOOP_END:%.*]] +; CHECK: middle.block: +; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: br label [[LOOP1:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[P1]], i64 [[INDEX]] ; CHECK-NEXT: [[LD1:%.*]] = load i64, ptr [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i64 [[INDEX]], [[LD1]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END:%.*]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP5:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP9]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -114,20 +192,50 @@ define i64 @loop_contains_safe_call() #1 { ; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 4 ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) +; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; CHECK: vector.ph: +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT2:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds float, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds float, ptr [[TMP1]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x float>, ptr [[TMP2]], align 1 +; CHECK-NEXT: [[TMP3:%.*]] = call fast <4 x float> @llvm.sqrt.v4f32(<4 x float> [[WIDE_LOAD]]) +; CHECK-NEXT: [[TMP4:%.*]] = fcmp fast ult <4 x float> [[TMP3]], splat (float 3.000000e+00) +; CHECK-NEXT: [[INDEX_NEXT2]] = add nuw i64 [[INDEX1]], 4 +; CHECK-NEXT: [[TMP5:%.*]] = xor <4 x i1> [[TMP4]], splat (i1 true) +; CHECK-NEXT: [[TMP6:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP5]]) +; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT2]], 64 +; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) +; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]] +; CHECK-NEXT: br i1 [[TMP8]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]] +; CHECK: middle.split: +; CHECK-NEXT: br i1 [[TMP6]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: [[TMP9:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP5]], i1 true) +; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP9]] +; CHECK-NEXT: br label [[LOOP_END:%.*]] +; CHECK: middle.block: +; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[P1]], i64 [[INDEX]] ; CHECK-NEXT: [[LD1:%.*]] = load float, ptr [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[SQRT:%.*]] = tail call fast float @llvm.sqrt.f32(float [[LD1]]) ; CHECK-NEXT: [[CMP:%.*]] = fcmp fast ult float [[SQRT]], 3.000000e+00 -; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_INC]], label [[LOOP_END:%.*]] +; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_INC]], label [[LOOP_END]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP7:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP10]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -164,20 +272,50 @@ define i64 @loop_contains_safe_div() #1 { ; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 4 ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) +; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; CHECK: vector.ph: ; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT2:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 1 +; CHECK-NEXT: [[TMP3:%.*]] = udiv <2 x i32> [[WIDE_LOAD]], splat (i32 20000) +; CHECK-NEXT: [[TMP4:%.*]] = icmp eq <2 x i32> [[TMP3]], splat (i32 1) +; CHECK-NEXT: [[INDEX_NEXT2]] = add nuw i64 [[INDEX1]], 2 +; CHECK-NEXT: [[TMP5:%.*]] = xor <2 x i1> [[TMP4]], splat (i1 true) +; CHECK-NEXT: [[TMP6:%.*]] = call i1 @llvm.vector.reduce.or.v2i1(<2 x i1> [[TMP5]]) +; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT2]], 64 +; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2) +; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]] +; CHECK-NEXT: br i1 [[TMP8]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP8:![0-9]+]] +; CHECK: middle.split: +; CHECK-NEXT: br i1 [[TMP6]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: [[TMP9:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v2i1(<2 x i1> [[TMP5]], i1 true) +; CHECK-NEXT: [[TMP10:%.*]] = extractelement <2 x i64> [[VEC_IND]], i64 [[TMP9]] +; CHECK-NEXT: br label [[LOOP_END:%.*]] +; CHECK: middle.block: +; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: br label [[LOOP1:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[P1]], i64 [[INDEX]] ; CHECK-NEXT: [[LD1:%.*]] = load i32, ptr [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[LD1]], 20000 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[DIV]], 1 -; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_INC]], label [[LOOP_END:%.*]] +; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_INC]], label [[LOOP_END]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP9:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP10]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -216,21 +354,54 @@ define i64 @loop_contains_load_after_early_exit(ptr dereferenceable(1024) align( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[P1:%.*]] = alloca [1024 x i8], align 4 ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) +; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; CHECK: vector.ph: ; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP2]], align 1 +; CHECK-NEXT: [[TMP3:%.*]] = icmp eq <4 x i32> [[WIDE_LOAD]], splat (i32 1) +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i64, ptr [[P2]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i64, ptr [[TMP4]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load <4 x i64>, ptr [[TMP5]], align 8 +; CHECK-NEXT: [[INDEX_NEXT3]] = add nuw i64 [[INDEX1]], 4 +; CHECK-NEXT: [[TMP6:%.*]] = xor <4 x i1> [[TMP3]], splat (i1 true) +; CHECK-NEXT: [[TMP7:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP6]]) +; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 +; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) +; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP7]], [[TMP8]] +; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP10:![0-9]+]] +; CHECK: middle.split: +; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[WIDE_LOAD2]], i32 3 +; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: [[TMP11:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) +; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP11]] +; CHECK-NEXT: br label [[LOOP_END:%.*]] +; CHECK: middle.block: +; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: br label [[LOOP1:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[P1]], i64 [[INDEX]] ; CHECK-NEXT: [[LD1:%.*]] = load i32, ptr [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[LD1]], 1 -; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_INC]], label [[LOOP_END:%.*]] +; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_INC]], label [[LOOP_END]] ; CHECK: loop.inc: ; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i64, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i64, ptr [[ARRAYIDX2]], align 8 ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP11:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ [[LD2]], [[LOOP_INC]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ [[LD2]], [[LOOP_INC]] ], [ [[TMP10]], [[MIDDLE_BLOCK]] ], [ [[TMP12]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -305,9 +476,11 @@ define i32 @diff_exit_block_needs_scev_check(i32 %end) { ; CHECK-NEXT: [[TMP15:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP14]]) ; CHECK-NEXT: [[TMP16:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] ; CHECK-NEXT: [[TMP17:%.*]] = or i1 [[TMP15]], [[TMP16]] -; CHECK-NEXT: br i1 [[TMP17]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] +; CHECK-NEXT: br i1 [[TMP17]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP12:![0-9]+]] ; CHECK: middle.split: -; CHECK-NEXT: br i1 [[TMP15]], label [[FOUND:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK-NEXT: br i1 [[TMP15]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: br label [[FOUND:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[UMAX1]], [[N_VEC]] ; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]] @@ -329,7 +502,7 @@ define i32 @diff_exit_block_needs_scev_check(i32 %end) { ; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[IND_NEXT]] to i32 ; CHECK-NEXT: [[GEP_IND_NEXT]] = add i64 [[GEP_IND]], 1 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[CONV]], [[END_CLAMPED]] -; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[EXIT]], !llvm.loop [[LOOP3:![0-9]+]] +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[EXIT]], !llvm.loop [[LOOP13:![0-9]+]] ; CHECK: found: ; CHECK-NEXT: ret i32 1 ; CHECK: exit: @@ -420,5 +593,15 @@ attributes #1 = { "target-features"="+sve" vscale_range(1,16) } ; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]} ; CHECK: [[META1]] = !{!"llvm.loop.isvectorized", i32 1} ; CHECK: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"} -; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META1]]} +; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META2]], [[META1]]} +; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[META1]], [[META2]]} +; CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[META2]], [[META1]]} +; CHECK: [[LOOP6]] = distinct !{[[LOOP6]], [[META1]], [[META2]]} +; CHECK: [[LOOP7]] = distinct !{[[LOOP7]], [[META2]], [[META1]]} +; CHECK: [[LOOP8]] = distinct !{[[LOOP8]], [[META1]], [[META2]]} +; CHECK: [[LOOP9]] = distinct !{[[LOOP9]], [[META2]], [[META1]]} +; CHECK: [[LOOP10]] = distinct !{[[LOOP10]], [[META1]], [[META2]]} +; CHECK: [[LOOP11]] = distinct !{[[LOOP11]], [[META2]], [[META1]]} +; CHECK: [[LOOP12]] = distinct !{[[LOOP12]], [[META1]], [[META2]]} +; CHECK: [[LOOP13]] = distinct !{[[LOOP13]], [[META1]]} ;. diff --git a/llvm/test/Transforms/LoopVectorize/early_exit_legality.ll b/llvm/test/Transforms/LoopVectorize/early_exit_legality.ll index 6d365b9d77e80..de455c81d363e 100644 --- a/llvm/test/Transforms/LoopVectorize/early_exit_legality.ll +++ b/llvm/test/Transforms/LoopVectorize/early_exit_legality.ll @@ -49,7 +49,7 @@ define i64 @same_exit_block_pre_inc_use1() { ; CHECK-LABEL: LV: Checking a loop in 'same_exit_block_pre_inc_use1' ; CHECK: LV: Found an early exit loop with symbolic max backedge taken count: 63 ; CHECK-NEXT: LV: We can vectorize this loop! -; CHECK: LV: Not vectorizing: Some exit values in loop with uncountable exit not supported yet. +; CHECK-NOT: LV: Not vectorizing entry: %p1 = alloca [1024 x i8] %p2 = alloca [1024 x i8] @@ -141,7 +141,7 @@ define i64 @loop_contains_load_after_early_exit(ptr dereferenceable(1024) align( ; CHECK-LABEL: LV: Checking a loop in 'loop_contains_load_after_early_exit' ; CHECK: LV: Found an early exit loop with symbolic max backedge taken count: 63 ; CHECK-NEXT: LV: We can vectorize this loop! -; CHECK: LV: Not vectorizing: Some exit values in loop with uncountable exit not supported yet. +; CHECK-NOT: LV: Not vectorizing entry: %p1 = alloca [1024 x i8] call void @init_mem(ptr %p1, i64 1024) diff --git a/llvm/test/Transforms/LoopVectorize/single_early_exit.ll b/llvm/test/Transforms/LoopVectorize/single_early_exit.ll index 67a64a90c1179..f447f623b3c99 100644 --- a/llvm/test/Transforms/LoopVectorize/single_early_exit.ll +++ b/llvm/test/Transforms/LoopVectorize/single_early_exit.ll @@ -33,8 +33,10 @@ define i64 @same_exit_block_phi_of_consts() { ; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] ; CHECK: middle.split: ; CHECK-NEXT: br i1 [[TMP7]], label [[LOOP_END:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: br label [[LOOP_END1:%.*]] ; CHECK: middle.block: -; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] +; CHECK-NEXT: br i1 true, label [[LOOP_END1]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] ; CHECK-NEXT: br label [[LOOP:%.*]] @@ -45,13 +47,13 @@ define i64 @same_exit_block_phi_of_consts() { ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END1]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP3:![0-9]+]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END1]], !llvm.loop [[LOOP3:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ 0, [[LOOP]] ], [ 1, [[LOOP_INC]] ], [ 1, [[MIDDLE_BLOCK]] ], [ 0, [[MIDDLE_SPLIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ 0, [[LOOP]] ], [ 1, [[LOOP_INC]] ], [ 1, [[MIDDLE_BLOCK]] ], [ 0, [[LOOP_END]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -110,6 +112,8 @@ define i64 @diff_exit_block_phi_of_consts() { ; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]] ; CHECK: middle.split: ; CHECK-NEXT: br i1 [[TMP7]], label [[LOOP_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: br label [[LOOP_EARLY_EXIT1:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END:%.*]], label [[SCALAR_PH]] ; CHECK: scalar.ph: @@ -122,7 +126,7 @@ define i64 @diff_exit_block_phi_of_consts() { ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_EARLY_EXIT]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_EARLY_EXIT1]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 @@ -206,7 +210,9 @@ define i32 @diff_exit_block_needs_scev_check(i32 %end) { ; CHECK-NEXT: [[TMP17:%.*]] = or i1 [[TMP15]], [[TMP16]] ; CHECK-NEXT: br i1 [[TMP17]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]] ; CHECK: middle.split: -; CHECK-NEXT: br i1 [[TMP15]], label [[FOUND:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK-NEXT: br i1 [[TMP15]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: br label [[FOUND:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[UMAX1]], [[N_VEC]] ; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]] @@ -292,6 +298,8 @@ define i32 @diff_blocks_invariant_early_exit_cond(ptr %s) { ; CHECK-NEXT: br i1 [[TMP3]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]] ; CHECK: middle.split: ; CHECK-NEXT: br i1 [[TMP1]], label [[EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: br label [[EARLY_EXIT1:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]] ; CHECK: scalar.ph: @@ -299,7 +307,7 @@ define i32 @diff_blocks_invariant_early_exit_cond(ptr %s) { ; CHECK-NEXT: br label [[FOR_BODY:%.*]] ; CHECK: for.body: ; CHECK-NEXT: [[IND:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IND_NEXT:%.*]], [[FOR_INC:%.*]] ] -; CHECK-NEXT: br i1 [[COND]], label [[FOR_INC]], label [[EARLY_EXIT]] +; CHECK-NEXT: br i1 [[COND]], label [[FOR_INC]], label [[EARLY_EXIT1]] ; CHECK: for.inc: ; CHECK-NEXT: [[IND_NEXT]] = add nsw i32 [[IND]], 1 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[IND_NEXT]], 266 diff --git a/llvm/test/Transforms/LoopVectorize/single_early_exit_live_outs.ll b/llvm/test/Transforms/LoopVectorize/single_early_exit_live_outs.ll index f03c0f544c294..94bacf14049ba 100644 --- a/llvm/test/Transforms/LoopVectorize/single_early_exit_live_outs.ll +++ b/llvm/test/Transforms/LoopVectorize/single_early_exit_live_outs.ll @@ -10,21 +10,53 @@ define i64 @same_exit_block_pre_inc_use1() { ; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 1 ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) +; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; CHECK: vector.ph: +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP2]], align 1 +; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load <4 x i8>, ptr [[TMP4]], align 1 +; CHECK-NEXT: [[TMP5:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], [[WIDE_LOAD2]] +; CHECK-NEXT: [[INDEX_NEXT3]] = add nuw i64 [[INDEX1]], 4 +; CHECK-NEXT: [[TMP6:%.*]] = xor <4 x i1> [[TMP5]], splat (i1 true) +; CHECK-NEXT: [[TMP7:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP6]]) +; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 +; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) +; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP7]], [[TMP8]] +; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] +; CHECK: middle.split: +; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: [[TMP10:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) +; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP10]] +; CHECK-NEXT: br label [[LOOP_END:%.*]] +; CHECK: middle.block: +; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] ; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END:%.*]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP3:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -62,22 +94,55 @@ define i64 @same_exit_block_pre_inc1_use_inv_cond(i1 %cond) { ; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 1 ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) +; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; CHECK: vector.ph: ; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP2]], align 1 +; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load <4 x i8>, ptr [[TMP4]], align 1 +; CHECK-NEXT: [[TMP5:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], [[WIDE_LOAD2]] +; CHECK-NEXT: [[TMP6:%.*]] = select i1 [[COND]], <4 x i1> [[TMP5]], <4 x i1> zeroinitializer +; CHECK-NEXT: [[INDEX_NEXT3]] = add nuw i64 [[INDEX1]], 4 +; CHECK-NEXT: [[TMP7:%.*]] = xor <4 x i1> [[TMP6]], splat (i1 true) +; CHECK-NEXT: [[TMP8:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP7]]) +; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 +; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) +; CHECK-NEXT: [[TMP10:%.*]] = or i1 [[TMP8]], [[TMP9]] +; CHECK-NEXT: br i1 [[TMP10]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP4:![0-9]+]] +; CHECK: middle.split: +; CHECK-NEXT: br i1 [[TMP8]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: [[TMP11:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP7]], i1 true) +; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP11]] +; CHECK-NEXT: br label [[LOOP_END:%.*]] +; CHECK: middle.block: +; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: br label [[LOOP1:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] ; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] ; CHECK-NEXT: [[CMP4:%.*]] = select i1 [[COND]], i1 [[CMP3]], i1 false -; CHECK-NEXT: br i1 [[CMP4]], label [[LOOP_INC]], label [[LOOP_END:%.*]] +; CHECK-NEXT: br i1 [[CMP4]], label [[LOOP_INC]], label [[LOOP_END]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP5:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP12]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -115,21 +180,53 @@ define i64 @same_exit_block_pre_inc_use1_gep_two_indices() { ; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 1 ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) +; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; CHECK: vector.ph: ; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1024 x i8], ptr [[P1]], i64 0, i64 [[TMP0]] +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP2]], align 1 +; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1024 x i8], ptr [[P2]], i64 0, i64 [[TMP0]] +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load <4 x i8>, ptr [[TMP4]], align 1 +; CHECK-NEXT: [[TMP5:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], [[WIDE_LOAD2]] +; CHECK-NEXT: [[INDEX_NEXT3]] = add nuw i64 [[INDEX1]], 4 +; CHECK-NEXT: [[TMP6:%.*]] = xor <4 x i1> [[TMP5]], splat (i1 true) +; CHECK-NEXT: [[TMP7:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP6]]) +; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 +; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) +; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP7]], [[TMP8]] +; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP6:![0-9]+]] +; CHECK: middle.split: +; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: [[TMP10:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) +; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP10]] +; CHECK-NEXT: br label [[LOOP_END:%.*]] +; CHECK: middle.block: +; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: br label [[LOOP1:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [1024 x i8], ptr [[P1]], i64 0, i64 [[INDEX]] ; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [1024 x i8], ptr [[P2]], i64 0, i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END:%.*]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP7:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -166,21 +263,53 @@ define i64 @same_exit_block_pre_inc_use1_alloca_diff_type() { ; CHECK-NEXT: [[P2:%.*]] = alloca [40 x i32], align 4 ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) +; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; CHECK: vector.ph: +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP2]], align 1 +; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load <4 x i8>, ptr [[TMP4]], align 1 +; CHECK-NEXT: [[TMP5:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], [[WIDE_LOAD2]] +; CHECK-NEXT: [[INDEX_NEXT3]] = add nuw i64 [[INDEX1]], 4 +; CHECK-NEXT: [[TMP6:%.*]] = xor <4 x i1> [[TMP5]], splat (i1 true) +; CHECK-NEXT: [[TMP7:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP6]]) +; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 +; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) +; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP7]], [[TMP8]] +; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]] +; CHECK: middle.split: +; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: [[TMP10:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) +; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP10]] +; CHECK-NEXT: br label [[LOOP_END:%.*]] +; CHECK: middle.block: +; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] ; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END:%.*]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP9:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -238,12 +367,14 @@ define i64 @same_exit_block_pre_inc_use2() { ; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) ; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP7]], [[TMP8]] -; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] +; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]] ; CHECK: middle.split: ; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 3 ; CHECK-NEXT: br i1 [[TMP7]], label [[LOOP_END:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: br label [[LOOP_END1:%.*]] ; CHECK: middle.block: -; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] +; CHECK-NEXT: br i1 true, label [[LOOP_END1]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] ; CHECK-NEXT: br label [[LOOP:%.*]] @@ -254,13 +385,13 @@ define i64 @same_exit_block_pre_inc_use2() { ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END1]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP3:![0-9]+]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END1]], !llvm.loop [[LOOP11:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ 67, [[LOOP]] ], [ [[INDEX]], [[LOOP_INC]] ], [ [[TMP10]], [[MIDDLE_BLOCK]] ], [ 67, [[MIDDLE_SPLIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ 67, [[LOOP]] ], [ [[INDEX]], [[LOOP_INC]] ], [ [[TMP10]], [[MIDDLE_BLOCK]] ], [ 67, [[LOOP_END]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -297,21 +428,54 @@ define i64 @same_exit_block_pre_inc_use3() { ; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 1 ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) +; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; CHECK: vector.ph: ; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP2]], align 1 +; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load <4 x i8>, ptr [[TMP4]], align 1 +; CHECK-NEXT: [[TMP5:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], [[WIDE_LOAD2]] +; CHECK-NEXT: [[INDEX_NEXT3]] = add nuw i64 [[INDEX1]], 4 +; CHECK-NEXT: [[TMP6:%.*]] = xor <4 x i1> [[TMP5]], splat (i1 true) +; CHECK-NEXT: [[TMP7:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP6]]) +; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 +; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) +; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP7]], [[TMP8]] +; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP12:![0-9]+]] +; CHECK: middle.split: +; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 3 +; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: [[TMP10:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) +; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP10]] +; CHECK-NEXT: br label [[LOOP_END:%.*]] +; CHECK: middle.block: +; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: br label [[LOOP1:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] ; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END:%.*]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP13:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[INDEX_LCSSA:%.*]] = phi i64 [ [[INDEX]], [[LOOP_INC]] ], [ [[INDEX]], [[LOOP]] ] +; CHECK-NEXT: [[INDEX_LCSSA:%.*]] = phi i64 [ [[INDEX]], [[LOOP_INC]] ], [ [[INDEX]], [[LOOP1]] ], [ [[TMP12]], [[MIDDLE_BLOCK]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[INDEX_LCSSA]] ; entry: @@ -349,19 +513,48 @@ define i64 @same_exit_block_pre_inc_use4() { ; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i64], align 8 ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) +; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; CHECK: vector.ph: ; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT2:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i64, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i64>, ptr [[TMP2]], align 1 +; CHECK-NEXT: [[TMP3:%.*]] = icmp ult <4 x i64> [[VEC_IND]], [[WIDE_LOAD]] +; CHECK-NEXT: [[INDEX_NEXT2]] = add nuw i64 [[INDEX1]], 4 +; CHECK-NEXT: [[TMP4:%.*]] = xor <4 x i1> [[TMP3]], splat (i1 true) +; CHECK-NEXT: [[TMP5:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP4]]) +; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[INDEX_NEXT2]], 64 +; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) +; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP5]], [[TMP6]] +; CHECK-NEXT: br i1 [[TMP7]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP14:![0-9]+]] +; CHECK: middle.split: +; CHECK-NEXT: br i1 [[TMP5]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: [[TMP8:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP4]], i1 true) +; CHECK-NEXT: [[TMP9:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP8]] +; CHECK-NEXT: br label [[LOOP_END:%.*]] +; CHECK: middle.block: +; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: br label [[LOOP1:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[P1]], i64 [[INDEX]] ; CHECK-NEXT: [[LD1:%.*]] = load i64, ptr [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i64 [[INDEX]], [[LD1]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END:%.*]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP15:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP9]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -396,21 +589,60 @@ define i64 @same_exit_block_post_inc_use() { ; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 1 ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) +; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; CHECK: vector.ph: ; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP13:%.*]] = add i64 [[OFFSET_IDX]], 1 +; CHECK-NEXT: [[TMP14:%.*]] = add i64 [[OFFSET_IDX]], 2 +; CHECK-NEXT: [[TMP15:%.*]] = add i64 [[OFFSET_IDX]], 3 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP2]], align 1 +; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load <4 x i8>, ptr [[TMP4]], align 1 +; CHECK-NEXT: [[TMP5:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], [[WIDE_LOAD2]] +; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[TMP0]], 1 +; CHECK-NEXT: [[TMP16:%.*]] = add i64 [[TMP13]], 1 +; CHECK-NEXT: [[TMP17:%.*]] = add i64 [[TMP14]], 1 +; CHECK-NEXT: [[TMP18:%.*]] = add i64 [[TMP15]], 1 +; CHECK-NEXT: [[INDEX_NEXT3]] = add nuw i64 [[INDEX1]], 4 +; CHECK-NEXT: [[TMP7:%.*]] = xor <4 x i1> [[TMP5]], splat (i1 true) +; CHECK-NEXT: [[TMP8:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP7]]) +; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 +; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) +; CHECK-NEXT: [[TMP10:%.*]] = or i1 [[TMP8]], [[TMP9]] +; CHECK-NEXT: br i1 [[TMP10]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP16:![0-9]+]] +; CHECK: middle.split: +; CHECK-NEXT: br i1 [[TMP8]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: [[TMP11:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP7]], i1 true) +; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP11]] +; CHECK-NEXT: br label [[LOOP_END:%.*]] +; CHECK: middle.block: +; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: br label [[LOOP1:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] ; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END:%.*]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP17:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ [[INDEX_NEXT]], [[LOOP_INC]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ [[INDEX_NEXT]], [[LOOP_INC]] ], [ [[TMP18]], [[MIDDLE_BLOCK]] ], [ [[TMP12]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -447,21 +679,65 @@ define i64 @same_exit_block_post_inc_use2() { ; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 1 ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) +; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; CHECK: vector.ph: ; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP15:%.*]] = add i64 [[OFFSET_IDX]], 1 +; CHECK-NEXT: [[TMP16:%.*]] = add i64 [[OFFSET_IDX]], 2 +; CHECK-NEXT: [[TMP17:%.*]] = add i64 [[OFFSET_IDX]], 3 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP2]], align 1 +; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load <4 x i8>, ptr [[TMP4]], align 1 +; CHECK-NEXT: [[TMP5:%.*]] = add i64 [[TMP0]], 1 +; CHECK-NEXT: [[TMP18:%.*]] = add i64 [[TMP15]], 1 +; CHECK-NEXT: [[TMP19:%.*]] = add i64 [[TMP16]], 1 +; CHECK-NEXT: [[TMP20:%.*]] = add i64 [[TMP17]], 1 +; CHECK-NEXT: [[TMP21:%.*]] = insertelement <4 x i64> poison, i64 [[TMP5]], i32 0 +; CHECK-NEXT: [[TMP22:%.*]] = insertelement <4 x i64> [[TMP21]], i64 [[TMP18]], i32 1 +; CHECK-NEXT: [[TMP14:%.*]] = insertelement <4 x i64> [[TMP22]], i64 [[TMP19]], i32 2 +; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = insertelement <4 x i64> [[TMP14]], i64 [[TMP20]], i32 3 +; CHECK-NEXT: [[TMP6:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], [[WIDE_LOAD2]] +; CHECK-NEXT: [[INDEX_NEXT3]] = add nuw i64 [[INDEX1]], 4 +; CHECK-NEXT: [[TMP7:%.*]] = xor <4 x i1> [[TMP6]], splat (i1 true) +; CHECK-NEXT: [[TMP8:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP7]]) +; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 +; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) +; CHECK-NEXT: [[TMP10:%.*]] = or i1 [[TMP8]], [[TMP9]] +; CHECK-NEXT: br i1 [[TMP10]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP18:![0-9]+]] +; CHECK: middle.split: +; CHECK-NEXT: [[TMP13:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 3 +; CHECK-NEXT: br i1 [[TMP8]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: [[TMP11:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP7]], i1 true) +; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x i64> [[BROADCAST_SPLAT]], i64 [[TMP11]] +; CHECK-NEXT: br label [[LOOP_END:%.*]] +; CHECK: middle.block: +; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: br label [[LOOP1:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] ; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END:%.*]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END]] ; CHECK: loop.inc: ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP19:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX_NEXT]], [[LOOP]] ], [ [[INDEX]], [[LOOP_INC]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX_NEXT]], [[LOOP1]] ], [ [[INDEX]], [[LOOP_INC]] ], [ [[TMP13]], [[MIDDLE_BLOCK]] ], [ [[TMP12]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -498,24 +774,56 @@ define i64 @diff_exit_block_pre_inc_use1() { ; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 1 ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) +; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; CHECK: vector.ph: ; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP2]], align 1 +; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load <4 x i8>, ptr [[TMP4]], align 1 +; CHECK-NEXT: [[TMP5:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], [[WIDE_LOAD2]] +; CHECK-NEXT: [[INDEX_NEXT3]] = add nuw i64 [[INDEX1]], 4 +; CHECK-NEXT: [[TMP6:%.*]] = xor <4 x i1> [[TMP5]], splat (i1 true) +; CHECK-NEXT: [[TMP7:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP6]]) +; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 +; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) +; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP7]], [[TMP8]] +; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP20:![0-9]+]] +; CHECK: middle.split: +; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: [[TMP10:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) +; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP10]] +; CHECK-NEXT: br label [[LOOP_EARLY_EXIT:%.*]] +; CHECK: middle.block: +; CHECK-NEXT: br i1 true, label [[LOOP_END:%.*]], label [[SCALAR_PH]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: br label [[LOOP1:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] ; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_EARLY_EXIT:%.*]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_EARLY_EXIT]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END:%.*]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP21:![0-9]+]] ; CHECK: loop.early.exit: -; CHECK-NEXT: [[RETVAL1:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ] +; CHECK-NEXT: [[RETVAL1:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL1]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL2:%.*]] = phi i64 [ 67, [[LOOP_INC]] ] +; CHECK-NEXT: [[RETVAL2:%.*]] = phi i64 [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ] ; CHECK-NEXT: ret i64 [[RETVAL2]] ; entry: @@ -577,9 +885,11 @@ define i64 @diff_exit_block_pre_inc_use2() { ; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) ; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP7]], [[TMP8]] -; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]] +; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP22:![0-9]+]] ; CHECK: middle.split: ; CHECK-NEXT: br i1 [[TMP7]], label [[LOOP_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: br label [[LOOP_EARLY_EXIT1:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 3 ; CHECK-NEXT: br i1 true, label [[LOOP_END:%.*]], label [[SCALAR_PH]] @@ -593,13 +903,13 @@ define i64 @diff_exit_block_pre_inc_use2() { ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_EARLY_EXIT]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_EARLY_EXIT1]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP5:![0-9]+]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP23:![0-9]+]] ; CHECK: loop.early.exit: -; CHECK-NEXT: [[RETVAL1:%.*]] = phi i64 [ 67, [[LOOP]] ], [ 67, [[MIDDLE_SPLIT]] ] +; CHECK-NEXT: [[RETVAL1:%.*]] = phi i64 [ 67, [[LOOP]] ], [ 67, [[LOOP_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL1]] ; CHECK: loop.end: ; CHECK-NEXT: [[RETVAL2:%.*]] = phi i64 [ [[INDEX]], [[LOOP_INC]] ], [ [[TMP10]], [[MIDDLE_BLOCK]] ] @@ -643,24 +953,57 @@ define i64 @diff_exit_block_pre_inc_use3() { ; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 1 ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) +; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; CHECK: vector.ph: ; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX2:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT4:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX2]] +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP2]], align 1 +; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD3:%.*]] = load <4 x i8>, ptr [[TMP4]], align 1 +; CHECK-NEXT: [[TMP5:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], [[WIDE_LOAD3]] +; CHECK-NEXT: [[INDEX_NEXT4]] = add nuw i64 [[INDEX2]], 4 +; CHECK-NEXT: [[TMP6:%.*]] = xor <4 x i1> [[TMP5]], splat (i1 true) +; CHECK-NEXT: [[TMP7:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP6]]) +; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT4]], 64 +; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) +; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP7]], [[TMP8]] +; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP24:![0-9]+]] +; CHECK: middle.split: +; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: [[TMP10:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) +; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP10]] +; CHECK-NEXT: br label [[LOOP_EARLY_EXIT:%.*]] +; CHECK: middle.block: +; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 3 +; CHECK-NEXT: br i1 true, label [[LOOP_END:%.*]], label [[SCALAR_PH]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: br label [[LOOP1:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] ; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_EARLY_EXIT:%.*]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_EARLY_EXIT]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END:%.*]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP25:![0-9]+]] ; CHECK: loop.early.exit: -; CHECK-NEXT: [[INDEX_LCSSA:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ] +; CHECK-NEXT: [[INDEX_LCSSA:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[INDEX_LCSSA]] ; CHECK: loop.end: -; CHECK-NEXT: [[INDEX_LCSSA1:%.*]] = phi i64 [ [[INDEX]], [[LOOP_INC]] ] +; CHECK-NEXT: [[INDEX_LCSSA1:%.*]] = phi i64 [ [[INDEX]], [[LOOP_INC]] ], [ [[TMP12]], [[MIDDLE_BLOCK]] ] ; CHECK-NEXT: ret i64 [[INDEX_LCSSA1]] ; entry: @@ -699,24 +1042,63 @@ define i64 @diff_exit_block_post_inc_use1() { ; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 1 ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) +; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; CHECK: vector.ph: ; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[OFFSET_IDX]], 1 +; CHECK-NEXT: [[TMP13:%.*]] = add i64 [[OFFSET_IDX]], 2 +; CHECK-NEXT: [[TMP14:%.*]] = add i64 [[OFFSET_IDX]], 3 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP2]], align 1 +; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load <4 x i8>, ptr [[TMP4]], align 1 +; CHECK-NEXT: [[TMP5:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], [[WIDE_LOAD2]] +; CHECK-NEXT: [[TMP15:%.*]] = add i64 [[TMP0]], 1 +; CHECK-NEXT: [[TMP16:%.*]] = add i64 [[TMP6]], 1 +; CHECK-NEXT: [[TMP17:%.*]] = add i64 [[TMP13]], 1 +; CHECK-NEXT: [[TMP18:%.*]] = add i64 [[TMP14]], 1 +; CHECK-NEXT: [[INDEX_NEXT3]] = add nuw i64 [[INDEX1]], 4 +; CHECK-NEXT: [[TMP7:%.*]] = xor <4 x i1> [[TMP5]], splat (i1 true) +; CHECK-NEXT: [[TMP8:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP7]]) +; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 +; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) +; CHECK-NEXT: [[TMP10:%.*]] = or i1 [[TMP8]], [[TMP9]] +; CHECK-NEXT: br i1 [[TMP10]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP26:![0-9]+]] +; CHECK: middle.split: +; CHECK-NEXT: br i1 [[TMP8]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: [[TMP11:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP7]], i1 true) +; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP11]] +; CHECK-NEXT: br label [[LOOP_EARLY_EXIT:%.*]] +; CHECK: middle.block: +; CHECK-NEXT: br i1 true, label [[LOOP_END:%.*]], label [[SCALAR_PH]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: br label [[LOOP1:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] ; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_EARLY_EXIT:%.*]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_EARLY_EXIT]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END:%.*]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP27:![0-9]+]] ; CHECK: loop.early.exit: -; CHECK-NEXT: [[RETVAL1:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ] +; CHECK-NEXT: [[RETVAL1:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ [[TMP12]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL1]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL2:%.*]] = phi i64 [ [[INDEX_NEXT]], [[LOOP_INC]] ] +; CHECK-NEXT: [[RETVAL2:%.*]] = phi i64 [ [[INDEX_NEXT]], [[LOOP_INC]] ], [ [[TMP18]], [[MIDDLE_BLOCK]] ] ; CHECK-NEXT: ret i64 [[RETVAL2]] ; entry: @@ -757,24 +1139,68 @@ define i64 @diff_exit_block_post_inc_use2() { ; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 1 ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) +; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; CHECK: vector.ph: ; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP13:%.*]] = add i64 [[OFFSET_IDX]], 1 +; CHECK-NEXT: [[TMP14:%.*]] = add i64 [[OFFSET_IDX]], 2 +; CHECK-NEXT: [[TMP15:%.*]] = add i64 [[OFFSET_IDX]], 3 +; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[TMP0]], 1 +; CHECK-NEXT: [[TMP16:%.*]] = add i64 [[TMP13]], 1 +; CHECK-NEXT: [[TMP17:%.*]] = add i64 [[TMP14]], 1 +; CHECK-NEXT: [[TMP18:%.*]] = add i64 [[TMP15]], 1 +; CHECK-NEXT: [[TMP19:%.*]] = insertelement <4 x i64> poison, i64 [[TMP1]], i32 0 +; CHECK-NEXT: [[TMP20:%.*]] = insertelement <4 x i64> [[TMP19]], i64 [[TMP16]], i32 1 +; CHECK-NEXT: [[TMP21:%.*]] = insertelement <4 x i64> [[TMP20]], i64 [[TMP17]], i32 2 +; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = insertelement <4 x i64> [[TMP21]], i64 [[TMP18]], i32 3 +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP3]], align 1 +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[TMP4]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load <4 x i8>, ptr [[TMP5]], align 1 +; CHECK-NEXT: [[TMP6:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], [[WIDE_LOAD2]] +; CHECK-NEXT: [[INDEX_NEXT3]] = add nuw i64 [[INDEX1]], 4 +; CHECK-NEXT: [[TMP7:%.*]] = xor <4 x i1> [[TMP6]], splat (i1 true) +; CHECK-NEXT: [[TMP8:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP7]]) +; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 +; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) +; CHECK-NEXT: [[TMP10:%.*]] = or i1 [[TMP8]], [[TMP9]] +; CHECK-NEXT: br i1 [[TMP10]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP28:![0-9]+]] +; CHECK: middle.split: +; CHECK-NEXT: br i1 [[TMP8]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: [[TMP11:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP7]], i1 true) +; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x i64> [[BROADCAST_SPLAT]], i64 [[TMP11]] +; CHECK-NEXT: br label [[LOOP_EARLY_EXIT:%.*]] +; CHECK: middle.block: +; CHECK-NEXT: [[TMP23:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 3 +; CHECK-NEXT: br i1 true, label [[LOOP_END:%.*]], label [[SCALAR_PH]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: br label [[LOOP1:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] ; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_EARLY_EXIT:%.*]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_EARLY_EXIT]] ; CHECK: loop.inc: ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END:%.*]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP29:![0-9]+]] ; CHECK: loop.early.exit: -; CHECK-NEXT: [[RETVAL1:%.*]] = phi i64 [ [[INDEX_NEXT]], [[LOOP]] ] +; CHECK-NEXT: [[RETVAL1:%.*]] = phi i64 [ [[INDEX_NEXT]], [[LOOP1]] ], [ [[TMP12]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL1]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL2:%.*]] = phi i64 [ [[INDEX]], [[LOOP_INC]] ] +; CHECK-NEXT: [[RETVAL2:%.*]] = phi i64 [ [[INDEX]], [[LOOP_INC]] ], [ [[TMP23]], [[MIDDLE_BLOCK]] ] ; CHECK-NEXT: ret i64 [[RETVAL2]] ; entry: @@ -815,20 +1241,50 @@ define i64 @loop_contains_safe_call() { ; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 1 ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) +; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; CHECK: vector.ph: ; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT2:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds float, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds float, ptr [[TMP1]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x float>, ptr [[TMP2]], align 1 +; CHECK-NEXT: [[TMP3:%.*]] = call fast <4 x float> @llvm.sqrt.v4f32(<4 x float> [[WIDE_LOAD]]) +; CHECK-NEXT: [[TMP4:%.*]] = fcmp fast ult <4 x float> [[TMP3]], splat (float 3.000000e+00) +; CHECK-NEXT: [[INDEX_NEXT2]] = add nuw i64 [[INDEX1]], 4 +; CHECK-NEXT: [[TMP5:%.*]] = xor <4 x i1> [[TMP4]], splat (i1 true) +; CHECK-NEXT: [[TMP6:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP5]]) +; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT2]], 64 +; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) +; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]] +; CHECK-NEXT: br i1 [[TMP8]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP30:![0-9]+]] +; CHECK: middle.split: +; CHECK-NEXT: br i1 [[TMP6]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: [[TMP9:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP5]], i1 true) +; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP9]] +; CHECK-NEXT: br label [[LOOP_END:%.*]] +; CHECK: middle.block: +; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: br label [[LOOP1:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[P1]], i64 [[INDEX]] ; CHECK-NEXT: [[LD1:%.*]] = load float, ptr [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[SQRT:%.*]] = tail call fast float @llvm.sqrt.f32(float [[LD1]]) ; CHECK-NEXT: [[CMP:%.*]] = fcmp fast ult float [[SQRT]], 3.000000e+00 -; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_INC]], label [[LOOP_END:%.*]] +; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_INC]], label [[LOOP_END]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP31:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP10]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -864,20 +1320,50 @@ define i64 @loop_contains_safe_div() { ; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 1 ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) +; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; CHECK: vector.ph: +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT2:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP2]], align 1 +; CHECK-NEXT: [[TMP3:%.*]] = udiv <4 x i32> [[WIDE_LOAD]], splat (i32 20000) +; CHECK-NEXT: [[TMP4:%.*]] = icmp eq <4 x i32> [[TMP3]], splat (i32 1) +; CHECK-NEXT: [[INDEX_NEXT2]] = add nuw i64 [[INDEX1]], 4 +; CHECK-NEXT: [[TMP5:%.*]] = xor <4 x i1> [[TMP4]], splat (i1 true) +; CHECK-NEXT: [[TMP6:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP5]]) +; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT2]], 64 +; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) +; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]] +; CHECK-NEXT: br i1 [[TMP8]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP32:![0-9]+]] +; CHECK: middle.split: +; CHECK-NEXT: br i1 [[TMP6]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: [[TMP9:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP5]], i1 true) +; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP9]] +; CHECK-NEXT: br label [[LOOP_END:%.*]] +; CHECK: middle.block: +; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[P1]], i64 [[INDEX]] ; CHECK-NEXT: [[LD1:%.*]] = load i32, ptr [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[LD1]], 20000 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[DIV]], 1 -; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_INC]], label [[LOOP_END:%.*]] +; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_INC]], label [[LOOP_END]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP33:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP10]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -912,21 +1398,54 @@ define i64 @loop_contains_load_after_early_exit(ptr dereferenceable(1024) align( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[P1:%.*]] = alloca [1024 x i8], align 1 ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) +; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; CHECK: vector.ph: ; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP2]], align 1 +; CHECK-NEXT: [[TMP3:%.*]] = icmp eq <4 x i32> [[WIDE_LOAD]], splat (i32 1) +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i64, ptr [[P2]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i64, ptr [[TMP4]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load <4 x i64>, ptr [[TMP5]], align 8 +; CHECK-NEXT: [[INDEX_NEXT3]] = add nuw i64 [[INDEX1]], 4 +; CHECK-NEXT: [[TMP6:%.*]] = xor <4 x i1> [[TMP3]], splat (i1 true) +; CHECK-NEXT: [[TMP7:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP6]]) +; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 +; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) +; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP7]], [[TMP8]] +; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP34:![0-9]+]] +; CHECK: middle.split: +; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x i64> [[WIDE_LOAD2]], i32 3 +; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: [[TMP10:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) +; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP10]] +; CHECK-NEXT: br label [[LOOP_END:%.*]] +; CHECK: middle.block: +; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: br label [[LOOP1:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[P1]], i64 [[INDEX]] ; CHECK-NEXT: [[LD1:%.*]] = load i32, ptr [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[LD1]], 1 -; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_INC]], label [[LOOP_END:%.*]] +; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_INC]], label [[LOOP_END]] ; CHECK: loop.inc: ; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i64, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i64, ptr [[ARRAYIDX2]], align 8 ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP35:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ [[LD2]], [[LOOP_INC]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ [[LD2]], [[LOOP_INC]] ], [ [[TMP12]], [[MIDDLE_BLOCK]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -961,21 +1480,57 @@ define i64 @same_exit_block_pre_inc_use1_reverse() { ; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 1 ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) +; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; CHECK: vector.ph: ; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT4:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = sub i64 1023, [[INDEX1]] +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i32 0 +; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i32 -3 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP3]], align 1 +; CHECK-NEXT: [[REVERSE:%.*]] = shufflevector <4 x i8> [[WIDE_LOAD]], <4 x i8> poison, <4 x i32> +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[TMP4]], i32 0 +; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8, ptr [[TMP5]], i32 -3 +; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load <4 x i8>, ptr [[TMP6]], align 1 +; CHECK-NEXT: [[REVERSE3:%.*]] = shufflevector <4 x i8> [[WIDE_LOAD2]], <4 x i8> poison, <4 x i32> +; CHECK-NEXT: [[TMP7:%.*]] = icmp eq <4 x i8> [[REVERSE]], [[REVERSE3]] +; CHECK-NEXT: [[INDEX_NEXT4]] = add nuw i64 [[INDEX1]], 4 +; CHECK-NEXT: [[TMP8:%.*]] = xor <4 x i1> [[TMP7]], splat (i1 true) +; CHECK-NEXT: [[TMP9:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP8]]) +; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT4]], 1020 +; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 -4) +; CHECK-NEXT: [[TMP11:%.*]] = or i1 [[TMP9]], [[TMP10]] +; CHECK-NEXT: br i1 [[TMP11]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP36:![0-9]+]] +; CHECK: middle.split: +; CHECK-NEXT: br i1 [[TMP9]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: [[TMP12:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP8]], i1 true) +; CHECK-NEXT: [[TMP13:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP12]] +; CHECK-NEXT: br label [[LOOP_END:%.*]] +; CHECK: middle.block: +; CHECK-NEXT: br i1 false, label [[LOOP_END]], label [[SCALAR_PH]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 3, [[MIDDLE_BLOCK]] ], [ 1023, [[ENTRY:%.*]] ] +; CHECK-NEXT: br label [[LOOP1:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 1023, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] ; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END:%.*]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], -1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDEX_NEXT]], 0 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP_END]], label [[LOOP]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP_END]], label [[LOOP1]], !llvm.loop [[LOOP37:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 1024, [[LOOP_INC]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ 1024, [[LOOP_INC]] ], [ 1024, [[MIDDLE_BLOCK]] ], [ [[TMP13]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -1009,21 +1564,53 @@ define i64 @same_exit_block_pre_inc_use1_deref_ptrs(ptr dereferenceable(1024) %p ; CHECK-LABEL: define i64 @same_exit_block_pre_inc_use1_deref_ptrs( ; CHECK-SAME: ptr dereferenceable(1024) [[P1:%.*]], ptr dereferenceable(1024) [[P2:%.*]]) { ; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; CHECK: vector.ph: ; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP2]], align 1 +; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load <4 x i8>, ptr [[TMP4]], align 1 +; CHECK-NEXT: [[TMP5:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], [[WIDE_LOAD2]] +; CHECK-NEXT: [[INDEX_NEXT3]] = add nuw i64 [[INDEX1]], 4 +; CHECK-NEXT: [[TMP6:%.*]] = xor <4 x i1> [[TMP5]], splat (i1 true) +; CHECK-NEXT: [[TMP7:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP6]]) +; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 +; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) +; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP7]], [[TMP8]] +; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP38:![0-9]+]] +; CHECK: middle.split: +; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK: vector.early.exit: +; CHECK-NEXT: [[TMP10:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) +; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP10]] +; CHECK-NEXT: br label [[LOOP_END:%.*]] +; CHECK: middle.block: +; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: br label [[LOOP1:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] ; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END:%.*]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP39:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -1060,4 +1647,38 @@ attributes #0 = { "vector-function-abi-variant"="_ZGVsNxv_foo(foo_vec)" } ; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META2]], [[META1]]} ; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[META1]], [[META2]]} ; CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[META2]], [[META1]]} +; CHECK: [[LOOP6]] = distinct !{[[LOOP6]], [[META1]], [[META2]]} +; CHECK: [[LOOP7]] = distinct !{[[LOOP7]], [[META2]], [[META1]]} +; CHECK: [[LOOP8]] = distinct !{[[LOOP8]], [[META1]], [[META2]]} +; CHECK: [[LOOP9]] = distinct !{[[LOOP9]], [[META2]], [[META1]]} +; CHECK: [[LOOP10]] = distinct !{[[LOOP10]], [[META1]], [[META2]]} +; CHECK: [[LOOP11]] = distinct !{[[LOOP11]], [[META2]], [[META1]]} +; CHECK: [[LOOP12]] = distinct !{[[LOOP12]], [[META1]], [[META2]]} +; CHECK: [[LOOP13]] = distinct !{[[LOOP13]], [[META2]], [[META1]]} +; CHECK: [[LOOP14]] = distinct !{[[LOOP14]], [[META1]], [[META2]]} +; CHECK: [[LOOP15]] = distinct !{[[LOOP15]], [[META2]], [[META1]]} +; CHECK: [[LOOP16]] = distinct !{[[LOOP16]], [[META1]], [[META2]]} +; CHECK: [[LOOP17]] = distinct !{[[LOOP17]], [[META2]], [[META1]]} +; CHECK: [[LOOP18]] = distinct !{[[LOOP18]], [[META1]], [[META2]]} +; CHECK: [[LOOP19]] = distinct !{[[LOOP19]], [[META2]], [[META1]]} +; CHECK: [[LOOP20]] = distinct !{[[LOOP20]], [[META1]], [[META2]]} +; CHECK: [[LOOP21]] = distinct !{[[LOOP21]], [[META2]], [[META1]]} +; CHECK: [[LOOP22]] = distinct !{[[LOOP22]], [[META1]], [[META2]]} +; CHECK: [[LOOP23]] = distinct !{[[LOOP23]], [[META2]], [[META1]]} +; CHECK: [[LOOP24]] = distinct !{[[LOOP24]], [[META1]], [[META2]]} +; CHECK: [[LOOP25]] = distinct !{[[LOOP25]], [[META2]], [[META1]]} +; CHECK: [[LOOP26]] = distinct !{[[LOOP26]], [[META1]], [[META2]]} +; CHECK: [[LOOP27]] = distinct !{[[LOOP27]], [[META2]], [[META1]]} +; CHECK: [[LOOP28]] = distinct !{[[LOOP28]], [[META1]], [[META2]]} +; CHECK: [[LOOP29]] = distinct !{[[LOOP29]], [[META2]], [[META1]]} +; CHECK: [[LOOP30]] = distinct !{[[LOOP30]], [[META1]], [[META2]]} +; CHECK: [[LOOP31]] = distinct !{[[LOOP31]], [[META2]], [[META1]]} +; CHECK: [[LOOP32]] = distinct !{[[LOOP32]], [[META1]], [[META2]]} +; CHECK: [[LOOP33]] = distinct !{[[LOOP33]], [[META2]], [[META1]]} +; CHECK: [[LOOP34]] = distinct !{[[LOOP34]], [[META1]], [[META2]]} +; CHECK: [[LOOP35]] = distinct !{[[LOOP35]], [[META2]], [[META1]]} +; CHECK: [[LOOP36]] = distinct !{[[LOOP36]], [[META1]], [[META2]]} +; CHECK: [[LOOP37]] = distinct !{[[LOOP37]], [[META2]], [[META1]]} +; CHECK: [[LOOP38]] = distinct !{[[LOOP38]], [[META1]], [[META2]]} +; CHECK: [[LOOP39]] = distinct !{[[LOOP39]], [[META2]], [[META1]]} ;. diff --git a/llvm/test/Transforms/LoopVectorize/uncountable-early-exit-vplan.ll b/llvm/test/Transforms/LoopVectorize/uncountable-early-exit-vplan.ll index b427b43cdb133..0520b3c77b5b6 100644 --- a/llvm/test/Transforms/LoopVectorize/uncountable-early-exit-vplan.ll +++ b/llvm/test/Transforms/LoopVectorize/uncountable-early-exit-vplan.ll @@ -39,7 +39,7 @@ define i64 @multi_exiting_to_different_exits_live_in_exit_values() { ; CHECK-EMPTY: ; CHECK-NEXT: middle.split: ; CHECK-NEXT: EMIT branch-on-cond vp<[[EA_TAKEN]]> -; CHECK-NEXT: Successor(s): ir-bb, middle.block +; CHECK-NEXT: Successor(s): vector.early.exit, middle.block ; CHECK-EMPTY: ; CHECK-NEXT: middle.block: ; CHECK-NEXT: EMIT vp<[[MIDDLE_CMP:%.+]]> = icmp eq ir<128>, vp<[[VTC]]> @@ -58,8 +58,11 @@ define i64 @multi_exiting_to_different_exits_live_in_exit_values() { ; CHECK-NEXT: IR %p2 = phi i64 [ 1, %loop.latch ] (extra operand: ir<1> from middle.block) ; CHECK-NEXT: No successors ; CHECK-EMPTY: +; CHECK-NEXT: vector.early.exit: +; CHECK-NEXT: Successor(s): ir-bb +; CHECK-EMPTY: ; CHECK-NEXT: ir-bb: -; CHECK-NEXT: IR %p1 = phi i64 [ 0, %loop.header ] (extra operand: ir<0> from middle.split) +; CHECK-NEXT: IR %p1 = phi i64 [ 0, %loop.header ] (extra operand: ir<0> from vector.early.exit) ; CHECK-NEXT: No successors ; CHECK-NEXT: } entry: @@ -122,7 +125,7 @@ define i64 @multi_exiting_to_same_exit_live_in_exit_values() { ; CHECK-EMPTY: ; CHECK-NEXT: middle.split: ; CHECK-NEXT: EMIT branch-on-cond vp<[[EA_TAKEN]]> -; CHECK-NEXT: Successor(s): ir-bb, middle.block +; CHECK-NEXT: Successor(s): vector.early.exit, middle.block ; CHECK-EMPTY: ; CHECK-NEXT: middle.block: ; CHECK-NEXT: EMIT vp<[[MIDDLE_CMP:%.+]]> = icmp eq ir<128>, vp<[[VTC]]> @@ -137,8 +140,11 @@ define i64 @multi_exiting_to_same_exit_live_in_exit_values() { ; CHECK-NEXT: IR %iv = phi i64 [ %inc, %loop.latch ], [ 0, %entry ] (extra operand: vp<[[RESUME]]> from scalar.ph) ; CHECK: No successors ; CHECK-EMPTY: +; CHECK-NEXT: vector.early.exit: +; CHECK-NEXT: Successor(s): ir-bb +; CHECK-EMPTY: ; CHECK-NEXT: ir-bb: -; CHECK-NEXT: IR %p = phi i64 [ 0, %loop.header ], [ 1, %loop.latch ] (extra operands: ir<1> from middle.block, ir<0> from middle.split) +; CHECK-NEXT: IR %p = phi i64 [ 0, %loop.header ], [ 1, %loop.latch ] (extra operands: ir<1> from middle.block, ir<0> from vector.early.exit) ; CHECK-NEXT: No successors ; CHECK-NEXT: } @@ -198,7 +204,7 @@ define i64 @multi_exiting_to_same_exit_live_in_exit_values_2() { ; CHECK-EMPTY: ; CHECK-NEXT: middle.split: ; CHECK-NEXT: EMIT branch-on-cond vp<[[EA_TAKEN]]> -; CHECK-NEXT: Successor(s): ir-bb, middle.block +; CHECK-NEXT: Successor(s): vector.early.exit, middle.block ; CHECK-EMPTY: ; CHECK-NEXT: middle.block: ; CHECK-NEXT: EMIT vp<[[MIDDLE_CMP:%.+]]> = icmp eq ir<128>, vp<[[VTC]]> @@ -213,8 +219,11 @@ define i64 @multi_exiting_to_same_exit_live_in_exit_values_2() { ; CHECK-NEXT: IR %iv = phi i64 [ %inc, %loop.latch ], [ 0, %entry ] (extra operand: vp<[[RESUME]]> from scalar.ph) ; CHECK: No successors ; CHECK-EMPTY: +; CHECK-NEXT: vector.early.exit: +; CHECK-NEXT: Successor(s): ir-bb +; CHECK-EMPTY: ; CHECK-NEXT: ir-bb: -; CHECK-NEXT: IR %p = phi i64 [ 0, %loop.header ], [ 1, %loop.latch ] (extra operands: ir<1> from middle.block, ir<0> from middle.split) +; CHECK-NEXT: IR %p = phi i64 [ 0, %loop.header ], [ 1, %loop.latch ] (extra operands: ir<1> from middle.block, ir<0> from vector.early.exit) ; CHECK-NEXT: No successors ; CHECK-NEXT: } From 9432e60ca3a836eaec70e41188b40d4e4e313430 Mon Sep 17 00:00:00 2001 From: David Sherwood Date: Wed, 29 Jan 2025 11:19:12 +0000 Subject: [PATCH 2/5] Attempt to fix Windows build issue with getExitBlocks --- llvm/lib/Transforms/Vectorize/VPlan.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp index e0aa59d819650..a2be8b039f2e4 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp @@ -958,7 +958,8 @@ void VPlan::prepareToExecute(Value *TripCountV, Value *VectorTripCountV, bool VPlan::isExitBlock(VPBlockBase *VPBB) { if (isa(VPBB) && VPBB->getNumSuccessors() == 0) { - assert(is_contained(getExitBlocks(), VPBB) && + [[maybe_unused]] auto ExitBlocks = getExitBlocks(); + assert(is_contained(ExitBlocks, VPBB) && "Expected to find VPlan block in list of exit blocks!"); return true; } From cff198abc5618f1e3b5e9f840d58edcea69f9b1c Mon Sep 17 00:00:00 2001 From: David Sherwood Date: Wed, 29 Jan 2025 11:19:28 +0000 Subject: [PATCH 3/5] Remove assert in isExitBlock --- llvm/lib/Transforms/Vectorize/VPlan.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp index a2be8b039f2e4..3c381307c237c 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp @@ -957,14 +957,7 @@ void VPlan::prepareToExecute(Value *TripCountV, Value *VectorTripCountV, } bool VPlan::isExitBlock(VPBlockBase *VPBB) { - if (isa(VPBB) && VPBB->getNumSuccessors() == 0) { - [[maybe_unused]] auto ExitBlocks = getExitBlocks(); - assert(is_contained(ExitBlocks, VPBB) && - "Expected to find VPlan block in list of exit blocks!"); - return true; - } - - return false; + return isa(VPBB) && VPBB->getNumSuccessors() == 0; } /// Generate the code inside the preheader and body of the vectorized loop. From 553bad4377f639866e4a0ce7ca58071fa5d8e69b Mon Sep 17 00:00:00 2001 From: David Sherwood Date: Wed, 29 Jan 2025 11:19:52 +0000 Subject: [PATCH 4/5] Address review comments + regen CHECK lines --- .../lib/Transforms/Vectorize/VPlanRecipes.cpp | 4 +- .../Transforms/Vectorize/VPlanTransforms.cpp | 1 - .../Transforms/Vectorize/VPlanVerifier.cpp | 10 +- .../AArch64/simple_early_exit.ll | 88 ++-- .../LoopVectorize/single_early_exit.ll | 24 +- .../single_early_exit_live_outs.ll | 474 +++++++++--------- 6 files changed, 299 insertions(+), 302 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index 31dc59762333c..b8c38cdd7ebcd 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -700,8 +700,8 @@ Value *VPInstruction::generate(VPTransformState &State) { case VPInstruction::ExtractFirstActive: { Value *Vec = State.get(getOperand(0)); Value *Mask = State.get(getOperand(1)); - Value *Ctz = - Builder.CreateCountTrailingZeroElems(Builder.getInt64Ty(), Mask); + Value *Ctz = Builder.CreateCountTrailingZeroElems( + Builder.getInt64Ty(), Mask, true, "first.active.lane"); return Builder.CreateExtractElement(Vec, Ctz); } default: diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp index 367bb929c1898..5b2ef68fff056 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp @@ -2128,7 +2128,6 @@ void VPlanTransforms::handleUncountableEarlyExit( ExitIRI->addOperand(IncomingFromLatch); ExitIRI->extractLastLaneOfOperand(MiddleBuilder); } - // Add the incoming value from the early exit. if (!IncomingFromEarlyExit->isLiveIn()) IncomingFromEarlyExit = diff --git a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp index e703a2b50934b..96156de444f88 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp @@ -209,7 +209,9 @@ bool VPlanVerifier::verifyVPBasicBlock(const VPBasicBlock *VPBB) { auto *UI = cast(U); // TODO: check dominance of incoming values for phis properly. if (!UI || - isa(UI)) + isa(UI) || + (isa(UI) && + isa(cast(UI)->getInstruction()))) continue; // If the user is in the same block, check it comes after R in the @@ -222,11 +224,7 @@ bool VPlanVerifier::verifyVPBasicBlock(const VPBasicBlock *VPBB) { continue; } - // Now that we support vectorising loops with uncountable early exits - // we can end up in situations where VPBB does not dominate the exit - // block. Only do the check if the user is not in a VPIRBasicBlock. - if (!isa(UI->getParent()) && - !VPDT.dominates(VPBB, UI->getParent())) { + if (!VPDT.dominates(VPBB, UI->getParent())) { errs() << "Use before def!\n"; return false; } diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/simple_early_exit.ll b/llvm/test/Transforms/LoopVectorize/AArch64/simple_early_exit.ll index 9c23f5ba3d12c..6eb3ee6d5225b 100644 --- a/llvm/test/Transforms/LoopVectorize/AArch64/simple_early_exit.ll +++ b/llvm/test/Transforms/LoopVectorize/AArch64/simple_early_exit.ll @@ -24,17 +24,17 @@ define i64 @same_exit_block_pre_inc_use1() #1 { ; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 64, [[N_MOD_VF]] ; CHECK-NEXT: [[TMP4:%.*]] = call i64 @llvm.vscale.i64() ; CHECK-NEXT: [[TMP5:%.*]] = mul i64 [[TMP4]], 16 -; CHECK-NEXT: [[INDEX_NEXT1:%.*]] = add i64 3, [[N_VEC]] +; CHECK-NEXT: [[TMP6:%.*]] = add i64 3, [[N_VEC]] ; CHECK-NEXT: [[TMP7:%.*]] = call @llvm.stepvector.nxv16i64() ; CHECK-NEXT: [[TMP8:%.*]] = mul [[TMP7]], splat (i64 1) ; CHECK-NEXT: [[INDUCTION:%.*]] = add splat (i64 3), [[TMP8]] ; CHECK-NEXT: [[TMP9:%.*]] = mul i64 1, [[TMP5]] ; CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, i64 [[TMP9]], i64 0 ; CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer -; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] ; CHECK: vector.body: -; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[VEC_IND:%.*]] = phi [ [[INDUCTION]], [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi [ [[INDUCTION]], [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] ; CHECK-NEXT: [[TMP10:%.*]] = add i64 [[OFFSET_IDX]], 0 ; CHECK-NEXT: [[TMP11:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP10]] @@ -50,33 +50,33 @@ define i64 @same_exit_block_pre_inc_use1() #1 { ; CHECK-NEXT: [[TMP18:%.*]] = icmp eq i64 [[INDEX_NEXT3]], [[N_VEC]] ; CHECK-NEXT: [[VEC_IND_NEXT]] = add [[VEC_IND]], [[DOTSPLAT]] ; CHECK-NEXT: [[TMP19:%.*]] = or i1 [[TMP17]], [[TMP18]] -; CHECK-NEXT: br i1 [[TMP19]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP0:![0-9]+]] +; CHECK-NEXT: br i1 [[TMP19]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] ; CHECK: middle.split: -; CHECK-NEXT: br i1 [[TMP17]], label [[VECTOR_EARLY_EXIT:%.*]], label [[LOOP_INC:%.*]] +; CHECK-NEXT: br i1 [[TMP17]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: [[TMP20:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.nxv16i1( [[TMP16]], i1 true) -; CHECK-NEXT: [[TMP21:%.*]] = extractelement [[VEC_IND]], i64 [[TMP20]] +; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.nxv16i1( [[TMP16]], i1 true) +; CHECK-NEXT: [[TMP20:%.*]] = extractelement [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 64, [[N_VEC]] ; CHECK-NEXT: br i1 [[CMP_N]], label [[LOOP_END]], label [[SCALAR_PH]] ; CHECK: scalar.ph: -; CHECK-NEXT: [[INDEX2:%.*]] = phi i64 [ [[INDEX_NEXT1]], [[LOOP_INC]] ], [ 3, [[ENTRY:%.*]] ] -; CHECK-NEXT: br label [[LOOP1:%.*]] +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[TMP6]], [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] +; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC1:%.*]] ], [ [[INDEX2]], [[SCALAR_PH]] ] +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] ; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC1]], label [[LOOP_END]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP3:![0-9]+]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP3:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ 67, [[LOOP_INC1]] ], [ 67, [[LOOP_INC]] ], [ [[TMP21]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP20]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -117,10 +117,10 @@ define i64 @same_exit_block_pre_inc_use4() { ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) ; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; CHECK: vector.ph: -; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] ; CHECK: vector.body: -; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT2:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT2:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i64, ptr [[P1]], i64 [[TMP0]] @@ -133,18 +133,18 @@ define i64 @same_exit_block_pre_inc_use4() { ; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[INDEX_NEXT2]], 64 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2) ; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP5]], [[TMP6]] -; CHECK-NEXT: br i1 [[TMP7]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP4:![0-9]+]] +; CHECK-NEXT: br i1 [[TMP7]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]] ; CHECK: middle.split: ; CHECK-NEXT: br i1 [[TMP5]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: [[TMP8:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v2i1(<2 x i1> [[TMP4]], i1 true) -; CHECK-NEXT: [[TMP9:%.*]] = extractelement <2 x i64> [[VEC_IND]], i64 [[TMP8]] +; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v2i1(<2 x i1> [[TMP4]], i1 true) +; CHECK-NEXT: [[TMP8:%.*]] = extractelement <2 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] -; CHECK-NEXT: br label [[LOOP1:%.*]] +; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[P1]], i64 [[INDEX]] @@ -154,9 +154,9 @@ define i64 @same_exit_block_pre_inc_use4() { ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP5:![0-9]+]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP5:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP9]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP8]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -215,8 +215,8 @@ define i64 @loop_contains_safe_call() #1 { ; CHECK: middle.split: ; CHECK-NEXT: br i1 [[TMP6]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: [[TMP9:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP5]], i1 true) -; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP9]] +; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP5]], i1 true) +; CHECK-NEXT: [[TMP9:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] @@ -235,7 +235,7 @@ define i64 @loop_contains_safe_call() #1 { ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP7:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP10]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP9]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -274,10 +274,10 @@ define i64 @loop_contains_safe_div() #1 { ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) ; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; CHECK: vector.ph: -; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] ; CHECK: vector.body: -; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT2:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT2:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[P1]], i64 [[TMP0]] @@ -291,18 +291,18 @@ define i64 @loop_contains_safe_div() #1 { ; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT2]], 64 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2) ; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]] -; CHECK-NEXT: br i1 [[TMP8]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP8:![0-9]+]] +; CHECK-NEXT: br i1 [[TMP8]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]] ; CHECK: middle.split: ; CHECK-NEXT: br i1 [[TMP6]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: [[TMP9:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v2i1(<2 x i1> [[TMP5]], i1 true) -; CHECK-NEXT: [[TMP10:%.*]] = extractelement <2 x i64> [[VEC_IND]], i64 [[TMP9]] +; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v2i1(<2 x i1> [[TMP5]], i1 true) +; CHECK-NEXT: [[TMP9:%.*]] = extractelement <2 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] -; CHECK-NEXT: br label [[LOOP1:%.*]] +; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[P1]], i64 [[INDEX]] @@ -313,9 +313,9 @@ define i64 @loop_contains_safe_div() #1 { ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP9:![0-9]+]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP9:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP10]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP9]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -356,10 +356,10 @@ define i64 @loop_contains_load_after_early_exit(ptr dereferenceable(1024) align( ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) ; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; CHECK: vector.ph: -; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] ; CHECK: vector.body: -; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[P1]], i64 [[TMP0]] @@ -375,19 +375,19 @@ define i64 @loop_contains_load_after_early_exit(ptr dereferenceable(1024) align( ; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) ; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP7]], [[TMP8]] -; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP10:![0-9]+]] +; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]] ; CHECK: middle.split: ; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[WIDE_LOAD2]], i32 3 ; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: [[TMP11:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) -; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP11]] +; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) +; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] -; CHECK-NEXT: br label [[LOOP1:%.*]] +; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[P1]], i64 [[INDEX]] @@ -399,9 +399,9 @@ define i64 @loop_contains_load_after_early_exit(ptr dereferenceable(1024) align( ; CHECK-NEXT: [[LD2:%.*]] = load i64, ptr [[ARRAYIDX2]], align 8 ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP11:![0-9]+]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP11:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ [[LD2]], [[LOOP_INC]] ], [ [[TMP10]], [[MIDDLE_BLOCK]] ], [ [[TMP12]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ [[LD2]], [[LOOP_INC]] ], [ [[TMP10]], [[MIDDLE_BLOCK]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: diff --git a/llvm/test/Transforms/LoopVectorize/single_early_exit.ll b/llvm/test/Transforms/LoopVectorize/single_early_exit.ll index f447f623b3c99..4bcf8e0180d63 100644 --- a/llvm/test/Transforms/LoopVectorize/single_early_exit.ll +++ b/llvm/test/Transforms/LoopVectorize/single_early_exit.ll @@ -32,11 +32,11 @@ define i64 @same_exit_block_phi_of_consts() { ; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP7]], [[TMP8]] ; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] ; CHECK: middle.split: -; CHECK-NEXT: br i1 [[TMP7]], label [[LOOP_END:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: br label [[LOOP_END1:%.*]] +; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: -; CHECK-NEXT: br i1 true, label [[LOOP_END1]], label [[SCALAR_PH]] +; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] ; CHECK-NEXT: br label [[LOOP:%.*]] @@ -47,13 +47,13 @@ define i64 @same_exit_block_phi_of_consts() { ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END1]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END1]], !llvm.loop [[LOOP3:![0-9]+]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP3:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ 0, [[LOOP]] ], [ 1, [[LOOP_INC]] ], [ 1, [[MIDDLE_BLOCK]] ], [ 0, [[LOOP_END]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ 0, [[LOOP]] ], [ 1, [[LOOP_INC]] ], [ 1, [[MIDDLE_BLOCK]] ], [ 0, [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -111,9 +111,9 @@ define i64 @diff_exit_block_phi_of_consts() { ; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP7]], [[TMP8]] ; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]] ; CHECK: middle.split: -; CHECK-NEXT: br i1 [[TMP7]], label [[LOOP_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: br label [[LOOP_EARLY_EXIT1:%.*]] +; CHECK-NEXT: br label [[LOOP_EARLY_EXIT:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END:%.*]], label [[SCALAR_PH]] ; CHECK: scalar.ph: @@ -126,7 +126,7 @@ define i64 @diff_exit_block_phi_of_consts() { ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_EARLY_EXIT1]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_EARLY_EXIT]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 @@ -297,9 +297,9 @@ define i32 @diff_blocks_invariant_early_exit_cond(ptr %s) { ; CHECK-NEXT: [[TMP3:%.*]] = or i1 [[TMP1]], [[TMP2]] ; CHECK-NEXT: br i1 [[TMP3]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]] ; CHECK: middle.split: -; CHECK-NEXT: br i1 [[TMP1]], label [[EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK-NEXT: br i1 [[TMP1]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: br label [[EARLY_EXIT1:%.*]] +; CHECK-NEXT: br label [[EARLY_EXIT:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]] ; CHECK: scalar.ph: @@ -307,7 +307,7 @@ define i32 @diff_blocks_invariant_early_exit_cond(ptr %s) { ; CHECK-NEXT: br label [[FOR_BODY:%.*]] ; CHECK: for.body: ; CHECK-NEXT: [[IND:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IND_NEXT:%.*]], [[FOR_INC:%.*]] ] -; CHECK-NEXT: br i1 [[COND]], label [[FOR_INC]], label [[EARLY_EXIT1]] +; CHECK-NEXT: br i1 [[COND]], label [[FOR_INC]], label [[EARLY_EXIT]] ; CHECK: for.inc: ; CHECK-NEXT: [[IND_NEXT]] = add nsw i32 [[IND]], 1 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[IND_NEXT]], 266 diff --git a/llvm/test/Transforms/LoopVectorize/single_early_exit_live_outs.ll b/llvm/test/Transforms/LoopVectorize/single_early_exit_live_outs.ll index 94bacf14049ba..8aa5d0b279a9c 100644 --- a/llvm/test/Transforms/LoopVectorize/single_early_exit_live_outs.ll +++ b/llvm/test/Transforms/LoopVectorize/single_early_exit_live_outs.ll @@ -35,8 +35,8 @@ define i64 @same_exit_block_pre_inc_use1() { ; CHECK: middle.split: ; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: [[TMP10:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) -; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP10]] +; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) +; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] @@ -56,7 +56,7 @@ define i64 @same_exit_block_pre_inc_use1() { ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP3:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP10]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -96,10 +96,10 @@ define i64 @same_exit_block_pre_inc1_use_inv_cond(i1 %cond) { ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) ; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; CHECK: vector.ph: -; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] ; CHECK: vector.body: -; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] @@ -116,18 +116,18 @@ define i64 @same_exit_block_pre_inc1_use_inv_cond(i1 %cond) { ; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) ; CHECK-NEXT: [[TMP10:%.*]] = or i1 [[TMP8]], [[TMP9]] -; CHECK-NEXT: br i1 [[TMP10]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP4:![0-9]+]] +; CHECK-NEXT: br i1 [[TMP10]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]] ; CHECK: middle.split: ; CHECK-NEXT: br i1 [[TMP8]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: [[TMP11:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP7]], i1 true) -; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP11]] +; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP7]], i1 true) +; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] -; CHECK-NEXT: br label [[LOOP1:%.*]] +; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] @@ -140,9 +140,9 @@ define i64 @same_exit_block_pre_inc1_use_inv_cond(i1 %cond) { ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP5:![0-9]+]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP5:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP12]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -182,10 +182,10 @@ define i64 @same_exit_block_pre_inc_use1_gep_two_indices() { ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) ; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; CHECK: vector.ph: -; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] ; CHECK: vector.body: -; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1024 x i8], ptr [[P1]], i64 0, i64 [[TMP0]] @@ -201,18 +201,18 @@ define i64 @same_exit_block_pre_inc_use1_gep_two_indices() { ; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) ; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP7]], [[TMP8]] -; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP6:![0-9]+]] +; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]] ; CHECK: middle.split: ; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: [[TMP10:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) -; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP10]] +; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) +; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] -; CHECK-NEXT: br label [[LOOP1:%.*]] +; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [1024 x i8], ptr [[P1]], i64 0, i64 [[INDEX]] @@ -224,9 +224,9 @@ define i64 @same_exit_block_pre_inc_use1_gep_two_indices() { ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP7:![0-9]+]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP7:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP10]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -288,8 +288,8 @@ define i64 @same_exit_block_pre_inc_use1_alloca_diff_type() { ; CHECK: middle.split: ; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: [[TMP10:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) -; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP10]] +; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) +; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] @@ -309,7 +309,7 @@ define i64 @same_exit_block_pre_inc_use1_alloca_diff_type() { ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP9:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP10]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -370,11 +370,11 @@ define i64 @same_exit_block_pre_inc_use2() { ; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]] ; CHECK: middle.split: ; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 3 -; CHECK-NEXT: br i1 [[TMP7]], label [[LOOP_END:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: br label [[LOOP_END1:%.*]] +; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: -; CHECK-NEXT: br i1 true, label [[LOOP_END1]], label [[SCALAR_PH]] +; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] ; CHECK-NEXT: br label [[LOOP:%.*]] @@ -385,13 +385,13 @@ define i64 @same_exit_block_pre_inc_use2() { ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END1]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END1]], !llvm.loop [[LOOP11:![0-9]+]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP11:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ 67, [[LOOP]] ], [ [[INDEX]], [[LOOP_INC]] ], [ [[TMP10]], [[MIDDLE_BLOCK]] ], [ 67, [[LOOP_END]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ 67, [[LOOP]] ], [ [[INDEX]], [[LOOP_INC]] ], [ [[TMP10]], [[MIDDLE_BLOCK]] ], [ 67, [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -430,10 +430,10 @@ define i64 @same_exit_block_pre_inc_use3() { ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) ; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; CHECK: vector.ph: -; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] ; CHECK: vector.body: -; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] @@ -449,19 +449,19 @@ define i64 @same_exit_block_pre_inc_use3() { ; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) ; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP7]], [[TMP8]] -; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP12:![0-9]+]] +; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP12:![0-9]+]] ; CHECK: middle.split: -; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 3 +; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 3 ; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: [[TMP10:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) -; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP10]] +; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) +; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] -; CHECK-NEXT: br label [[LOOP1:%.*]] +; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] @@ -473,9 +473,9 @@ define i64 @same_exit_block_pre_inc_use3() { ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP13:![0-9]+]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP13:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[INDEX_LCSSA:%.*]] = phi i64 [ [[INDEX]], [[LOOP_INC]] ], [ [[INDEX]], [[LOOP1]] ], [ [[TMP12]], [[MIDDLE_BLOCK]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[INDEX_LCSSA:%.*]] = phi i64 [ [[INDEX]], [[LOOP_INC]] ], [ [[INDEX]], [[LOOP]] ], [ [[TMP10]], [[MIDDLE_BLOCK]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[INDEX_LCSSA]] ; entry: @@ -515,10 +515,10 @@ define i64 @same_exit_block_pre_inc_use4() { ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) ; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; CHECK: vector.ph: -; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] ; CHECK: vector.body: -; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT2:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT2:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i64, ptr [[P1]], i64 [[TMP0]] @@ -531,18 +531,18 @@ define i64 @same_exit_block_pre_inc_use4() { ; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[INDEX_NEXT2]], 64 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) ; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP5]], [[TMP6]] -; CHECK-NEXT: br i1 [[TMP7]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP14:![0-9]+]] +; CHECK-NEXT: br i1 [[TMP7]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP14:![0-9]+]] ; CHECK: middle.split: ; CHECK-NEXT: br i1 [[TMP5]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: [[TMP8:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP4]], i1 true) -; CHECK-NEXT: [[TMP9:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP8]] +; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP4]], i1 true) +; CHECK-NEXT: [[TMP8:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] -; CHECK-NEXT: br label [[LOOP1:%.*]] +; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[P1]], i64 [[INDEX]] @@ -552,9 +552,9 @@ define i64 @same_exit_block_pre_inc_use4() { ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP15:![0-9]+]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP15:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP9]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP8]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -591,44 +591,44 @@ define i64 @same_exit_block_post_inc_use() { ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) ; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; CHECK: vector.ph: -; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] ; CHECK: vector.body: -; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 -; CHECK-NEXT: [[TMP13:%.*]] = add i64 [[OFFSET_IDX]], 1 -; CHECK-NEXT: [[TMP14:%.*]] = add i64 [[OFFSET_IDX]], 2 -; CHECK-NEXT: [[TMP15:%.*]] = add i64 [[OFFSET_IDX]], 3 -; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] -; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i32 0 -; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP2]], align 1 -; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[TMP0]] -; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i32 0 -; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load <4 x i8>, ptr [[TMP4]], align 1 -; CHECK-NEXT: [[TMP5:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], [[WIDE_LOAD2]] -; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[TMP0]], 1 -; CHECK-NEXT: [[TMP16:%.*]] = add i64 [[TMP13]], 1 -; CHECK-NEXT: [[TMP17:%.*]] = add i64 [[TMP14]], 1 -; CHECK-NEXT: [[TMP18:%.*]] = add i64 [[TMP15]], 1 +; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[OFFSET_IDX]], 1 +; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[OFFSET_IDX]], 2 +; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[OFFSET_IDX]], 3 +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[TMP4]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP5]], align 1 +; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i8, ptr [[TMP6]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load <4 x i8>, ptr [[TMP7]], align 1 +; CHECK-NEXT: [[TMP8:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], [[WIDE_LOAD2]] +; CHECK-NEXT: [[TMP9:%.*]] = add i64 [[TMP0]], 1 +; CHECK-NEXT: [[TMP10:%.*]] = add i64 [[TMP1]], 1 +; CHECK-NEXT: [[TMP11:%.*]] = add i64 [[TMP2]], 1 +; CHECK-NEXT: [[TMP12:%.*]] = add i64 [[TMP3]], 1 ; CHECK-NEXT: [[INDEX_NEXT3]] = add nuw i64 [[INDEX1]], 4 -; CHECK-NEXT: [[TMP7:%.*]] = xor <4 x i1> [[TMP5]], splat (i1 true) -; CHECK-NEXT: [[TMP8:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP7]]) -; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 +; CHECK-NEXT: [[TMP13:%.*]] = xor <4 x i1> [[TMP8]], splat (i1 true) +; CHECK-NEXT: [[TMP14:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP13]]) +; CHECK-NEXT: [[TMP15:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) -; CHECK-NEXT: [[TMP10:%.*]] = or i1 [[TMP8]], [[TMP9]] -; CHECK-NEXT: br i1 [[TMP10]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP16:![0-9]+]] +; CHECK-NEXT: [[TMP16:%.*]] = or i1 [[TMP14]], [[TMP15]] +; CHECK-NEXT: br i1 [[TMP16]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP16:![0-9]+]] ; CHECK: middle.split: -; CHECK-NEXT: br i1 [[TMP8]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK-NEXT: br i1 [[TMP14]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: [[TMP11:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP7]], i1 true) -; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP11]] +; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP13]], i1 true) +; CHECK-NEXT: [[TMP17:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] -; CHECK-NEXT: br label [[LOOP1:%.*]] +; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] @@ -640,9 +640,9 @@ define i64 @same_exit_block_post_inc_use() { ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP17:![0-9]+]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP17:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ [[INDEX_NEXT]], [[LOOP_INC]] ], [ [[TMP18]], [[MIDDLE_BLOCK]] ], [ [[TMP12]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ [[INDEX_NEXT]], [[LOOP_INC]] ], [ [[TMP12]], [[MIDDLE_BLOCK]] ], [ [[TMP17]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -681,49 +681,49 @@ define i64 @same_exit_block_post_inc_use2() { ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) ; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; CHECK: vector.ph: -; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] ; CHECK: vector.body: -; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 -; CHECK-NEXT: [[TMP15:%.*]] = add i64 [[OFFSET_IDX]], 1 -; CHECK-NEXT: [[TMP16:%.*]] = add i64 [[OFFSET_IDX]], 2 -; CHECK-NEXT: [[TMP17:%.*]] = add i64 [[OFFSET_IDX]], 3 -; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] -; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i32 0 -; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP2]], align 1 -; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[TMP0]] -; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i32 0 -; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load <4 x i8>, ptr [[TMP4]], align 1 -; CHECK-NEXT: [[TMP5:%.*]] = add i64 [[TMP0]], 1 -; CHECK-NEXT: [[TMP18:%.*]] = add i64 [[TMP15]], 1 -; CHECK-NEXT: [[TMP19:%.*]] = add i64 [[TMP16]], 1 -; CHECK-NEXT: [[TMP20:%.*]] = add i64 [[TMP17]], 1 -; CHECK-NEXT: [[TMP21:%.*]] = insertelement <4 x i64> poison, i64 [[TMP5]], i32 0 -; CHECK-NEXT: [[TMP22:%.*]] = insertelement <4 x i64> [[TMP21]], i64 [[TMP18]], i32 1 -; CHECK-NEXT: [[TMP14:%.*]] = insertelement <4 x i64> [[TMP22]], i64 [[TMP19]], i32 2 -; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = insertelement <4 x i64> [[TMP14]], i64 [[TMP20]], i32 3 -; CHECK-NEXT: [[TMP6:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], [[WIDE_LOAD2]] +; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[OFFSET_IDX]], 1 +; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[OFFSET_IDX]], 2 +; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[OFFSET_IDX]], 3 +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[TMP4]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP5]], align 1 +; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i8, ptr [[TMP6]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load <4 x i8>, ptr [[TMP7]], align 1 +; CHECK-NEXT: [[TMP8:%.*]] = add i64 [[TMP0]], 1 +; CHECK-NEXT: [[TMP9:%.*]] = add i64 [[TMP1]], 1 +; CHECK-NEXT: [[TMP10:%.*]] = add i64 [[TMP2]], 1 +; CHECK-NEXT: [[TMP11:%.*]] = add i64 [[TMP3]], 1 +; CHECK-NEXT: [[TMP12:%.*]] = insertelement <4 x i64> poison, i64 [[TMP8]], i32 0 +; CHECK-NEXT: [[TMP13:%.*]] = insertelement <4 x i64> [[TMP12]], i64 [[TMP9]], i32 1 +; CHECK-NEXT: [[TMP14:%.*]] = insertelement <4 x i64> [[TMP13]], i64 [[TMP10]], i32 2 +; CHECK-NEXT: [[TMP15:%.*]] = insertelement <4 x i64> [[TMP14]], i64 [[TMP11]], i32 3 +; CHECK-NEXT: [[TMP16:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], [[WIDE_LOAD2]] ; CHECK-NEXT: [[INDEX_NEXT3]] = add nuw i64 [[INDEX1]], 4 -; CHECK-NEXT: [[TMP7:%.*]] = xor <4 x i1> [[TMP6]], splat (i1 true) -; CHECK-NEXT: [[TMP8:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP7]]) -; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 +; CHECK-NEXT: [[TMP17:%.*]] = xor <4 x i1> [[TMP16]], splat (i1 true) +; CHECK-NEXT: [[TMP18:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP17]]) +; CHECK-NEXT: [[TMP19:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) -; CHECK-NEXT: [[TMP10:%.*]] = or i1 [[TMP8]], [[TMP9]] -; CHECK-NEXT: br i1 [[TMP10]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP18:![0-9]+]] +; CHECK-NEXT: [[TMP20:%.*]] = or i1 [[TMP18]], [[TMP19]] +; CHECK-NEXT: br i1 [[TMP20]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP18:![0-9]+]] ; CHECK: middle.split: -; CHECK-NEXT: [[TMP13:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 3 -; CHECK-NEXT: br i1 [[TMP8]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK-NEXT: [[TMP21:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 3 +; CHECK-NEXT: br i1 [[TMP18]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: [[TMP11:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP7]], i1 true) -; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x i64> [[BROADCAST_SPLAT]], i64 [[TMP11]] +; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP17]], i1 true) +; CHECK-NEXT: [[TMP22:%.*]] = extractelement <4 x i64> [[TMP15]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] -; CHECK-NEXT: br label [[LOOP1:%.*]] +; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] @@ -735,9 +735,9 @@ define i64 @same_exit_block_post_inc_use2() { ; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END]] ; CHECK: loop.inc: ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP19:![0-9]+]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP19:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX_NEXT]], [[LOOP1]] ], [ [[INDEX]], [[LOOP_INC]] ], [ [[TMP13]], [[MIDDLE_BLOCK]] ], [ [[TMP12]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX_NEXT]], [[LOOP]] ], [ [[INDEX]], [[LOOP_INC]] ], [ [[TMP21]], [[MIDDLE_BLOCK]] ], [ [[TMP22]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -776,10 +776,10 @@ define i64 @diff_exit_block_pre_inc_use1() { ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) ; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; CHECK: vector.ph: -; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] ; CHECK: vector.body: -; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] @@ -795,18 +795,18 @@ define i64 @diff_exit_block_pre_inc_use1() { ; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) ; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP7]], [[TMP8]] -; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP20:![0-9]+]] +; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP20:![0-9]+]] ; CHECK: middle.split: ; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: [[TMP10:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) -; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP10]] +; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) +; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_EARLY_EXIT:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END:%.*]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] -; CHECK-NEXT: br label [[LOOP1:%.*]] +; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] @@ -818,9 +818,9 @@ define i64 @diff_exit_block_pre_inc_use1() { ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP21:![0-9]+]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP21:![0-9]+]] ; CHECK: loop.early.exit: -; CHECK-NEXT: [[RETVAL1:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL1:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ [[TMP10]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL1]] ; CHECK: loop.end: ; CHECK-NEXT: [[RETVAL2:%.*]] = phi i64 [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ] @@ -887,9 +887,9 @@ define i64 @diff_exit_block_pre_inc_use2() { ; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP7]], [[TMP8]] ; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP22:![0-9]+]] ; CHECK: middle.split: -; CHECK-NEXT: br i1 [[TMP7]], label [[LOOP_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: br label [[LOOP_EARLY_EXIT1:%.*]] +; CHECK-NEXT: br label [[LOOP_EARLY_EXIT:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 3 ; CHECK-NEXT: br i1 true, label [[LOOP_END:%.*]], label [[SCALAR_PH]] @@ -903,13 +903,13 @@ define i64 @diff_exit_block_pre_inc_use2() { ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] -; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_EARLY_EXIT1]] +; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_EARLY_EXIT]] ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP23:![0-9]+]] ; CHECK: loop.early.exit: -; CHECK-NEXT: [[RETVAL1:%.*]] = phi i64 [ 67, [[LOOP]] ], [ 67, [[LOOP_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL1:%.*]] = phi i64 [ 67, [[LOOP]] ], [ 67, [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL1]] ; CHECK: loop.end: ; CHECK-NEXT: [[RETVAL2:%.*]] = phi i64 [ [[INDEX]], [[LOOP_INC]] ], [ [[TMP10]], [[MIDDLE_BLOCK]] ] @@ -955,10 +955,10 @@ define i64 @diff_exit_block_pre_inc_use3() { ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) ; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; CHECK: vector.ph: -; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] ; CHECK: vector.body: -; CHECK-NEXT: [[INDEX2:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT4:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDEX2:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT4:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX2]] ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] @@ -974,19 +974,19 @@ define i64 @diff_exit_block_pre_inc_use3() { ; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT4]], 64 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) ; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP7]], [[TMP8]] -; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP24:![0-9]+]] +; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP24:![0-9]+]] ; CHECK: middle.split: ; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: [[TMP10:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) -; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP10]] +; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) +; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_EARLY_EXIT:%.*]] ; CHECK: middle.block: -; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 3 +; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 3 ; CHECK-NEXT: br i1 true, label [[LOOP_END:%.*]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] -; CHECK-NEXT: br label [[LOOP1:%.*]] +; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] @@ -998,12 +998,12 @@ define i64 @diff_exit_block_pre_inc_use3() { ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP25:![0-9]+]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP25:![0-9]+]] ; CHECK: loop.early.exit: -; CHECK-NEXT: [[INDEX_LCSSA:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[INDEX_LCSSA:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ [[TMP10]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[INDEX_LCSSA]] ; CHECK: loop.end: -; CHECK-NEXT: [[INDEX_LCSSA1:%.*]] = phi i64 [ [[INDEX]], [[LOOP_INC]] ], [ [[TMP12]], [[MIDDLE_BLOCK]] ] +; CHECK-NEXT: [[INDEX_LCSSA1:%.*]] = phi i64 [ [[INDEX]], [[LOOP_INC]] ], [ [[TMP11]], [[MIDDLE_BLOCK]] ] ; CHECK-NEXT: ret i64 [[INDEX_LCSSA1]] ; entry: @@ -1044,44 +1044,44 @@ define i64 @diff_exit_block_post_inc_use1() { ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) ; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; CHECK: vector.ph: -; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] ; CHECK: vector.body: -; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 -; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[OFFSET_IDX]], 1 -; CHECK-NEXT: [[TMP13:%.*]] = add i64 [[OFFSET_IDX]], 2 -; CHECK-NEXT: [[TMP14:%.*]] = add i64 [[OFFSET_IDX]], 3 -; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] -; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i32 0 -; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP2]], align 1 -; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[TMP0]] -; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i32 0 -; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load <4 x i8>, ptr [[TMP4]], align 1 -; CHECK-NEXT: [[TMP5:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], [[WIDE_LOAD2]] -; CHECK-NEXT: [[TMP15:%.*]] = add i64 [[TMP0]], 1 -; CHECK-NEXT: [[TMP16:%.*]] = add i64 [[TMP6]], 1 -; CHECK-NEXT: [[TMP17:%.*]] = add i64 [[TMP13]], 1 -; CHECK-NEXT: [[TMP18:%.*]] = add i64 [[TMP14]], 1 +; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[OFFSET_IDX]], 1 +; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[OFFSET_IDX]], 2 +; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[OFFSET_IDX]], 3 +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[TMP4]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP5]], align 1 +; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i8, ptr [[TMP6]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load <4 x i8>, ptr [[TMP7]], align 1 +; CHECK-NEXT: [[TMP8:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], [[WIDE_LOAD2]] +; CHECK-NEXT: [[TMP9:%.*]] = add i64 [[TMP0]], 1 +; CHECK-NEXT: [[TMP10:%.*]] = add i64 [[TMP1]], 1 +; CHECK-NEXT: [[TMP11:%.*]] = add i64 [[TMP2]], 1 +; CHECK-NEXT: [[TMP12:%.*]] = add i64 [[TMP3]], 1 ; CHECK-NEXT: [[INDEX_NEXT3]] = add nuw i64 [[INDEX1]], 4 -; CHECK-NEXT: [[TMP7:%.*]] = xor <4 x i1> [[TMP5]], splat (i1 true) -; CHECK-NEXT: [[TMP8:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP7]]) -; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 +; CHECK-NEXT: [[TMP13:%.*]] = xor <4 x i1> [[TMP8]], splat (i1 true) +; CHECK-NEXT: [[TMP14:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP13]]) +; CHECK-NEXT: [[TMP15:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) -; CHECK-NEXT: [[TMP10:%.*]] = or i1 [[TMP8]], [[TMP9]] -; CHECK-NEXT: br i1 [[TMP10]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP26:![0-9]+]] +; CHECK-NEXT: [[TMP16:%.*]] = or i1 [[TMP14]], [[TMP15]] +; CHECK-NEXT: br i1 [[TMP16]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP26:![0-9]+]] ; CHECK: middle.split: -; CHECK-NEXT: br i1 [[TMP8]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK-NEXT: br i1 [[TMP14]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: [[TMP11:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP7]], i1 true) -; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP11]] +; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP13]], i1 true) +; CHECK-NEXT: [[TMP17:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_EARLY_EXIT:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END:%.*]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] -; CHECK-NEXT: br label [[LOOP1:%.*]] +; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] @@ -1093,12 +1093,12 @@ define i64 @diff_exit_block_post_inc_use1() { ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP27:![0-9]+]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP27:![0-9]+]] ; CHECK: loop.early.exit: -; CHECK-NEXT: [[RETVAL1:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ [[TMP12]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL1:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ [[TMP17]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL1]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL2:%.*]] = phi i64 [ [[INDEX_NEXT]], [[LOOP_INC]] ], [ [[TMP18]], [[MIDDLE_BLOCK]] ] +; CHECK-NEXT: [[RETVAL2:%.*]] = phi i64 [ [[INDEX_NEXT]], [[LOOP_INC]] ], [ [[TMP12]], [[MIDDLE_BLOCK]] ] ; CHECK-NEXT: ret i64 [[RETVAL2]] ; entry: @@ -1141,49 +1141,49 @@ define i64 @diff_exit_block_post_inc_use2() { ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) ; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; CHECK: vector.ph: -; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] ; CHECK: vector.body: -; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 -; CHECK-NEXT: [[TMP13:%.*]] = add i64 [[OFFSET_IDX]], 1 -; CHECK-NEXT: [[TMP14:%.*]] = add i64 [[OFFSET_IDX]], 2 -; CHECK-NEXT: [[TMP15:%.*]] = add i64 [[OFFSET_IDX]], 3 -; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[TMP0]], 1 -; CHECK-NEXT: [[TMP16:%.*]] = add i64 [[TMP13]], 1 -; CHECK-NEXT: [[TMP17:%.*]] = add i64 [[TMP14]], 1 -; CHECK-NEXT: [[TMP18:%.*]] = add i64 [[TMP15]], 1 -; CHECK-NEXT: [[TMP19:%.*]] = insertelement <4 x i64> poison, i64 [[TMP1]], i32 0 -; CHECK-NEXT: [[TMP20:%.*]] = insertelement <4 x i64> [[TMP19]], i64 [[TMP16]], i32 1 -; CHECK-NEXT: [[TMP21:%.*]] = insertelement <4 x i64> [[TMP20]], i64 [[TMP17]], i32 2 -; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = insertelement <4 x i64> [[TMP21]], i64 [[TMP18]], i32 3 -; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] -; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i32 0 -; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP3]], align 1 -; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[TMP0]] -; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[TMP4]], i32 0 -; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load <4 x i8>, ptr [[TMP5]], align 1 -; CHECK-NEXT: [[TMP6:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], [[WIDE_LOAD2]] +; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[OFFSET_IDX]], 1 +; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[OFFSET_IDX]], 2 +; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[OFFSET_IDX]], 3 +; CHECK-NEXT: [[TMP4:%.*]] = add i64 [[TMP0]], 1 +; CHECK-NEXT: [[TMP5:%.*]] = add i64 [[TMP1]], 1 +; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[TMP2]], 1 +; CHECK-NEXT: [[TMP7:%.*]] = add i64 [[TMP3]], 1 +; CHECK-NEXT: [[TMP8:%.*]] = insertelement <4 x i64> poison, i64 [[TMP4]], i32 0 +; CHECK-NEXT: [[TMP9:%.*]] = insertelement <4 x i64> [[TMP8]], i64 [[TMP5]], i32 1 +; CHECK-NEXT: [[TMP10:%.*]] = insertelement <4 x i64> [[TMP9]], i64 [[TMP6]], i32 2 +; CHECK-NEXT: [[TMP11:%.*]] = insertelement <4 x i64> [[TMP10]], i64 [[TMP7]], i32 3 +; CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds i8, ptr [[TMP12]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP13]], align 1 +; CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[TMP0]] +; CHECK-NEXT: [[TMP15:%.*]] = getelementptr inbounds i8, ptr [[TMP14]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load <4 x i8>, ptr [[TMP15]], align 1 +; CHECK-NEXT: [[TMP16:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], [[WIDE_LOAD2]] ; CHECK-NEXT: [[INDEX_NEXT3]] = add nuw i64 [[INDEX1]], 4 -; CHECK-NEXT: [[TMP7:%.*]] = xor <4 x i1> [[TMP6]], splat (i1 true) -; CHECK-NEXT: [[TMP8:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP7]]) -; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 +; CHECK-NEXT: [[TMP17:%.*]] = xor <4 x i1> [[TMP16]], splat (i1 true) +; CHECK-NEXT: [[TMP18:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP17]]) +; CHECK-NEXT: [[TMP19:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) -; CHECK-NEXT: [[TMP10:%.*]] = or i1 [[TMP8]], [[TMP9]] -; CHECK-NEXT: br i1 [[TMP10]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP28:![0-9]+]] +; CHECK-NEXT: [[TMP20:%.*]] = or i1 [[TMP18]], [[TMP19]] +; CHECK-NEXT: br i1 [[TMP20]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP28:![0-9]+]] ; CHECK: middle.split: -; CHECK-NEXT: br i1 [[TMP8]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] +; CHECK-NEXT: br i1 [[TMP18]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: [[TMP11:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP7]], i1 true) -; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x i64> [[BROADCAST_SPLAT]], i64 [[TMP11]] +; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP17]], i1 true) +; CHECK-NEXT: [[TMP21:%.*]] = extractelement <4 x i64> [[TMP11]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_EARLY_EXIT:%.*]] ; CHECK: middle.block: -; CHECK-NEXT: [[TMP23:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 3 +; CHECK-NEXT: [[TMP22:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 3 ; CHECK-NEXT: br i1 true, label [[LOOP_END:%.*]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] -; CHECK-NEXT: br label [[LOOP1:%.*]] +; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 @@ -1195,12 +1195,12 @@ define i64 @diff_exit_block_post_inc_use2() { ; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_EARLY_EXIT]] ; CHECK: loop.inc: ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP29:![0-9]+]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP29:![0-9]+]] ; CHECK: loop.early.exit: -; CHECK-NEXT: [[RETVAL1:%.*]] = phi i64 [ [[INDEX_NEXT]], [[LOOP1]] ], [ [[TMP12]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL1:%.*]] = phi i64 [ [[INDEX_NEXT]], [[LOOP]] ], [ [[TMP21]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL1]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL2:%.*]] = phi i64 [ [[INDEX]], [[LOOP_INC]] ], [ [[TMP23]], [[MIDDLE_BLOCK]] ] +; CHECK-NEXT: [[RETVAL2:%.*]] = phi i64 [ [[INDEX]], [[LOOP_INC]] ], [ [[TMP22]], [[MIDDLE_BLOCK]] ] ; CHECK-NEXT: ret i64 [[RETVAL2]] ; entry: @@ -1243,10 +1243,10 @@ define i64 @loop_contains_safe_call() { ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) ; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; CHECK: vector.ph: -; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] ; CHECK: vector.body: -; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT2:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT2:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds float, ptr [[P1]], i64 [[TMP0]] @@ -1260,18 +1260,18 @@ define i64 @loop_contains_safe_call() { ; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT2]], 64 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) ; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]] -; CHECK-NEXT: br i1 [[TMP8]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP30:![0-9]+]] +; CHECK-NEXT: br i1 [[TMP8]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP30:![0-9]+]] ; CHECK: middle.split: ; CHECK-NEXT: br i1 [[TMP6]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: [[TMP9:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP5]], i1 true) -; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP9]] +; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP5]], i1 true) +; CHECK-NEXT: [[TMP9:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] -; CHECK-NEXT: br label [[LOOP1:%.*]] +; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[P1]], i64 [[INDEX]] @@ -1282,9 +1282,9 @@ define i64 @loop_contains_safe_call() { ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP31:![0-9]+]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP31:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP10]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP9]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -1343,8 +1343,8 @@ define i64 @loop_contains_safe_div() { ; CHECK: middle.split: ; CHECK-NEXT: br i1 [[TMP6]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: [[TMP9:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP5]], i1 true) -; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP9]] +; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP5]], i1 true) +; CHECK-NEXT: [[TMP9:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] @@ -1363,7 +1363,7 @@ define i64 @loop_contains_safe_div() { ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP33:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP10]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP9]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -1400,10 +1400,10 @@ define i64 @loop_contains_load_after_early_exit(ptr dereferenceable(1024) align( ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) ; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; CHECK: vector.ph: -; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] ; CHECK: vector.body: -; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[P1]], i64 [[TMP0]] @@ -1419,19 +1419,19 @@ define i64 @loop_contains_load_after_early_exit(ptr dereferenceable(1024) align( ; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) ; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP7]], [[TMP8]] -; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP34:![0-9]+]] +; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP34:![0-9]+]] ; CHECK: middle.split: -; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x i64> [[WIDE_LOAD2]], i32 3 +; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[WIDE_LOAD2]], i32 3 ; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: [[TMP10:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) -; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP10]] +; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) +; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] -; CHECK-NEXT: br label [[LOOP1:%.*]] +; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[P1]], i64 [[INDEX]] @@ -1443,9 +1443,9 @@ define i64 @loop_contains_load_after_early_exit(ptr dereferenceable(1024) align( ; CHECK-NEXT: [[LD2:%.*]] = load i64, ptr [[ARRAYIDX2]], align 8 ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP35:![0-9]+]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP35:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ [[LD2]], [[LOOP_INC]] ], [ [[TMP12]], [[MIDDLE_BLOCK]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ [[LD2]], [[LOOP_INC]] ], [ [[TMP10]], [[MIDDLE_BLOCK]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -1482,10 +1482,10 @@ define i64 @same_exit_block_pre_inc_use1_reverse() { ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) ; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; CHECK: vector.ph: -; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] ; CHECK: vector.body: -; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT4:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT4:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = sub i64 1023, [[INDEX1]] ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] @@ -1505,18 +1505,18 @@ define i64 @same_exit_block_pre_inc_use1_reverse() { ; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT4]], 1020 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 -4) ; CHECK-NEXT: [[TMP11:%.*]] = or i1 [[TMP9]], [[TMP10]] -; CHECK-NEXT: br i1 [[TMP11]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP36:![0-9]+]] +; CHECK-NEXT: br i1 [[TMP11]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP36:![0-9]+]] ; CHECK: middle.split: ; CHECK-NEXT: br i1 [[TMP9]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: [[TMP12:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP8]], i1 true) -; CHECK-NEXT: [[TMP13:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP12]] +; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP8]], i1 true) +; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 false, label [[LOOP_END]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 3, [[MIDDLE_BLOCK]] ], [ 1023, [[ENTRY:%.*]] ] -; CHECK-NEXT: br label [[LOOP1:%.*]] +; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] @@ -1528,9 +1528,9 @@ define i64 @same_exit_block_pre_inc_use1_reverse() { ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], -1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDEX_NEXT]], 0 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP_END]], label [[LOOP1]], !llvm.loop [[LOOP37:![0-9]+]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP_END]], label [[LOOP]], !llvm.loop [[LOOP37:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ 1024, [[LOOP_INC]] ], [ 1024, [[MIDDLE_BLOCK]] ], [ [[TMP13]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 1024, [[LOOP_INC]] ], [ 1024, [[MIDDLE_BLOCK]] ], [ [[TMP12]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -1566,10 +1566,10 @@ define i64 @same_exit_block_pre_inc_use1_deref_ptrs(ptr dereferenceable(1024) %p ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; CHECK: vector.ph: -; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] ; CHECK: vector.body: -; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT3:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 3, [[INDEX1]] ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[TMP0]] @@ -1585,18 +1585,18 @@ define i64 @same_exit_block_pre_inc_use1_deref_ptrs(ptr dereferenceable(1024) %p ; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT3]], 64 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) ; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP7]], [[TMP8]] -; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP38:![0-9]+]] +; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP38:![0-9]+]] ; CHECK: middle.split: ; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: -; CHECK-NEXT: [[TMP10:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) -; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[TMP10]] +; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) +; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] -; CHECK-NEXT: br label [[LOOP1:%.*]] +; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] @@ -1608,9 +1608,9 @@ define i64 @same_exit_block_pre_inc_use1_deref_ptrs(ptr dereferenceable(1024) %p ; CHECK: loop.inc: ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END]], !llvm.loop [[LOOP39:![0-9]+]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP39:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP1]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP10]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: From 71fec6bfb0f95b561113c0b09999b3e7f479024b Mon Sep 17 00:00:00 2001 From: David Sherwood Date: Thu, 30 Jan 2025 09:48:11 +0000 Subject: [PATCH 5/5] Add name for early exit value --- .../lib/Transforms/Vectorize/VPlanRecipes.cpp | 2 +- .../AArch64/simple_early_exit.ll | 20 ++--- .../single_early_exit_live_outs.ll | 76 +++++++++---------- 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index b8c38cdd7ebcd..81031b9401ca0 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -702,7 +702,7 @@ Value *VPInstruction::generate(VPTransformState &State) { Value *Mask = State.get(getOperand(1)); Value *Ctz = Builder.CreateCountTrailingZeroElems( Builder.getInt64Ty(), Mask, true, "first.active.lane"); - return Builder.CreateExtractElement(Vec, Ctz); + return Builder.CreateExtractElement(Vec, Ctz, "early.exit.value"); } default: llvm_unreachable("Unsupported opcode for instruction"); diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/simple_early_exit.ll b/llvm/test/Transforms/LoopVectorize/AArch64/simple_early_exit.ll index 6eb3ee6d5225b..9d21ea0ab6de3 100644 --- a/llvm/test/Transforms/LoopVectorize/AArch64/simple_early_exit.ll +++ b/llvm/test/Transforms/LoopVectorize/AArch64/simple_early_exit.ll @@ -55,7 +55,7 @@ define i64 @same_exit_block_pre_inc_use1() #1 { ; CHECK-NEXT: br i1 [[TMP17]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: ; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.nxv16i1( [[TMP16]], i1 true) -; CHECK-NEXT: [[TMP20:%.*]] = extractelement [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] +; CHECK-NEXT: [[EARLY_EXIT_VALUE:%.*]] = extractelement [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 64, [[N_VEC]] @@ -76,7 +76,7 @@ define i64 @same_exit_block_pre_inc_use1() #1 { ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP3:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP20]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[EARLY_EXIT_VALUE]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -138,7 +138,7 @@ define i64 @same_exit_block_pre_inc_use4() { ; CHECK-NEXT: br i1 [[TMP5]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: ; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v2i1(<2 x i1> [[TMP4]], i1 true) -; CHECK-NEXT: [[TMP8:%.*]] = extractelement <2 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] +; CHECK-NEXT: [[EARLY_EXIT_VALUE:%.*]] = extractelement <2 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] @@ -156,7 +156,7 @@ define i64 @same_exit_block_pre_inc_use4() { ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP5:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP8]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[EARLY_EXIT_VALUE]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -216,7 +216,7 @@ define i64 @loop_contains_safe_call() #1 { ; CHECK-NEXT: br i1 [[TMP6]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: ; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP5]], i1 true) -; CHECK-NEXT: [[TMP9:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] +; CHECK-NEXT: [[EARLY_EXIT_VALUE:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] @@ -235,7 +235,7 @@ define i64 @loop_contains_safe_call() #1 { ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP7:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP9]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[EARLY_EXIT_VALUE]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -296,7 +296,7 @@ define i64 @loop_contains_safe_div() #1 { ; CHECK-NEXT: br i1 [[TMP6]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: ; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v2i1(<2 x i1> [[TMP5]], i1 true) -; CHECK-NEXT: [[TMP9:%.*]] = extractelement <2 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] +; CHECK-NEXT: [[EARLY_EXIT_VALUE:%.*]] = extractelement <2 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] @@ -315,7 +315,7 @@ define i64 @loop_contains_safe_div() #1 { ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP9:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP9]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[EARLY_EXIT_VALUE]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -381,7 +381,7 @@ define i64 @loop_contains_load_after_early_exit(ptr dereferenceable(1024) align( ; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: ; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) -; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] +; CHECK-NEXT: [[EARLY_EXIT_VALUE:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] @@ -401,7 +401,7 @@ define i64 @loop_contains_load_after_early_exit(ptr dereferenceable(1024) align( ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP11:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ [[LD2]], [[LOOP_INC]] ], [ [[TMP10]], [[MIDDLE_BLOCK]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ [[LD2]], [[LOOP_INC]] ], [ [[TMP10]], [[MIDDLE_BLOCK]] ], [ [[EARLY_EXIT_VALUE]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: diff --git a/llvm/test/Transforms/LoopVectorize/single_early_exit_live_outs.ll b/llvm/test/Transforms/LoopVectorize/single_early_exit_live_outs.ll index 8aa5d0b279a9c..1bfe054057089 100644 --- a/llvm/test/Transforms/LoopVectorize/single_early_exit_live_outs.ll +++ b/llvm/test/Transforms/LoopVectorize/single_early_exit_live_outs.ll @@ -36,7 +36,7 @@ define i64 @same_exit_block_pre_inc_use1() { ; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: ; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) -; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] +; CHECK-NEXT: [[EARLY_EXIT_VALUE:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] @@ -56,7 +56,7 @@ define i64 @same_exit_block_pre_inc_use1() { ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP3:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP10]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[EARLY_EXIT_VALUE]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -121,7 +121,7 @@ define i64 @same_exit_block_pre_inc1_use_inv_cond(i1 %cond) { ; CHECK-NEXT: br i1 [[TMP8]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: ; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP7]], i1 true) -; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] +; CHECK-NEXT: [[EARLY_EXIT_VALUE:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] @@ -142,7 +142,7 @@ define i64 @same_exit_block_pre_inc1_use_inv_cond(i1 %cond) { ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP5:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[EARLY_EXIT_VALUE]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -206,7 +206,7 @@ define i64 @same_exit_block_pre_inc_use1_gep_two_indices() { ; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: ; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) -; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] +; CHECK-NEXT: [[EARLY_EXIT_VALUE:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] @@ -226,7 +226,7 @@ define i64 @same_exit_block_pre_inc_use1_gep_two_indices() { ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP7:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP10]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[EARLY_EXIT_VALUE]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -289,7 +289,7 @@ define i64 @same_exit_block_pre_inc_use1_alloca_diff_type() { ; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: ; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) -; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] +; CHECK-NEXT: [[EARLY_EXIT_VALUE:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] @@ -309,7 +309,7 @@ define i64 @same_exit_block_pre_inc_use1_alloca_diff_type() { ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP9:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP10]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[EARLY_EXIT_VALUE]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -455,7 +455,7 @@ define i64 @same_exit_block_pre_inc_use3() { ; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: ; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) -; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] +; CHECK-NEXT: [[EARLY_EXIT_VALUE:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] @@ -475,7 +475,7 @@ define i64 @same_exit_block_pre_inc_use3() { ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP13:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[INDEX_LCSSA:%.*]] = phi i64 [ [[INDEX]], [[LOOP_INC]] ], [ [[INDEX]], [[LOOP]] ], [ [[TMP10]], [[MIDDLE_BLOCK]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[INDEX_LCSSA:%.*]] = phi i64 [ [[INDEX]], [[LOOP_INC]] ], [ [[INDEX]], [[LOOP]] ], [ [[TMP10]], [[MIDDLE_BLOCK]] ], [ [[EARLY_EXIT_VALUE]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[INDEX_LCSSA]] ; entry: @@ -536,7 +536,7 @@ define i64 @same_exit_block_pre_inc_use4() { ; CHECK-NEXT: br i1 [[TMP5]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: ; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP4]], i1 true) -; CHECK-NEXT: [[TMP8:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] +; CHECK-NEXT: [[EARLY_EXIT_VALUE:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] @@ -554,7 +554,7 @@ define i64 @same_exit_block_pre_inc_use4() { ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP15:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP8]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[EARLY_EXIT_VALUE]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -622,7 +622,7 @@ define i64 @same_exit_block_post_inc_use() { ; CHECK-NEXT: br i1 [[TMP14]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: ; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP13]], i1 true) -; CHECK-NEXT: [[TMP17:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] +; CHECK-NEXT: [[EARLY_EXIT_VALUE:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] @@ -642,7 +642,7 @@ define i64 @same_exit_block_post_inc_use() { ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP17:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ [[INDEX_NEXT]], [[LOOP_INC]] ], [ [[TMP12]], [[MIDDLE_BLOCK]] ], [ [[TMP17]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ [[INDEX_NEXT]], [[LOOP_INC]] ], [ [[TMP12]], [[MIDDLE_BLOCK]] ], [ [[EARLY_EXIT_VALUE]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -717,7 +717,7 @@ define i64 @same_exit_block_post_inc_use2() { ; CHECK-NEXT: br i1 [[TMP18]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: ; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP17]], i1 true) -; CHECK-NEXT: [[TMP22:%.*]] = extractelement <4 x i64> [[TMP15]], i64 [[FIRST_ACTIVE_LANE]] +; CHECK-NEXT: [[EARLY_EXIT_VALUE:%.*]] = extractelement <4 x i64> [[TMP15]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] @@ -737,7 +737,7 @@ define i64 @same_exit_block_post_inc_use2() { ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP19:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX_NEXT]], [[LOOP]] ], [ [[INDEX]], [[LOOP_INC]] ], [ [[TMP21]], [[MIDDLE_BLOCK]] ], [ [[TMP22]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX_NEXT]], [[LOOP]] ], [ [[INDEX]], [[LOOP_INC]] ], [ [[TMP21]], [[MIDDLE_BLOCK]] ], [ [[EARLY_EXIT_VALUE]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -800,7 +800,7 @@ define i64 @diff_exit_block_pre_inc_use1() { ; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: ; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) -; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] +; CHECK-NEXT: [[EARLY_EXIT_VALUE:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_EARLY_EXIT:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END:%.*]], label [[SCALAR_PH]] @@ -820,7 +820,7 @@ define i64 @diff_exit_block_pre_inc_use1() { ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP21:![0-9]+]] ; CHECK: loop.early.exit: -; CHECK-NEXT: [[RETVAL1:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ [[TMP10]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL1:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ [[EARLY_EXIT_VALUE]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL1]] ; CHECK: loop.end: ; CHECK-NEXT: [[RETVAL2:%.*]] = phi i64 [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ] @@ -979,10 +979,10 @@ define i64 @diff_exit_block_pre_inc_use3() { ; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: ; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) -; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] +; CHECK-NEXT: [[EARLY_EXIT_VALUE:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_EARLY_EXIT:%.*]] ; CHECK: middle.block: -; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 3 +; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 3 ; CHECK-NEXT: br i1 true, label [[LOOP_END:%.*]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] @@ -1000,10 +1000,10 @@ define i64 @diff_exit_block_pre_inc_use3() { ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP25:![0-9]+]] ; CHECK: loop.early.exit: -; CHECK-NEXT: [[INDEX_LCSSA:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ [[TMP10]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[INDEX_LCSSA:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ [[EARLY_EXIT_VALUE]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[INDEX_LCSSA]] ; CHECK: loop.end: -; CHECK-NEXT: [[INDEX_LCSSA1:%.*]] = phi i64 [ [[INDEX]], [[LOOP_INC]] ], [ [[TMP11]], [[MIDDLE_BLOCK]] ] +; CHECK-NEXT: [[INDEX_LCSSA1:%.*]] = phi i64 [ [[INDEX]], [[LOOP_INC]] ], [ [[TMP10]], [[MIDDLE_BLOCK]] ] ; CHECK-NEXT: ret i64 [[INDEX_LCSSA1]] ; entry: @@ -1075,7 +1075,7 @@ define i64 @diff_exit_block_post_inc_use1() { ; CHECK-NEXT: br i1 [[TMP14]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: ; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP13]], i1 true) -; CHECK-NEXT: [[TMP17:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] +; CHECK-NEXT: [[EARLY_EXIT_VALUE:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_EARLY_EXIT:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END:%.*]], label [[SCALAR_PH]] @@ -1095,7 +1095,7 @@ define i64 @diff_exit_block_post_inc_use1() { ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP27:![0-9]+]] ; CHECK: loop.early.exit: -; CHECK-NEXT: [[RETVAL1:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ [[TMP17]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL1:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ [[EARLY_EXIT_VALUE]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL1]] ; CHECK: loop.end: ; CHECK-NEXT: [[RETVAL2:%.*]] = phi i64 [ [[INDEX_NEXT]], [[LOOP_INC]] ], [ [[TMP12]], [[MIDDLE_BLOCK]] ] @@ -1176,10 +1176,10 @@ define i64 @diff_exit_block_post_inc_use2() { ; CHECK-NEXT: br i1 [[TMP18]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: ; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP17]], i1 true) -; CHECK-NEXT: [[TMP21:%.*]] = extractelement <4 x i64> [[TMP11]], i64 [[FIRST_ACTIVE_LANE]] +; CHECK-NEXT: [[EARLY_EXIT_VALUE:%.*]] = extractelement <4 x i64> [[TMP11]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_EARLY_EXIT:%.*]] ; CHECK: middle.block: -; CHECK-NEXT: [[TMP22:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 3 +; CHECK-NEXT: [[TMP21:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 3 ; CHECK-NEXT: br i1 true, label [[LOOP_END:%.*]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 67, [[MIDDLE_BLOCK]] ], [ 3, [[ENTRY:%.*]] ] @@ -1197,10 +1197,10 @@ define i64 @diff_exit_block_post_inc_use2() { ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP29:![0-9]+]] ; CHECK: loop.early.exit: -; CHECK-NEXT: [[RETVAL1:%.*]] = phi i64 [ [[INDEX_NEXT]], [[LOOP]] ], [ [[TMP21]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL1:%.*]] = phi i64 [ [[INDEX_NEXT]], [[LOOP]] ], [ [[EARLY_EXIT_VALUE]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL1]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL2:%.*]] = phi i64 [ [[INDEX]], [[LOOP_INC]] ], [ [[TMP22]], [[MIDDLE_BLOCK]] ] +; CHECK-NEXT: [[RETVAL2:%.*]] = phi i64 [ [[INDEX]], [[LOOP_INC]] ], [ [[TMP21]], [[MIDDLE_BLOCK]] ] ; CHECK-NEXT: ret i64 [[RETVAL2]] ; entry: @@ -1265,7 +1265,7 @@ define i64 @loop_contains_safe_call() { ; CHECK-NEXT: br i1 [[TMP6]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: ; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP5]], i1 true) -; CHECK-NEXT: [[TMP9:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] +; CHECK-NEXT: [[EARLY_EXIT_VALUE:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] @@ -1284,7 +1284,7 @@ define i64 @loop_contains_safe_call() { ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP31:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP9]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[EARLY_EXIT_VALUE]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -1344,7 +1344,7 @@ define i64 @loop_contains_safe_div() { ; CHECK-NEXT: br i1 [[TMP6]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: ; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP5]], i1 true) -; CHECK-NEXT: [[TMP9:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] +; CHECK-NEXT: [[EARLY_EXIT_VALUE:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] @@ -1363,7 +1363,7 @@ define i64 @loop_contains_safe_div() { ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP33:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP9]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[EARLY_EXIT_VALUE]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -1425,7 +1425,7 @@ define i64 @loop_contains_load_after_early_exit(ptr dereferenceable(1024) align( ; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: ; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) -; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] +; CHECK-NEXT: [[EARLY_EXIT_VALUE:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] @@ -1445,7 +1445,7 @@ define i64 @loop_contains_load_after_early_exit(ptr dereferenceable(1024) align( ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP35:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ [[LD2]], [[LOOP_INC]] ], [ [[TMP10]], [[MIDDLE_BLOCK]] ], [ [[TMP11]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ [[LD2]], [[LOOP_INC]] ], [ [[TMP10]], [[MIDDLE_BLOCK]] ], [ [[EARLY_EXIT_VALUE]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -1510,7 +1510,7 @@ define i64 @same_exit_block_pre_inc_use1_reverse() { ; CHECK-NEXT: br i1 [[TMP9]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: ; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP8]], i1 true) -; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] +; CHECK-NEXT: [[EARLY_EXIT_VALUE:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 false, label [[LOOP_END]], label [[SCALAR_PH]] @@ -1530,7 +1530,7 @@ define i64 @same_exit_block_pre_inc_use1_reverse() { ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDEX_NEXT]], 0 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP_END]], label [[LOOP]], !llvm.loop [[LOOP37:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 1024, [[LOOP_INC]] ], [ 1024, [[MIDDLE_BLOCK]] ], [ [[TMP12]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 1024, [[LOOP_INC]] ], [ 1024, [[MIDDLE_BLOCK]] ], [ [[EARLY_EXIT_VALUE]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: @@ -1590,7 +1590,7 @@ define i64 @same_exit_block_pre_inc_use1_deref_ptrs(ptr dereferenceable(1024) %p ; CHECK-NEXT: br i1 [[TMP7]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] ; CHECK: vector.early.exit: ; CHECK-NEXT: [[FIRST_ACTIVE_LANE:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true) -; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] +; CHECK-NEXT: [[EARLY_EXIT_VALUE:%.*]] = extractelement <4 x i64> [[VEC_IND]], i64 [[FIRST_ACTIVE_LANE]] ; CHECK-NEXT: br label [[LOOP_END:%.*]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[LOOP_END]], label [[SCALAR_PH]] @@ -1610,7 +1610,7 @@ define i64 @same_exit_block_pre_inc_use1_deref_ptrs(ptr dereferenceable(1024) %p ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]], !llvm.loop [[LOOP39:![0-9]+]] ; CHECK: loop.end: -; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[TMP10]], [[VECTOR_EARLY_EXIT]] ] +; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ], [ 67, [[MIDDLE_BLOCK]] ], [ [[EARLY_EXIT_VALUE]], [[VECTOR_EARLY_EXIT]] ] ; CHECK-NEXT: ret i64 [[RETVAL]] ; entry: