aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.target/riscv
diff options
context:
space:
mode:
authorPan Li <pan2.li@intel.com>2025-01-23 14:28:39 +0800
committerPan Li <pan2.li@intel.com>2025-01-29 17:36:52 +0800
commit5a48079c15fda4863b02eb253e473c57a5105528 (patch)
treec8ffdb46d9c1bd1cf3f8e4444939c619b7d7c795 /gcc/testsuite/gcc.target/riscv
parentbfb57d62c743235284f9b31a88c6ceed9971d27a (diff)
downloadgcc-5a48079c15fda4863b02eb253e473c57a5105528.zip
gcc-5a48079c15fda4863b02eb253e473c57a5105528.tar.gz
gcc-5a48079c15fda4863b02eb253e473c57a5105528.tar.bz2
RISC-V: Fix incorrect code gen for scalar signed SAT_TRUNC [PR117688]
This patch would like to fix the wroing code generation for the scalar signed SAT_TRUNC. The input can be QI/HI/SI/DI while the alu like sub can only work on Xmode. Unfortunately we don't have sub/add for non-Xmode like QImode in scalar, thus we need to sign extend to Xmode to ensure we have the correct value before ALU like add. The gen_lowpart will generate something like lbu which has all zero for highest bits. For example, when 0xff7f(-129 for HImode) trunc to QImode, we actually want compare -129 to -128, but if there is no sign extend like lbu, we will compare 0xff7f to 0xffffffffffffff80(assum Xmode is DImode). Thus, we have to sign extend 0xff(Qmode) to 0xffffffffffffff7f(assume Xmode is DImode) before compare in Xmode. The below test suites are passed for this patch. * The rv64gcv fully regression test. PR target/117688 gcc/ChangeLog: * config/riscv/riscv.cc (riscv_expand_sstrunc): Leverage the helper riscv_extend_to_xmode_reg with SIGN_EXTEND. gcc/testsuite/ChangeLog: * gcc.target/riscv/pr117688.h: Add test helper macros. * gcc.target/riscv/pr117688-trunc-run-1-s16-to-s8.c: New test. * gcc.target/riscv/pr117688-trunc-run-1-s32-to-s16.c: New test. * gcc.target/riscv/pr117688-trunc-run-1-s32-to-s8.c: New test. * gcc.target/riscv/pr117688-trunc-run-1-s64-to-s16.c: New test. * gcc.target/riscv/pr117688-trunc-run-1-s64-to-s32.c: New test. * gcc.target/riscv/pr117688-trunc-run-1-s64-to-s8.c: New test. Signed-off-by: Pan Li <pan2.li@intel.com>
Diffstat (limited to 'gcc/testsuite/gcc.target/riscv')
-rw-r--r--gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s16-to-s8.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s32-to-s16.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s32-to-s8.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s64-to-s16.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s64-to-s32.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s64-to-s8.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/pr117688.h22
7 files changed, 58 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s16-to-s8.c b/gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s16-to-s8.c
new file mode 100644
index 0000000..df84615
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s16-to-s8.c
@@ -0,0 +1,6 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "pr117688.h"
+
+DEFINE_SIGNED_SAT_TRUNC_RUN(int16_t, int8_t, INT8_MIN, INT8_MAX)
diff --git a/gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s32-to-s16.c b/gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s32-to-s16.c
new file mode 100644
index 0000000..1b0f860
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s32-to-s16.c
@@ -0,0 +1,6 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "pr117688.h"
+
+DEFINE_SIGNED_SAT_TRUNC_RUN(int32_t, int16_t, INT16_MIN, INT16_MAX)
diff --git a/gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s32-to-s8.c b/gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s32-to-s8.c
new file mode 100644
index 0000000..e412a29
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s32-to-s8.c
@@ -0,0 +1,6 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "pr117688.h"
+
+DEFINE_SIGNED_SAT_TRUNC_RUN(int32_t, int8_t, INT8_MIN, INT8_MAX)
diff --git a/gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s64-to-s16.c b/gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s64-to-s16.c
new file mode 100644
index 0000000..234d33b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s64-to-s16.c
@@ -0,0 +1,6 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "pr117688.h"
+
+DEFINE_SIGNED_SAT_TRUNC_RUN(int64_t, int16_t, INT16_MIN, INT16_MAX)
diff --git a/gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s64-to-s32.c b/gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s64-to-s32.c
new file mode 100644
index 0000000..5f9e7f5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s64-to-s32.c
@@ -0,0 +1,6 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "pr117688.h"
+
+DEFINE_SIGNED_SAT_TRUNC_RUN(int64_t, int32_t, INT32_MIN, INT32_MAX)
diff --git a/gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s64-to-s8.c b/gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s64-to-s8.c
new file mode 100644
index 0000000..aae6be9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr117688-trunc-run-1-s64-to-s8.c
@@ -0,0 +1,6 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "pr117688.h"
+
+DEFINE_SIGNED_SAT_TRUNC_RUN(int64_t, int8_t, INT8_MIN, INT8_MAX)
diff --git a/gcc/testsuite/gcc.target/riscv/pr117688.h b/gcc/testsuite/gcc.target/riscv/pr117688.h
index 3b734ce..7621021 100644
--- a/gcc/testsuite/gcc.target/riscv/pr117688.h
+++ b/gcc/testsuite/gcc.target/riscv/pr117688.h
@@ -45,4 +45,26 @@
return 0; \
}
+#define DEFINE_SIGNED_SAT_TRUNC_RUN(WT, NT, NT_MIN, NT_MAX) \
+ WT x; \
+ NT result; \
+ \
+ __attribute__ ((noipa)) void \
+ foo () \
+ { \
+ NT trunc = (NT)x; \
+ result = (WT)NT_MIN <= x && x <= (WT)NT_MAX \
+ ? trunc \
+ : x < 0 ? NT_MIN : NT_MAX; \
+ } \
+ \
+ int main () \
+ { \
+ x = (WT)NT_MIN - 1 ; \
+ foo(); \
+ if (result != (NT)NT_MIN) \
+ __builtin_abort (); \
+ return 0; \
+ }
+
#endif