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); }