https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84301
--- Comment #1 from Uroš Bizjak <ubizjak at gmail dot com> --- The function should have either be declared void or with a value return. Otherwise, selective scheduler should be taught to not separate (insn 16) from its use (insn 19): ... (insn 17 9 18 2 (clobber (reg/i:SI 0 ax)) "pr84301.c":13 -1 (nil)) (insn 18 17 16 2 (clobber (reg:SI 0 ax [orig:94 <retval> ] [94])) "pr84301.c":13 -1 (nil)) (insn 16 18 10 2 (set (reg/i:SI 0 ax) (reg:SI 0 ax [orig:94 <retval> ] [94])) "pr84301.c":13 86 {*movsi_internal} (nil)) (insn 10 16 27 2 (parallel [ (set (reg:DI 2 cx [orig:96 lr ] [96]) (minus:DI (reg:DI 2 cx [orig:96 lr ] [96]) (reg:DI 1 dx [orig:88 _2 ] [88]))) (clobber (reg:CC 17 flags)) ]) "pr84301.c":10 278 {*subdi_1} (nil)) (insn 27 10 11 2 (set (reg:DI 1 dx [98]) (reg:DI 2 cx [orig:96 lr ] [96])) "pr84301.c":10 85 {*movdi_internal} (nil)) (insn 11 27 19 2 (set (reg:CCGC 17 flags) (compare:CCGC (reg:DI 1 dx [98]) (const_int 1 [0x1]))) "pr84301.c":10 12 {*cmpdi_1} (nil)) (insn 19 11 21 2 (use (reg/i:SI 0 ax)) "pr84301.c":13 -1 (nil)) ... The assert in mode-switching.c is there to catch the above case. So, probably ice-on-ivalid-code with selective scheduling.