Index: include/clang/Basic/Builtins.def =================================================================== --- include/clang/Basic/Builtins.def +++ include/clang/Basic/Builtins.def @@ -778,6 +778,7 @@ LANGBUILTIN(__abnormal_termination, "i", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_abnormal_termination, "i", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__GetExceptionInfo, "v*.", "ntu", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedAdd, "NiNiD*Ni", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedAnd8, "ccD*c", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedAnd16, "ssD*s", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedAnd, "NiNiD*Ni", "n", ALL_MS_LANGUAGES) Index: lib/CodeGen/CGBuiltin.cpp =================================================================== --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -737,6 +737,7 @@ enum class CodeGenFunction::MSVCIntrin { _BitScanForward, _BitScanReverse, + _InterlockedAdd, _InterlockedAnd, _InterlockedDecrement, _InterlockedExchange, @@ -799,6 +800,8 @@ Builder.SetInsertPoint(End); return Result; } + case MSVCIntrin::_InterlockedAdd: + return MakeBinaryAtomicValue(*this, AtomicRMWInst::Add, E); case MSVCIntrin::_InterlockedAnd: return MakeBinaryAtomicValue(*this, AtomicRMWInst::And, E); case MSVCIntrin::_InterlockedExchange: @@ -3048,6 +3051,8 @@ case Builtin::BI_InterlockedDecrement: return RValue::get( EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E)); + case Builtin::BI_InterlockedAdd: + return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAdd, E)); case Builtin::BI_InterlockedAnd8: case Builtin::BI_InterlockedAnd16: case Builtin::BI_InterlockedAnd: Index: test/CodeGen/ms-intrinsics.c =================================================================== --- test/CodeGen/ms-intrinsics.c +++ test/CodeGen/ms-intrinsics.c @@ -370,6 +370,15 @@ // CHECK: ret i32 [[RESULT:%[0-9]+]] // CHECK: } +long test_InterlockedAdd(long volatile *value, long mask) { + return _InterlockedAdd(value, mask); +} + +// CHECK: define{{.*}}i32 @test_InterlockedAdd(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: [[RESULT:%[0-9]+]] = atomicrmw add i32* %value, i32 %mask seq_cst +// CHECK: ret i32 [[RESULT:%[0-9]+]] +// CHECK: } + char test_InterlockedAnd8(char volatile *value, char mask) { return _InterlockedAnd8(value, mask); }