[backport gcc-4.8/trunk r195888 ] gcc/ 2013-02-08 Jakub Jelinek PR tree-optimization/56250 * fold-const.c (extract_muldiv_1) : Don't optimize if type is unsigned and code isn't MULT_EXPR. gcc/testsuite/ 2013-02-08 Jakub Jelinek PR tree-optimization/56250 * gcc.c-torture/execute/pr56250.c: New test. --- gcc-4.7.2/gcc/fold-const.c.~1~ 2012-06-01 19:03:19.000000000 +0200 +++ gcc-4.7.2/gcc/fold-const.c 2013-02-10 13:13:55.817721925 +0100 @@ -5701,6 +5701,11 @@ extract_muldiv_1 (tree t, tree c, enum t break; /* FALLTHROUGH */ case NEGATE_EXPR: + /* For division and modulus, type can't be unsigned, as e.g. + (-(x / 2U)) / 2U isn't equal to -((x / 2U) / 2U) for x >= 2. + For signed types, even with wrapping overflow, this is fine. */ + if (code != MULT_EXPR && TYPE_UNSIGNED (type)) + break; if ((t1 = extract_muldiv (op0, c, code, wide_type, strict_overflow_p)) != 0) return fold_build1 (tcode, ctype, fold_convert (ctype, t1)); --- gcc-4.7.2/gcc/testsuite/gcc.c-torture/execute/pr56250.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.7.2/gcc/testsuite/gcc.c-torture/execute/pr56250.c 2013-02-10 13:13:55.827721889 +0100 @@ -0,0 +1,13 @@ +/* PR tree-optimization/56250 */ + +extern void abort (void); + +int +main () +{ + unsigned int x = 2; + unsigned int y = (0U - x / 2) / 2; + if (-1U / x != y) + abort (); + return 0; +}