https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104914

--- Comment #14 from YunQiang Su <syq at gcc dot gnu.org> ---
New patch:

diff --git a/gcc/expmed.cc b/gcc/expmed.cc
index fbd4ce2d42f..66d45da67df 100644
--- a/gcc/expmed.cc
+++ b/gcc/expmed.cc
@@ -850,6 +850,7 @@ store_bit_field_1 (rtx str_rtx, poly_uint64 bitsize,
poly_uint64 bitnum,
      since that case is valid for any mode.  The following cases are only
      valid for integral modes.  */
   opt_scalar_int_mode op0_mode = int_mode_for_mode (GET_MODE (op0));
+  opt_scalar_int_mode str_mode = int_mode_for_mode (GET_MODE (str_rtx));
   scalar_int_mode imode;
   if (!op0_mode.exists (&imode) || imode != GET_MODE (op0))
     {
@@ -881,8 +882,15 @@ store_bit_field_1 (rtx str_rtx, poly_uint64 bitsize,
poly_uint64 bitnum,
        op0 = gen_lowpart (op0_mode.require (), op0);
     }

-  return store_integral_bit_field (op0, op0_mode, ibitsize, ibitnum,
-                                  bitregion_start, bitregion_end,
+  bool use_str_mode = false;
+  if (GET_MODE_CLASS(GET_MODE (str_rtx)) == MODE_INT
+      && GET_MODE_CLASS(GET_MODE (op0)) == MODE_INT
+      && known_gt (GET_MODE_SIZE(GET_MODE(op0)),
GET_MODE_SIZE(GET_MODE(str_rtx))))
+    use_str_mode = true;
+
+  return store_integral_bit_field (use_str_mode ? str_rtx : op0,
+                                  use_str_mode ? str_mode : op0_mode,
+                                  ibitsize, ibitnum, bitregion_start,
bitregion_end,
                                   fieldmode, value, reverse, fallback_p);
 }

Reply via email to