<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - __cpu_indicator_init() runs too late on macOS"
   href="https://bugs.llvm.org/show_bug.cgi?id=48459">48459</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>__cpu_indicator_init() runs too late on macOS
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>compiler-rt
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>11.0
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>MacOS X
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>builtins
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>chfast@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>The usage of __builtin_cpu_supports() requires CPU information being
initialized up front. This is done by __cpu_indicator_init() which is
implemented in compiler-rt/builtins as __attribute__((constructor)). From the
GCC documentation and this comment in code:
<a href="https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/builtins/cpu_model.c#L709-L713">https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/builtins/cpu_model.c#L709-L713</a>,
the __cpu_indicator_init() should be invoked with high priority and calling it
directly from other "constructors" should only be needed only in very specific
cases like IFUNC resolving.

However this promise is not fulfilled on macOS. From my experiments the
__cpu_indicator_init() is actually the last in __mod_init_func section of
Mach-O.

For example program cpu_check.c:


int puts(const char *str);

__attribute__((constructor)) static void check_cpu()
{
    if (__builtin_cpu_supports("sse2"))
        puts("SSE2 supported");
    else
        puts("SSE2 not supported");
}

int main() {}


I get the following:

<span class="quote">> objdump -macho -section=__mod_init_func ./a.out</span >
./a.out:
Contents of (__DATA,__mod_init_func) section
0x0000000100002020 0x00000001000014d0 _check_cpu
0x0000000100002060 0x0000000100001510 ___cpu_indicator_init


It does not matter if I set any explicit priority value for my constructor.


In the compiler-rt the __cpu_indicator_init() is declared with this attribute:

#if defined(HAVE_INIT_PRIORITY)
#define CONSTRUCTOR_ATTRIBUTE __attribute__((__constructor__ 101))
#elif __has_attribute(__constructor__)
#define CONSTRUCTOR_ATTRIBUTE __attribute__((__constructor__))
#else

<a href="https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/builtins/cpu_model.c#L16-L20">https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/builtins/cpu_model.c#L16-L20</a>

I haven't built it for macOS, but at least from searching on GitHub the
HAVE_INIT_PRIORITY is never defined therefore it does not have the priority
set.
Furthermore, the 101 priority value does not look correct as "user" priorities
start from 100.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>