[Bug middle-end/87237] __atomic_load on 4-byte-sized, 1-byte-aligned struct is not atomic

2018-09-11 Thread richard-gccbugzilla at metafoo dot co.uk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87237

--- Comment #4 from Richard Smith  ---
(In reply to Alexander Monakov from comment #3)
> With GCC size/align are 3/1 while with Clang it's 4/4 as you said

Oh sorry, you're right, I'd forgotten about this ABI discrepancy. We really
need to get the psABI fixed to say one way or the other! :)

[Bug middle-end/87237] __atomic_load on 4-byte-sized, 1-byte-aligned struct is not atomic

2018-09-11 Thread amonakov at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87237

--- Comment #3 from Alexander Monakov  ---
(In reply to Richard Smith from comment #2)
> I think that's only true for objects whose size corresponds to that of a
> fundamental type. Consider:
> 
> struct B { char c[3]; };
> 
> Here, an atomic object of type B (eg, _Atomic(B) or std::atomic) would
> have size=4, align=4, and yet GCC treats B as having an alignment of 1 for
> the purpose of atomic accesses.

No, this does not appear to be true. With GCC size/align are 3/1 while with
Clang it's 4/4 as you said:

struct B { char c[3];};

_Atomic struct B b;

int a = _Alignof b;
int s = sizeof b;

s:
.long   3
[...]
a:
.long   1
.comm   b,3,1

[Bug middle-end/87237] __atomic_load on 4-byte-sized, 1-byte-aligned struct is not atomic

2018-09-11 Thread richard-gccbugzilla at metafoo dot co.uk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87237

--- Comment #2 from Richard Smith  ---
(In reply to Alexander Monakov from comment #1)
> GCC assumes the access is sufficiently aligned for an atomic object of
> corresponding type

I think that's only true for objects whose size corresponds to that of a
fundamental type. Consider:

struct B { char c[3]; };

Here, an atomic object of type B (eg, _Atomic(B) or std::atomic) would have
size=4, align=4, and yet GCC treats B as having an alignment of 1 for the
purpose of atomic accesses.

Rather, GCC appears (from its external behavior) to consider only the object
size and not the alignment for atomic accesses, and assumes power-of-2-sized
objects to be aligned to their size (or to the maximum alignment of a
fundamental type, whichever is lower).

There exists code that assumes that GCC behaves as documented in this regard.
For example, libc++'s std::atomic makes this assumption, and as a result,
std::atomic is not atomic when using gcc with libc++. For that reason,
changing GCC to avoid the unwarranted alignment assumption seems superior to me
to updating the documentation to match the behavior. (For what it's worth, I
recently fixed Clang to behave per the GCC documentation in this regard; Clang
used to fall back to a libcall for the underaligned case, but would mistakenly
call the "optimized" library routines that assume the object is sufficiently
aligned.)

[Bug middle-end/87237] __atomic_load on 4-byte-sized, 1-byte-aligned struct is not atomic

2018-09-11 Thread amonakov at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87237

Alexander Monakov  changed:

   What|Removed |Added

 CC||amonakov at gcc dot gnu.org

--- Comment #1 from Alexander Monakov  ---
GCC assumes the access is sufficiently aligned for an atomic object of
corresponding type, so either the documentation needs to mention that, or gcc
should stop "upgrading" alignment.

typedef int i1 __attribute__((aligned(1)));

int f(i1 *p)
{
  return __atomic_load_n(p, __ATOMIC_RELAXED);
}


We expand the load to (note A32)

(insn 6 3 7 2 (set (reg:SI 87 [ _4 ])
(mem/v:SI (reg/v/f:DI 89 [ p ]) [-1  S4 A32])) ttt.c:5 -1
 (nil))