Open
Description
Multiplying f128 0x00000000000000000000000000000001 * 0x0001ffffffffffffffffffffffffffff
should have the result 0x3f8e0000000000000000000000000001
, which is produced by the GCC libraries (godbolt). Clang's compiler-rt returns a value with an incorrect exponent, 0x3f8f0000000000000000000000000001
.
Reproduction, needs to link against compiler-rt divtf3.c
with __divtf3
renamed to __divtf3_x
so the system library doesn't get linked instead.
#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;
}