From 75a75e91fdd362c68e552a9e2bb5c0469e4e70af Mon Sep 17 00:00:00 2001
From: Martin Jambor <mjambor@suse.cz>
Date: Wed, 21 Jul 2010 16:17:11 +0200
Subject: [PATCH] re PR tree-optimization/44900 (The variable of SSE will be
 broken)

2010-07-21  Martin Jambor  <mjambor@suse.cz>

	PR tree-optimization/44900
	* tree-sra.c (load_assign_lhs_subreplacements): Updated comments.
	(sra_modify_assign): Move gsi to the next statmenent unconditionally.

	* testsuite/g++.dg/torture/pr44900.C: New test.

From-SVN: r162375
---
 gcc/ChangeLog                          |  6 ++
 gcc/testsuite/ChangeLog                |  5 ++
 gcc/testsuite/g++.dg/torture/pr44900.C | 76 ++++++++++++++++++++++++++
 gcc/tree-sra.c                         | 12 ++--
 4 files changed, 93 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/torture/pr44900.C

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4b7045179b4d..517ff7462897 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2010-07-21  Martin Jambor  <mjambor@suse.cz>
+
+	PR tree-optimization/44900
+	* tree-sra.c (load_assign_lhs_subreplacements): Updated comments.
+	(sra_modify_assign): Move gsi to the next statmenent unconditionally.
+
 2010-07-21  Bernd Schmidt  <bernds@codesourcery.com>
 
 	PR middle-end/44738
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 56aba5fd6eba..a6555a898968 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2010-07-21  Martin Jambor  <mjambor@suse.cz>
+
+	PR tree-optimization/44900
+	* g++.dg/torture/pr44900.C: New test.
+
 2010-07-21  Bernd Schmidt  <bernds@codesourcery.com>
 
 	PR middle-end/44738
diff --git a/gcc/testsuite/g++.dg/torture/pr44900.C b/gcc/testsuite/g++.dg/torture/pr44900.C
new file mode 100644
index 000000000000..5c0efcb4b4eb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr44900.C
@@ -0,0 +1,76 @@
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-msse" } */
+/* { dg-require-effective-target sse } */
+
+typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__));
+typedef float __v4sf __attribute__ ((__vector_size__ (16)));
+
+extern __inline __m128 __attribute__((__gnu_inline__, __always_inline__,
+__artificial__))
+_mm_set_ps (const float __Z, const float __Y, const float __X, const float __W)
+{
+  return __extension__ (__m128)(__v4sf){ __W, __X, __Y, __Z };
+}
+
+struct vec
+{
+        union {
+                __m128 v;
+                float  e[4];
+        };
+
+        static const vec & zero()
+        {
+                static const vec v = _mm_set_ps(0, 0, 0, 0);
+                return v;
+        }
+
+        vec() {}
+        vec(const __m128 & a) : v(a) {}
+
+        operator const __m128&() const { return v; }
+};
+
+struct vec2
+{
+        vec _v1;
+        vec _v2;
+
+        vec2() {}
+        vec2(const vec & a, const vec & b) : _v1(a), _v2(b) {}
+
+        static vec2 load(const float * a)
+        {
+                return vec2(
+                        __builtin_ia32_loadups(&a[0]),
+                        __builtin_ia32_loadups(&a[4]));
+        }
+
+        const vec & v1() const { return _v1; }
+        const vec & v2() const { return _v2; }
+};
+
+extern "C" void abort(void);
+
+
+inline bool operator==(const vec & a, const vec & b)
+{ return 0xf == __builtin_ia32_movmskps(__builtin_ia32_cmpeqps(a, b)); }
+
+int main( int argc, char * argv[] )
+{
+        __attribute__((aligned(16))) float data[] =
+        { 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5 };
+
+        float * p = &data[2];
+        vec2 a;
+
+        a = vec2::load(p);
+
+        vec v1 = a.v1();
+        vec v2 = a.v2();
+
+	if (v2.e[3] != 7.0)
+	  abort();
+
+        return 0;
+}
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index e4971d2385b7..9fd6d2cc5922 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -2416,9 +2416,11 @@ handle_unscalarized_data_in_subtree (struct access *top_racc, tree lhs,
    (sub)tree.  If that is not possible, refresh the TOP_RACC base aggregate and
    load the accesses from it.  LEFT_OFFSET is the offset of the left whole
    subtree being copied, RIGHT_OFFSET is the same thing for the right subtree.
-   GSI is stmt iterator used for statement insertions.  *REFRESHED is true iff
-   the rhs top aggregate has already been refreshed by contents of its scalar
-   reductions and is set to true if this function has to do it.  */
+   NEW_GSI is stmt iterator used for statement insertions after the original
+   assignment, OLD_GSI is used to insert statements before the assignment.
+   *REFRESHED keeps the information whether we have needed to refresh
+   replacements of the LHS and from which side of the assignments this takes
+   place.  */
 
 static void
 load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
@@ -2722,9 +2724,7 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
 					   &orig_gsi, gsi, &refreshed, lhs);
 	  if (refreshed != SRA_UDH_RIGHT)
 	    {
-	      if (*stmt == gsi_stmt (*gsi))
-		gsi_next (gsi);
-
+	      gsi_next (gsi);
 	      unlink_stmt_vdef (*stmt);
 	      gsi_remove (&orig_gsi, true);
 	      sra_stats.deleted++;
-- 
GitLab