https://bugs.llvm.org/show_bug.cgi?id=50121

            Bug ID: 50121
           Summary: __attribute__((no_caller_saved_registers)) ignored for
                    struct members and typedefs
           Product: clang
           Version: trunk
          Hardware: PC
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: -New Bugs
          Assignee: [email protected]
          Reporter: [email protected]
                CC: [email protected], [email protected],
                    [email protected], [email protected]

Take the following program that uses no_caller_saved_registers:

__attribute__((no_caller_saved_registers)) void g();

int f(int x) {
  g();
  return x;
}

This produces the expected output, edi is preserved across the call:

0000000000000000 <f>:
   0:   50                      push   rax
   1:   31 c0                   xor    eax,eax
   3:   e8 00 00 00 00          call   8 <f+0x8>
                        4: R_X86_64_PLT32       g-0x4
   8:   89 f8                   mov    eax,edi
   a:   59                      pop    rcx
   b:   c3                      ret

However the following program does not generate the same output:

struct {
  __attribute__((no_caller_saved_registers)) void (*g)();
} st;

int f(int x) {
  st.g();
  return x;
}

In this case the attribute is ignored, and edi is spilled to a normal
callee-save register:

0000000000000000 <f>:
   0:   53                      push   rbx
   1:   89 fb                   mov    ebx,edi
   3:   31 c0                   xor    eax,eax
   5:   ff 15 00 00 00 00       call   QWORD PTR [rip+0x0]        # b <f+0xb>
                        7: R_X86_64_PC32        st-0x4
   b:   89 d8                   mov    eax,ebx
   d:   5b                      pop    rbx
   e:   c3                      ret

If we copy into a local variable with the attribute, it works:

struct {
  __attribute__((no_caller_saved_registers)) void (*g)();
} st;

int f(int x) {
  __attribute__((no_caller_saved_registers)) void (*local)() = st.g;
  local();
  return x;
}

However it does not work if the attribute is on a typedef:

typedef __attribute__((no_caller_saved_registers)) void g_type();
g_type *g;

int f(int x) {
  g();
  return x;
}

This bug appears to be similar to https://bugs.llvm.org/show_bug.cgi?id=21082

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to