Look through widening type conversions for possible edge assertions
diff mbox

Message ID CAFiYyc0Ved1EyHPA4HXzkrrHeo=JhYJg4d6JZ7AasktoVn=VxA@mail.gmail.com
State New
Headers show

Commit Message

Richard Biener Nov. 11, 2014, 1:48 p.m. UTC
On Tue, Nov 11, 2014 at 1:10 PM, Patrick Palka <patrick@parcs.ath.cx> wrote:
> This patch is a replacement for the 2nd VRP refactoring patch.  It
> simply teaches VRP to look through widening type conversions when
> finding suitable edge assertions, e.g.
>
> bool p = x != y;
> int q = (int) p;
> if (q == 0) // new edge assert: p == 0 and therefore x == y

I think the proper fix is to forward x != y to q == 0 instead of this one.
That said - the tree-ssa-forwprop.c restriction on only forwarding
single-uses into conditions is clearly bogus here.  I suggest to
relax it for conversions and compares.  Like with



Thanks,
Richard.

> The new testcase requires that such an edge assertion be inserted.
>
> Full bootstrap + regtest on x86_64-unknown-linux-gnu in progress.  Does
> the patch look OK for trunk if no new regressions?
>
> 2014-11-11  Patrick Palka  <ppalka@gcc.gnu.org>
>
> gcc/
>         * tree-vrp.c (register_edge_assert_for): Look through
>         widening type conversions for posible edge assertions.
>
> gcc/testsuite/
>         * gcc.dg/vrp-1.c: New testcase.
> ---
>  gcc/testsuite/gcc.dg/vrp-1.c | 31 +++++++++++++++++++++++++++++++
>  gcc/tree-vrp.c               | 22 ++++++++++++++++++++++
>  2 files changed, 53 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.dg/vrp-1.c
>
> diff --git a/gcc/testsuite/gcc.dg/vrp-1.c b/gcc/testsuite/gcc.dg/vrp-1.c
> new file mode 100644
> index 0000000..df5334e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/vrp-1.c
> @@ -0,0 +1,31 @@
> +/* { dg-options "-O2" } */
> +
> +void runtime_error (void) __attribute__ ((noreturn));
> +void compiletime_error (void) __attribute__ ((noreturn, error ("")));
> +
> +static void
> +compiletime_check_equals_1 (int *x, int y)
> +{
> +  int __p = *x != y;
> +  if (__builtin_constant_p (__p) && __p)
> +    compiletime_error ();
> +  if (__p)
> +    runtime_error ();
> +}
> +
> +static void
> +compiletime_check_equals_2 (int *x, int y)
> +{
> +  int __p = *x != y;
> +  if (__builtin_constant_p (__p) && __p)
> +    compiletime_error (); /* { dg-error "call to" } */
> +  if (__p)
> +    runtime_error ();
> +}
> +
> +void
> +foo (int *x)
> +{
> +  compiletime_check_equals_1 (x, 5);
> +  compiletime_check_equals_2 (x, 10);
> +}
> diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
> index f0a4382..979ab44 100644
> --- a/gcc/tree-vrp.c
> +++ b/gcc/tree-vrp.c
> @@ -5634,6 +5634,7 @@ register_edge_assert_for (tree name, edge e, gimple_stmt_iterator si,
>       the value zero or one, then we may be able to assert values
>       for SSA_NAMEs which flow into COND.  */
>
> +
>    /* In the case of NAME == 1 or NAME != 0, for BIT_AND_EXPR defining
>       statement of NAME we can assert both operands of the BIT_AND_EXPR
>       have nonzero value.  */
> @@ -5673,6 +5674,27 @@ register_edge_assert_for (tree name, edge e, gimple_stmt_iterator si,
>           register_edge_assert_for_1 (op1, EQ_EXPR, e, si);
>         }
>      }
> +
> +  /* In the case of NAME != 0 or NAME == 0, if NAME's defining statement
> +     is a widening type conversion then we can assert that NAME's
> +     RHS is accordingly nonzero or zero.  */
> +  if ((comp_code == EQ_EXPR || comp_code == NE_EXPR)
> +      && integer_zerop (val))
> +    {
> +      gimple def_stmt = SSA_NAME_DEF_STMT (name);
> +      if (is_gimple_assign (def_stmt))
> +       {
> +         enum tree_code def_code = gimple_assign_rhs_code (def_stmt);
> +         if (CONVERT_EXPR_CODE_P (def_code))
> +           {
> +             tree lhs = gimple_assign_lhs (def_stmt);
> +             tree rhs = gimple_assign_rhs1 (def_stmt);
> +             if (TYPE_PRECISION (TREE_TYPE (lhs))
> +                 >= TYPE_PRECISION (TREE_TYPE (rhs)))
> +               register_edge_assert_for_1 (rhs, comp_code, e, si);
> +           }
> +       }
> +    }
>  }
>
>
> --
> 2.2.0.rc1.16.g6066a7e
>

Patch
diff mbox

Index: tree-ssa-forwprop.c
===================================================================
--- tree-ssa-forwprop.c (revision 217349)
+++ tree-ssa-forwprop.c (working copy)
@@ -476,7 +476,7 @@  forward_propagate_into_comparison_1 (gim
        {
          rhs0 = rhs_to_tree (TREE_TYPE (op1), def_stmt);
          tmp = combine_cond_expr_cond (stmt, code, type,
-                                       rhs0, op1, !single_use0_p);
+                                       rhs0, op1, false);
          if (tmp)
            return tmp;
        }