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.