summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CGBuiltin.cpp
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2017-04-07 16:41:47 +0000
committerHans Wennborg <hans@hanshq.net>2017-04-07 16:41:47 +0000
commit7a351322b4f455f6485649124423f347cb559c3b (patch)
treec7e8f0453724651724a639c15224b6d72bfc10fd /lib/CodeGen/CGBuiltin.cpp
parent49c4c7d799281c219c71cae4419afef8b300ee43 (diff)
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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@299782 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGBuiltin.cpp')
-rw-r--r--lib/CodeGen/CGBuiltin.cpp24
1 files changed, 21 insertions, 3 deletions
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index a23fa9e470..6ea0a325a4 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -492,6 +492,7 @@ enum class CodeGenFunction::MSVCIntrin {
_InterlockedIncrement,
_InterlockedOr,
_InterlockedXor,
+ _interlockedbittestandset,
__fastfail,
};
@@ -559,6 +560,22 @@ Value *CodeGenFunction::EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID,
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(const FunctionDecl *FD,
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(const FunctionDecl *FD,
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();