aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPan Li <pan2.li@intel.com>2024-12-11 19:37:06 +0800
committerPan Li <pan2.li@intel.com>2025-01-08 07:35:36 +0800
commitd20e9b7b5a4dd99f0486d2b0a946208a9563e196 (patch)
tree03de302a6bc6aa5ea8ea70a60a28bb24499f4e80 /gcc
parent5080dbb807063061dbbe0a497d04629575f8c2af (diff)
downloadgcc-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.pd65
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)