diff mbox series

[v1] RISC-V: Add testcases for form 2 of signed scalar SAT_ADD

Message ID 20240913021453.1205324-1-pan2.li@intel.com
State New
Headers show
Series [v1] RISC-V: Add testcases for form 2 of signed scalar SAT_ADD | expand

Commit Message

Li, Pan2 Sept. 13, 2024, 2:14 a.m. UTC
From: Pan Li <pan2.li@intel.com>

This patch would like to add testcases of the signed scalar SAT_ADD
for form 2.  Aka:

Form 2:
  #define DEF_SAT_S_ADD_FMT_2(T, UT, MIN, MAX) \
  T __attribute__((noinline))                  \
  sat_s_add_##T##_fmt_2 (T x, T y)             \
  {                                            \
    T sum = (UT)x + (UT)y;                     \
    if ((x ^ y) < 0 || (sum ^ x) >= 0)         \
      return sum;                              \
    return x < 0 ? MIN : MAX;                  \
  }

DEF_SAT_S_ADD_FMT_2 (int64_t, uint64_t, INT64_MIN, INT64_MAX)

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

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/sat_arith.h: Add test helper macros.
	* gcc.target/riscv/sat_s_add-5.c: New test.
	* gcc.target/riscv/sat_s_add-6.c: New test.
	* gcc.target/riscv/sat_s_add-7.c: New test.
	* gcc.target/riscv/sat_s_add-8.c: New test.
	* gcc.target/riscv/sat_s_add-run-5.c: New test.
	* gcc.target/riscv/sat_s_add-run-6.c: New test.
	* gcc.target/riscv/sat_s_add-run-7.c: New test.
	* gcc.target/riscv/sat_s_add-run-8.c: New test.

Signed-off-by: Pan Li <pan2.li@intel.com>
---
 gcc/testsuite/gcc.target/riscv/sat_arith.h    | 13 ++++++++
 gcc/testsuite/gcc.target/riscv/sat_s_add-5.c  | 30 +++++++++++++++++
 gcc/testsuite/gcc.target/riscv/sat_s_add-6.c  | 32 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/sat_s_add-7.c  | 31 ++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/sat_s_add-8.c  | 29 +++++++++++++++++
 .../gcc.target/riscv/sat_s_add-run-5.c        | 16 ++++++++++
 .../gcc.target/riscv/sat_s_add-run-6.c        | 16 ++++++++++
 .../gcc.target/riscv/sat_s_add-run-7.c        | 16 ++++++++++
 .../gcc.target/riscv/sat_s_add-run-8.c        | 16 ++++++++++
 9 files changed, 199 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-8.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-run-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-run-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-run-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-run-8.c

Comments

Jeff Law Sept. 18, 2024, 3:10 p.m. UTC | #1
On 9/12/24 8:14 PM, pan2.li@intel.com wrote:
> From: Pan Li <pan2.li@intel.com>
> 
> This patch would like to add testcases of the signed scalar SAT_ADD
> for form 2.  Aka:
> 
> Form 2:
>    #define DEF_SAT_S_ADD_FMT_2(T, UT, MIN, MAX) \
>    T __attribute__((noinline))                  \
>    sat_s_add_##T##_fmt_2 (T x, T y)             \
>    {                                            \
>      T sum = (UT)x + (UT)y;                     \
>      if ((x ^ y) < 0 || (sum ^ x) >= 0)         \
>        return sum;                              \
>      return x < 0 ? MIN : MAX;                  \
>    }
> 
> DEF_SAT_S_ADD_FMT_2 (int64_t, uint64_t, INT64_MIN, INT64_MAX)
> 
> The below test are passed for this patch.
> * The rv64gcv fully regression test.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* gcc.target/riscv/sat_arith.h: Add test helper macros.
> 	* gcc.target/riscv/sat_s_add-5.c: New test.
> 	* gcc.target/riscv/sat_s_add-6.c: New test.
> 	* gcc.target/riscv/sat_s_add-7.c: New test.
> 	* gcc.target/riscv/sat_s_add-8.c: New test.
> 	* gcc.target/riscv/sat_s_add-run-5.c: New test.
> 	* gcc.target/riscv/sat_s_add-run-6.c: New test.
> 	* gcc.target/riscv/sat_s_add-run-7.c: New test.
> 	* gcc.target/riscv/sat_s_add-run-8.c: New test.
Not particularly happy with the wall of expected assembly output, though 
it at least tries to be generic in terms of registers and such.

So I'll ACK.  But....

I'd like us to start thinking about what is the most important part of 
what's being tested rather than just matching a blob of assembly text.

I believe (and please correct me if I'm wrong), what you're really 
testing here is whether or not we're recognizing the saturation idiom in 
gimple and then proceeding to generate code via the RISC-V backend's 
define_expand patterns.

So a better test would check for the IFN, probably in the .optimized or 
.expand dump.  What I don't offhand see is a good way to test that we're 
in one of the saturation related expanders.

I wonder if we could emit debugging output as part of the expander. 
It's reasonably likely that the dump_file and dump_flags are exposed as 
global variables.  That in turn would allow us to emit messages into the 
.expand dump file.  It doesn't have to be terribly complex.  Just a note 
about which expander we're in and perhaps some info about the arguments. 
   The point being to get away from using a scan-asm test for something 
we can look at more directly if we're willing to add a bit more 
information into the dump file.

jeff
> 
> Signed-off-by: Pan Li <pan2.li@intel.com>
> ---
>   gcc/testsuite/gcc.target/riscv/sat_arith.h    | 13 ++++++++
>   gcc/testsuite/gcc.target/riscv/sat_s_add-5.c  | 30 +++++++++++++++++
>   gcc/testsuite/gcc.target/riscv/sat_s_add-6.c  | 32 +++++++++++++++++++
>   gcc/testsuite/gcc.target/riscv/sat_s_add-7.c  | 31 ++++++++++++++++++
>   gcc/testsuite/gcc.target/riscv/sat_s_add-8.c  | 29 +++++++++++++++++
>   .../gcc.target/riscv/sat_s_add-run-5.c        | 16 ++++++++++
>   .../gcc.target/riscv/sat_s_add-run-6.c        | 16 ++++++++++
>   .../gcc.target/riscv/sat_s_add-run-7.c        | 16 ++++++++++
>   .../gcc.target/riscv/sat_s_add-run-8.c        | 16 ++++++++++
>   9 files changed, 199 insertions(+)
>   create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-5.c
>   create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-6.c
>   create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-7.c
>   create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-8.c
>   create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-run-5.c
>   create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-run-6.c
>   create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-run-7.c
>   create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-run-8.c
> 
> diff --git a/gcc/testsuite/gcc.target/riscv/sat_arith.h b/gcc/testsuite/gcc.target/riscv/sat_arith.h
> index a8672f66322..b4fbf5dc662 100644
> --- a/gcc/testsuite/gcc.target/riscv/sat_arith.h
> +++ b/gcc/testsuite/gcc.target/riscv/sat_arith.h
> @@ -132,9 +132,22 @@ sat_s_add_##T##_fmt_1 (T x, T y)             \
>   #define DEF_SAT_S_ADD_FMT_1_WRAP(T, UT, MIN, MAX) \
>     DEF_SAT_S_ADD_FMT_1(T, UT, MIN, MAX)
>   
> +#define DEF_SAT_S_ADD_FMT_2(T, UT, MIN, MAX) \
> +T __attribute__((noinline))                  \
> +sat_s_add_##T##_fmt_2 (T x, T y)             \
> +{                                            \
> +  T sum = (UT)x + (UT)y;                     \
> +  if ((x ^ y) < 0 || (sum ^ x) >= 0)         \
> +    return sum;                              \
> +  return x < 0 ? MIN : MAX;                  \
> +}
> +
>   #define RUN_SAT_S_ADD_FMT_1(T, x, y) sat_s_add_##T##_fmt_1(x, y)
>   #define RUN_SAT_S_ADD_FMT_1_WRAP(T, x, y) RUN_SAT_S_ADD_FMT_1(T, x, y)
>   
> +#define RUN_SAT_S_ADD_FMT_2(T, x, y) sat_s_add_##T##_fmt_2(x, y)
> +#define RUN_SAT_S_ADD_FMT_2_WRAP(T, x, y) RUN_SAT_S_ADD_FMT_2(T, x, y)
> +
>   /******************************************************************************/
>   /* Saturation Sub (Unsigned and Signed)                                       */
>   /******************************************************************************/
> diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-5.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-5.c
> new file mode 100644
> index 00000000000..b644022eb4e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-5.c
> @@ -0,0 +1,30 @@
> +/* { 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_s_add_int8_t_fmt_2:
> +** add\s+[atx][0-9]+,\s*a0,\s*a1
> +** xor\s+[atx][0-9]+,\s*a0,\s*a1
> +** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+
> +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*7
> +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*7
> +** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
> +** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
> +** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63
> +** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127
> +** neg\s+[atx][0-9]+,\s*[atx][0-9]+
> +** and\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+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** slliw\s+a0,\s*a0,\s*24
> +** sraiw\s+a0,\s*a0,\s*24
> +** ret
> +*/
> +DEF_SAT_S_ADD_FMT_2(int8_t, uint8_t, INT8_MIN, INT8_MAX)
> +
> +/* { dg-final { scan-rtl-dump-times ".SAT_ADD " 2 "expand" } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-6.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-6.c
> new file mode 100644
> index 00000000000..bc36ebe5187
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-6.c
> @@ -0,0 +1,32 @@
> +/* { 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_s_add_int16_t_fmt_2:
> +** add\s+[atx][0-9]+,\s*a0,\s*a1
> +** xor\s+[atx][0-9]+,\s*a0,\s*a1
> +** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+
> +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15
> +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15
> +** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
> +** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
> +** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63
> +** li\s+[atx][0-9]+,\s*32768
> +** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1
> +** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** neg\s+[atx][0-9]+,\s*[atx][0-9]+
> +** and\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+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** slliw\s+a0,\s*a0,\s*16
> +** sraiw\s+a0,\s*a0,\s*16
> +** ret
> +*/
> +DEF_SAT_S_ADD_FMT_2(int16_t, uint16_t, INT16_MIN, INT16_MAX)
> +
> +/* { dg-final { scan-rtl-dump-times ".SAT_ADD " 2 "expand" } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-7.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-7.c
> new file mode 100644
> index 00000000000..921d3c7c65a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-7.c
> @@ -0,0 +1,31 @@
> +/* { 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_s_add_int32_t_fmt_2:
> +** add\s+[atx][0-9]+,\s*a0,\s*a1
> +** xor\s+[atx][0-9]+,\s*a0,\s*a1
> +** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+
> +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31
> +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31
> +** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
> +** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
> +** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63
> +** li\s+[atx][0-9]+,\s*-2147483648
> +** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1
> +** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** neg\s+[atx][0-9]+,\s*[atx][0-9]+
> +** and\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+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** sext\.w\s+a0,\s*a0
> +** ret
> +*/
> +DEF_SAT_S_ADD_FMT_2(int32_t, uint32_t, INT32_MIN, INT32_MAX)
> +
> +/* { dg-final { scan-rtl-dump-times ".SAT_ADD " 2 "expand" } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-8.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-8.c
> new file mode 100644
> index 00000000000..4453b826fd0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-8.c
> @@ -0,0 +1,29 @@
> +/* { 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_s_add_int64_t_fmt_2:
> +** add\s+[atx][0-9]+,\s*a0,\s*a1
> +** xor\s+[atx][0-9]+,\s*a0,\s*a1
> +** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+
> +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63
> +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63
> +** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
> +** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63
> +** li\s+[atx][0-9]+,\s*-1
> +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
> +** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** neg\s+[atx][0-9]+,\s*[atx][0-9]+
> +** and\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+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** ret
> +*/
> +DEF_SAT_S_ADD_FMT_2(int64_t, uint64_t, INT64_MIN, INT64_MAX)
> +
> +/* { dg-final { scan-rtl-dump-times ".SAT_ADD " 2 "expand" } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-run-5.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-5.c
> new file mode 100644
> index 00000000000..9a4ce338d0c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-5.c
> @@ -0,0 +1,16 @@
> +/* { dg-do run { target { riscv_v } } } */
> +/* { dg-additional-options "-std=c99" } */
> +
> +#include "sat_arith.h"
> +#include "sat_arith_data.h"
> +
> +#define T1 int8_t
> +#define T2 uint8_t
> +
> +DEF_SAT_S_ADD_FMT_1_WRAP(T1, T2, INT8_MIN, INT8_MAX)
> +
> +#define DATA             TEST_BINARY_DATA_WRAP(T1, ssadd)
> +#define T                TEST_BINARY_STRUCT_DECL(T1, ssadd)
> +#define RUN_BINARY(x, y) RUN_SAT_S_ADD_FMT_1_WRAP(T1, x, y)
> +
> +#include "scalar_sat_binary_run_xxx.h"
> diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-run-6.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-6.c
> new file mode 100644
> index 00000000000..34459b85e2b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-6.c
> @@ -0,0 +1,16 @@
> +/* { dg-do run { target { riscv_v } } } */
> +/* { dg-additional-options "-std=c99" } */
> +
> +#include "sat_arith.h"
> +#include "sat_arith_data.h"
> +
> +#define T1 int16_t
> +#define T2 uint16_t
> +
> +DEF_SAT_S_ADD_FMT_1_WRAP(T1, T2, INT16_MIN, INT16_MAX)
> +
> +#define DATA             TEST_BINARY_DATA_WRAP(T1, ssadd)
> +#define T                TEST_BINARY_STRUCT_DECL(T1, ssadd)
> +#define RUN_BINARY(x, y) RUN_SAT_S_ADD_FMT_1_WRAP(T1, x, y)
> +
> +#include "scalar_sat_binary_run_xxx.h"
> diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-run-7.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-7.c
> new file mode 100644
> index 00000000000..4d4841f4066
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-7.c
> @@ -0,0 +1,16 @@
> +/* { dg-do run { target { riscv_v } } } */
> +/* { dg-additional-options "-std=c99" } */
> +
> +#include "sat_arith.h"
> +#include "sat_arith_data.h"
> +
> +#define T1 int32_t
> +#define T2 uint32_t
> +
> +DEF_SAT_S_ADD_FMT_1_WRAP(T1, T2, INT32_MIN, INT32_MAX)
> +
> +#define DATA             TEST_BINARY_DATA_WRAP(T1, ssadd)
> +#define T                TEST_BINARY_STRUCT_DECL(T1, ssadd)
> +#define RUN_BINARY(x, y) RUN_SAT_S_ADD_FMT_1_WRAP(T1, x, y)
> +
> +#include "scalar_sat_binary_run_xxx.h"
> diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-run-8.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-8.c
> new file mode 100644
> index 00000000000..df818879628
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-8.c
> @@ -0,0 +1,16 @@
> +/* { dg-do run { target { riscv_v } } } */
> +/* { dg-additional-options "-std=c99" } */
> +
> +#include "sat_arith.h"
> +#include "sat_arith_data.h"
> +
> +#define T1 int64_t
> +#define T2 uint64_t
> +
> +DEF_SAT_S_ADD_FMT_1_WRAP(T1, T2, INT64_MIN, INT64_MAX)
> +
> +#define DATA             TEST_BINARY_DATA_WRAP(T1, ssadd)
> +#define T                TEST_BINARY_STRUCT_DECL(T1, ssadd)
> +#define RUN_BINARY(x, y) RUN_SAT_S_ADD_FMT_1_WRAP(T1, x, y)
> +
> +#include "scalar_sat_binary_run_xxx.h"
Li, Pan2 Sept. 18, 2024, 11:38 p.m. UTC | #2
Thanks Jeff for comments.

> Not particularly happy with the wall of expected assembly output, though 
> it at least tries to be generic in terms of registers and such.

Sort of, the asm check for ssadd is quit long up to a point.

> So I'll ACK.  But....

> I'd like us to start thinking about what is the most important part of 
> what's being tested rather than just matching a blob of assembly text.

> I believe (and please correct me if I'm wrong), what you're really 
> testing here is whether or not we're recognizing the saturation idiom in 
> gimple and then proceeding to generate code via the RISC-V backend's 
> define_expand patterns.

Yes, you are right. The tests cover 3 parts, the SAT IR in expand dump, the 
Riscv backend code-gen, and the run test.

> So a better test would check for the IFN, probably in the .optimized or 
> .expand dump.  What I don't offhand see is a good way to test that we're 
> in one of the saturation related expanders.

> I wonder if we could emit debugging output as part of the expander. 
> It's reasonably likely that the dump_file and dump_flags are exposed as 
> global variables.  That in turn would allow us to emit messages into the 
> .expand dump file.  It doesn't have to be terribly complex.  Just a note 
> about which expander we're in and perhaps some info about the arguments. 
>   The point being to get away from using a scan-asm test for something 
> we can look at more directly if we're willing to add a bit more 
> information into the dump file.

I see, that would be a alternative approach for the backend code-gen checking.
It may make it easier for similar cases, I think we can have a try in short future.

Pan

-----Original Message-----
From: Jeff Law <jeffreyalaw@gmail.com> 
Sent: Wednesday, September 18, 2024 11:10 PM
To: Li, Pan2 <pan2.li@intel.com>; gcc-patches@gcc.gnu.org
Cc: juzhe.zhong@rivai.ai; kito.cheng@gmail.com; rdapp.gcc@gmail.com
Subject: Re: [PATCH v1] RISC-V: Add testcases for form 2 of signed scalar SAT_ADD



On 9/12/24 8:14 PM, pan2.li@intel.com wrote:
> From: Pan Li <pan2.li@intel.com>
> 
> This patch would like to add testcases of the signed scalar SAT_ADD
> for form 2.  Aka:
> 
> Form 2:
>    #define DEF_SAT_S_ADD_FMT_2(T, UT, MIN, MAX) \
>    T __attribute__((noinline))                  \
>    sat_s_add_##T##_fmt_2 (T x, T y)             \
>    {                                            \
>      T sum = (UT)x + (UT)y;                     \
>      if ((x ^ y) < 0 || (sum ^ x) >= 0)         \
>        return sum;                              \
>      return x < 0 ? MIN : MAX;                  \
>    }
> 
> DEF_SAT_S_ADD_FMT_2 (int64_t, uint64_t, INT64_MIN, INT64_MAX)
> 
> The below test are passed for this patch.
> * The rv64gcv fully regression test.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* gcc.target/riscv/sat_arith.h: Add test helper macros.
> 	* gcc.target/riscv/sat_s_add-5.c: New test.
> 	* gcc.target/riscv/sat_s_add-6.c: New test.
> 	* gcc.target/riscv/sat_s_add-7.c: New test.
> 	* gcc.target/riscv/sat_s_add-8.c: New test.
> 	* gcc.target/riscv/sat_s_add-run-5.c: New test.
> 	* gcc.target/riscv/sat_s_add-run-6.c: New test.
> 	* gcc.target/riscv/sat_s_add-run-7.c: New test.
> 	* gcc.target/riscv/sat_s_add-run-8.c: New test.
Not particularly happy with the wall of expected assembly output, though 
it at least tries to be generic in terms of registers and such.

So I'll ACK.  But....

I'd like us to start thinking about what is the most important part of 
what's being tested rather than just matching a blob of assembly text.

I believe (and please correct me if I'm wrong), what you're really 
testing here is whether or not we're recognizing the saturation idiom in 
gimple and then proceeding to generate code via the RISC-V backend's 
define_expand patterns.

So a better test would check for the IFN, probably in the .optimized or 
.expand dump.  What I don't offhand see is a good way to test that we're 
in one of the saturation related expanders.

I wonder if we could emit debugging output as part of the expander. 
It's reasonably likely that the dump_file and dump_flags are exposed as 
global variables.  That in turn would allow us to emit messages into the 
.expand dump file.  It doesn't have to be terribly complex.  Just a note 
about which expander we're in and perhaps some info about the arguments. 
   The point being to get away from using a scan-asm test for something 
we can look at more directly if we're willing to add a bit more 
information into the dump file.

jeff
> 
> Signed-off-by: Pan Li <pan2.li@intel.com>
> ---
>   gcc/testsuite/gcc.target/riscv/sat_arith.h    | 13 ++++++++
>   gcc/testsuite/gcc.target/riscv/sat_s_add-5.c  | 30 +++++++++++++++++
>   gcc/testsuite/gcc.target/riscv/sat_s_add-6.c  | 32 +++++++++++++++++++
>   gcc/testsuite/gcc.target/riscv/sat_s_add-7.c  | 31 ++++++++++++++++++
>   gcc/testsuite/gcc.target/riscv/sat_s_add-8.c  | 29 +++++++++++++++++
>   .../gcc.target/riscv/sat_s_add-run-5.c        | 16 ++++++++++
>   .../gcc.target/riscv/sat_s_add-run-6.c        | 16 ++++++++++
>   .../gcc.target/riscv/sat_s_add-run-7.c        | 16 ++++++++++
>   .../gcc.target/riscv/sat_s_add-run-8.c        | 16 ++++++++++
>   9 files changed, 199 insertions(+)
>   create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-5.c
>   create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-6.c
>   create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-7.c
>   create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-8.c
>   create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-run-5.c
>   create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-run-6.c
>   create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-run-7.c
>   create mode 100644 gcc/testsuite/gcc.target/riscv/sat_s_add-run-8.c
> 
> diff --git a/gcc/testsuite/gcc.target/riscv/sat_arith.h b/gcc/testsuite/gcc.target/riscv/sat_arith.h
> index a8672f66322..b4fbf5dc662 100644
> --- a/gcc/testsuite/gcc.target/riscv/sat_arith.h
> +++ b/gcc/testsuite/gcc.target/riscv/sat_arith.h
> @@ -132,9 +132,22 @@ sat_s_add_##T##_fmt_1 (T x, T y)             \
>   #define DEF_SAT_S_ADD_FMT_1_WRAP(T, UT, MIN, MAX) \
>     DEF_SAT_S_ADD_FMT_1(T, UT, MIN, MAX)
>   
> +#define DEF_SAT_S_ADD_FMT_2(T, UT, MIN, MAX) \
> +T __attribute__((noinline))                  \
> +sat_s_add_##T##_fmt_2 (T x, T y)             \
> +{                                            \
> +  T sum = (UT)x + (UT)y;                     \
> +  if ((x ^ y) < 0 || (sum ^ x) >= 0)         \
> +    return sum;                              \
> +  return x < 0 ? MIN : MAX;                  \
> +}
> +
>   #define RUN_SAT_S_ADD_FMT_1(T, x, y) sat_s_add_##T##_fmt_1(x, y)
>   #define RUN_SAT_S_ADD_FMT_1_WRAP(T, x, y) RUN_SAT_S_ADD_FMT_1(T, x, y)
>   
> +#define RUN_SAT_S_ADD_FMT_2(T, x, y) sat_s_add_##T##_fmt_2(x, y)
> +#define RUN_SAT_S_ADD_FMT_2_WRAP(T, x, y) RUN_SAT_S_ADD_FMT_2(T, x, y)
> +
>   /******************************************************************************/
>   /* Saturation Sub (Unsigned and Signed)                                       */
>   /******************************************************************************/
> diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-5.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-5.c
> new file mode 100644
> index 00000000000..b644022eb4e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-5.c
> @@ -0,0 +1,30 @@
> +/* { 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_s_add_int8_t_fmt_2:
> +** add\s+[atx][0-9]+,\s*a0,\s*a1
> +** xor\s+[atx][0-9]+,\s*a0,\s*a1
> +** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+
> +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*7
> +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*7
> +** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
> +** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
> +** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63
> +** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127
> +** neg\s+[atx][0-9]+,\s*[atx][0-9]+
> +** and\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+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** slliw\s+a0,\s*a0,\s*24
> +** sraiw\s+a0,\s*a0,\s*24
> +** ret
> +*/
> +DEF_SAT_S_ADD_FMT_2(int8_t, uint8_t, INT8_MIN, INT8_MAX)
> +
> +/* { dg-final { scan-rtl-dump-times ".SAT_ADD " 2 "expand" } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-6.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-6.c
> new file mode 100644
> index 00000000000..bc36ebe5187
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-6.c
> @@ -0,0 +1,32 @@
> +/* { 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_s_add_int16_t_fmt_2:
> +** add\s+[atx][0-9]+,\s*a0,\s*a1
> +** xor\s+[atx][0-9]+,\s*a0,\s*a1
> +** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+
> +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15
> +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15
> +** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
> +** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
> +** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63
> +** li\s+[atx][0-9]+,\s*32768
> +** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1
> +** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** neg\s+[atx][0-9]+,\s*[atx][0-9]+
> +** and\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+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** slliw\s+a0,\s*a0,\s*16
> +** sraiw\s+a0,\s*a0,\s*16
> +** ret
> +*/
> +DEF_SAT_S_ADD_FMT_2(int16_t, uint16_t, INT16_MIN, INT16_MAX)
> +
> +/* { dg-final { scan-rtl-dump-times ".SAT_ADD " 2 "expand" } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-7.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-7.c
> new file mode 100644
> index 00000000000..921d3c7c65a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-7.c
> @@ -0,0 +1,31 @@
> +/* { 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_s_add_int32_t_fmt_2:
> +** add\s+[atx][0-9]+,\s*a0,\s*a1
> +** xor\s+[atx][0-9]+,\s*a0,\s*a1
> +** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+
> +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31
> +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31
> +** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
> +** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
> +** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63
> +** li\s+[atx][0-9]+,\s*-2147483648
> +** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1
> +** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** neg\s+[atx][0-9]+,\s*[atx][0-9]+
> +** and\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+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** sext\.w\s+a0,\s*a0
> +** ret
> +*/
> +DEF_SAT_S_ADD_FMT_2(int32_t, uint32_t, INT32_MIN, INT32_MAX)
> +
> +/* { dg-final { scan-rtl-dump-times ".SAT_ADD " 2 "expand" } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-8.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-8.c
> new file mode 100644
> index 00000000000..4453b826fd0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-8.c
> @@ -0,0 +1,29 @@
> +/* { 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_s_add_int64_t_fmt_2:
> +** add\s+[atx][0-9]+,\s*a0,\s*a1
> +** xor\s+[atx][0-9]+,\s*a0,\s*a1
> +** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+
> +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63
> +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63
> +** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
> +** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63
> +** li\s+[atx][0-9]+,\s*-1
> +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
> +** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** neg\s+[atx][0-9]+,\s*[atx][0-9]+
> +** and\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+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
> +** ret
> +*/
> +DEF_SAT_S_ADD_FMT_2(int64_t, uint64_t, INT64_MIN, INT64_MAX)
> +
> +/* { dg-final { scan-rtl-dump-times ".SAT_ADD " 2 "expand" } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-run-5.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-5.c
> new file mode 100644
> index 00000000000..9a4ce338d0c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-5.c
> @@ -0,0 +1,16 @@
> +/* { dg-do run { target { riscv_v } } } */
> +/* { dg-additional-options "-std=c99" } */
> +
> +#include "sat_arith.h"
> +#include "sat_arith_data.h"
> +
> +#define T1 int8_t
> +#define T2 uint8_t
> +
> +DEF_SAT_S_ADD_FMT_1_WRAP(T1, T2, INT8_MIN, INT8_MAX)
> +
> +#define DATA             TEST_BINARY_DATA_WRAP(T1, ssadd)
> +#define T                TEST_BINARY_STRUCT_DECL(T1, ssadd)
> +#define RUN_BINARY(x, y) RUN_SAT_S_ADD_FMT_1_WRAP(T1, x, y)
> +
> +#include "scalar_sat_binary_run_xxx.h"
> diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-run-6.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-6.c
> new file mode 100644
> index 00000000000..34459b85e2b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-6.c
> @@ -0,0 +1,16 @@
> +/* { dg-do run { target { riscv_v } } } */
> +/* { dg-additional-options "-std=c99" } */
> +
> +#include "sat_arith.h"
> +#include "sat_arith_data.h"
> +
> +#define T1 int16_t
> +#define T2 uint16_t
> +
> +DEF_SAT_S_ADD_FMT_1_WRAP(T1, T2, INT16_MIN, INT16_MAX)
> +
> +#define DATA             TEST_BINARY_DATA_WRAP(T1, ssadd)
> +#define T                TEST_BINARY_STRUCT_DECL(T1, ssadd)
> +#define RUN_BINARY(x, y) RUN_SAT_S_ADD_FMT_1_WRAP(T1, x, y)
> +
> +#include "scalar_sat_binary_run_xxx.h"
> diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-run-7.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-7.c
> new file mode 100644
> index 00000000000..4d4841f4066
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-7.c
> @@ -0,0 +1,16 @@
> +/* { dg-do run { target { riscv_v } } } */
> +/* { dg-additional-options "-std=c99" } */
> +
> +#include "sat_arith.h"
> +#include "sat_arith_data.h"
> +
> +#define T1 int32_t
> +#define T2 uint32_t
> +
> +DEF_SAT_S_ADD_FMT_1_WRAP(T1, T2, INT32_MIN, INT32_MAX)
> +
> +#define DATA             TEST_BINARY_DATA_WRAP(T1, ssadd)
> +#define T                TEST_BINARY_STRUCT_DECL(T1, ssadd)
> +#define RUN_BINARY(x, y) RUN_SAT_S_ADD_FMT_1_WRAP(T1, x, y)
> +
> +#include "scalar_sat_binary_run_xxx.h"
> diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-run-8.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-8.c
> new file mode 100644
> index 00000000000..df818879628
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-8.c
> @@ -0,0 +1,16 @@
> +/* { dg-do run { target { riscv_v } } } */
> +/* { dg-additional-options "-std=c99" } */
> +
> +#include "sat_arith.h"
> +#include "sat_arith_data.h"
> +
> +#define T1 int64_t
> +#define T2 uint64_t
> +
> +DEF_SAT_S_ADD_FMT_1_WRAP(T1, T2, INT64_MIN, INT64_MAX)
> +
> +#define DATA             TEST_BINARY_DATA_WRAP(T1, ssadd)
> +#define T                TEST_BINARY_STRUCT_DECL(T1, ssadd)
> +#define RUN_BINARY(x, y) RUN_SAT_S_ADD_FMT_1_WRAP(T1, x, y)
> +
> +#include "scalar_sat_binary_run_xxx.h"
diff mbox series

Patch

diff --git a/gcc/testsuite/gcc.target/riscv/sat_arith.h b/gcc/testsuite/gcc.target/riscv/sat_arith.h
index a8672f66322..b4fbf5dc662 100644
--- a/gcc/testsuite/gcc.target/riscv/sat_arith.h
+++ b/gcc/testsuite/gcc.target/riscv/sat_arith.h
@@ -132,9 +132,22 @@  sat_s_add_##T##_fmt_1 (T x, T y)             \
 #define DEF_SAT_S_ADD_FMT_1_WRAP(T, UT, MIN, MAX) \
   DEF_SAT_S_ADD_FMT_1(T, UT, MIN, MAX)
 
+#define DEF_SAT_S_ADD_FMT_2(T, UT, MIN, MAX) \
+T __attribute__((noinline))                  \
+sat_s_add_##T##_fmt_2 (T x, T y)             \
+{                                            \
+  T sum = (UT)x + (UT)y;                     \
+  if ((x ^ y) < 0 || (sum ^ x) >= 0)         \
+    return sum;                              \
+  return x < 0 ? MIN : MAX;                  \
+}
+
 #define RUN_SAT_S_ADD_FMT_1(T, x, y) sat_s_add_##T##_fmt_1(x, y)
 #define RUN_SAT_S_ADD_FMT_1_WRAP(T, x, y) RUN_SAT_S_ADD_FMT_1(T, x, y)
 
+#define RUN_SAT_S_ADD_FMT_2(T, x, y) sat_s_add_##T##_fmt_2(x, y)
+#define RUN_SAT_S_ADD_FMT_2_WRAP(T, x, y) RUN_SAT_S_ADD_FMT_2(T, x, y)
+
 /******************************************************************************/
 /* Saturation Sub (Unsigned and Signed)                                       */
 /******************************************************************************/
diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-5.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-5.c
new file mode 100644
index 00000000000..b644022eb4e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-5.c
@@ -0,0 +1,30 @@ 
+/* { 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_s_add_int8_t_fmt_2:
+** add\s+[atx][0-9]+,\s*a0,\s*a1
+** xor\s+[atx][0-9]+,\s*a0,\s*a1
+** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*7
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*7
+** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
+** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
+** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
+** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63
+** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127
+** neg\s+[atx][0-9]+,\s*[atx][0-9]+
+** and\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+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
+** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
+** slliw\s+a0,\s*a0,\s*24
+** sraiw\s+a0,\s*a0,\s*24
+** ret
+*/
+DEF_SAT_S_ADD_FMT_2(int8_t, uint8_t, INT8_MIN, INT8_MAX)
+
+/* { dg-final { scan-rtl-dump-times ".SAT_ADD " 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-6.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-6.c
new file mode 100644
index 00000000000..bc36ebe5187
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-6.c
@@ -0,0 +1,32 @@ 
+/* { 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_s_add_int16_t_fmt_2:
+** add\s+[atx][0-9]+,\s*a0,\s*a1
+** xor\s+[atx][0-9]+,\s*a0,\s*a1
+** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15
+** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
+** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
+** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
+** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63
+** li\s+[atx][0-9]+,\s*32768
+** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1
+** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
+** neg\s+[atx][0-9]+,\s*[atx][0-9]+
+** and\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+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
+** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
+** slliw\s+a0,\s*a0,\s*16
+** sraiw\s+a0,\s*a0,\s*16
+** ret
+*/
+DEF_SAT_S_ADD_FMT_2(int16_t, uint16_t, INT16_MIN, INT16_MAX)
+
+/* { dg-final { scan-rtl-dump-times ".SAT_ADD " 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-7.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-7.c
new file mode 100644
index 00000000000..921d3c7c65a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-7.c
@@ -0,0 +1,31 @@ 
+/* { 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_s_add_int32_t_fmt_2:
+** add\s+[atx][0-9]+,\s*a0,\s*a1
+** xor\s+[atx][0-9]+,\s*a0,\s*a1
+** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31
+** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
+** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
+** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
+** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63
+** li\s+[atx][0-9]+,\s*-2147483648
+** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1
+** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
+** neg\s+[atx][0-9]+,\s*[atx][0-9]+
+** and\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+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
+** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
+** sext\.w\s+a0,\s*a0
+** ret
+*/
+DEF_SAT_S_ADD_FMT_2(int32_t, uint32_t, INT32_MIN, INT32_MAX)
+
+/* { dg-final { scan-rtl-dump-times ".SAT_ADD " 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-8.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-8.c
new file mode 100644
index 00000000000..4453b826fd0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-8.c
@@ -0,0 +1,29 @@ 
+/* { 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_s_add_int64_t_fmt_2:
+** add\s+[atx][0-9]+,\s*a0,\s*a1
+** xor\s+[atx][0-9]+,\s*a0,\s*a1
+** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63
+** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
+** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
+** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63
+** li\s+[atx][0-9]+,\s*-1
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
+** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
+** neg\s+[atx][0-9]+,\s*[atx][0-9]+
+** and\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+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
+** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
+** ret
+*/
+DEF_SAT_S_ADD_FMT_2(int64_t, uint64_t, INT64_MIN, INT64_MAX)
+
+/* { dg-final { scan-rtl-dump-times ".SAT_ADD " 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-run-5.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-5.c
new file mode 100644
index 00000000000..9a4ce338d0c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-5.c
@@ -0,0 +1,16 @@ 
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+#include "sat_arith_data.h"
+
+#define T1 int8_t
+#define T2 uint8_t
+
+DEF_SAT_S_ADD_FMT_1_WRAP(T1, T2, INT8_MIN, INT8_MAX)
+
+#define DATA             TEST_BINARY_DATA_WRAP(T1, ssadd)
+#define T                TEST_BINARY_STRUCT_DECL(T1, ssadd)
+#define RUN_BINARY(x, y) RUN_SAT_S_ADD_FMT_1_WRAP(T1, x, y)
+
+#include "scalar_sat_binary_run_xxx.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-run-6.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-6.c
new file mode 100644
index 00000000000..34459b85e2b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-6.c
@@ -0,0 +1,16 @@ 
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+#include "sat_arith_data.h"
+
+#define T1 int16_t
+#define T2 uint16_t
+
+DEF_SAT_S_ADD_FMT_1_WRAP(T1, T2, INT16_MIN, INT16_MAX)
+
+#define DATA             TEST_BINARY_DATA_WRAP(T1, ssadd)
+#define T                TEST_BINARY_STRUCT_DECL(T1, ssadd)
+#define RUN_BINARY(x, y) RUN_SAT_S_ADD_FMT_1_WRAP(T1, x, y)
+
+#include "scalar_sat_binary_run_xxx.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-run-7.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-7.c
new file mode 100644
index 00000000000..4d4841f4066
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-7.c
@@ -0,0 +1,16 @@ 
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+#include "sat_arith_data.h"
+
+#define T1 int32_t
+#define T2 uint32_t
+
+DEF_SAT_S_ADD_FMT_1_WRAP(T1, T2, INT32_MIN, INT32_MAX)
+
+#define DATA             TEST_BINARY_DATA_WRAP(T1, ssadd)
+#define T                TEST_BINARY_STRUCT_DECL(T1, ssadd)
+#define RUN_BINARY(x, y) RUN_SAT_S_ADD_FMT_1_WRAP(T1, x, y)
+
+#include "scalar_sat_binary_run_xxx.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-run-8.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-8.c
new file mode 100644
index 00000000000..df818879628
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-8.c
@@ -0,0 +1,16 @@ 
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+#include "sat_arith_data.h"
+
+#define T1 int64_t
+#define T2 uint64_t
+
+DEF_SAT_S_ADD_FMT_1_WRAP(T1, T2, INT64_MIN, INT64_MAX)
+
+#define DATA             TEST_BINARY_DATA_WRAP(T1, ssadd)
+#define T                TEST_BINARY_STRUCT_DECL(T1, ssadd)
+#define RUN_BINARY(x, y) RUN_SAT_S_ADD_FMT_1_WRAP(T1, x, y)
+
+#include "scalar_sat_binary_run_xxx.h"