aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2015-03-05 09:14:01 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2015-03-05 09:14:01 +0000
commitb162e1e749b8c7cb567e5f38bbc461d77c9f8439 (patch)
treee5dfb81be4531429f97f92096b41772275a9c87e
parent637e43b8e1b2d18f51f6d18714cb794717ced3c4 (diff)
downloadgcc-b162e1e749b8c7cb567e5f38bbc461d77c9f8439.zip
gcc-b162e1e749b8c7cb567e5f38bbc461d77c9f8439.tar.gz
gcc-b162e1e749b8c7cb567e5f38bbc461d77c9f8439.tar.bz2
re PR tree-optimization/65310 (vectorizer uses wrong alignment)
2015-03-05 Richard Biener <rguenther@suse.de> PR tree-optimization/65310 * tree-vect-data-refs.c (vect_compute_data_ref_alignment): Properly preserve alignment of the base of the access. * gcc.dg/vect/pr65310.c: New testcase. From-SVN: r221206
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr65310.c23
-rw-r--r--gcc/tree-vect-data-refs.c51
4 files changed, 58 insertions, 27 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a50a378..2d5e245 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
2015-03-05 Richard Biener <rguenther@suse.de>
+ PR tree-optimization/65310
+ * tree-vect-data-refs.c (vect_compute_data_ref_alignment):
+ Properly preserve alignment of the base of the access.
+
+2015-03-05 Richard Biener <rguenther@suse.de>
+
PR ipa/65270
* ipa-icf-gimple.c (func_checker::compare_memory_operand):
Compare dependence info.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 937afa5..77da7e9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2015-03-05 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/65310
+ * gcc.dg/vect/pr65310.c: New testcase.
+
2015-03-05 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/64834
diff --git a/gcc/testsuite/gcc.dg/vect/pr65310.c b/gcc/testsuite/gcc.dg/vect/pr65310.c
new file mode 100644
index 0000000..2fd51b4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr65310.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+
+struct a
+{
+ int a[100];
+};
+typedef struct a b __attribute__ ((aligned (32)));
+typedef struct a c __attribute__ ((aligned (8)));
+
+int t(b *a)
+{
+ int i;
+ c *ptr = a;
+ for (i=0;i<100;i++)
+ ptr->a[i]++;
+}
+
+/* The memory access is through a pointer of type c which means
+ *ptr is not aligned. */
+
+/* { dg-final { scan-tree-dump "can't force alignment" "vect" } } */
+/* { dg-final { scan-tree-dump-not "misalign = 0" "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 2c74060..ffe83e2 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -650,7 +650,8 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
tree base, base_addr;
bool base_aligned;
tree misalign;
- tree aligned_to, alignment;
+ tree aligned_to;
+ unsigned HOST_WIDE_INT alignment;
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,
@@ -720,36 +721,43 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
}
}
- base = build_fold_indirect_ref (base_addr);
- alignment = ssize_int (TYPE_ALIGN (vectype)/BITS_PER_UNIT);
+ alignment = TYPE_ALIGN_UNIT (vectype);
- if ((aligned_to && tree_int_cst_compare (aligned_to, alignment) < 0)
+ if ((compare_tree_int (aligned_to, alignment) < 0)
|| !misalign)
{
if (dump_enabled_p ())
{
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
"Unknown alignment for access: ");
- dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, base);
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, ref);
dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
}
return true;
}
- if ((DECL_P (base)
- && tree_int_cst_compare (ssize_int (DECL_ALIGN_UNIT (base)),
- alignment) >= 0)
- || (TREE_CODE (base_addr) == SSA_NAME
- && tree_int_cst_compare (ssize_int (TYPE_ALIGN_UNIT (TREE_TYPE (
- TREE_TYPE (base_addr)))),
- alignment) >= 0)
- || (get_pointer_alignment (base_addr) >= TYPE_ALIGN (vectype)))
+ /* 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)
{
+ /* Strip an inner MEM_REF to a bare decl if possible. */
+ if (TREE_CODE (base) == MEM_REF
+ && integer_zerop (TREE_OPERAND (base, 1))
+ && TREE_CODE (TREE_OPERAND (base, 0)) == ADDR_EXPR)
+ base = TREE_OPERAND (TREE_OPERAND (base, 0), 0);
+
/* Do not change the alignment of global variables here if
flag_section_anchors is enabled as we already generated
RTL for other functions. Most global variables should
@@ -784,7 +792,7 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
/* If this is a backward running DR then first access in the larger
vectype actually is N-1 elements before the address in the DR.
Adjust misalign accordingly. */
- if (tree_int_cst_compare (DR_STEP (dr), size_zero_node) < 0)
+ if (tree_int_cst_sgn (DR_STEP (dr)) < 0)
{
tree offset = ssize_int (TYPE_VECTOR_SUBPARTS (vectype) - 1);
/* DR_STEP(dr) is the same as -TYPE_SIZE of the scalar type,
@@ -794,19 +802,8 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
misalign = size_binop (PLUS_EXPR, misalign, offset);
}
- /* Modulo alignment. */
- misalign = size_binop (FLOOR_MOD_EXPR, misalign, alignment);
-
- if (!tree_fits_uhwi_p (misalign))
- {
- /* Negative or overflowed misalignment value. */
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "unexpected misalign value\n");
- return false;
- }
-
- SET_DR_MISALIGNMENT (dr, tree_to_uhwi (misalign));
+ SET_DR_MISALIGNMENT (dr,
+ wi::mod_floor (misalign, alignment, SIGNED).to_uhwi ());
if (dump_enabled_p ())
{