r299782 - Implement _interlockedbittestandset as a builtin
Hans Wennborg via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 7 09:41:48 PDT 2017
Author: hans
Date: Fri Apr 7 11:41:47 2017
New Revision: 299782
URL: http://llvm.org/viewvc/llvm-project?rev=299782&view=rev
Log:
Implement _interlockedbittestandset as a builtin
It's used by MS headers in VS 2017 without including intrin.h, so we
can't implement it in the header anymore.
Differential Revision: https://reviews.llvm.org/D31736
Modified:
cfe/trunk/include/clang/Basic/Builtins.def
cfe/trunk/lib/CodeGen/CGBuiltin.cpp
cfe/trunk/lib/Headers/intrin.h
cfe/trunk/test/CodeGen/ms-intrinsics.c
Modified: cfe/trunk/include/clang/Basic/Builtins.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=299782&r1=299781&r2=299782&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Builtins.def (original)
+++ cfe/trunk/include/clang/Basic/Builtins.def Fri Apr 7 11:41:47 2017
@@ -756,6 +756,7 @@ LANGBUILTIN(_InterlockedOr, "LiLiD*Li"
LANGBUILTIN(_InterlockedXor8, "ccD*c", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedXor16, "ssD*s", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedXor, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_interlockedbittestandset, "UcLiD*Li", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__popcnt16, "UsUs", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__popcnt, "UiUi", "nc", ALL_MS_LANGUAGES)
Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=299782&r1=299781&r2=299782&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Fri Apr 7 11:41:47 2017
@@ -492,6 +492,7 @@ enum class CodeGenFunction::MSVCIntrin {
_InterlockedIncrement,
_InterlockedOr,
_InterlockedXor,
+ _interlockedbittestandset,
__fastfail,
};
@@ -559,6 +560,22 @@ Value *CodeGenFunction::EmitMSVCBuiltinE
case MSVCIntrin::_InterlockedXor:
return MakeBinaryAtomicValue(*this, AtomicRMWInst::Xor, E);
+ case MSVCIntrin::_interlockedbittestandset: {
+ llvm::Value *Addr = EmitScalarExpr(E->getArg(0));
+ llvm::Value *Bit = EmitScalarExpr(E->getArg(1));
+ AtomicRMWInst *RMWI = Builder.CreateAtomicRMW(
+ AtomicRMWInst::Or, Addr,
+ Builder.CreateShl(ConstantInt::get(Bit->getType(), 1), Bit),
+ llvm::AtomicOrdering::SequentiallyConsistent);
+ // Shift the relevant bit to the least significant position, truncate to
+ // the result type, and test the low bit.
+ llvm::Value *Shifted = Builder.CreateLShr(RMWI, Bit);
+ llvm::Value *Truncated =
+ Builder.CreateTrunc(Shifted, ConvertType(E->getType()));
+ return Builder.CreateAnd(Truncated,
+ ConstantInt::get(Truncated->getType(), 1));
+ }
+
case MSVCIntrin::_InterlockedDecrement: {
llvm::Type *IntTy = ConvertType(E->getType());
AtomicRMWInst *RMWI = Builder.CreateAtomicRMW(
@@ -2238,6 +2255,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(
case Builtin::BI_InterlockedXor16:
case Builtin::BI_InterlockedXor:
return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E));
+ case Builtin::BI_interlockedbittestandset:
+ return RValue::get(
+ EmitMSVCBuiltinExpr(MSVCIntrin::_interlockedbittestandset, E));
case Builtin::BI__exception_code:
case Builtin::BI_exception_code:
@@ -2309,10 +2329,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(
break;
}
- case Builtin::BI__fastfail: {
+ case Builtin::BI__fastfail:
return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::__fastfail, E));
- break;
- }
case Builtin::BI__builtin_coro_size: {
auto & Context = getContext();
Modified: cfe/trunk/lib/Headers/intrin.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/intrin.h?rev=299782&r1=299781&r2=299782&view=diff
==============================================================================
--- cfe/trunk/lib/Headers/intrin.h (original)
+++ cfe/trunk/lib/Headers/intrin.h Fri Apr 7 11:41:47 2017
@@ -173,7 +173,6 @@ void __cdecl _disable(void);
void __cdecl _enable(void);
long _InterlockedAddLargeStatistic(__int64 volatile *_Addend, long _Value);
unsigned char _interlockedbittestandreset(long volatile *, long);
-static __inline__
unsigned char _interlockedbittestandset(long volatile *, long);
long _InterlockedCompareExchange_HLEAcquire(long volatile *, long, long);
long _InterlockedCompareExchange_HLERelease(long volatile *, long, long);
@@ -369,11 +368,6 @@ _bittestandset(long *_BitBase, long _Bit
*_BitBase = *_BitBase | (1 << _BitPos);
return _Res;
}
-static __inline__ unsigned char __DEFAULT_FN_ATTRS
-_interlockedbittestandset(long volatile *_BitBase, long _BitPos) {
- long _PrevVal = __atomic_fetch_or(_BitBase, 1l << _BitPos, __ATOMIC_SEQ_CST);
- return (_PrevVal >> _BitPos) & 1;
-}
#if defined(__arm__) || defined(__aarch64__)
static __inline__ unsigned char __DEFAULT_FN_ATTRS
_interlockedbittestandset_acq(long volatile *_BitBase, long _BitPos) {
Modified: cfe/trunk/test/CodeGen/ms-intrinsics.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-intrinsics.c?rev=299782&r1=299781&r2=299782&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/ms-intrinsics.c (original)
+++ cfe/trunk/test/CodeGen/ms-intrinsics.c Fri Apr 7 11:41:47 2017
@@ -434,6 +434,17 @@ __int64 test_InterlockedDecrement64(__in
#endif
+unsigned char test_interlockedbittestandset(volatile long *ptr, long bit) {
+ return _interlockedbittestandset(ptr, bit);
+}
+// CHECK-LABEL: define{{.*}} i8 @test_interlockedbittestandset
+// CHECK: %0 = shl i32 1, %bit
+// CHECK: %1 = atomicrmw or i32* %ptr, i32 %0 seq_cst
+// CHECK: %2 = lshr i32 %1, %bit
+// CHECK: %3 = trunc i32 %2 to i8
+// CHECK: %4 = and i8 %3, 1
+// CHECK: ret i8 %4
+
void test__fastfail() {
__fastfail(42);
}
More information about the cfe-commits
mailing list