[PATCH] Implement the MSVC _InterlockedCompareExchange, _InterlockedIncrement* and _InterlockedDecrement* intrinsics.
Peter Collingbourne
peter at pcc.me.uk
Wed Apr 17 23:41:37 PDT 2013
Hi rnk,
http://llvm-reviews.chandlerc.com/D688
Files:
include/clang/Basic/Builtins.def
lib/CodeGen/CGBuiltin.cpp
test/CodeGen/builtin-ms-atomic.c
Index: include/clang/Basic/Builtins.def
===================================================================
--- include/clang/Basic/Builtins.def
+++ include/clang/Basic/Builtins.def
@@ -670,6 +670,13 @@
BUILTIN(__assume, "vb", "n")
BUILTIN(__noop, "v.", "n")
BUILTIN(__debugbreak, "v", "n")
+BUILTIN(_InterlockedCompareExchange, "LiLiD*LiLi", "n")
+BUILTIN(_InterlockedDecrement, "LiLi*", "n")
+BUILTIN(_InterlockedDecrement16, "ss*", "n")
+BUILTIN(_InterlockedDecrement64, "LLiLLi*", "n")
+BUILTIN(_InterlockedIncrement, "LiLi*", "n")
+BUILTIN(_InterlockedIncrement16, "ss*", "n")
+BUILTIN(_InterlockedIncrement64, "LLiLLi*", "n")
// C99 library functions
Index: lib/CodeGen/CGBuiltin.cpp
===================================================================
--- lib/CodeGen/CGBuiltin.cpp
+++ lib/CodeGen/CGBuiltin.cpp
@@ -1412,6 +1412,34 @@
}
case Builtin::BI__noop:
return RValue::get(0);
+
+ case Builtin::BI_InterlockedCompareExchange: {
+ llvm::Value *Dest = EmitScalarExpr(E->getArg(0));
+ llvm::Value *Exch = EmitScalarExpr(E->getArg(1));
+ llvm::Value *Comp = EmitScalarExpr(E->getArg(2));
+
+ return RValue::get(Builder.CreateAtomicCmpXchg(Dest, Comp, Exch,
+ llvm::SequentiallyConsistent));
+ }
+
+ case Builtin::BI_InterlockedDecrement:
+ case Builtin::BI_InterlockedDecrement16:
+ case Builtin::BI_InterlockedDecrement64:
+ case Builtin::BI_InterlockedIncrement:
+ case Builtin::BI_InterlockedIncrement16:
+ case Builtin::BI_InterlockedIncrement64: {
+ int Addend = (BuiltinID == Builtin::BI_InterlockedIncrement ||
+ BuiltinID == Builtin::BI_InterlockedIncrement16 ||
+ BuiltinID == Builtin::BI_InterlockedIncrement64) ? 1 : -1;
+ llvm::Type *ResultType = ConvertType(E->getType());
+ llvm::Constant *AddendCst = ConstantInt::getSigned(ResultType, Addend);
+
+ llvm::Value *Ptr = EmitScalarExpr(E->getArg(0));
+ llvm::Value *AtomicRMW =
+ Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Add, Ptr, AddendCst,
+ llvm::SequentiallyConsistent);
+ return RValue::get(Builder.CreateAdd(AtomicRMW, AddendCst));
+ }
}
// If this is an alias for a lib function (e.g. __builtin_sin), emit
Index: test/CodeGen/builtin-ms-atomic.c
===================================================================
--- /dev/null
+++ test/CodeGen/builtin-ms-atomic.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -emit-llvm %s -o - | FileCheck %s
+
+void ice(long *p) {
+ // CHECK: @ice
+ // CHECK: cmpxchg i32* {{.*}}, i32 2, i32 1 seq_cst
+ _InterlockedCompareExchange(p, 1, 2);
+}
+
+void iinc(long *p) {
+ // CHECK: @iinc
+ // CHECK: %[[I:.*]] = atomicrmw add i32* {{.*}}, i32 1 seq_cst
+ // CHECK: add i32 %[[I]], 1
+ _InterlockedIncrement(p);
+}
+
+void idec(long *p) {
+ // CHECK: @idec
+ // CHECK: %[[D:.*]] = atomicrmw add i32* {{.*}}, i32 -1 seq_cst
+ // CHECK: add i32 %[[D]], -1
+ _InterlockedDecrement(p);
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D688.1.patch
Type: text/x-patch
Size: 3009 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130417/19f991ce/attachment.bin>
More information about the cfe-commits
mailing list