This is an archive of the discontinued LLVM Phabricator instance.

Atomics: support __c11_* calls on _Atomic struct types
ClosedPublic

Authored by t.p.northover on Oct 19 2015, 2:05 PM.

Details

Reviewers
compnerd
Summary

When a struct's size is not a power of 2, the corresponding _Atomic() type is promoted to the nearest. We already correctly handled normal C++ expressions of this form, but direct calls to the __c11_atomic_whatever builtins ended up performing dodgy operations on the smaller non-atomic types (e.g. memcpy too much). Later optimisations removed this as undefined behaviour.

This patch converts EmitAtomicExpr to allocate its temporaries at the full atomic width, sidestepping the issue.

It also tidies up that function a little: previously there was a confusing dual-return situation, where sometimes the result was returned as an RValue, other times stored into a user-provided destination. I don't think this is necessary (it dates back from the very beginning of CGAtomic.cpp).

Diff Detail

Repository
rL LLVM

Event Timeline

t.p.northover retitled this revision from to Atomics: support __c11_* calls on _Atomic struct types.
t.p.northover updated this object.
t.p.northover set the repository for this revision to rL LLVM.
t.p.northover added a subscriber: cfe-commits.
compnerd accepted this revision.Oct 27 2015, 7:49 PM
compnerd added a reviewer: compnerd.
compnerd added a subscriber: compnerd.
compnerd added inline comments.
lib/CodeGen/CGAtomic.cpp
782

s/Atomics/AI/? Or perhaps Atomic?

1021

It feels like it might be nice to hoist the CreateBitCast.

This revision is now accepted and ready to land.Oct 27 2015, 7:49 PM
t.p.northover closed this revision.Nov 9 2015, 11:59 AM

Thanks Saleem, committed in r252507.

lib/CodeGen/CGAtomic.cpp
782

Atomics seems to be the dominant name in the file, though both that and AI are used.

1021

That doesn't quite work. Some atomics don't have a Dest (e.g. c11_atomic_store produces no value) so you'd have to move the RValTy->isVoidType() check up, but others can have a void RValTy yet still need to store (e.g. if an "atomic_load(addr, &dest)" is converted into a "dest = atomic_load_n(addr)" call).

The matrix of possibilities is a horrible mess.