[llvm] [LV] Add initial legality checks for ee loops with stores (PR #145663)
David Sherwood via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 29 04:17:55 PDT 2025
================
@@ -1771,13 +1815,63 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
// TODO: Handle loops that may fault.
Predicates.clear();
- if (!isDereferenceableReadOnlyLoop(TheLoop, PSE.getSE(), DT, AC,
- &Predicates)) {
- reportVectorizationFailure(
- "Loop may fault",
- "Cannot vectorize potentially faulting early exit loop",
- "PotentiallyFaultingEarlyExitLoop", ORE, TheLoop);
- return false;
+ if (UncountedExitWithSideEffects) {
+ // Record load for analysis by isDereferenceableAndAlignedInLoop
+ // and later by dependence analysis.
+ if (BranchInst *Br = dyn_cast<BranchInst>(
+ SingleUncountableEdge->first->getTerminator())) {
+ // FIXME: Handle exit conditions with multiple users, more complex exit
+ // conditions than br(icmp(load, loop_inv)).
+ ICmpInst *Cmp = dyn_cast<ICmpInst>(Br->getCondition());
+ if (Cmp && Cmp->hasOneUse() &&
+ TheLoop->isLoopInvariant(Cmp->getOperand(1))) {
+ LoadInst *Load = dyn_cast<LoadInst>(Cmp->getOperand(0));
+ if (Load && Load->hasOneUse() && !TheLoop->isLoopInvariant(Load)) {
+ if (isDereferenceableAndAlignedInLoop(Load, TheLoop, *PSE.getSE(),
----------------
david-arm wrote:
The fact you're relying upon a single dereferenceable check here implies that you know it's possible to move this load above all other memory accesses, which I don't think is true. I realise you're checking for memory dependences in canVectorizeMemory, but I don't expect that to cover cases like this:
```
%off = load i8, ptr %a
%off64 = zext i8 %off to i64
%load = load i32, ptr %b, i64 %off64
```
In this case there isn't a strict memory dependence between the two loads, but the second load requires the first to have been executed. It's perfectly possible for `isDereferenceableAndAlignedInLoop` to return true for `%load` due to the limited range of the offset. In this example you also need to check if the first load is dereferenceable too since it must be executed first.
I think you have two choices:
1. Check that all loads prior to this one are also dereferenceable, or
2. Bail out if the critical load depends upon an earlier load.
https://github.com/llvm/llvm-project/pull/145663
More information about the llvm-commits
mailing list