|
17 | 17 | #include "VPlanAnalysis.h"
|
18 | 18 | #include "VPlanCFG.h"
|
19 | 19 | #include "VPlanDominatorTree.h"
|
| 20 | +#include "VPlanHelpers.h" |
20 | 21 | #include "VPlanPatternMatch.h"
|
21 | 22 | #include "VPlanUtils.h"
|
22 | 23 | #include "VPlanVerifier.h"
|
@@ -2457,7 +2458,8 @@ void VPlanTransforms::convertToConcreteRecipes(VPlan &Plan,
|
2457 | 2458 |
|
2458 | 2459 | void VPlanTransforms::handleUncountableEarlyExit(
|
2459 | 2460 | VPlan &Plan, ScalarEvolution &SE, Loop *OrigLoop,
|
2460 |
| - BasicBlock *UncountableExitingBlock, VPRecipeBuilder &RecipeBuilder) { |
| 2461 | + BasicBlock *UncountableExitingBlock, VPRecipeBuilder &RecipeBuilder, |
| 2462 | + VFRange &Range) { |
2461 | 2463 | VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
|
2462 | 2464 | auto *LatchVPBB = cast<VPBasicBlock>(LoopRegion->getExiting());
|
2463 | 2465 | VPBuilder Builder(LatchVPBB->getTerminator());
|
@@ -2512,8 +2514,14 @@ void VPlanTransforms::handleUncountableEarlyExit(
|
2512 | 2514 | ExitIRI->addOperand(IncomingFromLatch);
|
2513 | 2515 | ExitIRI->extractLastLaneOfOperand(MiddleBuilder);
|
2514 | 2516 | }
|
2515 |
| - // Add the incoming value from the early exit. |
2516 |
| - if (!IncomingFromEarlyExit->isLiveIn() && !Plan.hasScalarVFOnly()) { |
| 2517 | + |
| 2518 | + auto IsVector = [](ElementCount VF) { return VF.isVector(); }; |
| 2519 | + // When the VFs are vectors, need to add `extract` to get the incoming value |
| 2520 | + // from early exit. When the range contains scalar VF, limit the range to |
| 2521 | + // scalar VF to prevent mis-compilation for the range containing both scalar |
| 2522 | + // and vector VFs. |
| 2523 | + if (!IncomingFromEarlyExit->isLiveIn() && |
| 2524 | + LoopVectorizationPlanner::getDecisionAndClampRange(IsVector, Range)) { |
2517 | 2525 | VPValue *FirstActiveLane = EarlyExitB.createNaryOp(
|
2518 | 2526 | VPInstruction::FirstActiveLane, {EarlyExitTakenCond}, nullptr,
|
2519 | 2527 | "first.active.lane");
|
|
0 commit comments