[llvm] [SCEV] Use power of two facts involving vscale when inferring wrap flags (PR #101380)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 31 11:49:12 PDT 2024


================
@@ -10845,6 +10843,25 @@ bool ScalarEvolution::isKnownNonZero(const SCEV *S) {
   return getUnsignedRangeMin(S) != 0;
 }
 
+bool ScalarEvolution::isKnownToBeAPowerOfTwo(const SCEV *S, bool OrZero) {
+  auto nonRecursive = [this](const SCEV *S) {
+    if (auto *C = dyn_cast<SCEVConstant>(S))
+      return C->getAPInt().isPowerOf2();
+    // The vscale_range indicates vscale is a power-of-two.
+    return S->getSCEVType() == scVScale && F.hasFnAttribute(Attribute::VScaleRange);;
+  };
+
+  if (nonRecursive(S))
+    return true;
+
+  auto *Mul = dyn_cast<SCEVMulExpr>(S);
+  if (!Mul || Mul->getNumOperands() != 2)
+    return false;
+  return nonRecursive(Mul->getOperand(0)) && nonRecursive(Mul->getOperand(1)) &&
+    (OrZero || isKnownNonZero(S));
----------------
nikic wrote:

```suggestion
  auto *Mul = dyn_cast<SCEVMulExpr>(S);
  if (!Mul)
    return false;
  return all_of(Mul->operands(), NonRecursive) &&
    (OrZero || isKnownNonZero(S));
```
I think it's fine to drop the two operand limitation here.

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


More information about the llvm-commits mailing list