From 5bfdb7d8893e24b94d39a0c2f5fa5380c7c79463 Mon Sep 17 00:00:00 2001 From: Ira Rosen Date: Sun, 23 Oct 2011 12:13:49 +0000 Subject: [PATCH] re PR tree-optimization/50819 (missed SLP vectorization) PR tree-optimization/50819 * tree-vectorizer.h (vect_analyze_data_ref_dependences): Remove the last argument. * tree-vect-loop.c (vect_analyze_loop_2): Update call to vect_analyze_data_ref_dependences. * tree-vect-data-refs.c (vect_analyze_data_ref_dependence): Remove the last argument. Check load-after-store dependence for unknown dependencies in basic blocks. (vect_analyze_data_ref_dependences): Update call to vect_analyze_data_ref_dependences. * tree-vect-patterns.c (vect_recog_widen_shift_pattern): Fix typo. * tree-vect-slp.c (vect_bb_vectorizable_with_dependencies): Remove. (vect_slp_analyze_bb_1): Update call to vect_analyze_data_ref_dependences. Don't call vect_bb_vectorizable_with_dependencies. From-SVN: r180334 --- gcc/ChangeLog | 18 ++++++++ gcc/testsuite/ChangeLog | 6 +++ gcc/testsuite/g++.dg/vect/slp-pr50819.cc | 53 ++++++++++++++++++++++++ gcc/testsuite/g++.dg/vect/vect.exp | 11 +++-- gcc/tree-vect-data-refs.c | 20 ++++----- gcc/tree-vect-loop.c | 4 +- gcc/tree-vect-patterns.c | 2 +- gcc/tree-vect-slp.c | 45 +------------------- gcc/tree-vectorizer.h | 2 +- 9 files changed, 98 insertions(+), 63 deletions(-) create mode 100644 gcc/testsuite/g++.dg/vect/slp-pr50819.cc diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 269c1cd2661..fac9fa920cc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2011-10-23 Ira Rosen + + PR tree-optimization/50819 + * tree-vectorizer.h (vect_analyze_data_ref_dependences): Remove + the last argument. + * tree-vect-loop.c (vect_analyze_loop_2): Update call to + vect_analyze_data_ref_dependences. + * tree-vect-data-refs.c (vect_analyze_data_ref_dependence): Remove + the last argument. Check load-after-store dependence for unknown + dependencies in basic blocks. + (vect_analyze_data_ref_dependences): Update call to + vect_analyze_data_ref_dependences. + * tree-vect-patterns.c (vect_recog_widen_shift_pattern): Fix typo. + * tree-vect-slp.c (vect_bb_vectorizable_with_dependencies): Remove. + (vect_slp_analyze_bb_1): Update call to + vect_analyze_data_ref_dependences. Don't call + vect_bb_vectorizable_with_dependencies. + 2011-10-22 David S. Miller * config/sparc/sparc.h (SECONDARY_INPUT_RELOAD_CLASS, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 71aa33df3bd..16b6f6f5c54 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2011-10-23 Ira Rosen + + PR tree-optimization/50819 + * g++.dg/vect/vect.exp: Set target dependent flags for slp-* tests. + * g++.dg/vect/slp-pr50819.cc: New test. + 2011-10-21 Paolo Carlini PR c++/45385 diff --git a/gcc/testsuite/g++.dg/vect/slp-pr50819.cc b/gcc/testsuite/g++.dg/vect/slp-pr50819.cc new file mode 100644 index 00000000000..402218bc5b7 --- /dev/null +++ b/gcc/testsuite/g++.dg/vect/slp-pr50819.cc @@ -0,0 +1,53 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ + +typedef float Value; + +struct LorentzVector +{ + + LorentzVector(Value x=0, Value y=0, Value z=0, Value t=0) : +theX(x),theY(y),theZ(z),theT(t){} + LorentzVector & operator+=(const LorentzVector & a) { + theX += a.theX; + theY += a.theY; + theZ += a.theZ; + theT += a.theT; + return *this; + } + + Value theX; + Value theY; + Value theZ; + Value theT; +} __attribute__ ((aligned(16))); + +inline LorentzVector +operator+(LorentzVector const & a, LorentzVector const & b) { + return +LorentzVector(a.theX+b.theX,a.theY+b.theY,a.theZ+b.theZ,a.theT+b.theT); +} + +inline LorentzVector +operator*(LorentzVector const & a, Value s) { + return LorentzVector(a.theX*s,a.theY*s,a.theZ*s,a.theT*s); +} + +inline LorentzVector +operator*(Value s, LorentzVector const & a) { + return a*s; +} + + +void sum1(LorentzVector & res, Value s, LorentzVector const & v1, LorentzVector +const & v2) { + res += s*(v1+v2); +} + +void sum2(LorentzVector & res, Value s, LorentzVector const & v1, LorentzVector +const & v2) { + res = res + s*(v1+v2); +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 2 "slp" } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ diff --git a/gcc/testsuite/g++.dg/vect/vect.exp b/gcc/testsuite/g++.dg/vect/vect.exp index ac22f4b017d..76bd99a9862 100644 --- a/gcc/testsuite/g++.dg/vect/vect.exp +++ b/gcc/testsuite/g++.dg/vect/vect.exp @@ -42,12 +42,6 @@ set DEFAULT_VECTCFLAGS "" # These flags are used for all targets. lappend DEFAULT_VECTCFLAGS "-O2" "-ftree-vectorize" "-fno-vect-cost-model" -set VECT_SLP_CFLAGS $DEFAULT_VECTCFLAGS - -lappend DEFAULT_VECTCFLAGS "-fdump-tree-vect-details" -lappend VECT_SLP_CFLAGS "-fdump-tree-slp-details" - - # Skip these tests for targets that do not support generating vector # code. Set additional target-dependent vector flags, which can be # overridden by using dg-options in individual tests. @@ -55,6 +49,11 @@ if ![check_vect_support_and_set_flags] { return } +set VECT_SLP_CFLAGS $DEFAULT_VECTCFLAGS + +lappend DEFAULT_VECTCFLAGS "-fdump-tree-vect-details" +lappend VECT_SLP_CFLAGS "-fdump-tree-slp-details" + # Initialize `dg'. dg-init diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index a9504cd2362..3634e5ecd5b 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -555,8 +555,7 @@ vect_mark_for_runtime_alias_test (ddr_p ddr, loop_vec_info loop_vinfo) static bool vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr, - loop_vec_info loop_vinfo, int *max_vf, - bool *data_dependence_in_bb) + loop_vec_info loop_vinfo, int *max_vf) { unsigned int i; struct loop *loop = NULL; @@ -587,6 +586,8 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr, if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know) { + gimple earlier_stmt; + if (loop_vinfo) { if (vect_print_dump_info (REPORT_DR_DETAILS)) @@ -624,10 +625,11 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr, if (DR_IS_WRITE (dra) && DR_IS_WRITE (drb)) return true; - /* We deal with read-write dependencies in basic blocks later (by - verifying that all the loads in the basic block are before all the - stores). */ - *data_dependence_in_bb = true; + /* Check that it's not a load-after-store dependence. */ + earlier_stmt = get_earlier_stmt (DR_STMT (dra), DR_STMT (drb)); + if (DR_IS_WRITE (STMT_VINFO_DATA_REF (vinfo_for_stmt (earlier_stmt)))) + return true; + return false; } @@ -753,8 +755,7 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr, bool vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo, - bb_vec_info bb_vinfo, int *max_vf, - bool *data_dependence_in_bb) + bb_vec_info bb_vinfo, int *max_vf) { unsigned int i; VEC (ddr_p, heap) *ddrs = NULL; @@ -769,8 +770,7 @@ vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo, ddrs = BB_VINFO_DDRS (bb_vinfo); FOR_EACH_VEC_ELT (ddr_p, ddrs, i, ddr) - if (vect_analyze_data_ref_dependence (ddr, loop_vinfo, max_vf, - data_dependence_in_bb)) + if (vect_analyze_data_ref_dependence (ddr, loop_vinfo, max_vf)) return false; return true; diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index ba8878a8663..3ef407e7121 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -1473,7 +1473,7 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp) static bool vect_analyze_loop_2 (loop_vec_info loop_vinfo) { - bool ok, dummy, slp = false; + bool ok, slp = false; int max_vf = MAX_VECTORIZATION_FACTOR; int min_vf = 2; @@ -1514,7 +1514,7 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo) the dependences. FORNOW: fail at the first data dependence that we encounter. */ - ok = vect_analyze_data_ref_dependences (loop_vinfo, NULL, &max_vf, &dummy); + ok = vect_analyze_data_ref_dependences (loop_vinfo, NULL, &max_vf); if (!ok || max_vf < min_vf) { diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 94ab9b79667..94e28016681 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -1225,7 +1225,7 @@ vect_recog_over_widening_pattern (VEC (gimple, heap) **stmts, where type 'TYPE' is at least double the size of type 'type'. - Also detect unsgigned cases: + Also detect unsigned cases: unsigned type a_t; unsigned TYPE u_res_T; diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index f131f1eec23..f75817b985f 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -1706,43 +1706,6 @@ vect_slp_analyze_operations (bb_vec_info bb_vinfo) return true; } -/* Check if loads and stores are mixed in the basic block (in that - case if we are not sure that the accesses differ, we can't vectorize the - basic block). Also return FALSE in case that there is statement marked as - not vectorizable. */ - -static bool -vect_bb_vectorizable_with_dependencies (bb_vec_info bb_vinfo) -{ - basic_block bb = BB_VINFO_BB (bb_vinfo); - gimple_stmt_iterator si; - bool detected_store = false; - gimple stmt; - struct data_reference *dr; - - for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si)) - { - stmt = gsi_stmt (si); - - /* We can't allow not analyzed statements, since they may contain data - accesses. */ - if (!STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (stmt))) - return false; - - if (!STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt))) - continue; - - dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt)); - if (DR_IS_READ (dr) && detected_store) - return false; - - if (!DR_IS_READ (dr)) - detected_store = true; - } - - return true; -} - /* Check if vectorization of the basic block is profitable. */ static bool @@ -1823,7 +1786,6 @@ vect_slp_analyze_bb_1 (basic_block bb) int i; int min_vf = 2; int max_vf = MAX_VECTORIZATION_FACTOR; - bool data_dependence_in_bb = false; bb_vinfo = new_bb_vec_info (bb); if (!bb_vinfo) @@ -1850,11 +1812,8 @@ vect_slp_analyze_bb_1 (basic_block bb) return NULL; } - if (!vect_analyze_data_ref_dependences (NULL, bb_vinfo, &max_vf, - &data_dependence_in_bb) - || min_vf > max_vf - || (data_dependence_in_bb - && !vect_bb_vectorizable_with_dependencies (bb_vinfo))) + if (!vect_analyze_data_ref_dependences (NULL, bb_vinfo, &max_vf) + || min_vf > max_vf) { if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS)) fprintf (vect_dump, "not vectorized: unhandled data dependence " diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index c27e76ca7ac..b0142e2ba7f 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -832,7 +832,7 @@ extern enum dr_alignment_support vect_supportable_dr_alignment extern tree vect_get_smallest_scalar_type (gimple, HOST_WIDE_INT *, HOST_WIDE_INT *); extern bool vect_analyze_data_ref_dependences (loop_vec_info, bb_vec_info, - int *, bool *); + int *); extern bool vect_enhance_data_refs_alignment (loop_vec_info); extern bool vect_analyze_data_refs_alignment (loop_vec_info, bb_vec_info); extern bool vect_verify_datarefs_alignment (loop_vec_info, bb_vec_info);