[llvm] [SLP] Handle strides that are the results of multiplication by constant (PR #194746)

Ryan Buchner via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 28 15:51:39 PDT 2026


================
@@ -6896,20 +6862,29 @@ static const SCEV *calculateRtStride(ArrayRef<Value *> PointerOps, Type *ElemTy,
   int Size = DL.getTypeStoreSize(ElemTy);
   auto TryGetStride = [&](const SCEV *Dist,
                           const SCEV *Multiplier) -> const SCEV * {
-    if (const auto *M = dyn_cast<SCEVMulExpr>(Dist)) {
-      if (M->getOperand(0) == Multiplier)
-        return M->getOperand(1);
-      if (M->getOperand(1) == Multiplier)
-        return M->getOperand(0);
-      return nullptr;
-    }
     if (Multiplier == Dist)
       return SE.getConstant(Dist->getType(), 1);
+    if (const auto *M = dyn_cast<SCEVMulExpr>(Dist)) {
+      // Want to simplify the distant/multiplier, but can only be done
+      // if NUW is assumed
+      SCEV::NoWrapFlags Flags =
+          ScalarEvolution::setFlags(M->getNoWrapFlags(), SCEV::FlagNUW);
+      SmallVector<SCEVUseT<const SCEV *>> Ops(M->operands());
+      Dist = SE.getMulExpr(Ops, Flags);
+    }
+    if (const auto *M = dyn_cast<SCEVMulExpr>(Multiplier)) {
+      // Want to simplify the distant/multiplier, but can only be done
+      // if NUW is assumed
+      SCEV::NoWrapFlags Flags =
+          ScalarEvolution::setFlags(M->getNoWrapFlags(), SCEV::FlagNUW);
+      SmallVector<SCEVUseT<const SCEV *>> Ops(M->operands());
+      Multiplier = SE.getMulExpr(Ops, Flags);
+    }
----------------
bababuck wrote:

The factoring that is already being done (i.e. `if (M->getOperand(0) == Multiplier) return M->getOperand(1)`) is implicitly assumes NUW is set. We already are assuming `NUW`, this change just makes that explicit.

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


More information about the llvm-commits mailing list