This is an archive of the discontinued LLVM Phabricator instance.

Allow build without __c11_atomic_fetch_nand
AbandonedPublic

Authored by brooks on May 25 2022, 10:07 AM.

Details

Summary

The atomic_fetch_nand libcalls added in 6ea2431d3f10 require
the
c11_atomic_fetch_nand builtin which means compiler-rt
can't be built with an older verison of clang. Change this
so the locked implementation is used any time the builtin is
not available.

Diff Detail

Event Timeline

brooks created this revision.May 25 2022, 10:07 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 25 2022, 10:07 AM
brooks requested review of this revision.May 25 2022, 10:07 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 25 2022, 10:07 AM
Herald added a subscriber: Restricted Project. · View Herald Transcript

This pops up trying to build FreeBSD with LLVM 14 integrated using clang from LLVM 13 and not building a bootstrap toolchain.

lkail added a comment.EditedMay 26 2022, 5:06 AM

I'm not sure if it's appropriate to use clang and compiler-rt in different versions. Added more reviewers for discussion.

The current version doesn't have the right semantics: if the pointer is lock-free, you have to use a lock-free implementation (e.g. a cmpxchg loop).

In terms of whether we'd accept a patch, this code isn't really portable in the first place, but if it's necessary to build FreeBSD, we could add a small hack, I guess.

(On a more general note, FreeBSD should probably consider pursuing a different solution to atomic libcalls; this implementation doesn't work correctly if you try to share an atomic variable across multiple shared objects.)

I'm not sure if it's appropriate to use clang and compiler-rt in different versions. Added more reviewers for discussion.

As consumers of compiler-rt in FreeBSD, we expect to be able to build compiler-rt (or previously libgcc) with an external compiler which might not match exactly and can generally be somewhat older than the integrated one (e.g., we'd been building with llvm 13 and we support building with gcc 9). We've been doing this since we started our switch to clang well over a decade ago.

The other alternative I considered was to not generate __atomic_fetch_nand_* symbols at all if __c11_atomic_fetch_nand isn't available. It sounds like this might be the more correct approach. It has the downside that the symbols in FreeBSD's libraries can variety depending on which compiler we're using, but doesn't emit incorrect libcalls.

The other alternative I considered was to not generate atomic_fetch_nand_* symbols at all if c11_atomic_fetch_nand isn't available

I'd accept that, sure.

theraven added a comment.EditedMay 27 2022, 1:36 AM

I don't believe this version is correct. It unconditionally does the lock. If code using this is mixed with code where the compiler inlines the operation then the two operations will not be atomic with respect to eachother. Worse, an atomic-fetch-nand is not atomic with respect to any other operation (e.g. an atomic increment). This needs to have the same if (lockfree(ptr) guard and do a CAS loop in the is-lock-free case.

Edit: In between writing this and realising that Fabricator hadn't actually submitted the comment, I notice that efriedma has made the same observation.

I've added D126710 as an alternative that just doesn't create the libcall functions.

brooks abandoned this revision.Jun 1 2022, 10:52 AM

D126710 was committed