<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/90675>90675</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[PPC] DoubleAPFloat scalbn fails to readjust high double when rounding affects its value
</td>
</tr>
<tr>
<th>Labels</th>
<td>
backend:PowerPC
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
hubert-reinterpretcast
</td>
</tr>
</table>
<pre>
The `DoubleAPFloat` `scalbn` implementation treats the high and the low double as being independent:
https://github.com/llvm/llvm-project/blob/0c0c5c475857e9cd6a2fe82fd1e46abdb174a1c1/llvm/lib/Support/APFloat.cpp#L5132-L5133
That is incorrect.
As can be observed from the following (https://godbolt.org/z/r64Wfv4zW), when the low double is close to 0.5 ulps of the high double, division by a power of 2 can cause the low double to round to 0.5 ulps of the high double (which can then require that the high double be adjusted so that its value is the value of the `long double` correctly rounded to a `double`):
```
constexpr double subnorm = __DBL_DENORM_MIN__ * 3.;
constexpr double subnormAdjacent = (1. + __DBL_EPSILON__) * 0x1p-1022 * 0x1p+3;
extern constexpr long double theValue = (long double)subnorm + subnormAdjacent;
extern constexpr long double expected = theValue / 2.;
```
The `DoubleAPFloat` implementation of `scalbnl` would (for division by 2 via an `n` of -1) produce a high double that changes from the input value only by the encoded exponent. The (correct) result produced by the division operation above differs from the input value in more than that.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyUVd9v4jgQ_mvMy6gomfwAHniAskgrdbvodnX7iBx7Qtwzds52oN2__mQHStu7W91JKGiS8TfzfR5_5t6rgyFasmrNqs2ED6GzbtkNDblw50iZQK53FAT3YdJY-bL83hGwOtvYodG02m215YHVWXznBdeNiYE69pqOZAIPyhoIjnjwEDqCTh064EamQNszyAQE3ENDyhxAGUk9GUkmsGLFsg3LVl0IvY8RbhluDyp0QzMV9shwq_Xp-nfXO_tEIjDcNto2DLeZyEQlylk1r2a0ELLm2NIcW5lTWfNGNvms5LnI3-CouO7b0PfWRaALwanoe4bFQ5UXeBefxdjY-Pze8QDKgzLCOkciTN9-XXkQ3EBDYBtP7kQSWmePSYDWam3PkTbD-QeWVjZWh6l1B4bbnwy3ri5_tKfy5w-GC4b3cO7IfJRReRDaeoJgIZtWMOjeg21v0o95cblUJ-Xj7jQvwKG3Z3IxE1O3gg8R5D14sODsEPful-CRy7lToktIIXbp6M9BuQjIw9_SGwIunwYfSIK3Y44KHk5cD4lRXDAGl2KszrQ1hyuZOoOL8Ppl7JBSjzwmvuZE1a4DFcPxl0JhjQ_03LtrS35ojHVHYMUG9vvN-mG_-fT49bcv-y-fH_d7YLiCYsqK9a-Xr-QTF2RCgmE4z6fAcH0B_LT79vnh6-N-z3CRALPnvL_LM8TXiOG6eC1Cz4GcgVutNwpEUX5PAl0qvVUHF69scP2xtf8GT889ibg9Ef5WC7eANxU-aHo9Gv_sFh8MwrY3_9Dx-9kOWkYmrXXvJhXhpDhwE_OT1dgW7vKoYe-sHAQBfzdcaZpEx82B_O3cKdMP4TpTRr9E5PiejLBxeOi5t4ZMmEIigPPLfMU6jvygw7WcvC59bdL25EZWvLGn-KFtyf1LcWXgaMeDYVKv04lcFnJRLPiElvksL6u8yrCedMtsNs9qwoayglqOHOW8bnNsRT7ntVjgRC0xwzIriwwxz7CeYlWVRTsrZ8jFfCELVmZ05EpPo9lFY5ko7wdaLrJ6Vk00b0j7dBMgNlz8QUayYrWLxrC7Z4jxgnDL5LTNcPCszLTywd_Qggo6XSW73T2rNvBu12HcXWi50j5ZCY2n_t12JU9LRziaIm9bEsHf3GAyOL3837dBYukZbhPRvwIAAP__tOVHeg">