diff options
author | Hans Wennborg <hans@hanshq.net> | 2017-04-07 16:41:47 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2017-04-07 16:41:47 +0000 |
commit | 7a351322b4f455f6485649124423f347cb559c3b (patch) | |
tree | c7e8f0453724651724a639c15224b6d72bfc10fd /lib/CodeGen/CGBuiltin.cpp | |
parent | 49c4c7d799281c219c71cae4419afef8b300ee43 (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.cpp | 24 |
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(); |