On Thu, 15 Nov 2018 at 14:41, Richard Biener <rguent...@suse.de> wrote: > > > With one of my last changes we regressed here so this goes all the > way cleaning up things so we only have a single flag to > vectorizable_condition whetehr we are called from reduction context. > In theory the !multiple-types restriction could be easily lifted now > (just remove the check). > > Bootstrapped and tested on x86_64-unknown-linux-gnu, applied. > > Richard. > > 2018-11-15 Richard Biener <rguent...@suse.de> > > PR tree-optimization/88031 > * tree-vect-loop.c (vectorizable_reduction): Move check > for multiple types earlier so we get the expected dump. > Simplify calls to vectorizable_condition. > * tree-vect-stmts.h (vectorizable_condition): Update prototype. > * tree-vect-stmts.c (vectorizable_condition): Instead of > reduc_def and reduc_index take just a flag. Simplify > code-generation now that we can rely on the defs being set up. > (vectorizable_comparison): Remove unused argument. > > * gcc.dg/pr88031.c: New testcase. >
Hi Richard, Since you committed this patch (r266182), I've noticed regressions on aarch64: gcc.target/aarch64/sve/clastb_1.c -march=armv8.2-a+sve (internal compiler error) gcc.target/aarch64/sve/clastb_2.c -march=armv8.2-a+sve (internal compiler error) gcc.target/aarch64/sve/clastb_3.c -march=armv8.2-a+sve (internal compiler error) gcc.target/aarch64/sve/clastb_4.c -march=armv8.2-a+sve (internal compiler error) gcc.target/aarch64/sve/clastb_5.c -march=armv8.2-a+sve (internal compiler error) gcc.target/aarch64/sve/clastb_6.c -march=armv8.2-a+sve (internal compiler error) gcc.target/aarch64/sve/clastb_7.c -march=armv8.2-a+sve (internal compiler error) during GIMPLE pass: vect /gcc/testsuite/gcc.target/aarch64/sve/clastb_1.c: In function 'condition_reduction': /gcc/testsuite/gcc.target/aarch64/sve/clastb_1.c:9:1: internal compiler error: in vect_get_vec_def_for_operand_1, at tree-vect-stmts.c:1485 0xe915ab vect_get_vec_def_for_operand_1(_stmt_vec_info*, vect_def_type) /gcc/tree-vect-stmts.c:1485 0xe987ea vect_get_vec_def_for_operand(tree_node*, _stmt_vec_info*, tree_node*) /gcc/tree-vect-stmts.c:1547 0xe9f944 vectorizable_condition(_stmt_vec_info*, gimple_stmt_iterator*, _stmt_vec_info**, bool, _slp_tree*, vec<stmt_info_for_cost, va_heap, vl_ptr>*) /gcc/tree-vect-stmts.c:8931 0xebed1d vectorizable_reduction(_stmt_vec_info*, gimple_stmt_iterator*, _stmt_vec_info**, _slp_tree*, _slp_instance*, vec<stmt_info_for_cost, va_heap, vl_ptr>*) /gcc/tree-vect-loop.c:6964 0xeb2640 vect_transform_stmt(_stmt_vec_info*, gimple_stmt_iterator*, _slp_tree*, _slp_instance*) /gcc/tree-vect-stmts.c:9691 0xeb4029 vect_transform_loop_stmt /gcc/tree-vect-loop.c:8185 0xec1ff2 vect_transform_loop(_loop_vec_info*) /gcc/tree-vect-loop.c:8405 0xee5950 try_vectorize_loop_1 /gcc/tree-vectorizer.c:969 0xee62f1 vectorize_loops() /gcc/tree-vectorizer.c:1102 Please submit a full bug report, Christophe > > diff --git a/gcc/testsuite/gcc.dg/pr88031.c b/gcc/testsuite/gcc.dg/pr88031.c > new file mode 100644 > index 00000000000..2c1d1c1391d > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr88031.c > @@ -0,0 +1,17 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O3" } */ > + > +int a[512]; > +int b; > +void d() > +{ > + unsigned char c; > + for (; b; b++) { > + c = 1; > + for (; c; c <<= 1) { > + a[b] <<= 8; > + if (b & c) > + a[b] = 1; > + } > + } > +} > diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c > index eb01acdf717..88b980bb9d7 100644 > --- a/gcc/tree-vect-loop.c > +++ b/gcc/tree-vect-loop.c > @@ -6531,14 +6531,24 @@ vectorizable_reduction (stmt_vec_info stmt_info, > gimple_stmt_iterator *gsi, > double_reduc = true; > } > > + vect_reduction_type reduction_type > + = STMT_VINFO_VEC_REDUCTION_TYPE (stmt_info); > + if ((double_reduc || reduction_type != TREE_CODE_REDUCTION) > + && ncopies > 1) > + { > + if (dump_enabled_p ()) > + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, > + "multiple types in double reduction or condition " > + "reduction.\n"); > + return false; > + } > + > if (code == COND_EXPR) > { > /* Only call during the analysis stage, otherwise we'll lose > - STMT_VINFO_TYPE. We'll pass ops[0] as reduc_op, it's only > - used as a flag during analysis. */ > + STMT_VINFO_TYPE. */ > if (!vec_stmt && !vectorizable_condition (stmt_info, gsi, NULL, > - ops[0], 0, NULL, > - cost_vec)) > + true, NULL, cost_vec)) > { > if (dump_enabled_p ()) > dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, > @@ -6638,8 +6648,6 @@ vectorizable_reduction (stmt_vec_info stmt_info, > gimple_stmt_iterator *gsi, > (and also the same tree-code) when generating the epilog code and > when generating the code inside the loop. */ > > - vect_reduction_type reduction_type > - = STMT_VINFO_VEC_REDUCTION_TYPE (stmt_info); > if (orig_stmt_info > && (reduction_type == TREE_CODE_REDUCTION > || reduction_type == FOLD_LEFT_REDUCTION)) > @@ -6729,16 +6737,6 @@ vectorizable_reduction (stmt_vec_info stmt_info, > gimple_stmt_iterator *gsi, > return false; > } > > - if ((double_reduc || reduction_type != TREE_CODE_REDUCTION) > - && ncopies > 1) > - { > - if (dump_enabled_p ()) > - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, > - "multiple types in double reduction or condition " > - "reduction.\n"); > - return false; > - } > - > /* For SLP reductions, see if there is a neutral value we can use. */ > tree neutral_op = NULL_TREE; > if (slp_node) > @@ -7003,7 +7001,7 @@ vectorizable_reduction (stmt_vec_info stmt_info, > gimple_stmt_iterator *gsi, > { > gcc_assert (!slp_node); > return vectorizable_condition (stmt_info, gsi, vec_stmt, > - NULL, reduc_index, NULL, NULL); > + true, NULL, NULL); > } > > /* Create the destination vector */ > @@ -7035,9 +7033,7 @@ vectorizable_reduction (stmt_vec_info stmt_info, > gimple_stmt_iterator *gsi, > { > gcc_assert (!slp_node); > vectorizable_condition (stmt_info, gsi, vec_stmt, > - PHI_RESULT (phis[0]->stmt), > - reduc_index, NULL, NULL); > - /* Multiple types are not supported for condition. */ > + true, NULL, NULL); > break; > } > if (code == LSHIFT_EXPR > diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c > index 74646570e2a..a67a7f4e348 100644 > --- a/gcc/tree-vect-stmts.c > +++ b/gcc/tree-vect-stmts.c > @@ -8675,17 +8675,14 @@ vect_is_simple_cond (tree cond, vec_info *vinfo, > stmt using VEC_COND_EXPR to replace it, put it in VEC_STMT, and insert it > at GSI. > > - When STMT_INFO is vectorized as a nested cycle, REDUC_DEF is the vector > - variable to be used at REDUC_INDEX (in then clause if REDUC_INDEX is 1, > - and in else clause if it is 2). > + When STMT_INFO is vectorized as a nested cycle, for_reduction is true. > > Return true if STMT_INFO is vectorizable in this way. */ > > bool > vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, > - stmt_vec_info *vec_stmt, tree reduc_def, > - int reduc_index, slp_tree slp_node, > - stmt_vector_for_cost *cost_vec) > + stmt_vec_info *vec_stmt, bool for_reduction, > + slp_tree slp_node, stmt_vector_for_cost *cost_vec) > { > vec_info *vinfo = stmt_info->vinfo; > tree scalar_dest = NULL_TREE; > @@ -8714,7 +8711,7 @@ vectorizable_condition (stmt_vec_info stmt_info, > gimple_stmt_iterator *gsi, > tree vec_cmp_type; > bool masked = false; > > - if (reduc_index && STMT_SLP_TYPE (stmt_info)) > + if (for_reduction && STMT_SLP_TYPE (stmt_info)) > return false; > > vect_reduction_type reduction_type > @@ -8726,7 +8723,7 @@ vectorizable_condition (stmt_vec_info stmt_info, > gimple_stmt_iterator *gsi, > > if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def > && !(STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle > - && reduc_def)) > + && for_reduction)) > return false; > > /* FORNOW: not yet supported. */ > @@ -8758,7 +8755,7 @@ vectorizable_condition (stmt_vec_info stmt_info, > gimple_stmt_iterator *gsi, > ncopies = vect_get_num_copies (loop_vinfo, vectype); > > gcc_assert (ncopies >= 1); > - if (reduc_index && ncopies > 1) > + if (for_reduction && ncopies > 1) > return false; /* FORNOW */ > > cond_expr = gimple_assign_rhs1 (stmt); > @@ -8928,22 +8925,12 @@ vectorizable_condition (stmt_vec_info stmt_info, > gimple_stmt_iterator *gsi, > stmt_info, comp_vectype); > vect_is_simple_use (cond_expr1, loop_vinfo, &dts[1]); > } > - if (reduc_index == 1) > - vec_then_clause = reduc_def; > - else > - { > - vec_then_clause = vect_get_vec_def_for_operand (then_clause, > - stmt_info); > - vect_is_simple_use (then_clause, loop_vinfo, &dts[2]); > - } > - if (reduc_index == 2) > - vec_else_clause = reduc_def; > - else > - { > - vec_else_clause = vect_get_vec_def_for_operand (else_clause, > - stmt_info); > - vect_is_simple_use (else_clause, loop_vinfo, &dts[3]); > - } > + vec_then_clause = vect_get_vec_def_for_operand (then_clause, > + stmt_info); > + vect_is_simple_use (then_clause, loop_vinfo, &dts[2]); > + vec_else_clause = vect_get_vec_def_for_operand (else_clause, > + stmt_info); > + vect_is_simple_use (else_clause, loop_vinfo, &dts[3]); > } > } > else > @@ -9023,7 +9010,6 @@ vectorizable_condition (stmt_vec_info stmt_info, > gimple_stmt_iterator *gsi, > vect_finish_stmt_generation (stmt_info, new_stmt, gsi); > vec_compare = vec_compare_name; > } > - gcc_assert (reduc_index == 2); > gcall *new_stmt = gimple_build_call_internal > (IFN_FOLD_EXTRACT_LAST, 3, else_clause, vec_compare, > vec_then_clause); > @@ -9085,7 +9071,7 @@ vectorizable_condition (stmt_vec_info stmt_info, > gimple_stmt_iterator *gsi, > > static bool > vectorizable_comparison (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, > - stmt_vec_info *vec_stmt, tree reduc_def, > + stmt_vec_info *vec_stmt, > slp_tree slp_node, stmt_vector_for_cost *cost_vec) > { > vec_info *vinfo = stmt_info->vinfo; > @@ -9123,9 +9109,7 @@ vectorizable_comparison (stmt_vec_info stmt_info, > gimple_stmt_iterator *gsi, > ncopies = vect_get_num_copies (loop_vinfo, vectype); > > gcc_assert (ncopies >= 1); > - if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def > - && !(STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle > - && reduc_def)) > + if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def) > return false; > > if (STMT_VINFO_LIVE_P (stmt_info)) > @@ -9556,9 +9540,9 @@ vect_analyze_stmt (stmt_vec_info stmt_info, bool > *need_to_vectorize, > node_instance, cost_vec) > || vectorizable_induction (stmt_info, NULL, NULL, node, cost_vec) > || vectorizable_shift (stmt_info, NULL, NULL, node, cost_vec) > - || vectorizable_condition (stmt_info, NULL, NULL, NULL, 0, node, > + || vectorizable_condition (stmt_info, NULL, NULL, false, node, > cost_vec) > - || vectorizable_comparison (stmt_info, NULL, NULL, NULL, node, > + || vectorizable_comparison (stmt_info, NULL, NULL, node, > cost_vec)); > else > { > @@ -9575,9 +9559,9 @@ vect_analyze_stmt (stmt_vec_info stmt_info, bool > *need_to_vectorize, > || vectorizable_load (stmt_info, NULL, NULL, node, > node_instance, > cost_vec) > || vectorizable_store (stmt_info, NULL, NULL, node, cost_vec) > - || vectorizable_condition (stmt_info, NULL, NULL, NULL, 0, node, > + || vectorizable_condition (stmt_info, NULL, NULL, false, node, > cost_vec) > - || vectorizable_comparison (stmt_info, NULL, NULL, NULL, node, > + || vectorizable_comparison (stmt_info, NULL, NULL, node, > cost_vec)); > } > > @@ -9680,13 +9664,13 @@ vect_transform_stmt (stmt_vec_info stmt_info, > gimple_stmt_iterator *gsi, > break; > > case condition_vec_info_type: > - done = vectorizable_condition (stmt_info, gsi, &vec_stmt, NULL, 0, > + done = vectorizable_condition (stmt_info, gsi, &vec_stmt, false, > slp_node, NULL); > gcc_assert (done); > break; > > case comparison_vec_info_type: > - done = vectorizable_comparison (stmt_info, gsi, &vec_stmt, NULL, > + done = vectorizable_comparison (stmt_info, gsi, &vec_stmt, > slp_node, NULL); > gcc_assert (done); > break; > diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h > index 1a906036fed..673ad5936bf 100644 > --- a/gcc/tree-vectorizer.h > +++ b/gcc/tree-vectorizer.h > @@ -1485,7 +1485,7 @@ extern void vect_remove_stores (stmt_vec_info); > extern opt_result vect_analyze_stmt (stmt_vec_info, bool *, slp_tree, > slp_instance, stmt_vector_for_cost *); > extern bool vectorizable_condition (stmt_vec_info, gimple_stmt_iterator *, > - stmt_vec_info *, tree, int, slp_tree, > + stmt_vec_info *, bool, slp_tree, > stmt_vector_for_cost *); > extern bool vectorizable_shift (stmt_vec_info, gimple_stmt_iterator *, > stmt_vec_info *, slp_tree,