<div dir="ltr">I fixed this in r212465.<div><br></div><div>It's very sad the bug has hidden a few other bugs being introduced into the codebase over the last couple of weeks...</div></div><div class="gmail_extra"><br><br>
<div class="gmail_quote">2014-06-21 0:38 GMT+04:00 Reid Kleckner <span dir="ltr"><<a href="mailto:rnk@google.com" target="_blank">rnk@google.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr">Remember how I said it'd be OK if we provided _InterlockedCompareExchangePointer on x86? Well, doing that broke the sanitizers. Do 'check-asan' on 32-bit Windows to reproduce.<div><br></div><div>
This is the problematic code:</div><div><div>inline static void *_InterlockedCompareExchangePointer(<br></div><div> void *volatile *Destination,</div><div> void *Exchange, void *Comparand) {</div><div> return reinterpret_cast<void*>(</div>
<div> _InterlockedCompareExchange(</div><div> reinterpret_cast<long volatile*>(Destination), // NOLINT</div><div> reinterpret_cast<long>(Exchange), // NOLINT</div><div> reinterpret_cast<long>(Comparand))); // NOLINT</div>
<div>}</div></div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Jun 18, 2014 at 1:51 PM, Saleem Abdulrasool <span dir="ltr"><<a href="mailto:compnerd@compnerd.org" target="_blank">compnerd@compnerd.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: compnerd<br>
Date: Wed Jun 18 15:51:10 2014<br>
New Revision: 211216<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=211216&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=211216&view=rev</a><br>
Log:<br>
CodeGen: improve ms instrincics support<br>
<br>
Add support for _InterlockedCompareExchangePointer, _InterlockExchangePointer,<br>
_InterlockExchange. These are available as a compiler intrinsic on ARM and x86.<br>
These are used directly by the Windows SDK headers without use of the intrin<br>
header.<br>
<br>
Added:<br>
cfe/trunk/test/CodeGen/ms-intrinsics.c<br>
Modified:<br>
cfe/trunk/include/clang/Basic/Builtins.def<br>
cfe/trunk/lib/CodeGen/CGBuiltin.cpp<br>
cfe/trunk/lib/Headers/Intrin.h<br>
<br>
Modified: cfe/trunk/include/clang/Basic/Builtins.def<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=211216&r1=211215&r2=211216&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=211216&r1=211215&r2=211216&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/Builtins.def (original)<br>
+++ cfe/trunk/include/clang/Basic/Builtins.def Wed Jun 18 15:51:10 2014<br>
@@ -683,9 +683,12 @@ LANGBUILTIN(__noop, "v.", "n", AL<br>
LANGBUILTIN(__debugbreak, "v", "n", ALL_MS_LANGUAGES)<br>
LANGBUILTIN(__va_start, "vc**.", "nt", ALL_MS_LANGUAGES)<br>
LANGBUILTIN(_InterlockedCompareExchange, "LiLiD*LiLi", "n", ALL_MS_LANGUAGES)<br>
+LANGBUILTIN(_InterlockedCompareExchangePointer, "v*v*D*v*v*", "n", ALL_MS_LANGUAGES)<br>
LANGBUILTIN(_InterlockedIncrement, "LiLiD*", "n", ALL_MS_LANGUAGES)<br>
LANGBUILTIN(_InterlockedDecrement, "LiLiD*", "n", ALL_MS_LANGUAGES)<br>
LANGBUILTIN(_InterlockedExchangeAdd, "LiLiD*Li", "n", ALL_MS_LANGUAGES)<br>
+LANGBUILTIN(_InterlockedExchangePointer, "v*v*D*v*", "n", ALL_MS_LANGUAGES)<br>
+LANGBUILTIN(_InterlockedExchange, "LiLiD*Li", "n", ALL_MS_LANGUAGES)<br>
<br>
// C99 library functions<br>
// C99 stdlib.h<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=211216&r1=211215&r2=211216&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=211216&r1=211215&r2=211216&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Wed Jun 18 15:51:10 2014<br>
@@ -1516,6 +1516,35 @@ RValue CodeGenFunction::EmitBuiltinExpr(<br>
E->getArg(0), true);<br>
case Builtin::BI__noop:<br>
return RValue::get(nullptr);<br>
+ case Builtin::BI_InterlockedExchange:<br>
+ case Builtin::BI_InterlockedExchangePointer:<br>
+ return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E);<br>
+ case Builtin::BI_InterlockedCompareExchangePointer: {<br>
+ llvm::Type *RTy;<br>
+ llvm::IntegerType *IntType =<br>
+ IntegerType::get(getLLVMContext(),<br>
+ getContext().getTypeSize(E->getType()));<br>
+ llvm::Type *IntPtrType = IntType->getPointerTo();<br>
+<br>
+ llvm::Value *Destination =<br>
+ Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), IntPtrType);<br>
+<br>
+ llvm::Value *Exchange = EmitScalarExpr(E->getArg(1));<br>
+ RTy = Exchange->getType();<br>
+ Exchange = Builder.CreatePtrToInt(Exchange, IntType);<br>
+<br>
+ llvm::Value *Comparand =<br>
+ Builder.CreatePtrToInt(EmitScalarExpr(E->getArg(2)), IntType);<br>
+<br>
+ auto Result = Builder.CreateAtomicCmpXchg(Destination, Comparand, Exchange,<br>
+ SequentiallyConsistent,<br>
+ SequentiallyConsistent);<br>
+ Result->setVolatile(true);<br>
+<br>
+ return RValue::get(Builder.CreateIntToPtr(Builder.CreateExtractValue(Result,<br>
+ 0),<br>
+ RTy));<br>
+ }<br>
case Builtin::BI_InterlockedCompareExchange: {<br>
AtomicCmpXchgInst *CXI = Builder.CreateAtomicCmpXchg(<br>
EmitScalarExpr(E->getArg(0)),<br>
<br>
Modified: cfe/trunk/lib/Headers/Intrin.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/Intrin.h?rev=211216&r1=211215&r2=211216&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/Intrin.h?rev=211216&r1=211215&r2=211216&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Headers/Intrin.h (original)<br>
+++ cfe/trunk/lib/Headers/Intrin.h Wed Jun 18 15:51:10 2014<br>
@@ -223,8 +223,7 @@ static __inline__<br>
long __cdecl _InterlockedDecrement(long volatile *_Addend);<br>
static __inline__<br>
short _InterlockedDecrement16(short volatile *_Addend);<br>
-static __inline__<br>
-long __cdecl _InterlockedExchange(long volatile *_Target, long _Value);<br>
+long _InterlockedExchange(long volatile *_Target, long _Value);<br>
static __inline__<br>
short _InterlockedExchange16(short volatile *_Target, short _Value);<br>
static __inline__<br>
@@ -411,7 +410,6 @@ __int64 _InterlockedCompareExchange64_HL<br>
__int64);<br>
__int64 _InterlockedCompareExchange64_np(__int64 volatile *_Destination,<br>
__int64 _Exchange, __int64 _Comparand);<br>
-static __inline__<br>
void *_InterlockedCompareExchangePointer(void *volatile *_Destination,<br>
void *_Exchange, void *_Comparand);<br>
void *_InterlockedCompareExchangePointer_np(void *volatile *_Destination,<br>
@@ -422,7 +420,6 @@ static __inline__<br>
__int64 _InterlockedExchange64(__int64 volatile *_Target, __int64 _Value);<br>
static __inline__<br>
__int64 _InterlockedExchangeAdd64(__int64 volatile *_Addend, __int64 _Value);<br>
-static __inline__<br>
void *_InterlockedExchangePointer(void *volatile *_Target, void *_Value);<br>
static __inline__<br>
__int64 _InterlockedIncrement64(__int64 volatile *_Addend);<br>
@@ -785,22 +782,12 @@ _InterlockedExchange16(short volatile *_<br>
__atomic_exchange(_Target, &_Value, &_Value, 0);<br>
return _Value;<br>
}<br>
-static __inline__ long __attribute__((__always_inline__, __nodebug__))<br>
-_InterlockedExchange(long volatile *_Target, long _Value) {<br>
- __atomic_exchange(_Target, &_Value, &_Value, 0);<br>
- return _Value;<br>
-}<br>
#ifdef __x86_64__<br>
static __inline__ __int64 __attribute__((__always_inline__, __nodebug__))<br>
_InterlockedExchange64(__int64 volatile *_Target, __int64 _Value) {<br>
__atomic_exchange(_Target, &_Value, &_Value, 0);<br>
return _Value;<br>
}<br>
-static __inline__ void *__attribute__((__always_inline__, __nodebug__))<br>
-_InterlockedExchangePointer(void *volatile *_Target, void *_Value) {<br>
- __atomic_exchange(_Target, &_Value, &_Value, 0);<br>
- return _Value;<br>
-}<br>
#endif<br>
/*----------------------------------------------------------------------------*\<br>
|* Interlocked Compare Exchange<br>
@@ -817,14 +804,6 @@ _InterlockedCompareExchange16(short vola<br>
__atomic_compare_exchange(_Destination, &_Comparand, &_Exchange, 0, 0, 0);<br>
return _Comparand;<br>
}<br>
-#ifdef __x86_64__<br>
-static __inline__ void *__attribute__((__always_inline__, __nodebug__))<br>
-_InterlockedCompareExchangePointer(void *volatile *_Destination,<br>
- void *_Exchange, void *_Comparand) {<br>
- __atomic_compare_exchange(_Destination, &_Comparand, &_Exchange, 0, 0, 0);<br>
- return _Comparand;<br>
-}<br>
-#endif<br>
static __inline__ __int64 __attribute__((__always_inline__, __nodebug__))<br>
_InterlockedCompareExchange64(__int64 volatile *_Destination,<br>
__int64 _Exchange, __int64 _Comparand) {<br>
<br>
Added: cfe/trunk/test/CodeGen/ms-intrinsics.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-intrinsics.c?rev=211216&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-intrinsics.c?rev=211216&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGen/ms-intrinsics.c (added)<br>
+++ cfe/trunk/test/CodeGen/ms-intrinsics.c Wed Jun 18 15:51:10 2014<br>
@@ -0,0 +1,41 @@<br>
+// RUN: %clang_cc1 -triple i686--windows -fms-compatibility -Oz -emit-llvm %s -o - | FileCheck %s<br>
+// RUN: %clang_cc1 -triple thumbv7--windows -fms-compatibility -Oz -emit-llvm %s -o - | FileCheck %s<br>
+<br>
+void *test_InterlockedExchangePointer(void * volatile *Target, void *Value) {<br>
+ return _InterlockedExchangePointer(Target, Value);<br>
+}<br>
+<br>
+// CHECK: define{{.*}}i8* @test_InterlockedExchangePointer(i8** %Target, i8* %Value){{.*}}{<br>
+// CHECK: entry:<br>
+// CHECK: %0 = bitcast i8** %Target to i32*<br>
+// CHECK: %1 = ptrtoint i8* %Value to i32<br>
+// CHECK: %2 = atomicrmw xchg i32* %0, i32 %1 seq_cst<br>
+// CHECK: %3 = inttoptr i32 %2 to i8*<br>
+// CHECK: ret i8* %3<br>
+// CHECK: }<br>
+<br>
+void *test_InterlockedCompareExchangePointer(void * volatile *Destination,<br>
+ void *Exchange, void *Comparand) {<br>
+ return _InterlockedCompareExchangePointer(Destination, Exchange, Comparand);<br>
+}<br>
+<br>
+// CHECK: define{{.*}}i8* @test_InterlockedCompareExchangePointer(i8** %Destination, i8* %Exchange, i8* %Comparand){{.*}}{<br>
+// CHECK: entry:<br>
+// CHECK: %0 = bitcast i8** %Destination to i32*<br>
+// CHECK: %1 = ptrtoint i8* %Exchange to i32<br>
+// CHECK: %2 = ptrtoint i8* %Comparand to i32<br>
+// CHECK: %3 = cmpxchg volatile i32* %0, i32 %2, i32 %1 seq_cst seq_cst<br>
+// CHECK: %4 = extractvalue { i32, i1 } %3, 0<br>
+// CHECK: %5 = inttoptr i32 %4 to i8*<br>
+// CHECK: ret i8* %5<br>
+// CHECK: }<br>
+<br>
+long test_InterlockedExchange(long *Target, long Value) {<br>
+ return _InterlockedExchange(Target, Value);<br>
+}<br>
+<br>
+// CHECK: define{{.*}}i32 @test_InterlockedExchange(i32* %Target, i32 %Value){{.*}}{<br>
+// CHECK: entry:<br>
+// CHECK: %0 = atomicrmw xchg i32* %Target, i32 %Value seq_cst<br>
+// CHECK: ret i32 %0<br>
+// CHECK: }<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">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>
</div></div></blockquote></div><br></div>