[llvm] [Mips] Use AtomicExpandPass for subword atomics (PR #225948)

Jiaxun Yang via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 24 02:05:13 PDT 2026


https://github.com/FlyGoat updated https://github.com/llvm/llvm-project/pull/225948

>From 1e6ad8819410db4cc585444036dc247a34602e5a 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 8d12786d52e12..5f08c17b57463 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 ac32426288e08..5dcb010fec2ac 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 b6d820bbc1025..342c03e475de8 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 b39eb9863b042..30e8182ee6e2c 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 d5ba9cbcbe7f8..0755bd6b671c1 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 75604cc20aaf4..85f857151abe3 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 6ffd94c9a72ea..76a6944e1d0d2 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 ec0c0d03ae4ee..75c6c0a8fd190 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 342e7ac31eb5a..1d503a111664b 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 dce05df0f609a..2c1cea59a0041 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 cd7b4c20ce3bd..0d89e2e977ee8 100644
--- a/llvm/lib/Target/Mips/MipsTargetMachine.cpp
+++ b/llvm/lib/Target/Mips/MipsTargetMachine.cpp
@@ -208,7 +208,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;
@@ -270,10 +270,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 0000000000000..9e3945e85191c
--- /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 0000000000000..1141ae9f31d38
--- /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 f3308c4b6ad12..b8dd0edecb1fb 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 5849ba13cc37a..7bbb0c58fbf39 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 f83de83b3d037..4b3e09b31299c 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 8d9c1ca866a75..443f68dadce29 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 906429b14a181..b1708d6392294 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 0000000000000..d5a55bb660dbf
--- /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 0000000000000..41007d54c5238
--- /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 0000000000000..540598c364414
--- /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 0000000000000..6164403b64536
--- /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 0000000000000..97713c4f017ca
--- /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 cd9f25ffb53846d8b479f1f4de63d1156904c122 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 30e8182ee6e2c..b689ce4da8666 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