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; @@ -32,6 +33,9 @@ MCOperand &MCOp, const AsmPrinter &AP); FunctionPass *createRISCVISelDag(RISCVTargetMachine &TM); +FunctionPass *createRISCVExpandPseudoPass(); + +void initializeRISCVExpandPseudoPass(PassRegistry &); } #endif Index: lib/Target/RISCV/RISCVExpandPseudoInsts.cpp =================================================================== --- /dev/null +++ lib/Target/RISCV/RISCVExpandPseudoInsts.cpp @@ -0,0 +1,407 @@ +//===-- 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, + 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::PseudoAtomicSwap8: + return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Xchg, 8, NextMBBI); + case RISCV::PseudoAtomicLoadAdd8: + return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Add, 8, NextMBBI); + case RISCV::PseudoAtomicLoadSub8: + return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Sub, 8, NextMBBI); + case RISCV::PseudoAtomicLoadAnd8: + return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::And, 8, NextMBBI); + case RISCV::PseudoAtomicLoadNand8: + return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Nand, 8, NextMBBI); + case RISCV::PseudoAtomicLoadOr8: + return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Or, 8, NextMBBI); + case RISCV::PseudoAtomicLoadXor8: + return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Xor, 8, NextMBBI); + case RISCV::PseudoAtomicSwap16: + return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Xchg, 16, NextMBBI); + case RISCV::PseudoAtomicLoadAdd16: + return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Add, 16, NextMBBI); + case RISCV::PseudoAtomicLoadSub16: + return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Sub, 16, NextMBBI); + case RISCV::PseudoAtomicLoadAnd16: + return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::And, 16, NextMBBI); + case RISCV::PseudoAtomicLoadNand16: + return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Nand, 16, NextMBBI); + case RISCV::PseudoAtomicLoadOr16: + return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Or, 16, NextMBBI); + case RISCV::PseudoAtomicLoadXor16: + return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Xor, 16, NextMBBI); + case RISCV::PseudoAtomicLoadSub32: + return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Sub, 32, NextMBBI); + case RISCV::PseudoAtomicLoadNand32: + return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Nand, 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 doPartWordAtomicBinOpExpansion( + const RISCVInstrInfo *TII, MachineInstr &MI, DebugLoc DL, + MachineBasicBlock *ThisMBB, MachineBasicBlock *LoopMBB, + MachineBasicBlock *DoneMBB, AtomicRMWInst::BinOp BinOp, int Width) { + assert((Width == 8 || Width == 16) && "Unexpected atomic width"); + + unsigned DestReg = MI.getOperand(0).getReg(); + unsigned Scratch1Reg = MI.getOperand(1).getReg(); + unsigned Scratch2Reg = MI.getOperand(2).getReg(); + unsigned Scratch3Reg = MI.getOperand(3).getReg(); + unsigned Scratch4Reg = MI.getOperand(4).getReg(); + unsigned Scratch5Reg = MI.getOperand(5).getReg(); + unsigned AddrReg = MI.getOperand(6).getReg(); + unsigned IncrReg = MI.getOperand(7).getReg(); + AtomicOrdering Ordering = (AtomicOrdering)MI.getOperand(8).getImm(); + + assert(Scratch1Reg == AddrReg && "AddrReg and Scratch1Reg should be tied"); + assert(Scratch2Reg == IncrReg && "IncrReg and Scratch1Reg should be tied"); + + // Register allocation. + unsigned SuccessReg, InvMaskTargetDataReg, SurroundingBytesReg, + MaskTargetDataReg, NewValReg, AlignedAddrReg, OffsetReg, OldValReg; + SuccessReg = InvMaskTargetDataReg = SurroundingBytesReg = DestReg; + AlignedAddrReg = AddrReg; + NewValReg = IncrReg; + OffsetReg = Scratch3Reg; + OldValReg = Scratch4Reg; + MaskTargetDataReg = Scratch5Reg; + + // andi offset, addr, 3 + // andi alignedaddr, addr, -4 + // slli offset, offset, 3 + // li masktargetdata 255 (or 65535 for i16) + // sll masktargetdata, masktargetdata, offset + // not invmasktargetdata, masktargetdata + // sll incr, incr, offset + BuildMI(ThisMBB, DL, TII->get(RISCV::ANDI), OffsetReg) + .addReg(AddrReg) + .addImm(3); + BuildMI(ThisMBB, DL, TII->get(RISCV::ANDI), AlignedAddrReg) + .addReg(AddrReg) + .addImm(-4); + BuildMI(ThisMBB, DL, TII->get(RISCV::SLLI), OffsetReg) + .addReg(OffsetReg) + .addImm(3); + if (Width == 8) { + BuildMI(ThisMBB, DL, TII->get(RISCV::ADDI), MaskTargetDataReg) + .addReg(RISCV::X0) + .addImm(255); + } else { + assert(Width == 16 && "Only 8/16-bit atomics supported"); + BuildMI(ThisMBB, DL, TII->get(RISCV::LUI), MaskTargetDataReg).addImm(0x10); + BuildMI(ThisMBB, DL, TII->get(RISCV::ADDI), MaskTargetDataReg) + .addReg(MaskTargetDataReg) + .addImm(-1); + } + BuildMI(ThisMBB, DL, TII->get(RISCV::SLL), MaskTargetDataReg) + .addReg(MaskTargetDataReg) + .addReg(OffsetReg); + BuildMI(ThisMBB, DL, TII->get(RISCV::XORI), InvMaskTargetDataReg) + .addReg(MaskTargetDataReg) + .addImm(-1); + BuildMI(ThisMBB, DL, TII->get(RISCV::SLL), IncrReg) + .addReg(IncrReg) + .addReg(OffsetReg); + + // .loop: + // lr.w oldval, (alignedaddr) + // binop newval, oldval, incr + // and newval, newval, masktargetdata + // and surroundingbytes, oldval, invmasktargetdata + // or newval, newval, surroundingbytes + // sc.w success, newval, (alignedaddr) + // bnez success, loop + BuildMI(LoopMBB, DL, TII->get(getLRForRMW32(Ordering)), OldValReg) + .addReg(AlignedAddrReg); + switch (BinOp) { + default: + llvm_unreachable("Unexpected AtomicRMW BinOp"); + case AtomicRMWInst::Xchg: + // No instruction needed as NewValReg == IncrReg. + break; + case AtomicRMWInst::Add: + BuildMI(LoopMBB, DL, TII->get(RISCV::ADD), NewValReg) + .addReg(OldValReg) + .addReg(IncrReg); + break; + case AtomicRMWInst::Sub: + BuildMI(LoopMBB, DL, TII->get(RISCV::SUB), NewValReg) + .addReg(OldValReg) + .addReg(IncrReg); + break; + case AtomicRMWInst::And: + BuildMI(LoopMBB, DL, TII->get(RISCV::AND), NewValReg) + .addReg(OldValReg) + .addReg(IncrReg); + break; + case AtomicRMWInst::Nand: + BuildMI(LoopMBB, DL, TII->get(RISCV::AND), NewValReg) + .addReg(OldValReg) + .addReg(IncrReg); + BuildMI(LoopMBB, DL, TII->get(RISCV::XORI), NewValReg) + .addReg(NewValReg) + .addImm(-1); + break; + case AtomicRMWInst::Or: + BuildMI(LoopMBB, DL, TII->get(RISCV::OR), NewValReg) + .addReg(OldValReg) + .addReg(IncrReg); + break; + case AtomicRMWInst::Xor: + BuildMI(LoopMBB, DL, TII->get(RISCV::XOR), NewValReg) + .addReg(OldValReg) + .addReg(IncrReg); + break; + } + + BuildMI(LoopMBB, DL, TII->get(RISCV::AND), NewValReg) + .addReg(NewValReg) + .addReg(MaskTargetDataReg); + BuildMI(LoopMBB, DL, TII->get(RISCV::AND), SurroundingBytesReg) + .addReg(OldValReg) + .addReg(InvMaskTargetDataReg); + BuildMI(LoopMBB, DL, TII->get(RISCV::OR), NewValReg) + .addReg(NewValReg) + .addReg(SurroundingBytesReg); + + BuildMI(LoopMBB, DL, TII->get(getSCForRMW32(Ordering)), SuccessReg) + .addReg(AlignedAddrReg) + .addReg(NewValReg); + BuildMI(LoopMBB, DL, TII->get(RISCV::BNE)) + .addReg(SuccessReg) + .addReg(RISCV::X0) + .addMBB(LoopMBB); + + // .done: + // and oldval, oldval, masktargetdata + // srl oldval, oldval, offset + // slli oldval, oldval, 24 + // srai dest, oldval, 24 + MachineBasicBlock::iterator NextMI = DoneMBB->getFirstNonPHI(); + BuildMI(*DoneMBB, NextMI, DL, TII->get(RISCV::AND), OldValReg) + .addReg(OldValReg) + .addReg(MaskTargetDataReg); + BuildMI(*DoneMBB, NextMI, DL, TII->get(RISCV::SRL), OldValReg) + .addReg(OldValReg) + .addReg(OffsetReg); + BuildMI(*DoneMBB, NextMI, DL, TII->get(RISCV::SLLI), OldValReg) + .addReg(OldValReg) + .addImm(24); + BuildMI(*DoneMBB, NextMI, DL, TII->get(RISCV::SRAI), DestReg) + .addReg(OldValReg) + .addImm(24); +} + +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 = (AtomicOrdering)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::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; + } + 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, 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); + + switch (Width) { + default: + llvm_unreachable("Unexpected atomic width"); + case 8: + doPartWordAtomicBinOpExpansion(TII, MI, DL, &MBB, LoopMBB, DoneMBB, BinOp, + 8); + break; + case 16: + doPartWordAtomicBinOpExpansion(TII, MI, DL, &MBB, LoopMBB, DoneMBB, BinOp, + 16); + break; + case 32: + doAtomicBinOpExpansion(TII, MI, DL, &MBB, LoopMBB, DoneMBB, BinOp, 32); + break; + } + + NextMBBI = MBB.end(); + MI.eraseFromParent(); + + LivePhysRegs LiveRegs; + computeAndAddLiveIns(LiveRegs, *LoopMBB); + 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/RISCVInstrInfo.td =================================================================== --- lib/Target/RISCV/RISCVInstrInfo.td +++ lib/Target/RISCV/RISCVInstrInfo.td @@ -526,7 +526,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,103 @@ 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">; + +/// 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; +} + +class PseudoPartWordAMO + : Pseudo<(outs GPR:$res, GPR:$scratch1, GPR:$scratch2, GPR:$scratch3, + GPR:$scratch4, GPR:$scratch5), + (ins GPR:$addr, GPR:$incr, i32imm:$ordering), []> { + let Constraints = "@earlyclobber $res, $addr = $scratch1, $incr = $scratch2," + "@earlyclobber $scratch3,@earlyclobber $scratch4," + "@earlyclobber $scratch5"; + let mayLoad = 1; + let mayStore = 1; + let hasSideEffects = 0; +} + +// Ordering constants must be kept in sync with the AtomicOrdering enum in +// AtomicOrdering.h. +multiclass PseudoAMOPat { + def : Pat<(!cast(AtomicOp#"_monotonic") GPR:$addr, GPR:$incr), + (AMOInst GPR:$addr, GPR:$incr, 2)>; + def : Pat<(!cast(AtomicOp#"_acquire") GPR:$addr, GPR:$incr), + (AMOInst GPR:$addr, GPR:$incr, 4)>; + def : Pat<(!cast(AtomicOp#"_release") GPR:$addr, GPR:$incr), + (AMOInst GPR:$addr, GPR:$incr, 5)>; + def : Pat<(!cast(AtomicOp#"_acq_rel") GPR:$addr, GPR:$incr), + (AMOInst GPR:$addr, GPR:$incr, 6)>; + def : Pat<(!cast(AtomicOp#"_seq_cst") GPR:$addr, GPR:$incr), + (AMOInst GPR:$addr, GPR:$incr, 7)>; +} + +def PseudoAtomicLoadSub32 : PseudoAMO; +defm : PseudoAMOPat<"atomic_load_sub_32", PseudoAtomicLoadSub32>; +def PseudoAtomicLoadNand32 : PseudoAMO; +defm : PseudoAMOPat<"atomic_load_nand_32", PseudoAtomicLoadNand32>; + +def PseudoAtomicSwap8 : PseudoPartWordAMO; +defm : PseudoAMOPat<"atomic_swap_8", PseudoAtomicSwap8>; +def PseudoAtomicLoadAdd8 : PseudoPartWordAMO; +defm : PseudoAMOPat<"atomic_load_add_8", PseudoAtomicLoadAdd8>; +def PseudoAtomicLoadSub8 : PseudoPartWordAMO; +defm : PseudoAMOPat<"atomic_load_sub_8", PseudoAtomicLoadSub8>; +def PseudoAtomicLoadAnd8 : PseudoPartWordAMO; +defm : PseudoAMOPat<"atomic_load_and_8", PseudoAtomicLoadAnd8>; +def PseudoAtomicLoadNand8 : PseudoPartWordAMO; +defm : PseudoAMOPat<"atomic_load_nand_8", PseudoAtomicLoadNand8>; +def PseudoAtomicLoadOr8 : PseudoPartWordAMO; +defm : PseudoAMOPat<"atomic_load_or_8", PseudoAtomicLoadOr8>; +def PseudoAtomicLoadXor8 : PseudoPartWordAMO; +defm : PseudoAMOPat<"atomic_load_xor_8", PseudoAtomicLoadXor8>; +def PseudoAtomicLoadMax8 : PseudoPartWordAMO; + +def PseudoAtomicSwap16 : PseudoPartWordAMO; +defm : PseudoAMOPat<"atomic_swap_16", PseudoAtomicSwap16>; +def PseudoAtomicLoadAdd16 : PseudoPartWordAMO; +defm : PseudoAMOPat<"atomic_load_add_16", PseudoAtomicLoadAdd16>; +def PseudoAtomicLoadSub16 : PseudoPartWordAMO; +defm : PseudoAMOPat<"atomic_load_sub_16", PseudoAtomicLoadSub16>; +def PseudoAtomicLoadAnd16 : PseudoPartWordAMO; +defm : PseudoAMOPat<"atomic_load_and_16", PseudoAtomicLoadAnd16>; +def PseudoAtomicLoadNand16 : PseudoPartWordAMO; +defm : PseudoAMOPat<"atomic_load_nand_16", PseudoAtomicLoadNand16>; +def PseudoAtomicLoadOr16 : PseudoPartWordAMO; +defm : PseudoAMOPat<"atomic_load_or_16", PseudoAtomicLoadOr16>; +def PseudoAtomicLoadXor16 : PseudoPartWordAMO; +defm : PseudoAMOPat<"atomic_load_xor_16", PseudoAtomicLoadXor16>; +def PseudoAtomicLoadMax16 : PseudoPartWordAMO; +} // 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 addPreSched2() override; }; } @@ -97,3 +100,5 @@ } void RISCVPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); } + +void RISCVPassConfig::addPreSched2() { addPass(createRISCVExpandPseudoPass()); } 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,30 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB0_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB0_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i8* %a, i8 %b monotonic ret i8 %1 } @@ -26,6 +52,30 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB1_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB1_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i8* %a, i8 %b acquire ret i8 %1 } @@ -40,6 +90,30 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB2_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB2_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i8* %a, i8 %b release ret i8 %1 } @@ -54,6 +128,30 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB3_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB3_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i8* %a, i8 %b acq_rel ret i8 %1 } @@ -68,6 +166,30 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB4_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.aqrl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB4_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i8* %a, i8 %b seq_cst ret i8 %1 } @@ -82,6 +204,31 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB5_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: add a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB5_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw add i8* %a, i8 %b monotonic ret i8 %1 } @@ -96,6 +243,31 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB6_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: add a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB6_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw add i8* %a, i8 %b acquire ret i8 %1 } @@ -110,6 +282,31 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB7_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: add a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB7_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw add i8* %a, i8 %b release ret i8 %1 } @@ -124,6 +321,31 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB8_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: add a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB8_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw add i8* %a, i8 %b acq_rel ret i8 %1 } @@ -138,6 +360,31 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB9_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: add a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.aqrl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB9_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw add i8* %a, i8 %b seq_cst ret i8 %1 } @@ -152,6 +399,31 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB10_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: sub a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB10_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw sub i8* %a, i8 %b monotonic ret i8 %1 } @@ -166,6 +438,31 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB11_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: sub a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB11_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw sub i8* %a, i8 %b acquire ret i8 %1 } @@ -180,6 +477,31 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB12_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: sub a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB12_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw sub i8* %a, i8 %b release ret i8 %1 } @@ -194,6 +516,31 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB13_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: sub a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB13_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw sub i8* %a, i8 %b acq_rel ret i8 %1 } @@ -208,6 +555,31 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB14_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: sub a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.aqrl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB14_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw sub i8* %a, i8 %b seq_cst ret i8 %1 } @@ -222,6 +594,31 @@ ; 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 a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB15_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB15_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw and i8* %a, i8 %b monotonic ret i8 %1 } @@ -236,6 +633,31 @@ ; 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 a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB16_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB16_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw and i8* %a, i8 %b acquire ret i8 %1 } @@ -250,6 +672,31 @@ ; 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 a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB17_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB17_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw and i8* %a, i8 %b release ret i8 %1 } @@ -264,6 +711,31 @@ ; 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 a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB18_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB18_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw and i8* %a, i8 %b acq_rel ret i8 %1 } @@ -278,6 +750,31 @@ ; 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 a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB19_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: and a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.aqrl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB19_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw and i8* %a, i8 %b seq_cst ret i8 %1 } @@ -292,6 +789,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB20_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a1, a4, a1 +; RV32IA-NEXT: not a1, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB20_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw nand i8* %a, i8 %b monotonic ret i8 %1 } @@ -306,6 +829,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB21_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a1, a4, a1 +; RV32IA-NEXT: not a1, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB21_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw nand i8* %a, i8 %b acquire ret i8 %1 } @@ -320,6 +869,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB22_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a1, a4, a1 +; RV32IA-NEXT: not a1, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB22_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw nand i8* %a, i8 %b release ret i8 %1 } @@ -334,6 +909,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB23_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a1, a4, a1 +; RV32IA-NEXT: not a1, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB23_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw nand i8* %a, i8 %b acq_rel ret i8 %1 } @@ -348,6 +949,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB24_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: and a1, a4, a1 +; RV32IA-NEXT: not a1, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.aqrl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB24_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw nand i8* %a, i8 %b seq_cst ret i8 %1 } @@ -362,6 +989,31 @@ ; 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 a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB25_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: or a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB25_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw or i8* %a, i8 %b monotonic ret i8 %1 } @@ -376,6 +1028,31 @@ ; 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 a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB26_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: or a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB26_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw or i8* %a, i8 %b acquire ret i8 %1 } @@ -390,6 +1067,31 @@ ; 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 a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB27_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: or a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB27_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw or i8* %a, i8 %b release ret i8 %1 } @@ -404,6 +1106,31 @@ ; 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 a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB28_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: or a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB28_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw or i8* %a, i8 %b acq_rel ret i8 %1 } @@ -418,6 +1145,31 @@ ; 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 a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB29_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: or a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.aqrl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB29_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw or i8* %a, i8 %b seq_cst ret i8 %1 } @@ -432,6 +1184,31 @@ ; 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 a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB30_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: xor a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB30_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xor i8* %a, i8 %b monotonic ret i8 %1 } @@ -446,6 +1223,31 @@ ; 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 a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB31_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: xor a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB31_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xor i8* %a, i8 %b acquire ret i8 %1 } @@ -460,6 +1262,31 @@ ; 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 a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB32_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: xor a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB32_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xor i8* %a, i8 %b release ret i8 %1 } @@ -474,6 +1301,31 @@ ; 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 a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB33_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: xor a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB33_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xor i8* %a, i8 %b acq_rel ret i8 %1 } @@ -488,6 +1340,31 @@ ; 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 a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: addi a5, zero, 255 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB34_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: xor a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.aqrl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB34_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xor i8* %a, i8 %b seq_cst ret i8 %1 } @@ -505,6 +1382,31 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB35_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB35_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i16* %a, i16 %b monotonic ret i16 %1 } @@ -519,6 +1421,31 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB36_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB36_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i16* %a, i16 %b acquire ret i16 %1 } @@ -533,6 +1460,31 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB37_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB37_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i16* %a, i16 %b release ret i16 %1 } @@ -547,6 +1499,31 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB38_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB38_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i16* %a, i16 %b acq_rel ret i16 %1 } @@ -561,6 +1538,31 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB39_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.aqrl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB39_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xchg i16* %a, i16 %b seq_cst ret i16 %1 } @@ -575,6 +1577,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB40_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: add a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB40_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw add i16* %a, i16 %b monotonic ret i16 %1 } @@ -589,6 +1617,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB41_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: add a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB41_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw add i16* %a, i16 %b acquire ret i16 %1 } @@ -603,6 +1657,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB42_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: add a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB42_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw add i16* %a, i16 %b release ret i16 %1 } @@ -617,6 +1697,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB43_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: add a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB43_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw add i16* %a, i16 %b acq_rel ret i16 %1 } @@ -631,6 +1737,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB44_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: add a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.aqrl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB44_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw add i16* %a, i16 %b seq_cst ret i16 %1 } @@ -645,6 +1777,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB45_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: sub a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB45_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw sub i16* %a, i16 %b monotonic ret i16 %1 } @@ -659,6 +1817,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB46_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: sub a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB46_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw sub i16* %a, i16 %b acquire ret i16 %1 } @@ -673,6 +1857,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB47_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: sub a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB47_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw sub i16* %a, i16 %b release ret i16 %1 } @@ -687,6 +1897,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB48_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: sub a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB48_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw sub i16* %a, i16 %b acq_rel ret i16 %1 } @@ -701,6 +1937,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB49_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: sub a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.aqrl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB49_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw sub i16* %a, i16 %b seq_cst ret i16 %1 } @@ -715,6 +1977,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB50_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB50_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw and i16* %a, i16 %b monotonic ret i16 %1 } @@ -729,6 +2017,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB51_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB51_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw and i16* %a, i16 %b acquire ret i16 %1 } @@ -743,6 +2057,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB52_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB52_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw and i16* %a, i16 %b release ret i16 %1 } @@ -757,6 +2097,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB53_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB53_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw and i16* %a, i16 %b acq_rel ret i16 %1 } @@ -771,6 +2137,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB54_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: and a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.aqrl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB54_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw and i16* %a, i16 %b seq_cst ret i16 %1 } @@ -785,6 +2177,33 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB55_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a1, a4, a1 +; RV32IA-NEXT: not a1, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB55_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw nand i16* %a, i16 %b monotonic ret i16 %1 } @@ -799,6 +2218,33 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB56_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a1, a4, a1 +; RV32IA-NEXT: not a1, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB56_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw nand i16* %a, i16 %b acquire ret i16 %1 } @@ -813,6 +2259,33 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB57_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: and a1, a4, a1 +; RV32IA-NEXT: not a1, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB57_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw nand i16* %a, i16 %b release ret i16 %1 } @@ -827,6 +2300,33 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB58_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: and a1, a4, a1 +; RV32IA-NEXT: not a1, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB58_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw nand i16* %a, i16 %b acq_rel ret i16 %1 } @@ -841,6 +2341,33 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB59_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: and a1, a4, a1 +; RV32IA-NEXT: not a1, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.aqrl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB59_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw nand i16* %a, i16 %b seq_cst ret i16 %1 } @@ -855,6 +2382,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB60_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: or a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB60_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw or i16* %a, i16 %b monotonic ret i16 %1 } @@ -869,6 +2422,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB61_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: or a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB61_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw or i16* %a, i16 %b acquire ret i16 %1 } @@ -883,6 +2462,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB62_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: or a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB62_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw or i16* %a, i16 %b release ret i16 %1 } @@ -897,6 +2502,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB63_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: or a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB63_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw or i16* %a, i16 %b acq_rel ret i16 %1 } @@ -911,6 +2542,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB64_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: or a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.aqrl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB64_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw or i16* %a, i16 %b seq_cst ret i16 %1 } @@ -925,6 +2582,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB65_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: xor a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB65_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xor i16* %a, i16 %b monotonic ret i16 %1 } @@ -939,6 +2622,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB66_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: xor a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB66_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xor i16* %a, i16 %b acquire ret i16 %1 } @@ -953,6 +2662,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB67_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a4, (a0) +; RV32IA-NEXT: xor a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB67_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xor i16* %a, i16 %b release ret i16 %1 } @@ -967,6 +2702,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB68_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a4, (a0) +; RV32IA-NEXT: xor a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.rl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB68_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xor i16* %a, i16 %b acq_rel ret i16 %1 } @@ -981,6 +2742,32 @@ ; 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: andi a3, a0, 3 +; RV32IA-NEXT: andi a0, a0, -4 +; RV32IA-NEXT: slli a3, a3, 3 +; RV32IA-NEXT: lui a5, 16 +; RV32IA-NEXT: addi a5, a5, -1 +; RV32IA-NEXT: sll a5, a5, a3 +; RV32IA-NEXT: not a2, a5 +; RV32IA-NEXT: sll a1, a1, a3 +; RV32IA-NEXT: .LBB69_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a4, (a0) +; RV32IA-NEXT: xor a1, a4, a1 +; RV32IA-NEXT: and a1, a1, a5 +; RV32IA-NEXT: and a2, a4, a2 +; RV32IA-NEXT: or a1, a1, a2 +; RV32IA-NEXT: sc.w.aqrl a2, a1, (a0) +; RV32IA-NEXT: bnez a2, .LBB69_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: and a4, a4, a5 +; RV32IA-NEXT: srl a4, a4, a3 +; RV32IA-NEXT: slli a4, a4, 24 +; RV32IA-NEXT: srai a2, a4, 24 +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw xor i16* %a, i16 %b seq_cst ret i16 %1 } @@ -998,6 +2785,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 } @@ -1012,6 +2804,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 } @@ -1026,6 +2823,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 } @@ -1040,6 +2842,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 } @@ -1054,6 +2861,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 } @@ -1068,6 +2880,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 } @@ -1082,6 +2899,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 } @@ -1096,6 +2918,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 } @@ -1110,6 +2937,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 } @@ -1124,6 +2956,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 } @@ -1138,6 +2975,17 @@ ; 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: .LBB80_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a2, (a0) +; RV32IA-NEXT: sub a3, a2, a1 +; RV32IA-NEXT: sc.w a3, a3, (a0) +; RV32IA-NEXT: bnez a3, .LBB80_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw sub i32* %a, i32 %b monotonic ret i32 %1 } @@ -1152,6 +3000,17 @@ ; 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: .LBB81_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a2, (a0) +; RV32IA-NEXT: sub a3, a2, a1 +; RV32IA-NEXT: sc.w a3, a3, (a0) +; RV32IA-NEXT: bnez a3, .LBB81_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw sub i32* %a, i32 %b acquire ret i32 %1 } @@ -1166,6 +3025,17 @@ ; 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: .LBB82_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w a2, (a0) +; RV32IA-NEXT: sub a3, a2, a1 +; RV32IA-NEXT: sc.w.rl a3, a3, (a0) +; RV32IA-NEXT: bnez a3, .LBB82_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw sub i32* %a, i32 %b release ret i32 %1 } @@ -1180,6 +3050,17 @@ ; 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: .LBB83_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aq a2, (a0) +; RV32IA-NEXT: sub a3, a2, a1 +; RV32IA-NEXT: sc.w.rl a3, a3, (a0) +; RV32IA-NEXT: bnez a3, .LBB83_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw sub i32* %a, i32 %b acq_rel ret i32 %1 } @@ -1194,6 +3075,17 @@ ; 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: .LBB84_1: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: lr.w.aqrl a2, (a0) +; RV32IA-NEXT: sub a3, a2, a1 +; RV32IA-NEXT: sc.w.aqrl a3, a3, (a0) +; RV32IA-NEXT: bnez a3, .LBB84_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw sub i32* %a, i32 %b seq_cst ret i32 %1 } @@ -1208,6 +3100,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 } @@ -1222,6 +3119,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 } @@ -1236,6 +3138,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 } @@ -1250,6 +3157,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 } @@ -1264,6 +3176,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 } @@ -1278,6 +3195,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: .LBB90_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, .LBB90_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw nand i32* %a, i32 %b monotonic ret i32 %1 } @@ -1292,6 +3221,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: .LBB91_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, .LBB91_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw nand i32* %a, i32 %b acquire ret i32 %1 } @@ -1306,6 +3247,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: .LBB92_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, .LBB92_1 +; RV32IA-NEXT: # %bb.2: +; RV32IA-NEXT: mv a0, a2 +; RV32IA-NEXT: ret %1 = atomicrmw nand i32* %a, i32 %b release ret i32 %1 } @@ -1320,6 +3273,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: .LBB93_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, .LBB93_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 } @@ -1334,6 +3299,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: .LBB94_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, .LBB94_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 } @@ -1348,6 +3325,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 } @@ -1362,6 +3344,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 } @@ -1376,6 +3363,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 } @@ -1390,6 +3382,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 } @@ -1404,6 +3401,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 } @@ -1418,6 +3420,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 } @@ -1432,6 +3439,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 } @@ -1446,6 +3458,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 } @@ -1460,6 +3477,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 } @@ -1474,6 +3496,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 } @@ -1514,6 +3541,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 } @@ -1557,6 +3589,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 } @@ -1600,6 +3637,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 } @@ -1646,6 +3688,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 } @@ -1689,6 +3736,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 } @@ -1729,6 +3781,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 } @@ -1772,6 +3829,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 } @@ -1815,6 +3877,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 } @@ -1861,6 +3928,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 } @@ -1904,6 +3976,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 } @@ -1944,6 +4021,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 } @@ -1987,6 +4069,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 } @@ -2030,6 +4117,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 } @@ -2076,6 +4168,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 } @@ -2119,6 +4216,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 } @@ -2159,6 +4261,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 } @@ -2202,6 +4309,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 } @@ -2245,6 +4357,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 } @@ -2291,6 +4408,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 } @@ -2334,6 +4456,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 } @@ -2348,6 +4475,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 } @@ -2362,6 +4499,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 } @@ -2376,6 +4523,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 } @@ -2390,6 +4547,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 } @@ -2404,6 +4571,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 } @@ -2418,6 +4595,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 } @@ -2432,6 +4619,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 } @@ -2446,6 +4643,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 } @@ -2460,6 +4667,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 } @@ -2474,6 +4691,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 } @@ -2488,6 +4715,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 } @@ -2502,6 +4739,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 } @@ -2516,6 +4763,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 } @@ -2530,6 +4787,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 } @@ -2544,6 +4811,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 } @@ -2558,6 +4835,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 } @@ -2572,6 +4859,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 } @@ -2586,6 +4883,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 } @@ -2600,6 +4907,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 } @@ -2614,6 +4931,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 } @@ -2628,6 +4955,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 } @@ -2642,6 +4979,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 } @@ -2656,6 +5003,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 } @@ -2670,6 +5027,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 } @@ -2684,6 +5051,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 } @@ -2698,6 +5075,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 } @@ -2712,6 +5099,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 } @@ -2726,6 +5123,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 } @@ -2740,6 +5147,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 } @@ -2754,6 +5171,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 } @@ -2768,6 +5195,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 } @@ -2782,6 +5219,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 } @@ -2796,6 +5243,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 } @@ -2810,6 +5267,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 } @@ -2824,6 +5291,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 } @@ -2886,6 +5363,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: .LBB160_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB160_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB160_1 Depth=1 +; RV32IA-NEXT: slt a0, s1, a1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB160_4 +; RV32IA-NEXT: j .LBB160_5 +; RV32IA-NEXT: .LBB160_3: # in Loop: Header=BB160_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB160_5 +; RV32IA-NEXT: .LBB160_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB160_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB160_5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB160_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB160_7 +; RV32IA-NEXT: # %bb.6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB160_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB160_7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB160_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, .LBB160_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 } @@ -2951,6 +5486,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: .LBB161_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB161_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB161_1 Depth=1 +; RV32IA-NEXT: slt a0, s1, a1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB161_4 +; RV32IA-NEXT: j .LBB161_5 +; RV32IA-NEXT: .LBB161_3: # in Loop: Header=BB161_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB161_5 +; RV32IA-NEXT: .LBB161_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB161_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB161_5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB161_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB161_7 +; RV32IA-NEXT: # %bb.6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB161_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB161_7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB161_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, .LBB161_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 } @@ -3016,6 +5612,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: .LBB162_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB162_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB162_1 Depth=1 +; RV32IA-NEXT: slt a0, s1, a1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB162_4 +; RV32IA-NEXT: j .LBB162_5 +; RV32IA-NEXT: .LBB162_3: # in Loop: Header=BB162_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB162_5 +; RV32IA-NEXT: .LBB162_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB162_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB162_5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB162_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB162_7 +; RV32IA-NEXT: # %bb.6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB162_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB162_7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB162_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, .LBB162_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 } @@ -3084,6 +5741,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: .LBB163_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB163_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB163_1 Depth=1 +; RV32IA-NEXT: slt a0, s1, a1 +; RV32IA-NEXT: sw a2, 8(sp) +; RV32IA-NEXT: beqz a0, .LBB163_4 +; RV32IA-NEXT: j .LBB163_5 +; RV32IA-NEXT: .LBB163_3: # in Loop: Header=BB163_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: sw a2, 8(sp) +; RV32IA-NEXT: bnez a0, .LBB163_5 +; RV32IA-NEXT: .LBB163_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB163_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB163_5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB163_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB163_7 +; RV32IA-NEXT: # %bb.6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB163_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB163_7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB163_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, .LBB163_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 } @@ -3149,6 +5870,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: .LBB164_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB164_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB164_1 Depth=1 +; RV32IA-NEXT: slt a0, s1, a1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB164_4 +; RV32IA-NEXT: j .LBB164_5 +; RV32IA-NEXT: .LBB164_3: # in Loop: Header=BB164_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB164_5 +; RV32IA-NEXT: .LBB164_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB164_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB164_5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB164_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB164_7 +; RV32IA-NEXT: # %bb.6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB164_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB164_7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB164_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, .LBB164_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 } @@ -3212,6 +5994,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: .LBB165_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB165_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB165_1 Depth=1 +; RV32IA-NEXT: slt a0, s1, a1 +; RV32IA-NEXT: j .LBB165_4 +; RV32IA-NEXT: .LBB165_3: # in Loop: Header=BB165_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: .LBB165_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB165_1 Depth=1 +; RV32IA-NEXT: xori a0, a0, 1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB165_6 +; RV32IA-NEXT: # %bb.5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB165_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB165_6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB165_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB165_8 +; RV32IA-NEXT: # %bb.7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB165_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB165_8: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB165_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, .LBB165_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 } @@ -3278,6 +6119,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: .LBB166_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB166_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB166_1 Depth=1 +; RV32IA-NEXT: slt a0, s1, a1 +; RV32IA-NEXT: j .LBB166_4 +; RV32IA-NEXT: .LBB166_3: # in Loop: Header=BB166_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: .LBB166_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB166_1 Depth=1 +; RV32IA-NEXT: xori a0, a0, 1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB166_6 +; RV32IA-NEXT: # %bb.5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB166_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB166_6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB166_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB166_8 +; RV32IA-NEXT: # %bb.7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB166_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB166_8: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB166_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, .LBB166_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 } @@ -3344,6 +6247,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: .LBB167_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB167_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB167_1 Depth=1 +; RV32IA-NEXT: slt a0, s1, a1 +; RV32IA-NEXT: j .LBB167_4 +; RV32IA-NEXT: .LBB167_3: # in Loop: Header=BB167_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: .LBB167_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB167_1 Depth=1 +; RV32IA-NEXT: xori a0, a0, 1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB167_6 +; RV32IA-NEXT: # %bb.5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB167_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB167_6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB167_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB167_8 +; RV32IA-NEXT: # %bb.7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB167_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB167_8: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB167_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, .LBB167_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 } @@ -3413,6 +6378,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: .LBB168_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB168_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB168_1 Depth=1 +; RV32IA-NEXT: slt a0, s1, a1 +; RV32IA-NEXT: j .LBB168_4 +; RV32IA-NEXT: .LBB168_3: # in Loop: Header=BB168_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: .LBB168_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB168_1 Depth=1 +; RV32IA-NEXT: xori a0, a0, 1 +; RV32IA-NEXT: sw a2, 8(sp) +; RV32IA-NEXT: bnez a0, .LBB168_6 +; RV32IA-NEXT: # %bb.5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB168_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB168_6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB168_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB168_8 +; RV32IA-NEXT: # %bb.7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB168_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB168_8: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB168_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, .LBB168_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 } @@ -3479,6 +6509,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: .LBB169_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB169_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB169_1 Depth=1 +; RV32IA-NEXT: slt a0, s1, a1 +; RV32IA-NEXT: j .LBB169_4 +; RV32IA-NEXT: .LBB169_3: # in Loop: Header=BB169_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: .LBB169_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB169_1 Depth=1 +; RV32IA-NEXT: xori a0, a0, 1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB169_6 +; RV32IA-NEXT: # %bb.5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB169_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB169_6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB169_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB169_8 +; RV32IA-NEXT: # %bb.7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB169_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB169_8: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB169_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, .LBB169_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 } @@ -3541,6 +6633,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: .LBB170_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB170_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB170_1 Depth=1 +; RV32IA-NEXT: sltu a0, s1, a1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB170_4 +; RV32IA-NEXT: j .LBB170_5 +; RV32IA-NEXT: .LBB170_3: # in Loop: Header=BB170_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB170_5 +; RV32IA-NEXT: .LBB170_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB170_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB170_5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB170_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB170_7 +; RV32IA-NEXT: # %bb.6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB170_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB170_7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB170_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, .LBB170_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 } @@ -3606,6 +6756,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: .LBB171_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB171_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB171_1 Depth=1 +; RV32IA-NEXT: sltu a0, s1, a1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB171_4 +; RV32IA-NEXT: j .LBB171_5 +; RV32IA-NEXT: .LBB171_3: # in Loop: Header=BB171_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB171_5 +; RV32IA-NEXT: .LBB171_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB171_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB171_5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB171_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB171_7 +; RV32IA-NEXT: # %bb.6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB171_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB171_7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB171_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, .LBB171_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 } @@ -3671,6 +6882,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: .LBB172_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB172_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB172_1 Depth=1 +; RV32IA-NEXT: sltu a0, s1, a1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB172_4 +; RV32IA-NEXT: j .LBB172_5 +; RV32IA-NEXT: .LBB172_3: # in Loop: Header=BB172_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB172_5 +; RV32IA-NEXT: .LBB172_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB172_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB172_5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB172_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB172_7 +; RV32IA-NEXT: # %bb.6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB172_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB172_7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB172_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, .LBB172_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 } @@ -3739,6 +7011,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: .LBB173_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB173_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB173_1 Depth=1 +; RV32IA-NEXT: sltu a0, s1, a1 +; RV32IA-NEXT: sw a2, 8(sp) +; RV32IA-NEXT: beqz a0, .LBB173_4 +; RV32IA-NEXT: j .LBB173_5 +; RV32IA-NEXT: .LBB173_3: # in Loop: Header=BB173_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: sw a2, 8(sp) +; RV32IA-NEXT: bnez a0, .LBB173_5 +; RV32IA-NEXT: .LBB173_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB173_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB173_5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB173_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB173_7 +; RV32IA-NEXT: # %bb.6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB173_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB173_7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB173_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, .LBB173_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 } @@ -3804,6 +7140,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: .LBB174_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB174_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB174_1 Depth=1 +; RV32IA-NEXT: sltu a0, s1, a1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: beqz a0, .LBB174_4 +; RV32IA-NEXT: j .LBB174_5 +; RV32IA-NEXT: .LBB174_3: # in Loop: Header=BB174_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB174_5 +; RV32IA-NEXT: .LBB174_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB174_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB174_5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB174_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB174_7 +; RV32IA-NEXT: # %bb.6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB174_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB174_7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB174_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, .LBB174_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 } @@ -3867,6 +7264,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: .LBB175_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB175_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB175_1 Depth=1 +; RV32IA-NEXT: sltu a0, s1, a1 +; RV32IA-NEXT: j .LBB175_4 +; RV32IA-NEXT: .LBB175_3: # in Loop: Header=BB175_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: .LBB175_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB175_1 Depth=1 +; RV32IA-NEXT: xori a0, a0, 1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB175_6 +; RV32IA-NEXT: # %bb.5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB175_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB175_6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB175_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB175_8 +; RV32IA-NEXT: # %bb.7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB175_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB175_8: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB175_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, .LBB175_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 } @@ -3933,6 +7389,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: .LBB176_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB176_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB176_1 Depth=1 +; RV32IA-NEXT: sltu a0, s1, a1 +; RV32IA-NEXT: j .LBB176_4 +; RV32IA-NEXT: .LBB176_3: # in Loop: Header=BB176_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: .LBB176_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB176_1 Depth=1 +; RV32IA-NEXT: xori a0, a0, 1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB176_6 +; RV32IA-NEXT: # %bb.5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB176_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB176_6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB176_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB176_8 +; RV32IA-NEXT: # %bb.7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB176_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB176_8: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB176_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, .LBB176_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 } @@ -3999,6 +7517,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: .LBB177_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB177_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB177_1 Depth=1 +; RV32IA-NEXT: sltu a0, s1, a1 +; RV32IA-NEXT: j .LBB177_4 +; RV32IA-NEXT: .LBB177_3: # in Loop: Header=BB177_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: .LBB177_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB177_1 Depth=1 +; RV32IA-NEXT: xori a0, a0, 1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB177_6 +; RV32IA-NEXT: # %bb.5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB177_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB177_6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB177_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB177_8 +; RV32IA-NEXT: # %bb.7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB177_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB177_8: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB177_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, .LBB177_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 } @@ -4068,6 +7648,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: .LBB178_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB178_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB178_1 Depth=1 +; RV32IA-NEXT: sltu a0, s1, a1 +; RV32IA-NEXT: j .LBB178_4 +; RV32IA-NEXT: .LBB178_3: # in Loop: Header=BB178_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: .LBB178_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB178_1 Depth=1 +; RV32IA-NEXT: xori a0, a0, 1 +; RV32IA-NEXT: sw a2, 8(sp) +; RV32IA-NEXT: bnez a0, .LBB178_6 +; RV32IA-NEXT: # %bb.5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB178_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB178_6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB178_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB178_8 +; RV32IA-NEXT: # %bb.7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB178_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB178_8: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB178_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, .LBB178_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 } @@ -4134,6 +7779,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: .LBB179_1: # %atomicrmw.start +; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IA-NEXT: beq a1, s1, .LBB179_3 +; RV32IA-NEXT: # %bb.2: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB179_1 Depth=1 +; RV32IA-NEXT: sltu a0, s1, a1 +; RV32IA-NEXT: j .LBB179_4 +; RV32IA-NEXT: .LBB179_3: # in Loop: Header=BB179_1 Depth=1 +; RV32IA-NEXT: sltu a0, s2, a2 +; RV32IA-NEXT: .LBB179_4: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB179_1 Depth=1 +; RV32IA-NEXT: xori a0, a0, 1 +; RV32IA-NEXT: sw a2, 0(sp) +; RV32IA-NEXT: bnez a0, .LBB179_6 +; RV32IA-NEXT: # %bb.5: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB179_1 Depth=1 +; RV32IA-NEXT: mv a2, s2 +; RV32IA-NEXT: .LBB179_6: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB179_1 Depth=1 +; RV32IA-NEXT: mv a3, a1 +; RV32IA-NEXT: bnez a0, .LBB179_8 +; RV32IA-NEXT: # %bb.7: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB179_1 Depth=1 +; RV32IA-NEXT: mv a3, s1 +; RV32IA-NEXT: .LBB179_8: # %atomicrmw.start +; RV32IA-NEXT: # in Loop: Header=BB179_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, .LBB179_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 }