[llvm] [SCEV] Simplify SCEVExpr for PHI to SCEV for operand if operands are identical (PR #115945)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 25 13:18:12 PST 2024


================
@@ -6019,6 +6019,34 @@ const SCEV *ScalarEvolution::createNodeFromSelectLikePHI(PHINode *PN) {
   return nullptr;
 }
 
+/// Returns SCEV for the first operand of a phi if all phi operands have
+/// identical opcodes and operands
+/// eg.
+/// a: %add = %a + %b
+///    br %c
+/// b: %add1 = %a + %b
+///    br %c
+/// c: %phi = phi [%add, a], [%add1, b]
+/// scev(%phi) => scev(%add)
+const SCEV *
+ScalarEvolution::createNodeForPHIWithIdenticalOperands(PHINode *PN) {
+  BinaryOperator *CommonInst = nullptr;
+  for (Value *Incoming : PN->incoming_values()) {
+    BinaryOperator *IncomingInst = dyn_cast<BinaryOperator>(Incoming);
+    if (CommonInst) {
+      if (!(IncomingInst && CommonInst->isIdenticalTo(IncomingInst)))
+        return nullptr; // Not identical, give up
+    } else if (IncomingInst) {
+      // Remember binary operator
+      CommonInst = IncomingInst;
+    } else {
+      // Not a binary operator, give up
+      return nullptr;
+    }
+  }
+  return CommonInst ? getSCEV(CommonInst) : nullptr;
----------------
nikic wrote:

I expect that you do need both loops -- not for correctness, but as a profitability heuristic. Computing SCEVs is expensive, and always recursing through phis would likely add significant cost.

I tried to confirm this but the stage2 build crashes (https://llvm-compile-time-tracker.com/show_error.php?commit=a4e3a0e648d7a3664ca6269e846abf2e6ddcdb08). I didn't investigate, but it might be that the recursion causes a stack overflow.

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


More information about the llvm-commits mailing list