On Wed, Apr 15, 2020 at 03:47:55AM -0500, luoxhu--- via Gcc-patches wrote:
>       2020-04-15  Xiong Hu Luo  <luo...@linux.ibm.com>
> 
>       PR rtl-optimization/37451, PR target/61837
>       loop-doloop.c (doloop_modify): Simplify (add -1; zero_ext; add +1)

"* " missing before loop-doloop.c

>       to zero_ext.
> ---
>  gcc/loop-doloop.c | 26 +++++++++++++++++++++++++-
>  1 file changed, 25 insertions(+), 1 deletion(-)
> 
> diff --git a/gcc/loop-doloop.c b/gcc/loop-doloop.c
> index db6a014e43d..9f967fa3a0b 100644
> --- a/gcc/loop-doloop.c
> +++ b/gcc/loop-doloop.c
> @@ -477,7 +477,31 @@ doloop_modify (class loop *loop, class niter_desc *desc,
>      }
>  
>    if (increment_count)
> -    count = simplify_gen_binary (PLUS, mode, count, const1_rtx);
> +    {
> +      /* Fold (add -1; zero_ext; add +1) operations to zero_ext based on 
> addop0
> +      is never zero, as gimple pass loop ch will do optimization to simplify
> +      the loop to NO loop for loop condition is false.  */

There is no guarantee the loop ch pass was run, one can do
-fno-tree-loop-ch, -fdisable-tree-ch, -fdisable-tree-ch=foobar or
perhaps the zext(x-1)+1 has been introduced after it (either the loop
appeared post that at GIMPLE or later)?
IMHO if you want something like that, you need to prove at the RTL level
that addop0 must be non-zero, perhaps using saved VRP info from the GIMPLE
stuff if there is REG_EXPR mapping it to a SSA_NAME with one (though even
that might not be safe if things changed during RTL opts).

> +      bool simplify_zext = false;
> +      rtx extop0 = XEXP (count, 0);
> +      if (mode == E_DImode

Why hardcode DImode and SImode?  In generic code, shouldn't it work with
something more generic, like word_mode and MODE_INT mode twice as big as
the word_mode (or do you want MODE_INT mode with half the size of word_mode
and word_mode)?

> +       && GET_CODE (count) == ZERO_EXTEND
> +       && GET_CODE (extop0) == PLUS)
> +     {
> +       rtx addop0 = XEXP (extop0, 0);
> +       rtx addop1 = XEXP (extop0, 1);
> +       if (CONST_SCALAR_INT_P (addop1)
> +           && GET_MODE (addop0) == E_SImode
> +           && addop1 == GEN_INT (-1))
> +         {
> +           count = simplify_gen_unary (ZERO_EXTEND, mode, addop0,
> +                                       GET_MODE (addop0));
> +           simplify_zext = true;
> +         }
> +     }
> +
> +      if (!simplify_zext)
> +     count = simplify_gen_binary (PLUS, mode, count, const1_rtx);
> +    }

        Jakub

Reply via email to