[v3,3/3] Match: make SAT_ADD case 7 commutative

Message ID 20241127202741.771893-4-Akram.Ahmad@arm.com
State New
Headers
Series Match: support additional cases of unsigned scalar arithmetic |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 fail Patch failed to apply

Commit Message

Akram Ahmad Nov. 27, 2024, 8:27 p.m. UTC
  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
  

Patch

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