On Wed, Nov 22, 2023 at 10:07 PM Feng Wang <wangf...@eswincomputing.com> wrote:
>
> This patch add another condition for gimple-cond optimization. Refer to
> the following test case.
> int foo1 (int data, int res)
> {
>   res = data & 0xf;
>   res |= res << 4;
>   if (res < 0x22)
>     return 0x22;
>   return res;
> }
> with the compilation flag "-march=rv64gc_zba_zbb -mabi=lp64d -O2",
> before this patch the compilation result is
> foo1:
>         andi    a0,a0,15
>         slliw   a5,a0,4
>         addw    a3,a5,a0
>         li      a4,33
>         add     a0,a5,a0
>         bleu    a3,a4,.L5
>         ret
> .L5:
>         li      a0,34
>         ret
> after this patch the compilation result is
> foo1:
>         andi    a0,a0,15
>         slliw   a5,a0,4
>         add     a5,a5,a0
>         li      a0,34
>         max     a0,a5,a0
>         ret
> The reason is in the pass_early_vrp, the arg0 of gimple_cond
> is replaced,but the PHI node still use the arg0.
> The some of evrp pass logs are as follows
>  gimple_assign <mult_expr, _9, _7, 17, NULL>
>   gimple_assign <nop_expr, res_5, _9, NULL, NULL>
>   gimple_cond <le_expr, _9, 33, NULL, NULL>
>     goto <bb 3>; [INV]
>   else
>     goto <bb 4>; [INV]
>
>   <bb 3> :
>   // predicted unlikely by early return (on trees) predictor.
>
>   <bb 4> :
>   # gimple_phi <_2, 34(3), res_5(2)>
> The arg0 of gimple_cond is replaced by _9,but the gimple_phi still
> uses res_5,it will cause optimization fail of PHI node to MAX_EXPR.
> So the next_use_is_phi is added to control the replacement.
>
> gcc/ChangeLog:
>
>         * vr-values.cc (next_use_is_phi):
>         (simplify_using_ranges::simplify_casted_compare):
>             add new function next_use_is_phi to control the replacement.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.target/riscv/zbb-min-max-04.c: New test.

One more comment, since this is a generic gimple change, you should
add a testcase that is not riscv specific that scans the tree dumps. I
would scan phiopt1 in this case to make sure we MAX_EXPR is created
early on.

Thanks,
Andrew Pinski


> ---
>  gcc/testsuite/gcc.target/riscv/zbb-min-max-04.c | 14 ++++++++++++++
>  gcc/vr-values.cc                                | 15 ++++++++++++++-
>  2 files changed, 28 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-min-max-04.c
>
> diff --git a/gcc/testsuite/gcc.target/riscv/zbb-min-max-04.c 
> b/gcc/testsuite/gcc.target/riscv/zbb-min-max-04.c
> new file mode 100644
> index 00000000000..8c3e87a35e0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/zbb-min-max-04.c
> @@ -0,0 +1,14 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gc_zba_zbb -mabi=lp64d" } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
> +
> +int foo1 (int data, int res)
> +{
> +  res = data & 0xf;
> +  res |= res << 4;
> +  if (res < 0x22)
> +    return 0x22;
> +  return res;
> +}
> +
> +/* { dg-final { scan-assembler-times "max\t" 1 } } */
> \ No newline at end of file
> diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc
> index ecb294131b0..1f7a727c638 100644
> --- a/gcc/vr-values.cc
> +++ b/gcc/vr-values.cc
> @@ -1263,6 +1263,18 @@ simplify_using_ranges::simplify_compare_using_ranges_1 
> (tree_code &cond_code, tr
>    return happened;
>  }
>
> +/* Return true if the next use of SSA_NAME is PHI node */
> +bool
> +next_use_is_phi (tree arg)
> +{
> +  use_operand_p imm = &(SSA_NAME_IMM_USE_NODE (arg));
> +  use_operand_p next = imm->next;
> +  if (next && next->loc.stmt
> +      && (gimple_code (next->loc.stmt) == GIMPLE_PHI))
> +    return true;
> +  return false;
> +}
> +
>  /* Simplify OP0 code OP1 when OP1 is a constant and OP0 was a SSA_NAME
>     defined by a type conversion. Replacing OP0 with RHS of the type 
> conversion.
>     Doing so makes the conversion dead which helps subsequent passes.  */
> @@ -1305,7 +1317,8 @@ simplify_using_ranges::simplify_casted_compare 
> (tree_code &, tree &op0, tree &op
>        if (TREE_CODE (innerop) == SSA_NAME
>           && !POINTER_TYPE_P (TREE_TYPE (innerop))
>           && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop)
> -         && desired_pro_or_demotion_p (TREE_TYPE (innerop), TREE_TYPE (op0)))
> +         && desired_pro_or_demotion_p (TREE_TYPE (innerop), TREE_TYPE (op0))
> +          && !next_use_is_phi (op0))
>         {
>           value_range vr;
>
> --
> 2.17.1
>

Reply via email to