https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81065
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org --- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- Oh, and I think it's fine to always distribute CST * (x * CST1 + CST2) in case x * CST1 and CST2 have the same sign. So the previous fix was incomplete and we now hit /* If we were able to eliminate our operation from the first side, apply our operation to the second side and reform the PLUS. */ if (t1 != 0 && (TREE_CODE (t1) != code || code == MULT_EXPR)) return fold_build2 (tcode, ctype, fold_convert (ctype, t1), op1); where the code immediately following it is correct: /* The last case is if we are a multiply. In that case, we can apply the distributive law to commute the multiply and addition if the multiplication of the constants doesn't overflow and overflow is defined. With undefined overflow op0 * c might overflow, while (op0 + orig_op1) * c doesn't. */ if (code == MULT_EXPR && TYPE_OVERFLOW_WRAPS (ctype)) return fold_build2 (tcode, ctype, fold_build2 (code, ctype, fold_convert (ctype, op0), fold_convert (ctype, c)), op1); Mine. Testing Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 249112) +++ gcc/fold-const.c (working copy) @@ -6243,7 +6243,7 @@ extract_muldiv_1 (tree t, tree c, enum t /* If we were able to eliminate our operation from the first side, apply our operation to the second side and reform the PLUS. */ - if (t1 != 0 && (TREE_CODE (t1) != code || code == MULT_EXPR)) + if (t1 != 0 && TREE_CODE (t1) != code) return fold_build2 (tcode, ctype, fold_convert (ctype, t1), op1); /* The last case is if we are a multiply. In that case, we can