aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vect-data-refs.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2015-08-03 07:13:36 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2015-08-03 07:13:36 +0000
commit52639a61657c667c68a4a3e0656a67ed1a95a9b0 (patch)
tree03864e5caa088bc8f553b9ca5791287f5d2b5a45 /gcc/tree-vect-data-refs.c
parent94b8fdccca7aa703f4cafc57eef3a7f8776e1290 (diff)
downloadgcc-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.c35
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