[llvm] LSV: forbid load-cycles when vectorizing; fix bug (PR #104815)

Madhur Amilkanthwar via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 21 22:19:46 PDT 2024


================
@@ -996,10 +996,32 @@ bool Vectorizer::isSafeToMove(
   LLVM_DEBUG(dbgs() << "LSV: isSafeToMove(" << *ChainElem << " -> "
                     << *ChainBegin << ")\n");
 
-  assert(isa<LoadInst>(ChainElem) == IsLoadChain);
+  assert(isa<LoadInst>(ChainElem) == IsLoadChain &&
+         isa<LoadInst>(ChainBegin) == IsLoadChain);
+
   if (ChainElem == ChainBegin)
     return true;
 
+  if constexpr (IsLoadChain) {
+    // If ChainElem depends on ChainBegin, they're not safe to reorder.
+    SmallVector<Instruction *, 8> Worklist;
+    Worklist.emplace_back(ChainElem);
+    while (!Worklist.empty()) {
+      Instruction *I = Worklist.pop_back_val();
+      for (Use &O : I->operands()) {
+        if (isa<PHINode>(O))
+          continue;
+        if (auto *J = dyn_cast<Instruction>(O)) {
+          if (J == ChainBegin) {
+            LLVM_DEBUG(dbgs() << "LSV: dependent loads; not safe to reorder\n");
+            return false;
+          }
+          Worklist.emplace_back(J);
----------------
madhur13490 wrote:

I think this can be written using early returns. What about this?

```
while (!Worklist.empty()) {
    Instruction *I = Worklist.pop_back_val();
    for (Use &O: I->operands()) {
        if (isa<PHINode>(O)) continue;
        auto CurrentUse = dyn_cast<Instruction>(O);
        if (!CurrentUse) continue;
        if (CurrentUse == ChainBegin) {
            LLVM_DEBUG ..
            return false;
        }
        Worklist.emplace_back(CurrentUse);
     }
}
```


https://github.com/llvm/llvm-project/pull/104815


More information about the llvm-commits mailing list