[llvm] c7df6b1 - Revert "[CodeGen][ARM] Implement atomicrmw as pseudo operations at -O0"

Tomas Matheson via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 30 08:53:48 PDT 2021


Author: Tomas Matheson
Date: 2021-04-30T16:53:14+01:00
New Revision: c7df6b1223d88dfd15248fbf7b7b83dacad22ae3

URL: https://github.com/llvm/llvm-project/commit/c7df6b1223d88dfd15248fbf7b7b83dacad22ae3
DIFF: https://github.com/llvm/llvm-project/commit/c7df6b1223d88dfd15248fbf7b7b83dacad22ae3.diff

LOG: Revert "[CodeGen][ARM] Implement atomicrmw as pseudo operations at -O0"

This reverts commit 3338290c187b254ad071f4b9cbf2ddb2623cefc0.

Broke expensive checks on debian.

Added: 
    

Modified: 
    llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
    llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
    llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
    llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
    llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
    llvm/lib/Target/ARM/ARMISelLowering.cpp
    llvm/lib/Target/ARM/ARMInstrInfo.td
    llvm/test/Transforms/AtomicExpand/ARM/atomicrmw-fp.ll

Removed: 
    llvm/test/CodeGen/ARM/atomicrmw_exclusive_monitor_all.ll


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index 5ee4d56bc4fde..966645e3256d2 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -2255,11 +2255,6 @@ void DAGTypeLegalizer::PromoteFloatResult(SDNode *N, unsigned ResNo) {
     case ISD::FREM:
     case ISD::FSUB:       R = PromoteFloatRes_BinOp(N); break;
 
-    case ISD::ATOMIC_LOAD_FADD:
-    case ISD::ATOMIC_LOAD_FSUB:
-      R = PromoteFloatRes_ATOMIC_LOAD_FXXX(N);
-      break;
-
     case ISD::FMA:        // FMA is same as FMAD
     case ISD::FMAD:       R = PromoteFloatRes_FMAD(N); break;
 
@@ -2458,21 +2453,6 @@ SDValue DAGTypeLegalizer::PromoteFloatRes_FP_ROUND(SDNode *N) {
   return DAG.getNode(GetPromotionOpcode(VT, NVT), DL, NVT, Round);
 }
 
-SDValue DAGTypeLegalizer::PromoteFloatRes_ATOMIC_LOAD_FXXX(SDNode *N) {
-  AtomicSDNode *A = cast<AtomicSDNode>(N);
-  EVT VT = N->getValueType(0);
-
-  // Load the value as an integer value with the same number of bits.
-  EVT IVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits());
-  SDValue PromotedVal = GetPromotedFloat(A->getVal());
-  SDValue NewA =
-      DAG.getAtomic(A->getOpcode(), SDLoc(N), IVT, A->getChain(),
-                    A->getBasePtr(), PromotedVal, A->getMemOperand());
-  ReplaceValueWith(SDValue(A, 1), NewA.getValue(1));
-
-  return NewA;
-}
-
 SDValue DAGTypeLegalizer::PromoteFloatRes_LOAD(SDNode *N) {
   LoadSDNode *L = cast<LoadSDNode>(N);
   EVT VT = N->getValueType(0);

diff  --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index f1230f47133d5..a40dd88870335 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -671,7 +671,6 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
   SDValue PromoteFloatRes_FMAD(SDNode *N);
   SDValue PromoteFloatRes_FPOWI(SDNode *N);
   SDValue PromoteFloatRes_FP_ROUND(SDNode *N);
-  SDValue PromoteFloatRes_ATOMIC_LOAD_FXXX(SDNode *N);
   SDValue PromoteFloatRes_LOAD(SDNode *N);
   SDValue PromoteFloatRes_SELECT(SDNode *N);
   SDValue PromoteFloatRes_SELECT_CC(SDNode *N);

diff  --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
index b1697436a9e0e..ed67b1eeb78e7 100644
--- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -928,25 +928,6 @@ void ARMBaseInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
     return;
   }
 
-  // Handle DPR to/from GPRPair
-  const auto *TRI = &getRegisterInfo();
-  if (ARM::DPRRegClass.contains(SrcReg) &&
-      ARM::GPRPairRegClass.contains(DestReg)) {
-    BuildMI(MBB, I, DL, get(ARM::VMOVRRD))
-        .addReg(TRI->getSubReg(DestReg, ARM::gsub_0), RegState::Define)
-        .addReg(TRI->getSubReg(DestReg, ARM::gsub_1), RegState::Define)
-        .addReg(SrcReg, getKillRegState(KillSrc))
-        .add(predOps(ARMCC::AL));
-    return;
-  } else if (ARM::GPRPairRegClass.contains(SrcReg) &&
-             ARM::DPRRegClass.contains(DestReg)) {
-    BuildMI(MBB, I, DL, get(ARM::VMOVDRR), DestReg)
-        .addReg(TRI->getSubReg(SrcReg, ARM::gsub_0), getKillRegState(KillSrc))
-        .addReg(TRI->getSubReg(SrcReg, ARM::gsub_1), getKillRegState(KillSrc))
-        .add(predOps(ARMCC::AL));
-    return;
-  }
-
   // Handle register classes that require multiple instructions.
   unsigned BeginIdx = 0;
   unsigned SubRegs = 0;
@@ -1032,6 +1013,7 @@ void ARMBaseInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
 
   assert(Opc && "Impossible reg-to-reg copy");
 
+  const TargetRegisterInfo *TRI = &getRegisterInfo();
   MachineInstrBuilder Mov;
 
   // Copy register tuples backward when the first Dest reg overlaps with SrcReg.

diff  --git a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
index f2e047a7ee8e8..5fe8e96fa2ec3 100644
--- a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
@@ -107,10 +107,6 @@ namespace {
                         MachineBasicBlock::iterator MBBI, unsigned LdrexOp,
                         unsigned StrexOp, unsigned UxtOp,
                         MachineBasicBlock::iterator &NextMBBI);
-    bool ExpandAtomicOp(MachineBasicBlock &MBB,
-                        MachineBasicBlock::iterator MBBI, const int Size,
-                        unsigned PseudoOp,
-                        MachineBasicBlock::iterator &NextMBBI);
 
     bool ExpandCMP_SWAP_64(MachineBasicBlock &MBB,
                            MachineBasicBlock::iterator MBBI,
@@ -1661,270 +1657,16 @@ bool ARMExpandPseudo::ExpandCMP_SWAP(MachineBasicBlock &MBB,
 /// ARM's ldrexd/strexd take a consecutive register pair (represented as a
 /// single GPRPair register), Thumb's take two separate registers so we need to
 /// extract the subregs from the pair.
-static void addExclusiveRegPair(MachineInstrBuilder &MIB, Register Reg,
+static void addExclusiveRegPair(MachineInstrBuilder &MIB, MachineOperand &Reg,
                                 unsigned Flags, bool IsThumb,
                                 const TargetRegisterInfo *TRI) {
   if (IsThumb) {
-    Register RegLo = TRI->getSubReg(Reg, ARM::gsub_0);
-    Register RegHi = TRI->getSubReg(Reg, ARM::gsub_1);
+    Register RegLo = TRI->getSubReg(Reg.getReg(), ARM::gsub_0);
+    Register RegHi = TRI->getSubReg(Reg.getReg(), ARM::gsub_1);
     MIB.addReg(RegLo, Flags);
     MIB.addReg(RegHi, Flags);
   } else
-    MIB.addReg(Reg, Flags);
-}
-
-static void
-makeAtomicUpdateInstrs(const unsigned PseudoOp, MachineBasicBlock *LoadStoreBB,
-                       const DebugLoc &DL, const ARMBaseInstrInfo *TII,
-                       const Register DestReg, const Register ValReg) {
-
-  auto BasicOp = [&](unsigned Opcode) {
-    auto MIB = BuildMI(LoadStoreBB, DL, TII->get(Opcode), DestReg)
-                   .addReg(DestReg, RegState::Kill)
-                   .addReg(ValReg)
-                   .add(predOps(ARMCC::AL));
-    if (Opcode != ARM::VADDS && Opcode != ARM::VSUBS && Opcode != ARM::VADDD &&
-        Opcode != ARM::VSUBD)
-      // Floating point operations don't have this.
-      // Add 's' bit operand (always reg0 for this)
-      MIB.addReg(0);
-  };
-  auto MinMax = [&](ARMCC::CondCodes Condition) {
-    BuildMI(LoadStoreBB, DL, TII->get(ARM::CMPrr), DestReg)
-        .addReg(ValReg)
-        .add(predOps(ARMCC::AL));
-    BuildMI(LoadStoreBB, DL, TII->get(ARM::MOVr), DestReg)
-        .addReg(ValReg)
-        .add(predOps(Condition))
-        .add(condCodeOp()); // 's' bit
-  };
-
-  switch (PseudoOp) {
-  // No operations (swaps)
-  case ARM::ATOMIC_SWAP_8:
-  case ARM::ATOMIC_SWAP_16:
-  case ARM::ATOMIC_SWAP_32:
-  case ARM::ATOMIC_SWAP_64:
-    llvm_unreachable("Swap should be handled at call site.");
-    return;
-
-  // Basic binary operation
-  case ARM::ATOMIC_LOAD_ADD_8:
-  case ARM::ATOMIC_LOAD_ADD_16:
-  case ARM::ATOMIC_LOAD_ADD_32:
-  case ARM::ATOMIC_LOAD_ADD_64:
-    return BasicOp(ARM::ADDrr);
-  case ARM::ATOMIC_LOAD_SUB_8:
-  case ARM::ATOMIC_LOAD_SUB_16:
-  case ARM::ATOMIC_LOAD_SUB_32:
-  case ARM::ATOMIC_LOAD_SUB_64:
-    return BasicOp(ARM::SUBrr);
-  case ARM::ATOMIC_LOAD_AND_8:
-  case ARM::ATOMIC_LOAD_AND_16:
-  case ARM::ATOMIC_LOAD_AND_32:
-  case ARM::ATOMIC_LOAD_AND_64:
-    return BasicOp(ARM::ANDrr);
-  case ARM::ATOMIC_LOAD_OR_8:
-  case ARM::ATOMIC_LOAD_OR_16:
-  case ARM::ATOMIC_LOAD_OR_32:
-  case ARM::ATOMIC_LOAD_OR_64:
-    return BasicOp(ARM::ORRrr);
-  case ARM::ATOMIC_LOAD_XOR_8:
-  case ARM::ATOMIC_LOAD_XOR_16:
-  case ARM::ATOMIC_LOAD_XOR_32:
-  case ARM::ATOMIC_LOAD_XOR_64:
-    return BasicOp(ARM::EORrr);
-  case ARM::ATOMIC_LOAD_FADD_16:
-  case ARM::ATOMIC_LOAD_FADD_32:
-    return BasicOp(ARM::VADDS);
-  case ARM::ATOMIC_LOAD_FADD_64:
-    return BasicOp(ARM::VADDD);
-  case ARM::ATOMIC_LOAD_FSUB_16:
-  case ARM::ATOMIC_LOAD_FSUB_32:
-    return BasicOp(ARM::VSUBS);
-  case ARM::ATOMIC_LOAD_FSUB_64:
-    return BasicOp(ARM::VSUBD);
-
-  // Minimum or maximum operations
-  case ARM::ATOMIC_LOAD_MAX_8:
-  case ARM::ATOMIC_LOAD_MAX_16:
-  case ARM::ATOMIC_LOAD_MAX_32:
-  case ARM::ATOMIC_LOAD_MAX_64:
-  case ARM::ATOMIC_LOAD_UMAX_8:
-  case ARM::ATOMIC_LOAD_UMAX_16:
-  case ARM::ATOMIC_LOAD_UMAX_32:
-  case ARM::ATOMIC_LOAD_UMAX_64:
-    return MinMax(ARMCC::LE);
-  case ARM::ATOMIC_LOAD_MIN_8:
-  case ARM::ATOMIC_LOAD_MIN_16:
-  case ARM::ATOMIC_LOAD_MIN_32:
-  case ARM::ATOMIC_LOAD_MIN_64:
-  case ARM::ATOMIC_LOAD_UMIN_8:
-  case ARM::ATOMIC_LOAD_UMIN_16:
-  case ARM::ATOMIC_LOAD_UMIN_32:
-  case ARM::ATOMIC_LOAD_UMIN_64:
-    return MinMax(ARMCC::GE);
-
-  // NAND
-  case ARM::ATOMIC_LOAD_NAND_8:
-  case ARM::ATOMIC_LOAD_NAND_16:
-  case ARM::ATOMIC_LOAD_NAND_32:
-  case ARM::ATOMIC_LOAD_NAND_64:
-    BuildMI(LoadStoreBB, DL, TII->get(ARM::ANDrr), DestReg)
-        .addReg(DestReg, RegState::Kill)
-        .addReg(ValReg)
-        .add(predOps(ARMCC::AL))
-        .addReg(0); // 's' bit
-    BuildMI(LoadStoreBB, DL, TII->get(ARM::MVNr), DestReg)
-        .addReg(DestReg, RegState::Kill)
-        .add(predOps(ARMCC::AL))
-        .addReg(0); // 's' bit
-    return;
-  }
-
-  llvm_unreachable("unexpected opcode");
-}
-
-bool ARMExpandPseudo::ExpandAtomicOp(MachineBasicBlock &MBB,
-                                     MachineBasicBlock::iterator MBBI,
-                                     const int Size, const unsigned PseudoOp,
-                                     MachineBasicBlock::iterator &NextMBBI) {
-  assert(!STI->isThumb() && "atomic pseudo-instructions are ARM only");
-
-  unsigned LdrexOp;
-  unsigned StrexOp;
-  switch (Size) {
-  case 8:
-    LdrexOp = ARM::LDREXB;
-    StrexOp = ARM::STREXB;
-    break;
-  case 16:
-    LdrexOp = ARM::LDREXH;
-    StrexOp = ARM::STREXH;
-    break;
-  case 32:
-    LdrexOp = ARM::LDREX;
-    StrexOp = ARM::STREX;
-    break;
-  case 64:
-    LdrexOp = ARM::LDREXD;
-    StrexOp = ARM::STREXD;
-    break;
-  default:
-    llvm_unreachable("Invalid Size");
-  }
-
-  MachineInstr &MI = *MBBI;
-  DebugLoc DL = MI.getDebugLoc();
-  MachineOperand &Dest = MI.getOperand(0);
-  MachineOperand &Temp = MI.getOperand(1);
-  // If Temp is a GPRPair, MiniTempReg is the first of the pair
-  Register MiniTempReg =
-      ARM::GPRPairRegClass.contains(Temp.getReg())
-          ? (Register)TRI->getSubReg(Temp.getReg(), ARM::gsub_0)
-          : Temp.getReg();
-  assert(ARM::GPRRegClass.contains(MiniTempReg));
-  Register AddrReg = MI.getOperand(2).getReg();
-  Register ValReg = MI.getOperand(3).getReg();
-
-  // TempReg is GPR and is used for load/store operations.
-  // DestReg is either GPR or DPR and is used for arithmetic operations.
-
-  // LoadStoreBB:
-  //   TempReg = LoadExclusive [AddrReg]
-  //   DestReg = mov TempReg
-  //   if xchg:
-  //      TempReg = mov ValReg
-  //   else:
-  //      DestReg = Operation DestReg, ValReg
-  //      TempReg = mov DestReg
-  //   MiniTempReg = StoreExclusive TempReg, [AddrReg]
-  //   cmp MiniTempReg, #0
-  //   bne LoadStoreBB
-  //   b DoneBB
-  // DoneBB:
-  //   bx lr
-
-  MachineFunction *MF = MBB.getParent();
-  auto *LoadStoreBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
-  auto *DoneBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
-
-  MF->insert(++MBB.getIterator(), LoadStoreBB);
-  MF->insert(++LoadStoreBB->getIterator(), DoneBB);
-
-  MachineInstrBuilder MIB;
-  // LoadExclusive into temporary general purpose register (pair)
-  MIB = BuildMI(LoadStoreBB, DL, TII->get(LdrexOp));
-  addExclusiveRegPair(MIB, Temp.getReg(), RegState::Define, STI->isThumb(),
-                      TRI);
-  MIB.addReg(AddrReg);
-  MIB.add(predOps(ARMCC::AL));
-
-  // Copy Temp into Dest. For floating point operations this is GPR -> DPR.
-  TII->copyPhysReg(*LoadStoreBB, LoadStoreBB->end(), DL, Dest.getReg(),
-                   Temp.getReg(), true /* KillSrc */);
-
-  const bool IsXchg =
-      PseudoOp == ARM::ATOMIC_SWAP_8 || PseudoOp == ARM::ATOMIC_SWAP_16 ||
-      PseudoOp == ARM::ATOMIC_SWAP_32 || PseudoOp == ARM::ATOMIC_SWAP_64;
-
-  if (IsXchg) {
-    // Copy ValReg into Temp. For floating point operations this is DPR -> GPR.
-    TII->copyPhysReg(*LoadStoreBB, LoadStoreBB->end(), DL, Temp.getReg(),
-                     ValReg, false /* KillSrc */);
-  } else {
-    // Update the value in Dest with the results of the operation
-    makeAtomicUpdateInstrs(PseudoOp, LoadStoreBB, DL, TII, Dest.getReg(),
-                           ValReg);
-
-    // Copy Dest into Temp. For floating point operations this is DPR -> GPR.
-    TII->copyPhysReg(*LoadStoreBB, LoadStoreBB->end(), DL, Temp.getReg(),
-                     Dest.getReg(), false /* KillSrc */);
-  }
-
-  // StoreExclusive Temp to Addr, store success in Temp (or MiniTempReg)
-  MIB = BuildMI(LoadStoreBB, DL, TII->get(StrexOp));
-  addExclusiveRegPair(MIB, MiniTempReg, RegState::Define, STI->isThumb(), TRI);
-  MIB.addReg(Temp.getReg(), RegState::Kill);
-  MIB.addReg(AddrReg);
-  MIB.add(predOps(ARMCC::AL));
-
-  // Compare to zero
-  BuildMI(LoadStoreBB, DL, TII->get(ARM::CMPri))
-      .addReg(MiniTempReg, RegState::Kill)
-      .addImm(0)
-      .add(predOps(ARMCC::AL));
-
-  // Branch to LoadStoreBB if failed
-  BuildMI(LoadStoreBB, DL, TII->get(ARM::Bcc))
-      .addMBB(LoadStoreBB)
-      .addImm(ARMCC::NE)
-      .addReg(ARM::CPSR, RegState::Kill);
-
-  // Branch to DoneBB if success
-  BuildMI(LoadStoreBB, DL, TII->get(ARM::B)).addMBB(DoneBB);
-
-  LoadStoreBB->addSuccessor(LoadStoreBB);
-  LoadStoreBB->addSuccessor(DoneBB);
-
-  // Copy remaining instructions in MBB into DoneBB
-  DoneBB->splice(DoneBB->end(), &MBB, MI, MBB.end());
-  DoneBB->transferSuccessors(&MBB);
-
-  MBB.addSuccessor(LoadStoreBB);
-
-  NextMBBI = MBB.end();
-  MI.eraseFromParent();
-
-  // Recompute livein lists.
-  LivePhysRegs LiveRegs;
-  computeAndAddLiveIns(LiveRegs, *DoneBB);
-  computeAndAddLiveIns(LiveRegs, *LoadStoreBB);
-  // Do an extra pass around the loop to get loop carried registers right.
-  LoadStoreBB->clearLiveIns();
-  computeAndAddLiveIns(LiveRegs, *LoadStoreBB);
-
-  return true;
+    MIB.addReg(Reg.getReg(), Flags);
 }
 
 /// Expand a 64-bit CMP_SWAP to an ldrexd/strexd loop.
@@ -1966,7 +1708,7 @@ bool ARMExpandPseudo::ExpandCMP_SWAP_64(MachineBasicBlock &MBB,
   unsigned LDREXD = IsThumb ? ARM::t2LDREXD : ARM::LDREXD;
   MachineInstrBuilder MIB;
   MIB = BuildMI(LoadCmpBB, DL, TII->get(LDREXD));
-  addExclusiveRegPair(MIB, Dest.getReg(), RegState::Define, IsThumb, TRI);
+  addExclusiveRegPair(MIB, Dest, RegState::Define, IsThumb, TRI);
   MIB.addReg(AddrReg).add(predOps(ARMCC::AL));
 
   unsigned CMPrr = IsThumb ? ARM::tCMPhir : ARM::CMPrr;
@@ -1995,7 +1737,7 @@ bool ARMExpandPseudo::ExpandCMP_SWAP_64(MachineBasicBlock &MBB,
   unsigned STREXD = IsThumb ? ARM::t2STREXD : ARM::STREXD;
   MIB = BuildMI(StoreBB, DL, TII->get(STREXD), TempReg);
   unsigned Flags = getKillRegState(New.isDead());
-  addExclusiveRegPair(MIB, New.getReg(), Flags, IsThumb, TRI);
+  addExclusiveRegPair(MIB, New, Flags, IsThumb, TRI);
   MIB.addReg(AddrReg).add(predOps(ARMCC::AL));
 
   unsigned CMPri = IsThumb ? ARM::t2CMPri : ARM::CMPri;
@@ -3061,64 +2803,6 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
     case ARM::CMP_SWAP_64:
       return ExpandCMP_SWAP_64(MBB, MBBI, NextMBBI);
 
-    case ARM::ATOMIC_LOAD_ADD_8:
-    case ARM::ATOMIC_LOAD_AND_8:
-    case ARM::ATOMIC_LOAD_MAX_8:
-    case ARM::ATOMIC_LOAD_MIN_8:
-    case ARM::ATOMIC_LOAD_NAND_8:
-    case ARM::ATOMIC_LOAD_OR_8:
-    case ARM::ATOMIC_LOAD_SUB_8:
-    case ARM::ATOMIC_LOAD_UMAX_8:
-    case ARM::ATOMIC_LOAD_UMIN_8:
-    case ARM::ATOMIC_LOAD_XOR_8:
-    case ARM::ATOMIC_SWAP_8:
-      return ExpandAtomicOp(MBB, MBBI, 8, Opcode, NextMBBI);
-
-    case ARM::ATOMIC_LOAD_ADD_16:
-    case ARM::ATOMIC_LOAD_AND_16:
-    case ARM::ATOMIC_LOAD_FADD_16:
-    case ARM::ATOMIC_LOAD_FSUB_16:
-    case ARM::ATOMIC_LOAD_MAX_16:
-    case ARM::ATOMIC_LOAD_MIN_16:
-    case ARM::ATOMIC_LOAD_NAND_16:
-    case ARM::ATOMIC_LOAD_OR_16:
-    case ARM::ATOMIC_LOAD_SUB_16:
-    case ARM::ATOMIC_LOAD_UMAX_16:
-    case ARM::ATOMIC_LOAD_UMIN_16:
-    case ARM::ATOMIC_LOAD_XOR_16:
-    case ARM::ATOMIC_SWAP_16:
-      return ExpandAtomicOp(MBB, MBBI, 16, Opcode, NextMBBI);
-
-    case ARM::ATOMIC_LOAD_ADD_32:
-    case ARM::ATOMIC_LOAD_AND_32:
-    case ARM::ATOMIC_LOAD_FADD_32:
-    case ARM::ATOMIC_LOAD_FSUB_32:
-    case ARM::ATOMIC_LOAD_MAX_32:
-    case ARM::ATOMIC_LOAD_MIN_32:
-    case ARM::ATOMIC_LOAD_NAND_32:
-    case ARM::ATOMIC_LOAD_OR_32:
-    case ARM::ATOMIC_LOAD_SUB_32:
-    case ARM::ATOMIC_LOAD_UMAX_32:
-    case ARM::ATOMIC_LOAD_UMIN_32:
-    case ARM::ATOMIC_LOAD_XOR_32:
-    case ARM::ATOMIC_SWAP_32:
-      return ExpandAtomicOp(MBB, MBBI, 32, Opcode, NextMBBI);
-
-    case ARM::ATOMIC_LOAD_ADD_64:
-    case ARM::ATOMIC_LOAD_AND_64:
-    case ARM::ATOMIC_LOAD_FADD_64:
-    case ARM::ATOMIC_LOAD_FSUB_64:
-    case ARM::ATOMIC_LOAD_MAX_64:
-    case ARM::ATOMIC_LOAD_MIN_64:
-    case ARM::ATOMIC_LOAD_NAND_64:
-    case ARM::ATOMIC_LOAD_OR_64:
-    case ARM::ATOMIC_LOAD_SUB_64:
-    case ARM::ATOMIC_LOAD_UMAX_64:
-    case ARM::ATOMIC_LOAD_UMIN_64:
-    case ARM::ATOMIC_LOAD_XOR_64:
-    case ARM::ATOMIC_SWAP_64:
-      return ExpandAtomicOp(MBB, MBBI, 64, Opcode, NextMBBI);
-
     case ARM::tBL_PUSHLR:
     case ARM::BL_PUSHLR: {
       const bool Thumb = Opcode == ARM::tBL_PUSHLR;

diff  --git a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
index 34a188ad69b59..e13a6723abd0c 100644
--- a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -310,7 +310,6 @@ class ARMDAGToDAGISel : public SelectionDAGISel {
   void SelectCMPZ(SDNode *N, bool &SwitchEQNEToPLMI);
 
   void SelectCMP_SWAP(SDNode *N);
-  void SelectAtomicOp(SDNode *N);
 
   /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
   /// inline asm expressions.
@@ -3319,142 +3318,6 @@ void ARMDAGToDAGISel::SelectCMP_SWAP(SDNode *N) {
   CurDAG->RemoveDeadNode(N);
 }
 
-/// Expand atomic operations to size- and type-specific pseudo-instructions
-void ARMDAGToDAGISel::SelectAtomicOp(SDNode *N) {
-  EVT MemTy = cast<MemSDNode>(N)->getMemoryVT();
-  const unsigned Opcode = [&]() {
-    switch (N->getOpcode()) {
-    case ISD::ATOMIC_SWAP:
-      if (MemTy == MVT::i8)
-        return ARM::ATOMIC_SWAP_8;
-      if (MemTy == MVT::i16)
-        return ARM::ATOMIC_SWAP_16;
-      if (MemTy == MVT::i32)
-        return ARM::ATOMIC_SWAP_32;
-      break;
-    case ISD::ATOMIC_LOAD_ADD:
-      if (MemTy == MVT::i8)
-        return ARM::ATOMIC_LOAD_ADD_8;
-      if (MemTy == MVT::i16)
-        return ARM::ATOMIC_LOAD_ADD_16;
-      if (MemTy == MVT::i32)
-        return ARM::ATOMIC_LOAD_ADD_32;
-      break;
-    case ISD::ATOMIC_LOAD_SUB:
-      if (MemTy == MVT::i8)
-        return ARM::ATOMIC_LOAD_SUB_8;
-      if (MemTy == MVT::i16)
-        return ARM::ATOMIC_LOAD_SUB_16;
-      if (MemTy == MVT::i32)
-        return ARM::ATOMIC_LOAD_SUB_32;
-      break;
-    case ISD::ATOMIC_LOAD_AND:
-      if (MemTy == MVT::i8)
-        return ARM::ATOMIC_LOAD_AND_8;
-      if (MemTy == MVT::i16)
-        return ARM::ATOMIC_LOAD_AND_16;
-      if (MemTy == MVT::i32)
-        return ARM::ATOMIC_LOAD_AND_32;
-      break;
-    case ISD::ATOMIC_LOAD_CLR:
-      llvm_unreachable("ATOMIC_LOAD_CLR in SelectAtomicOp");
-      break;
-    case ISD::ATOMIC_LOAD_OR:
-      if (MemTy == MVT::i8)
-        return ARM::ATOMIC_LOAD_OR_8;
-      if (MemTy == MVT::i16)
-        return ARM::ATOMIC_LOAD_OR_16;
-      if (MemTy == MVT::i32)
-        return ARM::ATOMIC_LOAD_OR_32;
-      break;
-    case ISD::ATOMIC_LOAD_XOR:
-      if (MemTy == MVT::i8)
-        return ARM::ATOMIC_LOAD_XOR_8;
-      if (MemTy == MVT::i16)
-        return ARM::ATOMIC_LOAD_XOR_16;
-      if (MemTy == MVT::i32)
-        return ARM::ATOMIC_LOAD_XOR_32;
-      break;
-    case ISD::ATOMIC_LOAD_NAND:
-      if (MemTy == MVT::i8)
-        return ARM::ATOMIC_LOAD_NAND_8;
-      if (MemTy == MVT::i16)
-        return ARM::ATOMIC_LOAD_NAND_16;
-      if (MemTy == MVT::i32)
-        return ARM::ATOMIC_LOAD_NAND_32;
-      break;
-    case ISD::ATOMIC_LOAD_MIN:
-      if (MemTy == MVT::i8)
-        return ARM::ATOMIC_LOAD_MIN_8;
-      if (MemTy == MVT::i16)
-        return ARM::ATOMIC_LOAD_MIN_16;
-      if (MemTy == MVT::i32)
-        return ARM::ATOMIC_LOAD_MIN_32;
-      break;
-    case ISD::ATOMIC_LOAD_MAX:
-      if (MemTy == MVT::i8)
-        return ARM::ATOMIC_LOAD_MAX_8;
-      if (MemTy == MVT::i16)
-        return ARM::ATOMIC_LOAD_MAX_16;
-      if (MemTy == MVT::i32)
-        return ARM::ATOMIC_LOAD_MAX_32;
-      break;
-    case ISD::ATOMIC_LOAD_UMIN:
-      if (MemTy == MVT::i8)
-        return ARM::ATOMIC_LOAD_UMIN_8;
-      if (MemTy == MVT::i16)
-        return ARM::ATOMIC_LOAD_UMIN_16;
-      if (MemTy == MVT::i32)
-        return ARM::ATOMIC_LOAD_UMIN_32;
-      break;
-    case ISD::ATOMIC_LOAD_UMAX:
-      if (MemTy == MVT::i8)
-        return ARM::ATOMIC_LOAD_UMAX_8;
-      if (MemTy == MVT::i16)
-        return ARM::ATOMIC_LOAD_UMAX_16;
-      if (MemTy == MVT::i32)
-        return ARM::ATOMIC_LOAD_UMAX_32;
-      break;
-    case ISD::ATOMIC_LOAD_FADD:
-      if (MemTy == MVT::i16)
-        return ARM::ATOMIC_LOAD_FADD_16; // f16 promoted to f32
-      if (MemTy == MVT::f16)
-        return ARM::ATOMIC_LOAD_FADD_16;
-      if (MemTy == MVT::f32)
-        return ARM::ATOMIC_LOAD_FADD_32;
-      if (MemTy == MVT::f64)
-        return ARM::ATOMIC_LOAD_FADD_64;
-      break;
-    case ISD::ATOMIC_LOAD_FSUB:
-      if (MemTy == MVT::i16)
-        return ARM::ATOMIC_LOAD_FSUB_16; // f16 promoted to f32
-      if (MemTy == MVT::f16)
-        return ARM::ATOMIC_LOAD_FSUB_16;
-      if (MemTy == MVT::f32)
-        return ARM::ATOMIC_LOAD_FSUB_32;
-      if (MemTy == MVT::f64)
-        return ARM::ATOMIC_LOAD_FSUB_64;
-      break;
-    }
-    llvm_unreachable("Unknown AtomicOp type");
-    return ARM::INSTRUCTION_LIST_END;
-  }();
-
-  SDValue Chain = N->getOperand(0);
-  SDValue Addr = N->getOperand(1);
-  SDValue Value = N->getOperand(2);
-  SDNode *Swap = CurDAG->getMachineNode(
-      Opcode, SDLoc(N), CurDAG->getVTList(Value.getValueType(), MVT::Other),
-      {Chain, Addr, Value});
-
-  MachineMemOperand *MemOp = cast<MemSDNode>(N)->getMemOperand();
-  CurDAG->setNodeMemRefs(cast<MachineSDNode>(Swap), {MemOp});
-
-  ReplaceUses(SDValue(N, 0), SDValue(Swap, 0)); // Result
-  ReplaceUses(SDValue(N, 1), SDValue(Swap, 1)); // Chain
-  CurDAG->RemoveDeadNode(N);
-}
-
 static Optional<std::pair<unsigned, unsigned>>
 getContiguousRangeOfSetBits(const APInt &A) {
   unsigned FirstOne = A.getBitWidth() - A.countLeadingZeros() - 1;
@@ -5165,23 +5028,6 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
   case ISD::ATOMIC_CMP_SWAP:
     SelectCMP_SWAP(N);
     return;
-
-  case ISD::ATOMIC_LOAD_ADD:
-  case ISD::ATOMIC_LOAD_SUB:
-  case ISD::ATOMIC_LOAD_AND:
-  case ISD::ATOMIC_LOAD_CLR:
-  case ISD::ATOMIC_LOAD_OR:
-  case ISD::ATOMIC_LOAD_XOR:
-  case ISD::ATOMIC_LOAD_NAND:
-  case ISD::ATOMIC_LOAD_MIN:
-  case ISD::ATOMIC_LOAD_MAX:
-  case ISD::ATOMIC_LOAD_UMIN:
-  case ISD::ATOMIC_LOAD_UMAX:
-  case ISD::ATOMIC_LOAD_FADD:
-  case ISD::ATOMIC_LOAD_FSUB:
-  case ISD::ATOMIC_SWAP:
-    SelectAtomicOp(N);
-    return;
   }
 
   SelectCode(N);

diff  --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 05e4234d2f6ec..1ea4cb4ed6027 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -19057,11 +19057,6 @@ ARMTargetLowering::shouldExpandAtomicLoadInIR(LoadInst *LI) const {
 // and up to 64 bits on the non-M profiles
 TargetLowering::AtomicExpansionKind
 ARMTargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
-  // At -O0 expand pseudo-instructions after register allocation to avoid
-  // inserting spills between ldrex/strex.
-  if (getTargetMachine().getOptLevel() == 0 && !Subtarget->isThumb())
-    return AtomicExpansionKind::None;
-
   if (AI->isFloatingPointOperation())
     return AtomicExpansionKind::CmpXChg;
 

diff  --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td
index 476dcc1890ea0..6b61c598f572f 100644
--- a/llvm/lib/Target/ARM/ARMInstrInfo.td
+++ b/llvm/lib/Target/ARM/ARMInstrInfo.td
@@ -6428,37 +6428,6 @@ def CMP_SWAP_64 : PseudoInst<(outs GPRPair:$Rd, GPR:$temp),
                              NoItinerary, []>, Sched<[]>;
 }
 
-let Constraints = "@earlyclobber $Rd, at earlyclobber $temp",
-    mayLoad = 1, mayStore = 1 in
-multiclass AtomicRMW {
-  def _8 : PseudoInst<(outs GPR:$Rd, GPR:$temp), (ins GPR:$addr, GPR:$new), NoItinerary, []>, Sched<[]>;
-  def _16 : PseudoInst<(outs GPR:$Rd, GPR:$temp), (ins GPR:$addr, GPR:$new), NoItinerary, []>, Sched<[]>;
-  def _32 : PseudoInst<(outs GPR:$Rd, GPR:$temp), (ins GPR:$addr, GPR:$new), NoItinerary, []>, Sched<[]>;
-  def _64 : PseudoInst<(outs GPRPair:$Rd, GPR:$temp), (ins GPR:$addr, GPRPair:$new), NoItinerary, []>, Sched<[]>;
-}
-defm ATOMIC_SWAP : AtomicRMW;
-defm ATOMIC_LOAD_ADD : AtomicRMW;
-defm ATOMIC_LOAD_SUB : AtomicRMW;
-defm ATOMIC_LOAD_AND : AtomicRMW;
-defm ATOMIC_LOAD_CLR : AtomicRMW;
-defm ATOMIC_LOAD_OR : AtomicRMW;
-defm ATOMIC_LOAD_XOR : AtomicRMW;
-defm ATOMIC_LOAD_NAND : AtomicRMW;
-defm ATOMIC_LOAD_MIN : AtomicRMW;
-defm ATOMIC_LOAD_MAX : AtomicRMW;
-defm ATOMIC_LOAD_UMIN : AtomicRMW;
-defm ATOMIC_LOAD_UMAX : AtomicRMW;
-// FADD and FSUB have GPRPair temporary for ldrexd/strexd and the return value of strexd, but DPR for result.
-let Constraints = "@earlyclobber $Rd, at earlyclobber $temp",
-    mayLoad = 1, mayStore = 1 in
-multiclass AtomicRMWFloat {
-  def _16 : PseudoInst<(outs SPR:$Rd, GPR:$temp), (ins GPR:$addr, SPR:$new), NoItinerary, []>, Sched<[]>;
-  def _32 : PseudoInst<(outs SPR:$Rd, GPR:$temp), (ins GPR:$addr, SPR:$new), NoItinerary, []>, Sched<[]>;
-  def _64 : PseudoInst<(outs DPR:$Rd, GPRPair:$temp), (ins GPR:$addr, DPR:$new), NoItinerary, []>, Sched<[]>;
-}
-defm ATOMIC_LOAD_FADD : AtomicRMWFloat;
-defm ATOMIC_LOAD_FSUB : AtomicRMWFloat;
-
 def CompilerBarrier : PseudoInst<(outs), (ins i32imm:$ordering), NoItinerary,
                                  [(atomic_fence timm:$ordering, 0)]> {
   let hasSideEffects = 1;

diff  --git a/llvm/test/CodeGen/ARM/atomicrmw_exclusive_monitor_all.ll b/llvm/test/CodeGen/ARM/atomicrmw_exclusive_monitor_all.ll
deleted file mode 100644
index 363e9336f2416..0000000000000
--- a/llvm/test/CodeGen/ARM/atomicrmw_exclusive_monitor_all.ll
+++ /dev/null
@@ -1,1024 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-
-; Test the instruction sequences produced by atomicrmw instructions. In
-; particular, ensure there are no stores/spills inserted between the exclusive
-; load and stores, which would invalidate the exclusive monitor.
-
-; atomicrmw xchg for floating point types are not implemented yet, so the tests
-; are commented.
-
-; RUN: llc -O0 -o - %s | FileCheck %s --check-prefix=CHECK
-target triple = "armv7-none-eabi"
-
- at atomic_i8 = external global i8
- at atomic_i16 = external global i16
- at atomic_i32 = external global i32
- at atomic_i64 = external global i64
-
- at atomic_half = external global half
- at atomic_float = external global float
- at atomic_double = external global double
-
-define i8 @test_xchg_i8() {
-; CHECK-LABEL: test_xchg_i8:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i8
-; CHECK-NEXT:    movt r2, :upper16:atomic_i8
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB0_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexb r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    mov r1, r3
-; CHECK-NEXT:    strexb r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB0_1
-; CHECK-NEXT:    b .LBB0_2
-; CHECK-NEXT:  .LBB0_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw xchg  i8* @atomic_i8, i8 1 monotonic
-  ret i8 %0
-}
-define i8 @test_add_i8() {
-; CHECK-LABEL: test_add_i8:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i8
-; CHECK-NEXT:    movt r2, :upper16:atomic_i8
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB1_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexb r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    add r0, r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strexb r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB1_1
-; CHECK-NEXT:    b .LBB1_2
-; CHECK-NEXT:  .LBB1_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw add  i8* @atomic_i8, i8 1 monotonic
-  ret i8 %0
-}
-define i8 @test_sub_i8() {
-; CHECK-LABEL: test_sub_i8:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i8
-; CHECK-NEXT:    movt r2, :upper16:atomic_i8
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB2_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexb r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    sub r0, r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strexb r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB2_1
-; CHECK-NEXT:    b .LBB2_2
-; CHECK-NEXT:  .LBB2_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw sub  i8* @atomic_i8, i8 1 monotonic
-  ret i8 %0
-}
-define i8 @test_and_i8() {
-; CHECK-LABEL: test_and_i8:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i8
-; CHECK-NEXT:    movt r2, :upper16:atomic_i8
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB3_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexb r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    and r0, r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strexb r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB3_1
-; CHECK-NEXT:    b .LBB3_2
-; CHECK-NEXT:  .LBB3_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw and  i8* @atomic_i8, i8 1 monotonic
-  ret i8 %0
-}
-define i8 @test_nand_i8() {
-; CHECK-LABEL: test_nand_i8:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i8
-; CHECK-NEXT:    movt r2, :upper16:atomic_i8
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB4_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexb r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    and r0, r0, r3
-; CHECK-NEXT:    mvn r0, r0
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strexb r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB4_1
-; CHECK-NEXT:    b .LBB4_2
-; CHECK-NEXT:  .LBB4_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw nand  i8* @atomic_i8, i8 1 monotonic
-  ret i8 %0
-}
-define i8 @test_or_i8() {
-; CHECK-LABEL: test_or_i8:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i8
-; CHECK-NEXT:    movt r2, :upper16:atomic_i8
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB5_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexb r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    orr r0, r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strexb r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB5_1
-; CHECK-NEXT:    b .LBB5_2
-; CHECK-NEXT:  .LBB5_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw or  i8* @atomic_i8, i8 1 monotonic
-  ret i8 %0
-}
-define i8 @test_xor_i8() {
-; CHECK-LABEL: test_xor_i8:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i8
-; CHECK-NEXT:    movt r2, :upper16:atomic_i8
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB6_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexb r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    eor r0, r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strexb r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB6_1
-; CHECK-NEXT:    b .LBB6_2
-; CHECK-NEXT:  .LBB6_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw xor  i8* @atomic_i8, i8 1 monotonic
-  ret i8 %0
-}
-define i8 @test_max_i8() {
-; CHECK-LABEL: test_max_i8:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i8
-; CHECK-NEXT:    movt r2, :upper16:atomic_i8
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB7_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexb r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    cmp r0, r3
-; CHECK-NEXT:    movle r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strexb r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB7_1
-; CHECK-NEXT:    b .LBB7_2
-; CHECK-NEXT:  .LBB7_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw max  i8* @atomic_i8, i8 1 monotonic
-  ret i8 %0
-}
-define i8 @test_min_i8() {
-; CHECK-LABEL: test_min_i8:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i8
-; CHECK-NEXT:    movt r2, :upper16:atomic_i8
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB8_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexb r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    cmp r0, r3
-; CHECK-NEXT:    movge r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strexb r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB8_1
-; CHECK-NEXT:    b .LBB8_2
-; CHECK-NEXT:  .LBB8_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw min  i8* @atomic_i8, i8 1 monotonic
-  ret i8 %0
-}
-define i8 @test_umax_i8() {
-; CHECK-LABEL: test_umax_i8:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i8
-; CHECK-NEXT:    movt r2, :upper16:atomic_i8
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB9_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexb r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    cmp r0, r3
-; CHECK-NEXT:    movle r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strexb r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB9_1
-; CHECK-NEXT:    b .LBB9_2
-; CHECK-NEXT:  .LBB9_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw umax  i8* @atomic_i8, i8 1 monotonic
-  ret i8 %0
-}
-define i8 @test_umin_i8() {
-; CHECK-LABEL: test_umin_i8:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i8
-; CHECK-NEXT:    movt r2, :upper16:atomic_i8
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB10_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexb r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    cmp r0, r3
-; CHECK-NEXT:    movge r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strexb r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB10_1
-; CHECK-NEXT:    b .LBB10_2
-; CHECK-NEXT:  .LBB10_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw umin  i8* @atomic_i8, i8 1 monotonic
-  ret i8 %0
-}
-
-
-define i16 @test_xchg_i16() {
-; CHECK-LABEL: test_xchg_i16:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i16
-; CHECK-NEXT:    movt r2, :upper16:atomic_i16
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB11_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexh r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    mov r1, r3
-; CHECK-NEXT:    strexh r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB11_1
-; CHECK-NEXT:    b .LBB11_2
-; CHECK-NEXT:  .LBB11_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw xchg  i16* @atomic_i16, i16 1 monotonic
-  ret i16 %0
-}
-define i16 @test_add_i16() {
-; CHECK-LABEL: test_add_i16:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i16
-; CHECK-NEXT:    movt r2, :upper16:atomic_i16
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB12_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexh r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    add r0, r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strexh r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB12_1
-; CHECK-NEXT:    b .LBB12_2
-; CHECK-NEXT:  .LBB12_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw add  i16* @atomic_i16, i16 1 monotonic
-  ret i16 %0
-}
-define i16 @test_sub_i16() {
-; CHECK-LABEL: test_sub_i16:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i16
-; CHECK-NEXT:    movt r2, :upper16:atomic_i16
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB13_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexh r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    sub r0, r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strexh r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB13_1
-; CHECK-NEXT:    b .LBB13_2
-; CHECK-NEXT:  .LBB13_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw sub  i16* @atomic_i16, i16 1 monotonic
-  ret i16 %0
-}
-define i16 @test_and_i16() {
-; CHECK-LABEL: test_and_i16:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i16
-; CHECK-NEXT:    movt r2, :upper16:atomic_i16
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB14_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexh r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    and r0, r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strexh r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB14_1
-; CHECK-NEXT:    b .LBB14_2
-; CHECK-NEXT:  .LBB14_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw and  i16* @atomic_i16, i16 1 monotonic
-  ret i16 %0
-}
-define i16 @test_nand_i16() {
-; CHECK-LABEL: test_nand_i16:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i16
-; CHECK-NEXT:    movt r2, :upper16:atomic_i16
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB15_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexh r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    and r0, r0, r3
-; CHECK-NEXT:    mvn r0, r0
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strexh r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB15_1
-; CHECK-NEXT:    b .LBB15_2
-; CHECK-NEXT:  .LBB15_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw nand  i16* @atomic_i16, i16 1 monotonic
-  ret i16 %0
-}
-define i16 @test_or_i16() {
-; CHECK-LABEL: test_or_i16:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i16
-; CHECK-NEXT:    movt r2, :upper16:atomic_i16
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB16_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexh r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    orr r0, r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strexh r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB16_1
-; CHECK-NEXT:    b .LBB16_2
-; CHECK-NEXT:  .LBB16_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw or  i16* @atomic_i16, i16 1 monotonic
-  ret i16 %0
-}
-define i16 @test_xor_i16() {
-; CHECK-LABEL: test_xor_i16:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i16
-; CHECK-NEXT:    movt r2, :upper16:atomic_i16
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB17_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexh r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    eor r0, r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strexh r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB17_1
-; CHECK-NEXT:    b .LBB17_2
-; CHECK-NEXT:  .LBB17_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw xor  i16* @atomic_i16, i16 1 monotonic
-  ret i16 %0
-}
-define i16 @test_max_i16() {
-; CHECK-LABEL: test_max_i16:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i16
-; CHECK-NEXT:    movt r2, :upper16:atomic_i16
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB18_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexh r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    cmp r0, r3
-; CHECK-NEXT:    movle r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strexh r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB18_1
-; CHECK-NEXT:    b .LBB18_2
-; CHECK-NEXT:  .LBB18_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw max  i16* @atomic_i16, i16 1 monotonic
-  ret i16 %0
-}
-define i16 @test_min_i16() {
-; CHECK-LABEL: test_min_i16:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i16
-; CHECK-NEXT:    movt r2, :upper16:atomic_i16
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB19_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexh r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    cmp r0, r3
-; CHECK-NEXT:    movge r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strexh r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB19_1
-; CHECK-NEXT:    b .LBB19_2
-; CHECK-NEXT:  .LBB19_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw min  i16* @atomic_i16, i16 1 monotonic
-  ret i16 %0
-}
-define i16 @test_umax_i16() {
-; CHECK-LABEL: test_umax_i16:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i16
-; CHECK-NEXT:    movt r2, :upper16:atomic_i16
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB20_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexh r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    cmp r0, r3
-; CHECK-NEXT:    movle r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strexh r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB20_1
-; CHECK-NEXT:    b .LBB20_2
-; CHECK-NEXT:  .LBB20_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw umax  i16* @atomic_i16, i16 1 monotonic
-  ret i16 %0
-}
-define i16 @test_umin_i16() {
-; CHECK-LABEL: test_umin_i16:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i16
-; CHECK-NEXT:    movt r2, :upper16:atomic_i16
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB21_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexh r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    cmp r0, r3
-; CHECK-NEXT:    movge r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strexh r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB21_1
-; CHECK-NEXT:    b .LBB21_2
-; CHECK-NEXT:  .LBB21_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw umin  i16* @atomic_i16, i16 1 monotonic
-  ret i16 %0
-}
-
-
-define i32 @test_xchg_i32() {
-; CHECK-LABEL: test_xchg_i32:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i32
-; CHECK-NEXT:    movt r2, :upper16:atomic_i32
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB22_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrex r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    mov r1, r3
-; CHECK-NEXT:    strex r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB22_1
-; CHECK-NEXT:    b .LBB22_2
-; CHECK-NEXT:  .LBB22_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw xchg  i32* @atomic_i32, i32 1 monotonic
-  ret i32 %0
-}
-define i32 @test_add_i32() {
-; CHECK-LABEL: test_add_i32:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i32
-; CHECK-NEXT:    movt r2, :upper16:atomic_i32
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB23_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrex r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    add r0, r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strex r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB23_1
-; CHECK-NEXT:    b .LBB23_2
-; CHECK-NEXT:  .LBB23_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw add  i32* @atomic_i32, i32 1 monotonic
-  ret i32 %0
-}
-define i32 @test_sub_i32() {
-; CHECK-LABEL: test_sub_i32:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i32
-; CHECK-NEXT:    movt r2, :upper16:atomic_i32
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB24_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrex r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    sub r0, r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strex r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB24_1
-; CHECK-NEXT:    b .LBB24_2
-; CHECK-NEXT:  .LBB24_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw sub  i32* @atomic_i32, i32 1 monotonic
-  ret i32 %0
-}
-define i32 @test_and_i32() {
-; CHECK-LABEL: test_and_i32:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i32
-; CHECK-NEXT:    movt r2, :upper16:atomic_i32
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB25_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrex r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    and r0, r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strex r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB25_1
-; CHECK-NEXT:    b .LBB25_2
-; CHECK-NEXT:  .LBB25_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw and  i32* @atomic_i32, i32 1 monotonic
-  ret i32 %0
-}
-define i32 @test_nand_i32() {
-; CHECK-LABEL: test_nand_i32:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i32
-; CHECK-NEXT:    movt r2, :upper16:atomic_i32
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB26_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrex r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    and r0, r0, r3
-; CHECK-NEXT:    mvn r0, r0
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strex r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB26_1
-; CHECK-NEXT:    b .LBB26_2
-; CHECK-NEXT:  .LBB26_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw nand  i32* @atomic_i32, i32 1 monotonic
-  ret i32 %0
-}
-define i32 @test_or_i32() {
-; CHECK-LABEL: test_or_i32:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i32
-; CHECK-NEXT:    movt r2, :upper16:atomic_i32
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB27_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrex r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    orr r0, r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strex r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB27_1
-; CHECK-NEXT:    b .LBB27_2
-; CHECK-NEXT:  .LBB27_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw or  i32* @atomic_i32, i32 1 monotonic
-  ret i32 %0
-}
-define i32 @test_xor_i32() {
-; CHECK-LABEL: test_xor_i32:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i32
-; CHECK-NEXT:    movt r2, :upper16:atomic_i32
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB28_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrex r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    eor r0, r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strex r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB28_1
-; CHECK-NEXT:    b .LBB28_2
-; CHECK-NEXT:  .LBB28_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw xor  i32* @atomic_i32, i32 1 monotonic
-  ret i32 %0
-}
-define i32 @test_max_i32() {
-; CHECK-LABEL: test_max_i32:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i32
-; CHECK-NEXT:    movt r2, :upper16:atomic_i32
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB29_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrex r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    cmp r0, r3
-; CHECK-NEXT:    movle r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strex r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB29_1
-; CHECK-NEXT:    b .LBB29_2
-; CHECK-NEXT:  .LBB29_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw max  i32* @atomic_i32, i32 1 monotonic
-  ret i32 %0
-}
-define i32 @test_min_i32() {
-; CHECK-LABEL: test_min_i32:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i32
-; CHECK-NEXT:    movt r2, :upper16:atomic_i32
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB30_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrex r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    cmp r0, r3
-; CHECK-NEXT:    movge r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strex r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB30_1
-; CHECK-NEXT:    b .LBB30_2
-; CHECK-NEXT:  .LBB30_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw min  i32* @atomic_i32, i32 1 monotonic
-  ret i32 %0
-}
-define i32 @test_umax_i32() {
-; CHECK-LABEL: test_umax_i32:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i32
-; CHECK-NEXT:    movt r2, :upper16:atomic_i32
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB31_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrex r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    cmp r0, r3
-; CHECK-NEXT:    movle r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strex r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB31_1
-; CHECK-NEXT:    b .LBB31_2
-; CHECK-NEXT:  .LBB31_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw umax  i32* @atomic_i32, i32 1 monotonic
-  ret i32 %0
-}
-define i32 @test_umin_i32() {
-; CHECK-LABEL: test_umin_i32:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_i32
-; CHECK-NEXT:    movt r2, :upper16:atomic_i32
-; CHECK-NEXT:    mov r3, #1
-; CHECK-NEXT:  .LBB32_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrex r1, [r2]
-; CHECK-NEXT:    mov r0, r1
-; CHECK-NEXT:    cmp r0, r3
-; CHECK-NEXT:    movge r0, r3
-; CHECK-NEXT:    mov r1, r0
-; CHECK-NEXT:    strex r1, r1, [r2]
-; CHECK-NEXT:    cmp r1, #0
-; CHECK-NEXT:    bne .LBB32_1
-; CHECK-NEXT:    b .LBB32_2
-; CHECK-NEXT:  .LBB32_2: @ %entry
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw umin  i32* @atomic_i32, i32 1 monotonic
-  ret i32 %0
-}
-
-
-
-define i64 @test_xchg_i64() {
-; CHECK-LABEL: test_xchg_i64:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    push {r11, lr}
-; CHECK-NEXT:    movw r0, :lower16:atomic_i64
-; CHECK-NEXT:    movt r0, :upper16:atomic_i64
-; CHECK-NEXT:    mov r2, #1
-; CHECK-NEXT:    mov r3, #0
-; CHECK-NEXT:    bl __sync_lock_test_and_set_8
-; CHECK-NEXT:    pop {r11, pc}
-entry:
-  %0  = atomicrmw xchg  i64* @atomic_i64, i64 1 monotonic
-  ret i64 %0
-}
-define i64 @test_add_i64() {
-; CHECK-LABEL: test_add_i64:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    push {r11, lr}
-; CHECK-NEXT:    movw r0, :lower16:atomic_i64
-; CHECK-NEXT:    movt r0, :upper16:atomic_i64
-; CHECK-NEXT:    mov r2, #1
-; CHECK-NEXT:    mov r3, #0
-; CHECK-NEXT:    bl __sync_fetch_and_add_8
-; CHECK-NEXT:    pop {r11, pc}
-entry:
-  %0  = atomicrmw add  i64* @atomic_i64, i64 1 monotonic
-  ret i64 %0
-}
-define i64 @test_sub_i64() {
-; CHECK-LABEL: test_sub_i64:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    push {r11, lr}
-; CHECK-NEXT:    movw r0, :lower16:atomic_i64
-; CHECK-NEXT:    movt r0, :upper16:atomic_i64
-; CHECK-NEXT:    mov r2, #1
-; CHECK-NEXT:    mov r3, #0
-; CHECK-NEXT:    bl __sync_fetch_and_sub_8
-; CHECK-NEXT:    pop {r11, pc}
-entry:
-  %0  = atomicrmw sub  i64* @atomic_i64, i64 1 monotonic
-  ret i64 %0
-}
-define i64 @test_and_i64() {
-; CHECK-LABEL: test_and_i64:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    push {r11, lr}
-; CHECK-NEXT:    movw r0, :lower16:atomic_i64
-; CHECK-NEXT:    movt r0, :upper16:atomic_i64
-; CHECK-NEXT:    mov r2, #1
-; CHECK-NEXT:    mov r3, #0
-; CHECK-NEXT:    bl __sync_fetch_and_and_8
-; CHECK-NEXT:    pop {r11, pc}
-entry:
-  %0  = atomicrmw and  i64* @atomic_i64, i64 1 monotonic
-  ret i64 %0
-}
-define i64 @test_nand_i64() {
-; CHECK-LABEL: test_nand_i64:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    push {r11, lr}
-; CHECK-NEXT:    movw r0, :lower16:atomic_i64
-; CHECK-NEXT:    movt r0, :upper16:atomic_i64
-; CHECK-NEXT:    mov r2, #1
-; CHECK-NEXT:    mov r3, #0
-; CHECK-NEXT:    bl __sync_fetch_and_nand_8
-; CHECK-NEXT:    pop {r11, pc}
-entry:
-  %0  = atomicrmw nand  i64* @atomic_i64, i64 1 monotonic
-  ret i64 %0
-}
-define i64 @test_or_i64() {
-; CHECK-LABEL: test_or_i64:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    push {r11, lr}
-; CHECK-NEXT:    movw r0, :lower16:atomic_i64
-; CHECK-NEXT:    movt r0, :upper16:atomic_i64
-; CHECK-NEXT:    mov r2, #1
-; CHECK-NEXT:    mov r3, #0
-; CHECK-NEXT:    bl __sync_fetch_and_or_8
-; CHECK-NEXT:    pop {r11, pc}
-entry:
-  %0  = atomicrmw or  i64* @atomic_i64, i64 1 monotonic
-  ret i64 %0
-}
-define i64 @test_xor_i64() {
-; CHECK-LABEL: test_xor_i64:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    push {r11, lr}
-; CHECK-NEXT:    movw r0, :lower16:atomic_i64
-; CHECK-NEXT:    movt r0, :upper16:atomic_i64
-; CHECK-NEXT:    mov r2, #1
-; CHECK-NEXT:    mov r3, #0
-; CHECK-NEXT:    bl __sync_fetch_and_xor_8
-; CHECK-NEXT:    pop {r11, pc}
-entry:
-  %0  = atomicrmw xor  i64* @atomic_i64, i64 1 monotonic
-  ret i64 %0
-}
-
-
-; ; Test floats
-; define half @test_xchg_half() {
-; entry:
-;   %0  = atomicrmw xchg half* @atomic_half, half 1.0 monotonic
-;   ret half %0
-; }
-define half @test_fadd_half() {
-; CHECK-LABEL: test_fadd_half:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    push {r11, lr}
-; CHECK-NEXT:    movw r1, :lower16:atomic_half
-; CHECK-NEXT:    movt r1, :upper16:atomic_half
-; CHECK-NEXT:    vmov.f32 s2, #1.000000e+00
-; CHECK-NEXT:  .LBB40_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexh r0, [r1]
-; CHECK-NEXT:    vmov s0, r0
-; CHECK-NEXT:    vadd.f32 s0, s0, s2
-; CHECK-NEXT:    vmov r0, s0
-; CHECK-NEXT:    strexh r0, r0, [r1]
-; CHECK-NEXT:    cmp r0, #0
-; CHECK-NEXT:    bne .LBB40_1
-; CHECK-NEXT:    b .LBB40_2
-; CHECK-NEXT:  .LBB40_2: @ %entry
-; CHECK-NEXT:    vmov r0, s0
-; CHECK-NEXT:    bl __gnu_f2h_ieee
-; CHECK-NEXT:    pop {r11, pc}
-entry:
-  %0  = atomicrmw fadd half* @atomic_half, half 1.0 monotonic
-  ret half %0
-}
-define half @test_fsub_half() {
-; CHECK-LABEL: test_fsub_half:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    push {r11, lr}
-; CHECK-NEXT:    movw r1, :lower16:atomic_half
-; CHECK-NEXT:    movt r1, :upper16:atomic_half
-; CHECK-NEXT:    vmov.f32 s2, #1.000000e+00
-; CHECK-NEXT:  .LBB41_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexh r0, [r1]
-; CHECK-NEXT:    vmov s0, r0
-; CHECK-NEXT:    vsub.f32 s0, s0, s2
-; CHECK-NEXT:    vmov r0, s0
-; CHECK-NEXT:    strexh r0, r0, [r1]
-; CHECK-NEXT:    cmp r0, #0
-; CHECK-NEXT:    bne .LBB41_1
-; CHECK-NEXT:    b .LBB41_2
-; CHECK-NEXT:  .LBB41_2: @ %entry
-; CHECK-NEXT:    vmov r0, s0
-; CHECK-NEXT:    bl __gnu_f2h_ieee
-; CHECK-NEXT:    pop {r11, pc}
-entry:
-  %0  = atomicrmw fsub half* @atomic_half, half 1.0 monotonic
-  ret half %0
-}
-; define float @test_xchg_float() {
-; entry:
-;   %0  = atomicrmw xchg float* @atomic_float, float 1.0 monotonic
-;   ret float %0
-; }
-define float @test_fadd_float() {
-; CHECK-LABEL: test_fadd_float:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r1, :lower16:atomic_float
-; CHECK-NEXT:    movt r1, :upper16:atomic_float
-; CHECK-NEXT:    vmov.f32 s2, #1.000000e+00
-; CHECK-NEXT:  .LBB42_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrex r0, [r1]
-; CHECK-NEXT:    vmov s0, r0
-; CHECK-NEXT:    vadd.f32 s0, s0, s2
-; CHECK-NEXT:    vmov r0, s0
-; CHECK-NEXT:    strex r0, r0, [r1]
-; CHECK-NEXT:    cmp r0, #0
-; CHECK-NEXT:    bne .LBB42_1
-; CHECK-NEXT:    b .LBB42_2
-; CHECK-NEXT:  .LBB42_2: @ %entry
-; CHECK-NEXT:    vmov r0, s0
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw fadd float* @atomic_float, float 1.0 monotonic
-  ret float %0
-}
-define float @test_fsub_float() {
-; CHECK-LABEL: test_fsub_float:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r1, :lower16:atomic_float
-; CHECK-NEXT:    movt r1, :upper16:atomic_float
-; CHECK-NEXT:    vmov.f32 s2, #1.000000e+00
-; CHECK-NEXT:  .LBB43_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrex r0, [r1]
-; CHECK-NEXT:    vmov s0, r0
-; CHECK-NEXT:    vsub.f32 s0, s0, s2
-; CHECK-NEXT:    vmov r0, s0
-; CHECK-NEXT:    strex r0, r0, [r1]
-; CHECK-NEXT:    cmp r0, #0
-; CHECK-NEXT:    bne .LBB43_1
-; CHECK-NEXT:    b .LBB43_2
-; CHECK-NEXT:  .LBB43_2: @ %entry
-; CHECK-NEXT:    vmov r0, s0
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw fsub float* @atomic_float, float 1.0 monotonic
-  ret float %0
-}
-; define double @test_xchg_double() {
-; entry:
-;   %0  = atomicrmw xchg double* @atomic_double, double 1.0 monotonic
-;   ret double %0
-; }
-define double @test_fadd_double() {
-; CHECK-LABEL: test_fadd_double:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_double
-; CHECK-NEXT:    movt r2, :upper16:atomic_double
-; CHECK-NEXT:    vmov.f64 d17, #1.000000e+00
-; CHECK-NEXT:  .LBB44_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexd r0, r1, [r2]
-; CHECK-NEXT:    vmov d16, r0, r1
-; CHECK-NEXT:    vadd.f64 d16, d16, d17
-; CHECK-NEXT:    vmov r0, r1, d16
-; CHECK-NEXT:    strexd r0, r0, r1, [r2]
-; CHECK-NEXT:    cmp r0, #0
-; CHECK-NEXT:    bne .LBB44_1
-; CHECK-NEXT:    b .LBB44_2
-; CHECK-NEXT:  .LBB44_2: @ %entry
-; CHECK-NEXT:    vmov r0, r1, d16
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw fadd double* @atomic_double, double 1.0 monotonic
-  ret double %0
-}
-define double @test_fsub_double() {
-; CHECK-LABEL: test_fsub_double:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movw r2, :lower16:atomic_double
-; CHECK-NEXT:    movt r2, :upper16:atomic_double
-; CHECK-NEXT:    vmov.f64 d17, #1.000000e+00
-; CHECK-NEXT:  .LBB45_1: @ %entry
-; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrexd r0, r1, [r2]
-; CHECK-NEXT:    vmov d16, r0, r1
-; CHECK-NEXT:    vsub.f64 d16, d16, d17
-; CHECK-NEXT:    vmov r0, r1, d16
-; CHECK-NEXT:    strexd r0, r0, r1, [r2]
-; CHECK-NEXT:    cmp r0, #0
-; CHECK-NEXT:    bne .LBB45_1
-; CHECK-NEXT:    b .LBB45_2
-; CHECK-NEXT:  .LBB45_2: @ %entry
-; CHECK-NEXT:    vmov r0, r1, d16
-; CHECK-NEXT:    bx lr
-entry:
-  %0  = atomicrmw fsub double* @atomic_double, double 1.0 monotonic
-  ret double %0
-}

diff  --git a/llvm/test/Transforms/AtomicExpand/ARM/atomicrmw-fp.ll b/llvm/test/Transforms/AtomicExpand/ARM/atomicrmw-fp.ll
index b908e75f91819..6f8ffc1cba21f 100644
--- a/llvm/test/Transforms/AtomicExpand/ARM/atomicrmw-fp.ll
+++ b/llvm/test/Transforms/AtomicExpand/ARM/atomicrmw-fp.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -O1 -S -mtriple=armv7-apple-ios7.0 -atomic-expand %s | FileCheck %s
+; RUN: opt -S -mtriple=armv7-apple-ios7.0 -atomic-expand %s | FileCheck %s
 
 define float @test_atomicrmw_fadd_f32(float* %ptr, float %value) {
 ; CHECK-LABEL: @test_atomicrmw_fadd_f32(


        


More information about the llvm-commits mailing list