[v3,2/3] Match: support new case of unsigned scalar SAT_SUB
Checks
Commit Message
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
@@ -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;
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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