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

--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> ---
In fact SCEV does, in chrec_fold_multiply for a mixed multiplication:

          return build_polynomial_chrec
            (CHREC_VARIABLE (op0),
             chrec_fold_multiply (type, CHREC_LEFT (op0), op1),
             chrec_fold_multiply (type, CHREC_RIGHT (op0), op1));

but that's (a + b) * c -> a * c + b * c which does not preserve overflow
behavior and thus isn't valid when the result is a signed CHREC with
undefined behavior on overflow and 'a + b' evaluates to 0, 1 or -1 as is
the case here with a == -1 and b == 2.  In the SCEV case it's OK to
do CHREC_LEFT * op1 but CHREC_RIGHT * op1 may not be evaluated this way.

fold-const.cc:fold_plusminus_mult deals with this by doing the multiplications
and addition in unsigned.

The exception we can definitely make is when for {a, +, b}_1 a and b have
the same sign or a is zero.  I'm not sure we can generally handle any
other case - we are already special-casing c == 0 and c == 1.

Reply via email to