diff options
author | Pan Li <pan2.li@intel.com> | 2024-12-11 19:37:06 +0800 |
---|---|---|
committer | Pan Li <pan2.li@intel.com> | 2025-01-08 07:35:36 +0800 |
commit | d20e9b7b5a4dd99f0486d2b0a946208a9563e196 (patch) | |
tree | 03de302a6bc6aa5ea8ea70a60a28bb24499f4e80 /gcc | |
parent | 5080dbb807063061dbbe0a497d04629575f8c2af (diff) | |
download | gcc-d20e9b7b5a4dd99f0486d2b0a946208a9563e196.zip gcc-d20e9b7b5a4dd99f0486d2b0a946208a9563e196.tar.gz gcc-d20e9b7b5a4dd99f0486d2b0a946208a9563e196.tar.bz2 |
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>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/match.pd | 65 |
1 files changed, 32 insertions, 33 deletions
diff --git a/gcc/match.pd b/gcc/match.pd index 5b5265a..8b72eaf 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) |