From b162e1e749b8c7cb567e5f38bbc461d77c9f8439 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 5 Mar 2015 09:14:01 +0000 Subject: [PATCH] re PR tree-optimization/65310 (vectorizer uses wrong alignment) 2015-03-05 Richard Biener 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 --- gcc/ChangeLog | 6 ++++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.dg/vect/pr65310.c | 23 +++++++++++++ gcc/tree-vect-data-refs.c | 51 ++++++++++++++--------------- 4 files changed, 58 insertions(+), 27 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/pr65310.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a50a378044e..2d5e2457a4e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-03-05 Richard Biener + + 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 PR ipa/65270 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 937afa58a36..77da7e936fb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-03-05 Richard Biener + + PR tree-optimization/65310 + * gcc.dg/vect/pr65310.c: New testcase. + 2015-03-05 Paolo Carlini 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 00000000000..2fd51b4d23b --- /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 2c74060d793..ffe83e2b2f3 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 ()) { -- 2.30.2