[v3,2/3] Match: support new case of unsigned scalar SAT_SUB

Message ID 20241127202741.771893-3-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
  This patch adds a new case for unsigned scalar saturating subtraction
using a branch with a greater-than-or-equal condition. For example,

X >= (X - Y) ? (X - Y) : 0

is transformed into SAT_SUB (X, Y) when X and Y are unsigned scalars,
which therefore correctly matches more cases of IFN SAT_SUB. New tests
are added to verify this behaviour on targets which use the standard
names for IFN SAT_SUB, and the tests are skipped if the current target
does not support IFN_SAT_SUB for each of these modes (via
dg-require-effective-target).

This passes the aarch64 regression tests with no additional failures.

gcc/ChangeLog:

	* match.pd: Add new match for SAT_SUB.

gcc/testsuite/ChangeLog:

	* gcc.dg/tree-ssa/sat-u-sub-match-1-u16.c: New test.
	* gcc.dg/tree-ssa/sat-u-sub-match-1-u32.c: New test.
	* gcc.dg/tree-ssa/sat-u-sub-match-1-u64.c: New test.
	* gcc.dg/tree-ssa/sat-u-sub-match-1-u8.c: New test.
---
 gcc/match.pd                                      |  8 ++++++++
 .../gcc.dg/tree-ssa/sat-u-sub-match-1-u16.c       | 15 +++++++++++++++
 .../gcc.dg/tree-ssa/sat-u-sub-match-1-u32.c       | 15 +++++++++++++++
 .../gcc.dg/tree-ssa/sat-u-sub-match-1-u64.c       | 15 +++++++++++++++
 .../gcc.dg/tree-ssa/sat-u-sub-match-1-u8.c        | 15 +++++++++++++++
 5 files changed, 68 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/sat-u-sub-match-1-u16.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/sat-u-sub-match-1-u32.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/sat-u-sub-match-1-u64.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/sat-u-sub-match-1-u8.c
  

Patch

diff --git a/gcc/match.pd b/gcc/match.pd
index ee53c25cef9..4fc5efa6247 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3360,6 +3360,14 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   }
   (if (wi::eq_p (sum, wi::uhwi (0, precision)))))))
 
+/* Unsigned saturation sub, case 11 (branch with ge):
+  SAT_U_SUB = X >= (X - Y) ? (X - Y) : 0.  */
+(match (unsigned_integer_sat_sub @0 @1)
+ (cond^ (ge @0 (minus @0 @1))
+  (convert? (minus (convert1? @0) (convert1? @1))) integer_zerop)
+ (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
+      && TYPE_UNSIGNED (TREE_TYPE (@0)) && types_match (@0, @1))))
+
 /* Signed saturation sub, case 1:
    T minus = (T)((UT)X - (UT)Y);
    SAT_S_SUB = (X ^ Y) & (X ^ minus) < 0 ? (-(T)(X < 0) ^ MAX) : minus;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sat-u-sub-match-1-u16.c b/gcc/testsuite/gcc.dg/tree-ssa/sat-u-sub-match-1-u16.c
new file mode 100644
index 00000000000..641fac50858
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/sat-u-sub-match-1-u16.c
@@ -0,0 +1,15 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target ussub_himode } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+#include <stdint.h>
+
+#define T uint16_t
+
+T sat_u_sub_1 (T a, T b)
+{
+  T sum = a - b;
+  return sum > a ? 0 : sum;
+}
+
+/* { dg-final { scan-tree-dump " .SAT_SUB " "optimized" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sat-u-sub-match-1-u32.c b/gcc/testsuite/gcc.dg/tree-ssa/sat-u-sub-match-1-u32.c
new file mode 100644
index 00000000000..27f3bae7d52
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/sat-u-sub-match-1-u32.c
@@ -0,0 +1,15 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target ussub_simode } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+#include <stdint.h>
+
+#define T uint32_t
+
+T sat_u_sub_1 (T a, T b)
+{
+  T sum = a - b;
+  return sum > a ? 0 : sum;
+}
+
+/* { dg-final { scan-tree-dump " .SAT_SUB " "optimized" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sat-u-sub-match-1-u64.c b/gcc/testsuite/gcc.dg/tree-ssa/sat-u-sub-match-1-u64.c
new file mode 100644
index 00000000000..92883ce60c7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/sat-u-sub-match-1-u64.c
@@ -0,0 +1,15 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target ussub_dimode } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+#include <stdint.h>
+
+#define T uint64_t
+
+T sat_u_sub_1 (T a, T b)
+{
+  T sum = a - b;
+  return sum > a ? 0 : sum;
+}
+
+/* { dg-final { scan-tree-dump " .SAT_SUB " "optimized" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sat-u-sub-match-1-u8.c b/gcc/testsuite/gcc.dg/tree-ssa/sat-u-sub-match-1-u8.c
new file mode 100644
index 00000000000..06ff91dbed0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/sat-u-sub-match-1-u8.c
@@ -0,0 +1,15 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target ussub_qimode } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+#include <stdint.h>
+
+#define T uint8_t
+
+T sat_u_sub_1 (T a, T b)
+{
+  T sum = a - b;
+  return sum > a ? 0 : sum;
+}
+
+/* { dg-final { scan-tree-dump " .SAT_SUB " "optimized" } } */
\ No newline at end of file