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 >