<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/151689>151689</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [Clang] __builtin_* behaviour leads to recursion
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          Photosounder
      </td>
    </tr>
</table>

<pre>
    Some builtins, depending on the situation, only produce a jump to a symbol, and in my situation this silently turns into recursion, which is a problem. I'm trying to use my own libc implementation, compiling with the `-nostdlib -ffreestanding` flags, which works fine when compiling to WebAssembly because they all map to an operand, but not to other platforms. My `sqrtf()` implementation looks like this:

```
float sqrtf(float x)
{
    return __builtin_sqrtf(x);
}
```

It seems like all targets produce similar recursive assembly, like x86-64:
```
sqrtf:
        jmp sqrtf
```

or ARM:
```
sqrtf:
        b       sqrtf
```

with the exception of WebAssembly:
```
sqrtf:
        local.get       0
 f32.sqrt
        end_function
```

On x86-64 when renaming my function to `my_sqrtf()` gives `jmp     sqrtf@PLT`, I'm not sure if that even works when compiling without a standard library.

Clang 19 to 20 do the same thing, Clang 12 to 18 behave a bit differently:

```
sqrtf:
.LBB0_1:
 jmp     .LBB0_1
```

GCC shows identical behaviour, except for GCC 4.5 and below where it used to emit a `sqrtss` instruction but recursed at the end anyway. Intel's icc and icx generate `sqrtss`, which surprises me both because I thought it was based on LLVM and because that means it doesn't set errno.

I tried several functions implemented using builtins. When using `` or lower some functions produce a `jmp`, however it's a jump to a symbol with `@PLT` appended, whereas oddly sqrt and sqrtf are unique in not having this suffix:

```
sqrtf:
        jmp     sqrtf

sqrt:
        jmp sqrt

floorf:
        jmp     floorf@PLT

floor:
        jmp floor@PLT

truncf:
        jmp     truncf@PLT

trunc:
        jmp trunc@PLT
```

I'm a bit perplexed that compiling with `-nostdlib -ffreestanding` would produce jumps for all these functions, because this also turns into recursion, and I'm not warned about this during compilation, nor can I test for this using `#if __has_builtin(__builtin_floorf)`.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJyMVl9v27oP_TTOC1HDVuI0fchD2qE_FOjwG-69uHsMZIuOtcmSJ0pN_e0vKDt_1q7YggBBJIo6JA8PJYn0wSJus-o-qz4tZAyd89svnQuOXLQK_aJ2atz-7XqEOmoTtKVMPIDCAa3S9gDOQugQSIcog3aWd501IwzeqdggSPgW-wGCAwk09rUzbCKtAm2hHy8nIXSagLRBG8wIIXpLoG1w4LGJnmbnx043HWgCyVfUBvscnjJx20PwIyMKDiIhu3ZHC0bXDeh-MNijDWeIjesHbdj8qEOXQsjWxY11FJTRNdy0rUekIFOU2bqA1sgDXQAcnf9O0GqLcOzQXjkMDr5ivSPCvjYj1NhIxhM6HEEaA72csmHBDeilVey0jgGsC7zhQoceBiND63xPOXweGRv98KHNxCYTdwzn55DAOPedwOjvmNKYLXdZkb7rYv4Wu9Y4GeDkZ_r3yu6KXXZ7nxU7AACPnHjY7-dy70_2yXJ5n4w_vfGcFbunAITYzxg4ziD9AQOdiUC610b6UzVfEOScI05AOva6Wd-sVzP4K_8ThrQM8-dbP8yhvIPiPOz--vxHXur59wNPZ27ga4NDSrRrr6v7R5cY10iTHzDM_9kM2qXI2fbKDq3at9E2iaPvsPzfzumZ-ObRyp7p1o9wOsTsydZFP-7fkOWgX5B4i7N2iXdVfHn-hy8QD3MLMQUpegTdQuhkAHxBO3P9Dc05Ny4G7mruEukV95qXfswnwA9G2gOUd4xKFKDcJBSyTxS1B751thFsU26gxk4yL6DWAZRuW_RJDH5J56tM58_398W-nNN-CvK0-i6V_3t4AOrckUArtEE30kxXaxc9w5rKDa3zwLarvEqCVaNxR84DJyiwyigGjr3mNMw9SpTa01LwcaoK9_ZEelQgw0Qoq0Da8SjHHJ5sQJOJWwLdNJMyNq9wQIteBvzJ70V_KPrBa0IClmYXurPQPAEX5tAFxniUBLXki52F5-d_P8-BnDRJBuhRstAGUA7JZuKWOzkAem_dXMonCF6jAsIX9NKcCUcXGUIFkZgXpzGRw1cmzLQ4ZR-cB-OO6IF4oFy8XGbFxNE50s4d-ULQIWXn_SSZxJutT1QGOfBkQjVlCj1KAqeUGRPnU_SJOCA9QrT6R0QeREx8JgDrdxpDsW316-94dy1GP8nIZPVrxZr2W-Oc_8DNvDfFdLF-bzwtX9kFH23zgdd57631e-Np-Wz3RueTTkwdOqAfDL5yFzCR3szU38zTo4tGnSvPlaXUcGl0dEhX_EgD8kxZHv2G3IcPBC7xRc2O0ltuu5q1Kh1W0TPGCe35QWCdh0Za7h6kqfWT9YW_Yqlb2O87SafZmInNZU7ORUuCmy_UdqnulndygdvytloVVVGtq0W3rcSylKJeLWW1xhbruqra1VrdqrJsSlGKhd6KQlTFpihLUa6LKl-rTVku15uNrKtCFpitCuylNrkxL33u_GGhiSJuy6pcb-4WRtZoKL3ohGhYXjMh-HHnt3zgpo4HylaF0RTo4iLoYNIzMAlyVn26egBkYndRRzAoFcF1zhfRm20XwpBeHeIxE48HHbpY543rM_HIl8w_N4N337AJmXhMoCkTjzPul634LwAA__-brGMC">