diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 5fe4273beb7..fb916217e5e 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -11564,6 +11564,24 @@ riscv_get_raw_result_mode (int regno)
   return default_get_reg_raw_mode (regno);
 }
 
+/* Cleanup the high bits of the RTX x and reserve the low bits.
+   The reserved bitsize comes from the bitsize of reserved_mode.  */
+
+static void
+riscv_cleanup_rtx_high (rtx x, machine_mode reserved_mode)
+{
+  machine_mode mode = GET_MODE (x);
+  int reserved_bitsize = GET_MODE_BITSIZE (reserved_mode).to_constant ();
+  int mode_bitsize = GET_MODE_BITSIZE (mode).to_constant ();
+
+  gcc_assert (mode_bitsize >= reserved_bitsize);
+
+  int shift_bitsize = mode_bitsize - reserved_bitsize;
+
+  riscv_emit_binary (ASHIFT, x, x, GEN_INT (shift_bitsize));
+  riscv_emit_binary (LSHIFTRT, x, x, GEN_INT (shift_bitsize));
+}
+
 /* Implements the unsigned saturation add standard name usadd for int mode.
 
    z = SAT_ADD(x, y).
@@ -11594,16 +11612,12 @@ riscv_expand_usadd (rtx dest, rtx x, rtx y)
   else
     riscv_emit_binary (PLUS, xmode_sum, xmode_x, xmode_y);
 
-  /* Step-1.1: truncate sum for HI and QI as we have no insn for add QI/HI.  */
+  /* Step-1.1: truncate sum for HI and QI as we have no insn for add QI/HI.
+	       truncate x for HI and QI as it may be sign-extended.  */
   if (mode == HImode || mode == QImode)
     {
-      int shift_bits = GET_MODE_BITSIZE (Xmode)
-	- GET_MODE_BITSIZE (mode).to_constant ();
-
-      gcc_assert (shift_bits > 0);
-
-      riscv_emit_binary (ASHIFT, xmode_sum, xmode_sum, GEN_INT (shift_bits));
-      riscv_emit_binary (LSHIFTRT, xmode_sum, xmode_sum, GEN_INT (shift_bits));
+      riscv_cleanup_rtx_high (xmode_sum, mode);
+      riscv_cleanup_rtx_high (xmode_x, mode);
     }
 
   /* Step-2: lt = sum < x  */
diff --git a/gcc/testsuite/gcc.target/riscv/pr116278-run-1.c b/gcc/testsuite/gcc.target/riscv/pr116278-run-1.c
new file mode 100644
index 00000000000..f6268e290ec
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr116278-run-1.c
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+signed char b[1];
+int c;
+signed char *d = b;
+
+int main() {
+  b[0] = -40;
+  c = ({
+    (unsigned short)d[0] < 0xFFF6 ? (unsigned short)d[0] : 0xFFF6;
+  }) + 9;
+
+  if (c != 65505)
+    __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_add-1.c b/gcc/testsuite/gcc.target/riscv/sat_u_add-1.c
index 609e1ea343b..c1951004ed1 100644
--- a/gcc/testsuite/gcc.target/riscv/sat_u_add-1.c
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_add-1.c
@@ -8,6 +8,7 @@
 ** sat_u_add_uint8_t_fmt_1:
 ** add\s+[atx][0-9]+,\s*a0,\s*a1
 ** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff
+** andi\s+a0,\s*a0,\s*0xff
 ** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
 ** neg\s+[atx][0-9]+,\s*[atx][0-9]+
 ** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_add-10.c b/gcc/testsuite/gcc.target/riscv/sat_u_add-10.c
index 3f627ef80b1..b9b756294a8 100644
--- a/gcc/testsuite/gcc.target/riscv/sat_u_add-10.c
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_add-10.c
@@ -9,6 +9,8 @@
 ** add\s+[atx][0-9]+,\s*a0,\s*a1
 ** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48
 ** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48
+** slli\s+a0,\s*a0+,\s*48
+** srli\s+a0,\s*a0+,\s*48
 ** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
 ** neg\s+[atx][0-9]+,\s*[atx][0-9]+
 ** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_add-13.c b/gcc/testsuite/gcc.target/riscv/sat_u_add-13.c
index b2d93f29f48..87334732573 100644
--- a/gcc/testsuite/gcc.target/riscv/sat_u_add-13.c
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_add-13.c
@@ -8,6 +8,7 @@
 ** sat_u_add_uint8_t_fmt_4:
 ** add\s+[atx][0-9]+,\s*a0,\s*a1
 ** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff
+** andi\s+a0,\s*a0,\s*0xff
 ** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
 ** neg\s+[atx][0-9]+,\s*[atx][0-9]+
 ** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_add-14.c b/gcc/testsuite/gcc.target/riscv/sat_u_add-14.c
index eafc578aafa..993c332a462 100644
--- a/gcc/testsuite/gcc.target/riscv/sat_u_add-14.c
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_add-14.c
@@ -9,6 +9,8 @@
 ** add\s+[atx][0-9]+,\s*a0,\s*a1
 ** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48
 ** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48
+** slli\s+a0,\s*a0,\s*48
+** srli\s+a0,\s*a0,\s*48
 ** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
 ** neg\s+[atx][0-9]+,\s*[atx][0-9]+
 ** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_add-17.c b/gcc/testsuite/gcc.target/riscv/sat_u_add-17.c
index 7085ac835f7..d71faf08f32 100644
--- a/gcc/testsuite/gcc.target/riscv/sat_u_add-17.c
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_add-17.c
@@ -8,6 +8,7 @@
 ** sat_u_add_uint8_t_fmt_5:
 ** add\s+[atx][0-9]+,\s*a0,\s*a1
 ** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff
+** andi\s+a0,\s*a0+,\s*0xff
 ** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
 ** neg\s+[atx][0-9]+,\s*[atx][0-9]+
 ** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_add-18.c b/gcc/testsuite/gcc.target/riscv/sat_u_add-18.c
index 355ff8ba4ef..6ebc12cf10d 100644
--- a/gcc/testsuite/gcc.target/riscv/sat_u_add-18.c
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_add-18.c
@@ -9,6 +9,8 @@
 ** add\s+[atx][0-9]+,\s*a0,\s*a1
 ** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48
 ** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48
+** slli\s+a0,\s*a0+,\s*48
+** srli\s+a0,\s*a0+,\s*48
 ** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
 ** neg\s+[atx][0-9]+,\s*[atx][0-9]+
 ** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_add-2.c b/gcc/testsuite/gcc.target/riscv/sat_u_add-2.c
index d30436c782a..bdc1591214e 100644
--- a/gcc/testsuite/gcc.target/riscv/sat_u_add-2.c
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_add-2.c
@@ -9,6 +9,8 @@
 ** add\s+[atx][0-9]+,\s*a0,\s*a1
 ** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48
 ** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48
+** slli\s+a0,\s*a0+,\s*48
+** srli\s+a0,\s*a0+,\s*48
 ** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
 ** neg\s+[atx][0-9]+,\s*[atx][0-9]+
 ** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_add-21.c b/gcc/testsuite/gcc.target/riscv/sat_u_add-21.c
index f75e35a5fa9..543a0436663 100644
--- a/gcc/testsuite/gcc.target/riscv/sat_u_add-21.c
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_add-21.c
@@ -8,6 +8,7 @@
 ** sat_u_add_uint8_t_fmt_6:
 ** add\s+[atx][0-9]+,\s*a0,\s*a1
 ** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff
+** andi\s+a0,\s*a0,\s*0xff
 ** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
 ** neg\s+[atx][0-9]+,\s*[atx][0-9]+
 ** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_add-22.c b/gcc/testsuite/gcc.target/riscv/sat_u_add-22.c
index ad957a061f4..2db186f86b0 100644
--- a/gcc/testsuite/gcc.target/riscv/sat_u_add-22.c
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_add-22.c
@@ -9,6 +9,8 @@
 ** add\s+[atx][0-9]+,\s*a0,\s*a1
 ** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48
 ** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48
+** slli\s+a0,\s*a0+,\s*48
+** srli\s+a0,\s*a0+,\s*48
 ** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
 ** neg\s+[atx][0-9]+,\s*[atx][0-9]+
 ** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_add-5.c b/gcc/testsuite/gcc.target/riscv/sat_u_add-5.c
index 4c73c7f8a21..0e487257dbb 100644
--- a/gcc/testsuite/gcc.target/riscv/sat_u_add-5.c
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_add-5.c
@@ -8,6 +8,7 @@
 ** sat_u_add_uint8_t_fmt_2:
 ** add\s+[atx][0-9]+,\s*a0,\s*a1
 ** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff
+** andi\s+a0,\s*a0,\s*0xff
 ** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
 ** neg\s+[atx][0-9]+,\s*[atx][0-9]+
 ** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_add-6.c b/gcc/testsuite/gcc.target/riscv/sat_u_add-6.c
index 0d64f5631bb..f47398459f9 100644
--- a/gcc/testsuite/gcc.target/riscv/sat_u_add-6.c
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_add-6.c
@@ -9,6 +9,8 @@
 ** add\s+[atx][0-9]+,\s*a0,\s*a1
 ** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48
 ** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48
+** slli\s+a0,\s*a0+,\s*48
+** srli\s+a0,\s*a0+,\s*48
 ** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
 ** neg\s+[atx][0-9]+,\s*[atx][0-9]+
 ** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_add-9.c b/gcc/testsuite/gcc.target/riscv/sat_u_add-9.c
index eac6707a407..082b4b0bd4d 100644
--- a/gcc/testsuite/gcc.target/riscv/sat_u_add-9.c
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_add-9.c
@@ -8,6 +8,7 @@
 ** sat_u_add_uint8_t_fmt_3:
 ** add\s+[atx][0-9]+,\s*a0,\s*a1
 ** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff
+** andi\s+a0,\s*a0,\s*0xff
 ** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
 ** neg\s+[atx][0-9]+,\s*[atx][0-9]+
 ** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-1.c b/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-1.c
index 14e9b7595a8..edaa86f69aa 100644
--- a/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-1.c
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-1.c
@@ -8,6 +8,7 @@
 ** sat_u_add_imm9_uint8_t_fmt_1:
 ** addi\s+[atx][0-9]+,\s*a0,\s*9
 ** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff
+** andi\s+a0,\s*a0,\s*0xff
 ** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
 ** neg\s+[atx][0-9]+,\s*[atx][0-9]+
 ** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-10.c b/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-10.c
index 24cdd267cca..84cc521c1d3 100644
--- a/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-10.c
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-10.c
@@ -9,6 +9,8 @@
 ** addi\s+[atx][0-9]+,\s*a0,\s*3
 ** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48
 ** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48
+** slli\s+a0,\s*a0,\s*48
+** srli\s+a0,\s*a0,\s*48
 ** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
 ** neg\s+[atx][0-9]+,\s*[atx][0-9]+
 ** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-13.c b/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-13.c
index a3b2679233c..3f8f59eb8cd 100644
--- a/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-13.c
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-13.c
@@ -8,6 +8,7 @@
 ** sat_u_add_imm9_uint8_t_fmt_4:
 ** addi\s+[atx][0-9]+,\s*a0,\s*9
 ** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff
+** andi\s+a0,\s*a0,\s*0xff
 ** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
 ** neg\s+[atx][0-9]+,\s*[atx][0-9]+
 ** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-14.c b/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-14.c
index 968534b74da..3e7dc0a3c4c 100644
--- a/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-14.c
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-14.c
@@ -9,6 +9,8 @@
 ** addi\s+[atx][0-9]+,\s*a0,\s*3
 ** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48
 ** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48
+** slli\s+a0,\s*a0,\s*48
+** srli\s+a0,\s*a0,\s*48
 ** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
 ** neg\s+[atx][0-9]+,\s*[atx][0-9]+
 ** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-2.c b/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-2.c
index c1a3c6ff21d..7232a37d9c5 100644
--- a/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-2.c
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-2.c
@@ -9,6 +9,8 @@
 ** addi\s+[atx][0-9]+,\s*a0,\s*3
 ** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48
 ** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48
+** slli\s+a0,\s*a0,\s*48
+** srli\s+a0,\s*a0,\s*48
 ** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
 ** neg\s+[atx][0-9]+,\s*[atx][0-9]+
 ** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-5.c b/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-5.c
index 19b502db6c9..522afaf481f 100644
--- a/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-5.c
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-5.c
@@ -8,6 +8,7 @@
 ** sat_u_add_imm9_uint8_t_fmt_2:
 ** addi\s+[atx][0-9]+,\s*a0,\s*9
 ** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff
+** andi\s+a0,\s*a0,\s*0xff
 ** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
 ** neg\s+[atx][0-9]+,\s*[atx][0-9]+
 ** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-6.c b/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-6.c
index 0317370b67e..12b7bfe3a70 100644
--- a/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-6.c
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-6.c
@@ -9,6 +9,8 @@
 ** addi\s+[atx][0-9]+,\s*a0,\s*3
 ** slli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48
 ** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*48
+** slli\s+a0,\s*a0,\s*48
+** srli\s+a0,\s*a0,\s*48
 ** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
 ** neg\s+[atx][0-9]+,\s*[atx][0-9]+
 ** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-9.c b/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-9.c
index 5fcd6d71a26..e53a459c021 100644
--- a/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-9.c
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_add_imm-9.c
@@ -8,6 +8,7 @@
 ** sat_u_add_imm9_uint8_t_fmt_3:
 ** addi\s+[atx][0-9]+,\s*a0,\s*9
 ** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*0xff
+** andi\s+a0,\s*a0,\s*0xff
 ** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
 ** neg\s+[atx][0-9]+,\s*[atx][0-9]+
 ** or\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
