This patch would like to support signed scalar SAT_ADD IMM form 2
Form2:
T __attribute__((noinline)) \
sat_s_add_imm_##T##_fmt_2##_##INDEX (T x) \
{ \
T sum = (T)((UT)x + (UT)IMM); \
return ((x ^ sum) < 0 && (x ^ IMM) >= 0) ? \
(-(T)(x < 0) ^ MAX) : sum; \
}
Take below form1 as example:
DEF_SAT_S_ADD_IMM_FMT_2(0, int8_t, uint8_t, 9, INT8_MIN, INT8_MAX)
Before this patch:
__attribute__((noinline))
int8_t sat_s_add_imm_int8_t_fmt_2_0 (int8_t x)
{
int8_t sum;
unsigned char x.0_1;
unsigned char _2;
signed char _3;
signed char _4;
_Bool _5;
signed char _6;
int8_t _7;
int8_t _10;
signed char _11;
signed char _13;
signed char _14;
<bb 2> [local count:
1073741822]:
x.0_1 = (unsigned char) x_8(D);
_2 = x.0_1 + 9;
sum_9 = (int8_t) _2;
_3 = x_8(D) ^ sum_9;
_4 = x_8(D) ^ 9;
_13 = ~_3;
_14 = _4 | _13;
if (_14 >= 0)
goto <bb 3>; [59.00%]
else
goto <bb 4>; [41.00%]
<bb 3> [local count:
259738146]:
_5 = x_8(D) < 0;
_11 = (signed char) _5;
_6 = -_11;
_10 = _6 ^ 127;
<bb 4> [local count:
1073741824]:
# _7 = PHI <sum_9(2), _10(3)>
return _7;
}
After this patch:
__attribute__((noinline))
int8_t sat_s_add_imm_int8_t_fmt_2_0 (int8_t x)
{
int8_t _7;
<bb 2> [local count:
1073741824]:
_7 = .SAT_ADD (x_8(D), 9); [tail call]
return _7;
}
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: Ciyan Pan <panciyan@eswincomputing.com>
gcc/ChangeLog:
* match.pd: Add signed scalar SAT_ADD IMM form2 matching.
wide_int c2 = wi::to_wide (@2);
wide_int sum = wi::add (c1, c2);
}
- (if (wi::eq_p (sum, wi::max_value (precision, SIGNED)))))))
+ (if (wi::eq_p (sum, wi::max_value (precision, SIGNED))))))
+
+(match (signed_integer_sat_add @0 @1)
+ /* T SUM = (T)((UT)X + (UT)IMM)
+ SAT_S_ADD = (X ^ SUM) < 0 && (X ^ IMM) >= 0 ? (-(T)(X < 0) ^ MAX) : SUM */
+ (cond^ (ge (bit_ior:c (bit_xor:c @0 INTEGER_CST@1)
+ (bit_not (bit_xor:c @0 (nop_convert@2 (plus (nop_convert @0)
+ INTEGER_CST@3)))))
+ integer_zerop)
+ (signed_integer_sat_val @0)
+ @2)
+ (if (wi::eq_p (wi::to_wide (@1), wi::to_wide (@3))))))
/* Saturation sub for signed integer. */
(if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type))