//===-- PPCInstrInfo.cpp - PowerPC Instruction Information ----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains the PowerPC implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//

#include "PPCInstrInfo.h"
#include "MCTargetDesc/PPCPredicates.h"
#include "PPC.h"
#include "PPCHazardRecognizers.h"
#include "PPCInstrBuilder.h"
#include "PPCMachineFunctionInfo.h"
#include "PPCTargetMachine.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/LiveIntervals.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/RegisterClassInfo.h"
#include "llvm/CodeGen/RegisterPressure.h"
#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/CodeGen/StackMaps.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCInst.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

#define DEBUG_TYPE "ppc-instr-info"

#define GET_INSTRMAP_INFO
#define GET_INSTRINFO_CTOR_DTOR
#include "PPCGenInstrInfo.inc"

STATISTIC(NumStoreSPILLVSRRCAsVec,
          "Number of spillvsrrc spilled to stack as vec");
STATISTIC(NumStoreSPILLVSRRCAsGpr,
          "Number of spillvsrrc spilled to stack as gpr");
STATISTIC(NumGPRtoVSRSpill, "Number of gpr spills to spillvsrrc");
STATISTIC(CmpIselsConverted,
          "Number of ISELs that depend on comparison of constants converted");
STATISTIC(MissedConvertibleImmediateInstrs,
          "Number of compare-immediate instructions fed by constants");
STATISTIC(NumRcRotatesConvertedToRcAnd,
          "Number of record-form rotates converted to record-form andi");

static cl::
opt<bool> DisableCTRLoopAnal("disable-ppc-ctrloop-analysis", cl::Hidden,
            cl::desc("Disable analysis for CTR loops"));

static cl::opt<bool> DisableCmpOpt("disable-ppc-cmp-opt",
cl::desc("Disable compare instruction optimization"), cl::Hidden);

static cl::opt<bool> VSXSelfCopyCrash("crash-on-ppc-vsx-self-copy",
cl::desc("Causes the backend to crash instead of generating a nop VSX copy"),
cl::Hidden);

static cl::opt<bool>
UseOldLatencyCalc("ppc-old-latency-calc", cl::Hidden,
  cl::desc("Use the old (incorrect) instruction latency calculation"));

static cl::opt<float>
    FMARPFactor("ppc-fma-rp-factor", cl::Hidden, cl::init(1.5),
                cl::desc("register pressure factor for the transformations."));

static cl::opt<bool> EnableFMARegPressureReduction(
    "ppc-fma-rp-reduction", cl::Hidden, cl::init(true),
    cl::desc("enable register pressure reduce in machine combiner pass."));

// Pin the vtable to this file.
void PPCInstrInfo::anchor() {}

PPCInstrInfo::PPCInstrInfo(PPCSubtarget &STI)
    : PPCGenInstrInfo(PPC::ADJCALLSTACKDOWN, PPC::ADJCALLSTACKUP,
                      /* CatchRetOpcode */ -1,
                      STI.isPPC64() ? PPC::BLR8 : PPC::BLR),
      Subtarget(STI), RI(STI.getTargetMachine()) {}

/// CreateTargetHazardRecognizer - Return the hazard recognizer to use for
/// this target when scheduling the DAG.
ScheduleHazardRecognizer *
PPCInstrInfo::CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI,
                                           const ScheduleDAG *DAG) const {
  unsigned Directive =
      static_cast<const PPCSubtarget *>(STI)->getCPUDirective();
  if (Directive == PPC::DIR_440 || Directive == PPC::DIR_A2 ||
      Directive == PPC::DIR_E500mc || Directive == PPC::DIR_E5500) {
    const InstrItineraryData *II =
        static_cast<const PPCSubtarget *>(STI)->getInstrItineraryData();
    return new ScoreboardHazardRecognizer(II, DAG);
  }

  return TargetInstrInfo::CreateTargetHazardRecognizer(STI, DAG);
}

/// CreateTargetPostRAHazardRecognizer - Return the postRA hazard recognizer
/// to use for this target when scheduling the DAG.
ScheduleHazardRecognizer *
PPCInstrInfo::CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
                                                 const ScheduleDAG *DAG) const {
  unsigned Directive =
      DAG->MF.getSubtarget<PPCSubtarget>().getCPUDirective();

  // FIXME: Leaving this as-is until we have POWER9 scheduling info
  if (Directive == PPC::DIR_PWR7 || Directive == PPC::DIR_PWR8)
    return new PPCDispatchGroupSBHazardRecognizer(II, DAG);

  // Most subtargets use a PPC970 recognizer.
  if (Directive != PPC::DIR_440 && Directive != PPC::DIR_A2 &&
      Directive != PPC::DIR_E500mc && Directive != PPC::DIR_E5500) {
    assert(DAG->TII && "No InstrInfo?");

    return new PPCHazardRecognizer970(*DAG);
  }

  return new ScoreboardHazardRecognizer(II, DAG);
}

unsigned PPCInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
                                       const MachineInstr &MI,
                                       unsigned *PredCost) const {
  if (!ItinData || UseOldLatencyCalc)
    return PPCGenInstrInfo::getInstrLatency(ItinData, MI, PredCost);

  // The default implementation of getInstrLatency calls getStageLatency, but
  // getStageLatency does not do the right thing for us. While we have
  // itinerary, most cores are fully pipelined, and so the itineraries only
  // express the first part of the pipeline, not every stage. Instead, we need
  // to use the listed output operand cycle number (using operand 0 here, which
  // is an output).

  unsigned Latency = 1;
  unsigned DefClass = MI.getDesc().getSchedClass();
  for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
    const MachineOperand &MO = MI.getOperand(i);
    if (!MO.isReg() || !MO.isDef() || MO.isImplicit())
      continue;

    int Cycle = ItinData->getOperandCycle(DefClass, i);
    if (Cycle < 0)
      continue;

    Latency = std::max(Latency, (unsigned) Cycle);
  }

  return Latency;
}

int PPCInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
                                    const MachineInstr &DefMI, unsigned DefIdx,
                                    const MachineInstr &UseMI,
                                    unsigned UseIdx) const {
  int Latency = PPCGenInstrInfo::getOperandLatency(ItinData, DefMI, DefIdx,
                                                   UseMI, UseIdx);

  if (!DefMI.getParent())
    return Latency;

  const MachineOperand &DefMO = DefMI.getOperand(DefIdx);
  Register Reg = DefMO.getReg();

  bool IsRegCR;
  if (Register::isVirtualRegister(Reg)) {
    const MachineRegisterInfo *MRI =
        &DefMI.getParent()->getParent()->getRegInfo();
    IsRegCR = MRI->getRegClass(Reg)->hasSuperClassEq(&PPC::CRRCRegClass) ||
              MRI->getRegClass(Reg)->hasSuperClassEq(&PPC::CRBITRCRegClass);
  } else {
    IsRegCR = PPC::CRRCRegClass.contains(Reg) ||
              PPC::CRBITRCRegClass.contains(Reg);
  }

  if (UseMI.isBranch() && IsRegCR) {
    if (Latency < 0)
      Latency = getInstrLatency(ItinData, DefMI);

    // On some cores, there is an additional delay between writing to a condition
    // register, and using it from a branch.
    unsigned Directive = Subtarget.getCPUDirective();
    switch (Directive) {
    default: break;
    case PPC::DIR_7400:
    case PPC::DIR_750:
    case PPC::DIR_970:
    case PPC::DIR_E5500:
    case PPC::DIR_PWR4:
    case PPC::DIR_PWR5:
    case PPC::DIR_PWR5X:
    case PPC::DIR_PWR6:
    case PPC::DIR_PWR6X:
    case PPC::DIR_PWR7:
    case PPC::DIR_PWR8:
    // FIXME: Is this needed for POWER9?
      Latency += 2;
      break;
    }
  }

  return Latency;
}

/// This is an architecture-specific helper function of reassociateOps.
/// Set special operand attributes for new instructions after reassociation.
void PPCInstrInfo::setSpecialOperandAttr(MachineInstr &OldMI1,
                                         MachineInstr &OldMI2,
                                         MachineInstr &NewMI1,
                                         MachineInstr &NewMI2) const {
  // Propagate FP flags from the original instructions.
  // But clear poison-generating flags because those may not be valid now.
  uint16_t IntersectedFlags = OldMI1.getFlags() & OldMI2.getFlags();
  NewMI1.setFlags(IntersectedFlags);
  NewMI1.clearFlag(MachineInstr::MIFlag::NoSWrap);
  NewMI1.clearFlag(MachineInstr::MIFlag::NoUWrap);
  NewMI1.clearFlag(MachineInstr::MIFlag::IsExact);

  NewMI2.setFlags(IntersectedFlags);
  NewMI2.clearFlag(MachineInstr::MIFlag::NoSWrap);
  NewMI2.clearFlag(MachineInstr::MIFlag::NoUWrap);
  NewMI2.clearFlag(MachineInstr::MIFlag::IsExact);
}

void PPCInstrInfo::setSpecialOperandAttr(MachineInstr &MI,
                                         uint16_t Flags) const {
  MI.setFlags(Flags);
  MI.clearFlag(MachineInstr::MIFlag::NoSWrap);
  MI.clearFlag(MachineInstr::MIFlag::NoUWrap);
  MI.clearFlag(MachineInstr::MIFlag::IsExact);
}

// This function does not list all associative and commutative operations, but
// only those worth feeding through the machine combiner in an attempt to
// reduce the critical path. Mostly, this means floating-point operations,
// because they have high latencies(>=5) (compared to other operations, such as
// and/or, which are also associative and commutative, but have low latencies).
bool PPCInstrInfo::isAssociativeAndCommutative(const MachineInstr &Inst) const {
  switch (Inst.getOpcode()) {
  // Floating point:
  // FP Add:
  case PPC::FADD:
  case PPC::FADDS:
  // FP Multiply:
  case PPC::FMUL:
  case PPC::FMULS:
  // Altivec Add:
  case PPC::VADDFP:
  // VSX Add:
  case PPC::XSADDDP:
  case PPC::XVADDDP:
  case PPC::XVADDSP:
  case PPC::XSADDSP:
  // VSX Multiply:
  case PPC::XSMULDP:
  case PPC::XVMULDP:
  case PPC::XVMULSP:
  case PPC::XSMULSP:
    return Inst.getFlag(MachineInstr::MIFlag::FmReassoc) &&
           Inst.getFlag(MachineInstr::MIFlag::FmNsz);
  // Fixed point:
  // Multiply:
  case PPC::MULHD:
  case PPC::MULLD:
  case PPC::MULHW:
  case PPC::MULLW:
    return true;
  default:
    return false;
  }
}

#define InfoArrayIdxFMAInst 0
#define InfoArrayIdxFAddInst 1
#define InfoArrayIdxFMULInst 2
#define InfoArrayIdxAddOpIdx 3
#define InfoArrayIdxMULOpIdx 4
#define InfoArrayIdxFSubInst 5
// Array keeps info for FMA instructions:
// Index 0(InfoArrayIdxFMAInst): FMA instruction;
// Index 1(InfoArrayIdxFAddInst): ADD instruction associated with FMA;
// Index 2(InfoArrayIdxFMULInst): MUL instruction associated with FMA;
// Index 3(InfoArrayIdxAddOpIdx): ADD operand index in FMA operands;
// Index 4(InfoArrayIdxMULOpIdx): first MUL operand index in FMA operands;
//                                second MUL operand index is plus 1;
// Index 5(InfoArrayIdxFSubInst): SUB instruction associated with FMA.
static const uint16_t FMAOpIdxInfo[][6] = {
    // FIXME: Add more FMA instructions like XSNMADDADP and so on.
    {PPC::XSMADDADP, PPC::XSADDDP, PPC::XSMULDP, 1, 2, PPC::XSSUBDP},
    {PPC::XSMADDASP, PPC::XSADDSP, PPC::XSMULSP, 1, 2, PPC::XSSUBSP},
    {PPC::XVMADDADP, PPC::XVADDDP, PPC::XVMULDP, 1, 2, PPC::XVSUBDP},
    {PPC::XVMADDASP, PPC::XVADDSP, PPC::XVMULSP, 1, 2, PPC::XVSUBSP},
    {PPC::FMADD, PPC::FADD, PPC::FMUL, 3, 1, PPC::FSUB},
    {PPC::FMADDS, PPC::FADDS, PPC::FMULS, 3, 1, PPC::FSUBS}};

// Check if an opcode is a FMA instruction. If it is, return the index in array
// FMAOpIdxInfo. Otherwise, return -1.
int16_t PPCInstrInfo::getFMAOpIdxInfo(unsigned Opcode) const {
  for (unsigned I = 0; I < array_lengthof(FMAOpIdxInfo); I++)
    if (FMAOpIdxInfo[I][InfoArrayIdxFMAInst] == Opcode)
      return I;
  return -1;
}

// On PowerPC target, we have two kinds of patterns related to FMA:
// 1: Improve ILP.
// Try to reassociate FMA chains like below:
//
// Pattern 1:
//   A =  FADD X,  Y          (Leaf)
//   B =  FMA  A,  M21,  M22  (Prev)
//   C =  FMA  B,  M31,  M32  (Root)
// -->
//   A =  FMA  X,  M21,  M22
//   B =  FMA  Y,  M31,  M32
//   C =  FADD A,  B
//
// Pattern 2:
//   A =  FMA  X,  M11,  M12  (Leaf)
//   B =  FMA  A,  M21,  M22  (Prev)
//   C =  FMA  B,  M31,  M32  (Root)
// -->
//   A =  FMUL M11,  M12
//   B =  FMA  X,  M21,  M22
//   D =  FMA  A,  M31,  M32
//   C =  FADD B,  D
//
// breaking the dependency between A and B, allowing FMA to be executed in
// parallel (or back-to-back in a pipeline) instead of depending on each other.
//
// 2: Reduce register pressure.
// Try to reassociate FMA with FSUB and a constant like below:
// C is a floating point const.
//
// Pattern 1:
//   A = FSUB  X,  Y      (Leaf)
//   D = FMA   B,  C,  A  (Root)
// -->
//   A = FMA   B,  Y,  -C
//   D = FMA   A,  X,  C
//
// Pattern 2:
//   A = FSUB  X,  Y      (Leaf)
//   D = FMA   B,  A,  C  (Root)
// -->
//   A = FMA   B,  Y,  -C
//   D = FMA   A,  X,  C
//
//  Before the transformation, A must be assigned with different hardware
//  register with D. After the transformation, A and D must be assigned with
//  same hardware register due to TIE attribute of FMA instructions.
//
bool PPCInstrInfo::getFMAPatterns(
    MachineInstr &Root, SmallVectorImpl<MachineCombinerPattern> &Patterns,
    bool DoRegPressureReduce) const {
  MachineBasicBlock *MBB = Root.getParent();
  const MachineRegisterInfo *MRI = &MBB->getParent()->getRegInfo();
  const TargetRegisterInfo *TRI = &getRegisterInfo();

  auto IsAllOpsVirtualReg = [](const MachineInstr &Instr) {
    for (const auto &MO : Instr.explicit_operands())
      if (!(MO.isReg() && Register::isVirtualRegister(MO.getReg())))
        return false;
    return true;
  };

  auto IsReassociableAddOrSub = [&](const MachineInstr &Instr,
                                    unsigned OpType) {
    if (Instr.getOpcode() !=
        FMAOpIdxInfo[getFMAOpIdxInfo(Root.getOpcode())][OpType])
      return false;

    // Instruction can be reassociated.
    // fast math flags may prohibit reassociation.
    if (!(Instr.getFlag(MachineInstr::MIFlag::FmReassoc) &&
          Instr.getFlag(MachineInstr::MIFlag::FmNsz)))
      return false;

    // Instruction operands are virtual registers for reassociation.
    if (!IsAllOpsVirtualReg(Instr))
      return false;

    // For register pressure reassociation, the FSub must have only one use as
    // we want to delete the sub to save its def.
    if (OpType == InfoArrayIdxFSubInst &&
        !MRI->hasOneNonDBGUse(Instr.getOperand(0).getReg()))
      return false;

    return true;
  };

  auto IsReassociableFMA = [&](const MachineInstr &Instr, int16_t &AddOpIdx,
                               int16_t &MulOpIdx, bool IsLeaf) {
    int16_t Idx = getFMAOpIdxInfo(Instr.getOpcode());
    if (Idx < 0)
      return false;

    // Instruction can be reassociated.
    // fast math flags may prohibit reassociation.
    if (!(Instr.getFlag(MachineInstr::MIFlag::FmReassoc) &&
          Instr.getFlag(MachineInstr::MIFlag::FmNsz)))
      return false;

    // Instruction operands are virtual registers for reassociation.
    if (!IsAllOpsVirtualReg(Instr))
      return false;

    MulOpIdx = FMAOpIdxInfo[Idx][InfoArrayIdxMULOpIdx];
    if (IsLeaf)
      return true;

    AddOpIdx = FMAOpIdxInfo[Idx][InfoArrayIdxAddOpIdx];

    const MachineOperand &OpAdd = Instr.getOperand(AddOpIdx);
    MachineInstr *MIAdd = MRI->getUniqueVRegDef(OpAdd.getReg());
    // If 'add' operand's def is not in current block, don't do ILP related opt.
    if (!MIAdd || MIAdd->getParent() != MBB)
      return false;

    // If this is not Leaf FMA Instr, its 'add' operand should only have one use
    // as this fma will be changed later.
    return IsLeaf ? true : MRI->hasOneNonDBGUse(OpAdd.getReg());
  };

  int16_t AddOpIdx = -1;
  int16_t MulOpIdx = -1;

  bool IsUsedOnceL = false;
  bool IsUsedOnceR = false;
  MachineInstr *MULInstrL = nullptr;
  MachineInstr *MULInstrR = nullptr;

  auto IsRPReductionCandidate = [&]() {
    // Currently, we only support float and double.
    // FIXME: add support for other types.
    unsigned Opcode = Root.getOpcode();
    if (Opcode != PPC::XSMADDASP && Opcode != PPC::XSMADDADP)
      return false;

    // Root must be a valid FMA like instruction.
    // Treat it as leaf as we don't care its add operand.
    if (IsReassociableFMA(Root, AddOpIdx, MulOpIdx, true)) {
      assert((MulOpIdx >= 0) && "mul operand index not right!");
      Register MULRegL = TRI->lookThruSingleUseCopyChain(
          Root.getOperand(MulOpIdx).getReg(), MRI);
      Register MULRegR = TRI->lookThruSingleUseCopyChain(
          Root.getOperand(MulOpIdx + 1).getReg(), MRI);
      if (!MULRegL && !MULRegR)
        return false;

      if (MULRegL && !MULRegR) {
        MULRegR =
            TRI->lookThruCopyLike(Root.getOperand(MulOpIdx + 1).getReg(), MRI);
        IsUsedOnceL = true;
      } else if (!MULRegL && MULRegR) {
        MULRegL =
            TRI->lookThruCopyLike(Root.getOperand(MulOpIdx).getReg(), MRI);
        IsUsedOnceR = true;
      } else {
        IsUsedOnceL = true;
        IsUsedOnceR = true;
      }

      if (!Register::isVirtualRegister(MULRegL) ||
          !Register::isVirtualRegister(MULRegR))
        return false;

      MULInstrL = MRI->getVRegDef(MULRegL);
      MULInstrR = MRI->getVRegDef(MULRegR);
      return true;
    }
    return false;
  };

  // Register pressure fma reassociation patterns.
  if (DoRegPressureReduce && IsRPReductionCandidate()) {
    assert((MULInstrL && MULInstrR) && "wrong register preduction candidate!");
    // Register pressure pattern 1
    if (isLoadFromConstantPool(MULInstrL) && IsUsedOnceR &&
        IsReassociableAddOrSub(*MULInstrR, InfoArrayIdxFSubInst)) {
      LLVM_DEBUG(dbgs() << "add pattern REASSOC_XY_BCA\n");
      Patterns.push_back(MachineCombinerPattern::REASSOC_XY_BCA);
      return true;
    }

    // Register pressure pattern 2
    if ((isLoadFromConstantPool(MULInstrR) && IsUsedOnceL &&
         IsReassociableAddOrSub(*MULInstrL, InfoArrayIdxFSubInst))) {
      LLVM_DEBUG(dbgs() << "add pattern REASSOC_XY_BAC\n");
      Patterns.push_back(MachineCombinerPattern::REASSOC_XY_BAC);
      return true;
    }
  }

  // ILP fma reassociation patterns.
  // Root must be a valid FMA like instruction.
  AddOpIdx = -1;
  if (!IsReassociableFMA(Root, AddOpIdx, MulOpIdx, false))
    return false;

  assert((AddOpIdx >= 0) && "add operand index not right!");

  Register RegB = Root.getOperand(AddOpIdx).getReg();
  MachineInstr *Prev = MRI->getUniqueVRegDef(RegB);

  // Prev must be a valid FMA like instruction.
  AddOpIdx = -1;
  if (!IsReassociableFMA(*Prev, AddOpIdx, MulOpIdx, false))
    return false;

  assert((AddOpIdx >= 0) && "add operand index not right!");

  Register RegA = Prev->getOperand(AddOpIdx).getReg();
  MachineInstr *Leaf = MRI->getUniqueVRegDef(RegA);
  AddOpIdx = -1;
  if (IsReassociableFMA(*Leaf, AddOpIdx, MulOpIdx, true)) {
    Patterns.push_back(MachineCombinerPattern::REASSOC_XMM_AMM_BMM);
    LLVM_DEBUG(dbgs() << "add pattern REASSOC_XMM_AMM_BMM\n");
    return true;
  }
  if (IsReassociableAddOrSub(*Leaf, InfoArrayIdxFAddInst)) {
    Patterns.push_back(MachineCombinerPattern::REASSOC_XY_AMM_BMM);
    LLVM_DEBUG(dbgs() << "add pattern REASSOC_XY_AMM_BMM\n");
    return true;
  }
  return false;
}

void PPCInstrInfo::finalizeInsInstrs(
    MachineInstr &Root, MachineCombinerPattern &P,
    SmallVectorImpl<MachineInstr *> &InsInstrs) const {
  assert(!InsInstrs.empty() && "Instructions set to be inserted is empty!");

  MachineFunction *MF = Root.getMF();
  MachineRegisterInfo *MRI = &MF->getRegInfo();
  const TargetRegisterInfo *TRI = &getRegisterInfo();
  MachineConstantPool *MCP = MF->getConstantPool();

  int16_t Idx = getFMAOpIdxInfo(Root.getOpcode());
  if (Idx < 0)
    return;

  uint16_t FirstMulOpIdx = FMAOpIdxInfo[Idx][InfoArrayIdxMULOpIdx];

  // For now we only need to fix up placeholder for register pressure reduce
  // patterns.
  Register ConstReg = 0;
  switch (P) {
  case MachineCombinerPattern::REASSOC_XY_BCA:
    ConstReg =
        TRI->lookThruCopyLike(Root.getOperand(FirstMulOpIdx).getReg(), MRI);
    break;
  case MachineCombinerPattern::REASSOC_XY_BAC:
    ConstReg =
        TRI->lookThruCopyLike(Root.getOperand(FirstMulOpIdx + 1).getReg(), MRI);
    break;
  default:
    // Not register pressure reduce patterns.
    return;
  }

  MachineInstr *ConstDefInstr = MRI->getVRegDef(ConstReg);
  // Get const value from const pool.
  const Constant *C = getConstantFromConstantPool(ConstDefInstr);
  assert(isa<llvm::ConstantFP>(C) && "not a valid constant!");

  // Get negative fp const.
  APFloat F1((dyn_cast<ConstantFP>(C))->getValueAPF());
  F1.changeSign();
  Constant *NegC = ConstantFP::get(dyn_cast<ConstantFP>(C)->getContext(), F1);
  Align Alignment = MF->getDataLayout().getPrefTypeAlign(C->getType());

  // Put negative fp const into constant pool.
  unsigned ConstPoolIdx = MCP->getConstantPoolIndex(NegC, Alignment);

  MachineOperand *Placeholder = nullptr;
  // Record the placeholder PPC::ZERO8 we add in reassociateFMA.
  for (auto *Inst : InsInstrs) {
    for (MachineOperand &Operand : Inst->explicit_operands()) {
      assert(Operand.isReg() && "Invalid instruction in InsInstrs!");
      if (Operand.getReg() == PPC::ZERO8) {
        Placeholder = &Operand;
        break;
      }
    }
  }

  assert(Placeholder && "Placeholder does not exist!");

  // Generate instructions to load the const fp from constant pool.
  // We only support PPC64 and medium code model.
  Register LoadNewConst =
      generateLoadForNewConst(ConstPoolIdx, &Root, C->getType(), InsInstrs);

  // Fill the placeholder with the new load from constant pool.
  Placeholder->setReg(LoadNewConst);
}

bool PPCInstrInfo::shouldReduceRegisterPressure(
    MachineBasicBlock *MBB, RegisterClassInfo *RegClassInfo) const {

  if (!EnableFMARegPressureReduction)
    return false;

  // Currently, we only enable register pressure reducing in machine combiner
  // for: 1: PPC64; 2: Code Model is Medium; 3: Power9 which also has vector
  // support.
  //
  // So we need following instructions to access a TOC entry:
  //
  // %6:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, %const.0
  // %7:vssrc = DFLOADf32 target-flags(ppc-toc-lo) %const.0,
  //   killed %6:g8rc_and_g8rc_nox0, implicit $x2 :: (load 4 from constant-pool)
  //
  // FIXME: add more supported targets, like Small and Large code model, PPC32,
  // AIX.
  if (!(Subtarget.isPPC64() && Subtarget.hasP9Vector() &&
        Subtarget.getTargetMachine().getCodeModel() == CodeModel::Medium))
    return false;

  const TargetRegisterInfo *TRI = &getRegisterInfo();
  MachineFunction *MF = MBB->getParent();
  MachineRegisterInfo *MRI = &MF->getRegInfo();

  auto GetMBBPressure = [&](MachineBasicBlock *MBB) -> std::vector<unsigned> {
    RegionPressure Pressure;
    RegPressureTracker RPTracker(Pressure);

    // Initialize the register pressure tracker.
    RPTracker.init(MBB->getParent(), RegClassInfo, nullptr, MBB, MBB->end(),
                   /*TrackLaneMasks*/ false, /*TrackUntiedDefs=*/true);

    for (MachineBasicBlock::iterator MII = MBB->instr_end(),
                                     MIE = MBB->instr_begin();
         MII != MIE; --MII) {
      MachineInstr &MI = *std::prev(MII);
      if (MI.isDebugValue() || MI.isDebugLabel())
        continue;
      RegisterOperands RegOpers;
      RegOpers.collect(MI, *TRI, *MRI, false, false);
      RPTracker.recedeSkipDebugValues();
      assert(&*RPTracker.getPos() == &MI && "RPTracker sync error!");
      RPTracker.recede(RegOpers);
    }

    // Close the RPTracker to finalize live ins.
    RPTracker.closeRegion();

    return RPTracker.getPressure().MaxSetPressure;
  };

  // For now we only care about float and double type fma.
  unsigned VSSRCLimit = TRI->getRegPressureSetLimit(
      *MBB->getParent(), PPC::RegisterPressureSets::VSSRC);

  // Only reduce register pressure when pressure is high.
  return GetMBBPressure(MBB)[PPC::RegisterPressureSets::VSSRC] >
         (float)VSSRCLimit * FMARPFactor;
}

bool PPCInstrInfo::isLoadFromConstantPool(MachineInstr *I) const {
  // I has only one memory operand which is load from constant pool.
  if (!I->hasOneMemOperand())
    return false;

  MachineMemOperand *Op = I->memoperands()[0];
  return Op->isLoad() && Op->getPseudoValue() &&
         Op->getPseudoValue()->kind() == PseudoSourceValue::ConstantPool;
}

Register PPCInstrInfo::generateLoadForNewConst(
    unsigned Idx, MachineInstr *MI, Type *Ty,
    SmallVectorImpl<MachineInstr *> &InsInstrs) const {
  // Now we only support PPC64, Medium code model and P9 with vector.
  // We have immutable pattern to access const pool. See function
  // shouldReduceRegisterPressure.
  assert((Subtarget.isPPC64() && Subtarget.hasP9Vector() &&
          Subtarget.getTargetMachine().getCodeModel() == CodeModel::Medium) &&
         "Target not supported!\n");

  MachineFunction *MF = MI->getMF();
  MachineRegisterInfo *MRI = &MF->getRegInfo();

  // Generate ADDIStocHA8
  Register VReg1 = MRI->createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
  MachineInstrBuilder TOCOffset =
      BuildMI(*MF, MI->getDebugLoc(), get(PPC::ADDIStocHA8), VReg1)
          .addReg(PPC::X2)
          .addConstantPoolIndex(Idx);

  assert((Ty->isFloatTy() || Ty->isDoubleTy()) &&
         "Only float and double are supported!");

  unsigned LoadOpcode;
  // Should be float type or double type.
  if (Ty->isFloatTy())
    LoadOpcode = PPC::DFLOADf32;
  else
    LoadOpcode = PPC::DFLOADf64;

  const TargetRegisterClass *RC = MRI->getRegClass(MI->getOperand(0).getReg());
  Register VReg2 = MRI->createVirtualRegister(RC);
  MachineMemOperand *MMO = MF->getMachineMemOperand(
      MachinePointerInfo::getConstantPool(*MF), MachineMemOperand::MOLoad,
      Ty->getScalarSizeInBits() / 8, MF->getDataLayout().getPrefTypeAlign(Ty));

  // Generate Load from constant pool.
  MachineInstrBuilder Load =
      BuildMI(*MF, MI->getDebugLoc(), get(LoadOpcode), VReg2)
          .addConstantPoolIndex(Idx)
          .addReg(VReg1, getKillRegState(true))
          .addMemOperand(MMO);

  Load->getOperand(1).setTargetFlags(PPCII::MO_TOC_LO);

  // Insert the toc load instructions into InsInstrs.
  InsInstrs.insert(InsInstrs.begin(), Load);
  InsInstrs.insert(InsInstrs.begin(), TOCOffset);
  return VReg2;
}

// This function returns the const value in constant pool if the \p I is a load
// from constant pool.
const Constant *
PPCInstrInfo::getConstantFromConstantPool(MachineInstr *I) const {
  MachineFunction *MF = I->getMF();
  MachineRegisterInfo *MRI = &MF->getRegInfo();
  MachineConstantPool *MCP = MF->getConstantPool();
  assert(I->mayLoad() && "Should be a load instruction.\n");
  for (auto MO : I->uses()) {
    if (!MO.isReg())
      continue;
    Register Reg = MO.getReg();
    if (Reg == 0 || !Register::isVirtualRegister(Reg))
      continue;
    // Find the toc address.
    MachineInstr *DefMI = MRI->getVRegDef(Reg);
    for (auto MO2 : DefMI->uses())
      if (MO2.isCPI())
        return (MCP->getConstants())[MO2.getIndex()].Val.ConstVal;
  }
  return nullptr;
}

bool PPCInstrInfo::getMachineCombinerPatterns(
    MachineInstr &Root, SmallVectorImpl<MachineCombinerPattern> &Patterns,
    bool DoRegPressureReduce) const {
  // Using the machine combiner in this way is potentially expensive, so
  // restrict to when aggressive optimizations are desired.
  if (Subtarget.getTargetMachine().getOptLevel() != CodeGenOpt::Aggressive)
    return false;

  if (getFMAPatterns(Root, Patterns, DoRegPressureReduce))
    return true;

  return TargetInstrInfo::getMachineCombinerPatterns(Root, Patterns,
                                                     DoRegPressureReduce);
}

void PPCInstrInfo::genAlternativeCodeSequence(
    MachineInstr &Root, MachineCombinerPattern Pattern,
    SmallVectorImpl<MachineInstr *> &InsInstrs,
    SmallVectorImpl<MachineInstr *> &DelInstrs,
    DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const {
  switch (Pattern) {
  case MachineCombinerPattern::REASSOC_XY_AMM_BMM:
  case MachineCombinerPattern::REASSOC_XMM_AMM_BMM:
  case MachineCombinerPattern::REASSOC_XY_BCA:
  case MachineCombinerPattern::REASSOC_XY_BAC:
    reassociateFMA(Root, Pattern, InsInstrs, DelInstrs, InstrIdxForVirtReg);
    break;
  default:
    // Reassociate default patterns.
    TargetInstrInfo::genAlternativeCodeSequence(Root, Pattern, InsInstrs,
                                                DelInstrs, InstrIdxForVirtReg);
    break;
  }
}

void PPCInstrInfo::reassociateFMA(
    MachineInstr &Root, MachineCombinerPattern Pattern,
    SmallVectorImpl<MachineInstr *> &InsInstrs,
    SmallVectorImpl<MachineInstr *> &DelInstrs,
    DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const {
  MachineFunction *MF = Root.getMF();
  MachineRegisterInfo &MRI = MF->getRegInfo();
  const TargetRegisterInfo *TRI = &getRegisterInfo();
  MachineOperand &OpC = Root.getOperand(0);
  Register RegC = OpC.getReg();
  const TargetRegisterClass *RC = MRI.getRegClass(RegC);
  MRI.constrainRegClass(RegC, RC);

  unsigned FmaOp = Root.getOpcode();
  int16_t Idx = getFMAOpIdxInfo(FmaOp);
  assert(Idx >= 0 && "Root must be a FMA instruction");

  bool IsILPReassociate =
      (Pattern == MachineCombinerPattern::REASSOC_XY_AMM_BMM) ||
      (Pattern == MachineCombinerPattern::REASSOC_XMM_AMM_BMM);

  uint16_t AddOpIdx = FMAOpIdxInfo[Idx][InfoArrayIdxAddOpIdx];
  uint16_t FirstMulOpIdx = FMAOpIdxInfo[Idx][InfoArrayIdxMULOpIdx];

  MachineInstr *Prev = nullptr;
  MachineInstr *Leaf = nullptr;
  switch (Pattern) {
  default:
    llvm_unreachable("not recognized pattern!");
  case MachineCombinerPattern::REASSOC_XY_AMM_BMM:
  case MachineCombinerPattern::REASSOC_XMM_AMM_BMM:
    Prev = MRI.getUniqueVRegDef(Root.getOperand(AddOpIdx).getReg());
    Leaf = MRI.getUniqueVRegDef(Prev->getOperand(AddOpIdx).getReg());
    break;
  case MachineCombinerPattern::REASSOC_XY_BAC: {
    Register MULReg =
        TRI->lookThruCopyLike(Root.getOperand(FirstMulOpIdx).getReg(), &MRI);
    Leaf = MRI.getVRegDef(MULReg);
    break;
  }
  case MachineCombinerPattern::REASSOC_XY_BCA: {
    Register MULReg = TRI->lookThruCopyLike(
        Root.getOperand(FirstMulOpIdx + 1).getReg(), &MRI);
    Leaf = MRI.getVRegDef(MULReg);
    break;
  }
  }

  uint16_t IntersectedFlags = 0;
  if (IsILPReassociate)
    IntersectedFlags = Root.getFlags() & Prev->getFlags() & Leaf->getFlags();
  else
    IntersectedFlags = Root.getFlags() & Leaf->getFlags();

  auto GetOperandInfo = [&](const MachineOperand &Operand, Register &Reg,
                            bool &KillFlag) {
    Reg = Operand.getReg();
    MRI.constrainRegClass(Reg, RC);
    KillFlag = Operand.isKill();
  };

  auto GetFMAInstrInfo = [&](const MachineInstr &Instr, Register &MulOp1,
                             Register &MulOp2, Register &AddOp,
                             bool &MulOp1KillFlag, bool &MulOp2KillFlag,
                             bool &AddOpKillFlag) {
    GetOperandInfo(Instr.getOperand(FirstMulOpIdx), MulOp1, MulOp1KillFlag);
    GetOperandInfo(Instr.getOperand(FirstMulOpIdx + 1), MulOp2, MulOp2KillFlag);
    GetOperandInfo(Instr.getOperand(AddOpIdx), AddOp, AddOpKillFlag);
  };

  Register RegM11, RegM12, RegX, RegY, RegM21, RegM22, RegM31, RegM32, RegA11,
      RegA21, RegB;
  bool KillX = false, KillY = false, KillM11 = false, KillM12 = false,
       KillM21 = false, KillM22 = false, KillM31 = false, KillM32 = false,
       KillA11 = false, KillA21 = false, KillB = false;

  GetFMAInstrInfo(Root, RegM31, RegM32, RegB, KillM31, KillM32, KillB);

  if (IsILPReassociate)
    GetFMAInstrInfo(*Prev, RegM21, RegM22, RegA21, KillM21, KillM22, KillA21);

  if (Pattern == MachineCombinerPattern::REASSOC_XMM_AMM_BMM) {
    GetFMAInstrInfo(*Leaf, RegM11, RegM12, RegA11, KillM11, KillM12, KillA11);
    GetOperandInfo(Leaf->getOperand(AddOpIdx), RegX, KillX);
  } else if (Pattern == MachineCombinerPattern::REASSOC_XY_AMM_BMM) {
    GetOperandInfo(Leaf->getOperand(1), RegX, KillX);
    GetOperandInfo(Leaf->getOperand(2), RegY, KillY);
  } else {
    // Get FSUB instruction info.
    GetOperandInfo(Leaf->getOperand(1), RegX, KillX);
    GetOperandInfo(Leaf->getOperand(2), RegY, KillY);
  }

  // Create new virtual registers for the new results instead of
  // recycling legacy ones because the MachineCombiner's computation of the
  // critical path requires a new register definition rather than an existing
  // one.
  // For register pressure reassociation, we only need create one virtual
  // register for the new fma.
  Register NewVRA = MRI.createVirtualRegister(RC);
  InstrIdxForVirtReg.insert(std::make_pair(NewVRA, 0));

  Register NewVRB = 0;
  if (IsILPReassociate) {
    NewVRB = MRI.createVirtualRegister(RC);
    InstrIdxForVirtReg.insert(std::make_pair(NewVRB, 1));
  }

  Register NewVRD = 0;
  if (Pattern == MachineCombinerPattern::REASSOC_XMM_AMM_BMM) {
    NewVRD = MRI.createVirtualRegister(RC);
    InstrIdxForVirtReg.insert(std::make_pair(NewVRD, 2));
  }

  auto AdjustOperandOrder = [&](MachineInstr *MI, Register RegAdd, bool KillAdd,
                                Register RegMul1, bool KillRegMul1,
                                Register RegMul2, bool KillRegMul2) {
    MI->getOperand(AddOpIdx).setReg(RegAdd);
    MI->getOperand(AddOpIdx).setIsKill(KillAdd);
    MI->getOperand(FirstMulOpIdx).setReg(RegMul1);
    MI->getOperand(FirstMulOpIdx).setIsKill(KillRegMul1);
    MI->getOperand(FirstMulOpIdx + 1).setReg(RegMul2);
    MI->getOperand(FirstMulOpIdx + 1).setIsKill(KillRegMul2);
  };

  MachineInstrBuilder NewARegPressure, NewCRegPressure;
  switch (Pattern) {
  default:
    llvm_unreachable("not recognized pattern!");
  case MachineCombinerPattern::REASSOC_XY_AMM_BMM: {
    // Create new instructions for insertion.
    MachineInstrBuilder MINewB =
        BuildMI(*MF, Prev->getDebugLoc(), get(FmaOp), NewVRB)
            .addReg(RegX, getKillRegState(KillX))
            .addReg(RegM21, getKillRegState(KillM21))
            .addReg(RegM22, getKillRegState(KillM22));
    MachineInstrBuilder MINewA =
        BuildMI(*MF, Root.getDebugLoc(), get(FmaOp), NewVRA)
            .addReg(RegY, getKillRegState(KillY))
            .addReg(RegM31, getKillRegState(KillM31))
            .addReg(RegM32, getKillRegState(KillM32));
    // If AddOpIdx is not 1, adjust the order.
    if (AddOpIdx != 1) {
      AdjustOperandOrder(MINewB, RegX, KillX, RegM21, KillM21, RegM22, KillM22);
      AdjustOperandOrder(MINewA, RegY, KillY, RegM31, KillM31, RegM32, KillM32);
    }

    MachineInstrBuilder MINewC =
        BuildMI(*MF, Root.getDebugLoc(),
                get(FMAOpIdxInfo[Idx][InfoArrayIdxFAddInst]), RegC)
            .addReg(NewVRB, getKillRegState(true))
            .addReg(NewVRA, getKillRegState(true));

    // Update flags for newly created instructions.
    setSpecialOperandAttr(*MINewA, IntersectedFlags);
    setSpecialOperandAttr(*MINewB, IntersectedFlags);
    setSpecialOperandAttr(*MINewC, IntersectedFlags);

    // Record new instructions for insertion.
    InsInstrs.push_back(MINewA);
    InsInstrs.push_back(MINewB);
    InsInstrs.push_back(MINewC);
    break;
  }
  case MachineCombinerPattern::REASSOC_XMM_AMM_BMM: {
    assert(NewVRD && "new FMA register not created!");
    // Create new instructions for insertion.
    MachineInstrBuilder MINewA =
        BuildMI(*MF, Leaf->getDebugLoc(),
                get(FMAOpIdxInfo[Idx][InfoArrayIdxFMULInst]), NewVRA)
            .addReg(RegM11, getKillRegState(KillM11))
            .addReg(RegM12, getKillRegState(KillM12));
    MachineInstrBuilder MINewB =
        BuildMI(*MF, Prev->getDebugLoc(), get(FmaOp), NewVRB)
            .addReg(RegX, getKillRegState(KillX))
            .addReg(RegM21, getKillRegState(KillM21))
            .addReg(RegM22, getKillRegState(KillM22));
    MachineInstrBuilder MINewD =
        BuildMI(*MF, Root.getDebugLoc(), get(FmaOp), NewVRD)
            .addReg(NewVRA, getKillRegState(true))
            .addReg(RegM31, getKillRegState(KillM31))
            .addReg(RegM32, getKillRegState(KillM32));
    // If AddOpIdx is not 1, adjust the order.
    if (AddOpIdx != 1) {
      AdjustOperandOrder(MINewB, RegX, KillX, RegM21, KillM21, RegM22, KillM22);
      AdjustOperandOrder(MINewD, NewVRA, true, RegM31, KillM31, RegM32,
                         KillM32);
    }

    MachineInstrBuilder MINewC =
        BuildMI(*MF, Root.getDebugLoc(),
                get(FMAOpIdxInfo[Idx][InfoArrayIdxFAddInst]), RegC)
            .addReg(NewVRB, getKillRegState(true))
            .addReg(NewVRD, getKillRegState(true));

    // Update flags for newly created instructions.
    setSpecialOperandAttr(*MINewA, IntersectedFlags);
    setSpecialOperandAttr(*MINewB, IntersectedFlags);
    setSpecialOperandAttr(*MINewD, IntersectedFlags);
    setSpecialOperandAttr(*MINewC, IntersectedFlags);

    // Record new instructions for insertion.
    InsInstrs.push_back(MINewA);
    InsInstrs.push_back(MINewB);
    InsInstrs.push_back(MINewD);
    InsInstrs.push_back(MINewC);
    break;
  }
  case MachineCombinerPattern::REASSOC_XY_BAC:
  case MachineCombinerPattern::REASSOC_XY_BCA: {
    Register VarReg;
    bool KillVarReg = false;
    if (Pattern == MachineCombinerPattern::REASSOC_XY_BCA) {
      VarReg = RegM31;
      KillVarReg = KillM31;
    } else {
      VarReg = RegM32;
      KillVarReg = KillM32;
    }
    // We don't want to get negative const from memory pool too early, as the
    // created entry will not be deleted even if it has no users. Since all
    // operand of Leaf and Root are virtual register, we use zero register
    // here as a placeholder. When the InsInstrs is selected in
    // MachineCombiner, we call finalizeInsInstrs to replace the zero register
    // with a virtual register which is a load from constant pool.
    NewARegPressure = BuildMI(*MF, Root.getDebugLoc(), get(FmaOp), NewVRA)
                          .addReg(RegB, getKillRegState(RegB))
                          .addReg(RegY, getKillRegState(KillY))
                          .addReg(PPC::ZERO8);
    NewCRegPressure = BuildMI(*MF, Root.getDebugLoc(), get(FmaOp), RegC)
                          .addReg(NewVRA, getKillRegState(true))
                          .addReg(RegX, getKillRegState(KillX))
                          .addReg(VarReg, getKillRegState(KillVarReg));
    // For now, we only support xsmaddadp/xsmaddasp, their add operand are
    // both at index 1, no need to adjust.
    // FIXME: when add more fma instructions support, like fma/fmas, adjust
    // the operand index here.
    break;
  }
  }

  if (!IsILPReassociate) {
    setSpecialOperandAttr(*NewARegPressure, IntersectedFlags);
    setSpecialOperandAttr(*NewCRegPressure, IntersectedFlags);

    InsInstrs.push_back(NewARegPressure);
    InsInstrs.push_back(NewCRegPressure);
  }

  assert(!InsInstrs.empty() &&
         "Insertion instructions set should not be empty!");

  // Record old instructions for deletion.
  DelInstrs.push_back(Leaf);
  if (IsILPReassociate)
    DelInstrs.push_back(Prev);
  DelInstrs.push_back(&Root);
}

// Detect 32 -> 64-bit extensions where we may reuse the low sub-register.
bool PPCInstrInfo::isCoalescableExtInstr(const MachineInstr &MI,
                                         Register &SrcReg, Register &DstReg,
                                         unsigned &SubIdx) const {
  switch (MI.getOpcode()) {
  default: return false;
  case PPC::EXTSW:
  case PPC::EXTSW_32:
  case PPC::EXTSW_32_64:
    SrcReg = MI.getOperand(1).getReg();
    DstReg = MI.getOperand(0).getReg();
    SubIdx = PPC::sub_32;
    return true;
  }
}

unsigned PPCInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
                                           int &FrameIndex) const {
  unsigned Opcode = MI.getOpcode();
  const unsigned *OpcodesForSpill = getLoadOpcodesForSpillArray();
  const unsigned *End = OpcodesForSpill + SOK_LastOpcodeSpill;

  if (End != std::find(OpcodesForSpill, End, Opcode)) {
    // Check for the operands added by addFrameReference (the immediate is the
    // offset which defaults to 0).
    if (MI.getOperand(1).isImm() && !MI.getOperand(1).getImm() &&
        MI.getOperand(2).isFI()) {
      FrameIndex = MI.getOperand(2).getIndex();
      return MI.getOperand(0).getReg();
    }
  }
  return 0;
}

// For opcodes with the ReMaterializable flag set, this function is called to
// verify the instruction is really rematable.
bool PPCInstrInfo::isReallyTriviallyReMaterializable(const MachineInstr &MI,
                                                     AliasAnalysis *AA) const {
  switch (MI.getOpcode()) {
  default:
    // This function should only be called for opcodes with the ReMaterializable
    // flag set.
    llvm_unreachable("Unknown rematerializable operation!");
    break;
  case PPC::LI:
  case PPC::LI8:
  case PPC::PLI:
  case PPC::PLI8:
  case PPC::LIS:
  case PPC::LIS8:
  case PPC::ADDIStocHA:
  case PPC::ADDIStocHA8:
  case PPC::ADDItocL:
  case PPC::LOAD_STACK_GUARD:
  case PPC::XXLXORz:
  case PPC::XXLXORspz:
  case PPC::XXLXORdpz:
  case PPC::XXLEQVOnes:
  case PPC::XXSPLTI32DX:
  case PPC::V_SET0B:
  case PPC::V_SET0H:
  case PPC::V_SET0:
  case PPC::V_SETALLONESB:
  case PPC::V_SETALLONESH:
  case PPC::V_SETALLONES:
  case PPC::CRSET:
  case PPC::CRUNSET:
  case PPC::XXSETACCZ:
    return true;
  }
  return false;
}

unsigned PPCInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
                                          int &FrameIndex) const {
  unsigned Opcode = MI.getOpcode();
  const unsigned *OpcodesForSpill = getStoreOpcodesForSpillArray();
  const unsigned *End = OpcodesForSpill + SOK_LastOpcodeSpill;

  if (End != std::find(OpcodesForSpill, End, Opcode)) {
    if (MI.getOperand(1).isImm() && !MI.getOperand(1).getImm() &&
        MI.getOperand(2).isFI()) {
      FrameIndex = MI.getOperand(2).getIndex();
      return MI.getOperand(0).getReg();
    }
  }
  return 0;
}

MachineInstr *PPCInstrInfo::commuteInstructionImpl(MachineInstr &MI, bool NewMI,
                                                   unsigned OpIdx1,
                                                   unsigned OpIdx2) const {
  MachineFunction &MF = *MI.getParent()->getParent();

  // Normal instructions can be commuted the obvious way.
  if (MI.getOpcode() != PPC::RLWIMI && MI.getOpcode() != PPC::RLWIMI_rec)
    return TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2);
  // Note that RLWIMI can be commuted as a 32-bit instruction, but not as a
  // 64-bit instruction (so we don't handle PPC::RLWIMI8 here), because
  // changing the relative order of the mask operands might change what happens
  // to the high-bits of the mask (and, thus, the result).

  // Cannot commute if it has a non-zero rotate count.
  if (MI.getOperand(3).getImm() != 0)
    return nullptr;

  // If we have a zero rotate count, we have:
  //   M = mask(MB,ME)
  //   Op0 = (Op1 & ~M) | (Op2 & M)
  // Change this to:
  //   M = mask((ME+1)&31, (MB-1)&31)
  //   Op0 = (Op2 & ~M) | (Op1 & M)

  // Swap op1/op2
  assert(((OpIdx1 == 1 && OpIdx2 == 2) || (OpIdx1 == 2 && OpIdx2 == 1)) &&
         "Only the operands 1 and 2 can be swapped in RLSIMI/RLWIMI_rec.");
  Register Reg0 = MI.getOperand(0).getReg();
  Register Reg1 = MI.getOperand(1).getReg();
  Register Reg2 = MI.getOperand(2).getReg();
  unsigned SubReg1 = MI.getOperand(1).getSubReg();
  unsigned SubReg2 = MI.getOperand(2).getSubReg();
  bool Reg1IsKill = MI.getOperand(1).isKill();
  bool Reg2IsKill = MI.getOperand(2).isKill();
  bool ChangeReg0 = false;
  // If machine instrs are no longer in two-address forms, update
  // destination register as well.
  if (Reg0 == Reg1) {
    // Must be two address instruction!
    assert(MI.getDesc().getOperandConstraint(0, MCOI::TIED_TO) &&
           "Expecting a two-address instruction!");
    assert(MI.getOperand(0).getSubReg() == SubReg1 && "Tied subreg mismatch");
    Reg2IsKill = false;
    ChangeReg0 = true;
  }

  // Masks.
  unsigned MB = MI.getOperand(4).getImm();
  unsigned ME = MI.getOperand(5).getImm();

  // We can't commute a trivial mask (there is no way to represent an all-zero
  // mask).
  if (MB == 0 && ME == 31)
    return nullptr;

  if (NewMI) {
    // Create a new instruction.
    Register Reg0 = ChangeReg0 ? Reg2 : MI.getOperand(0).getReg();
    bool Reg0IsDead = MI.getOperand(0).isDead();
    return BuildMI(MF, MI.getDebugLoc(), MI.getDesc())
        .addReg(Reg0, RegState::Define | getDeadRegState(Reg0IsDead))
        .addReg(Reg2, getKillRegState(Reg2IsKill))
        .addReg(Reg1, getKillRegState(Reg1IsKill))
        .addImm((ME + 1) & 31)
        .addImm((MB - 1) & 31);
  }

  if (ChangeReg0) {
    MI.getOperand(0).setReg(Reg2);
    MI.getOperand(0).setSubReg(SubReg2);
  }
  MI.getOperand(2).setReg(Reg1);
  MI.getOperand(1).setReg(Reg2);
  MI.getOperand(2).setSubReg(SubReg1);
  MI.getOperand(1).setSubReg(SubReg2);
  MI.getOperand(2).setIsKill(Reg1IsKill);
  MI.getOperand(1).setIsKill(Reg2IsKill);

  // Swap the mask around.
  MI.getOperand(4).setImm((ME + 1) & 31);
  MI.getOperand(5).setImm((MB - 1) & 31);
  return &MI;
}

bool PPCInstrInfo::findCommutedOpIndices(const MachineInstr &MI,
                                         unsigned &SrcOpIdx1,
                                         unsigned &SrcOpIdx2) const {
  // For VSX A-Type FMA instructions, it is the first two operands that can be
  // commuted, however, because the non-encoded tied input operand is listed
  // first, the operands to swap are actually the second and third.

  int AltOpc = PPC::getAltVSXFMAOpcode(MI.getOpcode());
  if (AltOpc == -1)
    return TargetInstrInfo::findCommutedOpIndices(MI, SrcOpIdx1, SrcOpIdx2);

  // The commutable operand indices are 2 and 3. Return them in SrcOpIdx1
  // and SrcOpIdx2.
  return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
}

void PPCInstrInfo::insertNoop(MachineBasicBlock &MBB,
                              MachineBasicBlock::iterator MI) const {
  // This function is used for scheduling, and the nop wanted here is the type
  // that terminates dispatch groups on the POWER cores.
  unsigned Directive = Subtarget.getCPUDirective();
  unsigned Opcode;
  switch (Directive) {
  default:            Opcode = PPC::NOP; break;
  case PPC::DIR_PWR6: Opcode = PPC::NOP_GT_PWR6; break;
  case PPC::DIR_PWR7: Opcode = PPC::NOP_GT_PWR7; break;
  case PPC::DIR_PWR8: Opcode = PPC::NOP_GT_PWR7; break; /* FIXME: Update when P8 InstrScheduling model is ready */
  // FIXME: Update when POWER9 scheduling model is ready.
  case PPC::DIR_PWR9: Opcode = PPC::NOP_GT_PWR7; break;
  }

  DebugLoc DL;
  BuildMI(MBB, MI, DL, get(Opcode));
}

/// Return the noop instruction to use for a noop.
MCInst PPCInstrInfo::getNop() const {
  MCInst Nop;
  Nop.setOpcode(PPC::NOP);
  return Nop;
}

// Branch analysis.
// Note: If the condition register is set to CTR or CTR8 then this is a
// BDNZ (imm == 1) or BDZ (imm == 0) branch.
bool PPCInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
                                 MachineBasicBlock *&TBB,
                                 MachineBasicBlock *&FBB,
                                 SmallVectorImpl<MachineOperand> &Cond,
                                 bool AllowModify) const {
  bool isPPC64 = Subtarget.isPPC64();

  // If the block has no terminators, it just falls into the block after it.
  MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
  if (I == MBB.end())
    return false;

  if (!isUnpredicatedTerminator(*I))
    return false;

  if (AllowModify) {
    // If the BB ends with an unconditional branch to the fallthrough BB,
    // we eliminate the branch instruction.
    if (I->getOpcode() == PPC::B &&
        MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
      I->eraseFromParent();

      // We update iterator after deleting the last branch.
      I = MBB.getLastNonDebugInstr();
      if (I == MBB.end() || !isUnpredicatedTerminator(*I))
        return false;
    }
  }

  // Get the last instruction in the block.
  MachineInstr &LastInst = *I;

  // If there is only one terminator instruction, process it.
  if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
    if (LastInst.getOpcode() == PPC::B) {
      if (!LastInst.getOperand(0).isMBB())
        return true;
      TBB = LastInst.getOperand(0).getMBB();
      return false;
    } else if (LastInst.getOpcode() == PPC::BCC) {
      if (!LastInst.getOperand(2).isMBB())
        return true;
      // Block ends with fall-through condbranch.
      TBB = LastInst.getOperand(2).getMBB();
      Cond.push_back(LastInst.getOperand(0));
      Cond.push_back(LastInst.getOperand(1));
      return false;
    } else if (LastInst.getOpcode() == PPC::BC) {
      if (!LastInst.getOperand(1).isMBB())
        return true;
      // Block ends with fall-through condbranch.
      TBB = LastInst.getOperand(1).getMBB();
      Cond.push_back(MachineOperand::CreateImm(PPC::PRED_BIT_SET));
      Cond.push_back(LastInst.getOperand(0));
      return false;
    } else if (LastInst.getOpcode() == PPC::BCn) {
      if (!LastInst.getOperand(1).isMBB())
        return true;
      // Block ends with fall-through condbranch.
      TBB = LastInst.getOperand(1).getMBB();
      Cond.push_back(MachineOperand::CreateImm(PPC::PRED_BIT_UNSET));
      Cond.push_back(LastInst.getOperand(0));
      return false;
    } else if (LastInst.getOpcode() == PPC::BDNZ8 ||
               LastInst.getOpcode() == PPC::BDNZ) {
      if (!LastInst.getOperand(0).isMBB())
        return true;
      if (DisableCTRLoopAnal)
        return true;
      TBB = LastInst.getOperand(0).getMBB();
      Cond.push_back(MachineOperand::CreateImm(1));
      Cond.push_back(MachineOperand::CreateReg(isPPC64 ? PPC::CTR8 : PPC::CTR,
                                               true));
      return false;
    } else if (LastInst.getOpcode() == PPC::BDZ8 ||
               LastInst.getOpcode() == PPC::BDZ) {
      if (!LastInst.getOperand(0).isMBB())
        return true;
      if (DisableCTRLoopAnal)
        return true;
      TBB = LastInst.getOperand(0).getMBB();
      Cond.push_back(MachineOperand::CreateImm(0));
      Cond.push_back(MachineOperand::CreateReg(isPPC64 ? PPC::CTR8 : PPC::CTR,
                                               true));
      return false;
    }

    // Otherwise, don't know what this is.
    return true;
  }

  // Get the instruction before it if it's a terminator.
  MachineInstr &SecondLastInst = *I;

  // If there are three terminators, we don't know what sort of block this is.
  if (I != MBB.begin() && isUnpredicatedTerminator(*--I))
    return true;

  // If the block ends with PPC::B and PPC:BCC, handle it.
  if (SecondLastInst.getOpcode() == PPC::BCC &&
      LastInst.getOpcode() == PPC::B) {
    if (!SecondLastInst.getOperand(2).isMBB() ||
        !LastInst.getOperand(0).isMBB())
      return true;
    TBB = SecondLastInst.getOperand(2).getMBB();
    Cond.push_back(SecondLastInst.getOperand(0));
    Cond.push_back(SecondLastInst.getOperand(1));
    FBB = LastInst.getOperand(0).getMBB();
    return false;
  } else if (SecondLastInst.getOpcode() == PPC::BC &&
             LastInst.getOpcode() == PPC::B) {
    if (!SecondLastInst.getOperand(1).isMBB() ||
        !LastInst.getOperand(0).isMBB())
      return true;
    TBB = SecondLastInst.getOperand(1).getMBB();
    Cond.push_back(MachineOperand::CreateImm(PPC::PRED_BIT_SET));
    Cond.push_back(SecondLastInst.getOperand(0));
    FBB = LastInst.getOperand(0).getMBB();
    return false;
  } else if (SecondLastInst.getOpcode() == PPC::BCn &&
             LastInst.getOpcode() == PPC::B) {
    if (!SecondLastInst.getOperand(1).isMBB() ||
        !LastInst.getOperand(0).isMBB())
      return true;
    TBB = SecondLastInst.getOperand(1).getMBB();
    Cond.push_back(MachineOperand::CreateImm(PPC::PRED_BIT_UNSET));
    Cond.push_back(SecondLastInst.getOperand(0));
    FBB = LastInst.getOperand(0).getMBB();
    return false;
  } else if ((SecondLastInst.getOpcode() == PPC::BDNZ8 ||
              SecondLastInst.getOpcode() == PPC::BDNZ) &&
             LastInst.getOpcode() == PPC::B) {
    if (!SecondLastInst.getOperand(0).isMBB() ||
        !LastInst.getOperand(0).isMBB())
      return true;
    if (DisableCTRLoopAnal)
      return true;
    TBB = SecondLastInst.getOperand(0).getMBB();
    Cond.push_back(MachineOperand::CreateImm(1));
    Cond.push_back(MachineOperand::CreateReg(isPPC64 ? PPC::CTR8 : PPC::CTR,
                                             true));
    FBB = LastInst.getOperand(0).getMBB();
    return false;
  } else if ((SecondLastInst.getOpcode() == PPC::BDZ8 ||
              SecondLastInst.getOpcode() == PPC::BDZ) &&
             LastInst.getOpcode() == PPC::B) {
    if (!SecondLastInst.getOperand(0).isMBB() ||
        !LastInst.getOperand(0).isMBB())
      return true;
    if (DisableCTRLoopAnal)
      return true;
    TBB = SecondLastInst.getOperand(0).getMBB();
    Cond.push_back(MachineOperand::CreateImm(0));
    Cond.push_back(MachineOperand::CreateReg(isPPC64 ? PPC::CTR8 : PPC::CTR,
                                             true));
    FBB = LastInst.getOperand(0).getMBB();
    return false;
  }

  // If the block ends with two PPC:Bs, handle it.  The second one is not
  // executed, so remove it.
  if (SecondLastInst.getOpcode() == PPC::B && LastInst.getOpcode() == PPC::B) {
    if (!SecondLastInst.getOperand(0).isMBB())
      return true;
    TBB = SecondLastInst.getOperand(0).getMBB();
    I = LastInst;
    if (AllowModify)
      I->eraseFromParent();
    return false;
  }

  // Otherwise, can't handle this.
  return true;
}

unsigned PPCInstrInfo::removeBranch(MachineBasicBlock &MBB,
                                    int *BytesRemoved) const {
  assert(!BytesRemoved && "code size not handled");

  MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
  if (I == MBB.end())
    return 0;

  if (I->getOpcode() != PPC::B && I->getOpcode() != PPC::BCC &&
      I->getOpcode() != PPC::BC && I->getOpcode() != PPC::BCn &&
      I->getOpcode() != PPC::BDNZ8 && I->getOpcode() != PPC::BDNZ &&
      I->getOpcode() != PPC::BDZ8  && I->getOpcode() != PPC::BDZ)
    return 0;

  // Remove the branch.
  I->eraseFromParent();

  I = MBB.end();

  if (I == MBB.begin()) return 1;
  --I;
  if (I->getOpcode() != PPC::BCC &&
      I->getOpcode() != PPC::BC && I->getOpcode() != PPC::BCn &&
      I->getOpcode() != PPC::BDNZ8 && I->getOpcode() != PPC::BDNZ &&
      I->getOpcode() != PPC::BDZ8  && I->getOpcode() != PPC::BDZ)
    return 1;

  // Remove the branch.
  I->eraseFromParent();
  return 2;
}

unsigned PPCInstrInfo::insertBranch(MachineBasicBlock &MBB,
                                    MachineBasicBlock *TBB,
                                    MachineBasicBlock *FBB,
                                    ArrayRef<MachineOperand> Cond,
                                    const DebugLoc &DL,
                                    int *BytesAdded) const {
  // Shouldn't be a fall through.
  assert(TBB && "insertBranch must not be told to insert a fallthrough");
  assert((Cond.size() == 2 || Cond.size() == 0) &&
         "PPC branch conditions have two components!");
  assert(!BytesAdded && "code size not handled");

  bool isPPC64 = Subtarget.isPPC64();

  // One-way branch.
  if (!FBB) {
    if (Cond.empty())   // Unconditional branch
      BuildMI(&MBB, DL, get(PPC::B)).addMBB(TBB);
    else if (Cond[1].getReg() == PPC::CTR || Cond[1].getReg() == PPC::CTR8)
      BuildMI(&MBB, DL, get(Cond[0].getImm() ?
                              (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :
                              (isPPC64 ? PPC::BDZ8  : PPC::BDZ))).addMBB(TBB);
    else if (Cond[0].getImm() == PPC::PRED_BIT_SET)
      BuildMI(&MBB, DL, get(PPC::BC)).add(Cond[1]).addMBB(TBB);
    else if (Cond[0].getImm() == PPC::PRED_BIT_UNSET)
      BuildMI(&MBB, DL, get(PPC::BCn)).add(Cond[1]).addMBB(TBB);
    else                // Conditional branch
      BuildMI(&MBB, DL, get(PPC::BCC))
          .addImm(Cond[0].getImm())
          .add(Cond[1])
          .addMBB(TBB);
    return 1;
  }

  // Two-way Conditional Branch.
  if (Cond[1].getReg() == PPC::CTR || Cond[1].getReg() == PPC::CTR8)
    BuildMI(&MBB, DL, get(Cond[0].getImm() ?
                            (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :
                            (isPPC64 ? PPC::BDZ8  : PPC::BDZ))).addMBB(TBB);
  else if (Cond[0].getImm() == PPC::PRED_BIT_SET)
    BuildMI(&MBB, DL, get(PPC::BC)).add(Cond[1]).addMBB(TBB);
  else if (Cond[0].getImm() == PPC::PRED_BIT_UNSET)
    BuildMI(&MBB, DL, get(PPC::BCn)).add(Cond[1]).addMBB(TBB);
  else
    BuildMI(&MBB, DL, get(PPC::BCC))
        .addImm(Cond[0].getImm())
        .add(Cond[1])
        .addMBB(TBB);
  BuildMI(&MBB, DL, get(PPC::B)).addMBB(FBB);
  return 2;
}

// Select analysis.
bool PPCInstrInfo::canInsertSelect(const MachineBasicBlock &MBB,
                                   ArrayRef<MachineOperand> Cond,
                                   Register DstReg, Register TrueReg,
                                   Register FalseReg, int &CondCycles,
                                   int &TrueCycles, int &FalseCycles) const {
  if (Cond.size() != 2)
    return false;

  // If this is really a bdnz-like condition, then it cannot be turned into a
  // select.
  if (Cond[1].getReg() == PPC::CTR || Cond[1].getReg() == PPC::CTR8)
    return false;

  // Check register classes.
  const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
  const TargetRegisterClass *RC =
    RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg));
  if (!RC)
    return false;

  // isel is for regular integer GPRs only.
  if (!PPC::GPRCRegClass.hasSubClassEq(RC) &&
      !PPC::GPRC_NOR0RegClass.hasSubClassEq(RC) &&
      !PPC::G8RCRegClass.hasSubClassEq(RC) &&
      !PPC::G8RC_NOX0RegClass.hasSubClassEq(RC))
    return false;

  // FIXME: These numbers are for the A2, how well they work for other cores is
  // an open question. On the A2, the isel instruction has a 2-cycle latency
  // but single-cycle throughput. These numbers are used in combination with
  // the MispredictPenalty setting from the active SchedMachineModel.
  CondCycles = 1;
  TrueCycles = 1;
  FalseCycles = 1;

  return true;
}

void PPCInstrInfo::insertSelect(MachineBasicBlock &MBB,
                                MachineBasicBlock::iterator MI,
                                const DebugLoc &dl, Register DestReg,
                                ArrayRef<MachineOperand> Cond, Register TrueReg,
                                Register FalseReg) const {
  assert(Cond.size() == 2 &&
         "PPC branch conditions have two components!");

  // Get the register classes.
  MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
  const TargetRegisterClass *RC =
    RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg));
  assert(RC && "TrueReg and FalseReg must have overlapping register classes");

  bool Is64Bit = PPC::G8RCRegClass.hasSubClassEq(RC) ||
                 PPC::G8RC_NOX0RegClass.hasSubClassEq(RC);
  assert((Is64Bit ||
          PPC::GPRCRegClass.hasSubClassEq(RC) ||
          PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) &&
         "isel is for regular integer GPRs only");

  unsigned OpCode = Is64Bit ? PPC::ISEL8 : PPC::ISEL;
  auto SelectPred = static_cast<PPC::Predicate>(Cond[0].getImm());

  unsigned SubIdx = 0;
  bool SwapOps = false;
  switch (SelectPred) {
  case PPC::PRED_EQ:
  case PPC::PRED_EQ_MINUS:
  case PPC::PRED_EQ_PLUS:
      SubIdx = PPC::sub_eq; SwapOps = false; break;
  case PPC::PRED_NE:
  case PPC::PRED_NE_MINUS:
  case PPC::PRED_NE_PLUS:
      SubIdx = PPC::sub_eq; SwapOps = true; break;
  case PPC::PRED_LT:
  case PPC::PRED_LT_MINUS:
  case PPC::PRED_LT_PLUS:
      SubIdx = PPC::sub_lt; SwapOps = false; break;
  case PPC::PRED_GE:
  case PPC::PRED_GE_MINUS:
  case PPC::PRED_GE_PLUS:
      SubIdx = PPC::sub_lt; SwapOps = true; break;
  case PPC::PRED_GT:
  case PPC::PRED_GT_MINUS:
  case PPC::PRED_GT_PLUS:
      SubIdx = PPC::sub_gt; SwapOps = false; break;
  case PPC::PRED_LE:
  case PPC::PRED_LE_MINUS:
  case PPC::PRED_LE_PLUS:
      SubIdx = PPC::sub_gt; SwapOps = true; break;
  case PPC::PRED_UN:
  case PPC::PRED_UN_MINUS:
  case PPC::PRED_UN_PLUS:
      SubIdx = PPC::sub_un; SwapOps = false; break;
  case PPC::PRED_NU:
  case PPC::PRED_NU_MINUS:
  case PPC::PRED_NU_PLUS:
      SubIdx = PPC::sub_un; SwapOps = true; break;
  case PPC::PRED_BIT_SET:   SubIdx = 0; SwapOps = false; break;
  case PPC::PRED_BIT_UNSET: SubIdx = 0; SwapOps = true; break;
  }

  Register FirstReg =  SwapOps ? FalseReg : TrueReg,
           SecondReg = SwapOps ? TrueReg  : FalseReg;

  // The first input register of isel cannot be r0. If it is a member
  // of a register class that can be r0, then copy it first (the
  // register allocator should eliminate the copy).
  if (MRI.getRegClass(FirstReg)->contains(PPC::R0) ||
      MRI.getRegClass(FirstReg)->contains(PPC::X0)) {
    const TargetRegisterClass *FirstRC =
      MRI.getRegClass(FirstReg)->contains(PPC::X0) ?
        &PPC::G8RC_NOX0RegClass : &PPC::GPRC_NOR0RegClass;
    Register OldFirstReg = FirstReg;
    FirstReg = MRI.createVirtualRegister(FirstRC);
    BuildMI(MBB, MI, dl, get(TargetOpcode::COPY), FirstReg)
      .addReg(OldFirstReg);
  }

  BuildMI(MBB, MI, dl, get(OpCode), DestReg)
    .addReg(FirstReg).addReg(SecondReg)
    .addReg(Cond[1].getReg(), 0, SubIdx);
}

static unsigned getCRBitValue(unsigned CRBit) {
  unsigned Ret = 4;
  if (CRBit == PPC::CR0LT || CRBit == PPC::CR1LT ||
      CRBit == PPC::CR2LT || CRBit == PPC::CR3LT ||
      CRBit == PPC::CR4LT || CRBit == PPC::CR5LT ||
      CRBit == PPC::CR6LT || CRBit == PPC::CR7LT)
    Ret = 3;
  if (CRBit == PPC::CR0GT || CRBit == PPC::CR1GT ||
      CRBit == PPC::CR2GT || CRBit == PPC::CR3GT ||
      CRBit == PPC::CR4GT || CRBit == PPC::CR5GT ||
      CRBit == PPC::CR6GT || CRBit == PPC::CR7GT)
    Ret = 2;
  if (CRBit == PPC::CR0EQ || CRBit == PPC::CR1EQ ||
      CRBit == PPC::CR2EQ || CRBit == PPC::CR3EQ ||
      CRBit == PPC::CR4EQ || CRBit == PPC::CR5EQ ||
      CRBit == PPC::CR6EQ || CRBit == PPC::CR7EQ)
    Ret = 1;
  if (CRBit == PPC::CR0UN || CRBit == PPC::CR1UN ||
      CRBit == PPC::CR2UN || CRBit == PPC::CR3UN ||
      CRBit == PPC::CR4UN || CRBit == PPC::CR5UN ||
      CRBit == PPC::CR6UN || CRBit == PPC::CR7UN)
    Ret = 0;

  assert(Ret != 4 && "Invalid CR bit register");
  return Ret;
}

void PPCInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
                               MachineBasicBlock::iterator I,
                               const DebugLoc &DL, MCRegister DestReg,
                               MCRegister SrcReg, bool KillSrc) const {
  // We can end up with self copies and similar things as a result of VSX copy
  // legalization. Promote them here.
  const TargetRegisterInfo *TRI = &getRegisterInfo();
  if (PPC::F8RCRegClass.contains(DestReg) &&
      PPC::VSRCRegClass.contains(SrcReg)) {
    MCRegister SuperReg =
        TRI->getMatchingSuperReg(DestReg, PPC::sub_64, &PPC::VSRCRegClass);

    if (VSXSelfCopyCrash && SrcReg == SuperReg)
      llvm_unreachable("nop VSX copy");

    DestReg = SuperReg;
  } else if (PPC::F8RCRegClass.contains(SrcReg) &&
             PPC::VSRCRegClass.contains(DestReg)) {
    MCRegister SuperReg =
        TRI->getMatchingSuperReg(SrcReg, PPC::sub_64, &PPC::VSRCRegClass);

    if (VSXSelfCopyCrash && DestReg == SuperReg)
      llvm_unreachable("nop VSX copy");

    SrcReg = SuperReg;
  }

  // Different class register copy
  if (PPC::CRBITRCRegClass.contains(SrcReg) &&
      PPC::GPRCRegClass.contains(DestReg)) {
    MCRegister CRReg = getCRFromCRBit(SrcReg);
    BuildMI(MBB, I, DL, get(PPC::MFOCRF), DestReg).addReg(CRReg);
    getKillRegState(KillSrc);
    // Rotate the CR bit in the CR fields to be the least significant bit and
    // then mask with 0x1 (MB = ME = 31).
    BuildMI(MBB, I, DL, get(PPC::RLWINM), DestReg)
       .addReg(DestReg, RegState::Kill)
       .addImm(TRI->getEncodingValue(CRReg) * 4 + (4 - getCRBitValue(SrcReg)))
       .addImm(31)
       .addImm(31);
    return;
  } else if (PPC::CRRCRegClass.contains(SrcReg) &&
             (PPC::G8RCRegClass.contains(DestReg) ||
              PPC::GPRCRegClass.contains(DestReg))) {
    bool Is64Bit = PPC::G8RCRegClass.contains(DestReg);
    unsigned MvCode = Is64Bit ? PPC::MFOCRF8 : PPC::MFOCRF;
    unsigned ShCode = Is64Bit ? PPC::RLWINM8 : PPC::RLWINM;
    unsigned CRNum = TRI->getEncodingValue(SrcReg);
    BuildMI(MBB, I, DL, get(MvCode), DestReg).addReg(SrcReg);
    getKillRegState(KillSrc);
    if (CRNum == 7)
      return;
    // Shift the CR bits to make the CR field in the lowest 4 bits of GRC.
    BuildMI(MBB, I, DL, get(ShCode), DestReg)
        .addReg(DestReg, RegState::Kill)
        .addImm(CRNum * 4 + 4)
        .addImm(28)
        .addImm(31);
    return;
  } else if (PPC::G8RCRegClass.contains(SrcReg) &&
             PPC::VSFRCRegClass.contains(DestReg)) {
    assert(Subtarget.hasDirectMove() &&
           "Subtarget doesn't support directmove, don't know how to copy.");
    BuildMI(MBB, I, DL, get(PPC::MTVSRD), DestReg).addReg(SrcReg);
    NumGPRtoVSRSpill++;
    getKillRegState(KillSrc);
    return;
  } else if (PPC::VSFRCRegClass.contains(SrcReg) &&
             PPC::G8RCRegClass.contains(DestReg)) {
    assert(Subtarget.hasDirectMove() &&
           "Subtarget doesn't support directmove, don't know how to copy.");
    BuildMI(MBB, I, DL, get(PPC::MFVSRD), DestReg).addReg(SrcReg);
    getKillRegState(KillSrc);
    return;
  } else if (PPC::SPERCRegClass.contains(SrcReg) &&
             PPC::GPRCRegClass.contains(DestReg)) {
    BuildMI(MBB, I, DL, get(PPC::EFSCFD), DestReg).addReg(SrcReg);
    getKillRegState(KillSrc);
    return;
  } else if (PPC::GPRCRegClass.contains(SrcReg) &&
             PPC::SPERCRegClass.contains(DestReg)) {
    BuildMI(MBB, I, DL, get(PPC::EFDCFS), DestReg).addReg(SrcReg);
    getKillRegState(KillSrc);
    return;
  }

  unsigned Opc;
  if (PPC::GPRCRegClass.contains(DestReg, SrcReg))
    Opc = PPC::OR;
  else if (PPC::G8RCRegClass.contains(DestReg, SrcReg))
    Opc = PPC::OR8;
  else if (PPC::F4RCRegClass.contains(DestReg, SrcReg))
    Opc = PPC::FMR;
  else if (PPC::CRRCRegClass.contains(DestReg, SrcReg))
    Opc = PPC::MCRF;
  else if (PPC::VRRCRegClass.contains(DestReg, SrcReg))
    Opc = PPC::VOR;
  else if (PPC::VSRCRegClass.contains(DestReg, SrcReg))
    // There are two different ways this can be done:
    //   1. xxlor : This has lower latency (on the P7), 2 cycles, but can only
    //      issue in VSU pipeline 0.
    //   2. xmovdp/xmovsp: This has higher latency (on the P7), 6 cycles, but
    //      can go to either pipeline.
    // We'll always use xxlor here, because in practically all cases where
    // copies are generated, they are close enough to some use that the
    // lower-latency form is preferable.
    Opc = PPC::XXLOR;
  else if (PPC::VSFRCRegClass.contains(DestReg, SrcReg) ||
           PPC::VSSRCRegClass.contains(DestReg, SrcReg))
    Opc = (Subtarget.hasP9Vector()) ? PPC::XSCPSGNDP : PPC::XXLORf;
  else if (Subtarget.pairedVectorMemops() &&
           PPC::VSRpRCRegClass.contains(DestReg, SrcReg)) {
    if (SrcReg > PPC::VSRp15)
      SrcReg = PPC::V0 + (SrcReg - PPC::VSRp16) * 2;
    else
      SrcReg = PPC::VSL0 + (SrcReg - PPC::VSRp0) * 2;
    if (DestReg > PPC::VSRp15)
      DestReg = PPC::V0 + (DestReg - PPC::VSRp16) * 2;
    else
      DestReg = PPC::VSL0 + (DestReg - PPC::VSRp0) * 2;
    BuildMI(MBB, I, DL, get(PPC::XXLOR), DestReg).
      addReg(SrcReg).addReg(SrcReg, getKillRegState(KillSrc));
    BuildMI(MBB, I, DL, get(PPC::XXLOR), DestReg + 1).
      addReg(SrcReg + 1).addReg(SrcReg + 1, getKillRegState(KillSrc));
    return;
  }
  else if (PPC::CRBITRCRegClass.contains(DestReg, SrcReg))
    Opc = PPC::CROR;
  else if (PPC::SPERCRegClass.contains(DestReg, SrcReg))
    Opc = PPC::EVOR;
  else if ((PPC::ACCRCRegClass.contains(DestReg) ||
            PPC::UACCRCRegClass.contains(DestReg)) &&
           (PPC::ACCRCRegClass.contains(SrcReg) ||
            PPC::UACCRCRegClass.contains(SrcReg))) {
    // If primed, de-prime the source register, copy the individual registers
    // and prime the destination if needed. The vector subregisters are
    // vs[(u)acc * 4] - vs[(u)acc * 4 + 3]. If the copy is not a kill and the
    // source is primed, we need to re-prime it after the copy as well.
    PPCRegisterInfo::emitAccCopyInfo(MBB, DestReg, SrcReg);
    bool DestPrimed = PPC::ACCRCRegClass.contains(DestReg);
    bool SrcPrimed = PPC::ACCRCRegClass.contains(SrcReg);
    MCRegister VSLSrcReg =
        PPC::VSL0 + (SrcReg - (SrcPrimed ? PPC::ACC0 : PPC::UACC0)) * 4;
    MCRegister VSLDestReg =
        PPC::VSL0 + (DestReg - (DestPrimed ? PPC::ACC0 : PPC::UACC0)) * 4;
    if (SrcPrimed)
      BuildMI(MBB, I, DL, get(PPC::XXMFACC), SrcReg).addReg(SrcReg);
    for (unsigned Idx = 0; Idx < 4; Idx++)
      BuildMI(MBB, I, DL, get(PPC::XXLOR), VSLDestReg + Idx)
          .addReg(VSLSrcReg + Idx)
          .addReg(VSLSrcReg + Idx, getKillRegState(KillSrc));
    if (DestPrimed)
      BuildMI(MBB, I, DL, get(PPC::XXMTACC), DestReg).addReg(DestReg);
    if (SrcPrimed && !KillSrc)
      BuildMI(MBB, I, DL, get(PPC::XXMTACC), SrcReg).addReg(SrcReg);
    return;
  } else
    llvm_unreachable("Impossible reg-to-reg copy");

  const MCInstrDesc &MCID = get(Opc);
  if (MCID.getNumOperands() == 3)
    BuildMI(MBB, I, DL, MCID, DestReg)
      .addReg(SrcReg).addReg(SrcReg, getKillRegState(KillSrc));
  else
    BuildMI(MBB, I, DL, MCID, DestReg).addReg(SrcReg, getKillRegState(KillSrc));
}

unsigned PPCInstrInfo::getSpillIndex(const TargetRegisterClass *RC) const {
  int OpcodeIndex = 0;

  if (PPC::GPRCRegClass.hasSubClassEq(RC) ||
      PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) {
    OpcodeIndex = SOK_Int4Spill;
  } else if (PPC::G8RCRegClass.hasSubClassEq(RC) ||
             PPC::G8RC_NOX0RegClass.hasSubClassEq(RC)) {
    OpcodeIndex = SOK_Int8Spill;
  } else if (PPC::F8RCRegClass.hasSubClassEq(RC)) {
    OpcodeIndex = SOK_Float8Spill;
  } else if (PPC::F4RCRegClass.hasSubClassEq(RC)) {
    OpcodeIndex = SOK_Float4Spill;
  } else if (PPC::SPERCRegClass.hasSubClassEq(RC)) {
    OpcodeIndex = SOK_SPESpill;
  } else if (PPC::CRRCRegClass.hasSubClassEq(RC)) {
    OpcodeIndex = SOK_CRSpill;
  } else if (PPC::CRBITRCRegClass.hasSubClassEq(RC)) {
    OpcodeIndex = SOK_CRBitSpill;
  } else if (PPC::VRRCRegClass.hasSubClassEq(RC)) {
    OpcodeIndex = SOK_VRVectorSpill;
  } else if (PPC::VSRCRegClass.hasSubClassEq(RC)) {
    OpcodeIndex = SOK_VSXVectorSpill;
  } else if (PPC::VSFRCRegClass.hasSubClassEq(RC)) {
    OpcodeIndex = SOK_VectorFloat8Spill;
  } else if (PPC::VSSRCRegClass.hasSubClassEq(RC)) {
    OpcodeIndex = SOK_VectorFloat4Spill;
  } else if (PPC::SPILLTOVSRRCRegClass.hasSubClassEq(RC)) {
    OpcodeIndex = SOK_SpillToVSR;
  } else if (PPC::ACCRCRegClass.hasSubClassEq(RC)) {
    assert(Subtarget.pairedVectorMemops() &&
           "Register unexpected when paired memops are disabled.");
    OpcodeIndex = SOK_AccumulatorSpill;
  } else if (PPC::UACCRCRegClass.hasSubClassEq(RC)) {
    assert(Subtarget.pairedVectorMemops() &&
           "Register unexpected when paired memops are disabled.");
    OpcodeIndex = SOK_UAccumulatorSpill;
  } else if (PPC::VSRpRCRegClass.hasSubClassEq(RC)) {
    assert(Subtarget.pairedVectorMemops() &&
           "Register unexpected when paired memops are disabled.");
    OpcodeIndex = SOK_PairedVecSpill;
  } else {
    llvm_unreachable("Unknown regclass!");
  }
  return OpcodeIndex;
}

unsigned
PPCInstrInfo::getStoreOpcodeForSpill(const TargetRegisterClass *RC) const {
  const unsigned *OpcodesForSpill = getStoreOpcodesForSpillArray();
  return OpcodesForSpill[getSpillIndex(RC)];
}

unsigned
PPCInstrInfo::getLoadOpcodeForSpill(const TargetRegisterClass *RC) const {
  const unsigned *OpcodesForSpill = getLoadOpcodesForSpillArray();
  return OpcodesForSpill[getSpillIndex(RC)];
}

void PPCInstrInfo::StoreRegToStackSlot(
    MachineFunction &MF, unsigned SrcReg, bool isKill, int FrameIdx,
    const TargetRegisterClass *RC,
    SmallVectorImpl<MachineInstr *> &NewMIs) const {
  unsigned Opcode = getStoreOpcodeForSpill(RC);
  DebugLoc DL;

  PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
  FuncInfo->setHasSpills();

  NewMIs.push_back(addFrameReference(
      BuildMI(MF, DL, get(Opcode)).addReg(SrcReg, getKillRegState(isKill)),
      FrameIdx));

  if (PPC::CRRCRegClass.hasSubClassEq(RC) ||
      PPC::CRBITRCRegClass.hasSubClassEq(RC))
    FuncInfo->setSpillsCR();

  if (isXFormMemOp(Opcode))
    FuncInfo->setHasNonRISpills();
}

void PPCInstrInfo::storeRegToStackSlotNoUpd(
    MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg,
    bool isKill, int FrameIdx, const TargetRegisterClass *RC,
    const TargetRegisterInfo *TRI) const {
  MachineFunction &MF = *MBB.getParent();
  SmallVector<MachineInstr *, 4> NewMIs;

  StoreRegToStackSlot(MF, SrcReg, isKill, FrameIdx, RC, NewMIs);

  for (unsigned i = 0, e = NewMIs.size(); i != e; ++i)
    MBB.insert(MI, NewMIs[i]);

  const MachineFrameInfo &MFI = MF.getFrameInfo();
  MachineMemOperand *MMO = MF.getMachineMemOperand(
      MachinePointerInfo::getFixedStack(MF, FrameIdx),
      MachineMemOperand::MOStore, MFI.getObjectSize(FrameIdx),
      MFI.getObjectAlign(FrameIdx));
  NewMIs.back()->addMemOperand(MF, MMO);
}

void PPCInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
                                       MachineBasicBlock::iterator MI,
                                       Register SrcReg, bool isKill,
                                       int FrameIdx,
                                       const TargetRegisterClass *RC,
                                       const TargetRegisterInfo *TRI) const {
  // We need to avoid a situation in which the value from a VRRC register is
  // spilled using an Altivec instruction and reloaded into a VSRC register
  // using a VSX instruction. The issue with this is that the VSX
  // load/store instructions swap the doublewords in the vector and the Altivec
  // ones don't. The register classes on the spill/reload may be different if
  // the register is defined using an Altivec instruction and is then used by a
  // VSX instruction.
  RC = updatedRC(RC);
  storeRegToStackSlotNoUpd(MBB, MI, SrcReg, isKill, FrameIdx, RC, TRI);
}

void PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, const DebugLoc &DL,
                                        unsigned DestReg, int FrameIdx,
                                        const TargetRegisterClass *RC,
                                        SmallVectorImpl<MachineInstr *> &NewMIs)
                                        const {
  unsigned Opcode = getLoadOpcodeForSpill(RC);
  NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(Opcode), DestReg),
                                     FrameIdx));
  PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();

  if (PPC::CRRCRegClass.hasSubClassEq(RC) ||
      PPC::CRBITRCRegClass.hasSubClassEq(RC))
    FuncInfo->setSpillsCR();

  if (isXFormMemOp(Opcode))
    FuncInfo->setHasNonRISpills();
}

void PPCInstrInfo::loadRegFromStackSlotNoUpd(
    MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg,
    int FrameIdx, const TargetRegisterClass *RC,
    const TargetRegisterInfo *TRI) const {
  MachineFunction &MF = *MBB.getParent();
  SmallVector<MachineInstr*, 4> NewMIs;
  DebugLoc DL;
  if (MI != MBB.end()) DL = MI->getDebugLoc();

  PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
  FuncInfo->setHasSpills();

  LoadRegFromStackSlot(MF, DL, DestReg, FrameIdx, RC, NewMIs);

  for (unsigned i = 0, e = NewMIs.size(); i != e; ++i)
    MBB.insert(MI, NewMIs[i]);

  const MachineFrameInfo &MFI = MF.getFrameInfo();
  MachineMemOperand *MMO = MF.getMachineMemOperand(
      MachinePointerInfo::getFixedStack(MF, FrameIdx),
      MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIdx),
      MFI.getObjectAlign(FrameIdx));
  NewMIs.back()->addMemOperand(MF, MMO);
}

void PPCInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
                                        MachineBasicBlock::iterator MI,
                                        Register DestReg, int FrameIdx,
                                        const TargetRegisterClass *RC,
                                        const TargetRegisterInfo *TRI) const {
  // We need to avoid a situation in which the value from a VRRC register is
  // spilled using an Altivec instruction and reloaded into a VSRC register
  // using a VSX instruction. The issue with this is that the VSX
  // load/store instructions swap the doublewords in the vector and the Altivec
  // ones don't. The register classes on the spill/reload may be different if
  // the register is defined using an Altivec instruction and is then used by a
  // VSX instruction.
  RC = updatedRC(RC);

  loadRegFromStackSlotNoUpd(MBB, MI, DestReg, FrameIdx, RC, TRI);
}

bool PPCInstrInfo::
reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
  assert(Cond.size() == 2 && "Invalid PPC branch opcode!");
  if (Cond[1].getReg() == PPC::CTR8 || Cond[1].getReg() == PPC::CTR)
    Cond[0].setImm(Cond[0].getImm() == 0 ? 1 : 0);
  else
    // Leave the CR# the same, but invert the condition.
    Cond[0].setImm(PPC::InvertPredicate((PPC::Predicate)Cond[0].getImm()));
  return false;
}

// For some instructions, it is legal to fold ZERO into the RA register field.
// This function performs that fold by replacing the operand with PPC::ZERO,
// it does not consider whether the load immediate zero is no longer in use.
bool PPCInstrInfo::onlyFoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
                                     Register Reg) const {
  // A zero immediate should always be loaded with a single li.
  unsigned DefOpc = DefMI.getOpcode();
  if (DefOpc != PPC::LI && DefOpc != PPC::LI8)
    return false;
  if (!DefMI.getOperand(1).isImm())
    return false;
  if (DefMI.getOperand(1).getImm() != 0)
    return false;

  // Note that we cannot here invert the arguments of an isel in order to fold
  // a ZERO into what is presented as the second argument. All we have here
  // is the condition bit, and that might come from a CR-logical bit operation.

  const MCInstrDesc &UseMCID = UseMI.getDesc();

  // Only fold into real machine instructions.
  if (UseMCID.isPseudo())
    return false;

  // We need to find which of the User's operands is to be folded, that will be
  // the operand that matches the given register ID.
  unsigned UseIdx;
  for (UseIdx = 0; UseIdx < UseMI.getNumOperands(); ++UseIdx)
    if (UseMI.getOperand(UseIdx).isReg() &&
        UseMI.getOperand(UseIdx).getReg() == Reg)
      break;

  assert(UseIdx < UseMI.getNumOperands() && "Cannot find Reg in UseMI");
  assert(UseIdx < UseMCID.getNumOperands() && "No operand description for Reg");

  const MCOperandInfo *UseInfo = &UseMCID.OpInfo[UseIdx];

  // We can fold the zero if this register requires a GPRC_NOR0/G8RC_NOX0
  // register (which might also be specified as a pointer class kind).
  if (UseInfo->isLookupPtrRegClass()) {
    if (UseInfo->RegClass /* Kind */ != 1)
      return false;
  } else {
    if (UseInfo->RegClass != PPC::GPRC_NOR0RegClassID &&
        UseInfo->RegClass != PPC::G8RC_NOX0RegClassID)
      return false;
  }

  // Make sure this is not tied to an output register (or otherwise
  // constrained). This is true for ST?UX registers, for example, which
  // are tied to their output registers.
  if (UseInfo->Constraints != 0)
    return false;

  MCRegister ZeroReg;
  if (UseInfo->isLookupPtrRegClass()) {
    bool isPPC64 = Subtarget.isPPC64();
    ZeroReg = isPPC64 ? PPC::ZERO8 : PPC::ZERO;
  } else {
    ZeroReg = UseInfo->RegClass == PPC::G8RC_NOX0RegClassID ?
              PPC::ZERO8 : PPC::ZERO;
  }

  UseMI.getOperand(UseIdx).setReg(ZeroReg);
  return true;
}

// Folds zero into instructions which have a load immediate zero as an operand
// but also recognize zero as immediate zero. If the definition of the load
// has no more users it is deleted.
bool PPCInstrInfo::FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
                                 Register Reg, MachineRegisterInfo *MRI) const {
  bool Changed = onlyFoldImmediate(UseMI, DefMI, Reg);
  if (MRI->use_nodbg_empty(Reg))
    DefMI.eraseFromParent();
  return Changed;
}

static bool MBBDefinesCTR(MachineBasicBlock &MBB) {
  for (MachineBasicBlock::iterator I = MBB.begin(), IE = MBB.end();
       I != IE; ++I)
    if (I->definesRegister(PPC::CTR) || I->definesRegister(PPC::CTR8))
      return true;
  return false;
}

// We should make sure that, if we're going to predicate both sides of a
// condition (a diamond), that both sides don't define the counter register. We
// can predicate counter-decrement-based branches, but while that predicates
// the branching, it does not predicate the counter decrement. If we tried to
// merge the triangle into one predicated block, we'd decrement the counter
// twice.
bool PPCInstrInfo::isProfitableToIfCvt(MachineBasicBlock &TMBB,
                     unsigned NumT, unsigned ExtraT,
                     MachineBasicBlock &FMBB,
                     unsigned NumF, unsigned ExtraF,
                     BranchProbability Probability) const {
  return !(MBBDefinesCTR(TMBB) && MBBDefinesCTR(FMBB));
}


bool PPCInstrInfo::isPredicated(const MachineInstr &MI) const {
  // The predicated branches are identified by their type, not really by the
  // explicit presence of a predicate. Furthermore, some of them can be
  // predicated more than once. Because if conversion won't try to predicate
  // any instruction which already claims to be predicated (by returning true
  // here), always return false. In doing so, we let isPredicable() be the
  // final word on whether not the instruction can be (further) predicated.

  return false;
}

bool PPCInstrInfo::isSchedulingBoundary(const MachineInstr &MI,
                                        const MachineBasicBlock *MBB,
                                        const MachineFunction &MF) const {
  // Set MFFS and MTFSF as scheduling boundary to avoid unexpected code motion
  // across them, since some FP operations may change content of FPSCR.
  // TODO: Model FPSCR in PPC instruction definitions and remove the workaround
  if (MI.getOpcode() == PPC::MFFS || MI.getOpcode() == PPC::MTFSF)
    return true;
  return TargetInstrInfo::isSchedulingBoundary(MI, MBB, MF);
}

bool PPCInstrInfo::PredicateInstruction(MachineInstr &MI,
                                        ArrayRef<MachineOperand> Pred) const {
  unsigned OpC = MI.getOpcode();
  if (OpC == PPC::BLR || OpC == PPC::BLR8) {
    if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) {
      bool isPPC64 = Subtarget.isPPC64();
      MI.setDesc(get(Pred[0].getImm() ? (isPPC64 ? PPC::BDNZLR8 : PPC::BDNZLR)
                                      : (isPPC64 ? PPC::BDZLR8 : PPC::BDZLR)));
      // Need add Def and Use for CTR implicit operand.
      MachineInstrBuilder(*MI.getParent()->getParent(), MI)
          .addReg(Pred[1].getReg(), RegState::Implicit)
          .addReg(Pred[1].getReg(), RegState::ImplicitDefine);
    } else if (Pred[0].getImm() == PPC::PRED_BIT_SET) {
      MI.setDesc(get(PPC::BCLR));
      MachineInstrBuilder(*MI.getParent()->getParent(), MI).add(Pred[1]);
    } else if (Pred[0].getImm() == PPC::PRED_BIT_UNSET) {
      MI.setDesc(get(PPC::BCLRn));
      MachineInstrBuilder(*MI.getParent()->getParent(), MI).add(Pred[1]);
    } else {
      MI.setDesc(get(PPC::BCCLR));
      MachineInstrBuilder(*MI.getParent()->getParent(), MI)
          .addImm(Pred[0].getImm())
          .add(Pred[1]);
    }

    return true;
  } else if (OpC == PPC::B) {
    if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) {
      bool isPPC64 = Subtarget.isPPC64();
      MI.setDesc(get(Pred[0].getImm() ? (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ)
                                      : (isPPC64 ? PPC::BDZ8 : PPC::BDZ)));
      // Need add Def and Use for CTR implicit operand.
      MachineInstrBuilder(*MI.getParent()->getParent(), MI)
          .addReg(Pred[1].getReg(), RegState::Implicit)
          .addReg(Pred[1].getReg(), RegState::ImplicitDefine);
    } else if (Pred[0].getImm() == PPC::PRED_BIT_SET) {
      MachineBasicBlock *MBB = MI.getOperand(0).getMBB();
      MI.RemoveOperand(0);

      MI.setDesc(get(PPC::BC));
      MachineInstrBuilder(*MI.getParent()->getParent(), MI)
          .add(Pred[1])
          .addMBB(MBB);
    } else if (Pred[0].getImm() == PPC::PRED_BIT_UNSET) {
      MachineBasicBlock *MBB = MI.getOperand(0).getMBB();
      MI.RemoveOperand(0);

      MI.setDesc(get(PPC::BCn));
      MachineInstrBuilder(*MI.getParent()->getParent(), MI)
          .add(Pred[1])
          .addMBB(MBB);
    } else {
      MachineBasicBlock *MBB = MI.getOperand(0).getMBB();
      MI.RemoveOperand(0);

      MI.setDesc(get(PPC::BCC));
      MachineInstrBuilder(*MI.getParent()->getParent(), MI)
          .addImm(Pred[0].getImm())
          .add(Pred[1])
          .addMBB(MBB);
    }

    return true;
  } else if (OpC == PPC::BCTR || OpC == PPC::BCTR8 || OpC == PPC::BCTRL ||
             OpC == PPC::BCTRL8) {
    if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR)
      llvm_unreachable("Cannot predicate bctr[l] on the ctr register");

    bool setLR = OpC == PPC::BCTRL || OpC == PPC::BCTRL8;
    bool isPPC64 = Subtarget.isPPC64();

    if (Pred[0].getImm() == PPC::PRED_BIT_SET) {
      MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCTRL8 : PPC::BCCTR8)
                             : (setLR ? PPC::BCCTRL : PPC::BCCTR)));
      MachineInstrBuilder(*MI.getParent()->getParent(), MI).add(Pred[1]);
    } else if (Pred[0].getImm() == PPC::PRED_BIT_UNSET) {
      MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCTRL8n : PPC::BCCTR8n)
                             : (setLR ? PPC::BCCTRLn : PPC::BCCTRn)));
      MachineInstrBuilder(*MI.getParent()->getParent(), MI).add(Pred[1]);
    } else {
      MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCCTRL8 : PPC::BCCCTR8)
                             : (setLR ? PPC::BCCCTRL : PPC::BCCCTR)));
      MachineInstrBuilder(*MI.getParent()->getParent(), MI)
          .addImm(Pred[0].getImm())
          .add(Pred[1]);
    }

    // Need add Def and Use for LR implicit operand.
    if (setLR)
      MachineInstrBuilder(*MI.getParent()->getParent(), MI)
          .addReg(isPPC64 ? PPC::LR8 : PPC::LR, RegState::Implicit)
          .addReg(isPPC64 ? PPC::LR8 : PPC::LR, RegState::ImplicitDefine);

    return true;
  }

  return false;
}

bool PPCInstrInfo::SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
                                     ArrayRef<MachineOperand> Pred2) const {
  assert(Pred1.size() == 2 && "Invalid PPC first predicate");
  assert(Pred2.size() == 2 && "Invalid PPC second predicate");

  if (Pred1[1].getReg() == PPC::CTR8 || Pred1[1].getReg() == PPC::CTR)
    return false;
  if (Pred2[1].getReg() == PPC::CTR8 || Pred2[1].getReg() == PPC::CTR)
    return false;

  // P1 can only subsume P2 if they test the same condition register.
  if (Pred1[1].getReg() != Pred2[1].getReg())
    return false;

  PPC::Predicate P1 = (PPC::Predicate) Pred1[0].getImm();
  PPC::Predicate P2 = (PPC::Predicate) Pred2[0].getImm();

  if (P1 == P2)
    return true;

  // Does P1 subsume P2, e.g. GE subsumes GT.
  if (P1 == PPC::PRED_LE &&
      (P2 == PPC::PRED_LT || P2 == PPC::PRED_EQ))
    return true;
  if (P1 == PPC::PRED_GE &&
      (P2 == PPC::PRED_GT || P2 == PPC::PRED_EQ))
    return true;

  return false;
}

bool PPCInstrInfo::ClobbersPredicate(MachineInstr &MI,
                                     std::vector<MachineOperand> &Pred,
                                     bool SkipDead) const {
  // Note: At the present time, the contents of Pred from this function is
  // unused by IfConversion. This implementation follows ARM by pushing the
  // CR-defining operand. Because the 'DZ' and 'DNZ' count as types of
  // predicate, instructions defining CTR or CTR8 are also included as
  // predicate-defining instructions.

  const TargetRegisterClass *RCs[] =
    { &PPC::CRRCRegClass, &PPC::CRBITRCRegClass,
      &PPC::CTRRCRegClass, &PPC::CTRRC8RegClass };

  bool Found = false;
  for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
    const MachineOperand &MO = MI.getOperand(i);
    for (unsigned c = 0; c < array_lengthof(RCs) && !Found; ++c) {
      const TargetRegisterClass *RC = RCs[c];
      if (MO.isReg()) {
        if (MO.isDef() && RC->contains(MO.getReg())) {
          Pred.push_back(MO);
          Found = true;
        }
      } else if (MO.isRegMask()) {
        for (TargetRegisterClass::iterator I = RC->begin(),
             IE = RC->end(); I != IE; ++I)
          if (MO.clobbersPhysReg(*I)) {
            Pred.push_back(MO);
            Found = true;
          }
      }
    }
  }

  return Found;
}

bool PPCInstrInfo::analyzeCompare(const MachineInstr &MI, Register &SrcReg,
                                  Register &SrcReg2, int &Mask,
                                  int &Value) const {
  unsigned Opc = MI.getOpcode();

  switch (Opc) {
  default: return false;
  case PPC::CMPWI:
  case PPC::CMPLWI:
  case PPC::CMPDI:
  case PPC::CMPLDI:
    SrcReg = MI.getOperand(1).getReg();
    SrcReg2 = 0;
    Value = MI.getOperand(2).getImm();
    Mask = 0xFFFF;
    return true;
  case PPC::CMPW:
  case PPC::CMPLW:
  case PPC::CMPD:
  case PPC::CMPLD:
  case PPC::FCMPUS:
  case PPC::FCMPUD:
    SrcReg = MI.getOperand(1).getReg();
    SrcReg2 = MI.getOperand(2).getReg();
    Value = 0;
    Mask = 0;
    return true;
  }
}

bool PPCInstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg,
                                        Register SrcReg2, int Mask, int Value,
                                        const MachineRegisterInfo *MRI) const {
  if (DisableCmpOpt)
    return false;

  int OpC = CmpInstr.getOpcode();
  Register CRReg = CmpInstr.getOperand(0).getReg();

  // FP record forms set CR1 based on the exception status bits, not a
  // comparison with zero.
  if (OpC == PPC::FCMPUS || OpC == PPC::FCMPUD)
    return false;

  const TargetRegisterInfo *TRI = &getRegisterInfo();
  // The record forms set the condition register based on a signed comparison
  // with zero (so says the ISA manual). This is not as straightforward as it
  // seems, however, because this is always a 64-bit comparison on PPC64, even
  // for instructions that are 32-bit in nature (like slw for example).
  // So, on PPC32, for unsigned comparisons, we can use the record forms only
  // for equality checks (as those don't depend on the sign). On PPC64,
  // we are restricted to equality for unsigned 64-bit comparisons and for
  // signed 32-bit comparisons the applicability is more restricted.
  bool isPPC64 = Subtarget.isPPC64();
  bool is32BitSignedCompare   = OpC ==  PPC::CMPWI || OpC == PPC::CMPW;
  bool is32BitUnsignedCompare = OpC == PPC::CMPLWI || OpC == PPC::CMPLW;
  bool is64BitUnsignedCompare = OpC == PPC::CMPLDI || OpC == PPC::CMPLD;

  // Look through copies unless that gets us to a physical register.
  Register ActualSrc = TRI->lookThruCopyLike(SrcReg, MRI);
  if (ActualSrc.isVirtual())
    SrcReg = ActualSrc;

  // Get the unique definition of SrcReg.
  MachineInstr *MI = MRI->getUniqueVRegDef(SrcReg);
  if (!MI) return false;

  bool equalityOnly = false;
  bool noSub = false;
  if (isPPC64) {
    if (is32BitSignedCompare) {
      // We can perform this optimization only if MI is sign-extending.
      if (isSignExtended(*MI))
        noSub = true;
      else
        return false;
    } else if (is32BitUnsignedCompare) {
      // We can perform this optimization, equality only, if MI is
      // zero-extending.
      if (isZeroExtended(*MI)) {
        noSub = true;
        equalityOnly = true;
      } else
        return false;
    } else
      equalityOnly = is64BitUnsignedCompare;
  } else
    equalityOnly = is32BitUnsignedCompare;

  if (equalityOnly) {
    // We need to check the uses of the condition register in order to reject
    // non-equality comparisons.
    for (MachineRegisterInfo::use_instr_iterator
         I = MRI->use_instr_begin(CRReg), IE = MRI->use_instr_end();
         I != IE; ++I) {
      MachineInstr *UseMI = &*I;
      if (UseMI->getOpcode() == PPC::BCC) {
        PPC::Predicate Pred = (PPC::Predicate)UseMI->getOperand(0).getImm();
        unsigned PredCond = PPC::getPredicateCondition(Pred);
        // We ignore hint bits when checking for non-equality comparisons.
        if (PredCond != PPC::PRED_EQ && PredCond != PPC::PRED_NE)
          return false;
      } else if (UseMI->getOpcode() == PPC::ISEL ||
                 UseMI->getOpcode() == PPC::ISEL8) {
        unsigned SubIdx = UseMI->getOperand(3).getSubReg();
        if (SubIdx != PPC::sub_eq)
          return false;
      } else
        return false;
    }
  }

  MachineBasicBlock::iterator I = CmpInstr;

  // Scan forward to find the first use of the compare.
  for (MachineBasicBlock::iterator EL = CmpInstr.getParent()->end(); I != EL;
       ++I) {
    bool FoundUse = false;
    for (MachineRegisterInfo::use_instr_iterator
         J = MRI->use_instr_begin(CRReg), JE = MRI->use_instr_end();
         J != JE; ++J)
      if (&*J == &*I) {
        FoundUse = true;
        break;
      }

    if (FoundUse)
      break;
  }

  SmallVector<std::pair<MachineOperand*, PPC::Predicate>, 4> PredsToUpdate;
  SmallVector<std::pair<MachineOperand*, unsigned>, 4> SubRegsToUpdate;

  // There are two possible candidates which can be changed to set CR[01].
  // One is MI, the other is a SUB instruction.
  // For CMPrr(r1,r2), we are looking for SUB(r1,r2) or SUB(r2,r1).
  MachineInstr *Sub = nullptr;
  if (SrcReg2 != 0)
    // MI is not a candidate for CMPrr.
    MI = nullptr;
  // FIXME: Conservatively refuse to convert an instruction which isn't in the
  // same BB as the comparison. This is to allow the check below to avoid calls
  // (and other explicit clobbers); instead we should really check for these
  // more explicitly (in at least a few predecessors).
  else if (MI->getParent() != CmpInstr.getParent())
    return false;
  else if (Value != 0) {
    // The record-form instructions set CR bit based on signed comparison
    // against 0. We try to convert a compare against 1 or -1 into a compare
    // against 0 to exploit record-form instructions. For example, we change
    // the condition "greater than -1" into "greater than or equal to 0"
    // and "less than 1" into "less than or equal to 0".

    // Since we optimize comparison based on a specific branch condition,
    // we don't optimize if condition code is used by more than once.
    if (equalityOnly || !MRI->hasOneUse(CRReg))
      return false;

    MachineInstr *UseMI = &*MRI->use_instr_begin(CRReg);
    if (UseMI->getOpcode() != PPC::BCC)
      return false;

    PPC::Predicate Pred = (PPC::Predicate)UseMI->getOperand(0).getImm();
    unsigned PredCond = PPC::getPredicateCondition(Pred);
    unsigned PredHint = PPC::getPredicateHint(Pred);
    int16_t Immed = (int16_t)Value;

    // When modifying the condition in the predicate, we propagate hint bits
    // from the original predicate to the new one.
    if (Immed == -1 && PredCond == PPC::PRED_GT)
      // We convert "greater than -1" into "greater than or equal to 0",
      // since we are assuming signed comparison by !equalityOnly
      Pred = PPC::getPredicate(PPC::PRED_GE, PredHint);
    else if (Immed == -1 && PredCond == PPC::PRED_LE)
      // We convert "less than or equal to -1" into "less than 0".
      Pred = PPC::getPredicate(PPC::PRED_LT, PredHint);
    else if (Immed == 1 && PredCond == PPC::PRED_LT)
      // We convert "less than 1" into "less than or equal to 0".
      Pred = PPC::getPredicate(PPC::PRED_LE, PredHint);
    else if (Immed == 1 && PredCond == PPC::PRED_GE)
      // We convert "greater than or equal to 1" into "greater than 0".
      Pred = PPC::getPredicate(PPC::PRED_GT, PredHint);
    else
      return false;

    PredsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(0)), Pred));
  }

  // Search for Sub.
  --I;

  // Get ready to iterate backward from CmpInstr.
  MachineBasicBlock::iterator E = MI, B = CmpInstr.getParent()->begin();

  for (; I != E && !noSub; --I) {
    const MachineInstr &Instr = *I;
    unsigned IOpC = Instr.getOpcode();

    if (&*I != &CmpInstr && (Instr.modifiesRegister(PPC::CR0, TRI) ||
                             Instr.readsRegister(PPC::CR0, TRI)))
      // This instruction modifies or uses the record condition register after
      // the one we want to change. While we could do this transformation, it
      // would likely not be profitable. This transformation removes one
      // instruction, and so even forcing RA to generate one move probably
      // makes it unprofitable.
      return false;

    // Check whether CmpInstr can be made redundant by the current instruction.
    if ((OpC == PPC::CMPW || OpC == PPC::CMPLW ||
         OpC == PPC::CMPD || OpC == PPC::CMPLD) &&
        (IOpC == PPC::SUBF || IOpC == PPC::SUBF8) &&
        ((Instr.getOperand(1).getReg() == SrcReg &&
          Instr.getOperand(2).getReg() == SrcReg2) ||
        (Instr.getOperand(1).getReg() == SrcReg2 &&
         Instr.getOperand(2).getReg() == SrcReg))) {
      Sub = &*I;
      break;
    }

    if (I == B)
      // The 'and' is below the comparison instruction.
      return false;
  }

  // Return false if no candidates exist.
  if (!MI && !Sub)
    return false;

  // The single candidate is called MI.
  if (!MI) MI = Sub;

  int NewOpC = -1;
  int MIOpC = MI->getOpcode();
  if (MIOpC == PPC::ANDI_rec || MIOpC == PPC::ANDI8_rec ||
      MIOpC == PPC::ANDIS_rec || MIOpC == PPC::ANDIS8_rec)
    NewOpC = MIOpC;
  else {
    NewOpC = PPC::getRecordFormOpcode(MIOpC);
    if (NewOpC == -1 && PPC::getNonRecordFormOpcode(MIOpC) != -1)
      NewOpC = MIOpC;
  }

  // FIXME: On the non-embedded POWER architectures, only some of the record
  // forms are fast, and we should use only the fast ones.

  // The defining instruction has a record form (or is already a record
  // form). It is possible, however, that we'll need to reverse the condition
  // code of the users.
  if (NewOpC == -1)
    return false;

  // This transformation should not be performed if `nsw` is missing and is not
  // `equalityOnly` comparison. Since if there is overflow, sub_lt, sub_gt in
  // CRReg do not reflect correct order. If `equalityOnly` is true, sub_eq in
  // CRReg can reflect if compared values are equal, this optz is still valid.
  if (!equalityOnly && (NewOpC == PPC::SUBF_rec || NewOpC == PPC::SUBF8_rec) &&
      Sub && !Sub->getFlag(MachineInstr::NoSWrap))
    return false;

  // If we have SUB(r1, r2) and CMP(r2, r1), the condition code based on CMP
  // needs to be updated to be based on SUB.  Push the condition code
  // operands to OperandsToUpdate.  If it is safe to remove CmpInstr, the
  // condition code of these operands will be modified.
  // Here, Value == 0 means we haven't converted comparison against 1 or -1 to
  // comparison against 0, which may modify predicate.
  bool ShouldSwap = false;
  if (Sub && Value == 0) {
    ShouldSwap = SrcReg2 != 0 && Sub->getOperand(1).getReg() == SrcReg2 &&
      Sub->getOperand(2).getReg() == SrcReg;

    // The operands to subf are the opposite of sub, so only in the fixed-point
    // case, invert the order.
    ShouldSwap = !ShouldSwap;
  }

  if (ShouldSwap)
    for (MachineRegisterInfo::use_instr_iterator
         I = MRI->use_instr_begin(CRReg), IE = MRI->use_instr_end();
         I != IE; ++I) {
      MachineInstr *UseMI = &*I;
      if (UseMI->getOpcode() == PPC::BCC) {
        PPC::Predicate Pred = (PPC::Predicate) UseMI->getOperand(0).getImm();
        unsigned PredCond = PPC::getPredicateCondition(Pred);
        assert((!equalityOnly ||
                PredCond == PPC::PRED_EQ || PredCond == PPC::PRED_NE) &&
               "Invalid predicate for equality-only optimization");
        (void)PredCond; // To suppress warning in release build.
        PredsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(0)),
                                PPC::getSwappedPredicate(Pred)));
      } else if (UseMI->getOpcode() == PPC::ISEL ||
                 UseMI->getOpcode() == PPC::ISEL8) {
        unsigned NewSubReg = UseMI->getOperand(3).getSubReg();
        assert((!equalityOnly || NewSubReg == PPC::sub_eq) &&
               "Invalid CR bit for equality-only optimization");

        if (NewSubReg == PPC::sub_lt)
          NewSubReg = PPC::sub_gt;
        else if (NewSubReg == PPC::sub_gt)
          NewSubReg = PPC::sub_lt;

        SubRegsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(3)),
                                                 NewSubReg));
      } else // We need to abort on a user we don't understand.
        return false;
    }
  assert(!(Value != 0 && ShouldSwap) &&
         "Non-zero immediate support and ShouldSwap"
         "may conflict in updating predicate");

  // Create a new virtual register to hold the value of the CR set by the
  // record-form instruction. If the instruction was not previously in
  // record form, then set the kill flag on the CR.
  CmpInstr.eraseFromParent();

  MachineBasicBlock::iterator MII = MI;
  BuildMI(*MI->getParent(), std::next(MII), MI->getDebugLoc(),
          get(TargetOpcode::COPY), CRReg)
    .addReg(PPC::CR0, MIOpC != NewOpC ? RegState::Kill : 0);

  // Even if CR0 register were dead before, it is alive now since the
  // instruction we just built uses it.
  MI->clearRegisterDeads(PPC::CR0);

  if (MIOpC != NewOpC) {
    // We need to be careful here: we're replacing one instruction with
    // another, and we need to make sure that we get all of the right
    // implicit uses and defs. On the other hand, the caller may be holding
    // an iterator to this instruction, and so we can't delete it (this is
    // specifically the case if this is the instruction directly after the
    // compare).

    // Rotates are expensive instructions. If we're emitting a record-form
    // rotate that can just be an andi/andis, we should just emit that.
    if (MIOpC == PPC::RLWINM || MIOpC == PPC::RLWINM8) {
      Register GPRRes = MI->getOperand(0).getReg();
      int64_t SH = MI->getOperand(2).getImm();
      int64_t MB = MI->getOperand(3).getImm();
      int64_t ME = MI->getOperand(4).getImm();
      // We can only do this if both the start and end of the mask are in the
      // same halfword.
      bool MBInLoHWord = MB >= 16;
      bool MEInLoHWord = ME >= 16;
      uint64_t Mask = ~0LLU;

      if (MB <= ME && MBInLoHWord == MEInLoHWord && SH == 0) {
        Mask = ((1LLU << (32 - MB)) - 1) & ~((1LLU << (31 - ME)) - 1);
        // The mask value needs to shift right 16 if we're emitting andis.
        Mask >>= MBInLoHWord ? 0 : 16;
        NewOpC = MIOpC == PPC::RLWINM
                     ? (MBInLoHWord ? PPC::ANDI_rec : PPC::ANDIS_rec)
                     : (MBInLoHWord ? PPC::ANDI8_rec : PPC::ANDIS8_rec);
      } else if (MRI->use_empty(GPRRes) && (ME == 31) &&
                 (ME - MB + 1 == SH) && (MB >= 16)) {
        // If we are rotating by the exact number of bits as are in the mask
        // and the mask is in the least significant bits of the register,
        // that's just an andis. (as long as the GPR result has no uses).
        Mask = ((1LLU << 32) - 1) & ~((1LLU << (32 - SH)) - 1);
        Mask >>= 16;
        NewOpC = MIOpC == PPC::RLWINM ? PPC::ANDIS_rec : PPC::ANDIS8_rec;
      }
      // If we've set the mask, we can transform.
      if (Mask != ~0LLU) {
        MI->RemoveOperand(4);
        MI->RemoveOperand(3);
        MI->getOperand(2).setImm(Mask);
        NumRcRotatesConvertedToRcAnd++;
      }
    } else if (MIOpC == PPC::RLDICL && MI->getOperand(2).getImm() == 0) {
      int64_t MB = MI->getOperand(3).getImm();
      if (MB >= 48) {
        uint64_t Mask = (1LLU << (63 - MB + 1)) - 1;
        NewOpC = PPC::ANDI8_rec;
        MI->RemoveOperand(3);
        MI->getOperand(2).setImm(Mask);
        NumRcRotatesConvertedToRcAnd++;
      }
    }

    const MCInstrDesc &NewDesc = get(NewOpC);
    MI->setDesc(NewDesc);

    if (NewDesc.ImplicitDefs)
      for (const MCPhysReg *ImpDefs = NewDesc.getImplicitDefs();
           *ImpDefs; ++ImpDefs)
        if (!MI->definesRegister(*ImpDefs))
          MI->addOperand(*MI->getParent()->getParent(),
                         MachineOperand::CreateReg(*ImpDefs, true, true));
    if (NewDesc.ImplicitUses)
      for (const MCPhysReg *ImpUses = NewDesc.getImplicitUses();
           *ImpUses; ++ImpUses)
        if (!MI->readsRegister(*ImpUses))
          MI->addOperand(*MI->getParent()->getParent(),
                         MachineOperand::CreateReg(*ImpUses, false, true));
  }
  assert(MI->definesRegister(PPC::CR0) &&
         "Record-form instruction does not define cr0?");

  // Modify the condition code of operands in OperandsToUpdate.
  // Since we have SUB(r1, r2) and CMP(r2, r1), the condition code needs to
  // be changed from r2 > r1 to r1 < r2, from r2 < r1 to r1 > r2, etc.
  for (unsigned i = 0, e = PredsToUpdate.size(); i < e; i++)
    PredsToUpdate[i].first->setImm(PredsToUpdate[i].second);

  for (unsigned i = 0, e = SubRegsToUpdate.size(); i < e; i++)
    SubRegsToUpdate[i].first->setSubReg(SubRegsToUpdate[i].second);

  return true;
}

bool PPCInstrInfo::getMemOperandsWithOffsetWidth(
    const MachineInstr &LdSt, SmallVectorImpl<const MachineOperand *> &BaseOps,
    int64_t &Offset, bool &OffsetIsScalable, unsigned &Width,
    const TargetRegisterInfo *TRI) const {
  const MachineOperand *BaseOp;
  OffsetIsScalable = false;
  if (!getMemOperandWithOffsetWidth(LdSt, BaseOp, Offset, Width, TRI))
    return false;
  BaseOps.push_back(BaseOp);
  return true;
}

static bool isLdStSafeToCluster(const MachineInstr &LdSt,
                                const TargetRegisterInfo *TRI) {
  // If this is a volatile load/store, don't mess with it.
  if (LdSt.hasOrderedMemoryRef() || LdSt.getNumExplicitOperands() != 3)
    return false;

  if (LdSt.getOperand(2).isFI())
    return true;

  assert(LdSt.getOperand(2).isReg() && "Expected a reg operand.");
  // Can't cluster if the instruction modifies the base register
  // or it is update form. e.g. ld r2,3(r2)
  if (LdSt.modifiesRegister(LdSt.getOperand(2).getReg(), TRI))
    return false;

  return true;
}

// Only cluster instruction pair that have the same opcode, and they are
// clusterable according to PowerPC specification.
static bool isClusterableLdStOpcPair(unsigned FirstOpc, unsigned SecondOpc,
                                     const PPCSubtarget &Subtarget) {
  switch (FirstOpc) {
  default:
    return false;
  case PPC::STD:
  case PPC::STFD:
  case PPC::STXSD:
  case PPC::DFSTOREf64:
    return FirstOpc == SecondOpc;
  // PowerPC backend has opcode STW/STW8 for instruction "stw" to deal with
  // 32bit and 64bit instruction selection. They are clusterable pair though
  // they are different opcode.
  case PPC::STW:
  case PPC::STW8:
    return SecondOpc == PPC::STW || SecondOpc == PPC::STW8;
  }
}

bool PPCInstrInfo::shouldClusterMemOps(
    ArrayRef<const MachineOperand *> BaseOps1,
    ArrayRef<const MachineOperand *> BaseOps2, unsigned NumLoads,
    unsigned NumBytes) const {

  assert(BaseOps1.size() == 1 && BaseOps2.size() == 1);
  const MachineOperand &BaseOp1 = *BaseOps1.front();
  const MachineOperand &BaseOp2 = *BaseOps2.front();
  assert((BaseOp1.isReg() || BaseOp1.isFI()) &&
         "Only base registers and frame indices are supported.");

  // The NumLoads means the number of loads that has been clustered.
  // Don't cluster memory op if there are already two ops clustered at least.
  if (NumLoads > 2)
    return false;

  // Cluster the load/store only when they have the same base
  // register or FI.
  if ((BaseOp1.isReg() != BaseOp2.isReg()) ||
      (BaseOp1.isReg() && BaseOp1.getReg() != BaseOp2.getReg()) ||
      (BaseOp1.isFI() && BaseOp1.getIndex() != BaseOp2.getIndex()))
    return false;

  // Check if the load/store are clusterable according to the PowerPC
  // specification.
  const MachineInstr &FirstLdSt = *BaseOp1.getParent();
  const MachineInstr &SecondLdSt = *BaseOp2.getParent();
  unsigned FirstOpc = FirstLdSt.getOpcode();
  unsigned SecondOpc = SecondLdSt.getOpcode();
  const TargetRegisterInfo *TRI = &getRegisterInfo();
  // Cluster the load/store only when they have the same opcode, and they are
  // clusterable opcode according to PowerPC specification.
  if (!isClusterableLdStOpcPair(FirstOpc, SecondOpc, Subtarget))
    return false;

  // Can't cluster load/store that have ordered or volatile memory reference.
  if (!isLdStSafeToCluster(FirstLdSt, TRI) ||
      !isLdStSafeToCluster(SecondLdSt, TRI))
    return false;

  int64_t Offset1 = 0, Offset2 = 0;
  unsigned Width1 = 0, Width2 = 0;
  const MachineOperand *Base1 = nullptr, *Base2 = nullptr;
  if (!getMemOperandWithOffsetWidth(FirstLdSt, Base1, Offset1, Width1, TRI) ||
      !getMemOperandWithOffsetWidth(SecondLdSt, Base2, Offset2, Width2, TRI) ||
      Width1 != Width2)
    return false;

  assert(Base1 == &BaseOp1 && Base2 == &BaseOp2 &&
         "getMemOperandWithOffsetWidth return incorrect base op");
  // The caller should already have ordered FirstMemOp/SecondMemOp by offset.
  assert(Offset1 <= Offset2 && "Caller should have ordered offsets.");
  return Offset1 + Width1 == Offset2;
}

/// GetInstSize - Return the number of bytes of code the specified
/// instruction may be.  This returns the maximum number of bytes.
///
unsigned PPCInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
  unsigned Opcode = MI.getOpcode();

  if (Opcode == PPC::INLINEASM || Opcode == PPC::INLINEASM_BR) {
    const MachineFunction *MF = MI.getParent()->getParent();
    const char *AsmStr = MI.getOperand(0).getSymbolName();
    return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
  } else if (Opcode == TargetOpcode::STACKMAP) {
    StackMapOpers Opers(&MI);
    return Opers.getNumPatchBytes();
  } else if (Opcode == TargetOpcode::PATCHPOINT) {
    PatchPointOpers Opers(&MI);
    return Opers.getNumPatchBytes();
  } else {
    return get(Opcode).getSize();
  }
}

std::pair<unsigned, unsigned>
PPCInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const {
  const unsigned Mask = PPCII::MO_ACCESS_MASK;
  return std::make_pair(TF & Mask, TF & ~Mask);
}

ArrayRef<std::pair<unsigned, const char *>>
PPCInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
  using namespace PPCII;
  static const std::pair<unsigned, const char *> TargetFlags[] = {
      {MO_LO, "ppc-lo"},
      {MO_HA, "ppc-ha"},
      {MO_TPREL_LO, "ppc-tprel-lo"},
      {MO_TPREL_HA, "ppc-tprel-ha"},
      {MO_DTPREL_LO, "ppc-dtprel-lo"},
      {MO_TLSLD_LO, "ppc-tlsld-lo"},
      {MO_TOC_LO, "ppc-toc-lo"},
      {MO_TLS, "ppc-tls"}};
  return makeArrayRef(TargetFlags);
}

ArrayRef<std::pair<unsigned, const char *>>
PPCInstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {
  using namespace PPCII;
  static const std::pair<unsigned, const char *> TargetFlags[] = {
      {MO_PLT, "ppc-plt"},
      {MO_PIC_FLAG, "ppc-pic"},
      {MO_PCREL_FLAG, "ppc-pcrel"},
      {MO_GOT_FLAG, "ppc-got"},
      {MO_PCREL_OPT_FLAG, "ppc-opt-pcrel"},
      {MO_TLSGD_FLAG, "ppc-tlsgd"},
      {MO_TLSLD_FLAG, "ppc-tlsld"},
      {MO_TPREL_FLAG, "ppc-tprel"},
      {MO_GOT_TLSGD_PCREL_FLAG, "ppc-got-tlsgd-pcrel"},
      {MO_GOT_TLSLD_PCREL_FLAG, "ppc-got-tlsld-pcrel"},
      {MO_GOT_TPREL_PCREL_FLAG, "ppc-got-tprel-pcrel"}};
  return makeArrayRef(TargetFlags);
}

// Expand VSX Memory Pseudo instruction to either a VSX or a FP instruction.
// The VSX versions have the advantage of a full 64-register target whereas
// the FP ones have the advantage of lower latency and higher throughput. So
// what we are after is using the faster instructions in low register pressure
// situations and using the larger register file in high register pressure
// situations.
bool PPCInstrInfo::expandVSXMemPseudo(MachineInstr &MI) const {
    unsigned UpperOpcode, LowerOpcode;
    switch (MI.getOpcode()) {
    case PPC::DFLOADf32:
      UpperOpcode = PPC::LXSSP;
      LowerOpcode = PPC::LFS;
      break;
    case PPC::DFLOADf64:
      UpperOpcode = PPC::LXSD;
      LowerOpcode = PPC::LFD;
      break;
    case PPC::DFSTOREf32:
      UpperOpcode = PPC::STXSSP;
      LowerOpcode = PPC::STFS;
      break;
    case PPC::DFSTOREf64:
      UpperOpcode = PPC::STXSD;
      LowerOpcode = PPC::STFD;
      break;
    case PPC::XFLOADf32:
      UpperOpcode = PPC::LXSSPX;
      LowerOpcode = PPC::LFSX;
      break;
    case PPC::XFLOADf64:
      UpperOpcode = PPC::LXSDX;
      LowerOpcode = PPC::LFDX;
      break;
    case PPC::XFSTOREf32:
      UpperOpcode = PPC::STXSSPX;
      LowerOpcode = PPC::STFSX;
      break;
    case PPC::XFSTOREf64:
      UpperOpcode = PPC::STXSDX;
      LowerOpcode = PPC::STFDX;
      break;
    case PPC::LIWAX:
      UpperOpcode = PPC::LXSIWAX;
      LowerOpcode = PPC::LFIWAX;
      break;
    case PPC::LIWZX:
      UpperOpcode = PPC::LXSIWZX;
      LowerOpcode = PPC::LFIWZX;
      break;
    case PPC::STIWX:
      UpperOpcode = PPC::STXSIWX;
      LowerOpcode = PPC::STFIWX;
      break;
    default:
      llvm_unreachable("Unknown Operation!");
    }

    Register TargetReg = MI.getOperand(0).getReg();
    unsigned Opcode;
    if ((TargetReg >= PPC::F0 && TargetReg <= PPC::F31) ||
        (TargetReg >= PPC::VSL0 && TargetReg <= PPC::VSL31))
      Opcode = LowerOpcode;
    else
      Opcode = UpperOpcode;
    MI.setDesc(get(Opcode));
    return true;
}

static bool isAnImmediateOperand(const MachineOperand &MO) {
  return MO.isCPI() || MO.isGlobal() || MO.isImm();
}

bool PPCInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
  auto &MBB = *MI.getParent();
  auto DL = MI.getDebugLoc();

  switch (MI.getOpcode()) {
  case PPC::BUILD_UACC: {
    MCRegister ACC = MI.getOperand(0).getReg();
    MCRegister UACC = MI.getOperand(1).getReg();
    if (ACC - PPC::ACC0 != UACC - PPC::UACC0) {
      MCRegister SrcVSR = PPC::VSL0 + (UACC - PPC::UACC0) * 4;
      MCRegister DstVSR = PPC::VSL0 + (ACC - PPC::ACC0) * 4;
      // FIXME: This can easily be improved to look up to the top of the MBB
      // to see if the inputs are XXLOR's. If they are and SrcReg is killed,
      // we can just re-target any such XXLOR's to DstVSR + offset.
      for (int VecNo = 0; VecNo < 4; VecNo++)
        BuildMI(MBB, MI, DL, get(PPC::XXLOR), DstVSR + VecNo)
            .addReg(SrcVSR + VecNo)
            .addReg(SrcVSR + VecNo);
    }
    // BUILD_UACC is expanded to 4 copies of the underlying vsx regisers.
    // So after building the 4 copies, we can replace the BUILD_UACC instruction
    // with a NOP.
    LLVM_FALLTHROUGH;
  }
  case PPC::KILL_PAIR: {
    MI.setDesc(get(PPC::UNENCODED_NOP));
    MI.RemoveOperand(1);
    MI.RemoveOperand(0);
    return true;
  }
  case TargetOpcode::LOAD_STACK_GUARD: {
    assert(Subtarget.isTargetLinux() &&
           "Only Linux target is expected to contain LOAD_STACK_GUARD");
    const int64_t Offset = Subtarget.isPPC64() ? -0x7010 : -0x7008;
    const unsigned Reg = Subtarget.isPPC64() ? PPC::X13 : PPC::R2;
    MI.setDesc(get(Subtarget.isPPC64() ? PPC::LD : PPC::LWZ));
    MachineInstrBuilder(*MI.getParent()->getParent(), MI)
        .addImm(Offset)
        .addReg(Reg);
    return true;
  }
  case PPC::DFLOADf32:
  case PPC::DFLOADf64:
  case PPC::DFSTOREf32:
  case PPC::DFSTOREf64: {
    assert(Subtarget.hasP9Vector() &&
           "Invalid D-Form Pseudo-ops on Pre-P9 target.");
    assert(MI.getOperand(2).isReg() &&
           isAnImmediateOperand(MI.getOperand(1)) &&
           "D-form op must have register and immediate operands");
    return expandVSXMemPseudo(MI);
  }
  case PPC::XFLOADf32:
  case PPC::XFSTOREf32:
  case PPC::LIWAX:
  case PPC::LIWZX:
  case PPC::STIWX: {
    assert(Subtarget.hasP8Vector() &&
           "Invalid X-Form Pseudo-ops on Pre-P8 target.");
    assert(MI.getOperand(2).isReg() && MI.getOperand(1).isReg() &&
           "X-form op must have register and register operands");
    return expandVSXMemPseudo(MI);
  }
  case PPC::XFLOADf64:
  case PPC::XFSTOREf64: {
    assert(Subtarget.hasVSX() &&
           "Invalid X-Form Pseudo-ops on target that has no VSX.");
    assert(MI.getOperand(2).isReg() && MI.getOperand(1).isReg() &&
           "X-form op must have register and register operands");
    return expandVSXMemPseudo(MI);
  }
  case PPC::SPILLTOVSR_LD: {
    Register TargetReg = MI.getOperand(0).getReg();
    if (PPC::VSFRCRegClass.contains(TargetReg)) {
      MI.setDesc(get(PPC::DFLOADf64));
      return expandPostRAPseudo(MI);
    }
    else
      MI.setDesc(get(PPC::LD));
    return true;
  }
  case PPC::SPILLTOVSR_ST: {
    Register SrcReg = MI.getOperand(0).getReg();
    if (PPC::VSFRCRegClass.contains(SrcReg)) {
      NumStoreSPILLVSRRCAsVec++;
      MI.setDesc(get(PPC::DFSTOREf64));
      return expandPostRAPseudo(MI);
    } else {
      NumStoreSPILLVSRRCAsGpr++;
      MI.setDesc(get(PPC::STD));
    }
    return true;
  }
  case PPC::SPILLTOVSR_LDX: {
    Register TargetReg = MI.getOperand(0).getReg();
    if (PPC::VSFRCRegClass.contains(TargetReg))
      MI.setDesc(get(PPC::LXSDX));
    else
      MI.setDesc(get(PPC::LDX));
    return true;
  }
  case PPC::SPILLTOVSR_STX: {
    Register SrcReg = MI.getOperand(0).getReg();
    if (PPC::VSFRCRegClass.contains(SrcReg)) {
      NumStoreSPILLVSRRCAsVec++;
      MI.setDesc(get(PPC::STXSDX));
    } else {
      NumStoreSPILLVSRRCAsGpr++;
      MI.setDesc(get(PPC::STDX));
    }
    return true;
  }

  case PPC::CFENCE8: {
    auto Val = MI.getOperand(0).getReg();
    BuildMI(MBB, MI, DL, get(PPC::CMPD), PPC::CR7).addReg(Val).addReg(Val);
    BuildMI(MBB, MI, DL, get(PPC::CTRL_DEP))
        .addImm(PPC::PRED_NE_MINUS)
        .addReg(PPC::CR7)
        .addImm(1);
    MI.setDesc(get(PPC::ISYNC));
    MI.RemoveOperand(0);
    return true;
  }
  }
  return false;
}

// Essentially a compile-time implementation of a compare->isel sequence.
// It takes two constants to compare, along with the true/false registers
// and the comparison type (as a subreg to a CR field) and returns one
// of the true/false registers, depending on the comparison results.
static unsigned selectReg(int64_t Imm1, int64_t Imm2, unsigned CompareOpc,
                          unsigned TrueReg, unsigned FalseReg,
                          unsigned CRSubReg) {
  // Signed comparisons. The immediates are assumed to be sign-extended.
  if (CompareOpc == PPC::CMPWI || CompareOpc == PPC::CMPDI) {
    switch (CRSubReg) {
    default: llvm_unreachable("Unknown integer comparison type.");
    case PPC::sub_lt:
      return Imm1 < Imm2 ? TrueReg : FalseReg;
    case PPC::sub_gt:
      return Imm1 > Imm2 ? TrueReg : FalseReg;
    case PPC::sub_eq:
      return Imm1 == Imm2 ? TrueReg : FalseReg;
    }
  }
  // Unsigned comparisons.
  else if (CompareOpc == PPC::CMPLWI || CompareOpc == PPC::CMPLDI) {
    switch (CRSubReg) {
    default: llvm_unreachable("Unknown integer comparison type.");
    case PPC::sub_lt:
      return (uint64_t)Imm1 < (uint64_t)Imm2 ? TrueReg : FalseReg;
    case PPC::sub_gt:
      return (uint64_t)Imm1 > (uint64_t)Imm2 ? TrueReg : FalseReg;
    case PPC::sub_eq:
      return Imm1 == Imm2 ? TrueReg : FalseReg;
    }
  }
  return PPC::NoRegister;
}

void PPCInstrInfo::replaceInstrOperandWithImm(MachineInstr &MI,
                                              unsigned OpNo,
                                              int64_t Imm) const {
  assert(MI.getOperand(OpNo).isReg() && "Operand must be a REG");
  // Replace the REG with the Immediate.
  Register InUseReg = MI.getOperand(OpNo).getReg();
  MI.getOperand(OpNo).ChangeToImmediate(Imm);

  if (MI.implicit_operands().empty())
    return;

  // We need to make sure that the MI didn't have any implicit use
  // of this REG any more.
  const TargetRegisterInfo *TRI = &getRegisterInfo();
  int UseOpIdx = MI.findRegisterUseOperandIdx(InUseReg, false, TRI);
  if (UseOpIdx >= 0) {
    MachineOperand &MO = MI.getOperand(UseOpIdx);
    if (MO.isImplicit())
      // The operands must always be in the following order:
      // - explicit reg defs,
      // - other explicit operands (reg uses, immediates, etc.),
      // - implicit reg defs
      // - implicit reg uses
      // Therefore, removing the implicit operand won't change the explicit
      // operands layout.
      MI.RemoveOperand(UseOpIdx);
  }
}

// Replace an instruction with one that materializes a constant (and sets
// CR0 if the original instruction was a record-form instruction).
void PPCInstrInfo::replaceInstrWithLI(MachineInstr &MI,
                                      const LoadImmediateInfo &LII) const {
  // Remove existing operands.
  int OperandToKeep = LII.SetCR ? 1 : 0;
  for (int i = MI.getNumOperands() - 1; i > OperandToKeep; i--)
    MI.RemoveOperand(i);

  // Replace the instruction.
  if (LII.SetCR) {
    MI.setDesc(get(LII.Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec));
    // Set the immediate.
    MachineInstrBuilder(*MI.getParent()->getParent(), MI)
        .addImm(LII.Imm).addReg(PPC::CR0, RegState::ImplicitDefine);
    return;
  }
  else
    MI.setDesc(get(LII.Is64Bit ? PPC::LI8 : PPC::LI));

  // Set the immediate.
  MachineInstrBuilder(*MI.getParent()->getParent(), MI)
      .addImm(LII.Imm);
}

MachineInstr *PPCInstrInfo::getDefMIPostRA(unsigned Reg, MachineInstr &MI,
                                           bool &SeenIntermediateUse) const {
  assert(!MI.getParent()->getParent()->getRegInfo().isSSA() &&
         "Should be called after register allocation.");
  const TargetRegisterInfo *TRI = &getRegisterInfo();
  MachineBasicBlock::reverse_iterator E = MI.getParent()->rend(), It = MI;
  It++;
  SeenIntermediateUse = false;
  for (; It != E; ++It) {
    if (It->modifiesRegister(Reg, TRI))
      return &*It;
    if (It->readsRegister(Reg, TRI))
      SeenIntermediateUse = true;
  }
  return nullptr;
}

MachineInstr *PPCInstrInfo::getForwardingDefMI(
  MachineInstr &MI,
  unsigned &OpNoForForwarding,
  bool &SeenIntermediateUse) const {
  OpNoForForwarding = ~0U;
  MachineInstr *DefMI = nullptr;
  MachineRegisterInfo *MRI = &MI.getParent()->getParent()->getRegInfo();
  const TargetRegisterInfo *TRI = &getRegisterInfo();
  // If we're in SSA, get the defs through the MRI. Otherwise, only look
  // within the basic block to see if the register is defined using an
  // LI/LI8/ADDI/ADDI8.
  if (MRI->isSSA()) {
    for (int i = 1, e = MI.getNumOperands(); i < e; i++) {
      if (!MI.getOperand(i).isReg())
        continue;
      Register Reg = MI.getOperand(i).getReg();
      if (!Register::isVirtualRegister(Reg))
        continue;
      unsigned TrueReg = TRI->lookThruCopyLike(Reg, MRI);
      if (Register::isVirtualRegister(TrueReg)) {
        DefMI = MRI->getVRegDef(TrueReg);
        if (DefMI->getOpcode() == PPC::LI || DefMI->getOpcode() == PPC::LI8 ||
            DefMI->getOpcode() == PPC::ADDI ||
            DefMI->getOpcode() == PPC::ADDI8) {
          OpNoForForwarding = i;
          // The ADDI and LI operand maybe exist in one instruction at same
          // time. we prefer to fold LI operand as LI only has one Imm operand
          // and is more possible to be converted. So if current DefMI is
          // ADDI/ADDI8, we continue to find possible LI/LI8.
          if (DefMI->getOpcode() == PPC::LI || DefMI->getOpcode() == PPC::LI8)
            break;
        }
      }
    }
  } else {
    // Looking back through the definition for each operand could be expensive,
    // so exit early if this isn't an instruction that either has an immediate
    // form or is already an immediate form that we can handle.
    ImmInstrInfo III;
    unsigned Opc = MI.getOpcode();
    bool ConvertibleImmForm =
        Opc == PPC::CMPWI || Opc == PPC::CMPLWI || Opc == PPC::CMPDI ||
        Opc == PPC::CMPLDI || Opc == PPC::ADDI || Opc == PPC::ADDI8 ||
        Opc == PPC::ORI || Opc == PPC::ORI8 || Opc == PPC::XORI ||
        Opc == PPC::XORI8 || Opc == PPC::RLDICL || Opc == PPC::RLDICL_rec ||
        Opc == PPC::RLDICL_32 || Opc == PPC::RLDICL_32_64 ||
        Opc == PPC::RLWINM || Opc == PPC::RLWINM_rec || Opc == PPC::RLWINM8 ||
        Opc == PPC::RLWINM8_rec;
    bool IsVFReg = (MI.getNumOperands() && MI.getOperand(0).isReg())
                       ? isVFRegister(MI.getOperand(0).getReg())
                       : false;
    if (!ConvertibleImmForm && !instrHasImmForm(Opc, IsVFReg, III, true))
      return nullptr;

    // Don't convert or %X, %Y, %Y since that's just a register move.
    if ((Opc == PPC::OR || Opc == PPC::OR8) &&
        MI.getOperand(1).getReg() == MI.getOperand(2).getReg())
      return nullptr;
    for (int i = 1, e = MI.getNumOperands(); i < e; i++) {
      MachineOperand &MO = MI.getOperand(i);
      SeenIntermediateUse = false;
      if (MO.isReg() && MO.isUse() && !MO.isImplicit()) {
        Register Reg = MI.getOperand(i).getReg();
        // If we see another use of this reg between the def and the MI,
        // we want to flat it so the def isn't deleted.
        MachineInstr *DefMI = getDefMIPostRA(Reg, MI, SeenIntermediateUse);
        if (DefMI) {
          // Is this register defined by some form of add-immediate (including
          // load-immediate) within this basic block?
          switch (DefMI->getOpcode()) {
          default:
            break;
          case PPC::LI:
          case PPC::LI8:
          case PPC::ADDItocL:
          case PPC::ADDI:
          case PPC::ADDI8:
            OpNoForForwarding = i;
            return DefMI;
          }
        }
      }
    }
  }
  return OpNoForForwarding == ~0U ? nullptr : DefMI;
}

unsigned PPCInstrInfo::getSpillTarget() const {
  // With P10, we may need to spill paired vector registers or accumulator
  // registers. MMA implies paired vectors, so we can just check that.
  bool IsP10Variant = Subtarget.isISA3_1() || Subtarget.pairedVectorMemops();
  return IsP10Variant ? 2 : Subtarget.hasP9Vector() ? 1 : 0;
}

const unsigned *PPCInstrInfo::getStoreOpcodesForSpillArray() const {
  return StoreSpillOpcodesArray[getSpillTarget()];
}

const unsigned *PPCInstrInfo::getLoadOpcodesForSpillArray() const {
  return LoadSpillOpcodesArray[getSpillTarget()];
}

void PPCInstrInfo::fixupIsDeadOrKill(MachineInstr *StartMI, MachineInstr *EndMI,
                                     unsigned RegNo) const {
  // Conservatively clear kill flag for the register if the instructions are in
  // different basic blocks and in SSA form, because the kill flag may no longer
  // be right. There is no need to bother with dead flags since defs with no
  // uses will be handled by DCE.
  MachineRegisterInfo &MRI = StartMI->getParent()->getParent()->getRegInfo();
  if (MRI.isSSA() && (StartMI->getParent() != EndMI->getParent())) {
    MRI.clearKillFlags(RegNo);
    return;
  }

  // Instructions between [StartMI, EndMI] should be in same basic block.
  assert((StartMI->getParent() == EndMI->getParent()) &&
         "Instructions are not in same basic block");

  // If before RA, StartMI may be def through COPY, we need to adjust it to the
  // real def. See function getForwardingDefMI.
  if (MRI.isSSA()) {
    bool Reads, Writes;
    std::tie(Reads, Writes) = StartMI->readsWritesVirtualRegister(RegNo);
    if (!Reads && !Writes) {
      assert(Register::isVirtualRegister(RegNo) &&
             "Must be a virtual register");
      // Get real def and ignore copies.
      StartMI = MRI.getVRegDef(RegNo);
    }
  }

  bool IsKillSet = false;

  auto clearOperandKillInfo = [=] (MachineInstr &MI, unsigned Index) {
    MachineOperand &MO = MI.getOperand(Index);
    if (MO.isReg() && MO.isUse() && MO.isKill() &&
        getRegisterInfo().regsOverlap(MO.getReg(), RegNo))
      MO.setIsKill(false);
  };

  // Set killed flag for EndMI.
  // No need to do anything if EndMI defines RegNo.
  int UseIndex =
      EndMI->findRegisterUseOperandIdx(RegNo, false, &getRegisterInfo());
  if (UseIndex != -1) {
    EndMI->getOperand(UseIndex).setIsKill(true);
    IsKillSet = true;
    // Clear killed flag for other EndMI operands related to RegNo. In some
    // upexpected cases, killed may be set multiple times for same register
    // operand in same MI.
    for (int i = 0, e = EndMI->getNumOperands(); i != e; ++i)
      if (i != UseIndex)
        clearOperandKillInfo(*EndMI, i);
  }

  // Walking the inst in reverse order (EndMI -> StartMI].
  MachineBasicBlock::reverse_iterator It = *EndMI;
  MachineBasicBlock::reverse_iterator E = EndMI->getParent()->rend();
  // EndMI has been handled above, skip it here.
  It++;
  MachineOperand *MO = nullptr;
  for (; It != E; ++It) {
    // Skip insturctions which could not be a def/use of RegNo.
    if (It->isDebugInstr() || It->isPosition())
      continue;

    // Clear killed flag for all It operands related to RegNo. In some
    // upexpected cases, killed may be set multiple times for same register
    // operand in same MI.
    for (int i = 0, e = It->getNumOperands(); i != e; ++i)
        clearOperandKillInfo(*It, i);

    // If killed is not set, set killed for its last use or set dead for its def
    // if no use found.
    if (!IsKillSet) {
      if ((MO = It->findRegisterUseOperand(RegNo, false, &getRegisterInfo()))) {
        // Use found, set it killed.
        IsKillSet = true;
        MO->setIsKill(true);
        continue;
      } else if ((MO = It->findRegisterDefOperand(RegNo, false, true,
                                                  &getRegisterInfo()))) {
        // No use found, set dead for its def.
        assert(&*It == StartMI && "No new def between StartMI and EndMI.");
        MO->setIsDead(true);
        break;
      }
    }

    if ((&*It) == StartMI)
      break;
  }
  // Ensure RegMo liveness is killed after EndMI.
  assert((IsKillSet || (MO && MO->isDead())) &&
         "RegNo should be killed or dead");
}

// This opt tries to convert the following imm form to an index form to save an
// add for stack variables.
// Return false if no such pattern found.
//
// ADDI instr: ToBeChangedReg = ADDI FrameBaseReg, OffsetAddi
// ADD instr:  ToBeDeletedReg = ADD ToBeChangedReg(killed), ScaleReg
// Imm instr:  Reg            = op OffsetImm, ToBeDeletedReg(killed)
//
// can be converted to:
//
// new ADDI instr: ToBeChangedReg = ADDI FrameBaseReg, (OffsetAddi + OffsetImm)
// Index instr:    Reg            = opx ScaleReg, ToBeChangedReg(killed)
//
// In order to eliminate ADD instr, make sure that:
// 1: (OffsetAddi + OffsetImm) must be int16 since this offset will be used in
//    new ADDI instr and ADDI can only take int16 Imm.
// 2: ToBeChangedReg must be killed in ADD instr and there is no other use
//    between ADDI and ADD instr since its original def in ADDI will be changed
//    in new ADDI instr. And also there should be no new def for it between
//    ADD and Imm instr as ToBeChangedReg will be used in Index instr.
// 3: ToBeDeletedReg must be killed in Imm instr and there is no other use
//    between ADD and Imm instr since ADD instr will be eliminated.
// 4: ScaleReg must not be redefined between ADD and Imm instr since it will be
//    moved to Index instr.
bool PPCInstrInfo::foldFrameOffset(MachineInstr &MI) const {
  MachineFunction *MF = MI.getParent()->getParent();
  MachineRegisterInfo *MRI = &MF->getRegInfo();
  bool PostRA = !MRI->isSSA();
  // Do this opt after PEI which is after RA. The reason is stack slot expansion
  // in PEI may expose such opportunities since in PEI, stack slot offsets to
  // frame base(OffsetAddi) are determined.
  if (!PostRA)
    return false;
  unsigned ToBeDeletedReg = 0;
  int64_t OffsetImm = 0;
  unsigned XFormOpcode = 0;
  ImmInstrInfo III;

  // Check if Imm instr meets requirement.
  if (!isImmInstrEligibleForFolding(MI, ToBeDeletedReg, XFormOpcode, OffsetImm,
                                    III))
    return false;

  bool OtherIntermediateUse = false;
  MachineInstr *ADDMI = getDefMIPostRA(ToBeDeletedReg, MI, OtherIntermediateUse);

  // Exit if there is other use between ADD and Imm instr or no def found.
  if (OtherIntermediateUse || !ADDMI)
    return false;

  // Check if ADD instr meets requirement.
  if (!isADDInstrEligibleForFolding(*ADDMI))
    return false;

  unsigned ScaleRegIdx = 0;
  int64_t OffsetAddi = 0;
  MachineInstr *ADDIMI = nullptr;

  // Check if there is a valid ToBeChangedReg in ADDMI.
  // 1: It must be killed.
  // 2: Its definition must be a valid ADDIMI.
  // 3: It must satify int16 offset requirement.
  if (isValidToBeChangedReg(ADDMI, 1, ADDIMI, OffsetAddi, OffsetImm))
    ScaleRegIdx = 2;
  else if (isValidToBeChangedReg(ADDMI, 2, ADDIMI, OffsetAddi, OffsetImm))
    ScaleRegIdx = 1;
  else
    return false;

  assert(ADDIMI && "There should be ADDIMI for valid ToBeChangedReg.");
  unsigned ToBeChangedReg = ADDIMI->getOperand(0).getReg();
  unsigned ScaleReg = ADDMI->getOperand(ScaleRegIdx).getReg();
  auto NewDefFor = [&](unsigned Reg, MachineBasicBlock::iterator Start,
                       MachineBasicBlock::iterator End) {
    for (auto It = ++Start; It != End; It++)
      if (It->modifiesRegister(Reg, &getRegisterInfo()))
        return true;
    return false;
  };

  // We are trying to replace the ImmOpNo with ScaleReg. Give up if it is
  // treated as special zero when ScaleReg is R0/X0 register.
  if (III.ZeroIsSpecialOrig == III.ImmOpNo &&
      (ScaleReg == PPC::R0 || ScaleReg == PPC::X0))
    return false;

  // Make sure no other def for ToBeChangedReg and ScaleReg between ADD Instr
  // and Imm Instr.
  if (NewDefFor(ToBeChangedReg, *ADDMI, MI) || NewDefFor(ScaleReg, *ADDMI, MI))
    return false;

  // Now start to do the transformation.
  LLVM_DEBUG(dbgs() << "Replace instruction: "
                    << "\n");
  LLVM_DEBUG(ADDIMI->dump());
  LLVM_DEBUG(ADDMI->dump());
  LLVM_DEBUG(MI.dump());
  LLVM_DEBUG(dbgs() << "with: "
                    << "\n");

  // Update ADDI instr.
  ADDIMI->getOperand(2).setImm(OffsetAddi + OffsetImm);

  // Update Imm instr.
  MI.setDesc(get(XFormOpcode));
  MI.getOperand(III.ImmOpNo)
      .ChangeToRegister(ScaleReg, false, false,
                        ADDMI->getOperand(ScaleRegIdx).isKill());

  MI.getOperand(III.OpNoForForwarding)
      .ChangeToRegister(ToBeChangedReg, false, false, true);

  // Eliminate ADD instr.
  ADDMI->eraseFromParent();

  LLVM_DEBUG(ADDIMI->dump());
  LLVM_DEBUG(MI.dump());

  return true;
}

bool PPCInstrInfo::isADDIInstrEligibleForFolding(MachineInstr &ADDIMI,
                                                 int64_t &Imm) const {
  unsigned Opc = ADDIMI.getOpcode();

  // Exit if the instruction is not ADDI.
  if (Opc != PPC::ADDI && Opc != PPC::ADDI8)
    return false;

  // The operand may not necessarily be an immediate - it could be a relocation.
  if (!ADDIMI.getOperand(2).isImm())
    return false;

  Imm = ADDIMI.getOperand(2).getImm();

  return true;
}

bool PPCInstrInfo::isADDInstrEligibleForFolding(MachineInstr &ADDMI) const {
  unsigned Opc = ADDMI.getOpcode();

  // Exit if the instruction is not ADD.
  return Opc == PPC::ADD4 || Opc == PPC::ADD8;
}

bool PPCInstrInfo::isImmInstrEligibleForFolding(MachineInstr &MI,
                                                unsigned &ToBeDeletedReg,
                                                unsigned &XFormOpcode,
                                                int64_t &OffsetImm,
                                                ImmInstrInfo &III) const {
  // Only handle load/store.
  if (!MI.mayLoadOrStore())
    return false;

  unsigned Opc = MI.getOpcode();

  XFormOpcode = RI.getMappedIdxOpcForImmOpc(Opc);

  // Exit if instruction has no index form.
  if (XFormOpcode == PPC::INSTRUCTION_LIST_END)
    return false;

  // TODO: sync the logic between instrHasImmForm() and ImmToIdxMap.
  if (!instrHasImmForm(XFormOpcode, isVFRegister(MI.getOperand(0).getReg()),
                       III, true))
    return false;

  if (!III.IsSummingOperands)
    return false;

  MachineOperand ImmOperand = MI.getOperand(III.ImmOpNo);
  MachineOperand RegOperand = MI.getOperand(III.OpNoForForwarding);
  // Only support imm operands, not relocation slots or others.
  if (!ImmOperand.isImm())
    return false;

  assert(RegOperand.isReg() && "Instruction format is not right");

  // There are other use for ToBeDeletedReg after Imm instr, can not delete it.
  if (!RegOperand.isKill())
    return false;

  ToBeDeletedReg = RegOperand.getReg();
  OffsetImm = ImmOperand.getImm();

  return true;
}

bool PPCInstrInfo::isValidToBeChangedReg(MachineInstr *ADDMI, unsigned Index,
                                         MachineInstr *&ADDIMI,
                                         int64_t &OffsetAddi,
                                         int64_t OffsetImm) const {
  assert((Index == 1 || Index == 2) && "Invalid operand index for add.");
  MachineOperand &MO = ADDMI->getOperand(Index);

  if (!MO.isKill())
    return false;

  bool OtherIntermediateUse = false;

  ADDIMI = getDefMIPostRA(MO.getReg(), *ADDMI, OtherIntermediateUse);
  // Currently handle only one "add + Imminstr" pair case, exit if other
  // intermediate use for ToBeChangedReg found.
  // TODO: handle the cases where there are other "add + Imminstr" pairs
  // with same offset in Imminstr which is like:
  //
  // ADDI instr: ToBeChangedReg  = ADDI FrameBaseReg, OffsetAddi
  // ADD instr1: ToBeDeletedReg1 = ADD ToBeChangedReg, ScaleReg1
  // Imm instr1: Reg1            = op1 OffsetImm, ToBeDeletedReg1(killed)
  // ADD instr2: ToBeDeletedReg2 = ADD ToBeChangedReg(killed), ScaleReg2
  // Imm instr2: Reg2            = op2 OffsetImm, ToBeDeletedReg2(killed)
  //
  // can be converted to:
  //
  // new ADDI instr: ToBeChangedReg = ADDI FrameBaseReg,
  //                                       (OffsetAddi + OffsetImm)
  // Index instr1:   Reg1           = opx1 ScaleReg1, ToBeChangedReg
  // Index instr2:   Reg2           = opx2 ScaleReg2, ToBeChangedReg(killed)

  if (OtherIntermediateUse || !ADDIMI)
    return false;
  // Check if ADDI instr meets requirement.
  if (!isADDIInstrEligibleForFolding(*ADDIMI, OffsetAddi))
    return false;

  if (isInt<16>(OffsetAddi + OffsetImm))
    return true;
  return false;
}

// If this instruction has an immediate form and one of its operands is a
// result of a load-immediate or an add-immediate, convert it to
// the immediate form if the constant is in range.
bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI,
                                          MachineInstr **KilledDef) const {
  MachineFunction *MF = MI.getParent()->getParent();
  MachineRegisterInfo *MRI = &MF->getRegInfo();
  bool PostRA = !MRI->isSSA();
  bool SeenIntermediateUse = true;
  unsigned ForwardingOperand = ~0U;
  MachineInstr *DefMI = getForwardingDefMI(MI, ForwardingOperand,
                                           SeenIntermediateUse);
  if (!DefMI)
    return false;
  assert(ForwardingOperand < MI.getNumOperands() &&
         "The forwarding operand needs to be valid at this point");
  bool IsForwardingOperandKilled = MI.getOperand(ForwardingOperand).isKill();
  bool KillFwdDefMI = !SeenIntermediateUse && IsForwardingOperandKilled;
  if (KilledDef && KillFwdDefMI)
    *KilledDef = DefMI;

  // If this is a imm instruction and its register operands is produced by ADDI,
  // put the imm into imm inst directly.
  if (RI.getMappedIdxOpcForImmOpc(MI.getOpcode()) !=
          PPC::INSTRUCTION_LIST_END &&
      transformToNewImmFormFedByAdd(MI, *DefMI, ForwardingOperand))
    return true;

  ImmInstrInfo III;
  bool IsVFReg = MI.getOperand(0).isReg()
                     ? isVFRegister(MI.getOperand(0).getReg())
                     : false;
  bool HasImmForm = instrHasImmForm(MI.getOpcode(), IsVFReg, III, PostRA);
  // If this is a reg+reg instruction that has a reg+imm form,
  // and one of the operands is produced by an add-immediate,
  // try to convert it.
  if (HasImmForm &&
      transformToImmFormFedByAdd(MI, III, ForwardingOperand, *DefMI,
                                 KillFwdDefMI))
    return true;

  // If this is a reg+reg instruction that has a reg+imm form,
  // and one of the operands is produced by LI, convert it now.
  if (HasImmForm &&
      transformToImmFormFedByLI(MI, III, ForwardingOperand, *DefMI))
    return true;

  // If this is not a reg+reg, but the DefMI is LI/LI8, check if its user MI
  // can be simpified to LI.
  if (!HasImmForm && simplifyToLI(MI, *DefMI, ForwardingOperand, KilledDef))
    return true;

  return false;
}

bool PPCInstrInfo::combineRLWINM(MachineInstr &MI,
                                 MachineInstr **ToErase) const {
  MachineRegisterInfo *MRI = &MI.getParent()->getParent()->getRegInfo();
  unsigned FoldingReg = MI.getOperand(1).getReg();
  if (!Register::isVirtualRegister(FoldingReg))
    return false;
  MachineInstr *SrcMI = MRI->getVRegDef(FoldingReg);
  if (SrcMI->getOpcode() != PPC::RLWINM &&
      SrcMI->getOpcode() != PPC::RLWINM_rec &&
      SrcMI->getOpcode() != PPC::RLWINM8 &&
      SrcMI->getOpcode() != PPC::RLWINM8_rec)
    return false;
  assert((MI.getOperand(2).isImm() && MI.getOperand(3).isImm() &&
          MI.getOperand(4).isImm() && SrcMI->getOperand(2).isImm() &&
          SrcMI->getOperand(3).isImm() && SrcMI->getOperand(4).isImm()) &&
         "Invalid PPC::RLWINM Instruction!");
  uint64_t SHSrc = SrcMI->getOperand(2).getImm();
  uint64_t SHMI = MI.getOperand(2).getImm();
  uint64_t MBSrc = SrcMI->getOperand(3).getImm();
  uint64_t MBMI = MI.getOperand(3).getImm();
  uint64_t MESrc = SrcMI->getOperand(4).getImm();
  uint64_t MEMI = MI.getOperand(4).getImm();

  assert((MEMI < 32 && MESrc < 32 && MBMI < 32 && MBSrc < 32) &&
         "Invalid PPC::RLWINM Instruction!");
  // If MBMI is bigger than MEMI, we always can not get run of ones.
  // RotatedSrcMask non-wrap:
  //                 0........31|32........63
  // RotatedSrcMask:   B---E        B---E
  // MaskMI:         -----------|--E  B------
  // Result:           -----          ---      (Bad candidate)
  //
  // RotatedSrcMask wrap:
  //                 0........31|32........63
  // RotatedSrcMask: --E   B----|--E    B----
  // MaskMI:         -----------|--E  B------
  // Result:         ---   -----|---    -----  (Bad candidate)
  //
  // One special case is RotatedSrcMask is a full set mask.
  // RotatedSrcMask full:
  //                 0........31|32........63
  // RotatedSrcMask: ------EB---|-------EB---
  // MaskMI:         -----------|--E  B------
  // Result:         -----------|---  -------  (Good candidate)

  // Mark special case.
  bool SrcMaskFull = (MBSrc - MESrc == 1) || (MBSrc == 0 && MESrc == 31);

  // For other MBMI > MEMI cases, just return.
  if ((MBMI > MEMI) && !SrcMaskFull)
    return false;

  // Handle MBMI <= MEMI cases.
  APInt MaskMI = APInt::getBitsSetWithWrap(32, 32 - MEMI - 1, 32 - MBMI);
  // In MI, we only need low 32 bits of SrcMI, just consider about low 32
  // bit of SrcMI mask. Note that in APInt, lowerest bit is at index 0,
  // while in PowerPC ISA, lowerest bit is at index 63.
  APInt MaskSrc = APInt::getBitsSetWithWrap(32, 32 - MESrc - 1, 32 - MBSrc);

  APInt RotatedSrcMask = MaskSrc.rotl(SHMI);
  APInt FinalMask = RotatedSrcMask & MaskMI;
  uint32_t NewMB, NewME;
  bool Simplified = false;

  // If final mask is 0, MI result should be 0 too.
  if (FinalMask.isNullValue()) {
    bool Is64Bit =
        (MI.getOpcode() == PPC::RLWINM8 || MI.getOpcode() == PPC::RLWINM8_rec);
    Simplified = true;
    LLVM_DEBUG(dbgs() << "Replace Instr: ");
    LLVM_DEBUG(MI.dump());

    if (MI.getOpcode() == PPC::RLWINM || MI.getOpcode() == PPC::RLWINM8) {
      // Replace MI with "LI 0"
      MI.RemoveOperand(4);
      MI.RemoveOperand(3);
      MI.RemoveOperand(2);
      MI.getOperand(1).ChangeToImmediate(0);
      MI.setDesc(get(Is64Bit ? PPC::LI8 : PPC::LI));
    } else {
      // Replace MI with "ANDI_rec reg, 0"
      MI.RemoveOperand(4);
      MI.RemoveOperand(3);
      MI.getOperand(2).setImm(0);
      MI.setDesc(get(Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec));
      MI.getOperand(1).setReg(SrcMI->getOperand(1).getReg());
      if (SrcMI->getOperand(1).isKill()) {
        MI.getOperand(1).setIsKill(true);
        SrcMI->getOperand(1).setIsKill(false);
      } else
        // About to replace MI.getOperand(1), clear its kill flag.
        MI.getOperand(1).setIsKill(false);
    }

    LLVM_DEBUG(dbgs() << "With: ");
    LLVM_DEBUG(MI.dump());

  } else if ((isRunOfOnes((unsigned)(FinalMask.getZExtValue()), NewMB, NewME) &&
              NewMB <= NewME) ||
             SrcMaskFull) {
    // Here we only handle MBMI <= MEMI case, so NewMB must be no bigger
    // than NewME. Otherwise we get a 64 bit value after folding, but MI
    // return a 32 bit value.
    Simplified = true;
    LLVM_DEBUG(dbgs() << "Converting Instr: ");
    LLVM_DEBUG(MI.dump());

    uint16_t NewSH = (SHSrc + SHMI) % 32;
    MI.getOperand(2).setImm(NewSH);
    // If SrcMI mask is full, no need to update MBMI and MEMI.
    if (!SrcMaskFull) {
      MI.getOperand(3).setImm(NewMB);
      MI.getOperand(4).setImm(NewME);
    }
    MI.getOperand(1).setReg(SrcMI->getOperand(1).getReg());
    if (SrcMI->getOperand(1).isKill()) {
      MI.getOperand(1).setIsKill(true);
      SrcMI->getOperand(1).setIsKill(false);
    } else
      // About to replace MI.getOperand(1), clear its kill flag.
      MI.getOperand(1).setIsKill(false);

    LLVM_DEBUG(dbgs() << "To: ");
    LLVM_DEBUG(MI.dump());
  }
  if (Simplified & MRI->use_nodbg_empty(FoldingReg) &&
      !SrcMI->hasImplicitDef()) {
    // If FoldingReg has no non-debug use and it has no implicit def (it
    // is not RLWINMO or RLWINM8o), it's safe to delete its def SrcMI.
    // Otherwise keep it.
    *ToErase = SrcMI;
    LLVM_DEBUG(dbgs() << "Delete dead instruction: ");
    LLVM_DEBUG(SrcMI->dump());
  }
  return Simplified;
}

bool PPCInstrInfo::instrHasImmForm(unsigned Opc, bool IsVFReg,
                                   ImmInstrInfo &III, bool PostRA) const {
  // The vast majority of the instructions would need their operand 2 replaced
  // with an immediate when switching to the reg+imm form. A marked exception
  // are the update form loads/stores for which a constant operand 2 would need
  // to turn into a displacement and move operand 1 to the operand 2 position.
  III.ImmOpNo = 2;
  III.OpNoForForwarding = 2;
  III.ImmWidth = 16;
  III.ImmMustBeMultipleOf = 1;
  III.TruncateImmTo = 0;
  III.IsSummingOperands = false;
  switch (Opc) {
  default: return false;
  case PPC::ADD4:
  case PPC::ADD8:
    III.SignedImm = true;
    III.ZeroIsSpecialOrig = 0;
    III.ZeroIsSpecialNew = 1;
    III.IsCommutative = true;
    III.IsSummingOperands = true;
    III.ImmOpcode = Opc == PPC::ADD4 ? PPC::ADDI : PPC::ADDI8;
    break;
  case PPC::ADDC:
  case PPC::ADDC8:
    III.SignedImm = true;
    III.ZeroIsSpecialOrig = 0;
    III.ZeroIsSpecialNew = 0;
    III.IsCommutative = true;
    III.IsSummingOperands = true;
    III.ImmOpcode = Opc == PPC::ADDC ? PPC::ADDIC : PPC::ADDIC8;
    break;
  case PPC::ADDC_rec:
    III.SignedImm = true;
    III.ZeroIsSpecialOrig = 0;
    III.ZeroIsSpecialNew = 0;
    III.IsCommutative = true;
    III.IsSummingOperands = true;
    III.ImmOpcode = PPC::ADDIC_rec;
    break;
  case PPC::SUBFC:
  case PPC::SUBFC8:
    III.SignedImm = true;
    III.ZeroIsSpecialOrig = 0;
    III.ZeroIsSpecialNew = 0;
    III.IsCommutative = false;
    III.ImmOpcode = Opc == PPC::SUBFC ? PPC::SUBFIC : PPC::SUBFIC8;
    break;
  case PPC::CMPW:
  case PPC::CMPD:
    III.SignedImm = true;
    III.ZeroIsSpecialOrig = 0;
    III.ZeroIsSpecialNew = 0;
    III.IsCommutative = false;
    III.ImmOpcode = Opc == PPC::CMPW ? PPC::CMPWI : PPC::CMPDI;
    break;
  case PPC::CMPLW:
  case PPC::CMPLD:
    III.SignedImm = false;
    III.ZeroIsSpecialOrig = 0;
    III.ZeroIsSpecialNew = 0;
    III.IsCommutative = false;
    III.ImmOpcode = Opc == PPC::CMPLW ? PPC::CMPLWI : PPC::CMPLDI;
    break;
  case PPC::AND_rec:
  case PPC::AND8_rec:
  case PPC::OR:
  case PPC::OR8:
  case PPC::XOR:
  case PPC::XOR8:
    III.SignedImm = false;
    III.ZeroIsSpecialOrig = 0;
    III.ZeroIsSpecialNew = 0;
    III.IsCommutative = true;
    switch(Opc) {
    default: llvm_unreachable("Unknown opcode");
    case PPC::AND_rec:
      III.ImmOpcode = PPC::ANDI_rec;
      break;
    case PPC::AND8_rec:
      III.ImmOpcode = PPC::ANDI8_rec;
      break;
    case PPC::OR: III.ImmOpcode = PPC::ORI; break;
    case PPC::OR8: III.ImmOpcode = PPC::ORI8; break;
    case PPC::XOR: III.ImmOpcode = PPC::XORI; break;
    case PPC::XOR8: III.ImmOpcode = PPC::XORI8; break;
    }
    break;
  case PPC::RLWNM:
  case PPC::RLWNM8:
  case PPC::RLWNM_rec:
  case PPC::RLWNM8_rec:
  case PPC::SLW:
  case PPC::SLW8:
  case PPC::SLW_rec:
  case PPC::SLW8_rec:
  case PPC::SRW:
  case PPC::SRW8:
  case PPC::SRW_rec:
  case PPC::SRW8_rec:
  case PPC::SRAW:
  case PPC::SRAW_rec:
    III.SignedImm = false;
    III.ZeroIsSpecialOrig = 0;
    III.ZeroIsSpecialNew = 0;
    III.IsCommutative = false;
    // This isn't actually true, but the instructions ignore any of the
    // upper bits, so any immediate loaded with an LI is acceptable.
    // This does not apply to shift right algebraic because a value
    // out of range will produce a -1/0.
    III.ImmWidth = 16;
    if (Opc == PPC::RLWNM || Opc == PPC::RLWNM8 || Opc == PPC::RLWNM_rec ||
        Opc == PPC::RLWNM8_rec)
      III.TruncateImmTo = 5;
    else
      III.TruncateImmTo = 6;
    switch(Opc) {
    default: llvm_unreachable("Unknown opcode");
    case PPC::RLWNM: III.ImmOpcode = PPC::RLWINM; break;
    case PPC::RLWNM8: III.ImmOpcode = PPC::RLWINM8; break;
    case PPC::RLWNM_rec:
      III.ImmOpcode = PPC::RLWINM_rec;
      break;
    case PPC::RLWNM8_rec:
      III.ImmOpcode = PPC::RLWINM8_rec;
      break;
    case PPC::SLW: III.ImmOpcode = PPC::RLWINM; break;
    case PPC::SLW8: III.ImmOpcode = PPC::RLWINM8; break;
    case PPC::SLW_rec:
      III.ImmOpcode = PPC::RLWINM_rec;
      break;
    case PPC::SLW8_rec:
      III.ImmOpcode = PPC::RLWINM8_rec;
      break;
    case PPC::SRW: III.ImmOpcode = PPC::RLWINM; break;
    case PPC::SRW8: III.ImmOpcode = PPC::RLWINM8; break;
    case PPC::SRW_rec:
      III.ImmOpcode = PPC::RLWINM_rec;
      break;
    case PPC::SRW8_rec:
      III.ImmOpcode = PPC::RLWINM8_rec;
      break;
    case PPC::SRAW:
      III.ImmWidth = 5;
      III.TruncateImmTo = 0;
      III.ImmOpcode = PPC::SRAWI;
      break;
    case PPC::SRAW_rec:
      III.ImmWidth = 5;
      III.TruncateImmTo = 0;
      III.ImmOpcode = PPC::SRAWI_rec;
      break;
    }
    break;
  case PPC::RLDCL:
  case PPC::RLDCL_rec:
  case PPC::RLDCR:
  case PPC::RLDCR_rec:
  case PPC::SLD:
  case PPC::SLD_rec:
  case PPC::SRD:
  case PPC::SRD_rec:
  case PPC::SRAD:
  case PPC::SRAD_rec:
    III.SignedImm = false;
    III.ZeroIsSpecialOrig = 0;
    III.ZeroIsSpecialNew = 0;
    III.IsCommutative = false;
    // This isn't actually true, but the instructions ignore any of the
    // upper bits, so any immediate loaded with an LI is acceptable.
    // This does not apply to shift right algebraic because a value
    // out of range will produce a -1/0.
    III.ImmWidth = 16;
    if (Opc == PPC::RLDCL || Opc == PPC::RLDCL_rec || Opc == PPC::RLDCR ||
        Opc == PPC::RLDCR_rec)
      III.TruncateImmTo = 6;
    else
      III.TruncateImmTo = 7;
    switch(Opc) {
    default: llvm_unreachable("Unknown opcode");
    case PPC::RLDCL: III.ImmOpcode = PPC::RLDICL; break;
    case PPC::RLDCL_rec:
      III.ImmOpcode = PPC::RLDICL_rec;
      break;
    case PPC::RLDCR: III.ImmOpcode = PPC::RLDICR; break;
    case PPC::RLDCR_rec:
      III.ImmOpcode = PPC::RLDICR_rec;
      break;
    case PPC::SLD: III.ImmOpcode = PPC::RLDICR; break;
    case PPC::SLD_rec:
      III.ImmOpcode = PPC::RLDICR_rec;
      break;
    case PPC::SRD: III.ImmOpcode = PPC::RLDICL; break;
    case PPC::SRD_rec:
      III.ImmOpcode = PPC::RLDICL_rec;
      break;
    case PPC::SRAD:
      III.ImmWidth = 6;
      III.TruncateImmTo = 0;
      III.ImmOpcode = PPC::SRADI;
       break;
    case PPC::SRAD_rec:
      III.ImmWidth = 6;
      III.TruncateImmTo = 0;
      III.ImmOpcode = PPC::SRADI_rec;
      break;
    }
    break;
  // Loads and stores:
  case PPC::LBZX:
  case PPC::LBZX8:
  case PPC::LHZX:
  case PPC::LHZX8:
  case PPC::LHAX:
  case PPC::LHAX8:
  case PPC::LWZX:
  case PPC::LWZX8:
  case PPC::LWAX:
  case PPC::LDX:
  case PPC::LFSX:
  case PPC::LFDX:
  case PPC::STBX:
  case PPC::STBX8:
  case PPC::STHX:
  case PPC::STHX8:
  case PPC::STWX:
  case PPC::STWX8:
  case PPC::STDX:
  case PPC::STFSX:
  case PPC::STFDX:
    III.SignedImm = true;
    III.ZeroIsSpecialOrig = 1;
    III.ZeroIsSpecialNew = 2;
    III.IsCommutative = true;
    III.IsSummingOperands = true;
    III.ImmOpNo = 1;
    III.OpNoForForwarding = 2;
    switch(Opc) {
    default: llvm_unreachable("Unknown opcode");
    case PPC::LBZX: III.ImmOpcode = PPC::LBZ; break;
    case PPC::LBZX8: III.ImmOpcode = PPC::LBZ8; break;
    case PPC::LHZX: III.ImmOpcode = PPC::LHZ; break;
    case PPC::LHZX8: III.ImmOpcode = PPC::LHZ8; break;
    case PPC::LHAX: III.ImmOpcode = PPC::LHA; break;
    case PPC::LHAX8: III.ImmOpcode = PPC::LHA8; break;
    case PPC::LWZX: III.ImmOpcode = PPC::LWZ; break;
    case PPC::LWZX8: III.ImmOpcode = PPC::LWZ8; break;
    case PPC::LWAX:
      III.ImmOpcode = PPC::LWA;
      III.ImmMustBeMultipleOf = 4;
      break;
    case PPC::LDX: III.ImmOpcode = PPC::LD; III.ImmMustBeMultipleOf = 4; break;
    case PPC::LFSX: III.ImmOpcode = PPC::LFS; break;
    case PPC::LFDX: III.ImmOpcode = PPC::LFD; break;
    case PPC::STBX: III.ImmOpcode = PPC::STB; break;
    case PPC::STBX8: III.ImmOpcode = PPC::STB8; break;
    case PPC::STHX: III.ImmOpcode = PPC::STH; break;
    case PPC::STHX8: III.ImmOpcode = PPC::STH8; break;
    case PPC::STWX: III.ImmOpcode = PPC::STW; break;
    case PPC::STWX8: III.ImmOpcode = PPC::STW8; break;
    case PPC::STDX:
      III.ImmOpcode = PPC::STD;
      III.ImmMustBeMultipleOf = 4;
      break;
    case PPC::STFSX: III.ImmOpcode = PPC::STFS; break;
    case PPC::STFDX: III.ImmOpcode = PPC::STFD; break;
    }
    break;
  case PPC::LBZUX:
  case PPC::LBZUX8:
  case PPC::LHZUX:
  case PPC::LHZUX8:
  case PPC::LHAUX:
  case PPC::LHAUX8:
  case PPC::LWZUX:
  case PPC::LWZUX8:
  case PPC::LDUX:
  case PPC::LFSUX:
  case PPC::LFDUX:
  case PPC::STBUX:
  case PPC::STBUX8:
  case PPC::STHUX:
  case PPC::STHUX8:
  case PPC::STWUX:
  case PPC::STWUX8:
  case PPC::STDUX:
  case PPC::STFSUX:
  case PPC::STFDUX:
    III.SignedImm = true;
    III.ZeroIsSpecialOrig = 2;
    III.ZeroIsSpecialNew = 3;
    III.IsCommutative = false;
    III.IsSummingOperands = true;
    III.ImmOpNo = 2;
    III.OpNoForForwarding = 3;
    switch(Opc) {
    default: llvm_unreachable("Unknown opcode");
    case PPC::LBZUX: III.ImmOpcode = PPC::LBZU; break;
    case PPC::LBZUX8: III.ImmOpcode = PPC::LBZU8; break;
    case PPC::LHZUX: III.ImmOpcode = PPC::LHZU; break;
    case PPC::LHZUX8: III.ImmOpcode = PPC::LHZU8; break;
    case PPC::LHAUX: III.ImmOpcode = PPC::LHAU; break;
    case PPC::LHAUX8: III.ImmOpcode = PPC::LHAU8; break;
    case PPC::LWZUX: III.ImmOpcode = PPC::LWZU; break;
    case PPC::LWZUX8: III.ImmOpcode = PPC::LWZU8; break;
    case PPC::LDUX:
      III.ImmOpcode = PPC::LDU;
      III.ImmMustBeMultipleOf = 4;
      break;
    case PPC::LFSUX: III.ImmOpcode = PPC::LFSU; break;
    case PPC::LFDUX: III.ImmOpcode = PPC::LFDU; break;
    case PPC::STBUX: III.ImmOpcode = PPC::STBU; break;
    case PPC::STBUX8: III.ImmOpcode = PPC::STBU8; break;
    case PPC::STHUX: III.ImmOpcode = PPC::STHU; break;
    case PPC::STHUX8: III.ImmOpcode = PPC::STHU8; break;
    case PPC::STWUX: III.ImmOpcode = PPC::STWU; break;
    case PPC::STWUX8: III.ImmOpcode = PPC::STWU8; break;
    case PPC::STDUX:
      III.ImmOpcode = PPC::STDU;
      III.ImmMustBeMultipleOf = 4;
      break;
    case PPC::STFSUX: III.ImmOpcode = PPC::STFSU; break;
    case PPC::STFDUX: III.ImmOpcode = PPC::STFDU; break;
    }
    break;
  // Power9 and up only. For some of these, the X-Form version has access to all
  // 64 VSR's whereas the D-Form only has access to the VR's. We replace those
  // with pseudo-ops pre-ra and for post-ra, we check that the register loaded
  // into or stored from is one of the VR registers.
  case PPC::LXVX:
  case PPC::LXSSPX:
  case PPC::LXSDX:
  case PPC::STXVX:
  case PPC::STXSSPX:
  case PPC::STXSDX:
  case PPC::XFLOADf32:
  case PPC::XFLOADf64:
  case PPC::XFSTOREf32:
  case PPC::XFSTOREf64:
    if (!Subtarget.hasP9Vector())
      return false;
    III.SignedImm = true;
    III.ZeroIsSpecialOrig = 1;
    III.ZeroIsSpecialNew = 2;
    III.IsCommutative = true;
    III.IsSummingOperands = true;
    III.ImmOpNo = 1;
    III.OpNoForForwarding = 2;
    III.ImmMustBeMultipleOf = 4;
    switch(Opc) {
    default: llvm_unreachable("Unknown opcode");
    case PPC::LXVX:
      III.ImmOpcode = PPC::LXV;
      III.ImmMustBeMultipleOf = 16;
      break;
    case PPC::LXSSPX:
      if (PostRA) {
        if (IsVFReg)
          III.ImmOpcode = PPC::LXSSP;
        else {
          III.ImmOpcode = PPC::LFS;
          III.ImmMustBeMultipleOf = 1;
        }
        break;
      }
      LLVM_FALLTHROUGH;
    case PPC::XFLOADf32:
      III.ImmOpcode = PPC::DFLOADf32;
      break;
    case PPC::LXSDX:
      if (PostRA) {
        if (IsVFReg)
          III.ImmOpcode = PPC::LXSD;
        else {
          III.ImmOpcode = PPC::LFD;
          III.ImmMustBeMultipleOf = 1;
        }
        break;
      }
      LLVM_FALLTHROUGH;
    case PPC::XFLOADf64:
      III.ImmOpcode = PPC::DFLOADf64;
      break;
    case PPC::STXVX:
      III.ImmOpcode = PPC::STXV;
      III.ImmMustBeMultipleOf = 16;
      break;
    case PPC::STXSSPX:
      if (PostRA) {
        if (IsVFReg)
          III.ImmOpcode = PPC::STXSSP;
        else {
          III.ImmOpcode = PPC::STFS;
          III.ImmMustBeMultipleOf = 1;
        }
        break;
      }
      LLVM_FALLTHROUGH;
    case PPC::XFSTOREf32:
      III.ImmOpcode = PPC::DFSTOREf32;
      break;
    case PPC::STXSDX:
      if (PostRA) {
        if (IsVFReg)
          III.ImmOpcode = PPC::STXSD;
        else {
          III.ImmOpcode = PPC::STFD;
          III.ImmMustBeMultipleOf = 1;
        }
        break;
      }
      LLVM_FALLTHROUGH;
    case PPC::XFSTOREf64:
      III.ImmOpcode = PPC::DFSTOREf64;
      break;
    }
    break;
  }
  return true;
}

// Utility function for swaping two arbitrary operands of an instruction.
static void swapMIOperands(MachineInstr &MI, unsigned Op1, unsigned Op2) {
  assert(Op1 != Op2 && "Cannot swap operand with itself.");

  unsigned MaxOp = std::max(Op1, Op2);
  unsigned MinOp = std::min(Op1, Op2);
  MachineOperand MOp1 = MI.getOperand(MinOp);
  MachineOperand MOp2 = MI.getOperand(MaxOp);
  MI.RemoveOperand(std::max(Op1, Op2));
  MI.RemoveOperand(std::min(Op1, Op2));

  // If the operands we are swapping are the two at the end (the common case)
  // we can just remove both and add them in the opposite order.
  if (MaxOp - MinOp == 1 && MI.getNumOperands() == MinOp) {
    MI.addOperand(MOp2);
    MI.addOperand(MOp1);
  } else {
    // Store all operands in a temporary vector, remove them and re-add in the
    // right order.
    SmallVector<MachineOperand, 2> MOps;
    unsigned TotalOps = MI.getNumOperands() + 2; // We've already removed 2 ops.
    for (unsigned i = MI.getNumOperands() - 1; i >= MinOp; i--) {
      MOps.push_back(MI.getOperand(i));
      MI.RemoveOperand(i);
    }
    // MOp2 needs to be added next.
    MI.addOperand(MOp2);
    // Now add the rest.
    for (unsigned i = MI.getNumOperands(); i < TotalOps; i++) {
      if (i == MaxOp)
        MI.addOperand(MOp1);
      else {
        MI.addOperand(MOps.back());
        MOps.pop_back();
      }
    }
  }
}

// Check if the 'MI' that has the index OpNoForForwarding
// meets the requirement described in the ImmInstrInfo.
bool PPCInstrInfo::isUseMIElgibleForForwarding(MachineInstr &MI,
                                               const ImmInstrInfo &III,
                                               unsigned OpNoForForwarding
                                               ) const {
  // As the algorithm of checking for PPC::ZERO/PPC::ZERO8
  // would not work pre-RA, we can only do the check post RA.
  MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
  if (MRI.isSSA())
    return false;

  // Cannot do the transform if MI isn't summing the operands.
  if (!III.IsSummingOperands)
    return false;

  // The instruction we are trying to replace must have the ZeroIsSpecialOrig set.
  if (!III.ZeroIsSpecialOrig)
    return false;

  // We cannot do the transform if the operand we are trying to replace
  // isn't the same as the operand the instruction allows.
  if (OpNoForForwarding != III.OpNoForForwarding)
    return false;

  // Check if the instruction we are trying to transform really has
  // the special zero register as its operand.
  if (MI.getOperand(III.ZeroIsSpecialOrig).getReg() != PPC::ZERO &&
      MI.getOperand(III.ZeroIsSpecialOrig).getReg() != PPC::ZERO8)
    return false;

  // This machine instruction is convertible if it is,
  // 1. summing the operands.
  // 2. one of the operands is special zero register.
  // 3. the operand we are trying to replace is allowed by the MI.
  return true;
}

// Check if the DefMI is the add inst and set the ImmMO and RegMO
// accordingly.
bool PPCInstrInfo::isDefMIElgibleForForwarding(MachineInstr &DefMI,
                                               const ImmInstrInfo &III,
                                               MachineOperand *&ImmMO,
                                               MachineOperand *&RegMO) const {
  unsigned Opc = DefMI.getOpcode();
  if (Opc != PPC::ADDItocL && Opc != PPC::ADDI && Opc != PPC::ADDI8)
    return false;

  assert(DefMI.getNumOperands() >= 3 &&
         "Add inst must have at least three operands");
  RegMO = &DefMI.getOperand(1);
  ImmMO = &DefMI.getOperand(2);

  // Before RA, ADDI first operand could be a frame index.
  if (!RegMO->isReg())
    return false;

  // This DefMI is elgible for forwarding if it is:
  // 1. add inst
  // 2. one of the operands is Imm/CPI/Global.
  return isAnImmediateOperand(*ImmMO);
}

bool PPCInstrInfo::isRegElgibleForForwarding(
    const MachineOperand &RegMO, const MachineInstr &DefMI,
    const MachineInstr &MI, bool KillDefMI,
    bool &IsFwdFeederRegKilled) const {
  // x = addi y, imm
  // ...
  // z = lfdx 0, x   -> z = lfd imm(y)
  // The Reg "y" can be forwarded to the MI(z) only when there is no DEF
  // of "y" between the DEF of "x" and "z".
  // The query is only valid post RA.
  const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
  if (MRI.isSSA())
    return false;

  Register Reg = RegMO.getReg();

  // Walking the inst in reverse(MI-->DefMI) to get the last DEF of the Reg.
  MachineBasicBlock::const_reverse_iterator It = MI;
  MachineBasicBlock::const_reverse_iterator E = MI.getParent()->rend();
  It++;
  for (; It != E; ++It) {
    if (It->modifiesRegister(Reg, &getRegisterInfo()) && (&*It) != &DefMI)
      return false;
    else if (It->killsRegister(Reg, &getRegisterInfo()) && (&*It) != &DefMI)
      IsFwdFeederRegKilled = true;
    // Made it to DefMI without encountering a clobber.
    if ((&*It) == &DefMI)
      break;
  }
  assert((&*It) == &DefMI && "DefMI is missing");

  // If DefMI also defines the register to be forwarded, we can only forward it
  // if DefMI is being erased.
  if (DefMI.modifiesRegister(Reg, &getRegisterInfo()))
    return KillDefMI;

  return true;
}

bool PPCInstrInfo::isImmElgibleForForwarding(const MachineOperand &ImmMO,
                                             const MachineInstr &DefMI,
                                             const ImmInstrInfo &III,
                                             int64_t &Imm,
                                             int64_t BaseImm) const {
  assert(isAnImmediateOperand(ImmMO) && "ImmMO is NOT an immediate");
  if (DefMI.getOpcode() == PPC::ADDItocL) {
    // The operand for ADDItocL is CPI, which isn't imm at compiling time,
    // However, we know that, it is 16-bit width, and has the alignment of 4.
    // Check if the instruction met the requirement.
    if (III.ImmMustBeMultipleOf > 4 ||
       III.TruncateImmTo || III.ImmWidth != 16)
      return false;

    // Going from XForm to DForm loads means that the displacement needs to be
    // not just an immediate but also a multiple of 4, or 16 depending on the
    // load. A DForm load cannot be represented if it is a multiple of say 2.
    // XForm loads do not have this restriction.
    if (ImmMO.isGlobal()) {
      const DataLayout &DL = ImmMO.getGlobal()->getParent()->getDataLayout();
      if (ImmMO.getGlobal()->getPointerAlignment(DL) < III.ImmMustBeMultipleOf)
        return false;
    }

    return true;
  }

  if (ImmMO.isImm()) {
    // It is Imm, we need to check if the Imm fit the range.
    // Sign-extend to 64-bits.
    // DefMI may be folded with another imm form instruction, the result Imm is
    // the sum of Imm of DefMI and BaseImm which is from imm form instruction.
    APInt ActualValue(64, ImmMO.getImm() + BaseImm, true);
    if (III.SignedImm && !ActualValue.isSignedIntN(III.ImmWidth))
      return false;
    if (!III.SignedImm && !ActualValue.isIntN(III.ImmWidth))
      return false;
    Imm = SignExtend64<16>(ImmMO.getImm() + BaseImm);

    if (Imm % III.ImmMustBeMultipleOf)
      return false;
    if (III.TruncateImmTo)
      Imm &= ((1 << III.TruncateImmTo) - 1);
  }
  else
    return false;

  // This ImmMO is forwarded if it meets the requriement describle
  // in ImmInstrInfo
  return true;
}

bool PPCInstrInfo::simplifyToLI(MachineInstr &MI, MachineInstr &DefMI,
                                unsigned OpNoForForwarding,
                                MachineInstr **KilledDef) const {
  if ((DefMI.getOpcode() != PPC::LI && DefMI.getOpcode() != PPC::LI8) ||
      !DefMI.getOperand(1).isImm())
    return false;

  MachineFunction *MF = MI.getParent()->getParent();
  MachineRegisterInfo *MRI = &MF->getRegInfo();
  bool PostRA = !MRI->isSSA();

  int64_t Immediate = DefMI.getOperand(1).getImm();
  // Sign-extend to 64-bits.
  int64_t SExtImm = SignExtend64<16>(Immediate);

  bool IsForwardingOperandKilled = MI.getOperand(OpNoForForwarding).isKill();
  Register ForwardingOperandReg = MI.getOperand(OpNoForForwarding).getReg();

  bool ReplaceWithLI = false;
  bool Is64BitLI = false;
  int64_t NewImm = 0;
  bool SetCR = false;
  unsigned Opc = MI.getOpcode();
  switch (Opc) {
  default:
    return false;

  // FIXME: Any branches conditional on such a comparison can be made
  // unconditional. At this time, this happens too infrequently to be worth
  // the implementation effort, but if that ever changes, we could convert
  // such a pattern here.
  case PPC::CMPWI:
  case PPC::CMPLWI:
  case PPC::CMPDI:
  case PPC::CMPLDI: {
    // Doing this post-RA would require dataflow analysis to reliably find uses
    // of the CR register set by the compare.
    // No need to fixup killed/dead flag since this transformation is only valid
    // before RA.
    if (PostRA)
      return false;
    // If a compare-immediate is fed by an immediate and is itself an input of
    // an ISEL (the most common case) into a COPY of the correct register.
    bool Changed = false;
    Register DefReg = MI.getOperand(0).getReg();
    int64_t Comparand = MI.getOperand(2).getImm();
    int64_t SExtComparand = ((uint64_t)Comparand & ~0x7FFFuLL) != 0
                                ? (Comparand | 0xFFFFFFFFFFFF0000)
                                : Comparand;

    for (auto &CompareUseMI : MRI->use_instructions(DefReg)) {
      unsigned UseOpc = CompareUseMI.getOpcode();
      if (UseOpc != PPC::ISEL && UseOpc != PPC::ISEL8)
        continue;
      unsigned CRSubReg = CompareUseMI.getOperand(3).getSubReg();
      Register TrueReg = CompareUseMI.getOperand(1).getReg();
      Register FalseReg = CompareUseMI.getOperand(2).getReg();
      unsigned RegToCopy =
          selectReg(SExtImm, SExtComparand, Opc, TrueReg, FalseReg, CRSubReg);
      if (RegToCopy == PPC::NoRegister)
        continue;
      // Can't use PPC::COPY to copy PPC::ZERO[8]. Convert it to LI[8] 0.
      if (RegToCopy == PPC::ZERO || RegToCopy == PPC::ZERO8) {
        CompareUseMI.setDesc(get(UseOpc == PPC::ISEL8 ? PPC::LI8 : PPC::LI));
        replaceInstrOperandWithImm(CompareUseMI, 1, 0);
        CompareUseMI.RemoveOperand(3);
        CompareUseMI.RemoveOperand(2);
        continue;
      }
      LLVM_DEBUG(
          dbgs() << "Found LI -> CMPI -> ISEL, replacing with a copy.\n");
      LLVM_DEBUG(DefMI.dump(); MI.dump(); CompareUseMI.dump());
      LLVM_DEBUG(dbgs() << "Is converted to:\n");
      // Convert to copy and remove unneeded operands.
      CompareUseMI.setDesc(get(PPC::COPY));
      CompareUseMI.RemoveOperand(3);
      CompareUseMI.RemoveOperand(RegToCopy == TrueReg ? 2 : 1);
      CmpIselsConverted++;
      Changed = true;
      LLVM_DEBUG(CompareUseMI.dump());
    }
    if (Changed)
      return true;
    // This may end up incremented multiple times since this function is called
    // during a fixed-point transformation, but it is only meant to indicate the
    // presence of this opportunity.
    MissedConvertibleImmediateInstrs++;
    return false;
  }

  // Immediate forms - may simply be convertable to an LI.
  case PPC::ADDI:
  case PPC::ADDI8: {
    // Does the sum fit in a 16-bit signed field?
    int64_t Addend = MI.getOperand(2).getImm();
    if (isInt<16>(Addend + SExtImm)) {
      ReplaceWithLI = true;
      Is64BitLI = Opc == PPC::ADDI8;
      NewImm = Addend + SExtImm;
      break;
    }
    return false;
  }
  case PPC::SUBFIC:
  case PPC::SUBFIC8: {
    // Only transform this if the CARRY implicit operand is dead.
    if (MI.getNumOperands() > 3 && !MI.getOperand(3).isDead())
      return false;
    int64_t Minuend = MI.getOperand(2).getImm();
    if (isInt<16>(Minuend - SExtImm)) {
      ReplaceWithLI = true;
      Is64BitLI = Opc == PPC::SUBFIC8;
      NewImm = Minuend - SExtImm;
      break;
    }
    return false;
  }
  case PPC::RLDICL:
  case PPC::RLDICL_rec:
  case PPC::RLDICL_32:
  case PPC::RLDICL_32_64: {
    // Use APInt's rotate function.
    int64_t SH = MI.getOperand(2).getImm();
    int64_t MB = MI.getOperand(3).getImm();
    APInt InVal((Opc == PPC::RLDICL || Opc == PPC::RLDICL_rec) ? 64 : 32,
                SExtImm, true);
    InVal = InVal.rotl(SH);
    uint64_t Mask = MB == 0 ? -1LLU : (1LLU << (63 - MB + 1)) - 1;
    InVal &= Mask;
    // Can't replace negative values with an LI as that will sign-extend
    // and not clear the left bits. If we're setting the CR bit, we will use
    // ANDI_rec which won't sign extend, so that's safe.
    if (isUInt<15>(InVal.getSExtValue()) ||
        (Opc == PPC::RLDICL_rec && isUInt<16>(InVal.getSExtValue()))) {
      ReplaceWithLI = true;
      Is64BitLI = Opc != PPC::RLDICL_32;
      NewImm = InVal.getSExtValue();
      SetCR = Opc == PPC::RLDICL_rec;
      break;
    }
    return false;
  }
  case PPC::RLWINM:
  case PPC::RLWINM8:
  case PPC::RLWINM_rec:
  case PPC::RLWINM8_rec: {
    int64_t SH = MI.getOperand(2).getImm();
    int64_t MB = MI.getOperand(3).getImm();
    int64_t ME = MI.getOperand(4).getImm();
    APInt InVal(32, SExtImm, true);
    InVal = InVal.rotl(SH);
    APInt Mask = APInt::getBitsSetWithWrap(32, 32 - ME - 1, 32 - MB);
    InVal &= Mask;
    // Can't replace negative values with an LI as that will sign-extend
    // and not clear the left bits. If we're setting the CR bit, we will use
    // ANDI_rec which won't sign extend, so that's safe.
    bool ValueFits = isUInt<15>(InVal.getSExtValue());
    ValueFits |= ((Opc == PPC::RLWINM_rec || Opc == PPC::RLWINM8_rec) &&
                  isUInt<16>(InVal.getSExtValue()));
    if (ValueFits) {
      ReplaceWithLI = true;
      Is64BitLI = Opc == PPC::RLWINM8 || Opc == PPC::RLWINM8_rec;
      NewImm = InVal.getSExtValue();
      SetCR = Opc == PPC::RLWINM_rec || Opc == PPC::RLWINM8_rec;
      break;
    }
    return false;
  }
  case PPC::ORI:
  case PPC::ORI8:
  case PPC::XORI:
  case PPC::XORI8: {
    int64_t LogicalImm = MI.getOperand(2).getImm();
    int64_t Result = 0;
    if (Opc == PPC::ORI || Opc == PPC::ORI8)
      Result = LogicalImm | SExtImm;
    else
      Result = LogicalImm ^ SExtImm;
    if (isInt<16>(Result)) {
      ReplaceWithLI = true;
      Is64BitLI = Opc == PPC::ORI8 || Opc == PPC::XORI8;
      NewImm = Result;
      break;
    }
    return false;
  }
  }

  if (ReplaceWithLI) {
    // We need to be careful with CR-setting instructions we're replacing.
    if (SetCR) {
      // We don't know anything about uses when we're out of SSA, so only
      // replace if the new immediate will be reproduced.
      bool ImmChanged = (SExtImm & NewImm) != NewImm;
      if (PostRA && ImmChanged)
        return false;

      if (!PostRA) {
        // If the defining load-immediate has no other uses, we can just replace
        // the immediate with the new immediate.
        if (MRI->hasOneUse(DefMI.getOperand(0).getReg()))
          DefMI.getOperand(1).setImm(NewImm);

        // If we're not using the GPR result of the CR-setting instruction, we
        // just need to and with zero/non-zero depending on the new immediate.
        else if (MRI->use_empty(MI.getOperand(0).getReg())) {
          if (NewImm) {
            assert(Immediate && "Transformation converted zero to non-zero?");
            NewImm = Immediate;
          }
        } else if (ImmChanged)
          return false;
      }
    }

    LLVM_DEBUG(dbgs() << "Replacing instruction:\n");
    LLVM_DEBUG(MI.dump());
    LLVM_DEBUG(dbgs() << "Fed by:\n");
    LLVM_DEBUG(DefMI.dump());
    LoadImmediateInfo LII;
    LII.Imm = NewImm;
    LII.Is64Bit = Is64BitLI;
    LII.SetCR = SetCR;
    // If we're setting the CR, the original load-immediate must be kept (as an
    // operand to ANDI_rec/ANDI8_rec).
    if (KilledDef && SetCR)
      *KilledDef = nullptr;
    replaceInstrWithLI(MI, LII);

    // Fixup killed/dead flag after transformation.
    // Pattern:
    // ForwardingOperandReg = LI imm1
    // y = op2 imm2, ForwardingOperandReg(killed)
    if (IsForwardingOperandKilled)
      fixupIsDeadOrKill(&DefMI, &MI, ForwardingOperandReg);

    LLVM_DEBUG(dbgs() << "With:\n");
    LLVM_DEBUG(MI.dump());
    return true;
  }
  return false;
}

bool PPCInstrInfo::transformToNewImmFormFedByAdd(
    MachineInstr &MI, MachineInstr &DefMI, unsigned OpNoForForwarding) const {
  MachineRegisterInfo *MRI = &MI.getParent()->getParent()->getRegInfo();
  bool PostRA = !MRI->isSSA();
  // FIXME: extend this to post-ra. Need to do some change in getForwardingDefMI
  // for post-ra.
  if (PostRA)
    return false;

  // Only handle load/store.
  if (!MI.mayLoadOrStore())
    return false;

  unsigned XFormOpcode = RI.getMappedIdxOpcForImmOpc(MI.getOpcode());

  assert((XFormOpcode != PPC::INSTRUCTION_LIST_END) &&
         "MI must have x-form opcode");

  // get Imm Form info.
  ImmInstrInfo III;
  bool IsVFReg = MI.getOperand(0).isReg()
                     ? isVFRegister(MI.getOperand(0).getReg())
                     : false;

  if (!instrHasImmForm(XFormOpcode, IsVFReg, III, PostRA))
    return false;

  if (!III.IsSummingOperands)
    return false;

  if (OpNoForForwarding != III.OpNoForForwarding)
    return false;

  MachineOperand ImmOperandMI = MI.getOperand(III.ImmOpNo);
  if (!ImmOperandMI.isImm())
    return false;

  // Check DefMI.
  MachineOperand *ImmMO = nullptr;
  MachineOperand *RegMO = nullptr;
  if (!isDefMIElgibleForForwarding(DefMI, III, ImmMO, RegMO))
    return false;
  assert(ImmMO && RegMO && "Imm and Reg operand must have been set");

  // Check Imm.
  // Set ImmBase from imm instruction as base and get new Imm inside
  // isImmElgibleForForwarding.
  int64_t ImmBase = ImmOperandMI.getImm();
  int64_t Imm = 0;
  if (!isImmElgibleForForwarding(*ImmMO, DefMI, III, Imm, ImmBase))
    return false;

  // Get killed info in case fixup needed after transformation.
  unsigned ForwardKilledOperandReg = ~0U;
  if (MI.getOperand(III.OpNoForForwarding).isKill())
    ForwardKilledOperandReg = MI.getOperand(III.OpNoForForwarding).getReg();

  // Do the transform
  LLVM_DEBUG(dbgs() << "Replacing instruction:\n");
  LLVM_DEBUG(MI.dump());
  LLVM_DEBUG(dbgs() << "Fed by:\n");
  LLVM_DEBUG(DefMI.dump());

  MI.getOperand(III.OpNoForForwarding).setReg(RegMO->getReg());
  MI.getOperand(III.OpNoForForwarding).setIsKill(RegMO->isKill());
  MI.getOperand(III.ImmOpNo).setImm(Imm);

  // FIXME: fix kill/dead flag if MI and DefMI are not in same basic block.
  if (DefMI.getParent() == MI.getParent()) {
    // Check if reg is killed between MI and DefMI.
    auto IsKilledFor = [&](unsigned Reg) {
      MachineBasicBlock::const_reverse_iterator It = MI;
      MachineBasicBlock::const_reverse_iterator E = DefMI;
      It++;
      for (; It != E; ++It) {
        if (It->killsRegister(Reg))
          return true;
      }
      return false;
    };

    // Update kill flag
    if (RegMO->isKill() || IsKilledFor(RegMO->getReg()))
      fixupIsDeadOrKill(&DefMI, &MI, RegMO->getReg());
    if (ForwardKilledOperandReg != ~0U)
      fixupIsDeadOrKill(&DefMI, &MI, ForwardKilledOperandReg);
  }

  LLVM_DEBUG(dbgs() << "With:\n");
  LLVM_DEBUG(MI.dump());
  return true;
}

// If an X-Form instruction is fed by an add-immediate and one of its operands
// is the literal zero, attempt to forward the source of the add-immediate to
// the corresponding D-Form instruction with the displacement coming from
// the immediate being added.
bool PPCInstrInfo::transformToImmFormFedByAdd(
    MachineInstr &MI, const ImmInstrInfo &III, unsigned OpNoForForwarding,
    MachineInstr &DefMI, bool KillDefMI) const {
  //         RegMO ImmMO
  //           |    |
  // x = addi reg, imm  <----- DefMI
  // y = op    0 ,  x   <----- MI
  //                |
  //         OpNoForForwarding
  // Check if the MI meet the requirement described in the III.
  if (!isUseMIElgibleForForwarding(MI, III, OpNoForForwarding))
    return false;

  // Check if the DefMI meet the requirement
  // described in the III. If yes, set the ImmMO and RegMO accordingly.
  MachineOperand *ImmMO = nullptr;
  MachineOperand *RegMO = nullptr;
  if (!isDefMIElgibleForForwarding(DefMI, III, ImmMO, RegMO))
    return false;
  assert(ImmMO && RegMO && "Imm and Reg operand must have been set");

  // As we get the Imm operand now, we need to check if the ImmMO meet
  // the requirement described in the III. If yes set the Imm.
  int64_t Imm = 0;
  if (!isImmElgibleForForwarding(*ImmMO, DefMI, III, Imm))
    return false;

  bool IsFwdFeederRegKilled = false;
  // Check if the RegMO can be forwarded to MI.
  if (!isRegElgibleForForwarding(*RegMO, DefMI, MI, KillDefMI,
                                 IsFwdFeederRegKilled))
    return false;

  // Get killed info in case fixup needed after transformation.
  unsigned ForwardKilledOperandReg = ~0U;
  MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
  bool PostRA = !MRI.isSSA();
  if (PostRA && MI.getOperand(OpNoForForwarding).isKill())
    ForwardKilledOperandReg = MI.getOperand(OpNoForForwarding).getReg();

  // We know that, the MI and DefMI both meet the pattern, and
  // the Imm also meet the requirement with the new Imm-form.
  // It is safe to do the transformation now.
  LLVM_DEBUG(dbgs() << "Replacing instruction:\n");
  LLVM_DEBUG(MI.dump());
  LLVM_DEBUG(dbgs() << "Fed by:\n");
  LLVM_DEBUG(DefMI.dump());

  // Update the base reg first.
  MI.getOperand(III.OpNoForForwarding).ChangeToRegister(RegMO->getReg(),
                                                        false, false,
                                                        RegMO->isKill());

  // Then, update the imm.
  if (ImmMO->isImm()) {
    // If the ImmMO is Imm, change the operand that has ZERO to that Imm
    // directly.
    replaceInstrOperandWithImm(MI, III.ZeroIsSpecialOrig, Imm);
  }
  else {
    // Otherwise, it is Constant Pool Index(CPI) or Global,
    // which is relocation in fact. We need to replace the special zero
    // register with ImmMO.
    // Before that, we need to fixup the target flags for imm.
    // For some reason, we miss to set the flag for the ImmMO if it is CPI.
    if (DefMI.getOpcode() == PPC::ADDItocL)
      ImmMO->setTargetFlags(PPCII::MO_TOC_LO);

    // MI didn't have the interface such as MI.setOperand(i) though
    // it has MI.getOperand(i). To repalce the ZERO MachineOperand with
    // ImmMO, we need to remove ZERO operand and all the operands behind it,
    // and, add the ImmMO, then, move back all the operands behind ZERO.
    SmallVector<MachineOperand, 2> MOps;
    for (unsigned i = MI.getNumOperands() - 1; i >= III.ZeroIsSpecialOrig; i--) {
      MOps.push_back(MI.getOperand(i));
      MI.RemoveOperand(i);
    }

    // Remove the last MO in the list, which is ZERO operand in fact.
    MOps.pop_back();
    // Add the imm operand.
    MI.addOperand(*ImmMO);
    // Now add the rest back.
    for (auto &MO : MOps)
      MI.addOperand(MO);
  }

  // Update the opcode.
  MI.setDesc(get(III.ImmOpcode));

  // Fix up killed/dead flag after transformation.
  // Pattern 1:
  // x = ADD KilledFwdFeederReg, imm
  // n = opn KilledFwdFeederReg(killed), regn
  // y = XOP 0, x
  // Pattern 2:
  // x = ADD reg(killed), imm
  // y = XOP 0, x
  if (IsFwdFeederRegKilled || RegMO->isKill())
    fixupIsDeadOrKill(&DefMI, &MI, RegMO->getReg());
  // Pattern 3:
  // ForwardKilledOperandReg = ADD reg, imm
  // y = XOP 0, ForwardKilledOperandReg(killed)
  if (ForwardKilledOperandReg != ~0U)
    fixupIsDeadOrKill(&DefMI, &MI, ForwardKilledOperandReg);

  LLVM_DEBUG(dbgs() << "With:\n");
  LLVM_DEBUG(MI.dump());

  return true;
}

bool PPCInstrInfo::transformToImmFormFedByLI(MachineInstr &MI,
                                             const ImmInstrInfo &III,
                                             unsigned ConstantOpNo,
                                             MachineInstr &DefMI) const {
  // DefMI must be LI or LI8.
  if ((DefMI.getOpcode() != PPC::LI && DefMI.getOpcode() != PPC::LI8) ||
      !DefMI.getOperand(1).isImm())
    return false;

  // Get Imm operand and Sign-extend to 64-bits.
  int64_t Imm = SignExtend64<16>(DefMI.getOperand(1).getImm());

  MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
  bool PostRA = !MRI.isSSA();
  // Exit early if we can't convert this.
  if ((ConstantOpNo != III.OpNoForForwarding) && !III.IsCommutative)
    return false;
  if (Imm % III.ImmMustBeMultipleOf)
    return false;
  if (III.TruncateImmTo)
    Imm &= ((1 << III.TruncateImmTo) - 1);
  if (III.SignedImm) {
    APInt ActualValue(64, Imm, true);
    if (!ActualValue.isSignedIntN(III.ImmWidth))
      return false;
  } else {
    uint64_t UnsignedMax = (1 << III.ImmWidth) - 1;
    if ((uint64_t)Imm > UnsignedMax)
      return false;
  }

  // If we're post-RA, the instructions don't agree on whether register zero is
  // special, we can transform this as long as the register operand that will
  // end up in the location where zero is special isn't R0.
  if (PostRA && III.ZeroIsSpecialOrig != III.ZeroIsSpecialNew) {
    unsigned PosForOrigZero = III.ZeroIsSpecialOrig ? III.ZeroIsSpecialOrig :
      III.ZeroIsSpecialNew + 1;
    Register OrigZeroReg = MI.getOperand(PosForOrigZero).getReg();
    Register NewZeroReg = MI.getOperand(III.ZeroIsSpecialNew).getReg();
    // If R0 is in the operand where zero is special for the new instruction,
    // it is unsafe to transform if the constant operand isn't that operand.
    if ((NewZeroReg == PPC::R0 || NewZeroReg == PPC::X0) &&
        ConstantOpNo != III.ZeroIsSpecialNew)
      return false;
    if ((OrigZeroReg == PPC::R0 || OrigZeroReg == PPC::X0) &&
        ConstantOpNo != PosForOrigZero)
      return false;
  }

  // Get killed info in case fixup needed after transformation.
  unsigned ForwardKilledOperandReg = ~0U;
  if (PostRA && MI.getOperand(ConstantOpNo).isKill())
    ForwardKilledOperandReg = MI.getOperand(ConstantOpNo).getReg();

  unsigned Opc = MI.getOpcode();
  bool SpecialShift32 = Opc == PPC::SLW || Opc == PPC::SLW_rec ||
                        Opc == PPC::SRW || Opc == PPC::SRW_rec ||
                        Opc == PPC::SLW8 || Opc == PPC::SLW8_rec ||
                        Opc == PPC::SRW8 || Opc == PPC::SRW8_rec;
  bool SpecialShift64 = Opc == PPC::SLD || Opc == PPC::SLD_rec ||
                        Opc == PPC::SRD || Opc == PPC::SRD_rec;
  bool SetCR = Opc == PPC::SLW_rec || Opc == PPC::SRW_rec ||
               Opc == PPC::SLD_rec || Opc == PPC::SRD_rec;
  bool RightShift = Opc == PPC::SRW || Opc == PPC::SRW_rec || Opc == PPC::SRD ||
                    Opc == PPC::SRD_rec;

  MI.setDesc(get(III.ImmOpcode));
  if (ConstantOpNo == III.OpNoForForwarding) {
    // Converting shifts to immediate form is a bit tricky since they may do
    // one of three things:
    // 1. If the shift amount is between OpSize and 2*OpSize, the result is zero
    // 2. If the shift amount is zero, the result is unchanged (save for maybe
    //    setting CR0)
    // 3. If the shift amount is in [1, OpSize), it's just a shift
    if (SpecialShift32 || SpecialShift64) {
      LoadImmediateInfo LII;
      LII.Imm = 0;
      LII.SetCR = SetCR;
      LII.Is64Bit = SpecialShift64;
      uint64_t ShAmt = Imm & (SpecialShift32 ? 0x1F : 0x3F);
      if (Imm & (SpecialShift32 ? 0x20 : 0x40))
        replaceInstrWithLI(MI, LII);
      // Shifts by zero don't change the value. If we don't need to set CR0,
      // just convert this to a COPY. Can't do this post-RA since we've already
      // cleaned up the copies.
      else if (!SetCR && ShAmt == 0 && !PostRA) {
        MI.RemoveOperand(2);
        MI.setDesc(get(PPC::COPY));
      } else {
        // The 32 bit and 64 bit instructions are quite different.
        if (SpecialShift32) {
          // Left shifts use (N, 0, 31-N).
          // Right shifts use (32-N, N, 31) if 0 < N < 32.
          //              use (0, 0, 31)    if N == 0.
          uint64_t SH = ShAmt == 0 ? 0 : RightShift ? 32 - ShAmt : ShAmt;
          uint64_t MB = RightShift ? ShAmt : 0;
          uint64_t ME = RightShift ? 31 : 31 - ShAmt;
          replaceInstrOperandWithImm(MI, III.OpNoForForwarding, SH);
          MachineInstrBuilder(*MI.getParent()->getParent(), MI).addImm(MB)
            .addImm(ME);
        } else {
          // Left shifts use (N, 63-N).
          // Right shifts use (64-N, N) if 0 < N < 64.
          //              use (0, 0)    if N == 0.
          uint64_t SH = ShAmt == 0 ? 0 : RightShift ? 64 - ShAmt : ShAmt;
          uint64_t ME = RightShift ? ShAmt : 63 - ShAmt;
          replaceInstrOperandWithImm(MI, III.OpNoForForwarding, SH);
          MachineInstrBuilder(*MI.getParent()->getParent(), MI).addImm(ME);
        }
      }
    } else
      replaceInstrOperandWithImm(MI, ConstantOpNo, Imm);
  }
  // Convert commutative instructions (switch the operands and convert the
  // desired one to an immediate.
  else if (III.IsCommutative) {
    replaceInstrOperandWithImm(MI, ConstantOpNo, Imm);
    swapMIOperands(MI, ConstantOpNo, III.OpNoForForwarding);
  } else
    llvm_unreachable("Should have exited early!");

  // For instructions for which the constant register replaces a different
  // operand than where the immediate goes, we need to swap them.
  if (III.OpNoForForwarding != III.ImmOpNo)
    swapMIOperands(MI, III.OpNoForForwarding, III.ImmOpNo);

  // If the special R0/X0 register index are different for original instruction
  // and new instruction, we need to fix up the register class in new
  // instruction.
  if (!PostRA && III.ZeroIsSpecialOrig != III.ZeroIsSpecialNew) {
    if (III.ZeroIsSpecialNew) {
      // If operand at III.ZeroIsSpecialNew is physical reg(eg: ZERO/ZERO8), no
      // need to fix up register class.
      Register RegToModify = MI.getOperand(III.ZeroIsSpecialNew).getReg();
      if (Register::isVirtualRegister(RegToModify)) {
        const TargetRegisterClass *NewRC =
          MRI.getRegClass(RegToModify)->hasSuperClassEq(&PPC::GPRCRegClass) ?
          &PPC::GPRC_and_GPRC_NOR0RegClass : &PPC::G8RC_and_G8RC_NOX0RegClass;
        MRI.setRegClass(RegToModify, NewRC);
      }
    }
  }

  // Fix up killed/dead flag after transformation.
  // Pattern:
  // ForwardKilledOperandReg = LI imm
  // y = XOP reg, ForwardKilledOperandReg(killed)
  if (ForwardKilledOperandReg != ~0U)
    fixupIsDeadOrKill(&DefMI, &MI, ForwardKilledOperandReg);
  return true;
}

const TargetRegisterClass *
PPCInstrInfo::updatedRC(const TargetRegisterClass *RC) const {
  if (Subtarget.hasVSX() && RC == &PPC::VRRCRegClass)
    return &PPC::VSRCRegClass;
  return RC;
}

int PPCInstrInfo::getRecordFormOpcode(unsigned Opcode) {
  return PPC::getRecordFormOpcode(Opcode);
}

// This function returns true if the machine instruction
// always outputs a value by sign-extending a 32 bit value,
// i.e. 0 to 31-th bits are same as 32-th bit.
static bool isSignExtendingOp(const MachineInstr &MI) {
  int Opcode = MI.getOpcode();
  if (Opcode == PPC::LI || Opcode == PPC::LI8 || Opcode == PPC::LIS ||
      Opcode == PPC::LIS8 || Opcode == PPC::SRAW || Opcode == PPC::SRAW_rec ||
      Opcode == PPC::SRAWI || Opcode == PPC::SRAWI_rec || Opcode == PPC::LWA ||
      Opcode == PPC::LWAX || Opcode == PPC::LWA_32 || Opcode == PPC::LWAX_32 ||
      Opcode == PPC::LHA || Opcode == PPC::LHAX || Opcode == PPC::LHA8 ||
      Opcode == PPC::LHAX8 || Opcode == PPC::LBZ || Opcode == PPC::LBZX ||
      Opcode == PPC::LBZ8 || Opcode == PPC::LBZX8 || Opcode == PPC::LBZU ||
      Opcode == PPC::LBZUX || Opcode == PPC::LBZU8 || Opcode == PPC::LBZUX8 ||
      Opcode == PPC::LHZ || Opcode == PPC::LHZX || Opcode == PPC::LHZ8 ||
      Opcode == PPC::LHZX8 || Opcode == PPC::LHZU || Opcode == PPC::LHZUX ||
      Opcode == PPC::LHZU8 || Opcode == PPC::LHZUX8 || Opcode == PPC::EXTSB ||
      Opcode == PPC::EXTSB_rec || Opcode == PPC::EXTSH ||
      Opcode == PPC::EXTSH_rec || Opcode == PPC::EXTSB8 ||
      Opcode == PPC::EXTSH8 || Opcode == PPC::EXTSW ||
      Opcode == PPC::EXTSW_rec || Opcode == PPC::SETB || Opcode == PPC::SETB8 ||
      Opcode == PPC::EXTSH8_32_64 || Opcode == PPC::EXTSW_32_64 ||
      Opcode == PPC::EXTSB8_32_64)
    return true;

  if (Opcode == PPC::RLDICL && MI.getOperand(3).getImm() >= 33)
    return true;

  if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
       Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec) &&
      MI.getOperand(3).getImm() > 0 &&
      MI.getOperand(3).getImm() <= MI.getOperand(4).getImm())
    return true;

  return false;
}

// This function returns true if the machine instruction
// always outputs zeros in higher 32 bits.
static bool isZeroExtendingOp(const MachineInstr &MI) {
  int Opcode = MI.getOpcode();
  // The 16-bit immediate is sign-extended in li/lis.
  // If the most significant bit is zero, all higher bits are zero.
  if (Opcode == PPC::LI  || Opcode == PPC::LI8 ||
      Opcode == PPC::LIS || Opcode == PPC::LIS8) {
    int64_t Imm = MI.getOperand(1).getImm();
    if (((uint64_t)Imm & ~0x7FFFuLL) == 0)
      return true;
  }

  // We have some variations of rotate-and-mask instructions
  // that clear higher 32-bits.
  if ((Opcode == PPC::RLDICL || Opcode == PPC::RLDICL_rec ||
       Opcode == PPC::RLDCL || Opcode == PPC::RLDCL_rec ||
       Opcode == PPC::RLDICL_32_64) &&
      MI.getOperand(3).getImm() >= 32)
    return true;

  if ((Opcode == PPC::RLDIC || Opcode == PPC::RLDIC_rec) &&
      MI.getOperand(3).getImm() >= 32 &&
      MI.getOperand(3).getImm() <= 63 - MI.getOperand(2).getImm())
    return true;

  if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
       Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec ||
       Opcode == PPC::RLWINM8 || Opcode == PPC::RLWNM8) &&
      MI.getOperand(3).getImm() <= MI.getOperand(4).getImm())
    return true;

  // There are other instructions that clear higher 32-bits.
  if (Opcode == PPC::CNTLZW || Opcode == PPC::CNTLZW_rec ||
      Opcode == PPC::CNTTZW || Opcode == PPC::CNTTZW_rec ||
      Opcode == PPC::CNTLZW8 || Opcode == PPC::CNTTZW8 ||
      Opcode == PPC::CNTLZD || Opcode == PPC::CNTLZD_rec ||
      Opcode == PPC::CNTTZD || Opcode == PPC::CNTTZD_rec ||
      Opcode == PPC::POPCNTD || Opcode == PPC::POPCNTW || Opcode == PPC::SLW ||
      Opcode == PPC::SLW_rec || Opcode == PPC::SRW || Opcode == PPC::SRW_rec ||
      Opcode == PPC::SLW8 || Opcode == PPC::SRW8 || Opcode == PPC::SLWI ||
      Opcode == PPC::SLWI_rec || Opcode == PPC::SRWI ||
      Opcode == PPC::SRWI_rec || Opcode == PPC::LWZ || Opcode == PPC::LWZX ||
      Opcode == PPC::LWZU || Opcode == PPC::LWZUX || Opcode == PPC::LWBRX ||
      Opcode == PPC::LHBRX || Opcode == PPC::LHZ || Opcode == PPC::LHZX ||
      Opcode == PPC::LHZU || Opcode == PPC::LHZUX || Opcode == PPC::LBZ ||
      Opcode == PPC::LBZX || Opcode == PPC::LBZU || Opcode == PPC::LBZUX ||
      Opcode == PPC::LWZ8 || Opcode == PPC::LWZX8 || Opcode == PPC::LWZU8 ||
      Opcode == PPC::LWZUX8 || Opcode == PPC::LWBRX8 || Opcode == PPC::LHBRX8 ||
      Opcode == PPC::LHZ8 || Opcode == PPC::LHZX8 || Opcode == PPC::LHZU8 ||
      Opcode == PPC::LHZUX8 || Opcode == PPC::LBZ8 || Opcode == PPC::LBZX8 ||
      Opcode == PPC::LBZU8 || Opcode == PPC::LBZUX8 ||
      Opcode == PPC::ANDI_rec || Opcode == PPC::ANDIS_rec ||
      Opcode == PPC::ROTRWI || Opcode == PPC::ROTRWI_rec ||
      Opcode == PPC::EXTLWI || Opcode == PPC::EXTLWI_rec ||
      Opcode == PPC::MFVSRWZ)
    return true;

  return false;
}

// This function returns true if the input MachineInstr is a TOC save
// instruction.
bool PPCInstrInfo::isTOCSaveMI(const MachineInstr &MI) const {
  if (!MI.getOperand(1).isImm() || !MI.getOperand(2).isReg())
    return false;
  unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
  unsigned StackOffset = MI.getOperand(1).getImm();
  Register StackReg = MI.getOperand(2).getReg();
  Register SPReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;
  if (StackReg == SPReg && StackOffset == TOCSaveOffset)
    return true;

  return false;
}

// We limit the max depth to track incoming values of PHIs or binary ops
// (e.g. AND) to avoid excessive cost.
const unsigned MAX_DEPTH = 1;

bool
PPCInstrInfo::isSignOrZeroExtended(const MachineInstr &MI, bool SignExt,
                                   const unsigned Depth) const {
  const MachineFunction *MF = MI.getParent()->getParent();
  const MachineRegisterInfo *MRI = &MF->getRegInfo();

  // If we know this instruction returns sign- or zero-extended result,
  // return true.
  if (SignExt ? isSignExtendingOp(MI):
                isZeroExtendingOp(MI))
    return true;

  switch (MI.getOpcode()) {
  case PPC::COPY: {
    Register SrcReg = MI.getOperand(1).getReg();

    // In both ELFv1 and v2 ABI, method parameters and the return value
    // are sign- or zero-extended.
    if (MF->getSubtarget<PPCSubtarget>().isSVR4ABI()) {
      const PPCFunctionInfo *FuncInfo = MF->getInfo<PPCFunctionInfo>();
      // We check the ZExt/SExt flags for a method parameter.
      if (MI.getParent()->getBasicBlock() ==
          &MF->getFunction().getEntryBlock()) {
        Register VReg = MI.getOperand(0).getReg();
        if (MF->getRegInfo().isLiveIn(VReg))
          return SignExt ? FuncInfo->isLiveInSExt(VReg) :
                           FuncInfo->isLiveInZExt(VReg);
      }

      // For a method return value, we check the ZExt/SExt flags in attribute.
      // We assume the following code sequence for method call.
      //   ADJCALLSTACKDOWN 32, implicit dead %r1, implicit %r1
      //   BL8_NOP @func,...
      //   ADJCALLSTACKUP 32, 0, implicit dead %r1, implicit %r1
      //   %5 = COPY %x3; G8RC:%5
      if (SrcReg == PPC::X3) {
        const MachineBasicBlock *MBB = MI.getParent();
        MachineBasicBlock::const_instr_iterator II =
          MachineBasicBlock::const_instr_iterator(&MI);
        if (II != MBB->instr_begin() &&
            (--II)->getOpcode() == PPC::ADJCALLSTACKUP) {
          const MachineInstr &CallMI = *(--II);
          if (CallMI.isCall() && CallMI.getOperand(0).isGlobal()) {
            const Function *CalleeFn =
              dyn_cast<Function>(CallMI.getOperand(0).getGlobal());
            if (!CalleeFn)
              return false;
            const IntegerType *IntTy =
              dyn_cast<IntegerType>(CalleeFn->getReturnType());
            const AttributeSet &Attrs =
              CalleeFn->getAttributes().getRetAttributes();
            if (IntTy && IntTy->getBitWidth() <= 32)
              return Attrs.hasAttribute(SignExt ? Attribute::SExt :
                                                  Attribute::ZExt);
          }
        }
      }
    }

    // If this is a copy from another register, we recursively check source.
    if (!Register::isVirtualRegister(SrcReg))
      return false;
    const MachineInstr *SrcMI = MRI->getVRegDef(SrcReg);
    if (SrcMI != NULL)
      return isSignOrZeroExtended(*SrcMI, SignExt, Depth);

    return false;
  }

  case PPC::ANDI_rec:
  case PPC::ANDIS_rec:
  case PPC::ORI:
  case PPC::ORIS:
  case PPC::XORI:
  case PPC::XORIS:
  case PPC::ANDI8_rec:
  case PPC::ANDIS8_rec:
  case PPC::ORI8:
  case PPC::ORIS8:
  case PPC::XORI8:
  case PPC::XORIS8: {
    // logical operation with 16-bit immediate does not change the upper bits.
    // So, we track the operand register as we do for register copy.
    Register SrcReg = MI.getOperand(1).getReg();
    if (!Register::isVirtualRegister(SrcReg))
      return false;
    const MachineInstr *SrcMI = MRI->getVRegDef(SrcReg);
    if (SrcMI != NULL)
      return isSignOrZeroExtended(*SrcMI, SignExt, Depth);

    return false;
  }

  // If all incoming values are sign-/zero-extended,
  // the output of OR, ISEL or PHI is also sign-/zero-extended.
  case PPC::OR:
  case PPC::OR8:
  case PPC::ISEL:
  case PPC::PHI: {
    if (Depth >= MAX_DEPTH)
      return false;

    // The input registers for PHI are operand 1, 3, ...
    // The input registers for others are operand 1 and 2.
    unsigned E = 3, D = 1;
    if (MI.getOpcode() == PPC::PHI) {
      E = MI.getNumOperands();
      D = 2;
    }

    for (unsigned I = 1; I != E; I += D) {
      if (MI.getOperand(I).isReg()) {
        Register SrcReg = MI.getOperand(I).getReg();
        if (!Register::isVirtualRegister(SrcReg))
          return false;
        const MachineInstr *SrcMI = MRI->getVRegDef(SrcReg);
        if (SrcMI == NULL || !isSignOrZeroExtended(*SrcMI, SignExt, Depth+1))
          return false;
      }
      else
        return false;
    }
    return true;
  }

  // If at least one of the incoming values of an AND is zero extended
  // then the output is also zero-extended. If both of the incoming values
  // are sign-extended then the output is also sign extended.
  case PPC::AND:
  case PPC::AND8: {
    if (Depth >= MAX_DEPTH)
       return false;

    assert(MI.getOperand(1).isReg() && MI.getOperand(2).isReg());

    Register SrcReg1 = MI.getOperand(1).getReg();
    Register SrcReg2 = MI.getOperand(2).getReg();

    if (!Register::isVirtualRegister(SrcReg1) ||
        !Register::isVirtualRegister(SrcReg2))
      return false;

    const MachineInstr *MISrc1 = MRI->getVRegDef(SrcReg1);
    const MachineInstr *MISrc2 = MRI->getVRegDef(SrcReg2);
    if (!MISrc1 || !MISrc2)
        return false;

    if(SignExt)
        return isSignOrZeroExtended(*MISrc1, SignExt, Depth+1) &&
               isSignOrZeroExtended(*MISrc2, SignExt, Depth+1);
    else
        return isSignOrZeroExtended(*MISrc1, SignExt, Depth+1) ||
               isSignOrZeroExtended(*MISrc2, SignExt, Depth+1);
  }

  default:
    break;
  }
  return false;
}

bool PPCInstrInfo::isBDNZ(unsigned Opcode) const {
  return (Opcode == (Subtarget.isPPC64() ? PPC::BDNZ8 : PPC::BDNZ));
}

namespace {
class PPCPipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {
  MachineInstr *Loop, *EndLoop, *LoopCount;
  MachineFunction *MF;
  const TargetInstrInfo *TII;
  int64_t TripCount;

public:
  PPCPipelinerLoopInfo(MachineInstr *Loop, MachineInstr *EndLoop,
                       MachineInstr *LoopCount)
      : Loop(Loop), EndLoop(EndLoop), LoopCount(LoopCount),
        MF(Loop->getParent()->getParent()),
        TII(MF->getSubtarget().getInstrInfo()) {
    // Inspect the Loop instruction up-front, as it may be deleted when we call
    // createTripCountGreaterCondition.
    if (LoopCount->getOpcode() == PPC::LI8 || LoopCount->getOpcode() == PPC::LI)
      TripCount = LoopCount->getOperand(1).getImm();
    else
      TripCount = -1;
  }

  bool shouldIgnoreForPipelining(const MachineInstr *MI) const override {
    // Only ignore the terminator.
    return MI == EndLoop;
  }

  Optional<bool>
  createTripCountGreaterCondition(int TC, MachineBasicBlock &MBB,
                                  SmallVectorImpl<MachineOperand> &Cond) override {
    if (TripCount == -1) {
      // Since BDZ/BDZ8 that we will insert will also decrease the ctr by 1,
      // so we don't need to generate any thing here.
      Cond.push_back(MachineOperand::CreateImm(0));
      Cond.push_back(MachineOperand::CreateReg(
          MF->getSubtarget<PPCSubtarget>().isPPC64() ? PPC::CTR8 : PPC::CTR,
          true));
      return {};
    }

    return TripCount > TC;
  }

  void setPreheader(MachineBasicBlock *NewPreheader) override {
    // Do nothing. We want the LOOP setup instruction to stay in the *old*
    // preheader, so we can use BDZ in the prologs to adapt the loop trip count.
  }

  void adjustTripCount(int TripCountAdjust) override {
    // If the loop trip count is a compile-time value, then just change the
    // value.
    if (LoopCount->getOpcode() == PPC::LI8 ||
        LoopCount->getOpcode() == PPC::LI) {
      int64_t TripCount = LoopCount->getOperand(1).getImm() + TripCountAdjust;
      LoopCount->getOperand(1).setImm(TripCount);
      return;
    }

    // Since BDZ/BDZ8 that we will insert will also decrease the ctr by 1,
    // so we don't need to generate any thing here.
  }

  void disposed() override {
    Loop->eraseFromParent();
    // Ensure the loop setup instruction is deleted too.
    LoopCount->eraseFromParent();
  }
};
} // namespace

std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
PPCInstrInfo::analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const {
  // We really "analyze" only hardware loops right now.
  MachineBasicBlock::iterator I = LoopBB->getFirstTerminator();
  MachineBasicBlock *Preheader = *LoopBB->pred_begin();
  if (Preheader == LoopBB)
    Preheader = *std::next(LoopBB->pred_begin());
  MachineFunction *MF = Preheader->getParent();

  if (I != LoopBB->end() && isBDNZ(I->getOpcode())) {
    SmallPtrSet<MachineBasicBlock *, 8> Visited;
    if (MachineInstr *LoopInst = findLoopInstr(*Preheader, Visited)) {
      Register LoopCountReg = LoopInst->getOperand(0).getReg();
      MachineRegisterInfo &MRI = MF->getRegInfo();
      MachineInstr *LoopCount = MRI.getUniqueVRegDef(LoopCountReg);
      return std::make_unique<PPCPipelinerLoopInfo>(LoopInst, &*I, LoopCount);
    }
  }
  return nullptr;
}

MachineInstr *PPCInstrInfo::findLoopInstr(
    MachineBasicBlock &PreHeader,
    SmallPtrSet<MachineBasicBlock *, 8> &Visited) const {

  unsigned LOOPi = (Subtarget.isPPC64() ? PPC::MTCTR8loop : PPC::MTCTRloop);

  // The loop set-up instruction should be in preheader
  for (auto &I : PreHeader.instrs())
    if (I.getOpcode() == LOOPi)
      return &I;
  return nullptr;
}

// Return true if get the base operand, byte offset of an instruction and the
// memory width. Width is the size of memory that is being loaded/stored.
bool PPCInstrInfo::getMemOperandWithOffsetWidth(
    const MachineInstr &LdSt, const MachineOperand *&BaseReg, int64_t &Offset,
    unsigned &Width, const TargetRegisterInfo *TRI) const {
  if (!LdSt.mayLoadOrStore() || LdSt.getNumExplicitOperands() != 3)
    return false;

  // Handle only loads/stores with base register followed by immediate offset.
  if (!LdSt.getOperand(1).isImm() ||
      (!LdSt.getOperand(2).isReg() && !LdSt.getOperand(2).isFI()))
    return false;
  if (!LdSt.getOperand(1).isImm() ||
      (!LdSt.getOperand(2).isReg() && !LdSt.getOperand(2).isFI()))
    return false;

  if (!LdSt.hasOneMemOperand())
    return false;

  Width = (*LdSt.memoperands_begin())->getSize();
  Offset = LdSt.getOperand(1).getImm();
  BaseReg = &LdSt.getOperand(2);
  return true;
}

bool PPCInstrInfo::areMemAccessesTriviallyDisjoint(
    const MachineInstr &MIa, const MachineInstr &MIb) const {
  assert(MIa.mayLoadOrStore() && "MIa must be a load or store.");
  assert(MIb.mayLoadOrStore() && "MIb must be a load or store.");

  if (MIa.hasUnmodeledSideEffects() || MIb.hasUnmodeledSideEffects() ||
      MIa.hasOrderedMemoryRef() || MIb.hasOrderedMemoryRef())
    return false;

  // Retrieve the base register, offset from the base register and width. Width
  // is the size of memory that is being loaded/stored (e.g. 1, 2, 4).  If
  // base registers are identical, and the offset of a lower memory access +
  // the width doesn't overlap the offset of a higher memory access,
  // then the memory accesses are different.
  const TargetRegisterInfo *TRI = &getRegisterInfo();
  const MachineOperand *BaseOpA = nullptr, *BaseOpB = nullptr;
  int64_t OffsetA = 0, OffsetB = 0;
  unsigned int WidthA = 0, WidthB = 0;
  if (getMemOperandWithOffsetWidth(MIa, BaseOpA, OffsetA, WidthA, TRI) &&
      getMemOperandWithOffsetWidth(MIb, BaseOpB, OffsetB, WidthB, TRI)) {
    if (BaseOpA->isIdenticalTo(*BaseOpB)) {
      int LowOffset = std::min(OffsetA, OffsetB);
      int HighOffset = std::max(OffsetA, OffsetB);
      int LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
      if (LowOffset + LowWidth <= HighOffset)
        return true;
    }
  }
  return false;
}
