From ab313a8c426ebb85411fee580d696537c520cff0 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 16 Jun 2015 10:29:16 +0000 Subject: [PATCH] tree-vect-stmts.c (vectorizable_load): Properly start loads with the first element if this is grouped loads. 2015-06-16 Richard Biener * tree-vect-stmts.c (vectorizable_load): Properly start loads with the first element if this is grouped loads. * gcc.dg/vect/slp-perm-11.c: New testcase. From-SVN: r224511 --- gcc/ChangeLog | 5 ++++ gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.dg/vect/slp-perm-11.c | 35 +++++++++++++++++++++++++ gcc/tree-vect-stmts.c | 26 +++++++++++------- 4 files changed, 60 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/slp-perm-11.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 57a41f7def5..6090a2d029c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2015-06-16 Richard Biener + + * tree-vect-stmts.c (vectorizable_load): Properly start loads + with the first element if this is grouped loads. + 2015-06-16 James Greenhalgh * config/arm/arm-protos.h (struct tune_params): Rename diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a87bb15092e..980363667a1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2015-06-16 Richard Biener + + * gcc.dg/vect/slp-perm-11.c: New testcase. + 2015-06-16 Christophe Lyon * gcc.target/arm/thumb-ifcvt.c: Add -mno-restrict-it to diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-11.c b/gcc/testsuite/gcc.dg/vect/slp-perm-11.c new file mode 100644 index 00000000000..0318d468ef1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-perm-11.c @@ -0,0 +1,35 @@ +/* { dg-require-effective-target vect_int } */ + +#include "tree-vect.h" + +int a[64]; +int b[128]; + +void __attribute__((noinline, noclone)) +foo (int s) +{ + int i; + for (i = 0; i < 32; ++i) + { + a[2*i] = b[i*s+1]; + a[2*i+1] = b[i*s]; + } +} + +int main () +{ + int i; + check_vect (); + for (i = 0; i < 128; ++i) + { + b[i] = i; + __asm__ volatile (""); + } + foo (4); + for (i = 0; i < 64; ++i) + if (a[i] != (4*(i/2) + (i & 1) ^ 1)) + abort (); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_perm } } } */ diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 2f77e8448ee..59a4390c153 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -6247,13 +6247,19 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, gcc_assert (!nested_in_vect_loop); + if (grouped_load) + first_dr = STMT_VINFO_DATA_REF + (vinfo_for_stmt (GROUP_FIRST_ELEMENT (stmt_info))); + else + first_dr = dr; + stride_base = fold_build_pointer_plus - (unshare_expr (DR_BASE_ADDRESS (dr)), + (DR_BASE_ADDRESS (first_dr), size_binop (PLUS_EXPR, - convert_to_ptrofftype (unshare_expr (DR_OFFSET (dr))), - convert_to_ptrofftype (DR_INIT (dr)))); - stride_step = fold_convert (sizetype, unshare_expr (DR_STEP (dr))); + convert_to_ptrofftype (DR_OFFSET (first_dr)), + convert_to_ptrofftype (DR_INIT (first_dr)))); + stride_step = fold_convert (sizetype, DR_STEP (first_dr)); /* For a load with loop-invariant (but other than power-of-2) stride (i.e. not a grouped access) like so: @@ -6271,25 +6277,25 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, vectemp = {tmp1, tmp2, ...} */ - ivstep = stride_step; - ivstep = fold_build2 (MULT_EXPR, TREE_TYPE (ivstep), ivstep, - build_int_cst (TREE_TYPE (ivstep), vf)); + ivstep = fold_build2 (MULT_EXPR, TREE_TYPE (stride_step), stride_step, + build_int_cst (TREE_TYPE (stride_step), vf)); standard_iv_increment_position (loop, &incr_gsi, &insert_after); - create_iv (stride_base, ivstep, NULL, + create_iv (unshare_expr (stride_base), unshare_expr (ivstep), NULL, loop, &incr_gsi, insert_after, &offvar, NULL); incr = gsi_stmt (incr_gsi); set_vinfo_for_stmt (incr, new_stmt_vec_info (incr, loop_vinfo, NULL)); - stride_step = force_gimple_operand (stride_step, &stmts, true, NULL_TREE); + stride_step = force_gimple_operand (unshare_expr (stride_step), + &stmts, true, NULL_TREE); if (stmts) gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts); prev_stmt_info = NULL; running_off = offvar; - alias_off = build_int_cst (reference_alias_ptr_type (DR_REF (dr)), 0); + alias_off = build_int_cst (reference_alias_ptr_type (DR_REF (first_dr)), 0); int nloads = nunits; tree ltype = TREE_TYPE (vectype); auto_vec dr_chain; -- 2.30.2