<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/88771>88771</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[libc][math] `fdim` functions can compile to incorrect code
</td>
</tr>
<tr>
<th>Labels</th>
<td>
libc
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
Flandini
</td>
</tr>
</table>
<pre>
Follow up on #61092 for the reported cases of `fdim(-inf, -inf)` raising `FE_INVALID` when it shouldn't and `fdim(-max, -den)` raising `FE_INEXACT` when it shouldn't.
Looks like this is caused by compiler optimizations https://godbolt.org/z/z3x8zGWzb evaluating both sides of a conditional operator on O1-O3 in [this code](https://github.com/llvm/llvm-project/blob/main/libc/src/__support/FPUtil/BasicOperations.h#L177).
I am using `clang-14`, and I get the following asm for `fdim`:
```
Dump of assembler code for function __llvm_libc_19_0_0_git::fdim(double, double):
0x0000000000408440 <+0>: push %rbp
0x0000000000408441 <+1>: mov %rsp,%rbp
0x0000000000408444 <+4>: movabs $0x7fffffffffffffff,%rax
0x000000000040844e <+14>: movabs $0x7ff0000000000000,%rcx
0x0000000000408458 <+24>: movq %xmm0,%rdx
=> 0x000000000040845d <+29>: and %rax,%rdx
0x0000000000408460 <+32>: cmp %rcx,%rdx
0x0000000000408463 <+35>: ja 0x408487 <__llvm_libc_19_0_0_git::fdim(double, double)+71>
0x0000000000408465 <+37>: movq %xmm1,%rdx
0x000000000040846a <+42>: and %rax,%rdx
0x000000000040846d <+45>: cmp %rcx,%rdx
0x0000000000408470 <+48>: ja 0x408483 <__llvm_libc_19_0_0_git::fdim(double, double)+67>
0x0000000000408472 <+50>: movdqa %xmm0,%xmm2
0x0000000000408476 <+54>: subsd %xmm1,%xmm2
0x000000000040847a <+58>: cmpltsd %xmm0,%xmm1
0x000000000040847f <+63>: andpd %xmm2,%xmm1
0x0000000000408483 <+67>: movapd %xmm1,%xmm0
0x0000000000408487 <+71>: pop %rbp
0x0000000000408488 <+72>: retq
```
Changing the conditional operator to an if-statement gives assembly that doesn't raise these exceptions, but this seems brittle; messing around with compiler explorer, I also sometimes get the same problematic assembly with an if-statement.
In discord, philnik brought up that we need to set `FENV_ACCESS` to on since clang defaults to off.
Tagging @nickdesaulniers @michaelrj-google.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyklt1u27gSx5-GvhnEkCjJki98EdvRQYCiPUB7evbOoMiRxIYiVZFK3Dz9grTljybudneFRE4szo8z_xlxhlkrG424ItmaZNsZG11rhlWpmBZSy1llxI9VaZQyLzD2YDQQmiziaEmhNgO4FmHA3gwOBXBm0YKpgSyiWsiO0OJO6prQDRw-l2QRwcCklbrxi8qH3ePHr_cfHrf-wUuLGqQD25pRCU1o7oBpAZe4ju0DTqC-gXv4437z5QZuTqItie4P9w_GPFlQ8gnBtdKCtMDZaFFA9QO46XqpcADTO9nJV-ak0RZa53pLkntCS0LLxojKKDc3Q0No-ep_k33x-p__v1aAz0yNzHnPKuNasFIctGHAjRbS85gC0-PAnBm8sJ_iu08JSA0kWwePuBFIsi2hxU_7SteO1ZybjtBSqefp464fzDfkjtCyUqYitOyY1P6hrDihpR38fbezY-8zRmhZ_vd_TipCyzWzkn8KzvhA5y2hyYc4zwldzuFStUdgHYyT4lwx3dzFKVlEPi0-W4_QoAt1UYeq8SuZ7UK1TIlcRD6WC6r_5vAT_t2OXR-0sha7yqfBSxEQ9ai5dxF2Ox_yzoe2i5e7aBftGuk8N7k_VoswY6XQOzb9tTztCwDRPjpdaVSkaQQk2RC6jkjyEBYu-9G2AEBoNlT9bcP4aBifDDvzDEdD2xO6uSK8sU-P9umlPassEJpG-7y-vo44tr-Fw8mdm7zo8jry-C1eVhx59Ir3_RDfvusmgjgSSLIlycNbjpg4yxMnvN8HncKbfYl5R-nFlKKEnhC86-Ho_1_bJ5N9drL_xrwHEO39giL3C_5hbdF1Hirg5u7ZtHv-vpDxb0TAplqhVyL-toJTEtLsSsFjEt6K-DMgn1KQFjckTP6VhIv8VxLm9Lh7Fl1KKL6z61rcdx29DVlMkHNB27Gy4joNv2ZMeciKSx2VO1HOnsS3pKyPjEVymcteTPVA3yDeOlJMJb24KirWv40mug3Jj5D8fIT15lQVN0-uYjoa8nM1Dui-v3uqH-6blunGNwXfIt5thc4A0yDrO-uYww61g0Y-o53awQ9wLXMgDNrDkOBHAN_E0SLgnmMfepgvrGp0h-ZuETsL1SCdU0iSNXRoQxNjgxm1gBfp2nPTx32vzICDRzwCU9aANR062aE9tTfLOoR-MJXCjjnJz-4F2E8hXI0ejxqEtNwMwu_Qt1Jp-QTVYMamdX7MCgG-IGhE4fWw6A4Dzsevu_vN5uHzZz_hOOPHBis1RwidGATWbFTOhkd1fbXpF9YE3UkaacmfBFo2Ki1xsP6rTvKWoRq-3TXGNArnM7FKxDJZshmu4jxOaJQu83zWrtIlZzxlNBbxMqJxlmcpX0RVmufLok4WYiZXNKJplMZZXMSLOJ9zjljnCYtrTBgvEpJG2DGp5v6I8NPTTFo74qoo8jyeKVahsmEepfQwuVA_mQ6rMONUY2NJGilpnT0DnHQqzLDBINuSbN0x15JsezF0nIYHP-npKd1eK6m5GQbkLgwas3FQq789coUYLKFlCOPPAAAA__8d7zi3">