https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88963
--- Comment #11 from Richard Biener <rguenth at gcc dot gnu.org> --- The issue RTL expansion spills is the inner MEM_REF is expanded to (mem:BLK (reg/v/f:DI 88 [ a ]) [1 *a_7(D)+0 S64 A256]) and somehow if (MEM_P (to_rtx)) { /* If the field is at offset zero, we could have been given the DECL_RTX of the parent struct. Don't munge it. */ to_rtx = shallow_copy_rtx (to_rtx); set_mem_attributes_minus_bitpos (to_rtx, to, 0, bitpos); if (volatilep) doesn't transfer the smaller mode of the BIT_FIELD_REF to to_rtx. It might be that we can use TYPE_MODE (TREE_TYPE (to)) in place of mode1 here: gcc_checking_assert (known_ge (bitpos, 0)); if (optimize_bitfield_assignment_op (bitsize, bitpos, bitregion_start, bitregion_end, mode1, to_rtx, to, from, reversep)) result = NULL; else result = store_field (to_rtx, bitsize, bitpos, bitregion_start, bitregion_end, mode1, from, get_alias_set (to), nontemporal, reversep); similar to how expand_expr tries to do that for bitfield extraction. Otherwise the code has no idea it should use vector stores when later running into store_bit_field_1 with a VOIDmode fieldmode where it ends up doing store_integral_bit_field.