On Mon, 13 Feb 2017, Jakub Jelinek wrote:

> On Mon, Feb 13, 2017 at 09:59:12AM +0100, Richard Biener wrote:
> > On Sun, 12 Feb 2017, Marc Glisse wrote:
> > 
> > > On Sun, 12 Feb 2017, Marc Glisse wrote:
> > > 
> > > > On Tue, 7 Feb 2017, Jakub Jelinek wrote:
> > > > 
> > > > >       * 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.
> > > > 
> > > > Would it make sense to use something like the operand_less_p helper so 
> > > > we
> > > > would also handle an INTEGER_CST lhs?
> > > 
> > > Oops, operand_less_p is just a helper for compare_values_warnv and even 
> > > that
> > > one doesn't seem to use ranges, so there may not already be a nice 
> > > function we
> > > can call (?). The idea remains that reusing such code would help handle 
> > > more
> > > cases (it may even handle a few symbolic cases).
> > 
> > Yeah, we only have the compare_range_with_value / compare_ranges functions
> > and those require you to "expand" the value you have a range for first.
> 
> I think we can do something like following, but not sure how you want to
> actually simplify it using helpers.  The only thing I can think of is
> something like get_value_range that works on both SSA_NAMEs and
> INTEGER_CSTs, but then it either has to allocate a new value range struct
> for the INTEGER_CST case, or be more like extract_range_from_tree and
> then it would copy the range for the SSA_NAME case, penalizing the code.

You'd of course allocate it on the stack.  But yeah, sth like your patch
works for me.

Richard.

> 2017-02-13  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR tree-optimization/79408
>       * tree-vrp.c (simplify_div_or_mod_using_ranges): Handle also the
>       case when on TRUNC_MOD_EXPR op0 is INTEGER_CST.
>       (simplify_stmt_using_ranges): Call simplify_div_or_mod_using_ranges
>       also if rhs1 is INTEGER_CST.
> 
>       * gcc.dg/tree-ssa/pr79408-2.c: New test.
> 
> --- gcc/tree-vrp.c.jj 2017-02-08 10:21:31.000000000 +0100
> +++ gcc/tree-vrp.c    2017-02-13 10:55:00.755070795 +0100
> @@ -9241,8 +9241,24 @@ simplify_div_or_mod_using_ranges (gimple
>    tree val = NULL;
>    tree op0 = gimple_assign_rhs1 (stmt);
>    tree op1 = gimple_assign_rhs2 (stmt);
> +  tree op0min = NULL_TREE, op0max = NULL_TREE;
>    tree op1min = op1;
> -  value_range *vr = get_value_range (op0);
> +  value_range *vr = NULL;
> +
> +  if (TREE_CODE (op0) == INTEGER_CST)
> +    {
> +      op0min = op0;
> +      op0max = op0;
> +    }
> +  else
> +    {
> +      vr = get_value_range (op0);
> +      if (range_int_cst_p (vr))
> +     {
> +       op0min = vr->min;
> +       op0max = vr->max;
> +     }
> +    }
>  
>    if (rhs_code == TRUNC_MOD_EXPR
>        && TREE_CODE (op1) == SSA_NAME)
> @@ -9254,13 +9270,13 @@ simplify_div_or_mod_using_ranges (gimple
>    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, op1min))
> +      && op0max
> +      && tree_int_cst_lt (op0max, op1min))
>      {
>        if (TYPE_UNSIGNED (TREE_TYPE (op0))
> -       || tree_int_cst_sgn (vr->min) >= 0
> +       || tree_int_cst_sgn (op0min) >= 0
>         || tree_int_cst_lt (fold_unary (NEGATE_EXPR, TREE_TYPE (op1min), 
> op1min),
> -                           vr->min))
> +                           op0min))
>       {
>         /* If op0 already has the range op0 % op1 has,
>            then TRUNC_MOD_EXPR won't change anything.  */
> @@ -9269,6 +9285,9 @@ simplify_div_or_mod_using_ranges (gimple
>       }
>      }
>  
> +  if (TREE_CODE (op0) != SSA_NAME)
> +    return false;
> +
>    if (!integer_pow2p (op1))
>      {
>        /* X % -Y can be only optimized into X % Y either if
> @@ -10377,7 +10396,8 @@ simplify_stmt_using_ranges (gimple_stmt_
>        range.  */
>       case TRUNC_DIV_EXPR:
>       case TRUNC_MOD_EXPR:
> -       if (TREE_CODE (rhs1) == SSA_NAME
> +       if ((TREE_CODE (rhs1) == SSA_NAME
> +            || TREE_CODE (rhs1) == INTEGER_CST)
>             && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
>           return simplify_div_or_mod_using_ranges (gsi, stmt);
>         break;
> --- gcc/testsuite/gcc.dg/tree-ssa/pr79408-2.c.jj      2017-02-13 
> 10:51:13.939063664 +0100
> +++ gcc/testsuite/gcc.dg/tree-ssa/pr79408-2.c 2017-02-13 10:52:33.868008990 
> +0100
> @@ -0,0 +1,34 @@
> +/* PR tree-optimization/79408 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +void link_error (void);
> +
> +void
> +foo (unsigned int y)
> +{
> +  if (y <= 7312)
> +    return;
> +  if (7312 % y != 7312)
> +    link_error ();
> +}
> +
> +void
> +bar (int x, int y)
> +{
> +  if (y <= 7312)
> +    return;
> +  if (7312 % y != 7312)
> +    link_error ();
> +}
> +
> +void
> +baz (int x, int y)
> +{
> +  if (y <= 7312)
> +    return;
> +  if (-7312 % y != -7312)
> +    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)

Reply via email to