On Mon, May 19, 2025 at 10:41 AM Li Xu <xu...@eswincomputing.com> wrote:
>
> From: xuli <xu...@eswincomputing.com>
>
> This patch would like to support .SAT_ADD when IMM=-1.
>
> Form1:
> T __attribute__((noinline))                  \
> sat_s_add_imm_##T##_fmt_1##_##INDEX (T x)             \
> {                                            \
>   T sum = (UT)x + (UT)IMM;                     \
>   return (x ^ IMM) < 0                         \
>     ? sum                                    \
>     : (sum ^ x) >= 0                         \
>       ? sum                                  \
>       : x < 0 ? MIN : MAX;                   \
> }
>
> Take below form1 as example:
> DEF_SAT_S_ADD_IMM_FMT_1(0, int8_t, uint8_t, -1, INT8_MIN, INT8_MAX)
>
> Before this patch:
> __attribute__((noinline))
> int8_t sat_s_add_imm_int8_t_fmt_1_0 (int8_t x)
> {
>   unsigned char x.0_1;
>   unsigned char _2;
>   unsigned char _3;
>   int8_t iftmp.1_4;
>   signed char _8;
>   unsigned char _9;
>   signed char _10;
>
>   <bb 2> [local count: 1073741824]:
>   x.0_1 = (unsigned char) x_5(D);
>   _3 = -x.0_1;
>   _10 = (signed char) _3;
>   _8 = x_5(D) & _10;
>   if (_8 < 0)
>     goto <bb 4>; [1.40%]
>   else
>     goto <bb 3>; [98.60%]
>
>   <bb 3> [local count: 434070867]:
>   _2 = x.0_1 + 255;
>
>   <bb 4> [local count: 1073741824]:
>   # _9 = PHI <_2(3), 128(2)>
>   iftmp.1_4 = (int8_t) _9;
>   return iftmp.1_4;
>
> }
>
> After this patch:
> __attribute__((noinline))
> int8_t sat_s_add_imm_int8_t_fmt_1_0 (int8_t x)
> {
>   int8_t _4;
>
>   <bb 2> [local count: 1073741824]:
>   gimple_call <.SAT_ADD, _4, x_5(D), 255> [tail call]
>   gimple_return <_4>
>
> }
>
> The below test suites are passed for this patch:
> 1. The rv64gcv fully regression tests.
> 2. The x86 bootstrap tests.
> 3. The x86 fully regression tests.

OK.

Richard.

> Signed-off-by: Li Xu <xu...@eswincomputing.com>
>
> gcc/ChangeLog:
>
>         * match.pd: Add signed scalar SAT_ADD IMM form1 with IMM=-1 matching.
>         * tree-ssa-math-opts.cc (match_unsigned_saturation_add): Adapt 
> function name.
>         (match_saturation_add_with_assign): Match signed and unsigned SAT_ADD 
> with assign.
>         (math_opts_dom_walker::after_dom_children): Match imm=-1 signed 
> SAT_ADD with NOP_EXPR case.
>
> ---
>  gcc/match.pd              | 19 ++++++++++++++++++-
>  gcc/tree-ssa-math-opts.cc | 30 +++++++++++++++++++++++++-----
>  2 files changed, 43 insertions(+), 6 deletions(-)
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 98411af3940..a07dbb808d2 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -3403,7 +3403,24 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>                         (bit_xor:c @0 INTEGER_CST@3)) integer_zerop)
>          (signed_integer_sat_val @0)
>          @2)
> -  (if (wi::bit_and (wi::to_wide (@1), wi::to_wide (@3)) == 0))))
> +  (if (wi::bit_and (wi::to_wide (@1), wi::to_wide (@3)) == 0)))
> +
> +(match (signed_integer_sat_add @0 @1)
> +  /* T SUM = (T)((UT)X + (UT)-1);
> +     SAT_S_ADD = (X ^ -1) < 0 ? SUM : (X ^ SUM) >= 0 ? SUM
> +                                                     : (x < 0) ? MIN : MAX  
> */
> +  (convert (cond^ (lt (bit_and:c @0 (nop_convert (negate (nop_convert @0))))
> +             integer_zerop)
> +        INTEGER_CST@2
> +        (plus (nop_convert @0) integer_all_onesp@1)))
> +   (with
> +    {
> +     unsigned precision = TYPE_PRECISION (type);
> +     wide_int c1 = wi::to_wide (@1);
> +     wide_int c2 = wi::to_wide (@2);
> +     wide_int sum = wi::add (c1, c2);
> +    }
> +    (if (wi::eq_p (sum, wi::max_value (precision, SIGNED)))))))
>
>  /* Saturation sub for signed integer.  */
>  (if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type))
> diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc
> index 292eb852f2d..f6a1bea2002 100644
> --- a/gcc/tree-ssa-math-opts.cc
> +++ b/gcc/tree-ssa-math-opts.cc
> @@ -4064,15 +4064,34 @@ build_saturation_binary_arith_call_and_insert 
> (gimple_stmt_iterator *gsi,
>   *   _10 = -_9;
>   *   _12 = _7 | _10;
>   *   =>
> - *   _12 = .SAT_ADD (_4, _6);  */
> + *   _12 = .SAT_ADD (_4, _6);
> + *
> + * Try to match IMM=-1 saturation signed add with assign.
> + * <bb 2> [local count: 1073741824]:
> + * x.0_1 = (unsigned char) x_5(D);
> + * _3 = -x.0_1;
> + * _10 = (signed char) _3;
> + * _8 = x_5(D) & _10;
> + * if (_8 < 0)
> + *   goto <bb 4>; [1.40%]
> + * else
> + *   goto <bb 3>; [98.60%]
> + * <bb 3> [local count: 434070867]:
> + * _2 = x.0_1 + 255;
> + * <bb 4> [local count: 1073741824]:
> + * # _9 = PHI <_2(3), 128(2)>
> + * _4 = (int8_t) _9;
> + *   =>
> + * _4 = .SAT_ADD (x_5, -1); */
>
>  static void
> -match_unsigned_saturation_add (gimple_stmt_iterator *gsi, gassign *stmt)
> +match_saturation_add_with_assign (gimple_stmt_iterator *gsi, gassign *stmt)
>  {
>    tree ops[2];
>    tree lhs = gimple_assign_lhs (stmt);
>
> -  if (gimple_unsigned_integer_sat_add (lhs, ops, NULL))
> +  if (gimple_unsigned_integer_sat_add (lhs, ops, NULL)
> +      || gimple_signed_integer_sat_add (lhs, ops, NULL))
>      build_saturation_binary_arith_call_and_replace (gsi, IFN_SAT_ADD, lhs,
>                                                     ops[0], ops[1]);
>  }
> @@ -6363,7 +6382,7 @@ math_opts_dom_walker::after_dom_children (basic_block 
> bb)
>               break;
>
>             case PLUS_EXPR:
> -             match_unsigned_saturation_add (&gsi, as_a<gassign *> (stmt));
> +             match_saturation_add_with_assign (&gsi, as_a<gassign *> (stmt));
>               match_unsigned_saturation_sub (&gsi, as_a<gassign *> (stmt));
>               /* fall-through  */
>             case MINUS_EXPR:
> @@ -6389,7 +6408,7 @@ math_opts_dom_walker::after_dom_children (basic_block 
> bb)
>               break;
>
>             case BIT_IOR_EXPR:
> -             match_unsigned_saturation_add (&gsi, as_a<gassign *> (stmt));
> +             match_saturation_add_with_assign (&gsi, as_a<gassign *> (stmt));
>               match_unsigned_saturation_trunc (&gsi, as_a<gassign *> (stmt));
>               /* fall-through  */
>             case BIT_XOR_EXPR:
> @@ -6410,6 +6429,7 @@ math_opts_dom_walker::after_dom_children (basic_block 
> bb)
>
>             case NOP_EXPR:
>               match_unsigned_saturation_trunc (&gsi, as_a<gassign *> (stmt));
> +             match_saturation_add_with_assign (&gsi, as_a<gassign *> (stmt));
>               break;
>
>             default:;
> --
> 2.17.1
>

Reply via email to