On Tue, 7 Feb 2017, Jakub Jelinek wrote: > Hi! > > While looking at the RTL problem when combiner optimizes away > (x & 0xfffe) % 0xffff into just (x & 0xfffe), I've looked at VRP > which optimizes that case well (-O2 only, the PR is -O1), but discovered > that it isn't generic enough, we actually don't need op1 to be constant > in this case, a range whose (positive) minimum satisfies it can be handled > the same. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk (or > shall I defer it for GCC8)?
Ok for trunk if you adjust the function comment accordingly. Thanks, Richard. > 2017-02-07 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/79408 > * tree-vrp.c (simplify_div_or_mod_using_ranges): If op1 is not > constant, but SSA_NAME with a known integer range, use the minimum > of that range instead of op1 to determine if modulo can be replaced > with its first operand. > > * gcc.dg/tree-ssa/pr79408.c: New test. > > --- gcc/tree-vrp.c.jj 2017-01-30 19:10:50.000000000 +0100 > +++ gcc/tree-vrp.c 2017-02-07 12:33:32.721482609 +0100 > @@ -9241,17 +9241,25 @@ simplify_div_or_mod_using_ranges (gimple > tree val = NULL; > tree op0 = gimple_assign_rhs1 (stmt); > tree op1 = gimple_assign_rhs2 (stmt); > + tree op1min = op1; > value_range *vr = get_value_range (op0); > > if (rhs_code == TRUNC_MOD_EXPR > - && TREE_CODE (op1) == INTEGER_CST > - && tree_int_cst_sgn (op1) == 1 > + && TREE_CODE (op1) == SSA_NAME) > + { > + value_range *vr1 = get_value_range (op1); > + if (range_int_cst_p (vr1)) > + op1min = vr1->min; > + } > + if (rhs_code == TRUNC_MOD_EXPR > + && TREE_CODE (op1min) == INTEGER_CST > + && tree_int_cst_sgn (op1min) == 1 > && range_int_cst_p (vr) > - && tree_int_cst_lt (vr->max, op1)) > + && tree_int_cst_lt (vr->max, op1min)) > { > if (TYPE_UNSIGNED (TREE_TYPE (op0)) > || tree_int_cst_sgn (vr->min) >= 0 > - || tree_int_cst_lt (fold_unary (NEGATE_EXPR, TREE_TYPE (op1), op1), > - vr->min)) > + || tree_int_cst_lt (fold_unary (NEGATE_EXPR, TREE_TYPE (op1min), > + op1min), vr->min)) > { > /* If op0 already has the range op0 % op1 has, > --- gcc/testsuite/gcc.dg/tree-ssa/pr79408.c.jj 2017-02-07 > 16:30:42.439774777 +0100 > +++ gcc/testsuite/gcc.dg/tree-ssa/pr79408.c 2017-02-07 16:32:37.653282317 > +0100 > @@ -0,0 +1,40 @@ > +/* PR tree-optimization/79408 */ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-optimized" } */ > + > +void link_error (void); > + > +void > +foo (unsigned int x, unsigned int y) > +{ > + if (x > 7312) > + return; > + if (y <= 7312) > + return; > + if (x % y != x) > + link_error (); > +} > + > +void > +bar (int x, int y) > +{ > + if (x > 7312 || x < 0) > + return; > + if (y <= 7312) > + return; > + if (x % y != x) > + link_error (); > +} > + > +void > +baz (int x, int y) > +{ > + if (x > 7312 || x < -7312) > + return; > + if (y <= 7312) > + return; > + if (x % y != x) > + link_error (); > +} > + > +/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized"} } */ > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)