aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.target/i386/pr55590-1.c27
-rw-r--r--gcc/testsuite/gcc.target/i386/pr55590-2.c27
-rw-r--r--gcc/tree-sra.c24
5 files changed, 71 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 99b86be..6a4a773 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,8 @@
-2012-12-06 Jason Merrill <jason@redhat.com>
+2012-12-07 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/55590
+ * tree-sra.c (build_ref_for_offset): Use get_object_alignment_1 to
+ get base alignment.
2012-12-06 Uros Bizjak <ubizjak@gmail.com>
H.J. Lu <hongjiu.lu@intel.com>
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index bb35d25..d50d73b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2012-12-07 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/55590
+ * gcc.target/i386/pr55590-1.c: New test.
+ * gcc.target/i386/pr55590-2.c: Likewise.
+
2012-12-07 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/54975
diff --git a/gcc/testsuite/gcc.target/i386/pr55590-1.c b/gcc/testsuite/gcc.target/i386/pr55590-1.c
new file mode 100644
index 0000000..a8dd912
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr55590-1.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx" } */
+
+#include <immintrin.h>
+
+struct S
+{
+ __m128 a, b;
+};
+
+struct T
+{
+ int a;
+ struct S s;
+};
+
+
+void foo (struct T *p, __m128 v)
+{
+ struct S s;
+
+ s = p->s;
+ s.b = _mm_add_ps(s.b, v);
+ p->s = s;
+}
+
+/* { dg-final { scan-assembler-not "vmovups" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr55590-2.c b/gcc/testsuite/gcc.target/i386/pr55590-2.c
new file mode 100644
index 0000000..afc0a63
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr55590-2.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx" } */
+
+#include <immintrin.h>
+
+struct S
+{
+ __m128 a, b;
+};
+
+struct T
+{
+ int a;
+ struct S s[8];
+};
+
+
+void foo (struct T *p, int i, __m128 v)
+{
+ struct S s;
+
+ s = p->s[i];
+ s.b = _mm_add_ps(s.b, v);
+ p->s[i] = s;
+}
+
+/* { dg-final { scan-assembler-not "vmovups" } } */
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 4580ad2..21d8a51 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -1423,7 +1423,10 @@ make_fancy_name (tree expr)
EXP_TYPE at the given OFFSET. If BASE is something for which
get_addr_base_and_unit_offset returns NULL, gsi must be non-NULL and is used
to insert new statements either before or below the current one as specified
- by INSERT_AFTER. This function is not capable of handling bitfields. */
+ by INSERT_AFTER. This function is not capable of handling bitfields.
+
+ BASE must be either a declaration or a memory reference that has correct
+ alignment ifformation embeded in it (e.g. a pre-existing one in SRA). */
tree
build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
@@ -1437,7 +1440,7 @@ build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
unsigned int align;
gcc_checking_assert (offset % BITS_PER_UNIT == 0);
-
+ get_object_alignment_1 (base, &align, &misalign);
base = get_addr_base_and_unit_offset (base, &base_offset);
/* get_addr_base_and_unit_offset returns NULL for references with a variable
@@ -1476,22 +1479,7 @@ build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
base = build_fold_addr_expr (unshare_expr (base));
}
- /* If prev_base were always an originally performed access
- we can extract more optimistic alignment information
- by looking at the access mode. That would constrain the
- alignment of base + base_offset which we would need to
- adjust according to offset. */
- if (!get_pointer_alignment_1 (base, &align, &misalign))
- {
- gcc_assert (misalign == 0);
- if (TREE_CODE (prev_base) == MEM_REF
- || TREE_CODE (prev_base) == TARGET_MEM_REF)
- align = TYPE_ALIGN (TREE_TYPE (prev_base));
- }
- misalign += (tree_to_double_int (off)
- .sext (TYPE_PRECISION (TREE_TYPE (off))).low
- * BITS_PER_UNIT);
- misalign = misalign & (align - 1);
+ misalign = (misalign + offset) & (align - 1);
if (misalign != 0)
align = (misalign & -misalign);
if (align < TYPE_ALIGN (exp_type))