From 0e0997a2d5484e496896f4a6b00245e2c191de1c Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 9 Dec 2015 14:58:22 +0000 Subject: [PATCH] re PR tree-optimization/66949 (ICE at -O2 and -O3 on x86_64-linux-gnu in tree_ssa_phiopt_worker, at tree-ssa-phiopt.c:335) PR tree-optimization/66949 * tree-ssa-phiopt.c (tree_ssa_phiopt_worker): Don't call single_non_singleton_phi_for_edges to get the PHI from factor_out_conditional_conversion. Use NULL_TREE instead of NULL. (factor_out_conditional_conversion): Adjust declaration. Make it return the newly-created PHI. * gcc.dg/torture/pr66949-1.c: New test. * gcc.dg/torture/pr66949-2.c: New test. From-SVN: r231457 --- gcc/ChangeLog | 9 ++++++ gcc/testsuite/ChangeLog | 6 ++++ gcc/testsuite/gcc.dg/torture/pr66949-1.c | 28 ++++++++++++++++++ gcc/testsuite/gcc.dg/torture/pr66949-2.c | 23 +++++++++++++++ gcc/tree-ssa-phiopt.c | 36 ++++++++++++------------ 5 files changed, 84 insertions(+), 18 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr66949-1.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr66949-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 56864aec60a..946e805e3a3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2015-12-09 Marek Polacek + + PR tree-optimization/66949 + * tree-ssa-phiopt.c (tree_ssa_phiopt_worker): Don't call + single_non_singleton_phi_for_edges to get the PHI from + factor_out_conditional_conversion. Use NULL_TREE instead of NULL. + (factor_out_conditional_conversion): Adjust declaration. Make it + return the newly-created PHI. + 2015-12-09 James Greenhalgh * config/aarch64/aarch64-protos.h diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a99f32079e2..e9c102079e8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-12-09 Marek Polacek + + PR tree-optimization/66949 + * gcc.dg/torture/pr66949-1.c: New test. + * gcc.dg/torture/pr66949-2.c: New test. + 2015-12-09 James Greenhalgh PR rtl-optimization/67609 diff --git a/gcc/testsuite/gcc.dg/torture/pr66949-1.c b/gcc/testsuite/gcc.dg/torture/pr66949-1.c new file mode 100644 index 00000000000..1b765bc282e --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr66949-1.c @@ -0,0 +1,28 @@ +/* PR tree-optimization/66949 */ +/* { dg-do compile } */ + +int a, *b = &a, c; + +unsigned short +fn1 (unsigned short p1, unsigned int p2) +{ + return p2 > 1 || p1 >> p2 ? p1 : p1 << p2; +} + +void +fn2 () +{ + int *d = &a; + for (a = 0; a < -1; a = 1) + ; + if (a < 0) + c = 0; + *b = fn1 (*d || c, *d); +} + +int +main () +{ + fn2 (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr66949-2.c b/gcc/testsuite/gcc.dg/torture/pr66949-2.c new file mode 100644 index 00000000000..e6250a34471 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr66949-2.c @@ -0,0 +1,23 @@ +/* PR tree-optimization/66949 */ +/* { dg-do compile } */ + +char a; +int b, c, d; +extern int fn2 (void); + +short +fn1 (short p1, short p2) +{ + return p2 == 0 ? p1 : p1 / p2; +} + +int +main (void) +{ + char e = 1; + int f = 7; + c = a >> f; + b = fn1 (c, 0 < d <= e && fn2 ()); + + return 0; +} diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index 344cd2f2701..e5e0a9a6ddb 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -49,7 +49,7 @@ along with GCC; see the file COPYING3. If not see static unsigned int tree_ssa_phiopt_worker (bool, bool); static bool conditional_replacement (basic_block, basic_block, edge, edge, gphi *, tree, tree); -static bool factor_out_conditional_conversion (edge, edge, gphi *, tree, tree); +static gphi *factor_out_conditional_conversion (edge, edge, gphi *, tree, tree); static int value_replacement (basic_block, basic_block, edge, edge, gimple *, tree, tree); static bool minmax_replacement (basic_block, basic_block, @@ -310,19 +310,19 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads) /* Something is wrong if we cannot find the arguments in the PHI node. */ - gcc_assert (arg0 != NULL && arg1 != NULL); + gcc_assert (arg0 != NULL_TREE && arg1 != NULL_TREE); - if (factor_out_conditional_conversion (e1, e2, phi, arg0, arg1)) + gphi *newphi = factor_out_conditional_conversion (e1, e2, phi, + arg0, arg1); + if (newphi != NULL) { + phi = newphi; /* factor_out_conditional_conversion may create a new PHI in BB2 and eliminate an existing PHI in BB2. Recompute values that may be affected by that change. */ - phis = phi_nodes (bb2); - phi = single_non_singleton_phi_for_edges (phis, e1, e2); - gcc_assert (phi); arg0 = gimple_phi_arg_def (phi, e1->dest_idx); arg1 = gimple_phi_arg_def (phi, e2->dest_idx); - gcc_assert (arg0 != NULL && arg1 != NULL); + gcc_assert (arg0 != NULL_TREE && arg1 != NULL_TREE); } /* Do the replacement of conditional if it can be done. */ @@ -402,9 +402,9 @@ replace_phi_edge_with_variable (basic_block cond_block, /* PR66726: Factor conversion out of COND_EXPR. If the arguments of the PHI stmt are CONVERT_STMT, factor out the conversion and perform the conversion - to the result of PHI stmt. */ + to the result of PHI stmt. Return the newly-created PHI, if any. */ -static bool +static gphi * factor_out_conditional_conversion (edge e0, edge e1, gphi *phi, tree arg0, tree arg1) { @@ -421,7 +421,7 @@ factor_out_conditional_conversion (edge e0, edge e1, gphi *phi, statement have the same unary operation, we can handle more than two arguments too. */ if (gimple_phi_num_args (phi) != 2) - return false; + return NULL; /* First canonicalize to simplify tests. */ if (TREE_CODE (arg0) != SSA_NAME) @@ -433,14 +433,14 @@ factor_out_conditional_conversion (edge e0, edge e1, gphi *phi, if (TREE_CODE (arg0) != SSA_NAME || (TREE_CODE (arg1) != SSA_NAME && TREE_CODE (arg1) != INTEGER_CST)) - return false; + return NULL; /* Check if arg0 is an SSA_NAME and the stmt which defines arg0 is a conversion. */ arg0_def_stmt = SSA_NAME_DEF_STMT (arg0); if (!is_gimple_assign (arg0_def_stmt) || !gimple_assign_cast_p (arg0_def_stmt)) - return false; + return NULL; /* Use the RHS as new_arg0. */ convert_code = gimple_assign_rhs_code (arg0_def_stmt); @@ -455,7 +455,7 @@ factor_out_conditional_conversion (edge e0, edge e1, gphi *phi, arg1_def_stmt = SSA_NAME_DEF_STMT (arg1); if (!is_gimple_assign (arg1_def_stmt) || gimple_assign_rhs_code (arg1_def_stmt) != convert_code) - return false; + return NULL; /* Use the RHS as new_arg1. */ new_arg1 = gimple_assign_rhs1 (arg1_def_stmt); @@ -471,21 +471,21 @@ factor_out_conditional_conversion (edge e0, edge e1, gphi *phi, if (gimple_assign_cast_p (arg0_def_stmt)) new_arg1 = fold_convert (TREE_TYPE (new_arg0), arg1); else - return false; + return NULL; } else - return false; + return NULL; } /* If arg0/arg1 have > 1 use, then this transformation actually increases the number of expressions evaluated at runtime. */ if (!has_single_use (arg0) || (arg1_def_stmt && !has_single_use (arg1))) - return false; + return NULL; /* If types of new_arg0 and new_arg1 are different bailout. */ if (!types_compatible_p (TREE_TYPE (new_arg0), TREE_TYPE (new_arg1))) - return false; + return NULL; /* Create a new PHI stmt. */ result = PHI_RESULT (phi); @@ -528,7 +528,7 @@ factor_out_conditional_conversion (edge e0, edge e1, gphi *phi, /* Remove the original PHI stmt. */ gsi = gsi_for_stmt (phi); gsi_remove (&gsi, true); - return true; + return newphi; } /* The function conditional_replacement does the main work of doing the -- 2.30.2