From 3ebde0e9e3028aded82176416029ef79e0423082 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Fri, 15 Jun 2012 13:30:36 +0000 Subject: [PATCH] re PR tree-optimization/53636 (SLP may create invalid unaligned memory accesses) gcc/ PR tree-optimization/53636 * tree-vect-data-refs.c (vect_compute_data_ref_alignment): Verify stride when doing basic-block vectorization. gcc/testsuite/ PR tree-optimization/53636 * gcc.target/arm/pr53636.c: New test. From-SVN: r188661 --- gcc/ChangeLog | 6 ++++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.target/arm/pr53636.c | 48 ++++++++++++++++++++++++++ gcc/tree-vect-data-refs.c | 18 ++++++++++ 4 files changed, 77 insertions(+) create mode 100644 gcc/testsuite/gcc.target/arm/pr53636.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5ce784a4c0e..99e290433f5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-06-15 Ulrich Weigand + + PR tree-optimization/53636 + * tree-vect-data-refs.c (vect_compute_data_ref_alignment): Verify + stride when doing basic-block vectorization. + 2012-06-15 Ramana Radhakrishnan * tree-vect-generic.c (lower_vec_perm): Propagate vector constants diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f3d10e3fb5e..ca264c33a3c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-06-15 Ulrich Weigand + + PR tree-optimization/53636 + * gcc.target/arm/pr53636.c: New test. + 2012-06-15 Jakub Jelinek PR tree-optimization/51581 diff --git a/gcc/testsuite/gcc.target/arm/pr53636.c b/gcc/testsuite/gcc.target/arm/pr53636.c new file mode 100644 index 00000000000..dbad7957e54 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr53636.c @@ -0,0 +1,48 @@ +/* { dg-do run } */ +/* { dg-require-effective-target arm_neon_hw } */ +/* { dg-options "-O -ftree-vectorize" } */ +/* { dg-add-options arm_neon } */ + +void fill (short *buf) __attribute__ ((noinline)); +void fill (short *buf) +{ + int i; + + for (i = 0; i < 11 * 8; i++) + buf[i] = i; +} + +void test (unsigned char *dst) __attribute__ ((noinline)); +void test (unsigned char *dst) +{ + short tmp[11 * 8], *tptr; + int i; + + fill (tmp); + + tptr = tmp; + for (i = 0; i < 8; i++) + { + dst[0] = (-tptr[0] + 9 * tptr[0 + 1] + 9 * tptr[0 + 2] - tptr[0 + 3]) >> 7; + dst[1] = (-tptr[1] + 9 * tptr[1 + 1] + 9 * tptr[1 + 2] - tptr[1 + 3]) >> 7; + dst[2] = (-tptr[2] + 9 * tptr[2 + 1] + 9 * tptr[2 + 2] - tptr[2 + 3]) >> 7; + dst[3] = (-tptr[3] + 9 * tptr[3 + 1] + 9 * tptr[3 + 2] - tptr[3 + 3]) >> 7; + dst[4] = (-tptr[4] + 9 * tptr[4 + 1] + 9 * tptr[4 + 2] - tptr[4 + 3]) >> 7; + dst[5] = (-tptr[5] + 9 * tptr[5 + 1] + 9 * tptr[5 + 2] - tptr[5 + 3]) >> 7; + dst[6] = (-tptr[6] + 9 * tptr[6 + 1] + 9 * tptr[6 + 2] - tptr[6 + 3]) >> 7; + dst[7] = (-tptr[7] + 9 * tptr[7 + 1] + 9 * tptr[7 + 2] - tptr[7 + 3]) >> 7; + + dst += 8; + tptr += 11; + } +} + +int main (void) +{ + char buf [8 * 8]; + + test (buf); + + return 0; +} + diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index ed967f236ad..29dff45482b 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -861,6 +861,24 @@ vect_compute_data_ref_alignment (struct data_reference *dr) } } + /* Similarly, if we're doing basic-block vectorization, we can only use + base and misalignment information relative to an innermost loop if the + misalignment stays the same throughout the execution of the loop. + As above, this is the case if the stride of the dataref evenly divides + by the vector size. */ + if (!loop) + { + tree step = DR_STEP (dr); + HOST_WIDE_INT dr_step = TREE_INT_CST_LOW (step); + + if (dr_step % GET_MODE_SIZE (TYPE_MODE (vectype)) != 0) + { + if (vect_print_dump_info (REPORT_ALIGNMENT)) + fprintf (vect_dump, "SLP: step doesn't divide the vector-size."); + misalign = NULL_TREE; + } + } + base = build_fold_indirect_ref (base_addr); alignment = ssize_int (TYPE_ALIGN (vectype)/BITS_PER_UNIT); -- 2.30.2