diff --git a/llvm/lib/CodeGen/AtomicExpandPass.cpp b/llvm/lib/CodeGen/AtomicExpandPass.cpp index 0c8956081f7ce5..aa82069c8a360a 100644 --- a/llvm/lib/CodeGen/AtomicExpandPass.cpp +++ b/llvm/lib/CodeGen/AtomicExpandPass.cpp @@ -125,6 +125,14 @@ class AtomicExpand : public FunctionPass { CreateCmpXchgInstFun CreateCmpXchg); }; +// IRBuilder to be used for replacement atomic instructions. +struct ReplacementIRBuilder : IRBuilder<> { + // Preserves the DebugLoc from I, and preserves still valid metadata. + explicit ReplacementIRBuilder(Instruction *I) : IRBuilder<>(I) { + this->CollectMetadataToCopy(I, {LLVMContext::MD_pcsections}); + } +}; + } // end anonymous namespace char AtomicExpand::ID = 0; @@ -310,7 +318,7 @@ bool AtomicExpand::runOnFunction(Function &F) { } bool AtomicExpand::bracketInstWithFences(Instruction *I, AtomicOrdering Order) { - IRBuilder<> Builder(I); + ReplacementIRBuilder Builder(I); auto LeadingFence = TLI->emitLeadingFence(Builder, I, Order); @@ -339,7 +347,7 @@ LoadInst *AtomicExpand::convertAtomicLoadToIntegerType(LoadInst *LI) { auto *M = LI->getModule(); Type *NewTy = getCorrespondingIntegerType(LI->getType(), M->getDataLayout()); - IRBuilder<> Builder(LI); + ReplacementIRBuilder Builder(LI); Value *Addr = LI->getPointerOperand(); Type *PT = PointerType::get(NewTy, Addr->getType()->getPointerAddressSpace()); @@ -363,7 +371,7 @@ AtomicExpand::convertAtomicXchgToIntegerType(AtomicRMWInst *RMWI) { Type *NewTy = getCorrespondingIntegerType(RMWI->getType(), M->getDataLayout()); - IRBuilder<> Builder(RMWI); + ReplacementIRBuilder Builder(RMWI); Value *Addr = RMWI->getPointerOperand(); Value *Val = RMWI->getValOperand(); @@ -425,7 +433,7 @@ bool AtomicExpand::tryExpandAtomicStore(StoreInst *SI) { } bool AtomicExpand::expandAtomicLoadToLL(LoadInst *LI) { - IRBuilder<> Builder(LI); + ReplacementIRBuilder Builder(LI); // On some architectures, load-linked instructions are atomic for larger // sizes than normal loads. For example, the only 64-bit load guaranteed @@ -441,7 +449,7 @@ bool AtomicExpand::expandAtomicLoadToLL(LoadInst *LI) { } bool AtomicExpand::expandAtomicLoadToCmpXchg(LoadInst *LI) { - IRBuilder<> Builder(LI); + ReplacementIRBuilder Builder(LI); AtomicOrdering Order = LI->getOrdering(); if (Order == AtomicOrdering::Unordered) Order = AtomicOrdering::Monotonic; @@ -470,7 +478,7 @@ bool AtomicExpand::expandAtomicLoadToCmpXchg(LoadInst *LI) { /// mechanism, we convert back to the old format which the backends understand. /// Each backend will need individual work to recognize the new format. StoreInst *AtomicExpand::convertAtomicStoreToIntegerType(StoreInst *SI) { - IRBuilder<> Builder(SI); + ReplacementIRBuilder Builder(SI); auto *M = SI->getModule(); Type *NewTy = getCorrespondingIntegerType(SI->getValueOperand()->getType(), M->getDataLayout()); @@ -496,7 +504,7 @@ void AtomicExpand::expandAtomicStore(StoreInst *SI) { // or lock cmpxchg8/16b on X86, as these are atomic for larger sizes. // It is the responsibility of the target to only signal expansion via // shouldExpandAtomicRMW in cases where this is required and possible. - IRBuilder<> Builder(SI); + ReplacementIRBuilder Builder(SI); AtomicOrdering Ordering = SI->getOrdering(); assert(Ordering != AtomicOrdering::NotAtomic); AtomicOrdering RMWOrdering = Ordering == AtomicOrdering::Unordered @@ -798,7 +806,7 @@ void AtomicExpand::expandPartwordAtomicRMW( AtomicOrdering MemOpOrder = AI->getOrdering(); SyncScope::ID SSID = AI->getSyncScopeID(); - IRBuilder<> Builder(AI); + ReplacementIRBuilder Builder(AI); PartwordMaskValues PMV = createMaskInstrs(Builder, AI, AI->getType(), AI->getPointerOperand(), @@ -832,7 +840,7 @@ void AtomicExpand::expandPartwordAtomicRMW( // Widen the bitwise atomicrmw (or/xor/and) to the minimum supported width. AtomicRMWInst *AtomicExpand::widenPartwordAtomicRMW(AtomicRMWInst *AI) { - IRBuilder<> Builder(AI); + ReplacementIRBuilder Builder(AI); AtomicRMWInst::BinOp Op = AI->getOperation(); assert((Op == AtomicRMWInst::Or || Op == AtomicRMWInst::Xor || @@ -907,7 +915,7 @@ bool AtomicExpand::expandPartwordCmpXchg(AtomicCmpXchgInst *CI) { BasicBlock *BB = CI->getParent(); Function *F = BB->getParent(); - IRBuilder<> Builder(CI); + ReplacementIRBuilder Builder(CI); LLVMContext &Ctx = Builder.getContext(); BasicBlock *EndBB = @@ -994,7 +1002,7 @@ void AtomicExpand::expandAtomicOpToLLSC( Instruction *I, Type *ResultType, Value *Addr, Align AddrAlign, AtomicOrdering MemOpOrder, function_ref &, Value *)> PerformOp) { - IRBuilder<> Builder(I); + ReplacementIRBuilder Builder(I); Value *Loaded = insertRMWLLSCLoop(Builder, ResultType, Addr, AddrAlign, MemOpOrder, PerformOp); @@ -1003,7 +1011,7 @@ void AtomicExpand::expandAtomicOpToLLSC( } void AtomicExpand::expandAtomicRMWToMaskedIntrinsic(AtomicRMWInst *AI) { - IRBuilder<> Builder(AI); + ReplacementIRBuilder Builder(AI); PartwordMaskValues PMV = createMaskInstrs(Builder, AI, AI->getType(), AI->getPointerOperand(), @@ -1029,7 +1037,7 @@ void AtomicExpand::expandAtomicRMWToMaskedIntrinsic(AtomicRMWInst *AI) { } void AtomicExpand::expandAtomicCmpXchgToMaskedIntrinsic(AtomicCmpXchgInst *CI) { - IRBuilder<> Builder(CI); + ReplacementIRBuilder Builder(CI); PartwordMaskValues PMV = createMaskInstrs( Builder, CI, CI->getCompareOperand()->getType(), CI->getPointerOperand(), @@ -1116,7 +1124,7 @@ AtomicExpand::convertCmpXchgToIntegerType(AtomicCmpXchgInst *CI) { Type *NewTy = getCorrespondingIntegerType(CI->getCompareOperand()->getType(), M->getDataLayout()); - IRBuilder<> Builder(CI); + ReplacementIRBuilder Builder(CI); Value *Addr = CI->getPointerOperand(); Type *PT = PointerType::get(NewTy, Addr->getType()->getPointerAddressSpace()); @@ -1240,8 +1248,7 @@ bool AtomicExpand::expandAtomicCmpXchg(AtomicCmpXchgInst *CI) { BasicBlock::Create(Ctx, "cmpxchg.fencedstore", F, TryStoreBB); auto StartBB = BasicBlock::Create(Ctx, "cmpxchg.start", F, ReleasingStoreBB); - // This grabs the DebugLoc from CI - IRBuilder<> Builder(CI); + ReplacementIRBuilder Builder(CI); // The split call above "helpfully" added a branch at the end of BB (to the // wrong place), but we might want a fence too. It's easiest to just remove @@ -1506,7 +1513,7 @@ bool AtomicExpand::tryExpandAtomicCmpXchg(AtomicCmpXchgInst *CI) { // Note: This function is exposed externally by AtomicExpandUtils.h bool llvm::expandAtomicRMWToCmpXchg(AtomicRMWInst *AI, CreateCmpXchgInstFun CreateCmpXchg) { - IRBuilder<> Builder(AI); + ReplacementIRBuilder Builder(AI); Value *Loaded = AtomicExpand::insertRMWCmpXchgLoop( Builder, AI->getType(), AI->getPointerOperand(), AI->getAlign(), AI->getOrdering(), AI->getSyncScopeID(), diff --git a/llvm/test/Transforms/AtomicExpand/AArch64/pcsections.ll b/llvm/test/Transforms/AtomicExpand/AArch64/pcsections.ll new file mode 100644 index 00000000000000..6d15d28509d533 --- /dev/null +++ b/llvm/test/Transforms/AtomicExpand/AArch64/pcsections.ll @@ -0,0 +1,4376 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -mtriple=aarch64-linux-gnu -atomic-expand %s | FileCheck %s + +define i8 @atomic8_load_unordered(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_load_unordered( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load atomic i8, i8* [[A:%.*]] unordered, align 1, !pcsections !0 +; CHECK-NEXT: ret i8 [[TMP0]] +; +entry: + %0 = load atomic i8, i8* %a unordered, align 1, !pcsections !0 + ret i8 %0 +} + +define i8 @atomic8_load_monotonic(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_load_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load atomic i8, i8* [[A:%.*]] monotonic, align 1, !pcsections !0 +; CHECK-NEXT: ret i8 [[TMP0]] +; +entry: + %0 = load atomic i8, i8* %a monotonic, align 1, !pcsections !0 + ret i8 %0 +} + +define i8 @atomic8_load_acquire(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_load_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load atomic i8, i8* [[A:%.*]] acquire, align 1, !pcsections !0 +; CHECK-NEXT: ret i8 [[TMP0]] +; +entry: + %0 = load atomic i8, i8* %a acquire, align 1, !pcsections !0 + ret i8 %0 +} + +define i8 @atomic8_load_seq_cst(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_load_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load atomic i8, i8* [[A:%.*]] seq_cst, align 1, !pcsections !0 +; CHECK-NEXT: ret i8 [[TMP0]] +; +entry: + %0 = load atomic i8, i8* %a seq_cst, align 1, !pcsections !0 + ret i8 %0 +} + +define void @atomic8_store_unordered(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_store_unordered( +; CHECK-NEXT: entry: +; CHECK-NEXT: store atomic i8 0, i8* [[A:%.*]] unordered, align 1, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + store atomic i8 0, i8* %a unordered, align 1, !pcsections !0 + ret void +} + +define void @atomic8_store_monotonic(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_store_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: store atomic i8 0, i8* [[A:%.*]] monotonic, align 1, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + store atomic i8 0, i8* %a monotonic, align 1, !pcsections !0 + ret void +} + +define void @atomic8_store_release(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_store_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: store atomic i8 0, i8* [[A:%.*]] release, align 1, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + store atomic i8 0, i8* %a release, align 1, !pcsections !0 + ret void +} + +define void @atomic8_store_seq_cst(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_store_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: store atomic i8 0, i8* [[A:%.*]] seq_cst, align 1, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + store atomic i8 0, i8* %a seq_cst, align 1, !pcsections !0 + ret void +} + +define void @atomic8_xchg_monotonic(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_xchg_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 0 monotonic monotonic, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i8* %a, i8 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic8_add_monotonic(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_add_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] monotonic monotonic, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i8* %a, i8 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic8_sub_monotonic(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_sub_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] monotonic monotonic, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i8* %a, i8 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic8_and_monotonic(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_and_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] monotonic monotonic, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i8* %a, i8 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic8_or_monotonic(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_or_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] monotonic monotonic, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i8* %a, i8 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic8_xor_monotonic(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_xor_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] monotonic monotonic, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i8* %a, i8 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic8_nand_monotonic(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_nand_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i8 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] monotonic monotonic, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i8* %a, i8 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic8_xchg_acquire(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_xchg_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 0 acquire acquire, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i8* %a, i8 0 acquire, !pcsections !0 + ret void +} + +define void @atomic8_add_acquire(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_add_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] acquire acquire, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i8* %a, i8 0 acquire, !pcsections !0 + ret void +} + +define void @atomic8_sub_acquire(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_sub_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] acquire acquire, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i8* %a, i8 0 acquire, !pcsections !0 + ret void +} + +define void @atomic8_and_acquire(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_and_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] acquire acquire, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i8* %a, i8 0 acquire, !pcsections !0 + ret void +} + +define void @atomic8_or_acquire(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_or_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] acquire acquire, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i8* %a, i8 0 acquire, !pcsections !0 + ret void +} + +define void @atomic8_xor_acquire(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_xor_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] acquire acquire, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i8* %a, i8 0 acquire, !pcsections !0 + ret void +} + +define void @atomic8_nand_acquire(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_nand_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i8 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] acquire acquire, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i8* %a, i8 0 acquire, !pcsections !0 + ret void +} + +define void @atomic8_xchg_release(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_xchg_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 0 release monotonic, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i8* %a, i8 0 release, !pcsections !0 + ret void +} + +define void @atomic8_add_release(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_add_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] release monotonic, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i8* %a, i8 0 release, !pcsections !0 + ret void +} + +define void @atomic8_sub_release(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_sub_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] release monotonic, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i8* %a, i8 0 release, !pcsections !0 + ret void +} + +define void @atomic8_and_release(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_and_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] release monotonic, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i8* %a, i8 0 release, !pcsections !0 + ret void +} + +define void @atomic8_or_release(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_or_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] release monotonic, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i8* %a, i8 0 release, !pcsections !0 + ret void +} + +define void @atomic8_xor_release(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_xor_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] release monotonic, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i8* %a, i8 0 release, !pcsections !0 + ret void +} + +define void @atomic8_nand_release(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_nand_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i8 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] release monotonic, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i8* %a, i8 0 release, !pcsections !0 + ret void +} + +define void @atomic8_xchg_acq_rel(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_xchg_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 0 acq_rel acquire, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i8* %a, i8 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic8_add_acq_rel(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_add_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] acq_rel acquire, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i8* %a, i8 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic8_sub_acq_rel(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_sub_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] acq_rel acquire, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i8* %a, i8 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic8_and_acq_rel(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_and_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] acq_rel acquire, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i8* %a, i8 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic8_or_acq_rel(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_or_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] acq_rel acquire, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i8* %a, i8 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic8_xor_acq_rel(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_xor_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] acq_rel acquire, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i8* %a, i8 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic8_nand_acq_rel(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_nand_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i8 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] acq_rel acquire, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i8* %a, i8 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic8_xchg_seq_cst(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_xchg_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 0 seq_cst seq_cst, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i8* %a, i8 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic8_add_seq_cst(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_add_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] seq_cst seq_cst, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i8* %a, i8 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic8_sub_seq_cst(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_sub_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] seq_cst seq_cst, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i8* %a, i8 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic8_and_seq_cst(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_and_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] seq_cst seq_cst, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i8* %a, i8 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic8_or_seq_cst(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_or_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] seq_cst seq_cst, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i8* %a, i8 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic8_xor_seq_cst(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_xor_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] seq_cst seq_cst, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i8* %a, i8 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic8_nand_seq_cst(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_nand_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[A:%.*]], align 1, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i8 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i8 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i8* [[A]], i8 [[LOADED]], i8 [[NEW]] seq_cst seq_cst, align 1, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i8, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i8, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i8* %a, i8 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic8_cas_monotonic(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_cas_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i8* [[A:%.*]], i8 0, i8 1 monotonic monotonic, align 1, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 0, i8 1 monotonic acquire, align 1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i8* [[A]], i8 0, i8 1 monotonic seq_cst, align 1, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i8* %a, i8 0, i8 1 monotonic monotonic, !pcsections !0 + cmpxchg i8* %a, i8 0, i8 1 monotonic acquire, !pcsections !0 + cmpxchg i8* %a, i8 0, i8 1 monotonic seq_cst, !pcsections !0 + ret void +} + +define void @atomic8_cas_acquire(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_cas_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i8* [[A:%.*]], i8 0, i8 1 acquire monotonic, align 1, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 0, i8 1 acquire acquire, align 1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i8* [[A]], i8 0, i8 1 acquire seq_cst, align 1, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i8* %a, i8 0, i8 1 acquire monotonic, !pcsections !0 + cmpxchg i8* %a, i8 0, i8 1 acquire acquire, !pcsections !0 + cmpxchg i8* %a, i8 0, i8 1 acquire seq_cst, !pcsections !0 + ret void +} + +define void @atomic8_cas_release(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_cas_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i8* [[A:%.*]], i8 0, i8 1 release monotonic, align 1, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 0, i8 1 release acquire, align 1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i8* [[A]], i8 0, i8 1 release seq_cst, align 1, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i8* %a, i8 0, i8 1 release monotonic, !pcsections !0 + cmpxchg i8* %a, i8 0, i8 1 release acquire, !pcsections !0 + cmpxchg i8* %a, i8 0, i8 1 release seq_cst, !pcsections !0 + ret void +} + +define void @atomic8_cas_acq_rel(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_cas_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i8* [[A:%.*]], i8 0, i8 1 acq_rel monotonic, align 1, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 0, i8 1 acq_rel acquire, align 1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i8* [[A]], i8 0, i8 1 acq_rel seq_cst, align 1, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i8* %a, i8 0, i8 1 acq_rel monotonic, !pcsections !0 + cmpxchg i8* %a, i8 0, i8 1 acq_rel acquire, !pcsections !0 + cmpxchg i8* %a, i8 0, i8 1 acq_rel seq_cst, !pcsections !0 + ret void +} + +define void @atomic8_cas_seq_cst(i8* %a) nounwind uwtable { +; CHECK-LABEL: @atomic8_cas_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i8* [[A:%.*]], i8 0, i8 1 seq_cst monotonic, align 1, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i8* [[A]], i8 0, i8 1 seq_cst acquire, align 1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i8* [[A]], i8 0, i8 1 seq_cst seq_cst, align 1, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i8* %a, i8 0, i8 1 seq_cst monotonic, !pcsections !0 + cmpxchg i8* %a, i8 0, i8 1 seq_cst acquire, !pcsections !0 + cmpxchg i8* %a, i8 0, i8 1 seq_cst seq_cst, !pcsections !0 + ret void +} + +define i16 @atomic16_load_unordered(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_load_unordered( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load atomic i16, i16* [[A:%.*]] unordered, align 2, !pcsections !0 +; CHECK-NEXT: ret i16 [[TMP0]] +; +entry: + %0 = load atomic i16, i16* %a unordered, align 2, !pcsections !0 + ret i16 %0 +} + +define i16 @atomic16_load_monotonic(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_load_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load atomic i16, i16* [[A:%.*]] monotonic, align 2, !pcsections !0 +; CHECK-NEXT: ret i16 [[TMP0]] +; +entry: + %0 = load atomic i16, i16* %a monotonic, align 2, !pcsections !0 + ret i16 %0 +} + +define i16 @atomic16_load_acquire(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_load_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load atomic i16, i16* [[A:%.*]] acquire, align 2, !pcsections !0 +; CHECK-NEXT: ret i16 [[TMP0]] +; +entry: + %0 = load atomic i16, i16* %a acquire, align 2, !pcsections !0 + ret i16 %0 +} + +define i16 @atomic16_load_seq_cst(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_load_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load atomic i16, i16* [[A:%.*]] seq_cst, align 2, !pcsections !0 +; CHECK-NEXT: ret i16 [[TMP0]] +; +entry: + %0 = load atomic i16, i16* %a seq_cst, align 2, !pcsections !0 + ret i16 %0 +} + +define void @atomic16_store_unordered(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_store_unordered( +; CHECK-NEXT: entry: +; CHECK-NEXT: store atomic i16 0, i16* [[A:%.*]] unordered, align 2, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + store atomic i16 0, i16* %a unordered, align 2, !pcsections !0 + ret void +} + +define void @atomic16_store_monotonic(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_store_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: store atomic i16 0, i16* [[A:%.*]] monotonic, align 2, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + store atomic i16 0, i16* %a monotonic, align 2, !pcsections !0 + ret void +} + +define void @atomic16_store_release(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_store_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: store atomic i16 0, i16* [[A:%.*]] release, align 2, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + store atomic i16 0, i16* %a release, align 2, !pcsections !0 + ret void +} + +define void @atomic16_store_seq_cst(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_store_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: store atomic i16 0, i16* [[A:%.*]] seq_cst, align 2, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + store atomic i16 0, i16* %a seq_cst, align 2, !pcsections !0 + ret void +} + +define void @atomic16_xchg_monotonic(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_xchg_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 0 monotonic monotonic, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i16* %a, i16 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic16_add_monotonic(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_add_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] monotonic monotonic, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i16* %a, i16 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic16_sub_monotonic(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_sub_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] monotonic monotonic, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i16* %a, i16 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic16_and_monotonic(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_and_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] monotonic monotonic, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i16* %a, i16 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic16_or_monotonic(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_or_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] monotonic monotonic, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i16* %a, i16 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic16_xor_monotonic(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_xor_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] monotonic monotonic, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i16* %a, i16 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic16_nand_monotonic(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_nand_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i16 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] monotonic monotonic, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i16* %a, i16 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic16_xchg_acquire(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_xchg_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 0 acquire acquire, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i16* %a, i16 0 acquire, !pcsections !0 + ret void +} + +define void @atomic16_add_acquire(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_add_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] acquire acquire, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i16* %a, i16 0 acquire, !pcsections !0 + ret void +} + +define void @atomic16_sub_acquire(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_sub_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] acquire acquire, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i16* %a, i16 0 acquire, !pcsections !0 + ret void +} + +define void @atomic16_and_acquire(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_and_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] acquire acquire, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i16* %a, i16 0 acquire, !pcsections !0 + ret void +} + +define void @atomic16_or_acquire(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_or_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] acquire acquire, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i16* %a, i16 0 acquire, !pcsections !0 + ret void +} + +define void @atomic16_xor_acquire(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_xor_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] acquire acquire, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i16* %a, i16 0 acquire, !pcsections !0 + ret void +} + +define void @atomic16_nand_acquire(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_nand_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i16 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] acquire acquire, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i16* %a, i16 0 acquire, !pcsections !0 + ret void +} + +define void @atomic16_xchg_release(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_xchg_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 0 release monotonic, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i16* %a, i16 0 release, !pcsections !0 + ret void +} + +define void @atomic16_add_release(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_add_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] release monotonic, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i16* %a, i16 0 release, !pcsections !0 + ret void +} + +define void @atomic16_sub_release(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_sub_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] release monotonic, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i16* %a, i16 0 release, !pcsections !0 + ret void +} + +define void @atomic16_and_release(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_and_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] release monotonic, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i16* %a, i16 0 release, !pcsections !0 + ret void +} + +define void @atomic16_or_release(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_or_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] release monotonic, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i16* %a, i16 0 release, !pcsections !0 + ret void +} + +define void @atomic16_xor_release(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_xor_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] release monotonic, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i16* %a, i16 0 release, !pcsections !0 + ret void +} + +define void @atomic16_nand_release(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_nand_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i16 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] release monotonic, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i16* %a, i16 0 release, !pcsections !0 + ret void +} + +define void @atomic16_xchg_acq_rel(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_xchg_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 0 acq_rel acquire, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i16* %a, i16 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic16_add_acq_rel(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_add_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] acq_rel acquire, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i16* %a, i16 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic16_sub_acq_rel(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_sub_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] acq_rel acquire, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i16* %a, i16 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic16_and_acq_rel(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_and_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] acq_rel acquire, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i16* %a, i16 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic16_or_acq_rel(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_or_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] acq_rel acquire, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i16* %a, i16 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic16_xor_acq_rel(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_xor_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] acq_rel acquire, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i16* %a, i16 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic16_nand_acq_rel(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_nand_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i16 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] acq_rel acquire, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i16* %a, i16 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic16_xchg_seq_cst(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_xchg_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 0 seq_cst seq_cst, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i16* %a, i16 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic16_add_seq_cst(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_add_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] seq_cst seq_cst, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i16* %a, i16 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic16_sub_seq_cst(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_sub_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] seq_cst seq_cst, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i16* %a, i16 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic16_and_seq_cst(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_and_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] seq_cst seq_cst, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i16* %a, i16 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic16_or_seq_cst(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_or_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] seq_cst seq_cst, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i16* %a, i16 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic16_xor_seq_cst(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_xor_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] seq_cst seq_cst, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i16* %a, i16 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic16_nand_seq_cst(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_nand_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* [[A:%.*]], align 2, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i16 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i16 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i16* [[A]], i16 [[LOADED]], i16 [[NEW]] seq_cst seq_cst, align 2, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i16, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i16, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i16* %a, i16 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic16_cas_monotonic(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_cas_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i16* [[A:%.*]], i16 0, i16 1 monotonic monotonic, align 2, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 0, i16 1 monotonic acquire, align 2, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i16* [[A]], i16 0, i16 1 monotonic seq_cst, align 2, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i16* %a, i16 0, i16 1 monotonic monotonic, !pcsections !0 + cmpxchg i16* %a, i16 0, i16 1 monotonic acquire, !pcsections !0 + cmpxchg i16* %a, i16 0, i16 1 monotonic seq_cst, !pcsections !0 + ret void +} + +define void @atomic16_cas_acquire(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_cas_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i16* [[A:%.*]], i16 0, i16 1 acquire monotonic, align 2, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 0, i16 1 acquire acquire, align 2, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i16* [[A]], i16 0, i16 1 acquire seq_cst, align 2, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i16* %a, i16 0, i16 1 acquire monotonic, !pcsections !0 + cmpxchg i16* %a, i16 0, i16 1 acquire acquire, !pcsections !0 + cmpxchg i16* %a, i16 0, i16 1 acquire seq_cst, !pcsections !0 + ret void +} + +define void @atomic16_cas_release(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_cas_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i16* [[A:%.*]], i16 0, i16 1 release monotonic, align 2, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 0, i16 1 release acquire, align 2, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i16* [[A]], i16 0, i16 1 release seq_cst, align 2, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i16* %a, i16 0, i16 1 release monotonic, !pcsections !0 + cmpxchg i16* %a, i16 0, i16 1 release acquire, !pcsections !0 + cmpxchg i16* %a, i16 0, i16 1 release seq_cst, !pcsections !0 + ret void +} + +define void @atomic16_cas_acq_rel(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_cas_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i16* [[A:%.*]], i16 0, i16 1 acq_rel monotonic, align 2, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 0, i16 1 acq_rel acquire, align 2, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i16* [[A]], i16 0, i16 1 acq_rel seq_cst, align 2, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i16* %a, i16 0, i16 1 acq_rel monotonic, !pcsections !0 + cmpxchg i16* %a, i16 0, i16 1 acq_rel acquire, !pcsections !0 + cmpxchg i16* %a, i16 0, i16 1 acq_rel seq_cst, !pcsections !0 + ret void +} + +define void @atomic16_cas_seq_cst(i16* %a) nounwind uwtable { +; CHECK-LABEL: @atomic16_cas_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i16* [[A:%.*]], i16 0, i16 1 seq_cst monotonic, align 2, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i16* [[A]], i16 0, i16 1 seq_cst acquire, align 2, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i16* [[A]], i16 0, i16 1 seq_cst seq_cst, align 2, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i16* %a, i16 0, i16 1 seq_cst monotonic, !pcsections !0 + cmpxchg i16* %a, i16 0, i16 1 seq_cst acquire, !pcsections !0 + cmpxchg i16* %a, i16 0, i16 1 seq_cst seq_cst, !pcsections !0 + ret void +} + +define i32 @atomic32_load_unordered(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_load_unordered( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load atomic i32, i32* [[A:%.*]] unordered, align 4, !pcsections !0 +; CHECK-NEXT: ret i32 [[TMP0]] +; +entry: + %0 = load atomic i32, i32* %a unordered, align 4, !pcsections !0 + ret i32 %0 +} + +define i32 @atomic32_load_monotonic(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_load_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load atomic i32, i32* [[A:%.*]] monotonic, align 4, !pcsections !0 +; CHECK-NEXT: ret i32 [[TMP0]] +; +entry: + %0 = load atomic i32, i32* %a monotonic, align 4, !pcsections !0 + ret i32 %0 +} + +define i32 @atomic32_load_acquire(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_load_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load atomic i32, i32* [[A:%.*]] acquire, align 4, !pcsections !0 +; CHECK-NEXT: ret i32 [[TMP0]] +; +entry: + %0 = load atomic i32, i32* %a acquire, align 4, !pcsections !0 + ret i32 %0 +} + +define i32 @atomic32_load_seq_cst(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_load_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load atomic i32, i32* [[A:%.*]] seq_cst, align 4, !pcsections !0 +; CHECK-NEXT: ret i32 [[TMP0]] +; +entry: + %0 = load atomic i32, i32* %a seq_cst, align 4, !pcsections !0 + ret i32 %0 +} + +define void @atomic32_store_unordered(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_store_unordered( +; CHECK-NEXT: entry: +; CHECK-NEXT: store atomic i32 0, i32* [[A:%.*]] unordered, align 4, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + store atomic i32 0, i32* %a unordered, align 4, !pcsections !0 + ret void +} + +define void @atomic32_store_monotonic(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_store_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: store atomic i32 0, i32* [[A:%.*]] monotonic, align 4, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + store atomic i32 0, i32* %a monotonic, align 4, !pcsections !0 + ret void +} + +define void @atomic32_store_release(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_store_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: store atomic i32 0, i32* [[A:%.*]] release, align 4, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + store atomic i32 0, i32* %a release, align 4, !pcsections !0 + ret void +} + +define void @atomic32_store_seq_cst(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_store_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: store atomic i32 0, i32* [[A:%.*]] seq_cst, align 4, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + store atomic i32 0, i32* %a seq_cst, align 4, !pcsections !0 + ret void +} + +define void @atomic32_xchg_monotonic(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_xchg_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 0 monotonic monotonic, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i32* %a, i32 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic32_add_monotonic(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_add_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] monotonic monotonic, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i32* %a, i32 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic32_sub_monotonic(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_sub_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] monotonic monotonic, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i32* %a, i32 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic32_and_monotonic(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_and_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] monotonic monotonic, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i32* %a, i32 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic32_or_monotonic(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_or_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] monotonic monotonic, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i32* %a, i32 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic32_xor_monotonic(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_xor_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] monotonic monotonic, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i32* %a, i32 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic32_nand_monotonic(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_nand_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i32 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] monotonic monotonic, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i32* %a, i32 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic32_xchg_acquire(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_xchg_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 0 acquire acquire, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i32* %a, i32 0 acquire, !pcsections !0 + ret void +} + +define void @atomic32_add_acquire(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_add_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] acquire acquire, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i32* %a, i32 0 acquire, !pcsections !0 + ret void +} + +define void @atomic32_sub_acquire(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_sub_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] acquire acquire, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i32* %a, i32 0 acquire, !pcsections !0 + ret void +} + +define void @atomic32_and_acquire(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_and_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] acquire acquire, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i32* %a, i32 0 acquire, !pcsections !0 + ret void +} + +define void @atomic32_or_acquire(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_or_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] acquire acquire, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i32* %a, i32 0 acquire, !pcsections !0 + ret void +} + +define void @atomic32_xor_acquire(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_xor_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] acquire acquire, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i32* %a, i32 0 acquire, !pcsections !0 + ret void +} + +define void @atomic32_nand_acquire(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_nand_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i32 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] acquire acquire, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i32* %a, i32 0 acquire, !pcsections !0 + ret void +} + +define void @atomic32_xchg_release(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_xchg_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 0 release monotonic, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i32* %a, i32 0 release, !pcsections !0 + ret void +} + +define void @atomic32_add_release(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_add_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] release monotonic, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i32* %a, i32 0 release, !pcsections !0 + ret void +} + +define void @atomic32_sub_release(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_sub_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] release monotonic, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i32* %a, i32 0 release, !pcsections !0 + ret void +} + +define void @atomic32_and_release(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_and_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] release monotonic, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i32* %a, i32 0 release, !pcsections !0 + ret void +} + +define void @atomic32_or_release(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_or_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] release monotonic, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i32* %a, i32 0 release, !pcsections !0 + ret void +} + +define void @atomic32_xor_release(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_xor_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] release monotonic, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i32* %a, i32 0 release, !pcsections !0 + ret void +} + +define void @atomic32_nand_release(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_nand_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i32 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] release monotonic, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i32* %a, i32 0 release, !pcsections !0 + ret void +} + +define void @atomic32_xchg_acq_rel(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_xchg_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 0 acq_rel acquire, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i32* %a, i32 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic32_add_acq_rel(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_add_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] acq_rel acquire, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i32* %a, i32 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic32_sub_acq_rel(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_sub_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] acq_rel acquire, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i32* %a, i32 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic32_and_acq_rel(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_and_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] acq_rel acquire, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i32* %a, i32 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic32_or_acq_rel(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_or_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] acq_rel acquire, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i32* %a, i32 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic32_xor_acq_rel(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_xor_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] acq_rel acquire, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i32* %a, i32 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic32_nand_acq_rel(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_nand_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i32 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] acq_rel acquire, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i32* %a, i32 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic32_xchg_seq_cst(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_xchg_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 0 seq_cst seq_cst, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i32* %a, i32 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic32_add_seq_cst(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_add_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] seq_cst seq_cst, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i32* %a, i32 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic32_sub_seq_cst(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_sub_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] seq_cst seq_cst, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i32* %a, i32 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic32_and_seq_cst(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_and_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] seq_cst seq_cst, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i32* %a, i32 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic32_or_seq_cst(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_or_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] seq_cst seq_cst, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i32* %a, i32 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic32_xor_seq_cst(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_xor_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] seq_cst seq_cst, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i32* %a, i32 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic32_nand_seq_cst(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_nand_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i32 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i32* [[A]], i32 [[LOADED]], i32 [[NEW]] seq_cst seq_cst, align 4, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i32* %a, i32 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic32_cas_monotonic(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_cas_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i32* [[A:%.*]], i32 0, i32 1 monotonic monotonic, align 4, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 0, i32 1 monotonic acquire, align 4, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i32* [[A]], i32 0, i32 1 monotonic seq_cst, align 4, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i32* %a, i32 0, i32 1 monotonic monotonic, !pcsections !0 + cmpxchg i32* %a, i32 0, i32 1 monotonic acquire, !pcsections !0 + cmpxchg i32* %a, i32 0, i32 1 monotonic seq_cst, !pcsections !0 + ret void +} + +define void @atomic32_cas_acquire(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_cas_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i32* [[A:%.*]], i32 0, i32 1 acquire monotonic, align 4, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 0, i32 1 acquire acquire, align 4, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i32* [[A]], i32 0, i32 1 acquire seq_cst, align 4, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i32* %a, i32 0, i32 1 acquire monotonic, !pcsections !0 + cmpxchg i32* %a, i32 0, i32 1 acquire acquire, !pcsections !0 + cmpxchg i32* %a, i32 0, i32 1 acquire seq_cst, !pcsections !0 + ret void +} + +define void @atomic32_cas_release(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_cas_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i32* [[A:%.*]], i32 0, i32 1 release monotonic, align 4, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 0, i32 1 release acquire, align 4, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i32* [[A]], i32 0, i32 1 release seq_cst, align 4, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i32* %a, i32 0, i32 1 release monotonic, !pcsections !0 + cmpxchg i32* %a, i32 0, i32 1 release acquire, !pcsections !0 + cmpxchg i32* %a, i32 0, i32 1 release seq_cst, !pcsections !0 + ret void +} + +define void @atomic32_cas_acq_rel(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_cas_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i32* [[A:%.*]], i32 0, i32 1 acq_rel monotonic, align 4, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 0, i32 1 acq_rel acquire, align 4, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i32* [[A]], i32 0, i32 1 acq_rel seq_cst, align 4, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i32* %a, i32 0, i32 1 acq_rel monotonic, !pcsections !0 + cmpxchg i32* %a, i32 0, i32 1 acq_rel acquire, !pcsections !0 + cmpxchg i32* %a, i32 0, i32 1 acq_rel seq_cst, !pcsections !0 + ret void +} + +define void @atomic32_cas_seq_cst(i32* %a) nounwind uwtable { +; CHECK-LABEL: @atomic32_cas_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i32* [[A:%.*]], i32 0, i32 1 seq_cst monotonic, align 4, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[A]], i32 0, i32 1 seq_cst acquire, align 4, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i32* [[A]], i32 0, i32 1 seq_cst seq_cst, align 4, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i32* %a, i32 0, i32 1 seq_cst monotonic, !pcsections !0 + cmpxchg i32* %a, i32 0, i32 1 seq_cst acquire, !pcsections !0 + cmpxchg i32* %a, i32 0, i32 1 seq_cst seq_cst, !pcsections !0 + ret void +} + +define i64 @atomic64_load_unordered(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_load_unordered( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load atomic i64, i64* [[A:%.*]] unordered, align 8, !pcsections !0 +; CHECK-NEXT: ret i64 [[TMP0]] +; +entry: + %0 = load atomic i64, i64* %a unordered, align 8, !pcsections !0 + ret i64 %0 +} + +define i64 @atomic64_load_monotonic(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_load_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load atomic i64, i64* [[A:%.*]] monotonic, align 8, !pcsections !0 +; CHECK-NEXT: ret i64 [[TMP0]] +; +entry: + %0 = load atomic i64, i64* %a monotonic, align 8, !pcsections !0 + ret i64 %0 +} + +define i64 @atomic64_load_acquire(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_load_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load atomic i64, i64* [[A:%.*]] acquire, align 8, !pcsections !0 +; CHECK-NEXT: ret i64 [[TMP0]] +; +entry: + %0 = load atomic i64, i64* %a acquire, align 8, !pcsections !0 + ret i64 %0 +} + +define i64 @atomic64_load_seq_cst(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_load_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load atomic i64, i64* [[A:%.*]] seq_cst, align 8, !pcsections !0 +; CHECK-NEXT: ret i64 [[TMP0]] +; +entry: + %0 = load atomic i64, i64* %a seq_cst, align 8, !pcsections !0 + ret i64 %0 +} + +define i8* @atomic64_load_seq_cst_ptr_ty(i8** %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_load_seq_cst_ptr_ty( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load atomic i8*, i8** [[A:%.*]] seq_cst, align 8, !pcsections !0 +; CHECK-NEXT: ret i8* [[TMP0]] +; +entry: + %0 = load atomic i8*, i8** %a seq_cst, align 8, !pcsections !0 + ret i8* %0 +} + +define void @atomic64_store_unordered(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_store_unordered( +; CHECK-NEXT: entry: +; CHECK-NEXT: store atomic i64 0, i64* [[A:%.*]] unordered, align 8, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + store atomic i64 0, i64* %a unordered, align 8, !pcsections !0 + ret void +} + +define void @atomic64_store_monotonic(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_store_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: store atomic i64 0, i64* [[A:%.*]] monotonic, align 8, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + store atomic i64 0, i64* %a monotonic, align 8, !pcsections !0 + ret void +} + +define void @atomic64_store_release(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_store_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: store atomic i64 0, i64* [[A:%.*]] release, align 8, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + store atomic i64 0, i64* %a release, align 8, !pcsections !0 + ret void +} + +define void @atomic64_store_seq_cst(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_store_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: store atomic i64 0, i64* [[A:%.*]] seq_cst, align 8, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + store atomic i64 0, i64* %a seq_cst, align 8, !pcsections !0 + ret void +} + +define void @atomic64_store_seq_cst_ptr_ty(i8** %a, i8* %v) nounwind uwtable { +; CHECK-LABEL: @atomic64_store_seq_cst_ptr_ty( +; CHECK-NEXT: entry: +; CHECK-NEXT: store atomic i8* [[V:%.*]], i8** [[A:%.*]] seq_cst, align 8, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + store atomic i8* %v, i8** %a seq_cst, align 8, !pcsections !0 + ret void +} + +define void @atomic64_xchg_monotonic(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_xchg_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 0 monotonic monotonic, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i64* %a, i64 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic64_add_monotonic(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_add_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] monotonic monotonic, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i64* %a, i64 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic64_sub_monotonic(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_sub_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] monotonic monotonic, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i64* %a, i64 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic64_and_monotonic(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_and_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] monotonic monotonic, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i64* %a, i64 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic64_or_monotonic(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_or_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] monotonic monotonic, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i64* %a, i64 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic64_xor_monotonic(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_xor_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] monotonic monotonic, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i64* %a, i64 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic64_nand_monotonic(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_nand_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i64 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] monotonic monotonic, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i64* %a, i64 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic64_xchg_acquire(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_xchg_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 0 acquire acquire, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i64* %a, i64 0 acquire, !pcsections !0 + ret void +} + +define void @atomic64_add_acquire(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_add_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] acquire acquire, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i64* %a, i64 0 acquire, !pcsections !0 + ret void +} + +define void @atomic64_sub_acquire(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_sub_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] acquire acquire, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i64* %a, i64 0 acquire, !pcsections !0 + ret void +} + +define void @atomic64_and_acquire(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_and_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] acquire acquire, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i64* %a, i64 0 acquire, !pcsections !0 + ret void +} + +define void @atomic64_or_acquire(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_or_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] acquire acquire, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i64* %a, i64 0 acquire, !pcsections !0 + ret void +} + +define void @atomic64_xor_acquire(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_xor_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] acquire acquire, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i64* %a, i64 0 acquire, !pcsections !0 + ret void +} + +define void @atomic64_nand_acquire(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_nand_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i64 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] acquire acquire, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i64* %a, i64 0 acquire, !pcsections !0 + ret void +} + +define void @atomic64_xchg_release(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_xchg_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 0 release monotonic, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i64* %a, i64 0 release, !pcsections !0 + ret void +} + +define void @atomic64_add_release(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_add_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] release monotonic, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i64* %a, i64 0 release, !pcsections !0 + ret void +} + +define void @atomic64_sub_release(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_sub_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] release monotonic, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i64* %a, i64 0 release, !pcsections !0 + ret void +} + +define void @atomic64_and_release(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_and_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] release monotonic, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i64* %a, i64 0 release, !pcsections !0 + ret void +} + +define void @atomic64_or_release(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_or_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] release monotonic, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i64* %a, i64 0 release, !pcsections !0 + ret void +} + +define void @atomic64_xor_release(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_xor_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] release monotonic, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i64* %a, i64 0 release, !pcsections !0 + ret void +} + +define void @atomic64_nand_release(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_nand_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i64 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] release monotonic, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i64* %a, i64 0 release, !pcsections !0 + ret void +} + +define void @atomic64_xchg_acq_rel(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_xchg_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 0 acq_rel acquire, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i64* %a, i64 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic64_add_acq_rel(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_add_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] acq_rel acquire, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i64* %a, i64 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic64_sub_acq_rel(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_sub_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] acq_rel acquire, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i64* %a, i64 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic64_and_acq_rel(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_and_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] acq_rel acquire, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i64* %a, i64 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic64_or_acq_rel(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_or_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] acq_rel acquire, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i64* %a, i64 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic64_xor_acq_rel(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_xor_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] acq_rel acquire, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i64* %a, i64 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic64_nand_acq_rel(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_nand_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i64 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] acq_rel acquire, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i64* %a, i64 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic64_xchg_seq_cst(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_xchg_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 0 seq_cst seq_cst, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i64* %a, i64 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic64_add_seq_cst(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_add_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] seq_cst seq_cst, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i64* %a, i64 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic64_sub_seq_cst(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_sub_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] seq_cst seq_cst, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i64* %a, i64 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic64_and_seq_cst(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_and_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] seq_cst seq_cst, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i64* %a, i64 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic64_or_seq_cst(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_or_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] seq_cst seq_cst, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i64* %a, i64 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic64_xor_seq_cst(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_xor_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] seq_cst seq_cst, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i64* %a, i64 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic64_nand_seq_cst(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_nand_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A:%.*]], align 8, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i64 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i64* [[A]], i64 [[LOADED]], i64 [[NEW]] seq_cst seq_cst, align 8, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i64* %a, i64 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic64_cas_monotonic(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_cas_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i64* [[A:%.*]], i64 0, i64 1 monotonic monotonic, align 8, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 0, i64 1 monotonic acquire, align 8, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i64* [[A]], i64 0, i64 1 monotonic seq_cst, align 8, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i64* %a, i64 0, i64 1 monotonic monotonic, !pcsections !0 + cmpxchg i64* %a, i64 0, i64 1 monotonic acquire, !pcsections !0 + cmpxchg i64* %a, i64 0, i64 1 monotonic seq_cst, !pcsections !0 + ret void +} + +define void @atomic64_cas_acquire(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_cas_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i64* [[A:%.*]], i64 0, i64 1 acquire monotonic, align 8, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 0, i64 1 acquire acquire, align 8, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i64* [[A]], i64 0, i64 1 acquire seq_cst, align 8, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i64* %a, i64 0, i64 1 acquire monotonic, !pcsections !0 + cmpxchg i64* %a, i64 0, i64 1 acquire acquire, !pcsections !0 + cmpxchg i64* %a, i64 0, i64 1 acquire seq_cst, !pcsections !0 + ret void +} + +define void @atomic64_cas_release(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_cas_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i64* [[A:%.*]], i64 0, i64 1 release monotonic, align 8, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 0, i64 1 release acquire, align 8, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i64* [[A]], i64 0, i64 1 release seq_cst, align 8, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i64* %a, i64 0, i64 1 release monotonic, !pcsections !0 + cmpxchg i64* %a, i64 0, i64 1 release acquire, !pcsections !0 + cmpxchg i64* %a, i64 0, i64 1 release seq_cst, !pcsections !0 + ret void +} + +define void @atomic64_cas_acq_rel(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_cas_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i64* [[A:%.*]], i64 0, i64 1 acq_rel monotonic, align 8, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 0, i64 1 acq_rel acquire, align 8, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i64* [[A]], i64 0, i64 1 acq_rel seq_cst, align 8, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i64* %a, i64 0, i64 1 acq_rel monotonic, !pcsections !0 + cmpxchg i64* %a, i64 0, i64 1 acq_rel acquire, !pcsections !0 + cmpxchg i64* %a, i64 0, i64 1 acq_rel seq_cst, !pcsections !0 + ret void +} + +define void @atomic64_cas_seq_cst(i64* %a) nounwind uwtable { +; CHECK-LABEL: @atomic64_cas_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i64* [[A:%.*]], i64 0, i64 1 seq_cst monotonic, align 8, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i64* [[A]], i64 0, i64 1 seq_cst acquire, align 8, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i64* [[A]], i64 0, i64 1 seq_cst seq_cst, align 8, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i64* %a, i64 0, i64 1 seq_cst monotonic, !pcsections !0 + cmpxchg i64* %a, i64 0, i64 1 seq_cst acquire, !pcsections !0 + cmpxchg i64* %a, i64 0, i64 1 seq_cst seq_cst, !pcsections !0 + ret void +} + +define void @atomic64_cas_seq_cst_ptr_ty(i8** %a, i8* %v1, i8* %v2) nounwind uwtable { +; CHECK-LABEL: @atomic64_cas_seq_cst_ptr_ty( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8** [[A:%.*]] to i64*, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint i8* [[V1:%.*]] to i64, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = ptrtoint i8* [[V2:%.*]] to i64, !pcsections !0 +; CHECK-NEXT: [[TMP3:%.*]] = cmpxchg i64* [[TMP0]], i64 [[TMP1]], i64 [[TMP2]] seq_cst seq_cst, align 8, !pcsections !0 +; CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i64, i1 } [[TMP3]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP5:%.*]] = extractvalue { i64, i1 } [[TMP3]], 1, !pcsections !0 +; CHECK-NEXT: [[TMP6:%.*]] = inttoptr i64 [[TMP4]] to i8*, !pcsections !0 +; CHECK-NEXT: [[TMP7:%.*]] = insertvalue { i8*, i1 } undef, i8* [[TMP6]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP8:%.*]] = insertvalue { i8*, i1 } [[TMP7]], i1 [[TMP5]], 1, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i8** %a, i8* %v1, i8* %v2 seq_cst seq_cst, !pcsections !0 + ret void +} + +define i128 @atomic128_load_unordered(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_load_unordered( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i128* [[A:%.*]], i128 0, i128 0 monotonic monotonic, align 16, !pcsections !0 +; CHECK-NEXT: [[LOADED:%.*]] = extractvalue { i128, i1 } [[TMP0]], 0, !pcsections !0 +; CHECK-NEXT: ret i128 [[LOADED]] +; +entry: + %0 = load atomic i128, i128* %a unordered, align 16, !pcsections !0 + ret i128 %0 +} + +define i128 @atomic128_load_monotonic(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_load_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i128* [[A:%.*]], i128 0, i128 0 monotonic monotonic, align 16, !pcsections !0 +; CHECK-NEXT: [[LOADED:%.*]] = extractvalue { i128, i1 } [[TMP0]], 0, !pcsections !0 +; CHECK-NEXT: ret i128 [[LOADED]] +; +entry: + %0 = load atomic i128, i128* %a monotonic, align 16, !pcsections !0 + ret i128 %0 +} + +define i128 @atomic128_load_acquire(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_load_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i128* [[A:%.*]], i128 0, i128 0 acquire acquire, align 16, !pcsections !0 +; CHECK-NEXT: [[LOADED:%.*]] = extractvalue { i128, i1 } [[TMP0]], 0, !pcsections !0 +; CHECK-NEXT: ret i128 [[LOADED]] +; +entry: + %0 = load atomic i128, i128* %a acquire, align 16, !pcsections !0 + ret i128 %0 +} + +define i128 @atomic128_load_seq_cst(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_load_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i128* [[A:%.*]], i128 0, i128 0 seq_cst seq_cst, align 16, !pcsections !0 +; CHECK-NEXT: [[LOADED:%.*]] = extractvalue { i128, i1 } [[TMP0]], 0, !pcsections !0 +; CHECK-NEXT: ret i128 [[LOADED]] +; +entry: + %0 = load atomic i128, i128* %a seq_cst, align 16, !pcsections !0 + ret i128 %0 +} + +define void @atomic128_store_unordered(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_store_unordered( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 0 monotonic monotonic, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + store atomic i128 0, i128* %a unordered, align 16, !pcsections !0 + ret void +} + +define void @atomic128_store_monotonic(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_store_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 0 monotonic monotonic, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + store atomic i128 0, i128* %a monotonic, align 16, !pcsections !0 + ret void +} + +define void @atomic128_store_release(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_store_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 0 release monotonic, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + store atomic i128 0, i128* %a release, align 16, !pcsections !0 + ret void +} + +define void @atomic128_store_seq_cst(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_store_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 0 seq_cst seq_cst, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + store atomic i128 0, i128* %a seq_cst, align 16, !pcsections !0 + ret void +} + +define void @atomic128_xchg_monotonic(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_xchg_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 0 monotonic monotonic, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i128* %a, i128 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic128_add_monotonic(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_add_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] monotonic monotonic, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i128* %a, i128 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic128_sub_monotonic(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_sub_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] monotonic monotonic, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i128* %a, i128 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic128_and_monotonic(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_and_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] monotonic monotonic, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i128* %a, i128 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic128_or_monotonic(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_or_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] monotonic monotonic, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i128* %a, i128 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic128_xor_monotonic(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_xor_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] monotonic monotonic, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i128* %a, i128 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic128_nand_monotonic(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_nand_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i128 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] monotonic monotonic, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i128* %a, i128 0 monotonic, !pcsections !0 + ret void +} + +define void @atomic128_xchg_acquire(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_xchg_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 0 acquire acquire, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i128* %a, i128 0 acquire, !pcsections !0 + ret void +} + +define void @atomic128_add_acquire(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_add_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] acquire acquire, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i128* %a, i128 0 acquire, !pcsections !0 + ret void +} + +define void @atomic128_sub_acquire(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_sub_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] acquire acquire, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i128* %a, i128 0 acquire, !pcsections !0 + ret void +} + +define void @atomic128_and_acquire(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_and_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] acquire acquire, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i128* %a, i128 0 acquire, !pcsections !0 + ret void +} + +define void @atomic128_or_acquire(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_or_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] acquire acquire, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i128* %a, i128 0 acquire, !pcsections !0 + ret void +} + +define void @atomic128_xor_acquire(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_xor_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] acquire acquire, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i128* %a, i128 0 acquire, !pcsections !0 + ret void +} + +define void @atomic128_nand_acquire(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_nand_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i128 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] acquire acquire, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i128* %a, i128 0 acquire, !pcsections !0 + ret void +} + +define void @atomic128_xchg_release(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_xchg_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 0 release monotonic, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i128* %a, i128 0 release, !pcsections !0 + ret void +} + +define void @atomic128_add_release(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_add_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] release monotonic, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i128* %a, i128 0 release, !pcsections !0 + ret void +} + +define void @atomic128_sub_release(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_sub_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] release monotonic, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i128* %a, i128 0 release, !pcsections !0 + ret void +} + +define void @atomic128_and_release(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_and_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] release monotonic, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i128* %a, i128 0 release, !pcsections !0 + ret void +} + +define void @atomic128_or_release(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_or_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] release monotonic, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i128* %a, i128 0 release, !pcsections !0 + ret void +} + +define void @atomic128_xor_release(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_xor_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] release monotonic, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i128* %a, i128 0 release, !pcsections !0 + ret void +} + +define void @atomic128_nand_release(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_nand_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i128 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] release monotonic, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i128* %a, i128 0 release, !pcsections !0 + ret void +} + +define void @atomic128_xchg_acq_rel(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_xchg_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 0 acq_rel acquire, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i128* %a, i128 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic128_add_acq_rel(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_add_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] acq_rel acquire, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i128* %a, i128 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic128_sub_acq_rel(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_sub_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] acq_rel acquire, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i128* %a, i128 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic128_and_acq_rel(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_and_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] acq_rel acquire, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i128* %a, i128 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic128_or_acq_rel(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_or_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] acq_rel acquire, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i128* %a, i128 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic128_xor_acq_rel(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_xor_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] acq_rel acquire, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i128* %a, i128 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic128_nand_acq_rel(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_nand_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i128 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] acq_rel acquire, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i128* %a, i128 0 acq_rel, !pcsections !0 + ret void +} + +define void @atomic128_xchg_seq_cst(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_xchg_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 0 seq_cst seq_cst, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xchg i128* %a, i128 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic128_add_seq_cst(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_add_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = add i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] seq_cst seq_cst, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw add i128* %a, i128 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic128_sub_seq_cst(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_sub_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = sub i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] seq_cst seq_cst, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw sub i128* %a, i128 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic128_and_seq_cst(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_and_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = and i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] seq_cst seq_cst, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw and i128* %a, i128 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic128_or_seq_cst(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_or_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = or i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] seq_cst seq_cst, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw or i128* %a, i128 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic128_xor_seq_cst(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_xor_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] seq_cst seq_cst, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP1]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP1]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw xor i128* %a, i128 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic128_nand_seq_cst(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_nand_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i128, i128* [[A:%.*]], align 16, !pcsections !0 +; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]], !pcsections !0 +; CHECK: atomicrmw.start: +; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ], !pcsections !0 +; CHECK-NEXT: [[TMP1:%.*]] = and i128 [[LOADED]], 0, !pcsections !0 +; CHECK-NEXT: [[NEW:%.*]] = xor i128 [[TMP1]], -1, !pcsections !0 +; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg i128* [[A]], i128 [[LOADED]], i128 [[NEW]] seq_cst seq_cst, align 16, !pcsections !0 +; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP2]], 1, !pcsections !0 +; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i128, i1 } [[TMP2]], 0, !pcsections !0 +; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]], !pcsections !0 +; CHECK: atomicrmw.end: +; CHECK-NEXT: ret void +; +entry: + atomicrmw nand i128* %a, i128 0 seq_cst, !pcsections !0 + ret void +} + +define void @atomic128_cas_monotonic(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_cas_monotonic( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i128* [[A:%.*]], i128 0, i128 1 monotonic monotonic, align 16, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i128* %a, i128 0, i128 1 monotonic monotonic, !pcsections !0 + ret void +} + +define void @atomic128_cas_acquire(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_cas_acquire( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i128* [[A:%.*]], i128 0, i128 1 acquire acquire, align 16, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i128* %a, i128 0, i128 1 acquire acquire, !pcsections !0 + ret void +} + +define void @atomic128_cas_release(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_cas_release( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i128* [[A:%.*]], i128 0, i128 1 release monotonic, align 16, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i128* %a, i128 0, i128 1 release monotonic, !pcsections !0 + ret void +} + +define void @atomic128_cas_acq_rel(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_cas_acq_rel( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i128* [[A:%.*]], i128 0, i128 1 acq_rel acquire, align 16, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i128* %a, i128 0, i128 1 acq_rel acquire, !pcsections !0 + ret void +} + +define void @atomic128_cas_seq_cst(i128* %a) nounwind uwtable { +; CHECK-LABEL: @atomic128_cas_seq_cst( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg i128* [[A:%.*]], i128 0, i128 1 seq_cst seq_cst, align 16, !pcsections !0 +; CHECK-NEXT: ret void +; +entry: + cmpxchg i128* %a, i128 0, i128 1 seq_cst seq_cst, !pcsections !0 + ret void +} + +!0 = !{!"foo"}