[PATCH 1/2] Match: Support IMM=max-1 for unsigned scalar .SAT_SUB IMM form 1
Richard Biener
richard.guenther@gmail.com
Mon Oct 21 09:26:58 GMT 2024
On Mon, Oct 21, 2024 at 5:09 AM Li Xu <xuli1@eswincomputing.com> wrote:
>
> From: xuli <xuli1@eswincomputing.com>
>
> This patch would like to support .SAT_SUB when one of the op
> is IMM = max - 1 of form1.
>
> Form 1:
> #define DEF_SAT_U_SUB_IMM_FMT_1(T, IMM) \
> T __attribute__((noinline)) \
> sat_u_sub_imm##IMM##_##T##_fmt_1 (T y) \
> { \
> return IMM >= y ? IMM - y : 0; \
> }
>
> Take below form 1 as example:
> DEF_SAT_U_SUB_IMM_FMT_1(uint8_t, 254)
>
> Before this patch:
> __attribute__((noinline))
> uint8_t sat_u_sub_imm254_uint8_t_fmt_1 (uint8_t y)
> {
> uint8_t _1;
> uint8_t _3;
>
> <bb 2> [local count: 1073741824]:
> if (y_2(D) != 255)
> goto <bb 3>; [66.00%]
> else
> goto <bb 4>; [34.00%]
>
> <bb 3> [local count: 708669600]:
> _3 = 254 - y_2(D);
>
> <bb 4> [local count: 1073741824]:
> # _1 = PHI <0(2), _3(3)>
> return _1;
>
> }
>
> After this patch:
> __attribute__((noinline))
> uint8_t sat_u_sub_imm254_uint8_t_fmt_1 (uint8_t y)
> {
> uint8_t _1;
>
> <bb 2> [local count: 1073741824]:
> _1 = .SAT_SUB (254, y_2(D)); [tail call]
> return _1;
>
> }
>
> 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.
>
> gcc/ChangeLog:
>
> * match.pd: Support IMM=max-1.
>
> Change-Id: Ifc8ad640088b8863720bfc46c36eafe765163f78
> ---
> gcc/match.pd | 18 +++++++++++++++++-
> 1 file changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 12d81fcac0d..9aa2129814b 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -3325,7 +3325,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
> && types_match (type, @0, @1))))
>
> -/* Unsigned saturation sub with op_0 imm, case 9 (branch with gt):
> +/* Unsigned saturation sub with op_0 imm, case 9 (branch with le):
> SAT_U_SUB = IMM > Y ? (IMM - Y) : 0.
> = IMM >= Y ? (IMM - Y) : 0. */
> (match (unsigned_integer_sat_sub @0 @1)
> @@ -3344,6 +3344,22 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> }
> (if (equal_p || less_than_1_p)))))
>
> +/* The boundary condition for case 9: IMM = max -1 (branch with ne):
> + SAT_U_SUB = IMM >= Y ? (IMM - Y) : 0. */
> +(match (unsigned_integer_sat_sub @0 @1)
> + (cond^ (ne @1 INTEGER_CST@2) (minus INTEGER_CST@0 @1) integer_zerop)
> + (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
> + && types_match (type, @1) && int_fits_type_p (@0, type))
if @1 matches type then @0 matches type as well because of the minus so the
int_fits_type_p check is redundant.
OK with it removed.
Richard.
> +(with
> + {
> + unsigned precision = TYPE_PRECISION (type);
> + wide_int max = wi::mask (precision, false, precision);
> + wide_int c0 = wi::to_wide (@0);
> + wide_int c2 = wi::to_wide (@2);
> + wide_int c0_add_1 = wi::add (c0, wi::uhwi (1, precision));
> + }
> + (if (wi::eq_p (c2, max) && wi::eq_p (c0_add_1, max))))))
> +
> /* Unsigned saturation sub with op_1 imm, case 10:
> SAT_U_SUB = X > IMM ? (X - IMM) : 0.
> = X >= IMM ? (X - IMM) : 0. */
> --
> 2.17.1
>
More information about the Gcc-patches
mailing list