Apparently what happens is that in expand_value_return, return_reg is (reg:QI 343 [ <retval> ]) (see C-code), while val is (subreg/s:QI (reg:SI 342 [ D.1978 ]) 0). This looks fine to me(?). On our machine, we define PROMOTE_MODE to SImode if possible. In expand_value_return the compiler then calls if (mode != old_mode) val = convert_modes (mode, old_mode, val, unsignedp); Which then makes the compiler call emit_move_insn from (reg:SI 342 [ D.1978 ]) to (reg:QI 343 [ <retval> ]) and asserts. Is this promotion model defined by us wrong? On Tue, Aug 27, 2013 at 10:05 AM, Hendrik Greving <hendrik.greving.intel@xxxxxxxxx> wrote: > In my backend (GCC 4.8.1), the compiler calls emit_move_insn from > expand_value_return. The C-code is > > static char > cnv(const char *str) { > int i = strtol(str, ((void *)0), 10); > if (i == -1) > i = 127; > return (char)i; > } > > x is SImode and y is QImode (makes sense from looking at the C-code). > Apparently the compiler doesn't call any sign or zero extend before > that. I am running into the assertion in emit_move_insn > > gcc_assert (mode != BLKmode > && (GET_MODE (y) == mode || GET_MODE (y) == VOIDmode)); > > because mode(x) != mode(y). > > Any idea what could causing this? > > Regards, > Thanks, > Hendrik Greving