Skip to content

Commit 6d1cc96

Browse files
committed
[VPlan] Remove loop region in optimizeForVFAndUF.
Update optimizeForVFAndUF to completely remove the vector loop region when possible. At the moment, we cannot remove the region if it contains * widened IVs: the recipe is needed to generate the step vector * reductions: ComputeReductionResults requires the reduction phi recipe for codegen. Both cases can be addressed by more explicit modeling. The patch also includes a number of updates to allow executing VPlans without a vector loop region which can be split off.
1 parent 7792b4a commit 6d1cc96

13 files changed

+290
-302
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2392,7 +2392,10 @@ void InnerLoopVectorizer::scalarizeInstruction(const Instruction *Instr,
23922392
AC->registerAssumption(II);
23932393

23942394
// End if-block.
2395-
bool IfPredicateInstr = RepRecipe->getParent()->getParent()->isReplicator();
2395+
bool IfPredicateInstr =
2396+
RepRecipe->getParent()->getParent()
2397+
? RepRecipe->getParent()->getParent()->isReplicator()
2398+
: false;
23962399
if (IfPredicateInstr)
23972400
PredicatedInstructions.push_back(Cloned);
23982401
}
@@ -2954,6 +2957,8 @@ void InnerLoopVectorizer::fixVectorizedLoop(VPTransformState &State,
29542957
for (PHINode &PN : Exit->phis())
29552958
PSE.getSE()->forgetLcssaPhiWithNewPredecessor(OrigLoop, &PN);
29562959

2960+
if (!isa<VPRegionBlock>(State.Plan->getEntry()->getSingleSuccessor()))
2961+
return;
29572962
VPRegionBlock *VectorRegion = State.Plan->getVectorLoopRegion();
29582963
VPBasicBlock *LatchVPBB = VectorRegion->getExitingBasicBlock();
29592964
Loop *VectorLoop = LI->getLoopFor(State.CFG.VPBB2IRBB[LatchVPBB]);
@@ -7598,8 +7603,8 @@ LoopVectorizationPlanner::executePlan(
75987603

75997604
// 2.5 Collect reduction resume values.
76007605
DenseMap<const RecurrenceDescriptor *, Value *> ReductionResumeValues;
7601-
auto *ExitVPBB =
7602-
cast<VPBasicBlock>(BestVPlan.getVectorLoopRegion()->getSingleSuccessor());
7606+
auto *ExitVPBB = cast<VPBasicBlock>(
7607+
BestVPlan.getEntry()->getSingleSuccessor()->getSingleSuccessor());
76037608
for (VPRecipeBase &R : *ExitVPBB) {
76047609
createAndCollectMergePhiForReduction(
76057610
dyn_cast<VPInstruction>(&R), ReductionResumeValues, State, OrigLoop,
@@ -7615,24 +7620,26 @@ LoopVectorizationPlanner::executePlan(
76157620
makeFollowupLoopID(OrigLoopID, {LLVMLoopVectorizeFollowupAll,
76167621
LLVMLoopVectorizeFollowupVectorized});
76177622

7618-
VPBasicBlock *HeaderVPBB =
7619-
BestVPlan.getVectorLoopRegion()->getEntryBasicBlock();
7620-
Loop *L = LI->getLoopFor(State.CFG.VPBB2IRBB[HeaderVPBB]);
7621-
if (VectorizedLoopID)
7622-
L->setLoopID(*VectorizedLoopID);
7623-
else {
7624-
// Keep all loop hints from the original loop on the vector loop (we'll
7625-
// replace the vectorizer-specific hints below).
7626-
if (MDNode *LID = OrigLoop->getLoopID())
7627-
L->setLoopID(LID);
7628-
7629-
LoopVectorizeHints Hints(L, true, *ORE);
7630-
Hints.setAlreadyVectorized();
7623+
if (auto *R =
7624+
dyn_cast<VPRegionBlock>(BestVPlan.getEntry()->getSingleSuccessor())) {
7625+
VPBasicBlock *HeaderVPBB = R->getEntryBasicBlock();
7626+
Loop *L = LI->getLoopFor(State.CFG.VPBB2IRBB[HeaderVPBB]);
7627+
if (VectorizedLoopID)
7628+
L->setLoopID(*VectorizedLoopID);
7629+
else {
7630+
// Keep all loop hints from the original loop on the vector loop (we'll
7631+
// replace the vectorizer-specific hints below).
7632+
if (MDNode *LID = OrigLoop->getLoopID())
7633+
L->setLoopID(LID);
7634+
7635+
LoopVectorizeHints Hints(L, true, *ORE);
7636+
Hints.setAlreadyVectorized();
7637+
}
7638+
TargetTransformInfo::UnrollingPreferences UP;
7639+
TTI.getUnrollingPreferences(L, *PSE.getSE(), UP, ORE);
7640+
if (!UP.UnrollVectorizedLoop || CanonicalIVStartValue)
7641+
addRuntimeUnrollDisableMetaData(L);
76317642
}
7632-
TargetTransformInfo::UnrollingPreferences UP;
7633-
TTI.getUnrollingPreferences(L, *PSE.getSE(), UP, ORE);
7634-
if (!UP.UnrollVectorizedLoop || CanonicalIVStartValue)
7635-
addRuntimeUnrollDisableMetaData(L);
76367643

76377644
// 3. Fix the vectorized code: take care of header phi's, live-outs,
76387645
// predication, updating analyses.
@@ -9468,7 +9475,8 @@ void VPDerivedIVRecipe::execute(VPTransformState &State) {
94689475
State.Builder, CanonicalIV, getStartValue()->getLiveInIRValue(), Step,
94699476
Kind, cast_if_present<BinaryOperator>(FPBinOp));
94709477
DerivedIV->setName("offset.idx");
9471-
assert(DerivedIV != CanonicalIV && "IV didn't need transforming?");
9478+
assert((isa<Constant>(CanonicalIV) || DerivedIV != CanonicalIV) &&
9479+
"IV didn't need transforming?");
94729480

94739481
State.set(this, DerivedIV, VPIteration(0, 0));
94749482
}

llvm/lib/Transforms/Vectorize/VPlan.cpp

Lines changed: 67 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,7 @@ VPTransformState::VPTransformState(ElementCount VF, unsigned UF, LoopInfo *LI,
226226
InnerLoopVectorizer *ILV, VPlan *Plan,
227227
LLVMContext &Ctx)
228228
: VF(VF), UF(UF), CFG(DT), LI(LI), Builder(Builder), ILV(ILV), Plan(Plan),
229-
LVer(nullptr),
230-
TypeAnalysis(Plan->getCanonicalIV()->getScalarType(), Ctx) {}
229+
LVer(nullptr), TypeAnalysis(IntegerType::get(Ctx, 64), Ctx) {}
231230

232231
Value *VPTransformState::get(VPValue *Def, const VPIteration &Instance) {
233232
if (Def->isLiveIn())
@@ -278,8 +277,8 @@ Value *VPTransformState::get(VPValue *Def, unsigned Part, bool NeedsScalar) {
278277
// Place the code for broadcasting invariant variables in the new preheader.
279278
IRBuilder<>::InsertPointGuard Guard(Builder);
280279
if (SafeToHoist) {
281-
BasicBlock *LoopVectorPreHeader = CFG.VPBB2IRBB[cast<VPBasicBlock>(
282-
Plan->getVectorLoopRegion()->getSinglePredecessor())];
280+
BasicBlock *LoopVectorPreHeader =
281+
CFG.VPBB2IRBB[cast<VPBasicBlock>(Plan->getEntry())];
283282
if (LoopVectorPreHeader)
284283
Builder.SetInsertPoint(LoopVectorPreHeader->getTerminator());
285284
}
@@ -934,7 +933,7 @@ void VPlan::prepareToExecute(Value *TripCountV, Value *VectorTripCountV,
934933

935934
IRBuilder<> Builder(State.CFG.PrevBB->getTerminator());
936935
// FIXME: Model VF * UF computation completely in VPlan.
937-
assert(VFxUF.getNumUsers() && "VFxUF expected to always have users");
936+
// assert(VFxUF.getNumUsers() && "VFxUF expected to always have users");
938937
if (VF.getNumUsers()) {
939938
Value *RuntimeVF = getRuntimeVF(Builder, TCTy, State.VF);
940939
VF.setUnderlyingValue(RuntimeVF);
@@ -1005,8 +1004,13 @@ void VPlan::execute(VPTransformState *State) {
10051004
// skeleton creation, so we can only create the VPIRBasicBlocks now during
10061005
// VPlan execution rather than earlier during VPlan construction.
10071006
BasicBlock *MiddleBB = State->CFG.ExitBB;
1008-
VPBasicBlock *MiddleVPBB =
1009-
cast<VPBasicBlock>(getVectorLoopRegion()->getSingleSuccessor());
1007+
VPBlockBase *Leaf = nullptr;
1008+
for (VPBlockBase *VPB : vp_depth_first_shallow(getEntry()))
1009+
if (VPB->getNumSuccessors() == 0) {
1010+
Leaf = VPB;
1011+
break;
1012+
}
1013+
VPBasicBlock *MiddleVPBB = cast<VPBasicBlock>(Leaf->getSinglePredecessor());
10101014
// Find the VPBB for the scalar preheader, relying on the current structure
10111015
// when creating the middle block and its successrs: if there's a single
10121016
// predecessor, it must be the scalar preheader. Otherwise, the second
@@ -1034,64 +1038,66 @@ void VPlan::execute(VPTransformState *State) {
10341038
for (VPBlockBase *Block : vp_depth_first_shallow(Entry))
10351039
Block->execute(State);
10361040

1037-
VPBasicBlock *LatchVPBB = getVectorLoopRegion()->getExitingBasicBlock();
1038-
BasicBlock *VectorLatchBB = State->CFG.VPBB2IRBB[LatchVPBB];
1039-
1040-
// Fix the latch value of canonical, reduction and first-order recurrences
1041-
// phis in the vector loop.
1042-
VPBasicBlock *Header = getVectorLoopRegion()->getEntryBasicBlock();
1043-
for (VPRecipeBase &R : Header->phis()) {
1044-
// Skip phi-like recipes that generate their backedege values themselves.
1045-
if (isa<VPWidenPHIRecipe>(&R))
1046-
continue;
1047-
1048-
if (isa<VPWidenPointerInductionRecipe>(&R) ||
1049-
isa<VPWidenIntOrFpInductionRecipe>(&R)) {
1050-
PHINode *Phi = nullptr;
1051-
if (isa<VPWidenIntOrFpInductionRecipe>(&R)) {
1052-
Phi = cast<PHINode>(State->get(R.getVPSingleValue(), 0));
1053-
} else {
1054-
auto *WidenPhi = cast<VPWidenPointerInductionRecipe>(&R);
1055-
assert(!WidenPhi->onlyScalarsGenerated(State->VF.isScalable()) &&
1056-
"recipe generating only scalars should have been replaced");
1057-
auto *GEP = cast<GetElementPtrInst>(State->get(WidenPhi, 0));
1058-
Phi = cast<PHINode>(GEP->getPointerOperand());
1059-
}
1060-
1061-
Phi->setIncomingBlock(1, VectorLatchBB);
1041+
if (auto *LoopRegion =
1042+
dyn_cast<VPRegionBlock>(getEntry()->getSingleSuccessor())) {
1043+
VPBasicBlock *LatchVPBB = LoopRegion->getExitingBasicBlock();
1044+
BasicBlock *VectorLatchBB = State->CFG.VPBB2IRBB[LatchVPBB];
1045+
1046+
// Fix the latch value of canonical, reduction and first-order recurrences
1047+
// phis in the vector loop.
1048+
VPBasicBlock *Header = LoopRegion->getEntryBasicBlock();
1049+
for (VPRecipeBase &R : Header->phis()) {
1050+
// Skip phi-like recipes that generate their backedege values themselves.
1051+
if (isa<VPWidenPHIRecipe>(&R))
1052+
continue;
10621053

1063-
// Move the last step to the end of the latch block. This ensures
1064-
// consistent placement of all induction updates.
1065-
Instruction *Inc = cast<Instruction>(Phi->getIncomingValue(1));
1066-
Inc->moveBefore(VectorLatchBB->getTerminator()->getPrevNode());
1067-
continue;
1068-
}
1054+
if (isa<VPWidenPointerInductionRecipe>(&R) ||
1055+
isa<VPWidenIntOrFpInductionRecipe>(&R)) {
1056+
PHINode *Phi = nullptr;
1057+
if (isa<VPWidenIntOrFpInductionRecipe>(&R)) {
1058+
Phi = cast<PHINode>(State->get(R.getVPSingleValue(), 0));
1059+
} else {
1060+
auto *WidenPhi = cast<VPWidenPointerInductionRecipe>(&R);
1061+
assert(!WidenPhi->onlyScalarsGenerated(State->VF.isScalable()) &&
1062+
"recipe generating only scalars should have been replaced");
1063+
auto *GEP = cast<GetElementPtrInst>(State->get(WidenPhi, 0));
1064+
Phi = cast<PHINode>(GEP->getPointerOperand());
1065+
}
1066+
1067+
Phi->setIncomingBlock(1, VectorLatchBB);
1068+
1069+
// Move the last step to the end of the latch block. This ensures
1070+
// consistent placement of all induction updates.
1071+
Instruction *Inc = cast<Instruction>(Phi->getIncomingValue(1));
1072+
Inc->moveBefore(VectorLatchBB->getTerminator()->getPrevNode());
1073+
continue;
1074+
}
10691075

1070-
auto *PhiR = cast<VPHeaderPHIRecipe>(&R);
1071-
// For canonical IV, first-order recurrences and in-order reduction phis,
1072-
// only a single part is generated, which provides the last part from the
1073-
// previous iteration. For non-ordered reductions all UF parts are
1074-
// generated.
1075-
bool SinglePartNeeded =
1076-
isa<VPCanonicalIVPHIRecipe>(PhiR) ||
1077-
isa<VPFirstOrderRecurrencePHIRecipe, VPEVLBasedIVPHIRecipe>(PhiR) ||
1078-
(isa<VPReductionPHIRecipe>(PhiR) &&
1079-
cast<VPReductionPHIRecipe>(PhiR)->isOrdered());
1080-
bool NeedsScalar =
1081-
isa<VPCanonicalIVPHIRecipe, VPEVLBasedIVPHIRecipe>(PhiR) ||
1082-
(isa<VPReductionPHIRecipe>(PhiR) &&
1083-
cast<VPReductionPHIRecipe>(PhiR)->isInLoop());
1084-
unsigned LastPartForNewPhi = SinglePartNeeded ? 1 : State->UF;
1085-
1086-
for (unsigned Part = 0; Part < LastPartForNewPhi; ++Part) {
1087-
Value *Phi = State->get(PhiR, Part, NeedsScalar);
1088-
Value *Val =
1089-
State->get(PhiR->getBackedgeValue(),
1090-
SinglePartNeeded ? State->UF - 1 : Part, NeedsScalar);
1091-
cast<PHINode>(Phi)->addIncoming(Val, VectorLatchBB);
1076+
auto *PhiR = cast<VPHeaderPHIRecipe>(&R);
1077+
// For canonical IV, first-order recurrences and in-order reduction phis,
1078+
// only a single part is generated, which provides the last part from the
1079+
// previous iteration. For non-ordered reductions all UF parts are
1080+
// generated.
1081+
bool SinglePartNeeded =
1082+
isa<VPCanonicalIVPHIRecipe>(PhiR) ||
1083+
isa<VPFirstOrderRecurrencePHIRecipe, VPEVLBasedIVPHIRecipe>(PhiR) ||
1084+
(isa<VPReductionPHIRecipe>(PhiR) &&
1085+
cast<VPReductionPHIRecipe>(PhiR)->isOrdered());
1086+
bool NeedsScalar =
1087+
isa<VPCanonicalIVPHIRecipe, VPEVLBasedIVPHIRecipe>(PhiR) ||
1088+
(isa<VPReductionPHIRecipe>(PhiR) &&
1089+
cast<VPReductionPHIRecipe>(PhiR)->isInLoop());
1090+
unsigned LastPartForNewPhi = SinglePartNeeded ? 1 : State->UF;
1091+
1092+
for (unsigned Part = 0; Part < LastPartForNewPhi; ++Part) {
1093+
Value *Phi = State->get(PhiR, Part, NeedsScalar);
1094+
Value *Val =
1095+
State->get(PhiR->getBackedgeValue(),
1096+
SinglePartNeeded ? State->UF - 1 : Part, NeedsScalar);
1097+
cast<PHINode>(Phi)->addIncoming(Val, VectorLatchBB);
1098+
}
10921099
}
10931100
}
1094-
10951101
State->CFG.DTU.flush();
10961102
assert(State->CFG.DTU.getDomTree().verify(
10971103
DominatorTree::VerificationLevel::Fast) &&

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3311,6 +3311,7 @@ class VPRegionBlock : public VPBlockBase {
33113311
assert(!isReplicator() && "should only get pre-header of loop regions");
33123312
return getSinglePredecessor()->getExitingBasicBlock();
33133313
}
3314+
void clearEntry() { Entry = nullptr; }
33143315

33153316
/// An indicator whether this region is to generate multiple replicated
33163317
/// instances of output IR corresponding to its VPBlockBases.

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -702,16 +702,46 @@ void VPlanTransforms::optimizeForVFAndUF(VPlan &Plan, ElementCount BestVF,
702702
!SE.isKnownPredicate(CmpInst::ICMP_ULE, TripCount, C))
703703
return;
704704

705-
LLVMContext &Ctx = SE.getContext();
706-
auto *BOC =
707-
new VPInstruction(VPInstruction::BranchOnCond,
708-
{Plan.getOrAddLiveIn(ConstantInt::getTrue(Ctx))});
709-
710705
SmallVector<VPValue *> PossiblyDead(Term->operands());
711706
Term->eraseFromParent();
707+
VPBasicBlock *Header =
708+
cast<VPBasicBlock>(Plan.getVectorLoopRegion()->getEntry());
709+
if (all_of(Header->phis(), [](VPRecipeBase &R) {
710+
return !isa<VPWidenIntOrFpInductionRecipe, VPReductionPHIRecipe>(&R);
711+
})) {
712+
for (VPRecipeBase &R : make_early_inc_range(Header->phis())) {
713+
auto *P = cast<VPHeaderPHIRecipe>(&R);
714+
P->replaceAllUsesWith(P->getStartValue());
715+
P->eraseFromParent();
716+
}
717+
718+
VPBlockBase *Preheader = Plan.getVectorLoopRegion()->getSinglePredecessor();
719+
auto HeaderSuccs = to_vector(Header->getSuccessors());
720+
VPBasicBlock *Exiting =
721+
cast<VPBasicBlock>(Plan.getVectorLoopRegion()->getExiting());
722+
723+
auto *LoopRegion = Plan.getVectorLoopRegion();
724+
VPBlockBase *Middle = LoopRegion->getSingleSuccessor();
725+
VPBlockUtils::disconnectBlocks(Preheader, LoopRegion);
726+
VPBlockUtils::disconnectBlocks(LoopRegion, Middle);
727+
728+
Header->setParent(nullptr);
729+
Exiting->setParent(nullptr);
730+
VPBlockUtils::connectBlocks(Preheader, Header);
731+
732+
VPBlockUtils::connectBlocks(Exiting, Middle);
733+
LoopRegion->clearEntry();
734+
delete LoopRegion;
735+
} else {
736+
LLVMContext &Ctx = SE.getContext();
737+
auto *BOC =
738+
new VPInstruction(VPInstruction::BranchOnCond,
739+
{Plan.getOrAddLiveIn(ConstantInt::getTrue(Ctx))});
740+
741+
ExitingVPBB->appendRecipe(BOC);
742+
}
712743
for (VPValue *Op : PossiblyDead)
713744
recursivelyDeleteDeadRecipes(Op);
714-
ExitingVPBB->appendRecipe(BOC);
715745
Plan.setVF(BestVF);
716746
Plan.setUF(BestUF);
717747
// TODO: Further simplifications are possible
@@ -720,7 +750,7 @@ void VPlanTransforms::optimizeForVFAndUF(VPlan &Plan, ElementCount BestVF,
720750
}
721751

722752
/// Sink users of \p FOR after the recipe defining the previous value \p
723-
/// Previous of the recurrence. \returns true if all users of \p FOR could be
753+
// Previous of the recurrence. \returns true if all users of \p FOR could be
724754
/// re-arranged as needed or false if it is not possible.
725755
static bool
726756
sinkRecurrenceUsersAfterPrevious(VPFirstOrderRecurrencePHIRecipe *FOR,

llvm/test/Transforms/LoopVectorize/AArch64/call-costs.ll

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -81,17 +81,13 @@ define void @powi_call(ptr %P) {
8181
; CHECK-NEXT: [[ENTRY:.*]]:
8282
; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
8383
; CHECK: [[VECTOR_PH]]:
84-
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
85-
; CHECK: [[VECTOR_BODY]]:
86-
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
87-
; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
88-
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds double, ptr [[P]], i64 [[TMP0]]
84+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds double, ptr [[P]], i64 0
8985
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds double, ptr [[TMP1]], i32 0
9086
; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x double>, ptr [[TMP2]], align 8
9187
; CHECK-NEXT: [[TMP3:%.*]] = call <2 x double> @llvm.powi.v2f64.i32(<2 x double> [[WIDE_LOAD]], i32 3)
92-
; CHECK-NEXT: store <2 x double> [[TMP3]], ptr [[TMP2]], align 8
93-
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
94-
; CHECK-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
88+
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds double, ptr [[TMP1]], i32 0
89+
; CHECK-NEXT: store <2 x double> [[TMP3]], ptr [[TMP4]], align 8
90+
; CHECK-NEXT: br label %[[MIDDLE_BLOCK:.*]]
9591
; CHECK: [[MIDDLE_BLOCK]]:
9692
; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]]
9793
; CHECK: [[SCALAR_PH]]:
@@ -105,7 +101,7 @@ define void @powi_call(ptr %P) {
105101
; CHECK-NEXT: store double [[POWI]], ptr [[GEP]], align 8
106102
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
107103
; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], 1
108-
; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP]], !llvm.loop [[LOOP5:![0-9]+]]
104+
; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP]], !llvm.loop [[LOOP4:![0-9]+]]
109105
; CHECK: [[EXIT]]:
110106
; CHECK-NEXT: ret void
111107
;
@@ -236,6 +232,5 @@ declare i64 @llvm.fshl.i64(i64, i64, i64)
236232
; CHECK: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}
237233
; CHECK: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"}
238234
; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META2]], [[META1]]}
239-
; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[META1]], [[META2]]}
240-
; CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[META2]], [[META1]]}
235+
; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[META2]], [[META1]]}
241236
;.

0 commit comments

Comments
 (0)