http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52419
--- Comment #4 from Richard Guenther <rguenth at gcc dot gnu.org> 2012-02-29 13:46:01 UTC --- We are not prepared to handle bitsize != GET_MODE_BITSIZE in expand_assignment for the movmisalign case. The following fixes it Index: gcc/expr.c =================================================================== --- gcc/expr.c (revision 184656) +++ gcc/expr.c (working copy) @@ -4687,7 +4687,13 @@ expand_assignment (tree to, tree from, b != CODE_FOR_nothing)) { misalignp = true; - to_rtx = gen_reg_rtx (mode); + /* If we only partly store to the misaligned memory region + perform a read-modify-write cycle. Otherwise use a scratch + register for the 'read' part. */ + if (bitsize != GET_MODE_BITSIZE (mode)) + to_rtx = expand_normal (tem); + else + to_rtx = gen_reg_rtx (mode); } else { of course we then generate foo: .LFB0: .cfi_startproc movdqu (%rdi), %xmm0 movhps .LC0(%rip), %xmm0 movdqu %xmm0, (%rdi) ret which is rather sub-optimal. Not sure who would be supposed to fix that. OTOH we could as well simply avoid going the movmisalign paths when the word is not accessed in full. But that's harder because we'd somehow have to circumvent the expand_normal case to fall into the movmisalign trap.