@@ -11801,6 +11801,23 @@ riscv_get_raw_result_mode (int regno)
return default_get_reg_raw_mode (regno);
}
+/* Generate a new rtx of Xmode based on the rtx and mode in define pattern.
+ The rtx x will be zero extended to Xmode if the mode is HI/QImode, and
+ the new zero extended Xmode rtx will be returned.
+ Or the gen_lowpart rtx of Xmode will be returned. */
+
+static rtx
+riscv_gen_zero_extend_rtx (rtx x, machine_mode mode)
+{
+ if (mode != HImode && mode != QImode)
+ return gen_lowpart (Xmode, x);
+
+ rtx xmode_reg = gen_reg_rtx (Xmode);
+ riscv_emit_unary (ZERO_EXTEND, xmode_reg, x);
+
+ return xmode_reg;
+}
+
/* Implements the unsigned saturation add standard name usadd for int mode.
z = SAT_ADD(x, y).
@@ -11817,7 +11834,7 @@ riscv_expand_usadd (rtx dest, rtx x, rtx y)
machine_mode mode = GET_MODE (dest);
rtx xmode_sum = gen_reg_rtx (Xmode);
rtx xmode_lt = gen_reg_rtx (Xmode);
- rtx xmode_x = gen_lowpart (Xmode, x);
+ rtx xmode_x = riscv_gen_zero_extend_rtx (x, mode);
rtx xmode_y = gen_lowpart (Xmode, y);
rtx xmode_dest = gen_reg_rtx (Xmode);
new file mode 100644
@@ -0,0 +1,20 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-options "-O2 -fdump-rtl-expand-details" } */
+
+#include <stdint-gcc.h>
+
+int8_t b[1];
+int8_t *d = b;
+int32_t c;
+
+int main() {
+ b[0] = -40;
+ uint16_t t = (uint16_t)d[0];
+
+ c = (t < 0xFFF6 ? t : 0xFFF6) + 9;
+
+ if (c != 65505)
+ __builtin_abort ();
+}
+
+/* { dg-final { scan-rtl-dump-times ".SAT_ADD " 2 "expand" } } */
new file mode 100644
@@ -0,0 +1,20 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-options "-O2 -fdump-rtl-expand-details" } */
+
+#include <stdint-gcc.h>
+
+int16_t b[1];
+int16_t *d = b;
+int64_t c;
+
+int main() {
+ b[0] = -40;
+ uint32_t t = (uint32_t)d[0];
+
+ c = (t < 0xFFFFFFF6u ? t : 0xFFFFFFF6u) + 9;
+
+ if (c != 4294967265)
+ __builtin_abort ();
+}
+
+/* { dg-final { scan-rtl-dump-times ".SAT_ADD " 2 "expand" } } */