From: Richard Biener Date: Mon, 7 Nov 2016 08:05:08 +0000 (+0000) Subject: re PR tree-optimization/78189 (movaps generated for unaligned store in aligned struct... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a0d3edf8a54e30d48f61eb59a0be33c7ed2b971f;p=gcc.git re PR tree-optimization/78189 (movaps generated for unaligned store in aligned struct, when struct is referenced via unaligned member.) 2016-11-07 Richard Biener PR tree-optimization/78189 * tree-vect-data-refs.c (vect_compute_data_ref_alignment): Fix alignment computation. * g++.dg/torture/pr78189.C: New testcase. From-SVN: r241892 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 71f3066c2db..960ea67b0bc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-11-07 Richard Biener + + PR tree-optimization/78189 + * tree-vect-data-refs.c (vect_compute_data_ref_alignment): Fix + alignment computation. + 2016-11-06 Kugan Vivekanandarajah * ipa-cp.c (ipcp_bits_lattice::meet_with): Remove unreachable code. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0a88fcd75c6..e0a1c8e77a5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-11-07 Richard Biener + + PR tree-optimization/78189 + * g++.dg/torture/pr78189.C: New testcase. + 2016-11-06 David Edelsohn * gcc.dg/Wtrampolines.c: XFAIL AIX. diff --git a/gcc/testsuite/g++.dg/torture/pr78189.C b/gcc/testsuite/g++.dg/torture/pr78189.C new file mode 100644 index 00000000000..9b65d2b5a63 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr78189.C @@ -0,0 +1,41 @@ +/* { dg-do run } */ +/* { dg-additional-options "-ftree-slp-vectorize -fno-vect-cost-model" } */ + +#include + +struct A +{ + void * a; + void * b; +}; + +struct alignas(16) B +{ + void * pad; + void * misaligned; + void * pad2; + + A a; + + void Null(); +}; + +void B::Null() +{ + a.a = nullptr; + a.b = nullptr; +} + +void __attribute__((noinline,noclone)) +NullB(void * misalignedPtr) +{ + B* b = reinterpret_cast(reinterpret_cast(misalignedPtr) - offsetof(B, misaligned)); + b->Null(); +} + +int main() +{ + B b; + NullB(&b.misaligned); + return 0; +} diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 9346cfeafd2..b03cb1ec637 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -773,10 +773,25 @@ vect_compute_data_ref_alignment (struct data_reference *dr) base = ref; while (handled_component_p (base)) base = TREE_OPERAND (base, 0); + unsigned int base_alignment; + unsigned HOST_WIDE_INT base_bitpos; + get_object_alignment_1 (base, &base_alignment, &base_bitpos); + /* As data-ref analysis strips the MEM_REF down to its base operand + to form DR_BASE_ADDRESS and adds the offset to DR_INIT we have to + adjust things to make base_alignment valid as the alignment of + DR_BASE_ADDRESS. */ if (TREE_CODE (base) == MEM_REF) - base = build2 (MEM_REF, TREE_TYPE (base), base_addr, - build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)), 0)); - unsigned int base_alignment = get_object_alignment (base); + { + base_bitpos -= mem_ref_offset (base).to_short_addr () * BITS_PER_UNIT; + base_bitpos &= (base_alignment - 1); + } + if (base_bitpos != 0) + base_alignment = base_bitpos & -base_bitpos; + /* Also look at the alignment of the base address DR analysis + computed. */ + unsigned int base_addr_alignment = get_pointer_alignment (base_addr); + if (base_addr_alignment > base_alignment) + base_alignment = base_addr_alignment; if (base_alignment >= TYPE_ALIGN (TREE_TYPE (vectype))) DR_VECT_AUX (dr)->base_element_aligned = true;