Index: include/llvm-c/Core.h =================================================================== --- include/llvm-c/Core.h +++ 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); /** * @} Index: lib/IR/Core.cpp =================================================================== --- lib/IR/Core.cpp +++ 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(AtomicInst); + + if (AtomicRMWInst *I = dyn_cast(P)) + return I->getSynchScope() == SingleThread; + return cast(P)->getSynchScope() == SingleThread; +} + +void LLVMSetAtomicSingleThread(LLVMValueRef AtomicInst, LLVMBool NewValue) { + Value *P = unwrap(AtomicInst); + SynchronizationScope Sync = NewValue ? SingleThread : CrossThread; + + if (AtomicRMWInst *I = dyn_cast(P)) + return I->setSynchScope(Sync); + return cast(P)->setSynchScope(Sync); +} + +LLVMAtomicOrdering LLVMGetCmpXchgSuccessOrdering(LLVMValueRef CmpXchgInst) { + Value *P = unwrap(CmpXchgInst); + return mapToLLVMOrdering(cast(P)->getSuccessOrdering()); +} + +void LLVMSetCmpXchgSuccessOrdering(LLVMValueRef CmpXchgInst, + LLVMAtomicOrdering Ordering) { + Value *P = unwrap(CmpXchgInst); + AtomicOrdering O = mapFromLLVMOrdering(Ordering); + + return cast(P)->setSuccessOrdering(O); +} + +LLVMAtomicOrdering LLVMGetCmpXchgFailureOrdering(LLVMValueRef CmpXchgInst) { + Value *P = unwrap(CmpXchgInst); + return mapToLLVMOrdering(cast(P)->getFailureOrdering()); +} + +void LLVMSetCmpXchgFailureOrdering(LLVMValueRef CmpXchgInst, + LLVMAtomicOrdering Ordering) { + Value *P = unwrap(CmpXchgInst); + AtomicOrdering O = mapFromLLVMOrdering(Ordering); + + return cast(P)->setFailureOrdering(O); +} /*===-- Module providers --------------------------------------------------===*/ Index: test/Bindings/llvm-c/atomics.ll =================================================================== --- /dev/null +++ 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 +} Index: tools/llvm-c-test/echo.cpp =================================================================== --- tools/llvm-c-test/echo.cpp +++ 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);