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.