From 22692f3ce9d00eac18d5582de90dda5ae5c07c77 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 15 Nov 2018 13:42:13 +0000 Subject: [PATCH] re PR tree-optimization/88031 (ICE in vectorizable_reduction, at tree-vect-loop.c:6953) 2018-11-15 Richard Biener 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. From-SVN: r266182 --- gcc/ChangeLog | 12 ++++++++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.dg/pr88031.c | 17 +++++++++++ gcc/tree-vect-loop.c | 36 ++++++++++------------ gcc/tree-vect-stmts.c | 56 ++++++++++++---------------------- gcc/tree-vectorizer.h | 2 +- 6 files changed, 71 insertions(+), 57 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr88031.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6258974e3e5..df863230c1c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2018-11-15 Richard Biener + + 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. + 2018-11-15 Richard Biener PR tree-optimization/88030 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3b0b6093f29..ee0d920c73e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-11-15 Richard Biener + + PR tree-optimization/88031 + * gcc.dg/pr88031.c: New testcase. + 2018-11-15 Wilco Dijkstra * gcc.target/aarch64/pr62178.c: Fix spaces. 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 dac6bb87847..f2d9d8ac2bc 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -6491,14 +6491,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, @@ -6598,8 +6608,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)) @@ -6689,16 +6697,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) @@ -6963,7 +6961,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 */ @@ -6995,9 +6993,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 7f21622ebfe..f1c186b8af5 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -1481,7 +1481,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, -- 2.30.2