[Bug c/112521] New: __float128 miscompilation: assignment as an aggregate field

2023-11-13 Thread andrew at ziglang dot org via Gcc-bugs
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 0x0040 however the
correct answer is 0x3FFF which is what clang
prints.

[Bug tree-optimization/112521] [11/12/13/14 Regression] __float128 miscompilation: assignment as an aggregate field

2023-11-13 Thread andrew at ziglang dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112521

--- Comment #7 from Andrew Kelley  ---
Thank you for looking into it!