On 29/10/2024 12:48, Richard Biener wrote:
On Mon, Oct 28, 2024 at 4:45 PM Akram Ahmad <akram.ah...@arm.com> wrote:
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 written in this patch will fail on targets which
do not implement the standard names for IFN SAT_ADD.
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 | 21 +++++++++++++++++++
.../gcc.dg/tree-ssa/sat-u-add-match-1-u32.c | 21 +++++++++++++++++++
.../gcc.dg/tree-ssa/sat-u-add-match-1-u64.c | 21 +++++++++++++++++++
.../gcc.dg/tree-ssa/sat-u-add-match-1-u8.c | 21 +++++++++++++++++++
5 files changed, 86 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..0202c70cc83
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/sat-u-add-match-1-u16.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { 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" } } */
The testcases will FAIL unless the target has support for .SAT_ADD - you want to
add proper effective target tests here.
The match.pd part looks OK to me.
Richard.
Hi Richard,
I assume this also applies to the tests written for the SAT_SUB pattern
too in that case?
Many thanks,
Akram
\ 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..34c80ba3854
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/sat-u-add-match-1-u32.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { 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..0718cb566d3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/sat-u-add-match-1-u64.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { 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..c3e0cc6c456
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/sat-u-add-match-1-u8.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { 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