diff mbox

Fix phiopt ICE in Factor conversion in COND_EXPR (PR tree-optimization/66949)

Message ID 20151209142223.GR3175@redhat.com
State New
Headers show

Commit Message

Marek Polacek Dec. 9, 2015, 2:22 p.m. UTC
On Wed, Dec 09, 2015 at 11:41:44AM +0100, Richard Biener wrote:
> But I don't see why we have the asserts at all - they seem to be originated from
> development.  IMHO factor_out_conditonal_conversion should simply return
> the new PHI it generates instead of relying on
> signle_non_signelton_phi_for_edges
> to return it.

Ok, that seems to work.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2015-12-09  Marek Polacek  <polacek@redhat.com>

	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.


	Marek

Comments

Richard Biener Dec. 9, 2015, 2:37 p.m. UTC | #1
On Wed, Dec 9, 2015 at 3:22 PM, Marek Polacek <polacek@redhat.com> wrote:
> On Wed, Dec 09, 2015 at 11:41:44AM +0100, Richard Biener wrote:
>> But I don't see why we have the asserts at all - they seem to be originated from
>> development.  IMHO factor_out_conditonal_conversion should simply return
>> the new PHI it generates instead of relying on
>> signle_non_signelton_phi_for_edges
>> to return it.
>
> Ok, that seems to work.
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk?

Ok.

Thanks,
Richard.

> 2015-12-09  Marek Polacek  <polacek@redhat.com>
>
>         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.
>
> diff --git gcc/testsuite/gcc.dg/torture/pr66949-1.c gcc/testsuite/gcc.dg/torture/pr66949-1.c
> index e69de29..1b765bc 100644
> --- gcc/testsuite/gcc.dg/torture/pr66949-1.c
> +++ 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 gcc/testsuite/gcc.dg/torture/pr66949-2.c gcc/testsuite/gcc.dg/torture/pr66949-2.c
> index e69de29..e6250a3 100644
> --- gcc/testsuite/gcc.dg/torture/pr66949-2.c
> +++ 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 gcc/tree-ssa-phiopt.c gcc/tree-ssa-phiopt.c
> index 344cd2f..d7e8aa0 100644
> --- gcc/tree-ssa-phiopt.c
> +++ 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
>
>         Marek
diff mbox

Patch

diff --git gcc/testsuite/gcc.dg/torture/pr66949-1.c gcc/testsuite/gcc.dg/torture/pr66949-1.c
index e69de29..1b765bc 100644
--- gcc/testsuite/gcc.dg/torture/pr66949-1.c
+++ 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 gcc/testsuite/gcc.dg/torture/pr66949-2.c gcc/testsuite/gcc.dg/torture/pr66949-2.c
index e69de29..e6250a3 100644
--- gcc/testsuite/gcc.dg/torture/pr66949-2.c
+++ 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 gcc/tree-ssa-phiopt.c gcc/tree-ssa-phiopt.c
index 344cd2f..d7e8aa0 100644
--- gcc/tree-ssa-phiopt.c
+++ 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