https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79209
--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- On x86_64 expansion is fine: ;; MEM[(volatile struct s0_t *)4B].y ={v} 1; (insn 5 4 6 (set (reg/f:DI 89) (const_int 4 [0x4])) "t.c":58 -1 (nil)) (insn 6 5 8 (set (reg:SI 90) (mem/v/j:SI (reg/f:DI 89) [0 +0 S4 A32])) "t.c":58 -1 (nil)) (insn 8 6 9 (parallel [ (set (reg:SI 92) (ior:SI (reg:SI 90) (const_int 1 [0x1]))) (clobber (reg:CC 17 flags)) ]) "t.c":58 -1 (nil)) (insn 9 8 10 (set (reg:SI 90) (reg:SI 92)) "t.c":58 -1 (nil)) (insn 10 9 0 (set (mem/v/j:SI (reg/f:DI 89) [0 +0 S4 A32]) (reg:SI 90)) "t.c":58 -1 (nil)) For the non-inlined case we run into static bool strict_volatile_bitfield_p (rtx op0, unsigned HOST_WIDE_INT bitsize, unsigned HOST_WIDE_INT bitnum, machine_mode fieldmode, unsigned HOST_WIDE_INT bitregion_start, unsigned HOST_WIDE_INT bitregion_end) ... /* The memory must be sufficiently aligned for a MODESIZE access. This condition guarantees, that the memory access will not touch anything after the end of the structure. */ if (MEM_ALIGN (op0) < modesize) return false; and thus get byte accesses forced. Thus you indeed need properly aligned bitfields for correctness reasons (in theory it could look at the bitregion to see if the access is allowed -- wouldn't help this testcase though).