[v3,2/4] RISC-V: Fix incorrect code gen for scalar signed SAT_ADD [PR117688]
Checks
Context |
Check |
Description |
rivoscibot/toolchain-ci-rivos-lint |
success
|
Lint passed
|
rivoscibot/toolchain-ci-rivos-apply-patch |
success
|
Patch applied
|
rivoscibot/toolchain-ci-rivos-build--linux-rv64gc_zba_zbb_zbc_zbs-lp64d-multilib |
success
|
Build passed
|
rivoscibot/toolchain-ci-rivos-build--newlib-rv64gcv-lp64d-multilib |
success
|
Build passed
|
rivoscibot/toolchain-ci-rivos-build--linux-rv64gcv-lp64d-multilib |
success
|
Build passed
|
rivoscibot/toolchain-ci-rivos-test |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gcc_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 |
success
|
Test passed
|
linaro-tcwg-bot/tcwg_gcc_check--master-arm |
success
|
Test passed
|
Commit Message
From: Pan Li <pan2.li@intel.com>
This patch would like to fix the wroing code generation for the scalar
signed SAT_ADD. 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 0xff(-1 for QImode) plus 0x2(1 for QImode), we actually
want to -1 + 2 = 1, but if there is no sign extend like lbu, we will get
0xff + 2 = 0x101 which is incorrect. Thus, we have to sign extend 0xff(Qmode)
to 0xffffffffffffffff(assume XImode is DImode) before plus 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_ssadd): Leverage the helper
riscv_extend_to_xmode_reg with SIGN_EXTEND.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/pr117688-add-run-1-s16.c: New test.
* gcc.target/riscv/pr117688-add-run-1-s32.c: New test.
* gcc.target/riscv/pr117688-add-run-1-s64.c: New test.
* gcc.target/riscv/pr117688-add-run-1-s8.c: New test.
* gcc.target/riscv/pr117688.h: New test.
Signed-off-by: Pan Li <pan2.li@intel.com>
---
gcc/config/riscv/riscv.cc | 4 +--
.../gcc.target/riscv/pr117688-add-run-1-s16.c | 6 +++++
.../gcc.target/riscv/pr117688-add-run-1-s32.c | 6 +++++
.../gcc.target/riscv/pr117688-add-run-1-s64.c | 6 +++++
.../gcc.target/riscv/pr117688-add-run-1-s8.c | 6 +++++
gcc/testsuite/gcc.target/riscv/pr117688.h | 27 +++++++++++++++++++
6 files changed, 53 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/pr117688-add-run-1-s16.c
create mode 100644 gcc/testsuite/gcc.target/riscv/pr117688-add-run-1-s32.c
create mode 100644 gcc/testsuite/gcc.target/riscv/pr117688-add-run-1-s64.c
create mode 100644 gcc/testsuite/gcc.target/riscv/pr117688-add-run-1-s8.c
create mode 100644 gcc/testsuite/gcc.target/riscv/pr117688.h
@@ -12815,8 +12815,8 @@ riscv_expand_ssadd (rtx dest, rtx x, rtx y)
machine_mode mode = GET_MODE (dest);
unsigned bitsize = GET_MODE_BITSIZE (mode).to_constant ();
rtx shift_bits = GEN_INT (bitsize - 1);
- rtx xmode_x = gen_lowpart (Xmode, x);
- rtx xmode_y = gen_lowpart (Xmode, y);
+ rtx xmode_x = riscv_extend_to_xmode_reg (x, mode, SIGN_EXTEND);
+ rtx xmode_y = riscv_extend_to_xmode_reg (y, mode, SIGN_EXTEND);
rtx xmode_sum = gen_reg_rtx (Xmode);
rtx xmode_dest = gen_reg_rtx (Xmode);
rtx xmode_xor_0 = gen_reg_rtx (Xmode);
new file mode 100644
@@ -0,0 +1,6 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "pr117688.h"
+
+DEFINE_SIGNED_SAT_ADD_RUN(int16_t, INT16_MIN, INT16_MAX)
new file mode 100644
@@ -0,0 +1,6 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "pr117688.h"
+
+DEFINE_SIGNED_SAT_ADD_RUN(int32_t, INT32_MIN, INT32_MAX)
new file mode 100644
@@ -0,0 +1,6 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "pr117688.h"
+
+DEFINE_SIGNED_SAT_ADD_RUN(int64_t, INT64_MIN, INT64_MAX)
new file mode 100644
@@ -0,0 +1,6 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "pr117688.h"
+
+DEFINE_SIGNED_SAT_ADD_RUN(int8_t, INT8_MIN, INT8_MAX)
new file mode 100644
@@ -0,0 +1,27 @@
+#ifndef HAVE_DEFINED_PR117688_H
+#define HAVE_DEFINED_PR117688_H
+
+#include <stdint.h>
+
+#define DEFINE_SIGNED_SAT_ADD_RUN(T, MIN, MAX) \
+ T x, y, result; \
+ \
+ __attribute__ ((noipa)) void \
+ foo () \
+ { \
+ T sum; \
+ _Bool overflow = __builtin_add_overflow (x, y, &sum); \
+ result = overflow ? (x < 0 ? MIN : MAX) : sum; \
+ } \
+ \
+ int main () \
+ { \
+ x = MIN; \
+ y = -0x1; \
+ foo(); \
+ if (result != (T)MIN) \
+ __builtin_abort (); \
+ return 0; \
+ }
+
+#endif