This is an archive of the discontinued LLVM Phabricator instance.

MS ABI: Implement /volatile:ms
ClosedPublic

Authored by majnemer on Feb 12 2015, 1:32 AM.

Details

Summary

The /volatile:ms semantics turn volatile loads and stores into atomic
acquire and release operations. This distinction is important because
volatile memory operations do not form a happens-before relationship
with non-atomic memory. This means that a volatile store is not
sufficient for implementing a mutex unlock routine.

Diff Detail

Event Timeline

majnemer updated this revision to Diff 19811.Feb 12 2015, 1:32 AM
majnemer retitled this revision from to MS ABI: Implement /volatile:ms.
majnemer updated this object.
majnemer added reviewers: rnk, hansw, rsmith.
majnemer added a subscriber: Unknown Object (MLST).
ABataev added inline comments.
lib/CodeGen/CGStmtOpenMP.cpp
836

I'd say that if IsSeqCst is false, Atomic Ordering must be Monotonic rather than Unordered.

  1. According to OpenMP 4.0 "non-sequentially consistent atomic construct has the same semantics as a

memory_order_relaxed atomic operation in C++11/C11.".

  1. According to http://llvm.org/docs/Atomics.html "Monotonic... This corresponds to the C++11/C11 memory_order_relaxed"
timurrrr added a subscriber: timurrrr.

Dima might want to take a look.

dvyukov added inline comments.Feb 12 2015, 2:51 AM
lib/CodeGen/CGAtomic.cpp
1011

I don't get the !AI.shouldUseLibcall() part.
If the atomic operation would use a libcall, then you don't turn volatile access into atomic? Why? How is it related to libcalls?

1017

Same here. How presence of builtin atomic affects this?

1018

In volatileIsAtomic you check that the value is volatile, but here you don't. Please make then consistent. Either check in both or don't check in both.

lib/CodeGen/CGExpr.cpp
1141

Won't this be overly fragile?
MS semantics effectively turn volatile variables into atomic variables. So the current isAtomicType becomes effectively useless, and whoever uses isAtomicType must also remember to add volatileIsAtomic. And there is nothing that reminds of that. Ty->isAtomicType() looks pretty much like what you need.
It would be less fragile if you fix the isAtomic predicate itself.
But I know very little about llvm internals, maybe it is not possible, or a bad idea for some other reason. I don't know.

lib/CodeGen/CodeGenFunction.h
2159

Here you use IsSeqCst, but in EmitAtomicStore you use AO.
Please make them consistent.

majnemer added inline comments.Feb 12 2015, 10:22 AM
lib/CodeGen/CGAtomic.cpp
1011

shouldUseLibcall means that than atomic operation is not suitably aligned or sized to be lowered to a load atomic or store atomic instruction. These conditions are identical to the conditions that MSVC uses to say that a volatile load or store will also have acquire or release semantics.

1017

As I mentioned earlier, not all volatile loads or stores will turn into acquire or release loads and stores.

1018

I can't check it here because the type being passed in might not be qualified with volatile, it might be a record with a volatile field. I'd rather not make everyone who calls the other overload to have to manually check LV.isVolatile() || hasVolatileMember(LV.getType()).

I'll just rename one of these to make it clear what it does.

lib/CodeGen/CGExpr.cpp
1141

I don't think that is semantically correct. isAtomicType() is used for types which are "qualified" with _Atomic.

Moreover, we would still need to be able to determine the different from a real _Atomic qualified type and a MS volatile type in order to determine the memory operation's order.

lib/CodeGen/CGStmtOpenMP.cpp
836

Good catch, will do.

lib/CodeGen/CodeGenFunction.h
2159

Sure, will do.

dvyukov added inline comments.Feb 12 2015, 10:29 AM
lib/CodeGen/CGAtomic.cpp
1011

Doesn't shouldUseLibcall also mean that the value is too fat for backend codegen, so just call a library functions (e.g. a 64-bit store on a 32-bit platform)? That's what I figure out from the name. Perhaps deserves a comment.

majnemer updated this revision to Diff 19848.Feb 12 2015, 11:10 AM
  • Address review feedback.
  • Cleanup argument parsing
rnk accepted this revision.Feb 12 2015, 1:48 PM
rnk edited edge metadata.

Looks good to me. Feel free to gather other feedback.

lib/CodeGen/CGAtomic.cpp
1017

Early return false if !CGOpts.MSVolatile before checking struct types for volatile members (not O(1))?

1023

Make the leading letter lowercase? "LValueIsSuitable..." starts with an initialism, so it stays upper.

lib/CodeGen/CodeGenFunction.h
2152–2153

Big enough to make not inline?

2173

ditto

This revision is now accepted and ready to land.Feb 12 2015, 1:48 PM
hans added a subscriber: hans.Feb 12 2015, 3:07 PM

I just looked at the flag stuff since others seem to have looked at the rest.

include/clang/Driver/CLCompatOptions.td
205

nit: I'd skip "C++": just "standard semantics" is shorter (and more accurate in the C case I guess)

207

nit: there's no "will" in the :iso flag description. I'd leave it out here too. Would it be less accurate to just say that loads and stores are atomic?

test/Driver/cl-options.c
126 ↗(On Diff #19848)

maybe add a test without /volatile and check that -fms-volatile doesn't get passed by default?

majnemer added inline comments.Feb 12 2015, 11:51 PM
include/clang/Driver/CLCompatOptions.td
205

Done.

207

Done.

lib/CodeGen/CGAtomic.cpp
1017

Sema has already figured it out so it is cheap to query.

1023

Done.

lib/CodeGen/CodeGenFunction.h
2152–2153

Done.

2173

Done.

test/Driver/cl-options.c
126 ↗(On Diff #19848)

-fms-volatile is passed by default depending on whether or not you are targeting x86.

This revision was automatically updated to reflect the committed changes.