Issue 93401
Summary Rounding error in compiler-rt `__divtf3` for `f128`
Labels new issue
Assignees
Reporter tgross35
    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;
}
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to