Closed
Description
For the following C(++) code Clang produces output that differs from every other major compiler (and from internal tests it was reduced from):
#include <cstdio>
int main() {
long x = 503489155L;
double y = *(double*)&x;
float fy = y;
printf("%lx, %e (%a)\n%f (%a)\n", x, y, y, fy, fy);
}
output:
1e02a283, 2.487567e-315 (0x0.000001e02a283p-1022)
0.000000 (0x1p-149)
expected:
1e02a283, 2.487567e-315 (0x0.000001e02a283p-1022)
0.000000 (0x0p+0)
I've pinpointed the issue to Val.convert in FPTrunc case of llvm::ConstantFoldCastInstruction
which for 0x0.000001e02a283p-1022
double returns 0x1p-149
float, whereas one would expect (assuming the other compilers are correct here) returned value to be 0
.
Furthermore, it is represented as float 0x36A0000000000000
in IR which may or may not be expected (if it was hex value for simple float, when there are eight extra zeroes, but if it uses double width even for regular floats, then it's ok.
godbolt: https://godbolt.org/z/YM3rvY3hM