https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114080
Bug ID: 114080 Summary: Inconsistent handling of 128bit ints between GCC versions Product: gcc Version: 13.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: rapier at psc dot edu Target Milestone: --- I'm attempting to XOR 2 128bit ints in 13.2.1 and am consistently getting a segfault when optimization is set at -O2. The problem is that this behaviour doesn't happen when using older versions of GCC. As an aside, what we are trying to do is XOR a stream of data as quickly as possible so using 128bit ints reduced the number of XORs we need to perform. I've been using the following MWE to test this: #include <stdlib.h> #include <stdio.h> #include <stdint.h> /* just informative */ void printAlignment(void *ptr, char *label) { for (int ta = 64; ta > 0; ta /= 2) if ((uint64_t) ptr % ta == 0) { printf("%s is %3u-bit aligned (%p)\n", label, ta * 8, ptr); return; } } /* offset is the desired alignment in BYTES */ /* startptr exists to free it later */ void * misaligned_128bit_malloc(size_t offset, void **startptr) { *startptr = malloc(16 + offset); /* 16 bytes = 128 bits */ void * ret = *startptr + 1; /* force minimal misalignment */ while ((uint64_t) ret % offset != 0) /* iterate until aligned */ ret = ret + 1; return ret; } int main() { __uint128_t *dstp, *srcp, *bufp; void *dst, *src, *buf; dstp = misaligned_128bit_malloc(16, &dst); srcp = misaligned_128bit_malloc(4, &src); bufp = misaligned_128bit_malloc(8, &buf); printAlignment(dstp, "dst"); printAlignment(srcp, "src"); printAlignment(bufp, "buf"); *dstp = 0; /* fill in some dummy data */ for(int i=0; i<16; i++) ((uint8_t *) srcp)[i] = 0x10; for(int i=0; i<16; i++) ((uint8_t *) bufp)[i] = i << 3; printf("src: 0x%016lx%016lx\n", (uint64_t) (*srcp >> 64), (uint64_t) (*srcp)); printf("buf: 0x%016lx%016lx\n", (uint64_t) (*bufp >> 64), (uint64_t) (*bufp)); printf("dst: 0x%016lx%016lx\n", (uint64_t) (*dstp >> 64), (uint64_t) (*dstp)); printf("xoring...\n"); fflush(stdout); *dstp = *srcp ^ *bufp; printf("success!\n"); printf("dst: 0x%016lx%016lx\n", (uint64_t) (*dstp >> 64), (uint64_t) (*dstp)); free(dst); free(src); free(buf); return 0; } Results: gcc version 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04) ~/test$ gcc -O2 mwe.c -o mwe $ ./mwe dst is 128-bit aligned (0x5637185eb2b0) src is 32-bit aligned (0x5637185eb2d4) buf is 64-bit aligned (0x5637185eb2f8) src: 0x10101010101010101010101010101010 buf: 0x78706860585048403830282018100800 dst: 0x00000000000000000000000000000000 xoring... success! dst: 0x68607870484058502820383008001810 gcc version 13.2.1 20231011 (Red Hat 13.2.1-4) (GCC) $ gcc -O2 mwe.c -o mwe $ ./mwe dst is 128-bit aligned (0x1cbc2b0) src is 32-bit aligned (0x1cbc2d4) buf is 64-bit aligned (0x1cbc2f8) src: 0x10101010101010101010101010101010 buf: 0x78706860585048403830282018100800 dst: 0x00000000000000000000000000000000 xoring... Segmentation fault (core dumped) gcc version 13.2.1 20231011 (Red Hat 13.2.1-4) (GCC) $ gcc -O0 mwe.c -o mwe $ ./mwe dst is 128-bit aligned (0xb022b0) src is 32-bit aligned (0xb022d4) buf is 64-bit aligned (0xb022f8) src: 0x10101010101010101010101010101010 buf: 0x78706860585048403830282018100800 dst: 0x00000000000000000000000000000000 xoring... success! dst: 0x68607870484058502820383008001810 I don't know if this is a bug in 13.2.1 or if the might be undefined behaviour that is now being enforced with a segfault. I've looked through the release documents for 13.2.1 and didn't see anything that seems to indicate the latter but I might have missed it. Any help or insight you could provide would be appreciated. Thanks for your time, Chris