===================================================================
@@ -4705,6 +4705,23 @@ expand_assignment (tree to, tree from, b
to_rtx = adjust_address (to_rtx, mode1, 0);
else if (GET_MODE (to_rtx) == VOIDmode)
to_rtx = adjust_address (to_rtx, BLKmode, 0);
+ /* If we have a bitfield access and the alignment of the
+ accessed object is larger than what its type would require
+ restrict the mode we use for accesses to avoid touching
+ the tail alignment-padding. See PR48124. */
+ else if (mode1 == VOIDmode
+ && TREE_CODE (to) == COMPONENT_REF
+ && TYPE_ALIGN (TREE_TYPE (tem)) < MEM_ALIGN (to_rtx))
+ {
+ mode1 = mode_for_size (TYPE_ALIGN (TREE_TYPE (tem)),
MODE_INT, 1);
+ if (mode1 == BLKmode
+ /* Not larger than word_mode. */
+ || GET_MODE_SIZE (mode1) > GET_MODE_SIZE (word_mode)
+ /* Nor smaller than the fields mode. */
+ || (GET_MODE_SIZE (mode1)
+ < GET_MODE_SIZE (DECL_MODE (TREE_OPERAND (to, 1)))))
+ mode1 = VOIDmode;
+ }
}