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

Richard Biener richard.guenther@gmail.com
Wed Dec 9 10:41:00 GMT 2015


On Tue, Dec 8, 2015 at 5:21 PM, Marek Polacek <polacek@redhat.com> wrote:
> The following is a conservative fix for this PR.  This is an ICE transpiring
> in the new "Factor conversion in COND_EXPR" optimization added in r225722.
>
> Before this optimization kicks in, we have
>   <bb 2>:
>   ...
>   p1_32 = (short unsigned int) _20;
>
>   <bb 3>:
>   ...
>   iftmp.0_18 = (short unsigned int) _20;
>
>   <bb 4>:
>   ...
>   # iftmp.0_19 = PHI <iftmp.0_18(3), p1_32(2)>
>
> after factor_out_conditional_conversion does its work, we end up with those two
> def stmts removed and instead of the PHI we'll have
>
>   # _35 = PHI <_20(3), _20(2)>
>   iftmp.0_19 = (short unsigned int) _35;
>
> That itself looks like a fine optimization, but after factor_out_conditional_conversion
> there's
>  320               phis = phi_nodes (bb2);
>  321               phi = single_non_singleton_phi_for_edges (phis, e1, e2);
>  322               gcc_assert (phi);
> and phis look like
>   b.2_38 = PHI <b.2_9(3), b.2_9(2)>
>   _35 = PHI <_20(3), _20(2)>
> so single_non_singleton_phi_for_edges returns NULL and the subsequent assert triggers.
>
> With this patch we won't ICE (and PRE should clean this up anyway), but I don't know,
> maybe I should try harder to optimize even this problematical case (not sure how hard
> it would be...)?
>
> pr66949-2.c only ICEd on powerpc64le and I have verified that this patch fixes it too.
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk?

Hmm.

Yes, there is an opportunity for optimization.

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.

Richard.

> 2015-12-08  Marek Polacek  <polacek@redhat.com>
>
>         PR tree-optimization/66949
>         * tree-ssa-phiopt.c (factor_out_conditional_conversion): Return false if
>         NEW_ARG0 and NEW_ARG1 are equal.
>
>         * 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..caac5d5 100644
> --- gcc/tree-ssa-phiopt.c
> +++ gcc/tree-ssa-phiopt.c
> @@ -477,6 +477,11 @@ factor_out_conditional_conversion (edge e0, edge e1, gphi *phi,
>         return false;
>      }
>
> +  /* If we were to continue, we'd create a PHI with same arguments for edges
> +     E0 and E1.  That could get us in trouble later, so punt.  */
> +  if (operand_equal_for_phi_arg_p (new_arg0, new_arg1))
> +    return false;
> +
>    /*  If arg0/arg1 have > 1 use, then this transformation actually increases
>        the number of expressions evaluated at runtime.  */
>    if (!has_single_use (arg0)
>
>         Marek



More information about the Gcc-patches mailing list