<div dir="ltr">I reverted this in r229123, it caused PR22577.</div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Feb 12, 2015 at 11:55 PM, David Majnemer <span dir="ltr"><<a href="mailto:david.majnemer@gmail.com" target="_blank">david.majnemer@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: majnemer<br>
Date: Fri Feb 13 01:55:47 2015<br>
New Revision: 229082<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=229082&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=229082&view=rev</a><br>
Log:<br>
MS ABI: Implement /volatile:ms<br>
<br>
The /volatile:ms semantics turn volatile loads and stores into atomic<br>
acquire and release operations.  This distinction is important because<br>
volatile memory operations do not form a happens-before relationship<br>
with non-atomic memory.  This means that a volatile store is not<br>
sufficient for implementing a mutex unlock routine.<br>
<br>
Differential Revision: <a href="http://reviews.llvm.org/D7580" target="_blank">http://reviews.llvm.org/D7580</a><br>
<br>
Added:<br>
    cfe/trunk/test/CodeGen/ms-volatile.c<br>
Modified:<br>
    cfe/trunk/include/clang/Driver/CLCompatOptions.td<br>
    cfe/trunk/include/clang/Driver/Options.td<br>
    cfe/trunk/include/clang/Frontend/CodeGenOptions.def<br>
    cfe/trunk/lib/CodeGen/CGAtomic.cpp<br>
    cfe/trunk/lib/CodeGen/CGExpr.cpp<br>
    cfe/trunk/lib/CodeGen/CGExprAgg.cpp<br>
    cfe/trunk/lib/CodeGen/CGExprComplex.cpp<br>
    cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp<br>
    cfe/trunk/lib/CodeGen/CodeGenFunction.h<br>
    cfe/trunk/lib/Driver/Tools.cpp<br>
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp<br>
    cfe/trunk/test/Driver/cl-options.c<br>
    cfe/trunk/test/OpenMP/atomic_read_codegen.c<br>
<br>
Modified: cfe/trunk/include/clang/Driver/CLCompatOptions.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CLCompatOptions.td?rev=229082&r1=229081&r2=229082&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CLCompatOptions.td?rev=229082&r1=229081&r2=229082&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Driver/CLCompatOptions.td (original)<br>
+++ cfe/trunk/include/clang/Driver/CLCompatOptions.td Fri Feb 13 01:55:47 2015<br>
@@ -157,6 +157,7 @@ def _SLASH_arch : CLCompileJoined<"arch:<br>
   HelpText<"Set architecture for code generation">;<br>
<br>
 def _SLASH_M_Group : OptionGroup<"</M group>">, Group<cl_compile_Group>;<br>
+def _SLASH_volatile_Group : OptionGroup<"</volatile group>">, Group<cl_compile_Group>;<br>
<br>
 def _SLASH_EH : CLJoined<"EH">, HelpText<"Exception handling model">;<br>
 def _SLASH_EP : CLFlag<"EP">,<br>
@@ -201,7 +202,10 @@ def _SLASH_TC : CLCompileFlag<"TC">, Hel<br>
 def _SLASH_Tp : CLCompileJoinedOrSeparate<"Tp">,<br>
   HelpText<"Specify a C++ source file">, MetaVarName<"<filename>">;<br>
 def _SLASH_TP : CLCompileFlag<"TP">, HelpText<"Treat all source files as C++">;<br>
-<br>
+def _SLASH_volatile_iso : Option<["/", "-"], "volatile:iso", KIND_FLAG>, Group<_SLASH_volatile_Group>,<br>
+  Flags<[CLOption, DriverOption]>, HelpText<"Volatile loads and stores have standard semantics">;<br>
+def _SLASH_volatile_ms  : Option<["/", "-"], "volatile:ms", KIND_FLAG>, Group<_SLASH_volatile_Group>,<br>
+  Flags<[CLOption, DriverOption]>, HelpText<"Volatile loads and stores have acquire and release semantics">;<br>
<br>
 // Ignored:<br>
<br>
@@ -220,7 +224,6 @@ def _SLASH_Ob2 : CLIgnoredFlag<"Ob2">;<br>
 def _SLASH_RTC : CLIgnoredJoined<"RTC">;<br>
 def _SLASH_sdl : CLIgnoredFlag<"sdl">;<br>
 def _SLASH_sdl_ : CLIgnoredFlag<"sdl-">;<br>
-def _SLASH_volatile_iso : CLIgnoredFlag<"volatile:iso">;<br>
 def _SLASH_w : CLIgnoredJoined<"w">;<br>
 def _SLASH_Zc_auto : CLIgnoredFlag<"Zc:auto">;<br>
 def _SLASH_Zc_forScope : CLIgnoredFlag<"Zc:forScope">;<br>
@@ -281,7 +284,6 @@ def _SLASH_Qpar : CLFlag<"Qpar">;<br>
 def _SLASH_Qvec_report : CLJoined<"Qvec-report">;<br>
 def _SLASH_u : CLFlag<"u">;<br>
 def _SLASH_V : CLFlag<"V">;<br>
-def _SLASH_volatile_ms : CLFlag<"volatile:ms">;<br>
 def _SLASH_WL : CLFlag<"WL">;<br>
 def _SLASH_Wp64 : CLFlag<"Wp64">;<br>
 def _SLASH_X : CLFlag<"X">;<br>
<br>
Modified: cfe/trunk/include/clang/Driver/Options.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=229082&r1=229081&r2=229082&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=229082&r1=229081&r2=229082&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Driver/Options.td (original)<br>
+++ cfe/trunk/include/clang/Driver/Options.td Fri Feb 13 01:55:47 2015<br>
@@ -628,6 +628,7 @@ def fms_extensions : Flag<["-"], "fms-ex<br>
   HelpText<"Accept some non-standard constructs supported by the Microsoft compiler">;<br>
 def fms_compatibility : Flag<["-"], "fms-compatibility">, Group<f_Group>, Flags<[CC1Option]>,<br>
   HelpText<"Enable full Microsoft Visual C++ compatibility">;<br>
+def fms_volatile : Joined<["-"], "fms-volatile">, Group<f_Group>, Flags<[CC1Option]>;<br>
 def fmsc_version : Joined<["-"], "fmsc-version=">, Group<f_Group>, Flags<[DriverOption, CoreOption]>,<br>
   HelpText<"Microsoft compiler version number to report in _MSC_VER (0 = don't define it (default))">;<br>
 def fms_compatibility_version<br>
<br>
Modified: cfe/trunk/include/clang/Frontend/CodeGenOptions.def<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CodeGenOptions.def?rev=229082&r1=229081&r2=229082&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CodeGenOptions.def?rev=229082&r1=229081&r2=229082&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Frontend/CodeGenOptions.def (original)<br>
+++ cfe/trunk/include/clang/Frontend/CodeGenOptions.def Fri Feb 13 01:55:47 2015<br>
@@ -68,6 +68,7 @@ CODEGENOPT(LessPreciseFPMAD  , 1, 0) ///<br>
                                      ///< be generated.<br>
 CODEGENOPT(MergeAllConstants , 1, 1) ///< Merge identical constants.<br>
 CODEGENOPT(MergeFunctions    , 1, 0) ///< Set when -fmerge-functions is enabled.<br>
+CODEGENOPT(MSVolatile        , 1, 0) ///< Set when /volatile:ms is enabled.<br>
 CODEGENOPT(NoCommon          , 1, 0) ///< Set when -fno-common or C++ is enabled.<br>
 CODEGENOPT(NoDwarfDirectoryAsm , 1, 0) ///< Set when -fno-dwarf-directory-asm is<br>
                                        ///< enabled.<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGAtomic.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGAtomic.cpp?rev=229082&r1=229081&r2=229082&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGAtomic.cpp?rev=229082&r1=229081&r2=229082&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGAtomic.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGAtomic.cpp Fri Feb 13 01:55:47 2015<br>
@@ -1006,9 +1006,45 @@ RValue AtomicInfo::convertIntToValue(llv<br>
   return convertTempToRValue(Temp, ResultSlot, Loc);<br>
 }<br>
<br>
+/// An LValue is a candidate for having its loads and stores be made atomic if<br>
+/// we are operating under /volatile:ms *and* the LValue itself is volatile and<br>
+/// performing such an operation can be performed without a libcall.<br>
+bool CodeGenFunction::LValueIsSuitableForInlineAtomic(LValue LV) {<br>
+  AtomicInfo AI(*this, LV);<br>
+  bool IsVolatile = LV.isVolatile() || hasVolatileMember(LV.getType());<br>
+  // An atomic is inline if we don't need to use a libcall.<br>
+  bool AtomicIsInline = !AI.shouldUseLibcall();<br>
+  return CGM.getCodeGenOpts().MSVolatile && IsVolatile && AtomicIsInline;<br>
+}<br>
+<br>
+/// An type is a candidate for having its loads and stores be made atomic if<br>
+/// we are operating under /volatile:ms *and* we know the access is volatile and<br>
+/// performing such an operation can be performed without a libcall.<br>
+bool CodeGenFunction::typeIsSuitableForInlineAtomic(QualType Ty,<br>
+                                                    bool IsVolatile) const {<br>
+  // An atomic is inline if we don't need to use a libcall (e.g. it is builtin).<br>
+  bool AtomicIsInline = getContext().getTargetInfo().hasBuiltinAtomic(<br>
+      getContext().getTypeSize(Ty), getContext().getTypeAlign(Ty));<br>
+  return CGM.getCodeGenOpts().MSVolatile && IsVolatile && AtomicIsInline;<br>
+}<br>
+<br>
+RValue CodeGenFunction::EmitAtomicLoad(LValue LV, SourceLocation SL,<br>
+                                       AggValueSlot Slot) {<br>
+  llvm::AtomicOrdering AO;<br>
+  bool IsVolatile = LV.isVolatileQualified();<br>
+  if (LV.getType()->isAtomicType()) {<br>
+    AO = llvm::SequentiallyConsistent;<br>
+  } else {<br>
+    AO = llvm::Acquire;<br>
+    IsVolatile = true;<br>
+  }<br>
+  return EmitAtomicLoad(LV, SL, AO, IsVolatile, Slot);<br>
+}<br>
+<br>
 /// Emit a load from an l-value of atomic type.  Note that the r-value<br>
 /// we produce is an r-value of the atomic *value* type.<br>
 RValue CodeGenFunction::EmitAtomicLoad(LValue src, SourceLocation loc,<br>
+                                       llvm::AtomicOrdering AO, bool IsVolatile,<br>
                                        AggValueSlot resultSlot) {<br>
   AtomicInfo atomics(*this, src);<br>
   LValue LVal = atomics.getAtomicLValue();<br>
@@ -1060,11 +1096,11 @@ RValue CodeGenFunction::EmitAtomicLoad(L<br>
   // Okay, we're doing this natively.<br>
   llvm::Value *addr = atomics.emitCastToAtomicIntPointer(SrcAddr);<br>
   llvm::LoadInst *load = Builder.CreateLoad(addr, "atomic-load");<br>
-  load->setAtomic(llvm::SequentiallyConsistent);<br>
+  load->setAtomic(AO);<br>
<br>
   // Other decoration.<br>
   load->setAlignment(src.getAlignment().getQuantity());<br>
-  if (src.isVolatileQualified())<br>
+  if (IsVolatile)<br>
     load->setVolatile(true);<br>
   if (src.getTBAAInfo())<br>
     CGM.DecorateInstruction(load, src.getTBAAInfo());<br>
@@ -1161,12 +1197,27 @@ llvm::Value *AtomicInfo::convertRValueTo<br>
                                        getAtomicAlignment().getQuantity());<br>
 }<br>
<br>
+void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue lvalue,<br>
+                                      bool isInit) {<br>
+  bool IsVolatile = lvalue.isVolatileQualified();<br>
+  llvm::AtomicOrdering AO;<br>
+  if (lvalue.getType()->isAtomicType()) {<br>
+    AO = llvm::SequentiallyConsistent;<br>
+  } else {<br>
+    AO = llvm::Release;<br>
+    IsVolatile = true;<br>
+  }<br>
+  return EmitAtomicStore(rvalue, lvalue, AO, IsVolatile, isInit);<br>
+}<br>
+<br>
 /// Emit a store to an l-value of atomic type.<br>
 ///<br>
 /// Note that the r-value is expected to be an r-value *of the atomic<br>
 /// type*; this means that for aggregate r-values, it should include<br>
 /// storage for any padding that was necessary.<br>
-void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue dest, bool isInit) {<br>
+void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue dest,<br>
+                                      llvm::AtomicOrdering AO, bool IsVolatile,<br>
+                                      bool isInit) {<br>
   // If this is an aggregate r-value, it should agree in type except<br>
   // maybe for address-space qualification.<br>
   assert(!rvalue.isAggregate() ||<br>
@@ -1209,11 +1260,11 @@ void CodeGenFunction::EmitAtomicStore(RV<br>
   llvm::StoreInst *store = Builder.CreateStore(intValue, addr);<br>
<br>
   // Initializations don't need to be atomic.<br>
-  if (!isInit) store->setAtomic(llvm::SequentiallyConsistent);<br>
+  if (!isInit) store->setAtomic(AO);<br>
<br>
   // Other decoration.<br>
   store->setAlignment(dest.getAlignment().getQuantity());<br>
-  if (dest.isVolatileQualified())<br>
+  if (IsVolatile)<br>
     store->setVolatile(true);<br>
   if (dest.getTBAAInfo())<br>
     CGM.DecorateInstruction(store, dest.getTBAAInfo());<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=229082&r1=229081&r2=229082&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=229082&r1=229081&r2=229082&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Fri Feb 13 01:55:47 2015<br>
@@ -1136,7 +1136,7 @@ llvm::Value *CodeGenFunction::EmitLoadOf<br>
   }<br>
<br>
   // Atomic operations have to be done on integral types.<br>
-  if (Ty->isAtomicType()) {<br>
+  if (Ty->isAtomicType() || typeIsSuitableForInlineAtomic(Ty, Volatile)) {<br>
     LValue lvalue = LValue::MakeAddr(Addr, Ty,<br>
                                      CharUnits::fromQuantity(Alignment),<br>
                                      getContext(), TBAAInfo);<br>
@@ -1255,7 +1255,8 @@ void CodeGenFunction::EmitStoreOfScalar(<br>
<br>
   Value = EmitToMemory(Value, Ty);<br>
<br>
-  if (Ty->isAtomicType()) {<br>
+  if (Ty->isAtomicType() ||<br>
+      (!isInit && typeIsSuitableForInlineAtomic(Ty, Volatile))) {<br>
     EmitAtomicStore(RValue::get(Value),<br>
                     LValue::MakeAddr(Addr, Ty,<br>
                                      CharUnits::fromQuantity(Alignment),<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=229082&r1=229081&r2=229082&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=229082&r1=229081&r2=229082&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Fri Feb 13 01:55:47 2015<br>
@@ -212,7 +212,7 @@ void AggExprEmitter::EmitAggLoadOfLValue<br>
   LValue LV = CGF.EmitLValue(E);<br>
<br>
   // If the type of the l-value is atomic, then do an atomic load.<br>
-  if (LV.getType()->isAtomicType()) {<br>
+  if (LV.getType()->isAtomicType() || CGF.LValueIsSuitableForInlineAtomic(LV)) {<br>
     CGF.EmitAtomicLoad(LV, E->getExprLoc(), Dest);<br>
     return;<br>
   }<br>
@@ -865,7 +865,8 @@ void AggExprEmitter::VisitBinAssign(cons<br>
     LValue LHS = CGF.EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);<br>
<br>
     // That copy is an atomic copy if the LHS is atomic.<br>
-    if (LHS.getType()->isAtomicType()) {<br>
+    if (LHS.getType()->isAtomicType() ||<br>
+        CGF.LValueIsSuitableForInlineAtomic(LHS)) {<br>
       CGF.EmitAtomicStore(Dest.asRValue(), LHS, /*isInit*/ false);<br>
       return;<br>
     }<br>
@@ -882,7 +883,8 @@ void AggExprEmitter::VisitBinAssign(cons<br>
<br>
   // If we have an atomic type, evaluate into the destination and then<br>
   // do an atomic copy.<br>
-  if (LHS.getType()->isAtomicType()) {<br>
+  if (LHS.getType()->isAtomicType() ||<br>
+      CGF.LValueIsSuitableForInlineAtomic(LHS)) {<br>
     EnsureDest(E->getRHS()->getType());<br>
     Visit(E->getRHS());<br>
     CGF.EmitAtomicStore(Dest.asRValue(), LHS, /*isInit*/ false);<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGExprComplex.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprComplex.cpp?rev=229082&r1=229081&r2=229082&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprComplex.cpp?rev=229082&r1=229081&r2=229082&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGExprComplex.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGExprComplex.cpp Fri Feb 13 01:55:47 2015<br>
@@ -336,7 +336,8 @@ ComplexPairTy ComplexExprEmitter::EmitLo<br>
 /// specified value pointer.<br>
 void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, LValue lvalue,<br>
                                             bool isInit) {<br>
-  if (lvalue.getType()->isAtomicType())<br>
+  if (lvalue.getType()->isAtomicType() ||<br>
+      (!isInit && CGF.LValueIsSuitableForInlineAtomic(lvalue)))<br>
     return CGF.EmitAtomicStore(RValue::getComplex(Val), lvalue, isInit);<br>
<br>
   llvm::Value *Ptr = lvalue.getAddress();<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=229082&r1=229081&r2=229082&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=229082&r1=229081&r2=229082&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Fri Feb 13 01:55:47 2015<br>
@@ -829,8 +829,11 @@ static void EmitOMPAtomicReadExpr(CodeGe<br>
   assert(X->isLValue() && "X of 'omp atomic read' is not lvalue");<br>
   LValue XLValue = CGF.EmitLValue(X);<br>
   LValue VLValue = CGF.EmitLValue(V);<br>
-  RValue Res = XLValue.isGlobalReg() ? CGF.EmitLoadOfLValue(XLValue, Loc)<br>
-                                     : CGF.EmitAtomicLoad(XLValue, Loc);<br>
+  RValue Res = XLValue.isGlobalReg()<br>
+                   ? CGF.EmitLoadOfLValue(XLValue, Loc)<br>
+                   : CGF.EmitAtomicLoad(XLValue, Loc,<br>
+                                        IsSeqCst ? llvm::SequentiallyConsistent<br>
+                                                 : llvm::Monotonic);<br>
   // OpenMP, 2.12.6, atomic Construct<br>
   // Any atomic construct with a seq_cst clause forces the atomically<br>
   // performed operation to include an implicit flush operation without a<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=229082&r1=229081&r2=229082&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=229082&r1=229081&r2=229082&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)<br>
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Fri Feb 13 01:55:47 2015<br>
@@ -2147,11 +2147,21 @@ public:<br>
<br>
   void EmitAtomicInit(Expr *E, LValue lvalue);<br>
<br>
+  bool LValueIsSuitableForInlineAtomic(LValue Src);<br>
+  bool typeIsSuitableForInlineAtomic(QualType Ty, bool IsVolatile) const;<br>
+<br>
+  RValue EmitAtomicLoad(LValue LV, SourceLocation SL,<br>
+                        AggValueSlot Slot = AggValueSlot::ignored());<br>
+<br>
   RValue EmitAtomicLoad(LValue lvalue, SourceLocation loc,<br>
+                        llvm::AtomicOrdering AO, bool IsVolatile = false,<br>
                         AggValueSlot slot = AggValueSlot::ignored());<br>
<br>
   void EmitAtomicStore(RValue rvalue, LValue lvalue, bool isInit);<br>
<br>
+  void EmitAtomicStore(RValue rvalue, LValue lvalue, llvm::AtomicOrdering AO,<br>
+                       bool IsVolatile, bool isInit);<br>
+<br>
   std::pair<RValue, RValue> EmitAtomicCompareExchange(<br>
       LValue Obj, RValue Expected, RValue Desired, SourceLocation Loc,<br>
       llvm::AtomicOrdering Success = llvm::SequentiallyConsistent,<br>
<br>
Modified: cfe/trunk/lib/Driver/Tools.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=229082&r1=229081&r2=229082&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=229082&r1=229081&r2=229082&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Driver/Tools.cpp (original)<br>
+++ cfe/trunk/lib/Driver/Tools.cpp Fri Feb 13 01:55:47 2015<br>
@@ -4888,6 +4888,19 @@ void Clang::AddClangCLArgs(const ArgList<br>
     CmdArgs.push_back("-P");<br>
   }<br>
<br>
+  unsigned VolatileOptionID;<br>
+  if (getToolChain().getTriple().getArch() == llvm::Triple::x86_64 ||<br>
+      getToolChain().getTriple().getArch() == llvm::Triple::x86)<br>
+    VolatileOptionID = options::OPT__SLASH_volatile_ms;<br>
+  else<br>
+    VolatileOptionID = options::OPT__SLASH_volatile_iso;<br>
+<br>
+  if (Arg *A = Args.getLastArg(options::OPT__SLASH_volatile_Group))<br>
+    VolatileOptionID = A->getOption().getID();<br>
+<br>
+  if (VolatileOptionID == options::OPT__SLASH_volatile_ms)<br>
+    CmdArgs.push_back("-fms-volatile");<br>
+<br>
   Arg *MostGeneralArg = Args.getLastArg(options::OPT__SLASH_vmg);<br>
   Arg *BestCaseArg = Args.getLastArg(options::OPT__SLASH_vmb);<br>
   if (MostGeneralArg && BestCaseArg)<br>
<br>
Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=229082&r1=229081&r2=229082&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=229082&r1=229081&r2=229082&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)<br>
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Fri Feb 13 01:55:47 2015<br>
@@ -477,6 +477,8 @@ static bool ParseCodeGenArgs(CodeGenOpti<br>
                                    OPT_fno_data_sections, false);<br>
   Opts.MergeFunctions = Args.hasArg(OPT_fmerge_functions);<br>
<br>
+  Opts.MSVolatile = Args.hasArg(OPT_fms_volatile);<br>
+<br>
   Opts.VectorizeBB = Args.hasArg(OPT_vectorize_slp_aggressive);<br>
   Opts.VectorizeLoop = Args.hasArg(OPT_vectorize_loops);<br>
   Opts.VectorizeSLP = Args.hasArg(OPT_vectorize_slp);<br>
<br>
Added: cfe/trunk/test/CodeGen/ms-volatile.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-volatile.c?rev=229082&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-volatile.c?rev=229082&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGen/ms-volatile.c (added)<br>
+++ cfe/trunk/test/CodeGen/ms-volatile.c Fri Feb 13 01:55:47 2015<br>
@@ -0,0 +1,62 @@<br>
+// RUN: %clang_cc1 -triple i386-pc-win32 -emit-llvm -fms-volatile -o - < %s | FileCheck %s<br>
+struct foo {<br>
+  volatile int x;<br>
+};<br>
+struct bar {<br>
+  int x;<br>
+};<br>
+typedef _Complex float __declspec(align(8)) baz;<br>
+<br>
+void test1(struct foo *p, struct foo *q) {<br>
+  *p = *q;<br>
+  // CHECK-LABEL: @test1<br>
+  // CHECK: load atomic volatile {{.*}} acquire<br>
+  // CHECK: store atomic volatile {{.*}}, {{.*}} release<br>
+}<br>
+void test2(volatile int *p, volatile int *q) {<br>
+  *p = *q;<br>
+  // CHECK-LABEL: @test2<br>
+  // CHECK: load atomic volatile {{.*}} acquire<br>
+  // CHECK: store atomic volatile {{.*}}, {{.*}} release<br>
+}<br>
+void test3(struct foo *p, struct foo *q) {<br>
+  p->x = q->x;<br>
+  // CHECK-LABEL: @test3<br>
+  // CHECK: load atomic volatile {{.*}} acquire<br>
+  // CHECK: store atomic volatile {{.*}}, {{.*}} release<br>
+}<br>
+void test4(volatile struct foo *p, volatile struct foo *q) {<br>
+  p->x = q->x;<br>
+  // CHECK-LABEL: @test4<br>
+  // CHECK: load atomic volatile {{.*}} acquire<br>
+  // CHECK: store atomic volatile {{.*}}, {{.*}} release<br>
+}<br>
+void test5(volatile struct foo *p, volatile struct foo *q) {<br>
+  *p = *q;<br>
+  // CHECK-LABEL: @test5<br>
+  // CHECK: load atomic volatile {{.*}} acquire<br>
+  // CHECK: store atomic volatile {{.*}}, {{.*}} release<br>
+}<br>
+void test6(struct bar *p, struct bar *q) {<br>
+  *p = *q;<br>
+  // CHECK-LABEL: @test6<br>
+  // CHECK-NOT: load atomic volatile {{.*}}<br>
+  // CHECK-NOT: store atomic volatile {{.*}}, {{.*}}<br>
+}<br>
+void test7(volatile struct bar *p, volatile struct bar *q) {<br>
+  *p = *q;<br>
+  // CHECK-LABEL: @test7<br>
+  // CHECK: load atomic volatile {{.*}} acquire<br>
+  // CHECK: store atomic volatile {{.*}}, {{.*}} release<br>
+}<br>
+void test8(volatile double *p, volatile double *q) {<br>
+  *p = *q;<br>
+  // CHECK-LABEL: @test8<br>
+  // CHECK: load atomic volatile {{.*}} acquire<br>
+  // CHECK: store atomic volatile {{.*}}, {{.*}} release<br>
+}<br>
+void test9(volatile baz *p, baz *q) {<br>
+  *p = *q;<br>
+  // CHECK-LABEL: @test9<br>
+  // CHECK: store atomic volatile {{.*}}, {{.*}} release<br>
+}<br>
<br>
Modified: cfe/trunk/test/Driver/cl-options.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/cl-options.c?rev=229082&r1=229081&r2=229082&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/cl-options.c?rev=229082&r1=229081&r2=229082&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Driver/cl-options.c (original)<br>
+++ cfe/trunk/test/Driver/cl-options.c Fri Feb 13 01:55:47 2015<br>
@@ -123,6 +123,12 @@<br>
 // RUN: %clang_cl /vmg /vmm /vms -### -- %s 2>&1 | FileCheck -check-prefix=VMX %s<br>
 // VMX: '/vms' not allowed with '/vmm'<br>
<br>
+// RUN: %clang_cl /volatile:iso -### -- %s 2>&1 | FileCheck -check-prefix=VOLATILE-ISO %s<br>
+// VOLATILE-ISO-NOT: "-fms-volatile"<br>
+<br>
+// RUN: %clang_cl /volatile:ms -### -- %s 2>&1 | FileCheck -check-prefix=VOLATILE-MS %s<br>
+// VOLATILE-MS: "-fms-volatile"<br>
+<br>
 // RUN: %clang_cl /W0 -### -- %s 2>&1 | FileCheck -check-prefix=W0 %s<br>
 // W0: -w<br>
<br>
<br>
Modified: cfe/trunk/test/OpenMP/atomic_read_codegen.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/atomic_read_codegen.c?rev=229082&r1=229081&r2=229082&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/atomic_read_codegen.c?rev=229082&r1=229081&r2=229082&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/OpenMP/atomic_read_codegen.c (original)<br>
+++ cfe/trunk/test/OpenMP/atomic_read_codegen.c Fri Feb 13 01:55:47 2015<br>
@@ -225,7 +225,7 @@ int main() {<br>
 // CHECK: store double<br>
 #pragma omp atomic read<br>
   cdv = llx;<br>
-// CHECK: [[I128VAL:%.+]] = load atomic i128* bitcast (<4 x i32>* @{{.+}} to i128*) seq_cst<br>
+// CHECK: [[I128VAL:%.+]] = load atomic i128* bitcast (<4 x i32>* @{{.+}} to i128*) monotonic<br>
 // CHECK: [[I128PTR:%.+]] = bitcast <4 x i32>* [[LDTEMP:%.+]] to i128*<br>
 // CHECK: store i128 [[I128VAL]], i128* [[I128PTR]]<br>
 // CHECK: [[LD:%.+]] = load <4 x i32>* [[LDTEMP]]<br>
@@ -233,7 +233,7 @@ int main() {<br>
 // CHECK: store i8<br>
 #pragma omp atomic read<br>
   bv = int4x[0];<br>
-// CHECK: [[LD:%.+]] = load atomic i32* bitcast (i8* getelementptr (i8* bitcast (%{{.+}}* @{{.+}} to i8*), i64 4) to i32*) seq_cst<br>
+// CHECK: [[LD:%.+]] = load atomic i32* bitcast (i8* getelementptr (i8* bitcast (%{{.+}}* @{{.+}} to i8*), i64 4) to i32*) monotonic<br>
 // CHECK: store i32 [[LD]], i32* [[LDTEMP:%.+]]<br>
 // CHECK: [[LD:%.+]] = load i32* [[LDTEMP]]<br>
 // CHECK: [[SHL:%.+]] = shl i32 [[LD]], 1<br>
@@ -249,21 +249,21 @@ int main() {<br>
 // CHECK: store x86_fp80<br>
 #pragma omp atomic read<br>
   ldv = bfx_packed.a;<br>
-// CHECK: [[LD:%.+]] = load atomic i32* getelementptr inbounds (%struct.BitFields2* @bfx2, i32 0, i32 0) seq_cst<br>
+// CHECK: [[LD:%.+]] = load atomic i32* getelementptr inbounds (%struct.BitFields2* @bfx2, i32 0, i32 0) monotonic<br>
 // CHECK: store i32 [[LD]], i32* [[LDTEMP:%.+]]<br>
 // CHECK: [[LD:%.+]] = load i32* [[LDTEMP]]<br>
 // CHECK: ashr i32 [[LD]], 31<br>
 // CHECK: store x86_fp80<br>
 #pragma omp atomic read<br>
   ldv = bfx2.a;<br>
-// CHECK: [[LD:%.+]] = load atomic i8* getelementptr (i8* bitcast (%struct.BitFields2_packed* @bfx2_packed to i8*), i64 3) seq_cst<br>
+// CHECK: [[LD:%.+]] = load atomic i8* getelementptr (i8* bitcast (%struct.BitFields2_packed* @bfx2_packed to i8*), i64 3) monotonic<br>
 // CHECK: store i8 [[LD]], i8* [[LDTEMP:%.+]]<br>
 // CHECK: [[LD:%.+]] = load i8* [[LDTEMP]]<br>
 // CHECK: ashr i8 [[LD]], 7<br>
 // CHECK: store x86_fp80<br>
 #pragma omp atomic read<br>
   ldv = bfx2_packed.a;<br>
-// CHECK: [[LD:%.+]] = load atomic i32* getelementptr inbounds (%struct.BitFields3* @bfx3, i32 0, i32 0) seq_cst<br>
+// CHECK: [[LD:%.+]] = load atomic i32* getelementptr inbounds (%struct.BitFields3* @bfx3, i32 0, i32 0) monotonic<br>
 // CHECK: store i32 [[LD]], i32* [[LDTEMP:%.+]]<br>
 // CHECK: [[LD:%.+]] = load i32* [[LDTEMP]]<br>
 // CHECK: [[SHL:%.+]] = shl i32 [[LD]], 7<br>
@@ -280,7 +280,7 @@ int main() {<br>
 // CHECK: store x86_fp80<br>
 #pragma omp atomic read<br>
   ldv = bfx3_packed.a;<br>
-// CHECK: [[LD:%.+]] = load atomic i64* bitcast (%struct.BitFields4* @bfx4 to i64*) seq_cst<br>
+// CHECK: [[LD:%.+]] = load atomic i64* bitcast (%struct.BitFields4* @bfx4 to i64*) monotonic<br>
 // CHECK: store i64 [[LD]], i64* [[LDTEMP:%.+]]<br>
 // CHECK: [[LD:%.+]] = load i64* [[LDTEMP]]<br>
 // CHECK: [[SHL:%.+]] = shl i64 [[LD]], 47<br>
@@ -289,7 +289,7 @@ int main() {<br>
 // CHECK: store x86_fp80<br>
 #pragma omp atomic read<br>
   ldv = bfx4.a;<br>
-// CHECK: [[LD:%.+]] = load atomic i8* getelementptr inbounds (%struct.BitFields4_packed* @bfx4_packed, i32 0, i32 0, i64 2) seq_cst<br>
+// CHECK: [[LD:%.+]] = load atomic i8* getelementptr inbounds (%struct.BitFields4_packed* @bfx4_packed, i32 0, i32 0, i64 2) monotonic<br>
 // CHECK: store i8 [[LD]], i8* [[LDTEMP:%.+]]<br>
 // CHECK: [[LD:%.+]] = load i8* [[LDTEMP]]<br>
 // CHECK: [[SHL:%.+]] = shl i8 [[LD]], 7<br>
@@ -298,7 +298,7 @@ int main() {<br>
 // CHECK: store x86_fp80<br>
 #pragma omp atomic read<br>
   ldv = bfx4_packed.a;<br>
-// CHECK: [[LD:%.+]] = load atomic i64* bitcast (%struct.BitFields4* @bfx4 to i64*) seq_cst<br>
+// CHECK: [[LD:%.+]] = load atomic i64* bitcast (%struct.BitFields4* @bfx4 to i64*) monotonic<br>
 // CHECK: store i64 [[LD]], i64* [[LDTEMP:%.+]]<br>
 // CHECK: [[LD:%.+]] = load i64* [[LDTEMP]]<br>
 // CHECK: [[SHL:%.+]] = shl i64 [[LD]], 40<br>
@@ -306,7 +306,7 @@ int main() {<br>
 // CHECK: store x86_fp80<br>
 #pragma omp atomic read<br>
   ldv = bfx4.b;<br>
-// CHECK: [[LD:%.+]] = load atomic i8* getelementptr inbounds (%struct.BitFields4_packed* @bfx4_packed, i32 0, i32 0, i64 2) seq_cst<br>
+// CHECK: [[LD:%.+]] = load atomic i8* getelementptr inbounds (%struct.BitFields4_packed* @bfx4_packed, i32 0, i32 0, i64 2) monotonic<br>
 // CHECK: store i8 [[LD]], i8* [[LDTEMP:%.+]]<br>
 // CHECK: [[LD:%.+]] = load i8* [[LDTEMP]]<br>
 // CHECK: [[ASHR:%.+]] = ashr i8 [[LD]], 1<br>
@@ -314,7 +314,7 @@ int main() {<br>
 // CHECK: store x86_fp80<br>
 #pragma omp atomic read<br>
   ldv = bfx4_packed.b;<br>
-// CHECK: [[LD:%.+]] = load atomic i32* bitcast (<2 x float>* @{{.+}} to i32*) seq_cst<br>
+// CHECK: [[LD:%.+]] = load atomic i32* bitcast (<2 x float>* @{{.+}} to i32*) monotonic<br>
 // CHECK: [[BITCAST:%.+]] = bitcast <2 x float>* [[LDTEMP:%.+]] to i32*<br>
 // CHECK: store i32 [[LD]], i32* [[BITCAST]]<br>
 // CHECK: [[LD:%.+]] = load <2 x float>* [[LDTEMP]]<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>