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

    <tr>
        <th>Summary</th>
        <td>
            Rounding error in compiler-rt `__divtf3` for `f128`
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

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

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

<pre>
    Multiplying f128 `0x0000000000000000000000000000000 * 0x0001ffffffffffffffffffffffffffff` should have the result `0x3f8e0000000000000000000000000001`, which is produced by the GCC libraries ([godbolt](https://gcc.godbolt.org/z/so1zrjfej)). Clang's compiler-rt returns a value with an incorrect exponent, `0x3f8e0000000000000000000000000001`.

Reproduction, needs to link against compiler-rt `divtf3.c` with  `__divtf3` renamed to `__divtf3_x` so the system library doesn't get linked instead.

```c
#define __STDC_WANT_IEC_60559_TYPES_EXT__

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>

#if defined(__clang__) && (defined(__i386) || defined(__x86_64))
#define _Float128 __float128
#endif

_Float128 __divtf3_x(_Float128, _Float128);

typedef struct {
    uint64_t lower, upper;
} u128;


void f128_print(_Float128 val) {
    u128 ival = *((u128 *)(&val));

    #ifndef __clang__
    char buf[1024];
 strfromf128(buf, sizeof(buf), "%.32g", val);
    printf("%#018" PRIx64 "%016" PRIx64 " %s\n", ival.upper, ival.lower, buf);
    #else
 printf("%#018" PRIx64 "%016" PRIx64 " %lf\n", ival.upper, ival.lower, (double)val);
    #endif
}

_Float128 new_f128(uint64_t upper, uint64_t lower) {
    u128 val;
    val.lower = lower;
    val.upper = upper;
    return *((_Float128 *)(&val));
}

int main() {
 _Float128 a = new_f128(0x0, 0x1);
    _Float128 b = new_f128(0x0001ffffffffffff, 0xffffffffffffffff);
    f128_print(a);
 f128_print(b);
    _Float128 c = __divtf3_x(a, b);
    // _Float128 c = a / b;
    f128_print(c);

    return 0;
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJykVlFv4ygQ_jXkZbQRxrGdPOShTZrTPtxptVvp7p4sbMYxewQiwGm6v_4EdhM7TfdWuqhyzczwzTfDh4E7J_cacU2yR5JtZ7zzrbFrv7fGuTSbVUa8rn_vlJdH9Sr1HpqELYHklJ7pz39A2APEqKT5yY_kFFxrOiWg5ScE3yJYdJ3yfZa0WeJPsiQkp4Rt4KWVdQvSwdEa0dUooHqNWL9tNqBkZbmV6ICwJcke90ZURnmSbQlbtt4fHUkfCNsRttvX9Xxwz43dE7b7QdjOmeSH_d7gd8JWhK3msFFc7wkrHNTmcJQK7SfrwaLvrHbA4cRVh_AifQtcg9S1sRZrD3g-Go3aB8q_Wt6c0C2hD_3zK_YFeml0ANGIwoE3oKT-B_ieS-38hBTJqZAn36TzOvQ6cgrGsuzNwWhR8wOKgDPylOe4OCb20b06j4ehla8gDDpNWOFhjz4mRwEhN3IxIRzWJ_7Vw5ilAhupEcry2_N2U_758Mdz-flpU-Y0y1bl899fnr6VT389l-UEhqVS16oTCCTdOC-kmbckffrAq2T1oVtq71-P6MYBl7AGenaCsGVZ1mGZy5KwFRCWE5YHAY0DZLrMo7fYkGIzmXte5mW-6AXzrvSdMtyHnVSWzfB6iUEtZDPmNY6-rAxbXsxBB6PBiqSP4-mhWIENOG-72gMpBi8AQCe1zxelB2Ve0Aag7nhEe0UottAF1Clk_zwZKeL3oDxaGTR9pRQ2QN-XcbLgkCeugKTb8HkIu5EtozmOVtGQ93PfFxIw4hrpUM51dS7OuuUWqq4h2WNC2SLs7zeEUH1jzaGJLVqGILYBJ3-gad7Gq7grGSMsm6dsH982QyVXIACI5TaRbAgmLKVJeIcvXz-f88WAQZN8agPCMkeyjR6QQyvmfb_fRpdlGAiNswZpKIeD4X9wUM0vkghiN12lkLDVnTbcaLXY3hetxpdyaPtFbpeEtwK8J5mQepz3wjHqqJ94648Jon8q6ODvP9NXAV6p_ocKpxVK7eHApY7hY95XPB4ZjBpAz_G0oufktpnXSdWdSTeHaI_x7ii9gZxsTT7xTlzVx1zqyGXy2eFRnu-1EE7PdzN5cED1Ma36_jYfloje6f3beTIT61Ss0hWf4Topkryg-bJIZu06y1ZpkS14lfJqkTWZEHlVJ8UyqStssBYzuWaULWjGclrQJEnmzQLzpimyqs6ytEoYWVA8cKnmSp0O4Rowk851uF6lC5rMFK9QuXhhYkzjC0Rn2E7ZdmbXYc6nqts7sqBKOu-uKF56heuvptMiXKXQWmNB6tvjenwyN8YGU1RCTmedVeubC4v0bVfNa3MgbBcyDf8-Ha35jrUnbBf5OcJ2Pf_Tmv0bAAD__9fTzdI">