[backport from gcc-4.7.1 r188010, sans the restrict-2.c changes ] gcc/ 2012-05-30 Richard Guenther PR middle-end/53501 * fold-const.c (fold_binary_loc): Make sure to call fold_plusminus_mult_expr with the original sign of operands. gcc/testsuite/ 2012-05-30 Richard Guenther PR middle-end/53501 * gcc.dg/torture/pr53501.c: New testcase. * c-c++-common/restrict-2.c: Adjust. --- gcc-4.6.3/gcc/fold-const.c.~1~ 2012-02-27 12:19:03.000000000 +0100 +++ gcc-4.6.3/gcc/fold-const.c 2012-06-09 22:14:21.000000000 +0200 @@ -9647,12 +9647,12 @@ fold_binary_loc (location_t loc, /* Handle (A1 * C1) + (A2 * C2) with A1, A2 or C1, C2 being the same or one. Make sure type is not saturating. fold_plusminus_mult_expr will re-associate. */ - if ((TREE_CODE (arg0) == MULT_EXPR - || TREE_CODE (arg1) == MULT_EXPR) + if ((TREE_CODE (op0) == MULT_EXPR + || TREE_CODE (op1) == MULT_EXPR) && !TYPE_SATURATING (type) && (!FLOAT_TYPE_P (type) || flag_associative_math)) { - tree tem = fold_plusminus_mult_expr (loc, code, type, arg0, arg1); + tree tem = fold_plusminus_mult_expr (loc, code, type, op0, op1); if (tem) return tem; } @@ -10266,12 +10266,12 @@ fold_binary_loc (location_t loc, /* Handle (A1 * C1) - (A2 * C2) with A1, A2 or C1, C2 being the same or one. Make sure type is not saturating. fold_plusminus_mult_expr will re-associate. */ - if ((TREE_CODE (arg0) == MULT_EXPR - || TREE_CODE (arg1) == MULT_EXPR) + if ((TREE_CODE (op0) == MULT_EXPR + || TREE_CODE (op1) == MULT_EXPR) && !TYPE_SATURATING (type) && (!FLOAT_TYPE_P (type) || flag_associative_math)) { - tree tem = fold_plusminus_mult_expr (loc, code, type, arg0, arg1); + tree tem = fold_plusminus_mult_expr (loc, code, type, op0, op1); if (tem) return tem; } --- gcc-4.6.3/gcc/testsuite/gcc.dg/torture/pr53501.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.6.3/gcc/testsuite/gcc.dg/torture/pr53501.c 2012-06-09 22:14:21.000000000 +0200 @@ -0,0 +1,22 @@ +/* { dg-do run } */ + +extern void abort (void); + +int e[100], n, here; + +void __attribute__((noinline)) +foo(void) +{ + int i, k = 0; + for (i = 0; i < n; ++i) { e[k] = 10; ++k; e[k] = 10; ++k; } + for (i = 0; i < k; ++i) here = 1; + if (here != 1) + abort (); +} + +int main(void) +{ + n = 10; + foo(); + return 0; +}