diff options
Diffstat (limited to 'llvm/lib/CodeGen/AtomicExpandPass.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AtomicExpandPass.cpp | 45 |
1 files changed, 38 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/AtomicExpandPass.cpp b/llvm/lib/CodeGen/AtomicExpandPass.cpp index 74cbea94542..e0c7fd6f883 100644 --- a/llvm/lib/CodeGen/AtomicExpandPass.cpp +++ b/llvm/lib/CodeGen/AtomicExpandPass.cpp @@ -937,6 +937,39 @@ bool llvm::expandAtomicRMWToCmpXchg(AtomicRMWInst *AI, return true; } +// This converts from LLVM's internal AtomicOrdering enum to the +// memory_order_* value required by the __atomic_* libcalls. +static int libcallAtomicModel(AtomicOrdering AO) { + enum { + AO_ABI_memory_order_relaxed = 0, + AO_ABI_memory_order_consume = 1, + AO_ABI_memory_order_acquire = 2, + AO_ABI_memory_order_release = 3, + AO_ABI_memory_order_acq_rel = 4, + AO_ABI_memory_order_seq_cst = 5 + }; + + switch (AO) { + case AtomicOrdering::NotAtomic: + llvm_unreachable("Expected atomic memory order."); + case AtomicOrdering::Unordered: + case AtomicOrdering::Monotonic: + return AO_ABI_memory_order_relaxed; + // Not implemented yet in llvm: + // case AtomicOrdering::Consume: + // return AO_ABI_memory_order_consume; + case AtomicOrdering::Acquire: + return AO_ABI_memory_order_acquire; + case AtomicOrdering::Release: + return AO_ABI_memory_order_release; + case AtomicOrdering::AcquireRelease: + return AO_ABI_memory_order_acq_rel; + case AtomicOrdering::SequentiallyConsistent: + return AO_ABI_memory_order_seq_cst; + } + llvm_unreachable("Unknown atomic memory order."); +} + // In order to use one of the sized library calls such as // __atomic_fetch_add_4, the alignment must be sufficient, the size // must be one of the potentially-specialized sizes, and the value @@ -1118,14 +1151,12 @@ bool AtomicExpand::expandAtomicOpToLibcall( // TODO: the "order" argument type is "int", not int32. So // getInt32Ty may be wrong if the arch uses e.g. 16-bit ints. ConstantInt *SizeVal64 = ConstantInt::get(Type::getInt64Ty(Ctx), Size); - assert(Ordering != AtomicOrdering::NotAtomic && "expect atomic MO"); Constant *OrderingVal = - ConstantInt::get(Type::getInt32Ty(Ctx), (int)toCABI(Ordering)); - assert(Ordering2 != AtomicOrdering::NotAtomic && "expect atomic MO"); - Constant *Ordering2Val = - CASExpected - ? ConstantInt::get(Type::getInt32Ty(Ctx), (int)toCABI(Ordering2)) - : nullptr; + ConstantInt::get(Type::getInt32Ty(Ctx), libcallAtomicModel(Ordering)); + Constant *Ordering2Val = CASExpected + ? ConstantInt::get(Type::getInt32Ty(Ctx), + libcallAtomicModel(Ordering2)) + : nullptr; bool HasResult = I->getType() != Type::getVoidTy(Ctx); RTLIB::Libcall RTLibType; |