https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114659
--- Comment #15 from Alexander Monakov <amonakov at gcc dot gnu.org> --- (In reply to Jakub Jelinek from comment #14) > (In reply to Alexander Monakov from comment #13) > > fldt does not convert (otherwise there's no way to spill/reload x87 > > registers). > > Doesn't it still misbehave say on pseudo denormals, pseudo infinities, > pseudo normals, pseudo NaNs etc.? That would be surprising to me. I tried the following test and it passed: #include <assert.h> #include <stdio.h> #include <string.h> static union { struct { long long mant; short signexp; } i; long double ld; } inp[] = { {{ 0x7fffffffffffffff, 32767 }}, // pseudo-QNaN, max payload {{ 0x4000000000000000, 32767 }}, // pseudo-QNaN, min payload {{ 0x3fffffffffffffff, 32767 }}, // pseudo-SNaN, max payload {{ 0x0000000000000001, 32767 }}, // pseudo-SNaN, min payload {{ 0x0000000000000000, 32767 }}, // pseudo-Inf {{ 0x7fffffffffffffff, 32766 }}, // max unnormal {{ 0x0000000000000001, 1 }}, // min unnormal {{ 0xffffffffffffffff, 0 }}, // max pseudo-denormal {{ 0x8000000000000001, 0 }}, // min pseudo-denormal // as above, with sign bit set {{ 0x7fffffffffffffff, 0x8000 | 32767 }}, {{ 0x4000000000000000, 0x8000 | 32767 }}, {{ 0x3fffffffffffffff, 0x8000 | 32767 }}, {{ 0x0000000000000001, 0x8000 | 32767 }}, {{ 0x0000000000000000, 0x8000 | 32767 }}, {{ 0x7fffffffffffffff, 0x8000 | 32766 }}, {{ 0x0000000000000001, 0x8000 | 1 }}, {{ 0xffffffffffffffff, 0x8000 | 0 }}, {{ 0x8000000000000001, 0x8000 | 0 }}, }; static long double out[sizeof inp / sizeof *inp]; int main() { for (int i = 0; i < sizeof inp / sizeof *inp; i++) { long double t = inp[i].ld; asm("" : "+t"(t)); out[i] = t; } assert(!memcmp(out, inp, sizeof inp)); } > And even if not, it still contains padding bits, as it loads 10 bytes rather > than 12 or 16 it occupies in memory. Yes, it would be wrong to copy a, say, __int128 using fldt/fstp.