llvm.org GIT mirror llvm / 2fdd5d3
[RISCV] Codegen for i8, i16, and i32 atomicrmw with RV32A Introduce a new RISCVExpandPseudoInsts pass to expand atomic pseudo-instructions after register allocation. This is necessary in order to ensure that register spills aren't introduced between LL and SC, thus breaking the forward progress guarantee for the operation. AArch64 does something similar for CmpXchg (though only at O0), and Mips is moving towards this approach (see D31287). See also [this mailing list post](http://lists.llvm.org/pipermail/llvm-dev/2016-May/099490.html) from James Knight, which summarises the issues with lowering to ll/sc in IR or pre-RA. See the [accompanying RFC thread](http://lists.llvm.org/pipermail/llvm-dev/2018-June/123993.html) for an overview of the lowering strategy. Differential Revision: https://reviews.llvm.org/D47882 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342534 91177308-0d34-0410-b5e6-96231b3b80d8 Alex Bradbury 1 year, 9 months ago
13 changed file(s) with 5065 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
162162 LLOnly, // Expand the (load) instruction into just a load-linked, which has
163163 // greater atomic guarantees than a normal load.
164164 CmpXChg, // Expand the instruction into cmpxchg; used by at least X86.
165 MaskedIntrinsic, // Use a target-specific intrinsic for the LL/SC loop.
165166 };
166167
167168 /// Enum that specifies when a multiplication should be expanded.
15591560 virtual Value *emitStoreConditional(IRBuilder<> &Builder, Value *Val,
15601561 Value *Addr, AtomicOrdering Ord) const {
15611562 llvm_unreachable("Store conditional unimplemented on this target");
1563 }
1564
1565 /// Perform a masked atomicrmw using a target-specific intrinsic. This
1566 /// represents the core LL/SC loop which will be lowered at a late stage by
1567 /// the backend.
1568 virtual Value *emitMaskedAtomicRMWIntrinsic(IRBuilder<> &Builder,
1569 AtomicRMWInst *AI,
1570 Value *AlignedAddr, Value *Incr,
1571 Value *Mask, Value *ShiftAmt,
1572 AtomicOrdering Ord) const {
1573 llvm_unreachable("Masked atomicrmw expansion unimplemented on this target");
15621574 }
15631575
15641576 /// Inserts in the IR a target-specific intrinsic specifying a fence.
10071007 include "llvm/IR/IntrinsicsBPF.td"
10081008 include "llvm/IR/IntrinsicsSystemZ.td"
10091009 include "llvm/IR/IntrinsicsWebAssembly.td"
1010 include "llvm/IR/IntrinsicsRISCV.td"
0 //===- IntrinsicsRISCV.td - Defines RISCV intrinsics -------*- tablegen -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines all of the RISCV-specific intrinsics.
10 //
11 //===----------------------------------------------------------------------===//
12
13 let TargetPrefix = "riscv" in {
14
15 //===----------------------------------------------------------------------===//
16 // Atomics
17
18 class MaskedAtomicRMW32Intrinsic
19 : Intrinsic<[llvm_i32_ty],
20 [llvm_anyptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
21 [IntrArgMemOnly, NoCapture<0>]>;
22
23 class MaskedAtomicRMW32WithSextIntrinsic
24 : Intrinsic<[llvm_i32_ty],
25 [llvm_anyptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
26 llvm_i32_ty],
27 [IntrArgMemOnly, NoCapture<0>]>;
28
29 def int_riscv_masked_atomicrmw_xchg_i32 : MaskedAtomicRMW32Intrinsic;
30 def int_riscv_masked_atomicrmw_add_i32 : MaskedAtomicRMW32Intrinsic;
31 def int_riscv_masked_atomicrmw_sub_i32 : MaskedAtomicRMW32Intrinsic;
32 def int_riscv_masked_atomicrmw_nand_i32 : MaskedAtomicRMW32Intrinsic;
33 def int_riscv_masked_atomicrmw_max_i32 : MaskedAtomicRMW32WithSextIntrinsic;
34 def int_riscv_masked_atomicrmw_min_i32 : MaskedAtomicRMW32WithSextIntrinsic;
35 def int_riscv_masked_atomicrmw_umax_i32 : MaskedAtomicRMW32Intrinsic;
36 def int_riscv_masked_atomicrmw_umin_i32 : MaskedAtomicRMW32Intrinsic;
37
38 } // TargetPrefix = "riscv"
8989 TargetLoweringBase::AtomicExpansionKind ExpansionKind);
9090 AtomicRMWInst *widenPartwordAtomicRMW(AtomicRMWInst *AI);
9191 void expandPartwordCmpXchg(AtomicCmpXchgInst *I);
92 void expandAtomicRMWToMaskedIntrinsic(AtomicRMWInst *AI);
9293
9394 AtomicCmpXchgInst *convertCmpXchgToIntegerType(AtomicCmpXchgInst *CI);
9495 static Value *insertRMWCmpXchgLoop(
410411 return expandAtomicLoadToLL(LI);
411412 case TargetLoweringBase::AtomicExpansionKind::CmpXChg:
412413 return expandAtomicLoadToCmpXchg(LI);
413 }
414 llvm_unreachable("Unhandled case in tryExpandAtomicLoad");
414 default:
415 llvm_unreachable("Unhandled case in tryExpandAtomicLoad");
416 }
415417 }
416418
417419 bool AtomicExpand::expandAtomicLoadToLL(LoadInst *LI) {
573575 }
574576 return true;
575577 }
578 case TargetLoweringBase::AtomicExpansionKind::MaskedIntrinsic: {
579 expandAtomicRMWToMaskedIntrinsic(AI);
580 return true;
581 }
576582 default:
577583 llvm_unreachable("Unhandled case in tryExpandAtomicRMW");
578584 }
661667 IRBuilder<> &Builder, Value *Loaded,
662668 Value *Shifted_Inc, Value *Inc,
663669 const PartwordMaskValues &PMV) {
670 // TODO: update to use
671 // https://graphics.stanford.edu/~seander/bithacks.html#MaskedMerge in order
672 // to merge bits from two values without requiring PMV.Inv_Mask.
664673 switch (Op) {
665674 case AtomicRMWInst::Xchg: {
666675 Value *Loaded_MaskOut = Builder.CreateAnd(Loaded, PMV.Inv_Mask);
911920
912921 I->replaceAllUsesWith(Loaded);
913922 I->eraseFromParent();
923 }
924
925 void AtomicExpand::expandAtomicRMWToMaskedIntrinsic(AtomicRMWInst *AI) {
926 IRBuilder<> Builder(AI);
927
928 PartwordMaskValues PMV =
929 createMaskInstrs(Builder, AI, AI->getType(), AI->getPointerOperand(),
930 TLI->getMinCmpXchgSizeInBits() / 8);
931
932 // The value operand must be sign-extended for signed min/max so that the
933 // target's signed comparison instructions can be used. Otherwise, just
934 // zero-ext.
935 Instruction::CastOps CastOp = Instruction::ZExt;
936 AtomicRMWInst::BinOp RMWOp = AI->getOperation();
937 if (RMWOp == AtomicRMWInst::Max || RMWOp == AtomicRMWInst::Min)
938 CastOp = Instruction::SExt;
939
940 Value *ValOperand_Shifted = Builder.CreateShl(
941 Builder.CreateCast(CastOp, AI->getValOperand(), PMV.WordType),
942 PMV.ShiftAmt, "ValOperand_Shifted");
943 Value *OldResult = TLI->emitMaskedAtomicRMWIntrinsic(
944 Builder, AI, PMV.AlignedAddr, ValOperand_Shifted, PMV.Mask, PMV.ShiftAmt,
945 AI->getOrdering());
946 Value *FinalOldResult = Builder.CreateTrunc(
947 Builder.CreateLShr(OldResult, PMV.ShiftAmt), PMV.ValueType);
948 AI->replaceAllUsesWith(FinalOldResult);
949 AI->eraseFromParent();
914950 }
915951
916952 Value *AtomicExpand::insertRMWLLSCLoop(
1414
1515 add_llvm_target(RISCVCodeGen
1616 RISCVAsmPrinter.cpp
17 RISCVExpandPseudoInsts.cpp
1718 RISCVFrameLowering.cpp
1819 RISCVInstrInfo.cpp
1920 RISCVISelDAGToDAG.cpp
1515 #define LLVM_LIB_TARGET_RISCV_RISCV_H
1616
1717 #include "MCTargetDesc/RISCVBaseInfo.h"
18 #include "llvm/Target/TargetMachine.h"
1819
1920 namespace llvm {
2021 class RISCVTargetMachine;
3536
3637 FunctionPass *createRISCVMergeBaseOffsetOptPass();
3738 void initializeRISCVMergeBaseOffsetOptPass(PassRegistry &);
39
40 FunctionPass *createRISCVExpandPseudoPass();
41 void initializeRISCVExpandPseudoPass(PassRegistry &);
3842 }
3943
4044 #endif
0 //===-- RISCVExpandPseudoInsts.cpp - Expand pseudo instructions -----------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains a pass that expands pseudo instructions into target
10 // instructions. This pass should be run after register allocation but before
11 // the post-regalloc scheduling pass.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "RISCV.h"
16 #include "RISCVInstrInfo.h"
17 #include "RISCVTargetMachine.h"
18
19 #include "llvm/CodeGen/LivePhysRegs.h"
20 #include "llvm/CodeGen/MachineFunctionPass.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22
23 using namespace llvm;
24
25 #define RISCV_EXPAND_PSEUDO_NAME "RISCV pseudo instruction expansion pass"
26
27 namespace {
28
29 class RISCVExpandPseudo : public MachineFunctionPass {
30 public:
31 const RISCVInstrInfo *TII;
32 static char ID;
33
34 RISCVExpandPseudo() : MachineFunctionPass(ID) {
35 initializeRISCVExpandPseudoPass(*PassRegistry::getPassRegistry());
36 }
37
38 bool runOnMachineFunction(MachineFunction &MF) override;
39
40 StringRef getPassName() const override { return RISCV_EXPAND_PSEUDO_NAME; }
41
42 private:
43 bool expandMBB(MachineBasicBlock &MBB);
44 bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
45 MachineBasicBlock::iterator &NextMBBI);
46 bool expandAtomicBinOp(MachineBasicBlock &MBB,
47 MachineBasicBlock::iterator MBBI, AtomicRMWInst::BinOp,
48 bool IsMasked, int Width,
49 MachineBasicBlock::iterator &NextMBBI);
50 bool expandAtomicMinMaxOp(MachineBasicBlock &MBB,
51 MachineBasicBlock::iterator MBBI,
52 AtomicRMWInst::BinOp, bool IsMasked, int Width,
53 MachineBasicBlock::iterator &NextMBBI);
54 };
55
56 char RISCVExpandPseudo::ID = 0;
57
58 bool RISCVExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
59 TII = static_cast(MF.getSubtarget().getInstrInfo());
60 bool Modified = false;
61 for (auto &MBB : MF)
62 Modified |= expandMBB(MBB);
63 return Modified;
64 }
65
66 bool RISCVExpandPseudo::expandMBB(MachineBasicBlock &MBB) {
67 bool Modified = false;
68
69 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
70 while (MBBI != E) {
71 MachineBasicBlock::iterator NMBBI = std::next(MBBI);
72 Modified |= expandMI(MBB, MBBI, NMBBI);
73 MBBI = NMBBI;
74 }
75
76 return Modified;
77 }
78
79 bool RISCVExpandPseudo::expandMI(MachineBasicBlock &MBB,
80 MachineBasicBlock::iterator MBBI,
81 MachineBasicBlock::iterator &NextMBBI) {
82 switch (MBBI->getOpcode()) {
83 case RISCV::PseudoAtomicLoadNand32:
84 return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Nand, false, 32,
85 NextMBBI);
86 case RISCV::PseudoMaskedAtomicSwap32:
87 return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Xchg, true, 32,
88 NextMBBI);
89 case RISCV::PseudoMaskedAtomicLoadAdd32:
90 return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Add, true, 32, NextMBBI);
91 case RISCV::PseudoMaskedAtomicLoadSub32:
92 return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Sub, true, 32, NextMBBI);
93 case RISCV::PseudoMaskedAtomicLoadNand32:
94 return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Nand, true, 32,
95 NextMBBI);
96 case RISCV::PseudoMaskedAtomicLoadMax32:
97 return expandAtomicMinMaxOp(MBB, MBBI, AtomicRMWInst::Max, true, 32,
98 NextMBBI);
99 case RISCV::PseudoMaskedAtomicLoadMin32:
100 return expandAtomicMinMaxOp(MBB, MBBI, AtomicRMWInst::Min, true, 32,
101 NextMBBI);
102 case RISCV::PseudoMaskedAtomicLoadUMax32:
103 return expandAtomicMinMaxOp(MBB, MBBI, AtomicRMWInst::UMax, true, 32,
104 NextMBBI);
105 case RISCV::PseudoMaskedAtomicLoadUMin32:
106 return expandAtomicMinMaxOp(MBB, MBBI, AtomicRMWInst::UMin, true, 32,
107 NextMBBI);
108 }
109
110 return false;
111 }
112
113 static unsigned getLRForRMW32(AtomicOrdering Ordering) {
114 switch (Ordering) {
115 default:
116 llvm_unreachable("Unexpected AtomicOrdering");
117 case AtomicOrdering::Monotonic:
118 return RISCV::LR_W;
119 case AtomicOrdering::Acquire:
120 return RISCV::LR_W_AQ;
121 case AtomicOrdering::Release:
122 return RISCV::LR_W;
123 case AtomicOrdering::AcquireRelease:
124 return RISCV::LR_W_AQ;
125 case AtomicOrdering::SequentiallyConsistent:
126 return RISCV::LR_W_AQ_RL;
127 }
128 }
129
130 static unsigned getSCForRMW32(AtomicOrdering Ordering) {
131 switch (Ordering) {
132 default:
133 llvm_unreachable("Unexpected AtomicOrdering");
134 case AtomicOrdering::Monotonic:
135 return RISCV::SC_W;
136 case AtomicOrdering::Acquire:
137 return RISCV::SC_W;
138 case AtomicOrdering::Release:
139 return RISCV::SC_W_RL;
140 case AtomicOrdering::AcquireRelease:
141 return RISCV::SC_W_RL;
142 case AtomicOrdering::SequentiallyConsistent:
143 return RISCV::SC_W_AQ_RL;
144 }
145 }
146
147 static void doAtomicBinOpExpansion(const RISCVInstrInfo *TII, MachineInstr &MI,
148 DebugLoc DL, MachineBasicBlock *ThisMBB,
149 MachineBasicBlock *LoopMBB,
150 MachineBasicBlock *DoneMBB,
151 AtomicRMWInst::BinOp BinOp, int Width) {
152 assert(Width == 32 && "RV64 atomic expansion currently unsupported");
153 unsigned DestReg = MI.getOperand(0).getReg();
154 unsigned ScratchReg = MI.getOperand(1).getReg();
155 unsigned AddrReg = MI.getOperand(2).getReg();
156 unsigned IncrReg = MI.getOperand(3).getReg();
157 AtomicOrdering Ordering =
158 static_cast(MI.getOperand(4).getImm());
159
160 // .loop:
161 // lr.w dest, (addr)
162 // binop scratch, dest, val
163 // sc.w scratch, scratch, (addr)
164 // bnez scratch, loop
165 BuildMI(LoopMBB, DL, TII->get(getLRForRMW32(Ordering)), DestReg)
166 .addReg(AddrReg);
167 switch (BinOp) {
168 default:
169 llvm_unreachable("Unexpected AtomicRMW BinOp");
170 case AtomicRMWInst::Nand:
171 BuildMI(LoopMBB, DL, TII->get(RISCV::AND), ScratchReg)
172 .addReg(DestReg)
173 .addReg(IncrReg);
174 BuildMI(LoopMBB, DL, TII->get(RISCV::XORI), ScratchReg)
175 .addReg(ScratchReg)
176 .addImm(-1);
177 break;
178 }
179 BuildMI(LoopMBB, DL, TII->get(getSCForRMW32(Ordering)), ScratchReg)
180 .addReg(AddrReg)
181 .addReg(ScratchReg);
182 BuildMI(LoopMBB, DL, TII->get(RISCV::BNE))
183 .addReg(ScratchReg)
184 .addReg(RISCV::X0)
185 .addMBB(LoopMBB);
186 }
187
188 static void insertMaskedMerge(const RISCVInstrInfo *TII, DebugLoc DL,
189 MachineBasicBlock *MBB, unsigned DestReg,
190 unsigned OldValReg, unsigned NewValReg,
191 unsigned MaskReg, unsigned ScratchReg) {
192 assert(OldValReg != ScratchReg && "OldValReg and ScratchReg must be unique");
193 assert(OldValReg != MaskReg && "OldValReg and MaskReg must be unique");
194 assert(ScratchReg != MaskReg && "ScratchReg and MaskReg must be unique");
195
196 // We select bits from newval and oldval using:
197 // https://graphics.stanford.edu/~seander/bithacks.html#MaskedMerge
198 // r = oldval ^ ((oldval ^ newval) & masktargetdata);
199 BuildMI(MBB, DL, TII->get(RISCV::XOR), ScratchReg)
200 .addReg(OldValReg)
201 .addReg(NewValReg);
202 BuildMI(MBB, DL, TII->get(RISCV::AND), ScratchReg)
203 .addReg(ScratchReg)
204 .addReg(MaskReg);
205 BuildMI(MBB, DL, TII->get(RISCV::XOR), DestReg)
206 .addReg(OldValReg)
207 .addReg(ScratchReg);
208 }
209
210 static void doMaskedAtomicBinOpExpansion(
211 const RISCVInstrInfo *TII, MachineInstr &MI, DebugLoc DL,
212 MachineBasicBlock *ThisMBB, MachineBasicBlock *LoopMBB,
213 MachineBasicBlock *DoneMBB, AtomicRMWInst::BinOp BinOp, int Width) {
214 assert(Width == 32 && "RV64 atomic expansion currently unsupported");
215 unsigned DestReg = MI.getOperand(0).getReg();
216 unsigned ScratchReg = MI.getOperand(1).getReg();
217 unsigned AddrReg = MI.getOperand(2).getReg();
218 unsigned IncrReg = MI.getOperand(3).getReg();
219 unsigned MaskReg = MI.getOperand(4).getReg();
220 AtomicOrdering Ordering =
221 static_cast(MI.getOperand(5).getImm());
222
223 // .loop:
224 // lr.w destreg, (alignedaddr)
225 // binop scratch, destreg, incr
226 // xor scratch, destreg, scratch
227 // and scratch, scratch, masktargetdata
228 // xor scratch, destreg, scratch
229 // sc.w scratch, scratch, (alignedaddr)
230 // bnez scratch, loop
231 BuildMI(LoopMBB, DL, TII->get(getLRForRMW32(Ordering)), DestReg)
232 .addReg(AddrReg);
233 switch (BinOp) {
234 default:
235 llvm_unreachable("Unexpected AtomicRMW BinOp");
236 case AtomicRMWInst::Xchg:
237 BuildMI(LoopMBB, DL, TII->get(RISCV::ADD), ScratchReg)
238 .addReg(RISCV::X0)
239 .addReg(IncrReg);
240 break;
241 case AtomicRMWInst::Add:
242 BuildMI(LoopMBB, DL, TII->get(RISCV::ADD), ScratchReg)
243 .addReg(DestReg)
244 .addReg(IncrReg);
245 break;
246 case AtomicRMWInst::Sub:
247 BuildMI(LoopMBB, DL, TII->get(RISCV::SUB), ScratchReg)
248 .addReg(DestReg)
249 .addReg(IncrReg);
250 break;
251 case AtomicRMWInst::Nand:
252 BuildMI(LoopMBB, DL, TII->get(RISCV::AND), ScratchReg)
253 .addReg(DestReg)
254 .addReg(IncrReg);
255 BuildMI(LoopMBB, DL, TII->get(RISCV::XORI), ScratchReg)
256 .addReg(ScratchReg)
257 .addImm(-1);
258 break;
259 }
260
261 insertMaskedMerge(TII, DL, LoopMBB, ScratchReg, DestReg, ScratchReg, MaskReg,
262 ScratchReg);
263
264 BuildMI(LoopMBB, DL, TII->get(getSCForRMW32(Ordering)), ScratchReg)
265 .addReg(AddrReg)
266 .addReg(ScratchReg);
267 BuildMI(LoopMBB, DL, TII->get(RISCV::BNE))
268 .addReg(ScratchReg)
269 .addReg(RISCV::X0)
270 .addMBB(LoopMBB);
271 }
272
273 bool RISCVExpandPseudo::expandAtomicBinOp(
274 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
275 AtomicRMWInst::BinOp BinOp, bool IsMasked, int Width,
276 MachineBasicBlock::iterator &NextMBBI) {
277 MachineInstr &MI = *MBBI;
278 DebugLoc DL = MI.getDebugLoc();
279
280 MachineFunction *MF = MBB.getParent();
281 auto LoopMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
282 auto DoneMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
283
284 // Insert new MBBs.
285 MF->insert(++MBB.getIterator(), LoopMBB);
286 MF->insert(++LoopMBB->getIterator(), DoneMBB);
287
288 // Set up successors and transfer remaining instructions to DoneMBB.
289 LoopMBB->addSuccessor(LoopMBB);
290 LoopMBB->addSuccessor(DoneMBB);
291 DoneMBB->splice(DoneMBB->end(), &MBB, MI, MBB.end());
292 DoneMBB->transferSuccessors(&MBB);
293 MBB.addSuccessor(LoopMBB);
294
295 if (!IsMasked)
296 doAtomicBinOpExpansion(TII, MI, DL, &MBB, LoopMBB, DoneMBB, BinOp, Width);
297 else
298 doMaskedAtomicBinOpExpansion(TII, MI, DL, &MBB, LoopMBB, DoneMBB, BinOp,
299 Width);
300
301 NextMBBI = MBB.end();
302 MI.eraseFromParent();
303
304 LivePhysRegs LiveRegs;
305 computeAndAddLiveIns(LiveRegs, *LoopMBB);
306 computeAndAddLiveIns(LiveRegs, *DoneMBB);
307
308 return true;
309 }
310
311 static void insertSext(const RISCVInstrInfo *TII, DebugLoc DL,
312 MachineBasicBlock *MBB, unsigned ValReg,
313 unsigned ShamtReg) {
314 BuildMI(MBB, DL, TII->get(RISCV::SLL), ValReg)
315 .addReg(ValReg)
316 .addReg(ShamtReg);
317 BuildMI(MBB, DL, TII->get(RISCV::SRA), ValReg)
318 .addReg(ValReg)
319 .addReg(ShamtReg);
320 }
321
322 bool RISCVExpandPseudo::expandAtomicMinMaxOp(
323 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
324 AtomicRMWInst::BinOp BinOp, bool IsMasked, int Width,
325 MachineBasicBlock::iterator &NextMBBI) {
326 assert(IsMasked == true &&
327 "Should only need to expand masked atomic max/min");
328 assert(Width == 32 && "RV64 atomic expansion currently unsupported");
329
330 MachineInstr &MI = *MBBI;
331 DebugLoc DL = MI.getDebugLoc();
332 MachineFunction *MF = MBB.getParent();
333 auto LoopHeadMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
334 auto LoopIfBodyMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
335 auto LoopTailMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
336 auto DoneMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
337
338 // Insert new MBBs.
339 MF->insert(++MBB.getIterator(), LoopHeadMBB);
340 MF->insert(++LoopHeadMBB->getIterator(), LoopIfBodyMBB);
341 MF->insert(++LoopIfBodyMBB->getIterator(), LoopTailMBB);
342 MF->insert(++LoopTailMBB->getIterator(), DoneMBB);
343
344 // Set up successors and transfer remaining instructions to DoneMBB.
345 LoopHeadMBB->addSuccessor(LoopIfBodyMBB);
346 LoopHeadMBB->addSuccessor(LoopTailMBB);
347 LoopIfBodyMBB->addSuccessor(LoopTailMBB);
348 LoopTailMBB->addSuccessor(LoopHeadMBB);
349 LoopTailMBB->addSuccessor(DoneMBB);
350 DoneMBB->splice(DoneMBB->end(), &MBB, MI, MBB.end());
351 DoneMBB->transferSuccessors(&MBB);
352 MBB.addSuccessor(LoopHeadMBB);
353
354 unsigned DestReg = MI.getOperand(0).getReg();
355 unsigned Scratch1Reg = MI.getOperand(1).getReg();
356 unsigned Scratch2Reg = MI.getOperand(2).getReg();
357 unsigned AddrReg = MI.getOperand(3).getReg();
358 unsigned IncrReg = MI.getOperand(4).getReg();
359 unsigned MaskReg = MI.getOperand(5).getReg();
360 bool IsSigned = BinOp == AtomicRMWInst::Min || BinOp == AtomicRMWInst::Max;
361 AtomicOrdering Ordering =
362 static_cast(MI.getOperand(IsSigned ? 7 : 6).getImm());
363
364 //
365 // .loophead:
366 // lr.w destreg, (alignedaddr)
367 // and scratch2, destreg, mask
368 // mv scratch1, destreg
369 // [sext scratch2 if signed min/max]
370 // ifnochangeneeded scratch2, incr, .looptail
371 BuildMI(LoopHeadMBB, DL, TII->get(getLRForRMW32(Ordering)), DestReg)
372 .addReg(AddrReg);
373 BuildMI(LoopHeadMBB, DL, TII->get(RISCV::AND), Scratch2Reg)
374 .addReg(DestReg)
375 .addReg(MaskReg);
376 BuildMI(LoopHeadMBB, DL, TII->get(RISCV::ADDI), Scratch1Reg)
377 .addReg(DestReg)
378 .addImm(0);
379
380 switch (BinOp) {
381 default:
382 llvm_unreachable("Unexpected AtomicRMW BinOp");
383 case AtomicRMWInst::Max: {
384 insertSext(TII, DL, LoopHeadMBB, Scratch2Reg, MI.getOperand(6).getReg());
385 BuildMI(LoopHeadMBB, DL, TII->get(RISCV::BGE))
386 .addReg(Scratch2Reg)
387 .addReg(IncrReg)
388 .addMBB(LoopTailMBB);
389 break;
390 }
391 case AtomicRMWInst::Min: {
392 insertSext(TII, DL, LoopHeadMBB, Scratch2Reg, MI.getOperand(6).getReg());
393 BuildMI(LoopHeadMBB, DL, TII->get(RISCV::BGE))
394 .addReg(IncrReg)
395 .addReg(Scratch2Reg)
396 .addMBB(LoopTailMBB);
397 break;
398 }
399 case AtomicRMWInst::UMax:
400 BuildMI(LoopHeadMBB, DL, TII->get(RISCV::BGEU))
401 .addReg(Scratch2Reg)
402 .addReg(IncrReg)
403 .addMBB(LoopTailMBB);
404 break;
405 case AtomicRMWInst::UMin:
406 BuildMI(LoopHeadMBB, DL, TII->get(RISCV::BGEU))
407 .addReg(IncrReg)
408 .addReg(Scratch2Reg)
409 .addMBB(LoopTailMBB);
410 break;
411 }
412
413 // .loopifbody:
414 // xor scratch1, destreg, incr
415 // and scratch1, scratch1, mask
416 // xor scratch1, destreg, scratch1
417 insertMaskedMerge(TII, DL, LoopIfBodyMBB, Scratch1Reg, DestReg, IncrReg,
418 MaskReg, Scratch1Reg);
419
420 // .looptail:
421 // sc.w scratch1, scratch1, (addr)
422 // bnez scratch1, loop
423 BuildMI(LoopTailMBB, DL, TII->get(getSCForRMW32(Ordering)), Scratch1Reg)
424 .addReg(AddrReg)
425 .addReg(Scratch1Reg);
426 BuildMI(LoopTailMBB, DL, TII->get(RISCV::BNE))
427 .addReg(Scratch1Reg)
428 .addReg(RISCV::X0)
429 .addMBB(LoopHeadMBB);
430
431 NextMBBI = MBB.end();
432 MI.eraseFromParent();
433
434 LivePhysRegs LiveRegs;
435 computeAndAddLiveIns(LiveRegs, *LoopHeadMBB);
436 computeAndAddLiveIns(LiveRegs, *LoopIfBodyMBB);
437 computeAndAddLiveIns(LiveRegs, *LoopTailMBB);
438 computeAndAddLiveIns(LiveRegs, *DoneMBB);
439
440 return true;
441 }
442
443 } // end of anonymous namespace
444
445 INITIALIZE_PASS(RISCVExpandPseudo, "riscv-expand-pseudo",
446 RISCV_EXPAND_PSEUDO_NAME, false, false)
447 namespace llvm {
448
449 FunctionPass *createRISCVExpandPseudoPass() { return new RISCVExpandPseudo(); }
450
451 } // end of namespace llvm
136136 setOperationAction(ISD::BlockAddress, XLenVT, Custom);
137137 setOperationAction(ISD::ConstantPool, XLenVT, Custom);
138138
139 if (Subtarget.hasStdExtA())
139 if (Subtarget.hasStdExtA()) {
140140 setMaxAtomicSizeInBitsSupported(Subtarget.getXLen());
141 else
141 setMinCmpXchgSizeInBits(32);
142 } else {
142143 setMaxAtomicSizeInBitsSupported(0);
144 }
143145
144146 setBooleanContents(ZeroOrOneBooleanContent);
145147
157159 if (!VT.isVector())
158160 return getPointerTy(DL);
159161 return VT.changeVectorElementTypeToInteger();
162 }
163
164 bool RISCVTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
165 const CallInst &I,
166 MachineFunction &MF,
167 unsigned Intrinsic) const {
168 switch (Intrinsic) {
169 default:
170 return false;
171 case Intrinsic::riscv_masked_atomicrmw_xchg_i32:
172 case Intrinsic::riscv_masked_atomicrmw_add_i32:
173 case Intrinsic::riscv_masked_atomicrmw_sub_i32:
174 case Intrinsic::riscv_masked_atomicrmw_nand_i32:
175 case Intrinsic::riscv_masked_atomicrmw_max_i32:
176 case Intrinsic::riscv_masked_atomicrmw_min_i32:
177 case Intrinsic::riscv_masked_atomicrmw_umax_i32:
178 case Intrinsic::riscv_masked_atomicrmw_umin_i32:
179 PointerType *PtrTy = cast(I.getArgOperand(0)->getType());
180 Info.opc = ISD::INTRINSIC_W_CHAIN;
181 Info.memVT = MVT::getVT(PtrTy->getElementType());
182 Info.ptrVal = I.getArgOperand(0);
183 Info.offset = 0;
184 Info.align = 4;
185 Info.flags = MachineMemOperand::MOLoad | MachineMemOperand::MOStore |
186 MachineMemOperand::MOVolatile;
187 return true;
188 }
160189 }
161190
162191 bool RISCVTargetLowering::isLegalAddressingMode(const DataLayout &DL,
15951624 return Builder.CreateFence(AtomicOrdering::Acquire);
15961625 return nullptr;
15971626 }
1627
1628 TargetLowering::AtomicExpansionKind
1629 RISCVTargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
1630 unsigned Size = AI->getType()->getPrimitiveSizeInBits();
1631 if (Size == 8 || Size == 16)
1632 return AtomicExpansionKind::MaskedIntrinsic;
1633 return AtomicExpansionKind::None;
1634 }
1635
1636 static Intrinsic::ID
1637 getIntrinsicForMaskedAtomicRMWBinOp32(AtomicRMWInst::BinOp BinOp) {
1638 switch (BinOp) {
1639 default:
1640 llvm_unreachable("Unexpected AtomicRMW BinOp");
1641 case AtomicRMWInst::Xchg:
1642 return Intrinsic::riscv_masked_atomicrmw_xchg_i32;
1643 case AtomicRMWInst::Add:
1644 return Intrinsic::riscv_masked_atomicrmw_add_i32;
1645 case AtomicRMWInst::Sub:
1646 return Intrinsic::riscv_masked_atomicrmw_sub_i32;
1647 case AtomicRMWInst::Nand:
1648 return Intrinsic::riscv_masked_atomicrmw_nand_i32;
1649 case AtomicRMWInst::Max:
1650 return Intrinsic::riscv_masked_atomicrmw_max_i32;
1651 case AtomicRMWInst::Min:
1652 return Intrinsic::riscv_masked_atomicrmw_min_i32;
1653 case AtomicRMWInst::UMax:
1654 return Intrinsic::riscv_masked_atomicrmw_umax_i32;
1655 case AtomicRMWInst::UMin:
1656 return Intrinsic::riscv_masked_atomicrmw_umin_i32;
1657 }
1658 }
1659
1660 Value *RISCVTargetLowering::emitMaskedAtomicRMWIntrinsic(
1661 IRBuilder<> &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr,
1662 Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const {
1663 Value *Ordering = Builder.getInt32(static_cast(AI->getOrdering()));
1664 Type *Tys[] = {AlignedAddr->getType()};
1665 Function *LrwOpScwLoop = Intrinsic::getDeclaration(
1666 AI->getModule(),
1667 getIntrinsicForMaskedAtomicRMWBinOp32(AI->getOperation()), Tys);
1668
1669 // Must pass the shift amount needed to sign extend the loaded value prior
1670 // to performing a signed comparison for min/max. ShiftAmt is the number of
1671 // bits to shift the value into position. Pass XLen-ShiftAmt-ValWidth, which
1672 // is the number of bits to left+right shift the value in order to
1673 // sign-extend.
1674 if (AI->getOperation() == AtomicRMWInst::Min ||
1675 AI->getOperation() == AtomicRMWInst::Max) {
1676 const DataLayout &DL = AI->getModule()->getDataLayout();
1677 unsigned ValWidth =
1678 DL.getTypeStoreSizeInBits(AI->getValOperand()->getType());
1679 Value *SextShamt = Builder.CreateSub(
1680 Builder.getInt32(Subtarget.getXLen() - ValWidth), ShiftAmt);
1681 return Builder.CreateCall(LrwOpScwLoop,
1682 {AlignedAddr, Incr, Mask, SextShamt, Ordering});
1683 }
1684
1685 return Builder.CreateCall(LrwOpScwLoop, {AlignedAddr, Incr, Mask, Ordering});
1686 }
4242 explicit RISCVTargetLowering(const TargetMachine &TM,
4343 const RISCVSubtarget &STI);
4444
45 bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I,
46 MachineFunction &MF,
47 unsigned Intrinsic) const override;
4548 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty,
4649 unsigned AS,
4750 Instruction *I = nullptr) const override;
114117 bool IsEligibleForTailCallOptimization(CCState &CCInfo,
115118 CallLoweringInfo &CLI, MachineFunction &MF,
116119 const SmallVector &ArgLocs) const;
120
121 TargetLowering::AtomicExpansionKind
122 shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override;
123 virtual Value *emitMaskedAtomicRMWIntrinsic(
124 IRBuilder<> &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr,
125 Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const override;
117126 };
118127 }
119128
602602
603603 /// Generic pattern classes
604604
605 class PatGprGprR Inst>
605 class PatGprGpr Inst>
606606 : Pat<(OpNode GPR:$rs1, GPR:$rs2), (Inst GPR:$rs1, GPR:$rs2)>;
607607 class PatGprSimm12
608608 : Pat<(OpNode GPR:$rs1, simm12:$imm12), (Inst GPR:$rs1, simm12:$imm12)>;
104104 defm : AtomicStPat;
105105 defm : AtomicStPat;
106106 defm : AtomicStPat;
107
108 /// AMOs
109
110 multiclass AMOPat {
111 def : PatGprGpr(AtomicOp#"_monotonic"),
112 !cast(BaseInst)>;
113 def : PatGprGpr(AtomicOp#"_acquire"),
114 !cast(BaseInst#"_AQ")>;
115 def : PatGprGpr(AtomicOp#"_release"),
116 !cast(BaseInst#"_RL")>;
117 def : PatGprGpr(AtomicOp#"_acq_rel"),
118 !cast(BaseInst#"_AQ_RL")>;
119 def : PatGprGpr(AtomicOp#"_seq_cst"),
120 !cast(BaseInst#"_AQ_RL")>;
121 }
122
123 defm : AMOPat<"atomic_swap_32", "AMOSWAP_W">;
124 defm : AMOPat<"atomic_load_add_32", "AMOADD_W">;
125 defm : AMOPat<"atomic_load_and_32", "AMOAND_W">;
126 defm : AMOPat<"atomic_load_or_32", "AMOOR_W">;
127 defm : AMOPat<"atomic_load_xor_32", "AMOXOR_W">;
128 defm : AMOPat<"atomic_load_max_32", "AMOMAX_W">;
129 defm : AMOPat<"atomic_load_min_32", "AMOMIN_W">;
130 defm : AMOPat<"atomic_load_umax_32", "AMOMAXU_W">;
131 defm : AMOPat<"atomic_load_umin_32", "AMOMINU_W">;
132
133 def : Pat<(atomic_load_sub_32_monotonic GPR:$addr, GPR:$incr),
134 (AMOADD_W GPR:$addr, (SUB X0, GPR:$incr))>;
135 def : Pat<(atomic_load_sub_32_acquire GPR:$addr, GPR:$incr),
136 (AMOADD_W_AQ GPR:$addr, (SUB X0, GPR:$incr))>;
137 def : Pat<(atomic_load_sub_32_release GPR:$addr, GPR:$incr),
138 (AMOADD_W_RL GPR:$addr, (SUB X0, GPR:$incr))>;
139 def : Pat<(atomic_load_sub_32_acq_rel GPR:$addr, GPR:$incr),
140 (AMOADD_W_AQ_RL GPR:$addr, (SUB X0, GPR:$incr))>;
141 def : Pat<(atomic_load_sub_32_seq_cst GPR:$addr, GPR:$incr),
142 (AMOADD_W_AQ_RL GPR:$addr, (SUB X0, GPR:$incr))>;
143
144 /// Pseudo AMOs
145
146 class PseudoAMO : Pseudo<(outs GPR:$res, GPR:$scratch),
147 (ins GPR:$addr, GPR:$incr, i32imm:$ordering), []> {
148 let Constraints = "@earlyclobber $res,@earlyclobber $scratch";
149 let mayLoad = 1;
150 let mayStore = 1;
151 let hasSideEffects = 0;
152 }
153
154 def PseudoAtomicLoadNand32 : PseudoAMO;
155 // Ordering constants must be kept in sync with the AtomicOrdering enum in
156 // AtomicOrdering.h.
157 def : Pat<(atomic_load_nand_32_monotonic GPR:$addr, GPR:$incr),
158 (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 2)>;
159 def : Pat<(atomic_load_nand_32_acquire GPR:$addr, GPR:$incr),
160 (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 4)>;
161 def : Pat<(atomic_load_nand_32_release GPR:$addr, GPR:$incr),
162 (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 5)>;
163 def : Pat<(atomic_load_nand_32_acq_rel GPR:$addr, GPR:$incr),
164 (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 6)>;
165 def : Pat<(atomic_load_nand_32_seq_cst GPR:$addr, GPR:$incr),
166 (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 7)>;
167
168 class PseudoMaskedAMO
169 : Pseudo<(outs GPR:$res, GPR:$scratch),
170 (ins GPR:$addr, GPR:$incr, GPR:$mask, i32imm:$ordering), []> {
171 let Constraints = "@earlyclobber $res,@earlyclobber $scratch";
172 let mayLoad = 1;
173 let mayStore = 1;
174 let hasSideEffects = 0;
175 }
176
177 class PseudoMaskedAMOMinMax
178 : Pseudo<(outs GPR:$res, GPR:$scratch1, GPR:$scratch2),
179 (ins GPR:$addr, GPR:$incr, GPR:$mask, i32imm:$sextshamt,
180 i32imm:$ordering), []> {
181 let Constraints = "@earlyclobber $res,@earlyclobber $scratch1,"
182 "@earlyclobber $scratch2";
183 let mayLoad = 1;
184 let mayStore = 1;
185 let hasSideEffects = 0;
186 }
187
188 class PseudoMaskedAMOUMinUMax
189 : Pseudo<(outs GPR:$res, GPR:$scratch1, GPR:$scratch2),
190 (ins GPR:$addr, GPR:$incr, GPR:$mask, i32imm:$ordering), []> {
191 let Constraints = "@earlyclobber $res,@earlyclobber $scratch1,"
192 "@earlyclobber $scratch2";
193 let mayLoad = 1;
194 let mayStore = 1;
195 let hasSideEffects = 0;
196 }
197
198 class PseudoMaskedAMOPat
199 : Pat<(intrin GPR:$addr, GPR:$incr, GPR:$mask, imm:$ordering),
200 (AMOInst GPR:$addr, GPR:$incr, GPR:$mask, imm:$ordering)>;
201
202 class PseudoMaskedAMOMinMaxPat
203 : Pat<(intrin GPR:$addr, GPR:$incr, GPR:$mask, GPR:$shiftamt,
204 imm:$ordering),
205 (AMOInst GPR:$addr, GPR:$incr, GPR:$mask, GPR:$shiftamt,
206 imm:$ordering)>;
207
208 def PseudoMaskedAtomicSwap32 : PseudoMaskedAMO;
209 def : PseudoMaskedAMOPat
210 PseudoMaskedAtomicSwap32>;
211 def PseudoMaskedAtomicLoadAdd32 : PseudoMaskedAMO;
212 def : PseudoMaskedAMOPat
213 PseudoMaskedAtomicLoadAdd32>;
214 def PseudoMaskedAtomicLoadSub32 : PseudoMaskedAMO;
215 def : PseudoMaskedAMOPat
216 PseudoMaskedAtomicLoadSub32>;
217 def PseudoMaskedAtomicLoadNand32 : PseudoMaskedAMO;
218 def : PseudoMaskedAMOPat
219 PseudoMaskedAtomicLoadNand32>;
220 def PseudoMaskedAtomicLoadMax32 : PseudoMaskedAMOMinMax;
221 def : PseudoMaskedAMOMinMaxPat
222 PseudoMaskedAtomicLoadMax32>;
223 def PseudoMaskedAtomicLoadMin32 : PseudoMaskedAMOMinMax;
224 def : PseudoMaskedAMOMinMaxPat
225 PseudoMaskedAtomicLoadMin32>;
226 def PseudoMaskedAtomicLoadUMax32 : PseudoMaskedAMOUMinUMax;
227 def : PseudoMaskedAMOPat
228 PseudoMaskedAtomicLoadUMax32>;
229 def PseudoMaskedAtomicLoadUMin32 : PseudoMaskedAMOUMinUMax;
230 def : PseudoMaskedAMOPat
231 PseudoMaskedAtomicLoadUMin32>;
107232 } // Predicates = [HasStdExtA]
2626 extern "C" void LLVMInitializeRISCVTarget() {
2727 RegisterTargetMachine X(getTheRISCV32Target());
2828 RegisterTargetMachine Y(getTheRISCV64Target());
29 auto PR = PassRegistry::getPassRegistry();
30 initializeRISCVExpandPseudoPass(*PR);
2931 }
3032
3133 static std::string computeDataLayout(const Triple &TT) {
7779 void addIRPasses() override;
7880 bool addInstSelector() override;
7981 void addPreEmitPass() override;
82 void addPreEmitPass2() override;
8083 void addPreRegAlloc() override;
8184 };
8285 }
98101
99102 void RISCVPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); }
100103
104 void RISCVPassConfig::addPreEmitPass2() {
105 // Schedule the expansion of AMOs at the last possible moment, avoiding the
106 // possibility for other passes to break the requirements for forward
107 // progress in the LR/SC block.
108 addPass(createRISCVExpandPseudoPass());
109 }
110
101111 void RISCVPassConfig::addPreRegAlloc() {
102112 addPass(createRISCVMergeBaseOffsetOptPass());
103113 }
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
11 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
22 ; RUN: | FileCheck -check-prefix=RV32I %s
3 ; RUN: llc -mtriple=riscv32 -mattr=+a -verify-machineinstrs < %s \
4 ; RUN: | FileCheck -check-prefix=RV32IA %s
35
46 define i8 @atomicrmw_xchg_i8_monotonic(i8* %a, i8 %b) {
57 ; RV32I-LABEL: atomicrmw_xchg_i8_monotonic:
1113 ; RV32I-NEXT: lw ra, 12(sp)
1214 ; RV32I-NEXT: addi sp, sp, 16
1315 ; RV32I-NEXT: ret
16 ;
17 ; RV32IA-LABEL: atomicrmw_xchg_i8_monotonic:
18 ; RV32IA: # %bb.0:
19 ; RV32IA-NEXT: slli a2, a0, 3
20 ; RV32IA-NEXT: andi a2, a2, 24
21 ; RV32IA-NEXT: addi a3, zero, 255
22 ; RV32IA-NEXT: sll a3, a3, a2
23 ; RV32IA-NEXT: andi a1, a1, 255
24 ; RV32IA-NEXT: sll a1, a1, a2
25 ; RV32IA-NEXT: andi a0, a0, -4
26 ; RV32IA-NEXT: .LBB0_1: # =>This Inner Loop Header: Depth=1
27 ; RV32IA-NEXT: lr.w a4, (a0)
28 ; RV32IA-NEXT: add a5, zero, a1
29 ; RV32IA-NEXT: xor a5, a4, a5
30 ; RV32IA-NEXT: and a5, a5, a3
31 ; RV32IA-NEXT: xor a5, a4, a5
32 ; RV32IA-NEXT: sc.w a5, a5, (a0)
33 ; RV32IA-NEXT: bnez a5, .LBB0_1
34 ; RV32IA-NEXT: # %bb.2:
35 ; RV32IA-NEXT: srl a0, a4, a2
36 ; RV32IA-NEXT: ret
1437 %1 = atomicrmw xchg i8* %a, i8 %b monotonic
1538 ret i8 %1
1639 }
2548 ; RV32I-NEXT: lw ra, 12(sp)
2649 ; RV32I-NEXT: addi sp, sp, 16
2750 ; RV32I-NEXT: ret
51 ;
52 ; RV32IA-LABEL: atomicrmw_xchg_i8_acquire:
53 ; RV32IA: # %bb.0:
54 ; RV32IA-NEXT: slli a2, a0, 3
55 ; RV32IA-NEXT: andi a2, a2, 24
56 ; RV32IA-NEXT: addi a3, zero, 255
57 ; RV32IA-NEXT: sll a3, a3, a2
58 ; RV32IA-NEXT: andi a1, a1, 255
59 ; RV32IA-NEXT: sll a1, a1, a2
60 ; RV32IA-NEXT: andi a0, a0, -4
61 ; RV32IA-NEXT: .LBB1_1: # =>This Inner Loop Header: Depth=1
62 ; RV32IA-NEXT: lr.w.aq a4, (a0)
63 ; RV32IA-NEXT: add a5, zero, a1
64 ; RV32IA-NEXT: xor a5, a4, a5
65 ; RV32IA-NEXT: and a5, a5, a3
66 ; RV32IA-NEXT: xor a5, a4, a5
67 ; RV32IA-NEXT: sc.w a5, a5, (a0)
68 ; RV32IA-NEXT: bnez a5, .LBB1_1
69 ; RV32IA-NEXT: # %bb.2:
70 ; RV32IA-NEXT: srl a0, a4, a2
71 ; RV32IA-NEXT: ret
2872 %1 = atomicrmw xchg i8* %a, i8 %b acquire
2973 ret i8 %1
3074 }
3983 ; RV32I-NEXT: lw ra, 12(sp)
4084 ; RV32I-NEXT: addi sp, sp, 16
4185 ; RV32I-NEXT: ret
86 ;
87 ; RV32IA-LABEL: atomicrmw_xchg_i8_release:
88 ; RV32IA: # %bb.0:
89 ; RV32IA-NEXT: slli a2, a0, 3
90 ; RV32IA-NEXT: andi a2, a2, 24
91 ; RV32IA-NEXT: addi a3, zero, 255
92 ; RV32IA-NEXT: sll a3, a3, a2
93 ; RV32IA-NEXT: andi a1, a1, 255
94 ; RV32IA-NEXT: sll a1, a1, a2
95 ; RV32IA-NEXT: andi a0, a0, -4
96 ; RV32IA-NEXT: .LBB2_1: # =>This Inner Loop Header: Depth=1
97 ; RV32IA-NEXT: lr.w a4, (a0)
98 ; RV32IA-NEXT: add a5, zero, a1
99 ; RV32IA-NEXT: xor a5, a4, a5
100 ; RV32IA-NEXT: and a5, a5, a3
101 ; RV32IA-NEXT: xor a5, a4, a5
102 ; RV32IA-NEXT: sc.w.rl a5, a5, (a0)
103 ; RV32IA-NEXT: bnez a5, .LBB2_1
104 ; RV32IA-NEXT: # %bb.2:
105 ; RV32IA-NEXT: srl a0, a4, a2
106 ; RV32IA-NEXT: ret
42107 %1 = atomicrmw xchg i8* %a, i8 %b release
43108 ret i8 %1
44109 }
53118 ; RV32I-NEXT: lw ra, 12(sp)
54119 ; RV32I-NEXT: addi sp, sp, 16
55120 ; RV32I-NEXT: ret
121 ;
122 ; RV32IA-LABEL: atomicrmw_xchg_i8_acq_rel:
123 ; RV32IA: # %bb.0:
124 ; RV32IA-NEXT: slli a2, a0, 3
125 ; RV32IA-NEXT: andi a2, a2, 24
126 ; RV32IA-NEXT: addi a3, zero, 255
127 ; RV32IA-NEXT: sll a3, a3, a2
128 ; RV32IA-NEXT: andi a1, a1, 255
129 ; RV32IA-NEXT: sll a1, a1, a2
130 ; RV32IA-NEXT: andi a0, a0, -4
131 ; RV32IA-NEXT: .LBB3_1: # =>This Inner Loop Header: Depth=1
132 ; RV32IA-NEXT: lr.w.aq a4, (a0)
133 ; RV32IA-NEXT: add a5, zero, a1
134 ; RV32IA-NEXT: xor a5, a4, a5
135 ; RV32IA-NEXT: and a5, a5, a3
136 ; RV32IA-NEXT: xor a5, a4, a5
137 ; RV32IA-NEXT: sc.w.rl a5, a5, (a0)
138 ; RV32IA-NEXT: bnez a5, .LBB3_1
139 ; RV32IA-NEXT: # %bb.2:
140 ; RV32IA-NEXT: srl a0, a4, a2
141 ; RV32IA-NEXT: ret
56142 %1 = atomicrmw xchg i8* %a, i8 %b acq_rel
57143 ret i8 %1
58144 }
67153 ; RV32I-NEXT: lw ra, 12(sp)
68154 ; RV32I-NEXT: addi sp, sp, 16
69155 ; RV32I-NEXT: ret
156 ;
157 ; RV32IA-LABEL: atomicrmw_xchg_i8_seq_cst:
158 ; RV32IA: # %bb.0:
159 ; RV32IA-NEXT: slli a2, a0, 3
160 ; RV32IA-NEXT: andi a2, a2, 24
161 ; RV32IA-NEXT: addi a3, zero, 255
162 ; RV32IA-NEXT: sll a3, a3, a2
163 ; RV32IA-NEXT: andi a1, a1, 255
164 ; RV32IA-NEXT: sll a1, a1, a2
165 ; RV32IA-NEXT: andi a0, a0, -4
166 ; RV32IA-NEXT: .LBB4_1: # =>This Inner Loop Header: Depth=1
167 ; RV32IA-NEXT: lr.w.aqrl a4, (a0)
168 ; RV32IA-NEXT: add a5, zero, a1
169 ; RV32IA-NEXT: xor a5, a4, a5
170 ; RV32IA-NEXT: and a5, a5, a3
171 ; RV32IA-NEXT: xor a5, a4, a5
172 ; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0)
173 ; RV32IA-NEXT: bnez a5, .LBB4_1
174 ; RV32IA-NEXT: # %bb.2:
175 ; RV32IA-NEXT: srl a0, a4, a2
176 ; RV32IA-NEXT: ret
70177 %1 = atomicrmw xchg i8* %a, i8 %b seq_cst
71178 ret i8 %1
72179 }
81188 ; RV32I-NEXT: lw ra, 12(sp)
82189 ; RV32I-NEXT: addi sp, sp, 16
83190 ; RV32I-NEXT: ret
191 ;
192 ; RV32IA-LABEL: atomicrmw_add_i8_monotonic:
193 ; RV32IA: # %bb.0:
194 ; RV32IA-NEXT: slli a2, a0, 3
195 ; RV32IA-NEXT: andi a2, a2, 24
196 ; RV32IA-NEXT: addi a3, zero, 255
197 ; RV32IA-NEXT: sll a3, a3, a2
198 ; RV32IA-NEXT: andi a1, a1, 255
199 ; RV32IA-NEXT: sll a1, a1, a2
200 ; RV32IA-NEXT: andi a0, a0, -4
201 ; RV32IA-NEXT: .LBB5_1: # =>This Inner Loop Header: Depth=1
202 ; RV32IA-NEXT: lr.w a4, (a0)
203 ; RV32IA-NEXT: add a5, a4, a1
204 ; RV32IA-NEXT: xor a5, a4, a5
205 ; RV32IA-NEXT: and a5, a5, a3
206 ; RV32IA-NEXT: xor a5, a4, a5
207 ; RV32IA-NEXT: sc.w a5, a5, (a0)
208 ; RV32IA-NEXT: bnez a5, .LBB5_1
209 ; RV32IA-NEXT: # %bb.2:
210 ; RV32IA-NEXT: srl a0, a4, a2
211 ; RV32IA-NEXT: ret
84212 %1 = atomicrmw add i8* %a, i8 %b monotonic
85213 ret i8 %1
86214 }
95223 ; RV32I-NEXT: lw ra, 12(sp)
96224 ; RV32I-NEXT: addi sp, sp, 16
97225 ; RV32I-NEXT: ret
226 ;
227 ; RV32IA-LABEL: atomicrmw_add_i8_acquire:
228 ; RV32IA: # %bb.0:
229 ; RV32IA-NEXT: slli a2, a0, 3
230 ; RV32IA-NEXT: andi a2, a2, 24
231 ; RV32IA-NEXT: addi a3, zero, 255
232 ; RV32IA-NEXT: sll a3, a3, a2
233 ; RV32IA-NEXT: andi a1, a1, 255
234 ; RV32IA-NEXT: sll a1, a1, a2
235 ; RV32IA-NEXT: andi a0, a0, -4
236 ; RV32IA-NEXT: .LBB6_1: # =>This Inner Loop Header: Depth=1
237 ; RV32IA-NEXT: lr.w.aq a4, (a0)
238 ; RV32IA-NEXT: add a5, a4, a1
239 ; RV32IA-NEXT: xor a5, a4, a5
240 ; RV32IA-NEXT: and a5, a5, a3
241 ; RV32IA-NEXT: xor a5, a4, a5
242 ; RV32IA-NEXT: sc.w a5, a5, (a0)
243 ; RV32IA-NEXT: bnez a5, .LBB6_1
244 ; RV32IA-NEXT: # %bb.2:
245 ; RV32IA-NEXT: srl a0, a4, a2
246 ; RV32IA-NEXT: ret
98247 %1 = atomicrmw add i8* %a, i8 %b acquire
99248 ret i8 %1
100249 }
109258 ; RV32I-NEXT: lw ra, 12(sp)
110259 ; RV32I-NEXT: addi sp, sp, 16
111260 ; RV32I-NEXT: ret
261 ;
262 ; RV32IA-LABEL: atomicrmw_add_i8_release:
263 ; RV32IA: # %bb.0:
264 ; RV32IA-NEXT: slli a2, a0, 3
265 ; RV32IA-NEXT: andi a2, a2, 24
266 ; RV32IA-NEXT: addi a3, zero, 255
267 ; RV32IA-NEXT: sll a3, a3, a2
268 ; RV32IA-NEXT: andi a1, a1, 255
269 ; RV32IA-NEXT: sll a1, a1, a2
270 ; RV32IA-NEXT: andi a0, a0, -4
271 ; RV32IA-NEXT: .LBB7_1: # =>This Inner Loop Header: Depth=1
272 ; RV32IA-NEXT: lr.w a4, (a0)
273 ; RV32IA-NEXT: add a5, a4, a1
274 ; RV32IA-NEXT: xor a5, a4, a5
275 ; RV32IA-NEXT: and a5, a5, a3
276 ; RV32IA-NEXT: xor a5, a4, a5
277 ; RV32IA-NEXT: sc.w.rl a5, a5, (a0)
278 ; RV32IA-NEXT: bnez a5, .LBB7_1
279 ; RV32IA-NEXT: # %bb.2:
280 ; RV32IA-NEXT: srl a0, a4, a2
281 ; RV32IA-NEXT: ret
112282 %1 = atomicrmw add i8* %a, i8 %b release
113283 ret i8 %1
114284 }
123293 ; RV32I-NEXT: lw ra, 12(sp)
124294 ; RV32I-NEXT: addi sp, sp, 16
125295 ; RV32I-NEXT: ret
296 ;
297 ; RV32IA-LABEL: atomicrmw_add_i8_acq_rel:
298 ; RV32IA: # %bb.0:
299 ; RV32IA-NEXT: slli a2, a0, 3
300 ; RV32IA-NEXT: andi a2, a2, 24
301 ; RV32IA-NEXT: addi a3, zero, 255
302 ; RV32IA-NEXT: sll a3, a3, a2
303 ; RV32IA-NEXT: andi a1, a1, 255
304 ; RV32IA-NEXT: sll a1, a1, a2
305 ; RV32IA-NEXT: andi a0, a0, -4
306 ; RV32IA-NEXT: .LBB8_1: # =>This Inner Loop Header: Depth=1
307 ; RV32IA-NEXT: lr.w.aq a4, (a0)
308 ; RV32IA-NEXT: add a5, a4, a1
309 ; RV32IA-NEXT: xor a5, a4, a5
310 ; RV32IA-NEXT: and a5, a5, a3
311 ; RV32IA-NEXT: xor a5, a4, a5
312 ; RV32IA-NEXT: sc.w.rl a5, a5, (a0)
313 ; RV32IA-NEXT: bnez a5, .LBB8_1
314 ; RV32IA-NEXT: # %bb.2:
315 ; RV32IA-NEXT: srl a0, a4, a2
316 ; RV32IA-NEXT: ret
126317 %1 = atomicrmw add i8* %a, i8 %b acq_rel
127318 ret i8 %1
128319 }
137328 ; RV32I-NEXT: lw ra, 12(sp)
138329 ; RV32I-NEXT: addi sp, sp, 16
139330 ; RV32I-NEXT: ret
331 ;
332 ; RV32IA-LABEL: atomicrmw_add_i8_seq_cst:
333 ; RV32IA: # %bb.0:
334 ; RV32IA-NEXT: slli a2, a0, 3
335 ; RV32IA-NEXT: andi a2, a2, 24
336 ; RV32IA-NEXT: addi a3, zero, 255
337 ; RV32IA-NEXT: sll a3, a3, a2
338 ; RV32IA-NEXT: andi a1, a1, 255
339 ; RV32IA-NEXT: sll a1, a1, a2
340 ; RV32IA-NEXT: andi a0, a0, -4
341 ; RV32IA-NEXT: .LBB9_1: # =>This Inner Loop Header: Depth=1
342 ; RV32IA-NEXT: lr.w.aqrl a4, (a0)
343 ; RV32IA-NEXT: add a5, a4, a1
344 ; RV32IA-NEXT: xor a5, a4, a5
345 ; RV32IA-NEXT: and a5, a5, a3
346 ; RV32IA-NEXT: xor a5, a4, a5
347 ; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0)
348 ; RV32IA-NEXT: bnez a5, .LBB9_1
349 ; RV32IA-NEXT: # %bb.2:
350 ; RV32IA-NEXT: srl a0, a4, a2
351 ; RV32IA-NEXT: ret
140352 %1 = atomicrmw add i8* %a, i8 %b seq_cst
141353 ret i8 %1
142354 }
151363 ; RV32I-NEXT: lw ra, 12(sp)
152364 ; RV32I-NEXT: addi sp, sp, 16
153365 ; RV32I-NEXT: ret
366 ;
367 ; RV32IA-LABEL: atomicrmw_sub_i8_monotonic:
368 ; RV32IA: # %bb.0:
369 ; RV32IA-NEXT: slli a2, a0, 3
370 ; RV32IA-NEXT: andi a2, a2, 24
371 ; RV32IA-NEXT: addi a3, zero, 255
372 ; RV32IA-NEXT: sll a3, a3, a2
373 ; RV32IA-NEXT: andi a1, a1, 255
374 ; RV32IA-NEXT: sll a1, a1, a2
375 ; RV32IA-NEXT: andi a0, a0, -4
376 ; RV32IA-NEXT: .LBB10_1: # =>This Inner Loop Header: Depth=1
377 ; RV32IA-NEXT: lr.w a4, (a0)
378 ; RV32IA-NEXT: sub a5, a4, a1
379 ; RV32IA-NEXT: xor a5, a4, a5
380 ; RV32IA-NEXT: and a5, a5, a3
381 ; RV32IA-NEXT: xor a5, a4, a5
382 ; RV32IA-NEXT: sc.w a5, a5, (a0)
383 ; RV32IA-NEXT: bnez a5, .LBB10_1
384 ; RV32IA-NEXT: # %bb.2:
385 ; RV32IA-NEXT: srl a0, a4, a2
386 ; RV32IA-NEXT: ret
154387 %1 = atomicrmw sub i8* %a, i8 %b monotonic
155388 ret i8 %1
156389 }
165398 ; RV32I-NEXT: lw ra, 12(sp)
166399 ; RV32I-NEXT: addi sp, sp, 16
167400 ; RV32I-NEXT: ret
401 ;
402 ; RV32IA-LABEL: atomicrmw_sub_i8_acquire:
403 ; RV32IA: # %bb.0:
404 ; RV32IA-NEXT: slli a2, a0, 3
405 ; RV32IA-NEXT: andi a2, a2, 24
406 ; RV32IA-NEXT: addi a3, zero, 255
407 ; RV32IA-NEXT: sll a3, a3, a2
408 ; RV32IA-NEXT: andi a1, a1, 255
409 ; RV32IA-NEXT: sll a1, a1, a2
410 ; RV32IA-NEXT: andi a0, a0, -4
411 ; RV32IA-NEXT: .LBB11_1: # =>This Inner Loop Header: Depth=1
412 ; RV32IA-NEXT: lr.w.aq a4, (a0)
413 ; RV32IA-NEXT: sub a5, a4, a1
414 ; RV32IA-NEXT: xor a5, a4, a5
415 ; RV32IA-NEXT: and a5, a5, a3
416 ; RV32IA-NEXT: xor a5, a4, a5
417 ; RV32IA-NEXT: sc.w a5, a5, (a0)
418 ; RV32IA-NEXT: bnez a5, .LBB11_1
419 ; RV32IA-NEXT: # %bb.2:
420 ; RV32IA-NEXT: srl a0, a4, a2
421 ; RV32IA-NEXT: ret
168422 %1 = atomicrmw sub i8* %a, i8 %b acquire
169423 ret i8 %1
170424 }
179433 ; RV32I-NEXT: lw ra, 12(sp)
180434 ; RV32I-NEXT: addi sp, sp, 16
181435 ; RV32I-NEXT: ret
436 ;
437 ; RV32IA-LABEL: atomicrmw_sub_i8_release:
438 ; RV32IA: # %bb.0:
439 ; RV32IA-NEXT: slli a2, a0, 3
440 ; RV32IA-NEXT: andi a2, a2, 24
441 ; RV32IA-NEXT: addi a3, zero, 255
442 ; RV32IA-NEXT: sll a3, a3, a2
443 ; RV32IA-NEXT: andi a1, a1, 255
444 ; RV32IA-NEXT: sll a1, a1, a2
445 ; RV32IA-NEXT: andi a0, a0, -4
446 ; RV32IA-NEXT: .LBB12_1: # =>This Inner Loop Header: Depth=1
447 ; RV32IA-NEXT: lr.w a4, (a0)
448 ; RV32IA-NEXT: sub a5, a4, a1
449 ; RV32IA-NEXT: xor a5, a4, a5
450 ; RV32IA-NEXT: and a5, a5, a3
451 ; RV32IA-NEXT: xor a5, a4, a5
452 ; RV32IA-NEXT: sc.w.rl a5, a5, (a0)
453 ; RV32IA-NEXT: bnez a5, .LBB12_1
454 ; RV32IA-NEXT: # %bb.2:
455 ; RV32IA-NEXT: srl a0, a4, a2
456 ; RV32IA-NEXT: ret
182457 %1 = atomicrmw sub i8* %a, i8 %b release
183458 ret i8 %1
184459 }
193468 ; RV32I-NEXT: lw ra, 12(sp)
194469 ; RV32I-NEXT: addi sp, sp, 16
195470 ; RV32I-NEXT: ret
471 ;
472 ; RV32IA-LABEL: atomicrmw_sub_i8_acq_rel:
473 ; RV32IA: # %bb.0:
474 ; RV32IA-NEXT: slli a2, a0, 3
475 ; RV32IA-NEXT: andi a2, a2, 24
476 ; RV32IA-NEXT: addi a3, zero, 255
477 ; RV32IA-NEXT: sll a3, a3, a2
478 ; RV32IA-NEXT: andi a1, a1, 255
479 ; RV32IA-NEXT: sll a1, a1, a2
480 ; RV32IA-NEXT: andi a0, a0, -4
481 ; RV32IA-NEXT: .LBB13_1: # =>This Inner Loop Header: Depth=1
482 ; RV32IA-NEXT: lr.w.aq a4, (a0)
483 ; RV32IA-NEXT: sub a5, a4, a1
484 ; RV32IA-NEXT: xor a5, a4, a5
485 ; RV32IA-NEXT: and a5, a5, a3
486 ; RV32IA-NEXT: xor a5, a4, a5
487 ; RV32IA-NEXT: sc.w.rl a5, a5, (a0)
488 ; RV32IA-NEXT: bnez a5, .LBB13_1
489 ; RV32IA-NEXT: # %bb.2:
490 ; RV32IA-NEXT: srl a0, a4, a2
491 ; RV32IA-NEXT: ret
196492 %1 = atomicrmw sub i8* %a, i8 %b acq_rel
197493 ret i8 %1
198494 }
207503 ; RV32I-NEXT: lw ra, 12(sp)
208504 ; RV32I-NEXT: addi sp, sp, 16
209505 ; RV32I-NEXT: ret
506 ;
507 ; RV32IA-LABEL: atomicrmw_sub_i8_seq_cst:
508 ; RV32IA: # %bb.0:
509 ; RV32IA-NEXT: slli a2, a0, 3
510 ; RV32IA-NEXT: andi a2, a2, 24
511 ; RV32IA-NEXT: addi a3, zero, 255
512 ; RV32IA-NEXT: sll a3, a3, a2
513 ; RV32IA-NEXT: andi a1, a1, 255
514 ; RV32IA-NEXT: sll a1, a1, a2
515 ; RV32IA-NEXT: andi a0, a0, -4
516 ; RV32IA-NEXT: .LBB14_1: # =>This Inner Loop Header: Depth=1
517 ; RV32IA-NEXT: lr.w.aqrl a4, (a0)
518 ; RV32IA-NEXT: sub a5, a4, a1
519 ; RV32IA-NEXT: xor a5, a4, a5
520 ; RV32IA-NEXT: and a5, a5, a3
521 ; RV32IA-NEXT: xor a5, a4, a5
522 ; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0)
523 ; RV32IA-NEXT: bnez a5, .LBB14_1
524 ; RV32IA-NEXT: # %bb.2:
525 ; RV32IA-NEXT: srl a0, a4, a2
526 ; RV32IA-NEXT: ret
210527 %1 = atomicrmw sub i8* %a, i8 %b seq_cst
211528 ret i8 %1
212529 }
221538 ; RV32I-NEXT: lw ra, 12(sp)
222539 ; RV32I-NEXT: addi sp, sp, 16
223540 ; RV32I-NEXT: ret
541 ;
542 ; RV32IA-LABEL: atomicrmw_and_i8_monotonic:
543 ; RV32IA: # %bb.0:
544 ; RV32IA-NEXT: andi a1, a1, 255
545 ; RV32IA-NEXT: slli a2, a0, 3
546 ; RV32IA-NEXT: andi a2, a2, 24
547 ; RV32IA-NEXT: sll a1, a1, a2
548 ; RV32IA-NEXT: addi a3, zero, 255
549 ; RV32IA-NEXT: sll a3, a3, a2
550 ; RV32IA-NEXT: not a3, a3
551 ; RV32IA-NEXT: or a1, a3, a1
552 ; RV32IA-NEXT: andi a0, a0, -4
553 ; RV32IA-NEXT: amoand.w a0, a1, (a0)
554 ; RV32IA-NEXT: srl a0, a0, a2
555 ; RV32IA-NEXT: ret
224556 %1 = atomicrmw and i8* %a, i8 %b monotonic
225557 ret i8 %1
226558 }
235567 ; RV32I-NEXT: lw ra, 12(sp)
236568 ; RV32I-NEXT: addi sp, sp, 16
237569 ; RV32I-NEXT: ret
570 ;
571 ; RV32IA-LABEL: atomicrmw_and_i8_acquire:
572 ; RV32IA: # %bb.0:
573 ; RV32IA-NEXT: andi a1, a1, 255
574 ; RV32IA-NEXT: slli a2, a0, 3
575 ; RV32IA-NEXT: andi a2, a2, 24
576 ; RV32IA-NEXT: sll a1, a1, a2
577 ; RV32IA-NEXT: addi a3, zero, 255
578 ; RV32IA-NEXT: sll a3, a3, a2
579 ; RV32IA-NEXT: not a3, a3
580 ; RV32IA-NEXT: or a1, a3, a1
581 ; RV32IA-NEXT: andi a0, a0, -4
582 ; RV32IA-NEXT: amoand.w.aq a0, a1, (a0)
583 ; RV32IA-NEXT: srl a0, a0, a2
584 ; RV32IA-NEXT: ret
238585 %1 = atomicrmw and i8* %a, i8 %b acquire
239586 ret i8 %1
240587 }
249596 ; RV32I-NEXT: lw ra, 12(sp)
250597 ; RV32I-NEXT: addi sp, sp, 16
251598 ; RV32I-NEXT: ret
599 ;
600 ; RV32IA-LABEL: atomicrmw_and_i8_release:
601 ; RV32IA: # %bb.0:
602 ; RV32IA-NEXT: andi a1, a1, 255
603 ; RV32IA-NEXT: slli a2, a0, 3
604 ; RV32IA-NEXT: andi a2, a2, 24
605 ; RV32IA-NEXT: sll a1, a1, a2
606 ; RV32IA-NEXT: addi a3, zero, 255
607 ; RV32IA-NEXT: sll a3, a3, a2
608 ; RV32IA-NEXT: not a3, a3
609 ; RV32IA-NEXT: or a1, a3, a1
610 ; RV32IA-NEXT: andi a0, a0, -4
611 ; RV32IA-NEXT: amoand.w.rl a0, a1, (a0)
612 ; RV32IA-NEXT: srl a0, a0, a2
613 ; RV32IA-NEXT: ret
252614 %1 = atomicrmw and i8* %a, i8 %b release
253615 ret i8 %1
254616 }
263625 ; RV32I-NEXT: lw ra, 12(sp)
264626 ; RV32I-NEXT: addi sp, sp, 16
265627 ; RV32I-NEXT: ret
628 ;
629 ; RV32IA-LABEL: atomicrmw_and_i8_acq_rel:
630 ; RV32IA: # %bb.0:
631 ; RV32IA-NEXT: andi a1, a1, 255
632 ; RV32IA-NEXT: slli a2, a0, 3
633 ; RV32IA-NEXT: andi a2, a2, 24
634 ; RV32IA-NEXT: sll a1, a1, a2
635 ; RV32IA-NEXT: addi a3, zero, 255
636 ; RV32IA-NEXT: sll a3, a3, a2
637 ; RV32IA-NEXT: not a3, a3
638 ; RV32IA-NEXT: or a1, a3, a1
639 ; RV32IA-NEXT: andi a0, a0, -4
640 ; RV32IA-NEXT: amoand.w.aqrl a0, a1, (a0)
641 ; RV32IA-NEXT: srl a0, a0, a2
642 ; RV32IA-NEXT: ret
266643 %1 = atomicrmw and i8* %a, i8 %b acq_rel
267644 ret i8 %1
268645 }
277654 ; RV32I-NEXT: lw ra, 12(sp)
278655 ; RV32I-NEXT: addi sp, sp, 16
279656 ; RV32I-NEXT: ret
657 ;
658 ; RV32IA-LABEL: atomicrmw_and_i8_seq_cst:
659 ; RV32IA: # %bb.0:
660 ; RV32IA-NEXT: andi a1, a1, 255
661 ; RV32IA-NEXT: slli a2, a0, 3
662 ; RV32IA-NEXT: andi a2, a2, 24
663 ; RV32IA-NEXT: sll a1, a1, a2
664 ; RV32IA-NEXT: addi a3, zero, 255
665 ; RV32IA-NEXT: sll a3, a3, a2
666 ; RV32IA-NEXT: not a3, a3
667 ; RV32IA-NEXT: or a1, a3, a1
668 ; RV32IA-NEXT: andi a0, a0, -4
669 ; RV32IA-NEXT: amoand.w.aqrl a0, a1, (a0)
670 ; RV32IA-NEXT: srl a0, a0, a2
671 ; RV32IA-NEXT: ret
280672 %1 = atomicrmw and i8* %a, i8 %b seq_cst
281673 ret i8 %1
282674 }
291683 ; RV32I-NEXT: lw ra, 12(sp)
292684 ; RV32I-NEXT: addi sp, sp, 16
293685 ; RV32I-NEXT: ret
686 ;
687 ; RV32IA-LABEL: atomicrmw_nand_i8_monotonic:
688 ; RV32IA: # %bb.0:
689 ; RV32IA-NEXT: slli a2, a0, 3
690 ; RV32IA-NEXT: andi a2, a2, 24
691 ; RV32IA-NEXT: addi a3, zero, 255
692 ; RV32IA-NEXT: sll a3, a3, a2
693 ; RV32IA-NEXT: andi a1, a1, 255
694 ; RV32IA-NEXT: sll a1, a1, a2
695 ; RV32IA-NEXT: andi a0, a0, -4
696 ; RV32IA-NEXT: .LBB20_1: # =>This Inner Loop Header: Depth=1
697 ; RV32IA-NEXT: lr.w a4, (a0)
698 ; RV32IA-NEXT: and a5, a4, a1
699 ; RV32IA-NEXT: not a5, a5
700 ; RV32IA-NEXT: xor a5, a4, a5
701 ; RV32IA-NEXT: and a5, a5, a3
702 ; RV32IA-NEXT: xor a5, a4, a5
703 ; RV32IA-NEXT: sc.w a5, a5, (a0)
704 ; RV32IA-NEXT: bnez a5, .LBB20_1
705 ; RV32IA-NEXT: # %bb.2:
706 ; RV32IA-NEXT: srl a0, a4, a2
707 ; RV32IA-NEXT: ret
294708 %1 = atomicrmw nand i8* %a, i8 %b monotonic
295709 ret i8 %1
296710 }
305719 ; RV32I-NEXT: lw ra, 12(sp)
306720 ; RV32I-NEXT: addi sp, sp, 16
307721 ; RV32I-NEXT: ret
722 ;
723 ; RV32IA-LABEL: atomicrmw_nand_i8_acquire:
724 ; RV32IA: # %bb.0:
725 ; RV32IA-NEXT: slli a2, a0, 3
726 ; RV32IA-NEXT: andi a2, a2, 24
727 ; RV32IA-NEXT: addi a3, zero, 255
728 ; RV32IA-NEXT: sll a3, a3, a2
729 ; RV32IA-NEXT: andi a1, a1, 255
730 ; RV32IA-NEXT: sll a1, a1, a2
731 ; RV32IA-NEXT: andi a0, a0, -4
732 ; RV32IA-NEXT: .LBB21_1: # =>This Inner Loop Header: Depth=1
733 ; RV32IA-NEXT: lr.w.aq a4, (a0)
734 ; RV32IA-NEXT: and a5, a4, a1
735 ; RV32IA-NEXT: not a5, a5
736 ; RV32IA-NEXT: xor a5, a4, a5
737 ; RV32IA-NEXT: and a5, a5, a3
738 ; RV32IA-NEXT: xor a5, a4, a5
739 ; RV32IA-NEXT: sc.w a5, a5, (a0)
740 ; RV32IA-NEXT: bnez a5, .LBB21_1
741 ; RV32IA-NEXT: # %bb.2:
742 ; RV32IA-NEXT: srl a0, a4, a2
743 ; RV32IA-NEXT: ret
308744 %1 = atomicrmw nand i8* %a, i8 %b acquire
309745 ret i8 %1
310746 }
319755 ; RV32I-NEXT: lw ra, 12(sp)
320756 ; RV32I-NEXT: addi sp, sp, 16
321757 ; RV32I-NEXT: ret
758 ;
759 ; RV32IA-LABEL: atomicrmw_nand_i8_release:
760 ; RV32IA: # %bb.0:
761 ; RV32IA-NEXT: slli a2, a0, 3
762 ; RV32IA-NEXT: andi a2, a2, 24
763 ; RV32IA-NEXT: addi a3, zero, 255
764 ; RV32IA-NEXT: sll a3, a3, a2
765 ; RV32IA-NEXT: andi a1, a1, 255
766 ; RV32IA-NEXT: sll a1, a1, a2
767 ; RV32IA-NEXT: andi a0, a0, -4
768 ; RV32IA-NEXT: .LBB22_1: # =>This Inner Loop Header: Depth=1
769 ; RV32IA-NEXT: lr.w a4, (a0)
770 ; RV32IA-NEXT: and a5, a4, a1
771 ; RV32IA-NEXT: not a5, a5
772 ; RV32IA-NEXT: xor a5, a4, a5
773 ; RV32IA-NEXT: and a5, a5, a3
774 ; RV32IA-NEXT: xor a5, a4, a5
775 ; RV32IA-NEXT: sc.w.rl a5, a5, (a0)
776 ; RV32IA-NEXT: bnez a5, .LBB22_1
777 ; RV32IA-NEXT: # %bb.2:
778 ; RV32IA-NEXT: srl a0, a4, a2
779 ; RV32IA-NEXT: ret
322780 %1 = atomicrmw nand i8* %a, i8 %b release
323781 ret i8 %1
324782 }
333791 ; RV32I-NEXT: lw ra, 12(sp)
334792 ; RV32I-NEXT: addi sp, sp, 16
335793 ; RV32I-NEXT: ret
794 ;
795 ; RV32IA-LABEL: atomicrmw_nand_i8_acq_rel:
796 ; RV32IA: # %bb.0:
797 ; RV32IA-NEXT: slli a2, a0, 3
798 ; RV32IA-NEXT: andi a2, a2, 24
799 ; RV32IA-NEXT: addi a3, zero, 255
800 ; RV32IA-NEXT: sll a3, a3, a2
801 ; RV32IA-NEXT: andi a1, a1, 255
802 ; RV32IA-NEXT: sll a1, a1, a2
803 ; RV32IA-NEXT: andi a0, a0, -4
804 ; RV32IA-NEXT: .LBB23_1: # =>This Inner Loop Header: Depth=1
805 ; RV32IA-NEXT: lr.w.aq a4, (a0)
806 ; RV32IA-NEXT: and a5, a4, a1
807 ; RV32IA-NEXT: not a5, a5
808 ; RV32IA-NEXT: xor a5, a4, a5
809 ; RV32IA-NEXT: and a5, a5, a3
810 ; RV32IA-NEXT: xor a5, a4, a5
811 ; RV32IA-NEXT: sc.w.rl a5, a5, (a0)
812 ; RV32IA-NEXT: bnez a5, .LBB23_1
813 ; RV32IA-NEXT: # %bb.2:
814 ; RV32IA-NEXT: srl a0, a4, a2
815 ; RV32IA-NEXT: ret
336816 %1 = atomicrmw nand i8* %a, i8 %b acq_rel
337817 ret i8 %1
338818 }
347827 ; RV32I-NEXT: lw ra, 12(sp)
348828 ; RV32I-NEXT: addi sp, sp, 16
349829 ; RV32I-NEXT: ret
830 ;
831 ; RV32IA-LABEL: atomicrmw_nand_i8_seq_cst:
832 ; RV32IA: # %bb.0:
833 ; RV32IA-NEXT: slli a2, a0, 3
834 ; RV32IA-NEXT: andi a2, a2, 24
835 ; RV32IA-NEXT: addi a3, zero, 255
836 ; RV32IA-NEXT: sll a3, a3, a2
837 ; RV32IA-NEXT: andi a1, a1, 255
838 ; RV32IA-NEXT: sll a1, a1, a2
839 ; RV32IA-NEXT: andi a0, a0, -4
840 ; RV32IA-NEXT: .LBB24_1: # =>This Inner Loop Header: Depth=1
841 ; RV32IA-NEXT: lr.w.aqrl a4, (a0)
842 ; RV32IA-NEXT: and a5, a4, a1
843 ; RV32IA-NEXT: not a5, a5
844 ; RV32IA-NEXT: xor a5, a4, a5
845 ; RV32IA-NEXT: and a5, a5, a3
846 ; RV32IA-NEXT: xor a5, a4, a5
847 ; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0)
848 ; RV32IA-NEXT: bnez a5, .LBB24_1
849 ; RV32IA-NEXT: # %bb.2:
850 ; RV32IA-NEXT: srl a0, a4, a2
851 ; RV32IA-NEXT: ret
350852 %1 = atomicrmw nand i8* %a, i8 %b seq_cst
351853 ret i8 %1
352854 }
361863 ; RV32I-NEXT: lw ra, 12(sp)
362864 ; RV32I-NEXT: addi sp, sp, 16
363865 ; RV32I-NEXT: ret
866 ;
867 ; RV32IA-LABEL: atomicrmw_or_i8_monotonic:
868 ; RV32IA: # %bb.0:
869 ; RV32IA-NEXT: andi a1, a1, 255
870 ; RV32IA-NEXT: slli a2, a0, 3
871 ; RV32IA-NEXT: andi a2, a2, 24
872 ; RV32IA-NEXT: sll a1, a1, a2
873 ; RV32IA-NEXT: andi a0, a0, -4
874 ; RV32IA-NEXT: amoor.w a0, a1, (a0)
875 ; RV32IA-NEXT: srl a0, a0, a2
876 ; RV32IA-NEXT: ret
364877 %1 = atomicrmw or i8* %a, i8 %b monotonic
365878 ret i8 %1
366879 }
375888 ; RV32I-NEXT: lw ra, 12(sp)
376889 ; RV32I-NEXT: addi sp, sp, 16
377890 ; RV32I-NEXT: ret
891 ;
892 ; RV32IA-LABEL: atomicrmw_or_i8_acquire:
893 ; RV32IA: # %bb.0:
894 ; RV32IA-NEXT: andi a1, a1, 255
895 ; RV32IA-NEXT: slli a2, a0, 3
896 ; RV32IA-NEXT: andi a2, a2, 24
897 ; RV32IA-NEXT: sll a1, a1, a2
898 ; RV32IA-NEXT: andi a0, a0, -4
899 ; RV32IA-NEXT: amoor.w.aq a0, a1, (a0)
900 ; RV32IA-NEXT: srl a0, a0, a2
901 ; RV32IA-NEXT: ret
378902 %1 = atomicrmw or i8* %a, i8 %b acquire
379903 ret i8 %1
380904 }
389913 ; RV32I-NEXT: lw ra, 12(sp)
390914 ; RV32I-NEXT: addi sp, sp, 16
391915 ; RV32I-NEXT: ret
916 ;
917 ; RV32IA-LABEL: atomicrmw_or_i8_release:
918 ; RV32IA: # %bb.0:
919 ; RV32IA-NEXT: andi a1, a1, 255
920 ; RV32IA-NEXT: slli a2, a0, 3
921 ; RV32IA-NEXT: andi a2, a2, 24
922 ; RV32IA-NEXT: sll a1, a1, a2
923 ; RV32IA-NEXT: andi a0, a0, -4
924 ; RV32IA-NEXT: amoor.w.rl a0, a1, (a0)
925 ; RV32IA-NEXT: srl a0, a0, a2
926 ; RV32IA-NEXT: ret
392927 %1 = atomicrmw or i8* %a, i8 %b release
393928 ret i8 %1
394929 }
403938 ; RV32I-NEXT: lw ra, 12(sp)
404939 ; RV32I-NEXT: addi sp, sp, 16
405940 ; RV32I-NEXT: ret
941 ;
942 ; RV32IA-LABEL: atomicrmw_or_i8_acq_rel:
943 ; RV32IA: # %bb.0:
944 ; RV32IA-NEXT: andi a1, a1, 255
945 ; RV32IA-NEXT: slli a2, a0, 3
946 ; RV32IA-NEXT: andi a2, a2, 24
947 ; RV32IA-NEXT: sll a1, a1, a2
948 ; RV32IA-NEXT: andi a0, a0, -4
949 ; RV32IA-NEXT: amoor.w.aqrl a0, a1, (a0)
950 ; RV32IA-NEXT: srl a0, a0, a2
951 ; RV32IA-NEXT: ret
406952 %1 = atomicrmw or i8* %a, i8 %b acq_rel
407953 ret i8 %1
408954 }
417963 ; RV32I-NEXT: lw ra, 12(sp)
418964 ; RV32I-NEXT: addi sp, sp, 16
419965 ; RV32I-NEXT: ret
966 ;
967 ; RV32IA-LABEL: atomicrmw_or_i8_seq_cst:
968 ; RV32IA: # %bb.0:
969 ; RV32IA-NEXT: andi a1, a1, 255
970 ; RV32IA-NEXT: slli a2, a0, 3
971 ; RV32IA-NEXT: andi a2, a2, 24
972 ; RV32IA-NEXT: sll a1, a1, a2
973 ; RV32IA-NEXT: andi a0, a0, -4
974 ; RV32IA-NEXT: amoor.w.aqrl a0, a1, (a0)
975 ; RV32IA-NEXT: srl a0, a0, a2
976 ; RV32IA-NEXT: ret
420977 %1 = atomicrmw or i8* %a, i8 %b seq_cst
421978 ret i8 %1
422979 }
431988 ; RV32I-NEXT: lw ra, 12(sp)
432989 ; RV32I-NEXT: addi sp, sp, 16
433990 ; RV32I-NEXT: ret
991 ;
992 ; RV32IA-LABEL: atomicrmw_xor_i8_monotonic:
993 ; RV32IA: # %bb.0:
994 ; RV32IA-NEXT: andi a1, a1, 255
995 ; RV32IA-NEXT: slli a2, a0, 3
996 ; RV32IA-NEXT: andi a2, a2, 24
997 ; RV32IA-NEXT: sll a1, a1, a2
998 ; RV32IA-NEXT: andi a0, a0, -4
999 ; RV32IA-NEXT: amoxor.w a0, a1, (a0)
1000 ; RV32IA-NEXT: srl a0, a0, a2
1001 ; RV32IA-NEXT: ret
4341002 %1 = atomicrmw xor i8* %a, i8 %b monotonic
4351003 ret i8 %1
4361004 }
4451013 ; RV32I-NEXT: lw ra, 12(sp)
4461014 ; RV32I-NEXT: addi sp, sp, 16
4471015 ; RV32I-NEXT: ret
1016 ;
1017 ; RV32IA-LABEL: atomicrmw_xor_i8_acquire:
1018 ; RV32IA: # %bb.0:
1019 ; RV32IA-NEXT: andi a1, a1, 255
1020 ; RV32IA-NEXT: slli a2, a0, 3
1021 ; RV32IA-NEXT: andi a2, a2, 24
1022 ; RV32IA-NEXT: sll a1, a1, a2
1023 ; RV32IA-NEXT: andi a0, a0, -4
1024 ; RV32IA-NEXT: amoxor.w.aq a0, a1, (a0)
1025 ; RV32IA-NEXT: srl a0, a0, a2
1026 ; RV32IA-NEXT: ret
4481027 %1 = atomicrmw xor i8* %a, i8 %b acquire
4491028 ret i8 %1
4501029 }
4591038 ; RV32I-NEXT: lw ra, 12(sp)
4601039 ; RV32I-NEXT: addi sp, sp, 16
4611040 ; RV32I-NEXT: ret
1041 ;
1042 ; RV32IA-LABEL: atomicrmw_xor_i8_release:
1043 ; RV32IA: # %bb.0:
1044 ; RV32IA-NEXT: andi a1, a1, 255
1045 ; RV32IA-NEXT: slli a2, a0, 3
1046 ; RV32IA-NEXT: andi a2, a2, 24
1047 ; RV32IA-NEXT: sll a1, a1, a2
1048 ; RV32IA-NEXT: andi a0, a0, -4
1049 ; RV32IA-NEXT: amoxor.w.rl a0, a1, (a0)
1050 ; RV32IA-NEXT: srl a0, a0, a2
1051 ; RV32IA-NEXT: ret
4621052 %1 = atomicrmw xor i8* %a, i8 %b release
4631053 ret i8 %1
4641054 }
4731063 ; RV32I-NEXT: lw ra, 12(sp)
4741064 ; RV32I-NEXT: addi sp, sp, 16
4751065 ; RV32I-NEXT: ret
1066 ;
1067 ; RV32IA-LABEL: atomicrmw_xor_i8_acq_rel:
1068 ; RV32IA: # %bb.0:
1069 ; RV32IA-NEXT: andi a1, a1, 255
1070 ; RV32IA-NEXT: slli a2, a0, 3
1071 ; RV32IA-NEXT: andi a2, a2, 24
1072 ; RV32IA-NEXT: sll a1, a1, a2
1073 ; RV32IA-NEXT: andi a0, a0, -4
1074 ; RV32IA-NEXT: amoxor.w.aqrl a0, a1, (a0)
1075 ; RV32IA-NEXT: srl a0, a0, a2
1076 ; RV32IA-NEXT: ret
4761077 %1 = atomicrmw xor i8* %a, i8 %b acq_rel
4771078 ret i8 %1
4781079 }
4871088 ; RV32I-NEXT: lw ra, 12(sp)
4881089 ; RV32I-NEXT: addi sp, sp, 16
4891090 ; RV32I-NEXT: ret
1091 ;
1092 ; RV32IA-LABEL: atomicrmw_xor_i8_seq_cst:
1093 ; RV32IA: # %bb.0:
1094 ; RV32IA-NEXT: andi a1, a1, 255
1095 ; RV32IA-NEXT: slli a2, a0, 3
1096 ; RV32IA-NEXT: andi a2, a2, 24
1097 ; RV32IA-NEXT: sll a1, a1, a2
1098 ; RV32IA-NEXT: andi a0, a0, -4
1099 ; RV32IA-NEXT: amoxor.w.aqrl a0, a1, (a0)
1100 ; RV32IA-NEXT: srl a0, a0, a2
1101 ; RV32IA-NEXT: ret
4901102 %1 = atomicrmw xor i8* %a, i8 %b seq_cst
4911103 ret i8 %1
4921104 }
5341146 ; RV32I-NEXT: lw ra, 28(sp)
5351147 ; RV32I-NEXT: addi sp, sp, 32
5361148 ; RV32I-NEXT: ret
1149 ;
1150 ; RV32IA-LABEL: atomicrmw_max_i8_monotonic:
1151 ; RV32IA: # %bb.0:
1152 ; RV32IA-NEXT: slli a2, a0, 3
1153 ; RV32IA-NEXT: andi a2, a2, 24
1154 ; RV32IA-NEXT: addi a3, zero, 24
1155 ; RV32IA-NEXT: sub a6, a3, a2
1156 ; RV32IA-NEXT: addi a4, zero, 255
1157 ; RV32IA-NEXT: sll a7, a4, a2
1158 ; RV32IA-NEXT: slli a1, a1, 24
1159 ; RV32IA-NEXT: srai a1, a1, 24
1160 ; RV32IA-NEXT: sll a1, a1, a2
1161 ; RV32IA-NEXT: andi a0, a0, -4
1162 ; RV32IA-NEXT: .LBB35_1: # =>This Inner Loop Header: Depth=1
1163 ; RV32IA-NEXT: lr.w a5, (a0)
1164 ; RV32IA-NEXT: and a4, a5, a7
1165 ; RV32IA-NEXT: mv a3, a5
1166 ; RV32IA-NEXT: sll a4, a4, a6
1167 ; RV32IA-NEXT: sra a4, a4, a6
1168 ; RV32IA-NEXT: bge a4, a1, .LBB35_3
1169 ; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB35_1 Depth=1
1170 ; RV32IA-NEXT: xor a3, a5, a1
1171 ; RV32IA-NEXT: and a3, a3, a7
1172 ; RV32IA-NEXT: xor a3, a5, a3
1173 ; RV32IA-NEXT: .LBB35_3: # in Loop: Header=BB35_1 Depth=1
1174 ; RV32IA-NEXT: sc.w a3, a3, (a0)
1175 ; RV32IA-NEXT: bnez a3, .LBB35_1
1176 ; RV32IA-NEXT: # %bb.4:
1177 ; RV32IA-NEXT: srl a0, a5, a2
1178 ; RV32IA-NEXT: ret
5371179 %1 = atomicrmw max i8* %a, i8 %b monotonic
5381180 ret i8 %1
5391181 }
5841226 ; RV32I-NEXT: lw ra, 28(sp)
5851227 ; RV32I-NEXT: addi sp, sp, 32
5861228 ; RV32I-NEXT: ret
1229 ;
1230 ; RV32IA-LABEL: atomicrmw_max_i8_acquire:
1231 ; RV32IA: # %bb.0:
1232 ; RV32IA-NEXT: slli a2, a0, 3
1233 ; RV32IA-NEXT: andi a2, a2, 24
1234 ; RV32IA-NEXT: addi a3, zero, 24
1235 ; RV32IA-NEXT: sub a6, a3, a2
1236 ; RV32IA-NEXT: addi a4, zero, 255
1237 ; RV32IA-NEXT: sll a7, a4, a2
1238 ; RV32IA-NEXT: slli a1, a1, 24
1239 ; RV32IA-NEXT: srai a1, a1, 24
1240 ; RV32IA-NEXT: sll a1, a1, a2
1241 ; RV32IA-NEXT: andi a0, a0, -4
1242 ; RV32IA-NEXT: .LBB36_1: # =>This Inner Loop Header: Depth=1
1243 ; RV32IA-NEXT: lr.w.aq a5, (a0)
1244 ; RV32IA-NEXT: and a4, a5, a7
1245 ; RV32IA-NEXT: mv a3, a5
1246 ; RV32IA-NEXT: sll a4, a4, a6
1247 ; RV32IA-NEXT: sra a4, a4, a6
1248 ; RV32IA-NEXT: bge a4, a1, .LBB36_3
1249 ; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB36_1 Depth=1
1250 ; RV32IA-NEXT: xor a3, a5, a1
1251 ; RV32IA-NEXT: and a3, a3, a7
1252 ; RV32IA-NEXT: xor a3, a5, a3
1253 ; RV32IA-NEXT: .LBB36_3: # in Loop: Header=BB36_1 Depth=1
1254 ; RV32IA-NEXT: sc.w a3, a3, (a0)
1255 ; RV32IA-NEXT: bnez a3, .LBB36_1
1256 ; RV32IA-NEXT: # %bb.4:
1257 ; RV32IA-NEXT: srl a0, a5, a2
1258 ; RV32IA-NEXT: ret
5871259 %1 = atomicrmw max i8* %a, i8 %b acquire
5881260 ret i8 %1
5891261 }
6341306 ; RV32I-NEXT: lw ra, 28(sp)
6351307 ; RV32I-NEXT: addi sp, sp, 32
6361308 ; RV32I-NEXT: ret
1309 ;
1310 ; RV32IA-LABEL: atomicrmw_max_i8_release:
1311 ; RV32IA: # %bb.0:
1312 ; RV32IA-NEXT: slli a2, a0, 3
1313 ; RV32IA-NEXT: andi a2, a2, 24
1314 ; RV32IA-NEXT: addi a3, zero, 24
1315 ; RV32IA-NEXT: sub a6, a3, a2
1316 ; RV32IA-NEXT: addi a4, zero, 255
1317 ; RV32IA-NEXT: sll a7, a4, a2
1318 ; RV32IA-NEXT: slli a1, a1, 24
1319 ; RV32IA-NEXT: srai a1, a1, 24
1320 ; RV32IA-NEXT: sll a1, a1, a2
1321 ; RV32IA-NEXT: andi a0, a0, -4
1322 ; RV32IA-NEXT: .LBB37_1: # =>This Inner Loop Header: Depth=1
1323 ; RV32IA-NEXT: lr.w a5, (a0)
1324 ; RV32IA-NEXT: and a4, a5, a7
1325 ; RV32IA-NEXT: mv a3, a5
1326 ; RV32IA-NEXT: sll a4, a4, a6
1327 ; RV32IA-NEXT: sra a4, a4, a6
1328 ; RV32IA-NEXT: bge a4, a1, .LBB37_3
1329 ; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB37_1 Depth=1
1330 ; RV32IA-NEXT: xor a3, a5, a1
1331 ; RV32IA-NEXT: and a3, a3, a7
1332 ; RV32IA-NEXT: xor a3, a5, a3
1333 ; RV32IA-NEXT: .LBB37_3: # in Loop: Header=BB37_1 Depth=1
1334 ; RV32IA-NEXT: sc.w.rl a3, a3, (a0)
1335 ; RV32IA-NEXT: bnez a3, .LBB37_1
1336 ; RV32IA-NEXT: # %bb.4:
1337 ; RV32IA-NEXT: srl a0, a5, a2
1338 ; RV32IA-NEXT: ret
6371339 %1 = atomicrmw max i8* %a, i8 %b release
6381340 ret i8 %1
6391341 }
6871389 ; RV32I-NEXT: lw ra, 28(sp)
6881390 ; RV32I-NEXT: addi sp, sp, 32
6891391 ; RV32I-NEXT: ret
1392 ;
1393 ; RV32IA-LABEL: atomicrmw_max_i8_acq_rel:
1394 ; RV32IA: # %bb.0:
1395 ; RV32IA-NEXT: slli a2, a0, 3
1396 ; RV32IA-NEXT: andi a2, a2, 24
1397 ; RV32IA-NEXT: addi a3, zero, 24
1398 ; RV32IA-NEXT: sub a6, a3, a2
1399 ; RV32IA-NEXT: addi a4, zero, 255
1400 ; RV32IA-NEXT: sll a7, a4, a2
1401 ; RV32IA-NEXT: slli a1, a1, 24
1402 ; RV32IA-NEXT: srai a1, a1, 24
1403 ; RV32IA-NEXT: sll a1, a1, a2
1404 ; RV32IA-NEXT: andi a0, a0, -4
1405 ; RV32IA-NEXT: .LBB38_1: # =>This Inner Loop Header: Depth=1
1406 ; RV32IA-NEXT: lr.w.aq a5, (a0)
1407 ; RV32IA-NEXT: and a4, a5, a7
1408 ; RV32IA-NEXT: mv a3, a5
1409 ; RV32IA-NEXT: sll a4, a4, a6
1410 ; RV32IA-NEXT: sra a4, a4, a6
1411 ; RV32IA-NEXT: bge a4, a1, .LBB38_3
1412 ; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB38_1 Depth=1
1413 ; RV32IA-NEXT: xor a3, a5, a1
1414 ; RV32IA-NEXT: and a3, a3, a7
1415 ; RV32IA-NEXT: xor a3, a5, a3
1416 ; RV32IA-NEXT: .LBB38_3: # in Loop: Header=BB38_1 Depth=1
1417 ; RV32IA-NEXT: sc.w.rl a3, a3, (a0)
1418 ; RV32IA-NEXT: bnez a3, .LBB38_1
1419 ; RV32IA-NEXT: # %bb.4:
1420 ; RV32IA-NEXT: srl a0, a5, a2
1421 ; RV32IA-NEXT: ret
6901422 %1 = atomicrmw max i8* %a, i8 %b acq_rel
6911423 ret i8 %1
6921424 }
7371469 ; RV32I-NEXT: lw ra, 28(sp)
7381470 ; RV32I-NEXT: addi sp, sp, 32
7391471 ; RV32I-NEXT: ret
1472 ;
1473 ; RV32IA-LABEL: atomicrmw_max_i8_seq_cst:
1474 ; RV32IA: # %bb.0:
1475 ; RV32IA-NEXT: slli a2, a0, 3
1476 ; RV32IA-NEXT: andi a2, a2, 24
1477 ; RV32IA-NEXT: addi a3, zero, 24
1478 ; RV32IA-NEXT: sub a6, a3, a2
1479 ; RV32IA-NEXT: addi a4, zero, 255
1480 ; RV32IA-NEXT: sll a7, a4, a2
1481 ; RV32IA-NEXT: slli a1, a1, 24
1482 ; RV32IA-NEXT: srai a1, a1, 24
1483 ; RV32IA-NEXT: sll a1, a1, a2
1484 ; RV32IA-NEXT: andi a0, a0, -4
1485 ; RV32IA-NEXT: .LBB39_1: # =>This Inner Loop Header: Depth=1
1486 ; RV32IA-NEXT: lr.w.aqrl a5, (a0)
1487 ; RV32IA-NEXT: and a4, a5, a7
1488 ; RV32IA-NEXT: mv a3, a5
1489 ; RV32IA-NEXT: sll a4, a4, a6
1490 ; RV32IA-NEXT: sra a4, a4, a6
1491 ; RV32IA-NEXT: bge a4, a1, .LBB39_3
1492 ; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB39_1 Depth=1
1493 ; RV32IA-NEXT: xor a3, a5, a1
1494 ; RV32IA-NEXT: and a3, a3, a7
1495 ; RV32IA-NEXT: xor a3, a5, a3
1496 ; RV32IA-NEXT: .LBB39_3: # in Loop: Header=BB39_1 Depth=1
1497 ; RV32IA-NEXT: sc.w.aqrl a3, a3, (a0)
1498 ; RV32IA-NEXT: bnez a3, .LBB39_1
1499 ; RV32IA-NEXT: # %bb.4:
1500 ; RV32IA-NEXT: srl a0, a5, a2
1501 ; RV32IA-NEXT: ret
7401502 %1 = atomicrmw max i8* %a, i8 %b seq_cst
7411503 ret i8 %1
7421504 }
7841546 ; RV32I-NEXT: lw ra, 28(sp)
7851547 ; RV32I-NEXT: addi sp, sp, 32
7861548 ; RV32I-NEXT: ret
1549 ;
1550 ; RV32IA-LABEL: atomicrmw_min_i8_monotonic:
1551 ; RV32IA: # %bb.0:
1552 ; RV32IA-NEXT: slli a2, a0, 3
1553 ; RV32IA-NEXT: andi a2, a2, 24
1554 ; RV32IA-NEXT: addi a3, zero, 24
1555 ; RV32IA-NEXT: sub a6, a3, a2
1556 ; RV32IA-NEXT: addi a4, zero, 255
1557 ; RV32IA-NEXT: sll a7, a4, a2
1558 ; RV32IA-NEXT: slli a1, a1, 24
1559 ; RV32IA-NEXT: srai a1, a1, 24
1560 ; RV32IA-NEXT: sll a1, a1, a2
1561 ; RV32IA-NEXT: andi a0, a0, -4
1562 ; RV32IA-NEXT: .LBB40_1: # =>This Inner Loop Header: Depth=1
1563 ; RV32IA-NEXT: lr.w a5, (a0)
1564 ; RV32IA-NEXT: and a4, a5, a7
1565 ; RV32IA-NEXT: mv a3, a5
1566 ; RV32IA-NEXT: sll a4, a4, a6
1567 ; RV32IA-NEXT: sra a4, a4, a6
1568 ; RV32IA-NEXT: bge a1, a4, .LBB40_3
1569 ; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB40_1 Depth=1
1570 ; RV32IA-NEXT: xor a3, a5, a1
1571 ; RV32IA-NEXT: and a3, a3, a7
1572 ; RV32IA-NEXT: xor a3, a5, a3
1573 ; RV32IA-NEXT: .LBB40_3: # in Loop: Header=BB40_1 Depth=1
1574 ; RV32IA-NEXT: sc.w a3, a3, (a0)
1575 ; RV32IA-NEXT: bnez a3, .LBB40_1
1576 ; RV32IA-NEXT: # %bb.4:
1577 ; RV32IA-NEXT: srl a0, a5, a2
1578 ; RV32IA-NEXT: ret
7871579 %1 = atomicrmw min i8* %a, i8 %b monotonic
7881580 ret i8 %1
7891581 }
8341626 ; RV32I-NEXT: lw ra, 28(sp)
8351627 ; RV32I-NEXT: addi sp, sp, 32
8361628 ; RV32I-NEXT: ret
1629 ;
1630 ; RV32IA-LABEL: atomicrmw_min_i8_acquire:
1631 ; RV32IA: # %bb.0:
1632 ; RV32IA-NEXT: slli a2, a0, 3
1633 ; RV32IA-NEXT: andi a2, a2, 24
1634 ; RV32IA-NEXT: addi a3, zero, 24
1635 ; RV32IA-NEXT: sub a6, a3, a2
1636 ; RV32IA-NEXT: addi a4, zero, 255
1637 ; RV32IA-NEXT: sll a7, a4, a2
1638 ; RV32IA-NEXT: slli a1, a1, 24
1639 ; RV32IA-NEXT: srai a1, a1, 24
1640 ; RV32IA-NEXT: sll a1, a1, a2
1641 ; RV32IA-NEXT: andi a0, a0, -4
1642 ; RV32IA-NEXT: .LBB41_1: # =>This Inner Loop Header: Depth=1
1643 ; RV32IA-NEXT: lr.w.aq a5, (a0)
1644 ; RV32IA-NEXT: and a4, a5, a7
1645 ; RV32IA-NEXT: mv a3, a5
1646 ; RV32IA-NEXT: sll a4, a4, a6
1647 ; RV32IA-NEXT: sra a4, a4, a6
1648 ; RV32IA-NEXT: bge a1, a4, .LBB41_3
1649 ; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB41_1 Depth=1
1650 ; RV32IA-NEXT: xor a3, a5, a1
1651 ; RV32IA-NEXT: and a3, a3, a7
1652 ; RV32IA-NEXT: xor a3, a5, a3
1653 ; RV32IA-NEXT: .LBB41_3: # in Loop: Header=BB41_1 Depth=1
1654 ; RV32IA-NEXT: sc.w a3, a3, (a0)
1655 ; RV32IA-NEXT: bnez a3, .LBB41_1
1656 ; RV32IA-NEXT: # %bb.4:
1657 ; RV32IA-NEXT: srl a0, a5, a2
1658 ; RV32IA-NEXT: ret
8371659 %1 = atomicrmw min i8* %a, i8 %b acquire
8381660 ret i8 %1
8391661 }
8841706 ; RV32I-NEXT: lw ra, 28(sp)
8851707 ; RV32I-NEXT: addi sp, sp, 32
8861708 ; RV32I-NEXT: ret
1709 ;
1710 ; RV32IA-LABEL: atomicrmw_min_i8_release:
1711 ; RV32IA: # %bb.0:
1712 ; RV32IA-NEXT: slli a2, a0, 3
1713 ; RV32IA-NEXT: andi a2, a2, 24
1714 ; RV32IA-NEXT: addi a3, zero, 24
1715 ; RV32IA-NEXT: sub a6, a3, a2
1716 ; RV32IA-NEXT: addi a4, zero, 255
1717 ; RV32IA-NEXT: sll a7, a4, a2
1718 ; RV32IA-NEXT: slli a1, a1, 24
1719 ; RV32IA-NEXT: srai a1, a1, 24
1720 ; RV32IA-NEXT: sll a1, a1, a2
1721 ; RV32IA-NEXT: andi a0, a0, -4
1722 ; RV32IA-NEXT: .LBB42_1: # =>This Inner Loop Header: Depth=1
1723 ; RV32IA-NEXT: lr.w a5, (a0)
1724 ; RV32IA-NEXT: and a4, a5, a7
1725 ; RV32IA-NEXT: mv a3, a5
1726 ; RV32IA-NEXT: sll a4, a4, a6
1727 ; RV32IA-NEXT: sra a4, a4, a6
1728 ; RV32IA-NEXT: bge a1, a4, .LBB42_3
1729 ; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB42_1 Depth=1
1730 ; RV32IA-NEXT: xor a3, a5, a1
1731 ; RV32IA-NEXT: and a3, a3, a7
1732 ; RV32IA-NEXT: xor a3, a5, a3
1733 ; RV32IA-NEXT: .LBB42_3: # in Loop: Header=BB42_1 Depth=1
1734 ; RV32IA-NEXT: sc.w.rl a3, a3, (a0)
1735 ; RV32IA-NEXT: bnez a3, .LBB42_1
1736 ; RV32IA-NEXT: # %bb.4:
1737 ; RV32IA-NEXT: srl a0, a5, a2
1738 ; RV32IA-NEXT: ret
8871739 %1 = atomicrmw min i8* %a, i8 %b release
8881740 ret i8 %1
8891741 }
9371789 ; RV32I-NEXT: lw ra, 28(sp)
9381790 ; RV32I-NEXT: addi sp, sp, 32
9391791 ; RV32I-NEXT: ret
1792 ;
1793 ; RV32IA-LABEL: atomicrmw_min_i8_acq_rel:
1794 ; RV32IA: # %bb.0:
1795 ; RV32IA-NEXT: slli a2, a0, 3
1796 ; RV32IA-NEXT: andi a2, a2, 24
1797 ; RV32IA-NEXT: addi a3, zero, 24
1798 ; RV32IA-NEXT: sub a6, a3, a2
1799 ; RV32IA-NEXT: addi a4, zero, 255
1800 ; RV32IA-NEXT: sll a7, a4, a2
1801 ; RV32IA-NEXT: slli a1, a1, 24
1802 ; RV32IA-NEXT: srai a1, a1, 24
1803 ; RV32IA-NEXT: sll a1, a1, a2
1804 ; RV32IA-NEXT: andi a0, a0, -4
1805 ; RV32IA-NEXT: .LBB43_1: # =>This Inner Loop Header: Depth=1
1806 ; RV32IA-NEXT: lr.w.aq a5, (a0)
1807 ; RV32IA-NEXT: and a4, a5, a7
1808 ; RV32IA-NEXT: mv a3, a5
1809 ; RV32IA-NEXT: sll a4, a4, a6
1810 ; RV32IA-NEXT: sra a4, a4, a6
1811 ; RV32IA-NEXT: bge a1, a4, .LBB43_3
1812 ; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB43_1 Depth=1
1813 ; RV32IA-NEXT: xor a3, a5, a1
1814 ; RV32IA-NEXT: and a3, a3, a7
1815 ; RV32IA-NEXT: xor a3, a5, a3
1816 ; RV32IA-NEXT: .LBB43_3: # in Loop: Header=BB43_1 Depth=1
1817 ; RV32IA-NEXT: sc.w.rl a3, a3, (a0)
1818 ; RV32IA-NEXT: bnez a3, .LBB43_1
1819 ; RV32IA-NEXT: # %bb.4:
1820 ; RV32IA-NEXT: srl a0, a5, a2
1821 ; RV32IA-NEXT: ret
9401822 %1 = atomicrmw min i8* %a, i8 %b acq_rel
9411823 ret i8 %1
9421824 }
9871869 ; RV32I-NEXT: lw ra, 28(sp)
9881870 ; RV32I-NEXT: addi sp, sp, 32
9891871 ; RV32I-NEXT: ret
1872 ;
1873 ; RV32IA-LABEL: atomicrmw_min_i8_seq_cst:
1874 ; RV32IA: # %bb.0:
1875 ; RV32IA-NEXT: slli a2, a0, 3
1876 ; RV32IA-NEXT: andi a2, a2, 24
1877 ; RV32IA-NEXT: addi a3, zero, 24
1878 ; RV32IA-NEXT: sub a6, a3, a2
1879 ; RV32IA-NEXT: addi a4, zero, 255
1880 ; RV32IA-NEXT: sll a7, a4, a2
1881 ; RV32IA-NEXT: slli a1, a1, 24
1882 ; RV32IA-NEXT: srai a1, a1, 24
1883 ; RV32IA-NEXT: sll a1, a1, a2
1884 ; RV32IA-NEXT: andi a0, a0, -4
1885 ; RV32IA-NEXT: .LBB44_1: # =>This Inner Loop Header: Depth=1
1886 ; RV32IA-NEXT: lr.w.aqrl a5, (a0)
1887 ; RV32IA-NEXT: and a4, a5, a7
1888 ; RV32IA-NEXT: mv a3, a5
1889 ; RV32IA-NEXT: sll a4, a4, a6
1890 ; RV32IA-NEXT: sra a4, a4, a6
1891 ; RV32IA-NEXT: bge a1, a4, .LBB44_3
1892 ; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB44_1 Depth=1
1893 ; RV32IA-NEXT: xor a3, a5, a1
1894 ; RV32IA-NEXT: and a3, a3, a7
1895 ; RV32IA-NEXT: xor a3, a5, a3
1896 ; RV32IA-NEXT: .LBB44_3: # in Loop: Header=BB44_1 Depth=1
1897 ; RV32IA-NEXT: sc.w.aqrl a3, a3, (a0)
1898 ; RV32IA-NEXT: bnez a3, .LBB44_1
1899 ; RV32IA-NEXT: # %bb.4:
1900 ; RV32IA-NEXT: srl a0, a5, a2
1901 ; RV32IA-NEXT: ret
9901902 %1 = atomicrmw min i8* %a, i8 %b seq_cst
9911903 ret i8 %1
9921904 }
10321944 ; RV32I-NEXT: lw ra, 28(sp)
10331945 ; RV32I-NEXT: addi sp, sp, 32
10341946 ; RV32I-NEXT: ret
1947 ;
1948 ; RV32IA-LABEL: atomicrmw_umax_i8_monotonic:
1949 ; RV32IA: # %bb.0:
1950 ; RV32IA-NEXT: slli a2, a0, 3
1951 ; RV32IA-NEXT: andi a2, a2, 24
1952 ; RV32IA-NEXT: addi a3, zero, 255
1953 ; RV32IA-NEXT: sll a6, a3, a2
1954 ; RV32IA-NEXT: andi a1, a1, 255
1955 ; RV32IA-NEXT: sll a1, a1, a2
1956 ; RV32IA-NEXT: andi a0, a0, -4
1957 ; RV32IA-NEXT: .LBB45_1: # =>This Inner Loop Header: Depth=1
1958 ; RV32IA-NEXT: lr.w a4, (a0)
1959 ; RV32IA-NEXT: and a3, a4, a6
1960 ; RV32IA-NEXT: mv a5, a4
1961 ; RV32IA-NEXT: bgeu a3, a1, .LBB45_3
1962 ; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB45_1 Depth=1
1963 ; RV32IA-NEXT: xor a5, a4, a1
1964 ; RV32IA-NEXT: and a5, a5, a6
1965 ; RV32IA-NEXT: xor a5, a4, a5
1966 ; RV32IA-NEXT: .LBB45_3: # in Loop: Header=BB45_1 Depth=1
1967 ; RV32IA-NEXT: sc.w a5, a5, (a0)
1968 ; RV32IA-NEXT: bnez a5, .LBB45_1
1969 ; RV32IA-NEXT: # %bb.4:
1970 ; RV32IA-NEXT: srl a0, a4, a2
1971 ; RV32IA-NEXT: ret
10351972 %1 = atomicrmw umax i8* %a, i8 %b monotonic
10361973 ret i8 %1
10371974 }
10802017 ; RV32I-NEXT: lw ra, 28(sp)
10812018 ; RV32I-NEXT: addi sp, sp, 32
10822019 ; RV32I-NEXT: ret
2020 ;
2021 ; RV32IA-LABEL: atomicrmw_umax_i8_acquire:
2022 ; RV32IA: # %bb.0:
2023 ; RV32IA-NEXT: slli a2, a0, 3
2024 ; RV32IA-NEXT: andi a2, a2, 24
2025 ; RV32IA-NEXT: addi a3, zero, 255
2026 ; RV32IA-NEXT: sll a6, a3, a2
2027 ; RV32IA-NEXT: andi a1, a1, 255
2028 ; RV32IA-NEXT: sll a1, a1, a2
2029 ; RV32IA-NEXT: andi a0, a0, -4
2030 ; RV32IA-NEXT: .LBB46_1: # =>This Inner Loop Header: Depth=1
2031 ; RV32IA-NEXT: lr.w.aq a4, (a0)
2032 ; RV32IA-NEXT: and a3, a4, a6
2033 ; RV32IA-NEXT: mv a5, a4
2034 ; RV32IA-NEXT: bgeu a3, a1, .LBB46_3
2035 ; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB46_1 Depth=1
2036 ; RV32IA-NEXT: xor a5, a4, a1
2037 ; RV32IA-NEXT: and a5, a5, a6
2038 ; RV32IA-NEXT: xor a5, a4, a5
2039 ; RV32IA-NEXT: .LBB46_3: # in Loop: Header=BB46_1 Depth=1
2040 ; RV32IA-NEXT: sc.w a5, a5, (a0)
2041 ; RV32IA-NEXT: bnez a5, .LBB46_1
2042 ; RV32IA-NEXT: # %bb.4:
2043 ; RV32IA-NEXT: srl a0, a4, a2
2044 ; RV32IA-NEXT: ret
10832045 %1 = atomicrmw umax i8* %a, i8 %b acquire
10842046 ret i8 %1
10852047 }
11282090 ; RV32I-NEXT: lw ra, 28(sp)
11292091 ; RV32I-NEXT: addi sp, sp, 32
11302092 ; RV32I-NEXT: ret
2093 ;
2094 ; RV32IA-LABEL: atomicrmw_umax_i8_release:
2095 ; RV32IA: # %bb.0:
2096 ; RV32IA-NEXT: slli a2, a0, 3
2097 ; RV32IA-NEXT: andi a2, a2, 24
2098 ; RV32IA-NEXT: addi a3, zero, 255
2099 ; RV32IA-NEXT: sll a6, a3, a2
2100 ; RV32IA-NEXT: andi a1, a1, 255
2101 ; RV32IA-NEXT: sll a1, a1, a2
2102 ; RV32IA-NEXT: andi a0, a0, -4
2103 ; RV32IA-NEXT: .LBB47_1: # =>This Inner Loop Header: Depth=1
2104 ; RV32IA-NEXT: lr.w a4, (a0)
2105 ; RV32IA-NEXT: and a3, a4, a6
2106 ; RV32IA-NEXT: mv a5, a4
2107 ; RV32IA-NEXT: bgeu a3, a1, .LBB47_3
2108 ; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB47_1 Depth=1
2109 ; RV32IA-NEXT: xor a5, a4, a1
2110 ; RV32IA-NEXT: and a5, a5, a6
2111 ; RV32IA-NEXT: xor a5, a4, a5
2112 ; RV32IA-NEXT: .LBB47_3: # in Loop: Header=BB47_1 Depth=1
2113 ; RV32IA-NEXT: sc.w.rl a5, a5, (a0)
2114 ; RV32IA-NEXT: bnez a5, .LBB47_1
2115 ; RV32IA-NEXT: # %bb.4:
2116 ; RV32IA-NEXT: srl a0, a4, a2
2117 ; RV32IA-NEXT: ret
11312118 %1 = atomicrmw umax i8* %a, i8 %b release
11322119 ret i8 %1
11332120 }
11792166 ; RV32I-NEXT: lw ra, 28(sp)
11802167 ; RV32I-NEXT: addi sp, sp, 32
11812168 ; RV32I-NEXT: ret
2169 ;
2170 ; RV32IA-LABEL: atomicrmw_umax_i8_acq_rel:
2171 ; RV32IA: # %bb.0:
2172 ; RV32IA-NEXT: slli a2, a0, 3
2173 ; RV32IA-NEXT: andi a2, a2, 24
2174 ; RV32IA-NEXT: addi a3, zero, 255
2175 ; RV32IA-NEXT: sll a6, a3, a2
2176 ; RV32IA-NEXT: andi a1, a1, 255
2177 ; RV32IA-NEXT: sll a1, a1, a2
2178 ; RV32IA-NEXT: andi a0, a0, -4
2179 ; RV32IA-NEXT: .LBB48_1: # =>This Inner Loop Header: Depth=1
2180 ; RV32IA-NEXT: lr.w.aq a4, (a0)
2181 ; RV32IA-NEXT: and a3, a4, a6
2182 ; RV32IA-NEXT: mv a5, a4
2183 ; RV32IA-NEXT: bgeu a3, a1, .LBB48_3
2184 ; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB48_1 Depth=1
2185 ; RV32IA-NEXT: xor a5, a4, a1
2186 ; RV32IA-NEXT: and a5, a5, a6
2187 ; RV32IA-NEXT: xor a5, a4, a5
2188 ; RV32IA-NEXT: .LBB48_3: # in Loop: Header=BB48_1 Depth=1
2189 ; RV32IA-NEXT: sc.w.rl a5, a5, (a0)
2190 ; RV32IA-NEXT: bnez a5, .LBB48_1
2191 ; RV32IA-NEXT: # %bb.4:
2192 ; RV32IA-NEXT: srl a0, a4, a2
2193 ; RV32IA-NEXT: ret
11822194 %1 = atomicrmw umax i8* %a, i8 %b acq_rel
11832195 ret i8 %1
11842196 }
12272239 ; RV32I-NEXT: lw ra, 28(sp)
12282240 ; RV32I-NEXT: addi sp, sp, 32
12292241 ; RV32I-NEXT: ret
2242 ;
2243 ; RV32IA-LABEL: atomicrmw_umax_i8_seq_cst:
2244 ; RV32IA: # %bb.0:
2245 ; RV32IA-NEXT: slli a2, a0, 3
2246 ; RV32IA-NEXT: andi a2, a2, 24
2247 ; RV32IA-NEXT: addi a3, zero, 255
2248 ; RV32IA-NEXT: sll a6, a3, a2
2249 ; RV32IA-NEXT: andi a1, a1, 255
2250 ; RV32IA-NEXT: sll a1, a1, a2
2251 ; RV32IA-NEXT: andi a0, a0, -4
2252 ; RV32IA-NEXT: .LBB49_1: # =>This Inner Loop Header: Depth=1
2253 ; RV32IA-NEXT: lr.w.aqrl a4, (a0)
2254 ; RV32IA-NEXT: and a3, a4, a6
2255 ; RV32IA-NEXT: mv a5, a4
2256 ; RV32IA-NEXT: bgeu a3, a1, .LBB49_3
2257 ; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB49_1 Depth=1
2258 ; RV32IA-NEXT: xor a5, a4, a1
2259 ; RV32IA-NEXT: and a5, a5, a6
2260 ; RV32IA-NEXT: xor a5, a4, a5
2261 ; RV32IA-NEXT: .LBB49_3: # in Loop: Header=BB49_1 Depth=1
2262 ; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0)
2263 ; RV32IA-NEXT: bnez a5, .LBB49_1
2264 ; RV32IA-NEXT: # %bb.4:
2265 ; RV32IA-NEXT: srl a0, a4, a2
2266 ; RV32IA-NEXT: ret
12302267 %1 = atomicrmw umax i8* %a, i8 %b seq_cst
12312268 ret i8 %1
12322269 }
12722309 ; RV32I-NEXT: lw ra, 28(sp)
12732310 ; RV32I-NEXT: addi sp, sp, 32
12742311 ; RV32I-NEXT: ret
2312 ;
2313 ; RV32IA-LABEL: atomicrmw_umin_i8_monotonic:
2314 ; RV32IA: # %bb.0:
2315 ; RV32IA-NEXT: slli a2, a0, 3
2316 ; RV32IA-NEXT: andi a2, a2, 24
2317 ; RV32IA-NEXT: addi a3, zero, 255
2318 ; RV32IA-NEXT: sll a6, a3, a2
2319 ; RV32IA-NEXT: andi a1, a1, 255
2320 ; RV32IA-NEXT: sll a1, a1, a2
2321 ; RV32IA-NEXT: andi a0, a0, -4
2322 ; RV32IA-NEXT: .LBB50_1: # =>This Inner Loop Header: Depth=1
2323 ; RV32IA-NEXT: lr.w a4, (a0)
2324 ; RV32IA-NEXT: and a3, a4, a6
2325 ; RV32IA-NEXT: mv a5, a4
2326 ; RV32IA-NEXT: bgeu a1, a3, .LBB50_3
2327 ; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB50_1 Depth=1
2328 ; RV32IA-NEXT: xor a5, a4, a1
2329 ; RV32IA-NEXT: and a5, a5, a6
2330 ; RV32IA-NEXT: xor a5, a4, a5
2331 ; RV32IA-NEXT: .LBB50_3: # in Loop: Header=BB50_1 Depth=1
2332 ; RV32IA-NEXT: sc.w a5, a5, (a0)
2333 ; RV32IA-NEXT: bnez a5, .LBB50_1
2334 ; RV32IA-NEXT: # %bb.4:
2335 ; RV32IA-NEXT: srl a0, a4, a2
2336 ; RV32IA-NEXT: ret
12752337 %1 = atomicrmw umin i8* %a, i8 %b monotonic
12762338 ret i8 %1
12772339 }
13202382 ; RV32I-NEXT: lw ra, 28(sp)
13212383 ; RV32I-NEXT: addi sp, sp, 32
13222384 ; RV32I-NEXT: ret
2385 ;
2386 ; RV32IA-LABEL: atomicrmw_umin_i8_acquire:
2387 ; RV32IA: # %bb.0:
2388 ; RV32IA-NEXT: slli a2, a0, 3
2389 ; RV32IA-NEXT: andi a2, a2, 24
2390 ; RV32IA-NEXT: addi a3, zero, 255
2391 ; RV32IA-NEXT: sll a6, a3, a2
2392 ; RV32IA-NEXT: andi a1, a1, 255
2393 ; RV32IA-NEXT: sll a1, a1, a2
2394 ; RV32IA-NEXT: andi a0, a0, -4
2395 ; RV32IA-NEXT: .LBB51_1: # =>This Inner Loop Header: Depth=1
2396 ; RV32IA-NEXT: lr.w.aq a4, (a0)
2397 ; RV32IA-NEXT: and a3, a4, a6
2398 ; RV32IA-NEXT: mv a5, a4
2399 ; RV32IA-NEXT: bgeu a1, a3, .LBB51_3
2400 ; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB51_1 Depth=1
2401 ; RV32IA-NEXT: xor a5, a4, a1
2402 ; RV32IA-NEXT: and a5, a5, a6
2403 ; RV32IA-NEXT: xor a5, a4, a5
2404 ; RV32IA-NEXT: .LBB51_3: # in Loop: Header=BB51_1 Depth=1
2405 ; RV32IA-NEXT: sc.w a5, a5, (a0)
2406 ; RV32IA-NEXT: bnez a5, .LBB51_1
2407 ; RV32IA-NEXT: # %bb.4:
2408 ; RV32IA-NEXT: srl a0, a4, a2
2409 ; RV32IA-NEXT: ret
13232410 %1 = atomicrmw umin i8* %a, i8 %b acquire
13242411 ret i8 %1
13252412 }
13682455 ; RV32I-NEXT: lw ra, 28(sp)
13692456 ; RV32I-NEXT: addi sp, sp, 32
13702457 ; RV32I-NEXT: ret
2458 ;
2459 ; RV32IA-LABEL: atomicrmw_umin_i8_release:
2460 ; RV32IA: # %bb.0:
2461 ; RV32IA-NEXT: slli a2, a0, 3
2462 ; RV32IA-NEXT: andi a2, a2, 24
2463 ; RV32IA-NEXT: addi a3, zero, 255
2464 ; RV32IA-NEXT: sll a6, a3, a2
2465 ; RV32IA-NEXT: andi a1, a1, 255
2466 ; RV32IA-NEXT: sll a1, a1, a2
2467 ; RV32IA-NEXT: andi a0, a0, -4
2468 ; RV32IA-NEXT: .LBB52_1: # =>This Inner Loop Header: Depth=1
2469 ; RV32IA-NEXT: lr.w a4, (a0)
2470 ; RV32IA-NEXT: and a3, a4, a6
2471 ; RV32IA-NEXT: mv a5, a4
2472 ; RV32IA-NEXT: bgeu a1, a3, .LBB52_3
2473 ; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB52_1 Depth=1
2474 ; RV32IA-NEXT: xor a5, a4, a1
2475 ; RV32IA-NEXT: and a5, a5, a6
2476 ; RV32IA-NEXT: xor a5, a4, a5
2477 ; RV32IA-NEXT: .LBB52_3: # in Loop: Header=BB52_1 Depth=1
2478 ; RV32IA-NEXT: sc.w.rl a5, a5, (a0)
2479 ; RV32IA-NEXT: bnez a5, .LBB52_1
2480 ; RV32IA-NEXT: # %bb.4:
2481 ; RV32IA-NEXT: srl a0, a4, a2
2482 ; RV32IA-NEXT: ret
13712483 %1 = atomicrmw umin i8* %a, i8 %b release
13722484 ret i8 %1
13732485 }
14192531 ; RV32I-NEXT: lw ra, 28(sp)
14202532 ; RV32I-NEXT: addi sp, sp, 32
14212533 ; RV32I-NEXT: ret
2534 ;
2535 ; RV32IA-LABEL: atomicrmw_umin_i8_acq_rel:
2536 ; RV32IA: # %bb.0:
2537 ; RV32IA-NEXT: slli a2, a0, 3
2538 ; RV32IA-NEXT: andi a2, a2, 24
2539 ; RV32IA-NEXT: addi a3, zero, 255
2540 ; RV32IA-NEXT: sll a6, a3, a2
2541 ; RV32IA-NEXT: andi a1, a1, 255
2542 ; RV32IA-NEXT: sll a1, a1, a2
2543 ; RV32IA-NEXT: andi a0, a0, -4
2544 ; RV32IA-NEXT: .LBB53_1: # =>This Inner Loop Header: Depth=1
2545 ; RV32IA-NEXT: lr.w.aq a4, (a0)
2546 ; RV32IA-NEXT: and a3, a4, a6
2547 ; RV32IA-NEXT: mv a5, a4
2548 ; RV32IA-NEXT: bgeu a1, a3, .LBB53_3
2549 ; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB53_1 Depth=1
2550 ; RV32IA-NEXT: xor a5, a4, a1
2551 ; RV32IA-NEXT: and a5, a5, a6
2552 ; RV32IA-NEXT: xor a5, a4, a5
2553 ; RV32IA-NEXT: .LBB53_3: # in Loop: Header=BB53_1 Depth=1
2554 ; RV32IA-NEXT: sc.w.rl a5, a5, (a0)
2555 ; RV32IA-NEXT: bnez a5, .LBB53_1
2556 ; RV32IA-NEXT: # %bb.4:
2557 ; RV32IA-NEXT: srl a0, a4, a2
2558 ; RV32IA-NEXT: ret
14222559 %1 = atomicrmw umin i8* %a, i8 %b acq_rel
14232560 ret i8 %1
14242561 }
14672604 ; RV32I-NEXT: lw ra, 28(sp)
14682605 ; RV32I-NEXT: addi sp, sp, 32
14692606 ; RV32I-NEXT: ret
2607 ;
2608 ; RV32IA-LABEL: atomicrmw_umin_i8_seq_cst:
2609 ; RV32IA: # %bb.0:
2610 ; RV32IA-NEXT: slli a2, a0, 3
2611 ; RV32IA-NEXT: andi a2, a2, 24
2612 ; RV32IA-NEXT: addi a3, zero, 255
2613 ; RV32IA-NEXT: sll a6, a3, a2
2614 ; RV32IA-NEXT: andi a1, a1, 255
2615 ; RV32IA-NEXT: sll a1, a1, a2
2616 ; RV32IA-NEXT: andi a0, a0, -4
2617 ; RV32IA-NEXT: .LBB54_1: # =>This Inner Loop Header: Depth=1
2618 ; RV32IA-NEXT: lr.w.aqrl a4, (a0)
2619 ; RV32IA-NEXT: and a3, a4, a6
2620 ; RV32IA-NEXT: mv a5, a4
2621 ; RV32IA-NEXT: bgeu a1, a3, .LBB54_3
2622 ; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB54_1 Depth=1
2623 ; RV32IA-NEXT: xor a5, a4, a1
2624 ; RV32IA-NEXT: and a5, a5, a6
2625 ; RV32IA-NEXT: xor a5, a4, a5
2626 ; RV32IA-NEXT: .LBB54_3: # in Loop: Header=BB54_1 Depth=1
2627 ; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0)
2628 ; RV32IA-NEXT: bnez a5, .LBB54_1
2629 ; RV32IA-NEXT: # %bb.4:
2630 ; RV32IA-NEXT: srl a0, a4, a2
2631 ; RV32IA-NEXT: ret
14702632 %1 = atomicrmw umin i8* %a, i8 %b seq_cst
14712633 ret i8 %1
14722634 }
14812643 ; RV32I-NEXT: lw ra, 12(sp)
14822644 ; RV32I-NEXT: addi sp, sp, 16
14832645 ; RV32I-NEXT: ret
2646 ;
2647 ; RV32IA-LABEL: atomicrmw_xchg_i16_monotonic:
2648 ; RV32IA: # %bb.0:
2649 ; RV32IA-NEXT: lui a2, 16
2650 ; RV32IA-NEXT: addi a2, a2, -1
2651 ; RV32IA-NEXT: and a1, a1, a2
2652 ; RV32IA-NEXT: slli a3, a0, 3
2653 ; RV32IA-NEXT: andi a3, a3, 24
2654 ; RV32IA-NEXT: sll a2, a2, a3
2655 ; RV32IA-NEXT: sll a1, a1, a3
2656 ; RV32IA-NEXT: andi a0, a0, -4
2657 ; RV32IA-NEXT: .LBB55_1: # =>This Inner Loop Header: Depth=1
2658 ; RV32IA-NEXT: lr.w a4, (a0)
2659 ; RV32IA-NEXT: add a5, zero, a1
2660 ; RV32IA-NEXT: xor a5, a4, a5
2661 ; RV32IA-NEXT: and a5, a5, a2
2662 ; RV32IA-NEXT: xor a5, a4, a5
2663 ; RV32IA-NEXT: sc.w a5, a5, (a0)
2664 ; RV32IA-NEXT: bnez a5, .LBB55_1
2665 ; RV32IA-NEXT: # %bb.2:
2666 ; RV32IA-NEXT: srl a0, a4, a3
2667 ; RV32IA-NEXT: ret
14842668 %1 = atomicrmw xchg i16* %a, i16 %b monotonic
14852669 ret i16 %1
14862670 }
14952679 ; RV32I-NEXT: lw ra, 12(sp)
14962680 ; RV32I-NEXT: addi sp, sp, 16
14972681 ; RV32I-NEXT: ret
2682 ;
2683 ; RV32IA-LABEL: atomicrmw_xchg_i16_acquire:
2684 ; RV32IA: # %bb.0:
2685 ; RV32IA-NEXT: lui a2, 16
2686 ; RV32IA-NEXT: addi a2, a2, -1
2687 ; RV32IA-NEXT: and a1, a1, a2
2688 ; RV32IA-NEXT: slli a3, a0, 3
2689 ; RV32IA-NEXT: andi a3, a3, 24
2690 ; RV32IA-NEXT: sll a2, a2, a3
2691 ; RV32IA-NEXT: sll a1, a1, a3
2692 ; RV32IA-NEXT: andi a0, a0, -4
2693 ; RV32IA-NEXT: .LBB56_1: # =>This Inner Loop Header: Depth=1
2694 ; RV32IA-NEXT: lr.w.aq a4, (a0)
2695 ; RV32IA-NEXT: add a5, zero, a1
2696 ; RV32IA-NEXT: xor a5, a4, a5
2697 ; RV32IA-NEXT: and a5, a5, a2
2698 ; RV32IA-NEXT: xor a5, a4, a5
2699 ; RV32IA-NEXT: sc.w a5, a5, (a0)
2700 ; RV32IA-NEXT: bnez a5, .LBB56_1
2701 ; RV32IA-NEXT: # %bb.2:
2702 ; RV32IA-NEXT: srl a0, a4, a3
2703 ; RV32IA-NEXT: ret
14982704 %1 = atomicrmw xchg i16* %a, i16 %b acquire
14992705 ret i16 %1
15002706 }
15092715 ; RV32I-NEXT: lw ra, 12(sp)
15102716 ; RV32I-NEXT: addi sp, sp, 16
15112717 ; RV32I-NEXT: ret
2718 ;
2719 ; RV32IA-LABEL: atomicrmw_xchg_i16_release:
2720 ; RV32IA: # %bb.0:
2721 ; RV32IA-NEXT: lui a2, 16
2722 ; RV32IA-NEXT: addi a2, a2, -1
2723 ; RV32IA-NEXT: and a1, a1, a2
2724 ; RV32IA-NEXT: slli a3, a0, 3
2725 ; RV32IA-NEXT: andi a3, a3, 24
2726 ; RV32IA-NEXT: sll a2, a2, a3
2727 ; RV32IA-NEXT: sll a1, a1, a3
2728 ; RV32IA-NEXT: andi a0, a0, -4
2729 ; RV32IA-NEXT: .LBB57_1: # =>This Inner Loop Header: Depth=1
2730 ; RV32IA-NEXT: lr.w a4, (a0)
2731 ; RV32IA-NEXT: add a5, zero, a1
2732 ; RV32IA-NEXT: xor a5, a4, a5
2733 ; RV32IA-NEXT: and a5, a5, a2
2734 ; RV32IA-NEXT: xor a5, a4, a5
2735 ; RV32IA-NEXT: sc.w.rl a5, a5, (a0)
2736 ; RV32IA-NEXT: bnez a5, .LBB57_1
2737 ; RV32IA-NEXT: # %bb.2:
2738 ; RV32IA-NEXT: srl a0, a4, a3
2739 ; RV32IA-NEXT: ret
15122740 %1 = atomicrmw xchg i16* %a, i16 %b release
15132741 ret i16 %1
15142742 }
15232751 ; RV32I-NEXT: lw ra, 12(sp)
15242752 ; RV32I-NEXT: addi sp, sp, 16
15252753 ; RV32I-NEXT: ret
2754 ;
2755 ; RV32IA-LABEL: atomicrmw_xchg_i16_acq_rel:
2756 ; RV32IA: # %bb.0:
2757 ; RV32IA-NEXT: lui a2, 16
2758 ; RV32IA-NEXT: addi a2, a2, -1
2759 ; RV32IA-NEXT: and a1, a1, a2
2760 ; RV32IA-NEXT: slli a3, a0, 3
2761 ; RV32IA-NEXT: andi a3, a3, 24
2762 ; RV32IA-NEXT: sll a2, a2, a3
2763 ; RV32IA-NEXT: sll a1, a1, a3
2764 ; RV32IA-NEXT: andi a0, a0, -4
2765 ; RV32IA-NEXT: .LBB58_1: # =>This Inner Loop Header: Depth=1
2766 ; RV32IA-NEXT: lr.w.aq a4, (a0)
2767 ; RV32IA-NEXT: add a5, zero, a1
2768 ; RV32IA-NEXT: xor a5, a4, a5
2769 ; RV32IA-NEXT: and a5, a5, a2
2770 ; RV32IA-NEXT: xor a5, a4, a5
2771 ; RV32IA-NEXT: sc.w.rl a5, a5, (a0)
2772 ; RV32IA-NEXT: bnez a5, .LBB58_1
2773 ; RV32IA-NEXT: # %bb.2:
2774 ; RV32IA-NEXT: srl a0, a4, a3
2775 ; RV32IA-NEXT: ret
15262776 %1 = atomicrmw xchg i16* %a, i16 %b acq_rel
15272777 ret i16 %1
15282778 }
15372787 ; RV32I-NEXT: lw ra, 12(sp)
15382788 ; RV32I-NEXT: addi sp, sp, 16
15392789 ; RV32I-NEXT: ret
2790 ;
2791 ; RV32IA-LABEL: atomicrmw_xchg_i16_seq_cst:
2792 ; RV32IA: # %bb.0:
2793 ; RV32IA-NEXT: lui a2, 16
2794 ; RV32IA-NEXT: addi a2, a2, -1
2795 ; RV32IA-NEXT: and a1, a1, a2
2796 ; RV32IA-NEXT: slli a3, a0, 3
2797 ; RV32IA-NEXT: andi a3, a3, 24
2798 ; RV32IA-NEXT: sll a2, a2, a3
2799 ; RV32IA-NEXT: sll a1, a1, a3
2800 ; RV32IA-NEXT: andi a0, a0, -4
2801 ; RV32IA-NEXT: .LBB59_1: # =>This Inner Loop Header: Depth=1
2802 ; RV32IA-NEXT: lr.w.aqrl a4, (a0)
2803 ; RV32IA-NEXT: add a5, zero, a1
2804 ; RV32IA-NEXT: xor a5, a4, a5
2805 ; RV32IA-NEXT: and a5, a5, a2
2806 ; RV32IA-NEXT: xor a5, a4, a5
2807 ; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0)
2808 ; RV32IA-NEXT: bnez a5, .LBB59_1
2809 ; RV32IA-NEXT: # %bb.2:
2810 ; RV32IA-NEXT: srl a0, a4, a3
2811 ; RV32IA-NEXT: ret
15402812 %1 = atomicrmw xchg i16* %a, i16 %b seq_cst
15412813 ret i16 %1
15422814 }
15512823 ; RV32I-NEXT: lw ra, 12(sp)
15522824 ; RV32I-NEXT: addi sp, sp, 16
15532825 ; RV32I-NEXT: ret
2826 ;
2827 ; RV32IA-LABEL: atomicrmw_add_i16_monotonic:
2828 ; RV32IA: # %bb.0:
2829 ; RV32IA-NEXT: lui a2, 16
2830 ; RV32IA-NEXT: addi a2, a2, -1
2831 ; RV32IA-NEXT: and a1, a1, a2
2832 ; RV32IA-NEXT: slli a3, a0, 3
2833 ; RV32IA-NEXT: andi a3, a3, 24
2834 ; RV32IA-NEXT: sll a2, a2, a3
2835 ; RV32IA-NEXT: sll a1, a1, a3
2836 ; RV32IA-NEXT: andi a0, a0, -4
2837 ; RV32IA-NEXT: .LBB60_1: # =>This Inner Loop Header: Depth=1
2838 ; RV32IA-NEXT: lr.w a4, (a0)
2839 ; RV32IA-NEXT: add a5, a4, a1
2840 ; RV32IA-NEXT: xor a5, a4, a5
2841 ; RV32IA-NEXT: and a5, a5, a2
2842 ; RV32IA-NEXT: xor a5, a4, a5
2843 ; RV32IA-NEXT: sc.w a5, a5, (a0)
2844 ; RV32IA-NEXT: bnez a5, .LBB60_1
2845 ; RV32IA-NEXT: # %bb.2:
2846 ; RV32IA-NEXT: srl a0, a4, a3
2847 ; RV32IA-NEXT: ret
15542848 %1 = atomicrmw add i16* %a, i16 %b monotonic
15552849 ret i16 %1
15562850 }
15652859 ; RV32I-NEXT: lw ra, 12(sp)
15662860 ; RV32I-NEXT: addi sp, sp, 16
15672861 ; RV32I-NEXT: ret
2862 ;
2863 ; RV32IA-LABEL: atomicrmw_add_i16_acquire:
2864 ; RV32IA: # %bb.0:
2865 ; RV32IA-NEXT: lui a2, 16
2866 ; RV32IA-NEXT: addi a2, a2, -1
2867 ; RV32IA-NEXT: and a1, a1, a2
2868 ; RV32IA-NEXT: slli a3, a0, 3
2869 ; RV32IA-NEXT: andi a3, a3, 24
2870 ; RV32IA-NEXT: sll a2, a2, a3
2871 ; RV32IA-NEXT: sll a1, a1, a3
2872 ; RV32IA-NEXT: andi a0, a0, -4
2873 ; RV32IA-NEXT: .LBB61_1: # =>This Inner Loop Header: Depth=1
2874 ; RV32IA-NEXT: lr.w.aq a4, (a0)
2875 ; RV32IA-NEXT: add a5, a4, a1
2876 ; RV32IA-NEXT: xor a5, a4, a5
2877 ; RV32IA-NEXT: and a5, a5, a2
2878 ; RV32IA-NEXT: xor a5, a4, a5
2879 ; RV32IA-NEXT: sc.w a5, a5, (a0)
2880 ; RV32IA-NEXT: bnez a5, .LBB61_1
2881 ; RV32IA-NEXT: # %bb.2:
2882 ; RV32IA-NEXT: srl a0, a4, a3
2883 ; RV32IA-NEXT: ret
15682884 %1 = atomicrmw add i16* %a, i16 %b acquire
15692885 ret i16 %1
15702886 }
15792895 ; RV32I-NEXT: lw ra, 12(sp)
15802896 ; RV32I-NEXT: addi sp, sp, 16
15812897 ; RV32I-NEXT: ret
2898 ;
2899 ; RV32IA-LABEL: atomicrmw_add_i16_release:
2900 ; RV32IA: # %bb.0:
2901 ; RV32IA-NEXT: lui a2, 16
2902 ; RV32IA-NEXT: addi a2, a2, -1
2903 ; RV32IA-NEXT: and a1, a1, a2
2904 ; RV32IA-NEXT: slli a3, a0, 3
2905 ; RV32IA-NEXT: andi a3, a3, 24
2906 ; RV32IA-NEXT: sll a2, a2, a3
2907 ; RV32IA-NEXT: sll a1, a1, a3
2908 ; RV32IA-NEXT: andi a0, a0, -4
2909 ; RV32IA-NEXT: .LBB62_1: # =>This Inner Loop Header: Depth=1
2910 ; RV32IA-NEXT: lr.w a4, (a0)
2911 ; RV32IA-NEXT: add a5, a4, a1
2912 ; RV32IA-NEXT: xor a5, a4, a5
2913 ; RV32IA-NEXT: and a5, a5, a2
2914 ; RV32IA-NEXT: xor a5, a4, a5
2915 ; RV32IA-NEXT: sc.w.rl a5, a5, (a0)
2916 ; RV32IA-NEXT: bnez a5, .LBB62_1
2917 ; RV32IA-NEXT: # %bb.2:
2918 ; RV32IA-NEXT: srl a0, a4, a3
2919 ; RV32IA-NEXT: ret
15822920 %1 = atomicrmw add i16* %a, i16 %b release
15832921 ret i16 %1
15842922 }
15932931 ; RV32I-NEXT: lw ra, 12(sp)
15942932 ; RV32I-NEXT: addi sp, sp, 16
15952933 ; RV32I-NEXT: ret
2934 ;
2935 ; RV32IA-LABEL: atomicrmw_add_i16_acq_rel:
2936 ; RV32IA: # %bb.0:
2937 ; RV32IA-NEXT: lui a2, 16
2938 ; RV32IA-NEXT: addi a2, a2, -1
2939 ; RV32IA-NEXT: and a1, a1, a2
2940 ; RV32IA-NEXT: slli a3, a0, 3
2941 ; RV32IA-NEXT: andi a3, a3, 24
2942 ; RV32IA-NEXT: sll a2, a2, a3
2943 ; RV32IA-NEXT: sll a1, a1, a3
2944 ; RV32IA-NEXT: andi a0, a0, -4
2945 ; RV32IA-NEXT: .LBB63_1: # =>This Inner Loop Header: Depth=1
2946 ; RV32IA-NEXT: lr.w.aq a4, (a0)
2947 ; RV32IA-NEXT: add a5, a4, a1
2948 ; RV32IA-NEXT: xor a5, a4, a5
2949 ; RV32IA-NEXT: and a5, a5, a2
2950 ; RV32IA-NEXT: xor a5, a4, a5
2951 ; RV32IA-NEXT: sc.w.rl a5, a5, (a0)
2952 ; RV32IA-NEXT: bnez a5, .LBB63_1
2953 ; RV32IA-NEXT: # %bb.2:
2954 ; RV32IA-NEXT: srl a0, a4, a3
2955 ; RV32IA-NEXT: ret
15962956 %1 = atomicrmw add i16* %a, i16 %b acq_rel
15972957 ret i16 %1
15982958 }
16072967 ; RV32I-NEXT: lw ra, 12(sp)
16082968 ; RV32I-NEXT: addi sp, sp, 16
16092969 ; RV32I-NEXT: ret
2970 ;
2971 ; RV32IA-LABEL: atomicrmw_add_i16_seq_cst:
2972 ; RV32IA: # %bb.0:
2973 ; RV32IA-NEXT: lui a2, 16
2974 ; RV32IA-NEXT: addi a2, a2, -1
2975 ; RV32IA-NEXT: and a1, a1, a2
2976 ; RV32IA-NEXT: slli a3, a0, 3
2977 ; RV32IA-NEXT: andi a3, a3, 24
2978 ; RV32IA-NEXT: sll a2, a2, a3
2979 ; RV32IA-NEXT: sll a1, a1, a3
2980 ; RV32IA-NEXT: andi a0, a0, -4
2981 ; RV32IA-NEXT: .LBB64_1: # =>This Inner Loop Header: Depth=1
2982 ; RV32IA-NEXT: lr.w.aqrl a4, (a0)
2983 ; RV32IA-NEXT: add a5, a4, a1
2984 ; RV32IA-NEXT: xor a5, a4, a5
2985 ; RV32IA-NEXT: and a5, a5, a2
2986 ; RV32IA-NEXT: xor a5, a4, a5
2987 ; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0)
2988 ; RV32IA-NEXT: bnez a5, .LBB64_1
2989 ; RV32IA-NEXT: # %bb.2:
2990 ; RV32IA-NEXT: srl a0, a4, a3
2991 ; RV32IA-NEXT: ret
16102992 %1 = atomicrmw add i16* %a, i16 %b seq_cst
16112993 ret i16 %1
16122994 }
16213003 ; RV32I-NEXT: lw ra, 12(sp)
16223004 ; RV32I-NEXT: addi sp, sp, 16
16233005 ; RV32I-NEXT: ret
3006 ;
3007 ; RV32IA-LABEL: atomicrmw_sub_i16_monotonic:
3008 ; RV32IA: # %bb.0:
3009 ; RV32IA-NEXT: lui a2, 16
3010 ; RV32IA-NEXT: addi a2, a2, -1
3011 ; RV32IA-NEXT: and a1, a1, a2
3012 ; RV32IA-NEXT: slli a3, a0, 3
3013 ; RV32IA-NEXT: andi a3, a3, 24
3014 ; RV32IA-NEXT: sll a2, a2, a3
3015 ; RV32IA-NEXT: sll a1, a1, a3
3016 ; RV32IA-NEXT: andi a0, a0, -4
3017 ; RV32IA-NEXT: .LBB65_1: # =>This Inner Loop Header: Depth=1
3018 ; RV32IA-NEXT: lr.w a4, (a0)
3019 ; RV32IA-NEXT: sub a5, a4, a1
3020 ; RV32IA-NEXT: xor a5, a4, a5
3021 ; RV32IA-NEXT: and a5, a5, a2
3022 ; RV32IA-NEXT: xor a5, a4, a5
3023 ; RV32IA-NEXT: sc.w a5, a5, (a0)
3024 ; RV32IA-NEXT: bnez a5, .LBB65_1
3025 ; RV32IA-NEXT: # %bb.2:
3026 ; RV32IA-NEXT: srl a0, a4, a3
3027 ; RV32IA-NEXT: ret
16243028 %1 = atomicrmw sub i16* %a, i16 %b monotonic
16253029 ret i16 %1
16263030 }
16353039 ; RV32I-NEXT: lw ra, 12(sp)
16363040 ; RV32I-NEXT: addi sp, sp, 16
16373041 ; RV32I-NEXT: ret
3042 ;
3043 ; RV32IA-LABEL: atomicrmw_sub_i16_acquire:
3044 ; RV32IA: # %bb.0:
3045 ; RV32IA-NEXT: lui a2, 16
3046 ; RV32IA-NEXT: addi a2, a2, -1
3047 ; RV32IA-NEXT: and a1, a1, a2
3048 ; RV32IA-NEXT: slli a3, a0, 3
3049 ; RV32IA-NEXT: andi a3, a3, 24
3050 ; RV32IA-NEXT: sll a2, a2, a3
3051 ; RV32IA-NEXT: sll a1, a1, a3
3052 ; RV32IA-NEXT: andi a0, a0, -4
3053 ; RV32IA-NEXT: .LBB66_1: # =>This Inner Loop Header: Depth=1
3054 ; RV32IA-NEXT: lr.w.aq a4, (a0)
3055 ; RV32IA-NEXT: sub a5, a4, a1
3056 ; RV32IA-NEXT: xor a5, a4, a5
3057 ; RV32IA-NEXT: and a5, a5, a2
3058 ; RV32IA-NEXT: xor a5, a4, a5
3059 ; RV32IA-NEXT: sc.w a5, a5, (a0)
3060 ; RV32IA-NEXT: bnez a5, .LBB66_1
3061 ; RV32IA-NEXT: # %bb.2:
3062 ; RV32IA-NEXT: srl a0, a4, a3
3063 ; RV32IA-NEXT: ret
16383064 %1 = atomicrmw sub i16* %a, i16 %b acquire
16393065 ret i16 %1
16403066 }
16493075 ; RV32I-NEXT: lw ra, 12(sp)
16503076 ; RV32I-NEXT: addi sp, sp, 16
16513077 ; RV32I-NEXT: ret
3078 ;
3079 ; RV32IA-LABEL: atomicrmw_sub_i16_release:
3080 ; RV32IA: # %bb.0:
3081 ; RV32IA-NEXT: lui a2, 16
3082 ; RV32IA-NEXT: addi a2, a2, -1
3083 ; RV32IA-NEXT: and a1, a1, a2
3084 ; RV32IA-NEXT: slli a3, a0, 3
3085 ; RV32IA-NEXT: andi a3, a3, 24
3086 ; RV32IA-NEXT: sll a2, a2, a3
3087 ; RV32IA-NEXT: sll a1, a1, a3
3088 ; RV32IA-NEXT: andi a0, a0, -4
3089 ; RV32IA-NEXT: .LBB67_1: # =>This Inner Loop Header: Depth=1
3090 ; RV32IA-NEXT: lr.w a4, (a0)
3091 ; RV32IA-NEXT: sub a5, a4, a1
3092 ; RV32IA-NEXT: xor a5, a4, a5
3093 ; RV32IA-NEXT: and a5, a5, a2
3094 ; RV32IA-NEXT: xor a5, a4, a5
3095 ; RV32IA-NEXT: sc.w.rl a5, a5, (a0)
3096 ; RV32IA-NEXT: bnez a5, .LBB67_1
3097 ; RV32IA-NEXT: # %bb.2:
3098 ; RV32IA-NEXT: srl a0, a4, a3
3099 ; RV32IA-NEXT: ret
16523100 %1 = atomicrmw sub i16* %a, i16 %b release
16533101 ret i16 %1
16543102 }
16633111 ; RV32I-NEXT: lw ra, 12(sp)
16643112 ; RV32I-NEXT: addi sp, sp, 16
16653113 ; RV32I-NEXT: ret
3114 ;
3115 ; RV32IA-LABEL: atomicrmw_sub_i16_acq_rel:
3116 ; RV32IA: # %bb.0:
3117 ; RV32IA-NEXT: lui a2, 16
3118 ; RV32IA-NEXT: addi a2, a2, -1
3119 ; RV32IA-NEXT: and a1, a1, a2
3120 ; RV32IA-NEXT: slli a3, a0, 3
3121 ; RV32IA-NEXT: andi a3, a3, 24
3122 ; RV32IA-NEXT: sll a2, a2, a3
3123 ; RV32IA-NEXT: sll a1, a1, a3
3124 ; RV32IA-NEXT: andi a0, a0, -4
3125 ; RV32IA-NEXT: .LBB68_1: # =>This Inner Loop Header: Depth=1
3126 ; RV32IA-NEXT: lr.w.aq a4, (a0)
3127 ; RV32IA-NEXT: sub a5, a4, a1
3128 ; RV32IA-NEXT: xor a5, a4, a5
3129 ; RV32IA-NEXT: and a5, a5, a2
3130 ; RV32IA-NEXT: xor a5, a4, a5
3131 ; RV32IA-NEXT: sc.w.rl a5, a5, (a0)
3132 ; RV32IA-NEXT: bnez a5, .LBB68_1
3133 ; RV32IA-NEXT: # %bb.2:
3134 ; RV32IA-NEXT: srl a0, a4, a3
3135 ; RV32IA-NEXT: ret
16663136 %1 = atomicrmw sub i16* %a, i16 %b acq_rel
16673137 ret i16 %1
16683138 }
16773147 ; RV32I-NEXT: lw ra, 12(sp)
16783148 ; RV32I-NEXT: addi sp, sp, 16
16793149 ; RV32I-NEXT: ret
3150 ;
3151 ; RV32IA-LABEL: atomicrmw_sub_i16_seq_cst:
3152 ; RV32IA: # %bb.0:
3153 ; RV32IA-NEXT: lui a2, 16
3154 ; RV32IA-NEXT: addi a2, a2, -1
3155 ; RV32IA-NEXT: and a1, a1, a2
3156 ; RV32IA-NEXT: slli a3, a0, 3
3157 ; RV32IA-NEXT: andi a3, a3, 24
3158 ; RV32IA-NEXT: sll a2, a2, a3
3159 ; RV32IA-NEXT: sll a1, a1, a3
3160 ; RV32IA-NEXT: andi a0, a0, -4
3161 ; RV32IA-NEXT: .LBB69_1: # =>This Inner Loop Header: Depth=1
3162 ; RV32IA-NEXT: lr.w.aqrl a4, (a0)
3163 ; RV32IA-NEXT: sub a5, a4, a1
3164 ; RV32IA-NEXT: xor a5, a4, a5
3165 ; RV32IA-NEXT: and a5, a5, a2
3166 ; RV32IA-NEXT: xor a5, a4, a5
3167 ; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0)
3168 ; RV32IA-NEXT: bnez a5, .LBB69_1
3169 ; RV32IA-NEXT: # %bb.2:
3170 ; RV32IA-NEXT: srl a0, a4, a3
3171 ; RV32IA-NEXT: ret
16803172 %1 = atomicrmw sub i16* %a, i16 %b seq_cst
16813173 ret i16 %1
16823174 }
16913183 ; RV32I-NEXT: lw ra, 12(sp)
16923184 ; RV32I-NEXT: addi sp, sp, 16
16933185 ; RV32I-NEXT: ret
3186 ;
3187 ; RV32IA-LABEL: atomicrmw_and_i16_monotonic:
3188 ; RV32IA: # %bb.0:
3189 ; RV32IA-NEXT: lui a2, 16
3190 ; RV32IA-NEXT: addi a2, a2, -1
3191 ; RV32IA-NEXT: and a1, a1, a2
3192 ; RV32IA-NEXT: slli a3, a0, 3
3193 ; RV32IA-NEXT: andi a3, a3, 24
3194 ; RV32IA-NEXT: sll a1, a1, a3
3195 ; RV32IA-NEXT: sll a2, a2, a3
3196 ; RV32IA-NEXT: not a2, a2
3197 ; RV32IA-NEXT: or a1, a2, a1
3198 ; RV32IA-NEXT: andi a0, a0, -4
3199 ; RV32IA-NEXT: amoand.w a0, a1, (a0)
3200 ; RV32IA-NEXT: srl a0, a0, a3
3201 ; RV32IA-NEXT: ret
16943202 %1 = atomicrmw and i16* %a, i16 %b monotonic
16953203 ret i16 %1
16963204 }
17053213 ; RV32I-NEXT: lw ra, 12(sp)
17063214 ; RV32I-NEXT: addi sp, sp, 16
17073215 ; RV32I-NEXT: ret
3216 ;
3217 ; RV32IA-LABEL: atomicrmw_and_i16_acquire:
3218 ; RV32IA: # %bb.0:
3219 ; RV32IA-NEXT: lui a2, 16
3220 ; RV32IA-NEXT: addi a2, a2, -1
3221 ; RV32IA-NEXT: and a1, a1, a2
3222 ; RV32IA-NEXT: slli a3, a0, 3
3223 ; RV32IA-NEXT: andi a3, a3, 24
3224 ; RV32IA-NEXT: sll a1, a1, a3
3225 ; RV32IA-NEXT: sll a2, a2, a3
3226 ; RV32IA-NEXT: not a2, a2
3227 ; RV32IA-NEXT: or a1, a2, a1
3228 ; RV32IA-NEXT: andi a0, a0, -4
3229 ; RV32IA-NEXT: amoand.w.aq a0, a1, (a0)
3230 ; RV32IA-NEXT: srl a0, a0, a3
3231 ; RV32IA-NEXT: ret
17083232 %1 = atomicrmw and i16* %a, i16 %b acquire
17093233 ret i16 %1
17103234 }
17193243 ; RV32I-NEXT: lw ra, 12(sp)
17203244 ; RV32I-NEXT: addi sp, sp, 16
17213245 ; RV32I-NEXT: ret
3246 ;
3247 ; RV32IA-LABEL: atomicrmw_and_i16_release:
3248 ; RV32IA: # %bb.0:
3249 ; RV32IA-NEXT: lui a2, 16
3250 ; RV32IA-NEXT: addi a2, a2, -1
3251 ; RV32IA-NEXT: and a1, a1, a2
3252 ; RV32IA-NEXT: slli a3, a0, 3
3253 ; RV32IA-NEXT: andi a3, a3, 24
3254 ; RV32IA-NEXT: sll a1, a1, a3
3255 ; RV32IA-NEXT: sll a2, a2, a3
3256 ; RV32IA-NEXT: not a2, a2
3257 ; RV32IA-NEXT: or a1, a2, a1
3258 ; RV32IA-NEXT: andi a0, a0, -4
3259 ; RV32IA-NEXT: amoand.w.rl a0, a1, (a0)
3260 ; RV32IA-NEXT: srl a0, a0, a3
3261 ; RV32IA-NEXT: ret
17223262 %1 = atomicrmw and i16* %a, i16 %b release
17233263 ret i16 %1
17243264 }
17333273 ; RV32I-NEXT: lw ra, 12(sp)
17343274 ; RV32I-NEXT: addi sp, sp, 16
17353275 ; RV32I-NEXT: ret
3276 ;
3277 ; RV32IA-LABEL: atomicrmw_and_i16_acq_rel:
3278 ; RV32IA: # %bb.0:
3279 ; RV32IA-NEXT: lui a2, 16
3280 ; RV32IA-NEXT: addi a2, a2, -1
3281 ; RV32IA-NEXT: and a1, a1, a2
3282 ; RV32IA-NEXT: slli a3, a0, 3
3283 ; RV32IA-NEXT: andi a3, a3, 24
3284 ; RV32IA-NEXT: sll a1, a1, a3
3285 ; RV32IA-NEXT: sll a2, a2, a3
3286 ; RV32IA-NEXT: not a2, a2
3287 ; RV32IA-NEXT: or a1, a2, a1
3288 ; RV32IA-NEXT: andi a0, a0, -4
3289 ; RV32IA-NEXT: amoand.w.aqrl a0, a1, (a0)
3290 ; RV32IA-NEXT: srl a0, a0, a3
3291 ; RV32IA-NEXT: ret
17363292 %1 = atomicrmw and i16* %a, i16 %b acq_rel
17373293 ret i16 %1
17383294 }
17473303 ; RV32I-NEXT: lw ra, 12(sp)
17483304 ; RV32I-NEXT: addi sp, sp, 16
17493305 ; RV32I-NEXT: ret
3306 ;
3307 ; RV32IA-LABEL: atomicrmw_and_i16_seq_cst:
3308 ; RV32IA: # %bb.0:
3309 ; RV32IA-NEXT: lui a2, 16
3310 ; RV32IA-NEXT: addi a2, a2, -1
3311 ; RV32IA-NEXT: and a1, a1, a2
3312 ; RV32IA-NEXT: slli a3, a0, 3
3313 ; RV32IA-NEXT: andi a3, a3, 24
3314 ; RV32IA-NEXT: sll a1, a1, a3
3315 ; RV32IA-NEXT: sll a2, a2, a3
3316 ; RV32IA-NEXT: not a2, a2
3317 ; RV32IA-NEXT: or a1, a2, a1
3318 ; RV32IA-NEXT: andi a0, a0, -4
3319 ; RV32IA-NEXT: amoand.w.aqrl a0, a1, (a0)
3320 ; RV32IA-NEXT: srl a0, a0, a3
3321 ; RV32IA-NEXT: ret
17503322 %1 = atomicrmw and i16* %a, i16 %b seq_cst
17513323 ret i16 %1
17523324 }
17613333 ; RV32I-NEXT: lw ra, 12(sp)
17623334 ; RV32I-NEXT: addi sp, sp, 16
17633335 ; RV32I-NEXT: ret
3336 ;
3337 ; RV32IA-LABEL: atomicrmw_nand_i16_monotonic:
3338 ; RV32IA: # %bb.0:
3339 ; RV32IA-NEXT: lui a2, 16
3340 ; RV32IA-NEXT: addi a2, a2, -1
3341 ; RV32IA-NEXT: and a1, a1, a2
3342 ; RV32IA-NEXT: slli a3, a0, 3
3343 ; RV32IA-NEXT: andi a3, a3, 24
3344 ; RV32IA-NEXT: sll a2, a2, a3
3345 ; RV32IA-NEXT: sll a1, a1, a3
3346 ; RV32IA-NEXT: andi a0, a0, -4
3347 ; RV32IA-NEXT: .LBB75_1: # =>This Inner Loop Header: Depth=1
3348 ; RV32IA-NEXT: lr.w a4, (a0)
3349 ; RV32IA-NEXT: and a5, a4, a1
3350 ; RV32IA-NEXT: not a5, a5
3351 ; RV32IA-NEXT: xor a5, a4, a5
3352 ; RV32IA-NEXT: and a5, a5, a2
3353 ; RV32IA-NEXT: xor a5, a4, a5
3354 ; RV32IA-NEXT: sc.w a5, a5, (a0)
3355 ; RV32IA-NEXT: bnez a5, .LBB75_1
3356 ; RV32IA-NEXT: # %bb.2:
3357 ; RV32IA-NEXT: srl a0, a4, a3
3358 ; RV32IA-NEXT: ret
17643359 %1 = atomicrmw nand i16* %a, i16 %b monotonic
17653360 ret i16 %1
17663361 }
17753370 ; RV32I-NEXT: lw ra, 12(sp)
17763371 ; RV32I-NEXT: addi sp, sp, 16
17773372 ; RV32I-NEXT: ret
3373 ;
3374 ; RV32IA-LABEL: atomicrmw_nand_i16_acquire:
3375 ; RV32IA: # %bb.0:
3376 ; RV32IA-NEXT: lui a2, 16
3377 ; RV32IA-NEXT: addi a2, a2, -1
3378 ; RV32IA-NEXT: and a1, a1, a2
3379 ; RV32IA-NEXT: slli a3, a0, 3
3380 ; RV32IA-NEXT: andi a3, a3, 24
3381 ; RV32IA-NEXT: sll a2, a2, a3
3382 ; RV32IA-NEXT: sll a1, a1, a3
3383 ; RV32IA-NEXT: andi a0, a0, -4
3384 ; RV32IA-NEXT: .LBB76_1: # =>This Inner Loop Header: Depth=1
3385 ; RV32IA-NEXT: lr.w.aq a4, (a0)
3386 ; RV32IA-NEXT: and a5, a4, a1
3387 ; RV32IA-NEXT: not a5, a5
3388 ; RV32IA-NEXT: xor a5, a4, a5
3389 ; RV32IA-NEXT: and a5, a5, a2
3390 ; RV32IA-NEXT: xor a5, a4, a5
3391 ; RV32IA-NEXT: sc.w a5, a5, (a0)
3392 ; RV32IA-NEXT: bnez a5, .LBB76_1
3393 ; RV32IA-NEXT: # %bb.2:
3394 ; RV32IA-NEXT: srl a0, a4, a3
3395 ; RV32IA-NEXT: ret
17783396 %1 = atomicrmw nand i16* %a, i16 %b acquire
17793397 ret i16 %1
17803398 }
17893407 ; RV32I-NEXT: lw ra, 12(sp)
17903408 ; RV32I-NEXT: addi sp, sp, 16
17913409 ; RV32I-NEXT: ret
3410 ;
3411 ; RV32IA-LABEL: atomicrmw_nand_i16_release:
3412 ; RV32IA: # %bb.0:
3413 ; RV32IA-NEXT: lui a2, 16
3414 ; RV32IA-NEXT: addi a2, a2, -1
3415 ; RV32IA-NEXT: and a1, a1, a2
3416 ; RV32IA-NEXT: slli a3, a0, 3
3417 ; RV32IA-NEXT: andi a3, a3, 24
3418 ; RV32IA-NEXT: sll a2, a2, a3
3419 ; RV32IA-NEXT: sll a1, a1, a3
3420 ; RV32IA-NEXT: andi a0, a0, -4
3421 ; RV32IA-NEXT: .LBB77_1: # =>This Inner Loop Header: Depth=1
3422 ; RV32IA-NEXT: lr.w a4, (a0)
3423 ; RV32IA-NEXT: and a5, a4, a1
3424 ; RV32IA-NEXT: not a5, a5
3425 ; RV32IA-NEXT: xor a5, a4, a5
3426 ; RV32IA-NEXT: and a5, a5, a2
3427 ; RV32IA-NEXT: xor a5, a4, a5
3428 ; RV32IA-NEXT: sc.w.rl a5, a5, (a0)
3429 ; RV32IA-NEXT: bnez a5, .LBB77_1
3430 ; RV32IA-NEXT: # %bb.2:
3431 ; RV32IA-NEXT: srl a0, a4, a3
3432 ; RV32IA-NEXT: ret
17923433 %1 = atomicrmw nand i16* %a, i16 %b release
17933434 ret i16 %1
17943435 }
18033444 ; RV32I-NEXT: lw ra, 12(sp)
18043445 ; RV32I-NEXT: addi sp, sp, 16
18053446 ; RV32I-NEXT: ret
3447 ;
3448 ; RV32IA-LABEL: atomicrmw_nand_i16_acq_rel:
3449 ; RV32IA: # %bb.0:
3450 ; RV32IA-NEXT: lui a2, 16
3451 ; RV32IA-NEXT: addi a2, a2, -1
3452 ; RV32IA-NEXT: and a1, a1, a2
3453 ; RV32IA-NEXT: slli a3, a0, 3
3454 ; RV32IA-NEXT: andi a3, a3, 24
3455 ; RV32IA-NEXT: sll a2, a2, a3
3456 ; RV32IA-NEXT: sll a1, a1, a3
3457 ; RV32IA-NEXT: andi a0, a0, -4
3458 ; RV32IA-NEXT: .LBB78_1: # =>This Inner Loop Header: Depth=1
3459 ; RV32IA-NEXT: lr.w.aq a4, (a0)
3460 ; RV32IA-NEXT: and a5, a4, a1
3461 ; RV32IA-NEXT: not a5, a5
3462 ; RV32IA-NEXT: xor a5, a4, a5
3463 ; RV32IA-NEXT: and a5, a5, a2
3464 ; RV32IA-NEXT: xor a5, a4, a5
3465 ; RV32IA-NEXT: sc.w.rl a5, a5, (a0)
3466 ; RV32IA-NEXT: bnez a5, .LBB78_1
3467 ; RV32IA-NEXT: # %bb.2:
3468 ; RV32IA-NEXT: srl a0, a4, a3
3469 ; RV32IA-NEXT: ret
18063470 %1 = atomicrmw nand i16* %a, i16 %b acq_rel
18073471 ret i16 %1
18083472 }
18173481 ; RV32I-NEXT: lw ra, 12(sp)
18183482 ; RV32I-NEXT: addi sp, sp, 16
18193483 ; RV32I-NEXT: ret
3484 ;
3485 ; RV32IA-LABEL: atomicrmw_nand_i16_seq_cst:
3486 ; RV32IA: # %bb.0:
3487 ; RV32IA-NEXT: lui a2, 16
3488 ; RV32IA-NEXT: addi a2, a2, -1
3489 ; RV32IA-NEXT: and a1, a1, a2
3490 ; RV32IA-NEXT: slli a3, a0, 3
3491 ; RV32IA-NEXT: andi a3, a3, 24
3492 ; RV32IA-NEXT: sll a2, a2, a3
3493 ; RV32IA-NEXT: sll a1, a1, a3
3494 ; RV32IA-NEXT: andi a0, a0, -4
3495 ; RV32IA-NEXT: .LBB79_1: # =>This Inner Loop Header: Depth=1
3496 ; RV32IA-NEXT: lr.w.aqrl a4, (a0)
3497 ; RV32IA-NEXT: and a5, a4, a1
3498 ; RV32IA-NEXT: not a5, a5
3499 ; RV32IA-NEXT: xor a5, a4, a5
3500 ; RV32IA-NEXT: and a5, a5, a2
3501 ; RV32IA-NEXT: xor a5, a4, a5
3502 ; RV32IA-NEXT: sc.w.aqrl a5, a5, (a0)
3503 ; RV32IA-NEXT: bnez a5, .LBB79_1
3504 ; RV32IA-NEXT: # %bb.2:
3505 ; RV32IA-NEXT: srl a0, a4, a3
3506 ; RV32IA-NEXT: ret
18203507 %1 = atomicrmw nand i16* %a, i16 %b seq_cst
18213508 ret i16 %1
18223509 }
18313518 ; RV32I-NEXT: lw ra, 12(sp)
18323519 ; RV32I-NEXT: addi sp, sp, 16
18333520 ; RV32I-NEXT: ret
3521 ;
3522 ; RV32IA-LABEL: atomicrmw_or_i16_monotonic:
3523 ; RV32IA: # %bb.0:
3524 ; RV32IA-NEXT: lui a2, 16
3525 ; RV32IA-NEXT: addi a2, a2, -1
3526 ; RV32IA-NEXT: and a1, a1, a2
3527 ; RV32IA-NEXT: slli a2, a0, 3
3528 ; RV32IA-NEXT: andi a2, a2, 24
3529 ; RV32IA-NEXT: sll a1, a1, a2
3530 ; RV32IA-NEXT: andi a0, a0, -4
3531 ; RV32IA-NEXT: amoor.w a0, a1, (a0)
3532 ; RV32IA-NEXT: srl a0, a0, a2
3533 ; RV32IA-NEXT: ret
18343534 %1 = atomicrmw or i16* %a, i16 %b monotonic
18353535 ret i16 %1
18363536 }
18453545 ; RV32I-NEXT: lw ra, 12(sp)
18463546 ; RV32I-NEXT: addi sp, sp, 16
18473547 ; RV32I-NEXT: ret
3548 ;
3549 ; RV32IA-LABEL: atomicrmw_or_i16_acquire:
3550 ; RV32IA: # %bb.0:
3551 ; RV32IA-NEXT: lui a2, 16
3552 ; RV32IA-NEXT: addi a2, a2, -1
3553 ; RV32IA-NEXT: and a1, a1, a2
3554 ; RV32IA-NEXT: slli a2, a0, 3
3555 ; RV32IA-NEXT: andi a2, a2, 24
3556 ; RV32IA-NEXT: sll a1, a1, a2
3557 ; RV32IA-NEXT: andi a0, a0, -4
3558 ; RV32IA-NEXT: amoor.w.aq a0, a1, (a0)
3559 ; RV32IA-NEXT: srl a0, a0, a2
3560 ; RV32IA-NEXT: ret
18483561 %1 = atomicrmw or i16* %a, i16 %b acquire
18493562 ret i16 %1
18503563 }
18593572 ; RV32I-NEXT: lw ra, 12(sp)
18603573 ; RV32I-NEXT: addi sp, sp, 16
18613574 ; RV32I-NEXT: ret
3575 ;
3576 ; RV32IA-LABEL: atomicrmw_or_i16_release:
3577 ; RV32IA: # %bb.0:
3578 ; RV32IA-NEXT: lui a2, 16
3579 ; RV32IA-NEXT: addi a2, a2, -1
3580 ; RV32IA-NEXT: and a1, a1, a2
3581 ; RV32IA-NEXT: slli a2, a0, 3
3582 ; RV32IA-NEXT: andi a2, a2, 24
3583 ; RV32IA-NEXT: sll a1, a1, a2
3584 ; RV32IA-NEXT: andi a0, a0, -4
3585 ; RV32IA-NEXT: amoor.w.rl a0, a1, (a0)
3586 ; RV32IA-NEXT: srl a0, a0, a2
3587 ; RV32IA-NEXT: ret
18623588 %1 = atomicrmw or i16* %a, i16 %b release
18633589 ret i16 %1
18643590 }
18733599 ; RV32I-NEXT: lw ra, 12(sp)
18743600 ; RV32I-NEXT: addi sp, sp, 16
18753601 ; RV32I-NEXT: ret
3602 ;
3603 ; RV32IA-LABEL: atomicrmw_or_i16_acq_rel:
3604 ; RV32IA: # %bb.0:
3605 ; RV32IA-NEXT: lui a2, 16
3606 ; RV32IA-NEXT: addi a2, a2, -1
3607 ; RV32IA-NEXT: and a1, a1, a2
3608 ; RV32IA-NEXT: slli a2, a0, 3
3609 ; RV32IA-NEXT: andi a2, a2, 24
3610 ; RV32IA-NEXT: sll a1, a1, a2
3611 ; RV32IA-NEXT: andi a0, a0, -4
3612 ; RV32IA-NEXT: amoor.w.aqrl a0, a1, (a0)
3613 ; RV32IA-NEXT: srl a0, a0, a2
3614 ; RV32IA-NEXT: ret
18763615 %1 = atomicrmw or i16* %a, i16 %b acq_rel
18773616 ret i16 %1
18783617 }
18873626 ; RV32I-NEXT: lw ra, 12(sp)
18883627 ; RV32I-NEXT: addi sp, sp, 16
18893628 ; RV32I-NEXT: ret
3629 ;
3630 ; RV32IA-LABEL: atomicrmw_or_i16_seq_cst:
3631 ; RV32IA: # %bb.0:
3632 ; RV32IA-NEXT: lui a2, 16
3633 ; RV32IA-NEXT: addi a2, a2, -1
3634 ; RV32IA-NEXT: and a1, a1, a2
3635 ; RV32IA-NEXT: slli a2, a0, 3
3636 ; RV32IA-NEXT: andi a2, a2, 24
3637 ; RV32IA-NEXT: sll a1, a1, a2
3638 ; RV32IA-NEXT: andi a0, a0, -4
3639 ; RV32IA-NEXT: amoor.w.aqrl a0, a1, (a0)
3640 ; RV32IA-NEXT: srl a0, a0, a2
3641 ; RV32IA-NEXT: ret
18903642 %1 = atomicrmw or i16* %a, i16 %b seq_cst
18913643 ret i16 %1
18923644 }
19013653 ; RV32I-NEXT: lw ra, 12(sp)
19023654 ; RV32I-NEXT: addi sp, sp, 16
19033655 ; RV32I-NEXT: ret
3656 ;
3657 ; RV32IA-LABEL: atomicrmw_xor_i16_monotonic:
3658 ; RV32IA: # %bb.0:
3659 ; RV32IA-NEXT: lui a2, 16
3660 ; RV32IA-NEXT: addi a2, a2, -1
3661 ; RV32IA-NEXT: and a1, a1, a2
3662 ; RV32IA-NEXT: slli a2, a0, 3
3663 ; RV32IA-NEXT: andi a2, a2, 24
3664 ; RV32IA-NEXT: sll a1, a1, a2
3665 ; RV32IA-NEXT: andi a0, a0, -4
3666 ; RV32IA-NEXT: amoxor.w a0, a1, (a0)
3667 ; RV32IA-NEXT: srl a0, a0, a2
3668 ; RV32IA-NEXT: ret
19043669 %1 = atomicrmw xor i16* %a, i16 %b monotonic
19053670 ret i16 %1
19063671 }
19153680 ; RV32I-NEXT: lw ra, 12(sp)
19163681 ; RV32I-NEXT: addi sp, sp, 16
19173682 ; RV32I-NEXT: ret
3683 ;
3684 ; RV32IA-LABEL: atomicrmw_xor_i16_acquire:
3685 ; RV32IA: # %bb.0:
3686 ; RV32IA-NEXT: lui a2, 16
3687 ; RV32IA-NEXT: addi a2, a2, -1
3688 ; RV32IA-NEXT: and a1, a1, a2
3689 ; RV32IA-NEXT: slli a2, a0, 3
3690 ; RV32IA-NEXT: andi a2, a2, 24
3691 ; RV32IA-NEXT: sll a1, a1, a2
3692 ; RV32IA-NEXT: andi a0, a0, -4
3693 ; RV32IA-NEXT: amoxor.w.aq a0, a1, (a0)
3694 ; RV32IA-NEXT: srl a0, a0, a2
3695 ; RV32IA-NEXT: ret
19183696 %1 = atomicrmw xor i16* %a, i16 %b acquire
19193697 ret i16 %1
19203698 }
19293707 ; RV32I-NEXT: lw ra, 12(sp)
19303708 ; RV32I-NEXT: addi sp, sp, 16
19313709 ; RV32I-NEXT: ret
3710 ;
3711 ; RV32IA-LABEL: atomicrmw_xor_i16_release:
3712 ; RV32IA: # %bb.0:
3713 ; RV32IA-NEXT: lui a2, 16
3714 ; RV32IA-NEXT: addi a2, a2, -1
3715 ; RV32IA-NEXT: and a1, a1, a2
3716 ; RV32IA-NEXT: slli a2, a0, 3
3717 ; RV32IA-NEXT: andi a2, a2, 24
3718 ; RV32IA-NEXT: sll a1, a1, a2
3719 ; RV32IA-NEXT: andi a0, a0, -4
3720 ; RV32IA-NEXT: amoxor.w.rl a0, a1, (a0)
3721 ; RV32IA-NEXT: srl a0, a0, a2
3722 ; RV32IA-NEXT: ret
19323723 %1 = atomicrmw xor i16* %a, i16 %b release
19333724 ret i16 %1
19343725 }
19433734 ; RV32I-NEXT: lw ra, 12(sp)
19443735 ; RV32I-NEXT: addi sp, sp, 16
19453736 ; RV32I-NEXT: ret
3737 ;
3738 ; RV32IA-LABEL: atomicrmw_xor_i16_acq_rel:
3739 ; RV32IA: # %bb.0:
3740 ; RV32IA-NEXT: lui a2, 16
3741 ; RV32IA-NEXT: addi a2, a2, -1
3742 ; RV32IA-NEXT: and a1, a1, a2
3743 ; RV32IA-NEXT: slli a2, a0, 3
3744 ; RV32IA-NEXT: andi a2, a2, 24
3745 ; RV32IA-NEXT: sll a1, a1, a2
3746 ; RV32IA-NEXT: andi a0, a0, -4
3747 ; RV32IA-NEXT: amoxor.w.aqrl a0, a1, (a0)
3748 ; RV32IA-NEXT: srl a0, a0, a2
3749 ; RV32IA-NEXT: ret
19463750 %1 = atomicrmw xor i16* %a, i16 %b acq_rel
19473751 ret i16 %1
19483752 }
19573761 ; RV32I-NEXT: lw ra, 12(sp)
19583762 ; RV32I-NEXT: addi sp, sp, 16
19593763 ; RV32I-NEXT: ret
3764 ;
3765 ; RV32IA-LABEL: atomicrmw_xor_i16_seq_cst:
3766 ; RV32IA: # %bb.0:
3767 ; RV32IA-NEXT: lui a2, 16
3768 ; RV32IA-NEXT: addi a2, a2, -1
3769 ; RV32IA-NEXT: and a1, a1, a2
3770 ; RV32IA-NEXT: slli a2, a0, 3
3771 ; RV32IA-NEXT: andi a2, a2, 24
3772 ; RV32IA-NEXT: sll a1, a1, a2
3773 ; RV32IA-NEXT: andi a0, a0, -4
3774 ; RV32IA-NEXT: amoxor.w.aqrl a0, a1, (a0)
3775 ; RV32IA-NEXT: srl a0, a0, a2
3776 ; RV32IA-NEXT: ret
19603777 %1 = atomicrmw xor i16* %a, i16 %b seq_cst
19613778 ret i16 %1
19623779 }
20043821 ; RV32I-NEXT: lw ra, 28(sp)
20053822 ; RV32I-NEXT: addi sp, sp, 32
20063823 ; RV32I-NEXT: ret
3824 ;
3825 ; RV32IA-LABEL: atomicrmw_max_i16_monotonic:
3826 ; RV32IA: # %bb.0:
3827 ; RV32IA-NEXT: slli a2, a0, 3
3828 ; RV32IA-NEXT: andi a2, a2, 24
3829 ; RV32IA-NEXT: addi a3, zero, 16
3830 ; RV32IA-NEXT: sub a6, a3, a2
3831 ; RV32IA-NEXT: lui a4, 16
3832 ; RV32IA-NEXT: addi a4, a4, -1
3833 ; RV32IA-NEXT: sll a7, a4, a2
3834 ; RV32IA-NEXT: slli a1, a1, 16
3835 ; RV32IA-NEXT: srai a1, a1, 16
3836 ; RV32IA-NEXT: sll a1, a1, a2
3837 ; RV32IA-NEXT: andi a0, a0, -4
3838 ; RV32IA-NEXT: .LBB90_1: # =>This Inner Loop Header: Depth=1
3839 ; RV32IA-NEXT: lr.w a5, (a0)
3840 ; RV32IA-NEXT: and a4, a5, a7
3841 ; RV32IA-NEXT: mv a3, a5
3842 ; RV32IA-NEXT: sll a4, a4, a6
3843 ; RV32IA-NEXT: sra a4, a4, a6
3844 ; RV32IA-NEXT: bge a4, a1, .LBB90_3
3845 ; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB90_1 Depth=1
3846 ; RV32IA-NEXT: xor a3, a5, a1
3847 ; RV32IA-NEXT: and a3, a3, a7
3848 ; RV32IA-NEXT: xor a3, a5, a3
3849 ; RV32IA-NEXT: .LBB90_3: # in Loop: Header=BB90_1 Depth=1
3850 ; RV32IA-NEXT: sc.w a3, a3, (a0)
3851 ; RV32IA-NEXT: bnez a3, .LBB90_1
3852 ; RV32IA-NEXT: # %bb.4:
3853 ; RV32IA-NEXT: srl a0, a5, a2
3854 ; RV32IA-NEXT: ret
20073855 %1 = atomicrmw max i16* %a, i16 %b monotonic
20083856 ret i16 %1
20093857 }
20543902 ; RV32I-NEXT: lw ra, 28(sp)
20553903 ; RV32I-NEXT: addi sp, sp, 32
20563904 ; RV32I-NEXT: ret
3905 ;
3906 ; RV32IA-LABEL: atomicrmw_max_i16_acquire:
3907 ; RV32IA: # %bb.0:
3908 ; RV32IA-NEXT: slli a2, a0, 3
3909 ; RV32IA-NEXT: andi a2, a2, 24
3910 ; RV32IA-NEXT: addi a3, zero, 16
3911 ; RV32IA-NEXT: sub a6, a3, a2
3912 ; RV32IA-NEXT: lui a4, 16
3913 ; RV32IA-NEXT: addi a4, a4, -1
3914 ; RV32IA-NEXT: sll a7, a4, a2
3915 ; RV32IA-NEXT: slli a1, a1, 16
3916 ; RV32IA-NEXT: srai a1, a1, 16
3917 ; RV32IA-NEXT: sll a1, a1, a2
3918 ; RV32IA-NEXT: andi a0, a0, -4
3919 ; RV32IA-NEXT: .LBB91_1: # =>This Inner Loop Header: Depth=1
3920 ; RV32IA-NEXT: lr.w.aq a5, (a0)
3921 ; RV32IA-NEXT: and a4, a5, a7
3922 ; RV32IA-NEXT: mv a3, a5
3923 ; RV32IA-NEXT: sll a4, a4, a6
3924 ; RV32IA-NEXT: sra a4, a4, a6
3925 ; RV32IA-NEXT: bge a4, a1, .LBB91_3
3926 ; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB91_1 Depth=1
3927 ; RV32IA-NEXT: xor a3, a5, a1
3928 ; RV32IA-NEXT: and a3, a3, a7
3929 ; RV32IA-NEXT: xor a3, a5, a3
3930 ; RV32IA-NEXT: .LBB91_3: # in Loop: Header=BB91_1 Depth=1
3931 ; RV32IA-NEXT: sc.w a3, a3, (a0)
3932 ; RV32IA-NEXT: bnez a3, .LBB91_1
3933 ; RV32IA-NEXT: # %bb.4:
3934 ; RV32IA-NEXT: srl a0, a5, a2
3935 ; RV32IA-NEXT: ret
20573936 %1 = atomicrmw max i16* %a, i16 %b acquire
20583937 ret i16 %1
20593938 }
21043983 ; RV32I-NEXT: lw ra, 28(sp)
21053984 ; RV32I-NEXT: addi sp, sp, 32
21063985 ; RV32I-NEXT: ret
3986 ;
3987 ; RV32IA-LABEL: atomicrmw_max_i16_release:
3988 ; RV32IA: # %bb.0:
3989 ; RV32IA-NEXT: slli a2, a0, 3
3990 ; RV32IA-NEXT: andi a2, a2, 24
3991 ; RV32IA-NEXT: addi a3, zero, 16
3992 ; RV32IA-NEXT: sub a6, a3, a2
3993 ; RV32IA-NEXT: lui a4, 16
3994 ; RV32IA-NEXT: addi a4, a4, -1
3995 ; RV32IA-NEXT: sll a7, a4, a2
3996 ; RV32IA-NEXT: slli a1, a1, 16
3997 ; RV32IA-NEXT: srai a1, a1, 16
3998 ; RV32IA-NEXT: sll a1, a1, a2
3999 ; RV32IA-NEXT: andi a0, a0, -4
4000 ; RV32IA-NEXT: .LBB92_1: # =>This Inner Loop Header: Depth=1
4001 ; RV32IA-NEXT: lr.w a5, (a0)
4002 ; RV32IA-NEXT: and a4, a5, a7
4003 ; RV32IA-NEXT: mv a3, a5
4004 ; RV32IA-NEXT: sll a4, a4, a6
4005 ; RV32IA-NEXT: sra a4, a4, a6
4006 ; RV32IA-NEXT: bge a4, a1, .LBB92_3
4007 ; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB92_1 Depth=1
4008 ; RV32IA-NEXT: xor a3, a5, a1
4009 ; RV32IA-NEXT: and a3, a3, a7
4010 ; RV32IA-NEXT: xor a3, a5, a3
4011 ; RV32IA-NEXT: .LBB92_3: # in Loop: Header=BB92_1 Depth=1
4012 ; RV32IA-NEXT: sc.w.rl a3, a3, (a0)
4013 ; RV32IA-NEXT: bnez a3, .LBB92_1
4014 ; RV32IA-NEXT: # %bb.4:
4015 ; RV32IA-NEXT: srl a0, a5, a2
4016 ; RV32IA-NEXT: ret
21074017 %1 = atomicrmw max i16* %a, i16 %b release
21084018 ret i16 %1
21094019 }
21574067 ; RV32I-NEXT: lw ra, 28(sp)
21584068 ; RV32I-NEXT: addi sp, sp, 32
21594069 ; RV32I-NEXT: ret
4070 ;