[llvm] r320791 - [PowerPC] Convert r+r instructions to r+i (pre and post RA)

Nemanja Ivanovic via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 14 23:27:53 PST 2017


Author: nemanjai
Date: Thu Dec 14 23:27:53 2017
New Revision: 320791

URL: http://llvm.org/viewvc/llvm-project?rev=320791&view=rev
Log:
[PowerPC] Convert r+r instructions to r+i (pre and post RA)

This patch adds the necessary infrastructure to convert instructions that
take two register operands to those that take a register and immediate if
the necessary operand is produced by a load-immediate. Furthermore, it uses
this infrastructure to perform such conversions twice - first at MachineSSA
and then pre-emit.

There are a number of reasons we may end up with opportunities for this
transformation, including but not limited to:
- X-Form instructions chosen since the exact offset isn't available at ISEL time
- Atomic instructions with constant operands (we will add patterns for this
  in the future)
- Tail duplication may duplicate code where one block contains this redundancy
- When emitting compare-free code in PPCDAGToDAGISel, we don't handle constant
  comparands specially

Furthermore, this patch moves the initialization of PPCMIPeepholePass so that
it can be used for MIR tests.

Added:
    llvm/trunk/lib/Target/PowerPC/PPCPreEmitPeephole.cpp
    llvm/trunk/test/CodeGen/PowerPC/convert-rr-to-ri-instrs-R0-special-handling.mir
    llvm/trunk/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir
    llvm/trunk/test/CodeGen/PowerPC/simplifyConstCmpToISEL.ll
Modified:
    llvm/trunk/lib/Target/PowerPC/CMakeLists.txt
    llvm/trunk/lib/Target/PowerPC/PPC.h
    llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td
    llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp
    llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h
    llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td
    llvm/trunk/lib/Target/PowerPC/PPCMIPeephole.cpp
    llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp
    llvm/trunk/test/CodeGen/PowerPC/build-vector-tests.ll
    llvm/trunk/test/CodeGen/PowerPC/fast-isel-call.ll
    llvm/trunk/test/CodeGen/PowerPC/setcc-logic.ll
    llvm/trunk/test/CodeGen/PowerPC/unaligned.ll
    llvm/trunk/test/CodeGen/PowerPC/variable_elem_vec_extracts.ll

Modified: llvm/trunk/lib/Target/PowerPC/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/CMakeLists.txt?rev=320791&r1=320790&r2=320791&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/CMakeLists.txt (original)
+++ llvm/trunk/lib/Target/PowerPC/CMakeLists.txt Thu Dec 14 23:27:53 2017
@@ -43,6 +43,7 @@ add_llvm_target(PowerPCCodeGen
   PPCVSXFMAMutate.cpp
   PPCVSXSwapRemoval.cpp
   PPCExpandISEL.cpp
+  PPCPreEmitPeephole.cpp
   )
 
 add_subdirectory(AsmParser)

Modified: llvm/trunk/lib/Target/PowerPC/PPC.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPC.h?rev=320791&r1=320790&r2=320791&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPC.h (original)
+++ llvm/trunk/lib/Target/PowerPC/PPC.h Thu Dec 14 23:27:53 2017
@@ -50,6 +50,7 @@ namespace llvm {
   FunctionPass *createPPCTLSDynamicCallPass();
   FunctionPass *createPPCBoolRetToIntPass();
   FunctionPass *createPPCExpandISELPass();
+  FunctionPass *createPPCPreEmitPeepholePass();
   void LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
                                     AsmPrinter &AP, bool isDarwin);
   bool LowerPPCMachineOperandToMCOperand(const MachineOperand &MO,
@@ -59,7 +60,9 @@ namespace llvm {
   void initializePPCVSXFMAMutatePass(PassRegistry&);
   void initializePPCBoolRetToIntPass(PassRegistry&);
   void initializePPCExpandISELPass(PassRegistry &);
+  void initializePPCPreEmitPeepholePass(PassRegistry &);
   void initializePPCTLSDynamicCallPass(PassRegistry &);
+  void initializePPCMIPeepholePass(PassRegistry&);
   extern char &PPCVSXFMAMutateID;
 
   namespace PPCII {

Modified: llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td?rev=320791&r1=320790&r2=320791&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td Thu Dec 14 23:27:53 2017
@@ -194,6 +194,11 @@ def : Pat<(PPCcall_nop (i64 texternalsym
           (BL8_NOP texternalsym:$dst)>;
 
 // Atomic operations
+// FIXME: some of these might be used with constant operands. This will result
+// in constant materialization instructions that may be redundant. We currently
+// clean this up in PPCMIPeephole with calls to
+// PPCInstrInfo::convertToImmediateForm() but we should probably not emit them
+// in the first place.
 let usesCustomInserter = 1 in {
   let Defs = [CR0] in {
     def ATOMIC_LOAD_ADD_I64 : Pseudo<

Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp?rev=320791&r1=320790&r2=320791&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp Thu Dec 14 23:27:53 2017
@@ -51,6 +51,10 @@ STATISTIC(NumStoreSPILLVSRRCAsVec,
 STATISTIC(NumStoreSPILLVSRRCAsGpr,
           "Number of spillvsrrc spilled to stack as gpr");
 STATISTIC(NumGPRtoVSRSpill, "Number of gpr spills to spillvsrrc");
+STATISTIC(CmpIselsConverted,
+          "Number of ISELs that depend on comparison of constants converted");
+STATISTIC(MissedConvertibleImmediateInstrs,
+          "Number of compare-immediate instructions fed by constants");
 
 static cl::
 opt<bool> DisableCTRLoopAnal("disable-ppc-ctrloop-analysis", cl::Hidden,
@@ -2147,6 +2151,816 @@ bool PPCInstrInfo::expandPostRAPseudo(Ma
   return false;
 }
 
+unsigned PPCInstrInfo::lookThruCopyLike(unsigned SrcReg,
+                                        const MachineRegisterInfo *MRI) {
+  while (true) {
+    MachineInstr *MI = MRI->getVRegDef(SrcReg);
+    if (!MI->isCopyLike())
+      return SrcReg;
+
+    unsigned CopySrcReg;
+    if (MI->isCopy())
+      CopySrcReg = MI->getOperand(1).getReg();
+    else {
+      assert(MI->isSubregToReg() && "Bad opcode for lookThruCopyLike");
+      CopySrcReg = MI->getOperand(2).getReg();
+    }
+
+    if (!TargetRegisterInfo::isVirtualRegister(CopySrcReg))
+      return CopySrcReg;
+
+    SrcReg = CopySrcReg;
+  }
+}
+
+// Essentially a compile-time implementation of a compare->isel sequence.
+// It takes two constants to compare, along with the true/false registers
+// and the comparison type (as a subreg to a CR field) and returns one
+// of the true/false registers, depending on the comparison results.
+static unsigned selectReg(int64_t Imm1, int64_t Imm2, unsigned CompareOpc,
+                          unsigned TrueReg, unsigned FalseReg,
+                          unsigned CRSubReg) {
+  // Signed comparisons. The immediates are assumed to be sign-extended.
+  if (CompareOpc == PPC::CMPWI || CompareOpc == PPC::CMPDI) {
+    switch (CRSubReg) {
+    default: llvm_unreachable("Unknown integer comparison type.");
+    case PPC::sub_lt:
+      return Imm1 < Imm2 ? TrueReg : FalseReg;
+    case PPC::sub_gt:
+      return Imm1 > Imm2 ? TrueReg : FalseReg;
+    case PPC::sub_eq:
+      return Imm1 == Imm2 ? TrueReg : FalseReg;
+    }
+  }
+  // Unsigned comparisons.
+  else if (CompareOpc == PPC::CMPLWI || CompareOpc == PPC::CMPLDI) {
+    switch (CRSubReg) {
+    default: llvm_unreachable("Unknown integer comparison type.");
+    case PPC::sub_lt:
+      return (uint64_t)Imm1 < (uint64_t)Imm2 ? TrueReg : FalseReg;
+    case PPC::sub_gt:
+      return (uint64_t)Imm1 > (uint64_t)Imm2 ? TrueReg : FalseReg;
+    case PPC::sub_eq:
+      return Imm1 == Imm2 ? TrueReg : FalseReg;
+    }
+  }
+  return PPC::NoRegister;
+}
+
+// Replace an instruction with one that materializes a constant (and sets
+// CR0 if the original instruction was a record-form instruction).
+void PPCInstrInfo::replaceInstrWithLI(MachineInstr &MI,
+                                      const LoadImmediateInfo &LII) const {
+  // Remove existing operands.
+  int OperandToKeep = LII.SetCR ? 1 : 0;
+  for (int i = MI.getNumOperands() - 1; i > OperandToKeep; i--)
+    MI.RemoveOperand(i);
+
+  // Replace the instruction.
+  if (LII.SetCR)
+    MI.setDesc(get(LII.Is64Bit ? PPC::ANDIo8 : PPC::ANDIo));
+  else
+    MI.setDesc(get(LII.Is64Bit ? PPC::LI8 : PPC::LI));
+
+  // Set the immediate.
+  MachineInstrBuilder(*MI.getParent()->getParent(), MI)
+      .addImm(LII.Imm);
+}
+
+MachineInstr *PPCInstrInfo::getConstantDefMI(MachineInstr &MI,
+                                             unsigned &ConstOp,
+                                             bool &SeenIntermediateUse) const {
+  ConstOp = ~0U;
+  MachineInstr *DefMI = nullptr;
+  MachineRegisterInfo *MRI = &MI.getParent()->getParent()->getRegInfo();
+  // If we'ere in SSA, get the defs through the MRI. Otherwise, only look
+  // within the basic block to see if the register is defined using an LI/LI8.
+  if (MRI->isSSA()) {
+    for (int i = 1, e = MI.getNumOperands(); i < e; i++) {
+      if (!MI.getOperand(i).isReg())
+        continue;
+      unsigned Reg = MI.getOperand(i).getReg();
+      if (!TargetRegisterInfo::isVirtualRegister(Reg))
+        continue;
+      unsigned TrueReg = lookThruCopyLike(Reg, MRI);
+      if (TargetRegisterInfo::isVirtualRegister(TrueReg)) {
+        DefMI = MRI->getVRegDef(TrueReg);
+        if (DefMI->getOpcode() == PPC::LI || DefMI->getOpcode() == PPC::LI8) {
+          ConstOp = i;
+          break;
+        }
+      }
+    }
+  } else {
+    // Looking back through the definition for each operand could be expensive,
+    // so exit early if this isn't an instruction that either has an immediate
+    // form or is already an immediate form that we can handle.
+    ImmInstrInfo III;
+    unsigned Opc = MI.getOpcode();
+    bool ConvertibleImmForm =
+      Opc == PPC::CMPWI || Opc == PPC::CMPLWI ||
+      Opc == PPC::CMPDI || Opc == PPC::CMPLDI ||
+      Opc == PPC::ADDI || Opc == PPC::ADDI8 ||
+      Opc == PPC::ORI || Opc == PPC::ORI8 ||
+      Opc == PPC::XORI || Opc == PPC::XORI8 ||
+      Opc == PPC::RLDICL || Opc == PPC::RLDICLo ||
+      Opc == PPC::RLDICL_32 || Opc == PPC::RLDICL_32_64 ||
+      Opc == PPC::RLWINM || Opc == PPC::RLWINMo ||
+      Opc == PPC::RLWINM8 || Opc == PPC::RLWINM8o;
+    if (!instrHasImmForm(MI, III) && !ConvertibleImmForm)
+      return nullptr;
+
+    // Don't convert or %X, %Y, %Y since that's just a register move.
+    if ((Opc == PPC::OR || Opc == PPC::OR8) &&
+        MI.getOperand(1).getReg() == MI.getOperand(2).getReg())
+      return nullptr;
+    for (int i = 1, e = MI.getNumOperands(); i < e; i++) {
+      MachineOperand &MO = MI.getOperand(i);
+      SeenIntermediateUse = false;
+      if (MO.isReg() && MO.isUse() && !MO.isImplicit()) {
+        MachineBasicBlock::reverse_iterator E = MI.getParent()->rend(), It = MI;
+        It++;
+        unsigned Reg = MI.getOperand(i).getReg();
+
+        // Is this register defined by a load-immediate in this block?
+        for ( ; It != E; ++It) {
+          if (It->modifiesRegister(Reg, &getRegisterInfo())) {
+            if (It->getOpcode() == PPC::LI || It->getOpcode() == PPC::LI8) {
+              ConstOp = i;
+              return &*It;
+            } else
+              break;
+          } else if (It->readsRegister(Reg, &getRegisterInfo()))
+            // If we see another use of this reg between the def and the MI,
+            // we want to flat it so the def isn't deleted.
+            SeenIntermediateUse = true;
+        }
+      }
+    }
+  }
+  return ConstOp == ~0U ? nullptr : DefMI;
+}
+
+// If this instruction has an immediate form and one of its operands is a
+// result of a load-immediate, convert it to the immediate form if the constant
+// is in range.
+bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI,
+                                          MachineInstr **KilledDef) const {
+  MachineFunction *MF = MI.getParent()->getParent();
+  MachineRegisterInfo *MRI = &MF->getRegInfo();
+  bool PostRA = !MRI->isSSA();
+  bool SeenIntermediateUse = true;
+  unsigned ConstantOperand = ~0U;
+  MachineInstr *DefMI = getConstantDefMI(MI, ConstantOperand,
+                                         SeenIntermediateUse);
+  if (!DefMI || !DefMI->getOperand(1).isImm())
+    return false;
+  assert(ConstantOperand < MI.getNumOperands() &&
+         "The constant operand needs to be valid at this point");
+
+  int64_t Immediate = DefMI->getOperand(1).getImm();
+  // Sign-extend to 64-bits.
+  int64_t SExtImm = ((uint64_t)Immediate & ~0x7FFFuLL) != 0 ?
+    (Immediate | 0xFFFFFFFFFFFF0000) : Immediate;
+
+  if (KilledDef && MI.getOperand(ConstantOperand).isKill() &&
+      !SeenIntermediateUse)
+    *KilledDef = DefMI;
+
+  // If this is a reg+reg instruction that has a reg+imm form, convert it now.
+  ImmInstrInfo III;
+  if (instrHasImmForm(MI, III))
+    return transformToImmForm(MI, III, ConstantOperand, SExtImm);
+
+  bool ReplaceWithLI = false;
+  bool Is64BitLI = false;
+  int64_t NewImm = 0;
+  bool SetCR = false;
+  unsigned Opc = MI.getOpcode();
+  switch (Opc) {
+  default: return false;
+
+  // FIXME: Any branches conditional on such a comparison can be made
+  // unconditional. At this time, this happens too infrequently to be worth
+  // the implementation effort, but if that ever changes, we could convert
+  // such a pattern here.
+  case PPC::CMPWI:
+  case PPC::CMPLWI:
+  case PPC::CMPDI:
+  case PPC::CMPLDI: {
+    // Doing this post-RA would require dataflow analysis to reliably find uses
+    // of the CR register set by the compare.
+    if (PostRA)
+      return false;
+    // If a compare-immediate is fed by an immediate and is itself an input of
+    // an ISEL (the most common case) into a COPY of the correct register.
+    bool Changed = false;
+    unsigned DefReg = MI.getOperand(0).getReg();
+    int64_t Comparand = MI.getOperand(2).getImm();
+    int64_t SExtComparand = ((uint64_t)Comparand & ~0x7FFFuLL) != 0 ?
+      (Comparand | 0xFFFFFFFFFFFF0000) : Comparand;
+
+    for (auto &CompareUseMI : MRI->use_instructions(DefReg)) {
+      unsigned UseOpc = CompareUseMI.getOpcode();
+      if (UseOpc != PPC::ISEL && UseOpc != PPC::ISEL8)
+        continue;
+      unsigned CRSubReg = CompareUseMI.getOperand(3).getSubReg();
+      unsigned TrueReg = CompareUseMI.getOperand(1).getReg();
+      unsigned FalseReg = CompareUseMI.getOperand(2).getReg();
+      unsigned RegToCopy = selectReg(SExtImm, SExtComparand, Opc, TrueReg,
+                                     FalseReg, CRSubReg);
+      if (RegToCopy == PPC::NoRegister)
+        continue;
+      // Can't use PPC::COPY to copy PPC::ZERO[8]. Convert it to LI[8] 0.
+      if (RegToCopy == PPC::ZERO || RegToCopy == PPC::ZERO8) {
+        CompareUseMI.setDesc(get(UseOpc == PPC::ISEL8 ? PPC::LI8 : PPC::LI));
+        CompareUseMI.getOperand(1).ChangeToImmediate(0);
+        CompareUseMI.RemoveOperand(3);
+        CompareUseMI.RemoveOperand(2);
+        continue;
+      }
+      DEBUG(dbgs() << "Found LI -> CMPI -> ISEL, replacing with a copy.\n");
+      DEBUG(DefMI->dump(); MI.dump(); CompareUseMI.dump());
+      DEBUG(dbgs() << "Is converted to:\n");
+      // Convert to copy and remove unneeded operands.
+      CompareUseMI.setDesc(get(PPC::COPY));
+      CompareUseMI.RemoveOperand(3);
+      CompareUseMI.RemoveOperand(RegToCopy == TrueReg ? 2 : 1);
+      CmpIselsConverted++;
+      Changed = true;
+      DEBUG(CompareUseMI.dump());
+    }
+    if (Changed)
+      return true;
+    // This may end up incremented multiple times since this function is called
+    // during a fixed-point transformation, but it is only meant to indicate the
+    // presence of this opportunity.
+    MissedConvertibleImmediateInstrs++;
+    return false;
+  }
+
+  // Immediate forms - may simply be convertable to an LI.
+  case PPC::ADDI:
+  case PPC::ADDI8: {
+    // Does the sum fit in a 16-bit signed field?
+    int64_t Addend = MI.getOperand(2).getImm();
+    if (isInt<16>(Addend + SExtImm)) {
+      ReplaceWithLI = true;
+      Is64BitLI = Opc == PPC::ADDI8;
+      NewImm = Addend + SExtImm;
+      break;
+    }
+  }
+  case PPC::RLDICL:
+  case PPC::RLDICLo:
+  case PPC::RLDICL_32:
+  case PPC::RLDICL_32_64: {
+    // Use APInt's rotate function.
+    int64_t SH = MI.getOperand(2).getImm();
+    int64_t MB = MI.getOperand(3).getImm();
+    APInt InVal(Opc == PPC::RLDICL ? 64 : 32, SExtImm, true);
+    InVal = InVal.rotl(SH);
+    uint64_t Mask = (1LU << (63 - MB + 1)) - 1;
+    InVal &= Mask;
+    // Can't replace negative values with an LI as that will sign-extend
+    // and not clear the left bits. If we're setting the CR bit, we will use
+    // ANDIo which won't sign extend, so that's safe.
+    if (isUInt<15>(InVal.getSExtValue()) ||
+        (Opc == PPC::RLDICLo && isUInt<16>(InVal.getSExtValue()))) {
+      ReplaceWithLI = true;
+      Is64BitLI = Opc != PPC::RLDICL_32;
+      NewImm = InVal.getSExtValue();
+      SetCR = Opc == PPC::RLDICLo;
+      break;
+    }
+    return false;
+  }
+  case PPC::RLWINM:
+  case PPC::RLWINM8:
+  case PPC::RLWINMo:
+  case PPC::RLWINM8o: {
+    int64_t SH = MI.getOperand(2).getImm();
+    int64_t MB = MI.getOperand(3).getImm();
+    int64_t ME = MI.getOperand(4).getImm();
+    APInt InVal(32, SExtImm, true);
+    InVal = InVal.rotl(SH);
+    // Set the bits (       MB + 32      ) to (       ME + 32      ).
+    uint64_t Mask = ((1 << (32 - MB)) - 1) & ~((1 << (31 - ME)) - 1);
+    InVal &= Mask;
+    // Can't replace negative values with an LI as that will sign-extend
+    // and not clear the left bits. If we're setting the CR bit, we will use
+    // ANDIo which won't sign extend, so that's safe.
+    bool ValueFits = isUInt<15>(InVal.getSExtValue());
+    ValueFits |= ((Opc == PPC::RLWINMo || Opc == PPC::RLWINM8o) &&
+                  isUInt<16>(InVal.getSExtValue()));
+    if (ValueFits) {
+      ReplaceWithLI = true;
+      Is64BitLI = Opc == PPC::RLWINM8 || Opc == PPC::RLWINM8o;
+      NewImm = InVal.getSExtValue();
+      SetCR = Opc == PPC::RLWINMo || Opc == PPC::RLWINM8o;
+      break;
+    }
+    return false;
+  }
+  case PPC::ORI:
+  case PPC::ORI8:
+  case PPC::XORI:
+  case PPC::XORI8: {
+    int64_t LogicalImm = MI.getOperand(2).getImm();
+    int64_t Result = 0;
+    if (Opc == PPC::ORI || Opc == PPC::ORI8)
+      Result = LogicalImm | SExtImm;
+    else
+      Result = LogicalImm ^ SExtImm;
+    if (isInt<16>(Result)) {
+      ReplaceWithLI = true;
+      Is64BitLI = Opc == PPC::ORI8 || Opc == PPC::XORI8;
+      NewImm = Result;
+      break;
+    }
+    return false;
+  }
+  }
+
+  if (ReplaceWithLI) {
+    DEBUG(dbgs() << "Replacing instruction:\n");
+    DEBUG(MI.dump());
+    DEBUG(dbgs() << "Fed by:\n");
+    DEBUG(DefMI->dump());
+    LoadImmediateInfo LII;
+    LII.Imm = NewImm;
+    LII.Is64Bit = Is64BitLI;
+    LII.SetCR = SetCR;
+    // If we're setting the CR, the original load-immediate must be kept (as an
+    // operand to ANDIo/ANDI8o).
+    if (KilledDef && SetCR)
+      *KilledDef = nullptr;
+    replaceInstrWithLI(MI, LII);
+    DEBUG(dbgs() << "With:\n");
+    DEBUG(MI.dump());
+    return true;
+  }
+  return false;
+}
+
+bool PPCInstrInfo::instrHasImmForm(const MachineInstr &MI,
+                                   ImmInstrInfo &III) const {
+  unsigned Opc = MI.getOpcode();
+  // The vast majority of the instructions would need their operand 2 replaced
+  // with an immediate when switching to the reg+imm form. A marked exception
+  // are the update form loads/stores for which a constant operand 2 would need
+  // to turn into a displacement and move operand 1 to the operand 2 position.
+  III.ImmOpNo = 2;
+  III.ConstantOpNo = 2;
+  III.ImmWidth = 16;
+  III.ImmMustBeMultipleOf = 1;
+  switch (Opc) {
+  default: return false;
+  case PPC::ADD4:
+  case PPC::ADD8:
+    III.SignedImm = true;
+    III.ZeroIsSpecialOrig = 0;
+    III.ZeroIsSpecialNew = 1;
+    III.IsCommutative = true;
+    III.ImmOpcode = Opc == PPC::ADD4 ? PPC::ADDI : PPC::ADDI8;
+    break;
+  case PPC::ADDC:
+  case PPC::ADDC8:
+    III.SignedImm = true;
+    III.ZeroIsSpecialOrig = 0;
+    III.ZeroIsSpecialNew = 0;
+    III.IsCommutative = true;
+    III.ImmOpcode = Opc == PPC::ADDC ? PPC::ADDIC : PPC::ADDIC8;
+    break;
+  case PPC::ADDCo:
+    III.SignedImm = true;
+    III.ZeroIsSpecialOrig = 0;
+    III.ZeroIsSpecialNew = 0;
+    III.IsCommutative = true;
+    III.ImmOpcode = PPC::ADDICo;
+    break;
+  case PPC::SUBFC:
+  case PPC::SUBFC8:
+    III.SignedImm = true;
+    III.ZeroIsSpecialOrig = 0;
+    III.ZeroIsSpecialNew = 0;
+    III.IsCommutative = false;
+    III.ImmOpcode = Opc == PPC::SUBFC ? PPC::SUBFIC : PPC::SUBFIC8;
+    break;
+  case PPC::CMPW:
+  case PPC::CMPD:
+    III.SignedImm = true;
+    III.ZeroIsSpecialOrig = 0;
+    III.ZeroIsSpecialNew = 0;
+    III.IsCommutative = false;
+    III.ImmOpcode = Opc == PPC::CMPW ? PPC::CMPWI : PPC::CMPDI;
+    break;
+  case PPC::CMPLW:
+  case PPC::CMPLD:
+    III.SignedImm = false;
+    III.ZeroIsSpecialOrig = 0;
+    III.ZeroIsSpecialNew = 0;
+    III.IsCommutative = false;
+    III.ImmOpcode = Opc == PPC::CMPLW ? PPC::CMPLWI : PPC::CMPLDI;
+    break;
+  case PPC::ANDo:
+  case PPC::AND8o:
+  case PPC::OR:
+  case PPC::OR8:
+  case PPC::XOR:
+  case PPC::XOR8:
+    III.SignedImm = false;
+    III.ZeroIsSpecialOrig = 0;
+    III.ZeroIsSpecialNew = 0;
+    III.IsCommutative = true;
+    switch(Opc) {
+    default: llvm_unreachable("Unknown opcode");
+    case PPC::ANDo: III.ImmOpcode = PPC::ANDIo; break;
+    case PPC::AND8o: III.ImmOpcode = PPC::ANDIo8; break;
+    case PPC::OR: III.ImmOpcode = PPC::ORI; break;
+    case PPC::OR8: III.ImmOpcode = PPC::ORI8; break;
+    case PPC::XOR: III.ImmOpcode = PPC::XORI; break;
+    case PPC::XOR8: III.ImmOpcode = PPC::XORI8; break;
+    }
+    break;
+  case PPC::RLWNM:
+  case PPC::RLWNM8:
+  case PPC::RLWNMo:
+  case PPC::RLWNM8o:
+  case PPC::RLDCL:
+  case PPC::RLDCLo:
+  case PPC::RLDCR:
+  case PPC::RLDCRo:
+  case PPC::SLW:
+  case PPC::SLW8:
+  case PPC::SLWo:
+  case PPC::SLW8o:
+  case PPC::SRW:
+  case PPC::SRW8:
+  case PPC::SRWo:
+  case PPC::SRW8o:
+  case PPC::SRAW:
+  case PPC::SRAWo:
+  case PPC::SLD:
+  case PPC::SLDo:
+  case PPC::SRD:
+  case PPC::SRDo:
+  case PPC::SRAD:
+  case PPC::SRADo:
+    III.SignedImm = false;
+    III.ZeroIsSpecialOrig = 0;
+    III.ZeroIsSpecialNew = 0;
+    III.IsCommutative = false;
+    // This isn't actually true, but the instructions ignore any of the
+    // upper bits, so any immediate loaded with an LI is acceptable.
+    III.ImmWidth = 16;
+    switch(Opc) {
+    default: llvm_unreachable("Unknown opcode");
+    case PPC::RLWNM: III.ImmOpcode = PPC::RLWINM; break;
+    case PPC::RLWNM8: III.ImmOpcode = PPC::RLWINM8; break;
+    case PPC::RLWNMo: III.ImmOpcode = PPC::RLWINMo; break;
+    case PPC::RLWNM8o: III.ImmOpcode = PPC::RLWINM8o; break;
+    case PPC::RLDCL: III.ImmOpcode = PPC::RLDICL; break;
+    case PPC::RLDCLo: III.ImmOpcode = PPC::RLDICLo; break;
+    case PPC::RLDCR: III.ImmOpcode = PPC::RLDICR; break;
+    case PPC::RLDCRo: III.ImmOpcode = PPC::RLDICRo; break;
+    case PPC::SLW: III.ImmOpcode = PPC::RLWINM; break;
+    case PPC::SLW8: III.ImmOpcode = PPC::RLWINM8; break;
+    case PPC::SLWo: III.ImmOpcode = PPC::RLWINMo; break;
+    case PPC::SLW8o: III.ImmOpcode = PPC::RLWINM8o; break;
+    case PPC::SRW: III.ImmOpcode = PPC::RLWINM; break;
+    case PPC::SRW8: III.ImmOpcode = PPC::RLWINM8; break;
+    case PPC::SRWo: III.ImmOpcode = PPC::RLWINMo; break;
+    case PPC::SRW8o: III.ImmOpcode = PPC::RLWINM8o; break;
+    case PPC::SRAW: III.ImmOpcode = PPC::SRAWI; break;
+    case PPC::SRAWo: III.ImmOpcode = PPC::SRAWIo; break;
+    case PPC::SLD: III.ImmOpcode = PPC::RLDICR; break;
+    case PPC::SLDo: III.ImmOpcode = PPC::RLDICRo; break;
+    case PPC::SRD: III.ImmOpcode = PPC::RLDICL; break;
+    case PPC::SRDo: III.ImmOpcode = PPC::RLDICLo; break;
+    case PPC::SRAD: III.ImmOpcode = PPC::SRADI; break;
+    case PPC::SRADo: III.ImmOpcode = PPC::SRADIo; break;
+    }
+    break;
+  // Loads and stores:
+  case PPC::LBZX:
+  case PPC::LBZX8:
+  case PPC::LHZX:
+  case PPC::LHZX8:
+  case PPC::LHAX:
+  case PPC::LHAX8:
+  case PPC::LWZX:
+  case PPC::LWZX8:
+  case PPC::LWAX:
+  case PPC::LDX:
+  case PPC::LFSX:
+  case PPC::LFDX:
+  case PPC::STBX:
+  case PPC::STBX8:
+  case PPC::STHX:
+  case PPC::STHX8:
+  case PPC::STWX:
+  case PPC::STWX8:
+  case PPC::STDX:
+  case PPC::STFSX:
+  case PPC::STFDX:
+    III.SignedImm = true;
+    III.ZeroIsSpecialOrig = 1;
+    III.ZeroIsSpecialNew = 2;
+    III.IsCommutative = true;
+    III.ImmOpNo = 1;
+    III.ConstantOpNo = 2;
+    switch(Opc) {
+    default: llvm_unreachable("Unknown opcode");
+    case PPC::LBZX: III.ImmOpcode = PPC::LBZ; break;
+    case PPC::LBZX8: III.ImmOpcode = PPC::LBZ8; break;
+    case PPC::LHZX: III.ImmOpcode = PPC::LHZ; break;
+    case PPC::LHZX8: III.ImmOpcode = PPC::LHZ8; break;
+    case PPC::LHAX: III.ImmOpcode = PPC::LHA; break;
+    case PPC::LHAX8: III.ImmOpcode = PPC::LHA8; break;
+    case PPC::LWZX: III.ImmOpcode = PPC::LWZ; break;
+    case PPC::LWZX8: III.ImmOpcode = PPC::LWZ8; break;
+    case PPC::LWAX:
+      III.ImmOpcode = PPC::LWA;
+      III.ImmMustBeMultipleOf = 4;
+      break;
+    case PPC::LDX: III.ImmOpcode = PPC::LD; III.ImmMustBeMultipleOf = 4; break;
+    case PPC::LFSX: III.ImmOpcode = PPC::LFS; break;
+    case PPC::LFDX: III.ImmOpcode = PPC::LFD; break;
+    case PPC::STBX: III.ImmOpcode = PPC::STB; break;
+    case PPC::STBX8: III.ImmOpcode = PPC::STB8; break;
+    case PPC::STHX: III.ImmOpcode = PPC::STH; break;
+    case PPC::STHX8: III.ImmOpcode = PPC::STH8; break;
+    case PPC::STWX: III.ImmOpcode = PPC::STW; break;
+    case PPC::STWX8: III.ImmOpcode = PPC::STW8; break;
+    case PPC::STDX:
+      III.ImmOpcode = PPC::STD;
+      III.ImmMustBeMultipleOf = 4;
+      break;
+    case PPC::STFSX: III.ImmOpcode = PPC::STFS; break;
+    case PPC::STFDX: III.ImmOpcode = PPC::STFD; break;
+    }
+    break;
+  case PPC::LBZUX:
+  case PPC::LBZUX8:
+  case PPC::LHZUX:
+  case PPC::LHZUX8:
+  case PPC::LHAUX:
+  case PPC::LHAUX8:
+  case PPC::LWZUX:
+  case PPC::LWZUX8:
+  case PPC::LDUX:
+  case PPC::LFSUX:
+  case PPC::LFDUX:
+  case PPC::STBUX:
+  case PPC::STBUX8:
+  case PPC::STHUX:
+  case PPC::STHUX8:
+  case PPC::STWUX:
+  case PPC::STWUX8:
+  case PPC::STDUX:
+  case PPC::STFSUX:
+  case PPC::STFDUX:
+    III.SignedImm = true;
+    III.ZeroIsSpecialOrig = 2;
+    III.ZeroIsSpecialNew = 3;
+    III.IsCommutative = false;
+    III.ImmOpNo = 2;
+    III.ConstantOpNo = 3;
+    switch(Opc) {
+    default: llvm_unreachable("Unknown opcode");
+    case PPC::LBZUX: III.ImmOpcode = PPC::LBZU; break;
+    case PPC::LBZUX8: III.ImmOpcode = PPC::LBZU8; break;
+    case PPC::LHZUX: III.ImmOpcode = PPC::LHZU; break;
+    case PPC::LHZUX8: III.ImmOpcode = PPC::LHZU8; break;
+    case PPC::LHAUX: III.ImmOpcode = PPC::LHAU; break;
+    case PPC::LHAUX8: III.ImmOpcode = PPC::LHAU8; break;
+    case PPC::LWZUX: III.ImmOpcode = PPC::LWZU; break;
+    case PPC::LWZUX8: III.ImmOpcode = PPC::LWZU8; break;
+    case PPC::LDUX:
+      III.ImmOpcode = PPC::LDU;
+      III.ImmMustBeMultipleOf = 4;
+      break;
+    case PPC::LFSUX: III.ImmOpcode = PPC::LFSU; break;
+    case PPC::LFDUX: III.ImmOpcode = PPC::LFDU; break;
+    case PPC::STBUX: III.ImmOpcode = PPC::STBU; break;
+    case PPC::STBUX8: III.ImmOpcode = PPC::STBU8; break;
+    case PPC::STHUX: III.ImmOpcode = PPC::STHU; break;
+    case PPC::STHUX8: III.ImmOpcode = PPC::STHU8; break;
+    case PPC::STWUX: III.ImmOpcode = PPC::STWU; break;
+    case PPC::STWUX8: III.ImmOpcode = PPC::STWU8; break;
+    case PPC::STDUX:
+      III.ImmOpcode = PPC::STDU;
+      III.ImmMustBeMultipleOf = 4;
+      break;
+    case PPC::STFSUX: III.ImmOpcode = PPC::STFSU; break;
+    case PPC::STFDUX: III.ImmOpcode = PPC::STFDU; break;
+    }
+    break;
+  // Power9 only.
+  case PPC::LXVX:
+  case PPC::LXSSPX:
+  case PPC::LXSDX:
+  case PPC::STXVX:
+  case PPC::STXSSPX:
+  case PPC::STXSDX:
+    if (!Subtarget.hasP9Vector())
+      return false;
+    III.SignedImm = true;
+    III.ZeroIsSpecialOrig = 1;
+    III.ZeroIsSpecialNew = 2;
+    III.IsCommutative = true;
+    III.ImmOpNo = 1;
+    III.ConstantOpNo = 2;
+    switch(Opc) {
+    default: llvm_unreachable("Unknown opcode");
+    case PPC::LXVX:
+      III.ImmOpcode = PPC::LXV;
+      III.ImmMustBeMultipleOf = 16;
+      break;
+    case PPC::LXSSPX:
+      III.ImmOpcode = PPC::LXSSP;
+      III.ImmMustBeMultipleOf = 4;
+      break;
+    case PPC::LXSDX:
+      III.ImmOpcode = PPC::LXSD;
+      III.ImmMustBeMultipleOf = 4;
+      break;
+    case PPC::STXVX:
+      III.ImmOpcode = PPC::STXV;
+      III.ImmMustBeMultipleOf = 16;
+      break;
+    case PPC::STXSSPX:
+      III.ImmOpcode = PPC::STXSSP;
+      III.ImmMustBeMultipleOf = 4;
+      break;
+    case PPC::STXSDX:
+      III.ImmOpcode = PPC::STXSD;
+      III.ImmMustBeMultipleOf = 4;
+      break;
+    }
+    break;
+  }
+  return true;
+}
+
+// Utility function for swaping two arbitrary operands of an instruction.
+static void swapMIOperands(MachineInstr &MI, unsigned Op1, unsigned Op2) {
+  assert(Op1 != Op2 && "Cannot swap operand with itself.");
+
+  unsigned MaxOp = std::max(Op1, Op2);
+  unsigned MinOp = std::min(Op1, Op2);
+  MachineOperand MOp1 = MI.getOperand(MinOp);
+  MachineOperand MOp2 = MI.getOperand(MaxOp);
+  MI.RemoveOperand(std::max(Op1, Op2));
+  MI.RemoveOperand(std::min(Op1, Op2));
+
+  // If the operands we are swapping are the two at the end (the common case)
+  // we can just remove both and add them in the opposite order.
+  if (MaxOp - MinOp == 1 && MI.getNumOperands() == MinOp) {
+    MI.addOperand(MOp2);
+    MI.addOperand(MOp1);
+  } else {
+    // Store all operands in a temporary vector, remove them and re-add in the
+    // right order.
+    SmallVector<MachineOperand, 2> MOps;
+    unsigned TotalOps = MI.getNumOperands() + 2; // We've already removed 2 ops.
+    for (unsigned i = MI.getNumOperands() - 1; i >= MinOp; i--) {
+      MOps.push_back(MI.getOperand(i));
+      MI.RemoveOperand(i);
+    }
+    // MOp2 needs to be added next.
+    MI.addOperand(MOp2);
+    // Now add the rest.
+    for (unsigned i = MI.getNumOperands(); i < TotalOps; i++) {
+      if (i == MaxOp)
+        MI.addOperand(MOp1);
+      else {
+        MI.addOperand(MOps.back());
+        MOps.pop_back();
+      }
+    }
+  }
+}
+
+bool PPCInstrInfo::transformToImmForm(MachineInstr &MI, const ImmInstrInfo &III,
+                                      unsigned ConstantOpNo,
+                                      int64_t Imm) const {
+  MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
+  bool PostRA = !MRI.isSSA();
+  // Exit early if we can't convert this.
+  if ((ConstantOpNo != III.ConstantOpNo) && !III.IsCommutative)
+    return false;
+  if (Imm % III.ImmMustBeMultipleOf)
+    return false;
+  if (III.SignedImm) {
+    APInt ActualValue(64, Imm, true);
+    if (!ActualValue.isSignedIntN(III.ImmWidth))
+      return false;
+  } else {
+    uint64_t UnsignedMax = (1 << III.ImmWidth) - 1;
+    if ((uint64_t)Imm > UnsignedMax)
+      return false;
+  }
+
+  // If we're post-RA, the instructions don't agree on whether register zero is
+  // special, we can transform this as long as the register operand that will
+  // end up in the location where zero is special isn't R0.
+  if (PostRA && III.ZeroIsSpecialOrig != III.ZeroIsSpecialNew) {
+    unsigned PosForOrigZero = III.ZeroIsSpecialOrig ? III.ZeroIsSpecialOrig :
+      III.ZeroIsSpecialNew + 1;
+    unsigned OrigZeroReg = MI.getOperand(PosForOrigZero).getReg();
+    unsigned NewZeroReg = MI.getOperand(III.ZeroIsSpecialNew).getReg();
+    // If R0 is in the operand where zero is special for the new instruction,
+    // it is unsafe to transform if the constant operand isn't that operand.
+    if ((NewZeroReg == PPC::R0 || NewZeroReg == PPC::X0) &&
+        ConstantOpNo != III.ZeroIsSpecialNew)
+      return false;
+    if ((OrigZeroReg == PPC::R0 || OrigZeroReg == PPC::X0) &&
+        ConstantOpNo != PosForOrigZero)
+      return false;
+  }
+
+  unsigned Opc = MI.getOpcode();
+  bool SpecialShift32 =
+    Opc == PPC::SLW || Opc == PPC::SLWo || Opc == PPC::SRW || Opc == PPC::SRWo;
+  bool SpecialShift64 =
+    Opc == PPC::SLD || Opc == PPC::SLDo || Opc == PPC::SRD || Opc == PPC::SRDo;
+  bool SetCR = Opc == PPC::SLWo || Opc == PPC::SRWo ||
+    Opc == PPC::SLDo || Opc == PPC::SRDo;
+  bool RightShift =
+    Opc == PPC::SRW || Opc == PPC::SRWo || Opc == PPC::SRD || Opc == PPC::SRDo;
+
+  MI.setDesc(get(III.ImmOpcode));
+  if (ConstantOpNo == III.ConstantOpNo) {
+    // Converting shifts to immediate form is a bit tricky since they may do
+    // one of three things:
+    // 1. If the shift amount is between OpSize and 2*OpSize, the result is zero
+    // 2. If the shift amount is zero, the result is unchanged (save for maybe
+    //    setting CR0)
+    // 3. If the shift amount is in [1, OpSize), it's just a shift
+    if (SpecialShift32 || SpecialShift64) {
+      LoadImmediateInfo LII;
+      LII.Imm = 0;
+      LII.SetCR = SetCR;
+      LII.Is64Bit = SpecialShift64;
+      uint64_t ShAmt = Imm & (SpecialShift32 ? 0x1F : 0x3F);
+      if (Imm & (SpecialShift32 ? 0x20 : 0x40))
+        replaceInstrWithLI(MI, LII);
+      // Shifts by zero don't change the value. If we don't need to set CR0,
+      // just convert this to a COPY. Can't do this post-RA since we've already
+      // cleaned up the copies.
+      else if (!SetCR && ShAmt == 0 && !PostRA) {
+        MI.RemoveOperand(2);
+        MI.setDesc(get(PPC::COPY));
+      } else {
+        // The 32 bit and 64 bit instructions are quite different.
+        if (SpecialShift32) {
+          // Left shifts use (N, 0, 31-N), right shifts use (32-N, N, 31).
+          uint64_t SH = RightShift ? 32 - ShAmt : ShAmt;
+          uint64_t MB = RightShift ? ShAmt : 0;
+          uint64_t ME = RightShift ? 31 : 31 - ShAmt;
+          MI.getOperand(III.ConstantOpNo).ChangeToImmediate(SH);
+          MachineInstrBuilder(*MI.getParent()->getParent(), MI).addImm(MB)
+            .addImm(ME);
+        } else {
+          // Left shifts use (N, 63-N), right shifts use (64-N, N).
+          uint64_t SH = RightShift ? 64 - ShAmt : ShAmt;
+          uint64_t ME = RightShift ? ShAmt : 63 - ShAmt;
+          MI.getOperand(III.ConstantOpNo).ChangeToImmediate(SH);
+          MachineInstrBuilder(*MI.getParent()->getParent(), MI).addImm(ME);
+        }
+      }
+    } else
+      MI.getOperand(ConstantOpNo).ChangeToImmediate(Imm);
+  }
+  // Convert commutative instructions (switch the operands and convert the
+  // desired one to an immediate.
+  else if (III.IsCommutative) {
+    MI.getOperand(ConstantOpNo).ChangeToImmediate(Imm);
+    swapMIOperands(MI, ConstantOpNo, III.ConstantOpNo);
+  } else
+    llvm_unreachable("Should have exited early!");
+
+  // For instructions for which the constant register replaces a different
+  // operand than where the immediate goes, we need to swap them.
+  if (III.ConstantOpNo != III.ImmOpNo)
+    swapMIOperands(MI, III.ConstantOpNo, III.ImmOpNo);
+
+  // If the R0/X0 register is special for the original instruction and not for
+  // the new instruction (or vice versa), we need to fix up the register class.
+  if (!PostRA && III.ZeroIsSpecialOrig != III.ZeroIsSpecialNew) {
+    if (!III.ZeroIsSpecialOrig) {
+      unsigned RegToModify = MI.getOperand(III.ZeroIsSpecialNew).getReg();
+      const TargetRegisterClass *NewRC =
+        MRI.getRegClass(RegToModify)->hasSuperClassEq(&PPC::GPRCRegClass) ?
+        &PPC::GPRC_and_GPRC_NOR0RegClass : &PPC::G8RC_and_G8RC_NOX0RegClass;
+      MRI.setRegClass(RegToModify, NewRC);
+    }
+  }
+  return true;
+}
+
 const TargetRegisterClass *
 PPCInstrInfo::updatedRC(const TargetRegisterClass *RC) const {
   if (Subtarget.hasVSX() && RC == &PPC::VRRCRegClass)

Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h?rev=320791&r1=320790&r2=320791&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h Thu Dec 14 23:27:53 2017
@@ -72,6 +72,41 @@ enum {
 };
 } // end namespace PPCII
 
+// Instructions that have an immediate form might be convertible to that
+// form if the correct input is a result of a load immediate. In order to
+// know whether the transformation is special, we might need to know some
+// of the details of the two forms.
+struct ImmInstrInfo {
+  // Is the immediate field in the immediate form signed or unsigned?
+  uint64_t SignedImm : 1;
+  // Does the immediate need to be a multiple of some value?
+  uint64_t ImmMustBeMultipleOf : 5;
+  // Is R0/X0 treated specially by the original r+r instruction?
+  // If so, in which operand?
+  uint64_t ZeroIsSpecialOrig : 3;
+  // Is R0/X0 treated specially by the new r+i instruction?
+  // If so, in which operand?
+  uint64_t ZeroIsSpecialNew : 3;
+  // Is the operation commutative?
+  uint64_t IsCommutative : 1;
+  // The operand number to check for load immediate.
+  uint64_t ConstantOpNo : 3;
+  // The operand number for the immediate.
+  uint64_t ImmOpNo : 3;
+  // The opcode of the new instruction.
+  uint64_t ImmOpcode : 16;
+  // The size of the immediate.
+  uint64_t ImmWidth : 5;
+};
+
+// Information required to convert an instruction to just a materialized
+// immediate.
+struct LoadImmediateInfo {
+  unsigned Imm : 16;
+  unsigned Is64Bit : 1;
+  unsigned SetCR : 1;
+};
+
 class PPCSubtarget;
 class PPCInstrInfo : public PPCGenInstrInfo {
   PPCSubtarget &Subtarget;
@@ -87,6 +122,10 @@ class PPCInstrInfo : public PPCGenInstrI
                             const TargetRegisterClass *RC,
                             SmallVectorImpl<MachineInstr *> &NewMIs,
                             bool &NonRI, bool &SpillsVRS) const;
+  bool transformToImmForm(MachineInstr &MI, const ImmInstrInfo &III,
+                          unsigned ConstantOpNo, int64_t Imm) const;
+  MachineInstr *getConstantDefMI(MachineInstr &MI, unsigned &ConstOp,
+                                 bool &SeenIntermediateUse) const;
   virtual void anchor();
 
 protected:
@@ -313,6 +352,19 @@ public:
   bool isZeroExtended(const MachineInstr &MI, const unsigned depth = 0) const {
    return isSignOrZeroExtended(MI, false, depth);
   }
+
+  bool convertToImmediateForm(MachineInstr &MI,
+                              MachineInstr **KilledDef = nullptr) const;
+  void replaceInstrWithLI(MachineInstr &MI, const LoadImmediateInfo &LII) const;
+
+  // This is used to find the "true" source register for n
+  // Machine instruction. Returns the original SrcReg unless it is the target
+  // of a copy-like operation, in which case we chain backwards through all
+  // such operations to the ultimate source register.  If a
+  // physical register is encountered, we stop the search.
+  static unsigned lookThruCopyLike(unsigned SrcReg,
+                                   const MachineRegisterInfo *MRI);
+  bool instrHasImmForm(const MachineInstr &MI, ImmInstrInfo &III) const;
 };
 
 }

Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td?rev=320791&r1=320790&r2=320791&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td Thu Dec 14 23:27:53 2017
@@ -1590,6 +1590,11 @@ def : Pat<(prefetch xoaddr:$dst, (i32 0)
           (ICBT 0, xoaddr:$dst)>, Requires<[HasICBT]>; // inst prefetch (for read)
 
 // Atomic operations
+// FIXME: some of these might be used with constant operands. This will result
+// in constant materialization instructions that may be redundant. We currently
+// clean this up in PPCMIPeephole with calls to
+// PPCInstrInfo::convertToImmediateForm() but we should probably not emit them
+// in the first place.
 let usesCustomInserter = 1 in {
   let Defs = [CR0] in {
     def ATOMIC_LOAD_ADD_I8 : Pseudo<

Modified: llvm/trunk/lib/Target/PowerPC/PPCMIPeephole.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCMIPeephole.cpp?rev=320791&r1=320790&r2=320791&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCMIPeephole.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCMIPeephole.cpp Thu Dec 14 23:27:53 2017
@@ -41,6 +41,22 @@ STATISTIC(MultiTOCSaves,
 STATISTIC(NumEliminatedSExt, "Number of eliminated sign-extensions");
 STATISTIC(NumEliminatedZExt, "Number of eliminated zero-extensions");
 STATISTIC(NumOptADDLIs, "Number of optimized ADD instruction fed by LI");
+STATISTIC(NumConvertedToImmediateForm,
+          "Number of instructions converted to their immediate form");
+STATISTIC(NumFunctionsEnteredInMIPeephole,
+          "Number of functions entered in PPC MI Peepholes");
+STATISTIC(NumFixedPointIterations,
+          "Number of fixed-point iterations converting reg-reg instructions "
+          "to reg-imm ones");
+
+static cl::opt<bool>
+FixedPointRegToImm("ppc-reg-to-imm-fixed-point", cl::Hidden, cl::init(true),
+                   cl::desc("Iterate to a fixed point when attempting to "
+                            "convert reg-reg instructions to reg-imm"));
+
+static cl::opt<bool>
+ConvertRegReg("ppc-convert-rr-to-ri", cl::Hidden, cl::init(true),
+              cl::desc("Convert eligible reg+reg instructions to reg+imm"));
 
 static cl::opt<bool>
     EnableSExtElimination("ppc-eliminate-signext",
@@ -52,10 +68,6 @@ static cl::opt<bool>
                           cl::desc("enable elimination of zero-extensions"),
                           cl::init(false), cl::Hidden);
 
-namespace llvm {
-  void initializePPCMIPeepholePass(PassRegistry&);
-}
-
 namespace {
 
 struct PPCMIPeephole : public MachineFunctionPass {
@@ -83,9 +95,6 @@ private:
   bool eliminateRedundantTOCSaves(std::map<MachineInstr *, bool> &TOCSaves);
   void UpdateTOCSaves(std::map<MachineInstr *, bool> &TOCSaves,
                       MachineInstr *MI);
-  // Find the "true" register represented by SrcReg (following chains
-  // of copies and subreg_to_reg operations).
-  unsigned lookThruCopyLike(unsigned SrcReg);
 
 public:
 
@@ -212,6 +221,35 @@ bool PPCMIPeephole::simplifyCode(void) {
   MachineInstr* ToErase = nullptr;
   std::map<MachineInstr *, bool> TOCSaves;
 
+  NumFunctionsEnteredInMIPeephole++;
+  if (ConvertRegReg) {
+    // Fixed-point conversion of reg/reg instructions fed by load-immediate
+    // into reg/imm instructions. FIXME: This is expensive, control it with
+    // an option.
+    bool SomethingChanged = false;
+    do {
+      NumFixedPointIterations++;
+      SomethingChanged = false;
+      for (MachineBasicBlock &MBB : *MF) {
+        for (MachineInstr &MI : MBB) {
+          if (MI.isDebugValue())
+            continue;
+
+          if (TII->convertToImmediateForm(MI)) {
+            // We don't erase anything in case the def has other uses. Let DCE
+            // remove it if it can be removed.
+            DEBUG(dbgs() << "Converted instruction to imm form: ");
+            DEBUG(MI.dump());
+            NumConvertedToImmediateForm++;
+            SomethingChanged = true;
+            Simplified = true;
+            continue;
+          }
+        }
+      }
+    } while (SomethingChanged && FixedPointRegToImm);
+  }
+
   for (MachineBasicBlock &MBB : *MF) {
     for (MachineInstr &MI : MBB) {
 
@@ -258,8 +296,10 @@ bool PPCMIPeephole::simplifyCode(void) {
           //   XXPERMDI t, SUBREG_TO_REG(s), SUBREG_TO_REG(s), immed.
           // We have to look through chains of COPY and SUBREG_TO_REG
           // to find the real source values for comparison.
-          unsigned TrueReg1 = lookThruCopyLike(MI.getOperand(1).getReg());
-          unsigned TrueReg2 = lookThruCopyLike(MI.getOperand(2).getReg());
+          unsigned TrueReg1 =
+            TII->lookThruCopyLike(MI.getOperand(1).getReg(), MRI);
+          unsigned TrueReg2 =
+            TII->lookThruCopyLike(MI.getOperand(2).getReg(), MRI);
 
           if (TrueReg1 == TrueReg2
               && TargetRegisterInfo::isVirtualRegister(TrueReg1)) {
@@ -273,7 +313,8 @@ bool PPCMIPeephole::simplifyCode(void) {
             auto isConversionOfLoadAndSplat = [=]() -> bool {
               if (DefOpc != PPC::XVCVDPSXDS && DefOpc != PPC::XVCVDPUXDS)
                 return false;
-              unsigned DefReg = lookThruCopyLike(DefMI->getOperand(1).getReg());
+              unsigned DefReg =
+                TII->lookThruCopyLike(DefMI->getOperand(1).getReg(), MRI);
               if (TargetRegisterInfo::isVirtualRegister(DefReg)) {
                 MachineInstr *LoadMI = MRI->getVRegDef(DefReg);
                 if (LoadMI && LoadMI->getOpcode() == PPC::LXVDSX)
@@ -299,10 +340,10 @@ bool PPCMIPeephole::simplifyCode(void) {
             // can replace it with a copy.
             if (DefOpc == PPC::XXPERMDI) {
               unsigned FeedImmed = DefMI->getOperand(3).getImm();
-              unsigned FeedReg1
-                = lookThruCopyLike(DefMI->getOperand(1).getReg());
-              unsigned FeedReg2
-                = lookThruCopyLike(DefMI->getOperand(2).getReg());
+              unsigned FeedReg1 =
+                TII->lookThruCopyLike(DefMI->getOperand(1).getReg(), MRI);
+              unsigned FeedReg2 =
+                TII->lookThruCopyLike(DefMI->getOperand(2).getReg(), MRI);
 
               if ((FeedImmed == 0 || FeedImmed == 3) && FeedReg1 == FeedReg2) {
                 DEBUG(dbgs()
@@ -360,7 +401,8 @@ bool PPCMIPeephole::simplifyCode(void) {
       case PPC::XXSPLTW: {
         unsigned MyOpcode = MI.getOpcode();
         unsigned OpNo = MyOpcode == PPC::XXSPLTW ? 1 : 2;
-        unsigned TrueReg = lookThruCopyLike(MI.getOperand(OpNo).getReg());
+        unsigned TrueReg =
+          TII->lookThruCopyLike(MI.getOperand(OpNo).getReg(), MRI);
         if (!TargetRegisterInfo::isVirtualRegister(TrueReg))
           break;
         MachineInstr *DefMI = MRI->getVRegDef(TrueReg);
@@ -422,7 +464,8 @@ bool PPCMIPeephole::simplifyCode(void) {
       }
       case PPC::XVCVDPSP: {
         // If this is a DP->SP conversion fed by an FRSP, the FRSP is redundant.
-        unsigned TrueReg = lookThruCopyLike(MI.getOperand(1).getReg());
+        unsigned TrueReg =
+          TII->lookThruCopyLike(MI.getOperand(1).getReg(), MRI);
         if (!TargetRegisterInfo::isVirtualRegister(TrueReg))
           break;
         MachineInstr *DefMI = MRI->getVRegDef(TrueReg);
@@ -430,8 +473,10 @@ bool PPCMIPeephole::simplifyCode(void) {
         // This can occur when building a vector of single precision or integer
         // values.
         if (DefMI && DefMI->getOpcode() == PPC::XXPERMDI) {
-          unsigned DefsReg1 = lookThruCopyLike(DefMI->getOperand(1).getReg());
-          unsigned DefsReg2 = lookThruCopyLike(DefMI->getOperand(2).getReg());
+          unsigned DefsReg1 =
+            TII->lookThruCopyLike(DefMI->getOperand(1).getReg(), MRI);
+          unsigned DefsReg2 =
+            TII->lookThruCopyLike(DefMI->getOperand(2).getReg(), MRI);
           if (!TargetRegisterInfo::isVirtualRegister(DefsReg1) ||
               !TargetRegisterInfo::isVirtualRegister(DefsReg2))
             break;
@@ -1221,36 +1266,6 @@ bool PPCMIPeephole::eliminateRedundantCo
   return Simplified;
 }
 
-// This is used to find the "true" source register for an
-// XXPERMDI instruction, since MachineCSE does not handle the
-// "copy-like" operations (Copy and SubregToReg).  Returns
-// the original SrcReg unless it is the target of a copy-like
-// operation, in which case we chain backwards through all
-// such operations to the ultimate source register.  If a
-// physical register is encountered, we stop the search.
-unsigned PPCMIPeephole::lookThruCopyLike(unsigned SrcReg) {
-
-  while (true) {
-
-    MachineInstr *MI = MRI->getVRegDef(SrcReg);
-    if (!MI->isCopyLike())
-      return SrcReg;
-
-    unsigned CopySrcReg;
-    if (MI->isCopy())
-      CopySrcReg = MI->getOperand(1).getReg();
-    else {
-      assert(MI->isSubregToReg() && "bad opcode for lookThruCopyLike");
-      CopySrcReg = MI->getOperand(2).getReg();
-    }
-
-    if (!TargetRegisterInfo::isVirtualRegister(CopySrcReg))
-      return CopySrcReg;
-
-    SrcReg = CopySrcReg;
-  }
-}
-
 } // end default namespace
 
 INITIALIZE_PASS_BEGIN(PPCMIPeephole, DEBUG_TYPE,

Added: llvm/trunk/lib/Target/PowerPC/PPCPreEmitPeephole.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCPreEmitPeephole.cpp?rev=320791&view=auto
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCPreEmitPeephole.cpp (added)
+++ llvm/trunk/lib/Target/PowerPC/PPCPreEmitPeephole.cpp Thu Dec 14 23:27:53 2017
@@ -0,0 +1,95 @@
+//===--------- PPCPreEmitPeephole.cpp - Late peephole optimizations -------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// A pre-emit peephole for catching opportunities introduced by late passes such
+// as MachineBlockPlacement.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PPC.h"
+#include "PPCInstrInfo.h"
+#include "PPCSubtarget.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/CodeGen/LivePhysRegs.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/Debug.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "ppc-pre-emit-peephole"
+
+STATISTIC(NumRRConvertedInPreEmit,
+          "Number of r+r instructions converted to r+i in pre-emit peephole");
+STATISTIC(NumRemovedInPreEmit,
+          "Number of instructions deleted in pre-emit peephole");
+
+static cl::opt<bool>
+RunPreEmitPeephole("ppc-late-peephole", cl::Hidden, cl::init(true),
+                   cl::desc("Run pre-emit peephole optimizations."));
+
+namespace {
+  class PPCPreEmitPeephole : public MachineFunctionPass {
+  public:
+    static char ID;
+    PPCPreEmitPeephole() : MachineFunctionPass(ID) {
+      initializePPCPreEmitPeepholePass(*PassRegistry::getPassRegistry());
+    }
+
+    void getAnalysisUsage(AnalysisUsage &AU) const override {
+      MachineFunctionPass::getAnalysisUsage(AU);
+    }
+
+    MachineFunctionProperties getRequiredProperties() const override {
+      return MachineFunctionProperties().set(
+          MachineFunctionProperties::Property::NoVRegs);
+    }
+
+    bool runOnMachineFunction(MachineFunction &MF) override {
+      if (skipFunction(*MF.getFunction()) || !RunPreEmitPeephole)
+        return false;
+      bool Changed = false;
+      const PPCInstrInfo *TII = MF.getSubtarget<PPCSubtarget>().getInstrInfo();
+      SmallVector<MachineInstr *, 4> InstrsToErase;
+      for (MachineBasicBlock &MBB : MF) {
+        for (MachineInstr &MI : MBB) {
+          MachineInstr *DefMIToErase = nullptr;
+          if (TII->convertToImmediateForm(MI, &DefMIToErase)) {
+            Changed = true;
+            NumRRConvertedInPreEmit++;
+            DEBUG(dbgs() << "Converted instruction to imm form: ");
+            DEBUG(MI.dump());
+            if (DefMIToErase) {
+              InstrsToErase.push_back(DefMIToErase);
+            }
+          }
+        }
+      }
+      for (MachineInstr *MI : InstrsToErase) {
+        DEBUG(dbgs() << "PPC pre-emit peephole: erasing instruction: ");
+        DEBUG(MI->dump());
+        MI->eraseFromParent();
+        NumRemovedInPreEmit++;
+      }
+      return Changed;
+    }
+  };
+}
+
+INITIALIZE_PASS(PPCPreEmitPeephole, DEBUG_TYPE, "PowerPC Pre-Emit Peephole",
+                false, false)
+char PPCPreEmitPeephole::ID = 0;
+
+FunctionPass *llvm::createPPCPreEmitPeepholePass() {
+  return new PPCPreEmitPeephole();
+}

Modified: llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp?rev=320791&r1=320790&r2=320791&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp Thu Dec 14 23:27:53 2017
@@ -101,7 +101,9 @@ extern "C" void LLVMInitializePowerPCTar
   PassRegistry &PR = *PassRegistry::getPassRegistry();
   initializePPCBoolRetToIntPass(PR);
   initializePPCExpandISELPass(PR);
+  initializePPCPreEmitPeepholePass(PR);
   initializePPCTLSDynamicCallPass(PR);
+  initializePPCMIPeepholePass(PR);
 }
 
 /// Return the datalayout string of a subtarget.
@@ -440,6 +442,7 @@ void PPCPassConfig::addPreSched2() {
 }
 
 void PPCPassConfig::addPreEmitPass() {
+  addPass(createPPCPreEmitPeepholePass());
   addPass(createPPCExpandISELPass());
 
   if (getOptLevel() != CodeGenOpt::None)

Modified: llvm/trunk/test/CodeGen/PowerPC/build-vector-tests.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/build-vector-tests.ll?rev=320791&r1=320790&r2=320791&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/build-vector-tests.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/build-vector-tests.ll Thu Dec 14 23:27:53 2017
@@ -3508,13 +3508,13 @@ entry:
 ; P9LE: xxmrghd
 ; P9LE-NEXT: xvcvdpsxds v2
 ; P9LE-NEXT: blr
-; P8BE: lfsx
-; P8BE: lfsx
+; P8BE: lfs
+; P8BE: lfs
 ; P8BE: xxmrghd
 ; P8BE-NEXT: xvcvdpsxds v2
 ; P8BE-NEXT: blr
-; P8LE: lfsx
-; P8LE: lfsx
+; P8LE: lfs
+; P8LE: lfs
 ; P8LE: xxmrghd
 ; P8LE-NEXT: xvcvdpsxds v2
 ; P8LE-NEXT: blr
@@ -3546,13 +3546,13 @@ entry:
 ; P9LE: xxmrghd
 ; P9LE-NEXT: xvcvdpsxds v2
 ; P9LE-NEXT: blr
-; P8BE: lfsx
-; P8BE: lfsx
+; P8BE: lfs
+; P8BE: lfs
 ; P8BE: xxmrghd
 ; P8BE-NEXT: xvcvdpsxds v2
 ; P8BE-NEXT: blr
-; P8LE: lfsx
-; P8LE: lfsx
+; P8LE: lfs
+; P8LE: lfs
 ; P8LE: xxmrghd
 ; P8LE-NEXT: xvcvdpsxds v2
 ; P8LE-NEXT: blr
@@ -3591,13 +3591,13 @@ entry:
 ; P9LE-NEXT: blr
 ; P8BE: sldi
 ; P8BE: lfsux
-; P8BE: lfsx
+; P8BE: lfs
 ; P8BE: xxmrghd
 ; P8BE-NEXT: xvcvdpsxds v2
 ; P8BE-NEXT: blr
 ; P8LE: sldi
 ; P8LE: lfsux
-; P8LE: lfsx
+; P8LE: lfs
 ; P8LE: xxmrghd
 ; P8LE-NEXT: xvcvdpsxds v2
 ; P8LE-NEXT: blr
@@ -3636,13 +3636,13 @@ entry:
 ; P9LE-NEXT: blr
 ; P8BE: sldi
 ; P8BE: lfsux
-; P8BE: lfsx
+; P8BE: lfs
 ; P8BE: xxmrghd
 ; P8BE-NEXT: xvcvdpsxds v2
 ; P8BE-NEXT: blr
 ; P8LE: sldi
 ; P8LE: lfsux
-; P8LE: lfsx
+; P8LE: lfs
 ; P8LE: xxmrghd
 ; P8LE-NEXT: xvcvdpsxds v2
 ; P8LE-NEXT: blr
@@ -3693,11 +3693,11 @@ entry:
 ; P9LE-NEXT: xscvdpsxds
 ; P9LE-NEXT: xxspltd v2
 ; P9LE-NEXT: blr
-; P8BE: lfsx
+; P8BE: lfs
 ; P8BE-NEXT: xscvdpsxds
 ; P8BE-NEXT: xxspltd v2
 ; P8BE-NEXT: blr
-; P8LE: lfsx
+; P8LE: lfs
 ; P8LE-NEXT: xscvdpsxds
 ; P8LE-NEXT: xxspltd v2
 ; P8LE-NEXT: blr
@@ -4412,13 +4412,13 @@ entry:
 ; P9LE: xxmrghd
 ; P9LE-NEXT: xvcvdpuxds v2
 ; P9LE-NEXT: blr
-; P8BE: lfsx
-; P8BE: lfsx
+; P8BE: lfs
+; P8BE: lfs
 ; P8BE: xxmrghd
 ; P8BE-NEXT: xvcvdpuxds v2
 ; P8BE-NEXT: blr
-; P8LE: lfsx
-; P8LE: lfsx
+; P8LE: lfs
+; P8LE: lfs
 ; P8LE: xxmrghd
 ; P8LE-NEXT: xvcvdpuxds v2
 ; P8LE-NEXT: blr
@@ -4450,13 +4450,13 @@ entry:
 ; P9LE: xxmrghd
 ; P9LE-NEXT: xvcvdpuxds v2
 ; P9LE-NEXT: blr
-; P8BE: lfsx
-; P8BE: lfsx
+; P8BE: lfs
+; P8BE: lfs
 ; P8BE: xxmrghd
 ; P8BE-NEXT: xvcvdpuxds v2
 ; P8BE-NEXT: blr
-; P8LE: lfsx
-; P8LE: lfsx
+; P8LE: lfs
+; P8LE: lfs
 ; P8LE: xxmrghd
 ; P8LE-NEXT: xvcvdpuxds v2
 ; P8LE-NEXT: blr
@@ -4495,13 +4495,13 @@ entry:
 ; P9LE-NEXT: blr
 ; P8BE: sldi
 ; P8BE: lfsux
-; P8BE: lfsx
+; P8BE: lfs
 ; P8BE: xxmrghd
 ; P8BE-NEXT: xvcvdpuxds v2
 ; P8BE-NEXT: blr
 ; P8LE: sldi
 ; P8LE: lfsux
-; P8LE: lfsx
+; P8LE: lfs
 ; P8LE: xxmrghd
 ; P8LE-NEXT: xvcvdpuxds v2
 ; P8LE-NEXT: blr
@@ -4540,13 +4540,13 @@ entry:
 ; P9LE-NEXT: blr
 ; P8BE: sldi
 ; P8BE: lfsux
-; P8BE: lfsx
+; P8BE: lfs
 ; P8BE: xxmrghd
 ; P8BE-NEXT: xvcvdpuxds v2
 ; P8BE-NEXT: blr
 ; P8LE: sldi
 ; P8LE: lfsux
-; P8LE: lfsx
+; P8LE: lfs
 ; P8LE: xxmrghd
 ; P8LE-NEXT: xvcvdpuxds v2
 ; P8LE-NEXT: blr
@@ -4597,11 +4597,11 @@ entry:
 ; P9LE-NEXT: xscvdpuxds
 ; P9LE-NEXT: xxspltd v2
 ; P9LE-NEXT: blr
-; P8BE: lfsx
+; P8BE: lfs
 ; P8BE-NEXT: xscvdpuxds
 ; P8BE-NEXT: xxspltd v2
 ; P8BE-NEXT: blr
-; P8LE: lfsx
+; P8LE: lfs
 ; P8LE-NEXT: xscvdpuxds
 ; P8LE-NEXT: xxspltd v2
 ; P8LE-NEXT: blr

Added: llvm/trunk/test/CodeGen/PowerPC/convert-rr-to-ri-instrs-R0-special-handling.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/convert-rr-to-ri-instrs-R0-special-handling.mir?rev=320791&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/convert-rr-to-ri-instrs-R0-special-handling.mir (added)
+++ llvm/trunk/test/CodeGen/PowerPC/convert-rr-to-ri-instrs-R0-special-handling.mir Thu Dec 14 23:27:53 2017
@@ -0,0 +1,436 @@
+# RUN: llc -start-after ppc-mi-peepholes -ppc-late-peephole %s -o - | FileCheck %s
+--- |
+  ; ModuleID = 'a.ll'
+  source_filename = "a.c"
+  target datalayout = "e-m:e-i64:64-n32:64"
+  target triple = "powerpc64le-unknown-linux-gnu"
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define signext i32 @unsafeAddR0R3(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {
+  entry:
+    %add = add nsw i32 %b, %a
+    ret i32 %add
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define signext i32 @unsafeAddR3R0(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {
+  entry:
+    %add = add nsw i32 %b, %a
+    ret i32 %add
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define signext i32 @safeAddR0R3(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {
+  entry:
+    %add = add nsw i32 %b, %a
+    ret i32 %add
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define signext i32 @safeAddR3R0(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {
+  entry:
+    %add = add nsw i32 %b, %a
+    ret i32 %add
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define i64 @unsafeLDXR3R0(i64* nocapture readonly %ptr, i64 %off) local_unnamed_addr #1 {
+  entry:
+    %0 = bitcast i64* %ptr to i8*
+    %add.ptr = getelementptr inbounds i8, i8* %0, i64 %off
+    %1 = bitcast i8* %add.ptr to i64*
+    %2 = load i64, i64* %1, align 8, !tbaa !3
+    ret i64 %2
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define i64 @safeLDXZeroR3(i64* nocapture readonly %ptr, i64 %off) local_unnamed_addr #1 {
+  entry:
+    %0 = bitcast i64* %ptr to i8*
+    %add.ptr = getelementptr inbounds i8, i8* %0, i64 %off
+    %1 = bitcast i8* %add.ptr to i64*
+    %2 = load i64, i64* %1, align 8, !tbaa !3
+    ret i64 %2
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define i64 @safeLDXR3R0(i64* nocapture readonly %ptr, i64 %off) local_unnamed_addr #1 {
+  entry:
+    %0 = bitcast i64* %ptr to i8*
+    %add.ptr = getelementptr inbounds i8, i8* %0, i64 %off
+    %1 = bitcast i8* %add.ptr to i64*
+    %2 = load i64, i64* %1, align 8, !tbaa !3
+    ret i64 %2
+  }
+  
+  attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="ppc64le" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+vsx,-power9-vector,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" }
+  attributes #1 = { norecurse nounwind readonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="ppc64le" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+vsx,-power9-vector,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" }
+  
+  !llvm.module.flags = !{!0, !1}
+  !llvm.ident = !{!2}
+  
+  !0 = !{i32 1, !"wchar_size", i32 4}
+  !1 = !{i32 7, !"PIC Level", i32 2}
+  !2 = !{!"clang version 6.0.0 (trunk 318832)"}
+  !3 = !{!4, !4, i64 0}
+  !4 = !{!"long long", !5, i64 0}
+  !5 = !{!"omnipotent char", !6, i64 0}
+  !6 = !{!"Simple C/C++ TBAA"}
+
+...
+---
+name:            unsafeAddR0R3
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: gprc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x0, %x4
+  
+    %1:g8rc = COPY %x4
+    %0:g8rc = COPY %x0
+    %2:gprc = LI 44
+    %3:gprc = COPY %1.sub_32
+    %4:gprc = ADD4 killed %r0, killed %2
+    ; CHECK: li 3, 44
+    ; CHECK: add 3, 0, 3
+    %5:g8rc = EXTSW_32_64 killed %4
+    %x3 = COPY %5
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            unsafeAddR3R0
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: gprc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x0, %x4
+  
+    %1:g8rc = COPY %x4
+    %0:g8rc = COPY %x0
+    %2:gprc = COPY %0.sub_32
+    %3:gprc = LI 44
+    %4:gprc = ADD4 killed %3, killed %r0
+    ; CHECK: li 3, 44
+    ; CHECK: add 3, 3, 0
+    %5:g8rc = EXTSW_32_64 killed %4
+    %x3 = COPY %5
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            safeAddR0R3
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: gprc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1:g8rc = COPY %x4
+    %0:g8rc = COPY %x3
+    %2:gprc = COPY %0.sub_32
+    %r0 = LI 44
+    %4:gprc = ADD4 killed %r0, killed %2
+    ; CHECK: addi 3, 3, 44
+    %5:g8rc = EXTSW_32_64 killed %4
+    %x3 = COPY %5
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            safeAddR3R0
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: gprc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1:g8rc = COPY %x4
+    %0:g8rc = COPY %x3
+    %2:gprc = COPY %0.sub_32
+    %r0 = LI 44
+    %4:gprc = ADD4 killed %2, killed %r0
+    ; CHECK: addi 3, 3, 44
+    %5:g8rc = EXTSW_32_64 killed %4
+    %x3 = COPY %5
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            unsafeLDXR3R0
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x0', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x0, %x4
+  
+    %1:g8rc = COPY %x4
+    %0:g8rc_and_g8rc_nox0 = LI8 44
+    %2:g8rc = LDX %0, %x0 :: (load 8 from %ir.1, !tbaa !3)
+    ; CHECK: li 3, 44
+    ; CHECK: ldx 3, 3, 0
+    %x3 = COPY %2
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            safeLDXZeroR3
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1:g8rc = LI8 44
+    %0:g8rc_and_g8rc_nox0 = LI8 44
+    %2:g8rc = LDX %zero8, %1 :: (load 8 from %ir.1, !tbaa !3)
+    ; CHECK: ld 3, 44(0)
+    %x3 = COPY %2
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            safeLDXR3R0
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %x0 = LI8 44
+    %0:g8rc_and_g8rc_nox0 = COPY %x3
+    %2:g8rc = LDX %0, %x0 :: (load 8 from %ir.1, !tbaa !3)
+    ; CHECK: ld 3, 44(3)
+    %x3 = COPY %2
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...

Added: llvm/trunk/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir?rev=320791&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir (added)
+++ llvm/trunk/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir Thu Dec 14 23:27:53 2017
@@ -0,0 +1,6129 @@
+# RUN: llc -run-pass ppc-mi-peepholes -ppc-convert-rr-to-ri %s -o - | FileCheck %s
+# RUN: llc -start-after ppc-mi-peepholes -ppc-late-peephole %s -o - | FileCheck %s --check-prefix=CHECK-LATE
+
+--- |
+  ; ModuleID = 'convert-rr-to-ri-instrs.ll'
+  source_filename = "convert-rr-to-ri-instrs.c"
+  target datalayout = "e-m:e-i64:64-n32:64"
+  target triple = "powerpc64le-unknown-linux-gnu"
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define signext i32 @testADD4(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {
+  entry:
+    %add = add nsw i32 %a, 33
+    %add1 = add nsw i32 %add, %b
+    ret i32 %add1
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testADD8(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %add = add nsw i64 %a, 33
+    %add1 = add nsw i64 %add, %b
+    ret i64 %add1
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i128 @testADDC(i128 %a, i128 %b) local_unnamed_addr #0 {
+  entry:
+    %add = add nsw i128 %b, %a
+    ret i128 %add
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i128 @testADDC8(i128 %a, i128 %b) local_unnamed_addr #0 {
+  entry:
+    %add = add nsw i128 %b, %a
+    ret i128 %add
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testADDCo(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %add = add nsw i64 %b, %a
+    %cmp = icmp eq i64 %add, 0
+    %neg = sext i1 %cmp to i64
+    %retval.0 = xor i64 %add, %neg
+    ret i64 %retval.0
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define signext i32 @testADDI(i32 signext %a) local_unnamed_addr #0 {
+  entry:
+    %add = add nsw i32 %a, 44
+    ret i32 %add
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define signext i32 @testADDI8(i32 signext %a) local_unnamed_addr #0 {
+  entry:
+    %add = add nsw i32 %a, 44
+    ret i32 %add
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define signext i32 @testANDo(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %and = and i64 %b, %a
+    %tobool = icmp eq i64 %and, 0
+    %cond = select i1 %tobool, i64 %b, i64 %a
+    %conv = trunc i64 %cond to i32
+    ret i32 %conv
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testAND8o(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %and = and i64 %b, %a
+    %tobool = icmp eq i64 %and, 0
+    %cond = select i1 %tobool, i64 %b, i64 %a
+    ret i64 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testCMPD(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %cmp = icmp sgt i64 %a, %b
+    %add = select i1 %cmp, i64 0, i64 %a
+    %cond = add nsw i64 %add, %b
+    ret i64 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testCMPDI(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %cmp = icmp sgt i64 %a, 87
+    %add = select i1 %cmp, i64 0, i64 %a
+    %cond = add nsw i64 %add, %b
+    ret i64 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testCMPDI_F(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %cmp = icmp sgt i64 %a, 87
+    %add = select i1 %cmp, i64 0, i64 %a
+    %cond = add nsw i64 %add, %b
+    ret i64 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testCMPLD(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %cmp = icmp ugt i64 %a, %b
+    %add = select i1 %cmp, i64 0, i64 %a
+    %cond = add i64 %add, %b
+    ret i64 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testCMPLDI(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %cmp = icmp ugt i64 %a, 87
+    %add = select i1 %cmp, i64 0, i64 %a
+    %cond = add i64 %add, %b
+    ret i64 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define signext i32 @testCMPW(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {
+  entry:
+    %cmp = icmp sgt i32 %a, %b
+    %add = select i1 %cmp, i32 0, i32 %a
+    %cond = add nsw i32 %add, %b
+    ret i32 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define signext i32 @testCMPWI(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {
+  entry:
+    %cmp = icmp sgt i32 %a, 87
+    %add = select i1 %cmp, i32 0, i32 %a
+    %cond = add nsw i32 %add, %b
+    ret i32 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define zeroext i32 @testCMPLW(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 {
+  entry:
+    %cmp = icmp ugt i32 %a, %b
+    %add = select i1 %cmp, i32 0, i32 %a
+    %cond = add i32 %add, %b
+    ret i32 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define zeroext i32 @testCMPLWI(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 {
+  entry:
+    %cmp = icmp ugt i32 %a, 87
+    %add = select i1 %cmp, i32 0, i32 %a
+    %cond = add i32 %add, %b
+    ret i32 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define zeroext i8 @testLBZUX(i8* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds i8, i8* %ptr, i64 %idxprom
+    %0 = load i8, i8* %arrayidx, align 1, !tbaa !3
+    %conv = zext i8 %0 to i32
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds i8, i8* %ptr, i64 %idxprom2
+    %1 = load i8, i8* %arrayidx3, align 1, !tbaa !3
+    %conv4 = zext i8 %1 to i32
+    %add5 = add nuw nsw i32 %conv4, %conv
+    %conv6 = trunc i32 %add5 to i8
+    ret i8 %conv6
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define zeroext i8 @testLBZX(i8* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds i8, i8* %ptr, i64 %idxprom
+    %0 = load i8, i8* %arrayidx, align 1, !tbaa !3
+    %conv = zext i8 %0 to i32
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds i8, i8* %ptr, i64 %idxprom2
+    %1 = load i8, i8* %arrayidx3, align 1, !tbaa !3
+    %conv4 = zext i8 %1 to i32
+    %add5 = add nuw nsw i32 %conv4, %conv
+    %conv6 = trunc i32 %add5 to i8
+    ret i8 %conv6
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define zeroext i16 @testLHZUX(i16* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom
+    %0 = load i16, i16* %arrayidx, align 2, !tbaa !6
+    %conv = zext i16 %0 to i32
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2
+    %1 = load i16, i16* %arrayidx3, align 2, !tbaa !6
+    %conv4 = zext i16 %1 to i32
+    %add5 = add nuw nsw i32 %conv4, %conv
+    %conv6 = trunc i32 %add5 to i16
+    ret i16 %conv6
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define zeroext i16 @testLHZX(i16* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom
+    %0 = load i16, i16* %arrayidx, align 2, !tbaa !6
+    %conv = zext i16 %0 to i32
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2
+    %1 = load i16, i16* %arrayidx3, align 2, !tbaa !6
+    %conv4 = zext i16 %1 to i32
+    %add5 = add nuw nsw i32 %conv4, %conv
+    %conv6 = trunc i32 %add5 to i16
+    ret i16 %conv6
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define signext i16 @testLHAUX(i16* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom
+    %0 = load i16, i16* %arrayidx, align 2, !tbaa !6
+    %conv9 = zext i16 %0 to i32
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2
+    %1 = load i16, i16* %arrayidx3, align 2, !tbaa !6
+    %conv410 = zext i16 %1 to i32
+    %add5 = add nuw nsw i32 %conv410, %conv9
+    %conv6 = trunc i32 %add5 to i16
+    ret i16 %conv6
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define signext i16 @testLHAX(i16* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom
+    %0 = load i16, i16* %arrayidx, align 2, !tbaa !6
+    %conv9 = zext i16 %0 to i32
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2
+    %1 = load i16, i16* %arrayidx3, align 2, !tbaa !6
+    %conv410 = zext i16 %1 to i32
+    %add5 = add nuw nsw i32 %conv410, %conv9
+    %conv6 = trunc i32 %add5 to i16
+    ret i16 %conv6
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define zeroext i32 @testLWZUX(i32* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds i32, i32* %ptr, i64 %idxprom
+    %0 = load i32, i32* %arrayidx, align 4, !tbaa !8
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds i32, i32* %ptr, i64 %idxprom2
+    %1 = load i32, i32* %arrayidx3, align 4, !tbaa !8
+    %add4 = add i32 %1, %0
+    ret i32 %add4
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define zeroext i32 @testLWZX(i32* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds i32, i32* %ptr, i64 %idxprom
+    %0 = load i32, i32* %arrayidx, align 4, !tbaa !8
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds i32, i32* %ptr, i64 %idxprom2
+    %1 = load i32, i32* %arrayidx3, align 4, !tbaa !8
+    %add4 = add i32 %1, %0
+    ret i32 %add4
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define i64 @testLWAX(i32* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds i32, i32* %ptr, i64 %idxprom
+    %0 = load i32, i32* %arrayidx, align 4, !tbaa !8
+    %conv = sext i32 %0 to i64
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds i32, i32* %ptr, i64 %idxprom2
+    %1 = load i32, i32* %arrayidx3, align 4, !tbaa !8
+    %conv4 = sext i32 %1 to i64
+    %add5 = add nsw i64 %conv4, %conv
+    ret i64 %add5
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define i64 @testLDUX(i64* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds i64, i64* %ptr, i64 %idxprom
+    %0 = load i64, i64* %arrayidx, align 8, !tbaa !10
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds i64, i64* %ptr, i64 %idxprom2
+    %1 = load i64, i64* %arrayidx3, align 8, !tbaa !10
+    %add4 = add i64 %1, %0
+    ret i64 %add4
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define i64 @testLDX(i64* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds i64, i64* %ptr, i64 %idxprom
+    %0 = load i64, i64* %arrayidx, align 8, !tbaa !10
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds i64, i64* %ptr, i64 %idxprom2
+    %1 = load i64, i64* %arrayidx3, align 8, !tbaa !10
+    %add4 = add i64 %1, %0
+    ret i64 %add4
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define double @testLFDUX(double* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #2 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds double, double* %ptr, i64 %idxprom
+    %0 = load double, double* %arrayidx, align 8, !tbaa !12
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds double, double* %ptr, i64 %idxprom2
+    %1 = load double, double* %arrayidx3, align 8, !tbaa !12
+    %add4 = fadd double %0, %1
+    ret double %add4
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define double @testLFDX(double* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #2 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds double, double* %ptr, i64 %idxprom
+    %0 = load double, double* %arrayidx, align 8, !tbaa !12
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds double, double* %ptr, i64 %idxprom2
+    %1 = load double, double* %arrayidx3, align 8, !tbaa !12
+    %add4 = fadd double %0, %1
+    ret double %add4
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define <4 x float> @testLFSUX(float* nocapture readonly %ptr, i32 signext %idx) local_unnamed_addr #2 {
+  entry:
+    %idxprom = sext i32 %idx to i64
+    %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom
+    %0 = load float, float* %arrayidx, align 4, !tbaa !14
+    %conv = fptoui float %0 to i32
+    %vecinit = insertelement <4 x i32> undef, i32 %conv, i32 0
+    %1 = bitcast float* %ptr to i8*
+    %2 = shl i64 %idxprom, 2
+    %uglygep = getelementptr i8, i8* %1, i64 %2
+    %uglygep2 = getelementptr i8, i8* %uglygep, i64 4
+    %3 = bitcast i8* %uglygep2 to float*
+    %4 = load float, float* %3, align 4, !tbaa !14
+    %conv3 = fptoui float %4 to i32
+    %vecinit4 = insertelement <4 x i32> %vecinit, i32 %conv3, i32 1
+    %uglygep5 = getelementptr i8, i8* %uglygep, i64 8
+    %5 = bitcast i8* %uglygep5 to float*
+    %6 = load float, float* %5, align 4, !tbaa !14
+    %conv8 = fptoui float %6 to i32
+    %vecinit9 = insertelement <4 x i32> %vecinit4, i32 %conv8, i32 2
+    %uglygep8 = getelementptr i8, i8* %uglygep, i64 12
+    %7 = bitcast i8* %uglygep8 to float*
+    %8 = load float, float* %7, align 4, !tbaa !14
+    %conv13 = fptoui float %8 to i32
+    %vecinit14 = insertelement <4 x i32> %vecinit9, i32 %conv13, i32 3
+    %9 = bitcast <4 x i32> %vecinit14 to <4 x float>
+    ret <4 x float> %9
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define float @testLFSX(float* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #2 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom
+    %0 = load float, float* %arrayidx, align 4, !tbaa !14
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds float, float* %ptr, i64 %idxprom2
+    %1 = load float, float* %arrayidx3, align 4, !tbaa !14
+    %add4 = fadd float %0, %1
+    ret float %add4
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define double @testLXSDX(double* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds double, double* %ptr, i64 %idxprom
+    %0 = load double, double* %arrayidx, align 8, !tbaa !12
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds double, double* %ptr, i64 %idxprom2
+    %1 = load double, double* %arrayidx3, align 8, !tbaa !12
+    %add4 = fadd double %0, %1
+    ret double %add4
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define float @testLXSSPX(float* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom
+    %0 = load float, float* %arrayidx, align 4, !tbaa !14
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds float, float* %ptr, i64 %idxprom2
+    %1 = load float, float* %arrayidx3, align 4, !tbaa !14
+    %add4 = fadd float %0, %1
+    ret float %add4
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define <4 x i32> @testLXVX(<4 x i32>* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds <4 x i32>, <4 x i32>* %ptr, i64 %idxprom
+    %0 = load <4 x i32>, <4 x i32>* %arrayidx, align 16, !tbaa !3
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds <4 x i32>, <4 x i32>* %ptr, i64 %idxprom2
+    %1 = load <4 x i32>, <4 x i32>* %arrayidx3, align 16, !tbaa !3
+    %add4 = add <4 x i32> %1, %0
+    ret <4 x i32> %add4
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define signext i32 @testOR(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {
+  entry:
+    %or = or i32 %b, %a
+    ret i32 %or
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testOR8(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %or = or i64 %b, %a
+    ret i64 %or
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define signext i32 @testORI(i32 signext %a) local_unnamed_addr #0 {
+  entry:
+    %or = or i32 %a, 88
+    ret i32 %or
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testORI8(i64 %a) local_unnamed_addr #0 {
+  entry:
+    %or = or i64 %a, 99
+    ret i64 %or
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testRLDCL(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %and = and i64 %b, 63
+    %shl = shl i64 %a, %and
+    %sub = sub nsw i64 64, %and
+    %shr = lshr i64 %a, %sub
+    %or = or i64 %shr, %shl
+    ret i64 %or
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testRLDCLo(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %and = and i64 %b, 63
+    %shl = shl i64 %a, %and
+    %sub = sub nsw i64 64, %and
+    %shr = lshr i64 %a, %sub
+    %or = or i64 %shr, %shl
+    %tobool = icmp eq i64 %or, 0
+    %cond = select i1 %tobool, i64 %and, i64 %a
+    ret i64 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testRLDCR(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %and = and i64 %b, 63
+    %shl = shl i64 %a, %and
+    %sub = sub nsw i64 64, %and
+    %shr = lshr i64 %a, %sub
+    %or = or i64 %shr, %shl
+    ret i64 %or
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testRLDCRo(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %and = and i64 %b, 63
+    %shl = shl i64 %a, %and
+    %sub = sub nsw i64 64, %and
+    %shr = lshr i64 %a, %sub
+    %or = or i64 %shr, %shl
+    %tobool = icmp eq i64 %or, 0
+    %cond = select i1 %tobool, i64 %and, i64 %a
+    ret i64 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testRLDICL(i64 %a) local_unnamed_addr #0 {
+  entry:
+    %shr = lshr i64 %a, 11
+    %and = and i64 %shr, 16777215
+    ret i64 %and
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testRLDICLo(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %shr = lshr i64 %a, 11
+    %and = and i64 %shr, 16777215
+    %tobool = icmp eq i64 %and, 0
+    %cond = select i1 %tobool, i64 %b, i64 %and
+    ret i64 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define zeroext i32 @testRLWINM(i32 zeroext %a) local_unnamed_addr #0 {
+  entry:
+    %shl = shl i32 %a, 4
+    %and = and i32 %shl, 4080
+    ret i32 %and
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testRLWINM8(i64 %a) local_unnamed_addr #0 {
+  entry:
+    %shl = shl i64 %a, 4
+    %and = and i64 %shl, 4080
+    ret i64 %and
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define zeroext i32 @testRLWINMo(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 {
+  entry:
+    %and = and i32 %a, 255
+    %tobool = icmp eq i32 %and, 0
+    %cond = select i1 %tobool, i32 %b, i32 %a
+    ret i32 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testRLWINM8o(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %a.tr = trunc i64 %a to i32
+    %0 = shl i32 %a.tr, 4
+    %conv = and i32 %0, 4080
+    %tobool = icmp eq i32 %conv, 0
+    %conv1 = zext i32 %conv to i64
+    %cond = select i1 %tobool, i64 %b, i64 %conv1
+    ret i64 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testSLD(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %shl = shl i64 %a, %b
+    ret i64 %shl
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testSLDo(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %shl = shl i64 %a, %b
+    %tobool = icmp eq i64 %shl, 0
+    %cond = select i1 %tobool, i64 %b, i64 %a
+    ret i64 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testSRD(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %shr = lshr i64 %a, %b
+    ret i64 %shr
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testSRDo(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %shr = lshr i64 %a, %b
+    %tobool = icmp eq i64 %shr, 0
+    %cond = select i1 %tobool, i64 %b, i64 %a
+    ret i64 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define zeroext i32 @testSLW(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 {
+  entry:
+    %shl = shl i32 %a, %b
+    ret i32 %shl
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define zeroext i32 @testSLWo(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 {
+  entry:
+    %shl = shl i32 %a, %b
+    %tobool = icmp eq i32 %shl, 0
+    %cond = select i1 %tobool, i32 %b, i32 %a
+    ret i32 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define zeroext i32 @testSRW(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 {
+  entry:
+    %shr = lshr i32 %a, %b
+    ret i32 %shr
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define zeroext i32 @testSRWo(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 {
+  entry:
+    %shr = lshr i32 %a, %b
+    %tobool = icmp eq i32 %shr, 0
+    %cond = select i1 %tobool, i32 %b, i32 %a
+    ret i32 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define signext i32 @testSRAW(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {
+  entry:
+    %shr = ashr i32 %a, %b
+    ret i32 %shr
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define signext i32 @testSRAWo(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {
+  entry:
+    %shr = ashr i32 %a, %b
+    %tobool = icmp eq i32 %shr, 0
+    %cond = select i1 %tobool, i32 %b, i32 %shr
+    ret i32 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testSRAD(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %shr = ashr i64 %a, %b
+    ret i64 %shr
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testSRADo(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %shr = ashr i64 %a, %b
+    %tobool = icmp eq i64 %shr, 0
+    %cond = select i1 %tobool, i64 %b, i64 %shr
+    ret i64 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind
+  define void @testSTBUX(i8* nocapture %ptr, i8 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds i8, i8* %ptr, i64 %idxprom
+    store i8 %a, i8* %arrayidx, align 1, !tbaa !3
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds i8, i8* %ptr, i64 %idxprom2
+    store i8 %a, i8* %arrayidx3, align 1, !tbaa !3
+    ret void
+  }
+  
+  ; Function Attrs: norecurse nounwind
+  define void @testSTBX(i8* nocapture %ptr, i8 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds i8, i8* %ptr, i64 %idxprom
+    store i8 %a, i8* %arrayidx, align 1, !tbaa !3
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds i8, i8* %ptr, i64 %idxprom2
+    store i8 %a, i8* %arrayidx3, align 1, !tbaa !3
+    ret void
+  }
+  
+  ; Function Attrs: norecurse nounwind
+  define void @testSTHUX(i16* nocapture %ptr, i16 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom
+    store i16 %a, i16* %arrayidx, align 2, !tbaa !6
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2
+    store i16 %a, i16* %arrayidx3, align 2, !tbaa !6
+    ret void
+  }
+  
+  ; Function Attrs: norecurse nounwind
+  define void @testSTHX(i16* nocapture %ptr, i16 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom
+    store i16 %a, i16* %arrayidx, align 1, !tbaa !3
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2
+    store i16 %a, i16* %arrayidx3, align 1, !tbaa !3
+    ret void
+  }
+  
+  ; Function Attrs: norecurse nounwind
+  define void @testSTWUX(i32* nocapture %ptr, i32 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds i32, i32* %ptr, i64 %idxprom
+    store i32 %a, i32* %arrayidx, align 4, !tbaa !8
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds i32, i32* %ptr, i64 %idxprom2
+    store i32 %a, i32* %arrayidx3, align 4, !tbaa !8
+    ret void
+  }
+  
+  ; Function Attrs: norecurse nounwind
+  define void @testSTWX(i32* nocapture %ptr, i32 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds i32, i32* %ptr, i64 %idxprom
+    store i32 %a, i32* %arrayidx, align 4, !tbaa !8
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds i32, i32* %ptr, i64 %idxprom2
+    store i32 %a, i32* %arrayidx3, align 4, !tbaa !8
+    ret void
+  }
+  
+  ; Function Attrs: norecurse nounwind
+  define void @testSTDUX(i64* nocapture %ptr, i64 %a, i32 zeroext %idx) local_unnamed_addr #3 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds i64, i64* %ptr, i64 %idxprom
+    store i64 %a, i64* %arrayidx, align 8, !tbaa !10
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds i64, i64* %ptr, i64 %idxprom2
+    store i64 %a, i64* %arrayidx3, align 8, !tbaa !10
+    ret void
+  }
+  
+  ; Function Attrs: norecurse nounwind
+  define void @testSTDX(i64* nocapture %ptr, i64 %a, i32 zeroext %idx) local_unnamed_addr #3 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds i64, i64* %ptr, i64 %idxprom
+    store i64 %a, i64* %arrayidx, align 8, !tbaa !10
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds i64, i64* %ptr, i64 %idxprom2
+    store i64 %a, i64* %arrayidx3, align 8, !tbaa !10
+    ret void
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define void @testSTFSX(float* nocapture %ptr, float %a, i32 zeroext %idx) local_unnamed_addr #2 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom
+    store float %a, float* %arrayidx, align 4, !tbaa !14
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds float, float* %ptr, i64 %idxprom2
+    store float %a, float* %arrayidx3, align 4, !tbaa !14
+    ret void
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define void @testSTFSUX(float* nocapture %ptr, float %a, i32 zeroext %idx) local_unnamed_addr #2 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom
+    store float %a, float* %arrayidx, align 4, !tbaa !14
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds float, float* %ptr, i64 %idxprom2
+    store float %a, float* %arrayidx3, align 4, !tbaa !14
+    ret void
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define void @testSTFDX(double* nocapture %ptr, double %a, i32 zeroext %idx) local_unnamed_addr #2 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds double, double* %ptr, i64 %idxprom
+    store double %a, double* %arrayidx, align 8, !tbaa !12
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds double, double* %ptr, i64 %idxprom2
+    store double %a, double* %arrayidx3, align 8, !tbaa !12
+    ret void
+  }
+  
+  ; Function Attrs: norecurse nounwind readonly
+  define void @testSTFDUX(double* nocapture %ptr, double %a, i32 zeroext %idx) local_unnamed_addr #2 {
+  entry:
+    %add = add i32 %idx, 1
+    %idxprom = zext i32 %add to i64
+    %arrayidx = getelementptr inbounds double, double* %ptr, i64 %idxprom
+    store double %a, double* %arrayidx, align 8, !tbaa !12
+    %add1 = add i32 %idx, 2
+    %idxprom2 = zext i32 %add1 to i64
+    %arrayidx3 = getelementptr inbounds double, double* %ptr, i64 %idxprom2
+    store double %a, double* %arrayidx3, align 8, !tbaa !12
+    ret void
+  }
+  
+  ; Function Attrs: norecurse nounwind
+  define void @testSTXSSPX(float* nocapture %ptr, float %a, i32 zeroext %idx) local_unnamed_addr #3 {
+  entry:
+    %idxprom = zext i32 %idx to i64
+    %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom
+    store float %a, float* %arrayidx, align 4, !tbaa !14
+    ret void
+  }
+  
+  ; Function Attrs: norecurse nounwind
+  define void @testSTXSDX(double* nocapture %ptr, double %a, i32 zeroext %idx) local_unnamed_addr #3 {
+  entry:
+    %idxprom = zext i32 %idx to i64
+    %arrayidx = getelementptr inbounds double, double* %ptr, i64 %idxprom
+    store double %a, double* %arrayidx, align 8, !tbaa !12
+    ret void
+  }
+  
+  ; Function Attrs: norecurse nounwind
+  define void @testSTXVX(<4 x i32>* nocapture %ptr, <4 x i32> %a, i32 zeroext %idx) local_unnamed_addr #3 {
+  entry:
+    %idxprom = zext i32 %idx to i64
+    %arrayidx = getelementptr inbounds <4 x i32>, <4 x i32>* %ptr, i64 %idxprom
+    store <4 x i32> %a, <4 x i32>* %arrayidx, align 16, !tbaa !3
+    ret void
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i128 @testSUBFC(i128 %a, i128 %b) local_unnamed_addr #0 {
+  entry:
+    %sub = sub nsw i128 %a, %b
+    ret i128 %sub
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i128 @testSUBFC8(i128 %a, i128 %b) local_unnamed_addr #0 {
+  entry:
+    %sub = sub nsw i128 %a, %b
+    ret i128 %sub
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define signext i32 @testXOR(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {
+  entry:
+    %xor = xor i32 %b, %a
+    ret i32 %xor
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testXOR8(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %xor = xor i64 %b, %a
+    ret i64 %xor
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define signext i32 @testXORI(i32 signext %a) local_unnamed_addr #0 {
+  entry:
+    %xor = xor i32 %a, 17
+    ret i32 %xor
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testXOR8I(i64 %a) local_unnamed_addr #0 {
+  entry:
+    %xor = xor i64 %a, 17
+    ret i64 %xor
+  }
+  
+  attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pwr9" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+power9-vector,+vsx,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" }
+  attributes #1 = { norecurse nounwind readonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pwr9" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+power9-vector,+vsx,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" }
+  attributes #2 = { norecurse nounwind readonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pwr9" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+power9-vector,-vsx,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" }
+  attributes #3 = { norecurse nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pwr9" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+power9-vector,+vsx,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" }
+  
+  !llvm.module.flags = !{!0, !1}
+  !llvm.ident = !{!2}
+  
+  !0 = !{i32 1, !"wchar_size", i32 4}
+  !1 = !{i32 7, !"PIC Level", i32 2}
+  !2 = !{!"clang version 6.0.0 (trunk 316067)"}
+  !3 = !{!4, !4, i64 0}
+  !4 = !{!"omnipotent char", !5, i64 0}
+  !5 = !{!"Simple C/C++ TBAA"}
+  !6 = !{!7, !7, i64 0}
+  !7 = !{!"short", !4, i64 0}
+  !8 = !{!9, !9, i64 0}
+  !9 = !{!"int", !4, i64 0}
+  !10 = !{!11, !11, i64 0}
+  !11 = !{!"long long", !4, i64 0}
+  !12 = !{!13, !13, i64 0}
+  !13 = !{!"double", !4, i64 0}
+  !14 = !{!15, !15, i64 0}
+  !15 = !{!"float", !4, i64 0}
+
+...
+---
+name:            testADD4
+# CHECK-ALL: name: testADD4
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 5, class: gprc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = LI 33
+    %3 = COPY %0.sub_32
+    %4 = ADD4 killed %3, %2
+    %5 = ADD4 killed %2, killed %4
+    ; CHECK: ADDI killed %3, 33
+    ; CHECK: ADDI killed %4, 33
+    ; CHECK-LATE: addi 3, 3, 33
+    ; CHECK-LATE: addi 3, 3, 33
+    %6 = EXTSW_32_64 killed %5
+    %x3 = COPY %6
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testADD8
+# CHECK-ALL: name: testADD8
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 3, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = LI8 33
+    %0 = COPY %x3
+    %2 = ADD8 %0, %1
+    %3 = ADD8 killed %1, killed %2
+    ; CHECK: ADDI8 %0, 33
+    ; CHECK: ADDI8 killed %2, 33
+    ; CHECK-LATE: addi 3, 3, 33
+    ; CHECK-LATE: addi 3, 3, 33
+    %x3 = COPY %3
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testADDC
+# CHECK-ALL: name: testADDC
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: g8rc, preferred-register: '' }
+  - { id: 4, class: gprc, preferred-register: '' }
+  - { id: 5, class: gprc, preferred-register: '' }
+  - { id: 6, class: gprc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+  - { id: 8, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+  - { reg: '%x5', virtual-reg: '%2' }
+  - { reg: '%x6', virtual-reg: '%3' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4, %x5, %x6
+  
+    %3 = COPY %x6
+    %2 = COPY %x5
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %4 = COPY %0.sub_32
+    %5 = LI 55
+    %6 = ADDC %5, %4, implicit-def %carry
+    ; CHECK: ADDIC %4, 55, implicit-def %carry
+    ; CHECK-LATE: addic 3, 3, 55
+    %7 = ADDE8 %3, %1, implicit-def dead %carry, implicit %carry
+    %8 = EXTSW_32_64 %6
+    %x3 = COPY %8
+    %x4 = COPY %7
+    BLR8 implicit %lr8, implicit %rm, implicit %x3, implicit %x4
+
+...
+---
+name:            testADDC8
+# CHECK-ALL: name: testADDC8
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: g8rc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+  - { reg: '%x5', virtual-reg: '%2' }
+  - { reg: '%x6', virtual-reg: '%3' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4, %x5, %x6
+  
+    %3 = COPY %x6
+    %2 = COPY %x5
+    %1 = COPY %x4
+    %0 = LI8 777
+    %4 = ADDC8 %2, %0, implicit-def %carry
+    ; CHECK: ADDIC8 %2, 777, implicit-def %carry
+    ; CHECK-LATE: addic 3, 5, 777
+    %5 = ADDE8 %3, %1, implicit-def dead %carry, implicit %carry
+    %x3 = COPY %4
+    %x4 = COPY %5
+    BLR8 implicit %lr8, implicit %rm, implicit %x3, implicit %x4
+
+...
+---
+name:            testADDCo
+# CHECK-ALL: name: testADDCo
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: gprc, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: crrc, preferred-register: '' }
+  - { id: 5, class: crbitrc, preferred-register: '' }
+  - { id: 6, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 7, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 8, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = LI 433
+    %0 = COPY %x3
+    %2 = COPY %0.sub_32
+    %3 = ADDCo %1, %2, implicit-def %cr0, implicit-def %carry
+    ; CHECK: ADDICo %2, 433, implicit-def %cr0, implicit-def %carry
+    ; CHECK-LATE: addic. 3, 3, 433
+    %4 = COPY killed %cr0
+    %5 = COPY %4.sub_eq
+    %6 = LI8 0
+    %7 = LI8 -1
+    %8 = ISEL8 %7, %6, %5
+    %x3 = COPY %8
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testADDI
+# CHECK-ALL: name: testADDI
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3
+  
+    %0 = COPY %x3
+    %1 = LI 77
+    %2 = ADDI killed %1, 44
+    %3 = EXTSW_32_64 killed %2
+    ; CHECK: LI 121
+    ; CHECK-LATE: li 3, 121
+    %x3 = COPY %3
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testADDI8
+# CHECK-ALL: name: testADDI8
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3
+  
+    %0 = COPY %x3
+    %1 = LI8 333
+    %2 = ADDI8 killed %1, 44
+    ; CHECK: LI8 377
+    ; CHECK-LATE: li 3, 377
+    %3 = EXTSW killed %2
+    %x3 = COPY %3
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testANDo
+# CHECK-ALL: name: testANDo
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: gprc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: crrc, preferred-register: '' }
+  - { id: 5, class: gprc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = LI 78
+    %0 = COPY %x3
+    %2 = COPY %0.sub_32
+    %3 = ANDo %1, %2, implicit-def %cr0
+    ; CHECK: ANDIo %2, 78, implicit-def %cr0
+    ; CHECK-LATE: andi. 5, 3, 78
+    %4 = COPY killed %cr0
+    %5 = ISEL %2, %1, %4.sub_eq
+    %6 = EXTSW_32_64 killed %5
+    %x3 = COPY %6
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testAND8o
+# CHECK-ALL: name: testAND8o
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: crrc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = LI8 321
+    %0 = COPY %x3
+    %2 = AND8o %1, %0, implicit-def %cr0
+    ; CHECK: ANDIo8 %0, 321, implicit-def %cr0
+    ; CHECK-LATE: andi. 5, 3, 321
+    %3 = COPY killed %cr0
+    %4 = ISEL8 %1, %0, %3.sub_eq
+    %x3 = COPY %4
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testCMPD
+# CHECK-ALL: name: testCMPD
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: crrc, preferred-register: '' }
+  - { id: 3, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = LI8 65533
+    %0 = COPY %x3
+    %2 = CMPD %0, %1
+    ; CHECK: CMPDI %0, -3
+    ; CHECK-LATE: cmpdi 3, -3
+    %4 = ISEL8 %zero8, %0, %2.sub_gt
+    %5 = ADD8 killed %4, %1
+    %x3 = COPY %5
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testCMPDI
+# CHECK-ALL: name: testCMPDI
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: crrc, preferred-register: '' }
+  - { id: 3, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = LI8 89
+    %2 = CMPDI %0, 87
+    %4 = ISEL8 %zero8, %0, %2.sub_gt
+    ; CHECK: LI8 0
+    %5 = ADD8 killed %4, %1
+    %x3 = COPY %5
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testCMPDI_F
+# CHECK-ALL: name: testCMPDI_F
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: crrc, preferred-register: '' }
+  - { id: 3, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = LI8 87
+    %2 = CMPDI %0, 87
+    %4 = ISEL8 %zero8, %0, %2.sub_gt
+    ; CHECK: COPY %0
+    %5 = ADD8 killed %4, %1
+    %x3 = COPY %5
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testCMPLD
+# CHECK-ALL: name: testCMPLD
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: crrc, preferred-register: '' }
+  - { id: 3, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = LI8 99
+    %0 = COPY %x3
+    %2 = CMPLD %0, %1
+    ; CHECK: CMPLDI %0, 99
+    ; CHECK-LATE: cmpldi 3, 99
+    %4 = ISEL8 %zero8, %0, %2.sub_gt
+    %5 = ADD8 killed %4, %1
+    %x3 = COPY %5
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testCMPLDI
+# CHECK-ALL: name: testCMPLDI
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: crrc, preferred-register: '' }
+  - { id: 3, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = LI8 65534
+    %2 = CMPLDI %0, 65535
+    %4 = ISEL8 %zero8, %0, %2.sub_gt
+    ; CHECK: COPY %0
+    %5 = ADD8 killed %4, %1
+    %x3 = COPY %5
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testCMPW
+# CHECK-ALL: name: testCMPW
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 4, class: crrc, preferred-register: '' }
+  - { id: 5, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 6, class: gprc, preferred-register: '' }
+  - { id: 7, class: gprc, preferred-register: '' }
+  - { id: 8, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = LI -1
+    %3 = COPY %0.sub_32
+    %4 = CMPW %3, %2
+    ; CHECK: CMPWI %3, -1
+    %6 = ISEL %zero, %3, %4.sub_gt
+    %7 = ADD4 killed %6, %2
+    %8 = EXTSW_32_64 killed %7
+    %x3 = COPY %8
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testCMPWI
+# CHECK-ALL: name: testCMPWI
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 4, class: crrc, preferred-register: '' }
+  - { id: 5, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 6, class: gprc, preferred-register: '' }
+  - { id: 7, class: gprc, preferred-register: '' }
+  - { id: 8, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = COPY %1.sub_32
+    %3 = LI -3
+    %4 = CMPWI %3, 87
+    %6 = ISEL %zero, %3, %4.sub_gt
+    ; CHECK: COPY %3
+    %7 = ADD4 killed %6, killed %2
+    %8 = EXTSW_32_64 killed %7
+    %x3 = COPY %8
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testCMPLW
+# CHECK-ALL: name: testCMPLW
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 4, class: crrc, preferred-register: '' }
+  - { id: 5, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 6, class: gprc, preferred-register: '' }
+  - { id: 7, class: gprc, preferred-register: '' }
+  - { id: 8, class: g8rc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = LI 32767
+    %3 = COPY %0.sub_32
+    %4 = CMPLW %3, %2
+    ; CHECK: CMPLWI %3, 32767
+    ; CHECK-LATE: cmplwi 3, 32767
+    %6 = ISEL %zero, %3, %4.sub_gt
+    %7 = ADD4 killed %6, %2
+    %9 = IMPLICIT_DEF
+    %8 = INSERT_SUBREG %9, killed %7, 1
+    %10 = RLDICL killed %8, 0, 32
+    %x3 = COPY %10
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testCMPLWI
+# CHECK-ALL: name: testCMPLWI
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 4, class: crrc, preferred-register: '' }
+  - { id: 5, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 6, class: gprc, preferred-register: '' }
+  - { id: 7, class: gprc, preferred-register: '' }
+  - { id: 8, class: g8rc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = COPY %1.sub_32
+    %3 = LI -3
+    %4 = CMPLWI %3, 87
+    %6 = ISEL %zero, %3, %4.sub_gt
+    ; CHECK: LI 0
+    %7 = ADD4 killed %6, killed %2
+    %9 = IMPLICIT_DEF
+    %8 = INSERT_SUBREG %9, killed %7, 1
+    %10 = RLDICL killed %8, 0, 32
+    %x3 = COPY %10
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testLBZUX
+# CHECK-ALL: name: testLBZUX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: gprc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: gprc, preferred-register: '' }
+  - { id: 13, class: gprc, preferred-register: '' }
+  - { id: 14, class: g8rc, preferred-register: '' }
+  - { id: 15, class: g8rc, preferred-register: '' }
+  - { id: 16, class: g8rc, preferred-register: '' }
+  - { id: 17, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = COPY %1.sub_32
+    %3 = ADDI %2, 1
+    %5 = IMPLICIT_DEF
+    %4 = INSERT_SUBREG %5, killed %3, 1
+    %6 = RLDICL killed %4, 0, 32
+    %7 = LBZX %0, killed %6 :: (load 1 from %ir.arrayidx, !tbaa !3)
+    %8 = ADDI %2, 2
+    %10 = IMPLICIT_DEF
+    %9 = INSERT_SUBREG %10, killed %8, 1
+    %11 = LI8 -15
+    %12,%17 = LBZUX %0, killed %11 :: (load 1 from %ir.arrayidx3, !tbaa !3)
+    ; CHECK: LBZU -15, %0
+    ; CHECK-LATE: lbzu 5, -15(3)
+    %13 = ADD4 killed %12, killed %7
+    %15 = IMPLICIT_DEF
+    %14 = INSERT_SUBREG %15, killed %13, 1
+    %16 = RLWINM8 killed %14, 0, 24, 31
+    %x3 = COPY %16
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testLBZX
+# CHECK-ALL: name: testLBZX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: gprc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: gprc, preferred-register: '' }
+  - { id: 13, class: gprc, preferred-register: '' }
+  - { id: 14, class: g8rc, preferred-register: '' }
+  - { id: 15, class: g8rc, preferred-register: '' }
+  - { id: 16, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = LI8 45
+    %2 = COPY %1.sub_32
+    %3 = ADDI %2, 1
+    %5 = IMPLICIT_DEF
+    %4 = INSERT_SUBREG %5, killed %3, 1
+    %6 = RLDICL killed %4, 0, 32
+    %7 = LBZX %0, killed %6 :: (load 1 from %ir.arrayidx, !tbaa !3)
+    ; CHECK: LBZ 45, killed %6
+    ; CHECK-LATE: lbz 5, 45(5)
+    %8 = ADDI %2, 2
+    %10 = IMPLICIT_DEF
+    %9 = INSERT_SUBREG %10, killed %8, 1
+    %11 = RLDICL killed %9, 0, 32
+    %12 = LBZX %0, killed %11 :: (load 1 from %ir.arrayidx3, !tbaa !3)
+    ; CHECK: LBZ 45, killed %11
+    ; CHECK-LATE: lbz 3, 45(4)
+    %13 = ADD4 killed %12, killed %7
+    %15 = IMPLICIT_DEF
+    %14 = INSERT_SUBREG %15, killed %13, 1
+    %16 = RLWINM8 killed %14, 0, 24, 31
+    %x3 = COPY %16
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testLHZUX
+# CHECK-ALL: name: testLHZUX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: gprc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: gprc, preferred-register: '' }
+  - { id: 13, class: gprc, preferred-register: '' }
+  - { id: 14, class: g8rc, preferred-register: '' }
+  - { id: 15, class: g8rc, preferred-register: '' }
+  - { id: 16, class: g8rc, preferred-register: '' }
+  - { id: 17, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = COPY %1.sub_32
+    %3 = ADDI %2, 1
+    %5 = IMPLICIT_DEF
+    %4 = INSERT_SUBREG %5, killed %3, 1
+    %6 = RLDIC killed %4, 1, 31
+    %7 = LHZX %0, killed %6 :: (load 2 from %ir.arrayidx, !tbaa !6)
+    %8 = ADDI %2, 2
+    %10 = IMPLICIT_DEF
+    %9 = INSERT_SUBREG %10, killed %8, 1
+    %11 = LI8 31440
+    %12,%17 = LHZUX %0, killed %11 :: (load 2 from %ir.arrayidx3, !tbaa !6)
+    ; CHECK: LHZU 31440, %0
+    ; CHECK-LATE: lhzu 5, 31440(3)
+    %13 = ADD4 killed %12, killed %7
+    %15 = IMPLICIT_DEF
+    %14 = INSERT_SUBREG %15, killed %13, 1
+    %16 = RLWINM8 killed %14, 0, 16, 31
+    %x3 = COPY %16
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testLHZX
+# CHECK-ALL: name: testLHZX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: gprc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: gprc, preferred-register: '' }
+  - { id: 13, class: gprc, preferred-register: '' }
+  - { id: 14, class: g8rc, preferred-register: '' }
+  - { id: 15, class: g8rc, preferred-register: '' }
+  - { id: 16, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = COPY %1.sub_32
+    %3 = ADDI %2, 1
+    %5 = IMPLICIT_DEF
+    %4 = INSERT_SUBREG %5, killed %3, 1
+    %6 = RLDIC killed %4, 1, 31
+    %7 = LHZX %0, killed %6 :: (load 2 from %ir.arrayidx, !tbaa !6)
+    %8 = ADDI %2, 2
+    %10 = IMPLICIT_DEF
+    %9 = INSERT_SUBREG %10, killed %8, 1
+    %11 = LI8 882
+    %12 = LHZX %0, killed %11 :: (load 2 from %ir.arrayidx3, !tbaa !6)
+    ; CHECK: LHZ 882, %0
+    ; CHECK-LATE: lhz 3, 882(3)
+    %13 = ADD4 killed %12, killed %7
+    %15 = IMPLICIT_DEF
+    %14 = INSERT_SUBREG %15, killed %13, 1
+    %16 = RLWINM8 killed %14, 0, 16, 31
+    %x3 = COPY %16
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testLHAUX
+# CHECK-ALL: name: testLHAUX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: gprc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: gprc, preferred-register: '' }
+  - { id: 13, class: gprc, preferred-register: '' }
+  - { id: 14, class: g8rc, preferred-register: '' }
+  - { id: 15, class: g8rc, preferred-register: '' }
+  - { id: 16, class: g8rc, preferred-register: '' }
+  - { id: 17, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = COPY %1.sub_32
+    %3 = ADDI %2, 1
+    %5 = IMPLICIT_DEF
+    %4 = INSERT_SUBREG %5, killed %3, 1
+    %6 = RLDIC %4, 1, 31
+    %7 = LHZX %0, killed %6 :: (load 2 from %ir.arrayidx, !tbaa !6)
+    %8 = ADDI %2, 2
+    %10 = IMPLICIT_DEF
+    %9 = INSERT_SUBREG %10, killed %8, 1
+    %11 = LI8 400
+    %12,%17 = LHAUX %0, killed %11 :: (load 2 from %ir.arrayidx3, !tbaa !6)
+    ; CHECK: LHAU 400, %0
+    ; CHECK-LATE: lhau 5, 400(3)
+    %13 = ADD4 killed %12, killed %7
+    %15 = IMPLICIT_DEF
+    %14 = INSERT_SUBREG %15, killed %13, 1
+    %16 = EXTSH8 killed %14
+    %x3 = COPY %16
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testLHAX
+# CHECK-ALL: name: testLHAX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: gprc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: gprc, preferred-register: '' }
+  - { id: 13, class: gprc, preferred-register: '' }
+  - { id: 14, class: g8rc, preferred-register: '' }
+  - { id: 15, class: g8rc, preferred-register: '' }
+  - { id: 16, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = COPY %1.sub_32
+    %3 = ADDI %2, 1
+    %5 = IMPLICIT_DEF
+    %4 = INSERT_SUBREG %5, killed %3, 1
+    %6 = LI8 -999
+    %7 = LHAX %0, killed %6 :: (load 2 from %ir.arrayidx, !tbaa !6)
+    ; CHECK: LHA -999, %0
+    ; CHECK-LATE: lha 4, -999(3)
+    %8 = ADDI %2, 2
+    %10 = IMPLICIT_DEF
+    %9 = INSERT_SUBREG %10, killed %8, 1
+    %11 = LI8 999
+    %12 = LHAX %0, killed %11 :: (load 2 from %ir.arrayidx3, !tbaa !6)
+    ; CHECK: LHA 999, %0 
+    ; CHECK-LATE: lha 3, 999(3)
+    %13 = ADD4 killed %12, killed %7
+    %15 = IMPLICIT_DEF
+    %14 = INSERT_SUBREG %15, killed %13, 1
+    %16 = EXTSH8 killed %14
+    %x3 = COPY %16
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testLWZUX
+# CHECK-ALL: name: testLWZUX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: gprc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: gprc, preferred-register: '' }
+  - { id: 13, class: gprc, preferred-register: '' }
+  - { id: 14, class: g8rc, preferred-register: '' }
+  - { id: 15, class: g8rc, preferred-register: '' }
+  - { id: 16, class: g8rc, preferred-register: '' }
+  - { id: 17, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 18, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = COPY %1.sub_32
+    %3 = ADDI %2, 1
+    %5 = IMPLICIT_DEF
+    %4 = INSERT_SUBREG %5, killed %3, 1
+    %6 = LI8 889
+    %7,%17 = LWZUX %0, killed %6 :: (load 4 from %ir.arrayidx, !tbaa !8)
+    ; CHECK: LWZU 889, %0
+    ; CHECK-LATE: lwzu 5, 889(4)
+    %8 = ADDI %2, 2
+    %10 = IMPLICIT_DEF
+    %9 = INSERT_SUBREG %10, killed %8, 1
+    %11 = LI8 -2
+    %12,%18 = LWZUX %0, killed %11 :: (load 4 from %ir.arrayidx3, !tbaa !8)
+    ; CHECK: LWZU -2, %0
+    ; CHECK-LATE: lwzu 4, -2(3)
+    %13 = ADD4 killed %12, killed %7
+    %15 = IMPLICIT_DEF
+    %14 = INSERT_SUBREG %15, killed %13, 1
+    %16 = RLDICL killed %14, 0, 32
+    %x3 = COPY %16
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testLWZX
+# CHECK-ALL: name: testLWZX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: gprc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: gprc, preferred-register: '' }
+  - { id: 13, class: gprc, preferred-register: '' }
+  - { id: 14, class: g8rc, preferred-register: '' }
+  - { id: 15, class: g8rc, preferred-register: '' }
+  - { id: 16, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = LI8 1000
+    %2 = COPY %1.sub_32
+    %3 = ADDI %2, 1
+    %5 = IMPLICIT_DEF
+    %4 = INSERT_SUBREG %5, killed %3, 1
+    %6 = RLDIC %4, 2, 30
+    %7 = LWZX %0, killed %6 :: (load 4 from %ir.arrayidx, !tbaa !8)
+    ; CHECK: LWZ 1000, killed %6
+    ; CHECK-LATE: lwz 5, 1000(5)
+    %8 = ADDI %2, 2
+    %10 = IMPLICIT_DEF
+    %9 = INSERT_SUBREG %10, killed %8, 1
+    %11 = RLDIC %9, 2, 30
+    %12 = LWZX %0, killed %11 :: (load 4 from %ir.arrayidx3, !tbaa !8)
+    ; CHECK: LWZ 1000, killed %11
+    ; CHECK-LATE: lwz 3, 1000(4)
+    %13 = ADD4 killed %12, killed %7
+    %15 = IMPLICIT_DEF
+    %14 = INSERT_SUBREG %15, killed %13, 1
+    %16 = RLDICL killed %14, 0, 32
+    %x3 = COPY %16
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testLWAX
+# CHECK-ALL: name: testLWAX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: g8rc, preferred-register: '' }
+  - { id: 13, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = LI8 444
+    %2 = COPY %1.sub_32
+    %3 = ADDI %2, 1
+    %5 = IMPLICIT_DEF
+    %4 = INSERT_SUBREG %5, killed %3, 1
+    %6 = RLDIC %4, 2, 30
+    %7 = LWAX %0, killed %6 :: (load 4 from %ir.arrayidx, !tbaa !8)
+    ; CHECK: LWA 444, killed %6
+    ; CHECK-LATE: lwa 5, 444(5)
+    %8 = ADDI %2, 2
+    %10 = IMPLICIT_DEF
+    %9 = INSERT_SUBREG %10, killed %8, 1
+    %11 = RLDIC %9, 2, 30
+    %12 = LWAX %0, killed %11 :: (load 4 from %ir.arrayidx3, !tbaa !8)
+    ; CHECK: LWA 444, killed %11
+    ; CHECK-LATE: lwa 3, 444(4)
+    %13 = ADD8 killed %12, killed %7
+    %x3 = COPY %13
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testLDUX
+# CHECK-ALL: name: testLDUX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: g8rc, preferred-register: '' }
+  - { id: 13, class: g8rc, preferred-register: '' }
+  - { id: 14, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 15, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = COPY %1.sub_32
+    %3 = ADDI %2, 1
+    %5 = IMPLICIT_DEF
+    %4 = INSERT_SUBREG %5, killed %3, 1
+    %6 = LI8 100
+    %7,%14 = LDUX %0, killed %6 :: (load 8 from %ir.arrayidx, !tbaa !10)
+    ; CHECK: LDU 100, %0
+    ; CHECK-LATE: ldu 5, 100(4)
+    %8 = ADDI %2, 2
+    %10 = IMPLICIT_DEF
+    %9 = INSERT_SUBREG %10, killed %8, 1
+    %11 = LI8 200
+    %12,%15 = LDUX %0, killed %11 :: (load 8 from %ir.arrayidx3, !tbaa !10)
+    ; CHECK: LDU 200, %0
+    ; CHECK-LATE: ldu 4, 200(3)
+    %13 = ADD8 killed %12, killed %7
+    %x3 = COPY %13
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testLDX
+# CHECK-ALL: name: testLDX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: g8rc, preferred-register: '' }
+  - { id: 13, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = COPY %1.sub_32
+    %3 = ADDI %2, 1
+    %5 = IMPLICIT_DEF
+    %4 = INSERT_SUBREG %5, killed %3, 1
+    %6 = LI8 120
+    %7 = LDX %0, killed %6 :: (load 8 from %ir.arrayidx, !tbaa !10)
+    ; CHECK: LD 120, %0
+    ; CHECK-LATE: ld 4, 120(3)
+    %8 = ADDI %2, 2
+    %10 = IMPLICIT_DEF
+    %9 = INSERT_SUBREG %10, killed %8, 1
+    %11 = LI8 280
+    %12 = LDX %0, killed %11 :: (load 8 from %ir.arrayidx3, !tbaa !10)
+    ; CHECK: LD 280, %0
+    ; CHECK-LATE: ld 12, 280(3)
+    %13 = ADD8 killed %12, killed %7
+    %x3 = COPY %13
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testLFDUX
+# CHECK-ALL: name: testLFDUX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: f8rc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: f8rc, preferred-register: '' }
+  - { id: 13, class: f8rc, preferred-register: '' }
+  - { id: 14, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 15, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = COPY %1.sub_32
+    %3 = ADDI %2, 1
+    %5 = IMPLICIT_DEF
+    %4 = INSERT_SUBREG %5, killed %3, 1
+    %6 = LI8 440
+    %7,%14 = LFDUX %0, killed %6 :: (load 8 from %ir.arrayidx, !tbaa !12)
+    ; CHECK: LFDU 440, %0
+    ; CHECK-LATE: lfdu 0, 440(4)
+    %8 = ADDI %2, 2
+    %10 = IMPLICIT_DEF
+    %9 = INSERT_SUBREG %10, killed %8, 1
+    %11 = LI8 16
+    %12,%15 = LFDUX %0, killed %11 :: (load 8 from %ir.arrayidx3, !tbaa !12)
+    ; CHECK: LFDU 16, %0
+    ; CHECK-LATE: lfdu 1, 16(3)
+    %13 = FADD killed %7, killed %12, implicit %rm
+    %f1 = COPY %13
+    BLR8 implicit %lr8, implicit %rm, implicit %f1
+
+...
+---
+name:            testLFDX
+# CHECK-ALL: name: testLFDX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: f8rc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: f8rc, preferred-register: '' }
+  - { id: 13, class: f8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = LI8 -20
+    %2 = COPY %1.sub_32
+    %3 = ADDI %2, 1
+    %5 = IMPLICIT_DEF
+    %4 = INSERT_SUBREG %5, killed %3, 1
+    %6 = RLDIC %4, 3, 29
+    %7 = LFDX %0, killed %6 :: (load 8 from %ir.arrayidx, !tbaa !12)
+    ; CHECK: LFD -20, killed %6
+    ; CHECK-LATE: lfd 0, -20(5)
+    %8 = ADDI %2, 2
+    %10 = IMPLICIT_DEF
+    %9 = INSERT_SUBREG %10, killed %8, 1
+    %11 = RLDIC %9, 3, 29
+    %12 = LFDX %0, killed %11 :: (load 8 from %ir.arrayidx3, !tbaa !12)
+    ; CHECK: LFD -20, killed %11
+    ; CHECK-LATE: lfd 1, -20(4)
+    %13 = FADD killed %7, killed %12, implicit %rm
+    %f1 = COPY %13
+    BLR8 implicit %lr8, implicit %rm, implicit %f1
+
+...
+---
+name:            testLFSUX
+# CHECK-ALL: name: testLFSUX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: f8rc, preferred-register: '' }
+  - { id: 4, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 5, class: f8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: gprc, preferred-register: '' }
+  - { id: 8, class: f8rc, preferred-register: '' }
+  - { id: 9, class: f8rc, preferred-register: '' }
+  - { id: 10, class: f8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: gprc, preferred-register: '' }
+  - { id: 13, class: f8rc, preferred-register: '' }
+  - { id: 14, class: f8rc, preferred-register: '' }
+  - { id: 15, class: f8rc, preferred-register: '' }
+  - { id: 16, class: g8rc, preferred-register: '' }
+  - { id: 17, class: gprc, preferred-register: '' }
+  - { id: 18, class: f8rc, preferred-register: '' }
+  - { id: 19, class: f8rc, preferred-register: '' }
+  - { id: 20, class: f8rc, preferred-register: '' }
+  - { id: 21, class: g8rc, preferred-register: '' }
+  - { id: 22, class: gprc, preferred-register: '' }
+  - { id: 23, class: g8rc, preferred-register: '' }
+  - { id: 24, class: vrrc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    16
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+  - { id: 0, name: '', type: default, offset: 0, size: 16, alignment: 16, 
+      stack-id: 0, callee-saved-register: '', callee-saved-restored: true, 
+      local-offset: -16, di-variable: '', di-expression: '', di-location: '' }
+  - { id: 1, name: '', type: default, offset: 0, size: 4, alignment: 4, 
+      stack-id: 0, callee-saved-register: '', callee-saved-restored: true, 
+      local-offset: -20, di-variable: '', di-expression: '', di-location: '' }
+  - { id: 2, name: '', type: default, offset: 0, size: 4, alignment: 4, 
+      stack-id: 0, callee-saved-register: '', callee-saved-restored: true, 
+      local-offset: -24, di-variable: '', di-expression: '', di-location: '' }
+  - { id: 3, name: '', type: default, offset: 0, size: 4, alignment: 4, 
+      stack-id: 0, callee-saved-register: '', callee-saved-restored: true, 
+      local-offset: -28, di-variable: '', di-expression: '', di-location: '' }
+  - { id: 4, name: '', type: default, offset: 0, size: 4, alignment: 4, 
+      stack-id: 0, callee-saved-register: '', callee-saved-restored: true, 
+      local-offset: -32, di-variable: '', di-expression: '', di-location: '' }
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = LI8 72
+    %3, %4 = LFSUX %0, killed %2 :: (load 4 from %ir.arrayidx, !tbaa !14)
+    ; CHECK: LFSU 72, %0
+    ; CHECK-LATE: lfsu 0, 72(3)
+    %5 = FCTIWUZ killed %3, implicit %rm
+    %6 = ADDI8 %stack.4, 0
+    STFIWX killed %5, %zero8, killed %6
+    %7 = LWZ 0, %stack.4 :: (load 4 from %stack.4)
+    %8 = LFS 4, %4 :: (load 4 from %ir.3, !tbaa !14)
+    %10 = FCTIWUZ %8, implicit %rm
+    %11 = ADDI8 %stack.1, 0
+    STFIWX killed %10, %zero8, killed %11
+    %12 = LWZ 0, %stack.1 :: (load 4 from %stack.1)
+    %13 = LFS 8, %4 :: (load 4 from %ir.5, !tbaa !14)
+    %15 = FCTIWUZ %13, implicit %rm
+    %16 = ADDI8 %stack.2, 0
+    STFIWX killed %15, %zero8, killed %16
+    %17 = LWZ 0, %stack.2 :: (load 4 from %stack.2)
+    %18 = LFS 12, %4 :: (load 4 from %ir.7, !tbaa !14)
+    %20 = FCTIWUZ %18, implicit %rm
+    %21 = ADDI8 %stack.3, 0
+    STFIWX killed %20, %zero8, killed %21
+    %22 = LWZ 0, %stack.3 :: (load 4 from %stack.3)
+    STW killed %7, 0, %stack.0 :: (store 4 into %stack.0, align 16)
+    STW killed %22, 12, %stack.0 :: (store 4 into %stack.0 + 12)
+    STW killed %17, 8, %stack.0 :: (store 4 into %stack.0 + 8, align 8)
+    STW killed %12, 4, %stack.0 :: (store 4 into %stack.0 + 4)
+    %23 = ADDI8 %stack.0, 0
+    %24 = LVX %zero8, killed %23 :: (load 16 from %stack.0)
+    %v2 = COPY %24
+    BLR8 implicit %lr8, implicit %rm, implicit %v2
+
+...
+---
+name:            testLFSX
+# CHECK-ALL: name: testLFSX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: f4rc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: f4rc, preferred-register: '' }
+  - { id: 13, class: f4rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = COPY %1.sub_32
+    %3 = ADDI %2, 1
+    %5 = IMPLICIT_DEF
+    %4 = INSERT_SUBREG %5, killed %3, 1
+    %6 = LI8 88
+    %7 = LFSX %0, killed %6 :: (load 4 from %ir.arrayidx, !tbaa !14)
+    ; CHECK: LFS 88, %0
+    ; CHECK-LATE: lfs 0, 88(3)
+    %8 = ADDI %2, 2
+    %10 = IMPLICIT_DEF
+    %9 = INSERT_SUBREG %10, killed %8, 1
+    %11 = LI8 -88
+    %12 = LFSX %0, killed %11 :: (load 4 from %ir.arrayidx3, !tbaa !14)
+    ; CHECK: LFS -88, %0
+    ; CHECK-LATE: lfs 1, -88(3)
+    %13 = FADDS killed %7, killed %12, implicit %rm
+    %f1 = COPY %13
+    BLR8 implicit %lr8, implicit %rm, implicit %f1
+
+...
+---
+name:            testLXSDX
+# CHECK-ALL: name: testLXSDX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: vsfrc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: vsfrc, preferred-register: '' }
+  - { id: 13, class: vsfrc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = COPY %1.sub_32
+    %3 = ADDI %2, 1
+    %5 = IMPLICIT_DEF
+    %4 = INSERT_SUBREG %5, killed %3, 1
+    %6 = LI8 100
+    %7 = LXSDX %0, killed %6, implicit %rm :: (load 8 from %ir.arrayidx, !tbaa !12)
+    ; CHECK: LXSD 100, %0
+    ; CHECK-LATE: lxsd 0, 100(3)
+    %8 = ADDI %2, 2
+    %10 = IMPLICIT_DEF
+    %9 = INSERT_SUBREG %10, killed %8, 1
+    %11 = LI8 -120
+    %12 = LXSDX %0, killed %11, implicit %rm :: (load 8 from %ir.arrayidx3, !tbaa !12)
+    ; CHECK: LXSD -120, %0
+    ; CHECK-LATE: lxsd 1, -120(3)
+    %13 = XSADDDP killed %7, killed %12, implicit %rm
+    %f1 = COPY %13
+    BLR8 implicit %lr8, implicit %rm, implicit %f1
+
+...
+---
+name:            testLXSSPX
+# CHECK-ALL: name: testLXSSPX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: vssrc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: vssrc, preferred-register: '' }
+  - { id: 13, class: vssrc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = COPY %1.sub_32
+    %3 = ADDI %2, 1
+    %5 = IMPLICIT_DEF
+    %4 = INSERT_SUBREG %5, killed %3, 1
+    %6 = LI8 96
+    %7 = LXSSPX %0, killed %6 :: (load 4 from %ir.arrayidx, !tbaa !14)
+    ; CHECK: LXSSP 96, %0
+    ; CHECK-LATE: lxssp 0, 96(3)
+    %8 = ADDI %2, 2
+    %10 = IMPLICIT_DEF
+    %9 = INSERT_SUBREG %10, killed %8, 1
+    %11 = LI8 -92
+    %12 = LXSSPX %0, killed %11 :: (load 4 from %ir.arrayidx3, !tbaa !14)
+    ; CHECK: LXSSP -92, %0
+    ; CHECK-LATE: lxssp 1, -92(3)
+    %13 = XSADDSP killed %7, killed %12
+    %f1 = COPY %13
+    BLR8 implicit %lr8, implicit %rm, implicit %f1
+
+...
+---
+name:            testLXVX
+# CHECK-ALL: name: testLXVX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: vrrc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: vrrc, preferred-register: '' }
+  - { id: 13, class: vrrc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = COPY %1.sub_32
+    %3 = ADDI %2, 1
+    %5 = IMPLICIT_DEF
+    %4 = INSERT_SUBREG %5, killed %3, 1
+    %6 = LI8 32
+    %7 = LXVX %0, killed %6 :: (load 16 from %ir.arrayidx, !tbaa !3)
+    ; CHECK: LXV 32, %0
+    ; CHECK-LATE: lxv 34, 32(3)
+    %8 = ADDI %2, 2
+    %10 = IMPLICIT_DEF
+    %9 = INSERT_SUBREG %10, killed %8, 1
+    %11 = LI8 -16
+    %12 = LXVX %0, killed %11 :: (load 16 from %ir.arrayidx3, !tbaa !3)
+    ; CHECK: LXV -16, %0
+    ; CHECK-LATE: lxv 35, -16(3)
+    %13 = VADDUWM killed %12, killed %7
+    %v2 = COPY %13
+    BLR8 implicit %lr8, implicit %rm, implicit %v2
+
+...
+---
+name:            testOR
+# CHECK-ALL: name: testOR
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: gprc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = LI 99
+    %3 = COPY %1.sub_32
+    %2 = OR %0, %3
+    ; CHECK: ORI %3, 99
+    ; CHECK-LATE: ori 3, 4, 99
+    %x3 = EXTSW_32_64 %2
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testOR8
+# CHECK-ALL: name: testOR8
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = LI8 777
+    %2 = OR8 %1, %0
+    ; CHECK: ORI8 %1, 777
+    ; CHECK-LATE: ori 3, 4, 777
+    %x3 = COPY %2
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testORI
+# CHECK-ALL: name: testORI
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: gprc, preferred-register: '' }
+  - { id: 1, class: gprc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3
+  
+    %0 = LI 777
+    %1 = ORI %0, 88
+    ; CHECK: LI 857
+    ; CHECK-LATE: li 3, 857
+    %x3 = EXTSW_32_64 %1
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testORI8
+# CHECK-ALL: name: testORI8
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3
+  
+    %0 = LI8 8721
+    %1 = ORI8 %0, 99
+    ; CHECK: LI8 8819
+    ; CHECK-LATE: li 3, 8819
+    %x3 = COPY %1
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testRLDCL
+# CHECK-ALL: name: testRLDCL
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = COPY %1.sub_32
+    %3 = LI 14
+    %4 = RLDCL %0, killed %3, 0
+    ; CHECK: RLDICL %0, 14, 0
+    ; CHECK-LATE: rotldi 3, 3, 14
+    %x3 = COPY %4
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testRLDCLo
+# CHECK-ALL: name: testRLDCLo
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: crrc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = RLDICL %1, 0, 58
+    %3 = LI 37
+    %4 = RLDCLo %0, killed %3, 0, implicit-def %cr0
+    ; CHECK: RLDICLo %0, 37, 0, implicit-def %cr0
+    ; CHECK-LATE: rldicl. 5, 3, 37, 0
+    %5 = COPY killed %cr0
+    %6 = ISEL8 %2, %0, %5.sub_eq
+    %x3 = COPY %6
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testRLDCR
+# CHECK-ALL: name: testRLDCR
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = COPY %1.sub_32
+    %3 = LI 0
+    %4 = RLDCR %0, killed %3, 0
+    ; CHECK: RLDICR %0, 0, 0
+    ; CHECK-LATE: rldicr 3, 3, 0, 0
+    %x3 = COPY %4
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testRLDCRo
+# CHECK-ALL: name: testRLDCRo
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: crrc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = RLDICL %1, 0, 58
+    %3 = LI 18
+    %4 = RLDCRo %0, killed %3, 0, implicit-def %cr0
+    ; CHECK: RLDICRo %0, 18, 0, implicit-def %cr0
+    ; CHECK-LATE: rldicr. 5, 3, 18, 0
+    %5 = COPY killed %cr0
+    %6 = ISEL8 %2, %0, %5.sub_eq
+    %x3 = COPY %6
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testRLDICL
+# CHECK-ALL: name: testRLDICL
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3
+  
+    %0 = LI8 -1
+    %1 = RLDICL %0, 53, 49
+    ; CHECK: LI8 32767
+    ; CHECK-LATE: li 3, 32767
+    %x3 = COPY %1
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testRLDICLo
+# CHECK-ALL: name: testRLDICLo
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 2, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 3, class: crrc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = LI8 -1
+    %2 = RLDICLo %0, 53, 48, implicit-def %cr0
+    ; CHECK: ANDIo8 %0, 65535
+    ; CHECK-LATE: li 3, -1
+    ; CHECK-LATE: andi. 3, 3, 65535
+    %3 = COPY killed %cr0
+    %4 = ISEL8 %1, %2, %3.sub_eq
+    %x3 = COPY %4
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testRLWINM
+# CHECK-ALL: name: testRLWINM
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: gprc, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: g8rc, preferred-register: '' }
+  - { id: 4, class: gprc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3
+  
+    %0 = COPY %x3
+    %1 = COPY %0.sub_32
+    %3 = IMPLICIT_DEF
+    %2 = LI 17
+    %4 = RLWINM killed %2, 4, 20, 27
+    ; CHECK: LI 272
+    ; CHECK-LATE: li 3, 272
+    %x3 = EXTSW_32_64 %4
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testRLWINM8
+# CHECK-ALL: name: testRLWINM8
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3
+  
+    %0 = LI8 234
+    %1 = RLWINM8 %0, 4, 20, 27
+    ; CHECK: LI8 3744
+    ; CHECK-LATE: li 3, 3744
+    %x3 = COPY %1
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testRLWINMo
+# CHECK-ALL: name: testRLWINMo
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 4, class: gprc, preferred-register: '' }
+  - { id: 5, class: crrc, preferred-register: '' }
+  - { id: 6, class: gprc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+  - { id: 8, class: g8rc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = COPY %1.sub_32
+    %3 = LI -22
+    %4 = RLWINMo %3, 0, 24, 31, implicit-def %cr0
+    ; CHECK: ANDIo %3, 234
+    ; CHECK-LATE: li 3, -22
+    ; CHECK-LATE: andi. 5, 3, 234
+    %5 = COPY killed %cr0
+    %6 = ISEL %2, %3, %5.sub_eq
+    %8 = IMPLICIT_DEF
+    %7 = INSERT_SUBREG %8, killed %6, 1
+    %9 = RLDICL killed %7, 0, 32
+    %x3 = COPY %9
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testRLWINM8o
+# CHECK-ALL: name: testRLWINM8o
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: g8rc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 7, class: crrc, preferred-register: '' }
+  - { id: 8, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = LI8 -18
+    %3 = RLWINM8o %2, 4, 20, 27, implicit-def %cr0
+    ; CHECK: ANDIo8 %2, 3808
+    ; CHECK-LATE: li 3, -18
+    ; CHECK-LATE: andi. 3, 3, 3808
+    %7 = COPY killed %cr0
+    %6 = RLDICL killed %3, 0, 32
+    %8 = ISEL8 %1, %6, %7.sub_eq
+    %x3 = COPY %8
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testSLD
+# CHECK-ALL: name: testSLD
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = LI 13
+    %3 = SLD %0, killed %2
+    ; CHECK: RLDICR %0, 13, 50
+    ; CHECK-LATE: sldi 3, 3, 13
+    %x3 = COPY %3
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testSLDo
+# CHECK-ALL: name: testSLDo
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: g8rc, preferred-register: '' }
+  - { id: 4, class: crrc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = LI 17
+    %3 = SLDo %0, killed %2, implicit-def %cr0
+    ; CHECK: RLDICRo %0, 17, 46, implicit-def %cr0
+    ; CHECK-LATE: rldicr. 5, 3, 17, 46
+    %4 = COPY killed %cr0
+    %5 = ISEL8 %1, %0, %4.sub_eq
+    %x3 = COPY %5
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testSRD
+# CHECK-ALL: name: testSRD
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = LI 4
+    %3 = SRD %0, killed %2
+    ; CHECK: RLDICL %0, 60, 4
+    ; CHECK-LATE: rldicl 3, 3, 60, 4
+    %x3 = COPY %3
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testSRDo
+# CHECK-ALL: name: testSRDo
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: g8rc, preferred-register: '' }
+  - { id: 4, class: crrc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = LI 17
+    %3 = SRDo %0, killed %2, implicit-def %cr0
+    ; CHECK: RLDICLo %0, 47, 17, implicit-def %cr0
+    ; CHECK-LATE: rldicl. 5, 3, 47, 17
+    %4 = COPY killed %cr0
+    %5 = ISEL8 %1, %0, %4.sub_eq
+    %x3 = COPY %5
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testSLW
+# CHECK-ALL: name: testSLW
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: g8rc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: gprc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = COPY %1.sub_32
+    %5 = LI 21
+    %8 = SLW killed %2, killed %5
+    ; CHECK: RLWINM killed %2, 21, 0, 10
+    ; CHECK-LATE: slwi 3, 4, 21
+    %x3 = EXTSW_32_64 %8
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testSLWo
+# CHECK-ALL: name: testSLWo
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 4, class: gprc, preferred-register: '' }
+  - { id: 5, class: crrc, preferred-register: '' }
+  - { id: 6, class: gprc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+  - { id: 8, class: g8rc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = LI 11
+    %3 = COPY %0.sub_32
+    %4 = SLWo %3, %2, implicit-def %cr0
+    ; CHECK: RLWINMo %3, 11, 0, 20, implicit-def %cr0
+    ; CHECK-LATE: rlwinm. 5, 3, 11, 0, 20
+    %5 = COPY killed %cr0
+    %6 = ISEL %2, %3, %5.sub_eq
+    %8 = IMPLICIT_DEF
+    %7 = INSERT_SUBREG %8, killed %6, 1
+    %9 = RLDICL killed %7, 0, 32
+    %x3 = COPY %9
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testSRW
+# CHECK-ALL: name: testSRW
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: g8rc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: gprc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = LI 8
+    %5 = COPY %0.sub_32
+    %8 = SRW killed %5, killed %2
+    ; CHECK: RLWINM killed %5, 24, 8, 31
+    ; CHECK-LATE: srwi 3, 3, 8
+    %x3 = EXTSW_32_64 %8
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testSRWo
+# CHECK-ALL: name: testSRWo
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 4, class: gprc, preferred-register: '' }
+  - { id: 5, class: crrc, preferred-register: '' }
+  - { id: 6, class: gprc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+  - { id: 8, class: g8rc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = LI 7
+    %3 = COPY %0.sub_32
+    %4 = SRWo %3, %2, implicit-def %cr0
+    ; CHECK: RLWINMo %3, 25, 7, 31
+    ; CHECK-LATE: rlwinm. 5, 3, 25, 7, 31
+    %5 = COPY killed %cr0
+    %6 = ISEL %2, %3, %5.sub_eq
+    %8 = IMPLICIT_DEF
+    %7 = INSERT_SUBREG %8, killed %6, 1
+    %9 = RLDICL killed %7, 0, 32
+    %x3 = COPY %9
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testSRAW
+# CHECK-ALL: name: testSRAW
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: gprc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = LI 15
+    %3 = COPY %0.sub_32
+    %4 = SRAW killed %3, killed %2, implicit-def dead %carry
+    ; CHECK: SRAWI killed %3, 15, implicit-def dead %carry
+    ; CHECK-LATE: srawi 3, 3, 15
+    %5 = EXTSW_32_64 killed %4
+    %x3 = COPY %5
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testSRAWo
+# CHECK-ALL: name: testSRAWo
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 5, class: crrc, preferred-register: '' }
+  - { id: 6, class: gprc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = LI 8
+    %3 = COPY %0.sub_32
+    %4 = SRAWo killed %3, %2, implicit-def dead %carry, implicit-def %cr0
+    ; CHECK: SRAWIo killed %3, 8, implicit-def dead %carry, implicit-def %cr0
+    ; CHECK-LATE: srawi. 3, 3, 8
+    %5 = COPY killed %cr0
+    %6 = ISEL %2, %4, %5.sub_eq
+    %7 = EXTSW_32_64 killed %6
+    %x3 = COPY %7
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testSRAD
+# CHECK-ALL: name: testSRAD
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = LI 44
+    %3 = SRAD %0, killed %2, implicit-def dead %carry
+    ; CHECK: SRADI %0, 44, implicit-def dead %carry
+    ; CHECK-LATE: sradi 3, 3, 44
+    %x3 = COPY %3
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testSRADo
+# CHECK-ALL: name: testSRADo
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 4, class: crrc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %2 = LI 61
+    %3 = SRADo %0, killed %2, implicit-def dead %carry, implicit-def %cr0
+    ; CHECK: SRADIo %0, 61, implicit-def dead %carry, implicit-def %cr0
+    ; CHECK-LATE: sradi. 3, 3, 61
+    %4 = COPY killed %cr0
+    %5 = ISEL8 %1, %3, %4.sub_eq
+    %x3 = COPY %5
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testSTBUX
+# CHECK-ALL: name: testSTBUX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 5, class: gprc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+  - { id: 8, class: g8rc, preferred-register: '' }
+  - { id: 9, class: gprc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: g8rc, preferred-register: '' }
+  - { id: 13, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 14, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+  - { reg: '%x5', virtual-reg: '%2' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4, %x5
+  
+    %2 = COPY %x5
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %3 = COPY %1.sub_32
+    %4 = COPY %2.sub_32
+    %5 = ADDI %4, 1
+    %7 = IMPLICIT_DEF
+    %6 = INSERT_SUBREG %7, killed %5, 1
+    %8 = LI8 966
+    %13 = STBUX %3, %0, killed %8 :: (store 1 into %ir.arrayidx, !tbaa !3)
+    ; CHECK: STBU %3, 966, %0
+    ; CHECK-LATE: 4, 966(5)
+    %9 = ADDI %4, 2
+    %11 = IMPLICIT_DEF
+    %10 = INSERT_SUBREG %11, killed %9, 1
+    %12 = LI8 777
+    %14 = STBUX %3, %0, killed %12 :: (store 1 into %ir.arrayidx3, !tbaa !3)
+    ; CHECK: STBU %3, 777, %0
+    ; CHECK-LATE: 4, 777(3)
+    BLR8 implicit %lr8, implicit %rm
+
+...
+---
+name:            testSTBX
+# CHECK-ALL: name: testSTBX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 5, class: gprc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+  - { id: 8, class: g8rc, preferred-register: '' }
+  - { id: 9, class: gprc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+  - { reg: '%x5', virtual-reg: '%2' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4, %x5
+  
+    %2 = COPY %x5
+    %1 = COPY %x4
+    %0 = LI8 975
+    %3 = COPY %1.sub_32
+    %4 = COPY %2.sub_32
+    %5 = ADDI %4, 1
+    %7 = IMPLICIT_DEF
+    %6 = INSERT_SUBREG %7, killed %5, 1
+    %8 = RLDICL killed %6, 0, 32
+    STBX %3, %0, killed %8 :: (store 1 into %ir.arrayidx, !tbaa !3)
+    ; CHECK: STB %3, 975, killed %8
+    ; CHECK-LATE: stb 4, 975(6)
+    %9 = ADDI %4, 2
+    %11 = IMPLICIT_DEF
+    %10 = INSERT_SUBREG %11, killed %9, 1
+    %12 = RLDICL killed %10, 0, 32
+    STBX %3, %0, killed %12 :: (store 1 into %ir.arrayidx3, !tbaa !3)
+    ; CHECK: STB %3, 975, killed %12
+    ; CHECK-LATE: stb 4, 975(5)
+    BLR8 implicit %lr8, implicit %rm
+
+...
+---
+name:            testSTHUX
+# CHECK-ALL: name: testSTHUX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 5, class: gprc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+  - { id: 8, class: g8rc, preferred-register: '' }
+  - { id: 9, class: gprc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: g8rc, preferred-register: '' }
+  - { id: 13, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 14, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+  - { reg: '%x5', virtual-reg: '%2' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4, %x5
+  
+    %2 = COPY %x5
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %3 = COPY %1.sub_32
+    %4 = COPY %2.sub_32
+    %5 = ADDI %4, 1
+    %7 = IMPLICIT_DEF
+    %6 = INSERT_SUBREG %7, killed %5, 1
+    %8 = LI8 32000
+    %13 = STHUX %3, %0, killed %8 :: (store 2 into %ir.arrayidx, !tbaa !6)
+    ; CHECK: STHU %3, 32000, %0
+    ; CHECK-LATE: sthu 4, 32000(5)
+    %9 = ADDI %4, 2
+    %11 = IMPLICIT_DEF
+    %10 = INSERT_SUBREG %11, killed %9, 1
+    %12 = LI8 -761
+    %14 = STHUX %3, %0, killed %12 :: (store 2 into %ir.arrayidx3, !tbaa !6)
+    ; CHECK: STHU %3, -761, %0
+    ; CHECK-LATE: sthu 4, -761(3)
+    BLR8 implicit %lr8, implicit %rm
+
+...
+---
+name:            testSTHX
+# CHECK-ALL: name: testSTHX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 5, class: gprc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+  - { id: 8, class: g8rc, preferred-register: '' }
+  - { id: 9, class: gprc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+  - { reg: '%x5', virtual-reg: '%2' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4, %x5
+  
+    %2 = COPY %x5
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %3 = COPY %1.sub_32
+    %4 = COPY %2.sub_32
+    %5 = ADDI %4, 1
+    %7 = IMPLICIT_DEF
+    %6 = INSERT_SUBREG %7, killed %5, 1
+    %8 = LI8 900
+    STHX %3, %0, killed %8 :: (store 1 into %ir.arrayidx, !tbaa !3)
+    ; CHECK: STH %3, 900, %0
+    ; CHECK-LATE: sth 4, 900(3)
+    %9 = ADDI %4, 2
+    %11 = IMPLICIT_DEF
+    %10 = INSERT_SUBREG %11, killed %9, 1
+    %12 = LI8 -900
+    STHX %3, %0, killed %12 :: (store 1 into %ir.arrayidx3, !tbaa !3)
+    ; CHECK: STH %3, -900, %0
+    ; CHECK-LATE: sth 4, -900(3)
+    BLR8 implicit %lr8, implicit %rm
+
+...
+---
+name:            testSTWUX
+# CHECK-ALL: name: testSTWUX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 5, class: gprc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+  - { id: 8, class: g8rc, preferred-register: '' }
+  - { id: 9, class: gprc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: g8rc, preferred-register: '' }
+  - { id: 13, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 14, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+  - { reg: '%x5', virtual-reg: '%2' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4, %x5
+  
+    %2 = COPY %x5
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %3 = COPY %1.sub_32
+    %4 = COPY %2.sub_32
+    %5 = ADDI %4, 1
+    %7 = IMPLICIT_DEF
+    %6 = INSERT_SUBREG %7, killed %5, 1
+    %8 = LI8 111
+    %13 = STWUX %3, %0, killed %8 :: (store 4 into %ir.arrayidx, !tbaa !8)
+    ; CHECK: STWU %3, 111, %0
+    ; CHECK-LATE: stwu 4, 111(5)
+    %9 = ADDI %4, 2
+    %11 = IMPLICIT_DEF
+    %10 = INSERT_SUBREG %11, killed %9, 1
+    %12 = LI8 0
+    %14 = STWUX %3, %0, killed %12 :: (store 4 into %ir.arrayidx3, !tbaa !8)
+    ; CHECK: STWU %3, 0, %0
+    ; CHECK-LATE: stwu 4, 0(3)
+    BLR8 implicit %lr8, implicit %rm
+
+...
+---
+name:            testSTWX
+# CHECK-ALL: name: testSTWX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 5, class: gprc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+  - { id: 8, class: g8rc, preferred-register: '' }
+  - { id: 9, class: gprc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+  - { reg: '%x5', virtual-reg: '%2' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4, %x5
+  
+    %2 = COPY %x5
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %3 = COPY %1.sub_32
+    %4 = COPY %2.sub_32
+    %5 = ADDI %4, 1
+    %7 = IMPLICIT_DEF
+    %6 = INSERT_SUBREG %7, killed %5, 1
+    %8 = LI8 2
+    STWX %3, %0, killed %8 :: (store 4 into %ir.arrayidx, !tbaa !8)
+    ; CHECK: STW %3, 2, %0
+    ; CHECK-LATE: stw 4, 2(3)
+    %9 = ADDI %4, 2
+    %11 = IMPLICIT_DEF
+    %10 = INSERT_SUBREG %11, killed %9, 1
+    %12 = LI8 99
+    STWX %3, %0, killed %12 :: (store 4 into %ir.arrayidx3, !tbaa !8)
+    ; CHECK: STW %3, 99, %0
+    ; CHECK-LATE: stw 4, 99(3)
+    BLR8 implicit %lr8, implicit %rm
+
+...
+---
+name:            testSTDUX
+# CHECK-ALL: name: testSTDUX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 4, class: gprc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 13, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+  - { reg: '%x5', virtual-reg: '%2' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4, %x5
+  
+    %2 = COPY %x5
+    %1 = COPY %x4
+    %0 = COPY %x3
+    %3 = COPY %2.sub_32
+    %4 = ADDI %3, 1
+    %6 = IMPLICIT_DEF
+    %5 = INSERT_SUBREG %6, killed %4, 1
+    %7 = LI8 444
+    %12 = STDUX %1, %0, killed %7 :: (store 8 into %ir.arrayidx, !tbaa !10)
+    ; CHECK: STDU %1, 444, %0
+    ; CHECK-LATE: stdu 4, 444(5)
+    %8 = ADDI %3, 2
+    %10 = IMPLICIT_DEF
+    %9 = INSERT_SUBREG %10, killed %8, 1
+    %11 = LI8 -8
+    %13 = STDUX %1, %0, killed %11 :: (store 8 into %ir.arrayidx3, !tbaa !10)
+    ; CHECK: STDU %1, -8, %0
+    ; CHECK-LATE: stdu 4, -8(3)
+    BLR8 implicit %lr8, implicit %rm
+
+...
+---
+name:            testSTDX
+# CHECK-ALL: name: testSTDX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 4, class: gprc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+  - { reg: '%x5', virtual-reg: '%2' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4, %x5
+  
+    %2 = COPY %x5
+    %1 = COPY %x4
+    %0 = LI8 1000
+    %3 = COPY %2.sub_32
+    %4 = ADDI %3, 1
+    %6 = IMPLICIT_DEF
+    %5 = INSERT_SUBREG %6, killed %4, 1
+    %7 = LI8 900
+    STDX %1, %0, killed %7 :: (store 8 into %ir.arrayidx, !tbaa !10)
+    ; CHECK: STD %1, 1000, killed %7
+    ; CHECK-LATE: 4, 1000(5)
+    %8 = ADDI %3, 2
+    %10 = IMPLICIT_DEF
+    %9 = INSERT_SUBREG %10, killed %8, 1
+    %11 = LI8 -900
+    STDX %1, %0, killed %11 :: (store 8 into %ir.arrayidx3, !tbaa !10)
+    ; CHECK: STD %1, 1000, killed %11
+    ; CHECK-LATE: 4, 1000(6)
+    BLR8 implicit %lr8, implicit %rm
+
+...
+---
+name:            testSTFSX
+# CHECK-ALL: name: testSTFSX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: f4rc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 4, class: gprc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%f1', virtual-reg: '%1' }
+  - { reg: '%x5', virtual-reg: '%2' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %f1, %x5
+  
+    %2 = COPY %x5
+    %1 = COPY %f1
+    %0 = COPY %x3
+    %3 = COPY %2.sub_32
+    %4 = ADDI %3, 1
+    %6 = IMPLICIT_DEF
+    %5 = INSERT_SUBREG %6, killed %4, 1
+    %7 = LI8 400
+    STFSX %1, %0, killed %7 :: (store 4 into %ir.arrayidx, !tbaa !14)
+    ; CHECK: STFS %1, 400, %0
+    ; CHECK-LATE: stfs 1, 400(3)
+    %8 = ADDI %3, 2
+    %10 = IMPLICIT_DEF
+    %9 = INSERT_SUBREG %10, killed %8, 1
+    %11 = LI8 -401
+    STFSX %1, %0, killed %11 :: (store 4 into %ir.arrayidx3, !tbaa !14)
+    ; CHECK: STFS %1, -401, %0
+    ; CHECK-LATE: stfs 1, -401(3)
+    BLR8 implicit %lr8, implicit %rm
+
+...
+---
+name:            testSTFSUX
+# CHECK-ALL: name: testSTFSUX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: f4rc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 4, class: gprc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 13, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%f1', virtual-reg: '%1' }
+  - { reg: '%x5', virtual-reg: '%2' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %f1, %x5
+  
+    %2 = COPY %x5
+    %1 = COPY %f1
+    %0 = COPY %x3
+    %3 = COPY %2.sub_32
+    %4 = ADDI %3, 1
+    %6 = IMPLICIT_DEF
+    %5 = INSERT_SUBREG %6, killed %4, 1
+    %7 = LI8 111
+    %12 = STFSUX %1, %0, killed %7 :: (store 4 into %ir.arrayidx, !tbaa !14)
+    ; CHECK: STFSU %1, 111, %0
+    ; CHECK-LATE: stfsu 1, 111(4)
+    %8 = ADDI %3, 2
+    %10 = IMPLICIT_DEF
+    %9 = INSERT_SUBREG %10, killed %8, 1
+    %11 = LI8 987
+    %13 = STFSUX %1, %0, killed %11 :: (store 4 into %ir.arrayidx3, !tbaa !14)
+    ; CHECK: STFSU %1, 987, %0
+    ; CHECK-LATE: stfsu 1, 987(3)
+    BLR8 implicit %lr8, implicit %rm
+
+...
+---
+name:            testSTFDX
+# CHECK-ALL: name: testSTFDX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: f8rc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 4, class: gprc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%f1', virtual-reg: '%1' }
+  - { reg: '%x5', virtual-reg: '%2' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %f1, %x5
+  
+    %2 = COPY %x5
+    %1 = COPY %f1
+    %0 = COPY %x3
+    %3 = COPY %2.sub_32
+    %4 = ADDI %3, 1
+    %6 = IMPLICIT_DEF
+    %5 = INSERT_SUBREG %6, killed %4, 1
+    %7 = LI8 876
+    STFDX %1, %0, killed %7 :: (store 8 into %ir.arrayidx, !tbaa !12)
+    ; CHECK: STFD %1, 876, %0
+    ; CHECK-LATE: stfd 1, 876(3)
+    %8 = ADDI %3, 2
+    %10 = IMPLICIT_DEF
+    %9 = INSERT_SUBREG %10, killed %8, 1
+    %11 = LI8 -873
+    STFDX %1, %0, killed %11 :: (store 8 into %ir.arrayidx3, !tbaa !12)
+    ; CHECK: STFD %1, -873, %0
+    ; CHECK-LATE: stfd 1, -873(3)
+    BLR8 implicit %lr8, implicit %rm
+
+...
+---
+name:            testSTFDUX
+# CHECK-ALL: name: testSTFDUX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: f8rc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 4, class: gprc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+  - { id: 6, class: g8rc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+  - { id: 9, class: g8rc, preferred-register: '' }
+  - { id: 10, class: g8rc, preferred-register: '' }
+  - { id: 11, class: g8rc, preferred-register: '' }
+  - { id: 12, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 13, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%f1', virtual-reg: '%1' }
+  - { reg: '%x5', virtual-reg: '%2' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %f1, %x5
+  
+    %2 = COPY %x5
+    %1 = COPY %f1
+    %0 = COPY %x3
+    %3 = COPY %2.sub_32
+    %4 = ADDI %3, 1
+    %6 = IMPLICIT_DEF
+    %5 = INSERT_SUBREG %6, killed %4, 1
+    %7 = LI8 -9038
+    %12 = STFDUX %1, %0, killed %7 :: (store 8 into %ir.arrayidx, !tbaa !12)
+    ; CHECK: STFDU %1, -9038, %0
+    ; CHECK-LATE: stfdu 1, -9038(4)
+    %8 = ADDI %3, 2
+    %10 = IMPLICIT_DEF
+    %9 = INSERT_SUBREG %10, killed %8, 1
+    %11 = LI8 6477
+    %13 = STFDUX %1, %0, killed %11 :: (store 8 into %ir.arrayidx3, !tbaa !12)
+    ; CHECK: STFDU %1, 6477, %0
+    ; CHECK-LATE: stfdu 1, 6477(3)
+    BLR8 implicit %lr8, implicit %rm
+
+...
+---
+name:            testSTXSSPX
+# CHECK-ALL: name: testSTXSSPX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: vssrc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%f1', virtual-reg: '%1' }
+  - { reg: '%x5', virtual-reg: '%2' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %f1, %x5
+  
+    %2 = COPY %x5
+    %1 = COPY %f1
+    %0 = COPY %x3
+    %3 = LI8 444
+    STXSSPX %1, %0, killed %3 :: (store 4 into %ir.arrayidx, !tbaa !14)
+    ; CHECK: STXSSP %1, 444, %0
+    ; CHECK-LATE: stxssp 1, 444(3)
+    BLR8 implicit %lr8, implicit %rm
+
+...
+---
+name:            testSTXSDX
+# CHECK-ALL: name: testSTXSDX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: vsfrc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%f1', virtual-reg: '%1' }
+  - { reg: '%x5', virtual-reg: '%2' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %f1, %x5
+  
+    %2 = COPY %x5
+    %1 = COPY %f1
+    %0 = COPY %x3
+    %3 = LI8 4
+    STXSDX %1, %0, killed %3, implicit %rm :: (store 8 into %ir.arrayidx, !tbaa !12)
+    ; CHECK: STXSD %1, 4, %0
+    ; CHECK-LATE: stxsd 1, 4(3)
+    BLR8 implicit %lr8, implicit %rm
+
+...
+---
+name:            testSTXVX
+# CHECK-ALL: name: testSTXVX
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: vrrc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%v2', virtual-reg: '%1' }
+  - { reg: '%x7', virtual-reg: '%2' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %v2, %x7
+  
+    %2 = COPY %x7
+    %1 = COPY %v2
+    %0 = LI8 16
+    %3 = RLDICR %2, 4, 59
+    STXVX %1, %0, killed %3 :: (store 16 into %ir.arrayidx, !tbaa !3)
+    ; CHECK: STXV %1, 16, killed %3
+    ; CHECK-LATE: stxv 34, 16(4)
+    BLR8 implicit %lr8, implicit %rm
+
+...
+---
+name:            testSUBFC
+# CHECK-ALL: name: testSUBFC
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: gprc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: g8rc, preferred-register: '' }
+  - { id: 4, class: gprc, preferred-register: '' }
+  - { id: 5, class: gprc, preferred-register: '' }
+  - { id: 6, class: gprc, preferred-register: '' }
+  - { id: 7, class: gprc, preferred-register: '' }
+  - { id: 8, class: gprc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+  - { reg: '%x5', virtual-reg: '%2' }
+  - { reg: '%x6', virtual-reg: '%3' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4, %x5, %x6
+  
+    %3 = COPY %x6
+    %2 = COPY %x5
+    %1 = COPY %x4
+    %6 = COPY %3.sub_32
+    %7 = COPY %2.sub_32
+    %8 = COPY %1.sub_32
+    %0 = LI 55
+    %4 = SUBFC %7, %0, implicit-def %carry
+    ; CHECK: SUBFIC %7, 55
+    ; CHECK-LATE: subfic 3, 5, 55
+    %5 = SUBFE %6, %8, implicit-def dead %carry, implicit %carry
+    %x3 = EXTSW_32_64 %4
+    %x4 = EXTSW_32_64 %5
+    BLR8 implicit %lr8, implicit %rm, implicit %x3, implicit %x4
+
+...
+---
+name:            testSUBFC8
+# CHECK-ALL: name: testSUBFC8
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: g8rc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+  - { id: 5, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+  - { reg: '%x5', virtual-reg: '%2' }
+  - { reg: '%x6', virtual-reg: '%3' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4, %x5, %x6
+  
+    %3 = COPY %x6
+    %2 = COPY %x5
+    %1 = COPY %x4
+    %0 = LI8 7635
+    %4 = SUBFC8 %2, %0, implicit-def %carry
+    ; CHECK: SUBFIC8 %2, 7635
+    ; CHECK-LATE: subfic 3, 5, 7635
+    %5 = SUBFE8 %3, %1, implicit-def dead %carry, implicit %carry
+    %x3 = COPY %4
+    %x4 = COPY %5
+    BLR8 implicit %lr8, implicit %rm, implicit %x3, implicit %x4
+
+...
+---
+name:            testXOR
+# CHECK-ALL: name: testXOR
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: gprc, preferred-register: '' }
+  - { id: 2, class: gprc, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = LI 10101
+    %0 = COPY %x3
+    %3 = COPY %0.sub_32
+    %2 = XOR %1, %3
+    ; CHECK: XORI %3, 10101
+    ; CHECK-LATE: 3, 3, 10101
+    %x3 = EXTSW_32_64 %2
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testXOR8
+# CHECK-ALL: name: testXOR8
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+  - { reg: '%x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3, %x4
+  
+    %1 = COPY %x4
+    %0 = LI8 5535
+    %2 = XOR8 %1, %0
+    ; CHECK: XORI8 %1, 5535
+    ; CHECK-LATE: xori 3, 4, 5535
+    %x3 = COPY %2
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testXORI
+# CHECK-ALL: name: testXORI
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: gprc, preferred-register: '' }
+  - { id: 1, class: gprc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3
+  
+    %0 = LI 871
+    %1 = XORI %0, 17
+    ; CHECK: LI 886
+    ; CHECK-LATE: li 3, 886
+    %x3 = EXTSW_32_64 %1
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...
+---
+name:            testXOR8I
+# CHECK-ALL: name: testXOR8I
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '%x3', virtual-reg: '%0' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: %x3
+  
+    %0 = LI8 453
+    %1 = XORI8 %0, 17
+    ; CHECK: LI8 468
+    ; CHECK-LATE: li 3, 468
+    %x3 = COPY %1
+    BLR8 implicit %lr8, implicit %rm, implicit %x3
+
+...

Modified: llvm/trunk/test/CodeGen/PowerPC/fast-isel-call.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/fast-isel-call.ll?rev=320791&r1=320790&r2=320791&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/fast-isel-call.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/fast-isel-call.ll Thu Dec 14 23:27:53 2017
@@ -37,9 +37,13 @@ define void @foo(i8 %a, i16 %b) nounwind
 
 ;; A few test to check materialization
   %5 = call i32 @t2(i8 zeroext 255)
-; ELF64: clrldi {{[0-9]+}}, {{[0-9]+}}, 56
+; ELF64: li 3, 255
+; ELF64-NOT: clrldi
   %6 = call i32 @t4(i16 zeroext 65535)
-; ELF64: clrldi {{[0-9]+}}, {{[0-9]+}}, 48
+; ELF64: lis 3, 0
+; ELF64: ori 3, 3, 65535
+; ELF64: clrldi 3, 3, 48
+; ELF64: bl t4
   ret void
 }
 
@@ -66,12 +70,8 @@ entry:
 ; ELF64: li 6, 28
 ; ELF64: li 7, 40
 ; ELF64: li 8, 186
-; ELF64: clrldi 3, 3, 56
-; ELF64: clrldi 4, 4, 56
-; ELF64: clrldi 5, 5, 56
-; ELF64: clrldi 6, 6, 56
-; ELF64: clrldi 7, 7, 56
-; ELF64: clrldi 8, 8, 56
+; ELF64-NOT: clrldi
+; ELF64: bl bar
   ret i32 0
 }
 

Modified: llvm/trunk/test/CodeGen/PowerPC/setcc-logic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/setcc-logic.ll?rev=320791&r1=320790&r2=320791&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/setcc-logic.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/setcc-logic.ll Thu Dec 14 23:27:53 2017
@@ -418,9 +418,9 @@ define <4 x i1> @any_sign_bits_clear_vec
 define zeroext i1 @ne_neg1_and_ne_zero(i64 %x) {
 ; CHECK-LABEL: ne_neg1_and_ne_zero:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    li 4, 1
 ; CHECK-NEXT:    addi 3, 3, 1
-; CHECK-NEXT:    subfc 3, 3, 4
+; CHECK-NEXT:    li 4, 1
+; CHECK-NEXT:    subfic 3, 3, 1
 ; CHECK-NEXT:    subfe 3, 4, 4
 ; CHECK-NEXT:    neg 3, 3
 ; CHECK-NEXT:    blr

Added: llvm/trunk/test/CodeGen/PowerPC/simplifyConstCmpToISEL.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/simplifyConstCmpToISEL.ll?rev=320791&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/simplifyConstCmpToISEL.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/simplifyConstCmpToISEL.ll Thu Dec 14 23:27:53 2017
@@ -0,0 +1,51 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=powerpc64le-unknown-unknown -mcpu=pwr8 \
+; RUN:   -ppc-convert-rr-to-ri -verify-machineinstrs | FileCheck %s
+define void @test(i32 zeroext %parts) {
+; CHECK-LABEL: test:
+; CHECK:       # %bb.0: # %cond.end.i
+; CHECK-NEXT:    cmplwi 0, 3, 1
+; CHECK-NEXT:    bnelr+ 0
+; CHECK-NEXT:  # %bb.1: # %test2.exit.us.unr-lcssa
+; CHECK-NEXT:    ld 3, 0(3)
+; CHECK-NEXT:    std 3, 0(3)
+entry:
+  br label %cond.end.i
+
+cond.end.i:                                       ; preds = %entry
+  %cmp18.i = icmp eq i32 %parts, 1
+  br i1 %cmp18.i, label %while.body.lr.ph.i.us.preheader, label %test3.exit.split
+
+while.body.lr.ph.i.us.preheader:                  ; preds = %cond.end.i
+  %0 = icmp eq i32 %parts, 1
+  br label %for.body.i62.us.preheader
+
+for.body.i62.us.preheader:                        ; preds = %while.body.lr.ph.i.us.preheader
+  br i1 %0, label %test2.exit.us.unr-lcssa, label %for.body.i62.us.preheader.new
+
+for.body.i62.us.preheader.new:                    ; preds = %for.body.i62.us.preheader
+  br label %for.body.i62.us
+
+for.body.i62.us:                                  ; preds = %if.end.i.us.1, %for.body.i62.us.preheader.new
+  %niter = phi i64 [ undef, %for.body.i62.us.preheader.new ], [ %niter.nsub.1, %if.end.i.us.1 ]
+  %cmp8.i.us.1 = icmp uge i64 undef, 0
+  br label %if.end.i.us.1
+
+test2.exit.us.unr-lcssa: ; preds = %if.end.i.us.1, %for.body.i62.us.preheader
+  %c.addr.036.i.us.unr = phi i64 [ 0, %for.body.i62.us.preheader ], [ %c.addr.1.i.us.1, %if.end.i.us.1 ]
+  %1 = load i64, i64* undef, align 8
+  %tobool.i61.us.epil = icmp eq i64 %c.addr.036.i.us.unr, 0
+  %add.neg.i.us.epil.pn = select i1 %tobool.i61.us.epil, i64 %1, i64 0
+  %storemerge269 = sub i64 %add.neg.i.us.epil.pn, 0
+  store i64 %storemerge269, i64* undef, align 8
+  unreachable
+
+test3.exit.split:             ; preds = %cond.end.i
+  ret void
+
+if.end.i.us.1:                                    ; preds = %for.body.i62.us
+  %c.addr.1.i.us.1 = zext i1 %cmp8.i.us.1 to i64
+  %niter.nsub.1 = add i64 %niter, -2
+  %niter.ncmp.1 = icmp eq i64 %niter.nsub.1, 0
+  br i1 %niter.ncmp.1, label %test2.exit.us.unr-lcssa, label %for.body.i62.us
+}

Modified: llvm/trunk/test/CodeGen/PowerPC/unaligned.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/unaligned.ll?rev=320791&r1=320790&r2=320791&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/unaligned.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/unaligned.ll Thu Dec 14 23:27:53 2017
@@ -89,7 +89,7 @@ entry:
 ; CHECK: @foo6
 ; CHECK-DAG: ld
 ; CHECK-DAG: ld
-; CHECK-DAG: stdx
+; CHECK-DAG: std
 ; CHECK: stdx
 
 ; For VSX on P7, unaligned loads and stores are preferable to aligned

Modified: llvm/trunk/test/CodeGen/PowerPC/variable_elem_vec_extracts.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/variable_elem_vec_extracts.ll?rev=320791&r1=320790&r2=320791&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/variable_elem_vec_extracts.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/variable_elem_vec_extracts.ll Thu Dec 14 23:27:53 2017
@@ -70,9 +70,9 @@ entry:
 ; CHECK-LABEL: @getf
 ; CHECK-P7-LABEL: @getf
 ; CHECK-BE-LABEL: @getf
-; CHECK: li [[IMMREG:[0-9]+]], 3
-; CHECK: xor [[TRUNCREG:[0-9]+]], [[IMMREG]], 5
-; CHECK: lvsl [[SHMSKREG:[0-9]+]], 0, [[TRUNCREG]]
+; CHECK: xori [[TRUNCREG:[0-9]+]], 5, 3
+; CHECK: sldi [[SHIFTREG:[0-9]+]], [[TRUNCREG]], 2
+; CHECK: lvsl [[SHMSKREG:[0-9]+]], 0, [[SHIFTREG]]
 ; CHECK: vperm {{[0-9]+}}, 2, 2, [[SHMSKREG]]
 ; CHECK: xscvspdpn 1,
 ; CHECK-P7-DAG: rlwinm [[ELEMOFFREG:[0-9]+]], 5, 2, 28, 29




More information about the llvm-commits mailing list