[llvm] [SimplifyCFG] More accurate use legality check for sinking (PR #94462)

Eli Friedman via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 13 16:30:35 PDT 2024


================
@@ -1981,21 +1981,19 @@ static bool canSinkInstructions(
       return false;
   }
 
-  // All instructions in Insts are known to be the same opcode. If they have a
-  // use, check that the only user is a PHI or in the same block as the
-  // instruction, because if a user is in the same block as an instruction we're
-  // contemplating sinking, it must already be determined to be sinkable.
+  // Uses must be consistent: If I0 is used in a phi node in the sink target,
+  // then the other phi operands must match the instructions from Insts. This
+  // also has to hold true for any phi nodes that would be created as a result
+  // of sinking. Both of these cases are represented by PhiOperands.
   if (HasUse) {
-    auto *PNUse = dyn_cast<PHINode>(*I0->user_begin());
-    auto *Succ = I0->getParent()->getTerminator()->getSuccessor(0);
-    if (!all_of(Insts, [&PNUse,&Succ](const Instruction *I) -> bool {
-          auto *U = cast<Instruction>(*I->user_begin());
-          return (PNUse &&
-                  PNUse->getParent() == Succ &&
-                  PNUse->getIncomingValueForBlock(I->getParent()) == I) ||
-                 U->getParent() == I->getParent();
-        }))
+    const Use &U = *I0->use_begin();
+    auto It = PHIOperands.find(&U);
+    if (It == PHIOperands.end())
+      // There may be uses in other blocks when sinking into a loop header.
       return false;
+    for (auto [I1, I2] : zip(Insts, It->second))
+      if (I1 != I2)
+        return false;
----------------
efriedma-quic wrote:

```suggestion
    if (!equal(Insts, It->second))
      return false;
```

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


More information about the llvm-commits mailing list