[llvm] [LLVM][SCEV] Look through common multiplicand when simplifying compares. (PR #141798)

Paul Walker via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 5 10:26:56 PDT 2025


================
@@ -10748,6 +10748,63 @@ bool ScalarEvolution::SimplifyICmpOperands(CmpPredicate &Pred, const SCEV *&LHS,
   if (Depth >= 3)
     return false;
 
+  if (isa<SCEVMulExpr>(LHS) && isa<SCEVMulExpr>(RHS)) {
+    const SCEVMulExpr *LMul = cast<SCEVMulExpr>(LHS);
+    const SCEVMulExpr *RMul = cast<SCEVMulExpr>(RHS);
+
+    auto FindCommonFactor =
+        [&](const SCEVMulExpr *LHS, const SCEVMulExpr *RHS,
+            bool (ScalarEvolution::*Predicate)(
+                const SCEV *)) -> std::optional<std::pair<int, int>> {
+      for (int i = 0, e = LHS->getNumOperands(); i != e; ++i)
+        for (int j = 0, e = RHS->getNumOperands(); j != e; ++j)
+          if (LHS->getOperand(i) == RHS->getOperand(j) &&
+              (this->*Predicate)(LHS->getOperand(i)))
+            return std::make_pair(i, j);
----------------
paulwalker-arm wrote:

Thanks for the review @artagnon and sorry for the delay.  I plan to pick this back up next week.  Before going down the wrong path I figured I'd ask first.

Whilst in the future I think three operand multiplies may be useful (e.g. `constant * vscale * variable`) my immediate requirements are simple two operand multiplies involving vscale.  Given `m_scev_Mul` and `m_SCEVVScale` exist (I wasn't aware of these prior to creating the PR) is there any objection to me matching the specific pattern (i.e. `m_SCEVVScale(A, m_SCEVVScale)`)? because then most all the complexity disappears.

FYI: This is an idiom I'm seeking to repeat for other SCEV operations beyond compares, for example `udiv(a * vscale, b * vscale)` that is also used by LoopVectorize and is currently hampering control flow optimisations.

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


More information about the llvm-commits mailing list