[llvm] [Mips] Use AtomicExpandPass for subword atomics (PR #225948)
Jiaxun Yang via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 25 01:37:17 PDT 2026
https://github.com/FlyGoat updated https://github.com/llvm/llvm-project/pull/225948
>From 7f587191dd8dcb7a259aca2f8ba5dd6eaed8b9a7 Mon Sep 17 00:00:00 2001
From: Jiaxun Yang <jiaxun.yang at flygoat.com>
Date: Wed, 23 Sep 2026 21:08:14 +0100
Subject: [PATCH 1/2] [Mips] Use AtomicExpandPass for subword atomics
MIPS duplicates subword atomic address and mask preparation already
provided by AtomicExpandPass. We referenced the RISC-V implementation
to move this work into the generic pass and simplify LL/SC expansion.
Lower byte and halfword atomic RMW and cmpxchg operations through masked
intrinsics so AtomicExpandPass prepares aligned addresses, endian-aware
shifts, masks and shifted operands. Reuse generic widening for bitwise
RMWs and cmpxchg expansion for operations without a native LL/SC lowering.
Select masked and fullword atomic pseudos with explicit early-clobber
scratch outputs. Share their late LL/SC expansion and remove the atomic
custom inserters and duplicate post-RA pseudos. Run expansion and the MIPS
finalization passes in addPreEmitPass2 to keep intervening machine passes
from inserting stores into LL/SC loops.
Preserve MIPS16 and R5900 libcall lowering, Add regression coverage for
masks, fences, endian and ABI variants, retry loops, and pass ordering.
Assisted-by: OpenAI Codex # Cherry-pick from our fork, add testcase
---
llvm/include/llvm/IR/IntrinsicsMips.td | 28 +
llvm/lib/Target/Mips/Mips16ISelLowering.cpp | 1 +
llvm/lib/Target/Mips/Mips64InstrInfo.td | 55 +-
llvm/lib/Target/Mips/MipsExpandPseudo.cpp | 1393 +---
llvm/lib/Target/Mips/MipsISelLowering.cpp | 785 +-
llvm/lib/Target/Mips/MipsISelLowering.h | 35 +-
llvm/lib/Target/Mips/MipsInstrInfo.td | 212 +-
llvm/lib/Target/Mips/MipsScheduleGeneric.td | 8 +-
llvm/lib/Target/Mips/MipsScheduleI6400.td | 8 +-
llvm/lib/Target/Mips/MipsScheduleP5600.td | 8 +-
llvm/lib/Target/Mips/MipsTargetMachine.cpp | 9 +-
.../CodeGen/Mips/atomic-expand-pipeline.ll | 16 +
llvm/test/CodeGen/Mips/atomic-masked-n32.ll | 362 +
llvm/test/CodeGen/Mips/atomic-min-max-64.ll | 263 +-
llvm/test/CodeGen/Mips/atomic-min-max.ll | 6320 +++++++----------
llvm/test/CodeGen/Mips/atomic.ll | 4950 ++++++-------
llvm/test/CodeGen/Mips/atomic64.ll | 18 +-
llvm/test/CodeGen/Mips/atomicops.ll | 34 +-
llvm/test/CodeGen/Mips/atomicrmw-cmpxchg.ll | 308 +
llvm/test/CodeGen/Mips/atomicrmw-cmpxchg64.ll | 111 +
.../AtomicExpand/Mips/atomicrmw-integer.ll | 475 ++
.../AtomicExpand/Mips/masked-atomics.ll | 1264 ++++
.../Mips/masked-cmpxchg-fences.ll | 42 +
23 files changed, 8460 insertions(+), 8245 deletions(-)
create mode 100644 llvm/test/CodeGen/Mips/atomic-expand-pipeline.ll
create mode 100644 llvm/test/CodeGen/Mips/atomic-masked-n32.ll
create mode 100644 llvm/test/CodeGen/Mips/atomicrmw-cmpxchg.ll
create mode 100644 llvm/test/CodeGen/Mips/atomicrmw-cmpxchg64.ll
create mode 100644 llvm/test/Transforms/AtomicExpand/Mips/atomicrmw-integer.ll
create mode 100644 llvm/test/Transforms/AtomicExpand/Mips/masked-atomics.ll
create mode 100644 llvm/test/Transforms/AtomicExpand/Mips/masked-cmpxchg-fences.ll
diff --git a/llvm/include/llvm/IR/IntrinsicsMips.td b/llvm/include/llvm/IR/IntrinsicsMips.td
index 8d12786d52e126..5f08c17b574634 100644
--- a/llvm/include/llvm/IR/IntrinsicsMips.td
+++ b/llvm/include/llvm/IR/IntrinsicsMips.td
@@ -18,6 +18,34 @@ def mips_q31_ty: LLVMType<i32>;
let TargetPrefix = "mips" in { // All intrinsics start with "llvm.mips.".
+// Operands: 4-byte-aligned address, shifted value, mask.
+// Returns the old i32 word.
+class MipsMaskedAtomicRMW :
+ Intrinsic<[llvm_i32_ty], [llvm_anyptr_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
+
+// The final operand is the shift used to sign-extend the positioned subword.
+class MipsMaskedAtomicMinMax :
+ Intrinsic<[llvm_i32_ty],
+ [llvm_anyptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
+
+def int_mips_masked_atomicrmw_xchg : MipsMaskedAtomicRMW;
+def int_mips_masked_atomicrmw_add : MipsMaskedAtomicRMW;
+def int_mips_masked_atomicrmw_sub : MipsMaskedAtomicRMW;
+def int_mips_masked_atomicrmw_nand : MipsMaskedAtomicRMW;
+def int_mips_masked_atomicrmw_umin : MipsMaskedAtomicRMW;
+def int_mips_masked_atomicrmw_umax : MipsMaskedAtomicRMW;
+def int_mips_masked_atomicrmw_min : MipsMaskedAtomicMinMax;
+def int_mips_masked_atomicrmw_max : MipsMaskedAtomicMinMax;
+
+// Operands: 4-byte-aligned address, shifted compare and new values, mask.
+// Returns the old i32 word. Compare and new values must be zero outside the mask.
+def int_mips_masked_cmpxchg :
+ Intrinsic<[llvm_i32_ty],
+ [llvm_anyptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
+
//===----------------------------------------------------------------------===//
// MIPS DSP Rev 1
diff --git a/llvm/lib/Target/Mips/Mips16ISelLowering.cpp b/llvm/lib/Target/Mips/Mips16ISelLowering.cpp
index ac32426288e082..5dcb010fec2acd 100644
--- a/llvm/lib/Target/Mips/Mips16ISelLowering.cpp
+++ b/llvm/lib/Target/Mips/Mips16ISelLowering.cpp
@@ -78,6 +78,7 @@ Mips16TargetLowering::Mips16TargetLowering(const MipsTargetMachine &TM,
addRegisterClass(MVT::i32, &Mips::CPU16RegsRegClass);
setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, LibCall);
+ setOperationAction(ISD::ATOMIC_LOAD, MVT::i32, Expand);
setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i32, LibCall);
setOperationAction(ISD::ATOMIC_SWAP, MVT::i32, LibCall);
setOperationAction(ISD::ATOMIC_LOAD_ADD, MVT::i32, LibCall);
diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td
index b6d820bbc10256..342c03e475de8e 100644
--- a/llvm/lib/Target/Mips/Mips64InstrInfo.td
+++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td
@@ -74,37 +74,34 @@ def assertzext_lt_i32 : PatFrag<(ops node:$src), (assertzext node:$src), [{
//===----------------------------------------------------------------------===//
// Instructions specific format
//===----------------------------------------------------------------------===//
-let usesCustomInserter = 1 in {
- def ATOMIC_LOAD_ADD_I64 : Atomic2Ops<atomic_load_add_i64, GPR64>;
- def ATOMIC_LOAD_SUB_I64 : Atomic2Ops<atomic_load_sub_i64, GPR64>;
- def ATOMIC_LOAD_AND_I64 : Atomic2Ops<atomic_load_and_i64, GPR64>;
- def ATOMIC_LOAD_OR_I64 : Atomic2Ops<atomic_load_or_i64, GPR64>;
- def ATOMIC_LOAD_XOR_I64 : Atomic2Ops<atomic_load_xor_i64, GPR64>;
- def ATOMIC_LOAD_NAND_I64 : Atomic2Ops<atomic_load_nand_i64, GPR64>;
- def ATOMIC_SWAP_I64 : Atomic2Ops<atomic_swap_i64, GPR64>;
- def ATOMIC_CMP_SWAP_I64 : AtomicCmpSwap<atomic_cmp_swap_i64, GPR64>;
- def ATOMIC_LOAD_MIN_I64 : Atomic2Ops<atomic_load_min_i64, GPR64>;
- def ATOMIC_LOAD_MAX_I64 : Atomic2Ops<atomic_load_max_i64, GPR64>;
- def ATOMIC_LOAD_UMIN_I64 : Atomic2Ops<atomic_load_umin_i64, GPR64>;
- def ATOMIC_LOAD_UMAX_I64 : Atomic2Ops<atomic_load_umax_i64, GPR64>;
+def ATOMIC_LOAD_ADD_I64 : PseudoAtomicRMW<GPR64>;
+def ATOMIC_LOAD_SUB_I64 : PseudoAtomicRMW<GPR64>;
+def ATOMIC_LOAD_AND_I64 : PseudoAtomicRMW<GPR64>;
+def ATOMIC_LOAD_OR_I64 : PseudoAtomicRMW<GPR64>;
+def ATOMIC_LOAD_XOR_I64 : PseudoAtomicRMW<GPR64>;
+def ATOMIC_LOAD_NAND_I64 : PseudoAtomicRMW<GPR64>;
+def ATOMIC_LOAD_MIN_I64 : PseudoAtomicRMW<GPR64, 1>;
+def ATOMIC_LOAD_MAX_I64 : PseudoAtomicRMW<GPR64, 1>;
+def ATOMIC_LOAD_UMIN_I64 : PseudoAtomicRMW<GPR64, 1>;
+def ATOMIC_LOAD_UMAX_I64 : PseudoAtomicRMW<GPR64, 1>;
+def ATOMIC_SWAP_I64 : PseudoAtomicRMW<GPR64>;
+def ATOMIC_CMP_SWAP_I64 : PseudoAtomicCmpSwap<GPR64>;
+
+let Predicates = [NotInMips16Mode, NotR5900] in {
+def : PseudoAtomicRMWPat<atomic_load_add_i64, ATOMIC_LOAD_ADD_I64, GPR64>;
+def : PseudoAtomicRMWPat<atomic_load_sub_i64, ATOMIC_LOAD_SUB_I64, GPR64>;
+def : PseudoAtomicRMWPat<atomic_load_and_i64, ATOMIC_LOAD_AND_I64, GPR64>;
+def : PseudoAtomicRMWPat<atomic_load_or_i64, ATOMIC_LOAD_OR_I64, GPR64>;
+def : PseudoAtomicRMWPat<atomic_load_xor_i64, ATOMIC_LOAD_XOR_I64, GPR64>;
+def : PseudoAtomicRMWPat<atomic_load_nand_i64, ATOMIC_LOAD_NAND_I64, GPR64>;
+def : PseudoAtomicRMWPat<atomic_load_min_i64, ATOMIC_LOAD_MIN_I64, GPR64>;
+def : PseudoAtomicRMWPat<atomic_load_max_i64, ATOMIC_LOAD_MAX_I64, GPR64>;
+def : PseudoAtomicRMWPat<atomic_load_umin_i64, ATOMIC_LOAD_UMIN_I64, GPR64>;
+def : PseudoAtomicRMWPat<atomic_load_umax_i64, ATOMIC_LOAD_UMAX_I64, GPR64>;
+def : PseudoAtomicRMWPat<atomic_swap_i64, ATOMIC_SWAP_I64, GPR64>;
+def : PseudoAtomicCmpSwapPat<atomic_cmp_swap_i64, ATOMIC_CMP_SWAP_I64, GPR64>;
}
-def ATOMIC_LOAD_ADD_I64_POSTRA : Atomic2OpsPostRA<GPR64>;
-def ATOMIC_LOAD_SUB_I64_POSTRA : Atomic2OpsPostRA<GPR64>;
-def ATOMIC_LOAD_AND_I64_POSTRA : Atomic2OpsPostRA<GPR64>;
-def ATOMIC_LOAD_OR_I64_POSTRA : Atomic2OpsPostRA<GPR64>;
-def ATOMIC_LOAD_XOR_I64_POSTRA : Atomic2OpsPostRA<GPR64>;
-def ATOMIC_LOAD_NAND_I64_POSTRA : Atomic2OpsPostRA<GPR64>;
-
-def ATOMIC_SWAP_I64_POSTRA : Atomic2OpsPostRA<GPR64>;
-
-def ATOMIC_CMP_SWAP_I64_POSTRA : AtomicCmpSwapPostRA<GPR64>;
-
-def ATOMIC_LOAD_MIN_I64_POSTRA : Atomic2OpsPostRA<GPR64>;
-def ATOMIC_LOAD_MAX_I64_POSTRA : Atomic2OpsPostRA<GPR64>;
-def ATOMIC_LOAD_UMIN_I64_POSTRA : Atomic2OpsPostRA<GPR64>;
-def ATOMIC_LOAD_UMAX_I64_POSTRA : Atomic2OpsPostRA<GPR64>;
-
/// Pseudo instructions for loading and storing accumulator registers.
let isPseudo = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in {
def LOAD_ACC128 : Load<"", ACC128>;
diff --git a/llvm/lib/Target/Mips/MipsExpandPseudo.cpp b/llvm/lib/Target/Mips/MipsExpandPseudo.cpp
index b39eb9863b0422..30e8182ee6e2cf 100644
--- a/llvm/lib/Target/Mips/MipsExpandPseudo.cpp
+++ b/llvm/lib/Target/Mips/MipsExpandPseudo.cpp
@@ -6,15 +6,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file contains a pass that expands pseudo instructions into target
-// instructions to allow proper scheduling, if-conversion, and other late
-// optimizations. This pass should be run after register allocation but before
-// the post-regalloc scheduling pass.
-//
-// This is currently only used for expanding atomic pseudos after register
-// allocation. We do this to avoid the fast register allocator introducing
-// spills between ll and sc. These stores cause some MIPS implementations to
-// abort the atomic RMW sequence.
+// Expand atomic pseudos into LL/SC loops after register allocation.
//
//===----------------------------------------------------------------------===//
@@ -24,1084 +16,419 @@
#include "llvm/CodeGen/LivePhysRegs.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/IR/Instructions.h"
using namespace llvm;
#define DEBUG_TYPE "mips-pseudo"
namespace {
- class MipsExpandPseudo : public MachineFunctionPass {
- public:
- static char ID;
- MipsExpandPseudo() : MachineFunctionPass(ID) {}
-
- const MipsInstrInfo *TII;
- const MipsSubtarget *STI;
-
- bool runOnMachineFunction(MachineFunction &Fn) override;
-
- MachineFunctionProperties getRequiredProperties() const override {
- return MachineFunctionProperties().setNoVRegs();
- }
+class MipsExpandPseudo : public MachineFunctionPass {
+public:
+ static char ID;
+ MipsExpandPseudo() : MachineFunctionPass(ID) {}
- StringRef getPassName() const override {
- return "Mips pseudo instruction expansion pass";
- }
+ bool runOnMachineFunction(MachineFunction &MF) override;
- private:
- bool expandAtomicCmpSwap(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MBBI,
- MachineBasicBlock::iterator &NextMBBI);
- bool expandAtomicCmpSwapSubword(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MBBI,
- MachineBasicBlock::iterator &NextMBBI);
+ MachineFunctionProperties getRequiredProperties() const override {
+ return MachineFunctionProperties().setNoVRegs();
+ }
- bool expandAtomicBinOp(MachineBasicBlock &BB,
- MachineBasicBlock::iterator I,
- MachineBasicBlock::iterator &NMBBI, unsigned Size);
- bool expandAtomicBinOpSubword(MachineBasicBlock &BB,
- MachineBasicBlock::iterator I,
- MachineBasicBlock::iterator &NMBBI);
+ StringRef getPassName() const override {
+ return "Mips pseudo instruction expansion pass";
+ }
- bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
- MachineBasicBlock::iterator &NMBB);
- bool expandMBB(MachineBasicBlock &MBB);
- };
- char MipsExpandPseudo::ID = 0;
+private:
+ const MipsInstrInfo *TII;
+ const MipsSubtarget *STI;
+
+ struct AtomicOpcodes {
+ unsigned LL, SC, BEQ, BNE, OR, Zero;
+ };
+ AtomicOpcodes getAtomicOpcodes(unsigned Width) const;
+
+ bool expandAtomicCmpSwap(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI, bool IsMasked,
+ unsigned Width,
+ MachineBasicBlock::iterator &NextMBBI);
+ bool expandAtomicRMW(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
+ AtomicRMWInst::BinOp BinOp, bool IsMasked,
+ unsigned Width, MachineBasicBlock::iterator &NextMBBI);
+ bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
+ MachineBasicBlock::iterator &NextMBBI);
+ bool expandMBB(MachineBasicBlock &MBB);
+};
+char MipsExpandPseudo::ID = 0;
+} // end anonymous namespace
+
+MipsExpandPseudo::AtomicOpcodes
+MipsExpandPseudo::getAtomicOpcodes(unsigned Width) const {
+ if (Width == 64)
+ return {STI->hasMips64r6() ? Mips::LLD_R6 : Mips::LLD,
+ STI->hasMips64r6() ? Mips::SCD_R6 : Mips::SCD,
+ Mips::BEQ64,
+ Mips::BNE64,
+ Mips::OR64,
+ Mips::ZERO_64};
+
+ assert(Width == 32 && "Unexpected atomic width");
+ if (STI->inMicroMipsMode())
+ return {STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM,
+ STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM,
+ STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM,
+ STI->hasMips32r6() ? Mips::BNEC_MMR6 : Mips::BNE_MM,
+ STI->hasMips32r6() ? Mips::OR_MMR6 : Mips::OR_MM,
+ Mips::ZERO};
+
+ bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
+ return {STI->hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
+ : (ArePtrs64bit ? Mips::LL64 : Mips::LL),
+ STI->hasMips32r6() ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
+ : (ArePtrs64bit ? Mips::SC64 : Mips::SC),
+ Mips::BEQ,
+ Mips::BNE,
+ Mips::OR,
+ Mips::ZERO};
}
-bool MipsExpandPseudo::expandAtomicCmpSwapSubword(
- MachineBasicBlock &BB, MachineBasicBlock::iterator I,
- MachineBasicBlock::iterator &NMBBI) {
-
- MachineFunction *MF = BB.getParent();
-
- const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
- DebugLoc DL = I->getDebugLoc();
- unsigned LL, SC;
-
- unsigned ZERO = Mips::ZERO;
- unsigned BNE = Mips::BNE;
- unsigned BEQ = Mips::BEQ;
- unsigned SEOp =
- I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I8_POSTRA ? Mips::SEB : Mips::SEH;
+// Merge selected bits as old ^ ((old ^ new) & mask).
+static void insertMaskedMerge(const MipsInstrInfo *TII, MachineBasicBlock *MBB,
+ DebugLoc DL, Register Dest, Register OldVal,
+ Register NewVal, Register Mask) {
+ assert(Dest != OldVal && "The old value must survive the masked merge");
+ BuildMI(MBB, DL, TII->get(Mips::XOR), Dest).addReg(OldVal).addReg(NewVal);
+ BuildMI(MBB, DL, TII->get(Mips::AND), Dest).addReg(Dest).addReg(Mask);
+ BuildMI(MBB, DL, TII->get(Mips::XOR), Dest).addReg(OldVal).addReg(Dest);
+}
- if (STI->inMicroMipsMode()) {
- LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
- SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
- BNE = STI->hasMips32r6() ? Mips::BNEC_MMR6 : Mips::BNE_MM;
- BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
+bool MipsExpandPseudo::expandAtomicCmpSwap(
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, bool IsMasked,
+ unsigned Width, MachineBasicBlock::iterator &NextMBBI) {
+ assert((!IsMasked || Width == 32) && "Masked atomics use a word LL/SC");
+ MachineInstr &MI = *MBBI;
+ MachineFunction *MF = MBB.getParent();
+ DebugLoc DL = MI.getDebugLoc();
+ AtomicOpcodes Opc = getAtomicOpcodes(Width);
+
+ Register Dest = MI.getOperand(0).getReg();
+ Register Scratch = MI.getOperand(1).getReg();
+ Register Ptr = MI.getOperand(2).getReg();
+ Register CmpVal = MI.getOperand(3).getReg();
+ Register NewVal = MI.getOperand(4).getReg();
+ Register Mask = IsMasked ? MI.getOperand(5).getReg() : Register();
+
+ auto *LoopMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
+ auto *StoreMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
+ auto *DoneMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
+ auto It = std::next(MBB.getIterator());
+ MF->insert(It, LoopMBB);
+ MF->insert(It, StoreMBB);
+ MF->insert(It, DoneMBB);
+
+ DoneMBB->splice(DoneMBB->end(), &MBB, MI, MBB.end());
+ DoneMBB->transferSuccessorsAndUpdatePHIs(&MBB);
+ MBB.addSuccessor(LoopMBB, BranchProbability::getOne());
+ LoopMBB->addSuccessor(DoneMBB);
+ LoopMBB->addSuccessor(StoreMBB);
+ LoopMBB->normalizeSuccProbs();
+ StoreMBB->addSuccessor(LoopMBB);
+ StoreMBB->addSuccessor(DoneMBB);
+ StoreMBB->normalizeSuccProbs();
+
+ BuildMI(LoopMBB, DL, TII->get(Opc.LL), Dest).addReg(Ptr).addImm(0);
+ Register Loaded = Dest;
+ if (IsMasked) {
+ BuildMI(LoopMBB, DL, TII->get(Mips::AND), Scratch)
+ .addReg(Dest)
+ .addReg(Mask);
+ Loaded = Scratch;
+ }
+ BuildMI(LoopMBB, DL, TII->get(Opc.BNE))
+ .addReg(Loaded)
+ .addReg(CmpVal)
+ .addMBB(DoneMBB);
+
+ if (IsMasked) {
+ // Scratch contains the masked old value; XOR clears those bits.
+ BuildMI(StoreMBB, DL, TII->get(Mips::XOR), Scratch)
+ .addReg(Dest)
+ .addReg(Scratch);
+ BuildMI(StoreMBB, DL, TII->get(Mips::OR), Scratch)
+ .addReg(Scratch)
+ .addReg(NewVal);
} else {
- LL = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
- : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
- SC = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
- : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
+ TII->copyPhysReg(*StoreMBB, StoreMBB->end(), DL, Scratch, NewVal, false);
}
-
- Register Dest = I->getOperand(0).getReg();
- Register Ptr = I->getOperand(1).getReg();
- Register Mask = I->getOperand(2).getReg();
- Register ShiftCmpVal = I->getOperand(3).getReg();
- Register Mask2 = I->getOperand(4).getReg();
- Register ShiftNewVal = I->getOperand(5).getReg();
- Register ShiftAmnt = I->getOperand(6).getReg();
- Register Scratch = I->getOperand(7).getReg();
- Register Scratch2 = I->getOperand(8).getReg();
-
- // insert new blocks after the current block
- const BasicBlock *LLVM_BB = BB.getBasicBlock();
- MachineBasicBlock *loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB);
- MachineBasicBlock *loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB);
- MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(LLVM_BB);
- MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
- MachineFunction::iterator It = ++BB.getIterator();
- MF->insert(It, loop1MBB);
- MF->insert(It, loop2MBB);
- MF->insert(It, sinkMBB);
- MF->insert(It, exitMBB);
-
- // Transfer the remainder of BB and its successor edges to exitMBB.
- exitMBB->splice(exitMBB->begin(), &BB,
- std::next(MachineBasicBlock::iterator(I)), BB.end());
- exitMBB->transferSuccessorsAndUpdatePHIs(&BB);
-
- // thisMBB:
- // ...
- // fallthrough --> loop1MBB
- BB.addSuccessor(loop1MBB, BranchProbability::getOne());
- loop1MBB->addSuccessor(sinkMBB);
- loop1MBB->addSuccessor(loop2MBB);
- loop1MBB->normalizeSuccProbs();
- loop2MBB->addSuccessor(loop1MBB);
- loop2MBB->addSuccessor(sinkMBB);
- loop2MBB->normalizeSuccProbs();
- sinkMBB->addSuccessor(exitMBB, BranchProbability::getOne());
-
- // loop1MBB:
- // ll dest, 0(ptr)
- // and Mask', dest, Mask
- // bne Mask', ShiftCmpVal, exitMBB
- BuildMI(loop1MBB, DL, TII->get(LL), Scratch).addReg(Ptr).addImm(0);
- BuildMI(loop1MBB, DL, TII->get(Mips::AND), Scratch2)
+ BuildMI(StoreMBB, DL, TII->get(Opc.SC), Scratch)
.addReg(Scratch)
- .addReg(Mask);
- BuildMI(loop1MBB, DL, TII->get(BNE))
- .addReg(Scratch2).addReg(ShiftCmpVal).addMBB(sinkMBB);
-
- // loop2MBB:
- // and dest, dest, mask2
- // or dest, dest, ShiftNewVal
- // sc dest, dest, 0(ptr)
- // beq dest, $0, loop1MBB
- BuildMI(loop2MBB, DL, TII->get(Mips::AND), Scratch)
- .addReg(Scratch, RegState::Kill)
- .addReg(Mask2);
- BuildMI(loop2MBB, DL, TII->get(Mips::OR), Scratch)
- .addReg(Scratch, RegState::Kill)
- .addReg(ShiftNewVal);
- BuildMI(loop2MBB, DL, TII->get(SC), Scratch)
- .addReg(Scratch, RegState::Kill)
.addReg(Ptr)
.addImm(0);
- BuildMI(loop2MBB, DL, TII->get(BEQ))
- .addReg(Scratch, RegState::Kill)
- .addReg(ZERO)
- .addMBB(loop1MBB);
-
- // sinkMBB:
- // srl srlres, Mask', shiftamt
- // sign_extend dest,srlres
- BuildMI(sinkMBB, DL, TII->get(Mips::SRLV), Dest)
- .addReg(Scratch2)
- .addReg(ShiftAmnt);
- if (STI->hasMips32r2()) {
- BuildMI(sinkMBB, DL, TII->get(SEOp), Dest).addReg(Dest);
- } else {
- const unsigned ShiftImm =
- I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I16_POSTRA ? 16 : 24;
- BuildMI(sinkMBB, DL, TII->get(Mips::SLL), Dest)
- .addReg(Dest, RegState::Kill)
- .addImm(ShiftImm);
- BuildMI(sinkMBB, DL, TII->get(Mips::SRA), Dest)
- .addReg(Dest, RegState::Kill)
- .addImm(ShiftImm);
- }
-
- LivePhysRegs LiveRegs;
- computeAndAddLiveIns(LiveRegs, *loop1MBB);
- computeAndAddLiveIns(LiveRegs, *loop2MBB);
- computeAndAddLiveIns(LiveRegs, *sinkMBB);
- computeAndAddLiveIns(LiveRegs, *exitMBB);
-
- NMBBI = BB.end();
- I->eraseFromParent();
- return true;
-}
-
-bool MipsExpandPseudo::expandAtomicCmpSwap(MachineBasicBlock &BB,
- MachineBasicBlock::iterator I,
- MachineBasicBlock::iterator &NMBBI) {
-
- const unsigned Size =
- I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I32_POSTRA ? 4 : 8;
- MachineFunction *MF = BB.getParent();
-
- const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
- DebugLoc DL = I->getDebugLoc();
-
- unsigned LL, SC, ZERO, BNE, BEQ, MOVE;
-
- if (Size == 4) {
- if (STI->inMicroMipsMode()) {
- LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
- SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
- BNE = STI->hasMips32r6() ? Mips::BNEC_MMR6 : Mips::BNE_MM;
- BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
- } else {
- LL = STI->hasMips32r6()
- ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
- : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
- SC = STI->hasMips32r6()
- ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
- : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
- BNE = Mips::BNE;
- BEQ = Mips::BEQ;
- }
-
- ZERO = Mips::ZERO;
- MOVE = Mips::OR;
- } else {
- LL = STI->hasMips64r6() ? Mips::LLD_R6 : Mips::LLD;
- SC = STI->hasMips64r6() ? Mips::SCD_R6 : Mips::SCD;
- ZERO = Mips::ZERO_64;
- BNE = Mips::BNE64;
- BEQ = Mips::BEQ64;
- MOVE = Mips::OR64;
- }
-
- Register Dest = I->getOperand(0).getReg();
- Register Ptr = I->getOperand(1).getReg();
- Register OldVal = I->getOperand(2).getReg();
- Register NewVal = I->getOperand(3).getReg();
- Register Scratch = I->getOperand(4).getReg();
-
- // insert new blocks after the current block
- const BasicBlock *LLVM_BB = BB.getBasicBlock();
- MachineBasicBlock *loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB);
- MachineBasicBlock *loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB);
- MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
- MachineFunction::iterator It = ++BB.getIterator();
- MF->insert(It, loop1MBB);
- MF->insert(It, loop2MBB);
- MF->insert(It, exitMBB);
-
- // Transfer the remainder of BB and its successor edges to exitMBB.
- exitMBB->splice(exitMBB->begin(), &BB,
- std::next(MachineBasicBlock::iterator(I)), BB.end());
- exitMBB->transferSuccessorsAndUpdatePHIs(&BB);
-
- // thisMBB:
- // ...
- // fallthrough --> loop1MBB
- BB.addSuccessor(loop1MBB, BranchProbability::getOne());
- loop1MBB->addSuccessor(exitMBB);
- loop1MBB->addSuccessor(loop2MBB);
- loop1MBB->normalizeSuccProbs();
- loop2MBB->addSuccessor(loop1MBB);
- loop2MBB->addSuccessor(exitMBB);
- loop2MBB->normalizeSuccProbs();
-
- // loop1MBB:
- // ll dest, 0(ptr)
- // bne dest, oldval, exitMBB
- BuildMI(loop1MBB, DL, TII->get(LL), Dest).addReg(Ptr).addImm(0);
- BuildMI(loop1MBB, DL, TII->get(BNE))
- .addReg(Dest, RegState::Kill).addReg(OldVal).addMBB(exitMBB);
+ BuildMI(StoreMBB, DL, TII->get(Opc.BEQ))
+ .addReg(Scratch)
+ .addReg(Opc.Zero)
+ .addMBB(LoopMBB);
- // loop2MBB:
- // move scratch, NewVal
- // sc Scratch, Scratch, 0(ptr)
- // beq Scratch, $0, loop1MBB
- BuildMI(loop2MBB, DL, TII->get(MOVE), Scratch).addReg(NewVal).addReg(ZERO);
- BuildMI(loop2MBB, DL, TII->get(SC), Scratch)
- .addReg(Scratch).addReg(Ptr).addImm(0);
- BuildMI(loop2MBB, DL, TII->get(BEQ))
- .addReg(Scratch, RegState::Kill).addReg(ZERO).addMBB(loop1MBB);
+ NextMBBI = MBB.end();
+ MI.eraseFromParent();
LivePhysRegs LiveRegs;
- computeAndAddLiveIns(LiveRegs, *loop1MBB);
- computeAndAddLiveIns(LiveRegs, *loop2MBB);
- computeAndAddLiveIns(LiveRegs, *exitMBB);
-
- NMBBI = BB.end();
- I->eraseFromParent();
+ computeAndAddLiveIns(LiveRegs, *LoopMBB);
+ computeAndAddLiveIns(LiveRegs, *StoreMBB);
+ computeAndAddLiveIns(LiveRegs, *DoneMBB);
return true;
}
-bool MipsExpandPseudo::expandAtomicBinOpSubword(
- MachineBasicBlock &BB, MachineBasicBlock::iterator I,
- MachineBasicBlock::iterator &NMBBI) {
-
- MachineFunction *MF = BB.getParent();
-
- const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
- DebugLoc DL = I->getDebugLoc();
-
- unsigned LL, SC, SLT, SLTu, OR, MOVN, MOVZ, SELNEZ, SELEQZ;
- unsigned BEQ = Mips::BEQ;
- unsigned SEOp = Mips::SEH;
-
- if (STI->inMicroMipsMode()) {
- LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
- SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
- BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
- SLT = Mips::SLT_MM;
- SLTu = Mips::SLTu_MM;
- OR = STI->hasMips32r6() ? Mips::OR_MMR6 : Mips::OR_MM;
- MOVN = Mips::MOVN_I_MM;
- MOVZ = Mips::MOVZ_I_MM;
- SELNEZ = STI->hasMips32r6() ? Mips::SELNEZ_MMR6 : Mips::SELNEZ;
- SELEQZ = STI->hasMips32r6() ? Mips::SELEQZ_MMR6 : Mips::SELEQZ;
- } else {
- LL = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
- : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
- SC = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
- : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
- SLT = Mips::SLT;
- SLTu = Mips::SLTu;
- OR = Mips::OR;
- MOVN = Mips::MOVN_I_I;
- MOVZ = Mips::MOVZ_I_I;
- SELNEZ = Mips::SELNEZ;
- SELEQZ = Mips::SELEQZ;
- }
-
- bool IsSwap = false;
- bool IsNand = false;
- bool IsMin = false;
- bool IsMax = false;
- bool IsUnsigned = false;
- bool DestOK = false;
-
- unsigned Opcode = 0;
- switch (I->getOpcode()) {
- case Mips::ATOMIC_LOAD_NAND_I8_POSTRA:
- SEOp = Mips::SEB;
- [[fallthrough]];
- case Mips::ATOMIC_LOAD_NAND_I16_POSTRA:
- IsNand = true;
- break;
- case Mips::ATOMIC_SWAP_I8_POSTRA:
- SEOp = Mips::SEB;
- [[fallthrough]];
- case Mips::ATOMIC_SWAP_I16_POSTRA:
- IsSwap = true;
- break;
- case Mips::ATOMIC_LOAD_ADD_I8_POSTRA:
- SEOp = Mips::SEB;
- [[fallthrough]];
- case Mips::ATOMIC_LOAD_ADD_I16_POSTRA:
- Opcode = Mips::ADDu;
- break;
- case Mips::ATOMIC_LOAD_SUB_I8_POSTRA:
- SEOp = Mips::SEB;
- [[fallthrough]];
- case Mips::ATOMIC_LOAD_SUB_I16_POSTRA:
- Opcode = Mips::SUBu;
- break;
- case Mips::ATOMIC_LOAD_AND_I8_POSTRA:
- SEOp = Mips::SEB;
- [[fallthrough]];
- case Mips::ATOMIC_LOAD_AND_I16_POSTRA:
- Opcode = Mips::AND;
- break;
- case Mips::ATOMIC_LOAD_OR_I8_POSTRA:
- SEOp = Mips::SEB;
- [[fallthrough]];
- case Mips::ATOMIC_LOAD_OR_I16_POSTRA:
- Opcode = Mips::OR;
- break;
- case Mips::ATOMIC_LOAD_XOR_I8_POSTRA:
- SEOp = Mips::SEB;
- [[fallthrough]];
- case Mips::ATOMIC_LOAD_XOR_I16_POSTRA:
- Opcode = Mips::XOR;
- break;
- case Mips::ATOMIC_LOAD_UMIN_I8_POSTRA:
- SEOp = Mips::SEB;
- IsUnsigned = true;
- IsMin = true;
- break;
- case Mips::ATOMIC_LOAD_UMIN_I16_POSTRA:
- IsUnsigned = true;
- IsMin = true;
- break;
- case Mips::ATOMIC_LOAD_MIN_I8_POSTRA:
- SEOp = Mips::SEB;
- IsMin = true;
- break;
- case Mips::ATOMIC_LOAD_MIN_I16_POSTRA:
- IsMin = true;
- break;
- case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA:
- SEOp = Mips::SEB;
- IsUnsigned = true;
- IsMax = true;
- break;
- case Mips::ATOMIC_LOAD_UMAX_I16_POSTRA:
- IsUnsigned = true;
- IsMax = true;
- break;
- case Mips::ATOMIC_LOAD_MAX_I8_POSTRA:
- SEOp = Mips::SEB;
- IsMax = true;
- break;
- case Mips::ATOMIC_LOAD_MAX_I16_POSTRA:
- IsMax = true;
- break;
+static unsigned getAtomicBinOp(AtomicRMWInst::BinOp BinOp, unsigned Width) {
+ switch (BinOp) {
default:
- llvm_unreachable("Unknown subword atomic pseudo for expansion!");
- }
-
- Register Dest = I->getOperand(0).getReg();
- Register Ptr = I->getOperand(1).getReg();
- Register Incr = I->getOperand(2).getReg();
- Register Mask = I->getOperand(3).getReg();
- Register Mask2 = I->getOperand(4).getReg();
- Register ShiftAmnt = I->getOperand(5).getReg();
- Register OldVal = I->getOperand(6).getReg();
- Register BinOpRes = I->getOperand(7).getReg();
- Register StoreVal = I->getOperand(8).getReg();
- bool NoMovnInstr = (IsMin || IsMax) && !STI->hasMips4() && !STI->hasMips32();
-
- const BasicBlock *LLVM_BB = BB.getBasicBlock();
- MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB);
- MachineBasicBlock *loop1MBB = nullptr;
- MachineBasicBlock *loop2MBB = nullptr;
- if (NoMovnInstr) {
- loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB);
- loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB);
+ llvm_unreachable("Unexpected atomicrmw operation");
+ case AtomicRMWInst::Add:
+ return Width == 64 ? Mips::DADDu : Mips::ADDu;
+ case AtomicRMWInst::Sub:
+ return Width == 64 ? Mips::DSUBu : Mips::SUBu;
+ case AtomicRMWInst::And:
+ case AtomicRMWInst::Nand:
+ return Width == 64 ? Mips::AND64 : Mips::AND;
+ case AtomicRMWInst::Or:
+ return Width == 64 ? Mips::OR64 : Mips::OR;
+ case AtomicRMWInst::Xor:
+ return Width == 64 ? Mips::XOR64 : Mips::XOR;
}
- MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(LLVM_BB);
- MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
- MachineFunction::iterator It = ++BB.getIterator();
- MF->insert(It, loopMBB);
- if (NoMovnInstr) {
- MF->insert(It, loop1MBB);
- MF->insert(It, loop2MBB);
- }
- MF->insert(It, sinkMBB);
- MF->insert(It, exitMBB);
-
- exitMBB->splice(exitMBB->begin(), &BB, std::next(I), BB.end());
- exitMBB->transferSuccessorsAndUpdatePHIs(&BB);
+}
- BB.addSuccessor(loopMBB, BranchProbability::getOne());
- if (NoMovnInstr) {
- loopMBB->addSuccessor(loop1MBB);
- loopMBB->addSuccessor(loop2MBB);
- } else {
- loopMBB->addSuccessor(sinkMBB);
- loopMBB->addSuccessor(loopMBB);
- loopMBB->normalizeSuccProbs();
- }
- if (NoMovnInstr) {
- loop1MBB->addSuccessor(loop2MBB);
- loop2MBB->addSuccessor(loopMBB);
- loop2MBB->addSuccessor(sinkMBB);
+bool MipsExpandPseudo::expandAtomicRMW(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI,
+ AtomicRMWInst::BinOp BinOp,
+ bool IsMasked, unsigned Width,
+ MachineBasicBlock::iterator &NextMBBI) {
+ assert((!IsMasked || Width == 32) && "Masked atomics use a word LL/SC");
+ MachineInstr &MI = *MBBI;
+ MachineFunction *MF = MBB.getParent();
+ DebugLoc DL = MI.getDebugLoc();
+ AtomicOpcodes Opc = getAtomicOpcodes(Width);
+ bool IsMin = BinOp == AtomicRMWInst::Min || BinOp == AtomicRMWInst::UMin;
+ bool IsMax = BinOp == AtomicRMWInst::Max || BinOp == AtomicRMWInst::UMax;
+ bool IsMinMax = IsMin || IsMax;
+ bool IsSigned = BinOp == AtomicRMWInst::Min || BinOp == AtomicRMWInst::Max;
+ bool NeedsBranch = IsMinMax && !STI->hasMips4() && !STI->hasMips32();
+
+ Register Dest = MI.getOperand(0).getReg();
+ Register Scratch = MI.getOperand(1).getReg();
+ unsigned FirstInput = MI.getNumExplicitDefs();
+ Register Ptr = MI.getOperand(FirstInput).getReg();
+ Register Incr = MI.getOperand(FirstInput + 1).getReg();
+ Register Mask =
+ IsMasked ? MI.getOperand(FirstInput + 2).getReg() : Register();
+
+ auto *LoopMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
+ MachineBasicBlock *UpdateMBB = nullptr;
+ MachineBasicBlock *StoreMBB = LoopMBB;
+ auto *DoneMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
+ auto It = std::next(MBB.getIterator());
+ MF->insert(It, LoopMBB);
+ if (NeedsBranch) {
+ UpdateMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
+ StoreMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
+ MF->insert(It, UpdateMBB);
+ MF->insert(It, StoreMBB);
+ LoopMBB->addSuccessor(UpdateMBB);
+ LoopMBB->addSuccessor(StoreMBB);
+ LoopMBB->normalizeSuccProbs();
+ UpdateMBB->addSuccessor(StoreMBB, BranchProbability::getOne());
}
-
- BuildMI(loopMBB, DL, TII->get(LL), OldVal).addReg(Ptr).addImm(0);
- if (IsNand) {
- // and andres, oldval, incr2
- // nor binopres, $0, andres
- // and newval, binopres, mask
- BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)
- .addReg(OldVal)
- .addReg(Incr);
- BuildMI(loopMBB, DL, TII->get(Mips::NOR), BinOpRes)
- .addReg(Mips::ZERO)
- .addReg(BinOpRes);
- BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)
- .addReg(BinOpRes)
- .addReg(Mask);
- } else if (IsMin || IsMax) {
-
- assert(I->getNumOperands() == 10 &&
- "Atomics min|max|umin|umax use an additional register");
- Register Scratch4 = I->getOperand(9).getReg();
-
- unsigned SLTScratch4 = IsUnsigned ? SLTu : SLT;
- unsigned SELIncr = IsMax ? SELNEZ : SELEQZ;
- unsigned SELOldVal = IsMax ? SELEQZ : SELNEZ;
- unsigned MOVIncr = IsMax ? MOVN : MOVZ;
-
- BuildMI(loopMBB, DL, TII->get(Mips::SRAV), StoreVal)
- .addReg(OldVal)
- .addReg(ShiftAmnt);
- if (IsUnsigned) {
- const unsigned OpMask = SEOp == Mips::SEH ? 0xffff : 0xff;
- BuildMI(loopMBB, DL, TII->get(Mips::ANDi), StoreVal)
- .addReg(StoreVal)
- .addImm(OpMask);
- } else if (STI->hasMips32r2()) {
- BuildMI(loopMBB, DL, TII->get(SEOp), StoreVal).addReg(StoreVal);
- } else {
- const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;
- const unsigned SROp = IsUnsigned ? Mips::SRL : Mips::SRA;
- BuildMI(loopMBB, DL, TII->get(Mips::SLL), StoreVal)
- .addReg(StoreVal, RegState::Kill)
- .addImm(ShiftImm);
- BuildMI(loopMBB, DL, TII->get(SROp), StoreVal)
- .addReg(StoreVal, RegState::Kill)
- .addImm(ShiftImm);
+ MF->insert(It, DoneMBB);
+ DoneMBB->splice(DoneMBB->end(), &MBB, MI, MBB.end());
+ DoneMBB->transferSuccessorsAndUpdatePHIs(&MBB);
+ MBB.addSuccessor(LoopMBB, BranchProbability::getOne());
+ StoreMBB->addSuccessor(LoopMBB);
+ StoreMBB->addSuccessor(DoneMBB);
+ StoreMBB->normalizeSuccProbs();
+
+ BuildMI(LoopMBB, DL, TII->get(Opc.LL), Dest).addReg(Ptr).addImm(0);
+ Register NewVal = Scratch;
+ if (IsMinMax) {
+ Register Cmp = MI.getOperand(2).getReg();
+ // SLT64 defines a GPR32 result, but the r6 selects reuse the full scratch
+ // register for a 64-bit value. Its explicit output reserves both aliases.
+ Register Cmp32 = Width == 64
+ ? STI->getRegisterInfo()->getSubReg(Cmp, Mips::sub_32)
+ : Cmp.asMCReg();
+ Register Loaded = Dest;
+ if (IsMasked) {
+ BuildMI(LoopMBB, DL, TII->get(Mips::AND), Scratch)
+ .addReg(Dest)
+ .addReg(Mask);
+ if (IsSigned) {
+ Register SextShift = MI.getOperand(FirstInput + 3).getReg();
+ BuildMI(LoopMBB, DL, TII->get(Mips::SLLV), Scratch)
+ .addReg(Scratch)
+ .addReg(SextShift);
+ BuildMI(LoopMBB, DL, TII->get(Mips::SRAV), Scratch)
+ .addReg(Scratch)
+ .addReg(SextShift);
+ }
+ Loaded = Scratch;
}
- BuildMI(loopMBB, DL, TII->get(Mips::OR), Dest)
- .addReg(Mips::ZERO)
- .addReg(StoreVal);
- DestOK = true;
- BuildMI(loopMBB, DL, TII->get(Mips::SLLV), StoreVal)
- .addReg(StoreVal)
- .addReg(ShiftAmnt);
- // unsigned: sltu Scratch4, StoreVal, Incr
- // signed: slt Scratch4, StoreVal, Incr
- BuildMI(loopMBB, DL, TII->get(SLTScratch4), Scratch4)
- .addReg(StoreVal)
- .addReg(Incr);
-
- if (STI->hasMips64r6() || STI->hasMips32r6()) {
- // max: seleqz BinOpRes, OldVal, Scratch4
- // selnez Scratch4, Incr, Scratch4
- // or BinOpRes, BinOpRes, Scratch4
- // min: selnqz BinOpRes, OldVal, Scratch4
- // seleqz Scratch4, Incr, Scratch4
- // or BinOpRes, BinOpRes, Scratch4
- BuildMI(loopMBB, DL, TII->get(SELOldVal), BinOpRes)
- .addReg(StoreVal)
- .addReg(Scratch4);
- BuildMI(loopMBB, DL, TII->get(SELIncr), Scratch4)
- .addReg(Incr)
- .addReg(Scratch4);
- BuildMI(loopMBB, DL, TII->get(OR), BinOpRes)
- .addReg(BinOpRes)
- .addReg(Scratch4);
- } else if (STI->hasMips4() || STI->hasMips32()) {
- // max: move BinOpRes, StoreVal
- // movn BinOpRes, Incr, Scratch4, BinOpRes
- // min: move BinOpRes, StoreVal
- // movz BinOpRes, Incr, Scratch4, BinOpRes
- BuildMI(loopMBB, DL, TII->get(OR), BinOpRes)
- .addReg(StoreVal)
- .addReg(Mips::ZERO);
- BuildMI(loopMBB, DL, TII->get(MOVIncr), BinOpRes)
- .addReg(Incr)
- .addReg(Scratch4)
- .addReg(BinOpRes);
+ unsigned SLT = IsSigned ? Mips::SLT : Mips::SLTu;
+ if (Width == 64)
+ SLT = IsSigned ? Mips::SLT64 : Mips::SLTu64;
+ else if (STI->inMicroMipsMode())
+ SLT = IsSigned ? Mips::SLT_MM : Mips::SLTu_MM;
+ BuildMI(LoopMBB, DL, TII->get(SLT), Cmp32)
+ .addReg(IsMin ? Incr : Loaded)
+ .addReg(IsMin ? Loaded : Incr);
+ if (STI->hasMips32r6()) {
+ unsigned SELEQZ = Width == 64 ? Mips::SELEQZ64 : Mips::SELEQZ;
+ unsigned SELNEZ = Width == 64 ? Mips::SELNEZ64 : Mips::SELNEZ;
+ if (STI->inMicroMipsMode()) {
+ SELEQZ = Mips::SELEQZ_MMR6;
+ SELNEZ = Mips::SELNEZ_MMR6;
+ }
+ BuildMI(LoopMBB, DL, TII->get(SELEQZ), Scratch)
+ .addReg(Loaded)
+ .addReg(Cmp);
+ BuildMI(LoopMBB, DL, TII->get(SELNEZ), Cmp).addReg(Incr).addReg(Cmp);
+ BuildMI(LoopMBB, DL, TII->get(Opc.OR), Scratch)
+ .addReg(Scratch)
+ .addReg(Cmp);
} else {
- // if min:
- // loopMBB: move BinOpRes, StoreVal
- // beq Scratch4, 0, loop1MBB
- // j loop2MBB
- // loop1MBB: move BinOpRes, Incr
- // loop2MBB: and BinOpRes, BinOpRes, Mask
- // and StoreVal, OlddVal, Mask2
- // or StoreVal, StoreVal, BinOpRes
- // StoreVal<tied1> = sc StoreVal, 0(Ptr)
- // beq StoreVal, zero, loopMBB
- //
- // if max:
- // loopMBB: move BinOpRes, Incr
- // beq Scratch4, 0, loop1MBB
- // j loop2MBB
- // loop1MBB: move BinOpRes, StoreVal
- // loop2MBB: and BinOpRes, BinOpRes, Mask
- // and StoreVal, OlddVal, Mask2
- // or StoreVal, StoreVal, BinOpRes
- // StoreVal<tied1> = sc StoreVal, 0(Ptr)
- // beq StoreVal, zero, loopMBB
- if (IsMin) {
- BuildMI(loopMBB, DL, TII->get(OR), BinOpRes)
- .addReg(StoreVal)
- .addReg(Mips::ZERO);
- BuildMI(loop1MBB, DL, TII->get(OR), BinOpRes)
+ if (!IsMasked)
+ BuildMI(LoopMBB, DL, TII->get(Opc.OR), Scratch)
+ .addReg(Dest)
+ .addReg(Opc.Zero);
+ if (!NeedsBranch) {
+ unsigned MOVN = Width == 64 ? Mips::MOVN_I64_I64 : Mips::MOVN_I_I;
+ if (STI->inMicroMipsMode())
+ MOVN = Mips::MOVN_I_MM;
+ BuildMI(LoopMBB, DL, TII->get(MOVN), Scratch)
.addReg(Incr)
- .addReg(Mips::ZERO);
+ .addReg(Cmp)
+ .addReg(Scratch);
} else {
- BuildMI(loopMBB, DL, TII->get(OR), BinOpRes)
+ BuildMI(LoopMBB, DL, TII->get(Mips::BEQ))
+ .addReg(Cmp32)
+ .addReg(Mips::ZERO)
+ .addMBB(StoreMBB);
+ BuildMI(UpdateMBB, DL, TII->get(Opc.OR), Scratch)
.addReg(Incr)
- .addReg(Mips::ZERO);
- BuildMI(loop1MBB, DL, TII->get(OR), BinOpRes)
- .addReg(StoreVal)
- .addReg(Mips::ZERO);
+ .addReg(Opc.Zero);
}
- BuildMI(loopMBB, DL, TII->get(BEQ))
- .addReg(Scratch4)
- .addReg(Mips::ZERO)
- .addMBB(loop1MBB);
- BuildMI(loopMBB, DL, TII->get(Mips::J)).addMBB(loop2MBB);
}
-
- // and BinOpRes, BinOpRes, Mask
- if (NoMovnInstr)
- BuildMI(loop2MBB, DL, TII->get(Mips::AND), BinOpRes)
- .addReg(BinOpRes)
- .addReg(Mask);
+ } else if (BinOp == AtomicRMWInst::Xchg) {
+ if (IsMasked)
+ NewVal = Incr;
else
- BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)
- .addReg(BinOpRes)
- .addReg(Mask);
-
- } else if (!IsSwap) {
- // <binop> binopres, oldval, incr2
- // and newval, binopres, mask
- BuildMI(loopMBB, DL, TII->get(Opcode), BinOpRes)
- .addReg(OldVal)
- .addReg(Incr);
- BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)
- .addReg(BinOpRes)
- .addReg(Mask);
- } else { // atomic.swap
- // and newval, incr2, mask
- BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)
- .addReg(Incr)
- .addReg(Mask);
- }
-
- // and StoreVal, OlddVal, Mask2
- // or StoreVal, StoreVal, BinOpRes
- // StoreVal<tied1> = sc StoreVal, 0(Ptr)
- // beq StoreVal, zero, loopMBB
- if (NoMovnInstr) {
- BuildMI(loop2MBB, DL, TII->get(Mips::AND), StoreVal)
- .addReg(OldVal)
- .addReg(Mask2);
- BuildMI(loop2MBB, DL, TII->get(Mips::OR), StoreVal)
- .addReg(StoreVal)
- .addReg(BinOpRes);
- BuildMI(loop2MBB, DL, TII->get(SC), StoreVal)
- .addReg(StoreVal)
- .addReg(Ptr)
- .addImm(0);
- BuildMI(loop2MBB, DL, TII->get(BEQ))
- .addReg(StoreVal)
- .addReg(Mips::ZERO)
- .addMBB(loopMBB);
+ BuildMI(LoopMBB, DL, TII->get(Opc.OR), Scratch)
+ .addReg(Incr)
+ .addReg(Opc.Zero);
} else {
- BuildMI(loopMBB, DL, TII->get(Mips::AND), StoreVal)
- .addReg(OldVal)
- .addReg(Mask2);
- BuildMI(loopMBB, DL, TII->get(Mips::OR), StoreVal)
- .addReg(StoreVal)
- .addReg(BinOpRes);
- BuildMI(loopMBB, DL, TII->get(SC), StoreVal)
- .addReg(StoreVal)
- .addReg(Ptr)
- .addImm(0);
- BuildMI(loopMBB, DL, TII->get(BEQ))
- .addReg(StoreVal)
- .addReg(Mips::ZERO)
- .addMBB(loopMBB);
- }
-
- // sinkMBB:
- // and maskedoldval1,oldval,mask
- // srl srlres,maskedoldval1,shiftamt
- // sign_extend dest,srlres
-
- if (!DestOK) {
- sinkMBB->addSuccessor(exitMBB, BranchProbability::getOne());
- BuildMI(sinkMBB, DL, TII->get(Mips::AND), Dest).addReg(OldVal).addReg(Mask);
- BuildMI(sinkMBB, DL, TII->get(Mips::SRLV), Dest)
+ BuildMI(LoopMBB, DL, TII->get(getAtomicBinOp(BinOp, Width)), Scratch)
.addReg(Dest)
- .addReg(ShiftAmnt);
-
- if (STI->hasMips32r2()) {
- BuildMI(sinkMBB, DL, TII->get(SEOp), Dest).addReg(Dest);
- } else {
- const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;
- BuildMI(sinkMBB, DL, TII->get(Mips::SLL), Dest)
- .addReg(Dest, RegState::Kill)
- .addImm(ShiftImm);
- BuildMI(sinkMBB, DL, TII->get(Mips::SRA), Dest)
- .addReg(Dest, RegState::Kill)
- .addImm(ShiftImm);
- }
- }
-
- LivePhysRegs LiveRegs;
- computeAndAddLiveIns(LiveRegs, *loopMBB);
- if (loop1MBB) {
- assert(loop2MBB && "should have 2 loop blocks");
- computeAndAddLiveIns(LiveRegs, *loop1MBB);
- computeAndAddLiveIns(LiveRegs, *loop2MBB);
- }
- computeAndAddLiveIns(LiveRegs, *sinkMBB);
- computeAndAddLiveIns(LiveRegs, *exitMBB);
-
- NMBBI = BB.end();
- I->eraseFromParent();
-
- return true;
-}
-
-bool MipsExpandPseudo::expandAtomicBinOp(MachineBasicBlock &BB,
- MachineBasicBlock::iterator I,
- MachineBasicBlock::iterator &NMBBI,
- unsigned Size) {
- MachineFunction *MF = BB.getParent();
-
- const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
- DebugLoc DL = I->getDebugLoc();
-
- unsigned LL, SC, ZERO, BEQ, SLT, SLTu, OR, MOVN, MOVZ, SELNEZ, SELEQZ;
-
- if (Size == 4) {
- if (STI->inMicroMipsMode()) {
- LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
- SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
- BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
- SLT = Mips::SLT_MM;
- SLTu = Mips::SLTu_MM;
- OR = STI->hasMips32r6() ? Mips::OR_MMR6 : Mips::OR_MM;
- MOVN = Mips::MOVN_I_MM;
- MOVZ = Mips::MOVZ_I_MM;
- SELNEZ = STI->hasMips32r6() ? Mips::SELNEZ_MMR6 : Mips::SELNEZ;
- SELEQZ = STI->hasMips32r6() ? Mips::SELEQZ_MMR6 : Mips::SELEQZ;
- } else {
- LL = STI->hasMips32r6()
- ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
- : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
- SC = STI->hasMips32r6()
- ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
- : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
- BEQ = Mips::BEQ;
- SLT = Mips::SLT;
- SLTu = Mips::SLTu;
- OR = Mips::OR;
- MOVN = Mips::MOVN_I_I;
- MOVZ = Mips::MOVZ_I_I;
- SELNEZ = Mips::SELNEZ;
- SELEQZ = Mips::SELEQZ;
- }
-
- ZERO = Mips::ZERO;
- } else {
- LL = STI->hasMips64r6() ? Mips::LLD_R6 : Mips::LLD;
- SC = STI->hasMips64r6() ? Mips::SCD_R6 : Mips::SCD;
- ZERO = Mips::ZERO_64;
- BEQ = Mips::BEQ64;
- SLT = Mips::SLT64;
- SLTu = Mips::SLTu64;
- OR = Mips::OR64;
- MOVN = Mips::MOVN_I64_I64;
- MOVZ = Mips::MOVZ_I64_I64;
- SELNEZ = Mips::SELNEZ64;
- SELEQZ = Mips::SELEQZ64;
- }
-
- Register OldVal = I->getOperand(0).getReg();
- Register Ptr = I->getOperand(1).getReg();
- Register Incr = I->getOperand(2).getReg();
- Register Scratch = I->getOperand(3).getReg();
-
- unsigned Opcode = 0;
- unsigned AND = 0;
- unsigned NOR = 0;
-
- bool IsOr = false;
- bool IsNand = false;
- bool IsMin = false;
- bool IsMax = false;
- bool IsUnsigned = false;
-
- switch (I->getOpcode()) {
- case Mips::ATOMIC_LOAD_ADD_I32_POSTRA:
- Opcode = Mips::ADDu;
- break;
- case Mips::ATOMIC_LOAD_SUB_I32_POSTRA:
- Opcode = Mips::SUBu;
- break;
- case Mips::ATOMIC_LOAD_AND_I32_POSTRA:
- Opcode = Mips::AND;
- break;
- case Mips::ATOMIC_LOAD_OR_I32_POSTRA:
- Opcode = Mips::OR;
- break;
- case Mips::ATOMIC_LOAD_XOR_I32_POSTRA:
- Opcode = Mips::XOR;
- break;
- case Mips::ATOMIC_LOAD_NAND_I32_POSTRA:
- IsNand = true;
- AND = Mips::AND;
- NOR = Mips::NOR;
- break;
- case Mips::ATOMIC_SWAP_I32_POSTRA:
- IsOr = true;
- break;
- case Mips::ATOMIC_LOAD_ADD_I64_POSTRA:
- Opcode = Mips::DADDu;
- break;
- case Mips::ATOMIC_LOAD_SUB_I64_POSTRA:
- Opcode = Mips::DSUBu;
- break;
- case Mips::ATOMIC_LOAD_AND_I64_POSTRA:
- Opcode = Mips::AND64;
- break;
- case Mips::ATOMIC_LOAD_OR_I64_POSTRA:
- Opcode = Mips::OR64;
- break;
- case Mips::ATOMIC_LOAD_XOR_I64_POSTRA:
- Opcode = Mips::XOR64;
- break;
- case Mips::ATOMIC_LOAD_NAND_I64_POSTRA:
- IsNand = true;
- AND = Mips::AND64;
- NOR = Mips::NOR64;
- break;
- case Mips::ATOMIC_SWAP_I64_POSTRA:
- IsOr = true;
- break;
- case Mips::ATOMIC_LOAD_UMIN_I32_POSTRA:
- case Mips::ATOMIC_LOAD_UMIN_I64_POSTRA:
- IsUnsigned = true;
- [[fallthrough]];
- case Mips::ATOMIC_LOAD_MIN_I32_POSTRA:
- case Mips::ATOMIC_LOAD_MIN_I64_POSTRA:
- IsMin = true;
- break;
- case Mips::ATOMIC_LOAD_UMAX_I32_POSTRA:
- case Mips::ATOMIC_LOAD_UMAX_I64_POSTRA:
- IsUnsigned = true;
- [[fallthrough]];
- case Mips::ATOMIC_LOAD_MAX_I32_POSTRA:
- case Mips::ATOMIC_LOAD_MAX_I64_POSTRA:
- IsMax = true;
- break;
- default:
- llvm_unreachable("Unknown pseudo atomic!");
- }
-
- bool NoMovnInstr = (IsMin || IsMax) && !STI->hasMips4() && !STI->hasMips32();
- const BasicBlock *LLVM_BB = BB.getBasicBlock();
- MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB);
- MachineBasicBlock *loop1MBB = nullptr;
- MachineBasicBlock *loop2MBB = nullptr;
- if (NoMovnInstr) {
- loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB);
- loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB);
- }
- MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
- MachineFunction::iterator It = ++BB.getIterator();
- MF->insert(It, loopMBB);
- if (NoMovnInstr) {
- MF->insert(It, loop1MBB);
- MF->insert(It, loop2MBB);
- }
- MF->insert(It, exitMBB);
-
- exitMBB->splice(exitMBB->begin(), &BB, std::next(I), BB.end());
- exitMBB->transferSuccessorsAndUpdatePHIs(&BB);
-
- BB.addSuccessor(loopMBB, BranchProbability::getOne());
- if (NoMovnInstr) {
- loopMBB->addSuccessor(loop1MBB);
- loopMBB->addSuccessor(loop2MBB);
- } else {
- loopMBB->addSuccessor(exitMBB);
- loopMBB->addSuccessor(loopMBB);
- }
- loopMBB->normalizeSuccProbs();
- if (NoMovnInstr) {
- loop1MBB->addSuccessor(loop2MBB);
- loop2MBB->addSuccessor(loopMBB);
- loop2MBB->addSuccessor(exitMBB);
- }
-
- BuildMI(loopMBB, DL, TII->get(LL), OldVal).addReg(Ptr).addImm(0);
- assert((OldVal != Ptr) && "Clobbered the wrong ptr reg!");
- assert((OldVal != Incr) && "Clobbered the wrong reg!");
- if (IsMin || IsMax) {
- // Remove trailing kill/dead register operands added by
- // MachineInstr::addRegisterKilled. These are super-register markers that
- // must correspond to one of the physical registers in operands 1-4.
- // The kill/dead markers may also appear on preceding subregs.
- const TargetRegisterInfo *TRI = STI->getRegisterInfo();
- while (I->getNumOperands() > 5) {
- auto &Op = I->getOperand(I->getNumOperands() - 1);
- // Check if this register overlaps with any physical register in
- // operands 1-4 that has kill/dead marker (i.e., it's a super-register
- // marker for subregs).
- bool HasOverlapWithKill = false;
- for (unsigned i = 1; i <= 4; ++i) {
- auto &RefOp = I->getOperand(i);
- if (RefOp.isReg() && RefOp.getReg().isPhysical() &&
- TRI->regsOverlap(Op.getReg(), RefOp.getReg()) &&
- (RefOp.isKill() || RefOp.isDead())) {
- HasOverlapWithKill = true;
- break;
- }
- }
- // Remove if HasOverlapWithKill is true or Op has kill/dead marker.
- bool HasKillOrDead = Op.isReg() && Op.getReg().isPhysical() &&
- (Op.isKill() || Op.isDead());
- if (!HasOverlapWithKill && !HasKillOrDead)
- break;
- I->removeOperand(I->getNumOperands() - 1);
- }
-
- assert(I->getNumOperands() == 5 &&
- "Atomics min|max|umin|umax use an additional register");
- MCRegister Scratch2 = I->getOperand(4).getReg().asMCReg();
-
- // On Mips64 result of slt is GPR32.
- MCRegister Scratch2_32 =
- (Size == 8) ? STI->getRegisterInfo()->getSubReg(Scratch2, Mips::sub_32)
- : Scratch2;
-
- unsigned SLTScratch2 = IsUnsigned ? SLTu : SLT;
- unsigned SELIncr = IsMax ? SELNEZ : SELEQZ;
- unsigned SELOldVal = IsMax ? SELEQZ : SELNEZ;
- unsigned MOVIncr = IsMax ? MOVN : MOVZ;
-
- // unsigned: sltu Scratch2, oldVal, Incr
- // signed: slt Scratch2, oldVal, Incr
- BuildMI(loopMBB, DL, TII->get(SLTScratch2), Scratch2_32)
- .addReg(OldVal)
.addReg(Incr);
-
- if (STI->hasMips64r6() || STI->hasMips32r6()) {
- // max: seleqz Scratch, OldVal, Scratch2
- // selnez Scratch2, Incr, Scratch2
- // or Scratch, Scratch, Scratch2
- // min: selnez Scratch, OldVal, Scratch2
- // seleqz Scratch2, Incr, Scratch2
- // or Scratch, Scratch, Scratch2
- BuildMI(loopMBB, DL, TII->get(SELOldVal), Scratch)
- .addReg(OldVal)
- .addReg(Scratch2);
- BuildMI(loopMBB, DL, TII->get(SELIncr), Scratch2)
- .addReg(Incr)
- .addReg(Scratch2);
- BuildMI(loopMBB, DL, TII->get(OR), Scratch)
+ if (BinOp == AtomicRMWInst::Nand)
+ BuildMI(LoopMBB, DL, TII->get(Width == 64 ? Mips::NOR64 : Mips::NOR),
+ Scratch)
.addReg(Scratch)
- .addReg(Scratch2);
- } else if (STI->hasMips4() || STI->hasMips32()) {
- // max: move Scratch, OldVal
- // movn Scratch, Incr, Scratch2, Scratch
- // min: move Scratch, OldVal
- // movz Scratch, Incr, Scratch2, Scratch
- BuildMI(loopMBB, DL, TII->get(OR), Scratch)
- .addReg(OldVal)
- .addReg(ZERO);
- BuildMI(loopMBB, DL, TII->get(MOVIncr), Scratch)
- .addReg(Incr)
- .addReg(Scratch2)
- .addReg(Scratch);
- } else {
- // if min:
- // loopMBB: move Scratch, OldVal
- // beq Scratch2_32, 0, loop1MBB
- // j loop2MBB
- // loop1MBB: move Scratch, Incr
- // loop2MBB: sc $2, 0($4)
- // beqz $2, $BB0_1
- // nop
- //
- // if max:
- // loopMBB: move Scratch, Incr
- // beq Scratch2_32, 0, loop1MBB
- // j loop2MBB
- // loop1MBB: move Scratch, OldVal
- // loop2MBB: sc $2, 0($4)
- // beqz $2, $BB0_1
- // nop
- if (IsMin) {
- BuildMI(loopMBB, DL, TII->get(OR), Scratch).addReg(OldVal).addReg(ZERO);
- BuildMI(loop1MBB, DL, TII->get(OR), Scratch).addReg(Incr).addReg(ZERO);
- } else {
- BuildMI(loopMBB, DL, TII->get(OR), Scratch).addReg(Incr).addReg(ZERO);
- BuildMI(loop1MBB, DL, TII->get(OR), Scratch)
- .addReg(OldVal)
- .addReg(ZERO);
- }
- BuildMI(loopMBB, DL, TII->get(BEQ))
- .addReg(Scratch2_32)
- .addReg(ZERO)
- .addMBB(loop1MBB);
- BuildMI(loopMBB, DL, TII->get(Mips::J)).addMBB(loop2MBB);
- }
-
- } else if (Opcode) {
- BuildMI(loopMBB, DL, TII->get(Opcode), Scratch).addReg(OldVal).addReg(Incr);
- } else if (IsNand) {
- assert(AND && NOR &&
- "Unknown nand instruction for atomic pseudo expansion");
- BuildMI(loopMBB, DL, TII->get(AND), Scratch).addReg(OldVal).addReg(Incr);
- BuildMI(loopMBB, DL, TII->get(NOR), Scratch).addReg(ZERO).addReg(Scratch);
- } else {
- assert(IsOr && OR && "Unknown instruction for atomic pseudo expansion!");
- (void)IsOr;
- BuildMI(loopMBB, DL, TII->get(OR), Scratch).addReg(Incr).addReg(ZERO);
+ .addReg(Opc.Zero);
}
- if (NoMovnInstr) {
- BuildMI(loop2MBB, DL, TII->get(SC), Scratch)
- .addReg(Scratch)
- .addReg(Ptr)
- .addImm(0);
- BuildMI(loop2MBB, DL, TII->get(BEQ))
- .addReg(Scratch)
- .addReg(ZERO)
- .addMBB(loopMBB);
- } else {
- BuildMI(loopMBB, DL, TII->get(SC), Scratch)
- .addReg(Scratch)
- .addReg(Ptr)
- .addImm(0);
- BuildMI(loopMBB, DL, TII->get(BEQ))
- .addReg(Scratch)
- .addReg(ZERO)
- .addMBB(loopMBB);
- }
+ if (IsMasked)
+ insertMaskedMerge(TII, StoreMBB, DL, Scratch, Dest, NewVal, Mask);
+ BuildMI(StoreMBB, DL, TII->get(Opc.SC), Scratch)
+ .addReg(Scratch)
+ .addReg(Ptr)
+ .addImm(0);
+ BuildMI(StoreMBB, DL, TII->get(Opc.BEQ))
+ .addReg(Scratch)
+ .addReg(Opc.Zero)
+ .addMBB(LoopMBB);
- NMBBI = BB.end();
- I->eraseFromParent();
+ NextMBBI = MBB.end();
+ MI.eraseFromParent();
LivePhysRegs LiveRegs;
- computeAndAddLiveIns(LiveRegs, *loopMBB);
- if (loop1MBB) {
- assert(loop2MBB && "should have 2 loop blocks");
- computeAndAddLiveIns(LiveRegs, *loop1MBB);
- computeAndAddLiveIns(LiveRegs, *loop2MBB);
+ computeAndAddLiveIns(LiveRegs, *LoopMBB);
+ if (NeedsBranch) {
+ computeAndAddLiveIns(LiveRegs, *UpdateMBB);
+ computeAndAddLiveIns(LiveRegs, *StoreMBB);
}
- computeAndAddLiveIns(LiveRegs, *exitMBB);
-
+ computeAndAddLiveIns(LiveRegs, *DoneMBB);
return true;
}
bool MipsExpandPseudo::expandMI(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
- MachineBasicBlock::iterator &NMBB) {
-
- bool Modified = false;
-
+ MachineBasicBlock::iterator &NextMBBI) {
switch (MBBI->getOpcode()) {
- case Mips::ATOMIC_CMP_SWAP_I32_POSTRA:
- case Mips::ATOMIC_CMP_SWAP_I64_POSTRA:
- return expandAtomicCmpSwap(MBB, MBBI, NMBB);
- case Mips::ATOMIC_CMP_SWAP_I8_POSTRA:
- case Mips::ATOMIC_CMP_SWAP_I16_POSTRA:
- return expandAtomicCmpSwapSubword(MBB, MBBI, NMBB);
- case Mips::ATOMIC_SWAP_I8_POSTRA:
- case Mips::ATOMIC_SWAP_I16_POSTRA:
- case Mips::ATOMIC_LOAD_NAND_I8_POSTRA:
- case Mips::ATOMIC_LOAD_NAND_I16_POSTRA:
- case Mips::ATOMIC_LOAD_ADD_I8_POSTRA:
- case Mips::ATOMIC_LOAD_ADD_I16_POSTRA:
- case Mips::ATOMIC_LOAD_SUB_I8_POSTRA:
- case Mips::ATOMIC_LOAD_SUB_I16_POSTRA:
- case Mips::ATOMIC_LOAD_AND_I8_POSTRA:
- case Mips::ATOMIC_LOAD_AND_I16_POSTRA:
- case Mips::ATOMIC_LOAD_OR_I8_POSTRA:
- case Mips::ATOMIC_LOAD_OR_I16_POSTRA:
- case Mips::ATOMIC_LOAD_XOR_I8_POSTRA:
- case Mips::ATOMIC_LOAD_XOR_I16_POSTRA:
- case Mips::ATOMIC_LOAD_MIN_I8_POSTRA:
- case Mips::ATOMIC_LOAD_MIN_I16_POSTRA:
- case Mips::ATOMIC_LOAD_MAX_I8_POSTRA:
- case Mips::ATOMIC_LOAD_MAX_I16_POSTRA:
- case Mips::ATOMIC_LOAD_UMIN_I8_POSTRA:
- case Mips::ATOMIC_LOAD_UMIN_I16_POSTRA:
- case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA:
- case Mips::ATOMIC_LOAD_UMAX_I16_POSTRA:
- return expandAtomicBinOpSubword(MBB, MBBI, NMBB);
- case Mips::ATOMIC_LOAD_ADD_I32_POSTRA:
- case Mips::ATOMIC_LOAD_SUB_I32_POSTRA:
- case Mips::ATOMIC_LOAD_AND_I32_POSTRA:
- case Mips::ATOMIC_LOAD_OR_I32_POSTRA:
- case Mips::ATOMIC_LOAD_XOR_I32_POSTRA:
- case Mips::ATOMIC_LOAD_NAND_I32_POSTRA:
- case Mips::ATOMIC_SWAP_I32_POSTRA:
- case Mips::ATOMIC_LOAD_MIN_I32_POSTRA:
- case Mips::ATOMIC_LOAD_MAX_I32_POSTRA:
- case Mips::ATOMIC_LOAD_UMIN_I32_POSTRA:
- case Mips::ATOMIC_LOAD_UMAX_I32_POSTRA:
- return expandAtomicBinOp(MBB, MBBI, NMBB, 4);
- case Mips::ATOMIC_LOAD_ADD_I64_POSTRA:
- case Mips::ATOMIC_LOAD_SUB_I64_POSTRA:
- case Mips::ATOMIC_LOAD_AND_I64_POSTRA:
- case Mips::ATOMIC_LOAD_OR_I64_POSTRA:
- case Mips::ATOMIC_LOAD_XOR_I64_POSTRA:
- case Mips::ATOMIC_LOAD_NAND_I64_POSTRA:
- case Mips::ATOMIC_SWAP_I64_POSTRA:
- case Mips::ATOMIC_LOAD_MIN_I64_POSTRA:
- case Mips::ATOMIC_LOAD_MAX_I64_POSTRA:
- case Mips::ATOMIC_LOAD_UMIN_I64_POSTRA:
- case Mips::ATOMIC_LOAD_UMAX_I64_POSTRA:
- return expandAtomicBinOp(MBB, MBBI, NMBB, 8);
default:
- return Modified;
+ return false;
+ case Mips::ATOMIC_CMP_SWAP_I32:
+ return expandAtomicCmpSwap(MBB, MBBI, false, 32, NextMBBI);
+ case Mips::ATOMIC_SWAP_I32:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::Xchg, false, 32, NextMBBI);
+ case Mips::ATOMIC_LOAD_ADD_I32:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::Add, false, 32, NextMBBI);
+ case Mips::ATOMIC_LOAD_SUB_I32:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::Sub, false, 32, NextMBBI);
+ case Mips::ATOMIC_LOAD_AND_I32:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::And, false, 32, NextMBBI);
+ case Mips::ATOMIC_LOAD_OR_I32:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::Or, false, 32, NextMBBI);
+ case Mips::ATOMIC_LOAD_XOR_I32:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::Xor, false, 32, NextMBBI);
+ case Mips::ATOMIC_LOAD_NAND_I32:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::Nand, false, 32, NextMBBI);
+ case Mips::ATOMIC_LOAD_MIN_I32:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::Min, false, 32, NextMBBI);
+ case Mips::ATOMIC_LOAD_MAX_I32:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::Max, false, 32, NextMBBI);
+ case Mips::ATOMIC_LOAD_UMIN_I32:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::UMin, false, 32, NextMBBI);
+ case Mips::ATOMIC_LOAD_UMAX_I32:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::UMax, false, 32, NextMBBI);
+ case Mips::ATOMIC_CMP_SWAP_I64:
+ return expandAtomicCmpSwap(MBB, MBBI, false, 64, NextMBBI);
+ case Mips::ATOMIC_SWAP_I64:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::Xchg, false, 64, NextMBBI);
+ case Mips::ATOMIC_LOAD_ADD_I64:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::Add, false, 64, NextMBBI);
+ case Mips::ATOMIC_LOAD_SUB_I64:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::Sub, false, 64, NextMBBI);
+ case Mips::ATOMIC_LOAD_AND_I64:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::And, false, 64, NextMBBI);
+ case Mips::ATOMIC_LOAD_OR_I64:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::Or, false, 64, NextMBBI);
+ case Mips::ATOMIC_LOAD_XOR_I64:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::Xor, false, 64, NextMBBI);
+ case Mips::ATOMIC_LOAD_NAND_I64:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::Nand, false, 64, NextMBBI);
+ case Mips::ATOMIC_LOAD_MIN_I64:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::Min, false, 64, NextMBBI);
+ case Mips::ATOMIC_LOAD_MAX_I64:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::Max, false, 64, NextMBBI);
+ case Mips::ATOMIC_LOAD_UMIN_I64:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::UMin, false, 64, NextMBBI);
+ case Mips::ATOMIC_LOAD_UMAX_I64:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::UMax, false, 64, NextMBBI);
+ case Mips::ATOMIC_CMP_SWAP_MASKED:
+ return expandAtomicCmpSwap(MBB, MBBI, true, 32, NextMBBI);
+ case Mips::ATOMIC_SWAP_MASKED:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::Xchg, true, 32, NextMBBI);
+ case Mips::ATOMIC_LOAD_ADD_MASKED:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::Add, true, 32, NextMBBI);
+ case Mips::ATOMIC_LOAD_SUB_MASKED:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::Sub, true, 32, NextMBBI);
+ case Mips::ATOMIC_LOAD_NAND_MASKED:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::Nand, true, 32, NextMBBI);
+ case Mips::ATOMIC_LOAD_MIN_MASKED:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::Min, true, 32, NextMBBI);
+ case Mips::ATOMIC_LOAD_MAX_MASKED:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::Max, true, 32, NextMBBI);
+ case Mips::ATOMIC_LOAD_UMIN_MASKED:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::UMin, true, 32, NextMBBI);
+ case Mips::ATOMIC_LOAD_UMAX_MASKED:
+ return expandAtomicRMW(MBB, MBBI, AtomicRMWInst::UMax, true, 32, NextMBBI);
}
}
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index a5f3cda3bc8a30..dba4b6a44335e9 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -53,6 +53,8 @@
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicsMips.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
@@ -422,6 +424,10 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
ISD::OR, ISD::ADD, ISD::SUB, ISD::AssertZext, ISD::SHL,
ISD::SIGN_EXTEND});
+ // MIPS16 uses libcalls, which support byte and halfword cmpxchg directly.
+ if (!Subtarget.inMips16Mode())
+ setMinCmpXchgSizeInBits(32);
+
// R5900 has no LL/SC instructions for atomic operations
if (Subtarget.isR5900())
setMaxAtomicSizeInBitsSupported(0);
@@ -1357,120 +1363,120 @@ insertDivByZeroTrap(MachineInstr &MI, MachineBasicBlock &MBB,
return &MBB;
}
+void MipsTargetLowering::getTgtMemIntrinsic(
+ SmallVectorImpl<IntrinsicInfo> &Infos, const CallBase &I,
+ MachineFunction &MF, unsigned Intrinsic) const {
+ switch (Intrinsic) {
+ default:
+ return;
+ case Intrinsic::mips_masked_atomicrmw_xchg:
+ case Intrinsic::mips_masked_atomicrmw_add:
+ case Intrinsic::mips_masked_atomicrmw_sub:
+ case Intrinsic::mips_masked_atomicrmw_nand:
+ case Intrinsic::mips_masked_atomicrmw_min:
+ case Intrinsic::mips_masked_atomicrmw_max:
+ case Intrinsic::mips_masked_atomicrmw_umin:
+ case Intrinsic::mips_masked_atomicrmw_umax:
+ case Intrinsic::mips_masked_cmpxchg:
+ IntrinsicInfo Info;
+ Info.opc = ISD::INTRINSIC_W_CHAIN;
+ Info.memVT = MVT::i32;
+ Info.ptrVal = I.getArgOperand(0);
+ Info.offset = 0;
+ Info.align = Align(4);
+ Info.flags = MachineMemOperand::MOLoad | MachineMemOperand::MOStore |
+ MachineMemOperand::MOVolatile;
+ Infos.push_back(Info);
+ return;
+ }
+}
+
+TargetLowering::AtomicExpansionKind
+MipsTargetLowering::shouldExpandAtomicRMWInIR(const AtomicRMWInst *AI) const {
+ if (AI->isFloatingPointOperation() || AI->getType()->isVectorTy() ||
+ AI->getOperation() == AtomicRMWInst::UIncWrap ||
+ AI->getOperation() == AtomicRMWInst::UDecWrap ||
+ AI->getOperation() == AtomicRMWInst::USubCond ||
+ AI->getOperation() == AtomicRMWInst::USubSat)
+ return AtomicExpansionKind::CmpXChg;
+
+ if (Subtarget.inMips16Mode())
+ return AtomicExpansionKind::None;
+
+ unsigned Size = AI->getType()->getPrimitiveSizeInBits();
+ if (Size == 8 || Size == 16)
+ return AtomicExpansionKind::MaskedIntrinsic;
+ return AtomicExpansionKind::None;
+}
+
+TargetLowering::AtomicExpansionKind
+MipsTargetLowering::shouldExpandAtomicCmpXchgInIR(
+ const AtomicCmpXchgInst *CI) const {
+ if (Subtarget.inMips16Mode())
+ return AtomicExpansionKind::None;
+
+ unsigned Size = CI->getCompareOperand()->getType()->getPrimitiveSizeInBits();
+ if (Size == 8 || Size == 16)
+ return AtomicExpansionKind::MaskedIntrinsic;
+ return AtomicExpansionKind::None;
+}
+
+static Intrinsic::ID
+getIntrinsicForMaskedAtomicRMWBinOp(AtomicRMWInst::BinOp BinOp) {
+ switch (BinOp) {
+ default:
+ llvm_unreachable("Unexpected masked atomicrmw operation");
+ case AtomicRMWInst::Xchg:
+ return Intrinsic::mips_masked_atomicrmw_xchg;
+ case AtomicRMWInst::Add:
+ return Intrinsic::mips_masked_atomicrmw_add;
+ case AtomicRMWInst::Sub:
+ return Intrinsic::mips_masked_atomicrmw_sub;
+ case AtomicRMWInst::Nand:
+ return Intrinsic::mips_masked_atomicrmw_nand;
+ case AtomicRMWInst::Min:
+ return Intrinsic::mips_masked_atomicrmw_min;
+ case AtomicRMWInst::Max:
+ return Intrinsic::mips_masked_atomicrmw_max;
+ case AtomicRMWInst::UMin:
+ return Intrinsic::mips_masked_atomicrmw_umin;
+ case AtomicRMWInst::UMax:
+ return Intrinsic::mips_masked_atomicrmw_umax;
+ }
+}
+
+Value *MipsTargetLowering::emitMaskedAtomicRMWIntrinsic(
+ IRBuilderBase &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr,
+ Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const {
+ SmallVector<Value *, 4> Args = {AlignedAddr, Incr, Mask};
+ if (AI->getOperation() == AtomicRMWInst::Min ||
+ AI->getOperation() == AtomicRMWInst::Max) {
+ // Sign extend the loaded subword without shifting it out of position.
+ unsigned Width = AI->getType()->getIntegerBitWidth();
+ Args.push_back(Builder.CreateSub(Builder.getInt32(32 - Width), ShiftAmt));
+ }
+ return Builder.CreateIntrinsic(
+ getIntrinsicForMaskedAtomicRMWBinOp(AI->getOperation()),
+ {AlignedAddr->getType()}, Args);
+}
+
+Value *MipsTargetLowering::emitMaskedAtomicCmpXchgIntrinsic(
+ IRBuilderBase &Builder, AtomicCmpXchgInst *CI, Value *AlignedAddr,
+ Value *CmpVal, Value *NewVal, Value *Mask, AtomicOrdering Ord) const {
+ emitLeadingFence(Builder, CI, Ord);
+ Value *Result = Builder.CreateIntrinsic(Intrinsic::mips_masked_cmpxchg,
+ {AlignedAddr->getType()},
+ {AlignedAddr, CmpVal, NewVal, Mask});
+ emitTrailingFence(Builder, CI, Ord);
+ return Result;
+}
+
MachineBasicBlock *
MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
MachineBasicBlock *BB) const {
switch (MI.getOpcode()) {
default:
llvm_unreachable("Unexpected instr type to insert");
- case Mips::ATOMIC_LOAD_ADD_I8:
- return emitAtomicBinaryPartword(MI, BB, 1);
- case Mips::ATOMIC_LOAD_ADD_I16:
- return emitAtomicBinaryPartword(MI, BB, 2);
- case Mips::ATOMIC_LOAD_ADD_I32:
- return emitAtomicBinary(MI, BB);
- case Mips::ATOMIC_LOAD_ADD_I64:
- return emitAtomicBinary(MI, BB);
-
- case Mips::ATOMIC_LOAD_AND_I8:
- return emitAtomicBinaryPartword(MI, BB, 1);
- case Mips::ATOMIC_LOAD_AND_I16:
- return emitAtomicBinaryPartword(MI, BB, 2);
- case Mips::ATOMIC_LOAD_AND_I32:
- return emitAtomicBinary(MI, BB);
- case Mips::ATOMIC_LOAD_AND_I64:
- return emitAtomicBinary(MI, BB);
-
- case Mips::ATOMIC_LOAD_OR_I8:
- return emitAtomicBinaryPartword(MI, BB, 1);
- case Mips::ATOMIC_LOAD_OR_I16:
- return emitAtomicBinaryPartword(MI, BB, 2);
- case Mips::ATOMIC_LOAD_OR_I32:
- return emitAtomicBinary(MI, BB);
- case Mips::ATOMIC_LOAD_OR_I64:
- return emitAtomicBinary(MI, BB);
-
- case Mips::ATOMIC_LOAD_XOR_I8:
- return emitAtomicBinaryPartword(MI, BB, 1);
- case Mips::ATOMIC_LOAD_XOR_I16:
- return emitAtomicBinaryPartword(MI, BB, 2);
- case Mips::ATOMIC_LOAD_XOR_I32:
- return emitAtomicBinary(MI, BB);
- case Mips::ATOMIC_LOAD_XOR_I64:
- return emitAtomicBinary(MI, BB);
-
- case Mips::ATOMIC_LOAD_NAND_I8:
- return emitAtomicBinaryPartword(MI, BB, 1);
- case Mips::ATOMIC_LOAD_NAND_I16:
- return emitAtomicBinaryPartword(MI, BB, 2);
- case Mips::ATOMIC_LOAD_NAND_I32:
- return emitAtomicBinary(MI, BB);
- case Mips::ATOMIC_LOAD_NAND_I64:
- return emitAtomicBinary(MI, BB);
-
- case Mips::ATOMIC_LOAD_SUB_I8:
- return emitAtomicBinaryPartword(MI, BB, 1);
- case Mips::ATOMIC_LOAD_SUB_I16:
- return emitAtomicBinaryPartword(MI, BB, 2);
- case Mips::ATOMIC_LOAD_SUB_I32:
- return emitAtomicBinary(MI, BB);
- case Mips::ATOMIC_LOAD_SUB_I64:
- return emitAtomicBinary(MI, BB);
-
- case Mips::ATOMIC_SWAP_I8:
- return emitAtomicBinaryPartword(MI, BB, 1);
- case Mips::ATOMIC_SWAP_I16:
- return emitAtomicBinaryPartword(MI, BB, 2);
- case Mips::ATOMIC_SWAP_I32:
- return emitAtomicBinary(MI, BB);
- case Mips::ATOMIC_SWAP_I64:
- return emitAtomicBinary(MI, BB);
-
- case Mips::ATOMIC_CMP_SWAP_I8:
- return emitAtomicCmpSwapPartword(MI, BB, 1);
- case Mips::ATOMIC_CMP_SWAP_I16:
- return emitAtomicCmpSwapPartword(MI, BB, 2);
- case Mips::ATOMIC_CMP_SWAP_I32:
- return emitAtomicCmpSwap(MI, BB);
- case Mips::ATOMIC_CMP_SWAP_I64:
- return emitAtomicCmpSwap(MI, BB);
-
- case Mips::ATOMIC_LOAD_MIN_I8:
- return emitAtomicBinaryPartword(MI, BB, 1);
- case Mips::ATOMIC_LOAD_MIN_I16:
- return emitAtomicBinaryPartword(MI, BB, 2);
- case Mips::ATOMIC_LOAD_MIN_I32:
- return emitAtomicBinary(MI, BB);
- case Mips::ATOMIC_LOAD_MIN_I64:
- return emitAtomicBinary(MI, BB);
-
- case Mips::ATOMIC_LOAD_MAX_I8:
- return emitAtomicBinaryPartword(MI, BB, 1);
- case Mips::ATOMIC_LOAD_MAX_I16:
- return emitAtomicBinaryPartword(MI, BB, 2);
- case Mips::ATOMIC_LOAD_MAX_I32:
- return emitAtomicBinary(MI, BB);
- case Mips::ATOMIC_LOAD_MAX_I64:
- return emitAtomicBinary(MI, BB);
-
- case Mips::ATOMIC_LOAD_UMIN_I8:
- return emitAtomicBinaryPartword(MI, BB, 1);
- case Mips::ATOMIC_LOAD_UMIN_I16:
- return emitAtomicBinaryPartword(MI, BB, 2);
- case Mips::ATOMIC_LOAD_UMIN_I32:
- return emitAtomicBinary(MI, BB);
- case Mips::ATOMIC_LOAD_UMIN_I64:
- return emitAtomicBinary(MI, BB);
-
- case Mips::ATOMIC_LOAD_UMAX_I8:
- return emitAtomicBinaryPartword(MI, BB, 1);
- case Mips::ATOMIC_LOAD_UMAX_I16:
- return emitAtomicBinaryPartword(MI, BB, 2);
- case Mips::ATOMIC_LOAD_UMAX_I32:
- return emitAtomicBinary(MI, BB);
- case Mips::ATOMIC_LOAD_UMAX_I64:
- return emitAtomicBinary(MI, BB);
-
case Mips::PseudoSDIV:
case Mips::PseudoUDIV:
case Mips::DIV:
@@ -1534,569 +1540,6 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
}
}
-// This function also handles Mips::ATOMIC_SWAP_I32 (when BinOpcode == 0), and
-// Mips::ATOMIC_LOAD_NAND_I32 (when Nand == true)
-MachineBasicBlock *
-MipsTargetLowering::emitAtomicBinary(MachineInstr &MI,
- MachineBasicBlock *BB) const {
-
- MachineFunction *MF = BB->getParent();
- MachineRegisterInfo &RegInfo = MF->getRegInfo();
- const TargetInstrInfo *TII = Subtarget.getInstrInfo();
- DebugLoc DL = MI.getDebugLoc();
-
- unsigned AtomicOp;
- bool NeedsAdditionalReg = false;
- switch (MI.getOpcode()) {
- case Mips::ATOMIC_LOAD_ADD_I32:
- AtomicOp = Mips::ATOMIC_LOAD_ADD_I32_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_SUB_I32:
- AtomicOp = Mips::ATOMIC_LOAD_SUB_I32_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_AND_I32:
- AtomicOp = Mips::ATOMIC_LOAD_AND_I32_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_OR_I32:
- AtomicOp = Mips::ATOMIC_LOAD_OR_I32_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_XOR_I32:
- AtomicOp = Mips::ATOMIC_LOAD_XOR_I32_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_NAND_I32:
- AtomicOp = Mips::ATOMIC_LOAD_NAND_I32_POSTRA;
- break;
- case Mips::ATOMIC_SWAP_I32:
- AtomicOp = Mips::ATOMIC_SWAP_I32_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_ADD_I64:
- AtomicOp = Mips::ATOMIC_LOAD_ADD_I64_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_SUB_I64:
- AtomicOp = Mips::ATOMIC_LOAD_SUB_I64_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_AND_I64:
- AtomicOp = Mips::ATOMIC_LOAD_AND_I64_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_OR_I64:
- AtomicOp = Mips::ATOMIC_LOAD_OR_I64_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_XOR_I64:
- AtomicOp = Mips::ATOMIC_LOAD_XOR_I64_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_NAND_I64:
- AtomicOp = Mips::ATOMIC_LOAD_NAND_I64_POSTRA;
- break;
- case Mips::ATOMIC_SWAP_I64:
- AtomicOp = Mips::ATOMIC_SWAP_I64_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_MIN_I32:
- AtomicOp = Mips::ATOMIC_LOAD_MIN_I32_POSTRA;
- NeedsAdditionalReg = true;
- break;
- case Mips::ATOMIC_LOAD_MAX_I32:
- AtomicOp = Mips::ATOMIC_LOAD_MAX_I32_POSTRA;
- NeedsAdditionalReg = true;
- break;
- case Mips::ATOMIC_LOAD_UMIN_I32:
- AtomicOp = Mips::ATOMIC_LOAD_UMIN_I32_POSTRA;
- NeedsAdditionalReg = true;
- break;
- case Mips::ATOMIC_LOAD_UMAX_I32:
- AtomicOp = Mips::ATOMIC_LOAD_UMAX_I32_POSTRA;
- NeedsAdditionalReg = true;
- break;
- case Mips::ATOMIC_LOAD_MIN_I64:
- AtomicOp = Mips::ATOMIC_LOAD_MIN_I64_POSTRA;
- NeedsAdditionalReg = true;
- break;
- case Mips::ATOMIC_LOAD_MAX_I64:
- AtomicOp = Mips::ATOMIC_LOAD_MAX_I64_POSTRA;
- NeedsAdditionalReg = true;
- break;
- case Mips::ATOMIC_LOAD_UMIN_I64:
- AtomicOp = Mips::ATOMIC_LOAD_UMIN_I64_POSTRA;
- NeedsAdditionalReg = true;
- break;
- case Mips::ATOMIC_LOAD_UMAX_I64:
- AtomicOp = Mips::ATOMIC_LOAD_UMAX_I64_POSTRA;
- NeedsAdditionalReg = true;
- break;
- default:
- llvm_unreachable("Unknown pseudo atomic for replacement!");
- }
-
- Register OldVal = MI.getOperand(0).getReg();
- Register Ptr = MI.getOperand(1).getReg();
- Register Incr = MI.getOperand(2).getReg();
- Register Scratch = RegInfo.createVirtualRegister(RegInfo.getRegClass(OldVal));
-
- MachineBasicBlock::iterator II(MI);
-
- // The scratch registers here with the EarlyClobber | Define | Implicit
- // flags is used to persuade the register allocator and the machine
- // verifier to accept the usage of this register. This has to be a real
- // register which has an UNDEF value but is dead after the instruction which
- // is unique among the registers chosen for the instruction.
-
- // The EarlyClobber flag has the semantic properties that the operand it is
- // attached to is clobbered before the rest of the inputs are read. Hence it
- // must be unique among the operands to the instruction.
- // The Define flag is needed to coerce the machine verifier that an Undef
- // value isn't a problem.
- // The Dead flag is needed as the value in scratch isn't used by any other
- // instruction. Kill isn't used as Dead is more precise.
- // The implicit flag is here due to the interaction between the other flags
- // and the machine verifier.
-
- // For correctness purpose, a new pseudo is introduced here. We need this
- // new pseudo, so that FastRegisterAllocator does not see an ll/sc sequence
- // that is spread over >1 basic blocks. A register allocator which
- // introduces (or any codegen infact) a store, can violate the expectations
- // of the hardware.
- //
- // An atomic read-modify-write sequence starts with a linked load
- // instruction and ends with a store conditional instruction. The atomic
- // read-modify-write sequence fails if any of the following conditions
- // occur between the execution of ll and sc:
- // * A coherent store is completed by another process or coherent I/O
- // module into the block of synchronizable physical memory containing
- // the word. The size and alignment of the block is
- // implementation-dependent.
- // * A coherent store is executed between an LL and SC sequence on the
- // same processor to the block of synchornizable physical memory
- // containing the word.
- //
-
- Register PtrCopy = RegInfo.createVirtualRegister(RegInfo.getRegClass(Ptr));
- Register IncrCopy = RegInfo.createVirtualRegister(RegInfo.getRegClass(Incr));
-
- BuildMI(*BB, II, DL, TII->get(Mips::COPY), IncrCopy).addReg(Incr);
- BuildMI(*BB, II, DL, TII->get(Mips::COPY), PtrCopy).addReg(Ptr);
-
- MachineInstrBuilder MIB =
- BuildMI(*BB, II, DL, TII->get(AtomicOp))
- .addReg(OldVal, RegState::Define | RegState::EarlyClobber)
- .addReg(PtrCopy)
- .addReg(IncrCopy)
- .addReg(Scratch, RegState::Define | RegState::EarlyClobber |
- RegState::Implicit | RegState::Dead);
- if (NeedsAdditionalReg) {
- Register Scratch2 =
- RegInfo.createVirtualRegister(RegInfo.getRegClass(OldVal));
- MIB.addReg(Scratch2, RegState::Define | RegState::EarlyClobber |
- RegState::Implicit | RegState::Dead);
- }
-
- MI.eraseFromParent();
-
- return BB;
-}
-
-MachineBasicBlock *MipsTargetLowering::emitSignExtendToI32InReg(
- MachineInstr &MI, MachineBasicBlock *BB, unsigned Size, unsigned DstReg,
- unsigned SrcReg) const {
- const TargetInstrInfo *TII = Subtarget.getInstrInfo();
- const DebugLoc &DL = MI.getDebugLoc();
-
- if (Subtarget.hasMips32r2() && Size == 1) {
- BuildMI(BB, DL, TII->get(Mips::SEB), DstReg).addReg(SrcReg);
- return BB;
- }
-
- if (Subtarget.hasMips32r2() && Size == 2) {
- BuildMI(BB, DL, TII->get(Mips::SEH), DstReg).addReg(SrcReg);
- return BB;
- }
-
- MachineFunction *MF = BB->getParent();
- MachineRegisterInfo &RegInfo = MF->getRegInfo();
- const TargetRegisterClass *RC = getRegClassFor(MVT::i32);
- Register ScrReg = RegInfo.createVirtualRegister(RC);
-
- assert(Size < 32);
- int64_t ShiftImm = 32 - (Size * 8);
-
- BuildMI(BB, DL, TII->get(Mips::SLL), ScrReg).addReg(SrcReg).addImm(ShiftImm);
- BuildMI(BB, DL, TII->get(Mips::SRA), DstReg).addReg(ScrReg).addImm(ShiftImm);
-
- return BB;
-}
-
-MachineBasicBlock *MipsTargetLowering::emitAtomicBinaryPartword(
- MachineInstr &MI, MachineBasicBlock *BB, unsigned Size) const {
- assert((Size == 1 || Size == 2) &&
- "Unsupported size for EmitAtomicBinaryPartial.");
-
- MachineFunction *MF = BB->getParent();
- MachineRegisterInfo &RegInfo = MF->getRegInfo();
- const TargetRegisterClass *RC = getRegClassFor(MVT::i32);
- const bool ArePtrs64bit = ABI.ArePtrs64bit();
- const TargetRegisterClass *RCp =
- getRegClassFor(ArePtrs64bit ? MVT::i64 : MVT::i32);
- const TargetInstrInfo *TII = Subtarget.getInstrInfo();
- DebugLoc DL = MI.getDebugLoc();
-
- Register Dest = MI.getOperand(0).getReg();
- Register Ptr = MI.getOperand(1).getReg();
- Register Incr = MI.getOperand(2).getReg();
-
- Register AlignedAddr = RegInfo.createVirtualRegister(RCp);
- Register ShiftAmt = RegInfo.createVirtualRegister(RC);
- Register Mask = RegInfo.createVirtualRegister(RC);
- Register Mask2 = RegInfo.createVirtualRegister(RC);
- Register Incr2 = RegInfo.createVirtualRegister(RC);
- Register MaskLSB2 = RegInfo.createVirtualRegister(RCp);
- Register PtrLSB2 = RegInfo.createVirtualRegister(RC);
- Register MaskUpper = RegInfo.createVirtualRegister(RC);
- Register Scratch = RegInfo.createVirtualRegister(RC);
- Register Scratch2 = RegInfo.createVirtualRegister(RC);
- Register Scratch3 = RegInfo.createVirtualRegister(RC);
-
- unsigned AtomicOp = 0;
- bool NeedsAdditionalReg = false;
- switch (MI.getOpcode()) {
- case Mips::ATOMIC_LOAD_NAND_I8:
- AtomicOp = Mips::ATOMIC_LOAD_NAND_I8_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_NAND_I16:
- AtomicOp = Mips::ATOMIC_LOAD_NAND_I16_POSTRA;
- break;
- case Mips::ATOMIC_SWAP_I8:
- AtomicOp = Mips::ATOMIC_SWAP_I8_POSTRA;
- break;
- case Mips::ATOMIC_SWAP_I16:
- AtomicOp = Mips::ATOMIC_SWAP_I16_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_ADD_I8:
- AtomicOp = Mips::ATOMIC_LOAD_ADD_I8_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_ADD_I16:
- AtomicOp = Mips::ATOMIC_LOAD_ADD_I16_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_SUB_I8:
- AtomicOp = Mips::ATOMIC_LOAD_SUB_I8_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_SUB_I16:
- AtomicOp = Mips::ATOMIC_LOAD_SUB_I16_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_AND_I8:
- AtomicOp = Mips::ATOMIC_LOAD_AND_I8_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_AND_I16:
- AtomicOp = Mips::ATOMIC_LOAD_AND_I16_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_OR_I8:
- AtomicOp = Mips::ATOMIC_LOAD_OR_I8_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_OR_I16:
- AtomicOp = Mips::ATOMIC_LOAD_OR_I16_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_XOR_I8:
- AtomicOp = Mips::ATOMIC_LOAD_XOR_I8_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_XOR_I16:
- AtomicOp = Mips::ATOMIC_LOAD_XOR_I16_POSTRA;
- break;
- case Mips::ATOMIC_LOAD_MIN_I8:
- AtomicOp = Mips::ATOMIC_LOAD_MIN_I8_POSTRA;
- NeedsAdditionalReg = true;
- break;
- case Mips::ATOMIC_LOAD_MIN_I16:
- AtomicOp = Mips::ATOMIC_LOAD_MIN_I16_POSTRA;
- NeedsAdditionalReg = true;
- break;
- case Mips::ATOMIC_LOAD_MAX_I8:
- AtomicOp = Mips::ATOMIC_LOAD_MAX_I8_POSTRA;
- NeedsAdditionalReg = true;
- break;
- case Mips::ATOMIC_LOAD_MAX_I16:
- AtomicOp = Mips::ATOMIC_LOAD_MAX_I16_POSTRA;
- NeedsAdditionalReg = true;
- break;
- case Mips::ATOMIC_LOAD_UMIN_I8:
- AtomicOp = Mips::ATOMIC_LOAD_UMIN_I8_POSTRA;
- NeedsAdditionalReg = true;
- break;
- case Mips::ATOMIC_LOAD_UMIN_I16:
- AtomicOp = Mips::ATOMIC_LOAD_UMIN_I16_POSTRA;
- NeedsAdditionalReg = true;
- break;
- case Mips::ATOMIC_LOAD_UMAX_I8:
- AtomicOp = Mips::ATOMIC_LOAD_UMAX_I8_POSTRA;
- NeedsAdditionalReg = true;
- break;
- case Mips::ATOMIC_LOAD_UMAX_I16:
- AtomicOp = Mips::ATOMIC_LOAD_UMAX_I16_POSTRA;
- NeedsAdditionalReg = true;
- break;
- default:
- llvm_unreachable("Unknown subword atomic pseudo for expansion!");
- }
-
- // insert new blocks after the current block
- const BasicBlock *LLVM_BB = BB->getBasicBlock();
- MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
- MachineFunction::iterator It = ++BB->getIterator();
- MF->insert(It, exitMBB);
-
- // Transfer the remainder of BB and its successor edges to exitMBB.
- exitMBB->splice(exitMBB->begin(), BB,
- std::next(MachineBasicBlock::iterator(MI)), BB->end());
- exitMBB->transferSuccessorsAndUpdatePHIs(BB);
-
- BB->addSuccessor(exitMBB, BranchProbability::getOne());
-
- // thisMBB:
- // addiu masklsb2,$0,-4 # 0xfffffffc
- // and alignedaddr,ptr,masklsb2
- // andi ptrlsb2,ptr,3
- // sll shiftamt,ptrlsb2,3
- // ori maskupper,$0,255 # 0xff
- // sll mask,maskupper,shiftamt
- // nor mask2,$0,mask
- // sll incr2,incr,shiftamt
-
- int64_t MaskImm = (Size == 1) ? 255 : 65535;
- BuildMI(BB, DL, TII->get(ABI.GetPtrAddiuOp()), MaskLSB2)
- .addReg(ABI.GetNullPtr()).addImm(-4);
- BuildMI(BB, DL, TII->get(ABI.GetPtrAndOp()), AlignedAddr)
- .addReg(Ptr).addReg(MaskLSB2);
- BuildMI(BB, DL, TII->get(Mips::ANDi), PtrLSB2)
- .addReg(Ptr, {}, ArePtrs64bit ? Mips::sub_32 : 0)
- .addImm(3);
- if (Subtarget.isLittle()) {
- BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(PtrLSB2).addImm(3);
- } else {
- Register Off = RegInfo.createVirtualRegister(RC);
- BuildMI(BB, DL, TII->get(Mips::XORi), Off)
- .addReg(PtrLSB2).addImm((Size == 1) ? 3 : 2);
- BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(Off).addImm(3);
- }
- BuildMI(BB, DL, TII->get(Mips::ORi), MaskUpper)
- .addReg(Mips::ZERO).addImm(MaskImm);
- BuildMI(BB, DL, TII->get(Mips::SLLV), Mask)
- .addReg(MaskUpper).addReg(ShiftAmt);
- BuildMI(BB, DL, TII->get(Mips::NOR), Mask2).addReg(Mips::ZERO).addReg(Mask);
- BuildMI(BB, DL, TII->get(Mips::SLLV), Incr2).addReg(Incr).addReg(ShiftAmt);
-
-
- // The purposes of the flags on the scratch registers is explained in
- // emitAtomicBinary. In summary, we need a scratch register which is going to
- // be undef, that is unique among registers chosen for the instruction.
-
- MachineInstrBuilder MIB =
- BuildMI(BB, DL, TII->get(AtomicOp))
- .addReg(Dest, RegState::Define | RegState::EarlyClobber)
- .addReg(AlignedAddr)
- .addReg(Incr2)
- .addReg(Mask)
- .addReg(Mask2)
- .addReg(ShiftAmt)
- .addReg(Scratch, RegState::EarlyClobber | RegState::Define |
- RegState::Dead | RegState::Implicit)
- .addReg(Scratch2, RegState::EarlyClobber | RegState::Define |
- RegState::Dead | RegState::Implicit)
- .addReg(Scratch3, RegState::EarlyClobber | RegState::Define |
- RegState::Dead | RegState::Implicit);
- if (NeedsAdditionalReg) {
- Register Scratch4 = RegInfo.createVirtualRegister(RC);
- MIB.addReg(Scratch4, RegState::EarlyClobber | RegState::Define |
- RegState::Dead | RegState::Implicit);
- }
-
- MI.eraseFromParent(); // The instruction is gone now.
-
- return exitMBB;
-}
-
-// Lower atomic compare and swap to a pseudo instruction, taking care to
-// define a scratch register for the pseudo instruction's expansion. The
-// instruction is expanded after the register allocator as to prevent
-// the insertion of stores between the linked load and the store conditional.
-
-MachineBasicBlock *
-MipsTargetLowering::emitAtomicCmpSwap(MachineInstr &MI,
- MachineBasicBlock *BB) const {
-
- assert((MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I32 ||
- MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I64) &&
- "Unsupported atomic pseudo for EmitAtomicCmpSwap.");
-
- const unsigned Size = MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I32 ? 4 : 8;
-
- MachineFunction *MF = BB->getParent();
- MachineRegisterInfo &MRI = MF->getRegInfo();
- const TargetRegisterClass *RC = getRegClassFor(MVT::getIntegerVT(Size * 8));
- const TargetInstrInfo *TII = Subtarget.getInstrInfo();
- DebugLoc DL = MI.getDebugLoc();
-
- unsigned AtomicOp = MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I32
- ? Mips::ATOMIC_CMP_SWAP_I32_POSTRA
- : Mips::ATOMIC_CMP_SWAP_I64_POSTRA;
- Register Dest = MI.getOperand(0).getReg();
- Register Ptr = MI.getOperand(1).getReg();
- Register OldVal = MI.getOperand(2).getReg();
- Register NewVal = MI.getOperand(3).getReg();
-
- Register Scratch = MRI.createVirtualRegister(RC);
- MachineBasicBlock::iterator II(MI);
-
- // We need to create copies of the various registers and kill them at the
- // atomic pseudo. If the copies are not made, when the atomic is expanded
- // after fast register allocation, the spills will end up outside of the
- // blocks that their values are defined in, causing livein errors.
-
- Register PtrCopy = MRI.createVirtualRegister(MRI.getRegClass(Ptr));
- Register OldValCopy = MRI.createVirtualRegister(MRI.getRegClass(OldVal));
- Register NewValCopy = MRI.createVirtualRegister(MRI.getRegClass(NewVal));
-
- BuildMI(*BB, II, DL, TII->get(Mips::COPY), PtrCopy).addReg(Ptr);
- BuildMI(*BB, II, DL, TII->get(Mips::COPY), OldValCopy).addReg(OldVal);
- BuildMI(*BB, II, DL, TII->get(Mips::COPY), NewValCopy).addReg(NewVal);
-
- // The purposes of the flags on the scratch registers is explained in
- // emitAtomicBinary. In summary, we need a scratch register which is going to
- // be undef, that is unique among registers chosen for the instruction.
-
- BuildMI(*BB, II, DL, TII->get(AtomicOp))
- .addReg(Dest, RegState::Define | RegState::EarlyClobber)
- .addReg(PtrCopy, RegState::Kill)
- .addReg(OldValCopy, RegState::Kill)
- .addReg(NewValCopy, RegState::Kill)
- .addReg(Scratch, RegState::EarlyClobber | RegState::Define |
- RegState::Dead | RegState::Implicit);
-
- MI.eraseFromParent(); // The instruction is gone now.
-
- return BB;
-}
-
-MachineBasicBlock *MipsTargetLowering::emitAtomicCmpSwapPartword(
- MachineInstr &MI, MachineBasicBlock *BB, unsigned Size) const {
- assert((Size == 1 || Size == 2) &&
- "Unsupported size for EmitAtomicCmpSwapPartial.");
-
- MachineFunction *MF = BB->getParent();
- MachineRegisterInfo &RegInfo = MF->getRegInfo();
- const TargetRegisterClass *RC = getRegClassFor(MVT::i32);
- const bool ArePtrs64bit = ABI.ArePtrs64bit();
- const TargetRegisterClass *RCp =
- getRegClassFor(ArePtrs64bit ? MVT::i64 : MVT::i32);
- const TargetInstrInfo *TII = Subtarget.getInstrInfo();
- DebugLoc DL = MI.getDebugLoc();
-
- Register Dest = MI.getOperand(0).getReg();
- Register Ptr = MI.getOperand(1).getReg();
- Register CmpVal = MI.getOperand(2).getReg();
- Register NewVal = MI.getOperand(3).getReg();
-
- Register AlignedAddr = RegInfo.createVirtualRegister(RCp);
- Register ShiftAmt = RegInfo.createVirtualRegister(RC);
- Register Mask = RegInfo.createVirtualRegister(RC);
- Register Mask2 = RegInfo.createVirtualRegister(RC);
- Register ShiftedCmpVal = RegInfo.createVirtualRegister(RC);
- Register ShiftedNewVal = RegInfo.createVirtualRegister(RC);
- Register MaskLSB2 = RegInfo.createVirtualRegister(RCp);
- Register PtrLSB2 = RegInfo.createVirtualRegister(RC);
- Register MaskUpper = RegInfo.createVirtualRegister(RC);
- Register MaskedCmpVal = RegInfo.createVirtualRegister(RC);
- Register MaskedNewVal = RegInfo.createVirtualRegister(RC);
- unsigned AtomicOp = MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I8
- ? Mips::ATOMIC_CMP_SWAP_I8_POSTRA
- : Mips::ATOMIC_CMP_SWAP_I16_POSTRA;
-
- // The scratch registers here with the EarlyClobber | Define | Dead | Implicit
- // flags are used to coerce the register allocator and the machine verifier to
- // accept the usage of these registers.
- // The EarlyClobber flag has the semantic properties that the operand it is
- // attached to is clobbered before the rest of the inputs are read. Hence it
- // must be unique among the operands to the instruction.
- // The Define flag is needed to coerce the machine verifier that an Undef
- // value isn't a problem.
- // The Dead flag is needed as the value in scratch isn't used by any other
- // instruction. Kill isn't used as Dead is more precise.
- Register Scratch = RegInfo.createVirtualRegister(RC);
- Register Scratch2 = RegInfo.createVirtualRegister(RC);
-
- // insert new blocks after the current block
- const BasicBlock *LLVM_BB = BB->getBasicBlock();
- MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
- MachineFunction::iterator It = ++BB->getIterator();
- MF->insert(It, exitMBB);
-
- // Transfer the remainder of BB and its successor edges to exitMBB.
- exitMBB->splice(exitMBB->begin(), BB,
- std::next(MachineBasicBlock::iterator(MI)), BB->end());
- exitMBB->transferSuccessorsAndUpdatePHIs(BB);
-
- BB->addSuccessor(exitMBB, BranchProbability::getOne());
-
- // thisMBB:
- // addiu masklsb2,$0,-4 # 0xfffffffc
- // and alignedaddr,ptr,masklsb2
- // andi ptrlsb2,ptr,3
- // xori ptrlsb2,ptrlsb2,3 # Only for BE
- // sll shiftamt,ptrlsb2,3
- // ori maskupper,$0,255 # 0xff
- // sll mask,maskupper,shiftamt
- // nor mask2,$0,mask
- // andi maskedcmpval,cmpval,255
- // sll shiftedcmpval,maskedcmpval,shiftamt
- // andi maskednewval,newval,255
- // sll shiftednewval,maskednewval,shiftamt
- int64_t MaskImm = (Size == 1) ? 255 : 65535;
- BuildMI(BB, DL, TII->get(ArePtrs64bit ? Mips::DADDiu : Mips::ADDiu), MaskLSB2)
- .addReg(ABI.GetNullPtr()).addImm(-4);
- BuildMI(BB, DL, TII->get(ArePtrs64bit ? Mips::AND64 : Mips::AND), AlignedAddr)
- .addReg(Ptr).addReg(MaskLSB2);
- BuildMI(BB, DL, TII->get(Mips::ANDi), PtrLSB2)
- .addReg(Ptr, {}, ArePtrs64bit ? Mips::sub_32 : 0)
- .addImm(3);
- if (Subtarget.isLittle()) {
- BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(PtrLSB2).addImm(3);
- } else {
- Register Off = RegInfo.createVirtualRegister(RC);
- BuildMI(BB, DL, TII->get(Mips::XORi), Off)
- .addReg(PtrLSB2).addImm((Size == 1) ? 3 : 2);
- BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(Off).addImm(3);
- }
- BuildMI(BB, DL, TII->get(Mips::ORi), MaskUpper)
- .addReg(Mips::ZERO).addImm(MaskImm);
- BuildMI(BB, DL, TII->get(Mips::SLLV), Mask)
- .addReg(MaskUpper).addReg(ShiftAmt);
- BuildMI(BB, DL, TII->get(Mips::NOR), Mask2).addReg(Mips::ZERO).addReg(Mask);
- BuildMI(BB, DL, TII->get(Mips::ANDi), MaskedCmpVal)
- .addReg(CmpVal).addImm(MaskImm);
- BuildMI(BB, DL, TII->get(Mips::SLLV), ShiftedCmpVal)
- .addReg(MaskedCmpVal).addReg(ShiftAmt);
- BuildMI(BB, DL, TII->get(Mips::ANDi), MaskedNewVal)
- .addReg(NewVal).addImm(MaskImm);
- BuildMI(BB, DL, TII->get(Mips::SLLV), ShiftedNewVal)
- .addReg(MaskedNewVal).addReg(ShiftAmt);
-
- // The purposes of the flags on the scratch registers are explained in
- // emitAtomicBinary. In summary, we need a scratch register which is going to
- // be undef, that is unique among the register chosen for the instruction.
-
- BuildMI(BB, DL, TII->get(AtomicOp))
- .addReg(Dest, RegState::Define | RegState::EarlyClobber)
- .addReg(AlignedAddr)
- .addReg(Mask)
- .addReg(ShiftedCmpVal)
- .addReg(Mask2)
- .addReg(ShiftedNewVal)
- .addReg(ShiftAmt)
- .addReg(Scratch, RegState::EarlyClobber | RegState::Define |
- RegState::Dead | RegState::Implicit)
- .addReg(Scratch2, RegState::EarlyClobber | RegState::Define |
- RegState::Dead | RegState::Implicit);
-
- MI.eraseFromParent(); // The instruction is gone now.
-
- return exitMBB;
-}
-
SDValue MipsTargetLowering::lowerREADCYCLECOUNTER(SDValue Op,
SelectionDAG &DAG) const {
SmallVector<SDValue, 3> Results;
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h
index 75604cc20aaf41..85f857151abe32 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.h
+++ b/llvm/lib/Target/Mips/MipsISelLowering.h
@@ -508,24 +508,27 @@ using TargetRegisterClass = MCRegisterClass;
return true;
}
+ void getTgtMemIntrinsic(SmallVectorImpl<IntrinsicInfo> &Infos,
+ const CallBase &I, MachineFunction &MF,
+ unsigned Intrinsic) const override;
+
+ AtomicExpansionKind
+ shouldExpandAtomicRMWInIR(const AtomicRMWInst *AI) const override;
+ AtomicExpansionKind
+ shouldExpandAtomicCmpXchgInIR(const AtomicCmpXchgInst *CI) const override;
+ Value *emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder,
+ AtomicRMWInst *AI, Value *AlignedAddr,
+ Value *Incr, Value *Mask,
+ Value *ShiftAmt,
+ AtomicOrdering Ord) const override;
+ Value *emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder,
+ AtomicCmpXchgInst *CI,
+ Value *AlignedAddr, Value *CmpVal,
+ Value *NewVal, Value *Mask,
+ AtomicOrdering Ord) const override;
+
ArrayRef<MCPhysReg> getRoundingControlRegisters() const override;
- /// Emit a sign-extension using sll/sra, seb, or seh appropriately.
- MachineBasicBlock *emitSignExtendToI32InReg(MachineInstr &MI,
- MachineBasicBlock *BB,
- unsigned Size, unsigned DstReg,
- unsigned SrcRec) const;
-
- MachineBasicBlock *emitAtomicBinary(MachineInstr &MI,
- MachineBasicBlock *BB) const;
- MachineBasicBlock *emitAtomicBinaryPartword(MachineInstr &MI,
- MachineBasicBlock *BB,
- unsigned Size) const;
- MachineBasicBlock *emitAtomicCmpSwap(MachineInstr &MI,
- MachineBasicBlock *BB) const;
- MachineBasicBlock *emitAtomicCmpSwapPartword(MachineInstr &MI,
- MachineBasicBlock *BB,
- unsigned Size) const;
MachineBasicBlock *emitPseudoSELECT(MachineInstr &MI, MachineBasicBlock *BB,
bool isFPCmp, unsigned Opc) const;
MachineBasicBlock *emitPseudoD_SELECT(MachineInstr &MI,
diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td
index 3b523af856d1cf..7905e5c644f09e 100644
--- a/llvm/lib/Target/Mips/MipsInstrInfo.td
+++ b/llvm/lib/Target/Mips/MipsInstrInfo.td
@@ -1827,50 +1827,34 @@ class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
let Constraints = "$src = $rt";
}
-// Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
-class Atomic2Ops<PatFrag Op, RegisterClass DRC> :
- PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
- [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]> {
- let hasNoSchedulingInfo = 1;
-}
-
-class Atomic2OpsPostRA<RegisterClass RC> :
- PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$incr), []> {
+class PseudoAtomic<dag outs, dag ins, string constraints> :
+ PseudoSE<outs, ins, []> {
+ let Constraints = constraints;
let mayLoad = 1;
let mayStore = 1;
+ let hasSideEffects = 0;
let Predicates = [NotR5900];
}
-class Atomic2OpsSubwordPostRA<RegisterClass RC>
- : PseudoSE<
- (outs RC:$dst),
- (ins PtrRC:$ptr, RC:$incr, RC:$mask, RC:$mask2, RC:$shiftamnt), []> {
- let Predicates = [NotR5900];
-}
+class PseudoAtomicRMW<RegisterClass RC, bit IsMinMax = 0> :
+ PseudoAtomic<!if(IsMinMax, (outs RC:$dst, RC:$scratch, RC:$cmp),
+ (outs RC:$dst, RC:$scratch)),
+ (ins PtrRC:$ptr, RC:$incr),
+ !if(IsMinMax,
+ "@earlyclobber $dst, at earlyclobber $scratch, at earlyclobber $cmp",
+ "@earlyclobber $dst, at earlyclobber $scratch")>;
-// Atomic Compare & Swap.
-// Atomic compare and swap is lowered into two stages. The first stage happens
-// during ISelLowering, which produces the PostRA version of this instruction.
-class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
- PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
- [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]> {
- let hasNoSchedulingInfo = 1;
-}
+class PseudoAtomicCmpSwap<RegisterClass RC> :
+ PseudoAtomic<(outs RC:$dst, RC:$scratch),
+ (ins PtrRC:$ptr, RC:$cmp, RC:$new),
+ "@earlyclobber $dst, at earlyclobber $scratch">;
-class AtomicCmpSwapPostRA<RegisterClass RC> :
- PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$cmp, RC:$swap), []> {
- let mayLoad = 1;
- let mayStore = 1;
- let Predicates = [NotR5900];
-}
+class PseudoAtomicRMWPat<PatFrag Op, Instruction Inst, RegisterClass RC> :
+ Pat<(Op iPTR:$ptr, RC:$incr), (Inst iPTR:$ptr, RC:$incr)>;
-class AtomicCmpSwapSubwordPostRA<RegisterClass RC> :
- PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$mask, RC:$ShiftCmpVal,
- RC:$mask2, RC:$ShiftNewVal, RC:$ShiftAmt), []> {
- let mayLoad = 1;
- let mayStore = 1;
- let Predicates = [NotR5900];
-}
+class PseudoAtomicCmpSwapPat<PatFrag Op, Instruction Inst, RegisterClass RC> :
+ Pat<(Op iPTR:$ptr, RC:$cmp, RC:$new),
+ (Inst iPTR:$ptr, RC:$cmp, RC:$new)>;
class LLBase<string opstr, RegisterOperand RO, DAGOperand MO = mem> :
InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
@@ -1929,87 +1913,81 @@ def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
[(callseq_end timm:$amt1, timm:$amt2)]>;
}
-let usesCustomInserter = 1 in {
- def ATOMIC_LOAD_ADD_I8 : Atomic2Ops<atomic_load_add_i8, GPR32>;
- def ATOMIC_LOAD_ADD_I16 : Atomic2Ops<atomic_load_add_i16, GPR32>;
- def ATOMIC_LOAD_ADD_I32 : Atomic2Ops<atomic_load_add_i32, GPR32>;
- def ATOMIC_LOAD_SUB_I8 : Atomic2Ops<atomic_load_sub_i8, GPR32>;
- def ATOMIC_LOAD_SUB_I16 : Atomic2Ops<atomic_load_sub_i16, GPR32>;
- def ATOMIC_LOAD_SUB_I32 : Atomic2Ops<atomic_load_sub_i32, GPR32>;
- def ATOMIC_LOAD_AND_I8 : Atomic2Ops<atomic_load_and_i8, GPR32>;
- def ATOMIC_LOAD_AND_I16 : Atomic2Ops<atomic_load_and_i16, GPR32>;
- def ATOMIC_LOAD_AND_I32 : Atomic2Ops<atomic_load_and_i32, GPR32>;
- def ATOMIC_LOAD_OR_I8 : Atomic2Ops<atomic_load_or_i8, GPR32>;
- def ATOMIC_LOAD_OR_I16 : Atomic2Ops<atomic_load_or_i16, GPR32>;
- def ATOMIC_LOAD_OR_I32 : Atomic2Ops<atomic_load_or_i32, GPR32>;
- def ATOMIC_LOAD_XOR_I8 : Atomic2Ops<atomic_load_xor_i8, GPR32>;
- def ATOMIC_LOAD_XOR_I16 : Atomic2Ops<atomic_load_xor_i16, GPR32>;
- def ATOMIC_LOAD_XOR_I32 : Atomic2Ops<atomic_load_xor_i32, GPR32>;
- def ATOMIC_LOAD_NAND_I8 : Atomic2Ops<atomic_load_nand_i8, GPR32>;
- def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_i16, GPR32>;
- def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_i32, GPR32>;
-
- def ATOMIC_SWAP_I8 : Atomic2Ops<atomic_swap_i8, GPR32>;
- def ATOMIC_SWAP_I16 : Atomic2Ops<atomic_swap_i16, GPR32>;
- def ATOMIC_SWAP_I32 : Atomic2Ops<atomic_swap_i32, GPR32>;
-
- def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap<atomic_cmp_swap_i8, GPR32>;
- def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<atomic_cmp_swap_i16, GPR32>;
- def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_i32, GPR32>;
-
- def ATOMIC_LOAD_MIN_I8 : Atomic2Ops<atomic_load_min_i8, GPR32>;
- def ATOMIC_LOAD_MIN_I16 : Atomic2Ops<atomic_load_min_i16, GPR32>;
- def ATOMIC_LOAD_MIN_I32 : Atomic2Ops<atomic_load_min_i32, GPR32>;
- def ATOMIC_LOAD_MAX_I8 : Atomic2Ops<atomic_load_max_i8, GPR32>;
- def ATOMIC_LOAD_MAX_I16 : Atomic2Ops<atomic_load_max_i16, GPR32>;
- def ATOMIC_LOAD_MAX_I32 : Atomic2Ops<atomic_load_max_i32, GPR32>;
- def ATOMIC_LOAD_UMIN_I8 : Atomic2Ops<atomic_load_umin_i8, GPR32>;
- def ATOMIC_LOAD_UMIN_I16 : Atomic2Ops<atomic_load_umin_i16, GPR32>;
- def ATOMIC_LOAD_UMIN_I32 : Atomic2Ops<atomic_load_umin_i32, GPR32>;
- def ATOMIC_LOAD_UMAX_I8 : Atomic2Ops<atomic_load_umax_i8, GPR32>;
- def ATOMIC_LOAD_UMAX_I16 : Atomic2Ops<atomic_load_umax_i16, GPR32>;
- def ATOMIC_LOAD_UMAX_I32 : Atomic2Ops<atomic_load_umax_i32, GPR32>;
-}
-
-def ATOMIC_LOAD_ADD_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
-def ATOMIC_LOAD_ADD_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
-def ATOMIC_LOAD_ADD_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
-def ATOMIC_LOAD_SUB_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
-def ATOMIC_LOAD_SUB_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
-def ATOMIC_LOAD_SUB_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
-def ATOMIC_LOAD_AND_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
-def ATOMIC_LOAD_AND_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
-def ATOMIC_LOAD_AND_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
-def ATOMIC_LOAD_OR_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
-def ATOMIC_LOAD_OR_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
-def ATOMIC_LOAD_OR_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
-def ATOMIC_LOAD_XOR_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
-def ATOMIC_LOAD_XOR_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
-def ATOMIC_LOAD_XOR_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
-def ATOMIC_LOAD_NAND_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
-def ATOMIC_LOAD_NAND_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
-def ATOMIC_LOAD_NAND_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
-
-def ATOMIC_SWAP_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
-def ATOMIC_SWAP_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
-def ATOMIC_SWAP_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
-
-def ATOMIC_CMP_SWAP_I8_POSTRA : AtomicCmpSwapSubwordPostRA<GPR32>;
-def ATOMIC_CMP_SWAP_I16_POSTRA : AtomicCmpSwapSubwordPostRA<GPR32>;
-def ATOMIC_CMP_SWAP_I32_POSTRA : AtomicCmpSwapPostRA<GPR32>;
-
-def ATOMIC_LOAD_MIN_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
-def ATOMIC_LOAD_MIN_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
-def ATOMIC_LOAD_MIN_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
-def ATOMIC_LOAD_MAX_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
-def ATOMIC_LOAD_MAX_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
-def ATOMIC_LOAD_MAX_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
-def ATOMIC_LOAD_UMIN_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
-def ATOMIC_LOAD_UMIN_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
-def ATOMIC_LOAD_UMIN_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
-def ATOMIC_LOAD_UMAX_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
-def ATOMIC_LOAD_UMAX_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
-def ATOMIC_LOAD_UMAX_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
+def ATOMIC_LOAD_ADD_I32 : PseudoAtomicRMW<GPR32>;
+def ATOMIC_LOAD_SUB_I32 : PseudoAtomicRMW<GPR32>;
+def ATOMIC_LOAD_AND_I32 : PseudoAtomicRMW<GPR32>;
+def ATOMIC_LOAD_OR_I32 : PseudoAtomicRMW<GPR32>;
+def ATOMIC_LOAD_XOR_I32 : PseudoAtomicRMW<GPR32>;
+def ATOMIC_LOAD_NAND_I32 : PseudoAtomicRMW<GPR32>;
+def ATOMIC_LOAD_MIN_I32 : PseudoAtomicRMW<GPR32, 1>;
+def ATOMIC_LOAD_MAX_I32 : PseudoAtomicRMW<GPR32, 1>;
+def ATOMIC_LOAD_UMIN_I32 : PseudoAtomicRMW<GPR32, 1>;
+def ATOMIC_LOAD_UMAX_I32 : PseudoAtomicRMW<GPR32, 1>;
+def ATOMIC_SWAP_I32 : PseudoAtomicRMW<GPR32>;
+def ATOMIC_CMP_SWAP_I32 : PseudoAtomicCmpSwap<GPR32>;
+
+let Predicates = [NotInMips16Mode, NotR5900] in {
+def : PseudoAtomicRMWPat<atomic_load_add_i32, ATOMIC_LOAD_ADD_I32, GPR32>;
+def : PseudoAtomicRMWPat<atomic_load_sub_i32, ATOMIC_LOAD_SUB_I32, GPR32>;
+def : PseudoAtomicRMWPat<atomic_load_and_i32, ATOMIC_LOAD_AND_I32, GPR32>;
+def : PseudoAtomicRMWPat<atomic_load_or_i32, ATOMIC_LOAD_OR_I32, GPR32>;
+def : PseudoAtomicRMWPat<atomic_load_xor_i32, ATOMIC_LOAD_XOR_I32, GPR32>;
+def : PseudoAtomicRMWPat<atomic_load_nand_i32, ATOMIC_LOAD_NAND_I32, GPR32>;
+def : PseudoAtomicRMWPat<atomic_load_min_i32, ATOMIC_LOAD_MIN_I32, GPR32>;
+def : PseudoAtomicRMWPat<atomic_load_max_i32, ATOMIC_LOAD_MAX_I32, GPR32>;
+def : PseudoAtomicRMWPat<atomic_load_umin_i32, ATOMIC_LOAD_UMIN_I32, GPR32>;
+def : PseudoAtomicRMWPat<atomic_load_umax_i32, ATOMIC_LOAD_UMAX_I32, GPR32>;
+def : PseudoAtomicRMWPat<atomic_swap_i32, ATOMIC_SWAP_I32, GPR32>;
+def : PseudoAtomicCmpSwapPat<atomic_cmp_swap_i32, ATOMIC_CMP_SWAP_I32, GPR32>;
+}
+
+class PseudoMaskedRMW :
+ PseudoAtomic<(outs GPR32:$dst, GPR32:$scratch),
+ (ins PtrRC:$ptr, GPR32:$incr, GPR32:$mask),
+ "@earlyclobber $dst, at earlyclobber $scratch">;
+
+class PseudoMaskedMinMax<dag ins = (ins PtrRC:$ptr, GPR32:$incr, GPR32:$mask)> :
+ PseudoAtomic<(outs GPR32:$dst, GPR32:$scratch, GPR32:$cmp), ins,
+ "@earlyclobber $dst, at earlyclobber $scratch,"
+ "@earlyclobber $cmp">;
+
+class PseudoMaskedRMWPat<Intrinsic Op, Instruction Inst> :
+ Pat<(Op iPTR:$ptr, GPR32:$incr, GPR32:$mask),
+ (Inst iPTR:$ptr, GPR32:$incr, GPR32:$mask)>;
+
+class PseudoMaskedMinMaxPat<Intrinsic Op, Instruction Inst> :
+ Pat<(Op iPTR:$ptr, GPR32:$incr, GPR32:$mask, GPR32:$sextshift),
+ (Inst iPTR:$ptr, GPR32:$incr, GPR32:$mask, GPR32:$sextshift)>;
+
+def ATOMIC_SWAP_MASKED : PseudoMaskedRMW;
+def ATOMIC_LOAD_ADD_MASKED : PseudoMaskedRMW;
+def ATOMIC_LOAD_SUB_MASKED : PseudoMaskedRMW;
+def ATOMIC_LOAD_NAND_MASKED : PseudoMaskedRMW;
+
+def ATOMIC_LOAD_UMIN_MASKED : PseudoMaskedMinMax<>;
+def ATOMIC_LOAD_UMAX_MASKED : PseudoMaskedMinMax<>;
+def ATOMIC_LOAD_MIN_MASKED :
+ PseudoMaskedMinMax<(ins PtrRC:$ptr, GPR32:$incr, GPR32:$mask, GPR32:$sextshift)>;
+def ATOMIC_LOAD_MAX_MASKED :
+ PseudoMaskedMinMax<(ins PtrRC:$ptr, GPR32:$incr, GPR32:$mask, GPR32:$sextshift)>;
+
+def ATOMIC_CMP_SWAP_MASKED :
+ PseudoAtomic<(outs GPR32:$dst, GPR32:$scratch),
+ (ins PtrRC:$ptr, GPR32:$cmp, GPR32:$new, GPR32:$mask),
+ "@earlyclobber $dst, at earlyclobber $scratch">;
+
+let Predicates = [NotInMips16Mode, NotR5900] in {
+def : PseudoMaskedRMWPat<int_mips_masked_atomicrmw_xchg, ATOMIC_SWAP_MASKED>;
+def : PseudoMaskedRMWPat<int_mips_masked_atomicrmw_add, ATOMIC_LOAD_ADD_MASKED>;
+def : PseudoMaskedRMWPat<int_mips_masked_atomicrmw_sub, ATOMIC_LOAD_SUB_MASKED>;
+def : PseudoMaskedRMWPat<int_mips_masked_atomicrmw_nand, ATOMIC_LOAD_NAND_MASKED>;
+def : PseudoMaskedRMWPat<int_mips_masked_atomicrmw_umin, ATOMIC_LOAD_UMIN_MASKED>;
+def : PseudoMaskedRMWPat<int_mips_masked_atomicrmw_umax, ATOMIC_LOAD_UMAX_MASKED>;
+def : PseudoMaskedMinMaxPat<int_mips_masked_atomicrmw_min, ATOMIC_LOAD_MIN_MASKED>;
+def : PseudoMaskedMinMaxPat<int_mips_masked_atomicrmw_max, ATOMIC_LOAD_MAX_MASKED>;
+def : Pat<(int_mips_masked_cmpxchg iPTR:$ptr, GPR32:$cmp, GPR32:$new, GPR32:$mask),
+ (ATOMIC_CMP_SWAP_MASKED iPTR:$ptr, GPR32:$cmp, GPR32:$new, GPR32:$mask)>;
+}
/// Pseudo instructions for loading and storing accumulator registers.
let isPseudo = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in {
diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td
index ec0c0d03ae4ee5..75c6c0a8fd1908 100644
--- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td
+++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td
@@ -1606,17 +1606,17 @@ def : InstRW<[GenericWriteFPULoad], (instregex "^LD_[BHWD]$")>;
// Atomic instructions
// FIXME: Define `WriteAtomic` in the MipsSchedule.td and
-// attach it to the Atomic2OpsPostRA, AtomicCmpSwapPostRA, ...
+// attach it to the PseudoAtomic
// classes. Then just define resources for the `WriteAtomic` in each
// machine models.
def GenericAtomic : ProcResource<1> { let BufferSize = 1; }
def GenericWriteAtomic : SchedWriteRes<[GenericAtomic]> { let Latency = 2; }
def : InstRW<[GenericWriteAtomic],
- (instregex "^ATOMIC_SWAP_I(8|16|32|64)_POSTRA$")>;
+ (instregex "^ATOMIC_SWAP_(I(32|64)|MASKED)$")>;
def : InstRW<[GenericWriteAtomic],
- (instregex "^ATOMIC_CMP_SWAP_I(8|16|32|64)_POSTRA$")>;
+ (instregex "^ATOMIC_CMP_SWAP_(I(32|64)|MASKED)$")>;
def : InstRW<[GenericWriteAtomic],
(instregex "^ATOMIC_LOAD_(ADD|SUB|AND|OR|XOR|NAND|MIN|MAX|UMIN|UMAX)"
- "_I(8|16|32|64)_POSTRA$")>;
+ "_(I(32|64)|MASKED)$")>;
}
diff --git a/llvm/lib/Target/Mips/MipsScheduleI6400.td b/llvm/lib/Target/Mips/MipsScheduleI6400.td
index 342e7ac31eb5a6..1d503a111664bc 100644
--- a/llvm/lib/Target/Mips/MipsScheduleI6400.td
+++ b/llvm/lib/Target/Mips/MipsScheduleI6400.td
@@ -437,16 +437,16 @@ let SchedModel = MipsI6400Model in {
// Atomic instructions
// FIXME: Define `WriteAtomic` in the MipsSchedule.td and
- // attach it to the Atomic2OpsPostRA, AtomicCmpSwapPostRA, ...
+ // attach it to the PseudoAtomic
// classes. Then just define resources for the `WriteAtomic` in each
// machine models.
def I6400WriteAtomic : SchedWriteRes<[I6400Atomic]> { let Latency = 2; }
def : InstRW<[I6400WriteAtomic],
- (instregex "^ATOMIC_SWAP_I(8|16|32|64)_POSTRA$")>;
+ (instregex "^ATOMIC_SWAP_(I(32|64)|MASKED)$")>;
def : InstRW<[I6400WriteAtomic],
- (instregex "^ATOMIC_CMP_SWAP_I(8|16|32|64)_POSTRA$")>;
+ (instregex "^ATOMIC_CMP_SWAP_(I(32|64)|MASKED)$")>;
def : InstRW<[I6400WriteAtomic],
(instregex "^ATOMIC_LOAD_(ADD|SUB|AND|OR|XOR|NAND|MIN|MAX|UMIN|UMAX)"
- "_I(8|16|32|64)_POSTRA$")>;
+ "_(I(32|64)|MASKED)$")>;
}
diff --git a/llvm/lib/Target/Mips/MipsScheduleP5600.td b/llvm/lib/Target/Mips/MipsScheduleP5600.td
index dce05df0f609a0..2c1cea59a0041d 100644
--- a/llvm/lib/Target/Mips/MipsScheduleP5600.td
+++ b/llvm/lib/Target/Mips/MipsScheduleP5600.td
@@ -620,17 +620,17 @@ def : InstRW<[P5600WriteEitherALU], (instrs ROTRV)>;
// Atomic instructions
// FIXME: Define `WriteAtomic` in the MipsSchedule.td and
-// attach it to the Atomic2OpsPostRA, AtomicCmpSwapPostRA, ...
+// attach it to the PseudoAtomic
// classes. Then just define resources for the `WriteAtomic` in each
// machine models.
def P5600Atomic : ProcResource<1> { let BufferSize = 1; }
def P5600WriteAtomic : SchedWriteRes<[P5600Atomic]> { let Latency = 2; }
def : InstRW<[P5600WriteAtomic],
- (instregex "^ATOMIC_SWAP_I(8|16|32|64)_POSTRA$")>;
+ (instregex "^ATOMIC_SWAP_(I(32|64)|MASKED)$")>;
def : InstRW<[P5600WriteAtomic],
- (instregex "^ATOMIC_CMP_SWAP_I(8|16|32|64)_POSTRA$")>;
+ (instregex "^ATOMIC_CMP_SWAP_(I(32|64)|MASKED)$")>;
def : InstRW<[P5600WriteAtomic],
(instregex "^ATOMIC_LOAD_(ADD|SUB|AND|OR|XOR|NAND|MIN|MAX|UMIN|UMAX)"
- "_I(8|16|32|64)_POSTRA$")>;
+ "_(I(32|64)|MASKED)$")>;
}
diff --git a/llvm/lib/Target/Mips/MipsTargetMachine.cpp b/llvm/lib/Target/Mips/MipsTargetMachine.cpp
index 0aa14d6171d5e7..b4a3b94a5344aa 100644
--- a/llvm/lib/Target/Mips/MipsTargetMachine.cpp
+++ b/llvm/lib/Target/Mips/MipsTargetMachine.cpp
@@ -198,7 +198,7 @@ class MipsPassConfig : public TargetPassConfig {
void addIRPasses() override;
bool addInstSelector() override;
- void addPreEmitPass() override;
+ void addPreEmitPass2() override;
void addPreRegAlloc() override;
bool addIRTranslator() override;
void addPreLegalizeMachineIR() override;
@@ -252,10 +252,9 @@ MachineFunctionInfo *MipsTargetMachine::createMachineFunctionInfo(
return MipsFunctionInfo::create<MipsFunctionInfo>(Allocator, F, STI);
}
-// Implemented by targets that want to run passes immediately before
-// machine code is emitted.
-void MipsPassConfig::addPreEmitPass() {
- // Expand pseudo instructions that are sensitive to register allocation.
+void MipsPassConfig::addPreEmitPass2() {
+ // Expand LL/SC loops after passes that can insert stores, but before
+ // instruction size reduction, delay-slot filling and branch expansion.
addPass(createMipsExpandPseudoPass());
// The microMIPS size reduction pass performs instruction reselection for
diff --git a/llvm/test/CodeGen/Mips/atomic-expand-pipeline.ll b/llvm/test/CodeGen/Mips/atomic-expand-pipeline.ll
new file mode 100644
index 00000000000000..9e3945e85191c0
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/atomic-expand-pipeline.ll
@@ -0,0 +1,16 @@
+; RUN: llc -mtriple=mipsel -mcpu=mips32r2 -O0 -debug-pass=Structure -o /dev/null %s 2>&1 | FileCheck %s
+; RUN: llc -mtriple=mipsel -mcpu=mips32r2 -O2 -debug-pass=Structure -o /dev/null %s 2>&1 | FileCheck %s
+
+; Expand LL/SC loops after generic machine passes and before MIPS finalization.
+; CHECK: Live DEBUG_VALUE analysis
+; CHECK: Stack Frame Layout Analysis
+; CHECK-NEXT: Mips pseudo instruction expansion pass
+; CHECK-NEXT: microMIPS instruction size reduction pass
+; CHECK-NEXT: Mips Delay Slot Filler
+; CHECK-NEXT: Mips Branch Expansion Pass
+; CHECK-NEXT: Mips Constant Islands
+
+define i8 @add(ptr %ptr, i8 %val) {
+ %old = atomicrmw add ptr %ptr, i8 %val monotonic
+ ret i8 %old
+}
diff --git a/llvm/test/CodeGen/Mips/atomic-masked-n32.ll b/llvm/test/CodeGen/Mips/atomic-masked-n32.ll
new file mode 100644
index 00000000000000..1141ae9f31d382
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/atomic-masked-n32.ll
@@ -0,0 +1,362 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=mips64el -target-abi=n32 -mcpu=mips64r2 -verify-machineinstrs < %s | FileCheck %s --check-prefix=LE
+; RUN: llc -mtriple=mips64 -target-abi=n32 -mcpu=mips64r2 -verify-machineinstrs < %s | FileCheck %s --check-prefix=BE
+; RUN: llc -mtriple=mips64el -target-abi=n32 -mcpu=mips64r6 -O0 -verify-machineinstrs < %s | FileCheck %s --check-prefix=LE-R6
+; RUN: llc -mtriple=mips64 -target-abi=n32 -mcpu=mips64r6 -O0 -verify-machineinstrs < %s | FileCheck %s --check-prefix=BE-R6
+
+; N32 masked atomics use 32-bit addresses and aligned i32 memory accesses.
+define signext i8 @signed_min(ptr %ptr, i8 signext %val) {
+; LE-LABEL: signed_min:
+; LE: # %bb.0:
+; LE-NEXT: sll $1, $4, 0
+; LE-NEXT: andi $2, $1, 3
+; LE-NEXT: addiu $3, $zero, -4
+; LE-NEXT: and $1, $1, $3
+; LE-NEXT: sll $2, $2, 3
+; LE-NEXT: addiu $3, $zero, 255
+; LE-NEXT: sllv $3, $3, $2
+; LE-NEXT: sllv $4, $5, $2
+; LE-NEXT: sync
+; LE-NEXT: xori $5, $2, 24
+; LE-NEXT: .LBB0_1: # =>This Inner Loop Header: Depth=1
+; LE-NEXT: ll $6, 0($1)
+; LE-NEXT: and $7, $6, $3
+; LE-NEXT: sllv $7, $7, $5
+; LE-NEXT: srav $7, $7, $5
+; LE-NEXT: slt $8, $4, $7
+; LE-NEXT: movn $7, $4, $8
+; LE-NEXT: xor $7, $6, $7
+; LE-NEXT: and $7, $7, $3
+; LE-NEXT: xor $7, $6, $7
+; LE-NEXT: sc $7, 0($1)
+; LE-NEXT: beqz $7, .LBB0_1
+; LE-NEXT: nop
+; LE-NEXT: # %bb.2:
+; LE-NEXT: srlv $1, $6, $2
+; LE-NEXT: seb $2, $1
+; LE-NEXT: sync
+; LE-NEXT: jr $ra
+; LE-NEXT: nop
+;
+; BE-LABEL: signed_min:
+; BE: # %bb.0:
+; BE-NEXT: sll $1, $4, 0
+; BE-NEXT: not $2, $1
+; BE-NEXT: andi $2, $2, 3
+; BE-NEXT: addiu $3, $zero, -4
+; BE-NEXT: and $1, $1, $3
+; BE-NEXT: sll $2, $2, 3
+; BE-NEXT: addiu $3, $zero, 255
+; BE-NEXT: sllv $3, $3, $2
+; BE-NEXT: sllv $4, $5, $2
+; BE-NEXT: sync
+; BE-NEXT: xori $5, $2, 24
+; BE-NEXT: .LBB0_1: # =>This Inner Loop Header: Depth=1
+; BE-NEXT: ll $6, 0($1)
+; BE-NEXT: and $7, $6, $3
+; BE-NEXT: sllv $7, $7, $5
+; BE-NEXT: srav $7, $7, $5
+; BE-NEXT: slt $8, $4, $7
+; BE-NEXT: movn $7, $4, $8
+; BE-NEXT: xor $7, $6, $7
+; BE-NEXT: and $7, $7, $3
+; BE-NEXT: xor $7, $6, $7
+; BE-NEXT: sc $7, 0($1)
+; BE-NEXT: beqz $7, .LBB0_1
+; BE-NEXT: nop
+; BE-NEXT: # %bb.2:
+; BE-NEXT: srlv $1, $6, $2
+; BE-NEXT: seb $2, $1
+; BE-NEXT: sync
+; BE-NEXT: jr $ra
+; BE-NEXT: nop
+;
+; LE-R6-LABEL: signed_min:
+; LE-R6: # %bb.0:
+; LE-R6-NEXT: move $1, $5
+; LE-R6-NEXT: move $2, $4
+; LE-R6-NEXT: sll $2, $2, 0
+; LE-R6-NEXT: sync
+; LE-R6-NEXT: addiu $3, $zero, -4
+; LE-R6-NEXT: and $5, $2, $3
+; LE-R6-NEXT: andi $2, $2, 3
+; LE-R6-NEXT: sll $2, $2, 3
+; LE-R6-NEXT: addiu $3, $zero, 255
+; LE-R6-NEXT: sllv $7, $3, $2
+; LE-R6-NEXT: sllv $6, $1, $2
+; LE-R6-NEXT: xori $8, $2, 24
+; LE-R6-NEXT: .LBB0_1: # =>This Inner Loop Header: Depth=1
+; LE-R6-NEXT: ll $1, 0($5)
+; LE-R6-NEXT: and $3, $1, $7
+; LE-R6-NEXT: sllv $3, $3, $8
+; LE-R6-NEXT: srav $3, $3, $8
+; LE-R6-NEXT: slt $4, $6, $3
+; LE-R6-NEXT: seleqz $3, $3, $4
+; LE-R6-NEXT: selnez $4, $6, $4
+; LE-R6-NEXT: or $3, $3, $4
+; LE-R6-NEXT: xor $3, $1, $3
+; LE-R6-NEXT: and $3, $3, $7
+; LE-R6-NEXT: xor $3, $1, $3
+; LE-R6-NEXT: sc $3, 0($5)
+; LE-R6-NEXT: beqzc $3, .LBB0_1
+; LE-R6-NEXT: # %bb.2:
+; LE-R6-NEXT: srlv $1, $1, $2
+; LE-R6-NEXT: sync
+; LE-R6-NEXT: seb $2, $1
+; LE-R6-NEXT: jrc $ra
+;
+; BE-R6-LABEL: signed_min:
+; BE-R6: # %bb.0:
+; BE-R6-NEXT: move $1, $5
+; BE-R6-NEXT: move $2, $4
+; BE-R6-NEXT: sll $3, $2, 0
+; BE-R6-NEXT: not $2, $3
+; BE-R6-NEXT: sync
+; BE-R6-NEXT: addiu $4, $zero, -4
+; BE-R6-NEXT: and $5, $3, $4
+; BE-R6-NEXT: andi $2, $2, 3
+; BE-R6-NEXT: sll $2, $2, 3
+; BE-R6-NEXT: addiu $3, $zero, 255
+; BE-R6-NEXT: sllv $7, $3, $2
+; BE-R6-NEXT: sllv $6, $1, $2
+; BE-R6-NEXT: xori $8, $2, 24
+; BE-R6-NEXT: .LBB0_1: # =>This Inner Loop Header: Depth=1
+; BE-R6-NEXT: ll $1, 0($5)
+; BE-R6-NEXT: and $3, $1, $7
+; BE-R6-NEXT: sllv $3, $3, $8
+; BE-R6-NEXT: srav $3, $3, $8
+; BE-R6-NEXT: slt $4, $6, $3
+; BE-R6-NEXT: seleqz $3, $3, $4
+; BE-R6-NEXT: selnez $4, $6, $4
+; BE-R6-NEXT: or $3, $3, $4
+; BE-R6-NEXT: xor $3, $1, $3
+; BE-R6-NEXT: and $3, $3, $7
+; BE-R6-NEXT: xor $3, $1, $3
+; BE-R6-NEXT: sc $3, 0($5)
+; BE-R6-NEXT: beqzc $3, .LBB0_1
+; BE-R6-NEXT: # %bb.2:
+; BE-R6-NEXT: srlv $1, $1, $2
+; BE-R6-NEXT: sync
+; BE-R6-NEXT: seb $2, $1
+; BE-R6-NEXT: jrc $ra
+ %old = atomicrmw min ptr %ptr, i8 %val seq_cst
+ ret i8 %old
+}
+
+define i32 @cmpxchg_result(ptr %ptr, i16 zeroext %cmp, i16 zeroext %val) {
+; LE-LABEL: cmpxchg_result:
+; LE: # %bb.0:
+; LE-NEXT: sll $1, $4, 0
+; LE-NEXT: andi $2, $1, 3
+; LE-NEXT: sll $2, $2, 3
+; LE-NEXT: ori $3, $zero, 65535
+; LE-NEXT: addiu $4, $zero, -4
+; LE-NEXT: and $1, $1, $4
+; LE-NEXT: sllv $3, $3, $2
+; LE-NEXT: sllv $4, $6, $2
+; LE-NEXT: sllv $5, $5, $2
+; LE-NEXT: sync
+; LE-NEXT: .LBB1_1: # =>This Inner Loop Header: Depth=1
+; LE-NEXT: ll $6, 0($1)
+; LE-NEXT: and $7, $6, $3
+; LE-NEXT: bne $7, $5, .LBB1_3
+; LE-NEXT: nop
+; LE-NEXT: # %bb.2: # in Loop: Header=BB1_1 Depth=1
+; LE-NEXT: xor $7, $6, $7
+; LE-NEXT: or $7, $7, $4
+; LE-NEXT: sc $7, 0($1)
+; LE-NEXT: beqz $7, .LBB1_1
+; LE-NEXT: nop
+; LE-NEXT: .LBB1_3:
+; LE-NEXT: srlv $2, $6, $2
+; LE-NEXT: and $1, $6, $3
+; LE-NEXT: xor $1, $5, $1
+; LE-NEXT: sltiu $1, $1, 1
+; LE-NEXT: ins $2, $1, 16, 16
+; LE-NEXT: sync
+; LE-NEXT: jr $ra
+; LE-NEXT: nop
+;
+; BE-LABEL: cmpxchg_result:
+; BE: # %bb.0:
+; BE-NEXT: sll $1, $4, 0
+; BE-NEXT: andi $2, $1, 3
+; BE-NEXT: xori $2, $2, 2
+; BE-NEXT: sll $2, $2, 3
+; BE-NEXT: ori $3, $zero, 65535
+; BE-NEXT: addiu $4, $zero, -4
+; BE-NEXT: and $1, $1, $4
+; BE-NEXT: sllv $3, $3, $2
+; BE-NEXT: sllv $4, $6, $2
+; BE-NEXT: sllv $5, $5, $2
+; BE-NEXT: sync
+; BE-NEXT: .LBB1_1: # =>This Inner Loop Header: Depth=1
+; BE-NEXT: ll $6, 0($1)
+; BE-NEXT: and $7, $6, $3
+; BE-NEXT: bne $7, $5, .LBB1_3
+; BE-NEXT: nop
+; BE-NEXT: # %bb.2: # in Loop: Header=BB1_1 Depth=1
+; BE-NEXT: xor $7, $6, $7
+; BE-NEXT: or $7, $7, $4
+; BE-NEXT: sc $7, 0($1)
+; BE-NEXT: beqz $7, .LBB1_1
+; BE-NEXT: nop
+; BE-NEXT: .LBB1_3:
+; BE-NEXT: srlv $2, $6, $2
+; BE-NEXT: and $1, $6, $3
+; BE-NEXT: xor $1, $5, $1
+; BE-NEXT: sltiu $1, $1, 1
+; BE-NEXT: ins $2, $1, 16, 16
+; BE-NEXT: sync
+; BE-NEXT: jr $ra
+; BE-NEXT: nop
+;
+; LE-R6-LABEL: cmpxchg_result:
+; LE-R6: # %bb.0:
+; LE-R6-NEXT: move $3, $6
+; LE-R6-NEXT: move $1, $5
+; LE-R6-NEXT: move $2, $4
+; LE-R6-NEXT: sll $2, $2, 0
+; LE-R6-NEXT: addiu $4, $zero, -4
+; LE-R6-NEXT: and $6, $2, $4
+; LE-R6-NEXT: andi $2, $2, 3
+; LE-R6-NEXT: sll $2, $2, 3
+; LE-R6-NEXT: ori $4, $zero, 65535
+; LE-R6-NEXT: sllv $4, $4, $2
+; LE-R6-NEXT: sllv $1, $1, $2
+; LE-R6-NEXT: sllv $7, $3, $2
+; LE-R6-NEXT: sync
+; LE-R6-NEXT: .LBB1_1: # =>This Inner Loop Header: Depth=1
+; LE-R6-NEXT: ll $3, 0($6)
+; LE-R6-NEXT: and $5, $3, $4
+; LE-R6-NEXT: bnec $5, $1, .LBB1_3
+; LE-R6-NEXT: # %bb.2: # in Loop: Header=BB1_1 Depth=1
+; LE-R6-NEXT: xor $5, $3, $5
+; LE-R6-NEXT: or $5, $5, $7
+; LE-R6-NEXT: sc $5, 0($6)
+; LE-R6-NEXT: beqzc $5, .LBB1_1
+; LE-R6-NEXT: .LBB1_3:
+; LE-R6-NEXT: sync
+; LE-R6-NEXT: srlv $2, $3, $2
+; LE-R6-NEXT: and $3, $3, $4
+; LE-R6-NEXT: xor $1, $1, $3
+; LE-R6-NEXT: sltiu $1, $1, 1
+; LE-R6-NEXT: ins $2, $1, 16, 16
+; LE-R6-NEXT: jrc $ra
+;
+; BE-R6-LABEL: cmpxchg_result:
+; BE-R6: # %bb.0:
+; BE-R6-NEXT: move $3, $6
+; BE-R6-NEXT: move $1, $5
+; BE-R6-NEXT: move $2, $4
+; BE-R6-NEXT: sll $2, $2, 0
+; BE-R6-NEXT: addiu $4, $zero, -4
+; BE-R6-NEXT: and $6, $2, $4
+; BE-R6-NEXT: andi $2, $2, 3
+; BE-R6-NEXT: xori $2, $2, 2
+; BE-R6-NEXT: sll $2, $2, 3
+; BE-R6-NEXT: ori $4, $zero, 65535
+; BE-R6-NEXT: sllv $4, $4, $2
+; BE-R6-NEXT: sllv $1, $1, $2
+; BE-R6-NEXT: sllv $7, $3, $2
+; BE-R6-NEXT: sync
+; BE-R6-NEXT: .LBB1_1: # =>This Inner Loop Header: Depth=1
+; BE-R6-NEXT: ll $3, 0($6)
+; BE-R6-NEXT: and $5, $3, $4
+; BE-R6-NEXT: bnec $5, $1, .LBB1_3
+; BE-R6-NEXT: # %bb.2: # in Loop: Header=BB1_1 Depth=1
+; BE-R6-NEXT: xor $5, $3, $5
+; BE-R6-NEXT: or $5, $5, $7
+; BE-R6-NEXT: sc $5, 0($6)
+; BE-R6-NEXT: beqzc $5, .LBB1_1
+; BE-R6-NEXT: .LBB1_3:
+; BE-R6-NEXT: sync
+; BE-R6-NEXT: srlv $2, $3, $2
+; BE-R6-NEXT: and $3, $3, $4
+; BE-R6-NEXT: xor $1, $1, $3
+; BE-R6-NEXT: sltiu $1, $1, 1
+; BE-R6-NEXT: ins $2, $1, 16, 16
+; BE-R6-NEXT: jrc $ra
+ %pair = cmpxchg ptr %ptr, i16 %cmp, i16 %val acq_rel acquire
+ %old = extractvalue { i16, i1 } %pair, 0
+ %ok = extractvalue { i16, i1 } %pair, 1
+ %old32 = zext i16 %old to i32
+ %ok32 = zext i1 %ok to i32
+ %flag = shl i32 %ok32, 16
+ %result = or i32 %old32, %flag
+ ret i32 %result
+}
+
+; Known alignment folds the address preparation and endian-dependent shifts.
+define zeroext i16 @aligned_xchg(ptr %ptr, i16 zeroext %val) {
+; LE-LABEL: aligned_xchg:
+; LE: # %bb.0:
+; LE-NEXT: sll $1, $4, 0
+; LE-NEXT: ori $2, $zero, 65535
+; LE-NEXT: .LBB2_1: # =>This Inner Loop Header: Depth=1
+; LE-NEXT: ll $3, 0($1)
+; LE-NEXT: xor $4, $3, $5
+; LE-NEXT: and $4, $4, $2
+; LE-NEXT: xor $4, $3, $4
+; LE-NEXT: sc $4, 0($1)
+; LE-NEXT: beqz $4, .LBB2_1
+; LE-NEXT: nop
+; LE-NEXT: # %bb.2:
+; LE-NEXT: jr $ra
+; LE-NEXT: andi $2, $3, 65535
+;
+; BE-LABEL: aligned_xchg:
+; BE: # %bb.0:
+; BE-NEXT: sll $1, $5, 16
+; BE-NEXT: sll $2, $4, 0
+; BE-NEXT: lui $3, 65535
+; BE-NEXT: .LBB2_1: # =>This Inner Loop Header: Depth=1
+; BE-NEXT: ll $4, 0($2)
+; BE-NEXT: xor $5, $4, $1
+; BE-NEXT: and $5, $5, $3
+; BE-NEXT: xor $5, $4, $5
+; BE-NEXT: sc $5, 0($2)
+; BE-NEXT: beqz $5, .LBB2_1
+; BE-NEXT: nop
+; BE-NEXT: # %bb.2:
+; BE-NEXT: jr $ra
+; BE-NEXT: srl $2, $4, 16
+;
+; LE-R6-LABEL: aligned_xchg:
+; LE-R6: # %bb.0:
+; LE-R6-NEXT: move $1, $4
+; LE-R6-NEXT: move $4, $5
+; LE-R6-NEXT: # kill: def $at killed $at killed $at_64
+; LE-R6-NEXT: sll $3, $1, 0
+; LE-R6-NEXT: ori $5, $zero, 65535
+; LE-R6-NEXT: .LBB2_1: # =>This Inner Loop Header: Depth=1
+; LE-R6-NEXT: ll $1, 0($3)
+; LE-R6-NEXT: xor $2, $1, $4
+; LE-R6-NEXT: and $2, $2, $5
+; LE-R6-NEXT: xor $2, $1, $2
+; LE-R6-NEXT: sc $2, 0($3)
+; LE-R6-NEXT: beqzc $2, .LBB2_1
+; LE-R6-NEXT: # %bb.2:
+; LE-R6-NEXT: andi $2, $1, 65535
+; LE-R6-NEXT: jrc $ra
+;
+; BE-R6-LABEL: aligned_xchg:
+; BE-R6: # %bb.0:
+; BE-R6-NEXT: move $1, $4
+; BE-R6-NEXT: sll $3, $1, 0
+; BE-R6-NEXT: move $1, $5
+; BE-R6-NEXT: sll $4, $1, 16
+; BE-R6-NEXT: lui $5, 65535
+; BE-R6-NEXT: .LBB2_1: # =>This Inner Loop Header: Depth=1
+; BE-R6-NEXT: ll $1, 0($3)
+; BE-R6-NEXT: xor $2, $1, $4
+; BE-R6-NEXT: and $2, $2, $5
+; BE-R6-NEXT: xor $2, $1, $2
+; BE-R6-NEXT: sc $2, 0($3)
+; BE-R6-NEXT: beqzc $2, .LBB2_1
+; BE-R6-NEXT: # %bb.2:
+; BE-R6-NEXT: srl $2, $1, 16
+; BE-R6-NEXT: jrc $ra
+ %old = atomicrmw xchg ptr %ptr, i16 %val monotonic, align 4
+ ret i16 %old
+}
diff --git a/llvm/test/CodeGen/Mips/atomic-min-max-64.ll b/llvm/test/CodeGen/Mips/atomic-min-max-64.ll
index f3308c4b6ad12e..b8dd0edecb1fb2 100644
--- a/llvm/test/CodeGen/Mips/atomic-min-max-64.ll
+++ b/llvm/test/CodeGen/Mips/atomic-min-max-64.ll
@@ -3,6 +3,9 @@
; RUN: llc -mtriple=mips64el-elf -O0 -mcpu=mips64r2 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=MIPS
; RUN: llc -mtriple=mips64-elf -O0 -mcpu=mips64r6 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=MIPSR6
; RUN: llc -mtriple=mips64el-elf -O0 -mcpu=mips64r6 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=MIPSR6
+; RUN: llc -mtriple=mips64el-elf -O0 -mcpu=mips3 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=MIPS3
+; RUN: llc -mtriple=mips64el-elf -target-abi=n32 -O0 -mcpu=mips64r2 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=N32
+; RUN: llc -mtriple=mips64el-elf -target-abi=n32 -O0 -mcpu=mips64r6 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=N32R6
define i64 @test_max(ptr nocapture %ptr, i64 signext %val) {
; MIPS-LABEL: test_max:
@@ -37,6 +40,66 @@ define i64 @test_max(ptr nocapture %ptr, i64 signext %val) {
; MIPSR6-NEXT: # %bb.2: # %entry
; MIPSR6-NEXT: sync
; MIPSR6-NEXT: jrc $ra
+;
+; MIPS3-LABEL: test_max:
+; MIPS3: # %bb.0: # %entry
+; MIPS3-NEXT: sync
+; MIPS3-NEXT: .LBB0_1: # %entry
+; MIPS3-NEXT: # =>This Inner Loop Header: Depth=1
+; MIPS3-NEXT: lld $2, 0($4)
+; MIPS3-NEXT: slt $3, $2, $5
+; MIPS3-NEXT: move $1, $2
+; MIPS3-NEXT: beqz $3, .LBB0_3
+; MIPS3-NEXT: nop
+; MIPS3-NEXT: # %bb.2: # %entry
+; MIPS3-NEXT: # in Loop: Header=BB0_1 Depth=1
+; MIPS3-NEXT: move $1, $5
+; MIPS3-NEXT: .LBB0_3: # %entry
+; MIPS3-NEXT: # in Loop: Header=BB0_1 Depth=1
+; MIPS3-NEXT: scd $1, 0($4)
+; MIPS3-NEXT: beqz $1, .LBB0_1
+; MIPS3-NEXT: nop
+; MIPS3-NEXT: # %bb.4: # %entry
+; MIPS3-NEXT: sync
+; MIPS3-NEXT: jr $ra
+; MIPS3-NEXT: nop
+;
+; N32-LABEL: test_max:
+; N32: # %bb.0: # %entry
+; N32-NEXT: move $1, $4
+; N32-NEXT: sll $4, $1, 0
+; N32-NEXT: sync
+; N32-NEXT: .LBB0_1: # %entry
+; N32-NEXT: # =>This Inner Loop Header: Depth=1
+; N32-NEXT: lld $2, 0($4)
+; N32-NEXT: slt $3, $2, $5
+; N32-NEXT: move $1, $2
+; N32-NEXT: movn $1, $5, $3
+; N32-NEXT: scd $1, 0($4)
+; N32-NEXT: beqz $1, .LBB0_1
+; N32-NEXT: nop
+; N32-NEXT: # %bb.2: # %entry
+; N32-NEXT: sync
+; N32-NEXT: jr $ra
+; N32-NEXT: nop
+;
+; N32R6-LABEL: test_max:
+; N32R6: # %bb.0: # %entry
+; N32R6-NEXT: move $1, $4
+; N32R6-NEXT: sll $4, $1, 0
+; N32R6-NEXT: sync
+; N32R6-NEXT: .LBB0_1: # %entry
+; N32R6-NEXT: # =>This Inner Loop Header: Depth=1
+; N32R6-NEXT: lld $2, 0($4)
+; N32R6-NEXT: slt $3, $2, $5
+; N32R6-NEXT: seleqz $1, $2, $3
+; N32R6-NEXT: selnez $3, $5, $3
+; N32R6-NEXT: or $1, $1, $3
+; N32R6-NEXT: scd $1, 0($4)
+; N32R6-NEXT: beqzc $1, .LBB0_1
+; N32R6-NEXT: # %bb.2: # %entry
+; N32R6-NEXT: sync
+; N32R6-NEXT: jrc $ra
entry:
%0 = atomicrmw max ptr %ptr, i64 %val seq_cst
ret i64 %0
@@ -49,9 +112,9 @@ define i64 @test_min(ptr nocapture %ptr, i64 signext %val) {
; MIPS-NEXT: .LBB1_1: # %entry
; MIPS-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS-NEXT: lld $2, 0($4)
-; MIPS-NEXT: slt $3, $2, $5
+; MIPS-NEXT: slt $3, $5, $2
; MIPS-NEXT: move $1, $2
-; MIPS-NEXT: movz $1, $5, $3
+; MIPS-NEXT: movn $1, $5, $3
; MIPS-NEXT: scd $1, 0($4)
; MIPS-NEXT: beqz $1, .LBB1_1
; MIPS-NEXT: nop
@@ -66,15 +129,75 @@ define i64 @test_min(ptr nocapture %ptr, i64 signext %val) {
; MIPSR6-NEXT: .LBB1_1: # %entry
; MIPSR6-NEXT: # =>This Inner Loop Header: Depth=1
; MIPSR6-NEXT: lld $2, 0($4)
-; MIPSR6-NEXT: slt $3, $2, $5
-; MIPSR6-NEXT: selnez $1, $2, $3
-; MIPSR6-NEXT: seleqz $3, $5, $3
+; MIPSR6-NEXT: slt $3, $5, $2
+; MIPSR6-NEXT: seleqz $1, $2, $3
+; MIPSR6-NEXT: selnez $3, $5, $3
; MIPSR6-NEXT: or $1, $1, $3
; MIPSR6-NEXT: scd $1, 0($4)
; MIPSR6-NEXT: beqzc $1, .LBB1_1
; MIPSR6-NEXT: # %bb.2: # %entry
; MIPSR6-NEXT: sync
; MIPSR6-NEXT: jrc $ra
+;
+; MIPS3-LABEL: test_min:
+; MIPS3: # %bb.0: # %entry
+; MIPS3-NEXT: sync
+; MIPS3-NEXT: .LBB1_1: # %entry
+; MIPS3-NEXT: # =>This Inner Loop Header: Depth=1
+; MIPS3-NEXT: lld $2, 0($4)
+; MIPS3-NEXT: slt $3, $5, $2
+; MIPS3-NEXT: move $1, $2
+; MIPS3-NEXT: beqz $3, .LBB1_3
+; MIPS3-NEXT: nop
+; MIPS3-NEXT: # %bb.2: # %entry
+; MIPS3-NEXT: # in Loop: Header=BB1_1 Depth=1
+; MIPS3-NEXT: move $1, $5
+; MIPS3-NEXT: .LBB1_3: # %entry
+; MIPS3-NEXT: # in Loop: Header=BB1_1 Depth=1
+; MIPS3-NEXT: scd $1, 0($4)
+; MIPS3-NEXT: beqz $1, .LBB1_1
+; MIPS3-NEXT: nop
+; MIPS3-NEXT: # %bb.4: # %entry
+; MIPS3-NEXT: sync
+; MIPS3-NEXT: jr $ra
+; MIPS3-NEXT: nop
+;
+; N32-LABEL: test_min:
+; N32: # %bb.0: # %entry
+; N32-NEXT: move $1, $4
+; N32-NEXT: sll $4, $1, 0
+; N32-NEXT: sync
+; N32-NEXT: .LBB1_1: # %entry
+; N32-NEXT: # =>This Inner Loop Header: Depth=1
+; N32-NEXT: lld $2, 0($4)
+; N32-NEXT: slt $3, $5, $2
+; N32-NEXT: move $1, $2
+; N32-NEXT: movn $1, $5, $3
+; N32-NEXT: scd $1, 0($4)
+; N32-NEXT: beqz $1, .LBB1_1
+; N32-NEXT: nop
+; N32-NEXT: # %bb.2: # %entry
+; N32-NEXT: sync
+; N32-NEXT: jr $ra
+; N32-NEXT: nop
+;
+; N32R6-LABEL: test_min:
+; N32R6: # %bb.0: # %entry
+; N32R6-NEXT: move $1, $4
+; N32R6-NEXT: sll $4, $1, 0
+; N32R6-NEXT: sync
+; N32R6-NEXT: .LBB1_1: # %entry
+; N32R6-NEXT: # =>This Inner Loop Header: Depth=1
+; N32R6-NEXT: lld $2, 0($4)
+; N32R6-NEXT: slt $3, $5, $2
+; N32R6-NEXT: seleqz $1, $2, $3
+; N32R6-NEXT: selnez $3, $5, $3
+; N32R6-NEXT: or $1, $1, $3
+; N32R6-NEXT: scd $1, 0($4)
+; N32R6-NEXT: beqzc $1, .LBB1_1
+; N32R6-NEXT: # %bb.2: # %entry
+; N32R6-NEXT: sync
+; N32R6-NEXT: jrc $ra
entry:
%0 = atomicrmw min ptr %ptr, i64 %val seq_cst
ret i64 %0
@@ -113,6 +236,66 @@ define i64 @test_umax(ptr nocapture %ptr, i64 zeroext %val) {
; MIPSR6-NEXT: # %bb.2: # %entry
; MIPSR6-NEXT: sync
; MIPSR6-NEXT: jrc $ra
+;
+; MIPS3-LABEL: test_umax:
+; MIPS3: # %bb.0: # %entry
+; MIPS3-NEXT: sync
+; MIPS3-NEXT: .LBB2_1: # %entry
+; MIPS3-NEXT: # =>This Inner Loop Header: Depth=1
+; MIPS3-NEXT: lld $2, 0($4)
+; MIPS3-NEXT: sltu $3, $2, $5
+; MIPS3-NEXT: move $1, $2
+; MIPS3-NEXT: beqz $3, .LBB2_3
+; MIPS3-NEXT: nop
+; MIPS3-NEXT: # %bb.2: # %entry
+; MIPS3-NEXT: # in Loop: Header=BB2_1 Depth=1
+; MIPS3-NEXT: move $1, $5
+; MIPS3-NEXT: .LBB2_3: # %entry
+; MIPS3-NEXT: # in Loop: Header=BB2_1 Depth=1
+; MIPS3-NEXT: scd $1, 0($4)
+; MIPS3-NEXT: beqz $1, .LBB2_1
+; MIPS3-NEXT: nop
+; MIPS3-NEXT: # %bb.4: # %entry
+; MIPS3-NEXT: sync
+; MIPS3-NEXT: jr $ra
+; MIPS3-NEXT: nop
+;
+; N32-LABEL: test_umax:
+; N32: # %bb.0: # %entry
+; N32-NEXT: move $1, $4
+; N32-NEXT: sll $4, $1, 0
+; N32-NEXT: sync
+; N32-NEXT: .LBB2_1: # %entry
+; N32-NEXT: # =>This Inner Loop Header: Depth=1
+; N32-NEXT: lld $2, 0($4)
+; N32-NEXT: sltu $3, $2, $5
+; N32-NEXT: move $1, $2
+; N32-NEXT: movn $1, $5, $3
+; N32-NEXT: scd $1, 0($4)
+; N32-NEXT: beqz $1, .LBB2_1
+; N32-NEXT: nop
+; N32-NEXT: # %bb.2: # %entry
+; N32-NEXT: sync
+; N32-NEXT: jr $ra
+; N32-NEXT: nop
+;
+; N32R6-LABEL: test_umax:
+; N32R6: # %bb.0: # %entry
+; N32R6-NEXT: move $1, $4
+; N32R6-NEXT: sll $4, $1, 0
+; N32R6-NEXT: sync
+; N32R6-NEXT: .LBB2_1: # %entry
+; N32R6-NEXT: # =>This Inner Loop Header: Depth=1
+; N32R6-NEXT: lld $2, 0($4)
+; N32R6-NEXT: sltu $3, $2, $5
+; N32R6-NEXT: seleqz $1, $2, $3
+; N32R6-NEXT: selnez $3, $5, $3
+; N32R6-NEXT: or $1, $1, $3
+; N32R6-NEXT: scd $1, 0($4)
+; N32R6-NEXT: beqzc $1, .LBB2_1
+; N32R6-NEXT: # %bb.2: # %entry
+; N32R6-NEXT: sync
+; N32R6-NEXT: jrc $ra
entry:
%0 = atomicrmw umax ptr %ptr, i64 %val seq_cst
ret i64 %0
@@ -125,9 +308,9 @@ define i64 @test_umin(ptr nocapture %ptr, i64 zeroext %val) {
; MIPS-NEXT: .LBB3_1: # %entry
; MIPS-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS-NEXT: lld $2, 0($4)
-; MIPS-NEXT: sltu $3, $2, $5
+; MIPS-NEXT: sltu $3, $5, $2
; MIPS-NEXT: move $1, $2
-; MIPS-NEXT: movz $1, $5, $3
+; MIPS-NEXT: movn $1, $5, $3
; MIPS-NEXT: scd $1, 0($4)
; MIPS-NEXT: beqz $1, .LBB3_1
; MIPS-NEXT: nop
@@ -142,15 +325,75 @@ define i64 @test_umin(ptr nocapture %ptr, i64 zeroext %val) {
; MIPSR6-NEXT: .LBB3_1: # %entry
; MIPSR6-NEXT: # =>This Inner Loop Header: Depth=1
; MIPSR6-NEXT: lld $2, 0($4)
-; MIPSR6-NEXT: sltu $3, $2, $5
-; MIPSR6-NEXT: selnez $1, $2, $3
-; MIPSR6-NEXT: seleqz $3, $5, $3
+; MIPSR6-NEXT: sltu $3, $5, $2
+; MIPSR6-NEXT: seleqz $1, $2, $3
+; MIPSR6-NEXT: selnez $3, $5, $3
; MIPSR6-NEXT: or $1, $1, $3
; MIPSR6-NEXT: scd $1, 0($4)
; MIPSR6-NEXT: beqzc $1, .LBB3_1
; MIPSR6-NEXT: # %bb.2: # %entry
; MIPSR6-NEXT: sync
; MIPSR6-NEXT: jrc $ra
+;
+; MIPS3-LABEL: test_umin:
+; MIPS3: # %bb.0: # %entry
+; MIPS3-NEXT: sync
+; MIPS3-NEXT: .LBB3_1: # %entry
+; MIPS3-NEXT: # =>This Inner Loop Header: Depth=1
+; MIPS3-NEXT: lld $2, 0($4)
+; MIPS3-NEXT: sltu $3, $5, $2
+; MIPS3-NEXT: move $1, $2
+; MIPS3-NEXT: beqz $3, .LBB3_3
+; MIPS3-NEXT: nop
+; MIPS3-NEXT: # %bb.2: # %entry
+; MIPS3-NEXT: # in Loop: Header=BB3_1 Depth=1
+; MIPS3-NEXT: move $1, $5
+; MIPS3-NEXT: .LBB3_3: # %entry
+; MIPS3-NEXT: # in Loop: Header=BB3_1 Depth=1
+; MIPS3-NEXT: scd $1, 0($4)
+; MIPS3-NEXT: beqz $1, .LBB3_1
+; MIPS3-NEXT: nop
+; MIPS3-NEXT: # %bb.4: # %entry
+; MIPS3-NEXT: sync
+; MIPS3-NEXT: jr $ra
+; MIPS3-NEXT: nop
+;
+; N32-LABEL: test_umin:
+; N32: # %bb.0: # %entry
+; N32-NEXT: move $1, $4
+; N32-NEXT: sll $4, $1, 0
+; N32-NEXT: sync
+; N32-NEXT: .LBB3_1: # %entry
+; N32-NEXT: # =>This Inner Loop Header: Depth=1
+; N32-NEXT: lld $2, 0($4)
+; N32-NEXT: sltu $3, $5, $2
+; N32-NEXT: move $1, $2
+; N32-NEXT: movn $1, $5, $3
+; N32-NEXT: scd $1, 0($4)
+; N32-NEXT: beqz $1, .LBB3_1
+; N32-NEXT: nop
+; N32-NEXT: # %bb.2: # %entry
+; N32-NEXT: sync
+; N32-NEXT: jr $ra
+; N32-NEXT: nop
+;
+; N32R6-LABEL: test_umin:
+; N32R6: # %bb.0: # %entry
+; N32R6-NEXT: move $1, $4
+; N32R6-NEXT: sll $4, $1, 0
+; N32R6-NEXT: sync
+; N32R6-NEXT: .LBB3_1: # %entry
+; N32R6-NEXT: # =>This Inner Loop Header: Depth=1
+; N32R6-NEXT: lld $2, 0($4)
+; N32R6-NEXT: sltu $3, $5, $2
+; N32R6-NEXT: seleqz $1, $2, $3
+; N32R6-NEXT: selnez $3, $5, $3
+; N32R6-NEXT: or $1, $1, $3
+; N32R6-NEXT: scd $1, 0($4)
+; N32R6-NEXT: beqzc $1, .LBB3_1
+; N32R6-NEXT: # %bb.2: # %entry
+; N32R6-NEXT: sync
+; N32R6-NEXT: jrc $ra
entry:
%0 = atomicrmw umin ptr %ptr, i64 %val seq_cst
ret i64 %0
diff --git a/llvm/test/CodeGen/Mips/atomic-min-max.ll b/llvm/test/CodeGen/Mips/atomic-min-max.ll
index 5849ba13cc37a1..7bbb0c58fbf396 100644
--- a/llvm/test/CodeGen/Mips/atomic-min-max.ll
+++ b/llvm/test/CodeGen/Mips/atomic-min-max.ll
@@ -32,33 +32,6 @@ define i32 @test_max_32(ptr nocapture %ptr, i32 signext %val) {
; MIPS-NEXT: jr $ra
; MIPS-NEXT: nop
;
-; MIPS2-LABEL: test_max_32:
-; MIPS2: # %bb.0: # %entry
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: $BB0_1: # %entry
-; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS2-NEXT: ll $2, 0($4)
-; MIPS2-NEXT: slt $3, $2, $5
-; MIPS2-NEXT: move $1, $5
-; MIPS2-NEXT: beqz $3, $BB0_3
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.2: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB0_1 Depth=1
-; MIPS2-NEXT: j $BB0_4
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: $BB0_3: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB0_1 Depth=1
-; MIPS2-NEXT: move $1, $2
-; MIPS2-NEXT: $BB0_4: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB0_1 Depth=1
-; MIPS2-NEXT: sc $1, 0($4)
-; MIPS2-NEXT: beqz $1, $BB0_1
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.5: # %entry
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: jr $ra
-; MIPS2-NEXT: nop
-;
; MIPSR6-LABEL: test_max_32:
; MIPSR6: # %bb.0: # %entry
; MIPSR6-NEXT: sync
@@ -106,6 +79,29 @@ define i32 @test_max_32(ptr nocapture %ptr, i32 signext %val) {
; MMR6-NEXT: sync
; MMR6-NEXT: jrc $ra
;
+; MIPS2-LABEL: test_max_32:
+; MIPS2: # %bb.0: # %entry
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: $BB0_1: # %entry
+; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
+; MIPS2-NEXT: ll $2, 0($4)
+; MIPS2-NEXT: slt $3, $2, $5
+; MIPS2-NEXT: move $1, $2
+; MIPS2-NEXT: beqz $3, $BB0_3
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.2: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB0_1 Depth=1
+; MIPS2-NEXT: move $1, $5
+; MIPS2-NEXT: $BB0_3: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB0_1 Depth=1
+; MIPS2-NEXT: sc $1, 0($4)
+; MIPS2-NEXT: beqz $1, $BB0_1
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.4: # %entry
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: jr $ra
+; MIPS2-NEXT: nop
+;
; MIPS32-LABEL: test_max_32:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: sync
@@ -268,9 +264,9 @@ define i32 @test_min_32(ptr nocapture %ptr, i32 signext %val) {
; MIPS-NEXT: $BB1_1: # %entry
; MIPS-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS-NEXT: ll $2, 0($4)
-; MIPS-NEXT: slt $3, $2, $5
+; MIPS-NEXT: slt $3, $5, $2
; MIPS-NEXT: move $1, $2
-; MIPS-NEXT: movz $1, $5, $3
+; MIPS-NEXT: movn $1, $5, $3
; MIPS-NEXT: sc $1, 0($4)
; MIPS-NEXT: beqz $1, $BB1_1
; MIPS-NEXT: nop
@@ -279,42 +275,15 @@ define i32 @test_min_32(ptr nocapture %ptr, i32 signext %val) {
; MIPS-NEXT: jr $ra
; MIPS-NEXT: nop
;
-; MIPS2-LABEL: test_min_32:
-; MIPS2: # %bb.0: # %entry
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: $BB1_1: # %entry
-; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS2-NEXT: ll $2, 0($4)
-; MIPS2-NEXT: slt $3, $2, $5
-; MIPS2-NEXT: move $1, $2
-; MIPS2-NEXT: beqz $3, $BB1_3
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.2: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB1_1 Depth=1
-; MIPS2-NEXT: j $BB1_4
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: $BB1_3: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB1_1 Depth=1
-; MIPS2-NEXT: move $1, $5
-; MIPS2-NEXT: $BB1_4: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB1_1 Depth=1
-; MIPS2-NEXT: sc $1, 0($4)
-; MIPS2-NEXT: beqz $1, $BB1_1
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.5: # %entry
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: jr $ra
-; MIPS2-NEXT: nop
-;
; MIPSR6-LABEL: test_min_32:
; MIPSR6: # %bb.0: # %entry
; MIPSR6-NEXT: sync
; MIPSR6-NEXT: $BB1_1: # %entry
; MIPSR6-NEXT: # =>This Inner Loop Header: Depth=1
; MIPSR6-NEXT: ll $2, 0($4)
-; MIPSR6-NEXT: slt $3, $2, $5
-; MIPSR6-NEXT: selnez $1, $2, $3
-; MIPSR6-NEXT: seleqz $3, $5, $3
+; MIPSR6-NEXT: slt $3, $5, $2
+; MIPSR6-NEXT: seleqz $1, $2, $3
+; MIPSR6-NEXT: selnez $3, $5, $3
; MIPSR6-NEXT: or $1, $1, $3
; MIPSR6-NEXT: sc $1, 0($4)
; MIPSR6-NEXT: beqzc $1, $BB1_1
@@ -328,9 +297,9 @@ define i32 @test_min_32(ptr nocapture %ptr, i32 signext %val) {
; MM-NEXT: $BB1_1: # %entry
; MM-NEXT: # =>This Inner Loop Header: Depth=1
; MM-NEXT: ll $2, 0($4)
-; MM-NEXT: slt $3, $2, $5
+; MM-NEXT: slt $3, $5, $2
; MM-NEXT: or $1, $2, $zero
-; MM-NEXT: movz $1, $5, $3
+; MM-NEXT: movn $1, $5, $3
; MM-NEXT: sc $1, 0($4)
; MM-NEXT: beqzc $1, $BB1_1
; MM-NEXT: # %bb.2: # %entry
@@ -343,9 +312,9 @@ define i32 @test_min_32(ptr nocapture %ptr, i32 signext %val) {
; MMR6-NEXT: $BB1_1: # %entry
; MMR6-NEXT: # =>This Inner Loop Header: Depth=1
; MMR6-NEXT: ll $2, 0($4)
-; MMR6-NEXT: slt $3, $2, $5
-; MMR6-NEXT: selnez $1, $2, $3
-; MMR6-NEXT: seleqz $3, $5, $3
+; MMR6-NEXT: slt $3, $5, $2
+; MMR6-NEXT: seleqz $1, $2, $3
+; MMR6-NEXT: selnez $3, $5, $3
; MMR6-NEXT: or $1, $1, $3
; MMR6-NEXT: sc $1, 0($4)
; MMR6-NEXT: beqc $1, $zero, $BB1_1
@@ -353,15 +322,38 @@ define i32 @test_min_32(ptr nocapture %ptr, i32 signext %val) {
; MMR6-NEXT: sync
; MMR6-NEXT: jrc $ra
;
+; MIPS2-LABEL: test_min_32:
+; MIPS2: # %bb.0: # %entry
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: $BB1_1: # %entry
+; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
+; MIPS2-NEXT: ll $2, 0($4)
+; MIPS2-NEXT: slt $3, $5, $2
+; MIPS2-NEXT: move $1, $2
+; MIPS2-NEXT: beqz $3, $BB1_3
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.2: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB1_1 Depth=1
+; MIPS2-NEXT: move $1, $5
+; MIPS2-NEXT: $BB1_3: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB1_1 Depth=1
+; MIPS2-NEXT: sc $1, 0($4)
+; MIPS2-NEXT: beqz $1, $BB1_1
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.4: # %entry
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: jr $ra
+; MIPS2-NEXT: nop
+;
; MIPS32-LABEL: test_min_32:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: sync
; MIPS32-NEXT: $BB1_1: # %entry
; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS32-NEXT: ll $2, 0($4)
-; MIPS32-NEXT: slt $3, $2, $5
+; MIPS32-NEXT: slt $3, $5, $2
; MIPS32-NEXT: move $1, $2
-; MIPS32-NEXT: movz $1, $5, $3
+; MIPS32-NEXT: movn $1, $5, $3
; MIPS32-NEXT: sc $1, 0($4)
; MIPS32-NEXT: beqz $1, $BB1_1
; MIPS32-NEXT: nop
@@ -376,9 +368,9 @@ define i32 @test_min_32(ptr nocapture %ptr, i32 signext %val) {
; MIPSEL-NEXT: $BB1_1: # %entry
; MIPSEL-NEXT: # =>This Inner Loop Header: Depth=1
; MIPSEL-NEXT: ll $2, 0($4)
-; MIPSEL-NEXT: slt $3, $2, $5
+; MIPSEL-NEXT: slt $3, $5, $2
; MIPSEL-NEXT: move $1, $2
-; MIPSEL-NEXT: movz $1, $5, $3
+; MIPSEL-NEXT: movn $1, $5, $3
; MIPSEL-NEXT: sc $1, 0($4)
; MIPSEL-NEXT: beqz $1, $BB1_1
; MIPSEL-NEXT: nop
@@ -393,9 +385,9 @@ define i32 @test_min_32(ptr nocapture %ptr, i32 signext %val) {
; MIPSELR6-NEXT: $BB1_1: # %entry
; MIPSELR6-NEXT: # =>This Inner Loop Header: Depth=1
; MIPSELR6-NEXT: ll $2, 0($4)
-; MIPSELR6-NEXT: slt $3, $2, $5
-; MIPSELR6-NEXT: selnez $1, $2, $3
-; MIPSELR6-NEXT: seleqz $3, $5, $3
+; MIPSELR6-NEXT: slt $3, $5, $2
+; MIPSELR6-NEXT: seleqz $1, $2, $3
+; MIPSELR6-NEXT: selnez $3, $5, $3
; MIPSELR6-NEXT: or $1, $1, $3
; MIPSELR6-NEXT: sc $1, 0($4)
; MIPSELR6-NEXT: beqzc $1, $BB1_1
@@ -409,9 +401,9 @@ define i32 @test_min_32(ptr nocapture %ptr, i32 signext %val) {
; MMEL-NEXT: $BB1_1: # %entry
; MMEL-NEXT: # =>This Inner Loop Header: Depth=1
; MMEL-NEXT: ll $2, 0($4)
-; MMEL-NEXT: slt $3, $2, $5
+; MMEL-NEXT: slt $3, $5, $2
; MMEL-NEXT: or $1, $2, $zero
-; MMEL-NEXT: movz $1, $5, $3
+; MMEL-NEXT: movn $1, $5, $3
; MMEL-NEXT: sc $1, 0($4)
; MMEL-NEXT: beqzc $1, $BB1_1
; MMEL-NEXT: # %bb.2: # %entry
@@ -424,9 +416,9 @@ define i32 @test_min_32(ptr nocapture %ptr, i32 signext %val) {
; MMELR6-NEXT: $BB1_1: # %entry
; MMELR6-NEXT: # =>This Inner Loop Header: Depth=1
; MMELR6-NEXT: ll $2, 0($4)
-; MMELR6-NEXT: slt $3, $2, $5
-; MMELR6-NEXT: selnez $1, $2, $3
-; MMELR6-NEXT: seleqz $3, $5, $3
+; MMELR6-NEXT: slt $3, $5, $2
+; MMELR6-NEXT: seleqz $1, $2, $3
+; MMELR6-NEXT: selnez $3, $5, $3
; MMELR6-NEXT: or $1, $1, $3
; MMELR6-NEXT: sc $1, 0($4)
; MMELR6-NEXT: beqc $1, $zero, $BB1_1
@@ -441,9 +433,9 @@ define i32 @test_min_32(ptr nocapture %ptr, i32 signext %val) {
; MIPS64-NEXT: .LBB1_1: # %entry
; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS64-NEXT: ll $2, 0($4)
-; MIPS64-NEXT: slt $3, $2, $5
+; MIPS64-NEXT: slt $3, $5, $2
; MIPS64-NEXT: move $1, $2
-; MIPS64-NEXT: movz $1, $5, $3
+; MIPS64-NEXT: movn $1, $5, $3
; MIPS64-NEXT: sc $1, 0($4)
; MIPS64-NEXT: beqz $1, .LBB1_1
; MIPS64-NEXT: nop
@@ -459,9 +451,9 @@ define i32 @test_min_32(ptr nocapture %ptr, i32 signext %val) {
; MIPS64R6-NEXT: .LBB1_1: # %entry
; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS64R6-NEXT: ll $2, 0($4)
-; MIPS64R6-NEXT: slt $3, $2, $5
-; MIPS64R6-NEXT: selnez $1, $2, $3
-; MIPS64R6-NEXT: seleqz $3, $5, $3
+; MIPS64R6-NEXT: slt $3, $5, $2
+; MIPS64R6-NEXT: seleqz $1, $2, $3
+; MIPS64R6-NEXT: selnez $3, $5, $3
; MIPS64R6-NEXT: or $1, $1, $3
; MIPS64R6-NEXT: sc $1, 0($4)
; MIPS64R6-NEXT: beqzc $1, .LBB1_1
@@ -476,9 +468,9 @@ define i32 @test_min_32(ptr nocapture %ptr, i32 signext %val) {
; MIPS64EL-NEXT: .LBB1_1: # %entry
; MIPS64EL-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS64EL-NEXT: ll $2, 0($4)
-; MIPS64EL-NEXT: slt $3, $2, $5
+; MIPS64EL-NEXT: slt $3, $5, $2
; MIPS64EL-NEXT: move $1, $2
-; MIPS64EL-NEXT: movz $1, $5, $3
+; MIPS64EL-NEXT: movn $1, $5, $3
; MIPS64EL-NEXT: sc $1, 0($4)
; MIPS64EL-NEXT: beqz $1, .LBB1_1
; MIPS64EL-NEXT: nop
@@ -494,9 +486,9 @@ define i32 @test_min_32(ptr nocapture %ptr, i32 signext %val) {
; MIPS64ELR6-NEXT: .LBB1_1: # %entry
; MIPS64ELR6-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS64ELR6-NEXT: ll $2, 0($4)
-; MIPS64ELR6-NEXT: slt $3, $2, $5
-; MIPS64ELR6-NEXT: selnez $1, $2, $3
-; MIPS64ELR6-NEXT: seleqz $3, $5, $3
+; MIPS64ELR6-NEXT: slt $3, $5, $2
+; MIPS64ELR6-NEXT: seleqz $1, $2, $3
+; MIPS64ELR6-NEXT: selnez $3, $5, $3
; MIPS64ELR6-NEXT: or $1, $1, $3
; MIPS64ELR6-NEXT: sc $1, 0($4)
; MIPS64ELR6-NEXT: beqzc $1, .LBB1_1
@@ -526,33 +518,6 @@ define i32 @test_umax_32(ptr nocapture %ptr, i32 signext %val) {
; MIPS-NEXT: jr $ra
; MIPS-NEXT: nop
;
-; MIPS2-LABEL: test_umax_32:
-; MIPS2: # %bb.0: # %entry
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: $BB2_1: # %entry
-; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS2-NEXT: ll $2, 0($4)
-; MIPS2-NEXT: sltu $3, $2, $5
-; MIPS2-NEXT: move $1, $5
-; MIPS2-NEXT: beqz $3, $BB2_3
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.2: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB2_1 Depth=1
-; MIPS2-NEXT: j $BB2_4
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: $BB2_3: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB2_1 Depth=1
-; MIPS2-NEXT: move $1, $2
-; MIPS2-NEXT: $BB2_4: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB2_1 Depth=1
-; MIPS2-NEXT: sc $1, 0($4)
-; MIPS2-NEXT: beqz $1, $BB2_1
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.5: # %entry
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: jr $ra
-; MIPS2-NEXT: nop
-;
; MIPSR6-LABEL: test_umax_32:
; MIPSR6: # %bb.0: # %entry
; MIPSR6-NEXT: sync
@@ -600,6 +565,29 @@ define i32 @test_umax_32(ptr nocapture %ptr, i32 signext %val) {
; MMR6-NEXT: sync
; MMR6-NEXT: jrc $ra
;
+; MIPS2-LABEL: test_umax_32:
+; MIPS2: # %bb.0: # %entry
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: $BB2_1: # %entry
+; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
+; MIPS2-NEXT: ll $2, 0($4)
+; MIPS2-NEXT: sltu $3, $2, $5
+; MIPS2-NEXT: move $1, $2
+; MIPS2-NEXT: beqz $3, $BB2_3
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.2: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB2_1 Depth=1
+; MIPS2-NEXT: move $1, $5
+; MIPS2-NEXT: $BB2_3: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB2_1 Depth=1
+; MIPS2-NEXT: sc $1, 0($4)
+; MIPS2-NEXT: beqz $1, $BB2_1
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.4: # %entry
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: jr $ra
+; MIPS2-NEXT: nop
+;
; MIPS32-LABEL: test_umax_32:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: sync
@@ -762,9 +750,9 @@ define i32 @test_umin_32(ptr nocapture %ptr, i32 signext %val) {
; MIPS-NEXT: $BB3_1: # %entry
; MIPS-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS-NEXT: ll $2, 0($4)
-; MIPS-NEXT: sltu $3, $2, $5
+; MIPS-NEXT: sltu $3, $5, $2
; MIPS-NEXT: move $1, $2
-; MIPS-NEXT: movz $1, $5, $3
+; MIPS-NEXT: movn $1, $5, $3
; MIPS-NEXT: sc $1, 0($4)
; MIPS-NEXT: beqz $1, $BB3_1
; MIPS-NEXT: nop
@@ -773,42 +761,15 @@ define i32 @test_umin_32(ptr nocapture %ptr, i32 signext %val) {
; MIPS-NEXT: jr $ra
; MIPS-NEXT: nop
;
-; MIPS2-LABEL: test_umin_32:
-; MIPS2: # %bb.0: # %entry
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: $BB3_1: # %entry
-; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS2-NEXT: ll $2, 0($4)
-; MIPS2-NEXT: sltu $3, $2, $5
-; MIPS2-NEXT: move $1, $2
-; MIPS2-NEXT: beqz $3, $BB3_3
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.2: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB3_1 Depth=1
-; MIPS2-NEXT: j $BB3_4
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: $BB3_3: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB3_1 Depth=1
-; MIPS2-NEXT: move $1, $5
-; MIPS2-NEXT: $BB3_4: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB3_1 Depth=1
-; MIPS2-NEXT: sc $1, 0($4)
-; MIPS2-NEXT: beqz $1, $BB3_1
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.5: # %entry
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: jr $ra
-; MIPS2-NEXT: nop
-;
; MIPSR6-LABEL: test_umin_32:
; MIPSR6: # %bb.0: # %entry
; MIPSR6-NEXT: sync
; MIPSR6-NEXT: $BB3_1: # %entry
; MIPSR6-NEXT: # =>This Inner Loop Header: Depth=1
; MIPSR6-NEXT: ll $2, 0($4)
-; MIPSR6-NEXT: sltu $3, $2, $5
-; MIPSR6-NEXT: selnez $1, $2, $3
-; MIPSR6-NEXT: seleqz $3, $5, $3
+; MIPSR6-NEXT: sltu $3, $5, $2
+; MIPSR6-NEXT: seleqz $1, $2, $3
+; MIPSR6-NEXT: selnez $3, $5, $3
; MIPSR6-NEXT: or $1, $1, $3
; MIPSR6-NEXT: sc $1, 0($4)
; MIPSR6-NEXT: beqzc $1, $BB3_1
@@ -822,9 +783,9 @@ define i32 @test_umin_32(ptr nocapture %ptr, i32 signext %val) {
; MM-NEXT: $BB3_1: # %entry
; MM-NEXT: # =>This Inner Loop Header: Depth=1
; MM-NEXT: ll $2, 0($4)
-; MM-NEXT: sltu $3, $2, $5
+; MM-NEXT: sltu $3, $5, $2
; MM-NEXT: or $1, $2, $zero
-; MM-NEXT: movz $1, $5, $3
+; MM-NEXT: movn $1, $5, $3
; MM-NEXT: sc $1, 0($4)
; MM-NEXT: beqzc $1, $BB3_1
; MM-NEXT: # %bb.2: # %entry
@@ -837,9 +798,9 @@ define i32 @test_umin_32(ptr nocapture %ptr, i32 signext %val) {
; MMR6-NEXT: $BB3_1: # %entry
; MMR6-NEXT: # =>This Inner Loop Header: Depth=1
; MMR6-NEXT: ll $2, 0($4)
-; MMR6-NEXT: sltu $3, $2, $5
-; MMR6-NEXT: selnez $1, $2, $3
-; MMR6-NEXT: seleqz $3, $5, $3
+; MMR6-NEXT: sltu $3, $5, $2
+; MMR6-NEXT: seleqz $1, $2, $3
+; MMR6-NEXT: selnez $3, $5, $3
; MMR6-NEXT: or $1, $1, $3
; MMR6-NEXT: sc $1, 0($4)
; MMR6-NEXT: beqc $1, $zero, $BB3_1
@@ -847,15 +808,38 @@ define i32 @test_umin_32(ptr nocapture %ptr, i32 signext %val) {
; MMR6-NEXT: sync
; MMR6-NEXT: jrc $ra
;
+; MIPS2-LABEL: test_umin_32:
+; MIPS2: # %bb.0: # %entry
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: $BB3_1: # %entry
+; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
+; MIPS2-NEXT: ll $2, 0($4)
+; MIPS2-NEXT: sltu $3, $5, $2
+; MIPS2-NEXT: move $1, $2
+; MIPS2-NEXT: beqz $3, $BB3_3
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.2: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB3_1 Depth=1
+; MIPS2-NEXT: move $1, $5
+; MIPS2-NEXT: $BB3_3: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB3_1 Depth=1
+; MIPS2-NEXT: sc $1, 0($4)
+; MIPS2-NEXT: beqz $1, $BB3_1
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.4: # %entry
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: jr $ra
+; MIPS2-NEXT: nop
+;
; MIPS32-LABEL: test_umin_32:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: sync
; MIPS32-NEXT: $BB3_1: # %entry
; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS32-NEXT: ll $2, 0($4)
-; MIPS32-NEXT: sltu $3, $2, $5
+; MIPS32-NEXT: sltu $3, $5, $2
; MIPS32-NEXT: move $1, $2
-; MIPS32-NEXT: movz $1, $5, $3
+; MIPS32-NEXT: movn $1, $5, $3
; MIPS32-NEXT: sc $1, 0($4)
; MIPS32-NEXT: beqz $1, $BB3_1
; MIPS32-NEXT: nop
@@ -870,9 +854,9 @@ define i32 @test_umin_32(ptr nocapture %ptr, i32 signext %val) {
; MIPSEL-NEXT: $BB3_1: # %entry
; MIPSEL-NEXT: # =>This Inner Loop Header: Depth=1
; MIPSEL-NEXT: ll $2, 0($4)
-; MIPSEL-NEXT: sltu $3, $2, $5
+; MIPSEL-NEXT: sltu $3, $5, $2
; MIPSEL-NEXT: move $1, $2
-; MIPSEL-NEXT: movz $1, $5, $3
+; MIPSEL-NEXT: movn $1, $5, $3
; MIPSEL-NEXT: sc $1, 0($4)
; MIPSEL-NEXT: beqz $1, $BB3_1
; MIPSEL-NEXT: nop
@@ -887,9 +871,9 @@ define i32 @test_umin_32(ptr nocapture %ptr, i32 signext %val) {
; MIPSELR6-NEXT: $BB3_1: # %entry
; MIPSELR6-NEXT: # =>This Inner Loop Header: Depth=1
; MIPSELR6-NEXT: ll $2, 0($4)
-; MIPSELR6-NEXT: sltu $3, $2, $5
-; MIPSELR6-NEXT: selnez $1, $2, $3
-; MIPSELR6-NEXT: seleqz $3, $5, $3
+; MIPSELR6-NEXT: sltu $3, $5, $2
+; MIPSELR6-NEXT: seleqz $1, $2, $3
+; MIPSELR6-NEXT: selnez $3, $5, $3
; MIPSELR6-NEXT: or $1, $1, $3
; MIPSELR6-NEXT: sc $1, 0($4)
; MIPSELR6-NEXT: beqzc $1, $BB3_1
@@ -903,9 +887,9 @@ define i32 @test_umin_32(ptr nocapture %ptr, i32 signext %val) {
; MMEL-NEXT: $BB3_1: # %entry
; MMEL-NEXT: # =>This Inner Loop Header: Depth=1
; MMEL-NEXT: ll $2, 0($4)
-; MMEL-NEXT: sltu $3, $2, $5
+; MMEL-NEXT: sltu $3, $5, $2
; MMEL-NEXT: or $1, $2, $zero
-; MMEL-NEXT: movz $1, $5, $3
+; MMEL-NEXT: movn $1, $5, $3
; MMEL-NEXT: sc $1, 0($4)
; MMEL-NEXT: beqzc $1, $BB3_1
; MMEL-NEXT: # %bb.2: # %entry
@@ -918,9 +902,9 @@ define i32 @test_umin_32(ptr nocapture %ptr, i32 signext %val) {
; MMELR6-NEXT: $BB3_1: # %entry
; MMELR6-NEXT: # =>This Inner Loop Header: Depth=1
; MMELR6-NEXT: ll $2, 0($4)
-; MMELR6-NEXT: sltu $3, $2, $5
-; MMELR6-NEXT: selnez $1, $2, $3
-; MMELR6-NEXT: seleqz $3, $5, $3
+; MMELR6-NEXT: sltu $3, $5, $2
+; MMELR6-NEXT: seleqz $1, $2, $3
+; MMELR6-NEXT: selnez $3, $5, $3
; MMELR6-NEXT: or $1, $1, $3
; MMELR6-NEXT: sc $1, 0($4)
; MMELR6-NEXT: beqc $1, $zero, $BB3_1
@@ -935,9 +919,9 @@ define i32 @test_umin_32(ptr nocapture %ptr, i32 signext %val) {
; MIPS64-NEXT: .LBB3_1: # %entry
; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS64-NEXT: ll $2, 0($4)
-; MIPS64-NEXT: sltu $3, $2, $5
+; MIPS64-NEXT: sltu $3, $5, $2
; MIPS64-NEXT: move $1, $2
-; MIPS64-NEXT: movz $1, $5, $3
+; MIPS64-NEXT: movn $1, $5, $3
; MIPS64-NEXT: sc $1, 0($4)
; MIPS64-NEXT: beqz $1, .LBB3_1
; MIPS64-NEXT: nop
@@ -953,9 +937,9 @@ define i32 @test_umin_32(ptr nocapture %ptr, i32 signext %val) {
; MIPS64R6-NEXT: .LBB3_1: # %entry
; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS64R6-NEXT: ll $2, 0($4)
-; MIPS64R6-NEXT: sltu $3, $2, $5
-; MIPS64R6-NEXT: selnez $1, $2, $3
-; MIPS64R6-NEXT: seleqz $3, $5, $3
+; MIPS64R6-NEXT: sltu $3, $5, $2
+; MIPS64R6-NEXT: seleqz $1, $2, $3
+; MIPS64R6-NEXT: selnez $3, $5, $3
; MIPS64R6-NEXT: or $1, $1, $3
; MIPS64R6-NEXT: sc $1, 0($4)
; MIPS64R6-NEXT: beqzc $1, .LBB3_1
@@ -970,9 +954,9 @@ define i32 @test_umin_32(ptr nocapture %ptr, i32 signext %val) {
; MIPS64EL-NEXT: .LBB3_1: # %entry
; MIPS64EL-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS64EL-NEXT: ll $2, 0($4)
-; MIPS64EL-NEXT: sltu $3, $2, $5
+; MIPS64EL-NEXT: sltu $3, $5, $2
; MIPS64EL-NEXT: move $1, $2
-; MIPS64EL-NEXT: movz $1, $5, $3
+; MIPS64EL-NEXT: movn $1, $5, $3
; MIPS64EL-NEXT: sc $1, 0($4)
; MIPS64EL-NEXT: beqz $1, .LBB3_1
; MIPS64EL-NEXT: nop
@@ -988,9 +972,9 @@ define i32 @test_umin_32(ptr nocapture %ptr, i32 signext %val) {
; MIPS64ELR6-NEXT: .LBB3_1: # %entry
; MIPS64ELR6-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS64ELR6-NEXT: ll $2, 0($4)
-; MIPS64ELR6-NEXT: sltu $3, $2, $5
-; MIPS64ELR6-NEXT: selnez $1, $2, $3
-; MIPS64ELR6-NEXT: seleqz $3, $5, $3
+; MIPS64ELR6-NEXT: sltu $3, $5, $2
+; MIPS64ELR6-NEXT: seleqz $1, $2, $3
+; MIPS64ELR6-NEXT: selnez $3, $5, $3
; MIPS64ELR6-NEXT: or $1, $1, $3
; MIPS64ELR6-NEXT: sc $1, 0($4)
; MIPS64ELR6-NEXT: beqzc $1, .LBB3_1
@@ -1005,173 +989,107 @@ entry:
define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) {
; MIPS-LABEL: test_max_16:
; MIPS: # %bb.0: # %entry
-; MIPS-NEXT: addiu $sp, $sp, -8
-; MIPS-NEXT: .cfi_def_cfa_offset 8
+; MIPS-NEXT: move $1, $5
; MIPS-NEXT: sync
-; MIPS-NEXT: addiu $1, $zero, -4
-; MIPS-NEXT: and $6, $4, $1
-; MIPS-NEXT: andi $1, $4, 3
-; MIPS-NEXT: xori $1, $1, 2
-; MIPS-NEXT: sll $10, $1, 3
-; MIPS-NEXT: ori $1, $zero, 65535
-; MIPS-NEXT: sllv $8, $1, $10
-; MIPS-NEXT: nor $9, $zero, $8
-; MIPS-NEXT: sllv $7, $5, $10
+; MIPS-NEXT: addiu $2, $zero, -4
+; MIPS-NEXT: and $5, $4, $2
+; MIPS-NEXT: andi $2, $4, 3
+; MIPS-NEXT: xori $2, $2, 2
+; MIPS-NEXT: sll $2, $2, 3
+; MIPS-NEXT: ori $3, $zero, 65535
+; MIPS-NEXT: sllv $7, $3, $2
+; MIPS-NEXT: sllv $6, $1, $2
+; MIPS-NEXT: addiu $1, $zero, 16
+; MIPS-NEXT: subu $8, $1, $2
; MIPS-NEXT: $BB4_1: # %entry
; MIPS-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS-NEXT: ll $2, 0($6)
-; MIPS-NEXT: srav $4, $2, $10
-; MIPS-NEXT: seh $4, $4
-; MIPS-NEXT: or $1, $zero, $4
-; MIPS-NEXT: sllv $4, $4, $10
-; MIPS-NEXT: slt $5, $4, $7
-; MIPS-NEXT: move $3, $4
-; MIPS-NEXT: movn $3, $7, $5
-; MIPS-NEXT: and $3, $3, $8
-; MIPS-NEXT: and $4, $2, $9
-; MIPS-NEXT: or $4, $4, $3
-; MIPS-NEXT: sc $4, 0($6)
-; MIPS-NEXT: beqz $4, $BB4_1
+; MIPS-NEXT: ll $1, 0($5)
+; MIPS-NEXT: and $3, $1, $7
+; MIPS-NEXT: sllv $3, $3, $8
+; MIPS-NEXT: srav $3, $3, $8
+; MIPS-NEXT: slt $4, $3, $6
+; MIPS-NEXT: movn $3, $6, $4
+; MIPS-NEXT: xor $3, $1, $3
+; MIPS-NEXT: and $3, $3, $7
+; MIPS-NEXT: xor $3, $1, $3
+; MIPS-NEXT: sc $3, 0($5)
+; MIPS-NEXT: beqz $3, $BB4_1
; MIPS-NEXT: nop
; MIPS-NEXT: # %bb.2: # %entry
-; MIPS-NEXT: .insn
-; MIPS-NEXT: # %bb.3: # %entry
-; MIPS-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS-NEXT: # %bb.4: # %entry
-; MIPS-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPS-NEXT: srlv $2, $1, $2
; MIPS-NEXT: sync
-; MIPS-NEXT: addiu $sp, $sp, 8
; MIPS-NEXT: jr $ra
; MIPS-NEXT: nop
;
-; MIPS2-LABEL: test_max_16:
-; MIPS2: # %bb.0: # %entry
-; MIPS2-NEXT: addiu $sp, $sp, -8
-; MIPS2-NEXT: .cfi_def_cfa_offset 8
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: addiu $1, $zero, -4
-; MIPS2-NEXT: and $6, $4, $1
-; MIPS2-NEXT: andi $1, $4, 3
-; MIPS2-NEXT: sll $10, $1, 3
-; MIPS2-NEXT: ori $1, $zero, 65535
-; MIPS2-NEXT: sllv $8, $1, $10
-; MIPS2-NEXT: nor $9, $zero, $8
-; MIPS2-NEXT: sllv $7, $5, $10
-; MIPS2-NEXT: $BB4_1: # %entry
-; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS2-NEXT: ll $2, 0($6)
-; MIPS2-NEXT: srav $4, $2, $10
-; MIPS2-NEXT: sll $4, $4, 16
-; MIPS2-NEXT: sra $4, $4, 16
-; MIPS2-NEXT: or $1, $zero, $4
-; MIPS2-NEXT: sllv $4, $4, $10
-; MIPS2-NEXT: slt $5, $4, $7
-; MIPS2-NEXT: move $3, $7
-; MIPS2-NEXT: beqz $5, $BB4_3
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.2: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB4_1 Depth=1
-; MIPS2-NEXT: j $BB4_4
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: $BB4_3: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB4_1 Depth=1
-; MIPS2-NEXT: move $3, $4
-; MIPS2-NEXT: $BB4_4: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB4_1 Depth=1
-; MIPS2-NEXT: and $3, $3, $8
-; MIPS2-NEXT: and $4, $2, $9
-; MIPS2-NEXT: or $4, $4, $3
-; MIPS2-NEXT: sc $4, 0($6)
-; MIPS2-NEXT: beqz $4, $BB4_1
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.5: # %entry
-; MIPS2-NEXT: .insn
-; MIPS2-NEXT: # %bb.6: # %entry
-; MIPS2-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS2-NEXT: # %bb.7: # %entry
-; MIPS2-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: addiu $sp, $sp, 8
-; MIPS2-NEXT: jr $ra
-; MIPS2-NEXT: nop
-;
; MIPSR6-LABEL: test_max_16:
; MIPSR6: # %bb.0: # %entry
-; MIPSR6-NEXT: addiu $sp, $sp, -8
-; MIPSR6-NEXT: .cfi_def_cfa_offset 8
+; MIPSR6-NEXT: move $1, $5
; MIPSR6-NEXT: sync
-; MIPSR6-NEXT: addiu $1, $zero, -4
-; MIPSR6-NEXT: and $6, $4, $1
-; MIPSR6-NEXT: andi $1, $4, 3
-; MIPSR6-NEXT: xori $1, $1, 2
-; MIPSR6-NEXT: sll $10, $1, 3
-; MIPSR6-NEXT: ori $1, $zero, 65535
-; MIPSR6-NEXT: sllv $8, $1, $10
-; MIPSR6-NEXT: nor $9, $zero, $8
-; MIPSR6-NEXT: sllv $7, $5, $10
+; MIPSR6-NEXT: addiu $2, $zero, -4
+; MIPSR6-NEXT: and $5, $4, $2
+; MIPSR6-NEXT: andi $2, $4, 3
+; MIPSR6-NEXT: xori $2, $2, 2
+; MIPSR6-NEXT: sll $2, $2, 3
+; MIPSR6-NEXT: ori $3, $zero, 65535
+; MIPSR6-NEXT: sllv $7, $3, $2
+; MIPSR6-NEXT: sllv $6, $1, $2
+; MIPSR6-NEXT: addiu $1, $zero, 16
+; MIPSR6-NEXT: subu $8, $1, $2
; MIPSR6-NEXT: $BB4_1: # %entry
; MIPSR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSR6-NEXT: ll $2, 0($6)
-; MIPSR6-NEXT: srav $4, $2, $10
-; MIPSR6-NEXT: seh $4, $4
-; MIPSR6-NEXT: or $1, $zero, $4
-; MIPSR6-NEXT: sllv $4, $4, $10
-; MIPSR6-NEXT: slt $5, $4, $7
-; MIPSR6-NEXT: seleqz $3, $4, $5
-; MIPSR6-NEXT: selnez $5, $7, $5
-; MIPSR6-NEXT: or $3, $3, $5
-; MIPSR6-NEXT: and $3, $3, $8
-; MIPSR6-NEXT: and $4, $2, $9
-; MIPSR6-NEXT: or $4, $4, $3
-; MIPSR6-NEXT: sc $4, 0($6)
-; MIPSR6-NEXT: beqzc $4, $BB4_1
-; MIPSR6-NEXT: nop
+; MIPSR6-NEXT: ll $1, 0($5)
+; MIPSR6-NEXT: and $3, $1, $7
+; MIPSR6-NEXT: sllv $3, $3, $8
+; MIPSR6-NEXT: srav $3, $3, $8
+; MIPSR6-NEXT: slt $4, $3, $6
+; MIPSR6-NEXT: seleqz $3, $3, $4
+; MIPSR6-NEXT: selnez $4, $6, $4
+; MIPSR6-NEXT: or $3, $3, $4
+; MIPSR6-NEXT: xor $3, $1, $3
+; MIPSR6-NEXT: and $3, $3, $7
+; MIPSR6-NEXT: xor $3, $1, $3
+; MIPSR6-NEXT: sc $3, 0($5)
+; MIPSR6-NEXT: beqzc $3, $BB4_1
; MIPSR6-NEXT: # %bb.2: # %entry
-; MIPSR6-NEXT: .insn
-; MIPSR6-NEXT: # %bb.3: # %entry
-; MIPSR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSR6-NEXT: # %bb.4: # %entry
-; MIPSR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSR6-NEXT: srlv $2, $1, $2
; MIPSR6-NEXT: sync
-; MIPSR6-NEXT: addiu $sp, $sp, 8
; MIPSR6-NEXT: jrc $ra
;
; MM-LABEL: test_max_16:
; MM: # %bb.0: # %entry
; MM-NEXT: addiu $sp, $sp, -8
; MM-NEXT: .cfi_def_cfa_offset 8
+; MM-NEXT: sw $16, 4($sp) # 4-byte Folded Spill
+; MM-NEXT: .cfi_offset 16, -4
+; MM-NEXT: move $1, $5
; MM-NEXT: sync
-; MM-NEXT: addiu $1, $zero, -4
-; MM-NEXT: and $6, $4, $1
-; MM-NEXT: andi $1, $4, 3
-; MM-NEXT: xori $1, $1, 2
-; MM-NEXT: sll $10, $1, 3
-; MM-NEXT: ori $1, $zero, 65535
-; MM-NEXT: sllv $8, $1, $10
-; MM-NEXT: nor $9, $zero, $8
-; MM-NEXT: sllv $7, $5, $10
+; MM-NEXT: addiu $5, $zero, -4
+; MM-NEXT: and16 $5, $4
+; MM-NEXT: andi16 $2, $4, 3
+; MM-NEXT: xori $2, $2, 2
+; MM-NEXT: sll16 $2, $2, 3
+; MM-NEXT: ori $3, $zero, 65535
+; MM-NEXT: sllv $7, $3, $2
+; MM-NEXT: sllv $6, $1, $2
+; MM-NEXT: li16 $3, 16
+; MM-NEXT: subu16 $16, $3, $2
; MM-NEXT: $BB4_1: # %entry
; MM-NEXT: # =>This Inner Loop Header: Depth=1
-; MM-NEXT: ll $2, 0($6)
-; MM-NEXT: srav $4, $2, $10
-; MM-NEXT: seh $4, $4
-; MM-NEXT: or $1, $zero, $4
-; MM-NEXT: sllv $4, $4, $10
-; MM-NEXT: slt $5, $4, $7
-; MM-NEXT: or $3, $4, $zero
-; MM-NEXT: movn $3, $7, $5
-; MM-NEXT: and $3, $3, $8
-; MM-NEXT: and $4, $2, $9
-; MM-NEXT: or $4, $4, $3
-; MM-NEXT: sc $4, 0($6)
-; MM-NEXT: beqzc $4, $BB4_1
+; MM-NEXT: ll $1, 0($5)
+; MM-NEXT: and $3, $1, $7
+; MM-NEXT: sllv $3, $3, $16
+; MM-NEXT: srav $3, $3, $16
+; MM-NEXT: slt $4, $3, $6
+; MM-NEXT: movn $3, $6, $4
+; MM-NEXT: xor $3, $1, $3
+; MM-NEXT: and $3, $3, $7
+; MM-NEXT: xor $3, $1, $3
+; MM-NEXT: sc $3, 0($5)
+; MM-NEXT: beqzc $3, $BB4_1
; MM-NEXT: # %bb.2: # %entry
-; MM-NEXT: .insn
-; MM-NEXT: # %bb.3: # %entry
-; MM-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MM-NEXT: # %bb.4: # %entry
-; MM-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MM-NEXT: srlv $2, $1, $2
; MM-NEXT: sync
+; MM-NEXT: lw $16, 4($sp) # 4-byte Folded Reload
; MM-NEXT: addiusp 8
; MM-NEXT: jrc $ra
;
@@ -1179,198 +1097,214 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) {
; MMR6: # %bb.0: # %entry
; MMR6-NEXT: addiu $sp, $sp, -8
; MMR6-NEXT: .cfi_def_cfa_offset 8
+; MMR6-NEXT: sw $16, 4($sp) # 4-byte Folded Spill
+; MMR6-NEXT: .cfi_offset 16, -4
+; MMR6-NEXT: move $1, $5
; MMR6-NEXT: sync
-; MMR6-NEXT: addiu $1, $zero, -4
-; MMR6-NEXT: and $6, $4, $1
-; MMR6-NEXT: andi $1, $4, 3
-; MMR6-NEXT: xori $1, $1, 2
-; MMR6-NEXT: sll $10, $1, 3
-; MMR6-NEXT: ori $1, $zero, 65535
-; MMR6-NEXT: sllv $8, $1, $10
-; MMR6-NEXT: nor $9, $zero, $8
-; MMR6-NEXT: sllv $7, $5, $10
+; MMR6-NEXT: addiu $2, $zero, -4
+; MMR6-NEXT: and $5, $4, $2
+; MMR6-NEXT: andi16 $2, $4, 3
+; MMR6-NEXT: xori $2, $2, 2
+; MMR6-NEXT: sll16 $2, $2, 3
+; MMR6-NEXT: ori $3, $zero, 65535
+; MMR6-NEXT: sllv $7, $3, $2
+; MMR6-NEXT: sllv $6, $1, $2
+; MMR6-NEXT: li16 $3, 16
+; MMR6-NEXT: subu16 $16, $3, $2
; MMR6-NEXT: $BB4_1: # %entry
; MMR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MMR6-NEXT: ll $2, 0($6)
-; MMR6-NEXT: srav $4, $2, $10
-; MMR6-NEXT: seh $4, $4
-; MMR6-NEXT: or $1, $zero, $4
-; MMR6-NEXT: sllv $4, $4, $10
-; MMR6-NEXT: slt $5, $4, $7
-; MMR6-NEXT: seleqz $3, $4, $5
-; MMR6-NEXT: selnez $5, $7, $5
-; MMR6-NEXT: or $3, $3, $5
-; MMR6-NEXT: and $3, $3, $8
-; MMR6-NEXT: and $4, $2, $9
-; MMR6-NEXT: or $4, $4, $3
-; MMR6-NEXT: sc $4, 0($6)
-; MMR6-NEXT: beqc $4, $zero, $BB4_1
+; MMR6-NEXT: ll $1, 0($5)
+; MMR6-NEXT: and $3, $1, $7
+; MMR6-NEXT: sllv $3, $3, $16
+; MMR6-NEXT: srav $3, $3, $16
+; MMR6-NEXT: slt $4, $3, $6
+; MMR6-NEXT: seleqz $3, $3, $4
+; MMR6-NEXT: selnez $4, $6, $4
+; MMR6-NEXT: or $3, $3, $4
+; MMR6-NEXT: xor $3, $1, $3
+; MMR6-NEXT: and $3, $3, $7
+; MMR6-NEXT: xor $3, $1, $3
+; MMR6-NEXT: sc $3, 0($5)
+; MMR6-NEXT: beqc $3, $zero, $BB4_1
; MMR6-NEXT: # %bb.2: # %entry
-; MMR6-NEXT: .insn
-; MMR6-NEXT: # %bb.3: # %entry
-; MMR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMR6-NEXT: # %bb.4: # %entry
-; MMR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMR6-NEXT: srlv $2, $1, $2
; MMR6-NEXT: sync
+; MMR6-NEXT: lw $16, 4($sp) # 4-byte Folded Reload
; MMR6-NEXT: addiu $sp, $sp, 8
; MMR6-NEXT: jrc $ra
;
+; MIPS2-LABEL: test_max_16:
+; MIPS2: # %bb.0: # %entry
+; MIPS2-NEXT: move $1, $5
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: addiu $2, $zero, -4
+; MIPS2-NEXT: and $5, $4, $2
+; MIPS2-NEXT: sll $2, $4, 3
+; MIPS2-NEXT: andi $3, $2, 24
+; MIPS2-NEXT: ori $4, $zero, 65535
+; MIPS2-NEXT: sllv $7, $4, $2
+; MIPS2-NEXT: sllv $6, $1, $2
+; MIPS2-NEXT: addiu $1, $zero, 16
+; MIPS2-NEXT: subu $8, $1, $3
+; MIPS2-NEXT: $BB4_1: # %entry
+; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
+; MIPS2-NEXT: ll $1, 0($5)
+; MIPS2-NEXT: and $3, $1, $7
+; MIPS2-NEXT: sllv $3, $3, $8
+; MIPS2-NEXT: srav $3, $3, $8
+; MIPS2-NEXT: slt $4, $3, $6
+; MIPS2-NEXT: beqz $4, $BB4_3
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.2: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB4_1 Depth=1
+; MIPS2-NEXT: move $3, $6
+; MIPS2-NEXT: $BB4_3: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB4_1 Depth=1
+; MIPS2-NEXT: xor $3, $1, $3
+; MIPS2-NEXT: and $3, $3, $7
+; MIPS2-NEXT: xor $3, $1, $3
+; MIPS2-NEXT: sc $3, 0($5)
+; MIPS2-NEXT: beqz $3, $BB4_1
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.4: # %entry
+; MIPS2-NEXT: srlv $2, $1, $2
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: jr $ra
+; MIPS2-NEXT: nop
+;
; MIPS32-LABEL: test_max_16:
; MIPS32: # %bb.0: # %entry
-; MIPS32-NEXT: addiu $sp, $sp, -8
-; MIPS32-NEXT: .cfi_def_cfa_offset 8
+; MIPS32-NEXT: move $1, $5
; MIPS32-NEXT: sync
-; MIPS32-NEXT: addiu $1, $zero, -4
-; MIPS32-NEXT: and $6, $4, $1
-; MIPS32-NEXT: andi $1, $4, 3
-; MIPS32-NEXT: sll $10, $1, 3
-; MIPS32-NEXT: ori $1, $zero, 65535
-; MIPS32-NEXT: sllv $8, $1, $10
-; MIPS32-NEXT: nor $9, $zero, $8
-; MIPS32-NEXT: sllv $7, $5, $10
+; MIPS32-NEXT: addiu $2, $zero, -4
+; MIPS32-NEXT: and $5, $4, $2
+; MIPS32-NEXT: sll $2, $4, 3
+; MIPS32-NEXT: andi $3, $2, 24
+; MIPS32-NEXT: ori $4, $zero, 65535
+; MIPS32-NEXT: sllv $7, $4, $2
+; MIPS32-NEXT: sllv $6, $1, $2
+; MIPS32-NEXT: addiu $1, $zero, 16
+; MIPS32-NEXT: subu $8, $1, $3
; MIPS32-NEXT: $BB4_1: # %entry
; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32-NEXT: ll $2, 0($6)
-; MIPS32-NEXT: srav $4, $2, $10
-; MIPS32-NEXT: sll $4, $4, 16
-; MIPS32-NEXT: sra $4, $4, 16
-; MIPS32-NEXT: or $1, $zero, $4
-; MIPS32-NEXT: sllv $4, $4, $10
-; MIPS32-NEXT: slt $5, $4, $7
-; MIPS32-NEXT: move $3, $4
-; MIPS32-NEXT: movn $3, $7, $5
-; MIPS32-NEXT: and $3, $3, $8
-; MIPS32-NEXT: and $4, $2, $9
-; MIPS32-NEXT: or $4, $4, $3
-; MIPS32-NEXT: sc $4, 0($6)
-; MIPS32-NEXT: beqz $4, $BB4_1
+; MIPS32-NEXT: ll $1, 0($5)
+; MIPS32-NEXT: and $3, $1, $7
+; MIPS32-NEXT: sllv $3, $3, $8
+; MIPS32-NEXT: srav $3, $3, $8
+; MIPS32-NEXT: slt $4, $3, $6
+; MIPS32-NEXT: movn $3, $6, $4
+; MIPS32-NEXT: xor $3, $1, $3
+; MIPS32-NEXT: and $3, $3, $7
+; MIPS32-NEXT: xor $3, $1, $3
+; MIPS32-NEXT: sc $3, 0($5)
+; MIPS32-NEXT: beqz $3, $BB4_1
; MIPS32-NEXT: nop
; MIPS32-NEXT: # %bb.2: # %entry
-; MIPS32-NEXT: .insn
-; MIPS32-NEXT: # %bb.3: # %entry
-; MIPS32-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32-NEXT: # %bb.4: # %entry
-; MIPS32-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPS32-NEXT: srlv $2, $1, $2
; MIPS32-NEXT: sync
-; MIPS32-NEXT: addiu $sp, $sp, 8
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPSEL-LABEL: test_max_16:
; MIPSEL: # %bb.0: # %entry
-; MIPSEL-NEXT: addiu $sp, $sp, -8
-; MIPSEL-NEXT: .cfi_def_cfa_offset 8
+; MIPSEL-NEXT: move $1, $5
; MIPSEL-NEXT: sync
-; MIPSEL-NEXT: addiu $1, $zero, -4
-; MIPSEL-NEXT: and $6, $4, $1
-; MIPSEL-NEXT: andi $1, $4, 3
-; MIPSEL-NEXT: sll $10, $1, 3
-; MIPSEL-NEXT: ori $1, $zero, 65535
-; MIPSEL-NEXT: sllv $8, $1, $10
-; MIPSEL-NEXT: nor $9, $zero, $8
-; MIPSEL-NEXT: sllv $7, $5, $10
+; MIPSEL-NEXT: addiu $2, $zero, -4
+; MIPSEL-NEXT: and $5, $4, $2
+; MIPSEL-NEXT: sll $2, $4, 3
+; MIPSEL-NEXT: andi $3, $2, 24
+; MIPSEL-NEXT: ori $4, $zero, 65535
+; MIPSEL-NEXT: sllv $7, $4, $2
+; MIPSEL-NEXT: sllv $6, $1, $2
+; MIPSEL-NEXT: addiu $1, $zero, 16
+; MIPSEL-NEXT: subu $8, $1, $3
; MIPSEL-NEXT: $BB4_1: # %entry
; MIPSEL-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSEL-NEXT: ll $2, 0($6)
-; MIPSEL-NEXT: srav $4, $2, $10
-; MIPSEL-NEXT: seh $4, $4
-; MIPSEL-NEXT: or $1, $zero, $4
-; MIPSEL-NEXT: sllv $4, $4, $10
-; MIPSEL-NEXT: slt $5, $4, $7
-; MIPSEL-NEXT: move $3, $4
-; MIPSEL-NEXT: movn $3, $7, $5
-; MIPSEL-NEXT: and $3, $3, $8
-; MIPSEL-NEXT: and $4, $2, $9
-; MIPSEL-NEXT: or $4, $4, $3
-; MIPSEL-NEXT: sc $4, 0($6)
-; MIPSEL-NEXT: beqz $4, $BB4_1
+; MIPSEL-NEXT: ll $1, 0($5)
+; MIPSEL-NEXT: and $3, $1, $7
+; MIPSEL-NEXT: sllv $3, $3, $8
+; MIPSEL-NEXT: srav $3, $3, $8
+; MIPSEL-NEXT: slt $4, $3, $6
+; MIPSEL-NEXT: movn $3, $6, $4
+; MIPSEL-NEXT: xor $3, $1, $3
+; MIPSEL-NEXT: and $3, $3, $7
+; MIPSEL-NEXT: xor $3, $1, $3
+; MIPSEL-NEXT: sc $3, 0($5)
+; MIPSEL-NEXT: beqz $3, $BB4_1
; MIPSEL-NEXT: nop
; MIPSEL-NEXT: # %bb.2: # %entry
-; MIPSEL-NEXT: .insn
-; MIPSEL-NEXT: # %bb.3: # %entry
-; MIPSEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSEL-NEXT: # %bb.4: # %entry
-; MIPSEL-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSEL-NEXT: srlv $2, $1, $2
; MIPSEL-NEXT: sync
-; MIPSEL-NEXT: addiu $sp, $sp, 8
; MIPSEL-NEXT: jr $ra
; MIPSEL-NEXT: nop
;
; MIPSELR6-LABEL: test_max_16:
; MIPSELR6: # %bb.0: # %entry
-; MIPSELR6-NEXT: addiu $sp, $sp, -8
-; MIPSELR6-NEXT: .cfi_def_cfa_offset 8
+; MIPSELR6-NEXT: move $1, $5
; MIPSELR6-NEXT: sync
-; MIPSELR6-NEXT: addiu $1, $zero, -4
-; MIPSELR6-NEXT: and $6, $4, $1
-; MIPSELR6-NEXT: andi $1, $4, 3
-; MIPSELR6-NEXT: sll $10, $1, 3
-; MIPSELR6-NEXT: ori $1, $zero, 65535
-; MIPSELR6-NEXT: sllv $8, $1, $10
-; MIPSELR6-NEXT: nor $9, $zero, $8
-; MIPSELR6-NEXT: sllv $7, $5, $10
+; MIPSELR6-NEXT: addiu $2, $zero, -4
+; MIPSELR6-NEXT: and $5, $4, $2
+; MIPSELR6-NEXT: sll $2, $4, 3
+; MIPSELR6-NEXT: andi $3, $2, 24
+; MIPSELR6-NEXT: ori $4, $zero, 65535
+; MIPSELR6-NEXT: sllv $7, $4, $2
+; MIPSELR6-NEXT: sllv $6, $1, $2
+; MIPSELR6-NEXT: addiu $1, $zero, 16
+; MIPSELR6-NEXT: subu $8, $1, $3
; MIPSELR6-NEXT: $BB4_1: # %entry
; MIPSELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSELR6-NEXT: ll $2, 0($6)
-; MIPSELR6-NEXT: srav $4, $2, $10
-; MIPSELR6-NEXT: seh $4, $4
-; MIPSELR6-NEXT: or $1, $zero, $4
-; MIPSELR6-NEXT: sllv $4, $4, $10
-; MIPSELR6-NEXT: slt $5, $4, $7
-; MIPSELR6-NEXT: seleqz $3, $4, $5
-; MIPSELR6-NEXT: selnez $5, $7, $5
-; MIPSELR6-NEXT: or $3, $3, $5
-; MIPSELR6-NEXT: and $3, $3, $8
-; MIPSELR6-NEXT: and $4, $2, $9
-; MIPSELR6-NEXT: or $4, $4, $3
-; MIPSELR6-NEXT: sc $4, 0($6)
-; MIPSELR6-NEXT: beqzc $4, $BB4_1
-; MIPSELR6-NEXT: nop
+; MIPSELR6-NEXT: ll $1, 0($5)
+; MIPSELR6-NEXT: and $3, $1, $7
+; MIPSELR6-NEXT: sllv $3, $3, $8
+; MIPSELR6-NEXT: srav $3, $3, $8
+; MIPSELR6-NEXT: slt $4, $3, $6
+; MIPSELR6-NEXT: seleqz $3, $3, $4
+; MIPSELR6-NEXT: selnez $4, $6, $4
+; MIPSELR6-NEXT: or $3, $3, $4
+; MIPSELR6-NEXT: xor $3, $1, $3
+; MIPSELR6-NEXT: and $3, $3, $7
+; MIPSELR6-NEXT: xor $3, $1, $3
+; MIPSELR6-NEXT: sc $3, 0($5)
+; MIPSELR6-NEXT: beqzc $3, $BB4_1
; MIPSELR6-NEXT: # %bb.2: # %entry
-; MIPSELR6-NEXT: .insn
-; MIPSELR6-NEXT: # %bb.3: # %entry
-; MIPSELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSELR6-NEXT: # %bb.4: # %entry
-; MIPSELR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSELR6-NEXT: srlv $2, $1, $2
; MIPSELR6-NEXT: sync
-; MIPSELR6-NEXT: addiu $sp, $sp, 8
; MIPSELR6-NEXT: jrc $ra
;
; MMEL-LABEL: test_max_16:
; MMEL: # %bb.0: # %entry
; MMEL-NEXT: addiu $sp, $sp, -8
; MMEL-NEXT: .cfi_def_cfa_offset 8
+; MMEL-NEXT: sw $16, 4($sp) # 4-byte Folded Spill
+; MMEL-NEXT: .cfi_offset 16, -4
+; MMEL-NEXT: move $1, $5
; MMEL-NEXT: sync
-; MMEL-NEXT: addiu $1, $zero, -4
-; MMEL-NEXT: and $6, $4, $1
-; MMEL-NEXT: andi $1, $4, 3
-; MMEL-NEXT: sll $10, $1, 3
-; MMEL-NEXT: ori $1, $zero, 65535
-; MMEL-NEXT: sllv $8, $1, $10
-; MMEL-NEXT: nor $9, $zero, $8
-; MMEL-NEXT: sllv $7, $5, $10
+; MMEL-NEXT: addiu $5, $zero, -4
+; MMEL-NEXT: and16 $5, $4
+; MMEL-NEXT: sll16 $2, $4, 3
+; MMEL-NEXT: andi $2, $2, 24
+; MMEL-NEXT: ori $3, $zero, 65535
+; MMEL-NEXT: sllv $7, $3, $2
+; MMEL-NEXT: sllv $6, $1, $2
+; MMEL-NEXT: li16 $3, 16
+; MMEL-NEXT: subu16 $16, $3, $2
; MMEL-NEXT: $BB4_1: # %entry
; MMEL-NEXT: # =>This Inner Loop Header: Depth=1
-; MMEL-NEXT: ll $2, 0($6)
-; MMEL-NEXT: srav $4, $2, $10
-; MMEL-NEXT: seh $4, $4
-; MMEL-NEXT: or $1, $zero, $4
-; MMEL-NEXT: sllv $4, $4, $10
-; MMEL-NEXT: slt $5, $4, $7
-; MMEL-NEXT: or $3, $4, $zero
-; MMEL-NEXT: movn $3, $7, $5
-; MMEL-NEXT: and $3, $3, $8
-; MMEL-NEXT: and $4, $2, $9
-; MMEL-NEXT: or $4, $4, $3
-; MMEL-NEXT: sc $4, 0($6)
-; MMEL-NEXT: beqzc $4, $BB4_1
+; MMEL-NEXT: ll $1, 0($5)
+; MMEL-NEXT: and $3, $1, $7
+; MMEL-NEXT: sllv $3, $3, $16
+; MMEL-NEXT: srav $3, $3, $16
+; MMEL-NEXT: slt $4, $3, $6
+; MMEL-NEXT: movn $3, $6, $4
+; MMEL-NEXT: xor $3, $1, $3
+; MMEL-NEXT: and $3, $3, $7
+; MMEL-NEXT: xor $3, $1, $3
+; MMEL-NEXT: sc $3, 0($5)
+; MMEL-NEXT: beqzc $3, $BB4_1
; MMEL-NEXT: # %bb.2: # %entry
-; MMEL-NEXT: .insn
-; MMEL-NEXT: # %bb.3: # %entry
-; MMEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMEL-NEXT: # %bb.4: # %entry
-; MMEL-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMEL-NEXT: srlv $2, $1, $2
; MMEL-NEXT: sync
+; MMEL-NEXT: lw $16, 4($sp) # 4-byte Folded Reload
; MMEL-NEXT: addiusp 8
; MMEL-NEXT: jrc $ra
;
@@ -1378,205 +1312,181 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) {
; MMELR6: # %bb.0: # %entry
; MMELR6-NEXT: addiu $sp, $sp, -8
; MMELR6-NEXT: .cfi_def_cfa_offset 8
+; MMELR6-NEXT: sw $16, 4($sp) # 4-byte Folded Spill
+; MMELR6-NEXT: .cfi_offset 16, -4
+; MMELR6-NEXT: move $1, $5
; MMELR6-NEXT: sync
-; MMELR6-NEXT: addiu $1, $zero, -4
-; MMELR6-NEXT: and $6, $4, $1
-; MMELR6-NEXT: andi $1, $4, 3
-; MMELR6-NEXT: sll $10, $1, 3
-; MMELR6-NEXT: ori $1, $zero, 65535
-; MMELR6-NEXT: sllv $8, $1, $10
-; MMELR6-NEXT: nor $9, $zero, $8
-; MMELR6-NEXT: sllv $7, $5, $10
+; MMELR6-NEXT: addiu $2, $zero, -4
+; MMELR6-NEXT: and $5, $4, $2
+; MMELR6-NEXT: sll16 $2, $4, 3
+; MMELR6-NEXT: andi $2, $2, 24
+; MMELR6-NEXT: ori $3, $zero, 65535
+; MMELR6-NEXT: sllv $7, $3, $2
+; MMELR6-NEXT: sllv $6, $1, $2
+; MMELR6-NEXT: li16 $3, 16
+; MMELR6-NEXT: subu16 $16, $3, $2
; MMELR6-NEXT: $BB4_1: # %entry
; MMELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MMELR6-NEXT: ll $2, 0($6)
-; MMELR6-NEXT: srav $4, $2, $10
-; MMELR6-NEXT: seh $4, $4
-; MMELR6-NEXT: or $1, $zero, $4
-; MMELR6-NEXT: sllv $4, $4, $10
-; MMELR6-NEXT: slt $5, $4, $7
-; MMELR6-NEXT: seleqz $3, $4, $5
-; MMELR6-NEXT: selnez $5, $7, $5
-; MMELR6-NEXT: or $3, $3, $5
-; MMELR6-NEXT: and $3, $3, $8
-; MMELR6-NEXT: and $4, $2, $9
-; MMELR6-NEXT: or $4, $4, $3
-; MMELR6-NEXT: sc $4, 0($6)
-; MMELR6-NEXT: beqc $4, $zero, $BB4_1
+; MMELR6-NEXT: ll $1, 0($5)
+; MMELR6-NEXT: and $3, $1, $7
+; MMELR6-NEXT: sllv $3, $3, $16
+; MMELR6-NEXT: srav $3, $3, $16
+; MMELR6-NEXT: slt $4, $3, $6
+; MMELR6-NEXT: seleqz $3, $3, $4
+; MMELR6-NEXT: selnez $4, $6, $4
+; MMELR6-NEXT: or $3, $3, $4
+; MMELR6-NEXT: xor $3, $1, $3
+; MMELR6-NEXT: and $3, $3, $7
+; MMELR6-NEXT: xor $3, $1, $3
+; MMELR6-NEXT: sc $3, 0($5)
+; MMELR6-NEXT: beqc $3, $zero, $BB4_1
; MMELR6-NEXT: # %bb.2: # %entry
-; MMELR6-NEXT: .insn
-; MMELR6-NEXT: # %bb.3: # %entry
-; MMELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMELR6-NEXT: # %bb.4: # %entry
-; MMELR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMELR6-NEXT: srlv $2, $1, $2
; MMELR6-NEXT: sync
+; MMELR6-NEXT: lw $16, 4($sp) # 4-byte Folded Reload
; MMELR6-NEXT: addiu $sp, $sp, 8
; MMELR6-NEXT: jrc $ra
;
; MIPS64-LABEL: test_max_16:
; MIPS64: # %bb.0: # %entry
-; MIPS64-NEXT: daddiu $sp, $sp, -16
-; MIPS64-NEXT: .cfi_def_cfa_offset 16
; MIPS64-NEXT: move $1, $5
; MIPS64-NEXT: sync
; MIPS64-NEXT: daddiu $2, $zero, -4
-; MIPS64-NEXT: and $6, $4, $2
-; MIPS64-NEXT: andi $2, $4, 3
+; MIPS64-NEXT: and $5, $4, $2
+; MIPS64-NEXT: move $2, $4
+; MIPS64-NEXT: sll $2, $2, 0
+; MIPS64-NEXT: andi $2, $2, 3
; MIPS64-NEXT: xori $2, $2, 2
-; MIPS64-NEXT: sll $10, $2, 3
-; MIPS64-NEXT: ori $2, $zero, 65535
-; MIPS64-NEXT: sllv $8, $2, $10
-; MIPS64-NEXT: nor $9, $zero, $8
-; MIPS64-NEXT: sllv $7, $1, $10
+; MIPS64-NEXT: sll $2, $2, 3
+; MIPS64-NEXT: ori $3, $zero, 65535
+; MIPS64-NEXT: sllv $7, $3, $2
+; MIPS64-NEXT: sllv $6, $1, $2
+; MIPS64-NEXT: addiu $1, $zero, 16
+; MIPS64-NEXT: subu $8, $1, $2
; MIPS64-NEXT: .LBB4_1: # %entry
; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64-NEXT: ll $2, 0($6)
-; MIPS64-NEXT: srav $4, $2, $10
-; MIPS64-NEXT: seh $4, $4
-; MIPS64-NEXT: or $1, $zero, $4
-; MIPS64-NEXT: sllv $4, $4, $10
-; MIPS64-NEXT: slt $5, $4, $7
-; MIPS64-NEXT: move $3, $4
-; MIPS64-NEXT: movn $3, $7, $5
-; MIPS64-NEXT: and $3, $3, $8
-; MIPS64-NEXT: and $4, $2, $9
-; MIPS64-NEXT: or $4, $4, $3
-; MIPS64-NEXT: sc $4, 0($6)
-; MIPS64-NEXT: beqz $4, .LBB4_1
+; MIPS64-NEXT: ll $1, 0($5)
+; MIPS64-NEXT: and $3, $1, $7
+; MIPS64-NEXT: sllv $3, $3, $8
+; MIPS64-NEXT: srav $3, $3, $8
+; MIPS64-NEXT: slt $4, $3, $6
+; MIPS64-NEXT: movn $3, $6, $4
+; MIPS64-NEXT: xor $3, $1, $3
+; MIPS64-NEXT: and $3, $3, $7
+; MIPS64-NEXT: xor $3, $1, $3
+; MIPS64-NEXT: sc $3, 0($5)
+; MIPS64-NEXT: beqz $3, .LBB4_1
; MIPS64-NEXT: nop
; MIPS64-NEXT: # %bb.2: # %entry
-; MIPS64-NEXT: .insn
-; MIPS64-NEXT: # %bb.3: # %entry
-; MIPS64-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64-NEXT: # %bb.4: # %entry
-; MIPS64-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64-NEXT: srlv $2, $1, $2
; MIPS64-NEXT: sync
-; MIPS64-NEXT: daddiu $sp, $sp, 16
; MIPS64-NEXT: jr $ra
; MIPS64-NEXT: nop
;
; MIPS64R6-LABEL: test_max_16:
; MIPS64R6: # %bb.0: # %entry
-; MIPS64R6-NEXT: daddiu $sp, $sp, -16
-; MIPS64R6-NEXT: .cfi_def_cfa_offset 16
; MIPS64R6-NEXT: move $1, $5
; MIPS64R6-NEXT: sync
; MIPS64R6-NEXT: daddiu $2, $zero, -4
-; MIPS64R6-NEXT: and $6, $4, $2
-; MIPS64R6-NEXT: andi $2, $4, 3
+; MIPS64R6-NEXT: and $5, $4, $2
+; MIPS64R6-NEXT: move $2, $4
+; MIPS64R6-NEXT: sll $2, $2, 0
+; MIPS64R6-NEXT: andi $2, $2, 3
; MIPS64R6-NEXT: xori $2, $2, 2
-; MIPS64R6-NEXT: sll $10, $2, 3
-; MIPS64R6-NEXT: ori $2, $zero, 65535
-; MIPS64R6-NEXT: sllv $8, $2, $10
-; MIPS64R6-NEXT: nor $9, $zero, $8
-; MIPS64R6-NEXT: sllv $7, $1, $10
+; MIPS64R6-NEXT: sll $2, $2, 3
+; MIPS64R6-NEXT: ori $3, $zero, 65535
+; MIPS64R6-NEXT: sllv $7, $3, $2
+; MIPS64R6-NEXT: sllv $6, $1, $2
+; MIPS64R6-NEXT: addiu $1, $zero, 16
+; MIPS64R6-NEXT: subu $8, $1, $2
; MIPS64R6-NEXT: .LBB4_1: # %entry
; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R6-NEXT: ll $2, 0($6)
-; MIPS64R6-NEXT: srav $4, $2, $10
-; MIPS64R6-NEXT: seh $4, $4
-; MIPS64R6-NEXT: or $1, $zero, $4
-; MIPS64R6-NEXT: sllv $4, $4, $10
-; MIPS64R6-NEXT: slt $5, $4, $7
-; MIPS64R6-NEXT: seleqz $3, $4, $5
-; MIPS64R6-NEXT: selnez $5, $7, $5
-; MIPS64R6-NEXT: or $3, $3, $5
-; MIPS64R6-NEXT: and $3, $3, $8
-; MIPS64R6-NEXT: and $4, $2, $9
-; MIPS64R6-NEXT: or $4, $4, $3
-; MIPS64R6-NEXT: sc $4, 0($6)
-; MIPS64R6-NEXT: beqzc $4, .LBB4_1
-; MIPS64R6-NEXT: nop
+; MIPS64R6-NEXT: ll $1, 0($5)
+; MIPS64R6-NEXT: and $3, $1, $7
+; MIPS64R6-NEXT: sllv $3, $3, $8
+; MIPS64R6-NEXT: srav $3, $3, $8
+; MIPS64R6-NEXT: slt $4, $3, $6
+; MIPS64R6-NEXT: seleqz $3, $3, $4
+; MIPS64R6-NEXT: selnez $4, $6, $4
+; MIPS64R6-NEXT: or $3, $3, $4
+; MIPS64R6-NEXT: xor $3, $1, $3
+; MIPS64R6-NEXT: and $3, $3, $7
+; MIPS64R6-NEXT: xor $3, $1, $3
+; MIPS64R6-NEXT: sc $3, 0($5)
+; MIPS64R6-NEXT: beqzc $3, .LBB4_1
; MIPS64R6-NEXT: # %bb.2: # %entry
-; MIPS64R6-NEXT: .insn
-; MIPS64R6-NEXT: # %bb.3: # %entry
-; MIPS64R6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64R6-NEXT: # %bb.4: # %entry
-; MIPS64R6-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64R6-NEXT: srlv $2, $1, $2
; MIPS64R6-NEXT: sync
-; MIPS64R6-NEXT: daddiu $sp, $sp, 16
; MIPS64R6-NEXT: jrc $ra
;
; MIPS64EL-LABEL: test_max_16:
; MIPS64EL: # %bb.0: # %entry
-; MIPS64EL-NEXT: daddiu $sp, $sp, -16
-; MIPS64EL-NEXT: .cfi_def_cfa_offset 16
; MIPS64EL-NEXT: move $1, $5
; MIPS64EL-NEXT: sync
; MIPS64EL-NEXT: daddiu $2, $zero, -4
-; MIPS64EL-NEXT: and $6, $4, $2
-; MIPS64EL-NEXT: andi $2, $4, 3
-; MIPS64EL-NEXT: sll $10, $2, 3
-; MIPS64EL-NEXT: ori $2, $zero, 65535
-; MIPS64EL-NEXT: sllv $8, $2, $10
-; MIPS64EL-NEXT: nor $9, $zero, $8
-; MIPS64EL-NEXT: sllv $7, $1, $10
+; MIPS64EL-NEXT: and $5, $4, $2
+; MIPS64EL-NEXT: move $2, $4
+; MIPS64EL-NEXT: sll $2, $2, 0
+; MIPS64EL-NEXT: andi $2, $2, 3
+; MIPS64EL-NEXT: sll $2, $2, 3
+; MIPS64EL-NEXT: ori $3, $zero, 65535
+; MIPS64EL-NEXT: sllv $7, $3, $2
+; MIPS64EL-NEXT: sllv $6, $1, $2
+; MIPS64EL-NEXT: addiu $1, $zero, 16
+; MIPS64EL-NEXT: subu $8, $1, $2
; MIPS64EL-NEXT: .LBB4_1: # %entry
; MIPS64EL-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64EL-NEXT: ll $2, 0($6)
-; MIPS64EL-NEXT: srav $4, $2, $10
-; MIPS64EL-NEXT: seh $4, $4
-; MIPS64EL-NEXT: or $1, $zero, $4
-; MIPS64EL-NEXT: sllv $4, $4, $10
-; MIPS64EL-NEXT: slt $5, $4, $7
-; MIPS64EL-NEXT: move $3, $4
-; MIPS64EL-NEXT: movn $3, $7, $5
-; MIPS64EL-NEXT: and $3, $3, $8
-; MIPS64EL-NEXT: and $4, $2, $9
-; MIPS64EL-NEXT: or $4, $4, $3
-; MIPS64EL-NEXT: sc $4, 0($6)
-; MIPS64EL-NEXT: beqz $4, .LBB4_1
+; MIPS64EL-NEXT: ll $1, 0($5)
+; MIPS64EL-NEXT: and $3, $1, $7
+; MIPS64EL-NEXT: sllv $3, $3, $8
+; MIPS64EL-NEXT: srav $3, $3, $8
+; MIPS64EL-NEXT: slt $4, $3, $6
+; MIPS64EL-NEXT: movn $3, $6, $4
+; MIPS64EL-NEXT: xor $3, $1, $3
+; MIPS64EL-NEXT: and $3, $3, $7
+; MIPS64EL-NEXT: xor $3, $1, $3
+; MIPS64EL-NEXT: sc $3, 0($5)
+; MIPS64EL-NEXT: beqz $3, .LBB4_1
; MIPS64EL-NEXT: nop
; MIPS64EL-NEXT: # %bb.2: # %entry
-; MIPS64EL-NEXT: .insn
-; MIPS64EL-NEXT: # %bb.3: # %entry
-; MIPS64EL-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64EL-NEXT: # %bb.4: # %entry
-; MIPS64EL-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64EL-NEXT: srlv $2, $1, $2
; MIPS64EL-NEXT: sync
-; MIPS64EL-NEXT: daddiu $sp, $sp, 16
; MIPS64EL-NEXT: jr $ra
; MIPS64EL-NEXT: nop
;
; MIPS64ELR6-LABEL: test_max_16:
; MIPS64ELR6: # %bb.0: # %entry
-; MIPS64ELR6-NEXT: daddiu $sp, $sp, -16
-; MIPS64ELR6-NEXT: .cfi_def_cfa_offset 16
; MIPS64ELR6-NEXT: move $1, $5
; MIPS64ELR6-NEXT: sync
; MIPS64ELR6-NEXT: daddiu $2, $zero, -4
-; MIPS64ELR6-NEXT: and $6, $4, $2
-; MIPS64ELR6-NEXT: andi $2, $4, 3
-; MIPS64ELR6-NEXT: sll $10, $2, 3
-; MIPS64ELR6-NEXT: ori $2, $zero, 65535
-; MIPS64ELR6-NEXT: sllv $8, $2, $10
-; MIPS64ELR6-NEXT: nor $9, $zero, $8
-; MIPS64ELR6-NEXT: sllv $7, $1, $10
+; MIPS64ELR6-NEXT: and $5, $4, $2
+; MIPS64ELR6-NEXT: move $2, $4
+; MIPS64ELR6-NEXT: sll $2, $2, 0
+; MIPS64ELR6-NEXT: andi $2, $2, 3
+; MIPS64ELR6-NEXT: sll $2, $2, 3
+; MIPS64ELR6-NEXT: ori $3, $zero, 65535
+; MIPS64ELR6-NEXT: sllv $7, $3, $2
+; MIPS64ELR6-NEXT: sllv $6, $1, $2
+; MIPS64ELR6-NEXT: addiu $1, $zero, 16
+; MIPS64ELR6-NEXT: subu $8, $1, $2
; MIPS64ELR6-NEXT: .LBB4_1: # %entry
; MIPS64ELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64ELR6-NEXT: ll $2, 0($6)
-; MIPS64ELR6-NEXT: srav $4, $2, $10
-; MIPS64ELR6-NEXT: seh $4, $4
-; MIPS64ELR6-NEXT: or $1, $zero, $4
-; MIPS64ELR6-NEXT: sllv $4, $4, $10
-; MIPS64ELR6-NEXT: slt $5, $4, $7
-; MIPS64ELR6-NEXT: seleqz $3, $4, $5
-; MIPS64ELR6-NEXT: selnez $5, $7, $5
-; MIPS64ELR6-NEXT: or $3, $3, $5
-; MIPS64ELR6-NEXT: and $3, $3, $8
-; MIPS64ELR6-NEXT: and $4, $2, $9
-; MIPS64ELR6-NEXT: or $4, $4, $3
-; MIPS64ELR6-NEXT: sc $4, 0($6)
-; MIPS64ELR6-NEXT: beqzc $4, .LBB4_1
-; MIPS64ELR6-NEXT: nop
+; MIPS64ELR6-NEXT: ll $1, 0($5)
+; MIPS64ELR6-NEXT: and $3, $1, $7
+; MIPS64ELR6-NEXT: sllv $3, $3, $8
+; MIPS64ELR6-NEXT: srav $3, $3, $8
+; MIPS64ELR6-NEXT: slt $4, $3, $6
+; MIPS64ELR6-NEXT: seleqz $3, $3, $4
+; MIPS64ELR6-NEXT: selnez $4, $6, $4
+; MIPS64ELR6-NEXT: or $3, $3, $4
+; MIPS64ELR6-NEXT: xor $3, $1, $3
+; MIPS64ELR6-NEXT: and $3, $3, $7
+; MIPS64ELR6-NEXT: xor $3, $1, $3
+; MIPS64ELR6-NEXT: sc $3, 0($5)
+; MIPS64ELR6-NEXT: beqzc $3, .LBB4_1
; MIPS64ELR6-NEXT: # %bb.2: # %entry
-; MIPS64ELR6-NEXT: .insn
-; MIPS64ELR6-NEXT: # %bb.3: # %entry
-; MIPS64ELR6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64ELR6-NEXT: # %bb.4: # %entry
-; MIPS64ELR6-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64ELR6-NEXT: srlv $2, $1, $2
; MIPS64ELR6-NEXT: sync
-; MIPS64ELR6-NEXT: daddiu $sp, $sp, 16
; MIPS64ELR6-NEXT: jrc $ra
entry:
@@ -1587,173 +1497,107 @@ entry:
define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) {
; MIPS-LABEL: test_min_16:
; MIPS: # %bb.0: # %entry
-; MIPS-NEXT: addiu $sp, $sp, -8
-; MIPS-NEXT: .cfi_def_cfa_offset 8
+; MIPS-NEXT: move $1, $5
; MIPS-NEXT: sync
-; MIPS-NEXT: addiu $1, $zero, -4
-; MIPS-NEXT: and $6, $4, $1
-; MIPS-NEXT: andi $1, $4, 3
-; MIPS-NEXT: xori $1, $1, 2
-; MIPS-NEXT: sll $10, $1, 3
-; MIPS-NEXT: ori $1, $zero, 65535
-; MIPS-NEXT: sllv $8, $1, $10
-; MIPS-NEXT: nor $9, $zero, $8
-; MIPS-NEXT: sllv $7, $5, $10
+; MIPS-NEXT: addiu $2, $zero, -4
+; MIPS-NEXT: and $5, $4, $2
+; MIPS-NEXT: andi $2, $4, 3
+; MIPS-NEXT: xori $2, $2, 2
+; MIPS-NEXT: sll $2, $2, 3
+; MIPS-NEXT: ori $3, $zero, 65535
+; MIPS-NEXT: sllv $7, $3, $2
+; MIPS-NEXT: sllv $6, $1, $2
+; MIPS-NEXT: addiu $1, $zero, 16
+; MIPS-NEXT: subu $8, $1, $2
; MIPS-NEXT: $BB5_1: # %entry
; MIPS-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS-NEXT: ll $2, 0($6)
-; MIPS-NEXT: srav $4, $2, $10
-; MIPS-NEXT: seh $4, $4
-; MIPS-NEXT: or $1, $zero, $4
-; MIPS-NEXT: sllv $4, $4, $10
-; MIPS-NEXT: slt $5, $4, $7
-; MIPS-NEXT: move $3, $4
-; MIPS-NEXT: movz $3, $7, $5
-; MIPS-NEXT: and $3, $3, $8
-; MIPS-NEXT: and $4, $2, $9
-; MIPS-NEXT: or $4, $4, $3
-; MIPS-NEXT: sc $4, 0($6)
-; MIPS-NEXT: beqz $4, $BB5_1
+; MIPS-NEXT: ll $1, 0($5)
+; MIPS-NEXT: and $3, $1, $7
+; MIPS-NEXT: sllv $3, $3, $8
+; MIPS-NEXT: srav $3, $3, $8
+; MIPS-NEXT: slt $4, $6, $3
+; MIPS-NEXT: movn $3, $6, $4
+; MIPS-NEXT: xor $3, $1, $3
+; MIPS-NEXT: and $3, $3, $7
+; MIPS-NEXT: xor $3, $1, $3
+; MIPS-NEXT: sc $3, 0($5)
+; MIPS-NEXT: beqz $3, $BB5_1
; MIPS-NEXT: nop
; MIPS-NEXT: # %bb.2: # %entry
-; MIPS-NEXT: .insn
-; MIPS-NEXT: # %bb.3: # %entry
-; MIPS-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS-NEXT: # %bb.4: # %entry
-; MIPS-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPS-NEXT: srlv $2, $1, $2
; MIPS-NEXT: sync
-; MIPS-NEXT: addiu $sp, $sp, 8
; MIPS-NEXT: jr $ra
; MIPS-NEXT: nop
;
-; MIPS2-LABEL: test_min_16:
-; MIPS2: # %bb.0: # %entry
-; MIPS2-NEXT: addiu $sp, $sp, -8
-; MIPS2-NEXT: .cfi_def_cfa_offset 8
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: addiu $1, $zero, -4
-; MIPS2-NEXT: and $6, $4, $1
-; MIPS2-NEXT: andi $1, $4, 3
-; MIPS2-NEXT: sll $10, $1, 3
-; MIPS2-NEXT: ori $1, $zero, 65535
-; MIPS2-NEXT: sllv $8, $1, $10
-; MIPS2-NEXT: nor $9, $zero, $8
-; MIPS2-NEXT: sllv $7, $5, $10
-; MIPS2-NEXT: $BB5_1: # %entry
-; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS2-NEXT: ll $2, 0($6)
-; MIPS2-NEXT: srav $4, $2, $10
-; MIPS2-NEXT: sll $4, $4, 16
-; MIPS2-NEXT: sra $4, $4, 16
-; MIPS2-NEXT: or $1, $zero, $4
-; MIPS2-NEXT: sllv $4, $4, $10
-; MIPS2-NEXT: slt $5, $4, $7
-; MIPS2-NEXT: move $3, $4
-; MIPS2-NEXT: beqz $5, $BB5_3
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.2: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB5_1 Depth=1
-; MIPS2-NEXT: j $BB5_4
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: $BB5_3: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB5_1 Depth=1
-; MIPS2-NEXT: move $3, $7
-; MIPS2-NEXT: $BB5_4: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB5_1 Depth=1
-; MIPS2-NEXT: and $3, $3, $8
-; MIPS2-NEXT: and $4, $2, $9
-; MIPS2-NEXT: or $4, $4, $3
-; MIPS2-NEXT: sc $4, 0($6)
-; MIPS2-NEXT: beqz $4, $BB5_1
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.5: # %entry
-; MIPS2-NEXT: .insn
-; MIPS2-NEXT: # %bb.6: # %entry
-; MIPS2-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS2-NEXT: # %bb.7: # %entry
-; MIPS2-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: addiu $sp, $sp, 8
-; MIPS2-NEXT: jr $ra
-; MIPS2-NEXT: nop
-;
; MIPSR6-LABEL: test_min_16:
; MIPSR6: # %bb.0: # %entry
-; MIPSR6-NEXT: addiu $sp, $sp, -8
-; MIPSR6-NEXT: .cfi_def_cfa_offset 8
+; MIPSR6-NEXT: move $1, $5
; MIPSR6-NEXT: sync
-; MIPSR6-NEXT: addiu $1, $zero, -4
-; MIPSR6-NEXT: and $6, $4, $1
-; MIPSR6-NEXT: andi $1, $4, 3
-; MIPSR6-NEXT: xori $1, $1, 2
-; MIPSR6-NEXT: sll $10, $1, 3
-; MIPSR6-NEXT: ori $1, $zero, 65535
-; MIPSR6-NEXT: sllv $8, $1, $10
-; MIPSR6-NEXT: nor $9, $zero, $8
-; MIPSR6-NEXT: sllv $7, $5, $10
+; MIPSR6-NEXT: addiu $2, $zero, -4
+; MIPSR6-NEXT: and $5, $4, $2
+; MIPSR6-NEXT: andi $2, $4, 3
+; MIPSR6-NEXT: xori $2, $2, 2
+; MIPSR6-NEXT: sll $2, $2, 3
+; MIPSR6-NEXT: ori $3, $zero, 65535
+; MIPSR6-NEXT: sllv $7, $3, $2
+; MIPSR6-NEXT: sllv $6, $1, $2
+; MIPSR6-NEXT: addiu $1, $zero, 16
+; MIPSR6-NEXT: subu $8, $1, $2
; MIPSR6-NEXT: $BB5_1: # %entry
; MIPSR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSR6-NEXT: ll $2, 0($6)
-; MIPSR6-NEXT: srav $4, $2, $10
-; MIPSR6-NEXT: seh $4, $4
-; MIPSR6-NEXT: or $1, $zero, $4
-; MIPSR6-NEXT: sllv $4, $4, $10
-; MIPSR6-NEXT: slt $5, $4, $7
-; MIPSR6-NEXT: selnez $3, $4, $5
-; MIPSR6-NEXT: seleqz $5, $7, $5
-; MIPSR6-NEXT: or $3, $3, $5
-; MIPSR6-NEXT: and $3, $3, $8
-; MIPSR6-NEXT: and $4, $2, $9
-; MIPSR6-NEXT: or $4, $4, $3
-; MIPSR6-NEXT: sc $4, 0($6)
-; MIPSR6-NEXT: beqzc $4, $BB5_1
-; MIPSR6-NEXT: nop
+; MIPSR6-NEXT: ll $1, 0($5)
+; MIPSR6-NEXT: and $3, $1, $7
+; MIPSR6-NEXT: sllv $3, $3, $8
+; MIPSR6-NEXT: srav $3, $3, $8
+; MIPSR6-NEXT: slt $4, $6, $3
+; MIPSR6-NEXT: seleqz $3, $3, $4
+; MIPSR6-NEXT: selnez $4, $6, $4
+; MIPSR6-NEXT: or $3, $3, $4
+; MIPSR6-NEXT: xor $3, $1, $3
+; MIPSR6-NEXT: and $3, $3, $7
+; MIPSR6-NEXT: xor $3, $1, $3
+; MIPSR6-NEXT: sc $3, 0($5)
+; MIPSR6-NEXT: beqzc $3, $BB5_1
; MIPSR6-NEXT: # %bb.2: # %entry
-; MIPSR6-NEXT: .insn
-; MIPSR6-NEXT: # %bb.3: # %entry
-; MIPSR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSR6-NEXT: # %bb.4: # %entry
-; MIPSR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSR6-NEXT: srlv $2, $1, $2
; MIPSR6-NEXT: sync
-; MIPSR6-NEXT: addiu $sp, $sp, 8
; MIPSR6-NEXT: jrc $ra
;
; MM-LABEL: test_min_16:
; MM: # %bb.0: # %entry
; MM-NEXT: addiu $sp, $sp, -8
; MM-NEXT: .cfi_def_cfa_offset 8
+; MM-NEXT: sw $16, 4($sp) # 4-byte Folded Spill
+; MM-NEXT: .cfi_offset 16, -4
+; MM-NEXT: move $1, $5
; MM-NEXT: sync
-; MM-NEXT: addiu $1, $zero, -4
-; MM-NEXT: and $6, $4, $1
-; MM-NEXT: andi $1, $4, 3
-; MM-NEXT: xori $1, $1, 2
-; MM-NEXT: sll $10, $1, 3
-; MM-NEXT: ori $1, $zero, 65535
-; MM-NEXT: sllv $8, $1, $10
-; MM-NEXT: nor $9, $zero, $8
-; MM-NEXT: sllv $7, $5, $10
+; MM-NEXT: addiu $5, $zero, -4
+; MM-NEXT: and16 $5, $4
+; MM-NEXT: andi16 $2, $4, 3
+; MM-NEXT: xori $2, $2, 2
+; MM-NEXT: sll16 $2, $2, 3
+; MM-NEXT: ori $3, $zero, 65535
+; MM-NEXT: sllv $7, $3, $2
+; MM-NEXT: sllv $6, $1, $2
+; MM-NEXT: li16 $3, 16
+; MM-NEXT: subu16 $16, $3, $2
; MM-NEXT: $BB5_1: # %entry
; MM-NEXT: # =>This Inner Loop Header: Depth=1
-; MM-NEXT: ll $2, 0($6)
-; MM-NEXT: srav $4, $2, $10
-; MM-NEXT: seh $4, $4
-; MM-NEXT: or $1, $zero, $4
-; MM-NEXT: sllv $4, $4, $10
-; MM-NEXT: slt $5, $4, $7
-; MM-NEXT: or $3, $4, $zero
-; MM-NEXT: movz $3, $7, $5
-; MM-NEXT: and $3, $3, $8
-; MM-NEXT: and $4, $2, $9
-; MM-NEXT: or $4, $4, $3
-; MM-NEXT: sc $4, 0($6)
-; MM-NEXT: beqzc $4, $BB5_1
+; MM-NEXT: ll $1, 0($5)
+; MM-NEXT: and $3, $1, $7
+; MM-NEXT: sllv $3, $3, $16
+; MM-NEXT: srav $3, $3, $16
+; MM-NEXT: slt $4, $6, $3
+; MM-NEXT: movn $3, $6, $4
+; MM-NEXT: xor $3, $1, $3
+; MM-NEXT: and $3, $3, $7
+; MM-NEXT: xor $3, $1, $3
+; MM-NEXT: sc $3, 0($5)
+; MM-NEXT: beqzc $3, $BB5_1
; MM-NEXT: # %bb.2: # %entry
-; MM-NEXT: .insn
-; MM-NEXT: # %bb.3: # %entry
-; MM-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MM-NEXT: # %bb.4: # %entry
-; MM-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MM-NEXT: srlv $2, $1, $2
; MM-NEXT: sync
+; MM-NEXT: lw $16, 4($sp) # 4-byte Folded Reload
; MM-NEXT: addiusp 8
; MM-NEXT: jrc $ra
;
@@ -1761,198 +1605,214 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) {
; MMR6: # %bb.0: # %entry
; MMR6-NEXT: addiu $sp, $sp, -8
; MMR6-NEXT: .cfi_def_cfa_offset 8
+; MMR6-NEXT: sw $16, 4($sp) # 4-byte Folded Spill
+; MMR6-NEXT: .cfi_offset 16, -4
+; MMR6-NEXT: move $1, $5
; MMR6-NEXT: sync
-; MMR6-NEXT: addiu $1, $zero, -4
-; MMR6-NEXT: and $6, $4, $1
-; MMR6-NEXT: andi $1, $4, 3
-; MMR6-NEXT: xori $1, $1, 2
-; MMR6-NEXT: sll $10, $1, 3
-; MMR6-NEXT: ori $1, $zero, 65535
-; MMR6-NEXT: sllv $8, $1, $10
-; MMR6-NEXT: nor $9, $zero, $8
-; MMR6-NEXT: sllv $7, $5, $10
+; MMR6-NEXT: addiu $2, $zero, -4
+; MMR6-NEXT: and $5, $4, $2
+; MMR6-NEXT: andi16 $2, $4, 3
+; MMR6-NEXT: xori $2, $2, 2
+; MMR6-NEXT: sll16 $2, $2, 3
+; MMR6-NEXT: ori $3, $zero, 65535
+; MMR6-NEXT: sllv $7, $3, $2
+; MMR6-NEXT: sllv $6, $1, $2
+; MMR6-NEXT: li16 $3, 16
+; MMR6-NEXT: subu16 $16, $3, $2
; MMR6-NEXT: $BB5_1: # %entry
; MMR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MMR6-NEXT: ll $2, 0($6)
-; MMR6-NEXT: srav $4, $2, $10
-; MMR6-NEXT: seh $4, $4
-; MMR6-NEXT: or $1, $zero, $4
-; MMR6-NEXT: sllv $4, $4, $10
-; MMR6-NEXT: slt $5, $4, $7
-; MMR6-NEXT: selnez $3, $4, $5
-; MMR6-NEXT: seleqz $5, $7, $5
-; MMR6-NEXT: or $3, $3, $5
-; MMR6-NEXT: and $3, $3, $8
-; MMR6-NEXT: and $4, $2, $9
-; MMR6-NEXT: or $4, $4, $3
-; MMR6-NEXT: sc $4, 0($6)
-; MMR6-NEXT: beqc $4, $zero, $BB5_1
+; MMR6-NEXT: ll $1, 0($5)
+; MMR6-NEXT: and $3, $1, $7
+; MMR6-NEXT: sllv $3, $3, $16
+; MMR6-NEXT: srav $3, $3, $16
+; MMR6-NEXT: slt $4, $6, $3
+; MMR6-NEXT: seleqz $3, $3, $4
+; MMR6-NEXT: selnez $4, $6, $4
+; MMR6-NEXT: or $3, $3, $4
+; MMR6-NEXT: xor $3, $1, $3
+; MMR6-NEXT: and $3, $3, $7
+; MMR6-NEXT: xor $3, $1, $3
+; MMR6-NEXT: sc $3, 0($5)
+; MMR6-NEXT: beqc $3, $zero, $BB5_1
; MMR6-NEXT: # %bb.2: # %entry
-; MMR6-NEXT: .insn
-; MMR6-NEXT: # %bb.3: # %entry
-; MMR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMR6-NEXT: # %bb.4: # %entry
-; MMR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMR6-NEXT: srlv $2, $1, $2
; MMR6-NEXT: sync
+; MMR6-NEXT: lw $16, 4($sp) # 4-byte Folded Reload
; MMR6-NEXT: addiu $sp, $sp, 8
; MMR6-NEXT: jrc $ra
;
+; MIPS2-LABEL: test_min_16:
+; MIPS2: # %bb.0: # %entry
+; MIPS2-NEXT: move $1, $5
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: addiu $2, $zero, -4
+; MIPS2-NEXT: and $5, $4, $2
+; MIPS2-NEXT: sll $2, $4, 3
+; MIPS2-NEXT: andi $3, $2, 24
+; MIPS2-NEXT: ori $4, $zero, 65535
+; MIPS2-NEXT: sllv $7, $4, $2
+; MIPS2-NEXT: sllv $6, $1, $2
+; MIPS2-NEXT: addiu $1, $zero, 16
+; MIPS2-NEXT: subu $8, $1, $3
+; MIPS2-NEXT: $BB5_1: # %entry
+; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
+; MIPS2-NEXT: ll $1, 0($5)
+; MIPS2-NEXT: and $3, $1, $7
+; MIPS2-NEXT: sllv $3, $3, $8
+; MIPS2-NEXT: srav $3, $3, $8
+; MIPS2-NEXT: slt $4, $6, $3
+; MIPS2-NEXT: beqz $4, $BB5_3
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.2: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB5_1 Depth=1
+; MIPS2-NEXT: move $3, $6
+; MIPS2-NEXT: $BB5_3: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB5_1 Depth=1
+; MIPS2-NEXT: xor $3, $1, $3
+; MIPS2-NEXT: and $3, $3, $7
+; MIPS2-NEXT: xor $3, $1, $3
+; MIPS2-NEXT: sc $3, 0($5)
+; MIPS2-NEXT: beqz $3, $BB5_1
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.4: # %entry
+; MIPS2-NEXT: srlv $2, $1, $2
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: jr $ra
+; MIPS2-NEXT: nop
+;
; MIPS32-LABEL: test_min_16:
; MIPS32: # %bb.0: # %entry
-; MIPS32-NEXT: addiu $sp, $sp, -8
-; MIPS32-NEXT: .cfi_def_cfa_offset 8
+; MIPS32-NEXT: move $1, $5
; MIPS32-NEXT: sync
-; MIPS32-NEXT: addiu $1, $zero, -4
-; MIPS32-NEXT: and $6, $4, $1
-; MIPS32-NEXT: andi $1, $4, 3
-; MIPS32-NEXT: sll $10, $1, 3
-; MIPS32-NEXT: ori $1, $zero, 65535
-; MIPS32-NEXT: sllv $8, $1, $10
-; MIPS32-NEXT: nor $9, $zero, $8
-; MIPS32-NEXT: sllv $7, $5, $10
+; MIPS32-NEXT: addiu $2, $zero, -4
+; MIPS32-NEXT: and $5, $4, $2
+; MIPS32-NEXT: sll $2, $4, 3
+; MIPS32-NEXT: andi $3, $2, 24
+; MIPS32-NEXT: ori $4, $zero, 65535
+; MIPS32-NEXT: sllv $7, $4, $2
+; MIPS32-NEXT: sllv $6, $1, $2
+; MIPS32-NEXT: addiu $1, $zero, 16
+; MIPS32-NEXT: subu $8, $1, $3
; MIPS32-NEXT: $BB5_1: # %entry
; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32-NEXT: ll $2, 0($6)
-; MIPS32-NEXT: srav $4, $2, $10
-; MIPS32-NEXT: sll $4, $4, 16
-; MIPS32-NEXT: sra $4, $4, 16
-; MIPS32-NEXT: or $1, $zero, $4
-; MIPS32-NEXT: sllv $4, $4, $10
-; MIPS32-NEXT: slt $5, $4, $7
-; MIPS32-NEXT: move $3, $4
-; MIPS32-NEXT: movz $3, $7, $5
-; MIPS32-NEXT: and $3, $3, $8
-; MIPS32-NEXT: and $4, $2, $9
-; MIPS32-NEXT: or $4, $4, $3
-; MIPS32-NEXT: sc $4, 0($6)
-; MIPS32-NEXT: beqz $4, $BB5_1
+; MIPS32-NEXT: ll $1, 0($5)
+; MIPS32-NEXT: and $3, $1, $7
+; MIPS32-NEXT: sllv $3, $3, $8
+; MIPS32-NEXT: srav $3, $3, $8
+; MIPS32-NEXT: slt $4, $6, $3
+; MIPS32-NEXT: movn $3, $6, $4
+; MIPS32-NEXT: xor $3, $1, $3
+; MIPS32-NEXT: and $3, $3, $7
+; MIPS32-NEXT: xor $3, $1, $3
+; MIPS32-NEXT: sc $3, 0($5)
+; MIPS32-NEXT: beqz $3, $BB5_1
; MIPS32-NEXT: nop
; MIPS32-NEXT: # %bb.2: # %entry
-; MIPS32-NEXT: .insn
-; MIPS32-NEXT: # %bb.3: # %entry
-; MIPS32-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32-NEXT: # %bb.4: # %entry
-; MIPS32-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPS32-NEXT: srlv $2, $1, $2
; MIPS32-NEXT: sync
-; MIPS32-NEXT: addiu $sp, $sp, 8
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPSEL-LABEL: test_min_16:
; MIPSEL: # %bb.0: # %entry
-; MIPSEL-NEXT: addiu $sp, $sp, -8
-; MIPSEL-NEXT: .cfi_def_cfa_offset 8
+; MIPSEL-NEXT: move $1, $5
; MIPSEL-NEXT: sync
-; MIPSEL-NEXT: addiu $1, $zero, -4
-; MIPSEL-NEXT: and $6, $4, $1
-; MIPSEL-NEXT: andi $1, $4, 3
-; MIPSEL-NEXT: sll $10, $1, 3
-; MIPSEL-NEXT: ori $1, $zero, 65535
-; MIPSEL-NEXT: sllv $8, $1, $10
-; MIPSEL-NEXT: nor $9, $zero, $8
-; MIPSEL-NEXT: sllv $7, $5, $10
+; MIPSEL-NEXT: addiu $2, $zero, -4
+; MIPSEL-NEXT: and $5, $4, $2
+; MIPSEL-NEXT: sll $2, $4, 3
+; MIPSEL-NEXT: andi $3, $2, 24
+; MIPSEL-NEXT: ori $4, $zero, 65535
+; MIPSEL-NEXT: sllv $7, $4, $2
+; MIPSEL-NEXT: sllv $6, $1, $2
+; MIPSEL-NEXT: addiu $1, $zero, 16
+; MIPSEL-NEXT: subu $8, $1, $3
; MIPSEL-NEXT: $BB5_1: # %entry
; MIPSEL-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSEL-NEXT: ll $2, 0($6)
-; MIPSEL-NEXT: srav $4, $2, $10
-; MIPSEL-NEXT: seh $4, $4
-; MIPSEL-NEXT: or $1, $zero, $4
-; MIPSEL-NEXT: sllv $4, $4, $10
-; MIPSEL-NEXT: slt $5, $4, $7
-; MIPSEL-NEXT: move $3, $4
-; MIPSEL-NEXT: movz $3, $7, $5
-; MIPSEL-NEXT: and $3, $3, $8
-; MIPSEL-NEXT: and $4, $2, $9
-; MIPSEL-NEXT: or $4, $4, $3
-; MIPSEL-NEXT: sc $4, 0($6)
-; MIPSEL-NEXT: beqz $4, $BB5_1
+; MIPSEL-NEXT: ll $1, 0($5)
+; MIPSEL-NEXT: and $3, $1, $7
+; MIPSEL-NEXT: sllv $3, $3, $8
+; MIPSEL-NEXT: srav $3, $3, $8
+; MIPSEL-NEXT: slt $4, $6, $3
+; MIPSEL-NEXT: movn $3, $6, $4
+; MIPSEL-NEXT: xor $3, $1, $3
+; MIPSEL-NEXT: and $3, $3, $7
+; MIPSEL-NEXT: xor $3, $1, $3
+; MIPSEL-NEXT: sc $3, 0($5)
+; MIPSEL-NEXT: beqz $3, $BB5_1
; MIPSEL-NEXT: nop
; MIPSEL-NEXT: # %bb.2: # %entry
-; MIPSEL-NEXT: .insn
-; MIPSEL-NEXT: # %bb.3: # %entry
-; MIPSEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSEL-NEXT: # %bb.4: # %entry
-; MIPSEL-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSEL-NEXT: srlv $2, $1, $2
; MIPSEL-NEXT: sync
-; MIPSEL-NEXT: addiu $sp, $sp, 8
; MIPSEL-NEXT: jr $ra
; MIPSEL-NEXT: nop
;
; MIPSELR6-LABEL: test_min_16:
; MIPSELR6: # %bb.0: # %entry
-; MIPSELR6-NEXT: addiu $sp, $sp, -8
-; MIPSELR6-NEXT: .cfi_def_cfa_offset 8
+; MIPSELR6-NEXT: move $1, $5
; MIPSELR6-NEXT: sync
-; MIPSELR6-NEXT: addiu $1, $zero, -4
-; MIPSELR6-NEXT: and $6, $4, $1
-; MIPSELR6-NEXT: andi $1, $4, 3
-; MIPSELR6-NEXT: sll $10, $1, 3
-; MIPSELR6-NEXT: ori $1, $zero, 65535
-; MIPSELR6-NEXT: sllv $8, $1, $10
-; MIPSELR6-NEXT: nor $9, $zero, $8
-; MIPSELR6-NEXT: sllv $7, $5, $10
+; MIPSELR6-NEXT: addiu $2, $zero, -4
+; MIPSELR6-NEXT: and $5, $4, $2
+; MIPSELR6-NEXT: sll $2, $4, 3
+; MIPSELR6-NEXT: andi $3, $2, 24
+; MIPSELR6-NEXT: ori $4, $zero, 65535
+; MIPSELR6-NEXT: sllv $7, $4, $2
+; MIPSELR6-NEXT: sllv $6, $1, $2
+; MIPSELR6-NEXT: addiu $1, $zero, 16
+; MIPSELR6-NEXT: subu $8, $1, $3
; MIPSELR6-NEXT: $BB5_1: # %entry
; MIPSELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSELR6-NEXT: ll $2, 0($6)
-; MIPSELR6-NEXT: srav $4, $2, $10
-; MIPSELR6-NEXT: seh $4, $4
-; MIPSELR6-NEXT: or $1, $zero, $4
-; MIPSELR6-NEXT: sllv $4, $4, $10
-; MIPSELR6-NEXT: slt $5, $4, $7
-; MIPSELR6-NEXT: selnez $3, $4, $5
-; MIPSELR6-NEXT: seleqz $5, $7, $5
-; MIPSELR6-NEXT: or $3, $3, $5
-; MIPSELR6-NEXT: and $3, $3, $8
-; MIPSELR6-NEXT: and $4, $2, $9
-; MIPSELR6-NEXT: or $4, $4, $3
-; MIPSELR6-NEXT: sc $4, 0($6)
-; MIPSELR6-NEXT: beqzc $4, $BB5_1
-; MIPSELR6-NEXT: nop
+; MIPSELR6-NEXT: ll $1, 0($5)
+; MIPSELR6-NEXT: and $3, $1, $7
+; MIPSELR6-NEXT: sllv $3, $3, $8
+; MIPSELR6-NEXT: srav $3, $3, $8
+; MIPSELR6-NEXT: slt $4, $6, $3
+; MIPSELR6-NEXT: seleqz $3, $3, $4
+; MIPSELR6-NEXT: selnez $4, $6, $4
+; MIPSELR6-NEXT: or $3, $3, $4
+; MIPSELR6-NEXT: xor $3, $1, $3
+; MIPSELR6-NEXT: and $3, $3, $7
+; MIPSELR6-NEXT: xor $3, $1, $3
+; MIPSELR6-NEXT: sc $3, 0($5)
+; MIPSELR6-NEXT: beqzc $3, $BB5_1
; MIPSELR6-NEXT: # %bb.2: # %entry
-; MIPSELR6-NEXT: .insn
-; MIPSELR6-NEXT: # %bb.3: # %entry
-; MIPSELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSELR6-NEXT: # %bb.4: # %entry
-; MIPSELR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSELR6-NEXT: srlv $2, $1, $2
; MIPSELR6-NEXT: sync
-; MIPSELR6-NEXT: addiu $sp, $sp, 8
; MIPSELR6-NEXT: jrc $ra
;
; MMEL-LABEL: test_min_16:
; MMEL: # %bb.0: # %entry
; MMEL-NEXT: addiu $sp, $sp, -8
; MMEL-NEXT: .cfi_def_cfa_offset 8
+; MMEL-NEXT: sw $16, 4($sp) # 4-byte Folded Spill
+; MMEL-NEXT: .cfi_offset 16, -4
+; MMEL-NEXT: move $1, $5
; MMEL-NEXT: sync
-; MMEL-NEXT: addiu $1, $zero, -4
-; MMEL-NEXT: and $6, $4, $1
-; MMEL-NEXT: andi $1, $4, 3
-; MMEL-NEXT: sll $10, $1, 3
-; MMEL-NEXT: ori $1, $zero, 65535
-; MMEL-NEXT: sllv $8, $1, $10
-; MMEL-NEXT: nor $9, $zero, $8
-; MMEL-NEXT: sllv $7, $5, $10
+; MMEL-NEXT: addiu $5, $zero, -4
+; MMEL-NEXT: and16 $5, $4
+; MMEL-NEXT: sll16 $2, $4, 3
+; MMEL-NEXT: andi $2, $2, 24
+; MMEL-NEXT: ori $3, $zero, 65535
+; MMEL-NEXT: sllv $7, $3, $2
+; MMEL-NEXT: sllv $6, $1, $2
+; MMEL-NEXT: li16 $3, 16
+; MMEL-NEXT: subu16 $16, $3, $2
; MMEL-NEXT: $BB5_1: # %entry
; MMEL-NEXT: # =>This Inner Loop Header: Depth=1
-; MMEL-NEXT: ll $2, 0($6)
-; MMEL-NEXT: srav $4, $2, $10
-; MMEL-NEXT: seh $4, $4
-; MMEL-NEXT: or $1, $zero, $4
-; MMEL-NEXT: sllv $4, $4, $10
-; MMEL-NEXT: slt $5, $4, $7
-; MMEL-NEXT: or $3, $4, $zero
-; MMEL-NEXT: movz $3, $7, $5
-; MMEL-NEXT: and $3, $3, $8
-; MMEL-NEXT: and $4, $2, $9
-; MMEL-NEXT: or $4, $4, $3
-; MMEL-NEXT: sc $4, 0($6)
-; MMEL-NEXT: beqzc $4, $BB5_1
+; MMEL-NEXT: ll $1, 0($5)
+; MMEL-NEXT: and $3, $1, $7
+; MMEL-NEXT: sllv $3, $3, $16
+; MMEL-NEXT: srav $3, $3, $16
+; MMEL-NEXT: slt $4, $6, $3
+; MMEL-NEXT: movn $3, $6, $4
+; MMEL-NEXT: xor $3, $1, $3
+; MMEL-NEXT: and $3, $3, $7
+; MMEL-NEXT: xor $3, $1, $3
+; MMEL-NEXT: sc $3, 0($5)
+; MMEL-NEXT: beqzc $3, $BB5_1
; MMEL-NEXT: # %bb.2: # %entry
-; MMEL-NEXT: .insn
-; MMEL-NEXT: # %bb.3: # %entry
-; MMEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMEL-NEXT: # %bb.4: # %entry
-; MMEL-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMEL-NEXT: srlv $2, $1, $2
; MMEL-NEXT: sync
+; MMEL-NEXT: lw $16, 4($sp) # 4-byte Folded Reload
; MMEL-NEXT: addiusp 8
; MMEL-NEXT: jrc $ra
;
@@ -1960,205 +1820,181 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) {
; MMELR6: # %bb.0: # %entry
; MMELR6-NEXT: addiu $sp, $sp, -8
; MMELR6-NEXT: .cfi_def_cfa_offset 8
+; MMELR6-NEXT: sw $16, 4($sp) # 4-byte Folded Spill
+; MMELR6-NEXT: .cfi_offset 16, -4
+; MMELR6-NEXT: move $1, $5
; MMELR6-NEXT: sync
-; MMELR6-NEXT: addiu $1, $zero, -4
-; MMELR6-NEXT: and $6, $4, $1
-; MMELR6-NEXT: andi $1, $4, 3
-; MMELR6-NEXT: sll $10, $1, 3
-; MMELR6-NEXT: ori $1, $zero, 65535
-; MMELR6-NEXT: sllv $8, $1, $10
-; MMELR6-NEXT: nor $9, $zero, $8
-; MMELR6-NEXT: sllv $7, $5, $10
+; MMELR6-NEXT: addiu $2, $zero, -4
+; MMELR6-NEXT: and $5, $4, $2
+; MMELR6-NEXT: sll16 $2, $4, 3
+; MMELR6-NEXT: andi $2, $2, 24
+; MMELR6-NEXT: ori $3, $zero, 65535
+; MMELR6-NEXT: sllv $7, $3, $2
+; MMELR6-NEXT: sllv $6, $1, $2
+; MMELR6-NEXT: li16 $3, 16
+; MMELR6-NEXT: subu16 $16, $3, $2
; MMELR6-NEXT: $BB5_1: # %entry
; MMELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MMELR6-NEXT: ll $2, 0($6)
-; MMELR6-NEXT: srav $4, $2, $10
-; MMELR6-NEXT: seh $4, $4
-; MMELR6-NEXT: or $1, $zero, $4
-; MMELR6-NEXT: sllv $4, $4, $10
-; MMELR6-NEXT: slt $5, $4, $7
-; MMELR6-NEXT: selnez $3, $4, $5
-; MMELR6-NEXT: seleqz $5, $7, $5
-; MMELR6-NEXT: or $3, $3, $5
-; MMELR6-NEXT: and $3, $3, $8
-; MMELR6-NEXT: and $4, $2, $9
-; MMELR6-NEXT: or $4, $4, $3
-; MMELR6-NEXT: sc $4, 0($6)
-; MMELR6-NEXT: beqc $4, $zero, $BB5_1
+; MMELR6-NEXT: ll $1, 0($5)
+; MMELR6-NEXT: and $3, $1, $7
+; MMELR6-NEXT: sllv $3, $3, $16
+; MMELR6-NEXT: srav $3, $3, $16
+; MMELR6-NEXT: slt $4, $6, $3
+; MMELR6-NEXT: seleqz $3, $3, $4
+; MMELR6-NEXT: selnez $4, $6, $4
+; MMELR6-NEXT: or $3, $3, $4
+; MMELR6-NEXT: xor $3, $1, $3
+; MMELR6-NEXT: and $3, $3, $7
+; MMELR6-NEXT: xor $3, $1, $3
+; MMELR6-NEXT: sc $3, 0($5)
+; MMELR6-NEXT: beqc $3, $zero, $BB5_1
; MMELR6-NEXT: # %bb.2: # %entry
-; MMELR6-NEXT: .insn
-; MMELR6-NEXT: # %bb.3: # %entry
-; MMELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMELR6-NEXT: # %bb.4: # %entry
-; MMELR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMELR6-NEXT: srlv $2, $1, $2
; MMELR6-NEXT: sync
+; MMELR6-NEXT: lw $16, 4($sp) # 4-byte Folded Reload
; MMELR6-NEXT: addiu $sp, $sp, 8
; MMELR6-NEXT: jrc $ra
;
; MIPS64-LABEL: test_min_16:
; MIPS64: # %bb.0: # %entry
-; MIPS64-NEXT: daddiu $sp, $sp, -16
-; MIPS64-NEXT: .cfi_def_cfa_offset 16
; MIPS64-NEXT: move $1, $5
; MIPS64-NEXT: sync
; MIPS64-NEXT: daddiu $2, $zero, -4
-; MIPS64-NEXT: and $6, $4, $2
-; MIPS64-NEXT: andi $2, $4, 3
+; MIPS64-NEXT: and $5, $4, $2
+; MIPS64-NEXT: move $2, $4
+; MIPS64-NEXT: sll $2, $2, 0
+; MIPS64-NEXT: andi $2, $2, 3
; MIPS64-NEXT: xori $2, $2, 2
-; MIPS64-NEXT: sll $10, $2, 3
-; MIPS64-NEXT: ori $2, $zero, 65535
-; MIPS64-NEXT: sllv $8, $2, $10
-; MIPS64-NEXT: nor $9, $zero, $8
-; MIPS64-NEXT: sllv $7, $1, $10
+; MIPS64-NEXT: sll $2, $2, 3
+; MIPS64-NEXT: ori $3, $zero, 65535
+; MIPS64-NEXT: sllv $7, $3, $2
+; MIPS64-NEXT: sllv $6, $1, $2
+; MIPS64-NEXT: addiu $1, $zero, 16
+; MIPS64-NEXT: subu $8, $1, $2
; MIPS64-NEXT: .LBB5_1: # %entry
; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64-NEXT: ll $2, 0($6)
-; MIPS64-NEXT: srav $4, $2, $10
-; MIPS64-NEXT: seh $4, $4
-; MIPS64-NEXT: or $1, $zero, $4
-; MIPS64-NEXT: sllv $4, $4, $10
-; MIPS64-NEXT: slt $5, $4, $7
-; MIPS64-NEXT: move $3, $4
-; MIPS64-NEXT: movz $3, $7, $5
-; MIPS64-NEXT: and $3, $3, $8
-; MIPS64-NEXT: and $4, $2, $9
-; MIPS64-NEXT: or $4, $4, $3
-; MIPS64-NEXT: sc $4, 0($6)
-; MIPS64-NEXT: beqz $4, .LBB5_1
+; MIPS64-NEXT: ll $1, 0($5)
+; MIPS64-NEXT: and $3, $1, $7
+; MIPS64-NEXT: sllv $3, $3, $8
+; MIPS64-NEXT: srav $3, $3, $8
+; MIPS64-NEXT: slt $4, $6, $3
+; MIPS64-NEXT: movn $3, $6, $4
+; MIPS64-NEXT: xor $3, $1, $3
+; MIPS64-NEXT: and $3, $3, $7
+; MIPS64-NEXT: xor $3, $1, $3
+; MIPS64-NEXT: sc $3, 0($5)
+; MIPS64-NEXT: beqz $3, .LBB5_1
; MIPS64-NEXT: nop
; MIPS64-NEXT: # %bb.2: # %entry
-; MIPS64-NEXT: .insn
-; MIPS64-NEXT: # %bb.3: # %entry
-; MIPS64-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64-NEXT: # %bb.4: # %entry
-; MIPS64-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64-NEXT: srlv $2, $1, $2
; MIPS64-NEXT: sync
-; MIPS64-NEXT: daddiu $sp, $sp, 16
; MIPS64-NEXT: jr $ra
; MIPS64-NEXT: nop
;
; MIPS64R6-LABEL: test_min_16:
; MIPS64R6: # %bb.0: # %entry
-; MIPS64R6-NEXT: daddiu $sp, $sp, -16
-; MIPS64R6-NEXT: .cfi_def_cfa_offset 16
; MIPS64R6-NEXT: move $1, $5
; MIPS64R6-NEXT: sync
; MIPS64R6-NEXT: daddiu $2, $zero, -4
-; MIPS64R6-NEXT: and $6, $4, $2
-; MIPS64R6-NEXT: andi $2, $4, 3
+; MIPS64R6-NEXT: and $5, $4, $2
+; MIPS64R6-NEXT: move $2, $4
+; MIPS64R6-NEXT: sll $2, $2, 0
+; MIPS64R6-NEXT: andi $2, $2, 3
; MIPS64R6-NEXT: xori $2, $2, 2
-; MIPS64R6-NEXT: sll $10, $2, 3
-; MIPS64R6-NEXT: ori $2, $zero, 65535
-; MIPS64R6-NEXT: sllv $8, $2, $10
-; MIPS64R6-NEXT: nor $9, $zero, $8
-; MIPS64R6-NEXT: sllv $7, $1, $10
+; MIPS64R6-NEXT: sll $2, $2, 3
+; MIPS64R6-NEXT: ori $3, $zero, 65535
+; MIPS64R6-NEXT: sllv $7, $3, $2
+; MIPS64R6-NEXT: sllv $6, $1, $2
+; MIPS64R6-NEXT: addiu $1, $zero, 16
+; MIPS64R6-NEXT: subu $8, $1, $2
; MIPS64R6-NEXT: .LBB5_1: # %entry
; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R6-NEXT: ll $2, 0($6)
-; MIPS64R6-NEXT: srav $4, $2, $10
-; MIPS64R6-NEXT: seh $4, $4
-; MIPS64R6-NEXT: or $1, $zero, $4
-; MIPS64R6-NEXT: sllv $4, $4, $10
-; MIPS64R6-NEXT: slt $5, $4, $7
-; MIPS64R6-NEXT: selnez $3, $4, $5
-; MIPS64R6-NEXT: seleqz $5, $7, $5
-; MIPS64R6-NEXT: or $3, $3, $5
-; MIPS64R6-NEXT: and $3, $3, $8
-; MIPS64R6-NEXT: and $4, $2, $9
-; MIPS64R6-NEXT: or $4, $4, $3
-; MIPS64R6-NEXT: sc $4, 0($6)
-; MIPS64R6-NEXT: beqzc $4, .LBB5_1
-; MIPS64R6-NEXT: nop
+; MIPS64R6-NEXT: ll $1, 0($5)
+; MIPS64R6-NEXT: and $3, $1, $7
+; MIPS64R6-NEXT: sllv $3, $3, $8
+; MIPS64R6-NEXT: srav $3, $3, $8
+; MIPS64R6-NEXT: slt $4, $6, $3
+; MIPS64R6-NEXT: seleqz $3, $3, $4
+; MIPS64R6-NEXT: selnez $4, $6, $4
+; MIPS64R6-NEXT: or $3, $3, $4
+; MIPS64R6-NEXT: xor $3, $1, $3
+; MIPS64R6-NEXT: and $3, $3, $7
+; MIPS64R6-NEXT: xor $3, $1, $3
+; MIPS64R6-NEXT: sc $3, 0($5)
+; MIPS64R6-NEXT: beqzc $3, .LBB5_1
; MIPS64R6-NEXT: # %bb.2: # %entry
-; MIPS64R6-NEXT: .insn
-; MIPS64R6-NEXT: # %bb.3: # %entry
-; MIPS64R6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64R6-NEXT: # %bb.4: # %entry
-; MIPS64R6-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64R6-NEXT: srlv $2, $1, $2
; MIPS64R6-NEXT: sync
-; MIPS64R6-NEXT: daddiu $sp, $sp, 16
; MIPS64R6-NEXT: jrc $ra
;
; MIPS64EL-LABEL: test_min_16:
; MIPS64EL: # %bb.0: # %entry
-; MIPS64EL-NEXT: daddiu $sp, $sp, -16
-; MIPS64EL-NEXT: .cfi_def_cfa_offset 16
; MIPS64EL-NEXT: move $1, $5
; MIPS64EL-NEXT: sync
; MIPS64EL-NEXT: daddiu $2, $zero, -4
-; MIPS64EL-NEXT: and $6, $4, $2
-; MIPS64EL-NEXT: andi $2, $4, 3
-; MIPS64EL-NEXT: sll $10, $2, 3
-; MIPS64EL-NEXT: ori $2, $zero, 65535
-; MIPS64EL-NEXT: sllv $8, $2, $10
-; MIPS64EL-NEXT: nor $9, $zero, $8
-; MIPS64EL-NEXT: sllv $7, $1, $10
+; MIPS64EL-NEXT: and $5, $4, $2
+; MIPS64EL-NEXT: move $2, $4
+; MIPS64EL-NEXT: sll $2, $2, 0
+; MIPS64EL-NEXT: andi $2, $2, 3
+; MIPS64EL-NEXT: sll $2, $2, 3
+; MIPS64EL-NEXT: ori $3, $zero, 65535
+; MIPS64EL-NEXT: sllv $7, $3, $2
+; MIPS64EL-NEXT: sllv $6, $1, $2
+; MIPS64EL-NEXT: addiu $1, $zero, 16
+; MIPS64EL-NEXT: subu $8, $1, $2
; MIPS64EL-NEXT: .LBB5_1: # %entry
; MIPS64EL-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64EL-NEXT: ll $2, 0($6)
-; MIPS64EL-NEXT: srav $4, $2, $10
-; MIPS64EL-NEXT: seh $4, $4
-; MIPS64EL-NEXT: or $1, $zero, $4
-; MIPS64EL-NEXT: sllv $4, $4, $10
-; MIPS64EL-NEXT: slt $5, $4, $7
-; MIPS64EL-NEXT: move $3, $4
-; MIPS64EL-NEXT: movz $3, $7, $5
-; MIPS64EL-NEXT: and $3, $3, $8
-; MIPS64EL-NEXT: and $4, $2, $9
-; MIPS64EL-NEXT: or $4, $4, $3
-; MIPS64EL-NEXT: sc $4, 0($6)
-; MIPS64EL-NEXT: beqz $4, .LBB5_1
+; MIPS64EL-NEXT: ll $1, 0($5)
+; MIPS64EL-NEXT: and $3, $1, $7
+; MIPS64EL-NEXT: sllv $3, $3, $8
+; MIPS64EL-NEXT: srav $3, $3, $8
+; MIPS64EL-NEXT: slt $4, $6, $3
+; MIPS64EL-NEXT: movn $3, $6, $4
+; MIPS64EL-NEXT: xor $3, $1, $3
+; MIPS64EL-NEXT: and $3, $3, $7
+; MIPS64EL-NEXT: xor $3, $1, $3
+; MIPS64EL-NEXT: sc $3, 0($5)
+; MIPS64EL-NEXT: beqz $3, .LBB5_1
; MIPS64EL-NEXT: nop
; MIPS64EL-NEXT: # %bb.2: # %entry
-; MIPS64EL-NEXT: .insn
-; MIPS64EL-NEXT: # %bb.3: # %entry
-; MIPS64EL-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64EL-NEXT: # %bb.4: # %entry
-; MIPS64EL-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64EL-NEXT: srlv $2, $1, $2
; MIPS64EL-NEXT: sync
-; MIPS64EL-NEXT: daddiu $sp, $sp, 16
; MIPS64EL-NEXT: jr $ra
; MIPS64EL-NEXT: nop
;
; MIPS64ELR6-LABEL: test_min_16:
; MIPS64ELR6: # %bb.0: # %entry
-; MIPS64ELR6-NEXT: daddiu $sp, $sp, -16
-; MIPS64ELR6-NEXT: .cfi_def_cfa_offset 16
; MIPS64ELR6-NEXT: move $1, $5
; MIPS64ELR6-NEXT: sync
; MIPS64ELR6-NEXT: daddiu $2, $zero, -4
-; MIPS64ELR6-NEXT: and $6, $4, $2
-; MIPS64ELR6-NEXT: andi $2, $4, 3
-; MIPS64ELR6-NEXT: sll $10, $2, 3
-; MIPS64ELR6-NEXT: ori $2, $zero, 65535
-; MIPS64ELR6-NEXT: sllv $8, $2, $10
-; MIPS64ELR6-NEXT: nor $9, $zero, $8
-; MIPS64ELR6-NEXT: sllv $7, $1, $10
+; MIPS64ELR6-NEXT: and $5, $4, $2
+; MIPS64ELR6-NEXT: move $2, $4
+; MIPS64ELR6-NEXT: sll $2, $2, 0
+; MIPS64ELR6-NEXT: andi $2, $2, 3
+; MIPS64ELR6-NEXT: sll $2, $2, 3
+; MIPS64ELR6-NEXT: ori $3, $zero, 65535
+; MIPS64ELR6-NEXT: sllv $7, $3, $2
+; MIPS64ELR6-NEXT: sllv $6, $1, $2
+; MIPS64ELR6-NEXT: addiu $1, $zero, 16
+; MIPS64ELR6-NEXT: subu $8, $1, $2
; MIPS64ELR6-NEXT: .LBB5_1: # %entry
; MIPS64ELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64ELR6-NEXT: ll $2, 0($6)
-; MIPS64ELR6-NEXT: srav $4, $2, $10
-; MIPS64ELR6-NEXT: seh $4, $4
-; MIPS64ELR6-NEXT: or $1, $zero, $4
-; MIPS64ELR6-NEXT: sllv $4, $4, $10
-; MIPS64ELR6-NEXT: slt $5, $4, $7
-; MIPS64ELR6-NEXT: selnez $3, $4, $5
-; MIPS64ELR6-NEXT: seleqz $5, $7, $5
-; MIPS64ELR6-NEXT: or $3, $3, $5
-; MIPS64ELR6-NEXT: and $3, $3, $8
-; MIPS64ELR6-NEXT: and $4, $2, $9
-; MIPS64ELR6-NEXT: or $4, $4, $3
-; MIPS64ELR6-NEXT: sc $4, 0($6)
-; MIPS64ELR6-NEXT: beqzc $4, .LBB5_1
-; MIPS64ELR6-NEXT: nop
+; MIPS64ELR6-NEXT: ll $1, 0($5)
+; MIPS64ELR6-NEXT: and $3, $1, $7
+; MIPS64ELR6-NEXT: sllv $3, $3, $8
+; MIPS64ELR6-NEXT: srav $3, $3, $8
+; MIPS64ELR6-NEXT: slt $4, $6, $3
+; MIPS64ELR6-NEXT: seleqz $3, $3, $4
+; MIPS64ELR6-NEXT: selnez $4, $6, $4
+; MIPS64ELR6-NEXT: or $3, $3, $4
+; MIPS64ELR6-NEXT: xor $3, $1, $3
+; MIPS64ELR6-NEXT: and $3, $3, $7
+; MIPS64ELR6-NEXT: xor $3, $1, $3
+; MIPS64ELR6-NEXT: sc $3, 0($5)
+; MIPS64ELR6-NEXT: beqzc $3, .LBB5_1
; MIPS64ELR6-NEXT: # %bb.2: # %entry
-; MIPS64ELR6-NEXT: .insn
-; MIPS64ELR6-NEXT: # %bb.3: # %entry
-; MIPS64ELR6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64ELR6-NEXT: # %bb.4: # %entry
-; MIPS64ELR6-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64ELR6-NEXT: srlv $2, $1, $2
; MIPS64ELR6-NEXT: sync
-; MIPS64ELR6-NEXT: daddiu $sp, $sp, 16
; MIPS64ELR6-NEXT: jrc $ra
entry:
%0 = atomicrmw min ptr %ptr, i16 %val seq_cst
@@ -2168,576 +2004,434 @@ entry:
define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) {
; MIPS-LABEL: test_umax_16:
; MIPS: # %bb.0: # %entry
-; MIPS-NEXT: addiu $sp, $sp, -8
-; MIPS-NEXT: .cfi_def_cfa_offset 8
+; MIPS-NEXT: move $1, $5
; MIPS-NEXT: sync
-; MIPS-NEXT: addiu $1, $zero, -4
-; MIPS-NEXT: and $6, $4, $1
-; MIPS-NEXT: andi $1, $4, 3
-; MIPS-NEXT: xori $1, $1, 2
-; MIPS-NEXT: sll $10, $1, 3
-; MIPS-NEXT: ori $1, $zero, 65535
-; MIPS-NEXT: sllv $8, $1, $10
-; MIPS-NEXT: nor $9, $zero, $8
-; MIPS-NEXT: sllv $7, $5, $10
+; MIPS-NEXT: addiu $2, $zero, -4
+; MIPS-NEXT: and $5, $4, $2
+; MIPS-NEXT: andi $2, $4, 3
+; MIPS-NEXT: xori $2, $2, 2
+; MIPS-NEXT: sll $2, $2, 3
+; MIPS-NEXT: ori $3, $zero, 65535
+; MIPS-NEXT: sllv $7, $3, $2
+; MIPS-NEXT: andi $1, $1, 65535
+; MIPS-NEXT: sllv $6, $1, $2
; MIPS-NEXT: $BB6_1: # %entry
; MIPS-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS-NEXT: ll $2, 0($6)
-; MIPS-NEXT: srav $4, $2, $10
-; MIPS-NEXT: andi $4, $4, 65535
-; MIPS-NEXT: or $1, $zero, $4
-; MIPS-NEXT: sllv $4, $4, $10
-; MIPS-NEXT: sltu $5, $4, $7
-; MIPS-NEXT: move $3, $4
-; MIPS-NEXT: movn $3, $7, $5
-; MIPS-NEXT: and $3, $3, $8
-; MIPS-NEXT: and $4, $2, $9
-; MIPS-NEXT: or $4, $4, $3
-; MIPS-NEXT: sc $4, 0($6)
-; MIPS-NEXT: beqz $4, $BB6_1
+; MIPS-NEXT: ll $1, 0($5)
+; MIPS-NEXT: and $3, $1, $7
+; MIPS-NEXT: sltu $4, $3, $6
+; MIPS-NEXT: movn $3, $6, $4
+; MIPS-NEXT: xor $3, $1, $3
+; MIPS-NEXT: and $3, $3, $7
+; MIPS-NEXT: xor $3, $1, $3
+; MIPS-NEXT: sc $3, 0($5)
+; MIPS-NEXT: beqz $3, $BB6_1
; MIPS-NEXT: nop
; MIPS-NEXT: # %bb.2: # %entry
-; MIPS-NEXT: .insn
-; MIPS-NEXT: # %bb.3: # %entry
-; MIPS-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS-NEXT: # %bb.4: # %entry
-; MIPS-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPS-NEXT: srlv $2, $1, $2
; MIPS-NEXT: sync
-; MIPS-NEXT: addiu $sp, $sp, 8
; MIPS-NEXT: jr $ra
; MIPS-NEXT: nop
;
-; MIPS2-LABEL: test_umax_16:
-; MIPS2: # %bb.0: # %entry
-; MIPS2-NEXT: addiu $sp, $sp, -8
-; MIPS2-NEXT: .cfi_def_cfa_offset 8
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: addiu $1, $zero, -4
-; MIPS2-NEXT: and $6, $4, $1
-; MIPS2-NEXT: andi $1, $4, 3
-; MIPS2-NEXT: sll $10, $1, 3
-; MIPS2-NEXT: ori $1, $zero, 65535
-; MIPS2-NEXT: sllv $8, $1, $10
-; MIPS2-NEXT: nor $9, $zero, $8
-; MIPS2-NEXT: sllv $7, $5, $10
-; MIPS2-NEXT: $BB6_1: # %entry
-; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS2-NEXT: ll $2, 0($6)
-; MIPS2-NEXT: srav $4, $2, $10
-; MIPS2-NEXT: andi $4, $4, 65535
-; MIPS2-NEXT: or $1, $zero, $4
-; MIPS2-NEXT: sllv $4, $4, $10
-; MIPS2-NEXT: sltu $5, $4, $7
-; MIPS2-NEXT: move $3, $7
-; MIPS2-NEXT: beqz $5, $BB6_3
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.2: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB6_1 Depth=1
-; MIPS2-NEXT: j $BB6_4
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: $BB6_3: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB6_1 Depth=1
-; MIPS2-NEXT: move $3, $4
-; MIPS2-NEXT: $BB6_4: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB6_1 Depth=1
-; MIPS2-NEXT: and $3, $3, $8
-; MIPS2-NEXT: and $4, $2, $9
-; MIPS2-NEXT: or $4, $4, $3
-; MIPS2-NEXT: sc $4, 0($6)
-; MIPS2-NEXT: beqz $4, $BB6_1
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.5: # %entry
-; MIPS2-NEXT: .insn
-; MIPS2-NEXT: # %bb.6: # %entry
-; MIPS2-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS2-NEXT: # %bb.7: # %entry
-; MIPS2-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: addiu $sp, $sp, 8
-; MIPS2-NEXT: jr $ra
-; MIPS2-NEXT: nop
-;
; MIPSR6-LABEL: test_umax_16:
; MIPSR6: # %bb.0: # %entry
-; MIPSR6-NEXT: addiu $sp, $sp, -8
-; MIPSR6-NEXT: .cfi_def_cfa_offset 8
+; MIPSR6-NEXT: move $1, $5
; MIPSR6-NEXT: sync
-; MIPSR6-NEXT: addiu $1, $zero, -4
-; MIPSR6-NEXT: and $6, $4, $1
-; MIPSR6-NEXT: andi $1, $4, 3
-; MIPSR6-NEXT: xori $1, $1, 2
-; MIPSR6-NEXT: sll $10, $1, 3
-; MIPSR6-NEXT: ori $1, $zero, 65535
-; MIPSR6-NEXT: sllv $8, $1, $10
-; MIPSR6-NEXT: nor $9, $zero, $8
-; MIPSR6-NEXT: sllv $7, $5, $10
+; MIPSR6-NEXT: addiu $2, $zero, -4
+; MIPSR6-NEXT: and $5, $4, $2
+; MIPSR6-NEXT: andi $2, $4, 3
+; MIPSR6-NEXT: xori $2, $2, 2
+; MIPSR6-NEXT: sll $2, $2, 3
+; MIPSR6-NEXT: ori $3, $zero, 65535
+; MIPSR6-NEXT: sllv $7, $3, $2
+; MIPSR6-NEXT: andi $1, $1, 65535
+; MIPSR6-NEXT: sllv $6, $1, $2
; MIPSR6-NEXT: $BB6_1: # %entry
; MIPSR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSR6-NEXT: ll $2, 0($6)
-; MIPSR6-NEXT: srav $4, $2, $10
-; MIPSR6-NEXT: andi $4, $4, 65535
-; MIPSR6-NEXT: or $1, $zero, $4
-; MIPSR6-NEXT: sllv $4, $4, $10
-; MIPSR6-NEXT: sltu $5, $4, $7
-; MIPSR6-NEXT: seleqz $3, $4, $5
-; MIPSR6-NEXT: selnez $5, $7, $5
-; MIPSR6-NEXT: or $3, $3, $5
-; MIPSR6-NEXT: and $3, $3, $8
-; MIPSR6-NEXT: and $4, $2, $9
-; MIPSR6-NEXT: or $4, $4, $3
-; MIPSR6-NEXT: sc $4, 0($6)
-; MIPSR6-NEXT: beqzc $4, $BB6_1
-; MIPSR6-NEXT: nop
+; MIPSR6-NEXT: ll $1, 0($5)
+; MIPSR6-NEXT: and $3, $1, $7
+; MIPSR6-NEXT: sltu $4, $3, $6
+; MIPSR6-NEXT: seleqz $3, $3, $4
+; MIPSR6-NEXT: selnez $4, $6, $4
+; MIPSR6-NEXT: or $3, $3, $4
+; MIPSR6-NEXT: xor $3, $1, $3
+; MIPSR6-NEXT: and $3, $3, $7
+; MIPSR6-NEXT: xor $3, $1, $3
+; MIPSR6-NEXT: sc $3, 0($5)
+; MIPSR6-NEXT: beqzc $3, $BB6_1
; MIPSR6-NEXT: # %bb.2: # %entry
-; MIPSR6-NEXT: .insn
-; MIPSR6-NEXT: # %bb.3: # %entry
-; MIPSR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSR6-NEXT: # %bb.4: # %entry
-; MIPSR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSR6-NEXT: srlv $2, $1, $2
; MIPSR6-NEXT: sync
-; MIPSR6-NEXT: addiu $sp, $sp, 8
; MIPSR6-NEXT: jrc $ra
;
; MM-LABEL: test_umax_16:
; MM: # %bb.0: # %entry
-; MM-NEXT: addiu $sp, $sp, -8
-; MM-NEXT: .cfi_def_cfa_offset 8
+; MM-NEXT: move $3, $5
; MM-NEXT: sync
-; MM-NEXT: addiu $1, $zero, -4
-; MM-NEXT: and $6, $4, $1
-; MM-NEXT: andi $1, $4, 3
-; MM-NEXT: xori $1, $1, 2
-; MM-NEXT: sll $10, $1, 3
+; MM-NEXT: addiu $5, $zero, -4
+; MM-NEXT: and16 $5, $4
+; MM-NEXT: andi16 $2, $4, 3
+; MM-NEXT: xori $2, $2, 2
+; MM-NEXT: sll16 $2, $2, 3
; MM-NEXT: ori $1, $zero, 65535
-; MM-NEXT: sllv $8, $1, $10
-; MM-NEXT: nor $9, $zero, $8
-; MM-NEXT: sllv $7, $5, $10
+; MM-NEXT: sllv $7, $1, $2
+; MM-NEXT: andi16 $3, $3, 65535
+; MM-NEXT: sllv $6, $3, $2
; MM-NEXT: $BB6_1: # %entry
; MM-NEXT: # =>This Inner Loop Header: Depth=1
-; MM-NEXT: ll $2, 0($6)
-; MM-NEXT: srav $4, $2, $10
-; MM-NEXT: andi $4, $4, 65535
-; MM-NEXT: or $1, $zero, $4
-; MM-NEXT: sllv $4, $4, $10
-; MM-NEXT: sltu $5, $4, $7
-; MM-NEXT: or $3, $4, $zero
-; MM-NEXT: movn $3, $7, $5
-; MM-NEXT: and $3, $3, $8
-; MM-NEXT: and $4, $2, $9
-; MM-NEXT: or $4, $4, $3
-; MM-NEXT: sc $4, 0($6)
-; MM-NEXT: beqzc $4, $BB6_1
+; MM-NEXT: ll $1, 0($5)
+; MM-NEXT: and $3, $1, $7
+; MM-NEXT: sltu $4, $3, $6
+; MM-NEXT: movn $3, $6, $4
+; MM-NEXT: xor $3, $1, $3
+; MM-NEXT: and $3, $3, $7
+; MM-NEXT: xor $3, $1, $3
+; MM-NEXT: sc $3, 0($5)
+; MM-NEXT: beqzc $3, $BB6_1
; MM-NEXT: # %bb.2: # %entry
-; MM-NEXT: .insn
-; MM-NEXT: # %bb.3: # %entry
-; MM-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MM-NEXT: # %bb.4: # %entry
-; MM-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MM-NEXT: srlv $2, $1, $2
; MM-NEXT: sync
-; MM-NEXT: addiusp 8
; MM-NEXT: jrc $ra
;
; MMR6-LABEL: test_umax_16:
; MMR6: # %bb.0: # %entry
-; MMR6-NEXT: addiu $sp, $sp, -8
-; MMR6-NEXT: .cfi_def_cfa_offset 8
+; MMR6-NEXT: move $3, $5
; MMR6-NEXT: sync
; MMR6-NEXT: addiu $1, $zero, -4
-; MMR6-NEXT: and $6, $4, $1
-; MMR6-NEXT: andi $1, $4, 3
-; MMR6-NEXT: xori $1, $1, 2
-; MMR6-NEXT: sll $10, $1, 3
+; MMR6-NEXT: and $5, $4, $1
+; MMR6-NEXT: andi16 $2, $4, 3
+; MMR6-NEXT: xori $2, $2, 2
+; MMR6-NEXT: sll16 $2, $2, 3
; MMR6-NEXT: ori $1, $zero, 65535
-; MMR6-NEXT: sllv $8, $1, $10
-; MMR6-NEXT: nor $9, $zero, $8
-; MMR6-NEXT: sllv $7, $5, $10
+; MMR6-NEXT: sllv $7, $1, $2
+; MMR6-NEXT: andi16 $3, $3, 65535
+; MMR6-NEXT: sllv $6, $3, $2
; MMR6-NEXT: $BB6_1: # %entry
; MMR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MMR6-NEXT: ll $2, 0($6)
-; MMR6-NEXT: srav $4, $2, $10
-; MMR6-NEXT: andi $4, $4, 65535
-; MMR6-NEXT: or $1, $zero, $4
-; MMR6-NEXT: sllv $4, $4, $10
-; MMR6-NEXT: sltu $5, $4, $7
-; MMR6-NEXT: seleqz $3, $4, $5
-; MMR6-NEXT: selnez $5, $7, $5
-; MMR6-NEXT: or $3, $3, $5
-; MMR6-NEXT: and $3, $3, $8
-; MMR6-NEXT: and $4, $2, $9
-; MMR6-NEXT: or $4, $4, $3
-; MMR6-NEXT: sc $4, 0($6)
-; MMR6-NEXT: beqc $4, $zero, $BB6_1
+; MMR6-NEXT: ll $1, 0($5)
+; MMR6-NEXT: and $3, $1, $7
+; MMR6-NEXT: sltu $4, $3, $6
+; MMR6-NEXT: seleqz $3, $3, $4
+; MMR6-NEXT: selnez $4, $6, $4
+; MMR6-NEXT: or $3, $3, $4
+; MMR6-NEXT: xor $3, $1, $3
+; MMR6-NEXT: and $3, $3, $7
+; MMR6-NEXT: xor $3, $1, $3
+; MMR6-NEXT: sc $3, 0($5)
+; MMR6-NEXT: beqc $3, $zero, $BB6_1
; MMR6-NEXT: # %bb.2: # %entry
-; MMR6-NEXT: .insn
-; MMR6-NEXT: # %bb.3: # %entry
-; MMR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMR6-NEXT: # %bb.4: # %entry
-; MMR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMR6-NEXT: srlv $2, $1, $2
; MMR6-NEXT: sync
-; MMR6-NEXT: addiu $sp, $sp, 8
; MMR6-NEXT: jrc $ra
;
+; MIPS2-LABEL: test_umax_16:
+; MIPS2: # %bb.0: # %entry
+; MIPS2-NEXT: move $1, $5
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: addiu $2, $zero, -4
+; MIPS2-NEXT: and $5, $4, $2
+; MIPS2-NEXT: sll $2, $4, 3
+; MIPS2-NEXT: ori $3, $zero, 65535
+; MIPS2-NEXT: sllv $7, $3, $2
+; MIPS2-NEXT: andi $1, $1, 65535
+; MIPS2-NEXT: sllv $6, $1, $2
+; MIPS2-NEXT: $BB6_1: # %entry
+; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
+; MIPS2-NEXT: ll $1, 0($5)
+; MIPS2-NEXT: and $3, $1, $7
+; MIPS2-NEXT: sltu $4, $3, $6
+; MIPS2-NEXT: beqz $4, $BB6_3
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.2: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB6_1 Depth=1
+; MIPS2-NEXT: move $3, $6
+; MIPS2-NEXT: $BB6_3: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB6_1 Depth=1
+; MIPS2-NEXT: xor $3, $1, $3
+; MIPS2-NEXT: and $3, $3, $7
+; MIPS2-NEXT: xor $3, $1, $3
+; MIPS2-NEXT: sc $3, 0($5)
+; MIPS2-NEXT: beqz $3, $BB6_1
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.4: # %entry
+; MIPS2-NEXT: srlv $2, $1, $2
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: jr $ra
+; MIPS2-NEXT: nop
+;
; MIPS32-LABEL: test_umax_16:
; MIPS32: # %bb.0: # %entry
-; MIPS32-NEXT: addiu $sp, $sp, -8
-; MIPS32-NEXT: .cfi_def_cfa_offset 8
+; MIPS32-NEXT: move $1, $5
; MIPS32-NEXT: sync
-; MIPS32-NEXT: addiu $1, $zero, -4
-; MIPS32-NEXT: and $6, $4, $1
-; MIPS32-NEXT: andi $1, $4, 3
-; MIPS32-NEXT: sll $10, $1, 3
-; MIPS32-NEXT: ori $1, $zero, 65535
-; MIPS32-NEXT: sllv $8, $1, $10
-; MIPS32-NEXT: nor $9, $zero, $8
-; MIPS32-NEXT: sllv $7, $5, $10
+; MIPS32-NEXT: addiu $2, $zero, -4
+; MIPS32-NEXT: and $5, $4, $2
+; MIPS32-NEXT: sll $2, $4, 3
+; MIPS32-NEXT: ori $3, $zero, 65535
+; MIPS32-NEXT: sllv $7, $3, $2
+; MIPS32-NEXT: andi $1, $1, 65535
+; MIPS32-NEXT: sllv $6, $1, $2
; MIPS32-NEXT: $BB6_1: # %entry
; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32-NEXT: ll $2, 0($6)
-; MIPS32-NEXT: srav $4, $2, $10
-; MIPS32-NEXT: andi $4, $4, 65535
-; MIPS32-NEXT: or $1, $zero, $4
-; MIPS32-NEXT: sllv $4, $4, $10
-; MIPS32-NEXT: sltu $5, $4, $7
-; MIPS32-NEXT: move $3, $4
-; MIPS32-NEXT: movn $3, $7, $5
-; MIPS32-NEXT: and $3, $3, $8
-; MIPS32-NEXT: and $4, $2, $9
-; MIPS32-NEXT: or $4, $4, $3
-; MIPS32-NEXT: sc $4, 0($6)
-; MIPS32-NEXT: beqz $4, $BB6_1
+; MIPS32-NEXT: ll $1, 0($5)
+; MIPS32-NEXT: and $3, $1, $7
+; MIPS32-NEXT: sltu $4, $3, $6
+; MIPS32-NEXT: movn $3, $6, $4
+; MIPS32-NEXT: xor $3, $1, $3
+; MIPS32-NEXT: and $3, $3, $7
+; MIPS32-NEXT: xor $3, $1, $3
+; MIPS32-NEXT: sc $3, 0($5)
+; MIPS32-NEXT: beqz $3, $BB6_1
; MIPS32-NEXT: nop
; MIPS32-NEXT: # %bb.2: # %entry
-; MIPS32-NEXT: .insn
-; MIPS32-NEXT: # %bb.3: # %entry
-; MIPS32-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32-NEXT: # %bb.4: # %entry
-; MIPS32-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPS32-NEXT: srlv $2, $1, $2
; MIPS32-NEXT: sync
-; MIPS32-NEXT: addiu $sp, $sp, 8
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPSEL-LABEL: test_umax_16:
; MIPSEL: # %bb.0: # %entry
-; MIPSEL-NEXT: addiu $sp, $sp, -8
-; MIPSEL-NEXT: .cfi_def_cfa_offset 8
+; MIPSEL-NEXT: move $1, $5
; MIPSEL-NEXT: sync
-; MIPSEL-NEXT: addiu $1, $zero, -4
-; MIPSEL-NEXT: and $6, $4, $1
-; MIPSEL-NEXT: andi $1, $4, 3
-; MIPSEL-NEXT: sll $10, $1, 3
-; MIPSEL-NEXT: ori $1, $zero, 65535
-; MIPSEL-NEXT: sllv $8, $1, $10
-; MIPSEL-NEXT: nor $9, $zero, $8
-; MIPSEL-NEXT: sllv $7, $5, $10
+; MIPSEL-NEXT: addiu $2, $zero, -4
+; MIPSEL-NEXT: and $5, $4, $2
+; MIPSEL-NEXT: sll $2, $4, 3
+; MIPSEL-NEXT: ori $3, $zero, 65535
+; MIPSEL-NEXT: sllv $7, $3, $2
+; MIPSEL-NEXT: andi $1, $1, 65535
+; MIPSEL-NEXT: sllv $6, $1, $2
; MIPSEL-NEXT: $BB6_1: # %entry
; MIPSEL-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSEL-NEXT: ll $2, 0($6)
-; MIPSEL-NEXT: srav $4, $2, $10
-; MIPSEL-NEXT: andi $4, $4, 65535
-; MIPSEL-NEXT: or $1, $zero, $4
-; MIPSEL-NEXT: sllv $4, $4, $10
-; MIPSEL-NEXT: sltu $5, $4, $7
-; MIPSEL-NEXT: move $3, $4
-; MIPSEL-NEXT: movn $3, $7, $5
-; MIPSEL-NEXT: and $3, $3, $8
-; MIPSEL-NEXT: and $4, $2, $9
-; MIPSEL-NEXT: or $4, $4, $3
-; MIPSEL-NEXT: sc $4, 0($6)
-; MIPSEL-NEXT: beqz $4, $BB6_1
+; MIPSEL-NEXT: ll $1, 0($5)
+; MIPSEL-NEXT: and $3, $1, $7
+; MIPSEL-NEXT: sltu $4, $3, $6
+; MIPSEL-NEXT: movn $3, $6, $4
+; MIPSEL-NEXT: xor $3, $1, $3
+; MIPSEL-NEXT: and $3, $3, $7
+; MIPSEL-NEXT: xor $3, $1, $3
+; MIPSEL-NEXT: sc $3, 0($5)
+; MIPSEL-NEXT: beqz $3, $BB6_1
; MIPSEL-NEXT: nop
; MIPSEL-NEXT: # %bb.2: # %entry
-; MIPSEL-NEXT: .insn
-; MIPSEL-NEXT: # %bb.3: # %entry
-; MIPSEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSEL-NEXT: # %bb.4: # %entry
-; MIPSEL-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSEL-NEXT: srlv $2, $1, $2
; MIPSEL-NEXT: sync
-; MIPSEL-NEXT: addiu $sp, $sp, 8
; MIPSEL-NEXT: jr $ra
; MIPSEL-NEXT: nop
;
; MIPSELR6-LABEL: test_umax_16:
; MIPSELR6: # %bb.0: # %entry
-; MIPSELR6-NEXT: addiu $sp, $sp, -8
-; MIPSELR6-NEXT: .cfi_def_cfa_offset 8
+; MIPSELR6-NEXT: move $1, $5
; MIPSELR6-NEXT: sync
-; MIPSELR6-NEXT: addiu $1, $zero, -4
-; MIPSELR6-NEXT: and $6, $4, $1
-; MIPSELR6-NEXT: andi $1, $4, 3
-; MIPSELR6-NEXT: sll $10, $1, 3
-; MIPSELR6-NEXT: ori $1, $zero, 65535
-; MIPSELR6-NEXT: sllv $8, $1, $10
-; MIPSELR6-NEXT: nor $9, $zero, $8
-; MIPSELR6-NEXT: sllv $7, $5, $10
+; MIPSELR6-NEXT: addiu $2, $zero, -4
+; MIPSELR6-NEXT: and $5, $4, $2
+; MIPSELR6-NEXT: sll $2, $4, 3
+; MIPSELR6-NEXT: ori $3, $zero, 65535
+; MIPSELR6-NEXT: sllv $7, $3, $2
+; MIPSELR6-NEXT: andi $1, $1, 65535
+; MIPSELR6-NEXT: sllv $6, $1, $2
; MIPSELR6-NEXT: $BB6_1: # %entry
; MIPSELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSELR6-NEXT: ll $2, 0($6)
-; MIPSELR6-NEXT: srav $4, $2, $10
-; MIPSELR6-NEXT: andi $4, $4, 65535
-; MIPSELR6-NEXT: or $1, $zero, $4
-; MIPSELR6-NEXT: sllv $4, $4, $10
-; MIPSELR6-NEXT: sltu $5, $4, $7
-; MIPSELR6-NEXT: seleqz $3, $4, $5
-; MIPSELR6-NEXT: selnez $5, $7, $5
-; MIPSELR6-NEXT: or $3, $3, $5
-; MIPSELR6-NEXT: and $3, $3, $8
-; MIPSELR6-NEXT: and $4, $2, $9
-; MIPSELR6-NEXT: or $4, $4, $3
-; MIPSELR6-NEXT: sc $4, 0($6)
-; MIPSELR6-NEXT: beqzc $4, $BB6_1
-; MIPSELR6-NEXT: nop
+; MIPSELR6-NEXT: ll $1, 0($5)
+; MIPSELR6-NEXT: and $3, $1, $7
+; MIPSELR6-NEXT: sltu $4, $3, $6
+; MIPSELR6-NEXT: seleqz $3, $3, $4
+; MIPSELR6-NEXT: selnez $4, $6, $4
+; MIPSELR6-NEXT: or $3, $3, $4
+; MIPSELR6-NEXT: xor $3, $1, $3
+; MIPSELR6-NEXT: and $3, $3, $7
+; MIPSELR6-NEXT: xor $3, $1, $3
+; MIPSELR6-NEXT: sc $3, 0($5)
+; MIPSELR6-NEXT: beqzc $3, $BB6_1
; MIPSELR6-NEXT: # %bb.2: # %entry
-; MIPSELR6-NEXT: .insn
-; MIPSELR6-NEXT: # %bb.3: # %entry
-; MIPSELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSELR6-NEXT: # %bb.4: # %entry
-; MIPSELR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSELR6-NEXT: srlv $2, $1, $2
; MIPSELR6-NEXT: sync
-; MIPSELR6-NEXT: addiu $sp, $sp, 8
; MIPSELR6-NEXT: jrc $ra
;
; MMEL-LABEL: test_umax_16:
; MMEL: # %bb.0: # %entry
-; MMEL-NEXT: addiu $sp, $sp, -8
-; MMEL-NEXT: .cfi_def_cfa_offset 8
+; MMEL-NEXT: move $3, $5
; MMEL-NEXT: sync
-; MMEL-NEXT: addiu $1, $zero, -4
-; MMEL-NEXT: and $6, $4, $1
-; MMEL-NEXT: andi $1, $4, 3
-; MMEL-NEXT: sll $10, $1, 3
+; MMEL-NEXT: addiu $5, $zero, -4
+; MMEL-NEXT: and16 $5, $4
+; MMEL-NEXT: sll16 $2, $4, 3
+; MMEL-NEXT: andi $2, $2, 24
; MMEL-NEXT: ori $1, $zero, 65535
-; MMEL-NEXT: sllv $8, $1, $10
-; MMEL-NEXT: nor $9, $zero, $8
-; MMEL-NEXT: sllv $7, $5, $10
+; MMEL-NEXT: sllv $7, $1, $2
+; MMEL-NEXT: andi16 $3, $3, 65535
+; MMEL-NEXT: sllv $6, $3, $2
; MMEL-NEXT: $BB6_1: # %entry
; MMEL-NEXT: # =>This Inner Loop Header: Depth=1
-; MMEL-NEXT: ll $2, 0($6)
-; MMEL-NEXT: srav $4, $2, $10
-; MMEL-NEXT: andi $4, $4, 65535
-; MMEL-NEXT: or $1, $zero, $4
-; MMEL-NEXT: sllv $4, $4, $10
-; MMEL-NEXT: sltu $5, $4, $7
-; MMEL-NEXT: or $3, $4, $zero
-; MMEL-NEXT: movn $3, $7, $5
-; MMEL-NEXT: and $3, $3, $8
-; MMEL-NEXT: and $4, $2, $9
-; MMEL-NEXT: or $4, $4, $3
-; MMEL-NEXT: sc $4, 0($6)
-; MMEL-NEXT: beqzc $4, $BB6_1
+; MMEL-NEXT: ll $1, 0($5)
+; MMEL-NEXT: and $3, $1, $7
+; MMEL-NEXT: sltu $4, $3, $6
+; MMEL-NEXT: movn $3, $6, $4
+; MMEL-NEXT: xor $3, $1, $3
+; MMEL-NEXT: and $3, $3, $7
+; MMEL-NEXT: xor $3, $1, $3
+; MMEL-NEXT: sc $3, 0($5)
+; MMEL-NEXT: beqzc $3, $BB6_1
; MMEL-NEXT: # %bb.2: # %entry
-; MMEL-NEXT: .insn
-; MMEL-NEXT: # %bb.3: # %entry
-; MMEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMEL-NEXT: # %bb.4: # %entry
-; MMEL-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMEL-NEXT: srlv $2, $1, $2
; MMEL-NEXT: sync
-; MMEL-NEXT: addiusp 8
; MMEL-NEXT: jrc $ra
;
; MMELR6-LABEL: test_umax_16:
; MMELR6: # %bb.0: # %entry
-; MMELR6-NEXT: addiu $sp, $sp, -8
-; MMELR6-NEXT: .cfi_def_cfa_offset 8
+; MMELR6-NEXT: move $3, $5
; MMELR6-NEXT: sync
; MMELR6-NEXT: addiu $1, $zero, -4
-; MMELR6-NEXT: and $6, $4, $1
-; MMELR6-NEXT: andi $1, $4, 3
-; MMELR6-NEXT: sll $10, $1, 3
+; MMELR6-NEXT: and $5, $4, $1
+; MMELR6-NEXT: sll16 $2, $4, 3
+; MMELR6-NEXT: andi $2, $2, 24
; MMELR6-NEXT: ori $1, $zero, 65535
-; MMELR6-NEXT: sllv $8, $1, $10
-; MMELR6-NEXT: nor $9, $zero, $8
-; MMELR6-NEXT: sllv $7, $5, $10
+; MMELR6-NEXT: sllv $7, $1, $2
+; MMELR6-NEXT: andi16 $3, $3, 65535
+; MMELR6-NEXT: sllv $6, $3, $2
; MMELR6-NEXT: $BB6_1: # %entry
; MMELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MMELR6-NEXT: ll $2, 0($6)
-; MMELR6-NEXT: srav $4, $2, $10
-; MMELR6-NEXT: andi $4, $4, 65535
-; MMELR6-NEXT: or $1, $zero, $4
-; MMELR6-NEXT: sllv $4, $4, $10
-; MMELR6-NEXT: sltu $5, $4, $7
-; MMELR6-NEXT: seleqz $3, $4, $5
-; MMELR6-NEXT: selnez $5, $7, $5
-; MMELR6-NEXT: or $3, $3, $5
-; MMELR6-NEXT: and $3, $3, $8
-; MMELR6-NEXT: and $4, $2, $9
-; MMELR6-NEXT: or $4, $4, $3
-; MMELR6-NEXT: sc $4, 0($6)
-; MMELR6-NEXT: beqc $4, $zero, $BB6_1
+; MMELR6-NEXT: ll $1, 0($5)
+; MMELR6-NEXT: and $3, $1, $7
+; MMELR6-NEXT: sltu $4, $3, $6
+; MMELR6-NEXT: seleqz $3, $3, $4
+; MMELR6-NEXT: selnez $4, $6, $4
+; MMELR6-NEXT: or $3, $3, $4
+; MMELR6-NEXT: xor $3, $1, $3
+; MMELR6-NEXT: and $3, $3, $7
+; MMELR6-NEXT: xor $3, $1, $3
+; MMELR6-NEXT: sc $3, 0($5)
+; MMELR6-NEXT: beqc $3, $zero, $BB6_1
; MMELR6-NEXT: # %bb.2: # %entry
-; MMELR6-NEXT: .insn
-; MMELR6-NEXT: # %bb.3: # %entry
-; MMELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMELR6-NEXT: # %bb.4: # %entry
-; MMELR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMELR6-NEXT: srlv $2, $1, $2
; MMELR6-NEXT: sync
-; MMELR6-NEXT: addiu $sp, $sp, 8
; MMELR6-NEXT: jrc $ra
;
; MIPS64-LABEL: test_umax_16:
; MIPS64: # %bb.0: # %entry
-; MIPS64-NEXT: daddiu $sp, $sp, -16
-; MIPS64-NEXT: .cfi_def_cfa_offset 16
; MIPS64-NEXT: move $1, $5
; MIPS64-NEXT: sync
; MIPS64-NEXT: daddiu $2, $zero, -4
-; MIPS64-NEXT: and $6, $4, $2
-; MIPS64-NEXT: andi $2, $4, 3
+; MIPS64-NEXT: and $5, $4, $2
+; MIPS64-NEXT: move $2, $4
+; MIPS64-NEXT: sll $2, $2, 0
+; MIPS64-NEXT: andi $2, $2, 3
; MIPS64-NEXT: xori $2, $2, 2
-; MIPS64-NEXT: sll $10, $2, 3
-; MIPS64-NEXT: ori $2, $zero, 65535
-; MIPS64-NEXT: sllv $8, $2, $10
-; MIPS64-NEXT: nor $9, $zero, $8
-; MIPS64-NEXT: sllv $7, $1, $10
+; MIPS64-NEXT: sll $2, $2, 3
+; MIPS64-NEXT: ori $3, $zero, 65535
+; MIPS64-NEXT: sllv $7, $3, $2
+; MIPS64-NEXT: andi $1, $1, 65535
+; MIPS64-NEXT: sllv $6, $1, $2
; MIPS64-NEXT: .LBB6_1: # %entry
; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64-NEXT: ll $2, 0($6)
-; MIPS64-NEXT: srav $4, $2, $10
-; MIPS64-NEXT: andi $4, $4, 65535
-; MIPS64-NEXT: or $1, $zero, $4
-; MIPS64-NEXT: sllv $4, $4, $10
-; MIPS64-NEXT: sltu $5, $4, $7
-; MIPS64-NEXT: move $3, $4
-; MIPS64-NEXT: movn $3, $7, $5
-; MIPS64-NEXT: and $3, $3, $8
-; MIPS64-NEXT: and $4, $2, $9
-; MIPS64-NEXT: or $4, $4, $3
-; MIPS64-NEXT: sc $4, 0($6)
-; MIPS64-NEXT: beqz $4, .LBB6_1
+; MIPS64-NEXT: ll $1, 0($5)
+; MIPS64-NEXT: and $3, $1, $7
+; MIPS64-NEXT: sltu $4, $3, $6
+; MIPS64-NEXT: movn $3, $6, $4
+; MIPS64-NEXT: xor $3, $1, $3
+; MIPS64-NEXT: and $3, $3, $7
+; MIPS64-NEXT: xor $3, $1, $3
+; MIPS64-NEXT: sc $3, 0($5)
+; MIPS64-NEXT: beqz $3, .LBB6_1
; MIPS64-NEXT: nop
; MIPS64-NEXT: # %bb.2: # %entry
-; MIPS64-NEXT: .insn
-; MIPS64-NEXT: # %bb.3: # %entry
-; MIPS64-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64-NEXT: # %bb.4: # %entry
-; MIPS64-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64-NEXT: srlv $2, $1, $2
; MIPS64-NEXT: sync
-; MIPS64-NEXT: daddiu $sp, $sp, 16
; MIPS64-NEXT: jr $ra
; MIPS64-NEXT: nop
;
; MIPS64R6-LABEL: test_umax_16:
; MIPS64R6: # %bb.0: # %entry
-; MIPS64R6-NEXT: daddiu $sp, $sp, -16
-; MIPS64R6-NEXT: .cfi_def_cfa_offset 16
; MIPS64R6-NEXT: move $1, $5
; MIPS64R6-NEXT: sync
; MIPS64R6-NEXT: daddiu $2, $zero, -4
-; MIPS64R6-NEXT: and $6, $4, $2
-; MIPS64R6-NEXT: andi $2, $4, 3
+; MIPS64R6-NEXT: and $5, $4, $2
+; MIPS64R6-NEXT: move $2, $4
+; MIPS64R6-NEXT: sll $2, $2, 0
+; MIPS64R6-NEXT: andi $2, $2, 3
; MIPS64R6-NEXT: xori $2, $2, 2
-; MIPS64R6-NEXT: sll $10, $2, 3
-; MIPS64R6-NEXT: ori $2, $zero, 65535
-; MIPS64R6-NEXT: sllv $8, $2, $10
-; MIPS64R6-NEXT: nor $9, $zero, $8
-; MIPS64R6-NEXT: sllv $7, $1, $10
+; MIPS64R6-NEXT: sll $2, $2, 3
+; MIPS64R6-NEXT: ori $3, $zero, 65535
+; MIPS64R6-NEXT: sllv $7, $3, $2
+; MIPS64R6-NEXT: andi $1, $1, 65535
+; MIPS64R6-NEXT: sllv $6, $1, $2
; MIPS64R6-NEXT: .LBB6_1: # %entry
; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R6-NEXT: ll $2, 0($6)
-; MIPS64R6-NEXT: srav $4, $2, $10
-; MIPS64R6-NEXT: andi $4, $4, 65535
-; MIPS64R6-NEXT: or $1, $zero, $4
-; MIPS64R6-NEXT: sllv $4, $4, $10
-; MIPS64R6-NEXT: sltu $5, $4, $7
-; MIPS64R6-NEXT: seleqz $3, $4, $5
-; MIPS64R6-NEXT: selnez $5, $7, $5
-; MIPS64R6-NEXT: or $3, $3, $5
-; MIPS64R6-NEXT: and $3, $3, $8
-; MIPS64R6-NEXT: and $4, $2, $9
-; MIPS64R6-NEXT: or $4, $4, $3
-; MIPS64R6-NEXT: sc $4, 0($6)
-; MIPS64R6-NEXT: beqzc $4, .LBB6_1
-; MIPS64R6-NEXT: nop
+; MIPS64R6-NEXT: ll $1, 0($5)
+; MIPS64R6-NEXT: and $3, $1, $7
+; MIPS64R6-NEXT: sltu $4, $3, $6
+; MIPS64R6-NEXT: seleqz $3, $3, $4
+; MIPS64R6-NEXT: selnez $4, $6, $4
+; MIPS64R6-NEXT: or $3, $3, $4
+; MIPS64R6-NEXT: xor $3, $1, $3
+; MIPS64R6-NEXT: and $3, $3, $7
+; MIPS64R6-NEXT: xor $3, $1, $3
+; MIPS64R6-NEXT: sc $3, 0($5)
+; MIPS64R6-NEXT: beqzc $3, .LBB6_1
; MIPS64R6-NEXT: # %bb.2: # %entry
-; MIPS64R6-NEXT: .insn
-; MIPS64R6-NEXT: # %bb.3: # %entry
-; MIPS64R6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64R6-NEXT: # %bb.4: # %entry
-; MIPS64R6-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64R6-NEXT: srlv $2, $1, $2
; MIPS64R6-NEXT: sync
-; MIPS64R6-NEXT: daddiu $sp, $sp, 16
; MIPS64R6-NEXT: jrc $ra
;
; MIPS64EL-LABEL: test_umax_16:
; MIPS64EL: # %bb.0: # %entry
-; MIPS64EL-NEXT: daddiu $sp, $sp, -16
-; MIPS64EL-NEXT: .cfi_def_cfa_offset 16
; MIPS64EL-NEXT: move $1, $5
; MIPS64EL-NEXT: sync
; MIPS64EL-NEXT: daddiu $2, $zero, -4
-; MIPS64EL-NEXT: and $6, $4, $2
-; MIPS64EL-NEXT: andi $2, $4, 3
-; MIPS64EL-NEXT: sll $10, $2, 3
-; MIPS64EL-NEXT: ori $2, $zero, 65535
-; MIPS64EL-NEXT: sllv $8, $2, $10
-; MIPS64EL-NEXT: nor $9, $zero, $8
-; MIPS64EL-NEXT: sllv $7, $1, $10
+; MIPS64EL-NEXT: and $5, $4, $2
+; MIPS64EL-NEXT: move $2, $4
+; MIPS64EL-NEXT: sll $2, $2, 0
+; MIPS64EL-NEXT: andi $2, $2, 3
+; MIPS64EL-NEXT: sll $2, $2, 3
+; MIPS64EL-NEXT: ori $3, $zero, 65535
+; MIPS64EL-NEXT: sllv $7, $3, $2
+; MIPS64EL-NEXT: andi $1, $1, 65535
+; MIPS64EL-NEXT: sllv $6, $1, $2
; MIPS64EL-NEXT: .LBB6_1: # %entry
; MIPS64EL-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64EL-NEXT: ll $2, 0($6)
-; MIPS64EL-NEXT: srav $4, $2, $10
-; MIPS64EL-NEXT: andi $4, $4, 65535
-; MIPS64EL-NEXT: or $1, $zero, $4
-; MIPS64EL-NEXT: sllv $4, $4, $10
-; MIPS64EL-NEXT: sltu $5, $4, $7
-; MIPS64EL-NEXT: move $3, $4
-; MIPS64EL-NEXT: movn $3, $7, $5
-; MIPS64EL-NEXT: and $3, $3, $8
-; MIPS64EL-NEXT: and $4, $2, $9
-; MIPS64EL-NEXT: or $4, $4, $3
-; MIPS64EL-NEXT: sc $4, 0($6)
-; MIPS64EL-NEXT: beqz $4, .LBB6_1
+; MIPS64EL-NEXT: ll $1, 0($5)
+; MIPS64EL-NEXT: and $3, $1, $7
+; MIPS64EL-NEXT: sltu $4, $3, $6
+; MIPS64EL-NEXT: movn $3, $6, $4
+; MIPS64EL-NEXT: xor $3, $1, $3
+; MIPS64EL-NEXT: and $3, $3, $7
+; MIPS64EL-NEXT: xor $3, $1, $3
+; MIPS64EL-NEXT: sc $3, 0($5)
+; MIPS64EL-NEXT: beqz $3, .LBB6_1
; MIPS64EL-NEXT: nop
; MIPS64EL-NEXT: # %bb.2: # %entry
-; MIPS64EL-NEXT: .insn
-; MIPS64EL-NEXT: # %bb.3: # %entry
-; MIPS64EL-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64EL-NEXT: # %bb.4: # %entry
-; MIPS64EL-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64EL-NEXT: srlv $2, $1, $2
; MIPS64EL-NEXT: sync
-; MIPS64EL-NEXT: daddiu $sp, $sp, 16
; MIPS64EL-NEXT: jr $ra
; MIPS64EL-NEXT: nop
;
; MIPS64ELR6-LABEL: test_umax_16:
; MIPS64ELR6: # %bb.0: # %entry
-; MIPS64ELR6-NEXT: daddiu $sp, $sp, -16
-; MIPS64ELR6-NEXT: .cfi_def_cfa_offset 16
; MIPS64ELR6-NEXT: move $1, $5
; MIPS64ELR6-NEXT: sync
; MIPS64ELR6-NEXT: daddiu $2, $zero, -4
-; MIPS64ELR6-NEXT: and $6, $4, $2
-; MIPS64ELR6-NEXT: andi $2, $4, 3
-; MIPS64ELR6-NEXT: sll $10, $2, 3
-; MIPS64ELR6-NEXT: ori $2, $zero, 65535
-; MIPS64ELR6-NEXT: sllv $8, $2, $10
-; MIPS64ELR6-NEXT: nor $9, $zero, $8
-; MIPS64ELR6-NEXT: sllv $7, $1, $10
+; MIPS64ELR6-NEXT: and $5, $4, $2
+; MIPS64ELR6-NEXT: move $2, $4
+; MIPS64ELR6-NEXT: sll $2, $2, 0
+; MIPS64ELR6-NEXT: andi $2, $2, 3
+; MIPS64ELR6-NEXT: sll $2, $2, 3
+; MIPS64ELR6-NEXT: ori $3, $zero, 65535
+; MIPS64ELR6-NEXT: sllv $7, $3, $2
+; MIPS64ELR6-NEXT: andi $1, $1, 65535
+; MIPS64ELR6-NEXT: sllv $6, $1, $2
; MIPS64ELR6-NEXT: .LBB6_1: # %entry
; MIPS64ELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64ELR6-NEXT: ll $2, 0($6)
-; MIPS64ELR6-NEXT: srav $4, $2, $10
-; MIPS64ELR6-NEXT: andi $4, $4, 65535
-; MIPS64ELR6-NEXT: or $1, $zero, $4
-; MIPS64ELR6-NEXT: sllv $4, $4, $10
-; MIPS64ELR6-NEXT: sltu $5, $4, $7
-; MIPS64ELR6-NEXT: seleqz $3, $4, $5
-; MIPS64ELR6-NEXT: selnez $5, $7, $5
-; MIPS64ELR6-NEXT: or $3, $3, $5
-; MIPS64ELR6-NEXT: and $3, $3, $8
-; MIPS64ELR6-NEXT: and $4, $2, $9
-; MIPS64ELR6-NEXT: or $4, $4, $3
-; MIPS64ELR6-NEXT: sc $4, 0($6)
-; MIPS64ELR6-NEXT: beqzc $4, .LBB6_1
-; MIPS64ELR6-NEXT: nop
+; MIPS64ELR6-NEXT: ll $1, 0($5)
+; MIPS64ELR6-NEXT: and $3, $1, $7
+; MIPS64ELR6-NEXT: sltu $4, $3, $6
+; MIPS64ELR6-NEXT: seleqz $3, $3, $4
+; MIPS64ELR6-NEXT: selnez $4, $6, $4
+; MIPS64ELR6-NEXT: or $3, $3, $4
+; MIPS64ELR6-NEXT: xor $3, $1, $3
+; MIPS64ELR6-NEXT: and $3, $3, $7
+; MIPS64ELR6-NEXT: xor $3, $1, $3
+; MIPS64ELR6-NEXT: sc $3, 0($5)
+; MIPS64ELR6-NEXT: beqzc $3, .LBB6_1
; MIPS64ELR6-NEXT: # %bb.2: # %entry
-; MIPS64ELR6-NEXT: .insn
-; MIPS64ELR6-NEXT: # %bb.3: # %entry
-; MIPS64ELR6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64ELR6-NEXT: # %bb.4: # %entry
-; MIPS64ELR6-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64ELR6-NEXT: srlv $2, $1, $2
; MIPS64ELR6-NEXT: sync
-; MIPS64ELR6-NEXT: daddiu $sp, $sp, 16
; MIPS64ELR6-NEXT: jrc $ra
entry:
%0 = atomicrmw umax ptr %ptr, i16 %val seq_cst
@@ -2747,576 +2441,434 @@ entry:
define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) {
; MIPS-LABEL: test_umin_16:
; MIPS: # %bb.0: # %entry
-; MIPS-NEXT: addiu $sp, $sp, -8
-; MIPS-NEXT: .cfi_def_cfa_offset 8
+; MIPS-NEXT: move $1, $5
; MIPS-NEXT: sync
-; MIPS-NEXT: addiu $1, $zero, -4
-; MIPS-NEXT: and $6, $4, $1
-; MIPS-NEXT: andi $1, $4, 3
-; MIPS-NEXT: xori $1, $1, 2
-; MIPS-NEXT: sll $10, $1, 3
-; MIPS-NEXT: ori $1, $zero, 65535
-; MIPS-NEXT: sllv $8, $1, $10
-; MIPS-NEXT: nor $9, $zero, $8
-; MIPS-NEXT: sllv $7, $5, $10
+; MIPS-NEXT: addiu $2, $zero, -4
+; MIPS-NEXT: and $5, $4, $2
+; MIPS-NEXT: andi $2, $4, 3
+; MIPS-NEXT: xori $2, $2, 2
+; MIPS-NEXT: sll $2, $2, 3
+; MIPS-NEXT: ori $3, $zero, 65535
+; MIPS-NEXT: sllv $7, $3, $2
+; MIPS-NEXT: andi $1, $1, 65535
+; MIPS-NEXT: sllv $6, $1, $2
; MIPS-NEXT: $BB7_1: # %entry
; MIPS-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS-NEXT: ll $2, 0($6)
-; MIPS-NEXT: srav $4, $2, $10
-; MIPS-NEXT: andi $4, $4, 65535
-; MIPS-NEXT: or $1, $zero, $4
-; MIPS-NEXT: sllv $4, $4, $10
-; MIPS-NEXT: sltu $5, $4, $7
-; MIPS-NEXT: move $3, $4
-; MIPS-NEXT: movz $3, $7, $5
-; MIPS-NEXT: and $3, $3, $8
-; MIPS-NEXT: and $4, $2, $9
-; MIPS-NEXT: or $4, $4, $3
-; MIPS-NEXT: sc $4, 0($6)
-; MIPS-NEXT: beqz $4, $BB7_1
+; MIPS-NEXT: ll $1, 0($5)
+; MIPS-NEXT: and $3, $1, $7
+; MIPS-NEXT: sltu $4, $6, $3
+; MIPS-NEXT: movn $3, $6, $4
+; MIPS-NEXT: xor $3, $1, $3
+; MIPS-NEXT: and $3, $3, $7
+; MIPS-NEXT: xor $3, $1, $3
+; MIPS-NEXT: sc $3, 0($5)
+; MIPS-NEXT: beqz $3, $BB7_1
; MIPS-NEXT: nop
; MIPS-NEXT: # %bb.2: # %entry
-; MIPS-NEXT: .insn
-; MIPS-NEXT: # %bb.3: # %entry
-; MIPS-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS-NEXT: # %bb.4: # %entry
-; MIPS-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPS-NEXT: srlv $2, $1, $2
; MIPS-NEXT: sync
-; MIPS-NEXT: addiu $sp, $sp, 8
; MIPS-NEXT: jr $ra
; MIPS-NEXT: nop
;
-; MIPS2-LABEL: test_umin_16:
-; MIPS2: # %bb.0: # %entry
-; MIPS2-NEXT: addiu $sp, $sp, -8
-; MIPS2-NEXT: .cfi_def_cfa_offset 8
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: addiu $1, $zero, -4
-; MIPS2-NEXT: and $6, $4, $1
-; MIPS2-NEXT: andi $1, $4, 3
-; MIPS2-NEXT: sll $10, $1, 3
-; MIPS2-NEXT: ori $1, $zero, 65535
-; MIPS2-NEXT: sllv $8, $1, $10
-; MIPS2-NEXT: nor $9, $zero, $8
-; MIPS2-NEXT: sllv $7, $5, $10
-; MIPS2-NEXT: $BB7_1: # %entry
-; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS2-NEXT: ll $2, 0($6)
-; MIPS2-NEXT: srav $4, $2, $10
-; MIPS2-NEXT: andi $4, $4, 65535
-; MIPS2-NEXT: or $1, $zero, $4
-; MIPS2-NEXT: sllv $4, $4, $10
-; MIPS2-NEXT: sltu $5, $4, $7
-; MIPS2-NEXT: move $3, $4
-; MIPS2-NEXT: beqz $5, $BB7_3
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.2: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB7_1 Depth=1
-; MIPS2-NEXT: j $BB7_4
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: $BB7_3: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB7_1 Depth=1
-; MIPS2-NEXT: move $3, $7
-; MIPS2-NEXT: $BB7_4: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB7_1 Depth=1
-; MIPS2-NEXT: and $3, $3, $8
-; MIPS2-NEXT: and $4, $2, $9
-; MIPS2-NEXT: or $4, $4, $3
-; MIPS2-NEXT: sc $4, 0($6)
-; MIPS2-NEXT: beqz $4, $BB7_1
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.5: # %entry
-; MIPS2-NEXT: .insn
-; MIPS2-NEXT: # %bb.6: # %entry
-; MIPS2-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS2-NEXT: # %bb.7: # %entry
-; MIPS2-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: addiu $sp, $sp, 8
-; MIPS2-NEXT: jr $ra
-; MIPS2-NEXT: nop
-;
; MIPSR6-LABEL: test_umin_16:
; MIPSR6: # %bb.0: # %entry
-; MIPSR6-NEXT: addiu $sp, $sp, -8
-; MIPSR6-NEXT: .cfi_def_cfa_offset 8
+; MIPSR6-NEXT: move $1, $5
; MIPSR6-NEXT: sync
-; MIPSR6-NEXT: addiu $1, $zero, -4
-; MIPSR6-NEXT: and $6, $4, $1
-; MIPSR6-NEXT: andi $1, $4, 3
-; MIPSR6-NEXT: xori $1, $1, 2
-; MIPSR6-NEXT: sll $10, $1, 3
-; MIPSR6-NEXT: ori $1, $zero, 65535
-; MIPSR6-NEXT: sllv $8, $1, $10
-; MIPSR6-NEXT: nor $9, $zero, $8
-; MIPSR6-NEXT: sllv $7, $5, $10
+; MIPSR6-NEXT: addiu $2, $zero, -4
+; MIPSR6-NEXT: and $5, $4, $2
+; MIPSR6-NEXT: andi $2, $4, 3
+; MIPSR6-NEXT: xori $2, $2, 2
+; MIPSR6-NEXT: sll $2, $2, 3
+; MIPSR6-NEXT: ori $3, $zero, 65535
+; MIPSR6-NEXT: sllv $7, $3, $2
+; MIPSR6-NEXT: andi $1, $1, 65535
+; MIPSR6-NEXT: sllv $6, $1, $2
; MIPSR6-NEXT: $BB7_1: # %entry
; MIPSR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSR6-NEXT: ll $2, 0($6)
-; MIPSR6-NEXT: srav $4, $2, $10
-; MIPSR6-NEXT: andi $4, $4, 65535
-; MIPSR6-NEXT: or $1, $zero, $4
-; MIPSR6-NEXT: sllv $4, $4, $10
-; MIPSR6-NEXT: sltu $5, $4, $7
-; MIPSR6-NEXT: selnez $3, $4, $5
-; MIPSR6-NEXT: seleqz $5, $7, $5
-; MIPSR6-NEXT: or $3, $3, $5
-; MIPSR6-NEXT: and $3, $3, $8
-; MIPSR6-NEXT: and $4, $2, $9
-; MIPSR6-NEXT: or $4, $4, $3
-; MIPSR6-NEXT: sc $4, 0($6)
-; MIPSR6-NEXT: beqzc $4, $BB7_1
-; MIPSR6-NEXT: nop
+; MIPSR6-NEXT: ll $1, 0($5)
+; MIPSR6-NEXT: and $3, $1, $7
+; MIPSR6-NEXT: sltu $4, $6, $3
+; MIPSR6-NEXT: seleqz $3, $3, $4
+; MIPSR6-NEXT: selnez $4, $6, $4
+; MIPSR6-NEXT: or $3, $3, $4
+; MIPSR6-NEXT: xor $3, $1, $3
+; MIPSR6-NEXT: and $3, $3, $7
+; MIPSR6-NEXT: xor $3, $1, $3
+; MIPSR6-NEXT: sc $3, 0($5)
+; MIPSR6-NEXT: beqzc $3, $BB7_1
; MIPSR6-NEXT: # %bb.2: # %entry
-; MIPSR6-NEXT: .insn
-; MIPSR6-NEXT: # %bb.3: # %entry
-; MIPSR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSR6-NEXT: # %bb.4: # %entry
-; MIPSR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSR6-NEXT: srlv $2, $1, $2
; MIPSR6-NEXT: sync
-; MIPSR6-NEXT: addiu $sp, $sp, 8
; MIPSR6-NEXT: jrc $ra
;
; MM-LABEL: test_umin_16:
; MM: # %bb.0: # %entry
-; MM-NEXT: addiu $sp, $sp, -8
-; MM-NEXT: .cfi_def_cfa_offset 8
+; MM-NEXT: move $3, $5
; MM-NEXT: sync
-; MM-NEXT: addiu $1, $zero, -4
-; MM-NEXT: and $6, $4, $1
-; MM-NEXT: andi $1, $4, 3
-; MM-NEXT: xori $1, $1, 2
-; MM-NEXT: sll $10, $1, 3
+; MM-NEXT: addiu $5, $zero, -4
+; MM-NEXT: and16 $5, $4
+; MM-NEXT: andi16 $2, $4, 3
+; MM-NEXT: xori $2, $2, 2
+; MM-NEXT: sll16 $2, $2, 3
; MM-NEXT: ori $1, $zero, 65535
-; MM-NEXT: sllv $8, $1, $10
-; MM-NEXT: nor $9, $zero, $8
-; MM-NEXT: sllv $7, $5, $10
+; MM-NEXT: sllv $7, $1, $2
+; MM-NEXT: andi16 $3, $3, 65535
+; MM-NEXT: sllv $6, $3, $2
; MM-NEXT: $BB7_1: # %entry
; MM-NEXT: # =>This Inner Loop Header: Depth=1
-; MM-NEXT: ll $2, 0($6)
-; MM-NEXT: srav $4, $2, $10
-; MM-NEXT: andi $4, $4, 65535
-; MM-NEXT: or $1, $zero, $4
-; MM-NEXT: sllv $4, $4, $10
-; MM-NEXT: sltu $5, $4, $7
-; MM-NEXT: or $3, $4, $zero
-; MM-NEXT: movz $3, $7, $5
-; MM-NEXT: and $3, $3, $8
-; MM-NEXT: and $4, $2, $9
-; MM-NEXT: or $4, $4, $3
-; MM-NEXT: sc $4, 0($6)
-; MM-NEXT: beqzc $4, $BB7_1
+; MM-NEXT: ll $1, 0($5)
+; MM-NEXT: and $3, $1, $7
+; MM-NEXT: sltu $4, $6, $3
+; MM-NEXT: movn $3, $6, $4
+; MM-NEXT: xor $3, $1, $3
+; MM-NEXT: and $3, $3, $7
+; MM-NEXT: xor $3, $1, $3
+; MM-NEXT: sc $3, 0($5)
+; MM-NEXT: beqzc $3, $BB7_1
; MM-NEXT: # %bb.2: # %entry
-; MM-NEXT: .insn
-; MM-NEXT: # %bb.3: # %entry
-; MM-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MM-NEXT: # %bb.4: # %entry
-; MM-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MM-NEXT: srlv $2, $1, $2
; MM-NEXT: sync
-; MM-NEXT: addiusp 8
; MM-NEXT: jrc $ra
;
; MMR6-LABEL: test_umin_16:
; MMR6: # %bb.0: # %entry
-; MMR6-NEXT: addiu $sp, $sp, -8
-; MMR6-NEXT: .cfi_def_cfa_offset 8
+; MMR6-NEXT: move $3, $5
; MMR6-NEXT: sync
; MMR6-NEXT: addiu $1, $zero, -4
-; MMR6-NEXT: and $6, $4, $1
-; MMR6-NEXT: andi $1, $4, 3
-; MMR6-NEXT: xori $1, $1, 2
-; MMR6-NEXT: sll $10, $1, 3
+; MMR6-NEXT: and $5, $4, $1
+; MMR6-NEXT: andi16 $2, $4, 3
+; MMR6-NEXT: xori $2, $2, 2
+; MMR6-NEXT: sll16 $2, $2, 3
; MMR6-NEXT: ori $1, $zero, 65535
-; MMR6-NEXT: sllv $8, $1, $10
-; MMR6-NEXT: nor $9, $zero, $8
-; MMR6-NEXT: sllv $7, $5, $10
+; MMR6-NEXT: sllv $7, $1, $2
+; MMR6-NEXT: andi16 $3, $3, 65535
+; MMR6-NEXT: sllv $6, $3, $2
; MMR6-NEXT: $BB7_1: # %entry
; MMR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MMR6-NEXT: ll $2, 0($6)
-; MMR6-NEXT: srav $4, $2, $10
-; MMR6-NEXT: andi $4, $4, 65535
-; MMR6-NEXT: or $1, $zero, $4
-; MMR6-NEXT: sllv $4, $4, $10
-; MMR6-NEXT: sltu $5, $4, $7
-; MMR6-NEXT: selnez $3, $4, $5
-; MMR6-NEXT: seleqz $5, $7, $5
-; MMR6-NEXT: or $3, $3, $5
-; MMR6-NEXT: and $3, $3, $8
-; MMR6-NEXT: and $4, $2, $9
-; MMR6-NEXT: or $4, $4, $3
-; MMR6-NEXT: sc $4, 0($6)
-; MMR6-NEXT: beqc $4, $zero, $BB7_1
+; MMR6-NEXT: ll $1, 0($5)
+; MMR6-NEXT: and $3, $1, $7
+; MMR6-NEXT: sltu $4, $6, $3
+; MMR6-NEXT: seleqz $3, $3, $4
+; MMR6-NEXT: selnez $4, $6, $4
+; MMR6-NEXT: or $3, $3, $4
+; MMR6-NEXT: xor $3, $1, $3
+; MMR6-NEXT: and $3, $3, $7
+; MMR6-NEXT: xor $3, $1, $3
+; MMR6-NEXT: sc $3, 0($5)
+; MMR6-NEXT: beqc $3, $zero, $BB7_1
; MMR6-NEXT: # %bb.2: # %entry
-; MMR6-NEXT: .insn
-; MMR6-NEXT: # %bb.3: # %entry
-; MMR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMR6-NEXT: # %bb.4: # %entry
-; MMR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMR6-NEXT: srlv $2, $1, $2
; MMR6-NEXT: sync
-; MMR6-NEXT: addiu $sp, $sp, 8
; MMR6-NEXT: jrc $ra
;
+; MIPS2-LABEL: test_umin_16:
+; MIPS2: # %bb.0: # %entry
+; MIPS2-NEXT: move $1, $5
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: addiu $2, $zero, -4
+; MIPS2-NEXT: and $5, $4, $2
+; MIPS2-NEXT: sll $2, $4, 3
+; MIPS2-NEXT: ori $3, $zero, 65535
+; MIPS2-NEXT: sllv $7, $3, $2
+; MIPS2-NEXT: andi $1, $1, 65535
+; MIPS2-NEXT: sllv $6, $1, $2
+; MIPS2-NEXT: $BB7_1: # %entry
+; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
+; MIPS2-NEXT: ll $1, 0($5)
+; MIPS2-NEXT: and $3, $1, $7
+; MIPS2-NEXT: sltu $4, $6, $3
+; MIPS2-NEXT: beqz $4, $BB7_3
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.2: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB7_1 Depth=1
+; MIPS2-NEXT: move $3, $6
+; MIPS2-NEXT: $BB7_3: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB7_1 Depth=1
+; MIPS2-NEXT: xor $3, $1, $3
+; MIPS2-NEXT: and $3, $3, $7
+; MIPS2-NEXT: xor $3, $1, $3
+; MIPS2-NEXT: sc $3, 0($5)
+; MIPS2-NEXT: beqz $3, $BB7_1
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.4: # %entry
+; MIPS2-NEXT: srlv $2, $1, $2
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: jr $ra
+; MIPS2-NEXT: nop
+;
; MIPS32-LABEL: test_umin_16:
; MIPS32: # %bb.0: # %entry
-; MIPS32-NEXT: addiu $sp, $sp, -8
-; MIPS32-NEXT: .cfi_def_cfa_offset 8
+; MIPS32-NEXT: move $1, $5
; MIPS32-NEXT: sync
-; MIPS32-NEXT: addiu $1, $zero, -4
-; MIPS32-NEXT: and $6, $4, $1
-; MIPS32-NEXT: andi $1, $4, 3
-; MIPS32-NEXT: sll $10, $1, 3
-; MIPS32-NEXT: ori $1, $zero, 65535
-; MIPS32-NEXT: sllv $8, $1, $10
-; MIPS32-NEXT: nor $9, $zero, $8
-; MIPS32-NEXT: sllv $7, $5, $10
+; MIPS32-NEXT: addiu $2, $zero, -4
+; MIPS32-NEXT: and $5, $4, $2
+; MIPS32-NEXT: sll $2, $4, 3
+; MIPS32-NEXT: ori $3, $zero, 65535
+; MIPS32-NEXT: sllv $7, $3, $2
+; MIPS32-NEXT: andi $1, $1, 65535
+; MIPS32-NEXT: sllv $6, $1, $2
; MIPS32-NEXT: $BB7_1: # %entry
; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32-NEXT: ll $2, 0($6)
-; MIPS32-NEXT: srav $4, $2, $10
-; MIPS32-NEXT: andi $4, $4, 65535
-; MIPS32-NEXT: or $1, $zero, $4
-; MIPS32-NEXT: sllv $4, $4, $10
-; MIPS32-NEXT: sltu $5, $4, $7
-; MIPS32-NEXT: move $3, $4
-; MIPS32-NEXT: movz $3, $7, $5
-; MIPS32-NEXT: and $3, $3, $8
-; MIPS32-NEXT: and $4, $2, $9
-; MIPS32-NEXT: or $4, $4, $3
-; MIPS32-NEXT: sc $4, 0($6)
-; MIPS32-NEXT: beqz $4, $BB7_1
+; MIPS32-NEXT: ll $1, 0($5)
+; MIPS32-NEXT: and $3, $1, $7
+; MIPS32-NEXT: sltu $4, $6, $3
+; MIPS32-NEXT: movn $3, $6, $4
+; MIPS32-NEXT: xor $3, $1, $3
+; MIPS32-NEXT: and $3, $3, $7
+; MIPS32-NEXT: xor $3, $1, $3
+; MIPS32-NEXT: sc $3, 0($5)
+; MIPS32-NEXT: beqz $3, $BB7_1
; MIPS32-NEXT: nop
; MIPS32-NEXT: # %bb.2: # %entry
-; MIPS32-NEXT: .insn
-; MIPS32-NEXT: # %bb.3: # %entry
-; MIPS32-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32-NEXT: # %bb.4: # %entry
-; MIPS32-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPS32-NEXT: srlv $2, $1, $2
; MIPS32-NEXT: sync
-; MIPS32-NEXT: addiu $sp, $sp, 8
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPSEL-LABEL: test_umin_16:
; MIPSEL: # %bb.0: # %entry
-; MIPSEL-NEXT: addiu $sp, $sp, -8
-; MIPSEL-NEXT: .cfi_def_cfa_offset 8
+; MIPSEL-NEXT: move $1, $5
; MIPSEL-NEXT: sync
-; MIPSEL-NEXT: addiu $1, $zero, -4
-; MIPSEL-NEXT: and $6, $4, $1
-; MIPSEL-NEXT: andi $1, $4, 3
-; MIPSEL-NEXT: sll $10, $1, 3
-; MIPSEL-NEXT: ori $1, $zero, 65535
-; MIPSEL-NEXT: sllv $8, $1, $10
-; MIPSEL-NEXT: nor $9, $zero, $8
-; MIPSEL-NEXT: sllv $7, $5, $10
+; MIPSEL-NEXT: addiu $2, $zero, -4
+; MIPSEL-NEXT: and $5, $4, $2
+; MIPSEL-NEXT: sll $2, $4, 3
+; MIPSEL-NEXT: ori $3, $zero, 65535
+; MIPSEL-NEXT: sllv $7, $3, $2
+; MIPSEL-NEXT: andi $1, $1, 65535
+; MIPSEL-NEXT: sllv $6, $1, $2
; MIPSEL-NEXT: $BB7_1: # %entry
; MIPSEL-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSEL-NEXT: ll $2, 0($6)
-; MIPSEL-NEXT: srav $4, $2, $10
-; MIPSEL-NEXT: andi $4, $4, 65535
-; MIPSEL-NEXT: or $1, $zero, $4
-; MIPSEL-NEXT: sllv $4, $4, $10
-; MIPSEL-NEXT: sltu $5, $4, $7
-; MIPSEL-NEXT: move $3, $4
-; MIPSEL-NEXT: movz $3, $7, $5
-; MIPSEL-NEXT: and $3, $3, $8
-; MIPSEL-NEXT: and $4, $2, $9
-; MIPSEL-NEXT: or $4, $4, $3
-; MIPSEL-NEXT: sc $4, 0($6)
-; MIPSEL-NEXT: beqz $4, $BB7_1
+; MIPSEL-NEXT: ll $1, 0($5)
+; MIPSEL-NEXT: and $3, $1, $7
+; MIPSEL-NEXT: sltu $4, $6, $3
+; MIPSEL-NEXT: movn $3, $6, $4
+; MIPSEL-NEXT: xor $3, $1, $3
+; MIPSEL-NEXT: and $3, $3, $7
+; MIPSEL-NEXT: xor $3, $1, $3
+; MIPSEL-NEXT: sc $3, 0($5)
+; MIPSEL-NEXT: beqz $3, $BB7_1
; MIPSEL-NEXT: nop
; MIPSEL-NEXT: # %bb.2: # %entry
-; MIPSEL-NEXT: .insn
-; MIPSEL-NEXT: # %bb.3: # %entry
-; MIPSEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSEL-NEXT: # %bb.4: # %entry
-; MIPSEL-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSEL-NEXT: srlv $2, $1, $2
; MIPSEL-NEXT: sync
-; MIPSEL-NEXT: addiu $sp, $sp, 8
; MIPSEL-NEXT: jr $ra
; MIPSEL-NEXT: nop
;
; MIPSELR6-LABEL: test_umin_16:
; MIPSELR6: # %bb.0: # %entry
-; MIPSELR6-NEXT: addiu $sp, $sp, -8
-; MIPSELR6-NEXT: .cfi_def_cfa_offset 8
+; MIPSELR6-NEXT: move $1, $5
; MIPSELR6-NEXT: sync
-; MIPSELR6-NEXT: addiu $1, $zero, -4
-; MIPSELR6-NEXT: and $6, $4, $1
-; MIPSELR6-NEXT: andi $1, $4, 3
-; MIPSELR6-NEXT: sll $10, $1, 3
-; MIPSELR6-NEXT: ori $1, $zero, 65535
-; MIPSELR6-NEXT: sllv $8, $1, $10
-; MIPSELR6-NEXT: nor $9, $zero, $8
-; MIPSELR6-NEXT: sllv $7, $5, $10
+; MIPSELR6-NEXT: addiu $2, $zero, -4
+; MIPSELR6-NEXT: and $5, $4, $2
+; MIPSELR6-NEXT: sll $2, $4, 3
+; MIPSELR6-NEXT: ori $3, $zero, 65535
+; MIPSELR6-NEXT: sllv $7, $3, $2
+; MIPSELR6-NEXT: andi $1, $1, 65535
+; MIPSELR6-NEXT: sllv $6, $1, $2
; MIPSELR6-NEXT: $BB7_1: # %entry
; MIPSELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSELR6-NEXT: ll $2, 0($6)
-; MIPSELR6-NEXT: srav $4, $2, $10
-; MIPSELR6-NEXT: andi $4, $4, 65535
-; MIPSELR6-NEXT: or $1, $zero, $4
-; MIPSELR6-NEXT: sllv $4, $4, $10
-; MIPSELR6-NEXT: sltu $5, $4, $7
-; MIPSELR6-NEXT: selnez $3, $4, $5
-; MIPSELR6-NEXT: seleqz $5, $7, $5
-; MIPSELR6-NEXT: or $3, $3, $5
-; MIPSELR6-NEXT: and $3, $3, $8
-; MIPSELR6-NEXT: and $4, $2, $9
-; MIPSELR6-NEXT: or $4, $4, $3
-; MIPSELR6-NEXT: sc $4, 0($6)
-; MIPSELR6-NEXT: beqzc $4, $BB7_1
-; MIPSELR6-NEXT: nop
+; MIPSELR6-NEXT: ll $1, 0($5)
+; MIPSELR6-NEXT: and $3, $1, $7
+; MIPSELR6-NEXT: sltu $4, $6, $3
+; MIPSELR6-NEXT: seleqz $3, $3, $4
+; MIPSELR6-NEXT: selnez $4, $6, $4
+; MIPSELR6-NEXT: or $3, $3, $4
+; MIPSELR6-NEXT: xor $3, $1, $3
+; MIPSELR6-NEXT: and $3, $3, $7
+; MIPSELR6-NEXT: xor $3, $1, $3
+; MIPSELR6-NEXT: sc $3, 0($5)
+; MIPSELR6-NEXT: beqzc $3, $BB7_1
; MIPSELR6-NEXT: # %bb.2: # %entry
-; MIPSELR6-NEXT: .insn
-; MIPSELR6-NEXT: # %bb.3: # %entry
-; MIPSELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSELR6-NEXT: # %bb.4: # %entry
-; MIPSELR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSELR6-NEXT: srlv $2, $1, $2
; MIPSELR6-NEXT: sync
-; MIPSELR6-NEXT: addiu $sp, $sp, 8
; MIPSELR6-NEXT: jrc $ra
;
; MMEL-LABEL: test_umin_16:
; MMEL: # %bb.0: # %entry
-; MMEL-NEXT: addiu $sp, $sp, -8
-; MMEL-NEXT: .cfi_def_cfa_offset 8
+; MMEL-NEXT: move $3, $5
; MMEL-NEXT: sync
-; MMEL-NEXT: addiu $1, $zero, -4
-; MMEL-NEXT: and $6, $4, $1
-; MMEL-NEXT: andi $1, $4, 3
-; MMEL-NEXT: sll $10, $1, 3
+; MMEL-NEXT: addiu $5, $zero, -4
+; MMEL-NEXT: and16 $5, $4
+; MMEL-NEXT: sll16 $2, $4, 3
+; MMEL-NEXT: andi $2, $2, 24
; MMEL-NEXT: ori $1, $zero, 65535
-; MMEL-NEXT: sllv $8, $1, $10
-; MMEL-NEXT: nor $9, $zero, $8
-; MMEL-NEXT: sllv $7, $5, $10
+; MMEL-NEXT: sllv $7, $1, $2
+; MMEL-NEXT: andi16 $3, $3, 65535
+; MMEL-NEXT: sllv $6, $3, $2
; MMEL-NEXT: $BB7_1: # %entry
; MMEL-NEXT: # =>This Inner Loop Header: Depth=1
-; MMEL-NEXT: ll $2, 0($6)
-; MMEL-NEXT: srav $4, $2, $10
-; MMEL-NEXT: andi $4, $4, 65535
-; MMEL-NEXT: or $1, $zero, $4
-; MMEL-NEXT: sllv $4, $4, $10
-; MMEL-NEXT: sltu $5, $4, $7
-; MMEL-NEXT: or $3, $4, $zero
-; MMEL-NEXT: movz $3, $7, $5
-; MMEL-NEXT: and $3, $3, $8
-; MMEL-NEXT: and $4, $2, $9
-; MMEL-NEXT: or $4, $4, $3
-; MMEL-NEXT: sc $4, 0($6)
-; MMEL-NEXT: beqzc $4, $BB7_1
+; MMEL-NEXT: ll $1, 0($5)
+; MMEL-NEXT: and $3, $1, $7
+; MMEL-NEXT: sltu $4, $6, $3
+; MMEL-NEXT: movn $3, $6, $4
+; MMEL-NEXT: xor $3, $1, $3
+; MMEL-NEXT: and $3, $3, $7
+; MMEL-NEXT: xor $3, $1, $3
+; MMEL-NEXT: sc $3, 0($5)
+; MMEL-NEXT: beqzc $3, $BB7_1
; MMEL-NEXT: # %bb.2: # %entry
-; MMEL-NEXT: .insn
-; MMEL-NEXT: # %bb.3: # %entry
-; MMEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMEL-NEXT: # %bb.4: # %entry
-; MMEL-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMEL-NEXT: srlv $2, $1, $2
; MMEL-NEXT: sync
-; MMEL-NEXT: addiusp 8
; MMEL-NEXT: jrc $ra
;
; MMELR6-LABEL: test_umin_16:
; MMELR6: # %bb.0: # %entry
-; MMELR6-NEXT: addiu $sp, $sp, -8
-; MMELR6-NEXT: .cfi_def_cfa_offset 8
+; MMELR6-NEXT: move $3, $5
; MMELR6-NEXT: sync
; MMELR6-NEXT: addiu $1, $zero, -4
-; MMELR6-NEXT: and $6, $4, $1
-; MMELR6-NEXT: andi $1, $4, 3
-; MMELR6-NEXT: sll $10, $1, 3
+; MMELR6-NEXT: and $5, $4, $1
+; MMELR6-NEXT: sll16 $2, $4, 3
+; MMELR6-NEXT: andi $2, $2, 24
; MMELR6-NEXT: ori $1, $zero, 65535
-; MMELR6-NEXT: sllv $8, $1, $10
-; MMELR6-NEXT: nor $9, $zero, $8
-; MMELR6-NEXT: sllv $7, $5, $10
+; MMELR6-NEXT: sllv $7, $1, $2
+; MMELR6-NEXT: andi16 $3, $3, 65535
+; MMELR6-NEXT: sllv $6, $3, $2
; MMELR6-NEXT: $BB7_1: # %entry
; MMELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MMELR6-NEXT: ll $2, 0($6)
-; MMELR6-NEXT: srav $4, $2, $10
-; MMELR6-NEXT: andi $4, $4, 65535
-; MMELR6-NEXT: or $1, $zero, $4
-; MMELR6-NEXT: sllv $4, $4, $10
-; MMELR6-NEXT: sltu $5, $4, $7
-; MMELR6-NEXT: selnez $3, $4, $5
-; MMELR6-NEXT: seleqz $5, $7, $5
-; MMELR6-NEXT: or $3, $3, $5
-; MMELR6-NEXT: and $3, $3, $8
-; MMELR6-NEXT: and $4, $2, $9
-; MMELR6-NEXT: or $4, $4, $3
-; MMELR6-NEXT: sc $4, 0($6)
-; MMELR6-NEXT: beqc $4, $zero, $BB7_1
+; MMELR6-NEXT: ll $1, 0($5)
+; MMELR6-NEXT: and $3, $1, $7
+; MMELR6-NEXT: sltu $4, $6, $3
+; MMELR6-NEXT: seleqz $3, $3, $4
+; MMELR6-NEXT: selnez $4, $6, $4
+; MMELR6-NEXT: or $3, $3, $4
+; MMELR6-NEXT: xor $3, $1, $3
+; MMELR6-NEXT: and $3, $3, $7
+; MMELR6-NEXT: xor $3, $1, $3
+; MMELR6-NEXT: sc $3, 0($5)
+; MMELR6-NEXT: beqc $3, $zero, $BB7_1
; MMELR6-NEXT: # %bb.2: # %entry
-; MMELR6-NEXT: .insn
-; MMELR6-NEXT: # %bb.3: # %entry
-; MMELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMELR6-NEXT: # %bb.4: # %entry
-; MMELR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMELR6-NEXT: srlv $2, $1, $2
; MMELR6-NEXT: sync
-; MMELR6-NEXT: addiu $sp, $sp, 8
; MMELR6-NEXT: jrc $ra
;
; MIPS64-LABEL: test_umin_16:
; MIPS64: # %bb.0: # %entry
-; MIPS64-NEXT: daddiu $sp, $sp, -16
-; MIPS64-NEXT: .cfi_def_cfa_offset 16
; MIPS64-NEXT: move $1, $5
; MIPS64-NEXT: sync
; MIPS64-NEXT: daddiu $2, $zero, -4
-; MIPS64-NEXT: and $6, $4, $2
-; MIPS64-NEXT: andi $2, $4, 3
+; MIPS64-NEXT: and $5, $4, $2
+; MIPS64-NEXT: move $2, $4
+; MIPS64-NEXT: sll $2, $2, 0
+; MIPS64-NEXT: andi $2, $2, 3
; MIPS64-NEXT: xori $2, $2, 2
-; MIPS64-NEXT: sll $10, $2, 3
-; MIPS64-NEXT: ori $2, $zero, 65535
-; MIPS64-NEXT: sllv $8, $2, $10
-; MIPS64-NEXT: nor $9, $zero, $8
-; MIPS64-NEXT: sllv $7, $1, $10
+; MIPS64-NEXT: sll $2, $2, 3
+; MIPS64-NEXT: ori $3, $zero, 65535
+; MIPS64-NEXT: sllv $7, $3, $2
+; MIPS64-NEXT: andi $1, $1, 65535
+; MIPS64-NEXT: sllv $6, $1, $2
; MIPS64-NEXT: .LBB7_1: # %entry
; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64-NEXT: ll $2, 0($6)
-; MIPS64-NEXT: srav $4, $2, $10
-; MIPS64-NEXT: andi $4, $4, 65535
-; MIPS64-NEXT: or $1, $zero, $4
-; MIPS64-NEXT: sllv $4, $4, $10
-; MIPS64-NEXT: sltu $5, $4, $7
-; MIPS64-NEXT: move $3, $4
-; MIPS64-NEXT: movz $3, $7, $5
-; MIPS64-NEXT: and $3, $3, $8
-; MIPS64-NEXT: and $4, $2, $9
-; MIPS64-NEXT: or $4, $4, $3
-; MIPS64-NEXT: sc $4, 0($6)
-; MIPS64-NEXT: beqz $4, .LBB7_1
+; MIPS64-NEXT: ll $1, 0($5)
+; MIPS64-NEXT: and $3, $1, $7
+; MIPS64-NEXT: sltu $4, $6, $3
+; MIPS64-NEXT: movn $3, $6, $4
+; MIPS64-NEXT: xor $3, $1, $3
+; MIPS64-NEXT: and $3, $3, $7
+; MIPS64-NEXT: xor $3, $1, $3
+; MIPS64-NEXT: sc $3, 0($5)
+; MIPS64-NEXT: beqz $3, .LBB7_1
; MIPS64-NEXT: nop
; MIPS64-NEXT: # %bb.2: # %entry
-; MIPS64-NEXT: .insn
-; MIPS64-NEXT: # %bb.3: # %entry
-; MIPS64-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64-NEXT: # %bb.4: # %entry
-; MIPS64-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64-NEXT: srlv $2, $1, $2
; MIPS64-NEXT: sync
-; MIPS64-NEXT: daddiu $sp, $sp, 16
; MIPS64-NEXT: jr $ra
; MIPS64-NEXT: nop
;
; MIPS64R6-LABEL: test_umin_16:
; MIPS64R6: # %bb.0: # %entry
-; MIPS64R6-NEXT: daddiu $sp, $sp, -16
-; MIPS64R6-NEXT: .cfi_def_cfa_offset 16
; MIPS64R6-NEXT: move $1, $5
; MIPS64R6-NEXT: sync
; MIPS64R6-NEXT: daddiu $2, $zero, -4
-; MIPS64R6-NEXT: and $6, $4, $2
-; MIPS64R6-NEXT: andi $2, $4, 3
+; MIPS64R6-NEXT: and $5, $4, $2
+; MIPS64R6-NEXT: move $2, $4
+; MIPS64R6-NEXT: sll $2, $2, 0
+; MIPS64R6-NEXT: andi $2, $2, 3
; MIPS64R6-NEXT: xori $2, $2, 2
-; MIPS64R6-NEXT: sll $10, $2, 3
-; MIPS64R6-NEXT: ori $2, $zero, 65535
-; MIPS64R6-NEXT: sllv $8, $2, $10
-; MIPS64R6-NEXT: nor $9, $zero, $8
-; MIPS64R6-NEXT: sllv $7, $1, $10
+; MIPS64R6-NEXT: sll $2, $2, 3
+; MIPS64R6-NEXT: ori $3, $zero, 65535
+; MIPS64R6-NEXT: sllv $7, $3, $2
+; MIPS64R6-NEXT: andi $1, $1, 65535
+; MIPS64R6-NEXT: sllv $6, $1, $2
; MIPS64R6-NEXT: .LBB7_1: # %entry
; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R6-NEXT: ll $2, 0($6)
-; MIPS64R6-NEXT: srav $4, $2, $10
-; MIPS64R6-NEXT: andi $4, $4, 65535
-; MIPS64R6-NEXT: or $1, $zero, $4
-; MIPS64R6-NEXT: sllv $4, $4, $10
-; MIPS64R6-NEXT: sltu $5, $4, $7
-; MIPS64R6-NEXT: selnez $3, $4, $5
-; MIPS64R6-NEXT: seleqz $5, $7, $5
-; MIPS64R6-NEXT: or $3, $3, $5
-; MIPS64R6-NEXT: and $3, $3, $8
-; MIPS64R6-NEXT: and $4, $2, $9
-; MIPS64R6-NEXT: or $4, $4, $3
-; MIPS64R6-NEXT: sc $4, 0($6)
-; MIPS64R6-NEXT: beqzc $4, .LBB7_1
-; MIPS64R6-NEXT: nop
+; MIPS64R6-NEXT: ll $1, 0($5)
+; MIPS64R6-NEXT: and $3, $1, $7
+; MIPS64R6-NEXT: sltu $4, $6, $3
+; MIPS64R6-NEXT: seleqz $3, $3, $4
+; MIPS64R6-NEXT: selnez $4, $6, $4
+; MIPS64R6-NEXT: or $3, $3, $4
+; MIPS64R6-NEXT: xor $3, $1, $3
+; MIPS64R6-NEXT: and $3, $3, $7
+; MIPS64R6-NEXT: xor $3, $1, $3
+; MIPS64R6-NEXT: sc $3, 0($5)
+; MIPS64R6-NEXT: beqzc $3, .LBB7_1
; MIPS64R6-NEXT: # %bb.2: # %entry
-; MIPS64R6-NEXT: .insn
-; MIPS64R6-NEXT: # %bb.3: # %entry
-; MIPS64R6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64R6-NEXT: # %bb.4: # %entry
-; MIPS64R6-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64R6-NEXT: srlv $2, $1, $2
; MIPS64R6-NEXT: sync
-; MIPS64R6-NEXT: daddiu $sp, $sp, 16
; MIPS64R6-NEXT: jrc $ra
;
; MIPS64EL-LABEL: test_umin_16:
; MIPS64EL: # %bb.0: # %entry
-; MIPS64EL-NEXT: daddiu $sp, $sp, -16
-; MIPS64EL-NEXT: .cfi_def_cfa_offset 16
; MIPS64EL-NEXT: move $1, $5
; MIPS64EL-NEXT: sync
; MIPS64EL-NEXT: daddiu $2, $zero, -4
-; MIPS64EL-NEXT: and $6, $4, $2
-; MIPS64EL-NEXT: andi $2, $4, 3
-; MIPS64EL-NEXT: sll $10, $2, 3
-; MIPS64EL-NEXT: ori $2, $zero, 65535
-; MIPS64EL-NEXT: sllv $8, $2, $10
-; MIPS64EL-NEXT: nor $9, $zero, $8
-; MIPS64EL-NEXT: sllv $7, $1, $10
+; MIPS64EL-NEXT: and $5, $4, $2
+; MIPS64EL-NEXT: move $2, $4
+; MIPS64EL-NEXT: sll $2, $2, 0
+; MIPS64EL-NEXT: andi $2, $2, 3
+; MIPS64EL-NEXT: sll $2, $2, 3
+; MIPS64EL-NEXT: ori $3, $zero, 65535
+; MIPS64EL-NEXT: sllv $7, $3, $2
+; MIPS64EL-NEXT: andi $1, $1, 65535
+; MIPS64EL-NEXT: sllv $6, $1, $2
; MIPS64EL-NEXT: .LBB7_1: # %entry
; MIPS64EL-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64EL-NEXT: ll $2, 0($6)
-; MIPS64EL-NEXT: srav $4, $2, $10
-; MIPS64EL-NEXT: andi $4, $4, 65535
-; MIPS64EL-NEXT: or $1, $zero, $4
-; MIPS64EL-NEXT: sllv $4, $4, $10
-; MIPS64EL-NEXT: sltu $5, $4, $7
-; MIPS64EL-NEXT: move $3, $4
-; MIPS64EL-NEXT: movz $3, $7, $5
-; MIPS64EL-NEXT: and $3, $3, $8
-; MIPS64EL-NEXT: and $4, $2, $9
-; MIPS64EL-NEXT: or $4, $4, $3
-; MIPS64EL-NEXT: sc $4, 0($6)
-; MIPS64EL-NEXT: beqz $4, .LBB7_1
+; MIPS64EL-NEXT: ll $1, 0($5)
+; MIPS64EL-NEXT: and $3, $1, $7
+; MIPS64EL-NEXT: sltu $4, $6, $3
+; MIPS64EL-NEXT: movn $3, $6, $4
+; MIPS64EL-NEXT: xor $3, $1, $3
+; MIPS64EL-NEXT: and $3, $3, $7
+; MIPS64EL-NEXT: xor $3, $1, $3
+; MIPS64EL-NEXT: sc $3, 0($5)
+; MIPS64EL-NEXT: beqz $3, .LBB7_1
; MIPS64EL-NEXT: nop
; MIPS64EL-NEXT: # %bb.2: # %entry
-; MIPS64EL-NEXT: .insn
-; MIPS64EL-NEXT: # %bb.3: # %entry
-; MIPS64EL-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64EL-NEXT: # %bb.4: # %entry
-; MIPS64EL-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64EL-NEXT: srlv $2, $1, $2
; MIPS64EL-NEXT: sync
-; MIPS64EL-NEXT: daddiu $sp, $sp, 16
; MIPS64EL-NEXT: jr $ra
; MIPS64EL-NEXT: nop
;
; MIPS64ELR6-LABEL: test_umin_16:
; MIPS64ELR6: # %bb.0: # %entry
-; MIPS64ELR6-NEXT: daddiu $sp, $sp, -16
-; MIPS64ELR6-NEXT: .cfi_def_cfa_offset 16
; MIPS64ELR6-NEXT: move $1, $5
; MIPS64ELR6-NEXT: sync
; MIPS64ELR6-NEXT: daddiu $2, $zero, -4
-; MIPS64ELR6-NEXT: and $6, $4, $2
-; MIPS64ELR6-NEXT: andi $2, $4, 3
-; MIPS64ELR6-NEXT: sll $10, $2, 3
-; MIPS64ELR6-NEXT: ori $2, $zero, 65535
-; MIPS64ELR6-NEXT: sllv $8, $2, $10
-; MIPS64ELR6-NEXT: nor $9, $zero, $8
-; MIPS64ELR6-NEXT: sllv $7, $1, $10
+; MIPS64ELR6-NEXT: and $5, $4, $2
+; MIPS64ELR6-NEXT: move $2, $4
+; MIPS64ELR6-NEXT: sll $2, $2, 0
+; MIPS64ELR6-NEXT: andi $2, $2, 3
+; MIPS64ELR6-NEXT: sll $2, $2, 3
+; MIPS64ELR6-NEXT: ori $3, $zero, 65535
+; MIPS64ELR6-NEXT: sllv $7, $3, $2
+; MIPS64ELR6-NEXT: andi $1, $1, 65535
+; MIPS64ELR6-NEXT: sllv $6, $1, $2
; MIPS64ELR6-NEXT: .LBB7_1: # %entry
; MIPS64ELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64ELR6-NEXT: ll $2, 0($6)
-; MIPS64ELR6-NEXT: srav $4, $2, $10
-; MIPS64ELR6-NEXT: andi $4, $4, 65535
-; MIPS64ELR6-NEXT: or $1, $zero, $4
-; MIPS64ELR6-NEXT: sllv $4, $4, $10
-; MIPS64ELR6-NEXT: sltu $5, $4, $7
-; MIPS64ELR6-NEXT: selnez $3, $4, $5
-; MIPS64ELR6-NEXT: seleqz $5, $7, $5
-; MIPS64ELR6-NEXT: or $3, $3, $5
-; MIPS64ELR6-NEXT: and $3, $3, $8
-; MIPS64ELR6-NEXT: and $4, $2, $9
-; MIPS64ELR6-NEXT: or $4, $4, $3
-; MIPS64ELR6-NEXT: sc $4, 0($6)
-; MIPS64ELR6-NEXT: beqzc $4, .LBB7_1
-; MIPS64ELR6-NEXT: nop
+; MIPS64ELR6-NEXT: ll $1, 0($5)
+; MIPS64ELR6-NEXT: and $3, $1, $7
+; MIPS64ELR6-NEXT: sltu $4, $6, $3
+; MIPS64ELR6-NEXT: seleqz $3, $3, $4
+; MIPS64ELR6-NEXT: selnez $4, $6, $4
+; MIPS64ELR6-NEXT: or $3, $3, $4
+; MIPS64ELR6-NEXT: xor $3, $1, $3
+; MIPS64ELR6-NEXT: and $3, $3, $7
+; MIPS64ELR6-NEXT: xor $3, $1, $3
+; MIPS64ELR6-NEXT: sc $3, 0($5)
+; MIPS64ELR6-NEXT: beqzc $3, .LBB7_1
; MIPS64ELR6-NEXT: # %bb.2: # %entry
-; MIPS64ELR6-NEXT: .insn
-; MIPS64ELR6-NEXT: # %bb.3: # %entry
-; MIPS64ELR6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64ELR6-NEXT: # %bb.4: # %entry
-; MIPS64ELR6-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64ELR6-NEXT: srlv $2, $1, $2
; MIPS64ELR6-NEXT: sync
-; MIPS64ELR6-NEXT: daddiu $sp, $sp, 16
; MIPS64ELR6-NEXT: jrc $ra
entry:
%0 = atomicrmw umin ptr %ptr, i16 %val seq_cst
@@ -3327,578 +2879,466 @@ entry:
define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) {
; MIPS-LABEL: test_max_8:
; MIPS: # %bb.0: # %entry
-; MIPS-NEXT: addiu $sp, $sp, -8
-; MIPS-NEXT: .cfi_def_cfa_offset 8
+; MIPS-NEXT: move $1, $5
+; MIPS-NEXT: not $2, $4
; MIPS-NEXT: sync
-; MIPS-NEXT: addiu $1, $zero, -4
-; MIPS-NEXT: and $6, $4, $1
-; MIPS-NEXT: andi $1, $4, 3
-; MIPS-NEXT: xori $1, $1, 3
-; MIPS-NEXT: sll $10, $1, 3
-; MIPS-NEXT: ori $1, $zero, 255
-; MIPS-NEXT: sllv $8, $1, $10
-; MIPS-NEXT: nor $9, $zero, $8
-; MIPS-NEXT: sllv $7, $5, $10
+; MIPS-NEXT: addiu $3, $zero, -4
+; MIPS-NEXT: and $5, $4, $3
+; MIPS-NEXT: andi $2, $2, 3
+; MIPS-NEXT: sll $2, $2, 3
+; MIPS-NEXT: addiu $3, $zero, 255
+; MIPS-NEXT: sllv $7, $3, $2
+; MIPS-NEXT: sllv $6, $1, $2
+; MIPS-NEXT: xori $8, $2, 24
; MIPS-NEXT: $BB8_1: # %entry
; MIPS-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS-NEXT: ll $2, 0($6)
-; MIPS-NEXT: srav $4, $2, $10
-; MIPS-NEXT: seb $4, $4
-; MIPS-NEXT: or $1, $zero, $4
-; MIPS-NEXT: sllv $4, $4, $10
-; MIPS-NEXT: slt $5, $4, $7
-; MIPS-NEXT: move $3, $4
-; MIPS-NEXT: movn $3, $7, $5
-; MIPS-NEXT: and $3, $3, $8
-; MIPS-NEXT: and $4, $2, $9
-; MIPS-NEXT: or $4, $4, $3
-; MIPS-NEXT: sc $4, 0($6)
-; MIPS-NEXT: beqz $4, $BB8_1
+; MIPS-NEXT: ll $1, 0($5)
+; MIPS-NEXT: and $3, $1, $7
+; MIPS-NEXT: sllv $3, $3, $8
+; MIPS-NEXT: srav $3, $3, $8
+; MIPS-NEXT: slt $4, $3, $6
+; MIPS-NEXT: movn $3, $6, $4
+; MIPS-NEXT: xor $3, $1, $3
+; MIPS-NEXT: and $3, $3, $7
+; MIPS-NEXT: xor $3, $1, $3
+; MIPS-NEXT: sc $3, 0($5)
+; MIPS-NEXT: beqz $3, $BB8_1
; MIPS-NEXT: nop
; MIPS-NEXT: # %bb.2: # %entry
-; MIPS-NEXT: .insn
-; MIPS-NEXT: # %bb.3: # %entry
-; MIPS-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS-NEXT: # %bb.4: # %entry
-; MIPS-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPS-NEXT: srlv $2, $1, $2
; MIPS-NEXT: sync
-; MIPS-NEXT: addiu $sp, $sp, 8
; MIPS-NEXT: jr $ra
; MIPS-NEXT: nop
;
-; MIPS2-LABEL: test_max_8:
-; MIPS2: # %bb.0: # %entry
-; MIPS2-NEXT: addiu $sp, $sp, -8
-; MIPS2-NEXT: .cfi_def_cfa_offset 8
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: addiu $1, $zero, -4
-; MIPS2-NEXT: and $6, $4, $1
-; MIPS2-NEXT: andi $1, $4, 3
-; MIPS2-NEXT: sll $10, $1, 3
-; MIPS2-NEXT: ori $1, $zero, 255
-; MIPS2-NEXT: sllv $8, $1, $10
-; MIPS2-NEXT: nor $9, $zero, $8
-; MIPS2-NEXT: sllv $7, $5, $10
-; MIPS2-NEXT: $BB8_1: # %entry
-; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS2-NEXT: ll $2, 0($6)
-; MIPS2-NEXT: srav $4, $2, $10
-; MIPS2-NEXT: sll $4, $4, 24
-; MIPS2-NEXT: sra $4, $4, 24
-; MIPS2-NEXT: or $1, $zero, $4
-; MIPS2-NEXT: sllv $4, $4, $10
-; MIPS2-NEXT: slt $5, $4, $7
-; MIPS2-NEXT: move $3, $7
-; MIPS2-NEXT: beqz $5, $BB8_3
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.2: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB8_1 Depth=1
-; MIPS2-NEXT: j $BB8_4
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: $BB8_3: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB8_1 Depth=1
-; MIPS2-NEXT: move $3, $4
-; MIPS2-NEXT: $BB8_4: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB8_1 Depth=1
-; MIPS2-NEXT: and $3, $3, $8
-; MIPS2-NEXT: and $4, $2, $9
-; MIPS2-NEXT: or $4, $4, $3
-; MIPS2-NEXT: sc $4, 0($6)
-; MIPS2-NEXT: beqz $4, $BB8_1
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.5: # %entry
-; MIPS2-NEXT: .insn
-; MIPS2-NEXT: # %bb.6: # %entry
-; MIPS2-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS2-NEXT: # %bb.7: # %entry
-; MIPS2-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: addiu $sp, $sp, 8
-; MIPS2-NEXT: jr $ra
-; MIPS2-NEXT: nop
-;
; MIPSR6-LABEL: test_max_8:
; MIPSR6: # %bb.0: # %entry
-; MIPSR6-NEXT: addiu $sp, $sp, -8
-; MIPSR6-NEXT: .cfi_def_cfa_offset 8
+; MIPSR6-NEXT: move $1, $5
+; MIPSR6-NEXT: not $2, $4
; MIPSR6-NEXT: sync
-; MIPSR6-NEXT: addiu $1, $zero, -4
-; MIPSR6-NEXT: and $6, $4, $1
-; MIPSR6-NEXT: andi $1, $4, 3
-; MIPSR6-NEXT: xori $1, $1, 3
-; MIPSR6-NEXT: sll $10, $1, 3
-; MIPSR6-NEXT: ori $1, $zero, 255
-; MIPSR6-NEXT: sllv $8, $1, $10
-; MIPSR6-NEXT: nor $9, $zero, $8
-; MIPSR6-NEXT: sllv $7, $5, $10
+; MIPSR6-NEXT: addiu $3, $zero, -4
+; MIPSR6-NEXT: and $5, $4, $3
+; MIPSR6-NEXT: andi $2, $2, 3
+; MIPSR6-NEXT: sll $2, $2, 3
+; MIPSR6-NEXT: addiu $3, $zero, 255
+; MIPSR6-NEXT: sllv $7, $3, $2
+; MIPSR6-NEXT: sllv $6, $1, $2
+; MIPSR6-NEXT: xori $8, $2, 24
; MIPSR6-NEXT: $BB8_1: # %entry
; MIPSR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSR6-NEXT: ll $2, 0($6)
-; MIPSR6-NEXT: srav $4, $2, $10
-; MIPSR6-NEXT: seb $4, $4
-; MIPSR6-NEXT: or $1, $zero, $4
-; MIPSR6-NEXT: sllv $4, $4, $10
-; MIPSR6-NEXT: slt $5, $4, $7
-; MIPSR6-NEXT: seleqz $3, $4, $5
-; MIPSR6-NEXT: selnez $5, $7, $5
-; MIPSR6-NEXT: or $3, $3, $5
-; MIPSR6-NEXT: and $3, $3, $8
-; MIPSR6-NEXT: and $4, $2, $9
-; MIPSR6-NEXT: or $4, $4, $3
-; MIPSR6-NEXT: sc $4, 0($6)
-; MIPSR6-NEXT: beqzc $4, $BB8_1
-; MIPSR6-NEXT: nop
+; MIPSR6-NEXT: ll $1, 0($5)
+; MIPSR6-NEXT: and $3, $1, $7
+; MIPSR6-NEXT: sllv $3, $3, $8
+; MIPSR6-NEXT: srav $3, $3, $8
+; MIPSR6-NEXT: slt $4, $3, $6
+; MIPSR6-NEXT: seleqz $3, $3, $4
+; MIPSR6-NEXT: selnez $4, $6, $4
+; MIPSR6-NEXT: or $3, $3, $4
+; MIPSR6-NEXT: xor $3, $1, $3
+; MIPSR6-NEXT: and $3, $3, $7
+; MIPSR6-NEXT: xor $3, $1, $3
+; MIPSR6-NEXT: sc $3, 0($5)
+; MIPSR6-NEXT: beqzc $3, $BB8_1
; MIPSR6-NEXT: # %bb.2: # %entry
-; MIPSR6-NEXT: .insn
-; MIPSR6-NEXT: # %bb.3: # %entry
-; MIPSR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSR6-NEXT: # %bb.4: # %entry
-; MIPSR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSR6-NEXT: srlv $2, $1, $2
; MIPSR6-NEXT: sync
-; MIPSR6-NEXT: addiu $sp, $sp, 8
; MIPSR6-NEXT: jrc $ra
;
; MM-LABEL: test_max_8:
; MM: # %bb.0: # %entry
-; MM-NEXT: addiu $sp, $sp, -8
-; MM-NEXT: .cfi_def_cfa_offset 8
+; MM-NEXT: move $1, $5
+; MM-NEXT: not16 $2, $4
; MM-NEXT: sync
-; MM-NEXT: addiu $1, $zero, -4
-; MM-NEXT: and $6, $4, $1
-; MM-NEXT: andi $1, $4, 3
-; MM-NEXT: xori $1, $1, 3
-; MM-NEXT: sll $10, $1, 3
-; MM-NEXT: ori $1, $zero, 255
-; MM-NEXT: sllv $8, $1, $10
-; MM-NEXT: nor $9, $zero, $8
-; MM-NEXT: sllv $7, $5, $10
+; MM-NEXT: addiu $5, $zero, -4
+; MM-NEXT: and16 $5, $4
+; MM-NEXT: andi16 $2, $2, 3
+; MM-NEXT: sll16 $2, $2, 3
+; MM-NEXT: addiu $3, $zero, 255
+; MM-NEXT: sllv $7, $3, $2
+; MM-NEXT: sllv $6, $1, $2
+; MM-NEXT: xori $8, $2, 24
; MM-NEXT: $BB8_1: # %entry
; MM-NEXT: # =>This Inner Loop Header: Depth=1
-; MM-NEXT: ll $2, 0($6)
-; MM-NEXT: srav $4, $2, $10
-; MM-NEXT: seb $4, $4
-; MM-NEXT: or $1, $zero, $4
-; MM-NEXT: sllv $4, $4, $10
-; MM-NEXT: slt $5, $4, $7
-; MM-NEXT: or $3, $4, $zero
-; MM-NEXT: movn $3, $7, $5
-; MM-NEXT: and $3, $3, $8
-; MM-NEXT: and $4, $2, $9
-; MM-NEXT: or $4, $4, $3
-; MM-NEXT: sc $4, 0($6)
-; MM-NEXT: beqzc $4, $BB8_1
+; MM-NEXT: ll $1, 0($5)
+; MM-NEXT: and $3, $1, $7
+; MM-NEXT: sllv $3, $3, $8
+; MM-NEXT: srav $3, $3, $8
+; MM-NEXT: slt $4, $3, $6
+; MM-NEXT: movn $3, $6, $4
+; MM-NEXT: xor $3, $1, $3
+; MM-NEXT: and $3, $3, $7
+; MM-NEXT: xor $3, $1, $3
+; MM-NEXT: sc $3, 0($5)
+; MM-NEXT: beqzc $3, $BB8_1
; MM-NEXT: # %bb.2: # %entry
-; MM-NEXT: .insn
-; MM-NEXT: # %bb.3: # %entry
-; MM-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MM-NEXT: # %bb.4: # %entry
-; MM-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MM-NEXT: srlv $2, $1, $2
; MM-NEXT: sync
-; MM-NEXT: addiusp 8
; MM-NEXT: jrc $ra
;
; MMR6-LABEL: test_max_8:
; MMR6: # %bb.0: # %entry
-; MMR6-NEXT: addiu $sp, $sp, -8
-; MMR6-NEXT: .cfi_def_cfa_offset 8
+; MMR6-NEXT: move $1, $5
+; MMR6-NEXT: not16 $2, $4
; MMR6-NEXT: sync
-; MMR6-NEXT: addiu $1, $zero, -4
-; MMR6-NEXT: and $6, $4, $1
-; MMR6-NEXT: andi $1, $4, 3
-; MMR6-NEXT: xori $1, $1, 3
-; MMR6-NEXT: sll $10, $1, 3
-; MMR6-NEXT: ori $1, $zero, 255
-; MMR6-NEXT: sllv $8, $1, $10
-; MMR6-NEXT: nor $9, $zero, $8
-; MMR6-NEXT: sllv $7, $5, $10
+; MMR6-NEXT: addiu $3, $zero, -4
+; MMR6-NEXT: and $5, $4, $3
+; MMR6-NEXT: andi16 $2, $2, 3
+; MMR6-NEXT: sll16 $2, $2, 3
+; MMR6-NEXT: addiu $3, $zero, 255
+; MMR6-NEXT: sllv $7, $3, $2
+; MMR6-NEXT: sllv $6, $1, $2
+; MMR6-NEXT: xori $8, $2, 24
; MMR6-NEXT: $BB8_1: # %entry
; MMR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MMR6-NEXT: ll $2, 0($6)
-; MMR6-NEXT: srav $4, $2, $10
-; MMR6-NEXT: seb $4, $4
-; MMR6-NEXT: or $1, $zero, $4
-; MMR6-NEXT: sllv $4, $4, $10
-; MMR6-NEXT: slt $5, $4, $7
-; MMR6-NEXT: seleqz $3, $4, $5
-; MMR6-NEXT: selnez $5, $7, $5
-; MMR6-NEXT: or $3, $3, $5
-; MMR6-NEXT: and $3, $3, $8
-; MMR6-NEXT: and $4, $2, $9
-; MMR6-NEXT: or $4, $4, $3
-; MMR6-NEXT: sc $4, 0($6)
-; MMR6-NEXT: beqc $4, $zero, $BB8_1
+; MMR6-NEXT: ll $1, 0($5)
+; MMR6-NEXT: and $3, $1, $7
+; MMR6-NEXT: sllv $3, $3, $8
+; MMR6-NEXT: srav $3, $3, $8
+; MMR6-NEXT: slt $4, $3, $6
+; MMR6-NEXT: seleqz $3, $3, $4
+; MMR6-NEXT: selnez $4, $6, $4
+; MMR6-NEXT: or $3, $3, $4
+; MMR6-NEXT: xor $3, $1, $3
+; MMR6-NEXT: and $3, $3, $7
+; MMR6-NEXT: xor $3, $1, $3
+; MMR6-NEXT: sc $3, 0($5)
+; MMR6-NEXT: beqc $3, $zero, $BB8_1
; MMR6-NEXT: # %bb.2: # %entry
-; MMR6-NEXT: .insn
-; MMR6-NEXT: # %bb.3: # %entry
-; MMR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMR6-NEXT: # %bb.4: # %entry
-; MMR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMR6-NEXT: srlv $2, $1, $2
; MMR6-NEXT: sync
-; MMR6-NEXT: addiu $sp, $sp, 8
; MMR6-NEXT: jrc $ra
;
+; MIPS2-LABEL: test_max_8:
+; MIPS2: # %bb.0: # %entry
+; MIPS2-NEXT: move $3, $5
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: addiu $1, $zero, -4
+; MIPS2-NEXT: and $5, $4, $1
+; MIPS2-NEXT: sll $2, $4, 3
+; MIPS2-NEXT: andi $1, $2, 24
+; MIPS2-NEXT: addiu $4, $zero, 255
+; MIPS2-NEXT: sllv $7, $4, $2
+; MIPS2-NEXT: sllv $6, $3, $2
+; MIPS2-NEXT: xori $8, $1, 24
+; MIPS2-NEXT: $BB8_1: # %entry
+; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
+; MIPS2-NEXT: ll $1, 0($5)
+; MIPS2-NEXT: and $3, $1, $7
+; MIPS2-NEXT: sllv $3, $3, $8
+; MIPS2-NEXT: srav $3, $3, $8
+; MIPS2-NEXT: slt $4, $3, $6
+; MIPS2-NEXT: beqz $4, $BB8_3
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.2: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB8_1 Depth=1
+; MIPS2-NEXT: move $3, $6
+; MIPS2-NEXT: $BB8_3: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB8_1 Depth=1
+; MIPS2-NEXT: xor $3, $1, $3
+; MIPS2-NEXT: and $3, $3, $7
+; MIPS2-NEXT: xor $3, $1, $3
+; MIPS2-NEXT: sc $3, 0($5)
+; MIPS2-NEXT: beqz $3, $BB8_1
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.4: # %entry
+; MIPS2-NEXT: srlv $2, $1, $2
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: jr $ra
+; MIPS2-NEXT: nop
+;
; MIPS32-LABEL: test_max_8:
; MIPS32: # %bb.0: # %entry
-; MIPS32-NEXT: addiu $sp, $sp, -8
-; MIPS32-NEXT: .cfi_def_cfa_offset 8
+; MIPS32-NEXT: move $3, $5
; MIPS32-NEXT: sync
; MIPS32-NEXT: addiu $1, $zero, -4
-; MIPS32-NEXT: and $6, $4, $1
-; MIPS32-NEXT: andi $1, $4, 3
-; MIPS32-NEXT: sll $10, $1, 3
-; MIPS32-NEXT: ori $1, $zero, 255
-; MIPS32-NEXT: sllv $8, $1, $10
-; MIPS32-NEXT: nor $9, $zero, $8
-; MIPS32-NEXT: sllv $7, $5, $10
+; MIPS32-NEXT: and $5, $4, $1
+; MIPS32-NEXT: sll $2, $4, 3
+; MIPS32-NEXT: andi $1, $2, 24
+; MIPS32-NEXT: addiu $4, $zero, 255
+; MIPS32-NEXT: sllv $7, $4, $2
+; MIPS32-NEXT: sllv $6, $3, $2
+; MIPS32-NEXT: xori $8, $1, 24
; MIPS32-NEXT: $BB8_1: # %entry
; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32-NEXT: ll $2, 0($6)
-; MIPS32-NEXT: srav $4, $2, $10
-; MIPS32-NEXT: sll $4, $4, 24
-; MIPS32-NEXT: sra $4, $4, 24
-; MIPS32-NEXT: or $1, $zero, $4
-; MIPS32-NEXT: sllv $4, $4, $10
-; MIPS32-NEXT: slt $5, $4, $7
-; MIPS32-NEXT: move $3, $4
-; MIPS32-NEXT: movn $3, $7, $5
-; MIPS32-NEXT: and $3, $3, $8
-; MIPS32-NEXT: and $4, $2, $9
-; MIPS32-NEXT: or $4, $4, $3
-; MIPS32-NEXT: sc $4, 0($6)
-; MIPS32-NEXT: beqz $4, $BB8_1
+; MIPS32-NEXT: ll $1, 0($5)
+; MIPS32-NEXT: and $3, $1, $7
+; MIPS32-NEXT: sllv $3, $3, $8
+; MIPS32-NEXT: srav $3, $3, $8
+; MIPS32-NEXT: slt $4, $3, $6
+; MIPS32-NEXT: movn $3, $6, $4
+; MIPS32-NEXT: xor $3, $1, $3
+; MIPS32-NEXT: and $3, $3, $7
+; MIPS32-NEXT: xor $3, $1, $3
+; MIPS32-NEXT: sc $3, 0($5)
+; MIPS32-NEXT: beqz $3, $BB8_1
; MIPS32-NEXT: nop
; MIPS32-NEXT: # %bb.2: # %entry
-; MIPS32-NEXT: .insn
-; MIPS32-NEXT: # %bb.3: # %entry
-; MIPS32-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32-NEXT: # %bb.4: # %entry
-; MIPS32-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPS32-NEXT: srlv $2, $1, $2
; MIPS32-NEXT: sync
-; MIPS32-NEXT: addiu $sp, $sp, 8
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPSEL-LABEL: test_max_8:
; MIPSEL: # %bb.0: # %entry
-; MIPSEL-NEXT: addiu $sp, $sp, -8
-; MIPSEL-NEXT: .cfi_def_cfa_offset 8
+; MIPSEL-NEXT: move $3, $5
; MIPSEL-NEXT: sync
; MIPSEL-NEXT: addiu $1, $zero, -4
-; MIPSEL-NEXT: and $6, $4, $1
-; MIPSEL-NEXT: andi $1, $4, 3
-; MIPSEL-NEXT: sll $10, $1, 3
-; MIPSEL-NEXT: ori $1, $zero, 255
-; MIPSEL-NEXT: sllv $8, $1, $10
-; MIPSEL-NEXT: nor $9, $zero, $8
-; MIPSEL-NEXT: sllv $7, $5, $10
+; MIPSEL-NEXT: and $5, $4, $1
+; MIPSEL-NEXT: sll $2, $4, 3
+; MIPSEL-NEXT: andi $1, $2, 24
+; MIPSEL-NEXT: addiu $4, $zero, 255
+; MIPSEL-NEXT: sllv $7, $4, $2
+; MIPSEL-NEXT: sllv $6, $3, $2
+; MIPSEL-NEXT: xori $8, $1, 24
; MIPSEL-NEXT: $BB8_1: # %entry
; MIPSEL-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSEL-NEXT: ll $2, 0($6)
-; MIPSEL-NEXT: srav $4, $2, $10
-; MIPSEL-NEXT: seb $4, $4
-; MIPSEL-NEXT: or $1, $zero, $4
-; MIPSEL-NEXT: sllv $4, $4, $10
-; MIPSEL-NEXT: slt $5, $4, $7
-; MIPSEL-NEXT: move $3, $4
-; MIPSEL-NEXT: movn $3, $7, $5
-; MIPSEL-NEXT: and $3, $3, $8
-; MIPSEL-NEXT: and $4, $2, $9
-; MIPSEL-NEXT: or $4, $4, $3
-; MIPSEL-NEXT: sc $4, 0($6)
-; MIPSEL-NEXT: beqz $4, $BB8_1
+; MIPSEL-NEXT: ll $1, 0($5)
+; MIPSEL-NEXT: and $3, $1, $7
+; MIPSEL-NEXT: sllv $3, $3, $8
+; MIPSEL-NEXT: srav $3, $3, $8
+; MIPSEL-NEXT: slt $4, $3, $6
+; MIPSEL-NEXT: movn $3, $6, $4
+; MIPSEL-NEXT: xor $3, $1, $3
+; MIPSEL-NEXT: and $3, $3, $7
+; MIPSEL-NEXT: xor $3, $1, $3
+; MIPSEL-NEXT: sc $3, 0($5)
+; MIPSEL-NEXT: beqz $3, $BB8_1
; MIPSEL-NEXT: nop
; MIPSEL-NEXT: # %bb.2: # %entry
-; MIPSEL-NEXT: .insn
-; MIPSEL-NEXT: # %bb.3: # %entry
-; MIPSEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSEL-NEXT: # %bb.4: # %entry
-; MIPSEL-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSEL-NEXT: srlv $2, $1, $2
; MIPSEL-NEXT: sync
-; MIPSEL-NEXT: addiu $sp, $sp, 8
; MIPSEL-NEXT: jr $ra
; MIPSEL-NEXT: nop
;
; MIPSELR6-LABEL: test_max_8:
; MIPSELR6: # %bb.0: # %entry
-; MIPSELR6-NEXT: addiu $sp, $sp, -8
-; MIPSELR6-NEXT: .cfi_def_cfa_offset 8
+; MIPSELR6-NEXT: move $3, $5
; MIPSELR6-NEXT: sync
; MIPSELR6-NEXT: addiu $1, $zero, -4
-; MIPSELR6-NEXT: and $6, $4, $1
-; MIPSELR6-NEXT: andi $1, $4, 3
-; MIPSELR6-NEXT: sll $10, $1, 3
-; MIPSELR6-NEXT: ori $1, $zero, 255
-; MIPSELR6-NEXT: sllv $8, $1, $10
-; MIPSELR6-NEXT: nor $9, $zero, $8
-; MIPSELR6-NEXT: sllv $7, $5, $10
+; MIPSELR6-NEXT: and $5, $4, $1
+; MIPSELR6-NEXT: sll $2, $4, 3
+; MIPSELR6-NEXT: andi $1, $2, 24
+; MIPSELR6-NEXT: addiu $4, $zero, 255
+; MIPSELR6-NEXT: sllv $7, $4, $2
+; MIPSELR6-NEXT: sllv $6, $3, $2
+; MIPSELR6-NEXT: xori $8, $1, 24
; MIPSELR6-NEXT: $BB8_1: # %entry
; MIPSELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSELR6-NEXT: ll $2, 0($6)
-; MIPSELR6-NEXT: srav $4, $2, $10
-; MIPSELR6-NEXT: seb $4, $4
-; MIPSELR6-NEXT: or $1, $zero, $4
-; MIPSELR6-NEXT: sllv $4, $4, $10
-; MIPSELR6-NEXT: slt $5, $4, $7
-; MIPSELR6-NEXT: seleqz $3, $4, $5
-; MIPSELR6-NEXT: selnez $5, $7, $5
-; MIPSELR6-NEXT: or $3, $3, $5
-; MIPSELR6-NEXT: and $3, $3, $8
-; MIPSELR6-NEXT: and $4, $2, $9
-; MIPSELR6-NEXT: or $4, $4, $3
-; MIPSELR6-NEXT: sc $4, 0($6)
-; MIPSELR6-NEXT: beqzc $4, $BB8_1
-; MIPSELR6-NEXT: nop
+; MIPSELR6-NEXT: ll $1, 0($5)
+; MIPSELR6-NEXT: and $3, $1, $7
+; MIPSELR6-NEXT: sllv $3, $3, $8
+; MIPSELR6-NEXT: srav $3, $3, $8
+; MIPSELR6-NEXT: slt $4, $3, $6
+; MIPSELR6-NEXT: seleqz $3, $3, $4
+; MIPSELR6-NEXT: selnez $4, $6, $4
+; MIPSELR6-NEXT: or $3, $3, $4
+; MIPSELR6-NEXT: xor $3, $1, $3
+; MIPSELR6-NEXT: and $3, $3, $7
+; MIPSELR6-NEXT: xor $3, $1, $3
+; MIPSELR6-NEXT: sc $3, 0($5)
+; MIPSELR6-NEXT: beqzc $3, $BB8_1
; MIPSELR6-NEXT: # %bb.2: # %entry
-; MIPSELR6-NEXT: .insn
-; MIPSELR6-NEXT: # %bb.3: # %entry
-; MIPSELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSELR6-NEXT: # %bb.4: # %entry
-; MIPSELR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSELR6-NEXT: srlv $2, $1, $2
; MIPSELR6-NEXT: sync
-; MIPSELR6-NEXT: addiu $sp, $sp, 8
; MIPSELR6-NEXT: jrc $ra
;
; MMEL-LABEL: test_max_8:
; MMEL: # %bb.0: # %entry
-; MMEL-NEXT: addiu $sp, $sp, -8
-; MMEL-NEXT: .cfi_def_cfa_offset 8
+; MMEL-NEXT: move $1, $5
; MMEL-NEXT: sync
-; MMEL-NEXT: addiu $1, $zero, -4
-; MMEL-NEXT: and $6, $4, $1
-; MMEL-NEXT: andi $1, $4, 3
-; MMEL-NEXT: sll $10, $1, 3
-; MMEL-NEXT: ori $1, $zero, 255
-; MMEL-NEXT: sllv $8, $1, $10
-; MMEL-NEXT: nor $9, $zero, $8
-; MMEL-NEXT: sllv $7, $5, $10
+; MMEL-NEXT: addiu $5, $zero, -4
+; MMEL-NEXT: and16 $5, $4
+; MMEL-NEXT: sll16 $2, $4, 3
+; MMEL-NEXT: andi $2, $2, 24
+; MMEL-NEXT: addiu $3, $zero, 255
+; MMEL-NEXT: sllv $7, $3, $2
+; MMEL-NEXT: sllv $6, $1, $2
+; MMEL-NEXT: xori $8, $2, 24
; MMEL-NEXT: $BB8_1: # %entry
; MMEL-NEXT: # =>This Inner Loop Header: Depth=1
-; MMEL-NEXT: ll $2, 0($6)
-; MMEL-NEXT: srav $4, $2, $10
-; MMEL-NEXT: seb $4, $4
-; MMEL-NEXT: or $1, $zero, $4
-; MMEL-NEXT: sllv $4, $4, $10
-; MMEL-NEXT: slt $5, $4, $7
-; MMEL-NEXT: or $3, $4, $zero
-; MMEL-NEXT: movn $3, $7, $5
-; MMEL-NEXT: and $3, $3, $8
-; MMEL-NEXT: and $4, $2, $9
-; MMEL-NEXT: or $4, $4, $3
-; MMEL-NEXT: sc $4, 0($6)
-; MMEL-NEXT: beqzc $4, $BB8_1
+; MMEL-NEXT: ll $1, 0($5)
+; MMEL-NEXT: and $3, $1, $7
+; MMEL-NEXT: sllv $3, $3, $8
+; MMEL-NEXT: srav $3, $3, $8
+; MMEL-NEXT: slt $4, $3, $6
+; MMEL-NEXT: movn $3, $6, $4
+; MMEL-NEXT: xor $3, $1, $3
+; MMEL-NEXT: and $3, $3, $7
+; MMEL-NEXT: xor $3, $1, $3
+; MMEL-NEXT: sc $3, 0($5)
+; MMEL-NEXT: beqzc $3, $BB8_1
; MMEL-NEXT: # %bb.2: # %entry
-; MMEL-NEXT: .insn
-; MMEL-NEXT: # %bb.3: # %entry
-; MMEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMEL-NEXT: # %bb.4: # %entry
-; MMEL-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMEL-NEXT: srlv $2, $1, $2
; MMEL-NEXT: sync
-; MMEL-NEXT: addiusp 8
; MMEL-NEXT: jrc $ra
;
; MMELR6-LABEL: test_max_8:
; MMELR6: # %bb.0: # %entry
-; MMELR6-NEXT: addiu $sp, $sp, -8
-; MMELR6-NEXT: .cfi_def_cfa_offset 8
+; MMELR6-NEXT: move $1, $5
; MMELR6-NEXT: sync
-; MMELR6-NEXT: addiu $1, $zero, -4
-; MMELR6-NEXT: and $6, $4, $1
-; MMELR6-NEXT: andi $1, $4, 3
-; MMELR6-NEXT: sll $10, $1, 3
-; MMELR6-NEXT: ori $1, $zero, 255
-; MMELR6-NEXT: sllv $8, $1, $10
-; MMELR6-NEXT: nor $9, $zero, $8
-; MMELR6-NEXT: sllv $7, $5, $10
+; MMELR6-NEXT: addiu $2, $zero, -4
+; MMELR6-NEXT: and $5, $4, $2
+; MMELR6-NEXT: sll16 $2, $4, 3
+; MMELR6-NEXT: andi $2, $2, 24
+; MMELR6-NEXT: addiu $3, $zero, 255
+; MMELR6-NEXT: sllv $7, $3, $2
+; MMELR6-NEXT: sllv $6, $1, $2
+; MMELR6-NEXT: xori $8, $2, 24
; MMELR6-NEXT: $BB8_1: # %entry
; MMELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MMELR6-NEXT: ll $2, 0($6)
-; MMELR6-NEXT: srav $4, $2, $10
-; MMELR6-NEXT: seb $4, $4
-; MMELR6-NEXT: or $1, $zero, $4
-; MMELR6-NEXT: sllv $4, $4, $10
-; MMELR6-NEXT: slt $5, $4, $7
-; MMELR6-NEXT: seleqz $3, $4, $5
-; MMELR6-NEXT: selnez $5, $7, $5
-; MMELR6-NEXT: or $3, $3, $5
-; MMELR6-NEXT: and $3, $3, $8
-; MMELR6-NEXT: and $4, $2, $9
-; MMELR6-NEXT: or $4, $4, $3
-; MMELR6-NEXT: sc $4, 0($6)
-; MMELR6-NEXT: beqc $4, $zero, $BB8_1
+; MMELR6-NEXT: ll $1, 0($5)
+; MMELR6-NEXT: and $3, $1, $7
+; MMELR6-NEXT: sllv $3, $3, $8
+; MMELR6-NEXT: srav $3, $3, $8
+; MMELR6-NEXT: slt $4, $3, $6
+; MMELR6-NEXT: seleqz $3, $3, $4
+; MMELR6-NEXT: selnez $4, $6, $4
+; MMELR6-NEXT: or $3, $3, $4
+; MMELR6-NEXT: xor $3, $1, $3
+; MMELR6-NEXT: and $3, $3, $7
+; MMELR6-NEXT: xor $3, $1, $3
+; MMELR6-NEXT: sc $3, 0($5)
+; MMELR6-NEXT: beqc $3, $zero, $BB8_1
; MMELR6-NEXT: # %bb.2: # %entry
-; MMELR6-NEXT: .insn
-; MMELR6-NEXT: # %bb.3: # %entry
-; MMELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMELR6-NEXT: # %bb.4: # %entry
-; MMELR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMELR6-NEXT: srlv $2, $1, $2
; MMELR6-NEXT: sync
-; MMELR6-NEXT: addiu $sp, $sp, 8
; MMELR6-NEXT: jrc $ra
;
; MIPS64-LABEL: test_max_8:
; MIPS64: # %bb.0: # %entry
-; MIPS64-NEXT: daddiu $sp, $sp, -16
-; MIPS64-NEXT: .cfi_def_cfa_offset 16
; MIPS64-NEXT: move $1, $5
; MIPS64-NEXT: sync
; MIPS64-NEXT: daddiu $2, $zero, -4
-; MIPS64-NEXT: and $6, $4, $2
-; MIPS64-NEXT: andi $2, $4, 3
-; MIPS64-NEXT: xori $2, $2, 3
-; MIPS64-NEXT: sll $10, $2, 3
-; MIPS64-NEXT: ori $2, $zero, 255
-; MIPS64-NEXT: sllv $8, $2, $10
-; MIPS64-NEXT: nor $9, $zero, $8
-; MIPS64-NEXT: sllv $7, $1, $10
+; MIPS64-NEXT: and $5, $4, $2
+; MIPS64-NEXT: move $2, $4
+; MIPS64-NEXT: sll $2, $2, 0
+; MIPS64-NEXT: not $2, $2
+; MIPS64-NEXT: andi $2, $2, 3
+; MIPS64-NEXT: sll $2, $2, 3
+; MIPS64-NEXT: addiu $3, $zero, 255
+; MIPS64-NEXT: sllv $7, $3, $2
+; MIPS64-NEXT: sllv $6, $1, $2
+; MIPS64-NEXT: xori $8, $2, 24
; MIPS64-NEXT: .LBB8_1: # %entry
; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64-NEXT: ll $2, 0($6)
-; MIPS64-NEXT: srav $4, $2, $10
-; MIPS64-NEXT: seb $4, $4
-; MIPS64-NEXT: or $1, $zero, $4
-; MIPS64-NEXT: sllv $4, $4, $10
-; MIPS64-NEXT: slt $5, $4, $7
-; MIPS64-NEXT: move $3, $4
-; MIPS64-NEXT: movn $3, $7, $5
-; MIPS64-NEXT: and $3, $3, $8
-; MIPS64-NEXT: and $4, $2, $9
-; MIPS64-NEXT: or $4, $4, $3
-; MIPS64-NEXT: sc $4, 0($6)
-; MIPS64-NEXT: beqz $4, .LBB8_1
+; MIPS64-NEXT: ll $1, 0($5)
+; MIPS64-NEXT: and $3, $1, $7
+; MIPS64-NEXT: sllv $3, $3, $8
+; MIPS64-NEXT: srav $3, $3, $8
+; MIPS64-NEXT: slt $4, $3, $6
+; MIPS64-NEXT: movn $3, $6, $4
+; MIPS64-NEXT: xor $3, $1, $3
+; MIPS64-NEXT: and $3, $3, $7
+; MIPS64-NEXT: xor $3, $1, $3
+; MIPS64-NEXT: sc $3, 0($5)
+; MIPS64-NEXT: beqz $3, .LBB8_1
; MIPS64-NEXT: nop
; MIPS64-NEXT: # %bb.2: # %entry
-; MIPS64-NEXT: .insn
-; MIPS64-NEXT: # %bb.3: # %entry
-; MIPS64-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64-NEXT: # %bb.4: # %entry
-; MIPS64-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64-NEXT: srlv $2, $1, $2
; MIPS64-NEXT: sync
-; MIPS64-NEXT: daddiu $sp, $sp, 16
; MIPS64-NEXT: jr $ra
; MIPS64-NEXT: nop
;
; MIPS64R6-LABEL: test_max_8:
; MIPS64R6: # %bb.0: # %entry
-; MIPS64R6-NEXT: daddiu $sp, $sp, -16
-; MIPS64R6-NEXT: .cfi_def_cfa_offset 16
; MIPS64R6-NEXT: move $1, $5
; MIPS64R6-NEXT: sync
; MIPS64R6-NEXT: daddiu $2, $zero, -4
-; MIPS64R6-NEXT: and $6, $4, $2
-; MIPS64R6-NEXT: andi $2, $4, 3
-; MIPS64R6-NEXT: xori $2, $2, 3
-; MIPS64R6-NEXT: sll $10, $2, 3
-; MIPS64R6-NEXT: ori $2, $zero, 255
-; MIPS64R6-NEXT: sllv $8, $2, $10
-; MIPS64R6-NEXT: nor $9, $zero, $8
-; MIPS64R6-NEXT: sllv $7, $1, $10
+; MIPS64R6-NEXT: and $5, $4, $2
+; MIPS64R6-NEXT: move $2, $4
+; MIPS64R6-NEXT: sll $2, $2, 0
+; MIPS64R6-NEXT: not $2, $2
+; MIPS64R6-NEXT: andi $2, $2, 3
+; MIPS64R6-NEXT: sll $2, $2, 3
+; MIPS64R6-NEXT: addiu $3, $zero, 255
+; MIPS64R6-NEXT: sllv $7, $3, $2
+; MIPS64R6-NEXT: sllv $6, $1, $2
+; MIPS64R6-NEXT: xori $8, $2, 24
; MIPS64R6-NEXT: .LBB8_1: # %entry
; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R6-NEXT: ll $2, 0($6)
-; MIPS64R6-NEXT: srav $4, $2, $10
-; MIPS64R6-NEXT: seb $4, $4
-; MIPS64R6-NEXT: or $1, $zero, $4
-; MIPS64R6-NEXT: sllv $4, $4, $10
-; MIPS64R6-NEXT: slt $5, $4, $7
-; MIPS64R6-NEXT: seleqz $3, $4, $5
-; MIPS64R6-NEXT: selnez $5, $7, $5
-; MIPS64R6-NEXT: or $3, $3, $5
-; MIPS64R6-NEXT: and $3, $3, $8
-; MIPS64R6-NEXT: and $4, $2, $9
-; MIPS64R6-NEXT: or $4, $4, $3
-; MIPS64R6-NEXT: sc $4, 0($6)
-; MIPS64R6-NEXT: beqzc $4, .LBB8_1
-; MIPS64R6-NEXT: nop
+; MIPS64R6-NEXT: ll $1, 0($5)
+; MIPS64R6-NEXT: and $3, $1, $7
+; MIPS64R6-NEXT: sllv $3, $3, $8
+; MIPS64R6-NEXT: srav $3, $3, $8
+; MIPS64R6-NEXT: slt $4, $3, $6
+; MIPS64R6-NEXT: seleqz $3, $3, $4
+; MIPS64R6-NEXT: selnez $4, $6, $4
+; MIPS64R6-NEXT: or $3, $3, $4
+; MIPS64R6-NEXT: xor $3, $1, $3
+; MIPS64R6-NEXT: and $3, $3, $7
+; MIPS64R6-NEXT: xor $3, $1, $3
+; MIPS64R6-NEXT: sc $3, 0($5)
+; MIPS64R6-NEXT: beqzc $3, .LBB8_1
; MIPS64R6-NEXT: # %bb.2: # %entry
-; MIPS64R6-NEXT: .insn
-; MIPS64R6-NEXT: # %bb.3: # %entry
-; MIPS64R6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64R6-NEXT: # %bb.4: # %entry
-; MIPS64R6-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64R6-NEXT: srlv $2, $1, $2
; MIPS64R6-NEXT: sync
-; MIPS64R6-NEXT: daddiu $sp, $sp, 16
; MIPS64R6-NEXT: jrc $ra
;
; MIPS64EL-LABEL: test_max_8:
; MIPS64EL: # %bb.0: # %entry
-; MIPS64EL-NEXT: daddiu $sp, $sp, -16
-; MIPS64EL-NEXT: .cfi_def_cfa_offset 16
; MIPS64EL-NEXT: move $1, $5
; MIPS64EL-NEXT: sync
; MIPS64EL-NEXT: daddiu $2, $zero, -4
-; MIPS64EL-NEXT: and $6, $4, $2
-; MIPS64EL-NEXT: andi $2, $4, 3
-; MIPS64EL-NEXT: sll $10, $2, 3
-; MIPS64EL-NEXT: ori $2, $zero, 255
-; MIPS64EL-NEXT: sllv $8, $2, $10
-; MIPS64EL-NEXT: nor $9, $zero, $8
-; MIPS64EL-NEXT: sllv $7, $1, $10
+; MIPS64EL-NEXT: and $5, $4, $2
+; MIPS64EL-NEXT: move $2, $4
+; MIPS64EL-NEXT: sll $2, $2, 0
+; MIPS64EL-NEXT: andi $2, $2, 3
+; MIPS64EL-NEXT: sll $2, $2, 3
+; MIPS64EL-NEXT: addiu $3, $zero, 255
+; MIPS64EL-NEXT: sllv $7, $3, $2
+; MIPS64EL-NEXT: sllv $6, $1, $2
+; MIPS64EL-NEXT: xori $8, $2, 24
; MIPS64EL-NEXT: .LBB8_1: # %entry
; MIPS64EL-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64EL-NEXT: ll $2, 0($6)
-; MIPS64EL-NEXT: srav $4, $2, $10
-; MIPS64EL-NEXT: seb $4, $4
-; MIPS64EL-NEXT: or $1, $zero, $4
-; MIPS64EL-NEXT: sllv $4, $4, $10
-; MIPS64EL-NEXT: slt $5, $4, $7
-; MIPS64EL-NEXT: move $3, $4
-; MIPS64EL-NEXT: movn $3, $7, $5
-; MIPS64EL-NEXT: and $3, $3, $8
-; MIPS64EL-NEXT: and $4, $2, $9
-; MIPS64EL-NEXT: or $4, $4, $3
-; MIPS64EL-NEXT: sc $4, 0($6)
-; MIPS64EL-NEXT: beqz $4, .LBB8_1
+; MIPS64EL-NEXT: ll $1, 0($5)
+; MIPS64EL-NEXT: and $3, $1, $7
+; MIPS64EL-NEXT: sllv $3, $3, $8
+; MIPS64EL-NEXT: srav $3, $3, $8
+; MIPS64EL-NEXT: slt $4, $3, $6
+; MIPS64EL-NEXT: movn $3, $6, $4
+; MIPS64EL-NEXT: xor $3, $1, $3
+; MIPS64EL-NEXT: and $3, $3, $7
+; MIPS64EL-NEXT: xor $3, $1, $3
+; MIPS64EL-NEXT: sc $3, 0($5)
+; MIPS64EL-NEXT: beqz $3, .LBB8_1
; MIPS64EL-NEXT: nop
; MIPS64EL-NEXT: # %bb.2: # %entry
-; MIPS64EL-NEXT: .insn
-; MIPS64EL-NEXT: # %bb.3: # %entry
-; MIPS64EL-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64EL-NEXT: # %bb.4: # %entry
-; MIPS64EL-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64EL-NEXT: srlv $2, $1, $2
; MIPS64EL-NEXT: sync
-; MIPS64EL-NEXT: daddiu $sp, $sp, 16
; MIPS64EL-NEXT: jr $ra
; MIPS64EL-NEXT: nop
;
; MIPS64ELR6-LABEL: test_max_8:
; MIPS64ELR6: # %bb.0: # %entry
-; MIPS64ELR6-NEXT: daddiu $sp, $sp, -16
-; MIPS64ELR6-NEXT: .cfi_def_cfa_offset 16
; MIPS64ELR6-NEXT: move $1, $5
; MIPS64ELR6-NEXT: sync
; MIPS64ELR6-NEXT: daddiu $2, $zero, -4
-; MIPS64ELR6-NEXT: and $6, $4, $2
-; MIPS64ELR6-NEXT: andi $2, $4, 3
-; MIPS64ELR6-NEXT: sll $10, $2, 3
-; MIPS64ELR6-NEXT: ori $2, $zero, 255
-; MIPS64ELR6-NEXT: sllv $8, $2, $10
-; MIPS64ELR6-NEXT: nor $9, $zero, $8
-; MIPS64ELR6-NEXT: sllv $7, $1, $10
+; MIPS64ELR6-NEXT: and $5, $4, $2
+; MIPS64ELR6-NEXT: move $2, $4
+; MIPS64ELR6-NEXT: sll $2, $2, 0
+; MIPS64ELR6-NEXT: andi $2, $2, 3
+; MIPS64ELR6-NEXT: sll $2, $2, 3
+; MIPS64ELR6-NEXT: addiu $3, $zero, 255
+; MIPS64ELR6-NEXT: sllv $7, $3, $2
+; MIPS64ELR6-NEXT: sllv $6, $1, $2
+; MIPS64ELR6-NEXT: xori $8, $2, 24
; MIPS64ELR6-NEXT: .LBB8_1: # %entry
; MIPS64ELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64ELR6-NEXT: ll $2, 0($6)
-; MIPS64ELR6-NEXT: srav $4, $2, $10
-; MIPS64ELR6-NEXT: seb $4, $4
-; MIPS64ELR6-NEXT: or $1, $zero, $4
-; MIPS64ELR6-NEXT: sllv $4, $4, $10
-; MIPS64ELR6-NEXT: slt $5, $4, $7
-; MIPS64ELR6-NEXT: seleqz $3, $4, $5
-; MIPS64ELR6-NEXT: selnez $5, $7, $5
-; MIPS64ELR6-NEXT: or $3, $3, $5
-; MIPS64ELR6-NEXT: and $3, $3, $8
-; MIPS64ELR6-NEXT: and $4, $2, $9
-; MIPS64ELR6-NEXT: or $4, $4, $3
-; MIPS64ELR6-NEXT: sc $4, 0($6)
-; MIPS64ELR6-NEXT: beqzc $4, .LBB8_1
-; MIPS64ELR6-NEXT: nop
+; MIPS64ELR6-NEXT: ll $1, 0($5)
+; MIPS64ELR6-NEXT: and $3, $1, $7
+; MIPS64ELR6-NEXT: sllv $3, $3, $8
+; MIPS64ELR6-NEXT: srav $3, $3, $8
+; MIPS64ELR6-NEXT: slt $4, $3, $6
+; MIPS64ELR6-NEXT: seleqz $3, $3, $4
+; MIPS64ELR6-NEXT: selnez $4, $6, $4
+; MIPS64ELR6-NEXT: or $3, $3, $4
+; MIPS64ELR6-NEXT: xor $3, $1, $3
+; MIPS64ELR6-NEXT: and $3, $3, $7
+; MIPS64ELR6-NEXT: xor $3, $1, $3
+; MIPS64ELR6-NEXT: sc $3, 0($5)
+; MIPS64ELR6-NEXT: beqzc $3, .LBB8_1
; MIPS64ELR6-NEXT: # %bb.2: # %entry
-; MIPS64ELR6-NEXT: .insn
-; MIPS64ELR6-NEXT: # %bb.3: # %entry
-; MIPS64ELR6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64ELR6-NEXT: # %bb.4: # %entry
-; MIPS64ELR6-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64ELR6-NEXT: srlv $2, $1, $2
; MIPS64ELR6-NEXT: sync
-; MIPS64ELR6-NEXT: daddiu $sp, $sp, 16
; MIPS64ELR6-NEXT: jrc $ra
entry:
%0 = atomicrmw max ptr %ptr, i8 %val seq_cst
@@ -3908,578 +3348,466 @@ entry:
define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) {
; MIPS-LABEL: test_min_8:
; MIPS: # %bb.0: # %entry
-; MIPS-NEXT: addiu $sp, $sp, -8
-; MIPS-NEXT: .cfi_def_cfa_offset 8
+; MIPS-NEXT: move $1, $5
+; MIPS-NEXT: not $2, $4
; MIPS-NEXT: sync
-; MIPS-NEXT: addiu $1, $zero, -4
-; MIPS-NEXT: and $6, $4, $1
-; MIPS-NEXT: andi $1, $4, 3
-; MIPS-NEXT: xori $1, $1, 3
-; MIPS-NEXT: sll $10, $1, 3
-; MIPS-NEXT: ori $1, $zero, 255
-; MIPS-NEXT: sllv $8, $1, $10
-; MIPS-NEXT: nor $9, $zero, $8
-; MIPS-NEXT: sllv $7, $5, $10
+; MIPS-NEXT: addiu $3, $zero, -4
+; MIPS-NEXT: and $5, $4, $3
+; MIPS-NEXT: andi $2, $2, 3
+; MIPS-NEXT: sll $2, $2, 3
+; MIPS-NEXT: addiu $3, $zero, 255
+; MIPS-NEXT: sllv $7, $3, $2
+; MIPS-NEXT: sllv $6, $1, $2
+; MIPS-NEXT: xori $8, $2, 24
; MIPS-NEXT: $BB9_1: # %entry
; MIPS-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS-NEXT: ll $2, 0($6)
-; MIPS-NEXT: srav $4, $2, $10
-; MIPS-NEXT: seb $4, $4
-; MIPS-NEXT: or $1, $zero, $4
-; MIPS-NEXT: sllv $4, $4, $10
-; MIPS-NEXT: slt $5, $4, $7
-; MIPS-NEXT: move $3, $4
-; MIPS-NEXT: movz $3, $7, $5
-; MIPS-NEXT: and $3, $3, $8
-; MIPS-NEXT: and $4, $2, $9
-; MIPS-NEXT: or $4, $4, $3
-; MIPS-NEXT: sc $4, 0($6)
-; MIPS-NEXT: beqz $4, $BB9_1
+; MIPS-NEXT: ll $1, 0($5)
+; MIPS-NEXT: and $3, $1, $7
+; MIPS-NEXT: sllv $3, $3, $8
+; MIPS-NEXT: srav $3, $3, $8
+; MIPS-NEXT: slt $4, $6, $3
+; MIPS-NEXT: movn $3, $6, $4
+; MIPS-NEXT: xor $3, $1, $3
+; MIPS-NEXT: and $3, $3, $7
+; MIPS-NEXT: xor $3, $1, $3
+; MIPS-NEXT: sc $3, 0($5)
+; MIPS-NEXT: beqz $3, $BB9_1
; MIPS-NEXT: nop
; MIPS-NEXT: # %bb.2: # %entry
-; MIPS-NEXT: .insn
-; MIPS-NEXT: # %bb.3: # %entry
-; MIPS-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS-NEXT: # %bb.4: # %entry
-; MIPS-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPS-NEXT: srlv $2, $1, $2
; MIPS-NEXT: sync
-; MIPS-NEXT: addiu $sp, $sp, 8
; MIPS-NEXT: jr $ra
; MIPS-NEXT: nop
;
-; MIPS2-LABEL: test_min_8:
-; MIPS2: # %bb.0: # %entry
-; MIPS2-NEXT: addiu $sp, $sp, -8
-; MIPS2-NEXT: .cfi_def_cfa_offset 8
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: addiu $1, $zero, -4
-; MIPS2-NEXT: and $6, $4, $1
-; MIPS2-NEXT: andi $1, $4, 3
-; MIPS2-NEXT: sll $10, $1, 3
-; MIPS2-NEXT: ori $1, $zero, 255
-; MIPS2-NEXT: sllv $8, $1, $10
-; MIPS2-NEXT: nor $9, $zero, $8
-; MIPS2-NEXT: sllv $7, $5, $10
-; MIPS2-NEXT: $BB9_1: # %entry
-; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS2-NEXT: ll $2, 0($6)
-; MIPS2-NEXT: srav $4, $2, $10
-; MIPS2-NEXT: sll $4, $4, 24
-; MIPS2-NEXT: sra $4, $4, 24
-; MIPS2-NEXT: or $1, $zero, $4
-; MIPS2-NEXT: sllv $4, $4, $10
-; MIPS2-NEXT: slt $5, $4, $7
-; MIPS2-NEXT: move $3, $4
-; MIPS2-NEXT: beqz $5, $BB9_3
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.2: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB9_1 Depth=1
-; MIPS2-NEXT: j $BB9_4
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: $BB9_3: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB9_1 Depth=1
-; MIPS2-NEXT: move $3, $7
-; MIPS2-NEXT: $BB9_4: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB9_1 Depth=1
-; MIPS2-NEXT: and $3, $3, $8
-; MIPS2-NEXT: and $4, $2, $9
-; MIPS2-NEXT: or $4, $4, $3
-; MIPS2-NEXT: sc $4, 0($6)
-; MIPS2-NEXT: beqz $4, $BB9_1
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.5: # %entry
-; MIPS2-NEXT: .insn
-; MIPS2-NEXT: # %bb.6: # %entry
-; MIPS2-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS2-NEXT: # %bb.7: # %entry
-; MIPS2-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: addiu $sp, $sp, 8
-; MIPS2-NEXT: jr $ra
-; MIPS2-NEXT: nop
-;
; MIPSR6-LABEL: test_min_8:
; MIPSR6: # %bb.0: # %entry
-; MIPSR6-NEXT: addiu $sp, $sp, -8
-; MIPSR6-NEXT: .cfi_def_cfa_offset 8
+; MIPSR6-NEXT: move $1, $5
+; MIPSR6-NEXT: not $2, $4
; MIPSR6-NEXT: sync
-; MIPSR6-NEXT: addiu $1, $zero, -4
-; MIPSR6-NEXT: and $6, $4, $1
-; MIPSR6-NEXT: andi $1, $4, 3
-; MIPSR6-NEXT: xori $1, $1, 3
-; MIPSR6-NEXT: sll $10, $1, 3
-; MIPSR6-NEXT: ori $1, $zero, 255
-; MIPSR6-NEXT: sllv $8, $1, $10
-; MIPSR6-NEXT: nor $9, $zero, $8
-; MIPSR6-NEXT: sllv $7, $5, $10
+; MIPSR6-NEXT: addiu $3, $zero, -4
+; MIPSR6-NEXT: and $5, $4, $3
+; MIPSR6-NEXT: andi $2, $2, 3
+; MIPSR6-NEXT: sll $2, $2, 3
+; MIPSR6-NEXT: addiu $3, $zero, 255
+; MIPSR6-NEXT: sllv $7, $3, $2
+; MIPSR6-NEXT: sllv $6, $1, $2
+; MIPSR6-NEXT: xori $8, $2, 24
; MIPSR6-NEXT: $BB9_1: # %entry
; MIPSR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSR6-NEXT: ll $2, 0($6)
-; MIPSR6-NEXT: srav $4, $2, $10
-; MIPSR6-NEXT: seb $4, $4
-; MIPSR6-NEXT: or $1, $zero, $4
-; MIPSR6-NEXT: sllv $4, $4, $10
-; MIPSR6-NEXT: slt $5, $4, $7
-; MIPSR6-NEXT: selnez $3, $4, $5
-; MIPSR6-NEXT: seleqz $5, $7, $5
-; MIPSR6-NEXT: or $3, $3, $5
-; MIPSR6-NEXT: and $3, $3, $8
-; MIPSR6-NEXT: and $4, $2, $9
-; MIPSR6-NEXT: or $4, $4, $3
-; MIPSR6-NEXT: sc $4, 0($6)
-; MIPSR6-NEXT: beqzc $4, $BB9_1
-; MIPSR6-NEXT: nop
+; MIPSR6-NEXT: ll $1, 0($5)
+; MIPSR6-NEXT: and $3, $1, $7
+; MIPSR6-NEXT: sllv $3, $3, $8
+; MIPSR6-NEXT: srav $3, $3, $8
+; MIPSR6-NEXT: slt $4, $6, $3
+; MIPSR6-NEXT: seleqz $3, $3, $4
+; MIPSR6-NEXT: selnez $4, $6, $4
+; MIPSR6-NEXT: or $3, $3, $4
+; MIPSR6-NEXT: xor $3, $1, $3
+; MIPSR6-NEXT: and $3, $3, $7
+; MIPSR6-NEXT: xor $3, $1, $3
+; MIPSR6-NEXT: sc $3, 0($5)
+; MIPSR6-NEXT: beqzc $3, $BB9_1
; MIPSR6-NEXT: # %bb.2: # %entry
-; MIPSR6-NEXT: .insn
-; MIPSR6-NEXT: # %bb.3: # %entry
-; MIPSR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSR6-NEXT: # %bb.4: # %entry
-; MIPSR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSR6-NEXT: srlv $2, $1, $2
; MIPSR6-NEXT: sync
-; MIPSR6-NEXT: addiu $sp, $sp, 8
; MIPSR6-NEXT: jrc $ra
;
; MM-LABEL: test_min_8:
; MM: # %bb.0: # %entry
-; MM-NEXT: addiu $sp, $sp, -8
-; MM-NEXT: .cfi_def_cfa_offset 8
+; MM-NEXT: move $1, $5
+; MM-NEXT: not16 $2, $4
; MM-NEXT: sync
-; MM-NEXT: addiu $1, $zero, -4
-; MM-NEXT: and $6, $4, $1
-; MM-NEXT: andi $1, $4, 3
-; MM-NEXT: xori $1, $1, 3
-; MM-NEXT: sll $10, $1, 3
-; MM-NEXT: ori $1, $zero, 255
-; MM-NEXT: sllv $8, $1, $10
-; MM-NEXT: nor $9, $zero, $8
-; MM-NEXT: sllv $7, $5, $10
+; MM-NEXT: addiu $5, $zero, -4
+; MM-NEXT: and16 $5, $4
+; MM-NEXT: andi16 $2, $2, 3
+; MM-NEXT: sll16 $2, $2, 3
+; MM-NEXT: addiu $3, $zero, 255
+; MM-NEXT: sllv $7, $3, $2
+; MM-NEXT: sllv $6, $1, $2
+; MM-NEXT: xori $8, $2, 24
; MM-NEXT: $BB9_1: # %entry
; MM-NEXT: # =>This Inner Loop Header: Depth=1
-; MM-NEXT: ll $2, 0($6)
-; MM-NEXT: srav $4, $2, $10
-; MM-NEXT: seb $4, $4
-; MM-NEXT: or $1, $zero, $4
-; MM-NEXT: sllv $4, $4, $10
-; MM-NEXT: slt $5, $4, $7
-; MM-NEXT: or $3, $4, $zero
-; MM-NEXT: movz $3, $7, $5
-; MM-NEXT: and $3, $3, $8
-; MM-NEXT: and $4, $2, $9
-; MM-NEXT: or $4, $4, $3
-; MM-NEXT: sc $4, 0($6)
-; MM-NEXT: beqzc $4, $BB9_1
+; MM-NEXT: ll $1, 0($5)
+; MM-NEXT: and $3, $1, $7
+; MM-NEXT: sllv $3, $3, $8
+; MM-NEXT: srav $3, $3, $8
+; MM-NEXT: slt $4, $6, $3
+; MM-NEXT: movn $3, $6, $4
+; MM-NEXT: xor $3, $1, $3
+; MM-NEXT: and $3, $3, $7
+; MM-NEXT: xor $3, $1, $3
+; MM-NEXT: sc $3, 0($5)
+; MM-NEXT: beqzc $3, $BB9_1
; MM-NEXT: # %bb.2: # %entry
-; MM-NEXT: .insn
-; MM-NEXT: # %bb.3: # %entry
-; MM-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MM-NEXT: # %bb.4: # %entry
-; MM-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MM-NEXT: srlv $2, $1, $2
; MM-NEXT: sync
-; MM-NEXT: addiusp 8
; MM-NEXT: jrc $ra
;
; MMR6-LABEL: test_min_8:
; MMR6: # %bb.0: # %entry
-; MMR6-NEXT: addiu $sp, $sp, -8
-; MMR6-NEXT: .cfi_def_cfa_offset 8
+; MMR6-NEXT: move $1, $5
+; MMR6-NEXT: not16 $2, $4
; MMR6-NEXT: sync
-; MMR6-NEXT: addiu $1, $zero, -4
-; MMR6-NEXT: and $6, $4, $1
-; MMR6-NEXT: andi $1, $4, 3
-; MMR6-NEXT: xori $1, $1, 3
-; MMR6-NEXT: sll $10, $1, 3
-; MMR6-NEXT: ori $1, $zero, 255
-; MMR6-NEXT: sllv $8, $1, $10
-; MMR6-NEXT: nor $9, $zero, $8
-; MMR6-NEXT: sllv $7, $5, $10
+; MMR6-NEXT: addiu $3, $zero, -4
+; MMR6-NEXT: and $5, $4, $3
+; MMR6-NEXT: andi16 $2, $2, 3
+; MMR6-NEXT: sll16 $2, $2, 3
+; MMR6-NEXT: addiu $3, $zero, 255
+; MMR6-NEXT: sllv $7, $3, $2
+; MMR6-NEXT: sllv $6, $1, $2
+; MMR6-NEXT: xori $8, $2, 24
; MMR6-NEXT: $BB9_1: # %entry
; MMR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MMR6-NEXT: ll $2, 0($6)
-; MMR6-NEXT: srav $4, $2, $10
-; MMR6-NEXT: seb $4, $4
-; MMR6-NEXT: or $1, $zero, $4
-; MMR6-NEXT: sllv $4, $4, $10
-; MMR6-NEXT: slt $5, $4, $7
-; MMR6-NEXT: selnez $3, $4, $5
-; MMR6-NEXT: seleqz $5, $7, $5
-; MMR6-NEXT: or $3, $3, $5
-; MMR6-NEXT: and $3, $3, $8
-; MMR6-NEXT: and $4, $2, $9
-; MMR6-NEXT: or $4, $4, $3
-; MMR6-NEXT: sc $4, 0($6)
-; MMR6-NEXT: beqc $4, $zero, $BB9_1
+; MMR6-NEXT: ll $1, 0($5)
+; MMR6-NEXT: and $3, $1, $7
+; MMR6-NEXT: sllv $3, $3, $8
+; MMR6-NEXT: srav $3, $3, $8
+; MMR6-NEXT: slt $4, $6, $3
+; MMR6-NEXT: seleqz $3, $3, $4
+; MMR6-NEXT: selnez $4, $6, $4
+; MMR6-NEXT: or $3, $3, $4
+; MMR6-NEXT: xor $3, $1, $3
+; MMR6-NEXT: and $3, $3, $7
+; MMR6-NEXT: xor $3, $1, $3
+; MMR6-NEXT: sc $3, 0($5)
+; MMR6-NEXT: beqc $3, $zero, $BB9_1
; MMR6-NEXT: # %bb.2: # %entry
-; MMR6-NEXT: .insn
-; MMR6-NEXT: # %bb.3: # %entry
-; MMR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMR6-NEXT: # %bb.4: # %entry
-; MMR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMR6-NEXT: srlv $2, $1, $2
; MMR6-NEXT: sync
-; MMR6-NEXT: addiu $sp, $sp, 8
; MMR6-NEXT: jrc $ra
;
+; MIPS2-LABEL: test_min_8:
+; MIPS2: # %bb.0: # %entry
+; MIPS2-NEXT: move $3, $5
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: addiu $1, $zero, -4
+; MIPS2-NEXT: and $5, $4, $1
+; MIPS2-NEXT: sll $2, $4, 3
+; MIPS2-NEXT: andi $1, $2, 24
+; MIPS2-NEXT: addiu $4, $zero, 255
+; MIPS2-NEXT: sllv $7, $4, $2
+; MIPS2-NEXT: sllv $6, $3, $2
+; MIPS2-NEXT: xori $8, $1, 24
+; MIPS2-NEXT: $BB9_1: # %entry
+; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
+; MIPS2-NEXT: ll $1, 0($5)
+; MIPS2-NEXT: and $3, $1, $7
+; MIPS2-NEXT: sllv $3, $3, $8
+; MIPS2-NEXT: srav $3, $3, $8
+; MIPS2-NEXT: slt $4, $6, $3
+; MIPS2-NEXT: beqz $4, $BB9_3
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.2: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB9_1 Depth=1
+; MIPS2-NEXT: move $3, $6
+; MIPS2-NEXT: $BB9_3: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB9_1 Depth=1
+; MIPS2-NEXT: xor $3, $1, $3
+; MIPS2-NEXT: and $3, $3, $7
+; MIPS2-NEXT: xor $3, $1, $3
+; MIPS2-NEXT: sc $3, 0($5)
+; MIPS2-NEXT: beqz $3, $BB9_1
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.4: # %entry
+; MIPS2-NEXT: srlv $2, $1, $2
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: jr $ra
+; MIPS2-NEXT: nop
+;
; MIPS32-LABEL: test_min_8:
; MIPS32: # %bb.0: # %entry
-; MIPS32-NEXT: addiu $sp, $sp, -8
-; MIPS32-NEXT: .cfi_def_cfa_offset 8
+; MIPS32-NEXT: move $3, $5
; MIPS32-NEXT: sync
; MIPS32-NEXT: addiu $1, $zero, -4
-; MIPS32-NEXT: and $6, $4, $1
-; MIPS32-NEXT: andi $1, $4, 3
-; MIPS32-NEXT: sll $10, $1, 3
-; MIPS32-NEXT: ori $1, $zero, 255
-; MIPS32-NEXT: sllv $8, $1, $10
-; MIPS32-NEXT: nor $9, $zero, $8
-; MIPS32-NEXT: sllv $7, $5, $10
+; MIPS32-NEXT: and $5, $4, $1
+; MIPS32-NEXT: sll $2, $4, 3
+; MIPS32-NEXT: andi $1, $2, 24
+; MIPS32-NEXT: addiu $4, $zero, 255
+; MIPS32-NEXT: sllv $7, $4, $2
+; MIPS32-NEXT: sllv $6, $3, $2
+; MIPS32-NEXT: xori $8, $1, 24
; MIPS32-NEXT: $BB9_1: # %entry
; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32-NEXT: ll $2, 0($6)
-; MIPS32-NEXT: srav $4, $2, $10
-; MIPS32-NEXT: sll $4, $4, 24
-; MIPS32-NEXT: sra $4, $4, 24
-; MIPS32-NEXT: or $1, $zero, $4
-; MIPS32-NEXT: sllv $4, $4, $10
-; MIPS32-NEXT: slt $5, $4, $7
-; MIPS32-NEXT: move $3, $4
-; MIPS32-NEXT: movz $3, $7, $5
-; MIPS32-NEXT: and $3, $3, $8
-; MIPS32-NEXT: and $4, $2, $9
-; MIPS32-NEXT: or $4, $4, $3
-; MIPS32-NEXT: sc $4, 0($6)
-; MIPS32-NEXT: beqz $4, $BB9_1
+; MIPS32-NEXT: ll $1, 0($5)
+; MIPS32-NEXT: and $3, $1, $7
+; MIPS32-NEXT: sllv $3, $3, $8
+; MIPS32-NEXT: srav $3, $3, $8
+; MIPS32-NEXT: slt $4, $6, $3
+; MIPS32-NEXT: movn $3, $6, $4
+; MIPS32-NEXT: xor $3, $1, $3
+; MIPS32-NEXT: and $3, $3, $7
+; MIPS32-NEXT: xor $3, $1, $3
+; MIPS32-NEXT: sc $3, 0($5)
+; MIPS32-NEXT: beqz $3, $BB9_1
; MIPS32-NEXT: nop
; MIPS32-NEXT: # %bb.2: # %entry
-; MIPS32-NEXT: .insn
-; MIPS32-NEXT: # %bb.3: # %entry
-; MIPS32-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32-NEXT: # %bb.4: # %entry
-; MIPS32-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPS32-NEXT: srlv $2, $1, $2
; MIPS32-NEXT: sync
-; MIPS32-NEXT: addiu $sp, $sp, 8
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPSEL-LABEL: test_min_8:
; MIPSEL: # %bb.0: # %entry
-; MIPSEL-NEXT: addiu $sp, $sp, -8
-; MIPSEL-NEXT: .cfi_def_cfa_offset 8
+; MIPSEL-NEXT: move $3, $5
; MIPSEL-NEXT: sync
; MIPSEL-NEXT: addiu $1, $zero, -4
-; MIPSEL-NEXT: and $6, $4, $1
-; MIPSEL-NEXT: andi $1, $4, 3
-; MIPSEL-NEXT: sll $10, $1, 3
-; MIPSEL-NEXT: ori $1, $zero, 255
-; MIPSEL-NEXT: sllv $8, $1, $10
-; MIPSEL-NEXT: nor $9, $zero, $8
-; MIPSEL-NEXT: sllv $7, $5, $10
+; MIPSEL-NEXT: and $5, $4, $1
+; MIPSEL-NEXT: sll $2, $4, 3
+; MIPSEL-NEXT: andi $1, $2, 24
+; MIPSEL-NEXT: addiu $4, $zero, 255
+; MIPSEL-NEXT: sllv $7, $4, $2
+; MIPSEL-NEXT: sllv $6, $3, $2
+; MIPSEL-NEXT: xori $8, $1, 24
; MIPSEL-NEXT: $BB9_1: # %entry
; MIPSEL-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSEL-NEXT: ll $2, 0($6)
-; MIPSEL-NEXT: srav $4, $2, $10
-; MIPSEL-NEXT: seb $4, $4
-; MIPSEL-NEXT: or $1, $zero, $4
-; MIPSEL-NEXT: sllv $4, $4, $10
-; MIPSEL-NEXT: slt $5, $4, $7
-; MIPSEL-NEXT: move $3, $4
-; MIPSEL-NEXT: movz $3, $7, $5
-; MIPSEL-NEXT: and $3, $3, $8
-; MIPSEL-NEXT: and $4, $2, $9
-; MIPSEL-NEXT: or $4, $4, $3
-; MIPSEL-NEXT: sc $4, 0($6)
-; MIPSEL-NEXT: beqz $4, $BB9_1
+; MIPSEL-NEXT: ll $1, 0($5)
+; MIPSEL-NEXT: and $3, $1, $7
+; MIPSEL-NEXT: sllv $3, $3, $8
+; MIPSEL-NEXT: srav $3, $3, $8
+; MIPSEL-NEXT: slt $4, $6, $3
+; MIPSEL-NEXT: movn $3, $6, $4
+; MIPSEL-NEXT: xor $3, $1, $3
+; MIPSEL-NEXT: and $3, $3, $7
+; MIPSEL-NEXT: xor $3, $1, $3
+; MIPSEL-NEXT: sc $3, 0($5)
+; MIPSEL-NEXT: beqz $3, $BB9_1
; MIPSEL-NEXT: nop
; MIPSEL-NEXT: # %bb.2: # %entry
-; MIPSEL-NEXT: .insn
-; MIPSEL-NEXT: # %bb.3: # %entry
-; MIPSEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSEL-NEXT: # %bb.4: # %entry
-; MIPSEL-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSEL-NEXT: srlv $2, $1, $2
; MIPSEL-NEXT: sync
-; MIPSEL-NEXT: addiu $sp, $sp, 8
; MIPSEL-NEXT: jr $ra
; MIPSEL-NEXT: nop
;
; MIPSELR6-LABEL: test_min_8:
; MIPSELR6: # %bb.0: # %entry
-; MIPSELR6-NEXT: addiu $sp, $sp, -8
-; MIPSELR6-NEXT: .cfi_def_cfa_offset 8
+; MIPSELR6-NEXT: move $3, $5
; MIPSELR6-NEXT: sync
; MIPSELR6-NEXT: addiu $1, $zero, -4
-; MIPSELR6-NEXT: and $6, $4, $1
-; MIPSELR6-NEXT: andi $1, $4, 3
-; MIPSELR6-NEXT: sll $10, $1, 3
-; MIPSELR6-NEXT: ori $1, $zero, 255
-; MIPSELR6-NEXT: sllv $8, $1, $10
-; MIPSELR6-NEXT: nor $9, $zero, $8
-; MIPSELR6-NEXT: sllv $7, $5, $10
+; MIPSELR6-NEXT: and $5, $4, $1
+; MIPSELR6-NEXT: sll $2, $4, 3
+; MIPSELR6-NEXT: andi $1, $2, 24
+; MIPSELR6-NEXT: addiu $4, $zero, 255
+; MIPSELR6-NEXT: sllv $7, $4, $2
+; MIPSELR6-NEXT: sllv $6, $3, $2
+; MIPSELR6-NEXT: xori $8, $1, 24
; MIPSELR6-NEXT: $BB9_1: # %entry
; MIPSELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSELR6-NEXT: ll $2, 0($6)
-; MIPSELR6-NEXT: srav $4, $2, $10
-; MIPSELR6-NEXT: seb $4, $4
-; MIPSELR6-NEXT: or $1, $zero, $4
-; MIPSELR6-NEXT: sllv $4, $4, $10
-; MIPSELR6-NEXT: slt $5, $4, $7
-; MIPSELR6-NEXT: selnez $3, $4, $5
-; MIPSELR6-NEXT: seleqz $5, $7, $5
-; MIPSELR6-NEXT: or $3, $3, $5
-; MIPSELR6-NEXT: and $3, $3, $8
-; MIPSELR6-NEXT: and $4, $2, $9
-; MIPSELR6-NEXT: or $4, $4, $3
-; MIPSELR6-NEXT: sc $4, 0($6)
-; MIPSELR6-NEXT: beqzc $4, $BB9_1
-; MIPSELR6-NEXT: nop
+; MIPSELR6-NEXT: ll $1, 0($5)
+; MIPSELR6-NEXT: and $3, $1, $7
+; MIPSELR6-NEXT: sllv $3, $3, $8
+; MIPSELR6-NEXT: srav $3, $3, $8
+; MIPSELR6-NEXT: slt $4, $6, $3
+; MIPSELR6-NEXT: seleqz $3, $3, $4
+; MIPSELR6-NEXT: selnez $4, $6, $4
+; MIPSELR6-NEXT: or $3, $3, $4
+; MIPSELR6-NEXT: xor $3, $1, $3
+; MIPSELR6-NEXT: and $3, $3, $7
+; MIPSELR6-NEXT: xor $3, $1, $3
+; MIPSELR6-NEXT: sc $3, 0($5)
+; MIPSELR6-NEXT: beqzc $3, $BB9_1
; MIPSELR6-NEXT: # %bb.2: # %entry
-; MIPSELR6-NEXT: .insn
-; MIPSELR6-NEXT: # %bb.3: # %entry
-; MIPSELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSELR6-NEXT: # %bb.4: # %entry
-; MIPSELR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSELR6-NEXT: srlv $2, $1, $2
; MIPSELR6-NEXT: sync
-; MIPSELR6-NEXT: addiu $sp, $sp, 8
; MIPSELR6-NEXT: jrc $ra
;
; MMEL-LABEL: test_min_8:
; MMEL: # %bb.0: # %entry
-; MMEL-NEXT: addiu $sp, $sp, -8
-; MMEL-NEXT: .cfi_def_cfa_offset 8
+; MMEL-NEXT: move $1, $5
; MMEL-NEXT: sync
-; MMEL-NEXT: addiu $1, $zero, -4
-; MMEL-NEXT: and $6, $4, $1
-; MMEL-NEXT: andi $1, $4, 3
-; MMEL-NEXT: sll $10, $1, 3
-; MMEL-NEXT: ori $1, $zero, 255
-; MMEL-NEXT: sllv $8, $1, $10
-; MMEL-NEXT: nor $9, $zero, $8
-; MMEL-NEXT: sllv $7, $5, $10
+; MMEL-NEXT: addiu $5, $zero, -4
+; MMEL-NEXT: and16 $5, $4
+; MMEL-NEXT: sll16 $2, $4, 3
+; MMEL-NEXT: andi $2, $2, 24
+; MMEL-NEXT: addiu $3, $zero, 255
+; MMEL-NEXT: sllv $7, $3, $2
+; MMEL-NEXT: sllv $6, $1, $2
+; MMEL-NEXT: xori $8, $2, 24
; MMEL-NEXT: $BB9_1: # %entry
; MMEL-NEXT: # =>This Inner Loop Header: Depth=1
-; MMEL-NEXT: ll $2, 0($6)
-; MMEL-NEXT: srav $4, $2, $10
-; MMEL-NEXT: seb $4, $4
-; MMEL-NEXT: or $1, $zero, $4
-; MMEL-NEXT: sllv $4, $4, $10
-; MMEL-NEXT: slt $5, $4, $7
-; MMEL-NEXT: or $3, $4, $zero
-; MMEL-NEXT: movz $3, $7, $5
-; MMEL-NEXT: and $3, $3, $8
-; MMEL-NEXT: and $4, $2, $9
-; MMEL-NEXT: or $4, $4, $3
-; MMEL-NEXT: sc $4, 0($6)
-; MMEL-NEXT: beqzc $4, $BB9_1
+; MMEL-NEXT: ll $1, 0($5)
+; MMEL-NEXT: and $3, $1, $7
+; MMEL-NEXT: sllv $3, $3, $8
+; MMEL-NEXT: srav $3, $3, $8
+; MMEL-NEXT: slt $4, $6, $3
+; MMEL-NEXT: movn $3, $6, $4
+; MMEL-NEXT: xor $3, $1, $3
+; MMEL-NEXT: and $3, $3, $7
+; MMEL-NEXT: xor $3, $1, $3
+; MMEL-NEXT: sc $3, 0($5)
+; MMEL-NEXT: beqzc $3, $BB9_1
; MMEL-NEXT: # %bb.2: # %entry
-; MMEL-NEXT: .insn
-; MMEL-NEXT: # %bb.3: # %entry
-; MMEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMEL-NEXT: # %bb.4: # %entry
-; MMEL-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMEL-NEXT: srlv $2, $1, $2
; MMEL-NEXT: sync
-; MMEL-NEXT: addiusp 8
; MMEL-NEXT: jrc $ra
;
; MMELR6-LABEL: test_min_8:
; MMELR6: # %bb.0: # %entry
-; MMELR6-NEXT: addiu $sp, $sp, -8
-; MMELR6-NEXT: .cfi_def_cfa_offset 8
+; MMELR6-NEXT: move $1, $5
; MMELR6-NEXT: sync
-; MMELR6-NEXT: addiu $1, $zero, -4
-; MMELR6-NEXT: and $6, $4, $1
-; MMELR6-NEXT: andi $1, $4, 3
-; MMELR6-NEXT: sll $10, $1, 3
-; MMELR6-NEXT: ori $1, $zero, 255
-; MMELR6-NEXT: sllv $8, $1, $10
-; MMELR6-NEXT: nor $9, $zero, $8
-; MMELR6-NEXT: sllv $7, $5, $10
+; MMELR6-NEXT: addiu $2, $zero, -4
+; MMELR6-NEXT: and $5, $4, $2
+; MMELR6-NEXT: sll16 $2, $4, 3
+; MMELR6-NEXT: andi $2, $2, 24
+; MMELR6-NEXT: addiu $3, $zero, 255
+; MMELR6-NEXT: sllv $7, $3, $2
+; MMELR6-NEXT: sllv $6, $1, $2
+; MMELR6-NEXT: xori $8, $2, 24
; MMELR6-NEXT: $BB9_1: # %entry
; MMELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MMELR6-NEXT: ll $2, 0($6)
-; MMELR6-NEXT: srav $4, $2, $10
-; MMELR6-NEXT: seb $4, $4
-; MMELR6-NEXT: or $1, $zero, $4
-; MMELR6-NEXT: sllv $4, $4, $10
-; MMELR6-NEXT: slt $5, $4, $7
-; MMELR6-NEXT: selnez $3, $4, $5
-; MMELR6-NEXT: seleqz $5, $7, $5
-; MMELR6-NEXT: or $3, $3, $5
-; MMELR6-NEXT: and $3, $3, $8
-; MMELR6-NEXT: and $4, $2, $9
-; MMELR6-NEXT: or $4, $4, $3
-; MMELR6-NEXT: sc $4, 0($6)
-; MMELR6-NEXT: beqc $4, $zero, $BB9_1
+; MMELR6-NEXT: ll $1, 0($5)
+; MMELR6-NEXT: and $3, $1, $7
+; MMELR6-NEXT: sllv $3, $3, $8
+; MMELR6-NEXT: srav $3, $3, $8
+; MMELR6-NEXT: slt $4, $6, $3
+; MMELR6-NEXT: seleqz $3, $3, $4
+; MMELR6-NEXT: selnez $4, $6, $4
+; MMELR6-NEXT: or $3, $3, $4
+; MMELR6-NEXT: xor $3, $1, $3
+; MMELR6-NEXT: and $3, $3, $7
+; MMELR6-NEXT: xor $3, $1, $3
+; MMELR6-NEXT: sc $3, 0($5)
+; MMELR6-NEXT: beqc $3, $zero, $BB9_1
; MMELR6-NEXT: # %bb.2: # %entry
-; MMELR6-NEXT: .insn
-; MMELR6-NEXT: # %bb.3: # %entry
-; MMELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMELR6-NEXT: # %bb.4: # %entry
-; MMELR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMELR6-NEXT: srlv $2, $1, $2
; MMELR6-NEXT: sync
-; MMELR6-NEXT: addiu $sp, $sp, 8
; MMELR6-NEXT: jrc $ra
;
; MIPS64-LABEL: test_min_8:
; MIPS64: # %bb.0: # %entry
-; MIPS64-NEXT: daddiu $sp, $sp, -16
-; MIPS64-NEXT: .cfi_def_cfa_offset 16
; MIPS64-NEXT: move $1, $5
; MIPS64-NEXT: sync
; MIPS64-NEXT: daddiu $2, $zero, -4
-; MIPS64-NEXT: and $6, $4, $2
-; MIPS64-NEXT: andi $2, $4, 3
-; MIPS64-NEXT: xori $2, $2, 3
-; MIPS64-NEXT: sll $10, $2, 3
-; MIPS64-NEXT: ori $2, $zero, 255
-; MIPS64-NEXT: sllv $8, $2, $10
-; MIPS64-NEXT: nor $9, $zero, $8
-; MIPS64-NEXT: sllv $7, $1, $10
+; MIPS64-NEXT: and $5, $4, $2
+; MIPS64-NEXT: move $2, $4
+; MIPS64-NEXT: sll $2, $2, 0
+; MIPS64-NEXT: not $2, $2
+; MIPS64-NEXT: andi $2, $2, 3
+; MIPS64-NEXT: sll $2, $2, 3
+; MIPS64-NEXT: addiu $3, $zero, 255
+; MIPS64-NEXT: sllv $7, $3, $2
+; MIPS64-NEXT: sllv $6, $1, $2
+; MIPS64-NEXT: xori $8, $2, 24
; MIPS64-NEXT: .LBB9_1: # %entry
; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64-NEXT: ll $2, 0($6)
-; MIPS64-NEXT: srav $4, $2, $10
-; MIPS64-NEXT: seb $4, $4
-; MIPS64-NEXT: or $1, $zero, $4
-; MIPS64-NEXT: sllv $4, $4, $10
-; MIPS64-NEXT: slt $5, $4, $7
-; MIPS64-NEXT: move $3, $4
-; MIPS64-NEXT: movz $3, $7, $5
-; MIPS64-NEXT: and $3, $3, $8
-; MIPS64-NEXT: and $4, $2, $9
-; MIPS64-NEXT: or $4, $4, $3
-; MIPS64-NEXT: sc $4, 0($6)
-; MIPS64-NEXT: beqz $4, .LBB9_1
+; MIPS64-NEXT: ll $1, 0($5)
+; MIPS64-NEXT: and $3, $1, $7
+; MIPS64-NEXT: sllv $3, $3, $8
+; MIPS64-NEXT: srav $3, $3, $8
+; MIPS64-NEXT: slt $4, $6, $3
+; MIPS64-NEXT: movn $3, $6, $4
+; MIPS64-NEXT: xor $3, $1, $3
+; MIPS64-NEXT: and $3, $3, $7
+; MIPS64-NEXT: xor $3, $1, $3
+; MIPS64-NEXT: sc $3, 0($5)
+; MIPS64-NEXT: beqz $3, .LBB9_1
; MIPS64-NEXT: nop
; MIPS64-NEXT: # %bb.2: # %entry
-; MIPS64-NEXT: .insn
-; MIPS64-NEXT: # %bb.3: # %entry
-; MIPS64-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64-NEXT: # %bb.4: # %entry
-; MIPS64-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64-NEXT: srlv $2, $1, $2
; MIPS64-NEXT: sync
-; MIPS64-NEXT: daddiu $sp, $sp, 16
; MIPS64-NEXT: jr $ra
; MIPS64-NEXT: nop
;
; MIPS64R6-LABEL: test_min_8:
; MIPS64R6: # %bb.0: # %entry
-; MIPS64R6-NEXT: daddiu $sp, $sp, -16
-; MIPS64R6-NEXT: .cfi_def_cfa_offset 16
; MIPS64R6-NEXT: move $1, $5
; MIPS64R6-NEXT: sync
; MIPS64R6-NEXT: daddiu $2, $zero, -4
-; MIPS64R6-NEXT: and $6, $4, $2
-; MIPS64R6-NEXT: andi $2, $4, 3
-; MIPS64R6-NEXT: xori $2, $2, 3
-; MIPS64R6-NEXT: sll $10, $2, 3
-; MIPS64R6-NEXT: ori $2, $zero, 255
-; MIPS64R6-NEXT: sllv $8, $2, $10
-; MIPS64R6-NEXT: nor $9, $zero, $8
-; MIPS64R6-NEXT: sllv $7, $1, $10
+; MIPS64R6-NEXT: and $5, $4, $2
+; MIPS64R6-NEXT: move $2, $4
+; MIPS64R6-NEXT: sll $2, $2, 0
+; MIPS64R6-NEXT: not $2, $2
+; MIPS64R6-NEXT: andi $2, $2, 3
+; MIPS64R6-NEXT: sll $2, $2, 3
+; MIPS64R6-NEXT: addiu $3, $zero, 255
+; MIPS64R6-NEXT: sllv $7, $3, $2
+; MIPS64R6-NEXT: sllv $6, $1, $2
+; MIPS64R6-NEXT: xori $8, $2, 24
; MIPS64R6-NEXT: .LBB9_1: # %entry
; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R6-NEXT: ll $2, 0($6)
-; MIPS64R6-NEXT: srav $4, $2, $10
-; MIPS64R6-NEXT: seb $4, $4
-; MIPS64R6-NEXT: or $1, $zero, $4
-; MIPS64R6-NEXT: sllv $4, $4, $10
-; MIPS64R6-NEXT: slt $5, $4, $7
-; MIPS64R6-NEXT: selnez $3, $4, $5
-; MIPS64R6-NEXT: seleqz $5, $7, $5
-; MIPS64R6-NEXT: or $3, $3, $5
-; MIPS64R6-NEXT: and $3, $3, $8
-; MIPS64R6-NEXT: and $4, $2, $9
-; MIPS64R6-NEXT: or $4, $4, $3
-; MIPS64R6-NEXT: sc $4, 0($6)
-; MIPS64R6-NEXT: beqzc $4, .LBB9_1
-; MIPS64R6-NEXT: nop
+; MIPS64R6-NEXT: ll $1, 0($5)
+; MIPS64R6-NEXT: and $3, $1, $7
+; MIPS64R6-NEXT: sllv $3, $3, $8
+; MIPS64R6-NEXT: srav $3, $3, $8
+; MIPS64R6-NEXT: slt $4, $6, $3
+; MIPS64R6-NEXT: seleqz $3, $3, $4
+; MIPS64R6-NEXT: selnez $4, $6, $4
+; MIPS64R6-NEXT: or $3, $3, $4
+; MIPS64R6-NEXT: xor $3, $1, $3
+; MIPS64R6-NEXT: and $3, $3, $7
+; MIPS64R6-NEXT: xor $3, $1, $3
+; MIPS64R6-NEXT: sc $3, 0($5)
+; MIPS64R6-NEXT: beqzc $3, .LBB9_1
; MIPS64R6-NEXT: # %bb.2: # %entry
-; MIPS64R6-NEXT: .insn
-; MIPS64R6-NEXT: # %bb.3: # %entry
-; MIPS64R6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64R6-NEXT: # %bb.4: # %entry
-; MIPS64R6-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64R6-NEXT: srlv $2, $1, $2
; MIPS64R6-NEXT: sync
-; MIPS64R6-NEXT: daddiu $sp, $sp, 16
; MIPS64R6-NEXT: jrc $ra
;
; MIPS64EL-LABEL: test_min_8:
; MIPS64EL: # %bb.0: # %entry
-; MIPS64EL-NEXT: daddiu $sp, $sp, -16
-; MIPS64EL-NEXT: .cfi_def_cfa_offset 16
; MIPS64EL-NEXT: move $1, $5
; MIPS64EL-NEXT: sync
; MIPS64EL-NEXT: daddiu $2, $zero, -4
-; MIPS64EL-NEXT: and $6, $4, $2
-; MIPS64EL-NEXT: andi $2, $4, 3
-; MIPS64EL-NEXT: sll $10, $2, 3
-; MIPS64EL-NEXT: ori $2, $zero, 255
-; MIPS64EL-NEXT: sllv $8, $2, $10
-; MIPS64EL-NEXT: nor $9, $zero, $8
-; MIPS64EL-NEXT: sllv $7, $1, $10
+; MIPS64EL-NEXT: and $5, $4, $2
+; MIPS64EL-NEXT: move $2, $4
+; MIPS64EL-NEXT: sll $2, $2, 0
+; MIPS64EL-NEXT: andi $2, $2, 3
+; MIPS64EL-NEXT: sll $2, $2, 3
+; MIPS64EL-NEXT: addiu $3, $zero, 255
+; MIPS64EL-NEXT: sllv $7, $3, $2
+; MIPS64EL-NEXT: sllv $6, $1, $2
+; MIPS64EL-NEXT: xori $8, $2, 24
; MIPS64EL-NEXT: .LBB9_1: # %entry
; MIPS64EL-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64EL-NEXT: ll $2, 0($6)
-; MIPS64EL-NEXT: srav $4, $2, $10
-; MIPS64EL-NEXT: seb $4, $4
-; MIPS64EL-NEXT: or $1, $zero, $4
-; MIPS64EL-NEXT: sllv $4, $4, $10
-; MIPS64EL-NEXT: slt $5, $4, $7
-; MIPS64EL-NEXT: move $3, $4
-; MIPS64EL-NEXT: movz $3, $7, $5
-; MIPS64EL-NEXT: and $3, $3, $8
-; MIPS64EL-NEXT: and $4, $2, $9
-; MIPS64EL-NEXT: or $4, $4, $3
-; MIPS64EL-NEXT: sc $4, 0($6)
-; MIPS64EL-NEXT: beqz $4, .LBB9_1
+; MIPS64EL-NEXT: ll $1, 0($5)
+; MIPS64EL-NEXT: and $3, $1, $7
+; MIPS64EL-NEXT: sllv $3, $3, $8
+; MIPS64EL-NEXT: srav $3, $3, $8
+; MIPS64EL-NEXT: slt $4, $6, $3
+; MIPS64EL-NEXT: movn $3, $6, $4
+; MIPS64EL-NEXT: xor $3, $1, $3
+; MIPS64EL-NEXT: and $3, $3, $7
+; MIPS64EL-NEXT: xor $3, $1, $3
+; MIPS64EL-NEXT: sc $3, 0($5)
+; MIPS64EL-NEXT: beqz $3, .LBB9_1
; MIPS64EL-NEXT: nop
; MIPS64EL-NEXT: # %bb.2: # %entry
-; MIPS64EL-NEXT: .insn
-; MIPS64EL-NEXT: # %bb.3: # %entry
-; MIPS64EL-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64EL-NEXT: # %bb.4: # %entry
-; MIPS64EL-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64EL-NEXT: srlv $2, $1, $2
; MIPS64EL-NEXT: sync
-; MIPS64EL-NEXT: daddiu $sp, $sp, 16
; MIPS64EL-NEXT: jr $ra
; MIPS64EL-NEXT: nop
;
; MIPS64ELR6-LABEL: test_min_8:
; MIPS64ELR6: # %bb.0: # %entry
-; MIPS64ELR6-NEXT: daddiu $sp, $sp, -16
-; MIPS64ELR6-NEXT: .cfi_def_cfa_offset 16
; MIPS64ELR6-NEXT: move $1, $5
; MIPS64ELR6-NEXT: sync
; MIPS64ELR6-NEXT: daddiu $2, $zero, -4
-; MIPS64ELR6-NEXT: and $6, $4, $2
-; MIPS64ELR6-NEXT: andi $2, $4, 3
-; MIPS64ELR6-NEXT: sll $10, $2, 3
-; MIPS64ELR6-NEXT: ori $2, $zero, 255
-; MIPS64ELR6-NEXT: sllv $8, $2, $10
-; MIPS64ELR6-NEXT: nor $9, $zero, $8
-; MIPS64ELR6-NEXT: sllv $7, $1, $10
+; MIPS64ELR6-NEXT: and $5, $4, $2
+; MIPS64ELR6-NEXT: move $2, $4
+; MIPS64ELR6-NEXT: sll $2, $2, 0
+; MIPS64ELR6-NEXT: andi $2, $2, 3
+; MIPS64ELR6-NEXT: sll $2, $2, 3
+; MIPS64ELR6-NEXT: addiu $3, $zero, 255
+; MIPS64ELR6-NEXT: sllv $7, $3, $2
+; MIPS64ELR6-NEXT: sllv $6, $1, $2
+; MIPS64ELR6-NEXT: xori $8, $2, 24
; MIPS64ELR6-NEXT: .LBB9_1: # %entry
; MIPS64ELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64ELR6-NEXT: ll $2, 0($6)
-; MIPS64ELR6-NEXT: srav $4, $2, $10
-; MIPS64ELR6-NEXT: seb $4, $4
-; MIPS64ELR6-NEXT: or $1, $zero, $4
-; MIPS64ELR6-NEXT: sllv $4, $4, $10
-; MIPS64ELR6-NEXT: slt $5, $4, $7
-; MIPS64ELR6-NEXT: selnez $3, $4, $5
-; MIPS64ELR6-NEXT: seleqz $5, $7, $5
-; MIPS64ELR6-NEXT: or $3, $3, $5
-; MIPS64ELR6-NEXT: and $3, $3, $8
-; MIPS64ELR6-NEXT: and $4, $2, $9
-; MIPS64ELR6-NEXT: or $4, $4, $3
-; MIPS64ELR6-NEXT: sc $4, 0($6)
-; MIPS64ELR6-NEXT: beqzc $4, .LBB9_1
-; MIPS64ELR6-NEXT: nop
+; MIPS64ELR6-NEXT: ll $1, 0($5)
+; MIPS64ELR6-NEXT: and $3, $1, $7
+; MIPS64ELR6-NEXT: sllv $3, $3, $8
+; MIPS64ELR6-NEXT: srav $3, $3, $8
+; MIPS64ELR6-NEXT: slt $4, $6, $3
+; MIPS64ELR6-NEXT: seleqz $3, $3, $4
+; MIPS64ELR6-NEXT: selnez $4, $6, $4
+; MIPS64ELR6-NEXT: or $3, $3, $4
+; MIPS64ELR6-NEXT: xor $3, $1, $3
+; MIPS64ELR6-NEXT: and $3, $3, $7
+; MIPS64ELR6-NEXT: xor $3, $1, $3
+; MIPS64ELR6-NEXT: sc $3, 0($5)
+; MIPS64ELR6-NEXT: beqzc $3, .LBB9_1
; MIPS64ELR6-NEXT: # %bb.2: # %entry
-; MIPS64ELR6-NEXT: .insn
-; MIPS64ELR6-NEXT: # %bb.3: # %entry
-; MIPS64ELR6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64ELR6-NEXT: # %bb.4: # %entry
-; MIPS64ELR6-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64ELR6-NEXT: srlv $2, $1, $2
; MIPS64ELR6-NEXT: sync
-; MIPS64ELR6-NEXT: daddiu $sp, $sp, 16
; MIPS64ELR6-NEXT: jrc $ra
entry:
%0 = atomicrmw min ptr %ptr, i8 %val seq_cst
@@ -4489,576 +3817,434 @@ entry:
define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) {
; MIPS-LABEL: test_umax_8:
; MIPS: # %bb.0: # %entry
-; MIPS-NEXT: addiu $sp, $sp, -8
-; MIPS-NEXT: .cfi_def_cfa_offset 8
+; MIPS-NEXT: move $1, $5
+; MIPS-NEXT: not $2, $4
; MIPS-NEXT: sync
-; MIPS-NEXT: addiu $1, $zero, -4
-; MIPS-NEXT: and $6, $4, $1
-; MIPS-NEXT: andi $1, $4, 3
-; MIPS-NEXT: xori $1, $1, 3
-; MIPS-NEXT: sll $10, $1, 3
-; MIPS-NEXT: ori $1, $zero, 255
-; MIPS-NEXT: sllv $8, $1, $10
-; MIPS-NEXT: nor $9, $zero, $8
-; MIPS-NEXT: sllv $7, $5, $10
+; MIPS-NEXT: addiu $3, $zero, -4
+; MIPS-NEXT: and $5, $4, $3
+; MIPS-NEXT: andi $2, $2, 3
+; MIPS-NEXT: sll $2, $2, 3
+; MIPS-NEXT: addiu $3, $zero, 255
+; MIPS-NEXT: sllv $7, $3, $2
+; MIPS-NEXT: andi $1, $1, 255
+; MIPS-NEXT: sllv $6, $1, $2
; MIPS-NEXT: $BB10_1: # %entry
; MIPS-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS-NEXT: ll $2, 0($6)
-; MIPS-NEXT: srav $4, $2, $10
-; MIPS-NEXT: andi $4, $4, 255
-; MIPS-NEXT: or $1, $zero, $4
-; MIPS-NEXT: sllv $4, $4, $10
-; MIPS-NEXT: sltu $5, $4, $7
-; MIPS-NEXT: move $3, $4
-; MIPS-NEXT: movn $3, $7, $5
-; MIPS-NEXT: and $3, $3, $8
-; MIPS-NEXT: and $4, $2, $9
-; MIPS-NEXT: or $4, $4, $3
-; MIPS-NEXT: sc $4, 0($6)
-; MIPS-NEXT: beqz $4, $BB10_1
+; MIPS-NEXT: ll $1, 0($5)
+; MIPS-NEXT: and $3, $1, $7
+; MIPS-NEXT: sltu $4, $3, $6
+; MIPS-NEXT: movn $3, $6, $4
+; MIPS-NEXT: xor $3, $1, $3
+; MIPS-NEXT: and $3, $3, $7
+; MIPS-NEXT: xor $3, $1, $3
+; MIPS-NEXT: sc $3, 0($5)
+; MIPS-NEXT: beqz $3, $BB10_1
; MIPS-NEXT: nop
; MIPS-NEXT: # %bb.2: # %entry
-; MIPS-NEXT: .insn
-; MIPS-NEXT: # %bb.3: # %entry
-; MIPS-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS-NEXT: # %bb.4: # %entry
-; MIPS-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPS-NEXT: srlv $2, $1, $2
; MIPS-NEXT: sync
-; MIPS-NEXT: addiu $sp, $sp, 8
; MIPS-NEXT: jr $ra
; MIPS-NEXT: nop
;
-; MIPS2-LABEL: test_umax_8:
-; MIPS2: # %bb.0: # %entry
-; MIPS2-NEXT: addiu $sp, $sp, -8
-; MIPS2-NEXT: .cfi_def_cfa_offset 8
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: addiu $1, $zero, -4
-; MIPS2-NEXT: and $6, $4, $1
-; MIPS2-NEXT: andi $1, $4, 3
-; MIPS2-NEXT: sll $10, $1, 3
-; MIPS2-NEXT: ori $1, $zero, 255
-; MIPS2-NEXT: sllv $8, $1, $10
-; MIPS2-NEXT: nor $9, $zero, $8
-; MIPS2-NEXT: sllv $7, $5, $10
-; MIPS2-NEXT: $BB10_1: # %entry
-; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS2-NEXT: ll $2, 0($6)
-; MIPS2-NEXT: srav $4, $2, $10
-; MIPS2-NEXT: andi $4, $4, 255
-; MIPS2-NEXT: or $1, $zero, $4
-; MIPS2-NEXT: sllv $4, $4, $10
-; MIPS2-NEXT: sltu $5, $4, $7
-; MIPS2-NEXT: move $3, $7
-; MIPS2-NEXT: beqz $5, $BB10_3
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.2: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB10_1 Depth=1
-; MIPS2-NEXT: j $BB10_4
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: $BB10_3: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB10_1 Depth=1
-; MIPS2-NEXT: move $3, $4
-; MIPS2-NEXT: $BB10_4: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB10_1 Depth=1
-; MIPS2-NEXT: and $3, $3, $8
-; MIPS2-NEXT: and $4, $2, $9
-; MIPS2-NEXT: or $4, $4, $3
-; MIPS2-NEXT: sc $4, 0($6)
-; MIPS2-NEXT: beqz $4, $BB10_1
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.5: # %entry
-; MIPS2-NEXT: .insn
-; MIPS2-NEXT: # %bb.6: # %entry
-; MIPS2-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS2-NEXT: # %bb.7: # %entry
-; MIPS2-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: addiu $sp, $sp, 8
-; MIPS2-NEXT: jr $ra
-; MIPS2-NEXT: nop
-;
; MIPSR6-LABEL: test_umax_8:
; MIPSR6: # %bb.0: # %entry
-; MIPSR6-NEXT: addiu $sp, $sp, -8
-; MIPSR6-NEXT: .cfi_def_cfa_offset 8
+; MIPSR6-NEXT: move $1, $5
+; MIPSR6-NEXT: not $2, $4
; MIPSR6-NEXT: sync
-; MIPSR6-NEXT: addiu $1, $zero, -4
-; MIPSR6-NEXT: and $6, $4, $1
-; MIPSR6-NEXT: andi $1, $4, 3
-; MIPSR6-NEXT: xori $1, $1, 3
-; MIPSR6-NEXT: sll $10, $1, 3
-; MIPSR6-NEXT: ori $1, $zero, 255
-; MIPSR6-NEXT: sllv $8, $1, $10
-; MIPSR6-NEXT: nor $9, $zero, $8
-; MIPSR6-NEXT: sllv $7, $5, $10
+; MIPSR6-NEXT: addiu $3, $zero, -4
+; MIPSR6-NEXT: and $5, $4, $3
+; MIPSR6-NEXT: andi $2, $2, 3
+; MIPSR6-NEXT: sll $2, $2, 3
+; MIPSR6-NEXT: addiu $3, $zero, 255
+; MIPSR6-NEXT: sllv $7, $3, $2
+; MIPSR6-NEXT: andi $1, $1, 255
+; MIPSR6-NEXT: sllv $6, $1, $2
; MIPSR6-NEXT: $BB10_1: # %entry
; MIPSR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSR6-NEXT: ll $2, 0($6)
-; MIPSR6-NEXT: srav $4, $2, $10
-; MIPSR6-NEXT: andi $4, $4, 255
-; MIPSR6-NEXT: or $1, $zero, $4
-; MIPSR6-NEXT: sllv $4, $4, $10
-; MIPSR6-NEXT: sltu $5, $4, $7
-; MIPSR6-NEXT: seleqz $3, $4, $5
-; MIPSR6-NEXT: selnez $5, $7, $5
-; MIPSR6-NEXT: or $3, $3, $5
-; MIPSR6-NEXT: and $3, $3, $8
-; MIPSR6-NEXT: and $4, $2, $9
-; MIPSR6-NEXT: or $4, $4, $3
-; MIPSR6-NEXT: sc $4, 0($6)
-; MIPSR6-NEXT: beqzc $4, $BB10_1
-; MIPSR6-NEXT: nop
+; MIPSR6-NEXT: ll $1, 0($5)
+; MIPSR6-NEXT: and $3, $1, $7
+; MIPSR6-NEXT: sltu $4, $3, $6
+; MIPSR6-NEXT: seleqz $3, $3, $4
+; MIPSR6-NEXT: selnez $4, $6, $4
+; MIPSR6-NEXT: or $3, $3, $4
+; MIPSR6-NEXT: xor $3, $1, $3
+; MIPSR6-NEXT: and $3, $3, $7
+; MIPSR6-NEXT: xor $3, $1, $3
+; MIPSR6-NEXT: sc $3, 0($5)
+; MIPSR6-NEXT: beqzc $3, $BB10_1
; MIPSR6-NEXT: # %bb.2: # %entry
-; MIPSR6-NEXT: .insn
-; MIPSR6-NEXT: # %bb.3: # %entry
-; MIPSR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSR6-NEXT: # %bb.4: # %entry
-; MIPSR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSR6-NEXT: srlv $2, $1, $2
; MIPSR6-NEXT: sync
-; MIPSR6-NEXT: addiu $sp, $sp, 8
; MIPSR6-NEXT: jrc $ra
;
; MM-LABEL: test_umax_8:
; MM: # %bb.0: # %entry
-; MM-NEXT: addiu $sp, $sp, -8
-; MM-NEXT: .cfi_def_cfa_offset 8
+; MM-NEXT: move $3, $5
+; MM-NEXT: not16 $2, $4
; MM-NEXT: sync
-; MM-NEXT: addiu $1, $zero, -4
-; MM-NEXT: and $6, $4, $1
-; MM-NEXT: andi $1, $4, 3
-; MM-NEXT: xori $1, $1, 3
-; MM-NEXT: sll $10, $1, 3
-; MM-NEXT: ori $1, $zero, 255
-; MM-NEXT: sllv $8, $1, $10
-; MM-NEXT: nor $9, $zero, $8
-; MM-NEXT: sllv $7, $5, $10
+; MM-NEXT: addiu $5, $zero, -4
+; MM-NEXT: and16 $5, $4
+; MM-NEXT: andi16 $2, $2, 3
+; MM-NEXT: sll16 $2, $2, 3
+; MM-NEXT: addiu $1, $zero, 255
+; MM-NEXT: sllv $7, $1, $2
+; MM-NEXT: andi16 $3, $3, 255
+; MM-NEXT: sllv $6, $3, $2
; MM-NEXT: $BB10_1: # %entry
; MM-NEXT: # =>This Inner Loop Header: Depth=1
-; MM-NEXT: ll $2, 0($6)
-; MM-NEXT: srav $4, $2, $10
-; MM-NEXT: andi $4, $4, 255
-; MM-NEXT: or $1, $zero, $4
-; MM-NEXT: sllv $4, $4, $10
-; MM-NEXT: sltu $5, $4, $7
-; MM-NEXT: or $3, $4, $zero
-; MM-NEXT: movn $3, $7, $5
-; MM-NEXT: and $3, $3, $8
-; MM-NEXT: and $4, $2, $9
-; MM-NEXT: or $4, $4, $3
-; MM-NEXT: sc $4, 0($6)
-; MM-NEXT: beqzc $4, $BB10_1
+; MM-NEXT: ll $1, 0($5)
+; MM-NEXT: and $3, $1, $7
+; MM-NEXT: sltu $4, $3, $6
+; MM-NEXT: movn $3, $6, $4
+; MM-NEXT: xor $3, $1, $3
+; MM-NEXT: and $3, $3, $7
+; MM-NEXT: xor $3, $1, $3
+; MM-NEXT: sc $3, 0($5)
+; MM-NEXT: beqzc $3, $BB10_1
; MM-NEXT: # %bb.2: # %entry
-; MM-NEXT: .insn
-; MM-NEXT: # %bb.3: # %entry
-; MM-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MM-NEXT: # %bb.4: # %entry
-; MM-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MM-NEXT: srlv $2, $1, $2
; MM-NEXT: sync
-; MM-NEXT: addiusp 8
; MM-NEXT: jrc $ra
;
; MMR6-LABEL: test_umax_8:
; MMR6: # %bb.0: # %entry
-; MMR6-NEXT: addiu $sp, $sp, -8
-; MMR6-NEXT: .cfi_def_cfa_offset 8
+; MMR6-NEXT: move $3, $5
+; MMR6-NEXT: not16 $2, $4
; MMR6-NEXT: sync
; MMR6-NEXT: addiu $1, $zero, -4
-; MMR6-NEXT: and $6, $4, $1
-; MMR6-NEXT: andi $1, $4, 3
-; MMR6-NEXT: xori $1, $1, 3
-; MMR6-NEXT: sll $10, $1, 3
-; MMR6-NEXT: ori $1, $zero, 255
-; MMR6-NEXT: sllv $8, $1, $10
-; MMR6-NEXT: nor $9, $zero, $8
-; MMR6-NEXT: sllv $7, $5, $10
+; MMR6-NEXT: and $5, $4, $1
+; MMR6-NEXT: andi16 $2, $2, 3
+; MMR6-NEXT: sll16 $2, $2, 3
+; MMR6-NEXT: addiu $1, $zero, 255
+; MMR6-NEXT: sllv $7, $1, $2
+; MMR6-NEXT: andi16 $3, $3, 255
+; MMR6-NEXT: sllv $6, $3, $2
; MMR6-NEXT: $BB10_1: # %entry
; MMR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MMR6-NEXT: ll $2, 0($6)
-; MMR6-NEXT: srav $4, $2, $10
-; MMR6-NEXT: andi $4, $4, 255
-; MMR6-NEXT: or $1, $zero, $4
-; MMR6-NEXT: sllv $4, $4, $10
-; MMR6-NEXT: sltu $5, $4, $7
-; MMR6-NEXT: seleqz $3, $4, $5
-; MMR6-NEXT: selnez $5, $7, $5
-; MMR6-NEXT: or $3, $3, $5
-; MMR6-NEXT: and $3, $3, $8
-; MMR6-NEXT: and $4, $2, $9
-; MMR6-NEXT: or $4, $4, $3
-; MMR6-NEXT: sc $4, 0($6)
-; MMR6-NEXT: beqc $4, $zero, $BB10_1
+; MMR6-NEXT: ll $1, 0($5)
+; MMR6-NEXT: and $3, $1, $7
+; MMR6-NEXT: sltu $4, $3, $6
+; MMR6-NEXT: seleqz $3, $3, $4
+; MMR6-NEXT: selnez $4, $6, $4
+; MMR6-NEXT: or $3, $3, $4
+; MMR6-NEXT: xor $3, $1, $3
+; MMR6-NEXT: and $3, $3, $7
+; MMR6-NEXT: xor $3, $1, $3
+; MMR6-NEXT: sc $3, 0($5)
+; MMR6-NEXT: beqc $3, $zero, $BB10_1
; MMR6-NEXT: # %bb.2: # %entry
-; MMR6-NEXT: .insn
-; MMR6-NEXT: # %bb.3: # %entry
-; MMR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMR6-NEXT: # %bb.4: # %entry
-; MMR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMR6-NEXT: srlv $2, $1, $2
; MMR6-NEXT: sync
-; MMR6-NEXT: addiu $sp, $sp, 8
; MMR6-NEXT: jrc $ra
;
+; MIPS2-LABEL: test_umax_8:
+; MIPS2: # %bb.0: # %entry
+; MIPS2-NEXT: move $1, $5
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: addiu $2, $zero, -4
+; MIPS2-NEXT: and $5, $4, $2
+; MIPS2-NEXT: sll $2, $4, 3
+; MIPS2-NEXT: addiu $3, $zero, 255
+; MIPS2-NEXT: sllv $7, $3, $2
+; MIPS2-NEXT: andi $1, $1, 255
+; MIPS2-NEXT: sllv $6, $1, $2
+; MIPS2-NEXT: $BB10_1: # %entry
+; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
+; MIPS2-NEXT: ll $1, 0($5)
+; MIPS2-NEXT: and $3, $1, $7
+; MIPS2-NEXT: sltu $4, $3, $6
+; MIPS2-NEXT: beqz $4, $BB10_3
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.2: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB10_1 Depth=1
+; MIPS2-NEXT: move $3, $6
+; MIPS2-NEXT: $BB10_3: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB10_1 Depth=1
+; MIPS2-NEXT: xor $3, $1, $3
+; MIPS2-NEXT: and $3, $3, $7
+; MIPS2-NEXT: xor $3, $1, $3
+; MIPS2-NEXT: sc $3, 0($5)
+; MIPS2-NEXT: beqz $3, $BB10_1
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.4: # %entry
+; MIPS2-NEXT: srlv $2, $1, $2
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: jr $ra
+; MIPS2-NEXT: nop
+;
; MIPS32-LABEL: test_umax_8:
; MIPS32: # %bb.0: # %entry
-; MIPS32-NEXT: addiu $sp, $sp, -8
-; MIPS32-NEXT: .cfi_def_cfa_offset 8
+; MIPS32-NEXT: move $1, $5
; MIPS32-NEXT: sync
-; MIPS32-NEXT: addiu $1, $zero, -4
-; MIPS32-NEXT: and $6, $4, $1
-; MIPS32-NEXT: andi $1, $4, 3
-; MIPS32-NEXT: sll $10, $1, 3
-; MIPS32-NEXT: ori $1, $zero, 255
-; MIPS32-NEXT: sllv $8, $1, $10
-; MIPS32-NEXT: nor $9, $zero, $8
-; MIPS32-NEXT: sllv $7, $5, $10
+; MIPS32-NEXT: addiu $2, $zero, -4
+; MIPS32-NEXT: and $5, $4, $2
+; MIPS32-NEXT: sll $2, $4, 3
+; MIPS32-NEXT: addiu $3, $zero, 255
+; MIPS32-NEXT: sllv $7, $3, $2
+; MIPS32-NEXT: andi $1, $1, 255
+; MIPS32-NEXT: sllv $6, $1, $2
; MIPS32-NEXT: $BB10_1: # %entry
; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32-NEXT: ll $2, 0($6)
-; MIPS32-NEXT: srav $4, $2, $10
-; MIPS32-NEXT: andi $4, $4, 255
-; MIPS32-NEXT: or $1, $zero, $4
-; MIPS32-NEXT: sllv $4, $4, $10
-; MIPS32-NEXT: sltu $5, $4, $7
-; MIPS32-NEXT: move $3, $4
-; MIPS32-NEXT: movn $3, $7, $5
-; MIPS32-NEXT: and $3, $3, $8
-; MIPS32-NEXT: and $4, $2, $9
-; MIPS32-NEXT: or $4, $4, $3
-; MIPS32-NEXT: sc $4, 0($6)
-; MIPS32-NEXT: beqz $4, $BB10_1
+; MIPS32-NEXT: ll $1, 0($5)
+; MIPS32-NEXT: and $3, $1, $7
+; MIPS32-NEXT: sltu $4, $3, $6
+; MIPS32-NEXT: movn $3, $6, $4
+; MIPS32-NEXT: xor $3, $1, $3
+; MIPS32-NEXT: and $3, $3, $7
+; MIPS32-NEXT: xor $3, $1, $3
+; MIPS32-NEXT: sc $3, 0($5)
+; MIPS32-NEXT: beqz $3, $BB10_1
; MIPS32-NEXT: nop
; MIPS32-NEXT: # %bb.2: # %entry
-; MIPS32-NEXT: .insn
-; MIPS32-NEXT: # %bb.3: # %entry
-; MIPS32-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32-NEXT: # %bb.4: # %entry
-; MIPS32-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPS32-NEXT: srlv $2, $1, $2
; MIPS32-NEXT: sync
-; MIPS32-NEXT: addiu $sp, $sp, 8
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPSEL-LABEL: test_umax_8:
; MIPSEL: # %bb.0: # %entry
-; MIPSEL-NEXT: addiu $sp, $sp, -8
-; MIPSEL-NEXT: .cfi_def_cfa_offset 8
+; MIPSEL-NEXT: move $1, $5
; MIPSEL-NEXT: sync
-; MIPSEL-NEXT: addiu $1, $zero, -4
-; MIPSEL-NEXT: and $6, $4, $1
-; MIPSEL-NEXT: andi $1, $4, 3
-; MIPSEL-NEXT: sll $10, $1, 3
-; MIPSEL-NEXT: ori $1, $zero, 255
-; MIPSEL-NEXT: sllv $8, $1, $10
-; MIPSEL-NEXT: nor $9, $zero, $8
-; MIPSEL-NEXT: sllv $7, $5, $10
+; MIPSEL-NEXT: addiu $2, $zero, -4
+; MIPSEL-NEXT: and $5, $4, $2
+; MIPSEL-NEXT: sll $2, $4, 3
+; MIPSEL-NEXT: addiu $3, $zero, 255
+; MIPSEL-NEXT: sllv $7, $3, $2
+; MIPSEL-NEXT: andi $1, $1, 255
+; MIPSEL-NEXT: sllv $6, $1, $2
; MIPSEL-NEXT: $BB10_1: # %entry
; MIPSEL-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSEL-NEXT: ll $2, 0($6)
-; MIPSEL-NEXT: srav $4, $2, $10
-; MIPSEL-NEXT: andi $4, $4, 255
-; MIPSEL-NEXT: or $1, $zero, $4
-; MIPSEL-NEXT: sllv $4, $4, $10
-; MIPSEL-NEXT: sltu $5, $4, $7
-; MIPSEL-NEXT: move $3, $4
-; MIPSEL-NEXT: movn $3, $7, $5
-; MIPSEL-NEXT: and $3, $3, $8
-; MIPSEL-NEXT: and $4, $2, $9
-; MIPSEL-NEXT: or $4, $4, $3
-; MIPSEL-NEXT: sc $4, 0($6)
-; MIPSEL-NEXT: beqz $4, $BB10_1
+; MIPSEL-NEXT: ll $1, 0($5)
+; MIPSEL-NEXT: and $3, $1, $7
+; MIPSEL-NEXT: sltu $4, $3, $6
+; MIPSEL-NEXT: movn $3, $6, $4
+; MIPSEL-NEXT: xor $3, $1, $3
+; MIPSEL-NEXT: and $3, $3, $7
+; MIPSEL-NEXT: xor $3, $1, $3
+; MIPSEL-NEXT: sc $3, 0($5)
+; MIPSEL-NEXT: beqz $3, $BB10_1
; MIPSEL-NEXT: nop
; MIPSEL-NEXT: # %bb.2: # %entry
-; MIPSEL-NEXT: .insn
-; MIPSEL-NEXT: # %bb.3: # %entry
-; MIPSEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSEL-NEXT: # %bb.4: # %entry
-; MIPSEL-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSEL-NEXT: srlv $2, $1, $2
; MIPSEL-NEXT: sync
-; MIPSEL-NEXT: addiu $sp, $sp, 8
; MIPSEL-NEXT: jr $ra
; MIPSEL-NEXT: nop
;
; MIPSELR6-LABEL: test_umax_8:
; MIPSELR6: # %bb.0: # %entry
-; MIPSELR6-NEXT: addiu $sp, $sp, -8
-; MIPSELR6-NEXT: .cfi_def_cfa_offset 8
+; MIPSELR6-NEXT: move $1, $5
; MIPSELR6-NEXT: sync
-; MIPSELR6-NEXT: addiu $1, $zero, -4
-; MIPSELR6-NEXT: and $6, $4, $1
-; MIPSELR6-NEXT: andi $1, $4, 3
-; MIPSELR6-NEXT: sll $10, $1, 3
-; MIPSELR6-NEXT: ori $1, $zero, 255
-; MIPSELR6-NEXT: sllv $8, $1, $10
-; MIPSELR6-NEXT: nor $9, $zero, $8
-; MIPSELR6-NEXT: sllv $7, $5, $10
+; MIPSELR6-NEXT: addiu $2, $zero, -4
+; MIPSELR6-NEXT: and $5, $4, $2
+; MIPSELR6-NEXT: sll $2, $4, 3
+; MIPSELR6-NEXT: addiu $3, $zero, 255
+; MIPSELR6-NEXT: sllv $7, $3, $2
+; MIPSELR6-NEXT: andi $1, $1, 255
+; MIPSELR6-NEXT: sllv $6, $1, $2
; MIPSELR6-NEXT: $BB10_1: # %entry
; MIPSELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSELR6-NEXT: ll $2, 0($6)
-; MIPSELR6-NEXT: srav $4, $2, $10
-; MIPSELR6-NEXT: andi $4, $4, 255
-; MIPSELR6-NEXT: or $1, $zero, $4
-; MIPSELR6-NEXT: sllv $4, $4, $10
-; MIPSELR6-NEXT: sltu $5, $4, $7
-; MIPSELR6-NEXT: seleqz $3, $4, $5
-; MIPSELR6-NEXT: selnez $5, $7, $5
-; MIPSELR6-NEXT: or $3, $3, $5
-; MIPSELR6-NEXT: and $3, $3, $8
-; MIPSELR6-NEXT: and $4, $2, $9
-; MIPSELR6-NEXT: or $4, $4, $3
-; MIPSELR6-NEXT: sc $4, 0($6)
-; MIPSELR6-NEXT: beqzc $4, $BB10_1
-; MIPSELR6-NEXT: nop
+; MIPSELR6-NEXT: ll $1, 0($5)
+; MIPSELR6-NEXT: and $3, $1, $7
+; MIPSELR6-NEXT: sltu $4, $3, $6
+; MIPSELR6-NEXT: seleqz $3, $3, $4
+; MIPSELR6-NEXT: selnez $4, $6, $4
+; MIPSELR6-NEXT: or $3, $3, $4
+; MIPSELR6-NEXT: xor $3, $1, $3
+; MIPSELR6-NEXT: and $3, $3, $7
+; MIPSELR6-NEXT: xor $3, $1, $3
+; MIPSELR6-NEXT: sc $3, 0($5)
+; MIPSELR6-NEXT: beqzc $3, $BB10_1
; MIPSELR6-NEXT: # %bb.2: # %entry
-; MIPSELR6-NEXT: .insn
-; MIPSELR6-NEXT: # %bb.3: # %entry
-; MIPSELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSELR6-NEXT: # %bb.4: # %entry
-; MIPSELR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSELR6-NEXT: srlv $2, $1, $2
; MIPSELR6-NEXT: sync
-; MIPSELR6-NEXT: addiu $sp, $sp, 8
; MIPSELR6-NEXT: jrc $ra
;
; MMEL-LABEL: test_umax_8:
; MMEL: # %bb.0: # %entry
-; MMEL-NEXT: addiu $sp, $sp, -8
-; MMEL-NEXT: .cfi_def_cfa_offset 8
+; MMEL-NEXT: move $3, $5
; MMEL-NEXT: sync
-; MMEL-NEXT: addiu $1, $zero, -4
-; MMEL-NEXT: and $6, $4, $1
-; MMEL-NEXT: andi $1, $4, 3
-; MMEL-NEXT: sll $10, $1, 3
-; MMEL-NEXT: ori $1, $zero, 255
-; MMEL-NEXT: sllv $8, $1, $10
-; MMEL-NEXT: nor $9, $zero, $8
-; MMEL-NEXT: sllv $7, $5, $10
+; MMEL-NEXT: addiu $5, $zero, -4
+; MMEL-NEXT: and16 $5, $4
+; MMEL-NEXT: sll16 $2, $4, 3
+; MMEL-NEXT: andi $2, $2, 24
+; MMEL-NEXT: addiu $1, $zero, 255
+; MMEL-NEXT: sllv $7, $1, $2
+; MMEL-NEXT: andi16 $3, $3, 255
+; MMEL-NEXT: sllv $6, $3, $2
; MMEL-NEXT: $BB10_1: # %entry
; MMEL-NEXT: # =>This Inner Loop Header: Depth=1
-; MMEL-NEXT: ll $2, 0($6)
-; MMEL-NEXT: srav $4, $2, $10
-; MMEL-NEXT: andi $4, $4, 255
-; MMEL-NEXT: or $1, $zero, $4
-; MMEL-NEXT: sllv $4, $4, $10
-; MMEL-NEXT: sltu $5, $4, $7
-; MMEL-NEXT: or $3, $4, $zero
-; MMEL-NEXT: movn $3, $7, $5
-; MMEL-NEXT: and $3, $3, $8
-; MMEL-NEXT: and $4, $2, $9
-; MMEL-NEXT: or $4, $4, $3
-; MMEL-NEXT: sc $4, 0($6)
-; MMEL-NEXT: beqzc $4, $BB10_1
+; MMEL-NEXT: ll $1, 0($5)
+; MMEL-NEXT: and $3, $1, $7
+; MMEL-NEXT: sltu $4, $3, $6
+; MMEL-NEXT: movn $3, $6, $4
+; MMEL-NEXT: xor $3, $1, $3
+; MMEL-NEXT: and $3, $3, $7
+; MMEL-NEXT: xor $3, $1, $3
+; MMEL-NEXT: sc $3, 0($5)
+; MMEL-NEXT: beqzc $3, $BB10_1
; MMEL-NEXT: # %bb.2: # %entry
-; MMEL-NEXT: .insn
-; MMEL-NEXT: # %bb.3: # %entry
-; MMEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMEL-NEXT: # %bb.4: # %entry
-; MMEL-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMEL-NEXT: srlv $2, $1, $2
; MMEL-NEXT: sync
-; MMEL-NEXT: addiusp 8
; MMEL-NEXT: jrc $ra
;
; MMELR6-LABEL: test_umax_8:
; MMELR6: # %bb.0: # %entry
-; MMELR6-NEXT: addiu $sp, $sp, -8
-; MMELR6-NEXT: .cfi_def_cfa_offset 8
+; MMELR6-NEXT: move $3, $5
; MMELR6-NEXT: sync
; MMELR6-NEXT: addiu $1, $zero, -4
-; MMELR6-NEXT: and $6, $4, $1
-; MMELR6-NEXT: andi $1, $4, 3
-; MMELR6-NEXT: sll $10, $1, 3
-; MMELR6-NEXT: ori $1, $zero, 255
-; MMELR6-NEXT: sllv $8, $1, $10
-; MMELR6-NEXT: nor $9, $zero, $8
-; MMELR6-NEXT: sllv $7, $5, $10
+; MMELR6-NEXT: and $5, $4, $1
+; MMELR6-NEXT: sll16 $2, $4, 3
+; MMELR6-NEXT: andi $2, $2, 24
+; MMELR6-NEXT: addiu $1, $zero, 255
+; MMELR6-NEXT: sllv $7, $1, $2
+; MMELR6-NEXT: andi16 $3, $3, 255
+; MMELR6-NEXT: sllv $6, $3, $2
; MMELR6-NEXT: $BB10_1: # %entry
; MMELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MMELR6-NEXT: ll $2, 0($6)
-; MMELR6-NEXT: srav $4, $2, $10
-; MMELR6-NEXT: andi $4, $4, 255
-; MMELR6-NEXT: or $1, $zero, $4
-; MMELR6-NEXT: sllv $4, $4, $10
-; MMELR6-NEXT: sltu $5, $4, $7
-; MMELR6-NEXT: seleqz $3, $4, $5
-; MMELR6-NEXT: selnez $5, $7, $5
-; MMELR6-NEXT: or $3, $3, $5
-; MMELR6-NEXT: and $3, $3, $8
-; MMELR6-NEXT: and $4, $2, $9
-; MMELR6-NEXT: or $4, $4, $3
-; MMELR6-NEXT: sc $4, 0($6)
-; MMELR6-NEXT: beqc $4, $zero, $BB10_1
+; MMELR6-NEXT: ll $1, 0($5)
+; MMELR6-NEXT: and $3, $1, $7
+; MMELR6-NEXT: sltu $4, $3, $6
+; MMELR6-NEXT: seleqz $3, $3, $4
+; MMELR6-NEXT: selnez $4, $6, $4
+; MMELR6-NEXT: or $3, $3, $4
+; MMELR6-NEXT: xor $3, $1, $3
+; MMELR6-NEXT: and $3, $3, $7
+; MMELR6-NEXT: xor $3, $1, $3
+; MMELR6-NEXT: sc $3, 0($5)
+; MMELR6-NEXT: beqc $3, $zero, $BB10_1
; MMELR6-NEXT: # %bb.2: # %entry
-; MMELR6-NEXT: .insn
-; MMELR6-NEXT: # %bb.3: # %entry
-; MMELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMELR6-NEXT: # %bb.4: # %entry
-; MMELR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMELR6-NEXT: srlv $2, $1, $2
; MMELR6-NEXT: sync
-; MMELR6-NEXT: addiu $sp, $sp, 8
; MMELR6-NEXT: jrc $ra
;
; MIPS64-LABEL: test_umax_8:
; MIPS64: # %bb.0: # %entry
-; MIPS64-NEXT: daddiu $sp, $sp, -16
-; MIPS64-NEXT: .cfi_def_cfa_offset 16
; MIPS64-NEXT: move $1, $5
; MIPS64-NEXT: sync
; MIPS64-NEXT: daddiu $2, $zero, -4
-; MIPS64-NEXT: and $6, $4, $2
-; MIPS64-NEXT: andi $2, $4, 3
-; MIPS64-NEXT: xori $2, $2, 3
-; MIPS64-NEXT: sll $10, $2, 3
-; MIPS64-NEXT: ori $2, $zero, 255
-; MIPS64-NEXT: sllv $8, $2, $10
-; MIPS64-NEXT: nor $9, $zero, $8
-; MIPS64-NEXT: sllv $7, $1, $10
+; MIPS64-NEXT: and $5, $4, $2
+; MIPS64-NEXT: move $2, $4
+; MIPS64-NEXT: sll $2, $2, 0
+; MIPS64-NEXT: not $2, $2
+; MIPS64-NEXT: andi $2, $2, 3
+; MIPS64-NEXT: sll $2, $2, 3
+; MIPS64-NEXT: addiu $3, $zero, 255
+; MIPS64-NEXT: sllv $7, $3, $2
+; MIPS64-NEXT: andi $1, $1, 255
+; MIPS64-NEXT: sllv $6, $1, $2
; MIPS64-NEXT: .LBB10_1: # %entry
; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64-NEXT: ll $2, 0($6)
-; MIPS64-NEXT: srav $4, $2, $10
-; MIPS64-NEXT: andi $4, $4, 255
-; MIPS64-NEXT: or $1, $zero, $4
-; MIPS64-NEXT: sllv $4, $4, $10
-; MIPS64-NEXT: sltu $5, $4, $7
-; MIPS64-NEXT: move $3, $4
-; MIPS64-NEXT: movn $3, $7, $5
-; MIPS64-NEXT: and $3, $3, $8
-; MIPS64-NEXT: and $4, $2, $9
-; MIPS64-NEXT: or $4, $4, $3
-; MIPS64-NEXT: sc $4, 0($6)
-; MIPS64-NEXT: beqz $4, .LBB10_1
+; MIPS64-NEXT: ll $1, 0($5)
+; MIPS64-NEXT: and $3, $1, $7
+; MIPS64-NEXT: sltu $4, $3, $6
+; MIPS64-NEXT: movn $3, $6, $4
+; MIPS64-NEXT: xor $3, $1, $3
+; MIPS64-NEXT: and $3, $3, $7
+; MIPS64-NEXT: xor $3, $1, $3
+; MIPS64-NEXT: sc $3, 0($5)
+; MIPS64-NEXT: beqz $3, .LBB10_1
; MIPS64-NEXT: nop
; MIPS64-NEXT: # %bb.2: # %entry
-; MIPS64-NEXT: .insn
-; MIPS64-NEXT: # %bb.3: # %entry
-; MIPS64-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64-NEXT: # %bb.4: # %entry
-; MIPS64-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64-NEXT: srlv $2, $1, $2
; MIPS64-NEXT: sync
-; MIPS64-NEXT: daddiu $sp, $sp, 16
; MIPS64-NEXT: jr $ra
; MIPS64-NEXT: nop
;
; MIPS64R6-LABEL: test_umax_8:
; MIPS64R6: # %bb.0: # %entry
-; MIPS64R6-NEXT: daddiu $sp, $sp, -16
-; MIPS64R6-NEXT: .cfi_def_cfa_offset 16
; MIPS64R6-NEXT: move $1, $5
; MIPS64R6-NEXT: sync
; MIPS64R6-NEXT: daddiu $2, $zero, -4
-; MIPS64R6-NEXT: and $6, $4, $2
-; MIPS64R6-NEXT: andi $2, $4, 3
-; MIPS64R6-NEXT: xori $2, $2, 3
-; MIPS64R6-NEXT: sll $10, $2, 3
-; MIPS64R6-NEXT: ori $2, $zero, 255
-; MIPS64R6-NEXT: sllv $8, $2, $10
-; MIPS64R6-NEXT: nor $9, $zero, $8
-; MIPS64R6-NEXT: sllv $7, $1, $10
+; MIPS64R6-NEXT: and $5, $4, $2
+; MIPS64R6-NEXT: move $2, $4
+; MIPS64R6-NEXT: sll $2, $2, 0
+; MIPS64R6-NEXT: not $2, $2
+; MIPS64R6-NEXT: andi $2, $2, 3
+; MIPS64R6-NEXT: sll $2, $2, 3
+; MIPS64R6-NEXT: addiu $3, $zero, 255
+; MIPS64R6-NEXT: sllv $7, $3, $2
+; MIPS64R6-NEXT: andi $1, $1, 255
+; MIPS64R6-NEXT: sllv $6, $1, $2
; MIPS64R6-NEXT: .LBB10_1: # %entry
; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R6-NEXT: ll $2, 0($6)
-; MIPS64R6-NEXT: srav $4, $2, $10
-; MIPS64R6-NEXT: andi $4, $4, 255
-; MIPS64R6-NEXT: or $1, $zero, $4
-; MIPS64R6-NEXT: sllv $4, $4, $10
-; MIPS64R6-NEXT: sltu $5, $4, $7
-; MIPS64R6-NEXT: seleqz $3, $4, $5
-; MIPS64R6-NEXT: selnez $5, $7, $5
-; MIPS64R6-NEXT: or $3, $3, $5
-; MIPS64R6-NEXT: and $3, $3, $8
-; MIPS64R6-NEXT: and $4, $2, $9
-; MIPS64R6-NEXT: or $4, $4, $3
-; MIPS64R6-NEXT: sc $4, 0($6)
-; MIPS64R6-NEXT: beqzc $4, .LBB10_1
-; MIPS64R6-NEXT: nop
+; MIPS64R6-NEXT: ll $1, 0($5)
+; MIPS64R6-NEXT: and $3, $1, $7
+; MIPS64R6-NEXT: sltu $4, $3, $6
+; MIPS64R6-NEXT: seleqz $3, $3, $4
+; MIPS64R6-NEXT: selnez $4, $6, $4
+; MIPS64R6-NEXT: or $3, $3, $4
+; MIPS64R6-NEXT: xor $3, $1, $3
+; MIPS64R6-NEXT: and $3, $3, $7
+; MIPS64R6-NEXT: xor $3, $1, $3
+; MIPS64R6-NEXT: sc $3, 0($5)
+; MIPS64R6-NEXT: beqzc $3, .LBB10_1
; MIPS64R6-NEXT: # %bb.2: # %entry
-; MIPS64R6-NEXT: .insn
-; MIPS64R6-NEXT: # %bb.3: # %entry
-; MIPS64R6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64R6-NEXT: # %bb.4: # %entry
-; MIPS64R6-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64R6-NEXT: srlv $2, $1, $2
; MIPS64R6-NEXT: sync
-; MIPS64R6-NEXT: daddiu $sp, $sp, 16
; MIPS64R6-NEXT: jrc $ra
;
; MIPS64EL-LABEL: test_umax_8:
; MIPS64EL: # %bb.0: # %entry
-; MIPS64EL-NEXT: daddiu $sp, $sp, -16
-; MIPS64EL-NEXT: .cfi_def_cfa_offset 16
; MIPS64EL-NEXT: move $1, $5
; MIPS64EL-NEXT: sync
; MIPS64EL-NEXT: daddiu $2, $zero, -4
-; MIPS64EL-NEXT: and $6, $4, $2
-; MIPS64EL-NEXT: andi $2, $4, 3
-; MIPS64EL-NEXT: sll $10, $2, 3
-; MIPS64EL-NEXT: ori $2, $zero, 255
-; MIPS64EL-NEXT: sllv $8, $2, $10
-; MIPS64EL-NEXT: nor $9, $zero, $8
-; MIPS64EL-NEXT: sllv $7, $1, $10
+; MIPS64EL-NEXT: and $5, $4, $2
+; MIPS64EL-NEXT: move $2, $4
+; MIPS64EL-NEXT: sll $2, $2, 0
+; MIPS64EL-NEXT: andi $2, $2, 3
+; MIPS64EL-NEXT: sll $2, $2, 3
+; MIPS64EL-NEXT: addiu $3, $zero, 255
+; MIPS64EL-NEXT: sllv $7, $3, $2
+; MIPS64EL-NEXT: andi $1, $1, 255
+; MIPS64EL-NEXT: sllv $6, $1, $2
; MIPS64EL-NEXT: .LBB10_1: # %entry
; MIPS64EL-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64EL-NEXT: ll $2, 0($6)
-; MIPS64EL-NEXT: srav $4, $2, $10
-; MIPS64EL-NEXT: andi $4, $4, 255
-; MIPS64EL-NEXT: or $1, $zero, $4
-; MIPS64EL-NEXT: sllv $4, $4, $10
-; MIPS64EL-NEXT: sltu $5, $4, $7
-; MIPS64EL-NEXT: move $3, $4
-; MIPS64EL-NEXT: movn $3, $7, $5
-; MIPS64EL-NEXT: and $3, $3, $8
-; MIPS64EL-NEXT: and $4, $2, $9
-; MIPS64EL-NEXT: or $4, $4, $3
-; MIPS64EL-NEXT: sc $4, 0($6)
-; MIPS64EL-NEXT: beqz $4, .LBB10_1
+; MIPS64EL-NEXT: ll $1, 0($5)
+; MIPS64EL-NEXT: and $3, $1, $7
+; MIPS64EL-NEXT: sltu $4, $3, $6
+; MIPS64EL-NEXT: movn $3, $6, $4
+; MIPS64EL-NEXT: xor $3, $1, $3
+; MIPS64EL-NEXT: and $3, $3, $7
+; MIPS64EL-NEXT: xor $3, $1, $3
+; MIPS64EL-NEXT: sc $3, 0($5)
+; MIPS64EL-NEXT: beqz $3, .LBB10_1
; MIPS64EL-NEXT: nop
; MIPS64EL-NEXT: # %bb.2: # %entry
-; MIPS64EL-NEXT: .insn
-; MIPS64EL-NEXT: # %bb.3: # %entry
-; MIPS64EL-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64EL-NEXT: # %bb.4: # %entry
-; MIPS64EL-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64EL-NEXT: srlv $2, $1, $2
; MIPS64EL-NEXT: sync
-; MIPS64EL-NEXT: daddiu $sp, $sp, 16
; MIPS64EL-NEXT: jr $ra
; MIPS64EL-NEXT: nop
;
; MIPS64ELR6-LABEL: test_umax_8:
; MIPS64ELR6: # %bb.0: # %entry
-; MIPS64ELR6-NEXT: daddiu $sp, $sp, -16
-; MIPS64ELR6-NEXT: .cfi_def_cfa_offset 16
; MIPS64ELR6-NEXT: move $1, $5
; MIPS64ELR6-NEXT: sync
; MIPS64ELR6-NEXT: daddiu $2, $zero, -4
-; MIPS64ELR6-NEXT: and $6, $4, $2
-; MIPS64ELR6-NEXT: andi $2, $4, 3
-; MIPS64ELR6-NEXT: sll $10, $2, 3
-; MIPS64ELR6-NEXT: ori $2, $zero, 255
-; MIPS64ELR6-NEXT: sllv $8, $2, $10
-; MIPS64ELR6-NEXT: nor $9, $zero, $8
-; MIPS64ELR6-NEXT: sllv $7, $1, $10
+; MIPS64ELR6-NEXT: and $5, $4, $2
+; MIPS64ELR6-NEXT: move $2, $4
+; MIPS64ELR6-NEXT: sll $2, $2, 0
+; MIPS64ELR6-NEXT: andi $2, $2, 3
+; MIPS64ELR6-NEXT: sll $2, $2, 3
+; MIPS64ELR6-NEXT: addiu $3, $zero, 255
+; MIPS64ELR6-NEXT: sllv $7, $3, $2
+; MIPS64ELR6-NEXT: andi $1, $1, 255
+; MIPS64ELR6-NEXT: sllv $6, $1, $2
; MIPS64ELR6-NEXT: .LBB10_1: # %entry
; MIPS64ELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64ELR6-NEXT: ll $2, 0($6)
-; MIPS64ELR6-NEXT: srav $4, $2, $10
-; MIPS64ELR6-NEXT: andi $4, $4, 255
-; MIPS64ELR6-NEXT: or $1, $zero, $4
-; MIPS64ELR6-NEXT: sllv $4, $4, $10
-; MIPS64ELR6-NEXT: sltu $5, $4, $7
-; MIPS64ELR6-NEXT: seleqz $3, $4, $5
-; MIPS64ELR6-NEXT: selnez $5, $7, $5
-; MIPS64ELR6-NEXT: or $3, $3, $5
-; MIPS64ELR6-NEXT: and $3, $3, $8
-; MIPS64ELR6-NEXT: and $4, $2, $9
-; MIPS64ELR6-NEXT: or $4, $4, $3
-; MIPS64ELR6-NEXT: sc $4, 0($6)
-; MIPS64ELR6-NEXT: beqzc $4, .LBB10_1
-; MIPS64ELR6-NEXT: nop
+; MIPS64ELR6-NEXT: ll $1, 0($5)
+; MIPS64ELR6-NEXT: and $3, $1, $7
+; MIPS64ELR6-NEXT: sltu $4, $3, $6
+; MIPS64ELR6-NEXT: seleqz $3, $3, $4
+; MIPS64ELR6-NEXT: selnez $4, $6, $4
+; MIPS64ELR6-NEXT: or $3, $3, $4
+; MIPS64ELR6-NEXT: xor $3, $1, $3
+; MIPS64ELR6-NEXT: and $3, $3, $7
+; MIPS64ELR6-NEXT: xor $3, $1, $3
+; MIPS64ELR6-NEXT: sc $3, 0($5)
+; MIPS64ELR6-NEXT: beqzc $3, .LBB10_1
; MIPS64ELR6-NEXT: # %bb.2: # %entry
-; MIPS64ELR6-NEXT: .insn
-; MIPS64ELR6-NEXT: # %bb.3: # %entry
-; MIPS64ELR6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64ELR6-NEXT: # %bb.4: # %entry
-; MIPS64ELR6-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64ELR6-NEXT: srlv $2, $1, $2
; MIPS64ELR6-NEXT: sync
-; MIPS64ELR6-NEXT: daddiu $sp, $sp, 16
; MIPS64ELR6-NEXT: jrc $ra
entry:
%0 = atomicrmw umax ptr %ptr, i8 %val seq_cst
@@ -5068,576 +4254,434 @@ entry:
define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) {
; MIPS-LABEL: test_umin_8:
; MIPS: # %bb.0: # %entry
-; MIPS-NEXT: addiu $sp, $sp, -8
-; MIPS-NEXT: .cfi_def_cfa_offset 8
+; MIPS-NEXT: move $1, $5
+; MIPS-NEXT: not $2, $4
; MIPS-NEXT: sync
-; MIPS-NEXT: addiu $1, $zero, -4
-; MIPS-NEXT: and $6, $4, $1
-; MIPS-NEXT: andi $1, $4, 3
-; MIPS-NEXT: xori $1, $1, 3
-; MIPS-NEXT: sll $10, $1, 3
-; MIPS-NEXT: ori $1, $zero, 255
-; MIPS-NEXT: sllv $8, $1, $10
-; MIPS-NEXT: nor $9, $zero, $8
-; MIPS-NEXT: sllv $7, $5, $10
+; MIPS-NEXT: addiu $3, $zero, -4
+; MIPS-NEXT: and $5, $4, $3
+; MIPS-NEXT: andi $2, $2, 3
+; MIPS-NEXT: sll $2, $2, 3
+; MIPS-NEXT: addiu $3, $zero, 255
+; MIPS-NEXT: sllv $7, $3, $2
+; MIPS-NEXT: andi $1, $1, 255
+; MIPS-NEXT: sllv $6, $1, $2
; MIPS-NEXT: $BB11_1: # %entry
; MIPS-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS-NEXT: ll $2, 0($6)
-; MIPS-NEXT: srav $4, $2, $10
-; MIPS-NEXT: andi $4, $4, 255
-; MIPS-NEXT: or $1, $zero, $4
-; MIPS-NEXT: sllv $4, $4, $10
-; MIPS-NEXT: sltu $5, $4, $7
-; MIPS-NEXT: move $3, $4
-; MIPS-NEXT: movz $3, $7, $5
-; MIPS-NEXT: and $3, $3, $8
-; MIPS-NEXT: and $4, $2, $9
-; MIPS-NEXT: or $4, $4, $3
-; MIPS-NEXT: sc $4, 0($6)
-; MIPS-NEXT: beqz $4, $BB11_1
+; MIPS-NEXT: ll $1, 0($5)
+; MIPS-NEXT: and $3, $1, $7
+; MIPS-NEXT: sltu $4, $6, $3
+; MIPS-NEXT: movn $3, $6, $4
+; MIPS-NEXT: xor $3, $1, $3
+; MIPS-NEXT: and $3, $3, $7
+; MIPS-NEXT: xor $3, $1, $3
+; MIPS-NEXT: sc $3, 0($5)
+; MIPS-NEXT: beqz $3, $BB11_1
; MIPS-NEXT: nop
; MIPS-NEXT: # %bb.2: # %entry
-; MIPS-NEXT: .insn
-; MIPS-NEXT: # %bb.3: # %entry
-; MIPS-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS-NEXT: # %bb.4: # %entry
-; MIPS-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPS-NEXT: srlv $2, $1, $2
; MIPS-NEXT: sync
-; MIPS-NEXT: addiu $sp, $sp, 8
; MIPS-NEXT: jr $ra
; MIPS-NEXT: nop
;
-; MIPS2-LABEL: test_umin_8:
-; MIPS2: # %bb.0: # %entry
-; MIPS2-NEXT: addiu $sp, $sp, -8
-; MIPS2-NEXT: .cfi_def_cfa_offset 8
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: addiu $1, $zero, -4
-; MIPS2-NEXT: and $6, $4, $1
-; MIPS2-NEXT: andi $1, $4, 3
-; MIPS2-NEXT: sll $10, $1, 3
-; MIPS2-NEXT: ori $1, $zero, 255
-; MIPS2-NEXT: sllv $8, $1, $10
-; MIPS2-NEXT: nor $9, $zero, $8
-; MIPS2-NEXT: sllv $7, $5, $10
-; MIPS2-NEXT: $BB11_1: # %entry
-; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS2-NEXT: ll $2, 0($6)
-; MIPS2-NEXT: srav $4, $2, $10
-; MIPS2-NEXT: andi $4, $4, 255
-; MIPS2-NEXT: or $1, $zero, $4
-; MIPS2-NEXT: sllv $4, $4, $10
-; MIPS2-NEXT: sltu $5, $4, $7
-; MIPS2-NEXT: move $3, $4
-; MIPS2-NEXT: beqz $5, $BB11_3
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.2: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB11_1 Depth=1
-; MIPS2-NEXT: j $BB11_4
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: $BB11_3: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB11_1 Depth=1
-; MIPS2-NEXT: move $3, $7
-; MIPS2-NEXT: $BB11_4: # %entry
-; MIPS2-NEXT: # in Loop: Header=BB11_1 Depth=1
-; MIPS2-NEXT: and $3, $3, $8
-; MIPS2-NEXT: and $4, $2, $9
-; MIPS2-NEXT: or $4, $4, $3
-; MIPS2-NEXT: sc $4, 0($6)
-; MIPS2-NEXT: beqz $4, $BB11_1
-; MIPS2-NEXT: nop
-; MIPS2-NEXT: # %bb.5: # %entry
-; MIPS2-NEXT: .insn
-; MIPS2-NEXT: # %bb.6: # %entry
-; MIPS2-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS2-NEXT: # %bb.7: # %entry
-; MIPS2-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
-; MIPS2-NEXT: sync
-; MIPS2-NEXT: addiu $sp, $sp, 8
-; MIPS2-NEXT: jr $ra
-; MIPS2-NEXT: nop
-;
; MIPSR6-LABEL: test_umin_8:
; MIPSR6: # %bb.0: # %entry
-; MIPSR6-NEXT: addiu $sp, $sp, -8
-; MIPSR6-NEXT: .cfi_def_cfa_offset 8
+; MIPSR6-NEXT: move $1, $5
+; MIPSR6-NEXT: not $2, $4
; MIPSR6-NEXT: sync
-; MIPSR6-NEXT: addiu $1, $zero, -4
-; MIPSR6-NEXT: and $6, $4, $1
-; MIPSR6-NEXT: andi $1, $4, 3
-; MIPSR6-NEXT: xori $1, $1, 3
-; MIPSR6-NEXT: sll $10, $1, 3
-; MIPSR6-NEXT: ori $1, $zero, 255
-; MIPSR6-NEXT: sllv $8, $1, $10
-; MIPSR6-NEXT: nor $9, $zero, $8
-; MIPSR6-NEXT: sllv $7, $5, $10
+; MIPSR6-NEXT: addiu $3, $zero, -4
+; MIPSR6-NEXT: and $5, $4, $3
+; MIPSR6-NEXT: andi $2, $2, 3
+; MIPSR6-NEXT: sll $2, $2, 3
+; MIPSR6-NEXT: addiu $3, $zero, 255
+; MIPSR6-NEXT: sllv $7, $3, $2
+; MIPSR6-NEXT: andi $1, $1, 255
+; MIPSR6-NEXT: sllv $6, $1, $2
; MIPSR6-NEXT: $BB11_1: # %entry
; MIPSR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSR6-NEXT: ll $2, 0($6)
-; MIPSR6-NEXT: srav $4, $2, $10
-; MIPSR6-NEXT: andi $4, $4, 255
-; MIPSR6-NEXT: or $1, $zero, $4
-; MIPSR6-NEXT: sllv $4, $4, $10
-; MIPSR6-NEXT: sltu $5, $4, $7
-; MIPSR6-NEXT: selnez $3, $4, $5
-; MIPSR6-NEXT: seleqz $5, $7, $5
-; MIPSR6-NEXT: or $3, $3, $5
-; MIPSR6-NEXT: and $3, $3, $8
-; MIPSR6-NEXT: and $4, $2, $9
-; MIPSR6-NEXT: or $4, $4, $3
-; MIPSR6-NEXT: sc $4, 0($6)
-; MIPSR6-NEXT: beqzc $4, $BB11_1
-; MIPSR6-NEXT: nop
+; MIPSR6-NEXT: ll $1, 0($5)
+; MIPSR6-NEXT: and $3, $1, $7
+; MIPSR6-NEXT: sltu $4, $6, $3
+; MIPSR6-NEXT: seleqz $3, $3, $4
+; MIPSR6-NEXT: selnez $4, $6, $4
+; MIPSR6-NEXT: or $3, $3, $4
+; MIPSR6-NEXT: xor $3, $1, $3
+; MIPSR6-NEXT: and $3, $3, $7
+; MIPSR6-NEXT: xor $3, $1, $3
+; MIPSR6-NEXT: sc $3, 0($5)
+; MIPSR6-NEXT: beqzc $3, $BB11_1
; MIPSR6-NEXT: # %bb.2: # %entry
-; MIPSR6-NEXT: .insn
-; MIPSR6-NEXT: # %bb.3: # %entry
-; MIPSR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSR6-NEXT: # %bb.4: # %entry
-; MIPSR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSR6-NEXT: srlv $2, $1, $2
; MIPSR6-NEXT: sync
-; MIPSR6-NEXT: addiu $sp, $sp, 8
; MIPSR6-NEXT: jrc $ra
;
; MM-LABEL: test_umin_8:
; MM: # %bb.0: # %entry
-; MM-NEXT: addiu $sp, $sp, -8
-; MM-NEXT: .cfi_def_cfa_offset 8
+; MM-NEXT: move $3, $5
+; MM-NEXT: not16 $2, $4
; MM-NEXT: sync
-; MM-NEXT: addiu $1, $zero, -4
-; MM-NEXT: and $6, $4, $1
-; MM-NEXT: andi $1, $4, 3
-; MM-NEXT: xori $1, $1, 3
-; MM-NEXT: sll $10, $1, 3
-; MM-NEXT: ori $1, $zero, 255
-; MM-NEXT: sllv $8, $1, $10
-; MM-NEXT: nor $9, $zero, $8
-; MM-NEXT: sllv $7, $5, $10
+; MM-NEXT: addiu $5, $zero, -4
+; MM-NEXT: and16 $5, $4
+; MM-NEXT: andi16 $2, $2, 3
+; MM-NEXT: sll16 $2, $2, 3
+; MM-NEXT: addiu $1, $zero, 255
+; MM-NEXT: sllv $7, $1, $2
+; MM-NEXT: andi16 $3, $3, 255
+; MM-NEXT: sllv $6, $3, $2
; MM-NEXT: $BB11_1: # %entry
; MM-NEXT: # =>This Inner Loop Header: Depth=1
-; MM-NEXT: ll $2, 0($6)
-; MM-NEXT: srav $4, $2, $10
-; MM-NEXT: andi $4, $4, 255
-; MM-NEXT: or $1, $zero, $4
-; MM-NEXT: sllv $4, $4, $10
-; MM-NEXT: sltu $5, $4, $7
-; MM-NEXT: or $3, $4, $zero
-; MM-NEXT: movz $3, $7, $5
-; MM-NEXT: and $3, $3, $8
-; MM-NEXT: and $4, $2, $9
-; MM-NEXT: or $4, $4, $3
-; MM-NEXT: sc $4, 0($6)
-; MM-NEXT: beqzc $4, $BB11_1
+; MM-NEXT: ll $1, 0($5)
+; MM-NEXT: and $3, $1, $7
+; MM-NEXT: sltu $4, $6, $3
+; MM-NEXT: movn $3, $6, $4
+; MM-NEXT: xor $3, $1, $3
+; MM-NEXT: and $3, $3, $7
+; MM-NEXT: xor $3, $1, $3
+; MM-NEXT: sc $3, 0($5)
+; MM-NEXT: beqzc $3, $BB11_1
; MM-NEXT: # %bb.2: # %entry
-; MM-NEXT: .insn
-; MM-NEXT: # %bb.3: # %entry
-; MM-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MM-NEXT: # %bb.4: # %entry
-; MM-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MM-NEXT: srlv $2, $1, $2
; MM-NEXT: sync
-; MM-NEXT: addiusp 8
; MM-NEXT: jrc $ra
;
; MMR6-LABEL: test_umin_8:
; MMR6: # %bb.0: # %entry
-; MMR6-NEXT: addiu $sp, $sp, -8
-; MMR6-NEXT: .cfi_def_cfa_offset 8
+; MMR6-NEXT: move $3, $5
+; MMR6-NEXT: not16 $2, $4
; MMR6-NEXT: sync
; MMR6-NEXT: addiu $1, $zero, -4
-; MMR6-NEXT: and $6, $4, $1
-; MMR6-NEXT: andi $1, $4, 3
-; MMR6-NEXT: xori $1, $1, 3
-; MMR6-NEXT: sll $10, $1, 3
-; MMR6-NEXT: ori $1, $zero, 255
-; MMR6-NEXT: sllv $8, $1, $10
-; MMR6-NEXT: nor $9, $zero, $8
-; MMR6-NEXT: sllv $7, $5, $10
+; MMR6-NEXT: and $5, $4, $1
+; MMR6-NEXT: andi16 $2, $2, 3
+; MMR6-NEXT: sll16 $2, $2, 3
+; MMR6-NEXT: addiu $1, $zero, 255
+; MMR6-NEXT: sllv $7, $1, $2
+; MMR6-NEXT: andi16 $3, $3, 255
+; MMR6-NEXT: sllv $6, $3, $2
; MMR6-NEXT: $BB11_1: # %entry
; MMR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MMR6-NEXT: ll $2, 0($6)
-; MMR6-NEXT: srav $4, $2, $10
-; MMR6-NEXT: andi $4, $4, 255
-; MMR6-NEXT: or $1, $zero, $4
-; MMR6-NEXT: sllv $4, $4, $10
-; MMR6-NEXT: sltu $5, $4, $7
-; MMR6-NEXT: selnez $3, $4, $5
-; MMR6-NEXT: seleqz $5, $7, $5
-; MMR6-NEXT: or $3, $3, $5
-; MMR6-NEXT: and $3, $3, $8
-; MMR6-NEXT: and $4, $2, $9
-; MMR6-NEXT: or $4, $4, $3
-; MMR6-NEXT: sc $4, 0($6)
-; MMR6-NEXT: beqc $4, $zero, $BB11_1
+; MMR6-NEXT: ll $1, 0($5)
+; MMR6-NEXT: and $3, $1, $7
+; MMR6-NEXT: sltu $4, $6, $3
+; MMR6-NEXT: seleqz $3, $3, $4
+; MMR6-NEXT: selnez $4, $6, $4
+; MMR6-NEXT: or $3, $3, $4
+; MMR6-NEXT: xor $3, $1, $3
+; MMR6-NEXT: and $3, $3, $7
+; MMR6-NEXT: xor $3, $1, $3
+; MMR6-NEXT: sc $3, 0($5)
+; MMR6-NEXT: beqc $3, $zero, $BB11_1
; MMR6-NEXT: # %bb.2: # %entry
-; MMR6-NEXT: .insn
-; MMR6-NEXT: # %bb.3: # %entry
-; MMR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMR6-NEXT: # %bb.4: # %entry
-; MMR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMR6-NEXT: srlv $2, $1, $2
; MMR6-NEXT: sync
-; MMR6-NEXT: addiu $sp, $sp, 8
; MMR6-NEXT: jrc $ra
;
+; MIPS2-LABEL: test_umin_8:
+; MIPS2: # %bb.0: # %entry
+; MIPS2-NEXT: move $1, $5
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: addiu $2, $zero, -4
+; MIPS2-NEXT: and $5, $4, $2
+; MIPS2-NEXT: sll $2, $4, 3
+; MIPS2-NEXT: addiu $3, $zero, 255
+; MIPS2-NEXT: sllv $7, $3, $2
+; MIPS2-NEXT: andi $1, $1, 255
+; MIPS2-NEXT: sllv $6, $1, $2
+; MIPS2-NEXT: $BB11_1: # %entry
+; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1
+; MIPS2-NEXT: ll $1, 0($5)
+; MIPS2-NEXT: and $3, $1, $7
+; MIPS2-NEXT: sltu $4, $6, $3
+; MIPS2-NEXT: beqz $4, $BB11_3
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.2: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB11_1 Depth=1
+; MIPS2-NEXT: move $3, $6
+; MIPS2-NEXT: $BB11_3: # %entry
+; MIPS2-NEXT: # in Loop: Header=BB11_1 Depth=1
+; MIPS2-NEXT: xor $3, $1, $3
+; MIPS2-NEXT: and $3, $3, $7
+; MIPS2-NEXT: xor $3, $1, $3
+; MIPS2-NEXT: sc $3, 0($5)
+; MIPS2-NEXT: beqz $3, $BB11_1
+; MIPS2-NEXT: nop
+; MIPS2-NEXT: # %bb.4: # %entry
+; MIPS2-NEXT: srlv $2, $1, $2
+; MIPS2-NEXT: sync
+; MIPS2-NEXT: jr $ra
+; MIPS2-NEXT: nop
+;
; MIPS32-LABEL: test_umin_8:
; MIPS32: # %bb.0: # %entry
-; MIPS32-NEXT: addiu $sp, $sp, -8
-; MIPS32-NEXT: .cfi_def_cfa_offset 8
+; MIPS32-NEXT: move $1, $5
; MIPS32-NEXT: sync
-; MIPS32-NEXT: addiu $1, $zero, -4
-; MIPS32-NEXT: and $6, $4, $1
-; MIPS32-NEXT: andi $1, $4, 3
-; MIPS32-NEXT: sll $10, $1, 3
-; MIPS32-NEXT: ori $1, $zero, 255
-; MIPS32-NEXT: sllv $8, $1, $10
-; MIPS32-NEXT: nor $9, $zero, $8
-; MIPS32-NEXT: sllv $7, $5, $10
+; MIPS32-NEXT: addiu $2, $zero, -4
+; MIPS32-NEXT: and $5, $4, $2
+; MIPS32-NEXT: sll $2, $4, 3
+; MIPS32-NEXT: addiu $3, $zero, 255
+; MIPS32-NEXT: sllv $7, $3, $2
+; MIPS32-NEXT: andi $1, $1, 255
+; MIPS32-NEXT: sllv $6, $1, $2
; MIPS32-NEXT: $BB11_1: # %entry
; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32-NEXT: ll $2, 0($6)
-; MIPS32-NEXT: srav $4, $2, $10
-; MIPS32-NEXT: andi $4, $4, 255
-; MIPS32-NEXT: or $1, $zero, $4
-; MIPS32-NEXT: sllv $4, $4, $10
-; MIPS32-NEXT: sltu $5, $4, $7
-; MIPS32-NEXT: move $3, $4
-; MIPS32-NEXT: movz $3, $7, $5
-; MIPS32-NEXT: and $3, $3, $8
-; MIPS32-NEXT: and $4, $2, $9
-; MIPS32-NEXT: or $4, $4, $3
-; MIPS32-NEXT: sc $4, 0($6)
-; MIPS32-NEXT: beqz $4, $BB11_1
+; MIPS32-NEXT: ll $1, 0($5)
+; MIPS32-NEXT: and $3, $1, $7
+; MIPS32-NEXT: sltu $4, $6, $3
+; MIPS32-NEXT: movn $3, $6, $4
+; MIPS32-NEXT: xor $3, $1, $3
+; MIPS32-NEXT: and $3, $3, $7
+; MIPS32-NEXT: xor $3, $1, $3
+; MIPS32-NEXT: sc $3, 0($5)
+; MIPS32-NEXT: beqz $3, $BB11_1
; MIPS32-NEXT: nop
; MIPS32-NEXT: # %bb.2: # %entry
-; MIPS32-NEXT: .insn
-; MIPS32-NEXT: # %bb.3: # %entry
-; MIPS32-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32-NEXT: # %bb.4: # %entry
-; MIPS32-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPS32-NEXT: srlv $2, $1, $2
; MIPS32-NEXT: sync
-; MIPS32-NEXT: addiu $sp, $sp, 8
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPSEL-LABEL: test_umin_8:
; MIPSEL: # %bb.0: # %entry
-; MIPSEL-NEXT: addiu $sp, $sp, -8
-; MIPSEL-NEXT: .cfi_def_cfa_offset 8
+; MIPSEL-NEXT: move $1, $5
; MIPSEL-NEXT: sync
-; MIPSEL-NEXT: addiu $1, $zero, -4
-; MIPSEL-NEXT: and $6, $4, $1
-; MIPSEL-NEXT: andi $1, $4, 3
-; MIPSEL-NEXT: sll $10, $1, 3
-; MIPSEL-NEXT: ori $1, $zero, 255
-; MIPSEL-NEXT: sllv $8, $1, $10
-; MIPSEL-NEXT: nor $9, $zero, $8
-; MIPSEL-NEXT: sllv $7, $5, $10
+; MIPSEL-NEXT: addiu $2, $zero, -4
+; MIPSEL-NEXT: and $5, $4, $2
+; MIPSEL-NEXT: sll $2, $4, 3
+; MIPSEL-NEXT: addiu $3, $zero, 255
+; MIPSEL-NEXT: sllv $7, $3, $2
+; MIPSEL-NEXT: andi $1, $1, 255
+; MIPSEL-NEXT: sllv $6, $1, $2
; MIPSEL-NEXT: $BB11_1: # %entry
; MIPSEL-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSEL-NEXT: ll $2, 0($6)
-; MIPSEL-NEXT: srav $4, $2, $10
-; MIPSEL-NEXT: andi $4, $4, 255
-; MIPSEL-NEXT: or $1, $zero, $4
-; MIPSEL-NEXT: sllv $4, $4, $10
-; MIPSEL-NEXT: sltu $5, $4, $7
-; MIPSEL-NEXT: move $3, $4
-; MIPSEL-NEXT: movz $3, $7, $5
-; MIPSEL-NEXT: and $3, $3, $8
-; MIPSEL-NEXT: and $4, $2, $9
-; MIPSEL-NEXT: or $4, $4, $3
-; MIPSEL-NEXT: sc $4, 0($6)
-; MIPSEL-NEXT: beqz $4, $BB11_1
+; MIPSEL-NEXT: ll $1, 0($5)
+; MIPSEL-NEXT: and $3, $1, $7
+; MIPSEL-NEXT: sltu $4, $6, $3
+; MIPSEL-NEXT: movn $3, $6, $4
+; MIPSEL-NEXT: xor $3, $1, $3
+; MIPSEL-NEXT: and $3, $3, $7
+; MIPSEL-NEXT: xor $3, $1, $3
+; MIPSEL-NEXT: sc $3, 0($5)
+; MIPSEL-NEXT: beqz $3, $BB11_1
; MIPSEL-NEXT: nop
; MIPSEL-NEXT: # %bb.2: # %entry
-; MIPSEL-NEXT: .insn
-; MIPSEL-NEXT: # %bb.3: # %entry
-; MIPSEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSEL-NEXT: # %bb.4: # %entry
-; MIPSEL-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSEL-NEXT: srlv $2, $1, $2
; MIPSEL-NEXT: sync
-; MIPSEL-NEXT: addiu $sp, $sp, 8
; MIPSEL-NEXT: jr $ra
; MIPSEL-NEXT: nop
;
; MIPSELR6-LABEL: test_umin_8:
; MIPSELR6: # %bb.0: # %entry
-; MIPSELR6-NEXT: addiu $sp, $sp, -8
-; MIPSELR6-NEXT: .cfi_def_cfa_offset 8
+; MIPSELR6-NEXT: move $1, $5
; MIPSELR6-NEXT: sync
-; MIPSELR6-NEXT: addiu $1, $zero, -4
-; MIPSELR6-NEXT: and $6, $4, $1
-; MIPSELR6-NEXT: andi $1, $4, 3
-; MIPSELR6-NEXT: sll $10, $1, 3
-; MIPSELR6-NEXT: ori $1, $zero, 255
-; MIPSELR6-NEXT: sllv $8, $1, $10
-; MIPSELR6-NEXT: nor $9, $zero, $8
-; MIPSELR6-NEXT: sllv $7, $5, $10
+; MIPSELR6-NEXT: addiu $2, $zero, -4
+; MIPSELR6-NEXT: and $5, $4, $2
+; MIPSELR6-NEXT: sll $2, $4, 3
+; MIPSELR6-NEXT: addiu $3, $zero, 255
+; MIPSELR6-NEXT: sllv $7, $3, $2
+; MIPSELR6-NEXT: andi $1, $1, 255
+; MIPSELR6-NEXT: sllv $6, $1, $2
; MIPSELR6-NEXT: $BB11_1: # %entry
; MIPSELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPSELR6-NEXT: ll $2, 0($6)
-; MIPSELR6-NEXT: srav $4, $2, $10
-; MIPSELR6-NEXT: andi $4, $4, 255
-; MIPSELR6-NEXT: or $1, $zero, $4
-; MIPSELR6-NEXT: sllv $4, $4, $10
-; MIPSELR6-NEXT: sltu $5, $4, $7
-; MIPSELR6-NEXT: selnez $3, $4, $5
-; MIPSELR6-NEXT: seleqz $5, $7, $5
-; MIPSELR6-NEXT: or $3, $3, $5
-; MIPSELR6-NEXT: and $3, $3, $8
-; MIPSELR6-NEXT: and $4, $2, $9
-; MIPSELR6-NEXT: or $4, $4, $3
-; MIPSELR6-NEXT: sc $4, 0($6)
-; MIPSELR6-NEXT: beqzc $4, $BB11_1
-; MIPSELR6-NEXT: nop
+; MIPSELR6-NEXT: ll $1, 0($5)
+; MIPSELR6-NEXT: and $3, $1, $7
+; MIPSELR6-NEXT: sltu $4, $6, $3
+; MIPSELR6-NEXT: seleqz $3, $3, $4
+; MIPSELR6-NEXT: selnez $4, $6, $4
+; MIPSELR6-NEXT: or $3, $3, $4
+; MIPSELR6-NEXT: xor $3, $1, $3
+; MIPSELR6-NEXT: and $3, $3, $7
+; MIPSELR6-NEXT: xor $3, $1, $3
+; MIPSELR6-NEXT: sc $3, 0($5)
+; MIPSELR6-NEXT: beqzc $3, $BB11_1
; MIPSELR6-NEXT: # %bb.2: # %entry
-; MIPSELR6-NEXT: .insn
-; MIPSELR6-NEXT: # %bb.3: # %entry
-; MIPSELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPSELR6-NEXT: # %bb.4: # %entry
-; MIPSELR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MIPSELR6-NEXT: srlv $2, $1, $2
; MIPSELR6-NEXT: sync
-; MIPSELR6-NEXT: addiu $sp, $sp, 8
; MIPSELR6-NEXT: jrc $ra
;
; MMEL-LABEL: test_umin_8:
; MMEL: # %bb.0: # %entry
-; MMEL-NEXT: addiu $sp, $sp, -8
-; MMEL-NEXT: .cfi_def_cfa_offset 8
+; MMEL-NEXT: move $3, $5
; MMEL-NEXT: sync
-; MMEL-NEXT: addiu $1, $zero, -4
-; MMEL-NEXT: and $6, $4, $1
-; MMEL-NEXT: andi $1, $4, 3
-; MMEL-NEXT: sll $10, $1, 3
-; MMEL-NEXT: ori $1, $zero, 255
-; MMEL-NEXT: sllv $8, $1, $10
-; MMEL-NEXT: nor $9, $zero, $8
-; MMEL-NEXT: sllv $7, $5, $10
+; MMEL-NEXT: addiu $5, $zero, -4
+; MMEL-NEXT: and16 $5, $4
+; MMEL-NEXT: sll16 $2, $4, 3
+; MMEL-NEXT: andi $2, $2, 24
+; MMEL-NEXT: addiu $1, $zero, 255
+; MMEL-NEXT: sllv $7, $1, $2
+; MMEL-NEXT: andi16 $3, $3, 255
+; MMEL-NEXT: sllv $6, $3, $2
; MMEL-NEXT: $BB11_1: # %entry
; MMEL-NEXT: # =>This Inner Loop Header: Depth=1
-; MMEL-NEXT: ll $2, 0($6)
-; MMEL-NEXT: srav $4, $2, $10
-; MMEL-NEXT: andi $4, $4, 255
-; MMEL-NEXT: or $1, $zero, $4
-; MMEL-NEXT: sllv $4, $4, $10
-; MMEL-NEXT: sltu $5, $4, $7
-; MMEL-NEXT: or $3, $4, $zero
-; MMEL-NEXT: movz $3, $7, $5
-; MMEL-NEXT: and $3, $3, $8
-; MMEL-NEXT: and $4, $2, $9
-; MMEL-NEXT: or $4, $4, $3
-; MMEL-NEXT: sc $4, 0($6)
-; MMEL-NEXT: beqzc $4, $BB11_1
+; MMEL-NEXT: ll $1, 0($5)
+; MMEL-NEXT: and $3, $1, $7
+; MMEL-NEXT: sltu $4, $6, $3
+; MMEL-NEXT: movn $3, $6, $4
+; MMEL-NEXT: xor $3, $1, $3
+; MMEL-NEXT: and $3, $3, $7
+; MMEL-NEXT: xor $3, $1, $3
+; MMEL-NEXT: sc $3, 0($5)
+; MMEL-NEXT: beqzc $3, $BB11_1
; MMEL-NEXT: # %bb.2: # %entry
-; MMEL-NEXT: .insn
-; MMEL-NEXT: # %bb.3: # %entry
-; MMEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMEL-NEXT: # %bb.4: # %entry
-; MMEL-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMEL-NEXT: srlv $2, $1, $2
; MMEL-NEXT: sync
-; MMEL-NEXT: addiusp 8
; MMEL-NEXT: jrc $ra
;
; MMELR6-LABEL: test_umin_8:
; MMELR6: # %bb.0: # %entry
-; MMELR6-NEXT: addiu $sp, $sp, -8
-; MMELR6-NEXT: .cfi_def_cfa_offset 8
+; MMELR6-NEXT: move $3, $5
; MMELR6-NEXT: sync
; MMELR6-NEXT: addiu $1, $zero, -4
-; MMELR6-NEXT: and $6, $4, $1
-; MMELR6-NEXT: andi $1, $4, 3
-; MMELR6-NEXT: sll $10, $1, 3
-; MMELR6-NEXT: ori $1, $zero, 255
-; MMELR6-NEXT: sllv $8, $1, $10
-; MMELR6-NEXT: nor $9, $zero, $8
-; MMELR6-NEXT: sllv $7, $5, $10
+; MMELR6-NEXT: and $5, $4, $1
+; MMELR6-NEXT: sll16 $2, $4, 3
+; MMELR6-NEXT: andi $2, $2, 24
+; MMELR6-NEXT: addiu $1, $zero, 255
+; MMELR6-NEXT: sllv $7, $1, $2
+; MMELR6-NEXT: andi16 $3, $3, 255
+; MMELR6-NEXT: sllv $6, $3, $2
; MMELR6-NEXT: $BB11_1: # %entry
; MMELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MMELR6-NEXT: ll $2, 0($6)
-; MMELR6-NEXT: srav $4, $2, $10
-; MMELR6-NEXT: andi $4, $4, 255
-; MMELR6-NEXT: or $1, $zero, $4
-; MMELR6-NEXT: sllv $4, $4, $10
-; MMELR6-NEXT: sltu $5, $4, $7
-; MMELR6-NEXT: selnez $3, $4, $5
-; MMELR6-NEXT: seleqz $5, $7, $5
-; MMELR6-NEXT: or $3, $3, $5
-; MMELR6-NEXT: and $3, $3, $8
-; MMELR6-NEXT: and $4, $2, $9
-; MMELR6-NEXT: or $4, $4, $3
-; MMELR6-NEXT: sc $4, 0($6)
-; MMELR6-NEXT: beqc $4, $zero, $BB11_1
+; MMELR6-NEXT: ll $1, 0($5)
+; MMELR6-NEXT: and $3, $1, $7
+; MMELR6-NEXT: sltu $4, $6, $3
+; MMELR6-NEXT: seleqz $3, $3, $4
+; MMELR6-NEXT: selnez $4, $6, $4
+; MMELR6-NEXT: or $3, $3, $4
+; MMELR6-NEXT: xor $3, $1, $3
+; MMELR6-NEXT: and $3, $3, $7
+; MMELR6-NEXT: xor $3, $1, $3
+; MMELR6-NEXT: sc $3, 0($5)
+; MMELR6-NEXT: beqc $3, $zero, $BB11_1
; MMELR6-NEXT: # %bb.2: # %entry
-; MMELR6-NEXT: .insn
-; MMELR6-NEXT: # %bb.3: # %entry
-; MMELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MMELR6-NEXT: # %bb.4: # %entry
-; MMELR6-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
+; MMELR6-NEXT: srlv $2, $1, $2
; MMELR6-NEXT: sync
-; MMELR6-NEXT: addiu $sp, $sp, 8
; MMELR6-NEXT: jrc $ra
;
; MIPS64-LABEL: test_umin_8:
; MIPS64: # %bb.0: # %entry
-; MIPS64-NEXT: daddiu $sp, $sp, -16
-; MIPS64-NEXT: .cfi_def_cfa_offset 16
; MIPS64-NEXT: move $1, $5
; MIPS64-NEXT: sync
; MIPS64-NEXT: daddiu $2, $zero, -4
-; MIPS64-NEXT: and $6, $4, $2
-; MIPS64-NEXT: andi $2, $4, 3
-; MIPS64-NEXT: xori $2, $2, 3
-; MIPS64-NEXT: sll $10, $2, 3
-; MIPS64-NEXT: ori $2, $zero, 255
-; MIPS64-NEXT: sllv $8, $2, $10
-; MIPS64-NEXT: nor $9, $zero, $8
-; MIPS64-NEXT: sllv $7, $1, $10
+; MIPS64-NEXT: and $5, $4, $2
+; MIPS64-NEXT: move $2, $4
+; MIPS64-NEXT: sll $2, $2, 0
+; MIPS64-NEXT: not $2, $2
+; MIPS64-NEXT: andi $2, $2, 3
+; MIPS64-NEXT: sll $2, $2, 3
+; MIPS64-NEXT: addiu $3, $zero, 255
+; MIPS64-NEXT: sllv $7, $3, $2
+; MIPS64-NEXT: andi $1, $1, 255
+; MIPS64-NEXT: sllv $6, $1, $2
; MIPS64-NEXT: .LBB11_1: # %entry
; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64-NEXT: ll $2, 0($6)
-; MIPS64-NEXT: srav $4, $2, $10
-; MIPS64-NEXT: andi $4, $4, 255
-; MIPS64-NEXT: or $1, $zero, $4
-; MIPS64-NEXT: sllv $4, $4, $10
-; MIPS64-NEXT: sltu $5, $4, $7
-; MIPS64-NEXT: move $3, $4
-; MIPS64-NEXT: movz $3, $7, $5
-; MIPS64-NEXT: and $3, $3, $8
-; MIPS64-NEXT: and $4, $2, $9
-; MIPS64-NEXT: or $4, $4, $3
-; MIPS64-NEXT: sc $4, 0($6)
-; MIPS64-NEXT: beqz $4, .LBB11_1
+; MIPS64-NEXT: ll $1, 0($5)
+; MIPS64-NEXT: and $3, $1, $7
+; MIPS64-NEXT: sltu $4, $6, $3
+; MIPS64-NEXT: movn $3, $6, $4
+; MIPS64-NEXT: xor $3, $1, $3
+; MIPS64-NEXT: and $3, $3, $7
+; MIPS64-NEXT: xor $3, $1, $3
+; MIPS64-NEXT: sc $3, 0($5)
+; MIPS64-NEXT: beqz $3, .LBB11_1
; MIPS64-NEXT: nop
; MIPS64-NEXT: # %bb.2: # %entry
-; MIPS64-NEXT: .insn
-; MIPS64-NEXT: # %bb.3: # %entry
-; MIPS64-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64-NEXT: # %bb.4: # %entry
-; MIPS64-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64-NEXT: srlv $2, $1, $2
; MIPS64-NEXT: sync
-; MIPS64-NEXT: daddiu $sp, $sp, 16
; MIPS64-NEXT: jr $ra
; MIPS64-NEXT: nop
;
; MIPS64R6-LABEL: test_umin_8:
; MIPS64R6: # %bb.0: # %entry
-; MIPS64R6-NEXT: daddiu $sp, $sp, -16
-; MIPS64R6-NEXT: .cfi_def_cfa_offset 16
; MIPS64R6-NEXT: move $1, $5
; MIPS64R6-NEXT: sync
; MIPS64R6-NEXT: daddiu $2, $zero, -4
-; MIPS64R6-NEXT: and $6, $4, $2
-; MIPS64R6-NEXT: andi $2, $4, 3
-; MIPS64R6-NEXT: xori $2, $2, 3
-; MIPS64R6-NEXT: sll $10, $2, 3
-; MIPS64R6-NEXT: ori $2, $zero, 255
-; MIPS64R6-NEXT: sllv $8, $2, $10
-; MIPS64R6-NEXT: nor $9, $zero, $8
-; MIPS64R6-NEXT: sllv $7, $1, $10
+; MIPS64R6-NEXT: and $5, $4, $2
+; MIPS64R6-NEXT: move $2, $4
+; MIPS64R6-NEXT: sll $2, $2, 0
+; MIPS64R6-NEXT: not $2, $2
+; MIPS64R6-NEXT: andi $2, $2, 3
+; MIPS64R6-NEXT: sll $2, $2, 3
+; MIPS64R6-NEXT: addiu $3, $zero, 255
+; MIPS64R6-NEXT: sllv $7, $3, $2
+; MIPS64R6-NEXT: andi $1, $1, 255
+; MIPS64R6-NEXT: sllv $6, $1, $2
; MIPS64R6-NEXT: .LBB11_1: # %entry
; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R6-NEXT: ll $2, 0($6)
-; MIPS64R6-NEXT: srav $4, $2, $10
-; MIPS64R6-NEXT: andi $4, $4, 255
-; MIPS64R6-NEXT: or $1, $zero, $4
-; MIPS64R6-NEXT: sllv $4, $4, $10
-; MIPS64R6-NEXT: sltu $5, $4, $7
-; MIPS64R6-NEXT: selnez $3, $4, $5
-; MIPS64R6-NEXT: seleqz $5, $7, $5
-; MIPS64R6-NEXT: or $3, $3, $5
-; MIPS64R6-NEXT: and $3, $3, $8
-; MIPS64R6-NEXT: and $4, $2, $9
-; MIPS64R6-NEXT: or $4, $4, $3
-; MIPS64R6-NEXT: sc $4, 0($6)
-; MIPS64R6-NEXT: beqzc $4, .LBB11_1
-; MIPS64R6-NEXT: nop
+; MIPS64R6-NEXT: ll $1, 0($5)
+; MIPS64R6-NEXT: and $3, $1, $7
+; MIPS64R6-NEXT: sltu $4, $6, $3
+; MIPS64R6-NEXT: seleqz $3, $3, $4
+; MIPS64R6-NEXT: selnez $4, $6, $4
+; MIPS64R6-NEXT: or $3, $3, $4
+; MIPS64R6-NEXT: xor $3, $1, $3
+; MIPS64R6-NEXT: and $3, $3, $7
+; MIPS64R6-NEXT: xor $3, $1, $3
+; MIPS64R6-NEXT: sc $3, 0($5)
+; MIPS64R6-NEXT: beqzc $3, .LBB11_1
; MIPS64R6-NEXT: # %bb.2: # %entry
-; MIPS64R6-NEXT: .insn
-; MIPS64R6-NEXT: # %bb.3: # %entry
-; MIPS64R6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64R6-NEXT: # %bb.4: # %entry
-; MIPS64R6-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64R6-NEXT: srlv $2, $1, $2
; MIPS64R6-NEXT: sync
-; MIPS64R6-NEXT: daddiu $sp, $sp, 16
; MIPS64R6-NEXT: jrc $ra
;
; MIPS64EL-LABEL: test_umin_8:
; MIPS64EL: # %bb.0: # %entry
-; MIPS64EL-NEXT: daddiu $sp, $sp, -16
-; MIPS64EL-NEXT: .cfi_def_cfa_offset 16
; MIPS64EL-NEXT: move $1, $5
; MIPS64EL-NEXT: sync
; MIPS64EL-NEXT: daddiu $2, $zero, -4
-; MIPS64EL-NEXT: and $6, $4, $2
-; MIPS64EL-NEXT: andi $2, $4, 3
-; MIPS64EL-NEXT: sll $10, $2, 3
-; MIPS64EL-NEXT: ori $2, $zero, 255
-; MIPS64EL-NEXT: sllv $8, $2, $10
-; MIPS64EL-NEXT: nor $9, $zero, $8
-; MIPS64EL-NEXT: sllv $7, $1, $10
+; MIPS64EL-NEXT: and $5, $4, $2
+; MIPS64EL-NEXT: move $2, $4
+; MIPS64EL-NEXT: sll $2, $2, 0
+; MIPS64EL-NEXT: andi $2, $2, 3
+; MIPS64EL-NEXT: sll $2, $2, 3
+; MIPS64EL-NEXT: addiu $3, $zero, 255
+; MIPS64EL-NEXT: sllv $7, $3, $2
+; MIPS64EL-NEXT: andi $1, $1, 255
+; MIPS64EL-NEXT: sllv $6, $1, $2
; MIPS64EL-NEXT: .LBB11_1: # %entry
; MIPS64EL-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64EL-NEXT: ll $2, 0($6)
-; MIPS64EL-NEXT: srav $4, $2, $10
-; MIPS64EL-NEXT: andi $4, $4, 255
-; MIPS64EL-NEXT: or $1, $zero, $4
-; MIPS64EL-NEXT: sllv $4, $4, $10
-; MIPS64EL-NEXT: sltu $5, $4, $7
-; MIPS64EL-NEXT: move $3, $4
-; MIPS64EL-NEXT: movz $3, $7, $5
-; MIPS64EL-NEXT: and $3, $3, $8
-; MIPS64EL-NEXT: and $4, $2, $9
-; MIPS64EL-NEXT: or $4, $4, $3
-; MIPS64EL-NEXT: sc $4, 0($6)
-; MIPS64EL-NEXT: beqz $4, .LBB11_1
+; MIPS64EL-NEXT: ll $1, 0($5)
+; MIPS64EL-NEXT: and $3, $1, $7
+; MIPS64EL-NEXT: sltu $4, $6, $3
+; MIPS64EL-NEXT: movn $3, $6, $4
+; MIPS64EL-NEXT: xor $3, $1, $3
+; MIPS64EL-NEXT: and $3, $3, $7
+; MIPS64EL-NEXT: xor $3, $1, $3
+; MIPS64EL-NEXT: sc $3, 0($5)
+; MIPS64EL-NEXT: beqz $3, .LBB11_1
; MIPS64EL-NEXT: nop
; MIPS64EL-NEXT: # %bb.2: # %entry
-; MIPS64EL-NEXT: .insn
-; MIPS64EL-NEXT: # %bb.3: # %entry
-; MIPS64EL-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64EL-NEXT: # %bb.4: # %entry
-; MIPS64EL-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64EL-NEXT: srlv $2, $1, $2
; MIPS64EL-NEXT: sync
-; MIPS64EL-NEXT: daddiu $sp, $sp, 16
; MIPS64EL-NEXT: jr $ra
; MIPS64EL-NEXT: nop
;
; MIPS64ELR6-LABEL: test_umin_8:
; MIPS64ELR6: # %bb.0: # %entry
-; MIPS64ELR6-NEXT: daddiu $sp, $sp, -16
-; MIPS64ELR6-NEXT: .cfi_def_cfa_offset 16
; MIPS64ELR6-NEXT: move $1, $5
; MIPS64ELR6-NEXT: sync
; MIPS64ELR6-NEXT: daddiu $2, $zero, -4
-; MIPS64ELR6-NEXT: and $6, $4, $2
-; MIPS64ELR6-NEXT: andi $2, $4, 3
-; MIPS64ELR6-NEXT: sll $10, $2, 3
-; MIPS64ELR6-NEXT: ori $2, $zero, 255
-; MIPS64ELR6-NEXT: sllv $8, $2, $10
-; MIPS64ELR6-NEXT: nor $9, $zero, $8
-; MIPS64ELR6-NEXT: sllv $7, $1, $10
+; MIPS64ELR6-NEXT: and $5, $4, $2
+; MIPS64ELR6-NEXT: move $2, $4
+; MIPS64ELR6-NEXT: sll $2, $2, 0
+; MIPS64ELR6-NEXT: andi $2, $2, 3
+; MIPS64ELR6-NEXT: sll $2, $2, 3
+; MIPS64ELR6-NEXT: addiu $3, $zero, 255
+; MIPS64ELR6-NEXT: sllv $7, $3, $2
+; MIPS64ELR6-NEXT: andi $1, $1, 255
+; MIPS64ELR6-NEXT: sllv $6, $1, $2
; MIPS64ELR6-NEXT: .LBB11_1: # %entry
; MIPS64ELR6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64ELR6-NEXT: ll $2, 0($6)
-; MIPS64ELR6-NEXT: srav $4, $2, $10
-; MIPS64ELR6-NEXT: andi $4, $4, 255
-; MIPS64ELR6-NEXT: or $1, $zero, $4
-; MIPS64ELR6-NEXT: sllv $4, $4, $10
-; MIPS64ELR6-NEXT: sltu $5, $4, $7
-; MIPS64ELR6-NEXT: selnez $3, $4, $5
-; MIPS64ELR6-NEXT: seleqz $5, $7, $5
-; MIPS64ELR6-NEXT: or $3, $3, $5
-; MIPS64ELR6-NEXT: and $3, $3, $8
-; MIPS64ELR6-NEXT: and $4, $2, $9
-; MIPS64ELR6-NEXT: or $4, $4, $3
-; MIPS64ELR6-NEXT: sc $4, 0($6)
-; MIPS64ELR6-NEXT: beqzc $4, .LBB11_1
-; MIPS64ELR6-NEXT: nop
+; MIPS64ELR6-NEXT: ll $1, 0($5)
+; MIPS64ELR6-NEXT: and $3, $1, $7
+; MIPS64ELR6-NEXT: sltu $4, $6, $3
+; MIPS64ELR6-NEXT: seleqz $3, $3, $4
+; MIPS64ELR6-NEXT: selnez $4, $6, $4
+; MIPS64ELR6-NEXT: or $3, $3, $4
+; MIPS64ELR6-NEXT: xor $3, $1, $3
+; MIPS64ELR6-NEXT: and $3, $3, $7
+; MIPS64ELR6-NEXT: xor $3, $1, $3
+; MIPS64ELR6-NEXT: sc $3, 0($5)
+; MIPS64ELR6-NEXT: beqzc $3, .LBB11_1
; MIPS64ELR6-NEXT: # %bb.2: # %entry
-; MIPS64ELR6-NEXT: .insn
-; MIPS64ELR6-NEXT: # %bb.3: # %entry
-; MIPS64ELR6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64ELR6-NEXT: # %bb.4: # %entry
-; MIPS64ELR6-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
+; MIPS64ELR6-NEXT: srlv $2, $1, $2
; MIPS64ELR6-NEXT: sync
-; MIPS64ELR6-NEXT: daddiu $sp, $sp, 16
; MIPS64ELR6-NEXT: jrc $ra
entry:
%0 = atomicrmw umin ptr %ptr, i8 %val seq_cst
diff --git a/llvm/test/CodeGen/Mips/atomic.ll b/llvm/test/CodeGen/Mips/atomic.ll
index f83de83b3d037d..4b3e09b31299c6 100644
--- a/llvm/test/CodeGen/Mips/atomic.ll
+++ b/llvm/test/CodeGen/Mips/atomic.ll
@@ -1322,7 +1322,7 @@ define i32 @AtomicLoadNand32(i32 signext %incr) nounwind {
; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS32-NEXT: ll $2, 0($1)
; MIPS32-NEXT: and $3, $2, $4
-; MIPS32-NEXT: nor $3, $zero, $3
+; MIPS32-NEXT: not $3, $3
; MIPS32-NEXT: sc $3, 0($1)
; MIPS32-NEXT: beqz $3, $BB5_1
; MIPS32-NEXT: nop
@@ -1340,7 +1340,7 @@ define i32 @AtomicLoadNand32(i32 signext %incr) nounwind {
; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS32O0-NEXT: ll $2, 0($3)
; MIPS32O0-NEXT: and $1, $2, $4
-; MIPS32O0-NEXT: nor $1, $zero, $1
+; MIPS32O0-NEXT: not $1, $1
; MIPS32O0-NEXT: sc $1, 0($3)
; MIPS32O0-NEXT: beqz $1, $BB5_1
; MIPS32O0-NEXT: nop
@@ -1358,7 +1358,7 @@ define i32 @AtomicLoadNand32(i32 signext %incr) nounwind {
; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS32R2-NEXT: ll $2, 0($1)
; MIPS32R2-NEXT: and $3, $2, $4
-; MIPS32R2-NEXT: nor $3, $zero, $3
+; MIPS32R2-NEXT: not $3, $3
; MIPS32R2-NEXT: sc $3, 0($1)
; MIPS32R2-NEXT: beqz $3, $BB5_1
; MIPS32R2-NEXT: nop
@@ -1376,7 +1376,7 @@ define i32 @AtomicLoadNand32(i32 signext %incr) nounwind {
; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS32R6-NEXT: ll $2, 0($1)
; MIPS32R6-NEXT: and $3, $2, $4
-; MIPS32R6-NEXT: nor $3, $zero, $3
+; MIPS32R6-NEXT: not $3, $3
; MIPS32R6-NEXT: sc $3, 0($1)
; MIPS32R6-NEXT: beqzc $3, $BB5_1
; MIPS32R6-NEXT: nop
@@ -1393,7 +1393,7 @@ define i32 @AtomicLoadNand32(i32 signext %incr) nounwind {
; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS32R6O0-NEXT: ll $2, 0($3)
; MIPS32R6O0-NEXT: and $1, $2, $4
-; MIPS32R6O0-NEXT: nor $1, $zero, $1
+; MIPS32R6O0-NEXT: not $1, $1
; MIPS32R6O0-NEXT: sc $1, 0($3)
; MIPS32R6O0-NEXT: beqzc $1, $BB5_1
; MIPS32R6O0-NEXT: nop
@@ -1410,7 +1410,7 @@ define i32 @AtomicLoadNand32(i32 signext %incr) nounwind {
; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS4-NEXT: ll $2, 0($1)
; MIPS4-NEXT: and $3, $2, $4
-; MIPS4-NEXT: nor $3, $zero, $3
+; MIPS4-NEXT: not $3, $3
; MIPS4-NEXT: sc $3, 0($1)
; MIPS4-NEXT: beqz $3, .LBB5_1
; MIPS4-NEXT: nop
@@ -1428,7 +1428,7 @@ define i32 @AtomicLoadNand32(i32 signext %incr) nounwind {
; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS64-NEXT: ll $2, 0($1)
; MIPS64-NEXT: and $3, $2, $4
-; MIPS64-NEXT: nor $3, $zero, $3
+; MIPS64-NEXT: not $3, $3
; MIPS64-NEXT: sc $3, 0($1)
; MIPS64-NEXT: beqz $3, .LBB5_1
; MIPS64-NEXT: nop
@@ -1446,7 +1446,7 @@ define i32 @AtomicLoadNand32(i32 signext %incr) nounwind {
; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS64R2-NEXT: ll $2, 0($1)
; MIPS64R2-NEXT: and $3, $2, $4
-; MIPS64R2-NEXT: nor $3, $zero, $3
+; MIPS64R2-NEXT: not $3, $3
; MIPS64R2-NEXT: sc $3, 0($1)
; MIPS64R2-NEXT: beqz $3, .LBB5_1
; MIPS64R2-NEXT: nop
@@ -1464,7 +1464,7 @@ define i32 @AtomicLoadNand32(i32 signext %incr) nounwind {
; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS64R6-NEXT: ll $2, 0($1)
; MIPS64R6-NEXT: and $3, $2, $4
-; MIPS64R6-NEXT: nor $3, $zero, $3
+; MIPS64R6-NEXT: not $3, $3
; MIPS64R6-NEXT: sc $3, 0($1)
; MIPS64R6-NEXT: beqzc $3, .LBB5_1
; MIPS64R6-NEXT: nop
@@ -1482,7 +1482,7 @@ define i32 @AtomicLoadNand32(i32 signext %incr) nounwind {
; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS64R6O0-NEXT: ll $2, 0($3)
; MIPS64R6O0-NEXT: and $1, $2, $4
-; MIPS64R6O0-NEXT: nor $1, $zero, $1
+; MIPS64R6O0-NEXT: not $1, $1
; MIPS64R6O0-NEXT: sc $1, 0($3)
; MIPS64R6O0-NEXT: beqzc $1, .LBB5_1
; MIPS64R6O0-NEXT: nop
@@ -1499,7 +1499,7 @@ define i32 @AtomicLoadNand32(i32 signext %incr) nounwind {
; MM32-NEXT: # =>This Inner Loop Header: Depth=1
; MM32-NEXT: ll $2, 0($1)
; MM32-NEXT: and $3, $2, $4
-; MM32-NEXT: nor $3, $zero, $3
+; MM32-NEXT: not $3, $3
; MM32-NEXT: sc $3, 0($1)
; MM32-NEXT: beqzc $3, $BB5_1
; MM32-NEXT: # %bb.2: # %entry
@@ -1515,7 +1515,7 @@ define i32 @AtomicLoadNand32(i32 signext %incr) nounwind {
; O1-NEXT: # =>This Inner Loop Header: Depth=1
; O1-NEXT: ll $2, 0($1)
; O1-NEXT: and $3, $2, $4
-; O1-NEXT: nor $3, $zero, $3
+; O1-NEXT: not $3, $3
; O1-NEXT: sc $3, 0($1)
; O1-NEXT: beqz $3, $BB5_1
; O1-NEXT: nop
@@ -1533,7 +1533,7 @@ define i32 @AtomicLoadNand32(i32 signext %incr) nounwind {
; O2-NEXT: # =>This Inner Loop Header: Depth=1
; O2-NEXT: ll $2, 0($1)
; O2-NEXT: and $3, $2, $4
-; O2-NEXT: nor $3, $zero, $3
+; O2-NEXT: not $3, $3
; O2-NEXT: sc $3, 0($1)
; O2-NEXT: beqz $3, $BB5_1
; O2-NEXT: nop
@@ -1551,7 +1551,7 @@ define i32 @AtomicLoadNand32(i32 signext %incr) nounwind {
; O3-NEXT: # =>This Inner Loop Header: Depth=1
; O3-NEXT: ll $2, 0($1)
; O3-NEXT: and $3, $2, $4
-; O3-NEXT: nor $3, $zero, $3
+; O3-NEXT: not $3, $3
; O3-NEXT: sc $3, 0($1)
; O3-NEXT: beqz $3, $BB5_1
; O3-NEXT: nop
@@ -1569,7 +1569,7 @@ define i32 @AtomicLoadNand32(i32 signext %incr) nounwind {
; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS32EB-NEXT: ll $2, 0($1)
; MIPS32EB-NEXT: and $3, $2, $4
-; MIPS32EB-NEXT: nor $3, $zero, $3
+; MIPS32EB-NEXT: not $3, $3
; MIPS32EB-NEXT: sc $3, 0($1)
; MIPS32EB-NEXT: beqz $3, $BB5_1
; MIPS32EB-NEXT: nop
@@ -1909,17 +1909,16 @@ define i32 @AtomicCmpSwap32(i32 signext %oldval, i32 signext %newval) nounwind {
; MIPS32O0-NEXT: addiu $sp, $sp, -8
; MIPS32O0-NEXT: addu $1, $2, $25
; MIPS32O0-NEXT: sw $5, 4($sp)
-; MIPS32O0-NEXT: lw $6, 4($sp)
+; MIPS32O0-NEXT: lw $5, 4($sp)
; MIPS32O0-NEXT: lw $3, %got(x)($1)
-; MIPS32O0-NEXT: move $5, $4
; MIPS32O0-NEXT: $BB7_1: # %entry
; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS32O0-NEXT: ll $2, 0($3)
-; MIPS32O0-NEXT: bne $2, $5, $BB7_3
+; MIPS32O0-NEXT: bne $2, $4, $BB7_3
; MIPS32O0-NEXT: nop
; MIPS32O0-NEXT: # %bb.2: # %entry
; MIPS32O0-NEXT: # in Loop: Header=BB7_1 Depth=1
-; MIPS32O0-NEXT: move $1, $6
+; MIPS32O0-NEXT: move $1, $5
; MIPS32O0-NEXT: sc $1, 0($3)
; MIPS32O0-NEXT: beqz $1, $BB7_1
; MIPS32O0-NEXT: nop
@@ -2243,71 +2242,62 @@ define signext i8 @AtomicLoadAdd8(i8 signext %incr) nounwind {
; MIPS32-NEXT: lui $2, %hi(_gp_disp)
; MIPS32-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32-NEXT: addu $1, $2, $25
-; MIPS32-NEXT: lw $1, %got(y)($1)
; MIPS32-NEXT: addiu $2, $zero, -4
-; MIPS32-NEXT: and $3, $1, $2
+; MIPS32-NEXT: lw $1, %got(y)($1)
+; MIPS32-NEXT: and $2, $1, $2
; MIPS32-NEXT: andi $1, $1, 3
; MIPS32-NEXT: sll $1, $1, 3
-; MIPS32-NEXT: ori $2, $zero, 255
-; MIPS32-NEXT: sllv $5, $2, $1
-; MIPS32-NEXT: nor $6, $zero, $5
+; MIPS32-NEXT: addiu $3, $zero, 255
+; MIPS32-NEXT: sllv $3, $3, $1
+; MIPS32-NEXT: andi $4, $4, 255
; MIPS32-NEXT: sllv $4, $4, $1
; MIPS32-NEXT: $BB8_1: # %entry
; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32-NEXT: ll $7, 0($3)
-; MIPS32-NEXT: addu $8, $7, $4
-; MIPS32-NEXT: and $8, $8, $5
-; MIPS32-NEXT: and $9, $7, $6
-; MIPS32-NEXT: or $9, $9, $8
-; MIPS32-NEXT: sc $9, 0($3)
-; MIPS32-NEXT: beqz $9, $BB8_1
+; MIPS32-NEXT: ll $5, 0($2)
+; MIPS32-NEXT: addu $6, $5, $4
+; MIPS32-NEXT: xor $6, $5, $6
+; MIPS32-NEXT: and $6, $6, $3
+; MIPS32-NEXT: xor $6, $5, $6
+; MIPS32-NEXT: sc $6, 0($2)
+; MIPS32-NEXT: beqz $6, $BB8_1
; MIPS32-NEXT: nop
; MIPS32-NEXT: # %bb.2: # %entry
-; MIPS32-NEXT: and $2, $7, $5
-; MIPS32-NEXT: srlv $2, $2, $1
-; MIPS32-NEXT: sll $2, $2, 24
-; MIPS32-NEXT: sra $2, $2, 24
-; MIPS32-NEXT: # %bb.3: # %entry
+; MIPS32-NEXT: srlv $1, $5, $1
+; MIPS32-NEXT: sll $1, $1, 24
; MIPS32-NEXT: jr $ra
-; MIPS32-NEXT: nop
+; MIPS32-NEXT: sra $2, $1, 24
;
; MIPS32O0-LABEL: AtomicLoadAdd8:
; MIPS32O0: # %bb.0: # %entry
; MIPS32O0-NEXT: lui $2, %hi(_gp_disp)
; MIPS32O0-NEXT: addiu $2, $2, %lo(_gp_disp)
-; MIPS32O0-NEXT: addiu $sp, $sp, -8
-; MIPS32O0-NEXT: addu $1, $2, $25
-; MIPS32O0-NEXT: lw $1, %got(y)($1)
-; MIPS32O0-NEXT: addiu $2, $zero, -4
-; MIPS32O0-NEXT: and $5, $1, $2
-; MIPS32O0-NEXT: andi $1, $1, 3
-; MIPS32O0-NEXT: sll $9, $1, 3
-; MIPS32O0-NEXT: ori $1, $zero, 255
-; MIPS32O0-NEXT: sllv $7, $1, $9
-; MIPS32O0-NEXT: nor $8, $zero, $7
-; MIPS32O0-NEXT: sllv $6, $4, $9
+; MIPS32O0-NEXT: addu $2, $2, $25
+; MIPS32O0-NEXT: move $1, $4
+; MIPS32O0-NEXT: lw $3, %got(y)($2)
+; MIPS32O0-NEXT: addiu $4, $zero, -4
+; MIPS32O0-NEXT: and $4, $3, $4
+; MIPS32O0-NEXT: lw $2, %got(y)($2)
+; MIPS32O0-NEXT: addiu $3, $zero, 3
+; MIPS32O0-NEXT: and $2, $2, $3
+; MIPS32O0-NEXT: sll $2, $2, 3
+; MIPS32O0-NEXT: addiu $3, $zero, 255
+; MIPS32O0-NEXT: sllv $6, $3, $2
+; MIPS32O0-NEXT: andi $1, $1, 255
+; MIPS32O0-NEXT: sllv $5, $1, $2
; MIPS32O0-NEXT: $BB8_1: # %entry
; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32O0-NEXT: ll $2, 0($5)
-; MIPS32O0-NEXT: addu $3, $2, $6
-; MIPS32O0-NEXT: and $3, $3, $7
-; MIPS32O0-NEXT: and $4, $2, $8
-; MIPS32O0-NEXT: or $4, $4, $3
-; MIPS32O0-NEXT: sc $4, 0($5)
-; MIPS32O0-NEXT: beqz $4, $BB8_1
+; MIPS32O0-NEXT: ll $1, 0($4)
+; MIPS32O0-NEXT: addu $3, $1, $5
+; MIPS32O0-NEXT: xor $3, $1, $3
+; MIPS32O0-NEXT: and $3, $3, $6
+; MIPS32O0-NEXT: xor $3, $1, $3
+; MIPS32O0-NEXT: sc $3, 0($4)
+; MIPS32O0-NEXT: beqz $3, $BB8_1
; MIPS32O0-NEXT: nop
; MIPS32O0-NEXT: # %bb.2: # %entry
-; MIPS32O0-NEXT: and $1, $2, $7
-; MIPS32O0-NEXT: srlv $1, $1, $9
-; MIPS32O0-NEXT: sll $1, $1, 24
-; MIPS32O0-NEXT: sra $1, $1, 24
-; MIPS32O0-NEXT: # %bb.3: # %entry
-; MIPS32O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32O0-NEXT: # %bb.4: # %entry
-; MIPS32O0-NEXT: lw $1, 4($sp) # 4-byte Folded Reload
+; MIPS32O0-NEXT: srlv $1, $1, $2
; MIPS32O0-NEXT: sll $1, $1, 24
; MIPS32O0-NEXT: sra $2, $1, 24
-; MIPS32O0-NEXT: addiu $sp, $sp, 8
; MIPS32O0-NEXT: jr $ra
; MIPS32O0-NEXT: nop
;
@@ -2316,96 +2306,85 @@ define signext i8 @AtomicLoadAdd8(i8 signext %incr) nounwind {
; MIPS32R2-NEXT: lui $2, %hi(_gp_disp)
; MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32R2-NEXT: addu $1, $2, $25
-; MIPS32R2-NEXT: lw $1, %got(y)($1)
; MIPS32R2-NEXT: addiu $2, $zero, -4
-; MIPS32R2-NEXT: and $3, $1, $2
+; MIPS32R2-NEXT: lw $1, %got(y)($1)
+; MIPS32R2-NEXT: and $2, $1, $2
; MIPS32R2-NEXT: andi $1, $1, 3
; MIPS32R2-NEXT: sll $1, $1, 3
-; MIPS32R2-NEXT: ori $2, $zero, 255
-; MIPS32R2-NEXT: sllv $5, $2, $1
-; MIPS32R2-NEXT: nor $6, $zero, $5
+; MIPS32R2-NEXT: addiu $3, $zero, 255
+; MIPS32R2-NEXT: sllv $3, $3, $1
+; MIPS32R2-NEXT: andi $4, $4, 255
; MIPS32R2-NEXT: sllv $4, $4, $1
; MIPS32R2-NEXT: $BB8_1: # %entry
; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32R2-NEXT: ll $7, 0($3)
-; MIPS32R2-NEXT: addu $8, $7, $4
-; MIPS32R2-NEXT: and $8, $8, $5
-; MIPS32R2-NEXT: and $9, $7, $6
-; MIPS32R2-NEXT: or $9, $9, $8
-; MIPS32R2-NEXT: sc $9, 0($3)
-; MIPS32R2-NEXT: beqz $9, $BB8_1
+; MIPS32R2-NEXT: ll $5, 0($2)
+; MIPS32R2-NEXT: addu $6, $5, $4
+; MIPS32R2-NEXT: xor $6, $5, $6
+; MIPS32R2-NEXT: and $6, $6, $3
+; MIPS32R2-NEXT: xor $6, $5, $6
+; MIPS32R2-NEXT: sc $6, 0($2)
+; MIPS32R2-NEXT: beqz $6, $BB8_1
; MIPS32R2-NEXT: nop
; MIPS32R2-NEXT: # %bb.2: # %entry
-; MIPS32R2-NEXT: and $2, $7, $5
-; MIPS32R2-NEXT: srlv $2, $2, $1
-; MIPS32R2-NEXT: seb $2, $2
-; MIPS32R2-NEXT: # %bb.3: # %entry
+; MIPS32R2-NEXT: srlv $1, $5, $1
; MIPS32R2-NEXT: jr $ra
-; MIPS32R2-NEXT: nop
+; MIPS32R2-NEXT: seb $2, $1
;
; MIPS32R6-LABEL: AtomicLoadAdd8:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lui $2, %hi(_gp_disp)
; MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32R6-NEXT: addu $1, $2, $25
-; MIPS32R6-NEXT: lw $1, %got(y)($1)
; MIPS32R6-NEXT: addiu $2, $zero, -4
-; MIPS32R6-NEXT: and $3, $1, $2
+; MIPS32R6-NEXT: lw $1, %got(y)($1)
+; MIPS32R6-NEXT: and $2, $1, $2
; MIPS32R6-NEXT: andi $1, $1, 3
; MIPS32R6-NEXT: sll $1, $1, 3
-; MIPS32R6-NEXT: ori $2, $zero, 255
-; MIPS32R6-NEXT: sllv $5, $2, $1
-; MIPS32R6-NEXT: nor $6, $zero, $5
+; MIPS32R6-NEXT: addiu $3, $zero, 255
+; MIPS32R6-NEXT: sllv $3, $3, $1
+; MIPS32R6-NEXT: andi $4, $4, 255
; MIPS32R6-NEXT: sllv $4, $4, $1
; MIPS32R6-NEXT: $BB8_1: # %entry
; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32R6-NEXT: ll $7, 0($3)
-; MIPS32R6-NEXT: addu $8, $7, $4
-; MIPS32R6-NEXT: and $8, $8, $5
-; MIPS32R6-NEXT: and $9, $7, $6
-; MIPS32R6-NEXT: or $9, $9, $8
-; MIPS32R6-NEXT: sc $9, 0($3)
-; MIPS32R6-NEXT: beqzc $9, $BB8_1
+; MIPS32R6-NEXT: ll $5, 0($2)
+; MIPS32R6-NEXT: addu $6, $5, $4
+; MIPS32R6-NEXT: xor $6, $5, $6
+; MIPS32R6-NEXT: and $6, $6, $3
+; MIPS32R6-NEXT: xor $6, $5, $6
+; MIPS32R6-NEXT: sc $6, 0($2)
+; MIPS32R6-NEXT: beqzc $6, $BB8_1
; MIPS32R6-NEXT: # %bb.2: # %entry
-; MIPS32R6-NEXT: and $2, $7, $5
-; MIPS32R6-NEXT: srlv $2, $2, $1
-; MIPS32R6-NEXT: seb $2, $2
-; MIPS32R6-NEXT: # %bb.3: # %entry
-; MIPS32R6-NEXT: jrc $ra
+; MIPS32R6-NEXT: srlv $1, $5, $1
+; MIPS32R6-NEXT: jr $ra
+; MIPS32R6-NEXT: seb $2, $1
;
; MIPS32R6O0-LABEL: AtomicLoadAdd8:
; MIPS32R6O0: # %bb.0: # %entry
; MIPS32R6O0-NEXT: lui $2, %hi(_gp_disp)
; MIPS32R6O0-NEXT: addiu $2, $2, %lo(_gp_disp)
-; MIPS32R6O0-NEXT: addiu $sp, $sp, -8
-; MIPS32R6O0-NEXT: addu $1, $2, $25
-; MIPS32R6O0-NEXT: lw $1, %got(y)($1)
-; MIPS32R6O0-NEXT: addiu $2, $zero, -4
-; MIPS32R6O0-NEXT: and $5, $1, $2
-; MIPS32R6O0-NEXT: andi $1, $1, 3
-; MIPS32R6O0-NEXT: sll $9, $1, 3
-; MIPS32R6O0-NEXT: ori $1, $zero, 255
-; MIPS32R6O0-NEXT: sllv $7, $1, $9
-; MIPS32R6O0-NEXT: nor $8, $zero, $7
-; MIPS32R6O0-NEXT: sllv $6, $4, $9
+; MIPS32R6O0-NEXT: addu $2, $2, $25
+; MIPS32R6O0-NEXT: move $1, $4
+; MIPS32R6O0-NEXT: lw $2, %got(y)($2)
+; MIPS32R6O0-NEXT: addiu $3, $zero, -4
+; MIPS32R6O0-NEXT: and $4, $2, $3
+; MIPS32R6O0-NEXT: andi $2, $2, 3
+; MIPS32R6O0-NEXT: sll $2, $2, 3
+; MIPS32R6O0-NEXT: addiu $3, $zero, 255
+; MIPS32R6O0-NEXT: sllv $6, $3, $2
+; MIPS32R6O0-NEXT: andi $1, $1, 255
+; MIPS32R6O0-NEXT: sllv $5, $1, $2
; MIPS32R6O0-NEXT: $BB8_1: # %entry
; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32R6O0-NEXT: ll $2, 0($5)
-; MIPS32R6O0-NEXT: addu $3, $2, $6
-; MIPS32R6O0-NEXT: and $3, $3, $7
-; MIPS32R6O0-NEXT: and $4, $2, $8
-; MIPS32R6O0-NEXT: or $4, $4, $3
-; MIPS32R6O0-NEXT: sc $4, 0($5)
-; MIPS32R6O0-NEXT: beqzc $4, $BB8_1
+; MIPS32R6O0-NEXT: ll $1, 0($4)
+; MIPS32R6O0-NEXT: addu $3, $1, $5
+; MIPS32R6O0-NEXT: xor $3, $1, $3
+; MIPS32R6O0-NEXT: and $3, $3, $6
+; MIPS32R6O0-NEXT: xor $3, $1, $3
+; MIPS32R6O0-NEXT: sc $3, 0($4)
+; MIPS32R6O0-NEXT: beqzc $3, $BB8_1
; MIPS32R6O0-NEXT: # %bb.2: # %entry
-; MIPS32R6O0-NEXT: and $1, $2, $7
-; MIPS32R6O0-NEXT: srlv $1, $1, $9
-; MIPS32R6O0-NEXT: seb $1, $1
-; MIPS32R6O0-NEXT: # %bb.3: # %entry
-; MIPS32R6O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32R6O0-NEXT: # %bb.4: # %entry
-; MIPS32R6O0-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
-; MIPS32R6O0-NEXT: addiu $sp, $sp, 8
+; MIPS32R6O0-NEXT: srlv $1, $1, $2
+; MIPS32R6O0-NEXT: seb $2, $1
; MIPS32R6O0-NEXT: jrc $ra
;
; MIPS4-LABEL: AtomicLoadAdd8:
@@ -2414,32 +2393,30 @@ define signext i8 @AtomicLoadAdd8(i8 signext %incr) nounwind {
; MIPS4-NEXT: daddu $1, $1, $25
; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd8)))
; MIPS4-NEXT: ld $1, %got_disp(y)($1)
-; MIPS4-NEXT: daddiu $2, $zero, -4
-; MIPS4-NEXT: and $3, $1, $2
-; MIPS4-NEXT: andi $1, $1, 3
-; MIPS4-NEXT: sll $1, $1, 3
-; MIPS4-NEXT: ori $2, $zero, 255
-; MIPS4-NEXT: sllv $5, $2, $1
-; MIPS4-NEXT: nor $6, $zero, $5
-; MIPS4-NEXT: sllv $4, $4, $1
+; MIPS4-NEXT: sll $2, $1, 0
+; MIPS4-NEXT: andi $2, $2, 3
+; MIPS4-NEXT: daddiu $3, $zero, -4
+; MIPS4-NEXT: and $1, $1, $3
+; MIPS4-NEXT: sll $2, $2, 3
+; MIPS4-NEXT: addiu $3, $zero, 255
+; MIPS4-NEXT: sllv $3, $3, $2
+; MIPS4-NEXT: andi $4, $4, 255
+; MIPS4-NEXT: sllv $4, $4, $2
; MIPS4-NEXT: .LBB8_1: # %entry
; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS4-NEXT: ll $7, 0($3)
-; MIPS4-NEXT: addu $8, $7, $4
-; MIPS4-NEXT: and $8, $8, $5
-; MIPS4-NEXT: and $9, $7, $6
-; MIPS4-NEXT: or $9, $9, $8
-; MIPS4-NEXT: sc $9, 0($3)
-; MIPS4-NEXT: beqz $9, .LBB8_1
+; MIPS4-NEXT: ll $5, 0($1)
+; MIPS4-NEXT: addu $6, $5, $4
+; MIPS4-NEXT: xor $6, $5, $6
+; MIPS4-NEXT: and $6, $6, $3
+; MIPS4-NEXT: xor $6, $5, $6
+; MIPS4-NEXT: sc $6, 0($1)
+; MIPS4-NEXT: beqz $6, .LBB8_1
; MIPS4-NEXT: nop
; MIPS4-NEXT: # %bb.2: # %entry
-; MIPS4-NEXT: and $2, $7, $5
-; MIPS4-NEXT: srlv $2, $2, $1
-; MIPS4-NEXT: sll $2, $2, 24
-; MIPS4-NEXT: sra $2, $2, 24
-; MIPS4-NEXT: # %bb.3: # %entry
+; MIPS4-NEXT: srlv $1, $5, $2
+; MIPS4-NEXT: sll $1, $1, 24
; MIPS4-NEXT: jr $ra
-; MIPS4-NEXT: nop
+; MIPS4-NEXT: sra $2, $1, 24
;
; MIPS64-LABEL: AtomicLoadAdd8:
; MIPS64: # %bb.0: # %entry
@@ -2447,32 +2424,30 @@ define signext i8 @AtomicLoadAdd8(i8 signext %incr) nounwind {
; MIPS64-NEXT: daddu $1, $1, $25
; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd8)))
; MIPS64-NEXT: ld $1, %got_disp(y)($1)
-; MIPS64-NEXT: daddiu $2, $zero, -4
-; MIPS64-NEXT: and $3, $1, $2
-; MIPS64-NEXT: andi $1, $1, 3
-; MIPS64-NEXT: sll $1, $1, 3
-; MIPS64-NEXT: ori $2, $zero, 255
-; MIPS64-NEXT: sllv $5, $2, $1
-; MIPS64-NEXT: nor $6, $zero, $5
-; MIPS64-NEXT: sllv $4, $4, $1
+; MIPS64-NEXT: sll $2, $1, 0
+; MIPS64-NEXT: andi $2, $2, 3
+; MIPS64-NEXT: daddiu $3, $zero, -4
+; MIPS64-NEXT: and $1, $1, $3
+; MIPS64-NEXT: sll $2, $2, 3
+; MIPS64-NEXT: addiu $3, $zero, 255
+; MIPS64-NEXT: sllv $3, $3, $2
+; MIPS64-NEXT: andi $4, $4, 255
+; MIPS64-NEXT: sllv $4, $4, $2
; MIPS64-NEXT: .LBB8_1: # %entry
; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64-NEXT: ll $7, 0($3)
-; MIPS64-NEXT: addu $8, $7, $4
-; MIPS64-NEXT: and $8, $8, $5
-; MIPS64-NEXT: and $9, $7, $6
-; MIPS64-NEXT: or $9, $9, $8
-; MIPS64-NEXT: sc $9, 0($3)
-; MIPS64-NEXT: beqz $9, .LBB8_1
+; MIPS64-NEXT: ll $5, 0($1)
+; MIPS64-NEXT: addu $6, $5, $4
+; MIPS64-NEXT: xor $6, $5, $6
+; MIPS64-NEXT: and $6, $6, $3
+; MIPS64-NEXT: xor $6, $5, $6
+; MIPS64-NEXT: sc $6, 0($1)
+; MIPS64-NEXT: beqz $6, .LBB8_1
; MIPS64-NEXT: nop
; MIPS64-NEXT: # %bb.2: # %entry
-; MIPS64-NEXT: and $2, $7, $5
-; MIPS64-NEXT: srlv $2, $2, $1
-; MIPS64-NEXT: sll $2, $2, 24
-; MIPS64-NEXT: sra $2, $2, 24
-; MIPS64-NEXT: # %bb.3: # %entry
+; MIPS64-NEXT: srlv $1, $5, $2
+; MIPS64-NEXT: sll $1, $1, 24
; MIPS64-NEXT: jr $ra
-; MIPS64-NEXT: nop
+; MIPS64-NEXT: sra $2, $1, 24
;
; MIPS64R2-LABEL: AtomicLoadAdd8:
; MIPS64R2: # %bb.0: # %entry
@@ -2480,31 +2455,29 @@ define signext i8 @AtomicLoadAdd8(i8 signext %incr) nounwind {
; MIPS64R2-NEXT: daddu $1, $1, $25
; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd8)))
; MIPS64R2-NEXT: ld $1, %got_disp(y)($1)
-; MIPS64R2-NEXT: daddiu $2, $zero, -4
-; MIPS64R2-NEXT: and $3, $1, $2
-; MIPS64R2-NEXT: andi $1, $1, 3
-; MIPS64R2-NEXT: sll $1, $1, 3
-; MIPS64R2-NEXT: ori $2, $zero, 255
-; MIPS64R2-NEXT: sllv $5, $2, $1
-; MIPS64R2-NEXT: nor $6, $zero, $5
-; MIPS64R2-NEXT: sllv $4, $4, $1
+; MIPS64R2-NEXT: sll $2, $1, 0
+; MIPS64R2-NEXT: andi $2, $2, 3
+; MIPS64R2-NEXT: daddiu $3, $zero, -4
+; MIPS64R2-NEXT: and $1, $1, $3
+; MIPS64R2-NEXT: sll $2, $2, 3
+; MIPS64R2-NEXT: addiu $3, $zero, 255
+; MIPS64R2-NEXT: sllv $3, $3, $2
+; MIPS64R2-NEXT: andi $4, $4, 255
+; MIPS64R2-NEXT: sllv $4, $4, $2
; MIPS64R2-NEXT: .LBB8_1: # %entry
; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R2-NEXT: ll $7, 0($3)
-; MIPS64R2-NEXT: addu $8, $7, $4
-; MIPS64R2-NEXT: and $8, $8, $5
-; MIPS64R2-NEXT: and $9, $7, $6
-; MIPS64R2-NEXT: or $9, $9, $8
-; MIPS64R2-NEXT: sc $9, 0($3)
-; MIPS64R2-NEXT: beqz $9, .LBB8_1
+; MIPS64R2-NEXT: ll $5, 0($1)
+; MIPS64R2-NEXT: addu $6, $5, $4
+; MIPS64R2-NEXT: xor $6, $5, $6
+; MIPS64R2-NEXT: and $6, $6, $3
+; MIPS64R2-NEXT: xor $6, $5, $6
+; MIPS64R2-NEXT: sc $6, 0($1)
+; MIPS64R2-NEXT: beqz $6, .LBB8_1
; MIPS64R2-NEXT: nop
; MIPS64R2-NEXT: # %bb.2: # %entry
-; MIPS64R2-NEXT: and $2, $7, $5
-; MIPS64R2-NEXT: srlv $2, $2, $1
-; MIPS64R2-NEXT: seb $2, $2
-; MIPS64R2-NEXT: # %bb.3: # %entry
+; MIPS64R2-NEXT: srlv $1, $5, $2
; MIPS64R2-NEXT: jr $ra
-; MIPS64R2-NEXT: nop
+; MIPS64R2-NEXT: seb $2, $1
;
; MIPS64R6-LABEL: AtomicLoadAdd8:
; MIPS64R6: # %bb.0: # %entry
@@ -2512,65 +2485,59 @@ define signext i8 @AtomicLoadAdd8(i8 signext %incr) nounwind {
; MIPS64R6-NEXT: daddu $1, $1, $25
; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd8)))
; MIPS64R6-NEXT: ld $1, %got_disp(y)($1)
-; MIPS64R6-NEXT: daddiu $2, $zero, -4
-; MIPS64R6-NEXT: and $3, $1, $2
-; MIPS64R6-NEXT: andi $1, $1, 3
-; MIPS64R6-NEXT: sll $1, $1, 3
-; MIPS64R6-NEXT: ori $2, $zero, 255
-; MIPS64R6-NEXT: sllv $5, $2, $1
-; MIPS64R6-NEXT: nor $6, $zero, $5
-; MIPS64R6-NEXT: sllv $4, $4, $1
+; MIPS64R6-NEXT: sll $2, $1, 0
+; MIPS64R6-NEXT: andi $2, $2, 3
+; MIPS64R6-NEXT: daddiu $3, $zero, -4
+; MIPS64R6-NEXT: and $1, $1, $3
+; MIPS64R6-NEXT: sll $2, $2, 3
+; MIPS64R6-NEXT: addiu $3, $zero, 255
+; MIPS64R6-NEXT: sllv $3, $3, $2
+; MIPS64R6-NEXT: andi $4, $4, 255
+; MIPS64R6-NEXT: sllv $4, $4, $2
; MIPS64R6-NEXT: .LBB8_1: # %entry
; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R6-NEXT: ll $7, 0($3)
-; MIPS64R6-NEXT: addu $8, $7, $4
-; MIPS64R6-NEXT: and $8, $8, $5
-; MIPS64R6-NEXT: and $9, $7, $6
-; MIPS64R6-NEXT: or $9, $9, $8
-; MIPS64R6-NEXT: sc $9, 0($3)
-; MIPS64R6-NEXT: beqzc $9, .LBB8_1
+; MIPS64R6-NEXT: ll $5, 0($1)
+; MIPS64R6-NEXT: addu $6, $5, $4
+; MIPS64R6-NEXT: xor $6, $5, $6
+; MIPS64R6-NEXT: and $6, $6, $3
+; MIPS64R6-NEXT: xor $6, $5, $6
+; MIPS64R6-NEXT: sc $6, 0($1)
+; MIPS64R6-NEXT: beqzc $6, .LBB8_1
; MIPS64R6-NEXT: # %bb.2: # %entry
-; MIPS64R6-NEXT: and $2, $7, $5
-; MIPS64R6-NEXT: srlv $2, $2, $1
-; MIPS64R6-NEXT: seb $2, $2
-; MIPS64R6-NEXT: # %bb.3: # %entry
-; MIPS64R6-NEXT: jrc $ra
+; MIPS64R6-NEXT: srlv $1, $5, $2
+; MIPS64R6-NEXT: jr $ra
+; MIPS64R6-NEXT: seb $2, $1
;
; MIPS64R6O0-LABEL: AtomicLoadAdd8:
; MIPS64R6O0: # %bb.0: # %entry
-; MIPS64R6O0-NEXT: daddiu $sp, $sp, -16
; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd8)))
; MIPS64R6O0-NEXT: daddu $1, $1, $25
; MIPS64R6O0-NEXT: daddiu $2, $1, %lo(%neg(%gp_rel(AtomicLoadAdd8)))
; MIPS64R6O0-NEXT: move $1, $4
; MIPS64R6O0-NEXT: ld $2, %got_disp(y)($2)
; MIPS64R6O0-NEXT: daddiu $3, $zero, -4
-; MIPS64R6O0-NEXT: and $5, $2, $3
+; MIPS64R6O0-NEXT: and $4, $2, $3
+; MIPS64R6O0-NEXT: # kill: def $v0 killed $v0 killed $v0_64
+; MIPS64R6O0-NEXT: sll $2, $2, 0
+; MIPS64R6O0-NEXT: not $2, $2
; MIPS64R6O0-NEXT: andi $2, $2, 3
-; MIPS64R6O0-NEXT: xori $2, $2, 3
-; MIPS64R6O0-NEXT: sll $9, $2, 3
-; MIPS64R6O0-NEXT: ori $2, $zero, 255
-; MIPS64R6O0-NEXT: sllv $7, $2, $9
-; MIPS64R6O0-NEXT: nor $8, $zero, $7
-; MIPS64R6O0-NEXT: sllv $6, $1, $9
+; MIPS64R6O0-NEXT: sll $2, $2, 3
+; MIPS64R6O0-NEXT: addiu $3, $zero, 255
+; MIPS64R6O0-NEXT: sllv $6, $3, $2
+; MIPS64R6O0-NEXT: andi $1, $1, 255
+; MIPS64R6O0-NEXT: sllv $5, $1, $2
; MIPS64R6O0-NEXT: .LBB8_1: # %entry
; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R6O0-NEXT: ll $2, 0($5)
-; MIPS64R6O0-NEXT: addu $3, $2, $6
-; MIPS64R6O0-NEXT: and $3, $3, $7
-; MIPS64R6O0-NEXT: and $4, $2, $8
-; MIPS64R6O0-NEXT: or $4, $4, $3
-; MIPS64R6O0-NEXT: sc $4, 0($5)
-; MIPS64R6O0-NEXT: beqzc $4, .LBB8_1
+; MIPS64R6O0-NEXT: ll $1, 0($4)
+; MIPS64R6O0-NEXT: addu $3, $1, $5
+; MIPS64R6O0-NEXT: xor $3, $1, $3
+; MIPS64R6O0-NEXT: and $3, $3, $6
+; MIPS64R6O0-NEXT: xor $3, $1, $3
+; MIPS64R6O0-NEXT: sc $3, 0($4)
+; MIPS64R6O0-NEXT: beqzc $3, .LBB8_1
; MIPS64R6O0-NEXT: # %bb.2: # %entry
-; MIPS64R6O0-NEXT: and $1, $2, $7
-; MIPS64R6O0-NEXT: srlv $1, $1, $9
-; MIPS64R6O0-NEXT: seb $1, $1
-; MIPS64R6O0-NEXT: # %bb.3: # %entry
-; MIPS64R6O0-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64R6O0-NEXT: # %bb.4: # %entry
-; MIPS64R6O0-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
-; MIPS64R6O0-NEXT: daddiu $sp, $sp, 16
+; MIPS64R6O0-NEXT: srlv $1, $1, $2
+; MIPS64R6O0-NEXT: seb $2, $1
; MIPS64R6O0-NEXT: jrc $ra
;
; MM32-LABEL: AtomicLoadAdd8:
@@ -2578,96 +2545,88 @@ define signext i8 @AtomicLoadAdd8(i8 signext %incr) nounwind {
; MM32-NEXT: lui $2, %hi(_gp_disp)
; MM32-NEXT: addiu $2, $2, %lo(_gp_disp)
; MM32-NEXT: addu $2, $2, $25
-; MM32-NEXT: lw $1, %got(y)($2)
-; MM32-NEXT: addiu $2, $zero, -4
-; MM32-NEXT: and $3, $1, $2
-; MM32-NEXT: andi $1, $1, 3
-; MM32-NEXT: sll $1, $1, 3
-; MM32-NEXT: ori $2, $zero, 255
-; MM32-NEXT: sllv $5, $2, $1
-; MM32-NEXT: nor $6, $zero, $5
-; MM32-NEXT: sllv $4, $4, $1
+; MM32-NEXT: addiu $3, $zero, -4
+; MM32-NEXT: lw $2, %got(y)($2)
+; MM32-NEXT: and16 $3, $2
+; MM32-NEXT: andi16 $2, $2, 3
+; MM32-NEXT: sll16 $2, $2, 3
+; MM32-NEXT: addiu $1, $zero, 255
+; MM32-NEXT: sllv $1, $1, $2
+; MM32-NEXT: andi16 $4, $4, 255
+; MM32-NEXT: sllv $4, $4, $2
; MM32-NEXT: $BB8_1: # %entry
; MM32-NEXT: # =>This Inner Loop Header: Depth=1
-; MM32-NEXT: ll $7, 0($3)
-; MM32-NEXT: addu $8, $7, $4
-; MM32-NEXT: and $8, $8, $5
-; MM32-NEXT: and $9, $7, $6
-; MM32-NEXT: or $9, $9, $8
-; MM32-NEXT: sc $9, 0($3)
-; MM32-NEXT: beqzc $9, $BB8_1
+; MM32-NEXT: ll $5, 0($3)
+; MM32-NEXT: addu16 $6, $5, $4
+; MM32-NEXT: xor16 $6, $5
+; MM32-NEXT: and $6, $6, $1
+; MM32-NEXT: xor16 $6, $5
+; MM32-NEXT: sc $6, 0($3)
+; MM32-NEXT: beqzc $6, $BB8_1
; MM32-NEXT: # %bb.2: # %entry
-; MM32-NEXT: and $2, $7, $5
-; MM32-NEXT: srlv $2, $2, $1
-; MM32-NEXT: seb $2, $2
-; MM32-NEXT: # %bb.3: # %entry
-; MM32-NEXT: jrc $ra
+; MM32-NEXT: srlv $1, $5, $2
+; MM32-NEXT: jr $ra
+; MM32-NEXT: seb $2, $1
;
; O1-LABEL: AtomicLoadAdd8:
; O1: # %bb.0: # %entry
; O1-NEXT: lui $2, %hi(_gp_disp)
; O1-NEXT: addiu $2, $2, %lo(_gp_disp)
; O1-NEXT: addu $1, $2, $25
-; O1-NEXT: lw $1, %got(y)($1)
; O1-NEXT: addiu $2, $zero, -4
-; O1-NEXT: and $3, $1, $2
+; O1-NEXT: lw $1, %got(y)($1)
+; O1-NEXT: and $2, $1, $2
; O1-NEXT: andi $1, $1, 3
; O1-NEXT: sll $1, $1, 3
-; O1-NEXT: ori $2, $zero, 255
-; O1-NEXT: sllv $5, $2, $1
-; O1-NEXT: nor $6, $zero, $5
+; O1-NEXT: addiu $3, $zero, 255
+; O1-NEXT: sllv $3, $3, $1
+; O1-NEXT: andi $4, $4, 255
; O1-NEXT: sllv $4, $4, $1
; O1-NEXT: $BB8_1: # %entry
; O1-NEXT: # =>This Inner Loop Header: Depth=1
-; O1-NEXT: ll $7, 0($3)
-; O1-NEXT: addu $8, $7, $4
-; O1-NEXT: and $8, $8, $5
-; O1-NEXT: and $9, $7, $6
-; O1-NEXT: or $9, $9, $8
-; O1-NEXT: sc $9, 0($3)
-; O1-NEXT: beqz $9, $BB8_1
+; O1-NEXT: ll $5, 0($2)
+; O1-NEXT: addu $6, $5, $4
+; O1-NEXT: xor $6, $5, $6
+; O1-NEXT: and $6, $6, $3
+; O1-NEXT: xor $6, $5, $6
+; O1-NEXT: sc $6, 0($2)
+; O1-NEXT: beqz $6, $BB8_1
; O1-NEXT: nop
; O1-NEXT: # %bb.2: # %entry
-; O1-NEXT: and $2, $7, $5
-; O1-NEXT: srlv $2, $2, $1
-; O1-NEXT: sll $2, $2, 24
-; O1-NEXT: sra $2, $2, 24
-; O1-NEXT: # %bb.3: # %entry
+; O1-NEXT: srlv $1, $5, $1
+; O1-NEXT: sll $1, $1, 24
; O1-NEXT: jr $ra
-; O1-NEXT: nop
+; O1-NEXT: sra $2, $1, 24
;
; O2-LABEL: AtomicLoadAdd8:
; O2: # %bb.0: # %entry
; O2-NEXT: lui $2, %hi(_gp_disp)
; O2-NEXT: addiu $2, $2, %lo(_gp_disp)
; O2-NEXT: addu $1, $2, $25
-; O2-NEXT: lw $1, %got(y)($1)
; O2-NEXT: addiu $2, $zero, -4
-; O2-NEXT: and $3, $1, $2
+; O2-NEXT: lw $1, %got(y)($1)
+; O2-NEXT: and $2, $1, $2
; O2-NEXT: andi $1, $1, 3
; O2-NEXT: sll $1, $1, 3
-; O2-NEXT: ori $2, $zero, 255
-; O2-NEXT: sllv $5, $2, $1
-; O2-NEXT: nor $6, $zero, $5
+; O2-NEXT: addiu $3, $zero, 255
+; O2-NEXT: sllv $3, $3, $1
+; O2-NEXT: andi $4, $4, 255
; O2-NEXT: sllv $4, $4, $1
; O2-NEXT: $BB8_1: # %entry
; O2-NEXT: # =>This Inner Loop Header: Depth=1
-; O2-NEXT: ll $7, 0($3)
-; O2-NEXT: addu $8, $7, $4
-; O2-NEXT: and $8, $8, $5
-; O2-NEXT: and $9, $7, $6
-; O2-NEXT: or $9, $9, $8
-; O2-NEXT: sc $9, 0($3)
-; O2-NEXT: beqz $9, $BB8_1
+; O2-NEXT: ll $5, 0($2)
+; O2-NEXT: addu $6, $5, $4
+; O2-NEXT: xor $6, $5, $6
+; O2-NEXT: and $6, $6, $3
+; O2-NEXT: xor $6, $5, $6
+; O2-NEXT: sc $6, 0($2)
+; O2-NEXT: beqz $6, $BB8_1
; O2-NEXT: nop
; O2-NEXT: # %bb.2: # %entry
-; O2-NEXT: and $2, $7, $5
-; O2-NEXT: srlv $2, $2, $1
-; O2-NEXT: sll $2, $2, 24
-; O2-NEXT: sra $2, $2, 24
-; O2-NEXT: # %bb.3: # %entry
+; O2-NEXT: srlv $1, $5, $1
+; O2-NEXT: sll $1, $1, 24
; O2-NEXT: jr $ra
-; O2-NEXT: nop
+; O2-NEXT: sra $2, $1, 24
;
; O3-LABEL: AtomicLoadAdd8:
; O3: # %bb.0: # %entry
@@ -2675,32 +2634,29 @@ define signext i8 @AtomicLoadAdd8(i8 signext %incr) nounwind {
; O3-NEXT: addiu $2, $2, %lo(_gp_disp)
; O3-NEXT: addu $1, $2, $25
; O3-NEXT: addiu $2, $zero, -4
+; O3-NEXT: addiu $3, $zero, 255
+; O3-NEXT: andi $4, $4, 255
; O3-NEXT: lw $1, %got(y)($1)
-; O3-NEXT: and $3, $1, $2
+; O3-NEXT: and $2, $1, $2
; O3-NEXT: andi $1, $1, 3
-; O3-NEXT: ori $2, $zero, 255
; O3-NEXT: sll $1, $1, 3
-; O3-NEXT: sllv $5, $2, $1
+; O3-NEXT: sllv $3, $3, $1
; O3-NEXT: sllv $4, $4, $1
-; O3-NEXT: nor $6, $zero, $5
; O3-NEXT: $BB8_1: # %entry
; O3-NEXT: # =>This Inner Loop Header: Depth=1
-; O3-NEXT: ll $7, 0($3)
-; O3-NEXT: addu $8, $7, $4
-; O3-NEXT: and $8, $8, $5
-; O3-NEXT: and $9, $7, $6
-; O3-NEXT: or $9, $9, $8
-; O3-NEXT: sc $9, 0($3)
-; O3-NEXT: beqz $9, $BB8_1
+; O3-NEXT: ll $5, 0($2)
+; O3-NEXT: addu $6, $5, $4
+; O3-NEXT: xor $6, $5, $6
+; O3-NEXT: and $6, $6, $3
+; O3-NEXT: xor $6, $5, $6
+; O3-NEXT: sc $6, 0($2)
+; O3-NEXT: beqz $6, $BB8_1
; O3-NEXT: nop
; O3-NEXT: # %bb.2: # %entry
-; O3-NEXT: and $2, $7, $5
-; O3-NEXT: srlv $2, $2, $1
-; O3-NEXT: sll $2, $2, 24
-; O3-NEXT: sra $2, $2, 24
-; O3-NEXT: # %bb.3: # %entry
+; O3-NEXT: srlv $1, $5, $1
+; O3-NEXT: sll $1, $1, 24
; O3-NEXT: jr $ra
-; O3-NEXT: nop
+; O3-NEXT: sra $2, $1, 24
;
; MIPS32EB-LABEL: AtomicLoadAdd8:
; MIPS32EB: # %bb.0: # %entry
@@ -2708,33 +2664,30 @@ define signext i8 @AtomicLoadAdd8(i8 signext %incr) nounwind {
; MIPS32EB-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32EB-NEXT: addu $1, $2, $25
; MIPS32EB-NEXT: lw $1, %got(y)($1)
-; MIPS32EB-NEXT: addiu $2, $zero, -4
-; MIPS32EB-NEXT: and $3, $1, $2
-; MIPS32EB-NEXT: andi $1, $1, 3
-; MIPS32EB-NEXT: xori $1, $1, 3
-; MIPS32EB-NEXT: sll $1, $1, 3
-; MIPS32EB-NEXT: ori $2, $zero, 255
-; MIPS32EB-NEXT: sllv $5, $2, $1
-; MIPS32EB-NEXT: nor $6, $zero, $5
-; MIPS32EB-NEXT: sllv $4, $4, $1
+; MIPS32EB-NEXT: not $2, $1
+; MIPS32EB-NEXT: addiu $3, $zero, -4
+; MIPS32EB-NEXT: and $1, $1, $3
+; MIPS32EB-NEXT: andi $2, $2, 3
+; MIPS32EB-NEXT: sll $2, $2, 3
+; MIPS32EB-NEXT: addiu $3, $zero, 255
+; MIPS32EB-NEXT: sllv $3, $3, $2
+; MIPS32EB-NEXT: andi $4, $4, 255
+; MIPS32EB-NEXT: sllv $4, $4, $2
; MIPS32EB-NEXT: $BB8_1: # %entry
; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32EB-NEXT: ll $7, 0($3)
-; MIPS32EB-NEXT: addu $8, $7, $4
-; MIPS32EB-NEXT: and $8, $8, $5
-; MIPS32EB-NEXT: and $9, $7, $6
-; MIPS32EB-NEXT: or $9, $9, $8
-; MIPS32EB-NEXT: sc $9, 0($3)
-; MIPS32EB-NEXT: beqz $9, $BB8_1
+; MIPS32EB-NEXT: ll $5, 0($1)
+; MIPS32EB-NEXT: addu $6, $5, $4
+; MIPS32EB-NEXT: xor $6, $5, $6
+; MIPS32EB-NEXT: and $6, $6, $3
+; MIPS32EB-NEXT: xor $6, $5, $6
+; MIPS32EB-NEXT: sc $6, 0($1)
+; MIPS32EB-NEXT: beqz $6, $BB8_1
; MIPS32EB-NEXT: nop
; MIPS32EB-NEXT: # %bb.2: # %entry
-; MIPS32EB-NEXT: and $2, $7, $5
-; MIPS32EB-NEXT: srlv $2, $2, $1
-; MIPS32EB-NEXT: sll $2, $2, 24
-; MIPS32EB-NEXT: sra $2, $2, 24
-; MIPS32EB-NEXT: # %bb.3: # %entry
+; MIPS32EB-NEXT: srlv $1, $5, $2
+; MIPS32EB-NEXT: sll $1, $1, 24
; MIPS32EB-NEXT: jr $ra
-; MIPS32EB-NEXT: nop
+; MIPS32EB-NEXT: sra $2, $1, 24
entry:
%0 = atomicrmw add ptr @y, i8 %incr monotonic
ret i8 %0
@@ -2746,71 +2699,62 @@ define signext i8 @AtomicLoadSub8(i8 signext %incr) nounwind {
; MIPS32-NEXT: lui $2, %hi(_gp_disp)
; MIPS32-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32-NEXT: addu $1, $2, $25
-; MIPS32-NEXT: lw $1, %got(y)($1)
; MIPS32-NEXT: addiu $2, $zero, -4
-; MIPS32-NEXT: and $3, $1, $2
+; MIPS32-NEXT: lw $1, %got(y)($1)
+; MIPS32-NEXT: and $2, $1, $2
; MIPS32-NEXT: andi $1, $1, 3
; MIPS32-NEXT: sll $1, $1, 3
-; MIPS32-NEXT: ori $2, $zero, 255
-; MIPS32-NEXT: sllv $5, $2, $1
-; MIPS32-NEXT: nor $6, $zero, $5
+; MIPS32-NEXT: addiu $3, $zero, 255
+; MIPS32-NEXT: sllv $3, $3, $1
+; MIPS32-NEXT: andi $4, $4, 255
; MIPS32-NEXT: sllv $4, $4, $1
; MIPS32-NEXT: $BB9_1: # %entry
; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32-NEXT: ll $7, 0($3)
-; MIPS32-NEXT: subu $8, $7, $4
-; MIPS32-NEXT: and $8, $8, $5
-; MIPS32-NEXT: and $9, $7, $6
-; MIPS32-NEXT: or $9, $9, $8
-; MIPS32-NEXT: sc $9, 0($3)
-; MIPS32-NEXT: beqz $9, $BB9_1
+; MIPS32-NEXT: ll $5, 0($2)
+; MIPS32-NEXT: subu $6, $5, $4
+; MIPS32-NEXT: xor $6, $5, $6
+; MIPS32-NEXT: and $6, $6, $3
+; MIPS32-NEXT: xor $6, $5, $6
+; MIPS32-NEXT: sc $6, 0($2)
+; MIPS32-NEXT: beqz $6, $BB9_1
; MIPS32-NEXT: nop
; MIPS32-NEXT: # %bb.2: # %entry
-; MIPS32-NEXT: and $2, $7, $5
-; MIPS32-NEXT: srlv $2, $2, $1
-; MIPS32-NEXT: sll $2, $2, 24
-; MIPS32-NEXT: sra $2, $2, 24
-; MIPS32-NEXT: # %bb.3: # %entry
+; MIPS32-NEXT: srlv $1, $5, $1
+; MIPS32-NEXT: sll $1, $1, 24
; MIPS32-NEXT: jr $ra
-; MIPS32-NEXT: nop
+; MIPS32-NEXT: sra $2, $1, 24
;
; MIPS32O0-LABEL: AtomicLoadSub8:
; MIPS32O0: # %bb.0: # %entry
; MIPS32O0-NEXT: lui $2, %hi(_gp_disp)
; MIPS32O0-NEXT: addiu $2, $2, %lo(_gp_disp)
-; MIPS32O0-NEXT: addiu $sp, $sp, -8
-; MIPS32O0-NEXT: addu $1, $2, $25
-; MIPS32O0-NEXT: lw $1, %got(y)($1)
-; MIPS32O0-NEXT: addiu $2, $zero, -4
-; MIPS32O0-NEXT: and $5, $1, $2
-; MIPS32O0-NEXT: andi $1, $1, 3
-; MIPS32O0-NEXT: sll $9, $1, 3
-; MIPS32O0-NEXT: ori $1, $zero, 255
-; MIPS32O0-NEXT: sllv $7, $1, $9
-; MIPS32O0-NEXT: nor $8, $zero, $7
-; MIPS32O0-NEXT: sllv $6, $4, $9
+; MIPS32O0-NEXT: addu $2, $2, $25
+; MIPS32O0-NEXT: move $1, $4
+; MIPS32O0-NEXT: lw $3, %got(y)($2)
+; MIPS32O0-NEXT: addiu $4, $zero, -4
+; MIPS32O0-NEXT: and $4, $3, $4
+; MIPS32O0-NEXT: lw $2, %got(y)($2)
+; MIPS32O0-NEXT: addiu $3, $zero, 3
+; MIPS32O0-NEXT: and $2, $2, $3
+; MIPS32O0-NEXT: sll $2, $2, 3
+; MIPS32O0-NEXT: addiu $3, $zero, 255
+; MIPS32O0-NEXT: sllv $6, $3, $2
+; MIPS32O0-NEXT: andi $1, $1, 255
+; MIPS32O0-NEXT: sllv $5, $1, $2
; MIPS32O0-NEXT: $BB9_1: # %entry
; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32O0-NEXT: ll $2, 0($5)
-; MIPS32O0-NEXT: subu $3, $2, $6
-; MIPS32O0-NEXT: and $3, $3, $7
-; MIPS32O0-NEXT: and $4, $2, $8
-; MIPS32O0-NEXT: or $4, $4, $3
-; MIPS32O0-NEXT: sc $4, 0($5)
-; MIPS32O0-NEXT: beqz $4, $BB9_1
+; MIPS32O0-NEXT: ll $1, 0($4)
+; MIPS32O0-NEXT: subu $3, $1, $5
+; MIPS32O0-NEXT: xor $3, $1, $3
+; MIPS32O0-NEXT: and $3, $3, $6
+; MIPS32O0-NEXT: xor $3, $1, $3
+; MIPS32O0-NEXT: sc $3, 0($4)
+; MIPS32O0-NEXT: beqz $3, $BB9_1
; MIPS32O0-NEXT: nop
; MIPS32O0-NEXT: # %bb.2: # %entry
-; MIPS32O0-NEXT: and $1, $2, $7
-; MIPS32O0-NEXT: srlv $1, $1, $9
-; MIPS32O0-NEXT: sll $1, $1, 24
-; MIPS32O0-NEXT: sra $1, $1, 24
-; MIPS32O0-NEXT: # %bb.3: # %entry
-; MIPS32O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32O0-NEXT: # %bb.4: # %entry
-; MIPS32O0-NEXT: lw $1, 4($sp) # 4-byte Folded Reload
+; MIPS32O0-NEXT: srlv $1, $1, $2
; MIPS32O0-NEXT: sll $1, $1, 24
; MIPS32O0-NEXT: sra $2, $1, 24
-; MIPS32O0-NEXT: addiu $sp, $sp, 8
; MIPS32O0-NEXT: jr $ra
; MIPS32O0-NEXT: nop
;
@@ -2819,96 +2763,85 @@ define signext i8 @AtomicLoadSub8(i8 signext %incr) nounwind {
; MIPS32R2-NEXT: lui $2, %hi(_gp_disp)
; MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32R2-NEXT: addu $1, $2, $25
-; MIPS32R2-NEXT: lw $1, %got(y)($1)
; MIPS32R2-NEXT: addiu $2, $zero, -4
-; MIPS32R2-NEXT: and $3, $1, $2
+; MIPS32R2-NEXT: lw $1, %got(y)($1)
+; MIPS32R2-NEXT: and $2, $1, $2
; MIPS32R2-NEXT: andi $1, $1, 3
; MIPS32R2-NEXT: sll $1, $1, 3
-; MIPS32R2-NEXT: ori $2, $zero, 255
-; MIPS32R2-NEXT: sllv $5, $2, $1
-; MIPS32R2-NEXT: nor $6, $zero, $5
+; MIPS32R2-NEXT: addiu $3, $zero, 255
+; MIPS32R2-NEXT: sllv $3, $3, $1
+; MIPS32R2-NEXT: andi $4, $4, 255
; MIPS32R2-NEXT: sllv $4, $4, $1
; MIPS32R2-NEXT: $BB9_1: # %entry
; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32R2-NEXT: ll $7, 0($3)
-; MIPS32R2-NEXT: subu $8, $7, $4
-; MIPS32R2-NEXT: and $8, $8, $5
-; MIPS32R2-NEXT: and $9, $7, $6
-; MIPS32R2-NEXT: or $9, $9, $8
-; MIPS32R2-NEXT: sc $9, 0($3)
-; MIPS32R2-NEXT: beqz $9, $BB9_1
+; MIPS32R2-NEXT: ll $5, 0($2)
+; MIPS32R2-NEXT: subu $6, $5, $4
+; MIPS32R2-NEXT: xor $6, $5, $6
+; MIPS32R2-NEXT: and $6, $6, $3
+; MIPS32R2-NEXT: xor $6, $5, $6
+; MIPS32R2-NEXT: sc $6, 0($2)
+; MIPS32R2-NEXT: beqz $6, $BB9_1
; MIPS32R2-NEXT: nop
; MIPS32R2-NEXT: # %bb.2: # %entry
-; MIPS32R2-NEXT: and $2, $7, $5
-; MIPS32R2-NEXT: srlv $2, $2, $1
-; MIPS32R2-NEXT: seb $2, $2
-; MIPS32R2-NEXT: # %bb.3: # %entry
+; MIPS32R2-NEXT: srlv $1, $5, $1
; MIPS32R2-NEXT: jr $ra
-; MIPS32R2-NEXT: nop
+; MIPS32R2-NEXT: seb $2, $1
;
; MIPS32R6-LABEL: AtomicLoadSub8:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lui $2, %hi(_gp_disp)
; MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32R6-NEXT: addu $1, $2, $25
-; MIPS32R6-NEXT: lw $1, %got(y)($1)
; MIPS32R6-NEXT: addiu $2, $zero, -4
-; MIPS32R6-NEXT: and $3, $1, $2
+; MIPS32R6-NEXT: lw $1, %got(y)($1)
+; MIPS32R6-NEXT: and $2, $1, $2
; MIPS32R6-NEXT: andi $1, $1, 3
; MIPS32R6-NEXT: sll $1, $1, 3
-; MIPS32R6-NEXT: ori $2, $zero, 255
-; MIPS32R6-NEXT: sllv $5, $2, $1
-; MIPS32R6-NEXT: nor $6, $zero, $5
+; MIPS32R6-NEXT: addiu $3, $zero, 255
+; MIPS32R6-NEXT: sllv $3, $3, $1
+; MIPS32R6-NEXT: andi $4, $4, 255
; MIPS32R6-NEXT: sllv $4, $4, $1
; MIPS32R6-NEXT: $BB9_1: # %entry
; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32R6-NEXT: ll $7, 0($3)
-; MIPS32R6-NEXT: subu $8, $7, $4
-; MIPS32R6-NEXT: and $8, $8, $5
-; MIPS32R6-NEXT: and $9, $7, $6
-; MIPS32R6-NEXT: or $9, $9, $8
-; MIPS32R6-NEXT: sc $9, 0($3)
-; MIPS32R6-NEXT: beqzc $9, $BB9_1
+; MIPS32R6-NEXT: ll $5, 0($2)
+; MIPS32R6-NEXT: subu $6, $5, $4
+; MIPS32R6-NEXT: xor $6, $5, $6
+; MIPS32R6-NEXT: and $6, $6, $3
+; MIPS32R6-NEXT: xor $6, $5, $6
+; MIPS32R6-NEXT: sc $6, 0($2)
+; MIPS32R6-NEXT: beqzc $6, $BB9_1
; MIPS32R6-NEXT: # %bb.2: # %entry
-; MIPS32R6-NEXT: and $2, $7, $5
-; MIPS32R6-NEXT: srlv $2, $2, $1
-; MIPS32R6-NEXT: seb $2, $2
-; MIPS32R6-NEXT: # %bb.3: # %entry
-; MIPS32R6-NEXT: jrc $ra
+; MIPS32R6-NEXT: srlv $1, $5, $1
+; MIPS32R6-NEXT: jr $ra
+; MIPS32R6-NEXT: seb $2, $1
;
; MIPS32R6O0-LABEL: AtomicLoadSub8:
; MIPS32R6O0: # %bb.0: # %entry
; MIPS32R6O0-NEXT: lui $2, %hi(_gp_disp)
; MIPS32R6O0-NEXT: addiu $2, $2, %lo(_gp_disp)
-; MIPS32R6O0-NEXT: addiu $sp, $sp, -8
-; MIPS32R6O0-NEXT: addu $1, $2, $25
-; MIPS32R6O0-NEXT: lw $1, %got(y)($1)
-; MIPS32R6O0-NEXT: addiu $2, $zero, -4
-; MIPS32R6O0-NEXT: and $5, $1, $2
-; MIPS32R6O0-NEXT: andi $1, $1, 3
-; MIPS32R6O0-NEXT: sll $9, $1, 3
-; MIPS32R6O0-NEXT: ori $1, $zero, 255
-; MIPS32R6O0-NEXT: sllv $7, $1, $9
-; MIPS32R6O0-NEXT: nor $8, $zero, $7
-; MIPS32R6O0-NEXT: sllv $6, $4, $9
+; MIPS32R6O0-NEXT: addu $2, $2, $25
+; MIPS32R6O0-NEXT: move $1, $4
+; MIPS32R6O0-NEXT: lw $2, %got(y)($2)
+; MIPS32R6O0-NEXT: addiu $3, $zero, -4
+; MIPS32R6O0-NEXT: and $4, $2, $3
+; MIPS32R6O0-NEXT: andi $2, $2, 3
+; MIPS32R6O0-NEXT: sll $2, $2, 3
+; MIPS32R6O0-NEXT: addiu $3, $zero, 255
+; MIPS32R6O0-NEXT: sllv $6, $3, $2
+; MIPS32R6O0-NEXT: andi $1, $1, 255
+; MIPS32R6O0-NEXT: sllv $5, $1, $2
; MIPS32R6O0-NEXT: $BB9_1: # %entry
; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32R6O0-NEXT: ll $2, 0($5)
-; MIPS32R6O0-NEXT: subu $3, $2, $6
-; MIPS32R6O0-NEXT: and $3, $3, $7
-; MIPS32R6O0-NEXT: and $4, $2, $8
-; MIPS32R6O0-NEXT: or $4, $4, $3
-; MIPS32R6O0-NEXT: sc $4, 0($5)
-; MIPS32R6O0-NEXT: beqzc $4, $BB9_1
+; MIPS32R6O0-NEXT: ll $1, 0($4)
+; MIPS32R6O0-NEXT: subu $3, $1, $5
+; MIPS32R6O0-NEXT: xor $3, $1, $3
+; MIPS32R6O0-NEXT: and $3, $3, $6
+; MIPS32R6O0-NEXT: xor $3, $1, $3
+; MIPS32R6O0-NEXT: sc $3, 0($4)
+; MIPS32R6O0-NEXT: beqzc $3, $BB9_1
; MIPS32R6O0-NEXT: # %bb.2: # %entry
-; MIPS32R6O0-NEXT: and $1, $2, $7
-; MIPS32R6O0-NEXT: srlv $1, $1, $9
-; MIPS32R6O0-NEXT: seb $1, $1
-; MIPS32R6O0-NEXT: # %bb.3: # %entry
-; MIPS32R6O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32R6O0-NEXT: # %bb.4: # %entry
-; MIPS32R6O0-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
-; MIPS32R6O0-NEXT: addiu $sp, $sp, 8
+; MIPS32R6O0-NEXT: srlv $1, $1, $2
+; MIPS32R6O0-NEXT: seb $2, $1
; MIPS32R6O0-NEXT: jrc $ra
;
; MIPS4-LABEL: AtomicLoadSub8:
@@ -2917,32 +2850,30 @@ define signext i8 @AtomicLoadSub8(i8 signext %incr) nounwind {
; MIPS4-NEXT: daddu $1, $1, $25
; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadSub8)))
; MIPS4-NEXT: ld $1, %got_disp(y)($1)
-; MIPS4-NEXT: daddiu $2, $zero, -4
-; MIPS4-NEXT: and $3, $1, $2
-; MIPS4-NEXT: andi $1, $1, 3
-; MIPS4-NEXT: sll $1, $1, 3
-; MIPS4-NEXT: ori $2, $zero, 255
-; MIPS4-NEXT: sllv $5, $2, $1
-; MIPS4-NEXT: nor $6, $zero, $5
-; MIPS4-NEXT: sllv $4, $4, $1
+; MIPS4-NEXT: sll $2, $1, 0
+; MIPS4-NEXT: andi $2, $2, 3
+; MIPS4-NEXT: daddiu $3, $zero, -4
+; MIPS4-NEXT: and $1, $1, $3
+; MIPS4-NEXT: sll $2, $2, 3
+; MIPS4-NEXT: addiu $3, $zero, 255
+; MIPS4-NEXT: sllv $3, $3, $2
+; MIPS4-NEXT: andi $4, $4, 255
+; MIPS4-NEXT: sllv $4, $4, $2
; MIPS4-NEXT: .LBB9_1: # %entry
; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS4-NEXT: ll $7, 0($3)
-; MIPS4-NEXT: subu $8, $7, $4
-; MIPS4-NEXT: and $8, $8, $5
-; MIPS4-NEXT: and $9, $7, $6
-; MIPS4-NEXT: or $9, $9, $8
-; MIPS4-NEXT: sc $9, 0($3)
-; MIPS4-NEXT: beqz $9, .LBB9_1
+; MIPS4-NEXT: ll $5, 0($1)
+; MIPS4-NEXT: subu $6, $5, $4
+; MIPS4-NEXT: xor $6, $5, $6
+; MIPS4-NEXT: and $6, $6, $3
+; MIPS4-NEXT: xor $6, $5, $6
+; MIPS4-NEXT: sc $6, 0($1)
+; MIPS4-NEXT: beqz $6, .LBB9_1
; MIPS4-NEXT: nop
; MIPS4-NEXT: # %bb.2: # %entry
-; MIPS4-NEXT: and $2, $7, $5
-; MIPS4-NEXT: srlv $2, $2, $1
-; MIPS4-NEXT: sll $2, $2, 24
-; MIPS4-NEXT: sra $2, $2, 24
-; MIPS4-NEXT: # %bb.3: # %entry
+; MIPS4-NEXT: srlv $1, $5, $2
+; MIPS4-NEXT: sll $1, $1, 24
; MIPS4-NEXT: jr $ra
-; MIPS4-NEXT: nop
+; MIPS4-NEXT: sra $2, $1, 24
;
; MIPS64-LABEL: AtomicLoadSub8:
; MIPS64: # %bb.0: # %entry
@@ -2950,32 +2881,30 @@ define signext i8 @AtomicLoadSub8(i8 signext %incr) nounwind {
; MIPS64-NEXT: daddu $1, $1, $25
; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadSub8)))
; MIPS64-NEXT: ld $1, %got_disp(y)($1)
-; MIPS64-NEXT: daddiu $2, $zero, -4
-; MIPS64-NEXT: and $3, $1, $2
-; MIPS64-NEXT: andi $1, $1, 3
-; MIPS64-NEXT: sll $1, $1, 3
-; MIPS64-NEXT: ori $2, $zero, 255
-; MIPS64-NEXT: sllv $5, $2, $1
-; MIPS64-NEXT: nor $6, $zero, $5
-; MIPS64-NEXT: sllv $4, $4, $1
+; MIPS64-NEXT: sll $2, $1, 0
+; MIPS64-NEXT: andi $2, $2, 3
+; MIPS64-NEXT: daddiu $3, $zero, -4
+; MIPS64-NEXT: and $1, $1, $3
+; MIPS64-NEXT: sll $2, $2, 3
+; MIPS64-NEXT: addiu $3, $zero, 255
+; MIPS64-NEXT: sllv $3, $3, $2
+; MIPS64-NEXT: andi $4, $4, 255
+; MIPS64-NEXT: sllv $4, $4, $2
; MIPS64-NEXT: .LBB9_1: # %entry
; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64-NEXT: ll $7, 0($3)
-; MIPS64-NEXT: subu $8, $7, $4
-; MIPS64-NEXT: and $8, $8, $5
-; MIPS64-NEXT: and $9, $7, $6
-; MIPS64-NEXT: or $9, $9, $8
-; MIPS64-NEXT: sc $9, 0($3)
-; MIPS64-NEXT: beqz $9, .LBB9_1
+; MIPS64-NEXT: ll $5, 0($1)
+; MIPS64-NEXT: subu $6, $5, $4
+; MIPS64-NEXT: xor $6, $5, $6
+; MIPS64-NEXT: and $6, $6, $3
+; MIPS64-NEXT: xor $6, $5, $6
+; MIPS64-NEXT: sc $6, 0($1)
+; MIPS64-NEXT: beqz $6, .LBB9_1
; MIPS64-NEXT: nop
; MIPS64-NEXT: # %bb.2: # %entry
-; MIPS64-NEXT: and $2, $7, $5
-; MIPS64-NEXT: srlv $2, $2, $1
-; MIPS64-NEXT: sll $2, $2, 24
-; MIPS64-NEXT: sra $2, $2, 24
-; MIPS64-NEXT: # %bb.3: # %entry
+; MIPS64-NEXT: srlv $1, $5, $2
+; MIPS64-NEXT: sll $1, $1, 24
; MIPS64-NEXT: jr $ra
-; MIPS64-NEXT: nop
+; MIPS64-NEXT: sra $2, $1, 24
;
; MIPS64R2-LABEL: AtomicLoadSub8:
; MIPS64R2: # %bb.0: # %entry
@@ -2983,31 +2912,29 @@ define signext i8 @AtomicLoadSub8(i8 signext %incr) nounwind {
; MIPS64R2-NEXT: daddu $1, $1, $25
; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadSub8)))
; MIPS64R2-NEXT: ld $1, %got_disp(y)($1)
-; MIPS64R2-NEXT: daddiu $2, $zero, -4
-; MIPS64R2-NEXT: and $3, $1, $2
-; MIPS64R2-NEXT: andi $1, $1, 3
-; MIPS64R2-NEXT: sll $1, $1, 3
-; MIPS64R2-NEXT: ori $2, $zero, 255
-; MIPS64R2-NEXT: sllv $5, $2, $1
-; MIPS64R2-NEXT: nor $6, $zero, $5
-; MIPS64R2-NEXT: sllv $4, $4, $1
+; MIPS64R2-NEXT: sll $2, $1, 0
+; MIPS64R2-NEXT: andi $2, $2, 3
+; MIPS64R2-NEXT: daddiu $3, $zero, -4
+; MIPS64R2-NEXT: and $1, $1, $3
+; MIPS64R2-NEXT: sll $2, $2, 3
+; MIPS64R2-NEXT: addiu $3, $zero, 255
+; MIPS64R2-NEXT: sllv $3, $3, $2
+; MIPS64R2-NEXT: andi $4, $4, 255
+; MIPS64R2-NEXT: sllv $4, $4, $2
; MIPS64R2-NEXT: .LBB9_1: # %entry
; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R2-NEXT: ll $7, 0($3)
-; MIPS64R2-NEXT: subu $8, $7, $4
-; MIPS64R2-NEXT: and $8, $8, $5
-; MIPS64R2-NEXT: and $9, $7, $6
-; MIPS64R2-NEXT: or $9, $9, $8
-; MIPS64R2-NEXT: sc $9, 0($3)
-; MIPS64R2-NEXT: beqz $9, .LBB9_1
+; MIPS64R2-NEXT: ll $5, 0($1)
+; MIPS64R2-NEXT: subu $6, $5, $4
+; MIPS64R2-NEXT: xor $6, $5, $6
+; MIPS64R2-NEXT: and $6, $6, $3
+; MIPS64R2-NEXT: xor $6, $5, $6
+; MIPS64R2-NEXT: sc $6, 0($1)
+; MIPS64R2-NEXT: beqz $6, .LBB9_1
; MIPS64R2-NEXT: nop
; MIPS64R2-NEXT: # %bb.2: # %entry
-; MIPS64R2-NEXT: and $2, $7, $5
-; MIPS64R2-NEXT: srlv $2, $2, $1
-; MIPS64R2-NEXT: seb $2, $2
-; MIPS64R2-NEXT: # %bb.3: # %entry
+; MIPS64R2-NEXT: srlv $1, $5, $2
; MIPS64R2-NEXT: jr $ra
-; MIPS64R2-NEXT: nop
+; MIPS64R2-NEXT: seb $2, $1
;
; MIPS64R6-LABEL: AtomicLoadSub8:
; MIPS64R6: # %bb.0: # %entry
@@ -3015,65 +2942,59 @@ define signext i8 @AtomicLoadSub8(i8 signext %incr) nounwind {
; MIPS64R6-NEXT: daddu $1, $1, $25
; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadSub8)))
; MIPS64R6-NEXT: ld $1, %got_disp(y)($1)
-; MIPS64R6-NEXT: daddiu $2, $zero, -4
-; MIPS64R6-NEXT: and $3, $1, $2
-; MIPS64R6-NEXT: andi $1, $1, 3
-; MIPS64R6-NEXT: sll $1, $1, 3
-; MIPS64R6-NEXT: ori $2, $zero, 255
-; MIPS64R6-NEXT: sllv $5, $2, $1
-; MIPS64R6-NEXT: nor $6, $zero, $5
-; MIPS64R6-NEXT: sllv $4, $4, $1
+; MIPS64R6-NEXT: sll $2, $1, 0
+; MIPS64R6-NEXT: andi $2, $2, 3
+; MIPS64R6-NEXT: daddiu $3, $zero, -4
+; MIPS64R6-NEXT: and $1, $1, $3
+; MIPS64R6-NEXT: sll $2, $2, 3
+; MIPS64R6-NEXT: addiu $3, $zero, 255
+; MIPS64R6-NEXT: sllv $3, $3, $2
+; MIPS64R6-NEXT: andi $4, $4, 255
+; MIPS64R6-NEXT: sllv $4, $4, $2
; MIPS64R6-NEXT: .LBB9_1: # %entry
; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R6-NEXT: ll $7, 0($3)
-; MIPS64R6-NEXT: subu $8, $7, $4
-; MIPS64R6-NEXT: and $8, $8, $5
-; MIPS64R6-NEXT: and $9, $7, $6
-; MIPS64R6-NEXT: or $9, $9, $8
-; MIPS64R6-NEXT: sc $9, 0($3)
-; MIPS64R6-NEXT: beqzc $9, .LBB9_1
+; MIPS64R6-NEXT: ll $5, 0($1)
+; MIPS64R6-NEXT: subu $6, $5, $4
+; MIPS64R6-NEXT: xor $6, $5, $6
+; MIPS64R6-NEXT: and $6, $6, $3
+; MIPS64R6-NEXT: xor $6, $5, $6
+; MIPS64R6-NEXT: sc $6, 0($1)
+; MIPS64R6-NEXT: beqzc $6, .LBB9_1
; MIPS64R6-NEXT: # %bb.2: # %entry
-; MIPS64R6-NEXT: and $2, $7, $5
-; MIPS64R6-NEXT: srlv $2, $2, $1
-; MIPS64R6-NEXT: seb $2, $2
-; MIPS64R6-NEXT: # %bb.3: # %entry
-; MIPS64R6-NEXT: jrc $ra
+; MIPS64R6-NEXT: srlv $1, $5, $2
+; MIPS64R6-NEXT: jr $ra
+; MIPS64R6-NEXT: seb $2, $1
;
; MIPS64R6O0-LABEL: AtomicLoadSub8:
; MIPS64R6O0: # %bb.0: # %entry
-; MIPS64R6O0-NEXT: daddiu $sp, $sp, -16
; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadSub8)))
; MIPS64R6O0-NEXT: daddu $1, $1, $25
; MIPS64R6O0-NEXT: daddiu $2, $1, %lo(%neg(%gp_rel(AtomicLoadSub8)))
; MIPS64R6O0-NEXT: move $1, $4
; MIPS64R6O0-NEXT: ld $2, %got_disp(y)($2)
; MIPS64R6O0-NEXT: daddiu $3, $zero, -4
-; MIPS64R6O0-NEXT: and $5, $2, $3
+; MIPS64R6O0-NEXT: and $4, $2, $3
+; MIPS64R6O0-NEXT: # kill: def $v0 killed $v0 killed $v0_64
+; MIPS64R6O0-NEXT: sll $2, $2, 0
+; MIPS64R6O0-NEXT: not $2, $2
; MIPS64R6O0-NEXT: andi $2, $2, 3
-; MIPS64R6O0-NEXT: xori $2, $2, 3
-; MIPS64R6O0-NEXT: sll $9, $2, 3
-; MIPS64R6O0-NEXT: ori $2, $zero, 255
-; MIPS64R6O0-NEXT: sllv $7, $2, $9
-; MIPS64R6O0-NEXT: nor $8, $zero, $7
-; MIPS64R6O0-NEXT: sllv $6, $1, $9
+; MIPS64R6O0-NEXT: sll $2, $2, 3
+; MIPS64R6O0-NEXT: addiu $3, $zero, 255
+; MIPS64R6O0-NEXT: sllv $6, $3, $2
+; MIPS64R6O0-NEXT: andi $1, $1, 255
+; MIPS64R6O0-NEXT: sllv $5, $1, $2
; MIPS64R6O0-NEXT: .LBB9_1: # %entry
; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R6O0-NEXT: ll $2, 0($5)
-; MIPS64R6O0-NEXT: subu $3, $2, $6
-; MIPS64R6O0-NEXT: and $3, $3, $7
-; MIPS64R6O0-NEXT: and $4, $2, $8
-; MIPS64R6O0-NEXT: or $4, $4, $3
-; MIPS64R6O0-NEXT: sc $4, 0($5)
-; MIPS64R6O0-NEXT: beqzc $4, .LBB9_1
+; MIPS64R6O0-NEXT: ll $1, 0($4)
+; MIPS64R6O0-NEXT: subu $3, $1, $5
+; MIPS64R6O0-NEXT: xor $3, $1, $3
+; MIPS64R6O0-NEXT: and $3, $3, $6
+; MIPS64R6O0-NEXT: xor $3, $1, $3
+; MIPS64R6O0-NEXT: sc $3, 0($4)
+; MIPS64R6O0-NEXT: beqzc $3, .LBB9_1
; MIPS64R6O0-NEXT: # %bb.2: # %entry
-; MIPS64R6O0-NEXT: and $1, $2, $7
-; MIPS64R6O0-NEXT: srlv $1, $1, $9
-; MIPS64R6O0-NEXT: seb $1, $1
-; MIPS64R6O0-NEXT: # %bb.3: # %entry
-; MIPS64R6O0-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64R6O0-NEXT: # %bb.4: # %entry
-; MIPS64R6O0-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
-; MIPS64R6O0-NEXT: daddiu $sp, $sp, 16
+; MIPS64R6O0-NEXT: srlv $1, $1, $2
+; MIPS64R6O0-NEXT: seb $2, $1
; MIPS64R6O0-NEXT: jrc $ra
;
; MM32-LABEL: AtomicLoadSub8:
@@ -3081,96 +3002,88 @@ define signext i8 @AtomicLoadSub8(i8 signext %incr) nounwind {
; MM32-NEXT: lui $2, %hi(_gp_disp)
; MM32-NEXT: addiu $2, $2, %lo(_gp_disp)
; MM32-NEXT: addu $2, $2, $25
-; MM32-NEXT: lw $1, %got(y)($2)
-; MM32-NEXT: addiu $2, $zero, -4
-; MM32-NEXT: and $3, $1, $2
-; MM32-NEXT: andi $1, $1, 3
-; MM32-NEXT: sll $1, $1, 3
-; MM32-NEXT: ori $2, $zero, 255
-; MM32-NEXT: sllv $5, $2, $1
-; MM32-NEXT: nor $6, $zero, $5
-; MM32-NEXT: sllv $4, $4, $1
+; MM32-NEXT: addiu $3, $zero, -4
+; MM32-NEXT: lw $2, %got(y)($2)
+; MM32-NEXT: and16 $3, $2
+; MM32-NEXT: andi16 $2, $2, 3
+; MM32-NEXT: sll16 $2, $2, 3
+; MM32-NEXT: addiu $1, $zero, 255
+; MM32-NEXT: sllv $1, $1, $2
+; MM32-NEXT: andi16 $4, $4, 255
+; MM32-NEXT: sllv $4, $4, $2
; MM32-NEXT: $BB9_1: # %entry
; MM32-NEXT: # =>This Inner Loop Header: Depth=1
-; MM32-NEXT: ll $7, 0($3)
-; MM32-NEXT: subu $8, $7, $4
-; MM32-NEXT: and $8, $8, $5
-; MM32-NEXT: and $9, $7, $6
-; MM32-NEXT: or $9, $9, $8
-; MM32-NEXT: sc $9, 0($3)
-; MM32-NEXT: beqzc $9, $BB9_1
+; MM32-NEXT: ll $5, 0($3)
+; MM32-NEXT: subu16 $6, $5, $4
+; MM32-NEXT: xor16 $6, $5
+; MM32-NEXT: and $6, $6, $1
+; MM32-NEXT: xor16 $6, $5
+; MM32-NEXT: sc $6, 0($3)
+; MM32-NEXT: beqzc $6, $BB9_1
; MM32-NEXT: # %bb.2: # %entry
-; MM32-NEXT: and $2, $7, $5
-; MM32-NEXT: srlv $2, $2, $1
-; MM32-NEXT: seb $2, $2
-; MM32-NEXT: # %bb.3: # %entry
-; MM32-NEXT: jrc $ra
+; MM32-NEXT: srlv $1, $5, $2
+; MM32-NEXT: jr $ra
+; MM32-NEXT: seb $2, $1
;
; O1-LABEL: AtomicLoadSub8:
; O1: # %bb.0: # %entry
; O1-NEXT: lui $2, %hi(_gp_disp)
; O1-NEXT: addiu $2, $2, %lo(_gp_disp)
; O1-NEXT: addu $1, $2, $25
-; O1-NEXT: lw $1, %got(y)($1)
; O1-NEXT: addiu $2, $zero, -4
-; O1-NEXT: and $3, $1, $2
+; O1-NEXT: lw $1, %got(y)($1)
+; O1-NEXT: and $2, $1, $2
; O1-NEXT: andi $1, $1, 3
; O1-NEXT: sll $1, $1, 3
-; O1-NEXT: ori $2, $zero, 255
-; O1-NEXT: sllv $5, $2, $1
-; O1-NEXT: nor $6, $zero, $5
+; O1-NEXT: addiu $3, $zero, 255
+; O1-NEXT: sllv $3, $3, $1
+; O1-NEXT: andi $4, $4, 255
; O1-NEXT: sllv $4, $4, $1
; O1-NEXT: $BB9_1: # %entry
; O1-NEXT: # =>This Inner Loop Header: Depth=1
-; O1-NEXT: ll $7, 0($3)
-; O1-NEXT: subu $8, $7, $4
-; O1-NEXT: and $8, $8, $5
-; O1-NEXT: and $9, $7, $6
-; O1-NEXT: or $9, $9, $8
-; O1-NEXT: sc $9, 0($3)
-; O1-NEXT: beqz $9, $BB9_1
+; O1-NEXT: ll $5, 0($2)
+; O1-NEXT: subu $6, $5, $4
+; O1-NEXT: xor $6, $5, $6
+; O1-NEXT: and $6, $6, $3
+; O1-NEXT: xor $6, $5, $6
+; O1-NEXT: sc $6, 0($2)
+; O1-NEXT: beqz $6, $BB9_1
; O1-NEXT: nop
; O1-NEXT: # %bb.2: # %entry
-; O1-NEXT: and $2, $7, $5
-; O1-NEXT: srlv $2, $2, $1
-; O1-NEXT: sll $2, $2, 24
-; O1-NEXT: sra $2, $2, 24
-; O1-NEXT: # %bb.3: # %entry
+; O1-NEXT: srlv $1, $5, $1
+; O1-NEXT: sll $1, $1, 24
; O1-NEXT: jr $ra
-; O1-NEXT: nop
+; O1-NEXT: sra $2, $1, 24
;
; O2-LABEL: AtomicLoadSub8:
; O2: # %bb.0: # %entry
; O2-NEXT: lui $2, %hi(_gp_disp)
; O2-NEXT: addiu $2, $2, %lo(_gp_disp)
; O2-NEXT: addu $1, $2, $25
-; O2-NEXT: lw $1, %got(y)($1)
; O2-NEXT: addiu $2, $zero, -4
-; O2-NEXT: and $3, $1, $2
+; O2-NEXT: lw $1, %got(y)($1)
+; O2-NEXT: and $2, $1, $2
; O2-NEXT: andi $1, $1, 3
; O2-NEXT: sll $1, $1, 3
-; O2-NEXT: ori $2, $zero, 255
-; O2-NEXT: sllv $5, $2, $1
-; O2-NEXT: nor $6, $zero, $5
+; O2-NEXT: addiu $3, $zero, 255
+; O2-NEXT: sllv $3, $3, $1
+; O2-NEXT: andi $4, $4, 255
; O2-NEXT: sllv $4, $4, $1
; O2-NEXT: $BB9_1: # %entry
; O2-NEXT: # =>This Inner Loop Header: Depth=1
-; O2-NEXT: ll $7, 0($3)
-; O2-NEXT: subu $8, $7, $4
-; O2-NEXT: and $8, $8, $5
-; O2-NEXT: and $9, $7, $6
-; O2-NEXT: or $9, $9, $8
-; O2-NEXT: sc $9, 0($3)
-; O2-NEXT: beqz $9, $BB9_1
+; O2-NEXT: ll $5, 0($2)
+; O2-NEXT: subu $6, $5, $4
+; O2-NEXT: xor $6, $5, $6
+; O2-NEXT: and $6, $6, $3
+; O2-NEXT: xor $6, $5, $6
+; O2-NEXT: sc $6, 0($2)
+; O2-NEXT: beqz $6, $BB9_1
; O2-NEXT: nop
; O2-NEXT: # %bb.2: # %entry
-; O2-NEXT: and $2, $7, $5
-; O2-NEXT: srlv $2, $2, $1
-; O2-NEXT: sll $2, $2, 24
-; O2-NEXT: sra $2, $2, 24
-; O2-NEXT: # %bb.3: # %entry
+; O2-NEXT: srlv $1, $5, $1
+; O2-NEXT: sll $1, $1, 24
; O2-NEXT: jr $ra
-; O2-NEXT: nop
+; O2-NEXT: sra $2, $1, 24
;
; O3-LABEL: AtomicLoadSub8:
; O3: # %bb.0: # %entry
@@ -3178,32 +3091,29 @@ define signext i8 @AtomicLoadSub8(i8 signext %incr) nounwind {
; O3-NEXT: addiu $2, $2, %lo(_gp_disp)
; O3-NEXT: addu $1, $2, $25
; O3-NEXT: addiu $2, $zero, -4
+; O3-NEXT: addiu $3, $zero, 255
+; O3-NEXT: andi $4, $4, 255
; O3-NEXT: lw $1, %got(y)($1)
-; O3-NEXT: and $3, $1, $2
+; O3-NEXT: and $2, $1, $2
; O3-NEXT: andi $1, $1, 3
-; O3-NEXT: ori $2, $zero, 255
; O3-NEXT: sll $1, $1, 3
-; O3-NEXT: sllv $5, $2, $1
+; O3-NEXT: sllv $3, $3, $1
; O3-NEXT: sllv $4, $4, $1
-; O3-NEXT: nor $6, $zero, $5
; O3-NEXT: $BB9_1: # %entry
; O3-NEXT: # =>This Inner Loop Header: Depth=1
-; O3-NEXT: ll $7, 0($3)
-; O3-NEXT: subu $8, $7, $4
-; O3-NEXT: and $8, $8, $5
-; O3-NEXT: and $9, $7, $6
-; O3-NEXT: or $9, $9, $8
-; O3-NEXT: sc $9, 0($3)
-; O3-NEXT: beqz $9, $BB9_1
+; O3-NEXT: ll $5, 0($2)
+; O3-NEXT: subu $6, $5, $4
+; O3-NEXT: xor $6, $5, $6
+; O3-NEXT: and $6, $6, $3
+; O3-NEXT: xor $6, $5, $6
+; O3-NEXT: sc $6, 0($2)
+; O3-NEXT: beqz $6, $BB9_1
; O3-NEXT: nop
; O3-NEXT: # %bb.2: # %entry
-; O3-NEXT: and $2, $7, $5
-; O3-NEXT: srlv $2, $2, $1
-; O3-NEXT: sll $2, $2, 24
-; O3-NEXT: sra $2, $2, 24
-; O3-NEXT: # %bb.3: # %entry
+; O3-NEXT: srlv $1, $5, $1
+; O3-NEXT: sll $1, $1, 24
; O3-NEXT: jr $ra
-; O3-NEXT: nop
+; O3-NEXT: sra $2, $1, 24
;
; MIPS32EB-LABEL: AtomicLoadSub8:
; MIPS32EB: # %bb.0: # %entry
@@ -3211,33 +3121,30 @@ define signext i8 @AtomicLoadSub8(i8 signext %incr) nounwind {
; MIPS32EB-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32EB-NEXT: addu $1, $2, $25
; MIPS32EB-NEXT: lw $1, %got(y)($1)
-; MIPS32EB-NEXT: addiu $2, $zero, -4
-; MIPS32EB-NEXT: and $3, $1, $2
-; MIPS32EB-NEXT: andi $1, $1, 3
-; MIPS32EB-NEXT: xori $1, $1, 3
-; MIPS32EB-NEXT: sll $1, $1, 3
-; MIPS32EB-NEXT: ori $2, $zero, 255
-; MIPS32EB-NEXT: sllv $5, $2, $1
-; MIPS32EB-NEXT: nor $6, $zero, $5
-; MIPS32EB-NEXT: sllv $4, $4, $1
+; MIPS32EB-NEXT: not $2, $1
+; MIPS32EB-NEXT: addiu $3, $zero, -4
+; MIPS32EB-NEXT: and $1, $1, $3
+; MIPS32EB-NEXT: andi $2, $2, 3
+; MIPS32EB-NEXT: sll $2, $2, 3
+; MIPS32EB-NEXT: addiu $3, $zero, 255
+; MIPS32EB-NEXT: sllv $3, $3, $2
+; MIPS32EB-NEXT: andi $4, $4, 255
+; MIPS32EB-NEXT: sllv $4, $4, $2
; MIPS32EB-NEXT: $BB9_1: # %entry
; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32EB-NEXT: ll $7, 0($3)
-; MIPS32EB-NEXT: subu $8, $7, $4
-; MIPS32EB-NEXT: and $8, $8, $5
-; MIPS32EB-NEXT: and $9, $7, $6
-; MIPS32EB-NEXT: or $9, $9, $8
-; MIPS32EB-NEXT: sc $9, 0($3)
-; MIPS32EB-NEXT: beqz $9, $BB9_1
+; MIPS32EB-NEXT: ll $5, 0($1)
+; MIPS32EB-NEXT: subu $6, $5, $4
+; MIPS32EB-NEXT: xor $6, $5, $6
+; MIPS32EB-NEXT: and $6, $6, $3
+; MIPS32EB-NEXT: xor $6, $5, $6
+; MIPS32EB-NEXT: sc $6, 0($1)
+; MIPS32EB-NEXT: beqz $6, $BB9_1
; MIPS32EB-NEXT: nop
; MIPS32EB-NEXT: # %bb.2: # %entry
-; MIPS32EB-NEXT: and $2, $7, $5
-; MIPS32EB-NEXT: srlv $2, $2, $1
-; MIPS32EB-NEXT: sll $2, $2, 24
-; MIPS32EB-NEXT: sra $2, $2, 24
-; MIPS32EB-NEXT: # %bb.3: # %entry
+; MIPS32EB-NEXT: srlv $1, $5, $2
+; MIPS32EB-NEXT: sll $1, $1, 24
; MIPS32EB-NEXT: jr $ra
-; MIPS32EB-NEXT: nop
+; MIPS32EB-NEXT: sra $2, $1, 24
entry:
%0 = atomicrmw sub ptr @y, i8 %incr monotonic
ret i8 %0
@@ -3250,73 +3157,64 @@ define signext i8 @AtomicLoadNand8(i8 signext %incr) nounwind {
; MIPS32-NEXT: lui $2, %hi(_gp_disp)
; MIPS32-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32-NEXT: addu $1, $2, $25
-; MIPS32-NEXT: lw $1, %got(y)($1)
; MIPS32-NEXT: addiu $2, $zero, -4
-; MIPS32-NEXT: and $3, $1, $2
+; MIPS32-NEXT: lw $1, %got(y)($1)
+; MIPS32-NEXT: and $2, $1, $2
; MIPS32-NEXT: andi $1, $1, 3
; MIPS32-NEXT: sll $1, $1, 3
-; MIPS32-NEXT: ori $2, $zero, 255
-; MIPS32-NEXT: sllv $5, $2, $1
-; MIPS32-NEXT: nor $6, $zero, $5
+; MIPS32-NEXT: addiu $3, $zero, 255
+; MIPS32-NEXT: sllv $3, $3, $1
+; MIPS32-NEXT: andi $4, $4, 255
; MIPS32-NEXT: sllv $4, $4, $1
; MIPS32-NEXT: $BB10_1: # %entry
; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32-NEXT: ll $7, 0($3)
-; MIPS32-NEXT: and $8, $7, $4
-; MIPS32-NEXT: nor $8, $zero, $8
-; MIPS32-NEXT: and $8, $8, $5
-; MIPS32-NEXT: and $9, $7, $6
-; MIPS32-NEXT: or $9, $9, $8
-; MIPS32-NEXT: sc $9, 0($3)
-; MIPS32-NEXT: beqz $9, $BB10_1
+; MIPS32-NEXT: ll $5, 0($2)
+; MIPS32-NEXT: and $6, $5, $4
+; MIPS32-NEXT: not $6, $6
+; MIPS32-NEXT: xor $6, $5, $6
+; MIPS32-NEXT: and $6, $6, $3
+; MIPS32-NEXT: xor $6, $5, $6
+; MIPS32-NEXT: sc $6, 0($2)
+; MIPS32-NEXT: beqz $6, $BB10_1
; MIPS32-NEXT: nop
; MIPS32-NEXT: # %bb.2: # %entry
-; MIPS32-NEXT: and $2, $7, $5
-; MIPS32-NEXT: srlv $2, $2, $1
-; MIPS32-NEXT: sll $2, $2, 24
-; MIPS32-NEXT: sra $2, $2, 24
-; MIPS32-NEXT: # %bb.3: # %entry
+; MIPS32-NEXT: srlv $1, $5, $1
+; MIPS32-NEXT: sll $1, $1, 24
; MIPS32-NEXT: jr $ra
-; MIPS32-NEXT: nop
+; MIPS32-NEXT: sra $2, $1, 24
;
; MIPS32O0-LABEL: AtomicLoadNand8:
; MIPS32O0: # %bb.0: # %entry
; MIPS32O0-NEXT: lui $2, %hi(_gp_disp)
; MIPS32O0-NEXT: addiu $2, $2, %lo(_gp_disp)
-; MIPS32O0-NEXT: addiu $sp, $sp, -8
-; MIPS32O0-NEXT: addu $1, $2, $25
-; MIPS32O0-NEXT: lw $1, %got(y)($1)
-; MIPS32O0-NEXT: addiu $2, $zero, -4
-; MIPS32O0-NEXT: and $5, $1, $2
-; MIPS32O0-NEXT: andi $1, $1, 3
-; MIPS32O0-NEXT: sll $9, $1, 3
-; MIPS32O0-NEXT: ori $1, $zero, 255
-; MIPS32O0-NEXT: sllv $7, $1, $9
-; MIPS32O0-NEXT: nor $8, $zero, $7
-; MIPS32O0-NEXT: sllv $6, $4, $9
+; MIPS32O0-NEXT: addu $2, $2, $25
+; MIPS32O0-NEXT: move $1, $4
+; MIPS32O0-NEXT: lw $3, %got(y)($2)
+; MIPS32O0-NEXT: addiu $4, $zero, -4
+; MIPS32O0-NEXT: and $4, $3, $4
+; MIPS32O0-NEXT: lw $2, %got(y)($2)
+; MIPS32O0-NEXT: addiu $3, $zero, 3
+; MIPS32O0-NEXT: and $2, $2, $3
+; MIPS32O0-NEXT: sll $2, $2, 3
+; MIPS32O0-NEXT: addiu $3, $zero, 255
+; MIPS32O0-NEXT: sllv $6, $3, $2
+; MIPS32O0-NEXT: andi $1, $1, 255
+; MIPS32O0-NEXT: sllv $5, $1, $2
; MIPS32O0-NEXT: $BB10_1: # %entry
; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32O0-NEXT: ll $2, 0($5)
-; MIPS32O0-NEXT: and $3, $2, $6
-; MIPS32O0-NEXT: nor $3, $zero, $3
-; MIPS32O0-NEXT: and $3, $3, $7
-; MIPS32O0-NEXT: and $4, $2, $8
-; MIPS32O0-NEXT: or $4, $4, $3
-; MIPS32O0-NEXT: sc $4, 0($5)
-; MIPS32O0-NEXT: beqz $4, $BB10_1
+; MIPS32O0-NEXT: ll $1, 0($4)
+; MIPS32O0-NEXT: and $3, $1, $5
+; MIPS32O0-NEXT: not $3, $3
+; MIPS32O0-NEXT: xor $3, $1, $3
+; MIPS32O0-NEXT: and $3, $3, $6
+; MIPS32O0-NEXT: xor $3, $1, $3
+; MIPS32O0-NEXT: sc $3, 0($4)
+; MIPS32O0-NEXT: beqz $3, $BB10_1
; MIPS32O0-NEXT: nop
; MIPS32O0-NEXT: # %bb.2: # %entry
-; MIPS32O0-NEXT: and $1, $2, $7
-; MIPS32O0-NEXT: srlv $1, $1, $9
-; MIPS32O0-NEXT: sll $1, $1, 24
-; MIPS32O0-NEXT: sra $1, $1, 24
-; MIPS32O0-NEXT: # %bb.3: # %entry
-; MIPS32O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32O0-NEXT: # %bb.4: # %entry
-; MIPS32O0-NEXT: lw $1, 4($sp) # 4-byte Folded Reload
+; MIPS32O0-NEXT: srlv $1, $1, $2
; MIPS32O0-NEXT: sll $1, $1, 24
; MIPS32O0-NEXT: sra $2, $1, 24
-; MIPS32O0-NEXT: addiu $sp, $sp, 8
; MIPS32O0-NEXT: jr $ra
; MIPS32O0-NEXT: nop
;
@@ -3325,99 +3223,88 @@ define signext i8 @AtomicLoadNand8(i8 signext %incr) nounwind {
; MIPS32R2-NEXT: lui $2, %hi(_gp_disp)
; MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32R2-NEXT: addu $1, $2, $25
-; MIPS32R2-NEXT: lw $1, %got(y)($1)
; MIPS32R2-NEXT: addiu $2, $zero, -4
-; MIPS32R2-NEXT: and $3, $1, $2
+; MIPS32R2-NEXT: lw $1, %got(y)($1)
+; MIPS32R2-NEXT: and $2, $1, $2
; MIPS32R2-NEXT: andi $1, $1, 3
; MIPS32R2-NEXT: sll $1, $1, 3
-; MIPS32R2-NEXT: ori $2, $zero, 255
-; MIPS32R2-NEXT: sllv $5, $2, $1
-; MIPS32R2-NEXT: nor $6, $zero, $5
+; MIPS32R2-NEXT: addiu $3, $zero, 255
+; MIPS32R2-NEXT: sllv $3, $3, $1
+; MIPS32R2-NEXT: andi $4, $4, 255
; MIPS32R2-NEXT: sllv $4, $4, $1
; MIPS32R2-NEXT: $BB10_1: # %entry
; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32R2-NEXT: ll $7, 0($3)
-; MIPS32R2-NEXT: and $8, $7, $4
-; MIPS32R2-NEXT: nor $8, $zero, $8
-; MIPS32R2-NEXT: and $8, $8, $5
-; MIPS32R2-NEXT: and $9, $7, $6
-; MIPS32R2-NEXT: or $9, $9, $8
-; MIPS32R2-NEXT: sc $9, 0($3)
-; MIPS32R2-NEXT: beqz $9, $BB10_1
+; MIPS32R2-NEXT: ll $5, 0($2)
+; MIPS32R2-NEXT: and $6, $5, $4
+; MIPS32R2-NEXT: not $6, $6
+; MIPS32R2-NEXT: xor $6, $5, $6
+; MIPS32R2-NEXT: and $6, $6, $3
+; MIPS32R2-NEXT: xor $6, $5, $6
+; MIPS32R2-NEXT: sc $6, 0($2)
+; MIPS32R2-NEXT: beqz $6, $BB10_1
; MIPS32R2-NEXT: nop
; MIPS32R2-NEXT: # %bb.2: # %entry
-; MIPS32R2-NEXT: and $2, $7, $5
-; MIPS32R2-NEXT: srlv $2, $2, $1
-; MIPS32R2-NEXT: seb $2, $2
-; MIPS32R2-NEXT: # %bb.3: # %entry
+; MIPS32R2-NEXT: srlv $1, $5, $1
; MIPS32R2-NEXT: jr $ra
-; MIPS32R2-NEXT: nop
+; MIPS32R2-NEXT: seb $2, $1
;
; MIPS32R6-LABEL: AtomicLoadNand8:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lui $2, %hi(_gp_disp)
; MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32R6-NEXT: addu $1, $2, $25
-; MIPS32R6-NEXT: lw $1, %got(y)($1)
; MIPS32R6-NEXT: addiu $2, $zero, -4
-; MIPS32R6-NEXT: and $3, $1, $2
+; MIPS32R6-NEXT: lw $1, %got(y)($1)
+; MIPS32R6-NEXT: and $2, $1, $2
; MIPS32R6-NEXT: andi $1, $1, 3
; MIPS32R6-NEXT: sll $1, $1, 3
-; MIPS32R6-NEXT: ori $2, $zero, 255
-; MIPS32R6-NEXT: sllv $5, $2, $1
-; MIPS32R6-NEXT: nor $6, $zero, $5
+; MIPS32R6-NEXT: addiu $3, $zero, 255
+; MIPS32R6-NEXT: sllv $3, $3, $1
+; MIPS32R6-NEXT: andi $4, $4, 255
; MIPS32R6-NEXT: sllv $4, $4, $1
; MIPS32R6-NEXT: $BB10_1: # %entry
; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32R6-NEXT: ll $7, 0($3)
-; MIPS32R6-NEXT: and $8, $7, $4
-; MIPS32R6-NEXT: nor $8, $zero, $8
-; MIPS32R6-NEXT: and $8, $8, $5
-; MIPS32R6-NEXT: and $9, $7, $6
-; MIPS32R6-NEXT: or $9, $9, $8
-; MIPS32R6-NEXT: sc $9, 0($3)
-; MIPS32R6-NEXT: beqzc $9, $BB10_1
+; MIPS32R6-NEXT: ll $5, 0($2)
+; MIPS32R6-NEXT: and $6, $5, $4
+; MIPS32R6-NEXT: not $6, $6
+; MIPS32R6-NEXT: xor $6, $5, $6
+; MIPS32R6-NEXT: and $6, $6, $3
+; MIPS32R6-NEXT: xor $6, $5, $6
+; MIPS32R6-NEXT: sc $6, 0($2)
+; MIPS32R6-NEXT: beqzc $6, $BB10_1
; MIPS32R6-NEXT: # %bb.2: # %entry
-; MIPS32R6-NEXT: and $2, $7, $5
-; MIPS32R6-NEXT: srlv $2, $2, $1
-; MIPS32R6-NEXT: seb $2, $2
-; MIPS32R6-NEXT: # %bb.3: # %entry
-; MIPS32R6-NEXT: jrc $ra
+; MIPS32R6-NEXT: srlv $1, $5, $1
+; MIPS32R6-NEXT: jr $ra
+; MIPS32R6-NEXT: seb $2, $1
;
; MIPS32R6O0-LABEL: AtomicLoadNand8:
; MIPS32R6O0: # %bb.0: # %entry
; MIPS32R6O0-NEXT: lui $2, %hi(_gp_disp)
; MIPS32R6O0-NEXT: addiu $2, $2, %lo(_gp_disp)
-; MIPS32R6O0-NEXT: addiu $sp, $sp, -8
-; MIPS32R6O0-NEXT: addu $1, $2, $25
-; MIPS32R6O0-NEXT: lw $1, %got(y)($1)
-; MIPS32R6O0-NEXT: addiu $2, $zero, -4
-; MIPS32R6O0-NEXT: and $5, $1, $2
-; MIPS32R6O0-NEXT: andi $1, $1, 3
-; MIPS32R6O0-NEXT: sll $9, $1, 3
-; MIPS32R6O0-NEXT: ori $1, $zero, 255
-; MIPS32R6O0-NEXT: sllv $7, $1, $9
-; MIPS32R6O0-NEXT: nor $8, $zero, $7
-; MIPS32R6O0-NEXT: sllv $6, $4, $9
+; MIPS32R6O0-NEXT: addu $2, $2, $25
+; MIPS32R6O0-NEXT: move $1, $4
+; MIPS32R6O0-NEXT: lw $2, %got(y)($2)
+; MIPS32R6O0-NEXT: addiu $3, $zero, -4
+; MIPS32R6O0-NEXT: and $4, $2, $3
+; MIPS32R6O0-NEXT: andi $2, $2, 3
+; MIPS32R6O0-NEXT: sll $2, $2, 3
+; MIPS32R6O0-NEXT: addiu $3, $zero, 255
+; MIPS32R6O0-NEXT: sllv $6, $3, $2
+; MIPS32R6O0-NEXT: andi $1, $1, 255
+; MIPS32R6O0-NEXT: sllv $5, $1, $2
; MIPS32R6O0-NEXT: $BB10_1: # %entry
; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32R6O0-NEXT: ll $2, 0($5)
-; MIPS32R6O0-NEXT: and $3, $2, $6
-; MIPS32R6O0-NEXT: nor $3, $zero, $3
-; MIPS32R6O0-NEXT: and $3, $3, $7
-; MIPS32R6O0-NEXT: and $4, $2, $8
-; MIPS32R6O0-NEXT: or $4, $4, $3
-; MIPS32R6O0-NEXT: sc $4, 0($5)
-; MIPS32R6O0-NEXT: beqzc $4, $BB10_1
+; MIPS32R6O0-NEXT: ll $1, 0($4)
+; MIPS32R6O0-NEXT: and $3, $1, $5
+; MIPS32R6O0-NEXT: not $3, $3
+; MIPS32R6O0-NEXT: xor $3, $1, $3
+; MIPS32R6O0-NEXT: and $3, $3, $6
+; MIPS32R6O0-NEXT: xor $3, $1, $3
+; MIPS32R6O0-NEXT: sc $3, 0($4)
+; MIPS32R6O0-NEXT: beqzc $3, $BB10_1
; MIPS32R6O0-NEXT: # %bb.2: # %entry
-; MIPS32R6O0-NEXT: and $1, $2, $7
-; MIPS32R6O0-NEXT: srlv $1, $1, $9
-; MIPS32R6O0-NEXT: seb $1, $1
-; MIPS32R6O0-NEXT: # %bb.3: # %entry
-; MIPS32R6O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32R6O0-NEXT: # %bb.4: # %entry
-; MIPS32R6O0-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
-; MIPS32R6O0-NEXT: addiu $sp, $sp, 8
+; MIPS32R6O0-NEXT: srlv $1, $1, $2
+; MIPS32R6O0-NEXT: seb $2, $1
; MIPS32R6O0-NEXT: jrc $ra
;
; MIPS4-LABEL: AtomicLoadNand8:
@@ -3426,33 +3313,31 @@ define signext i8 @AtomicLoadNand8(i8 signext %incr) nounwind {
; MIPS4-NEXT: daddu $1, $1, $25
; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadNand8)))
; MIPS4-NEXT: ld $1, %got_disp(y)($1)
-; MIPS4-NEXT: daddiu $2, $zero, -4
-; MIPS4-NEXT: and $3, $1, $2
-; MIPS4-NEXT: andi $1, $1, 3
-; MIPS4-NEXT: sll $1, $1, 3
-; MIPS4-NEXT: ori $2, $zero, 255
-; MIPS4-NEXT: sllv $5, $2, $1
-; MIPS4-NEXT: nor $6, $zero, $5
-; MIPS4-NEXT: sllv $4, $4, $1
+; MIPS4-NEXT: sll $2, $1, 0
+; MIPS4-NEXT: andi $2, $2, 3
+; MIPS4-NEXT: daddiu $3, $zero, -4
+; MIPS4-NEXT: and $1, $1, $3
+; MIPS4-NEXT: sll $2, $2, 3
+; MIPS4-NEXT: addiu $3, $zero, 255
+; MIPS4-NEXT: sllv $3, $3, $2
+; MIPS4-NEXT: andi $4, $4, 255
+; MIPS4-NEXT: sllv $4, $4, $2
; MIPS4-NEXT: .LBB10_1: # %entry
; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS4-NEXT: ll $7, 0($3)
-; MIPS4-NEXT: and $8, $7, $4
-; MIPS4-NEXT: nor $8, $zero, $8
-; MIPS4-NEXT: and $8, $8, $5
-; MIPS4-NEXT: and $9, $7, $6
-; MIPS4-NEXT: or $9, $9, $8
-; MIPS4-NEXT: sc $9, 0($3)
-; MIPS4-NEXT: beqz $9, .LBB10_1
+; MIPS4-NEXT: ll $5, 0($1)
+; MIPS4-NEXT: and $6, $5, $4
+; MIPS4-NEXT: not $6, $6
+; MIPS4-NEXT: xor $6, $5, $6
+; MIPS4-NEXT: and $6, $6, $3
+; MIPS4-NEXT: xor $6, $5, $6
+; MIPS4-NEXT: sc $6, 0($1)
+; MIPS4-NEXT: beqz $6, .LBB10_1
; MIPS4-NEXT: nop
; MIPS4-NEXT: # %bb.2: # %entry
-; MIPS4-NEXT: and $2, $7, $5
-; MIPS4-NEXT: srlv $2, $2, $1
-; MIPS4-NEXT: sll $2, $2, 24
-; MIPS4-NEXT: sra $2, $2, 24
-; MIPS4-NEXT: # %bb.3: # %entry
+; MIPS4-NEXT: srlv $1, $5, $2
+; MIPS4-NEXT: sll $1, $1, 24
; MIPS4-NEXT: jr $ra
-; MIPS4-NEXT: nop
+; MIPS4-NEXT: sra $2, $1, 24
;
; MIPS64-LABEL: AtomicLoadNand8:
; MIPS64: # %bb.0: # %entry
@@ -3460,33 +3345,31 @@ define signext i8 @AtomicLoadNand8(i8 signext %incr) nounwind {
; MIPS64-NEXT: daddu $1, $1, $25
; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadNand8)))
; MIPS64-NEXT: ld $1, %got_disp(y)($1)
-; MIPS64-NEXT: daddiu $2, $zero, -4
-; MIPS64-NEXT: and $3, $1, $2
-; MIPS64-NEXT: andi $1, $1, 3
-; MIPS64-NEXT: sll $1, $1, 3
-; MIPS64-NEXT: ori $2, $zero, 255
-; MIPS64-NEXT: sllv $5, $2, $1
-; MIPS64-NEXT: nor $6, $zero, $5
-; MIPS64-NEXT: sllv $4, $4, $1
+; MIPS64-NEXT: sll $2, $1, 0
+; MIPS64-NEXT: andi $2, $2, 3
+; MIPS64-NEXT: daddiu $3, $zero, -4
+; MIPS64-NEXT: and $1, $1, $3
+; MIPS64-NEXT: sll $2, $2, 3
+; MIPS64-NEXT: addiu $3, $zero, 255
+; MIPS64-NEXT: sllv $3, $3, $2
+; MIPS64-NEXT: andi $4, $4, 255
+; MIPS64-NEXT: sllv $4, $4, $2
; MIPS64-NEXT: .LBB10_1: # %entry
; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64-NEXT: ll $7, 0($3)
-; MIPS64-NEXT: and $8, $7, $4
-; MIPS64-NEXT: nor $8, $zero, $8
-; MIPS64-NEXT: and $8, $8, $5
-; MIPS64-NEXT: and $9, $7, $6
-; MIPS64-NEXT: or $9, $9, $8
-; MIPS64-NEXT: sc $9, 0($3)
-; MIPS64-NEXT: beqz $9, .LBB10_1
+; MIPS64-NEXT: ll $5, 0($1)
+; MIPS64-NEXT: and $6, $5, $4
+; MIPS64-NEXT: not $6, $6
+; MIPS64-NEXT: xor $6, $5, $6
+; MIPS64-NEXT: and $6, $6, $3
+; MIPS64-NEXT: xor $6, $5, $6
+; MIPS64-NEXT: sc $6, 0($1)
+; MIPS64-NEXT: beqz $6, .LBB10_1
; MIPS64-NEXT: nop
; MIPS64-NEXT: # %bb.2: # %entry
-; MIPS64-NEXT: and $2, $7, $5
-; MIPS64-NEXT: srlv $2, $2, $1
-; MIPS64-NEXT: sll $2, $2, 24
-; MIPS64-NEXT: sra $2, $2, 24
-; MIPS64-NEXT: # %bb.3: # %entry
+; MIPS64-NEXT: srlv $1, $5, $2
+; MIPS64-NEXT: sll $1, $1, 24
; MIPS64-NEXT: jr $ra
-; MIPS64-NEXT: nop
+; MIPS64-NEXT: sra $2, $1, 24
;
; MIPS64R2-LABEL: AtomicLoadNand8:
; MIPS64R2: # %bb.0: # %entry
@@ -3494,32 +3377,30 @@ define signext i8 @AtomicLoadNand8(i8 signext %incr) nounwind {
; MIPS64R2-NEXT: daddu $1, $1, $25
; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadNand8)))
; MIPS64R2-NEXT: ld $1, %got_disp(y)($1)
-; MIPS64R2-NEXT: daddiu $2, $zero, -4
-; MIPS64R2-NEXT: and $3, $1, $2
-; MIPS64R2-NEXT: andi $1, $1, 3
-; MIPS64R2-NEXT: sll $1, $1, 3
-; MIPS64R2-NEXT: ori $2, $zero, 255
-; MIPS64R2-NEXT: sllv $5, $2, $1
-; MIPS64R2-NEXT: nor $6, $zero, $5
-; MIPS64R2-NEXT: sllv $4, $4, $1
+; MIPS64R2-NEXT: sll $2, $1, 0
+; MIPS64R2-NEXT: andi $2, $2, 3
+; MIPS64R2-NEXT: daddiu $3, $zero, -4
+; MIPS64R2-NEXT: and $1, $1, $3
+; MIPS64R2-NEXT: sll $2, $2, 3
+; MIPS64R2-NEXT: addiu $3, $zero, 255
+; MIPS64R2-NEXT: sllv $3, $3, $2
+; MIPS64R2-NEXT: andi $4, $4, 255
+; MIPS64R2-NEXT: sllv $4, $4, $2
; MIPS64R2-NEXT: .LBB10_1: # %entry
; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R2-NEXT: ll $7, 0($3)
-; MIPS64R2-NEXT: and $8, $7, $4
-; MIPS64R2-NEXT: nor $8, $zero, $8
-; MIPS64R2-NEXT: and $8, $8, $5
-; MIPS64R2-NEXT: and $9, $7, $6
-; MIPS64R2-NEXT: or $9, $9, $8
-; MIPS64R2-NEXT: sc $9, 0($3)
-; MIPS64R2-NEXT: beqz $9, .LBB10_1
+; MIPS64R2-NEXT: ll $5, 0($1)
+; MIPS64R2-NEXT: and $6, $5, $4
+; MIPS64R2-NEXT: not $6, $6
+; MIPS64R2-NEXT: xor $6, $5, $6
+; MIPS64R2-NEXT: and $6, $6, $3
+; MIPS64R2-NEXT: xor $6, $5, $6
+; MIPS64R2-NEXT: sc $6, 0($1)
+; MIPS64R2-NEXT: beqz $6, .LBB10_1
; MIPS64R2-NEXT: nop
; MIPS64R2-NEXT: # %bb.2: # %entry
-; MIPS64R2-NEXT: and $2, $7, $5
-; MIPS64R2-NEXT: srlv $2, $2, $1
-; MIPS64R2-NEXT: seb $2, $2
-; MIPS64R2-NEXT: # %bb.3: # %entry
+; MIPS64R2-NEXT: srlv $1, $5, $2
; MIPS64R2-NEXT: jr $ra
-; MIPS64R2-NEXT: nop
+; MIPS64R2-NEXT: seb $2, $1
;
; MIPS64R6-LABEL: AtomicLoadNand8:
; MIPS64R6: # %bb.0: # %entry
@@ -3527,67 +3408,61 @@ define signext i8 @AtomicLoadNand8(i8 signext %incr) nounwind {
; MIPS64R6-NEXT: daddu $1, $1, $25
; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadNand8)))
; MIPS64R6-NEXT: ld $1, %got_disp(y)($1)
-; MIPS64R6-NEXT: daddiu $2, $zero, -4
-; MIPS64R6-NEXT: and $3, $1, $2
-; MIPS64R6-NEXT: andi $1, $1, 3
-; MIPS64R6-NEXT: sll $1, $1, 3
-; MIPS64R6-NEXT: ori $2, $zero, 255
-; MIPS64R6-NEXT: sllv $5, $2, $1
-; MIPS64R6-NEXT: nor $6, $zero, $5
-; MIPS64R6-NEXT: sllv $4, $4, $1
+; MIPS64R6-NEXT: sll $2, $1, 0
+; MIPS64R6-NEXT: andi $2, $2, 3
+; MIPS64R6-NEXT: daddiu $3, $zero, -4
+; MIPS64R6-NEXT: and $1, $1, $3
+; MIPS64R6-NEXT: sll $2, $2, 3
+; MIPS64R6-NEXT: addiu $3, $zero, 255
+; MIPS64R6-NEXT: sllv $3, $3, $2
+; MIPS64R6-NEXT: andi $4, $4, 255
+; MIPS64R6-NEXT: sllv $4, $4, $2
; MIPS64R6-NEXT: .LBB10_1: # %entry
; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R6-NEXT: ll $7, 0($3)
-; MIPS64R6-NEXT: and $8, $7, $4
-; MIPS64R6-NEXT: nor $8, $zero, $8
-; MIPS64R6-NEXT: and $8, $8, $5
-; MIPS64R6-NEXT: and $9, $7, $6
-; MIPS64R6-NEXT: or $9, $9, $8
-; MIPS64R6-NEXT: sc $9, 0($3)
-; MIPS64R6-NEXT: beqzc $9, .LBB10_1
+; MIPS64R6-NEXT: ll $5, 0($1)
+; MIPS64R6-NEXT: and $6, $5, $4
+; MIPS64R6-NEXT: not $6, $6
+; MIPS64R6-NEXT: xor $6, $5, $6
+; MIPS64R6-NEXT: and $6, $6, $3
+; MIPS64R6-NEXT: xor $6, $5, $6
+; MIPS64R6-NEXT: sc $6, 0($1)
+; MIPS64R6-NEXT: beqzc $6, .LBB10_1
; MIPS64R6-NEXT: # %bb.2: # %entry
-; MIPS64R6-NEXT: and $2, $7, $5
-; MIPS64R6-NEXT: srlv $2, $2, $1
-; MIPS64R6-NEXT: seb $2, $2
-; MIPS64R6-NEXT: # %bb.3: # %entry
-; MIPS64R6-NEXT: jrc $ra
+; MIPS64R6-NEXT: srlv $1, $5, $2
+; MIPS64R6-NEXT: jr $ra
+; MIPS64R6-NEXT: seb $2, $1
;
; MIPS64R6O0-LABEL: AtomicLoadNand8:
; MIPS64R6O0: # %bb.0: # %entry
-; MIPS64R6O0-NEXT: daddiu $sp, $sp, -16
; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadNand8)))
; MIPS64R6O0-NEXT: daddu $1, $1, $25
; MIPS64R6O0-NEXT: daddiu $2, $1, %lo(%neg(%gp_rel(AtomicLoadNand8)))
; MIPS64R6O0-NEXT: move $1, $4
; MIPS64R6O0-NEXT: ld $2, %got_disp(y)($2)
; MIPS64R6O0-NEXT: daddiu $3, $zero, -4
-; MIPS64R6O0-NEXT: and $5, $2, $3
+; MIPS64R6O0-NEXT: and $4, $2, $3
+; MIPS64R6O0-NEXT: # kill: def $v0 killed $v0 killed $v0_64
+; MIPS64R6O0-NEXT: sll $2, $2, 0
+; MIPS64R6O0-NEXT: not $2, $2
; MIPS64R6O0-NEXT: andi $2, $2, 3
-; MIPS64R6O0-NEXT: xori $2, $2, 3
-; MIPS64R6O0-NEXT: sll $9, $2, 3
-; MIPS64R6O0-NEXT: ori $2, $zero, 255
-; MIPS64R6O0-NEXT: sllv $7, $2, $9
-; MIPS64R6O0-NEXT: nor $8, $zero, $7
-; MIPS64R6O0-NEXT: sllv $6, $1, $9
+; MIPS64R6O0-NEXT: sll $2, $2, 3
+; MIPS64R6O0-NEXT: addiu $3, $zero, 255
+; MIPS64R6O0-NEXT: sllv $6, $3, $2
+; MIPS64R6O0-NEXT: andi $1, $1, 255
+; MIPS64R6O0-NEXT: sllv $5, $1, $2
; MIPS64R6O0-NEXT: .LBB10_1: # %entry
; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R6O0-NEXT: ll $2, 0($5)
-; MIPS64R6O0-NEXT: and $3, $2, $6
-; MIPS64R6O0-NEXT: nor $3, $zero, $3
-; MIPS64R6O0-NEXT: and $3, $3, $7
-; MIPS64R6O0-NEXT: and $4, $2, $8
-; MIPS64R6O0-NEXT: or $4, $4, $3
-; MIPS64R6O0-NEXT: sc $4, 0($5)
-; MIPS64R6O0-NEXT: beqzc $4, .LBB10_1
+; MIPS64R6O0-NEXT: ll $1, 0($4)
+; MIPS64R6O0-NEXT: and $3, $1, $5
+; MIPS64R6O0-NEXT: not $3, $3
+; MIPS64R6O0-NEXT: xor $3, $1, $3
+; MIPS64R6O0-NEXT: and $3, $3, $6
+; MIPS64R6O0-NEXT: xor $3, $1, $3
+; MIPS64R6O0-NEXT: sc $3, 0($4)
+; MIPS64R6O0-NEXT: beqzc $3, .LBB10_1
; MIPS64R6O0-NEXT: # %bb.2: # %entry
-; MIPS64R6O0-NEXT: and $1, $2, $7
-; MIPS64R6O0-NEXT: srlv $1, $1, $9
-; MIPS64R6O0-NEXT: seb $1, $1
-; MIPS64R6O0-NEXT: # %bb.3: # %entry
-; MIPS64R6O0-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64R6O0-NEXT: # %bb.4: # %entry
-; MIPS64R6O0-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
-; MIPS64R6O0-NEXT: daddiu $sp, $sp, 16
+; MIPS64R6O0-NEXT: srlv $1, $1, $2
+; MIPS64R6O0-NEXT: seb $2, $1
; MIPS64R6O0-NEXT: jrc $ra
;
; MM32-LABEL: AtomicLoadNand8:
@@ -3595,99 +3470,91 @@ define signext i8 @AtomicLoadNand8(i8 signext %incr) nounwind {
; MM32-NEXT: lui $2, %hi(_gp_disp)
; MM32-NEXT: addiu $2, $2, %lo(_gp_disp)
; MM32-NEXT: addu $2, $2, $25
-; MM32-NEXT: lw $1, %got(y)($2)
-; MM32-NEXT: addiu $2, $zero, -4
-; MM32-NEXT: and $3, $1, $2
-; MM32-NEXT: andi $1, $1, 3
-; MM32-NEXT: sll $1, $1, 3
-; MM32-NEXT: ori $2, $zero, 255
-; MM32-NEXT: sllv $5, $2, $1
-; MM32-NEXT: nor $6, $zero, $5
-; MM32-NEXT: sllv $4, $4, $1
+; MM32-NEXT: addiu $3, $zero, -4
+; MM32-NEXT: lw $2, %got(y)($2)
+; MM32-NEXT: and16 $3, $2
+; MM32-NEXT: andi16 $2, $2, 3
+; MM32-NEXT: sll16 $2, $2, 3
+; MM32-NEXT: addiu $1, $zero, 255
+; MM32-NEXT: sllv $1, $1, $2
+; MM32-NEXT: andi16 $4, $4, 255
+; MM32-NEXT: sllv $4, $4, $2
; MM32-NEXT: $BB10_1: # %entry
; MM32-NEXT: # =>This Inner Loop Header: Depth=1
-; MM32-NEXT: ll $7, 0($3)
-; MM32-NEXT: and $8, $7, $4
-; MM32-NEXT: nor $8, $zero, $8
-; MM32-NEXT: and $8, $8, $5
-; MM32-NEXT: and $9, $7, $6
-; MM32-NEXT: or $9, $9, $8
-; MM32-NEXT: sc $9, 0($3)
-; MM32-NEXT: beqzc $9, $BB10_1
+; MM32-NEXT: ll $5, 0($3)
+; MM32-NEXT: and $6, $5, $4
+; MM32-NEXT: not $6, $6
+; MM32-NEXT: xor16 $6, $5
+; MM32-NEXT: and $6, $6, $1
+; MM32-NEXT: xor16 $6, $5
+; MM32-NEXT: sc $6, 0($3)
+; MM32-NEXT: beqzc $6, $BB10_1
; MM32-NEXT: # %bb.2: # %entry
-; MM32-NEXT: and $2, $7, $5
-; MM32-NEXT: srlv $2, $2, $1
-; MM32-NEXT: seb $2, $2
-; MM32-NEXT: # %bb.3: # %entry
-; MM32-NEXT: jrc $ra
+; MM32-NEXT: srlv $1, $5, $2
+; MM32-NEXT: jr $ra
+; MM32-NEXT: seb $2, $1
;
; O1-LABEL: AtomicLoadNand8:
; O1: # %bb.0: # %entry
; O1-NEXT: lui $2, %hi(_gp_disp)
; O1-NEXT: addiu $2, $2, %lo(_gp_disp)
; O1-NEXT: addu $1, $2, $25
-; O1-NEXT: lw $1, %got(y)($1)
; O1-NEXT: addiu $2, $zero, -4
-; O1-NEXT: and $3, $1, $2
+; O1-NEXT: lw $1, %got(y)($1)
+; O1-NEXT: and $2, $1, $2
; O1-NEXT: andi $1, $1, 3
; O1-NEXT: sll $1, $1, 3
-; O1-NEXT: ori $2, $zero, 255
-; O1-NEXT: sllv $5, $2, $1
-; O1-NEXT: nor $6, $zero, $5
+; O1-NEXT: addiu $3, $zero, 255
+; O1-NEXT: sllv $3, $3, $1
+; O1-NEXT: andi $4, $4, 255
; O1-NEXT: sllv $4, $4, $1
; O1-NEXT: $BB10_1: # %entry
; O1-NEXT: # =>This Inner Loop Header: Depth=1
-; O1-NEXT: ll $7, 0($3)
-; O1-NEXT: and $8, $7, $4
-; O1-NEXT: nor $8, $zero, $8
-; O1-NEXT: and $8, $8, $5
-; O1-NEXT: and $9, $7, $6
-; O1-NEXT: or $9, $9, $8
-; O1-NEXT: sc $9, 0($3)
-; O1-NEXT: beqz $9, $BB10_1
+; O1-NEXT: ll $5, 0($2)
+; O1-NEXT: and $6, $5, $4
+; O1-NEXT: not $6, $6
+; O1-NEXT: xor $6, $5, $6
+; O1-NEXT: and $6, $6, $3
+; O1-NEXT: xor $6, $5, $6
+; O1-NEXT: sc $6, 0($2)
+; O1-NEXT: beqz $6, $BB10_1
; O1-NEXT: nop
; O1-NEXT: # %bb.2: # %entry
-; O1-NEXT: and $2, $7, $5
-; O1-NEXT: srlv $2, $2, $1
-; O1-NEXT: sll $2, $2, 24
-; O1-NEXT: sra $2, $2, 24
-; O1-NEXT: # %bb.3: # %entry
+; O1-NEXT: srlv $1, $5, $1
+; O1-NEXT: sll $1, $1, 24
; O1-NEXT: jr $ra
-; O1-NEXT: nop
+; O1-NEXT: sra $2, $1, 24
;
; O2-LABEL: AtomicLoadNand8:
; O2: # %bb.0: # %entry
; O2-NEXT: lui $2, %hi(_gp_disp)
; O2-NEXT: addiu $2, $2, %lo(_gp_disp)
; O2-NEXT: addu $1, $2, $25
-; O2-NEXT: lw $1, %got(y)($1)
; O2-NEXT: addiu $2, $zero, -4
-; O2-NEXT: and $3, $1, $2
+; O2-NEXT: lw $1, %got(y)($1)
+; O2-NEXT: and $2, $1, $2
; O2-NEXT: andi $1, $1, 3
; O2-NEXT: sll $1, $1, 3
-; O2-NEXT: ori $2, $zero, 255
-; O2-NEXT: sllv $5, $2, $1
-; O2-NEXT: nor $6, $zero, $5
+; O2-NEXT: addiu $3, $zero, 255
+; O2-NEXT: sllv $3, $3, $1
+; O2-NEXT: andi $4, $4, 255
; O2-NEXT: sllv $4, $4, $1
; O2-NEXT: $BB10_1: # %entry
; O2-NEXT: # =>This Inner Loop Header: Depth=1
-; O2-NEXT: ll $7, 0($3)
-; O2-NEXT: and $8, $7, $4
-; O2-NEXT: nor $8, $zero, $8
-; O2-NEXT: and $8, $8, $5
-; O2-NEXT: and $9, $7, $6
-; O2-NEXT: or $9, $9, $8
-; O2-NEXT: sc $9, 0($3)
-; O2-NEXT: beqz $9, $BB10_1
+; O2-NEXT: ll $5, 0($2)
+; O2-NEXT: and $6, $5, $4
+; O2-NEXT: not $6, $6
+; O2-NEXT: xor $6, $5, $6
+; O2-NEXT: and $6, $6, $3
+; O2-NEXT: xor $6, $5, $6
+; O2-NEXT: sc $6, 0($2)
+; O2-NEXT: beqz $6, $BB10_1
; O2-NEXT: nop
; O2-NEXT: # %bb.2: # %entry
-; O2-NEXT: and $2, $7, $5
-; O2-NEXT: srlv $2, $2, $1
-; O2-NEXT: sll $2, $2, 24
-; O2-NEXT: sra $2, $2, 24
-; O2-NEXT: # %bb.3: # %entry
+; O2-NEXT: srlv $1, $5, $1
+; O2-NEXT: sll $1, $1, 24
; O2-NEXT: jr $ra
-; O2-NEXT: nop
+; O2-NEXT: sra $2, $1, 24
;
; O3-LABEL: AtomicLoadNand8:
; O3: # %bb.0: # %entry
@@ -3695,33 +3562,30 @@ define signext i8 @AtomicLoadNand8(i8 signext %incr) nounwind {
; O3-NEXT: addiu $2, $2, %lo(_gp_disp)
; O3-NEXT: addu $1, $2, $25
; O3-NEXT: addiu $2, $zero, -4
+; O3-NEXT: addiu $3, $zero, 255
+; O3-NEXT: andi $4, $4, 255
; O3-NEXT: lw $1, %got(y)($1)
-; O3-NEXT: and $3, $1, $2
+; O3-NEXT: and $2, $1, $2
; O3-NEXT: andi $1, $1, 3
-; O3-NEXT: ori $2, $zero, 255
; O3-NEXT: sll $1, $1, 3
-; O3-NEXT: sllv $5, $2, $1
+; O3-NEXT: sllv $3, $3, $1
; O3-NEXT: sllv $4, $4, $1
-; O3-NEXT: nor $6, $zero, $5
; O3-NEXT: $BB10_1: # %entry
; O3-NEXT: # =>This Inner Loop Header: Depth=1
-; O3-NEXT: ll $7, 0($3)
-; O3-NEXT: and $8, $7, $4
-; O3-NEXT: nor $8, $zero, $8
-; O3-NEXT: and $8, $8, $5
-; O3-NEXT: and $9, $7, $6
-; O3-NEXT: or $9, $9, $8
-; O3-NEXT: sc $9, 0($3)
-; O3-NEXT: beqz $9, $BB10_1
+; O3-NEXT: ll $5, 0($2)
+; O3-NEXT: and $6, $5, $4
+; O3-NEXT: not $6, $6
+; O3-NEXT: xor $6, $5, $6
+; O3-NEXT: and $6, $6, $3
+; O3-NEXT: xor $6, $5, $6
+; O3-NEXT: sc $6, 0($2)
+; O3-NEXT: beqz $6, $BB10_1
; O3-NEXT: nop
; O3-NEXT: # %bb.2: # %entry
-; O3-NEXT: and $2, $7, $5
-; O3-NEXT: srlv $2, $2, $1
-; O3-NEXT: sll $2, $2, 24
-; O3-NEXT: sra $2, $2, 24
-; O3-NEXT: # %bb.3: # %entry
+; O3-NEXT: srlv $1, $5, $1
+; O3-NEXT: sll $1, $1, 24
; O3-NEXT: jr $ra
-; O3-NEXT: nop
+; O3-NEXT: sra $2, $1, 24
;
; MIPS32EB-LABEL: AtomicLoadNand8:
; MIPS32EB: # %bb.0: # %entry
@@ -3729,34 +3593,31 @@ define signext i8 @AtomicLoadNand8(i8 signext %incr) nounwind {
; MIPS32EB-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32EB-NEXT: addu $1, $2, $25
; MIPS32EB-NEXT: lw $1, %got(y)($1)
-; MIPS32EB-NEXT: addiu $2, $zero, -4
-; MIPS32EB-NEXT: and $3, $1, $2
-; MIPS32EB-NEXT: andi $1, $1, 3
-; MIPS32EB-NEXT: xori $1, $1, 3
-; MIPS32EB-NEXT: sll $1, $1, 3
-; MIPS32EB-NEXT: ori $2, $zero, 255
-; MIPS32EB-NEXT: sllv $5, $2, $1
-; MIPS32EB-NEXT: nor $6, $zero, $5
-; MIPS32EB-NEXT: sllv $4, $4, $1
+; MIPS32EB-NEXT: not $2, $1
+; MIPS32EB-NEXT: addiu $3, $zero, -4
+; MIPS32EB-NEXT: and $1, $1, $3
+; MIPS32EB-NEXT: andi $2, $2, 3
+; MIPS32EB-NEXT: sll $2, $2, 3
+; MIPS32EB-NEXT: addiu $3, $zero, 255
+; MIPS32EB-NEXT: sllv $3, $3, $2
+; MIPS32EB-NEXT: andi $4, $4, 255
+; MIPS32EB-NEXT: sllv $4, $4, $2
; MIPS32EB-NEXT: $BB10_1: # %entry
; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32EB-NEXT: ll $7, 0($3)
-; MIPS32EB-NEXT: and $8, $7, $4
-; MIPS32EB-NEXT: nor $8, $zero, $8
-; MIPS32EB-NEXT: and $8, $8, $5
-; MIPS32EB-NEXT: and $9, $7, $6
-; MIPS32EB-NEXT: or $9, $9, $8
-; MIPS32EB-NEXT: sc $9, 0($3)
-; MIPS32EB-NEXT: beqz $9, $BB10_1
+; MIPS32EB-NEXT: ll $5, 0($1)
+; MIPS32EB-NEXT: and $6, $5, $4
+; MIPS32EB-NEXT: not $6, $6
+; MIPS32EB-NEXT: xor $6, $5, $6
+; MIPS32EB-NEXT: and $6, $6, $3
+; MIPS32EB-NEXT: xor $6, $5, $6
+; MIPS32EB-NEXT: sc $6, 0($1)
+; MIPS32EB-NEXT: beqz $6, $BB10_1
; MIPS32EB-NEXT: nop
; MIPS32EB-NEXT: # %bb.2: # %entry
-; MIPS32EB-NEXT: and $2, $7, $5
-; MIPS32EB-NEXT: srlv $2, $2, $1
-; MIPS32EB-NEXT: sll $2, $2, 24
-; MIPS32EB-NEXT: sra $2, $2, 24
-; MIPS32EB-NEXT: # %bb.3: # %entry
+; MIPS32EB-NEXT: srlv $1, $5, $2
+; MIPS32EB-NEXT: sll $1, $1, 24
; MIPS32EB-NEXT: jr $ra
-; MIPS32EB-NEXT: nop
+; MIPS32EB-NEXT: sra $2, $1, 24
entry:
%0 = atomicrmw nand ptr @y, i8 %incr monotonic
ret i8 %0
@@ -3769,69 +3630,60 @@ define signext i8 @AtomicSwap8(i8 signext %newval) nounwind {
; MIPS32-NEXT: lui $2, %hi(_gp_disp)
; MIPS32-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32-NEXT: addu $1, $2, $25
-; MIPS32-NEXT: lw $1, %got(y)($1)
; MIPS32-NEXT: addiu $2, $zero, -4
-; MIPS32-NEXT: and $3, $1, $2
+; MIPS32-NEXT: lw $1, %got(y)($1)
+; MIPS32-NEXT: and $2, $1, $2
; MIPS32-NEXT: andi $1, $1, 3
; MIPS32-NEXT: sll $1, $1, 3
-; MIPS32-NEXT: ori $2, $zero, 255
-; MIPS32-NEXT: sllv $5, $2, $1
-; MIPS32-NEXT: nor $6, $zero, $5
+; MIPS32-NEXT: addiu $3, $zero, 255
+; MIPS32-NEXT: sllv $3, $3, $1
+; MIPS32-NEXT: andi $4, $4, 255
; MIPS32-NEXT: sllv $4, $4, $1
; MIPS32-NEXT: $BB11_1: # %entry
; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32-NEXT: ll $7, 0($3)
-; MIPS32-NEXT: and $8, $4, $5
-; MIPS32-NEXT: and $9, $7, $6
-; MIPS32-NEXT: or $9, $9, $8
-; MIPS32-NEXT: sc $9, 0($3)
-; MIPS32-NEXT: beqz $9, $BB11_1
+; MIPS32-NEXT: ll $5, 0($2)
+; MIPS32-NEXT: xor $6, $5, $4
+; MIPS32-NEXT: and $6, $6, $3
+; MIPS32-NEXT: xor $6, $5, $6
+; MIPS32-NEXT: sc $6, 0($2)
+; MIPS32-NEXT: beqz $6, $BB11_1
; MIPS32-NEXT: nop
; MIPS32-NEXT: # %bb.2: # %entry
-; MIPS32-NEXT: and $2, $7, $5
-; MIPS32-NEXT: srlv $2, $2, $1
-; MIPS32-NEXT: sll $2, $2, 24
-; MIPS32-NEXT: sra $2, $2, 24
-; MIPS32-NEXT: # %bb.3: # %entry
+; MIPS32-NEXT: srlv $1, $5, $1
+; MIPS32-NEXT: sll $1, $1, 24
; MIPS32-NEXT: jr $ra
-; MIPS32-NEXT: nop
+; MIPS32-NEXT: sra $2, $1, 24
;
; MIPS32O0-LABEL: AtomicSwap8:
; MIPS32O0: # %bb.0: # %entry
; MIPS32O0-NEXT: lui $2, %hi(_gp_disp)
; MIPS32O0-NEXT: addiu $2, $2, %lo(_gp_disp)
-; MIPS32O0-NEXT: addiu $sp, $sp, -8
-; MIPS32O0-NEXT: addu $1, $2, $25
-; MIPS32O0-NEXT: lw $1, %got(y)($1)
-; MIPS32O0-NEXT: addiu $2, $zero, -4
-; MIPS32O0-NEXT: and $5, $1, $2
-; MIPS32O0-NEXT: andi $1, $1, 3
-; MIPS32O0-NEXT: sll $9, $1, 3
-; MIPS32O0-NEXT: ori $1, $zero, 255
-; MIPS32O0-NEXT: sllv $7, $1, $9
-; MIPS32O0-NEXT: nor $8, $zero, $7
-; MIPS32O0-NEXT: sllv $6, $4, $9
+; MIPS32O0-NEXT: addu $2, $2, $25
+; MIPS32O0-NEXT: move $1, $4
+; MIPS32O0-NEXT: lw $3, %got(y)($2)
+; MIPS32O0-NEXT: addiu $4, $zero, -4
+; MIPS32O0-NEXT: and $4, $3, $4
+; MIPS32O0-NEXT: lw $2, %got(y)($2)
+; MIPS32O0-NEXT: addiu $3, $zero, 3
+; MIPS32O0-NEXT: and $2, $2, $3
+; MIPS32O0-NEXT: sll $2, $2, 3
+; MIPS32O0-NEXT: addiu $3, $zero, 255
+; MIPS32O0-NEXT: sllv $6, $3, $2
+; MIPS32O0-NEXT: andi $1, $1, 255
+; MIPS32O0-NEXT: sllv $5, $1, $2
; MIPS32O0-NEXT: $BB11_1: # %entry
; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32O0-NEXT: ll $2, 0($5)
-; MIPS32O0-NEXT: and $3, $6, $7
-; MIPS32O0-NEXT: and $4, $2, $8
-; MIPS32O0-NEXT: or $4, $4, $3
-; MIPS32O0-NEXT: sc $4, 0($5)
-; MIPS32O0-NEXT: beqz $4, $BB11_1
-; MIPS32O0-NEXT: nop
+; MIPS32O0-NEXT: ll $1, 0($4)
+; MIPS32O0-NEXT: xor $3, $1, $5
+; MIPS32O0-NEXT: and $3, $3, $6
+; MIPS32O0-NEXT: xor $3, $1, $3
+; MIPS32O0-NEXT: sc $3, 0($4)
+; MIPS32O0-NEXT: beqz $3, $BB11_1
+; MIPS32O0-NEXT: nop
; MIPS32O0-NEXT: # %bb.2: # %entry
-; MIPS32O0-NEXT: and $1, $2, $7
-; MIPS32O0-NEXT: srlv $1, $1, $9
-; MIPS32O0-NEXT: sll $1, $1, 24
-; MIPS32O0-NEXT: sra $1, $1, 24
-; MIPS32O0-NEXT: # %bb.3: # %entry
-; MIPS32O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32O0-NEXT: # %bb.4: # %entry
-; MIPS32O0-NEXT: lw $1, 4($sp) # 4-byte Folded Reload
+; MIPS32O0-NEXT: srlv $1, $1, $2
; MIPS32O0-NEXT: sll $1, $1, 24
; MIPS32O0-NEXT: sra $2, $1, 24
-; MIPS32O0-NEXT: addiu $sp, $sp, 8
; MIPS32O0-NEXT: jr $ra
; MIPS32O0-NEXT: nop
;
@@ -3840,93 +3692,82 @@ define signext i8 @AtomicSwap8(i8 signext %newval) nounwind {
; MIPS32R2-NEXT: lui $2, %hi(_gp_disp)
; MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32R2-NEXT: addu $1, $2, $25
-; MIPS32R2-NEXT: lw $1, %got(y)($1)
; MIPS32R2-NEXT: addiu $2, $zero, -4
-; MIPS32R2-NEXT: and $3, $1, $2
+; MIPS32R2-NEXT: lw $1, %got(y)($1)
+; MIPS32R2-NEXT: and $2, $1, $2
; MIPS32R2-NEXT: andi $1, $1, 3
; MIPS32R2-NEXT: sll $1, $1, 3
-; MIPS32R2-NEXT: ori $2, $zero, 255
-; MIPS32R2-NEXT: sllv $5, $2, $1
-; MIPS32R2-NEXT: nor $6, $zero, $5
+; MIPS32R2-NEXT: addiu $3, $zero, 255
+; MIPS32R2-NEXT: sllv $3, $3, $1
+; MIPS32R2-NEXT: andi $4, $4, 255
; MIPS32R2-NEXT: sllv $4, $4, $1
; MIPS32R2-NEXT: $BB11_1: # %entry
; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32R2-NEXT: ll $7, 0($3)
-; MIPS32R2-NEXT: and $8, $4, $5
-; MIPS32R2-NEXT: and $9, $7, $6
-; MIPS32R2-NEXT: or $9, $9, $8
-; MIPS32R2-NEXT: sc $9, 0($3)
-; MIPS32R2-NEXT: beqz $9, $BB11_1
+; MIPS32R2-NEXT: ll $5, 0($2)
+; MIPS32R2-NEXT: xor $6, $5, $4
+; MIPS32R2-NEXT: and $6, $6, $3
+; MIPS32R2-NEXT: xor $6, $5, $6
+; MIPS32R2-NEXT: sc $6, 0($2)
+; MIPS32R2-NEXT: beqz $6, $BB11_1
; MIPS32R2-NEXT: nop
; MIPS32R2-NEXT: # %bb.2: # %entry
-; MIPS32R2-NEXT: and $2, $7, $5
-; MIPS32R2-NEXT: srlv $2, $2, $1
-; MIPS32R2-NEXT: seb $2, $2
-; MIPS32R2-NEXT: # %bb.3: # %entry
+; MIPS32R2-NEXT: srlv $1, $5, $1
; MIPS32R2-NEXT: jr $ra
-; MIPS32R2-NEXT: nop
+; MIPS32R2-NEXT: seb $2, $1
;
; MIPS32R6-LABEL: AtomicSwap8:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lui $2, %hi(_gp_disp)
; MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32R6-NEXT: addu $1, $2, $25
-; MIPS32R6-NEXT: lw $1, %got(y)($1)
; MIPS32R6-NEXT: addiu $2, $zero, -4
-; MIPS32R6-NEXT: and $3, $1, $2
+; MIPS32R6-NEXT: lw $1, %got(y)($1)
+; MIPS32R6-NEXT: and $2, $1, $2
; MIPS32R6-NEXT: andi $1, $1, 3
; MIPS32R6-NEXT: sll $1, $1, 3
-; MIPS32R6-NEXT: ori $2, $zero, 255
-; MIPS32R6-NEXT: sllv $5, $2, $1
-; MIPS32R6-NEXT: nor $6, $zero, $5
+; MIPS32R6-NEXT: addiu $3, $zero, 255
+; MIPS32R6-NEXT: sllv $3, $3, $1
+; MIPS32R6-NEXT: andi $4, $4, 255
; MIPS32R6-NEXT: sllv $4, $4, $1
; MIPS32R6-NEXT: $BB11_1: # %entry
; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32R6-NEXT: ll $7, 0($3)
-; MIPS32R6-NEXT: and $8, $4, $5
-; MIPS32R6-NEXT: and $9, $7, $6
-; MIPS32R6-NEXT: or $9, $9, $8
-; MIPS32R6-NEXT: sc $9, 0($3)
-; MIPS32R6-NEXT: beqzc $9, $BB11_1
+; MIPS32R6-NEXT: ll $5, 0($2)
+; MIPS32R6-NEXT: xor $6, $5, $4
+; MIPS32R6-NEXT: and $6, $6, $3
+; MIPS32R6-NEXT: xor $6, $5, $6
+; MIPS32R6-NEXT: sc $6, 0($2)
+; MIPS32R6-NEXT: beqzc $6, $BB11_1
; MIPS32R6-NEXT: # %bb.2: # %entry
-; MIPS32R6-NEXT: and $2, $7, $5
-; MIPS32R6-NEXT: srlv $2, $2, $1
-; MIPS32R6-NEXT: seb $2, $2
-; MIPS32R6-NEXT: # %bb.3: # %entry
-; MIPS32R6-NEXT: jrc $ra
+; MIPS32R6-NEXT: srlv $1, $5, $1
+; MIPS32R6-NEXT: jr $ra
+; MIPS32R6-NEXT: seb $2, $1
;
; MIPS32R6O0-LABEL: AtomicSwap8:
; MIPS32R6O0: # %bb.0: # %entry
; MIPS32R6O0-NEXT: lui $2, %hi(_gp_disp)
; MIPS32R6O0-NEXT: addiu $2, $2, %lo(_gp_disp)
-; MIPS32R6O0-NEXT: addiu $sp, $sp, -8
-; MIPS32R6O0-NEXT: addu $1, $2, $25
-; MIPS32R6O0-NEXT: lw $1, %got(y)($1)
-; MIPS32R6O0-NEXT: addiu $2, $zero, -4
-; MIPS32R6O0-NEXT: and $5, $1, $2
-; MIPS32R6O0-NEXT: andi $1, $1, 3
-; MIPS32R6O0-NEXT: sll $9, $1, 3
-; MIPS32R6O0-NEXT: ori $1, $zero, 255
-; MIPS32R6O0-NEXT: sllv $7, $1, $9
-; MIPS32R6O0-NEXT: nor $8, $zero, $7
-; MIPS32R6O0-NEXT: sllv $6, $4, $9
+; MIPS32R6O0-NEXT: addu $2, $2, $25
+; MIPS32R6O0-NEXT: move $1, $4
+; MIPS32R6O0-NEXT: lw $2, %got(y)($2)
+; MIPS32R6O0-NEXT: addiu $3, $zero, -4
+; MIPS32R6O0-NEXT: and $4, $2, $3
+; MIPS32R6O0-NEXT: andi $2, $2, 3
+; MIPS32R6O0-NEXT: sll $2, $2, 3
+; MIPS32R6O0-NEXT: addiu $3, $zero, 255
+; MIPS32R6O0-NEXT: sllv $6, $3, $2
+; MIPS32R6O0-NEXT: andi $1, $1, 255
+; MIPS32R6O0-NEXT: sllv $5, $1, $2
; MIPS32R6O0-NEXT: $BB11_1: # %entry
; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32R6O0-NEXT: ll $2, 0($5)
-; MIPS32R6O0-NEXT: and $3, $6, $7
-; MIPS32R6O0-NEXT: and $4, $2, $8
-; MIPS32R6O0-NEXT: or $4, $4, $3
-; MIPS32R6O0-NEXT: sc $4, 0($5)
-; MIPS32R6O0-NEXT: beqzc $4, $BB11_1
+; MIPS32R6O0-NEXT: ll $1, 0($4)
+; MIPS32R6O0-NEXT: xor $3, $1, $5
+; MIPS32R6O0-NEXT: and $3, $3, $6
+; MIPS32R6O0-NEXT: xor $3, $1, $3
+; MIPS32R6O0-NEXT: sc $3, 0($4)
+; MIPS32R6O0-NEXT: beqzc $3, $BB11_1
; MIPS32R6O0-NEXT: # %bb.2: # %entry
-; MIPS32R6O0-NEXT: and $1, $2, $7
-; MIPS32R6O0-NEXT: srlv $1, $1, $9
-; MIPS32R6O0-NEXT: seb $1, $1
-; MIPS32R6O0-NEXT: # %bb.3: # %entry
-; MIPS32R6O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32R6O0-NEXT: # %bb.4: # %entry
-; MIPS32R6O0-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
-; MIPS32R6O0-NEXT: addiu $sp, $sp, 8
+; MIPS32R6O0-NEXT: srlv $1, $1, $2
+; MIPS32R6O0-NEXT: seb $2, $1
; MIPS32R6O0-NEXT: jrc $ra
;
; MIPS4-LABEL: AtomicSwap8:
@@ -3935,31 +3776,29 @@ define signext i8 @AtomicSwap8(i8 signext %newval) nounwind {
; MIPS4-NEXT: daddu $1, $1, $25
; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicSwap8)))
; MIPS4-NEXT: ld $1, %got_disp(y)($1)
-; MIPS4-NEXT: daddiu $2, $zero, -4
-; MIPS4-NEXT: and $3, $1, $2
-; MIPS4-NEXT: andi $1, $1, 3
-; MIPS4-NEXT: sll $1, $1, 3
-; MIPS4-NEXT: ori $2, $zero, 255
-; MIPS4-NEXT: sllv $5, $2, $1
-; MIPS4-NEXT: nor $6, $zero, $5
-; MIPS4-NEXT: sllv $4, $4, $1
+; MIPS4-NEXT: sll $2, $1, 0
+; MIPS4-NEXT: andi $2, $2, 3
+; MIPS4-NEXT: daddiu $3, $zero, -4
+; MIPS4-NEXT: and $1, $1, $3
+; MIPS4-NEXT: sll $2, $2, 3
+; MIPS4-NEXT: addiu $3, $zero, 255
+; MIPS4-NEXT: sllv $3, $3, $2
+; MIPS4-NEXT: andi $4, $4, 255
+; MIPS4-NEXT: sllv $4, $4, $2
; MIPS4-NEXT: .LBB11_1: # %entry
; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS4-NEXT: ll $7, 0($3)
-; MIPS4-NEXT: and $8, $4, $5
-; MIPS4-NEXT: and $9, $7, $6
-; MIPS4-NEXT: or $9, $9, $8
-; MIPS4-NEXT: sc $9, 0($3)
-; MIPS4-NEXT: beqz $9, .LBB11_1
+; MIPS4-NEXT: ll $5, 0($1)
+; MIPS4-NEXT: xor $6, $5, $4
+; MIPS4-NEXT: and $6, $6, $3
+; MIPS4-NEXT: xor $6, $5, $6
+; MIPS4-NEXT: sc $6, 0($1)
+; MIPS4-NEXT: beqz $6, .LBB11_1
; MIPS4-NEXT: nop
; MIPS4-NEXT: # %bb.2: # %entry
-; MIPS4-NEXT: and $2, $7, $5
-; MIPS4-NEXT: srlv $2, $2, $1
-; MIPS4-NEXT: sll $2, $2, 24
-; MIPS4-NEXT: sra $2, $2, 24
-; MIPS4-NEXT: # %bb.3: # %entry
+; MIPS4-NEXT: srlv $1, $5, $2
+; MIPS4-NEXT: sll $1, $1, 24
; MIPS4-NEXT: jr $ra
-; MIPS4-NEXT: nop
+; MIPS4-NEXT: sra $2, $1, 24
;
; MIPS64-LABEL: AtomicSwap8:
; MIPS64: # %bb.0: # %entry
@@ -3967,31 +3806,29 @@ define signext i8 @AtomicSwap8(i8 signext %newval) nounwind {
; MIPS64-NEXT: daddu $1, $1, $25
; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicSwap8)))
; MIPS64-NEXT: ld $1, %got_disp(y)($1)
-; MIPS64-NEXT: daddiu $2, $zero, -4
-; MIPS64-NEXT: and $3, $1, $2
-; MIPS64-NEXT: andi $1, $1, 3
-; MIPS64-NEXT: sll $1, $1, 3
-; MIPS64-NEXT: ori $2, $zero, 255
-; MIPS64-NEXT: sllv $5, $2, $1
-; MIPS64-NEXT: nor $6, $zero, $5
-; MIPS64-NEXT: sllv $4, $4, $1
+; MIPS64-NEXT: sll $2, $1, 0
+; MIPS64-NEXT: andi $2, $2, 3
+; MIPS64-NEXT: daddiu $3, $zero, -4
+; MIPS64-NEXT: and $1, $1, $3
+; MIPS64-NEXT: sll $2, $2, 3
+; MIPS64-NEXT: addiu $3, $zero, 255
+; MIPS64-NEXT: sllv $3, $3, $2
+; MIPS64-NEXT: andi $4, $4, 255
+; MIPS64-NEXT: sllv $4, $4, $2
; MIPS64-NEXT: .LBB11_1: # %entry
; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64-NEXT: ll $7, 0($3)
-; MIPS64-NEXT: and $8, $4, $5
-; MIPS64-NEXT: and $9, $7, $6
-; MIPS64-NEXT: or $9, $9, $8
-; MIPS64-NEXT: sc $9, 0($3)
-; MIPS64-NEXT: beqz $9, .LBB11_1
+; MIPS64-NEXT: ll $5, 0($1)
+; MIPS64-NEXT: xor $6, $5, $4
+; MIPS64-NEXT: and $6, $6, $3
+; MIPS64-NEXT: xor $6, $5, $6
+; MIPS64-NEXT: sc $6, 0($1)
+; MIPS64-NEXT: beqz $6, .LBB11_1
; MIPS64-NEXT: nop
; MIPS64-NEXT: # %bb.2: # %entry
-; MIPS64-NEXT: and $2, $7, $5
-; MIPS64-NEXT: srlv $2, $2, $1
-; MIPS64-NEXT: sll $2, $2, 24
-; MIPS64-NEXT: sra $2, $2, 24
-; MIPS64-NEXT: # %bb.3: # %entry
+; MIPS64-NEXT: srlv $1, $5, $2
+; MIPS64-NEXT: sll $1, $1, 24
; MIPS64-NEXT: jr $ra
-; MIPS64-NEXT: nop
+; MIPS64-NEXT: sra $2, $1, 24
;
; MIPS64R2-LABEL: AtomicSwap8:
; MIPS64R2: # %bb.0: # %entry
@@ -3999,30 +3836,28 @@ define signext i8 @AtomicSwap8(i8 signext %newval) nounwind {
; MIPS64R2-NEXT: daddu $1, $1, $25
; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicSwap8)))
; MIPS64R2-NEXT: ld $1, %got_disp(y)($1)
-; MIPS64R2-NEXT: daddiu $2, $zero, -4
-; MIPS64R2-NEXT: and $3, $1, $2
-; MIPS64R2-NEXT: andi $1, $1, 3
-; MIPS64R2-NEXT: sll $1, $1, 3
-; MIPS64R2-NEXT: ori $2, $zero, 255
-; MIPS64R2-NEXT: sllv $5, $2, $1
-; MIPS64R2-NEXT: nor $6, $zero, $5
-; MIPS64R2-NEXT: sllv $4, $4, $1
+; MIPS64R2-NEXT: sll $2, $1, 0
+; MIPS64R2-NEXT: andi $2, $2, 3
+; MIPS64R2-NEXT: daddiu $3, $zero, -4
+; MIPS64R2-NEXT: and $1, $1, $3
+; MIPS64R2-NEXT: sll $2, $2, 3
+; MIPS64R2-NEXT: addiu $3, $zero, 255
+; MIPS64R2-NEXT: sllv $3, $3, $2
+; MIPS64R2-NEXT: andi $4, $4, 255
+; MIPS64R2-NEXT: sllv $4, $4, $2
; MIPS64R2-NEXT: .LBB11_1: # %entry
; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R2-NEXT: ll $7, 0($3)
-; MIPS64R2-NEXT: and $8, $4, $5
-; MIPS64R2-NEXT: and $9, $7, $6
-; MIPS64R2-NEXT: or $9, $9, $8
-; MIPS64R2-NEXT: sc $9, 0($3)
-; MIPS64R2-NEXT: beqz $9, .LBB11_1
+; MIPS64R2-NEXT: ll $5, 0($1)
+; MIPS64R2-NEXT: xor $6, $5, $4
+; MIPS64R2-NEXT: and $6, $6, $3
+; MIPS64R2-NEXT: xor $6, $5, $6
+; MIPS64R2-NEXT: sc $6, 0($1)
+; MIPS64R2-NEXT: beqz $6, .LBB11_1
; MIPS64R2-NEXT: nop
; MIPS64R2-NEXT: # %bb.2: # %entry
-; MIPS64R2-NEXT: and $2, $7, $5
-; MIPS64R2-NEXT: srlv $2, $2, $1
-; MIPS64R2-NEXT: seb $2, $2
-; MIPS64R2-NEXT: # %bb.3: # %entry
+; MIPS64R2-NEXT: srlv $1, $5, $2
; MIPS64R2-NEXT: jr $ra
-; MIPS64R2-NEXT: nop
+; MIPS64R2-NEXT: seb $2, $1
;
; MIPS64R6-LABEL: AtomicSwap8:
; MIPS64R6: # %bb.0: # %entry
@@ -4030,63 +3865,57 @@ define signext i8 @AtomicSwap8(i8 signext %newval) nounwind {
; MIPS64R6-NEXT: daddu $1, $1, $25
; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicSwap8)))
; MIPS64R6-NEXT: ld $1, %got_disp(y)($1)
-; MIPS64R6-NEXT: daddiu $2, $zero, -4
-; MIPS64R6-NEXT: and $3, $1, $2
-; MIPS64R6-NEXT: andi $1, $1, 3
-; MIPS64R6-NEXT: sll $1, $1, 3
-; MIPS64R6-NEXT: ori $2, $zero, 255
-; MIPS64R6-NEXT: sllv $5, $2, $1
-; MIPS64R6-NEXT: nor $6, $zero, $5
-; MIPS64R6-NEXT: sllv $4, $4, $1
+; MIPS64R6-NEXT: sll $2, $1, 0
+; MIPS64R6-NEXT: andi $2, $2, 3
+; MIPS64R6-NEXT: daddiu $3, $zero, -4
+; MIPS64R6-NEXT: and $1, $1, $3
+; MIPS64R6-NEXT: sll $2, $2, 3
+; MIPS64R6-NEXT: addiu $3, $zero, 255
+; MIPS64R6-NEXT: sllv $3, $3, $2
+; MIPS64R6-NEXT: andi $4, $4, 255
+; MIPS64R6-NEXT: sllv $4, $4, $2
; MIPS64R6-NEXT: .LBB11_1: # %entry
; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R6-NEXT: ll $7, 0($3)
-; MIPS64R6-NEXT: and $8, $4, $5
-; MIPS64R6-NEXT: and $9, $7, $6
-; MIPS64R6-NEXT: or $9, $9, $8
-; MIPS64R6-NEXT: sc $9, 0($3)
-; MIPS64R6-NEXT: beqzc $9, .LBB11_1
+; MIPS64R6-NEXT: ll $5, 0($1)
+; MIPS64R6-NEXT: xor $6, $5, $4
+; MIPS64R6-NEXT: and $6, $6, $3
+; MIPS64R6-NEXT: xor $6, $5, $6
+; MIPS64R6-NEXT: sc $6, 0($1)
+; MIPS64R6-NEXT: beqzc $6, .LBB11_1
; MIPS64R6-NEXT: # %bb.2: # %entry
-; MIPS64R6-NEXT: and $2, $7, $5
-; MIPS64R6-NEXT: srlv $2, $2, $1
-; MIPS64R6-NEXT: seb $2, $2
-; MIPS64R6-NEXT: # %bb.3: # %entry
-; MIPS64R6-NEXT: jrc $ra
+; MIPS64R6-NEXT: srlv $1, $5, $2
+; MIPS64R6-NEXT: jr $ra
+; MIPS64R6-NEXT: seb $2, $1
;
; MIPS64R6O0-LABEL: AtomicSwap8:
; MIPS64R6O0: # %bb.0: # %entry
-; MIPS64R6O0-NEXT: daddiu $sp, $sp, -16
; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicSwap8)))
; MIPS64R6O0-NEXT: daddu $1, $1, $25
; MIPS64R6O0-NEXT: daddiu $2, $1, %lo(%neg(%gp_rel(AtomicSwap8)))
; MIPS64R6O0-NEXT: move $1, $4
; MIPS64R6O0-NEXT: ld $2, %got_disp(y)($2)
; MIPS64R6O0-NEXT: daddiu $3, $zero, -4
-; MIPS64R6O0-NEXT: and $5, $2, $3
+; MIPS64R6O0-NEXT: and $4, $2, $3
+; MIPS64R6O0-NEXT: # kill: def $v0 killed $v0 killed $v0_64
+; MIPS64R6O0-NEXT: sll $2, $2, 0
+; MIPS64R6O0-NEXT: not $2, $2
; MIPS64R6O0-NEXT: andi $2, $2, 3
-; MIPS64R6O0-NEXT: xori $2, $2, 3
-; MIPS64R6O0-NEXT: sll $9, $2, 3
-; MIPS64R6O0-NEXT: ori $2, $zero, 255
-; MIPS64R6O0-NEXT: sllv $7, $2, $9
-; MIPS64R6O0-NEXT: nor $8, $zero, $7
-; MIPS64R6O0-NEXT: sllv $6, $1, $9
+; MIPS64R6O0-NEXT: sll $2, $2, 3
+; MIPS64R6O0-NEXT: addiu $3, $zero, 255
+; MIPS64R6O0-NEXT: sllv $6, $3, $2
+; MIPS64R6O0-NEXT: andi $1, $1, 255
+; MIPS64R6O0-NEXT: sllv $5, $1, $2
; MIPS64R6O0-NEXT: .LBB11_1: # %entry
; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R6O0-NEXT: ll $2, 0($5)
-; MIPS64R6O0-NEXT: and $3, $6, $7
-; MIPS64R6O0-NEXT: and $4, $2, $8
-; MIPS64R6O0-NEXT: or $4, $4, $3
-; MIPS64R6O0-NEXT: sc $4, 0($5)
-; MIPS64R6O0-NEXT: beqzc $4, .LBB11_1
+; MIPS64R6O0-NEXT: ll $1, 0($4)
+; MIPS64R6O0-NEXT: xor $3, $1, $5
+; MIPS64R6O0-NEXT: and $3, $3, $6
+; MIPS64R6O0-NEXT: xor $3, $1, $3
+; MIPS64R6O0-NEXT: sc $3, 0($4)
+; MIPS64R6O0-NEXT: beqzc $3, .LBB11_1
; MIPS64R6O0-NEXT: # %bb.2: # %entry
-; MIPS64R6O0-NEXT: and $1, $2, $7
-; MIPS64R6O0-NEXT: srlv $1, $1, $9
-; MIPS64R6O0-NEXT: seb $1, $1
-; MIPS64R6O0-NEXT: # %bb.3: # %entry
-; MIPS64R6O0-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64R6O0-NEXT: # %bb.4: # %entry
-; MIPS64R6O0-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
-; MIPS64R6O0-NEXT: daddiu $sp, $sp, 16
+; MIPS64R6O0-NEXT: srlv $1, $1, $2
+; MIPS64R6O0-NEXT: seb $2, $1
; MIPS64R6O0-NEXT: jrc $ra
;
; MM32-LABEL: AtomicSwap8:
@@ -4094,93 +3923,85 @@ define signext i8 @AtomicSwap8(i8 signext %newval) nounwind {
; MM32-NEXT: lui $2, %hi(_gp_disp)
; MM32-NEXT: addiu $2, $2, %lo(_gp_disp)
; MM32-NEXT: addu $2, $2, $25
-; MM32-NEXT: lw $1, %got(y)($2)
-; MM32-NEXT: addiu $2, $zero, -4
-; MM32-NEXT: and $3, $1, $2
-; MM32-NEXT: andi $1, $1, 3
-; MM32-NEXT: sll $1, $1, 3
-; MM32-NEXT: ori $2, $zero, 255
-; MM32-NEXT: sllv $5, $2, $1
-; MM32-NEXT: nor $6, $zero, $5
-; MM32-NEXT: sllv $4, $4, $1
+; MM32-NEXT: addiu $3, $zero, -4
+; MM32-NEXT: lw $2, %got(y)($2)
+; MM32-NEXT: and16 $3, $2
+; MM32-NEXT: andi16 $2, $2, 3
+; MM32-NEXT: sll16 $2, $2, 3
+; MM32-NEXT: addiu $1, $zero, 255
+; MM32-NEXT: sllv $1, $1, $2
+; MM32-NEXT: andi16 $4, $4, 255
+; MM32-NEXT: sllv $4, $4, $2
; MM32-NEXT: $BB11_1: # %entry
; MM32-NEXT: # =>This Inner Loop Header: Depth=1
-; MM32-NEXT: ll $7, 0($3)
-; MM32-NEXT: and $8, $4, $5
-; MM32-NEXT: and $9, $7, $6
-; MM32-NEXT: or $9, $9, $8
-; MM32-NEXT: sc $9, 0($3)
-; MM32-NEXT: beqzc $9, $BB11_1
+; MM32-NEXT: ll $5, 0($3)
+; MM32-NEXT: xor $6, $5, $4
+; MM32-NEXT: and $6, $6, $1
+; MM32-NEXT: xor16 $6, $5
+; MM32-NEXT: sc $6, 0($3)
+; MM32-NEXT: beqzc $6, $BB11_1
; MM32-NEXT: # %bb.2: # %entry
-; MM32-NEXT: and $2, $7, $5
-; MM32-NEXT: srlv $2, $2, $1
-; MM32-NEXT: seb $2, $2
-; MM32-NEXT: # %bb.3: # %entry
-; MM32-NEXT: jrc $ra
+; MM32-NEXT: srlv $1, $5, $2
+; MM32-NEXT: jr $ra
+; MM32-NEXT: seb $2, $1
;
; O1-LABEL: AtomicSwap8:
; O1: # %bb.0: # %entry
; O1-NEXT: lui $2, %hi(_gp_disp)
; O1-NEXT: addiu $2, $2, %lo(_gp_disp)
; O1-NEXT: addu $1, $2, $25
-; O1-NEXT: lw $1, %got(y)($1)
; O1-NEXT: addiu $2, $zero, -4
-; O1-NEXT: and $3, $1, $2
+; O1-NEXT: lw $1, %got(y)($1)
+; O1-NEXT: and $2, $1, $2
; O1-NEXT: andi $1, $1, 3
; O1-NEXT: sll $1, $1, 3
-; O1-NEXT: ori $2, $zero, 255
-; O1-NEXT: sllv $5, $2, $1
-; O1-NEXT: nor $6, $zero, $5
+; O1-NEXT: addiu $3, $zero, 255
+; O1-NEXT: sllv $3, $3, $1
+; O1-NEXT: andi $4, $4, 255
; O1-NEXT: sllv $4, $4, $1
; O1-NEXT: $BB11_1: # %entry
; O1-NEXT: # =>This Inner Loop Header: Depth=1
-; O1-NEXT: ll $7, 0($3)
-; O1-NEXT: and $8, $4, $5
-; O1-NEXT: and $9, $7, $6
-; O1-NEXT: or $9, $9, $8
-; O1-NEXT: sc $9, 0($3)
-; O1-NEXT: beqz $9, $BB11_1
+; O1-NEXT: ll $5, 0($2)
+; O1-NEXT: xor $6, $5, $4
+; O1-NEXT: and $6, $6, $3
+; O1-NEXT: xor $6, $5, $6
+; O1-NEXT: sc $6, 0($2)
+; O1-NEXT: beqz $6, $BB11_1
; O1-NEXT: nop
; O1-NEXT: # %bb.2: # %entry
-; O1-NEXT: and $2, $7, $5
-; O1-NEXT: srlv $2, $2, $1
-; O1-NEXT: sll $2, $2, 24
-; O1-NEXT: sra $2, $2, 24
-; O1-NEXT: # %bb.3: # %entry
+; O1-NEXT: srlv $1, $5, $1
+; O1-NEXT: sll $1, $1, 24
; O1-NEXT: jr $ra
-; O1-NEXT: nop
+; O1-NEXT: sra $2, $1, 24
;
; O2-LABEL: AtomicSwap8:
; O2: # %bb.0: # %entry
; O2-NEXT: lui $2, %hi(_gp_disp)
; O2-NEXT: addiu $2, $2, %lo(_gp_disp)
; O2-NEXT: addu $1, $2, $25
-; O2-NEXT: lw $1, %got(y)($1)
; O2-NEXT: addiu $2, $zero, -4
-; O2-NEXT: and $3, $1, $2
+; O2-NEXT: lw $1, %got(y)($1)
+; O2-NEXT: and $2, $1, $2
; O2-NEXT: andi $1, $1, 3
; O2-NEXT: sll $1, $1, 3
-; O2-NEXT: ori $2, $zero, 255
-; O2-NEXT: sllv $5, $2, $1
-; O2-NEXT: nor $6, $zero, $5
+; O2-NEXT: addiu $3, $zero, 255
+; O2-NEXT: sllv $3, $3, $1
+; O2-NEXT: andi $4, $4, 255
; O2-NEXT: sllv $4, $4, $1
; O2-NEXT: $BB11_1: # %entry
; O2-NEXT: # =>This Inner Loop Header: Depth=1
-; O2-NEXT: ll $7, 0($3)
-; O2-NEXT: and $8, $4, $5
-; O2-NEXT: and $9, $7, $6
-; O2-NEXT: or $9, $9, $8
-; O2-NEXT: sc $9, 0($3)
-; O2-NEXT: beqz $9, $BB11_1
+; O2-NEXT: ll $5, 0($2)
+; O2-NEXT: xor $6, $5, $4
+; O2-NEXT: and $6, $6, $3
+; O2-NEXT: xor $6, $5, $6
+; O2-NEXT: sc $6, 0($2)
+; O2-NEXT: beqz $6, $BB11_1
; O2-NEXT: nop
; O2-NEXT: # %bb.2: # %entry
-; O2-NEXT: and $2, $7, $5
-; O2-NEXT: srlv $2, $2, $1
-; O2-NEXT: sll $2, $2, 24
-; O2-NEXT: sra $2, $2, 24
-; O2-NEXT: # %bb.3: # %entry
+; O2-NEXT: srlv $1, $5, $1
+; O2-NEXT: sll $1, $1, 24
; O2-NEXT: jr $ra
-; O2-NEXT: nop
+; O2-NEXT: sra $2, $1, 24
;
; O3-LABEL: AtomicSwap8:
; O3: # %bb.0: # %entry
@@ -4188,31 +4009,28 @@ define signext i8 @AtomicSwap8(i8 signext %newval) nounwind {
; O3-NEXT: addiu $2, $2, %lo(_gp_disp)
; O3-NEXT: addu $1, $2, $25
; O3-NEXT: addiu $2, $zero, -4
+; O3-NEXT: addiu $3, $zero, 255
+; O3-NEXT: andi $4, $4, 255
; O3-NEXT: lw $1, %got(y)($1)
-; O3-NEXT: and $3, $1, $2
+; O3-NEXT: and $2, $1, $2
; O3-NEXT: andi $1, $1, 3
-; O3-NEXT: ori $2, $zero, 255
; O3-NEXT: sll $1, $1, 3
-; O3-NEXT: sllv $5, $2, $1
+; O3-NEXT: sllv $3, $3, $1
; O3-NEXT: sllv $4, $4, $1
-; O3-NEXT: nor $6, $zero, $5
; O3-NEXT: $BB11_1: # %entry
; O3-NEXT: # =>This Inner Loop Header: Depth=1
-; O3-NEXT: ll $7, 0($3)
-; O3-NEXT: and $8, $4, $5
-; O3-NEXT: and $9, $7, $6
-; O3-NEXT: or $9, $9, $8
-; O3-NEXT: sc $9, 0($3)
-; O3-NEXT: beqz $9, $BB11_1
+; O3-NEXT: ll $5, 0($2)
+; O3-NEXT: xor $6, $5, $4
+; O3-NEXT: and $6, $6, $3
+; O3-NEXT: xor $6, $5, $6
+; O3-NEXT: sc $6, 0($2)
+; O3-NEXT: beqz $6, $BB11_1
; O3-NEXT: nop
; O3-NEXT: # %bb.2: # %entry
-; O3-NEXT: and $2, $7, $5
-; O3-NEXT: srlv $2, $2, $1
-; O3-NEXT: sll $2, $2, 24
-; O3-NEXT: sra $2, $2, 24
-; O3-NEXT: # %bb.3: # %entry
+; O3-NEXT: srlv $1, $5, $1
+; O3-NEXT: sll $1, $1, 24
; O3-NEXT: jr $ra
-; O3-NEXT: nop
+; O3-NEXT: sra $2, $1, 24
;
; MIPS32EB-LABEL: AtomicSwap8:
; MIPS32EB: # %bb.0: # %entry
@@ -4220,32 +4038,29 @@ define signext i8 @AtomicSwap8(i8 signext %newval) nounwind {
; MIPS32EB-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32EB-NEXT: addu $1, $2, $25
; MIPS32EB-NEXT: lw $1, %got(y)($1)
-; MIPS32EB-NEXT: addiu $2, $zero, -4
-; MIPS32EB-NEXT: and $3, $1, $2
-; MIPS32EB-NEXT: andi $1, $1, 3
-; MIPS32EB-NEXT: xori $1, $1, 3
-; MIPS32EB-NEXT: sll $1, $1, 3
-; MIPS32EB-NEXT: ori $2, $zero, 255
-; MIPS32EB-NEXT: sllv $5, $2, $1
-; MIPS32EB-NEXT: nor $6, $zero, $5
-; MIPS32EB-NEXT: sllv $4, $4, $1
+; MIPS32EB-NEXT: not $2, $1
+; MIPS32EB-NEXT: addiu $3, $zero, -4
+; MIPS32EB-NEXT: and $1, $1, $3
+; MIPS32EB-NEXT: andi $2, $2, 3
+; MIPS32EB-NEXT: sll $2, $2, 3
+; MIPS32EB-NEXT: addiu $3, $zero, 255
+; MIPS32EB-NEXT: sllv $3, $3, $2
+; MIPS32EB-NEXT: andi $4, $4, 255
+; MIPS32EB-NEXT: sllv $4, $4, $2
; MIPS32EB-NEXT: $BB11_1: # %entry
; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32EB-NEXT: ll $7, 0($3)
-; MIPS32EB-NEXT: and $8, $4, $5
-; MIPS32EB-NEXT: and $9, $7, $6
-; MIPS32EB-NEXT: or $9, $9, $8
-; MIPS32EB-NEXT: sc $9, 0($3)
-; MIPS32EB-NEXT: beqz $9, $BB11_1
+; MIPS32EB-NEXT: ll $5, 0($1)
+; MIPS32EB-NEXT: xor $6, $5, $4
+; MIPS32EB-NEXT: and $6, $6, $3
+; MIPS32EB-NEXT: xor $6, $5, $6
+; MIPS32EB-NEXT: sc $6, 0($1)
+; MIPS32EB-NEXT: beqz $6, $BB11_1
; MIPS32EB-NEXT: nop
; MIPS32EB-NEXT: # %bb.2: # %entry
-; MIPS32EB-NEXT: and $2, $7, $5
-; MIPS32EB-NEXT: srlv $2, $2, $1
-; MIPS32EB-NEXT: sll $2, $2, 24
-; MIPS32EB-NEXT: sra $2, $2, 24
-; MIPS32EB-NEXT: # %bb.3: # %entry
+; MIPS32EB-NEXT: srlv $1, $5, $2
+; MIPS32EB-NEXT: sll $1, $1, 24
; MIPS32EB-NEXT: jr $ra
-; MIPS32EB-NEXT: nop
+; MIPS32EB-NEXT: sra $2, $1, 24
entry:
%0 = atomicrmw xchg ptr @y, i8 %newval monotonic
ret i8 %0
@@ -4258,82 +4073,70 @@ define signext i8 @AtomicCmpSwap8(i8 signext %oldval, i8 signext %newval) nounwi
; MIPS32-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32-NEXT: addu $1, $2, $25
; MIPS32-NEXT: lw $1, %got(y)($1)
-; MIPS32-NEXT: addiu $2, $zero, -4
-; MIPS32-NEXT: and $3, $1, $2
-; MIPS32-NEXT: andi $1, $1, 3
-; MIPS32-NEXT: sll $1, $1, 3
-; MIPS32-NEXT: ori $2, $zero, 255
-; MIPS32-NEXT: sllv $6, $2, $1
-; MIPS32-NEXT: nor $7, $zero, $6
-; MIPS32-NEXT: andi $2, $4, 255
-; MIPS32-NEXT: sllv $4, $2, $1
-; MIPS32-NEXT: andi $2, $5, 255
-; MIPS32-NEXT: sllv $5, $2, $1
+; MIPS32-NEXT: andi $2, $1, 3
+; MIPS32-NEXT: sll $2, $2, 3
+; MIPS32-NEXT: addiu $3, $zero, 255
+; MIPS32-NEXT: addiu $6, $zero, -4
+; MIPS32-NEXT: and $1, $1, $6
+; MIPS32-NEXT: sllv $3, $3, $2
+; MIPS32-NEXT: andi $5, $5, 255
+; MIPS32-NEXT: sllv $5, $5, $2
+; MIPS32-NEXT: andi $4, $4, 255
+; MIPS32-NEXT: sllv $4, $4, $2
; MIPS32-NEXT: $BB12_1: # %entry
; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32-NEXT: ll $8, 0($3)
-; MIPS32-NEXT: and $9, $8, $6
-; MIPS32-NEXT: bne $9, $4, $BB12_3
+; MIPS32-NEXT: ll $6, 0($1)
+; MIPS32-NEXT: and $7, $6, $3
+; MIPS32-NEXT: bne $7, $4, $BB12_3
; MIPS32-NEXT: nop
; MIPS32-NEXT: # %bb.2: # %entry
; MIPS32-NEXT: # in Loop: Header=BB12_1 Depth=1
-; MIPS32-NEXT: and $8, $8, $7
-; MIPS32-NEXT: or $8, $8, $5
-; MIPS32-NEXT: sc $8, 0($3)
-; MIPS32-NEXT: beqz $8, $BB12_1
+; MIPS32-NEXT: xor $7, $6, $7
+; MIPS32-NEXT: or $7, $7, $5
+; MIPS32-NEXT: sc $7, 0($1)
+; MIPS32-NEXT: beqz $7, $BB12_1
; MIPS32-NEXT: nop
; MIPS32-NEXT: $BB12_3: # %entry
-; MIPS32-NEXT: srlv $2, $9, $1
-; MIPS32-NEXT: sll $2, $2, 24
-; MIPS32-NEXT: sra $2, $2, 24
-; MIPS32-NEXT: # %bb.4: # %entry
+; MIPS32-NEXT: srlv $1, $6, $2
+; MIPS32-NEXT: sll $1, $1, 24
; MIPS32-NEXT: jr $ra
-; MIPS32-NEXT: nop
+; MIPS32-NEXT: sra $2, $1, 24
;
; MIPS32O0-LABEL: AtomicCmpSwap8:
; MIPS32O0: # %bb.0: # %entry
; MIPS32O0-NEXT: lui $2, %hi(_gp_disp)
; MIPS32O0-NEXT: addiu $2, $2, %lo(_gp_disp)
-; MIPS32O0-NEXT: addiu $sp, $sp, -8
-; MIPS32O0-NEXT: addu $3, $2, $25
+; MIPS32O0-NEXT: addu $2, $2, $25
; MIPS32O0-NEXT: move $1, $5
-; MIPS32O0-NEXT: move $2, $4
-; MIPS32O0-NEXT: lw $3, %got(y)($3)
+; MIPS32O0-NEXT: move $3, $4
+; MIPS32O0-NEXT: lw $2, %got(y)($2)
; MIPS32O0-NEXT: addiu $4, $zero, -4
-; MIPS32O0-NEXT: and $4, $3, $4
-; MIPS32O0-NEXT: andi $3, $3, 3
-; MIPS32O0-NEXT: sll $9, $3, 3
-; MIPS32O0-NEXT: ori $3, $zero, 255
-; MIPS32O0-NEXT: sllv $5, $3, $9
-; MIPS32O0-NEXT: nor $7, $zero, $5
-; MIPS32O0-NEXT: andi $2, $2, 255
-; MIPS32O0-NEXT: sllv $6, $2, $9
+; MIPS32O0-NEXT: and $4, $2, $4
+; MIPS32O0-NEXT: andi $2, $2, 3
+; MIPS32O0-NEXT: sll $2, $2, 3
+; MIPS32O0-NEXT: addiu $5, $zero, 255
+; MIPS32O0-NEXT: sllv $7, $5, $2
+; MIPS32O0-NEXT: andi $3, $3, 255
+; MIPS32O0-NEXT: sllv $5, $3, $2
; MIPS32O0-NEXT: andi $1, $1, 255
-; MIPS32O0-NEXT: sllv $8, $1, $9
+; MIPS32O0-NEXT: sllv $6, $1, $2
; MIPS32O0-NEXT: $BB12_1: # %entry
; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32O0-NEXT: ll $2, 0($4)
-; MIPS32O0-NEXT: and $3, $2, $5
-; MIPS32O0-NEXT: bne $3, $6, $BB12_3
+; MIPS32O0-NEXT: ll $1, 0($4)
+; MIPS32O0-NEXT: and $3, $1, $7
+; MIPS32O0-NEXT: bne $3, $5, $BB12_3
; MIPS32O0-NEXT: nop
; MIPS32O0-NEXT: # %bb.2: # %entry
; MIPS32O0-NEXT: # in Loop: Header=BB12_1 Depth=1
-; MIPS32O0-NEXT: and $2, $2, $7
-; MIPS32O0-NEXT: or $2, $2, $8
-; MIPS32O0-NEXT: sc $2, 0($4)
-; MIPS32O0-NEXT: beqz $2, $BB12_1
+; MIPS32O0-NEXT: xor $3, $1, $3
+; MIPS32O0-NEXT: or $3, $3, $6
+; MIPS32O0-NEXT: sc $3, 0($4)
+; MIPS32O0-NEXT: beqz $3, $BB12_1
; MIPS32O0-NEXT: nop
; MIPS32O0-NEXT: $BB12_3: # %entry
-; MIPS32O0-NEXT: srlv $1, $3, $9
-; MIPS32O0-NEXT: sll $1, $1, 24
-; MIPS32O0-NEXT: sra $1, $1, 24
-; MIPS32O0-NEXT: # %bb.4: # %entry
-; MIPS32O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32O0-NEXT: # %bb.5: # %entry
-; MIPS32O0-NEXT: lw $1, 4($sp) # 4-byte Folded Reload
+; MIPS32O0-NEXT: srlv $1, $1, $2
; MIPS32O0-NEXT: sll $1, $1, 24
; MIPS32O0-NEXT: sra $2, $1, 24
-; MIPS32O0-NEXT: addiu $sp, $sp, 8
; MIPS32O0-NEXT: jr $ra
; MIPS32O0-NEXT: nop
;
@@ -4343,36 +4146,33 @@ define signext i8 @AtomicCmpSwap8(i8 signext %oldval, i8 signext %newval) nounwi
; MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32R2-NEXT: addu $1, $2, $25
; MIPS32R2-NEXT: lw $1, %got(y)($1)
-; MIPS32R2-NEXT: addiu $2, $zero, -4
-; MIPS32R2-NEXT: and $3, $1, $2
-; MIPS32R2-NEXT: andi $1, $1, 3
-; MIPS32R2-NEXT: sll $1, $1, 3
-; MIPS32R2-NEXT: ori $2, $zero, 255
-; MIPS32R2-NEXT: sllv $6, $2, $1
-; MIPS32R2-NEXT: nor $7, $zero, $6
-; MIPS32R2-NEXT: andi $2, $4, 255
-; MIPS32R2-NEXT: sllv $4, $2, $1
-; MIPS32R2-NEXT: andi $2, $5, 255
-; MIPS32R2-NEXT: sllv $5, $2, $1
+; MIPS32R2-NEXT: andi $2, $1, 3
+; MIPS32R2-NEXT: sll $2, $2, 3
+; MIPS32R2-NEXT: addiu $3, $zero, 255
+; MIPS32R2-NEXT: addiu $6, $zero, -4
+; MIPS32R2-NEXT: and $1, $1, $6
+; MIPS32R2-NEXT: sllv $3, $3, $2
+; MIPS32R2-NEXT: andi $5, $5, 255
+; MIPS32R2-NEXT: sllv $5, $5, $2
+; MIPS32R2-NEXT: andi $4, $4, 255
+; MIPS32R2-NEXT: sllv $4, $4, $2
; MIPS32R2-NEXT: $BB12_1: # %entry
; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32R2-NEXT: ll $8, 0($3)
-; MIPS32R2-NEXT: and $9, $8, $6
-; MIPS32R2-NEXT: bne $9, $4, $BB12_3
+; MIPS32R2-NEXT: ll $6, 0($1)
+; MIPS32R2-NEXT: and $7, $6, $3
+; MIPS32R2-NEXT: bne $7, $4, $BB12_3
; MIPS32R2-NEXT: nop
; MIPS32R2-NEXT: # %bb.2: # %entry
; MIPS32R2-NEXT: # in Loop: Header=BB12_1 Depth=1
-; MIPS32R2-NEXT: and $8, $8, $7
-; MIPS32R2-NEXT: or $8, $8, $5
-; MIPS32R2-NEXT: sc $8, 0($3)
-; MIPS32R2-NEXT: beqz $8, $BB12_1
+; MIPS32R2-NEXT: xor $7, $6, $7
+; MIPS32R2-NEXT: or $7, $7, $5
+; MIPS32R2-NEXT: sc $7, 0($1)
+; MIPS32R2-NEXT: beqz $7, $BB12_1
; MIPS32R2-NEXT: nop
; MIPS32R2-NEXT: $BB12_3: # %entry
-; MIPS32R2-NEXT: srlv $2, $9, $1
-; MIPS32R2-NEXT: seb $2, $2
-; MIPS32R2-NEXT: # %bb.4: # %entry
+; MIPS32R2-NEXT: srlv $1, $6, $2
; MIPS32R2-NEXT: jr $ra
-; MIPS32R2-NEXT: nop
+; MIPS32R2-NEXT: seb $2, $1
;
; MIPS32R6-LABEL: AtomicCmpSwap8:
; MIPS32R6: # %bb.0: # %entry
@@ -4380,73 +4180,64 @@ define signext i8 @AtomicCmpSwap8(i8 signext %oldval, i8 signext %newval) nounwi
; MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32R6-NEXT: addu $1, $2, $25
; MIPS32R6-NEXT: lw $1, %got(y)($1)
-; MIPS32R6-NEXT: addiu $2, $zero, -4
-; MIPS32R6-NEXT: and $3, $1, $2
-; MIPS32R6-NEXT: andi $1, $1, 3
-; MIPS32R6-NEXT: sll $1, $1, 3
-; MIPS32R6-NEXT: ori $2, $zero, 255
-; MIPS32R6-NEXT: sllv $6, $2, $1
-; MIPS32R6-NEXT: nor $7, $zero, $6
-; MIPS32R6-NEXT: andi $2, $4, 255
-; MIPS32R6-NEXT: sllv $4, $2, $1
-; MIPS32R6-NEXT: andi $2, $5, 255
-; MIPS32R6-NEXT: sllv $5, $2, $1
+; MIPS32R6-NEXT: andi $2, $1, 3
+; MIPS32R6-NEXT: sll $2, $2, 3
+; MIPS32R6-NEXT: addiu $3, $zero, 255
+; MIPS32R6-NEXT: addiu $6, $zero, -4
+; MIPS32R6-NEXT: and $1, $1, $6
+; MIPS32R6-NEXT: sllv $3, $3, $2
+; MIPS32R6-NEXT: andi $5, $5, 255
+; MIPS32R6-NEXT: sllv $5, $5, $2
+; MIPS32R6-NEXT: andi $4, $4, 255
+; MIPS32R6-NEXT: sllv $4, $4, $2
; MIPS32R6-NEXT: $BB12_1: # %entry
; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32R6-NEXT: ll $8, 0($3)
-; MIPS32R6-NEXT: and $9, $8, $6
-; MIPS32R6-NEXT: bnec $9, $4, $BB12_3
+; MIPS32R6-NEXT: ll $6, 0($1)
+; MIPS32R6-NEXT: and $7, $6, $3
+; MIPS32R6-NEXT: bnec $7, $4, $BB12_3
; MIPS32R6-NEXT: # %bb.2: # %entry
; MIPS32R6-NEXT: # in Loop: Header=BB12_1 Depth=1
-; MIPS32R6-NEXT: and $8, $8, $7
-; MIPS32R6-NEXT: or $8, $8, $5
-; MIPS32R6-NEXT: sc $8, 0($3)
-; MIPS32R6-NEXT: beqzc $8, $BB12_1
+; MIPS32R6-NEXT: xor $7, $6, $7
+; MIPS32R6-NEXT: or $7, $7, $5
+; MIPS32R6-NEXT: sc $7, 0($1)
+; MIPS32R6-NEXT: beqzc $7, $BB12_1
; MIPS32R6-NEXT: $BB12_3: # %entry
-; MIPS32R6-NEXT: srlv $2, $9, $1
-; MIPS32R6-NEXT: seb $2, $2
-; MIPS32R6-NEXT: # %bb.4: # %entry
-; MIPS32R6-NEXT: jrc $ra
+; MIPS32R6-NEXT: srlv $1, $6, $2
+; MIPS32R6-NEXT: jr $ra
+; MIPS32R6-NEXT: seb $2, $1
;
; MIPS32R6O0-LABEL: AtomicCmpSwap8:
; MIPS32R6O0: # %bb.0: # %entry
; MIPS32R6O0-NEXT: lui $2, %hi(_gp_disp)
; MIPS32R6O0-NEXT: addiu $2, $2, %lo(_gp_disp)
-; MIPS32R6O0-NEXT: addiu $sp, $sp, -8
-; MIPS32R6O0-NEXT: addu $3, $2, $25
+; MIPS32R6O0-NEXT: addu $2, $2, $25
; MIPS32R6O0-NEXT: move $1, $5
-; MIPS32R6O0-NEXT: move $2, $4
-; MIPS32R6O0-NEXT: lw $3, %got(y)($3)
+; MIPS32R6O0-NEXT: move $3, $4
+; MIPS32R6O0-NEXT: lw $2, %got(y)($2)
; MIPS32R6O0-NEXT: addiu $4, $zero, -4
-; MIPS32R6O0-NEXT: and $4, $3, $4
-; MIPS32R6O0-NEXT: andi $3, $3, 3
-; MIPS32R6O0-NEXT: sll $9, $3, 3
-; MIPS32R6O0-NEXT: ori $3, $zero, 255
-; MIPS32R6O0-NEXT: sllv $5, $3, $9
-; MIPS32R6O0-NEXT: nor $7, $zero, $5
-; MIPS32R6O0-NEXT: andi $2, $2, 255
-; MIPS32R6O0-NEXT: sllv $6, $2, $9
+; MIPS32R6O0-NEXT: and $4, $2, $4
+; MIPS32R6O0-NEXT: andi $2, $2, 3
+; MIPS32R6O0-NEXT: sll $2, $2, 3
+; MIPS32R6O0-NEXT: addiu $5, $zero, 255
+; MIPS32R6O0-NEXT: sllv $7, $5, $2
+; MIPS32R6O0-NEXT: andi $3, $3, 255
+; MIPS32R6O0-NEXT: sllv $5, $3, $2
; MIPS32R6O0-NEXT: andi $1, $1, 255
-; MIPS32R6O0-NEXT: sllv $8, $1, $9
+; MIPS32R6O0-NEXT: sllv $6, $1, $2
; MIPS32R6O0-NEXT: $BB12_1: # %entry
; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32R6O0-NEXT: ll $2, 0($4)
-; MIPS32R6O0-NEXT: and $3, $2, $5
-; MIPS32R6O0-NEXT: bnec $3, $6, $BB12_3
+; MIPS32R6O0-NEXT: ll $1, 0($4)
+; MIPS32R6O0-NEXT: and $3, $1, $7
+; MIPS32R6O0-NEXT: bnec $3, $5, $BB12_3
; MIPS32R6O0-NEXT: # %bb.2: # %entry
; MIPS32R6O0-NEXT: # in Loop: Header=BB12_1 Depth=1
-; MIPS32R6O0-NEXT: and $2, $2, $7
-; MIPS32R6O0-NEXT: or $2, $2, $8
-; MIPS32R6O0-NEXT: sc $2, 0($4)
-; MIPS32R6O0-NEXT: beqzc $2, $BB12_1
+; MIPS32R6O0-NEXT: xor $3, $1, $3
+; MIPS32R6O0-NEXT: or $3, $3, $6
+; MIPS32R6O0-NEXT: sc $3, 0($4)
+; MIPS32R6O0-NEXT: beqzc $3, $BB12_1
; MIPS32R6O0-NEXT: $BB12_3: # %entry
-; MIPS32R6O0-NEXT: srlv $1, $3, $9
-; MIPS32R6O0-NEXT: seb $1, $1
-; MIPS32R6O0-NEXT: # %bb.4: # %entry
-; MIPS32R6O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32R6O0-NEXT: # %bb.5: # %entry
-; MIPS32R6O0-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
-; MIPS32R6O0-NEXT: addiu $sp, $sp, 8
+; MIPS32R6O0-NEXT: srlv $1, $1, $2
+; MIPS32R6O0-NEXT: seb $2, $1
; MIPS32R6O0-NEXT: jrc $ra
;
; MIPS4-LABEL: AtomicCmpSwap8:
@@ -4455,37 +4246,35 @@ define signext i8 @AtomicCmpSwap8(i8 signext %oldval, i8 signext %newval) nounwi
; MIPS4-NEXT: daddu $1, $1, $25
; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicCmpSwap8)))
; MIPS4-NEXT: ld $1, %got_disp(y)($1)
-; MIPS4-NEXT: daddiu $2, $zero, -4
-; MIPS4-NEXT: and $3, $1, $2
-; MIPS4-NEXT: andi $1, $1, 3
-; MIPS4-NEXT: sll $1, $1, 3
-; MIPS4-NEXT: ori $2, $zero, 255
-; MIPS4-NEXT: sllv $6, $2, $1
-; MIPS4-NEXT: nor $7, $zero, $6
-; MIPS4-NEXT: andi $2, $4, 255
-; MIPS4-NEXT: sllv $4, $2, $1
-; MIPS4-NEXT: andi $2, $5, 255
-; MIPS4-NEXT: sllv $5, $2, $1
+; MIPS4-NEXT: sll $2, $1, 0
+; MIPS4-NEXT: andi $2, $2, 3
+; MIPS4-NEXT: sll $2, $2, 3
+; MIPS4-NEXT: addiu $3, $zero, 255
+; MIPS4-NEXT: daddiu $6, $zero, -4
+; MIPS4-NEXT: and $1, $1, $6
+; MIPS4-NEXT: sllv $3, $3, $2
+; MIPS4-NEXT: andi $5, $5, 255
+; MIPS4-NEXT: sllv $5, $5, $2
+; MIPS4-NEXT: andi $4, $4, 255
+; MIPS4-NEXT: sllv $4, $4, $2
; MIPS4-NEXT: .LBB12_1: # %entry
; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS4-NEXT: ll $8, 0($3)
-; MIPS4-NEXT: and $9, $8, $6
-; MIPS4-NEXT: bne $9, $4, .LBB12_3
+; MIPS4-NEXT: ll $6, 0($1)
+; MIPS4-NEXT: and $7, $6, $3
+; MIPS4-NEXT: bne $7, $4, .LBB12_3
; MIPS4-NEXT: nop
; MIPS4-NEXT: # %bb.2: # %entry
; MIPS4-NEXT: # in Loop: Header=BB12_1 Depth=1
-; MIPS4-NEXT: and $8, $8, $7
-; MIPS4-NEXT: or $8, $8, $5
-; MIPS4-NEXT: sc $8, 0($3)
-; MIPS4-NEXT: beqz $8, .LBB12_1
+; MIPS4-NEXT: xor $7, $6, $7
+; MIPS4-NEXT: or $7, $7, $5
+; MIPS4-NEXT: sc $7, 0($1)
+; MIPS4-NEXT: beqz $7, .LBB12_1
; MIPS4-NEXT: nop
; MIPS4-NEXT: .LBB12_3: # %entry
-; MIPS4-NEXT: srlv $2, $9, $1
-; MIPS4-NEXT: sll $2, $2, 24
-; MIPS4-NEXT: sra $2, $2, 24
-; MIPS4-NEXT: # %bb.4: # %entry
+; MIPS4-NEXT: srlv $1, $6, $2
+; MIPS4-NEXT: sll $1, $1, 24
; MIPS4-NEXT: jr $ra
-; MIPS4-NEXT: nop
+; MIPS4-NEXT: sra $2, $1, 24
;
; MIPS64-LABEL: AtomicCmpSwap8:
; MIPS64: # %bb.0: # %entry
@@ -4493,37 +4282,35 @@ define signext i8 @AtomicCmpSwap8(i8 signext %oldval, i8 signext %newval) nounwi
; MIPS64-NEXT: daddu $1, $1, $25
; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicCmpSwap8)))
; MIPS64-NEXT: ld $1, %got_disp(y)($1)
-; MIPS64-NEXT: daddiu $2, $zero, -4
-; MIPS64-NEXT: and $3, $1, $2
-; MIPS64-NEXT: andi $1, $1, 3
-; MIPS64-NEXT: sll $1, $1, 3
-; MIPS64-NEXT: ori $2, $zero, 255
-; MIPS64-NEXT: sllv $6, $2, $1
-; MIPS64-NEXT: nor $7, $zero, $6
-; MIPS64-NEXT: andi $2, $4, 255
-; MIPS64-NEXT: sllv $4, $2, $1
-; MIPS64-NEXT: andi $2, $5, 255
-; MIPS64-NEXT: sllv $5, $2, $1
+; MIPS64-NEXT: sll $2, $1, 0
+; MIPS64-NEXT: andi $2, $2, 3
+; MIPS64-NEXT: sll $2, $2, 3
+; MIPS64-NEXT: addiu $3, $zero, 255
+; MIPS64-NEXT: daddiu $6, $zero, -4
+; MIPS64-NEXT: and $1, $1, $6
+; MIPS64-NEXT: sllv $3, $3, $2
+; MIPS64-NEXT: andi $5, $5, 255
+; MIPS64-NEXT: sllv $5, $5, $2
+; MIPS64-NEXT: andi $4, $4, 255
+; MIPS64-NEXT: sllv $4, $4, $2
; MIPS64-NEXT: .LBB12_1: # %entry
; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64-NEXT: ll $8, 0($3)
-; MIPS64-NEXT: and $9, $8, $6
-; MIPS64-NEXT: bne $9, $4, .LBB12_3
+; MIPS64-NEXT: ll $6, 0($1)
+; MIPS64-NEXT: and $7, $6, $3
+; MIPS64-NEXT: bne $7, $4, .LBB12_3
; MIPS64-NEXT: nop
; MIPS64-NEXT: # %bb.2: # %entry
; MIPS64-NEXT: # in Loop: Header=BB12_1 Depth=1
-; MIPS64-NEXT: and $8, $8, $7
-; MIPS64-NEXT: or $8, $8, $5
-; MIPS64-NEXT: sc $8, 0($3)
-; MIPS64-NEXT: beqz $8, .LBB12_1
+; MIPS64-NEXT: xor $7, $6, $7
+; MIPS64-NEXT: or $7, $7, $5
+; MIPS64-NEXT: sc $7, 0($1)
+; MIPS64-NEXT: beqz $7, .LBB12_1
; MIPS64-NEXT: nop
; MIPS64-NEXT: .LBB12_3: # %entry
-; MIPS64-NEXT: srlv $2, $9, $1
-; MIPS64-NEXT: sll $2, $2, 24
-; MIPS64-NEXT: sra $2, $2, 24
-; MIPS64-NEXT: # %bb.4: # %entry
+; MIPS64-NEXT: srlv $1, $6, $2
+; MIPS64-NEXT: sll $1, $1, 24
; MIPS64-NEXT: jr $ra
-; MIPS64-NEXT: nop
+; MIPS64-NEXT: sra $2, $1, 24
;
; MIPS64R2-LABEL: AtomicCmpSwap8:
; MIPS64R2: # %bb.0: # %entry
@@ -4531,36 +4318,34 @@ define signext i8 @AtomicCmpSwap8(i8 signext %oldval, i8 signext %newval) nounwi
; MIPS64R2-NEXT: daddu $1, $1, $25
; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicCmpSwap8)))
; MIPS64R2-NEXT: ld $1, %got_disp(y)($1)
-; MIPS64R2-NEXT: daddiu $2, $zero, -4
-; MIPS64R2-NEXT: and $3, $1, $2
-; MIPS64R2-NEXT: andi $1, $1, 3
-; MIPS64R2-NEXT: sll $1, $1, 3
-; MIPS64R2-NEXT: ori $2, $zero, 255
-; MIPS64R2-NEXT: sllv $6, $2, $1
-; MIPS64R2-NEXT: nor $7, $zero, $6
-; MIPS64R2-NEXT: andi $2, $4, 255
-; MIPS64R2-NEXT: sllv $4, $2, $1
-; MIPS64R2-NEXT: andi $2, $5, 255
-; MIPS64R2-NEXT: sllv $5, $2, $1
+; MIPS64R2-NEXT: sll $2, $1, 0
+; MIPS64R2-NEXT: andi $2, $2, 3
+; MIPS64R2-NEXT: sll $2, $2, 3
+; MIPS64R2-NEXT: addiu $3, $zero, 255
+; MIPS64R2-NEXT: daddiu $6, $zero, -4
+; MIPS64R2-NEXT: and $1, $1, $6
+; MIPS64R2-NEXT: sllv $3, $3, $2
+; MIPS64R2-NEXT: andi $5, $5, 255
+; MIPS64R2-NEXT: sllv $5, $5, $2
+; MIPS64R2-NEXT: andi $4, $4, 255
+; MIPS64R2-NEXT: sllv $4, $4, $2
; MIPS64R2-NEXT: .LBB12_1: # %entry
; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R2-NEXT: ll $8, 0($3)
-; MIPS64R2-NEXT: and $9, $8, $6
-; MIPS64R2-NEXT: bne $9, $4, .LBB12_3
+; MIPS64R2-NEXT: ll $6, 0($1)
+; MIPS64R2-NEXT: and $7, $6, $3
+; MIPS64R2-NEXT: bne $7, $4, .LBB12_3
; MIPS64R2-NEXT: nop
; MIPS64R2-NEXT: # %bb.2: # %entry
; MIPS64R2-NEXT: # in Loop: Header=BB12_1 Depth=1
-; MIPS64R2-NEXT: and $8, $8, $7
-; MIPS64R2-NEXT: or $8, $8, $5
-; MIPS64R2-NEXT: sc $8, 0($3)
-; MIPS64R2-NEXT: beqz $8, .LBB12_1
+; MIPS64R2-NEXT: xor $7, $6, $7
+; MIPS64R2-NEXT: or $7, $7, $5
+; MIPS64R2-NEXT: sc $7, 0($1)
+; MIPS64R2-NEXT: beqz $7, .LBB12_1
; MIPS64R2-NEXT: nop
; MIPS64R2-NEXT: .LBB12_3: # %entry
-; MIPS64R2-NEXT: srlv $2, $9, $1
-; MIPS64R2-NEXT: seb $2, $2
-; MIPS64R2-NEXT: # %bb.4: # %entry
+; MIPS64R2-NEXT: srlv $1, $6, $2
; MIPS64R2-NEXT: jr $ra
-; MIPS64R2-NEXT: nop
+; MIPS64R2-NEXT: seb $2, $1
;
; MIPS64R6-LABEL: AtomicCmpSwap8:
; MIPS64R6: # %bb.0: # %entry
@@ -4568,74 +4353,68 @@ define signext i8 @AtomicCmpSwap8(i8 signext %oldval, i8 signext %newval) nounwi
; MIPS64R6-NEXT: daddu $1, $1, $25
; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicCmpSwap8)))
; MIPS64R6-NEXT: ld $1, %got_disp(y)($1)
-; MIPS64R6-NEXT: daddiu $2, $zero, -4
-; MIPS64R6-NEXT: and $3, $1, $2
-; MIPS64R6-NEXT: andi $1, $1, 3
-; MIPS64R6-NEXT: sll $1, $1, 3
-; MIPS64R6-NEXT: ori $2, $zero, 255
-; MIPS64R6-NEXT: sllv $6, $2, $1
-; MIPS64R6-NEXT: nor $7, $zero, $6
-; MIPS64R6-NEXT: andi $2, $4, 255
-; MIPS64R6-NEXT: sllv $4, $2, $1
-; MIPS64R6-NEXT: andi $2, $5, 255
-; MIPS64R6-NEXT: sllv $5, $2, $1
+; MIPS64R6-NEXT: sll $2, $1, 0
+; MIPS64R6-NEXT: andi $2, $2, 3
+; MIPS64R6-NEXT: sll $2, $2, 3
+; MIPS64R6-NEXT: addiu $3, $zero, 255
+; MIPS64R6-NEXT: daddiu $6, $zero, -4
+; MIPS64R6-NEXT: and $1, $1, $6
+; MIPS64R6-NEXT: sllv $3, $3, $2
+; MIPS64R6-NEXT: andi $5, $5, 255
+; MIPS64R6-NEXT: sllv $5, $5, $2
+; MIPS64R6-NEXT: andi $4, $4, 255
+; MIPS64R6-NEXT: sllv $4, $4, $2
; MIPS64R6-NEXT: .LBB12_1: # %entry
; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R6-NEXT: ll $8, 0($3)
-; MIPS64R6-NEXT: and $9, $8, $6
-; MIPS64R6-NEXT: bnec $9, $4, .LBB12_3
+; MIPS64R6-NEXT: ll $6, 0($1)
+; MIPS64R6-NEXT: and $7, $6, $3
+; MIPS64R6-NEXT: bnec $7, $4, .LBB12_3
; MIPS64R6-NEXT: # %bb.2: # %entry
; MIPS64R6-NEXT: # in Loop: Header=BB12_1 Depth=1
-; MIPS64R6-NEXT: and $8, $8, $7
-; MIPS64R6-NEXT: or $8, $8, $5
-; MIPS64R6-NEXT: sc $8, 0($3)
-; MIPS64R6-NEXT: beqzc $8, .LBB12_1
+; MIPS64R6-NEXT: xor $7, $6, $7
+; MIPS64R6-NEXT: or $7, $7, $5
+; MIPS64R6-NEXT: sc $7, 0($1)
+; MIPS64R6-NEXT: beqzc $7, .LBB12_1
; MIPS64R6-NEXT: .LBB12_3: # %entry
-; MIPS64R6-NEXT: srlv $2, $9, $1
-; MIPS64R6-NEXT: seb $2, $2
-; MIPS64R6-NEXT: # %bb.4: # %entry
-; MIPS64R6-NEXT: jrc $ra
+; MIPS64R6-NEXT: srlv $1, $6, $2
+; MIPS64R6-NEXT: jr $ra
+; MIPS64R6-NEXT: seb $2, $1
;
; MIPS64R6O0-LABEL: AtomicCmpSwap8:
; MIPS64R6O0: # %bb.0: # %entry
-; MIPS64R6O0-NEXT: daddiu $sp, $sp, -16
; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicCmpSwap8)))
; MIPS64R6O0-NEXT: daddu $1, $1, $25
-; MIPS64R6O0-NEXT: daddiu $3, $1, %lo(%neg(%gp_rel(AtomicCmpSwap8)))
+; MIPS64R6O0-NEXT: daddiu $2, $1, %lo(%neg(%gp_rel(AtomicCmpSwap8)))
; MIPS64R6O0-NEXT: move $1, $5
-; MIPS64R6O0-NEXT: move $2, $4
-; MIPS64R6O0-NEXT: ld $3, %got_disp(y)($3)
+; MIPS64R6O0-NEXT: move $3, $4
+; MIPS64R6O0-NEXT: ld $2, %got_disp(y)($2)
; MIPS64R6O0-NEXT: daddiu $4, $zero, -4
-; MIPS64R6O0-NEXT: and $4, $3, $4
-; MIPS64R6O0-NEXT: andi $3, $3, 3
-; MIPS64R6O0-NEXT: xori $3, $3, 3
-; MIPS64R6O0-NEXT: sll $9, $3, 3
-; MIPS64R6O0-NEXT: ori $3, $zero, 255
-; MIPS64R6O0-NEXT: sllv $5, $3, $9
-; MIPS64R6O0-NEXT: nor $7, $zero, $5
-; MIPS64R6O0-NEXT: andi $2, $2, 255
-; MIPS64R6O0-NEXT: sllv $6, $2, $9
+; MIPS64R6O0-NEXT: and $4, $2, $4
+; MIPS64R6O0-NEXT: # kill: def $v0 killed $v0 killed $v0_64
+; MIPS64R6O0-NEXT: sll $2, $2, 0
+; MIPS64R6O0-NEXT: not $2, $2
+; MIPS64R6O0-NEXT: andi $2, $2, 3
+; MIPS64R6O0-NEXT: sll $2, $2, 3
+; MIPS64R6O0-NEXT: addiu $5, $zero, 255
+; MIPS64R6O0-NEXT: sllv $7, $5, $2
+; MIPS64R6O0-NEXT: andi $3, $3, 255
+; MIPS64R6O0-NEXT: sllv $5, $3, $2
; MIPS64R6O0-NEXT: andi $1, $1, 255
-; MIPS64R6O0-NEXT: sllv $8, $1, $9
+; MIPS64R6O0-NEXT: sllv $6, $1, $2
; MIPS64R6O0-NEXT: .LBB12_1: # %entry
; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R6O0-NEXT: ll $2, 0($4)
-; MIPS64R6O0-NEXT: and $3, $2, $5
-; MIPS64R6O0-NEXT: bnec $3, $6, .LBB12_3
+; MIPS64R6O0-NEXT: ll $1, 0($4)
+; MIPS64R6O0-NEXT: and $3, $1, $7
+; MIPS64R6O0-NEXT: bnec $3, $5, .LBB12_3
; MIPS64R6O0-NEXT: # %bb.2: # %entry
; MIPS64R6O0-NEXT: # in Loop: Header=BB12_1 Depth=1
-; MIPS64R6O0-NEXT: and $2, $2, $7
-; MIPS64R6O0-NEXT: or $2, $2, $8
-; MIPS64R6O0-NEXT: sc $2, 0($4)
-; MIPS64R6O0-NEXT: beqzc $2, .LBB12_1
+; MIPS64R6O0-NEXT: xor $3, $1, $3
+; MIPS64R6O0-NEXT: or $3, $3, $6
+; MIPS64R6O0-NEXT: sc $3, 0($4)
+; MIPS64R6O0-NEXT: beqzc $3, .LBB12_1
; MIPS64R6O0-NEXT: .LBB12_3: # %entry
-; MIPS64R6O0-NEXT: srlv $1, $3, $9
-; MIPS64R6O0-NEXT: seb $1, $1
-; MIPS64R6O0-NEXT: # %bb.4: # %entry
-; MIPS64R6O0-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64R6O0-NEXT: # %bb.5: # %entry
-; MIPS64R6O0-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
-; MIPS64R6O0-NEXT: daddiu $sp, $sp, 16
+; MIPS64R6O0-NEXT: srlv $1, $1, $2
+; MIPS64R6O0-NEXT: seb $2, $1
; MIPS64R6O0-NEXT: jrc $ra
;
; MM32-LABEL: AtomicCmpSwap8:
@@ -4643,35 +4422,33 @@ define signext i8 @AtomicCmpSwap8(i8 signext %oldval, i8 signext %newval) nounwi
; MM32-NEXT: lui $2, %hi(_gp_disp)
; MM32-NEXT: addiu $2, $2, %lo(_gp_disp)
; MM32-NEXT: addu $2, $2, $25
-; MM32-NEXT: lw $1, %got(y)($2)
-; MM32-NEXT: addiu $2, $zero, -4
-; MM32-NEXT: and $3, $1, $2
-; MM32-NEXT: andi $1, $1, 3
-; MM32-NEXT: sll $1, $1, 3
-; MM32-NEXT: ori $2, $zero, 255
-; MM32-NEXT: sllv $6, $2, $1
-; MM32-NEXT: nor $7, $zero, $6
-; MM32-NEXT: andi $2, $4, 255
-; MM32-NEXT: sllv $4, $2, $1
-; MM32-NEXT: andi $2, $5, 255
-; MM32-NEXT: sllv $5, $2, $1
+; MM32-NEXT: lw $2, %got(y)($2)
+; MM32-NEXT: andi16 $3, $2, 3
+; MM32-NEXT: sll16 $3, $3, 3
+; MM32-NEXT: addiu $1, $zero, 255
+; MM32-NEXT: addiu $6, $zero, -4
+; MM32-NEXT: and16 $6, $2
+; MM32-NEXT: sllv $1, $1, $3
+; MM32-NEXT: andi16 $2, $5, 255
+; MM32-NEXT: sllv $2, $2, $3
+; MM32-NEXT: andi16 $4, $4, 255
+; MM32-NEXT: sllv $4, $4, $3
; MM32-NEXT: $BB12_1: # %entry
; MM32-NEXT: # =>This Inner Loop Header: Depth=1
-; MM32-NEXT: ll $8, 0($3)
-; MM32-NEXT: and $9, $8, $6
-; MM32-NEXT: bne $9, $4, $BB12_3
+; MM32-NEXT: ll $5, 0($6)
+; MM32-NEXT: and $7, $5, $1
+; MM32-NEXT: bne $7, $4, $BB12_3
; MM32-NEXT: nop
; MM32-NEXT: # %bb.2: # %entry
; MM32-NEXT: # in Loop: Header=BB12_1 Depth=1
-; MM32-NEXT: and $8, $8, $7
-; MM32-NEXT: or $8, $8, $5
-; MM32-NEXT: sc $8, 0($3)
-; MM32-NEXT: beqzc $8, $BB12_1
+; MM32-NEXT: xor16 $7, $5
+; MM32-NEXT: or $7, $7, $2
+; MM32-NEXT: sc $7, 0($6)
+; MM32-NEXT: beqzc $7, $BB12_1
; MM32-NEXT: $BB12_3: # %entry
-; MM32-NEXT: srlv $2, $9, $1
-; MM32-NEXT: seb $2, $2
-; MM32-NEXT: # %bb.4: # %entry
-; MM32-NEXT: jrc $ra
+; MM32-NEXT: srlv $1, $5, $3
+; MM32-NEXT: jr $ra
+; MM32-NEXT: seb $2, $1
;
; O1-LABEL: AtomicCmpSwap8:
; O1: # %bb.0: # %entry
@@ -4679,37 +4456,34 @@ define signext i8 @AtomicCmpSwap8(i8 signext %oldval, i8 signext %newval) nounwi
; O1-NEXT: addiu $2, $2, %lo(_gp_disp)
; O1-NEXT: addu $1, $2, $25
; O1-NEXT: lw $1, %got(y)($1)
-; O1-NEXT: addiu $2, $zero, -4
-; O1-NEXT: and $3, $1, $2
-; O1-NEXT: andi $1, $1, 3
-; O1-NEXT: sll $1, $1, 3
-; O1-NEXT: ori $2, $zero, 255
-; O1-NEXT: sllv $6, $2, $1
-; O1-NEXT: nor $7, $zero, $6
-; O1-NEXT: andi $2, $4, 255
-; O1-NEXT: sllv $4, $2, $1
-; O1-NEXT: andi $2, $5, 255
-; O1-NEXT: sllv $5, $2, $1
+; O1-NEXT: andi $2, $1, 3
+; O1-NEXT: sll $2, $2, 3
+; O1-NEXT: addiu $3, $zero, 255
+; O1-NEXT: addiu $6, $zero, -4
+; O1-NEXT: and $1, $1, $6
+; O1-NEXT: sllv $3, $3, $2
+; O1-NEXT: andi $5, $5, 255
+; O1-NEXT: sllv $5, $5, $2
+; O1-NEXT: andi $4, $4, 255
+; O1-NEXT: sllv $4, $4, $2
; O1-NEXT: $BB12_1: # %entry
; O1-NEXT: # =>This Inner Loop Header: Depth=1
-; O1-NEXT: ll $8, 0($3)
-; O1-NEXT: and $9, $8, $6
-; O1-NEXT: bne $9, $4, $BB12_3
+; O1-NEXT: ll $6, 0($1)
+; O1-NEXT: and $7, $6, $3
+; O1-NEXT: bne $7, $4, $BB12_3
; O1-NEXT: nop
; O1-NEXT: # %bb.2: # %entry
; O1-NEXT: # in Loop: Header=BB12_1 Depth=1
-; O1-NEXT: and $8, $8, $7
-; O1-NEXT: or $8, $8, $5
-; O1-NEXT: sc $8, 0($3)
-; O1-NEXT: beqz $8, $BB12_1
+; O1-NEXT: xor $7, $6, $7
+; O1-NEXT: or $7, $7, $5
+; O1-NEXT: sc $7, 0($1)
+; O1-NEXT: beqz $7, $BB12_1
; O1-NEXT: nop
; O1-NEXT: $BB12_3: # %entry
-; O1-NEXT: srlv $2, $9, $1
-; O1-NEXT: sll $2, $2, 24
-; O1-NEXT: sra $2, $2, 24
-; O1-NEXT: # %bb.4: # %entry
+; O1-NEXT: srlv $1, $6, $2
+; O1-NEXT: sll $1, $1, 24
; O1-NEXT: jr $ra
-; O1-NEXT: nop
+; O1-NEXT: sra $2, $1, 24
;
; O2-LABEL: AtomicCmpSwap8:
; O2: # %bb.0: # %entry
@@ -4717,75 +4491,69 @@ define signext i8 @AtomicCmpSwap8(i8 signext %oldval, i8 signext %newval) nounwi
; O2-NEXT: addiu $2, $2, %lo(_gp_disp)
; O2-NEXT: addu $1, $2, $25
; O2-NEXT: lw $1, %got(y)($1)
-; O2-NEXT: addiu $2, $zero, -4
-; O2-NEXT: and $3, $1, $2
-; O2-NEXT: andi $1, $1, 3
-; O2-NEXT: sll $1, $1, 3
-; O2-NEXT: ori $2, $zero, 255
-; O2-NEXT: sllv $6, $2, $1
-; O2-NEXT: nor $7, $zero, $6
-; O2-NEXT: andi $2, $4, 255
-; O2-NEXT: sllv $4, $2, $1
-; O2-NEXT: andi $2, $5, 255
-; O2-NEXT: sllv $5, $2, $1
+; O2-NEXT: andi $2, $1, 3
+; O2-NEXT: sll $2, $2, 3
+; O2-NEXT: addiu $3, $zero, 255
+; O2-NEXT: addiu $6, $zero, -4
+; O2-NEXT: and $1, $1, $6
+; O2-NEXT: sllv $3, $3, $2
+; O2-NEXT: andi $5, $5, 255
+; O2-NEXT: sllv $5, $5, $2
+; O2-NEXT: andi $4, $4, 255
+; O2-NEXT: sllv $4, $4, $2
; O2-NEXT: $BB12_1: # %entry
; O2-NEXT: # =>This Inner Loop Header: Depth=1
-; O2-NEXT: ll $8, 0($3)
-; O2-NEXT: and $9, $8, $6
-; O2-NEXT: bne $9, $4, $BB12_3
+; O2-NEXT: ll $6, 0($1)
+; O2-NEXT: and $7, $6, $3
+; O2-NEXT: bne $7, $4, $BB12_3
; O2-NEXT: nop
; O2-NEXT: # %bb.2: # %entry
; O2-NEXT: # in Loop: Header=BB12_1 Depth=1
-; O2-NEXT: and $8, $8, $7
-; O2-NEXT: or $8, $8, $5
-; O2-NEXT: sc $8, 0($3)
-; O2-NEXT: beqz $8, $BB12_1
+; O2-NEXT: xor $7, $6, $7
+; O2-NEXT: or $7, $7, $5
+; O2-NEXT: sc $7, 0($1)
+; O2-NEXT: beqz $7, $BB12_1
; O2-NEXT: nop
; O2-NEXT: $BB12_3: # %entry
-; O2-NEXT: srlv $2, $9, $1
-; O2-NEXT: sll $2, $2, 24
-; O2-NEXT: sra $2, $2, 24
-; O2-NEXT: # %bb.4: # %entry
+; O2-NEXT: srlv $1, $6, $2
+; O2-NEXT: sll $1, $1, 24
; O2-NEXT: jr $ra
-; O2-NEXT: nop
+; O2-NEXT: sra $2, $1, 24
;
; O3-LABEL: AtomicCmpSwap8:
; O3: # %bb.0: # %entry
; O3-NEXT: lui $2, %hi(_gp_disp)
; O3-NEXT: addiu $2, $2, %lo(_gp_disp)
; O3-NEXT: addu $1, $2, $25
-; O3-NEXT: addiu $2, $zero, -4
+; O3-NEXT: addiu $3, $zero, 255
+; O3-NEXT: addiu $6, $zero, -4
+; O3-NEXT: andi $5, $5, 255
+; O3-NEXT: andi $4, $4, 255
; O3-NEXT: lw $1, %got(y)($1)
-; O3-NEXT: and $3, $1, $2
-; O3-NEXT: andi $1, $1, 3
-; O3-NEXT: ori $2, $zero, 255
-; O3-NEXT: sll $1, $1, 3
-; O3-NEXT: sllv $6, $2, $1
-; O3-NEXT: andi $2, $4, 255
-; O3-NEXT: sllv $4, $2, $1
-; O3-NEXT: andi $2, $5, 255
-; O3-NEXT: nor $7, $zero, $6
-; O3-NEXT: sllv $5, $2, $1
+; O3-NEXT: andi $2, $1, 3
+; O3-NEXT: and $1, $1, $6
+; O3-NEXT: sll $2, $2, 3
+; O3-NEXT: sllv $3, $3, $2
+; O3-NEXT: sllv $5, $5, $2
+; O3-NEXT: sllv $4, $4, $2
; O3-NEXT: $BB12_1: # %entry
; O3-NEXT: # =>This Inner Loop Header: Depth=1
-; O3-NEXT: ll $8, 0($3)
-; O3-NEXT: and $9, $8, $6
-; O3-NEXT: bne $9, $4, $BB12_3
+; O3-NEXT: ll $6, 0($1)
+; O3-NEXT: and $7, $6, $3
+; O3-NEXT: bne $7, $4, $BB12_3
; O3-NEXT: nop
; O3-NEXT: # %bb.2: # %entry
; O3-NEXT: # in Loop: Header=BB12_1 Depth=1
-; O3-NEXT: and $8, $8, $7
-; O3-NEXT: or $8, $8, $5
-; O3-NEXT: sc $8, 0($3)
-; O3-NEXT: beqz $8, $BB12_1
+; O3-NEXT: xor $7, $6, $7
+; O3-NEXT: or $7, $7, $5
+; O3-NEXT: sc $7, 0($1)
+; O3-NEXT: beqz $7, $BB12_1
; O3-NEXT: nop
; O3-NEXT: $BB12_3: # %entry
-; O3-NEXT: srlv $2, $9, $1
-; O3-NEXT: sll $2, $2, 24
-; O3-NEXT: sra $2, $2, 24
-; O3-NEXT: # %bb.4: # %entry
+; O3-NEXT: srlv $1, $6, $2
+; O3-NEXT: sll $1, $1, 24
; O3-NEXT: jr $ra
-; O3-NEXT: nop
+; O3-NEXT: sra $2, $1, 24
;
; MIPS32EB-LABEL: AtomicCmpSwap8:
; MIPS32EB: # %bb.0: # %entry
@@ -4793,38 +4561,35 @@ define signext i8 @AtomicCmpSwap8(i8 signext %oldval, i8 signext %newval) nounwi
; MIPS32EB-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32EB-NEXT: addu $1, $2, $25
; MIPS32EB-NEXT: lw $1, %got(y)($1)
-; MIPS32EB-NEXT: addiu $2, $zero, -4
-; MIPS32EB-NEXT: and $3, $1, $2
-; MIPS32EB-NEXT: andi $1, $1, 3
-; MIPS32EB-NEXT: xori $1, $1, 3
-; MIPS32EB-NEXT: sll $1, $1, 3
-; MIPS32EB-NEXT: ori $2, $zero, 255
-; MIPS32EB-NEXT: sllv $6, $2, $1
-; MIPS32EB-NEXT: nor $7, $zero, $6
-; MIPS32EB-NEXT: andi $2, $4, 255
-; MIPS32EB-NEXT: sllv $4, $2, $1
-; MIPS32EB-NEXT: andi $2, $5, 255
-; MIPS32EB-NEXT: sllv $5, $2, $1
+; MIPS32EB-NEXT: not $2, $1
+; MIPS32EB-NEXT: andi $2, $2, 3
+; MIPS32EB-NEXT: sll $2, $2, 3
+; MIPS32EB-NEXT: addiu $3, $zero, 255
+; MIPS32EB-NEXT: addiu $6, $zero, -4
+; MIPS32EB-NEXT: and $1, $1, $6
+; MIPS32EB-NEXT: sllv $3, $3, $2
+; MIPS32EB-NEXT: andi $5, $5, 255
+; MIPS32EB-NEXT: sllv $5, $5, $2
+; MIPS32EB-NEXT: andi $4, $4, 255
+; MIPS32EB-NEXT: sllv $4, $4, $2
; MIPS32EB-NEXT: $BB12_1: # %entry
; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32EB-NEXT: ll $8, 0($3)
-; MIPS32EB-NEXT: and $9, $8, $6
-; MIPS32EB-NEXT: bne $9, $4, $BB12_3
+; MIPS32EB-NEXT: ll $6, 0($1)
+; MIPS32EB-NEXT: and $7, $6, $3
+; MIPS32EB-NEXT: bne $7, $4, $BB12_3
; MIPS32EB-NEXT: nop
; MIPS32EB-NEXT: # %bb.2: # %entry
; MIPS32EB-NEXT: # in Loop: Header=BB12_1 Depth=1
-; MIPS32EB-NEXT: and $8, $8, $7
-; MIPS32EB-NEXT: or $8, $8, $5
-; MIPS32EB-NEXT: sc $8, 0($3)
-; MIPS32EB-NEXT: beqz $8, $BB12_1
+; MIPS32EB-NEXT: xor $7, $6, $7
+; MIPS32EB-NEXT: or $7, $7, $5
+; MIPS32EB-NEXT: sc $7, 0($1)
+; MIPS32EB-NEXT: beqz $7, $BB12_1
; MIPS32EB-NEXT: nop
; MIPS32EB-NEXT: $BB12_3: # %entry
-; MIPS32EB-NEXT: srlv $2, $9, $1
-; MIPS32EB-NEXT: sll $2, $2, 24
-; MIPS32EB-NEXT: sra $2, $2, 24
-; MIPS32EB-NEXT: # %bb.4: # %entry
+; MIPS32EB-NEXT: srlv $1, $6, $2
+; MIPS32EB-NEXT: sll $1, $1, 24
; MIPS32EB-NEXT: jr $ra
-; MIPS32EB-NEXT: nop
+; MIPS32EB-NEXT: sra $2, $1, 24
entry:
%pair0 = cmpxchg ptr @y, i8 %oldval, i8 %newval monotonic monotonic
%0 = extractvalue { i8, i1 } %pair0, 0
@@ -4834,545 +4599,463 @@ entry:
define i1 @AtomicCmpSwapRes8(ptr %ptr, i8 signext %oldval, i8 signext %newval) nounwind {
; MIPS32-LABEL: AtomicCmpSwapRes8:
; MIPS32: # %bb.0: # %entry
-; MIPS32-NEXT: addiu $1, $zero, -4
-; MIPS32-NEXT: and $2, $4, $1
-; MIPS32-NEXT: andi $1, $4, 3
-; MIPS32-NEXT: sll $3, $1, 3
-; MIPS32-NEXT: ori $1, $zero, 255
-; MIPS32-NEXT: sllv $4, $1, $3
-; MIPS32-NEXT: nor $7, $zero, $4
-; MIPS32-NEXT: andi $1, $5, 255
-; MIPS32-NEXT: sllv $8, $1, $3
-; MIPS32-NEXT: andi $1, $6, 255
-; MIPS32-NEXT: sllv $6, $1, $3
+; MIPS32-NEXT: sll $1, $4, 3
+; MIPS32-NEXT: addiu $2, $zero, 255
+; MIPS32-NEXT: addiu $3, $zero, -4
+; MIPS32-NEXT: and $3, $4, $3
+; MIPS32-NEXT: sllv $2, $2, $1
+; MIPS32-NEXT: andi $4, $6, 255
+; MIPS32-NEXT: sllv $4, $4, $1
+; MIPS32-NEXT: andi $5, $5, 255
+; MIPS32-NEXT: sllv $1, $5, $1
; MIPS32-NEXT: $BB13_1: # %entry
; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32-NEXT: ll $9, 0($2)
-; MIPS32-NEXT: and $10, $9, $4
-; MIPS32-NEXT: bne $10, $8, $BB13_3
+; MIPS32-NEXT: ll $5, 0($3)
+; MIPS32-NEXT: and $6, $5, $2
+; MIPS32-NEXT: bne $6, $1, $BB13_3
; MIPS32-NEXT: nop
; MIPS32-NEXT: # %bb.2: # %entry
; MIPS32-NEXT: # in Loop: Header=BB13_1 Depth=1
-; MIPS32-NEXT: and $9, $9, $7
-; MIPS32-NEXT: or $9, $9, $6
-; MIPS32-NEXT: sc $9, 0($2)
-; MIPS32-NEXT: beqz $9, $BB13_1
+; MIPS32-NEXT: xor $6, $5, $6
+; MIPS32-NEXT: or $6, $6, $4
+; MIPS32-NEXT: sc $6, 0($3)
+; MIPS32-NEXT: beqz $6, $BB13_1
; MIPS32-NEXT: nop
; MIPS32-NEXT: $BB13_3: # %entry
-; MIPS32-NEXT: srlv $1, $10, $3
-; MIPS32-NEXT: sll $1, $1, 24
-; MIPS32-NEXT: sra $1, $1, 24
-; MIPS32-NEXT: # %bb.4: # %entry
-; MIPS32-NEXT: xor $1, $1, $5
+; MIPS32-NEXT: and $2, $5, $2
+; MIPS32-NEXT: xor $1, $1, $2
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: sltiu $2, $1, 1
;
; MIPS32O0-LABEL: AtomicCmpSwapRes8:
; MIPS32O0: # %bb.0: # %entry
-; MIPS32O0-NEXT: addiu $sp, $sp, -8
-; MIPS32O0-NEXT: move $1, $6
-; MIPS32O0-NEXT: move $2, $5
-; MIPS32O0-NEXT: move $3, $4
-; MIPS32O0-NEXT: sw $2, 0($sp) # 4-byte Folded Spill
-; MIPS32O0-NEXT: addiu $4, $zero, -4
-; MIPS32O0-NEXT: and $4, $3, $4
-; MIPS32O0-NEXT: andi $3, $3, 3
-; MIPS32O0-NEXT: sll $9, $3, 3
-; MIPS32O0-NEXT: ori $3, $zero, 255
-; MIPS32O0-NEXT: sllv $5, $3, $9
-; MIPS32O0-NEXT: nor $7, $zero, $5
+; MIPS32O0-NEXT: move $2, $6
+; MIPS32O0-NEXT: addiu $1, $zero, -4
+; MIPS32O0-NEXT: and $6, $4, $1
+; MIPS32O0-NEXT: sll $4, $4, 3
+; MIPS32O0-NEXT: addiu $1, $zero, 255
+; MIPS32O0-NEXT: sllv $3, $1, $4
+; MIPS32O0-NEXT: andi $1, $5, 255
+; MIPS32O0-NEXT: sllv $1, $1, $4
; MIPS32O0-NEXT: andi $2, $2, 255
-; MIPS32O0-NEXT: sllv $6, $2, $9
-; MIPS32O0-NEXT: andi $1, $1, 255
-; MIPS32O0-NEXT: sllv $8, $1, $9
+; MIPS32O0-NEXT: sllv $7, $2, $4
; MIPS32O0-NEXT: $BB13_1: # %entry
; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32O0-NEXT: ll $2, 0($4)
-; MIPS32O0-NEXT: and $3, $2, $5
-; MIPS32O0-NEXT: bne $3, $6, $BB13_3
+; MIPS32O0-NEXT: ll $2, 0($6)
+; MIPS32O0-NEXT: and $5, $2, $3
+; MIPS32O0-NEXT: bne $5, $1, $BB13_3
; MIPS32O0-NEXT: nop
; MIPS32O0-NEXT: # %bb.2: # %entry
; MIPS32O0-NEXT: # in Loop: Header=BB13_1 Depth=1
-; MIPS32O0-NEXT: and $2, $2, $7
-; MIPS32O0-NEXT: or $2, $2, $8
-; MIPS32O0-NEXT: sc $2, 0($4)
-; MIPS32O0-NEXT: beqz $2, $BB13_1
+; MIPS32O0-NEXT: xor $5, $2, $5
+; MIPS32O0-NEXT: or $5, $5, $7
+; MIPS32O0-NEXT: sc $5, 0($6)
+; MIPS32O0-NEXT: beqz $5, $BB13_1
; MIPS32O0-NEXT: nop
; MIPS32O0-NEXT: $BB13_3: # %entry
-; MIPS32O0-NEXT: srlv $1, $3, $9
-; MIPS32O0-NEXT: sll $1, $1, 24
-; MIPS32O0-NEXT: sra $1, $1, 24
-; MIPS32O0-NEXT: # %bb.4: # %entry
-; MIPS32O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32O0-NEXT: # %bb.5: # %entry
-; MIPS32O0-NEXT: lw $1, 4($sp) # 4-byte Folded Reload
-; MIPS32O0-NEXT: lw $2, 0($sp) # 4-byte Folded Reload
-; MIPS32O0-NEXT: sll $2, $2, 24
-; MIPS32O0-NEXT: sra $2, $2, 24
+; MIPS32O0-NEXT: srlv $4, $2, $4
+; MIPS32O0-NEXT: and $2, $2, $3
; MIPS32O0-NEXT: xor $1, $1, $2
; MIPS32O0-NEXT: sltiu $2, $1, 1
-; MIPS32O0-NEXT: addiu $sp, $sp, 8
; MIPS32O0-NEXT: jr $ra
; MIPS32O0-NEXT: nop
;
; MIPS32R2-LABEL: AtomicCmpSwapRes8:
; MIPS32R2: # %bb.0: # %entry
-; MIPS32R2-NEXT: addiu $1, $zero, -4
-; MIPS32R2-NEXT: and $2, $4, $1
-; MIPS32R2-NEXT: andi $1, $4, 3
-; MIPS32R2-NEXT: sll $3, $1, 3
-; MIPS32R2-NEXT: ori $1, $zero, 255
-; MIPS32R2-NEXT: sllv $4, $1, $3
-; MIPS32R2-NEXT: nor $7, $zero, $4
-; MIPS32R2-NEXT: andi $1, $5, 255
-; MIPS32R2-NEXT: sllv $8, $1, $3
-; MIPS32R2-NEXT: andi $1, $6, 255
-; MIPS32R2-NEXT: sllv $6, $1, $3
+; MIPS32R2-NEXT: sll $1, $4, 3
+; MIPS32R2-NEXT: addiu $2, $zero, 255
+; MIPS32R2-NEXT: addiu $3, $zero, -4
+; MIPS32R2-NEXT: and $3, $4, $3
+; MIPS32R2-NEXT: sllv $2, $2, $1
+; MIPS32R2-NEXT: andi $4, $6, 255
+; MIPS32R2-NEXT: sllv $4, $4, $1
+; MIPS32R2-NEXT: andi $5, $5, 255
+; MIPS32R2-NEXT: sllv $1, $5, $1
; MIPS32R2-NEXT: $BB13_1: # %entry
; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32R2-NEXT: ll $9, 0($2)
-; MIPS32R2-NEXT: and $10, $9, $4
-; MIPS32R2-NEXT: bne $10, $8, $BB13_3
+; MIPS32R2-NEXT: ll $5, 0($3)
+; MIPS32R2-NEXT: and $6, $5, $2
+; MIPS32R2-NEXT: bne $6, $1, $BB13_3
; MIPS32R2-NEXT: nop
; MIPS32R2-NEXT: # %bb.2: # %entry
; MIPS32R2-NEXT: # in Loop: Header=BB13_1 Depth=1
-; MIPS32R2-NEXT: and $9, $9, $7
-; MIPS32R2-NEXT: or $9, $9, $6
-; MIPS32R2-NEXT: sc $9, 0($2)
-; MIPS32R2-NEXT: beqz $9, $BB13_1
+; MIPS32R2-NEXT: xor $6, $5, $6
+; MIPS32R2-NEXT: or $6, $6, $4
+; MIPS32R2-NEXT: sc $6, 0($3)
+; MIPS32R2-NEXT: beqz $6, $BB13_1
; MIPS32R2-NEXT: nop
; MIPS32R2-NEXT: $BB13_3: # %entry
-; MIPS32R2-NEXT: srlv $1, $10, $3
-; MIPS32R2-NEXT: seb $1, $1
-; MIPS32R2-NEXT: # %bb.4: # %entry
-; MIPS32R2-NEXT: xor $1, $1, $5
+; MIPS32R2-NEXT: and $2, $5, $2
+; MIPS32R2-NEXT: xor $1, $1, $2
; MIPS32R2-NEXT: jr $ra
; MIPS32R2-NEXT: sltiu $2, $1, 1
;
; MIPS32R6-LABEL: AtomicCmpSwapRes8:
; MIPS32R6: # %bb.0: # %entry
-; MIPS32R6-NEXT: addiu $1, $zero, -4
-; MIPS32R6-NEXT: and $2, $4, $1
-; MIPS32R6-NEXT: andi $1, $4, 3
-; MIPS32R6-NEXT: sll $3, $1, 3
-; MIPS32R6-NEXT: ori $1, $zero, 255
-; MIPS32R6-NEXT: sllv $4, $1, $3
-; MIPS32R6-NEXT: nor $7, $zero, $4
-; MIPS32R6-NEXT: andi $1, $5, 255
-; MIPS32R6-NEXT: sllv $8, $1, $3
-; MIPS32R6-NEXT: andi $1, $6, 255
-; MIPS32R6-NEXT: sllv $6, $1, $3
+; MIPS32R6-NEXT: sll $1, $4, 3
+; MIPS32R6-NEXT: addiu $2, $zero, 255
+; MIPS32R6-NEXT: addiu $3, $zero, -4
+; MIPS32R6-NEXT: and $3, $4, $3
+; MIPS32R6-NEXT: sllv $2, $2, $1
+; MIPS32R6-NEXT: andi $4, $6, 255
+; MIPS32R6-NEXT: sllv $4, $4, $1
+; MIPS32R6-NEXT: andi $5, $5, 255
+; MIPS32R6-NEXT: sllv $1, $5, $1
; MIPS32R6-NEXT: $BB13_1: # %entry
; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32R6-NEXT: ll $9, 0($2)
-; MIPS32R6-NEXT: and $10, $9, $4
-; MIPS32R6-NEXT: bnec $10, $8, $BB13_3
+; MIPS32R6-NEXT: ll $5, 0($3)
+; MIPS32R6-NEXT: and $6, $5, $2
+; MIPS32R6-NEXT: bnec $6, $1, $BB13_3
; MIPS32R6-NEXT: # %bb.2: # %entry
; MIPS32R6-NEXT: # in Loop: Header=BB13_1 Depth=1
-; MIPS32R6-NEXT: and $9, $9, $7
-; MIPS32R6-NEXT: or $9, $9, $6
-; MIPS32R6-NEXT: sc $9, 0($2)
-; MIPS32R6-NEXT: beqzc $9, $BB13_1
+; MIPS32R6-NEXT: xor $6, $5, $6
+; MIPS32R6-NEXT: or $6, $6, $4
+; MIPS32R6-NEXT: sc $6, 0($3)
+; MIPS32R6-NEXT: beqzc $6, $BB13_1
; MIPS32R6-NEXT: $BB13_3: # %entry
-; MIPS32R6-NEXT: srlv $1, $10, $3
-; MIPS32R6-NEXT: seb $1, $1
-; MIPS32R6-NEXT: # %bb.4: # %entry
-; MIPS32R6-NEXT: xor $1, $1, $5
+; MIPS32R6-NEXT: and $2, $5, $2
+; MIPS32R6-NEXT: xor $1, $1, $2
; MIPS32R6-NEXT: jr $ra
; MIPS32R6-NEXT: sltiu $2, $1, 1
;
; MIPS32R6O0-LABEL: AtomicCmpSwapRes8:
; MIPS32R6O0: # %bb.0: # %entry
-; MIPS32R6O0-NEXT: addiu $sp, $sp, -8
-; MIPS32R6O0-NEXT: move $1, $6
-; MIPS32R6O0-NEXT: move $2, $5
-; MIPS32R6O0-NEXT: sw $2, 0($sp) # 4-byte Folded Spill
-; MIPS32R6O0-NEXT: move $3, $4
-; MIPS32R6O0-NEXT: addiu $4, $zero, -4
-; MIPS32R6O0-NEXT: and $4, $3, $4
-; MIPS32R6O0-NEXT: andi $3, $3, 3
-; MIPS32R6O0-NEXT: sll $9, $3, 3
-; MIPS32R6O0-NEXT: ori $3, $zero, 255
-; MIPS32R6O0-NEXT: sllv $5, $3, $9
-; MIPS32R6O0-NEXT: nor $7, $zero, $5
-; MIPS32R6O0-NEXT: andi $2, $2, 255
-; MIPS32R6O0-NEXT: sllv $6, $2, $9
+; MIPS32R6O0-NEXT: move $1, $5
+; MIPS32R6O0-NEXT: addiu $2, $zero, -4
+; MIPS32R6O0-NEXT: and $5, $4, $2
+; MIPS32R6O0-NEXT: sll $4, $4, 3
+; MIPS32R6O0-NEXT: addiu $2, $zero, 255
+; MIPS32R6O0-NEXT: sllv $3, $2, $4
; MIPS32R6O0-NEXT: andi $1, $1, 255
-; MIPS32R6O0-NEXT: sllv $8, $1, $9
+; MIPS32R6O0-NEXT: sllv $1, $1, $4
+; MIPS32R6O0-NEXT: andi $2, $6, 255
+; MIPS32R6O0-NEXT: sllv $6, $2, $4
; MIPS32R6O0-NEXT: $BB13_1: # %entry
; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32R6O0-NEXT: ll $2, 0($4)
-; MIPS32R6O0-NEXT: and $3, $2, $5
-; MIPS32R6O0-NEXT: bnec $3, $6, $BB13_3
+; MIPS32R6O0-NEXT: ll $2, 0($5)
+; MIPS32R6O0-NEXT: and $4, $2, $3
+; MIPS32R6O0-NEXT: bnec $4, $1, $BB13_3
; MIPS32R6O0-NEXT: # %bb.2: # %entry
; MIPS32R6O0-NEXT: # in Loop: Header=BB13_1 Depth=1
-; MIPS32R6O0-NEXT: and $2, $2, $7
-; MIPS32R6O0-NEXT: or $2, $2, $8
-; MIPS32R6O0-NEXT: sc $2, 0($4)
-; MIPS32R6O0-NEXT: beqzc $2, $BB13_1
+; MIPS32R6O0-NEXT: xor $4, $2, $4
+; MIPS32R6O0-NEXT: or $4, $4, $6
+; MIPS32R6O0-NEXT: sc $4, 0($5)
+; MIPS32R6O0-NEXT: beqzc $4, $BB13_1
; MIPS32R6O0-NEXT: $BB13_3: # %entry
-; MIPS32R6O0-NEXT: srlv $1, $3, $9
-; MIPS32R6O0-NEXT: seb $1, $1
-; MIPS32R6O0-NEXT: # %bb.4: # %entry
-; MIPS32R6O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32R6O0-NEXT: # %bb.5: # %entry
-; MIPS32R6O0-NEXT: lw $1, 4($sp) # 4-byte Folded Reload
-; MIPS32R6O0-NEXT: lw $2, 0($sp) # 4-byte Folded Reload
+; MIPS32R6O0-NEXT: and $2, $2, $3
; MIPS32R6O0-NEXT: xor $1, $1, $2
; MIPS32R6O0-NEXT: sltiu $2, $1, 1
-; MIPS32R6O0-NEXT: addiu $sp, $sp, 8
; MIPS32R6O0-NEXT: jrc $ra
;
; MIPS4-LABEL: AtomicCmpSwapRes8:
; MIPS4: # %bb.0: # %entry
-; MIPS4-NEXT: daddiu $1, $zero, -4
-; MIPS4-NEXT: and $2, $4, $1
-; MIPS4-NEXT: andi $1, $4, 3
-; MIPS4-NEXT: sll $3, $1, 3
-; MIPS4-NEXT: ori $1, $zero, 255
-; MIPS4-NEXT: sllv $4, $1, $3
-; MIPS4-NEXT: nor $7, $zero, $4
-; MIPS4-NEXT: andi $1, $5, 255
-; MIPS4-NEXT: sllv $8, $1, $3
-; MIPS4-NEXT: andi $1, $6, 255
-; MIPS4-NEXT: sllv $6, $1, $3
+; MIPS4-NEXT: sll $1, $4, 0
+; MIPS4-NEXT: andi $1, $1, 3
+; MIPS4-NEXT: sll $1, $1, 3
+; MIPS4-NEXT: addiu $2, $zero, 255
+; MIPS4-NEXT: daddiu $3, $zero, -4
+; MIPS4-NEXT: and $3, $4, $3
+; MIPS4-NEXT: sllv $2, $2, $1
+; MIPS4-NEXT: andi $4, $6, 255
+; MIPS4-NEXT: sllv $4, $4, $1
+; MIPS4-NEXT: andi $5, $5, 255
+; MIPS4-NEXT: sllv $1, $5, $1
; MIPS4-NEXT: .LBB13_1: # %entry
; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS4-NEXT: ll $9, 0($2)
-; MIPS4-NEXT: and $10, $9, $4
-; MIPS4-NEXT: bne $10, $8, .LBB13_3
+; MIPS4-NEXT: ll $5, 0($3)
+; MIPS4-NEXT: and $6, $5, $2
+; MIPS4-NEXT: bne $6, $1, .LBB13_3
; MIPS4-NEXT: nop
; MIPS4-NEXT: # %bb.2: # %entry
; MIPS4-NEXT: # in Loop: Header=BB13_1 Depth=1
-; MIPS4-NEXT: and $9, $9, $7
-; MIPS4-NEXT: or $9, $9, $6
-; MIPS4-NEXT: sc $9, 0($2)
-; MIPS4-NEXT: beqz $9, .LBB13_1
+; MIPS4-NEXT: xor $6, $5, $6
+; MIPS4-NEXT: or $6, $6, $4
+; MIPS4-NEXT: sc $6, 0($3)
+; MIPS4-NEXT: beqz $6, .LBB13_1
; MIPS4-NEXT: nop
; MIPS4-NEXT: .LBB13_3: # %entry
-; MIPS4-NEXT: srlv $1, $10, $3
-; MIPS4-NEXT: sll $1, $1, 24
-; MIPS4-NEXT: sra $1, $1, 24
-; MIPS4-NEXT: # %bb.4: # %entry
-; MIPS4-NEXT: xor $1, $1, $5
+; MIPS4-NEXT: and $2, $5, $2
+; MIPS4-NEXT: xor $1, $1, $2
; MIPS4-NEXT: jr $ra
; MIPS4-NEXT: sltiu $2, $1, 1
;
; MIPS64-LABEL: AtomicCmpSwapRes8:
; MIPS64: # %bb.0: # %entry
-; MIPS64-NEXT: daddiu $1, $zero, -4
-; MIPS64-NEXT: and $2, $4, $1
-; MIPS64-NEXT: andi $1, $4, 3
-; MIPS64-NEXT: sll $3, $1, 3
-; MIPS64-NEXT: ori $1, $zero, 255
-; MIPS64-NEXT: sllv $4, $1, $3
-; MIPS64-NEXT: nor $7, $zero, $4
-; MIPS64-NEXT: andi $1, $5, 255
-; MIPS64-NEXT: sllv $8, $1, $3
-; MIPS64-NEXT: andi $1, $6, 255
-; MIPS64-NEXT: sllv $6, $1, $3
+; MIPS64-NEXT: sll $1, $4, 0
+; MIPS64-NEXT: andi $1, $1, 3
+; MIPS64-NEXT: sll $1, $1, 3
+; MIPS64-NEXT: addiu $2, $zero, 255
+; MIPS64-NEXT: daddiu $3, $zero, -4
+; MIPS64-NEXT: and $3, $4, $3
+; MIPS64-NEXT: sllv $2, $2, $1
+; MIPS64-NEXT: andi $4, $6, 255
+; MIPS64-NEXT: sllv $4, $4, $1
+; MIPS64-NEXT: andi $5, $5, 255
+; MIPS64-NEXT: sllv $1, $5, $1
; MIPS64-NEXT: .LBB13_1: # %entry
; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64-NEXT: ll $9, 0($2)
-; MIPS64-NEXT: and $10, $9, $4
-; MIPS64-NEXT: bne $10, $8, .LBB13_3
+; MIPS64-NEXT: ll $5, 0($3)
+; MIPS64-NEXT: and $6, $5, $2
+; MIPS64-NEXT: bne $6, $1, .LBB13_3
; MIPS64-NEXT: nop
; MIPS64-NEXT: # %bb.2: # %entry
; MIPS64-NEXT: # in Loop: Header=BB13_1 Depth=1
-; MIPS64-NEXT: and $9, $9, $7
-; MIPS64-NEXT: or $9, $9, $6
-; MIPS64-NEXT: sc $9, 0($2)
-; MIPS64-NEXT: beqz $9, .LBB13_1
+; MIPS64-NEXT: xor $6, $5, $6
+; MIPS64-NEXT: or $6, $6, $4
+; MIPS64-NEXT: sc $6, 0($3)
+; MIPS64-NEXT: beqz $6, .LBB13_1
; MIPS64-NEXT: nop
; MIPS64-NEXT: .LBB13_3: # %entry
-; MIPS64-NEXT: srlv $1, $10, $3
-; MIPS64-NEXT: sll $1, $1, 24
-; MIPS64-NEXT: sra $1, $1, 24
-; MIPS64-NEXT: # %bb.4: # %entry
-; MIPS64-NEXT: xor $1, $1, $5
+; MIPS64-NEXT: and $2, $5, $2
+; MIPS64-NEXT: xor $1, $1, $2
; MIPS64-NEXT: jr $ra
; MIPS64-NEXT: sltiu $2, $1, 1
;
; MIPS64R2-LABEL: AtomicCmpSwapRes8:
; MIPS64R2: # %bb.0: # %entry
-; MIPS64R2-NEXT: daddiu $1, $zero, -4
-; MIPS64R2-NEXT: and $2, $4, $1
-; MIPS64R2-NEXT: andi $1, $4, 3
-; MIPS64R2-NEXT: sll $3, $1, 3
-; MIPS64R2-NEXT: ori $1, $zero, 255
-; MIPS64R2-NEXT: sllv $4, $1, $3
-; MIPS64R2-NEXT: nor $7, $zero, $4
-; MIPS64R2-NEXT: andi $1, $5, 255
-; MIPS64R2-NEXT: sllv $8, $1, $3
-; MIPS64R2-NEXT: andi $1, $6, 255
-; MIPS64R2-NEXT: sllv $6, $1, $3
+; MIPS64R2-NEXT: sll $1, $4, 0
+; MIPS64R2-NEXT: andi $1, $1, 3
+; MIPS64R2-NEXT: sll $1, $1, 3
+; MIPS64R2-NEXT: addiu $2, $zero, 255
+; MIPS64R2-NEXT: daddiu $3, $zero, -4
+; MIPS64R2-NEXT: and $3, $4, $3
+; MIPS64R2-NEXT: sllv $2, $2, $1
+; MIPS64R2-NEXT: andi $4, $6, 255
+; MIPS64R2-NEXT: sllv $4, $4, $1
+; MIPS64R2-NEXT: andi $5, $5, 255
+; MIPS64R2-NEXT: sllv $1, $5, $1
; MIPS64R2-NEXT: .LBB13_1: # %entry
; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R2-NEXT: ll $9, 0($2)
-; MIPS64R2-NEXT: and $10, $9, $4
-; MIPS64R2-NEXT: bne $10, $8, .LBB13_3
+; MIPS64R2-NEXT: ll $5, 0($3)
+; MIPS64R2-NEXT: and $6, $5, $2
+; MIPS64R2-NEXT: bne $6, $1, .LBB13_3
; MIPS64R2-NEXT: nop
; MIPS64R2-NEXT: # %bb.2: # %entry
; MIPS64R2-NEXT: # in Loop: Header=BB13_1 Depth=1
-; MIPS64R2-NEXT: and $9, $9, $7
-; MIPS64R2-NEXT: or $9, $9, $6
-; MIPS64R2-NEXT: sc $9, 0($2)
-; MIPS64R2-NEXT: beqz $9, .LBB13_1
+; MIPS64R2-NEXT: xor $6, $5, $6
+; MIPS64R2-NEXT: or $6, $6, $4
+; MIPS64R2-NEXT: sc $6, 0($3)
+; MIPS64R2-NEXT: beqz $6, .LBB13_1
; MIPS64R2-NEXT: nop
; MIPS64R2-NEXT: .LBB13_3: # %entry
-; MIPS64R2-NEXT: srlv $1, $10, $3
-; MIPS64R2-NEXT: seb $1, $1
-; MIPS64R2-NEXT: # %bb.4: # %entry
-; MIPS64R2-NEXT: xor $1, $1, $5
+; MIPS64R2-NEXT: and $2, $5, $2
+; MIPS64R2-NEXT: xor $1, $1, $2
; MIPS64R2-NEXT: jr $ra
; MIPS64R2-NEXT: sltiu $2, $1, 1
;
; MIPS64R6-LABEL: AtomicCmpSwapRes8:
; MIPS64R6: # %bb.0: # %entry
-; MIPS64R6-NEXT: daddiu $1, $zero, -4
-; MIPS64R6-NEXT: and $2, $4, $1
-; MIPS64R6-NEXT: andi $1, $4, 3
-; MIPS64R6-NEXT: sll $3, $1, 3
-; MIPS64R6-NEXT: ori $1, $zero, 255
-; MIPS64R6-NEXT: sllv $4, $1, $3
-; MIPS64R6-NEXT: nor $7, $zero, $4
-; MIPS64R6-NEXT: andi $1, $5, 255
-; MIPS64R6-NEXT: sllv $8, $1, $3
-; MIPS64R6-NEXT: andi $1, $6, 255
-; MIPS64R6-NEXT: sllv $6, $1, $3
+; MIPS64R6-NEXT: sll $1, $4, 0
+; MIPS64R6-NEXT: andi $1, $1, 3
+; MIPS64R6-NEXT: sll $1, $1, 3
+; MIPS64R6-NEXT: addiu $2, $zero, 255
+; MIPS64R6-NEXT: daddiu $3, $zero, -4
+; MIPS64R6-NEXT: and $3, $4, $3
+; MIPS64R6-NEXT: sllv $2, $2, $1
+; MIPS64R6-NEXT: andi $4, $6, 255
+; MIPS64R6-NEXT: sllv $4, $4, $1
+; MIPS64R6-NEXT: andi $5, $5, 255
+; MIPS64R6-NEXT: sllv $1, $5, $1
; MIPS64R6-NEXT: .LBB13_1: # %entry
; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R6-NEXT: ll $9, 0($2)
-; MIPS64R6-NEXT: and $10, $9, $4
-; MIPS64R6-NEXT: bnec $10, $8, .LBB13_3
+; MIPS64R6-NEXT: ll $5, 0($3)
+; MIPS64R6-NEXT: and $6, $5, $2
+; MIPS64R6-NEXT: bnec $6, $1, .LBB13_3
; MIPS64R6-NEXT: # %bb.2: # %entry
; MIPS64R6-NEXT: # in Loop: Header=BB13_1 Depth=1
-; MIPS64R6-NEXT: and $9, $9, $7
-; MIPS64R6-NEXT: or $9, $9, $6
-; MIPS64R6-NEXT: sc $9, 0($2)
-; MIPS64R6-NEXT: beqzc $9, .LBB13_1
+; MIPS64R6-NEXT: xor $6, $5, $6
+; MIPS64R6-NEXT: or $6, $6, $4
+; MIPS64R6-NEXT: sc $6, 0($3)
+; MIPS64R6-NEXT: beqzc $6, .LBB13_1
; MIPS64R6-NEXT: .LBB13_3: # %entry
-; MIPS64R6-NEXT: srlv $1, $10, $3
-; MIPS64R6-NEXT: seb $1, $1
-; MIPS64R6-NEXT: # %bb.4: # %entry
-; MIPS64R6-NEXT: xor $1, $1, $5
+; MIPS64R6-NEXT: and $2, $5, $2
+; MIPS64R6-NEXT: xor $1, $1, $2
; MIPS64R6-NEXT: jr $ra
; MIPS64R6-NEXT: sltiu $2, $1, 1
;
; MIPS64R6O0-LABEL: AtomicCmpSwapRes8:
; MIPS64R6O0: # %bb.0: # %entry
-; MIPS64R6O0-NEXT: daddiu $sp, $sp, -16
+; MIPS64R6O0-NEXT: move $2, $6
+; MIPS64R6O0-NEXT: move $1, $5
+; MIPS64R6O0-NEXT: daddiu $3, $zero, -4
+; MIPS64R6O0-NEXT: and $5, $4, $3
; MIPS64R6O0-NEXT: move $3, $4
-; MIPS64R6O0-NEXT: move $1, $6
-; MIPS64R6O0-NEXT: move $2, $5
-; MIPS64R6O0-NEXT: sw $2, 8($sp) # 4-byte Folded Spill
-; MIPS64R6O0-NEXT: daddiu $4, $zero, -4
-; MIPS64R6O0-NEXT: and $4, $3, $4
+; MIPS64R6O0-NEXT: sll $3, $3, 0
+; MIPS64R6O0-NEXT: not $3, $3
; MIPS64R6O0-NEXT: andi $3, $3, 3
-; MIPS64R6O0-NEXT: xori $3, $3, 3
-; MIPS64R6O0-NEXT: sll $9, $3, 3
-; MIPS64R6O0-NEXT: ori $3, $zero, 255
-; MIPS64R6O0-NEXT: sllv $5, $3, $9
-; MIPS64R6O0-NEXT: nor $7, $zero, $5
-; MIPS64R6O0-NEXT: andi $2, $2, 255
-; MIPS64R6O0-NEXT: sllv $6, $2, $9
+; MIPS64R6O0-NEXT: sll $4, $3, 3
+; MIPS64R6O0-NEXT: addiu $3, $zero, 255
+; MIPS64R6O0-NEXT: sllv $3, $3, $4
; MIPS64R6O0-NEXT: andi $1, $1, 255
-; MIPS64R6O0-NEXT: sllv $8, $1, $9
+; MIPS64R6O0-NEXT: sllv $1, $1, $4
+; MIPS64R6O0-NEXT: andi $2, $2, 255
+; MIPS64R6O0-NEXT: sllv $6, $2, $4
; MIPS64R6O0-NEXT: .LBB13_1: # %entry
; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R6O0-NEXT: ll $2, 0($4)
-; MIPS64R6O0-NEXT: and $3, $2, $5
-; MIPS64R6O0-NEXT: bnec $3, $6, .LBB13_3
+; MIPS64R6O0-NEXT: ll $2, 0($5)
+; MIPS64R6O0-NEXT: and $4, $2, $3
+; MIPS64R6O0-NEXT: bnec $4, $1, .LBB13_3
; MIPS64R6O0-NEXT: # %bb.2: # %entry
; MIPS64R6O0-NEXT: # in Loop: Header=BB13_1 Depth=1
-; MIPS64R6O0-NEXT: and $2, $2, $7
-; MIPS64R6O0-NEXT: or $2, $2, $8
-; MIPS64R6O0-NEXT: sc $2, 0($4)
-; MIPS64R6O0-NEXT: beqzc $2, .LBB13_1
+; MIPS64R6O0-NEXT: xor $4, $2, $4
+; MIPS64R6O0-NEXT: or $4, $4, $6
+; MIPS64R6O0-NEXT: sc $4, 0($5)
+; MIPS64R6O0-NEXT: beqzc $4, .LBB13_1
; MIPS64R6O0-NEXT: .LBB13_3: # %entry
-; MIPS64R6O0-NEXT: srlv $1, $3, $9
-; MIPS64R6O0-NEXT: seb $1, $1
-; MIPS64R6O0-NEXT: # %bb.4: # %entry
-; MIPS64R6O0-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64R6O0-NEXT: # %bb.5: # %entry
-; MIPS64R6O0-NEXT: lw $1, 12($sp) # 4-byte Folded Reload
-; MIPS64R6O0-NEXT: lw $2, 8($sp) # 4-byte Folded Reload
+; MIPS64R6O0-NEXT: and $2, $2, $3
; MIPS64R6O0-NEXT: xor $1, $1, $2
; MIPS64R6O0-NEXT: sltiu $2, $1, 1
-; MIPS64R6O0-NEXT: daddiu $sp, $sp, 16
; MIPS64R6O0-NEXT: jrc $ra
;
; MM32-LABEL: AtomicCmpSwapRes8:
; MM32: # %bb.0: # %entry
-; MM32-NEXT: addiu $1, $zero, -4
-; MM32-NEXT: and $2, $4, $1
-; MM32-NEXT: andi $1, $4, 3
-; MM32-NEXT: sll $3, $1, 3
-; MM32-NEXT: ori $1, $zero, 255
-; MM32-NEXT: sllv $4, $1, $3
-; MM32-NEXT: nor $7, $zero, $4
-; MM32-NEXT: andi $1, $5, 255
-; MM32-NEXT: sllv $8, $1, $3
-; MM32-NEXT: andi $1, $6, 255
-; MM32-NEXT: sllv $6, $1, $3
+; MM32-NEXT: sll16 $2, $4, 3
+; MM32-NEXT: andi $1, $2, 24
+; MM32-NEXT: addiu $2, $zero, 255
+; MM32-NEXT: addiu $3, $zero, -4
+; MM32-NEXT: and16 $3, $4
+; MM32-NEXT: sllv $2, $2, $1
+; MM32-NEXT: andi16 $4, $6, 255
+; MM32-NEXT: sllv $4, $4, $1
+; MM32-NEXT: andi16 $5, $5, 255
+; MM32-NEXT: sllv $1, $5, $1
; MM32-NEXT: $BB13_1: # %entry
; MM32-NEXT: # =>This Inner Loop Header: Depth=1
-; MM32-NEXT: ll $9, 0($2)
-; MM32-NEXT: and $10, $9, $4
-; MM32-NEXT: bne $10, $8, $BB13_3
+; MM32-NEXT: ll $6, 0($3)
+; MM32-NEXT: and $5, $6, $2
+; MM32-NEXT: bne $5, $1, $BB13_3
; MM32-NEXT: nop
; MM32-NEXT: # %bb.2: # %entry
; MM32-NEXT: # in Loop: Header=BB13_1 Depth=1
-; MM32-NEXT: and $9, $9, $7
-; MM32-NEXT: or $9, $9, $6
-; MM32-NEXT: sc $9, 0($2)
-; MM32-NEXT: beqzc $9, $BB13_1
+; MM32-NEXT: xor16 $5, $6
+; MM32-NEXT: or $5, $5, $4
+; MM32-NEXT: sc $5, 0($3)
+; MM32-NEXT: beqzc $5, $BB13_1
; MM32-NEXT: $BB13_3: # %entry
-; MM32-NEXT: srlv $1, $10, $3
-; MM32-NEXT: seb $1, $1
-; MM32-NEXT: # %bb.4: # %entry
-; MM32-NEXT: xor $1, $1, $5
+; MM32-NEXT: and16 $6, $2
+; MM32-NEXT: xor $1, $1, $6
; MM32-NEXT: jr $ra
; MM32-NEXT: sltiu $2, $1, 1
;
; O1-LABEL: AtomicCmpSwapRes8:
; O1: # %bb.0: # %entry
-; O1-NEXT: addiu $1, $zero, -4
-; O1-NEXT: and $2, $4, $1
-; O1-NEXT: andi $1, $4, 3
-; O1-NEXT: sll $3, $1, 3
-; O1-NEXT: ori $1, $zero, 255
-; O1-NEXT: sllv $4, $1, $3
-; O1-NEXT: nor $7, $zero, $4
-; O1-NEXT: andi $1, $5, 255
-; O1-NEXT: sllv $8, $1, $3
-; O1-NEXT: andi $1, $6, 255
-; O1-NEXT: sllv $6, $1, $3
+; O1-NEXT: sll $1, $4, 3
+; O1-NEXT: addiu $2, $zero, 255
+; O1-NEXT: addiu $3, $zero, -4
+; O1-NEXT: and $3, $4, $3
+; O1-NEXT: sllv $2, $2, $1
+; O1-NEXT: andi $4, $6, 255
+; O1-NEXT: sllv $4, $4, $1
+; O1-NEXT: andi $5, $5, 255
+; O1-NEXT: sllv $1, $5, $1
; O1-NEXT: $BB13_1: # %entry
; O1-NEXT: # =>This Inner Loop Header: Depth=1
-; O1-NEXT: ll $9, 0($2)
-; O1-NEXT: and $10, $9, $4
-; O1-NEXT: bne $10, $8, $BB13_3
+; O1-NEXT: ll $5, 0($3)
+; O1-NEXT: and $6, $5, $2
+; O1-NEXT: bne $6, $1, $BB13_3
; O1-NEXT: nop
; O1-NEXT: # %bb.2: # %entry
; O1-NEXT: # in Loop: Header=BB13_1 Depth=1
-; O1-NEXT: and $9, $9, $7
-; O1-NEXT: or $9, $9, $6
-; O1-NEXT: sc $9, 0($2)
-; O1-NEXT: beqz $9, $BB13_1
+; O1-NEXT: xor $6, $5, $6
+; O1-NEXT: or $6, $6, $4
+; O1-NEXT: sc $6, 0($3)
+; O1-NEXT: beqz $6, $BB13_1
; O1-NEXT: nop
; O1-NEXT: $BB13_3: # %entry
-; O1-NEXT: srlv $1, $10, $3
-; O1-NEXT: sll $1, $1, 24
-; O1-NEXT: sra $1, $1, 24
-; O1-NEXT: # %bb.4: # %entry
-; O1-NEXT: xor $1, $1, $5
+; O1-NEXT: and $2, $5, $2
+; O1-NEXT: xor $1, $1, $2
; O1-NEXT: jr $ra
; O1-NEXT: sltiu $2, $1, 1
;
; O2-LABEL: AtomicCmpSwapRes8:
; O2: # %bb.0: # %entry
-; O2-NEXT: addiu $1, $zero, -4
-; O2-NEXT: and $2, $4, $1
-; O2-NEXT: andi $1, $4, 3
-; O2-NEXT: sll $3, $1, 3
-; O2-NEXT: ori $1, $zero, 255
-; O2-NEXT: sllv $4, $1, $3
-; O2-NEXT: nor $7, $zero, $4
-; O2-NEXT: andi $1, $5, 255
-; O2-NEXT: sllv $8, $1, $3
-; O2-NEXT: andi $1, $6, 255
-; O2-NEXT: sllv $6, $1, $3
+; O2-NEXT: sll $1, $4, 3
+; O2-NEXT: addiu $2, $zero, 255
+; O2-NEXT: addiu $3, $zero, -4
+; O2-NEXT: and $3, $4, $3
+; O2-NEXT: sllv $2, $2, $1
+; O2-NEXT: andi $4, $6, 255
+; O2-NEXT: sllv $4, $4, $1
+; O2-NEXT: andi $5, $5, 255
+; O2-NEXT: sllv $1, $5, $1
; O2-NEXT: $BB13_1: # %entry
; O2-NEXT: # =>This Inner Loop Header: Depth=1
-; O2-NEXT: ll $9, 0($2)
-; O2-NEXT: and $10, $9, $4
-; O2-NEXT: bne $10, $8, $BB13_3
+; O2-NEXT: ll $5, 0($3)
+; O2-NEXT: and $6, $5, $2
+; O2-NEXT: bne $6, $1, $BB13_3
; O2-NEXT: nop
; O2-NEXT: # %bb.2: # %entry
; O2-NEXT: # in Loop: Header=BB13_1 Depth=1
-; O2-NEXT: and $9, $9, $7
-; O2-NEXT: or $9, $9, $6
-; O2-NEXT: sc $9, 0($2)
-; O2-NEXT: beqz $9, $BB13_1
+; O2-NEXT: xor $6, $5, $6
+; O2-NEXT: or $6, $6, $4
+; O2-NEXT: sc $6, 0($3)
+; O2-NEXT: beqz $6, $BB13_1
; O2-NEXT: nop
; O2-NEXT: $BB13_3: # %entry
-; O2-NEXT: srlv $1, $10, $3
-; O2-NEXT: sll $1, $1, 24
-; O2-NEXT: sra $1, $1, 24
-; O2-NEXT: # %bb.4: # %entry
-; O2-NEXT: xor $1, $1, $5
+; O2-NEXT: and $2, $5, $2
+; O2-NEXT: xor $1, $1, $2
; O2-NEXT: jr $ra
; O2-NEXT: sltiu $2, $1, 1
;
; O3-LABEL: AtomicCmpSwapRes8:
; O3: # %bb.0: # %entry
-; O3-NEXT: addiu $1, $zero, -4
-; O3-NEXT: and $2, $4, $1
-; O3-NEXT: andi $1, $4, 3
-; O3-NEXT: sll $3, $1, 3
-; O3-NEXT: ori $1, $zero, 255
-; O3-NEXT: sllv $4, $1, $3
-; O3-NEXT: andi $1, $5, 255
-; O3-NEXT: sllv $8, $1, $3
-; O3-NEXT: andi $1, $6, 255
-; O3-NEXT: nor $7, $zero, $4
-; O3-NEXT: sllv $6, $1, $3
+; O3-NEXT: addiu $3, $zero, -4
+; O3-NEXT: sll $1, $4, 3
+; O3-NEXT: addiu $2, $zero, 255
+; O3-NEXT: andi $5, $5, 255
+; O3-NEXT: and $3, $4, $3
+; O3-NEXT: andi $4, $6, 255
+; O3-NEXT: sllv $2, $2, $1
+; O3-NEXT: sllv $4, $4, $1
+; O3-NEXT: sllv $1, $5, $1
; O3-NEXT: $BB13_1: # %entry
; O3-NEXT: # =>This Inner Loop Header: Depth=1
-; O3-NEXT: ll $9, 0($2)
-; O3-NEXT: and $10, $9, $4
-; O3-NEXT: bne $10, $8, $BB13_3
+; O3-NEXT: ll $5, 0($3)
+; O3-NEXT: and $6, $5, $2
+; O3-NEXT: bne $6, $1, $BB13_3
; O3-NEXT: nop
; O3-NEXT: # %bb.2: # %entry
; O3-NEXT: # in Loop: Header=BB13_1 Depth=1
-; O3-NEXT: and $9, $9, $7
-; O3-NEXT: or $9, $9, $6
-; O3-NEXT: sc $9, 0($2)
-; O3-NEXT: beqz $9, $BB13_1
+; O3-NEXT: xor $6, $5, $6
+; O3-NEXT: or $6, $6, $4
+; O3-NEXT: sc $6, 0($3)
+; O3-NEXT: beqz $6, $BB13_1
; O3-NEXT: nop
; O3-NEXT: $BB13_3: # %entry
-; O3-NEXT: srlv $1, $10, $3
-; O3-NEXT: sll $1, $1, 24
-; O3-NEXT: sra $1, $1, 24
-; O3-NEXT: # %bb.4: # %entry
-; O3-NEXT: xor $1, $1, $5
+; O3-NEXT: and $2, $5, $2
+; O3-NEXT: xor $1, $1, $2
; O3-NEXT: jr $ra
; O3-NEXT: sltiu $2, $1, 1
;
; MIPS32EB-LABEL: AtomicCmpSwapRes8:
; MIPS32EB: # %bb.0: # %entry
-; MIPS32EB-NEXT: addiu $1, $zero, -4
-; MIPS32EB-NEXT: and $2, $4, $1
-; MIPS32EB-NEXT: andi $1, $4, 3
-; MIPS32EB-NEXT: xori $1, $1, 3
-; MIPS32EB-NEXT: sll $3, $1, 3
-; MIPS32EB-NEXT: ori $1, $zero, 255
-; MIPS32EB-NEXT: sllv $4, $1, $3
-; MIPS32EB-NEXT: nor $7, $zero, $4
-; MIPS32EB-NEXT: andi $1, $5, 255
-; MIPS32EB-NEXT: sllv $8, $1, $3
-; MIPS32EB-NEXT: andi $1, $6, 255
-; MIPS32EB-NEXT: sllv $6, $1, $3
+; MIPS32EB-NEXT: not $1, $4
+; MIPS32EB-NEXT: andi $1, $1, 3
+; MIPS32EB-NEXT: sll $1, $1, 3
+; MIPS32EB-NEXT: addiu $2, $zero, 255
+; MIPS32EB-NEXT: addiu $3, $zero, -4
+; MIPS32EB-NEXT: and $3, $4, $3
+; MIPS32EB-NEXT: sllv $2, $2, $1
+; MIPS32EB-NEXT: andi $4, $6, 255
+; MIPS32EB-NEXT: sllv $4, $4, $1
+; MIPS32EB-NEXT: andi $5, $5, 255
+; MIPS32EB-NEXT: sllv $1, $5, $1
; MIPS32EB-NEXT: $BB13_1: # %entry
; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32EB-NEXT: ll $9, 0($2)
-; MIPS32EB-NEXT: and $10, $9, $4
-; MIPS32EB-NEXT: bne $10, $8, $BB13_3
+; MIPS32EB-NEXT: ll $5, 0($3)
+; MIPS32EB-NEXT: and $6, $5, $2
+; MIPS32EB-NEXT: bne $6, $1, $BB13_3
; MIPS32EB-NEXT: nop
; MIPS32EB-NEXT: # %bb.2: # %entry
; MIPS32EB-NEXT: # in Loop: Header=BB13_1 Depth=1
-; MIPS32EB-NEXT: and $9, $9, $7
-; MIPS32EB-NEXT: or $9, $9, $6
-; MIPS32EB-NEXT: sc $9, 0($2)
-; MIPS32EB-NEXT: beqz $9, $BB13_1
+; MIPS32EB-NEXT: xor $6, $5, $6
+; MIPS32EB-NEXT: or $6, $6, $4
+; MIPS32EB-NEXT: sc $6, 0($3)
+; MIPS32EB-NEXT: beqz $6, $BB13_1
; MIPS32EB-NEXT: nop
; MIPS32EB-NEXT: $BB13_3: # %entry
-; MIPS32EB-NEXT: srlv $1, $10, $3
-; MIPS32EB-NEXT: sll $1, $1, 24
-; MIPS32EB-NEXT: sra $1, $1, 24
-; MIPS32EB-NEXT: # %bb.4: # %entry
-; MIPS32EB-NEXT: xor $1, $1, $5
+; MIPS32EB-NEXT: and $2, $5, $2
+; MIPS32EB-NEXT: xor $1, $1, $2
; MIPS32EB-NEXT: jr $ra
; MIPS32EB-NEXT: sltiu $2, $1, 1
entry:
@@ -5393,71 +5076,62 @@ define signext i16 @AtomicLoadAdd16(i16 signext %incr) nounwind {
; MIPS32-NEXT: lui $2, %hi(_gp_disp)
; MIPS32-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32-NEXT: addu $1, $2, $25
-; MIPS32-NEXT: lw $1, %got(z)($1)
; MIPS32-NEXT: addiu $2, $zero, -4
-; MIPS32-NEXT: and $3, $1, $2
+; MIPS32-NEXT: lw $1, %got(z)($1)
+; MIPS32-NEXT: and $2, $1, $2
; MIPS32-NEXT: andi $1, $1, 3
; MIPS32-NEXT: sll $1, $1, 3
-; MIPS32-NEXT: ori $2, $zero, 65535
-; MIPS32-NEXT: sllv $5, $2, $1
-; MIPS32-NEXT: nor $6, $zero, $5
+; MIPS32-NEXT: ori $3, $zero, 65535
+; MIPS32-NEXT: sllv $3, $3, $1
+; MIPS32-NEXT: andi $4, $4, 65535
; MIPS32-NEXT: sllv $4, $4, $1
; MIPS32-NEXT: $BB14_1: # %entry
; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32-NEXT: ll $7, 0($3)
-; MIPS32-NEXT: addu $8, $7, $4
-; MIPS32-NEXT: and $8, $8, $5
-; MIPS32-NEXT: and $9, $7, $6
-; MIPS32-NEXT: or $9, $9, $8
-; MIPS32-NEXT: sc $9, 0($3)
-; MIPS32-NEXT: beqz $9, $BB14_1
+; MIPS32-NEXT: ll $5, 0($2)
+; MIPS32-NEXT: addu $6, $5, $4
+; MIPS32-NEXT: xor $6, $5, $6
+; MIPS32-NEXT: and $6, $6, $3
+; MIPS32-NEXT: xor $6, $5, $6
+; MIPS32-NEXT: sc $6, 0($2)
+; MIPS32-NEXT: beqz $6, $BB14_1
; MIPS32-NEXT: nop
; MIPS32-NEXT: # %bb.2: # %entry
-; MIPS32-NEXT: and $2, $7, $5
-; MIPS32-NEXT: srlv $2, $2, $1
-; MIPS32-NEXT: sll $2, $2, 16
-; MIPS32-NEXT: sra $2, $2, 16
-; MIPS32-NEXT: # %bb.3: # %entry
+; MIPS32-NEXT: srlv $1, $5, $1
+; MIPS32-NEXT: sll $1, $1, 16
; MIPS32-NEXT: jr $ra
-; MIPS32-NEXT: nop
+; MIPS32-NEXT: sra $2, $1, 16
;
; MIPS32O0-LABEL: AtomicLoadAdd16:
; MIPS32O0: # %bb.0: # %entry
; MIPS32O0-NEXT: lui $2, %hi(_gp_disp)
; MIPS32O0-NEXT: addiu $2, $2, %lo(_gp_disp)
-; MIPS32O0-NEXT: addiu $sp, $sp, -8
-; MIPS32O0-NEXT: addu $1, $2, $25
-; MIPS32O0-NEXT: lw $1, %got(z)($1)
-; MIPS32O0-NEXT: addiu $2, $zero, -4
-; MIPS32O0-NEXT: and $5, $1, $2
-; MIPS32O0-NEXT: andi $1, $1, 3
-; MIPS32O0-NEXT: sll $9, $1, 3
-; MIPS32O0-NEXT: ori $1, $zero, 65535
-; MIPS32O0-NEXT: sllv $7, $1, $9
-; MIPS32O0-NEXT: nor $8, $zero, $7
-; MIPS32O0-NEXT: sllv $6, $4, $9
+; MIPS32O0-NEXT: addu $2, $2, $25
+; MIPS32O0-NEXT: move $1, $4
+; MIPS32O0-NEXT: lw $3, %got(z)($2)
+; MIPS32O0-NEXT: addiu $4, $zero, -4
+; MIPS32O0-NEXT: and $4, $3, $4
+; MIPS32O0-NEXT: lw $2, %got(z)($2)
+; MIPS32O0-NEXT: addiu $3, $zero, 3
+; MIPS32O0-NEXT: and $2, $2, $3
+; MIPS32O0-NEXT: sll $2, $2, 3
+; MIPS32O0-NEXT: ori $3, $zero, 65535
+; MIPS32O0-NEXT: sllv $6, $3, $2
+; MIPS32O0-NEXT: andi $1, $1, 65535
+; MIPS32O0-NEXT: sllv $5, $1, $2
; MIPS32O0-NEXT: $BB14_1: # %entry
; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32O0-NEXT: ll $2, 0($5)
-; MIPS32O0-NEXT: addu $3, $2, $6
-; MIPS32O0-NEXT: and $3, $3, $7
-; MIPS32O0-NEXT: and $4, $2, $8
-; MIPS32O0-NEXT: or $4, $4, $3
-; MIPS32O0-NEXT: sc $4, 0($5)
-; MIPS32O0-NEXT: beqz $4, $BB14_1
+; MIPS32O0-NEXT: ll $1, 0($4)
+; MIPS32O0-NEXT: addu $3, $1, $5
+; MIPS32O0-NEXT: xor $3, $1, $3
+; MIPS32O0-NEXT: and $3, $3, $6
+; MIPS32O0-NEXT: xor $3, $1, $3
+; MIPS32O0-NEXT: sc $3, 0($4)
+; MIPS32O0-NEXT: beqz $3, $BB14_1
; MIPS32O0-NEXT: nop
; MIPS32O0-NEXT: # %bb.2: # %entry
-; MIPS32O0-NEXT: and $1, $2, $7
-; MIPS32O0-NEXT: srlv $1, $1, $9
-; MIPS32O0-NEXT: sll $1, $1, 16
-; MIPS32O0-NEXT: sra $1, $1, 16
-; MIPS32O0-NEXT: # %bb.3: # %entry
-; MIPS32O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32O0-NEXT: # %bb.4: # %entry
-; MIPS32O0-NEXT: lw $1, 4($sp) # 4-byte Folded Reload
+; MIPS32O0-NEXT: srlv $1, $1, $2
; MIPS32O0-NEXT: sll $1, $1, 16
; MIPS32O0-NEXT: sra $2, $1, 16
-; MIPS32O0-NEXT: addiu $sp, $sp, 8
; MIPS32O0-NEXT: jr $ra
; MIPS32O0-NEXT: nop
;
@@ -5466,96 +5140,85 @@ define signext i16 @AtomicLoadAdd16(i16 signext %incr) nounwind {
; MIPS32R2-NEXT: lui $2, %hi(_gp_disp)
; MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32R2-NEXT: addu $1, $2, $25
-; MIPS32R2-NEXT: lw $1, %got(z)($1)
; MIPS32R2-NEXT: addiu $2, $zero, -4
-; MIPS32R2-NEXT: and $3, $1, $2
+; MIPS32R2-NEXT: lw $1, %got(z)($1)
+; MIPS32R2-NEXT: and $2, $1, $2
; MIPS32R2-NEXT: andi $1, $1, 3
; MIPS32R2-NEXT: sll $1, $1, 3
-; MIPS32R2-NEXT: ori $2, $zero, 65535
-; MIPS32R2-NEXT: sllv $5, $2, $1
-; MIPS32R2-NEXT: nor $6, $zero, $5
+; MIPS32R2-NEXT: ori $3, $zero, 65535
+; MIPS32R2-NEXT: sllv $3, $3, $1
+; MIPS32R2-NEXT: andi $4, $4, 65535
; MIPS32R2-NEXT: sllv $4, $4, $1
; MIPS32R2-NEXT: $BB14_1: # %entry
; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32R2-NEXT: ll $7, 0($3)
-; MIPS32R2-NEXT: addu $8, $7, $4
-; MIPS32R2-NEXT: and $8, $8, $5
-; MIPS32R2-NEXT: and $9, $7, $6
-; MIPS32R2-NEXT: or $9, $9, $8
-; MIPS32R2-NEXT: sc $9, 0($3)
-; MIPS32R2-NEXT: beqz $9, $BB14_1
+; MIPS32R2-NEXT: ll $5, 0($2)
+; MIPS32R2-NEXT: addu $6, $5, $4
+; MIPS32R2-NEXT: xor $6, $5, $6
+; MIPS32R2-NEXT: and $6, $6, $3
+; MIPS32R2-NEXT: xor $6, $5, $6
+; MIPS32R2-NEXT: sc $6, 0($2)
+; MIPS32R2-NEXT: beqz $6, $BB14_1
; MIPS32R2-NEXT: nop
; MIPS32R2-NEXT: # %bb.2: # %entry
-; MIPS32R2-NEXT: and $2, $7, $5
-; MIPS32R2-NEXT: srlv $2, $2, $1
-; MIPS32R2-NEXT: seh $2, $2
-; MIPS32R2-NEXT: # %bb.3: # %entry
+; MIPS32R2-NEXT: srlv $1, $5, $1
; MIPS32R2-NEXT: jr $ra
-; MIPS32R2-NEXT: nop
+; MIPS32R2-NEXT: seh $2, $1
;
; MIPS32R6-LABEL: AtomicLoadAdd16:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lui $2, %hi(_gp_disp)
; MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32R6-NEXT: addu $1, $2, $25
-; MIPS32R6-NEXT: lw $1, %got(z)($1)
; MIPS32R6-NEXT: addiu $2, $zero, -4
-; MIPS32R6-NEXT: and $3, $1, $2
+; MIPS32R6-NEXT: lw $1, %got(z)($1)
+; MIPS32R6-NEXT: and $2, $1, $2
; MIPS32R6-NEXT: andi $1, $1, 3
; MIPS32R6-NEXT: sll $1, $1, 3
-; MIPS32R6-NEXT: ori $2, $zero, 65535
-; MIPS32R6-NEXT: sllv $5, $2, $1
-; MIPS32R6-NEXT: nor $6, $zero, $5
+; MIPS32R6-NEXT: ori $3, $zero, 65535
+; MIPS32R6-NEXT: sllv $3, $3, $1
+; MIPS32R6-NEXT: andi $4, $4, 65535
; MIPS32R6-NEXT: sllv $4, $4, $1
; MIPS32R6-NEXT: $BB14_1: # %entry
; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32R6-NEXT: ll $7, 0($3)
-; MIPS32R6-NEXT: addu $8, $7, $4
-; MIPS32R6-NEXT: and $8, $8, $5
-; MIPS32R6-NEXT: and $9, $7, $6
-; MIPS32R6-NEXT: or $9, $9, $8
-; MIPS32R6-NEXT: sc $9, 0($3)
-; MIPS32R6-NEXT: beqzc $9, $BB14_1
+; MIPS32R6-NEXT: ll $5, 0($2)
+; MIPS32R6-NEXT: addu $6, $5, $4
+; MIPS32R6-NEXT: xor $6, $5, $6
+; MIPS32R6-NEXT: and $6, $6, $3
+; MIPS32R6-NEXT: xor $6, $5, $6
+; MIPS32R6-NEXT: sc $6, 0($2)
+; MIPS32R6-NEXT: beqzc $6, $BB14_1
; MIPS32R6-NEXT: # %bb.2: # %entry
-; MIPS32R6-NEXT: and $2, $7, $5
-; MIPS32R6-NEXT: srlv $2, $2, $1
-; MIPS32R6-NEXT: seh $2, $2
-; MIPS32R6-NEXT: # %bb.3: # %entry
-; MIPS32R6-NEXT: jrc $ra
+; MIPS32R6-NEXT: srlv $1, $5, $1
+; MIPS32R6-NEXT: jr $ra
+; MIPS32R6-NEXT: seh $2, $1
;
; MIPS32R6O0-LABEL: AtomicLoadAdd16:
; MIPS32R6O0: # %bb.0: # %entry
; MIPS32R6O0-NEXT: lui $2, %hi(_gp_disp)
; MIPS32R6O0-NEXT: addiu $2, $2, %lo(_gp_disp)
-; MIPS32R6O0-NEXT: addiu $sp, $sp, -8
-; MIPS32R6O0-NEXT: addu $1, $2, $25
-; MIPS32R6O0-NEXT: lw $1, %got(z)($1)
-; MIPS32R6O0-NEXT: addiu $2, $zero, -4
-; MIPS32R6O0-NEXT: and $5, $1, $2
-; MIPS32R6O0-NEXT: andi $1, $1, 3
-; MIPS32R6O0-NEXT: sll $9, $1, 3
-; MIPS32R6O0-NEXT: ori $1, $zero, 65535
-; MIPS32R6O0-NEXT: sllv $7, $1, $9
-; MIPS32R6O0-NEXT: nor $8, $zero, $7
-; MIPS32R6O0-NEXT: sllv $6, $4, $9
+; MIPS32R6O0-NEXT: addu $2, $2, $25
+; MIPS32R6O0-NEXT: move $1, $4
+; MIPS32R6O0-NEXT: lw $2, %got(z)($2)
+; MIPS32R6O0-NEXT: addiu $3, $zero, -4
+; MIPS32R6O0-NEXT: and $4, $2, $3
+; MIPS32R6O0-NEXT: andi $2, $2, 3
+; MIPS32R6O0-NEXT: sll $2, $2, 3
+; MIPS32R6O0-NEXT: ori $3, $zero, 65535
+; MIPS32R6O0-NEXT: sllv $6, $3, $2
+; MIPS32R6O0-NEXT: andi $1, $1, 65535
+; MIPS32R6O0-NEXT: sllv $5, $1, $2
; MIPS32R6O0-NEXT: $BB14_1: # %entry
; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32R6O0-NEXT: ll $2, 0($5)
-; MIPS32R6O0-NEXT: addu $3, $2, $6
-; MIPS32R6O0-NEXT: and $3, $3, $7
-; MIPS32R6O0-NEXT: and $4, $2, $8
-; MIPS32R6O0-NEXT: or $4, $4, $3
-; MIPS32R6O0-NEXT: sc $4, 0($5)
-; MIPS32R6O0-NEXT: beqzc $4, $BB14_1
+; MIPS32R6O0-NEXT: ll $1, 0($4)
+; MIPS32R6O0-NEXT: addu $3, $1, $5
+; MIPS32R6O0-NEXT: xor $3, $1, $3
+; MIPS32R6O0-NEXT: and $3, $3, $6
+; MIPS32R6O0-NEXT: xor $3, $1, $3
+; MIPS32R6O0-NEXT: sc $3, 0($4)
+; MIPS32R6O0-NEXT: beqzc $3, $BB14_1
; MIPS32R6O0-NEXT: # %bb.2: # %entry
-; MIPS32R6O0-NEXT: and $1, $2, $7
-; MIPS32R6O0-NEXT: srlv $1, $1, $9
-; MIPS32R6O0-NEXT: seh $1, $1
-; MIPS32R6O0-NEXT: # %bb.3: # %entry
-; MIPS32R6O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32R6O0-NEXT: # %bb.4: # %entry
-; MIPS32R6O0-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
-; MIPS32R6O0-NEXT: addiu $sp, $sp, 8
+; MIPS32R6O0-NEXT: srlv $1, $1, $2
+; MIPS32R6O0-NEXT: seh $2, $1
; MIPS32R6O0-NEXT: jrc $ra
;
; MIPS4-LABEL: AtomicLoadAdd16:
@@ -5564,32 +5227,30 @@ define signext i16 @AtomicLoadAdd16(i16 signext %incr) nounwind {
; MIPS4-NEXT: daddu $1, $1, $25
; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd16)))
; MIPS4-NEXT: ld $1, %got_disp(z)($1)
-; MIPS4-NEXT: daddiu $2, $zero, -4
-; MIPS4-NEXT: and $3, $1, $2
-; MIPS4-NEXT: andi $1, $1, 3
-; MIPS4-NEXT: sll $1, $1, 3
-; MIPS4-NEXT: ori $2, $zero, 65535
-; MIPS4-NEXT: sllv $5, $2, $1
-; MIPS4-NEXT: nor $6, $zero, $5
-; MIPS4-NEXT: sllv $4, $4, $1
+; MIPS4-NEXT: sll $2, $1, 0
+; MIPS4-NEXT: andi $2, $2, 3
+; MIPS4-NEXT: daddiu $3, $zero, -4
+; MIPS4-NEXT: and $1, $1, $3
+; MIPS4-NEXT: sll $2, $2, 3
+; MIPS4-NEXT: ori $3, $zero, 65535
+; MIPS4-NEXT: sllv $3, $3, $2
+; MIPS4-NEXT: andi $4, $4, 65535
+; MIPS4-NEXT: sllv $4, $4, $2
; MIPS4-NEXT: .LBB14_1: # %entry
; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS4-NEXT: ll $7, 0($3)
-; MIPS4-NEXT: addu $8, $7, $4
-; MIPS4-NEXT: and $8, $8, $5
-; MIPS4-NEXT: and $9, $7, $6
-; MIPS4-NEXT: or $9, $9, $8
-; MIPS4-NEXT: sc $9, 0($3)
-; MIPS4-NEXT: beqz $9, .LBB14_1
+; MIPS4-NEXT: ll $5, 0($1)
+; MIPS4-NEXT: addu $6, $5, $4
+; MIPS4-NEXT: xor $6, $5, $6
+; MIPS4-NEXT: and $6, $6, $3
+; MIPS4-NEXT: xor $6, $5, $6
+; MIPS4-NEXT: sc $6, 0($1)
+; MIPS4-NEXT: beqz $6, .LBB14_1
; MIPS4-NEXT: nop
; MIPS4-NEXT: # %bb.2: # %entry
-; MIPS4-NEXT: and $2, $7, $5
-; MIPS4-NEXT: srlv $2, $2, $1
-; MIPS4-NEXT: sll $2, $2, 16
-; MIPS4-NEXT: sra $2, $2, 16
-; MIPS4-NEXT: # %bb.3: # %entry
+; MIPS4-NEXT: srlv $1, $5, $2
+; MIPS4-NEXT: sll $1, $1, 16
; MIPS4-NEXT: jr $ra
-; MIPS4-NEXT: nop
+; MIPS4-NEXT: sra $2, $1, 16
;
; MIPS64-LABEL: AtomicLoadAdd16:
; MIPS64: # %bb.0: # %entry
@@ -5597,32 +5258,30 @@ define signext i16 @AtomicLoadAdd16(i16 signext %incr) nounwind {
; MIPS64-NEXT: daddu $1, $1, $25
; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd16)))
; MIPS64-NEXT: ld $1, %got_disp(z)($1)
-; MIPS64-NEXT: daddiu $2, $zero, -4
-; MIPS64-NEXT: and $3, $1, $2
-; MIPS64-NEXT: andi $1, $1, 3
-; MIPS64-NEXT: sll $1, $1, 3
-; MIPS64-NEXT: ori $2, $zero, 65535
-; MIPS64-NEXT: sllv $5, $2, $1
-; MIPS64-NEXT: nor $6, $zero, $5
-; MIPS64-NEXT: sllv $4, $4, $1
+; MIPS64-NEXT: sll $2, $1, 0
+; MIPS64-NEXT: andi $2, $2, 3
+; MIPS64-NEXT: daddiu $3, $zero, -4
+; MIPS64-NEXT: and $1, $1, $3
+; MIPS64-NEXT: sll $2, $2, 3
+; MIPS64-NEXT: ori $3, $zero, 65535
+; MIPS64-NEXT: sllv $3, $3, $2
+; MIPS64-NEXT: andi $4, $4, 65535
+; MIPS64-NEXT: sllv $4, $4, $2
; MIPS64-NEXT: .LBB14_1: # %entry
; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64-NEXT: ll $7, 0($3)
-; MIPS64-NEXT: addu $8, $7, $4
-; MIPS64-NEXT: and $8, $8, $5
-; MIPS64-NEXT: and $9, $7, $6
-; MIPS64-NEXT: or $9, $9, $8
-; MIPS64-NEXT: sc $9, 0($3)
-; MIPS64-NEXT: beqz $9, .LBB14_1
+; MIPS64-NEXT: ll $5, 0($1)
+; MIPS64-NEXT: addu $6, $5, $4
+; MIPS64-NEXT: xor $6, $5, $6
+; MIPS64-NEXT: and $6, $6, $3
+; MIPS64-NEXT: xor $6, $5, $6
+; MIPS64-NEXT: sc $6, 0($1)
+; MIPS64-NEXT: beqz $6, .LBB14_1
; MIPS64-NEXT: nop
; MIPS64-NEXT: # %bb.2: # %entry
-; MIPS64-NEXT: and $2, $7, $5
-; MIPS64-NEXT: srlv $2, $2, $1
-; MIPS64-NEXT: sll $2, $2, 16
-; MIPS64-NEXT: sra $2, $2, 16
-; MIPS64-NEXT: # %bb.3: # %entry
+; MIPS64-NEXT: srlv $1, $5, $2
+; MIPS64-NEXT: sll $1, $1, 16
; MIPS64-NEXT: jr $ra
-; MIPS64-NEXT: nop
+; MIPS64-NEXT: sra $2, $1, 16
;
; MIPS64R2-LABEL: AtomicLoadAdd16:
; MIPS64R2: # %bb.0: # %entry
@@ -5630,31 +5289,29 @@ define signext i16 @AtomicLoadAdd16(i16 signext %incr) nounwind {
; MIPS64R2-NEXT: daddu $1, $1, $25
; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd16)))
; MIPS64R2-NEXT: ld $1, %got_disp(z)($1)
-; MIPS64R2-NEXT: daddiu $2, $zero, -4
-; MIPS64R2-NEXT: and $3, $1, $2
-; MIPS64R2-NEXT: andi $1, $1, 3
-; MIPS64R2-NEXT: sll $1, $1, 3
-; MIPS64R2-NEXT: ori $2, $zero, 65535
-; MIPS64R2-NEXT: sllv $5, $2, $1
-; MIPS64R2-NEXT: nor $6, $zero, $5
-; MIPS64R2-NEXT: sllv $4, $4, $1
+; MIPS64R2-NEXT: sll $2, $1, 0
+; MIPS64R2-NEXT: andi $2, $2, 3
+; MIPS64R2-NEXT: daddiu $3, $zero, -4
+; MIPS64R2-NEXT: and $1, $1, $3
+; MIPS64R2-NEXT: sll $2, $2, 3
+; MIPS64R2-NEXT: ori $3, $zero, 65535
+; MIPS64R2-NEXT: sllv $3, $3, $2
+; MIPS64R2-NEXT: andi $4, $4, 65535
+; MIPS64R2-NEXT: sllv $4, $4, $2
; MIPS64R2-NEXT: .LBB14_1: # %entry
; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R2-NEXT: ll $7, 0($3)
-; MIPS64R2-NEXT: addu $8, $7, $4
-; MIPS64R2-NEXT: and $8, $8, $5
-; MIPS64R2-NEXT: and $9, $7, $6
-; MIPS64R2-NEXT: or $9, $9, $8
-; MIPS64R2-NEXT: sc $9, 0($3)
-; MIPS64R2-NEXT: beqz $9, .LBB14_1
+; MIPS64R2-NEXT: ll $5, 0($1)
+; MIPS64R2-NEXT: addu $6, $5, $4
+; MIPS64R2-NEXT: xor $6, $5, $6
+; MIPS64R2-NEXT: and $6, $6, $3
+; MIPS64R2-NEXT: xor $6, $5, $6
+; MIPS64R2-NEXT: sc $6, 0($1)
+; MIPS64R2-NEXT: beqz $6, .LBB14_1
; MIPS64R2-NEXT: nop
; MIPS64R2-NEXT: # %bb.2: # %entry
-; MIPS64R2-NEXT: and $2, $7, $5
-; MIPS64R2-NEXT: srlv $2, $2, $1
-; MIPS64R2-NEXT: seh $2, $2
-; MIPS64R2-NEXT: # %bb.3: # %entry
+; MIPS64R2-NEXT: srlv $1, $5, $2
; MIPS64R2-NEXT: jr $ra
-; MIPS64R2-NEXT: nop
+; MIPS64R2-NEXT: seh $2, $1
;
; MIPS64R6-LABEL: AtomicLoadAdd16:
; MIPS64R6: # %bb.0: # %entry
@@ -5662,65 +5319,59 @@ define signext i16 @AtomicLoadAdd16(i16 signext %incr) nounwind {
; MIPS64R6-NEXT: daddu $1, $1, $25
; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd16)))
; MIPS64R6-NEXT: ld $1, %got_disp(z)($1)
-; MIPS64R6-NEXT: daddiu $2, $zero, -4
-; MIPS64R6-NEXT: and $3, $1, $2
-; MIPS64R6-NEXT: andi $1, $1, 3
-; MIPS64R6-NEXT: sll $1, $1, 3
-; MIPS64R6-NEXT: ori $2, $zero, 65535
-; MIPS64R6-NEXT: sllv $5, $2, $1
-; MIPS64R6-NEXT: nor $6, $zero, $5
-; MIPS64R6-NEXT: sllv $4, $4, $1
+; MIPS64R6-NEXT: sll $2, $1, 0
+; MIPS64R6-NEXT: andi $2, $2, 3
+; MIPS64R6-NEXT: daddiu $3, $zero, -4
+; MIPS64R6-NEXT: and $1, $1, $3
+; MIPS64R6-NEXT: sll $2, $2, 3
+; MIPS64R6-NEXT: ori $3, $zero, 65535
+; MIPS64R6-NEXT: sllv $3, $3, $2
+; MIPS64R6-NEXT: andi $4, $4, 65535
+; MIPS64R6-NEXT: sllv $4, $4, $2
; MIPS64R6-NEXT: .LBB14_1: # %entry
; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R6-NEXT: ll $7, 0($3)
-; MIPS64R6-NEXT: addu $8, $7, $4
-; MIPS64R6-NEXT: and $8, $8, $5
-; MIPS64R6-NEXT: and $9, $7, $6
-; MIPS64R6-NEXT: or $9, $9, $8
-; MIPS64R6-NEXT: sc $9, 0($3)
-; MIPS64R6-NEXT: beqzc $9, .LBB14_1
+; MIPS64R6-NEXT: ll $5, 0($1)
+; MIPS64R6-NEXT: addu $6, $5, $4
+; MIPS64R6-NEXT: xor $6, $5, $6
+; MIPS64R6-NEXT: and $6, $6, $3
+; MIPS64R6-NEXT: xor $6, $5, $6
+; MIPS64R6-NEXT: sc $6, 0($1)
+; MIPS64R6-NEXT: beqzc $6, .LBB14_1
; MIPS64R6-NEXT: # %bb.2: # %entry
-; MIPS64R6-NEXT: and $2, $7, $5
-; MIPS64R6-NEXT: srlv $2, $2, $1
-; MIPS64R6-NEXT: seh $2, $2
-; MIPS64R6-NEXT: # %bb.3: # %entry
-; MIPS64R6-NEXT: jrc $ra
+; MIPS64R6-NEXT: srlv $1, $5, $2
+; MIPS64R6-NEXT: jr $ra
+; MIPS64R6-NEXT: seh $2, $1
;
; MIPS64R6O0-LABEL: AtomicLoadAdd16:
; MIPS64R6O0: # %bb.0: # %entry
-; MIPS64R6O0-NEXT: daddiu $sp, $sp, -16
; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd16)))
; MIPS64R6O0-NEXT: daddu $1, $1, $25
; MIPS64R6O0-NEXT: daddiu $2, $1, %lo(%neg(%gp_rel(AtomicLoadAdd16)))
; MIPS64R6O0-NEXT: move $1, $4
; MIPS64R6O0-NEXT: ld $2, %got_disp(z)($2)
; MIPS64R6O0-NEXT: daddiu $3, $zero, -4
-; MIPS64R6O0-NEXT: and $5, $2, $3
+; MIPS64R6O0-NEXT: and $4, $2, $3
+; MIPS64R6O0-NEXT: # kill: def $v0 killed $v0 killed $v0_64
+; MIPS64R6O0-NEXT: sll $2, $2, 0
; MIPS64R6O0-NEXT: andi $2, $2, 3
; MIPS64R6O0-NEXT: xori $2, $2, 2
-; MIPS64R6O0-NEXT: sll $9, $2, 3
-; MIPS64R6O0-NEXT: ori $2, $zero, 65535
-; MIPS64R6O0-NEXT: sllv $7, $2, $9
-; MIPS64R6O0-NEXT: nor $8, $zero, $7
-; MIPS64R6O0-NEXT: sllv $6, $1, $9
+; MIPS64R6O0-NEXT: sll $2, $2, 3
+; MIPS64R6O0-NEXT: ori $3, $zero, 65535
+; MIPS64R6O0-NEXT: sllv $6, $3, $2
+; MIPS64R6O0-NEXT: andi $1, $1, 65535
+; MIPS64R6O0-NEXT: sllv $5, $1, $2
; MIPS64R6O0-NEXT: .LBB14_1: # %entry
; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS64R6O0-NEXT: ll $2, 0($5)
-; MIPS64R6O0-NEXT: addu $3, $2, $6
-; MIPS64R6O0-NEXT: and $3, $3, $7
-; MIPS64R6O0-NEXT: and $4, $2, $8
-; MIPS64R6O0-NEXT: or $4, $4, $3
-; MIPS64R6O0-NEXT: sc $4, 0($5)
-; MIPS64R6O0-NEXT: beqzc $4, .LBB14_1
+; MIPS64R6O0-NEXT: ll $1, 0($4)
+; MIPS64R6O0-NEXT: addu $3, $1, $5
+; MIPS64R6O0-NEXT: xor $3, $1, $3
+; MIPS64R6O0-NEXT: and $3, $3, $6
+; MIPS64R6O0-NEXT: xor $3, $1, $3
+; MIPS64R6O0-NEXT: sc $3, 0($4)
+; MIPS64R6O0-NEXT: beqzc $3, .LBB14_1
; MIPS64R6O0-NEXT: # %bb.2: # %entry
-; MIPS64R6O0-NEXT: and $1, $2, $7
-; MIPS64R6O0-NEXT: srlv $1, $1, $9
-; MIPS64R6O0-NEXT: seh $1, $1
-; MIPS64R6O0-NEXT: # %bb.3: # %entry
-; MIPS64R6O0-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64R6O0-NEXT: # %bb.4: # %entry
-; MIPS64R6O0-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
-; MIPS64R6O0-NEXT: daddiu $sp, $sp, 16
+; MIPS64R6O0-NEXT: srlv $1, $1, $2
+; MIPS64R6O0-NEXT: seh $2, $1
; MIPS64R6O0-NEXT: jrc $ra
;
; MM32-LABEL: AtomicLoadAdd16:
@@ -5728,96 +5379,88 @@ define signext i16 @AtomicLoadAdd16(i16 signext %incr) nounwind {
; MM32-NEXT: lui $2, %hi(_gp_disp)
; MM32-NEXT: addiu $2, $2, %lo(_gp_disp)
; MM32-NEXT: addu $2, $2, $25
-; MM32-NEXT: lw $1, %got(z)($2)
-; MM32-NEXT: addiu $2, $zero, -4
-; MM32-NEXT: and $3, $1, $2
-; MM32-NEXT: andi $1, $1, 3
-; MM32-NEXT: sll $1, $1, 3
-; MM32-NEXT: ori $2, $zero, 65535
-; MM32-NEXT: sllv $5, $2, $1
-; MM32-NEXT: nor $6, $zero, $5
-; MM32-NEXT: sllv $4, $4, $1
+; MM32-NEXT: addiu $3, $zero, -4
+; MM32-NEXT: lw $2, %got(z)($2)
+; MM32-NEXT: and16 $3, $2
+; MM32-NEXT: andi16 $2, $2, 3
+; MM32-NEXT: sll16 $2, $2, 3
+; MM32-NEXT: ori $1, $zero, 65535
+; MM32-NEXT: sllv $1, $1, $2
+; MM32-NEXT: andi16 $4, $4, 65535
+; MM32-NEXT: sllv $4, $4, $2
; MM32-NEXT: $BB14_1: # %entry
; MM32-NEXT: # =>This Inner Loop Header: Depth=1
-; MM32-NEXT: ll $7, 0($3)
-; MM32-NEXT: addu $8, $7, $4
-; MM32-NEXT: and $8, $8, $5
-; MM32-NEXT: and $9, $7, $6
-; MM32-NEXT: or $9, $9, $8
-; MM32-NEXT: sc $9, 0($3)
-; MM32-NEXT: beqzc $9, $BB14_1
+; MM32-NEXT: ll $5, 0($3)
+; MM32-NEXT: addu16 $6, $5, $4
+; MM32-NEXT: xor16 $6, $5
+; MM32-NEXT: and $6, $6, $1
+; MM32-NEXT: xor16 $6, $5
+; MM32-NEXT: sc $6, 0($3)
+; MM32-NEXT: beqzc $6, $BB14_1
; MM32-NEXT: # %bb.2: # %entry
-; MM32-NEXT: and $2, $7, $5
-; MM32-NEXT: srlv $2, $2, $1
-; MM32-NEXT: seh $2, $2
-; MM32-NEXT: # %bb.3: # %entry
-; MM32-NEXT: jrc $ra
+; MM32-NEXT: srlv $1, $5, $2
+; MM32-NEXT: jr $ra
+; MM32-NEXT: seh $2, $1
;
; O1-LABEL: AtomicLoadAdd16:
; O1: # %bb.0: # %entry
; O1-NEXT: lui $2, %hi(_gp_disp)
; O1-NEXT: addiu $2, $2, %lo(_gp_disp)
; O1-NEXT: addu $1, $2, $25
-; O1-NEXT: lw $1, %got(z)($1)
; O1-NEXT: addiu $2, $zero, -4
-; O1-NEXT: and $3, $1, $2
+; O1-NEXT: lw $1, %got(z)($1)
+; O1-NEXT: and $2, $1, $2
; O1-NEXT: andi $1, $1, 3
; O1-NEXT: sll $1, $1, 3
-; O1-NEXT: ori $2, $zero, 65535
-; O1-NEXT: sllv $5, $2, $1
-; O1-NEXT: nor $6, $zero, $5
+; O1-NEXT: ori $3, $zero, 65535
+; O1-NEXT: sllv $3, $3, $1
+; O1-NEXT: andi $4, $4, 65535
; O1-NEXT: sllv $4, $4, $1
; O1-NEXT: $BB14_1: # %entry
; O1-NEXT: # =>This Inner Loop Header: Depth=1
-; O1-NEXT: ll $7, 0($3)
-; O1-NEXT: addu $8, $7, $4
-; O1-NEXT: and $8, $8, $5
-; O1-NEXT: and $9, $7, $6
-; O1-NEXT: or $9, $9, $8
-; O1-NEXT: sc $9, 0($3)
-; O1-NEXT: beqz $9, $BB14_1
+; O1-NEXT: ll $5, 0($2)
+; O1-NEXT: addu $6, $5, $4
+; O1-NEXT: xor $6, $5, $6
+; O1-NEXT: and $6, $6, $3
+; O1-NEXT: xor $6, $5, $6
+; O1-NEXT: sc $6, 0($2)
+; O1-NEXT: beqz $6, $BB14_1
; O1-NEXT: nop
; O1-NEXT: # %bb.2: # %entry
-; O1-NEXT: and $2, $7, $5
-; O1-NEXT: srlv $2, $2, $1
-; O1-NEXT: sll $2, $2, 16
-; O1-NEXT: sra $2, $2, 16
-; O1-NEXT: # %bb.3: # %entry
+; O1-NEXT: srlv $1, $5, $1
+; O1-NEXT: sll $1, $1, 16
; O1-NEXT: jr $ra
-; O1-NEXT: nop
+; O1-NEXT: sra $2, $1, 16
;
; O2-LABEL: AtomicLoadAdd16:
; O2: # %bb.0: # %entry
; O2-NEXT: lui $2, %hi(_gp_disp)
; O2-NEXT: addiu $2, $2, %lo(_gp_disp)
; O2-NEXT: addu $1, $2, $25
-; O2-NEXT: lw $1, %got(z)($1)
; O2-NEXT: addiu $2, $zero, -4
-; O2-NEXT: and $3, $1, $2
+; O2-NEXT: lw $1, %got(z)($1)
+; O2-NEXT: and $2, $1, $2
; O2-NEXT: andi $1, $1, 3
; O2-NEXT: sll $1, $1, 3
-; O2-NEXT: ori $2, $zero, 65535
-; O2-NEXT: sllv $5, $2, $1
-; O2-NEXT: nor $6, $zero, $5
+; O2-NEXT: ori $3, $zero, 65535
+; O2-NEXT: sllv $3, $3, $1
+; O2-NEXT: andi $4, $4, 65535
; O2-NEXT: sllv $4, $4, $1
; O2-NEXT: $BB14_1: # %entry
; O2-NEXT: # =>This Inner Loop Header: Depth=1
-; O2-NEXT: ll $7, 0($3)
-; O2-NEXT: addu $8, $7, $4
-; O2-NEXT: and $8, $8, $5
-; O2-NEXT: and $9, $7, $6
-; O2-NEXT: or $9, $9, $8
-; O2-NEXT: sc $9, 0($3)
-; O2-NEXT: beqz $9, $BB14_1
+; O2-NEXT: ll $5, 0($2)
+; O2-NEXT: addu $6, $5, $4
+; O2-NEXT: xor $6, $5, $6
+; O2-NEXT: and $6, $6, $3
+; O2-NEXT: xor $6, $5, $6
+; O2-NEXT: sc $6, 0($2)
+; O2-NEXT: beqz $6, $BB14_1
; O2-NEXT: nop
; O2-NEXT: # %bb.2: # %entry
-; O2-NEXT: and $2, $7, $5
-; O2-NEXT: srlv $2, $2, $1
-; O2-NEXT: sll $2, $2, 16
-; O2-NEXT: sra $2, $2, 16
-; O2-NEXT: # %bb.3: # %entry
+; O2-NEXT: srlv $1, $5, $1
+; O2-NEXT: sll $1, $1, 16
; O2-NEXT: jr $ra
-; O2-NEXT: nop
+; O2-NEXT: sra $2, $1, 16
;
; O3-LABEL: AtomicLoadAdd16:
; O3: # %bb.0: # %entry
@@ -5825,32 +5468,29 @@ define signext i16 @AtomicLoadAdd16(i16 signext %incr) nounwind {
; O3-NEXT: addiu $2, $2, %lo(_gp_disp)
; O3-NEXT: addu $1, $2, $25
; O3-NEXT: addiu $2, $zero, -4
+; O3-NEXT: ori $3, $zero, 65535
+; O3-NEXT: andi $4, $4, 65535
; O3-NEXT: lw $1, %got(z)($1)
-; O3-NEXT: and $3, $1, $2
+; O3-NEXT: and $2, $1, $2
; O3-NEXT: andi $1, $1, 3
-; O3-NEXT: ori $2, $zero, 65535
; O3-NEXT: sll $1, $1, 3
-; O3-NEXT: sllv $5, $2, $1
+; O3-NEXT: sllv $3, $3, $1
; O3-NEXT: sllv $4, $4, $1
-; O3-NEXT: nor $6, $zero, $5
; O3-NEXT: $BB14_1: # %entry
; O3-NEXT: # =>This Inner Loop Header: Depth=1
-; O3-NEXT: ll $7, 0($3)
-; O3-NEXT: addu $8, $7, $4
-; O3-NEXT: and $8, $8, $5
-; O3-NEXT: and $9, $7, $6
-; O3-NEXT: or $9, $9, $8
-; O3-NEXT: sc $9, 0($3)
-; O3-NEXT: beqz $9, $BB14_1
+; O3-NEXT: ll $5, 0($2)
+; O3-NEXT: addu $6, $5, $4
+; O3-NEXT: xor $6, $5, $6
+; O3-NEXT: and $6, $6, $3
+; O3-NEXT: xor $6, $5, $6
+; O3-NEXT: sc $6, 0($2)
+; O3-NEXT: beqz $6, $BB14_1
; O3-NEXT: nop
; O3-NEXT: # %bb.2: # %entry
-; O3-NEXT: and $2, $7, $5
-; O3-NEXT: srlv $2, $2, $1
-; O3-NEXT: sll $2, $2, 16
-; O3-NEXT: sra $2, $2, 16
-; O3-NEXT: # %bb.3: # %entry
+; O3-NEXT: srlv $1, $5, $1
+; O3-NEXT: sll $1, $1, 16
; O3-NEXT: jr $ra
-; O3-NEXT: nop
+; O3-NEXT: sra $2, $1, 16
;
; MIPS32EB-LABEL: AtomicLoadAdd16:
; MIPS32EB: # %bb.0: # %entry
@@ -5858,33 +5498,30 @@ define signext i16 @AtomicLoadAdd16(i16 signext %incr) nounwind {
; MIPS32EB-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPS32EB-NEXT: addu $1, $2, $25
; MIPS32EB-NEXT: lw $1, %got(z)($1)
-; MIPS32EB-NEXT: addiu $2, $zero, -4
-; MIPS32EB-NEXT: and $3, $1, $2
-; MIPS32EB-NEXT: andi $1, $1, 3
-; MIPS32EB-NEXT: xori $1, $1, 2
-; MIPS32EB-NEXT: sll $1, $1, 3
-; MIPS32EB-NEXT: ori $2, $zero, 65535
-; MIPS32EB-NEXT: sllv $5, $2, $1
-; MIPS32EB-NEXT: nor $6, $zero, $5
-; MIPS32EB-NEXT: sllv $4, $4, $1
+; MIPS32EB-NEXT: andi $2, $1, 3
+; MIPS32EB-NEXT: addiu $3, $zero, -4
+; MIPS32EB-NEXT: and $1, $1, $3
+; MIPS32EB-NEXT: xori $2, $2, 2
+; MIPS32EB-NEXT: sll $2, $2, 3
+; MIPS32EB-NEXT: ori $3, $zero, 65535
+; MIPS32EB-NEXT: sllv $3, $3, $2
+; MIPS32EB-NEXT: andi $4, $4, 65535
+; MIPS32EB-NEXT: sllv $4, $4, $2
; MIPS32EB-NEXT: $BB14_1: # %entry
; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1
-; MIPS32EB-NEXT: ll $7, 0($3)
-; MIPS32EB-NEXT: addu $8, $7, $4
-; MIPS32EB-NEXT: and $8, $8, $5
-; MIPS32EB-NEXT: and $9, $7, $6
-; MIPS32EB-NEXT: or $9, $9, $8
-; MIPS32EB-NEXT: sc $9, 0($3)
-; MIPS32EB-NEXT: beqz $9, $BB14_1
+; MIPS32EB-NEXT: ll $5, 0($1)
+; MIPS32EB-NEXT: addu $6, $5, $4
+; MIPS32EB-NEXT: xor $6, $5, $6
+; MIPS32EB-NEXT: and $6, $6, $3
+; MIPS32EB-NEXT: xor $6, $5, $6
+; MIPS32EB-NEXT: sc $6, 0($1)
+; MIPS32EB-NEXT: beqz $6, $BB14_1
; MIPS32EB-NEXT: nop
; MIPS32EB-NEXT: # %bb.2: # %entry
-; MIPS32EB-NEXT: and $2, $7, $5
-; MIPS32EB-NEXT: srlv $2, $2, $1
-; MIPS32EB-NEXT: sll $2, $2, 16
-; MIPS32EB-NEXT: sra $2, $2, 16
-; MIPS32EB-NEXT: # %bb.3: # %entry
+; MIPS32EB-NEXT: srlv $1, $5, $2
+; MIPS32EB-NEXT: sll $1, $1, 16
; MIPS32EB-NEXT: jr $ra
-; MIPS32EB-NEXT: nop
+; MIPS32EB-NEXT: sra $2, $1, 16
entry:
%0 = atomicrmw add ptr @z, i16 %incr monotonic
ret i16 %0
@@ -5899,38 +5536,32 @@ entry:
define {i16, i1} @foo(ptr %addr, i16 %l, i16 %r, i16 %new) {
; MIPS32-LABEL: foo:
; MIPS32: # %bb.0:
-; MIPS32-NEXT: addu $1, $5, $6
+; MIPS32-NEXT: andi $1, $7, 65535
+; MIPS32-NEXT: sll $2, $4, 3
+; MIPS32-NEXT: ori $3, $zero, 65535
+; MIPS32-NEXT: addiu $7, $zero, -4
+; MIPS32-NEXT: and $4, $4, $7
+; MIPS32-NEXT: sllv $3, $3, $2
+; MIPS32-NEXT: sllv $1, $1, $2
+; MIPS32-NEXT: addu $5, $5, $6
+; MIPS32-NEXT: andi $5, $5, 65535
+; MIPS32-NEXT: sllv $5, $5, $2
; MIPS32-NEXT: sync
-; MIPS32-NEXT: addiu $2, $zero, -4
-; MIPS32-NEXT: and $3, $4, $2
-; MIPS32-NEXT: andi $2, $4, 3
-; MIPS32-NEXT: sll $4, $2, 3
-; MIPS32-NEXT: ori $2, $zero, 65535
-; MIPS32-NEXT: sllv $5, $2, $4
-; MIPS32-NEXT: nor $6, $zero, $5
-; MIPS32-NEXT: andi $2, $1, 65535
-; MIPS32-NEXT: sllv $8, $2, $4
-; MIPS32-NEXT: andi $2, $7, 65535
-; MIPS32-NEXT: sllv $7, $2, $4
; MIPS32-NEXT: $BB15_1: # =>This Inner Loop Header: Depth=1
-; MIPS32-NEXT: ll $9, 0($3)
-; MIPS32-NEXT: and $10, $9, $5
-; MIPS32-NEXT: bne $10, $8, $BB15_3
+; MIPS32-NEXT: ll $6, 0($4)
+; MIPS32-NEXT: and $7, $6, $3
+; MIPS32-NEXT: bne $7, $5, $BB15_3
; MIPS32-NEXT: nop
; MIPS32-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1
-; MIPS32-NEXT: and $9, $9, $6
-; MIPS32-NEXT: or $9, $9, $7
-; MIPS32-NEXT: sc $9, 0($3)
-; MIPS32-NEXT: beqz $9, $BB15_1
+; MIPS32-NEXT: xor $7, $6, $7
+; MIPS32-NEXT: or $7, $7, $1
+; MIPS32-NEXT: sc $7, 0($4)
+; MIPS32-NEXT: beqz $7, $BB15_1
; MIPS32-NEXT: nop
; MIPS32-NEXT: $BB15_3:
-; MIPS32-NEXT: srlv $2, $10, $4
-; MIPS32-NEXT: sll $2, $2, 16
-; MIPS32-NEXT: sra $2, $2, 16
-; MIPS32-NEXT: # %bb.4:
-; MIPS32-NEXT: sll $1, $1, 16
-; MIPS32-NEXT: sra $1, $1, 16
-; MIPS32-NEXT: xor $1, $2, $1
+; MIPS32-NEXT: srlv $2, $6, $2
+; MIPS32-NEXT: and $1, $6, $3
+; MIPS32-NEXT: xor $1, $5, $1
; MIPS32-NEXT: sltiu $3, $1, 1
; MIPS32-NEXT: sync
; MIPS32-NEXT: jr $ra
@@ -5938,85 +5569,65 @@ define {i16, i1} @foo(ptr %addr, i16 %l, i16 %r, i16 %new) {
;
; MIPS32O0-LABEL: foo:
; MIPS32O0: # %bb.0:
-; MIPS32O0-NEXT: addiu $sp, $sp, -8
-; MIPS32O0-NEXT: .cfi_def_cfa_offset 8
-; MIPS32O0-NEXT: move $1, $7
-; MIPS32O0-NEXT: move $3, $4
-; MIPS32O0-NEXT: addu $2, $5, $6
-; MIPS32O0-NEXT: sw $2, 0($sp) # 4-byte Folded Spill
-; MIPS32O0-NEXT: sync
-; MIPS32O0-NEXT: addiu $4, $zero, -4
-; MIPS32O0-NEXT: and $4, $3, $4
-; MIPS32O0-NEXT: andi $3, $3, 3
-; MIPS32O0-NEXT: sll $9, $3, 3
+; MIPS32O0-NEXT: addu $1, $5, $6
+; MIPS32O0-NEXT: addiu $2, $zero, -4
+; MIPS32O0-NEXT: and $6, $4, $2
+; MIPS32O0-NEXT: sll $2, $4, 3
; MIPS32O0-NEXT: ori $3, $zero, 65535
-; MIPS32O0-NEXT: sllv $5, $3, $9
-; MIPS32O0-NEXT: nor $7, $zero, $5
-; MIPS32O0-NEXT: andi $2, $2, 65535
-; MIPS32O0-NEXT: sllv $6, $2, $9
+; MIPS32O0-NEXT: sllv $4, $3, $2
; MIPS32O0-NEXT: andi $1, $1, 65535
-; MIPS32O0-NEXT: sllv $8, $1, $9
+; MIPS32O0-NEXT: sllv $1, $1, $2
+; MIPS32O0-NEXT: andi $3, $7, 65535
+; MIPS32O0-NEXT: sllv $7, $3, $2
+; MIPS32O0-NEXT: sync
; MIPS32O0-NEXT: $BB15_1: # =>This Inner Loop Header: Depth=1
-; MIPS32O0-NEXT: ll $2, 0($4)
-; MIPS32O0-NEXT: and $3, $2, $5
-; MIPS32O0-NEXT: bne $3, $6, $BB15_3
+; MIPS32O0-NEXT: ll $3, 0($6)
+; MIPS32O0-NEXT: and $5, $3, $4
+; MIPS32O0-NEXT: bne $5, $1, $BB15_3
; MIPS32O0-NEXT: nop
; MIPS32O0-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1
-; MIPS32O0-NEXT: and $2, $2, $7
-; MIPS32O0-NEXT: or $2, $2, $8
-; MIPS32O0-NEXT: sc $2, 0($4)
-; MIPS32O0-NEXT: beqz $2, $BB15_1
+; MIPS32O0-NEXT: xor $5, $3, $5
+; MIPS32O0-NEXT: or $5, $5, $7
+; MIPS32O0-NEXT: sc $5, 0($6)
+; MIPS32O0-NEXT: beqz $5, $BB15_1
; MIPS32O0-NEXT: nop
; MIPS32O0-NEXT: $BB15_3:
-; MIPS32O0-NEXT: srlv $1, $3, $9
-; MIPS32O0-NEXT: sll $1, $1, 16
-; MIPS32O0-NEXT: sra $1, $1, 16
-; MIPS32O0-NEXT: # %bb.4:
-; MIPS32O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32O0-NEXT: # %bb.5:
-; MIPS32O0-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
-; MIPS32O0-NEXT: lw $1, 0($sp) # 4-byte Folded Reload
-; MIPS32O0-NEXT: sll $1, $1, 16
-; MIPS32O0-NEXT: sra $1, $1, 16
-; MIPS32O0-NEXT: xor $1, $2, $1
-; MIPS32O0-NEXT: sltiu $3, $1, 1
; MIPS32O0-NEXT: sync
-; MIPS32O0-NEXT: addiu $sp, $sp, 8
+; MIPS32O0-NEXT: srlv $2, $3, $2
+; MIPS32O0-NEXT: and $3, $3, $4
+; MIPS32O0-NEXT: xor $1, $1, $3
+; MIPS32O0-NEXT: sltiu $3, $1, 1
; MIPS32O0-NEXT: jr $ra
; MIPS32O0-NEXT: nop
;
; MIPS32R2-LABEL: foo:
; MIPS32R2: # %bb.0:
-; MIPS32R2-NEXT: addu $1, $5, $6
+; MIPS32R2-NEXT: andi $1, $7, 65535
+; MIPS32R2-NEXT: sll $2, $4, 3
+; MIPS32R2-NEXT: ori $3, $zero, 65535
+; MIPS32R2-NEXT: addiu $7, $zero, -4
+; MIPS32R2-NEXT: and $4, $4, $7
+; MIPS32R2-NEXT: sllv $3, $3, $2
+; MIPS32R2-NEXT: sllv $1, $1, $2
+; MIPS32R2-NEXT: addu $5, $5, $6
+; MIPS32R2-NEXT: andi $5, $5, 65535
+; MIPS32R2-NEXT: sllv $5, $5, $2
; MIPS32R2-NEXT: sync
-; MIPS32R2-NEXT: addiu $2, $zero, -4
-; MIPS32R2-NEXT: and $3, $4, $2
-; MIPS32R2-NEXT: andi $2, $4, 3
-; MIPS32R2-NEXT: sll $4, $2, 3
-; MIPS32R2-NEXT: ori $2, $zero, 65535
-; MIPS32R2-NEXT: sllv $5, $2, $4
-; MIPS32R2-NEXT: nor $6, $zero, $5
-; MIPS32R2-NEXT: andi $2, $1, 65535
-; MIPS32R2-NEXT: sllv $8, $2, $4
-; MIPS32R2-NEXT: andi $2, $7, 65535
-; MIPS32R2-NEXT: sllv $7, $2, $4
; MIPS32R2-NEXT: $BB15_1: # =>This Inner Loop Header: Depth=1
-; MIPS32R2-NEXT: ll $9, 0($3)
-; MIPS32R2-NEXT: and $10, $9, $5
-; MIPS32R2-NEXT: bne $10, $8, $BB15_3
+; MIPS32R2-NEXT: ll $6, 0($4)
+; MIPS32R2-NEXT: and $7, $6, $3
+; MIPS32R2-NEXT: bne $7, $5, $BB15_3
; MIPS32R2-NEXT: nop
; MIPS32R2-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1
-; MIPS32R2-NEXT: and $9, $9, $6
-; MIPS32R2-NEXT: or $9, $9, $7
-; MIPS32R2-NEXT: sc $9, 0($3)
-; MIPS32R2-NEXT: beqz $9, $BB15_1
+; MIPS32R2-NEXT: xor $7, $6, $7
+; MIPS32R2-NEXT: or $7, $7, $1
+; MIPS32R2-NEXT: sc $7, 0($4)
+; MIPS32R2-NEXT: beqz $7, $BB15_1
; MIPS32R2-NEXT: nop
; MIPS32R2-NEXT: $BB15_3:
-; MIPS32R2-NEXT: srlv $2, $10, $4
-; MIPS32R2-NEXT: seh $2, $2
-; MIPS32R2-NEXT: # %bb.4:
-; MIPS32R2-NEXT: seh $1, $1
-; MIPS32R2-NEXT: xor $1, $2, $1
+; MIPS32R2-NEXT: srlv $2, $6, $2
+; MIPS32R2-NEXT: and $1, $6, $3
+; MIPS32R2-NEXT: xor $1, $5, $1
; MIPS32R2-NEXT: sltiu $3, $1, 1
; MIPS32R2-NEXT: sync
; MIPS32R2-NEXT: jr $ra
@@ -6024,119 +5635,97 @@ define {i16, i1} @foo(ptr %addr, i16 %l, i16 %r, i16 %new) {
;
; MIPS32R6-LABEL: foo:
; MIPS32R6: # %bb.0:
-; MIPS32R6-NEXT: addu $1, $5, $6
+; MIPS32R6-NEXT: andi $1, $7, 65535
+; MIPS32R6-NEXT: sll $2, $4, 3
+; MIPS32R6-NEXT: ori $3, $zero, 65535
+; MIPS32R6-NEXT: addiu $7, $zero, -4
+; MIPS32R6-NEXT: and $4, $4, $7
+; MIPS32R6-NEXT: sllv $3, $3, $2
+; MIPS32R6-NEXT: sllv $1, $1, $2
+; MIPS32R6-NEXT: addu $5, $5, $6
+; MIPS32R6-NEXT: andi $5, $5, 65535
+; MIPS32R6-NEXT: sllv $5, $5, $2
; MIPS32R6-NEXT: sync
-; MIPS32R6-NEXT: addiu $2, $zero, -4
-; MIPS32R6-NEXT: and $3, $4, $2
-; MIPS32R6-NEXT: andi $2, $4, 3
-; MIPS32R6-NEXT: sll $4, $2, 3
-; MIPS32R6-NEXT: ori $2, $zero, 65535
-; MIPS32R6-NEXT: sllv $5, $2, $4
-; MIPS32R6-NEXT: nor $6, $zero, $5
-; MIPS32R6-NEXT: andi $2, $1, 65535
-; MIPS32R6-NEXT: sllv $8, $2, $4
-; MIPS32R6-NEXT: andi $2, $7, 65535
-; MIPS32R6-NEXT: sllv $7, $2, $4
; MIPS32R6-NEXT: $BB15_1: # =>This Inner Loop Header: Depth=1
-; MIPS32R6-NEXT: ll $9, 0($3)
-; MIPS32R6-NEXT: and $10, $9, $5
-; MIPS32R6-NEXT: bnec $10, $8, $BB15_3
+; MIPS32R6-NEXT: ll $6, 0($4)
+; MIPS32R6-NEXT: and $7, $6, $3
+; MIPS32R6-NEXT: bnec $7, $5, $BB15_3
; MIPS32R6-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1
-; MIPS32R6-NEXT: and $9, $9, $6
-; MIPS32R6-NEXT: or $9, $9, $7
-; MIPS32R6-NEXT: sc $9, 0($3)
-; MIPS32R6-NEXT: beqzc $9, $BB15_1
+; MIPS32R6-NEXT: xor $7, $6, $7
+; MIPS32R6-NEXT: or $7, $7, $1
+; MIPS32R6-NEXT: sc $7, 0($4)
+; MIPS32R6-NEXT: beqzc $7, $BB15_1
; MIPS32R6-NEXT: $BB15_3:
-; MIPS32R6-NEXT: srlv $2, $10, $4
-; MIPS32R6-NEXT: seh $2, $2
-; MIPS32R6-NEXT: # %bb.4:
-; MIPS32R6-NEXT: seh $1, $1
-; MIPS32R6-NEXT: xor $1, $2, $1
+; MIPS32R6-NEXT: srlv $2, $6, $2
+; MIPS32R6-NEXT: and $1, $6, $3
+; MIPS32R6-NEXT: xor $1, $5, $1
; MIPS32R6-NEXT: sltiu $3, $1, 1
; MIPS32R6-NEXT: sync
; MIPS32R6-NEXT: jrc $ra
;
; MIPS32R6O0-LABEL: foo:
; MIPS32R6O0: # %bb.0:
-; MIPS32R6O0-NEXT: addiu $sp, $sp, -8
-; MIPS32R6O0-NEXT: .cfi_def_cfa_offset 8
-; MIPS32R6O0-NEXT: move $1, $7
-; MIPS32R6O0-NEXT: move $3, $4
-; MIPS32R6O0-NEXT: addu $2, $5, $6
-; MIPS32R6O0-NEXT: sw $2, 0($sp) # 4-byte Folded Spill
-; MIPS32R6O0-NEXT: sync
-; MIPS32R6O0-NEXT: addiu $4, $zero, -4
-; MIPS32R6O0-NEXT: and $4, $3, $4
-; MIPS32R6O0-NEXT: andi $3, $3, 3
-; MIPS32R6O0-NEXT: sll $9, $3, 3
+; MIPS32R6O0-NEXT: addu $1, $5, $6
+; MIPS32R6O0-NEXT: addiu $2, $zero, -4
+; MIPS32R6O0-NEXT: and $6, $4, $2
+; MIPS32R6O0-NEXT: sll $2, $4, 3
; MIPS32R6O0-NEXT: ori $3, $zero, 65535
-; MIPS32R6O0-NEXT: sllv $5, $3, $9
-; MIPS32R6O0-NEXT: nor $7, $zero, $5
-; MIPS32R6O0-NEXT: andi $2, $2, 65535
-; MIPS32R6O0-NEXT: sllv $6, $2, $9
+; MIPS32R6O0-NEXT: sllv $4, $3, $2
; MIPS32R6O0-NEXT: andi $1, $1, 65535
-; MIPS32R6O0-NEXT: sllv $8, $1, $9
+; MIPS32R6O0-NEXT: sllv $1, $1, $2
+; MIPS32R6O0-NEXT: andi $3, $7, 65535
+; MIPS32R6O0-NEXT: sllv $7, $3, $2
+; MIPS32R6O0-NEXT: sync
; MIPS32R6O0-NEXT: $BB15_1: # =>This Inner Loop Header: Depth=1
-; MIPS32R6O0-NEXT: ll $2, 0($4)
-; MIPS32R6O0-NEXT: and $3, $2, $5
-; MIPS32R6O0-NEXT: bnec $3, $6, $BB15_3
+; MIPS32R6O0-NEXT: ll $3, 0($6)
+; MIPS32R6O0-NEXT: and $5, $3, $4
+; MIPS32R6O0-NEXT: bnec $5, $1, $BB15_3
; MIPS32R6O0-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1
-; MIPS32R6O0-NEXT: and $2, $2, $7
-; MIPS32R6O0-NEXT: or $2, $2, $8
-; MIPS32R6O0-NEXT: sc $2, 0($4)
-; MIPS32R6O0-NEXT: beqzc $2, $BB15_1
+; MIPS32R6O0-NEXT: xor $5, $3, $5
+; MIPS32R6O0-NEXT: or $5, $5, $7
+; MIPS32R6O0-NEXT: sc $5, 0($6)
+; MIPS32R6O0-NEXT: beqzc $5, $BB15_1
; MIPS32R6O0-NEXT: $BB15_3:
-; MIPS32R6O0-NEXT: srlv $1, $3, $9
-; MIPS32R6O0-NEXT: seh $1, $1
-; MIPS32R6O0-NEXT: # %bb.4:
-; MIPS32R6O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill
-; MIPS32R6O0-NEXT: # %bb.5:
-; MIPS32R6O0-NEXT: lw $2, 4($sp) # 4-byte Folded Reload
-; MIPS32R6O0-NEXT: lw $1, 0($sp) # 4-byte Folded Reload
-; MIPS32R6O0-NEXT: seh $1, $1
-; MIPS32R6O0-NEXT: xor $1, $2, $1
-; MIPS32R6O0-NEXT: sltiu $3, $1, 1
; MIPS32R6O0-NEXT: sync
-; MIPS32R6O0-NEXT: addiu $sp, $sp, 8
+; MIPS32R6O0-NEXT: srlv $2, $3, $2
+; MIPS32R6O0-NEXT: and $3, $3, $4
+; MIPS32R6O0-NEXT: xor $1, $1, $3
+; MIPS32R6O0-NEXT: sltiu $3, $1, 1
; MIPS32R6O0-NEXT: jrc $ra
;
; MIPS4-LABEL: foo:
; MIPS4: # %bb.0:
-; MIPS4-NEXT: sll $1, $6, 0
-; MIPS4-NEXT: sll $2, $5, 0
-; MIPS4-NEXT: addu $1, $2, $1
+; MIPS4-NEXT: sll $1, $7, 0
+; MIPS4-NEXT: andi $1, $1, 65535
+; MIPS4-NEXT: sll $2, $4, 0
+; MIPS4-NEXT: andi $2, $2, 3
+; MIPS4-NEXT: sll $2, $2, 3
+; MIPS4-NEXT: ori $3, $zero, 65535
+; MIPS4-NEXT: daddiu $7, $zero, -4
+; MIPS4-NEXT: and $4, $4, $7
+; MIPS4-NEXT: sllv $3, $3, $2
+; MIPS4-NEXT: sllv $1, $1, $2
+; MIPS4-NEXT: sll $6, $6, 0
+; MIPS4-NEXT: sll $5, $5, 0
+; MIPS4-NEXT: addu $5, $5, $6
+; MIPS4-NEXT: andi $5, $5, 65535
+; MIPS4-NEXT: sllv $5, $5, $2
; MIPS4-NEXT: sync
-; MIPS4-NEXT: sll $2, $7, 0
-; MIPS4-NEXT: daddiu $3, $zero, -4
-; MIPS4-NEXT: and $3, $4, $3
-; MIPS4-NEXT: andi $4, $4, 3
-; MIPS4-NEXT: sll $4, $4, 3
-; MIPS4-NEXT: ori $5, $zero, 65535
-; MIPS4-NEXT: sllv $5, $5, $4
-; MIPS4-NEXT: nor $6, $zero, $5
-; MIPS4-NEXT: andi $7, $1, 65535
-; MIPS4-NEXT: sllv $7, $7, $4
-; MIPS4-NEXT: andi $2, $2, 65535
-; MIPS4-NEXT: sllv $8, $2, $4
; MIPS4-NEXT: .LBB15_1: # =>This Inner Loop Header: Depth=1
-; MIPS4-NEXT: ll $9, 0($3)
-; MIPS4-NEXT: and $10, $9, $5
-; MIPS4-NEXT: bne $10, $7, .LBB15_3
+; MIPS4-NEXT: ll $6, 0($4)
+; MIPS4-NEXT: and $7, $6, $3
+; MIPS4-NEXT: bne $7, $5, .LBB15_3
; MIPS4-NEXT: nop
; MIPS4-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1
-; MIPS4-NEXT: and $9, $9, $6
-; MIPS4-NEXT: or $9, $9, $8
-; MIPS4-NEXT: sc $9, 0($3)
-; MIPS4-NEXT: beqz $9, .LBB15_1
+; MIPS4-NEXT: xor $7, $6, $7
+; MIPS4-NEXT: or $7, $7, $1
+; MIPS4-NEXT: sc $7, 0($4)
+; MIPS4-NEXT: beqz $7, .LBB15_1
; MIPS4-NEXT: nop
; MIPS4-NEXT: .LBB15_3:
-; MIPS4-NEXT: srlv $2, $10, $4
-; MIPS4-NEXT: sll $2, $2, 16
-; MIPS4-NEXT: sra $2, $2, 16
-; MIPS4-NEXT: # %bb.4:
-; MIPS4-NEXT: sll $1, $1, 16
-; MIPS4-NEXT: sra $1, $1, 16
-; MIPS4-NEXT: xor $1, $2, $1
+; MIPS4-NEXT: srlv $2, $6, $2
+; MIPS4-NEXT: and $1, $6, $3
+; MIPS4-NEXT: xor $1, $5, $1
; MIPS4-NEXT: sltiu $3, $1, 1
; MIPS4-NEXT: sync
; MIPS4-NEXT: jr $ra
@@ -6144,41 +5733,37 @@ define {i16, i1} @foo(ptr %addr, i16 %l, i16 %r, i16 %new) {
;
; MIPS64-LABEL: foo:
; MIPS64: # %bb.0:
-; MIPS64-NEXT: sll $1, $6, 0
-; MIPS64-NEXT: sll $2, $5, 0
-; MIPS64-NEXT: addu $1, $2, $1
+; MIPS64-NEXT: sll $1, $7, 0
+; MIPS64-NEXT: andi $1, $1, 65535
+; MIPS64-NEXT: sll $2, $4, 0
+; MIPS64-NEXT: andi $2, $2, 3
+; MIPS64-NEXT: sll $2, $2, 3
+; MIPS64-NEXT: ori $3, $zero, 65535
+; MIPS64-NEXT: daddiu $7, $zero, -4
+; MIPS64-NEXT: and $4, $4, $7
+; MIPS64-NEXT: sllv $3, $3, $2
+; MIPS64-NEXT: sllv $1, $1, $2
+; MIPS64-NEXT: sll $6, $6, 0
+; MIPS64-NEXT: sll $5, $5, 0
+; MIPS64-NEXT: addu $5, $5, $6
+; MIPS64-NEXT: andi $5, $5, 65535
+; MIPS64-NEXT: sllv $5, $5, $2
; MIPS64-NEXT: sync
-; MIPS64-NEXT: sll $2, $7, 0
-; MIPS64-NEXT: daddiu $3, $zero, -4
-; MIPS64-NEXT: and $3, $4, $3
-; MIPS64-NEXT: andi $4, $4, 3
-; MIPS64-NEXT: sll $4, $4, 3
-; MIPS64-NEXT: ori $5, $zero, 65535
-; MIPS64-NEXT: sllv $5, $5, $4
-; MIPS64-NEXT: nor $6, $zero, $5
-; MIPS64-NEXT: andi $7, $1, 65535
-; MIPS64-NEXT: sllv $7, $7, $4
-; MIPS64-NEXT: andi $2, $2, 65535
-; MIPS64-NEXT: sllv $8, $2, $4
; MIPS64-NEXT: .LBB15_1: # =>This Inner Loop Header: Depth=1
-; MIPS64-NEXT: ll $9, 0($3)
-; MIPS64-NEXT: and $10, $9, $5
-; MIPS64-NEXT: bne $10, $7, .LBB15_3
+; MIPS64-NEXT: ll $6, 0($4)
+; MIPS64-NEXT: and $7, $6, $3
+; MIPS64-NEXT: bne $7, $5, .LBB15_3
; MIPS64-NEXT: nop
; MIPS64-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1
-; MIPS64-NEXT: and $9, $9, $6
-; MIPS64-NEXT: or $9, $9, $8
-; MIPS64-NEXT: sc $9, 0($3)
-; MIPS64-NEXT: beqz $9, .LBB15_1
+; MIPS64-NEXT: xor $7, $6, $7
+; MIPS64-NEXT: or $7, $7, $1
+; MIPS64-NEXT: sc $7, 0($4)
+; MIPS64-NEXT: beqz $7, .LBB15_1
; MIPS64-NEXT: nop
; MIPS64-NEXT: .LBB15_3:
-; MIPS64-NEXT: srlv $2, $10, $4
-; MIPS64-NEXT: sll $2, $2, 16
-; MIPS64-NEXT: sra $2, $2, 16
-; MIPS64-NEXT: # %bb.4:
-; MIPS64-NEXT: sll $1, $1, 16
-; MIPS64-NEXT: sra $1, $1, 16
-; MIPS64-NEXT: xor $1, $2, $1
+; MIPS64-NEXT: srlv $2, $6, $2
+; MIPS64-NEXT: and $1, $6, $3
+; MIPS64-NEXT: xor $1, $5, $1
; MIPS64-NEXT: sltiu $3, $1, 1
; MIPS64-NEXT: sync
; MIPS64-NEXT: jr $ra
@@ -6186,39 +5771,37 @@ define {i16, i1} @foo(ptr %addr, i16 %l, i16 %r, i16 %new) {
;
; MIPS64R2-LABEL: foo:
; MIPS64R2: # %bb.0:
-; MIPS64R2-NEXT: sll $1, $6, 0
-; MIPS64R2-NEXT: sll $2, $5, 0
-; MIPS64R2-NEXT: addu $1, $2, $1
+; MIPS64R2-NEXT: sll $1, $7, 0
+; MIPS64R2-NEXT: andi $1, $1, 65535
+; MIPS64R2-NEXT: sll $2, $4, 0
+; MIPS64R2-NEXT: andi $2, $2, 3
+; MIPS64R2-NEXT: sll $2, $2, 3
+; MIPS64R2-NEXT: ori $3, $zero, 65535
+; MIPS64R2-NEXT: daddiu $7, $zero, -4
+; MIPS64R2-NEXT: and $4, $4, $7
+; MIPS64R2-NEXT: sllv $3, $3, $2
+; MIPS64R2-NEXT: sllv $1, $1, $2
+; MIPS64R2-NEXT: sll $6, $6, 0
+; MIPS64R2-NEXT: sll $5, $5, 0
+; MIPS64R2-NEXT: addu $5, $5, $6
+; MIPS64R2-NEXT: andi $5, $5, 65535
+; MIPS64R2-NEXT: sllv $5, $5, $2
; MIPS64R2-NEXT: sync
-; MIPS64R2-NEXT: sll $2, $7, 0
-; MIPS64R2-NEXT: daddiu $3, $zero, -4
-; MIPS64R2-NEXT: and $3, $4, $3
-; MIPS64R2-NEXT: andi $4, $4, 3
-; MIPS64R2-NEXT: sll $4, $4, 3
-; MIPS64R2-NEXT: ori $5, $zero, 65535
-; MIPS64R2-NEXT: sllv $5, $5, $4
-; MIPS64R2-NEXT: nor $6, $zero, $5
-; MIPS64R2-NEXT: andi $7, $1, 65535
-; MIPS64R2-NEXT: sllv $7, $7, $4
-; MIPS64R2-NEXT: andi $2, $2, 65535
-; MIPS64R2-NEXT: sllv $8, $2, $4
; MIPS64R2-NEXT: .LBB15_1: # =>This Inner Loop Header: Depth=1
-; MIPS64R2-NEXT: ll $9, 0($3)
-; MIPS64R2-NEXT: and $10, $9, $5
-; MIPS64R2-NEXT: bne $10, $7, .LBB15_3
+; MIPS64R2-NEXT: ll $6, 0($4)
+; MIPS64R2-NEXT: and $7, $6, $3
+; MIPS64R2-NEXT: bne $7, $5, .LBB15_3
; MIPS64R2-NEXT: nop
; MIPS64R2-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1
-; MIPS64R2-NEXT: and $9, $9, $6
-; MIPS64R2-NEXT: or $9, $9, $8
-; MIPS64R2-NEXT: sc $9, 0($3)
-; MIPS64R2-NEXT: beqz $9, .LBB15_1
+; MIPS64R2-NEXT: xor $7, $6, $7
+; MIPS64R2-NEXT: or $7, $7, $1
+; MIPS64R2-NEXT: sc $7, 0($4)
+; MIPS64R2-NEXT: beqz $7, .LBB15_1
; MIPS64R2-NEXT: nop
; MIPS64R2-NEXT: .LBB15_3:
-; MIPS64R2-NEXT: srlv $2, $10, $4
-; MIPS64R2-NEXT: seh $2, $2
-; MIPS64R2-NEXT: # %bb.4:
-; MIPS64R2-NEXT: seh $1, $1
-; MIPS64R2-NEXT: xor $1, $2, $1
+; MIPS64R2-NEXT: srlv $2, $6, $2
+; MIPS64R2-NEXT: and $1, $6, $3
+; MIPS64R2-NEXT: xor $1, $5, $1
; MIPS64R2-NEXT: sltiu $3, $1, 1
; MIPS64R2-NEXT: sync
; MIPS64R2-NEXT: jr $ra
@@ -6226,160 +5809,139 @@ define {i16, i1} @foo(ptr %addr, i16 %l, i16 %r, i16 %new) {
;
; MIPS64R6-LABEL: foo:
; MIPS64R6: # %bb.0:
-; MIPS64R6-NEXT: sll $1, $6, 0
-; MIPS64R6-NEXT: sll $2, $5, 0
-; MIPS64R6-NEXT: addu $1, $2, $1
+; MIPS64R6-NEXT: sll $1, $7, 0
+; MIPS64R6-NEXT: andi $1, $1, 65535
+; MIPS64R6-NEXT: sll $2, $4, 0
+; MIPS64R6-NEXT: andi $2, $2, 3
+; MIPS64R6-NEXT: sll $2, $2, 3
+; MIPS64R6-NEXT: ori $3, $zero, 65535
+; MIPS64R6-NEXT: daddiu $7, $zero, -4
+; MIPS64R6-NEXT: and $4, $4, $7
+; MIPS64R6-NEXT: sllv $3, $3, $2
+; MIPS64R6-NEXT: sllv $1, $1, $2
+; MIPS64R6-NEXT: sll $6, $6, 0
+; MIPS64R6-NEXT: sll $5, $5, 0
+; MIPS64R6-NEXT: addu $5, $5, $6
+; MIPS64R6-NEXT: andi $5, $5, 65535
+; MIPS64R6-NEXT: sllv $5, $5, $2
; MIPS64R6-NEXT: sync
-; MIPS64R6-NEXT: sll $2, $7, 0
-; MIPS64R6-NEXT: daddiu $3, $zero, -4
-; MIPS64R6-NEXT: and $3, $4, $3
-; MIPS64R6-NEXT: andi $4, $4, 3
-; MIPS64R6-NEXT: sll $4, $4, 3
-; MIPS64R6-NEXT: ori $5, $zero, 65535
-; MIPS64R6-NEXT: sllv $5, $5, $4
-; MIPS64R6-NEXT: nor $6, $zero, $5
-; MIPS64R6-NEXT: andi $7, $1, 65535
-; MIPS64R6-NEXT: sllv $7, $7, $4
-; MIPS64R6-NEXT: andi $2, $2, 65535
-; MIPS64R6-NEXT: sllv $8, $2, $4
; MIPS64R6-NEXT: .LBB15_1: # =>This Inner Loop Header: Depth=1
-; MIPS64R6-NEXT: ll $9, 0($3)
-; MIPS64R6-NEXT: and $10, $9, $5
-; MIPS64R6-NEXT: bnec $10, $7, .LBB15_3
+; MIPS64R6-NEXT: ll $6, 0($4)
+; MIPS64R6-NEXT: and $7, $6, $3
+; MIPS64R6-NEXT: bnec $7, $5, .LBB15_3
; MIPS64R6-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1
-; MIPS64R6-NEXT: and $9, $9, $6
-; MIPS64R6-NEXT: or $9, $9, $8
-; MIPS64R6-NEXT: sc $9, 0($3)
-; MIPS64R6-NEXT: beqzc $9, .LBB15_1
+; MIPS64R6-NEXT: xor $7, $6, $7
+; MIPS64R6-NEXT: or $7, $7, $1
+; MIPS64R6-NEXT: sc $7, 0($4)
+; MIPS64R6-NEXT: beqzc $7, .LBB15_1
; MIPS64R6-NEXT: .LBB15_3:
-; MIPS64R6-NEXT: srlv $2, $10, $4
-; MIPS64R6-NEXT: seh $2, $2
-; MIPS64R6-NEXT: # %bb.4:
-; MIPS64R6-NEXT: seh $1, $1
-; MIPS64R6-NEXT: xor $1, $2, $1
+; MIPS64R6-NEXT: srlv $2, $6, $2
+; MIPS64R6-NEXT: and $1, $6, $3
+; MIPS64R6-NEXT: xor $1, $5, $1
; MIPS64R6-NEXT: sltiu $3, $1, 1
; MIPS64R6-NEXT: sync
; MIPS64R6-NEXT: jrc $ra
;
; MIPS64R6O0-LABEL: foo:
; MIPS64R6O0: # %bb.0:
-; MIPS64R6O0-NEXT: daddiu $sp, $sp, -16
-; MIPS64R6O0-NEXT: .cfi_def_cfa_offset 16
-; MIPS64R6O0-NEXT: move $3, $4
-; MIPS64R6O0-NEXT: move $1, $7
+; MIPS64R6O0-NEXT: move $1, $6
+; MIPS64R6O0-NEXT: sll $2, $1, 0
+; MIPS64R6O0-NEXT: move $1, $5
; MIPS64R6O0-NEXT: sll $1, $1, 0
-; MIPS64R6O0-NEXT: move $2, $6
-; MIPS64R6O0-NEXT: sll $4, $2, 0
-; MIPS64R6O0-NEXT: move $2, $5
+; MIPS64R6O0-NEXT: move $3, $7
+; MIPS64R6O0-NEXT: sll $3, $3, 0
+; MIPS64R6O0-NEXT: addu $1, $1, $2
+; MIPS64R6O0-NEXT: daddiu $2, $zero, -4
+; MIPS64R6O0-NEXT: and $6, $4, $2
+; MIPS64R6O0-NEXT: move $2, $4
; MIPS64R6O0-NEXT: sll $2, $2, 0
-; MIPS64R6O0-NEXT: addu $2, $2, $4
-; MIPS64R6O0-NEXT: sw $2, 8($sp) # 4-byte Folded Spill
-; MIPS64R6O0-NEXT: sync
-; MIPS64R6O0-NEXT: daddiu $4, $zero, -4
-; MIPS64R6O0-NEXT: and $4, $3, $4
-; MIPS64R6O0-NEXT: andi $3, $3, 3
-; MIPS64R6O0-NEXT: xori $3, $3, 2
-; MIPS64R6O0-NEXT: sll $9, $3, 3
-; MIPS64R6O0-NEXT: ori $3, $zero, 65535
-; MIPS64R6O0-NEXT: sllv $5, $3, $9
-; MIPS64R6O0-NEXT: nor $7, $zero, $5
-; MIPS64R6O0-NEXT: andi $2, $2, 65535
-; MIPS64R6O0-NEXT: sllv $6, $2, $9
+; MIPS64R6O0-NEXT: andi $2, $2, 3
+; MIPS64R6O0-NEXT: xori $2, $2, 2
+; MIPS64R6O0-NEXT: sll $2, $2, 3
+; MIPS64R6O0-NEXT: ori $4, $zero, 65535
+; MIPS64R6O0-NEXT: sllv $4, $4, $2
; MIPS64R6O0-NEXT: andi $1, $1, 65535
-; MIPS64R6O0-NEXT: sllv $8, $1, $9
+; MIPS64R6O0-NEXT: sllv $1, $1, $2
+; MIPS64R6O0-NEXT: andi $3, $3, 65535
+; MIPS64R6O0-NEXT: sllv $7, $3, $2
+; MIPS64R6O0-NEXT: sync
; MIPS64R6O0-NEXT: .LBB15_1: # =>This Inner Loop Header: Depth=1
-; MIPS64R6O0-NEXT: ll $2, 0($4)
-; MIPS64R6O0-NEXT: and $3, $2, $5
-; MIPS64R6O0-NEXT: bnec $3, $6, .LBB15_3
+; MIPS64R6O0-NEXT: ll $3, 0($6)
+; MIPS64R6O0-NEXT: and $5, $3, $4
+; MIPS64R6O0-NEXT: bnec $5, $1, .LBB15_3
; MIPS64R6O0-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1
-; MIPS64R6O0-NEXT: and $2, $2, $7
-; MIPS64R6O0-NEXT: or $2, $2, $8
-; MIPS64R6O0-NEXT: sc $2, 0($4)
-; MIPS64R6O0-NEXT: beqzc $2, .LBB15_1
+; MIPS64R6O0-NEXT: xor $5, $3, $5
+; MIPS64R6O0-NEXT: or $5, $5, $7
+; MIPS64R6O0-NEXT: sc $5, 0($6)
+; MIPS64R6O0-NEXT: beqzc $5, .LBB15_1
; MIPS64R6O0-NEXT: .LBB15_3:
-; MIPS64R6O0-NEXT: srlv $1, $3, $9
-; MIPS64R6O0-NEXT: seh $1, $1
-; MIPS64R6O0-NEXT: # %bb.4:
-; MIPS64R6O0-NEXT: sw $1, 12($sp) # 4-byte Folded Spill
-; MIPS64R6O0-NEXT: # %bb.5:
-; MIPS64R6O0-NEXT: lw $2, 12($sp) # 4-byte Folded Reload
-; MIPS64R6O0-NEXT: lw $1, 8($sp) # 4-byte Folded Reload
-; MIPS64R6O0-NEXT: seh $1, $1
-; MIPS64R6O0-NEXT: xor $1, $2, $1
-; MIPS64R6O0-NEXT: sltiu $3, $1, 1
; MIPS64R6O0-NEXT: sync
-; MIPS64R6O0-NEXT: daddiu $sp, $sp, 16
+; MIPS64R6O0-NEXT: srlv $2, $3, $2
+; MIPS64R6O0-NEXT: and $3, $3, $4
+; MIPS64R6O0-NEXT: xor $1, $1, $3
+; MIPS64R6O0-NEXT: sltiu $3, $1, 1
; MIPS64R6O0-NEXT: jrc $ra
;
; MM32-LABEL: foo:
; MM32: # %bb.0:
-; MM32-NEXT: addu16 $3, $5, $6
+; MM32-NEXT: andi16 $2, $7, 65535
+; MM32-NEXT: sll16 $3, $4, 3
+; MM32-NEXT: andi $1, $3, 24
+; MM32-NEXT: ori $3, $zero, 65535
+; MM32-NEXT: addiu $7, $zero, -4
+; MM32-NEXT: and16 $7, $4
+; MM32-NEXT: sllv $3, $3, $1
+; MM32-NEXT: sllv $2, $2, $1
+; MM32-NEXT: addu16 $4, $5, $6
+; MM32-NEXT: andi16 $4, $4, 65535
+; MM32-NEXT: sllv $4, $4, $1
; MM32-NEXT: sync
-; MM32-NEXT: addiu $1, $zero, -4
-; MM32-NEXT: and $1, $4, $1
-; MM32-NEXT: andi $2, $4, 3
-; MM32-NEXT: sll $4, $2, 3
-; MM32-NEXT: ori $2, $zero, 65535
-; MM32-NEXT: sllv $5, $2, $4
-; MM32-NEXT: nor $6, $zero, $5
-; MM32-NEXT: andi $2, $3, 65535
-; MM32-NEXT: sllv $8, $2, $4
-; MM32-NEXT: andi $2, $7, 65535
-; MM32-NEXT: sllv $7, $2, $4
; MM32-NEXT: $BB15_1: # =>This Inner Loop Header: Depth=1
-; MM32-NEXT: ll $9, 0($1)
-; MM32-NEXT: and $10, $9, $5
-; MM32-NEXT: bne $10, $8, $BB15_3
+; MM32-NEXT: ll $5, 0($7)
+; MM32-NEXT: and $6, $5, $3
+; MM32-NEXT: bne $6, $4, $BB15_3
; MM32-NEXT: nop
; MM32-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1
-; MM32-NEXT: and $9, $9, $6
-; MM32-NEXT: or $9, $9, $7
-; MM32-NEXT: sc $9, 0($1)
-; MM32-NEXT: beqzc $9, $BB15_1
+; MM32-NEXT: xor16 $6, $5
+; MM32-NEXT: or $6, $6, $2
+; MM32-NEXT: sc $6, 0($7)
+; MM32-NEXT: beqzc $6, $BB15_1
; MM32-NEXT: $BB15_3:
-; MM32-NEXT: srlv $2, $10, $4
-; MM32-NEXT: seh $2, $2
-; MM32-NEXT: # %bb.4:
-; MM32-NEXT: seh $1, $3
-; MM32-NEXT: xor $1, $2, $1
+; MM32-NEXT: srlv $2, $5, $1
+; MM32-NEXT: and16 $3, $5
+; MM32-NEXT: xor $1, $4, $3
; MM32-NEXT: sltiu $3, $1, 1
; MM32-NEXT: sync
; MM32-NEXT: jrc $ra
;
; O1-LABEL: foo:
; O1: # %bb.0:
-; O1-NEXT: addu $1, $5, $6
+; O1-NEXT: andi $1, $7, 65535
+; O1-NEXT: sll $2, $4, 3
+; O1-NEXT: ori $3, $zero, 65535
+; O1-NEXT: addiu $7, $zero, -4
+; O1-NEXT: and $4, $4, $7
+; O1-NEXT: sllv $3, $3, $2
+; O1-NEXT: sllv $1, $1, $2
+; O1-NEXT: addu $5, $5, $6
+; O1-NEXT: andi $5, $5, 65535
+; O1-NEXT: sllv $5, $5, $2
; O1-NEXT: sync
-; O1-NEXT: addiu $2, $zero, -4
-; O1-NEXT: and $3, $4, $2
-; O1-NEXT: andi $2, $4, 3
-; O1-NEXT: sll $4, $2, 3
-; O1-NEXT: ori $2, $zero, 65535
-; O1-NEXT: sllv $5, $2, $4
-; O1-NEXT: nor $6, $zero, $5
-; O1-NEXT: andi $2, $1, 65535
-; O1-NEXT: sllv $8, $2, $4
-; O1-NEXT: andi $2, $7, 65535
-; O1-NEXT: sllv $7, $2, $4
; O1-NEXT: $BB15_1: # =>This Inner Loop Header: Depth=1
-; O1-NEXT: ll $9, 0($3)
-; O1-NEXT: and $10, $9, $5
-; O1-NEXT: bne $10, $8, $BB15_3
+; O1-NEXT: ll $6, 0($4)
+; O1-NEXT: and $7, $6, $3
+; O1-NEXT: bne $7, $5, $BB15_3
; O1-NEXT: nop
; O1-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1
-; O1-NEXT: and $9, $9, $6
-; O1-NEXT: or $9, $9, $7
-; O1-NEXT: sc $9, 0($3)
-; O1-NEXT: beqz $9, $BB15_1
+; O1-NEXT: xor $7, $6, $7
+; O1-NEXT: or $7, $7, $1
+; O1-NEXT: sc $7, 0($4)
+; O1-NEXT: beqz $7, $BB15_1
; O1-NEXT: nop
; O1-NEXT: $BB15_3:
-; O1-NEXT: srlv $2, $10, $4
-; O1-NEXT: sll $2, $2, 16
-; O1-NEXT: sra $2, $2, 16
-; O1-NEXT: # %bb.4:
-; O1-NEXT: sll $1, $1, 16
-; O1-NEXT: sra $1, $1, 16
-; O1-NEXT: xor $1, $2, $1
+; O1-NEXT: srlv $2, $6, $2
+; O1-NEXT: and $1, $6, $3
+; O1-NEXT: xor $1, $5, $1
; O1-NEXT: sltiu $3, $1, 1
; O1-NEXT: sync
; O1-NEXT: jr $ra
@@ -6387,38 +5949,32 @@ define {i16, i1} @foo(ptr %addr, i16 %l, i16 %r, i16 %new) {
;
; O2-LABEL: foo:
; O2: # %bb.0:
-; O2-NEXT: addu $1, $5, $6
+; O2-NEXT: andi $1, $7, 65535
+; O2-NEXT: sll $2, $4, 3
+; O2-NEXT: ori $3, $zero, 65535
+; O2-NEXT: addiu $7, $zero, -4
+; O2-NEXT: and $4, $4, $7
+; O2-NEXT: sllv $3, $3, $2
+; O2-NEXT: sllv $1, $1, $2
+; O2-NEXT: addu $5, $5, $6
+; O2-NEXT: andi $5, $5, 65535
+; O2-NEXT: sllv $5, $5, $2
; O2-NEXT: sync
-; O2-NEXT: addiu $2, $zero, -4
-; O2-NEXT: and $3, $4, $2
-; O2-NEXT: andi $2, $4, 3
-; O2-NEXT: sll $4, $2, 3
-; O2-NEXT: ori $2, $zero, 65535
-; O2-NEXT: sllv $5, $2, $4
-; O2-NEXT: nor $6, $zero, $5
-; O2-NEXT: andi $2, $1, 65535
-; O2-NEXT: sllv $8, $2, $4
-; O2-NEXT: andi $2, $7, 65535
-; O2-NEXT: sllv $7, $2, $4
; O2-NEXT: $BB15_1: # =>This Inner Loop Header: Depth=1
-; O2-NEXT: ll $9, 0($3)
-; O2-NEXT: and $10, $9, $5
-; O2-NEXT: bne $10, $8, $BB15_3
+; O2-NEXT: ll $6, 0($4)
+; O2-NEXT: and $7, $6, $3
+; O2-NEXT: bne $7, $5, $BB15_3
; O2-NEXT: nop
; O2-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1
-; O2-NEXT: and $9, $9, $6
-; O2-NEXT: or $9, $9, $7
-; O2-NEXT: sc $9, 0($3)
-; O2-NEXT: beqz $9, $BB15_1
+; O2-NEXT: xor $7, $6, $7
+; O2-NEXT: or $7, $7, $1
+; O2-NEXT: sc $7, 0($4)
+; O2-NEXT: beqz $7, $BB15_1
; O2-NEXT: nop
; O2-NEXT: $BB15_3:
-; O2-NEXT: srlv $2, $10, $4
-; O2-NEXT: sll $2, $2, 16
-; O2-NEXT: sra $2, $2, 16
-; O2-NEXT: # %bb.4:
-; O2-NEXT: sll $1, $1, 16
-; O2-NEXT: sra $1, $1, 16
-; O2-NEXT: xor $1, $2, $1
+; O2-NEXT: srlv $2, $6, $2
+; O2-NEXT: and $1, $6, $3
+; O2-NEXT: xor $1, $5, $1
; O2-NEXT: sltiu $3, $1, 1
; O2-NEXT: sync
; O2-NEXT: jr $ra
@@ -6426,77 +5982,66 @@ define {i16, i1} @foo(ptr %addr, i16 %l, i16 %r, i16 %new) {
;
; O3-LABEL: foo:
; O3: # %bb.0:
-; O3-NEXT: addiu $2, $zero, -4
-; O3-NEXT: addu $1, $5, $6
+; O3-NEXT: addu $5, $5, $6
+; O3-NEXT: andi $1, $7, 65535
+; O3-NEXT: sll $2, $4, 3
+; O3-NEXT: ori $3, $zero, 65535
+; O3-NEXT: addiu $7, $zero, -4
; O3-NEXT: sync
-; O3-NEXT: and $3, $4, $2
-; O3-NEXT: andi $2, $4, 3
-; O3-NEXT: sll $4, $2, 3
-; O3-NEXT: ori $2, $zero, 65535
-; O3-NEXT: sllv $5, $2, $4
-; O3-NEXT: andi $2, $1, 65535
-; O3-NEXT: sll $1, $1, 16
-; O3-NEXT: sllv $8, $2, $4
-; O3-NEXT: andi $2, $7, 65535
-; O3-NEXT: nor $6, $zero, $5
-; O3-NEXT: sra $1, $1, 16
-; O3-NEXT: sllv $7, $2, $4
+; O3-NEXT: andi $5, $5, 65535
+; O3-NEXT: and $4, $4, $7
+; O3-NEXT: sllv $3, $3, $2
+; O3-NEXT: sllv $1, $1, $2
+; O3-NEXT: sllv $5, $5, $2
; O3-NEXT: $BB15_1: # =>This Inner Loop Header: Depth=1
-; O3-NEXT: ll $9, 0($3)
-; O3-NEXT: and $10, $9, $5
-; O3-NEXT: bne $10, $8, $BB15_3
+; O3-NEXT: ll $6, 0($4)
+; O3-NEXT: and $7, $6, $3
+; O3-NEXT: bne $7, $5, $BB15_3
; O3-NEXT: nop
; O3-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1
-; O3-NEXT: and $9, $9, $6
-; O3-NEXT: or $9, $9, $7
-; O3-NEXT: sc $9, 0($3)
-; O3-NEXT: beqz $9, $BB15_1
+; O3-NEXT: xor $7, $6, $7
+; O3-NEXT: or $7, $7, $1
+; O3-NEXT: sc $7, 0($4)
+; O3-NEXT: beqz $7, $BB15_1
; O3-NEXT: nop
; O3-NEXT: $BB15_3:
-; O3-NEXT: srlv $2, $10, $4
-; O3-NEXT: sll $2, $2, 16
-; O3-NEXT: sra $2, $2, 16
-; O3-NEXT: # %bb.4:
; O3-NEXT: sync
-; O3-NEXT: xor $1, $2, $1
+; O3-NEXT: and $1, $6, $3
+; O3-NEXT: srlv $2, $6, $2
+; O3-NEXT: xor $1, $5, $1
; O3-NEXT: jr $ra
; O3-NEXT: sltiu $3, $1, 1
;
; MIPS32EB-LABEL: foo:
; MIPS32EB: # %bb.0:
-; MIPS32EB-NEXT: addu $1, $5, $6
-; MIPS32EB-NEXT: sync
-; MIPS32EB-NEXT: addiu $2, $zero, -4
-; MIPS32EB-NEXT: and $3, $4, $2
+; MIPS32EB-NEXT: andi $1, $7, 65535
; MIPS32EB-NEXT: andi $2, $4, 3
; MIPS32EB-NEXT: xori $2, $2, 2
-; MIPS32EB-NEXT: sll $4, $2, 3
-; MIPS32EB-NEXT: ori $2, $zero, 65535
-; MIPS32EB-NEXT: sllv $5, $2, $4
-; MIPS32EB-NEXT: nor $6, $zero, $5
-; MIPS32EB-NEXT: andi $2, $1, 65535
-; MIPS32EB-NEXT: sllv $8, $2, $4
-; MIPS32EB-NEXT: andi $2, $7, 65535
-; MIPS32EB-NEXT: sllv $7, $2, $4
+; MIPS32EB-NEXT: sll $2, $2, 3
+; MIPS32EB-NEXT: ori $3, $zero, 65535
+; MIPS32EB-NEXT: addiu $7, $zero, -4
+; MIPS32EB-NEXT: and $4, $4, $7
+; MIPS32EB-NEXT: sllv $3, $3, $2
+; MIPS32EB-NEXT: sllv $1, $1, $2
+; MIPS32EB-NEXT: addu $5, $5, $6
+; MIPS32EB-NEXT: andi $5, $5, 65535
+; MIPS32EB-NEXT: sllv $5, $5, $2
+; MIPS32EB-NEXT: sync
; MIPS32EB-NEXT: $BB15_1: # =>This Inner Loop Header: Depth=1
-; MIPS32EB-NEXT: ll $9, 0($3)
-; MIPS32EB-NEXT: and $10, $9, $5
-; MIPS32EB-NEXT: bne $10, $8, $BB15_3
+; MIPS32EB-NEXT: ll $6, 0($4)
+; MIPS32EB-NEXT: and $7, $6, $3
+; MIPS32EB-NEXT: bne $7, $5, $BB15_3
; MIPS32EB-NEXT: nop
; MIPS32EB-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1
-; MIPS32EB-NEXT: and $9, $9, $6
-; MIPS32EB-NEXT: or $9, $9, $7
-; MIPS32EB-NEXT: sc $9, 0($3)
-; MIPS32EB-NEXT: beqz $9, $BB15_1
+; MIPS32EB-NEXT: xor $7, $6, $7
+; MIPS32EB-NEXT: or $7, $7, $1
+; MIPS32EB-NEXT: sc $7, 0($4)
+; MIPS32EB-NEXT: beqz $7, $BB15_1
; MIPS32EB-NEXT: nop
; MIPS32EB-NEXT: $BB15_3:
-; MIPS32EB-NEXT: srlv $2, $10, $4
-; MIPS32EB-NEXT: sll $2, $2, 16
-; MIPS32EB-NEXT: sra $2, $2, 16
-; MIPS32EB-NEXT: # %bb.4:
-; MIPS32EB-NEXT: sll $1, $1, 16
-; MIPS32EB-NEXT: sra $1, $1, 16
-; MIPS32EB-NEXT: xor $1, $2, $1
+; MIPS32EB-NEXT: srlv $2, $6, $2
+; MIPS32EB-NEXT: and $1, $6, $3
+; MIPS32EB-NEXT: xor $1, $5, $1
; MIPS32EB-NEXT: sltiu $3, $1, 1
; MIPS32EB-NEXT: sync
; MIPS32EB-NEXT: jr $ra
@@ -6833,17 +6378,16 @@ define i32 @zeroreg() nounwind {
; MIPS32O0-NEXT: addu $1, $2, $25
; MIPS32O0-NEXT: sync
; MIPS32O0-NEXT: lw $4, %got(a)($1)
-; MIPS32O0-NEXT: addiu $6, $zero, 0
+; MIPS32O0-NEXT: addiu $5, $zero, 0
; MIPS32O0-NEXT: addiu $2, $zero, 1
-; MIPS32O0-NEXT: move $5, $2
; MIPS32O0-NEXT: $BB17_1: # %entry
; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS32O0-NEXT: ll $1, 0($4)
-; MIPS32O0-NEXT: bne $1, $5, $BB17_3
+; MIPS32O0-NEXT: bne $1, $2, $BB17_3
; MIPS32O0-NEXT: nop
; MIPS32O0-NEXT: # %bb.2: # %entry
; MIPS32O0-NEXT: # in Loop: Header=BB17_1 Depth=1
-; MIPS32O0-NEXT: move $3, $6
+; MIPS32O0-NEXT: move $3, $5
; MIPS32O0-NEXT: sc $3, 0($4)
; MIPS32O0-NEXT: beqz $3, $BB17_1
; MIPS32O0-NEXT: nop
@@ -6916,16 +6460,15 @@ define i32 @zeroreg() nounwind {
; MIPS32R6O0-NEXT: addu $1, $2, $25
; MIPS32R6O0-NEXT: sync
; MIPS32R6O0-NEXT: lw $4, %got(a)($1)
-; MIPS32R6O0-NEXT: addiu $6, $zero, 0
+; MIPS32R6O0-NEXT: addiu $5, $zero, 0
; MIPS32R6O0-NEXT: addiu $2, $zero, 1
-; MIPS32R6O0-NEXT: move $5, $2
; MIPS32R6O0-NEXT: $BB17_1: # %entry
; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS32R6O0-NEXT: ll $1, 0($4)
-; MIPS32R6O0-NEXT: bnec $1, $5, $BB17_3
+; MIPS32R6O0-NEXT: bnec $1, $2, $BB17_3
; MIPS32R6O0-NEXT: # %bb.2: # %entry
; MIPS32R6O0-NEXT: # in Loop: Header=BB17_1 Depth=1
-; MIPS32R6O0-NEXT: move $3, $6
+; MIPS32R6O0-NEXT: move $3, $5
; MIPS32R6O0-NEXT: sc $3, 0($4)
; MIPS32R6O0-NEXT: beqzc $3, $BB17_1
; MIPS32R6O0-NEXT: $BB17_3: # %entry
@@ -7046,16 +6589,15 @@ define i32 @zeroreg() nounwind {
; MIPS64R6O0-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(zeroreg)))
; MIPS64R6O0-NEXT: sync
; MIPS64R6O0-NEXT: ld $4, %got_disp(a)($1)
-; MIPS64R6O0-NEXT: addiu $6, $zero, 0
+; MIPS64R6O0-NEXT: addiu $5, $zero, 0
; MIPS64R6O0-NEXT: addiu $2, $zero, 1
-; MIPS64R6O0-NEXT: move $5, $2
; MIPS64R6O0-NEXT: .LBB17_1: # %entry
; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS64R6O0-NEXT: ll $1, 0($4)
-; MIPS64R6O0-NEXT: bnec $1, $5, .LBB17_3
+; MIPS64R6O0-NEXT: bnec $1, $2, .LBB17_3
; MIPS64R6O0-NEXT: # %bb.2: # %entry
; MIPS64R6O0-NEXT: # in Loop: Header=BB17_1 Depth=1
-; MIPS64R6O0-NEXT: move $3, $6
+; MIPS64R6O0-NEXT: move $3, $5
; MIPS64R6O0-NEXT: sc $3, 0($4)
; MIPS64R6O0-NEXT: beqzc $3, .LBB17_1
; MIPS64R6O0-NEXT: .LBB17_3: # %entry
diff --git a/llvm/test/CodeGen/Mips/atomic64.ll b/llvm/test/CodeGen/Mips/atomic64.ll
index 8d9c1ca866a751..443f68dadce296 100644
--- a/llvm/test/CodeGen/Mips/atomic64.ll
+++ b/llvm/test/CodeGen/Mips/atomic64.ll
@@ -818,7 +818,7 @@ define i64 @AtomicLoadNand(i64 signext %incr) nounwind {
; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS4-NEXT: lld $2, 0($1)
; MIPS4-NEXT: and $3, $2, $4
-; MIPS4-NEXT: nor $3, $zero, $3
+; MIPS4-NEXT: not $3, $3
; MIPS4-NEXT: scd $3, 0($1)
; MIPS4-NEXT: beqz $3, .LBB5_1
; MIPS4-NEXT: nop
@@ -836,7 +836,7 @@ define i64 @AtomicLoadNand(i64 signext %incr) nounwind {
; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS64-NEXT: lld $2, 0($1)
; MIPS64-NEXT: and $3, $2, $4
-; MIPS64-NEXT: nor $3, $zero, $3
+; MIPS64-NEXT: not $3, $3
; MIPS64-NEXT: scd $3, 0($1)
; MIPS64-NEXT: beqz $3, .LBB5_1
; MIPS64-NEXT: nop
@@ -854,7 +854,7 @@ define i64 @AtomicLoadNand(i64 signext %incr) nounwind {
; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS64R2-NEXT: lld $2, 0($1)
; MIPS64R2-NEXT: and $3, $2, $4
-; MIPS64R2-NEXT: nor $3, $zero, $3
+; MIPS64R2-NEXT: not $3, $3
; MIPS64R2-NEXT: scd $3, 0($1)
; MIPS64R2-NEXT: beqz $3, .LBB5_1
; MIPS64R2-NEXT: nop
@@ -872,7 +872,7 @@ define i64 @AtomicLoadNand(i64 signext %incr) nounwind {
; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS64R6-NEXT: lld $2, 0($1)
; MIPS64R6-NEXT: and $3, $2, $4
-; MIPS64R6-NEXT: nor $3, $zero, $3
+; MIPS64R6-NEXT: not $3, $3
; MIPS64R6-NEXT: scd $3, 0($1)
; MIPS64R6-NEXT: beqzc $3, .LBB5_1
; MIPS64R6-NEXT: nop
@@ -889,7 +889,7 @@ define i64 @AtomicLoadNand(i64 signext %incr) nounwind {
; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS64R6O0-NEXT: lld $2, 0($3)
; MIPS64R6O0-NEXT: and $1, $2, $4
-; MIPS64R6O0-NEXT: nor $1, $zero, $1
+; MIPS64R6O0-NEXT: not $1, $1
; MIPS64R6O0-NEXT: scd $1, 0($3)
; MIPS64R6O0-NEXT: beqzc $1, .LBB5_1
; MIPS64R6O0-NEXT: nop
@@ -906,7 +906,7 @@ define i64 @AtomicLoadNand(i64 signext %incr) nounwind {
; O1-NEXT: # =>This Inner Loop Header: Depth=1
; O1-NEXT: lld $2, 0($1)
; O1-NEXT: and $3, $2, $4
-; O1-NEXT: nor $3, $zero, $3
+; O1-NEXT: not $3, $3
; O1-NEXT: scd $3, 0($1)
; O1-NEXT: beqz $3, .LBB5_1
; O1-NEXT: nop
@@ -924,7 +924,7 @@ define i64 @AtomicLoadNand(i64 signext %incr) nounwind {
; O2-NEXT: # =>This Inner Loop Header: Depth=1
; O2-NEXT: lld $2, 0($1)
; O2-NEXT: and $3, $2, $4
-; O2-NEXT: nor $3, $zero, $3
+; O2-NEXT: not $3, $3
; O2-NEXT: scd $3, 0($1)
; O2-NEXT: beqz $3, .LBB5_1
; O2-NEXT: nop
@@ -942,7 +942,7 @@ define i64 @AtomicLoadNand(i64 signext %incr) nounwind {
; O3-NEXT: # =>This Inner Loop Header: Depth=1
; O3-NEXT: lld $2, 0($1)
; O3-NEXT: and $3, $2, $4
-; O3-NEXT: nor $3, $zero, $3
+; O3-NEXT: not $3, $3
; O3-NEXT: scd $3, 0($1)
; O3-NEXT: beqz $3, .LBB5_1
; O3-NEXT: nop
@@ -960,7 +960,7 @@ define i64 @AtomicLoadNand(i64 signext %incr) nounwind {
; MIPS64EB-NEXT: # =>This Inner Loop Header: Depth=1
; MIPS64EB-NEXT: lld $2, 0($1)
; MIPS64EB-NEXT: and $3, $2, $4
-; MIPS64EB-NEXT: nor $3, $zero, $3
+; MIPS64EB-NEXT: not $3, $3
; MIPS64EB-NEXT: scd $3, 0($1)
; MIPS64EB-NEXT: beqz $3, .LBB5_1
; MIPS64EB-NEXT: nop
diff --git a/llvm/test/CodeGen/Mips/atomicops.ll b/llvm/test/CodeGen/Mips/atomicops.ll
index 906429b14a1810..b1708d6392294e 100644
--- a/llvm/test/CodeGen/Mips/atomicops.ll
+++ b/llvm/test/CodeGen/Mips/atomicops.ll
@@ -1,4 +1,5 @@
-; RUN: llc -mtriple=mipsel -mattr=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16
+; RUN: llc -mtriple=mipsel -mattr=mips16 -relocation-model=pic -O3 -verify-machineinstrs < %s | FileCheck %s -check-prefix=16
+; RUN: llc -mtriple=mips -mattr=mips16 -relocation-model=pic -O0 -verify-machineinstrs < %s | FileCheck %s -check-prefix=16
@.str = private unnamed_addr constant [8 x i8] c"%d, %d\0A\00", align 1
@@ -46,3 +47,34 @@ entry:
}
declare i32 @printf(ptr nocapture, ...) nounwind
+
+; MIPS16 uses byte and halfword libcalls.
+define i8 @add_i8(ptr %ptr, i8 %value) {
+; 16-LABEL: add_i8:
+; 16: %call16(__sync_fetch_and_add_1)
+ %old = atomicrmw add ptr %ptr, i8 %value seq_cst
+ ret i8 %old
+}
+
+define i8 @cmpxchg_i8(ptr %ptr, i8 %cmp, i8 %value) {
+; 16-LABEL: cmpxchg_i8:
+; 16: %call16(__sync_val_compare_and_swap_1)
+ %pair = cmpxchg ptr %ptr, i8 %cmp, i8 %value seq_cst acquire
+ %old = extractvalue { i8, i1 } %pair, 0
+ ret i8 %old
+}
+
+define i16 @add_i16(ptr %ptr, i16 %value) {
+; 16-LABEL: add_i16:
+; 16: %call16(__sync_fetch_and_add_2)
+ %old = atomicrmw add ptr %ptr, i16 %value seq_cst
+ ret i16 %old
+}
+
+define i16 @cmpxchg_i16(ptr %ptr, i16 %cmp, i16 %value) {
+; 16-LABEL: cmpxchg_i16:
+; 16: %call16(__sync_val_compare_and_swap_2)
+ %pair = cmpxchg ptr %ptr, i16 %cmp, i16 %value seq_cst acquire
+ %old = extractvalue { i16, i1 } %pair, 0
+ ret i16 %old
+}
diff --git a/llvm/test/CodeGen/Mips/atomicrmw-cmpxchg.ll b/llvm/test/CodeGen/Mips/atomicrmw-cmpxchg.ll
new file mode 100644
index 00000000000000..d5a55bb660dbfd
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/atomicrmw-cmpxchg.ll
@@ -0,0 +1,308 @@
+; RUN: llc -mtriple=mipsel -mcpu=mips32r2 -verify-machineinstrs < %s | FileCheck %s --check-prefix=NATIVE
+; RUN: llc -mtriple=mipsel -mcpu=mips32r6 -O0 -verify-machineinstrs < %s | FileCheck %s --check-prefix=NATIVE
+; RUN: llc -mtriple=mips64el -mcpu=mips64r2 -verify-machineinstrs < %s | FileCheck %s --check-prefix=NATIVE
+; RUN: llc -mtriple=mips64el -mcpu=mips64r6 -O0 -verify-machineinstrs < %s | FileCheck %s --check-prefix=NATIVE
+; RUN: llc -mtriple=mipsel -mattr=+mips16 -verify-machineinstrs < %s | FileCheck %s --check-prefix=MIPS16
+
+define i8 @uinc_wrap_i8(ptr %ptr, i8 %value) {
+; NATIVE-LABEL: uinc_wrap_i8:
+; NATIVE: [[RMW:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: [[LLSC:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: {{^[ \t]+}}ll $[[OLD:[0-9]+]], 0($[[PTR:[0-9]+]])
+; NATIVE-NEXT: {{[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP:[0-9]+]], [[CMPDONE:(\$BB|\.LBB)[0-9]+_[0-9]+]]
+; NATIVE-NOT: {{^[ \t]+s[bhwd]([lr]|c[0-3])?[ \t]}}
+; NATIVE: {{^[ \t]+}}sc $[[SC:[0-9]+]], 0($[[PTR]])
+; NATIVE-NEXT: {{[ \t]+}}beqz{{c?}} $[[SC]], [[LLSC]]
+; NATIVE: [[CMPDONE]]:
+; NATIVE: {{^[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP]], [[RMW]]
+; MIPS16-LABEL: uinc_wrap_i8:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_1
+; MIPS16: {{^[ \t]+}}b [[COMPUTE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: [[RETRY:\$BB[0-9]+_[0-9]+]]:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_1
+; MIPS16: {{^[ \t]+}}cmp ${{[0-9]+}}, ${{[0-9]+}}
+; MIPS16: {{^[ \t]+}}bteqz [[DONE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: [[COMPUTE]]:
+; MIPS16: {{^[ \t]+}}b [[RETRY]]
+; MIPS16: [[DONE]]:
+ %old = atomicrmw uinc_wrap ptr %ptr, i8 %value seq_cst
+ ret i8 %old
+}
+
+define i8 @udec_wrap_i8(ptr %ptr, i8 %value) {
+; NATIVE-LABEL: udec_wrap_i8:
+; NATIVE: [[RMW:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: [[LLSC:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: {{^[ \t]+}}ll $[[OLD:[0-9]+]], 0($[[PTR:[0-9]+]])
+; NATIVE-NEXT: {{[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP:[0-9]+]], [[CMPDONE:(\$BB|\.LBB)[0-9]+_[0-9]+]]
+; NATIVE-NOT: {{^[ \t]+s[bhwd]([lr]|c[0-3])?[ \t]}}
+; NATIVE: {{^[ \t]+}}sc $[[SC:[0-9]+]], 0($[[PTR]])
+; NATIVE-NEXT: {{[ \t]+}}beqz{{c?}} $[[SC]], [[LLSC]]
+; NATIVE: [[CMPDONE]]:
+; NATIVE: {{^[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP]], [[RMW]]
+; MIPS16-LABEL: udec_wrap_i8:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_1
+; MIPS16: {{^[ \t]+}}b [[COMPUTE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: [[RETRY:\$BB[0-9]+_[0-9]+]]:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_1
+; MIPS16: {{^[ \t]+}}cmp ${{[0-9]+}}, ${{[0-9]+}}
+; MIPS16: {{^[ \t]+}}bteqz [[DONE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: [[COMPUTE]]:
+; MIPS16: {{^[ \t]+}}b [[RETRY]]
+; MIPS16: [[DONE]]:
+ %old = atomicrmw udec_wrap ptr %ptr, i8 %value seq_cst
+ ret i8 %old
+}
+
+define i8 @usub_cond_i8(ptr %ptr, i8 %value) {
+; NATIVE-LABEL: usub_cond_i8:
+; NATIVE: [[RMW:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: [[LLSC:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: {{^[ \t]+}}ll $[[OLD:[0-9]+]], 0($[[PTR:[0-9]+]])
+; NATIVE-NEXT: {{[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP:[0-9]+]], [[CMPDONE:(\$BB|\.LBB)[0-9]+_[0-9]+]]
+; NATIVE-NOT: {{^[ \t]+s[bhwd]([lr]|c[0-3])?[ \t]}}
+; NATIVE: {{^[ \t]+}}sc $[[SC:[0-9]+]], 0($[[PTR]])
+; NATIVE-NEXT: {{[ \t]+}}beqz{{c?}} $[[SC]], [[LLSC]]
+; NATIVE: [[CMPDONE]]:
+; NATIVE: {{^[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP]], [[RMW]]
+; MIPS16-LABEL: usub_cond_i8:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_1
+; MIPS16: {{^[ \t]+}}b [[COMPUTE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: {{^\$BB[0-9]+_[0-9]+:}}
+; MIPS16: [[RETRY:\$BB[0-9]+_[0-9]+]]:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_1
+; MIPS16: {{^[ \t]+}}cmp ${{[0-9]+}}, ${{[0-9]+}}
+; MIPS16: {{^[ \t]+}}bteqz [[DONE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: [[COMPUTE]]:
+; MIPS16: {{^[ \t]+}}b [[RETRY]]
+; MIPS16: [[DONE]]:
+ %old = atomicrmw usub_cond ptr %ptr, i8 %value seq_cst
+ ret i8 %old
+}
+
+define i8 @usub_sat_i8(ptr %ptr, i8 %value) {
+; NATIVE-LABEL: usub_sat_i8:
+; NATIVE: [[RMW:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: [[LLSC:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: {{^[ \t]+}}ll $[[OLD:[0-9]+]], 0($[[PTR:[0-9]+]])
+; NATIVE-NEXT: {{[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP:[0-9]+]], [[CMPDONE:(\$BB|\.LBB)[0-9]+_[0-9]+]]
+; NATIVE-NOT: {{^[ \t]+s[bhwd]([lr]|c[0-3])?[ \t]}}
+; NATIVE: {{^[ \t]+}}sc $[[SC:[0-9]+]], 0($[[PTR]])
+; NATIVE-NEXT: {{[ \t]+}}beqz{{c?}} $[[SC]], [[LLSC]]
+; NATIVE: [[CMPDONE]]:
+; NATIVE: {{^[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP]], [[RMW]]
+; MIPS16-LABEL: usub_sat_i8:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_1
+; MIPS16: {{^[ \t]+}}b [[COMPUTE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: [[RETRY:\$BB[0-9]+_[0-9]+]]:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_1
+; MIPS16: {{^[ \t]+}}cmp ${{[0-9]+}}, ${{[0-9]+}}
+; MIPS16: {{^[ \t]+}}bteqz [[DONE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: [[COMPUTE]]:
+; MIPS16: {{^[ \t]+}}b [[RETRY]]
+; MIPS16: [[DONE]]:
+ %old = atomicrmw usub_sat ptr %ptr, i8 %value seq_cst
+ ret i8 %old
+}
+
+define i16 @uinc_wrap_i16(ptr %ptr, i16 %value) {
+; NATIVE-LABEL: uinc_wrap_i16:
+; NATIVE: [[RMW:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: [[LLSC:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: {{^[ \t]+}}ll $[[OLD:[0-9]+]], 0($[[PTR:[0-9]+]])
+; NATIVE-NEXT: {{[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP:[0-9]+]], [[CMPDONE:(\$BB|\.LBB)[0-9]+_[0-9]+]]
+; NATIVE-NOT: {{^[ \t]+s[bhwd]([lr]|c[0-3])?[ \t]}}
+; NATIVE: {{^[ \t]+}}sc $[[SC:[0-9]+]], 0($[[PTR]])
+; NATIVE-NEXT: {{[ \t]+}}beqz{{c?}} $[[SC]], [[LLSC]]
+; NATIVE: [[CMPDONE]]:
+; NATIVE: {{^[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP]], [[RMW]]
+; MIPS16-LABEL: uinc_wrap_i16:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_2
+; MIPS16: {{^[ \t]+}}b [[COMPUTE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: [[RETRY:\$BB[0-9]+_[0-9]+]]:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_2
+; MIPS16: {{^[ \t]+}}cmp ${{[0-9]+}}, ${{[0-9]+}}
+; MIPS16: {{^[ \t]+}}bteqz [[DONE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: [[COMPUTE]]:
+; MIPS16: {{^[ \t]+}}b [[RETRY]]
+; MIPS16: [[DONE]]:
+ %old = atomicrmw uinc_wrap ptr %ptr, i16 %value seq_cst
+ ret i16 %old
+}
+
+define i16 @udec_wrap_i16(ptr %ptr, i16 %value) {
+; NATIVE-LABEL: udec_wrap_i16:
+; NATIVE: [[RMW:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: [[LLSC:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: {{^[ \t]+}}ll $[[OLD:[0-9]+]], 0($[[PTR:[0-9]+]])
+; NATIVE-NEXT: {{[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP:[0-9]+]], [[CMPDONE:(\$BB|\.LBB)[0-9]+_[0-9]+]]
+; NATIVE-NOT: {{^[ \t]+s[bhwd]([lr]|c[0-3])?[ \t]}}
+; NATIVE: {{^[ \t]+}}sc $[[SC:[0-9]+]], 0($[[PTR]])
+; NATIVE-NEXT: {{[ \t]+}}beqz{{c?}} $[[SC]], [[LLSC]]
+; NATIVE: [[CMPDONE]]:
+; NATIVE: {{^[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP]], [[RMW]]
+; MIPS16-LABEL: udec_wrap_i16:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_2
+; MIPS16: {{^[ \t]+}}b [[COMPUTE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: [[RETRY:\$BB[0-9]+_[0-9]+]]:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_2
+; MIPS16: {{^[ \t]+}}cmp ${{[0-9]+}}, ${{[0-9]+}}
+; MIPS16: {{^[ \t]+}}bteqz [[DONE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: [[COMPUTE]]:
+; MIPS16: {{^[ \t]+}}b [[RETRY]]
+; MIPS16: [[DONE]]:
+ %old = atomicrmw udec_wrap ptr %ptr, i16 %value seq_cst
+ ret i16 %old
+}
+
+define i16 @usub_cond_i16(ptr %ptr, i16 %value) {
+; NATIVE-LABEL: usub_cond_i16:
+; NATIVE: [[RMW:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: [[LLSC:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: {{^[ \t]+}}ll $[[OLD:[0-9]+]], 0($[[PTR:[0-9]+]])
+; NATIVE-NEXT: {{[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP:[0-9]+]], [[CMPDONE:(\$BB|\.LBB)[0-9]+_[0-9]+]]
+; NATIVE-NOT: {{^[ \t]+s[bhwd]([lr]|c[0-3])?[ \t]}}
+; NATIVE: {{^[ \t]+}}sc $[[SC:[0-9]+]], 0($[[PTR]])
+; NATIVE-NEXT: {{[ \t]+}}beqz{{c?}} $[[SC]], [[LLSC]]
+; NATIVE: [[CMPDONE]]:
+; NATIVE: {{^[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP]], [[RMW]]
+; MIPS16-LABEL: usub_cond_i16:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_2
+; MIPS16: {{^[ \t]+}}b [[COMPUTE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: {{^\$BB[0-9]+_[0-9]+:}}
+; MIPS16: [[RETRY:\$BB[0-9]+_[0-9]+]]:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_2
+; MIPS16: {{^[ \t]+}}cmp ${{[0-9]+}}, ${{[0-9]+}}
+; MIPS16: {{^[ \t]+}}bteqz [[DONE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: [[COMPUTE]]:
+; MIPS16: {{^[ \t]+}}b [[RETRY]]
+; MIPS16: [[DONE]]:
+ %old = atomicrmw usub_cond ptr %ptr, i16 %value seq_cst
+ ret i16 %old
+}
+
+define i16 @usub_sat_i16(ptr %ptr, i16 %value) {
+; NATIVE-LABEL: usub_sat_i16:
+; NATIVE: [[RMW:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: [[LLSC:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: {{^[ \t]+}}ll $[[OLD:[0-9]+]], 0($[[PTR:[0-9]+]])
+; NATIVE-NEXT: {{[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP:[0-9]+]], [[CMPDONE:(\$BB|\.LBB)[0-9]+_[0-9]+]]
+; NATIVE-NOT: {{^[ \t]+s[bhwd]([lr]|c[0-3])?[ \t]}}
+; NATIVE: {{^[ \t]+}}sc $[[SC:[0-9]+]], 0($[[PTR]])
+; NATIVE-NEXT: {{[ \t]+}}beqz{{c?}} $[[SC]], [[LLSC]]
+; NATIVE: [[CMPDONE]]:
+; NATIVE: {{^[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP]], [[RMW]]
+; MIPS16-LABEL: usub_sat_i16:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_2
+; MIPS16: {{^[ \t]+}}b [[COMPUTE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: [[RETRY:\$BB[0-9]+_[0-9]+]]:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_2
+; MIPS16: {{^[ \t]+}}cmp ${{[0-9]+}}, ${{[0-9]+}}
+; MIPS16: {{^[ \t]+}}bteqz [[DONE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: [[COMPUTE]]:
+; MIPS16: {{^[ \t]+}}b [[RETRY]]
+; MIPS16: [[DONE]]:
+ %old = atomicrmw usub_sat ptr %ptr, i16 %value seq_cst
+ ret i16 %old
+}
+
+define i32 @uinc_wrap_i32(ptr %ptr, i32 %value) {
+; NATIVE-LABEL: uinc_wrap_i32:
+; NATIVE: [[RMW:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: [[LLSC:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: {{^[ \t]+}}ll $[[OLD:[0-9]+]], 0($[[PTR:[0-9]+]])
+; NATIVE-NEXT: {{[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP:[0-9]+]], [[CMPDONE:(\$BB|\.LBB)[0-9]+_[0-9]+]]
+; NATIVE-NOT: {{^[ \t]+s[bhwd]([lr]|c[0-3])?[ \t]}}
+; NATIVE: {{^[ \t]+}}sc $[[SC:[0-9]+]], 0($[[PTR]])
+; NATIVE-NEXT: {{[ \t]+}}beqz{{c?}} $[[SC]], [[LLSC]]
+; NATIVE: [[CMPDONE]]:
+; NATIVE: {{^[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP]], [[RMW]]
+; MIPS16-LABEL: uinc_wrap_i32:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_4
+; MIPS16: {{^[ \t]+}}b [[COMPUTE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: [[RETRY:\$BB[0-9]+_[0-9]+]]:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_4
+; MIPS16: {{^[ \t]+}}cmp ${{[0-9]+}}, ${{[0-9]+}}
+; MIPS16: {{^[ \t]+}}bteqz [[DONE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: [[COMPUTE]]:
+; MIPS16: {{^[ \t]+}}b [[RETRY]]
+; MIPS16: [[DONE]]:
+ %old = atomicrmw uinc_wrap ptr %ptr, i32 %value seq_cst
+ ret i32 %old
+}
+
+define i32 @udec_wrap_i32(ptr %ptr, i32 %value) {
+; NATIVE-LABEL: udec_wrap_i32:
+; NATIVE: [[RMW:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: [[LLSC:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: {{^[ \t]+}}ll $[[OLD:[0-9]+]], 0($[[PTR:[0-9]+]])
+; NATIVE-NEXT: {{[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP:[0-9]+]], [[CMPDONE:(\$BB|\.LBB)[0-9]+_[0-9]+]]
+; NATIVE-NOT: {{^[ \t]+s[bhwd]([lr]|c[0-3])?[ \t]}}
+; NATIVE: {{^[ \t]+}}sc $[[SC:[0-9]+]], 0($[[PTR]])
+; NATIVE-NEXT: {{[ \t]+}}beqz{{c?}} $[[SC]], [[LLSC]]
+; NATIVE: [[CMPDONE]]:
+; NATIVE: {{^[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP]], [[RMW]]
+; MIPS16-LABEL: udec_wrap_i32:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_4
+; MIPS16: {{^[ \t]+}}b [[COMPUTE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: [[RETRY:\$BB[0-9]+_[0-9]+]]:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_4
+; MIPS16: {{^[ \t]+}}cmp ${{[0-9]+}}, ${{[0-9]+}}
+; MIPS16: {{^[ \t]+}}bteqz [[DONE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: [[COMPUTE]]:
+; MIPS16: {{^[ \t]+}}b [[RETRY]]
+; MIPS16: [[DONE]]:
+ %old = atomicrmw udec_wrap ptr %ptr, i32 %value seq_cst
+ ret i32 %old
+}
+
+define i32 @usub_cond_i32(ptr %ptr, i32 %value) {
+; NATIVE-LABEL: usub_cond_i32:
+; NATIVE: [[RMW:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: [[LLSC:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: {{^[ \t]+}}ll $[[OLD:[0-9]+]], 0($[[PTR:[0-9]+]])
+; NATIVE-NEXT: {{[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP:[0-9]+]], [[CMPDONE:(\$BB|\.LBB)[0-9]+_[0-9]+]]
+; NATIVE-NOT: {{^[ \t]+s[bhwd]([lr]|c[0-3])?[ \t]}}
+; NATIVE: {{^[ \t]+}}sc $[[SC:[0-9]+]], 0($[[PTR]])
+; NATIVE-NEXT: {{[ \t]+}}beqz{{c?}} $[[SC]], [[LLSC]]
+; NATIVE: [[CMPDONE]]:
+; NATIVE: {{^[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP]], [[RMW]]
+; MIPS16-LABEL: usub_cond_i32:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_4
+; MIPS16: {{^[ \t]+}}b [[COMPUTE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: {{^\$BB[0-9]+_[0-9]+:}}
+; MIPS16: [[RETRY:\$BB[0-9]+_[0-9]+]]:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_4
+; MIPS16: {{^[ \t]+}}cmp ${{[0-9]+}}, ${{[0-9]+}}
+; MIPS16: {{^[ \t]+}}bteqz [[DONE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: [[COMPUTE]]:
+; MIPS16: {{^[ \t]+}}b [[RETRY]]
+; MIPS16: [[DONE]]:
+ %old = atomicrmw usub_cond ptr %ptr, i32 %value seq_cst
+ ret i32 %old
+}
+
+define i32 @usub_sat_i32(ptr %ptr, i32 %value) {
+; NATIVE-LABEL: usub_sat_i32:
+; NATIVE: [[RMW:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: [[LLSC:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; NATIVE: {{^[ \t]+}}ll $[[OLD:[0-9]+]], 0($[[PTR:[0-9]+]])
+; NATIVE-NEXT: {{[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP:[0-9]+]], [[CMPDONE:(\$BB|\.LBB)[0-9]+_[0-9]+]]
+; NATIVE-NOT: {{^[ \t]+s[bhwd]([lr]|c[0-3])?[ \t]}}
+; NATIVE: {{^[ \t]+}}sc $[[SC:[0-9]+]], 0($[[PTR]])
+; NATIVE-NEXT: {{[ \t]+}}beqz{{c?}} $[[SC]], [[LLSC]]
+; NATIVE: [[CMPDONE]]:
+; NATIVE: {{^[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP]], [[RMW]]
+; MIPS16-LABEL: usub_sat_i32:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_4
+; MIPS16: {{^[ \t]+}}b [[COMPUTE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: [[RETRY:\$BB[0-9]+_[0-9]+]]:
+; MIPS16: {{^[ \t]+}}jal __sync_val_compare_and_swap_4
+; MIPS16: {{^[ \t]+}}cmp ${{[0-9]+}}, ${{[0-9]+}}
+; MIPS16: {{^[ \t]+}}bteqz [[DONE:\$BB[0-9]+_[0-9]+]]
+; MIPS16: [[COMPUTE]]:
+; MIPS16: {{^[ \t]+}}b [[RETRY]]
+; MIPS16: [[DONE]]:
+ %old = atomicrmw usub_sat ptr %ptr, i32 %value seq_cst
+ ret i32 %old
+}
diff --git a/llvm/test/CodeGen/Mips/atomicrmw-cmpxchg64.ll b/llvm/test/CodeGen/Mips/atomicrmw-cmpxchg64.ll
new file mode 100644
index 00000000000000..41007d54c5238b
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/atomicrmw-cmpxchg64.ll
@@ -0,0 +1,111 @@
+; RUN: llc -mtriple=mipsel -mcpu=mips32r2 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=MIPS32,MIPS32R2
+; RUN: llc -mtriple=mipsel -mcpu=mips32r6 -O0 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=MIPS32,MIPS32R6
+; RUN: llc -mtriple=mips64el -mcpu=mips64r2 -verify-machineinstrs < %s | FileCheck %s --check-prefix=MIPS64
+; RUN: llc -mtriple=mips64el -mcpu=mips64r6 -O0 -verify-machineinstrs < %s | FileCheck %s --check-prefix=MIPS64
+
+define i64 @uinc_wrap_i64(ptr %ptr, i64 %value) {
+; MIPS64-LABEL: uinc_wrap_i64:
+; MIPS64: [[RMW:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; MIPS64: [[LLSC:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; MIPS64: {{^[ \t]+}}lld $[[OLD:[0-9]+]], 0($[[PTR:[0-9]+]])
+; MIPS64-NEXT: {{[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP:[0-9]+]], [[CMPDONE:(\$BB|\.LBB)[0-9]+_[0-9]+]]
+; MIPS64-NOT: {{^[ \t]+s[bhwd]([lr]|c[0-3])?[ \t]}}
+; MIPS64: {{^[ \t]+}}scd $[[SC:[0-9]+]], 0($[[PTR]])
+; MIPS64-NEXT: {{[ \t]+}}beqz{{c?}} $[[SC]], [[LLSC]]
+; MIPS64: [[CMPDONE]]:
+; MIPS64: {{^[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP]], [[RMW]]
+; MIPS32-LABEL: uinc_wrap_i64:
+; MIPS32: {{^[ \t]+}}jal __atomic_load_8
+; MIPS32: [[RETRY:\$BB[0-9]+_[0-9]+]]:
+; MIPS32: {{^[ \t]+}}sw ${{[0-9]+}}, [[#EXPECTED:]]($sp)
+; MIPS32-NEXT: {{[ \t]+}}sw ${{[0-9]+}}, [[#EXPECTED + 4]]($sp)
+; MIPS32: {{^[ \t]+}}jal __atomic_compare_exchange_8
+; MIPS32R2: {{^[ \t]+}}move $[[SUCCESS:[0-9]+]], $2
+; MIPS32: {{^[ \t]+}}lw ${{[0-9]+}}, [[#EXPECTED + 4]]($sp)
+; MIPS32R2: {{^[ \t]+}}beqz $[[SUCCESS]], [[RETRY]]
+; MIPS32R2-NEXT: {{[ \t]+}}lw ${{[0-9]+}}, [[#EXPECTED]]($sp)
+; MIPS32R6: {{^[ \t]+}}lw ${{[0-9]+}}, [[#EXPECTED]]($sp)
+; MIPS32R6: {{^[ \t]+}}beqzc $2, [[RETRY]]
+ %old = atomicrmw uinc_wrap ptr %ptr, i64 %value seq_cst
+ ret i64 %old
+}
+
+define i64 @udec_wrap_i64(ptr %ptr, i64 %value) {
+; MIPS64-LABEL: udec_wrap_i64:
+; MIPS64: [[RMW:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; MIPS64: [[LLSC:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; MIPS64: {{^[ \t]+}}lld $[[OLD:[0-9]+]], 0($[[PTR:[0-9]+]])
+; MIPS64-NEXT: {{[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP:[0-9]+]], [[CMPDONE:(\$BB|\.LBB)[0-9]+_[0-9]+]]
+; MIPS64-NOT: {{^[ \t]+s[bhwd]([lr]|c[0-3])?[ \t]}}
+; MIPS64: {{^[ \t]+}}scd $[[SC:[0-9]+]], 0($[[PTR]])
+; MIPS64-NEXT: {{[ \t]+}}beqz{{c?}} $[[SC]], [[LLSC]]
+; MIPS64: [[CMPDONE]]:
+; MIPS64: {{^[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP]], [[RMW]]
+; MIPS32-LABEL: udec_wrap_i64:
+; MIPS32: {{^[ \t]+}}jal __atomic_load_8
+; MIPS32: [[RETRY:\$BB[0-9]+_[0-9]+]]:
+; MIPS32: {{^[ \t]+}}sw ${{[0-9]+}}, [[#EXPECTED:]]($sp)
+; MIPS32-NEXT: {{[ \t]+}}sw ${{[0-9]+}}, [[#EXPECTED + 4]]($sp)
+; MIPS32: {{^[ \t]+}}jal __atomic_compare_exchange_8
+; MIPS32R2: {{^[ \t]+}}move $[[SUCCESS:[0-9]+]], $2
+; MIPS32: {{^[ \t]+}}lw ${{[0-9]+}}, [[#EXPECTED + 4]]($sp)
+; MIPS32R2: {{^[ \t]+}}beqz $[[SUCCESS]], [[RETRY]]
+; MIPS32R2-NEXT: {{[ \t]+}}lw ${{[0-9]+}}, [[#EXPECTED]]($sp)
+; MIPS32R6: {{^[ \t]+}}lw ${{[0-9]+}}, [[#EXPECTED]]($sp)
+; MIPS32R6: {{^[ \t]+}}beqzc $2, [[RETRY]]
+ %old = atomicrmw udec_wrap ptr %ptr, i64 %value seq_cst
+ ret i64 %old
+}
+
+define i64 @usub_cond_i64(ptr %ptr, i64 %value) {
+; MIPS64-LABEL: usub_cond_i64:
+; MIPS64: [[RMW:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; MIPS64: [[LLSC:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; MIPS64: {{^[ \t]+}}lld $[[OLD:[0-9]+]], 0($[[PTR:[0-9]+]])
+; MIPS64-NEXT: {{[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP:[0-9]+]], [[CMPDONE:(\$BB|\.LBB)[0-9]+_[0-9]+]]
+; MIPS64-NOT: {{^[ \t]+s[bhwd]([lr]|c[0-3])?[ \t]}}
+; MIPS64: {{^[ \t]+}}scd $[[SC:[0-9]+]], 0($[[PTR]])
+; MIPS64-NEXT: {{[ \t]+}}beqz{{c?}} $[[SC]], [[LLSC]]
+; MIPS64: [[CMPDONE]]:
+; MIPS64: {{^[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP]], [[RMW]]
+; MIPS32-LABEL: usub_cond_i64:
+; MIPS32: {{^[ \t]+}}jal __atomic_load_8
+; MIPS32: [[RETRY:\$BB[0-9]+_[0-9]+]]:
+; MIPS32: {{^[ \t]+}}sw ${{[0-9]+}}, [[#EXPECTED:]]($sp)
+; MIPS32-NEXT: {{[ \t]+}}sw ${{[0-9]+}}, [[#EXPECTED + 4]]($sp)
+; MIPS32: {{^[ \t]+}}jal __atomic_compare_exchange_8
+; MIPS32: {{^[ \t]+}}lw ${{[0-9]+}}, [[#EXPECTED + 4]]($sp)
+; MIPS32R2: {{^[ \t]+}}beqz $2, [[RETRY]]
+; MIPS32R2-NEXT: {{[ \t]+}}lw ${{[0-9]+}}, [[#EXPECTED]]($sp)
+; MIPS32R6: {{^[ \t]+}}lw ${{[0-9]+}}, [[#EXPECTED]]($sp)
+; MIPS32R6: {{^[ \t]+}}beqzc $2, [[RETRY]]
+ %old = atomicrmw usub_cond ptr %ptr, i64 %value seq_cst
+ ret i64 %old
+}
+
+define i64 @usub_sat_i64(ptr %ptr, i64 %value) {
+; MIPS64-LABEL: usub_sat_i64:
+; MIPS64: [[RMW:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; MIPS64: [[LLSC:(\$BB|\.LBB)[0-9]+_[0-9]+]]:
+; MIPS64: {{^[ \t]+}}lld $[[OLD:[0-9]+]], 0($[[PTR:[0-9]+]])
+; MIPS64-NEXT: {{[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP:[0-9]+]], [[CMPDONE:(\$BB|\.LBB)[0-9]+_[0-9]+]]
+; MIPS64-NOT: {{^[ \t]+s[bhwd]([lr]|c[0-3])?[ \t]}}
+; MIPS64: {{^[ \t]+}}scd $[[SC:[0-9]+]], 0($[[PTR]])
+; MIPS64-NEXT: {{[ \t]+}}beqz{{c?}} $[[SC]], [[LLSC]]
+; MIPS64: [[CMPDONE]]:
+; MIPS64: {{^[ \t]+}}bne{{c?}} $[[OLD]], $[[CMP]], [[RMW]]
+; MIPS32-LABEL: usub_sat_i64:
+; MIPS32: {{^[ \t]+}}jal __atomic_load_8
+; MIPS32: [[RETRY:\$BB[0-9]+_[0-9]+]]:
+; MIPS32: {{^[ \t]+}}sw ${{[0-9]+}}, [[#EXPECTED:]]($sp)
+; MIPS32-NEXT: {{[ \t]+}}sw ${{[0-9]+}}, [[#EXPECTED + 4]]($sp)
+; MIPS32: {{^[ \t]+}}jal __atomic_compare_exchange_8
+; MIPS32R2: {{^[ \t]+}}move $[[SUCCESS:[0-9]+]], $2
+; MIPS32: {{^[ \t]+}}lw ${{[0-9]+}}, [[#EXPECTED + 4]]($sp)
+; MIPS32R2: {{^[ \t]+}}beqz $[[SUCCESS]], [[RETRY]]
+; MIPS32R2-NEXT: {{[ \t]+}}lw ${{[0-9]+}}, [[#EXPECTED]]($sp)
+; MIPS32R6: {{^[ \t]+}}lw ${{[0-9]+}}, [[#EXPECTED]]($sp)
+; MIPS32R6: {{^[ \t]+}}beqzc $2, [[RETRY]]
+ %old = atomicrmw usub_sat ptr %ptr, i64 %value seq_cst
+ ret i64 %old
+}
diff --git a/llvm/test/Transforms/AtomicExpand/Mips/atomicrmw-integer.ll b/llvm/test/Transforms/AtomicExpand/Mips/atomicrmw-integer.ll
new file mode 100644
index 00000000000000..540598c364414d
--- /dev/null
+++ b/llvm/test/Transforms/AtomicExpand/Mips/atomicrmw-integer.ll
@@ -0,0 +1,475 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -mtriple=mips64el -mcpu=mips64r2 -passes='require<libcall-lowering-info>,atomic-expand' %s | FileCheck %s
+; These operations require cmpxchg expansion at every width.
+
+define i8 @uinc_wrap_i8(ptr %ptr, i8 %value) {
+; CHECK-LABEL: @uinc_wrap_i8(
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
+; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
+; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
+; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; CHECK-NEXT: [[TMP3:%.*]] = load atomic i32, ptr [[ALIGNEDADDR]] monotonic, align 4
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; CHECK-NEXT: [[TMP4:%.*]] = add i8 [[EXTRACTED]], 1
+; CHECK-NEXT: [[TMP5:%.*]] = icmp uge i8 [[EXTRACTED]], [[VALUE:%.*]]
+; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP5]], i8 0, i8 [[TMP4]]
+; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32
+; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
+; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
+; CHECK-NEXT: [[TMP6:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] monotonic monotonic, align 4
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
+; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: ret i8 [[EXTRACTED3]]
+;
+ %old = atomicrmw uinc_wrap ptr %ptr, i8 %value seq_cst
+ ret i8 %old
+}
+
+define i8 @udec_wrap_i8(ptr %ptr, i8 %value) {
+; CHECK-LABEL: @udec_wrap_i8(
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
+; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
+; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
+; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; CHECK-NEXT: [[TMP3:%.*]] = load atomic i32, ptr [[ALIGNEDADDR]] monotonic, align 4
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; CHECK-NEXT: [[TMP4:%.*]] = sub i8 [[EXTRACTED]], 1
+; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[EXTRACTED]], 0
+; CHECK-NEXT: [[TMP6:%.*]] = icmp ugt i8 [[EXTRACTED]], [[VALUE:%.*]]
+; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP5]], [[TMP6]]
+; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP7]], i8 [[VALUE]], i8 [[TMP4]]
+; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32
+; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
+; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
+; CHECK-NEXT: [[TMP8:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] monotonic monotonic, align 4
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1
+; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP8]], 0
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: ret i8 [[EXTRACTED3]]
+;
+ %old = atomicrmw udec_wrap ptr %ptr, i8 %value seq_cst
+ ret i8 %old
+}
+
+define i8 @usub_cond_i8(ptr %ptr, i8 %value) {
+; CHECK-LABEL: @usub_cond_i8(
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
+; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
+; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
+; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; CHECK-NEXT: [[TMP3:%.*]] = load atomic i32, ptr [[ALIGNEDADDR]] monotonic, align 4
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; CHECK-NEXT: [[TMP4:%.*]] = icmp uge i8 [[EXTRACTED]], [[VALUE:%.*]]
+; CHECK-NEXT: [[TMP5:%.*]] = sub i8 [[EXTRACTED]], [[VALUE]]
+; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP4]], i8 [[TMP5]], i8 [[EXTRACTED]]
+; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32
+; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
+; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
+; CHECK-NEXT: [[TMP6:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] monotonic monotonic, align 4
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
+; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: ret i8 [[EXTRACTED3]]
+;
+ %old = atomicrmw usub_cond ptr %ptr, i8 %value seq_cst
+ ret i8 %old
+}
+
+define i8 @usub_sat_i8(ptr %ptr, i8 %value) {
+; CHECK-LABEL: @usub_sat_i8(
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
+; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
+; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
+; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; CHECK-NEXT: [[TMP3:%.*]] = load atomic i32, ptr [[ALIGNEDADDR]] monotonic, align 4
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; CHECK-NEXT: [[NEW:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[EXTRACTED]], i8 [[VALUE:%.*]])
+; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32
+; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
+; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
+; CHECK-NEXT: [[TMP4:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] monotonic monotonic, align 4
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
+; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP4]], 0
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: ret i8 [[EXTRACTED3]]
+;
+ %old = atomicrmw usub_sat ptr %ptr, i8 %value seq_cst
+ ret i8 %old
+}
+
+define i16 @uinc_wrap_i16(ptr %ptr, i16 %value) {
+; CHECK-LABEL: @uinc_wrap_i16(
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
+; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
+; CHECK-NEXT: [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
+; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; CHECK-NEXT: [[TMP3:%.*]] = load atomic i32, ptr [[ALIGNEDADDR]] monotonic, align 4
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; CHECK-NEXT: [[TMP4:%.*]] = add i16 [[EXTRACTED]], 1
+; CHECK-NEXT: [[TMP5:%.*]] = icmp uge i16 [[EXTRACTED]], [[VALUE:%.*]]
+; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP5]], i16 0, i16 [[TMP4]]
+; CHECK-NEXT: [[EXTENDED:%.*]] = zext i16 [[NEW]] to i32
+; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
+; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
+; CHECK-NEXT: [[TMP6:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] monotonic monotonic, align 4
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
+; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i16
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: ret i16 [[EXTRACTED3]]
+;
+ %old = atomicrmw uinc_wrap ptr %ptr, i16 %value seq_cst
+ ret i16 %old
+}
+
+define i16 @udec_wrap_i16(ptr %ptr, i16 %value) {
+; CHECK-LABEL: @udec_wrap_i16(
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
+; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
+; CHECK-NEXT: [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
+; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; CHECK-NEXT: [[TMP3:%.*]] = load atomic i32, ptr [[ALIGNEDADDR]] monotonic, align 4
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; CHECK-NEXT: [[TMP4:%.*]] = sub i16 [[EXTRACTED]], 1
+; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i16 [[EXTRACTED]], 0
+; CHECK-NEXT: [[TMP6:%.*]] = icmp ugt i16 [[EXTRACTED]], [[VALUE:%.*]]
+; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP5]], [[TMP6]]
+; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP7]], i16 [[VALUE]], i16 [[TMP4]]
+; CHECK-NEXT: [[EXTENDED:%.*]] = zext i16 [[NEW]] to i32
+; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
+; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
+; CHECK-NEXT: [[TMP8:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] monotonic monotonic, align 4
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1
+; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP8]], 0
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i16
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: ret i16 [[EXTRACTED3]]
+;
+ %old = atomicrmw udec_wrap ptr %ptr, i16 %value seq_cst
+ ret i16 %old
+}
+
+define i16 @usub_cond_i16(ptr %ptr, i16 %value) {
+; CHECK-LABEL: @usub_cond_i16(
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
+; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
+; CHECK-NEXT: [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
+; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; CHECK-NEXT: [[TMP3:%.*]] = load atomic i32, ptr [[ALIGNEDADDR]] monotonic, align 4
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; CHECK-NEXT: [[TMP4:%.*]] = icmp uge i16 [[EXTRACTED]], [[VALUE:%.*]]
+; CHECK-NEXT: [[TMP5:%.*]] = sub i16 [[EXTRACTED]], [[VALUE]]
+; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP4]], i16 [[TMP5]], i16 [[EXTRACTED]]
+; CHECK-NEXT: [[EXTENDED:%.*]] = zext i16 [[NEW]] to i32
+; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
+; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
+; CHECK-NEXT: [[TMP6:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] monotonic monotonic, align 4
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
+; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i16
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: ret i16 [[EXTRACTED3]]
+;
+ %old = atomicrmw usub_cond ptr %ptr, i16 %value seq_cst
+ ret i16 %old
+}
+
+define i16 @usub_sat_i16(ptr %ptr, i16 %value) {
+; CHECK-LABEL: @usub_sat_i16(
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
+; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
+; CHECK-NEXT: [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
+; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; CHECK-NEXT: [[TMP3:%.*]] = load atomic i32, ptr [[ALIGNEDADDR]] monotonic, align 4
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; CHECK-NEXT: [[NEW:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[EXTRACTED]], i16 [[VALUE:%.*]])
+; CHECK-NEXT: [[EXTENDED:%.*]] = zext i16 [[NEW]] to i32
+; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]]
+; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]]
+; CHECK-NEXT: [[TMP4:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] monotonic monotonic, align 4
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
+; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP4]], 0
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]]
+; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i16
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: ret i16 [[EXTRACTED3]]
+;
+ %old = atomicrmw usub_sat ptr %ptr, i16 %value seq_cst
+ ret i16 %old
+}
+
+define i32 @uinc_wrap_i32(ptr %ptr, i32 %value) {
+; CHECK-LABEL: @uinc_wrap_i32(
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: [[TMP1:%.*]] = load atomic i32, ptr [[PTR:%.*]] monotonic, align 4
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[LOADED]], 1
+; CHECK-NEXT: [[TMP3:%.*]] = icmp uge i32 [[LOADED]], [[VALUE:%.*]]
+; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
+; CHECK-NEXT: [[TMP4:%.*]] = cmpxchg ptr [[PTR]], i32 [[LOADED]], i32 [[NEW]] monotonic monotonic, align 4
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
+; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP4]], 0
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: ret i32 [[NEWLOADED]]
+;
+ %old = atomicrmw uinc_wrap ptr %ptr, i32 %value seq_cst
+ ret i32 %old
+}
+
+define i32 @udec_wrap_i32(ptr %ptr, i32 %value) {
+; CHECK-LABEL: @udec_wrap_i32(
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: [[TMP1:%.*]] = load atomic i32, ptr [[PTR:%.*]] monotonic, align 4
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[LOADED]], 1
+; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[LOADED]], 0
+; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt i32 [[LOADED]], [[VALUE:%.*]]
+; CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP3]], [[TMP4]]
+; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP5]], i32 [[VALUE]], i32 [[TMP2]]
+; CHECK-NEXT: [[TMP6:%.*]] = cmpxchg ptr [[PTR]], i32 [[LOADED]], i32 [[NEW]] monotonic monotonic, align 4
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1
+; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: ret i32 [[NEWLOADED]]
+;
+ %old = atomicrmw udec_wrap ptr %ptr, i32 %value seq_cst
+ ret i32 %old
+}
+
+define i32 @usub_cond_i32(ptr %ptr, i32 %value) {
+; CHECK-LABEL: @usub_cond_i32(
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: [[TMP1:%.*]] = load atomic i32, ptr [[PTR:%.*]] monotonic, align 4
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i32 [[LOADED]], [[VALUE:%.*]]
+; CHECK-NEXT: [[TMP3:%.*]] = sub i32 [[LOADED]], [[VALUE]]
+; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 [[LOADED]]
+; CHECK-NEXT: [[TMP4:%.*]] = cmpxchg ptr [[PTR]], i32 [[LOADED]], i32 [[NEW]] monotonic monotonic, align 4
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
+; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP4]], 0
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: ret i32 [[NEWLOADED]]
+;
+ %old = atomicrmw usub_cond ptr %ptr, i32 %value seq_cst
+ ret i32 %old
+}
+
+define i32 @usub_sat_i32(ptr %ptr, i32 %value) {
+; CHECK-LABEL: @usub_sat_i32(
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: [[TMP1:%.*]] = load atomic i32, ptr [[PTR:%.*]] monotonic, align 4
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[NEW:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[LOADED]], i32 [[VALUE:%.*]])
+; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg ptr [[PTR]], i32 [[LOADED]], i32 [[NEW]] monotonic monotonic, align 4
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
+; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP2]], 0
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: ret i32 [[NEWLOADED]]
+;
+ %old = atomicrmw usub_sat ptr %ptr, i32 %value seq_cst
+ ret i32 %old
+}
+
+define i64 @uinc_wrap_i64(ptr %ptr, i64 %value) {
+; CHECK-LABEL: @uinc_wrap_i64(
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: [[TMP1:%.*]] = load atomic i64, ptr [[PTR:%.*]] monotonic, align 8
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[LOADED]], 1
+; CHECK-NEXT: [[TMP3:%.*]] = icmp uge i64 [[LOADED]], [[VALUE:%.*]]
+; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP3]], i64 0, i64 [[TMP2]]
+; CHECK-NEXT: [[TMP4:%.*]] = cmpxchg ptr [[PTR]], i64 [[LOADED]], i64 [[NEW]] monotonic monotonic, align 8
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP4]], 1
+; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP4]], 0
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: ret i64 [[NEWLOADED]]
+;
+ %old = atomicrmw uinc_wrap ptr %ptr, i64 %value seq_cst
+ ret i64 %old
+}
+
+define i64 @udec_wrap_i64(ptr %ptr, i64 %value) {
+; CHECK-LABEL: @udec_wrap_i64(
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: [[TMP1:%.*]] = load atomic i64, ptr [[PTR:%.*]] monotonic, align 8
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[LOADED]], 1
+; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i64 [[LOADED]], 0
+; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt i64 [[LOADED]], [[VALUE:%.*]]
+; CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP3]], [[TMP4]]
+; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP5]], i64 [[VALUE]], i64 [[TMP2]]
+; CHECK-NEXT: [[TMP6:%.*]] = cmpxchg ptr [[PTR]], i64 [[LOADED]], i64 [[NEW]] monotonic monotonic, align 8
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP6]], 1
+; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP6]], 0
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: ret i64 [[NEWLOADED]]
+;
+ %old = atomicrmw udec_wrap ptr %ptr, i64 %value seq_cst
+ ret i64 %old
+}
+
+define i64 @usub_cond_i64(ptr %ptr, i64 %value) {
+; CHECK-LABEL: @usub_cond_i64(
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: [[TMP1:%.*]] = load atomic i64, ptr [[PTR:%.*]] monotonic, align 8
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[LOADED]], [[VALUE:%.*]]
+; CHECK-NEXT: [[TMP3:%.*]] = sub i64 [[LOADED]], [[VALUE]]
+; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP2]], i64 [[TMP3]], i64 [[LOADED]]
+; CHECK-NEXT: [[TMP4:%.*]] = cmpxchg ptr [[PTR]], i64 [[LOADED]], i64 [[NEW]] monotonic monotonic, align 8
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP4]], 1
+; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP4]], 0
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: ret i64 [[NEWLOADED]]
+;
+ %old = atomicrmw usub_cond ptr %ptr, i64 %value seq_cst
+ ret i64 %old
+}
+
+define i64 @usub_sat_i64(ptr %ptr, i64 %value) {
+; CHECK-LABEL: @usub_sat_i64(
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: [[TMP1:%.*]] = load atomic i64, ptr [[PTR:%.*]] monotonic, align 8
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi i64 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[NEW:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[LOADED]], i64 [[VALUE:%.*]])
+; CHECK-NEXT: [[TMP2:%.*]] = cmpxchg ptr [[PTR]], i64 [[LOADED]], i64 [[NEW]] monotonic monotonic, align 8
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP2]], 1
+; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i64, i1 } [[TMP2]], 0
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: ret i64 [[NEWLOADED]]
+;
+ %old = atomicrmw usub_sat ptr %ptr, i64 %value seq_cst
+ ret i64 %old
+}
diff --git a/llvm/test/Transforms/AtomicExpand/Mips/masked-atomics.ll b/llvm/test/Transforms/AtomicExpand/Mips/masked-atomics.ll
new file mode 100644
index 00000000000000..6164403b64536c
--- /dev/null
+++ b/llvm/test/Transforms/AtomicExpand/Mips/masked-atomics.ll
@@ -0,0 +1,1264 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -mtriple=mipsel-unknown-linux-gnu -passes='require<libcall-lowering-info>,atomic-expand' %s | FileCheck %s --check-prefix=LE32
+; RUN: opt -S -mtriple=mips-unknown-linux-gnu -passes='require<libcall-lowering-info>,atomic-expand' %s | FileCheck %s --check-prefix=BE32
+; RUN: opt -S -mtriple=mips64el-unknown-linux-gnu -passes='require<libcall-lowering-info>,atomic-expand' %s | FileCheck %s --check-prefix=LE64
+; RUN: opt -S -mtriple=mips64-unknown-linux-gnu -passes='require<libcall-lowering-info>,atomic-expand' %s | FileCheck %s --check-prefix=BE64
+
+; Bitwise RMWs widen to i32; other supported RMWs use masked intrinsics.
+
+define i8 @add_i8(ptr %ptr, i8 %val) {
+; LE32-LABEL: @add_i8(
+; LE32-NEXT: fence seq_cst
+; LE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; LE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; LE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; LE32-NEXT: [[TMP2:%.*]] = shl i32 [[PTRLSB]], 3
+; LE32-NEXT: [[MASK:%.*]] = shl i32 255, [[TMP2]]
+; LE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE32-NEXT: [[TMP3:%.*]] = zext i8 [[VAL:%.*]] to i32
+; LE32-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[TMP2]]
+; LE32-NEXT: [[TMP5:%.*]] = call i32 @llvm.mips.masked.atomicrmw.add.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; LE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP5]], [[TMP2]]
+; LE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; LE32-NEXT: fence seq_cst
+; LE32-NEXT: ret i8 [[EXTRACTED]]
+;
+; BE32-LABEL: @add_i8(
+; BE32-NEXT: fence seq_cst
+; BE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; BE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; BE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; BE32-NEXT: [[TMP2:%.*]] = xor i32 [[PTRLSB]], 3
+; BE32-NEXT: [[TMP3:%.*]] = shl i32 [[TMP2]], 3
+; BE32-NEXT: [[MASK:%.*]] = shl i32 255, [[TMP3]]
+; BE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE32-NEXT: [[TMP4:%.*]] = zext i8 [[VAL:%.*]] to i32
+; BE32-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP4]], [[TMP3]]
+; BE32-NEXT: [[TMP6:%.*]] = call i32 @llvm.mips.masked.atomicrmw.add.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; BE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP6]], [[TMP3]]
+; BE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; BE32-NEXT: fence seq_cst
+; BE32-NEXT: ret i8 [[EXTRACTED]]
+;
+; LE64-LABEL: @add_i8(
+; LE64-NEXT: fence seq_cst
+; LE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; LE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; LE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; LE64-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
+; LE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
+; LE64-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
+; LE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE64-NEXT: [[TMP3:%.*]] = zext i8 [[VAL:%.*]] to i32
+; LE64-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
+; LE64-NEXT: [[TMP5:%.*]] = call i32 @llvm.mips.masked.atomicrmw.add.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; LE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP5]], [[SHIFTAMT]]
+; LE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; LE64-NEXT: fence seq_cst
+; LE64-NEXT: ret i8 [[EXTRACTED]]
+;
+; BE64-LABEL: @add_i8(
+; BE64-NEXT: fence seq_cst
+; BE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; BE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; BE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; BE64-NEXT: [[TMP2:%.*]] = xor i64 [[PTRLSB]], 3
+; BE64-NEXT: [[TMP3:%.*]] = shl i64 [[TMP2]], 3
+; BE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP3]] to i32
+; BE64-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
+; BE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE64-NEXT: [[TMP4:%.*]] = zext i8 [[VAL:%.*]] to i32
+; BE64-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP4]], [[SHIFTAMT]]
+; BE64-NEXT: [[TMP6:%.*]] = call i32 @llvm.mips.masked.atomicrmw.add.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; BE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP6]], [[SHIFTAMT]]
+; BE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; BE64-NEXT: fence seq_cst
+; BE64-NEXT: ret i8 [[EXTRACTED]]
+;
+ %old = atomicrmw add ptr %ptr, i8 %val seq_cst
+ ret i8 %old
+}
+
+define i16 @sub_i16(ptr %ptr, i16 %val) {
+; LE32-LABEL: @sub_i16(
+; LE32-NEXT: fence seq_cst
+; LE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; LE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; LE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; LE32-NEXT: [[TMP2:%.*]] = shl i32 [[PTRLSB]], 3
+; LE32-NEXT: [[MASK:%.*]] = shl i32 65535, [[TMP2]]
+; LE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE32-NEXT: [[TMP3:%.*]] = zext i16 [[VAL:%.*]] to i32
+; LE32-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[TMP2]]
+; LE32-NEXT: [[TMP5:%.*]] = call i32 @llvm.mips.masked.atomicrmw.sub.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; LE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP5]], [[TMP2]]
+; LE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; LE32-NEXT: fence seq_cst
+; LE32-NEXT: ret i16 [[EXTRACTED]]
+;
+; BE32-LABEL: @sub_i16(
+; BE32-NEXT: fence seq_cst
+; BE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; BE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; BE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; BE32-NEXT: [[TMP2:%.*]] = xor i32 [[PTRLSB]], 2
+; BE32-NEXT: [[TMP3:%.*]] = shl i32 [[TMP2]], 3
+; BE32-NEXT: [[MASK:%.*]] = shl i32 65535, [[TMP3]]
+; BE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE32-NEXT: [[TMP4:%.*]] = zext i16 [[VAL:%.*]] to i32
+; BE32-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP4]], [[TMP3]]
+; BE32-NEXT: [[TMP6:%.*]] = call i32 @llvm.mips.masked.atomicrmw.sub.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; BE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP6]], [[TMP3]]
+; BE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; BE32-NEXT: fence seq_cst
+; BE32-NEXT: ret i16 [[EXTRACTED]]
+;
+; LE64-LABEL: @sub_i16(
+; LE64-NEXT: fence seq_cst
+; LE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; LE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; LE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; LE64-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
+; LE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
+; LE64-NEXT: [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
+; LE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE64-NEXT: [[TMP3:%.*]] = zext i16 [[VAL:%.*]] to i32
+; LE64-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
+; LE64-NEXT: [[TMP5:%.*]] = call i32 @llvm.mips.masked.atomicrmw.sub.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; LE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP5]], [[SHIFTAMT]]
+; LE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; LE64-NEXT: fence seq_cst
+; LE64-NEXT: ret i16 [[EXTRACTED]]
+;
+; BE64-LABEL: @sub_i16(
+; BE64-NEXT: fence seq_cst
+; BE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; BE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; BE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; BE64-NEXT: [[TMP2:%.*]] = xor i64 [[PTRLSB]], 2
+; BE64-NEXT: [[TMP3:%.*]] = shl i64 [[TMP2]], 3
+; BE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP3]] to i32
+; BE64-NEXT: [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
+; BE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE64-NEXT: [[TMP4:%.*]] = zext i16 [[VAL:%.*]] to i32
+; BE64-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP4]], [[SHIFTAMT]]
+; BE64-NEXT: [[TMP6:%.*]] = call i32 @llvm.mips.masked.atomicrmw.sub.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; BE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP6]], [[SHIFTAMT]]
+; BE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; BE64-NEXT: fence seq_cst
+; BE64-NEXT: ret i16 [[EXTRACTED]]
+;
+ %old = atomicrmw sub ptr %ptr, i16 %val seq_cst
+ ret i16 %old
+}
+
+define i8 @xchg_i8(ptr %ptr, i8 %val) {
+; LE32-LABEL: @xchg_i8(
+; LE32-NEXT: fence seq_cst
+; LE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; LE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; LE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; LE32-NEXT: [[TMP2:%.*]] = shl i32 [[PTRLSB]], 3
+; LE32-NEXT: [[MASK:%.*]] = shl i32 255, [[TMP2]]
+; LE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE32-NEXT: [[TMP3:%.*]] = zext i8 [[VAL:%.*]] to i32
+; LE32-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[TMP2]]
+; LE32-NEXT: [[TMP5:%.*]] = call i32 @llvm.mips.masked.atomicrmw.xchg.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; LE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP5]], [[TMP2]]
+; LE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; LE32-NEXT: fence seq_cst
+; LE32-NEXT: ret i8 [[EXTRACTED]]
+;
+; BE32-LABEL: @xchg_i8(
+; BE32-NEXT: fence seq_cst
+; BE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; BE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; BE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; BE32-NEXT: [[TMP2:%.*]] = xor i32 [[PTRLSB]], 3
+; BE32-NEXT: [[TMP3:%.*]] = shl i32 [[TMP2]], 3
+; BE32-NEXT: [[MASK:%.*]] = shl i32 255, [[TMP3]]
+; BE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE32-NEXT: [[TMP4:%.*]] = zext i8 [[VAL:%.*]] to i32
+; BE32-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP4]], [[TMP3]]
+; BE32-NEXT: [[TMP6:%.*]] = call i32 @llvm.mips.masked.atomicrmw.xchg.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; BE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP6]], [[TMP3]]
+; BE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; BE32-NEXT: fence seq_cst
+; BE32-NEXT: ret i8 [[EXTRACTED]]
+;
+; LE64-LABEL: @xchg_i8(
+; LE64-NEXT: fence seq_cst
+; LE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; LE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; LE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; LE64-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
+; LE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
+; LE64-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
+; LE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE64-NEXT: [[TMP3:%.*]] = zext i8 [[VAL:%.*]] to i32
+; LE64-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
+; LE64-NEXT: [[TMP5:%.*]] = call i32 @llvm.mips.masked.atomicrmw.xchg.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; LE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP5]], [[SHIFTAMT]]
+; LE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; LE64-NEXT: fence seq_cst
+; LE64-NEXT: ret i8 [[EXTRACTED]]
+;
+; BE64-LABEL: @xchg_i8(
+; BE64-NEXT: fence seq_cst
+; BE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; BE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; BE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; BE64-NEXT: [[TMP2:%.*]] = xor i64 [[PTRLSB]], 3
+; BE64-NEXT: [[TMP3:%.*]] = shl i64 [[TMP2]], 3
+; BE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP3]] to i32
+; BE64-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
+; BE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE64-NEXT: [[TMP4:%.*]] = zext i8 [[VAL:%.*]] to i32
+; BE64-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP4]], [[SHIFTAMT]]
+; BE64-NEXT: [[TMP6:%.*]] = call i32 @llvm.mips.masked.atomicrmw.xchg.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; BE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP6]], [[SHIFTAMT]]
+; BE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; BE64-NEXT: fence seq_cst
+; BE64-NEXT: ret i8 [[EXTRACTED]]
+;
+ %old = atomicrmw xchg ptr %ptr, i8 %val seq_cst
+ ret i8 %old
+}
+
+define i16 @nand_i16(ptr %ptr, i16 %val) {
+; LE32-LABEL: @nand_i16(
+; LE32-NEXT: fence seq_cst
+; LE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; LE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; LE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; LE32-NEXT: [[TMP2:%.*]] = shl i32 [[PTRLSB]], 3
+; LE32-NEXT: [[MASK:%.*]] = shl i32 65535, [[TMP2]]
+; LE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE32-NEXT: [[TMP3:%.*]] = zext i16 [[VAL:%.*]] to i32
+; LE32-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[TMP2]]
+; LE32-NEXT: [[TMP5:%.*]] = call i32 @llvm.mips.masked.atomicrmw.nand.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; LE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP5]], [[TMP2]]
+; LE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; LE32-NEXT: fence seq_cst
+; LE32-NEXT: ret i16 [[EXTRACTED]]
+;
+; BE32-LABEL: @nand_i16(
+; BE32-NEXT: fence seq_cst
+; BE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; BE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; BE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; BE32-NEXT: [[TMP2:%.*]] = xor i32 [[PTRLSB]], 2
+; BE32-NEXT: [[TMP3:%.*]] = shl i32 [[TMP2]], 3
+; BE32-NEXT: [[MASK:%.*]] = shl i32 65535, [[TMP3]]
+; BE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE32-NEXT: [[TMP4:%.*]] = zext i16 [[VAL:%.*]] to i32
+; BE32-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP4]], [[TMP3]]
+; BE32-NEXT: [[TMP6:%.*]] = call i32 @llvm.mips.masked.atomicrmw.nand.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; BE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP6]], [[TMP3]]
+; BE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; BE32-NEXT: fence seq_cst
+; BE32-NEXT: ret i16 [[EXTRACTED]]
+;
+; LE64-LABEL: @nand_i16(
+; LE64-NEXT: fence seq_cst
+; LE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; LE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; LE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; LE64-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
+; LE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
+; LE64-NEXT: [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
+; LE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE64-NEXT: [[TMP3:%.*]] = zext i16 [[VAL:%.*]] to i32
+; LE64-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
+; LE64-NEXT: [[TMP5:%.*]] = call i32 @llvm.mips.masked.atomicrmw.nand.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; LE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP5]], [[SHIFTAMT]]
+; LE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; LE64-NEXT: fence seq_cst
+; LE64-NEXT: ret i16 [[EXTRACTED]]
+;
+; BE64-LABEL: @nand_i16(
+; BE64-NEXT: fence seq_cst
+; BE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; BE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; BE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; BE64-NEXT: [[TMP2:%.*]] = xor i64 [[PTRLSB]], 2
+; BE64-NEXT: [[TMP3:%.*]] = shl i64 [[TMP2]], 3
+; BE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP3]] to i32
+; BE64-NEXT: [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
+; BE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE64-NEXT: [[TMP4:%.*]] = zext i16 [[VAL:%.*]] to i32
+; BE64-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP4]], [[SHIFTAMT]]
+; BE64-NEXT: [[TMP6:%.*]] = call i32 @llvm.mips.masked.atomicrmw.nand.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; BE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP6]], [[SHIFTAMT]]
+; BE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; BE64-NEXT: fence seq_cst
+; BE64-NEXT: ret i16 [[EXTRACTED]]
+;
+ %old = atomicrmw nand ptr %ptr, i16 %val seq_cst
+ ret i16 %old
+}
+
+define i8 @min_i8(ptr %ptr, i8 %val) {
+; LE32-LABEL: @min_i8(
+; LE32-NEXT: fence seq_cst
+; LE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; LE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; LE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; LE32-NEXT: [[TMP2:%.*]] = shl i32 [[PTRLSB]], 3
+; LE32-NEXT: [[MASK:%.*]] = shl i32 255, [[TMP2]]
+; LE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE32-NEXT: [[TMP3:%.*]] = sext i8 [[VAL:%.*]] to i32
+; LE32-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[TMP2]]
+; LE32-NEXT: [[TMP5:%.*]] = sub i32 24, [[TMP2]]
+; LE32-NEXT: [[TMP6:%.*]] = call i32 @llvm.mips.masked.atomicrmw.min.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]], i32 [[TMP5]])
+; LE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP6]], [[TMP2]]
+; LE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; LE32-NEXT: fence seq_cst
+; LE32-NEXT: ret i8 [[EXTRACTED]]
+;
+; BE32-LABEL: @min_i8(
+; BE32-NEXT: fence seq_cst
+; BE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; BE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; BE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; BE32-NEXT: [[TMP2:%.*]] = xor i32 [[PTRLSB]], 3
+; BE32-NEXT: [[TMP3:%.*]] = shl i32 [[TMP2]], 3
+; BE32-NEXT: [[MASK:%.*]] = shl i32 255, [[TMP3]]
+; BE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE32-NEXT: [[TMP4:%.*]] = sext i8 [[VAL:%.*]] to i32
+; BE32-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP4]], [[TMP3]]
+; BE32-NEXT: [[TMP6:%.*]] = sub i32 24, [[TMP3]]
+; BE32-NEXT: [[TMP7:%.*]] = call i32 @llvm.mips.masked.atomicrmw.min.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]], i32 [[TMP6]])
+; BE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP7]], [[TMP3]]
+; BE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; BE32-NEXT: fence seq_cst
+; BE32-NEXT: ret i8 [[EXTRACTED]]
+;
+; LE64-LABEL: @min_i8(
+; LE64-NEXT: fence seq_cst
+; LE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; LE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; LE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; LE64-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
+; LE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
+; LE64-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
+; LE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE64-NEXT: [[TMP3:%.*]] = sext i8 [[VAL:%.*]] to i32
+; LE64-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
+; LE64-NEXT: [[TMP5:%.*]] = sub i32 24, [[SHIFTAMT]]
+; LE64-NEXT: [[TMP6:%.*]] = call i32 @llvm.mips.masked.atomicrmw.min.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]], i32 [[TMP5]])
+; LE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP6]], [[SHIFTAMT]]
+; LE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; LE64-NEXT: fence seq_cst
+; LE64-NEXT: ret i8 [[EXTRACTED]]
+;
+; BE64-LABEL: @min_i8(
+; BE64-NEXT: fence seq_cst
+; BE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; BE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; BE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; BE64-NEXT: [[TMP2:%.*]] = xor i64 [[PTRLSB]], 3
+; BE64-NEXT: [[TMP3:%.*]] = shl i64 [[TMP2]], 3
+; BE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP3]] to i32
+; BE64-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
+; BE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE64-NEXT: [[TMP4:%.*]] = sext i8 [[VAL:%.*]] to i32
+; BE64-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP4]], [[SHIFTAMT]]
+; BE64-NEXT: [[TMP6:%.*]] = sub i32 24, [[SHIFTAMT]]
+; BE64-NEXT: [[TMP7:%.*]] = call i32 @llvm.mips.masked.atomicrmw.min.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]], i32 [[TMP6]])
+; BE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP7]], [[SHIFTAMT]]
+; BE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; BE64-NEXT: fence seq_cst
+; BE64-NEXT: ret i8 [[EXTRACTED]]
+;
+ %old = atomicrmw min ptr %ptr, i8 %val seq_cst
+ ret i8 %old
+}
+
+define i16 @max_i16(ptr %ptr, i16 %val) {
+; LE32-LABEL: @max_i16(
+; LE32-NEXT: fence seq_cst
+; LE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; LE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; LE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; LE32-NEXT: [[TMP2:%.*]] = shl i32 [[PTRLSB]], 3
+; LE32-NEXT: [[MASK:%.*]] = shl i32 65535, [[TMP2]]
+; LE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE32-NEXT: [[TMP3:%.*]] = sext i16 [[VAL:%.*]] to i32
+; LE32-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[TMP2]]
+; LE32-NEXT: [[TMP5:%.*]] = sub i32 16, [[TMP2]]
+; LE32-NEXT: [[TMP6:%.*]] = call i32 @llvm.mips.masked.atomicrmw.max.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]], i32 [[TMP5]])
+; LE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP6]], [[TMP2]]
+; LE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; LE32-NEXT: fence seq_cst
+; LE32-NEXT: ret i16 [[EXTRACTED]]
+;
+; BE32-LABEL: @max_i16(
+; BE32-NEXT: fence seq_cst
+; BE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; BE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; BE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; BE32-NEXT: [[TMP2:%.*]] = xor i32 [[PTRLSB]], 2
+; BE32-NEXT: [[TMP3:%.*]] = shl i32 [[TMP2]], 3
+; BE32-NEXT: [[MASK:%.*]] = shl i32 65535, [[TMP3]]
+; BE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE32-NEXT: [[TMP4:%.*]] = sext i16 [[VAL:%.*]] to i32
+; BE32-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP4]], [[TMP3]]
+; BE32-NEXT: [[TMP6:%.*]] = sub i32 16, [[TMP3]]
+; BE32-NEXT: [[TMP7:%.*]] = call i32 @llvm.mips.masked.atomicrmw.max.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]], i32 [[TMP6]])
+; BE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP7]], [[TMP3]]
+; BE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; BE32-NEXT: fence seq_cst
+; BE32-NEXT: ret i16 [[EXTRACTED]]
+;
+; LE64-LABEL: @max_i16(
+; LE64-NEXT: fence seq_cst
+; LE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; LE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; LE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; LE64-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
+; LE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
+; LE64-NEXT: [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
+; LE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE64-NEXT: [[TMP3:%.*]] = sext i16 [[VAL:%.*]] to i32
+; LE64-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
+; LE64-NEXT: [[TMP5:%.*]] = sub i32 16, [[SHIFTAMT]]
+; LE64-NEXT: [[TMP6:%.*]] = call i32 @llvm.mips.masked.atomicrmw.max.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]], i32 [[TMP5]])
+; LE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP6]], [[SHIFTAMT]]
+; LE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; LE64-NEXT: fence seq_cst
+; LE64-NEXT: ret i16 [[EXTRACTED]]
+;
+; BE64-LABEL: @max_i16(
+; BE64-NEXT: fence seq_cst
+; BE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; BE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; BE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; BE64-NEXT: [[TMP2:%.*]] = xor i64 [[PTRLSB]], 2
+; BE64-NEXT: [[TMP3:%.*]] = shl i64 [[TMP2]], 3
+; BE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP3]] to i32
+; BE64-NEXT: [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
+; BE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE64-NEXT: [[TMP4:%.*]] = sext i16 [[VAL:%.*]] to i32
+; BE64-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP4]], [[SHIFTAMT]]
+; BE64-NEXT: [[TMP6:%.*]] = sub i32 16, [[SHIFTAMT]]
+; BE64-NEXT: [[TMP7:%.*]] = call i32 @llvm.mips.masked.atomicrmw.max.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]], i32 [[TMP6]])
+; BE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP7]], [[SHIFTAMT]]
+; BE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; BE64-NEXT: fence seq_cst
+; BE64-NEXT: ret i16 [[EXTRACTED]]
+;
+ %old = atomicrmw max ptr %ptr, i16 %val seq_cst
+ ret i16 %old
+}
+
+define i8 @umin_i8(ptr %ptr, i8 %val) {
+; LE32-LABEL: @umin_i8(
+; LE32-NEXT: fence seq_cst
+; LE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; LE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; LE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; LE32-NEXT: [[TMP2:%.*]] = shl i32 [[PTRLSB]], 3
+; LE32-NEXT: [[MASK:%.*]] = shl i32 255, [[TMP2]]
+; LE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE32-NEXT: [[TMP3:%.*]] = zext i8 [[VAL:%.*]] to i32
+; LE32-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[TMP2]]
+; LE32-NEXT: [[TMP5:%.*]] = call i32 @llvm.mips.masked.atomicrmw.umin.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; LE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP5]], [[TMP2]]
+; LE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; LE32-NEXT: fence seq_cst
+; LE32-NEXT: ret i8 [[EXTRACTED]]
+;
+; BE32-LABEL: @umin_i8(
+; BE32-NEXT: fence seq_cst
+; BE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; BE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; BE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; BE32-NEXT: [[TMP2:%.*]] = xor i32 [[PTRLSB]], 3
+; BE32-NEXT: [[TMP3:%.*]] = shl i32 [[TMP2]], 3
+; BE32-NEXT: [[MASK:%.*]] = shl i32 255, [[TMP3]]
+; BE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE32-NEXT: [[TMP4:%.*]] = zext i8 [[VAL:%.*]] to i32
+; BE32-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP4]], [[TMP3]]
+; BE32-NEXT: [[TMP6:%.*]] = call i32 @llvm.mips.masked.atomicrmw.umin.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; BE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP6]], [[TMP3]]
+; BE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; BE32-NEXT: fence seq_cst
+; BE32-NEXT: ret i8 [[EXTRACTED]]
+;
+; LE64-LABEL: @umin_i8(
+; LE64-NEXT: fence seq_cst
+; LE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; LE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; LE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; LE64-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
+; LE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
+; LE64-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
+; LE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE64-NEXT: [[TMP3:%.*]] = zext i8 [[VAL:%.*]] to i32
+; LE64-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
+; LE64-NEXT: [[TMP5:%.*]] = call i32 @llvm.mips.masked.atomicrmw.umin.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; LE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP5]], [[SHIFTAMT]]
+; LE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; LE64-NEXT: fence seq_cst
+; LE64-NEXT: ret i8 [[EXTRACTED]]
+;
+; BE64-LABEL: @umin_i8(
+; BE64-NEXT: fence seq_cst
+; BE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; BE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; BE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; BE64-NEXT: [[TMP2:%.*]] = xor i64 [[PTRLSB]], 3
+; BE64-NEXT: [[TMP3:%.*]] = shl i64 [[TMP2]], 3
+; BE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP3]] to i32
+; BE64-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
+; BE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE64-NEXT: [[TMP4:%.*]] = zext i8 [[VAL:%.*]] to i32
+; BE64-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP4]], [[SHIFTAMT]]
+; BE64-NEXT: [[TMP6:%.*]] = call i32 @llvm.mips.masked.atomicrmw.umin.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; BE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP6]], [[SHIFTAMT]]
+; BE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; BE64-NEXT: fence seq_cst
+; BE64-NEXT: ret i8 [[EXTRACTED]]
+;
+ %old = atomicrmw umin ptr %ptr, i8 %val seq_cst
+ ret i8 %old
+}
+
+define i16 @umax_i16(ptr %ptr, i16 %val) {
+; LE32-LABEL: @umax_i16(
+; LE32-NEXT: fence seq_cst
+; LE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; LE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; LE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; LE32-NEXT: [[TMP2:%.*]] = shl i32 [[PTRLSB]], 3
+; LE32-NEXT: [[MASK:%.*]] = shl i32 65535, [[TMP2]]
+; LE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE32-NEXT: [[TMP3:%.*]] = zext i16 [[VAL:%.*]] to i32
+; LE32-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[TMP2]]
+; LE32-NEXT: [[TMP5:%.*]] = call i32 @llvm.mips.masked.atomicrmw.umax.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; LE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP5]], [[TMP2]]
+; LE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; LE32-NEXT: fence seq_cst
+; LE32-NEXT: ret i16 [[EXTRACTED]]
+;
+; BE32-LABEL: @umax_i16(
+; BE32-NEXT: fence seq_cst
+; BE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; BE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; BE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; BE32-NEXT: [[TMP2:%.*]] = xor i32 [[PTRLSB]], 2
+; BE32-NEXT: [[TMP3:%.*]] = shl i32 [[TMP2]], 3
+; BE32-NEXT: [[MASK:%.*]] = shl i32 65535, [[TMP3]]
+; BE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE32-NEXT: [[TMP4:%.*]] = zext i16 [[VAL:%.*]] to i32
+; BE32-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP4]], [[TMP3]]
+; BE32-NEXT: [[TMP6:%.*]] = call i32 @llvm.mips.masked.atomicrmw.umax.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; BE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP6]], [[TMP3]]
+; BE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; BE32-NEXT: fence seq_cst
+; BE32-NEXT: ret i16 [[EXTRACTED]]
+;
+; LE64-LABEL: @umax_i16(
+; LE64-NEXT: fence seq_cst
+; LE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; LE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; LE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; LE64-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
+; LE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
+; LE64-NEXT: [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
+; LE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE64-NEXT: [[TMP3:%.*]] = zext i16 [[VAL:%.*]] to i32
+; LE64-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
+; LE64-NEXT: [[TMP5:%.*]] = call i32 @llvm.mips.masked.atomicrmw.umax.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; LE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP5]], [[SHIFTAMT]]
+; LE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; LE64-NEXT: fence seq_cst
+; LE64-NEXT: ret i16 [[EXTRACTED]]
+;
+; BE64-LABEL: @umax_i16(
+; BE64-NEXT: fence seq_cst
+; BE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; BE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; BE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; BE64-NEXT: [[TMP2:%.*]] = xor i64 [[PTRLSB]], 2
+; BE64-NEXT: [[TMP3:%.*]] = shl i64 [[TMP2]], 3
+; BE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP3]] to i32
+; BE64-NEXT: [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
+; BE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE64-NEXT: [[TMP4:%.*]] = zext i16 [[VAL:%.*]] to i32
+; BE64-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP4]], [[SHIFTAMT]]
+; BE64-NEXT: [[TMP6:%.*]] = call i32 @llvm.mips.masked.atomicrmw.umax.p0(ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]], i32 [[MASK]])
+; BE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP6]], [[SHIFTAMT]]
+; BE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; BE64-NEXT: fence seq_cst
+; BE64-NEXT: ret i16 [[EXTRACTED]]
+;
+ %old = atomicrmw umax ptr %ptr, i16 %val seq_cst
+ ret i16 %old
+}
+
+define i8 @and_i8(ptr %ptr, i8 %val) {
+; LE32-LABEL: @and_i8(
+; LE32-NEXT: fence seq_cst
+; LE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; LE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; LE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; LE32-NEXT: [[TMP2:%.*]] = shl i32 [[PTRLSB]], 3
+; LE32-NEXT: [[MASK:%.*]] = shl i32 255, [[TMP2]]
+; LE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE32-NEXT: [[TMP3:%.*]] = zext i8 [[VAL:%.*]] to i32
+; LE32-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[TMP2]]
+; LE32-NEXT: [[ANDOPERAND:%.*]] = or i32 [[VALOPERAND_SHIFTED]], [[INV_MASK]]
+; LE32-NEXT: [[TMP4:%.*]] = atomicrmw and ptr [[ALIGNEDADDR]], i32 [[ANDOPERAND]] monotonic, align 4
+; LE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP4]], [[TMP2]]
+; LE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; LE32-NEXT: fence seq_cst
+; LE32-NEXT: ret i8 [[EXTRACTED]]
+;
+; BE32-LABEL: @and_i8(
+; BE32-NEXT: fence seq_cst
+; BE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; BE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; BE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; BE32-NEXT: [[TMP2:%.*]] = xor i32 [[PTRLSB]], 3
+; BE32-NEXT: [[TMP3:%.*]] = shl i32 [[TMP2]], 3
+; BE32-NEXT: [[MASK:%.*]] = shl i32 255, [[TMP3]]
+; BE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE32-NEXT: [[TMP4:%.*]] = zext i8 [[VAL:%.*]] to i32
+; BE32-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP4]], [[TMP3]]
+; BE32-NEXT: [[ANDOPERAND:%.*]] = or i32 [[VALOPERAND_SHIFTED]], [[INV_MASK]]
+; BE32-NEXT: [[TMP5:%.*]] = atomicrmw and ptr [[ALIGNEDADDR]], i32 [[ANDOPERAND]] monotonic, align 4
+; BE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP5]], [[TMP3]]
+; BE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; BE32-NEXT: fence seq_cst
+; BE32-NEXT: ret i8 [[EXTRACTED]]
+;
+; LE64-LABEL: @and_i8(
+; LE64-NEXT: fence seq_cst
+; LE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; LE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; LE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; LE64-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
+; LE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
+; LE64-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
+; LE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE64-NEXT: [[TMP3:%.*]] = zext i8 [[VAL:%.*]] to i32
+; LE64-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
+; LE64-NEXT: [[ANDOPERAND:%.*]] = or i32 [[VALOPERAND_SHIFTED]], [[INV_MASK]]
+; LE64-NEXT: [[TMP4:%.*]] = atomicrmw and ptr [[ALIGNEDADDR]], i32 [[ANDOPERAND]] monotonic, align 4
+; LE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP4]], [[SHIFTAMT]]
+; LE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; LE64-NEXT: fence seq_cst
+; LE64-NEXT: ret i8 [[EXTRACTED]]
+;
+; BE64-LABEL: @and_i8(
+; BE64-NEXT: fence seq_cst
+; BE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; BE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; BE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; BE64-NEXT: [[TMP2:%.*]] = xor i64 [[PTRLSB]], 3
+; BE64-NEXT: [[TMP3:%.*]] = shl i64 [[TMP2]], 3
+; BE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP3]] to i32
+; BE64-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
+; BE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE64-NEXT: [[TMP4:%.*]] = zext i8 [[VAL:%.*]] to i32
+; BE64-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP4]], [[SHIFTAMT]]
+; BE64-NEXT: [[ANDOPERAND:%.*]] = or i32 [[VALOPERAND_SHIFTED]], [[INV_MASK]]
+; BE64-NEXT: [[TMP5:%.*]] = atomicrmw and ptr [[ALIGNEDADDR]], i32 [[ANDOPERAND]] monotonic, align 4
+; BE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP5]], [[SHIFTAMT]]
+; BE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; BE64-NEXT: fence seq_cst
+; BE64-NEXT: ret i8 [[EXTRACTED]]
+;
+ %old = atomicrmw and ptr %ptr, i8 %val seq_cst
+ ret i8 %old
+}
+
+define i16 @or_i16(ptr %ptr, i16 %val) {
+; LE32-LABEL: @or_i16(
+; LE32-NEXT: fence seq_cst
+; LE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; LE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; LE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; LE32-NEXT: [[TMP2:%.*]] = shl i32 [[PTRLSB]], 3
+; LE32-NEXT: [[MASK:%.*]] = shl i32 65535, [[TMP2]]
+; LE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE32-NEXT: [[TMP3:%.*]] = zext i16 [[VAL:%.*]] to i32
+; LE32-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[TMP2]]
+; LE32-NEXT: [[TMP4:%.*]] = atomicrmw or ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]] monotonic, align 4
+; LE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP4]], [[TMP2]]
+; LE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; LE32-NEXT: fence seq_cst
+; LE32-NEXT: ret i16 [[EXTRACTED]]
+;
+; BE32-LABEL: @or_i16(
+; BE32-NEXT: fence seq_cst
+; BE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; BE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; BE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; BE32-NEXT: [[TMP2:%.*]] = xor i32 [[PTRLSB]], 2
+; BE32-NEXT: [[TMP3:%.*]] = shl i32 [[TMP2]], 3
+; BE32-NEXT: [[MASK:%.*]] = shl i32 65535, [[TMP3]]
+; BE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE32-NEXT: [[TMP4:%.*]] = zext i16 [[VAL:%.*]] to i32
+; BE32-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP4]], [[TMP3]]
+; BE32-NEXT: [[TMP5:%.*]] = atomicrmw or ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]] monotonic, align 4
+; BE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP5]], [[TMP3]]
+; BE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; BE32-NEXT: fence seq_cst
+; BE32-NEXT: ret i16 [[EXTRACTED]]
+;
+; LE64-LABEL: @or_i16(
+; LE64-NEXT: fence seq_cst
+; LE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; LE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; LE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; LE64-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
+; LE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
+; LE64-NEXT: [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
+; LE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE64-NEXT: [[TMP3:%.*]] = zext i16 [[VAL:%.*]] to i32
+; LE64-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
+; LE64-NEXT: [[TMP4:%.*]] = atomicrmw or ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]] monotonic, align 4
+; LE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP4]], [[SHIFTAMT]]
+; LE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; LE64-NEXT: fence seq_cst
+; LE64-NEXT: ret i16 [[EXTRACTED]]
+;
+; BE64-LABEL: @or_i16(
+; BE64-NEXT: fence seq_cst
+; BE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; BE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; BE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; BE64-NEXT: [[TMP2:%.*]] = xor i64 [[PTRLSB]], 2
+; BE64-NEXT: [[TMP3:%.*]] = shl i64 [[TMP2]], 3
+; BE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP3]] to i32
+; BE64-NEXT: [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
+; BE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE64-NEXT: [[TMP4:%.*]] = zext i16 [[VAL:%.*]] to i32
+; BE64-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP4]], [[SHIFTAMT]]
+; BE64-NEXT: [[TMP5:%.*]] = atomicrmw or ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]] monotonic, align 4
+; BE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP5]], [[SHIFTAMT]]
+; BE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; BE64-NEXT: fence seq_cst
+; BE64-NEXT: ret i16 [[EXTRACTED]]
+;
+ %old = atomicrmw or ptr %ptr, i16 %val seq_cst
+ ret i16 %old
+}
+
+define i8 @xor_i8(ptr %ptr, i8 %val) {
+; LE32-LABEL: @xor_i8(
+; LE32-NEXT: fence seq_cst
+; LE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; LE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; LE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; LE32-NEXT: [[TMP2:%.*]] = shl i32 [[PTRLSB]], 3
+; LE32-NEXT: [[MASK:%.*]] = shl i32 255, [[TMP2]]
+; LE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE32-NEXT: [[TMP3:%.*]] = zext i8 [[VAL:%.*]] to i32
+; LE32-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[TMP2]]
+; LE32-NEXT: [[TMP4:%.*]] = atomicrmw xor ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]] monotonic, align 4
+; LE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP4]], [[TMP2]]
+; LE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; LE32-NEXT: fence seq_cst
+; LE32-NEXT: ret i8 [[EXTRACTED]]
+;
+; BE32-LABEL: @xor_i8(
+; BE32-NEXT: fence seq_cst
+; BE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; BE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; BE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; BE32-NEXT: [[TMP2:%.*]] = xor i32 [[PTRLSB]], 3
+; BE32-NEXT: [[TMP3:%.*]] = shl i32 [[TMP2]], 3
+; BE32-NEXT: [[MASK:%.*]] = shl i32 255, [[TMP3]]
+; BE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE32-NEXT: [[TMP4:%.*]] = zext i8 [[VAL:%.*]] to i32
+; BE32-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP4]], [[TMP3]]
+; BE32-NEXT: [[TMP5:%.*]] = atomicrmw xor ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]] monotonic, align 4
+; BE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP5]], [[TMP3]]
+; BE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; BE32-NEXT: fence seq_cst
+; BE32-NEXT: ret i8 [[EXTRACTED]]
+;
+; LE64-LABEL: @xor_i8(
+; LE64-NEXT: fence seq_cst
+; LE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; LE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; LE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; LE64-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
+; LE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
+; LE64-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
+; LE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE64-NEXT: [[TMP3:%.*]] = zext i8 [[VAL:%.*]] to i32
+; LE64-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
+; LE64-NEXT: [[TMP4:%.*]] = atomicrmw xor ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]] monotonic, align 4
+; LE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP4]], [[SHIFTAMT]]
+; LE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; LE64-NEXT: fence seq_cst
+; LE64-NEXT: ret i8 [[EXTRACTED]]
+;
+; BE64-LABEL: @xor_i8(
+; BE64-NEXT: fence seq_cst
+; BE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; BE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; BE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; BE64-NEXT: [[TMP2:%.*]] = xor i64 [[PTRLSB]], 3
+; BE64-NEXT: [[TMP3:%.*]] = shl i64 [[TMP2]], 3
+; BE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP3]] to i32
+; BE64-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
+; BE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE64-NEXT: [[TMP4:%.*]] = zext i8 [[VAL:%.*]] to i32
+; BE64-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP4]], [[SHIFTAMT]]
+; BE64-NEXT: [[TMP5:%.*]] = atomicrmw xor ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]] monotonic, align 4
+; BE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP5]], [[SHIFTAMT]]
+; BE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; BE64-NEXT: fence seq_cst
+; BE64-NEXT: ret i8 [[EXTRACTED]]
+;
+ %old = atomicrmw xor ptr %ptr, i8 %val seq_cst
+ ret i8 %old
+}
+
+define { i8, i1 } @cmpxchg_i8_align1(ptr %ptr, i8 %cmp, i8 %val) {
+; LE32-LABEL: @cmpxchg_i8_align1(
+; LE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; LE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; LE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; LE32-NEXT: [[TMP2:%.*]] = shl i32 [[PTRLSB]], 3
+; LE32-NEXT: [[MASK:%.*]] = shl i32 255, [[TMP2]]
+; LE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE32-NEXT: [[TMP3:%.*]] = zext i8 [[CMP:%.*]] to i32
+; LE32-NEXT: [[CMPVAL_SHIFTED:%.*]] = shl i32 [[TMP3]], [[TMP2]]
+; LE32-NEXT: [[TMP4:%.*]] = zext i8 [[VAL:%.*]] to i32
+; LE32-NEXT: [[NEWVAL_SHIFTED:%.*]] = shl i32 [[TMP4]], [[TMP2]]
+; LE32-NEXT: fence acq_rel
+; LE32-NEXT: [[TMP6:%.*]] = call i32 @llvm.mips.masked.cmpxchg.p0(ptr [[ALIGNEDADDR]], i32 [[CMPVAL_SHIFTED]], i32 [[NEWVAL_SHIFTED]], i32 [[MASK]])
+; LE32-NEXT: fence acq_rel
+; LE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP6]], [[TMP2]]
+; LE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; LE32-NEXT: [[TMP7:%.*]] = insertvalue { i8, i1 } poison, i8 [[EXTRACTED]], 0
+; LE32-NEXT: [[TMP8:%.*]] = and i32 [[TMP6]], [[MASK]]
+; LE32-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[CMPVAL_SHIFTED]], [[TMP8]]
+; LE32-NEXT: [[TMP9:%.*]] = insertvalue { i8, i1 } [[TMP7]], i1 [[SUCCESS]], 1
+; LE32-NEXT: ret { i8, i1 } [[TMP9]]
+;
+; BE32-LABEL: @cmpxchg_i8_align1(
+; BE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; BE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; BE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; BE32-NEXT: [[TMP2:%.*]] = xor i32 [[PTRLSB]], 3
+; BE32-NEXT: [[TMP3:%.*]] = shl i32 [[TMP2]], 3
+; BE32-NEXT: [[MASK:%.*]] = shl i32 255, [[TMP3]]
+; BE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE32-NEXT: [[TMP4:%.*]] = zext i8 [[CMP:%.*]] to i32
+; BE32-NEXT: [[CMPVAL_SHIFTED:%.*]] = shl i32 [[TMP4]], [[TMP3]]
+; BE32-NEXT: [[TMP5:%.*]] = zext i8 [[VAL:%.*]] to i32
+; BE32-NEXT: [[NEWVAL_SHIFTED:%.*]] = shl i32 [[TMP5]], [[TMP3]]
+; BE32-NEXT: fence acq_rel
+; BE32-NEXT: [[TMP7:%.*]] = call i32 @llvm.mips.masked.cmpxchg.p0(ptr [[ALIGNEDADDR]], i32 [[CMPVAL_SHIFTED]], i32 [[NEWVAL_SHIFTED]], i32 [[MASK]])
+; BE32-NEXT: fence acq_rel
+; BE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP7]], [[TMP3]]
+; BE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; BE32-NEXT: [[TMP8:%.*]] = insertvalue { i8, i1 } poison, i8 [[EXTRACTED]], 0
+; BE32-NEXT: [[TMP9:%.*]] = and i32 [[TMP7]], [[MASK]]
+; BE32-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[CMPVAL_SHIFTED]], [[TMP9]]
+; BE32-NEXT: [[TMP10:%.*]] = insertvalue { i8, i1 } [[TMP8]], i1 [[SUCCESS]], 1
+; BE32-NEXT: ret { i8, i1 } [[TMP10]]
+;
+; LE64-LABEL: @cmpxchg_i8_align1(
+; LE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; LE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; LE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; LE64-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
+; LE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
+; LE64-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
+; LE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE64-NEXT: [[TMP3:%.*]] = zext i8 [[CMP:%.*]] to i32
+; LE64-NEXT: [[CMPVAL_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
+; LE64-NEXT: [[TMP4:%.*]] = zext i8 [[VAL:%.*]] to i32
+; LE64-NEXT: [[NEWVAL_SHIFTED:%.*]] = shl i32 [[TMP4]], [[SHIFTAMT]]
+; LE64-NEXT: fence acq_rel
+; LE64-NEXT: [[TMP6:%.*]] = call i32 @llvm.mips.masked.cmpxchg.p0(ptr [[ALIGNEDADDR]], i32 [[CMPVAL_SHIFTED]], i32 [[NEWVAL_SHIFTED]], i32 [[MASK]])
+; LE64-NEXT: fence acq_rel
+; LE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP6]], [[SHIFTAMT]]
+; LE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; LE64-NEXT: [[TMP7:%.*]] = insertvalue { i8, i1 } poison, i8 [[EXTRACTED]], 0
+; LE64-NEXT: [[TMP8:%.*]] = and i32 [[TMP6]], [[MASK]]
+; LE64-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[CMPVAL_SHIFTED]], [[TMP8]]
+; LE64-NEXT: [[TMP9:%.*]] = insertvalue { i8, i1 } [[TMP7]], i1 [[SUCCESS]], 1
+; LE64-NEXT: ret { i8, i1 } [[TMP9]]
+;
+; BE64-LABEL: @cmpxchg_i8_align1(
+; BE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; BE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; BE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; BE64-NEXT: [[TMP2:%.*]] = xor i64 [[PTRLSB]], 3
+; BE64-NEXT: [[TMP3:%.*]] = shl i64 [[TMP2]], 3
+; BE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP3]] to i32
+; BE64-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
+; BE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE64-NEXT: [[TMP4:%.*]] = zext i8 [[CMP:%.*]] to i32
+; BE64-NEXT: [[CMPVAL_SHIFTED:%.*]] = shl i32 [[TMP4]], [[SHIFTAMT]]
+; BE64-NEXT: [[TMP5:%.*]] = zext i8 [[VAL:%.*]] to i32
+; BE64-NEXT: [[NEWVAL_SHIFTED:%.*]] = shl i32 [[TMP5]], [[SHIFTAMT]]
+; BE64-NEXT: fence acq_rel
+; BE64-NEXT: [[TMP7:%.*]] = call i32 @llvm.mips.masked.cmpxchg.p0(ptr [[ALIGNEDADDR]], i32 [[CMPVAL_SHIFTED]], i32 [[NEWVAL_SHIFTED]], i32 [[MASK]])
+; BE64-NEXT: fence acq_rel
+; BE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP7]], [[SHIFTAMT]]
+; BE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; BE64-NEXT: [[TMP8:%.*]] = insertvalue { i8, i1 } poison, i8 [[EXTRACTED]], 0
+; BE64-NEXT: [[TMP9:%.*]] = and i32 [[TMP7]], [[MASK]]
+; BE64-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[CMPVAL_SHIFTED]], [[TMP9]]
+; BE64-NEXT: [[TMP10:%.*]] = insertvalue { i8, i1 } [[TMP8]], i1 [[SUCCESS]], 1
+; BE64-NEXT: ret { i8, i1 } [[TMP10]]
+;
+ %pair = cmpxchg ptr %ptr, i8 %cmp, i8 %val acq_rel acquire, align 1
+ ret { i8, i1 } %pair
+}
+
+define { i16, i1 } @cmpxchg_i16_align2(ptr %ptr, i16 %cmp, i16 %val) {
+; LE32-LABEL: @cmpxchg_i16_align2(
+; LE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; LE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; LE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; LE32-NEXT: [[TMP2:%.*]] = shl i32 [[PTRLSB]], 3
+; LE32-NEXT: [[MASK:%.*]] = shl i32 65535, [[TMP2]]
+; LE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE32-NEXT: [[TMP3:%.*]] = zext i16 [[CMP:%.*]] to i32
+; LE32-NEXT: [[CMPVAL_SHIFTED:%.*]] = shl i32 [[TMP3]], [[TMP2]]
+; LE32-NEXT: [[TMP4:%.*]] = zext i16 [[VAL:%.*]] to i32
+; LE32-NEXT: [[NEWVAL_SHIFTED:%.*]] = shl i32 [[TMP4]], [[TMP2]]
+; LE32-NEXT: fence acq_rel
+; LE32-NEXT: [[TMP6:%.*]] = call i32 @llvm.mips.masked.cmpxchg.p0(ptr [[ALIGNEDADDR]], i32 [[CMPVAL_SHIFTED]], i32 [[NEWVAL_SHIFTED]], i32 [[MASK]])
+; LE32-NEXT: fence acq_rel
+; LE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP6]], [[TMP2]]
+; LE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; LE32-NEXT: [[TMP7:%.*]] = insertvalue { i16, i1 } poison, i16 [[EXTRACTED]], 0
+; LE32-NEXT: [[TMP8:%.*]] = and i32 [[TMP6]], [[MASK]]
+; LE32-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[CMPVAL_SHIFTED]], [[TMP8]]
+; LE32-NEXT: [[TMP9:%.*]] = insertvalue { i16, i1 } [[TMP7]], i1 [[SUCCESS]], 1
+; LE32-NEXT: ret { i16, i1 } [[TMP9]]
+;
+; BE32-LABEL: @cmpxchg_i16_align2(
+; BE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; BE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; BE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; BE32-NEXT: [[TMP2:%.*]] = xor i32 [[PTRLSB]], 2
+; BE32-NEXT: [[TMP3:%.*]] = shl i32 [[TMP2]], 3
+; BE32-NEXT: [[MASK:%.*]] = shl i32 65535, [[TMP3]]
+; BE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE32-NEXT: [[TMP4:%.*]] = zext i16 [[CMP:%.*]] to i32
+; BE32-NEXT: [[CMPVAL_SHIFTED:%.*]] = shl i32 [[TMP4]], [[TMP3]]
+; BE32-NEXT: [[TMP5:%.*]] = zext i16 [[VAL:%.*]] to i32
+; BE32-NEXT: [[NEWVAL_SHIFTED:%.*]] = shl i32 [[TMP5]], [[TMP3]]
+; BE32-NEXT: fence acq_rel
+; BE32-NEXT: [[TMP7:%.*]] = call i32 @llvm.mips.masked.cmpxchg.p0(ptr [[ALIGNEDADDR]], i32 [[CMPVAL_SHIFTED]], i32 [[NEWVAL_SHIFTED]], i32 [[MASK]])
+; BE32-NEXT: fence acq_rel
+; BE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP7]], [[TMP3]]
+; BE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; BE32-NEXT: [[TMP8:%.*]] = insertvalue { i16, i1 } poison, i16 [[EXTRACTED]], 0
+; BE32-NEXT: [[TMP9:%.*]] = and i32 [[TMP7]], [[MASK]]
+; BE32-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[CMPVAL_SHIFTED]], [[TMP9]]
+; BE32-NEXT: [[TMP10:%.*]] = insertvalue { i16, i1 } [[TMP8]], i1 [[SUCCESS]], 1
+; BE32-NEXT: ret { i16, i1 } [[TMP10]]
+;
+; LE64-LABEL: @cmpxchg_i16_align2(
+; LE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; LE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; LE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; LE64-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
+; LE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
+; LE64-NEXT: [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
+; LE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE64-NEXT: [[TMP3:%.*]] = zext i16 [[CMP:%.*]] to i32
+; LE64-NEXT: [[CMPVAL_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
+; LE64-NEXT: [[TMP4:%.*]] = zext i16 [[VAL:%.*]] to i32
+; LE64-NEXT: [[NEWVAL_SHIFTED:%.*]] = shl i32 [[TMP4]], [[SHIFTAMT]]
+; LE64-NEXT: fence acq_rel
+; LE64-NEXT: [[TMP6:%.*]] = call i32 @llvm.mips.masked.cmpxchg.p0(ptr [[ALIGNEDADDR]], i32 [[CMPVAL_SHIFTED]], i32 [[NEWVAL_SHIFTED]], i32 [[MASK]])
+; LE64-NEXT: fence acq_rel
+; LE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP6]], [[SHIFTAMT]]
+; LE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; LE64-NEXT: [[TMP7:%.*]] = insertvalue { i16, i1 } poison, i16 [[EXTRACTED]], 0
+; LE64-NEXT: [[TMP8:%.*]] = and i32 [[TMP6]], [[MASK]]
+; LE64-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[CMPVAL_SHIFTED]], [[TMP8]]
+; LE64-NEXT: [[TMP9:%.*]] = insertvalue { i16, i1 } [[TMP7]], i1 [[SUCCESS]], 1
+; LE64-NEXT: ret { i16, i1 } [[TMP9]]
+;
+; BE64-LABEL: @cmpxchg_i16_align2(
+; BE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; BE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; BE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; BE64-NEXT: [[TMP2:%.*]] = xor i64 [[PTRLSB]], 2
+; BE64-NEXT: [[TMP3:%.*]] = shl i64 [[TMP2]], 3
+; BE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP3]] to i32
+; BE64-NEXT: [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]]
+; BE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE64-NEXT: [[TMP4:%.*]] = zext i16 [[CMP:%.*]] to i32
+; BE64-NEXT: [[CMPVAL_SHIFTED:%.*]] = shl i32 [[TMP4]], [[SHIFTAMT]]
+; BE64-NEXT: [[TMP5:%.*]] = zext i16 [[VAL:%.*]] to i32
+; BE64-NEXT: [[NEWVAL_SHIFTED:%.*]] = shl i32 [[TMP5]], [[SHIFTAMT]]
+; BE64-NEXT: fence acq_rel
+; BE64-NEXT: [[TMP7:%.*]] = call i32 @llvm.mips.masked.cmpxchg.p0(ptr [[ALIGNEDADDR]], i32 [[CMPVAL_SHIFTED]], i32 [[NEWVAL_SHIFTED]], i32 [[MASK]])
+; BE64-NEXT: fence acq_rel
+; BE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP7]], [[SHIFTAMT]]
+; BE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; BE64-NEXT: [[TMP8:%.*]] = insertvalue { i16, i1 } poison, i16 [[EXTRACTED]], 0
+; BE64-NEXT: [[TMP9:%.*]] = and i32 [[TMP7]], [[MASK]]
+; BE64-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[CMPVAL_SHIFTED]], [[TMP9]]
+; BE64-NEXT: [[TMP10:%.*]] = insertvalue { i16, i1 } [[TMP8]], i1 [[SUCCESS]], 1
+; BE64-NEXT: ret { i16, i1 } [[TMP10]]
+;
+ %pair = cmpxchg ptr %ptr, i16 %cmp, i16 %val acq_rel acquire, align 2
+ ret { i16, i1 } %pair
+}
+
+define { i8, i1 } @cmpxchg_i8_align4(ptr %ptr, i8 %cmp, i8 %val) {
+; LE32-LABEL: @cmpxchg_i8_align4(
+; LE32-NEXT: [[TMP1:%.*]] = zext i8 [[CMP:%.*]] to i32
+; LE32-NEXT: [[TMP2:%.*]] = zext i8 [[VAL:%.*]] to i32
+; LE32-NEXT: fence acq_rel
+; LE32-NEXT: [[TMP3:%.*]] = call i32 @llvm.mips.masked.cmpxchg.p0(ptr [[PTR:%.*]], i32 [[TMP1]], i32 [[TMP2]], i32 255)
+; LE32-NEXT: fence acq_rel
+; LE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[TMP3]] to i8
+; LE32-NEXT: [[TMP4:%.*]] = insertvalue { i8, i1 } poison, i8 [[EXTRACTED]], 0
+; LE32-NEXT: [[TMP5:%.*]] = and i32 [[TMP3]], 255
+; LE32-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[TMP1]], [[TMP5]]
+; LE32-NEXT: [[TMP6:%.*]] = insertvalue { i8, i1 } [[TMP4]], i1 [[SUCCESS]], 1
+; LE32-NEXT: ret { i8, i1 } [[TMP6]]
+;
+; BE32-LABEL: @cmpxchg_i8_align4(
+; BE32-NEXT: [[TMP1:%.*]] = zext i8 [[CMP:%.*]] to i32
+; BE32-NEXT: [[CMPVAL_SHIFTED:%.*]] = shl i32 [[TMP1]], 24
+; BE32-NEXT: [[TMP2:%.*]] = zext i8 [[VAL:%.*]] to i32
+; BE32-NEXT: [[NEWVAL_SHIFTED:%.*]] = shl i32 [[TMP2]], 24
+; BE32-NEXT: fence acq_rel
+; BE32-NEXT: [[TMP3:%.*]] = call i32 @llvm.mips.masked.cmpxchg.p0(ptr [[PTR:%.*]], i32 [[CMPVAL_SHIFTED]], i32 [[NEWVAL_SHIFTED]], i32 -16777216)
+; BE32-NEXT: fence acq_rel
+; BE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP3]], 24
+; BE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; BE32-NEXT: [[TMP4:%.*]] = insertvalue { i8, i1 } poison, i8 [[EXTRACTED]], 0
+; BE32-NEXT: [[TMP5:%.*]] = and i32 [[TMP3]], -16777216
+; BE32-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[CMPVAL_SHIFTED]], [[TMP5]]
+; BE32-NEXT: [[TMP6:%.*]] = insertvalue { i8, i1 } [[TMP4]], i1 [[SUCCESS]], 1
+; BE32-NEXT: ret { i8, i1 } [[TMP6]]
+;
+; LE64-LABEL: @cmpxchg_i8_align4(
+; LE64-NEXT: [[TMP1:%.*]] = zext i8 [[CMP:%.*]] to i32
+; LE64-NEXT: [[TMP2:%.*]] = zext i8 [[VAL:%.*]] to i32
+; LE64-NEXT: fence acq_rel
+; LE64-NEXT: [[TMP3:%.*]] = call i32 @llvm.mips.masked.cmpxchg.p0(ptr [[PTR:%.*]], i32 [[TMP1]], i32 [[TMP2]], i32 255)
+; LE64-NEXT: fence acq_rel
+; LE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[TMP3]] to i8
+; LE64-NEXT: [[TMP4:%.*]] = insertvalue { i8, i1 } poison, i8 [[EXTRACTED]], 0
+; LE64-NEXT: [[TMP5:%.*]] = and i32 [[TMP3]], 255
+; LE64-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[TMP1]], [[TMP5]]
+; LE64-NEXT: [[TMP6:%.*]] = insertvalue { i8, i1 } [[TMP4]], i1 [[SUCCESS]], 1
+; LE64-NEXT: ret { i8, i1 } [[TMP6]]
+;
+; BE64-LABEL: @cmpxchg_i8_align4(
+; BE64-NEXT: [[TMP1:%.*]] = zext i8 [[CMP:%.*]] to i32
+; BE64-NEXT: [[CMPVAL_SHIFTED:%.*]] = shl i32 [[TMP1]], 24
+; BE64-NEXT: [[TMP2:%.*]] = zext i8 [[VAL:%.*]] to i32
+; BE64-NEXT: [[NEWVAL_SHIFTED:%.*]] = shl i32 [[TMP2]], 24
+; BE64-NEXT: fence acq_rel
+; BE64-NEXT: [[TMP3:%.*]] = call i32 @llvm.mips.masked.cmpxchg.p0(ptr [[PTR:%.*]], i32 [[CMPVAL_SHIFTED]], i32 [[NEWVAL_SHIFTED]], i32 -16777216)
+; BE64-NEXT: fence acq_rel
+; BE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP3]], 24
+; BE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; BE64-NEXT: [[TMP4:%.*]] = insertvalue { i8, i1 } poison, i8 [[EXTRACTED]], 0
+; BE64-NEXT: [[TMP5:%.*]] = and i32 [[TMP3]], -16777216
+; BE64-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[CMPVAL_SHIFTED]], [[TMP5]]
+; BE64-NEXT: [[TMP6:%.*]] = insertvalue { i8, i1 } [[TMP4]], i1 [[SUCCESS]], 1
+; BE64-NEXT: ret { i8, i1 } [[TMP6]]
+;
+ %pair = cmpxchg ptr %ptr, i8 %cmp, i8 %val acq_rel acquire, align 4
+ ret { i8, i1 } %pair
+}
+
+define { i16, i1 } @cmpxchg_i16_align4(ptr %ptr, i16 %cmp, i16 %val) {
+; LE32-LABEL: @cmpxchg_i16_align4(
+; LE32-NEXT: [[TMP1:%.*]] = zext i16 [[CMP:%.*]] to i32
+; LE32-NEXT: [[TMP2:%.*]] = zext i16 [[VAL:%.*]] to i32
+; LE32-NEXT: fence acq_rel
+; LE32-NEXT: [[TMP3:%.*]] = call i32 @llvm.mips.masked.cmpxchg.p0(ptr [[PTR:%.*]], i32 [[TMP1]], i32 [[TMP2]], i32 65535)
+; LE32-NEXT: fence acq_rel
+; LE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[TMP3]] to i16
+; LE32-NEXT: [[TMP4:%.*]] = insertvalue { i16, i1 } poison, i16 [[EXTRACTED]], 0
+; LE32-NEXT: [[TMP5:%.*]] = and i32 [[TMP3]], 65535
+; LE32-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[TMP1]], [[TMP5]]
+; LE32-NEXT: [[TMP6:%.*]] = insertvalue { i16, i1 } [[TMP4]], i1 [[SUCCESS]], 1
+; LE32-NEXT: ret { i16, i1 } [[TMP6]]
+;
+; BE32-LABEL: @cmpxchg_i16_align4(
+; BE32-NEXT: [[TMP1:%.*]] = zext i16 [[CMP:%.*]] to i32
+; BE32-NEXT: [[CMPVAL_SHIFTED:%.*]] = shl i32 [[TMP1]], 16
+; BE32-NEXT: [[TMP2:%.*]] = zext i16 [[VAL:%.*]] to i32
+; BE32-NEXT: [[NEWVAL_SHIFTED:%.*]] = shl i32 [[TMP2]], 16
+; BE32-NEXT: fence acq_rel
+; BE32-NEXT: [[TMP3:%.*]] = call i32 @llvm.mips.masked.cmpxchg.p0(ptr [[PTR:%.*]], i32 [[CMPVAL_SHIFTED]], i32 [[NEWVAL_SHIFTED]], i32 -65536)
+; BE32-NEXT: fence acq_rel
+; BE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP3]], 16
+; BE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; BE32-NEXT: [[TMP4:%.*]] = insertvalue { i16, i1 } poison, i16 [[EXTRACTED]], 0
+; BE32-NEXT: [[TMP5:%.*]] = and i32 [[TMP3]], -65536
+; BE32-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[CMPVAL_SHIFTED]], [[TMP5]]
+; BE32-NEXT: [[TMP6:%.*]] = insertvalue { i16, i1 } [[TMP4]], i1 [[SUCCESS]], 1
+; BE32-NEXT: ret { i16, i1 } [[TMP6]]
+;
+; LE64-LABEL: @cmpxchg_i16_align4(
+; LE64-NEXT: [[TMP1:%.*]] = zext i16 [[CMP:%.*]] to i32
+; LE64-NEXT: [[TMP2:%.*]] = zext i16 [[VAL:%.*]] to i32
+; LE64-NEXT: fence acq_rel
+; LE64-NEXT: [[TMP3:%.*]] = call i32 @llvm.mips.masked.cmpxchg.p0(ptr [[PTR:%.*]], i32 [[TMP1]], i32 [[TMP2]], i32 65535)
+; LE64-NEXT: fence acq_rel
+; LE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[TMP3]] to i16
+; LE64-NEXT: [[TMP4:%.*]] = insertvalue { i16, i1 } poison, i16 [[EXTRACTED]], 0
+; LE64-NEXT: [[TMP5:%.*]] = and i32 [[TMP3]], 65535
+; LE64-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[TMP1]], [[TMP5]]
+; LE64-NEXT: [[TMP6:%.*]] = insertvalue { i16, i1 } [[TMP4]], i1 [[SUCCESS]], 1
+; LE64-NEXT: ret { i16, i1 } [[TMP6]]
+;
+; BE64-LABEL: @cmpxchg_i16_align4(
+; BE64-NEXT: [[TMP1:%.*]] = zext i16 [[CMP:%.*]] to i32
+; BE64-NEXT: [[CMPVAL_SHIFTED:%.*]] = shl i32 [[TMP1]], 16
+; BE64-NEXT: [[TMP2:%.*]] = zext i16 [[VAL:%.*]] to i32
+; BE64-NEXT: [[NEWVAL_SHIFTED:%.*]] = shl i32 [[TMP2]], 16
+; BE64-NEXT: fence acq_rel
+; BE64-NEXT: [[TMP3:%.*]] = call i32 @llvm.mips.masked.cmpxchg.p0(ptr [[PTR:%.*]], i32 [[CMPVAL_SHIFTED]], i32 [[NEWVAL_SHIFTED]], i32 -65536)
+; BE64-NEXT: fence acq_rel
+; BE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP3]], 16
+; BE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; BE64-NEXT: [[TMP4:%.*]] = insertvalue { i16, i1 } poison, i16 [[EXTRACTED]], 0
+; BE64-NEXT: [[TMP5:%.*]] = and i32 [[TMP3]], -65536
+; BE64-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[CMPVAL_SHIFTED]], [[TMP5]]
+; BE64-NEXT: [[TMP6:%.*]] = insertvalue { i16, i1 } [[TMP4]], i1 [[SUCCESS]], 1
+; BE64-NEXT: ret { i16, i1 } [[TMP6]]
+;
+ %pair = cmpxchg ptr %ptr, i16 %cmp, i16 %val acq_rel acquire, align 4
+ ret { i16, i1 } %pair
+}
+
+define { i8, i1 } @weak_cmpxchg_i8(ptr %ptr, i8 %cmp, i8 %val) {
+; LE32-LABEL: @weak_cmpxchg_i8(
+; LE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; LE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; LE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; LE32-NEXT: [[TMP2:%.*]] = shl i32 [[PTRLSB]], 3
+; LE32-NEXT: [[MASK:%.*]] = shl i32 255, [[TMP2]]
+; LE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE32-NEXT: [[TMP3:%.*]] = zext i8 [[CMP:%.*]] to i32
+; LE32-NEXT: [[CMPVAL_SHIFTED:%.*]] = shl i32 [[TMP3]], [[TMP2]]
+; LE32-NEXT: [[TMP4:%.*]] = zext i8 [[VAL:%.*]] to i32
+; LE32-NEXT: [[NEWVAL_SHIFTED:%.*]] = shl i32 [[TMP4]], [[TMP2]]
+; LE32-NEXT: [[TMP6:%.*]] = call i32 @llvm.mips.masked.cmpxchg.p0(ptr [[ALIGNEDADDR]], i32 [[CMPVAL_SHIFTED]], i32 [[NEWVAL_SHIFTED]], i32 [[MASK]])
+; LE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP6]], [[TMP2]]
+; LE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; LE32-NEXT: [[TMP7:%.*]] = insertvalue { i8, i1 } poison, i8 [[EXTRACTED]], 0
+; LE32-NEXT: [[TMP8:%.*]] = and i32 [[TMP6]], [[MASK]]
+; LE32-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[CMPVAL_SHIFTED]], [[TMP8]]
+; LE32-NEXT: [[TMP9:%.*]] = insertvalue { i8, i1 } [[TMP7]], i1 [[SUCCESS]], 1
+; LE32-NEXT: ret { i8, i1 } [[TMP9]]
+;
+; BE32-LABEL: @weak_cmpxchg_i8(
+; BE32-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -4)
+; BE32-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i32
+; BE32-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3
+; BE32-NEXT: [[TMP2:%.*]] = xor i32 [[PTRLSB]], 3
+; BE32-NEXT: [[TMP3:%.*]] = shl i32 [[TMP2]], 3
+; BE32-NEXT: [[MASK:%.*]] = shl i32 255, [[TMP3]]
+; BE32-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE32-NEXT: [[TMP4:%.*]] = zext i8 [[CMP:%.*]] to i32
+; BE32-NEXT: [[CMPVAL_SHIFTED:%.*]] = shl i32 [[TMP4]], [[TMP3]]
+; BE32-NEXT: [[TMP5:%.*]] = zext i8 [[VAL:%.*]] to i32
+; BE32-NEXT: [[NEWVAL_SHIFTED:%.*]] = shl i32 [[TMP5]], [[TMP3]]
+; BE32-NEXT: [[TMP7:%.*]] = call i32 @llvm.mips.masked.cmpxchg.p0(ptr [[ALIGNEDADDR]], i32 [[CMPVAL_SHIFTED]], i32 [[NEWVAL_SHIFTED]], i32 [[MASK]])
+; BE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP7]], [[TMP3]]
+; BE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; BE32-NEXT: [[TMP8:%.*]] = insertvalue { i8, i1 } poison, i8 [[EXTRACTED]], 0
+; BE32-NEXT: [[TMP9:%.*]] = and i32 [[TMP7]], [[MASK]]
+; BE32-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[CMPVAL_SHIFTED]], [[TMP9]]
+; BE32-NEXT: [[TMP10:%.*]] = insertvalue { i8, i1 } [[TMP8]], i1 [[SUCCESS]], 1
+; BE32-NEXT: ret { i8, i1 } [[TMP10]]
+;
+; LE64-LABEL: @weak_cmpxchg_i8(
+; LE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; LE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; LE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; LE64-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3
+; LE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32
+; LE64-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
+; LE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; LE64-NEXT: [[TMP3:%.*]] = zext i8 [[CMP:%.*]] to i32
+; LE64-NEXT: [[CMPVAL_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]]
+; LE64-NEXT: [[TMP4:%.*]] = zext i8 [[VAL:%.*]] to i32
+; LE64-NEXT: [[NEWVAL_SHIFTED:%.*]] = shl i32 [[TMP4]], [[SHIFTAMT]]
+; LE64-NEXT: [[TMP6:%.*]] = call i32 @llvm.mips.masked.cmpxchg.p0(ptr [[ALIGNEDADDR]], i32 [[CMPVAL_SHIFTED]], i32 [[NEWVAL_SHIFTED]], i32 [[MASK]])
+; LE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP6]], [[SHIFTAMT]]
+; LE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; LE64-NEXT: [[TMP7:%.*]] = insertvalue { i8, i1 } poison, i8 [[EXTRACTED]], 0
+; LE64-NEXT: [[TMP8:%.*]] = and i32 [[TMP6]], [[MASK]]
+; LE64-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[CMPVAL_SHIFTED]], [[TMP8]]
+; LE64-NEXT: [[TMP9:%.*]] = insertvalue { i8, i1 } [[TMP7]], i1 [[SUCCESS]], 1
+; LE64-NEXT: ret { i8, i1 } [[TMP9]]
+;
+; BE64-LABEL: @weak_cmpxchg_i8(
+; BE64-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4)
+; BE64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64
+; BE64-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3
+; BE64-NEXT: [[TMP2:%.*]] = xor i64 [[PTRLSB]], 3
+; BE64-NEXT: [[TMP3:%.*]] = shl i64 [[TMP2]], 3
+; BE64-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP3]] to i32
+; BE64-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]]
+; BE64-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1
+; BE64-NEXT: [[TMP4:%.*]] = zext i8 [[CMP:%.*]] to i32
+; BE64-NEXT: [[CMPVAL_SHIFTED:%.*]] = shl i32 [[TMP4]], [[SHIFTAMT]]
+; BE64-NEXT: [[TMP5:%.*]] = zext i8 [[VAL:%.*]] to i32
+; BE64-NEXT: [[NEWVAL_SHIFTED:%.*]] = shl i32 [[TMP5]], [[SHIFTAMT]]
+; BE64-NEXT: [[TMP7:%.*]] = call i32 @llvm.mips.masked.cmpxchg.p0(ptr [[ALIGNEDADDR]], i32 [[CMPVAL_SHIFTED]], i32 [[NEWVAL_SHIFTED]], i32 [[MASK]])
+; BE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP7]], [[SHIFTAMT]]
+; BE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8
+; BE64-NEXT: [[TMP8:%.*]] = insertvalue { i8, i1 } poison, i8 [[EXTRACTED]], 0
+; BE64-NEXT: [[TMP9:%.*]] = and i32 [[TMP7]], [[MASK]]
+; BE64-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[CMPVAL_SHIFTED]], [[TMP9]]
+; BE64-NEXT: [[TMP10:%.*]] = insertvalue { i8, i1 } [[TMP8]], i1 [[SUCCESS]], 1
+; BE64-NEXT: ret { i8, i1 } [[TMP10]]
+;
+ %pair = cmpxchg weak volatile ptr %ptr, i8 %cmp, i8 %val monotonic monotonic
+ ret { i8, i1 } %pair
+}
+
+define i16 @aligned_add_i16(ptr %ptr, i16 %val) {
+; LE32-LABEL: @aligned_add_i16(
+; LE32-NEXT: [[TMP1:%.*]] = zext i16 [[VAL:%.*]] to i32
+; LE32-NEXT: [[TMP2:%.*]] = call i32 @llvm.mips.masked.atomicrmw.add.p0(ptr [[PTR:%.*]], i32 [[TMP1]], i32 65535)
+; LE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[TMP2]] to i16
+; LE32-NEXT: ret i16 [[EXTRACTED]]
+;
+; BE32-LABEL: @aligned_add_i16(
+; BE32-NEXT: [[TMP1:%.*]] = zext i16 [[VAL:%.*]] to i32
+; BE32-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP1]], 16
+; BE32-NEXT: [[TMP2:%.*]] = call i32 @llvm.mips.masked.atomicrmw.add.p0(ptr [[PTR:%.*]], i32 [[VALOPERAND_SHIFTED]], i32 -65536)
+; BE32-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP2]], 16
+; BE32-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; BE32-NEXT: ret i16 [[EXTRACTED]]
+;
+; LE64-LABEL: @aligned_add_i16(
+; LE64-NEXT: [[TMP1:%.*]] = zext i16 [[VAL:%.*]] to i32
+; LE64-NEXT: [[TMP2:%.*]] = call i32 @llvm.mips.masked.atomicrmw.add.p0(ptr [[PTR:%.*]], i32 [[TMP1]], i32 65535)
+; LE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[TMP2]] to i16
+; LE64-NEXT: ret i16 [[EXTRACTED]]
+;
+; BE64-LABEL: @aligned_add_i16(
+; BE64-NEXT: [[TMP1:%.*]] = zext i16 [[VAL:%.*]] to i32
+; BE64-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP1]], 16
+; BE64-NEXT: [[TMP2:%.*]] = call i32 @llvm.mips.masked.atomicrmw.add.p0(ptr [[PTR:%.*]], i32 [[VALOPERAND_SHIFTED]], i32 -65536)
+; BE64-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP2]], 16
+; BE64-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16
+; BE64-NEXT: ret i16 [[EXTRACTED]]
+;
+ %old = atomicrmw add ptr %ptr, i16 %val monotonic, align 4
+ ret i16 %old
+}
diff --git a/llvm/test/Transforms/AtomicExpand/Mips/masked-cmpxchg-fences.ll b/llvm/test/Transforms/AtomicExpand/Mips/masked-cmpxchg-fences.ll
new file mode 100644
index 00000000000000..97713c4f017ca3
--- /dev/null
+++ b/llvm/test/Transforms/AtomicExpand/Mips/masked-cmpxchg-fences.ll
@@ -0,0 +1,42 @@
+; RUN: opt -S -mtriple=mipsel -passes='require<libcall-lowering-info>,atomic-expand' %s | FileCheck %s --implicit-check-not='{{^[ \t]+fence[ \t]}}'
+; RUN: opt -S -mtriple=mips -passes='require<libcall-lowering-info>,atomic-expand' %s | FileCheck %s --implicit-check-not='{{^[ \t]+fence[ \t]}}'
+; RUN: opt -S -mtriple=mips64el -passes='require<libcall-lowering-info>,atomic-expand' %s | FileCheck %s --implicit-check-not='{{^[ \t]+fence[ \t]}}'
+; RUN: opt -S -mtriple=mips64 -passes='require<libcall-lowering-info>,atomic-expand' %s | FileCheck %s --implicit-check-not='{{^[ \t]+fence[ \t]}}'
+
+; Acquire needs only a trailing fence; release needs only a leading fence.
+
+define { i8, i1 } @cmpxchg_acquire_i8(ptr %ptr, i8 %cmp, i8 %val) {
+; CHECK-LABEL: @cmpxchg_acquire_i8(
+; CHECK: call i32 @llvm.mips.masked.cmpxchg.p0(
+; CHECK-NEXT: fence acquire
+; CHECK: ret { i8, i1 }
+ %pair = cmpxchg ptr %ptr, i8 %cmp, i8 %val acquire monotonic
+ ret { i8, i1 } %pair
+}
+
+define { i16, i1 } @cmpxchg_acquire_i16(ptr %ptr, i16 %cmp, i16 %val) {
+; CHECK-LABEL: @cmpxchg_acquire_i16(
+; CHECK: call i32 @llvm.mips.masked.cmpxchg.p0(
+; CHECK-NEXT: fence acquire
+; CHECK: ret { i16, i1 }
+ %pair = cmpxchg ptr %ptr, i16 %cmp, i16 %val acquire monotonic
+ ret { i16, i1 } %pair
+}
+
+define { i8, i1 } @cmpxchg_release_i8(ptr %ptr, i8 %cmp, i8 %val) {
+; CHECK-LABEL: @cmpxchg_release_i8(
+; CHECK: fence release
+; CHECK-NEXT: call i32 @llvm.mips.masked.cmpxchg.p0(
+; CHECK: ret { i8, i1 }
+ %pair = cmpxchg ptr %ptr, i8 %cmp, i8 %val release monotonic
+ ret { i8, i1 } %pair
+}
+
+define { i16, i1 } @cmpxchg_release_i16(ptr %ptr, i16 %cmp, i16 %val) {
+; CHECK-LABEL: @cmpxchg_release_i16(
+; CHECK: fence release
+; CHECK-NEXT: call i32 @llvm.mips.masked.cmpxchg.p0(
+; CHECK: ret { i16, i1 }
+ %pair = cmpxchg ptr %ptr, i16 %cmp, i16 %val release monotonic
+ ret { i16, i1 } %pair
+}
>From 3c08a7f471440c8b8b9a8ad04aa13bfc45d0948e Mon Sep 17 00:00:00 2001
From: Jiaxun Yang <jiaxun.yang at flygoat.com>
Date: Thu, 24 Sep 2026 10:02:17 +0100
Subject: [PATCH 2/2] [Mips] Fix atomic opcode initialization on Windows
Windows builds reject runtime opcode enum expressions in unsigned
aggregate initializers as narrowing conversions. Convert the selected
opcodes to unsigned locals before constructing AtomicOpcodes, preserving
the existing opcode selection.
Assisted-by: OpenAI Codex
---
llvm/lib/Target/Mips/MipsExpandPseudo.cpp | 42 +++++++++++------------
1 file changed, 20 insertions(+), 22 deletions(-)
diff --git a/llvm/lib/Target/Mips/MipsExpandPseudo.cpp b/llvm/lib/Target/Mips/MipsExpandPseudo.cpp
index 30e8182ee6e2cf..b689ce4da8666d 100644
--- a/llvm/lib/Target/Mips/MipsExpandPseudo.cpp
+++ b/llvm/lib/Target/Mips/MipsExpandPseudo.cpp
@@ -63,32 +63,30 @@ char MipsExpandPseudo::ID = 0;
MipsExpandPseudo::AtomicOpcodes
MipsExpandPseudo::getAtomicOpcodes(unsigned Width) const {
- if (Width == 64)
- return {STI->hasMips64r6() ? Mips::LLD_R6 : Mips::LLD,
- STI->hasMips64r6() ? Mips::SCD_R6 : Mips::SCD,
- Mips::BEQ64,
- Mips::BNE64,
- Mips::OR64,
- Mips::ZERO_64};
+ if (Width == 64) {
+ unsigned LL = STI->hasMips64r6() ? Mips::LLD_R6 : Mips::LLD;
+ unsigned SC = STI->hasMips64r6() ? Mips::SCD_R6 : Mips::SCD;
+ return {LL, SC, Mips::BEQ64, Mips::BNE64, Mips::OR64, Mips::ZERO_64};
+ }
assert(Width == 32 && "Unexpected atomic width");
- if (STI->inMicroMipsMode())
- return {STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM,
- STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM,
- STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM,
- STI->hasMips32r6() ? Mips::BNEC_MMR6 : Mips::BNE_MM,
- STI->hasMips32r6() ? Mips::OR_MMR6 : Mips::OR_MM,
- Mips::ZERO};
+ if (STI->inMicroMipsMode()) {
+ unsigned LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
+ unsigned SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
+ unsigned BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
+ unsigned BNE = STI->hasMips32r6() ? Mips::BNEC_MMR6 : Mips::BNE_MM;
+ unsigned OR = STI->hasMips32r6() ? Mips::OR_MMR6 : Mips::OR_MM;
+ return {LL, SC, BEQ, BNE, OR, Mips::ZERO};
+ }
bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
- return {STI->hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
- : (ArePtrs64bit ? Mips::LL64 : Mips::LL),
- STI->hasMips32r6() ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
- : (ArePtrs64bit ? Mips::SC64 : Mips::SC),
- Mips::BEQ,
- Mips::BNE,
- Mips::OR,
- Mips::ZERO};
+ unsigned LL = STI->hasMips32r6()
+ ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
+ : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
+ unsigned SC = STI->hasMips32r6()
+ ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
+ : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
+ return {LL, SC, Mips::BEQ, Mips::BNE, Mips::OR, Mips::ZERO};
}
// Merge selected bits as old ^ ((old ^ new) & mask).
More information about the llvm-commits
mailing list