[llvm] [LV] Use SCEV loop-uniformity for outer-loop branch legality (PR #199632)
Ming Yan via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 4 00:45:07 PDT 2026
================
@@ -621,38 +541,39 @@ bool LoopVectorizationLegality::canVectorizeOuterLoop() {
}
// Check whether the branch is a supported one. Only unconditional
- // branches, conditional branches with an outer loop invariant condition or
+ // branches, conditional branches with an outer loop uniform condition or
// backedges are supported.
// FIXME: We skip these checks when VPlan predication is enabled as we
// want to allow divergent branches. This whole check will be removed
// once VPlan predication is on by default.
auto *Br = dyn_cast<CondBrInst>(Term);
- if (Br && !TheLoop->isLoopInvariant(Br->getCondition()) &&
- !LI->isLoopHeader(Br->getSuccessor(0)) &&
- !LI->isLoopHeader(Br->getSuccessor(1))) {
- reportVectorizationFailure(
- "Unsupported conditional branch",
- "loop control flow is not understood by vectorizer",
- "CFGNotUnderstood", ORE, TheLoop);
- if (DoExtraAnalysis)
- Result = false;
- else
- return false;
- }
- }
+ if (Br && !TheLoop->isLoopLatch(BB)) {
+ bool isUniformCondBr = TheLoop->isLoopInvariant(Br->getCondition());
+
+ auto *Cmp = dyn_cast<CmpInst>(Br->getCondition());
+ auto *SE = PSE.getSE();
+ if (!isUniformCondBr && Cmp &&
+ SE->isSCEVable(Cmp->getOperand(0)->getType())) {
+ const SCEV *LhsExpr = PSE.getSCEV(Cmp->getOperand(0));
+ const SCEV *RhsExpr = PSE.getSCEV(Cmp->getOperand(1));
+ isUniformCondBr |= (SE->isLoopUniform(LhsExpr, TheLoop) &&
+ SE->isLoopUniform(RhsExpr, TheLoop));
+ }
- // Check whether inner loops are uniform. At this point, we only support
- // simple outer loops scenarios with uniform nested loops.
- if (!isUniformLoopNest(TheLoop /*loop nest*/,
- TheLoop /*context outer loop*/)) {
- reportVectorizationFailure(
- "Outer loop contains divergent loops",
- "loop control flow is not understood by vectorizer", "CFGNotUnderstood",
- ORE, TheLoop);
- if (DoExtraAnalysis)
- Result = false;
- else
- return false;
+ // If the condition is not uniform, report a failure. We currently require
+ // uniform conditions to avoid the complexity of vectorizing divergent
+ // control flow in the outer loop.
+ if (!isUniformCondBr) {
+ reportVectorizationFailure(
+ "Outer loop contains divergent conditional branch",
+ "loop control flow is not understood by vectorizer",
+ "CFGNotUnderstood", ORE, TheLoop);
----------------
NexMing wrote:
I removed the previous overly specialized checks. I am not quite sure what more specific information you would like to see here.
https://github.com/llvm/llvm-project/pull/199632
More information about the llvm-commits
mailing list