diff options
author | Pan Li <pan2.li@intel.com> | 2024-07-05 20:36:35 +0800 |
---|---|---|
committer | Pan Li <pan2.li@intel.com> | 2024-07-10 17:30:40 +0800 |
commit | 80e446e829d818dc19daa6e671b9626e93ee4949 (patch) | |
tree | 61552d9b715aab00ce0e78391fd7dcdd30c5ad85 | |
parent | 1ae5fc24e86ecc9e7b60346d9ca2e56f83517bda (diff) | |
download | gcc-80e446e829d818dc19daa6e671b9626e93ee4949.zip gcc-80e446e829d818dc19daa6e671b9626e93ee4949.tar.gz gcc-80e446e829d818dc19daa6e671b9626e93ee4949.tar.bz2 |
Match: Support form 2 for the .SAT_TRUNC
This patch would like to add form 2 support for the .SAT_TRUNC. Aka:
Form 2:
#define DEF_SAT_U_TRUC_FMT_2(NT, WT) \
NT __attribute__((noinline)) \
sat_u_truc_##WT##_to_##NT##_fmt_2 (WT x) \
{ \
bool overflow = x > (WT)(NT)(-1); \
return overflow ? (NT)-1 : (NT)x; \
}
DEF_SAT_U_TRUC_FMT_2(uint32, uint64)
Before this patch:
3 │
4 │ __attribute__((noinline))
5 │ uint32_t sat_u_truc_uint64_t_to_uint32_t_fmt_2 (uint64_t x)
6 │ {
7 │ uint32_t _1;
8 │ long unsigned int _3;
9 │
10 │ ;; basic block 2, loop depth 0
11 │ ;; pred: ENTRY
12 │ _3 = MIN_EXPR <x_2(D), 4294967295>;
13 │ _1 = (uint32_t) _3;
14 │ return _1;
15 │ ;; succ: EXIT
16 │
17 │ }
After this patch:
3 │
4 │ __attribute__((noinline))
5 │ uint32_t sat_u_truc_uint64_t_to_uint32_t_fmt_2 (uint64_t x)
6 │ {
7 │ uint32_t _1;
8 │
9 │ ;; basic block 2, loop depth 0
10 │ ;; pred: ENTRY
11 │ _1 = .SAT_TRUNC (x_2(D)); [tail call]
12 │ return _1;
13 │ ;; succ: EXIT
14 │
15 │ }
The below test suites are passed for this patch:
1. The x86 bootstrap test.
2. The x86 fully regression test.
3. The rv64gcv fully regresssion test.
gcc/ChangeLog:
* match.pd: Add form 2 for .SAT_TRUNC.
* tree-ssa-math-opts.cc (math_opts_dom_walker::after_dom_children):
Add new case NOP_EXPR, and try to match SAT_TRUNC.
Signed-off-by: Pan Li <pan2.li@intel.com>
-rw-r--r-- | gcc/match.pd | 17 | ||||
-rw-r--r-- | gcc/tree-ssa-math-opts.cc | 4 |
2 files changed, 20 insertions, 1 deletions
diff --git a/gcc/match.pd b/gcc/match.pd index 4edfa2a..3759c64 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3234,7 +3234,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type) && types_match (type, @0, @1)))) -/* Unsigned saturation truncate, case 1 (), sizeof (WT) > sizeof (NT). +/* Unsigned saturation truncate, case 1, sizeof (WT) > sizeof (NT). SAT_U_TRUNC = (NT)x | (NT)(-(X > (WT)(NT)(-1))). */ (match (unsigned_integer_sat_trunc @0) (bit_ior:c (negate (convert (gt @0 INTEGER_CST@1))) @@ -3250,6 +3250,21 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) } (if (otype_precision < itype_precision && wi::eq_p (trunc_max, int_cst)))))) +/* Unsigned saturation truncate, case 2, sizeof (WT) > sizeof (NT). + SAT_U_TRUNC = (NT)(MIN_EXPR (X, 255)). */ +(match (unsigned_integer_sat_trunc @0) + (convert (min @0 INTEGER_CST@1)) + (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type) + && TYPE_UNSIGNED (TREE_TYPE (@0))) + (with + { + unsigned itype_precision = TYPE_PRECISION (TREE_TYPE (@0)); + unsigned otype_precision = TYPE_PRECISION (type); + wide_int trunc_max = wi::mask (otype_precision, false, itype_precision); + wide_int int_cst = wi::to_wide (@1, itype_precision); + } + (if (otype_precision < itype_precision && wi::eq_p (trunc_max, int_cst)))))) + /* x > y && x != XXX_MIN --> x > y x > y && x == XXX_MIN --> false . */ (for eqne (eq ne) diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc index a35caf5..ac86be8 100644 --- a/gcc/tree-ssa-math-opts.cc +++ b/gcc/tree-ssa-math-opts.cc @@ -6170,6 +6170,10 @@ math_opts_dom_walker::after_dom_children (basic_block bb) match_unsigned_saturation_sub (&gsi, as_a<gassign *> (stmt)); break; + case NOP_EXPR: + match_unsigned_saturation_trunc (&gsi, as_a<gassign *> (stmt)); + break; + default:; } } |