https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87984
--- Comment #32 from Segher Boessenkool <segher at gcc dot gnu.org> --- Historically, a local register asm variable *does* live in that variable for its entire scope. This stopped working correctly, even with the many caveats there were for it, and many years ago the manual added language saying that only using such a var in an extended asm in or out is supported, and there was language warning you to keep the life time short, etc. This did *not* change the implementation. Any other use still is explicitly unsupported, and all such testcases are invalid code. It would be nice if GCC was changed such that such vars were expanded to a pseudo like any other var, and copies to/from a hard reg just around the asm. Gimple doesn't need to do *anything* for that, just keep track that the var is declared as local register var, and the gimple it had now at expand is just fine: === f () { register int a __asm__ (*eax); int o; ;; basic block 2, loop depth 0 ;; pred: ENTRY a = 1; __asm__("add %1, %0" : "=g" o_14 : "r" a, "0" 0); clear_eax (); __asm__("add %1, %0" : "=g" o_21 : "r" a, "0" o_14); clear_eax (); __asm__("add %1, %0" : "=g" o_28 : "r" a, "0" o_21); clear_eax (); return o_28; ;; succ: EXIT } === But currently "a" is expanded as a hard reg, not a pseudo, and the code does not do what you want at all. As the manual tells you. === ;; Generating RTL for gimple basic block 2 ;; a = 1; (insn 5 4 0 (set (reg/v:SI 0 ax [ a ]) (const_int 1 [0x1])) "cax.c":6:18 -1 (nil)) === (and it gets worse after that).