The SLP vectorizer is confused by the aggregate store in typedef __complex__ float Value; struct A { Value a[16 / sizeof (Value)]; } __attribute__ ((aligned(16))); A sum(A a, A b) { a.a[0]+=b.a[0]; a.a[1]+=b.a[1]; return a; } when built with -O3 -fno-tree-sra: <bb 2>: D.2130_11 = REALPART_EXPR <a.a[0]>; D.2131_12 = IMAGPART_EXPR <a.a[0]>; D.2132_13 = REALPART_EXPR <b.a[0]>; D.2133_14 = IMAGPART_EXPR <b.a[0]>; D.2134_15 = D.2130_11 + D.2132_13; D.2135_16 = D.2131_12 + D.2133_14; REALPART_EXPR <a.a[0]> = D.2134_15; IMAGPART_EXPR <a.a[0]> = D.2135_16; D.2136_17 = REALPART_EXPR <a.a[1]>; D.2137_18 = IMAGPART_EXPR <a.a[1]>; D.2138_19 = REALPART_EXPR <b.a[1]>; D.2139_20 = IMAGPART_EXPR <b.a[1]>; D.2140_21 = D.2136_17 + D.2138_19; D.2141_22 = D.2137_18 + D.2139_20; REALPART_EXPR <a.a[1]> = D.2140_21; IMAGPART_EXPR <a.a[1]> = D.2141_22; D.2119 = a; return D.2119; but I don't see why SLP couldn't simply stop analyzing the BB when it encounters a DR that it cannot build or handle. The previous instructions can be still vectorized. If you put an unrelated volatile store at the end of any sequence in a bb-slp testcase this reproduces as well. The above testcase will probably fail due to unsupported strided stores.
Tested only with the vectorizer tests. Index: tree-vect-data-refs.c =================================================================== --- tree-vect-data-refs.c (revision 179789) +++ tree-vect-data-refs.c (working copy) @@ -2524,7 +2524,7 @@ vect_analyze_data_refs (loop_vec_info lo VEC (data_reference_p, heap) *datarefs; struct data_reference *dr; tree scalar_type; - bool res; + bool res, stop_bb_analysis = false; if (vect_print_dump_info (REPORT_DETAILS)) fprintf (vect_dump, "=== vect_analyze_data_refs ===\n"); @@ -2579,12 +2579,19 @@ vect_analyze_data_refs (loop_vec_info lo { if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS)) fprintf (vect_dump, "not vectorized: unhandled data-ref "); + return false; } stmt = DR_STMT (dr); stmt_info = vinfo_for_stmt (stmt); + if (stop_bb_analysis) + { + STMT_VINFO_VECTORIZABLE (stmt_info) = false; + continue; + } + /* Check that analysis of the data-ref succeeded. */ if (!DR_BASE_ADDRESS (dr) || !DR_OFFSET (dr) || !DR_INIT (dr) || !DR_STEP (dr)) @@ -2595,6 +2602,13 @@ vect_analyze_data_refs (loop_vec_info lo print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); } + if (bb_vinfo) + { + STMT_VINFO_VECTORIZABLE (stmt_info) = false; + stop_bb_analysis = true; + continue; + } + return false; } @@ -2603,7 +2617,15 @@ vect_analyze_data_refs (loop_vec_info lo if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS)) fprintf (vect_dump, "not vectorized: base addr of dr is a " "constant"); - return false; + + if (bb_vinfo) + { + STMT_VINFO_VECTORIZABLE (stmt_info) = false; + stop_bb_analysis = true; + continue; + } + + return false; } if (TREE_THIS_VOLATILE (DR_REF (dr))) @@ -2613,6 +2635,14 @@ vect_analyze_data_refs (loop_vec_info lo fprintf (vect_dump, "not vectorized: volatile type "); print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); } + + if (bb_vinfo) + { + STMT_VINFO_VECTORIZABLE (stmt_info) = false; + stop_bb_analysis = true; + continue; + } + return false; } @@ -2628,6 +2658,14 @@ vect_analyze_data_refs (loop_vec_info lo "exception "); print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); } + + if (bb_vinfo) + { + STMT_VINFO_VECTORIZABLE (stmt_info) = false; + stop_bb_analysis = true; + continue; + } + return false; } @@ -2745,6 +2783,14 @@ vect_analyze_data_refs (loop_vec_info lo "not vectorized: more than one data ref in stmt: "); print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); } + + if (bb_vinfo) + { + STMT_VINFO_VECTORIZABLE (stmt_info) = false; + stop_bb_analysis = true; + continue; + } + return false; } @@ -2769,6 +2815,7 @@ vect_analyze_data_refs (loop_vec_info lo { /* Mark the statement as not vectorizable. */ STMT_VINFO_VECTORIZABLE (stmt_info) = false; + stop_bb_analysis = true; continue; } else
First blush, looks like something could be abstracted as a function or a macro?!?
(In reply to comment #2) > First blush, looks like something could be abstracted as a function or a > macro?!? Hmm, I don't know. There is a 'continue' there...
Author: irar Date: Mon Oct 24 09:16:53 2011 New Revision: 180367 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=180367 Log: PR tree-optimization/50730 * tree-vect-data-refs.c (vect_analyze_data_refs): Stop basic block analysis if encountered unsupported data-ref. Added: trunk/gcc/testsuite/gcc.dg/vect/no-tree-sra-bb-slp-pr50730.c Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gcc.dg/vect/vect.exp trunk/gcc/tree-vect-data-refs.c
Fixed.
Author: irar Date: Fri Nov 4 12:55:06 2011 New Revision: 180945 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=180945 Log: Unrevert: 2011-10-24 Ira Rosen <ira.rosen@linaro.org> PR tree-optimization/50730 * tree-vect-data-refs.c (vect_analyze_data_refs): Stop basic block analysis if encountered unsupported data-ref. Modified: trunk/gcc/ChangeLog trunk/gcc/tree-vect-data-refs.c