diff options
author | Richard Biener <rguenther@suse.de> | 2015-08-03 07:13:36 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2015-08-03 07:13:36 +0000 |
commit | 52639a61657c667c68a4a3e0656a67ed1a95a9b0 (patch) | |
tree | 03864e5caa088bc8f553b9ca5791287f5d2b5a45 /gcc/tree-vect-data-refs.c | |
parent | 94b8fdccca7aa703f4cafc57eef3a7f8776e1290 (diff) | |
download | gcc-52639a61657c667c68a4a3e0656a67ed1a95a9b0.zip gcc-52639a61657c667c68a4a3e0656a67ed1a95a9b0.tar.gz gcc-52639a61657c667c68a4a3e0656a67ed1a95a9b0.tar.bz2 |
re PR tree-optimization/66917 (ARM: NEON: memcpy compiles to vst1 with incorrect alignment)
2015-08-03 Richard Biener <rguenther@suse.de>
PR tree-optimization/66917
* tree-vectorizer.h (struct dataref_aux): Add base_element_aligned
field.
(DR_VECT_AUX): New macro.
(set_dr_misalignment): Adjust.
(dr_misalignment): Likewise.
* tree-vect-data-refs.c (vect_compute_data_ref_alignment):
Compute whether the base is at least element aligned.
* tree-vect-stmts.c (ensure_base_align): Adjust.
(vectorizable_store): If the base is not element aligned
preserve alignment of the original access if misalignment is unknown.
(vectorizable_load): Likewise.
From-SVN: r226487
Diffstat (limited to 'gcc/tree-vect-data-refs.c')
-rw-r--r-- | gcc/tree-vect-data-refs.c | 35 |
1 files changed, 17 insertions, 18 deletions
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 731fe7d..80df9df 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -622,7 +622,6 @@ vect_compute_data_ref_alignment (struct data_reference *dr) tree ref = DR_REF (dr); tree vectype; tree base, base_addr; - bool base_aligned; tree misalign = NULL_TREE; tree aligned_to; unsigned HOST_WIDE_INT alignment; @@ -698,6 +697,19 @@ vect_compute_data_ref_alignment (struct data_reference *dr) } } + /* To look at alignment of the base we have to preserve an inner MEM_REF + as that carries alignment information of the actual access. */ + base = ref; + while (handled_component_p (base)) + base = TREE_OPERAND (base, 0); + 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); + + if (base_alignment >= TYPE_ALIGN (TREE_TYPE (vectype))) + DR_VECT_AUX (dr)->base_element_aligned = true; + alignment = TYPE_ALIGN_UNIT (vectype); if ((compare_tree_int (aligned_to, alignment) < 0) @@ -713,21 +725,7 @@ vect_compute_data_ref_alignment (struct data_reference *dr) return true; } - /* To look at alignment of the base we have to preserve an inner MEM_REF - as that carries alignment information of the actual access. */ - base = ref; - while (handled_component_p (base)) - base = TREE_OPERAND (base, 0); - 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)); - - if (get_object_alignment (base) >= TYPE_ALIGN (vectype)) - base_aligned = true; - else - base_aligned = false; - - if (!base_aligned) + if (base_alignment < TYPE_ALIGN (vectype)) { /* Strip an inner MEM_REF to a bare decl if possible. */ if (TREE_CODE (base) == MEM_REF @@ -757,8 +755,9 @@ vect_compute_data_ref_alignment (struct data_reference *dr) dump_printf (MSG_NOTE, "\n"); } - ((dataref_aux *)dr->aux)->base_decl = base; - ((dataref_aux *)dr->aux)->base_misaligned = true; + DR_VECT_AUX (dr)->base_decl = base; + DR_VECT_AUX (dr)->base_misaligned = true; + DR_VECT_AUX (dr)->base_element_aligned = true; } /* If this is a backward running DR then first access in the larger |