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