<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/62282>62282</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[libc++] `long double` function call relies on `double` function
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
JoseLuis-SolidSands
</td>
</tr>
</table>
<pre>
In line 745 of file _libcxx/include/cmath_ the following function template is defined:
```c++
template <class _Tp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp __constexpr_scalbn(_Tp __x, int __exp)
```
This function can be called with a value of type `long double` as the first argument (e.g., line 710 of file _libcxx/include/complex_). However, its return statement is:
```c++
return __builtin_scalbn(__x, __exp);
```
This other built-in function takes a `double` as the first argument (instead of a `long double`) and also returns a `double` (instead of a `long double`). This accuracy loss yields undesired results, as it can be seen in the following example ([Compiler Explorer](https://cpp.godbolt.org/z/19MqbWhMc)):
```c++
#include <complex>
int main( ){
bool res = true;
const std::complex<long double> &a = {0.L, 0.5L};
const std::complex<long double> &b = {0.L, 0.549306144334054845697622618461262852323745278911374725867L};
std::complex<long double> x = std::atan<>( a );
res &= ( std::real<long double>(x) == std::real<long double>(b) );
res &= ( std::imag<long double>(x) == std::imag<long double>(b) );
return !res;
}
```
This bug was found in `clang 16.0.0` using the SuperTest suite, `clang 15.0.0` still works fine.
Compilation flags: `-m64 -std=c++20 -stdlib=libc++ -O0 -funsigned-char`
Replacing the call to `__builtin_scalbn()` with a call to `__builtin_scalbnl()` for this case should fix it (or creating a specialization).
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyUVktv2zgQ_jX0ZWBBpt4HH-IXmkX6QBNgexMocixzS5Nakmqc_voFacd2mjbtAgIMk_P8ZuYbMudkrxHnpFiQYjVho98ZO__LOLwbpZveGyXFPdPCTTojnua3GpTUCFVegNnCViqEVsmOHw6EbqTmahRI6Ibvmd-14HcIW6OUeZS6h-2ouZdGg8f9oJhHkA4EbqVGQbIbkq5IekPK9PhxQhfhi6dnDZItuWLOQfswkGwN7d3tYvnpU_vudrVuN58_vm9vFrfn0-XHD_cP6y-fPrf3tx-W63b55QtNgyq0LTfaeTwMtnWcqU4TWh8vDoQuQWoPbYuHgdDmh8COfx920l0y4kxDh8CZUijgUfodMPjG1IgBJv80IJAyVUb3IMzYKSRlCswdAZLWeWC2H_eoPRBaY9InIYgj1LP0bajNflB4aAltEnhnHvEb2piBd2DRj1aD88xjNC7db4A-abRtN0rlpb4C5wjMGZRs8WtcjN-hhWhiKvVV4dlXdMACFn8AgwwFYiJkz17DR2gDTAtgyplToq9M_4mRBGLIjPPRMv4EyjgHTxKVcDBqgU5aFGDRjcq7gABzIP1zxR2iBql_6HQ8sFCU4J8Ui6XZD1KhhfVhUMaiJcWK0Hrn_RDLQTehjMOQ9EZ0RvnE2J7QzXdCN7Pm_b_d37v3PCAeQH8u3hslJDQ7dUeclmN7kGx9rRnae89kqCsEu9VJFwCgM0aFfIFkK_B2xEupzzJxeMD5OLfZzdnJ8hrebA2ElizaIdUiTe4CfGlS3JFqdTb6P811r83lTZaWszzPsjwt8jovyqYqKS1ndV7OaEnrgmY0q_KCVnUzm2VVXtGiLqsXYZyC-X0MhxjAWY55pkm2DPjSOrTY9WicE4xw0jKGTuuLtkWmXrkgtD6E7ibZ6oWrXwl3UfjK71se5Z71f-zxV8KvPF77jQRC6Myiu9xXqx9aFq7ooht7eGQOtmbUIkxTaGnFdA-zMkmTKD66MFhhzO7HAe0DhoYZpcfQBBf54lneeakUPBr71UHYMMnR33EWWWSjrWJ9GMCgPt2XOUxj4qvTNNE0HijZkWwViPd4DNOPKUy3o46bU0z5jtkz-33GQTH-HGlYB-BNsP8TQg34lenzsnhDVl2Et8aCD5Bx5hDczoxKwFYeAiMRWhsL3CLzIQAGbkAumZLfY7qB6iZinokma9gE57OypmldV1k-2c1FWuRVLZqmqESNrGgaLjJO02rLWdowMZFzmtIszelslhd0lidNVfMiZV1adCLvGkHyFPdMqkSpb_vAYBPp3IjzktKaThTrULn4yqBU4yPES0JpeHTYedCZdmPvSJ4q6by7WPHSq_g8uVSAFKufbNOrXawCfymJDox-uRCehSajVfOXBNxLvxu7hJs9oZvg_vQzHaz5B7kPSzcE7QjdxKT-CwAA__9t2ciC">