[backport gcc-4.8.1 r197693 ] gcc/ 2013-04-11 Jakub Jelinek PR tree-optimization/56899 * fold-const.c (extract_muldiv_1): Apply distributive law only if TYPE_OVERFLOW_WRAPS (ctype). gcc/testsuite/ 2013-04-11 Jakub Jelinek PR tree-optimization/56899 * gcc.c-torture/execute/pr56899.c: New test. --- gcc-4.7.3/gcc/fold-const.c.~1~ 2013-02-19 18:26:04.000000000 +0100 +++ gcc-4.7.3/gcc/fold-const.c 2013-05-12 13:20:01.225667903 +0200 @@ -5859,8 +5859,10 @@ extract_muldiv_1 (tree t, tree c, enum t /* 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. */ - if (code == MULT_EXPR) + 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), --- gcc-4.7.3/gcc/testsuite/gcc.c-torture/execute/pr56899.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.7.3/gcc/testsuite/gcc.c-torture/execute/pr56899.c 2013-05-12 13:20:01.225667903 +0200 @@ -0,0 +1,47 @@ +/* PR tree-optimization/56899 */ + +#if __SIZEOF_INT__ == 4 && __CHAR_BIT__ == 8 +__attribute__((noinline, noclone)) void +f1 (int v) +{ + int x = -214748365 * (v - 1); + if (x != -1932735285) + __builtin_abort (); +} + +__attribute__((noinline, noclone)) void +f2 (int v) +{ + int x = 214748365 * (v + 1); + if (x != -1932735285) + __builtin_abort (); +} + +__attribute__((noinline, noclone)) void +f3 (unsigned int v) +{ + unsigned int x = -214748365U * (v - 1); + if (x != -1932735285U) + __builtin_abort (); +} + +__attribute__((noinline, noclone)) void +f4 (unsigned int v) +{ + unsigned int x = 214748365U * (v + 1); + if (x != -1932735285U) + __builtin_abort (); +} +#endif + +int +main () +{ +#if __SIZEOF_INT__ == 4 && __CHAR_BIT__ == 8 + f1 (10); + f2 (-10); + f3 (10); + f4 (-10U); +#endif + return 0; +}