diff options
author | Pan Li <pan2.li@intel.com> | 2024-05-28 15:37:44 +0800 |
---|---|---|
committer | Pan Li <pan2.li@intel.com> | 2024-06-05 16:37:21 +0800 |
commit | abe6d39365476e6be724815d09d072e305018755 (patch) | |
tree | ed675a2d4eed3147cfe8f635e8fae4b1efa8fe88 /gcc/match.pd | |
parent | 993142677e2cf780ef578e1d46309f0042743dd5 (diff) | |
download | gcc-abe6d39365476e6be724815d09d072e305018755.zip gcc-abe6d39365476e6be724815d09d072e305018755.tar.gz gcc-abe6d39365476e6be724815d09d072e305018755.tar.bz2 |
Internal-fn: Support new IFN SAT_SUB for unsigned scalar int
This patch would like to add the middle-end presentation for the
saturation sub. Aka set the result of add to the min when downflow.
It will take the pattern similar as below.
SAT_SUB (x, y) => (x - y) & (-(TYPE)(x >= y));
For example for uint8_t, we have
* SAT_SUB (255, 0) => 255
* SAT_SUB (1, 2) => 0
* SAT_SUB (254, 255) => 0
* SAT_SUB (0, 255) => 0
Given below SAT_SUB for uint64
uint64_t sat_sub_u64 (uint64_t x, uint64_t y)
{
return (x - y) & (-(TYPE)(x >= y));
}
Before this patch:
uint64_t sat_sub_u_0_uint64_t (uint64_t x, uint64_t y)
{
_Bool _1;
long unsigned int _3;
uint64_t _6;
;; basic block 2, loop depth 0
;; pred: ENTRY
_1 = x_4(D) >= y_5(D);
_3 = x_4(D) - y_5(D);
_6 = _1 ? _3 : 0;
return _6;
;; succ: EXIT
}
After this patch:
uint64_t sat_sub_u_0_uint64_t (uint64_t x, uint64_t y)
{
uint64_t _6;
;; basic block 2, loop depth 0
;; pred: ENTRY
_6 = .SAT_SUB (x_4(D), y_5(D)); [tail call]
return _6;
;; succ: EXIT
}
The below tests are running for this patch:
*. The riscv fully regression tests.
*. The x86 bootstrap tests.
*. The x86 fully regression tests.
PR target/51492
PR target/112600
gcc/ChangeLog:
* internal-fn.def (SAT_SUB): Add new IFN define for SAT_SUB.
* match.pd: Add new match for SAT_SUB.
* optabs.def (OPTAB_NL): Remove fixed-point for ussub/ssub.
* tree-ssa-math-opts.cc (gimple_unsigned_integer_sat_sub): Add
new decl for generated in match.pd.
(build_saturation_binary_arith_call): Add new helper function
to build the gimple call to binary SAT alu.
(match_saturation_arith): Rename from.
(match_unsigned_saturation_add): Rename to.
(match_unsigned_saturation_sub): Add new func to match the
unsigned sat sub.
(math_opts_dom_walker::after_dom_children): Add SAT_SUB matching
try when COND_EXPR.
Signed-off-by: Pan Li <pan2.li@intel.com>
Diffstat (limited to 'gcc/match.pd')
-rw-r--r-- | gcc/match.pd | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/gcc/match.pd b/gcc/match.pd index f19ef70..7c1ad42 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3096,6 +3096,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (match (unsigned_integer_sat_add @0 @1) (bit_ior:c (usadd_left_part_2 @0 @1) (usadd_right_part_2 @0 @1))) +/* Unsigned saturation sub, case 1 (branch with gt): + SAT_U_SUB = X > Y ? X - Y : 0 */ +(match (unsigned_integer_sat_sub @0 @1) + (cond (gt @0 @1) (minus @0 @1) integer_zerop) + (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type) + && types_match (type, @0, @1)))) + +/* Unsigned saturation sub, case 2 (branch with ge): + SAT_U_SUB = X >= Y ? X - Y : 0. */ +(match (unsigned_integer_sat_sub @0 @1) + (cond (ge @0 @1) (minus @0 @1) integer_zerop) + (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type) + && types_match (type, @0, @1)))) + /* x > y && x != XXX_MIN --> x > y x > y && x == XXX_MIN --> false . */ (for eqne (eq ne) |