On Tue, 12 Jan 2021, Jakub Jelinek wrote:

> Hi!
> 
> As the testcase shows, my latest changes caused ICE on that testcase.
> The problem is that arith_overflow_check_p now can change the use_stmt
> argument (has a reference), so that if it succeeds (returns non-zero),
> it points it to the GIMPLE_COND or EQ/NE or COND_EXPR assignment from the
> TRUNC_DIV_EXPR assignment.
> The problem was that it would change use_stmt also if it returned 0 in some
> cases, such as multiple imm uses of the division, and in one of the callers
> if arith_overflow_check_p returns 0 it looks at use_stmt again and performs
> other checks, which of course assumes that use_stmt is the one passed
> to arith_overflow_check_p and not e.g. NULL instead or some other unrelated
> stmt.
> 
> The following patch fixes that by only changing use_stmt when we are about
> to return non-zero (for the MULT_EXPR case, which is the only one with the
> need to use different use_stmt).
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Richard.

> 2021-01-12  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR tree-optimization/98629
>       * tree-ssa-math-opts.c (arith_overflow_check_p): Don't update use_stmt
>       unless returning non-zero.
> 
>       * gcc.c-torture/compile/pr98629.c: New test.
> 
> --- gcc/tree-ssa-math-opts.c.jj       2021-01-11 10:35:02.196501461 +0100
> +++ gcc/tree-ssa-math-opts.c  2021-01-11 23:56:24.154380944 +0100
> @@ -3667,6 +3667,7 @@ arith_overflow_check_p (gimple *stmt, gi
>    tree rhs1 = gimple_assign_rhs1 (stmt);
>    tree rhs2 = gimple_assign_rhs2 (stmt);
>    tree multop = NULL_TREE, divlhs = NULL_TREE;
> +  gimple *cur_use_stmt = use_stmt;
>  
>    if (code == MULT_EXPR)
>      {
> @@ -3697,26 +3698,26 @@ arith_overflow_check_p (gimple *stmt, gi
>        if (!divlhs)
>       return 0;
>        use_operand_p use;
> -      if (!single_imm_use (divlhs, &use, &use_stmt))
> +      if (!single_imm_use (divlhs, &use, &cur_use_stmt))
>       return 0;
>      }
> -  if (gimple_code (use_stmt) == GIMPLE_COND)
> +  if (gimple_code (cur_use_stmt) == GIMPLE_COND)
>      {
> -      ccode = gimple_cond_code (use_stmt);
> -      crhs1 = gimple_cond_lhs (use_stmt);
> -      crhs2 = gimple_cond_rhs (use_stmt);
> +      ccode = gimple_cond_code (cur_use_stmt);
> +      crhs1 = gimple_cond_lhs (cur_use_stmt);
> +      crhs2 = gimple_cond_rhs (cur_use_stmt);
>      }
> -  else if (is_gimple_assign (use_stmt))
> +  else if (is_gimple_assign (cur_use_stmt))
>      {
> -      if (gimple_assign_rhs_class (use_stmt) == GIMPLE_BINARY_RHS)
> +      if (gimple_assign_rhs_class (cur_use_stmt) == GIMPLE_BINARY_RHS)
>       {
> -       ccode = gimple_assign_rhs_code (use_stmt);
> -       crhs1 = gimple_assign_rhs1 (use_stmt);
> -       crhs2 = gimple_assign_rhs2 (use_stmt);
> +       ccode = gimple_assign_rhs_code (cur_use_stmt);
> +       crhs1 = gimple_assign_rhs1 (cur_use_stmt);
> +       crhs2 = gimple_assign_rhs2 (cur_use_stmt);
>       }
> -      else if (gimple_assign_rhs_code (use_stmt) == COND_EXPR)
> +      else if (gimple_assign_rhs_code (cur_use_stmt) == COND_EXPR)
>       {
> -       tree cond = gimple_assign_rhs1 (use_stmt);
> +       tree cond = gimple_assign_rhs1 (cur_use_stmt);
>         if (COMPARISON_CLASS_P (cond))
>           {
>             ccode = TREE_CODE (cond);
> @@ -3792,11 +3793,17 @@ arith_overflow_check_p (gimple *stmt, gi
>           {
>             if ((crhs1 == divlhs && arith_cast_equal_p (crhs2, multop))
>                 || (crhs2 == divlhs && arith_cast_equal_p (crhs1, multop)))
> -             return ccode == NE_EXPR ? 1 : -1;
> +             {
> +               use_stmt = cur_use_stmt;
> +               return ccode == NE_EXPR ? 1 : -1;
> +             }
>           }
>         else if ((crhs1 == divlhs && operand_equal_p (crhs2, multop, 0))
>                  || (crhs2 == divlhs && crhs1 == multop))
> -         return ccode == NE_EXPR ? 1 : -1;
> +         {
> +           use_stmt = cur_use_stmt;
> +           return ccode == NE_EXPR ? 1 : -1;
> +         }
>       }
>        break;
>      default:
> --- gcc/testsuite/gcc.c-torture/compile/pr98629.c.jj  2021-01-12 
> 00:00:21.132949613 +0100
> +++ gcc/testsuite/gcc.c-torture/compile/pr98629.c     2021-01-11 
> 23:59:58.178206894 +0100
> @@ -0,0 +1,11 @@
> +/* PR tree-optimization/98629 */
> +
> +unsigned int a;
> +int b, c;
> +
> +void
> +foo (void)
> +{
> +  unsigned int *e = &a;
> +  (a /= a |= b) - (0 <= (*e += *e)) * (c *= *e);
> +}
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)

Reply via email to