https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112521
Bug ID: 112521 Summary: __float128 miscompilation: assignment as an aggregate field Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: andrew at ziglang dot org Target Milestone: --- https://godbolt.org/z/3hfrTxvE3 typedef signed char i8; typedef unsigned char u8; typedef signed short int i16; typedef unsigned short int u16; typedef signed int i32; typedef unsigned int u32; typedef signed long int isize; typedef unsigned long int usize; typedef signed long long int i64; typedef unsigned long long int u64; typedef signed __int128 i128; typedef unsigned __int128 u128; typedef _Float16 f16; typedef float f32; typedef double f64; typedef long double f80; typedef __float128 f128; extern void *memcpy(void *restrict, void const *restrict, usize); struct Storage { union { f16 flt16; f32 flt32; f64 flt64; f80 flt80; f128 flt128; } flt; enum { flt16, flt32, flt64, flt80, flt128, } tag; }; struct Storage readFromMemory(const u8 *buffer, u32 bits); [[gnu::noinline]] struct Storage readFromMemory(const u8 *buffer, u32 bits) { struct Storage storage1, storage2; switch (bits) { case 16: { f16 flt; memcpy(&flt, buffer, 2); storage1.flt.flt16 = flt; storage1.tag = flt16; storage2 = storage1; break; } case 32: { f32 flt; memcpy(&flt, buffer, 4); storage1.flt.flt32 = flt; storage1.tag = flt32; storage2 = storage1; break; } case 64: { f64 flt; memcpy(&flt, buffer, 8); storage1.flt.flt64 = flt; storage1.tag = flt64; storage2 = storage1; break; } case 80: { f80 flt; memcpy(&flt, buffer, 10); storage1.flt.flt80 = flt; storage1.tag = flt80; storage2 = storage1; break; } case 128: { f128 flt; memcpy(&flt, buffer, 16); storage1.flt.flt128 = flt; storage1.tag = flt128; storage2 = storage1; break; } default: __builtin_unreachable(); } return storage2; } extern int printf(const char *restrict format, ...); int main() { u8 buffer[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x3F}; struct Storage storage = readFromMemory(buffer, 128); u64 repr[2]; memcpy(repr, &storage.flt.flt128, 16); printf("0x%016llX%016llX\n", repr[1], repr[0]); } compile with gcc -O1. it prints 0x00000000004000000000000000000000 however the correct answer is 0x3FFF0000000000000000000000000000 which is what clang prints.