aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vect-data-refs.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2016-11-07 08:05:08 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2016-11-07 08:05:08 +0000
commita0d3edf8a54e30d48f61eb59a0be33c7ed2b971f (patch)
treeef5f5054bbe0f2fc255f9f42ab020ae3580c96fa /gcc/tree-vect-data-refs.c
parente34b855ed55fc5bb99aeaf013c64db98eb333ca0 (diff)
downloadgcc-a0d3edf8a54e30d48f61eb59a0be33c7ed2b971f.zip
gcc-a0d3edf8a54e30d48f61eb59a0be33c7ed2b971f.tar.gz
gcc-a0d3edf8a54e30d48f61eb59a0be33c7ed2b971f.tar.bz2
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 <rguenther@suse.de> 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
Diffstat (limited to 'gcc/tree-vect-data-refs.c')
-rw-r--r--gcc/tree-vect-data-refs.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 9346cfe..b03cb1e 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;