diff options
author | Martin Jambor <mjambor@suse.cz> | 2012-12-07 13:50:43 +0100 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2012-12-07 13:50:43 +0100 |
commit | 4bd7b70b8954bb935a3b88ffa70f384552cc6fb3 (patch) | |
tree | d07f6d3b5a64e67856103436b1ad8de49a207b82 | |
parent | a09b3c50dd4ab7df41376abae0fe5f07cc172e07 (diff) | |
download | gcc-4bd7b70b8954bb935a3b88ffa70f384552cc6fb3.zip gcc-4bd7b70b8954bb935a3b88ffa70f384552cc6fb3.tar.gz gcc-4bd7b70b8954bb935a3b88ffa70f384552cc6fb3.tar.bz2 |
re PR tree-optimization/55590 (SRA still produces unnecessarily unaligned memory accesses)
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.
* testsuite/gcc.target/i386/pr55590-1.c: New test.
* testsuite/gcc.target/i386/pr55590-2.c: Likewise.
From-SVN: r194300
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr55590-1.c | 27 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr55590-2.c | 27 | ||||
-rw-r--r-- | gcc/tree-sra.c | 24 |
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)) |