https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115954

            Bug ID: 115954
           Summary: Alignment of _Atomic structs incompatible between GCC
                    and LLVM
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: wilco at gcc dot gnu.org
  Target Milestone: ---

The following code shows ABI inconsistencies between GCC and LLVM:

#include <stdio.h>
#include <stdatomic.h>
#include <stdalign.h>

_Atomic struct A3 { char a[3]; } a3;
_Atomic struct A7 { char a[7]; } a7;
_Atomic struct A8 { char a[8]; } a8;
_Atomic struct A9 { char a[9]; } a9;
_Atomic struct A16 { char a[16]; } a16;

int main (void)
{
   printf("size %ld align %ld lockfree %d\n", sizeof (a3), alignof (a3),
atomic_is_lock_free (&a3));
   printf("size %ld align %ld lockfree %d\n", sizeof (a7), alignof (a7),
atomic_is_lock_free (&a7));
   printf("size %ld align %ld lockfree %d\n", sizeof (a8), alignof (a8),
atomic_is_lock_free (&a8));
   printf("size %ld align %ld lockfree %d\n", sizeof (a9), alignof (a9),
atomic_is_lock_free (&a9));
   printf("size %ld align %ld lockfree %d\n", sizeof (a16), alignof (a16),
atomic_is_lock_free (&a16));
   return 0;
}

Compiled with GCC -O2 -latomic I get this on AArch64:

size 3 align 1 lockfree 1
size 7 align 1 lockfree 1
size 8 align 8 lockfree 1
size 9 align 1 lockfree 0
size 16 align 16 lockfree 0

However LLVM reports:

size 4 align 4 lockfree 1
size 8 align 8 lockfree 1
size 8 align 8 lockfree 1
size 16 align 16 lockfree 1
size 16 align 16 lockfree 1

The same is true for x86_64 GCC:

size 3 align 1 lockfree 0
size 7 align 1 lockfree 1  (due to alignment in libatomic)
size 8 align 8 lockfree 1
size 9 align 1 lockfree 0
size 16 align 16 lockfree 0

and LLVM:

size 4 align 4 lockfree 1
size 8 align 8 lockfree 1
size 8 align 8 lockfree 1
size 16 align 16 lockfree 0
size 16 align 16 lockfree 0

Increasing the alignment of small _Atomic structs to a power of 2 means these
will always be lock free rather than sometimes depending on alignment.

This also has the nice property that all types smaller than the maximum
supported atomic size are always lock free so there is no need to make
libatomic calls.

Reply via email to