http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55876
--- Comment #3 from vries at gcc dot gnu.org 2013-01-04 16:42:36 UTC --- Another way to go about it is to prevent the assert from triggering: ... Index: optabs.c =================================================================== --- optabs.c (revision 194898) +++ optabs.c (working copy) @@ -329,7 +329,8 @@ widen_operand (rtx op, enum machine_mode /* If MODE is no wider than a single word, we return a paradoxical SUBREG. */ - if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD) + if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD + && GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (op))) return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0); /* Otherwise, get an object of MODE, clobber it, and set the low-order part to OP. */ ... The generated code seems to be ok: ... (insn 34 33 35 (clobber (reg:SI 228)) -1 (nil)) (insn 35 34 36 (set (subreg:DI (reg:SI 228) 0) (reg:DI 222 [ usedD.1407 ])) -1 (nil)) (insn 36 35 37 (set (reg:SI 229) (xor:SI (reg:SI 228) (const_int 1 [0x1]))) -1 (nil)) ... But I'm not sure this is the proper location to fix this.