public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH v2] RISC-V: Implement .SAT_SUB for unsigned scalar int
@ 2024-06-07  2:13 pan2.li
  2024-06-07 10:18 ` Robin Dapp
  0 siblings, 1 reply; 4+ messages in thread
From: pan2.li @ 2024-06-07  2:13 UTC (permalink / raw)
  To: gcc-patches; +Cc: juzhe.zhong, kito.cheng, Pan Li

From: Pan Li <pan2.li@intel.com>

As the middle support of .SAT_SUB committed,  implement the unsigned
scalar int of .SAT_SUB for the riscv backend.  Consider below example
code:

T __attribute__((noinline))        \
sat_u_sub_##T##_fmt_1 (T x, T y)   \
{                                  \
  return (x - y) & (-(T)(x >= y)); \
}

T __attribute__((noinline))       \
sat_u_sub_##T##_fmt_2 (T x, T y)  \
{                                 \
  return (x - y) & (-(T)(x > y)); \
}

DEF_SAT_U_SUB_FMT_1(uint64_t);
DEF_SAT_U_SUB_FMT_2(uint64_t);

Before this patch:
sat_u_sub_uint64_t_fmt_1:
        bltu    a0,a1,.L2
        sub     a0,a0,a1
        ret
.L2:
        li      a0,0
        ret

After this patch:
sat_u_sub_uint64_t_fmt_1:
        sltu    a5,a0,a1
        addi    a5,a5,-1
        sub     a0,a0,a1
        and     a0,a5,a0
        ret

Please note only above 2 forms of .SAT_SUB are support for now,  we will
add more forms in short future.

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

gcc/ChangeLog:

	* config/riscv/riscv-protos.h (riscv_expand_ussub): Add new func
	decl for ussub expanding.
	* config/riscv/riscv.cc (riscv_expand_ussub): Ditto but for impl.
	* config/riscv/riscv.md (ussub<mode>3): Add new pattern ussub
	for scalar modes.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/sat_arith.h: Add test macros and comments.
	* gcc.target/riscv/sat_u_sub-1.c: New test.
	* gcc.target/riscv/sat_u_sub-2.c: New test.
	* gcc.target/riscv/sat_u_sub-3.c: New test.
	* gcc.target/riscv/sat_u_sub-4.c: New test.
	* gcc.target/riscv/sat_u_sub-5.c: New test.
	* gcc.target/riscv/sat_u_sub-6.c: New test.
	* gcc.target/riscv/sat_u_sub-7.c: New test.
	* gcc.target/riscv/sat_u_sub-8.c: New test.
	* gcc.target/riscv/sat_u_sub-run-1.c: New test.
	* gcc.target/riscv/sat_u_sub-run-2.c: New test.
	* gcc.target/riscv/sat_u_sub-run-3.c: New test.
	* gcc.target/riscv/sat_u_sub-run-4.c: New test.
	* gcc.target/riscv/sat_u_sub-run-5.c: New test.
	* gcc.target/riscv/sat_u_sub-run-6.c: New test.
	* gcc.target/riscv/sat_u_sub-run-7.c: New test.
	* gcc.target/riscv/sat_u_sub-run-8.c: New test.

Signed-off-by: Pan Li <pan2.li@intel.com>
---
 gcc/config/riscv/riscv-protos.h               |  1 +
 gcc/config/riscv/riscv.cc                     | 39 +++++++++++++++++++
 gcc/config/riscv/riscv.md                     | 11 ++++++
 gcc/testsuite/gcc.target/riscv/sat_arith.h    | 23 +++++++++++
 gcc/testsuite/gcc.target/riscv/sat_u_sub-1.c  | 18 +++++++++
 gcc/testsuite/gcc.target/riscv/sat_u_sub-2.c  | 19 +++++++++
 gcc/testsuite/gcc.target/riscv/sat_u_sub-3.c  | 18 +++++++++
 gcc/testsuite/gcc.target/riscv/sat_u_sub-4.c  | 17 ++++++++
 gcc/testsuite/gcc.target/riscv/sat_u_sub-5.c  | 18 +++++++++
 gcc/testsuite/gcc.target/riscv/sat_u_sub-6.c  | 19 +++++++++
 gcc/testsuite/gcc.target/riscv/sat_u_sub-7.c  | 18 +++++++++
 gcc/testsuite/gcc.target/riscv/sat_u_sub-8.c  | 17 ++++++++
 .../gcc.target/riscv/sat_u_sub-run-1.c        | 25 ++++++++++++
 .../gcc.target/riscv/sat_u_sub-run-2.c        | 25 ++++++++++++
 .../gcc.target/riscv/sat_u_sub-run-3.c        | 25 ++++++++++++
 .../gcc.target/riscv/sat_u_sub-run-4.c        | 25 ++++++++++++
 .../gcc.target/riscv/sat_u_sub-run-5.c        | 25 ++++++++++++
 .../gcc.target/riscv/sat_u_sub-run-6.c        | 25 ++++++++++++
 .../gcc.target/riscv/sat_u_sub-run-7.c        | 25 ++++++++++++
 .../gcc.target/riscv/sat_u_sub-run-8.c        | 25 ++++++++++++
 20 files changed, 418 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_u_sub-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_u_sub-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_u_sub-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_u_sub-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_u_sub-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_u_sub-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_u_sub-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_u_sub-8.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_u_sub-run-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_u_sub-run-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_u_sub-run-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_u_sub-run-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_u_sub-run-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_u_sub-run-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_u_sub-run-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_u_sub-run-8.c

diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 0704968561b..09eb3a574e3 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -134,6 +134,7 @@ extern bool
 riscv_zcmp_valid_stack_adj_bytes_p (HOST_WIDE_INT, int);
 extern void riscv_legitimize_poly_move (machine_mode, rtx, rtx, rtx);
 extern void riscv_expand_usadd (rtx, rtx, rtx);
+extern void riscv_expand_ussub (rtx, rtx, rtx);
 
 #ifdef RTX_CODE
 extern void riscv_expand_int_scc (rtx, enum rtx_code, rtx, rtx, bool *invert_ptr = 0);
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 9704ff9c6a0..5d1b1b2dfd7 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -11612,6 +11612,45 @@ riscv_expand_usadd (rtx dest, rtx x, rtx y)
   emit_move_insn (dest, gen_lowpart (mode, xmode_dest));
 }
 
+/* Implements the unsigned saturation sub standard name usadd for int mode.
+
+   z = SAT_SUB(x, y).
+   =>
+   1. minus = x - y.
+   2. lt = x < y.
+   3. lt = -lt.
+   4. lt = ~lt.
+   5. z = minus & lt.  */
+
+void
+riscv_expand_ussub (rtx dest, rtx x, rtx y)
+{
+  machine_mode mode = GET_MODE (dest);
+  rtx pmode_x = gen_lowpart (Pmode, x);
+  rtx pmode_y = gen_lowpart (Pmode, y);
+  rtx pmode_lt = gen_reg_rtx (Pmode);
+  rtx pmode_minus = gen_reg_rtx (Pmode);
+  rtx pmode_dest = gen_reg_rtx (Pmode);
+
+  /* Step-1: minus = x - y  */
+  riscv_emit_binary (MINUS, pmode_minus, pmode_x, pmode_y);
+
+  /* Step-2: lt = x < y  */
+  riscv_emit_binary (LTU, pmode_lt, pmode_x, pmode_y);
+
+  /* Step-3: lt = -lt  */
+  riscv_emit_unary (NEG, pmode_lt, pmode_lt);
+
+  /* Step-4: lt = ~lt  */
+  riscv_emit_unary (NOT, pmode_lt, pmode_lt);
+
+  /* Step-5: pmode_dest = minus & lt  */
+  riscv_emit_binary (AND, pmode_dest, pmode_lt, pmode_minus);
+
+  /* Step-6: dest = pmode_dest  */
+  emit_move_insn (dest, gen_lowpart (mode, pmode_dest));
+}
+
 /* Initialize the GCC target structure.  */
 #undef TARGET_ASM_ALIGNED_HI_OP
 #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index e57bfcf616a..7a9454de430 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -4228,6 +4228,17 @@ (define_expand "usadd<mode>3"
   }
 )
 
+(define_expand "ussub<mode>3"
+  [(match_operand:ANYI 0 "register_operand")
+   (match_operand:ANYI 1 "register_operand")
+   (match_operand:ANYI 2 "register_operand")]
+  ""
+  {
+    riscv_expand_ussub (operands[0], operands[1], operands[2]);
+    DONE;
+  }
+)
+
 ;; These are forms of (x << C1) + C2, potentially canonicalized from
 ;; ((x + C2') << C1.  Depending on the cost to load C2 vs C2' we may
 ;; want to go ahead and recognize this form as C2 may be cheaper to
diff --git a/gcc/testsuite/gcc.target/riscv/sat_arith.h b/gcc/testsuite/gcc.target/riscv/sat_arith.h
index 976ef1c44c1..9c60ac09f41 100644
--- a/gcc/testsuite/gcc.target/riscv/sat_arith.h
+++ b/gcc/testsuite/gcc.target/riscv/sat_arith.h
@@ -3,6 +3,9 @@
 
 #include <stdint-gcc.h>
 
+/******************************************************************************/
+/* Saturation Add (unsigned and signed)                                       */
+/******************************************************************************/
 #define DEF_SAT_U_ADD_FMT_1(T)             \
 T __attribute__((noinline))                \
 sat_u_add_##T##_fmt_1 (T x, T y)           \
@@ -72,4 +75,24 @@ vec_sat_u_add_##T##_fmt_1 (T *out, T *op_1, T *op_2, unsigned limit) \
 #define RUN_VEC_SAT_U_ADD_FMT_1(T, out, op_1, op_2, N) \
   vec_sat_u_add_##T##_fmt_1(out, op_1, op_2, N)
 
+/******************************************************************************/
+/* Saturation Sub (Unsigned and Signed)                                       */
+/******************************************************************************/
+#define DEF_SAT_U_SUB_FMT_1(T)     \
+T __attribute__((noinline))        \
+sat_u_sub_##T##_fmt_1 (T x, T y)   \
+{                                  \
+  return (x - y) & (-(T)(x >= y)); \
+}
+
+#define DEF_SAT_U_SUB_FMT_2(T)    \
+T __attribute__((noinline))       \
+sat_u_sub_##T##_fmt_2 (T x, T y)  \
+{                                 \
+  return (x - y) & (-(T)(x > y)); \
+}
+
+#define RUN_SAT_U_SUB_FMT_1(T, x, y) sat_u_sub_##T##_fmt_1(x, y)
+#define RUN_SAT_U_SUB_FMT_2(T, x, y) sat_u_sub_##T##_fmt_2(x, y)
+
 #endif
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-1.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-1.c
new file mode 100644
index 00000000000..73be7d59422
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fdump-rtl-expand-details -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "sat_arith.h"
+
+/*
+** sat_u_sub_uint8_t_fmt_1:
+** sub\s+[atx][0-9]+,\s*a0,\s*a1
+** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
+** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1
+** and\s+a0,\s*a0,\s*[atx][0-9]+
+** andi\s+a0,\s*a0,\s*0xff
+** ret
+*/
+DEF_SAT_U_SUB_FMT_1(uint8_t)
+
+/* { dg-final { scan-rtl-dump-times ".SAT_SUB " 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-2.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-2.c
new file mode 100644
index 00000000000..7bd5efcd9d9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-2.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fdump-rtl-expand-details -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "sat_arith.h"
+
+/*
+** sat_u_sub_uint16_t_fmt_1:
+** sub\s+[atx][0-9]+,\s*a0,\s*a1
+** sltu\s+[atx][0-9]+,\s*a0,\s*a1
+** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1
+** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
+** slli\s+a0,\s*a0,\s*48
+** srli\s+a0,\s*a0,\s*48
+** ret
+*/
+DEF_SAT_U_SUB_FMT_1(uint16_t)
+
+/* { dg-final { scan-rtl-dump-times ".SAT_SUB " 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-3.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-3.c
new file mode 100644
index 00000000000..a60fc9ba71e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-3.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fdump-rtl-expand-details -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "sat_arith.h"
+
+/*
+** sat_u_sub_uint32_t_fmt_1:
+** sub\s+[atx][0-9]+,\s*a0,\s*a1
+** sltu\s+[atx][0-9]+,\s*a0,\s*a1
+** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1
+** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
+** sext.w\s+a0,\s*a0
+** ret
+*/
+DEF_SAT_U_SUB_FMT_1(uint32_t)
+
+/* { dg-final { scan-rtl-dump-times ".SAT_SUB " 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-4.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-4.c
new file mode 100644
index 00000000000..bae46a0bd83
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-4.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fdump-rtl-expand-details -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "sat_arith.h"
+
+/*
+** sat_u_sub_uint64_t_fmt_1:
+** sub\s+[atx][0-9]+,\s*a0,\s*a1
+** sltu\s+[atx][0-9]+,\s*a0,\s*a1
+** addi\s+a0,\s*[atx][0-9]+,\s*-1
+** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
+** ret
+*/
+DEF_SAT_U_SUB_FMT_1(uint64_t)
+
+/* { dg-final { scan-rtl-dump-times ".SAT_SUB " 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-5.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-5.c
new file mode 100644
index 00000000000..e917487a640
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-5.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fdump-rtl-expand-details -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "sat_arith.h"
+
+/*
+** sat_u_sub_uint8_t_fmt_2:
+** sub\s+[atx][0-9]+,\s*a0,\s*a1
+** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
+** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1
+** and\s+a0,\s*a0,\s*[atx][0-9]+
+** andi\s+a0,\s*a0,\s*0xff
+** ret
+*/
+DEF_SAT_U_SUB_FMT_2(uint8_t)
+
+/* { dg-final { scan-rtl-dump-times ".SAT_SUB " 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-6.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-6.c
new file mode 100644
index 00000000000..4e3c91d205d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-6.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fdump-rtl-expand-details -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "sat_arith.h"
+
+/*
+** sat_u_sub_uint16_t_fmt_2:
+** sub\s+[atx][0-9]+,\s*a0,\s*a1
+** sltu\s+[atx][0-9]+,\s*a0,\s*a1
+** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1
+** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
+** slli\s+a0,\s*a0,\s*48
+** srli\s+a0,\s*a0,\s*48
+** ret
+*/
+DEF_SAT_U_SUB_FMT_2(uint16_t)
+
+/* { dg-final { scan-rtl-dump-times ".SAT_SUB " 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-7.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-7.c
new file mode 100644
index 00000000000..e1b0eaccf95
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-7.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fdump-rtl-expand-details -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "sat_arith.h"
+
+/*
+** sat_u_sub_uint32_t_fmt_2:
+** sub\s+[atx][0-9]+,\s*a0,\s*a1
+** sltu\s+[atx][0-9]+,\s*a0,\s*a1
+** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1
+** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
+** sext.w\s+a0,\s*a0
+** ret
+*/
+DEF_SAT_U_SUB_FMT_2(uint32_t)
+
+/* { dg-final { scan-rtl-dump-times ".SAT_SUB " 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-8.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-8.c
new file mode 100644
index 00000000000..d73f00fcf02
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-8.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fdump-rtl-expand-details -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "sat_arith.h"
+
+/*
+** sat_u_sub_uint64_t_fmt_2:
+** sub\s+[atx][0-9]+,\s*a0,\s*a1
+** sltu\s+[atx][0-9]+,\s*a0,\s*a1
+** addi\s+a0,\s*[atx][0-9]+,\s*-1
+** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
+** ret
+*/
+DEF_SAT_U_SUB_FMT_2(uint64_t)
+
+/* { dg-final { scan-rtl-dump-times ".SAT_SUB " 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-1.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-1.c
new file mode 100644
index 00000000000..931420a3098
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-1.c
@@ -0,0 +1,25 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+
+#define T              uint8_t
+#define RUN_SAT_BINARY RUN_SAT_U_SUB_FMT_1
+
+DEF_SAT_U_SUB_FMT_1(T)
+
+T test_data[][3] = {
+  /* arg_0, arg_1, expect */
+  {      0,     0,      0, },
+  {      0,     1,      0, },
+  {      1,     1,      0, },
+  {    255,   254,      1, },
+  {    255,   255,      0, },
+  {    254,   255,      0, },
+  {    253,   254,      0, },
+  {      0,   255,      0, },
+  {      1,   255,      0, },
+  {     32,     5,     27, },
+};
+
+#include "scalar_sat_binary.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-2.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-2.c
new file mode 100644
index 00000000000..1534cf99827
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-2.c
@@ -0,0 +1,25 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+
+#define T              uint16_t
+#define RUN_SAT_BINARY RUN_SAT_U_SUB_FMT_1
+
+DEF_SAT_U_SUB_FMT_1(T)
+
+T test_data[][3] = {
+  /* arg_0, arg_1, expect */
+  {      0,     0,      0, },
+  {      0,     1,      0, },
+  {      1,     1,      0, },
+  {  65535, 65534,      1, },
+  {  65535, 65535,      0, },
+  {  65534, 65535,      0, },
+  {  65533, 65534,      0, },
+  {      0, 65535,      0, },
+  {      1, 65535,      0, },
+  {     35,     5,     30, },
+};
+
+#include "scalar_sat_binary.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-3.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-3.c
new file mode 100644
index 00000000000..5c60d28997f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-3.c
@@ -0,0 +1,25 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+
+#define T              uint32_t
+#define RUN_SAT_BINARY RUN_SAT_U_SUB_FMT_1
+
+DEF_SAT_U_SUB_FMT_1(T)
+
+T test_data[][3] = {
+  /*     arg_0,      arg_1,      expect */
+  {          0,          0,           0, },
+  {          0,          1,           0, },
+  {          1,          1,           0, },
+  { 4294967295, 4294967294,           1, },
+  { 4294967295, 4294967295,           0, },
+  { 4294967294, 4294967295,           0, },
+  { 4294967293, 4294967294,           0, },
+  {          1, 4294967295,           0, },
+  {          2, 4294967295,           0, },
+  {          5,          1,           4, },
+};
+
+#include "scalar_sat_binary.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-4.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-4.c
new file mode 100644
index 00000000000..403764c8568
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-4.c
@@ -0,0 +1,25 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+
+#define T              uint64_t
+#define RUN_SAT_BINARY RUN_SAT_U_SUB_FMT_1
+
+DEF_SAT_U_SUB_FMT_1(T)
+
+T test_data[][3] = {
+  /*                arg_0,                 arg_1,                 expect */
+  {                     0,                     0,                      0, },
+  {                     0,                     1,                      0, },
+  {                     1,                     1,                      0, },
+  { 18446744073709551615u, 18446744073709551614u,                      1, },
+  { 18446744073709551615u, 18446744073709551615u,                      0, },
+  { 18446744073709551614u, 18446744073709551615u,                      0, },
+  { 18446744073709551613u, 18446744073709551614u,                      0, },
+  {                     0, 18446744073709551615u,                      0, },
+  {                     1, 18446744073709551615u,                      0, },
+  {                    43,                    11,                     32, },
+};
+
+#include "scalar_sat_binary.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-5.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-5.c
new file mode 100644
index 00000000000..6fa44ca323b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-5.c
@@ -0,0 +1,25 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+
+#define T              uint8_t
+#define RUN_SAT_BINARY RUN_SAT_U_SUB_FMT_2
+
+DEF_SAT_U_SUB_FMT_2(T)
+
+T test_data[][3] = {
+  /* arg_0, arg_1, expect */
+  {      0,     0,      0, },
+  {      0,     1,      0, },
+  {      1,     1,      0, },
+  {    255,   254,      1, },
+  {    255,   255,      0, },
+  {    254,   255,      0, },
+  {    253,   254,      0, },
+  {      0,   255,      0, },
+  {      1,   255,      0, },
+  {     32,     5,     27, },
+};
+
+#include "scalar_sat_binary.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-6.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-6.c
new file mode 100644
index 00000000000..7deaae9a5fd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-6.c
@@ -0,0 +1,25 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+
+#define T              uint16_t
+#define RUN_SAT_BINARY RUN_SAT_U_SUB_FMT_2
+
+DEF_SAT_U_SUB_FMT_2(T)
+
+T test_data[][3] = {
+  /* arg_0, arg_1, expect */
+  {      0,     0,      0, },
+  {      0,     1,      0, },
+  {      1,     1,      0, },
+  {  65535, 65534,      1, },
+  {  65535, 65535,      0, },
+  {  65534, 65535,      0, },
+  {  65533, 65534,      0, },
+  {      0, 65535,      0, },
+  {      1, 65535,      0, },
+  {     35,     5,     30, },
+};
+
+#include "scalar_sat_binary.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-7.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-7.c
new file mode 100644
index 00000000000..d9b1d5cbfe2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-7.c
@@ -0,0 +1,25 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+
+#define T              uint32_t
+#define RUN_SAT_BINARY RUN_SAT_U_SUB_FMT_2
+
+DEF_SAT_U_SUB_FMT_2(T)
+
+T test_data[][3] = {
+  /*     arg_0,      arg_1,      expect */
+  {          0,          0,           0, },
+  {          0,          1,           0, },
+  {          1,          1,           0, },
+  { 4294967295, 4294967294,           1, },
+  { 4294967295, 4294967295,           0, },
+  { 4294967294, 4294967295,           0, },
+  { 4294967293, 4294967294,           0, },
+  {          1, 4294967295,           0, },
+  {          2, 4294967295,           0, },
+  {          5,          1,           4, },
+};
+
+#include "scalar_sat_binary.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-8.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-8.c
new file mode 100644
index 00000000000..2774c235cc3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-8.c
@@ -0,0 +1,25 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+
+#define T              uint64_t
+#define RUN_SAT_BINARY RUN_SAT_U_SUB_FMT_2
+
+DEF_SAT_U_SUB_FMT_2(T)
+
+T test_data[][3] = {
+  /*                arg_0,                 arg_1,                 expect */
+  {                     0,                     0,                      0, },
+  {                     0,                     1,                      0, },
+  {                     1,                     1,                      0, },
+  { 18446744073709551615u, 18446744073709551614u,                      1, },
+  { 18446744073709551615u, 18446744073709551615u,                      0, },
+  { 18446744073709551614u, 18446744073709551615u,                      0, },
+  { 18446744073709551613u, 18446744073709551614u,                      0, },
+  {                     0, 18446744073709551615u,                      0, },
+  {                     1, 18446744073709551615u,                      0, },
+  {                    43,                    11,                     32, },
+};
+
+#include "scalar_sat_binary.h"
-- 
2.34.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] RISC-V: Implement .SAT_SUB for unsigned scalar int
  2024-06-07  2:13 [PATCH v2] RISC-V: Implement .SAT_SUB for unsigned scalar int pan2.li
@ 2024-06-07 10:18 ` Robin Dapp
  2024-06-07 12:13   ` Li, Pan2
  0 siblings, 1 reply; 4+ messages in thread
From: Robin Dapp @ 2024-06-07 10:18 UTC (permalink / raw)
  To: pan2.li, gcc-patches; +Cc: rdapp.gcc, juzhe.zhong, kito.cheng

Hi Pan,

> +  /* Step-2: lt = x < y  */
> +  riscv_emit_binary (LTU, pmode_lt, pmode_x, pmode_y);
> +
> +  /* Step-3: lt = -lt  */
> +  riscv_emit_unary (NEG, pmode_lt, pmode_lt);
> +
> +  /* Step-4: lt = ~lt  */
> +  riscv_emit_unary (NOT, pmode_lt, pmode_lt);

Can we replace step 3 and 4 with sub lt, -1 directly when
it's supposed to be optimized like that anyway?
I was a bit irritated when reading the code because I
figured we could surely save one instruction there but then
realized that the cover letter has the shorter sequence.

The rest LGTM.

When you say other variants are still to be implemented
does that also include variants for zbb with min/max
or zicond?

Regards
 Robin

^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: [PATCH v2] RISC-V: Implement .SAT_SUB for unsigned scalar int
  2024-06-07 10:18 ` Robin Dapp
@ 2024-06-07 12:13   ` Li, Pan2
  2024-06-07 12:20     ` Robin Dapp
  0 siblings, 1 reply; 4+ messages in thread
From: Li, Pan2 @ 2024-06-07 12:13 UTC (permalink / raw)
  To: Robin Dapp, gcc-patches; +Cc: juzhe.zhong, kito.cheng

Thanks Robin for comments.

> Can we replace step 3 and 4 with sub lt, -1 directly when
> it's supposed to be optimized like that anyway?

Sure thing, will update in v3.

> When you say other variants are still to be implemented
> does that also include variants for zbb with min/max
> or zicond?

No, I mean some other forms like branch need the improvement from the middle end(aka widen_mul).

Pan

-----Original Message-----
From: Robin Dapp <rdapp.gcc@gmail.com> 
Sent: Friday, June 7, 2024 6:18 PM
To: Li, Pan2 <pan2.li@intel.com>; gcc-patches@gcc.gnu.org
Cc: rdapp.gcc@gmail.com; juzhe.zhong@rivai.ai; kito.cheng@gmail.com
Subject: Re: [PATCH v2] RISC-V: Implement .SAT_SUB for unsigned scalar int

Hi Pan,

> +  /* Step-2: lt = x < y  */
> +  riscv_emit_binary (LTU, pmode_lt, pmode_x, pmode_y);
> +
> +  /* Step-3: lt = -lt  */
> +  riscv_emit_unary (NEG, pmode_lt, pmode_lt);
> +
> +  /* Step-4: lt = ~lt  */
> +  riscv_emit_unary (NOT, pmode_lt, pmode_lt);

Can we replace step 3 and 4 with sub lt, -1 directly when
it's supposed to be optimized like that anyway?
I was a bit irritated when reading the code because I
figured we could surely save one instruction there but then
realized that the cover letter has the shorter sequence.

The rest LGTM.

When you say other variants are still to be implemented
does that also include variants for zbb with min/max
or zicond?

Regards
 Robin

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] RISC-V: Implement .SAT_SUB for unsigned scalar int
  2024-06-07 12:13   ` Li, Pan2
@ 2024-06-07 12:20     ` Robin Dapp
  0 siblings, 0 replies; 4+ messages in thread
From: Robin Dapp @ 2024-06-07 12:20 UTC (permalink / raw)
  To: Li, Pan2, gcc-patches; +Cc: rdapp.gcc, juzhe.zhong, kito.cheng

>> When you say other variants are still to be implemented
>> does that also include variants for zbb with min/max
>> or zicond?
> 
> No, I mean some other forms like branch need the improvement from the
> middle end(aka widen_mul).

Ah, I see, thanks.  Those can save one instruction and we want them
at some point.  No need to add them now but maybe add a TODO for later.

Regards
 Robin


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-06-07 12:20 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-06-07  2:13 [PATCH v2] RISC-V: Implement .SAT_SUB for unsigned scalar int pan2.li
2024-06-07 10:18 ` Robin Dapp
2024-06-07 12:13   ` Li, Pan2
2024-06-07 12:20     ` Robin Dapp

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).