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.