diff options
author | Michael Matz <matz@suse.de> | 2010-09-17 13:26:43 +0000 |
---|---|---|
committer | Michael Matz <matz@gcc.gnu.org> | 2010-09-17 13:26:43 +0000 |
commit | 18ba3ce7e3f3d220bca82a1edeadf4a1db019e7c (patch) | |
tree | 724f8c663f3db02bdbd8dae5e34e5ecb48d6bced /gcc/tree-vect-data-refs.c | |
parent | 4c588abff3db7852724edf638a795b7a37f70f2b (diff) | |
download | gcc-18ba3ce7e3f3d220bca82a1edeadf4a1db019e7c.zip gcc-18ba3ce7e3f3d220bca82a1edeadf4a1db019e7c.tar.gz gcc-18ba3ce7e3f3d220bca82a1edeadf4a1db019e7c.tar.bz2 |
re PR tree-optimization/43432 (Missed vectorization: "complicated access pattern" for increasing and decreasing data indexing)
PR tree-optimization/43432
* tree-vect-data-refs.c (vect_analyze_data_ref_access):
Accept backwards consecutive accesses.
(vect_create_data_ref_ptr): If step is negative generate
decreasing IVs.
* tree-vect-stmts.c (vectorizable_store): Reject negative steps.
(perm_mask_for_reverse, reverse_vec_elements): New functions.
(vectorizable_load): Handle loads with negative steps when easily
possible.
testsuite/
PR tree-optimization/43432
* lib/target-supports.exp (check_effective_target_vect_perm_byte,
check_effective_target_vect_perm_short): New predicates.
(check_effective_target_vect_perm): Include x86_64.
* gcc.dg/vect/pr43432.c: New test.
* gcc.dg/vect/vect-114.c: Adjust.
* gcc.dg/vect/vect-15.c: Ditto.
* gcc.dg/vect/slp-perm-8.c: Use new predicate.
* gcc.dg/vect/slp-perm-9.c: Ditto.
From-SVN: r164367
Diffstat (limited to 'gcc/tree-vect-data-refs.c')
-rw-r--r-- | gcc/tree-vect-data-refs.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 0d1e338..7182513 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -2287,7 +2287,9 @@ vect_analyze_data_ref_access (struct data_reference *dr) } /* Consecutive? */ - if (!tree_int_cst_compare (step, TYPE_SIZE_UNIT (scalar_type))) + if (!tree_int_cst_compare (step, TYPE_SIZE_UNIT (scalar_type)) + || (dr_step < 0 + && !compare_tree_int (TYPE_SIZE_UNIT (scalar_type), -dr_step))) { /* Mark that it is not interleaving. */ DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)) = NULL; @@ -2970,6 +2972,7 @@ vect_create_data_ref_ptr (gimple stmt, struct loop *at_loop, tree vptr; gimple_stmt_iterator incr_gsi; bool insert_after; + bool negative; tree indx_before_incr, indx_after_incr; gimple incr; tree step; @@ -3002,6 +3005,7 @@ vect_create_data_ref_ptr (gimple stmt, struct loop *at_loop, *inv_p = true; else *inv_p = false; + negative = tree_int_cst_compare (step, size_zero_node) < 0; /* Create an expression for the first address accessed by this load in LOOP. */ @@ -3160,6 +3164,8 @@ vect_create_data_ref_ptr (gimple stmt, struct loop *at_loop, LOOP is zero. In this case the step here is also zero. */ if (*inv_p) step = size_zero_node; + else if (negative) + step = fold_build1 (NEGATE_EXPR, TREE_TYPE (step), step); standard_iv_increment_position (loop, &incr_gsi, &insert_after); |