[backport from gcc-4.8/trunk r185465 ] gcc/ 2012-03-16 Richard Guenther Kai Tietz PR middle-end/48814 * gimplify.c (gimplify_self_mod_expr): Evaluate postfix side-effects completely in the pre-queue and use a temporary for the result. gcc/testsuite/ 2012-03-16 Richard Guenther Kai Tietz PR middle-end/48814 * gcc.c-torture/execute/pr48814-1.c: New test. * gcc.c-torture/execute/pr48814-2.c: New test. * gcc.dg/tree-ssa/assign-1.c: New test. * gcc.dg/tree-ssa/assign-2.c: New test. * gcc.dg/tree-ssa/assign-3.c: New test. --- gcc-4.7.1/gcc/gimplify.c.~1~ 2012-05-10 17:00:11.000000000 +0200 +++ gcc-4.7.1/gcc/gimplify.c 2012-09-01 22:23:51.000000000 +0200 @@ -2272,17 +2272,18 @@ gimplify_self_mod_expr (tree *expr_p, gi arith_code = POINTER_PLUS_EXPR; } - t1 = build2 (arith_code, TREE_TYPE (*expr_p), lhs, rhs); - if (postfix) { - gimplify_assign (lvalue, t1, orig_post_p); + tree t2 = get_initialized_tmp_var (lhs, pre_p, NULL); + t1 = build2 (arith_code, TREE_TYPE (*expr_p), t2, rhs); + gimplify_assign (lvalue, t1, pre_p); gimplify_seq_add_seq (orig_post_p, post); - *expr_p = lhs; + *expr_p = t2; return GS_ALL_DONE; } else { + t1 = build2 (arith_code, TREE_TYPE (*expr_p), lhs, rhs); *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1); return GS_OK; } --- gcc-4.7.1/gcc/testsuite/gcc.c-torture/execute/pr48814-1.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.7.1/gcc/testsuite/gcc.c-torture/execute/pr48814-1.c 2012-09-01 22:23:51.000000000 +0200 @@ -0,0 +1,18 @@ +extern void abort (void); + +int arr[] = {1,2,3,4}; +int count = 0; + +int __attribute__((noinline)) +incr (void) +{ + return ++count; +} + +int main() +{ + arr[count++] = incr (); + if (count != 2 || arr[count] != 3) + abort (); + return 0; +} --- gcc-4.7.1/gcc/testsuite/gcc.c-torture/execute/pr48814-2.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.7.1/gcc/testsuite/gcc.c-torture/execute/pr48814-2.c 2012-09-01 22:23:51.000000000 +0200 @@ -0,0 +1,18 @@ +extern void abort (void); + +int arr[] = {1,2,3,4}; +int count = 0; + +int +incr (void) +{ + return ++count; +} + +int main() +{ + arr[count++] = incr (); + if (count != 2 || arr[count] != 3) + abort (); + return 0; +} --- gcc-4.7.1/gcc/testsuite/gcc.dg/tree-ssa/assign-1.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.7.1/gcc/testsuite/gcc.dg/tree-ssa/assign-1.c 2012-09-01 22:23:51.000000000 +0200 @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +volatile int count; +void bar(int); +void foo() +{ + bar(count++); +} + +/* { dg-final { scan-tree-dump-times "count =" 1 "optimized"} } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ --- gcc-4.7.1/gcc/testsuite/gcc.dg/tree-ssa/assign-2.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.7.1/gcc/testsuite/gcc.dg/tree-ssa/assign-2.c 2012-09-01 22:23:51.000000000 +0200 @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +volatile int count; +int arr[4]; +void foo() +{ + arr[count++] = 0; +} + +/* { dg-final { scan-tree-dump-times "count =" 1 "optimized"} } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ + --- gcc-4.7.1/gcc/testsuite/gcc.dg/tree-ssa/assign-3.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.7.1/gcc/testsuite/gcc.dg/tree-ssa/assign-3.c 2012-09-01 22:23:51.000000000 +0200 @@ -0,0 +1,24 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fdump-tree-gimple" } */ + +extern void abort (void); +struct S { int i; }; +struct S arr[32]; +volatile int count = 0; + +struct S __attribute__((noinline)) +incr () +{ + ++count; +} + +int main() +{ + arr[count++] = incr (); + if (count != 2) + abort (); + return 0; +} + +/* { dg-final { scan-tree-dump-times " = count;" 3 "gimple" } } */ +/* { dg-final { cleanup-tree-dump "gimple" } } */