diff options
author | Pan Li <pan2.li@intel.com> | 2024-10-11 11:51:52 +0800 |
---|---|---|
committer | Pan Li <pan2.li@intel.com> | 2024-10-12 13:23:46 +0800 |
commit | b4f2fccf302bfe4ce704d11017b1a174eb3da89f (patch) | |
tree | a799b560739dd588b71226365aa6875f9f3fb306 /gcc | |
parent | b45e3ad78252cd4594a16db72665016b54838b4c (diff) | |
download | gcc-b4f2fccf302bfe4ce704d11017b1a174eb3da89f.zip gcc-b4f2fccf302bfe4ce704d11017b1a174eb3da89f.tar.gz gcc-b4f2fccf302bfe4ce704d11017b1a174eb3da89f.tar.bz2 |
Match: Support form 1 for vector signed integer SAT_SUB
This patch would like to support the form 1 of the vector signed
integer SAT_SUB. Aka below example:
Form 1:
#define DEF_VEC_SAT_S_SUB_FMT_1(T, UT, MIN, MAX) \
void __attribute__((noinline)) \
vec_sat_s_add_##T##_fmt_1 (T *out, T *op_1, T *op_2, unsigned limit) \
{ \
unsigned i; \
for (i = 0; i < limit; i++) \
{ \
T x = op_1[i]; \
T y = op_2[i]; \
T minus = (UT)x - (UT)y; \
out[i] = (x ^ y) >= 0 \
? minus \
: (minus ^ x) >= 0 \
? minus \
: x < 0 ? MIN : MAX; \
} \
}
DEF_VEC_SAT_S_SUB_FMT_1(int8_t, uint8_t, INT8_MIN, INT8_MAX)
Before this patch:
91 │ _108 = .SELECT_VL (ivtmp_106, POLY_INT_CST [16, 16]);
92 │ vect_x_16.11_80 = .MASK_LEN_LOAD (vectp_op_1.9_78, 8B, { -1, ... }, _108, 0);
93 │ _69 = vect_x_16.11_80 >> 7;
94 │ vect_x.12_81 = VIEW_CONVERT_EXPR<vector([16,16]) unsigned char>(vect_x_16.11_80);
95 │ vect_y_18.15_85 = .MASK_LEN_LOAD (vectp_op_2.13_83, 8B, { -1, ... }, _108, 0);
96 │ vect__7.21_91 = vect_x_16.11_80 ^ vect_y_18.15_85;
97 │ mask__44.22_92 = vect__7.21_91 < { 0, ... };
98 │ vect_y.16_86 = VIEW_CONVERT_EXPR<vector([16,16]) unsigned char>(vect_y_18.15_85);
99 │ vect__6.17_87 = vect_x.12_81 - vect_y.16_86;
100 │ vect_minus_19.18_88 = VIEW_CONVERT_EXPR<vector([16,16]) signed char>(vect__6.17_87);
101 │ vect__8.19_89 = vect_x_16.11_80 ^ vect_minus_19.18_88;
102 │ mask__42.20_90 = vect__8.19_89 < { 0, ... };
103 │ mask__41.23_93 = mask__42.20_90 & mask__44.22_92;
104 │ _4 = .COND_XOR (mask__41.23_93, _69, { 127, ... }, vect_minus_19.18_88);
105 │ .MASK_LEN_STORE (vectp_out.31_102, 8B, { -1, ... }, _108, 0, _4);
106 │ vectp_op_1.9_79 = vectp_op_1.9_78 + _108;
107 │ vectp_op_2.13_84 = vectp_op_2.13_83 + _108;
108 │ vectp_out.31_103 = vectp_out.31_102 + _108;
109 │ ivtmp_107 = ivtmp_106 - _108;
After this patch:
81 │ _102 = .SELECT_VL (ivtmp_100, POLY_INT_CST [16, 16]);
82 │ vect_x_16.11_89 = .MASK_LEN_LOAD (vectp_op_1.9_87, 8B, { -1, ... }, _102, 0);
83 │ vect_y_18.14_93 = .MASK_LEN_LOAD (vectp_op_2.12_91, 8B, { -1, ... }, _102, 0);
84 │ vect_patt_38.15_94 = .SAT_SUB (vect_x_16.11_89, vect_y_18.14_93);
85 │ .MASK_LEN_STORE (vectp_out.16_96, 8B, { -1, ... }, _102, 0, vect_patt_38.15_94);
86 │ vectp_op_1.9_88 = vectp_op_1.9_87 + _102;
87 │ vectp_op_2.12_92 = vectp_op_2.12_91 + _102;
88 │ vectp_out.16_97 = vectp_out.16_96 + _102;
89 │ ivtmp_101 = ivtmp_100 - _102;
The below test suites are passed for this patch.
* The rv64gcv fully regression test.
* The x86 bootstrap test.
* The x86 fully regression test.
gcc/ChangeLog:
* match.pd: Add case 1 matching pattern for vector signed SAT_SUB.
Signed-off-by: Pan Li <pan2.li@intel.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/match.pd | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/gcc/match.pd b/gcc/match.pd index 78084bb..f2b5f3a 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3401,6 +3401,22 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type) && types_match (type, @0, @1)))) +/* Signed saturation sub, case 4: + T minus = (T)((UT)X - (UT)Y); + SAT_S_SUB = (X ^ Y) < 0 & (X ^ minus) < 0 ? (-(T)(X < 0) ^ MAX) : minus; + + The T and UT are type pair like T=int8_t, UT=uint8_t. */ +(match (signed_integer_sat_sub @0 @1) + (cond^ (bit_and:c (lt (bit_xor @0 (nop_convert@2 (minus (nop_convert @0) + (nop_convert @1)))) + integer_zerop) + (lt (bit_xor:c @0 @1) integer_zerop)) + (bit_xor:c (nop_convert (negate (nop_convert (convert + (lt @0 integer_zerop))))) + max_value) + @2) + (if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type)))) + /* Unsigned saturation truncate, case 1, sizeof (WT) > sizeof (NT). SAT_U_TRUNC = (NT)x | (NT)(-(X > (WT)(NT)(-1))). */ (match (unsigned_integer_sat_trunc @0) |