From 4bd7b70b8954bb935a3b88ffa70f384552cc6fb3 Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Fri, 7 Dec 2012 13:50:43 +0100 Subject: [PATCH] re PR tree-optimization/55590 (SRA still produces unnecessarily unaligned memory accesses) 2012-12-07 Martin Jambor 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 --- gcc/ChangeLog | 6 ++++- gcc/testsuite/ChangeLog | 6 +++++ gcc/testsuite/gcc.target/i386/pr55590-1.c | 27 +++++++++++++++++++++++ gcc/testsuite/gcc.target/i386/pr55590-2.c | 27 +++++++++++++++++++++++ gcc/tree-sra.c | 24 +++++--------------- 5 files changed, 71 insertions(+), 19 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr55590-1.c create mode 100644 gcc/testsuite/gcc.target/i386/pr55590-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 99b86be1ac4..6a4a7739d29 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,8 @@ -2012-12-06 Jason Merrill +2012-12-07 Martin Jambor + + 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 H.J. Lu diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bb35d251ba3..d50d73b0e9d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2012-12-07 Martin Jambor + + PR tree-optimization/55590 + * gcc.target/i386/pr55590-1.c: New test. + * gcc.target/i386/pr55590-2.c: Likewise. + 2012-12-07 Paolo Carlini 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 00000000000..a8dd91232c5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr55590-1.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mavx" } */ + +#include + +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 00000000000..afc0a6379a8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr55590-2.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mavx" } */ + +#include + +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 4580ad22e64..21d8a514117 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)) -- 2.30.2