https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87978
Bug ID: 87978 Summary: Local Register Variables Have No Effect When There is A Call Statement Between Product: gcc Version: 8.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: manjian2006 at gmail dot com Target Milestone: --- Source: struct Code { void* instruction_start; }; Code GetCode(); #define WRONG_CODE 1 void __attribute__((noreturn)) Foo(int numargs, void* entry) { #if WRONG_CODE register int param1 asm("r1") = numargs; register void* param2 asm("r0") = entry; asm volatile("bx %0\n" : : "r"(GetCode().instruction_start), "r"(param1), "r"(param2)); #else Code code = GetCode(); register int param1 asm("r1") = numargs; register void* param2 asm("r0") = entry; void* instruction_start = code.instruction_start; asm volatile("bx %0\n" : : "r"(instruction_start), "r"(param1), "r"(param2)); #endif __builtin_unreachable(); } When WRONG_CODE and compile with arm-linux-androideabi-g++ -fPIC -O2 -march=armv7-a -mfloat-abi=softfp -mthumb --sysroot=/home/linzj/android-ndk-r13b/platforms/android-21/arch-arm/ -fomit-frame-pointer -S -mfpu=neon -Wall testclobber.cpp The code generated is push {r3, lr} .save {r3, lr} bl _Z7GetCodev(PLT) .syntax unified @ 13 "testclobber.cpp" 1 bx r0 And When the opposite: push {r3, r4, r5, lr} .save {r3, r4, r5, lr} mov r4, r1 mov r5, r0 bl _Z7GetCodev(PLT) mov r1, r5 mov r3, r0 mov r0, r4 .syntax unified @ 21 "testclobber.cpp" 1 bx r3 clang/llvm can make both case correct.