https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114074

--- Comment #10 from Richard Biener <rguenth at gcc dot gnu.org> ---
Some thoughts on the CHREC folding, in the context of the many reported
optimization regressions.

We try to handle { a, +, b } * c as { a * c, +, b * c } and the issue is
cases of undefined overflow this exposes.

We have to make sure to not introduce undefined behavior that isn't there

 - at the first evaluation (the first iteration) both expressions behave
   the same with respect to overflow since it's a * c without any increment
 - further evaluations will do ((a + b) + ... + b) * c before and
   (a * c + b * c) + ... + b * c after the transform
 - (a + b) + b doesn't necessarily behave the same as a + 2*b

I'm not sure we can, say, rely on a * c not invoking undefined overflow
since we do not know whether the expression will be evaluated at runtime
and whether SCEV analysis properly handles conditional execution in this
regard (it just follows the data dependence graph).

For the fix I've looked at the simplest part, when does (a + b) * c possibly
not overflow but a * c or b * c does?  Only when a + b has smaller magnitude
than a or b which should mean a and b have to have opposite sign.  Without
proving I think (a + b + b) * c vs. a * c + b * c + b * c doesn't add
anything, thus the addition can be ignored and just the multiplication matters.

When in the future maybe adding 'assumptions' to SCEV results we could
unconditionally do the simplification but register an appropriate
assumption that needs to hold (and which we could check at runtime).
At runtime it's probably enough to verify that b * c does not overflow,
the evaluation of a * c should be guarded.

Reply via email to