From 3fc356dcdc68bf3e44d8b08a0579b057021c95f4 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 2 Jun 2015 07:50:19 +0000 Subject: [PATCH] re PR tree-optimization/65961 (ice in vect_is_simple_use_1 with -O3) 2015-06-02 Richard Biener PR tree-optimization/65961 * tree-vect-slp.c (vect_get_and_check_slp_defs): Remove bogus check and clarify dump message. (vect_build_slp_tree): If all children are built up from scalars build up the parent from scalars instead. * tree-vect-stmts.c (vect_is_simple_use): Cleanup. * gcc.dg/torture/pr65961.c: New testcase. From-SVN: r224013 --- gcc/ChangeLog | 9 +++++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.dg/torture/pr65961.c | 20 +++++++++++ gcc/tree-vect-slp.c | 34 ++++++++++++++++-- gcc/tree-vect-stmts.c | 49 +++++++------------------- 5 files changed, 78 insertions(+), 39 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr65961.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b88973708a0..d7597c79a65 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2015-06-02 Richard Biener + + PR tree-optimization/65961 + * tree-vect-slp.c (vect_get_and_check_slp_defs): Remove bogus + check and clarify dump message. + (vect_build_slp_tree): If all children are built up from scalars + build up the parent from scalars instead. + * tree-vect-stmts.c (vect_is_simple_use): Cleanup. + 2015-06-02 Jan Kratochvil PR other/65366 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2bd0a31bfda..9dd08e5b581 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-06-02 Richard Biener + + PR tree-optimization/65961 + * gcc.dg/torture/pr65961.c: New testcase. + 2015-06-02 Bin Cheng PR tree-optimization/52563 diff --git a/gcc/testsuite/gcc.dg/torture/pr65961.c b/gcc/testsuite/gcc.dg/torture/pr65961.c new file mode 100644 index 00000000000..984ad1d6a9e --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr65961.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ + +int *a; +void +foo () +{ + do + { + a[16] = (a[1] ^ a[0]) << 1 | a[1]; + a[17] = (a[0] ^ a[1]) << 1 | a[0]; + a[18] = (a[0] ^ a[1]) << 1 | a[0]; + a[19] = (a[0] ^ a[1]) << 1 | a[0]; + a[20] = (a[0] ^ a[1]) << 1 | a[0]; + a[21] = (a[0] ^ a[1]) << 1 | a[0]; + a[22] = (a[0] ^ a[1]) << 1 | a[0]; + a[23] = (a[20] ^ a[1]) << 1 | a[9]; + a += 8; + } + while (1); +} diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index fb57dd41111..9e36d9cccab 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -301,13 +301,12 @@ again: oprnd_info = (*oprnds_info)[i]; if (!vect_is_simple_use (oprnd, NULL, loop_vinfo, bb_vinfo, &def_stmt, - &def, &dt) - || (!def_stmt && dt != vect_constant_def)) + &def, &dt)) { if (dump_enabled_p ()) { dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "Build SLP failed: can't find def for "); + "Build SLP failed: can't analyze def for "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, oprnd); dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } @@ -1092,6 +1091,35 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, vectorization_factor, matches, npermutes, &this_tree_size, max_tree_size)) { + /* If we have all children of child built up from scalars then just + throw that away and build it up this node from scalars. */ + if (!SLP_TREE_CHILDREN (child).is_empty ()) + { + unsigned int j; + slp_tree grandchild; + + FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (child), j, grandchild) + if (grandchild != NULL) + break; + if (!grandchild) + { + /* Roll back. */ + *max_nunits = old_max_nunits; + loads->truncate (old_nloads); + FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (child), j, grandchild) + vect_free_slp_tree (grandchild); + SLP_TREE_CHILDREN (child).truncate (0); + + dump_printf_loc (MSG_NOTE, vect_location, + "Building parent vector operands from " + "scalars instead\n"); + oprnd_info->def_stmts = vNULL; + vect_free_slp_tree (child); + SLP_TREE_CHILDREN (*node).quick_push (NULL); + continue; + } + } + oprnd_info->def_stmts = vNULL; SLP_TREE_CHILDREN (*node).quick_push (child); continue; diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 6b018e53aad..0eeebb0dafb 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -7878,15 +7878,9 @@ vect_is_simple_use (tree operand, gimple stmt, loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, gimple *def_stmt, tree *def, enum vect_def_type *dt) { - basic_block bb; - stmt_vec_info stmt_vinfo; - struct loop *loop = NULL; - - if (loop_vinfo) - loop = LOOP_VINFO_LOOP (loop_vinfo); - *def_stmt = NULL; *def = NULL_TREE; + *dt = vect_unknown_def_type; if (dump_enabled_p ()) { @@ -7909,13 +7903,6 @@ vect_is_simple_use (tree operand, gimple stmt, loop_vec_info loop_vinfo, return true; } - if (TREE_CODE (operand) == PAREN_EXPR) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "non-associatable copy.\n"); - operand = TREE_OPERAND (operand, 0); - } - if (TREE_CODE (operand) != SSA_NAME) { if (dump_enabled_p ()) @@ -7924,40 +7911,30 @@ vect_is_simple_use (tree operand, gimple stmt, loop_vec_info loop_vinfo, return false; } - *def_stmt = SSA_NAME_DEF_STMT (operand); - if (*def_stmt == NULL) + if (SSA_NAME_IS_DEFAULT_DEF (operand)) { - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "no def_stmt.\n"); - return false; + *def = operand; + *dt = vect_external_def; + return true; } + *def_stmt = SSA_NAME_DEF_STMT (operand); if (dump_enabled_p ()) { dump_printf_loc (MSG_NOTE, vect_location, "def_stmt: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, *def_stmt, 0); } - /* Empty stmt is expected only in case of a function argument. - (Otherwise - we expect a phi_node or a GIMPLE_ASSIGN). */ - if (gimple_nop_p (*def_stmt)) - { - *def = operand; - *dt = vect_external_def; - return true; - } - - bb = gimple_bb (*def_stmt); - - if ((loop && !flow_bb_inside_loop_p (loop, bb)) - || (!loop && bb != BB_VINFO_BB (bb_vinfo)) - || (!loop && gimple_code (*def_stmt) == GIMPLE_PHI)) + basic_block bb = gimple_bb (*def_stmt); + if ((loop_vinfo && !flow_bb_inside_loop_p (LOOP_VINFO_LOOP (loop_vinfo), bb)) + || (bb_vinfo + && (bb != BB_VINFO_BB (bb_vinfo) + || gimple_code (*def_stmt) == GIMPLE_PHI))) *dt = vect_external_def; else { - stmt_vinfo = vinfo_for_stmt (*def_stmt); - if (!loop && !STMT_VINFO_VECTORIZABLE (stmt_vinfo)) + stmt_vec_info stmt_vinfo = vinfo_for_stmt (*def_stmt); + if (bb_vinfo && !STMT_VINFO_VECTORIZABLE (stmt_vinfo)) *dt = vect_external_def; else *dt = STMT_VINFO_DEF_TYPE (stmt_vinfo); -- 2.30.2