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.

Reply via email to