[llvm] [VPlan] Move tail folding out of VPlanPredicator. NFC (PR #176143)
Andrei Elovikov via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 22 08:13:07 PST 2026
eas wrote:
> Yes but the vector mask condition is the problem since VPInstruction::BranchOnCond isn't designed as a masking construct but for regular control flow, i.e. see VPInstruction::usesFirstLaneOnly where it states the condition operand is scalar. In retrospect I think it was more a coincidence that VPPredicator happened to work with it because it was automatically broadcasting scalars when predicating.
For
```llvm
header:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
%mask = icmp slt i64 %iv, %n
br i1 %mask, label %body, label %latch
body:
%gep = getelementptr i64, ptr %ptr, i64 %iv
%ld = load i64, ptr %gep
%add = add i64 %ld, %iv
store i64 %add, ptr %gep
br label %latch
latch:
%iv.next = add nsw i64 %iv, 1
%exitcond = icmp slt i64 %iv.next, %n
br i1 %exitcond, label %header, label %exit
```
Right before predicator (current trunk):
```llvm
<x1> vector loop: {
vector.body:
EMIT vp<%4> = CANONICAL-INDUCTION ir<0>, vp<%index.next>
ir<%iv> = WIDEN-INDUCTION nsw ir<0>, ir<1>, vp<%0>
EMIT ir<%mask> = icmp slt ir<%iv>, ir<%n>
EMIT branch-on-cond ir<%mask> ;; ! branch-on-cond too !
Successor(s): body, latch
body:
EMIT ir<%gep> = getelementptr ir<%ptr>, ir<%iv>
EMIT ir<%ld> = load ir<%gep>
EMIT ir<%add> = add ir<%ld>, ir<%iv>
EMIT store ir<%add>, ir<%gep>
Successor(s): latch
latch:
EMIT ir<%iv.next> = add nsw ir<%iv>, ir<1>
EMIT ir<%exitcond> = icmp slt ir<%iv.next>, ir<%n>
EMIT vp<%5> = not ir<%exitcond>
EMIT vp<%index.next> = add nuw vp<%4>, vp<%1>
EMIT branch-on-count vp<%index.next>, vp<%2>
No successors
}
Successor(s): middle.block
```
How is that different from manually created `icmp`? I don't think predicator looks into `BranchOnCond->getOperand(0)->getUnderlyingValue()` (and really there would be no reason for it to do that).
https://github.com/llvm/llvm-project/pull/176143
More information about the llvm-commits
mailing list