https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121973
--- Comment #6 from Andrew Pinski <pinskia at gcc dot gnu.org> --- The nop comes from the need of debugging. Specifically from cfgcleanup: ``` /* If not optimizing, preserve the locus of the single edge between blocks A and B if necessary by emitting a nop. */ if (!optimize && !forward_edge_locus && !DECL_IGNORED_P (current_function_decl)) { emit_nop_for_unique_locus_between (a, b); a_end = BB_END (a); } ``` The mv comes from the expansion of the return: ``` (insn 10 6 11 2 (clobber (reg/i:TI 10 a0)) "/app/example.c":32:1 -1 (nil)) (insn 11 10 14 2 (clobber (reg:TI 134 [ <retval> ])) "/app/example.c":32:1 -1 (nil)) (insn 14 11 8 2 (const_int 0 [0]) "/app/example.c":32:1 -1 (nil)) (insn 8 14 9 2 (set (reg:DI 10 a0) (subreg:DI (reg:TI 134 [ <retval> ]) 0)) "/app/example.c":32:1 -1 (nil)) (insn 9 8 12 2 (set (reg:DI 11 a1 [+8 ]) (subreg:DI (reg:TI 134 [ <retval> ]) 8)) "/app/example.c":32:1 -1 (nil)) (insn 12 9 0 2 (use (reg/i:TI 10 a0)) "/app/example.c":32:1 -1 (nil)) ``` The easy workaround is to add: __builtin_unreachable(); right before the last asm.