On Tue, Nov 11, 2014 at 1:10 PM, Patrick Palka <patr...@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 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; } 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 <ppa...@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 >