[llvm] [SCEVExpander] Support hoisting udiv X, Y where Y is non-zero (PR #96102)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 1 09:36:39 PDT 2024


================
@@ -1470,12 +1470,11 @@ Value *SCEVExpander::expand(const SCEV *S) {
 
   // We can move insertion point only if there is no div or rem operations
   // otherwise we are risky to move it over the check for zero denominator.
-  auto SafeToHoist = [](const SCEV *S) {
-    return !SCEVExprContains(S, [](const SCEV *S) {
+  auto SafeToHoist = [&](const SCEV *S) {
+    return !SCEVExprContains(S, [&](const SCEV *S) {
               if (const auto *D = dyn_cast<SCEVUDivExpr>(S)) {
-                if (const auto *SC = dyn_cast<SCEVConstant>(D->getRHS()))
-                  // Division by non-zero constants can be hoisted.
-                  return SC->getValue()->isZero();
+                if (SE.isKnownNonZero(D->getRHS()))
----------------
nikic wrote:

>  We also appear to need to worry about undef by the same logic.

Undef is not known to be non-zero.

> We also have no infrastructure for proving a SCEV non-poison directly, so the scope of a fix here is significant. I think we'd basically have to duplicate all of isGuaranteedNotToBeUndefOrPoison over SCEV.

We have the infrastructure for this (SCEVPoisonCollector), but it looks like we currently don't expose an isGuaranteedNotToBePoison() API based on it.

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


More information about the llvm-commits mailing list