Index: include/llvm/CodeGen/TargetLowering.h =================================================================== --- include/llvm/CodeGen/TargetLowering.h +++ include/llvm/CodeGen/TargetLowering.h @@ -163,6 +163,7 @@ LLOnly, // Expand the (load) instruction into just a load-linked, which has // greater atomic guarantees than a normal load. CmpXChg, // Expand the instruction into cmpxchg; used by at least X86. + MaskedIntrinsic, // Use a target-specific intrinsic for the LL/SC loop. }; /// Enum that specifies when a multiplication should be expanded. @@ -1550,6 +1551,17 @@ llvm_unreachable("Store conditional unimplemented on this target"); } + /// Perform a masked atomicrmw using a target-specific intrinsic. This + /// represents the core LL/SC loop which will be lowered at a late stage by + /// the backend. + virtual Value *emitMaskedAtomicRMWIntrinsic(IRBuilder<> &Builder, + AtomicRMWInst *AI, + Value *AlignedAddr, Value *Incr, + Value *Mask, + AtomicOrdering Ord) const { + llvm_unreachable("Masked atomicrmw expansion unimplemented on this target"); + } + /// Inserts in the IR a target-specific intrinsic specifying a fence. /// It is called by AtomicExpandPass before expanding an /// AtomicRMW/AtomicCmpXchg/AtomicStore/AtomicLoad Index: include/llvm/IR/Intrinsics.td =================================================================== --- include/llvm/IR/Intrinsics.td +++ include/llvm/IR/Intrinsics.td @@ -1008,3 +1008,4 @@ include "llvm/IR/IntrinsicsBPF.td" include "llvm/IR/IntrinsicsSystemZ.td" include "llvm/IR/IntrinsicsWebAssembly.td" +include "llvm/IR/IntrinsicsRISCV.td" Index: include/llvm/IR/IntrinsicsRISCV.td =================================================================== --- /dev/null +++ include/llvm/IR/IntrinsicsRISCV.td @@ -0,0 +1,39 @@ +//===- IntrinsicsRISCV.td - Defines RISCV intrinsics -------*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines all of the RISCV-specific intrinsics. +// +//===----------------------------------------------------------------------===// + +let TargetPrefix = "riscv" in { + +//===----------------------------------------------------------------------===// +// Atomics + +class MaskedAtomicRMW32Intrinsic + : Intrinsic<[llvm_i32_ty], + [llvm_anyptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrArgMemOnly, NoCapture<0>]>; + +class MaskedAtomicRMW32WithSextIntrinsic + : Intrinsic<[llvm_i32_ty], + [llvm_anyptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, + llvm_i32_ty], + [IntrArgMemOnly, NoCapture<0>]>; + +def int_riscv_masked_atomicrmw_xchg_i32 : MaskedAtomicRMW32Intrinsic; +def int_riscv_masked_atomicrmw_add_i32 : MaskedAtomicRMW32Intrinsic; +def int_riscv_masked_atomicrmw_sub_i32 : MaskedAtomicRMW32Intrinsic; +def int_riscv_masked_atomicrmw_nand_i32 : MaskedAtomicRMW32Intrinsic; +def int_riscv_masked_atomicrmw_max_i32 : MaskedAtomicRMW32WithSextIntrinsic; +def int_riscv_masked_atomicrmw_min_i32 : MaskedAtomicRMW32WithSextIntrinsic; +def int_riscv_masked_atomicrmw_umax_i32 : MaskedAtomicRMW32Intrinsic; +def int_riscv_masked_atomicrmw_umin_i32 : MaskedAtomicRMW32Intrinsic; + +} // TargetPrefix = "riscv" Index: lib/CodeGen/AtomicExpandPass.cpp =================================================================== --- lib/CodeGen/AtomicExpandPass.cpp +++ lib/CodeGen/AtomicExpandPass.cpp @@ -90,6 +90,7 @@ TargetLoweringBase::AtomicExpansionKind ExpansionKind); AtomicRMWInst *widenPartwordAtomicRMW(AtomicRMWInst *AI); void expandPartwordCmpXchg(AtomicCmpXchgInst *I); + void expandAtomicOpToMaskedIntrinsic(AtomicRMWInst *AI); AtomicCmpXchgInst *convertCmpXchgToIntegerType(AtomicCmpXchgInst *CI); static Value *insertRMWCmpXchgLoop( @@ -411,8 +412,9 @@ return expandAtomicLoadToLL(LI); case TargetLoweringBase::AtomicExpansionKind::CmpXChg: return expandAtomicLoadToCmpXchg(LI); + default: + llvm_unreachable("Unhandled case in tryExpandAtomicLoad"); } - llvm_unreachable("Unhandled case in tryExpandAtomicLoad"); } bool AtomicExpand::expandAtomicLoadToLL(LoadInst *LI) { @@ -574,6 +576,10 @@ } return true; } + case TargetLoweringBase::AtomicExpansionKind::MaskedIntrinsic: { + expandAtomicOpToMaskedIntrinsic(AI); + return true; + } default: llvm_unreachable("Unhandled case in tryExpandAtomicRMW"); } @@ -662,6 +668,9 @@ IRBuilder<> &Builder, Value *Loaded, Value *Shifted_Inc, Value *Inc, const PartwordMaskValues &PMV) { + // TODO: update to use + // https://graphics.stanford.edu/~seander/bithacks.html#MaskedMerge in order + // to merge bits from two values without requiring PMV.Inv_Mask. switch (Op) { case AtomicRMWInst::Xchg: { Value *Loaded_MaskOut = Builder.CreateAnd(Loaded, PMV.Inv_Mask); @@ -914,6 +923,24 @@ I->eraseFromParent(); } +void AtomicExpand::expandAtomicOpToMaskedIntrinsic(AtomicRMWInst *AI) { + IRBuilder<> Builder(AI); + + PartwordMaskValues PMV = + createMaskInstrs(Builder, AI, AI->getType(), AI->getPointerOperand(), + TLI->getMinCmpXchgSizeInBits() / 8); + Value *ValOperand_Shifted = + Builder.CreateShl(Builder.CreateZExt(AI->getValOperand(), PMV.WordType), + PMV.ShiftAmt, "ValOperand_Shifted"); + Value *OldResult = TLI->emitMaskedAtomicRMWIntrinsic( + Builder, AI, PMV.AlignedAddr, ValOperand_Shifted, PMV.Mask, + AI->getOrdering()); + Value *FinalOldResult = Builder.CreateTrunc( + Builder.CreateLShr(OldResult, PMV.ShiftAmt), PMV.ValueType); + AI->replaceAllUsesWith(FinalOldResult); + AI->eraseFromParent(); +} + Value *AtomicExpand::insertRMWLLSCLoop( IRBuilder<> &Builder, Type *ResultTy, Value *Addr, AtomicOrdering MemOpOrder, Index: lib/Target/RISCV/CMakeLists.txt =================================================================== --- lib/Target/RISCV/CMakeLists.txt +++ lib/Target/RISCV/CMakeLists.txt @@ -15,6 +15,7 @@ add_llvm_target(RISCVCodeGen RISCVAsmPrinter.cpp + RISCVExpandPseudoInsts.cpp RISCVFrameLowering.cpp RISCVInstrInfo.cpp RISCVISelDAGToDAG.cpp Index: lib/Target/RISCV/RISCV.h =================================================================== --- lib/Target/RISCV/RISCV.h +++ lib/Target/RISCV/RISCV.h @@ -16,6 +16,7 @@ #define LLVM_LIB_TARGET_RISCV_RISCV_H #include "MCTargetDesc/RISCVBaseInfo.h" +#include "llvm/Target/TargetMachine.h" namespace llvm { class RISCVTargetMachine; @@ -36,6 +37,9 @@ FunctionPass *createRISCVMergeBaseOffsetOptPass(); void initializeRISCVMergeBaseOffsetOptPass(PassRegistry &); + +FunctionPass *createRISCVExpandPseudoPass(); +void initializeRISCVExpandPseudoPass(PassRegistry &); } #endif Index: lib/Target/RISCV/RISCVExpandPseudoInsts.cpp =================================================================== --- /dev/null +++ lib/Target/RISCV/RISCVExpandPseudoInsts.cpp @@ -0,0 +1,454 @@ +//===-- RISCVExpandPseudoInsts.cpp - Expand pseudo instructions -----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains a pass that expands pseudo instructions into target +// instructions. This pass should be run after register allocation but before +// the post-regalloc scheduling pass. +// +//===----------------------------------------------------------------------===// + +#include "RISCV.h" +#include "RISCVInstrInfo.h" +#include "RISCVTargetMachine.h" + +#include "llvm/CodeGen/LivePhysRegs.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" + +using namespace llvm; + +#define RISCV_EXPAND_PSEUDO_NAME "RISCV pseudo instruction expansion pass" + +namespace { + +class RISCVExpandPseudo : public MachineFunctionPass { +public: + const RISCVInstrInfo *TII; + static char ID; + + RISCVExpandPseudo() : MachineFunctionPass(ID) { + initializeRISCVExpandPseudoPass(*PassRegistry::getPassRegistry()); + } + + bool runOnMachineFunction(MachineFunction &MF) override; + + StringRef getPassName() const override { return RISCV_EXPAND_PSEUDO_NAME; } + +private: + bool expandMBB(MachineBasicBlock &MBB); + bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, + MachineBasicBlock::iterator &NextMBBI); + bool expandAtomicBinOp(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, AtomicRMWInst::BinOp, + bool IsMasked, int Width, + MachineBasicBlock::iterator &NextMBBI); + bool expandAtomicMinMaxOp(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + AtomicRMWInst::BinOp, bool IsMasked, int Width, + MachineBasicBlock::iterator &NextMBBI); +}; + +char RISCVExpandPseudo::ID = 0; + +bool RISCVExpandPseudo::runOnMachineFunction(MachineFunction &MF) { + TII = static_cast(MF.getSubtarget().getInstrInfo()); + bool Modified = false; + for (auto &MBB : MF) + Modified |= expandMBB(MBB); + return Modified; +} + +bool RISCVExpandPseudo::expandMBB(MachineBasicBlock &MBB) { + bool Modified = false; + + MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); + while (MBBI != E) { + MachineBasicBlock::iterator NMBBI = std::next(MBBI); + Modified |= expandMI(MBB, MBBI, NMBBI); + MBBI = NMBBI; + } + + return Modified; +} + +bool RISCVExpandPseudo::expandMI(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + MachineBasicBlock::iterator &NextMBBI) { + switch (MBBI->getOpcode()) { + case RISCV::PseudoAtomicLoadNand32: + return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Nand, false, 32, + NextMBBI); + case RISCV::PseudoMaskedAtomicSwap32: + return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Xchg, true, 32, + NextMBBI); + case RISCV::PseudoMaskedAtomicLoadAdd32: + return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Add, true, 32, NextMBBI); + case RISCV::PseudoMaskedAtomicLoadSub32: + return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Sub, true, 32, NextMBBI); + case RISCV::PseudoMaskedAtomicLoadNand32: + return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Nand, true, 32, + NextMBBI); + case RISCV::PseudoMaskedAtomicLoadMax32: + return expandAtomicMinMaxOp(MBB, MBBI, AtomicRMWInst::Max, true, 32, + NextMBBI); + case RISCV::PseudoMaskedAtomicLoadMin32: + return expandAtomicMinMaxOp(MBB, MBBI, AtomicRMWInst::Min, true, 32, + NextMBBI); + case RISCV::PseudoMaskedAtomicLoadUMax32: + return expandAtomicMinMaxOp(MBB, MBBI, AtomicRMWInst::UMax, true, 32, + NextMBBI); + case RISCV::PseudoMaskedAtomicLoadUMin32: + return expandAtomicMinMaxOp(MBB, MBBI, AtomicRMWInst::UMin, true, 32, + NextMBBI); + } + + return false; +} + +static unsigned getLRForRMW32(AtomicOrdering Ordering) { + switch (Ordering) { + default: + llvm_unreachable("Unexpected AtomicOrdering"); + case AtomicOrdering::Monotonic: + return RISCV::LR_W; + case AtomicOrdering::Acquire: + return RISCV::LR_W_AQ; + case AtomicOrdering::Release: + return RISCV::LR_W; + case AtomicOrdering::AcquireRelease: + return RISCV::LR_W_AQ; + case AtomicOrdering::SequentiallyConsistent: + return RISCV::LR_W_AQ_RL; + } +} + +static unsigned getSCForRMW32(AtomicOrdering Ordering) { + switch (Ordering) { + default: + llvm_unreachable("Unexpected AtomicOrdering"); + case AtomicOrdering::Monotonic: + return RISCV::SC_W; + case AtomicOrdering::Acquire: + return RISCV::SC_W; + case AtomicOrdering::Release: + return RISCV::SC_W_RL; + case AtomicOrdering::AcquireRelease: + return RISCV::SC_W_RL; + case AtomicOrdering::SequentiallyConsistent: + return RISCV::SC_W_AQ_RL; + } +} + +static void doAtomicBinOpExpansion(const RISCVInstrInfo *TII, MachineInstr &MI, + DebugLoc DL, MachineBasicBlock *ThisMBB, + MachineBasicBlock *LoopMBB, + MachineBasicBlock *DoneMBB, + AtomicRMWInst::BinOp BinOp, int Width) { + assert(Width == 32 && "RV64 atomic expansion currently unsupported"); + unsigned DestReg = MI.getOperand(0).getReg(); + unsigned ScratchReg = MI.getOperand(1).getReg(); + unsigned AddrReg = MI.getOperand(2).getReg(); + unsigned IncrReg = MI.getOperand(3).getReg(); + AtomicOrdering Ordering = + static_cast(MI.getOperand(4).getImm()); + + // .loop: + // lr.w dest, (addr) + // binop scratch, dest, val + // sc.w scratch, scratch, (addr) + // bnez scratch, loop + BuildMI(LoopMBB, DL, TII->get(getLRForRMW32(Ordering)), DestReg) + .addReg(AddrReg); + switch (BinOp) { + default: + llvm_unreachable("Unexpected AtomicRMW BinOp"); + case AtomicRMWInst::Nand: + BuildMI(LoopMBB, DL, TII->get(RISCV::AND), ScratchReg) + .addReg(DestReg) + .addReg(IncrReg); + BuildMI(LoopMBB, DL, TII->get(RISCV::XORI), ScratchReg) + .addReg(ScratchReg) + .addImm(-1); + break; + } + BuildMI(LoopMBB, DL, TII->get(getSCForRMW32(Ordering)), ScratchReg) + .addReg(AddrReg) + .addReg(ScratchReg); + BuildMI(LoopMBB, DL, TII->get(RISCV::BNE)) + .addReg(ScratchReg) + .addReg(RISCV::X0) + .addMBB(LoopMBB); +} + +static void insertMaskedMerge(const RISCVInstrInfo *TII, DebugLoc DL, + MachineBasicBlock *MBB, unsigned DestReg, + unsigned OldValReg, unsigned NewValReg, + unsigned MaskReg, unsigned ScratchReg) { + assert(OldValReg != ScratchReg && "OldValReg and ScratchReg must be unique"); + assert(OldValReg != MaskReg && "OldValReg and MaskReg must be unique"); + assert(ScratchReg != MaskReg && "ScratchReg and MaskReg must be unique"); + + // We select bits from newval and oldval using: + // https://graphics.stanford.edu/~seander/bithacks.html#MaskedMerge + // r = oldval ^ ((oldval ^ newval) & masktargetdata); + BuildMI(MBB, DL, TII->get(RISCV::XOR), ScratchReg) + .addReg(OldValReg) + .addReg(NewValReg); + BuildMI(MBB, DL, TII->get(RISCV::AND), ScratchReg) + .addReg(ScratchReg) + .addReg(MaskReg); + BuildMI(MBB, DL, TII->get(RISCV::XOR), DestReg) + .addReg(OldValReg) + .addReg(ScratchReg); +} + +static void doMaskedAtomicBinOpExpansion( + const RISCVInstrInfo *TII, MachineInstr &MI, DebugLoc DL, + MachineBasicBlock *ThisMBB, MachineBasicBlock *LoopMBB, + MachineBasicBlock *DoneMBB, AtomicRMWInst::BinOp BinOp, int Width) { + assert(Width == 32 && "RV64 atomic expansion currently unsupported"); + unsigned DestReg = MI.getOperand(0).getReg(); + unsigned ScratchReg = MI.getOperand(1).getReg(); + unsigned AddrReg = MI.getOperand(2).getReg(); + unsigned IncrReg = MI.getOperand(3).getReg(); + unsigned MaskReg = MI.getOperand(4).getReg(); + AtomicOrdering Ordering = + static_cast(MI.getOperand(5).getImm()); + + // .loop: + // lr.w destreg, (alignedaddr) + // binop scratch, destreg, incr + // xor scratch, destreg, scratch + // and scratch, scratch, masktargetdata + // xor scratch, destreg, scratch + // sc.w scratch, scratch, (alignedaddr) + // bnez scratch, loop + BuildMI(LoopMBB, DL, TII->get(getLRForRMW32(Ordering)), DestReg) + .addReg(AddrReg); + switch (BinOp) { + default: + llvm_unreachable("Unexpected AtomicRMW BinOp"); + case AtomicRMWInst::Xchg: + BuildMI(LoopMBB, DL, TII->get(RISCV::ADD), ScratchReg) + .addReg(RISCV::X0) + .addReg(IncrReg); + break; + case AtomicRMWInst::Add: + BuildMI(LoopMBB, DL, TII->get(RISCV::ADD), ScratchReg) + .addReg(DestReg) + .addReg(IncrReg); + break; + case AtomicRMWInst::Sub: + BuildMI(LoopMBB, DL, TII->get(RISCV::SUB), ScratchReg) + .addReg(DestReg) + .addReg(IncrReg); + break; + case AtomicRMWInst::Nand: + BuildMI(LoopMBB, DL, TII->get(RISCV::AND), ScratchReg) + .addReg(DestReg) + .addReg(IncrReg); + BuildMI(LoopMBB, DL, TII->get(RISCV::XORI), ScratchReg) + .addReg(ScratchReg) + .addImm(-1); + break; + } + + insertMaskedMerge(TII, DL, LoopMBB, ScratchReg, DestReg, ScratchReg, MaskReg, + ScratchReg); + + BuildMI(LoopMBB, DL, TII->get(getSCForRMW32(Ordering)), ScratchReg) + .addReg(AddrReg) + .addReg(ScratchReg); + BuildMI(LoopMBB, DL, TII->get(RISCV::BNE)) + .addReg(ScratchReg) + .addReg(RISCV::X0) + .addMBB(LoopMBB); +} + +bool RISCVExpandPseudo::expandAtomicBinOp( + MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, + AtomicRMWInst::BinOp BinOp, bool IsMasked, int Width, + MachineBasicBlock::iterator &NextMBBI) { + MachineInstr &MI = *MBBI; + DebugLoc DL = MI.getDebugLoc(); + + MachineFunction *MF = MBB.getParent(); + auto LoopMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock()); + auto DoneMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock()); + + // Insert new MBBs. + MF->insert(++MBB.getIterator(), LoopMBB); + MF->insert(++LoopMBB->getIterator(), DoneMBB); + + // Set up successors and transfer remaining instructions to DoneMBB. + LoopMBB->addSuccessor(LoopMBB); + LoopMBB->addSuccessor(DoneMBB); + DoneMBB->splice(DoneMBB->end(), &MBB, MI, MBB.end()); + DoneMBB->transferSuccessors(&MBB); + MBB.addSuccessor(LoopMBB); + + if (!IsMasked) + doAtomicBinOpExpansion(TII, MI, DL, &MBB, LoopMBB, DoneMBB, BinOp, Width); + else + doMaskedAtomicBinOpExpansion(TII, MI, DL, &MBB, LoopMBB, DoneMBB, BinOp, + Width); + + NextMBBI = MBB.end(); + MI.eraseFromParent(); + + LivePhysRegs LiveRegs; + computeAndAddLiveIns(LiveRegs, *LoopMBB); + computeAndAddLiveIns(LiveRegs, *DoneMBB); + + return true; +} + +static void insertSext(const RISCVInstrInfo *TII, DebugLoc DL, + MachineBasicBlock *MBB, unsigned Reg, unsigned Shamt) { + BuildMI(MBB, DL, TII->get(RISCV::SLLI), Reg) + .addReg(Reg).addImm(Shamt); + BuildMI(MBB, DL, TII->get(RISCV::SRAI), Reg) + .addReg(Reg).addImm(Shamt); +} + +bool RISCVExpandPseudo::expandAtomicMinMaxOp( + MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, + AtomicRMWInst::BinOp BinOp, bool IsMasked, int Width, + MachineBasicBlock::iterator &NextMBBI) { + assert(IsMasked == true && + "Should only need to expand masked atomic max/min"); + assert(Width == 32 && "RV64 atomic expansion currently unsupported"); + + MachineInstr &MI = *MBBI; + DebugLoc DL = MI.getDebugLoc(); + MachineFunction *MF = MBB.getParent(); + auto LoopHeadMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock()); + auto LoopIfBodyMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock()); + auto LoopTailMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock()); + auto DoneMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock()); + + // Insert new MBBs. + MF->insert(++MBB.getIterator(), LoopHeadMBB); + MF->insert(++LoopHeadMBB->getIterator(), LoopIfBodyMBB); + MF->insert(++LoopIfBodyMBB->getIterator(), LoopTailMBB); + MF->insert(++LoopTailMBB->getIterator(), DoneMBB); + + // Set up successors and transfer remaining instructions to DoneMBB. + LoopHeadMBB->addSuccessor(LoopIfBodyMBB); + LoopHeadMBB->addSuccessor(LoopTailMBB); + LoopIfBodyMBB->addSuccessor(LoopTailMBB); + LoopTailMBB->addSuccessor(LoopHeadMBB); + LoopTailMBB->addSuccessor(DoneMBB); + DoneMBB->splice(DoneMBB->end(), &MBB, MI, MBB.end()); + DoneMBB->transferSuccessors(&MBB); + MBB.addSuccessor(LoopHeadMBB); + + unsigned DestReg = MI.getOperand(0).getReg(); + unsigned Scratch1Reg = MI.getOperand(1).getReg(); + unsigned Scratch2Reg = MI.getOperand(2).getReg(); + unsigned AddrReg = MI.getOperand(3).getReg(); + unsigned IncrReg = MI.getOperand(4).getReg(); + unsigned MaskReg = MI.getOperand(5).getReg(); + bool IsSigned = BinOp == AtomicRMWInst::Min || BinOp == AtomicRMWInst::Max; + AtomicOrdering Ordering = + static_cast(MI.getOperand(IsSigned ? 7 : 6).getImm()); + + // sext incr + if (IsSigned) { + insertSext(TII, DL, &MBB, IncrReg, MI.getOperand(6).getImm()); + } + + // + // .loophead: + // lr.w destreg, (alignedaddr) + // and scratch2, destreg, mask + // mv scratch1, destreg + // [sext scratch2 if signed min/max] + // ifnochangeneeded scratch2, incr, .looptail + BuildMI(LoopHeadMBB, DL, TII->get(getLRForRMW32(Ordering)), DestReg) + .addReg(AddrReg); + BuildMI(LoopHeadMBB, DL, TII->get(RISCV::AND), Scratch2Reg) + .addReg(DestReg) + .addReg(MaskReg); + BuildMI(LoopHeadMBB, DL, TII->get(RISCV::ADDI), Scratch1Reg) + .addReg(DestReg) + .addImm(0); + + switch (BinOp) { + default: + llvm_unreachable("Unexpected AtomicRMW BinOp"); + case AtomicRMWInst::Max: { + insertSext(TII, DL, LoopHeadMBB, Scratch2Reg, MI.getOperand(6).getImm()); + BuildMI(LoopHeadMBB, DL, TII->get(RISCV::BGE)) + .addReg(Scratch2Reg) + .addReg(IncrReg) + .addMBB(LoopTailMBB); + break; + } + case AtomicRMWInst::Min: { + insertSext(TII, DL, LoopHeadMBB, Scratch2Reg, MI.getOperand(6).getImm()); + BuildMI(LoopHeadMBB, DL, TII->get(RISCV::BGE)) + .addReg(IncrReg) + .addReg(Scratch2Reg) + .addMBB(LoopTailMBB); + break; + } + case AtomicRMWInst::UMax: + BuildMI(LoopHeadMBB, DL, TII->get(RISCV::BGEU)) + .addReg(Scratch2Reg) + .addReg(IncrReg) + .addMBB(LoopTailMBB); + break; + case AtomicRMWInst::UMin: + BuildMI(LoopHeadMBB, DL, TII->get(RISCV::BGEU)) + .addReg(IncrReg) + .addReg(Scratch2Reg) + .addMBB(LoopTailMBB); + break; + } + + // .loopifbody: + // xor scratch1, destreg, incr + // and scratch1, scratch1, mask + // xor scratch1, destreg, scratch1 + insertMaskedMerge(TII, DL, LoopIfBodyMBB, Scratch1Reg, DestReg, IncrReg, + MaskReg, Scratch1Reg); + + // .looptail: + // sc.w scratch1, scratch1, (addr) + // bnez scratch1, loop + BuildMI(LoopTailMBB, DL, TII->get(getSCForRMW32(Ordering)), Scratch1Reg) + .addReg(AddrReg) + .addReg(Scratch1Reg); + BuildMI(LoopTailMBB, DL, TII->get(RISCV::BNE)) + .addReg(Scratch1Reg) + .addReg(RISCV::X0) + .addMBB(LoopHeadMBB); + + NextMBBI = MBB.end(); + MI.eraseFromParent(); + + LivePhysRegs LiveRegs; + computeAndAddLiveIns(LiveRegs, *LoopHeadMBB); + computeAndAddLiveIns(LiveRegs, *LoopIfBodyMBB); + computeAndAddLiveIns(LiveRegs, *LoopTailMBB); + computeAndAddLiveIns(LiveRegs, *DoneMBB); + + return true; +} + +} // end of anonymous namespace + +INITIALIZE_PASS(RISCVExpandPseudo, "riscv-expand-pseudo", + RISCV_EXPAND_PSEUDO_NAME, false, false) +namespace llvm { + +FunctionPass *createRISCVExpandPseudoPass() { return new RISCVExpandPseudo(); } + +} // end of namespace llvm Index: lib/Target/RISCV/RISCVISelLowering.h =================================================================== --- lib/Target/RISCV/RISCVISelLowering.h +++ lib/Target/RISCV/RISCVISelLowering.h @@ -43,6 +43,9 @@ explicit RISCVTargetLowering(const TargetMachine &TM, const RISCVSubtarget &STI); + bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I, + MachineFunction &MF, + unsigned Intrinsic) const override; bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I = nullptr) const override; @@ -115,6 +118,13 @@ bool IsEligibleForTailCallOptimization(CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF, const SmallVector &ArgLocs) const; + + TargetLowering::AtomicExpansionKind + shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override; + virtual Value * + emitMaskedAtomicRMWIntrinsic(IRBuilder<> &Builder, AtomicRMWInst *AI, + Value *AlignedAddr, Value *Incr, Value *Mask, + AtomicOrdering Ord) const override; }; } Index: lib/Target/RISCV/RISCVISelLowering.cpp =================================================================== --- lib/Target/RISCV/RISCVISelLowering.cpp +++ lib/Target/RISCV/RISCVISelLowering.cpp @@ -137,10 +137,12 @@ setOperationAction(ISD::BlockAddress, XLenVT, Custom); setOperationAction(ISD::ConstantPool, XLenVT, Custom); - if (Subtarget.hasStdExtA()) + if (Subtarget.hasStdExtA()) { setMaxAtomicSizeInBitsSupported(Subtarget.getXLen()); - else + setMinCmpXchgSizeInBits(32); + } else { setMaxAtomicSizeInBitsSupported(0); + } setBooleanContents(ZeroOrOneBooleanContent); @@ -160,6 +162,33 @@ return VT.changeVectorElementTypeToInteger(); } +bool RISCVTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info, + const CallInst &I, + MachineFunction &MF, + unsigned Intrinsic) const { + switch (Intrinsic) { + default: + return false; + case Intrinsic::riscv_masked_atomicrmw_xchg_i32: + case Intrinsic::riscv_masked_atomicrmw_add_i32: + case Intrinsic::riscv_masked_atomicrmw_sub_i32: + case Intrinsic::riscv_masked_atomicrmw_nand_i32: + case Intrinsic::riscv_masked_atomicrmw_max_i32: + case Intrinsic::riscv_masked_atomicrmw_min_i32: + case Intrinsic::riscv_masked_atomicrmw_umax_i32: + case Intrinsic::riscv_masked_atomicrmw_umin_i32: + PointerType *PtrTy = cast(I.getArgOperand(0)->getType()); + Info.opc = ISD::INTRINSIC_W_CHAIN; + Info.memVT = MVT::getVT(PtrTy->getElementType()); + Info.ptrVal = I.getArgOperand(0); + Info.offset = 0; + Info.align = 4; + Info.flags = MachineMemOperand::MOLoad | MachineMemOperand::MOStore | + MachineMemOperand::MOVolatile; + return true; + } +} + bool RISCVTargetLowering::isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, @@ -1596,3 +1625,59 @@ return Builder.CreateFence(AtomicOrdering::Acquire); return nullptr; } + +TargetLowering::AtomicExpansionKind +RISCVTargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const { + unsigned Size = AI->getType()->getPrimitiveSizeInBits(); + if (Size == 8 || Size == 16) + return AtomicExpansionKind::MaskedIntrinsic; + return AtomicExpansionKind::None; +} + +static Intrinsic::ID +getIntrinsicForMaskedAtomicRMWBinOp32(AtomicRMWInst::BinOp BinOp) { + switch (BinOp) { + default: + llvm_unreachable("Unexpected AtomicRMW BinOp"); + case AtomicRMWInst::Xchg: + return Intrinsic::riscv_masked_atomicrmw_xchg_i32; + case AtomicRMWInst::Add: + return Intrinsic::riscv_masked_atomicrmw_add_i32; + case AtomicRMWInst::Sub: + return Intrinsic::riscv_masked_atomicrmw_sub_i32; + case AtomicRMWInst::Nand: + return Intrinsic::riscv_masked_atomicrmw_nand_i32; + case AtomicRMWInst::Max: + return Intrinsic::riscv_masked_atomicrmw_max_i32; + case AtomicRMWInst::Min: + return Intrinsic::riscv_masked_atomicrmw_min_i32; + case AtomicRMWInst::UMax: + return Intrinsic::riscv_masked_atomicrmw_umax_i32; + case AtomicRMWInst::UMin: + return Intrinsic::riscv_masked_atomicrmw_umin_i32; + } +} + +Value *RISCVTargetLowering::emitMaskedAtomicRMWIntrinsic( + IRBuilder<> &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr, + Value *Mask, AtomicOrdering Ord) const { + Value *Ordering = Builder.getInt32(static_cast(AI->getOrdering())); + Type *Tys[] = {AlignedAddr->getType()}; + Function *LrwOpScwLoop = Intrinsic::getDeclaration( + AI->getModule(), + getIntrinsicForMaskedAtomicRMWBinOp32(AI->getOperation()), Tys); + + // Must pass the shift amount needed to sign extended the loaded value for + // signed min/max. + if (AI->getOperation() == AtomicRMWInst::Min || + AI->getOperation() == AtomicRMWInst::Max) { + const DataLayout &DL = AI->getModule()->getDataLayout(); + unsigned OriginalWidth = + DL.getTypeStoreSizeInBits(AI->getValOperand()->getType()); + Value *SextShamt = Builder.getInt32(Subtarget.getXLen() - OriginalWidth); + return Builder.CreateCall(LrwOpScwLoop, + {AlignedAddr, Incr, Mask, SextShamt, Ordering}); + } + + return Builder.CreateCall(LrwOpScwLoop, {AlignedAddr, Incr, Mask, Ordering}); +} Index: lib/Target/RISCV/RISCVInstrInfo.td =================================================================== --- lib/Target/RISCV/RISCVInstrInfo.td +++ lib/Target/RISCV/RISCVInstrInfo.td @@ -599,7 +599,7 @@ /// Generic pattern classes -class PatGprGpr +class PatGprGpr : Pat<(OpNode GPR:$rs1, GPR:$rs2), (Inst GPR:$rs1, GPR:$rs2)>; class PatGprSimm12 : Pat<(OpNode GPR:$rs1, simm12:$imm12), (Inst GPR:$rs1, simm12:$imm12)>; Index: lib/Target/RISCV/RISCVInstrInfoA.td =================================================================== --- lib/Target/RISCV/RISCVInstrInfoA.td +++ lib/Target/RISCV/RISCVInstrInfoA.td @@ -94,4 +94,129 @@ defm : StPat; defm : StPat; defm : StPat; -} // Predicates = [HasStdExtF] + +/// AMOs + +multiclass AMOPat { + def : PatGprGpr(AtomicOp#"_monotonic"), + !cast(BaseInst)>; + def : PatGprGpr(AtomicOp#"_acquire"), + !cast(BaseInst#"_AQ")>; + def : PatGprGpr(AtomicOp#"_release"), + !cast(BaseInst#"_RL")>; + def : PatGprGpr(AtomicOp#"_acq_rel"), + !cast(BaseInst#"_AQ_RL")>; + def : PatGprGpr(AtomicOp#"_seq_cst"), + !cast(BaseInst#"_AQ_RL")>; +} + +defm : AMOPat<"atomic_swap_32", "AMOSWAP_W">; +defm : AMOPat<"atomic_load_add_32", "AMOADD_W">; +defm : AMOPat<"atomic_load_and_32", "AMOAND_W">; +defm : AMOPat<"atomic_load_or_32", "AMOOR_W">; +defm : AMOPat<"atomic_load_xor_32", "AMOXOR_W">; +defm : AMOPat<"atomic_load_max_32", "AMOMAX_W">; +defm : AMOPat<"atomic_load_min_32", "AMOMIN_W">; +defm : AMOPat<"atomic_load_umax_32", "AMOMAXU_W">; +defm : AMOPat<"atomic_load_umin_32", "AMOMINU_W">; + +def : Pat<(atomic_load_sub_32_monotonic GPR:$addr, GPR:$incr), + (AMOADD_W GPR:$addr, (SUB X0, GPR:$incr))>; +def : Pat<(atomic_load_sub_32_acquire GPR:$addr, GPR:$incr), + (AMOADD_W_AQ GPR:$addr, (SUB X0, GPR:$incr))>; +def : Pat<(atomic_load_sub_32_release GPR:$addr, GPR:$incr), + (AMOADD_W_RL GPR:$addr, (SUB X0, GPR:$incr))>; +def : Pat<(atomic_load_sub_32_acq_rel GPR:$addr, GPR:$incr), + (AMOADD_W_AQ_RL GPR:$addr, (SUB X0, GPR:$incr))>; +def : Pat<(atomic_load_sub_32_seq_cst GPR:$addr, GPR:$incr), + (AMOADD_W_AQ_RL GPR:$addr, (SUB X0, GPR:$incr))>; + +/// Pseudo AMOs + +class PseudoAMO : Pseudo<(outs GPR:$res, GPR:$scratch), + (ins GPR:$addr, GPR:$incr, i32imm:$ordering), []> { + let Constraints = "@earlyclobber $res,@earlyclobber $scratch"; + let mayLoad = 1; + let mayStore = 1; + let hasSideEffects = 0; +} + +def PseudoAtomicLoadNand32 : PseudoAMO; +// Ordering constants must be kept in sync with the AtomicOrdering enum in +// AtomicOrdering.h. +def : Pat<(atomic_load_nand_32_monotonic GPR:$addr, GPR:$incr), + (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 2)>; +def : Pat<(atomic_load_nand_32_acquire GPR:$addr, GPR:$incr), + (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 4)>; +def : Pat<(atomic_load_nand_32_release GPR:$addr, GPR:$incr), + (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 5)>; +def : Pat<(atomic_load_nand_32_acq_rel GPR:$addr, GPR:$incr), + (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 6)>; +def : Pat<(atomic_load_nand_32_seq_cst GPR:$addr, GPR:$incr), + (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 7)>; + +class PseudoMaskedAMO + : Pseudo<(outs GPR:$res, GPR:$scratch), + (ins GPR:$addr, GPR:$incr, GPR:$mask, i32imm:$ordering), []> { + let Constraints = "@earlyclobber $res,@earlyclobber $scratch"; + let mayLoad = 1; + let mayStore = 1; + let hasSideEffects = 0; +} + +class PseudoMaskedAMOMinMax + : Pseudo<(outs GPR:$res, GPR:$scratch1, GPR:$scratch2), + (ins GPR:$addr, GPR:$incr, GPR:$mask, i32imm:$sextshamt, + i32imm:$ordering), []> { + let Constraints = "@earlyclobber $res,@earlyclobber $scratch1," + "@earlyclobber $scratch2"; + let mayLoad = 1; + let mayStore = 1; + let hasSideEffects = 0; +} + +class PseudoMaskedAMOUMinUMax + : Pseudo<(outs GPR:$res, GPR:$scratch1, GPR:$scratch2), + (ins GPR:$addr, GPR:$incr, GPR:$mask, i32imm:$ordering), []> { + let Constraints = "@earlyclobber $res,@earlyclobber $scratch1," + "@earlyclobber $scratch2"; + let mayLoad = 1; + let mayStore = 1; + let hasSideEffects = 0; +} + +class PseudoMaskedAMOPat + : Pat<(intrin GPR:$addr, GPR:$incr, GPR:$mask, imm:$ordering), + (AMOInst GPR:$addr, GPR:$incr, GPR:$mask, imm:$ordering)>; + +class PseudoMaskedAMOMinMaxPat + : Pat<(intrin GPR:$addr, GPR:$incr, GPR:$mask, imm:$sextshamt, + imm:$ordering), + (AMOInst GPR:$addr, GPR:$incr, GPR:$mask, imm:$sextshamt, + imm:$ordering)>; + +def PseudoMaskedAtomicSwap32 : PseudoMaskedAMO; +def : PseudoMaskedAMOPat; +def PseudoMaskedAtomicLoadAdd32 : PseudoMaskedAMO; +def : PseudoMaskedAMOPat; +def PseudoMaskedAtomicLoadSub32 : PseudoMaskedAMO; +def : PseudoMaskedAMOPat; +def PseudoMaskedAtomicLoadNand32 : PseudoMaskedAMO; +def : PseudoMaskedAMOPat; +def PseudoMaskedAtomicLoadMax32 : PseudoMaskedAMOMinMax; +def : PseudoMaskedAMOMinMaxPat; +def PseudoMaskedAtomicLoadMin32 : PseudoMaskedAMOMinMax; +def : PseudoMaskedAMOMinMaxPat; +def PseudoMaskedAtomicLoadUMax32 : PseudoMaskedAMOUMinUMax; +def : PseudoMaskedAMOPat; +def PseudoMaskedAtomicLoadUMin32 : PseudoMaskedAMOUMinUMax; +def : PseudoMaskedAMOPat; +} // Predicates = [HasStdExtA] Index: lib/Target/RISCV/RISCVTargetMachine.cpp =================================================================== --- lib/Target/RISCV/RISCVTargetMachine.cpp +++ lib/Target/RISCV/RISCVTargetMachine.cpp @@ -27,6 +27,8 @@ extern "C" void LLVMInitializeRISCVTarget() { RegisterTargetMachine X(getTheRISCV32Target()); RegisterTargetMachine Y(getTheRISCV64Target()); + auto PR = PassRegistry::getPassRegistry(); + initializeRISCVExpandPseudoPass(*PR); } static std::string computeDataLayout(const Triple &TT) { @@ -78,6 +80,7 @@ void addIRPasses() override; bool addInstSelector() override; void addPreEmitPass() override; + void addPreEmitPass2() override; void addPreRegAlloc() override; }; } @@ -99,6 +102,13 @@ void RISCVPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); } +void RISCVPassConfig::addPreEmitPass2() { + // Schedule the expansion of AMOs at the last possible moment, avoiding the + // possibility for other passes to break the requirements for forward + // progress in the LR/SC block. + addPass(createRISCVExpandPseudoPass()); +} + void RISCVPassConfig::addPreRegAlloc() { addPass(createRISCVMergeBaseOffsetOptPass()); } Index: test/CodeGen/RISCV/atomic-rmw.ll =================================================================== --- test/CodeGen/RISCV/atomic-rmw.ll +++ test/CodeGen/RISCV/atomic-rmw.ll @@ -1,6 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ ; RUN: | FileCheck -check-prefix=RV32I %s +; RUN: llc -mtriple=riscv32 -mattr=+a -verify-machineinstrs < %s \ +; RUN: | FileCheck -check-prefix=RV32IA %s define i8 @atomicrmw_xchg_i8_monotonic(i8* %a, i8 %b) { ; RV32I-LABEL: atomicrmw_xchg_i8_monotonic: @@ -12,6 +14,27 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xchg_i8_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB0_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: add a5, zero, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a3 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB0_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i8* %a, i8 %b monotonic ret i8 %1 } @@ -26,6 +49,27 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xchg_i8_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB1_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: add a5, zero, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a3 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB1_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i8* %a, i8 %b acquire ret i8 %1 } @@ -40,6 +84,27 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xchg_i8_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB2_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: add a5, zero, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a3 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB2_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i8* %a, i8 %b release ret i8 %1 } @@ -54,6 +119,27 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xchg_i8_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB3_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: add a5, zero, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a3 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB3_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i8* %a, i8 %b acq_rel ret i8 %1 } @@ -68,6 +154,27 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xchg_i8_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB4_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: add a5, zero, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a3 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB4_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i8* %a, i8 %b seq_cst ret i8 %1 } @@ -82,6 +189,27 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_add_i8_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB5_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: add a5, a4, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a3 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB5_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw add i8* %a, i8 %b monotonic ret i8 %1 } @@ -96,6 +224,27 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_add_i8_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB6_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: add a5, a4, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a3 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB6_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw add i8* %a, i8 %b acquire ret i8 %1 } @@ -110,6 +259,27 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_add_i8_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB7_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: add a5, a4, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a3 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB7_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw add i8* %a, i8 %b release ret i8 %1 } @@ -124,6 +294,27 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_add_i8_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB8_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: add a5, a4, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a3 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB8_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw add i8* %a, i8 %b acq_rel ret i8 %1 } @@ -138,6 +329,27 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_add_i8_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB9_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: add a5, a4, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a3 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB9_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw add i8* %a, i8 %b seq_cst ret i8 %1 } @@ -152,6 +364,27 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_sub_i8_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB10_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: sub a5, a4, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a3 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB10_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw sub i8* %a, i8 %b monotonic ret i8 %1 } @@ -166,6 +399,27 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_sub_i8_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB11_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: sub a5, a4, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a3 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB11_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw sub i8* %a, i8 %b acquire ret i8 %1 } @@ -180,6 +434,27 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_sub_i8_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB12_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: sub a5, a4, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a3 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB12_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw sub i8* %a, i8 %b release ret i8 %1 } @@ -194,6 +469,27 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_sub_i8_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB13_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: sub a5, a4, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a3 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB13_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw sub i8* %a, i8 %b acq_rel ret i8 %1 } @@ -208,6 +504,27 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_sub_i8_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB14_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: sub a5, a4, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a3 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB14_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw sub i8* %a, i8 %b seq_cst ret i8 %1 } @@ -222,6 +539,21 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_and_i8_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: not a3, a3 +; RV32IA-NEXT: or a1, a3, a1 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoand.w a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw and i8* %a, i8 %b monotonic ret i8 %1 } @@ -236,6 +568,21 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_and_i8_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: not a3, a3 +; RV32IA-NEXT: or a1, a3, a1 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoand.w.aq a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw and i8* %a, i8 %b acquire ret i8 %1 } @@ -250,6 +597,21 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_and_i8_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: not a3, a3 +; RV32IA-NEXT: or a1, a3, a1 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoand.w.rl a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw and i8* %a, i8 %b release ret i8 %1 } @@ -264,6 +626,21 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_and_i8_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: not a3, a3 +; RV32IA-NEXT: or a1, a3, a1 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoand.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw and i8* %a, i8 %b acq_rel ret i8 %1 } @@ -278,6 +655,21 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_and_i8_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: not a3, a3 +; RV32IA-NEXT: or a1, a3, a1 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoand.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw and i8* %a, i8 %b seq_cst ret i8 %1 } @@ -292,6 +684,28 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_nand_i8_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB20_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a5, a4, a1 +; RV32IA-NEXT: not a5, a5 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a3 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB20_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw nand i8* %a, i8 %b monotonic ret i8 %1 } @@ -306,6 +720,28 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_nand_i8_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB21_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a5, a4, a1 +; RV32IA-NEXT: not a5, a5 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a3 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB21_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw nand i8* %a, i8 %b acquire ret i8 %1 } @@ -320,6 +756,28 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_nand_i8_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB22_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a5, a4, a1 +; RV32IA-NEXT: not a5, a5 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a3 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB22_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw nand i8* %a, i8 %b release ret i8 %1 } @@ -334,6 +792,28 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_nand_i8_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB23_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a5, a4, a1 +; RV32IA-NEXT: not a5, a5 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a3 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB23_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw nand i8* %a, i8 %b acq_rel ret i8 %1 } @@ -348,6 +828,28 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_nand_i8_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a3, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB24_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: and a5, a4, a1 +; RV32IA-NEXT: not a5, a5 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a3 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB24_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw nand i8* %a, i8 %b seq_cst ret i8 %1 } @@ -362,6 +864,17 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_or_i8_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoor.w a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw or i8* %a, i8 %b monotonic ret i8 %1 } @@ -376,6 +889,17 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_or_i8_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoor.w.aq a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw or i8* %a, i8 %b acquire ret i8 %1 } @@ -390,6 +914,17 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_or_i8_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoor.w.rl a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw or i8* %a, i8 %b release ret i8 %1 } @@ -404,6 +939,17 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_or_i8_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoor.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw or i8* %a, i8 %b acq_rel ret i8 %1 } @@ -418,6 +964,17 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_or_i8_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoor.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw or i8* %a, i8 %b seq_cst ret i8 %1 } @@ -432,6 +989,17 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xor_i8_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoxor.w a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xor i8* %a, i8 %b monotonic ret i8 %1 } @@ -446,6 +1014,17 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xor_i8_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoxor.w.aq a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xor i8* %a, i8 %b acquire ret i8 %1 } @@ -460,6 +1039,17 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xor_i8_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoxor.w.rl a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xor i8* %a, i8 %b release ret i8 %1 } @@ -474,6 +1064,17 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xor_i8_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoxor.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xor i8* %a, i8 %b acq_rel ret i8 %1 } @@ -488,6 +1089,17 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xor_i8_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoxor.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xor i8* %a, i8 %b seq_cst ret i8 %1 } @@ -535,6 +1147,35 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_max_i8_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a6, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a1, a1, 24 +; RV32IA-NEXT: srai a1, a1, 24 +; RV32IA-NEXT: .LBB35_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a3, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: slli a3, a3, 24 +; RV32IA-NEXT: srai a3, a3, 24 +; RV32IA-NEXT: bge a3, a1, .LBB35_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB35_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB35_3: # in Loop: Header=BB35_1 Depth=1 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB35_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw max i8* %a, i8 %b monotonic ret i8 %1 } @@ -585,6 +1226,35 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_max_i8_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a6, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a1, a1, 24 +; RV32IA-NEXT: srai a1, a1, 24 +; RV32IA-NEXT: .LBB36_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a3, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: slli a3, a3, 24 +; RV32IA-NEXT: srai a3, a3, 24 +; RV32IA-NEXT: bge a3, a1, .LBB36_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB36_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB36_3: # in Loop: Header=BB36_1 Depth=1 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB36_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw max i8* %a, i8 %b acquire ret i8 %1 } @@ -635,6 +1305,35 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_max_i8_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a6, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a1, a1, 24 +; RV32IA-NEXT: srai a1, a1, 24 +; RV32IA-NEXT: .LBB37_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a3, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: slli a3, a3, 24 +; RV32IA-NEXT: srai a3, a3, 24 +; RV32IA-NEXT: bge a3, a1, .LBB37_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB37_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB37_3: # in Loop: Header=BB37_1 Depth=1 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB37_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw max i8* %a, i8 %b release ret i8 %1 } @@ -688,6 +1387,35 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_max_i8_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a6, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a1, a1, 24 +; RV32IA-NEXT: srai a1, a1, 24 +; RV32IA-NEXT: .LBB38_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a3, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: slli a3, a3, 24 +; RV32IA-NEXT: srai a3, a3, 24 +; RV32IA-NEXT: bge a3, a1, .LBB38_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB38_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB38_3: # in Loop: Header=BB38_1 Depth=1 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB38_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw max i8* %a, i8 %b acq_rel ret i8 %1 } @@ -738,6 +1466,35 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_max_i8_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a6, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a1, a1, 24 +; RV32IA-NEXT: srai a1, a1, 24 +; RV32IA-NEXT: .LBB39_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: and a3, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: slli a3, a3, 24 +; RV32IA-NEXT: srai a3, a3, 24 +; RV32IA-NEXT: bge a3, a1, .LBB39_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB39_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB39_3: # in Loop: Header=BB39_1 Depth=1 +; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB39_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw max i8* %a, i8 %b seq_cst ret i8 %1 } @@ -785,6 +1542,35 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_min_i8_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a6, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a1, a1, 24 +; RV32IA-NEXT: srai a1, a1, 24 +; RV32IA-NEXT: .LBB40_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a3, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: slli a3, a3, 24 +; RV32IA-NEXT: srai a3, a3, 24 +; RV32IA-NEXT: bge a1, a3, .LBB40_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB40_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB40_3: # in Loop: Header=BB40_1 Depth=1 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB40_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw min i8* %a, i8 %b monotonic ret i8 %1 } @@ -835,6 +1621,35 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_min_i8_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a6, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a1, a1, 24 +; RV32IA-NEXT: srai a1, a1, 24 +; RV32IA-NEXT: .LBB41_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a3, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: slli a3, a3, 24 +; RV32IA-NEXT: srai a3, a3, 24 +; RV32IA-NEXT: bge a1, a3, .LBB41_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB41_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB41_3: # in Loop: Header=BB41_1 Depth=1 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB41_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw min i8* %a, i8 %b acquire ret i8 %1 } @@ -885,6 +1700,35 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_min_i8_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a6, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a1, a1, 24 +; RV32IA-NEXT: srai a1, a1, 24 +; RV32IA-NEXT: .LBB42_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a3, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: slli a3, a3, 24 +; RV32IA-NEXT: srai a3, a3, 24 +; RV32IA-NEXT: bge a1, a3, .LBB42_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB42_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB42_3: # in Loop: Header=BB42_1 Depth=1 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB42_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw min i8* %a, i8 %b release ret i8 %1 } @@ -938,6 +1782,35 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_min_i8_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a6, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a1, a1, 24 +; RV32IA-NEXT: srai a1, a1, 24 +; RV32IA-NEXT: .LBB43_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a3, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: slli a3, a3, 24 +; RV32IA-NEXT: srai a3, a3, 24 +; RV32IA-NEXT: bge a1, a3, .LBB43_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB43_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB43_3: # in Loop: Header=BB43_1 Depth=1 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB43_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw min i8* %a, i8 %b acq_rel ret i8 %1 } @@ -988,6 +1861,35 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_min_i8_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a6, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a1, a1, 24 +; RV32IA-NEXT: srai a1, a1, 24 +; RV32IA-NEXT: .LBB44_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: and a3, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: slli a3, a3, 24 +; RV32IA-NEXT: srai a3, a3, 24 +; RV32IA-NEXT: bge a1, a3, .LBB44_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB44_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB44_3: # in Loop: Header=BB44_1 Depth=1 +; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB44_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw min i8* %a, i8 %b seq_cst ret i8 %1 } @@ -1033,6 +1935,31 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umax_i8_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a6, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB45_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a3, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: bgeu a3, a1, .LBB45_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB45_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB45_3: # in Loop: Header=BB45_1 Depth=1 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB45_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw umax i8* %a, i8 %b monotonic ret i8 %1 } @@ -1081,6 +2008,31 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umax_i8_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a6, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB46_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a3, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: bgeu a3, a1, .LBB46_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB46_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB46_3: # in Loop: Header=BB46_1 Depth=1 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB46_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw umax i8* %a, i8 %b acquire ret i8 %1 } @@ -1129,6 +2081,31 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umax_i8_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a6, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB47_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a3, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: bgeu a3, a1, .LBB47_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB47_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB47_3: # in Loop: Header=BB47_1 Depth=1 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB47_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw umax i8* %a, i8 %b release ret i8 %1 } @@ -1180,6 +2157,31 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umax_i8_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a6, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB48_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a3, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: bgeu a3, a1, .LBB48_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB48_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB48_3: # in Loop: Header=BB48_1 Depth=1 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB48_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw umax i8* %a, i8 %b acq_rel ret i8 %1 } @@ -1228,6 +2230,31 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umax_i8_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a6, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB49_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: and a3, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: bgeu a3, a1, .LBB49_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB49_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB49_3: # in Loop: Header=BB49_1 Depth=1 +; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB49_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw umax i8* %a, i8 %b seq_cst ret i8 %1 } @@ -1273,6 +2300,31 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umin_i8_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a6, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB50_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a3, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: bgeu a1, a3, .LBB50_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB50_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB50_3: # in Loop: Header=BB50_1 Depth=1 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB50_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw umin i8* %a, i8 %b monotonic ret i8 %1 } @@ -1321,6 +2373,31 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umin_i8_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a6, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB51_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a3, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: bgeu a1, a3, .LBB51_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB51_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB51_3: # in Loop: Header=BB51_1 Depth=1 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB51_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw umin i8* %a, i8 %b acquire ret i8 %1 } @@ -1369,6 +2446,31 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umin_i8_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a6, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB52_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a3, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: bgeu a1, a3, .LBB52_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB52_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB52_3: # in Loop: Header=BB52_1 Depth=1 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB52_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw umin i8* %a, i8 %b release ret i8 %1 } @@ -1420,6 +2522,31 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umin_i8_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a6, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB53_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a3, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: bgeu a1, a3, .LBB53_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB53_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB53_3: # in Loop: Header=BB53_1 Depth=1 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB53_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw umin i8* %a, i8 %b acq_rel ret i8 %1 } @@ -1468,6 +2595,31 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umin_i8_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: addi a3, zero, 255 +; RV32IA-NEXT: sll a6, a3, a2 +; RV32IA-NEXT: andi a1, a1, 255 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB54_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: and a3, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: bgeu a1, a3, .LBB54_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB54_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB54_3: # in Loop: Header=BB54_1 Depth=1 +; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB54_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a2 +; RV32IA-NEXT: ret %1 = atomicrmw umin i8* %a, i8 %b seq_cst ret i8 %1 } @@ -1482,6 +2634,28 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xchg_i16_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB55_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: add a5, zero, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a2 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB55_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i16* %a, i16 %b monotonic ret i16 %1 } @@ -1496,6 +2670,28 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xchg_i16_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB56_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: add a5, zero, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a2 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB56_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i16* %a, i16 %b acquire ret i16 %1 } @@ -1510,6 +2706,28 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xchg_i16_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB57_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: add a5, zero, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a2 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB57_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i16* %a, i16 %b release ret i16 %1 } @@ -1524,6 +2742,28 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xchg_i16_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB58_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: add a5, zero, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a2 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB58_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i16* %a, i16 %b acq_rel ret i16 %1 } @@ -1538,6 +2778,28 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xchg_i16_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB59_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: add a5, zero, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a2 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB59_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i16* %a, i16 %b seq_cst ret i16 %1 } @@ -1552,6 +2814,28 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_add_i16_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB60_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: add a5, a4, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a2 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB60_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw add i16* %a, i16 %b monotonic ret i16 %1 } @@ -1566,6 +2850,28 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_add_i16_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB61_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: add a5, a4, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a2 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB61_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw add i16* %a, i16 %b acquire ret i16 %1 } @@ -1580,6 +2886,28 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_add_i16_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB62_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: add a5, a4, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a2 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB62_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw add i16* %a, i16 %b release ret i16 %1 } @@ -1594,6 +2922,28 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_add_i16_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB63_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: add a5, a4, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a2 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB63_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw add i16* %a, i16 %b acq_rel ret i16 %1 } @@ -1608,6 +2958,28 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_add_i16_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB64_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: add a5, a4, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a2 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB64_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw add i16* %a, i16 %b seq_cst ret i16 %1 } @@ -1622,6 +2994,28 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_sub_i16_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB65_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: sub a5, a4, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a2 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB65_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw sub i16* %a, i16 %b monotonic ret i16 %1 } @@ -1636,6 +3030,28 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_sub_i16_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB66_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: sub a5, a4, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a2 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB66_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw sub i16* %a, i16 %b acquire ret i16 %1 } @@ -1650,6 +3066,28 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_sub_i16_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB67_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: sub a5, a4, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a2 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB67_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw sub i16* %a, i16 %b release ret i16 %1 } @@ -1664,6 +3102,28 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_sub_i16_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB68_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: sub a5, a4, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a2 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB68_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw sub i16* %a, i16 %b acq_rel ret i16 %1 } @@ -1678,6 +3138,28 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_sub_i16_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB69_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: sub a5, a4, a1 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a2 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB69_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw sub i16* %a, i16 %b seq_cst ret i16 %1 } @@ -1692,6 +3174,22 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_and_i16_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: not a2, a2 +; RV32IA-NEXT: or a1, a2, a1 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoand.w a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a3 +; RV32IA-NEXT: ret %1 = atomicrmw and i16* %a, i16 %b monotonic ret i16 %1 } @@ -1706,6 +3204,22 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_and_i16_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: not a2, a2 +; RV32IA-NEXT: or a1, a2, a1 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoand.w.aq a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a3 +; RV32IA-NEXT: ret %1 = atomicrmw and i16* %a, i16 %b acquire ret i16 %1 } @@ -1720,6 +3234,22 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_and_i16_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: not a2, a2 +; RV32IA-NEXT: or a1, a2, a1 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoand.w.rl a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a3 +; RV32IA-NEXT: ret %1 = atomicrmw and i16* %a, i16 %b release ret i16 %1 } @@ -1734,6 +3264,22 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_and_i16_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: not a2, a2 +; RV32IA-NEXT: or a1, a2, a1 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoand.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a3 +; RV32IA-NEXT: ret %1 = atomicrmw and i16* %a, i16 %b acq_rel ret i16 %1 } @@ -1748,6 +3294,22 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_and_i16_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: not a2, a2 +; RV32IA-NEXT: or a1, a2, a1 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoand.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a3 +; RV32IA-NEXT: ret %1 = atomicrmw and i16* %a, i16 %b seq_cst ret i16 %1 } @@ -1762,6 +3324,29 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_nand_i16_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB75_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a5, a4, a1 +; RV32IA-NEXT: not a5, a5 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a2 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB75_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw nand i16* %a, i16 %b monotonic ret i16 %1 } @@ -1776,6 +3361,29 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_nand_i16_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB76_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a5, a4, a1 +; RV32IA-NEXT: not a5, a5 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a2 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB76_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw nand i16* %a, i16 %b acquire ret i16 %1 } @@ -1790,6 +3398,29 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_nand_i16_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB77_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a5, a4, a1 +; RV32IA-NEXT: not a5, a5 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a2 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB77_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw nand i16* %a, i16 %b release ret i16 %1 } @@ -1804,6 +3435,29 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_nand_i16_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB78_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a5, a4, a1 +; RV32IA-NEXT: not a5, a5 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a2 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB78_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw nand i16* %a, i16 %b acq_rel ret i16 %1 } @@ -1818,6 +3472,29 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_nand_i16_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a2, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB79_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: and a5, a4, a1 +; RV32IA-NEXT: not a5, a5 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: and a5, a5, a2 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB79_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw nand i16* %a, i16 %b seq_cst ret i16 %1 } @@ -1832,6 +3509,19 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_or_i16_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoor.w a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw or i16* %a, i16 %b monotonic ret i16 %1 } @@ -1846,6 +3536,19 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_or_i16_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoor.w.aq a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw or i16* %a, i16 %b acquire ret i16 %1 } @@ -1860,6 +3563,19 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_or_i16_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoor.w.rl a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw or i16* %a, i16 %b release ret i16 %1 } @@ -1874,6 +3590,19 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_or_i16_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoor.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw or i16* %a, i16 %b acq_rel ret i16 %1 } @@ -1888,6 +3617,19 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_or_i16_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoor.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw or i16* %a, i16 %b seq_cst ret i16 %1 } @@ -1902,6 +3644,19 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xor_i16_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoxor.w a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xor i16* %a, i16 %b monotonic ret i16 %1 } @@ -1916,6 +3671,19 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xor_i16_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoxor.w.aq a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xor i16* %a, i16 %b acquire ret i16 %1 } @@ -1930,6 +3698,19 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xor_i16_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoxor.w.rl a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xor i16* %a, i16 %b release ret i16 %1 } @@ -1944,6 +3725,19 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xor_i16_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoxor.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xor i16* %a, i16 %b acq_rel ret i16 %1 } @@ -1958,6 +3752,19 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xor_i16_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a2, a0, 3 +; RV32IA-NEXT: andi a2, a2, 24 +; RV32IA-NEXT: sll a1, a1, a2 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: amoxor.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: srl a0, a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xor i16* %a, i16 %b seq_cst ret i16 %1 } @@ -2005,6 +3812,36 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_max_i16_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a6, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a1, a1, 16 +; RV32IA-NEXT: srai a1, a1, 16 +; RV32IA-NEXT: .LBB90_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a2, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: slli a2, a2, 16 +; RV32IA-NEXT: srai a2, a2, 16 +; RV32IA-NEXT: bge a2, a1, .LBB90_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB90_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB90_3: # in Loop: Header=BB90_1 Depth=1 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB90_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw max i16* %a, i16 %b monotonic ret i16 %1 } @@ -2055,6 +3892,36 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_max_i16_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a6, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a1, a1, 16 +; RV32IA-NEXT: srai a1, a1, 16 +; RV32IA-NEXT: .LBB91_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a2, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: slli a2, a2, 16 +; RV32IA-NEXT: srai a2, a2, 16 +; RV32IA-NEXT: bge a2, a1, .LBB91_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB91_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB91_3: # in Loop: Header=BB91_1 Depth=1 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB91_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw max i16* %a, i16 %b acquire ret i16 %1 } @@ -2105,6 +3972,36 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_max_i16_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a6, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a1, a1, 16 +; RV32IA-NEXT: srai a1, a1, 16 +; RV32IA-NEXT: .LBB92_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a2, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: slli a2, a2, 16 +; RV32IA-NEXT: srai a2, a2, 16 +; RV32IA-NEXT: bge a2, a1, .LBB92_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB92_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB92_3: # in Loop: Header=BB92_1 Depth=1 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB92_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw max i16* %a, i16 %b release ret i16 %1 } @@ -2158,6 +4055,36 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_max_i16_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a6, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a1, a1, 16 +; RV32IA-NEXT: srai a1, a1, 16 +; RV32IA-NEXT: .LBB93_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a2, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: slli a2, a2, 16 +; RV32IA-NEXT: srai a2, a2, 16 +; RV32IA-NEXT: bge a2, a1, .LBB93_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB93_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB93_3: # in Loop: Header=BB93_1 Depth=1 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB93_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw max i16* %a, i16 %b acq_rel ret i16 %1 } @@ -2208,6 +4135,36 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_max_i16_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a6, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a1, a1, 16 +; RV32IA-NEXT: srai a1, a1, 16 +; RV32IA-NEXT: .LBB94_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: and a2, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: slli a2, a2, 16 +; RV32IA-NEXT: srai a2, a2, 16 +; RV32IA-NEXT: bge a2, a1, .LBB94_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB94_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB94_3: # in Loop: Header=BB94_1 Depth=1 +; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB94_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw max i16* %a, i16 %b seq_cst ret i16 %1 } @@ -2255,6 +4212,36 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_min_i16_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a6, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a1, a1, 16 +; RV32IA-NEXT: srai a1, a1, 16 +; RV32IA-NEXT: .LBB95_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a2, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: slli a2, a2, 16 +; RV32IA-NEXT: srai a2, a2, 16 +; RV32IA-NEXT: bge a1, a2, .LBB95_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB95_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB95_3: # in Loop: Header=BB95_1 Depth=1 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB95_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw min i16* %a, i16 %b monotonic ret i16 %1 } @@ -2305,6 +4292,36 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_min_i16_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a6, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a1, a1, 16 +; RV32IA-NEXT: srai a1, a1, 16 +; RV32IA-NEXT: .LBB96_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a2, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: slli a2, a2, 16 +; RV32IA-NEXT: srai a2, a2, 16 +; RV32IA-NEXT: bge a1, a2, .LBB96_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB96_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB96_3: # in Loop: Header=BB96_1 Depth=1 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB96_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw min i16* %a, i16 %b acquire ret i16 %1 } @@ -2355,6 +4372,36 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_min_i16_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a6, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a1, a1, 16 +; RV32IA-NEXT: srai a1, a1, 16 +; RV32IA-NEXT: .LBB97_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a2, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: slli a2, a2, 16 +; RV32IA-NEXT: srai a2, a2, 16 +; RV32IA-NEXT: bge a1, a2, .LBB97_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB97_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB97_3: # in Loop: Header=BB97_1 Depth=1 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB97_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw min i16* %a, i16 %b release ret i16 %1 } @@ -2408,6 +4455,36 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_min_i16_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a6, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a1, a1, 16 +; RV32IA-NEXT: srai a1, a1, 16 +; RV32IA-NEXT: .LBB98_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a2, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: slli a2, a2, 16 +; RV32IA-NEXT: srai a2, a2, 16 +; RV32IA-NEXT: bge a1, a2, .LBB98_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB98_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB98_3: # in Loop: Header=BB98_1 Depth=1 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB98_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw min i16* %a, i16 %b acq_rel ret i16 %1 } @@ -2458,6 +4535,36 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_min_i16_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a6, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a1, a1, 16 +; RV32IA-NEXT: srai a1, a1, 16 +; RV32IA-NEXT: .LBB99_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: and a2, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: slli a2, a2, 16 +; RV32IA-NEXT: srai a2, a2, 16 +; RV32IA-NEXT: bge a1, a2, .LBB99_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB99_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB99_3: # in Loop: Header=BB99_1 Depth=1 +; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB99_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw min i16* %a, i16 %b seq_cst ret i16 %1 } @@ -2507,6 +4614,32 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umax_i16_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a6, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB100_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a2, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: bgeu a2, a1, .LBB100_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB100_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB100_3: # in Loop: Header=BB100_1 Depth=1 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB100_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw umax i16* %a, i16 %b monotonic ret i16 %1 } @@ -2559,6 +4692,32 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umax_i16_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a6, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB101_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a2, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: bgeu a2, a1, .LBB101_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB101_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB101_3: # in Loop: Header=BB101_1 Depth=1 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB101_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw umax i16* %a, i16 %b acquire ret i16 %1 } @@ -2611,6 +4770,32 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umax_i16_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a6, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB102_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a2, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: bgeu a2, a1, .LBB102_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB102_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB102_3: # in Loop: Header=BB102_1 Depth=1 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB102_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw umax i16* %a, i16 %b release ret i16 %1 } @@ -2666,6 +4851,32 @@ ; RV32I-NEXT: lw ra, 44(sp) ; RV32I-NEXT: addi sp, sp, 48 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umax_i16_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a6, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB103_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a2, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: bgeu a2, a1, .LBB103_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB103_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB103_3: # in Loop: Header=BB103_1 Depth=1 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB103_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw umax i16* %a, i16 %b acq_rel ret i16 %1 } @@ -2718,6 +4929,32 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umax_i16_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a6, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB104_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: and a2, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: bgeu a2, a1, .LBB104_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB104_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB104_3: # in Loop: Header=BB104_1 Depth=1 +; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB104_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw umax i16* %a, i16 %b seq_cst ret i16 %1 } @@ -2767,6 +5004,32 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umin_i16_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a6, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB105_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a2, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: bgeu a1, a2, .LBB105_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB105_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB105_3: # in Loop: Header=BB105_1 Depth=1 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB105_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw umin i16* %a, i16 %b monotonic ret i16 %1 } @@ -2819,6 +5082,32 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umin_i16_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a6, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB106_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a2, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: bgeu a1, a2, .LBB106_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB106_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB106_3: # in Loop: Header=BB106_1 Depth=1 +; RV32IA-NEXT: sc.w a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB106_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw umin i16* %a, i16 %b acquire ret i16 %1 } @@ -2871,6 +5160,32 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umin_i16_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a6, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB107_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a2, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: bgeu a1, a2, .LBB107_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB107_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB107_3: # in Loop: Header=BB107_1 Depth=1 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB107_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw umin i16* %a, i16 %b release ret i16 %1 } @@ -2926,6 +5241,32 @@ ; RV32I-NEXT: lw ra, 44(sp) ; RV32I-NEXT: addi sp, sp, 48 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umin_i16_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a6, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB108_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a2, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: bgeu a1, a2, .LBB108_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB108_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB108_3: # in Loop: Header=BB108_1 Depth=1 +; RV32IA-NEXT: sc.w.rl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB108_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw umin i16* %a, i16 %b acq_rel ret i16 %1 } @@ -2978,6 +5319,32 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umin_i16_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: lui a2, 16 +; RV32IA-NEXT: addi a2, a2, -1 +; RV32IA-NEXT: and a1, a1, a2 +; RV32IA-NEXT: slli a3, a0, 3 +; RV32IA-NEXT: andi a3, a3, 24 +; RV32IA-NEXT: sll a6, a2, a3 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: .LBB109_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: and a2, a4, a6 +; RV32IA-NEXT: mv a5, a4 +; RV32IA-NEXT: bgeu a1, a2, .LBB109_3 +; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB109_1 Depth=1 +; RV32IA-NEXT: xor a5, a4, a1 +; RV32IA-NEXT: and a5, a5, a6 +; RV32IA-NEXT: xor a5, a4, a5 +; RV32IA-NEXT: .LBB109_3: # in Loop: Header=BB109_1 Depth=1 +; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0) +; RV32IA-NEXT: bnez a5, .LBB109_1 +; RV32IA-NEXT: # %bb.4: +; RV32IA-NEXT: srl a0, a4, a3 +; RV32IA-NEXT: ret %1 = atomicrmw umin i16* %a, i16 %b seq_cst ret i16 %1 } @@ -2992,6 +5359,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xchg_i32_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoswap.w a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw xchg i32* %a, i32 %b monotonic ret i32 %1 } @@ -3006,6 +5378,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xchg_i32_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoswap.w.aq a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw xchg i32* %a, i32 %b acquire ret i32 %1 } @@ -3020,6 +5397,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xchg_i32_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoswap.w.rl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw xchg i32* %a, i32 %b release ret i32 %1 } @@ -3034,6 +5416,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xchg_i32_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoswap.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw xchg i32* %a, i32 %b acq_rel ret i32 %1 } @@ -3048,6 +5435,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xchg_i32_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoswap.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw xchg i32* %a, i32 %b seq_cst ret i32 %1 } @@ -3062,6 +5454,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_add_i32_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoadd.w a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw add i32* %a, i32 %b monotonic ret i32 %1 } @@ -3076,6 +5473,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_add_i32_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoadd.w.aq a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw add i32* %a, i32 %b acquire ret i32 %1 } @@ -3090,6 +5492,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_add_i32_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoadd.w.rl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw add i32* %a, i32 %b release ret i32 %1 } @@ -3104,6 +5511,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_add_i32_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoadd.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw add i32* %a, i32 %b acq_rel ret i32 %1 } @@ -3118,6 +5530,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_add_i32_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoadd.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw add i32* %a, i32 %b seq_cst ret i32 %1 } @@ -3132,6 +5549,12 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_sub_i32_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: neg a1, a1 +; RV32IA-NEXT: amoadd.w a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw sub i32* %a, i32 %b monotonic ret i32 %1 } @@ -3146,6 +5569,12 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_sub_i32_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: neg a1, a1 +; RV32IA-NEXT: amoadd.w.aq a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw sub i32* %a, i32 %b acquire ret i32 %1 } @@ -3160,6 +5589,12 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_sub_i32_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: neg a1, a1 +; RV32IA-NEXT: amoadd.w.rl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw sub i32* %a, i32 %b release ret i32 %1 } @@ -3174,6 +5609,12 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_sub_i32_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: neg a1, a1 +; RV32IA-NEXT: amoadd.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw sub i32* %a, i32 %b acq_rel ret i32 %1 } @@ -3188,6 +5629,12 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_sub_i32_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: neg a1, a1 +; RV32IA-NEXT: amoadd.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw sub i32* %a, i32 %b seq_cst ret i32 %1 } @@ -3202,6 +5649,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_and_i32_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoand.w a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw and i32* %a, i32 %b monotonic ret i32 %1 } @@ -3216,6 +5668,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_and_i32_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoand.w.aq a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw and i32* %a, i32 %b acquire ret i32 %1 } @@ -3230,6 +5687,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_and_i32_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoand.w.rl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw and i32* %a, i32 %b release ret i32 %1 } @@ -3244,6 +5706,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_and_i32_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoand.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw and i32* %a, i32 %b acq_rel ret i32 %1 } @@ -3258,6 +5725,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_and_i32_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoand.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw and i32* %a, i32 %b seq_cst ret i32 %1 } @@ -3272,6 +5744,18 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_nand_i32_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: .LBB130_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a2, (a0) +; RV32IA-NEXT: and a3, a2, a1 +; RV32IA-NEXT: not a3, a3 +; RV32IA-NEXT: sc.w a3, a3, (a0) +; RV32IA-NEXT: bnez a3, .LBB130_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw nand i32* %a, i32 %b monotonic ret i32 %1 } @@ -3286,6 +5770,18 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_nand_i32_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: .LBB131_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a2, (a0) +; RV32IA-NEXT: and a3, a2, a1 +; RV32IA-NEXT: not a3, a3 +; RV32IA-NEXT: sc.w a3, a3, (a0) +; RV32IA-NEXT: bnez a3, .LBB131_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw nand i32* %a, i32 %b acquire ret i32 %1 } @@ -3300,6 +5796,18 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_nand_i32_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: .LBB132_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a2, (a0) +; RV32IA-NEXT: and a3, a2, a1 +; RV32IA-NEXT: not a3, a3 +; RV32IA-NEXT: sc.w.rl a3, a3, (a0) +; RV32IA-NEXT: bnez a3, .LBB132_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw nand i32* %a, i32 %b release ret i32 %1 } @@ -3314,6 +5822,18 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_nand_i32_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: .LBB133_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a2, (a0) +; RV32IA-NEXT: and a3, a2, a1 +; RV32IA-NEXT: not a3, a3 +; RV32IA-NEXT: sc.w.rl a3, a3, (a0) +; RV32IA-NEXT: bnez a3, .LBB133_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw nand i32* %a, i32 %b acq_rel ret i32 %1 } @@ -3328,6 +5848,18 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_nand_i32_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: .LBB134_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a2, (a0) +; RV32IA-NEXT: and a3, a2, a1 +; RV32IA-NEXT: not a3, a3 +; RV32IA-NEXT: sc.w.aqrl a3, a3, (a0) +; RV32IA-NEXT: bnez a3, .LBB134_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw nand i32* %a, i32 %b seq_cst ret i32 %1 } @@ -3342,6 +5874,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_or_i32_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoor.w a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw or i32* %a, i32 %b monotonic ret i32 %1 } @@ -3356,6 +5893,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_or_i32_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoor.w.aq a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw or i32* %a, i32 %b acquire ret i32 %1 } @@ -3370,6 +5912,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_or_i32_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoor.w.rl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw or i32* %a, i32 %b release ret i32 %1 } @@ -3384,6 +5931,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_or_i32_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoor.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw or i32* %a, i32 %b acq_rel ret i32 %1 } @@ -3398,6 +5950,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_or_i32_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoor.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw or i32* %a, i32 %b seq_cst ret i32 %1 } @@ -3412,6 +5969,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xor_i32_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoxor.w a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw xor i32* %a, i32 %b monotonic ret i32 %1 } @@ -3426,6 +5988,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xor_i32_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoxor.w.aq a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw xor i32* %a, i32 %b acquire ret i32 %1 } @@ -3440,6 +6007,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xor_i32_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoxor.w.rl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw xor i32* %a, i32 %b release ret i32 %1 } @@ -3454,6 +6026,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xor_i32_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoxor.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw xor i32* %a, i32 %b acq_rel ret i32 %1 } @@ -3468,6 +6045,11 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xor_i32_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amoxor.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw xor i32* %a, i32 %b seq_cst ret i32 %1 } @@ -3508,6 +6090,11 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_max_i32_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amomax.w a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw max i32* %a, i32 %b monotonic ret i32 %1 } @@ -3551,6 +6138,11 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_max_i32_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amomax.w.aq a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw max i32* %a, i32 %b acquire ret i32 %1 } @@ -3594,6 +6186,11 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_max_i32_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amomax.w.rl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw max i32* %a, i32 %b release ret i32 %1 } @@ -3640,6 +6237,11 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_max_i32_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amomax.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw max i32* %a, i32 %b acq_rel ret i32 %1 } @@ -3683,6 +6285,11 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_max_i32_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amomax.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw max i32* %a, i32 %b seq_cst ret i32 %1 } @@ -3723,6 +6330,11 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_min_i32_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amomin.w a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw min i32* %a, i32 %b monotonic ret i32 %1 } @@ -3766,6 +6378,11 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_min_i32_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amomin.w.aq a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw min i32* %a, i32 %b acquire ret i32 %1 } @@ -3809,6 +6426,11 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_min_i32_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amomin.w.rl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw min i32* %a, i32 %b release ret i32 %1 } @@ -3855,6 +6477,11 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_min_i32_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amomin.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw min i32* %a, i32 %b acq_rel ret i32 %1 } @@ -3898,6 +6525,11 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_min_i32_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amomin.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw min i32* %a, i32 %b seq_cst ret i32 %1 } @@ -3938,6 +6570,11 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umax_i32_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amomaxu.w a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw umax i32* %a, i32 %b monotonic ret i32 %1 } @@ -3981,6 +6618,11 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umax_i32_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amomaxu.w.aq a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw umax i32* %a, i32 %b acquire ret i32 %1 } @@ -4024,6 +6666,11 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umax_i32_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amomaxu.w.rl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw umax i32* %a, i32 %b release ret i32 %1 } @@ -4070,6 +6717,11 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umax_i32_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amomaxu.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw umax i32* %a, i32 %b acq_rel ret i32 %1 } @@ -4113,6 +6765,11 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umax_i32_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amomaxu.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw umax i32* %a, i32 %b seq_cst ret i32 %1 } @@ -4153,6 +6810,11 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umin_i32_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amominu.w a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw umin i32* %a, i32 %b monotonic ret i32 %1 } @@ -4196,6 +6858,11 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umin_i32_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amominu.w.aq a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw umin i32* %a, i32 %b acquire ret i32 %1 } @@ -4239,6 +6906,11 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umin_i32_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amominu.w.rl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw umin i32* %a, i32 %b release ret i32 %1 } @@ -4285,6 +6957,11 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umin_i32_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amominu.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw umin i32* %a, i32 %b acq_rel ret i32 %1 } @@ -4328,6 +7005,11 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umin_i32_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: amominu.w.aqrl a0, a1, (a0) +; RV32IA-NEXT: ret %1 = atomicrmw umin i32* %a, i32 %b seq_cst ret i32 %1 } @@ -4342,6 +7024,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xchg_i64_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: mv a3, zero +; RV32IA-NEXT: call __atomic_exchange_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i64* %a, i64 %b monotonic ret i64 %1 } @@ -4356,6 +7048,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xchg_i64_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 2 +; RV32IA-NEXT: call __atomic_exchange_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i64* %a, i64 %b acquire ret i64 %1 } @@ -4370,6 +7072,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xchg_i64_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 3 +; RV32IA-NEXT: call __atomic_exchange_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i64* %a, i64 %b release ret i64 %1 } @@ -4384,6 +7096,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xchg_i64_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 4 +; RV32IA-NEXT: call __atomic_exchange_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i64* %a, i64 %b acq_rel ret i64 %1 } @@ -4398,6 +7120,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xchg_i64_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 5 +; RV32IA-NEXT: call __atomic_exchange_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i64* %a, i64 %b seq_cst ret i64 %1 } @@ -4412,6 +7144,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_add_i64_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: mv a3, zero +; RV32IA-NEXT: call __atomic_fetch_add_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw add i64* %a, i64 %b monotonic ret i64 %1 } @@ -4426,6 +7168,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_add_i64_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 2 +; RV32IA-NEXT: call __atomic_fetch_add_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw add i64* %a, i64 %b acquire ret i64 %1 } @@ -4440,6 +7192,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_add_i64_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 3 +; RV32IA-NEXT: call __atomic_fetch_add_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw add i64* %a, i64 %b release ret i64 %1 } @@ -4454,6 +7216,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_add_i64_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 4 +; RV32IA-NEXT: call __atomic_fetch_add_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw add i64* %a, i64 %b acq_rel ret i64 %1 } @@ -4468,6 +7240,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_add_i64_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 5 +; RV32IA-NEXT: call __atomic_fetch_add_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw add i64* %a, i64 %b seq_cst ret i64 %1 } @@ -4482,6 +7264,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_sub_i64_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: mv a3, zero +; RV32IA-NEXT: call __atomic_fetch_sub_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw sub i64* %a, i64 %b monotonic ret i64 %1 } @@ -4496,6 +7288,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_sub_i64_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 2 +; RV32IA-NEXT: call __atomic_fetch_sub_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw sub i64* %a, i64 %b acquire ret i64 %1 } @@ -4510,6 +7312,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_sub_i64_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 3 +; RV32IA-NEXT: call __atomic_fetch_sub_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw sub i64* %a, i64 %b release ret i64 %1 } @@ -4524,6 +7336,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_sub_i64_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 4 +; RV32IA-NEXT: call __atomic_fetch_sub_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw sub i64* %a, i64 %b acq_rel ret i64 %1 } @@ -4538,6 +7360,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_sub_i64_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 5 +; RV32IA-NEXT: call __atomic_fetch_sub_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw sub i64* %a, i64 %b seq_cst ret i64 %1 } @@ -4552,6 +7384,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_and_i64_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: mv a3, zero +; RV32IA-NEXT: call __atomic_fetch_and_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw and i64* %a, i64 %b monotonic ret i64 %1 } @@ -4566,6 +7408,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_and_i64_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 2 +; RV32IA-NEXT: call __atomic_fetch_and_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw and i64* %a, i64 %b acquire ret i64 %1 } @@ -4580,6 +7432,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_and_i64_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 3 +; RV32IA-NEXT: call __atomic_fetch_and_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw and i64* %a, i64 %b release ret i64 %1 } @@ -4594,6 +7456,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_and_i64_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 4 +; RV32IA-NEXT: call __atomic_fetch_and_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw and i64* %a, i64 %b acq_rel ret i64 %1 } @@ -4608,6 +7480,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_and_i64_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 5 +; RV32IA-NEXT: call __atomic_fetch_and_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw and i64* %a, i64 %b seq_cst ret i64 %1 } @@ -4622,6 +7504,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_nand_i64_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: mv a3, zero +; RV32IA-NEXT: call __atomic_fetch_nand_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw nand i64* %a, i64 %b monotonic ret i64 %1 } @@ -4636,6 +7528,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_nand_i64_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 2 +; RV32IA-NEXT: call __atomic_fetch_nand_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw nand i64* %a, i64 %b acquire ret i64 %1 } @@ -4650,6 +7552,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_nand_i64_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 3 +; RV32IA-NEXT: call __atomic_fetch_nand_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw nand i64* %a, i64 %b release ret i64 %1 } @@ -4664,6 +7576,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_nand_i64_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 4 +; RV32IA-NEXT: call __atomic_fetch_nand_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw nand i64* %a, i64 %b acq_rel ret i64 %1 } @@ -4678,6 +7600,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_nand_i64_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 5 +; RV32IA-NEXT: call __atomic_fetch_nand_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw nand i64* %a, i64 %b seq_cst ret i64 %1 } @@ -4692,6 +7624,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_or_i64_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: mv a3, zero +; RV32IA-NEXT: call __atomic_fetch_or_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw or i64* %a, i64 %b monotonic ret i64 %1 } @@ -4706,6 +7648,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_or_i64_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 2 +; RV32IA-NEXT: call __atomic_fetch_or_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw or i64* %a, i64 %b acquire ret i64 %1 } @@ -4720,6 +7672,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_or_i64_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 3 +; RV32IA-NEXT: call __atomic_fetch_or_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw or i64* %a, i64 %b release ret i64 %1 } @@ -4734,6 +7696,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_or_i64_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 4 +; RV32IA-NEXT: call __atomic_fetch_or_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw or i64* %a, i64 %b acq_rel ret i64 %1 } @@ -4748,6 +7720,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_or_i64_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 5 +; RV32IA-NEXT: call __atomic_fetch_or_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw or i64* %a, i64 %b seq_cst ret i64 %1 } @@ -4762,6 +7744,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xor_i64_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: mv a3, zero +; RV32IA-NEXT: call __atomic_fetch_xor_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw xor i64* %a, i64 %b monotonic ret i64 %1 } @@ -4776,6 +7768,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xor_i64_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 2 +; RV32IA-NEXT: call __atomic_fetch_xor_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw xor i64* %a, i64 %b acquire ret i64 %1 } @@ -4790,6 +7792,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xor_i64_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 3 +; RV32IA-NEXT: call __atomic_fetch_xor_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw xor i64* %a, i64 %b release ret i64 %1 } @@ -4804,6 +7816,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xor_i64_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 4 +; RV32IA-NEXT: call __atomic_fetch_xor_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw xor i64* %a, i64 %b acq_rel ret i64 %1 } @@ -4818,6 +7840,16 @@ ; RV32I-NEXT: lw ra, 12(sp) ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_xor_i64_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -16 +; RV32IA-NEXT: sw ra, 12(sp) +; RV32IA-NEXT: addi a3, zero, 5 +; RV32IA-NEXT: call __atomic_fetch_xor_8 +; RV32IA-NEXT: lw ra, 12(sp) +; RV32IA-NEXT: addi sp, sp, 16 +; RV32IA-NEXT: ret %1 = atomicrmw xor i64* %a, i64 %b seq_cst ret i64 %1 } @@ -4880,6 +7912,64 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_max_i64_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -32 +; RV32IA-NEXT: sw ra, 28(sp) +; RV32IA-NEXT: sw s1, 24(sp) +; RV32IA-NEXT: sw s2, 20(sp) +; RV32IA-NEXT: sw s3, 16(sp) +; RV32IA-NEXT: sw s4, 12(sp) +; RV32IA-NEXT: mv s1, a2 +; RV32IA-NEXT: mv s2, a1 +; RV32IA-NEXT: mv s3, a0 +; RV32IA-NEXT: lw a1, 4(a0) +; RV32IA-NEXT: lw a2, 0(a0) +; RV32IA-NEXT: mv s4, sp +; RV32IA-NEXT: .LBB200_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB200_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB200_1 Depth=1 +; RV32IA-NEXT: slt a0, s1, a1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB200_4 +; RV32IA-NEXT: j .LBB200_5 +; RV32IA-NEXT: .LBB200_3: # in Loop: Header=BB200_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB200_5 +; RV32IA-NEXT: .LBB200_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB200_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB200_5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB200_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB200_7 +; RV32IA-NEXT: # %bb.6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB200_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB200_7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB200_1 Depth=1 +; RV32IA-NEXT: sw a1, 4(sp) +; RV32IA-NEXT: mv a0, s3 +; RV32IA-NEXT: mv a1, s4 +; RV32IA-NEXT: mv a4, zero +; RV32IA-NEXT: mv a5, zero +; RV32IA-NEXT: call __atomic_compare_exchange_8 +; RV32IA-NEXT: lw a1, 4(sp) +; RV32IA-NEXT: lw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB200_1 +; RV32IA-NEXT: # %bb.8: # %atomicrmw.end +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: lw s4, 12(sp) +; RV32IA-NEXT: lw s3, 16(sp) +; RV32IA-NEXT: lw s2, 20(sp) +; RV32IA-NEXT: lw s1, 24(sp) +; RV32IA-NEXT: lw ra, 28(sp) +; RV32IA-NEXT: addi sp, sp, 32 +; RV32IA-NEXT: ret %1 = atomicrmw max i64* %a, i64 %b monotonic ret i64 %1 } @@ -4945,6 +8035,67 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_max_i64_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -32 +; RV32IA-NEXT: sw ra, 28(sp) +; RV32IA-NEXT: sw s1, 24(sp) +; RV32IA-NEXT: sw s2, 20(sp) +; RV32IA-NEXT: sw s3, 16(sp) +; RV32IA-NEXT: sw s4, 12(sp) +; RV32IA-NEXT: sw s5, 8(sp) +; RV32IA-NEXT: mv s1, a2 +; RV32IA-NEXT: mv s2, a1 +; RV32IA-NEXT: mv s3, a0 +; RV32IA-NEXT: lw a1, 4(a0) +; RV32IA-NEXT: lw a2, 0(a0) +; RV32IA-NEXT: mv s4, sp +; RV32IA-NEXT: addi s5, zero, 2 +; RV32IA-NEXT: .LBB201_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB201_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB201_1 Depth=1 +; RV32IA-NEXT: slt a0, s1, a1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB201_4 +; RV32IA-NEXT: j .LBB201_5 +; RV32IA-NEXT: .LBB201_3: # in Loop: Header=BB201_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB201_5 +; RV32IA-NEXT: .LBB201_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB201_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB201_5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB201_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB201_7 +; RV32IA-NEXT: # %bb.6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB201_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB201_7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB201_1 Depth=1 +; RV32IA-NEXT: sw a1, 4(sp) +; RV32IA-NEXT: mv a0, s3 +; RV32IA-NEXT: mv a1, s4 +; RV32IA-NEXT: mv a4, s5 +; RV32IA-NEXT: mv a5, s5 +; RV32IA-NEXT: call __atomic_compare_exchange_8 +; RV32IA-NEXT: lw a1, 4(sp) +; RV32IA-NEXT: lw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB201_1 +; RV32IA-NEXT: # %bb.8: # %atomicrmw.end +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: lw s5, 8(sp) +; RV32IA-NEXT: lw s4, 12(sp) +; RV32IA-NEXT: lw s3, 16(sp) +; RV32IA-NEXT: lw s2, 20(sp) +; RV32IA-NEXT: lw s1, 24(sp) +; RV32IA-NEXT: lw ra, 28(sp) +; RV32IA-NEXT: addi sp, sp, 32 +; RV32IA-NEXT: ret %1 = atomicrmw max i64* %a, i64 %b acquire ret i64 %1 } @@ -5010,6 +8161,67 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_max_i64_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -32 +; RV32IA-NEXT: sw ra, 28(sp) +; RV32IA-NEXT: sw s1, 24(sp) +; RV32IA-NEXT: sw s2, 20(sp) +; RV32IA-NEXT: sw s3, 16(sp) +; RV32IA-NEXT: sw s4, 12(sp) +; RV32IA-NEXT: sw s5, 8(sp) +; RV32IA-NEXT: mv s1, a2 +; RV32IA-NEXT: mv s2, a1 +; RV32IA-NEXT: mv s3, a0 +; RV32IA-NEXT: lw a1, 4(a0) +; RV32IA-NEXT: lw a2, 0(a0) +; RV32IA-NEXT: mv s4, sp +; RV32IA-NEXT: addi s5, zero, 3 +; RV32IA-NEXT: .LBB202_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB202_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB202_1 Depth=1 +; RV32IA-NEXT: slt a0, s1, a1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB202_4 +; RV32IA-NEXT: j .LBB202_5 +; RV32IA-NEXT: .LBB202_3: # in Loop: Header=BB202_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB202_5 +; RV32IA-NEXT: .LBB202_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB202_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB202_5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB202_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB202_7 +; RV32IA-NEXT: # %bb.6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB202_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB202_7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB202_1 Depth=1 +; RV32IA-NEXT: sw a1, 4(sp) +; RV32IA-NEXT: mv a0, s3 +; RV32IA-NEXT: mv a1, s4 +; RV32IA-NEXT: mv a4, s5 +; RV32IA-NEXT: mv a5, zero +; RV32IA-NEXT: call __atomic_compare_exchange_8 +; RV32IA-NEXT: lw a1, 4(sp) +; RV32IA-NEXT: lw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB202_1 +; RV32IA-NEXT: # %bb.8: # %atomicrmw.end +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: lw s5, 8(sp) +; RV32IA-NEXT: lw s4, 12(sp) +; RV32IA-NEXT: lw s3, 16(sp) +; RV32IA-NEXT: lw s2, 20(sp) +; RV32IA-NEXT: lw s1, 24(sp) +; RV32IA-NEXT: lw ra, 28(sp) +; RV32IA-NEXT: addi sp, sp, 32 +; RV32IA-NEXT: ret %1 = atomicrmw max i64* %a, i64 %b release ret i64 %1 } @@ -5078,6 +8290,70 @@ ; RV32I-NEXT: lw ra, 44(sp) ; RV32I-NEXT: addi sp, sp, 48 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_max_i64_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -48 +; RV32IA-NEXT: sw ra, 44(sp) +; RV32IA-NEXT: sw s1, 40(sp) +; RV32IA-NEXT: sw s2, 36(sp) +; RV32IA-NEXT: sw s3, 32(sp) +; RV32IA-NEXT: sw s4, 28(sp) +; RV32IA-NEXT: sw s5, 24(sp) +; RV32IA-NEXT: sw s6, 20(sp) +; RV32IA-NEXT: mv s1, a2 +; RV32IA-NEXT: mv s2, a1 +; RV32IA-NEXT: mv s3, a0 +; RV32IA-NEXT: lw a1, 4(a0) +; RV32IA-NEXT: lw a2, 0(a0) +; RV32IA-NEXT: addi s4, sp, 8 +; RV32IA-NEXT: addi s5, zero, 4 +; RV32IA-NEXT: addi s6, zero, 2 +; RV32IA-NEXT: .LBB203_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB203_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB203_1 Depth=1 +; RV32IA-NEXT: slt a0, s1, a1 +; RV32IA-NEXT: sw a2, 8(sp) +; RV32IA-NEXT: beqz a0, .LBB203_4 +; RV32IA-NEXT: j .LBB203_5 +; RV32IA-NEXT: .LBB203_3: # in Loop: Header=BB203_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: sw a2, 8(sp) +; RV32IA-NEXT: bnez a0, .LBB203_5 +; RV32IA-NEXT: .LBB203_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB203_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB203_5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB203_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB203_7 +; RV32IA-NEXT: # %bb.6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB203_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB203_7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB203_1 Depth=1 +; RV32IA-NEXT: sw a1, 12(sp) +; RV32IA-NEXT: mv a0, s3 +; RV32IA-NEXT: mv a1, s4 +; RV32IA-NEXT: mv a4, s5 +; RV32IA-NEXT: mv a5, s6 +; RV32IA-NEXT: call __atomic_compare_exchange_8 +; RV32IA-NEXT: lw a1, 12(sp) +; RV32IA-NEXT: lw a2, 8(sp) +; RV32IA-NEXT: beqz a0, .LBB203_1 +; RV32IA-NEXT: # %bb.8: # %atomicrmw.end +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: lw s6, 20(sp) +; RV32IA-NEXT: lw s5, 24(sp) +; RV32IA-NEXT: lw s4, 28(sp) +; RV32IA-NEXT: lw s3, 32(sp) +; RV32IA-NEXT: lw s2, 36(sp) +; RV32IA-NEXT: lw s1, 40(sp) +; RV32IA-NEXT: lw ra, 44(sp) +; RV32IA-NEXT: addi sp, sp, 48 +; RV32IA-NEXT: ret %1 = atomicrmw max i64* %a, i64 %b acq_rel ret i64 %1 } @@ -5143,6 +8419,67 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_max_i64_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -32 +; RV32IA-NEXT: sw ra, 28(sp) +; RV32IA-NEXT: sw s1, 24(sp) +; RV32IA-NEXT: sw s2, 20(sp) +; RV32IA-NEXT: sw s3, 16(sp) +; RV32IA-NEXT: sw s4, 12(sp) +; RV32IA-NEXT: sw s5, 8(sp) +; RV32IA-NEXT: mv s1, a2 +; RV32IA-NEXT: mv s2, a1 +; RV32IA-NEXT: mv s3, a0 +; RV32IA-NEXT: lw a1, 4(a0) +; RV32IA-NEXT: lw a2, 0(a0) +; RV32IA-NEXT: mv s4, sp +; RV32IA-NEXT: addi s5, zero, 5 +; RV32IA-NEXT: .LBB204_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB204_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB204_1 Depth=1 +; RV32IA-NEXT: slt a0, s1, a1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB204_4 +; RV32IA-NEXT: j .LBB204_5 +; RV32IA-NEXT: .LBB204_3: # in Loop: Header=BB204_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB204_5 +; RV32IA-NEXT: .LBB204_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB204_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB204_5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB204_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB204_7 +; RV32IA-NEXT: # %bb.6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB204_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB204_7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB204_1 Depth=1 +; RV32IA-NEXT: sw a1, 4(sp) +; RV32IA-NEXT: mv a0, s3 +; RV32IA-NEXT: mv a1, s4 +; RV32IA-NEXT: mv a4, s5 +; RV32IA-NEXT: mv a5, s5 +; RV32IA-NEXT: call __atomic_compare_exchange_8 +; RV32IA-NEXT: lw a1, 4(sp) +; RV32IA-NEXT: lw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB204_1 +; RV32IA-NEXT: # %bb.8: # %atomicrmw.end +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: lw s5, 8(sp) +; RV32IA-NEXT: lw s4, 12(sp) +; RV32IA-NEXT: lw s3, 16(sp) +; RV32IA-NEXT: lw s2, 20(sp) +; RV32IA-NEXT: lw s1, 24(sp) +; RV32IA-NEXT: lw ra, 28(sp) +; RV32IA-NEXT: addi sp, sp, 32 +; RV32IA-NEXT: ret %1 = atomicrmw max i64* %a, i64 %b seq_cst ret i64 %1 } @@ -5206,6 +8543,65 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_min_i64_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -32 +; RV32IA-NEXT: sw ra, 28(sp) +; RV32IA-NEXT: sw s1, 24(sp) +; RV32IA-NEXT: sw s2, 20(sp) +; RV32IA-NEXT: sw s3, 16(sp) +; RV32IA-NEXT: sw s4, 12(sp) +; RV32IA-NEXT: mv s1, a2 +; RV32IA-NEXT: mv s2, a1 +; RV32IA-NEXT: mv s3, a0 +; RV32IA-NEXT: lw a1, 4(a0) +; RV32IA-NEXT: lw a2, 0(a0) +; RV32IA-NEXT: mv s4, sp +; RV32IA-NEXT: .LBB205_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB205_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB205_1 Depth=1 +; RV32IA-NEXT: slt a0, s1, a1 +; RV32IA-NEXT: j .LBB205_4 +; RV32IA-NEXT: .LBB205_3: # in Loop: Header=BB205_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: .LBB205_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB205_1 Depth=1 +; RV32IA-NEXT: xori a0, a0, 1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB205_6 +; RV32IA-NEXT: # %bb.5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB205_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB205_6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB205_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB205_8 +; RV32IA-NEXT: # %bb.7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB205_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB205_8: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB205_1 Depth=1 +; RV32IA-NEXT: sw a1, 4(sp) +; RV32IA-NEXT: mv a0, s3 +; RV32IA-NEXT: mv a1, s4 +; RV32IA-NEXT: mv a4, zero +; RV32IA-NEXT: mv a5, zero +; RV32IA-NEXT: call __atomic_compare_exchange_8 +; RV32IA-NEXT: lw a1, 4(sp) +; RV32IA-NEXT: lw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB205_1 +; RV32IA-NEXT: # %bb.9: # %atomicrmw.end +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: lw s4, 12(sp) +; RV32IA-NEXT: lw s3, 16(sp) +; RV32IA-NEXT: lw s2, 20(sp) +; RV32IA-NEXT: lw s1, 24(sp) +; RV32IA-NEXT: lw ra, 28(sp) +; RV32IA-NEXT: addi sp, sp, 32 +; RV32IA-NEXT: ret %1 = atomicrmw min i64* %a, i64 %b monotonic ret i64 %1 } @@ -5272,6 +8668,68 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_min_i64_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -32 +; RV32IA-NEXT: sw ra, 28(sp) +; RV32IA-NEXT: sw s1, 24(sp) +; RV32IA-NEXT: sw s2, 20(sp) +; RV32IA-NEXT: sw s3, 16(sp) +; RV32IA-NEXT: sw s4, 12(sp) +; RV32IA-NEXT: sw s5, 8(sp) +; RV32IA-NEXT: mv s1, a2 +; RV32IA-NEXT: mv s2, a1 +; RV32IA-NEXT: mv s3, a0 +; RV32IA-NEXT: lw a1, 4(a0) +; RV32IA-NEXT: lw a2, 0(a0) +; RV32IA-NEXT: mv s4, sp +; RV32IA-NEXT: addi s5, zero, 2 +; RV32IA-NEXT: .LBB206_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB206_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB206_1 Depth=1 +; RV32IA-NEXT: slt a0, s1, a1 +; RV32IA-NEXT: j .LBB206_4 +; RV32IA-NEXT: .LBB206_3: # in Loop: Header=BB206_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: .LBB206_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB206_1 Depth=1 +; RV32IA-NEXT: xori a0, a0, 1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB206_6 +; RV32IA-NEXT: # %bb.5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB206_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB206_6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB206_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB206_8 +; RV32IA-NEXT: # %bb.7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB206_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB206_8: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB206_1 Depth=1 +; RV32IA-NEXT: sw a1, 4(sp) +; RV32IA-NEXT: mv a0, s3 +; RV32IA-NEXT: mv a1, s4 +; RV32IA-NEXT: mv a4, s5 +; RV32IA-NEXT: mv a5, s5 +; RV32IA-NEXT: call __atomic_compare_exchange_8 +; RV32IA-NEXT: lw a1, 4(sp) +; RV32IA-NEXT: lw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB206_1 +; RV32IA-NEXT: # %bb.9: # %atomicrmw.end +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: lw s5, 8(sp) +; RV32IA-NEXT: lw s4, 12(sp) +; RV32IA-NEXT: lw s3, 16(sp) +; RV32IA-NEXT: lw s2, 20(sp) +; RV32IA-NEXT: lw s1, 24(sp) +; RV32IA-NEXT: lw ra, 28(sp) +; RV32IA-NEXT: addi sp, sp, 32 +; RV32IA-NEXT: ret %1 = atomicrmw min i64* %a, i64 %b acquire ret i64 %1 } @@ -5338,6 +8796,68 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_min_i64_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -32 +; RV32IA-NEXT: sw ra, 28(sp) +; RV32IA-NEXT: sw s1, 24(sp) +; RV32IA-NEXT: sw s2, 20(sp) +; RV32IA-NEXT: sw s3, 16(sp) +; RV32IA-NEXT: sw s4, 12(sp) +; RV32IA-NEXT: sw s5, 8(sp) +; RV32IA-NEXT: mv s1, a2 +; RV32IA-NEXT: mv s2, a1 +; RV32IA-NEXT: mv s3, a0 +; RV32IA-NEXT: lw a1, 4(a0) +; RV32IA-NEXT: lw a2, 0(a0) +; RV32IA-NEXT: mv s4, sp +; RV32IA-NEXT: addi s5, zero, 3 +; RV32IA-NEXT: .LBB207_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB207_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB207_1 Depth=1 +; RV32IA-NEXT: slt a0, s1, a1 +; RV32IA-NEXT: j .LBB207_4 +; RV32IA-NEXT: .LBB207_3: # in Loop: Header=BB207_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: .LBB207_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB207_1 Depth=1 +; RV32IA-NEXT: xori a0, a0, 1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB207_6 +; RV32IA-NEXT: # %bb.5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB207_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB207_6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB207_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB207_8 +; RV32IA-NEXT: # %bb.7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB207_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB207_8: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB207_1 Depth=1 +; RV32IA-NEXT: sw a1, 4(sp) +; RV32IA-NEXT: mv a0, s3 +; RV32IA-NEXT: mv a1, s4 +; RV32IA-NEXT: mv a4, s5 +; RV32IA-NEXT: mv a5, zero +; RV32IA-NEXT: call __atomic_compare_exchange_8 +; RV32IA-NEXT: lw a1, 4(sp) +; RV32IA-NEXT: lw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB207_1 +; RV32IA-NEXT: # %bb.9: # %atomicrmw.end +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: lw s5, 8(sp) +; RV32IA-NEXT: lw s4, 12(sp) +; RV32IA-NEXT: lw s3, 16(sp) +; RV32IA-NEXT: lw s2, 20(sp) +; RV32IA-NEXT: lw s1, 24(sp) +; RV32IA-NEXT: lw ra, 28(sp) +; RV32IA-NEXT: addi sp, sp, 32 +; RV32IA-NEXT: ret %1 = atomicrmw min i64* %a, i64 %b release ret i64 %1 } @@ -5407,6 +8927,71 @@ ; RV32I-NEXT: lw ra, 44(sp) ; RV32I-NEXT: addi sp, sp, 48 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_min_i64_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -48 +; RV32IA-NEXT: sw ra, 44(sp) +; RV32IA-NEXT: sw s1, 40(sp) +; RV32IA-NEXT: sw s2, 36(sp) +; RV32IA-NEXT: sw s3, 32(sp) +; RV32IA-NEXT: sw s4, 28(sp) +; RV32IA-NEXT: sw s5, 24(sp) +; RV32IA-NEXT: sw s6, 20(sp) +; RV32IA-NEXT: mv s1, a2 +; RV32IA-NEXT: mv s2, a1 +; RV32IA-NEXT: mv s3, a0 +; RV32IA-NEXT: lw a1, 4(a0) +; RV32IA-NEXT: lw a2, 0(a0) +; RV32IA-NEXT: addi s4, sp, 8 +; RV32IA-NEXT: addi s5, zero, 4 +; RV32IA-NEXT: addi s6, zero, 2 +; RV32IA-NEXT: .LBB208_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB208_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB208_1 Depth=1 +; RV32IA-NEXT: slt a0, s1, a1 +; RV32IA-NEXT: j .LBB208_4 +; RV32IA-NEXT: .LBB208_3: # in Loop: Header=BB208_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: .LBB208_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB208_1 Depth=1 +; RV32IA-NEXT: xori a0, a0, 1 +; RV32IA-NEXT: sw a2, 8(sp) +; RV32IA-NEXT: bnez a0, .LBB208_6 +; RV32IA-NEXT: # %bb.5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB208_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB208_6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB208_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB208_8 +; RV32IA-NEXT: # %bb.7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB208_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB208_8: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB208_1 Depth=1 +; RV32IA-NEXT: sw a1, 12(sp) +; RV32IA-NEXT: mv a0, s3 +; RV32IA-NEXT: mv a1, s4 +; RV32IA-NEXT: mv a4, s5 +; RV32IA-NEXT: mv a5, s6 +; RV32IA-NEXT: call __atomic_compare_exchange_8 +; RV32IA-NEXT: lw a1, 12(sp) +; RV32IA-NEXT: lw a2, 8(sp) +; RV32IA-NEXT: beqz a0, .LBB208_1 +; RV32IA-NEXT: # %bb.9: # %atomicrmw.end +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: lw s6, 20(sp) +; RV32IA-NEXT: lw s5, 24(sp) +; RV32IA-NEXT: lw s4, 28(sp) +; RV32IA-NEXT: lw s3, 32(sp) +; RV32IA-NEXT: lw s2, 36(sp) +; RV32IA-NEXT: lw s1, 40(sp) +; RV32IA-NEXT: lw ra, 44(sp) +; RV32IA-NEXT: addi sp, sp, 48 +; RV32IA-NEXT: ret %1 = atomicrmw min i64* %a, i64 %b acq_rel ret i64 %1 } @@ -5473,6 +9058,68 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_min_i64_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -32 +; RV32IA-NEXT: sw ra, 28(sp) +; RV32IA-NEXT: sw s1, 24(sp) +; RV32IA-NEXT: sw s2, 20(sp) +; RV32IA-NEXT: sw s3, 16(sp) +; RV32IA-NEXT: sw s4, 12(sp) +; RV32IA-NEXT: sw s5, 8(sp) +; RV32IA-NEXT: mv s1, a2 +; RV32IA-NEXT: mv s2, a1 +; RV32IA-NEXT: mv s3, a0 +; RV32IA-NEXT: lw a1, 4(a0) +; RV32IA-NEXT: lw a2, 0(a0) +; RV32IA-NEXT: mv s4, sp +; RV32IA-NEXT: addi s5, zero, 5 +; RV32IA-NEXT: .LBB209_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB209_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB209_1 Depth=1 +; RV32IA-NEXT: slt a0, s1, a1 +; RV32IA-NEXT: j .LBB209_4 +; RV32IA-NEXT: .LBB209_3: # in Loop: Header=BB209_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: .LBB209_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB209_1 Depth=1 +; RV32IA-NEXT: xori a0, a0, 1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB209_6 +; RV32IA-NEXT: # %bb.5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB209_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB209_6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB209_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB209_8 +; RV32IA-NEXT: # %bb.7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB209_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB209_8: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB209_1 Depth=1 +; RV32IA-NEXT: sw a1, 4(sp) +; RV32IA-NEXT: mv a0, s3 +; RV32IA-NEXT: mv a1, s4 +; RV32IA-NEXT: mv a4, s5 +; RV32IA-NEXT: mv a5, s5 +; RV32IA-NEXT: call __atomic_compare_exchange_8 +; RV32IA-NEXT: lw a1, 4(sp) +; RV32IA-NEXT: lw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB209_1 +; RV32IA-NEXT: # %bb.9: # %atomicrmw.end +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: lw s5, 8(sp) +; RV32IA-NEXT: lw s4, 12(sp) +; RV32IA-NEXT: lw s3, 16(sp) +; RV32IA-NEXT: lw s2, 20(sp) +; RV32IA-NEXT: lw s1, 24(sp) +; RV32IA-NEXT: lw ra, 28(sp) +; RV32IA-NEXT: addi sp, sp, 32 +; RV32IA-NEXT: ret %1 = atomicrmw min i64* %a, i64 %b seq_cst ret i64 %1 } @@ -5535,6 +9182,64 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umax_i64_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -32 +; RV32IA-NEXT: sw ra, 28(sp) +; RV32IA-NEXT: sw s1, 24(sp) +; RV32IA-NEXT: sw s2, 20(sp) +; RV32IA-NEXT: sw s3, 16(sp) +; RV32IA-NEXT: sw s4, 12(sp) +; RV32IA-NEXT: mv s1, a2 +; RV32IA-NEXT: mv s2, a1 +; RV32IA-NEXT: mv s3, a0 +; RV32IA-NEXT: lw a1, 4(a0) +; RV32IA-NEXT: lw a2, 0(a0) +; RV32IA-NEXT: mv s4, sp +; RV32IA-NEXT: .LBB210_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB210_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB210_1 Depth=1 +; RV32IA-NEXT: sltu a0, s1, a1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB210_4 +; RV32IA-NEXT: j .LBB210_5 +; RV32IA-NEXT: .LBB210_3: # in Loop: Header=BB210_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB210_5 +; RV32IA-NEXT: .LBB210_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB210_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB210_5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB210_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB210_7 +; RV32IA-NEXT: # %bb.6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB210_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB210_7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB210_1 Depth=1 +; RV32IA-NEXT: sw a1, 4(sp) +; RV32IA-NEXT: mv a0, s3 +; RV32IA-NEXT: mv a1, s4 +; RV32IA-NEXT: mv a4, zero +; RV32IA-NEXT: mv a5, zero +; RV32IA-NEXT: call __atomic_compare_exchange_8 +; RV32IA-NEXT: lw a1, 4(sp) +; RV32IA-NEXT: lw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB210_1 +; RV32IA-NEXT: # %bb.8: # %atomicrmw.end +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: lw s4, 12(sp) +; RV32IA-NEXT: lw s3, 16(sp) +; RV32IA-NEXT: lw s2, 20(sp) +; RV32IA-NEXT: lw s1, 24(sp) +; RV32IA-NEXT: lw ra, 28(sp) +; RV32IA-NEXT: addi sp, sp, 32 +; RV32IA-NEXT: ret %1 = atomicrmw umax i64* %a, i64 %b monotonic ret i64 %1 } @@ -5600,6 +9305,67 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umax_i64_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -32 +; RV32IA-NEXT: sw ra, 28(sp) +; RV32IA-NEXT: sw s1, 24(sp) +; RV32IA-NEXT: sw s2, 20(sp) +; RV32IA-NEXT: sw s3, 16(sp) +; RV32IA-NEXT: sw s4, 12(sp) +; RV32IA-NEXT: sw s5, 8(sp) +; RV32IA-NEXT: mv s1, a2 +; RV32IA-NEXT: mv s2, a1 +; RV32IA-NEXT: mv s3, a0 +; RV32IA-NEXT: lw a1, 4(a0) +; RV32IA-NEXT: lw a2, 0(a0) +; RV32IA-NEXT: mv s4, sp +; RV32IA-NEXT: addi s5, zero, 2 +; RV32IA-NEXT: .LBB211_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB211_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB211_1 Depth=1 +; RV32IA-NEXT: sltu a0, s1, a1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB211_4 +; RV32IA-NEXT: j .LBB211_5 +; RV32IA-NEXT: .LBB211_3: # in Loop: Header=BB211_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB211_5 +; RV32IA-NEXT: .LBB211_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB211_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB211_5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB211_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB211_7 +; RV32IA-NEXT: # %bb.6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB211_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB211_7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB211_1 Depth=1 +; RV32IA-NEXT: sw a1, 4(sp) +; RV32IA-NEXT: mv a0, s3 +; RV32IA-NEXT: mv a1, s4 +; RV32IA-NEXT: mv a4, s5 +; RV32IA-NEXT: mv a5, s5 +; RV32IA-NEXT: call __atomic_compare_exchange_8 +; RV32IA-NEXT: lw a1, 4(sp) +; RV32IA-NEXT: lw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB211_1 +; RV32IA-NEXT: # %bb.8: # %atomicrmw.end +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: lw s5, 8(sp) +; RV32IA-NEXT: lw s4, 12(sp) +; RV32IA-NEXT: lw s3, 16(sp) +; RV32IA-NEXT: lw s2, 20(sp) +; RV32IA-NEXT: lw s1, 24(sp) +; RV32IA-NEXT: lw ra, 28(sp) +; RV32IA-NEXT: addi sp, sp, 32 +; RV32IA-NEXT: ret %1 = atomicrmw umax i64* %a, i64 %b acquire ret i64 %1 } @@ -5665,6 +9431,67 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umax_i64_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -32 +; RV32IA-NEXT: sw ra, 28(sp) +; RV32IA-NEXT: sw s1, 24(sp) +; RV32IA-NEXT: sw s2, 20(sp) +; RV32IA-NEXT: sw s3, 16(sp) +; RV32IA-NEXT: sw s4, 12(sp) +; RV32IA-NEXT: sw s5, 8(sp) +; RV32IA-NEXT: mv s1, a2 +; RV32IA-NEXT: mv s2, a1 +; RV32IA-NEXT: mv s3, a0 +; RV32IA-NEXT: lw a1, 4(a0) +; RV32IA-NEXT: lw a2, 0(a0) +; RV32IA-NEXT: mv s4, sp +; RV32IA-NEXT: addi s5, zero, 3 +; RV32IA-NEXT: .LBB212_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB212_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB212_1 Depth=1 +; RV32IA-NEXT: sltu a0, s1, a1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB212_4 +; RV32IA-NEXT: j .LBB212_5 +; RV32IA-NEXT: .LBB212_3: # in Loop: Header=BB212_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB212_5 +; RV32IA-NEXT: .LBB212_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB212_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB212_5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB212_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB212_7 +; RV32IA-NEXT: # %bb.6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB212_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB212_7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB212_1 Depth=1 +; RV32IA-NEXT: sw a1, 4(sp) +; RV32IA-NEXT: mv a0, s3 +; RV32IA-NEXT: mv a1, s4 +; RV32IA-NEXT: mv a4, s5 +; RV32IA-NEXT: mv a5, zero +; RV32IA-NEXT: call __atomic_compare_exchange_8 +; RV32IA-NEXT: lw a1, 4(sp) +; RV32IA-NEXT: lw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB212_1 +; RV32IA-NEXT: # %bb.8: # %atomicrmw.end +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: lw s5, 8(sp) +; RV32IA-NEXT: lw s4, 12(sp) +; RV32IA-NEXT: lw s3, 16(sp) +; RV32IA-NEXT: lw s2, 20(sp) +; RV32IA-NEXT: lw s1, 24(sp) +; RV32IA-NEXT: lw ra, 28(sp) +; RV32IA-NEXT: addi sp, sp, 32 +; RV32IA-NEXT: ret %1 = atomicrmw umax i64* %a, i64 %b release ret i64 %1 } @@ -5733,6 +9560,70 @@ ; RV32I-NEXT: lw ra, 44(sp) ; RV32I-NEXT: addi sp, sp, 48 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umax_i64_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -48 +; RV32IA-NEXT: sw ra, 44(sp) +; RV32IA-NEXT: sw s1, 40(sp) +; RV32IA-NEXT: sw s2, 36(sp) +; RV32IA-NEXT: sw s3, 32(sp) +; RV32IA-NEXT: sw s4, 28(sp) +; RV32IA-NEXT: sw s5, 24(sp) +; RV32IA-NEXT: sw s6, 20(sp) +; RV32IA-NEXT: mv s1, a2 +; RV32IA-NEXT: mv s2, a1 +; RV32IA-NEXT: mv s3, a0 +; RV32IA-NEXT: lw a1, 4(a0) +; RV32IA-NEXT: lw a2, 0(a0) +; RV32IA-NEXT: addi s4, sp, 8 +; RV32IA-NEXT: addi s5, zero, 4 +; RV32IA-NEXT: addi s6, zero, 2 +; RV32IA-NEXT: .LBB213_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB213_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB213_1 Depth=1 +; RV32IA-NEXT: sltu a0, s1, a1 +; RV32IA-NEXT: sw a2, 8(sp) +; RV32IA-NEXT: beqz a0, .LBB213_4 +; RV32IA-NEXT: j .LBB213_5 +; RV32IA-NEXT: .LBB213_3: # in Loop: Header=BB213_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: sw a2, 8(sp) +; RV32IA-NEXT: bnez a0, .LBB213_5 +; RV32IA-NEXT: .LBB213_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB213_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB213_5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB213_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB213_7 +; RV32IA-NEXT: # %bb.6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB213_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB213_7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB213_1 Depth=1 +; RV32IA-NEXT: sw a1, 12(sp) +; RV32IA-NEXT: mv a0, s3 +; RV32IA-NEXT: mv a1, s4 +; RV32IA-NEXT: mv a4, s5 +; RV32IA-NEXT: mv a5, s6 +; RV32IA-NEXT: call __atomic_compare_exchange_8 +; RV32IA-NEXT: lw a1, 12(sp) +; RV32IA-NEXT: lw a2, 8(sp) +; RV32IA-NEXT: beqz a0, .LBB213_1 +; RV32IA-NEXT: # %bb.8: # %atomicrmw.end +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: lw s6, 20(sp) +; RV32IA-NEXT: lw s5, 24(sp) +; RV32IA-NEXT: lw s4, 28(sp) +; RV32IA-NEXT: lw s3, 32(sp) +; RV32IA-NEXT: lw s2, 36(sp) +; RV32IA-NEXT: lw s1, 40(sp) +; RV32IA-NEXT: lw ra, 44(sp) +; RV32IA-NEXT: addi sp, sp, 48 +; RV32IA-NEXT: ret %1 = atomicrmw umax i64* %a, i64 %b acq_rel ret i64 %1 } @@ -5798,6 +9689,67 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umax_i64_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -32 +; RV32IA-NEXT: sw ra, 28(sp) +; RV32IA-NEXT: sw s1, 24(sp) +; RV32IA-NEXT: sw s2, 20(sp) +; RV32IA-NEXT: sw s3, 16(sp) +; RV32IA-NEXT: sw s4, 12(sp) +; RV32IA-NEXT: sw s5, 8(sp) +; RV32IA-NEXT: mv s1, a2 +; RV32IA-NEXT: mv s2, a1 +; RV32IA-NEXT: mv s3, a0 +; RV32IA-NEXT: lw a1, 4(a0) +; RV32IA-NEXT: lw a2, 0(a0) +; RV32IA-NEXT: mv s4, sp +; RV32IA-NEXT: addi s5, zero, 5 +; RV32IA-NEXT: .LBB214_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB214_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB214_1 Depth=1 +; RV32IA-NEXT: sltu a0, s1, a1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB214_4 +; RV32IA-NEXT: j .LBB214_5 +; RV32IA-NEXT: .LBB214_3: # in Loop: Header=BB214_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB214_5 +; RV32IA-NEXT: .LBB214_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB214_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB214_5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB214_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB214_7 +; RV32IA-NEXT: # %bb.6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB214_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB214_7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB214_1 Depth=1 +; RV32IA-NEXT: sw a1, 4(sp) +; RV32IA-NEXT: mv a0, s3 +; RV32IA-NEXT: mv a1, s4 +; RV32IA-NEXT: mv a4, s5 +; RV32IA-NEXT: mv a5, s5 +; RV32IA-NEXT: call __atomic_compare_exchange_8 +; RV32IA-NEXT: lw a1, 4(sp) +; RV32IA-NEXT: lw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB214_1 +; RV32IA-NEXT: # %bb.8: # %atomicrmw.end +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: lw s5, 8(sp) +; RV32IA-NEXT: lw s4, 12(sp) +; RV32IA-NEXT: lw s3, 16(sp) +; RV32IA-NEXT: lw s2, 20(sp) +; RV32IA-NEXT: lw s1, 24(sp) +; RV32IA-NEXT: lw ra, 28(sp) +; RV32IA-NEXT: addi sp, sp, 32 +; RV32IA-NEXT: ret %1 = atomicrmw umax i64* %a, i64 %b seq_cst ret i64 %1 } @@ -5861,6 +9813,65 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umin_i64_monotonic: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -32 +; RV32IA-NEXT: sw ra, 28(sp) +; RV32IA-NEXT: sw s1, 24(sp) +; RV32IA-NEXT: sw s2, 20(sp) +; RV32IA-NEXT: sw s3, 16(sp) +; RV32IA-NEXT: sw s4, 12(sp) +; RV32IA-NEXT: mv s1, a2 +; RV32IA-NEXT: mv s2, a1 +; RV32IA-NEXT: mv s3, a0 +; RV32IA-NEXT: lw a1, 4(a0) +; RV32IA-NEXT: lw a2, 0(a0) +; RV32IA-NEXT: mv s4, sp +; RV32IA-NEXT: .LBB215_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB215_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB215_1 Depth=1 +; RV32IA-NEXT: sltu a0, s1, a1 +; RV32IA-NEXT: j .LBB215_4 +; RV32IA-NEXT: .LBB215_3: # in Loop: Header=BB215_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: .LBB215_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB215_1 Depth=1 +; RV32IA-NEXT: xori a0, a0, 1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB215_6 +; RV32IA-NEXT: # %bb.5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB215_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB215_6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB215_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB215_8 +; RV32IA-NEXT: # %bb.7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB215_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB215_8: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB215_1 Depth=1 +; RV32IA-NEXT: sw a1, 4(sp) +; RV32IA-NEXT: mv a0, s3 +; RV32IA-NEXT: mv a1, s4 +; RV32IA-NEXT: mv a4, zero +; RV32IA-NEXT: mv a5, zero +; RV32IA-NEXT: call __atomic_compare_exchange_8 +; RV32IA-NEXT: lw a1, 4(sp) +; RV32IA-NEXT: lw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB215_1 +; RV32IA-NEXT: # %bb.9: # %atomicrmw.end +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: lw s4, 12(sp) +; RV32IA-NEXT: lw s3, 16(sp) +; RV32IA-NEXT: lw s2, 20(sp) +; RV32IA-NEXT: lw s1, 24(sp) +; RV32IA-NEXT: lw ra, 28(sp) +; RV32IA-NEXT: addi sp, sp, 32 +; RV32IA-NEXT: ret %1 = atomicrmw umin i64* %a, i64 %b monotonic ret i64 %1 } @@ -5927,6 +9938,68 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umin_i64_acquire: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -32 +; RV32IA-NEXT: sw ra, 28(sp) +; RV32IA-NEXT: sw s1, 24(sp) +; RV32IA-NEXT: sw s2, 20(sp) +; RV32IA-NEXT: sw s3, 16(sp) +; RV32IA-NEXT: sw s4, 12(sp) +; RV32IA-NEXT: sw s5, 8(sp) +; RV32IA-NEXT: mv s1, a2 +; RV32IA-NEXT: mv s2, a1 +; RV32IA-NEXT: mv s3, a0 +; RV32IA-NEXT: lw a1, 4(a0) +; RV32IA-NEXT: lw a2, 0(a0) +; RV32IA-NEXT: mv s4, sp +; RV32IA-NEXT: addi s5, zero, 2 +; RV32IA-NEXT: .LBB216_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB216_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB216_1 Depth=1 +; RV32IA-NEXT: sltu a0, s1, a1 +; RV32IA-NEXT: j .LBB216_4 +; RV32IA-NEXT: .LBB216_3: # in Loop: Header=BB216_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: .LBB216_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB216_1 Depth=1 +; RV32IA-NEXT: xori a0, a0, 1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB216_6 +; RV32IA-NEXT: # %bb.5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB216_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB216_6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB216_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB216_8 +; RV32IA-NEXT: # %bb.7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB216_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB216_8: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB216_1 Depth=1 +; RV32IA-NEXT: sw a1, 4(sp) +; RV32IA-NEXT: mv a0, s3 +; RV32IA-NEXT: mv a1, s4 +; RV32IA-NEXT: mv a4, s5 +; RV32IA-NEXT: mv a5, s5 +; RV32IA-NEXT: call __atomic_compare_exchange_8 +; RV32IA-NEXT: lw a1, 4(sp) +; RV32IA-NEXT: lw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB216_1 +; RV32IA-NEXT: # %bb.9: # %atomicrmw.end +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: lw s5, 8(sp) +; RV32IA-NEXT: lw s4, 12(sp) +; RV32IA-NEXT: lw s3, 16(sp) +; RV32IA-NEXT: lw s2, 20(sp) +; RV32IA-NEXT: lw s1, 24(sp) +; RV32IA-NEXT: lw ra, 28(sp) +; RV32IA-NEXT: addi sp, sp, 32 +; RV32IA-NEXT: ret %1 = atomicrmw umin i64* %a, i64 %b acquire ret i64 %1 } @@ -5993,6 +10066,68 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umin_i64_release: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -32 +; RV32IA-NEXT: sw ra, 28(sp) +; RV32IA-NEXT: sw s1, 24(sp) +; RV32IA-NEXT: sw s2, 20(sp) +; RV32IA-NEXT: sw s3, 16(sp) +; RV32IA-NEXT: sw s4, 12(sp) +; RV32IA-NEXT: sw s5, 8(sp) +; RV32IA-NEXT: mv s1, a2 +; RV32IA-NEXT: mv s2, a1 +; RV32IA-NEXT: mv s3, a0 +; RV32IA-NEXT: lw a1, 4(a0) +; RV32IA-NEXT: lw a2, 0(a0) +; RV32IA-NEXT: mv s4, sp +; RV32IA-NEXT: addi s5, zero, 3 +; RV32IA-NEXT: .LBB217_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB217_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB217_1 Depth=1 +; RV32IA-NEXT: sltu a0, s1, a1 +; RV32IA-NEXT: j .LBB217_4 +; RV32IA-NEXT: .LBB217_3: # in Loop: Header=BB217_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: .LBB217_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB217_1 Depth=1 +; RV32IA-NEXT: xori a0, a0, 1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB217_6 +; RV32IA-NEXT: # %bb.5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB217_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB217_6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB217_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB217_8 +; RV32IA-NEXT: # %bb.7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB217_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB217_8: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB217_1 Depth=1 +; RV32IA-NEXT: sw a1, 4(sp) +; RV32IA-NEXT: mv a0, s3 +; RV32IA-NEXT: mv a1, s4 +; RV32IA-NEXT: mv a4, s5 +; RV32IA-NEXT: mv a5, zero +; RV32IA-NEXT: call __atomic_compare_exchange_8 +; RV32IA-NEXT: lw a1, 4(sp) +; RV32IA-NEXT: lw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB217_1 +; RV32IA-NEXT: # %bb.9: # %atomicrmw.end +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: lw s5, 8(sp) +; RV32IA-NEXT: lw s4, 12(sp) +; RV32IA-NEXT: lw s3, 16(sp) +; RV32IA-NEXT: lw s2, 20(sp) +; RV32IA-NEXT: lw s1, 24(sp) +; RV32IA-NEXT: lw ra, 28(sp) +; RV32IA-NEXT: addi sp, sp, 32 +; RV32IA-NEXT: ret %1 = atomicrmw umin i64* %a, i64 %b release ret i64 %1 } @@ -6062,6 +10197,71 @@ ; RV32I-NEXT: lw ra, 44(sp) ; RV32I-NEXT: addi sp, sp, 48 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umin_i64_acq_rel: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -48 +; RV32IA-NEXT: sw ra, 44(sp) +; RV32IA-NEXT: sw s1, 40(sp) +; RV32IA-NEXT: sw s2, 36(sp) +; RV32IA-NEXT: sw s3, 32(sp) +; RV32IA-NEXT: sw s4, 28(sp) +; RV32IA-NEXT: sw s5, 24(sp) +; RV32IA-NEXT: sw s6, 20(sp) +; RV32IA-NEXT: mv s1, a2 +; RV32IA-NEXT: mv s2, a1 +; RV32IA-NEXT: mv s3, a0 +; RV32IA-NEXT: lw a1, 4(a0) +; RV32IA-NEXT: lw a2, 0(a0) +; RV32IA-NEXT: addi s4, sp, 8 +; RV32IA-NEXT: addi s5, zero, 4 +; RV32IA-NEXT: addi s6, zero, 2 +; RV32IA-NEXT: .LBB218_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB218_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB218_1 Depth=1 +; RV32IA-NEXT: sltu a0, s1, a1 +; RV32IA-NEXT: j .LBB218_4 +; RV32IA-NEXT: .LBB218_3: # in Loop: Header=BB218_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: .LBB218_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB218_1 Depth=1 +; RV32IA-NEXT: xori a0, a0, 1 +; RV32IA-NEXT: sw a2, 8(sp) +; RV32IA-NEXT: bnez a0, .LBB218_6 +; RV32IA-NEXT: # %bb.5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB218_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB218_6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB218_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB218_8 +; RV32IA-NEXT: # %bb.7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB218_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB218_8: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB218_1 Depth=1 +; RV32IA-NEXT: sw a1, 12(sp) +; RV32IA-NEXT: mv a0, s3 +; RV32IA-NEXT: mv a1, s4 +; RV32IA-NEXT: mv a4, s5 +; RV32IA-NEXT: mv a5, s6 +; RV32IA-NEXT: call __atomic_compare_exchange_8 +; RV32IA-NEXT: lw a1, 12(sp) +; RV32IA-NEXT: lw a2, 8(sp) +; RV32IA-NEXT: beqz a0, .LBB218_1 +; RV32IA-NEXT: # %bb.9: # %atomicrmw.end +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: lw s6, 20(sp) +; RV32IA-NEXT: lw s5, 24(sp) +; RV32IA-NEXT: lw s4, 28(sp) +; RV32IA-NEXT: lw s3, 32(sp) +; RV32IA-NEXT: lw s2, 36(sp) +; RV32IA-NEXT: lw s1, 40(sp) +; RV32IA-NEXT: lw ra, 44(sp) +; RV32IA-NEXT: addi sp, sp, 48 +; RV32IA-NEXT: ret %1 = atomicrmw umin i64* %a, i64 %b acq_rel ret i64 %1 } @@ -6128,6 +10328,68 @@ ; RV32I-NEXT: lw ra, 28(sp) ; RV32I-NEXT: addi sp, sp, 32 ; RV32I-NEXT: ret +; +; RV32IA-LABEL: atomicrmw_umin_i64_seq_cst: +; RV32IA: # %bb.0: +; RV32IA-NEXT: addi sp, sp, -32 +; RV32IA-NEXT: sw ra, 28(sp) +; RV32IA-NEXT: sw s1, 24(sp) +; RV32IA-NEXT: sw s2, 20(sp) +; RV32IA-NEXT: sw s3, 16(sp) +; RV32IA-NEXT: sw s4, 12(sp) +; RV32IA-NEXT: sw s5, 8(sp) +; RV32IA-NEXT: mv s1, a2 +; RV32IA-NEXT: mv s2, a1 +; RV32IA-NEXT: mv s3, a0 +; RV32IA-NEXT: lw a1, 4(a0) +; RV32IA-NEXT: lw a2, 0(a0) +; RV32IA-NEXT: mv s4, sp +; RV32IA-NEXT: addi s5, zero, 5 +; RV32IA-NEXT: .LBB219_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB219_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB219_1 Depth=1 +; RV32IA-NEXT: sltu a0, s1, a1 +; RV32IA-NEXT: j .LBB219_4 +; RV32IA-NEXT: .LBB219_3: # in Loop: Header=BB219_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: .LBB219_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB219_1 Depth=1 +; RV32IA-NEXT: xori a0, a0, 1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB219_6 +; RV32IA-NEXT: # %bb.5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB219_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB219_6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB219_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB219_8 +; RV32IA-NEXT: # %bb.7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB219_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB219_8: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB219_1 Depth=1 +; RV32IA-NEXT: sw a1, 4(sp) +; RV32IA-NEXT: mv a0, s3 +; RV32IA-NEXT: mv a1, s4 +; RV32IA-NEXT: mv a4, s5 +; RV32IA-NEXT: mv a5, s5 +; RV32IA-NEXT: call __atomic_compare_exchange_8 +; RV32IA-NEXT: lw a1, 4(sp) +; RV32IA-NEXT: lw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB219_1 +; RV32IA-NEXT: # %bb.9: # %atomicrmw.end +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: lw s5, 8(sp) +; RV32IA-NEXT: lw s4, 12(sp) +; RV32IA-NEXT: lw s3, 16(sp) +; RV32IA-NEXT: lw s2, 20(sp) +; RV32IA-NEXT: lw s1, 24(sp) +; RV32IA-NEXT: lw ra, 28(sp) +; RV32IA-NEXT: addi sp, sp, 32 +; RV32IA-NEXT: ret %1 = atomicrmw umin i64* %a, i64 %b seq_cst ret i64 %1 }