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);
--- /dev/null
+/* { 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)
--- /dev/null
+/* { 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)
--- /dev/null
+/* { 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)
--- /dev/null
+/* { 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)
--- /dev/null
+#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