Recommendation: Swift does not define 'consume' ordering.
C 'consume' operations are directly inherited from the C implementation. Presumably, clang will emit an acquire before returning to Swift code. Apparently other C compilers do the same, but there's no reason for Swift to define that behavior.
Swift (and C/C++) programmers who know with certainty that they need consume-like ordering (i.e. 'acquire' is too expensive) must use 'relaxed' ordering and should read about the rules of "semantic dependence":
More general guidance:
Programmers who aren't sure what they need should always use 'seq_cst', "sequential consistency".... it won't be significantly worse than what clang does for 'consume'!
Programmers who are sure they don't need "sequential consistency", but still need to order multiple loads/reads should use 'acquire'.
The only reason anyone would be interested in 'consume' semantics (which we should keep hidden as much as possible) is that 'acquire' does not meet their performance requirements. They need to be redirected to 'relaxed' with appropriate caveats.
My argument is based on these premises:
The introduction of C++ 'consume' ordering created a new category of undefined behavior in existing well-engineered code without accomplishing anything useful.
Regardless of the C++ standard, programmers who need "semantic dependence" need to ensure that "Subsequent execution must not lead to a situation where there is only one possible value for the variable that is intended to carry the dependency." There's no reasonable way for a compiler to automatically preserve data dependence under all possible circumstances.
In the compiler, there's no useful difference between C++ 'relaxed' vs. C++ 'consume'. If we actually wanted programmers who need the semantics of data dependence to use 'consume' ordering, then both 'relax' and 'consume' should be lowered to LLVM 'monotonic'.
Previously in this thread, I mentioned "tightening LLVM's treatment of unordered/monotonic". I don't think there's anything that needs to be fixed. We just need to agree that the compiler shouldn't actively break code that follows the rules of "semantic dependence" by, say, materializing pointer comparisons out of thin air.
Currently, clang degrades C++ 'consume' to 'acquire'. I can only guess this is meant to punish programmers who try to use 'consume'. So, if they really want "semantic dependence", and are willing to follow the rules, then they need to use 'relaxed' instead. The compiler has given them no other choice.
If making clang compliant to the letter of the standard really takes priority over usefulness, and we were not actively trying to deprecate 'consume', then a sensible middle-ground would be for the compiler to optimize 'consume' as if it had 'acquire' semantics, but emit a regular load instruction.
This is partially moot because C++ 'consume' and associated craziness will be deprecated in some future standard. I don't know what will happen in the C standard.
I think the overall situation we're in now is:
No one should ever use 'consume'.
Programmers who need 'consume'-like ordering should use 'relaxed' and know the rules for protecting themselves against the compiler.
Hopefully in the near future, dependence semantics will be formalized in C++ as a smart-pointer-like dependence-carrying type so the compiler can enforce those rules.
Swift should follow suit when it provides native atomics and define a dependence-carrying wrapper type.
All the existing code that was written using 'relaxed' ordering and follows "semantic dependence" rules should continue to be considered standards compliant, and programmers could continue to write code this way as long as they know the rules. The standard shouldn't retroactively consider it undefined behavior.