diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c8272188caa1e19f6fda2bb06fb574569cf4f983..e18d220975f00e30dd424fe03b9019e60e1eb664 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2012-03-16 Richard Guenther <rguenther@suse.de> + Kai Tietz <ktietz@redhat.com> + + 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. + 2012-03-16 Richard Guenther <rguenther@suse.de> * stor-layout.c (finish_bitfield_representative): Fall back diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 07eb8fd81df08b76a007c5725568fc4a42367f4d..3c412944e334aaee80fe82f6652f94355c2ffb1f 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -2265,17 +2265,18 @@ gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, 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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index eddbface0f9845dffe864294b58ed67a20558ebd..ba1e455391a43f1994d4226b4a1eb4025e443bac 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2012-03-16 Richard Guenther <rguenther@suse.de> + Kai Tietz <ktietz@redhat.com> + + 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. + 2012-03-16 Richard Guenther <rguenther@suse.de> * gnat.dg/specs/pack7.ads: New testcase. diff --git a/gcc/testsuite/gcc.c-torture/execute/pr48814-1.c b/gcc/testsuite/gcc.c-torture/execute/pr48814-1.c new file mode 100644 index 0000000000000000000000000000000000000000..452aaab30f9593d1116d3d94d7c9b0f46fc76468 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr48814-1.c @@ -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; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr48814-2.c b/gcc/testsuite/gcc.c-torture/execute/pr48814-2.c new file mode 100644 index 0000000000000000000000000000000000000000..9eea3289ab1a594fb254642f08239acf480eff5b --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr48814-2.c @@ -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; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/assign-1.c b/gcc/testsuite/gcc.dg/tree-ssa/assign-1.c new file mode 100644 index 0000000000000000000000000000000000000000..f95f03ff42865ba9de027ff629fd1f834e22a872 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/assign-1.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/assign-2.c b/gcc/testsuite/gcc.dg/tree-ssa/assign-2.c new file mode 100644 index 0000000000000000000000000000000000000000..47c38225b67ba7b398e936edf9c2d805f431e037 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/assign-2.c @@ -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" } } */ + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/assign-3.c b/gcc/testsuite/gcc.dg/tree-ssa/assign-3.c new file mode 100644 index 0000000000000000000000000000000000000000..e5426d781e593f31e98b9b14741b66566bad7a60 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/assign-3.c @@ -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" } } */