[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