From d20e9b7b5a4dd99f0486d2b0a946208a9563e196 Mon Sep 17 00:00:00 2001 From: Pan Li <pan2.li@intel.com> Date: Wed, 11 Dec 2024 19:37:06 +0800 Subject: [PATCH] Match: Refactor the signed SAT_TRUNC match patterns [NFC] This patch would like to refactor the all signed SAT_TRUNC patterns, aka: * Extract type check outside. * Re-arrange the related match pattern forms together. 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: Refactor sorts of signed SAT_TRUNC match patterns Signed-off-by: Pan Li <pan2.li@intel.com> --- gcc/match.pd | 65 ++++++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/gcc/match.pd b/gcc/match.pd index 5b5265afe96a..8b72eaf713a0 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3431,6 +3431,38 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (realpart @2)) (if (types_match (type, @0, @1))))) +(if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type)) + (match (signed_integer_sat_trunc @0) + /* SAT_S_TRUNC(X) = (unsigned)X + NT_MAX + 1 > Unsigned_MAX ? (NT)X */ + (cond^ (gt (plus:c (convert@4 @0) INTEGER_CST@1) INTEGER_CST@2) + (bit_xor:c (nop_convert? + (negate (nop_convert? (convert (lt @0 integer_zerop))))) + INTEGER_CST@3) + (convert @0)) + (if (!TYPE_UNSIGNED (TREE_TYPE (@0)) && TYPE_UNSIGNED (TREE_TYPE (@4))) + (with + { + unsigned itype_prec = TYPE_PRECISION (TREE_TYPE (@0)); + unsigned otype_prec = TYPE_PRECISION (type); + wide_int offset = wi::uhwi (HOST_WIDE_INT_1U << (otype_prec - 1), + itype_prec); // Aka 128 for int8_t + wide_int limit_0 = wi::mask (otype_prec, false, itype_prec); // Aka 255 + wide_int limit_1 = wi::uhwi ((HOST_WIDE_INT_1U << otype_prec) - 3, + itype_prec); // Aka 253 + wide_int limit_2 = wi::uhwi ((HOST_WIDE_INT_1U << otype_prec) - 2, + itype_prec); // Aka 254 + wide_int otype_max = wi::mask (otype_prec - 1, false, otype_prec); + wide_int itype_max = wi::mask (otype_prec - 1, false, itype_prec); + wide_int int_cst_1 = wi::to_wide (@1); + wide_int int_cst_2 = wi::to_wide (@2); + wide_int int_cst_3 = wi::to_wide (@3); + } + (if (((wi::eq_p (int_cst_1, offset) && wi::eq_p (int_cst_2, limit_0)) + || (wi::eq_p (int_cst_1, itype_max) && wi::eq_p (int_cst_2, limit_2)) + || (wi::eq_p (int_cst_1, offset) && wi::eq_p (int_cst_2, limit_2)) + || (wi::eq_p (int_cst_1, itype_max) && wi::eq_p (int_cst_2, limit_1))) + && wi::eq_p (int_cst_3, otype_max))))))) + /* The boundary condition for case 10: IMM = 1: SAT_U_SUB = X >= IMM ? (X - IMM) : 0. simplify (X != 0 ? X + ~0 : 0) to X - (X != 0). */ @@ -3442,39 +3474,6 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (with { tree itype = TREE_TYPE (@2); } (convert (minus @2 (convert:itype @1)))))) -/* Signed saturation truncate, case 1 and case 2, sizeof (WT) > sizeof (NT). - SAT_S_TRUNC(X) = (unsigned)X + NT_MAX + 1 > Unsigned_MAX ? (NT)X. */ -(match (signed_integer_sat_trunc @0) - (cond^ (gt (plus:c (convert@4 @0) INTEGER_CST@1) INTEGER_CST@2) - (bit_xor:c (nop_convert? - (negate (nop_convert? (convert (lt @0 integer_zerop))))) - INTEGER_CST@3) - (convert @0)) - (if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type) - && !TYPE_UNSIGNED (TREE_TYPE (@0)) && TYPE_UNSIGNED (TREE_TYPE (@4))) - (with - { - unsigned itype_prec = TYPE_PRECISION (TREE_TYPE (@0)); - unsigned otype_prec = TYPE_PRECISION (type); - wide_int offset = wi::uhwi (HOST_WIDE_INT_1U << (otype_prec - 1), - itype_prec); // Aka 128 for int8_t - wide_int limit_0 = wi::mask (otype_prec, false, itype_prec); // Aka 255 - wide_int limit_1 = wi::uhwi ((HOST_WIDE_INT_1U << otype_prec) - 3, - itype_prec); // Aka 253 - wide_int limit_2 = wi::uhwi ((HOST_WIDE_INT_1U << otype_prec) - 2, - itype_prec); // Aka 254 - wide_int otype_max = wi::mask (otype_prec - 1, false, otype_prec); - wide_int itype_max = wi::mask (otype_prec - 1, false, itype_prec); - wide_int int_cst_1 = wi::to_wide (@1); - wide_int int_cst_2 = wi::to_wide (@2); - wide_int int_cst_3 = wi::to_wide (@3); - } - (if (((wi::eq_p (int_cst_1, offset) && wi::eq_p (int_cst_2, limit_0)) - || (wi::eq_p (int_cst_1, itype_max) && wi::eq_p (int_cst_2, limit_2)) - || (wi::eq_p (int_cst_1, offset) && wi::eq_p (int_cst_2, limit_2)) - || (wi::eq_p (int_cst_1, itype_max) && wi::eq_p (int_cst_2, limit_1))) - && wi::eq_p (int_cst_3, otype_max)))))) - /* x > y && x != XXX_MIN --> x > y x > y && x == XXX_MIN --> false . */ (for eqne (eq ne) -- GitLab