Case 7 of unsigned scalar saturating addition defines SAT_ADD = X <= (X + Y) ? (X + Y) : -1. This is the same as SAT_ADD = Y <= (X + Y) ? (X + Y) : -1 due to usadd_left_part_1 being commutative.
The pattern for case 7 currently does not accept the alternative where Y is used in the condition. Therefore, this commit adds the commutative property to this case which causes more valid cases of unsigned saturating arithmetic to be recognised. Before: <bb 2> _1 = BIT_FIELD_REF <b_3(D), 8, 0>; sum_5 = _1 + a_4(D); if (a_4(D) <= sum_5) goto <bb 4>; [INV] else goto <bb 3>; [INV] <bb 3> : <bb 4> : _2 = PHI <255(3), sum_5(2)> return _2; After: <bb 2> [local count: 1073741824]: _1 = BIT_FIELD_REF <b_3(D), 8, 0>; _2 = .SAT_ADD (_1, a_4(D)); [tail call] return _2; This passes the aarch64-none-linux-gnu regression tests with no new failures. The tests will be skipped on targets which do not support IFN_SAT_ADD for each of these modes via dg-require-effective-target. gcc/ChangeLog: * match.pd: Modify existing case for SAT_ADD. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/sat-u-add-match-1-u16.c: New test. * gcc.dg/tree-ssa/sat-u-add-match-1-u32.c: New test. * gcc.dg/tree-ssa/sat-u-add-match-1-u64.c: New test. * gcc.dg/tree-ssa/sat-u-add-match-1-u8.c: New test. --- gcc/match.pd | 4 ++-- .../gcc.dg/tree-ssa/sat-u-add-match-1-u16.c | 22 +++++++++++++++++++ .../gcc.dg/tree-ssa/sat-u-add-match-1-u32.c | 22 +++++++++++++++++++ .../gcc.dg/tree-ssa/sat-u-add-match-1-u64.c | 22 +++++++++++++++++++ .../gcc.dg/tree-ssa/sat-u-add-match-1-u8.c | 22 +++++++++++++++++++ 5 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/sat-u-add-match-1-u16.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/sat-u-add-match-1-u32.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/sat-u-add-match-1-u64.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/sat-u-add-match-1-u8.c diff --git a/gcc/match.pd b/gcc/match.pd index 4fc5efa6247..98c50ab097f 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3085,7 +3085,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* SAT_ADD = usadd_left_part_1 | usadd_right_part_1, aka: SAT_ADD = (X + Y) | -((X + Y) < X) */ (match (usadd_left_part_1 @0 @1) - (plus:c @0 @1) + (plus @0 @1) (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type) && types_match (type, @0, @1)))) @@ -3166,7 +3166,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* Unsigned saturation add, case 7 (branch with le): SAT_ADD = x <= (X + Y) ? (X + Y) : -1. */ (match (unsigned_integer_sat_add @0 @1) - (cond^ (le @0 (usadd_left_part_1@2 @0 @1)) @2 integer_minus_onep)) + (cond^ (le @0 (usadd_left_part_1:C@2 @0 @1)) @2 integer_minus_onep)) /* Unsigned saturation add, case 8 (branch with gt): SAT_ADD = x > (X + Y) ? -1 : (X + Y). */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sat-u-add-match-1-u16.c b/gcc/testsuite/gcc.dg/tree-ssa/sat-u-add-match-1-u16.c new file mode 100644 index 00000000000..866ce6cdbc1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/sat-u-add-match-1-u16.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target usadd_himode } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +#include <stdint.h> + +#define T uint16_t +#define UMAX (T) -1 + +T sat_u_add_1 (T a, T b) +{ + T sum = a + b; + return sum < a ? UMAX : sum; +} + +T sat_u_add_2 (T a, T b) +{ + T sum = a + b; + return sum < b ? UMAX : sum; +} + +/* { dg-final { scan-tree-dump-times " .SAT_ADD " 2 "optimized" } } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sat-u-add-match-1-u32.c b/gcc/testsuite/gcc.dg/tree-ssa/sat-u-add-match-1-u32.c new file mode 100644 index 00000000000..8f841c32852 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/sat-u-add-match-1-u32.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target usadd_simode } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +#include <stdint.h> + +#define T uint32_t +#define UMAX (T) -1 + +T sat_u_add_1 (T a, T b) +{ + T sum = a + b; + return sum < a ? UMAX : sum; +} + +T sat_u_add_2 (T a, T b) +{ + T sum = a + b; + return sum < b ? UMAX : sum; +} + +/* { dg-final { scan-tree-dump-times " .SAT_ADD " 2 "optimized" } } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sat-u-add-match-1-u64.c b/gcc/testsuite/gcc.dg/tree-ssa/sat-u-add-match-1-u64.c new file mode 100644 index 00000000000..39548d63384 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/sat-u-add-match-1-u64.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target usadd_dimode } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +#include <stdint.h> + +#define T uint64_t +#define UMAX (T) -1 + +T sat_u_add_1 (T a, T b) +{ + T sum = a + b; + return sum < a ? UMAX : sum; +} + +T sat_u_add_2 (T a, T b) +{ + T sum = a + b; + return sum < b ? UMAX : sum; +} + +/* { dg-final { scan-tree-dump-times " .SAT_ADD " 2 "optimized" } } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sat-u-add-match-1-u8.c b/gcc/testsuite/gcc.dg/tree-ssa/sat-u-add-match-1-u8.c new file mode 100644 index 00000000000..c43ddd717d9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/sat-u-add-match-1-u8.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target usadd_qimode } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +#include <stdint.h> + +#define T uint8_t +#define UMAX (T) -1 + +T sat_u_add_1 (T a, T b) +{ + T sum = a + b; + return sum < a ? UMAX : sum; +} + +T sat_u_add_2 (T a, T b) +{ + T sum = a + b; + return sum < b ? UMAX : sum; +} + +/* { dg-final { scan-tree-dump-times " .SAT_ADD " 2 "optimized" } } */ \ No newline at end of file -- 2.34.1