Expose IRBuilder::CreateAtomicCmpXchg as LLVMBuildAtomicCmpXchg in the C API.
Summary: Also expose getters and setters in the C API, so that the change can be tested.
Reviewers: nhaehnle, axw, joker.eph
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D18260
From: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
llvm-svn: 263886
diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h
index a09c922..db7e3b1 100644
--- a/llvm/include/llvm-c/Core.h
+++ b/llvm/include/llvm-c/Core.h
@@ -2940,6 +2940,21 @@
LLVMValueRef PTR, LLVMValueRef Val,
LLVMAtomicOrdering ordering,
LLVMBool singleThread);
+LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Ptr,
+ LLVMValueRef Cmp, LLVMValueRef New,
+ LLVMAtomicOrdering SuccessOrdering,
+ LLVMAtomicOrdering FailureOrdering,
+ LLVMBool SingleThread);
+
+LLVMBool LLVMIsAtomicSingleThread(LLVMValueRef AtomicInst);
+void LLVMSetAtomicSingleThread(LLVMValueRef AtomicInst, LLVMBool SingleThread);
+
+LLVMAtomicOrdering LLVMGetCmpXchgSuccessOrdering(LLVMValueRef CmpXchgInst);
+void LLVMSetCmpXchgSuccessOrdering(LLVMValueRef CmpXchgInst,
+ LLVMAtomicOrdering Ordering);
+LLVMAtomicOrdering LLVMGetCmpXchgFailureOrdering(LLVMValueRef CmpXchgInst);
+void LLVMSetCmpXchgFailureOrdering(LLVMValueRef CmpXchgInst,
+ LLVMAtomicOrdering Ordering);
/**
* @}
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index 55d719c..8de8a82 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -2908,6 +2908,61 @@
mapFromLLVMOrdering(ordering), singleThread ? SingleThread : CrossThread));
}
+LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Ptr,
+ LLVMValueRef Cmp, LLVMValueRef New,
+ LLVMAtomicOrdering SuccessOrdering,
+ LLVMAtomicOrdering FailureOrdering,
+ LLVMBool singleThread) {
+
+ return wrap(unwrap(B)->CreateAtomicCmpXchg(unwrap(Ptr), unwrap(Cmp),
+ unwrap(New), mapFromLLVMOrdering(SuccessOrdering),
+ mapFromLLVMOrdering(FailureOrdering),
+ singleThread ? SingleThread : CrossThread));
+}
+
+
+LLVMBool LLVMIsAtomicSingleThread(LLVMValueRef AtomicInst) {
+ Value *P = unwrap<Value>(AtomicInst);
+
+ if (AtomicRMWInst *I = dyn_cast<AtomicRMWInst>(P))
+ return I->getSynchScope() == SingleThread;
+ return cast<AtomicCmpXchgInst>(P)->getSynchScope() == SingleThread;
+}
+
+void LLVMSetAtomicSingleThread(LLVMValueRef AtomicInst, LLVMBool NewValue) {
+ Value *P = unwrap<Value>(AtomicInst);
+ SynchronizationScope Sync = NewValue ? SingleThread : CrossThread;
+
+ if (AtomicRMWInst *I = dyn_cast<AtomicRMWInst>(P))
+ return I->setSynchScope(Sync);
+ return cast<AtomicCmpXchgInst>(P)->setSynchScope(Sync);
+}
+
+LLVMAtomicOrdering LLVMGetCmpXchgSuccessOrdering(LLVMValueRef CmpXchgInst) {
+ Value *P = unwrap<Value>(CmpXchgInst);
+ return mapToLLVMOrdering(cast<AtomicCmpXchgInst>(P)->getSuccessOrdering());
+}
+
+void LLVMSetCmpXchgSuccessOrdering(LLVMValueRef CmpXchgInst,
+ LLVMAtomicOrdering Ordering) {
+ Value *P = unwrap<Value>(CmpXchgInst);
+ AtomicOrdering O = mapFromLLVMOrdering(Ordering);
+
+ return cast<AtomicCmpXchgInst>(P)->setSuccessOrdering(O);
+}
+
+LLVMAtomicOrdering LLVMGetCmpXchgFailureOrdering(LLVMValueRef CmpXchgInst) {
+ Value *P = unwrap<Value>(CmpXchgInst);
+ return mapToLLVMOrdering(cast<AtomicCmpXchgInst>(P)->getFailureOrdering());
+}
+
+void LLVMSetCmpXchgFailureOrdering(LLVMValueRef CmpXchgInst,
+ LLVMAtomicOrdering Ordering) {
+ Value *P = unwrap<Value>(CmpXchgInst);
+ AtomicOrdering O = mapFromLLVMOrdering(Ordering);
+
+ return cast<AtomicCmpXchgInst>(P)->setFailureOrdering(O);
+}
/*===-- Module providers --------------------------------------------------===*/
diff --git a/llvm/test/Bindings/llvm-c/atomics.ll b/llvm/test/Bindings/llvm-c/atomics.ll
new file mode 100644
index 0000000..4fe62b0
--- /dev/null
+++ b/llvm/test/Bindings/llvm-c/atomics.ll
@@ -0,0 +1,10 @@
+; RUN: llvm-as < %s | llvm-dis > %t.orig
+; RUN: llvm-as < %s | llvm-c-test --echo > %t.echo
+; RUN: diff -w %t.orig %t.echo
+
+define i32 @main() {
+ %1 = alloca i32
+ %2 = cmpxchg i32* %1, i32 2, i32 3 seq_cst acquire
+ %3 = extractvalue { i32, i1 } %2, 0
+ ret i32 %3
+}
diff --git a/llvm/tools/llvm-c-test/echo.cpp b/llvm/tools/llvm-c-test/echo.cpp
index a8f9baf..5a2102a 100644
--- a/llvm/tools/llvm-c-test/echo.cpp
+++ b/llvm/tools/llvm-c-test/echo.cpp
@@ -522,6 +522,17 @@
Dst = LLVMBuildGEP(Builder, Ptr, Idx.data(), NumIdx, Name);
break;
}
+ case LLVMAtomicCmpXchg: {
+ LLVMValueRef Ptr = CloneValue(LLVMGetOperand(Src, 0));
+ LLVMValueRef Cmp = CloneValue(LLVMGetOperand(Src, 1));
+ LLVMValueRef New = CloneValue(LLVMGetOperand(Src, 2));
+ LLVMAtomicOrdering Succ = LLVMGetCmpXchgSuccessOrdering(Src);
+ LLVMAtomicOrdering Fail = LLVMGetCmpXchgFailureOrdering(Src);
+ LLVMBool SingleThread = LLVMIsAtomicSingleThread(Src);
+
+ Dst = LLVMBuildAtomicCmpXchg(Builder, Ptr, Cmp, New, Succ, Fail,
+ SingleThread);
+ } break;
case LLVMBitCast: {
LLVMValueRef V = CloneValue(LLVMGetOperand(Src, 0));
Dst = LLVMBuildBitCast(Builder, V, CloneType(Src), Name);