https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105817
--- Comment #1 from Richard Earnshaw <rearnsha at gcc dot gnu.org> --- The GCC manual says <quote> register int *p1 asm ("r0") = …; register int *p2 asm ("r1") = …; register int *result asm ("r0"); asm ("sysint" : "=r" (result) : "0" (p1), "r" (p2)); Warning: In the above example, be aware that a register (for example r0) can be call-clobbered by subsequent code, including function calls and library calls for arithmetic operators on other variables (for example the initialization of p2). In this case, use temporary variables for expressions between the register assignments: int t1 = …; register int *p1 asm ("r0") = …; register int *p2 asm ("r1") = t1; register int *result asm ("r0"); asm ("sysint" : "=r" (result) : "0" (p1), "r" (p2)); </quote> So I think by that statement this testcase is invalid. You need to write something like: extern __thread uint64_t p; int foo(unsigned int *result) { register uint64_t r0 asm("x0"); register uint64_t r1 asm("x1"); uint64_t real_r0; uint64_t real_r1; asm("hvc %2" : "=r"(r0), "=r"(r1) : "i"(0) : "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17"); real_r0 = r0; real_r1 = r1; *result = real_r1; return (int)real_r0; } It's unfortunate that this type of testcase just fails silently with no diagnostic from the compiler.