From: Richard Biener Date: Fri, 15 Jan 2016 15:43:48 +0000 (+0000) Subject: re PR tree-optimization/66856 (ICE in compute_live_loop_exits, at tree-ssa-loop-manip... X-Git-Tag: basepoints/gcc-7~1596 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=78810bd35336529a133661a5e4f801ccda57fd74;p=thirdparty%2Fgcc.git re PR tree-optimization/66856 (ICE in compute_live_loop_exits, at tree-ssa-loop-manip.c:234) 2016-01-15 Richard Biener PR tree-optimization/66856 * tree-vect-loop.c (vect_transform_loop): Free SLP instances here. * tree-vect-slp.c (vect_free_slp_tree): Decrement stmt reference count. (vect_create_new_slp_node): Increment stmt reference count. (vect_get_and_check_slp_defs): Make sure stmts are nor already in an SLP tree before swapping operands. (vect_build_slp_tree): Likewise. (destroy_bb_vec_info): Free stmt info after SLP instances. * tree-vect-stmts.c (new_stmt_vec_info): Initialize reference count. * tree-vectorizer.h (struct _stmt_vec_info): Add num_slp_uses field. (STMT_VINFO_NUM_SLP_USES): New macro. * gcc.dg/torture/pr66856-1.c: New testcase. * gcc.dg/torture/pr66856-2.c: Likewise. From-SVN: r232435 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 675893e69931..067fb0757952 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2016-01-15 Richard Biener + + PR tree-optimization/66856 + * tree-vect-loop.c (vect_transform_loop): Free SLP instances here. + * tree-vect-slp.c (vect_free_slp_tree): Decrement stmt reference count. + (vect_create_new_slp_node): Increment stmt reference count. + (vect_get_and_check_slp_defs): Make sure stmts are nor already in + an SLP tree before swapping operands. + (vect_build_slp_tree): Likewise. + (destroy_bb_vec_info): Free stmt info after SLP instances. + * tree-vect-stmts.c (new_stmt_vec_info): Initialize reference count. + * tree-vectorizer.h (struct _stmt_vec_info): Add num_slp_uses field. + (STMT_VINFO_NUM_SLP_USES): New macro. + 2016-01-15 Richard Biener PR debug/69137 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a09358502f67..bc6105d922ee 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2016-01-15 Richard Biener + + PR tree-optimization/66856 + * gcc.dg/torture/pr66856-1.c: New testcase. + * gcc.dg/torture/pr66856-2.c: Likewise. + 2016-01-15 Richard Biener PR debug/69137 diff --git a/gcc/testsuite/gcc.dg/torture/pr66856-1.c b/gcc/testsuite/gcc.dg/torture/pr66856-1.c new file mode 100644 index 000000000000..9da89fb48861 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr66856-1.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-mavx2" { target x86_64-*-* i?86-*-* } } */ + +short c; +int d; +int fn1(int p1, int p2) { + int a, b; + a = p1 >> 3 & p2; + b = p1 & 072; + a |= a >> 5; + a |= b >> 5; + return a; +} +void fn2() { + short *e = &c; + int *f; + int g; + while (d -= 4) { + fn1(1, 1); + fn1(1, 1) * fn1(1, 1) * fn1(1, 1); + *e++ = fn1(*f++, g); + *e++ = fn1(*f++, g); + } +} diff --git a/gcc/testsuite/gcc.dg/torture/pr66856-2.c b/gcc/testsuite/gcc.dg/torture/pr66856-2.c new file mode 100644 index 000000000000..50890853db9f --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr66856-2.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ + +typedef int uint32_t; +int c, e, f, g, h; +short *d; +uint32_t fn1(uint32_t p1, uint32_t p2) +{ + uint32_t a, b; + a = p1 >> 3 & p2; + b = p1 & 072; + a |= a >> 5; + a |= b >> 5; + return a; +} + +void fn2() +{ + uint32_t *i; + uint32_t j; + while (c -= 4) { + fn1(e, j); + fn1(f, j) * fn1(g, j) * fn1(h, j); + *d++ = fn1(*i++, j); + *d++ = fn1(*i++, j); + } +} diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 83ded8b7fb2f..60346725a441 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -6930,4 +6930,11 @@ vect_transform_loop (loop_vec_info loop_vinfo) "OUTER LOOP VECTORIZED\n"); dump_printf (MSG_NOTE, "\n"); } + + /* Free SLP instances here because otherwise stmt reference counting + won't work. */ + slp_instance instance; + FOR_EACH_VEC_ELT (LOOP_VINFO_SLP_INSTANCES (loop_vinfo), i, instance) + vect_free_slp_instance (instance); + LOOP_VINFO_SLP_INSTANCES (loop_vinfo).release (); } diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index fe422f858fe7..5767e19e8847 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -54,6 +54,15 @@ vect_free_slp_tree (slp_tree node) FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child) vect_free_slp_tree (child); + gimple *stmt; + FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt) + /* After transform some stmts are removed and thus their vinfo is gone. */ + if (vinfo_for_stmt (stmt)) + { + gcc_assert (STMT_VINFO_NUM_SLP_USES (vinfo_for_stmt (stmt)) > 0); + STMT_VINFO_NUM_SLP_USES (vinfo_for_stmt (stmt))--; + } + SLP_TREE_CHILDREN (node).release (); SLP_TREE_SCALAR_STMTS (node).release (); SLP_TREE_VEC_STMTS (node).release (); @@ -102,6 +111,10 @@ vect_create_new_slp_node (vec scalar_stmts) SLP_TREE_TWO_OPERATORS (node) = false; SLP_TREE_DEF_TYPE (node) = vect_internal_def; + unsigned i; + FOR_EACH_VEC_ELT (scalar_stmts, i, stmt) + STMT_VINFO_NUM_SLP_USES (vinfo_for_stmt (stmt))++; + return node; } @@ -401,6 +414,20 @@ again: /* Swap operands. */ if (swapped) { + /* If there are already uses of this stmt in a SLP instance then + we've committed to the operand order and can't swap it. */ + if (STMT_VINFO_NUM_SLP_USES (vinfo_for_stmt (stmt)) != 0) + { + if (dump_enabled_p ()) + { + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "Build SLP failed: cannot swap operands of " + "shared stmt "); + dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + } + return -1; + } + if (first_op_cond) { tree cond = gimple_assign_rhs1 (stmt); @@ -411,6 +438,12 @@ again: else swap_ssa_operands (stmt, gimple_assign_rhs1_ptr (stmt), gimple_assign_rhs2_ptr (stmt)); + if (dump_enabled_p ()) + { + dump_printf_loc (MSG_NOTE, vect_location, + "swapped operands to match def types in "); + dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0); + } } return 0; @@ -1007,6 +1040,23 @@ vect_build_slp_tree (vec_info *vinfo, behavior. */ && *npermutes < 4) { + /* Verify if we can safely swap or if we committed to a specific + operand order already. */ + for (j = 0; j < group_size; ++j) + if (!matches[j] + && STMT_VINFO_NUM_SLP_USES (vinfo_for_stmt (stmts[j])) != 0) + { + if (dump_enabled_p ()) + { + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "Build SLP failed: cannot swap operands " + "of shared stmt "); + dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, + stmts[j], 0); + } + goto fail; + } + /* Swap mismatched definition stmts. */ dump_printf_loc (MSG_NOTE, vect_location, "Re-trying with swapped operands of stmts "); @@ -1095,6 +1145,7 @@ vect_build_slp_tree (vec_info *vinfo, ++*npermutes; } +fail: gcc_assert (child == NULL); FOR_EACH_VEC_ELT (children, j, child) vect_free_slp_tree (child); @@ -2186,18 +2237,21 @@ new_bb_vec_info (gimple_stmt_iterator region_begin, static void destroy_bb_vec_info (bb_vec_info bb_vinfo) { - vec slp_instances; slp_instance instance; - basic_block bb; - gimple_stmt_iterator si; unsigned i; if (!bb_vinfo) return; - bb = BB_VINFO_BB (bb_vinfo); + vect_destroy_datarefs (bb_vinfo); + free_dependence_relations (BB_VINFO_DDRS (bb_vinfo)); + BB_VINFO_GROUPED_STORES (bb_vinfo).release (); + FOR_EACH_VEC_ELT (BB_VINFO_SLP_INSTANCES (bb_vinfo), i, instance) + vect_free_slp_instance (instance); + BB_VINFO_SLP_INSTANCES (bb_vinfo).release (); + destroy_cost_data (BB_VINFO_TARGET_COST_DATA (bb_vinfo)); - for (si = bb_vinfo->region_begin; + for (gimple_stmt_iterator si = bb_vinfo->region_begin; gsi_stmt (si) != gsi_stmt (bb_vinfo->region_end); gsi_next (&si)) { gimple *stmt = gsi_stmt (si); @@ -2211,16 +2265,8 @@ destroy_bb_vec_info (bb_vec_info bb_vinfo) gimple_set_uid (stmt, -1); } - vect_destroy_datarefs (bb_vinfo); - free_dependence_relations (BB_VINFO_DDRS (bb_vinfo)); - BB_VINFO_GROUPED_STORES (bb_vinfo).release (); - slp_instances = BB_VINFO_SLP_INSTANCES (bb_vinfo); - FOR_EACH_VEC_ELT (slp_instances, i, instance) - vect_free_slp_instance (instance); - BB_VINFO_SLP_INSTANCES (bb_vinfo).release (); - destroy_cost_data (BB_VINFO_TARGET_COST_DATA (bb_vinfo)); + BB_VINFO_BB (bb_vinfo)->aux = NULL; free (bb_vinfo); - bb->aux = NULL; } diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 872fa0766401..635c7970fca0 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -8391,6 +8391,8 @@ new_stmt_vec_info (gimple *stmt, vec_info *vinfo) STMT_VINFO_SAME_ALIGN_REFS (res).create (0); STMT_SLP_TYPE (res) = loop_vect; + STMT_VINFO_NUM_SLP_USES (res) = 0; + GROUP_FIRST_ELEMENT (res) = NULL; GROUP_NEXT_ELEMENT (res) = NULL; GROUP_SIZE (res) = 0; diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 1465070a0066..0a3f5d75ffba 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -601,6 +601,8 @@ typedef struct _stmt_vec_info { /* For reduction loops, this is the type of reduction. */ enum vect_reduction_type v_reduc_type; + /* The number of scalar stmt references from active SLP instances. */ + unsigned int num_slp_uses; } *stmt_vec_info; /* Access Functions. */ @@ -653,6 +655,7 @@ STMT_VINFO_BB_VINFO (stmt_vec_info stmt_vinfo) #define STMT_VINFO_LOOP_PHI_EVOLUTION_BASE_UNCHANGED(S) (S)->loop_phi_evolution_base_unchanged #define STMT_VINFO_LOOP_PHI_EVOLUTION_PART(S) (S)->loop_phi_evolution_part #define STMT_VINFO_MIN_NEG_DIST(S) (S)->min_neg_dist +#define STMT_VINFO_NUM_SLP_USES(S) (S)->num_slp_uses #define GROUP_FIRST_ELEMENT(S) (S)->first_element #define GROUP_NEXT_ELEMENT(S) (S)->next_element