diff options
author | xuli <xuli1@eswincomputing.com> | 2024-12-27 07:03:14 +0000 |
---|---|---|
committer | xuli <xuli1@eswincomputing.com> | 2025-05-27 02:35:40 +0000 |
commit | 7cf7149ec8303d0ed828fb7629417b28e6565d32 (patch) | |
tree | 782bd70fa1c6ff783278562b29a824eeebec51fd | |
parent | 15e55f3fb559fad1acaaadb57561a15c42c20c7d (diff) | |
download | gcc-7cf7149ec8303d0ed828fb7629417b28e6565d32.zip gcc-7cf7149ec8303d0ed828fb7629417b28e6565d32.tar.gz gcc-7cf7149ec8303d0ed828fb7629417b28e6565d32.tar.bz2 |
Match:Support IMM=-1 for signed scalar SAT_ADD IMM form1
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.
Signed-off-by: Li Xu <xuli1@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.
-rw-r--r-- | gcc/match.pd | 19 | ||||
-rw-r--r-- | 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 27f662f..50bd853 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3461,7 +3461,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 eb03ebe..7e819f3 100644 --- a/gcc/tree-ssa-math-opts.cc +++ b/gcc/tree-ssa-math-opts.cc @@ -4104,15 +4104,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]); } @@ -6403,7 +6422,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: @@ -6429,7 +6448,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: @@ -6450,6 +6469,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:; |