[v2,02/10] Match: Simplify branch form 7 of unsigned SAT_ADD into branchless

Message ID 20241031062742.2709845-2-pan2.li@intel.com
State New
Headers
Series [v2,01/10] Match: Simplify branch form 4 of unsigned SAT_ADD into branchless |

Commit Message

Li, Pan2 Oct. 31, 2024, 6:27 a.m. UTC
  From: Pan Li <pan2.li@intel.com>

There are sorts of forms for the unsigned SAT_ADD.  Some of them are
complicated while others are cheap.  This patch would like to simplify
the complicated form into the cheap ones.  For example as below:

From the form 7 (branch):
  SAT_U_ADD = x <= (T)(x + y) ? (x + y) : -1.

To (branchless):
  SAT_U_ADD = (X + Y) | - ((X + Y) < X).

  #define T uint8_t

  T sat_add_u_1 (T x, T y)
  {
    return x <= (T)(x + y) ? (x + y) : -1;
  }

Before this patch:
   1   │ uint8_t sat_add_u_1 (uint8_t x, uint8_t y)
   2   │ {
   3   │   uint8_t D.2809;
   4   │
   5   │   _1 = x + y;
   6   │   if (x <= _1) goto <D.2810>; else goto <D.2811>;
   7   │   <D.2810>:
   8   │   D.2809 = x + y;
   9   │   goto <D.2812>;
  10   │   <D.2811>:
  11   │   D.2809 = 255;
  12   │   <D.2812>:
  13   │   return D.2809;
  14   │ }

After this patch:
   1   │ uint8_t sat_add_u_1 (uint8_t x, uint8_t y)
   2   │ {
   3   │   uint8_t D.2809;
   4   │
   5   │   _1 = x + y;
   6   │   _2 = x + y;
   7   │   _3 = x > _2;
   8   │   _4 = (unsigned char) _3;
   9   │   _5 = -_4;
  10   │   D.2809 = _1 | _5;
  11   │   return D.2809;
  12   │ }

The simplify doesn't need to check if target support the SAT_ADD, it
is somehow the optimization in gimple level.

The below test suites are passed for this patch.
* The rv64gcv fully regression test.
* The x86 bootstrap test.
* The x86 fully regression test.

gcc/ChangeLog:

	* match.pd: Remove unsigned branch form 7 for SAT_ADD, and
	add simplify to branchless instead.

gcc/testsuite/ChangeLog:

	* gcc.dg/sat_arith_simplify.h: Add test helper macros.
	* gcc.dg/sat_u_add-simplify-3-u16.c: New test.
	* gcc.dg/sat_u_add-simplify-3-u32.c: New test.
	* gcc.dg/sat_u_add-simplify-3-u64.c: New test.
	* gcc.dg/sat_u_add-simplify-3-u8.c: New test.

Signed-off-by: Pan Li <pan2.li@intel.com>
---
 gcc/match.pd                                    |  9 ++++-----
 gcc/testsuite/gcc.dg/sat_arith_simplify.h       |  6 ++++++
 gcc/testsuite/gcc.dg/sat_u_add-simplify-3-u16.c | 11 +++++++++++
 gcc/testsuite/gcc.dg/sat_u_add-simplify-3-u32.c | 11 +++++++++++
 gcc/testsuite/gcc.dg/sat_u_add-simplify-3-u64.c | 11 +++++++++++
 gcc/testsuite/gcc.dg/sat_u_add-simplify-3-u8.c  | 11 +++++++++++
 6 files changed, 54 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/sat_u_add-simplify-3-u16.c
 create mode 100644 gcc/testsuite/gcc.dg/sat_u_add-simplify-3-u32.c
 create mode 100644 gcc/testsuite/gcc.dg/sat_u_add-simplify-3-u64.c
 create mode 100644 gcc/testsuite/gcc.dg/sat_u_add-simplify-3-u8.c
  

Patch

diff --git a/gcc/match.pd b/gcc/match.pd
index 8425d7c4f20..5bfba46b0ce 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3153,6 +3153,10 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (simplify (cond (ge (plus:c@2 @0 @1) @0) @2 integer_minus_onep)
   (if (types_match (type, @0, @1))
    (bit_ior (plus@2 @0 @1) (negate (convert (lt @2 @0))))))
+ /* From SAT_ADD = x <= (X + Y) ? (X + Y) : -1.  */
+ (simplify (cond (le @0 (plus:c@2 @0 @1)) @2 integer_minus_onep)
+  (if (types_match (type, @0, @1))
+   (bit_ior (plus@2 @0 @1) (negate (convert (lt @2 @0))))))
  /* From SAT_U_ADD = (X + Y) < x ? -1 : (X + Y).  */
  (simplify (cond (lt (plus:c@2 @0 @1) @0) integer_minus_onep @2)
   (if (types_match (type, @0, @1))
@@ -3170,11 +3174,6 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (cond^ (ne (imagpart (IFN_ADD_OVERFLOW:c @0 @1)) integer_zerop)
   integer_minus_onep (usadd_left_part_2 @0 @1)))
 
-/* 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))
-
 /* Unsigned saturation add, case 8 (branch with gt):
    SAT_ADD = x > (X + Y) ? -1 : (X + Y).  */
 (match (unsigned_integer_sat_add @0 @1)
diff --git a/gcc/testsuite/gcc.dg/sat_arith_simplify.h b/gcc/testsuite/gcc.dg/sat_arith_simplify.h
index 46ac00426b2..a630936108f 100644
--- a/gcc/testsuite/gcc.dg/sat_arith_simplify.h
+++ b/gcc/testsuite/gcc.dg/sat_arith_simplify.h
@@ -7,4 +7,10 @@  T sat_u_add_##T##_2 (T x, T y)          \
   return (T)(x + y) < x ? -1 : (x + y); \
 }
 
+#define DEF_SAT_U_ADD_3(T)               \
+T sat_u_add_##T##_3 (T x, T y)           \
+{                                        \
+  return x <= (T)(x + y) ? (x + y) : -1; \
+}
+
 #endif
diff --git a/gcc/testsuite/gcc.dg/sat_u_add-simplify-3-u16.c b/gcc/testsuite/gcc.dg/sat_u_add-simplify-3-u16.c
new file mode 100644
index 00000000000..6998ce0999d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/sat_u_add-simplify-3-u16.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-gimple-details" } */
+
+#include <stdint.h>
+#include "sat_arith_simplify.h"
+
+DEF_SAT_U_ADD_3 (uint16_t)
+
+/* { dg-final { scan-tree-dump-not " if " "gimple" } } */
+/* { dg-final { scan-tree-dump-not " else " "gimple" } } */
+/* { dg-final { scan-tree-dump-not " goto " "gimple" } } */
diff --git a/gcc/testsuite/gcc.dg/sat_u_add-simplify-3-u32.c b/gcc/testsuite/gcc.dg/sat_u_add-simplify-3-u32.c
new file mode 100644
index 00000000000..6ee61ef7102
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/sat_u_add-simplify-3-u32.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-gimple-details" } */
+
+#include <stdint.h>
+#include "sat_arith_simplify.h"
+
+DEF_SAT_U_ADD_3 (uint32_t)
+
+/* { dg-final { scan-tree-dump-not " if " "gimple" } } */
+/* { dg-final { scan-tree-dump-not " else " "gimple" } } */
+/* { dg-final { scan-tree-dump-not " goto " "gimple" } } */
diff --git a/gcc/testsuite/gcc.dg/sat_u_add-simplify-3-u64.c b/gcc/testsuite/gcc.dg/sat_u_add-simplify-3-u64.c
new file mode 100644
index 00000000000..e444b93c70c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/sat_u_add-simplify-3-u64.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-gimple-details" } */
+
+#include <stdint.h>
+#include "sat_arith_simplify.h"
+
+DEF_SAT_U_ADD_3 (uint64_t)
+
+/* { dg-final { scan-tree-dump-not " if " "gimple" } } */
+/* { dg-final { scan-tree-dump-not " else " "gimple" } } */
+/* { dg-final { scan-tree-dump-not " goto " "gimple" } } */
diff --git a/gcc/testsuite/gcc.dg/sat_u_add-simplify-3-u8.c b/gcc/testsuite/gcc.dg/sat_u_add-simplify-3-u8.c
new file mode 100644
index 00000000000..3f114d77b75
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/sat_u_add-simplify-3-u8.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-gimple-details" } */
+
+#include <stdint.h>
+#include "sat_arith_simplify.h"
+
+DEF_SAT_U_ADD_3 (uint8_t)
+
+/* { dg-final { scan-tree-dump-not " if " "gimple" } } */
+/* { dg-final { scan-tree-dump-not " else " "gimple" } } */
+/* { dg-final { scan-tree-dump-not " goto " "gimple" } } */