<div dir="ltr"><div><div>Thanks Ben,<br></div>This was a silly oversight on my end. Thanks for disabling it for the time being. I'll post a fix for it ASAP.<br></div>Nemanja<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Dec 18, 2017 at 8:01 PM, Benjamin Kramer <span dir="ltr"><<a href="mailto:benny.kra@gmail.com" target="_blank">benny.kra@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This crashes the compiler in some edge cases, test case at<br>
<a href="https://bugs.llvm.org/show_bug.cgi?id=35688" rel="noreferrer" target="_blank">https://bugs.llvm.org/show_<wbr>bug.cgi?id=35688</a>.<br>
<br>
I turned the transform off for now in r321010<br>
<br>
On Fri, Dec 15, 2017 at 8:27 AM, Nemanja Ivanovic via llvm-commits<br>
<<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br>
> Author: nemanjai<br>
> Date: Thu Dec 14 23:27:53 2017<br>
> New Revision: 320791<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=320791&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=320791&view=rev</a><br>
> Log:<br>
> [PowerPC] Convert r+r instructions to r+i (pre and post RA)<br>
><br>
> This patch adds the necessary infrastructure to convert instructions that<br>
> take two register operands to those that take a register and immediate if<br>
> the necessary operand is produced by a load-immediate. Furthermore, it uses<br>
> this infrastructure to perform such conversions twice - first at MachineSSA<br>
> and then pre-emit.<br>
><br>
> There are a number of reasons we may end up with opportunities for this<br>
> transformation, including but not limited to:<br>
> - X-Form instructions chosen since the exact offset isn't available at ISEL time<br>
> - Atomic instructions with constant operands (we will add patterns for this<br>
>   in the future)<br>
> - Tail duplication may duplicate code where one block contains this redundancy<br>
> - When emitting compare-free code in PPCDAGToDAGISel, we don't handle constant<br>
>   comparands specially<br>
><br>
> Furthermore, this patch moves the initialization of PPCMIPeepholePass so that<br>
> it can be used for MIR tests.<br>
><br>
> Added:<br>
>     llvm/trunk/lib/Target/PowerPC/<wbr>PPCPreEmitPeephole.cpp<br>
>     llvm/trunk/test/CodeGen/<wbr>PowerPC/convert-rr-to-ri-<wbr>instrs-R0-special-handling.mir<br>
>     llvm/trunk/test/CodeGen/<wbr>PowerPC/convert-rr-to-ri-<wbr>instrs.mir<br>
>     llvm/trunk/test/CodeGen/<wbr>PowerPC/<wbr>simplifyConstCmpToISEL.ll<br>
> Modified:<br>
>     llvm/trunk/lib/Target/PowerPC/<wbr>CMakeLists.txt<br>
>     llvm/trunk/lib/Target/PowerPC/<wbr>PPC.h<br>
>     llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstr64Bit.td<br>
>     llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.cpp<br>
>     llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.h<br>
>     llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.td<br>
>     llvm/trunk/lib/Target/PowerPC/<wbr>PPCMIPeephole.cpp<br>
>     llvm/trunk/lib/Target/PowerPC/<wbr>PPCTargetMachine.cpp<br>
>     llvm/trunk/test/CodeGen/<wbr>PowerPC/build-vector-tests.ll<br>
>     llvm/trunk/test/CodeGen/<wbr>PowerPC/fast-isel-call.ll<br>
>     llvm/trunk/test/CodeGen/<wbr>PowerPC/setcc-logic.ll<br>
>     llvm/trunk/test/CodeGen/<wbr>PowerPC/unaligned.ll<br>
>     llvm/trunk/test/CodeGen/<wbr>PowerPC/variable_elem_vec_<wbr>extracts.ll<br>
><br>
> Modified: llvm/trunk/lib/Target/PowerPC/<wbr>CMakeLists.txt<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/CMakeLists.txt?rev=320791&r1=320790&r2=320791&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>PowerPC/CMakeLists.txt?rev=<wbr>320791&r1=320790&r2=320791&<wbr>view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Target/PowerPC/<wbr>CMakeLists.txt (original)<br>
> +++ llvm/trunk/lib/Target/PowerPC/<wbr>CMakeLists.txt Thu Dec 14 23:27:53 2017<br>
> @@ -43,6 +43,7 @@ add_llvm_target(PowerPCCodeGen<br>
>    PPCVSXFMAMutate.cpp<br>
>    PPCVSXSwapRemoval.cpp<br>
>    PPCExpandISEL.cpp<br>
> +  PPCPreEmitPeephole.cpp<br>
>    )<br>
><br>
>  add_subdirectory(AsmParser)<br>
><br>
> Modified: llvm/trunk/lib/Target/PowerPC/<wbr>PPC.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPC.h?rev=320791&r1=320790&r2=320791&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>PowerPC/PPC.h?rev=320791&r1=<wbr>320790&r2=320791&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Target/PowerPC/<wbr>PPC.h (original)<br>
> +++ llvm/trunk/lib/Target/PowerPC/<wbr>PPC.h Thu Dec 14 23:27:53 2017<br>
> @@ -50,6 +50,7 @@ namespace llvm {<br>
>    FunctionPass *createPPCTLSDynamicCallPass()<wbr>;<br>
>    FunctionPass *createPPCBoolRetToIntPass();<br>
>    FunctionPass *createPPCExpandISELPass();<br>
> +  FunctionPass *createPPCPreEmitPeepholePass(<wbr>);<br>
>    void LowerPPCMachineInstrToMCInst(<wbr>const MachineInstr *MI, MCInst &OutMI,<br>
>                                      AsmPrinter &AP, bool isDarwin);<br>
>    bool LowerPPCMachineOperandToMCOper<wbr>and(const MachineOperand &MO,<br>
> @@ -59,7 +60,9 @@ namespace llvm {<br>
>    void initializePPCVSXFMAMutatePass(<wbr>PassRegistry&);<br>
>    void initializePPCBoolRetToIntPass(<wbr>PassRegistry&);<br>
>    void initializePPCExpandISELPass(<wbr>PassRegistry &);<br>
> +  void initializePPCPreEmitPeepholePa<wbr>ss(PassRegistry &);<br>
>    void initializePPCTLSDynamicCallPas<wbr>s(PassRegistry &);<br>
> +  void initializePPCMIPeepholePass(<wbr>PassRegistry&);<br>
>    extern char &PPCVSXFMAMutateID;<br>
><br>
>    namespace PPCII {<br>
><br>
> Modified: llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstr64Bit.td<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td?rev=320791&r1=320790&r2=320791&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>PowerPC/PPCInstr64Bit.td?rev=<wbr>320791&r1=320790&r2=320791&<wbr>view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstr64Bit.td (original)<br>
> +++ llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstr64Bit.td Thu Dec 14 23:27:53 2017<br>
> @@ -194,6 +194,11 @@ def : Pat<(PPCcall_nop (i64 texternalsym<br>
>            (BL8_NOP texternalsym:$dst)>;<br>
><br>
>  // Atomic operations<br>
> +// FIXME: some of these might be used with constant operands. This will result<br>
> +// in constant materialization instructions that may be redundant. We currently<br>
> +// clean this up in PPCMIPeephole with calls to<br>
> +// PPCInstrInfo::<wbr>convertToImmediateForm() but we should probably not emit them<br>
> +// in the first place.<br>
>  let usesCustomInserter = 1 in {<br>
>    let Defs = [CR0] in {<br>
>      def ATOMIC_LOAD_ADD_I64 : Pseudo<<br>
><br>
> Modified: llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp?rev=320791&r1=320790&r2=320791&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>PowerPC/PPCInstrInfo.cpp?rev=<wbr>320791&r1=320790&r2=320791&<wbr>view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.cpp (original)<br>
> +++ llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.cpp Thu Dec 14 23:27:53 2017<br>
> @@ -51,6 +51,10 @@ STATISTIC(<wbr>NumStoreSPILLVSRRCAsVec,<br>
>  STATISTIC(<wbr>NumStoreSPILLVSRRCAsGpr,<br>
>            "Number of spillvsrrc spilled to stack as gpr");<br>
>  STATISTIC(NumGPRtoVSRSpill, "Number of gpr spills to spillvsrrc");<br>
> +STATISTIC(CmpIselsConverted,<br>
> +          "Number of ISELs that depend on comparison of constants converted");<br>
> +STATISTIC(<wbr>MissedConvertibleImmediateInst<wbr>rs,<br>
> +          "Number of compare-immediate instructions fed by constants");<br>
><br>
>  static cl::<br>
>  opt<bool> DisableCTRLoopAnal("disable-<wbr>ppc-ctrloop-analysis", cl::Hidden,<br>
> @@ -2147,6 +2151,816 @@ bool PPCInstrInfo::<wbr>expandPostRAPseudo(Ma<br>
>    return false;<br>
>  }<br>
><br>
> +unsigned PPCInstrInfo::<wbr>lookThruCopyLike(unsigned SrcReg,<br>
> +                                        const MachineRegisterInfo *MRI) {<br>
> +  while (true) {<br>
> +    MachineInstr *MI = MRI->getVRegDef(SrcReg);<br>
> +    if (!MI->isCopyLike())<br>
> +      return SrcReg;<br>
> +<br>
> +    unsigned CopySrcReg;<br>
> +    if (MI->isCopy())<br>
> +      CopySrcReg = MI->getOperand(1).getReg();<br>
> +    else {<br>
> +      assert(MI->isSubregToReg() && "Bad opcode for lookThruCopyLike");<br>
> +      CopySrcReg = MI->getOperand(2).getReg();<br>
> +    }<br>
> +<br>
> +    if (!TargetRegisterInfo::<wbr>isVirtualRegister(CopySrcReg))<br>
> +      return CopySrcReg;<br>
> +<br>
> +    SrcReg = CopySrcReg;<br>
> +  }<br>
> +}<br>
> +<br>
> +// Essentially a compile-time implementation of a compare->isel sequence.<br>
> +// It takes two constants to compare, along with the true/false registers<br>
> +// and the comparison type (as a subreg to a CR field) and returns one<br>
> +// of the true/false registers, depending on the comparison results.<br>
> +static unsigned selectReg(int64_t Imm1, int64_t Imm2, unsigned CompareOpc,<br>
> +                          unsigned TrueReg, unsigned FalseReg,<br>
> +                          unsigned CRSubReg) {<br>
> +  // Signed comparisons. The immediates are assumed to be sign-extended.<br>
> +  if (CompareOpc == PPC::CMPWI || CompareOpc == PPC::CMPDI) {<br>
> +    switch (CRSubReg) {<br>
> +    default: llvm_unreachable("Unknown integer comparison type.");<br>
> +    case PPC::sub_lt:<br>
> +      return Imm1 < Imm2 ? TrueReg : FalseReg;<br>
> +    case PPC::sub_gt:<br>
> +      return Imm1 > Imm2 ? TrueReg : FalseReg;<br>
> +    case PPC::sub_eq:<br>
> +      return Imm1 == Imm2 ? TrueReg : FalseReg;<br>
> +    }<br>
> +  }<br>
> +  // Unsigned comparisons.<br>
> +  else if (CompareOpc == PPC::CMPLWI || CompareOpc == PPC::CMPLDI) {<br>
> +    switch (CRSubReg) {<br>
> +    default: llvm_unreachable("Unknown integer comparison type.");<br>
> +    case PPC::sub_lt:<br>
> +      return (uint64_t)Imm1 < (uint64_t)Imm2 ? TrueReg : FalseReg;<br>
> +    case PPC::sub_gt:<br>
> +      return (uint64_t)Imm1 > (uint64_t)Imm2 ? TrueReg : FalseReg;<br>
> +    case PPC::sub_eq:<br>
> +      return Imm1 == Imm2 ? TrueReg : FalseReg;<br>
> +    }<br>
> +  }<br>
> +  return PPC::NoRegister;<br>
> +}<br>
> +<br>
> +// Replace an instruction with one that materializes a constant (and sets<br>
> +// CR0 if the original instruction was a record-form instruction).<br>
> +void PPCInstrInfo::<wbr>replaceInstrWithLI(<wbr>MachineInstr &MI,<br>
> +                                      const LoadImmediateInfo &LII) const {<br>
> +  // Remove existing operands.<br>
> +  int OperandToKeep = LII.SetCR ? 1 : 0;<br>
> +  for (int i = MI.getNumOperands() - 1; i > OperandToKeep; i--)<br>
> +    MI.RemoveOperand(i);<br>
> +<br>
> +  // Replace the instruction.<br>
> +  if (LII.SetCR)<br>
> +    MI.setDesc(get(LII.Is64Bit ? PPC::ANDIo8 : PPC::ANDIo));<br>
> +  else<br>
> +    MI.setDesc(get(LII.Is64Bit ? PPC::LI8 : PPC::LI));<br>
> +<br>
> +  // Set the immediate.<br>
> +  MachineInstrBuilder(*MI.<wbr>getParent()->getParent(), MI)<br>
> +      .addImm(LII.Imm);<br>
> +}<br>
> +<br>
> +MachineInstr *PPCInstrInfo::<wbr>getConstantDefMI(MachineInstr &MI,<br>
> +                                             unsigned &ConstOp,<br>
> +                                             bool &SeenIntermediateUse) const {<br>
> +  ConstOp = ~0U;<br>
> +  MachineInstr *DefMI = nullptr;<br>
> +  MachineRegisterInfo *MRI = &MI.getParent()->getParent()-><wbr>getRegInfo();<br>
> +  // If we'ere in SSA, get the defs through the MRI. Otherwise, only look<br>
> +  // within the basic block to see if the register is defined using an LI/LI8.<br>
> +  if (MRI->isSSA()) {<br>
> +    for (int i = 1, e = MI.getNumOperands(); i < e; i++) {<br>
> +      if (!MI.getOperand(i).isReg())<br>
> +        continue;<br>
> +      unsigned Reg = MI.getOperand(i).getReg();<br>
> +      if (!TargetRegisterInfo::<wbr>isVirtualRegister(Reg))<br>
> +        continue;<br>
> +      unsigned TrueReg = lookThruCopyLike(Reg, MRI);<br>
> +      if (TargetRegisterInfo::<wbr>isVirtualRegister(TrueReg)) {<br>
> +        DefMI = MRI->getVRegDef(TrueReg);<br>
> +        if (DefMI->getOpcode() == PPC::LI || DefMI->getOpcode() == PPC::LI8) {<br>
> +          ConstOp = i;<br>
> +          break;<br>
> +        }<br>
> +      }<br>
> +    }<br>
> +  } else {<br>
> +    // Looking back through the definition for each operand could be expensive,<br>
> +    // so exit early if this isn't an instruction that either has an immediate<br>
> +    // form or is already an immediate form that we can handle.<br>
> +    ImmInstrInfo III;<br>
> +    unsigned Opc = MI.getOpcode();<br>
> +    bool ConvertibleImmForm =<br>
> +      Opc == PPC::CMPWI || Opc == PPC::CMPLWI ||<br>
> +      Opc == PPC::CMPDI || Opc == PPC::CMPLDI ||<br>
> +      Opc == PPC::ADDI || Opc == PPC::ADDI8 ||<br>
> +      Opc == PPC::ORI || Opc == PPC::ORI8 ||<br>
> +      Opc == PPC::XORI || Opc == PPC::XORI8 ||<br>
> +      Opc == PPC::RLDICL || Opc == PPC::RLDICLo ||<br>
> +      Opc == PPC::RLDICL_32 || Opc == PPC::RLDICL_32_64 ||<br>
> +      Opc == PPC::RLWINM || Opc == PPC::RLWINMo ||<br>
> +      Opc == PPC::RLWINM8 || Opc == PPC::RLWINM8o;<br>
> +    if (!instrHasImmForm(MI, III) && !ConvertibleImmForm)<br>
> +      return nullptr;<br>
> +<br>
> +    // Don't convert or %X, %Y, %Y since that's just a register move.<br>
> +    if ((Opc == PPC::OR || Opc == PPC::OR8) &&<br>
> +        MI.getOperand(1).getReg() == MI.getOperand(2).getReg())<br>
> +      return nullptr;<br>
> +    for (int i = 1, e = MI.getNumOperands(); i < e; i++) {<br>
> +      MachineOperand &MO = MI.getOperand(i);<br>
> +      SeenIntermediateUse = false;<br>
> +      if (MO.isReg() && MO.isUse() && !MO.isImplicit()) {<br>
> +        MachineBasicBlock::reverse_<wbr>iterator E = MI.getParent()->rend(), It = MI;<br>
> +        It++;<br>
> +        unsigned Reg = MI.getOperand(i).getReg();<br>
> +<br>
> +        // Is this register defined by a load-immediate in this block?<br>
> +        for ( ; It != E; ++It) {<br>
> +          if (It->modifiesRegister(Reg, &getRegisterInfo())) {<br>
> +            if (It->getOpcode() == PPC::LI || It->getOpcode() == PPC::LI8) {<br>
> +              ConstOp = i;<br>
> +              return &*It;<br>
> +            } else<br>
> +              break;<br>
> +          } else if (It->readsRegister(Reg, &getRegisterInfo()))<br>
> +            // If we see another use of this reg between the def and the MI,<br>
> +            // we want to flat it so the def isn't deleted.<br>
> +            SeenIntermediateUse = true;<br>
> +        }<br>
> +      }<br>
> +    }<br>
> +  }<br>
> +  return ConstOp == ~0U ? nullptr : DefMI;<br>
> +}<br>
> +<br>
> +// If this instruction has an immediate form and one of its operands is a<br>
> +// result of a load-immediate, convert it to the immediate form if the constant<br>
> +// is in range.<br>
> +bool PPCInstrInfo::<wbr>convertToImmediateForm(<wbr>MachineInstr &MI,<br>
> +                                          MachineInstr **KilledDef) const {<br>
> +  MachineFunction *MF = MI.getParent()->getParent();<br>
> +  MachineRegisterInfo *MRI = &MF->getRegInfo();<br>
> +  bool PostRA = !MRI->isSSA();<br>
> +  bool SeenIntermediateUse = true;<br>
> +  unsigned ConstantOperand = ~0U;<br>
> +  MachineInstr *DefMI = getConstantDefMI(MI, ConstantOperand,<br>
> +                                         SeenIntermediateUse);<br>
> +  if (!DefMI || !DefMI->getOperand(1).isImm())<br>
> +    return false;<br>
> +  assert(ConstantOperand < MI.getNumOperands() &&<br>
> +         "The constant operand needs to be valid at this point");<br>
> +<br>
> +  int64_t Immediate = DefMI->getOperand(1).getImm();<br>
> +  // Sign-extend to 64-bits.<br>
> +  int64_t SExtImm = ((uint64_t)Immediate & ~0x7FFFuLL) != 0 ?<br>
> +    (Immediate | 0xFFFFFFFFFFFF0000) : Immediate;<br>
> +<br>
> +  if (KilledDef && MI.getOperand(ConstantOperand)<wbr>.isKill() &&<br>
> +      !SeenIntermediateUse)<br>
> +    *KilledDef = DefMI;<br>
> +<br>
> +  // If this is a reg+reg instruction that has a reg+imm form, convert it now.<br>
> +  ImmInstrInfo III;<br>
> +  if (instrHasImmForm(MI, III))<br>
> +    return transformToImmForm(MI, III, ConstantOperand, SExtImm);<br>
> +<br>
> +  bool ReplaceWithLI = false;<br>
> +  bool Is64BitLI = false;<br>
> +  int64_t NewImm = 0;<br>
> +  bool SetCR = false;<br>
> +  unsigned Opc = MI.getOpcode();<br>
> +  switch (Opc) {<br>
> +  default: return false;<br>
> +<br>
> +  // FIXME: Any branches conditional on such a comparison can be made<br>
> +  // unconditional. At this time, this happens too infrequently to be worth<br>
> +  // the implementation effort, but if that ever changes, we could convert<br>
> +  // such a pattern here.<br>
> +  case PPC::CMPWI:<br>
> +  case PPC::CMPLWI:<br>
> +  case PPC::CMPDI:<br>
> +  case PPC::CMPLDI: {<br>
> +    // Doing this post-RA would require dataflow analysis to reliably find uses<br>
> +    // of the CR register set by the compare.<br>
> +    if (PostRA)<br>
> +      return false;<br>
> +    // If a compare-immediate is fed by an immediate and is itself an input of<br>
> +    // an ISEL (the most common case) into a COPY of the correct register.<br>
> +    bool Changed = false;<br>
> +    unsigned DefReg = MI.getOperand(0).getReg();<br>
> +    int64_t Comparand = MI.getOperand(2).getImm();<br>
> +    int64_t SExtComparand = ((uint64_t)Comparand & ~0x7FFFuLL) != 0 ?<br>
> +      (Comparand | 0xFFFFFFFFFFFF0000) : Comparand;<br>
> +<br>
> +    for (auto &CompareUseMI : MRI->use_instructions(DefReg)) {<br>
> +      unsigned UseOpc = CompareUseMI.getOpcode();<br>
> +      if (UseOpc != PPC::ISEL && UseOpc != PPC::ISEL8)<br>
> +        continue;<br>
> +      unsigned CRSubReg = CompareUseMI.getOperand(3).<wbr>getSubReg();<br>
> +      unsigned TrueReg = CompareUseMI.getOperand(1).<wbr>getReg();<br>
> +      unsigned FalseReg = CompareUseMI.getOperand(2).<wbr>getReg();<br>
> +      unsigned RegToCopy = selectReg(SExtImm, SExtComparand, Opc, TrueReg,<br>
> +                                     FalseReg, CRSubReg);<br>
> +      if (RegToCopy == PPC::NoRegister)<br>
> +        continue;<br>
> +      // Can't use PPC::COPY to copy PPC::ZERO[8]. Convert it to LI[8] 0.<br>
> +      if (RegToCopy == PPC::ZERO || RegToCopy == PPC::ZERO8) {<br>
> +        CompareUseMI.setDesc(get(<wbr>UseOpc == PPC::ISEL8 ? PPC::LI8 : PPC::LI));<br>
> +        CompareUseMI.getOperand(1).<wbr>ChangeToImmediate(0);<br>
> +        CompareUseMI.RemoveOperand(3);<br>
> +        CompareUseMI.RemoveOperand(2);<br>
> +        continue;<br>
> +      }<br>
> +      DEBUG(dbgs() << "Found LI -> CMPI -> ISEL, replacing with a copy.\n");<br>
> +      DEBUG(DefMI->dump(); MI.dump(); CompareUseMI.dump());<br>
> +      DEBUG(dbgs() << "Is converted to:\n");<br>
> +      // Convert to copy and remove unneeded operands.<br>
> +      CompareUseMI.setDesc(get(PPC::<wbr>COPY));<br>
> +      CompareUseMI.RemoveOperand(3);<br>
> +      CompareUseMI.RemoveOperand(<wbr>RegToCopy == TrueReg ? 2 : 1);<br>
> +      CmpIselsConverted++;<br>
> +      Changed = true;<br>
> +      DEBUG(CompareUseMI.dump());<br>
> +    }<br>
> +    if (Changed)<br>
> +      return true;<br>
> +    // This may end up incremented multiple times since this function is called<br>
> +    // during a fixed-point transformation, but it is only meant to indicate the<br>
> +    // presence of this opportunity.<br>
> +    MissedConvertibleImmediateInst<wbr>rs++;<br>
> +    return false;<br>
> +  }<br>
> +<br>
> +  // Immediate forms - may simply be convertable to an LI.<br>
> +  case PPC::ADDI:<br>
> +  case PPC::ADDI8: {<br>
> +    // Does the sum fit in a 16-bit signed field?<br>
> +    int64_t Addend = MI.getOperand(2).getImm();<br>
> +    if (isInt<16>(Addend + SExtImm)) {<br>
> +      ReplaceWithLI = true;<br>
> +      Is64BitLI = Opc == PPC::ADDI8;<br>
> +      NewImm = Addend + SExtImm;<br>
> +      break;<br>
> +    }<br>
> +  }<br>
> +  case PPC::RLDICL:<br>
> +  case PPC::RLDICLo:<br>
> +  case PPC::RLDICL_32:<br>
> +  case PPC::RLDICL_32_64: {<br>
> +    // Use APInt's rotate function.<br>
> +    int64_t SH = MI.getOperand(2).getImm();<br>
> +    int64_t MB = MI.getOperand(3).getImm();<br>
> +    APInt InVal(Opc == PPC::RLDICL ? 64 : 32, SExtImm, true);<br>
> +    InVal = InVal.rotl(SH);<br>
> +    uint64_t Mask = (1LU << (63 - MB + 1)) - 1;<br>
> +    InVal &= Mask;<br>
> +    // Can't replace negative values with an LI as that will sign-extend<br>
> +    // and not clear the left bits. If we're setting the CR bit, we will use<br>
> +    // ANDIo which won't sign extend, so that's safe.<br>
> +    if (isUInt<15>(InVal.<wbr>getSExtValue()) ||<br>
> +        (Opc == PPC::RLDICLo && isUInt<16>(InVal.getSExtValue(<wbr>)))) {<br>
> +      ReplaceWithLI = true;<br>
> +      Is64BitLI = Opc != PPC::RLDICL_32;<br>
> +      NewImm = InVal.getSExtValue();<br>
> +      SetCR = Opc == PPC::RLDICLo;<br>
> +      break;<br>
> +    }<br>
> +    return false;<br>
> +  }<br>
> +  case PPC::RLWINM:<br>
> +  case PPC::RLWINM8:<br>
> +  case PPC::RLWINMo:<br>
> +  case PPC::RLWINM8o: {<br>
> +    int64_t SH = MI.getOperand(2).getImm();<br>
> +    int64_t MB = MI.getOperand(3).getImm();<br>
> +    int64_t ME = MI.getOperand(4).getImm();<br>
> +    APInt InVal(32, SExtImm, true);<br>
> +    InVal = InVal.rotl(SH);<br>
> +    // Set the bits (       MB + 32      ) to (       ME + 32      ).<br>
> +    uint64_t Mask = ((1 << (32 - MB)) - 1) & ~((1 << (31 - ME)) - 1);<br>
> +    InVal &= Mask;<br>
> +    // Can't replace negative values with an LI as that will sign-extend<br>
> +    // and not clear the left bits. If we're setting the CR bit, we will use<br>
> +    // ANDIo which won't sign extend, so that's safe.<br>
> +    bool ValueFits = isUInt<15>(InVal.getSExtValue(<wbr>));<br>
> +    ValueFits |= ((Opc == PPC::RLWINMo || Opc == PPC::RLWINM8o) &&<br>
> +                  isUInt<16>(InVal.getSExtValue(<wbr>)));<br>
> +    if (ValueFits) {<br>
> +      ReplaceWithLI = true;<br>
> +      Is64BitLI = Opc == PPC::RLWINM8 || Opc == PPC::RLWINM8o;<br>
> +      NewImm = InVal.getSExtValue();<br>
> +      SetCR = Opc == PPC::RLWINMo || Opc == PPC::RLWINM8o;<br>
> +      break;<br>
> +    }<br>
> +    return false;<br>
> +  }<br>
> +  case PPC::ORI:<br>
> +  case PPC::ORI8:<br>
> +  case PPC::XORI:<br>
> +  case PPC::XORI8: {<br>
> +    int64_t LogicalImm = MI.getOperand(2).getImm();<br>
> +    int64_t Result = 0;<br>
> +    if (Opc == PPC::ORI || Opc == PPC::ORI8)<br>
> +      Result = LogicalImm | SExtImm;<br>
> +    else<br>
> +      Result = LogicalImm ^ SExtImm;<br>
> +    if (isInt<16>(Result)) {<br>
> +      ReplaceWithLI = true;<br>
> +      Is64BitLI = Opc == PPC::ORI8 || Opc == PPC::XORI8;<br>
> +      NewImm = Result;<br>
> +      break;<br>
> +    }<br>
> +    return false;<br>
> +  }<br>
> +  }<br>
> +<br>
> +  if (ReplaceWithLI) {<br>
> +    DEBUG(dbgs() << "Replacing instruction:\n");<br>
> +    DEBUG(MI.dump());<br>
> +    DEBUG(dbgs() << "Fed by:\n");<br>
> +    DEBUG(DefMI->dump());<br>
> +    LoadImmediateInfo LII;<br>
> +    LII.Imm = NewImm;<br>
> +    LII.Is64Bit = Is64BitLI;<br>
> +    LII.SetCR = SetCR;<br>
> +    // If we're setting the CR, the original load-immediate must be kept (as an<br>
> +    // operand to ANDIo/ANDI8o).<br>
> +    if (KilledDef && SetCR)<br>
> +      *KilledDef = nullptr;<br>
> +    replaceInstrWithLI(MI, LII);<br>
> +    DEBUG(dbgs() << "With:\n");<br>
> +    DEBUG(MI.dump());<br>
> +    return true;<br>
> +  }<br>
> +  return false;<br>
> +}<br>
> +<br>
> +bool PPCInstrInfo::instrHasImmForm(<wbr>const MachineInstr &MI,<br>
> +                                   ImmInstrInfo &III) const {<br>
> +  unsigned Opc = MI.getOpcode();<br>
> +  // The vast majority of the instructions would need their operand 2 replaced<br>
> +  // with an immediate when switching to the reg+imm form. A marked exception<br>
> +  // are the update form loads/stores for which a constant operand 2 would need<br>
> +  // to turn into a displacement and move operand 1 to the operand 2 position.<br>
> +  III.ImmOpNo = 2;<br>
> +  III.ConstantOpNo = 2;<br>
> +  III.ImmWidth = 16;<br>
> +  III.ImmMustBeMultipleOf = 1;<br>
> +  switch (Opc) {<br>
> +  default: return false;<br>
> +  case PPC::ADD4:<br>
> +  case PPC::ADD8:<br>
> +    III.SignedImm = true;<br>
> +    III.ZeroIsSpecialOrig = 0;<br>
> +    III.ZeroIsSpecialNew = 1;<br>
> +    III.IsCommutative = true;<br>
> +    III.ImmOpcode = Opc == PPC::ADD4 ? PPC::ADDI : PPC::ADDI8;<br>
> +    break;<br>
> +  case PPC::ADDC:<br>
> +  case PPC::ADDC8:<br>
> +    III.SignedImm = true;<br>
> +    III.ZeroIsSpecialOrig = 0;<br>
> +    III.ZeroIsSpecialNew = 0;<br>
> +    III.IsCommutative = true;<br>
> +    III.ImmOpcode = Opc == PPC::ADDC ? PPC::ADDIC : PPC::ADDIC8;<br>
> +    break;<br>
> +  case PPC::ADDCo:<br>
> +    III.SignedImm = true;<br>
> +    III.ZeroIsSpecialOrig = 0;<br>
> +    III.ZeroIsSpecialNew = 0;<br>
> +    III.IsCommutative = true;<br>
> +    III.ImmOpcode = PPC::ADDICo;<br>
> +    break;<br>
> +  case PPC::SUBFC:<br>
> +  case PPC::SUBFC8:<br>
> +    III.SignedImm = true;<br>
> +    III.ZeroIsSpecialOrig = 0;<br>
> +    III.ZeroIsSpecialNew = 0;<br>
> +    III.IsCommutative = false;<br>
> +    III.ImmOpcode = Opc == PPC::SUBFC ? PPC::SUBFIC : PPC::SUBFIC8;<br>
> +    break;<br>
> +  case PPC::CMPW:<br>
> +  case PPC::CMPD:<br>
> +    III.SignedImm = true;<br>
> +    III.ZeroIsSpecialOrig = 0;<br>
> +    III.ZeroIsSpecialNew = 0;<br>
> +    III.IsCommutative = false;<br>
> +    III.ImmOpcode = Opc == PPC::CMPW ? PPC::CMPWI : PPC::CMPDI;<br>
> +    break;<br>
> +  case PPC::CMPLW:<br>
> +  case PPC::CMPLD:<br>
> +    III.SignedImm = false;<br>
> +    III.ZeroIsSpecialOrig = 0;<br>
> +    III.ZeroIsSpecialNew = 0;<br>
> +    III.IsCommutative = false;<br>
> +    III.ImmOpcode = Opc == PPC::CMPLW ? PPC::CMPLWI : PPC::CMPLDI;<br>
> +    break;<br>
> +  case PPC::ANDo:<br>
> +  case PPC::AND8o:<br>
> +  case PPC::OR:<br>
> +  case PPC::OR8:<br>
> +  case PPC::XOR:<br>
> +  case PPC::XOR8:<br>
> +    III.SignedImm = false;<br>
> +    III.ZeroIsSpecialOrig = 0;<br>
> +    III.ZeroIsSpecialNew = 0;<br>
> +    III.IsCommutative = true;<br>
> +    switch(Opc) {<br>
> +    default: llvm_unreachable("Unknown opcode");<br>
> +    case PPC::ANDo: III.ImmOpcode = PPC::ANDIo; break;<br>
> +    case PPC::AND8o: III.ImmOpcode = PPC::ANDIo8; break;<br>
> +    case PPC::OR: III.ImmOpcode = PPC::ORI; break;<br>
> +    case PPC::OR8: III.ImmOpcode = PPC::ORI8; break;<br>
> +    case PPC::XOR: III.ImmOpcode = PPC::XORI; break;<br>
> +    case PPC::XOR8: III.ImmOpcode = PPC::XORI8; break;<br>
> +    }<br>
> +    break;<br>
> +  case PPC::RLWNM:<br>
> +  case PPC::RLWNM8:<br>
> +  case PPC::RLWNMo:<br>
> +  case PPC::RLWNM8o:<br>
> +  case PPC::RLDCL:<br>
> +  case PPC::RLDCLo:<br>
> +  case PPC::RLDCR:<br>
> +  case PPC::RLDCRo:<br>
> +  case PPC::SLW:<br>
> +  case PPC::SLW8:<br>
> +  case PPC::SLWo:<br>
> +  case PPC::SLW8o:<br>
> +  case PPC::SRW:<br>
> +  case PPC::SRW8:<br>
> +  case PPC::SRWo:<br>
> +  case PPC::SRW8o:<br>
> +  case PPC::SRAW:<br>
> +  case PPC::SRAWo:<br>
> +  case PPC::SLD:<br>
> +  case PPC::SLDo:<br>
> +  case PPC::SRD:<br>
> +  case PPC::SRDo:<br>
> +  case PPC::SRAD:<br>
> +  case PPC::SRADo:<br>
> +    III.SignedImm = false;<br>
> +    III.ZeroIsSpecialOrig = 0;<br>
> +    III.ZeroIsSpecialNew = 0;<br>
> +    III.IsCommutative = false;<br>
> +    // This isn't actually true, but the instructions ignore any of the<br>
> +    // upper bits, so any immediate loaded with an LI is acceptable.<br>
> +    III.ImmWidth = 16;<br>
> +    switch(Opc) {<br>
> +    default: llvm_unreachable("Unknown opcode");<br>
> +    case PPC::RLWNM: III.ImmOpcode = PPC::RLWINM; break;<br>
> +    case PPC::RLWNM8: III.ImmOpcode = PPC::RLWINM8; break;<br>
> +    case PPC::RLWNMo: III.ImmOpcode = PPC::RLWINMo; break;<br>
> +    case PPC::RLWNM8o: III.ImmOpcode = PPC::RLWINM8o; break;<br>
> +    case PPC::RLDCL: III.ImmOpcode = PPC::RLDICL; break;<br>
> +    case PPC::RLDCLo: III.ImmOpcode = PPC::RLDICLo; break;<br>
> +    case PPC::RLDCR: III.ImmOpcode = PPC::RLDICR; break;<br>
> +    case PPC::RLDCRo: III.ImmOpcode = PPC::RLDICRo; break;<br>
> +    case PPC::SLW: III.ImmOpcode = PPC::RLWINM; break;<br>
> +    case PPC::SLW8: III.ImmOpcode = PPC::RLWINM8; break;<br>
> +    case PPC::SLWo: III.ImmOpcode = PPC::RLWINMo; break;<br>
> +    case PPC::SLW8o: III.ImmOpcode = PPC::RLWINM8o; break;<br>
> +    case PPC::SRW: III.ImmOpcode = PPC::RLWINM; break;<br>
> +    case PPC::SRW8: III.ImmOpcode = PPC::RLWINM8; break;<br>
> +    case PPC::SRWo: III.ImmOpcode = PPC::RLWINMo; break;<br>
> +    case PPC::SRW8o: III.ImmOpcode = PPC::RLWINM8o; break;<br>
> +    case PPC::SRAW: III.ImmOpcode = PPC::SRAWI; break;<br>
> +    case PPC::SRAWo: III.ImmOpcode = PPC::SRAWIo; break;<br>
> +    case PPC::SLD: III.ImmOpcode = PPC::RLDICR; break;<br>
> +    case PPC::SLDo: III.ImmOpcode = PPC::RLDICRo; break;<br>
> +    case PPC::SRD: III.ImmOpcode = PPC::RLDICL; break;<br>
> +    case PPC::SRDo: III.ImmOpcode = PPC::RLDICLo; break;<br>
> +    case PPC::SRAD: III.ImmOpcode = PPC::SRADI; break;<br>
> +    case PPC::SRADo: III.ImmOpcode = PPC::SRADIo; break;<br>
> +    }<br>
> +    break;<br>
> +  // Loads and stores:<br>
> +  case PPC::LBZX:<br>
> +  case PPC::LBZX8:<br>
> +  case PPC::LHZX:<br>
> +  case PPC::LHZX8:<br>
> +  case PPC::LHAX:<br>
> +  case PPC::LHAX8:<br>
> +  case PPC::LWZX:<br>
> +  case PPC::LWZX8:<br>
> +  case PPC::LWAX:<br>
> +  case PPC::LDX:<br>
> +  case PPC::LFSX:<br>
> +  case PPC::LFDX:<br>
> +  case PPC::STBX:<br>
> +  case PPC::STBX8:<br>
> +  case PPC::STHX:<br>
> +  case PPC::STHX8:<br>
> +  case PPC::STWX:<br>
> +  case PPC::STWX8:<br>
> +  case PPC::STDX:<br>
> +  case PPC::STFSX:<br>
> +  case PPC::STFDX:<br>
> +    III.SignedImm = true;<br>
> +    III.ZeroIsSpecialOrig = 1;<br>
> +    III.ZeroIsSpecialNew = 2;<br>
> +    III.IsCommutative = true;<br>
> +    III.ImmOpNo = 1;<br>
> +    III.ConstantOpNo = 2;<br>
> +    switch(Opc) {<br>
> +    default: llvm_unreachable("Unknown opcode");<br>
> +    case PPC::LBZX: III.ImmOpcode = PPC::LBZ; break;<br>
> +    case PPC::LBZX8: III.ImmOpcode = PPC::LBZ8; break;<br>
> +    case PPC::LHZX: III.ImmOpcode = PPC::LHZ; break;<br>
> +    case PPC::LHZX8: III.ImmOpcode = PPC::LHZ8; break;<br>
> +    case PPC::LHAX: III.ImmOpcode = PPC::LHA; break;<br>
> +    case PPC::LHAX8: III.ImmOpcode = PPC::LHA8; break;<br>
> +    case PPC::LWZX: III.ImmOpcode = PPC::LWZ; break;<br>
> +    case PPC::LWZX8: III.ImmOpcode = PPC::LWZ8; break;<br>
> +    case PPC::LWAX:<br>
> +      III.ImmOpcode = PPC::LWA;<br>
> +      III.ImmMustBeMultipleOf = 4;<br>
> +      break;<br>
> +    case PPC::LDX: III.ImmOpcode = PPC::LD; III.ImmMustBeMultipleOf = 4; break;<br>
> +    case PPC::LFSX: III.ImmOpcode = PPC::LFS; break;<br>
> +    case PPC::LFDX: III.ImmOpcode = PPC::LFD; break;<br>
> +    case PPC::STBX: III.ImmOpcode = PPC::STB; break;<br>
> +    case PPC::STBX8: III.ImmOpcode = PPC::STB8; break;<br>
> +    case PPC::STHX: III.ImmOpcode = PPC::STH; break;<br>
> +    case PPC::STHX8: III.ImmOpcode = PPC::STH8; break;<br>
> +    case PPC::STWX: III.ImmOpcode = PPC::STW; break;<br>
> +    case PPC::STWX8: III.ImmOpcode = PPC::STW8; break;<br>
> +    case PPC::STDX:<br>
> +      III.ImmOpcode = PPC::STD;<br>
> +      III.ImmMustBeMultipleOf = 4;<br>
> +      break;<br>
> +    case PPC::STFSX: III.ImmOpcode = PPC::STFS; break;<br>
> +    case PPC::STFDX: III.ImmOpcode = PPC::STFD; break;<br>
> +    }<br>
> +    break;<br>
> +  case PPC::LBZUX:<br>
> +  case PPC::LBZUX8:<br>
> +  case PPC::LHZUX:<br>
> +  case PPC::LHZUX8:<br>
> +  case PPC::LHAUX:<br>
> +  case PPC::LHAUX8:<br>
> +  case PPC::LWZUX:<br>
> +  case PPC::LWZUX8:<br>
> +  case PPC::LDUX:<br>
> +  case PPC::LFSUX:<br>
> +  case PPC::LFDUX:<br>
> +  case PPC::STBUX:<br>
> +  case PPC::STBUX8:<br>
> +  case PPC::STHUX:<br>
> +  case PPC::STHUX8:<br>
> +  case PPC::STWUX:<br>
> +  case PPC::STWUX8:<br>
> +  case PPC::STDUX:<br>
> +  case PPC::STFSUX:<br>
> +  case PPC::STFDUX:<br>
> +    III.SignedImm = true;<br>
> +    III.ZeroIsSpecialOrig = 2;<br>
> +    III.ZeroIsSpecialNew = 3;<br>
> +    III.IsCommutative = false;<br>
> +    III.ImmOpNo = 2;<br>
> +    III.ConstantOpNo = 3;<br>
> +    switch(Opc) {<br>
> +    default: llvm_unreachable("Unknown opcode");<br>
> +    case PPC::LBZUX: III.ImmOpcode = PPC::LBZU; break;<br>
> +    case PPC::LBZUX8: III.ImmOpcode = PPC::LBZU8; break;<br>
> +    case PPC::LHZUX: III.ImmOpcode = PPC::LHZU; break;<br>
> +    case PPC::LHZUX8: III.ImmOpcode = PPC::LHZU8; break;<br>
> +    case PPC::LHAUX: III.ImmOpcode = PPC::LHAU; break;<br>
> +    case PPC::LHAUX8: III.ImmOpcode = PPC::LHAU8; break;<br>
> +    case PPC::LWZUX: III.ImmOpcode = PPC::LWZU; break;<br>
> +    case PPC::LWZUX8: III.ImmOpcode = PPC::LWZU8; break;<br>
> +    case PPC::LDUX:<br>
> +      III.ImmOpcode = PPC::LDU;<br>
> +      III.ImmMustBeMultipleOf = 4;<br>
> +      break;<br>
> +    case PPC::LFSUX: III.ImmOpcode = PPC::LFSU; break;<br>
> +    case PPC::LFDUX: III.ImmOpcode = PPC::LFDU; break;<br>
> +    case PPC::STBUX: III.ImmOpcode = PPC::STBU; break;<br>
> +    case PPC::STBUX8: III.ImmOpcode = PPC::STBU8; break;<br>
> +    case PPC::STHUX: III.ImmOpcode = PPC::STHU; break;<br>
> +    case PPC::STHUX8: III.ImmOpcode = PPC::STHU8; break;<br>
> +    case PPC::STWUX: III.ImmOpcode = PPC::STWU; break;<br>
> +    case PPC::STWUX8: III.ImmOpcode = PPC::STWU8; break;<br>
> +    case PPC::STDUX:<br>
> +      III.ImmOpcode = PPC::STDU;<br>
> +      III.ImmMustBeMultipleOf = 4;<br>
> +      break;<br>
> +    case PPC::STFSUX: III.ImmOpcode = PPC::STFSU; break;<br>
> +    case PPC::STFDUX: III.ImmOpcode = PPC::STFDU; break;<br>
> +    }<br>
> +    break;<br>
> +  // Power9 only.<br>
> +  case PPC::LXVX:<br>
> +  case PPC::LXSSPX:<br>
> +  case PPC::LXSDX:<br>
> +  case PPC::STXVX:<br>
> +  case PPC::STXSSPX:<br>
> +  case PPC::STXSDX:<br>
> +    if (!Subtarget.hasP9Vector())<br>
> +      return false;<br>
> +    III.SignedImm = true;<br>
> +    III.ZeroIsSpecialOrig = 1;<br>
> +    III.ZeroIsSpecialNew = 2;<br>
> +    III.IsCommutative = true;<br>
> +    III.ImmOpNo = 1;<br>
> +    III.ConstantOpNo = 2;<br>
> +    switch(Opc) {<br>
> +    default: llvm_unreachable("Unknown opcode");<br>
> +    case PPC::LXVX:<br>
> +      III.ImmOpcode = PPC::LXV;<br>
> +      III.ImmMustBeMultipleOf = 16;<br>
> +      break;<br>
> +    case PPC::LXSSPX:<br>
> +      III.ImmOpcode = PPC::LXSSP;<br>
> +      III.ImmMustBeMultipleOf = 4;<br>
> +      break;<br>
> +    case PPC::LXSDX:<br>
> +      III.ImmOpcode = PPC::LXSD;<br>
> +      III.ImmMustBeMultipleOf = 4;<br>
> +      break;<br>
> +    case PPC::STXVX:<br>
> +      III.ImmOpcode = PPC::STXV;<br>
> +      III.ImmMustBeMultipleOf = 16;<br>
> +      break;<br>
> +    case PPC::STXSSPX:<br>
> +      III.ImmOpcode = PPC::STXSSP;<br>
> +      III.ImmMustBeMultipleOf = 4;<br>
> +      break;<br>
> +    case PPC::STXSDX:<br>
> +      III.ImmOpcode = PPC::STXSD;<br>
> +      III.ImmMustBeMultipleOf = 4;<br>
> +      break;<br>
> +    }<br>
> +    break;<br>
> +  }<br>
> +  return true;<br>
> +}<br>
> +<br>
> +// Utility function for swaping two arbitrary operands of an instruction.<br>
> +static void swapMIOperands(MachineInstr &MI, unsigned Op1, unsigned Op2) {<br>
> +  assert(Op1 != Op2 && "Cannot swap operand with itself.");<br>
> +<br>
> +  unsigned MaxOp = std::max(Op1, Op2);<br>
> +  unsigned MinOp = std::min(Op1, Op2);<br>
> +  MachineOperand MOp1 = MI.getOperand(MinOp);<br>
> +  MachineOperand MOp2 = MI.getOperand(MaxOp);<br>
> +  MI.RemoveOperand(std::max(Op1, Op2));<br>
> +  MI.RemoveOperand(std::min(Op1, Op2));<br>
> +<br>
> +  // If the operands we are swapping are the two at the end (the common case)<br>
> +  // we can just remove both and add them in the opposite order.<br>
> +  if (MaxOp - MinOp == 1 && MI.getNumOperands() == MinOp) {<br>
> +    MI.addOperand(MOp2);<br>
> +    MI.addOperand(MOp1);<br>
> +  } else {<br>
> +    // Store all operands in a temporary vector, remove them and re-add in the<br>
> +    // right order.<br>
> +    SmallVector<MachineOperand, 2> MOps;<br>
> +    unsigned TotalOps = MI.getNumOperands() + 2; // We've already removed 2 ops.<br>
> +    for (unsigned i = MI.getNumOperands() - 1; i >= MinOp; i--) {<br>
> +      MOps.push_back(MI.getOperand(<wbr>i));<br>
> +      MI.RemoveOperand(i);<br>
> +    }<br>
> +    // MOp2 needs to be added next.<br>
> +    MI.addOperand(MOp2);<br>
> +    // Now add the rest.<br>
> +    for (unsigned i = MI.getNumOperands(); i < TotalOps; i++) {<br>
> +      if (i == MaxOp)<br>
> +        MI.addOperand(MOp1);<br>
> +      else {<br>
> +        MI.addOperand(MOps.back());<br>
> +        MOps.pop_back();<br>
> +      }<br>
> +    }<br>
> +  }<br>
> +}<br>
> +<br>
> +bool PPCInstrInfo::<wbr>transformToImmForm(<wbr>MachineInstr &MI, const ImmInstrInfo &III,<br>
> +                                      unsigned ConstantOpNo,<br>
> +                                      int64_t Imm) const {<br>
> +  MachineRegisterInfo &MRI = MI.getParent()->getParent()-><wbr>getRegInfo();<br>
> +  bool PostRA = !MRI.isSSA();<br>
> +  // Exit early if we can't convert this.<br>
> +  if ((ConstantOpNo != III.ConstantOpNo) && !III.IsCommutative)<br>
> +    return false;<br>
> +  if (Imm % III.ImmMustBeMultipleOf)<br>
> +    return false;<br>
> +  if (III.SignedImm) {<br>
> +    APInt ActualValue(64, Imm, true);<br>
> +    if (!ActualValue.isSignedIntN(<wbr>III.ImmWidth))<br>
> +      return false;<br>
> +  } else {<br>
> +    uint64_t UnsignedMax = (1 << III.ImmWidth) - 1;<br>
> +    if ((uint64_t)Imm > UnsignedMax)<br>
> +      return false;<br>
> +  }<br>
> +<br>
> +  // If we're post-RA, the instructions don't agree on whether register zero is<br>
> +  // special, we can transform this as long as the register operand that will<br>
> +  // end up in the location where zero is special isn't R0.<br>
> +  if (PostRA && III.ZeroIsSpecialOrig != III.ZeroIsSpecialNew) {<br>
> +    unsigned PosForOrigZero = III.ZeroIsSpecialOrig ? III.ZeroIsSpecialOrig :<br>
> +      III.ZeroIsSpecialNew + 1;<br>
> +    unsigned OrigZeroReg = MI.getOperand(PosForOrigZero).<wbr>getReg();<br>
> +    unsigned NewZeroReg = MI.getOperand(III.<wbr>ZeroIsSpecialNew).getReg();<br>
> +    // If R0 is in the operand where zero is special for the new instruction,<br>
> +    // it is unsafe to transform if the constant operand isn't that operand.<br>
> +    if ((NewZeroReg == PPC::R0 || NewZeroReg == PPC::X0) &&<br>
> +        ConstantOpNo != III.ZeroIsSpecialNew)<br>
> +      return false;<br>
> +    if ((OrigZeroReg == PPC::R0 || OrigZeroReg == PPC::X0) &&<br>
> +        ConstantOpNo != PosForOrigZero)<br>
> +      return false;<br>
> +  }<br>
> +<br>
> +  unsigned Opc = MI.getOpcode();<br>
> +  bool SpecialShift32 =<br>
> +    Opc == PPC::SLW || Opc == PPC::SLWo || Opc == PPC::SRW || Opc == PPC::SRWo;<br>
> +  bool SpecialShift64 =<br>
> +    Opc == PPC::SLD || Opc == PPC::SLDo || Opc == PPC::SRD || Opc == PPC::SRDo;<br>
> +  bool SetCR = Opc == PPC::SLWo || Opc == PPC::SRWo ||<br>
> +    Opc == PPC::SLDo || Opc == PPC::SRDo;<br>
> +  bool RightShift =<br>
> +    Opc == PPC::SRW || Opc == PPC::SRWo || Opc == PPC::SRD || Opc == PPC::SRDo;<br>
> +<br>
> +  MI.setDesc(get(III.ImmOpcode))<wbr>;<br>
> +  if (ConstantOpNo == III.ConstantOpNo) {<br>
> +    // Converting shifts to immediate form is a bit tricky since they may do<br>
> +    // one of three things:<br>
> +    // 1. If the shift amount is between OpSize and 2*OpSize, the result is zero<br>
> +    // 2. If the shift amount is zero, the result is unchanged (save for maybe<br>
> +    //    setting CR0)<br>
> +    // 3. If the shift amount is in [1, OpSize), it's just a shift<br>
> +    if (SpecialShift32 || SpecialShift64) {<br>
> +      LoadImmediateInfo LII;<br>
> +      LII.Imm = 0;<br>
> +      LII.SetCR = SetCR;<br>
> +      LII.Is64Bit = SpecialShift64;<br>
> +      uint64_t ShAmt = Imm & (SpecialShift32 ? 0x1F : 0x3F);<br>
> +      if (Imm & (SpecialShift32 ? 0x20 : 0x40))<br>
> +        replaceInstrWithLI(MI, LII);<br>
> +      // Shifts by zero don't change the value. If we don't need to set CR0,<br>
> +      // just convert this to a COPY. Can't do this post-RA since we've already<br>
> +      // cleaned up the copies.<br>
> +      else if (!SetCR && ShAmt == 0 && !PostRA) {<br>
> +        MI.RemoveOperand(2);<br>
> +        MI.setDesc(get(PPC::COPY));<br>
> +      } else {<br>
> +        // The 32 bit and 64 bit instructions are quite different.<br>
> +        if (SpecialShift32) {<br>
> +          // Left shifts use (N, 0, 31-N), right shifts use (32-N, N, 31).<br>
> +          uint64_t SH = RightShift ? 32 - ShAmt : ShAmt;<br>
> +          uint64_t MB = RightShift ? ShAmt : 0;<br>
> +          uint64_t ME = RightShift ? 31 : 31 - ShAmt;<br>
> +          MI.getOperand(III.<wbr>ConstantOpNo).<wbr>ChangeToImmediate(SH);<br>
> +          MachineInstrBuilder(*MI.<wbr>getParent()->getParent(), MI).addImm(MB)<br>
> +            .addImm(ME);<br>
> +        } else {<br>
> +          // Left shifts use (N, 63-N), right shifts use (64-N, N).<br>
> +          uint64_t SH = RightShift ? 64 - ShAmt : ShAmt;<br>
> +          uint64_t ME = RightShift ? ShAmt : 63 - ShAmt;<br>
> +          MI.getOperand(III.<wbr>ConstantOpNo).<wbr>ChangeToImmediate(SH);<br>
> +          MachineInstrBuilder(*MI.<wbr>getParent()->getParent(), MI).addImm(ME);<br>
> +        }<br>
> +      }<br>
> +    } else<br>
> +      MI.getOperand(ConstantOpNo).<wbr>ChangeToImmediate(Imm);<br>
> +  }<br>
> +  // Convert commutative instructions (switch the operands and convert the<br>
> +  // desired one to an immediate.<br>
> +  else if (III.IsCommutative) {<br>
> +    MI.getOperand(ConstantOpNo).<wbr>ChangeToImmediate(Imm);<br>
> +    swapMIOperands(MI, ConstantOpNo, III.ConstantOpNo);<br>
> +  } else<br>
> +    llvm_unreachable("Should have exited early!");<br>
> +<br>
> +  // For instructions for which the constant register replaces a different<br>
> +  // operand than where the immediate goes, we need to swap them.<br>
> +  if (III.ConstantOpNo != III.ImmOpNo)<br>
> +    swapMIOperands(MI, III.ConstantOpNo, III.ImmOpNo);<br>
> +<br>
> +  // If the R0/X0 register is special for the original instruction and not for<br>
> +  // the new instruction (or vice versa), we need to fix up the register class.<br>
> +  if (!PostRA && III.ZeroIsSpecialOrig != III.ZeroIsSpecialNew) {<br>
> +    if (!III.ZeroIsSpecialOrig) {<br>
> +      unsigned RegToModify = MI.getOperand(III.<wbr>ZeroIsSpecialNew).getReg();<br>
> +      const TargetRegisterClass *NewRC =<br>
> +        MRI.getRegClass(RegToModify)-><wbr>hasSuperClassEq(&PPC::<wbr>GPRCRegClass) ?<br>
> +        &PPC::GPRC_and_GPRC_<wbr>NOR0RegClass : &PPC::G8RC_and_G8RC_<wbr>NOX0RegClass;<br>
> +      MRI.setRegClass(RegToModify, NewRC);<br>
> +    }<br>
> +  }<br>
> +  return true;<br>
> +}<br>
> +<br>
>  const TargetRegisterClass *<br>
>  PPCInstrInfo::updatedRC(const TargetRegisterClass *RC) const {<br>
>    if (Subtarget.hasVSX() && RC == &PPC::VRRCRegClass)<br>
><br>
> Modified: llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h?rev=320791&r1=320790&r2=320791&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>PowerPC/PPCInstrInfo.h?rev=<wbr>320791&r1=320790&r2=320791&<wbr>view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.h (original)<br>
> +++ llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.h Thu Dec 14 23:27:53 2017<br>
> @@ -72,6 +72,41 @@ enum {<br>
>  };<br>
>  } // end namespace PPCII<br>
><br>
> +// Instructions that have an immediate form might be convertible to that<br>
> +// form if the correct input is a result of a load immediate. In order to<br>
> +// know whether the transformation is special, we might need to know some<br>
> +// of the details of the two forms.<br>
> +struct ImmInstrInfo {<br>
> +  // Is the immediate field in the immediate form signed or unsigned?<br>
> +  uint64_t SignedImm : 1;<br>
> +  // Does the immediate need to be a multiple of some value?<br>
> +  uint64_t ImmMustBeMultipleOf : 5;<br>
> +  // Is R0/X0 treated specially by the original r+r instruction?<br>
> +  // If so, in which operand?<br>
> +  uint64_t ZeroIsSpecialOrig : 3;<br>
> +  // Is R0/X0 treated specially by the new r+i instruction?<br>
> +  // If so, in which operand?<br>
> +  uint64_t ZeroIsSpecialNew : 3;<br>
> +  // Is the operation commutative?<br>
> +  uint64_t IsCommutative : 1;<br>
> +  // The operand number to check for load immediate.<br>
> +  uint64_t ConstantOpNo : 3;<br>
> +  // The operand number for the immediate.<br>
> +  uint64_t ImmOpNo : 3;<br>
> +  // The opcode of the new instruction.<br>
> +  uint64_t ImmOpcode : 16;<br>
> +  // The size of the immediate.<br>
> +  uint64_t ImmWidth : 5;<br>
> +};<br>
> +<br>
> +// Information required to convert an instruction to just a materialized<br>
> +// immediate.<br>
> +struct LoadImmediateInfo {<br>
> +  unsigned Imm : 16;<br>
> +  unsigned Is64Bit : 1;<br>
> +  unsigned SetCR : 1;<br>
> +};<br>
> +<br>
>  class PPCSubtarget;<br>
>  class PPCInstrInfo : public PPCGenInstrInfo {<br>
>    PPCSubtarget &Subtarget;<br>
> @@ -87,6 +122,10 @@ class PPCInstrInfo : public PPCGenInstrI<br>
>                              const TargetRegisterClass *RC,<br>
>                              SmallVectorImpl<MachineInstr *> &NewMIs,<br>
>                              bool &NonRI, bool &SpillsVRS) const;<br>
> +  bool transformToImmForm(<wbr>MachineInstr &MI, const ImmInstrInfo &III,<br>
> +                          unsigned ConstantOpNo, int64_t Imm) const;<br>
> +  MachineInstr *getConstantDefMI(MachineInstr &MI, unsigned &ConstOp,<br>
> +                                 bool &SeenIntermediateUse) const;<br>
>    virtual void anchor();<br>
><br>
>  protected:<br>
> @@ -313,6 +352,19 @@ public:<br>
>    bool isZeroExtended(const MachineInstr &MI, const unsigned depth = 0) const {<br>
>     return isSignOrZeroExtended(MI, false, depth);<br>
>    }<br>
> +<br>
> +  bool convertToImmediateForm(<wbr>MachineInstr &MI,<br>
> +                              MachineInstr **KilledDef = nullptr) const;<br>
> +  void replaceInstrWithLI(<wbr>MachineInstr &MI, const LoadImmediateInfo &LII) const;<br>
> +<br>
> +  // This is used to find the "true" source register for n<br>
> +  // Machine instruction. Returns the original SrcReg unless it is the target<br>
> +  // of a copy-like operation, in which case we chain backwards through all<br>
> +  // such operations to the ultimate source register.  If a<br>
> +  // physical register is encountered, we stop the search.<br>
> +  static unsigned lookThruCopyLike(unsigned SrcReg,<br>
> +                                   const MachineRegisterInfo *MRI);<br>
> +  bool instrHasImmForm(const MachineInstr &MI, ImmInstrInfo &III) const;<br>
>  };<br>
><br>
>  }<br>
><br>
> Modified: llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.td<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td?rev=320791&r1=320790&r2=320791&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>PowerPC/PPCInstrInfo.td?rev=<wbr>320791&r1=320790&r2=320791&<wbr>view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.td (original)<br>
> +++ llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.td Thu Dec 14 23:27:53 2017<br>
> @@ -1590,6 +1590,11 @@ def : Pat<(prefetch xoaddr:$dst, (i32 0)<br>
>            (ICBT 0, xoaddr:$dst)>, Requires<[HasICBT]>; // inst prefetch (for read)<br>
><br>
>  // Atomic operations<br>
> +// FIXME: some of these might be used with constant operands. This will result<br>
> +// in constant materialization instructions that may be redundant. We currently<br>
> +// clean this up in PPCMIPeephole with calls to<br>
> +// PPCInstrInfo::<wbr>convertToImmediateForm() but we should probably not emit them<br>
> +// in the first place.<br>
>  let usesCustomInserter = 1 in {<br>
>    let Defs = [CR0] in {<br>
>      def ATOMIC_LOAD_ADD_I8 : Pseudo<<br>
><br>
> Modified: llvm/trunk/lib/Target/PowerPC/<wbr>PPCMIPeephole.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCMIPeephole.cpp?rev=320791&r1=320790&r2=320791&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>PowerPC/PPCMIPeephole.cpp?rev=<wbr>320791&r1=320790&r2=320791&<wbr>view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Target/PowerPC/<wbr>PPCMIPeephole.cpp (original)<br>
> +++ llvm/trunk/lib/Target/PowerPC/<wbr>PPCMIPeephole.cpp Thu Dec 14 23:27:53 2017<br>
> @@ -41,6 +41,22 @@ STATISTIC(MultiTOCSaves,<br>
>  STATISTIC(NumEliminatedSExt, "Number of eliminated sign-extensions");<br>
>  STATISTIC(NumEliminatedZExt, "Number of eliminated zero-extensions");<br>
>  STATISTIC(NumOptADDLIs, "Number of optimized ADD instruction fed by LI");<br>
> +STATISTIC(<wbr>NumConvertedToImmediateForm,<br>
> +          "Number of instructions converted to their immediate form");<br>
> +STATISTIC(<wbr>NumFunctionsEnteredInMIPeephol<wbr>e,<br>
> +          "Number of functions entered in PPC MI Peepholes");<br>
> +STATISTIC(<wbr>NumFixedPointIterations,<br>
> +          "Number of fixed-point iterations converting reg-reg instructions "<br>
> +          "to reg-imm ones");<br>
> +<br>
> +static cl::opt<bool><br>
> +FixedPointRegToImm("ppc-reg-<wbr>to-imm-fixed-point", cl::Hidden, cl::init(true),<br>
> +                   cl::desc("Iterate to a fixed point when attempting to "<br>
> +                            "convert reg-reg instructions to reg-imm"));<br>
> +<br>
> +static cl::opt<bool><br>
> +ConvertRegReg("ppc-convert-<wbr>rr-to-ri", cl::Hidden, cl::init(true),<br>
> +              cl::desc("Convert eligible reg+reg instructions to reg+imm"));<br>
><br>
>  static cl::opt<bool><br>
>      EnableSExtElimination("ppc-<wbr>eliminate-signext",<br>
> @@ -52,10 +68,6 @@ static cl::opt<bool><br>
>                            cl::desc("enable elimination of zero-extensions"),<br>
>                            cl::init(false), cl::Hidden);<br>
><br>
> -namespace llvm {<br>
> -  void initializePPCMIPeepholePass(<wbr>PassRegistry&);<br>
> -}<br>
> -<br>
>  namespace {<br>
><br>
>  struct PPCMIPeephole : public MachineFunctionPass {<br>
> @@ -83,9 +95,6 @@ private:<br>
>    bool eliminateRedundantTOCSaves(<wbr>std::map<MachineInstr *, bool> &TOCSaves);<br>
>    void UpdateTOCSaves(std::map<<wbr>MachineInstr *, bool> &TOCSaves,<br>
>                        MachineInstr *MI);<br>
> -  // Find the "true" register represented by SrcReg (following chains<br>
> -  // of copies and subreg_to_reg operations).<br>
> -  unsigned lookThruCopyLike(unsigned SrcReg);<br>
><br>
>  public:<br>
><br>
> @@ -212,6 +221,35 @@ bool PPCMIPeephole::simplifyCode(<wbr>void) {<br>
>    MachineInstr* ToErase = nullptr;<br>
>    std::map<MachineInstr *, bool> TOCSaves;<br>
><br>
> +  NumFunctionsEnteredInMIPeephol<wbr>e++;<br>
> +  if (ConvertRegReg) {<br>
> +    // Fixed-point conversion of reg/reg instructions fed by load-immediate<br>
> +    // into reg/imm instructions. FIXME: This is expensive, control it with<br>
> +    // an option.<br>
> +    bool SomethingChanged = false;<br>
> +    do {<br>
> +      NumFixedPointIterations++;<br>
> +      SomethingChanged = false;<br>
> +      for (MachineBasicBlock &MBB : *MF) {<br>
> +        for (MachineInstr &MI : MBB) {<br>
> +          if (MI.isDebugValue())<br>
> +            continue;<br>
> +<br>
> +          if (TII->convertToImmediateForm(<wbr>MI)) {<br>
> +            // We don't erase anything in case the def has other uses. Let DCE<br>
> +            // remove it if it can be removed.<br>
> +            DEBUG(dbgs() << "Converted instruction to imm form: ");<br>
> +            DEBUG(MI.dump());<br>
> +            NumConvertedToImmediateForm++;<br>
> +            SomethingChanged = true;<br>
> +            Simplified = true;<br>
> +            continue;<br>
> +          }<br>
> +        }<br>
> +      }<br>
> +    } while (SomethingChanged && FixedPointRegToImm);<br>
> +  }<br>
> +<br>
>    for (MachineBasicBlock &MBB : *MF) {<br>
>      for (MachineInstr &MI : MBB) {<br>
><br>
> @@ -258,8 +296,10 @@ bool PPCMIPeephole::simplifyCode(<wbr>void) {<br>
>            //   XXPERMDI t, SUBREG_TO_REG(s), SUBREG_TO_REG(s), immed.<br>
>            // We have to look through chains of COPY and SUBREG_TO_REG<br>
>            // to find the real source values for comparison.<br>
> -          unsigned TrueReg1 = lookThruCopyLike(MI.<wbr>getOperand(1).getReg());<br>
> -          unsigned TrueReg2 = lookThruCopyLike(MI.<wbr>getOperand(2).getReg());<br>
> +          unsigned TrueReg1 =<br>
> +            TII->lookThruCopyLike(MI.<wbr>getOperand(1).getReg(), MRI);<br>
> +          unsigned TrueReg2 =<br>
> +            TII->lookThruCopyLike(MI.<wbr>getOperand(2).getReg(), MRI);<br>
><br>
>            if (TrueReg1 == TrueReg2<br>
>                && TargetRegisterInfo::<wbr>isVirtualRegister(TrueReg1)) {<br>
> @@ -273,7 +313,8 @@ bool PPCMIPeephole::simplifyCode(<wbr>void) {<br>
>              auto isConversionOfLoadAndSplat = [=]() -> bool {<br>
>                if (DefOpc != PPC::XVCVDPSXDS && DefOpc != PPC::XVCVDPUXDS)<br>
>                  return false;<br>
> -              unsigned DefReg = lookThruCopyLike(DefMI-><wbr>getOperand(1).getReg());<br>
> +              unsigned DefReg =<br>
> +                TII->lookThruCopyLike(DefMI-><wbr>getOperand(1).getReg(), MRI);<br>
>                if (TargetRegisterInfo::<wbr>isVirtualRegister(DefReg)) {<br>
>                  MachineInstr *LoadMI = MRI->getVRegDef(DefReg);<br>
>                  if (LoadMI && LoadMI->getOpcode() == PPC::LXVDSX)<br>
> @@ -299,10 +340,10 @@ bool PPCMIPeephole::simplifyCode(<wbr>void) {<br>
>              // can replace it with a copy.<br>
>              if (DefOpc == PPC::XXPERMDI) {<br>
>                unsigned FeedImmed = DefMI->getOperand(3).getImm();<br>
> -              unsigned FeedReg1<br>
> -                = lookThruCopyLike(DefMI-><wbr>getOperand(1).getReg());<br>
> -              unsigned FeedReg2<br>
> -                = lookThruCopyLike(DefMI-><wbr>getOperand(2).getReg());<br>
> +              unsigned FeedReg1 =<br>
> +                TII->lookThruCopyLike(DefMI-><wbr>getOperand(1).getReg(), MRI);<br>
> +              unsigned FeedReg2 =<br>
> +                TII->lookThruCopyLike(DefMI-><wbr>getOperand(2).getReg(), MRI);<br>
><br>
>                if ((FeedImmed == 0 || FeedImmed == 3) && FeedReg1 == FeedReg2) {<br>
>                  DEBUG(dbgs()<br>
> @@ -360,7 +401,8 @@ bool PPCMIPeephole::simplifyCode(<wbr>void) {<br>
>        case PPC::XXSPLTW: {<br>
>          unsigned MyOpcode = MI.getOpcode();<br>
>          unsigned OpNo = MyOpcode == PPC::XXSPLTW ? 1 : 2;<br>
> -        unsigned TrueReg = lookThruCopyLike(MI.<wbr>getOperand(OpNo).getReg());<br>
> +        unsigned TrueReg =<br>
> +          TII->lookThruCopyLike(MI.<wbr>getOperand(OpNo).getReg(), MRI);<br>
>          if (!TargetRegisterInfo::<wbr>isVirtualRegister(TrueReg))<br>
>            break;<br>
>          MachineInstr *DefMI = MRI->getVRegDef(TrueReg);<br>
> @@ -422,7 +464,8 @@ bool PPCMIPeephole::simplifyCode(<wbr>void) {<br>
>        }<br>
>        case PPC::XVCVDPSP: {<br>
>          // If this is a DP->SP conversion fed by an FRSP, the FRSP is redundant.<br>
> -        unsigned TrueReg = lookThruCopyLike(MI.<wbr>getOperand(1).getReg());<br>
> +        unsigned TrueReg =<br>
> +          TII->lookThruCopyLike(MI.<wbr>getOperand(1).getReg(), MRI);<br>
>          if (!TargetRegisterInfo::<wbr>isVirtualRegister(TrueReg))<br>
>            break;<br>
>          MachineInstr *DefMI = MRI->getVRegDef(TrueReg);<br>
> @@ -430,8 +473,10 @@ bool PPCMIPeephole::simplifyCode(<wbr>void) {<br>
>          // This can occur when building a vector of single precision or integer<br>
>          // values.<br>
>          if (DefMI && DefMI->getOpcode() == PPC::XXPERMDI) {<br>
> -          unsigned DefsReg1 = lookThruCopyLike(DefMI-><wbr>getOperand(1).getReg());<br>
> -          unsigned DefsReg2 = lookThruCopyLike(DefMI-><wbr>getOperand(2).getReg());<br>
> +          unsigned DefsReg1 =<br>
> +            TII->lookThruCopyLike(DefMI-><wbr>getOperand(1).getReg(), MRI);<br>
> +          unsigned DefsReg2 =<br>
> +            TII->lookThruCopyLike(DefMI-><wbr>getOperand(2).getReg(), MRI);<br>
>            if (!TargetRegisterInfo::<wbr>isVirtualRegister(DefsReg1) ||<br>
>                !TargetRegisterInfo::<wbr>isVirtualRegister(DefsReg2))<br>
>              break;<br>
> @@ -1221,36 +1266,6 @@ bool PPCMIPeephole::<wbr>eliminateRedundantCo<br>
>    return Simplified;<br>
>  }<br>
><br>
> -// This is used to find the "true" source register for an<br>
> -// XXPERMDI instruction, since MachineCSE does not handle the<br>
> -// "copy-like" operations (Copy and SubregToReg).  Returns<br>
> -// the original SrcReg unless it is the target of a copy-like<br>
> -// operation, in which case we chain backwards through all<br>
> -// such operations to the ultimate source register.  If a<br>
> -// physical register is encountered, we stop the search.<br>
> -unsigned PPCMIPeephole::<wbr>lookThruCopyLike(unsigned SrcReg) {<br>
> -<br>
> -  while (true) {<br>
> -<br>
> -    MachineInstr *MI = MRI->getVRegDef(SrcReg);<br>
> -    if (!MI->isCopyLike())<br>
> -      return SrcReg;<br>
> -<br>
> -    unsigned CopySrcReg;<br>
> -    if (MI->isCopy())<br>
> -      CopySrcReg = MI->getOperand(1).getReg();<br>
> -    else {<br>
> -      assert(MI->isSubregToReg() && "bad opcode for lookThruCopyLike");<br>
> -      CopySrcReg = MI->getOperand(2).getReg();<br>
> -    }<br>
> -<br>
> -    if (!TargetRegisterInfo::<wbr>isVirtualRegister(CopySrcReg))<br>
> -      return CopySrcReg;<br>
> -<br>
> -    SrcReg = CopySrcReg;<br>
> -  }<br>
> -}<br>
> -<br>
>  } // end default namespace<br>
><br>
>  INITIALIZE_PASS_BEGIN(<wbr>PPCMIPeephole, DEBUG_TYPE,<br>
><br>
> Added: llvm/trunk/lib/Target/PowerPC/<wbr>PPCPreEmitPeephole.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCPreEmitPeephole.cpp?rev=320791&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>PowerPC/PPCPreEmitPeephole.<wbr>cpp?rev=320791&view=auto</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Target/PowerPC/<wbr>PPCPreEmitPeephole.cpp (added)<br>
> +++ llvm/trunk/lib/Target/PowerPC/<wbr>PPCPreEmitPeephole.cpp Thu Dec 14 23:27:53 2017<br>
> @@ -0,0 +1,95 @@<br>
> +//===--------- PPCPreEmitPeephole.cpp - Late peephole optimizations -------===//<br>
> +//<br>
> +//                     The LLVM Compiler Infrastructure<br>
> +//<br>
> +// This file is distributed under the University of Illinois Open Source<br>
> +// License. See LICENSE.TXT for details.<br>
> +//<br>
> +//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
> +//<br>
> +// A pre-emit peephole for catching opportunities introduced by late passes such<br>
> +// as MachineBlockPlacement.<br>
> +//<br>
> +//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
> +<br>
> +#include "PPC.h"<br>
> +#include "PPCInstrInfo.h"<br>
> +#include "PPCSubtarget.h"<br>
> +#include "llvm/ADT/DenseMap.h"<br>
> +#include "llvm/ADT/Statistic.h"<br>
> +#include "llvm/CodeGen/LivePhysRegs.h"<br>
> +#include "llvm/CodeGen/<wbr>MachineFunctionPass.h"<br>
> +#include "llvm/CodeGen/<wbr>MachineInstrBuilder.h"<br>
> +#include "llvm/CodeGen/<wbr>MachineRegisterInfo.h"<br>
> +#include "llvm/Support/CommandLine.h"<br>
> +#include "llvm/ADT/Statistic.h"<br>
> +#include "llvm/Support/Debug.h"<br>
> +<br>
> +using namespace llvm;<br>
> +<br>
> +#define DEBUG_TYPE "ppc-pre-emit-peephole"<br>
> +<br>
> +STATISTIC(<wbr>NumRRConvertedInPreEmit,<br>
> +          "Number of r+r instructions converted to r+i in pre-emit peephole");<br>
> +STATISTIC(<wbr>NumRemovedInPreEmit,<br>
> +          "Number of instructions deleted in pre-emit peephole");<br>
> +<br>
> +static cl::opt<bool><br>
> +RunPreEmitPeephole("ppc-late-<wbr>peephole", cl::Hidden, cl::init(true),<br>
> +                   cl::desc("Run pre-emit peephole optimizations."));<br>
> +<br>
> +namespace {<br>
> +  class PPCPreEmitPeephole : public MachineFunctionPass {<br>
> +  public:<br>
> +    static char ID;<br>
> +    PPCPreEmitPeephole() : MachineFunctionPass(ID) {<br>
> +      initializePPCPreEmitPeepholePa<wbr>ss(*PassRegistry::<wbr>getPassRegistry());<br>
> +    }<br>
> +<br>
> +    void getAnalysisUsage(AnalysisUsage &AU) const override {<br>
> +      MachineFunctionPass::<wbr>getAnalysisUsage(AU);<br>
> +    }<br>
> +<br>
> +    MachineFunctionProperties getRequiredProperties() const override {<br>
> +      return MachineFunctionProperties().<wbr>set(<br>
> +          MachineFunctionProperties::<wbr>Property::NoVRegs);<br>
> +    }<br>
> +<br>
> +    bool runOnMachineFunction(<wbr>MachineFunction &MF) override {<br>
> +      if (skipFunction(*MF.getFunction(<wbr>)) || !RunPreEmitPeephole)<br>
> +        return false;<br>
> +      bool Changed = false;<br>
> +      const PPCInstrInfo *TII = MF.getSubtarget<PPCSubtarget>(<wbr>).getInstrInfo();<br>
> +      SmallVector<MachineInstr *, 4> InstrsToErase;<br>
> +      for (MachineBasicBlock &MBB : MF) {<br>
> +        for (MachineInstr &MI : MBB) {<br>
> +          MachineInstr *DefMIToErase = nullptr;<br>
> +          if (TII->convertToImmediateForm(<wbr>MI, &DefMIToErase)) {<br>
> +            Changed = true;<br>
> +            NumRRConvertedInPreEmit++;<br>
> +            DEBUG(dbgs() << "Converted instruction to imm form: ");<br>
> +            DEBUG(MI.dump());<br>
> +            if (DefMIToErase) {<br>
> +              InstrsToErase.push_back(<wbr>DefMIToErase);<br>
> +            }<br>
> +          }<br>
> +        }<br>
> +      }<br>
> +      for (MachineInstr *MI : InstrsToErase) {<br>
> +        DEBUG(dbgs() << "PPC pre-emit peephole: erasing instruction: ");<br>
> +        DEBUG(MI->dump());<br>
> +        MI->eraseFromParent();<br>
> +        NumRemovedInPreEmit++;<br>
> +      }<br>
> +      return Changed;<br>
> +    }<br>
> +  };<br>
> +}<br>
> +<br>
> +INITIALIZE_PASS(<wbr>PPCPreEmitPeephole, DEBUG_TYPE, "PowerPC Pre-Emit Peephole",<br>
> +                false, false)<br>
> +char PPCPreEmitPeephole::ID = 0;<br>
> +<br>
> +FunctionPass *llvm::<wbr>createPPCPreEmitPeepholePass() {<br>
> +  return new PPCPreEmitPeephole();<br>
> +}<br>
><br>
> Modified: llvm/trunk/lib/Target/PowerPC/<wbr>PPCTargetMachine.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp?rev=320791&r1=320790&r2=320791&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>PowerPC/PPCTargetMachine.cpp?<wbr>rev=320791&r1=320790&r2=<wbr>320791&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Target/PowerPC/<wbr>PPCTargetMachine.cpp (original)<br>
> +++ llvm/trunk/lib/Target/PowerPC/<wbr>PPCTargetMachine.cpp Thu Dec 14 23:27:53 2017<br>
> @@ -101,7 +101,9 @@ extern "C" void LLVMInitializePowerPCTar<br>
>    PassRegistry &PR = *PassRegistry::<wbr>getPassRegistry();<br>
>    initializePPCBoolRetToIntPass(<wbr>PR);<br>
>    initializePPCExpandISELPass(<wbr>PR);<br>
> +  initializePPCPreEmitPeepholePa<wbr>ss(PR);<br>
>    initializePPCTLSDynamicCallPas<wbr>s(PR);<br>
> +  initializePPCMIPeepholePass(<wbr>PR);<br>
>  }<br>
><br>
>  /// Return the datalayout string of a subtarget.<br>
> @@ -440,6 +442,7 @@ void PPCPassConfig::addPreSched2() {<br>
>  }<br>
><br>
>  void PPCPassConfig::addPreEmitPass(<wbr>) {<br>
> +  addPass(<wbr>createPPCPreEmitPeepholePass()<wbr>);<br>
>    addPass(<wbr>createPPCExpandISELPass());<br>
><br>
>    if (getOptLevel() != CodeGenOpt::None)<br>
><br>
> Modified: llvm/trunk/test/CodeGen/<wbr>PowerPC/build-vector-tests.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/build-vector-tests.ll?rev=320791&r1=320790&r2=320791&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>CodeGen/PowerPC/build-vector-<wbr>tests.ll?rev=320791&r1=320790&<wbr>r2=320791&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/test/CodeGen/<wbr>PowerPC/build-vector-tests.ll (original)<br>
> +++ llvm/trunk/test/CodeGen/<wbr>PowerPC/build-vector-tests.ll Thu Dec 14 23:27:53 2017<br>
> @@ -3508,13 +3508,13 @@ entry:<br>
>  ; P9LE: xxmrghd<br>
>  ; P9LE-NEXT: xvcvdpsxds v2<br>
>  ; P9LE-NEXT: blr<br>
> -; P8BE: lfsx<br>
> -; P8BE: lfsx<br>
> +; P8BE: lfs<br>
> +; P8BE: lfs<br>
>  ; P8BE: xxmrghd<br>
>  ; P8BE-NEXT: xvcvdpsxds v2<br>
>  ; P8BE-NEXT: blr<br>
> -; P8LE: lfsx<br>
> -; P8LE: lfsx<br>
> +; P8LE: lfs<br>
> +; P8LE: lfs<br>
>  ; P8LE: xxmrghd<br>
>  ; P8LE-NEXT: xvcvdpsxds v2<br>
>  ; P8LE-NEXT: blr<br>
> @@ -3546,13 +3546,13 @@ entry:<br>
>  ; P9LE: xxmrghd<br>
>  ; P9LE-NEXT: xvcvdpsxds v2<br>
>  ; P9LE-NEXT: blr<br>
> -; P8BE: lfsx<br>
> -; P8BE: lfsx<br>
> +; P8BE: lfs<br>
> +; P8BE: lfs<br>
>  ; P8BE: xxmrghd<br>
>  ; P8BE-NEXT: xvcvdpsxds v2<br>
>  ; P8BE-NEXT: blr<br>
> -; P8LE: lfsx<br>
> -; P8LE: lfsx<br>
> +; P8LE: lfs<br>
> +; P8LE: lfs<br>
>  ; P8LE: xxmrghd<br>
>  ; P8LE-NEXT: xvcvdpsxds v2<br>
>  ; P8LE-NEXT: blr<br>
> @@ -3591,13 +3591,13 @@ entry:<br>
>  ; P9LE-NEXT: blr<br>
>  ; P8BE: sldi<br>
>  ; P8BE: lfsux<br>
> -; P8BE: lfsx<br>
> +; P8BE: lfs<br>
>  ; P8BE: xxmrghd<br>
>  ; P8BE-NEXT: xvcvdpsxds v2<br>
>  ; P8BE-NEXT: blr<br>
>  ; P8LE: sldi<br>
>  ; P8LE: lfsux<br>
> -; P8LE: lfsx<br>
> +; P8LE: lfs<br>
>  ; P8LE: xxmrghd<br>
>  ; P8LE-NEXT: xvcvdpsxds v2<br>
>  ; P8LE-NEXT: blr<br>
> @@ -3636,13 +3636,13 @@ entry:<br>
>  ; P9LE-NEXT: blr<br>
>  ; P8BE: sldi<br>
>  ; P8BE: lfsux<br>
> -; P8BE: lfsx<br>
> +; P8BE: lfs<br>
>  ; P8BE: xxmrghd<br>
>  ; P8BE-NEXT: xvcvdpsxds v2<br>
>  ; P8BE-NEXT: blr<br>
>  ; P8LE: sldi<br>
>  ; P8LE: lfsux<br>
> -; P8LE: lfsx<br>
> +; P8LE: lfs<br>
>  ; P8LE: xxmrghd<br>
>  ; P8LE-NEXT: xvcvdpsxds v2<br>
>  ; P8LE-NEXT: blr<br>
> @@ -3693,11 +3693,11 @@ entry:<br>
>  ; P9LE-NEXT: xscvdpsxds<br>
>  ; P9LE-NEXT: xxspltd v2<br>
>  ; P9LE-NEXT: blr<br>
> -; P8BE: lfsx<br>
> +; P8BE: lfs<br>
>  ; P8BE-NEXT: xscvdpsxds<br>
>  ; P8BE-NEXT: xxspltd v2<br>
>  ; P8BE-NEXT: blr<br>
> -; P8LE: lfsx<br>
> +; P8LE: lfs<br>
>  ; P8LE-NEXT: xscvdpsxds<br>
>  ; P8LE-NEXT: xxspltd v2<br>
>  ; P8LE-NEXT: blr<br>
> @@ -4412,13 +4412,13 @@ entry:<br>
>  ; P9LE: xxmrghd<br>
>  ; P9LE-NEXT: xvcvdpuxds v2<br>
>  ; P9LE-NEXT: blr<br>
> -; P8BE: lfsx<br>
> -; P8BE: lfsx<br>
> +; P8BE: lfs<br>
> +; P8BE: lfs<br>
>  ; P8BE: xxmrghd<br>
>  ; P8BE-NEXT: xvcvdpuxds v2<br>
>  ; P8BE-NEXT: blr<br>
> -; P8LE: lfsx<br>
> -; P8LE: lfsx<br>
> +; P8LE: lfs<br>
> +; P8LE: lfs<br>
>  ; P8LE: xxmrghd<br>
>  ; P8LE-NEXT: xvcvdpuxds v2<br>
>  ; P8LE-NEXT: blr<br>
> @@ -4450,13 +4450,13 @@ entry:<br>
>  ; P9LE: xxmrghd<br>
>  ; P9LE-NEXT: xvcvdpuxds v2<br>
>  ; P9LE-NEXT: blr<br>
> -; P8BE: lfsx<br>
> -; P8BE: lfsx<br>
> +; P8BE: lfs<br>
> +; P8BE: lfs<br>
>  ; P8BE: xxmrghd<br>
>  ; P8BE-NEXT: xvcvdpuxds v2<br>
>  ; P8BE-NEXT: blr<br>
> -; P8LE: lfsx<br>
> -; P8LE: lfsx<br>
> +; P8LE: lfs<br>
> +; P8LE: lfs<br>
>  ; P8LE: xxmrghd<br>
>  ; P8LE-NEXT: xvcvdpuxds v2<br>
>  ; P8LE-NEXT: blr<br>
> @@ -4495,13 +4495,13 @@ entry:<br>
>  ; P9LE-NEXT: blr<br>
>  ; P8BE: sldi<br>
>  ; P8BE: lfsux<br>
> -; P8BE: lfsx<br>
> +; P8BE: lfs<br>
>  ; P8BE: xxmrghd<br>
>  ; P8BE-NEXT: xvcvdpuxds v2<br>
>  ; P8BE-NEXT: blr<br>
>  ; P8LE: sldi<br>
>  ; P8LE: lfsux<br>
> -; P8LE: lfsx<br>
> +; P8LE: lfs<br>
>  ; P8LE: xxmrghd<br>
>  ; P8LE-NEXT: xvcvdpuxds v2<br>
>  ; P8LE-NEXT: blr<br>
> @@ -4540,13 +4540,13 @@ entry:<br>
>  ; P9LE-NEXT: blr<br>
>  ; P8BE: sldi<br>
>  ; P8BE: lfsux<br>
> -; P8BE: lfsx<br>
> +; P8BE: lfs<br>
>  ; P8BE: xxmrghd<br>
>  ; P8BE-NEXT: xvcvdpuxds v2<br>
>  ; P8BE-NEXT: blr<br>
>  ; P8LE: sldi<br>
>  ; P8LE: lfsux<br>
> -; P8LE: lfsx<br>
> +; P8LE: lfs<br>
>  ; P8LE: xxmrghd<br>
>  ; P8LE-NEXT: xvcvdpuxds v2<br>
>  ; P8LE-NEXT: blr<br>
> @@ -4597,11 +4597,11 @@ entry:<br>
>  ; P9LE-NEXT: xscvdpuxds<br>
>  ; P9LE-NEXT: xxspltd v2<br>
>  ; P9LE-NEXT: blr<br>
> -; P8BE: lfsx<br>
> +; P8BE: lfs<br>
>  ; P8BE-NEXT: xscvdpuxds<br>
>  ; P8BE-NEXT: xxspltd v2<br>
>  ; P8BE-NEXT: blr<br>
> -; P8LE: lfsx<br>
> +; P8LE: lfs<br>
>  ; P8LE-NEXT: xscvdpuxds<br>
>  ; P8LE-NEXT: xxspltd v2<br>
>  ; P8LE-NEXT: blr<br>
><br>
> Added: llvm/trunk/test/CodeGen/<wbr>PowerPC/convert-rr-to-ri-<wbr>instrs-R0-special-handling.mir<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/convert-rr-to-ri-instrs-R0-special-handling.mir?rev=320791&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>CodeGen/PowerPC/convert-rr-to-<wbr>ri-instrs-R0-special-handling.<wbr>mir?rev=320791&view=auto</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/test/CodeGen/<wbr>PowerPC/convert-rr-to-ri-<wbr>instrs-R0-special-handling.mir (added)<br>
> +++ llvm/trunk/test/CodeGen/<wbr>PowerPC/convert-rr-to-ri-<wbr>instrs-R0-special-handling.mir Thu Dec 14 23:27:53 2017<br>
> @@ -0,0 +1,436 @@<br>
> +# RUN: llc -start-after ppc-mi-peepholes -ppc-late-peephole %s -o - | FileCheck %s<br>
> +--- |<br>
> +  ; ModuleID = 'a.ll'<br>
> +  source_filename = "a.c"<br>
> +  target datalayout = "e-m:e-i64:64-n32:64"<br>
> +  target triple = "powerpc64le-unknown-linux-<wbr>gnu"<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @unsafeAddR0R3(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %add = add nsw i32 %b, %a<br>
> +    ret i32 %add<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @unsafeAddR3R0(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %add = add nsw i32 %b, %a<br>
> +    ret i32 %add<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @safeAddR0R3(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %add = add nsw i32 %b, %a<br>
> +    ret i32 %add<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @safeAddR3R0(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %add = add nsw i32 %b, %a<br>
> +    ret i32 %add<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define i64 @unsafeLDXR3R0(i64* nocapture readonly %ptr, i64 %off) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %0 = bitcast i64* %ptr to i8*<br>
> +    %add.ptr = getelementptr inbounds i8, i8* %0, i64 %off<br>
> +    %1 = bitcast i8* %add.ptr to i64*<br>
> +    %2 = load i64, i64* %1, align 8, !tbaa !3<br>
> +    ret i64 %2<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define i64 @safeLDXZeroR3(i64* nocapture readonly %ptr, i64 %off) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %0 = bitcast i64* %ptr to i8*<br>
> +    %add.ptr = getelementptr inbounds i8, i8* %0, i64 %off<br>
> +    %1 = bitcast i8* %add.ptr to i64*<br>
> +    %2 = load i64, i64* %1, align 8, !tbaa !3<br>
> +    ret i64 %2<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define i64 @safeLDXR3R0(i64* nocapture readonly %ptr, i64 %off) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %0 = bitcast i64* %ptr to i8*<br>
> +    %add.ptr = getelementptr inbounds i8, i8* %0, i64 %off<br>
> +    %1 = bitcast i8* %add.ptr to i64*<br>
> +    %2 = load i64, i64* %1, align 8, !tbaa !3<br>
> +    ret i64 %2<br>
> +  }<br>
> +<br>
> +  attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-<wbr>sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="<wbr>false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="<wbr>false" "no-trapping-math"="false" "stack-protector-buffer-size"=<wbr>"8" "target-cpu"="ppc64le" "target-features"="+altivec,+<wbr>bpermd,+crypto,+direct-move,+<wbr>extdiv,+htm,+power8-vector,+<wbr>vsx,-power9-vector,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
> +  attributes #1 = { norecurse nounwind readonly "correctly-rounded-divide-<wbr>sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="<wbr>false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="<wbr>false" "no-trapping-math"="false" "stack-protector-buffer-size"=<wbr>"8" "target-cpu"="ppc64le" "target-features"="+altivec,+<wbr>bpermd,+crypto,+direct-move,+<wbr>extdiv,+htm,+power8-vector,+<wbr>vsx,-power9-vector,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
> +<br>
> +  !llvm.module.flags = !{!0, !1}<br>
> +  !llvm.ident = !{!2}<br>
> +<br>
> +  !0 = !{i32 1, !"wchar_size", i32 4}<br>
> +  !1 = !{i32 7, !"PIC Level", i32 2}<br>
> +  !2 = !{!"clang version 6.0.0 (trunk 318832)"}<br>
> +  !3 = !{!4, !4, i64 0}<br>
> +  !4 = !{!"long long", !5, i64 0}<br>
> +  !5 = !{!"omnipotent char", !6, i64 0}<br>
> +  !6 = !{!"Simple C/C++ TBAA"}<br>
> +<br>
> +...<br>
> +---<br>
> +name:            unsafeAddR0R3<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: gprc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x0, %x4<br>
> +<br>
> +    %1:g8rc = COPY %x4<br>
> +    %0:g8rc = COPY %x0<br>
> +    %2:gprc = LI 44<br>
> +    %3:gprc = COPY %1.sub_32<br>
> +    %4:gprc = ADD4 killed %r0, killed %2<br>
> +    ; CHECK: li 3, 44<br>
> +    ; CHECK: add 3, 0, 3<br>
> +    %5:g8rc = EXTSW_32_64 killed %4<br>
> +    %x3 = COPY %5<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            unsafeAddR3R0<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: gprc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x0, %x4<br>
> +<br>
> +    %1:g8rc = COPY %x4<br>
> +    %0:g8rc = COPY %x0<br>
> +    %2:gprc = COPY %0.sub_32<br>
> +    %3:gprc = LI 44<br>
> +    %4:gprc = ADD4 killed %3, killed %r0<br>
> +    ; CHECK: li 3, 44<br>
> +    ; CHECK: add 3, 3, 0<br>
> +    %5:g8rc = EXTSW_32_64 killed %4<br>
> +    %x3 = COPY %5<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            safeAddR0R3<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: gprc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1:g8rc = COPY %x4<br>
> +    %0:g8rc = COPY %x3<br>
> +    %2:gprc = COPY %0.sub_32<br>
> +    %r0 = LI 44<br>
> +    %4:gprc = ADD4 killed %r0, killed %2<br>
> +    ; CHECK: addi 3, 3, 44<br>
> +    %5:g8rc = EXTSW_32_64 killed %4<br>
> +    %x3 = COPY %5<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            safeAddR3R0<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: gprc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1:g8rc = COPY %x4<br>
> +    %0:g8rc = COPY %x3<br>
> +    %2:gprc = COPY %0.sub_32<br>
> +    %r0 = LI 44<br>
> +    %4:gprc = ADD4 killed %2, killed %r0<br>
> +    ; CHECK: addi 3, 3, 44<br>
> +    %5:g8rc = EXTSW_32_64 killed %4<br>
> +    %x3 = COPY %5<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            unsafeLDXR3R0<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x0', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x0, %x4<br>
> +<br>
> +    %1:g8rc = COPY %x4<br>
> +    %0:g8rc_and_g8rc_nox0 = LI8 44<br>
> +    %2:g8rc = LDX %0, %x0 :: (load 8 from %ir.1, !tbaa !3)<br>
> +    ; CHECK: li 3, 44<br>
> +    ; CHECK: ldx 3, 3, 0<br>
> +    %x3 = COPY %2<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            safeLDXZeroR3<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1:g8rc = LI8 44<br>
> +    %0:g8rc_and_g8rc_nox0 = LI8 44<br>
> +    %2:g8rc = LDX %zero8, %1 :: (load 8 from %ir.1, !tbaa !3)<br>
> +    ; CHECK: ld 3, 44(0)<br>
> +    %x3 = COPY %2<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            safeLDXR3R0<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %x0 = LI8 44<br>
> +    %0:g8rc_and_g8rc_nox0 = COPY %x3<br>
> +    %2:g8rc = LDX %0, %x0 :: (load 8 from %ir.1, !tbaa !3)<br>
> +    ; CHECK: ld 3, 44(3)<br>
> +    %x3 = COPY %2<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
><br>
> Added: llvm/trunk/test/CodeGen/<wbr>PowerPC/convert-rr-to-ri-<wbr>instrs.mir<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir?rev=320791&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>CodeGen/PowerPC/convert-rr-to-<wbr>ri-instrs.mir?rev=320791&view=<wbr>auto</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/test/CodeGen/<wbr>PowerPC/convert-rr-to-ri-<wbr>instrs.mir (added)<br>
> +++ llvm/trunk/test/CodeGen/<wbr>PowerPC/convert-rr-to-ri-<wbr>instrs.mir Thu Dec 14 23:27:53 2017<br>
> @@ -0,0 +1,6129 @@<br>
> +# RUN: llc -run-pass ppc-mi-peepholes -ppc-convert-rr-to-ri %s -o - | FileCheck %s<br>
> +# RUN: llc -start-after ppc-mi-peepholes -ppc-late-peephole %s -o - | FileCheck %s --check-prefix=CHECK-LATE<br>
> +<br>
> +--- |<br>
> +  ; ModuleID = 'convert-rr-to-ri-instrs.ll'<br>
> +  source_filename = "convert-rr-to-ri-instrs.c"<br>
> +  target datalayout = "e-m:e-i64:64-n32:64"<br>
> +  target triple = "powerpc64le-unknown-linux-<wbr>gnu"<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @testADD4(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %add = add nsw i32 %a, 33<br>
> +    %add1 = add nsw i32 %add, %b<br>
> +    ret i32 %add1<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testADD8(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %add = add nsw i64 %a, 33<br>
> +    %add1 = add nsw i64 %add, %b<br>
> +    ret i64 %add1<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i128 @testADDC(i128 %a, i128 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %add = add nsw i128 %b, %a<br>
> +    ret i128 %add<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i128 @testADDC8(i128 %a, i128 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %add = add nsw i128 %b, %a<br>
> +    ret i128 %add<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testADDCo(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %add = add nsw i64 %b, %a<br>
> +    %cmp = icmp eq i64 %add, 0<br>
> +    %neg = sext i1 %cmp to i64<br>
> +    %retval.0 = xor i64 %add, %neg<br>
> +    ret i64 %retval.0<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @testADDI(i32 signext %a) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %add = add nsw i32 %a, 44<br>
> +    ret i32 %add<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @testADDI8(i32 signext %a) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %add = add nsw i32 %a, 44<br>
> +    ret i32 %add<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @testANDo(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %and = and i64 %b, %a<br>
> +    %tobool = icmp eq i64 %and, 0<br>
> +    %cond = select i1 %tobool, i64 %b, i64 %a<br>
> +    %conv = trunc i64 %cond to i32<br>
> +    ret i32 %conv<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testAND8o(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %and = and i64 %b, %a<br>
> +    %tobool = icmp eq i64 %and, 0<br>
> +    %cond = select i1 %tobool, i64 %b, i64 %a<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testCMPD(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %cmp = icmp sgt i64 %a, %b<br>
> +    %add = select i1 %cmp, i64 0, i64 %a<br>
> +    %cond = add nsw i64 %add, %b<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testCMPDI(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %cmp = icmp sgt i64 %a, 87<br>
> +    %add = select i1 %cmp, i64 0, i64 %a<br>
> +    %cond = add nsw i64 %add, %b<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testCMPDI_F(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %cmp = icmp sgt i64 %a, 87<br>
> +    %add = select i1 %cmp, i64 0, i64 %a<br>
> +    %cond = add nsw i64 %add, %b<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testCMPLD(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %cmp = icmp ugt i64 %a, %b<br>
> +    %add = select i1 %cmp, i64 0, i64 %a<br>
> +    %cond = add i64 %add, %b<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testCMPLDI(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %cmp = icmp ugt i64 %a, 87<br>
> +    %add = select i1 %cmp, i64 0, i64 %a<br>
> +    %cond = add i64 %add, %b<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @testCMPW(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %cmp = icmp sgt i32 %a, %b<br>
> +    %add = select i1 %cmp, i32 0, i32 %a<br>
> +    %cond = add nsw i32 %add, %b<br>
> +    ret i32 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @testCMPWI(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %cmp = icmp sgt i32 %a, 87<br>
> +    %add = select i1 %cmp, i32 0, i32 %a<br>
> +    %cond = add nsw i32 %add, %b<br>
> +    ret i32 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define zeroext i32 @testCMPLW(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %cmp = icmp ugt i32 %a, %b<br>
> +    %add = select i1 %cmp, i32 0, i32 %a<br>
> +    %cond = add i32 %add, %b<br>
> +    ret i32 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define zeroext i32 @testCMPLWI(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %cmp = icmp ugt i32 %a, 87<br>
> +    %add = select i1 %cmp, i32 0, i32 %a<br>
> +    %cond = add i32 %add, %b<br>
> +    ret i32 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define zeroext i8 @testLBZUX(i8* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i8, i8* %ptr, i64 %idxprom<br>
> +    %0 = load i8, i8* %arrayidx, align 1, !tbaa !3<br>
> +    %conv = zext i8 %0 to i32<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i8, i8* %ptr, i64 %idxprom2<br>
> +    %1 = load i8, i8* %arrayidx3, align 1, !tbaa !3<br>
> +    %conv4 = zext i8 %1 to i32<br>
> +    %add5 = add nuw nsw i32 %conv4, %conv<br>
> +    %conv6 = trunc i32 %add5 to i8<br>
> +    ret i8 %conv6<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define zeroext i8 @testLBZX(i8* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i8, i8* %ptr, i64 %idxprom<br>
> +    %0 = load i8, i8* %arrayidx, align 1, !tbaa !3<br>
> +    %conv = zext i8 %0 to i32<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i8, i8* %ptr, i64 %idxprom2<br>
> +    %1 = load i8, i8* %arrayidx3, align 1, !tbaa !3<br>
> +    %conv4 = zext i8 %1 to i32<br>
> +    %add5 = add nuw nsw i32 %conv4, %conv<br>
> +    %conv6 = trunc i32 %add5 to i8<br>
> +    ret i8 %conv6<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define zeroext i16 @testLHZUX(i16* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom<br>
> +    %0 = load i16, i16* %arrayidx, align 2, !tbaa !6<br>
> +    %conv = zext i16 %0 to i32<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2<br>
> +    %1 = load i16, i16* %arrayidx3, align 2, !tbaa !6<br>
> +    %conv4 = zext i16 %1 to i32<br>
> +    %add5 = add nuw nsw i32 %conv4, %conv<br>
> +    %conv6 = trunc i32 %add5 to i16<br>
> +    ret i16 %conv6<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define zeroext i16 @testLHZX(i16* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom<br>
> +    %0 = load i16, i16* %arrayidx, align 2, !tbaa !6<br>
> +    %conv = zext i16 %0 to i32<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2<br>
> +    %1 = load i16, i16* %arrayidx3, align 2, !tbaa !6<br>
> +    %conv4 = zext i16 %1 to i32<br>
> +    %add5 = add nuw nsw i32 %conv4, %conv<br>
> +    %conv6 = trunc i32 %add5 to i16<br>
> +    ret i16 %conv6<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define signext i16 @testLHAUX(i16* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom<br>
> +    %0 = load i16, i16* %arrayidx, align 2, !tbaa !6<br>
> +    %conv9 = zext i16 %0 to i32<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2<br>
> +    %1 = load i16, i16* %arrayidx3, align 2, !tbaa !6<br>
> +    %conv410 = zext i16 %1 to i32<br>
> +    %add5 = add nuw nsw i32 %conv410, %conv9<br>
> +    %conv6 = trunc i32 %add5 to i16<br>
> +    ret i16 %conv6<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define signext i16 @testLHAX(i16* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom<br>
> +    %0 = load i16, i16* %arrayidx, align 2, !tbaa !6<br>
> +    %conv9 = zext i16 %0 to i32<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2<br>
> +    %1 = load i16, i16* %arrayidx3, align 2, !tbaa !6<br>
> +    %conv410 = zext i16 %1 to i32<br>
> +    %add5 = add nuw nsw i32 %conv410, %conv9<br>
> +    %conv6 = trunc i32 %add5 to i16<br>
> +    ret i16 %conv6<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define zeroext i32 @testLWZUX(i32* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i32, i32* %ptr, i64 %idxprom<br>
> +    %0 = load i32, i32* %arrayidx, align 4, !tbaa !8<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i32, i32* %ptr, i64 %idxprom2<br>
> +    %1 = load i32, i32* %arrayidx3, align 4, !tbaa !8<br>
> +    %add4 = add i32 %1, %0<br>
> +    ret i32 %add4<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define zeroext i32 @testLWZX(i32* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i32, i32* %ptr, i64 %idxprom<br>
> +    %0 = load i32, i32* %arrayidx, align 4, !tbaa !8<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i32, i32* %ptr, i64 %idxprom2<br>
> +    %1 = load i32, i32* %arrayidx3, align 4, !tbaa !8<br>
> +    %add4 = add i32 %1, %0<br>
> +    ret i32 %add4<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define i64 @testLWAX(i32* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i32, i32* %ptr, i64 %idxprom<br>
> +    %0 = load i32, i32* %arrayidx, align 4, !tbaa !8<br>
> +    %conv = sext i32 %0 to i64<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i32, i32* %ptr, i64 %idxprom2<br>
> +    %1 = load i32, i32* %arrayidx3, align 4, !tbaa !8<br>
> +    %conv4 = sext i32 %1 to i64<br>
> +    %add5 = add nsw i64 %conv4, %conv<br>
> +    ret i64 %add5<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define i64 @testLDUX(i64* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i64, i64* %ptr, i64 %idxprom<br>
> +    %0 = load i64, i64* %arrayidx, align 8, !tbaa !10<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i64, i64* %ptr, i64 %idxprom2<br>
> +    %1 = load i64, i64* %arrayidx3, align 8, !tbaa !10<br>
> +    %add4 = add i64 %1, %0<br>
> +    ret i64 %add4<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define i64 @testLDX(i64* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i64, i64* %ptr, i64 %idxprom<br>
> +    %0 = load i64, i64* %arrayidx, align 8, !tbaa !10<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i64, i64* %ptr, i64 %idxprom2<br>
> +    %1 = load i64, i64* %arrayidx3, align 8, !tbaa !10<br>
> +    %add4 = add i64 %1, %0<br>
> +    ret i64 %add4<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define double @testLFDUX(double* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #2 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds double, double* %ptr, i64 %idxprom<br>
> +    %0 = load double, double* %arrayidx, align 8, !tbaa !12<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds double, double* %ptr, i64 %idxprom2<br>
> +    %1 = load double, double* %arrayidx3, align 8, !tbaa !12<br>
> +    %add4 = fadd double %0, %1<br>
> +    ret double %add4<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define double @testLFDX(double* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #2 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds double, double* %ptr, i64 %idxprom<br>
> +    %0 = load double, double* %arrayidx, align 8, !tbaa !12<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds double, double* %ptr, i64 %idxprom2<br>
> +    %1 = load double, double* %arrayidx3, align 8, !tbaa !12<br>
> +    %add4 = fadd double %0, %1<br>
> +    ret double %add4<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define <4 x float> @testLFSUX(float* nocapture readonly %ptr, i32 signext %idx) local_unnamed_addr #2 {<br>
> +  entry:<br>
> +    %idxprom = sext i32 %idx to i64<br>
> +    %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom<br>
> +    %0 = load float, float* %arrayidx, align 4, !tbaa !14<br>
> +    %conv = fptoui float %0 to i32<br>
> +    %vecinit = insertelement <4 x i32> undef, i32 %conv, i32 0<br>
> +    %1 = bitcast float* %ptr to i8*<br>
> +    %2 = shl i64 %idxprom, 2<br>
> +    %uglygep = getelementptr i8, i8* %1, i64 %2<br>
> +    %uglygep2 = getelementptr i8, i8* %uglygep, i64 4<br>
> +    %3 = bitcast i8* %uglygep2 to float*<br>
> +    %4 = load float, float* %3, align 4, !tbaa !14<br>
> +    %conv3 = fptoui float %4 to i32<br>
> +    %vecinit4 = insertelement <4 x i32> %vecinit, i32 %conv3, i32 1<br>
> +    %uglygep5 = getelementptr i8, i8* %uglygep, i64 8<br>
> +    %5 = bitcast i8* %uglygep5 to float*<br>
> +    %6 = load float, float* %5, align 4, !tbaa !14<br>
> +    %conv8 = fptoui float %6 to i32<br>
> +    %vecinit9 = insertelement <4 x i32> %vecinit4, i32 %conv8, i32 2<br>
> +    %uglygep8 = getelementptr i8, i8* %uglygep, i64 12<br>
> +    %7 = bitcast i8* %uglygep8 to float*<br>
> +    %8 = load float, float* %7, align 4, !tbaa !14<br>
> +    %conv13 = fptoui float %8 to i32<br>
> +    %vecinit14 = insertelement <4 x i32> %vecinit9, i32 %conv13, i32 3<br>
> +    %9 = bitcast <4 x i32> %vecinit14 to <4 x float><br>
> +    ret <4 x float> %9<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define float @testLFSX(float* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #2 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom<br>
> +    %0 = load float, float* %arrayidx, align 4, !tbaa !14<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds float, float* %ptr, i64 %idxprom2<br>
> +    %1 = load float, float* %arrayidx3, align 4, !tbaa !14<br>
> +    %add4 = fadd float %0, %1<br>
> +    ret float %add4<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define double @testLXSDX(double* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds double, double* %ptr, i64 %idxprom<br>
> +    %0 = load double, double* %arrayidx, align 8, !tbaa !12<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds double, double* %ptr, i64 %idxprom2<br>
> +    %1 = load double, double* %arrayidx3, align 8, !tbaa !12<br>
> +    %add4 = fadd double %0, %1<br>
> +    ret double %add4<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define float @testLXSSPX(float* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom<br>
> +    %0 = load float, float* %arrayidx, align 4, !tbaa !14<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds float, float* %ptr, i64 %idxprom2<br>
> +    %1 = load float, float* %arrayidx3, align 4, !tbaa !14<br>
> +    %add4 = fadd float %0, %1<br>
> +    ret float %add4<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define <4 x i32> @testLXVX(<4 x i32>* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds <4 x i32>, <4 x i32>* %ptr, i64 %idxprom<br>
> +    %0 = load <4 x i32>, <4 x i32>* %arrayidx, align 16, !tbaa !3<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds <4 x i32>, <4 x i32>* %ptr, i64 %idxprom2<br>
> +    %1 = load <4 x i32>, <4 x i32>* %arrayidx3, align 16, !tbaa !3<br>
> +    %add4 = add <4 x i32> %1, %0<br>
> +    ret <4 x i32> %add4<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @testOR(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %or = or i32 %b, %a<br>
> +    ret i32 %or<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testOR8(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %or = or i64 %b, %a<br>
> +    ret i64 %or<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @testORI(i32 signext %a) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %or = or i32 %a, 88<br>
> +    ret i32 %or<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testORI8(i64 %a) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %or = or i64 %a, 99<br>
> +    ret i64 %or<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testRLDCL(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %and = and i64 %b, 63<br>
> +    %shl = shl i64 %a, %and<br>
> +    %sub = sub nsw i64 64, %and<br>
> +    %shr = lshr i64 %a, %sub<br>
> +    %or = or i64 %shr, %shl<br>
> +    ret i64 %or<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testRLDCLo(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %and = and i64 %b, 63<br>
> +    %shl = shl i64 %a, %and<br>
> +    %sub = sub nsw i64 64, %and<br>
> +    %shr = lshr i64 %a, %sub<br>
> +    %or = or i64 %shr, %shl<br>
> +    %tobool = icmp eq i64 %or, 0<br>
> +    %cond = select i1 %tobool, i64 %and, i64 %a<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testRLDCR(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %and = and i64 %b, 63<br>
> +    %shl = shl i64 %a, %and<br>
> +    %sub = sub nsw i64 64, %and<br>
> +    %shr = lshr i64 %a, %sub<br>
> +    %or = or i64 %shr, %shl<br>
> +    ret i64 %or<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testRLDCRo(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %and = and i64 %b, 63<br>
> +    %shl = shl i64 %a, %and<br>
> +    %sub = sub nsw i64 64, %and<br>
> +    %shr = lshr i64 %a, %sub<br>
> +    %or = or i64 %shr, %shl<br>
> +    %tobool = icmp eq i64 %or, 0<br>
> +    %cond = select i1 %tobool, i64 %and, i64 %a<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testRLDICL(i64 %a) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shr = lshr i64 %a, 11<br>
> +    %and = and i64 %shr, 16777215<br>
> +    ret i64 %and<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testRLDICLo(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shr = lshr i64 %a, 11<br>
> +    %and = and i64 %shr, 16777215<br>
> +    %tobool = icmp eq i64 %and, 0<br>
> +    %cond = select i1 %tobool, i64 %b, i64 %and<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define zeroext i32 @testRLWINM(i32 zeroext %a) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shl = shl i32 %a, 4<br>
> +    %and = and i32 %shl, 4080<br>
> +    ret i32 %and<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testRLWINM8(i64 %a) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shl = shl i64 %a, 4<br>
> +    %and = and i64 %shl, 4080<br>
> +    ret i64 %and<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define zeroext i32 @testRLWINMo(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %and = and i32 %a, 255<br>
> +    %tobool = icmp eq i32 %and, 0<br>
> +    %cond = select i1 %tobool, i32 %b, i32 %a<br>
> +    ret i32 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testRLWINM8o(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %<a href="http://a.tr" rel="noreferrer" target="_blank">a.tr</a> = trunc i64 %a to i32<br>
> +    %0 = shl i32 %<a href="http://a.tr" rel="noreferrer" target="_blank">a.tr</a>, 4<br>
> +    %conv = and i32 %0, 4080<br>
> +    %tobool = icmp eq i32 %conv, 0<br>
> +    %conv1 = zext i32 %conv to i64<br>
> +    %cond = select i1 %tobool, i64 %b, i64 %conv1<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testSLD(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shl = shl i64 %a, %b<br>
> +    ret i64 %shl<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testSLDo(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shl = shl i64 %a, %b<br>
> +    %tobool = icmp eq i64 %shl, 0<br>
> +    %cond = select i1 %tobool, i64 %b, i64 %a<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testSRD(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shr = lshr i64 %a, %b<br>
> +    ret i64 %shr<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testSRDo(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shr = lshr i64 %a, %b<br>
> +    %tobool = icmp eq i64 %shr, 0<br>
> +    %cond = select i1 %tobool, i64 %b, i64 %a<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define zeroext i32 @testSLW(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shl = shl i32 %a, %b<br>
> +    ret i32 %shl<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define zeroext i32 @testSLWo(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shl = shl i32 %a, %b<br>
> +    %tobool = icmp eq i32 %shl, 0<br>
> +    %cond = select i1 %tobool, i32 %b, i32 %a<br>
> +    ret i32 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define zeroext i32 @testSRW(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shr = lshr i32 %a, %b<br>
> +    ret i32 %shr<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define zeroext i32 @testSRWo(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shr = lshr i32 %a, %b<br>
> +    %tobool = icmp eq i32 %shr, 0<br>
> +    %cond = select i1 %tobool, i32 %b, i32 %a<br>
> +    ret i32 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @testSRAW(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shr = ashr i32 %a, %b<br>
> +    ret i32 %shr<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @testSRAWo(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shr = ashr i32 %a, %b<br>
> +    %tobool = icmp eq i32 %shr, 0<br>
> +    %cond = select i1 %tobool, i32 %b, i32 %shr<br>
> +    ret i32 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testSRAD(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shr = ashr i64 %a, %b<br>
> +    ret i64 %shr<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testSRADo(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shr = ashr i64 %a, %b<br>
> +    %tobool = icmp eq i64 %shr, 0<br>
> +    %cond = select i1 %tobool, i64 %b, i64 %shr<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind<br>
> +  define void @testSTBUX(i8* nocapture %ptr, i8 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i8, i8* %ptr, i64 %idxprom<br>
> +    store i8 %a, i8* %arrayidx, align 1, !tbaa !3<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i8, i8* %ptr, i64 %idxprom2<br>
> +    store i8 %a, i8* %arrayidx3, align 1, !tbaa !3<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind<br>
> +  define void @testSTBX(i8* nocapture %ptr, i8 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i8, i8* %ptr, i64 %idxprom<br>
> +    store i8 %a, i8* %arrayidx, align 1, !tbaa !3<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i8, i8* %ptr, i64 %idxprom2<br>
> +    store i8 %a, i8* %arrayidx3, align 1, !tbaa !3<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind<br>
> +  define void @testSTHUX(i16* nocapture %ptr, i16 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom<br>
> +    store i16 %a, i16* %arrayidx, align 2, !tbaa !6<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2<br>
> +    store i16 %a, i16* %arrayidx3, align 2, !tbaa !6<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind<br>
> +  define void @testSTHX(i16* nocapture %ptr, i16 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom<br>
> +    store i16 %a, i16* %arrayidx, align 1, !tbaa !3<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2<br>
> +    store i16 %a, i16* %arrayidx3, align 1, !tbaa !3<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind<br>
> +  define void @testSTWUX(i32* nocapture %ptr, i32 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i32, i32* %ptr, i64 %idxprom<br>
> +    store i32 %a, i32* %arrayidx, align 4, !tbaa !8<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i32, i32* %ptr, i64 %idxprom2<br>
> +    store i32 %a, i32* %arrayidx3, align 4, !tbaa !8<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind<br>
> +  define void @testSTWX(i32* nocapture %ptr, i32 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i32, i32* %ptr, i64 %idxprom<br>
> +    store i32 %a, i32* %arrayidx, align 4, !tbaa !8<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i32, i32* %ptr, i64 %idxprom2<br>
> +    store i32 %a, i32* %arrayidx3, align 4, !tbaa !8<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind<br>
> +  define void @testSTDUX(i64* nocapture %ptr, i64 %a, i32 zeroext %idx) local_unnamed_addr #3 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i64, i64* %ptr, i64 %idxprom<br>
> +    store i64 %a, i64* %arrayidx, align 8, !tbaa !10<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i64, i64* %ptr, i64 %idxprom2<br>
> +    store i64 %a, i64* %arrayidx3, align 8, !tbaa !10<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind<br>
> +  define void @testSTDX(i64* nocapture %ptr, i64 %a, i32 zeroext %idx) local_unnamed_addr #3 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i64, i64* %ptr, i64 %idxprom<br>
> +    store i64 %a, i64* %arrayidx, align 8, !tbaa !10<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i64, i64* %ptr, i64 %idxprom2<br>
> +    store i64 %a, i64* %arrayidx3, align 8, !tbaa !10<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define void @testSTFSX(float* nocapture %ptr, float %a, i32 zeroext %idx) local_unnamed_addr #2 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom<br>
> +    store float %a, float* %arrayidx, align 4, !tbaa !14<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds float, float* %ptr, i64 %idxprom2<br>
> +    store float %a, float* %arrayidx3, align 4, !tbaa !14<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define void @testSTFSUX(float* nocapture %ptr, float %a, i32 zeroext %idx) local_unnamed_addr #2 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom<br>
> +    store float %a, float* %arrayidx, align 4, !tbaa !14<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds float, float* %ptr, i64 %idxprom2<br>
> +    store float %a, float* %arrayidx3, align 4, !tbaa !14<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define void @testSTFDX(double* nocapture %ptr, double %a, i32 zeroext %idx) local_unnamed_addr #2 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds double, double* %ptr, i64 %idxprom<br>
> +    store double %a, double* %arrayidx, align 8, !tbaa !12<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds double, double* %ptr, i64 %idxprom2<br>
> +    store double %a, double* %arrayidx3, align 8, !tbaa !12<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define void @testSTFDUX(double* nocapture %ptr, double %a, i32 zeroext %idx) local_unnamed_addr #2 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds double, double* %ptr, i64 %idxprom<br>
> +    store double %a, double* %arrayidx, align 8, !tbaa !12<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds double, double* %ptr, i64 %idxprom2<br>
> +    store double %a, double* %arrayidx3, align 8, !tbaa !12<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind<br>
> +  define void @testSTXSSPX(float* nocapture %ptr, float %a, i32 zeroext %idx) local_unnamed_addr #3 {<br>
> +  entry:<br>
> +    %idxprom = zext i32 %idx to i64<br>
> +    %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom<br>
> +    store float %a, float* %arrayidx, align 4, !tbaa !14<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind<br>
> +  define void @testSTXSDX(double* nocapture %ptr, double %a, i32 zeroext %idx) local_unnamed_addr #3 {<br>
> +  entry:<br>
> +    %idxprom = zext i32 %idx to i64<br>
> +    %arrayidx = getelementptr inbounds double, double* %ptr, i64 %idxprom<br>
> +    store double %a, double* %arrayidx, align 8, !tbaa !12<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind<br>
> +  define void @testSTXVX(<4 x i32>* nocapture %ptr, <4 x i32> %a, i32 zeroext %idx) local_unnamed_addr #3 {<br>
> +  entry:<br>
> +    %idxprom = zext i32 %idx to i64<br>
> +    %arrayidx = getelementptr inbounds <4 x i32>, <4 x i32>* %ptr, i64 %idxprom<br>
> +    store <4 x i32> %a, <4 x i32>* %arrayidx, align 16, !tbaa !3<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i128 @testSUBFC(i128 %a, i128 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %sub = sub nsw i128 %a, %b<br>
> +    ret i128 %sub<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i128 @testSUBFC8(i128 %a, i128 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %sub = sub nsw i128 %a, %b<br>
> +    ret i128 %sub<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @testXOR(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %xor = xor i32 %b, %a<br>
> +    ret i32 %xor<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testXOR8(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %xor = xor i64 %b, %a<br>
> +    ret i64 %xor<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @testXORI(i32 signext %a) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %xor = xor i32 %a, 17<br>
> +    ret i32 %xor<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testXOR8I(i64 %a) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %xor = xor i64 %a, 17<br>
> +    ret i64 %xor<br>
> +  }<br>
> +<br>
> +  attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-<wbr>sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="<wbr>false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="<wbr>false" "no-trapping-math"="false" "stack-protector-buffer-size"=<wbr>"8" "target-cpu"="pwr9" "target-features"="+altivec,+<wbr>bpermd,+crypto,+direct-move,+<wbr>extdiv,+htm,+power8-vector,+<wbr>power9-vector,+vsx,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
> +  attributes #1 = { norecurse nounwind readonly "correctly-rounded-divide-<wbr>sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="<wbr>false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="<wbr>false" "no-trapping-math"="false" "stack-protector-buffer-size"=<wbr>"8" "target-cpu"="pwr9" "target-features"="+altivec,+<wbr>bpermd,+crypto,+direct-move,+<wbr>extdiv,+htm,+power8-vector,+<wbr>power9-vector,+vsx,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
> +  attributes #2 = { norecurse nounwind readonly "correctly-rounded-divide-<wbr>sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="<wbr>false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="<wbr>false" "no-trapping-math"="false" "stack-protector-buffer-size"=<wbr>"8" "target-cpu"="pwr9" "target-features"="+altivec,+<wbr>bpermd,+crypto,+direct-move,+<wbr>extdiv,+htm,+power8-vector,+<wbr>power9-vector,-vsx,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
> +  attributes #3 = { norecurse nounwind "correctly-rounded-divide-<wbr>sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="<wbr>false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="<wbr>false" "no-trapping-math"="false" "stack-protector-buffer-size"=<wbr>"8" "target-cpu"="pwr9" "target-features"="+altivec,+<wbr>bpermd,+crypto,+direct-move,+<wbr>extdiv,+htm,+power8-vector,+<wbr>power9-vector,+vsx,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
> +<br>
> +  !llvm.module.flags = !{!0, !1}<br>
> +  !llvm.ident = !{!2}<br>
> +<br>
> +  !0 = !{i32 1, !"wchar_size", i32 4}<br>
> +  !1 = !{i32 7, !"PIC Level", i32 2}<br>
> +  !2 = !{!"clang version 6.0.0 (trunk 316067)"}<br>
> +  !3 = !{!4, !4, i64 0}<br>
> +  !4 = !{!"omnipotent char", !5, i64 0}<br>
> +  !5 = !{!"Simple C/C++ TBAA"}<br>
> +  !6 = !{!7, !7, i64 0}<br>
> +  !7 = !{!"short", !4, i64 0}<br>
> +  !8 = !{!9, !9, i64 0}<br>
> +  !9 = !{!"int", !4, i64 0}<br>
> +  !10 = !{!11, !11, i64 0}<br>
> +  !11 = !{!"long long", !4, i64 0}<br>
> +  !12 = !{!13, !13, i64 0}<br>
> +  !13 = !{!"double", !4, i64 0}<br>
> +  !14 = !{!15, !15, i64 0}<br>
> +  !15 = !{!"float", !4, i64 0}<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testADD4<br>
> +# CHECK-ALL: name: testADD4<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 5, class: gprc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = LI 33<br>
> +    %3 = COPY %0.sub_32<br>
> +    %4 = ADD4 killed %3, %2<br>
> +    %5 = ADD4 killed %2, killed %4<br>
> +    ; CHECK: ADDI killed %3, 33<br>
> +    ; CHECK: ADDI killed %4, 33<br>
> +    ; CHECK-LATE: addi 3, 3, 33<br>
> +    ; CHECK-LATE: addi 3, 3, 33<br>
> +    %6 = EXTSW_32_64 killed %5<br>
> +    %x3 = COPY %6<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testADD8<br>
> +# CHECK-ALL: name: testADD8<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = LI8 33<br>
> +    %0 = COPY %x3<br>
> +    %2 = ADD8 %0, %1<br>
> +    %3 = ADD8 killed %1, killed %2<br>
> +    ; CHECK: ADDI8 %0, 33<br>
> +    ; CHECK: ADDI8 killed %2, 33<br>
> +    ; CHECK-LATE: addi 3, 3, 33<br>
> +    ; CHECK-LATE: addi 3, 3, 33<br>
> +    %x3 = COPY %3<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testADDC<br>
> +# CHECK-ALL: name: testADDC<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc, preferred-register: '' }<br>
> +  - { id: 4, class: gprc, preferred-register: '' }<br>
> +  - { id: 5, class: gprc, preferred-register: '' }<br>
> +  - { id: 6, class: gprc, preferred-register: '' }<br>
> +  - { id: 7, class: g8rc, preferred-register: '' }<br>
> +  - { id: 8, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +  - { reg: '%x5', virtual-reg: '%2' }<br>
> +  - { reg: '%x6', virtual-reg: '%3' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4, %x5, %x6<br>
> +<br>
> +    %3 = COPY %x6<br>
> +    %2 = COPY %x5<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %4 = COPY %0.sub_32<br>
> +    %5 = LI 55<br>
> +    %6 = ADDC %5, %4, implicit-def %carry<br>
> +    ; CHECK: ADDIC %4, 55, implicit-def %carry<br>
> +    ; CHECK-LATE: addic 3, 3, 55<br>
> +    %7 = ADDE8 %3, %1, implicit-def dead %carry, implicit %carry<br>
> +    %8 = EXTSW_32_64 %6<br>
> +    %x3 = COPY %8<br>
> +    %x4 = COPY %7<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3, implicit %x4<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testADDC8<br>
> +# CHECK-ALL: name: testADDC8<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +  - { reg: '%x5', virtual-reg: '%2' }<br>
> +  - { reg: '%x6', virtual-reg: '%3' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4, %x5, %x6<br>
> +<br>
> +    %3 = COPY %x6<br>
> +    %2 = COPY %x5<br>
> +    %1 = COPY %x4<br>
> +    %0 = LI8 777<br>
> +    %4 = ADDC8 %2, %0, implicit-def %carry<br>
> +    ; CHECK: ADDIC8 %2, 777, implicit-def %carry<br>
> +    ; CHECK-LATE: addic 3, 5, 777<br>
> +    %5 = ADDE8 %3, %1, implicit-def dead %carry, implicit %carry<br>
> +    %x3 = COPY %4<br>
> +    %x4 = COPY %5<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3, implicit %x4<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testADDCo<br>
> +# CHECK-ALL: name: testADDCo<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: gprc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: crrc, preferred-register: '' }<br>
> +  - { id: 5, class: crbitrc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 7, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 8, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = LI 433<br>
> +    %0 = COPY %x3<br>
> +    %2 = COPY %0.sub_32<br>
> +    %3 = ADDCo %1, %2, implicit-def %cr0, implicit-def %carry<br>
> +    ; CHECK: ADDICo %2, 433, implicit-def %cr0, implicit-def %carry<br>
> +    ; CHECK-LATE: addic. 3, 3, 433<br>
> +    %4 = COPY killed %cr0<br>
> +    %5 = COPY %4.sub_eq<br>
> +    %6 = LI8 0<br>
> +    %7 = LI8 -1<br>
> +    %8 = ISEL8 %7, %6, %5<br>
> +    %x3 = COPY %8<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testADDI<br>
> +# CHECK-ALL: name: testADDI<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3<br>
> +<br>
> +    %0 = COPY %x3<br>
> +    %1 = LI 77<br>
> +    %2 = ADDI killed %1, 44<br>
> +    %3 = EXTSW_32_64 killed %2<br>
> +    ; CHECK: LI 121<br>
> +    ; CHECK-LATE: li 3, 121<br>
> +    %x3 = COPY %3<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testADDI8<br>
> +# CHECK-ALL: name: testADDI8<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3<br>
> +<br>
> +    %0 = COPY %x3<br>
> +    %1 = LI8 333<br>
> +    %2 = ADDI8 killed %1, 44<br>
> +    ; CHECK: LI8 377<br>
> +    ; CHECK-LATE: li 3, 377<br>
> +    %3 = EXTSW killed %2<br>
> +    %x3 = COPY %3<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testANDo<br>
> +# CHECK-ALL: name: testANDo<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: gprc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: crrc, preferred-register: '' }<br>
> +  - { id: 5, class: gprc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = LI 78<br>
> +    %0 = COPY %x3<br>
> +    %2 = COPY %0.sub_32<br>
> +    %3 = ANDo %1, %2, implicit-def %cr0<br>
> +    ; CHECK: ANDIo %2, 78, implicit-def %cr0<br>
> +    ; CHECK-LATE: andi. 5, 3, 78<br>
> +    %4 = COPY killed %cr0<br>
> +    %5 = ISEL %2, %1, %4.sub_eq<br>
> +    %6 = EXTSW_32_64 killed %5<br>
> +    %x3 = COPY %6<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testAND8o<br>
> +# CHECK-ALL: name: testAND8o<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +  - { id: 3, class: crrc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = LI8 321<br>
> +    %0 = COPY %x3<br>
> +    %2 = AND8o %1, %0, implicit-def %cr0<br>
> +    ; CHECK: ANDIo8 %0, 321, implicit-def %cr0<br>
> +    ; CHECK-LATE: andi. 5, 3, 321<br>
> +    %3 = COPY killed %cr0<br>
> +    %4 = ISEL8 %1, %0, %3.sub_eq<br>
> +    %x3 = COPY %4<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testCMPD<br>
> +# CHECK-ALL: name: testCMPD<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: crrc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = LI8 65533<br>
> +    %0 = COPY %x3<br>
> +    %2 = CMPD %0, %1<br>
> +    ; CHECK: CMPDI %0, -3<br>
> +    ; CHECK-LATE: cmpdi 3, -3<br>
> +    %4 = ISEL8 %zero8, %0, %2.sub_gt<br>
> +    %5 = ADD8 killed %4, %1<br>
> +    %x3 = COPY %5<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testCMPDI<br>
> +# CHECK-ALL: name: testCMPDI<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: crrc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = LI8 89<br>
> +    %2 = CMPDI %0, 87<br>
> +    %4 = ISEL8 %zero8, %0, %2.sub_gt<br>
> +    ; CHECK: LI8 0<br>
> +    %5 = ADD8 killed %4, %1<br>
> +    %x3 = COPY %5<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testCMPDI_F<br>
> +# CHECK-ALL: name: testCMPDI_F<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: crrc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = LI8 87<br>
> +    %2 = CMPDI %0, 87<br>
> +    %4 = ISEL8 %zero8, %0, %2.sub_gt<br>
> +    ; CHECK: COPY %0<br>
> +    %5 = ADD8 killed %4, %1<br>
> +    %x3 = COPY %5<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testCMPLD<br>
> +# CHECK-ALL: name: testCMPLD<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: crrc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = LI8 99<br>
> +    %0 = COPY %x3<br>
> +    %2 = CMPLD %0, %1<br>
> +    ; CHECK: CMPLDI %0, 99<br>
> +    ; CHECK-LATE: cmpldi 3, 99<br>
> +    %4 = ISEL8 %zero8, %0, %2.sub_gt<br>
> +    %5 = ADD8 killed %4, %1<br>
> +    %x3 = COPY %5<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testCMPLDI<br>
> +# CHECK-ALL: name: testCMPLDI<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: crrc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = LI8 65534<br>
> +    %2 = CMPLDI %0, 65535<br>
> +    %4 = ISEL8 %zero8, %0, %2.sub_gt<br>
> +    ; CHECK: COPY %0<br>
> +    %5 = ADD8 killed %4, %1<br>
> +    %x3 = COPY %5<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testCMPW<br>
> +# CHECK-ALL: name: testCMPW<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 4, class: crrc, preferred-register: '' }<br>
> +  - { id: 5, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 6, class: gprc, preferred-register: '' }<br>
> +  - { id: 7, class: gprc, preferred-register: '' }<br>
> +  - { id: 8, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = LI -1<br>
> +    %3 = COPY %0.sub_32<br>
> +    %4 = CMPW %3, %2<br>
> +    ; CHECK: CMPWI %3, -1<br>
> +    %6 = ISEL %zero, %3, %4.sub_gt<br>
> +    %7 = ADD4 killed %6, %2<br>
> +    %8 = EXTSW_32_64 killed %7<br>
> +    %x3 = COPY %8<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testCMPWI<br>
> +# CHECK-ALL: name: testCMPWI<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 4, class: crrc, preferred-register: '' }<br>
> +  - { id: 5, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 6, class: gprc, preferred-register: '' }<br>
> +  - { id: 7, class: gprc, preferred-register: '' }<br>
> +  - { id: 8, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = COPY %1.sub_32<br>
> +    %3 = LI -3<br>
> +    %4 = CMPWI %3, 87<br>
> +    %6 = ISEL %zero, %3, %4.sub_gt<br>
> +    ; CHECK: COPY %3<br>
> +    %7 = ADD4 killed %6, killed %2<br>
> +    %8 = EXTSW_32_64 killed %7<br>
> +    %x3 = COPY %8<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testCMPLW<br>
> +# CHECK-ALL: name: testCMPLW<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 4, class: crrc, preferred-register: '' }<br>
> +  - { id: 5, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 6, class: gprc, preferred-register: '' }<br>
> +  - { id: 7, class: gprc, preferred-register: '' }<br>
> +  - { id: 8, class: g8rc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = LI 32767<br>
> +    %3 = COPY %0.sub_32<br>
> +    %4 = CMPLW %3, %2<br>
> +    ; CHECK: CMPLWI %3, 32767<br>
> +    ; CHECK-LATE: cmplwi 3, 32767<br>
> +    %6 = ISEL %zero, %3, %4.sub_gt<br>
> +    %7 = ADD4 killed %6, %2<br>
> +    %9 = IMPLICIT_DEF<br>
> +    %8 = INSERT_SUBREG %9, killed %7, 1<br>
> +    %10 = RLDICL killed %8, 0, 32<br>
> +    %x3 = COPY %10<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testCMPLWI<br>
> +# CHECK-ALL: name: testCMPLWI<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 4, class: crrc, preferred-register: '' }<br>
> +  - { id: 5, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 6, class: gprc, preferred-register: '' }<br>
> +  - { id: 7, class: gprc, preferred-register: '' }<br>
> +  - { id: 8, class: g8rc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = COPY %1.sub_32<br>
> +    %3 = LI -3<br>
> +    %4 = CMPLWI %3, 87<br>
> +    %6 = ISEL %zero, %3, %4.sub_gt<br>
> +    ; CHECK: LI 0<br>
> +    %7 = ADD4 killed %6, killed %2<br>
> +    %9 = IMPLICIT_DEF<br>
> +    %8 = INSERT_SUBREG %9, killed %7, 1<br>
> +    %10 = RLDICL killed %8, 0, 32<br>
> +    %x3 = COPY %10<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testLBZUX<br>
> +# CHECK-ALL: name: testLBZUX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: gprc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: gprc, preferred-register: '' }<br>
> +  - { id: 13, class: gprc, preferred-register: '' }<br>
> +  - { id: 14, class: g8rc, preferred-register: '' }<br>
> +  - { id: 15, class: g8rc, preferred-register: '' }<br>
> +  - { id: 16, class: g8rc, preferred-register: '' }<br>
> +  - { id: 17, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = COPY %1.sub_32<br>
> +    %3 = ADDI %2, 1<br>
> +    %5 = IMPLICIT_DEF<br>
> +    %4 = INSERT_SUBREG %5, killed %3, 1<br>
> +    %6 = RLDICL killed %4, 0, 32<br>
> +    %7 = LBZX %0, killed %6 :: (load 1 from %ir.arrayidx, !tbaa !3)<br>
> +    %8 = ADDI %2, 2<br>
> +    %10 = IMPLICIT_DEF<br>
> +    %9 = INSERT_SUBREG %10, killed %8, 1<br>
> +    %11 = LI8 -15<br>
> +    %12,%17 = LBZUX %0, killed %11 :: (load 1 from %ir.arrayidx3, !tbaa !3)<br>
> +    ; CHECK: LBZU -15, %0<br>
> +    ; CHECK-LATE: lbzu 5, -15(3)<br>
> +    %13 = ADD4 killed %12, killed %7<br>
> +    %15 = IMPLICIT_DEF<br>
> +    %14 = INSERT_SUBREG %15, killed %13, 1<br>
> +    %16 = RLWINM8 killed %14, 0, 24, 31<br>
> +    %x3 = COPY %16<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testLBZX<br>
> +# CHECK-ALL: name: testLBZX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: gprc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: gprc, preferred-register: '' }<br>
> +  - { id: 13, class: gprc, preferred-register: '' }<br>
> +  - { id: 14, class: g8rc, preferred-register: '' }<br>
> +  - { id: 15, class: g8rc, preferred-register: '' }<br>
> +  - { id: 16, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = LI8 45<br>
> +    %2 = COPY %1.sub_32<br>
> +    %3 = ADDI %2, 1<br>
> +    %5 = IMPLICIT_DEF<br>
> +    %4 = INSERT_SUBREG %5, killed %3, 1<br>
> +    %6 = RLDICL killed %4, 0, 32<br>
> +    %7 = LBZX %0, killed %6 :: (load 1 from %ir.arrayidx, !tbaa !3)<br>
> +    ; CHECK: LBZ 45, killed %6<br>
> +    ; CHECK-LATE: lbz 5, 45(5)<br>
> +    %8 = ADDI %2, 2<br>
> +    %10 = IMPLICIT_DEF<br>
> +    %9 = INSERT_SUBREG %10, killed %8, 1<br>
> +    %11 = RLDICL killed %9, 0, 32<br>
> +    %12 = LBZX %0, killed %11 :: (load 1 from %ir.arrayidx3, !tbaa !3)<br>
> +    ; CHECK: LBZ 45, killed %11<br>
> +    ; CHECK-LATE: lbz 3, 45(4)<br>
> +    %13 = ADD4 killed %12, killed %7<br>
> +    %15 = IMPLICIT_DEF<br>
> +    %14 = INSERT_SUBREG %15, killed %13, 1<br>
> +    %16 = RLWINM8 killed %14, 0, 24, 31<br>
> +    %x3 = COPY %16<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testLHZUX<br>
> +# CHECK-ALL: name: testLHZUX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: gprc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: gprc, preferred-register: '' }<br>
> +  - { id: 13, class: gprc, preferred-register: '' }<br>
> +  - { id: 14, class: g8rc, preferred-register: '' }<br>
> +  - { id: 15, class: g8rc, preferred-register: '' }<br>
> +  - { id: 16, class: g8rc, preferred-register: '' }<br>
> +  - { id: 17, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = COPY %1.sub_32<br>
> +    %3 = ADDI %2, 1<br>
> +    %5 = IMPLICIT_DEF<br>
> +    %4 = INSERT_SUBREG %5, killed %3, 1<br>
> +    %6 = RLDIC killed %4, 1, 31<br>
> +    %7 = LHZX %0, killed %6 :: (load 2 from %ir.arrayidx, !tbaa !6)<br>
> +    %8 = ADDI %2, 2<br>
> +    %10 = IMPLICIT_DEF<br>
> +    %9 = INSERT_SUBREG %10, killed %8, 1<br>
> +    %11 = LI8 31440<br>
> +    %12,%17 = LHZUX %0, killed %11 :: (load 2 from %ir.arrayidx3, !tbaa !6)<br>
> +    ; CHECK: LHZU 31440, %0<br>
> +    ; CHECK-LATE: lhzu 5, 31440(3)<br>
> +    %13 = ADD4 killed %12, killed %7<br>
> +    %15 = IMPLICIT_DEF<br>
> +    %14 = INSERT_SUBREG %15, killed %13, 1<br>
> +    %16 = RLWINM8 killed %14, 0, 16, 31<br>
> +    %x3 = COPY %16<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testLHZX<br>
> +# CHECK-ALL: name: testLHZX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: gprc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: gprc, preferred-register: '' }<br>
> +  - { id: 13, class: gprc, preferred-register: '' }<br>
> +  - { id: 14, class: g8rc, preferred-register: '' }<br>
> +  - { id: 15, class: g8rc, preferred-register: '' }<br>
> +  - { id: 16, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = COPY %1.sub_32<br>
> +    %3 = ADDI %2, 1<br>
> +    %5 = IMPLICIT_DEF<br>
> +    %4 = INSERT_SUBREG %5, killed %3, 1<br>
> +    %6 = RLDIC killed %4, 1, 31<br>
> +    %7 = LHZX %0, killed %6 :: (load 2 from %ir.arrayidx, !tbaa !6)<br>
> +    %8 = ADDI %2, 2<br>
> +    %10 = IMPLICIT_DEF<br>
> +    %9 = INSERT_SUBREG %10, killed %8, 1<br>
> +    %11 = LI8 882<br>
> +    %12 = LHZX %0, killed %11 :: (load 2 from %ir.arrayidx3, !tbaa !6)<br>
> +    ; CHECK: LHZ 882, %0<br>
> +    ; CHECK-LATE: lhz 3, 882(3)<br>
> +    %13 = ADD4 killed %12, killed %7<br>
> +    %15 = IMPLICIT_DEF<br>
> +    %14 = INSERT_SUBREG %15, killed %13, 1<br>
> +    %16 = RLWINM8 killed %14, 0, 16, 31<br>
> +    %x3 = COPY %16<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testLHAUX<br>
> +# CHECK-ALL: name: testLHAUX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: gprc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: gprc, preferred-register: '' }<br>
> +  - { id: 13, class: gprc, preferred-register: '' }<br>
> +  - { id: 14, class: g8rc, preferred-register: '' }<br>
> +  - { id: 15, class: g8rc, preferred-register: '' }<br>
> +  - { id: 16, class: g8rc, preferred-register: '' }<br>
> +  - { id: 17, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = COPY %1.sub_32<br>
> +    %3 = ADDI %2, 1<br>
> +    %5 = IMPLICIT_DEF<br>
> +    %4 = INSERT_SUBREG %5, killed %3, 1<br>
> +    %6 = RLDIC %4, 1, 31<br>
> +    %7 = LHZX %0, killed %6 :: (load 2 from %ir.arrayidx, !tbaa !6)<br>
> +    %8 = ADDI %2, 2<br>
> +    %10 = IMPLICIT_DEF<br>
> +    %9 = INSERT_SUBREG %10, killed %8, 1<br>
> +    %11 = LI8 400<br>
> +    %12,%17 = LHAUX %0, killed %11 :: (load 2 from %ir.arrayidx3, !tbaa !6)<br>
> +    ; CHECK: LHAU 400, %0<br>
> +    ; CHECK-LATE: lhau 5, 400(3)<br>
> +    %13 = ADD4 killed %12, killed %7<br>
> +    %15 = IMPLICIT_DEF<br>
> +    %14 = INSERT_SUBREG %15, killed %13, 1<br>
> +    %16 = EXTSH8 killed %14<br>
> +    %x3 = COPY %16<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testLHAX<br>
> +# CHECK-ALL: name: testLHAX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: gprc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: gprc, preferred-register: '' }<br>
> +  - { id: 13, class: gprc, preferred-register: '' }<br>
> +  - { id: 14, class: g8rc, preferred-register: '' }<br>
> +  - { id: 15, class: g8rc, preferred-register: '' }<br>
> +  - { id: 16, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = COPY %1.sub_32<br>
> +    %3 = ADDI %2, 1<br>
> +    %5 = IMPLICIT_DEF<br>
> +    %4 = INSERT_SUBREG %5, killed %3, 1<br>
> +    %6 = LI8 -999<br>
> +    %7 = LHAX %0, killed %6 :: (load 2 from %ir.arrayidx, !tbaa !6)<br>
> +    ; CHECK: LHA -999, %0<br>
> +    ; CHECK-LATE: lha 4, -999(3)<br>
> +    %8 = ADDI %2, 2<br>
> +    %10 = IMPLICIT_DEF<br>
> +    %9 = INSERT_SUBREG %10, killed %8, 1<br>
> +    %11 = LI8 999<br>
> +    %12 = LHAX %0, killed %11 :: (load 2 from %ir.arrayidx3, !tbaa !6)<br>
> +    ; CHECK: LHA 999, %0<br>
> +    ; CHECK-LATE: lha 3, 999(3)<br>
> +    %13 = ADD4 killed %12, killed %7<br>
> +    %15 = IMPLICIT_DEF<br>
> +    %14 = INSERT_SUBREG %15, killed %13, 1<br>
> +    %16 = EXTSH8 killed %14<br>
> +    %x3 = COPY %16<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testLWZUX<br>
> +# CHECK-ALL: name: testLWZUX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: gprc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: gprc, preferred-register: '' }<br>
> +  - { id: 13, class: gprc, preferred-register: '' }<br>
> +  - { id: 14, class: g8rc, preferred-register: '' }<br>
> +  - { id: 15, class: g8rc, preferred-register: '' }<br>
> +  - { id: 16, class: g8rc, preferred-register: '' }<br>
> +  - { id: 17, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 18, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = COPY %1.sub_32<br>
> +    %3 = ADDI %2, 1<br>
> +    %5 = IMPLICIT_DEF<br>
> +    %4 = INSERT_SUBREG %5, killed %3, 1<br>
> +    %6 = LI8 889<br>
> +    %7,%17 = LWZUX %0, killed %6 :: (load 4 from %ir.arrayidx, !tbaa !8)<br>
> +    ; CHECK: LWZU 889, %0<br>
> +    ; CHECK-LATE: lwzu 5, 889(4)<br>
> +    %8 = ADDI %2, 2<br>
> +    %10 = IMPLICIT_DEF<br>
> +    %9 = INSERT_SUBREG %10, killed %8, 1<br>
> +    %11 = LI8 -2<br>
> +    %12,%18 = LWZUX %0, killed %11 :: (load 4 from %ir.arrayidx3, !tbaa !8)<br>
> +    ; CHECK: LWZU -2, %0<br>
> +    ; CHECK-LATE: lwzu 4, -2(3)<br>
> +    %13 = ADD4 killed %12, killed %7<br>
> +    %15 = IMPLICIT_DEF<br>
> +    %14 = INSERT_SUBREG %15, killed %13, 1<br>
> +    %16 = RLDICL killed %14, 0, 32<br>
> +    %x3 = COPY %16<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testLWZX<br>
> +# CHECK-ALL: name: testLWZX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: gprc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: gprc, preferred-register: '' }<br>
> +  - { id: 13, class: gprc, preferred-register: '' }<br>
> +  - { id: 14, class: g8rc, preferred-register: '' }<br>
> +  - { id: 15, class: g8rc, preferred-register: '' }<br>
> +  - { id: 16, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = LI8 1000<br>
> +    %2 = COPY %1.sub_32<br>
> +    %3 = ADDI %2, 1<br>
> +    %5 = IMPLICIT_DEF<br>
> +    %4 = INSERT_SUBREG %5, killed %3, 1<br>
> +    %6 = RLDIC %4, 2, 30<br>
> +    %7 = LWZX %0, killed %6 :: (load 4 from %ir.arrayidx, !tbaa !8)<br>
> +    ; CHECK: LWZ 1000, killed %6<br>
> +    ; CHECK-LATE: lwz 5, 1000(5)<br>
> +    %8 = ADDI %2, 2<br>
> +    %10 = IMPLICIT_DEF<br>
> +    %9 = INSERT_SUBREG %10, killed %8, 1<br>
> +    %11 = RLDIC %9, 2, 30<br>
> +    %12 = LWZX %0, killed %11 :: (load 4 from %ir.arrayidx3, !tbaa !8)<br>
> +    ; CHECK: LWZ 1000, killed %11<br>
> +    ; CHECK-LATE: lwz 3, 1000(4)<br>
> +    %13 = ADD4 killed %12, killed %7<br>
> +    %15 = IMPLICIT_DEF<br>
> +    %14 = INSERT_SUBREG %15, killed %13, 1<br>
> +    %16 = RLDICL killed %14, 0, 32<br>
> +    %x3 = COPY %16<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testLWAX<br>
> +# CHECK-ALL: name: testLWAX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: g8rc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: g8rc, preferred-register: '' }<br>
> +  - { id: 13, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = LI8 444<br>
> +    %2 = COPY %1.sub_32<br>
> +    %3 = ADDI %2, 1<br>
> +    %5 = IMPLICIT_DEF<br>
> +    %4 = INSERT_SUBREG %5, killed %3, 1<br>
> +    %6 = RLDIC %4, 2, 30<br>
> +    %7 = LWAX %0, killed %6 :: (load 4 from %ir.arrayidx, !tbaa !8)<br>
> +    ; CHECK: LWA 444, killed %6<br>
> +    ; CHECK-LATE: lwa 5, 444(5)<br>
> +    %8 = ADDI %2, 2<br>
> +    %10 = IMPLICIT_DEF<br>
> +    %9 = INSERT_SUBREG %10, killed %8, 1<br>
> +    %11 = RLDIC %9, 2, 30<br>
> +    %12 = LWAX %0, killed %11 :: (load 4 from %ir.arrayidx3, !tbaa !8)<br>
> +    ; CHECK: LWA 444, killed %11<br>
> +    ; CHECK-LATE: lwa 3, 444(4)<br>
> +    %13 = ADD8 killed %12, killed %7<br>
> +    %x3 = COPY %13<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testLDUX<br>
> +# CHECK-ALL: name: testLDUX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: g8rc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: g8rc, preferred-register: '' }<br>
> +  - { id: 13, class: g8rc, preferred-register: '' }<br>
> +  - { id: 14, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 15, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = COPY %1.sub_32<br>
> +    %3 = ADDI %2, 1<br>
> +    %5 = IMPLICIT_DEF<br>
> +    %4 = INSERT_SUBREG %5, killed %3, 1<br>
> +    %6 = LI8 100<br>
> +    %7,%14 = LDUX %0, killed %6 :: (load 8 from %ir.arrayidx, !tbaa !10)<br>
> +    ; CHECK: LDU 100, %0<br>
> +    ; CHECK-LATE: ldu 5, 100(4)<br>
> +    %8 = ADDI %2, 2<br>
> +    %10 = IMPLICIT_DEF<br>
> +    %9 = INSERT_SUBREG %10, killed %8, 1<br>
> +    %11 = LI8 200<br>
> +    %12,%15 = LDUX %0, killed %11 :: (load 8 from %ir.arrayidx3, !tbaa !10)<br>
> +    ; CHECK: LDU 200, %0<br>
> +    ; CHECK-LATE: ldu 4, 200(3)<br>
> +    %13 = ADD8 killed %12, killed %7<br>
> +    %x3 = COPY %13<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testLDX<br>
> +# CHECK-ALL: name: testLDX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: g8rc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: g8rc, preferred-register: '' }<br>
> +  - { id: 13, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = COPY %1.sub_32<br>
> +    %3 = ADDI %2, 1<br>
> +    %5 = IMPLICIT_DEF<br>
> +    %4 = INSERT_SUBREG %5, killed %3, 1<br>
> +    %6 = LI8 120<br>
> +    %7 = LDX %0, killed %6 :: (load 8 from %ir.arrayidx, !tbaa !10)<br>
> +    ; CHECK: LD 120, %0<br>
> +    ; CHECK-LATE: ld 4, 120(3)<br>
> +    %8 = ADDI %2, 2<br>
> +    %10 = IMPLICIT_DEF<br>
> +    %9 = INSERT_SUBREG %10, killed %8, 1<br>
> +    %11 = LI8 280<br>
> +    %12 = LDX %0, killed %11 :: (load 8 from %ir.arrayidx3, !tbaa !10)<br>
> +    ; CHECK: LD 280, %0<br>
> +    ; CHECK-LATE: ld 12, 280(3)<br>
> +    %13 = ADD8 killed %12, killed %7<br>
> +    %x3 = COPY %13<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testLFDUX<br>
> +# CHECK-ALL: name: testLFDUX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: f8rc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: f8rc, preferred-register: '' }<br>
> +  - { id: 13, class: f8rc, preferred-register: '' }<br>
> +  - { id: 14, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 15, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = COPY %1.sub_32<br>
> +    %3 = ADDI %2, 1<br>
> +    %5 = IMPLICIT_DEF<br>
> +    %4 = INSERT_SUBREG %5, killed %3, 1<br>
> +    %6 = LI8 440<br>
> +    %7,%14 = LFDUX %0, killed %6 :: (load 8 from %ir.arrayidx, !tbaa !12)<br>
> +    ; CHECK: LFDU 440, %0<br>
> +    ; CHECK-LATE: lfdu 0, 440(4)<br>
> +    %8 = ADDI %2, 2<br>
> +    %10 = IMPLICIT_DEF<br>
> +    %9 = INSERT_SUBREG %10, killed %8, 1<br>
> +    %11 = LI8 16<br>
> +    %12,%15 = LFDUX %0, killed %11 :: (load 8 from %ir.arrayidx3, !tbaa !12)<br>
> +    ; CHECK: LFDU 16, %0<br>
> +    ; CHECK-LATE: lfdu 1, 16(3)<br>
> +    %13 = FADD killed %7, killed %12, implicit %rm<br>
> +    %f1 = COPY %13<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %f1<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testLFDX<br>
> +# CHECK-ALL: name: testLFDX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: f8rc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: f8rc, preferred-register: '' }<br>
> +  - { id: 13, class: f8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = LI8 -20<br>
> +    %2 = COPY %1.sub_32<br>
> +    %3 = ADDI %2, 1<br>
> +    %5 = IMPLICIT_DEF<br>
> +    %4 = INSERT_SUBREG %5, killed %3, 1<br>
> +    %6 = RLDIC %4, 3, 29<br>
> +    %7 = LFDX %0, killed %6 :: (load 8 from %ir.arrayidx, !tbaa !12)<br>
> +    ; CHECK: LFD -20, killed %6<br>
> +    ; CHECK-LATE: lfd 0, -20(5)<br>
> +    %8 = ADDI %2, 2<br>
> +    %10 = IMPLICIT_DEF<br>
> +    %9 = INSERT_SUBREG %10, killed %8, 1<br>
> +    %11 = RLDIC %9, 3, 29<br>
> +    %12 = LFDX %0, killed %11 :: (load 8 from %ir.arrayidx3, !tbaa !12)<br>
> +    ; CHECK: LFD -20, killed %11<br>
> +    ; CHECK-LATE: lfd 1, -20(4)<br>
> +    %13 = FADD killed %7, killed %12, implicit %rm<br>
> +    %f1 = COPY %13<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %f1<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testLFSUX<br>
> +# CHECK-ALL: name: testLFSUX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +  - { id: 3, class: f8rc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 5, class: f8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: gprc, preferred-register: '' }<br>
> +  - { id: 8, class: f8rc, preferred-register: '' }<br>
> +  - { id: 9, class: f8rc, preferred-register: '' }<br>
> +  - { id: 10, class: f8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: gprc, preferred-register: '' }<br>
> +  - { id: 13, class: f8rc, preferred-register: '' }<br>
> +  - { id: 14, class: f8rc, preferred-register: '' }<br>
> +  - { id: 15, class: f8rc, preferred-register: '' }<br>
> +  - { id: 16, class: g8rc, preferred-register: '' }<br>
> +  - { id: 17, class: gprc, preferred-register: '' }<br>
> +  - { id: 18, class: f8rc, preferred-register: '' }<br>
> +  - { id: 19, class: f8rc, preferred-register: '' }<br>
> +  - { id: 20, class: f8rc, preferred-register: '' }<br>
> +  - { id: 21, class: g8rc, preferred-register: '' }<br>
> +  - { id: 22, class: gprc, preferred-register: '' }<br>
> +  - { id: 23, class: g8rc, preferred-register: '' }<br>
> +  - { id: 24, class: vrrc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    16<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +  - { id: 0, name: '', type: default, offset: 0, size: 16, alignment: 16,<br>
> +      stack-id: 0, callee-saved-register: '', callee-saved-restored: true,<br>
> +      local-offset: -16, di-variable: '', di-expression: '', di-location: '' }<br>
> +  - { id: 1, name: '', type: default, offset: 0, size: 4, alignment: 4,<br>
> +      stack-id: 0, callee-saved-register: '', callee-saved-restored: true,<br>
> +      local-offset: -20, di-variable: '', di-expression: '', di-location: '' }<br>
> +  - { id: 2, name: '', type: default, offset: 0, size: 4, alignment: 4,<br>
> +      stack-id: 0, callee-saved-register: '', callee-saved-restored: true,<br>
> +      local-offset: -24, di-variable: '', di-expression: '', di-location: '' }<br>
> +  - { id: 3, name: '', type: default, offset: 0, size: 4, alignment: 4,<br>
> +      stack-id: 0, callee-saved-register: '', callee-saved-restored: true,<br>
> +      local-offset: -28, di-variable: '', di-expression: '', di-location: '' }<br>
> +  - { id: 4, name: '', type: default, offset: 0, size: 4, alignment: 4,<br>
> +      stack-id: 0, callee-saved-register: '', callee-saved-restored: true,<br>
> +      local-offset: -32, di-variable: '', di-expression: '', di-location: '' }<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = LI8 72<br>
> +    %3, %4 = LFSUX %0, killed %2 :: (load 4 from %ir.arrayidx, !tbaa !14)<br>
> +    ; CHECK: LFSU 72, %0<br>
> +    ; CHECK-LATE: lfsu 0, 72(3)<br>
> +    %5 = FCTIWUZ killed %3, implicit %rm<br>
> +    %6 = ADDI8 %stack.4, 0<br>
> +    STFIWX killed %5, %zero8, killed %6<br>
> +    %7 = LWZ 0, %stack.4 :: (load 4 from %stack.4)<br>
> +    %8 = LFS 4, %4 :: (load 4 from %ir.3, !tbaa !14)<br>
> +    %10 = FCTIWUZ %8, implicit %rm<br>
> +    %11 = ADDI8 %stack.1, 0<br>
> +    STFIWX killed %10, %zero8, killed %11<br>
> +    %12 = LWZ 0, %stack.1 :: (load 4 from %stack.1)<br>
> +    %13 = LFS 8, %4 :: (load 4 from %ir.5, !tbaa !14)<br>
> +    %15 = FCTIWUZ %13, implicit %rm<br>
> +    %16 = ADDI8 %stack.2, 0<br>
> +    STFIWX killed %15, %zero8, killed %16<br>
> +    %17 = LWZ 0, %stack.2 :: (load 4 from %stack.2)<br>
> +    %18 = LFS 12, %4 :: (load 4 from %ir.7, !tbaa !14)<br>
> +    %20 = FCTIWUZ %18, implicit %rm<br>
> +    %21 = ADDI8 %stack.3, 0<br>
> +    STFIWX killed %20, %zero8, killed %21<br>
> +    %22 = LWZ 0, %stack.3 :: (load 4 from %stack.3)<br>
> +    STW killed %7, 0, %stack.0 :: (store 4 into %stack.0, align 16)<br>
> +    STW killed %22, 12, %stack.0 :: (store 4 into %stack.0 + 12)<br>
> +    STW killed %17, 8, %stack.0 :: (store 4 into %stack.0 + 8, align 8)<br>
> +    STW killed %12, 4, %stack.0 :: (store 4 into %stack.0 + 4)<br>
> +    %23 = ADDI8 %stack.0, 0<br>
> +    %24 = LVX %zero8, killed %23 :: (load 16 from %stack.0)<br>
> +    %v2 = COPY %24<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %v2<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testLFSX<br>
> +# CHECK-ALL: name: testLFSX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: f4rc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: f4rc, preferred-register: '' }<br>
> +  - { id: 13, class: f4rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = COPY %1.sub_32<br>
> +    %3 = ADDI %2, 1<br>
> +    %5 = IMPLICIT_DEF<br>
> +    %4 = INSERT_SUBREG %5, killed %3, 1<br>
> +    %6 = LI8 88<br>
> +    %7 = LFSX %0, killed %6 :: (load 4 from %ir.arrayidx, !tbaa !14)<br>
> +    ; CHECK: LFS 88, %0<br>
> +    ; CHECK-LATE: lfs 0, 88(3)<br>
> +    %8 = ADDI %2, 2<br>
> +    %10 = IMPLICIT_DEF<br>
> +    %9 = INSERT_SUBREG %10, killed %8, 1<br>
> +    %11 = LI8 -88<br>
> +    %12 = LFSX %0, killed %11 :: (load 4 from %ir.arrayidx3, !tbaa !14)<br>
> +    ; CHECK: LFS -88, %0<br>
> +    ; CHECK-LATE: lfs 1, -88(3)<br>
> +    %13 = FADDS killed %7, killed %12, implicit %rm<br>
> +    %f1 = COPY %13<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %f1<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testLXSDX<br>
> +# CHECK-ALL: name: testLXSDX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: vsfrc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: vsfrc, preferred-register: '' }<br>
> +  - { id: 13, class: vsfrc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = COPY %1.sub_32<br>
> +    %3 = ADDI %2, 1<br>
> +    %5 = IMPLICIT_DEF<br>
> +    %4 = INSERT_SUBREG %5, killed %3, 1<br>
> +    %6 = LI8 100<br>
> +    %7 = LXSDX %0, killed %6, implicit %rm :: (load 8 from %ir.arrayidx, !tbaa !12)<br>
> +    ; CHECK: LXSD 100, %0<br>
> +    ; CHECK-LATE: lxsd 0, 100(3)<br>
> +    %8 = ADDI %2, 2<br>
> +    %10 = IMPLICIT_DEF<br>
> +    %9 = INSERT_SUBREG %10, killed %8, 1<br>
> +    %11 = LI8 -120<br>
> +    %12 = LXSDX %0, killed %11, implicit %rm :: (load 8 from %ir.arrayidx3, !tbaa !12)<br>
> +    ; CHECK: LXSD -120, %0<br>
> +    ; CHECK-LATE: lxsd 1, -120(3)<br>
> +    %13 = XSADDDP killed %7, killed %12, implicit %rm<br>
> +    %f1 = COPY %13<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %f1<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testLXSSPX<br>
> +# CHECK-ALL: name: testLXSSPX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: vssrc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: vssrc, preferred-register: '' }<br>
> +  - { id: 13, class: vssrc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = COPY %1.sub_32<br>
> +    %3 = ADDI %2, 1<br>
> +    %5 = IMPLICIT_DEF<br>
> +    %4 = INSERT_SUBREG %5, killed %3, 1<br>
> +    %6 = LI8 96<br>
> +    %7 = LXSSPX %0, killed %6 :: (load 4 from %ir.arrayidx, !tbaa !14)<br>
> +    ; CHECK: LXSSP 96, %0<br>
> +    ; CHECK-LATE: lxssp 0, 96(3)<br>
> +    %8 = ADDI %2, 2<br>
> +    %10 = IMPLICIT_DEF<br>
> +    %9 = INSERT_SUBREG %10, killed %8, 1<br>
> +    %11 = LI8 -92<br>
> +    %12 = LXSSPX %0, killed %11 :: (load 4 from %ir.arrayidx3, !tbaa !14)<br>
> +    ; CHECK: LXSSP -92, %0<br>
> +    ; CHECK-LATE: lxssp 1, -92(3)<br>
> +    %13 = XSADDSP killed %7, killed %12<br>
> +    %f1 = COPY %13<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %f1<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testLXVX<br>
> +# CHECK-ALL: name: testLXVX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: vrrc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: vrrc, preferred-register: '' }<br>
> +  - { id: 13, class: vrrc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = COPY %1.sub_32<br>
> +    %3 = ADDI %2, 1<br>
> +    %5 = IMPLICIT_DEF<br>
> +    %4 = INSERT_SUBREG %5, killed %3, 1<br>
> +    %6 = LI8 32<br>
> +    %7 = LXVX %0, killed %6 :: (load 16 from %ir.arrayidx, !tbaa !3)<br>
> +    ; CHECK: LXV 32, %0<br>
> +    ; CHECK-LATE: lxv 34, 32(3)<br>
> +    %8 = ADDI %2, 2<br>
> +    %10 = IMPLICIT_DEF<br>
> +    %9 = INSERT_SUBREG %10, killed %8, 1<br>
> +    %11 = LI8 -16<br>
> +    %12 = LXVX %0, killed %11 :: (load 16 from %ir.arrayidx3, !tbaa !3)<br>
> +    ; CHECK: LXV -16, %0<br>
> +    ; CHECK-LATE: lxv 35, -16(3)<br>
> +    %13 = VADDUWM killed %12, killed %7<br>
> +    %v2 = COPY %13<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %v2<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testOR<br>
> +# CHECK-ALL: name: testOR<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: gprc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = LI 99<br>
> +    %3 = COPY %1.sub_32<br>
> +    %2 = OR %0, %3<br>
> +    ; CHECK: ORI %3, 99<br>
> +    ; CHECK-LATE: ori 3, 4, 99<br>
> +    %x3 = EXTSW_32_64 %2<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testOR8<br>
> +# CHECK-ALL: name: testOR8<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = LI8 777<br>
> +    %2 = OR8 %1, %0<br>
> +    ; CHECK: ORI8 %1, 777<br>
> +    ; CHECK-LATE: ori 3, 4, 777<br>
> +    %x3 = COPY %2<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testORI<br>
> +# CHECK-ALL: name: testORI<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: gprc, preferred-register: '' }<br>
> +  - { id: 1, class: gprc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3<br>
> +<br>
> +    %0 = LI 777<br>
> +    %1 = ORI %0, 88<br>
> +    ; CHECK: LI 857<br>
> +    ; CHECK-LATE: li 3, 857<br>
> +    %x3 = EXTSW_32_64 %1<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testORI8<br>
> +# CHECK-ALL: name: testORI8<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3<br>
> +<br>
> +    %0 = LI8 8721<br>
> +    %1 = ORI8 %0, 99<br>
> +    ; CHECK: LI8 8819<br>
> +    ; CHECK-LATE: li 3, 8819<br>
> +    %x3 = COPY %1<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testRLDCL<br>
> +# CHECK-ALL: name: testRLDCL<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = COPY %1.sub_32<br>
> +    %3 = LI 14<br>
> +    %4 = RLDCL %0, killed %3, 0<br>
> +    ; CHECK: RLDICL %0, 14, 0<br>
> +    ; CHECK-LATE: rotldi 3, 3, 14<br>
> +    %x3 = COPY %4<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testRLDCLo<br>
> +# CHECK-ALL: name: testRLDCLo<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: crrc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = RLDICL %1, 0, 58<br>
> +    %3 = LI 37<br>
> +    %4 = RLDCLo %0, killed %3, 0, implicit-def %cr0<br>
> +    ; CHECK: RLDICLo %0, 37, 0, implicit-def %cr0<br>
> +    ; CHECK-LATE: rldicl. 5, 3, 37, 0<br>
> +    %5 = COPY killed %cr0<br>
> +    %6 = ISEL8 %2, %0, %5.sub_eq<br>
> +    %x3 = COPY %6<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testRLDCR<br>
> +# CHECK-ALL: name: testRLDCR<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = COPY %1.sub_32<br>
> +    %3 = LI 0<br>
> +    %4 = RLDCR %0, killed %3, 0<br>
> +    ; CHECK: RLDICR %0, 0, 0<br>
> +    ; CHECK-LATE: rldicr 3, 3, 0, 0<br>
> +    %x3 = COPY %4<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testRLDCRo<br>
> +# CHECK-ALL: name: testRLDCRo<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: crrc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = RLDICL %1, 0, 58<br>
> +    %3 = LI 18<br>
> +    %4 = RLDCRo %0, killed %3, 0, implicit-def %cr0<br>
> +    ; CHECK: RLDICRo %0, 18, 0, implicit-def %cr0<br>
> +    ; CHECK-LATE: rldicr. 5, 3, 18, 0<br>
> +    %5 = COPY killed %cr0<br>
> +    %6 = ISEL8 %2, %0, %5.sub_eq<br>
> +    %x3 = COPY %6<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testRLDICL<br>
> +# CHECK-ALL: name: testRLDICL<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3<br>
> +<br>
> +    %0 = LI8 -1<br>
> +    %1 = RLDICL %0, 53, 49<br>
> +    ; CHECK: LI8 32767<br>
> +    ; CHECK-LATE: li 3, 32767<br>
> +    %x3 = COPY %1<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testRLDICLo<br>
> +# CHECK-ALL: name: testRLDICLo<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 3, class: crrc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = LI8 -1<br>
> +    %2 = RLDICLo %0, 53, 48, implicit-def %cr0<br>
> +    ; CHECK: ANDIo8 %0, 65535<br>
> +    ; CHECK-LATE: li 3, -1<br>
> +    ; CHECK-LATE: andi. 3, 3, 65535<br>
> +    %3 = COPY killed %cr0<br>
> +    %4 = ISEL8 %1, %2, %3.sub_eq<br>
> +    %x3 = COPY %4<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testRLWINM<br>
> +# CHECK-ALL: name: testRLWINM<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: gprc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc, preferred-register: '' }<br>
> +  - { id: 4, class: gprc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3<br>
> +<br>
> +    %0 = COPY %x3<br>
> +    %1 = COPY %0.sub_32<br>
> +    %3 = IMPLICIT_DEF<br>
> +    %2 = LI 17<br>
> +    %4 = RLWINM killed %2, 4, 20, 27<br>
> +    ; CHECK: LI 272<br>
> +    ; CHECK-LATE: li 3, 272<br>
> +    %x3 = EXTSW_32_64 %4<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testRLWINM8<br>
> +# CHECK-ALL: name: testRLWINM8<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3<br>
> +<br>
> +    %0 = LI8 234<br>
> +    %1 = RLWINM8 %0, 4, 20, 27<br>
> +    ; CHECK: LI8 3744<br>
> +    ; CHECK-LATE: li 3, 3744<br>
> +    %x3 = COPY %1<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testRLWINMo<br>
> +# CHECK-ALL: name: testRLWINMo<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 4, class: gprc, preferred-register: '' }<br>
> +  - { id: 5, class: crrc, preferred-register: '' }<br>
> +  - { id: 6, class: gprc, preferred-register: '' }<br>
> +  - { id: 7, class: g8rc, preferred-register: '' }<br>
> +  - { id: 8, class: g8rc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = COPY %1.sub_32<br>
> +    %3 = LI -22<br>
> +    %4 = RLWINMo %3, 0, 24, 31, implicit-def %cr0<br>
> +    ; CHECK: ANDIo %3, 234<br>
> +    ; CHECK-LATE: li 3, -22<br>
> +    ; CHECK-LATE: andi. 5, 3, 234<br>
> +    %5 = COPY killed %cr0<br>
> +    %6 = ISEL %2, %3, %5.sub_eq<br>
> +    %8 = IMPLICIT_DEF<br>
> +    %7 = INSERT_SUBREG %8, killed %6, 1<br>
> +    %9 = RLDICL killed %7, 0, 32<br>
> +    %x3 = COPY %9<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testRLWINM8o<br>
> +# CHECK-ALL: name: testRLWINM8o<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 7, class: crrc, preferred-register: '' }<br>
> +  - { id: 8, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = LI8 -18<br>
> +    %3 = RLWINM8o %2, 4, 20, 27, implicit-def %cr0<br>
> +    ; CHECK: ANDIo8 %2, 3808<br>
> +    ; CHECK-LATE: li 3, -18<br>
> +    ; CHECK-LATE: andi. 3, 3, 3808<br>
> +    %7 = COPY killed %cr0<br>
> +    %6 = RLDICL killed %3, 0, 32<br>
> +    %8 = ISEL8 %1, %6, %7.sub_eq<br>
> +    %x3 = COPY %8<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSLD<br>
> +# CHECK-ALL: name: testSLD<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = LI 13<br>
> +    %3 = SLD %0, killed %2<br>
> +    ; CHECK: RLDICR %0, 13, 50<br>
> +    ; CHECK-LATE: sldi 3, 3, 13<br>
> +    %x3 = COPY %3<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSLDo<br>
> +# CHECK-ALL: name: testSLDo<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc, preferred-register: '' }<br>
> +  - { id: 4, class: crrc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = LI 17<br>
> +    %3 = SLDo %0, killed %2, implicit-def %cr0<br>
> +    ; CHECK: RLDICRo %0, 17, 46, implicit-def %cr0<br>
> +    ; CHECK-LATE: rldicr. 5, 3, 17, 46<br>
> +    %4 = COPY killed %cr0<br>
> +    %5 = ISEL8 %1, %0, %4.sub_eq<br>
> +    %x3 = COPY %5<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSRD<br>
> +# CHECK-ALL: name: testSRD<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = LI 4<br>
> +    %3 = SRD %0, killed %2<br>
> +    ; CHECK: RLDICL %0, 60, 4<br>
> +    ; CHECK-LATE: rldicl 3, 3, 60, 4<br>
> +    %x3 = COPY %3<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSRDo<br>
> +# CHECK-ALL: name: testSRDo<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc, preferred-register: '' }<br>
> +  - { id: 4, class: crrc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = LI 17<br>
> +    %3 = SRDo %0, killed %2, implicit-def %cr0<br>
> +    ; CHECK: RLDICLo %0, 47, 17, implicit-def %cr0<br>
> +    ; CHECK-LATE: rldicl. 5, 3, 47, 17<br>
> +    %4 = COPY killed %cr0<br>
> +    %5 = ISEL8 %1, %0, %4.sub_eq<br>
> +    %x3 = COPY %5<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSLW<br>
> +# CHECK-ALL: name: testSLW<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: gprc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: g8rc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = COPY %1.sub_32<br>
> +    %5 = LI 21<br>
> +    %8 = SLW killed %2, killed %5<br>
> +    ; CHECK: RLWINM killed %2, 21, 0, 10<br>
> +    ; CHECK-LATE: slwi 3, 4, 21<br>
> +    %x3 = EXTSW_32_64 %8<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSLWo<br>
> +# CHECK-ALL: name: testSLWo<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 4, class: gprc, preferred-register: '' }<br>
> +  - { id: 5, class: crrc, preferred-register: '' }<br>
> +  - { id: 6, class: gprc, preferred-register: '' }<br>
> +  - { id: 7, class: g8rc, preferred-register: '' }<br>
> +  - { id: 8, class: g8rc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = LI 11<br>
> +    %3 = COPY %0.sub_32<br>
> +    %4 = SLWo %3, %2, implicit-def %cr0<br>
> +    ; CHECK: RLWINMo %3, 11, 0, 20, implicit-def %cr0<br>
> +    ; CHECK-LATE: rlwinm. 5, 3, 11, 0, 20<br>
> +    %5 = COPY killed %cr0<br>
> +    %6 = ISEL %2, %3, %5.sub_eq<br>
> +    %8 = IMPLICIT_DEF<br>
> +    %7 = INSERT_SUBREG %8, killed %6, 1<br>
> +    %9 = RLDICL killed %7, 0, 32<br>
> +    %x3 = COPY %9<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSRW<br>
> +# CHECK-ALL: name: testSRW<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: gprc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: g8rc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = LI 8<br>
> +    %5 = COPY %0.sub_32<br>
> +    %8 = SRW killed %5, killed %2<br>
> +    ; CHECK: RLWINM killed %5, 24, 8, 31<br>
> +    ; CHECK-LATE: srwi 3, 3, 8<br>
> +    %x3 = EXTSW_32_64 %8<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSRWo<br>
> +# CHECK-ALL: name: testSRWo<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 4, class: gprc, preferred-register: '' }<br>
> +  - { id: 5, class: crrc, preferred-register: '' }<br>
> +  - { id: 6, class: gprc, preferred-register: '' }<br>
> +  - { id: 7, class: g8rc, preferred-register: '' }<br>
> +  - { id: 8, class: g8rc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = LI 7<br>
> +    %3 = COPY %0.sub_32<br>
> +    %4 = SRWo %3, %2, implicit-def %cr0<br>
> +    ; CHECK: RLWINMo %3, 25, 7, 31<br>
> +    ; CHECK-LATE: rlwinm. 5, 3, 25, 7, 31<br>
> +    %5 = COPY killed %cr0<br>
> +    %6 = ISEL %2, %3, %5.sub_eq<br>
> +    %8 = IMPLICIT_DEF<br>
> +    %7 = INSERT_SUBREG %8, killed %6, 1<br>
> +    %9 = RLDICL killed %7, 0, 32<br>
> +    %x3 = COPY %9<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSRAW<br>
> +# CHECK-ALL: name: testSRAW<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: gprc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = LI 15<br>
> +    %3 = COPY %0.sub_32<br>
> +    %4 = SRAW killed %3, killed %2, implicit-def dead %carry<br>
> +    ; CHECK: SRAWI killed %3, 15, implicit-def dead %carry<br>
> +    ; CHECK-LATE: srawi 3, 3, 15<br>
> +    %5 = EXTSW_32_64 killed %4<br>
> +    %x3 = COPY %5<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSRAWo<br>
> +# CHECK-ALL: name: testSRAWo<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 5, class: crrc, preferred-register: '' }<br>
> +  - { id: 6, class: gprc, preferred-register: '' }<br>
> +  - { id: 7, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = LI 8<br>
> +    %3 = COPY %0.sub_32<br>
> +    %4 = SRAWo killed %3, %2, implicit-def dead %carry, implicit-def %cr0<br>
> +    ; CHECK: SRAWIo killed %3, 8, implicit-def dead %carry, implicit-def %cr0<br>
> +    ; CHECK-LATE: srawi. 3, 3, 8<br>
> +    %5 = COPY killed %cr0<br>
> +    %6 = ISEL %2, %4, %5.sub_eq<br>
> +    %7 = EXTSW_32_64 killed %6<br>
> +    %x3 = COPY %7<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSRAD<br>
> +# CHECK-ALL: name: testSRAD<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = LI 44<br>
> +    %3 = SRAD %0, killed %2, implicit-def dead %carry<br>
> +    ; CHECK: SRADI %0, 44, implicit-def dead %carry<br>
> +    ; CHECK-LATE: sradi 3, 3, 44<br>
> +    %x3 = COPY %3<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSRADo<br>
> +# CHECK-ALL: name: testSRADo<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 4, class: crrc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %2 = LI 61<br>
> +    %3 = SRADo %0, killed %2, implicit-def dead %carry, implicit-def %cr0<br>
> +    ; CHECK: SRADIo %0, 61, implicit-def dead %carry, implicit-def %cr0<br>
> +    ; CHECK-LATE: sradi. 3, 3, 61<br>
> +    %4 = COPY killed %cr0<br>
> +    %5 = ISEL8 %1, %3, %4.sub_eq<br>
> +    %x3 = COPY %5<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSTBUX<br>
> +# CHECK-ALL: name: testSTBUX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 5, class: gprc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: g8rc, preferred-register: '' }<br>
> +  - { id: 8, class: g8rc, preferred-register: '' }<br>
> +  - { id: 9, class: gprc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: g8rc, preferred-register: '' }<br>
> +  - { id: 13, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 14, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +  - { reg: '%x5', virtual-reg: '%2' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4, %x5<br>
> +<br>
> +    %2 = COPY %x5<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %3 = COPY %1.sub_32<br>
> +    %4 = COPY %2.sub_32<br>
> +    %5 = ADDI %4, 1<br>
> +    %7 = IMPLICIT_DEF<br>
> +    %6 = INSERT_SUBREG %7, killed %5, 1<br>
> +    %8 = LI8 966<br>
> +    %13 = STBUX %3, %0, killed %8 :: (store 1 into %ir.arrayidx, !tbaa !3)<br>
> +    ; CHECK: STBU %3, 966, %0<br>
> +    ; CHECK-LATE: 4, 966(5)<br>
> +    %9 = ADDI %4, 2<br>
> +    %11 = IMPLICIT_DEF<br>
> +    %10 = INSERT_SUBREG %11, killed %9, 1<br>
> +    %12 = LI8 777<br>
> +    %14 = STBUX %3, %0, killed %12 :: (store 1 into %ir.arrayidx3, !tbaa !3)<br>
> +    ; CHECK: STBU %3, 777, %0<br>
> +    ; CHECK-LATE: 4, 777(3)<br>
> +    BLR8 implicit %lr8, implicit %rm<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSTBX<br>
> +# CHECK-ALL: name: testSTBX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 5, class: gprc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: g8rc, preferred-register: '' }<br>
> +  - { id: 8, class: g8rc, preferred-register: '' }<br>
> +  - { id: 9, class: gprc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +  - { reg: '%x5', virtual-reg: '%2' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4, %x5<br>
> +<br>
> +    %2 = COPY %x5<br>
> +    %1 = COPY %x4<br>
> +    %0 = LI8 975<br>
> +    %3 = COPY %1.sub_32<br>
> +    %4 = COPY %2.sub_32<br>
> +    %5 = ADDI %4, 1<br>
> +    %7 = IMPLICIT_DEF<br>
> +    %6 = INSERT_SUBREG %7, killed %5, 1<br>
> +    %8 = RLDICL killed %6, 0, 32<br>
> +    STBX %3, %0, killed %8 :: (store 1 into %ir.arrayidx, !tbaa !3)<br>
> +    ; CHECK: STB %3, 975, killed %8<br>
> +    ; CHECK-LATE: stb 4, 975(6)<br>
> +    %9 = ADDI %4, 2<br>
> +    %11 = IMPLICIT_DEF<br>
> +    %10 = INSERT_SUBREG %11, killed %9, 1<br>
> +    %12 = RLDICL killed %10, 0, 32<br>
> +    STBX %3, %0, killed %12 :: (store 1 into %ir.arrayidx3, !tbaa !3)<br>
> +    ; CHECK: STB %3, 975, killed %12<br>
> +    ; CHECK-LATE: stb 4, 975(5)<br>
> +    BLR8 implicit %lr8, implicit %rm<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSTHUX<br>
> +# CHECK-ALL: name: testSTHUX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 5, class: gprc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: g8rc, preferred-register: '' }<br>
> +  - { id: 8, class: g8rc, preferred-register: '' }<br>
> +  - { id: 9, class: gprc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: g8rc, preferred-register: '' }<br>
> +  - { id: 13, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 14, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +  - { reg: '%x5', virtual-reg: '%2' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4, %x5<br>
> +<br>
> +    %2 = COPY %x5<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %3 = COPY %1.sub_32<br>
> +    %4 = COPY %2.sub_32<br>
> +    %5 = ADDI %4, 1<br>
> +    %7 = IMPLICIT_DEF<br>
> +    %6 = INSERT_SUBREG %7, killed %5, 1<br>
> +    %8 = LI8 32000<br>
> +    %13 = STHUX %3, %0, killed %8 :: (store 2 into %ir.arrayidx, !tbaa !6)<br>
> +    ; CHECK: STHU %3, 32000, %0<br>
> +    ; CHECK-LATE: sthu 4, 32000(5)<br>
> +    %9 = ADDI %4, 2<br>
> +    %11 = IMPLICIT_DEF<br>
> +    %10 = INSERT_SUBREG %11, killed %9, 1<br>
> +    %12 = LI8 -761<br>
> +    %14 = STHUX %3, %0, killed %12 :: (store 2 into %ir.arrayidx3, !tbaa !6)<br>
> +    ; CHECK: STHU %3, -761, %0<br>
> +    ; CHECK-LATE: sthu 4, -761(3)<br>
> +    BLR8 implicit %lr8, implicit %rm<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSTHX<br>
> +# CHECK-ALL: name: testSTHX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 5, class: gprc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: g8rc, preferred-register: '' }<br>
> +  - { id: 8, class: g8rc, preferred-register: '' }<br>
> +  - { id: 9, class: gprc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +  - { reg: '%x5', virtual-reg: '%2' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4, %x5<br>
> +<br>
> +    %2 = COPY %x5<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %3 = COPY %1.sub_32<br>
> +    %4 = COPY %2.sub_32<br>
> +    %5 = ADDI %4, 1<br>
> +    %7 = IMPLICIT_DEF<br>
> +    %6 = INSERT_SUBREG %7, killed %5, 1<br>
> +    %8 = LI8 900<br>
> +    STHX %3, %0, killed %8 :: (store 1 into %ir.arrayidx, !tbaa !3)<br>
> +    ; CHECK: STH %3, 900, %0<br>
> +    ; CHECK-LATE: sth 4, 900(3)<br>
> +    %9 = ADDI %4, 2<br>
> +    %11 = IMPLICIT_DEF<br>
> +    %10 = INSERT_SUBREG %11, killed %9, 1<br>
> +    %12 = LI8 -900<br>
> +    STHX %3, %0, killed %12 :: (store 1 into %ir.arrayidx3, !tbaa !3)<br>
> +    ; CHECK: STH %3, -900, %0<br>
> +    ; CHECK-LATE: sth 4, -900(3)<br>
> +    BLR8 implicit %lr8, implicit %rm<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSTWUX<br>
> +# CHECK-ALL: name: testSTWUX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 5, class: gprc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: g8rc, preferred-register: '' }<br>
> +  - { id: 8, class: g8rc, preferred-register: '' }<br>
> +  - { id: 9, class: gprc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: g8rc, preferred-register: '' }<br>
> +  - { id: 13, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 14, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +  - { reg: '%x5', virtual-reg: '%2' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4, %x5<br>
> +<br>
> +    %2 = COPY %x5<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %3 = COPY %1.sub_32<br>
> +    %4 = COPY %2.sub_32<br>
> +    %5 = ADDI %4, 1<br>
> +    %7 = IMPLICIT_DEF<br>
> +    %6 = INSERT_SUBREG %7, killed %5, 1<br>
> +    %8 = LI8 111<br>
> +    %13 = STWUX %3, %0, killed %8 :: (store 4 into %ir.arrayidx, !tbaa !8)<br>
> +    ; CHECK: STWU %3, 111, %0<br>
> +    ; CHECK-LATE: stwu 4, 111(5)<br>
> +    %9 = ADDI %4, 2<br>
> +    %11 = IMPLICIT_DEF<br>
> +    %10 = INSERT_SUBREG %11, killed %9, 1<br>
> +    %12 = LI8 0<br>
> +    %14 = STWUX %3, %0, killed %12 :: (store 4 into %ir.arrayidx3, !tbaa !8)<br>
> +    ; CHECK: STWU %3, 0, %0<br>
> +    ; CHECK-LATE: stwu 4, 0(3)<br>
> +    BLR8 implicit %lr8, implicit %rm<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSTWX<br>
> +# CHECK-ALL: name: testSTWX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 5, class: gprc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: g8rc, preferred-register: '' }<br>
> +  - { id: 8, class: g8rc, preferred-register: '' }<br>
> +  - { id: 9, class: gprc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +  - { reg: '%x5', virtual-reg: '%2' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4, %x5<br>
> +<br>
> +    %2 = COPY %x5<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %3 = COPY %1.sub_32<br>
> +    %4 = COPY %2.sub_32<br>
> +    %5 = ADDI %4, 1<br>
> +    %7 = IMPLICIT_DEF<br>
> +    %6 = INSERT_SUBREG %7, killed %5, 1<br>
> +    %8 = LI8 2<br>
> +    STWX %3, %0, killed %8 :: (store 4 into %ir.arrayidx, !tbaa !8)<br>
> +    ; CHECK: STW %3, 2, %0<br>
> +    ; CHECK-LATE: stw 4, 2(3)<br>
> +    %9 = ADDI %4, 2<br>
> +    %11 = IMPLICIT_DEF<br>
> +    %10 = INSERT_SUBREG %11, killed %9, 1<br>
> +    %12 = LI8 99<br>
> +    STWX %3, %0, killed %12 :: (store 4 into %ir.arrayidx3, !tbaa !8)<br>
> +    ; CHECK: STW %3, 99, %0<br>
> +    ; CHECK-LATE: stw 4, 99(3)<br>
> +    BLR8 implicit %lr8, implicit %rm<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSTDUX<br>
> +# CHECK-ALL: name: testSTDUX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 4, class: gprc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: g8rc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 13, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +  - { reg: '%x5', virtual-reg: '%2' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4, %x5<br>
> +<br>
> +    %2 = COPY %x5<br>
> +    %1 = COPY %x4<br>
> +    %0 = COPY %x3<br>
> +    %3 = COPY %2.sub_32<br>
> +    %4 = ADDI %3, 1<br>
> +    %6 = IMPLICIT_DEF<br>
> +    %5 = INSERT_SUBREG %6, killed %4, 1<br>
> +    %7 = LI8 444<br>
> +    %12 = STDUX %1, %0, killed %7 :: (store 8 into %ir.arrayidx, !tbaa !10)<br>
> +    ; CHECK: STDU %1, 444, %0<br>
> +    ; CHECK-LATE: stdu 4, 444(5)<br>
> +    %8 = ADDI %3, 2<br>
> +    %10 = IMPLICIT_DEF<br>
> +    %9 = INSERT_SUBREG %10, killed %8, 1<br>
> +    %11 = LI8 -8<br>
> +    %13 = STDUX %1, %0, killed %11 :: (store 8 into %ir.arrayidx3, !tbaa !10)<br>
> +    ; CHECK: STDU %1, -8, %0<br>
> +    ; CHECK-LATE: stdu 4, -8(3)<br>
> +    BLR8 implicit %lr8, implicit %rm<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSTDX<br>
> +# CHECK-ALL: name: testSTDX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 4, class: gprc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: g8rc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +  - { reg: '%x5', virtual-reg: '%2' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4, %x5<br>
> +<br>
> +    %2 = COPY %x5<br>
> +    %1 = COPY %x4<br>
> +    %0 = LI8 1000<br>
> +    %3 = COPY %2.sub_32<br>
> +    %4 = ADDI %3, 1<br>
> +    %6 = IMPLICIT_DEF<br>
> +    %5 = INSERT_SUBREG %6, killed %4, 1<br>
> +    %7 = LI8 900<br>
> +    STDX %1, %0, killed %7 :: (store 8 into %ir.arrayidx, !tbaa !10)<br>
> +    ; CHECK: STD %1, 1000, killed %7<br>
> +    ; CHECK-LATE: 4, 1000(5)<br>
> +    %8 = ADDI %3, 2<br>
> +    %10 = IMPLICIT_DEF<br>
> +    %9 = INSERT_SUBREG %10, killed %8, 1<br>
> +    %11 = LI8 -900<br>
> +    STDX %1, %0, killed %11 :: (store 8 into %ir.arrayidx3, !tbaa !10)<br>
> +    ; CHECK: STD %1, 1000, killed %11<br>
> +    ; CHECK-LATE: 4, 1000(6)<br>
> +    BLR8 implicit %lr8, implicit %rm<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSTFSX<br>
> +# CHECK-ALL: name: testSTFSX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: f4rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 4, class: gprc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: g8rc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%f1', virtual-reg: '%1' }<br>
> +  - { reg: '%x5', virtual-reg: '%2' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %f1, %x5<br>
> +<br>
> +    %2 = COPY %x5<br>
> +    %1 = COPY %f1<br>
> +    %0 = COPY %x3<br>
> +    %3 = COPY %2.sub_32<br>
> +    %4 = ADDI %3, 1<br>
> +    %6 = IMPLICIT_DEF<br>
> +    %5 = INSERT_SUBREG %6, killed %4, 1<br>
> +    %7 = LI8 400<br>
> +    STFSX %1, %0, killed %7 :: (store 4 into %ir.arrayidx, !tbaa !14)<br>
> +    ; CHECK: STFS %1, 400, %0<br>
> +    ; CHECK-LATE: stfs 1, 400(3)<br>
> +    %8 = ADDI %3, 2<br>
> +    %10 = IMPLICIT_DEF<br>
> +    %9 = INSERT_SUBREG %10, killed %8, 1<br>
> +    %11 = LI8 -401<br>
> +    STFSX %1, %0, killed %11 :: (store 4 into %ir.arrayidx3, !tbaa !14)<br>
> +    ; CHECK: STFS %1, -401, %0<br>
> +    ; CHECK-LATE: stfs 1, -401(3)<br>
> +    BLR8 implicit %lr8, implicit %rm<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSTFSUX<br>
> +# CHECK-ALL: name: testSTFSUX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: f4rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 4, class: gprc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: g8rc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 13, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%f1', virtual-reg: '%1' }<br>
> +  - { reg: '%x5', virtual-reg: '%2' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %f1, %x5<br>
> +<br>
> +    %2 = COPY %x5<br>
> +    %1 = COPY %f1<br>
> +    %0 = COPY %x3<br>
> +    %3 = COPY %2.sub_32<br>
> +    %4 = ADDI %3, 1<br>
> +    %6 = IMPLICIT_DEF<br>
> +    %5 = INSERT_SUBREG %6, killed %4, 1<br>
> +    %7 = LI8 111<br>
> +    %12 = STFSUX %1, %0, killed %7 :: (store 4 into %ir.arrayidx, !tbaa !14)<br>
> +    ; CHECK: STFSU %1, 111, %0<br>
> +    ; CHECK-LATE: stfsu 1, 111(4)<br>
> +    %8 = ADDI %3, 2<br>
> +    %10 = IMPLICIT_DEF<br>
> +    %9 = INSERT_SUBREG %10, killed %8, 1<br>
> +    %11 = LI8 987<br>
> +    %13 = STFSUX %1, %0, killed %11 :: (store 4 into %ir.arrayidx3, !tbaa !14)<br>
> +    ; CHECK: STFSU %1, 987, %0<br>
> +    ; CHECK-LATE: stfsu 1, 987(3)<br>
> +    BLR8 implicit %lr8, implicit %rm<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSTFDX<br>
> +# CHECK-ALL: name: testSTFDX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: f8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 4, class: gprc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: g8rc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%f1', virtual-reg: '%1' }<br>
> +  - { reg: '%x5', virtual-reg: '%2' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %f1, %x5<br>
> +<br>
> +    %2 = COPY %x5<br>
> +    %1 = COPY %f1<br>
> +    %0 = COPY %x3<br>
> +    %3 = COPY %2.sub_32<br>
> +    %4 = ADDI %3, 1<br>
> +    %6 = IMPLICIT_DEF<br>
> +    %5 = INSERT_SUBREG %6, killed %4, 1<br>
> +    %7 = LI8 876<br>
> +    STFDX %1, %0, killed %7 :: (store 8 into %ir.arrayidx, !tbaa !12)<br>
> +    ; CHECK: STFD %1, 876, %0<br>
> +    ; CHECK-LATE: stfd 1, 876(3)<br>
> +    %8 = ADDI %3, 2<br>
> +    %10 = IMPLICIT_DEF<br>
> +    %9 = INSERT_SUBREG %10, killed %8, 1<br>
> +    %11 = LI8 -873<br>
> +    STFDX %1, %0, killed %11 :: (store 8 into %ir.arrayidx3, !tbaa !12)<br>
> +    ; CHECK: STFD %1, -873, %0<br>
> +    ; CHECK-LATE: stfd 1, -873(3)<br>
> +    BLR8 implicit %lr8, implicit %rm<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSTFDUX<br>
> +# CHECK-ALL: name: testSTFDUX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: f8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }<br>
> +  - { id: 4, class: gprc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +  - { id: 6, class: g8rc, preferred-register: '' }<br>
> +  - { id: 7, class: g8rc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +  - { id: 9, class: g8rc, preferred-register: '' }<br>
> +  - { id: 10, class: g8rc, preferred-register: '' }<br>
> +  - { id: 11, class: g8rc, preferred-register: '' }<br>
> +  - { id: 12, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 13, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%f1', virtual-reg: '%1' }<br>
> +  - { reg: '%x5', virtual-reg: '%2' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %f1, %x5<br>
> +<br>
> +    %2 = COPY %x5<br>
> +    %1 = COPY %f1<br>
> +    %0 = COPY %x3<br>
> +    %3 = COPY %2.sub_32<br>
> +    %4 = ADDI %3, 1<br>
> +    %6 = IMPLICIT_DEF<br>
> +    %5 = INSERT_SUBREG %6, killed %4, 1<br>
> +    %7 = LI8 -9038<br>
> +    %12 = STFDUX %1, %0, killed %7 :: (store 8 into %ir.arrayidx, !tbaa !12)<br>
> +    ; CHECK: STFDU %1, -9038, %0<br>
> +    ; CHECK-LATE: stfdu 1, -9038(4)<br>
> +    %8 = ADDI %3, 2<br>
> +    %10 = IMPLICIT_DEF<br>
> +    %9 = INSERT_SUBREG %10, killed %8, 1<br>
> +    %11 = LI8 6477<br>
> +    %13 = STFDUX %1, %0, killed %11 :: (store 8 into %ir.arrayidx3, !tbaa !12)<br>
> +    ; CHECK: STFDU %1, 6477, %0<br>
> +    ; CHECK-LATE: stfdu 1, 6477(3)<br>
> +    BLR8 implicit %lr8, implicit %rm<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSTXSSPX<br>
> +# CHECK-ALL: name: testSTXSSPX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: vssrc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%f1', virtual-reg: '%1' }<br>
> +  - { reg: '%x5', virtual-reg: '%2' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %f1, %x5<br>
> +<br>
> +    %2 = COPY %x5<br>
> +    %1 = COPY %f1<br>
> +    %0 = COPY %x3<br>
> +    %3 = LI8 444<br>
> +    STXSSPX %1, %0, killed %3 :: (store 4 into %ir.arrayidx, !tbaa !14)<br>
> +    ; CHECK: STXSSP %1, 444, %0<br>
> +    ; CHECK-LATE: stxssp 1, 444(3)<br>
> +    BLR8 implicit %lr8, implicit %rm<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSTXSDX<br>
> +# CHECK-ALL: name: testSTXSDX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: vsfrc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%f1', virtual-reg: '%1' }<br>
> +  - { reg: '%x5', virtual-reg: '%2' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %f1, %x5<br>
> +<br>
> +    %2 = COPY %x5<br>
> +    %1 = COPY %f1<br>
> +    %0 = COPY %x3<br>
> +    %3 = LI8 4<br>
> +    STXSDX %1, %0, killed %3, implicit %rm :: (store 8 into %ir.arrayidx, !tbaa !12)<br>
> +    ; CHECK: STXSD %1, 4, %0<br>
> +    ; CHECK-LATE: stxsd 1, 4(3)<br>
> +    BLR8 implicit %lr8, implicit %rm<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSTXVX<br>
> +# CHECK-ALL: name: testSTXVX<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: vrrc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%v2', virtual-reg: '%1' }<br>
> +  - { reg: '%x7', virtual-reg: '%2' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %v2, %x7<br>
> +<br>
> +    %2 = COPY %x7<br>
> +    %1 = COPY %v2<br>
> +    %0 = LI8 16<br>
> +    %3 = RLDICR %2, 4, 59<br>
> +    STXVX %1, %0, killed %3 :: (store 16 into %ir.arrayidx, !tbaa !3)<br>
> +    ; CHECK: STXV %1, 16, killed %3<br>
> +    ; CHECK-LATE: stxv 34, 16(4)<br>
> +    BLR8 implicit %lr8, implicit %rm<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSUBFC<br>
> +# CHECK-ALL: name: testSUBFC<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: gprc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc, preferred-register: '' }<br>
> +  - { id: 4, class: gprc, preferred-register: '' }<br>
> +  - { id: 5, class: gprc, preferred-register: '' }<br>
> +  - { id: 6, class: gprc, preferred-register: '' }<br>
> +  - { id: 7, class: gprc, preferred-register: '' }<br>
> +  - { id: 8, class: gprc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +  - { reg: '%x5', virtual-reg: '%2' }<br>
> +  - { reg: '%x6', virtual-reg: '%3' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4, %x5, %x6<br>
> +<br>
> +    %3 = COPY %x6<br>
> +    %2 = COPY %x5<br>
> +    %1 = COPY %x4<br>
> +    %6 = COPY %3.sub_32<br>
> +    %7 = COPY %2.sub_32<br>
> +    %8 = COPY %1.sub_32<br>
> +    %0 = LI 55<br>
> +    %4 = SUBFC %7, %0, implicit-def %carry<br>
> +    ; CHECK: SUBFIC %7, 55<br>
> +    ; CHECK-LATE: subfic 3, 5, 55<br>
> +    %5 = SUBFE %6, %8, implicit-def dead %carry, implicit %carry<br>
> +    %x3 = EXTSW_32_64 %4<br>
> +    %x4 = EXTSW_32_64 %5<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3, implicit %x4<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testSUBFC8<br>
> +# CHECK-ALL: name: testSUBFC8<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +  - { id: 3, class: g8rc, preferred-register: '' }<br>
> +  - { id: 4, class: g8rc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +  - { reg: '%x5', virtual-reg: '%2' }<br>
> +  - { reg: '%x6', virtual-reg: '%3' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4, %x5, %x6<br>
> +<br>
> +    %3 = COPY %x6<br>
> +    %2 = COPY %x5<br>
> +    %1 = COPY %x4<br>
> +    %0 = LI8 7635<br>
> +    %4 = SUBFC8 %2, %0, implicit-def %carry<br>
> +    ; CHECK: SUBFIC8 %2, 7635<br>
> +    ; CHECK-LATE: subfic 3, 5, 7635<br>
> +    %5 = SUBFE8 %3, %1, implicit-def dead %carry, implicit %carry<br>
> +    %x3 = COPY %4<br>
> +    %x4 = COPY %5<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3, implicit %x4<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testXOR<br>
> +# CHECK-ALL: name: testXOR<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: gprc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = LI 10101<br>
> +    %0 = COPY %x3<br>
> +    %3 = COPY %0.sub_32<br>
> +    %2 = XOR %1, %3<br>
> +    ; CHECK: XORI %3, 10101<br>
> +    ; CHECK-LATE: 3, 3, 10101<br>
> +    %x3 = EXTSW_32_64 %2<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testXOR8<br>
> +# CHECK-ALL: name: testXOR8<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1 = COPY %x4<br>
> +    %0 = LI8 5535<br>
> +    %2 = XOR8 %1, %0<br>
> +    ; CHECK: XORI8 %1, 5535<br>
> +    ; CHECK-LATE: xori 3, 4, 5535<br>
> +    %x3 = COPY %2<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testXORI<br>
> +# CHECK-ALL: name: testXORI<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: gprc, preferred-register: '' }<br>
> +  - { id: 1, class: gprc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3<br>
> +<br>
> +    %0 = LI 871<br>
> +    %1 = XORI %0, 17<br>
> +    ; CHECK: LI 886<br>
> +    ; CHECK-LATE: li 3, 886<br>
> +    %x3 = EXTSW_32_64 %1<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            testXOR8I<br>
> +# CHECK-ALL: name: testXOR8I<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3<br>
> +<br>
> +    %0 = LI8 453<br>
> +    %1 = XORI8 %0, 17<br>
> +    ; CHECK: LI8 468<br>
> +    ; CHECK-LATE: li 3, 468<br>
> +    %x3 = COPY %1<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
><br>
> Modified: llvm/trunk/test/CodeGen/<wbr>PowerPC/fast-isel-call.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/fast-isel-call.ll?rev=320791&r1=320790&r2=320791&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>CodeGen/PowerPC/fast-isel-<wbr>call.ll?rev=320791&r1=320790&<wbr>r2=320791&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/test/CodeGen/<wbr>PowerPC/fast-isel-call.ll (original)<br>
> +++ llvm/trunk/test/CodeGen/<wbr>PowerPC/fast-isel-call.ll Thu Dec 14 23:27:53 2017<br>
> @@ -37,9 +37,13 @@ define void @foo(i8 %a, i16 %b) nounwind<br>
><br>
>  ;; A few test to check materialization<br>
>    %5 = call i32 @t2(i8 zeroext 255)<br>
> -; ELF64: clrldi {{[0-9]+}}, {{[0-9]+}}, 56<br>
> +; ELF64: li 3, 255<br>
> +; ELF64-NOT: clrldi<br>
>    %6 = call i32 @t4(i16 zeroext 65535)<br>
> -; ELF64: clrldi {{[0-9]+}}, {{[0-9]+}}, 48<br>
> +; ELF64: lis 3, 0<br>
> +; ELF64: ori 3, 3, 65535<br>
> +; ELF64: clrldi 3, 3, 48<br>
> +; ELF64: bl t4<br>
>    ret void<br>
>  }<br>
><br>
> @@ -66,12 +70,8 @@ entry:<br>
>  ; ELF64: li 6, 28<br>
>  ; ELF64: li 7, 40<br>
>  ; ELF64: li 8, 186<br>
> -; ELF64: clrldi 3, 3, 56<br>
> -; ELF64: clrldi 4, 4, 56<br>
> -; ELF64: clrldi 5, 5, 56<br>
> -; ELF64: clrldi 6, 6, 56<br>
> -; ELF64: clrldi 7, 7, 56<br>
> -; ELF64: clrldi 8, 8, 56<br>
> +; ELF64-NOT: clrldi<br>
> +; ELF64: bl bar<br>
>    ret i32 0<br>
>  }<br>
><br>
><br>
> Modified: llvm/trunk/test/CodeGen/<wbr>PowerPC/setcc-logic.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/setcc-logic.ll?rev=320791&r1=320790&r2=320791&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>CodeGen/PowerPC/setcc-logic.<wbr>ll?rev=320791&r1=320790&r2=<wbr>320791&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/test/CodeGen/<wbr>PowerPC/setcc-logic.ll (original)<br>
> +++ llvm/trunk/test/CodeGen/<wbr>PowerPC/setcc-logic.ll Thu Dec 14 23:27:53 2017<br>
> @@ -418,9 +418,9 @@ define <4 x i1> @any_sign_bits_clear_vec<br>
>  define zeroext i1 @ne_neg1_and_ne_zero(i64 %x) {<br>
>  ; CHECK-LABEL: ne_neg1_and_ne_zero:<br>
>  ; CHECK:       # %bb.0:<br>
> -; CHECK-NEXT:    li 4, 1<br>
>  ; CHECK-NEXT:    addi 3, 3, 1<br>
> -; CHECK-NEXT:    subfc 3, 3, 4<br>
> +; CHECK-NEXT:    li 4, 1<br>
> +; CHECK-NEXT:    subfic 3, 3, 1<br>
>  ; CHECK-NEXT:    subfe 3, 4, 4<br>
>  ; CHECK-NEXT:    neg 3, 3<br>
>  ; CHECK-NEXT:    blr<br>
><br>
> Added: llvm/trunk/test/CodeGen/<wbr>PowerPC/<wbr>simplifyConstCmpToISEL.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/simplifyConstCmpToISEL.ll?rev=320791&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>CodeGen/PowerPC/<wbr>simplifyConstCmpToISEL.ll?rev=<wbr>320791&view=auto</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/test/CodeGen/<wbr>PowerPC/<wbr>simplifyConstCmpToISEL.ll (added)<br>
> +++ llvm/trunk/test/CodeGen/<wbr>PowerPC/<wbr>simplifyConstCmpToISEL.ll Thu Dec 14 23:27:53 2017<br>
> @@ -0,0 +1,51 @@<br>
> +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.<wbr>py<br>
> +; RUN: llc < %s -mtriple=powerpc64le-unknown-<wbr>unknown -mcpu=pwr8 \<br>
> +; RUN:   -ppc-convert-rr-to-ri -verify-machineinstrs | FileCheck %s<br>
> +define void @test(i32 zeroext %parts) {<br>
> +; CHECK-LABEL: test:<br>
> +; CHECK:       # %bb.0: # %cond.end.i<br>
> +; CHECK-NEXT:    cmplwi 0, 3, 1<br>
> +; CHECK-NEXT:    bnelr+ 0<br>
> +; CHECK-NEXT:  # %bb.1: # %test2.exit.us.unr-lcssa<br>
> +; CHECK-NEXT:    ld 3, 0(3)<br>
> +; CHECK-NEXT:    std 3, 0(3)<br>
> +entry:<br>
> +  br label %cond.end.i<br>
> +<br>
> +cond.end.i:                                       ; preds = %entry<br>
> +  %cmp18.i = icmp eq i32 %parts, 1<br>
> +  br i1 %cmp18.i, label %<a href="http://while.body.lr.ph.i.us">while.body.lr.ph.i.us</a>.<wbr>preheader, label %test3.exit.split<br>
> +<br>
> +<a href="http://while.body.lr.ph.i.us">while.body.lr.ph.i.us</a>.<wbr>preheader:                  ; preds = %cond.end.i<br>
> +  %0 = icmp eq i32 %parts, 1<br>
> +  br label %for.body.i62.us.preheader<br>
> +<br>
> +for.body.i62.us.preheader:                        ; preds = %<a href="http://while.body.lr.ph.i.us">while.body.lr.ph.i.us</a>.<wbr>preheader<br>
> +  br i1 %0, label %test2.exit.us.unr-lcssa, label %for.body.i62.us.preheader.new<br>
> +<br>
> +for.body.i62.us.preheader.<wbr>new:                    ; preds = %for.body.i62.us.preheader<br>
> +  br label %<a href="http://for.body.i62.us" rel="noreferrer" target="_blank">for.body.i62.us</a><br>
> +<br>
> +<a href="http://for.body.i62.us" rel="noreferrer" target="_blank">for.body.i62.us</a>:                                  ; preds = %if.end.i.us.1, %for.body.i62.us.preheader.new<br>
> +  %niter = phi i64 [ undef, %for.body.i62.us.preheader.new ], [ %niter.nsub.1, %if.end.i.us.1 ]<br>
> +  %cmp8.i.us.1 = icmp uge i64 undef, 0<br>
> +  br label %if.end.i.us.1<br>
> +<br>
> +test2.exit.us.unr-lcssa: ; preds = %if.end.i.us.1, %for.body.i62.us.preheader<br>
> +  %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 ]<br>
> +  %1 = load i64, i64* undef, align 8<br>
> +  %tobool.i61.us.epil = icmp eq i64 %c.addr.036.i.us.unr, 0<br>
> +  %<a href="http://add.neg.i.us.epil.pn" rel="noreferrer" target="_blank">add.neg.i.us.epil.pn</a> = select i1 %tobool.i61.us.epil, i64 %1, i64 0<br>
> +  %storemerge269 = sub i64 %<a href="http://add.neg.i.us.epil.pn" rel="noreferrer" target="_blank">add.neg.i.us.epil.pn</a>, 0<br>
> +  store i64 %storemerge269, i64* undef, align 8<br>
> +  unreachable<br>
> +<br>
> +test3.exit.split:             ; preds = %cond.end.i<br>
> +  ret void<br>
> +<br>
> +if.end.i.us.1:                                    ; preds = %<a href="http://for.body.i62.us" rel="noreferrer" target="_blank">for.body.i62.us</a><br>
> +  %c.addr.1.i.us.1 = zext i1 %cmp8.i.us.1 to i64<br>
> +  %niter.nsub.1 = add i64 %niter, -2<br>
> +  %niter.ncmp.1 = icmp eq i64 %niter.nsub.1, 0<br>
> +  br i1 %niter.ncmp.1, label %test2.exit.us.unr-lcssa, label %<a href="http://for.body.i62.us" rel="noreferrer" target="_blank">for.body.i62.us</a><br>
> +}<br>
><br>
> Modified: llvm/trunk/test/CodeGen/<wbr>PowerPC/unaligned.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/unaligned.ll?rev=320791&r1=320790&r2=320791&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>CodeGen/PowerPC/unaligned.ll?<wbr>rev=320791&r1=320790&r2=<wbr>320791&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/test/CodeGen/<wbr>PowerPC/unaligned.ll (original)<br>
> +++ llvm/trunk/test/CodeGen/<wbr>PowerPC/unaligned.ll Thu Dec 14 23:27:53 2017<br>
> @@ -89,7 +89,7 @@ entry:<br>
>  ; CHECK: @foo6<br>
>  ; CHECK-DAG: ld<br>
>  ; CHECK-DAG: ld<br>
> -; CHECK-DAG: stdx<br>
> +; CHECK-DAG: std<br>
>  ; CHECK: stdx<br>
><br>
>  ; For VSX on P7, unaligned loads and stores are preferable to aligned<br>
><br>
> Modified: llvm/trunk/test/CodeGen/<wbr>PowerPC/variable_elem_vec_<wbr>extracts.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/variable_elem_vec_extracts.ll?rev=320791&r1=320790&r2=320791&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>CodeGen/PowerPC/variable_elem_<wbr>vec_extracts.ll?rev=320791&r1=<wbr>320790&r2=320791&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/test/CodeGen/<wbr>PowerPC/variable_elem_vec_<wbr>extracts.ll (original)<br>
> +++ llvm/trunk/test/CodeGen/<wbr>PowerPC/variable_elem_vec_<wbr>extracts.ll Thu Dec 14 23:27:53 2017<br>
> @@ -70,9 +70,9 @@ entry:<br>
>  ; CHECK-LABEL: @getf<br>
>  ; CHECK-P7-LABEL: @getf<br>
>  ; CHECK-BE-LABEL: @getf<br>
> -; CHECK: li [[IMMREG:[0-9]+]], 3<br>
> -; CHECK: xor [[TRUNCREG:[0-9]+]], [[IMMREG]], 5<br>
> -; CHECK: lvsl [[SHMSKREG:[0-9]+]], 0, [[TRUNCREG]]<br>
> +; CHECK: xori [[TRUNCREG:[0-9]+]], 5, 3<br>
> +; CHECK: sldi [[SHIFTREG:[0-9]+]], [[TRUNCREG]], 2<br>
> +; CHECK: lvsl [[SHMSKREG:[0-9]+]], 0, [[SHIFTREG]]<br>
>  ; CHECK: vperm {{[0-9]+}}, 2, 2, [[SHMSKREG]]<br>
>  ; CHECK: xscvspdpn 1,<br>
>  ; CHECK-P7-DAG: rlwinm [[ELEMOFFREG:[0-9]+]], 5, 2, 28, 29<br>
><br>
><br>
> ______________________________<wbr>_________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
<br>
On Fri, Dec 15, 2017 at 8:27 AM, Nemanja Ivanovic via llvm-commits<br>
<<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br>
> Author: nemanjai<br>
> Date: Thu Dec 14 23:27:53 2017<br>
> New Revision: 320791<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=320791&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=320791&view=rev</a><br>
> Log:<br>
> [PowerPC] Convert r+r instructions to r+i (pre and post RA)<br>
><br>
> This patch adds the necessary infrastructure to convert instructions that<br>
> take two register operands to those that take a register and immediate if<br>
> the necessary operand is produced by a load-immediate. Furthermore, it uses<br>
> this infrastructure to perform such conversions twice - first at MachineSSA<br>
> and then pre-emit.<br>
><br>
> There are a number of reasons we may end up with opportunities for this<br>
> transformation, including but not limited to:<br>
> - X-Form instructions chosen since the exact offset isn't available at ISEL time<br>
> - Atomic instructions with constant operands (we will add patterns for this<br>
>   in the future)<br>
> - Tail duplication may duplicate code where one block contains this redundancy<br>
> - When emitting compare-free code in PPCDAGToDAGISel, we don't handle constant<br>
>   comparands specially<br>
><br>
> Furthermore, this patch moves the initialization of PPCMIPeepholePass so that<br>
> it can be used for MIR tests.<br>
><br>
> Added:<br>
>     llvm/trunk/lib/Target/PowerPC/<wbr>PPCPreEmitPeephole.cpp<br>
>     llvm/trunk/test/CodeGen/<wbr>PowerPC/convert-rr-to-ri-<wbr>instrs-R0-special-handling.mir<br>
>     llvm/trunk/test/CodeGen/<wbr>PowerPC/convert-rr-to-ri-<wbr>instrs.mir<br>
>     llvm/trunk/test/CodeGen/<wbr>PowerPC/<wbr>simplifyConstCmpToISEL.ll<br>
> Modified:<br>
>     llvm/trunk/lib/Target/PowerPC/<wbr>CMakeLists.txt<br>
>     llvm/trunk/lib/Target/PowerPC/<wbr>PPC.h<br>
>     llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstr64Bit.td<br>
>     llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.cpp<br>
>     llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.h<br>
>     llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.td<br>
>     llvm/trunk/lib/Target/PowerPC/<wbr>PPCMIPeephole.cpp<br>
>     llvm/trunk/lib/Target/PowerPC/<wbr>PPCTargetMachine.cpp<br>
>     llvm/trunk/test/CodeGen/<wbr>PowerPC/build-vector-tests.ll<br>
>     llvm/trunk/test/CodeGen/<wbr>PowerPC/fast-isel-call.ll<br>
>     llvm/trunk/test/CodeGen/<wbr>PowerPC/setcc-logic.ll<br>
>     llvm/trunk/test/CodeGen/<wbr>PowerPC/unaligned.ll<br>
>     llvm/trunk/test/CodeGen/<wbr>PowerPC/variable_elem_vec_<wbr>extracts.ll<br>
><br>
> Modified: llvm/trunk/lib/Target/PowerPC/<wbr>CMakeLists.txt<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/CMakeLists.txt?rev=320791&r1=320790&r2=320791&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>PowerPC/CMakeLists.txt?rev=<wbr>320791&r1=320790&r2=320791&<wbr>view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Target/PowerPC/<wbr>CMakeLists.txt (original)<br>
> +++ llvm/trunk/lib/Target/PowerPC/<wbr>CMakeLists.txt Thu Dec 14 23:27:53 2017<br>
> @@ -43,6 +43,7 @@ add_llvm_target(PowerPCCodeGen<br>
>    PPCVSXFMAMutate.cpp<br>
>    PPCVSXSwapRemoval.cpp<br>
>    PPCExpandISEL.cpp<br>
> +  PPCPreEmitPeephole.cpp<br>
>    )<br>
><br>
>  add_subdirectory(AsmParser)<br>
><br>
> Modified: llvm/trunk/lib/Target/PowerPC/<wbr>PPC.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPC.h?rev=320791&r1=320790&r2=320791&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>PowerPC/PPC.h?rev=320791&r1=<wbr>320790&r2=320791&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Target/PowerPC/<wbr>PPC.h (original)<br>
> +++ llvm/trunk/lib/Target/PowerPC/<wbr>PPC.h Thu Dec 14 23:27:53 2017<br>
> @@ -50,6 +50,7 @@ namespace llvm {<br>
>    FunctionPass *createPPCTLSDynamicCallPass()<wbr>;<br>
>    FunctionPass *createPPCBoolRetToIntPass();<br>
>    FunctionPass *createPPCExpandISELPass();<br>
> +  FunctionPass *createPPCPreEmitPeepholePass(<wbr>);<br>
>    void LowerPPCMachineInstrToMCInst(<wbr>const MachineInstr *MI, MCInst &OutMI,<br>
>                                      AsmPrinter &AP, bool isDarwin);<br>
>    bool LowerPPCMachineOperandToMCOper<wbr>and(const MachineOperand &MO,<br>
> @@ -59,7 +60,9 @@ namespace llvm {<br>
>    void initializePPCVSXFMAMutatePass(<wbr>PassRegistry&);<br>
>    void initializePPCBoolRetToIntPass(<wbr>PassRegistry&);<br>
>    void initializePPCExpandISELPass(<wbr>PassRegistry &);<br>
> +  void initializePPCPreEmitPeepholePa<wbr>ss(PassRegistry &);<br>
>    void initializePPCTLSDynamicCallPas<wbr>s(PassRegistry &);<br>
> +  void initializePPCMIPeepholePass(<wbr>PassRegistry&);<br>
>    extern char &PPCVSXFMAMutateID;<br>
><br>
>    namespace PPCII {<br>
><br>
> Modified: llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstr64Bit.td<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td?rev=320791&r1=320790&r2=320791&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>PowerPC/PPCInstr64Bit.td?rev=<wbr>320791&r1=320790&r2=320791&<wbr>view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstr64Bit.td (original)<br>
> +++ llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstr64Bit.td Thu Dec 14 23:27:53 2017<br>
> @@ -194,6 +194,11 @@ def : Pat<(PPCcall_nop (i64 texternalsym<br>
>            (BL8_NOP texternalsym:$dst)>;<br>
><br>
>  // Atomic operations<br>
> +// FIXME: some of these might be used with constant operands. This will result<br>
> +// in constant materialization instructions that may be redundant. We currently<br>
> +// clean this up in PPCMIPeephole with calls to<br>
> +// PPCInstrInfo::<wbr>convertToImmediateForm() but we should probably not emit them<br>
> +// in the first place.<br>
>  let usesCustomInserter = 1 in {<br>
>    let Defs = [CR0] in {<br>
>      def ATOMIC_LOAD_ADD_I64 : Pseudo<<br>
><br>
> Modified: llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp?rev=320791&r1=320790&r2=320791&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>PowerPC/PPCInstrInfo.cpp?rev=<wbr>320791&r1=320790&r2=320791&<wbr>view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.cpp (original)<br>
> +++ llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.cpp Thu Dec 14 23:27:53 2017<br>
> @@ -51,6 +51,10 @@ STATISTIC(<wbr>NumStoreSPILLVSRRCAsVec,<br>
>  STATISTIC(<wbr>NumStoreSPILLVSRRCAsGpr,<br>
>            "Number of spillvsrrc spilled to stack as gpr");<br>
>  STATISTIC(NumGPRtoVSRSpill, "Number of gpr spills to spillvsrrc");<br>
> +STATISTIC(CmpIselsConverted,<br>
> +          "Number of ISELs that depend on comparison of constants converted");<br>
> +STATISTIC(<wbr>MissedConvertibleImmediateInst<wbr>rs,<br>
> +          "Number of compare-immediate instructions fed by constants");<br>
><br>
>  static cl::<br>
>  opt<bool> DisableCTRLoopAnal("disable-<wbr>ppc-ctrloop-analysis", cl::Hidden,<br>
> @@ -2147,6 +2151,816 @@ bool PPCInstrInfo::<wbr>expandPostRAPseudo(Ma<br>
>    return false;<br>
>  }<br>
><br>
> +unsigned PPCInstrInfo::<wbr>lookThruCopyLike(unsigned SrcReg,<br>
> +                                        const MachineRegisterInfo *MRI) {<br>
> +  while (true) {<br>
> +    MachineInstr *MI = MRI->getVRegDef(SrcReg);<br>
> +    if (!MI->isCopyLike())<br>
> +      return SrcReg;<br>
> +<br>
> +    unsigned CopySrcReg;<br>
> +    if (MI->isCopy())<br>
> +      CopySrcReg = MI->getOperand(1).getReg();<br>
> +    else {<br>
> +      assert(MI->isSubregToReg() && "Bad opcode for lookThruCopyLike");<br>
> +      CopySrcReg = MI->getOperand(2).getReg();<br>
> +    }<br>
> +<br>
> +    if (!TargetRegisterInfo::<wbr>isVirtualRegister(CopySrcReg))<br>
> +      return CopySrcReg;<br>
> +<br>
> +    SrcReg = CopySrcReg;<br>
> +  }<br>
> +}<br>
> +<br>
> +// Essentially a compile-time implementation of a compare->isel sequence.<br>
> +// It takes two constants to compare, along with the true/false registers<br>
> +// and the comparison type (as a subreg to a CR field) and returns one<br>
> +// of the true/false registers, depending on the comparison results.<br>
> +static unsigned selectReg(int64_t Imm1, int64_t Imm2, unsigned CompareOpc,<br>
> +                          unsigned TrueReg, unsigned FalseReg,<br>
> +                          unsigned CRSubReg) {<br>
> +  // Signed comparisons. The immediates are assumed to be sign-extended.<br>
> +  if (CompareOpc == PPC::CMPWI || CompareOpc == PPC::CMPDI) {<br>
> +    switch (CRSubReg) {<br>
> +    default: llvm_unreachable("Unknown integer comparison type.");<br>
> +    case PPC::sub_lt:<br>
> +      return Imm1 < Imm2 ? TrueReg : FalseReg;<br>
> +    case PPC::sub_gt:<br>
> +      return Imm1 > Imm2 ? TrueReg : FalseReg;<br>
> +    case PPC::sub_eq:<br>
> +      return Imm1 == Imm2 ? TrueReg : FalseReg;<br>
> +    }<br>
> +  }<br>
> +  // Unsigned comparisons.<br>
> +  else if (CompareOpc == PPC::CMPLWI || CompareOpc == PPC::CMPLDI) {<br>
> +    switch (CRSubReg) {<br>
> +    default: llvm_unreachable("Unknown integer comparison type.");<br>
> +    case PPC::sub_lt:<br>
> +      return (uint64_t)Imm1 < (uint64_t)Imm2 ? TrueReg : FalseReg;<br>
> +    case PPC::sub_gt:<br>
> +      return (uint64_t)Imm1 > (uint64_t)Imm2 ? TrueReg : FalseReg;<br>
> +    case PPC::sub_eq:<br>
> +      return Imm1 == Imm2 ? TrueReg : FalseReg;<br>
> +    }<br>
> +  }<br>
> +  return PPC::NoRegister;<br>
> +}<br>
> +<br>
> +// Replace an instruction with one that materializes a constant (and sets<br>
> +// CR0 if the original instruction was a record-form instruction).<br>
> +void PPCInstrInfo::<wbr>replaceInstrWithLI(<wbr>MachineInstr &MI,<br>
> +                                      const LoadImmediateInfo &LII) const {<br>
> +  // Remove existing operands.<br>
> +  int OperandToKeep = LII.SetCR ? 1 : 0;<br>
> +  for (int i = MI.getNumOperands() - 1; i > OperandToKeep; i--)<br>
> +    MI.RemoveOperand(i);<br>
> +<br>
> +  // Replace the instruction.<br>
> +  if (LII.SetCR)<br>
> +    MI.setDesc(get(LII.Is64Bit ? PPC::ANDIo8 : PPC::ANDIo));<br>
> +  else<br>
> +    MI.setDesc(get(LII.Is64Bit ? PPC::LI8 : PPC::LI));<br>
> +<br>
> +  // Set the immediate.<br>
> +  MachineInstrBuilder(*MI.<wbr>getParent()->getParent(), MI)<br>
> +      .addImm(LII.Imm);<br>
> +}<br>
> +<br>
> +MachineInstr *PPCInstrInfo::<wbr>getConstantDefMI(MachineInstr &MI,<br>
> +                                             unsigned &ConstOp,<br>
> +                                             bool &SeenIntermediateUse) const {<br>
> +  ConstOp = ~0U;<br>
> +  MachineInstr *DefMI = nullptr;<br>
> +  MachineRegisterInfo *MRI = &MI.getParent()->getParent()-><wbr>getRegInfo();<br>
> +  // If we'ere in SSA, get the defs through the MRI. Otherwise, only look<br>
> +  // within the basic block to see if the register is defined using an LI/LI8.<br>
> +  if (MRI->isSSA()) {<br>
> +    for (int i = 1, e = MI.getNumOperands(); i < e; i++) {<br>
> +      if (!MI.getOperand(i).isReg())<br>
> +        continue;<br>
> +      unsigned Reg = MI.getOperand(i).getReg();<br>
> +      if (!TargetRegisterInfo::<wbr>isVirtualRegister(Reg))<br>
> +        continue;<br>
> +      unsigned TrueReg = lookThruCopyLike(Reg, MRI);<br>
> +      if (TargetRegisterInfo::<wbr>isVirtualRegister(TrueReg)) {<br>
> +        DefMI = MRI->getVRegDef(TrueReg);<br>
> +        if (DefMI->getOpcode() == PPC::LI || DefMI->getOpcode() == PPC::LI8) {<br>
> +          ConstOp = i;<br>
> +          break;<br>
> +        }<br>
> +      }<br>
> +    }<br>
> +  } else {<br>
> +    // Looking back through the definition for each operand could be expensive,<br>
> +    // so exit early if this isn't an instruction that either has an immediate<br>
> +    // form or is already an immediate form that we can handle.<br>
> +    ImmInstrInfo III;<br>
> +    unsigned Opc = MI.getOpcode();<br>
> +    bool ConvertibleImmForm =<br>
> +      Opc == PPC::CMPWI || Opc == PPC::CMPLWI ||<br>
> +      Opc == PPC::CMPDI || Opc == PPC::CMPLDI ||<br>
> +      Opc == PPC::ADDI || Opc == PPC::ADDI8 ||<br>
> +      Opc == PPC::ORI || Opc == PPC::ORI8 ||<br>
> +      Opc == PPC::XORI || Opc == PPC::XORI8 ||<br>
> +      Opc == PPC::RLDICL || Opc == PPC::RLDICLo ||<br>
> +      Opc == PPC::RLDICL_32 || Opc == PPC::RLDICL_32_64 ||<br>
> +      Opc == PPC::RLWINM || Opc == PPC::RLWINMo ||<br>
> +      Opc == PPC::RLWINM8 || Opc == PPC::RLWINM8o;<br>
> +    if (!instrHasImmForm(MI, III) && !ConvertibleImmForm)<br>
> +      return nullptr;<br>
> +<br>
> +    // Don't convert or %X, %Y, %Y since that's just a register move.<br>
> +    if ((Opc == PPC::OR || Opc == PPC::OR8) &&<br>
> +        MI.getOperand(1).getReg() == MI.getOperand(2).getReg())<br>
> +      return nullptr;<br>
> +    for (int i = 1, e = MI.getNumOperands(); i < e; i++) {<br>
> +      MachineOperand &MO = MI.getOperand(i);<br>
> +      SeenIntermediateUse = false;<br>
> +      if (MO.isReg() && MO.isUse() && !MO.isImplicit()) {<br>
> +        MachineBasicBlock::reverse_<wbr>iterator E = MI.getParent()->rend(), It = MI;<br>
> +        It++;<br>
> +        unsigned Reg = MI.getOperand(i).getReg();<br>
> +<br>
> +        // Is this register defined by a load-immediate in this block?<br>
> +        for ( ; It != E; ++It) {<br>
> +          if (It->modifiesRegister(Reg, &getRegisterInfo())) {<br>
> +            if (It->getOpcode() == PPC::LI || It->getOpcode() == PPC::LI8) {<br>
> +              ConstOp = i;<br>
> +              return &*It;<br>
> +            } else<br>
> +              break;<br>
> +          } else if (It->readsRegister(Reg, &getRegisterInfo()))<br>
> +            // If we see another use of this reg between the def and the MI,<br>
> +            // we want to flat it so the def isn't deleted.<br>
> +            SeenIntermediateUse = true;<br>
> +        }<br>
> +      }<br>
> +    }<br>
> +  }<br>
> +  return ConstOp == ~0U ? nullptr : DefMI;<br>
> +}<br>
> +<br>
> +// If this instruction has an immediate form and one of its operands is a<br>
> +// result of a load-immediate, convert it to the immediate form if the constant<br>
> +// is in range.<br>
> +bool PPCInstrInfo::<wbr>convertToImmediateForm(<wbr>MachineInstr &MI,<br>
> +                                          MachineInstr **KilledDef) const {<br>
> +  MachineFunction *MF = MI.getParent()->getParent();<br>
> +  MachineRegisterInfo *MRI = &MF->getRegInfo();<br>
> +  bool PostRA = !MRI->isSSA();<br>
> +  bool SeenIntermediateUse = true;<br>
> +  unsigned ConstantOperand = ~0U;<br>
> +  MachineInstr *DefMI = getConstantDefMI(MI, ConstantOperand,<br>
> +                                         SeenIntermediateUse);<br>
> +  if (!DefMI || !DefMI->getOperand(1).isImm())<br>
> +    return false;<br>
> +  assert(ConstantOperand < MI.getNumOperands() &&<br>
> +         "The constant operand needs to be valid at this point");<br>
> +<br>
> +  int64_t Immediate = DefMI->getOperand(1).getImm();<br>
> +  // Sign-extend to 64-bits.<br>
> +  int64_t SExtImm = ((uint64_t)Immediate & ~0x7FFFuLL) != 0 ?<br>
> +    (Immediate | 0xFFFFFFFFFFFF0000) : Immediate;<br>
> +<br>
> +  if (KilledDef && MI.getOperand(ConstantOperand)<wbr>.isKill() &&<br>
> +      !SeenIntermediateUse)<br>
> +    *KilledDef = DefMI;<br>
> +<br>
> +  // If this is a reg+reg instruction that has a reg+imm form, convert it now.<br>
> +  ImmInstrInfo III;<br>
> +  if (instrHasImmForm(MI, III))<br>
> +    return transformToImmForm(MI, III, ConstantOperand, SExtImm);<br>
> +<br>
> +  bool ReplaceWithLI = false;<br>
> +  bool Is64BitLI = false;<br>
> +  int64_t NewImm = 0;<br>
> +  bool SetCR = false;<br>
> +  unsigned Opc = MI.getOpcode();<br>
> +  switch (Opc) {<br>
> +  default: return false;<br>
> +<br>
> +  // FIXME: Any branches conditional on such a comparison can be made<br>
> +  // unconditional. At this time, this happens too infrequently to be worth<br>
> +  // the implementation effort, but if that ever changes, we could convert<br>
> +  // such a pattern here.<br>
> +  case PPC::CMPWI:<br>
> +  case PPC::CMPLWI:<br>
> +  case PPC::CMPDI:<br>
> +  case PPC::CMPLDI: {<br>
> +    // Doing this post-RA would require dataflow analysis to reliably find uses<br>
> +    // of the CR register set by the compare.<br>
> +    if (PostRA)<br>
> +      return false;<br>
> +    // If a compare-immediate is fed by an immediate and is itself an input of<br>
> +    // an ISEL (the most common case) into a COPY of the correct register.<br>
> +    bool Changed = false;<br>
> +    unsigned DefReg = MI.getOperand(0).getReg();<br>
> +    int64_t Comparand = MI.getOperand(2).getImm();<br>
> +    int64_t SExtComparand = ((uint64_t)Comparand & ~0x7FFFuLL) != 0 ?<br>
> +      (Comparand | 0xFFFFFFFFFFFF0000) : Comparand;<br>
> +<br>
> +    for (auto &CompareUseMI : MRI->use_instructions(DefReg)) {<br>
> +      unsigned UseOpc = CompareUseMI.getOpcode();<br>
> +      if (UseOpc != PPC::ISEL && UseOpc != PPC::ISEL8)<br>
> +        continue;<br>
> +      unsigned CRSubReg = CompareUseMI.getOperand(3).<wbr>getSubReg();<br>
> +      unsigned TrueReg = CompareUseMI.getOperand(1).<wbr>getReg();<br>
> +      unsigned FalseReg = CompareUseMI.getOperand(2).<wbr>getReg();<br>
> +      unsigned RegToCopy = selectReg(SExtImm, SExtComparand, Opc, TrueReg,<br>
> +                                     FalseReg, CRSubReg);<br>
> +      if (RegToCopy == PPC::NoRegister)<br>
> +        continue;<br>
> +      // Can't use PPC::COPY to copy PPC::ZERO[8]. Convert it to LI[8] 0.<br>
> +      if (RegToCopy == PPC::ZERO || RegToCopy == PPC::ZERO8) {<br>
> +        CompareUseMI.setDesc(get(<wbr>UseOpc == PPC::ISEL8 ? PPC::LI8 : PPC::LI));<br>
> +        CompareUseMI.getOperand(1).<wbr>ChangeToImmediate(0);<br>
> +        CompareUseMI.RemoveOperand(3);<br>
> +        CompareUseMI.RemoveOperand(2);<br>
> +        continue;<br>
> +      }<br>
> +      DEBUG(dbgs() << "Found LI -> CMPI -> ISEL, replacing with a copy.\n");<br>
> +      DEBUG(DefMI->dump(); MI.dump(); CompareUseMI.dump());<br>
> +      DEBUG(dbgs() << "Is converted to:\n");<br>
> +      // Convert to copy and remove unneeded operands.<br>
> +      CompareUseMI.setDesc(get(PPC::<wbr>COPY));<br>
> +      CompareUseMI.RemoveOperand(3);<br>
> +      CompareUseMI.RemoveOperand(<wbr>RegToCopy == TrueReg ? 2 : 1);<br>
> +      CmpIselsConverted++;<br>
> +      Changed = true;<br>
> +      DEBUG(CompareUseMI.dump());<br>
> +    }<br>
> +    if (Changed)<br>
> +      return true;<br>
> +    // This may end up incremented multiple times since this function is called<br>
> +    // during a fixed-point transformation, but it is only meant to indicate the<br>
> +    // presence of this opportunity.<br>
> +    MissedConvertibleImmediateInst<wbr>rs++;<br>
> +    return false;<br>
> +  }<br>
> +<br>
> +  // Immediate forms - may simply be convertable to an LI.<br>
> +  case PPC::ADDI:<br>
> +  case PPC::ADDI8: {<br>
> +    // Does the sum fit in a 16-bit signed field?<br>
> +    int64_t Addend = MI.getOperand(2).getImm();<br>
> +    if (isInt<16>(Addend + SExtImm)) {<br>
> +      ReplaceWithLI = true;<br>
> +      Is64BitLI = Opc == PPC::ADDI8;<br>
> +      NewImm = Addend + SExtImm;<br>
> +      break;<br>
> +    }<br>
> +  }<br>
> +  case PPC::RLDICL:<br>
> +  case PPC::RLDICLo:<br>
> +  case PPC::RLDICL_32:<br>
> +  case PPC::RLDICL_32_64: {<br>
> +    // Use APInt's rotate function.<br>
> +    int64_t SH = MI.getOperand(2).getImm();<br>
> +    int64_t MB = MI.getOperand(3).getImm();<br>
> +    APInt InVal(Opc == PPC::RLDICL ? 64 : 32, SExtImm, true);<br>
> +    InVal = InVal.rotl(SH);<br>
> +    uint64_t Mask = (1LU << (63 - MB + 1)) - 1;<br>
> +    InVal &= Mask;<br>
> +    // Can't replace negative values with an LI as that will sign-extend<br>
> +    // and not clear the left bits. If we're setting the CR bit, we will use<br>
> +    // ANDIo which won't sign extend, so that's safe.<br>
> +    if (isUInt<15>(InVal.<wbr>getSExtValue()) ||<br>
> +        (Opc == PPC::RLDICLo && isUInt<16>(InVal.getSExtValue(<wbr>)))) {<br>
> +      ReplaceWithLI = true;<br>
> +      Is64BitLI = Opc != PPC::RLDICL_32;<br>
> +      NewImm = InVal.getSExtValue();<br>
> +      SetCR = Opc == PPC::RLDICLo;<br>
> +      break;<br>
> +    }<br>
> +    return false;<br>
> +  }<br>
> +  case PPC::RLWINM:<br>
> +  case PPC::RLWINM8:<br>
> +  case PPC::RLWINMo:<br>
> +  case PPC::RLWINM8o: {<br>
> +    int64_t SH = MI.getOperand(2).getImm();<br>
> +    int64_t MB = MI.getOperand(3).getImm();<br>
> +    int64_t ME = MI.getOperand(4).getImm();<br>
> +    APInt InVal(32, SExtImm, true);<br>
> +    InVal = InVal.rotl(SH);<br>
> +    // Set the bits (       MB + 32      ) to (       ME + 32      ).<br>
> +    uint64_t Mask = ((1 << (32 - MB)) - 1) & ~((1 << (31 - ME)) - 1);<br>
> +    InVal &= Mask;<br>
> +    // Can't replace negative values with an LI as that will sign-extend<br>
> +    // and not clear the left bits. If we're setting the CR bit, we will use<br>
> +    // ANDIo which won't sign extend, so that's safe.<br>
> +    bool ValueFits = isUInt<15>(InVal.getSExtValue(<wbr>));<br>
> +    ValueFits |= ((Opc == PPC::RLWINMo || Opc == PPC::RLWINM8o) &&<br>
> +                  isUInt<16>(InVal.getSExtValue(<wbr>)));<br>
> +    if (ValueFits) {<br>
> +      ReplaceWithLI = true;<br>
> +      Is64BitLI = Opc == PPC::RLWINM8 || Opc == PPC::RLWINM8o;<br>
> +      NewImm = InVal.getSExtValue();<br>
> +      SetCR = Opc == PPC::RLWINMo || Opc == PPC::RLWINM8o;<br>
> +      break;<br>
> +    }<br>
> +    return false;<br>
> +  }<br>
> +  case PPC::ORI:<br>
> +  case PPC::ORI8:<br>
> +  case PPC::XORI:<br>
> +  case PPC::XORI8: {<br>
> +    int64_t LogicalImm = MI.getOperand(2).getImm();<br>
> +    int64_t Result = 0;<br>
> +    if (Opc == PPC::ORI || Opc == PPC::ORI8)<br>
> +      Result = LogicalImm | SExtImm;<br>
> +    else<br>
> +      Result = LogicalImm ^ SExtImm;<br>
> +    if (isInt<16>(Result)) {<br>
> +      ReplaceWithLI = true;<br>
> +      Is64BitLI = Opc == PPC::ORI8 || Opc == PPC::XORI8;<br>
> +      NewImm = Result;<br>
> +      break;<br>
> +    }<br>
> +    return false;<br>
> +  }<br>
> +  }<br>
> +<br>
> +  if (ReplaceWithLI) {<br>
> +    DEBUG(dbgs() << "Replacing instruction:\n");<br>
> +    DEBUG(MI.dump());<br>
> +    DEBUG(dbgs() << "Fed by:\n");<br>
> +    DEBUG(DefMI->dump());<br>
> +    LoadImmediateInfo LII;<br>
> +    LII.Imm = NewImm;<br>
> +    LII.Is64Bit = Is64BitLI;<br>
> +    LII.SetCR = SetCR;<br>
> +    // If we're setting the CR, the original load-immediate must be kept (as an<br>
> +    // operand to ANDIo/ANDI8o).<br>
> +    if (KilledDef && SetCR)<br>
> +      *KilledDef = nullptr;<br>
> +    replaceInstrWithLI(MI, LII);<br>
> +    DEBUG(dbgs() << "With:\n");<br>
> +    DEBUG(MI.dump());<br>
> +    return true;<br>
> +  }<br>
> +  return false;<br>
> +}<br>
> +<br>
> +bool PPCInstrInfo::instrHasImmForm(<wbr>const MachineInstr &MI,<br>
> +                                   ImmInstrInfo &III) const {<br>
> +  unsigned Opc = MI.getOpcode();<br>
> +  // The vast majority of the instructions would need their operand 2 replaced<br>
> +  // with an immediate when switching to the reg+imm form. A marked exception<br>
> +  // are the update form loads/stores for which a constant operand 2 would need<br>
> +  // to turn into a displacement and move operand 1 to the operand 2 position.<br>
> +  III.ImmOpNo = 2;<br>
> +  III.ConstantOpNo = 2;<br>
> +  III.ImmWidth = 16;<br>
> +  III.ImmMustBeMultipleOf = 1;<br>
> +  switch (Opc) {<br>
> +  default: return false;<br>
> +  case PPC::ADD4:<br>
> +  case PPC::ADD8:<br>
> +    III.SignedImm = true;<br>
> +    III.ZeroIsSpecialOrig = 0;<br>
> +    III.ZeroIsSpecialNew = 1;<br>
> +    III.IsCommutative = true;<br>
> +    III.ImmOpcode = Opc == PPC::ADD4 ? PPC::ADDI : PPC::ADDI8;<br>
> +    break;<br>
> +  case PPC::ADDC:<br>
> +  case PPC::ADDC8:<br>
> +    III.SignedImm = true;<br>
> +    III.ZeroIsSpecialOrig = 0;<br>
> +    III.ZeroIsSpecialNew = 0;<br>
> +    III.IsCommutative = true;<br>
> +    III.ImmOpcode = Opc == PPC::ADDC ? PPC::ADDIC : PPC::ADDIC8;<br>
> +    break;<br>
> +  case PPC::ADDCo:<br>
> +    III.SignedImm = true;<br>
> +    III.ZeroIsSpecialOrig = 0;<br>
> +    III.ZeroIsSpecialNew = 0;<br>
> +    III.IsCommutative = true;<br>
> +    III.ImmOpcode = PPC::ADDICo;<br>
> +    break;<br>
> +  case PPC::SUBFC:<br>
> +  case PPC::SUBFC8:<br>
> +    III.SignedImm = true;<br>
> +    III.ZeroIsSpecialOrig = 0;<br>
> +    III.ZeroIsSpecialNew = 0;<br>
> +    III.IsCommutative = false;<br>
> +    III.ImmOpcode = Opc == PPC::SUBFC ? PPC::SUBFIC : PPC::SUBFIC8;<br>
> +    break;<br>
> +  case PPC::CMPW:<br>
> +  case PPC::CMPD:<br>
> +    III.SignedImm = true;<br>
> +    III.ZeroIsSpecialOrig = 0;<br>
> +    III.ZeroIsSpecialNew = 0;<br>
> +    III.IsCommutative = false;<br>
> +    III.ImmOpcode = Opc == PPC::CMPW ? PPC::CMPWI : PPC::CMPDI;<br>
> +    break;<br>
> +  case PPC::CMPLW:<br>
> +  case PPC::CMPLD:<br>
> +    III.SignedImm = false;<br>
> +    III.ZeroIsSpecialOrig = 0;<br>
> +    III.ZeroIsSpecialNew = 0;<br>
> +    III.IsCommutative = false;<br>
> +    III.ImmOpcode = Opc == PPC::CMPLW ? PPC::CMPLWI : PPC::CMPLDI;<br>
> +    break;<br>
> +  case PPC::ANDo:<br>
> +  case PPC::AND8o:<br>
> +  case PPC::OR:<br>
> +  case PPC::OR8:<br>
> +  case PPC::XOR:<br>
> +  case PPC::XOR8:<br>
> +    III.SignedImm = false;<br>
> +    III.ZeroIsSpecialOrig = 0;<br>
> +    III.ZeroIsSpecialNew = 0;<br>
> +    III.IsCommutative = true;<br>
> +    switch(Opc) {<br>
> +    default: llvm_unreachable("Unknown opcode");<br>
> +    case PPC::ANDo: III.ImmOpcode = PPC::ANDIo; break;<br>
> +    case PPC::AND8o: III.ImmOpcode = PPC::ANDIo8; break;<br>
> +    case PPC::OR: III.ImmOpcode = PPC::ORI; break;<br>
> +    case PPC::OR8: III.ImmOpcode = PPC::ORI8; break;<br>
> +    case PPC::XOR: III.ImmOpcode = PPC::XORI; break;<br>
> +    case PPC::XOR8: III.ImmOpcode = PPC::XORI8; break;<br>
> +    }<br>
> +    break;<br>
> +  case PPC::RLWNM:<br>
> +  case PPC::RLWNM8:<br>
> +  case PPC::RLWNMo:<br>
> +  case PPC::RLWNM8o:<br>
> +  case PPC::RLDCL:<br>
> +  case PPC::RLDCLo:<br>
> +  case PPC::RLDCR:<br>
> +  case PPC::RLDCRo:<br>
> +  case PPC::SLW:<br>
> +  case PPC::SLW8:<br>
> +  case PPC::SLWo:<br>
> +  case PPC::SLW8o:<br>
> +  case PPC::SRW:<br>
> +  case PPC::SRW8:<br>
> +  case PPC::SRWo:<br>
> +  case PPC::SRW8o:<br>
> +  case PPC::SRAW:<br>
> +  case PPC::SRAWo:<br>
> +  case PPC::SLD:<br>
> +  case PPC::SLDo:<br>
> +  case PPC::SRD:<br>
> +  case PPC::SRDo:<br>
> +  case PPC::SRAD:<br>
> +  case PPC::SRADo:<br>
> +    III.SignedImm = false;<br>
> +    III.ZeroIsSpecialOrig = 0;<br>
> +    III.ZeroIsSpecialNew = 0;<br>
> +    III.IsCommutative = false;<br>
> +    // This isn't actually true, but the instructions ignore any of the<br>
> +    // upper bits, so any immediate loaded with an LI is acceptable.<br>
> +    III.ImmWidth = 16;<br>
> +    switch(Opc) {<br>
> +    default: llvm_unreachable("Unknown opcode");<br>
> +    case PPC::RLWNM: III.ImmOpcode = PPC::RLWINM; break;<br>
> +    case PPC::RLWNM8: III.ImmOpcode = PPC::RLWINM8; break;<br>
> +    case PPC::RLWNMo: III.ImmOpcode = PPC::RLWINMo; break;<br>
> +    case PPC::RLWNM8o: III.ImmOpcode = PPC::RLWINM8o; break;<br>
> +    case PPC::RLDCL: III.ImmOpcode = PPC::RLDICL; break;<br>
> +    case PPC::RLDCLo: III.ImmOpcode = PPC::RLDICLo; break;<br>
> +    case PPC::RLDCR: III.ImmOpcode = PPC::RLDICR; break;<br>
> +    case PPC::RLDCRo: III.ImmOpcode = PPC::RLDICRo; break;<br>
> +    case PPC::SLW: III.ImmOpcode = PPC::RLWINM; break;<br>
> +    case PPC::SLW8: III.ImmOpcode = PPC::RLWINM8; break;<br>
> +    case PPC::SLWo: III.ImmOpcode = PPC::RLWINMo; break;<br>
> +    case PPC::SLW8o: III.ImmOpcode = PPC::RLWINM8o; break;<br>
> +    case PPC::SRW: III.ImmOpcode = PPC::RLWINM; break;<br>
> +    case PPC::SRW8: III.ImmOpcode = PPC::RLWINM8; break;<br>
> +    case PPC::SRWo: III.ImmOpcode = PPC::RLWINMo; break;<br>
> +    case PPC::SRW8o: III.ImmOpcode = PPC::RLWINM8o; break;<br>
> +    case PPC::SRAW: III.ImmOpcode = PPC::SRAWI; break;<br>
> +    case PPC::SRAWo: III.ImmOpcode = PPC::SRAWIo; break;<br>
> +    case PPC::SLD: III.ImmOpcode = PPC::RLDICR; break;<br>
> +    case PPC::SLDo: III.ImmOpcode = PPC::RLDICRo; break;<br>
> +    case PPC::SRD: III.ImmOpcode = PPC::RLDICL; break;<br>
> +    case PPC::SRDo: III.ImmOpcode = PPC::RLDICLo; break;<br>
> +    case PPC::SRAD: III.ImmOpcode = PPC::SRADI; break;<br>
> +    case PPC::SRADo: III.ImmOpcode = PPC::SRADIo; break;<br>
> +    }<br>
> +    break;<br>
> +  // Loads and stores:<br>
> +  case PPC::LBZX:<br>
> +  case PPC::LBZX8:<br>
> +  case PPC::LHZX:<br>
> +  case PPC::LHZX8:<br>
> +  case PPC::LHAX:<br>
> +  case PPC::LHAX8:<br>
> +  case PPC::LWZX:<br>
> +  case PPC::LWZX8:<br>
> +  case PPC::LWAX:<br>
> +  case PPC::LDX:<br>
> +  case PPC::LFSX:<br>
> +  case PPC::LFDX:<br>
> +  case PPC::STBX:<br>
> +  case PPC::STBX8:<br>
> +  case PPC::STHX:<br>
> +  case PPC::STHX8:<br>
> +  case PPC::STWX:<br>
> +  case PPC::STWX8:<br>
> +  case PPC::STDX:<br>
> +  case PPC::STFSX:<br>
> +  case PPC::STFDX:<br>
> +    III.SignedImm = true;<br>
> +    III.ZeroIsSpecialOrig = 1;<br>
> +    III.ZeroIsSpecialNew = 2;<br>
> +    III.IsCommutative = true;<br>
> +    III.ImmOpNo = 1;<br>
> +    III.ConstantOpNo = 2;<br>
> +    switch(Opc) {<br>
> +    default: llvm_unreachable("Unknown opcode");<br>
> +    case PPC::LBZX: III.ImmOpcode = PPC::LBZ; break;<br>
> +    case PPC::LBZX8: III.ImmOpcode = PPC::LBZ8; break;<br>
> +    case PPC::LHZX: III.ImmOpcode = PPC::LHZ; break;<br>
> +    case PPC::LHZX8: III.ImmOpcode = PPC::LHZ8; break;<br>
> +    case PPC::LHAX: III.ImmOpcode = PPC::LHA; break;<br>
> +    case PPC::LHAX8: III.ImmOpcode = PPC::LHA8; break;<br>
> +    case PPC::LWZX: III.ImmOpcode = PPC::LWZ; break;<br>
> +    case PPC::LWZX8: III.ImmOpcode = PPC::LWZ8; break;<br>
> +    case PPC::LWAX:<br>
> +      III.ImmOpcode = PPC::LWA;<br>
> +      III.ImmMustBeMultipleOf = 4;<br>
> +      break;<br>
> +    case PPC::LDX: III.ImmOpcode = PPC::LD; III.ImmMustBeMultipleOf = 4; break;<br>
> +    case PPC::LFSX: III.ImmOpcode = PPC::LFS; break;<br>
> +    case PPC::LFDX: III.ImmOpcode = PPC::LFD; break;<br>
> +    case PPC::STBX: III.ImmOpcode = PPC::STB; break;<br>
> +    case PPC::STBX8: III.ImmOpcode = PPC::STB8; break;<br>
> +    case PPC::STHX: III.ImmOpcode = PPC::STH; break;<br>
> +    case PPC::STHX8: III.ImmOpcode = PPC::STH8; break;<br>
> +    case PPC::STWX: III.ImmOpcode = PPC::STW; break;<br>
> +    case PPC::STWX8: III.ImmOpcode = PPC::STW8; break;<br>
> +    case PPC::STDX:<br>
> +      III.ImmOpcode = PPC::STD;<br>
> +      III.ImmMustBeMultipleOf = 4;<br>
> +      break;<br>
> +    case PPC::STFSX: III.ImmOpcode = PPC::STFS; break;<br>
> +    case PPC::STFDX: III.ImmOpcode = PPC::STFD; break;<br>
> +    }<br>
> +    break;<br>
> +  case PPC::LBZUX:<br>
> +  case PPC::LBZUX8:<br>
> +  case PPC::LHZUX:<br>
> +  case PPC::LHZUX8:<br>
> +  case PPC::LHAUX:<br>
> +  case PPC::LHAUX8:<br>
> +  case PPC::LWZUX:<br>
> +  case PPC::LWZUX8:<br>
> +  case PPC::LDUX:<br>
> +  case PPC::LFSUX:<br>
> +  case PPC::LFDUX:<br>
> +  case PPC::STBUX:<br>
> +  case PPC::STBUX8:<br>
> +  case PPC::STHUX:<br>
> +  case PPC::STHUX8:<br>
> +  case PPC::STWUX:<br>
> +  case PPC::STWUX8:<br>
> +  case PPC::STDUX:<br>
> +  case PPC::STFSUX:<br>
> +  case PPC::STFDUX:<br>
> +    III.SignedImm = true;<br>
> +    III.ZeroIsSpecialOrig = 2;<br>
> +    III.ZeroIsSpecialNew = 3;<br>
> +    III.IsCommutative = false;<br>
> +    III.ImmOpNo = 2;<br>
> +    III.ConstantOpNo = 3;<br>
> +    switch(Opc) {<br>
> +    default: llvm_unreachable("Unknown opcode");<br>
> +    case PPC::LBZUX: III.ImmOpcode = PPC::LBZU; break;<br>
> +    case PPC::LBZUX8: III.ImmOpcode = PPC::LBZU8; break;<br>
> +    case PPC::LHZUX: III.ImmOpcode = PPC::LHZU; break;<br>
> +    case PPC::LHZUX8: III.ImmOpcode = PPC::LHZU8; break;<br>
> +    case PPC::LHAUX: III.ImmOpcode = PPC::LHAU; break;<br>
> +    case PPC::LHAUX8: III.ImmOpcode = PPC::LHAU8; break;<br>
> +    case PPC::LWZUX: III.ImmOpcode = PPC::LWZU; break;<br>
> +    case PPC::LWZUX8: III.ImmOpcode = PPC::LWZU8; break;<br>
> +    case PPC::LDUX:<br>
> +      III.ImmOpcode = PPC::LDU;<br>
> +      III.ImmMustBeMultipleOf = 4;<br>
> +      break;<br>
> +    case PPC::LFSUX: III.ImmOpcode = PPC::LFSU; break;<br>
> +    case PPC::LFDUX: III.ImmOpcode = PPC::LFDU; break;<br>
> +    case PPC::STBUX: III.ImmOpcode = PPC::STBU; break;<br>
> +    case PPC::STBUX8: III.ImmOpcode = PPC::STBU8; break;<br>
> +    case PPC::STHUX: III.ImmOpcode = PPC::STHU; break;<br>
> +    case PPC::STHUX8: III.ImmOpcode = PPC::STHU8; break;<br>
> +    case PPC::STWUX: III.ImmOpcode = PPC::STWU; break;<br>
> +    case PPC::STWUX8: III.ImmOpcode = PPC::STWU8; break;<br>
> +    case PPC::STDUX:<br>
> +      III.ImmOpcode = PPC::STDU;<br>
> +      III.ImmMustBeMultipleOf = 4;<br>
> +      break;<br>
> +    case PPC::STFSUX: III.ImmOpcode = PPC::STFSU; break;<br>
> +    case PPC::STFDUX: III.ImmOpcode = PPC::STFDU; break;<br>
> +    }<br>
> +    break;<br>
> +  // Power9 only.<br>
> +  case PPC::LXVX:<br>
> +  case PPC::LXSSPX:<br>
> +  case PPC::LXSDX:<br>
> +  case PPC::STXVX:<br>
> +  case PPC::STXSSPX:<br>
> +  case PPC::STXSDX:<br>
> +    if (!Subtarget.hasP9Vector())<br>
> +      return false;<br>
> +    III.SignedImm = true;<br>
> +    III.ZeroIsSpecialOrig = 1;<br>
> +    III.ZeroIsSpecialNew = 2;<br>
> +    III.IsCommutative = true;<br>
> +    III.ImmOpNo = 1;<br>
> +    III.ConstantOpNo = 2;<br>
> +    switch(Opc) {<br>
> +    default: llvm_unreachable("Unknown opcode");<br>
> +    case PPC::LXVX:<br>
> +      III.ImmOpcode = PPC::LXV;<br>
> +      III.ImmMustBeMultipleOf = 16;<br>
> +      break;<br>
> +    case PPC::LXSSPX:<br>
> +      III.ImmOpcode = PPC::LXSSP;<br>
> +      III.ImmMustBeMultipleOf = 4;<br>
> +      break;<br>
> +    case PPC::LXSDX:<br>
> +      III.ImmOpcode = PPC::LXSD;<br>
> +      III.ImmMustBeMultipleOf = 4;<br>
> +      break;<br>
> +    case PPC::STXVX:<br>
> +      III.ImmOpcode = PPC::STXV;<br>
> +      III.ImmMustBeMultipleOf = 16;<br>
> +      break;<br>
> +    case PPC::STXSSPX:<br>
> +      III.ImmOpcode = PPC::STXSSP;<br>
> +      III.ImmMustBeMultipleOf = 4;<br>
> +      break;<br>
> +    case PPC::STXSDX:<br>
> +      III.ImmOpcode = PPC::STXSD;<br>
> +      III.ImmMustBeMultipleOf = 4;<br>
> +      break;<br>
> +    }<br>
> +    break;<br>
> +  }<br>
> +  return true;<br>
> +}<br>
> +<br>
> +// Utility function for swaping two arbitrary operands of an instruction.<br>
> +static void swapMIOperands(MachineInstr &MI, unsigned Op1, unsigned Op2) {<br>
> +  assert(Op1 != Op2 && "Cannot swap operand with itself.");<br>
> +<br>
> +  unsigned MaxOp = std::max(Op1, Op2);<br>
> +  unsigned MinOp = std::min(Op1, Op2);<br>
> +  MachineOperand MOp1 = MI.getOperand(MinOp);<br>
> +  MachineOperand MOp2 = MI.getOperand(MaxOp);<br>
> +  MI.RemoveOperand(std::max(Op1, Op2));<br>
> +  MI.RemoveOperand(std::min(Op1, Op2));<br>
> +<br>
> +  // If the operands we are swapping are the two at the end (the common case)<br>
> +  // we can just remove both and add them in the opposite order.<br>
> +  if (MaxOp - MinOp == 1 && MI.getNumOperands() == MinOp) {<br>
> +    MI.addOperand(MOp2);<br>
> +    MI.addOperand(MOp1);<br>
> +  } else {<br>
> +    // Store all operands in a temporary vector, remove them and re-add in the<br>
> +    // right order.<br>
> +    SmallVector<MachineOperand, 2> MOps;<br>
> +    unsigned TotalOps = MI.getNumOperands() + 2; // We've already removed 2 ops.<br>
> +    for (unsigned i = MI.getNumOperands() - 1; i >= MinOp; i--) {<br>
> +      MOps.push_back(MI.getOperand(<wbr>i));<br>
> +      MI.RemoveOperand(i);<br>
> +    }<br>
> +    // MOp2 needs to be added next.<br>
> +    MI.addOperand(MOp2);<br>
> +    // Now add the rest.<br>
> +    for (unsigned i = MI.getNumOperands(); i < TotalOps; i++) {<br>
> +      if (i == MaxOp)<br>
> +        MI.addOperand(MOp1);<br>
> +      else {<br>
> +        MI.addOperand(MOps.back());<br>
> +        MOps.pop_back();<br>
> +      }<br>
> +    }<br>
> +  }<br>
> +}<br>
> +<br>
> +bool PPCInstrInfo::<wbr>transformToImmForm(<wbr>MachineInstr &MI, const ImmInstrInfo &III,<br>
> +                                      unsigned ConstantOpNo,<br>
> +                                      int64_t Imm) const {<br>
> +  MachineRegisterInfo &MRI = MI.getParent()->getParent()-><wbr>getRegInfo();<br>
> +  bool PostRA = !MRI.isSSA();<br>
> +  // Exit early if we can't convert this.<br>
> +  if ((ConstantOpNo != III.ConstantOpNo) && !III.IsCommutative)<br>
> +    return false;<br>
> +  if (Imm % III.ImmMustBeMultipleOf)<br>
> +    return false;<br>
> +  if (III.SignedImm) {<br>
> +    APInt ActualValue(64, Imm, true);<br>
> +    if (!ActualValue.isSignedIntN(<wbr>III.ImmWidth))<br>
> +      return false;<br>
> +  } else {<br>
> +    uint64_t UnsignedMax = (1 << III.ImmWidth) - 1;<br>
> +    if ((uint64_t)Imm > UnsignedMax)<br>
> +      return false;<br>
> +  }<br>
> +<br>
> +  // If we're post-RA, the instructions don't agree on whether register zero is<br>
> +  // special, we can transform this as long as the register operand that will<br>
> +  // end up in the location where zero is special isn't R0.<br>
> +  if (PostRA && III.ZeroIsSpecialOrig != III.ZeroIsSpecialNew) {<br>
> +    unsigned PosForOrigZero = III.ZeroIsSpecialOrig ? III.ZeroIsSpecialOrig :<br>
> +      III.ZeroIsSpecialNew + 1;<br>
> +    unsigned OrigZeroReg = MI.getOperand(PosForOrigZero).<wbr>getReg();<br>
> +    unsigned NewZeroReg = MI.getOperand(III.<wbr>ZeroIsSpecialNew).getReg();<br>
> +    // If R0 is in the operand where zero is special for the new instruction,<br>
> +    // it is unsafe to transform if the constant operand isn't that operand.<br>
> +    if ((NewZeroReg == PPC::R0 || NewZeroReg == PPC::X0) &&<br>
> +        ConstantOpNo != III.ZeroIsSpecialNew)<br>
> +      return false;<br>
> +    if ((OrigZeroReg == PPC::R0 || OrigZeroReg == PPC::X0) &&<br>
> +        ConstantOpNo != PosForOrigZero)<br>
> +      return false;<br>
> +  }<br>
> +<br>
> +  unsigned Opc = MI.getOpcode();<br>
> +  bool SpecialShift32 =<br>
> +    Opc == PPC::SLW || Opc == PPC::SLWo || Opc == PPC::SRW || Opc == PPC::SRWo;<br>
> +  bool SpecialShift64 =<br>
> +    Opc == PPC::SLD || Opc == PPC::SLDo || Opc == PPC::SRD || Opc == PPC::SRDo;<br>
> +  bool SetCR = Opc == PPC::SLWo || Opc == PPC::SRWo ||<br>
> +    Opc == PPC::SLDo || Opc == PPC::SRDo;<br>
> +  bool RightShift =<br>
> +    Opc == PPC::SRW || Opc == PPC::SRWo || Opc == PPC::SRD || Opc == PPC::SRDo;<br>
> +<br>
> +  MI.setDesc(get(III.ImmOpcode))<wbr>;<br>
> +  if (ConstantOpNo == III.ConstantOpNo) {<br>
> +    // Converting shifts to immediate form is a bit tricky since they may do<br>
> +    // one of three things:<br>
> +    // 1. If the shift amount is between OpSize and 2*OpSize, the result is zero<br>
> +    // 2. If the shift amount is zero, the result is unchanged (save for maybe<br>
> +    //    setting CR0)<br>
> +    // 3. If the shift amount is in [1, OpSize), it's just a shift<br>
> +    if (SpecialShift32 || SpecialShift64) {<br>
> +      LoadImmediateInfo LII;<br>
> +      LII.Imm = 0;<br>
> +      LII.SetCR = SetCR;<br>
> +      LII.Is64Bit = SpecialShift64;<br>
> +      uint64_t ShAmt = Imm & (SpecialShift32 ? 0x1F : 0x3F);<br>
> +      if (Imm & (SpecialShift32 ? 0x20 : 0x40))<br>
> +        replaceInstrWithLI(MI, LII);<br>
> +      // Shifts by zero don't change the value. If we don't need to set CR0,<br>
> +      // just convert this to a COPY. Can't do this post-RA since we've already<br>
> +      // cleaned up the copies.<br>
> +      else if (!SetCR && ShAmt == 0 && !PostRA) {<br>
> +        MI.RemoveOperand(2);<br>
> +        MI.setDesc(get(PPC::COPY));<br>
> +      } else {<br>
> +        // The 32 bit and 64 bit instructions are quite different.<br>
> +        if (SpecialShift32) {<br>
> +          // Left shifts use (N, 0, 31-N), right shifts use (32-N, N, 31).<br>
> +          uint64_t SH = RightShift ? 32 - ShAmt : ShAmt;<br>
> +          uint64_t MB = RightShift ? ShAmt : 0;<br>
> +          uint64_t ME = RightShift ? 31 : 31 - ShAmt;<br>
> +          MI.getOperand(III.<wbr>ConstantOpNo).<wbr>ChangeToImmediate(SH);<br>
> +          MachineInstrBuilder(*MI.<wbr>getParent()->getParent(), MI).addImm(MB)<br>
> +            .addImm(ME);<br>
> +        } else {<br>
> +          // Left shifts use (N, 63-N), right shifts use (64-N, N).<br>
> +          uint64_t SH = RightShift ? 64 - ShAmt : ShAmt;<br>
> +          uint64_t ME = RightShift ? ShAmt : 63 - ShAmt;<br>
> +          MI.getOperand(III.<wbr>ConstantOpNo).<wbr>ChangeToImmediate(SH);<br>
> +          MachineInstrBuilder(*MI.<wbr>getParent()->getParent(), MI).addImm(ME);<br>
> +        }<br>
> +      }<br>
> +    } else<br>
> +      MI.getOperand(ConstantOpNo).<wbr>ChangeToImmediate(Imm);<br>
> +  }<br>
> +  // Convert commutative instructions (switch the operands and convert the<br>
> +  // desired one to an immediate.<br>
> +  else if (III.IsCommutative) {<br>
> +    MI.getOperand(ConstantOpNo).<wbr>ChangeToImmediate(Imm);<br>
> +    swapMIOperands(MI, ConstantOpNo, III.ConstantOpNo);<br>
> +  } else<br>
> +    llvm_unreachable("Should have exited early!");<br>
> +<br>
> +  // For instructions for which the constant register replaces a different<br>
> +  // operand than where the immediate goes, we need to swap them.<br>
> +  if (III.ConstantOpNo != III.ImmOpNo)<br>
> +    swapMIOperands(MI, III.ConstantOpNo, III.ImmOpNo);<br>
> +<br>
> +  // If the R0/X0 register is special for the original instruction and not for<br>
> +  // the new instruction (or vice versa), we need to fix up the register class.<br>
> +  if (!PostRA && III.ZeroIsSpecialOrig != III.ZeroIsSpecialNew) {<br>
> +    if (!III.ZeroIsSpecialOrig) {<br>
> +      unsigned RegToModify = MI.getOperand(III.<wbr>ZeroIsSpecialNew).getReg();<br>
> +      const TargetRegisterClass *NewRC =<br>
> +        MRI.getRegClass(RegToModify)-><wbr>hasSuperClassEq(&PPC::<wbr>GPRCRegClass) ?<br>
> +        &PPC::GPRC_and_GPRC_<wbr>NOR0RegClass : &PPC::G8RC_and_G8RC_<wbr>NOX0RegClass;<br>
> +      MRI.setRegClass(RegToModify, NewRC);<br>
> +    }<br>
> +  }<br>
> +  return true;<br>
> +}<br>
> +<br>
>  const TargetRegisterClass *<br>
>  PPCInstrInfo::updatedRC(const TargetRegisterClass *RC) const {<br>
>    if (Subtarget.hasVSX() && RC == &PPC::VRRCRegClass)<br>
><br>
> Modified: llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h?rev=320791&r1=320790&r2=320791&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>PowerPC/PPCInstrInfo.h?rev=<wbr>320791&r1=320790&r2=320791&<wbr>view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.h (original)<br>
> +++ llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.h Thu Dec 14 23:27:53 2017<br>
> @@ -72,6 +72,41 @@ enum {<br>
>  };<br>
>  } // end namespace PPCII<br>
><br>
> +// Instructions that have an immediate form might be convertible to that<br>
> +// form if the correct input is a result of a load immediate. In order to<br>
> +// know whether the transformation is special, we might need to know some<br>
> +// of the details of the two forms.<br>
> +struct ImmInstrInfo {<br>
> +  // Is the immediate field in the immediate form signed or unsigned?<br>
> +  uint64_t SignedImm : 1;<br>
> +  // Does the immediate need to be a multiple of some value?<br>
> +  uint64_t ImmMustBeMultipleOf : 5;<br>
> +  // Is R0/X0 treated specially by the original r+r instruction?<br>
> +  // If so, in which operand?<br>
> +  uint64_t ZeroIsSpecialOrig : 3;<br>
> +  // Is R0/X0 treated specially by the new r+i instruction?<br>
> +  // If so, in which operand?<br>
> +  uint64_t ZeroIsSpecialNew : 3;<br>
> +  // Is the operation commutative?<br>
> +  uint64_t IsCommutative : 1;<br>
> +  // The operand number to check for load immediate.<br>
> +  uint64_t ConstantOpNo : 3;<br>
> +  // The operand number for the immediate.<br>
> +  uint64_t ImmOpNo : 3;<br>
> +  // The opcode of the new instruction.<br>
> +  uint64_t ImmOpcode : 16;<br>
> +  // The size of the immediate.<br>
> +  uint64_t ImmWidth : 5;<br>
> +};<br>
> +<br>
> +// Information required to convert an instruction to just a materialized<br>
> +// immediate.<br>
> +struct LoadImmediateInfo {<br>
> +  unsigned Imm : 16;<br>
> +  unsigned Is64Bit : 1;<br>
> +  unsigned SetCR : 1;<br>
> +};<br>
> +<br>
>  class PPCSubtarget;<br>
>  class PPCInstrInfo : public PPCGenInstrInfo {<br>
>    PPCSubtarget &Subtarget;<br>
> @@ -87,6 +122,10 @@ class PPCInstrInfo : public PPCGenInstrI<br>
>                              const TargetRegisterClass *RC,<br>
>                              SmallVectorImpl<MachineInstr *> &NewMIs,<br>
>                              bool &NonRI, bool &SpillsVRS) const;<br>
> +  bool transformToImmForm(<wbr>MachineInstr &MI, const ImmInstrInfo &III,<br>
> +                          unsigned ConstantOpNo, int64_t Imm) const;<br>
> +  MachineInstr *getConstantDefMI(MachineInstr &MI, unsigned &ConstOp,<br>
> +                                 bool &SeenIntermediateUse) const;<br>
>    virtual void anchor();<br>
><br>
>  protected:<br>
> @@ -313,6 +352,19 @@ public:<br>
>    bool isZeroExtended(const MachineInstr &MI, const unsigned depth = 0) const {<br>
>     return isSignOrZeroExtended(MI, false, depth);<br>
>    }<br>
> +<br>
> +  bool convertToImmediateForm(<wbr>MachineInstr &MI,<br>
> +                              MachineInstr **KilledDef = nullptr) const;<br>
> +  void replaceInstrWithLI(<wbr>MachineInstr &MI, const LoadImmediateInfo &LII) const;<br>
> +<br>
> +  // This is used to find the "true" source register for n<br>
> +  // Machine instruction. Returns the original SrcReg unless it is the target<br>
> +  // of a copy-like operation, in which case we chain backwards through all<br>
> +  // such operations to the ultimate source register.  If a<br>
> +  // physical register is encountered, we stop the search.<br>
> +  static unsigned lookThruCopyLike(unsigned SrcReg,<br>
> +                                   const MachineRegisterInfo *MRI);<br>
> +  bool instrHasImmForm(const MachineInstr &MI, ImmInstrInfo &III) const;<br>
>  };<br>
><br>
>  }<br>
><br>
> Modified: llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.td<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td?rev=320791&r1=320790&r2=320791&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>PowerPC/PPCInstrInfo.td?rev=<wbr>320791&r1=320790&r2=320791&<wbr>view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.td (original)<br>
> +++ llvm/trunk/lib/Target/PowerPC/<wbr>PPCInstrInfo.td Thu Dec 14 23:27:53 2017<br>
> @@ -1590,6 +1590,11 @@ def : Pat<(prefetch xoaddr:$dst, (i32 0)<br>
>            (ICBT 0, xoaddr:$dst)>, Requires<[HasICBT]>; // inst prefetch (for read)<br>
><br>
>  // Atomic operations<br>
> +// FIXME: some of these might be used with constant operands. This will result<br>
> +// in constant materialization instructions that may be redundant. We currently<br>
> +// clean this up in PPCMIPeephole with calls to<br>
> +// PPCInstrInfo::<wbr>convertToImmediateForm() but we should probably not emit them<br>
> +// in the first place.<br>
>  let usesCustomInserter = 1 in {<br>
>    let Defs = [CR0] in {<br>
>      def ATOMIC_LOAD_ADD_I8 : Pseudo<<br>
><br>
> Modified: llvm/trunk/lib/Target/PowerPC/<wbr>PPCMIPeephole.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCMIPeephole.cpp?rev=320791&r1=320790&r2=320791&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>PowerPC/PPCMIPeephole.cpp?rev=<wbr>320791&r1=320790&r2=320791&<wbr>view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Target/PowerPC/<wbr>PPCMIPeephole.cpp (original)<br>
> +++ llvm/trunk/lib/Target/PowerPC/<wbr>PPCMIPeephole.cpp Thu Dec 14 23:27:53 2017<br>
> @@ -41,6 +41,22 @@ STATISTIC(MultiTOCSaves,<br>
>  STATISTIC(NumEliminatedSExt, "Number of eliminated sign-extensions");<br>
>  STATISTIC(NumEliminatedZExt, "Number of eliminated zero-extensions");<br>
>  STATISTIC(NumOptADDLIs, "Number of optimized ADD instruction fed by LI");<br>
> +STATISTIC(<wbr>NumConvertedToImmediateForm,<br>
> +          "Number of instructions converted to their immediate form");<br>
> +STATISTIC(<wbr>NumFunctionsEnteredInMIPeephol<wbr>e,<br>
> +          "Number of functions entered in PPC MI Peepholes");<br>
> +STATISTIC(<wbr>NumFixedPointIterations,<br>
> +          "Number of fixed-point iterations converting reg-reg instructions "<br>
> +          "to reg-imm ones");<br>
> +<br>
> +static cl::opt<bool><br>
> +FixedPointRegToImm("ppc-reg-<wbr>to-imm-fixed-point", cl::Hidden, cl::init(true),<br>
> +                   cl::desc("Iterate to a fixed point when attempting to "<br>
> +                            "convert reg-reg instructions to reg-imm"));<br>
> +<br>
> +static cl::opt<bool><br>
> +ConvertRegReg("ppc-convert-<wbr>rr-to-ri", cl::Hidden, cl::init(true),<br>
> +              cl::desc("Convert eligible reg+reg instructions to reg+imm"));<br>
><br>
>  static cl::opt<bool><br>
>      EnableSExtElimination("ppc-<wbr>eliminate-signext",<br>
> @@ -52,10 +68,6 @@ static cl::opt<bool><br>
>                            cl::desc("enable elimination of zero-extensions"),<br>
>                            cl::init(false), cl::Hidden);<br>
><br>
> -namespace llvm {<br>
> -  void initializePPCMIPeepholePass(<wbr>PassRegistry&);<br>
> -}<br>
> -<br>
>  namespace {<br>
><br>
>  struct PPCMIPeephole : public MachineFunctionPass {<br>
> @@ -83,9 +95,6 @@ private:<br>
>    bool eliminateRedundantTOCSaves(<wbr>std::map<MachineInstr *, bool> &TOCSaves);<br>
>    void UpdateTOCSaves(std::map<<wbr>MachineInstr *, bool> &TOCSaves,<br>
>                        MachineInstr *MI);<br>
> -  // Find the "true" register represented by SrcReg (following chains<br>
> -  // of copies and subreg_to_reg operations).<br>
> -  unsigned lookThruCopyLike(unsigned SrcReg);<br>
><br>
>  public:<br>
><br>
> @@ -212,6 +221,35 @@ bool PPCMIPeephole::simplifyCode(<wbr>void) {<br>
>    MachineInstr* ToErase = nullptr;<br>
>    std::map<MachineInstr *, bool> TOCSaves;<br>
><br>
> +  NumFunctionsEnteredInMIPeephol<wbr>e++;<br>
> +  if (ConvertRegReg) {<br>
> +    // Fixed-point conversion of reg/reg instructions fed by load-immediate<br>
> +    // into reg/imm instructions. FIXME: This is expensive, control it with<br>
> +    // an option.<br>
> +    bool SomethingChanged = false;<br>
> +    do {<br>
> +      NumFixedPointIterations++;<br>
> +      SomethingChanged = false;<br>
> +      for (MachineBasicBlock &MBB : *MF) {<br>
> +        for (MachineInstr &MI : MBB) {<br>
> +          if (MI.isDebugValue())<br>
> +            continue;<br>
> +<br>
> +          if (TII->convertToImmediateForm(<wbr>MI)) {<br>
> +            // We don't erase anything in case the def has other uses. Let DCE<br>
> +            // remove it if it can be removed.<br>
> +            DEBUG(dbgs() << "Converted instruction to imm form: ");<br>
> +            DEBUG(MI.dump());<br>
> +            NumConvertedToImmediateForm++;<br>
> +            SomethingChanged = true;<br>
> +            Simplified = true;<br>
> +            continue;<br>
> +          }<br>
> +        }<br>
> +      }<br>
> +    } while (SomethingChanged && FixedPointRegToImm);<br>
> +  }<br>
> +<br>
>    for (MachineBasicBlock &MBB : *MF) {<br>
>      for (MachineInstr &MI : MBB) {<br>
><br>
> @@ -258,8 +296,10 @@ bool PPCMIPeephole::simplifyCode(<wbr>void) {<br>
>            //   XXPERMDI t, SUBREG_TO_REG(s), SUBREG_TO_REG(s), immed.<br>
>            // We have to look through chains of COPY and SUBREG_TO_REG<br>
>            // to find the real source values for comparison.<br>
> -          unsigned TrueReg1 = lookThruCopyLike(MI.<wbr>getOperand(1).getReg());<br>
> -          unsigned TrueReg2 = lookThruCopyLike(MI.<wbr>getOperand(2).getReg());<br>
> +          unsigned TrueReg1 =<br>
> +            TII->lookThruCopyLike(MI.<wbr>getOperand(1).getReg(), MRI);<br>
> +          unsigned TrueReg2 =<br>
> +            TII->lookThruCopyLike(MI.<wbr>getOperand(2).getReg(), MRI);<br>
><br>
>            if (TrueReg1 == TrueReg2<br>
>                && TargetRegisterInfo::<wbr>isVirtualRegister(TrueReg1)) {<br>
> @@ -273,7 +313,8 @@ bool PPCMIPeephole::simplifyCode(<wbr>void) {<br>
>              auto isConversionOfLoadAndSplat = [=]() -> bool {<br>
>                if (DefOpc != PPC::XVCVDPSXDS && DefOpc != PPC::XVCVDPUXDS)<br>
>                  return false;<br>
> -              unsigned DefReg = lookThruCopyLike(DefMI-><wbr>getOperand(1).getReg());<br>
> +              unsigned DefReg =<br>
> +                TII->lookThruCopyLike(DefMI-><wbr>getOperand(1).getReg(), MRI);<br>
>                if (TargetRegisterInfo::<wbr>isVirtualRegister(DefReg)) {<br>
>                  MachineInstr *LoadMI = MRI->getVRegDef(DefReg);<br>
>                  if (LoadMI && LoadMI->getOpcode() == PPC::LXVDSX)<br>
> @@ -299,10 +340,10 @@ bool PPCMIPeephole::simplifyCode(<wbr>void) {<br>
>              // can replace it with a copy.<br>
>              if (DefOpc == PPC::XXPERMDI) {<br>
>                unsigned FeedImmed = DefMI->getOperand(3).getImm();<br>
> -              unsigned FeedReg1<br>
> -                = lookThruCopyLike(DefMI-><wbr>getOperand(1).getReg());<br>
> -              unsigned FeedReg2<br>
> -                = lookThruCopyLike(DefMI-><wbr>getOperand(2).getReg());<br>
> +              unsigned FeedReg1 =<br>
> +                TII->lookThruCopyLike(DefMI-><wbr>getOperand(1).getReg(), MRI);<br>
> +              unsigned FeedReg2 =<br>
> +                TII->lookThruCopyLike(DefMI-><wbr>getOperand(2).getReg(), MRI);<br>
><br>
>                if ((FeedImmed == 0 || FeedImmed == 3) && FeedReg1 == FeedReg2) {<br>
>                  DEBUG(dbgs()<br>
> @@ -360,7 +401,8 @@ bool PPCMIPeephole::simplifyCode(<wbr>void) {<br>
>        case PPC::XXSPLTW: {<br>
>          unsigned MyOpcode = MI.getOpcode();<br>
>          unsigned OpNo = MyOpcode == PPC::XXSPLTW ? 1 : 2;<br>
> -        unsigned TrueReg = lookThruCopyLike(MI.<wbr>getOperand(OpNo).getReg());<br>
> +        unsigned TrueReg =<br>
> +          TII->lookThruCopyLike(MI.<wbr>getOperand(OpNo).getReg(), MRI);<br>
>          if (!TargetRegisterInfo::<wbr>isVirtualRegister(TrueReg))<br>
>            break;<br>
>          MachineInstr *DefMI = MRI->getVRegDef(TrueReg);<br>
> @@ -422,7 +464,8 @@ bool PPCMIPeephole::simplifyCode(<wbr>void) {<br>
>        }<br>
>        case PPC::XVCVDPSP: {<br>
>          // If this is a DP->SP conversion fed by an FRSP, the FRSP is redundant.<br>
> -        unsigned TrueReg = lookThruCopyLike(MI.<wbr>getOperand(1).getReg());<br>
> +        unsigned TrueReg =<br>
> +          TII->lookThruCopyLike(MI.<wbr>getOperand(1).getReg(), MRI);<br>
>          if (!TargetRegisterInfo::<wbr>isVirtualRegister(TrueReg))<br>
>            break;<br>
>          MachineInstr *DefMI = MRI->getVRegDef(TrueReg);<br>
> @@ -430,8 +473,10 @@ bool PPCMIPeephole::simplifyCode(<wbr>void) {<br>
>          // This can occur when building a vector of single precision or integer<br>
>          // values.<br>
>          if (DefMI && DefMI->getOpcode() == PPC::XXPERMDI) {<br>
> -          unsigned DefsReg1 = lookThruCopyLike(DefMI-><wbr>getOperand(1).getReg());<br>
> -          unsigned DefsReg2 = lookThruCopyLike(DefMI-><wbr>getOperand(2).getReg());<br>
> +          unsigned DefsReg1 =<br>
> +            TII->lookThruCopyLike(DefMI-><wbr>getOperand(1).getReg(), MRI);<br>
> +          unsigned DefsReg2 =<br>
> +            TII->lookThruCopyLike(DefMI-><wbr>getOperand(2).getReg(), MRI);<br>
>            if (!TargetRegisterInfo::<wbr>isVirtualRegister(DefsReg1) ||<br>
>                !TargetRegisterInfo::<wbr>isVirtualRegister(DefsReg2))<br>
>              break;<br>
> @@ -1221,36 +1266,6 @@ bool PPCMIPeephole::<wbr>eliminateRedundantCo<br>
>    return Simplified;<br>
>  }<br>
><br>
> -// This is used to find the "true" source register for an<br>
> -// XXPERMDI instruction, since MachineCSE does not handle the<br>
> -// "copy-like" operations (Copy and SubregToReg).  Returns<br>
> -// the original SrcReg unless it is the target of a copy-like<br>
> -// operation, in which case we chain backwards through all<br>
> -// such operations to the ultimate source register.  If a<br>
> -// physical register is encountered, we stop the search.<br>
> -unsigned PPCMIPeephole::<wbr>lookThruCopyLike(unsigned SrcReg) {<br>
> -<br>
> -  while (true) {<br>
> -<br>
> -    MachineInstr *MI = MRI->getVRegDef(SrcReg);<br>
> -    if (!MI->isCopyLike())<br>
> -      return SrcReg;<br>
> -<br>
> -    unsigned CopySrcReg;<br>
> -    if (MI->isCopy())<br>
> -      CopySrcReg = MI->getOperand(1).getReg();<br>
> -    else {<br>
> -      assert(MI->isSubregToReg() && "bad opcode for lookThruCopyLike");<br>
> -      CopySrcReg = MI->getOperand(2).getReg();<br>
> -    }<br>
> -<br>
> -    if (!TargetRegisterInfo::<wbr>isVirtualRegister(CopySrcReg))<br>
> -      return CopySrcReg;<br>
> -<br>
> -    SrcReg = CopySrcReg;<br>
> -  }<br>
> -}<br>
> -<br>
>  } // end default namespace<br>
><br>
>  INITIALIZE_PASS_BEGIN(<wbr>PPCMIPeephole, DEBUG_TYPE,<br>
><br>
> Added: llvm/trunk/lib/Target/PowerPC/<wbr>PPCPreEmitPeephole.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCPreEmitPeephole.cpp?rev=320791&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>PowerPC/PPCPreEmitPeephole.<wbr>cpp?rev=320791&view=auto</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Target/PowerPC/<wbr>PPCPreEmitPeephole.cpp (added)<br>
> +++ llvm/trunk/lib/Target/PowerPC/<wbr>PPCPreEmitPeephole.cpp Thu Dec 14 23:27:53 2017<br>
> @@ -0,0 +1,95 @@<br>
> +//===--------- PPCPreEmitPeephole.cpp - Late peephole optimizations -------===//<br>
> +//<br>
> +//                     The LLVM Compiler Infrastructure<br>
> +//<br>
> +// This file is distributed under the University of Illinois Open Source<br>
> +// License. See LICENSE.TXT for details.<br>
> +//<br>
> +//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
> +//<br>
> +// A pre-emit peephole for catching opportunities introduced by late passes such<br>
> +// as MachineBlockPlacement.<br>
> +//<br>
> +//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
> +<br>
> +#include "PPC.h"<br>
> +#include "PPCInstrInfo.h"<br>
> +#include "PPCSubtarget.h"<br>
> +#include "llvm/ADT/DenseMap.h"<br>
> +#include "llvm/ADT/Statistic.h"<br>
> +#include "llvm/CodeGen/LivePhysRegs.h"<br>
> +#include "llvm/CodeGen/<wbr>MachineFunctionPass.h"<br>
> +#include "llvm/CodeGen/<wbr>MachineInstrBuilder.h"<br>
> +#include "llvm/CodeGen/<wbr>MachineRegisterInfo.h"<br>
> +#include "llvm/Support/CommandLine.h"<br>
> +#include "llvm/ADT/Statistic.h"<br>
> +#include "llvm/Support/Debug.h"<br>
> +<br>
> +using namespace llvm;<br>
> +<br>
> +#define DEBUG_TYPE "ppc-pre-emit-peephole"<br>
> +<br>
> +STATISTIC(<wbr>NumRRConvertedInPreEmit,<br>
> +          "Number of r+r instructions converted to r+i in pre-emit peephole");<br>
> +STATISTIC(<wbr>NumRemovedInPreEmit,<br>
> +          "Number of instructions deleted in pre-emit peephole");<br>
> +<br>
> +static cl::opt<bool><br>
> +RunPreEmitPeephole("ppc-late-<wbr>peephole", cl::Hidden, cl::init(true),<br>
> +                   cl::desc("Run pre-emit peephole optimizations."));<br>
> +<br>
> +namespace {<br>
> +  class PPCPreEmitPeephole : public MachineFunctionPass {<br>
> +  public:<br>
> +    static char ID;<br>
> +    PPCPreEmitPeephole() : MachineFunctionPass(ID) {<br>
> +      initializePPCPreEmitPeepholePa<wbr>ss(*PassRegistry::<wbr>getPassRegistry());<br>
> +    }<br>
> +<br>
> +    void getAnalysisUsage(AnalysisUsage &AU) const override {<br>
> +      MachineFunctionPass::<wbr>getAnalysisUsage(AU);<br>
> +    }<br>
> +<br>
> +    MachineFunctionProperties getRequiredProperties() const override {<br>
> +      return MachineFunctionProperties().<wbr>set(<br>
> +          MachineFunctionProperties::<wbr>Property::NoVRegs);<br>
> +    }<br>
> +<br>
> +    bool runOnMachineFunction(<wbr>MachineFunction &MF) override {<br>
> +      if (skipFunction(*MF.getFunction(<wbr>)) || !RunPreEmitPeephole)<br>
> +        return false;<br>
> +      bool Changed = false;<br>
> +      const PPCInstrInfo *TII = MF.getSubtarget<PPCSubtarget>(<wbr>).getInstrInfo();<br>
> +      SmallVector<MachineInstr *, 4> InstrsToErase;<br>
> +      for (MachineBasicBlock &MBB : MF) {<br>
> +        for (MachineInstr &MI : MBB) {<br>
> +          MachineInstr *DefMIToErase = nullptr;<br>
> +          if (TII->convertToImmediateForm(<wbr>MI, &DefMIToErase)) {<br>
> +            Changed = true;<br>
> +            NumRRConvertedInPreEmit++;<br>
> +            DEBUG(dbgs() << "Converted instruction to imm form: ");<br>
> +            DEBUG(MI.dump());<br>
> +            if (DefMIToErase) {<br>
> +              InstrsToErase.push_back(<wbr>DefMIToErase);<br>
> +            }<br>
> +          }<br>
> +        }<br>
> +      }<br>
> +      for (MachineInstr *MI : InstrsToErase) {<br>
> +        DEBUG(dbgs() << "PPC pre-emit peephole: erasing instruction: ");<br>
> +        DEBUG(MI->dump());<br>
> +        MI->eraseFromParent();<br>
> +        NumRemovedInPreEmit++;<br>
> +      }<br>
> +      return Changed;<br>
> +    }<br>
> +  };<br>
> +}<br>
> +<br>
> +INITIALIZE_PASS(<wbr>PPCPreEmitPeephole, DEBUG_TYPE, "PowerPC Pre-Emit Peephole",<br>
> +                false, false)<br>
> +char PPCPreEmitPeephole::ID = 0;<br>
> +<br>
> +FunctionPass *llvm::<wbr>createPPCPreEmitPeepholePass() {<br>
> +  return new PPCPreEmitPeephole();<br>
> +}<br>
><br>
> Modified: llvm/trunk/lib/Target/PowerPC/<wbr>PPCTargetMachine.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp?rev=320791&r1=320790&r2=320791&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>PowerPC/PPCTargetMachine.cpp?<wbr>rev=320791&r1=320790&r2=<wbr>320791&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Target/PowerPC/<wbr>PPCTargetMachine.cpp (original)<br>
> +++ llvm/trunk/lib/Target/PowerPC/<wbr>PPCTargetMachine.cpp Thu Dec 14 23:27:53 2017<br>
> @@ -101,7 +101,9 @@ extern "C" void LLVMInitializePowerPCTar<br>
>    PassRegistry &PR = *PassRegistry::<wbr>getPassRegistry();<br>
>    initializePPCBoolRetToIntPass(<wbr>PR);<br>
>    initializePPCExpandISELPass(<wbr>PR);<br>
> +  initializePPCPreEmitPeepholePa<wbr>ss(PR);<br>
>    initializePPCTLSDynamicCallPas<wbr>s(PR);<br>
> +  initializePPCMIPeepholePass(<wbr>PR);<br>
>  }<br>
><br>
>  /// Return the datalayout string of a subtarget.<br>
> @@ -440,6 +442,7 @@ void PPCPassConfig::addPreSched2() {<br>
>  }<br>
><br>
>  void PPCPassConfig::addPreEmitPass(<wbr>) {<br>
> +  addPass(<wbr>createPPCPreEmitPeepholePass()<wbr>);<br>
>    addPass(<wbr>createPPCExpandISELPass());<br>
><br>
>    if (getOptLevel() != CodeGenOpt::None)<br>
><br>
> Modified: llvm/trunk/test/CodeGen/<wbr>PowerPC/build-vector-tests.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/build-vector-tests.ll?rev=320791&r1=320790&r2=320791&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>CodeGen/PowerPC/build-vector-<wbr>tests.ll?rev=320791&r1=320790&<wbr>r2=320791&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/test/CodeGen/<wbr>PowerPC/build-vector-tests.ll (original)<br>
> +++ llvm/trunk/test/CodeGen/<wbr>PowerPC/build-vector-tests.ll Thu Dec 14 23:27:53 2017<br>
> @@ -3508,13 +3508,13 @@ entry:<br>
>  ; P9LE: xxmrghd<br>
>  ; P9LE-NEXT: xvcvdpsxds v2<br>
>  ; P9LE-NEXT: blr<br>
> -; P8BE: lfsx<br>
> -; P8BE: lfsx<br>
> +; P8BE: lfs<br>
> +; P8BE: lfs<br>
>  ; P8BE: xxmrghd<br>
>  ; P8BE-NEXT: xvcvdpsxds v2<br>
>  ; P8BE-NEXT: blr<br>
> -; P8LE: lfsx<br>
> -; P8LE: lfsx<br>
> +; P8LE: lfs<br>
> +; P8LE: lfs<br>
>  ; P8LE: xxmrghd<br>
>  ; P8LE-NEXT: xvcvdpsxds v2<br>
>  ; P8LE-NEXT: blr<br>
> @@ -3546,13 +3546,13 @@ entry:<br>
>  ; P9LE: xxmrghd<br>
>  ; P9LE-NEXT: xvcvdpsxds v2<br>
>  ; P9LE-NEXT: blr<br>
> -; P8BE: lfsx<br>
> -; P8BE: lfsx<br>
> +; P8BE: lfs<br>
> +; P8BE: lfs<br>
>  ; P8BE: xxmrghd<br>
>  ; P8BE-NEXT: xvcvdpsxds v2<br>
>  ; P8BE-NEXT: blr<br>
> -; P8LE: lfsx<br>
> -; P8LE: lfsx<br>
> +; P8LE: lfs<br>
> +; P8LE: lfs<br>
>  ; P8LE: xxmrghd<br>
>  ; P8LE-NEXT: xvcvdpsxds v2<br>
>  ; P8LE-NEXT: blr<br>
> @@ -3591,13 +3591,13 @@ entry:<br>
>  ; P9LE-NEXT: blr<br>
>  ; P8BE: sldi<br>
>  ; P8BE: lfsux<br>
> -; P8BE: lfsx<br>
> +; P8BE: lfs<br>
>  ; P8BE: xxmrghd<br>
>  ; P8BE-NEXT: xvcvdpsxds v2<br>
>  ; P8BE-NEXT: blr<br>
>  ; P8LE: sldi<br>
>  ; P8LE: lfsux<br>
> -; P8LE: lfsx<br>
> +; P8LE: lfs<br>
>  ; P8LE: xxmrghd<br>
>  ; P8LE-NEXT: xvcvdpsxds v2<br>
>  ; P8LE-NEXT: blr<br>
> @@ -3636,13 +3636,13 @@ entry:<br>
>  ; P9LE-NEXT: blr<br>
>  ; P8BE: sldi<br>
>  ; P8BE: lfsux<br>
> -; P8BE: lfsx<br>
> +; P8BE: lfs<br>
>  ; P8BE: xxmrghd<br>
>  ; P8BE-NEXT: xvcvdpsxds v2<br>
>  ; P8BE-NEXT: blr<br>
>  ; P8LE: sldi<br>
>  ; P8LE: lfsux<br>
> -; P8LE: lfsx<br>
> +; P8LE: lfs<br>
>  ; P8LE: xxmrghd<br>
>  ; P8LE-NEXT: xvcvdpsxds v2<br>
>  ; P8LE-NEXT: blr<br>
> @@ -3693,11 +3693,11 @@ entry:<br>
>  ; P9LE-NEXT: xscvdpsxds<br>
>  ; P9LE-NEXT: xxspltd v2<br>
>  ; P9LE-NEXT: blr<br>
> -; P8BE: lfsx<br>
> +; P8BE: lfs<br>
>  ; P8BE-NEXT: xscvdpsxds<br>
>  ; P8BE-NEXT: xxspltd v2<br>
>  ; P8BE-NEXT: blr<br>
> -; P8LE: lfsx<br>
> +; P8LE: lfs<br>
>  ; P8LE-NEXT: xscvdpsxds<br>
>  ; P8LE-NEXT: xxspltd v2<br>
>  ; P8LE-NEXT: blr<br>
> @@ -4412,13 +4412,13 @@ entry:<br>
>  ; P9LE: xxmrghd<br>
>  ; P9LE-NEXT: xvcvdpuxds v2<br>
>  ; P9LE-NEXT: blr<br>
> -; P8BE: lfsx<br>
> -; P8BE: lfsx<br>
> +; P8BE: lfs<br>
> +; P8BE: lfs<br>
>  ; P8BE: xxmrghd<br>
>  ; P8BE-NEXT: xvcvdpuxds v2<br>
>  ; P8BE-NEXT: blr<br>
> -; P8LE: lfsx<br>
> -; P8LE: lfsx<br>
> +; P8LE: lfs<br>
> +; P8LE: lfs<br>
>  ; P8LE: xxmrghd<br>
>  ; P8LE-NEXT: xvcvdpuxds v2<br>
>  ; P8LE-NEXT: blr<br>
> @@ -4450,13 +4450,13 @@ entry:<br>
>  ; P9LE: xxmrghd<br>
>  ; P9LE-NEXT: xvcvdpuxds v2<br>
>  ; P9LE-NEXT: blr<br>
> -; P8BE: lfsx<br>
> -; P8BE: lfsx<br>
> +; P8BE: lfs<br>
> +; P8BE: lfs<br>
>  ; P8BE: xxmrghd<br>
>  ; P8BE-NEXT: xvcvdpuxds v2<br>
>  ; P8BE-NEXT: blr<br>
> -; P8LE: lfsx<br>
> -; P8LE: lfsx<br>
> +; P8LE: lfs<br>
> +; P8LE: lfs<br>
>  ; P8LE: xxmrghd<br>
>  ; P8LE-NEXT: xvcvdpuxds v2<br>
>  ; P8LE-NEXT: blr<br>
> @@ -4495,13 +4495,13 @@ entry:<br>
>  ; P9LE-NEXT: blr<br>
>  ; P8BE: sldi<br>
>  ; P8BE: lfsux<br>
> -; P8BE: lfsx<br>
> +; P8BE: lfs<br>
>  ; P8BE: xxmrghd<br>
>  ; P8BE-NEXT: xvcvdpuxds v2<br>
>  ; P8BE-NEXT: blr<br>
>  ; P8LE: sldi<br>
>  ; P8LE: lfsux<br>
> -; P8LE: lfsx<br>
> +; P8LE: lfs<br>
>  ; P8LE: xxmrghd<br>
>  ; P8LE-NEXT: xvcvdpuxds v2<br>
>  ; P8LE-NEXT: blr<br>
> @@ -4540,13 +4540,13 @@ entry:<br>
>  ; P9LE-NEXT: blr<br>
>  ; P8BE: sldi<br>
>  ; P8BE: lfsux<br>
> -; P8BE: lfsx<br>
> +; P8BE: lfs<br>
>  ; P8BE: xxmrghd<br>
>  ; P8BE-NEXT: xvcvdpuxds v2<br>
>  ; P8BE-NEXT: blr<br>
>  ; P8LE: sldi<br>
>  ; P8LE: lfsux<br>
> -; P8LE: lfsx<br>
> +; P8LE: lfs<br>
>  ; P8LE: xxmrghd<br>
>  ; P8LE-NEXT: xvcvdpuxds v2<br>
>  ; P8LE-NEXT: blr<br>
> @@ -4597,11 +4597,11 @@ entry:<br>
>  ; P9LE-NEXT: xscvdpuxds<br>
>  ; P9LE-NEXT: xxspltd v2<br>
>  ; P9LE-NEXT: blr<br>
> -; P8BE: lfsx<br>
> +; P8BE: lfs<br>
>  ; P8BE-NEXT: xscvdpuxds<br>
>  ; P8BE-NEXT: xxspltd v2<br>
>  ; P8BE-NEXT: blr<br>
> -; P8LE: lfsx<br>
> +; P8LE: lfs<br>
>  ; P8LE-NEXT: xscvdpuxds<br>
>  ; P8LE-NEXT: xxspltd v2<br>
>  ; P8LE-NEXT: blr<br>
><br>
> Added: llvm/trunk/test/CodeGen/<wbr>PowerPC/convert-rr-to-ri-<wbr>instrs-R0-special-handling.mir<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/convert-rr-to-ri-instrs-R0-special-handling.mir?rev=320791&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>CodeGen/PowerPC/convert-rr-to-<wbr>ri-instrs-R0-special-handling.<wbr>mir?rev=320791&view=auto</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/test/CodeGen/<wbr>PowerPC/convert-rr-to-ri-<wbr>instrs-R0-special-handling.mir (added)<br>
> +++ llvm/trunk/test/CodeGen/<wbr>PowerPC/convert-rr-to-ri-<wbr>instrs-R0-special-handling.mir Thu Dec 14 23:27:53 2017<br>
> @@ -0,0 +1,436 @@<br>
> +# RUN: llc -start-after ppc-mi-peepholes -ppc-late-peephole %s -o - | FileCheck %s<br>
> +--- |<br>
> +  ; ModuleID = 'a.ll'<br>
> +  source_filename = "a.c"<br>
> +  target datalayout = "e-m:e-i64:64-n32:64"<br>
> +  target triple = "powerpc64le-unknown-linux-<wbr>gnu"<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @unsafeAddR0R3(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %add = add nsw i32 %b, %a<br>
> +    ret i32 %add<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @unsafeAddR3R0(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %add = add nsw i32 %b, %a<br>
> +    ret i32 %add<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @safeAddR0R3(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %add = add nsw i32 %b, %a<br>
> +    ret i32 %add<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @safeAddR3R0(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %add = add nsw i32 %b, %a<br>
> +    ret i32 %add<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define i64 @unsafeLDXR3R0(i64* nocapture readonly %ptr, i64 %off) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %0 = bitcast i64* %ptr to i8*<br>
> +    %add.ptr = getelementptr inbounds i8, i8* %0, i64 %off<br>
> +    %1 = bitcast i8* %add.ptr to i64*<br>
> +    %2 = load i64, i64* %1, align 8, !tbaa !3<br>
> +    ret i64 %2<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define i64 @safeLDXZeroR3(i64* nocapture readonly %ptr, i64 %off) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %0 = bitcast i64* %ptr to i8*<br>
> +    %add.ptr = getelementptr inbounds i8, i8* %0, i64 %off<br>
> +    %1 = bitcast i8* %add.ptr to i64*<br>
> +    %2 = load i64, i64* %1, align 8, !tbaa !3<br>
> +    ret i64 %2<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define i64 @safeLDXR3R0(i64* nocapture readonly %ptr, i64 %off) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %0 = bitcast i64* %ptr to i8*<br>
> +    %add.ptr = getelementptr inbounds i8, i8* %0, i64 %off<br>
> +    %1 = bitcast i8* %add.ptr to i64*<br>
> +    %2 = load i64, i64* %1, align 8, !tbaa !3<br>
> +    ret i64 %2<br>
> +  }<br>
> +<br>
> +  attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-<wbr>sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="<wbr>false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="<wbr>false" "no-trapping-math"="false" "stack-protector-buffer-size"=<wbr>"8" "target-cpu"="ppc64le" "target-features"="+altivec,+<wbr>bpermd,+crypto,+direct-move,+<wbr>extdiv,+htm,+power8-vector,+<wbr>vsx,-power9-vector,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
> +  attributes #1 = { norecurse nounwind readonly "correctly-rounded-divide-<wbr>sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="<wbr>false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="<wbr>false" "no-trapping-math"="false" "stack-protector-buffer-size"=<wbr>"8" "target-cpu"="ppc64le" "target-features"="+altivec,+<wbr>bpermd,+crypto,+direct-move,+<wbr>extdiv,+htm,+power8-vector,+<wbr>vsx,-power9-vector,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
> +<br>
> +  !llvm.module.flags = !{!0, !1}<br>
> +  !llvm.ident = !{!2}<br>
> +<br>
> +  !0 = !{i32 1, !"wchar_size", i32 4}<br>
> +  !1 = !{i32 7, !"PIC Level", i32 2}<br>
> +  !2 = !{!"clang version 6.0.0 (trunk 318832)"}<br>
> +  !3 = !{!4, !4, i64 0}<br>
> +  !4 = !{!"long long", !5, i64 0}<br>
> +  !5 = !{!"omnipotent char", !6, i64 0}<br>
> +  !6 = !{!"Simple C/C++ TBAA"}<br>
> +<br>
> +...<br>
> +---<br>
> +name:            unsafeAddR0R3<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: gprc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x0, %x4<br>
> +<br>
> +    %1:g8rc = COPY %x4<br>
> +    %0:g8rc = COPY %x0<br>
> +    %2:gprc = LI 44<br>
> +    %3:gprc = COPY %1.sub_32<br>
> +    %4:gprc = ADD4 killed %r0, killed %2<br>
> +    ; CHECK: li 3, 44<br>
> +    ; CHECK: add 3, 0, 3<br>
> +    %5:g8rc = EXTSW_32_64 killed %4<br>
> +    %x3 = COPY %5<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            unsafeAddR3R0<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: gprc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x0, %x4<br>
> +<br>
> +    %1:g8rc = COPY %x4<br>
> +    %0:g8rc = COPY %x0<br>
> +    %2:gprc = COPY %0.sub_32<br>
> +    %3:gprc = LI 44<br>
> +    %4:gprc = ADD4 killed %3, killed %r0<br>
> +    ; CHECK: li 3, 44<br>
> +    ; CHECK: add 3, 3, 0<br>
> +    %5:g8rc = EXTSW_32_64 killed %4<br>
> +    %x3 = COPY %5<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            safeAddR0R3<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: gprc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1:g8rc = COPY %x4<br>
> +    %0:g8rc = COPY %x3<br>
> +    %2:gprc = COPY %0.sub_32<br>
> +    %r0 = LI 44<br>
> +    %4:gprc = ADD4 killed %r0, killed %2<br>
> +    ; CHECK: addi 3, 3, 44<br>
> +    %5:g8rc = EXTSW_32_64 killed %4<br>
> +    %x3 = COPY %5<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            safeAddR3R0<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: gprc, preferred-register: '' }<br>
> +  - { id: 3, class: gprc, preferred-register: '' }<br>
> +  - { id: 4, class: gprc, preferred-register: '' }<br>
> +  - { id: 5, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1:g8rc = COPY %x4<br>
> +    %0:g8rc = COPY %x3<br>
> +    %2:gprc = COPY %0.sub_32<br>
> +    %r0 = LI 44<br>
> +    %4:gprc = ADD4 killed %2, killed %r0<br>
> +    ; CHECK: addi 3, 3, 44<br>
> +    %5:g8rc = EXTSW_32_64 killed %4<br>
> +    %x3 = COPY %5<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            unsafeLDXR3R0<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x0', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x0, %x4<br>
> +<br>
> +    %1:g8rc = COPY %x4<br>
> +    %0:g8rc_and_g8rc_nox0 = LI8 44<br>
> +    %2:g8rc = LDX %0, %x0 :: (load 8 from %ir.1, !tbaa !3)<br>
> +    ; CHECK: li 3, 44<br>
> +    ; CHECK: ldx 3, 3, 0<br>
> +    %x3 = COPY %2<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            safeLDXZeroR3<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %1:g8rc = LI8 44<br>
> +    %0:g8rc_and_g8rc_nox0 = LI8 44<br>
> +    %2:g8rc = LDX %zero8, %1 :: (load 8 from %ir.1, !tbaa !3)<br>
> +    ; CHECK: ld 3, 44(0)<br>
> +    %x3 = COPY %2<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
> +---<br>
> +name:            safeLDXR3R0<br>
> +alignment:       4<br>
> +exposesReturnsTwice: false<br>
> +legalized:       false<br>
> +regBankSelected: false<br>
> +selected:        false<br>
> +tracksRegLiveness: true<br>
> +registers:<br>
> +  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }<br>
> +  - { id: 1, class: g8rc, preferred-register: '' }<br>
> +  - { id: 2, class: g8rc, preferred-register: '' }<br>
> +liveins:<br>
> +  - { reg: '%x3', virtual-reg: '%0' }<br>
> +  - { reg: '%x4', virtual-reg: '%1' }<br>
> +frameInfo:<br>
> +  isFrameAddressTaken: false<br>
> +  isReturnAddressTaken: false<br>
> +  hasStackMap:     false<br>
> +  hasPatchPoint:   false<br>
> +  stackSize:       0<br>
> +  offsetAdjustment: 0<br>
> +  maxAlignment:    0<br>
> +  adjustsStack:    false<br>
> +  hasCalls:        false<br>
> +  stackProtector:  ''<br>
> +  maxCallFrameSize: 4294967295<br>
> +  hasOpaqueSPAdjustment: false<br>
> +  hasVAStart:      false<br>
> +  hasMustTailInVarArgFunc: false<br>
> +  savePoint:       ''<br>
> +  restorePoint:    ''<br>
> +fixedStack:<br>
> +stack:<br>
> +constants:<br>
> +body:             |<br>
> +  bb.0.entry:<br>
> +    liveins: %x3, %x4<br>
> +<br>
> +    %x0 = LI8 44<br>
> +    %0:g8rc_and_g8rc_nox0 = COPY %x3<br>
> +    %2:g8rc = LDX %0, %x0 :: (load 8 from %ir.1, !tbaa !3)<br>
> +    ; CHECK: ld 3, 44(3)<br>
> +    %x3 = COPY %2<br>
> +    BLR8 implicit %lr8, implicit %rm, implicit %x3<br>
> +<br>
> +...<br>
><br>
> Added: llvm/trunk/test/CodeGen/<wbr>PowerPC/convert-rr-to-ri-<wbr>instrs.mir<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir?rev=320791&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>CodeGen/PowerPC/convert-rr-to-<wbr>ri-instrs.mir?rev=320791&view=<wbr>auto</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/test/CodeGen/<wbr>PowerPC/convert-rr-to-ri-<wbr>instrs.mir (added)<br>
> +++ llvm/trunk/test/CodeGen/<wbr>PowerPC/convert-rr-to-ri-<wbr>instrs.mir Thu Dec 14 23:27:53 2017<br>
> @@ -0,0 +1,6129 @@<br>
> +# RUN: llc -run-pass ppc-mi-peepholes -ppc-convert-rr-to-ri %s -o - | FileCheck %s<br>
> +# RUN: llc -start-after ppc-mi-peepholes -ppc-late-peephole %s -o - | FileCheck %s --check-prefix=CHECK-LATE<br>
> +<br>
> +--- |<br>
> +  ; ModuleID = 'convert-rr-to-ri-instrs.ll'<br>
> +  source_filename = "convert-rr-to-ri-instrs.c"<br>
> +  target datalayout = "e-m:e-i64:64-n32:64"<br>
> +  target triple = "powerpc64le-unknown-linux-<wbr>gnu"<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @testADD4(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %add = add nsw i32 %a, 33<br>
> +    %add1 = add nsw i32 %add, %b<br>
> +    ret i32 %add1<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testADD8(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %add = add nsw i64 %a, 33<br>
> +    %add1 = add nsw i64 %add, %b<br>
> +    ret i64 %add1<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i128 @testADDC(i128 %a, i128 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %add = add nsw i128 %b, %a<br>
> +    ret i128 %add<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i128 @testADDC8(i128 %a, i128 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %add = add nsw i128 %b, %a<br>
> +    ret i128 %add<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testADDCo(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %add = add nsw i64 %b, %a<br>
> +    %cmp = icmp eq i64 %add, 0<br>
> +    %neg = sext i1 %cmp to i64<br>
> +    %retval.0 = xor i64 %add, %neg<br>
> +    ret i64 %retval.0<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @testADDI(i32 signext %a) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %add = add nsw i32 %a, 44<br>
> +    ret i32 %add<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @testADDI8(i32 signext %a) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %add = add nsw i32 %a, 44<br>
> +    ret i32 %add<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @testANDo(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %and = and i64 %b, %a<br>
> +    %tobool = icmp eq i64 %and, 0<br>
> +    %cond = select i1 %tobool, i64 %b, i64 %a<br>
> +    %conv = trunc i64 %cond to i32<br>
> +    ret i32 %conv<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testAND8o(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %and = and i64 %b, %a<br>
> +    %tobool = icmp eq i64 %and, 0<br>
> +    %cond = select i1 %tobool, i64 %b, i64 %a<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testCMPD(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %cmp = icmp sgt i64 %a, %b<br>
> +    %add = select i1 %cmp, i64 0, i64 %a<br>
> +    %cond = add nsw i64 %add, %b<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testCMPDI(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %cmp = icmp sgt i64 %a, 87<br>
> +    %add = select i1 %cmp, i64 0, i64 %a<br>
> +    %cond = add nsw i64 %add, %b<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testCMPDI_F(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %cmp = icmp sgt i64 %a, 87<br>
> +    %add = select i1 %cmp, i64 0, i64 %a<br>
> +    %cond = add nsw i64 %add, %b<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testCMPLD(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %cmp = icmp ugt i64 %a, %b<br>
> +    %add = select i1 %cmp, i64 0, i64 %a<br>
> +    %cond = add i64 %add, %b<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testCMPLDI(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %cmp = icmp ugt i64 %a, 87<br>
> +    %add = select i1 %cmp, i64 0, i64 %a<br>
> +    %cond = add i64 %add, %b<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @testCMPW(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %cmp = icmp sgt i32 %a, %b<br>
> +    %add = select i1 %cmp, i32 0, i32 %a<br>
> +    %cond = add nsw i32 %add, %b<br>
> +    ret i32 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @testCMPWI(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %cmp = icmp sgt i32 %a, 87<br>
> +    %add = select i1 %cmp, i32 0, i32 %a<br>
> +    %cond = add nsw i32 %add, %b<br>
> +    ret i32 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define zeroext i32 @testCMPLW(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %cmp = icmp ugt i32 %a, %b<br>
> +    %add = select i1 %cmp, i32 0, i32 %a<br>
> +    %cond = add i32 %add, %b<br>
> +    ret i32 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define zeroext i32 @testCMPLWI(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %cmp = icmp ugt i32 %a, 87<br>
> +    %add = select i1 %cmp, i32 0, i32 %a<br>
> +    %cond = add i32 %add, %b<br>
> +    ret i32 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define zeroext i8 @testLBZUX(i8* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i8, i8* %ptr, i64 %idxprom<br>
> +    %0 = load i8, i8* %arrayidx, align 1, !tbaa !3<br>
> +    %conv = zext i8 %0 to i32<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i8, i8* %ptr, i64 %idxprom2<br>
> +    %1 = load i8, i8* %arrayidx3, align 1, !tbaa !3<br>
> +    %conv4 = zext i8 %1 to i32<br>
> +    %add5 = add nuw nsw i32 %conv4, %conv<br>
> +    %conv6 = trunc i32 %add5 to i8<br>
> +    ret i8 %conv6<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define zeroext i8 @testLBZX(i8* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i8, i8* %ptr, i64 %idxprom<br>
> +    %0 = load i8, i8* %arrayidx, align 1, !tbaa !3<br>
> +    %conv = zext i8 %0 to i32<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i8, i8* %ptr, i64 %idxprom2<br>
> +    %1 = load i8, i8* %arrayidx3, align 1, !tbaa !3<br>
> +    %conv4 = zext i8 %1 to i32<br>
> +    %add5 = add nuw nsw i32 %conv4, %conv<br>
> +    %conv6 = trunc i32 %add5 to i8<br>
> +    ret i8 %conv6<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define zeroext i16 @testLHZUX(i16* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom<br>
> +    %0 = load i16, i16* %arrayidx, align 2, !tbaa !6<br>
> +    %conv = zext i16 %0 to i32<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2<br>
> +    %1 = load i16, i16* %arrayidx3, align 2, !tbaa !6<br>
> +    %conv4 = zext i16 %1 to i32<br>
> +    %add5 = add nuw nsw i32 %conv4, %conv<br>
> +    %conv6 = trunc i32 %add5 to i16<br>
> +    ret i16 %conv6<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define zeroext i16 @testLHZX(i16* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom<br>
> +    %0 = load i16, i16* %arrayidx, align 2, !tbaa !6<br>
> +    %conv = zext i16 %0 to i32<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2<br>
> +    %1 = load i16, i16* %arrayidx3, align 2, !tbaa !6<br>
> +    %conv4 = zext i16 %1 to i32<br>
> +    %add5 = add nuw nsw i32 %conv4, %conv<br>
> +    %conv6 = trunc i32 %add5 to i16<br>
> +    ret i16 %conv6<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define signext i16 @testLHAUX(i16* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom<br>
> +    %0 = load i16, i16* %arrayidx, align 2, !tbaa !6<br>
> +    %conv9 = zext i16 %0 to i32<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2<br>
> +    %1 = load i16, i16* %arrayidx3, align 2, !tbaa !6<br>
> +    %conv410 = zext i16 %1 to i32<br>
> +    %add5 = add nuw nsw i32 %conv410, %conv9<br>
> +    %conv6 = trunc i32 %add5 to i16<br>
> +    ret i16 %conv6<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define signext i16 @testLHAX(i16* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom<br>
> +    %0 = load i16, i16* %arrayidx, align 2, !tbaa !6<br>
> +    %conv9 = zext i16 %0 to i32<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2<br>
> +    %1 = load i16, i16* %arrayidx3, align 2, !tbaa !6<br>
> +    %conv410 = zext i16 %1 to i32<br>
> +    %add5 = add nuw nsw i32 %conv410, %conv9<br>
> +    %conv6 = trunc i32 %add5 to i16<br>
> +    ret i16 %conv6<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define zeroext i32 @testLWZUX(i32* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i32, i32* %ptr, i64 %idxprom<br>
> +    %0 = load i32, i32* %arrayidx, align 4, !tbaa !8<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i32, i32* %ptr, i64 %idxprom2<br>
> +    %1 = load i32, i32* %arrayidx3, align 4, !tbaa !8<br>
> +    %add4 = add i32 %1, %0<br>
> +    ret i32 %add4<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define zeroext i32 @testLWZX(i32* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i32, i32* %ptr, i64 %idxprom<br>
> +    %0 = load i32, i32* %arrayidx, align 4, !tbaa !8<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i32, i32* %ptr, i64 %idxprom2<br>
> +    %1 = load i32, i32* %arrayidx3, align 4, !tbaa !8<br>
> +    %add4 = add i32 %1, %0<br>
> +    ret i32 %add4<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define i64 @testLWAX(i32* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i32, i32* %ptr, i64 %idxprom<br>
> +    %0 = load i32, i32* %arrayidx, align 4, !tbaa !8<br>
> +    %conv = sext i32 %0 to i64<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i32, i32* %ptr, i64 %idxprom2<br>
> +    %1 = load i32, i32* %arrayidx3, align 4, !tbaa !8<br>
> +    %conv4 = sext i32 %1 to i64<br>
> +    %add5 = add nsw i64 %conv4, %conv<br>
> +    ret i64 %add5<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define i64 @testLDUX(i64* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i64, i64* %ptr, i64 %idxprom<br>
> +    %0 = load i64, i64* %arrayidx, align 8, !tbaa !10<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i64, i64* %ptr, i64 %idxprom2<br>
> +    %1 = load i64, i64* %arrayidx3, align 8, !tbaa !10<br>
> +    %add4 = add i64 %1, %0<br>
> +    ret i64 %add4<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define i64 @testLDX(i64* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i64, i64* %ptr, i64 %idxprom<br>
> +    %0 = load i64, i64* %arrayidx, align 8, !tbaa !10<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i64, i64* %ptr, i64 %idxprom2<br>
> +    %1 = load i64, i64* %arrayidx3, align 8, !tbaa !10<br>
> +    %add4 = add i64 %1, %0<br>
> +    ret i64 %add4<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define double @testLFDUX(double* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #2 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds double, double* %ptr, i64 %idxprom<br>
> +    %0 = load double, double* %arrayidx, align 8, !tbaa !12<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds double, double* %ptr, i64 %idxprom2<br>
> +    %1 = load double, double* %arrayidx3, align 8, !tbaa !12<br>
> +    %add4 = fadd double %0, %1<br>
> +    ret double %add4<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define double @testLFDX(double* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #2 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds double, double* %ptr, i64 %idxprom<br>
> +    %0 = load double, double* %arrayidx, align 8, !tbaa !12<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds double, double* %ptr, i64 %idxprom2<br>
> +    %1 = load double, double* %arrayidx3, align 8, !tbaa !12<br>
> +    %add4 = fadd double %0, %1<br>
> +    ret double %add4<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define <4 x float> @testLFSUX(float* nocapture readonly %ptr, i32 signext %idx) local_unnamed_addr #2 {<br>
> +  entry:<br>
> +    %idxprom = sext i32 %idx to i64<br>
> +    %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom<br>
> +    %0 = load float, float* %arrayidx, align 4, !tbaa !14<br>
> +    %conv = fptoui float %0 to i32<br>
> +    %vecinit = insertelement <4 x i32> undef, i32 %conv, i32 0<br>
> +    %1 = bitcast float* %ptr to i8*<br>
> +    %2 = shl i64 %idxprom, 2<br>
> +    %uglygep = getelementptr i8, i8* %1, i64 %2<br>
> +    %uglygep2 = getelementptr i8, i8* %uglygep, i64 4<br>
> +    %3 = bitcast i8* %uglygep2 to float*<br>
> +    %4 = load float, float* %3, align 4, !tbaa !14<br>
> +    %conv3 = fptoui float %4 to i32<br>
> +    %vecinit4 = insertelement <4 x i32> %vecinit, i32 %conv3, i32 1<br>
> +    %uglygep5 = getelementptr i8, i8* %uglygep, i64 8<br>
> +    %5 = bitcast i8* %uglygep5 to float*<br>
> +    %6 = load float, float* %5, align 4, !tbaa !14<br>
> +    %conv8 = fptoui float %6 to i32<br>
> +    %vecinit9 = insertelement <4 x i32> %vecinit4, i32 %conv8, i32 2<br>
> +    %uglygep8 = getelementptr i8, i8* %uglygep, i64 12<br>
> +    %7 = bitcast i8* %uglygep8 to float*<br>
> +    %8 = load float, float* %7, align 4, !tbaa !14<br>
> +    %conv13 = fptoui float %8 to i32<br>
> +    %vecinit14 = insertelement <4 x i32> %vecinit9, i32 %conv13, i32 3<br>
> +    %9 = bitcast <4 x i32> %vecinit14 to <4 x float><br>
> +    ret <4 x float> %9<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define float @testLFSX(float* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #2 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom<br>
> +    %0 = load float, float* %arrayidx, align 4, !tbaa !14<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds float, float* %ptr, i64 %idxprom2<br>
> +    %1 = load float, float* %arrayidx3, align 4, !tbaa !14<br>
> +    %add4 = fadd float %0, %1<br>
> +    ret float %add4<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define double @testLXSDX(double* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds double, double* %ptr, i64 %idxprom<br>
> +    %0 = load double, double* %arrayidx, align 8, !tbaa !12<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds double, double* %ptr, i64 %idxprom2<br>
> +    %1 = load double, double* %arrayidx3, align 8, !tbaa !12<br>
> +    %add4 = fadd double %0, %1<br>
> +    ret double %add4<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define float @testLXSSPX(float* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom<br>
> +    %0 = load float, float* %arrayidx, align 4, !tbaa !14<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds float, float* %ptr, i64 %idxprom2<br>
> +    %1 = load float, float* %arrayidx3, align 4, !tbaa !14<br>
> +    %add4 = fadd float %0, %1<br>
> +    ret float %add4<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define <4 x i32> @testLXVX(<4 x i32>* nocapture readonly %ptr, i32 zeroext %idx) local_unnamed_addr #1 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds <4 x i32>, <4 x i32>* %ptr, i64 %idxprom<br>
> +    %0 = load <4 x i32>, <4 x i32>* %arrayidx, align 16, !tbaa !3<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds <4 x i32>, <4 x i32>* %ptr, i64 %idxprom2<br>
> +    %1 = load <4 x i32>, <4 x i32>* %arrayidx3, align 16, !tbaa !3<br>
> +    %add4 = add <4 x i32> %1, %0<br>
> +    ret <4 x i32> %add4<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @testOR(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %or = or i32 %b, %a<br>
> +    ret i32 %or<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testOR8(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %or = or i64 %b, %a<br>
> +    ret i64 %or<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @testORI(i32 signext %a) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %or = or i32 %a, 88<br>
> +    ret i32 %or<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testORI8(i64 %a) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %or = or i64 %a, 99<br>
> +    ret i64 %or<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testRLDCL(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %and = and i64 %b, 63<br>
> +    %shl = shl i64 %a, %and<br>
> +    %sub = sub nsw i64 64, %and<br>
> +    %shr = lshr i64 %a, %sub<br>
> +    %or = or i64 %shr, %shl<br>
> +    ret i64 %or<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testRLDCLo(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %and = and i64 %b, 63<br>
> +    %shl = shl i64 %a, %and<br>
> +    %sub = sub nsw i64 64, %and<br>
> +    %shr = lshr i64 %a, %sub<br>
> +    %or = or i64 %shr, %shl<br>
> +    %tobool = icmp eq i64 %or, 0<br>
> +    %cond = select i1 %tobool, i64 %and, i64 %a<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testRLDCR(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %and = and i64 %b, 63<br>
> +    %shl = shl i64 %a, %and<br>
> +    %sub = sub nsw i64 64, %and<br>
> +    %shr = lshr i64 %a, %sub<br>
> +    %or = or i64 %shr, %shl<br>
> +    ret i64 %or<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testRLDCRo(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %and = and i64 %b, 63<br>
> +    %shl = shl i64 %a, %and<br>
> +    %sub = sub nsw i64 64, %and<br>
> +    %shr = lshr i64 %a, %sub<br>
> +    %or = or i64 %shr, %shl<br>
> +    %tobool = icmp eq i64 %or, 0<br>
> +    %cond = select i1 %tobool, i64 %and, i64 %a<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testRLDICL(i64 %a) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shr = lshr i64 %a, 11<br>
> +    %and = and i64 %shr, 16777215<br>
> +    ret i64 %and<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testRLDICLo(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shr = lshr i64 %a, 11<br>
> +    %and = and i64 %shr, 16777215<br>
> +    %tobool = icmp eq i64 %and, 0<br>
> +    %cond = select i1 %tobool, i64 %b, i64 %and<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define zeroext i32 @testRLWINM(i32 zeroext %a) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shl = shl i32 %a, 4<br>
> +    %and = and i32 %shl, 4080<br>
> +    ret i32 %and<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testRLWINM8(i64 %a) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shl = shl i64 %a, 4<br>
> +    %and = and i64 %shl, 4080<br>
> +    ret i64 %and<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define zeroext i32 @testRLWINMo(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %and = and i32 %a, 255<br>
> +    %tobool = icmp eq i32 %and, 0<br>
> +    %cond = select i1 %tobool, i32 %b, i32 %a<br>
> +    ret i32 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testRLWINM8o(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %<a href="http://a.tr" rel="noreferrer" target="_blank">a.tr</a> = trunc i64 %a to i32<br>
> +    %0 = shl i32 %<a href="http://a.tr" rel="noreferrer" target="_blank">a.tr</a>, 4<br>
> +    %conv = and i32 %0, 4080<br>
> +    %tobool = icmp eq i32 %conv, 0<br>
> +    %conv1 = zext i32 %conv to i64<br>
> +    %cond = select i1 %tobool, i64 %b, i64 %conv1<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testSLD(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shl = shl i64 %a, %b<br>
> +    ret i64 %shl<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testSLDo(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shl = shl i64 %a, %b<br>
> +    %tobool = icmp eq i64 %shl, 0<br>
> +    %cond = select i1 %tobool, i64 %b, i64 %a<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testSRD(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shr = lshr i64 %a, %b<br>
> +    ret i64 %shr<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testSRDo(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shr = lshr i64 %a, %b<br>
> +    %tobool = icmp eq i64 %shr, 0<br>
> +    %cond = select i1 %tobool, i64 %b, i64 %a<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define zeroext i32 @testSLW(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shl = shl i32 %a, %b<br>
> +    ret i32 %shl<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define zeroext i32 @testSLWo(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shl = shl i32 %a, %b<br>
> +    %tobool = icmp eq i32 %shl, 0<br>
> +    %cond = select i1 %tobool, i32 %b, i32 %a<br>
> +    ret i32 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define zeroext i32 @testSRW(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shr = lshr i32 %a, %b<br>
> +    ret i32 %shr<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define zeroext i32 @testSRWo(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shr = lshr i32 %a, %b<br>
> +    %tobool = icmp eq i32 %shr, 0<br>
> +    %cond = select i1 %tobool, i32 %b, i32 %a<br>
> +    ret i32 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @testSRAW(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shr = ashr i32 %a, %b<br>
> +    ret i32 %shr<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define signext i32 @testSRAWo(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shr = ashr i32 %a, %b<br>
> +    %tobool = icmp eq i32 %shr, 0<br>
> +    %cond = select i1 %tobool, i32 %b, i32 %shr<br>
> +    ret i32 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testSRAD(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shr = ashr i64 %a, %b<br>
> +    ret i64 %shr<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readnone<br>
> +  define i64 @testSRADo(i64 %a, i64 %b) local_unnamed_addr #0 {<br>
> +  entry:<br>
> +    %shr = ashr i64 %a, %b<br>
> +    %tobool = icmp eq i64 %shr, 0<br>
> +    %cond = select i1 %tobool, i64 %b, i64 %shr<br>
> +    ret i64 %cond<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind<br>
> +  define void @testSTBUX(i8* nocapture %ptr, i8 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i8, i8* %ptr, i64 %idxprom<br>
> +    store i8 %a, i8* %arrayidx, align 1, !tbaa !3<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i8, i8* %ptr, i64 %idxprom2<br>
> +    store i8 %a, i8* %arrayidx3, align 1, !tbaa !3<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind<br>
> +  define void @testSTBX(i8* nocapture %ptr, i8 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i8, i8* %ptr, i64 %idxprom<br>
> +    store i8 %a, i8* %arrayidx, align 1, !tbaa !3<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i8, i8* %ptr, i64 %idxprom2<br>
> +    store i8 %a, i8* %arrayidx3, align 1, !tbaa !3<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind<br>
> +  define void @testSTHUX(i16* nocapture %ptr, i16 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom<br>
> +    store i16 %a, i16* %arrayidx, align 2, !tbaa !6<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2<br>
> +    store i16 %a, i16* %arrayidx3, align 2, !tbaa !6<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind<br>
> +  define void @testSTHX(i16* nocapture %ptr, i16 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i16, i16* %ptr, i64 %idxprom<br>
> +    store i16 %a, i16* %arrayidx, align 1, !tbaa !3<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i16, i16* %ptr, i64 %idxprom2<br>
> +    store i16 %a, i16* %arrayidx3, align 1, !tbaa !3<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind<br>
> +  define void @testSTWUX(i32* nocapture %ptr, i32 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i32, i32* %ptr, i64 %idxprom<br>
> +    store i32 %a, i32* %arrayidx, align 4, !tbaa !8<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i32, i32* %ptr, i64 %idxprom2<br>
> +    store i32 %a, i32* %arrayidx3, align 4, !tbaa !8<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind<br>
> +  define void @testSTWX(i32* nocapture %ptr, i32 zeroext %a, i32 zeroext %idx) local_unnamed_addr #3 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i32, i32* %ptr, i64 %idxprom<br>
> +    store i32 %a, i32* %arrayidx, align 4, !tbaa !8<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i32, i32* %ptr, i64 %idxprom2<br>
> +    store i32 %a, i32* %arrayidx3, align 4, !tbaa !8<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind<br>
> +  define void @testSTDUX(i64* nocapture %ptr, i64 %a, i32 zeroext %idx) local_unnamed_addr #3 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i64, i64* %ptr, i64 %idxprom<br>
> +    store i64 %a, i64* %arrayidx, align 8, !tbaa !10<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i64, i64* %ptr, i64 %idxprom2<br>
> +    store i64 %a, i64* %arrayidx3, align 8, !tbaa !10<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind<br>
> +  define void @testSTDX(i64* nocapture %ptr, i64 %a, i32 zeroext %idx) local_unnamed_addr #3 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds i64, i64* %ptr, i64 %idxprom<br>
> +    store i64 %a, i64* %arrayidx, align 8, !tbaa !10<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds i64, i64* %ptr, i64 %idxprom2<br>
> +    store i64 %a, i64* %arrayidx3, align 8, !tbaa !10<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define void @testSTFSX(float* nocapture %ptr, float %a, i32 zeroext %idx) local_unnamed_addr #2 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom<br>
> +    store float %a, float* %arrayidx, align 4, !tbaa !14<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds float, float* %ptr, i64 %idxprom2<br>
> +    store float %a, float* %arrayidx3, align 4, !tbaa !14<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define void @testSTFSUX(float* nocapture %ptr, float %a, i32 zeroext %idx) local_unnamed_addr #2 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom<br>
> +    store float %a, float* %arrayidx, align 4, !tbaa !14<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds float, float* %ptr, i64 %idxprom2<br>
> +    store float %a, float* %arrayidx3, align 4, !tbaa !14<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define void @testSTFDX(double* nocapture %ptr, double %a, i32 zeroext %idx) local_unnamed_addr #2 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds double, double* %ptr, i64 %idxprom<br>
> +    store double %a, double* %arrayidx, align 8, !tbaa !12<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds double, double* %ptr, i64 %idxprom2<br>
> +    store double %a, double* %arrayidx3, align 8, !tbaa !12<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind readonly<br>
> +  define void @testSTFDUX(double* nocapture %ptr, double %a, i32 zeroext %idx) local_unnamed_addr #2 {<br>
> +  entry:<br>
> +    %add = add i32 %idx, 1<br>
> +    %idxprom = zext i32 %add to i64<br>
> +    %arrayidx = getelementptr inbounds double, double* %ptr, i64 %idxprom<br>
> +    store double %a, double* %arrayidx, align 8, !tbaa !12<br>
> +    %add1 = add i32 %idx, 2<br>
> +    %idxprom2 = zext i32 %add1 to i64<br>
> +    %arrayidx3 = getelementptr inbounds double, double* %ptr, i64 %idxprom2<br>
> +    store double %a, double* %arrayidx3, align 8, !tbaa !12<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind<br>
> +  define void @testSTXSSPX(float* nocapture %ptr, float %a, i32 zeroext %idx) local_unnamed_addr #3 {<br>
> +  entry:<br>
> +    %idxprom = zext i32 %idx to i64<br>
> +    %arrayidx = getelementptr inbounds float, float* %ptr, i64 %idxprom<br>
> +    store float %a, float* %arrayidx, align 4, !tbaa !14<br>
> +    ret void<br>
> +  }<br>
> +<br>
> +  ; Function Attrs: norecurse nounwind<br>
> +  define void ...<br>
><br>
> [Message clipped]<br>
</blockquote></div><br></div>