[llvm-bugs] [Bug 50121] New: __attribute__((no_caller_saved_registers)) ignored for struct members and typedefs

via llvm-bugs llvm-bugs at lists.llvm.org
Sun Apr 25 22:58:41 PDT 2021


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: unassignedclangbugs at nondot.org
          Reporter: jhaberman at gmail.com
                CC: htmldeveloper at gmail.com, llvm-bugs at lists.llvm.org,
                    neeilans at live.com, richard-llvm at metafoo.co.uk

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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20210426/fbaf2fc6/attachment.html>


More information about the llvm-bugs mailing list