From cf1867a027259b46b63abed5f6e34b479d52f186 Mon Sep 17 00:00:00 2001
From: Richard Guenther <rguenther@suse.de>
Date: Fri, 16 Mar 2012 11:48:48 +0000
Subject: [PATCH] re PR middle-end/48814 (Incorrect scalar increment result)

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.

	* 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.

Co-Authored-By: Kai Tietz <ktietz@redhat.com>

From-SVN: r185465
---
 gcc/ChangeLog                                 |  8 +++++++
 gcc/gimplify.c                                |  9 +++----
 gcc/testsuite/ChangeLog                       | 10 ++++++++
 .../gcc.c-torture/execute/pr48814-1.c         | 18 ++++++++++++++
 .../gcc.c-torture/execute/pr48814-2.c         | 18 ++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/assign-1.c      | 12 ++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/assign-2.c      | 13 ++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/assign-3.c      | 24 +++++++++++++++++++
 8 files changed, 108 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr48814-1.c
 create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr48814-2.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/assign-1.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/assign-2.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/assign-3.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c8272188caa1..e18d220975f0 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 07eb8fd81df0..3c412944e334 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 eddbface0f98..ba1e455391a4 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 000000000000..452aaab30f95
--- /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 000000000000..9eea3289ab1a
--- /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 000000000000..f95f03ff4286
--- /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 000000000000..47c38225b67b
--- /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 000000000000..e5426d781e59
--- /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" } } */
-- 
GitLab