[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