[llvm] [SCEVDivision] Prevent propagation of incorrect no-wrap flags (PR #154745)

Ryotaro Kasuga via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 21 06:43:14 PDT 2025


kasuga-fj wrote:

> > In `SCEVDivision`, when the numerator is `SCEVAddRecExpr`, its no-wrap flags were propagated to the quotient and remainder. In general, it is incorrect. For example, consider dividing `{0,+,(%m * %n)}<nuw><nsw><%loop>` by `%m`. The quotient would be `{0,+,1}<%loop>` and the remainder would be `{0,+,%n}<%loop>`.
> 
> Was this example supposed to be `{%n,+,%m}<nuw><nsw><%loop>`?

Sorry, the description is somewhat wrong... I'm reconsidering about it. 

> Is the invariant here that it gives you an expression of type `Q*Numerator + R`, but _without_ the normal requirement that `R < Numerator`?

Yes, I think. Maybe it's a bit different from the common integer division.

> For the nowrap flags, I think you can justify preserving `nuw` because division should make everything strictly smaller in an unsigned sense. So if it did not wrap with larger values, it should not wrap with smaller ones. The caveat here is that this is not correct for division by zero. We can't preserve flags for a possible division by zero.

(I'm probably wrong about this, but) Even in unsigned division, what happens `{0,+,(%m * %n)}<nuw><%loop>` dividing by `%m` and `(%m * %n)` is wrapping? Or does SCEV guarantee that `%m * %n` does't wrap?



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


More information about the llvm-commits mailing list