//===-- PPCISelLowering.cpp - PPC DAG Lowering Implementation -------------===//
//
// 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 implements the PPCISelLowering class.
//
//===----------------------------------------------------------------------===//

#include "PPCISelLowering.h"
#include "MCTargetDesc/PPCMCTargetDesc.h"
#include "MCTargetDesc/PPCPredicates.h"
#include "PPC.h"
#include "PPCCallingConv.h"
#include "PPCFrameLowering.h"
#include "PPCInstrInfo.h"
#include "PPCMachineFunctionInfo.h"
#include "PPCPerfectShuffle.h"
#include "PPCRegisterInfo.h"
#include "PPCSelectionDAGInfo.h"
#include "PPCSubtarget.h"
#include "PPCTargetMachine.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/LivePhysRegs.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/CodeGenTypes/MachineValueType.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsPowerPC.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Use.h"
#include "llvm/IR/Value.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSectionXCOFF.h"
#include "llvm/MC/MCSymbolXCOFF.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <iterator>
#include <list>
#include <optional>
#include <utility>
#include <vector>

using namespace llvm;

#define DEBUG_TYPE "ppc-lowering"

static cl::opt<bool> DisableP10StoreForward(
    "disable-p10-store-forward",
    cl::desc("disable P10 store forward-friendly conversion"), cl::Hidden,
    cl::init(false));

static cl::opt<bool> DisablePPCPreinc("disable-ppc-preinc",
cl::desc("disable preincrement load/store generation on PPC"), cl::Hidden);

static cl::opt<bool> DisableILPPref("disable-ppc-ilp-pref",
cl::desc("disable setting the node scheduling preference to ILP on PPC"), cl::Hidden);

static cl::opt<bool> DisablePPCUnaligned("disable-ppc-unaligned",
cl::desc("disable unaligned load/store generation on PPC"), cl::Hidden);

static cl::opt<bool> DisableSCO("disable-ppc-sco",
cl::desc("disable sibling call optimization on ppc"), cl::Hidden);

static cl::opt<bool> DisableInnermostLoopAlign32("disable-ppc-innermost-loop-align32",
cl::desc("don't always align innermost loop to 32 bytes on ppc"), cl::Hidden);

static cl::opt<bool> UseAbsoluteJumpTables("ppc-use-absolute-jumptables",
cl::desc("use absolute jump tables on ppc"), cl::Hidden);

static cl::opt<bool>
    DisablePerfectShuffle("ppc-disable-perfect-shuffle",
                          cl::desc("disable vector permute decomposition"),
                          cl::init(true), cl::Hidden);

cl::opt<bool> DisableAutoPairedVecSt(
    "disable-auto-paired-vec-st",
    cl::desc("disable automatically generated 32byte paired vector stores"),
    cl::init(true), cl::Hidden);

static cl::opt<unsigned> PPCMinimumJumpTableEntries(
    "ppc-min-jump-table-entries", cl::init(64), cl::Hidden,
    cl::desc("Set minimum number of entries to use a jump table on PPC"));

static cl::opt<unsigned> PPCMinimumBitTestCmps(
    "ppc-min-bit-test-cmps", cl::init(3), cl::Hidden,
    cl::desc("Set minimum of largest number of comparisons to use bit test for "
             "switch on PPC."));

static cl::opt<unsigned> PPCGatherAllAliasesMaxDepth(
    "ppc-gather-alias-max-depth", cl::init(18), cl::Hidden,
    cl::desc("max depth when checking alias info in GatherAllAliases()"));

static cl::opt<unsigned> PPCAIXTLSModelOptUseIEForLDLimit(
    "ppc-aix-shared-lib-tls-model-opt-limit", cl::init(1), cl::Hidden,
    cl::desc("Set inclusive limit count of TLS local-dynamic access(es) in a "
             "function to use initial-exec"));

STATISTIC(NumTailCalls, "Number of tail calls");
STATISTIC(NumSiblingCalls, "Number of sibling calls");
STATISTIC(ShufflesHandledWithVPERM,
          "Number of shuffles lowered to a VPERM or XXPERM");
STATISTIC(NumDynamicAllocaProbed, "Number of dynamic stack allocation probed");

static bool isNByteElemShuffleMask(ShuffleVectorSDNode *, unsigned, int);

static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl);

// A faster local-[exec|dynamic] TLS access sequence (enabled with the
// -maix-small-local-[exec|dynamic]-tls option) can be produced for TLS
// variables; consistent with the IBM XL compiler, we apply a max size of
// slightly under 32KB.
constexpr uint64_t AIXSmallTlsPolicySizeLimit = 32751;

// FIXME: Remove this once the bug has been fixed!
extern cl::opt<bool> ANDIGlueBug;

PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
                                     const PPCSubtarget &STI)
    : TargetLowering(TM, STI), Subtarget(STI) {
  // Initialize map that relates the PPC addressing modes to the computed flags
  // of a load/store instruction. The map is used to determine the optimal
  // addressing mode when selecting load and stores.
  initializeAddrModeMap();
  // On PPC32/64, arguments smaller than 4/8 bytes are extended, so all
  // arguments are at least 4/8 bytes aligned.
  bool isPPC64 = Subtarget.isPPC64();
  setMinStackArgumentAlignment(isPPC64 ? Align(8) : Align(4));
  const MVT RegVT = Subtarget.getScalarIntVT();

  // Set up the register classes.
  addRegisterClass(MVT::i32, &PPC::GPRCRegClass);
  if (!useSoftFloat()) {
    if (hasSPE()) {
      addRegisterClass(MVT::f32, &PPC::GPRCRegClass);
      // EFPU2 APU only supports f32
      if (!Subtarget.hasEFPU2())
        addRegisterClass(MVT::f64, &PPC::SPERCRegClass);
    } else {
      addRegisterClass(MVT::f32, &PPC::F4RCRegClass);
      addRegisterClass(MVT::f64, &PPC::F8RCRegClass);
    }
  }

  setOperationAction(ISD::UADDO, RegVT, Custom);
  setOperationAction(ISD::USUBO, RegVT, Custom);

  // PowerPC uses addo_carry,subo_carry to propagate carry.
  setOperationAction(ISD::UADDO_CARRY, RegVT, Custom);
  setOperationAction(ISD::USUBO_CARRY, RegVT, Custom);

  // On P10, the default lowering generates better code using the
  // setbc instruction.
  if (!Subtarget.hasP10Vector()) {
    setOperationAction(ISD::SSUBO, MVT::i32, Custom);
    setOperationAction(ISD::SADDO, MVT::i32, Custom);
    if (isPPC64) {
      setOperationAction(ISD::SSUBO, MVT::i64, Custom);
      setOperationAction(ISD::SADDO, MVT::i64, Custom);
    }
  }

  // Match BITREVERSE to customized fast code sequence in the td file.
  setOperationAction(ISD::BITREVERSE, MVT::i32, Legal);
  setOperationAction(ISD::BITREVERSE, MVT::i64, Legal);

  // Sub-word ATOMIC_CMP_SWAP need to ensure that the input is zero-extended.
  setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i32, Custom);

  // Custom lower inline assembly to check for special registers.
  setOperationAction(ISD::INLINEASM, MVT::Other, Custom);
  setOperationAction(ISD::INLINEASM_BR, MVT::Other, Custom);

  // PowerPC has an i16 but no i8 (or i1) SEXTLOAD.
  for (MVT VT : MVT::integer_valuetypes()) {
    setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote);
    setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i8, Expand);
  }

  setTruncStoreAction(MVT::f128, MVT::f16, Expand);
  setOperationAction(ISD::FP_TO_FP16, MVT::f128, Expand);

  if (Subtarget.isISA3_0()) {
    setLoadExtAction(ISD::EXTLOAD, MVT::f128, MVT::f16, Legal);
    setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f16, Legal);
    setLoadExtAction(ISD::EXTLOAD, MVT::f32, MVT::f16, Legal);
    setTruncStoreAction(MVT::f64, MVT::f16, Legal);
    setTruncStoreAction(MVT::f32, MVT::f16, Legal);
  } else {
    // No extending loads from f16 or HW conversions back and forth.
    setLoadExtAction(ISD::EXTLOAD, MVT::f128, MVT::f16, Expand);
    setOperationAction(ISD::FP16_TO_FP, MVT::f128, Expand);
    setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f16, Expand);
    setOperationAction(ISD::FP16_TO_FP, MVT::f64, Expand);
    setOperationAction(ISD::FP_TO_FP16, MVT::f64, Expand);
    setLoadExtAction(ISD::EXTLOAD, MVT::f32, MVT::f16, Expand);
    setOperationAction(ISD::FP16_TO_FP, MVT::f32, Expand);
    setOperationAction(ISD::FP_TO_FP16, MVT::f32, Expand);
    setTruncStoreAction(MVT::f64, MVT::f16, Expand);
    setTruncStoreAction(MVT::f32, MVT::f16, Expand);
  }

  setTruncStoreAction(MVT::f64, MVT::f32, Expand);

  // PowerPC has pre-inc load and store's.
  setIndexedLoadAction(ISD::PRE_INC, MVT::i1, Legal);
  setIndexedLoadAction(ISD::PRE_INC, MVT::i8, Legal);
  setIndexedLoadAction(ISD::PRE_INC, MVT::i16, Legal);
  setIndexedLoadAction(ISD::PRE_INC, MVT::i32, Legal);
  setIndexedLoadAction(ISD::PRE_INC, MVT::i64, Legal);
  setIndexedStoreAction(ISD::PRE_INC, MVT::i1, Legal);
  setIndexedStoreAction(ISD::PRE_INC, MVT::i8, Legal);
  setIndexedStoreAction(ISD::PRE_INC, MVT::i16, Legal);
  setIndexedStoreAction(ISD::PRE_INC, MVT::i32, Legal);
  setIndexedStoreAction(ISD::PRE_INC, MVT::i64, Legal);
  if (!Subtarget.hasSPE()) {
    setIndexedLoadAction(ISD::PRE_INC, MVT::f32, Legal);
    setIndexedLoadAction(ISD::PRE_INC, MVT::f64, Legal);
    setIndexedStoreAction(ISD::PRE_INC, MVT::f32, Legal);
    setIndexedStoreAction(ISD::PRE_INC, MVT::f64, Legal);
  }

  if (Subtarget.useCRBits()) {
    setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);

    if (isPPC64 || Subtarget.hasFPCVT()) {
      setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i1, Promote);
      AddPromotedToType(ISD::STRICT_SINT_TO_FP, MVT::i1, RegVT);
      setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i1, Promote);
      AddPromotedToType(ISD::STRICT_UINT_TO_FP, MVT::i1, RegVT);

      setOperationAction(ISD::SINT_TO_FP, MVT::i1, Promote);
      AddPromotedToType(ISD::SINT_TO_FP, MVT::i1, RegVT);
      setOperationAction(ISD::UINT_TO_FP, MVT::i1, Promote);
      AddPromotedToType(ISD::UINT_TO_FP, MVT::i1, RegVT);

      setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i1, Promote);
      AddPromotedToType(ISD::STRICT_FP_TO_SINT, MVT::i1, RegVT);
      setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i1, Promote);
      AddPromotedToType(ISD::STRICT_FP_TO_UINT, MVT::i1, RegVT);

      setOperationAction(ISD::FP_TO_SINT, MVT::i1, Promote);
      AddPromotedToType(ISD::FP_TO_SINT, MVT::i1, RegVT);
      setOperationAction(ISD::FP_TO_UINT, MVT::i1, Promote);
      AddPromotedToType(ISD::FP_TO_UINT, MVT::i1, RegVT);
    } else {
      setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i1, Custom);
      setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i1, Custom);
      setOperationAction(ISD::SINT_TO_FP, MVT::i1, Custom);
      setOperationAction(ISD::UINT_TO_FP, MVT::i1, Custom);
    }

    // PowerPC does not support direct load/store of condition registers.
    setOperationAction(ISD::LOAD, MVT::i1, Custom);
    setOperationAction(ISD::STORE, MVT::i1, Custom);

    // FIXME: Remove this once the ANDI glue bug is fixed:
    if (ANDIGlueBug)
      setOperationAction(ISD::TRUNCATE, MVT::i1, Custom);

    for (MVT VT : MVT::integer_valuetypes()) {
      setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote);
      setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::i1, Promote);
      setTruncStoreAction(VT, MVT::i1, Expand);
    }

    addRegisterClass(MVT::i1, &PPC::CRBITRCRegClass);
  }

  // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
  // PPC (the libcall is not available).
  setOperationAction(ISD::FP_TO_SINT, MVT::ppcf128, Custom);
  setOperationAction(ISD::FP_TO_UINT, MVT::ppcf128, Custom);
  setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::ppcf128, Custom);
  setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::ppcf128, Custom);

  // We do not currently implement these libm ops for PowerPC.
  setOperationAction(ISD::FFLOOR, MVT::ppcf128, Expand);
  setOperationAction(ISD::FCEIL,  MVT::ppcf128, Expand);
  setOperationAction(ISD::FTRUNC, MVT::ppcf128, Expand);
  setOperationAction(ISD::FRINT,  MVT::ppcf128, Expand);
  setOperationAction(ISD::FNEARBYINT, MVT::ppcf128, Expand);
  setOperationAction(ISD::FREM, MVT::ppcf128, LibCall);

  // PowerPC has no SREM/UREM instructions unless we are on P9
  // On P9 we may use a hardware instruction to compute the remainder.
  // When the result of both the remainder and the division is required it is
  // more efficient to compute the remainder from the result of the division
  // rather than use the remainder instruction. The instructions are legalized
  // directly because the DivRemPairsPass performs the transformation at the IR
  // level.
  if (Subtarget.isISA3_0()) {
    setOperationAction(ISD::SREM, MVT::i32, Legal);
    setOperationAction(ISD::UREM, MVT::i32, Legal);
    setOperationAction(ISD::SREM, MVT::i64, Legal);
    setOperationAction(ISD::UREM, MVT::i64, Legal);
  } else {
    setOperationAction(ISD::SREM, MVT::i32, Expand);
    setOperationAction(ISD::UREM, MVT::i32, Expand);
    setOperationAction(ISD::SREM, MVT::i64, Expand);
    setOperationAction(ISD::UREM, MVT::i64, Expand);
  }

  // Don't use SMUL_LOHI/UMUL_LOHI or SDIVREM/UDIVREM to lower SREM/UREM.
  setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
  setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand);
  setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand);
  setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
  setOperationAction(ISD::UDIVREM, MVT::i32, Expand);
  setOperationAction(ISD::SDIVREM, MVT::i32, Expand);
  setOperationAction(ISD::UDIVREM, MVT::i64, Expand);
  setOperationAction(ISD::SDIVREM, MVT::i64, Expand);

  // Handle constrained floating-point operations of scalar.
  // TODO: Handle SPE specific operation.
  setOperationAction(ISD::STRICT_FADD, MVT::f32, Legal);
  setOperationAction(ISD::STRICT_FSUB, MVT::f32, Legal);
  setOperationAction(ISD::STRICT_FMUL, MVT::f32, Legal);
  setOperationAction(ISD::STRICT_FDIV, MVT::f32, Legal);
  setOperationAction(ISD::STRICT_FP_ROUND, MVT::f32, Legal);

  setOperationAction(ISD::STRICT_FADD, MVT::f64, Legal);
  setOperationAction(ISD::STRICT_FSUB, MVT::f64, Legal);
  setOperationAction(ISD::STRICT_FMUL, MVT::f64, Legal);
  setOperationAction(ISD::STRICT_FDIV, MVT::f64, Legal);

  if (!Subtarget.hasSPE()) {
    setOperationAction(ISD::STRICT_FMA, MVT::f32, Legal);
    setOperationAction(ISD::STRICT_FMA, MVT::f64, Legal);
  }

  if (Subtarget.hasVSX()) {
    setOperationAction(ISD::STRICT_FRINT, MVT::f32, Legal);
    setOperationAction(ISD::STRICT_FRINT, MVT::f64, Legal);
  }

  if (Subtarget.hasFSQRT()) {
    setOperationAction(ISD::STRICT_FSQRT, MVT::f32, Legal);
    setOperationAction(ISD::STRICT_FSQRT, MVT::f64, Legal);
  }

  if (Subtarget.hasFPRND()) {
    setOperationAction(ISD::STRICT_FFLOOR, MVT::f32, Legal);
    setOperationAction(ISD::STRICT_FCEIL,  MVT::f32, Legal);
    setOperationAction(ISD::STRICT_FTRUNC, MVT::f32, Legal);
    setOperationAction(ISD::STRICT_FROUND, MVT::f32, Legal);

    setOperationAction(ISD::STRICT_FFLOOR, MVT::f64, Legal);
    setOperationAction(ISD::STRICT_FCEIL,  MVT::f64, Legal);
    setOperationAction(ISD::STRICT_FTRUNC, MVT::f64, Legal);
    setOperationAction(ISD::STRICT_FROUND, MVT::f64, Legal);
  }

  // We don't support sin/cos/sqrt/fmod/pow
  setOperationAction(ISD::FSIN , MVT::f64, Expand);
  setOperationAction(ISD::FCOS , MVT::f64, Expand);
  setOperationAction(ISD::FSINCOS, MVT::f64, Expand);
  setOperationAction(ISD::FREM, MVT::f64, LibCall);
  setOperationAction(ISD::FPOW , MVT::f64, Expand);
  setOperationAction(ISD::FSIN , MVT::f32, Expand);
  setOperationAction(ISD::FCOS , MVT::f32, Expand);
  setOperationAction(ISD::FSINCOS, MVT::f32, Expand);
  setOperationAction(ISD::FREM, MVT::f32, LibCall);
  setOperationAction(ISD::FPOW , MVT::f32, Expand);

  // MASS transformation for LLVM intrinsics with replicating fast-math flag
  // to be consistent to PPCGenScalarMASSEntries pass
  if (TM.getOptLevel() == CodeGenOptLevel::Aggressive) {
    setOperationAction(ISD::FSIN , MVT::f64, Custom);
    setOperationAction(ISD::FCOS , MVT::f64, Custom);
    setOperationAction(ISD::FPOW , MVT::f64, Custom);
    setOperationAction(ISD::FLOG, MVT::f64, Custom);
    setOperationAction(ISD::FLOG10, MVT::f64, Custom);
    setOperationAction(ISD::FEXP, MVT::f64, Custom);
    setOperationAction(ISD::FSIN , MVT::f32, Custom);
    setOperationAction(ISD::FCOS , MVT::f32, Custom);
    setOperationAction(ISD::FPOW , MVT::f32, Custom);
    setOperationAction(ISD::FLOG, MVT::f32, Custom);
    setOperationAction(ISD::FLOG10, MVT::f32, Custom);
    setOperationAction(ISD::FEXP, MVT::f32, Custom);
  }

  if (Subtarget.hasSPE()) {
    setOperationAction(ISD::FMA  , MVT::f64, Expand);
    setOperationAction(ISD::FMA  , MVT::f32, Expand);
  } else {
    setOperationAction(ISD::FMA  , MVT::f64, Legal);
    setOperationAction(ISD::FMA  , MVT::f32, Legal);
    setOperationAction(ISD::GET_ROUNDING, MVT::i32, Custom);
    setOperationAction(ISD::SET_ROUNDING, MVT::Other, Custom);
  }

  if (Subtarget.hasSPE())
    setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f32, Expand);

  // If we're enabling GP optimizations, use hardware square root
  if (!Subtarget.hasFSQRT() && !(Subtarget.hasFRSQRTE() && Subtarget.hasFRE()))
    setOperationAction(ISD::FSQRT, MVT::f64, Expand);

  if (!Subtarget.hasFSQRT() &&
      !(Subtarget.hasFRSQRTES() && Subtarget.hasFRES()))
    setOperationAction(ISD::FSQRT, MVT::f32, Expand);

  if (Subtarget.hasFCPSGN()) {
    setOperationAction(ISD::FCOPYSIGN, MVT::f64, Legal);
    setOperationAction(ISD::FCOPYSIGN, MVT::f32, Legal);
  } else {
    setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
    setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
  }

  if (Subtarget.hasFPRND()) {
    setOperationAction(ISD::FFLOOR, MVT::f64, Legal);
    setOperationAction(ISD::FCEIL,  MVT::f64, Legal);
    setOperationAction(ISD::FTRUNC, MVT::f64, Legal);
    setOperationAction(ISD::FROUND, MVT::f64, Legal);

    setOperationAction(ISD::FFLOOR, MVT::f32, Legal);
    setOperationAction(ISD::FCEIL,  MVT::f32, Legal);
    setOperationAction(ISD::FTRUNC, MVT::f32, Legal);
    setOperationAction(ISD::FROUND, MVT::f32, Legal);
  }

  // Prior to P10, PowerPC does not have BSWAP, but we can use vector BSWAP
  // instruction xxbrd to speed up scalar BSWAP64.
  if (Subtarget.isISA3_1()) {
    setOperationAction(ISD::BSWAP, MVT::i32, Legal);
    setOperationAction(ISD::BSWAP, MVT::i64, Legal);
  } else {
    setOperationAction(ISD::BSWAP, MVT::i32, Expand);
    setOperationAction(ISD::BSWAP, MVT::i64,
                       (Subtarget.hasP9Vector() && isPPC64) ? Custom : Expand);
  }

  // CTPOP or CTTZ were introduced in P8/P9 respectively
  if (Subtarget.isISA3_0()) {
    setOperationAction(ISD::CTTZ , MVT::i32  , Legal);
    setOperationAction(ISD::CTTZ , MVT::i64  , Legal);
  } else {
    setOperationAction(ISD::CTTZ , MVT::i32  , Expand);
    setOperationAction(ISD::CTTZ , MVT::i64  , Expand);
  }

  if (Subtarget.hasPOPCNTD() == PPCSubtarget::POPCNTD_Fast) {
    setOperationAction(ISD::CTPOP, MVT::i32  , Legal);
    setOperationAction(ISD::CTPOP, MVT::i64  , Legal);
  } else {
    setOperationAction(ISD::CTPOP, MVT::i32  , Expand);
    setOperationAction(ISD::CTPOP, MVT::i64  , Expand);
  }

  // PowerPC does not have ROTR
  setOperationAction(ISD::ROTR, MVT::i32   , Expand);
  setOperationAction(ISD::ROTR, MVT::i64   , Expand);

  if (!Subtarget.useCRBits()) {
    // PowerPC does not have Select
    setOperationAction(ISD::SELECT, MVT::i32, Expand);
    setOperationAction(ISD::SELECT, MVT::i64, Expand);
    setOperationAction(ISD::SELECT, MVT::f32, Expand);
    setOperationAction(ISD::SELECT, MVT::f64, Expand);
  }

  // PowerPC wants to turn select_cc of FP into fsel when possible.
  setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
  setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);

  // PowerPC wants to optimize integer setcc a bit
  if (!Subtarget.useCRBits())
    setOperationAction(ISD::SETCC, MVT::i32, Custom);

  if (Subtarget.hasFPU()) {
    setOperationAction(ISD::STRICT_FSETCC, MVT::f32, Legal);
    setOperationAction(ISD::STRICT_FSETCC, MVT::f64, Legal);
    setOperationAction(ISD::STRICT_FSETCC, MVT::f128, Legal);

    setOperationAction(ISD::STRICT_FSETCCS, MVT::f32, Legal);
    setOperationAction(ISD::STRICT_FSETCCS, MVT::f64, Legal);
    setOperationAction(ISD::STRICT_FSETCCS, MVT::f128, Legal);
  }

  // PowerPC does not have BRCOND which requires SetCC
  if (!Subtarget.useCRBits())
    setOperationAction(ISD::BRCOND, MVT::Other, Expand);

  setOperationAction(ISD::BR_JT,  MVT::Other, Expand);

  if (Subtarget.hasSPE()) {
    // SPE has built-in conversions
    setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i32, Legal);
    setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i32, Legal);
    setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i32, Legal);
    setOperationAction(ISD::FP_TO_SINT, MVT::i32, Legal);
    setOperationAction(ISD::SINT_TO_FP, MVT::i32, Legal);
    setOperationAction(ISD::UINT_TO_FP, MVT::i32, Legal);

    // SPE supports signaling compare of f32/f64.
    setOperationAction(ISD::STRICT_FSETCCS, MVT::f32, Legal);
    setOperationAction(ISD::STRICT_FSETCCS, MVT::f64, Legal);
  } else {
    // PowerPC turns FP_TO_SINT into FCTIWZ and some load/stores.
    setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i32, Custom);
    setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);

    // PowerPC does not have [U|S]INT_TO_FP
    setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i32, Expand);
    setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i32, Expand);
    setOperationAction(ISD::SINT_TO_FP, MVT::i32, Expand);
    setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
  }

  if (Subtarget.hasDirectMove() && isPPC64) {
    setOperationAction(ISD::BITCAST, MVT::f32, Legal);
    setOperationAction(ISD::BITCAST, MVT::i32, Legal);
    setOperationAction(ISD::BITCAST, MVT::i64, Legal);
    setOperationAction(ISD::BITCAST, MVT::f64, Legal);

    setOperationAction(ISD::STRICT_LRINT, MVT::f64, Custom);
    setOperationAction(ISD::STRICT_LRINT, MVT::f32, Custom);
    setOperationAction(ISD::STRICT_LLRINT, MVT::f64, Custom);
    setOperationAction(ISD::STRICT_LLRINT, MVT::f32, Custom);
    setOperationAction(ISD::STRICT_LROUND, MVT::f64, Custom);
    setOperationAction(ISD::STRICT_LROUND, MVT::f32, Custom);
    setOperationAction(ISD::STRICT_LLROUND, MVT::f64, Custom);
    setOperationAction(ISD::STRICT_LLROUND, MVT::f32, Custom);
  } else {
    setOperationAction(ISD::BITCAST, MVT::f32, Expand);
    setOperationAction(ISD::BITCAST, MVT::i32, Expand);
    setOperationAction(ISD::BITCAST, MVT::i64, Expand);
    setOperationAction(ISD::BITCAST, MVT::f64, Expand);
  }

  // We cannot sextinreg(i1).  Expand to shifts.
  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);

  // Custom handling for PowerPC ucmp instruction
  setOperationAction(ISD::UCMP, MVT::i32, Custom);
  setOperationAction(ISD::UCMP, MVT::i64, isPPC64 ? Custom : Expand);

  // NOTE: EH_SJLJ_SETJMP/_LONGJMP supported here is NOT intended to support
  // SjLj exception handling but a light-weight setjmp/longjmp replacement to
  // support continuation, user-level threading, and etc.. As a result, no
  // other SjLj exception interfaces are implemented and please don't build
  // your own exception handling based on them.
  // LLVM/Clang supports zero-cost DWARF exception handling.
  setOperationAction(ISD::EH_SJLJ_SETJMP, MVT::i32, Custom);
  setOperationAction(ISD::EH_SJLJ_LONGJMP, MVT::Other, Custom);

  // We want to legalize GlobalAddress and ConstantPool nodes into the
  // appropriate instructions to materialize the address.
  setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
  setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
  setOperationAction(ISD::BlockAddress,  MVT::i32, Custom);
  setOperationAction(ISD::ConstantPool,  MVT::i32, Custom);
  setOperationAction(ISD::JumpTable,     MVT::i32, Custom);
  setOperationAction(ISD::GlobalAddress, MVT::i64, Custom);
  setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom);
  setOperationAction(ISD::BlockAddress,  MVT::i64, Custom);
  setOperationAction(ISD::ConstantPool,  MVT::i64, Custom);
  setOperationAction(ISD::JumpTable,     MVT::i64, Custom);

  // TRAP is legal.
  setOperationAction(ISD::TRAP, MVT::Other, Legal);

  // TRAMPOLINE is custom lowered.
  setOperationAction(ISD::INIT_TRAMPOLINE, MVT::Other, Custom);
  setOperationAction(ISD::ADJUST_TRAMPOLINE, MVT::Other, Custom);

  // VASTART needs to be custom lowered to use the VarArgsFrameIndex
  setOperationAction(ISD::VASTART           , MVT::Other, Custom);

  if (Subtarget.is64BitELFABI()) {
    // VAARG always uses double-word chunks, so promote anything smaller.
    setOperationAction(ISD::VAARG, MVT::i1, Promote);
    AddPromotedToType(ISD::VAARG, MVT::i1, MVT::i64);
    setOperationAction(ISD::VAARG, MVT::i8, Promote);
    AddPromotedToType(ISD::VAARG, MVT::i8, MVT::i64);
    setOperationAction(ISD::VAARG, MVT::i16, Promote);
    AddPromotedToType(ISD::VAARG, MVT::i16, MVT::i64);
    setOperationAction(ISD::VAARG, MVT::i32, Promote);
    AddPromotedToType(ISD::VAARG, MVT::i32, MVT::i64);
    setOperationAction(ISD::VAARG, MVT::Other, Expand);
  } else if (Subtarget.is32BitELFABI()) {
    // VAARG is custom lowered with the 32-bit SVR4 ABI.
    setOperationAction(ISD::VAARG, MVT::Other, Custom);
    setOperationAction(ISD::VAARG, MVT::i64, Custom);
  } else
    setOperationAction(ISD::VAARG, MVT::Other, Expand);

  // VACOPY is custom lowered with the 32-bit SVR4 ABI.
  if (Subtarget.is32BitELFABI())
    setOperationAction(ISD::VACOPY            , MVT::Other, Custom);
  else
    setOperationAction(ISD::VACOPY            , MVT::Other, Expand);

  // Use the default implementation.
  setOperationAction(ISD::VAEND             , MVT::Other, Expand);
  setOperationAction(ISD::STACKSAVE         , MVT::Other, Expand);
  setOperationAction(ISD::STACKRESTORE      , MVT::Other, Custom);
  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32  , Custom);
  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64  , Custom);
  setOperationAction(ISD::GET_DYNAMIC_AREA_OFFSET, MVT::i32, Custom);
  setOperationAction(ISD::GET_DYNAMIC_AREA_OFFSET, MVT::i64, Custom);
  setOperationAction(ISD::EH_DWARF_CFA, MVT::i32, Custom);
  setOperationAction(ISD::EH_DWARF_CFA, MVT::i64, Custom);

  if (Subtarget.isISA3_0() && isPPC64) {
    setOperationAction(ISD::VP_STORE, MVT::v16i1, Custom);
    setOperationAction(ISD::VP_STORE, MVT::v8i1, Custom);
    setOperationAction(ISD::VP_STORE, MVT::v4i1, Custom);
    setOperationAction(ISD::VP_STORE, MVT::v2i1, Custom);
    setOperationAction(ISD::VP_LOAD, MVT::v16i1, Custom);
    setOperationAction(ISD::VP_LOAD, MVT::v8i1, Custom);
    setOperationAction(ISD::VP_LOAD, MVT::v4i1, Custom);
    setOperationAction(ISD::VP_LOAD, MVT::v2i1, Custom);
  }

  // We want to custom lower some of our intrinsics.
  setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
  setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::f64, Custom);
  setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::ppcf128, Custom);
  setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::v4f32, Custom);
  setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::v2f64, Custom);

  // To handle counter-based loop conditions.
  setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i1, Custom);
  setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);

  setOperationAction(ISD::INTRINSIC_VOID, MVT::i8, Custom);
  setOperationAction(ISD::INTRINSIC_VOID, MVT::i16, Custom);
  setOperationAction(ISD::INTRINSIC_VOID, MVT::i32, Custom);
  setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);

  // Comparisons that require checking two conditions.
  if (Subtarget.hasSPE()) {
    setCondCodeAction(ISD::SETO, MVT::f32, Expand);
    setCondCodeAction(ISD::SETO, MVT::f64, Expand);
    setCondCodeAction(ISD::SETUO, MVT::f32, Expand);
    setCondCodeAction(ISD::SETUO, MVT::f64, Expand);
  }
  setCondCodeAction(ISD::SETULT, MVT::f32, Expand);
  setCondCodeAction(ISD::SETULT, MVT::f64, Expand);
  setCondCodeAction(ISD::SETUGT, MVT::f32, Expand);
  setCondCodeAction(ISD::SETUGT, MVT::f64, Expand);
  setCondCodeAction(ISD::SETUEQ, MVT::f32, Expand);
  setCondCodeAction(ISD::SETUEQ, MVT::f64, Expand);
  setCondCodeAction(ISD::SETOGE, MVT::f32, Expand);
  setCondCodeAction(ISD::SETOGE, MVT::f64, Expand);
  setCondCodeAction(ISD::SETOLE, MVT::f32, Expand);
  setCondCodeAction(ISD::SETOLE, MVT::f64, Expand);
  setCondCodeAction(ISD::SETONE, MVT::f32, Expand);
  setCondCodeAction(ISD::SETONE, MVT::f64, Expand);

  setOperationAction(ISD::STRICT_FP_EXTEND, MVT::f32, Legal);
  setOperationAction(ISD::STRICT_FP_EXTEND, MVT::f64, Legal);

  if (Subtarget.has64BitSupport()) {
    // They also have instructions for converting between i64 and fp.
    setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i64, Custom);
    setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i64, Expand);
    setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i64, Custom);
    setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i64, Expand);
    setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
    setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand);
    setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
    setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand);
    // This is just the low 32 bits of a (signed) fp->i64 conversion.
    // We cannot do this with Promote because i64 is not a legal type.
    setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Custom);
    setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);

    if (Subtarget.hasLFIWAX() || isPPC64) {
      setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
      setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i32, Custom);
    }
  } else {
    // PowerPC does not have FP_TO_UINT on 32-bit implementations.
    if (Subtarget.hasSPE()) {
      setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Legal);
      setOperationAction(ISD::FP_TO_UINT, MVT::i32, Legal);
    } else {
      setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Expand);
      setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
    }
  }

  // With the instructions enabled under FPCVT, we can do everything.
  if (Subtarget.hasFPCVT()) {
    if (Subtarget.has64BitSupport()) {
      setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i64, Custom);
      setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i64, Custom);
      setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i64, Custom);
      setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i64, Custom);
      setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
      setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom);
      setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
      setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
    }

    setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i32, Custom);
    setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Custom);
    setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i32, Custom);
    setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i32, Custom);
    setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
    setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
    setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
    setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom);
  }

  if (Subtarget.use64BitRegs()) {
    // 64-bit PowerPC implementations can support i64 types directly
    addRegisterClass(MVT::i64, &PPC::G8RCRegClass);
    // BUILD_PAIR can't be handled natively, and should be expanded to shl/or
    setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand);
    // 64-bit PowerPC wants to expand i128 shifts itself.
    setOperationAction(ISD::SHL_PARTS, MVT::i64, Custom);
    setOperationAction(ISD::SRA_PARTS, MVT::i64, Custom);
    setOperationAction(ISD::SRL_PARTS, MVT::i64, Custom);
  } else {
    // 32-bit PowerPC wants to expand i64 shifts itself.
    setOperationAction(ISD::SHL_PARTS, MVT::i32, Custom);
    setOperationAction(ISD::SRA_PARTS, MVT::i32, Custom);
    setOperationAction(ISD::SRL_PARTS, MVT::i32, Custom);
  }

  // PowerPC has better expansions for funnel shifts than the generic
  // TargetLowering::expandFunnelShift.
  if (Subtarget.has64BitSupport()) {
    setOperationAction(ISD::FSHL, MVT::i64, Custom);
    setOperationAction(ISD::FSHR, MVT::i64, Custom);
  }
  setOperationAction(ISD::FSHL, MVT::i32, Custom);
  setOperationAction(ISD::FSHR, MVT::i32, Custom);

  if (Subtarget.hasVSX()) {
    setOperationAction(ISD::FMAXNUM_IEEE, MVT::f64, Legal);
    setOperationAction(ISD::FMAXNUM_IEEE, MVT::f32, Legal);
    setOperationAction(ISD::FMINNUM_IEEE, MVT::f64, Legal);
    setOperationAction(ISD::FMINNUM_IEEE, MVT::f32, Legal);
    setOperationAction(ISD::FMAXNUM, MVT::f64, Legal);
    setOperationAction(ISD::FMAXNUM, MVT::f32, Legal);
    setOperationAction(ISD::FMINNUM, MVT::f64, Legal);
    setOperationAction(ISD::FMINNUM, MVT::f32, Legal);
    setOperationAction(ISD::FCANONICALIZE, MVT::f64, Legal);
    setOperationAction(ISD::FCANONICALIZE, MVT::f32, Legal);
  }

  if (Subtarget.hasAltivec()) {
    for (MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
      setOperationAction(ISD::SADDSAT, VT, Legal);
      setOperationAction(ISD::SSUBSAT, VT, Legal);
      setOperationAction(ISD::UADDSAT, VT, Legal);
      setOperationAction(ISD::USUBSAT, VT, Legal);
    }
    // First set operation action for all vector types to expand. Then we
    // will selectively turn on ones that can be effectively codegen'd.
    for (MVT VT : MVT::fixedlen_vector_valuetypes()) {
      // add/sub are legal for all supported vector VT's.
      setOperationAction(ISD::ADD, VT, Legal);
      setOperationAction(ISD::SUB, VT, Legal);

      // For v2i64, these are only valid with P8Vector. This is corrected after
      // the loop.
      if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
        setOperationAction(ISD::SMAX, VT, Legal);
        setOperationAction(ISD::SMIN, VT, Legal);
        setOperationAction(ISD::UMAX, VT, Legal);
        setOperationAction(ISD::UMIN, VT, Legal);
      }
      else {
        setOperationAction(ISD::SMAX, VT, Expand);
        setOperationAction(ISD::SMIN, VT, Expand);
        setOperationAction(ISD::UMAX, VT, Expand);
        setOperationAction(ISD::UMIN, VT, Expand);
      }

      if (Subtarget.hasVSX()) {
        setOperationAction(ISD::FMAXNUM_IEEE, VT, Legal);
        setOperationAction(ISD::FMINNUM_IEEE, VT, Legal);
        setOperationAction(ISD::FMAXNUM, VT, Legal);
        setOperationAction(ISD::FMINNUM, VT, Legal);
        setOperationAction(ISD::FCANONICALIZE, VT, Legal);
      }

      // Vector instructions introduced in P8
      if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
        setOperationAction(ISD::CTPOP, VT, Legal);
        setOperationAction(ISD::CTLZ, VT, Legal);
      }
      else {
        setOperationAction(ISD::CTPOP, VT, Expand);
        setOperationAction(ISD::CTLZ, VT, Expand);
      }

      // Vector instructions introduced in P9
      if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
        setOperationAction(ISD::CTTZ, VT, Legal);
      else
        setOperationAction(ISD::CTTZ, VT, Expand);

      // We promote all shuffles to v16i8.
      setOperationAction(ISD::VECTOR_SHUFFLE, VT, Promote);
      AddPromotedToType (ISD::VECTOR_SHUFFLE, VT, MVT::v16i8);

      // We promote all non-typed operations to v4i32.
      setOperationAction(ISD::AND   , VT, Promote);
      AddPromotedToType (ISD::AND   , VT, MVT::v4i32);
      setOperationAction(ISD::OR    , VT, Promote);
      AddPromotedToType (ISD::OR    , VT, MVT::v4i32);
      setOperationAction(ISD::XOR   , VT, Promote);
      AddPromotedToType (ISD::XOR   , VT, MVT::v4i32);
      setOperationAction(ISD::LOAD  , VT, Promote);
      AddPromotedToType (ISD::LOAD  , VT, MVT::v4i32);
      setOperationAction(ISD::SELECT, VT, Promote);
      AddPromotedToType (ISD::SELECT, VT, MVT::v4i32);
      setOperationAction(ISD::VSELECT, VT, Legal);
      setOperationAction(ISD::SELECT_CC, VT, Promote);
      AddPromotedToType (ISD::SELECT_CC, VT, MVT::v4i32);
      setOperationAction(ISD::STORE, VT, Promote);
      AddPromotedToType (ISD::STORE, VT, MVT::v4i32);

      // No other operations are legal.
      setOperationAction(ISD::MUL , VT, Expand);
      setOperationAction(ISD::SDIV, VT, Expand);
      setOperationAction(ISD::SREM, VT, Expand);
      setOperationAction(ISD::UDIV, VT, Expand);
      setOperationAction(ISD::UREM, VT, Expand);
      setOperationAction(ISD::FDIV, VT, Expand);
      setOperationAction(ISD::FREM, VT, Expand);
      setOperationAction(ISD::FNEG, VT, Expand);
      setOperationAction(ISD::FSQRT, VT, Expand);
      setOperationAction(ISD::FLOG, VT, Expand);
      setOperationAction(ISD::FLOG10, VT, Expand);
      setOperationAction(ISD::FLOG2, VT, Expand);
      setOperationAction(ISD::FEXP, VT, Expand);
      setOperationAction(ISD::FEXP2, VT, Expand);
      setOperationAction(ISD::FSIN, VT, Expand);
      setOperationAction(ISD::FCOS, VT, Expand);
      setOperationAction(ISD::FABS, VT, Expand);
      setOperationAction(ISD::FFLOOR, VT, Expand);
      setOperationAction(ISD::FCEIL,  VT, Expand);
      setOperationAction(ISD::FTRUNC, VT, Expand);
      setOperationAction(ISD::FRINT,  VT, Expand);
      setOperationAction(ISD::FLDEXP, VT, Expand);
      setOperationAction(ISD::FNEARBYINT, VT, Expand);
      setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT, Expand);
      setOperationAction(ISD::INSERT_VECTOR_ELT, VT, Expand);
      setOperationAction(ISD::BUILD_VECTOR, VT, Expand);
      setOperationAction(ISD::MULHU, VT, Expand);
      setOperationAction(ISD::MULHS, VT, Expand);
      setOperationAction(ISD::UMUL_LOHI, VT, Expand);
      setOperationAction(ISD::SMUL_LOHI, VT, Expand);
      setOperationAction(ISD::UDIVREM, VT, Expand);
      setOperationAction(ISD::SDIVREM, VT, Expand);
      setOperationAction(ISD::SCALAR_TO_VECTOR, VT, Expand);
      setOperationAction(ISD::FPOW, VT, Expand);
      setOperationAction(ISD::BSWAP, VT, Expand);
      setOperationAction(ISD::SIGN_EXTEND_INREG, VT, Expand);
      setOperationAction(ISD::ROTL, VT, Expand);
      setOperationAction(ISD::ROTR, VT, Expand);

      for (MVT InnerVT : MVT::fixedlen_vector_valuetypes()) {
        setTruncStoreAction(VT, InnerVT, Expand);
        setLoadExtAction(ISD::SEXTLOAD, VT, InnerVT, Expand);
        setLoadExtAction(ISD::ZEXTLOAD, VT, InnerVT, Expand);
        setLoadExtAction(ISD::EXTLOAD, VT, InnerVT, Expand);
      }
    }
    setOperationAction(ISD::SELECT_CC, MVT::v4i32, Expand);
    if (!Subtarget.hasP8Vector()) {
      setOperationAction(ISD::SMAX, MVT::v2i64, Expand);
      setOperationAction(ISD::SMIN, MVT::v2i64, Expand);
      setOperationAction(ISD::UMAX, MVT::v2i64, Expand);
      setOperationAction(ISD::UMIN, MVT::v2i64, Expand);
    }

    // We can custom expand all VECTOR_SHUFFLEs to VPERM, others we can handle
    // with merges, splats, etc.
    setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v16i8, Custom);

    // Vector truncates to sub-word integer that fit in an Altivec/VSX register
    // are cheap, so handle them before they get expanded to scalar.
    setOperationAction(ISD::TRUNCATE, MVT::v8i8, Custom);
    setOperationAction(ISD::TRUNCATE, MVT::v4i8, Custom);
    setOperationAction(ISD::TRUNCATE, MVT::v2i8, Custom);
    setOperationAction(ISD::TRUNCATE, MVT::v4i16, Custom);
    setOperationAction(ISD::TRUNCATE, MVT::v2i16, Custom);

    setOperationAction(ISD::AND   , MVT::v4i32, Legal);
    setOperationAction(ISD::OR    , MVT::v4i32, Legal);
    setOperationAction(ISD::XOR   , MVT::v4i32, Legal);
    setOperationAction(ISD::LOAD  , MVT::v4i32, Legal);
    setOperationAction(ISD::SELECT, MVT::v4i32,
                       Subtarget.useCRBits() ? Legal : Expand);
    setOperationAction(ISD::STORE , MVT::v4i32, Legal);
    setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::v4i32, Legal);
    setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::v4i32, Legal);
    setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::v4i32, Legal);
    setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v4i32, Legal);
    setOperationAction(ISD::FP_TO_SINT, MVT::v4i32, Legal);
    setOperationAction(ISD::FP_TO_UINT, MVT::v4i32, Legal);
    setOperationAction(ISD::SINT_TO_FP, MVT::v4i32, Legal);
    setOperationAction(ISD::UINT_TO_FP, MVT::v4i32, Legal);
    setOperationAction(ISD::FFLOOR, MVT::v4f32, Legal);
    setOperationAction(ISD::FCEIL, MVT::v4f32, Legal);
    setOperationAction(ISD::FTRUNC, MVT::v4f32, Legal);
    setOperationAction(ISD::FNEARBYINT, MVT::v4f32, Legal);

    // Custom lowering ROTL v1i128 to VECTOR_SHUFFLE v16i8.
    setOperationAction(ISD::ROTL, MVT::v1i128, Custom);
    // With hasAltivec set, we can lower ISD::ROTL to vrl(b|h|w).
    if (Subtarget.hasAltivec())
      for (auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
        setOperationAction(ISD::ROTL, VT, Legal);
    // With hasP8Altivec set, we can lower ISD::ROTL to vrld.
    if (Subtarget.hasP8Altivec())
      setOperationAction(ISD::ROTL, MVT::v2i64, Legal);

    addRegisterClass(MVT::v4f32, &PPC::VRRCRegClass);
    addRegisterClass(MVT::v4i32, &PPC::VRRCRegClass);
    addRegisterClass(MVT::v8i16, &PPC::VRRCRegClass);
    addRegisterClass(MVT::v16i8, &PPC::VRRCRegClass);

    setOperationAction(ISD::MUL, MVT::v4f32, Legal);
    setOperationAction(ISD::FMA, MVT::v4f32, Legal);

    if (Subtarget.hasVSX()) {
      setOperationAction(ISD::FDIV, MVT::v4f32, Legal);
      setOperationAction(ISD::FSQRT, MVT::v4f32, Legal);
      setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v2f64, Custom);
    }

    if (Subtarget.hasP8Altivec())
      setOperationAction(ISD::MUL, MVT::v4i32, Legal);
    else
      setOperationAction(ISD::MUL, MVT::v4i32, Custom);

    if (Subtarget.isISA3_1()) {
      setOperationAction(ISD::MUL, MVT::v2i64, Legal);
      setOperationAction(ISD::MULHS, MVT::v2i64, Legal);
      setOperationAction(ISD::MULHU, MVT::v2i64, Legal);
      setOperationAction(ISD::MULHS, MVT::v4i32, Legal);
      setOperationAction(ISD::MULHU, MVT::v4i32, Legal);
      setOperationAction(ISD::UDIV, MVT::v2i64, Legal);
      setOperationAction(ISD::SDIV, MVT::v2i64, Legal);
      setOperationAction(ISD::UDIV, MVT::v4i32, Legal);
      setOperationAction(ISD::SDIV, MVT::v4i32, Legal);
      setOperationAction(ISD::UREM, MVT::v2i64, Legal);
      setOperationAction(ISD::SREM, MVT::v2i64, Legal);
      setOperationAction(ISD::UREM, MVT::v4i32, Legal);
      setOperationAction(ISD::SREM, MVT::v4i32, Legal);
      setOperationAction(ISD::UREM, MVT::v1i128, Legal);
      setOperationAction(ISD::SREM, MVT::v1i128, Legal);
      setOperationAction(ISD::UDIV, MVT::v1i128, Legal);
      setOperationAction(ISD::SDIV, MVT::v1i128, Legal);
      setOperationAction(ISD::ROTL, MVT::v1i128, Legal);
    }

    setOperationAction(ISD::MUL, MVT::v8i16, Legal);
    setOperationAction(ISD::MUL, MVT::v16i8, Custom);

    setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Custom);
    setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4i32, Custom);
    // LE is P8+/64-bit so direct moves are supported and these operations
    // are legal. The custom transformation requires 64-bit since we need a
    // pair of stores that will cover a 128-bit load for P10.
    if (!DisableP10StoreForward && isPPC64 && !Subtarget.isLittleEndian()) {
      setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v2i64, Custom);
      setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v8i16, Custom);
      setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v16i8, Custom);
    }

    setOperationAction(ISD::BUILD_VECTOR, MVT::v16i8, Custom);
    setOperationAction(ISD::BUILD_VECTOR, MVT::v8i16, Custom);
    setOperationAction(ISD::BUILD_VECTOR, MVT::v4i32, Custom);
    setOperationAction(ISD::BUILD_VECTOR, MVT::v4f32, Custom);

    // Altivec does not contain unordered floating-point compare instructions
    setCondCodeAction(ISD::SETUO, MVT::v4f32, Expand);
    setCondCodeAction(ISD::SETUEQ, MVT::v4f32, Expand);
    setCondCodeAction(ISD::SETO,   MVT::v4f32, Expand);
    setCondCodeAction(ISD::SETONE, MVT::v4f32, Expand);

    if (Subtarget.hasVSX()) {
      setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v2f64, Legal);
      setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v2f64, Legal);
      if (Subtarget.hasP8Vector()) {
        setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Legal);
        setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4f32, Legal);
      }
      if (Subtarget.hasDirectMove() && isPPC64) {
        setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v16i8, Legal);
        setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v8i16, Legal);
        setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4i32, Legal);
        setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v2i64, Legal);
        setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v16i8, Legal);
        setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v8i16, Legal);
        setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4i32, Legal);
        setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v2i64, Legal);
      }
      setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v2f64, Legal);

      // The nearbyint variants are not allowed to raise the inexact exception
      // so we can only code-gen them with fpexcept.ignore.
      setOperationAction(ISD::STRICT_FNEARBYINT, MVT::f64, Custom);
      setOperationAction(ISD::STRICT_FNEARBYINT, MVT::f32, Custom);
      setOperationAction(ISD::STRICT_FNEARBYINT, MVT::v2f64, Custom);
      setOperationAction(ISD::STRICT_FNEARBYINT, MVT::v4f32, Custom);

      setOperationAction(ISD::FFLOOR, MVT::v2f64, Legal);
      setOperationAction(ISD::FCEIL, MVT::v2f64, Legal);
      setOperationAction(ISD::FTRUNC, MVT::v2f64, Legal);
      setOperationAction(ISD::FRINT, MVT::v2f64, Legal);
      setOperationAction(ISD::FROUND, MVT::v2f64, Legal);
      setOperationAction(ISD::FROUND, MVT::f64, Legal);
      setOperationAction(ISD::FRINT, MVT::f64, Legal);

      setOperationAction(ISD::FRINT, MVT::v4f32, Legal);
      setOperationAction(ISD::FROUND, MVT::v4f32, Legal);
      setOperationAction(ISD::FROUND, MVT::f32, Legal);
      setOperationAction(ISD::FRINT, MVT::f32, Legal);

      setOperationAction(ISD::MUL, MVT::v2f64, Legal);
      setOperationAction(ISD::FMA, MVT::v2f64, Legal);

      setOperationAction(ISD::FDIV, MVT::v2f64, Legal);
      setOperationAction(ISD::FSQRT, MVT::v2f64, Legal);

      // Share the Altivec comparison restrictions.
      setCondCodeAction(ISD::SETUO, MVT::v2f64, Expand);
      setCondCodeAction(ISD::SETUEQ, MVT::v2f64, Expand);
      setCondCodeAction(ISD::SETO,   MVT::v2f64, Expand);
      setCondCodeAction(ISD::SETONE, MVT::v2f64, Expand);

      setOperationAction(ISD::LOAD, MVT::v2f64, Legal);
      setOperationAction(ISD::STORE, MVT::v2f64, Legal);

      setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v2f64, Custom);

      if (Subtarget.hasP8Vector())
        addRegisterClass(MVT::f32, &PPC::VSSRCRegClass);

      addRegisterClass(MVT::f64, &PPC::VSFRCRegClass);

      addRegisterClass(MVT::v4i32, &PPC::VSRCRegClass);
      addRegisterClass(MVT::v4f32, &PPC::VSRCRegClass);
      addRegisterClass(MVT::v2f64, &PPC::VSRCRegClass);

      if (Subtarget.hasP8Altivec()) {
        setOperationAction(ISD::SHL, MVT::v2i64, Legal);
        setOperationAction(ISD::SRA, MVT::v2i64, Legal);
        setOperationAction(ISD::SRL, MVT::v2i64, Legal);

        // 128 bit shifts can be accomplished via 3 instructions for SHL and
        // SRL, but not for SRA because of the instructions available:
        // VS{RL} and VS{RL}O. However due to direct move costs, it's not worth
        // doing
        setOperationAction(ISD::SHL, MVT::v1i128, Expand);
        setOperationAction(ISD::SRL, MVT::v1i128, Expand);
        setOperationAction(ISD::SRA, MVT::v1i128, Expand);

        setOperationAction(ISD::SETCC, MVT::v2i64, Legal);
      }
      else {
        setOperationAction(ISD::SHL, MVT::v2i64, Expand);
        setOperationAction(ISD::SRA, MVT::v2i64, Expand);
        setOperationAction(ISD::SRL, MVT::v2i64, Expand);

        setOperationAction(ISD::SETCC, MVT::v2i64, Custom);

        // VSX v2i64 only supports non-arithmetic operations.
        setOperationAction(ISD::ADD, MVT::v2i64, Expand);
        setOperationAction(ISD::SUB, MVT::v2i64, Expand);
      }

      if (Subtarget.isISA3_1())
        setOperationAction(ISD::SETCC, MVT::v1i128, Legal);
      else
        setOperationAction(ISD::SETCC, MVT::v1i128, Expand);

      setOperationAction(ISD::LOAD, MVT::v2i64, Promote);
      AddPromotedToType (ISD::LOAD, MVT::v2i64, MVT::v2f64);
      setOperationAction(ISD::STORE, MVT::v2i64, Promote);
      AddPromotedToType (ISD::STORE, MVT::v2i64, MVT::v2f64);

      setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v2i64, Custom);

      setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::v2i64, Legal);
      setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v2i64, Legal);
      setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::v2i64, Legal);
      setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::v2i64, Legal);
      setOperationAction(ISD::SINT_TO_FP, MVT::v2i64, Legal);
      setOperationAction(ISD::UINT_TO_FP, MVT::v2i64, Legal);
      setOperationAction(ISD::FP_TO_SINT, MVT::v2i64, Legal);
      setOperationAction(ISD::FP_TO_UINT, MVT::v2i64, Legal);

      // Custom handling for partial vectors of integers converted to
      // floating point. We already have optimal handling for v2i32 through
      // the DAG combine, so those aren't necessary.
      setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v2i8, Custom);
      setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v4i8, Custom);
      setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v2i16, Custom);
      setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v4i16, Custom);
      setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::v2i8, Custom);
      setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::v4i8, Custom);
      setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::v2i16, Custom);
      setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::v4i16, Custom);
      setOperationAction(ISD::UINT_TO_FP, MVT::v2i8, Custom);
      setOperationAction(ISD::UINT_TO_FP, MVT::v4i8, Custom);
      setOperationAction(ISD::UINT_TO_FP, MVT::v2i16, Custom);
      setOperationAction(ISD::UINT_TO_FP, MVT::v4i16, Custom);
      setOperationAction(ISD::SINT_TO_FP, MVT::v2i8, Custom);
      setOperationAction(ISD::SINT_TO_FP, MVT::v4i8, Custom);
      setOperationAction(ISD::SINT_TO_FP, MVT::v2i16, Custom);
      setOperationAction(ISD::SINT_TO_FP, MVT::v4i16, Custom);

      setOperationAction(ISD::FNEG, MVT::v4f32, Legal);
      setOperationAction(ISD::FNEG, MVT::v2f64, Legal);
      setOperationAction(ISD::FABS, MVT::v4f32, Legal);
      setOperationAction(ISD::FABS, MVT::v2f64, Legal);
      setOperationAction(ISD::FCOPYSIGN, MVT::v4f32, Legal);
      setOperationAction(ISD::FCOPYSIGN, MVT::v2f64, Legal);

      setOperationAction(ISD::BUILD_VECTOR, MVT::v2i64, Custom);
      setOperationAction(ISD::BUILD_VECTOR, MVT::v2f64, Custom);

      // Handle constrained floating-point operations of vector.
      // The predictor is `hasVSX` because altivec instruction has
      // no exception but VSX vector instruction has.
      setOperationAction(ISD::STRICT_FADD, MVT::v4f32, Legal);
      setOperationAction(ISD::STRICT_FSUB, MVT::v4f32, Legal);
      setOperationAction(ISD::STRICT_FMUL, MVT::v4f32, Legal);
      setOperationAction(ISD::STRICT_FDIV, MVT::v4f32, Legal);
      setOperationAction(ISD::STRICT_FMA, MVT::v4f32, Legal);
      setOperationAction(ISD::STRICT_FSQRT, MVT::v4f32, Legal);
      setOperationAction(ISD::STRICT_FMAXNUM, MVT::v4f32, Legal);
      setOperationAction(ISD::STRICT_FMINNUM, MVT::v4f32, Legal);
      setOperationAction(ISD::STRICT_FRINT, MVT::v4f32, Legal);
      setOperationAction(ISD::STRICT_FFLOOR, MVT::v4f32, Legal);
      setOperationAction(ISD::STRICT_FCEIL,  MVT::v4f32, Legal);
      setOperationAction(ISD::STRICT_FTRUNC, MVT::v4f32, Legal);
      setOperationAction(ISD::STRICT_FROUND, MVT::v4f32, Legal);

      setOperationAction(ISD::STRICT_FADD, MVT::v2f64, Legal);
      setOperationAction(ISD::STRICT_FSUB, MVT::v2f64, Legal);
      setOperationAction(ISD::STRICT_FMUL, MVT::v2f64, Legal);
      setOperationAction(ISD::STRICT_FDIV, MVT::v2f64, Legal);
      setOperationAction(ISD::STRICT_FMA, MVT::v2f64, Legal);
      setOperationAction(ISD::STRICT_FSQRT, MVT::v2f64, Legal);
      setOperationAction(ISD::STRICT_FMAXNUM, MVT::v2f64, Legal);
      setOperationAction(ISD::STRICT_FMINNUM, MVT::v2f64, Legal);
      setOperationAction(ISD::STRICT_FRINT, MVT::v2f64, Legal);
      setOperationAction(ISD::STRICT_FFLOOR, MVT::v2f64, Legal);
      setOperationAction(ISD::STRICT_FCEIL,  MVT::v2f64, Legal);
      setOperationAction(ISD::STRICT_FTRUNC, MVT::v2f64, Legal);
      setOperationAction(ISD::STRICT_FROUND, MVT::v2f64, Legal);

      addRegisterClass(MVT::v2i64, &PPC::VSRCRegClass);
      addRegisterClass(MVT::f128, &PPC::VRRCRegClass);

      for (MVT FPT : MVT::fp_valuetypes())
        setLoadExtAction(ISD::EXTLOAD, MVT::f128, FPT, Expand);

      // Expand the SELECT to SELECT_CC
      setOperationAction(ISD::SELECT, MVT::f128, Expand);

      setTruncStoreAction(MVT::f128, MVT::f64, Expand);
      setTruncStoreAction(MVT::f128, MVT::f32, Expand);

      // No implementation for these ops for PowerPC.
      setOperationAction(ISD::FSINCOS, MVT::f128, Expand);
      setOperationAction(ISD::FSIN, MVT::f128, Expand);
      setOperationAction(ISD::FCOS, MVT::f128, Expand);
      setOperationAction(ISD::FPOW, MVT::f128, Expand);
      setOperationAction(ISD::FPOWI, MVT::f128, Expand);
      setOperationAction(ISD::FREM, MVT::f128, LibCall);
    }

    if (Subtarget.hasP8Altivec()) {
      addRegisterClass(MVT::v2i64, &PPC::VRRCRegClass);
      addRegisterClass(MVT::v1i128, &PPC::VRRCRegClass);
    }

    if (Subtarget.hasP9Vector()) {
      setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4i32, Custom);
      setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4f32, Custom);

      // Test data class instructions store results in CR bits.
      if (Subtarget.useCRBits()) {
        setOperationAction(ISD::IS_FPCLASS, MVT::f32, Custom);
        setOperationAction(ISD::IS_FPCLASS, MVT::f64, Custom);
        setOperationAction(ISD::IS_FPCLASS, MVT::f128, Custom);
        setOperationAction(ISD::IS_FPCLASS, MVT::ppcf128, Custom);
      }

      // 128 bit shifts can be accomplished via 3 instructions for SHL and
      // SRL, but not for SRA because of the instructions available:
      // VS{RL} and VS{RL}O.
      setOperationAction(ISD::SHL, MVT::v1i128, Legal);
      setOperationAction(ISD::SRL, MVT::v1i128, Legal);
      setOperationAction(ISD::SRA, MVT::v1i128, Expand);

      setOperationAction(ISD::FADD, MVT::f128, Legal);
      setOperationAction(ISD::FSUB, MVT::f128, Legal);
      setOperationAction(ISD::FDIV, MVT::f128, Legal);
      setOperationAction(ISD::FMUL, MVT::f128, Legal);
      setOperationAction(ISD::FP_EXTEND, MVT::f128, Legal);

      setOperationAction(ISD::FMA, MVT::f128, Legal);
      setCondCodeAction(ISD::SETULT, MVT::f128, Expand);
      setCondCodeAction(ISD::SETUGT, MVT::f128, Expand);
      setCondCodeAction(ISD::SETUEQ, MVT::f128, Expand);
      setCondCodeAction(ISD::SETOGE, MVT::f128, Expand);
      setCondCodeAction(ISD::SETOLE, MVT::f128, Expand);
      setCondCodeAction(ISD::SETONE, MVT::f128, Expand);

      setOperationAction(ISD::FTRUNC, MVT::f128, Legal);
      setOperationAction(ISD::FRINT, MVT::f128, Legal);
      setOperationAction(ISD::FFLOOR, MVT::f128, Legal);
      setOperationAction(ISD::FCEIL, MVT::f128, Legal);
      setOperationAction(ISD::FNEARBYINT, MVT::f128, Legal);
      setOperationAction(ISD::FROUND, MVT::f128, Legal);

      setOperationAction(ISD::FP_ROUND, MVT::f64, Legal);
      setOperationAction(ISD::FP_ROUND, MVT::f32, Legal);
      setOperationAction(ISD::BITCAST, MVT::i128, Custom);

      // Handle constrained floating-point operations of fp128
      setOperationAction(ISD::STRICT_FADD, MVT::f128, Legal);
      setOperationAction(ISD::STRICT_FSUB, MVT::f128, Legal);
      setOperationAction(ISD::STRICT_FMUL, MVT::f128, Legal);
      setOperationAction(ISD::STRICT_FDIV, MVT::f128, Legal);
      setOperationAction(ISD::STRICT_FMA, MVT::f128, Legal);
      setOperationAction(ISD::STRICT_FSQRT, MVT::f128, Legal);
      setOperationAction(ISD::STRICT_FP_EXTEND, MVT::f128, Legal);
      setOperationAction(ISD::STRICT_FP_ROUND, MVT::f64, Legal);
      setOperationAction(ISD::STRICT_FP_ROUND, MVT::f32, Legal);
      setOperationAction(ISD::STRICT_FRINT, MVT::f128, Legal);
      setOperationAction(ISD::STRICT_FNEARBYINT, MVT::f128, Legal);
      setOperationAction(ISD::STRICT_FFLOOR, MVT::f128, Legal);
      setOperationAction(ISD::STRICT_FCEIL, MVT::f128, Legal);
      setOperationAction(ISD::STRICT_FTRUNC, MVT::f128, Legal);
      setOperationAction(ISD::STRICT_FROUND, MVT::f128, Legal);
      setOperationAction(ISD::FP_EXTEND, MVT::v2f32, Custom);
      setOperationAction(ISD::BSWAP, MVT::v8i16, Legal);
      setOperationAction(ISD::BSWAP, MVT::v4i32, Legal);
      setOperationAction(ISD::BSWAP, MVT::v2i64, Legal);
      setOperationAction(ISD::BSWAP, MVT::v1i128, Legal);
    } else if (Subtarget.hasVSX()) {
      setOperationAction(ISD::LOAD, MVT::f128, Promote);
      setOperationAction(ISD::STORE, MVT::f128, Promote);

      AddPromotedToType(ISD::LOAD, MVT::f128, MVT::v4i32);
      AddPromotedToType(ISD::STORE, MVT::f128, MVT::v4i32);

      // Set FADD/FSUB as libcall to avoid the legalizer to expand the
      // fp_to_uint and int_to_fp.
      setOperationAction(ISD::FADD, MVT::f128, LibCall);
      setOperationAction(ISD::FSUB, MVT::f128, LibCall);

      setOperationAction(ISD::FMUL, MVT::f128, Expand);
      setOperationAction(ISD::FDIV, MVT::f128, Expand);
      setOperationAction(ISD::FNEG, MVT::f128, Expand);
      setOperationAction(ISD::FABS, MVT::f128, Expand);
      setOperationAction(ISD::FSQRT, MVT::f128, Expand);
      setOperationAction(ISD::FMA, MVT::f128, Expand);
      setOperationAction(ISD::FCOPYSIGN, MVT::f128, Expand);

      // Expand the fp_extend if the target type is fp128.
      setOperationAction(ISD::FP_EXTEND, MVT::f128, Expand);
      setOperationAction(ISD::STRICT_FP_EXTEND, MVT::f128, Expand);

      // Expand the fp_round if the source type is fp128.
      for (MVT VT : {MVT::f32, MVT::f64}) {
        setOperationAction(ISD::FP_ROUND, VT, Custom);
        setOperationAction(ISD::STRICT_FP_ROUND, VT, Custom);
      }

      setOperationAction(ISD::SETCC, MVT::f128, Custom);
      setOperationAction(ISD::STRICT_FSETCC, MVT::f128, Custom);
      setOperationAction(ISD::STRICT_FSETCCS, MVT::f128, Custom);
      setOperationAction(ISD::BR_CC, MVT::f128, Expand);

      // Lower following f128 select_cc pattern:
      // select_cc x, y, tv, fv, cc -> select_cc (setcc x, y, cc), 0, tv, fv, NE
      setOperationAction(ISD::SELECT_CC, MVT::f128, Custom);

      // We need to handle f128 SELECT_CC with integer result type.
      setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
      setOperationAction(ISD::SELECT_CC, MVT::i64, isPPC64 ? Custom : Expand);
    }

    if (Subtarget.hasP9Altivec()) {
      if (Subtarget.isISA3_1()) {
        setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v2i64, Legal);
        setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v8i16, Legal);
        setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v16i8, Legal);
        setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4i32, Legal);
      } else {
        setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v8i16, Custom);
        setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v16i8, Custom);
      }
      setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::v4i8,  Legal);
      setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::v4i16, Legal);
      setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::v4i32, Legal);
      setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::v2i8,  Legal);
      setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::v2i16, Legal);
      setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::v2i32, Legal);
      setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::v2i64, Legal);

      setOperationAction(ISD::ABDU, MVT::v16i8, Legal);
      setOperationAction(ISD::ABDU, MVT::v8i16, Legal);
      setOperationAction(ISD::ABDU, MVT::v4i32, Legal);
      setOperationAction(ISD::ABDS, MVT::v4i32, Legal);
    }

    if (Subtarget.hasP10Vector()) {
      setOperationAction(ISD::SELECT_CC, MVT::f128, Custom);
    }
  }

  if (Subtarget.pairedVectorMemops()) {
    addRegisterClass(MVT::v256i1, &PPC::VSRpRCRegClass);
    setOperationAction(ISD::LOAD, MVT::v256i1, Custom);
    setOperationAction(ISD::STORE, MVT::v256i1, Custom);
  }
  if (Subtarget.hasMMA()) {
    if (Subtarget.isISAFuture()) {
      addRegisterClass(MVT::v512i1, &PPC::WACCRCRegClass);
      addRegisterClass(MVT::v1024i1, &PPC::DMRRCRegClass);
      addRegisterClass(MVT::v2048i1, &PPC::DMRpRCRegClass);
      setOperationAction(ISD::LOAD, MVT::v1024i1, Custom);
      setOperationAction(ISD::STORE, MVT::v1024i1, Custom);
      setOperationAction(ISD::LOAD, MVT::v2048i1, Custom);
      setOperationAction(ISD::STORE, MVT::v2048i1, Custom);
    } else {
      addRegisterClass(MVT::v512i1, &PPC::UACCRCRegClass);
    }
    setOperationAction(ISD::LOAD, MVT::v512i1, Custom);
    setOperationAction(ISD::STORE, MVT::v512i1, Custom);
    setOperationAction(ISD::BUILD_VECTOR, MVT::v512i1, Custom);
  }

  if (Subtarget.has64BitSupport())
    setOperationAction(ISD::PREFETCH, MVT::Other, Legal);

  if (Subtarget.isISA3_1())
    setOperationAction(ISD::SRA, MVT::v1i128, Legal);

  setOperationAction(ISD::READCYCLECOUNTER, MVT::i64, isPPC64 ? Legal : Custom);

  if (!isPPC64) {
    setOperationAction(ISD::ATOMIC_LOAD,  MVT::i64, Expand);
    setOperationAction(ISD::ATOMIC_STORE, MVT::i64, Expand);
  }

  if (shouldInlineQuadwordAtomics()) {
    setOperationAction(ISD::ATOMIC_LOAD, MVT::i128, Custom);
    setOperationAction(ISD::ATOMIC_STORE, MVT::i128, Custom);
    setOperationAction(ISD::INTRINSIC_VOID, MVT::i128, Custom);
  }

  setBooleanContents(ZeroOrOneBooleanContent);

  if (Subtarget.hasAltivec()) {
    // Altivec instructions set fields to all zeros or all ones.
    setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
  }

  if (shouldInlineQuadwordAtomics())
    setMaxAtomicSizeInBitsSupported(128);
  else if (isPPC64)
    setMaxAtomicSizeInBitsSupported(64);
  else
    setMaxAtomicSizeInBitsSupported(32);

  setStackPointerRegisterToSaveRestore(isPPC64 ? PPC::X1 : PPC::R1);

  // We have target-specific dag combine patterns for the following nodes:
  setTargetDAGCombine({ISD::AND, ISD::ADD, ISD::SHL, ISD::SRA, ISD::SRL,
                       ISD::MUL, ISD::FMA, ISD::SINT_TO_FP, ISD::BUILD_VECTOR});
  if (Subtarget.hasFPCVT())
    setTargetDAGCombine(ISD::UINT_TO_FP);
  setTargetDAGCombine({ISD::LOAD, ISD::STORE, ISD::BR_CC});
  if (Subtarget.useCRBits())
    setTargetDAGCombine(ISD::BRCOND);
  setTargetDAGCombine({ISD::BSWAP, ISD::INTRINSIC_WO_CHAIN,
                       ISD::INTRINSIC_W_CHAIN, ISD::INTRINSIC_VOID});

  setTargetDAGCombine({ISD::SIGN_EXTEND, ISD::ZERO_EXTEND, ISD::ANY_EXTEND});

  setTargetDAGCombine({ISD::TRUNCATE, ISD::VECTOR_SHUFFLE});

  if (Subtarget.useCRBits()) {
    setTargetDAGCombine({ISD::TRUNCATE, ISD::SETCC, ISD::SELECT_CC});
  }

  // With 32 condition bits, we don't need to sink (and duplicate) compares
  // aggressively in CodeGenPrep.
  if (Subtarget.useCRBits()) {
    setJumpIsExpensive();
  }

  // TODO: The default entry number is set to 64. This stops most jump table
  // generation on PPC. But it is good for current PPC HWs because the indirect
  // branch instruction mtctr to the jump table may lead to bad branch predict.
  // Re-evaluate this value on future HWs that can do better with mtctr.
  setMinimumJumpTableEntries(PPCMinimumJumpTableEntries);

  // The default minimum of largest number in a BitTest cluster is 3.
  setMinimumBitTestCmps(PPCMinimumBitTestCmps);

  setMinFunctionAlignment(Align(4));
  setMinCmpXchgSizeInBits(Subtarget.hasPartwordAtomics() ? 8 : 32);

  auto CPUDirective = Subtarget.getCPUDirective();
  switch (CPUDirective) {
  default: break;
  case PPC::DIR_970:
  case PPC::DIR_A2:
  case PPC::DIR_E500:
  case PPC::DIR_E500mc:
  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:
  case PPC::DIR_PWR9:
  case PPC::DIR_PWR10:
  case PPC::DIR_PWR11:
  case PPC::DIR_PWR_FUTURE:
    setPrefLoopAlignment(Align(16));
    setPrefFunctionAlignment(Align(16));
    break;
  }

  if (Subtarget.enableMachineScheduler())
    setSchedulingPreference(Sched::Source);
  else
    setSchedulingPreference(Sched::Hybrid);

  computeRegisterProperties(STI.getRegisterInfo());

  // The Freescale cores do better with aggressive inlining of memcpy and
  // friends. GCC uses same threshold of 128 bytes (= 32 word stores).
  if (CPUDirective == PPC::DIR_E500mc || CPUDirective == PPC::DIR_E5500) {
    MaxStoresPerMemset = 32;
    MaxStoresPerMemsetOptSize = 16;
    MaxStoresPerMemcpy = 32;
    MaxStoresPerMemcpyOptSize = 8;
    MaxStoresPerMemmove = 32;
    MaxStoresPerMemmoveOptSize = 8;
  } else if (CPUDirective == PPC::DIR_A2) {
    // The A2 also benefits from (very) aggressive inlining of memcpy and
    // friends. The overhead of a the function call, even when warm, can be
    // over one hundred cycles.
    MaxStoresPerMemset = 128;
    MaxStoresPerMemcpy = 128;
    MaxStoresPerMemmove = 128;
    MaxLoadsPerMemcmp = 128;
  } else {
    MaxLoadsPerMemcmp = 8;
    MaxLoadsPerMemcmpOptSize = 4;
  }

  // Enable generation of STXVP instructions by default for mcpu=future.
  if (CPUDirective == PPC::DIR_PWR_FUTURE &&
      DisableAutoPairedVecSt.getNumOccurrences() == 0)
    DisableAutoPairedVecSt = false;

  IsStrictFPEnabled = true;

  // Let the subtarget (CPU) decide if a predictable select is more expensive
  // than the corresponding branch. This information is used in CGP to decide
  // when to convert selects into branches.
  PredictableSelectIsExpensive = Subtarget.isPredictableSelectIsExpensive();

  GatherAllAliasesMaxDepth = PPCGatherAllAliasesMaxDepth;
}

// *********************************** NOTE ************************************
// For selecting load and store instructions, the addressing modes are defined
// as ComplexPatterns in PPCInstrInfo.td, which are then utilized in the TD
// patterns to match the load the store instructions.
//
// The TD definitions for the addressing modes correspond to their respective
// Select<AddrMode>Form() function in PPCISelDAGToDAG.cpp. These functions rely
// on SelectOptimalAddrMode(), which calls computeMOFlags() to compute the
// address mode flags of a particular node. Afterwards, the computed address
// flags are passed into getAddrModeForFlags() in order to retrieve the optimal
// addressing mode. SelectOptimalAddrMode() then sets the Base and Displacement
// accordingly, based on the preferred addressing mode.
//
// Within PPCISelLowering.h, there are two enums: MemOpFlags and AddrMode.
// MemOpFlags contains all the possible flags that can be used to compute the
// optimal addressing mode for load and store instructions.
// AddrMode contains all the possible load and store addressing modes available
// on Power (such as DForm, DSForm, DQForm, XForm, etc.)
//
// When adding new load and store instructions, it is possible that new address
// flags may need to be added into MemOpFlags, and a new addressing mode will
// need to be added to AddrMode. An entry of the new addressing mode (consisting
// of the minimal and main distinguishing address flags for the new load/store
// instructions) will need to be added into initializeAddrModeMap() below.
// Finally, when adding new addressing modes, the getAddrModeForFlags() will
// need to be updated to account for selecting the optimal addressing mode.
// *****************************************************************************
/// Initialize the map that relates the different addressing modes of the load
/// and store instructions to a set of flags. This ensures the load/store
/// instruction is correctly matched during instruction selection.
void PPCTargetLowering::initializeAddrModeMap() {
  AddrModesMap[PPC::AM_DForm] = {
      // LWZ, STW
      PPC::MOF_ZExt | PPC::MOF_RPlusSImm16 | PPC::MOF_WordInt,
      PPC::MOF_ZExt | PPC::MOF_RPlusLo | PPC::MOF_WordInt,
      PPC::MOF_ZExt | PPC::MOF_NotAddNorCst | PPC::MOF_WordInt,
      PPC::MOF_ZExt | PPC::MOF_AddrIsSImm32 | PPC::MOF_WordInt,
      // LBZ, LHZ, STB, STH
      PPC::MOF_ZExt | PPC::MOF_RPlusSImm16 | PPC::MOF_SubWordInt,
      PPC::MOF_ZExt | PPC::MOF_RPlusLo | PPC::MOF_SubWordInt,
      PPC::MOF_ZExt | PPC::MOF_NotAddNorCst | PPC::MOF_SubWordInt,
      PPC::MOF_ZExt | PPC::MOF_AddrIsSImm32 | PPC::MOF_SubWordInt,
      // LHA
      PPC::MOF_SExt | PPC::MOF_RPlusSImm16 | PPC::MOF_SubWordInt,
      PPC::MOF_SExt | PPC::MOF_RPlusLo | PPC::MOF_SubWordInt,
      PPC::MOF_SExt | PPC::MOF_NotAddNorCst | PPC::MOF_SubWordInt,
      PPC::MOF_SExt | PPC::MOF_AddrIsSImm32 | PPC::MOF_SubWordInt,
      // LFS, LFD, STFS, STFD
      PPC::MOF_RPlusSImm16 | PPC::MOF_ScalarFloat | PPC::MOF_SubtargetBeforeP9,
      PPC::MOF_RPlusLo | PPC::MOF_ScalarFloat | PPC::MOF_SubtargetBeforeP9,
      PPC::MOF_NotAddNorCst | PPC::MOF_ScalarFloat | PPC::MOF_SubtargetBeforeP9,
      PPC::MOF_AddrIsSImm32 | PPC::MOF_ScalarFloat | PPC::MOF_SubtargetBeforeP9,
  };
  AddrModesMap[PPC::AM_DSForm] = {
      // LWA
      PPC::MOF_SExt | PPC::MOF_RPlusSImm16Mult4 | PPC::MOF_WordInt,
      PPC::MOF_SExt | PPC::MOF_NotAddNorCst | PPC::MOF_WordInt,
      PPC::MOF_SExt | PPC::MOF_AddrIsSImm32 | PPC::MOF_WordInt,
      // LD, STD
      PPC::MOF_RPlusSImm16Mult4 | PPC::MOF_DoubleWordInt,
      PPC::MOF_NotAddNorCst | PPC::MOF_DoubleWordInt,
      PPC::MOF_AddrIsSImm32 | PPC::MOF_DoubleWordInt,
      // DFLOADf32, DFLOADf64, DSTOREf32, DSTOREf64
      PPC::MOF_RPlusSImm16Mult4 | PPC::MOF_ScalarFloat | PPC::MOF_SubtargetP9,
      PPC::MOF_NotAddNorCst | PPC::MOF_ScalarFloat | PPC::MOF_SubtargetP9,
      PPC::MOF_AddrIsSImm32 | PPC::MOF_ScalarFloat | PPC::MOF_SubtargetP9,
  };
  AddrModesMap[PPC::AM_DQForm] = {
      // LXV, STXV
      PPC::MOF_RPlusSImm16Mult16 | PPC::MOF_Vector | PPC::MOF_SubtargetP9,
      PPC::MOF_NotAddNorCst | PPC::MOF_Vector | PPC::MOF_SubtargetP9,
      PPC::MOF_AddrIsSImm32 | PPC::MOF_Vector | PPC::MOF_SubtargetP9,
  };
  AddrModesMap[PPC::AM_PrefixDForm] = {PPC::MOF_RPlusSImm34 |
                                       PPC::MOF_SubtargetP10};
  // TODO: Add mapping for quadword load/store.
}

/// getMaxByValAlign - Helper for getByValTypeAlignment to determine
/// the desired ByVal argument alignment.
static void getMaxByValAlign(Type *Ty, Align &MaxAlign, Align MaxMaxAlign) {
  if (MaxAlign == MaxMaxAlign)
    return;
  if (VectorType *VTy = dyn_cast<VectorType>(Ty)) {
    if (MaxMaxAlign >= 32 &&
        VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
      MaxAlign = Align(32);
    else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
             MaxAlign < 16)
      MaxAlign = Align(16);
  } else if (ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
    Align EltAlign;
    getMaxByValAlign(ATy->getElementType(), EltAlign, MaxMaxAlign);
    if (EltAlign > MaxAlign)
      MaxAlign = EltAlign;
  } else if (StructType *STy = dyn_cast<StructType>(Ty)) {
    for (auto *EltTy : STy->elements()) {
      Align EltAlign;
      getMaxByValAlign(EltTy, EltAlign, MaxMaxAlign);
      if (EltAlign > MaxAlign)
        MaxAlign = EltAlign;
      if (MaxAlign == MaxMaxAlign)
        break;
    }
  }
}

/// getByValTypeAlignment - Return the desired alignment for ByVal aggregate
/// function arguments in the caller parameter area.
Align PPCTargetLowering::getByValTypeAlignment(Type *Ty,
                                               const DataLayout &DL) const {
  // 16byte and wider vectors are passed on 16byte boundary.
  // The rest is 8 on PPC64 and 4 on PPC32 boundary.
  Align Alignment = Subtarget.isPPC64() ? Align(8) : Align(4);
  if (Subtarget.hasAltivec())
    getMaxByValAlign(Ty, Alignment, Align(16));
  return Alignment;
}

bool PPCTargetLowering::useSoftFloat() const {
  return Subtarget.useSoftFloat();
}

bool PPCTargetLowering::hasSPE() const {
  return Subtarget.hasSPE();
}

bool PPCTargetLowering::preferIncOfAddToSubOfNot(EVT VT) const {
  return VT.isScalarInteger();
}

bool PPCTargetLowering::shallExtractConstSplatVectorElementToStore(
    Type *VectorTy, unsigned ElemSizeInBits, unsigned &Index) const {
  if (!Subtarget.isPPC64() || !Subtarget.hasVSX())
    return false;

  if (auto *VTy = dyn_cast<VectorType>(VectorTy)) {
    if (VTy->getScalarType()->isIntegerTy()) {
      // ElemSizeInBits 8/16 can fit in immediate field, not needed here.
      if (ElemSizeInBits == 32) {
        Index = Subtarget.isLittleEndian() ? 2 : 1;
        return true;
      }
      if (ElemSizeInBits == 64) {
        Index = Subtarget.isLittleEndian() ? 1 : 0;
        return true;
      }
    }
  }
  return false;
}

EVT PPCTargetLowering::getSetCCResultType(const DataLayout &DL, LLVMContext &C,
                                          EVT VT) const {
  if (!VT.isVector())
    return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;

  return VT.changeVectorElementTypeToInteger();
}

bool PPCTargetLowering::enableAggressiveFMAFusion(EVT VT) const {
  assert(VT.isFloatingPoint() && "Non-floating-point FMA?");
  return true;
}

//===----------------------------------------------------------------------===//
// Node matching predicates, for use by the tblgen matching code.
//===----------------------------------------------------------------------===//

/// isFloatingPointZero - Return true if this is 0.0 or -0.0.
static bool isFloatingPointZero(SDValue Op) {
  if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(Op))
    return CFP->getValueAPF().isZero();
  else if (ISD::isEXTLoad(Op.getNode()) || ISD::isNON_EXTLoad(Op.getNode())) {
    // Maybe this has already been legalized into the constant pool?
    if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Op.getOperand(1)))
      if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
        return CFP->getValueAPF().isZero();
  }
  return false;
}

/// isConstantOrUndef - Op is either an undef node or a ConstantSDNode.  Return
/// true if Op is undef or if it matches the specified value.
static bool isConstantOrUndef(int Op, int Val) {
  return Op < 0 || Op == Val;
}

/// isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a
/// VPKUHUM instruction.
/// The ShuffleKind distinguishes between big-endian operations with
/// two different inputs (0), either-endian operations with two identical
/// inputs (1), and little-endian operations with two different inputs (2).
/// For the latter, the input operands are swapped (see PPCInstrAltivec.td).
bool PPC::isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind,
                               SelectionDAG &DAG) {
  bool IsLE = DAG.getDataLayout().isLittleEndian();
  if (ShuffleKind == 0) {
    if (IsLE)
      return false;
    for (unsigned i = 0; i != 16; ++i)
      if (!isConstantOrUndef(N->getMaskElt(i), i*2+1))
        return false;
  } else if (ShuffleKind == 2) {
    if (!IsLE)
      return false;
    for (unsigned i = 0; i != 16; ++i)
      if (!isConstantOrUndef(N->getMaskElt(i), i*2))
        return false;
  } else if (ShuffleKind == 1) {
    unsigned j = IsLE ? 0 : 1;
    for (unsigned i = 0; i != 8; ++i)
      if (!isConstantOrUndef(N->getMaskElt(i),    i*2+j) ||
          !isConstantOrUndef(N->getMaskElt(i+8),  i*2+j))
        return false;
  }
  return true;
}

/// isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a
/// VPKUWUM instruction.
/// The ShuffleKind distinguishes between big-endian operations with
/// two different inputs (0), either-endian operations with two identical
/// inputs (1), and little-endian operations with two different inputs (2).
/// For the latter, the input operands are swapped (see PPCInstrAltivec.td).
bool PPC::isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind,
                               SelectionDAG &DAG) {
  bool IsLE = DAG.getDataLayout().isLittleEndian();
  if (ShuffleKind == 0) {
    if (IsLE)
      return false;
    for (unsigned i = 0; i != 16; i += 2)
      if (!isConstantOrUndef(N->getMaskElt(i  ),  i*2+2) ||
          !isConstantOrUndef(N->getMaskElt(i+1),  i*2+3))
        return false;
  } else if (ShuffleKind == 2) {
    if (!IsLE)
      return false;
    for (unsigned i = 0; i != 16; i += 2)
      if (!isConstantOrUndef(N->getMaskElt(i  ),  i*2) ||
          !isConstantOrUndef(N->getMaskElt(i+1),  i*2+1))
        return false;
  } else if (ShuffleKind == 1) {
    unsigned j = IsLE ? 0 : 2;
    for (unsigned i = 0; i != 8; i += 2)
      if (!isConstantOrUndef(N->getMaskElt(i  ),  i*2+j)   ||
          !isConstantOrUndef(N->getMaskElt(i+1),  i*2+j+1) ||
          !isConstantOrUndef(N->getMaskElt(i+8),  i*2+j)   ||
          !isConstantOrUndef(N->getMaskElt(i+9),  i*2+j+1))
        return false;
  }
  return true;
}

/// isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a
/// VPKUDUM instruction, AND the VPKUDUM instruction exists for the
/// current subtarget.
///
/// The ShuffleKind distinguishes between big-endian operations with
/// two different inputs (0), either-endian operations with two identical
/// inputs (1), and little-endian operations with two different inputs (2).
/// For the latter, the input operands are swapped (see PPCInstrAltivec.td).
bool PPC::isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind,
                               SelectionDAG &DAG) {
  const PPCSubtarget &Subtarget = DAG.getSubtarget<PPCSubtarget>();
  if (!Subtarget.hasP8Vector())
    return false;

  bool IsLE = DAG.getDataLayout().isLittleEndian();
  if (ShuffleKind == 0) {
    if (IsLE)
      return false;
    for (unsigned i = 0; i != 16; i += 4)
      if (!isConstantOrUndef(N->getMaskElt(i  ),  i*2+4) ||
          !isConstantOrUndef(N->getMaskElt(i+1),  i*2+5) ||
          !isConstantOrUndef(N->getMaskElt(i+2),  i*2+6) ||
          !isConstantOrUndef(N->getMaskElt(i+3),  i*2+7))
        return false;
  } else if (ShuffleKind == 2) {
    if (!IsLE)
      return false;
    for (unsigned i = 0; i != 16; i += 4)
      if (!isConstantOrUndef(N->getMaskElt(i  ),  i*2) ||
          !isConstantOrUndef(N->getMaskElt(i+1),  i*2+1) ||
          !isConstantOrUndef(N->getMaskElt(i+2),  i*2+2) ||
          !isConstantOrUndef(N->getMaskElt(i+3),  i*2+3))
        return false;
  } else if (ShuffleKind == 1) {
    unsigned j = IsLE ? 0 : 4;
    for (unsigned i = 0; i != 8; i += 4)
      if (!isConstantOrUndef(N->getMaskElt(i  ),  i*2+j)   ||
          !isConstantOrUndef(N->getMaskElt(i+1),  i*2+j+1) ||
          !isConstantOrUndef(N->getMaskElt(i+2),  i*2+j+2) ||
          !isConstantOrUndef(N->getMaskElt(i+3),  i*2+j+3) ||
          !isConstantOrUndef(N->getMaskElt(i+8),  i*2+j)   ||
          !isConstantOrUndef(N->getMaskElt(i+9),  i*2+j+1) ||
          !isConstantOrUndef(N->getMaskElt(i+10), i*2+j+2) ||
          !isConstantOrUndef(N->getMaskElt(i+11), i*2+j+3))
        return false;
  }
  return true;
}

/// isVMerge - Common function, used to match vmrg* shuffles.
///
static bool isVMerge(ShuffleVectorSDNode *N, unsigned UnitSize,
                     unsigned LHSStart, unsigned RHSStart) {
  if (N->getValueType(0) != MVT::v16i8)
    return false;
  assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
         "Unsupported merge size!");

  for (unsigned i = 0; i != 8/UnitSize; ++i)     // Step over units
    for (unsigned j = 0; j != UnitSize; ++j) {   // Step over bytes within unit
      if (!isConstantOrUndef(N->getMaskElt(i*UnitSize*2+j),
                             LHSStart+j+i*UnitSize) ||
          !isConstantOrUndef(N->getMaskElt(i*UnitSize*2+UnitSize+j),
                             RHSStart+j+i*UnitSize))
        return false;
    }
  return true;
}

/// isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for
/// a VMRGL* instruction with the specified unit size (1,2 or 4 bytes).
/// The ShuffleKind distinguishes between big-endian merges with two
/// different inputs (0), either-endian merges with two identical inputs (1),
/// and little-endian merges with two different inputs (2).  For the latter,
/// the input operands are swapped (see PPCInstrAltivec.td).
bool PPC::isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize,
                             unsigned ShuffleKind, SelectionDAG &DAG) {
  if (DAG.getDataLayout().isLittleEndian()) {
    if (ShuffleKind == 1) // unary
      return isVMerge(N, UnitSize, 0, 0);
    else if (ShuffleKind == 2) // swapped
      return isVMerge(N, UnitSize, 0, 16);
    else
      return false;
  } else {
    if (ShuffleKind == 1) // unary
      return isVMerge(N, UnitSize, 8, 8);
    else if (ShuffleKind == 0) // normal
      return isVMerge(N, UnitSize, 8, 24);
    else
      return false;
  }
}

/// isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for
/// a VMRGH* instruction with the specified unit size (1,2 or 4 bytes).
/// The ShuffleKind distinguishes between big-endian merges with two
/// different inputs (0), either-endian merges with two identical inputs (1),
/// and little-endian merges with two different inputs (2).  For the latter,
/// the input operands are swapped (see PPCInstrAltivec.td).
bool PPC::isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize,
                             unsigned ShuffleKind, SelectionDAG &DAG) {
  if (DAG.getDataLayout().isLittleEndian()) {
    if (ShuffleKind == 1) // unary
      return isVMerge(N, UnitSize, 8, 8);
    else if (ShuffleKind == 2) // swapped
      return isVMerge(N, UnitSize, 8, 24);
    else
      return false;
  } else {
    if (ShuffleKind == 1) // unary
      return isVMerge(N, UnitSize, 0, 0);
    else if (ShuffleKind == 0) // normal
      return isVMerge(N, UnitSize, 0, 16);
    else
      return false;
  }
}

/**
 * Common function used to match vmrgew and vmrgow shuffles
 *
 * The indexOffset determines whether to look for even or odd words in
 * the shuffle mask. This is based on the of the endianness of the target
 * machine.
 *   - Little Endian:
 *     - Use offset of 0 to check for odd elements
 *     - Use offset of 4 to check for even elements
 *   - Big Endian:
 *     - Use offset of 0 to check for even elements
 *     - Use offset of 4 to check for odd elements
 * A detailed description of the vector element ordering for little endian and
 * big endian can be found at
 * http://www.ibm.com/developerworks/library/l-ibm-xl-c-cpp-compiler/index.html
 * Targeting your applications - what little endian and big endian IBM XL C/C++
 * compiler differences mean to you
 *
 * The mask to the shuffle vector instruction specifies the indices of the
 * elements from the two input vectors to place in the result. The elements are
 * numbered in array-access order, starting with the first vector. These vectors
 * are always of type v16i8, thus each vector will contain 16 elements of size
 * 8. More info on the shuffle vector can be found in the
 * http://llvm.org/docs/LangRef.html#shufflevector-instruction
 * Language Reference.
 *
 * The RHSStartValue indicates whether the same input vectors are used (unary)
 * or two different input vectors are used, based on the following:
 *   - If the instruction uses the same vector for both inputs, the range of the
 *     indices will be 0 to 15. In this case, the RHSStart value passed should
 *     be 0.
 *   - If the instruction has two different vectors then the range of the
 *     indices will be 0 to 31. In this case, the RHSStart value passed should
 *     be 16 (indices 0-15 specify elements in the first vector while indices 16
 *     to 31 specify elements in the second vector).
 *
 * \param[in] N The shuffle vector SD Node to analyze
 * \param[in] IndexOffset Specifies whether to look for even or odd elements
 * \param[in] RHSStartValue Specifies the starting index for the righthand input
 * vector to the shuffle_vector instruction
 * \return true iff this shuffle vector represents an even or odd word merge
 */
static bool isVMerge(ShuffleVectorSDNode *N, unsigned IndexOffset,
                     unsigned RHSStartValue) {
  if (N->getValueType(0) != MVT::v16i8)
    return false;

  for (unsigned i = 0; i < 2; ++i)
    for (unsigned j = 0; j < 4; ++j)
      if (!isConstantOrUndef(N->getMaskElt(i*4+j),
                             i*RHSStartValue+j+IndexOffset) ||
          !isConstantOrUndef(N->getMaskElt(i*4+j+8),
                             i*RHSStartValue+j+IndexOffset+8))
        return false;
  return true;
}

/**
 * Determine if the specified shuffle mask is suitable for the vmrgew or
 * vmrgow instructions.
 *
 * \param[in] N The shuffle vector SD Node to analyze
 * \param[in] CheckEven Check for an even merge (true) or an odd merge (false)
 * \param[in] ShuffleKind Identify the type of merge:
 *   - 0 = big-endian merge with two different inputs;
 *   - 1 = either-endian merge with two identical inputs;
 *   - 2 = little-endian merge with two different inputs (inputs are swapped for
 *     little-endian merges).
 * \param[in] DAG The current SelectionDAG
 * \return true iff this shuffle mask
 */
bool PPC::isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven,
                              unsigned ShuffleKind, SelectionDAG &DAG) {
  if (DAG.getDataLayout().isLittleEndian()) {
    unsigned indexOffset = CheckEven ? 4 : 0;
    if (ShuffleKind == 1) // Unary
      return isVMerge(N, indexOffset, 0);
    else if (ShuffleKind == 2) // swapped
      return isVMerge(N, indexOffset, 16);
    else
      return false;
  }
  else {
    unsigned indexOffset = CheckEven ? 0 : 4;
    if (ShuffleKind == 1) // Unary
      return isVMerge(N, indexOffset, 0);
    else if (ShuffleKind == 0) // Normal
      return isVMerge(N, indexOffset, 16);
    else
      return false;
  }
  return false;
}

/// isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift
/// amount, otherwise return -1.
/// The ShuffleKind distinguishes between big-endian operations with two
/// different inputs (0), either-endian operations with two identical inputs
/// (1), and little-endian operations with two different inputs (2).  For the
/// latter, the input operands are swapped (see PPCInstrAltivec.td).
int PPC::isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind,
                             SelectionDAG &DAG) {
  if (N->getValueType(0) != MVT::v16i8)
    return -1;

  ShuffleVectorSDNode *SVOp = cast<ShuffleVectorSDNode>(N);

  // Find the first non-undef value in the shuffle mask.
  unsigned i;
  for (i = 0; i != 16 && SVOp->getMaskElt(i) < 0; ++i)
    /*search*/;

  if (i == 16) return -1;  // all undef.

  // Otherwise, check to see if the rest of the elements are consecutively
  // numbered from this value.
  unsigned ShiftAmt = SVOp->getMaskElt(i);
  if (ShiftAmt < i) return -1;

  ShiftAmt -= i;
  bool isLE = DAG.getDataLayout().isLittleEndian();

  if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
    // Check the rest of the elements to see if they are consecutive.
    for (++i; i != 16; ++i)
      if (!isConstantOrUndef(SVOp->getMaskElt(i), ShiftAmt+i))
        return -1;
  } else if (ShuffleKind == 1) {
    // Check the rest of the elements to see if they are consecutive.
    for (++i; i != 16; ++i)
      if (!isConstantOrUndef(SVOp->getMaskElt(i), (ShiftAmt+i) & 15))
        return -1;
  } else
    return -1;

  if (isLE)
    ShiftAmt = 16 - ShiftAmt;

  return ShiftAmt;
}

/// isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand
/// specifies a splat of a single element that is suitable for input to
/// one of the splat operations (VSPLTB/VSPLTH/VSPLTW/XXSPLTW/LXVDSX/etc.).
bool PPC::isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize) {
  EVT VT = N->getValueType(0);
  if (VT == MVT::v2i64 || VT == MVT::v2f64)
    return EltSize == 8 && N->getMaskElt(0) == N->getMaskElt(1);

  assert(VT == MVT::v16i8 && isPowerOf2_32(EltSize) &&
         EltSize <= 8 && "Can only handle 1,2,4,8 byte element sizes");

  // The consecutive indices need to specify an element, not part of two
  // different elements.  So abandon ship early if this isn't the case.
  if (N->getMaskElt(0) % EltSize != 0)
    return false;

  // This is a splat operation if each element of the permute is the same, and
  // if the value doesn't reference the second vector.
  unsigned ElementBase = N->getMaskElt(0);

  // FIXME: Handle UNDEF elements too!
  if (ElementBase >= 16)
    return false;

  // Check that the indices are consecutive, in the case of a multi-byte element
  // splatted with a v16i8 mask.
  for (unsigned i = 1; i != EltSize; ++i)
    if (N->getMaskElt(i) < 0 || N->getMaskElt(i) != (int)(i+ElementBase))
      return false;

  for (unsigned i = EltSize, e = 16; i != e; i += EltSize) {
    // An UNDEF element is a sequence of UNDEF bytes.
    if (N->getMaskElt(i) < 0) {
      for (unsigned j = 1; j != EltSize; ++j)
        if (N->getMaskElt(i + j) >= 0)
          return false;
    } else
      for (unsigned j = 0; j != EltSize; ++j)
        if (N->getMaskElt(i + j) != N->getMaskElt(j))
          return false;
  }
  return true;
}

/// Check that the mask is shuffling N byte elements. Within each N byte
/// element of the mask, the indices could be either in increasing or
/// decreasing order as long as they are consecutive.
/// \param[in] N the shuffle vector SD Node to analyze
/// \param[in] Width the element width in bytes, could be 2/4/8/16 (HalfWord/
/// Word/DoubleWord/QuadWord).
/// \param[in] StepLen the delta indices number among the N byte element, if
/// the mask is in increasing/decreasing order then it is 1/-1.
/// \return true iff the mask is shuffling N byte elements.
static bool isNByteElemShuffleMask(ShuffleVectorSDNode *N, unsigned Width,
                                   int StepLen) {
  assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
         "Unexpected element width.");
  assert((StepLen == 1 || StepLen == -1) && "Unexpected element width.");

  unsigned NumOfElem = 16 / Width;
  unsigned MaskVal[16]; //  Width is never greater than 16
  for (unsigned i = 0; i < NumOfElem; ++i) {
    MaskVal[0] = N->getMaskElt(i * Width);
    if ((StepLen == 1) && (MaskVal[0] % Width)) {
      return false;
    } else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
      return false;
    }

    for (unsigned int j = 1; j < Width; ++j) {
      MaskVal[j] = N->getMaskElt(i * Width + j);
      if (MaskVal[j] != MaskVal[j-1] + StepLen) {
        return false;
      }
    }
  }

  return true;
}

bool PPC::isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts,
                          unsigned &InsertAtByte, bool &Swap, bool IsLE) {
  if (!isNByteElemShuffleMask(N, 4, 1))
    return false;

  // Now we look at mask elements 0,4,8,12
  unsigned M0 = N->getMaskElt(0) / 4;
  unsigned M1 = N->getMaskElt(4) / 4;
  unsigned M2 = N->getMaskElt(8) / 4;
  unsigned M3 = N->getMaskElt(12) / 4;
  unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
  unsigned BigEndianShifts[] = { 3, 0, 1, 2 };

  // Below, let H and L be arbitrary elements of the shuffle mask
  // where H is in the range [4,7] and L is in the range [0,3].
  // H, 1, 2, 3 or L, 5, 6, 7
  if ((M0 > 3 && M1 == 1 && M2 == 2 && M3 == 3) ||
      (M0 < 4 && M1 == 5 && M2 == 6 && M3 == 7)) {
    ShiftElts = IsLE ? LittleEndianShifts[M0 & 0x3] : BigEndianShifts[M0 & 0x3];
    InsertAtByte = IsLE ? 12 : 0;
    Swap = M0 < 4;
    return true;
  }
  // 0, H, 2, 3 or 4, L, 6, 7
  if ((M1 > 3 && M0 == 0 && M2 == 2 && M3 == 3) ||
      (M1 < 4 && M0 == 4 && M2 == 6 && M3 == 7)) {
    ShiftElts = IsLE ? LittleEndianShifts[M1 & 0x3] : BigEndianShifts[M1 & 0x3];
    InsertAtByte = IsLE ? 8 : 4;
    Swap = M1 < 4;
    return true;
  }
  // 0, 1, H, 3 or 4, 5, L, 7
  if ((M2 > 3 && M0 == 0 && M1 == 1 && M3 == 3) ||
      (M2 < 4 && M0 == 4 && M1 == 5 && M3 == 7)) {
    ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
    InsertAtByte = IsLE ? 4 : 8;
    Swap = M2 < 4;
    return true;
  }
  // 0, 1, 2, H or 4, 5, 6, L
  if ((M3 > 3 && M0 == 0 && M1 == 1 && M2 == 2) ||
      (M3 < 4 && M0 == 4 && M1 == 5 && M2 == 6)) {
    ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
    InsertAtByte = IsLE ? 0 : 12;
    Swap = M3 < 4;
    return true;
  }

  // If both vector operands for the shuffle are the same vector, the mask will
  // contain only elements from the first one and the second one will be undef.
  if (N->getOperand(1).isUndef()) {
    ShiftElts = 0;
    Swap = true;
    unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
    if (M0 == XXINSERTWSrcElem && M1 == 1 && M2 == 2 && M3 == 3) {
      InsertAtByte = IsLE ? 12 : 0;
      return true;
    }
    if (M0 == 0 && M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
      InsertAtByte = IsLE ? 8 : 4;
      return true;
    }
    if (M0 == 0 && M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
      InsertAtByte = IsLE ? 4 : 8;
      return true;
    }
    if (M0 == 0 && M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
      InsertAtByte = IsLE ? 0 : 12;
      return true;
    }
  }

  return false;
}

bool PPC::isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts,
                               bool &Swap, bool IsLE) {
  assert(N->getValueType(0) == MVT::v16i8 && "Shuffle vector expects v16i8");
  // Ensure each byte index of the word is consecutive.
  if (!isNByteElemShuffleMask(N, 4, 1))
    return false;

  // Now we look at mask elements 0,4,8,12, which are the beginning of words.
  unsigned M0 = N->getMaskElt(0) / 4;
  unsigned M1 = N->getMaskElt(4) / 4;
  unsigned M2 = N->getMaskElt(8) / 4;
  unsigned M3 = N->getMaskElt(12) / 4;

  // If both vector operands for the shuffle are the same vector, the mask will
  // contain only elements from the first one and the second one will be undef.
  if (N->getOperand(1).isUndef()) {
    assert(M0 < 4 && "Indexing into an undef vector?");
    if (M1 != (M0 + 1) % 4 || M2 != (M1 + 1) % 4 || M3 != (M2 + 1) % 4)
      return false;

    ShiftElts = IsLE ? (4 - M0) % 4 : M0;
    Swap = false;
    return true;
  }

  // Ensure each word index of the ShuffleVector Mask is consecutive.
  if (M1 != (M0 + 1) % 8 || M2 != (M1 + 1) % 8 || M3 != (M2 + 1) % 8)
    return false;

  if (IsLE) {
    if (M0 == 0 || M0 == 7 || M0 == 6 || M0 == 5) {
      // Input vectors don't need to be swapped if the leading element
      // of the result is one of the 3 left elements of the second vector
      // (or if there is no shift to be done at all).
      Swap = false;
      ShiftElts = (8 - M0) % 8;
    } else if (M0 == 4 || M0 == 3 || M0 == 2 || M0 == 1) {
      // Input vectors need to be swapped if the leading element
      // of the result is one of the 3 left elements of the first vector
      // (or if we're shifting by 4 - thereby simply swapping the vectors).
      Swap = true;
      ShiftElts = (4 - M0) % 4;
    }

    return true;
  } else {                                          // BE
    if (M0 == 0 || M0 == 1 || M0 == 2 || M0 == 3) {
      // Input vectors don't need to be swapped if the leading element
      // of the result is one of the 4 elements of the first vector.
      Swap = false;
      ShiftElts = M0;
    } else if (M0 == 4 || M0 == 5 || M0 == 6 || M0 == 7) {
      // Input vectors need to be swapped if the leading element
      // of the result is one of the 4 elements of the right vector.
      Swap = true;
      ShiftElts = M0 - 4;
    }

    return true;
  }
}

bool static isXXBRShuffleMaskHelper(ShuffleVectorSDNode *N, int Width) {
  assert(N->getValueType(0) == MVT::v16i8 && "Shuffle vector expects v16i8");

  if (!isNByteElemShuffleMask(N, Width, -1))
    return false;

  for (int i = 0; i < 16; i += Width)
    if (N->getMaskElt(i) != i + Width - 1)
      return false;

  return true;
}

bool PPC::isXXBRHShuffleMask(ShuffleVectorSDNode *N) {
  return isXXBRShuffleMaskHelper(N, 2);
}

bool PPC::isXXBRWShuffleMask(ShuffleVectorSDNode *N) {
  return isXXBRShuffleMaskHelper(N, 4);
}

bool PPC::isXXBRDShuffleMask(ShuffleVectorSDNode *N) {
  return isXXBRShuffleMaskHelper(N, 8);
}

bool PPC::isXXBRQShuffleMask(ShuffleVectorSDNode *N) {
  return isXXBRShuffleMaskHelper(N, 16);
}

/// Can node \p N be lowered to an XXPERMDI instruction? If so, set \p Swap
/// if the inputs to the instruction should be swapped and set \p DM to the
/// value for the immediate.
/// Specifically, set \p Swap to true only if \p N can be lowered to XXPERMDI
/// AND element 0 of the result comes from the first input (LE) or second input
/// (BE). Set \p DM to the calculated result (0-3) only if \p N can be lowered.
/// \return true iff the given mask of shuffle node \p N is a XXPERMDI shuffle
/// mask.
bool PPC::isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &DM,
                               bool &Swap, bool IsLE) {
  assert(N->getValueType(0) == MVT::v16i8 && "Shuffle vector expects v16i8");

  // Ensure each byte index of the double word is consecutive.
  if (!isNByteElemShuffleMask(N, 8, 1))
    return false;

  unsigned M0 = N->getMaskElt(0) / 8;
  unsigned M1 = N->getMaskElt(8) / 8;
  assert(((M0 | M1) < 4) && "A mask element out of bounds?");

  // If both vector operands for the shuffle are the same vector, the mask will
  // contain only elements from the first one and the second one will be undef.
  if (N->getOperand(1).isUndef()) {
    if ((M0 | M1) < 2) {
      DM = IsLE ? (((~M1) & 1) << 1) + ((~M0) & 1) : (M0 << 1) + (M1 & 1);
      Swap = false;
      return true;
    } else
      return false;
  }

  if (IsLE) {
    if (M0 > 1 && M1 < 2) {
      Swap = false;
    } else if (M0 < 2 && M1 > 1) {
      M0 = (M0 + 2) % 4;
      M1 = (M1 + 2) % 4;
      Swap = true;
    } else
      return false;

    // Note: if control flow comes here that means Swap is already set above
    DM = (((~M1) & 1) << 1) + ((~M0) & 1);
    return true;
  } else { // BE
    if (M0 < 2 && M1 > 1) {
      Swap = false;
    } else if (M0 > 1 && M1 < 2) {
      M0 = (M0 + 2) % 4;
      M1 = (M1 + 2) % 4;
      Swap = true;
    } else
      return false;

    // Note: if control flow comes here that means Swap is already set above
    DM = (M0 << 1) + (M1 & 1);
    return true;
  }
}


/// getSplatIdxForPPCMnemonics - Return the splat index as a value that is
/// appropriate for PPC mnemonics (which have a big endian bias - namely
/// elements are counted from the left of the vector register).
unsigned PPC::getSplatIdxForPPCMnemonics(SDNode *N, unsigned EltSize,
                                         SelectionDAG &DAG) {
  ShuffleVectorSDNode *SVOp = cast<ShuffleVectorSDNode>(N);
  assert(isSplatShuffleMask(SVOp, EltSize));
  EVT VT = SVOp->getValueType(0);

  if (VT == MVT::v2i64 || VT == MVT::v2f64)
    return DAG.getDataLayout().isLittleEndian() ? 1 - SVOp->getMaskElt(0)
                                                : SVOp->getMaskElt(0);

  if (DAG.getDataLayout().isLittleEndian())
    return (16 / EltSize) - 1 - (SVOp->getMaskElt(0) / EltSize);
  else
    return SVOp->getMaskElt(0) / EltSize;
}

/// get_VSPLTI_elt - If this is a build_vector of constants which can be formed
/// by using a vspltis[bhw] instruction of the specified element size, return
/// the constant being splatted.  The ByteSize field indicates the number of
/// bytes of each element [124] -> [bhw].
SDValue PPC::get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG) {
  SDValue OpVal;

  // If ByteSize of the splat is bigger than the element size of the
  // build_vector, then we have a case where we are checking for a splat where
  // multiple elements of the buildvector are folded together into a single
  // logical element of the splat (e.g. "vsplish 1" to splat {0,1}*8).
  unsigned EltSize = 16/N->getNumOperands();
  if (EltSize < ByteSize) {
    unsigned Multiple = ByteSize/EltSize;   // Number of BV entries per spltval.
    SDValue UniquedVals[4];
    assert(Multiple > 1 && Multiple <= 4 && "How can this happen?");

    // See if all of the elements in the buildvector agree across.
    for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
      if (N->getOperand(i).isUndef()) continue;
      // If the element isn't a constant, bail fully out.
      if (!isa<ConstantSDNode>(N->getOperand(i))) return SDValue();

      if (!UniquedVals[i&(Multiple-1)].getNode())
        UniquedVals[i&(Multiple-1)] = N->getOperand(i);
      else if (UniquedVals[i&(Multiple-1)] != N->getOperand(i))
        return SDValue();  // no match.
    }

    // Okay, if we reached this point, UniquedVals[0..Multiple-1] contains
    // either constant or undef values that are identical for each chunk.  See
    // if these chunks can form into a larger vspltis*.

    // Check to see if all of the leading entries are either 0 or -1.  If
    // neither, then this won't fit into the immediate field.
    bool LeadingZero = true;
    bool LeadingOnes = true;
    for (unsigned i = 0; i != Multiple-1; ++i) {
      if (!UniquedVals[i].getNode()) continue;  // Must have been undefs.

      LeadingZero &= isNullConstant(UniquedVals[i]);
      LeadingOnes &= isAllOnesConstant(UniquedVals[i]);
    }
    // Finally, check the least significant entry.
    if (LeadingZero) {
      if (!UniquedVals[Multiple-1].getNode())
        return DAG.getTargetConstant(0, SDLoc(N), MVT::i32);  // 0,0,0,undef
      int Val = UniquedVals[Multiple - 1]->getAsZExtVal();
      if (Val < 16)                                   // 0,0,0,4 -> vspltisw(4)
        return DAG.getTargetConstant(Val, SDLoc(N), MVT::i32);
    }
    if (LeadingOnes) {
      if (!UniquedVals[Multiple-1].getNode())
        return DAG.getTargetConstant(~0U, SDLoc(N), MVT::i32); // -1,-1,-1,undef
      int Val =cast<ConstantSDNode>(UniquedVals[Multiple-1])->getSExtValue();
      if (Val >= -16)                            // -1,-1,-1,-2 -> vspltisw(-2)
        return DAG.getTargetConstant(Val, SDLoc(N), MVT::i32);
    }

    return SDValue();
  }

  // Check to see if this buildvec has a single non-undef value in its elements.
  for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
    if (N->getOperand(i).isUndef()) continue;
    if (!OpVal.getNode())
      OpVal = N->getOperand(i);
    else if (OpVal != N->getOperand(i))
      return SDValue();
  }

  if (!OpVal.getNode()) return SDValue();  // All UNDEF: use implicit def.

  unsigned ValSizeInBytes = EltSize;
  uint64_t Value = 0;
  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
    Value = CN->getZExtValue();
  } else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
    assert(CN->getValueType(0) == MVT::f32 && "Only one legal FP vector type!");
    Value = llvm::bit_cast<uint32_t>(CN->getValueAPF().convertToFloat());
  }

  // If the splat value is larger than the element value, then we can never do
  // this splat.  The only case that we could fit the replicated bits into our
  // immediate field for would be zero, and we prefer to use vxor for it.
  if (ValSizeInBytes < ByteSize) return SDValue();

  // If the element value is larger than the splat value, check if it consists
  // of a repeated bit pattern of size ByteSize.
  if (!APInt(ValSizeInBytes * 8, Value).isSplat(ByteSize * 8))
    return SDValue();

  // Properly sign extend the value.
  int MaskVal = SignExtend32(Value, ByteSize * 8);

  // If this is zero, don't match, zero matches ISD::isBuildVectorAllZeros.
  if (MaskVal == 0) return SDValue();

  // Finally, if this value fits in a 5 bit sext field, return it
  if (SignExtend32<5>(MaskVal) == MaskVal)
    return DAG.getSignedTargetConstant(MaskVal, SDLoc(N), MVT::i32);
  return SDValue();
}

//===----------------------------------------------------------------------===//
//  Addressing Mode Selection
//===----------------------------------------------------------------------===//

/// isIntS16Immediate - This method tests to see if the node is either a 32-bit
/// or 64-bit immediate, and if the value can be accurately represented as a
/// sign extension from a 16-bit value.  If so, this returns true and the
/// immediate.
bool llvm::isIntS16Immediate(SDNode *N, int16_t &Imm) {
  if (!isa<ConstantSDNode>(N))
    return false;

  Imm = (int16_t)N->getAsZExtVal();
  if (N->getValueType(0) == MVT::i32)
    return Imm == (int32_t)N->getAsZExtVal();
  else
    return Imm == (int64_t)N->getAsZExtVal();
}
bool llvm::isIntS16Immediate(SDValue Op, int16_t &Imm) {
  return isIntS16Immediate(Op.getNode(), Imm);
}

/// Used when computing address flags for selecting loads and stores.
/// If we have an OR, check if the LHS and RHS are provably disjoint.
/// An OR of two provably disjoint values is equivalent to an ADD.
/// Most PPC load/store instructions compute the effective address as a sum,
/// so doing this conversion is useful.
static bool provablyDisjointOr(SelectionDAG &DAG, const SDValue &N) {
  if (N.getOpcode() != ISD::OR)
    return false;
  KnownBits LHSKnown = DAG.computeKnownBits(N.getOperand(0));
  if (!LHSKnown.Zero.getBoolValue())
    return false;
  KnownBits RHSKnown = DAG.computeKnownBits(N.getOperand(1));
  return (~(LHSKnown.Zero | RHSKnown.Zero) == 0);
}

/// SelectAddressEVXRegReg - Given the specified address, check to see if it can
/// be represented as an indexed [r+r] operation.
bool PPCTargetLowering::SelectAddressEVXRegReg(SDValue N, SDValue &Base,
                                               SDValue &Index,
                                               SelectionDAG &DAG) const {
  for (SDNode *U : N->users()) {
    if (MemSDNode *Memop = dyn_cast<MemSDNode>(U)) {
      if (Memop->getMemoryVT() == MVT::f64) {
          Base = N.getOperand(0);
          Index = N.getOperand(1);
          return true;
      }
    }
  }
  return false;
}

/// isIntS34Immediate - This method tests if value of node given can be
/// accurately represented as a sign extension from a 34-bit value.  If so,
/// this returns true and the immediate.
bool llvm::isIntS34Immediate(SDNode *N, int64_t &Imm) {
  if (!isa<ConstantSDNode>(N))
    return false;

  Imm = cast<ConstantSDNode>(N)->getSExtValue();
  return isInt<34>(Imm);
}
bool llvm::isIntS34Immediate(SDValue Op, int64_t &Imm) {
  return isIntS34Immediate(Op.getNode(), Imm);
}

/// SelectAddressRegReg - Given the specified addressed, check to see if it
/// can be represented as an indexed [r+r] operation.  Returns false if it
/// can be more efficiently represented as [r+imm]. If \p EncodingAlignment is
/// non-zero and N can be represented by a base register plus a signed 16-bit
/// displacement, make a more precise judgement by checking (displacement % \p
/// EncodingAlignment).
bool PPCTargetLowering::SelectAddressRegReg(
    SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG,
    MaybeAlign EncodingAlignment) const {
  // If we have a PC Relative target flag don't select as [reg+reg]. It will be
  // a [pc+imm].
  if (SelectAddressPCRel(N, Base))
    return false;

  int16_t Imm = 0;
  if (N.getOpcode() == ISD::ADD) {
    // Is there any SPE load/store (f64), which can't handle 16bit offset?
    // SPE load/store can only handle 8-bit offsets.
    if (hasSPE() && SelectAddressEVXRegReg(N, Base, Index, DAG))
        return true;
    if (isIntS16Immediate(N.getOperand(1), Imm) &&
        (!EncodingAlignment || isAligned(*EncodingAlignment, Imm)))
      return false; // r+i
    if (N.getOperand(1).getOpcode() == PPCISD::Lo)
      return false;    // r+i

    Base = N.getOperand(0);
    Index = N.getOperand(1);
    return true;
  } else if (N.getOpcode() == ISD::OR) {
    if (isIntS16Immediate(N.getOperand(1), Imm) &&
        (!EncodingAlignment || isAligned(*EncodingAlignment, Imm)))
      return false; // r+i can fold it if we can.

    // If this is an or of disjoint bitfields, we can codegen this as an add
    // (for better address arithmetic) if the LHS and RHS of the OR are provably
    // disjoint.
    KnownBits LHSKnown = DAG.computeKnownBits(N.getOperand(0));

    if (LHSKnown.Zero.getBoolValue()) {
      KnownBits RHSKnown = DAG.computeKnownBits(N.getOperand(1));
      // If all of the bits are known zero on the LHS or RHS, the add won't
      // carry.
      if (~(LHSKnown.Zero | RHSKnown.Zero) == 0) {
        Base = N.getOperand(0);
        Index = N.getOperand(1);
        return true;
      }
    }
  }

  return false;
}

// If we happen to be doing an i64 load or store into a stack slot that has
// less than a 4-byte alignment, then the frame-index elimination may need to
// use an indexed load or store instruction (because the offset may not be a
// multiple of 4). The extra register needed to hold the offset comes from the
// register scavenger, and it is possible that the scavenger will need to use
// an emergency spill slot. As a result, we need to make sure that a spill slot
// is allocated when doing an i64 load/store into a less-than-4-byte-aligned
// stack slot.
static void fixupFuncForFI(SelectionDAG &DAG, int FrameIdx, EVT VT) {
  // FIXME: This does not handle the LWA case.
  if (VT != MVT::i64)
    return;

  // NOTE: We'll exclude negative FIs here, which come from argument
  // lowering, because there are no known test cases triggering this problem
  // using packed structures (or similar). We can remove this exclusion if
  // we find such a test case. The reason why this is so test-case driven is
  // because this entire 'fixup' is only to prevent crashes (from the
  // register scavenger) on not-really-valid inputs. For example, if we have:
  //   %a = alloca i1
  //   %b = bitcast i1* %a to i64*
  //   store i64* a, i64 b
  // then the store should really be marked as 'align 1', but is not. If it
  // were marked as 'align 1' then the indexed form would have been
  // instruction-selected initially, and the problem this 'fixup' is preventing
  // won't happen regardless.
  if (FrameIdx < 0)
    return;

  MachineFunction &MF = DAG.getMachineFunction();
  MachineFrameInfo &MFI = MF.getFrameInfo();

  if (MFI.getObjectAlign(FrameIdx) >= Align(4))
    return;

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

/// Returns true if the address N can be represented by a base register plus
/// a signed 16-bit displacement [r+imm], and if it is not better
/// represented as reg+reg.  If \p EncodingAlignment is non-zero, only accept
/// displacements that are multiples of that value.
bool PPCTargetLowering::SelectAddressRegImm(
    SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG,
    MaybeAlign EncodingAlignment) const {
  // FIXME dl should come from parent load or store, not from address
  SDLoc dl(N);

  // If we have a PC Relative target flag don't select as [reg+imm]. It will be
  // a [pc+imm].
  if (SelectAddressPCRel(N, Base))
    return false;

  // If this can be more profitably realized as r+r, fail.
  if (SelectAddressRegReg(N, Disp, Base, DAG, EncodingAlignment))
    return false;

  if (N.getOpcode() == ISD::ADD) {
    int16_t imm = 0;
    if (isIntS16Immediate(N.getOperand(1), imm) &&
        (!EncodingAlignment || isAligned(*EncodingAlignment, imm))) {
      Disp = DAG.getSignedTargetConstant(imm, dl, N.getValueType());
      if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N.getOperand(0))) {
        Base = DAG.getTargetFrameIndex(FI->getIndex(), N.getValueType());
        fixupFuncForFI(DAG, FI->getIndex(), N.getValueType());
      } else {
        Base = N.getOperand(0);
      }
      return true; // [r+i]
    } else if (N.getOperand(1).getOpcode() == PPCISD::Lo) {
      // Match LOAD (ADD (X, Lo(G))).
      assert(!N.getOperand(1).getConstantOperandVal(1) &&
             "Cannot handle constant offsets yet!");
      Disp = N.getOperand(1).getOperand(0);  // The global address.
      assert(Disp.getOpcode() == ISD::TargetGlobalAddress ||
             Disp.getOpcode() == ISD::TargetGlobalTLSAddress ||
             Disp.getOpcode() == ISD::TargetConstantPool ||
             Disp.getOpcode() == ISD::TargetJumpTable);
      Base = N.getOperand(0);
      return true;  // [&g+r]
    }
  } else if (N.getOpcode() == ISD::OR) {
    int16_t imm = 0;
    if (isIntS16Immediate(N.getOperand(1), imm) &&
        (!EncodingAlignment || isAligned(*EncodingAlignment, imm))) {
      // If this is an or of disjoint bitfields, we can codegen this as an add
      // (for better address arithmetic) if the LHS and RHS of the OR are
      // provably disjoint.
      KnownBits LHSKnown = DAG.computeKnownBits(N.getOperand(0));

      if ((LHSKnown.Zero.getZExtValue()|~(uint64_t)imm) == ~0ULL) {
        // If all of the bits are known zero on the LHS or RHS, the add won't
        // carry.
        if (FrameIndexSDNode *FI =
              dyn_cast<FrameIndexSDNode>(N.getOperand(0))) {
          Base = DAG.getTargetFrameIndex(FI->getIndex(), N.getValueType());
          fixupFuncForFI(DAG, FI->getIndex(), N.getValueType());
        } else {
          Base = N.getOperand(0);
        }
        Disp = DAG.getTargetConstant(imm, dl, N.getValueType());
        return true;
      }
    }
  } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N)) {
    // Loading from a constant address.

    // If this address fits entirely in a 16-bit sext immediate field, codegen
    // this as "d, 0"
    int16_t Imm;
    if (isIntS16Immediate(CN, Imm) &&
        (!EncodingAlignment || isAligned(*EncodingAlignment, Imm))) {
      Disp = DAG.getTargetConstant(Imm, dl, CN->getValueType(0));
      Base = DAG.getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
                             CN->getValueType(0));
      return true;
    }

    // Handle 32-bit sext immediates with LIS + addr mode.
    if ((CN->getValueType(0) == MVT::i32 ||
         (int64_t)CN->getZExtValue() == (int)CN->getZExtValue()) &&
        (!EncodingAlignment ||
         isAligned(*EncodingAlignment, CN->getZExtValue()))) {
      int Addr = (int)CN->getZExtValue();

      // Otherwise, break this down into an LIS + disp.
      Disp = DAG.getTargetConstant((short)Addr, dl, MVT::i32);

      Base = DAG.getTargetConstant((Addr - (signed short)Addr) >> 16, dl,
                                   MVT::i32);
      unsigned Opc = CN->getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
      Base = SDValue(DAG.getMachineNode(Opc, dl, CN->getValueType(0), Base), 0);
      return true;
    }
  }

  Disp = DAG.getTargetConstant(0, dl, getPointerTy(DAG.getDataLayout()));
  if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N)) {
    Base = DAG.getTargetFrameIndex(FI->getIndex(), N.getValueType());
    fixupFuncForFI(DAG, FI->getIndex(), N.getValueType());
  } else
    Base = N;
  return true;      // [r+0]
}

/// Similar to the 16-bit case but for instructions that take a 34-bit
/// displacement field (prefixed loads/stores).
bool PPCTargetLowering::SelectAddressRegImm34(SDValue N, SDValue &Disp,
                                              SDValue &Base,
                                              SelectionDAG &DAG) const {
  // Only on 64-bit targets.
  if (N.getValueType() != MVT::i64)
    return false;

  SDLoc dl(N);
  int64_t Imm = 0;

  if (N.getOpcode() == ISD::ADD) {
    if (!isIntS34Immediate(N.getOperand(1), Imm))
      return false;
    Disp = DAG.getSignedTargetConstant(Imm, dl, N.getValueType());
    if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N.getOperand(0)))
      Base = DAG.getTargetFrameIndex(FI->getIndex(), N.getValueType());
    else
      Base = N.getOperand(0);
    return true;
  }

  if (N.getOpcode() == ISD::OR) {
    if (!isIntS34Immediate(N.getOperand(1), Imm))
      return false;
    // If this is an or of disjoint bitfields, we can codegen this as an add
    // (for better address arithmetic) if the LHS and RHS of the OR are
    // provably disjoint.
    KnownBits LHSKnown = DAG.computeKnownBits(N.getOperand(0));
    if ((LHSKnown.Zero.getZExtValue() | ~(uint64_t)Imm) != ~0ULL)
      return false;
    if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N.getOperand(0)))
      Base = DAG.getTargetFrameIndex(FI->getIndex(), N.getValueType());
    else
      Base = N.getOperand(0);
    Disp = DAG.getSignedTargetConstant(Imm, dl, N.getValueType());
    return true;
  }

  if (isIntS34Immediate(N, Imm)) { // If the address is a 34-bit const.
    Disp = DAG.getSignedTargetConstant(Imm, dl, N.getValueType());
    Base = DAG.getRegister(PPC::ZERO8, N.getValueType());
    return true;
  }

  return false;
}

/// SelectAddressRegRegOnly - Given the specified addressed, force it to be
/// represented as an indexed [r+r] operation.
bool PPCTargetLowering::SelectAddressRegRegOnly(SDValue N, SDValue &Base,
                                                SDValue &Index,
                                                SelectionDAG &DAG) const {
  // Check to see if we can easily represent this as an [r+r] address.  This
  // will fail if it thinks that the address is more profitably represented as
  // reg+imm, e.g. where imm = 0.
  if (SelectAddressRegReg(N, Base, Index, DAG))
    return true;

  // If the address is the result of an add, we will utilize the fact that the
  // address calculation includes an implicit add.  However, we can reduce
  // register pressure if we do not materialize a constant just for use as the
  // index register.  We only get rid of the add if it is not an add of a
  // value and a 16-bit signed constant and both have a single use.
  int16_t imm = 0;
  if (N.getOpcode() == ISD::ADD &&
      (!isIntS16Immediate(N.getOperand(1), imm) ||
       !N.getOperand(1).hasOneUse() || !N.getOperand(0).hasOneUse())) {
    Base = N.getOperand(0);
    Index = N.getOperand(1);
    return true;
  }

  // Otherwise, do it the hard way, using R0 as the base register.
  Base = DAG.getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
                         N.getValueType());
  Index = N;
  return true;
}

template <typename Ty> static bool isValidPCRelNode(SDValue N) {
  Ty *PCRelCand = dyn_cast<Ty>(N);
  return PCRelCand && (PPCInstrInfo::hasPCRelFlag(PCRelCand->getTargetFlags()));
}

/// Returns true if this address is a PC Relative address.
/// PC Relative addresses are marked with the flag PPCII::MO_PCREL_FLAG
/// or if the node opcode is PPCISD::MAT_PCREL_ADDR.
bool PPCTargetLowering::SelectAddressPCRel(SDValue N, SDValue &Base) const {
  // This is a materialize PC Relative node. Always select this as PC Relative.
  Base = N;
  if (N.getOpcode() == PPCISD::MAT_PCREL_ADDR)
    return true;
  if (isValidPCRelNode<ConstantPoolSDNode>(N) ||
      isValidPCRelNode<GlobalAddressSDNode>(N) ||
      isValidPCRelNode<JumpTableSDNode>(N) ||
      isValidPCRelNode<BlockAddressSDNode>(N))
    return true;
  return false;
}

/// Returns true if we should use a direct load into vector instruction
/// (such as lxsd or lfd), instead of a load into gpr + direct move sequence.
static bool usePartialVectorLoads(SDNode *N, const PPCSubtarget& ST) {

  // If there are any other uses other than scalar to vector, then we should
  // keep it as a scalar load -> direct move pattern to prevent multiple
  // loads.
  LoadSDNode *LD = dyn_cast<LoadSDNode>(N);
  if (!LD)
    return false;

  EVT MemVT = LD->getMemoryVT();
  if (!MemVT.isSimple())
    return false;
  switch(MemVT.getSimpleVT().SimpleTy) {
  case MVT::i64:
    break;
  case MVT::i32:
    if (!ST.hasP8Vector())
      return false;
    break;
  case MVT::i16:
  case MVT::i8:
    if (!ST.hasP9Vector())
      return false;
    break;
  default:
    return false;
  }

  SDValue LoadedVal(N, 0);
  if (!LoadedVal.hasOneUse())
    return false;

  for (SDUse &Use : LD->uses())
    if (Use.getResNo() == 0 &&
        Use.getUser()->getOpcode() != ISD::SCALAR_TO_VECTOR &&
        Use.getUser()->getOpcode() != PPCISD::SCALAR_TO_VECTOR_PERMUTED)
      return false;

  return true;
}

/// getPreIndexedAddressParts - returns true by value, base pointer and
/// offset pointer and addressing mode by reference if the node's address
/// can be legally represented as pre-indexed load / store address.
bool PPCTargetLowering::getPreIndexedAddressParts(SDNode *N, SDValue &Base,
                                                  SDValue &Offset,
                                                  ISD::MemIndexedMode &AM,
                                                  SelectionDAG &DAG) const {
  if (DisablePPCPreinc) return false;

  bool isLoad = true;
  SDValue Ptr;
  EVT VT;
  Align Alignment;
  if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
    Ptr = LD->getBasePtr();
    VT = LD->getMemoryVT();
    Alignment = LD->getAlign();
  } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
    Ptr = ST->getBasePtr();
    VT  = ST->getMemoryVT();
    Alignment = ST->getAlign();
    isLoad = false;
  } else
    return false;

  // Do not generate pre-inc forms for specific loads that feed scalar_to_vector
  // instructions because we can fold these into a more efficient instruction
  // instead, (such as LXSD).
  if (isLoad && usePartialVectorLoads(N, Subtarget)) {
    return false;
  }

  // PowerPC doesn't have preinc load/store instructions for vectors
  if (VT.isVector())
    return false;

  if (SelectAddressRegReg(Ptr, Base, Offset, DAG)) {
    // Common code will reject creating a pre-inc form if the base pointer
    // is a frame index, or if N is a store and the base pointer is either
    // the same as or a predecessor of the value being stored.  Check for
    // those situations here, and try with swapped Base/Offset instead.
    bool Swap = false;

    if (isa<FrameIndexSDNode>(Base) || isa<RegisterSDNode>(Base))
      Swap = true;
    else if (!isLoad) {
      SDValue Val = cast<StoreSDNode>(N)->getValue();
      if (Val == Base || Base.getNode()->isPredecessorOf(Val.getNode()))
        Swap = true;
    }

    if (Swap)
      std::swap(Base, Offset);

    AM = ISD::PRE_INC;
    return true;
  }

  // LDU/STU can only handle immediates that are a multiple of 4.
  if (VT != MVT::i64) {
    if (!SelectAddressRegImm(Ptr, Offset, Base, DAG, std::nullopt))
      return false;
  } else {
    // LDU/STU need an address with at least 4-byte alignment.
    if (Alignment < Align(4))
      return false;

    if (!SelectAddressRegImm(Ptr, Offset, Base, DAG, Align(4)))
      return false;
  }

  if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
    // PPC64 doesn't have lwau, but it does have lwaux.  Reject preinc load of
    // sext i32 to i64 when addr mode is r+i.
    if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
        LD->getExtensionType() == ISD::SEXTLOAD &&
        isa<ConstantSDNode>(Offset))
      return false;
  }

  AM = ISD::PRE_INC;
  return true;
}

//===----------------------------------------------------------------------===//
//  LowerOperation implementation
//===----------------------------------------------------------------------===//

/// Return true if we should reference labels using a PICBase, set the HiOpFlags
/// and LoOpFlags to the target MO flags.
static void getLabelAccessInfo(bool IsPIC, const PPCSubtarget &Subtarget,
                               unsigned &HiOpFlags, unsigned &LoOpFlags,
                               const GlobalValue *GV = nullptr) {
  HiOpFlags = PPCII::MO_HA;
  LoOpFlags = PPCII::MO_LO;

  // Don't use the pic base if not in PIC relocation model.
  if (IsPIC) {
    HiOpFlags = PPCII::MO_PIC_HA_FLAG;
    LoOpFlags = PPCII::MO_PIC_LO_FLAG;
  }
}

static SDValue LowerLabelRef(SDValue HiPart, SDValue LoPart, bool isPIC,
                             SelectionDAG &DAG) {
  SDLoc DL(HiPart);
  EVT PtrVT = HiPart.getValueType();
  SDValue Zero = DAG.getConstant(0, DL, PtrVT);

  SDValue Hi = DAG.getNode(PPCISD::Hi, DL, PtrVT, HiPart, Zero);
  SDValue Lo = DAG.getNode(PPCISD::Lo, DL, PtrVT, LoPart, Zero);

  // With PIC, the first instruction is actually "GR+hi(&G)".
  if (isPIC)
    Hi = DAG.getNode(ISD::ADD, DL, PtrVT,
                     DAG.getNode(PPCISD::GlobalBaseReg, DL, PtrVT), Hi);

  // Generate non-pic code that has direct accesses to the constant pool.
  // The address of the global is just (hi(&g)+lo(&g)).
  return DAG.getNode(ISD::ADD, DL, PtrVT, Hi, Lo);
}

static void setUsesTOCBasePtr(MachineFunction &MF) {
  PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
  FuncInfo->setUsesTOCBasePtr();
}

static void setUsesTOCBasePtr(SelectionDAG &DAG) {
  setUsesTOCBasePtr(DAG.getMachineFunction());
}

SDValue PPCTargetLowering::getTOCEntry(SelectionDAG &DAG, const SDLoc &dl,
                                       SDValue GA) const {
  EVT VT = Subtarget.getScalarIntVT();
  SDValue Reg = Subtarget.isPPC64() ? DAG.getRegister(PPC::X2, VT)
                : Subtarget.isAIXABI()
                    ? DAG.getRegister(PPC::R2, VT)
                    : DAG.getNode(PPCISD::GlobalBaseReg, dl, VT);
  SDValue Ops[] = { GA, Reg };
  return DAG.getMemIntrinsicNode(
      PPCISD::TOC_ENTRY, dl, DAG.getVTList(VT, MVT::Other), Ops, VT,
      MachinePointerInfo::getGOT(DAG.getMachineFunction()), std::nullopt,
      MachineMemOperand::MOLoad);
}

SDValue PPCTargetLowering::LowerConstantPool(SDValue Op,
                                             SelectionDAG &DAG) const {
  EVT PtrVT = Op.getValueType();
  ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
  const Constant *C = CP->getConstVal();

  // 64-bit SVR4 ABI and AIX ABI code are always position-independent.
  // The actual address of the GlobalValue is stored in the TOC.
  if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
    if (Subtarget.isUsingPCRelativeCalls()) {
      SDLoc DL(CP);
      EVT Ty = getPointerTy(DAG.getDataLayout());
      SDValue ConstPool = DAG.getTargetConstantPool(
          C, Ty, CP->getAlign(), CP->getOffset(), PPCII::MO_PCREL_FLAG);
      return DAG.getNode(PPCISD::MAT_PCREL_ADDR, DL, Ty, ConstPool);
    }
    setUsesTOCBasePtr(DAG);
    SDValue GA = DAG.getTargetConstantPool(C, PtrVT, CP->getAlign(), 0);
    return getTOCEntry(DAG, SDLoc(CP), GA);
  }

  unsigned MOHiFlag, MOLoFlag;
  bool IsPIC = isPositionIndependent();
  getLabelAccessInfo(IsPIC, Subtarget, MOHiFlag, MOLoFlag);

  if (IsPIC && Subtarget.isSVR4ABI()) {
    SDValue GA =
        DAG.getTargetConstantPool(C, PtrVT, CP->getAlign(), PPCII::MO_PIC_FLAG);
    return getTOCEntry(DAG, SDLoc(CP), GA);
  }

  SDValue CPIHi =
      DAG.getTargetConstantPool(C, PtrVT, CP->getAlign(), 0, MOHiFlag);
  SDValue CPILo =
      DAG.getTargetConstantPool(C, PtrVT, CP->getAlign(), 0, MOLoFlag);
  return LowerLabelRef(CPIHi, CPILo, IsPIC, DAG);
}

// For 64-bit PowerPC, prefer the more compact relative encodings.
// This trades 32 bits per jump table entry for one or two instructions
// on the jump site.
unsigned PPCTargetLowering::getJumpTableEncoding() const {
  if (isJumpTableRelative())
    return MachineJumpTableInfo::EK_LabelDifference32;

  return TargetLowering::getJumpTableEncoding();
}

bool PPCTargetLowering::isJumpTableRelative() const {
  if (UseAbsoluteJumpTables)
    return false;
  if (Subtarget.isPPC64() || Subtarget.isAIXABI())
    return true;
  return TargetLowering::isJumpTableRelative();
}

SDValue PPCTargetLowering::getPICJumpTableRelocBase(SDValue Table,
                                                    SelectionDAG &DAG) const {
  if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
    return TargetLowering::getPICJumpTableRelocBase(Table, DAG);

  switch (getTargetMachine().getCodeModel()) {
  case CodeModel::Small:
  case CodeModel::Medium:
    return TargetLowering::getPICJumpTableRelocBase(Table, DAG);
  default:
    return DAG.getNode(PPCISD::GlobalBaseReg, SDLoc(),
                       getPointerTy(DAG.getDataLayout()));
  }
}

const MCExpr *
PPCTargetLowering::getPICJumpTableRelocBaseExpr(const MachineFunction *MF,
                                                unsigned JTI,
                                                MCContext &Ctx) const {
  if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
    return TargetLowering::getPICJumpTableRelocBaseExpr(MF, JTI, Ctx);

  switch (getTargetMachine().getCodeModel()) {
  case CodeModel::Small:
  case CodeModel::Medium:
    return TargetLowering::getPICJumpTableRelocBaseExpr(MF, JTI, Ctx);
  default:
    return MCSymbolRefExpr::create(MF->getPICBaseSymbol(), Ctx);
  }
}

SDValue PPCTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) const {
  EVT PtrVT = Op.getValueType();
  JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);

  // isUsingPCRelativeCalls() returns true when PCRelative is enabled
  if (Subtarget.isUsingPCRelativeCalls()) {
    SDLoc DL(JT);
    EVT Ty = getPointerTy(DAG.getDataLayout());
    SDValue GA =
        DAG.getTargetJumpTable(JT->getIndex(), Ty, PPCII::MO_PCREL_FLAG);
    SDValue MatAddr = DAG.getNode(PPCISD::MAT_PCREL_ADDR, DL, Ty, GA);
    return MatAddr;
  }

  // 64-bit SVR4 ABI and AIX ABI code are always position-independent.
  // The actual address of the GlobalValue is stored in the TOC.
  if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
    setUsesTOCBasePtr(DAG);
    SDValue GA = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
    return getTOCEntry(DAG, SDLoc(JT), GA);
  }

  unsigned MOHiFlag, MOLoFlag;
  bool IsPIC = isPositionIndependent();
  getLabelAccessInfo(IsPIC, Subtarget, MOHiFlag, MOLoFlag);

  if (IsPIC && Subtarget.isSVR4ABI()) {
    SDValue GA = DAG.getTargetJumpTable(JT->getIndex(), PtrVT,
                                        PPCII::MO_PIC_FLAG);
    return getTOCEntry(DAG, SDLoc(GA), GA);
  }

  SDValue JTIHi = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, MOHiFlag);
  SDValue JTILo = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, MOLoFlag);
  return LowerLabelRef(JTIHi, JTILo, IsPIC, DAG);
}

SDValue PPCTargetLowering::LowerBlockAddress(SDValue Op,
                                             SelectionDAG &DAG) const {
  EVT PtrVT = Op.getValueType();
  BlockAddressSDNode *BASDN = cast<BlockAddressSDNode>(Op);
  const BlockAddress *BA = BASDN->getBlockAddress();

  // isUsingPCRelativeCalls() returns true when PCRelative is enabled
  if (Subtarget.isUsingPCRelativeCalls()) {
    SDLoc DL(BASDN);
    EVT Ty = getPointerTy(DAG.getDataLayout());
    SDValue GA = DAG.getTargetBlockAddress(BA, Ty, BASDN->getOffset(),
                                           PPCII::MO_PCREL_FLAG);
    SDValue MatAddr = DAG.getNode(PPCISD::MAT_PCREL_ADDR, DL, Ty, GA);
    return MatAddr;
  }

  // 64-bit SVR4 ABI and AIX ABI code are always position-independent.
  // The actual BlockAddress is stored in the TOC.
  if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
    setUsesTOCBasePtr(DAG);
    SDValue GA = DAG.getTargetBlockAddress(BA, PtrVT, BASDN->getOffset());
    return getTOCEntry(DAG, SDLoc(BASDN), GA);
  }

  // 32-bit position-independent ELF stores the BlockAddress in the .got.
  if (Subtarget.is32BitELFABI() && isPositionIndependent())
    return getTOCEntry(
        DAG, SDLoc(BASDN),
        DAG.getTargetBlockAddress(BA, PtrVT, BASDN->getOffset()));

  unsigned MOHiFlag, MOLoFlag;
  bool IsPIC = isPositionIndependent();
  getLabelAccessInfo(IsPIC, Subtarget, MOHiFlag, MOLoFlag);
  SDValue TgtBAHi = DAG.getTargetBlockAddress(BA, PtrVT, 0, MOHiFlag);
  SDValue TgtBALo = DAG.getTargetBlockAddress(BA, PtrVT, 0, MOLoFlag);
  return LowerLabelRef(TgtBAHi, TgtBALo, IsPIC, DAG);
}

SDValue PPCTargetLowering::LowerGlobalTLSAddress(SDValue Op,
                                              SelectionDAG &DAG) const {
  if (Subtarget.isAIXABI())
    return LowerGlobalTLSAddressAIX(Op, DAG);

  return LowerGlobalTLSAddressLinux(Op, DAG);
}

/// updateForAIXShLibTLSModelOpt - Helper to initialize TLS model opt settings,
/// and then apply the update.
static void updateForAIXShLibTLSModelOpt(TLSModel::Model &Model,
                                         SelectionDAG &DAG,
                                         const TargetMachine &TM) {
  // Initialize TLS model opt setting lazily:
  // (1) Use initial-exec for single TLS var references within current function.
  // (2) Use local-dynamic for multiple TLS var references within current
  // function.
  PPCFunctionInfo *FuncInfo =
      DAG.getMachineFunction().getInfo<PPCFunctionInfo>();
  if (!FuncInfo->isAIXFuncTLSModelOptInitDone()) {
    SmallPtrSet<const GlobalValue *, 8> TLSGV;
    // Iterate over all instructions within current function, collect all TLS
    // global variables (global variables taken as the first parameter to
    // Intrinsic::threadlocal_address).
    const Function &Func = DAG.getMachineFunction().getFunction();
    for (const BasicBlock &BB : Func)
      for (const Instruction &I : BB)
        if (I.getOpcode() == Instruction::Call)
          if (const CallInst *CI = dyn_cast<const CallInst>(&I))
            if (Function *CF = CI->getCalledFunction())
              if (CF->isDeclaration() &&
                  CF->getIntrinsicID() == Intrinsic::threadlocal_address)
                if (const GlobalValue *GV =
                        dyn_cast<GlobalValue>(I.getOperand(0))) {
                  TLSModel::Model GVModel = TM.getTLSModel(GV);
                  if (GVModel == TLSModel::LocalDynamic)
                    TLSGV.insert(GV);
                }

    unsigned TLSGVCnt = TLSGV.size();
    LLVM_DEBUG(dbgs() << format("LocalDynamic TLSGV count:%d\n", TLSGVCnt));
    if (TLSGVCnt <= PPCAIXTLSModelOptUseIEForLDLimit)
      FuncInfo->setAIXFuncUseTLSIEForLD();
    FuncInfo->setAIXFuncTLSModelOptInitDone();
  }

  if (FuncInfo->isAIXFuncUseTLSIEForLD()) {
    LLVM_DEBUG(
        dbgs() << DAG.getMachineFunction().getName()
               << " function is using the TLS-IE model for TLS-LD access.\n");
    Model = TLSModel::InitialExec;
  }
}

SDValue PPCTargetLowering::LowerGlobalTLSAddressAIX(SDValue Op,
                                                    SelectionDAG &DAG) const {
  GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);

  if (DAG.getTarget().useEmulatedTLS())
    report_fatal_error("Emulated TLS is not yet supported on AIX");

  SDLoc dl(GA);
  const GlobalValue *GV = GA->getGlobal();
  EVT PtrVT = getPointerTy(DAG.getDataLayout());
  bool Is64Bit = Subtarget.isPPC64();
  TLSModel::Model Model = getTargetMachine().getTLSModel(GV);

  // Apply update to the TLS model.
  if (Subtarget.hasAIXShLibTLSModelOpt())
    updateForAIXShLibTLSModelOpt(Model, DAG, getTargetMachine());

  // TLS variables are accessed through TOC entries.
  // To support this, set the DAG to use the TOC base pointer.
  setUsesTOCBasePtr(DAG);

  bool IsTLSLocalExecModel = Model == TLSModel::LocalExec;

  if (IsTLSLocalExecModel || Model == TLSModel::InitialExec) {
    bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
    bool HasAIXSmallTLSGlobalAttr = false;
    SDValue VariableOffsetTGA =
        DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, PPCII::MO_TPREL_FLAG);
    SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
    SDValue TLSReg;

    if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
      if (GVar->hasAttribute("aix-small-tls"))
        HasAIXSmallTLSGlobalAttr = true;

    if (Is64Bit) {
      // For local-exec and initial-exec on AIX (64-bit), the sequence generated
      // involves a load of the variable offset (from the TOC), followed by an
      // add of the loaded variable offset to R13 (the thread pointer).
      // This code sequence looks like:
      //    ld reg1,var[TC](2)
      //    add reg2, reg1, r13     // r13 contains the thread pointer
      TLSReg = DAG.getRegister(PPC::X13, MVT::i64);

      // With the -maix-small-local-exec-tls option, or with the "aix-small-tls"
      // global variable attribute, produce a faster access sequence for
      // local-exec TLS variables where the offset from the TLS base is encoded
      // as an immediate operand.
      //
      // We only utilize the faster local-exec access sequence when the TLS
      // variable has a size within the policy limit. We treat types that are
      // not sized or are empty as being over the policy size limit.
      if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
          IsTLSLocalExecModel) {
        Type *GVType = GV->getValueType();
        if (GVType->isSized() && !GVType->isEmptyTy() &&
            GV->getDataLayout().getTypeAllocSize(GVType) <=
                AIXSmallTlsPolicySizeLimit)
          return DAG.getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA, TLSReg);
      }
    } else {
      // For local-exec and initial-exec on AIX (32-bit), the sequence generated
      // involves loading the variable offset from the TOC, generating a call to
      // .__get_tpointer to get the thread pointer (which will be in R3), and
      // adding the two together:
      //    lwz reg1,var[TC](2)
      //    bla .__get_tpointer
      //    add reg2, reg1, r3
      TLSReg = DAG.getNode(PPCISD::GET_TPOINTER, dl, PtrVT);

      // We do not implement the 32-bit version of the faster access sequence
      // for local-exec that is controlled by the -maix-small-local-exec-tls
      // option, or the "aix-small-tls" global variable attribute.
      if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
        report_fatal_error("The small-local-exec TLS access sequence is "
                           "currently only supported on AIX (64-bit mode).");
    }
    return DAG.getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, VariableOffset);
  }

  if (Model == TLSModel::LocalDynamic) {
    bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();

    // We do not implement the 32-bit version of the faster access sequence
    // for local-dynamic that is controlled by -maix-small-local-dynamic-tls.
    if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
      report_fatal_error("The small-local-dynamic TLS access sequence is "
                         "currently only supported on AIX (64-bit mode).");

    // For local-dynamic on AIX, we need to generate one TOC entry for each
    // variable offset, and a single module-handle TOC entry for the entire
    // file.

    SDValue VariableOffsetTGA =
        DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, PPCII::MO_TLSLD_FLAG);
    SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);

    Module *M = DAG.getMachineFunction().getFunction().getParent();
    GlobalVariable *TLSGV =
        dyn_cast_or_null<GlobalVariable>(M->getOrInsertGlobal(
            StringRef("_$TLSML"), PointerType::getUnqual(*DAG.getContext())));
    TLSGV->setThreadLocalMode(GlobalVariable::LocalDynamicTLSModel);
    assert(TLSGV && "Not able to create GV for _$TLSML.");
    SDValue ModuleHandleTGA =
        DAG.getTargetGlobalAddress(TLSGV, dl, PtrVT, 0, PPCII::MO_TLSLDM_FLAG);
    SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
    SDValue ModuleHandle =
        DAG.getNode(PPCISD::TLSLD_AIX, dl, PtrVT, ModuleHandleTOC);

    // With the -maix-small-local-dynamic-tls option, produce a faster access
    // sequence for local-dynamic TLS variables where the offset from the
    // module-handle is encoded as an immediate operand.
    //
    // We only utilize the faster local-dynamic access sequence when the TLS
    // variable has a size within the policy limit. We treat types that are
    // not sized or are empty as being over the policy size limit.
    if (HasAIXSmallLocalDynamicTLS) {
      Type *GVType = GV->getValueType();
      if (GVType->isSized() && !GVType->isEmptyTy() &&
          GV->getDataLayout().getTypeAllocSize(GVType) <=
              AIXSmallTlsPolicySizeLimit)
        return DAG.getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA,
                           ModuleHandle);
    }

    return DAG.getNode(ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
  }

  // If Local- or Initial-exec or Local-dynamic is not possible or specified,
  // all GlobalTLSAddress nodes are lowered using the general-dynamic model. We
  // need to generate two TOC entries, one for the variable offset, one for the
  // region handle. The global address for the TOC entry of the region handle is
  // created with the MO_TLSGDM_FLAG flag and the global address for the TOC
  // entry of the variable offset is created with MO_TLSGD_FLAG.
  SDValue VariableOffsetTGA =
      DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, PPCII::MO_TLSGD_FLAG);
  SDValue RegionHandleTGA =
      DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, PPCII::MO_TLSGDM_FLAG);
  SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
  SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
  return DAG.getNode(PPCISD::TLSGD_AIX, dl, PtrVT, VariableOffset,
                     RegionHandle);
}

SDValue PPCTargetLowering::LowerGlobalTLSAddressLinux(SDValue Op,
                                                      SelectionDAG &DAG) const {
  // FIXME: TLS addresses currently use medium model code sequences,
  // which is the most useful form.  Eventually support for small and
  // large models could be added if users need it, at the cost of
  // additional complexity.
  GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);
  if (DAG.getTarget().useEmulatedTLS())
    return LowerToTLSEmulatedModel(GA, DAG);

  SDLoc dl(GA);
  const GlobalValue *GV = GA->getGlobal();
  EVT PtrVT = getPointerTy(DAG.getDataLayout());
  bool is64bit = Subtarget.isPPC64();
  const Module *M = DAG.getMachineFunction().getFunction().getParent();
  PICLevel::Level picLevel = M->getPICLevel();

  const TargetMachine &TM = getTargetMachine();
  TLSModel::Model Model = TM.getTLSModel(GV);

  if (Model == TLSModel::LocalExec) {
    if (Subtarget.isUsingPCRelativeCalls()) {
      SDValue TLSReg = DAG.getRegister(PPC::X13, MVT::i64);
      SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
                                               PPCII::MO_TPREL_PCREL_FLAG);
      SDValue MatAddr =
          DAG.getNode(PPCISD::TLS_LOCAL_EXEC_MAT_ADDR, dl, PtrVT, TGA);
      return DAG.getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, MatAddr);
    }

    SDValue TGAHi = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
                                               PPCII::MO_TPREL_HA);
    SDValue TGALo = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
                                               PPCII::MO_TPREL_LO);
    SDValue TLSReg = is64bit ? DAG.getRegister(PPC::X13, MVT::i64)
                             : DAG.getRegister(PPC::R2, MVT::i32);

    SDValue Hi = DAG.getNode(PPCISD::Hi, dl, PtrVT, TGAHi, TLSReg);
    return DAG.getNode(PPCISD::Lo, dl, PtrVT, TGALo, Hi);
  }

  if (Model == TLSModel::InitialExec) {
    bool IsPCRel = Subtarget.isUsingPCRelativeCalls();
    SDValue TGA = DAG.getTargetGlobalAddress(
        GV, dl, PtrVT, 0, IsPCRel ? PPCII::MO_GOT_TPREL_PCREL_FLAG : 0);
    SDValue TGATLS = DAG.getTargetGlobalAddress(
        GV, dl, PtrVT, 0, IsPCRel ? PPCII::MO_TLS_PCREL_FLAG : PPCII::MO_TLS);
    SDValue TPOffset;
    if (IsPCRel) {
      SDValue MatPCRel = DAG.getNode(PPCISD::MAT_PCREL_ADDR, dl, PtrVT, TGA);
      TPOffset = DAG.getLoad(MVT::i64, dl, DAG.getEntryNode(), MatPCRel,
                             MachinePointerInfo());
    } else {
      SDValue GOTPtr;
      if (is64bit) {
        setUsesTOCBasePtr(DAG);
        SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
        GOTPtr =
            DAG.getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl, PtrVT, GOTReg, TGA);
      } else {
        if (!TM.isPositionIndependent())
          GOTPtr = DAG.getNode(PPCISD::PPC32_GOT, dl, PtrVT);
        else if (picLevel == PICLevel::SmallPIC)
          GOTPtr = DAG.getNode(PPCISD::GlobalBaseReg, dl, PtrVT);
        else
          GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT);
      }
      TPOffset = DAG.getNode(PPCISD::LD_GOT_TPREL_L, dl, PtrVT, TGA, GOTPtr);
    }
    return DAG.getNode(PPCISD::ADD_TLS, dl, PtrVT, TPOffset, TGATLS);
  }

  if (Model == TLSModel::GeneralDynamic) {
    if (Subtarget.isUsingPCRelativeCalls()) {
      SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
                                               PPCII::MO_GOT_TLSGD_PCREL_FLAG);
      return DAG.getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
    }

    SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, 0);
    SDValue GOTPtr;
    if (is64bit) {
      setUsesTOCBasePtr(DAG);
      SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
      GOTPtr = DAG.getNode(PPCISD::ADDIS_TLSGD_HA, dl, PtrVT,
                                   GOTReg, TGA);
    } else {
      if (picLevel == PICLevel::SmallPIC)
        GOTPtr = DAG.getNode(PPCISD::GlobalBaseReg, dl, PtrVT);
      else
        GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT);
    }
    return DAG.getNode(PPCISD::ADDI_TLSGD_L_ADDR, dl, PtrVT,
                       GOTPtr, TGA, TGA);
  }

  if (Model == TLSModel::LocalDynamic) {
    if (Subtarget.isUsingPCRelativeCalls()) {
      SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
                                               PPCII::MO_GOT_TLSLD_PCREL_FLAG);
      SDValue MatPCRel =
          DAG.getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
      return DAG.getNode(PPCISD::PADDI_DTPREL, dl, PtrVT, MatPCRel, TGA);
    }

    SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, 0);
    SDValue GOTPtr;
    if (is64bit) {
      setUsesTOCBasePtr(DAG);
      SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
      GOTPtr = DAG.getNode(PPCISD::ADDIS_TLSLD_HA, dl, PtrVT,
                           GOTReg, TGA);
    } else {
      if (picLevel == PICLevel::SmallPIC)
        GOTPtr = DAG.getNode(PPCISD::GlobalBaseReg, dl, PtrVT);
      else
        GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT);
    }
    SDValue TLSAddr = DAG.getNode(PPCISD::ADDI_TLSLD_L_ADDR, dl,
                                  PtrVT, GOTPtr, TGA, TGA);
    SDValue DtvOffsetHi = DAG.getNode(PPCISD::ADDIS_DTPREL_HA, dl,
                                      PtrVT, TLSAddr, TGA);
    return DAG.getNode(PPCISD::ADDI_DTPREL_L, dl, PtrVT, DtvOffsetHi, TGA);
  }

  llvm_unreachable("Unknown TLS model!");
}

SDValue PPCTargetLowering::LowerGlobalAddress(SDValue Op,
                                              SelectionDAG &DAG) const {
  EVT PtrVT = Op.getValueType();
  GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
  SDLoc DL(GSDN);
  const GlobalValue *GV = GSDN->getGlobal();

  // 64-bit SVR4 ABI & AIX ABI code is always position-independent.
  // The actual address of the GlobalValue is stored in the TOC.
  if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
    if (Subtarget.isUsingPCRelativeCalls()) {
      EVT Ty = getPointerTy(DAG.getDataLayout());
      if (isAccessedAsGotIndirect(Op)) {
        SDValue GA = DAG.getTargetGlobalAddress(GV, DL, Ty, GSDN->getOffset(),
                                                PPCII::MO_GOT_PCREL_FLAG);
        SDValue MatPCRel = DAG.getNode(PPCISD::MAT_PCREL_ADDR, DL, Ty, GA);
        SDValue Load = DAG.getLoad(MVT::i64, DL, DAG.getEntryNode(), MatPCRel,
                                   MachinePointerInfo());
        return Load;
      } else {
        SDValue GA = DAG.getTargetGlobalAddress(GV, DL, Ty, GSDN->getOffset(),
                                                PPCII::MO_PCREL_FLAG);
        return DAG.getNode(PPCISD::MAT_PCREL_ADDR, DL, Ty, GA);
      }
    }
    setUsesTOCBasePtr(DAG);
    SDValue GA = DAG.getTargetGlobalAddress(GV, DL, PtrVT, GSDN->getOffset());
    return getTOCEntry(DAG, DL, GA);
  }

  unsigned MOHiFlag, MOLoFlag;
  bool IsPIC = isPositionIndependent();
  getLabelAccessInfo(IsPIC, Subtarget, MOHiFlag, MOLoFlag, GV);

  if (IsPIC && Subtarget.isSVR4ABI()) {
    SDValue GA = DAG.getTargetGlobalAddress(GV, DL, PtrVT,
                                            GSDN->getOffset(),
                                            PPCII::MO_PIC_FLAG);
    return getTOCEntry(DAG, DL, GA);
  }

  SDValue GAHi =
    DAG.getTargetGlobalAddress(GV, DL, PtrVT, GSDN->getOffset(), MOHiFlag);
  SDValue GALo =
    DAG.getTargetGlobalAddress(GV, DL, PtrVT, GSDN->getOffset(), MOLoFlag);

  return LowerLabelRef(GAHi, GALo, IsPIC, DAG);
}

SDValue PPCTargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
  bool IsStrict = Op->isStrictFPOpcode();
  ISD::CondCode CC =
      cast<CondCodeSDNode>(Op.getOperand(IsStrict ? 3 : 2))->get();
  SDValue LHS = Op.getOperand(IsStrict ? 1 : 0);
  SDValue RHS = Op.getOperand(IsStrict ? 2 : 1);
  SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
  EVT LHSVT = LHS.getValueType();
  SDLoc dl(Op);

  // Soften the setcc with libcall if it is fp128.
  if (LHSVT == MVT::f128) {
    assert(!Subtarget.hasP9Vector() &&
           "SETCC for f128 is already legal under Power9!");
    softenSetCCOperands(DAG, LHSVT, LHS, RHS, CC, dl, LHS, RHS, Chain,
                        Op->getOpcode() == ISD::STRICT_FSETCCS);
    if (RHS.getNode())
      LHS = DAG.getNode(ISD::SETCC, dl, Op.getValueType(), LHS, RHS,
                        DAG.getCondCode(CC));
    if (IsStrict)
      return DAG.getMergeValues({LHS, Chain}, dl);
    return LHS;
  }

  assert(!IsStrict && "Don't know how to handle STRICT_FSETCC!");

  if (Op.getValueType() == MVT::v2i64) {
    // When the operands themselves are v2i64 values, we need to do something
    // special because VSX has no underlying comparison operations for these.
    if (LHS.getValueType() == MVT::v2i64) {
      // Equality can be handled by casting to the legal type for Altivec
      // comparisons, everything else needs to be expanded.
      if (CC != ISD::SETEQ && CC != ISD::SETNE)
        return SDValue();
      SDValue SetCC32 = DAG.getSetCC(
          dl, MVT::v4i32, DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, LHS),
          DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, RHS), CC);
      int ShuffV[] = {1, 0, 3, 2};
      SDValue Shuff =
          DAG.getVectorShuffle(MVT::v4i32, dl, SetCC32, SetCC32, ShuffV);
      return DAG.getBitcast(MVT::v2i64,
                            DAG.getNode(CC == ISD::SETEQ ? ISD::AND : ISD::OR,
                                        dl, MVT::v4i32, Shuff, SetCC32));
    }

    // We handle most of these in the usual way.
    return Op;
  }

  // If we're comparing for equality to zero, expose the fact that this is
  // implemented as a ctlz/srl pair on ppc, so that the dag combiner can
  // fold the new nodes.
  if (SDValue V = lowerCmpEqZeroToCtlzSrl(Op, DAG))
    return V;

  if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(RHS)) {
    // Leave comparisons against 0 and -1 alone for now, since they're usually
    // optimized.  FIXME: revisit this when we can custom lower all setcc
    // optimizations.
    if (C->isAllOnes() || C->isZero())
      return SDValue();
  }

  // If we have an integer seteq/setne, turn it into a compare against zero
  // by xor'ing the rhs with the lhs, which is faster than setting a
  // condition register, reading it back out, and masking the correct bit.  The
  // normal approach here uses sub to do this instead of xor.  Using xor exposes
  // the result to other bit-twiddling opportunities.
  if (LHSVT.isInteger() && (CC == ISD::SETEQ || CC == ISD::SETNE)) {
    EVT VT = Op.getValueType();
    SDValue Sub = DAG.getNode(ISD::XOR, dl, LHSVT, LHS, RHS);
    return DAG.getSetCC(dl, VT, Sub, DAG.getConstant(0, dl, LHSVT), CC);
  }
  return SDValue();
}

SDValue PPCTargetLowering::LowerVAARG(SDValue Op, SelectionDAG &DAG) const {
  SDNode *Node = Op.getNode();
  EVT VT = Node->getValueType(0);
  EVT PtrVT = getPointerTy(DAG.getDataLayout());
  SDValue InChain = Node->getOperand(0);
  SDValue VAListPtr = Node->getOperand(1);
  const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
  SDLoc dl(Node);

  assert(!Subtarget.isPPC64() && "LowerVAARG is PPC32 only");

  // gpr_index
  SDValue GprIndex = DAG.getExtLoad(ISD::ZEXTLOAD, dl, MVT::i32, InChain,
                                    VAListPtr, MachinePointerInfo(SV), MVT::i8);
  InChain = GprIndex.getValue(1);

  if (VT == MVT::i64) {
    // Check if GprIndex is even
    SDValue GprAnd = DAG.getNode(ISD::AND, dl, MVT::i32, GprIndex,
                                 DAG.getConstant(1, dl, MVT::i32));
    SDValue CC64 = DAG.getSetCC(dl, MVT::i32, GprAnd,
                                DAG.getConstant(0, dl, MVT::i32), ISD::SETNE);
    SDValue GprIndexPlusOne = DAG.getNode(ISD::ADD, dl, MVT::i32, GprIndex,
                                          DAG.getConstant(1, dl, MVT::i32));
    // Align GprIndex to be even if it isn't
    GprIndex = DAG.getNode(ISD::SELECT, dl, MVT::i32, CC64, GprIndexPlusOne,
                           GprIndex);
  }

  // fpr index is 1 byte after gpr
  SDValue FprPtr = DAG.getNode(ISD::ADD, dl, PtrVT, VAListPtr,
                               DAG.getConstant(1, dl, MVT::i32));

  // fpr
  SDValue FprIndex = DAG.getExtLoad(ISD::ZEXTLOAD, dl, MVT::i32, InChain,
                                    FprPtr, MachinePointerInfo(SV), MVT::i8);
  InChain = FprIndex.getValue(1);

  SDValue RegSaveAreaPtr = DAG.getNode(ISD::ADD, dl, PtrVT, VAListPtr,
                                       DAG.getConstant(8, dl, MVT::i32));

  SDValue OverflowAreaPtr = DAG.getNode(ISD::ADD, dl, PtrVT, VAListPtr,
                                        DAG.getConstant(4, dl, MVT::i32));

  // areas
  SDValue OverflowArea =
      DAG.getLoad(MVT::i32, dl, InChain, OverflowAreaPtr, MachinePointerInfo());
  InChain = OverflowArea.getValue(1);

  SDValue RegSaveArea =
      DAG.getLoad(MVT::i32, dl, InChain, RegSaveAreaPtr, MachinePointerInfo());
  InChain = RegSaveArea.getValue(1);

  // select overflow_area if index > 8
  SDValue CC = DAG.getSetCC(dl, MVT::i32, VT.isInteger() ? GprIndex : FprIndex,
                            DAG.getConstant(8, dl, MVT::i32), ISD::SETLT);

  // adjustment constant gpr_index * 4/8
  SDValue RegConstant = DAG.getNode(ISD::MUL, dl, MVT::i32,
                                    VT.isInteger() ? GprIndex : FprIndex,
                                    DAG.getConstant(VT.isInteger() ? 4 : 8, dl,
                                                    MVT::i32));

  // OurReg = RegSaveArea + RegConstant
  SDValue OurReg = DAG.getNode(ISD::ADD, dl, PtrVT, RegSaveArea,
                               RegConstant);

  // Floating types are 32 bytes into RegSaveArea
  if (VT.isFloatingPoint())
    OurReg = DAG.getNode(ISD::ADD, dl, PtrVT, OurReg,
                         DAG.getConstant(32, dl, MVT::i32));

  // increase {f,g}pr_index by 1 (or 2 if VT is i64)
  SDValue IndexPlus1 = DAG.getNode(ISD::ADD, dl, MVT::i32,
                                   VT.isInteger() ? GprIndex : FprIndex,
                                   DAG.getConstant(VT == MVT::i64 ? 2 : 1, dl,
                                                   MVT::i32));

  InChain = DAG.getTruncStore(InChain, dl, IndexPlus1,
                              VT.isInteger() ? VAListPtr : FprPtr,
                              MachinePointerInfo(SV), MVT::i8);

  // determine if we should load from reg_save_area or overflow_area
  SDValue Result = DAG.getNode(ISD::SELECT, dl, PtrVT, CC, OurReg, OverflowArea);

  // increase overflow_area by 4/8 if gpr/fpr > 8
  SDValue OverflowAreaPlusN = DAG.getNode(ISD::ADD, dl, PtrVT, OverflowArea,
                                          DAG.getConstant(VT.isInteger() ? 4 : 8,
                                          dl, MVT::i32));

  OverflowArea = DAG.getNode(ISD::SELECT, dl, MVT::i32, CC, OverflowArea,
                             OverflowAreaPlusN);

  InChain = DAG.getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
                              MachinePointerInfo(), MVT::i32);

  return DAG.getLoad(VT, dl, InChain, Result, MachinePointerInfo());
}

SDValue PPCTargetLowering::LowerVACOPY(SDValue Op, SelectionDAG &DAG) const {
  assert(!Subtarget.isPPC64() && "LowerVACOPY is PPC32 only");

  // We have to copy the entire va_list struct:
  // 2*sizeof(char) + 2 Byte alignment + 2*sizeof(char*) = 12 Byte
  return DAG.getMemcpy(Op.getOperand(0), Op, Op.getOperand(1), Op.getOperand(2),
                       DAG.getConstant(12, SDLoc(Op), MVT::i32), Align(8),
                       false, true, /*CI=*/nullptr, std::nullopt,
                       MachinePointerInfo(), MachinePointerInfo());
}

SDValue PPCTargetLowering::LowerADJUST_TRAMPOLINE(SDValue Op,
                                                  SelectionDAG &DAG) const {
  return Op.getOperand(0);
}

SDValue PPCTargetLowering::LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const {
  MachineFunction &MF = DAG.getMachineFunction();
  PPCFunctionInfo &MFI = *MF.getInfo<PPCFunctionInfo>();

  assert((Op.getOpcode() == ISD::INLINEASM ||
          Op.getOpcode() == ISD::INLINEASM_BR) &&
         "Expecting Inline ASM node.");

  // If an LR store is already known to be required then there is not point in
  // checking this ASM as well.
  if (MFI.isLRStoreRequired())
    return Op;

  // Inline ASM nodes have an optional last operand that is an incoming Flag of
  // type MVT::Glue. We want to ignore this last operand if that is the case.
  unsigned NumOps = Op.getNumOperands();
  if (Op.getOperand(NumOps - 1).getValueType() == MVT::Glue)
    --NumOps;

  // Check all operands that may contain the LR.
  for (unsigned i = InlineAsm::Op_FirstOperand; i != NumOps;) {
    const InlineAsm::Flag Flags(Op.getConstantOperandVal(i));
    unsigned NumVals = Flags.getNumOperandRegisters();
    ++i; // Skip the ID value.

    switch (Flags.getKind()) {
    default:
      llvm_unreachable("Bad flags!");
    case InlineAsm::Kind::RegUse:
    case InlineAsm::Kind::Imm:
    case InlineAsm::Kind::Mem:
      i += NumVals;
      break;
    case InlineAsm::Kind::Clobber:
    case InlineAsm::Kind::RegDef:
    case InlineAsm::Kind::RegDefEarlyClobber: {
      for (; NumVals; --NumVals, ++i) {
        Register Reg = cast<RegisterSDNode>(Op.getOperand(i))->getReg();
        if (Reg != PPC::LR && Reg != PPC::LR8)
          continue;
        MFI.setLRStoreRequired();
        return Op;
      }
      break;
    }
    }
  }

  return Op;
}

SDValue PPCTargetLowering::LowerINIT_TRAMPOLINE(SDValue Op,
                                                SelectionDAG &DAG) const {
  SDValue Chain = Op.getOperand(0);
  SDValue Trmp = Op.getOperand(1); // trampoline
  SDValue FPtr = Op.getOperand(2); // nested function
  SDValue Nest = Op.getOperand(3); // 'nest' parameter value
  SDLoc dl(Op);

  EVT PtrVT = getPointerTy(DAG.getDataLayout());

  if (Subtarget.isAIXABI()) {
    // On AIX we create a trampoline descriptor by combining the
    // entry point and TOC from the global descriptor (FPtr) with the
    // nest argument as the environment pointer.
    uint64_t PointerSize = Subtarget.isPPC64() ? 8 : 4;
    MaybeAlign PointerAlign(PointerSize);
    auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
                        ? (MachineMemOperand::MODereferenceable |
                           MachineMemOperand::MOInvariant)
                        : MachineMemOperand::MONone;

    uint64_t TOCPointerOffset = 1 * PointerSize;
    uint64_t EnvPointerOffset = 2 * PointerSize;
    SDValue SDTOCPtrOffset = DAG.getConstant(TOCPointerOffset, dl, PtrVT);
    SDValue SDEnvPtrOffset = DAG.getConstant(EnvPointerOffset, dl, PtrVT);

    const Value *TrampolineAddr =
        cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
    const Function *Func =
        cast<Function>(cast<SrcValueSDNode>(Op.getOperand(5))->getValue());

    SDValue OutChains[3];

    // Copy the entry point address from the global descriptor to the
    // trampoline buffer.
    SDValue LoadEntryPoint =
        DAG.getLoad(PtrVT, dl, Chain, FPtr, MachinePointerInfo(Func, 0),
                    PointerAlign, MMOFlags);
    SDValue EPLoadChain = LoadEntryPoint.getValue(1);
    OutChains[0] = DAG.getStore(EPLoadChain, dl, LoadEntryPoint, Trmp,
                                MachinePointerInfo(TrampolineAddr, 0));

    // Copy the TOC pointer from the global descriptor to the trampoline
    // buffer.
    SDValue TOCFromDescriptorPtr =
        DAG.getNode(ISD::ADD, dl, PtrVT, FPtr, SDTOCPtrOffset);
    SDValue TOCReg = DAG.getLoad(PtrVT, dl, Chain, TOCFromDescriptorPtr,
                                 MachinePointerInfo(Func, TOCPointerOffset),
                                 PointerAlign, MMOFlags);
    SDValue TrampolineTOCPointer =
        DAG.getNode(ISD::ADD, dl, PtrVT, Trmp, SDTOCPtrOffset);
    SDValue TOCLoadChain = TOCReg.getValue(1);
    OutChains[1] =
        DAG.getStore(TOCLoadChain, dl, TOCReg, TrampolineTOCPointer,
                     MachinePointerInfo(TrampolineAddr, TOCPointerOffset));

    // Store the nest argument into the environment pointer in the trampoline
    // buffer.
    SDValue EnvPointer = DAG.getNode(ISD::ADD, dl, PtrVT, Trmp, SDEnvPtrOffset);
    OutChains[2] =
        DAG.getStore(Chain, dl, Nest, EnvPointer,
                     MachinePointerInfo(TrampolineAddr, EnvPointerOffset));

    SDValue TokenFactor =
        DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
    return TokenFactor;
  }

  bool isPPC64 = (PtrVT == MVT::i64);
  Type *IntPtrTy = DAG.getDataLayout().getIntPtrType(*DAG.getContext());

  TargetLowering::ArgListTy Args;
  Args.emplace_back(Trmp, IntPtrTy);
  // TrampSize == (isPPC64 ? 48 : 40);
  Args.emplace_back(
      DAG.getConstant(isPPC64 ? 48 : 40, dl, Subtarget.getScalarIntVT()),
      IntPtrTy);
  Args.emplace_back(FPtr, IntPtrTy);
  Args.emplace_back(Nest, IntPtrTy);

  // Lower to a call to __trampoline_setup(Trmp, TrampSize, FPtr, ctx_reg)
  TargetLowering::CallLoweringInfo CLI(DAG);
  CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
      CallingConv::C, Type::getVoidTy(*DAG.getContext()),
      DAG.getExternalSymbol("__trampoline_setup", PtrVT), std::move(Args));

  std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);
  return CallResult.second;
}

SDValue PPCTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const {
  MachineFunction &MF = DAG.getMachineFunction();
  PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
  EVT PtrVT = getPointerTy(MF.getDataLayout());

  SDLoc dl(Op);

  if (Subtarget.isPPC64() || Subtarget.isAIXABI()) {
    // vastart just stores the address of the VarArgsFrameIndex slot into the
    // memory location argument.
    SDValue FR = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);
    const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
    return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1),
                        MachinePointerInfo(SV));
  }

  // For the 32-bit SVR4 ABI we follow the layout of the va_list struct.
  // We suppose the given va_list is already allocated.
  //
  // typedef struct {
  //  char gpr;     /* index into the array of 8 GPRs
  //                 * stored in the register save area
  //                 * gpr=0 corresponds to r3,
  //                 * gpr=1 to r4, etc.
  //                 */
  //  char fpr;     /* index into the array of 8 FPRs
  //                 * stored in the register save area
  //                 * fpr=0 corresponds to f1,
  //                 * fpr=1 to f2, etc.
  //                 */
  //  char *overflow_arg_area;
  //                /* location on stack that holds
  //                 * the next overflow argument
  //                 */
  //  char *reg_save_area;
  //               /* where r3:r10 and f1:f8 (if saved)
  //                * are stored
  //                */
  // } va_list[1];

  SDValue ArgGPR = DAG.getConstant(FuncInfo->getVarArgsNumGPR(), dl, MVT::i32);
  SDValue ArgFPR = DAG.getConstant(FuncInfo->getVarArgsNumFPR(), dl, MVT::i32);
  SDValue StackOffsetFI = DAG.getFrameIndex(FuncInfo->getVarArgsStackOffset(),
                                            PtrVT);
  SDValue FR = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
                                 PtrVT);

  uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
  SDValue ConstFrameOffset = DAG.getConstant(FrameOffset, dl, PtrVT);

  uint64_t StackOffset = PtrVT.getSizeInBits()/8 - 1;
  SDValue ConstStackOffset = DAG.getConstant(StackOffset, dl, PtrVT);

  uint64_t FPROffset = 1;
  SDValue ConstFPROffset = DAG.getConstant(FPROffset, dl, PtrVT);

  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();

  // Store first byte : number of int regs
  SDValue firstStore =
      DAG.getTruncStore(Op.getOperand(0), dl, ArgGPR, Op.getOperand(1),
                        MachinePointerInfo(SV), MVT::i8);
  uint64_t nextOffset = FPROffset;
  SDValue nextPtr = DAG.getNode(ISD::ADD, dl, PtrVT, Op.getOperand(1),
                                  ConstFPROffset);

  // Store second byte : number of float regs
  SDValue secondStore =
      DAG.getTruncStore(firstStore, dl, ArgFPR, nextPtr,
                        MachinePointerInfo(SV, nextOffset), MVT::i8);
  nextOffset += StackOffset;
  nextPtr = DAG.getNode(ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);

  // Store second word : arguments given on stack
  SDValue thirdStore = DAG.getStore(secondStore, dl, StackOffsetFI, nextPtr,
                                    MachinePointerInfo(SV, nextOffset));
  nextOffset += FrameOffset;
  nextPtr = DAG.getNode(ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);

  // Store third word : arguments given in registers
  return DAG.getStore(thirdStore, dl, FR, nextPtr,
                      MachinePointerInfo(SV, nextOffset));
}

/// FPR - The set of FP registers that should be allocated for arguments
/// on Darwin and AIX.
static const MCPhysReg FPR[] = {PPC::F1,  PPC::F2,  PPC::F3, PPC::F4, PPC::F5,
                                PPC::F6,  PPC::F7,  PPC::F8, PPC::F9, PPC::F10,
                                PPC::F11, PPC::F12, PPC::F13};

/// CalculateStackSlotSize - Calculates the size reserved for this argument on
/// the stack.
static unsigned CalculateStackSlotSize(EVT ArgVT, ISD::ArgFlagsTy Flags,
                                       unsigned PtrByteSize) {
  unsigned ArgSize = ArgVT.getStoreSize();
  if (Flags.isByVal())
    ArgSize = Flags.getByValSize();

  // Round up to multiples of the pointer size, except for array members,
  // which are always packed.
  if (!Flags.isInConsecutiveRegs())
    ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;

  return ArgSize;
}

/// CalculateStackSlotAlignment - Calculates the alignment of this argument
/// on the stack.
static Align CalculateStackSlotAlignment(EVT ArgVT, EVT OrigVT,
                                         ISD::ArgFlagsTy Flags,
                                         unsigned PtrByteSize) {
  Align Alignment(PtrByteSize);

  // Altivec parameters are padded to a 16 byte boundary.
  if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
      ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
      ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
      ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
    Alignment = Align(16);

  // ByVal parameters are aligned as requested.
  if (Flags.isByVal()) {
    auto BVAlign = Flags.getNonZeroByValAlign();
    if (BVAlign > PtrByteSize) {
      if (BVAlign.value() % PtrByteSize != 0)
        llvm_unreachable(
            "ByVal alignment is not a multiple of the pointer size");

      Alignment = BVAlign;
    }
  }

  // Array members are always packed to their original alignment.
  if (Flags.isInConsecutiveRegs()) {
    // If the array member was split into multiple registers, the first
    // needs to be aligned to the size of the full type.  (Except for
    // ppcf128, which is only aligned as its f64 components.)
    if (Flags.isSplit() && OrigVT != MVT::ppcf128)
      Alignment = Align(OrigVT.getStoreSize());
    else
      Alignment = Align(ArgVT.getStoreSize());
  }

  return Alignment;
}

/// CalculateStackSlotUsed - Return whether this argument will use its
/// stack slot (instead of being passed in registers).  ArgOffset,
/// AvailableFPRs, and AvailableVRs must hold the current argument
/// position, and will be updated to account for this argument.
static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags,
                                   unsigned PtrByteSize, unsigned LinkageSize,
                                   unsigned ParamAreaSize, unsigned &ArgOffset,
                                   unsigned &AvailableFPRs,
                                   unsigned &AvailableVRs) {
  bool UseMemory = false;

  // Respect alignment of argument on the stack.
  Align Alignment =
      CalculateStackSlotAlignment(ArgVT, OrigVT, Flags, PtrByteSize);
  ArgOffset = alignTo(ArgOffset, Alignment);
  // If there's no space left in the argument save area, we must
  // use memory (this check also catches zero-sized arguments).
  if (ArgOffset >= LinkageSize + ParamAreaSize)
    UseMemory = true;

  // Allocate argument on the stack.
  ArgOffset += CalculateStackSlotSize(ArgVT, Flags, PtrByteSize);
  if (Flags.isInConsecutiveRegsLast())
    ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
  // If we overran the argument save area, we must use memory
  // (this check catches arguments passed partially in memory)
  if (ArgOffset > LinkageSize + ParamAreaSize)
    UseMemory = true;

  // However, if the argument is actually passed in an FPR or a VR,
  // we don't use memory after all.
  if (!Flags.isByVal()) {
    if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
      if (AvailableFPRs > 0) {
        --AvailableFPRs;
        return false;
      }
    if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
        ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
        ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
        ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
      if (AvailableVRs > 0) {
        --AvailableVRs;
        return false;
      }
  }

  return UseMemory;
}

/// EnsureStackAlignment - Round stack frame size up from NumBytes to
/// ensure minimum alignment required for target.
static unsigned EnsureStackAlignment(const PPCFrameLowering *Lowering,
                                     unsigned NumBytes) {
  return alignTo(NumBytes, Lowering->getStackAlign());
}

SDValue PPCTargetLowering::LowerFormalArguments(
    SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
    const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
    SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
  if (Subtarget.isAIXABI())
    return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
                                    InVals);
  if (Subtarget.is64BitELFABI())
    return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
                                       InVals);
  assert(Subtarget.is32BitELFABI());
  return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
                                     InVals);
}

SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
    SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
    const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
    SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {

  // 32-bit SVR4 ABI Stack Frame Layout:
  //              +-----------------------------------+
  //        +-->  |            Back chain             |
  //        |     +-----------------------------------+
  //        |     | Floating-point register save area |
  //        |     +-----------------------------------+
  //        |     |    General register save area     |
  //        |     +-----------------------------------+
  //        |     |          CR save word             |
  //        |     +-----------------------------------+
  //        |     |         VRSAVE save word          |
  //        |     +-----------------------------------+
  //        |     |         Alignment padding         |
  //        |     +-----------------------------------+
  //        |     |     Vector register save area     |
  //        |     +-----------------------------------+
  //        |     |       Local variable space        |
  //        |     +-----------------------------------+
  //        |     |        Parameter list area        |
  //        |     +-----------------------------------+
  //        |     |           LR save word            |
  //        |     +-----------------------------------+
  // SP-->  +---  |            Back chain             |
  //              +-----------------------------------+
  //
  // Specifications:
  //   System V Application Binary Interface PowerPC Processor Supplement
  //   AltiVec Technology Programming Interface Manual

  MachineFunction &MF = DAG.getMachineFunction();
  MachineFrameInfo &MFI = MF.getFrameInfo();
  PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();

  EVT PtrVT = getPointerTy(MF.getDataLayout());
  // Potential tail calls could cause overwriting of argument stack slots.
  bool isImmutable = !(getTargetMachine().Options.GuaranteedTailCallOpt &&
                       (CallConv == CallingConv::Fast));
  const Align PtrAlign(4);

  // Assign locations to all of the incoming arguments.
  SmallVector<CCValAssign, 16> ArgLocs;
  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
                 *DAG.getContext());

  // Reserve space for the linkage area on the stack.
  unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
  CCInfo.AllocateStack(LinkageSize, PtrAlign);
  CCInfo.AnalyzeFormalArguments(Ins, CC_PPC32_SVR4);

  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
    CCValAssign &VA = ArgLocs[i];

    // Arguments stored in registers.
    if (VA.isRegLoc()) {
      const TargetRegisterClass *RC;
      EVT ValVT = VA.getValVT();

      switch (ValVT.getSimpleVT().SimpleTy) {
        default:
          llvm_unreachable("ValVT not supported by formal arguments Lowering");
        case MVT::i1:
        case MVT::i32:
          RC = &PPC::GPRCRegClass;
          break;
        case MVT::f32:
          if (Subtarget.hasP8Vector())
            RC = &PPC::VSSRCRegClass;
          else if (Subtarget.hasSPE())
            RC = &PPC::GPRCRegClass;
          else
            RC = &PPC::F4RCRegClass;
          break;
        case MVT::f64:
          if (Subtarget.hasVSX())
            RC = &PPC::VSFRCRegClass;
          else if (Subtarget.hasSPE())
            // SPE passes doubles in GPR pairs.
            RC = &PPC::GPRCRegClass;
          else
            RC = &PPC::F8RCRegClass;
          break;
        case MVT::v16i8:
        case MVT::v8i16:
        case MVT::v4i32:
          RC = &PPC::VRRCRegClass;
          break;
        case MVT::v4f32:
          RC = &PPC::VRRCRegClass;
          break;
        case MVT::v2f64:
        case MVT::v2i64:
          RC = &PPC::VRRCRegClass;
          break;
      }

      SDValue ArgValue;
      // Transform the arguments stored in physical registers into
      // virtual ones.
      if (VA.getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
        assert(i + 1 < e && "No second half of double precision argument");
        Register RegLo = MF.addLiveIn(VA.getLocReg(), RC);
        Register RegHi = MF.addLiveIn(ArgLocs[++i].getLocReg(), RC);
        SDValue ArgValueLo = DAG.getCopyFromReg(Chain, dl, RegLo, MVT::i32);
        SDValue ArgValueHi = DAG.getCopyFromReg(Chain, dl, RegHi, MVT::i32);
        if (!Subtarget.isLittleEndian())
          std::swap (ArgValueLo, ArgValueHi);
        ArgValue = DAG.getNode(PPCISD::BUILD_SPE64, dl, MVT::f64, ArgValueLo,
                               ArgValueHi);
      } else {
        Register Reg = MF.addLiveIn(VA.getLocReg(), RC);
        ArgValue = DAG.getCopyFromReg(Chain, dl, Reg,
                                      ValVT == MVT::i1 ? MVT::i32 : ValVT);
        if (ValVT == MVT::i1)
          ArgValue = DAG.getNode(ISD::TRUNCATE, dl, MVT::i1, ArgValue);
      }

      InVals.push_back(ArgValue);
    } else {
      // Argument stored in memory.
      assert(VA.isMemLoc());

      // Get the extended size of the argument type in stack
      unsigned ArgSize = VA.getLocVT().getStoreSize();
      // Get the actual size of the argument type
      unsigned ObjSize = VA.getValVT().getStoreSize();
      unsigned ArgOffset = VA.getLocMemOffset();
      // Stack objects in PPC32 are right justified.
      ArgOffset += ArgSize - ObjSize;
      int FI = MFI.CreateFixedObject(ArgSize, ArgOffset, isImmutable);

      // Create load nodes to retrieve arguments from the stack.
      SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
      InVals.push_back(
          DAG.getLoad(VA.getValVT(), dl, Chain, FIN, MachinePointerInfo()));
    }
  }

  // Assign locations to all of the incoming aggregate by value arguments.
  // Aggregates passed by value are stored in the local variable space of the
  // caller's stack frame, right above the parameter list area.
  SmallVector<CCValAssign, 16> ByValArgLocs;
  CCState CCByValInfo(CallConv, isVarArg, DAG.getMachineFunction(),
                      ByValArgLocs, *DAG.getContext());

  // Reserve stack space for the allocations in CCInfo.
  CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);

  CCByValInfo.AnalyzeFormalArguments(Ins, CC_PPC32_SVR4_ByVal);

  // Area that is at least reserved in the caller of this function.
  unsigned MinReservedArea = CCByValInfo.getStackSize();
  MinReservedArea = std::max(MinReservedArea, LinkageSize);

  // Set the size that is at least reserved in caller of this function.  Tail
  // call optimized function's reserved stack space needs to be aligned so that
  // taking the difference between two stack areas will result in an aligned
  // stack.
  MinReservedArea =
      EnsureStackAlignment(Subtarget.getFrameLowering(), MinReservedArea);
  FuncInfo->setMinReservedArea(MinReservedArea);

  SmallVector<SDValue, 8> MemOps;

  // If the function takes variable number of arguments, make a frame index for
  // the start of the first vararg value... for expansion of llvm.va_start.
  if (isVarArg) {
    static const MCPhysReg GPArgRegs[] = {
      PPC::R3, PPC::R4, PPC::R5, PPC::R6,
      PPC::R7, PPC::R8, PPC::R9, PPC::R10,
    };
    const unsigned NumGPArgRegs = std::size(GPArgRegs);

    static const MCPhysReg FPArgRegs[] = {
      PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
      PPC::F8
    };
    unsigned NumFPArgRegs = std::size(FPArgRegs);

    if (useSoftFloat() || hasSPE())
       NumFPArgRegs = 0;

    FuncInfo->setVarArgsNumGPR(CCInfo.getFirstUnallocated(GPArgRegs));
    FuncInfo->setVarArgsNumFPR(CCInfo.getFirstUnallocated(FPArgRegs));

    // Make room for NumGPArgRegs and NumFPArgRegs.
    int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
                NumFPArgRegs * MVT(MVT::f64).getSizeInBits()/8;

    FuncInfo->setVarArgsStackOffset(MFI.CreateFixedObject(
        PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(), true));

    FuncInfo->setVarArgsFrameIndex(
        MFI.CreateStackObject(Depth, Align(8), false));
    SDValue FIN = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);

    // The fixed integer arguments of a variadic function are stored to the
    // VarArgsFrameIndex on the stack so that they may be loaded by
    // dereferencing the result of va_next.
    for (MCPhysReg GPArgReg : GPArgRegs) {
      // Get an existing live-in vreg, or add a new one.
      Register VReg = MF.getRegInfo().getLiveInVirtReg(GPArgReg);
      if (!VReg)
        VReg = MF.addLiveIn(GPArgReg, &PPC::GPRCRegClass);

      SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT);
      SDValue Store =
          DAG.getStore(Val.getValue(1), dl, Val, FIN, MachinePointerInfo());
      MemOps.push_back(Store);
      // Increment the address by four for the next argument to store
      SDValue PtrOff = DAG.getConstant(PtrVT.getSizeInBits()/8, dl, PtrVT);
      FIN = DAG.getNode(ISD::ADD, dl, PtrOff.getValueType(), FIN, PtrOff);
    }

    // FIXME 32-bit SVR4: We only need to save FP argument registers if CR bit 6
    // is set.
    // The double arguments are stored to the VarArgsFrameIndex
    // on the stack.
    for (unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
      // Get an existing live-in vreg, or add a new one.
      Register VReg = MF.getRegInfo().getLiveInVirtReg(FPArgRegs[FPRIndex]);
      if (!VReg)
        VReg = MF.addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);

      SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::f64);
      SDValue Store =
          DAG.getStore(Val.getValue(1), dl, Val, FIN, MachinePointerInfo());
      MemOps.push_back(Store);
      // Increment the address by eight for the next argument to store
      SDValue PtrOff = DAG.getConstant(MVT(MVT::f64).getSizeInBits()/8, dl,
                                         PtrVT);
      FIN = DAG.getNode(ISD::ADD, dl, PtrOff.getValueType(), FIN, PtrOff);
    }
  }

  if (!MemOps.empty())
    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOps);

  return Chain;
}

// PPC64 passes i8, i16, and i32 values in i64 registers. Promote
// value to MVT::i64 and then truncate to the correct register size.
SDValue PPCTargetLowering::extendArgForPPC64(ISD::ArgFlagsTy Flags,
                                             EVT ObjectVT, SelectionDAG &DAG,
                                             SDValue ArgVal,
                                             const SDLoc &dl) const {
  if (Flags.isSExt())
    ArgVal = DAG.getNode(ISD::AssertSext, dl, MVT::i64, ArgVal,
                         DAG.getValueType(ObjectVT));
  else if (Flags.isZExt())
    ArgVal = DAG.getNode(ISD::AssertZext, dl, MVT::i64, ArgVal,
                         DAG.getValueType(ObjectVT));

  return DAG.getNode(ISD::TRUNCATE, dl, ObjectVT, ArgVal);
}

SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
    SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
    const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
    SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
  // TODO: add description of PPC stack frame format, or at least some docs.
  //
  bool isELFv2ABI = Subtarget.isELFv2ABI();
  bool isLittleEndian = Subtarget.isLittleEndian();
  MachineFunction &MF = DAG.getMachineFunction();
  MachineFrameInfo &MFI = MF.getFrameInfo();
  PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();

  assert(!(CallConv == CallingConv::Fast && isVarArg) &&
         "fastcc not supported on varargs functions");

  EVT PtrVT = getPointerTy(MF.getDataLayout());
  // Potential tail calls could cause overwriting of argument stack slots.
  bool isImmutable = !(getTargetMachine().Options.GuaranteedTailCallOpt &&
                       (CallConv == CallingConv::Fast));
  unsigned PtrByteSize = 8;
  unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();

  static const MCPhysReg GPR[] = {
    PPC::X3, PPC::X4, PPC::X5, PPC::X6,
    PPC::X7, PPC::X8, PPC::X9, PPC::X10,
  };
  static const MCPhysReg VR[] = {
    PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
    PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
  };

  const unsigned Num_GPR_Regs = std::size(GPR);
  const unsigned Num_FPR_Regs = useSoftFloat() ? 0 : 13;
  const unsigned Num_VR_Regs = std::size(VR);

  // Do a first pass over the arguments to determine whether the ABI
  // guarantees that our caller has allocated the parameter save area
  // on its stack frame.  In the ELFv1 ABI, this is always the case;
  // in the ELFv2 ABI, it is true if this is a vararg function or if
  // any parameter is located in a stack slot.

  bool HasParameterArea = !isELFv2ABI || isVarArg;
  unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
  unsigned NumBytes = LinkageSize;
  unsigned AvailableFPRs = Num_FPR_Regs;
  unsigned AvailableVRs = Num_VR_Regs;
  for (const ISD::InputArg &In : Ins) {
    if (In.Flags.isNest())
      continue;

    if (CalculateStackSlotUsed(In.VT, In.ArgVT, In.Flags, PtrByteSize,
                               LinkageSize, ParamAreaSize, NumBytes,
                               AvailableFPRs, AvailableVRs))
      HasParameterArea = true;
  }

  // Add DAG nodes to load the arguments or copy them out of registers.  On
  // entry to a function on PPC, the arguments start after the linkage area,
  // although the first ones are often in registers.

  unsigned ArgOffset = LinkageSize;
  unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
  SmallVector<SDValue, 8> MemOps;
  Function::const_arg_iterator FuncArg = MF.getFunction().arg_begin();
  unsigned CurArgIdx = 0;
  for (unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) {
    SDValue ArgVal;
    bool needsLoad = false;
    EVT ObjectVT = Ins[ArgNo].VT;
    EVT OrigVT = Ins[ArgNo].ArgVT;
    unsigned ObjSize = ObjectVT.getStoreSize();
    unsigned ArgSize = ObjSize;
    ISD::ArgFlagsTy Flags = Ins[ArgNo].Flags;
    if (Ins[ArgNo].isOrigArg()) {
      std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
      CurArgIdx = Ins[ArgNo].getOrigArgIndex();
    }
    // We re-align the argument offset for each argument, except when using the
    // fast calling convention, when we need to make sure we do that only when
    // we'll actually use a stack slot.
    unsigned CurArgOffset;
    Align Alignment;
    auto ComputeArgOffset = [&]() {
      /* Respect alignment of argument on the stack.  */
      Alignment =
          CalculateStackSlotAlignment(ObjectVT, OrigVT, Flags, PtrByteSize);
      ArgOffset = alignTo(ArgOffset, Alignment);
      CurArgOffset = ArgOffset;
    };

    if (CallConv != CallingConv::Fast) {
      ComputeArgOffset();

      /* Compute GPR index associated with argument offset.  */
      GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
      GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
    }

    // FIXME the codegen can be much improved in some cases.
    // We do not have to keep everything in memory.
    if (Flags.isByVal()) {
      assert(Ins[ArgNo].isOrigArg() && "Byval arguments cannot be implicit");

      if (CallConv == CallingConv::Fast)
        ComputeArgOffset();

      // ObjSize is the true size, ArgSize rounded up to multiple of registers.
      ObjSize = Flags.getByValSize();
      ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
      // Empty aggregate parameters do not take up registers.  Examples:
      //   struct { } a;
      //   union  { } b;
      //   int c[0];
      // etc.  However, we have to provide a place-holder in InVals, so
      // pretend we have an 8-byte item at the current address for that
      // purpose.
      if (!ObjSize) {
        int FI = MFI.CreateFixedObject(PtrByteSize, ArgOffset, true);
        SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
        InVals.push_back(FIN);
        continue;
      }

      // Create a stack object covering all stack doublewords occupied
      // by the argument.  If the argument is (fully or partially) on
      // the stack, or if the argument is fully in registers but the
      // caller has allocated the parameter save anyway, we can refer
      // directly to the caller's stack frame.  Otherwise, create a
      // local copy in our own frame.
      int FI;
      if (HasParameterArea ||
          ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
        FI = MFI.CreateFixedObject(ArgSize, ArgOffset, false, true);
      else
        FI = MFI.CreateStackObject(ArgSize, Alignment, false);
      SDValue FIN = DAG.getFrameIndex(FI, PtrVT);

      // Handle aggregates smaller than 8 bytes.
      if (ObjSize < PtrByteSize) {
        // The value of the object is its address, which differs from the
        // address of the enclosing doubleword on big-endian systems.
        SDValue Arg = FIN;
        if (!isLittleEndian) {
          SDValue ArgOff = DAG.getConstant(PtrByteSize - ObjSize, dl, PtrVT);
          Arg = DAG.getNode(ISD::ADD, dl, ArgOff.getValueType(), Arg, ArgOff);
        }
        InVals.push_back(Arg);

        if (GPR_idx != Num_GPR_Regs) {
          Register VReg = MF.addLiveIn(GPR[GPR_idx++], &PPC::G8RCRegClass);
          FuncInfo->addLiveInAttr(VReg, Flags);
          SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT);
          EVT ObjType = EVT::getIntegerVT(*DAG.getContext(), ObjSize * 8);
          SDValue Store =
              DAG.getTruncStore(Val.getValue(1), dl, Val, Arg,
                                MachinePointerInfo(&*FuncArg), ObjType);
          MemOps.push_back(Store);
        }
        // Whether we copied from a register or not, advance the offset
        // into the parameter save area by a full doubleword.
        ArgOffset += PtrByteSize;
        continue;
      }

      // The value of the object is its address, which is the address of
      // its first stack doubleword.
      InVals.push_back(FIN);

      // Store whatever pieces of the object are in registers to memory.
      for (unsigned j = 0; j < ArgSize; j += PtrByteSize) {
        if (GPR_idx == Num_GPR_Regs)
          break;

        Register VReg = MF.addLiveIn(GPR[GPR_idx], &PPC::G8RCRegClass);
        FuncInfo->addLiveInAttr(VReg, Flags);
        SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT);
        SDValue Addr = FIN;
        if (j) {
          SDValue Off = DAG.getConstant(j, dl, PtrVT);
          Addr = DAG.getNode(ISD::ADD, dl, Off.getValueType(), Addr, Off);
        }
        unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
        EVT ObjType = EVT::getIntegerVT(*DAG.getContext(), StoreSizeInBits);
        SDValue Store =
            DAG.getTruncStore(Val.getValue(1), dl, Val, Addr,
                              MachinePointerInfo(&*FuncArg, j), ObjType);
        MemOps.push_back(Store);
        ++GPR_idx;
      }
      ArgOffset += ArgSize;
      continue;
    }

    switch (ObjectVT.getSimpleVT().SimpleTy) {
    default: llvm_unreachable("Unhandled argument type!");
    case MVT::i1:
    case MVT::i32:
    case MVT::i64:
      if (Flags.isNest()) {
        // The 'nest' parameter, if any, is passed in R11.
        Register VReg = MF.addLiveIn(PPC::X11, &PPC::G8RCRegClass);
        ArgVal = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i64);

        if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
          ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);

        break;
      }

      // These can be scalar arguments or elements of an integer array type
      // passed directly.  Clang may use those instead of "byval" aggregate
      // types to avoid forcing arguments to memory unnecessarily.
      if (GPR_idx != Num_GPR_Regs) {
        Register VReg = MF.addLiveIn(GPR[GPR_idx++], &PPC::G8RCRegClass);
        FuncInfo->addLiveInAttr(VReg, Flags);
        ArgVal = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i64);

        if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
          // PPC64 passes i8, i16, and i32 values in i64 registers. Promote
          // value to MVT::i64 and then truncate to the correct register size.
          ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
      } else {
        if (CallConv == CallingConv::Fast)
          ComputeArgOffset();

        needsLoad = true;
        ArgSize = PtrByteSize;
      }
      if (CallConv != CallingConv::Fast || needsLoad)
        ArgOffset += 8;
      break;

    case MVT::f32:
    case MVT::f64:
      // These can be scalar arguments or elements of a float array type
      // passed directly.  The latter are used to implement ELFv2 homogenous
      // float aggregates.
      if (FPR_idx != Num_FPR_Regs) {
        unsigned VReg;

        if (ObjectVT == MVT::f32)
          VReg = MF.addLiveIn(FPR[FPR_idx],
                              Subtarget.hasP8Vector()
                                  ? &PPC::VSSRCRegClass
                                  : &PPC::F4RCRegClass);
        else
          VReg = MF.addLiveIn(FPR[FPR_idx], Subtarget.hasVSX()
                                                ? &PPC::VSFRCRegClass
                                                : &PPC::F8RCRegClass);

        ArgVal = DAG.getCopyFromReg(Chain, dl, VReg, ObjectVT);
        ++FPR_idx;
      } else if (GPR_idx != Num_GPR_Regs && CallConv != CallingConv::Fast) {
        // FIXME: We may want to re-enable this for CallingConv::Fast on the P8
        // once we support fp <-> gpr moves.

        // This can only ever happen in the presence of f32 array types,
        // since otherwise we never run out of FPRs before running out
        // of GPRs.
        Register VReg = MF.addLiveIn(GPR[GPR_idx++], &PPC::G8RCRegClass);
        FuncInfo->addLiveInAttr(VReg, Flags);
        ArgVal = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i64);

        if (ObjectVT == MVT::f32) {
          if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
            ArgVal = DAG.getNode(ISD::SRL, dl, MVT::i64, ArgVal,
                                 DAG.getConstant(32, dl, MVT::i32));
          ArgVal = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, ArgVal);
        }

        ArgVal = DAG.getNode(ISD::BITCAST, dl, ObjectVT, ArgVal);
      } else {
        if (CallConv == CallingConv::Fast)
          ComputeArgOffset();

        needsLoad = true;
      }

      // When passing an array of floats, the array occupies consecutive
      // space in the argument area; only round up to the next doubleword
      // at the end of the array.  Otherwise, each float takes 8 bytes.
      if (CallConv != CallingConv::Fast || needsLoad) {
        ArgSize = Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
        ArgOffset += ArgSize;
        if (Flags.isInConsecutiveRegsLast())
          ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
      }
      break;
    case MVT::v4f32:
    case MVT::v4i32:
    case MVT::v8i16:
    case MVT::v16i8:
    case MVT::v2f64:
    case MVT::v2i64:
    case MVT::v1i128:
    case MVT::f128:
      // These can be scalar arguments or elements of a vector array type
      // passed directly.  The latter are used to implement ELFv2 homogenous
      // vector aggregates.
      if (VR_idx != Num_VR_Regs) {
        Register VReg = MF.addLiveIn(VR[VR_idx], &PPC::VRRCRegClass);
        ArgVal = DAG.getCopyFromReg(Chain, dl, VReg, ObjectVT);
        ++VR_idx;
      } else {
        if (CallConv == CallingConv::Fast)
          ComputeArgOffset();
        needsLoad = true;
      }
      if (CallConv != CallingConv::Fast || needsLoad)
        ArgOffset += 16;
      break;
    }

    // We need to load the argument to a virtual register if we determined
    // above that we ran out of physical registers of the appropriate type.
    if (needsLoad) {
      if (ObjSize < ArgSize && !isLittleEndian)
        CurArgOffset += ArgSize - ObjSize;
      int FI = MFI.CreateFixedObject(ObjSize, CurArgOffset, isImmutable);
      SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
      ArgVal = DAG.getLoad(ObjectVT, dl, Chain, FIN, MachinePointerInfo());
    }

    InVals.push_back(ArgVal);
  }

  // Area that is at least reserved in the caller of this function.
  unsigned MinReservedArea;
  if (HasParameterArea)
    MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
  else
    MinReservedArea = LinkageSize;

  // Set the size that is at least reserved in caller of this function.  Tail
  // call optimized functions' reserved stack space needs to be aligned so that
  // taking the difference between two stack areas will result in an aligned
  // stack.
  MinReservedArea =
      EnsureStackAlignment(Subtarget.getFrameLowering(), MinReservedArea);
  FuncInfo->setMinReservedArea(MinReservedArea);

  // If the function takes variable number of arguments, make a frame index for
  // the start of the first vararg value... for expansion of llvm.va_start.
  // On ELFv2ABI spec, it writes:
  // C programs that are intended to be *portable* across different compilers
  // and architectures must use the header file <stdarg.h> to deal with variable
  // argument lists.
  if (isVarArg && MFI.hasVAStart()) {
    int Depth = ArgOffset;

    FuncInfo->setVarArgsFrameIndex(
      MFI.CreateFixedObject(PtrByteSize, Depth, true));
    SDValue FIN = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);

    // If this function is vararg, store any remaining integer argument regs
    // to their spots on the stack so that they may be loaded by dereferencing
    // the result of va_next.
    for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
         GPR_idx < Num_GPR_Regs; ++GPR_idx) {
      Register VReg = MF.addLiveIn(GPR[GPR_idx], &PPC::G8RCRegClass);
      SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT);
      SDValue Store =
          DAG.getStore(Val.getValue(1), dl, Val, FIN, MachinePointerInfo());
      MemOps.push_back(Store);
      // Increment the address by four for the next argument to store
      SDValue PtrOff = DAG.getConstant(PtrByteSize, dl, PtrVT);
      FIN = DAG.getNode(ISD::ADD, dl, PtrOff.getValueType(), FIN, PtrOff);
    }
  }

  if (!MemOps.empty())
    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOps);

  return Chain;
}

/// CalculateTailCallSPDiff - Get the amount the stack pointer has to be
/// adjusted to accommodate the arguments for the tailcall.
static int CalculateTailCallSPDiff(SelectionDAG& DAG, bool isTailCall,
                                   unsigned ParamSize) {

  if (!isTailCall) return 0;

  PPCFunctionInfo *FI = DAG.getMachineFunction().getInfo<PPCFunctionInfo>();
  unsigned CallerMinReservedArea = FI->getMinReservedArea();
  int SPDiff = (int)CallerMinReservedArea - (int)ParamSize;
  // Remember only if the new adjustment is bigger.
  if (SPDiff < FI->getTailCallSPDelta())
    FI->setTailCallSPDelta(SPDiff);

  return SPDiff;
}

static bool isFunctionGlobalAddress(const GlobalValue *CalleeGV);

static bool callsShareTOCBase(const Function *Caller,
                              const GlobalValue *CalleeGV,
                              const TargetMachine &TM) {
  // It does not make sense to call callsShareTOCBase() with a caller that
  // is PC Relative since PC Relative callers do not have a TOC.
#ifndef NDEBUG
  const PPCSubtarget *STICaller = &TM.getSubtarget<PPCSubtarget>(*Caller);
  assert(!STICaller->isUsingPCRelativeCalls() &&
         "PC Relative callers do not have a TOC and cannot share a TOC Base");
#endif

  // Callee is either a GlobalAddress or an ExternalSymbol. ExternalSymbols
  // don't have enough information to determine if the caller and callee share
  // the same  TOC base, so we have to pessimistically assume they don't for
  // correctness.
  if (!CalleeGV)
    return false;

  // If the callee is preemptable, then the static linker will use a plt-stub
  // which saves the toc to the stack, and needs a nop after the call
  // instruction to convert to a toc-restore.
  if (!TM.shouldAssumeDSOLocal(CalleeGV))
    return false;

  // Functions with PC Relative enabled may clobber the TOC in the same DSO.
  // We may need a TOC restore in the situation where the caller requires a
  // valid TOC but the callee is PC Relative and does not.
  const Function *F = dyn_cast<Function>(CalleeGV);
  const GlobalAlias *Alias = dyn_cast<GlobalAlias>(CalleeGV);

  // If we have an Alias we can try to get the function from there.
  if (Alias) {
    const GlobalObject *GlobalObj = Alias->getAliaseeObject();
    F = dyn_cast<Function>(GlobalObj);
  }

  // If we still have no valid function pointer we do not have enough
  // information to determine if the callee uses PC Relative calls so we must
  // assume that it does.
  if (!F)
    return false;

  // If the callee uses PC Relative we cannot guarantee that the callee won't
  // clobber the TOC of the caller and so we must assume that the two
  // functions do not share a TOC base.
  const PPCSubtarget *STICallee = &TM.getSubtarget<PPCSubtarget>(*F);
  if (STICallee->isUsingPCRelativeCalls())
    return false;

  // If the GV is not a strong definition then we need to assume it can be
  // replaced by another function at link time. The function that replaces
  // it may not share the same TOC as the caller since the callee may be
  // replaced by a PC Relative version of the same function.
  if (!CalleeGV->isStrongDefinitionForLinker())
    return false;

  // The medium and large code models are expected to provide a sufficiently
  // large TOC to provide all data addressing needs of a module with a
  // single TOC.
  if (CodeModel::Medium == TM.getCodeModel() ||
      CodeModel::Large == TM.getCodeModel())
    return true;

  // Any explicitly-specified sections and section prefixes must also match.
  // Also, if we're using -ffunction-sections, then each function is always in
  // a different section (the same is true for COMDAT functions).
  if (TM.getFunctionSections() || CalleeGV->hasComdat() ||
      Caller->hasComdat() || CalleeGV->getSection() != Caller->getSection())
    return false;
  if (const auto *F = dyn_cast<Function>(CalleeGV)) {
    if (F->getSectionPrefix() != Caller->getSectionPrefix())
      return false;
  }

  return true;
}

static bool
needStackSlotPassParameters(const PPCSubtarget &Subtarget,
                            const SmallVectorImpl<ISD::OutputArg> &Outs) {
  assert(Subtarget.is64BitELFABI());

  const unsigned PtrByteSize = 8;
  const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();

  static const MCPhysReg GPR[] = {
    PPC::X3, PPC::X4, PPC::X5, PPC::X6,
    PPC::X7, PPC::X8, PPC::X9, PPC::X10,
  };
  static const MCPhysReg VR[] = {
    PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
    PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
  };

  const unsigned NumGPRs = std::size(GPR);
  const unsigned NumFPRs = 13;
  const unsigned NumVRs = std::size(VR);
  const unsigned ParamAreaSize = NumGPRs * PtrByteSize;

  unsigned NumBytes = LinkageSize;
  unsigned AvailableFPRs = NumFPRs;
  unsigned AvailableVRs = NumVRs;

  for (const ISD::OutputArg& Param : Outs) {
    if (Param.Flags.isNest()) continue;

    if (CalculateStackSlotUsed(Param.VT, Param.ArgVT, Param.Flags, PtrByteSize,
                               LinkageSize, ParamAreaSize, NumBytes,
                               AvailableFPRs, AvailableVRs))
      return true;
  }
  return false;
}

static bool hasSameArgumentList(const Function *CallerFn, const CallBase &CB) {
  if (CB.arg_size() != CallerFn->arg_size())
    return false;

  auto CalleeArgIter = CB.arg_begin();
  auto CalleeArgEnd = CB.arg_end();
  Function::const_arg_iterator CallerArgIter = CallerFn->arg_begin();

  for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
    const Value* CalleeArg = *CalleeArgIter;
    const Value* CallerArg = &(*CallerArgIter);
    if (CalleeArg == CallerArg)
      continue;

    // e.g. @caller([4 x i64] %a, [4 x i64] %b) {
    //        tail call @callee([4 x i64] undef, [4 x i64] %b)
    //      }
    // 1st argument of callee is undef and has the same type as caller.
    if (CalleeArg->getType() == CallerArg->getType() &&
        isa<UndefValue>(CalleeArg))
      continue;

    return false;
  }

  return true;
}

// Returns true if TCO is possible between the callers and callees
// calling conventions.
static bool
areCallingConvEligibleForTCO_64SVR4(CallingConv::ID CallerCC,
                                    CallingConv::ID CalleeCC) {
  // Tail calls are possible with fastcc and ccc.
  auto isTailCallableCC  = [] (CallingConv::ID CC){
      return  CC == CallingConv::C || CC == CallingConv::Fast;
  };
  if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
    return false;

  // We can safely tail call both fastcc and ccc callees from a c calling
  // convention caller. If the caller is fastcc, we may have less stack space
  // than a non-fastcc caller with the same signature so disable tail-calls in
  // that case.
  return CallerCC == CallingConv::C || CallerCC == CalleeCC;
}

bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
    const GlobalValue *CalleeGV, CallingConv::ID CalleeCC,
    CallingConv::ID CallerCC, const CallBase *CB, bool isVarArg,
    const SmallVectorImpl<ISD::OutputArg> &Outs,
    const SmallVectorImpl<ISD::InputArg> &Ins, const Function *CallerFunc,
    bool isCalleeExternalSymbol) const {
  bool TailCallOpt = getTargetMachine().Options.GuaranteedTailCallOpt;

  if (DisableSCO && !TailCallOpt) return false;

  // Variadic argument functions are not supported.
  if (isVarArg) return false;

  // Check that the calling conventions are compatible for tco.
  if (!areCallingConvEligibleForTCO_64SVR4(CallerCC, CalleeCC))
    return false;

  // Caller contains any byval parameter is not supported.
  if (any_of(Ins, [](const ISD::InputArg &IA) { return IA.Flags.isByVal(); }))
    return false;

  // Callee contains any byval parameter is not supported, too.
  // Note: This is a quick work around, because in some cases, e.g.
  // caller's stack size > callee's stack size, we are still able to apply
  // sibling call optimization. For example, gcc is able to do SCO for caller1
  // in the following example, but not for caller2.
  //   struct test {
  //     long int a;
  //     char ary[56];
  //   } gTest;
  //   __attribute__((noinline)) int callee(struct test v, struct test *b) {
  //     b->a = v.a;
  //     return 0;
  //   }
  //   void caller1(struct test a, struct test c, struct test *b) {
  //     callee(gTest, b); }
  //   void caller2(struct test *b) { callee(gTest, b); }
  if (any_of(Outs, [](const ISD::OutputArg& OA) { return OA.Flags.isByVal(); }))
    return false;

  // If callee and caller use different calling conventions, we cannot pass
  // parameters on stack since offsets for the parameter area may be different.
  if (CallerCC != CalleeCC && needStackSlotPassParameters(Subtarget, Outs))
    return false;

  // All variants of 64-bit ELF ABIs without PC-Relative addressing require that
  // the caller and callee share the same TOC for TCO/SCO. If the caller and
  // callee potentially have different TOC bases then we cannot tail call since
  // we need to restore the TOC pointer after the call.
  // ref: https://bugzilla.mozilla.org/show_bug.cgi?id=973977
  // We cannot guarantee this for indirect calls or calls to external functions.
  // When PC-Relative addressing is used, the concept of the TOC is no longer
  // applicable so this check is not required.
  // Check first for indirect calls.
  if (!Subtarget.isUsingPCRelativeCalls() &&
      !isFunctionGlobalAddress(CalleeGV) && !isCalleeExternalSymbol)
    return false;

  // Check if we share the TOC base.
  if (!Subtarget.isUsingPCRelativeCalls() &&
      !callsShareTOCBase(CallerFunc, CalleeGV, getTargetMachine()))
    return false;

  // TCO allows altering callee ABI, so we don't have to check further.
  if (CalleeCC == CallingConv::Fast && TailCallOpt)
    return true;

  if (DisableSCO) return false;

  // If callee use the same argument list that caller is using, then we can
  // apply SCO on this case. If it is not, then we need to check if callee needs
  // stack for passing arguments.
  // PC Relative tail calls may not have a CallBase.
  // If there is no CallBase we cannot verify if we have the same argument
  // list so assume that we don't have the same argument list.
  if (CB && !hasSameArgumentList(CallerFunc, *CB) &&
      needStackSlotPassParameters(Subtarget, Outs))
    return false;
  else if (!CB && needStackSlotPassParameters(Subtarget, Outs))
    return false;

  return true;
}

/// IsEligibleForTailCallOptimization - Check whether the call is eligible
/// for tail call optimization. Targets which want to do tail call
/// optimization should implement this function.
bool PPCTargetLowering::IsEligibleForTailCallOptimization(
    const GlobalValue *CalleeGV, CallingConv::ID CalleeCC,
    CallingConv::ID CallerCC, bool isVarArg,
    const SmallVectorImpl<ISD::InputArg> &Ins) const {
  if (!getTargetMachine().Options.GuaranteedTailCallOpt)
    return false;

  // Variable argument functions are not supported.
  if (isVarArg)
    return false;

  if (CalleeCC == CallingConv::Fast && CallerCC == CalleeCC) {
    // Functions containing by val parameters are not supported.
    if (any_of(Ins, [](const ISD::InputArg &IA) { return IA.Flags.isByVal(); }))
      return false;

    // Non-PIC/GOT tail calls are supported.
    if (getTargetMachine().getRelocationModel() != Reloc::PIC_)
      return true;

    // At the moment we can only do local tail calls (in same module, hidden
    // or protected) if we are generating PIC.
    if (CalleeGV)
      return CalleeGV->hasHiddenVisibility() ||
             CalleeGV->hasProtectedVisibility();
  }

  return false;
}

/// isCallCompatibleAddress - Return the immediate to use if the specified
/// 32-bit value is representable in the immediate field of a BxA instruction.
static SDNode *isBLACompatibleAddress(SDValue Op, SelectionDAG &DAG) {
  ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
  if (!C) return nullptr;

  int Addr = C->getZExtValue();
  if ((Addr & 3) != 0 ||  // Low 2 bits are implicitly zero.
      SignExtend32<26>(Addr) != Addr)
    return nullptr;  // Top 6 bits have to be sext of immediate.

  return DAG
      .getSignedConstant(
          (int)C->getZExtValue() >> 2, SDLoc(Op),
          DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout()))
      .getNode();
}

namespace {

struct TailCallArgumentInfo {
  SDValue Arg;
  SDValue FrameIdxOp;
  int FrameIdx = 0;

  TailCallArgumentInfo() = default;
};

} // end anonymous namespace

/// StoreTailCallArgumentsToStackSlot - Stores arguments to their stack slot.
static void StoreTailCallArgumentsToStackSlot(
    SelectionDAG &DAG, SDValue Chain,
    const SmallVectorImpl<TailCallArgumentInfo> &TailCallArgs,
    SmallVectorImpl<SDValue> &MemOpChains, const SDLoc &dl) {
  for (unsigned i = 0, e = TailCallArgs.size(); i != e; ++i) {
    SDValue Arg = TailCallArgs[i].Arg;
    SDValue FIN = TailCallArgs[i].FrameIdxOp;
    int FI = TailCallArgs[i].FrameIdx;
    // Store relative to framepointer.
    MemOpChains.push_back(DAG.getStore(
        Chain, dl, Arg, FIN,
        MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI)));
  }
}

/// EmitTailCallStoreFPAndRetAddr - Move the frame pointer and return address to
/// the appropriate stack slot for the tail call optimized function call.
static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG, SDValue Chain,
                                             SDValue OldRetAddr, SDValue OldFP,
                                             int SPDiff, const SDLoc &dl) {
  if (SPDiff) {
    // Calculate the new stack slot for the return address.
    MachineFunction &MF = DAG.getMachineFunction();
    const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>();
    const PPCFrameLowering *FL = Subtarget.getFrameLowering();
    int SlotSize = Subtarget.isPPC64() ? 8 : 4;
    int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
    int NewRetAddr = MF.getFrameInfo().CreateFixedObject(SlotSize,
                                                         NewRetAddrLoc, true);
    SDValue NewRetAddrFrIdx =
        DAG.getFrameIndex(NewRetAddr, Subtarget.getScalarIntVT());
    Chain = DAG.getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
                         MachinePointerInfo::getFixedStack(MF, NewRetAddr));
  }
  return Chain;
}

/// CalculateTailCallArgDest - Remember Argument for later processing. Calculate
/// the position of the argument.
static void CalculateTailCallArgDest(
    SelectionDAG &DAG, MachineFunction &MF, bool IsPPC64, SDValue Arg,
    int SPDiff, unsigned ArgOffset,
    SmallVectorImpl<TailCallArgumentInfo> &TailCallArguments) {
  int Offset = ArgOffset + SPDiff;
  uint32_t OpSize = (Arg.getValueSizeInBits() + 7) / 8;
  int FI = MF.getFrameInfo().CreateFixedObject(OpSize, Offset, true);
  EVT VT = IsPPC64 ? MVT::i64 : MVT::i32;
  SDValue FIN = DAG.getFrameIndex(FI, VT);
  TailCallArgumentInfo Info;
  Info.Arg = Arg;
  Info.FrameIdxOp = FIN;
  Info.FrameIdx = FI;
  TailCallArguments.push_back(Info);
}

/// EmitTCFPAndRetAddrLoad - Emit load from frame pointer and return address
/// stack slot. Returns the chain as result and the loaded frame pointers in
/// LROpOut/FPOpout. Used when tail calling.
SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
    SelectionDAG &DAG, int SPDiff, SDValue Chain, SDValue &LROpOut,
    SDValue &FPOpOut, const SDLoc &dl) const {
  if (SPDiff) {
    // Load the LR and FP stack slot for later adjusting.
    LROpOut = getReturnAddrFrameIndex(DAG);
    LROpOut = DAG.getLoad(Subtarget.getScalarIntVT(), dl, Chain, LROpOut,
                          MachinePointerInfo());
    Chain = SDValue(LROpOut.getNode(), 1);
  }
  return Chain;
}

/// CreateCopyOfByValArgument - Make a copy of an aggregate at address specified
/// by "Src" to address "Dst" of size "Size".  Alignment information is
/// specified by the specific parameter attribute. The copy will be passed as
/// a byval function parameter.
/// Sometimes what we are copying is the end of a larger object, the part that
/// does not fit in registers.
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst,
                                         SDValue Chain, ISD::ArgFlagsTy Flags,
                                         SelectionDAG &DAG, const SDLoc &dl) {
  SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), dl, MVT::i32);
  return DAG.getMemcpy(
      Chain, dl, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(), false, false,
      /*CI=*/nullptr, std::nullopt, MachinePointerInfo(), MachinePointerInfo());
}

/// LowerMemOpCallTo - Store the argument to the stack or remember it in case of
/// tail calls.
static void LowerMemOpCallTo(
    SelectionDAG &DAG, MachineFunction &MF, SDValue Chain, SDValue Arg,
    SDValue PtrOff, int SPDiff, unsigned ArgOffset, bool isPPC64,
    bool isTailCall, bool isVector, SmallVectorImpl<SDValue> &MemOpChains,
    SmallVectorImpl<TailCallArgumentInfo> &TailCallArguments, const SDLoc &dl) {
  EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout());
  if (!isTailCall) {
    if (isVector) {
      SDValue StackPtr;
      if (isPPC64)
        StackPtr = DAG.getRegister(PPC::X1, MVT::i64);
      else
        StackPtr = DAG.getRegister(PPC::R1, MVT::i32);
      PtrOff = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr,
                           DAG.getConstant(ArgOffset, dl, PtrVT));
    }
    MemOpChains.push_back(
        DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
    // Calculate and remember argument location.
  } else
    CalculateTailCallArgDest(DAG, MF, isPPC64, Arg, SPDiff, ArgOffset,
                             TailCallArguments);
}

static void
PrepareTailCall(SelectionDAG &DAG, SDValue &InGlue, SDValue &Chain,
                const SDLoc &dl, int SPDiff, unsigned NumBytes, SDValue LROp,
                SDValue FPOp,
                SmallVectorImpl<TailCallArgumentInfo> &TailCallArguments) {
  // Emit a sequence of copyto/copyfrom virtual registers for arguments that
  // might overwrite each other in case of tail call optimization.
  SmallVector<SDValue, 8> MemOpChains2;
  // Do not flag preceding copytoreg stuff together with the following stuff.
  InGlue = SDValue();
  StoreTailCallArgumentsToStackSlot(DAG, Chain, TailCallArguments,
                                    MemOpChains2, dl);
  if (!MemOpChains2.empty())
    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains2);

  // Store the return address to the appropriate stack slot.
  Chain = EmitTailCallStoreFPAndRetAddr(DAG, Chain, LROp, FPOp, SPDiff, dl);

  // Emit callseq_end just before tailcall node.
  Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, InGlue, dl);
  InGlue = Chain.getValue(1);
}

// Is this global address that of a function that can be called by name? (as
// opposed to something that must hold a descriptor for an indirect call).
static bool isFunctionGlobalAddress(const GlobalValue *GV) {
  if (GV) {
    if (GV->isThreadLocal())
      return false;

    return GV->getValueType()->isFunctionTy();
  }

  return false;
}

SDValue PPCTargetLowering::LowerCallResult(
    SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool isVarArg,
    const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
    SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
  SmallVector<CCValAssign, 16> RVLocs;
  CCState CCRetInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
                    *DAG.getContext());

  CCRetInfo.AnalyzeCallResult(
      Ins, (Subtarget.isSVR4ABI() && CallConv == CallingConv::Cold)
               ? RetCC_PPC_Cold
               : RetCC_PPC);

  // Copy all of the result registers out of their specified physreg.
  for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
    CCValAssign &VA = RVLocs[i];
    assert(VA.isRegLoc() && "Can only return in registers!");

    SDValue Val;

    if (Subtarget.hasSPE() && VA.getLocVT() == MVT::f64) {
      SDValue Lo = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32,
                                      InGlue);
      Chain = Lo.getValue(1);
      InGlue = Lo.getValue(2);
      VA = RVLocs[++i]; // skip ahead to next loc
      SDValue Hi = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32,
                                      InGlue);
      Chain = Hi.getValue(1);
      InGlue = Hi.getValue(2);
      if (!Subtarget.isLittleEndian())
        std::swap (Lo, Hi);
      Val = DAG.getNode(PPCISD::BUILD_SPE64, dl, MVT::f64, Lo, Hi);
    } else {
      Val = DAG.getCopyFromReg(Chain, dl,
                               VA.getLocReg(), VA.getLocVT(), InGlue);
      Chain = Val.getValue(1);
      InGlue = Val.getValue(2);
    }

    switch (VA.getLocInfo()) {
    default: llvm_unreachable("Unknown loc info!");
    case CCValAssign::Full: break;
    case CCValAssign::AExt:
      Val = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), Val);
      break;
    case CCValAssign::ZExt:
      Val = DAG.getNode(ISD::AssertZext, dl, VA.getLocVT(), Val,
                        DAG.getValueType(VA.getValVT()));
      Val = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), Val);
      break;
    case CCValAssign::SExt:
      Val = DAG.getNode(ISD::AssertSext, dl, VA.getLocVT(), Val,
                        DAG.getValueType(VA.getValVT()));
      Val = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), Val);
      break;
    }

    InVals.push_back(Val);
  }

  return Chain;
}

static bool isIndirectCall(const SDValue &Callee, SelectionDAG &DAG,
                           const PPCSubtarget &Subtarget, bool isPatchPoint) {
  auto *G = dyn_cast<GlobalAddressSDNode>(Callee);
  const GlobalValue *GV = G ? G->getGlobal() : nullptr;

  // PatchPoint calls are not indirect.
  if (isPatchPoint)
    return false;

  if (isFunctionGlobalAddress(GV) || isa<ExternalSymbolSDNode>(Callee))
    return false;

  // Darwin, and 32-bit ELF can use a BLA. The descriptor based ABIs can not
  // becuase the immediate function pointer points to a descriptor instead of
  // a function entry point. The ELFv2 ABI cannot use a BLA because the function
  // pointer immediate points to the global entry point, while the BLA would
  // need to jump to the local entry point (see rL211174).
  if (!Subtarget.usesFunctionDescriptors() && !Subtarget.isELFv2ABI() &&
      isBLACompatibleAddress(Callee, DAG))
    return false;

  return true;
}

// AIX and 64-bit ELF ABIs w/o PCRel require a TOC save/restore around calls.
static inline bool isTOCSaveRestoreRequired(const PPCSubtarget &Subtarget) {
  return Subtarget.isAIXABI() ||
         (Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls());
}

static unsigned getCallOpcode(PPCTargetLowering::CallFlags CFlags,
                              const Function &Caller, const SDValue &Callee,
                              const PPCSubtarget &Subtarget,
                              const TargetMachine &TM,
                              bool IsStrictFPCall = false) {
  if (CFlags.IsTailCall)
    return PPCISD::TC_RETURN;

  unsigned RetOpc = 0;
  // This is a call through a function pointer.
  if (CFlags.IsIndirect) {
    // AIX and the 64-bit ELF ABIs need to maintain the TOC pointer accross
    // indirect calls. The save of the caller's TOC pointer to the stack will be
    // inserted into the DAG as part of call lowering. The restore of the TOC
    // pointer is modeled by using a pseudo instruction for the call opcode that
    // represents the 2 instruction sequence of an indirect branch and link,
    // immediately followed by a load of the TOC pointer from the stack save
    // slot into gpr2. For 64-bit ELFv2 ABI with PCRel, do not restore the TOC
    // as it is not saved or used.
    RetOpc = isTOCSaveRestoreRequired(Subtarget) ? PPCISD::BCTRL_LOAD_TOC
                                                 : PPCISD::BCTRL;
  } else if (Subtarget.isUsingPCRelativeCalls()) {
    assert(Subtarget.is64BitELFABI() && "PC Relative is only on ELF ABI.");
    RetOpc = PPCISD::CALL_NOTOC;
  } else if (Subtarget.isAIXABI() || Subtarget.is64BitELFABI()) {
    // The ABIs that maintain a TOC pointer accross calls need to have a nop
    // immediately following the call instruction if the caller and callee may
    // have different TOC bases. At link time if the linker determines the calls
    // may not share a TOC base, the call is redirected to a trampoline inserted
    // by the linker. The trampoline will (among other things) save the callers
    // TOC pointer at an ABI designated offset in the linkage area and the
    // linker will rewrite the nop to be a load of the TOC pointer from the
    // linkage area into gpr2.
    auto *G = dyn_cast<GlobalAddressSDNode>(Callee);
    const GlobalValue *GV = G ? G->getGlobal() : nullptr;
    RetOpc =
        callsShareTOCBase(&Caller, GV, TM) ? PPCISD::CALL : PPCISD::CALL_NOP;
  } else
    RetOpc = PPCISD::CALL;
  if (IsStrictFPCall) {
    switch (RetOpc) {
    default:
      llvm_unreachable("Unknown call opcode");
    case PPCISD::BCTRL_LOAD_TOC:
      RetOpc = PPCISD::BCTRL_LOAD_TOC_RM;
      break;
    case PPCISD::BCTRL:
      RetOpc = PPCISD::BCTRL_RM;
      break;
    case PPCISD::CALL_NOTOC:
      RetOpc = PPCISD::CALL_NOTOC_RM;
      break;
    case PPCISD::CALL:
      RetOpc = PPCISD::CALL_RM;
      break;
    case PPCISD::CALL_NOP:
      RetOpc = PPCISD::CALL_NOP_RM;
      break;
    }
  }
  return RetOpc;
}

static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG,
                               const SDLoc &dl, const PPCSubtarget &Subtarget) {
  if (!Subtarget.usesFunctionDescriptors() && !Subtarget.isELFv2ABI())
    if (SDNode *Dest = isBLACompatibleAddress(Callee, DAG))
      return SDValue(Dest, 0);

  // Returns true if the callee is local, and false otherwise.
  auto isLocalCallee = [&]() {
    const GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee);
    const GlobalValue *GV = G ? G->getGlobal() : nullptr;

    return DAG.getTarget().shouldAssumeDSOLocal(GV) &&
           !isa_and_nonnull<GlobalIFunc>(GV);
  };

  // The PLT is only used in 32-bit ELF PIC mode.  Attempting to use the PLT in
  // a static relocation model causes some versions of GNU LD (2.17.50, at
  // least) to force BSS-PLT, instead of secure-PLT, even if all objects are
  // built with secure-PLT.
  bool UsePlt =
      Subtarget.is32BitELFABI() && !isLocalCallee() &&
      Subtarget.getTargetMachine().getRelocationModel() == Reloc::PIC_;

  const auto getAIXFuncEntryPointSymbolSDNode = [&](const GlobalValue *GV) {
    const TargetMachine &TM = Subtarget.getTargetMachine();
    const TargetLoweringObjectFile *TLOF = TM.getObjFileLowering();
    auto *S =
        static_cast<MCSymbolXCOFF *>(TLOF->getFunctionEntryPointSymbol(GV, TM));

    MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout());
    return DAG.getMCSymbol(S, PtrVT);
  };

  auto *G = dyn_cast<GlobalAddressSDNode>(Callee);
  const GlobalValue *GV = G ? G->getGlobal() : nullptr;
  if (isFunctionGlobalAddress(GV)) {
    const GlobalValue *GV = cast<GlobalAddressSDNode>(Callee)->getGlobal();

    if (Subtarget.isAIXABI()) {
      assert(!isa<GlobalIFunc>(GV) && "IFunc is not supported on AIX.");
      return getAIXFuncEntryPointSymbolSDNode(GV);
    }
    return DAG.getTargetGlobalAddress(GV, dl, Callee.getValueType(), 0,
                                      UsePlt ? PPCII::MO_PLT : 0);
  }

  if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
    const char *SymName = S->getSymbol();
    if (Subtarget.isAIXABI()) {
      // If there exists a user-declared function whose name is the same as the
      // ExternalSymbol's, then we pick up the user-declared version.
      const Module *Mod = DAG.getMachineFunction().getFunction().getParent();
      if (const Function *F =
              dyn_cast_or_null<Function>(Mod->getNamedValue(SymName)))
        return getAIXFuncEntryPointSymbolSDNode(F);

      // On AIX, direct function calls reference the symbol for the function's
      // entry point, which is named by prepending a "." before the function's
      // C-linkage name. A Qualname is returned here because an external
      // function entry point is a csect with XTY_ER property.
      const auto getExternalFunctionEntryPointSymbol = [&](StringRef SymName) {
        auto &Context = DAG.getMachineFunction().getContext();
        MCSectionXCOFF *Sec = Context.getXCOFFSection(
            (Twine(".") + Twine(SymName)).str(), SectionKind::getMetadata(),
            XCOFF::CsectProperties(XCOFF::XMC_PR, XCOFF::XTY_ER));
        return Sec->getQualNameSymbol();
      };

      SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
    }
    return DAG.getTargetExternalSymbol(SymName, Callee.getValueType(),
                                       UsePlt ? PPCII::MO_PLT : 0);
  }

  // No transformation needed.
  assert(Callee.getNode() && "What no callee?");
  return Callee;
}

static SDValue getOutputChainFromCallSeq(SDValue CallSeqStart) {
  assert(CallSeqStart.getOpcode() == ISD::CALLSEQ_START &&
         "Expected a CALLSEQ_STARTSDNode.");

  // The last operand is the chain, except when the node has glue. If the node
  // has glue, then the last operand is the glue, and the chain is the second
  // last operand.
  SDValue LastValue = CallSeqStart.getValue(CallSeqStart->getNumValues() - 1);
  if (LastValue.getValueType() != MVT::Glue)
    return LastValue;

  return CallSeqStart.getValue(CallSeqStart->getNumValues() - 2);
}

// Creates the node that moves a functions address into the count register
// to prepare for an indirect call instruction.
static void prepareIndirectCall(SelectionDAG &DAG, SDValue &Callee,
                                SDValue &Glue, SDValue &Chain,
                                const SDLoc &dl) {
  SDValue MTCTROps[] = {Chain, Callee, Glue};
  EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
  Chain = DAG.getNode(PPCISD::MTCTR, dl, ReturnTypes,
                      ArrayRef(MTCTROps, Glue.getNode() ? 3 : 2));
  // The glue is the second value produced.
  Glue = Chain.getValue(1);
}

static void prepareDescriptorIndirectCall(SelectionDAG &DAG, SDValue &Callee,
                                          SDValue &Glue, SDValue &Chain,
                                          SDValue CallSeqStart,
                                          const CallBase *CB, const SDLoc &dl,
                                          bool hasNest,
                                          const PPCSubtarget &Subtarget) {
  // Function pointers in the 64-bit SVR4 ABI do not point to the function
  // entry point, but to the function descriptor (the function entry point
  // address is part of the function descriptor though).
  // The function descriptor is a three doubleword structure with the
  // following fields: function entry point, TOC base address and
  // environment pointer.
  // Thus for a call through a function pointer, the following actions need
  // to be performed:
  //   1. Save the TOC of the caller in the TOC save area of its stack
  //      frame (this is done in LowerCall_Darwin() or LowerCall_64SVR4()).
  //   2. Load the address of the function entry point from the function
  //      descriptor.
  //   3. Load the TOC of the callee from the function descriptor into r2.
  //   4. Load the environment pointer from the function descriptor into
  //      r11.
  //   5. Branch to the function entry point address.
  //   6. On return of the callee, the TOC of the caller needs to be
  //      restored (this is done in FinishCall()).
  //
  // The loads are scheduled at the beginning of the call sequence, and the
  // register copies are flagged together to ensure that no other
  // operations can be scheduled in between. E.g. without flagging the
  // copies together, a TOC access in the caller could be scheduled between
  // the assignment of the callee TOC and the branch to the callee, which leads
  // to incorrect code.

  // Start by loading the function address from the descriptor.
  SDValue LDChain = getOutputChainFromCallSeq(CallSeqStart);
  auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
                      ? (MachineMemOperand::MODereferenceable |
                         MachineMemOperand::MOInvariant)
                      : MachineMemOperand::MONone;

  MachinePointerInfo MPI(CB ? CB->getCalledOperand() : nullptr);

  // Registers used in building the DAG.
  const MCRegister EnvPtrReg = Subtarget.getEnvironmentPointerRegister();
  const MCRegister TOCReg = Subtarget.getTOCPointerRegister();

  // Offsets of descriptor members.
  const unsigned TOCAnchorOffset = Subtarget.descriptorTOCAnchorOffset();
  const unsigned EnvPtrOffset = Subtarget.descriptorEnvironmentPointerOffset();

  const MVT RegVT = Subtarget.getScalarIntVT();
  const Align Alignment = Subtarget.isPPC64() ? Align(8) : Align(4);

  // One load for the functions entry point address.
  SDValue LoadFuncPtr = DAG.getLoad(RegVT, dl, LDChain, Callee, MPI,
                                    Alignment, MMOFlags);

  // One for loading the TOC anchor for the module that contains the called
  // function.
  SDValue TOCOff = DAG.getIntPtrConstant(TOCAnchorOffset, dl);
  SDValue AddTOC = DAG.getNode(ISD::ADD, dl, RegVT, Callee, TOCOff);
  SDValue TOCPtr =
      DAG.getLoad(RegVT, dl, LDChain, AddTOC,
                  MPI.getWithOffset(TOCAnchorOffset), Alignment, MMOFlags);

  // One for loading the environment pointer.
  SDValue PtrOff = DAG.getIntPtrConstant(EnvPtrOffset, dl);
  SDValue AddPtr = DAG.getNode(ISD::ADD, dl, RegVT, Callee, PtrOff);
  SDValue LoadEnvPtr =
      DAG.getLoad(RegVT, dl, LDChain, AddPtr,
                  MPI.getWithOffset(EnvPtrOffset), Alignment, MMOFlags);


  // Then copy the newly loaded TOC anchor to the TOC pointer.
  SDValue TOCVal = DAG.getCopyToReg(Chain, dl, TOCReg, TOCPtr, Glue);
  Chain = TOCVal.getValue(0);
  Glue = TOCVal.getValue(1);

  // If the function call has an explicit 'nest' parameter, it takes the
  // place of the environment pointer.
  assert((!hasNest || !Subtarget.isAIXABI()) &&
         "Nest parameter is not supported on AIX.");
  if (!hasNest) {
    SDValue EnvVal = DAG.getCopyToReg(Chain, dl, EnvPtrReg, LoadEnvPtr, Glue);
    Chain = EnvVal.getValue(0);
    Glue = EnvVal.getValue(1);
  }

  // The rest of the indirect call sequence is the same as the non-descriptor
  // DAG.
  prepareIndirectCall(DAG, LoadFuncPtr, Glue, Chain, dl);
}

static void
buildCallOperands(SmallVectorImpl<SDValue> &Ops,
                  PPCTargetLowering::CallFlags CFlags, const SDLoc &dl,
                  SelectionDAG &DAG,
                  SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
                  SDValue Glue, SDValue Chain, SDValue &Callee, int SPDiff,
                  const PPCSubtarget &Subtarget) {
  const bool IsPPC64 = Subtarget.isPPC64();
  // MVT for a general purpose register.
  const MVT RegVT = Subtarget.getScalarIntVT();

  // First operand is always the chain.
  Ops.push_back(Chain);

  // If it's a direct call pass the callee as the second operand.
  if (!CFlags.IsIndirect)
    Ops.push_back(Callee);
  else {
    assert(!CFlags.IsPatchPoint && "Patch point calls are not indirect.");

    // For the TOC based ABIs, we have saved the TOC pointer to the linkage area
    // on the stack (this would have been done in `LowerCall_64SVR4` or
    // `LowerCall_AIX`). The call instruction is a pseudo instruction that
    // represents both the indirect branch and a load that restores the TOC
    // pointer from the linkage area. The operand for the TOC restore is an add
    // of the TOC save offset to the stack pointer. This must be the second
    // operand: after the chain input but before any other variadic arguments.
    // For 64-bit ELFv2 ABI with PCRel, do not restore the TOC as it is not
    // saved or used.
    if (isTOCSaveRestoreRequired(Subtarget)) {
      const MCRegister StackPtrReg = Subtarget.getStackPointerRegister();

      SDValue StackPtr = DAG.getRegister(StackPtrReg, RegVT);
      unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
      SDValue TOCOff = DAG.getIntPtrConstant(TOCSaveOffset, dl);
      SDValue AddTOC = DAG.getNode(ISD::ADD, dl, RegVT, StackPtr, TOCOff);
      Ops.push_back(AddTOC);
    }

    // Add the register used for the environment pointer.
    if (Subtarget.usesFunctionDescriptors() && !CFlags.HasNest)
      Ops.push_back(DAG.getRegister(Subtarget.getEnvironmentPointerRegister(),
                                    RegVT));


    // Add CTR register as callee so a bctr can be emitted later.
    if (CFlags.IsTailCall)
      Ops.push_back(DAG.getRegister(IsPPC64 ? PPC::CTR8 : PPC::CTR, RegVT));
  }

  // If this is a tail call add stack pointer delta.
  if (CFlags.IsTailCall)
    Ops.push_back(DAG.getConstant(SPDiff, dl, MVT::i32));

  // Add argument registers to the end of the list so that they are known live
  // into the call.
  for (const auto &[Reg, N] : RegsToPass)
    Ops.push_back(DAG.getRegister(Reg, N.getValueType()));

  // We cannot add R2/X2 as an operand here for PATCHPOINT, because there is
  // no way to mark dependencies as implicit here.
  // We will add the R2/X2 dependency in EmitInstrWithCustomInserter.
  if ((Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) &&
       !CFlags.IsPatchPoint && !Subtarget.isUsingPCRelativeCalls())
    Ops.push_back(DAG.getRegister(Subtarget.getTOCPointerRegister(), RegVT));

  // Add implicit use of CR bit 6 for 32-bit SVR4 vararg calls
  if (CFlags.IsVarArg && Subtarget.is32BitELFABI())
    Ops.push_back(DAG.getRegister(PPC::CR1EQ, MVT::i32));

  // Add a register mask operand representing the call-preserved registers.
  const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
  const uint32_t *Mask =
      TRI->getCallPreservedMask(DAG.getMachineFunction(), CFlags.CallConv);
  assert(Mask && "Missing call preserved mask for calling convention");
  Ops.push_back(DAG.getRegisterMask(Mask));

  // If the glue is valid, it is the last operand.
  if (Glue.getNode())
    Ops.push_back(Glue);
}

SDValue PPCTargetLowering::FinishCall(
    CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG,
    SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass, SDValue Glue,
    SDValue Chain, SDValue CallSeqStart, SDValue &Callee, int SPDiff,
    unsigned NumBytes, const SmallVectorImpl<ISD::InputArg> &Ins,
    SmallVectorImpl<SDValue> &InVals, const CallBase *CB) const {

  if ((Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls()) ||
      Subtarget.isAIXABI())
    setUsesTOCBasePtr(DAG);

  unsigned CallOpc =
      getCallOpcode(CFlags, DAG.getMachineFunction().getFunction(), Callee,
                    Subtarget, DAG.getTarget(), CB ? CB->isStrictFP() : false);

  if (!CFlags.IsIndirect)
    Callee = transformCallee(Callee, DAG, dl, Subtarget);
  else if (Subtarget.usesFunctionDescriptors())
    prepareDescriptorIndirectCall(DAG, Callee, Glue, Chain, CallSeqStart, CB,
                                  dl, CFlags.HasNest, Subtarget);
  else
    prepareIndirectCall(DAG, Callee, Glue, Chain, dl);

  // Build the operand list for the call instruction.
  SmallVector<SDValue, 8> Ops;
  buildCallOperands(Ops, CFlags, dl, DAG, RegsToPass, Glue, Chain, Callee,
                    SPDiff, Subtarget);

  // Emit tail call.
  if (CFlags.IsTailCall) {
    // Indirect tail call when using PC Relative calls do not have the same
    // constraints.
    assert(((Callee.getOpcode() == ISD::Register &&
             cast<RegisterSDNode>(Callee)->getReg() == PPC::CTR) ||
            Callee.getOpcode() == ISD::TargetExternalSymbol ||
            Callee.getOpcode() == ISD::TargetGlobalAddress ||
            isa<ConstantSDNode>(Callee) ||
            (CFlags.IsIndirect && Subtarget.isUsingPCRelativeCalls())) &&
           "Expecting a global address, external symbol, absolute value, "
           "register or an indirect tail call when PC Relative calls are "
           "used.");
    // PC Relative calls also use TC_RETURN as the way to mark tail calls.
    assert(CallOpc == PPCISD::TC_RETURN &&
           "Unexpected call opcode for a tail call.");
    DAG.getMachineFunction().getFrameInfo().setHasTailCall();
    SDValue Ret = DAG.getNode(CallOpc, dl, MVT::Other, Ops);
    DAG.addNoMergeSiteInfo(Ret.getNode(), CFlags.NoMerge);
    return Ret;
  }

  std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
  Chain = DAG.getNode(CallOpc, dl, ReturnTypes, Ops);
  DAG.addNoMergeSiteInfo(Chain.getNode(), CFlags.NoMerge);
  Glue = Chain.getValue(1);

  // When performing tail call optimization the callee pops its arguments off
  // the stack. Account for this here so these bytes can be pushed back on in
  // PPCFrameLowering::eliminateCallFramePseudoInstr.
  int BytesCalleePops = (CFlags.CallConv == CallingConv::Fast &&
                         getTargetMachine().Options.GuaranteedTailCallOpt)
                            ? NumBytes
                            : 0;

  Chain = DAG.getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
  Glue = Chain.getValue(1);

  return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
                         DAG, InVals);
}

bool PPCTargetLowering::supportsTailCallFor(const CallBase *CB) const {
  CallingConv::ID CalleeCC = CB->getCallingConv();
  const Function *CallerFunc = CB->getCaller();
  CallingConv::ID CallerCC = CallerFunc->getCallingConv();
  const Function *CalleeFunc = CB->getCalledFunction();
  if (!CalleeFunc)
    return false;
  const GlobalValue *CalleeGV = dyn_cast<GlobalValue>(CalleeFunc);

  SmallVector<ISD::OutputArg, 2> Outs;
  SmallVector<ISD::InputArg, 2> Ins;

  GetReturnInfo(CalleeCC, CalleeFunc->getReturnType(),
                CalleeFunc->getAttributes(), Outs, *this,
                CalleeFunc->getDataLayout());

  return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
                          CalleeFunc->isVarArg(), Outs, Ins, CallerFunc,
                          false /*isCalleeExternalSymbol*/);
}

bool PPCTargetLowering::isEligibleForTCO(
    const GlobalValue *CalleeGV, CallingConv::ID CalleeCC,
    CallingConv::ID CallerCC, const CallBase *CB, bool isVarArg,
    const SmallVectorImpl<ISD::OutputArg> &Outs,
    const SmallVectorImpl<ISD::InputArg> &Ins, const Function *CallerFunc,
    bool isCalleeExternalSymbol) const {
  if (Subtarget.useLongCalls() && !(CB && CB->isMustTailCall()))
    return false;

  if (Subtarget.isSVR4ABI() && Subtarget.isPPC64())
    return IsEligibleForTailCallOptimization_64SVR4(
        CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
        isCalleeExternalSymbol);
  else
    return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
                                             isVarArg, Ins);
}

SDValue
PPCTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
                             SmallVectorImpl<SDValue> &InVals) const {
  SelectionDAG &DAG                     = CLI.DAG;
  SDLoc &dl                             = CLI.DL;
  SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
  SmallVectorImpl<SDValue> &OutVals     = CLI.OutVals;
  SmallVectorImpl<ISD::InputArg> &Ins   = CLI.Ins;
  SDValue Chain                         = CLI.Chain;
  SDValue Callee                        = CLI.Callee;
  bool &isTailCall                      = CLI.IsTailCall;
  CallingConv::ID CallConv              = CLI.CallConv;
  bool isVarArg                         = CLI.IsVarArg;
  bool isPatchPoint                     = CLI.IsPatchPoint;
  const CallBase *CB                    = CLI.CB;

  if (isTailCall) {
    MachineFunction &MF = DAG.getMachineFunction();
    CallingConv::ID CallerCC = MF.getFunction().getCallingConv();
    auto *G = dyn_cast<GlobalAddressSDNode>(Callee);
    const GlobalValue *GV = G ? G->getGlobal() : nullptr;
    bool IsCalleeExternalSymbol = isa<ExternalSymbolSDNode>(Callee);

    isTailCall =
        isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
                         &(MF.getFunction()), IsCalleeExternalSymbol);
    if (isTailCall) {
      ++NumTailCalls;
      if (!getTargetMachine().Options.GuaranteedTailCallOpt)
        ++NumSiblingCalls;

      // PC Relative calls no longer guarantee that the callee is a Global
      // Address Node. The callee could be an indirect tail call in which
      // case the SDValue for the callee could be a load (to load the address
      // of a function pointer) or it may be a register copy (to move the
      // address of the callee from a function parameter into a virtual
      // register). It may also be an ExternalSymbolSDNode (ex memcopy).
      assert((Subtarget.isUsingPCRelativeCalls() ||
              isa<GlobalAddressSDNode>(Callee)) &&
             "Callee should be an llvm::Function object.");

      LLVM_DEBUG(dbgs() << "TCO caller: " << DAG.getMachineFunction().getName()
                        << "\nTCO callee: ");
      LLVM_DEBUG(Callee.dump());
    }
  }

  if (!isTailCall && CB && CB->isMustTailCall())
    report_fatal_error("failed to perform tail call elimination on a call "
                       "site marked musttail");

  // When long calls (i.e. indirect calls) are always used, calls are always
  // made via function pointer. If we have a function name, first translate it
  // into a pointer.
  if (Subtarget.useLongCalls() && isa<GlobalAddressSDNode>(Callee) &&
      !isTailCall)
    Callee = LowerGlobalAddress(Callee, DAG);

  CallFlags CFlags(
      CallConv, isTailCall, isVarArg, isPatchPoint,
      isIndirectCall(Callee, DAG, Subtarget, isPatchPoint),
      // hasNest
      Subtarget.is64BitELFABI() &&
          any_of(Outs, [](ISD::OutputArg Arg) { return Arg.Flags.isNest(); }),
      CLI.NoMerge);

  if (Subtarget.isAIXABI())
    return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
                         InVals, CB);

  assert(Subtarget.isSVR4ABI());
  if (Subtarget.isPPC64())
    return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
                            InVals, CB);
  return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
                          InVals, CB);
}

SDValue PPCTargetLowering::LowerCall_32SVR4(
    SDValue Chain, SDValue Callee, CallFlags CFlags,
    const SmallVectorImpl<ISD::OutputArg> &Outs,
    const SmallVectorImpl<SDValue> &OutVals,
    const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
    SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
    const CallBase *CB) const {
  // See PPCTargetLowering::LowerFormalArguments_32SVR4() for a description
  // of the 32-bit SVR4 ABI stack frame layout.

  const CallingConv::ID CallConv = CFlags.CallConv;
  const bool IsVarArg = CFlags.IsVarArg;
  const bool IsTailCall = CFlags.IsTailCall;

  assert((CallConv == CallingConv::C ||
          CallConv == CallingConv::Cold ||
          CallConv == CallingConv::Fast) && "Unknown calling convention!");

  const Align PtrAlign(4);

  MachineFunction &MF = DAG.getMachineFunction();

  // Mark this function as potentially containing a function that contains a
  // tail call. As a consequence the frame pointer will be used for dynamicalloc
  // and restoring the callers stack pointer in this functions epilog. This is
  // done because by tail calling the called function might overwrite the value
  // in this function's (MF) stack pointer stack slot 0(SP).
  if (getTargetMachine().Options.GuaranteedTailCallOpt &&
      CallConv == CallingConv::Fast)
    MF.getInfo<PPCFunctionInfo>()->setHasFastCall();

  // Count how many bytes are to be pushed on the stack, including the linkage
  // area, parameter list area and the part of the local variable space which
  // contains copies of aggregates which are passed by value.

  // Assign locations to all of the outgoing arguments.
  SmallVector<CCValAssign, 16> ArgLocs;
  CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());

  // Reserve space for the linkage area on the stack.
  CCInfo.AllocateStack(Subtarget.getFrameLowering()->getLinkageSize(),
                       PtrAlign);

  if (IsVarArg) {
    // Handle fixed and variable vector arguments differently.
    // Fixed vector arguments go into registers as long as registers are
    // available. Variable vector arguments always go into memory.
    unsigned NumArgs = Outs.size();

    for (unsigned i = 0; i != NumArgs; ++i) {
      MVT ArgVT = Outs[i].VT;
      ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
      bool Result;

      if (!ArgFlags.isVarArg()) {
        Result = CC_PPC32_SVR4(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags,
                               Outs[i].OrigTy, CCInfo);
      } else {
        Result = CC_PPC32_SVR4_VarArg(i, ArgVT, ArgVT, CCValAssign::Full,
                                      ArgFlags, Outs[i].OrigTy, CCInfo);
      }

      if (Result) {
#ifndef NDEBUG
        errs() << "Call operand #" << i << " has unhandled type "
               << ArgVT << "\n";
#endif
        llvm_unreachable(nullptr);
      }
    }
  } else {
    // All arguments are treated the same.
    CCInfo.AnalyzeCallOperands(Outs, CC_PPC32_SVR4);
  }

  // Assign locations to all of the outgoing aggregate by value arguments.
  SmallVector<CCValAssign, 16> ByValArgLocs;
  CCState CCByValInfo(CallConv, IsVarArg, MF, ByValArgLocs, *DAG.getContext());

  // Reserve stack space for the allocations in CCInfo.
  CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);

  CCByValInfo.AnalyzeCallOperands(Outs, CC_PPC32_SVR4_ByVal);

  // Size of the linkage area, parameter list area and the part of the local
  // space variable where copies of aggregates which are passed by value are
  // stored.
  unsigned NumBytes = CCByValInfo.getStackSize();

  // Calculate by how many bytes the stack has to be adjusted in case of tail
  // call optimization.
  int SPDiff = CalculateTailCallSPDiff(DAG, IsTailCall, NumBytes);

  // Adjust the stack pointer for the new arguments...
  // These operations are automatically eliminated by the prolog/epilog pass
  Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, dl);
  SDValue CallSeqStart = Chain;

  // Load the return address and frame pointer so it can be moved somewhere else
  // later.
  SDValue LROp, FPOp;
  Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);

  // Set up a copy of the stack pointer for use loading and storing any
  // arguments that may not fit in the registers available for argument
  // passing.
  SDValue StackPtr = DAG.getRegister(PPC::R1, MVT::i32);

  SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass;
  SmallVector<TailCallArgumentInfo, 8> TailCallArguments;
  SmallVector<SDValue, 8> MemOpChains;

  bool seenFloatArg = false;
  // Walk the register/memloc assignments, inserting copies/loads.
  // i - Tracks the index into the list of registers allocated for the call
  // RealArgIdx - Tracks the index into the list of actual function arguments
  // j - Tracks the index into the list of byval arguments
  for (unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.size();
       i != e;
       ++i, ++RealArgIdx) {
    CCValAssign &VA = ArgLocs[i];
    SDValue Arg = OutVals[RealArgIdx];
    ISD::ArgFlagsTy Flags = Outs[RealArgIdx].Flags;

    if (Flags.isByVal()) {
      // Argument is an aggregate which is passed by value, thus we need to
      // create a copy of it in the local variable space of the current stack
      // frame (which is the stack frame of the caller) and pass the address of
      // this copy to the callee.
      assert((j < ByValArgLocs.size()) && "Index out of bounds!");
      CCValAssign &ByValVA = ByValArgLocs[j++];
      assert((VA.getValNo() == ByValVA.getValNo()) && "ValNo mismatch!");

      // Memory reserved in the local variable space of the callers stack frame.
      unsigned LocMemOffset = ByValVA.getLocMemOffset();

      SDValue PtrOff = DAG.getIntPtrConstant(LocMemOffset, dl);
      PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(MF.getDataLayout()),
                           StackPtr, PtrOff);

      // Create a copy of the argument in the local area of the current
      // stack frame.
      SDValue MemcpyCall =
        CreateCopyOfByValArgument(Arg, PtrOff,
                                  CallSeqStart.getNode()->getOperand(0),
                                  Flags, DAG, dl);

      // This must go outside the CALLSEQ_START..END.
      SDValue NewCallSeqStart = DAG.getCALLSEQ_START(MemcpyCall, NumBytes, 0,
                                                     SDLoc(MemcpyCall));
      DAG.ReplaceAllUsesWith(CallSeqStart.getNode(),
                             NewCallSeqStart.getNode());
      Chain = CallSeqStart = NewCallSeqStart;

      // Pass the address of the aggregate copy on the stack either in a
      // physical register or in the parameter list area of the current stack
      // frame to the callee.
      Arg = PtrOff;
    }

    // When useCRBits() is true, there can be i1 arguments.
    // It is because getRegisterType(MVT::i1) => MVT::i1,
    // and for other integer types getRegisterType() => MVT::i32.
    // Extend i1 and ensure callee will get i32.
    if (Arg.getValueType() == MVT::i1)
      Arg = DAG.getNode(Flags.isSExt() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND,
                        dl, MVT::i32, Arg);

    if (VA.isRegLoc()) {
      seenFloatArg |= VA.getLocVT().isFloatingPoint();
      // Put argument in a physical register.
      if (Subtarget.hasSPE() && Arg.getValueType() == MVT::f64) {
        bool IsLE = Subtarget.isLittleEndian();
        SDValue SVal = DAG.getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
                        DAG.getIntPtrConstant(IsLE ? 0 : 1, dl));
        RegsToPass.push_back(std::make_pair(VA.getLocReg(), SVal.getValue(0)));
        SVal = DAG.getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
                           DAG.getIntPtrConstant(IsLE ? 1 : 0, dl));
        RegsToPass.push_back(std::make_pair(ArgLocs[++i].getLocReg(),
                             SVal.getValue(0)));
      } else
        RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
    } else {
      // Put argument in the parameter list area of the current stack frame.
      assert(VA.isMemLoc());
      unsigned LocMemOffset = VA.getLocMemOffset();

      if (!IsTailCall) {
        SDValue PtrOff = DAG.getIntPtrConstant(LocMemOffset, dl);
        PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(MF.getDataLayout()),
                             StackPtr, PtrOff);

        MemOpChains.push_back(
            DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
      } else {
        // Calculate and remember argument location.
        CalculateTailCallArgDest(DAG, MF, false, Arg, SPDiff, LocMemOffset,
                                 TailCallArguments);
      }
    }
  }

  if (!MemOpChains.empty())
    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);

  // Build a sequence of copy-to-reg nodes chained together with token chain
  // and flag operands which copy the outgoing args into the appropriate regs.
  SDValue InGlue;
  for (const auto &[Reg, N] : RegsToPass) {
    Chain = DAG.getCopyToReg(Chain, dl, Reg, N, InGlue);
    InGlue = Chain.getValue(1);
  }

  // Set CR bit 6 to true if this is a vararg call with floating args passed in
  // registers.
  if (IsVarArg) {
    SDVTList VTs = DAG.getVTList(MVT::Other, MVT::Glue);
    SDValue Ops[] = { Chain, InGlue };

    Chain = DAG.getNode(seenFloatArg ? PPCISD::CR6SET : PPCISD::CR6UNSET, dl,
                        VTs, ArrayRef(Ops, InGlue.getNode() ? 2 : 1));

    InGlue = Chain.getValue(1);
  }

  if (IsTailCall)
    PrepareTailCall(DAG, InGlue, Chain, dl, SPDiff, NumBytes, LROp, FPOp,
                    TailCallArguments);

  return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
                    Callee, SPDiff, NumBytes, Ins, InVals, CB);
}

// Copy an argument into memory, being careful to do this outside the
// call sequence for the call to which the argument belongs.
SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
    SDValue Arg, SDValue PtrOff, SDValue CallSeqStart, ISD::ArgFlagsTy Flags,
    SelectionDAG &DAG, const SDLoc &dl) const {
  SDValue MemcpyCall = CreateCopyOfByValArgument(Arg, PtrOff,
                        CallSeqStart.getNode()->getOperand(0),
                        Flags, DAG, dl);
  // The MEMCPY must go outside the CALLSEQ_START..END.
  int64_t FrameSize = CallSeqStart.getConstantOperandVal(1);
  SDValue NewCallSeqStart = DAG.getCALLSEQ_START(MemcpyCall, FrameSize, 0,
                                                 SDLoc(MemcpyCall));
  DAG.ReplaceAllUsesWith(CallSeqStart.getNode(),
                         NewCallSeqStart.getNode());
  return NewCallSeqStart;
}

SDValue PPCTargetLowering::LowerCall_64SVR4(
    SDValue Chain, SDValue Callee, CallFlags CFlags,
    const SmallVectorImpl<ISD::OutputArg> &Outs,
    const SmallVectorImpl<SDValue> &OutVals,
    const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
    SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
    const CallBase *CB) const {
  bool isELFv2ABI = Subtarget.isELFv2ABI();
  bool isLittleEndian = Subtarget.isLittleEndian();
  unsigned NumOps = Outs.size();
  bool IsSibCall = false;
  bool IsFastCall = CFlags.CallConv == CallingConv::Fast;

  EVT PtrVT = getPointerTy(DAG.getDataLayout());
  unsigned PtrByteSize = 8;

  MachineFunction &MF = DAG.getMachineFunction();

  if (CFlags.IsTailCall && !getTargetMachine().Options.GuaranteedTailCallOpt)
    IsSibCall = true;

  // Mark this function as potentially containing a function that contains a
  // tail call. As a consequence the frame pointer will be used for dynamicalloc
  // and restoring the callers stack pointer in this functions epilog. This is
  // done because by tail calling the called function might overwrite the value
  // in this function's (MF) stack pointer stack slot 0(SP).
  if (getTargetMachine().Options.GuaranteedTailCallOpt && IsFastCall)
    MF.getInfo<PPCFunctionInfo>()->setHasFastCall();

  assert(!(IsFastCall && CFlags.IsVarArg) &&
         "fastcc not supported on varargs functions");

  // Count how many bytes are to be pushed on the stack, including the linkage
  // area, and parameter passing area.  On ELFv1, the linkage area is 48 bytes
  // reserved space for [SP][CR][LR][2 x unused][TOC]; on ELFv2, the linkage
  // area is 32 bytes reserved space for [SP][CR][LR][TOC].
  unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
  unsigned NumBytes = LinkageSize;
  unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;

  static const MCPhysReg GPR[] = {
    PPC::X3, PPC::X4, PPC::X5, PPC::X6,
    PPC::X7, PPC::X8, PPC::X9, PPC::X10,
  };
  static const MCPhysReg VR[] = {
    PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
    PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
  };

  const unsigned NumGPRs = std::size(GPR);
  const unsigned NumFPRs = useSoftFloat() ? 0 : 13;
  const unsigned NumVRs = std::size(VR);

  // On ELFv2, we can avoid allocating the parameter area if all the arguments
  // can be passed to the callee in registers.
  // For the fast calling convention, there is another check below.
  // Note: We should keep consistent with LowerFormalArguments_64SVR4()
  bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
  if (!HasParameterArea) {
    unsigned ParamAreaSize = NumGPRs * PtrByteSize;
    unsigned AvailableFPRs = NumFPRs;
    unsigned AvailableVRs = NumVRs;
    unsigned NumBytesTmp = NumBytes;
    for (unsigned i = 0; i != NumOps; ++i) {
      if (Outs[i].Flags.isNest()) continue;
      if (CalculateStackSlotUsed(Outs[i].VT, Outs[i].ArgVT, Outs[i].Flags,
                                 PtrByteSize, LinkageSize, ParamAreaSize,
                                 NumBytesTmp, AvailableFPRs, AvailableVRs))
        HasParameterArea = true;
    }
  }

  // When using the fast calling convention, we don't provide backing for
  // arguments that will be in registers.
  unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;

  // Avoid allocating parameter area for fastcc functions if all the arguments
  // can be passed in the registers.
  if (IsFastCall)
    HasParameterArea = false;

  // Add up all the space actually used.
  for (unsigned i = 0; i != NumOps; ++i) {
    ISD::ArgFlagsTy Flags = Outs[i].Flags;
    EVT ArgVT = Outs[i].VT;
    EVT OrigVT = Outs[i].ArgVT;

    if (Flags.isNest())
      continue;

    if (IsFastCall) {
      if (Flags.isByVal()) {
        NumGPRsUsed += (Flags.getByValSize()+7)/8;
        if (NumGPRsUsed > NumGPRs)
          HasParameterArea = true;
      } else {
        switch (ArgVT.getSimpleVT().SimpleTy) {
        default: llvm_unreachable("Unexpected ValueType for argument!");
        case MVT::i1:
        case MVT::i32:
        case MVT::i64:
          if (++NumGPRsUsed <= NumGPRs)
            continue;
          break;
        case MVT::v4i32:
        case MVT::v8i16:
        case MVT::v16i8:
        case MVT::v2f64:
        case MVT::v2i64:
        case MVT::v1i128:
        case MVT::f128:
          if (++NumVRsUsed <= NumVRs)
            continue;
          break;
        case MVT::v4f32:
          if (++NumVRsUsed <= NumVRs)
            continue;
          break;
        case MVT::f32:
        case MVT::f64:
          if (++NumFPRsUsed <= NumFPRs)
            continue;
          break;
        }
        HasParameterArea = true;
      }
    }

    /* Respect alignment of argument on the stack.  */
    auto Alignement =
        CalculateStackSlotAlignment(ArgVT, OrigVT, Flags, PtrByteSize);
    NumBytes = alignTo(NumBytes, Alignement);

    NumBytes += CalculateStackSlotSize(ArgVT, Flags, PtrByteSize);
    if (Flags.isInConsecutiveRegsLast())
      NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
  }

  unsigned NumBytesActuallyUsed = NumBytes;

  // In the old ELFv1 ABI,
  // the prolog code of the callee may store up to 8 GPR argument registers to
  // the stack, allowing va_start to index over them in memory if its varargs.
  // Because we cannot tell if this is needed on the caller side, we have to
  // conservatively assume that it is needed.  As such, make sure we have at
  // least enough stack space for the caller to store the 8 GPRs.
  // In the ELFv2 ABI, we allocate the parameter area iff a callee
  // really requires memory operands, e.g. a vararg function.
  if (HasParameterArea)
    NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
  else
    NumBytes = LinkageSize;

  // Tail call needs the stack to be aligned.
  if (getTargetMachine().Options.GuaranteedTailCallOpt && IsFastCall)
    NumBytes = EnsureStackAlignment(Subtarget.getFrameLowering(), NumBytes);

  int SPDiff = 0;

  // Calculate by how many bytes the stack has to be adjusted in case of tail
  // call optimization.
  if (!IsSibCall)
    SPDiff = CalculateTailCallSPDiff(DAG, CFlags.IsTailCall, NumBytes);

  // To protect arguments on the stack from being clobbered in a tail call,
  // force all the loads to happen before doing any other lowering.
  if (CFlags.IsTailCall)
    Chain = DAG.getStackArgumentTokenFactor(Chain);

  // Adjust the stack pointer for the new arguments...
  // These operations are automatically eliminated by the prolog/epilog pass
  if (!IsSibCall)
    Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, dl);
  SDValue CallSeqStart = Chain;

  // Load the return address and frame pointer so it can be move somewhere else
  // later.
  SDValue LROp, FPOp;
  Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);

  // Set up a copy of the stack pointer for use loading and storing any
  // arguments that may not fit in the registers available for argument
  // passing.
  SDValue StackPtr = DAG.getRegister(PPC::X1, MVT::i64);

  // Figure out which arguments are going to go in registers, and which in
  // memory.  Also, if this is a vararg function, floating point operations
  // must be stored to our stack, and loaded into integer regs as well, if
  // any integer regs are available for argument passing.
  unsigned ArgOffset = LinkageSize;

  SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass;
  SmallVector<TailCallArgumentInfo, 8> TailCallArguments;

  SmallVector<SDValue, 8> MemOpChains;
  for (unsigned i = 0; i != NumOps; ++i) {
    SDValue Arg = OutVals[i];
    ISD::ArgFlagsTy Flags = Outs[i].Flags;
    EVT ArgVT = Outs[i].VT;
    EVT OrigVT = Outs[i].ArgVT;

    // PtrOff will be used to store the current argument to the stack if a
    // register cannot be found for it.
    SDValue PtrOff;

    // We re-align the argument offset for each argument, except when using the
    // fast calling convention, when we need to make sure we do that only when
    // we'll actually use a stack slot.
    auto ComputePtrOff = [&]() {
      /* Respect alignment of argument on the stack.  */
      auto Alignment =
          CalculateStackSlotAlignment(ArgVT, OrigVT, Flags, PtrByteSize);
      ArgOffset = alignTo(ArgOffset, Alignment);

      PtrOff = DAG.getConstant(ArgOffset, dl, StackPtr.getValueType());

      PtrOff = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr, PtrOff);
    };

    if (!IsFastCall) {
      ComputePtrOff();

      /* Compute GPR index associated with argument offset.  */
      GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
      GPR_idx = std::min(GPR_idx, NumGPRs);
    }

    // Promote integers to 64-bit values.
    if (Arg.getValueType() == MVT::i32 || Arg.getValueType() == MVT::i1) {
      // FIXME: Should this use ANY_EXTEND if neither sext nor zext?
      unsigned ExtOp = Flags.isSExt() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
      Arg = DAG.getNode(ExtOp, dl, MVT::i64, Arg);
    }

    // FIXME memcpy is used way more than necessary.  Correctness first.
    // Note: "by value" is code for passing a structure by value, not
    // basic types.
    if (Flags.isByVal()) {
      // Note: Size includes alignment padding, so
      //   struct x { short a; char b; }
      // will have Size = 4.  With #pragma pack(1), it will have Size = 3.
      // These are the proper values we need for right-justifying the
      // aggregate in a parameter register.
      unsigned Size = Flags.getByValSize();

      // An empty aggregate parameter takes up no storage and no
      // registers.
      if (Size == 0)
        continue;

      if (IsFastCall)
        ComputePtrOff();

      // All aggregates smaller than 8 bytes must be passed right-justified.
      if (Size==1 || Size==2 || Size==4) {
        EVT VT = (Size==1) ? MVT::i8 : ((Size==2) ? MVT::i16 : MVT::i32);
        if (GPR_idx != NumGPRs) {
          SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, PtrVT, Chain, Arg,
                                        MachinePointerInfo(), VT);
          MemOpChains.push_back(Load.getValue(1));
          RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load));

          ArgOffset += PtrByteSize;
          continue;
        }
      }

      if (GPR_idx == NumGPRs && Size < 8) {
        SDValue AddPtr = PtrOff;
        if (!isLittleEndian) {
          SDValue Const = DAG.getConstant(PtrByteSize - Size, dl,
                                          PtrOff.getValueType());
          AddPtr = DAG.getNode(ISD::ADD, dl, PtrVT, PtrOff, Const);
        }
        Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
                                                          CallSeqStart,
                                                          Flags, DAG, dl);
        ArgOffset += PtrByteSize;
        continue;
      }
      // Copy the object to parameter save area if it can not be entirely passed 
      // by registers.
      // FIXME: we only need to copy the parts which need to be passed in
      // parameter save area. For the parts passed by registers, we don't need
      // to copy them to the stack although we need to allocate space for them
      // in parameter save area.
      if ((NumGPRs - GPR_idx) * PtrByteSize < Size)
        Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
                                                          CallSeqStart,
                                                          Flags, DAG, dl);

      // When a register is available, pass a small aggregate right-justified.
      if (Size < 8 && GPR_idx != NumGPRs) {
        // The easiest way to get this right-justified in a register
        // is to copy the structure into the rightmost portion of a
        // local variable slot, then load the whole slot into the
        // register.
        // FIXME: The memcpy seems to produce pretty awful code for
        // small aggregates, particularly for packed ones.
        // FIXME: It would be preferable to use the slot in the
        // parameter save area instead of a new local variable.
        SDValue AddPtr = PtrOff;
        if (!isLittleEndian) {
          SDValue Const = DAG.getConstant(8 - Size, dl, PtrOff.getValueType());
          AddPtr = DAG.getNode(ISD::ADD, dl, PtrVT, PtrOff, Const);
        }
        Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
                                                          CallSeqStart,
                                                          Flags, DAG, dl);

        // Load the slot into the register.
        SDValue Load =
            DAG.getLoad(PtrVT, dl, Chain, PtrOff, MachinePointerInfo());
        MemOpChains.push_back(Load.getValue(1));
        RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load));

        // Done with this argument.
        ArgOffset += PtrByteSize;
        continue;
      }

      // For aggregates larger than PtrByteSize, copy the pieces of the
      // object that fit into registers from the parameter save area.
      for (unsigned j=0; j<Size; j+=PtrByteSize) {
        SDValue Const = DAG.getConstant(j, dl, PtrOff.getValueType());
        SDValue AddArg = DAG.getNode(ISD::ADD, dl, PtrVT, Arg, Const);
        if (GPR_idx != NumGPRs) {
          unsigned LoadSizeInBits = std::min(PtrByteSize, (Size - j)) * 8;
          EVT ObjType = EVT::getIntegerVT(*DAG.getContext(), LoadSizeInBits);
          SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, PtrVT, Chain, AddArg,
                                        MachinePointerInfo(), ObjType);

          MemOpChains.push_back(Load.getValue(1));
          RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load));
          ArgOffset += PtrByteSize;
        } else {
          ArgOffset += ((Size - j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
          break;
        }
      }
      continue;
    }

    switch (Arg.getSimpleValueType().SimpleTy) {
    default: llvm_unreachable("Unexpected ValueType for argument!");
    case MVT::i1:
    case MVT::i32:
    case MVT::i64:
      if (Flags.isNest()) {
        // The 'nest' parameter, if any, is passed in R11.
        RegsToPass.push_back(std::make_pair(PPC::X11, Arg));
        break;
      }

      // These can be scalar arguments or elements of an integer array type
      // passed directly.  Clang may use those instead of "byval" aggregate
      // types to avoid forcing arguments to memory unnecessarily.
      if (GPR_idx != NumGPRs) {
        RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Arg));
      } else {
        if (IsFastCall)
          ComputePtrOff();

        assert(HasParameterArea &&
               "Parameter area must exist to pass an argument in memory.");
        LowerMemOpCallTo(DAG, MF, Chain, Arg, PtrOff, SPDiff, ArgOffset,
                         true, CFlags.IsTailCall, false, MemOpChains,
                         TailCallArguments, dl);
        if (IsFastCall)
          ArgOffset += PtrByteSize;
      }
      if (!IsFastCall)
        ArgOffset += PtrByteSize;
      break;
    case MVT::f32:
    case MVT::f64: {
      // These can be scalar arguments or elements of a float array type
      // passed directly.  The latter are used to implement ELFv2 homogenous
      // float aggregates.

      // Named arguments go into FPRs first, and once they overflow, the
      // remaining arguments go into GPRs and then the parameter save area.
      // Unnamed arguments for vararg functions always go to GPRs and
      // then the parameter save area.  For now, put all arguments to vararg
      // routines always in both locations (FPR *and* GPR or stack slot).
      bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
      bool NeededLoad = false;

      // First load the argument into the next available FPR.
      if (FPR_idx != NumFPRs)
        RegsToPass.push_back(std::make_pair(FPR[FPR_idx++], Arg));

      // Next, load the argument into GPR or stack slot if needed.
      if (!NeedGPROrStack)
        ;
      else if (GPR_idx != NumGPRs && !IsFastCall) {
        // FIXME: We may want to re-enable this for CallingConv::Fast on the P8
        // once we support fp <-> gpr moves.

        // In the non-vararg case, this can only ever happen in the
        // presence of f32 array types, since otherwise we never run
        // out of FPRs before running out of GPRs.
        SDValue ArgVal;

        // Double values are always passed in a single GPR.
        if (Arg.getValueType() != MVT::f32) {
          ArgVal = DAG.getNode(ISD::BITCAST, dl, MVT::i64, Arg);

        // Non-array float values are extended and passed in a GPR.
        } else if (!Flags.isInConsecutiveRegs()) {
          ArgVal = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Arg);
          ArgVal = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i64, ArgVal);

        // If we have an array of floats, we collect every odd element
        // together with its predecessor into one GPR.
        } else if (ArgOffset % PtrByteSize != 0) {
          SDValue Lo, Hi;
          Lo = DAG.getNode(ISD::BITCAST, dl, MVT::i32, OutVals[i - 1]);
          Hi = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Arg);
          if (!isLittleEndian)
            std::swap(Lo, Hi);
          ArgVal = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);

        // The final element, if even, goes into the first half of a GPR.
        } else if (Flags.isInConsecutiveRegsLast()) {
          ArgVal = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Arg);
          ArgVal = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i64, ArgVal);
          if (!isLittleEndian)
            ArgVal = DAG.getNode(ISD::SHL, dl, MVT::i64, ArgVal,
                                 DAG.getConstant(32, dl, MVT::i32));

        // Non-final even elements are skipped; they will be handled
        // together the with subsequent argument on the next go-around.
        } else
          ArgVal = SDValue();

        if (ArgVal.getNode())
          RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
      } else {
        if (IsFastCall)
          ComputePtrOff();

        // Single-precision floating-point values are mapped to the
        // second (rightmost) word of the stack doubleword.
        if (Arg.getValueType() == MVT::f32 &&
            !isLittleEndian && !Flags.isInConsecutiveRegs()) {
          SDValue ConstFour = DAG.getConstant(4, dl, PtrOff.getValueType());
          PtrOff = DAG.getNode(ISD::ADD, dl, PtrVT, PtrOff, ConstFour);
        }

        assert(HasParameterArea &&
               "Parameter area must exist to pass an argument in memory.");
        LowerMemOpCallTo(DAG, MF, Chain, Arg, PtrOff, SPDiff, ArgOffset,
                         true, CFlags.IsTailCall, false, MemOpChains,
                         TailCallArguments, dl);

        NeededLoad = true;
      }
      // When passing an array of floats, the array occupies consecutive
      // space in the argument area; only round up to the next doubleword
      // at the end of the array.  Otherwise, each float takes 8 bytes.
      if (!IsFastCall || NeededLoad) {
        ArgOffset += (Arg.getValueType() == MVT::f32 &&
                      Flags.isInConsecutiveRegs()) ? 4 : 8;
        if (Flags.isInConsecutiveRegsLast())
          ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
      }
      break;
    }
    case MVT::v4f32:
    case MVT::v4i32:
    case MVT::v8i16:
    case MVT::v16i8:
    case MVT::v2f64:
    case MVT::v2i64:
    case MVT::v1i128:
    case MVT::f128:
      // These can be scalar arguments or elements of a vector array type
      // passed directly.  The latter are used to implement ELFv2 homogenous
      // vector aggregates.

      // For a varargs call, named arguments go into VRs or on the stack as
      // usual; unnamed arguments always go to the stack or the corresponding
      // GPRs when within range.  For now, we always put the value in both
      // locations (or even all three).
      if (CFlags.IsVarArg) {
        assert(HasParameterArea &&
               "Parameter area must exist if we have a varargs call.");
        // We could elide this store in the case where the object fits
        // entirely in R registers.  Maybe later.
        SDValue Store =
            DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
        MemOpChains.push_back(Store);
        if (VR_idx != NumVRs) {
          SDValue Load =
              DAG.getLoad(MVT::v4f32, dl, Store, PtrOff, MachinePointerInfo());
          MemOpChains.push_back(Load.getValue(1));
          RegsToPass.push_back(std::make_pair(VR[VR_idx++], Load));
        }
        ArgOffset += 16;
        for (unsigned i=0; i<16; i+=PtrByteSize) {
          if (GPR_idx == NumGPRs)
            break;
          SDValue Ix = DAG.getNode(ISD::ADD, dl, PtrVT, PtrOff,
                                   DAG.getConstant(i, dl, PtrVT));
          SDValue Load =
              DAG.getLoad(PtrVT, dl, Store, Ix, MachinePointerInfo());
          MemOpChains.push_back(Load.getValue(1));
          RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load));
        }
        break;
      }

      // Non-varargs Altivec params go into VRs or on the stack.
      if (VR_idx != NumVRs) {
        RegsToPass.push_back(std::make_pair(VR[VR_idx++], Arg));
      } else {
        if (IsFastCall)
          ComputePtrOff();

        assert(HasParameterArea &&
               "Parameter area must exist to pass an argument in memory.");
        LowerMemOpCallTo(DAG, MF, Chain, Arg, PtrOff, SPDiff, ArgOffset,
                         true, CFlags.IsTailCall, true, MemOpChains,
                         TailCallArguments, dl);
        if (IsFastCall)
          ArgOffset += 16;
      }

      if (!IsFastCall)
        ArgOffset += 16;
      break;
    }
  }

  assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
         "mismatch in size of parameter area");
  (void)NumBytesActuallyUsed;

  if (!MemOpChains.empty())
    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);

  // Check if this is an indirect call (MTCTR/BCTRL).
  // See prepareDescriptorIndirectCall and buildCallOperands for more
  // information about calls through function pointers in the 64-bit SVR4 ABI.
  if (CFlags.IsIndirect) {
    // For 64-bit ELFv2 ABI with PCRel, do not save the TOC of the
    // caller in the TOC save area.
    if (isTOCSaveRestoreRequired(Subtarget)) {
      assert(!CFlags.IsTailCall && "Indirect tails calls not supported");
      // Load r2 into a virtual register and store it to the TOC save area.
      setUsesTOCBasePtr(DAG);
      SDValue Val = DAG.getCopyFromReg(Chain, dl, PPC::X2, MVT::i64);
      // TOC save area offset.
      unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
      SDValue PtrOff = DAG.getIntPtrConstant(TOCSaveOffset, dl);
      SDValue AddPtr = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr, PtrOff);
      Chain = DAG.getStore(Val.getValue(1), dl, Val, AddPtr,
                           MachinePointerInfo::getStack(
                               DAG.getMachineFunction(), TOCSaveOffset));
    }
    // In the ELFv2 ABI, R12 must contain the address of an indirect callee.
    // This does not mean the MTCTR instruction must use R12; it's easier
    // to model this as an extra parameter, so do that.
    if (isELFv2ABI && !CFlags.IsPatchPoint)
      RegsToPass.push_back(std::make_pair((unsigned)PPC::X12, Callee));
  }

  // Build a sequence of copy-to-reg nodes chained together with token chain
  // and flag operands which copy the outgoing args into the appropriate regs.
  SDValue InGlue;
  for (const auto &[Reg, N] : RegsToPass) {
    Chain = DAG.getCopyToReg(Chain, dl, Reg, N, InGlue);
    InGlue = Chain.getValue(1);
  }

  if (CFlags.IsTailCall && !IsSibCall)
    PrepareTailCall(DAG, InGlue, Chain, dl, SPDiff, NumBytes, LROp, FPOp,
                    TailCallArguments);

  return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
                    Callee, SPDiff, NumBytes, Ins, InVals, CB);
}

// Returns true when the shadow of a general purpose argument register
// in the parameter save area is aligned to at least 'RequiredAlign'.
static bool isGPRShadowAligned(MCPhysReg Reg, Align RequiredAlign) {
  assert(RequiredAlign.value() <= 16 &&
         "Required alignment greater than stack alignment.");
  switch (Reg) {
  default:
    report_fatal_error("called on invalid register.");
  case PPC::R5:
  case PPC::R9:
  case PPC::X3:
  case PPC::X5:
  case PPC::X7:
  case PPC::X9:
    // These registers are 16 byte aligned which is the most strict aligment
    // we can support.
    return true;
  case PPC::R3:
  case PPC::R7:
  case PPC::X4:
  case PPC::X6:
  case PPC::X8:
  case PPC::X10:
    // The shadow of these registers in the PSA is 8 byte aligned.
    return RequiredAlign <= 8;
  case PPC::R4:
  case PPC::R6:
  case PPC::R8:
  case PPC::R10:
    return RequiredAlign <= 4;
  }
}

static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT,
                   CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags,
                   Type *OrigTy, CCState &State) {
  const PPCSubtarget &Subtarget = static_cast<const PPCSubtarget &>(
      State.getMachineFunction().getSubtarget());
  const bool IsPPC64 = Subtarget.isPPC64();
  const unsigned PtrSize = IsPPC64 ? 8 : 4;
  const Align PtrAlign(PtrSize);
  const Align StackAlign(16);
  const MVT RegVT = Subtarget.getScalarIntVT();

  if (ValVT == MVT::f128)
    report_fatal_error("f128 is unimplemented on AIX.");

  static const MCPhysReg GPR_32[] = {// 32-bit registers.
                                     PPC::R3, PPC::R4, PPC::R5, PPC::R6,
                                     PPC::R7, PPC::R8, PPC::R9, PPC::R10};
  static const MCPhysReg GPR_64[] = {// 64-bit registers.
                                     PPC::X3, PPC::X4, PPC::X5, PPC::X6,
                                     PPC::X7, PPC::X8, PPC::X9, PPC::X10};

  static const MCPhysReg VR[] = {// Vector registers.
                                 PPC::V2,  PPC::V3,  PPC::V4,  PPC::V5,
                                 PPC::V6,  PPC::V7,  PPC::V8,  PPC::V9,
                                 PPC::V10, PPC::V11, PPC::V12, PPC::V13};

  const ArrayRef<MCPhysReg> GPRs = IsPPC64 ? GPR_64 : GPR_32;

  if (ArgFlags.isNest()) {
    MCRegister EnvReg = State.AllocateReg(IsPPC64 ? PPC::X11 : PPC::R11);
    if (!EnvReg)
      report_fatal_error("More then one nest argument.");
    State.addLoc(CCValAssign::getReg(ValNo, ValVT, EnvReg, RegVT, LocInfo));
    return false;
  }

  if (ArgFlags.isByVal()) {
    const Align ByValAlign(ArgFlags.getNonZeroByValAlign());
    if (ByValAlign > StackAlign)
      report_fatal_error("Pass-by-value arguments with alignment greater than "
                         "16 are not supported.");

    const unsigned ByValSize = ArgFlags.getByValSize();
    const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;

    // An empty aggregate parameter takes up no storage and no registers,
    // but needs a MemLoc for a stack slot for the formal arguments side.
    if (ByValSize == 0) {
      State.addLoc(CCValAssign::getMem(ValNo, MVT::INVALID_SIMPLE_VALUE_TYPE,
                                       State.getStackSize(), RegVT, LocInfo));
      return false;
    }

    // Shadow allocate any registers that are not properly aligned.
    unsigned NextReg = State.getFirstUnallocated(GPRs);
    while (NextReg != GPRs.size() &&
           !isGPRShadowAligned(GPRs[NextReg], ObjAlign)) {
      // Shadow allocate next registers since its aligment is not strict enough.
      MCRegister Reg = State.AllocateReg(GPRs);
      // Allocate the stack space shadowed by said register.
      State.AllocateStack(PtrSize, PtrAlign);
      assert(Reg && "Alocating register unexpectedly failed.");
      (void)Reg;
      NextReg = State.getFirstUnallocated(GPRs);
    }

    const unsigned StackSize = alignTo(ByValSize, ObjAlign);
    unsigned Offset = State.AllocateStack(StackSize, ObjAlign);
    for (const unsigned E = Offset + StackSize; Offset < E; Offset += PtrSize) {
      if (MCRegister Reg = State.AllocateReg(GPRs))
        State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, RegVT, LocInfo));
      else {
        State.addLoc(CCValAssign::getMem(ValNo, MVT::INVALID_SIMPLE_VALUE_TYPE,
                                         Offset, MVT::INVALID_SIMPLE_VALUE_TYPE,
                                         LocInfo));
        break;
      }
    }
    return false;
  }

  // Arguments always reserve parameter save area.
  switch (ValVT.SimpleTy) {
  default:
    report_fatal_error("Unhandled value type for argument.");
  case MVT::i64:
    // i64 arguments should have been split to i32 for PPC32.
    assert(IsPPC64 && "PPC32 should have split i64 values.");
    [[fallthrough]];
  case MVT::i1:
  case MVT::i32: {
    const unsigned Offset = State.AllocateStack(PtrSize, PtrAlign);
    // AIX integer arguments are always passed in register width.
    if (ValVT.getFixedSizeInBits() < RegVT.getFixedSizeInBits())
      LocInfo = ArgFlags.isSExt() ? CCValAssign::LocInfo::SExt
                                  : CCValAssign::LocInfo::ZExt;
    if (MCRegister Reg = State.AllocateReg(GPRs))
      State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, RegVT, LocInfo));
    else
      State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, RegVT, LocInfo));

    return false;
  }
  case MVT::f32:
  case MVT::f64: {
    // Parameter save area (PSA) is reserved even if the float passes in fpr.
    const unsigned StoreSize = LocVT.getStoreSize();
    // Floats are always 4-byte aligned in the PSA on AIX.
    // This includes f64 in 64-bit mode for ABI compatibility.
    const unsigned Offset =
        State.AllocateStack(IsPPC64 ? 8 : StoreSize, Align(4));
    MCRegister FReg = State.AllocateReg(FPR);
    if (FReg)
      State.addLoc(CCValAssign::getReg(ValNo, ValVT, FReg, LocVT, LocInfo));

    // Reserve and initialize GPRs or initialize the PSA as required.
    for (unsigned I = 0; I < StoreSize; I += PtrSize) {
      if (MCRegister Reg = State.AllocateReg(GPRs)) {
        assert(FReg && "An FPR should be available when a GPR is reserved.");
        if (State.isVarArg()) {
          // Successfully reserved GPRs are only initialized for vararg calls.
          // Custom handling is required for:
          //   f64 in PPC32 needs to be split into 2 GPRs.
          //   f32 in PPC64 needs to occupy only lower 32 bits of 64-bit GPR.
          State.addLoc(
              CCValAssign::getCustomReg(ValNo, ValVT, Reg, RegVT, LocInfo));
        }
      } else {
        // If there are insufficient GPRs, the PSA needs to be initialized.
        // Initialization occurs even if an FPR was initialized for
        // compatibility with the AIX XL compiler. The full memory for the
        // argument will be initialized even if a prior word is saved in GPR.
        // A custom memLoc is used when the argument also passes in FPR so
        // that the callee handling can skip over it easily.
        State.addLoc(
            FReg ? CCValAssign::getCustomMem(ValNo, ValVT, Offset, LocVT,
                                             LocInfo)
                 : CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
        break;
      }
    }

    return false;
  }
  case MVT::v4f32:
  case MVT::v4i32:
  case MVT::v8i16:
  case MVT::v16i8:
  case MVT::v2i64:
  case MVT::v2f64:
  case MVT::v1i128: {
    const unsigned VecSize = 16;
    const Align VecAlign(VecSize);

    if (!State.isVarArg()) {
      // If there are vector registers remaining we don't consume any stack
      // space.
      if (MCRegister VReg = State.AllocateReg(VR)) {
        State.addLoc(CCValAssign::getReg(ValNo, ValVT, VReg, LocVT, LocInfo));
        return false;
      }
      // Vectors passed on the stack do not shadow GPRs or FPRs even though they
      // might be allocated in the portion of the PSA that is shadowed by the
      // GPRs.
      const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
      State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
      return false;
    }

    unsigned NextRegIndex = State.getFirstUnallocated(GPRs);
    // Burn any underaligned registers and their shadowed stack space until
    // we reach the required alignment.
    while (NextRegIndex != GPRs.size() &&
           !isGPRShadowAligned(GPRs[NextRegIndex], VecAlign)) {
      // Shadow allocate register and its stack shadow.
      MCRegister Reg = State.AllocateReg(GPRs);
      State.AllocateStack(PtrSize, PtrAlign);
      assert(Reg && "Allocating register unexpectedly failed.");
      (void)Reg;
      NextRegIndex = State.getFirstUnallocated(GPRs);
    }

    // Vectors that are passed as fixed arguments are handled differently.
    // They are passed in VRs if any are available (unlike arguments passed
    // through ellipses) and shadow GPRs (unlike arguments to non-vaarg
    // functions)
    if (!ArgFlags.isVarArg()) {
      if (MCRegister VReg = State.AllocateReg(VR)) {
        State.addLoc(CCValAssign::getReg(ValNo, ValVT, VReg, LocVT, LocInfo));
        // Shadow allocate GPRs and stack space even though we pass in a VR.
        for (unsigned I = 0; I != VecSize; I += PtrSize)
          State.AllocateReg(GPRs);
        State.AllocateStack(VecSize, VecAlign);
        return false;
      }
      // No vector registers remain so pass on the stack.
      const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
      State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
      return false;
    }

    // If all GPRS are consumed then we pass the argument fully on the stack.
    if (NextRegIndex == GPRs.size()) {
      const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
      State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
      return false;
    }

    // Corner case for 32-bit codegen. We have 2 registers to pass the first
    // half of the argument, and then need to pass the remaining half on the
    // stack.
    if (GPRs[NextRegIndex] == PPC::R9) {
      const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
      State.addLoc(
          CCValAssign::getCustomMem(ValNo, ValVT, Offset, LocVT, LocInfo));

      const MCRegister FirstReg = State.AllocateReg(PPC::R9);
      const MCRegister SecondReg = State.AllocateReg(PPC::R10);
      assert(FirstReg && SecondReg &&
             "Allocating R9 or R10 unexpectedly failed.");
      State.addLoc(
          CCValAssign::getCustomReg(ValNo, ValVT, FirstReg, RegVT, LocInfo));
      State.addLoc(
          CCValAssign::getCustomReg(ValNo, ValVT, SecondReg, RegVT, LocInfo));
      return false;
    }

    // We have enough GPRs to fully pass the vector argument, and we have
    // already consumed any underaligned registers. Start with the custom
    // MemLoc and then the custom RegLocs.
    const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
    State.addLoc(
        CCValAssign::getCustomMem(ValNo, ValVT, Offset, LocVT, LocInfo));
    for (unsigned I = 0; I != VecSize; I += PtrSize) {
      const MCRegister Reg = State.AllocateReg(GPRs);
      assert(Reg && "Failed to allocated register for vararg vector argument");
      State.addLoc(
          CCValAssign::getCustomReg(ValNo, ValVT, Reg, RegVT, LocInfo));
    }
    return false;
  }
  }
  return true;
}

// So far, this function is only used by LowerFormalArguments_AIX()
static const TargetRegisterClass *getRegClassForSVT(MVT::SimpleValueType SVT,
                                                    bool IsPPC64,
                                                    bool HasP8Vector,
                                                    bool HasVSX) {
  assert((IsPPC64 || SVT != MVT::i64) &&
         "i64 should have been split for 32-bit codegen.");

  switch (SVT) {
  default:
    report_fatal_error("Unexpected value type for formal argument");
  case MVT::i1:
  case MVT::i32:
  case MVT::i64:
    return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
  case MVT::f32:
    return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
  case MVT::f64:
    return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
  case MVT::v4f32:
  case MVT::v4i32:
  case MVT::v8i16:
  case MVT::v16i8:
  case MVT::v2i64:
  case MVT::v2f64:
  case MVT::v1i128:
    return &PPC::VRRCRegClass;
  }
}

static SDValue truncateScalarIntegerArg(ISD::ArgFlagsTy Flags, EVT ValVT,
                                        SelectionDAG &DAG, SDValue ArgValue,
                                        MVT LocVT, const SDLoc &dl) {
  assert(ValVT.isScalarInteger() && LocVT.isScalarInteger());
  assert(ValVT.getFixedSizeInBits() < LocVT.getFixedSizeInBits());

  if (Flags.isSExt())
    ArgValue = DAG.getNode(ISD::AssertSext, dl, LocVT, ArgValue,
                           DAG.getValueType(ValVT));
  else if (Flags.isZExt())
    ArgValue = DAG.getNode(ISD::AssertZext, dl, LocVT, ArgValue,
                           DAG.getValueType(ValVT));

  return DAG.getNode(ISD::TRUNCATE, dl, ValVT, ArgValue);
}

static unsigned mapArgRegToOffsetAIX(unsigned Reg, const PPCFrameLowering *FL) {
  const unsigned LASize = FL->getLinkageSize();

  if (PPC::GPRCRegClass.contains(Reg)) {
    assert(Reg >= PPC::R3 && Reg <= PPC::R10 &&
           "Reg must be a valid argument register!");
    return LASize + 4 * (Reg - PPC::R3);
  }

  if (PPC::G8RCRegClass.contains(Reg)) {
    assert(Reg >= PPC::X3 && Reg <= PPC::X10 &&
           "Reg must be a valid argument register!");
    return LASize + 8 * (Reg - PPC::X3);
  }

  llvm_unreachable("Only general purpose registers expected.");
}

//   AIX ABI Stack Frame Layout:
//
//   Low Memory +--------------------------------------------+
//   SP   +---> | Back chain                                 | ---+
//        |     +--------------------------------------------+    |   
//        |     | Saved Condition Register                   |    |
//        |     +--------------------------------------------+    |
//        |     | Saved Linkage Register                     |    |
//        |     +--------------------------------------------+    | Linkage Area
//        |     | Reserved for compilers                     |    |
//        |     +--------------------------------------------+    |
//        |     | Reserved for binders                       |    |
//        |     +--------------------------------------------+    |
//        |     | Saved TOC pointer                          | ---+
//        |     +--------------------------------------------+
//        |     | Parameter save area                        |
//        |     +--------------------------------------------+
//        |     | Alloca space                               |
//        |     +--------------------------------------------+
//        |     | Local variable space                       |
//        |     +--------------------------------------------+
//        |     | Float/int conversion temporary             |
//        |     +--------------------------------------------+
//        |     | Save area for AltiVec registers            |
//        |     +--------------------------------------------+
//        |     | AltiVec alignment padding                  |
//        |     +--------------------------------------------+
//        |     | Save area for VRSAVE register              |
//        |     +--------------------------------------------+
//        |     | Save area for General Purpose registers    |
//        |     +--------------------------------------------+
//        |     | Save area for Floating Point registers     |
//        |     +--------------------------------------------+
//        +---- | Back chain                                 |
// High Memory  +--------------------------------------------+
//
//  Specifications:
//  AIX 7.2 Assembler Language Reference
//  Subroutine linkage convention

SDValue PPCTargetLowering::LowerFormalArguments_AIX(
    SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
    const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
    SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {

  assert((CallConv == CallingConv::C || CallConv == CallingConv::Cold ||
          CallConv == CallingConv::Fast) &&
         "Unexpected calling convention!");

  if (getTargetMachine().Options.GuaranteedTailCallOpt)
    report_fatal_error("Tail call support is unimplemented on AIX.");

  if (useSoftFloat())
    report_fatal_error("Soft float support is unimplemented on AIX.");

  const PPCSubtarget &Subtarget = DAG.getSubtarget<PPCSubtarget>();

  const bool IsPPC64 = Subtarget.isPPC64();
  const unsigned PtrByteSize = IsPPC64 ? 8 : 4;

  // Assign locations to all of the incoming arguments.
  SmallVector<CCValAssign, 16> ArgLocs;
  MachineFunction &MF = DAG.getMachineFunction();
  MachineFrameInfo &MFI = MF.getFrameInfo();
  PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
  CCState CCInfo(CallConv, isVarArg, MF, ArgLocs, *DAG.getContext());

  const EVT PtrVT = getPointerTy(MF.getDataLayout());
  // Reserve space for the linkage area on the stack.
  const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
  CCInfo.AllocateStack(LinkageSize, Align(PtrByteSize));
  uint64_t SaveStackPos = CCInfo.getStackSize();
  bool SaveParams = MF.getFunction().hasFnAttribute("save-reg-params");
  CCInfo.AnalyzeFormalArguments(Ins, CC_AIX);

  SmallVector<SDValue, 8> MemOps;

  for (size_t I = 0, End = ArgLocs.size(); I != End; /* No increment here */) {
    CCValAssign &VA = ArgLocs[I++];
    MVT LocVT = VA.getLocVT();
    MVT ValVT = VA.getValVT();
    ISD::ArgFlagsTy Flags = Ins[VA.getValNo()].Flags;

    EVT ArgVT = Ins[VA.getValNo()].ArgVT;
    bool ArgSignExt = Ins[VA.getValNo()].Flags.isSExt();
    // For compatibility with the AIX XL compiler, the float args in the
    // parameter save area are initialized even if the argument is available
    // in register.  The caller is required to initialize both the register
    // and memory, however, the callee can choose to expect it in either.
    // The memloc is dismissed here because the argument is retrieved from
    // the register.
    if (VA.isMemLoc() && VA.needsCustom() && ValVT.isFloatingPoint())
      continue;

    if (SaveParams && VA.isRegLoc() && !Flags.isByVal() && !VA.needsCustom()) {
      const TargetRegisterClass *RegClass = getRegClassForSVT(
          LocVT.SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
      // On PPC64, debugger assumes extended 8-byte values are stored from GPR.
      MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
      const Register VReg = MF.addLiveIn(VA.getLocReg(), RegClass);
      SDValue Parm = DAG.getCopyFromReg(Chain, dl, VReg, SaveVT);
      int FI = MFI.CreateFixedObject(SaveVT.getStoreSize(), SaveStackPos, true);
      SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
      SDValue StoreReg = DAG.getStore(Chain, dl, Parm, FIN,
                                      MachinePointerInfo(), Align(PtrByteSize));
      SaveStackPos = alignTo(SaveStackPos + SaveVT.getStoreSize(), PtrByteSize);
      MemOps.push_back(StoreReg);
    }

    if (SaveParams && (VA.isMemLoc() || Flags.isByVal()) && !VA.needsCustom()) {
      unsigned StoreSize =
          Flags.isByVal() ? Flags.getByValSize() : LocVT.getStoreSize();
      SaveStackPos = alignTo(SaveStackPos + StoreSize, PtrByteSize);
    }

    auto HandleMemLoc = [&]() {
      const unsigned LocSize = LocVT.getStoreSize();
      const unsigned ValSize = ValVT.getStoreSize();
      assert((ValSize <= LocSize) &&
             "Object size is larger than size of MemLoc");
      int CurArgOffset = VA.getLocMemOffset();
      // Objects are right-justified because AIX is big-endian.
      if (LocSize > ValSize)
        CurArgOffset += LocSize - ValSize;
      // Potential tail calls could cause overwriting of argument stack slots.
      const bool IsImmutable =
          !(getTargetMachine().Options.GuaranteedTailCallOpt &&
            (CallConv == CallingConv::Fast));
      int FI = MFI.CreateFixedObject(ValSize, CurArgOffset, IsImmutable);
      SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
      SDValue ArgValue =
          DAG.getLoad(ValVT, dl, Chain, FIN, MachinePointerInfo());

      // While the ABI specifies the argument type is (sign or zero) extended
      // out to register width, not all code is compliant. We truncate and
      // re-extend to be more forgiving of these callers when the argument type
      // is smaller than register width.
      if (!ArgVT.isVector() && !ValVT.isVector() && ArgVT.isInteger() &&
          ValVT.isInteger() &&
          ArgVT.getScalarSizeInBits() < ValVT.getScalarSizeInBits()) {
        // It is possible to have either real integer values
        // or integers that were not originally integers.
        // In the latter case, these could have came from structs,
        // and these integers would not have an extend on the parameter.
        // Since these types of integers do not have an extend specified
        // in the first place, the type of extend that we do should not matter.
        EVT TruncatedArgVT = ArgVT.isSimple() && ArgVT.getSimpleVT() == MVT::i1
                                 ? MVT::i8
                                 : ArgVT;
        SDValue ArgValueTrunc =
            DAG.getNode(ISD::TRUNCATE, dl, TruncatedArgVT, ArgValue);
        SDValue ArgValueExt =
            ArgSignExt ? DAG.getSExtOrTrunc(ArgValueTrunc, dl, ValVT)
                       : DAG.getZExtOrTrunc(ArgValueTrunc, dl, ValVT);
        InVals.push_back(ArgValueExt);
      } else {
        InVals.push_back(ArgValue);
      }
    };

    // Vector arguments to VaArg functions are passed both on the stack, and
    // in any available GPRs. Load the value from the stack and add the GPRs
    // as live ins.
    if (VA.isMemLoc() && VA.needsCustom()) {
      assert(ValVT.isVector() && "Unexpected Custom MemLoc type.");
      assert(isVarArg && "Only use custom memloc for vararg.");
      // ValNo of the custom MemLoc, so we can compare it to the ValNo of the
      // matching custom RegLocs.
      const unsigned OriginalValNo = VA.getValNo();
      (void)OriginalValNo;

      auto HandleCustomVecRegLoc = [&]() {
        assert(I != End && ArgLocs[I].isRegLoc() && ArgLocs[I].needsCustom() &&
               "Missing custom RegLoc.");
        VA = ArgLocs[I++];
        assert(VA.getValVT().isVector() &&
               "Unexpected Val type for custom RegLoc.");
        assert(VA.getValNo() == OriginalValNo &&
               "ValNo mismatch between custom MemLoc and RegLoc.");
        MVT::SimpleValueType SVT = VA.getLocVT().SimpleTy;
        MF.addLiveIn(VA.getLocReg(),
                     getRegClassForSVT(SVT, IsPPC64, Subtarget.hasP8Vector(),
                                       Subtarget.hasVSX()));
      };

      HandleMemLoc();
      // In 64-bit there will be exactly 2 custom RegLocs that follow, and in
      // in 32-bit there will be 2 custom RegLocs if we are passing in R9 and
      // R10.
      HandleCustomVecRegLoc();
      HandleCustomVecRegLoc();

      // If we are targeting 32-bit, there might be 2 extra custom RegLocs if
      // we passed the vector in R5, R6, R7 and R8.
      if (I != End && ArgLocs[I].isRegLoc() && ArgLocs[I].needsCustom()) {
        assert(!IsPPC64 &&
               "Only 2 custom RegLocs expected for 64-bit codegen.");
        HandleCustomVecRegLoc();
        HandleCustomVecRegLoc();
      }

      continue;
    }

    if (VA.isRegLoc()) {
      if (VA.getValVT().isScalarInteger())
        FuncInfo->appendParameterType(PPCFunctionInfo::FixedType);
      else if (VA.getValVT().isFloatingPoint() && !VA.getValVT().isVector()) {
        switch (VA.getValVT().SimpleTy) {
        default:
          report_fatal_error("Unhandled value type for argument.");
        case MVT::f32:
          FuncInfo->appendParameterType(PPCFunctionInfo::ShortFloatingPoint);
          break;
        case MVT::f64:
          FuncInfo->appendParameterType(PPCFunctionInfo::LongFloatingPoint);
          break;
        }
      } else if (VA.getValVT().isVector()) {
        switch (VA.getValVT().SimpleTy) {
        default:
          report_fatal_error("Unhandled value type for argument.");
        case MVT::v16i8:
          FuncInfo->appendParameterType(PPCFunctionInfo::VectorChar);
          break;
        case MVT::v8i16:
          FuncInfo->appendParameterType(PPCFunctionInfo::VectorShort);
          break;
        case MVT::v4i32:
        case MVT::v2i64:
        case MVT::v1i128:
          FuncInfo->appendParameterType(PPCFunctionInfo::VectorInt);
          break;
        case MVT::v4f32:
        case MVT::v2f64:
          FuncInfo->appendParameterType(PPCFunctionInfo::VectorFloat);
          break;
        }
      }
    }

    if (Flags.isByVal() && VA.isMemLoc()) {
      const unsigned Size =
          alignTo(Flags.getByValSize() ? Flags.getByValSize() : PtrByteSize,
                  PtrByteSize);
      const int FI = MF.getFrameInfo().CreateFixedObject(
          Size, VA.getLocMemOffset(), /* IsImmutable */ false,
          /* IsAliased */ true);
      SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
      InVals.push_back(FIN);

      continue;
    }

    if (Flags.isByVal()) {
      assert(VA.isRegLoc() && "MemLocs should already be handled.");

      const MCPhysReg ArgReg = VA.getLocReg();
      const PPCFrameLowering *FL = Subtarget.getFrameLowering();

      const unsigned StackSize = alignTo(Flags.getByValSize(), PtrByteSize);
      const int FI = MF.getFrameInfo().CreateFixedObject(
          StackSize, mapArgRegToOffsetAIX(ArgReg, FL), /* IsImmutable */ false,
          /* IsAliased */ true);
      SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
      InVals.push_back(FIN);

      // Add live ins for all the RegLocs for the same ByVal.
      const TargetRegisterClass *RegClass =
          IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;

      auto HandleRegLoc = [&, RegClass, LocVT](const MCPhysReg PhysReg,
                                               unsigned Offset) {
        const Register VReg = MF.addLiveIn(PhysReg, RegClass);
        // Since the callers side has left justified the aggregate in the
        // register, we can simply store the entire register into the stack
        // slot.
        SDValue CopyFrom = DAG.getCopyFromReg(Chain, dl, VReg, LocVT);
        // The store to the fixedstack object is needed becuase accessing a
        // field of the ByVal will use a gep and load. Ideally we will optimize
        // to extracting the value from the register directly, and elide the
        // stores when the arguments address is not taken, but that will need to
        // be future work.
        SDValue Store = DAG.getStore(
            CopyFrom.getValue(1), dl, CopyFrom,
            DAG.getObjectPtrOffset(dl, FIN, TypeSize::getFixed(Offset)),
            MachinePointerInfo::getFixedStack(MF, FI, Offset));

        MemOps.push_back(Store);
      };

      unsigned Offset = 0;
      HandleRegLoc(VA.getLocReg(), Offset);
      Offset += PtrByteSize;
      for (; Offset != StackSize && ArgLocs[I].isRegLoc();
           Offset += PtrByteSize) {
        assert(ArgLocs[I].getValNo() == VA.getValNo() &&
               "RegLocs should be for ByVal argument.");

        const CCValAssign RL = ArgLocs[I++];
        HandleRegLoc(RL.getLocReg(), Offset);
        FuncInfo->appendParameterType(PPCFunctionInfo::FixedType);
      }

      if (Offset != StackSize) {
        assert(ArgLocs[I].getValNo() == VA.getValNo() &&
               "Expected MemLoc for remaining bytes.");
        assert(ArgLocs[I].isMemLoc() && "Expected MemLoc for remaining bytes.");
        // Consume the MemLoc.The InVal has already been emitted, so nothing
        // more needs to be done.
        ++I;
      }

      continue;
    }

    if (VA.isRegLoc() && !VA.needsCustom()) {
      MVT::SimpleValueType SVT = ValVT.SimpleTy;
      Register VReg =
          MF.addLiveIn(VA.getLocReg(),
                       getRegClassForSVT(SVT, IsPPC64, Subtarget.hasP8Vector(),
                                         Subtarget.hasVSX()));
      SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, LocVT);
      if (ValVT.isScalarInteger() &&
          (ValVT.getFixedSizeInBits() < LocVT.getFixedSizeInBits())) {
        ArgValue =
            truncateScalarIntegerArg(Flags, ValVT, DAG, ArgValue, LocVT, dl);
      }
      InVals.push_back(ArgValue);
      continue;
    }
    if (VA.isMemLoc()) {
      HandleMemLoc();
      continue;
    }
  }

  // On AIX a minimum of 8 words is saved to the parameter save area.
  const unsigned MinParameterSaveArea = 8 * PtrByteSize;
  // Area that is at least reserved in the caller of this function.
  unsigned CallerReservedArea = std::max<unsigned>(
      CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);

  // Set the size that is at least reserved in caller of this function. Tail
  // call optimized function's reserved stack space needs to be aligned so
  // that taking the difference between two stack areas will result in an
  // aligned stack.
  CallerReservedArea =
      EnsureStackAlignment(Subtarget.getFrameLowering(), CallerReservedArea);
  FuncInfo->setMinReservedArea(CallerReservedArea);

  if (isVarArg) {
    int VAListIndex = 0;
    // If any of the optional arguments are passed in register then the fixed
    // stack object we spill into is not immutable. Create a fixed stack object
    // that overlaps the remainder of the parameter save area.
    if (CCInfo.getStackSize() < (LinkageSize + MinParameterSaveArea)) {
      unsigned FixedStackSize =
          LinkageSize + MinParameterSaveArea - CCInfo.getStackSize();
      VAListIndex =
          MFI.CreateFixedObject(FixedStackSize, CCInfo.getStackSize(),
                                /* IsImmutable */ false, /* IsAliased */ true);
    } else {
      // All the arguments passed through ellipses are on the stack. Create a
      // dummy fixed stack object the same size as a pointer since we don't
      // know the actual size.
      VAListIndex =
          MFI.CreateFixedObject(PtrByteSize, CCInfo.getStackSize(),
                                /* IsImmutable */ true, /* IsAliased */ true);
    }

    FuncInfo->setVarArgsFrameIndex(VAListIndex);
    SDValue FIN = DAG.getFrameIndex(VAListIndex, PtrVT);

    static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
                                       PPC::R7, PPC::R8, PPC::R9, PPC::R10};

    static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
                                       PPC::X7, PPC::X8, PPC::X9, PPC::X10};
    const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);

    // The fixed integer arguments of a variadic function are stored to the
    // VarArgsFrameIndex on the stack so that they may be loaded by
    // dereferencing the result of va_next.
    for (unsigned
             GPRIndex = (CCInfo.getStackSize() - LinkageSize) / PtrByteSize,
             Offset = 0;
         GPRIndex < NumGPArgRegs; ++GPRIndex, Offset += PtrByteSize) {

      const Register VReg =
          IsPPC64 ? MF.addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
                  : MF.addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);

      SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT);
      MachinePointerInfo MPI =
          MachinePointerInfo::getFixedStack(MF, VAListIndex, Offset);
      SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, MPI);
      MemOps.push_back(Store);
      // Increment the address for the next argument to store.
      SDValue PtrOff = DAG.getConstant(PtrByteSize, dl, PtrVT);
      FIN = DAG.getNode(ISD::ADD, dl, PtrOff.getValueType(), FIN, PtrOff);
    }
  }

  if (!MemOps.empty())
    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOps);

  return Chain;
}

SDValue PPCTargetLowering::LowerCall_AIX(
    SDValue Chain, SDValue Callee, CallFlags CFlags,
    const SmallVectorImpl<ISD::OutputArg> &Outs,
    const SmallVectorImpl<SDValue> &OutVals,
    const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
    SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
    const CallBase *CB) const {
  // See PPCTargetLowering::LowerFormalArguments_AIX() for a description of the
  // AIX ABI stack frame layout.

  assert((CFlags.CallConv == CallingConv::C ||
          CFlags.CallConv == CallingConv::Cold ||
          CFlags.CallConv == CallingConv::Fast) &&
         "Unexpected calling convention!");

  if (CFlags.IsPatchPoint)
    report_fatal_error("This call type is unimplemented on AIX.");

  const PPCSubtarget &Subtarget = DAG.getSubtarget<PPCSubtarget>();

  MachineFunction &MF = DAG.getMachineFunction();
  SmallVector<CCValAssign, 16> ArgLocs;
  CCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
                 *DAG.getContext());

  // Reserve space for the linkage save area (LSA) on the stack.
  // In both PPC32 and PPC64 there are 6 reserved slots in the LSA:
  //   [SP][CR][LR][2 x reserved][TOC].
  // The LSA is 24 bytes (6x4) in PPC32 and 48 bytes (6x8) in PPC64.
  const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
  const bool IsPPC64 = Subtarget.isPPC64();
  const EVT PtrVT = getPointerTy(DAG.getDataLayout());
  const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
  CCInfo.AllocateStack(LinkageSize, Align(PtrByteSize));
  CCInfo.AnalyzeCallOperands(Outs, CC_AIX);

  // The prolog code of the callee may store up to 8 GPR argument registers to
  // the stack, allowing va_start to index over them in memory if the callee
  // is variadic.
  // Because we cannot tell if this is needed on the caller side, we have to
  // conservatively assume that it is needed.  As such, make sure we have at
  // least enough stack space for the caller to store the 8 GPRs.
  const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
  const unsigned NumBytes = std::max<unsigned>(
      LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());

  // Adjust the stack pointer for the new arguments...
  // These operations are automatically eliminated by the prolog/epilog pass.
  Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, dl);
  SDValue CallSeqStart = Chain;

  SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass;
  SmallVector<SDValue, 8> MemOpChains;

  // Set up a copy of the stack pointer for loading and storing any
  // arguments that may not fit in the registers available for argument
  // passing.
  const SDValue StackPtr = IsPPC64 ? DAG.getRegister(PPC::X1, MVT::i64)
                                   : DAG.getRegister(PPC::R1, MVT::i32);

  for (unsigned I = 0, E = ArgLocs.size(); I != E;) {
    const unsigned ValNo = ArgLocs[I].getValNo();
    SDValue Arg = OutVals[ValNo];
    ISD::ArgFlagsTy Flags = Outs[ValNo].Flags;

    if (Flags.isByVal()) {
      const unsigned ByValSize = Flags.getByValSize();

      // Nothing to do for zero-sized ByVals on the caller side.
      if (!ByValSize) {
        ++I;
        continue;
      }

      auto GetLoad = [&](EVT VT, unsigned LoadOffset) {
        return DAG.getExtLoad(ISD::ZEXTLOAD, dl, PtrVT, Chain,
                              (LoadOffset != 0)
                                  ? DAG.getObjectPtrOffset(
                                        dl, Arg, TypeSize::getFixed(LoadOffset))
                                  : Arg,
                              MachinePointerInfo(), VT);
      };

      unsigned LoadOffset = 0;

      // Initialize registers, which are fully occupied by the by-val argument.
      while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[I].isRegLoc()) {
        SDValue Load = GetLoad(PtrVT, LoadOffset);
        MemOpChains.push_back(Load.getValue(1));
        LoadOffset += PtrByteSize;
        const CCValAssign &ByValVA = ArgLocs[I++];
        assert(ByValVA.getValNo() == ValNo &&
               "Unexpected location for pass-by-value argument.");
        RegsToPass.push_back(std::make_pair(ByValVA.getLocReg(), Load));
      }

      if (LoadOffset == ByValSize)
        continue;

      // There must be one more loc to handle the remainder.
      assert(ArgLocs[I].getValNo() == ValNo &&
             "Expected additional location for by-value argument.");

      if (ArgLocs[I].isMemLoc()) {
        assert(LoadOffset < ByValSize && "Unexpected memloc for by-val arg.");
        const CCValAssign &ByValVA = ArgLocs[I++];
        ISD::ArgFlagsTy MemcpyFlags = Flags;
        // Only memcpy the bytes that don't pass in register.
        MemcpyFlags.setByValSize(ByValSize - LoadOffset);
        Chain = CallSeqStart = createMemcpyOutsideCallSeq(
            (LoadOffset != 0) ? DAG.getObjectPtrOffset(
                                    dl, Arg, TypeSize::getFixed(LoadOffset))
                              : Arg,
            DAG.getObjectPtrOffset(
                dl, StackPtr, TypeSize::getFixed(ByValVA.getLocMemOffset())),
            CallSeqStart, MemcpyFlags, DAG, dl);
        continue;
      }

      // Initialize the final register residue.
      // Any residue that occupies the final by-val arg register must be
      // left-justified on AIX. Loads must be a power-of-2 size and cannot be
      // larger than the ByValSize. For example: a 7 byte by-val arg requires 4,
      // 2 and 1 byte loads.
      const unsigned ResidueBytes = ByValSize % PtrByteSize;
      assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
             "Unexpected register residue for by-value argument.");
      SDValue ResidueVal;
      for (unsigned Bytes = 0; Bytes != ResidueBytes;) {
        const unsigned N = llvm::bit_floor(ResidueBytes - Bytes);
        const MVT VT =
            N == 1 ? MVT::i8
                   : ((N == 2) ? MVT::i16 : (N == 4 ? MVT::i32 : MVT::i64));
        SDValue Load = GetLoad(VT, LoadOffset);
        MemOpChains.push_back(Load.getValue(1));
        LoadOffset += N;
        Bytes += N;

        // By-val arguments are passed left-justfied in register.
        // Every load here needs to be shifted, otherwise a full register load
        // should have been used.
        assert(PtrVT.getSimpleVT().getSizeInBits() > (Bytes * 8) &&
               "Unexpected load emitted during handling of pass-by-value "
               "argument.");
        unsigned NumSHLBits = PtrVT.getSimpleVT().getSizeInBits() - (Bytes * 8);
        EVT ShiftAmountTy =
            getShiftAmountTy(Load->getValueType(0), DAG.getDataLayout());
        SDValue SHLAmt = DAG.getConstant(NumSHLBits, dl, ShiftAmountTy);
        SDValue ShiftedLoad =
            DAG.getNode(ISD::SHL, dl, Load.getValueType(), Load, SHLAmt);
        ResidueVal = ResidueVal ? DAG.getNode(ISD::OR, dl, PtrVT, ResidueVal,
                                              ShiftedLoad)
                                : ShiftedLoad;
      }

      const CCValAssign &ByValVA = ArgLocs[I++];
      RegsToPass.push_back(std::make_pair(ByValVA.getLocReg(), ResidueVal));
      continue;
    }

    CCValAssign &VA = ArgLocs[I++];
    const MVT LocVT = VA.getLocVT();
    const MVT ValVT = VA.getValVT();

    switch (VA.getLocInfo()) {
    default:
      report_fatal_error("Unexpected argument extension type.");
    case CCValAssign::Full:
      break;
    case CCValAssign::ZExt:
      Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
      break;
    case CCValAssign::SExt:
      Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
      break;
    }

    if (VA.isRegLoc() && !VA.needsCustom()) {
      RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
      continue;
    }

    // Vector arguments passed to VarArg functions need custom handling when
    // they are passed (at least partially) in GPRs.
    if (VA.isMemLoc() && VA.needsCustom() && ValVT.isVector()) {
      assert(CFlags.IsVarArg && "Custom MemLocs only used for Vector args.");
      // Store value to its stack slot.
      SDValue PtrOff =
          DAG.getConstant(VA.getLocMemOffset(), dl, StackPtr.getValueType());
      PtrOff = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr, PtrOff);
      SDValue Store =
          DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
      MemOpChains.push_back(Store);
      const unsigned OriginalValNo = VA.getValNo();
      // Then load the GPRs from the stack
      unsigned LoadOffset = 0;
      auto HandleCustomVecRegLoc = [&]() {
        assert(I != E && "Unexpected end of CCvalAssigns.");
        assert(ArgLocs[I].isRegLoc() && ArgLocs[I].needsCustom() &&
               "Expected custom RegLoc.");
        CCValAssign RegVA = ArgLocs[I++];
        assert(RegVA.getValNo() == OriginalValNo &&
               "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
        SDValue Add = DAG.getNode(ISD::ADD, dl, PtrVT, PtrOff,
                                  DAG.getConstant(LoadOffset, dl, PtrVT));
        SDValue Load = DAG.getLoad(PtrVT, dl, Store, Add, MachinePointerInfo());
        MemOpChains.push_back(Load.getValue(1));
        RegsToPass.push_back(std::make_pair(RegVA.getLocReg(), Load));
        LoadOffset += PtrByteSize;
      };

      // In 64-bit there will be exactly 2 custom RegLocs that follow, and in
      // in 32-bit there will be 2 custom RegLocs if we are passing in R9 and
      // R10.
      HandleCustomVecRegLoc();
      HandleCustomVecRegLoc();

      if (I != E && ArgLocs[I].isRegLoc() && ArgLocs[I].needsCustom() &&
          ArgLocs[I].getValNo() == OriginalValNo) {
        assert(!IsPPC64 &&
               "Only 2 custom RegLocs expected for 64-bit codegen.");
        HandleCustomVecRegLoc();
        HandleCustomVecRegLoc();
      }

      continue;
    }

    if (VA.isMemLoc()) {
      SDValue PtrOff =
          DAG.getConstant(VA.getLocMemOffset(), dl, StackPtr.getValueType());
      PtrOff = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr, PtrOff);
      MemOpChains.push_back(
          DAG.getStore(Chain, dl, Arg, PtrOff,
                       MachinePointerInfo::getStack(MF, VA.getLocMemOffset()),
                       Subtarget.getFrameLowering()->getStackAlign()));

      continue;
    }

    if (!ValVT.isFloatingPoint())
      report_fatal_error(
          "Unexpected register handling for calling convention.");

    // Custom handling is used for GPR initializations for vararg float
    // arguments.
    assert(VA.isRegLoc() && VA.needsCustom() && CFlags.IsVarArg &&
           LocVT.isInteger() &&
           "Custom register handling only expected for VarArg.");

    SDValue ArgAsInt =
        DAG.getBitcast(MVT::getIntegerVT(ValVT.getSizeInBits()), Arg);

    if (Arg.getValueType().getStoreSize() == LocVT.getStoreSize())
      // f32 in 32-bit GPR
      // f64 in 64-bit GPR
      RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgAsInt));
    else if (Arg.getValueType().getFixedSizeInBits() <
             LocVT.getFixedSizeInBits())
      // f32 in 64-bit GPR.
      RegsToPass.push_back(std::make_pair(
          VA.getLocReg(), DAG.getZExtOrTrunc(ArgAsInt, dl, LocVT)));
    else {
      // f64 in two 32-bit GPRs
      // The 2 GPRs are marked custom and expected to be adjacent in ArgLocs.
      assert(Arg.getValueType() == MVT::f64 && CFlags.IsVarArg && !IsPPC64 &&
             "Unexpected custom register for argument!");
      CCValAssign &GPR1 = VA;
      SDValue MSWAsI64 = DAG.getNode(ISD::SRL, dl, MVT::i64, ArgAsInt,
                                     DAG.getConstant(32, dl, MVT::i8));
      RegsToPass.push_back(std::make_pair(
          GPR1.getLocReg(), DAG.getZExtOrTrunc(MSWAsI64, dl, MVT::i32)));

      if (I != E) {
        // If only 1 GPR was available, there will only be one custom GPR and
        // the argument will also pass in memory.
        CCValAssign &PeekArg = ArgLocs[I];
        if (PeekArg.isRegLoc() && PeekArg.getValNo() == PeekArg.getValNo()) {
          assert(PeekArg.needsCustom() && "A second custom GPR is expected.");
          CCValAssign &GPR2 = ArgLocs[I++];
          RegsToPass.push_back(std::make_pair(
              GPR2.getLocReg(), DAG.getZExtOrTrunc(ArgAsInt, dl, MVT::i32)));
        }
      }
    }
  }

  if (!MemOpChains.empty())
    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);

  // For indirect calls, we need to save the TOC base to the stack for
  // restoration after the call.
  if (CFlags.IsIndirect) {
    assert(!CFlags.IsTailCall && "Indirect tail-calls not supported.");
    const MCRegister TOCBaseReg = Subtarget.getTOCPointerRegister();
    const MCRegister StackPtrReg = Subtarget.getStackPointerRegister();
    const MVT PtrVT = Subtarget.getScalarIntVT();
    const unsigned TOCSaveOffset =
        Subtarget.getFrameLowering()->getTOCSaveOffset();

    setUsesTOCBasePtr(DAG);
    SDValue Val = DAG.getCopyFromReg(Chain, dl, TOCBaseReg, PtrVT);
    SDValue PtrOff = DAG.getIntPtrConstant(TOCSaveOffset, dl);
    SDValue StackPtr = DAG.getRegister(StackPtrReg, PtrVT);
    SDValue AddPtr = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr, PtrOff);
    Chain = DAG.getStore(
        Val.getValue(1), dl, Val, AddPtr,
        MachinePointerInfo::getStack(DAG.getMachineFunction(), TOCSaveOffset));
  }

  // Build a sequence of copy-to-reg nodes chained together with token chain
  // and flag operands which copy the outgoing args into the appropriate regs.
  SDValue InGlue;
  for (auto Reg : RegsToPass) {
    Chain = DAG.getCopyToReg(Chain, dl, Reg.first, Reg.second, InGlue);
    InGlue = Chain.getValue(1);
  }

  const int SPDiff = 0;
  return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
                    Callee, SPDiff, NumBytes, Ins, InVals, CB);
}

bool
PPCTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
                                  MachineFunction &MF, bool isVarArg,
                                  const SmallVectorImpl<ISD::OutputArg> &Outs,
                                  LLVMContext &Context,
                                  const Type *RetTy) const {
  SmallVector<CCValAssign, 16> RVLocs;
  CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
  return CCInfo.CheckReturn(
      Outs, (Subtarget.isSVR4ABI() && CallConv == CallingConv::Cold)
                ? RetCC_PPC_Cold
                : RetCC_PPC);
}

SDValue
PPCTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
                               bool isVarArg,
                               const SmallVectorImpl<ISD::OutputArg> &Outs,
                               const SmallVectorImpl<SDValue> &OutVals,
                               const SDLoc &dl, SelectionDAG &DAG) const {
  SmallVector<CCValAssign, 16> RVLocs;
  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
                 *DAG.getContext());
  CCInfo.AnalyzeReturn(Outs,
                       (Subtarget.isSVR4ABI() && CallConv == CallingConv::Cold)
                           ? RetCC_PPC_Cold
                           : RetCC_PPC);

  SDValue Glue;
  SmallVector<SDValue, 4> RetOps(1, Chain);

  // Copy the result values into the output registers.
  for (unsigned i = 0, RealResIdx = 0; i != RVLocs.size(); ++i, ++RealResIdx) {
    CCValAssign &VA = RVLocs[i];
    assert(VA.isRegLoc() && "Can only return in registers!");

    SDValue Arg = OutVals[RealResIdx];

    switch (VA.getLocInfo()) {
    default: llvm_unreachable("Unknown loc info!");
    case CCValAssign::Full: break;
    case CCValAssign::AExt:
      Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
      break;
    case CCValAssign::ZExt:
      Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
      break;
    case CCValAssign::SExt:
      Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
      break;
    }
    if (Subtarget.hasSPE() && VA.getLocVT() == MVT::f64) {
      bool isLittleEndian = Subtarget.isLittleEndian();
      // Legalize ret f64 -> ret 2 x i32.
      SDValue SVal =
          DAG.getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
                      DAG.getIntPtrConstant(isLittleEndian ? 0 : 1, dl));
      Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), SVal, Glue);
      RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
      SVal = DAG.getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
                         DAG.getIntPtrConstant(isLittleEndian ? 1 : 0, dl));
      Glue = Chain.getValue(1);
      VA = RVLocs[++i]; // skip ahead to next loc
      Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), SVal, Glue);
    } else
      Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), Arg, Glue);
    Glue = Chain.getValue(1);
    RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
  }

  RetOps[0] = Chain;  // Update chain.

  // Add the glue if we have it.
  if (Glue.getNode())
    RetOps.push_back(Glue);

  return DAG.getNode(PPCISD::RET_GLUE, dl, MVT::Other, RetOps);
}

SDValue
PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(SDValue Op,
                                                SelectionDAG &DAG) const {
  SDLoc dl(Op);

  // Get the correct type for integers.
  EVT IntVT = Op.getValueType();

  // Get the inputs.
  SDValue Chain = Op.getOperand(0);
  SDValue FPSIdx = getFramePointerFrameIndex(DAG);
  // Build a DYNAREAOFFSET node.
  SDValue Ops[2] = {Chain, FPSIdx};
  SDVTList VTs = DAG.getVTList(IntVT);
  return DAG.getNode(PPCISD::DYNAREAOFFSET, dl, VTs, Ops);
}

SDValue PPCTargetLowering::LowerSTACKRESTORE(SDValue Op,
                                             SelectionDAG &DAG) const {
  // When we pop the dynamic allocation we need to restore the SP link.
  SDLoc dl(Op);

  // Get the correct type for pointers.
  EVT PtrVT = getPointerTy(DAG.getDataLayout());

  // Construct the stack pointer operand.
  bool isPPC64 = Subtarget.isPPC64();
  unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
  SDValue StackPtr = DAG.getRegister(SP, PtrVT);

  // Get the operands for the STACKRESTORE.
  SDValue Chain = Op.getOperand(0);
  SDValue SaveSP = Op.getOperand(1);

  // Load the old link SP.
  SDValue LoadLinkSP =
      DAG.getLoad(PtrVT, dl, Chain, StackPtr, MachinePointerInfo());

  // Restore the stack pointer.
  Chain = DAG.getCopyToReg(LoadLinkSP.getValue(1), dl, SP, SaveSP);

  // Store the old link SP.
  return DAG.getStore(Chain, dl, LoadLinkSP, StackPtr, MachinePointerInfo());
}

SDValue PPCTargetLowering::getReturnAddrFrameIndex(SelectionDAG &DAG) const {
  MachineFunction &MF = DAG.getMachineFunction();
  bool isPPC64 = Subtarget.isPPC64();
  EVT PtrVT = getPointerTy(MF.getDataLayout());

  // Get current frame pointer save index.  The users of this index will be
  // primarily DYNALLOC instructions.
  PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
  int RASI = FI->getReturnAddrSaveIndex();

  // If the frame pointer save index hasn't been defined yet.
  if (!RASI) {
    // Find out what the fix offset of the frame pointer save area.
    int LROffset = Subtarget.getFrameLowering()->getReturnSaveOffset();
    // Allocate the frame index for frame pointer save area.
    RASI = MF.getFrameInfo().CreateFixedObject(isPPC64? 8 : 4, LROffset, false);
    // Save the result.
    FI->setReturnAddrSaveIndex(RASI);
  }
  return DAG.getFrameIndex(RASI, PtrVT);
}

SDValue
PPCTargetLowering::getFramePointerFrameIndex(SelectionDAG & DAG) const {
  MachineFunction &MF = DAG.getMachineFunction();
  bool isPPC64 = Subtarget.isPPC64();
  EVT PtrVT = getPointerTy(MF.getDataLayout());

  // Get current frame pointer save index.  The users of this index will be
  // primarily DYNALLOC instructions.
  PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
  int FPSI = FI->getFramePointerSaveIndex();

  // If the frame pointer save index hasn't been defined yet.
  if (!FPSI) {
    // Find out what the fix offset of the frame pointer save area.
    int FPOffset = Subtarget.getFrameLowering()->getFramePointerSaveOffset();
    // Allocate the frame index for frame pointer save area.
    FPSI = MF.getFrameInfo().CreateFixedObject(isPPC64? 8 : 4, FPOffset, true);
    // Save the result.
    FI->setFramePointerSaveIndex(FPSI);
  }
  return DAG.getFrameIndex(FPSI, PtrVT);
}

SDValue PPCTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
                                                   SelectionDAG &DAG) const {
  MachineFunction &MF = DAG.getMachineFunction();
  // Get the inputs.
  SDValue Chain = Op.getOperand(0);
  SDValue Size  = Op.getOperand(1);
  SDLoc dl(Op);

  // Get the correct type for pointers.
  EVT PtrVT = getPointerTy(DAG.getDataLayout());
  // Negate the size.
  SDValue NegSize = DAG.getNode(ISD::SUB, dl, PtrVT,
                                DAG.getConstant(0, dl, PtrVT), Size);
  // Construct a node for the frame pointer save index.
  SDValue FPSIdx = getFramePointerFrameIndex(DAG);
  SDValue Ops[3] = { Chain, NegSize, FPSIdx };
  SDVTList VTs = DAG.getVTList(PtrVT, MVT::Other);
  if (hasInlineStackProbe(MF))
    return DAG.getNode(PPCISD::PROBED_ALLOCA, dl, VTs, Ops);
  return DAG.getNode(PPCISD::DYNALLOC, dl, VTs, Ops);
}

SDValue PPCTargetLowering::LowerEH_DWARF_CFA(SDValue Op,
                                                     SelectionDAG &DAG) const {
  MachineFunction &MF = DAG.getMachineFunction();

  bool isPPC64 = Subtarget.isPPC64();
  EVT PtrVT = getPointerTy(DAG.getDataLayout());

  int FI = MF.getFrameInfo().CreateFixedObject(isPPC64 ? 8 : 4, 0, false);
  return DAG.getFrameIndex(FI, PtrVT);
}

SDValue PPCTargetLowering::lowerEH_SJLJ_SETJMP(SDValue Op,
                                               SelectionDAG &DAG) const {
  SDLoc DL(Op);
  return DAG.getNode(PPCISD::EH_SJLJ_SETJMP, DL,
                     DAG.getVTList(MVT::i32, MVT::Other),
                     Op.getOperand(0), Op.getOperand(1));
}

SDValue PPCTargetLowering::lowerEH_SJLJ_LONGJMP(SDValue Op,
                                                SelectionDAG &DAG) const {
  SDLoc DL(Op);
  return DAG.getNode(PPCISD::EH_SJLJ_LONGJMP, DL, MVT::Other,
                     Op.getOperand(0), Op.getOperand(1));
}

SDValue PPCTargetLowering::LowerLOAD(SDValue Op, SelectionDAG &DAG) const {
  if (Op.getValueType().isVector())
    return LowerVectorLoad(Op, DAG);

  assert(Op.getValueType() == MVT::i1 &&
         "Custom lowering only for i1 loads");

  // First, load 8 bits into 32 bits, then truncate to 1 bit.

  SDLoc dl(Op);
  LoadSDNode *LD = cast<LoadSDNode>(Op);

  SDValue Chain = LD->getChain();
  SDValue BasePtr = LD->getBasePtr();
  MachineMemOperand *MMO = LD->getMemOperand();

  SDValue NewLD =
      DAG.getExtLoad(ISD::EXTLOAD, dl, getPointerTy(DAG.getDataLayout()), Chain,
                     BasePtr, MVT::i8, MMO);
  SDValue Result = DAG.getNode(ISD::TRUNCATE, dl, MVT::i1, NewLD);

  SDValue Ops[] = { Result, SDValue(NewLD.getNode(), 1) };
  return DAG.getMergeValues(Ops, dl);
}

SDValue PPCTargetLowering::LowerSTORE(SDValue Op, SelectionDAG &DAG) const {
  if (Op.getOperand(1).getValueType().isVector())
    return LowerVectorStore(Op, DAG);

  assert(Op.getOperand(1).getValueType() == MVT::i1 &&
         "Custom lowering only for i1 stores");

  // First, zero extend to 32 bits, then use a truncating store to 8 bits.

  SDLoc dl(Op);
  StoreSDNode *ST = cast<StoreSDNode>(Op);

  SDValue Chain = ST->getChain();
  SDValue BasePtr = ST->getBasePtr();
  SDValue Value = ST->getValue();
  MachineMemOperand *MMO = ST->getMemOperand();

  Value = DAG.getNode(ISD::ZERO_EXTEND, dl, getPointerTy(DAG.getDataLayout()),
                      Value);
  return DAG.getTruncStore(Chain, dl, Value, BasePtr, MVT::i8, MMO);
}

// FIXME: Remove this once the ANDI glue bug is fixed:
SDValue PPCTargetLowering::LowerTRUNCATE(SDValue Op, SelectionDAG &DAG) const {
  assert(Op.getValueType() == MVT::i1 &&
         "Custom lowering only for i1 results");

  SDLoc DL(Op);
  return DAG.getNode(PPCISD::ANDI_rec_1_GT_BIT, DL, MVT::i1, Op.getOperand(0));
}

SDValue PPCTargetLowering::LowerTRUNCATEVector(SDValue Op,
                                               SelectionDAG &DAG) const {

  // Implements a vector truncate that fits in a vector register as a shuffle.
  // We want to legalize vector truncates down to where the source fits in
  // a vector register (and target is therefore smaller than vector register
  // size).  At that point legalization will try to custom lower the sub-legal
  // result and get here - where we can contain the truncate as a single target
  // operation.

  // For example a trunc <2 x i16> to <2 x i8> could be visualized as follows:
  //   <MSB1|LSB1, MSB2|LSB2> to <LSB1, LSB2>
  //
  // We will implement it for big-endian ordering as this (where x denotes
  // undefined):
  //   < MSB1|LSB1, MSB2|LSB2, uu, uu, uu, uu, uu, uu> to
  //   < LSB1, LSB2, u, u, u, u, u, u, u, u, u, u, u, u, u, u>
  //
  // The same operation in little-endian ordering will be:
  //   <uu, uu, uu, uu, uu, uu, LSB2|MSB2, LSB1|MSB1> to
  //   <u, u, u, u, u, u, u, u, u, u, u, u, u, u, LSB2, LSB1>

  EVT TrgVT = Op.getValueType();
  assert(TrgVT.isVector() && "Vector type expected.");
  unsigned TrgNumElts = TrgVT.getVectorNumElements();
  EVT EltVT = TrgVT.getVectorElementType();
  if (!isOperationCustom(Op.getOpcode(), TrgVT) ||
      TrgVT.getSizeInBits() > 128 || !isPowerOf2_32(TrgNumElts) ||
      !llvm::has_single_bit<uint32_t>(EltVT.getSizeInBits()))
    return SDValue();

  SDValue N1 = Op.getOperand(0);
  EVT SrcVT = N1.getValueType();  
  unsigned SrcSize = SrcVT.getSizeInBits();
  if (SrcSize > 256 || !isPowerOf2_32(SrcVT.getVectorNumElements()) ||
      !llvm::has_single_bit<uint32_t>(
          SrcVT.getVectorElementType().getSizeInBits()))
    return SDValue();
  if (SrcSize == 256 && SrcVT.getVectorNumElements() < 2)
    return SDValue();

  unsigned WideNumElts = 128 / EltVT.getSizeInBits();
  EVT WideVT = EVT::getVectorVT(*DAG.getContext(), EltVT, WideNumElts);

  SDLoc DL(Op);
  SDValue Op1, Op2;
  if (SrcSize == 256) {
    EVT VecIdxTy = getVectorIdxTy(DAG.getDataLayout());
    EVT SplitVT =
        N1.getValueType().getHalfNumVectorElementsVT(*DAG.getContext());
    unsigned SplitNumElts = SplitVT.getVectorNumElements();
    Op1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SplitVT, N1,
                      DAG.getConstant(0, DL, VecIdxTy));
    Op2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SplitVT, N1,
                      DAG.getConstant(SplitNumElts, DL, VecIdxTy));
  }
  else {
    Op1 = SrcSize == 128 ? N1 : widenVec(DAG, N1, DL);
    Op2 = DAG.getUNDEF(WideVT);
  }

  // First list the elements we want to keep.
  unsigned SizeMult = SrcSize / TrgVT.getSizeInBits();
  SmallVector<int, 16> ShuffV;
  if (Subtarget.isLittleEndian())
    for (unsigned i = 0; i < TrgNumElts; ++i)
      ShuffV.push_back(i * SizeMult);
  else
    for (unsigned i = 1; i <= TrgNumElts; ++i)
      ShuffV.push_back(i * SizeMult - 1);

  // Populate the remaining elements with undefs.
  for (unsigned i = TrgNumElts; i < WideNumElts; ++i)
    // ShuffV.push_back(i + WideNumElts);
    ShuffV.push_back(WideNumElts + 1);

  Op1 = DAG.getNode(ISD::BITCAST, DL, WideVT, Op1);
  Op2 = DAG.getNode(ISD::BITCAST, DL, WideVT, Op2);
  return DAG.getVectorShuffle(WideVT, DL, Op1, Op2, ShuffV);
}

/// LowerSELECT_CC - Lower floating point select_cc's into fsel instruction when
/// possible.
SDValue PPCTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
  EVT ResVT = Op.getValueType();
  EVT CmpVT = Op.getOperand(0).getValueType();
  SDValue LHS = Op.getOperand(0), RHS = Op.getOperand(1);
  SDValue TV  = Op.getOperand(2), FV  = Op.getOperand(3);
  SDLoc dl(Op);

  // Without power9-vector, we don't have native instruction for f128 comparison.
  // Following transformation to libcall is needed for setcc:
  // select_cc lhs, rhs, tv, fv, cc -> select_cc (setcc cc, x, y), 0, tv, fv, NE
  if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
    SDValue Z = DAG.getSetCC(
        dl, getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), CmpVT),
        LHS, RHS, CC);
    SDValue Zero = DAG.getConstant(0, dl, Z.getValueType());
    return DAG.getSelectCC(dl, Z, Zero, TV, FV, ISD::SETNE);
  }

  // Not FP, or using SPE? Not a fsel.
  if (!CmpVT.isFloatingPoint() || !TV.getValueType().isFloatingPoint() ||
      Subtarget.hasSPE())
    return Op;

  SDNodeFlags Flags = Op.getNode()->getFlags();

  // We have xsmaxc[dq]p/xsminc[dq]p which are OK to emit even in the
  // presence of infinities.
  if (Subtarget.hasP9Vector() && LHS == TV && RHS == FV) {
    switch (CC) {
    default:
      break;
    case ISD::SETOGT:
    case ISD::SETGT:
      return DAG.getNode(PPCISD::XSMAXC, dl, Op.getValueType(), LHS, RHS);
    case ISD::SETOLT:
    case ISD::SETLT:
      return DAG.getNode(PPCISD::XSMINC, dl, Op.getValueType(), LHS, RHS);
    }
  }

  // We might be able to do better than this under some circumstances, but in
  // general, fsel-based lowering of select is a finite-math-only optimization.
  // For more information, see section F.3 of the 2.06 ISA specification.
  // With ISA 3.0
  if ((!DAG.getTarget().Options.NoInfsFPMath && !Flags.hasNoInfs()) ||
      (!DAG.getTarget().Options.NoNaNsFPMath && !Flags.hasNoNaNs()) ||
      ResVT == MVT::f128)
    return Op;

  // If the RHS of the comparison is a 0.0, we don't need to do the
  // subtraction at all.
  SDValue Sel1;
  if (isFloatingPointZero(RHS))
    switch (CC) {
    default: break;       // SETUO etc aren't handled by fsel.
    case ISD::SETNE:
      std::swap(TV, FV);
      [[fallthrough]];
    case ISD::SETEQ:
      if (LHS.getValueType() == MVT::f32)   // Comparison is always 64-bits
        LHS = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, LHS);
      Sel1 = DAG.getNode(PPCISD::FSEL, dl, ResVT, LHS, TV, FV);
      if (Sel1.getValueType() == MVT::f32)   // Comparison is always 64-bits
        Sel1 = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Sel1);
      return DAG.getNode(PPCISD::FSEL, dl, ResVT,
                         DAG.getNode(ISD::FNEG, dl, MVT::f64, LHS), Sel1, FV);
    case ISD::SETULT:
    case ISD::SETLT:
      std::swap(TV, FV);  // fsel is natively setge, swap operands for setlt
      [[fallthrough]];
    case ISD::SETOGE:
    case ISD::SETGE:
      if (LHS.getValueType() == MVT::f32)   // Comparison is always 64-bits
        LHS = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, LHS);
      return DAG.getNode(PPCISD::FSEL, dl, ResVT, LHS, TV, FV);
    case ISD::SETUGT:
    case ISD::SETGT:
      std::swap(TV, FV);  // fsel is natively setge, swap operands for setlt
      [[fallthrough]];
    case ISD::SETOLE:
    case ISD::SETLE:
      if (LHS.getValueType() == MVT::f32)   // Comparison is always 64-bits
        LHS = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, LHS);
      return DAG.getNode(PPCISD::FSEL, dl, ResVT,
                         DAG.getNode(ISD::FNEG, dl, MVT::f64, LHS), TV, FV);
    }

  SDValue Cmp;
  switch (CC) {
  default: break;       // SETUO etc aren't handled by fsel.
  case ISD::SETNE:
    std::swap(TV, FV);
    [[fallthrough]];
  case ISD::SETEQ:
    Cmp = DAG.getNode(ISD::FSUB, dl, CmpVT, LHS, RHS, Flags);
    if (Cmp.getValueType() == MVT::f32)   // Comparison is always 64-bits
      Cmp = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
    Sel1 = DAG.getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
    if (Sel1.getValueType() == MVT::f32)   // Comparison is always 64-bits
      Sel1 = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Sel1);
    return DAG.getNode(PPCISD::FSEL, dl, ResVT,
                       DAG.getNode(ISD::FNEG, dl, MVT::f64, Cmp), Sel1, FV);
  case ISD::SETULT:
  case ISD::SETLT:
    Cmp = DAG.getNode(ISD::FSUB, dl, CmpVT, LHS, RHS, Flags);
    if (Cmp.getValueType() == MVT::f32)   // Comparison is always 64-bits
      Cmp = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
    return DAG.getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
  case ISD::SETOGE:
  case ISD::SETGE:
    Cmp = DAG.getNode(ISD::FSUB, dl, CmpVT, LHS, RHS, Flags);
    if (Cmp.getValueType() == MVT::f32)   // Comparison is always 64-bits
      Cmp = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
    return DAG.getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
  case ISD::SETUGT:
  case ISD::SETGT:
    Cmp = DAG.getNode(ISD::FSUB, dl, CmpVT, RHS, LHS, Flags);
    if (Cmp.getValueType() == MVT::f32)   // Comparison is always 64-bits
      Cmp = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
    return DAG.getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
  case ISD::SETOLE:
  case ISD::SETLE:
    Cmp = DAG.getNode(ISD::FSUB, dl, CmpVT, RHS, LHS, Flags);
    if (Cmp.getValueType() == MVT::f32)   // Comparison is always 64-bits
      Cmp = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
    return DAG.getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
  }
  return Op;
}

static unsigned getPPCStrictOpcode(unsigned Opc) {
  switch (Opc) {
  default:
    llvm_unreachable("No strict version of this opcode!");
  case PPCISD::FCTIDZ:
    return PPCISD::STRICT_FCTIDZ;
  case PPCISD::FCTIWZ:
    return PPCISD::STRICT_FCTIWZ;
  case PPCISD::FCTIDUZ:
    return PPCISD::STRICT_FCTIDUZ;
  case PPCISD::FCTIWUZ:
    return PPCISD::STRICT_FCTIWUZ;
  case PPCISD::FCFID:
    return PPCISD::STRICT_FCFID;
  case PPCISD::FCFIDU:
    return PPCISD::STRICT_FCFIDU;
  case PPCISD::FCFIDS:
    return PPCISD::STRICT_FCFIDS;
  case PPCISD::FCFIDUS:
    return PPCISD::STRICT_FCFIDUS;
  }
}

static SDValue convertFPToInt(SDValue Op, SelectionDAG &DAG,
                              const PPCSubtarget &Subtarget) {
  SDLoc dl(Op);
  bool IsStrict = Op->isStrictFPOpcode();
  bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT ||
                  Op.getOpcode() == ISD::STRICT_FP_TO_SINT;

  // TODO: Any other flags to propagate?
  SDNodeFlags Flags;
  Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept());

  // For strict nodes, source is the second operand.
  SDValue Src = Op.getOperand(IsStrict ? 1 : 0);
  SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
  MVT DestTy = Op.getSimpleValueType();
  assert(Src.getValueType().isFloatingPoint() &&
         (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
          DestTy == MVT::i64) &&
         "Invalid FP_TO_INT types");
  if (Src.getValueType() == MVT::f32) {
    if (IsStrict) {
      Src =
          DAG.getNode(ISD::STRICT_FP_EXTEND, dl,
                      DAG.getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
      Chain = Src.getValue(1);
    } else
      Src = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Src);
  }
  if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
    DestTy = Subtarget.getScalarIntVT();
  unsigned Opc = ISD::DELETED_NODE;
  switch (DestTy.SimpleTy) {
  default: llvm_unreachable("Unhandled FP_TO_INT type in custom expander!");
  case MVT::i32:
    Opc = IsSigned ? PPCISD::FCTIWZ
                   : (Subtarget.hasFPCVT() ? PPCISD::FCTIWUZ : PPCISD::FCTIDZ);
    break;
  case MVT::i64:
    assert((IsSigned || Subtarget.hasFPCVT()) &&
           "i64 FP_TO_UINT is supported only with FPCVT");
    Opc = IsSigned ? PPCISD::FCTIDZ : PPCISD::FCTIDUZ;
  }
  EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
  SDValue Conv;
  if (IsStrict) {
    Opc = getPPCStrictOpcode(Opc);
    Conv = DAG.getNode(Opc, dl, DAG.getVTList(ConvTy, MVT::Other), {Chain, Src},
                       Flags);
  } else {
    Conv = DAG.getNode(Opc, dl, ConvTy, Src);
  }
  return Conv;
}

void PPCTargetLowering::LowerFP_TO_INTForReuse(SDValue Op, ReuseLoadInfo &RLI,
                                               SelectionDAG &DAG,
                                               const SDLoc &dl) const {
  SDValue Tmp = convertFPToInt(Op, DAG, Subtarget);
  bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT ||
                  Op.getOpcode() == ISD::STRICT_FP_TO_SINT;
  bool IsStrict = Op->isStrictFPOpcode();

  // Convert the FP value to an int value through memory.
  bool i32Stack = Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
                  (IsSigned || Subtarget.hasFPCVT());
  SDValue FIPtr = DAG.CreateStackTemporary(i32Stack ? MVT::i32 : MVT::f64);
  int FI = cast<FrameIndexSDNode>(FIPtr)->getIndex();
  MachinePointerInfo MPI =
      MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI);

  // Emit a store to the stack slot.
  SDValue Chain = IsStrict ? Tmp.getValue(1) : DAG.getEntryNode();
  Align Alignment(DAG.getEVTAlign(Tmp.getValueType()));
  if (i32Stack) {
    MachineFunction &MF = DAG.getMachineFunction();
    Alignment = Align(4);
    MachineMemOperand *MMO =
        MF.getMachineMemOperand(MPI, MachineMemOperand::MOStore, 4, Alignment);
    SDValue Ops[] = { Chain, Tmp, FIPtr };
    Chain = DAG.getMemIntrinsicNode(PPCISD::STFIWX, dl,
              DAG.getVTList(MVT::Other), Ops, MVT::i32, MMO);
  } else
    Chain = DAG.getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);

  // Result is a load from the stack slot.  If loading 4 bytes, make sure to
  // add in a bias on big endian.
  if (Op.getValueType() == MVT::i32 && !i32Stack &&
      !Subtarget.isLittleEndian()) {
    FIPtr = DAG.getNode(ISD::ADD, dl, FIPtr.getValueType(), FIPtr,
                        DAG.getConstant(4, dl, FIPtr.getValueType()));
    MPI = MPI.getWithOffset(4);
  }

  RLI.Chain = Chain;
  RLI.Ptr = FIPtr;
  RLI.MPI = MPI;
  RLI.Alignment = Alignment;
}

/// Custom lowers floating point to integer conversions to use
/// the direct move instructions available in ISA 2.07 to avoid the
/// need for load/store combinations.
SDValue PPCTargetLowering::LowerFP_TO_INTDirectMove(SDValue Op,
                                                    SelectionDAG &DAG,
                                                    const SDLoc &dl) const {
  SDValue Conv = convertFPToInt(Op, DAG, Subtarget);
  SDValue Mov = DAG.getNode(PPCISD::MFVSR, dl, Op.getValueType(), Conv);
  if (Op->isStrictFPOpcode())
    return DAG.getMergeValues({Mov, Conv.getValue(1)}, dl);
  else
    return Mov;
}

SDValue PPCTargetLowering::LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG,
                                          const SDLoc &dl) const {
  bool IsStrict = Op->isStrictFPOpcode();
  bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT ||
                  Op.getOpcode() == ISD::STRICT_FP_TO_SINT;
  SDValue Src = Op.getOperand(IsStrict ? 1 : 0);
  EVT SrcVT = Src.getValueType();
  EVT DstVT = Op.getValueType();

  // FP to INT conversions are legal for f128.
  if (SrcVT == MVT::f128)
    return Subtarget.hasP9Vector() ? Op : SDValue();

  // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
  // PPC (the libcall is not available).
  if (SrcVT == MVT::ppcf128) {
    if (DstVT == MVT::i32) {
      // TODO: Conservatively pass only nofpexcept flag here. Need to check and
      // set other fast-math flags to FP operations in both strict and
      // non-strict cases. (FP_TO_SINT, FSUB)
      SDNodeFlags Flags;
      Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept());

      if (IsSigned) {
        SDValue Lo, Hi;
        std::tie(Lo, Hi) = DAG.SplitScalar(Src, dl, MVT::f64, MVT::f64);

        // Add the two halves of the long double in round-to-zero mode, and use
        // a smaller FP_TO_SINT.
        if (IsStrict) {
          SDValue Res = DAG.getNode(PPCISD::STRICT_FADDRTZ, dl,
                                    DAG.getVTList(MVT::f64, MVT::Other),
                                    {Op.getOperand(0), Lo, Hi}, Flags);
          return DAG.getNode(ISD::STRICT_FP_TO_SINT, dl,
                             DAG.getVTList(MVT::i32, MVT::Other),
                             {Res.getValue(1), Res}, Flags);
        } else {
          SDValue Res = DAG.getNode(PPCISD::FADDRTZ, dl, MVT::f64, Lo, Hi);
          return DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Res);
        }
      } else {
        const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
        APFloat APF = APFloat(APFloat::PPCDoubleDouble(), APInt(128, TwoE31));
        SDValue Cst = DAG.getConstantFP(APF, dl, SrcVT);
        SDValue SignMask = DAG.getConstant(0x80000000, dl, DstVT);
        if (IsStrict) {
          // Sel = Src < 0x80000000
          // FltOfs = select Sel, 0.0, 0x80000000
          // IntOfs = select Sel, 0, 0x80000000
          // Result = fp_to_sint(Src - FltOfs) ^ IntOfs
          SDValue Chain = Op.getOperand(0);
          EVT SetCCVT =
              getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), SrcVT);
          EVT DstSetCCVT =
              getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), DstVT);
          SDValue Sel = DAG.getSetCC(dl, SetCCVT, Src, Cst, ISD::SETLT,
                                     Chain, true);
          Chain = Sel.getValue(1);

          SDValue FltOfs = DAG.getSelect(
              dl, SrcVT, Sel, DAG.getConstantFP(0.0, dl, SrcVT), Cst);
          Sel = DAG.getBoolExtOrTrunc(Sel, dl, DstSetCCVT, DstVT);

          SDValue Val = DAG.getNode(ISD::STRICT_FSUB, dl,
                                    DAG.getVTList(SrcVT, MVT::Other),
                                    {Chain, Src, FltOfs}, Flags);
          Chain = Val.getValue(1);
          SDValue SInt = DAG.getNode(ISD::STRICT_FP_TO_SINT, dl,
                                     DAG.getVTList(DstVT, MVT::Other),
                                     {Chain, Val}, Flags);
          Chain = SInt.getValue(1);
          SDValue IntOfs = DAG.getSelect(
              dl, DstVT, Sel, DAG.getConstant(0, dl, DstVT), SignMask);
          SDValue Result = DAG.getNode(ISD::XOR, dl, DstVT, SInt, IntOfs);
          return DAG.getMergeValues({Result, Chain}, dl);
        } else {
          // X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X
          // FIXME: generated code sucks.
          SDValue True = DAG.getNode(ISD::FSUB, dl, MVT::ppcf128, Src, Cst);
          True = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, True);
          True = DAG.getNode(ISD::ADD, dl, MVT::i32, True, SignMask);
          SDValue False = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Src);
          return DAG.getSelectCC(dl, Src, Cst, True, False, ISD::SETGE);
        }
      }
    }

    return SDValue();
  }

  if (Subtarget.hasDirectMove() && Subtarget.isPPC64())
    return LowerFP_TO_INTDirectMove(Op, DAG, dl);

  ReuseLoadInfo RLI;
  LowerFP_TO_INTForReuse(Op, RLI, DAG, dl);

  return DAG.getLoad(Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
                     RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
}

// We're trying to insert a regular store, S, and then a load, L. If the
// incoming value, O, is a load, we might just be able to have our load use the
// address used by O. However, we don't know if anything else will store to
// that address before we can load from it. To prevent this situation, we need
// to insert our load, L, into the chain as a peer of O. To do this, we give L
// the same chain operand as O, we create a token factor from the chain results
// of O and L, and we replace all uses of O's chain result with that token
// factor (this last part is handled by makeEquivalentMemoryOrdering).
bool PPCTargetLowering::canReuseLoadAddress(SDValue Op, EVT MemVT,
                                            ReuseLoadInfo &RLI,
                                            SelectionDAG &DAG,
                                            ISD::LoadExtType ET) const {
  // Conservatively skip reusing for constrained FP nodes.
  if (Op->isStrictFPOpcode())
    return false;

  SDLoc dl(Op);
  bool ValidFPToUint = Op.getOpcode() == ISD::FP_TO_UINT &&
                       (Subtarget.hasFPCVT() || Op.getValueType() == MVT::i32);
  if (ET == ISD::NON_EXTLOAD &&
      (ValidFPToUint || Op.getOpcode() == ISD::FP_TO_SINT) &&
      isOperationLegalOrCustom(Op.getOpcode(),
                               Op.getOperand(0).getValueType())) {

    LowerFP_TO_INTForReuse(Op, RLI, DAG, dl);
    return true;
  }

  LoadSDNode *LD = dyn_cast<LoadSDNode>(Op);
  if (!LD || LD->getExtensionType() != ET || LD->isVolatile() ||
      LD->isNonTemporal())
    return false;
  if (LD->getMemoryVT() != MemVT)
    return false;

  // If the result of the load is an illegal type, then we can't build a
  // valid chain for reuse since the legalised loads and token factor node that
  // ties the legalised loads together uses a different output chain then the
  // illegal load.
  if (!isTypeLegal(LD->getValueType(0)))
    return false;

  RLI.Ptr = LD->getBasePtr();
  if (LD->isIndexed() && !LD->getOffset().isUndef()) {
    assert(LD->getAddressingMode() == ISD::PRE_INC &&
           "Non-pre-inc AM on PPC?");
    RLI.Ptr = DAG.getNode(ISD::ADD, dl, RLI.Ptr.getValueType(), RLI.Ptr,
                          LD->getOffset());
  }

  RLI.Chain = LD->getChain();
  RLI.MPI = LD->getPointerInfo();
  RLI.IsDereferenceable = LD->isDereferenceable();
  RLI.IsInvariant = LD->isInvariant();
  RLI.Alignment = LD->getAlign();
  RLI.AAInfo = LD->getAAInfo();
  RLI.Ranges = LD->getRanges();

  RLI.ResChain = SDValue(LD, LD->isIndexed() ? 2 : 1);
  return true;
}

/// Analyze profitability of direct move
/// prefer float load to int load plus direct move
/// when there is no integer use of int load
bool PPCTargetLowering::directMoveIsProfitable(const SDValue &Op) const {
  SDNode *Origin = Op.getOperand(Op->isStrictFPOpcode() ? 1 : 0).getNode();
  if (Origin->getOpcode() != ISD::LOAD)
    return true;

  // If there is no LXSIBZX/LXSIHZX, like Power8,
  // prefer direct move if the memory size is 1 or 2 bytes.
  MachineMemOperand *MMO = cast<LoadSDNode>(Origin)->getMemOperand();
  if (!Subtarget.hasP9Vector() &&
      (!MMO->getSize().hasValue() || MMO->getSize().getValue() <= 2))
    return true;

  for (SDUse &Use : Origin->uses()) {

    // Only look at the users of the loaded value.
    if (Use.getResNo() != 0)
      continue;

    SDNode *User = Use.getUser();
    if (User->getOpcode() != ISD::SINT_TO_FP &&
        User->getOpcode() != ISD::UINT_TO_FP &&
        User->getOpcode() != ISD::STRICT_SINT_TO_FP &&
        User->getOpcode() != ISD::STRICT_UINT_TO_FP)
      return true;
  }

  return false;
}

static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG,
                              const PPCSubtarget &Subtarget,
                              SDValue Chain = SDValue()) {
  bool IsSigned = Op.getOpcode() == ISD::SINT_TO_FP ||
                  Op.getOpcode() == ISD::STRICT_SINT_TO_FP;
  SDLoc dl(Op);

  // TODO: Any other flags to propagate?
  SDNodeFlags Flags;
  Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept());

  // If we have FCFIDS, then use it when converting to single-precision.
  // Otherwise, convert to double-precision and then round.
  bool IsSingle = Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
  unsigned ConvOpc = IsSingle ? (IsSigned ? PPCISD::FCFIDS : PPCISD::FCFIDUS)
                              : (IsSigned ? PPCISD::FCFID : PPCISD::FCFIDU);
  EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
  if (Op->isStrictFPOpcode()) {
    if (!Chain)
      Chain = Op.getOperand(0);
    return DAG.getNode(getPPCStrictOpcode(ConvOpc), dl,
                       DAG.getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
  } else
    return DAG.getNode(ConvOpc, dl, ConvTy, Src);
}

/// Custom lowers integer to floating point conversions to use
/// the direct move instructions available in ISA 2.07 to avoid the
/// need for load/store combinations.
SDValue PPCTargetLowering::LowerINT_TO_FPDirectMove(SDValue Op,
                                                    SelectionDAG &DAG,
                                                    const SDLoc &dl) const {
  assert((Op.getValueType() == MVT::f32 ||
          Op.getValueType() == MVT::f64) &&
         "Invalid floating point type as target of conversion");
  assert(Subtarget.hasFPCVT() &&
         "Int to FP conversions with direct moves require FPCVT");
  SDValue Src = Op.getOperand(Op->isStrictFPOpcode() ? 1 : 0);
  bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
  bool Signed = Op.getOpcode() == ISD::SINT_TO_FP ||
                Op.getOpcode() == ISD::STRICT_SINT_TO_FP;
  unsigned MovOpc = (WordInt && !Signed) ? PPCISD::MTVSRZ : PPCISD::MTVSRA;
  SDValue Mov = DAG.getNode(MovOpc, dl, MVT::f64, Src);
  return convertIntToFP(Op, Mov, DAG, Subtarget);
}

static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl) {

  EVT VecVT = Vec.getValueType();
  assert(VecVT.isVector() && "Expected a vector type.");
  assert(VecVT.getSizeInBits() < 128 && "Vector is already full width.");

  EVT EltVT = VecVT.getVectorElementType();
  unsigned WideNumElts = 128 / EltVT.getSizeInBits();
  EVT WideVT = EVT::getVectorVT(*DAG.getContext(), EltVT, WideNumElts);

  unsigned NumConcat = WideNumElts / VecVT.getVectorNumElements();
  SmallVector<SDValue, 16> Ops(NumConcat);
  Ops[0] = Vec;
  SDValue UndefVec = DAG.getUNDEF(VecVT);
  for (unsigned i = 1; i < NumConcat; ++i)
    Ops[i] = UndefVec;

  return DAG.getNode(ISD::CONCAT_VECTORS, dl, WideVT, Ops);
}

SDValue PPCTargetLowering::LowerINT_TO_FPVector(SDValue Op, SelectionDAG &DAG,
                                                const SDLoc &dl) const {
  bool IsStrict = Op->isStrictFPOpcode();
  unsigned Opc = Op.getOpcode();
  SDValue Src = Op.getOperand(IsStrict ? 1 : 0);
  assert((Opc == ISD::UINT_TO_FP || Opc == ISD::SINT_TO_FP ||
          Opc == ISD::STRICT_UINT_TO_FP || Opc == ISD::STRICT_SINT_TO_FP) &&
         "Unexpected conversion type");
  assert((Op.getValueType() == MVT::v2f64 || Op.getValueType() == MVT::v4f32) &&
         "Supports conversions to v2f64/v4f32 only.");

  // TODO: Any other flags to propagate?
  SDNodeFlags Flags;
  Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept());

  bool SignedConv = Opc == ISD::SINT_TO_FP || Opc == ISD::STRICT_SINT_TO_FP;
  bool FourEltRes = Op.getValueType() == MVT::v4f32;

  SDValue Wide = widenVec(DAG, Src, dl);
  EVT WideVT = Wide.getValueType();
  unsigned WideNumElts = WideVT.getVectorNumElements();
  MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;

  SmallVector<int, 16> ShuffV;
  for (unsigned i = 0; i < WideNumElts; ++i)
    ShuffV.push_back(i + WideNumElts);

  int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
  int SaveElts = FourEltRes ? 4 : 2;
  if (Subtarget.isLittleEndian())
    for (int i = 0; i < SaveElts; i++)
      ShuffV[i * Stride] = i;
  else
    for (int i = 1; i <= SaveElts; i++)
      ShuffV[i * Stride - 1] = i - 1;

  SDValue ShuffleSrc2 =
      SignedConv ? DAG.getUNDEF(WideVT) : DAG.getConstant(0, dl, WideVT);
  SDValue Arrange = DAG.getVectorShuffle(WideVT, dl, Wide, ShuffleSrc2, ShuffV);

  SDValue Extend;
  if (SignedConv) {
    Arrange = DAG.getBitcast(IntermediateVT, Arrange);
    EVT ExtVT = Src.getValueType();
    if (Subtarget.hasP9Altivec())
      ExtVT = EVT::getVectorVT(*DAG.getContext(), WideVT.getVectorElementType(),
                               IntermediateVT.getVectorNumElements());

    Extend = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, IntermediateVT, Arrange,
                         DAG.getValueType(ExtVT));
  } else
    Extend = DAG.getNode(ISD::BITCAST, dl, IntermediateVT, Arrange);

  if (IsStrict)
    return DAG.getNode(Opc, dl, DAG.getVTList(Op.getValueType(), MVT::Other),
                       {Op.getOperand(0), Extend}, Flags);

  return DAG.getNode(Opc, dl, Op.getValueType(), Extend);
}

SDValue PPCTargetLowering::LowerINT_TO_FP(SDValue Op,
                                          SelectionDAG &DAG) const {
  SDLoc dl(Op);
  bool IsSigned = Op.getOpcode() == ISD::SINT_TO_FP ||
                  Op.getOpcode() == ISD::STRICT_SINT_TO_FP;
  bool IsStrict = Op->isStrictFPOpcode();
  SDValue Src = Op.getOperand(IsStrict ? 1 : 0);
  SDValue Chain = IsStrict ? Op.getOperand(0) : DAG.getEntryNode();

  // TODO: Any other flags to propagate?
  SDNodeFlags Flags;
  Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept());

  EVT InVT = Src.getValueType();
  EVT OutVT = Op.getValueType();
  if (OutVT.isVector() && OutVT.isFloatingPoint() &&
      isOperationCustom(Op.getOpcode(), InVT))
    return LowerINT_TO_FPVector(Op, DAG, dl);

  // Conversions to f128 are legal.
  if (Op.getValueType() == MVT::f128)
    return Subtarget.hasP9Vector() ? Op : SDValue();

  // Don't handle ppc_fp128 here; let it be lowered to a libcall.
  if (Op.getValueType() != MVT::f32 && Op.getValueType() != MVT::f64)
    return SDValue();

  if (Src.getValueType() == MVT::i1) {
    SDValue Sel = DAG.getNode(ISD::SELECT, dl, Op.getValueType(), Src,
                              DAG.getConstantFP(1.0, dl, Op.getValueType()),
                              DAG.getConstantFP(0.0, dl, Op.getValueType()));
    if (IsStrict)
      return DAG.getMergeValues({Sel, Chain}, dl);
    else
      return Sel;
  }

  // If we have direct moves, we can do all the conversion, skip the store/load
  // however, without FPCVT we can't do most conversions.
  if (Subtarget.hasDirectMove() && directMoveIsProfitable(Op) &&
      Subtarget.isPPC64() && Subtarget.hasFPCVT())
    return LowerINT_TO_FPDirectMove(Op, DAG, dl);

  assert((IsSigned || Subtarget.hasFPCVT()) &&
         "UINT_TO_FP is supported only with FPCVT");

  if (Src.getValueType() == MVT::i64) {
    SDValue SINT = Src;
    // When converting to single-precision, we actually need to convert
    // to double-precision first and then round to single-precision.
    // To avoid double-rounding effects during that operation, we have
    // to prepare the input operand.  Bits that might be truncated when
    // converting to double-precision are replaced by a bit that won't
    // be lost at this stage, but is below the single-precision rounding
    // position.
    //
    // However, if afn is in effect, accept double
    // rounding to avoid the extra overhead.
    // FIXME: Currently INT_TO_FP can't support fast math flags because
    // of nneg flag, thus Op->getFlags().hasApproximateFuncs() is always
    // false.
    if (Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT() &&
        !Op->getFlags().hasApproximateFuncs()) {

      // Twiddle input to make sure the low 11 bits are zero.  (If this
      // is the case, we are guaranteed the value will fit into the 53 bit
      // mantissa of an IEEE double-precision value without rounding.)
      // If any of those low 11 bits were not zero originally, make sure
      // bit 12 (value 2048) is set instead, so that the final rounding
      // to single-precision gets the correct result.
      SDValue Round = DAG.getNode(ISD::AND, dl, MVT::i64,
                                  SINT, DAG.getConstant(2047, dl, MVT::i64));
      Round = DAG.getNode(ISD::ADD, dl, MVT::i64,
                          Round, DAG.getConstant(2047, dl, MVT::i64));
      Round = DAG.getNode(ISD::OR, dl, MVT::i64, Round, SINT);
      Round = DAG.getNode(ISD::AND, dl, MVT::i64, Round,
                          DAG.getSignedConstant(-2048, dl, MVT::i64));

      // However, we cannot use that value unconditionally: if the magnitude
      // of the input value is small, the bit-twiddling we did above might
      // end up visibly changing the output.  Fortunately, in that case, we
      // don't need to twiddle bits since the original input will convert
      // exactly to double-precision floating-point already.  Therefore,
      // construct a conditional to use the original value if the top 11
      // bits are all sign-bit copies, and use the rounded value computed
      // above otherwise.
      SDValue Cond = DAG.getNode(ISD::SRA, dl, MVT::i64,
                                 SINT, DAG.getConstant(53, dl, MVT::i32));
      Cond = DAG.getNode(ISD::ADD, dl, MVT::i64,
                         Cond, DAG.getConstant(1, dl, MVT::i64));
      Cond = DAG.getSetCC(
          dl,
          getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), MVT::i64),
          Cond, DAG.getConstant(1, dl, MVT::i64), ISD::SETUGT);

      SINT = DAG.getNode(ISD::SELECT, dl, MVT::i64, Cond, Round, SINT);
    }

    ReuseLoadInfo RLI;
    SDValue Bits;

    MachineFunction &MF = DAG.getMachineFunction();
    if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
      Bits = DAG.getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
                         RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
      if (RLI.ResChain)
        DAG.makeEquivalentMemoryOrdering(RLI.ResChain, Bits.getValue(1));
    } else if (Subtarget.hasLFIWAX() &&
               canReuseLoadAddress(SINT, MVT::i32, RLI, DAG, ISD::SEXTLOAD)) {
      MachineMemOperand *MMO =
        MF.getMachineMemOperand(RLI.MPI, MachineMemOperand::MOLoad, 4,
                                RLI.Alignment, RLI.AAInfo, RLI.Ranges);
      SDValue Ops[] = { RLI.Chain, RLI.Ptr };
      Bits = DAG.getMemIntrinsicNode(PPCISD::LFIWAX, dl,
                                     DAG.getVTList(MVT::f64, MVT::Other),
                                     Ops, MVT::i32, MMO);
      if (RLI.ResChain)
        DAG.makeEquivalentMemoryOrdering(RLI.ResChain, Bits.getValue(1));
    } else if (Subtarget.hasFPCVT() &&
               canReuseLoadAddress(SINT, MVT::i32, RLI, DAG, ISD::ZEXTLOAD)) {
      MachineMemOperand *MMO =
        MF.getMachineMemOperand(RLI.MPI, MachineMemOperand::MOLoad, 4,
                                RLI.Alignment, RLI.AAInfo, RLI.Ranges);
      SDValue Ops[] = { RLI.Chain, RLI.Ptr };
      Bits = DAG.getMemIntrinsicNode(PPCISD::LFIWZX, dl,
                                     DAG.getVTList(MVT::f64, MVT::Other),
                                     Ops, MVT::i32, MMO);
      if (RLI.ResChain)
        DAG.makeEquivalentMemoryOrdering(RLI.ResChain, Bits.getValue(1));
    } else if (((Subtarget.hasLFIWAX() &&
                 SINT.getOpcode() == ISD::SIGN_EXTEND) ||
                (Subtarget.hasFPCVT() &&
                 SINT.getOpcode() == ISD::ZERO_EXTEND)) &&
               SINT.getOperand(0).getValueType() == MVT::i32) {
      MachineFrameInfo &MFI = MF.getFrameInfo();
      EVT PtrVT = getPointerTy(DAG.getDataLayout());

      int FrameIdx = MFI.CreateStackObject(4, Align(4), false);
      SDValue FIdx = DAG.getFrameIndex(FrameIdx, PtrVT);

      SDValue Store = DAG.getStore(Chain, dl, SINT.getOperand(0), FIdx,
                                   MachinePointerInfo::getFixedStack(
                                       DAG.getMachineFunction(), FrameIdx));
      Chain = Store;

      assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
             "Expected an i32 store");

      RLI.Ptr = FIdx;
      RLI.Chain = Chain;
      RLI.MPI =
          MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FrameIdx);
      RLI.Alignment = Align(4);

      MachineMemOperand *MMO =
        MF.getMachineMemOperand(RLI.MPI, MachineMemOperand::MOLoad, 4,
                                RLI.Alignment, RLI.AAInfo, RLI.Ranges);
      SDValue Ops[] = { RLI.Chain, RLI.Ptr };
      Bits = DAG.getMemIntrinsicNode(SINT.getOpcode() == ISD::ZERO_EXTEND ?
                                     PPCISD::LFIWZX : PPCISD::LFIWAX,
                                     dl, DAG.getVTList(MVT::f64, MVT::Other),
                                     Ops, MVT::i32, MMO);
      Chain = Bits.getValue(1);
    } else
      Bits = DAG.getNode(ISD::BITCAST, dl, MVT::f64, SINT);

    SDValue FP = convertIntToFP(Op, Bits, DAG, Subtarget, Chain);
    if (IsStrict)
      Chain = FP.getValue(1);

    if (Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
      if (IsStrict)
        FP = DAG.getNode(
            ISD::STRICT_FP_ROUND, dl, DAG.getVTList(MVT::f32, MVT::Other),
            {Chain, FP, DAG.getIntPtrConstant(0, dl, /*isTarget=*/true)},
            Flags);
      else
        FP = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, FP,
                         DAG.getIntPtrConstant(0, dl, /*isTarget=*/true));
    }
    return FP;
  }

  assert(Src.getValueType() == MVT::i32 &&
         "Unhandled INT_TO_FP type in custom expander!");
  // Since we only generate this in 64-bit mode, we can take advantage of
  // 64-bit registers.  In particular, sign extend the input value into the
  // 64-bit register with extsw, store the WHOLE 64-bit value into the stack
  // then lfd it and fcfid it.
  MachineFunction &MF = DAG.getMachineFunction();
  MachineFrameInfo &MFI = MF.getFrameInfo();
  EVT PtrVT = getPointerTy(MF.getDataLayout());

  SDValue Ld;
  if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
    ReuseLoadInfo RLI;
    bool ReusingLoad;
    if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
      int FrameIdx = MFI.CreateStackObject(4, Align(4), false);
      SDValue FIdx = DAG.getFrameIndex(FrameIdx, PtrVT);

      SDValue Store = DAG.getStore(Chain, dl, Src, FIdx,
                                   MachinePointerInfo::getFixedStack(
                                       DAG.getMachineFunction(), FrameIdx));
      Chain = Store;

      assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
             "Expected an i32 store");

      RLI.Ptr = FIdx;
      RLI.Chain = Chain;
      RLI.MPI =
          MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FrameIdx);
      RLI.Alignment = Align(4);
    }

    MachineMemOperand *MMO =
      MF.getMachineMemOperand(RLI.MPI, MachineMemOperand::MOLoad, 4,
                              RLI.Alignment, RLI.AAInfo, RLI.Ranges);
    SDValue Ops[] = { RLI.Chain, RLI.Ptr };
    Ld = DAG.getMemIntrinsicNode(IsSigned ? PPCISD::LFIWAX : PPCISD::LFIWZX, dl,
                                 DAG.getVTList(MVT::f64, MVT::Other), Ops,
                                 MVT::i32, MMO);
    Chain = Ld.getValue(1);
    if (ReusingLoad && RLI.ResChain) {
      DAG.makeEquivalentMemoryOrdering(RLI.ResChain, Ld.getValue(1));
    }
  } else {
    assert(Subtarget.isPPC64() &&
           "i32->FP without LFIWAX supported only on PPC64");

    int FrameIdx = MFI.CreateStackObject(8, Align(8), false);
    SDValue FIdx = DAG.getFrameIndex(FrameIdx, PtrVT);

    SDValue Ext64 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i64, Src);

    // STD the extended value into the stack slot.
    SDValue Store = DAG.getStore(
        Chain, dl, Ext64, FIdx,
        MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FrameIdx));
    Chain = Store;

    // Load the value as a double.
    Ld = DAG.getLoad(
        MVT::f64, dl, Chain, FIdx,
        MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FrameIdx));
    Chain = Ld.getValue(1);
  }

  // FCFID it and return it.
  SDValue FP = convertIntToFP(Op, Ld, DAG, Subtarget, Chain);
  if (IsStrict)
    Chain = FP.getValue(1);
  if (Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
    if (IsStrict)
      FP = DAG.getNode(
          ISD::STRICT_FP_ROUND, dl, DAG.getVTList(MVT::f32, MVT::Other),
          {Chain, FP, DAG.getIntPtrConstant(0, dl, /*isTarget=*/true)}, Flags);
    else
      FP = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, FP,
                       DAG.getIntPtrConstant(0, dl, /*isTarget=*/true));
  }
  return FP;
}

SDValue PPCTargetLowering::LowerSET_ROUNDING(SDValue Op,
                                             SelectionDAG &DAG) const {
  SDLoc Dl(Op);
  MachineFunction &MF = DAG.getMachineFunction();
  EVT PtrVT = getPointerTy(MF.getDataLayout());
  SDValue Chain = Op.getOperand(0);

  // If requested mode is constant, just use simpler mtfsb/mffscrni
  if (auto *CVal = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
    uint64_t Mode = CVal->getZExtValue();
    assert(Mode < 4 && "Unsupported rounding mode!");
    unsigned InternalRnd = Mode ^ (~(Mode >> 1) & 1);
    if (Subtarget.isISA3_0())
      return SDValue(
          DAG.getMachineNode(
              PPC::MFFSCRNI, Dl, {MVT::f64, MVT::Other},
              {DAG.getConstant(InternalRnd, Dl, MVT::i32, true), Chain}),
          1);
    SDNode *SetHi = DAG.getMachineNode(
        (InternalRnd & 2) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
        {DAG.getConstant(30, Dl, MVT::i32, true), Chain});
    SDNode *SetLo = DAG.getMachineNode(
        (InternalRnd & 1) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
        {DAG.getConstant(31, Dl, MVT::i32, true), SDValue(SetHi, 0)});
    return SDValue(SetLo, 0);
  }

  // Use x ^ (~(x >> 1) & 1) to transform LLVM rounding mode to Power format.
  SDValue One = DAG.getConstant(1, Dl, MVT::i32);
  SDValue SrcFlag = DAG.getNode(ISD::AND, Dl, MVT::i32, Op.getOperand(1),
                                DAG.getConstant(3, Dl, MVT::i32));
  SDValue DstFlag = DAG.getNode(
      ISD::XOR, Dl, MVT::i32, SrcFlag,
      DAG.getNode(ISD::AND, Dl, MVT::i32,
                  DAG.getNOT(Dl,
                             DAG.getNode(ISD::SRL, Dl, MVT::i32, SrcFlag, One),
                             MVT::i32),
                  One));
  // For Power9, there's faster mffscrn, and we don't need to read FPSCR
  SDValue MFFS;
  if (!Subtarget.isISA3_0()) {
    MFFS = DAG.getNode(PPCISD::MFFS, Dl, {MVT::f64, MVT::Other}, Chain);
    Chain = MFFS.getValue(1);
  }
  SDValue NewFPSCR;
  if (Subtarget.isPPC64()) {
    if (Subtarget.isISA3_0()) {
      NewFPSCR = DAG.getAnyExtOrTrunc(DstFlag, Dl, MVT::i64);
    } else {
      // Set the last two bits (rounding mode) of bitcasted FPSCR.
      SDNode *InsertRN = DAG.getMachineNode(
          PPC::RLDIMI, Dl, MVT::i64,
          {DAG.getNode(ISD::BITCAST, Dl, MVT::i64, MFFS),
           DAG.getNode(ISD::ZERO_EXTEND, Dl, MVT::i64, DstFlag),
           DAG.getTargetConstant(0, Dl, MVT::i32),
           DAG.getTargetConstant(62, Dl, MVT::i32)});
      NewFPSCR = SDValue(InsertRN, 0);
    }
    NewFPSCR = DAG.getNode(ISD::BITCAST, Dl, MVT::f64, NewFPSCR);
  } else {
    // In 32-bit mode, store f64, load and update the lower half.
    int SSFI = MF.getFrameInfo().CreateStackObject(8, Align(8), false);
    SDValue StackSlot = DAG.getFrameIndex(SSFI, PtrVT);
    SDValue Addr = Subtarget.isLittleEndian()
                       ? StackSlot
                       : DAG.getNode(ISD::ADD, Dl, PtrVT, StackSlot,
                                     DAG.getConstant(4, Dl, PtrVT));
    if (Subtarget.isISA3_0()) {
      Chain = DAG.getStore(Chain, Dl, DstFlag, Addr, MachinePointerInfo());
    } else {
      Chain = DAG.getStore(Chain, Dl, MFFS, StackSlot, MachinePointerInfo());
      SDValue Tmp =
          DAG.getLoad(MVT::i32, Dl, Chain, Addr, MachinePointerInfo());
      Chain = Tmp.getValue(1);
      Tmp = SDValue(DAG.getMachineNode(
                        PPC::RLWIMI, Dl, MVT::i32,
                        {Tmp, DstFlag, DAG.getTargetConstant(0, Dl, MVT::i32),
                         DAG.getTargetConstant(30, Dl, MVT::i32),
                         DAG.getTargetConstant(31, Dl, MVT::i32)}),
                    0);
      Chain = DAG.getStore(Chain, Dl, Tmp, Addr, MachinePointerInfo());
    }
    NewFPSCR =
        DAG.getLoad(MVT::f64, Dl, Chain, StackSlot, MachinePointerInfo());
    Chain = NewFPSCR.getValue(1);
  }
  if (Subtarget.isISA3_0())
    return SDValue(DAG.getMachineNode(PPC::MFFSCRN, Dl, {MVT::f64, MVT::Other},
                                      {NewFPSCR, Chain}),
                   1);
  SDValue Zero = DAG.getConstant(0, Dl, MVT::i32, true);
  SDNode *MTFSF = DAG.getMachineNode(
      PPC::MTFSF, Dl, MVT::Other,
      {DAG.getConstant(255, Dl, MVT::i32, true), NewFPSCR, Zero, Zero, Chain});
  return SDValue(MTFSF, 0);
}

SDValue PPCTargetLowering::LowerGET_ROUNDING(SDValue Op,
                                             SelectionDAG &DAG) const {
  SDLoc dl(Op);
  /*
   The rounding mode is in bits 30:31 of FPSR, and has the following
   settings:
     00 Round to nearest
     01 Round to 0
     10 Round to +inf
     11 Round to -inf

  GET_ROUNDING, on the other hand, expects the following:
    -1 Undefined
     0 Round to 0
     1 Round to nearest
     2 Round to +inf
     3 Round to -inf

  To perform the conversion, we do:
    ((FPSCR & 0x3) ^ ((~FPSCR & 0x3) >> 1))
  */

  MachineFunction &MF = DAG.getMachineFunction();
  EVT VT = Op.getValueType();
  EVT PtrVT = getPointerTy(MF.getDataLayout());

  // Save FP Control Word to register
  SDValue Chain = Op.getOperand(0);
  SDValue MFFS = DAG.getNode(PPCISD::MFFS, dl, {MVT::f64, MVT::Other}, Chain);
  Chain = MFFS.getValue(1);

  SDValue CWD;
  if (isTypeLegal(MVT::i64)) {
    CWD = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32,
                      DAG.getNode(ISD::BITCAST, dl, MVT::i64, MFFS));
  } else {
    // Save FP register to stack slot
    int SSFI = MF.getFrameInfo().CreateStackObject(8, Align(8), false);
    SDValue StackSlot = DAG.getFrameIndex(SSFI, PtrVT);
    Chain = DAG.getStore(Chain, dl, MFFS, StackSlot, MachinePointerInfo());

    // Load FP Control Word from low 32 bits of stack slot.
    assert(hasBigEndianPartOrdering(MVT::i64, MF.getDataLayout()) &&
           "Stack slot adjustment is valid only on big endian subtargets!");
    SDValue Four = DAG.getConstant(4, dl, PtrVT);
    SDValue Addr = DAG.getNode(ISD::ADD, dl, PtrVT, StackSlot, Four);
    CWD = DAG.getLoad(MVT::i32, dl, Chain, Addr, MachinePointerInfo());
    Chain = CWD.getValue(1);
  }

  // Transform as necessary
  SDValue CWD1 =
    DAG.getNode(ISD::AND, dl, MVT::i32,
                CWD, DAG.getConstant(3, dl, MVT::i32));
  SDValue CWD2 =
    DAG.getNode(ISD::SRL, dl, MVT::i32,
                DAG.getNode(ISD::AND, dl, MVT::i32,
                            DAG.getNode(ISD::XOR, dl, MVT::i32,
                                        CWD, DAG.getConstant(3, dl, MVT::i32)),
                            DAG.getConstant(3, dl, MVT::i32)),
                DAG.getConstant(1, dl, MVT::i32));

  SDValue RetVal =
    DAG.getNode(ISD::XOR, dl, MVT::i32, CWD1, CWD2);

  RetVal =
      DAG.getNode((VT.getSizeInBits() < 16 ? ISD::TRUNCATE : ISD::ZERO_EXTEND),
                  dl, VT, RetVal);

  return DAG.getMergeValues({RetVal, Chain}, dl);
}

SDValue PPCTargetLowering::LowerSHL_PARTS(SDValue Op, SelectionDAG &DAG) const {
  EVT VT = Op.getValueType();
  uint64_t BitWidth = VT.getSizeInBits();
  SDLoc dl(Op);
  assert(Op.getNumOperands() == 3 &&
         VT == Op.getOperand(1).getValueType() &&
         "Unexpected SHL!");

  // Expand into a bunch of logical ops.  Note that these ops
  // depend on the PPC behavior for oversized shift amounts.
  SDValue Lo = Op.getOperand(0);
  SDValue Hi = Op.getOperand(1);
  SDValue Amt = Op.getOperand(2);
  EVT AmtVT = Amt.getValueType();

  SDValue Tmp1 = DAG.getNode(ISD::SUB, dl, AmtVT,
                             DAG.getConstant(BitWidth, dl, AmtVT), Amt);
  SDValue Tmp2 = DAG.getNode(PPCISD::SHL, dl, VT, Hi, Amt);
  SDValue Tmp3 = DAG.getNode(PPCISD::SRL, dl, VT, Lo, Tmp1);
  SDValue Tmp4 = DAG.getNode(ISD::OR , dl, VT, Tmp2, Tmp3);
  SDValue Tmp5 = DAG.getNode(ISD::ADD, dl, AmtVT, Amt,
                             DAG.getSignedConstant(-BitWidth, dl, AmtVT));
  SDValue Tmp6 = DAG.getNode(PPCISD::SHL, dl, VT, Lo, Tmp5);
  SDValue OutHi = DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp6);
  SDValue OutLo = DAG.getNode(PPCISD::SHL, dl, VT, Lo, Amt);
  SDValue OutOps[] = { OutLo, OutHi };
  return DAG.getMergeValues(OutOps, dl);
}

SDValue PPCTargetLowering::LowerSRL_PARTS(SDValue Op, SelectionDAG &DAG) const {
  EVT VT = Op.getValueType();
  SDLoc dl(Op);
  uint64_t BitWidth = VT.getSizeInBits();
  assert(Op.getNumOperands() == 3 &&
         VT == Op.getOperand(1).getValueType() &&
         "Unexpected SRL!");

  // Expand into a bunch of logical ops.  Note that these ops
  // depend on the PPC behavior for oversized shift amounts.
  SDValue Lo = Op.getOperand(0);
  SDValue Hi = Op.getOperand(1);
  SDValue Amt = Op.getOperand(2);
  EVT AmtVT = Amt.getValueType();

  SDValue Tmp1 = DAG.getNode(ISD::SUB, dl, AmtVT,
                             DAG.getConstant(BitWidth, dl, AmtVT), Amt);
  SDValue Tmp2 = DAG.getNode(PPCISD::SRL, dl, VT, Lo, Amt);
  SDValue Tmp3 = DAG.getNode(PPCISD::SHL, dl, VT, Hi, Tmp1);
  SDValue Tmp4 = DAG.getNode(ISD::OR, dl, VT, Tmp2, Tmp3);
  SDValue Tmp5 = DAG.getNode(ISD::ADD, dl, AmtVT, Amt,
                             DAG.getSignedConstant(-BitWidth, dl, AmtVT));
  SDValue Tmp6 = DAG.getNode(PPCISD::SRL, dl, VT, Hi, Tmp5);
  SDValue OutLo = DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp6);
  SDValue OutHi = DAG.getNode(PPCISD::SRL, dl, VT, Hi, Amt);
  SDValue OutOps[] = { OutLo, OutHi };
  return DAG.getMergeValues(OutOps, dl);
}

SDValue PPCTargetLowering::LowerSRA_PARTS(SDValue Op, SelectionDAG &DAG) const {
  SDLoc dl(Op);
  EVT VT = Op.getValueType();
  uint64_t BitWidth = VT.getSizeInBits();
  assert(Op.getNumOperands() == 3 &&
         VT == Op.getOperand(1).getValueType() &&
         "Unexpected SRA!");

  // Expand into a bunch of logical ops, followed by a select_cc.
  SDValue Lo = Op.getOperand(0);
  SDValue Hi = Op.getOperand(1);
  SDValue Amt = Op.getOperand(2);
  EVT AmtVT = Amt.getValueType();

  SDValue Tmp1 = DAG.getNode(ISD::SUB, dl, AmtVT,
                             DAG.getConstant(BitWidth, dl, AmtVT), Amt);
  SDValue Tmp2 = DAG.getNode(PPCISD::SRL, dl, VT, Lo, Amt);
  SDValue Tmp3 = DAG.getNode(PPCISD::SHL, dl, VT, Hi, Tmp1);
  SDValue Tmp4 = DAG.getNode(ISD::OR, dl, VT, Tmp2, Tmp3);
  SDValue Tmp5 = DAG.getNode(ISD::ADD, dl, AmtVT, Amt,
                             DAG.getSignedConstant(-BitWidth, dl, AmtVT));
  SDValue Tmp6 = DAG.getNode(PPCISD::SRA, dl, VT, Hi, Tmp5);
  SDValue OutHi = DAG.getNode(PPCISD::SRA, dl, VT, Hi, Amt);
  SDValue OutLo = DAG.getSelectCC(dl, Tmp5, DAG.getConstant(0, dl, AmtVT),
                                  Tmp4, Tmp6, ISD::SETLE);
  SDValue OutOps[] = { OutLo, OutHi };
  return DAG.getMergeValues(OutOps, dl);
}

SDValue PPCTargetLowering::LowerFunnelShift(SDValue Op,
                                            SelectionDAG &DAG) const {
  SDLoc dl(Op);
  EVT VT = Op.getValueType();
  unsigned BitWidth = VT.getSizeInBits();

  bool IsFSHL = Op.getOpcode() == ISD::FSHL;
  SDValue X = Op.getOperand(0);
  SDValue Y = Op.getOperand(1);
  SDValue Z = Op.getOperand(2);
  EVT AmtVT = Z.getValueType();

  // fshl: (X << (Z % BW)) | (Y >> (BW - (Z % BW)))
  // fshr: (X << (BW - (Z % BW))) | (Y >> (Z % BW))
  // This is simpler than TargetLowering::expandFunnelShift because we can rely
  // on PowerPC shift by BW being well defined.
  Z = DAG.getNode(ISD::AND, dl, AmtVT, Z,
                  DAG.getConstant(BitWidth - 1, dl, AmtVT));
  SDValue SubZ =
      DAG.getNode(ISD::SUB, dl, AmtVT, DAG.getConstant(BitWidth, dl, AmtVT), Z);
  X = DAG.getNode(PPCISD::SHL, dl, VT, X, IsFSHL ? Z : SubZ);
  Y = DAG.getNode(PPCISD::SRL, dl, VT, Y, IsFSHL ? SubZ : Z);
  return DAG.getNode(ISD::OR, dl, VT, X, Y);
}

//===----------------------------------------------------------------------===//
// Vector related lowering.
//

/// getCanonicalConstSplat - Build a canonical splat immediate of Val with an
/// element size of SplatSize. Cast the result to VT.
static SDValue getCanonicalConstSplat(uint64_t Val, unsigned SplatSize, EVT VT,
                                      SelectionDAG &DAG, const SDLoc &dl) {
  static const MVT VTys[] = { // canonical VT to use for each size.
    MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
  };

  EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];

  // For a splat with all ones, turn it to vspltisb 0xFF to canonicalize.
  if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
    SplatSize = 1;
    Val = 0xFF;
  }

  EVT CanonicalVT = VTys[SplatSize-1];

  // Build a canonical splat for this value.
  // Explicitly truncate APInt here, as this API is used with a mix of
  // signed and unsigned values.
  return DAG.getBitcast(
      ReqVT,
      DAG.getConstant(APInt(64, Val).trunc(SplatSize * 8), dl, CanonicalVT));
}

/// BuildIntrinsicOp - Return a unary operator intrinsic node with the
/// specified intrinsic ID.
static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op, SelectionDAG &DAG,
                                const SDLoc &dl, EVT DestVT = MVT::Other) {
  if (DestVT == MVT::Other) DestVT = Op.getValueType();
  return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, DestVT,
                     DAG.getConstant(IID, dl, MVT::i32), Op);
}

/// BuildIntrinsicOp - Return a binary operator intrinsic node with the
/// specified intrinsic ID.
static SDValue BuildIntrinsicOp(unsigned IID, SDValue LHS, SDValue RHS,
                                SelectionDAG &DAG, const SDLoc &dl,
                                EVT DestVT = MVT::Other) {
  if (DestVT == MVT::Other) DestVT = LHS.getValueType();
  return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, DestVT,
                     DAG.getConstant(IID, dl, MVT::i32), LHS, RHS);
}

/// BuildIntrinsicOp - Return a ternary operator intrinsic node with the
/// specified intrinsic ID.
static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op0, SDValue Op1,
                                SDValue Op2, SelectionDAG &DAG, const SDLoc &dl,
                                EVT DestVT = MVT::Other) {
  if (DestVT == MVT::Other) DestVT = Op0.getValueType();
  return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, DestVT,
                     DAG.getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
}

/// BuildVSLDOI - Return a VECTOR_SHUFFLE that is a vsldoi of the specified
/// amount.  The result has the specified value type.
static SDValue BuildVSLDOI(SDValue LHS, SDValue RHS, unsigned Amt, EVT VT,
                           SelectionDAG &DAG, const SDLoc &dl) {
  // Force LHS/RHS to be the right type.
  LHS = DAG.getNode(ISD::BITCAST, dl, MVT::v16i8, LHS);
  RHS = DAG.getNode(ISD::BITCAST, dl, MVT::v16i8, RHS);

  int Ops[16];
  for (unsigned i = 0; i != 16; ++i)
    Ops[i] = i + Amt;
  SDValue T = DAG.getVectorShuffle(MVT::v16i8, dl, LHS, RHS, Ops);
  return DAG.getNode(ISD::BITCAST, dl, VT, T);
}

/// Do we have an efficient pattern in a .td file for this node?
///
/// \param V - pointer to the BuildVectorSDNode being matched
/// \param HasDirectMove - does this subtarget have VSR <-> GPR direct moves?
///
/// There are some patterns where it is beneficial to keep a BUILD_VECTOR
/// node as a BUILD_VECTOR node rather than expanding it. The patterns where
/// the opposite is true (expansion is beneficial) are:
/// - The node builds a vector out of integers that are not 32 or 64-bits
/// - The node builds a vector out of constants
/// - The node is a "load-and-splat"
/// In all other cases, we will choose to keep the BUILD_VECTOR.
static bool haveEfficientBuildVectorPattern(BuildVectorSDNode *V,
                                            bool HasDirectMove,
                                            bool HasP8Vector) {
  EVT VecVT = V->getValueType(0);
  bool RightType = VecVT == MVT::v2f64 ||
    (HasP8Vector && VecVT == MVT::v4f32) ||
    (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
  if (!RightType)
    return false;

  bool IsSplat = true;
  bool IsLoad = false;
  SDValue Op0 = V->getOperand(0);

  // This function is called in a block that confirms the node is not a constant
  // splat. So a constant BUILD_VECTOR here means the vector is built out of
  // different constants.
  if (V->isConstant())
    return false;
  for (int i = 0, e = V->getNumOperands(); i < e; ++i) {
    if (V->getOperand(i).isUndef())
      return false;
    // We want to expand nodes that represent load-and-splat even if the
    // loaded value is a floating point truncation or conversion to int.
    if (V->getOperand(i).getOpcode() == ISD::LOAD ||
        (V->getOperand(i).getOpcode() == ISD::FP_ROUND &&
         V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD) ||
        (V->getOperand(i).getOpcode() == ISD::FP_TO_SINT &&
         V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD) ||
        (V->getOperand(i).getOpcode() == ISD::FP_TO_UINT &&
         V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD))
      IsLoad = true;
    // If the operands are different or the input is not a load and has more
    // uses than just this BV node, then it isn't a splat.
    if (V->getOperand(i) != Op0 ||
        (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
      IsSplat = false;
  }
  return !(IsSplat && IsLoad);
}

// Lower BITCAST(f128, (build_pair i64, i64)) to BUILD_FP128.
SDValue PPCTargetLowering::LowerBITCAST(SDValue Op, SelectionDAG &DAG) const {

  SDLoc dl(Op);
  SDValue Op0 = Op->getOperand(0);

  if (!Subtarget.isPPC64() || (Op0.getOpcode() != ISD::BUILD_PAIR) ||
      (Op.getValueType() != MVT::f128))
    return SDValue();

  SDValue Lo = Op0.getOperand(0);
  SDValue Hi = Op0.getOperand(1);
  if ((Lo.getValueType() != MVT::i64) || (Hi.getValueType() != MVT::i64))
    return SDValue();

  if (!Subtarget.isLittleEndian())
    std::swap(Lo, Hi);

  return DAG.getNode(PPCISD::BUILD_FP128, dl, MVT::f128, Lo, Hi);
}

static const SDValue *getNormalLoadInput(const SDValue &Op, bool &IsPermuted) {
  const SDValue *InputLoad = &Op;
  while (InputLoad->getOpcode() == ISD::BITCAST)
    InputLoad = &InputLoad->getOperand(0);
  if (InputLoad->getOpcode() == ISD::SCALAR_TO_VECTOR ||
      InputLoad->getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED) {
    IsPermuted = InputLoad->getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED;
    InputLoad = &InputLoad->getOperand(0);
  }
  if (InputLoad->getOpcode() != ISD::LOAD)
    return nullptr;
  LoadSDNode *LD = cast<LoadSDNode>(*InputLoad);
  return ISD::isNormalLoad(LD) ? InputLoad : nullptr;
}

// Convert the argument APFloat to a single precision APFloat if there is no
// loss in information during the conversion to single precision APFloat and the
// resulting number is not a denormal number. Return true if successful.
bool llvm::convertToNonDenormSingle(APFloat &ArgAPFloat) {
  APFloat APFloatToConvert = ArgAPFloat;
  bool LosesInfo = true;
  APFloatToConvert.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven,
                           &LosesInfo);
  bool Success = (!LosesInfo && !APFloatToConvert.isDenormal());
  if (Success)
    ArgAPFloat = APFloatToConvert;
  return Success;
}

// Bitcast the argument APInt to a double and convert it to a single precision
// APFloat, bitcast the APFloat to an APInt and assign it to the original
// argument if there is no loss in information during the conversion from
// double to single precision APFloat and the resulting number is not a denormal
// number. Return true if successful.
bool llvm::convertToNonDenormSingle(APInt &ArgAPInt) {
  double DpValue = ArgAPInt.bitsToDouble();
  APFloat APFloatDp(DpValue);
  bool Success = convertToNonDenormSingle(APFloatDp);
  if (Success)
    ArgAPInt = APFloatDp.bitcastToAPInt();
  return Success;
}

// Nondestructive check for convertTonNonDenormSingle.
bool llvm::checkConvertToNonDenormSingle(APFloat &ArgAPFloat) {
  // Only convert if it loses info, since XXSPLTIDP should
  // handle the other case.
  APFloat APFloatToConvert = ArgAPFloat;
  bool LosesInfo = true;
  APFloatToConvert.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven,
                           &LosesInfo);

  return (!LosesInfo && !APFloatToConvert.isDenormal());
}

static bool isValidSplatLoad(const PPCSubtarget &Subtarget, const SDValue &Op,
                             unsigned &Opcode) {
  LoadSDNode *InputNode = dyn_cast<LoadSDNode>(Op.getOperand(0));
  if (!InputNode || !Subtarget.hasVSX() || !ISD::isUNINDEXEDLoad(InputNode))
    return false;

  EVT Ty = Op->getValueType(0);
  // For v2f64, v4f32 and v4i32 types, we require the load to be non-extending
  // as we cannot handle extending loads for these types.
  if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
      ISD::isNON_EXTLoad(InputNode))
    return true;

  EVT MemVT = InputNode->getMemoryVT();
  // For v8i16 and v16i8 types, extending loads can be handled as long as the
  // memory VT is the same vector element VT type.
  // The loads feeding into the v8i16 and v16i8 types will be extending because
  // scalar i8/i16 are not legal types.
  if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) && ISD::isEXTLoad(InputNode) &&
      (MemVT == Ty.getVectorElementType()))
    return true;

  if (Ty == MVT::v2i64) {
    // Check the extend type, when the input type is i32, and the output vector
    // type is v2i64.
    if (MemVT == MVT::i32) {
      if (ISD::isZEXTLoad(InputNode))
        Opcode = PPCISD::ZEXT_LD_SPLAT;
      if (ISD::isSEXTLoad(InputNode))
        Opcode = PPCISD::SEXT_LD_SPLAT;
    }
    return true;
  }
  return false;
}

bool isValidMtVsrBmi(APInt &BitMask, BuildVectorSDNode &BVN,
                     bool IsLittleEndian) {
  assert(BVN.getNumOperands() > 0 && "Unexpected 0-size build vector");

  BitMask.clearAllBits();
  EVT VT = BVN.getValueType(0);
  unsigned VTSize = VT.getSizeInBits();
  APInt ConstValue(VTSize, 0);

  unsigned EltWidth = VT.getScalarSizeInBits();

  unsigned BitPos = 0;
  for (auto OpVal : BVN.op_values()) {
    auto *CN = dyn_cast<ConstantSDNode>(OpVal);

    if (!CN)
      return false;
    // The elements in a vector register are ordered in reverse byte order
    // between little-endian and big-endian modes.
    ConstValue.insertBits(CN->getAPIntValue().zextOrTrunc(EltWidth),
                          IsLittleEndian ? BitPos : VTSize - EltWidth - BitPos);
    BitPos += EltWidth;
  }

  for (unsigned J = 0; J < 16; ++J) {
    APInt ExtractValue = ConstValue.extractBits(8, J * 8);
    if (ExtractValue != 0x00 && ExtractValue != 0xFF)
      return false;
    if (ExtractValue == 0xFF)
      BitMask.setBit(J);
  }
  return true;
}

// If this is a case we can't handle, return null and let the default
// expansion code take care of it.  If we CAN select this case, and if it
// selects to a single instruction, return Op.  Otherwise, if we can codegen
// this case more efficiently than a constant pool load, lower it to the
// sequence of ops that should be used.
SDValue PPCTargetLowering::LowerBUILD_VECTOR(SDValue Op,
                                             SelectionDAG &DAG) const {
  SDLoc dl(Op);
  BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(Op.getNode());
  assert(BVN && "Expected a BuildVectorSDNode in LowerBUILD_VECTOR");

  if (Subtarget.hasP10Vector()) {
    APInt BitMask(32, 0);
    // If the value of the vector is all zeros or all ones,
    // we do not convert it to MTVSRBMI.
    // The xxleqv instruction sets a vector with all ones.
    // The xxlxor instruction sets a vector with all zeros.
    if (isValidMtVsrBmi(BitMask, *BVN, Subtarget.isLittleEndian()) &&
        BitMask != 0 && BitMask != 0xffff) {
      SDValue SDConstant = DAG.getTargetConstant(BitMask, dl, MVT::i32);
      MachineSDNode *MSDNode =
          DAG.getMachineNode(PPC::MTVSRBMI, dl, MVT::v16i8, SDConstant);
      SDValue SDV = SDValue(MSDNode, 0);
      EVT DVT = BVN->getValueType(0);
      EVT SVT = SDV.getValueType();
      if (SVT != DVT) {
        SDV = DAG.getNode(ISD::BITCAST, dl, DVT, SDV);
      }
      return SDV;
    }
    // Recognize build vector patterns to emit VSX vector instructions
    // instead of loading value from memory.
    if (SDValue VecPat = combineBVLoadsSpecialValue(Op, DAG))
      return VecPat;
  }
  // Check if this is a splat of a constant value.
  APInt APSplatBits, APSplatUndef;
  unsigned SplatBitSize;
  bool HasAnyUndefs;
  bool BVNIsConstantSplat =
      BVN->isConstantSplat(APSplatBits, APSplatUndef, SplatBitSize,
                           HasAnyUndefs, 0, !Subtarget.isLittleEndian());

  // If it is a splat of a double, check if we can shrink it to a 32 bit
  // non-denormal float which when converted back to double gives us the same
  // double. This is to exploit the XXSPLTIDP instruction.
  // If we lose precision, we use XXSPLTI32DX.
  if (BVNIsConstantSplat && (SplatBitSize == 64) &&
      Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
    // Check the type first to short-circuit so we don't modify APSplatBits if
    // this block isn't executed.
    if ((Op->getValueType(0) == MVT::v2f64) &&
        convertToNonDenormSingle(APSplatBits)) {
      SDValue SplatNode = DAG.getNode(
          PPCISD::XXSPLTI_SP_TO_DP, dl, MVT::v2f64,
          DAG.getTargetConstant(APSplatBits.getZExtValue(), dl, MVT::i32));
      return DAG.getBitcast(Op.getValueType(), SplatNode);
    } else {
      // We may lose precision, so we have to use XXSPLTI32DX.

      uint32_t Hi = Hi_32(APSplatBits.getZExtValue());
      uint32_t Lo = Lo_32(APSplatBits.getZExtValue());
      SDValue SplatNode = DAG.getUNDEF(MVT::v2i64);

      if (!Hi || !Lo)
        // If either load is 0, then we should generate XXLXOR to set to 0.
        SplatNode = DAG.getTargetConstant(0, dl, MVT::v2i64);

      if (Hi)
        SplatNode = DAG.getNode(
            PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
            DAG.getTargetConstant(0, dl, MVT::i32),
            DAG.getTargetConstant(Hi, dl, MVT::i32));

      if (Lo)
        SplatNode =
            DAG.getNode(PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
                        DAG.getTargetConstant(1, dl, MVT::i32),
                        DAG.getTargetConstant(Lo, dl, MVT::i32));

      return DAG.getBitcast(Op.getValueType(), SplatNode);
    }
  }

  bool IsSplat64 = false;
  uint64_t SplatBits = 0;
  int32_t SextVal = 0;
  if (BVNIsConstantSplat && SplatBitSize <= 64) {
    SplatBits = APSplatBits.getZExtValue();
    if (SplatBitSize <= 32) {
      SextVal = SignExtend32(SplatBits, SplatBitSize);
    } else if (SplatBitSize == 64 && Subtarget.hasP8Altivec()) {
      int64_t Splat64Val = static_cast<int64_t>(SplatBits);
      bool P9Vector = Subtarget.hasP9Vector();
      int32_t Hi = P9Vector ? 127 : 15;
      int32_t Lo = P9Vector ? -128 : -16;
      IsSplat64 = Splat64Val >= Lo && Splat64Val <= Hi;
      SextVal = static_cast<int32_t>(SplatBits);
    }
  }

  if (!BVNIsConstantSplat || (SplatBitSize > 32 && !IsSplat64)) {
    unsigned NewOpcode = PPCISD::LD_SPLAT;

    // Handle load-and-splat patterns as we have instructions that will do this
    // in one go.
    if (DAG.isSplatValue(Op, true) &&
        isValidSplatLoad(Subtarget, Op, NewOpcode)) {
      const SDValue *InputLoad = &Op.getOperand(0);
      LoadSDNode *LD = cast<LoadSDNode>(*InputLoad);

      // If the input load is an extending load, it will be an i32 -> i64
      // extending load and isValidSplatLoad() will update NewOpcode.
      unsigned MemorySize = LD->getMemoryVT().getScalarSizeInBits();
      unsigned ElementSize =
          MemorySize * ((NewOpcode == PPCISD::LD_SPLAT) ? 1 : 2);

      assert(((ElementSize == 2 * MemorySize)
                  ? (NewOpcode == PPCISD::ZEXT_LD_SPLAT ||
                     NewOpcode == PPCISD::SEXT_LD_SPLAT)
                  : (NewOpcode == PPCISD::LD_SPLAT)) &&
             "Unmatched element size and opcode!\n");

      // Checking for a single use of this load, we have to check for vector
      // width (128 bits) / ElementSize uses (since each operand of the
      // BUILD_VECTOR is a separate use of the value.
      unsigned NumUsesOfInputLD = 128 / ElementSize;
      for (SDValue BVInOp : Op->ops())
        if (BVInOp.isUndef())
          NumUsesOfInputLD--;

      // Exclude somes case where LD_SPLAT is worse than scalar_to_vector:
      // Below cases should also happen for "lfiwzx/lfiwax + LE target + index
      // 1" and "lxvrhx + BE target + index 7" and "lxvrbx + BE target + index
      // 15", but function IsValidSplatLoad() now will only return true when
      // the data at index 0 is not nullptr. So we will not get into trouble for
      // these cases.
      //
      // case 1 - lfiwzx/lfiwax
      // 1.1: load result is i32 and is sign/zero extend to i64;
      // 1.2: build a v2i64 vector type with above loaded value;
      // 1.3: the vector has only one value at index 0, others are all undef;
      // 1.4: on BE target, so that lfiwzx/lfiwax does not need any permute.
      if (NumUsesOfInputLD == 1 &&
          (Op->getValueType(0) == MVT::v2i64 && NewOpcode != PPCISD::LD_SPLAT &&
           !Subtarget.isLittleEndian() && Subtarget.hasVSX() &&
           Subtarget.hasLFIWAX()))
        return SDValue();

      // case 2 - lxvr[hb]x
      // 2.1: load result is at most i16;
      // 2.2: build a vector with above loaded value;
      // 2.3: the vector has only one value at index 0, others are all undef;
      // 2.4: on LE target, so that lxvr[hb]x does not need any permute.
      if (NumUsesOfInputLD == 1 && Subtarget.isLittleEndian() &&
          Subtarget.isISA3_1() && ElementSize <= 16)
        return SDValue();

      assert(NumUsesOfInputLD > 0 && "No uses of input LD of a build_vector?");
      if (InputLoad->getNode()->hasNUsesOfValue(NumUsesOfInputLD, 0) &&
          Subtarget.hasVSX()) {
        SDValue Ops[] = {
          LD->getChain(),    // Chain
          LD->getBasePtr(),  // Ptr
          DAG.getValueType(Op.getValueType()) // VT
        };
        SDValue LdSplt = DAG.getMemIntrinsicNode(
            NewOpcode, dl, DAG.getVTList(Op.getValueType(), MVT::Other), Ops,
            LD->getMemoryVT(), LD->getMemOperand());
        // Replace all uses of the output chain of the original load with the
        // output chain of the new load.
        DAG.ReplaceAllUsesOfValueWith(InputLoad->getValue(1),
                                      LdSplt.getValue(1));
        return LdSplt;
      }
    }

    // In 64BIT mode BUILD_VECTOR nodes that are not constant splats of up to
    // 32-bits can be lowered to VSX instructions under certain conditions.
    // Without VSX, there is no pattern more efficient than expanding the node.
    if (Subtarget.hasVSX() && Subtarget.isPPC64() &&
        haveEfficientBuildVectorPattern(BVN, Subtarget.hasDirectMove(),
                                        Subtarget.hasP8Vector()))
      return Op;
    return SDValue();
  }

  uint64_t SplatUndef = APSplatUndef.getZExtValue();
  unsigned SplatSize = SplatBitSize / 8;

  // First, handle single instruction cases.

  // All zeros?
  if (SplatBits == 0) {
    // Canonicalize all zero vectors to be v4i32.
    if (Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
      SDValue Z = DAG.getConstant(0, dl, MVT::v4i32);
      Op = DAG.getNode(ISD::BITCAST, dl, Op.getValueType(), Z);
    }
    return Op;
  }

  // We have XXSPLTIW for constant splats four bytes wide.
  // Given vector length is a multiple of 4, 2-byte splats can be replaced
  // with 4-byte splats. We replicate the SplatBits in case of 2-byte splat to
  // make a 4-byte splat element. For example: 2-byte splat of 0xABAB can be
  // turned into a 4-byte splat of 0xABABABAB.
  if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
    return getCanonicalConstSplat(SplatBits | (SplatBits << 16), SplatSize * 2,
                                  Op.getValueType(), DAG, dl);

  if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
    return getCanonicalConstSplat(SplatBits, SplatSize, Op.getValueType(), DAG,
                                  dl);

  // We have XXSPLTIB for constant splats one byte wide.
  if (Subtarget.hasP9Vector() && SplatSize == 1)
    return getCanonicalConstSplat(SplatBits, SplatSize, Op.getValueType(), DAG,
                                  dl);

  // If the sign extended value is in the range [-16,15], use VSPLTI[bhw].
  // Use VSPLTIW/VUPKLSW for v2i64 in range [-16,15].
  if (SextVal >= -16 && SextVal <= 15) {
    // SplatSize may be 1, 2, 4, or 8. Use size 4 instead of 8 for the splat to
    // generate a splat word with extend for size 8.
    unsigned UseSize = SplatSize == 8 ? 4 : SplatSize;
    SDValue Res =
        getCanonicalConstSplat(SextVal, UseSize, Op.getValueType(), DAG, dl);
    if (SplatSize != 8)
      return Res;
    return BuildIntrinsicOp(Intrinsic::ppc_altivec_vupklsw, Res, DAG, dl);
  }

  // Two instruction sequences.

  if (Subtarget.hasP9Vector() && SextVal >= -128 && SextVal <= 127) {
    SDValue C = DAG.getConstant((unsigned char)SextVal, dl, MVT::i32);
    SmallVector<SDValue, 16> Ops(16, C);
    SDValue BV = DAG.getBuildVector(MVT::v16i8, dl, Ops);
    unsigned IID;
    EVT VT;
    switch (SplatSize) {
    default:
      llvm_unreachable("Unexpected type for vector constant.");
    case 2:
      IID = Intrinsic::ppc_altivec_vupklsb;
      VT = MVT::v8i16;
      break;
    case 4:
      IID = Intrinsic::ppc_altivec_vextsb2w;
      VT = MVT::v4i32;
      break;
    case 8:
      IID = Intrinsic::ppc_altivec_vextsb2d;
      VT = MVT::v2i64;
      break;
    }
    SDValue Extend = BuildIntrinsicOp(IID, BV, DAG, dl, VT);
    return DAG.getBitcast(Op->getValueType(0), Extend);
  }
  assert(!IsSplat64 && "Unhandled 64-bit splat pattern");

  // If this value is in the range [-32,30] and is even, use:
  //     VSPLTI[bhw](val/2) + VSPLTI[bhw](val/2)
  // If this value is in the range [17,31] and is odd, use:
  //     VSPLTI[bhw](val-16) - VSPLTI[bhw](-16)
  // If this value is in the range [-31,-17] and is odd, use:
  //     VSPLTI[bhw](val+16) + VSPLTI[bhw](-16)
  // Note the last two are three-instruction sequences.
  if (SextVal >= -32 && SextVal <= 31) {
    // To avoid having these optimizations undone by constant folding,
    // we convert to a pseudo that will be expanded later into one of
    // the above forms.
    SDValue Elt = DAG.getSignedConstant(SextVal, dl, MVT::i32);
    EVT VT = (SplatSize == 1 ? MVT::v16i8 :
              (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
    SDValue EltSize = DAG.getConstant(SplatSize, dl, MVT::i32);
    SDValue RetVal = DAG.getNode(PPCISD::VADD_SPLAT, dl, VT, Elt, EltSize);
    if (VT == Op.getValueType())
      return RetVal;
    else
      return DAG.getNode(ISD::BITCAST, dl, Op.getValueType(), RetVal);
  }

  // If this is 0x8000_0000 x 4, turn into vspltisw + vslw.  If it is
  // 0x7FFF_FFFF x 4, turn it into not(0x8000_0000).  This is important
  // for fneg/fabs.
  if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
    // Make -1 and vspltisw -1:
    SDValue OnesV = getCanonicalConstSplat(-1, 4, MVT::v4i32, DAG, dl);

    // Make the VSLW intrinsic, computing 0x8000_0000.
    SDValue Res = BuildIntrinsicOp(Intrinsic::ppc_altivec_vslw, OnesV,
                                   OnesV, DAG, dl);

    // xor by OnesV to invert it.
    Res = DAG.getNode(ISD::XOR, dl, MVT::v4i32, Res, OnesV);
    return DAG.getNode(ISD::BITCAST, dl, Op.getValueType(), Res);
  }

  // Check to see if this is a wide variety of vsplti*, binop self cases.
  static const signed char SplatCsts[] = {
    -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
    -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
  };

  for (unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
    // Indirect through the SplatCsts array so that we favor 'vsplti -1' for
    // cases which are ambiguous (e.g. formation of 0x8000_0000).  'vsplti -1'
    int i = SplatCsts[idx];

    // Figure out what shift amount will be used by altivec if shifted by i in
    // this splat size.
    unsigned TypeShiftAmt = i & (SplatBitSize-1);

    // vsplti + shl self.
    if (SextVal == (int)((unsigned)i << TypeShiftAmt)) {
      SDValue Res = getCanonicalConstSplat(i, SplatSize, MVT::Other, DAG, dl);
      static const unsigned IIDs[] = { // Intrinsic to use for each size.
        Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
        Intrinsic::ppc_altivec_vslw
      };
      Res = BuildIntrinsicOp(IIDs[SplatSize-1], Res, Res, DAG, dl);
      return DAG.getNode(ISD::BITCAST, dl, Op.getValueType(), Res);
    }

    // vsplti + srl self.
    if (SextVal == (int)((unsigned)i >> TypeShiftAmt)) {
      SDValue Res = getCanonicalConstSplat(i, SplatSize, MVT::Other, DAG, dl);
      static const unsigned IIDs[] = { // Intrinsic to use for each size.
        Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
        Intrinsic::ppc_altivec_vsrw
      };
      Res = BuildIntrinsicOp(IIDs[SplatSize-1], Res, Res, DAG, dl);
      return DAG.getNode(ISD::BITCAST, dl, Op.getValueType(), Res);
    }

    // vsplti + rol self.
    if (SextVal == (int)(((unsigned)i << TypeShiftAmt) |
                         ((unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
      SDValue Res = getCanonicalConstSplat(i, SplatSize, MVT::Other, DAG, dl);
      static const unsigned IIDs[] = { // Intrinsic to use for each size.
        Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
        Intrinsic::ppc_altivec_vrlw
      };
      Res = BuildIntrinsicOp(IIDs[SplatSize-1], Res, Res, DAG, dl);
      return DAG.getNode(ISD::BITCAST, dl, Op.getValueType(), Res);
    }

    // t = vsplti c, result = vsldoi t, t, 1
    if (SextVal == (int)(((unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
      SDValue T = getCanonicalConstSplat(i, SplatSize, MVT::v16i8, DAG, dl);
      unsigned Amt = Subtarget.isLittleEndian() ? 15 : 1;
      return BuildVSLDOI(T, T, Amt, Op.getValueType(), DAG, dl);
    }
    // t = vsplti c, result = vsldoi t, t, 2
    if (SextVal == (int)(((unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
      SDValue T = getCanonicalConstSplat(i, SplatSize, MVT::v16i8, DAG, dl);
      unsigned Amt = Subtarget.isLittleEndian() ? 14 : 2;
      return BuildVSLDOI(T, T, Amt, Op.getValueType(), DAG, dl);
    }
    // t = vsplti c, result = vsldoi t, t, 3
    if (SextVal == (int)(((unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
      SDValue T = getCanonicalConstSplat(i, SplatSize, MVT::v16i8, DAG, dl);
      unsigned Amt = Subtarget.isLittleEndian() ? 13 : 3;
      return BuildVSLDOI(T, T, Amt, Op.getValueType(), DAG, dl);
    }
  }

  return SDValue();
}

/// GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit
/// the specified operations to build the shuffle.
static SDValue GeneratePerfectShuffle(unsigned PFEntry, SDValue LHS,
                                      SDValue RHS, SelectionDAG &DAG,
                                      const SDLoc &dl) {
  unsigned OpNum = (PFEntry >> 26) & 0x0F;
  unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
  unsigned RHSID = (PFEntry >>  0) & ((1 << 13)-1);

  enum {
    OP_COPY = 0,  // Copy, used for things like <u,u,u,3> to say it is <0,1,2,3>
    OP_VMRGHW,
    OP_VMRGLW,
    OP_VSPLTISW0,
    OP_VSPLTISW1,
    OP_VSPLTISW2,
    OP_VSPLTISW3,
    OP_VSLDOI4,
    OP_VSLDOI8,
    OP_VSLDOI12
  };

  if (OpNum == OP_COPY) {
    if (LHSID == (1*9+2)*9+3) return LHS;
    assert(LHSID == ((4*9+5)*9+6)*9+7 && "Illegal OP_COPY!");
    return RHS;
  }

  SDValue OpLHS, OpRHS;
  OpLHS = GeneratePerfectShuffle(PerfectShuffleTable[LHSID], LHS, RHS, DAG, dl);
  OpRHS = GeneratePerfectShuffle(PerfectShuffleTable[RHSID], LHS, RHS, DAG, dl);

  int ShufIdxs[16];
  switch (OpNum) {
  default: llvm_unreachable("Unknown i32 permute!");
  case OP_VMRGHW:
    ShufIdxs[ 0] =  0; ShufIdxs[ 1] =  1; ShufIdxs[ 2] =  2; ShufIdxs[ 3] =  3;
    ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
    ShufIdxs[ 8] =  4; ShufIdxs[ 9] =  5; ShufIdxs[10] =  6; ShufIdxs[11] =  7;
    ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
    break;
  case OP_VMRGLW:
    ShufIdxs[ 0] =  8; ShufIdxs[ 1] =  9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
    ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
    ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
    ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
    break;
  case OP_VSPLTISW0:
    for (unsigned i = 0; i != 16; ++i)
      ShufIdxs[i] = (i&3)+0;
    break;
  case OP_VSPLTISW1:
    for (unsigned i = 0; i != 16; ++i)
      ShufIdxs[i] = (i&3)+4;
    break;
  case OP_VSPLTISW2:
    for (unsigned i = 0; i != 16; ++i)
      ShufIdxs[i] = (i&3)+8;
    break;
  case OP_VSPLTISW3:
    for (unsigned i = 0; i != 16; ++i)
      ShufIdxs[i] = (i&3)+12;
    break;
  case OP_VSLDOI4:
    return BuildVSLDOI(OpLHS, OpRHS, 4, OpLHS.getValueType(), DAG, dl);
  case OP_VSLDOI8:
    return BuildVSLDOI(OpLHS, OpRHS, 8, OpLHS.getValueType(), DAG, dl);
  case OP_VSLDOI12:
    return BuildVSLDOI(OpLHS, OpRHS, 12, OpLHS.getValueType(), DAG, dl);
  }
  EVT VT = OpLHS.getValueType();
  OpLHS = DAG.getNode(ISD::BITCAST, dl, MVT::v16i8, OpLHS);
  OpRHS = DAG.getNode(ISD::BITCAST, dl, MVT::v16i8, OpRHS);
  SDValue T = DAG.getVectorShuffle(MVT::v16i8, dl, OpLHS, OpRHS, ShufIdxs);
  return DAG.getNode(ISD::BITCAST, dl, VT, T);
}

/// lowerToVINSERTB - Return the SDValue if this VECTOR_SHUFFLE can be handled
/// by the VINSERTB instruction introduced in ISA 3.0, else just return default
/// SDValue.
SDValue PPCTargetLowering::lowerToVINSERTB(ShuffleVectorSDNode *N,
                                           SelectionDAG &DAG) const {
  const unsigned BytesInVector = 16;
  bool IsLE = Subtarget.isLittleEndian();
  SDLoc dl(N);
  SDValue V1 = N->getOperand(0);
  SDValue V2 = N->getOperand(1);
  unsigned ShiftElts = 0, InsertAtByte = 0;
  bool Swap = false;

  // Shifts required to get the byte we want at element 7.
  unsigned LittleEndianShifts[] = {8, 7,  6,  5,  4,  3,  2,  1,
                                   0, 15, 14, 13, 12, 11, 10, 9};
  unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
                                1, 2,  3,  4,  5,  6,  7,  8};

  ArrayRef<int> Mask = N->getMask();
  int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};

  // For each mask element, find out if we're just inserting something
  // from V2 into V1 or vice versa.
  // Possible permutations inserting an element from V2 into V1:
  //   X, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
  //   0, X, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
  //   ...
  //   0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, X
  // Inserting from V1 into V2 will be similar, except mask range will be
  // [16,31].

  bool FoundCandidate = false;
  // If both vector operands for the shuffle are the same vector, the mask
  // will contain only elements from the first one and the second one will be
  // undef.
  unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
  // Go through the mask of half-words to find an element that's being moved
  // from one vector to the other.
  for (unsigned i = 0; i < BytesInVector; ++i) {
    unsigned CurrentElement = Mask[i];
    // If 2nd operand is undefined, we should only look for element 7 in the
    // Mask.
    if (V2.isUndef() && CurrentElement != VINSERTBSrcElem)
      continue;

    bool OtherElementsInOrder = true;
    // Examine the other elements in the Mask to see if they're in original
    // order.
    for (unsigned j = 0; j < BytesInVector; ++j) {
      if (j == i)
        continue;
      // If CurrentElement is from V1 [0,15], then we the rest of the Mask to be
      // from V2 [16,31] and vice versa.  Unless the 2nd operand is undefined,
      // in which we always assume we're always picking from the 1st operand.
      int MaskOffset =
          (!V2.isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
      if (Mask[j] != OriginalOrder[j] + MaskOffset) {
        OtherElementsInOrder = false;
        break;
      }
    }
    // If other elements are in original order, we record the number of shifts
    // we need to get the element we want into element 7. Also record which byte
    // in the vector we should insert into.
    if (OtherElementsInOrder) {
      // If 2nd operand is undefined, we assume no shifts and no swapping.
      if (V2.isUndef()) {
        ShiftElts = 0;
        Swap = false;
      } else {
        // Only need the last 4-bits for shifts because operands will be swapped if CurrentElement is >= 2^4.
        ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
                         : BigEndianShifts[CurrentElement & 0xF];
        Swap = CurrentElement < BytesInVector;
      }
      InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
      FoundCandidate = true;
      break;
    }
  }

  if (!FoundCandidate)
    return SDValue();

  // Candidate found, construct the proper SDAG sequence with VINSERTB,
  // optionally with VECSHL if shift is required.
  if (Swap)
    std::swap(V1, V2);
  if (V2.isUndef())
    V2 = V1;
  if (ShiftElts) {
    SDValue Shl = DAG.getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
                              DAG.getConstant(ShiftElts, dl, MVT::i32));
    return DAG.getNode(PPCISD::VECINSERT, dl, MVT::v16i8, V1, Shl,
                       DAG.getConstant(InsertAtByte, dl, MVT::i32));
  }
  return DAG.getNode(PPCISD::VECINSERT, dl, MVT::v16i8, V1, V2,
                     DAG.getConstant(InsertAtByte, dl, MVT::i32));
}

/// lowerToVINSERTH - Return the SDValue if this VECTOR_SHUFFLE can be handled
/// by the VINSERTH instruction introduced in ISA 3.0, else just return default
/// SDValue.
SDValue PPCTargetLowering::lowerToVINSERTH(ShuffleVectorSDNode *N,
                                           SelectionDAG &DAG) const {
  const unsigned NumHalfWords = 8;
  const unsigned BytesInVector = NumHalfWords * 2;
  // Check that the shuffle is on half-words.
  if (!isNByteElemShuffleMask(N, 2, 1))
    return SDValue();

  bool IsLE = Subtarget.isLittleEndian();
  SDLoc dl(N);
  SDValue V1 = N->getOperand(0);
  SDValue V2 = N->getOperand(1);
  unsigned ShiftElts = 0, InsertAtByte = 0;
  bool Swap = false;

  // Shifts required to get the half-word we want at element 3.
  unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
  unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};

  uint32_t Mask = 0;
  uint32_t OriginalOrderLow = 0x1234567;
  uint32_t OriginalOrderHigh = 0x89ABCDEF;
  // Now we look at mask elements 0,2,4,6,8,10,12,14.  Pack the mask into a
  // 32-bit space, only need 4-bit nibbles per element.
  for (unsigned i = 0; i < NumHalfWords; ++i) {
    unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
    Mask |= ((uint32_t)(N->getMaskElt(i * 2) / 2) << MaskShift);
  }

  // For each mask element, find out if we're just inserting something
  // from V2 into V1 or vice versa.  Possible permutations inserting an element
  // from V2 into V1:
  //   X, 1, 2, 3, 4, 5, 6, 7
  //   0, X, 2, 3, 4, 5, 6, 7
  //   0, 1, X, 3, 4, 5, 6, 7
  //   0, 1, 2, X, 4, 5, 6, 7
  //   0, 1, 2, 3, X, 5, 6, 7
  //   0, 1, 2, 3, 4, X, 6, 7
  //   0, 1, 2, 3, 4, 5, X, 7
  //   0, 1, 2, 3, 4, 5, 6, X
  // Inserting from V1 into V2 will be similar, except mask range will be [8,15].

  bool FoundCandidate = false;
  // Go through the mask of half-words to find an element that's being moved
  // from one vector to the other.
  for (unsigned i = 0; i < NumHalfWords; ++i) {
    unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
    uint32_t MaskOneElt = (Mask >> MaskShift) & 0xF;
    uint32_t MaskOtherElts = ~(0xF << MaskShift);
    uint32_t TargetOrder = 0x0;

    // If both vector operands for the shuffle are the same vector, the mask
    // will contain only elements from the first one and the second one will be
    // undef.
    if (V2.isUndef()) {
      ShiftElts = 0;
      unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
      TargetOrder = OriginalOrderLow;
      Swap = false;
      // Skip if not the correct element or mask of other elements don't equal
      // to our expected order.
      if (MaskOneElt == VINSERTHSrcElem &&
          (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
        InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
        FoundCandidate = true;
        break;
      }
    } else { // If both operands are defined.
      // Target order is [8,15] if the current mask is between [0,7].
      TargetOrder =
          (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
      // Skip if mask of other elements don't equal our expected order.
      if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
        // We only need the last 3 bits for the number of shifts.
        ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
                         : BigEndianShifts[MaskOneElt & 0x7];
        InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
        Swap = MaskOneElt < NumHalfWords;
        FoundCandidate = true;
        break;
      }
    }
  }

  if (!FoundCandidate)
    return SDValue();

  // Candidate found, construct the proper SDAG sequence with VINSERTH,
  // optionally with VECSHL if shift is required.
  if (Swap)
    std::swap(V1, V2);
  if (V2.isUndef())
    V2 = V1;
  SDValue Conv1 = DAG.getNode(ISD::BITCAST, dl, MVT::v8i16, V1);
  if (ShiftElts) {
    // Double ShiftElts because we're left shifting on v16i8 type.
    SDValue Shl = DAG.getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
                              DAG.getConstant(2 * ShiftElts, dl, MVT::i32));
    SDValue Conv2 = DAG.getNode(ISD::BITCAST, dl, MVT::v8i16, Shl);
    SDValue Ins = DAG.getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
                              DAG.getConstant(InsertAtByte, dl, MVT::i32));
    return DAG.getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
  }
  SDValue Conv2 = DAG.getNode(ISD::BITCAST, dl, MVT::v8i16, V2);
  SDValue Ins = DAG.getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
                            DAG.getConstant(InsertAtByte, dl, MVT::i32));
  return DAG.getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
}

/// lowerToXXSPLTI32DX - Return the SDValue if this VECTOR_SHUFFLE can be
/// handled by the XXSPLTI32DX instruction introduced in ISA 3.1, otherwise
/// return the default SDValue.
SDValue PPCTargetLowering::lowerToXXSPLTI32DX(ShuffleVectorSDNode *SVN,
                                              SelectionDAG &DAG) const {
  // The LHS and RHS may be bitcasts to v16i8 as we canonicalize shuffles
  // to v16i8. Peek through the bitcasts to get the actual operands.
  SDValue LHS = peekThroughBitcasts(SVN->getOperand(0));
  SDValue RHS = peekThroughBitcasts(SVN->getOperand(1));

  auto ShuffleMask = SVN->getMask();
  SDValue VecShuffle(SVN, 0);
  SDLoc DL(SVN);

  // Check that we have a four byte shuffle.
  if (!isNByteElemShuffleMask(SVN, 4, 1))
    return SDValue();

  // Canonicalize the RHS being a BUILD_VECTOR when lowering to xxsplti32dx.
  if (RHS->getOpcode() != ISD::BUILD_VECTOR) {
    std::swap(LHS, RHS);
    VecShuffle = peekThroughBitcasts(DAG.getCommutedVectorShuffle(*SVN));
    ShuffleVectorSDNode *CommutedSV = dyn_cast<ShuffleVectorSDNode>(VecShuffle);
    if (!CommutedSV)
      return SDValue();
    ShuffleMask = CommutedSV->getMask();
  }

  // Ensure that the RHS is a vector of constants.
  BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(RHS.getNode());
  if (!BVN)
    return SDValue();

  // Check if RHS is a splat of 4-bytes (or smaller).
  APInt APSplatValue, APSplatUndef;
  unsigned SplatBitSize;
  bool HasAnyUndefs;
  if (!BVN->isConstantSplat(APSplatValue, APSplatUndef, SplatBitSize,
                            HasAnyUndefs, 0, !Subtarget.isLittleEndian()) ||
      SplatBitSize > 32)
    return SDValue();

  // Check that the shuffle mask matches the semantics of XXSPLTI32DX.
  // The instruction splats a constant C into two words of the source vector
  // producing { C, Unchanged, C, Unchanged } or { Unchanged, C, Unchanged, C }.
  // Thus we check that the shuffle mask is the equivalent  of
  // <0, [4-7], 2, [4-7]> or <[4-7], 1, [4-7], 3> respectively.
  // Note: the check above of isNByteElemShuffleMask() ensures that the bytes
  // within each word are consecutive, so we only need to check the first byte.
  SDValue Index;
  bool IsLE = Subtarget.isLittleEndian();
  if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
      (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
       ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
    Index = DAG.getTargetConstant(IsLE ? 0 : 1, DL, MVT::i32);
  else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
           (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
            ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
    Index = DAG.getTargetConstant(IsLE ? 1 : 0, DL, MVT::i32);
  else
    return SDValue();

  // If the splat is narrower than 32-bits, we need to get the 32-bit value
  // for XXSPLTI32DX.
  unsigned SplatVal = APSplatValue.getZExtValue();
  for (; SplatBitSize < 32; SplatBitSize <<= 1)
    SplatVal |= (SplatVal << SplatBitSize);

  SDValue SplatNode = DAG.getNode(
      PPCISD::XXSPLTI32DX, DL, MVT::v2i64, DAG.getBitcast(MVT::v2i64, LHS),
      Index, DAG.getTargetConstant(SplatVal, DL, MVT::i32));
  return DAG.getNode(ISD::BITCAST, DL, MVT::v16i8, SplatNode);
}

/// LowerROTL - Custom lowering for ROTL(v1i128) to vector_shuffle(v16i8).
/// We lower ROTL(v1i128) to vector_shuffle(v16i8) only if shift amount is
/// a multiple of 8. Otherwise convert it to a scalar rotation(i128)
/// i.e (or (shl x, C1), (srl x, 128-C1)).
SDValue PPCTargetLowering::LowerROTL(SDValue Op, SelectionDAG &DAG) const {
  assert(Op.getOpcode() == ISD::ROTL && "Should only be called for ISD::ROTL");
  assert(Op.getValueType() == MVT::v1i128 &&
         "Only set v1i128 as custom, other type shouldn't reach here!");
  SDLoc dl(Op);
  SDValue N0 = peekThroughBitcasts(Op.getOperand(0));
  SDValue N1 = peekThroughBitcasts(Op.getOperand(1));
  unsigned SHLAmt = N1.getConstantOperandVal(0);
  if (SHLAmt % 8 == 0) {
    std::array<int, 16> Mask;
    std::iota(Mask.begin(), Mask.end(), 0);
    std::rotate(Mask.begin(), Mask.begin() + SHLAmt / 8, Mask.end());
    if (SDValue Shuffle =
            DAG.getVectorShuffle(MVT::v16i8, dl, DAG.getBitcast(MVT::v16i8, N0),
                                 DAG.getUNDEF(MVT::v16i8), Mask))
      return DAG.getNode(ISD::BITCAST, dl, MVT::v1i128, Shuffle);
  }
  SDValue ArgVal = DAG.getBitcast(MVT::i128, N0);
  SDValue SHLOp = DAG.getNode(ISD::SHL, dl, MVT::i128, ArgVal,
                              DAG.getConstant(SHLAmt, dl, MVT::i32));
  SDValue SRLOp = DAG.getNode(ISD::SRL, dl, MVT::i128, ArgVal,
                              DAG.getConstant(128 - SHLAmt, dl, MVT::i32));
  SDValue OROp = DAG.getNode(ISD::OR, dl, MVT::i128, SHLOp, SRLOp);
  return DAG.getNode(ISD::BITCAST, dl, MVT::v1i128, OROp);
}

/// LowerVECTOR_SHUFFLE - Return the code we lower for VECTOR_SHUFFLE.  If this
/// is a shuffle we can handle in a single instruction, return it.  Otherwise,
/// return the code it can be lowered into.  Worst case, it can always be
/// lowered into a vperm.
SDValue PPCTargetLowering::LowerVECTOR_SHUFFLE(SDValue Op,
                                               SelectionDAG &DAG) const {
  SDLoc dl(Op);
  SDValue V1 = Op.getOperand(0);
  SDValue V2 = Op.getOperand(1);
  ShuffleVectorSDNode *SVOp = cast<ShuffleVectorSDNode>(Op);

  // Any nodes that were combined in the target-independent combiner prior
  // to vector legalization will not be sent to the target combine. Try to
  // combine it here.
  if (SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
    if (!isa<ShuffleVectorSDNode>(NewShuffle))
      return NewShuffle;
    Op = NewShuffle;
    SVOp = cast<ShuffleVectorSDNode>(Op);
    V1 = Op.getOperand(0);
    V2 = Op.getOperand(1);
  }
  EVT VT = Op.getValueType();
  bool isLittleEndian = Subtarget.isLittleEndian();

  unsigned ShiftElts, InsertAtByte;
  bool Swap = false;

  // If this is a load-and-splat, we can do that with a single instruction
  // in some cases. However if the load has multiple uses, we don't want to
  // combine it because that will just produce multiple loads.
  bool IsPermutedLoad = false;
  const SDValue *InputLoad = getNormalLoadInput(V1, IsPermutedLoad);
  if (InputLoad && Subtarget.hasVSX() && V2.isUndef() &&
      (PPC::isSplatShuffleMask(SVOp, 4) || PPC::isSplatShuffleMask(SVOp, 8)) &&
      InputLoad->hasOneUse()) {
    bool IsFourByte = PPC::isSplatShuffleMask(SVOp, 4);
    int SplatIdx =
      PPC::getSplatIdxForPPCMnemonics(SVOp, IsFourByte ? 4 : 8, DAG);

    // The splat index for permuted loads will be in the left half of the vector
    // which is strictly wider than the loaded value by 8 bytes. So we need to
    // adjust the splat index to point to the correct address in memory.
    if (IsPermutedLoad) {
      assert((isLittleEndian || IsFourByte) &&
             "Unexpected size for permuted load on big endian target");
      SplatIdx += IsFourByte ? 2 : 1;
      assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
             "Splat of a value outside of the loaded memory");
    }

    LoadSDNode *LD = cast<LoadSDNode>(*InputLoad);
    // For 4-byte load-and-splat, we need Power9.
    if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
      uint64_t Offset = 0;
      if (IsFourByte)
        Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
      else
        Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;

      // If the width of the load is the same as the width of the splat,
      // loading with an offset would load the wrong memory.
      if (LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
        Offset = 0;

      SDValue BasePtr = LD->getBasePtr();
      if (Offset != 0)
        BasePtr = DAG.getNode(ISD::ADD, dl, getPointerTy(DAG.getDataLayout()),
                              BasePtr, DAG.getIntPtrConstant(Offset, dl));
      SDValue Ops[] = {
        LD->getChain(),    // Chain
        BasePtr,           // BasePtr
        DAG.getValueType(Op.getValueType()) // VT
      };
      SDVTList VTL =
        DAG.getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
      SDValue LdSplt =
        DAG.getMemIntrinsicNode(PPCISD::LD_SPLAT, dl, VTL,
                                Ops, LD->getMemoryVT(), LD->getMemOperand());
      DAG.ReplaceAllUsesOfValueWith(InputLoad->getValue(1), LdSplt.getValue(1));
      if (LdSplt.getValueType() != SVOp->getValueType(0))
        LdSplt = DAG.getBitcast(SVOp->getValueType(0), LdSplt);
      return LdSplt;
    }
  }

  // All v2i64 and v2f64 shuffles are legal
  if (VT == MVT::v2i64 || VT == MVT::v2f64)
    return Op;

  if (Subtarget.hasP9Vector() &&
      PPC::isXXINSERTWMask(SVOp, ShiftElts, InsertAtByte, Swap,
                           isLittleEndian)) {
    if (V2.isUndef())
      V2 = V1;
    else if (Swap)
      std::swap(V1, V2);
    SDValue Conv1 = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, V1);
    SDValue Conv2 = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, V2);
    if (ShiftElts) {
      SDValue Shl = DAG.getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv2, Conv2,
                                DAG.getConstant(ShiftElts, dl, MVT::i32));
      SDValue Ins = DAG.getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Shl,
                                DAG.getConstant(InsertAtByte, dl, MVT::i32));
      return DAG.getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
    }
    SDValue Ins = DAG.getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Conv2,
                              DAG.getConstant(InsertAtByte, dl, MVT::i32));
    return DAG.getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
  }

  if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
    SDValue SplatInsertNode;
    if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
      return SplatInsertNode;
  }

  if (Subtarget.hasP9Altivec()) {
    SDValue NewISDNode;
    if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
      return NewISDNode;

    if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
      return NewISDNode;
  }

  if (Subtarget.hasVSX() &&
      PPC::isXXSLDWIShuffleMask(SVOp, ShiftElts, Swap, isLittleEndian)) {
    if (Swap)
      std::swap(V1, V2);
    SDValue Conv1 = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, V1);
    SDValue Conv2 =
        DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, V2.isUndef() ? V1 : V2);

    SDValue Shl = DAG.getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv1, Conv2,
                              DAG.getConstant(ShiftElts, dl, MVT::i32));
    return DAG.getNode(ISD::BITCAST, dl, MVT::v16i8, Shl);
  }

  if (Subtarget.hasVSX() &&
    PPC::isXXPERMDIShuffleMask(SVOp, ShiftElts, Swap, isLittleEndian)) {
    if (Swap)
      std::swap(V1, V2);
    SDValue Conv1 = DAG.getNode(ISD::BITCAST, dl, MVT::v2i64, V1);
    SDValue Conv2 =
        DAG.getNode(ISD::BITCAST, dl, MVT::v2i64, V2.isUndef() ? V1 : V2);

    SDValue PermDI = DAG.getNode(PPCISD::XXPERMDI, dl, MVT::v2i64, Conv1, Conv2,
                              DAG.getConstant(ShiftElts, dl, MVT::i32));
    return DAG.getNode(ISD::BITCAST, dl, MVT::v16i8, PermDI);
  }

  if (Subtarget.hasP9Vector()) {
     if (PPC::isXXBRHShuffleMask(SVOp)) {
      SDValue Conv = DAG.getNode(ISD::BITCAST, dl, MVT::v8i16, V1);
      SDValue ReveHWord = DAG.getNode(ISD::BSWAP, dl, MVT::v8i16, Conv);
      return DAG.getNode(ISD::BITCAST, dl, MVT::v16i8, ReveHWord);
    } else if (PPC::isXXBRWShuffleMask(SVOp)) {
      SDValue Conv = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, V1);
      SDValue ReveWord = DAG.getNode(ISD::BSWAP, dl, MVT::v4i32, Conv);
      return DAG.getNode(ISD::BITCAST, dl, MVT::v16i8, ReveWord);
    } else if (PPC::isXXBRDShuffleMask(SVOp)) {
      SDValue Conv = DAG.getNode(ISD::BITCAST, dl, MVT::v2i64, V1);
      SDValue ReveDWord = DAG.getNode(ISD::BSWAP, dl, MVT::v2i64, Conv);
      return DAG.getNode(ISD::BITCAST, dl, MVT::v16i8, ReveDWord);
    } else if (PPC::isXXBRQShuffleMask(SVOp)) {
      SDValue Conv = DAG.getNode(ISD::BITCAST, dl, MVT::v1i128, V1);
      SDValue ReveQWord = DAG.getNode(ISD::BSWAP, dl, MVT::v1i128, Conv);
      return DAG.getNode(ISD::BITCAST, dl, MVT::v16i8, ReveQWord);
    }
  }

  if (Subtarget.hasVSX()) {
    if (V2.isUndef() && PPC::isSplatShuffleMask(SVOp, 4)) {
      int SplatIdx = PPC::getSplatIdxForPPCMnemonics(SVOp, 4, DAG);

      SDValue Conv = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, V1);
      SDValue Splat = DAG.getNode(PPCISD::XXSPLT, dl, MVT::v4i32, Conv,
                                  DAG.getConstant(SplatIdx, dl, MVT::i32));
      return DAG.getNode(ISD::BITCAST, dl, MVT::v16i8, Splat);
    }

    // Left shifts of 8 bytes are actually swaps. Convert accordingly.
    if (V2.isUndef() && PPC::isVSLDOIShuffleMask(SVOp, 1, DAG) == 8) {
      SDValue Conv = DAG.getNode(ISD::BITCAST, dl, MVT::v2f64, V1);
      SDValue Swap = DAG.getNode(PPCISD::SWAP_NO_CHAIN, dl, MVT::v2f64, Conv);
      return DAG.getNode(ISD::BITCAST, dl, MVT::v16i8, Swap);
    }
  }

  // Cases that are handled by instructions that take permute immediates
  // (such as vsplt*) should be left as VECTOR_SHUFFLE nodes so they can be
  // selected by the instruction selector.
  if (V2.isUndef()) {
    if (PPC::isSplatShuffleMask(SVOp, 1) ||
        PPC::isSplatShuffleMask(SVOp, 2) ||
        PPC::isSplatShuffleMask(SVOp, 4) ||
        PPC::isVPKUWUMShuffleMask(SVOp, 1, DAG) ||
        PPC::isVPKUHUMShuffleMask(SVOp, 1, DAG) ||
        PPC::isVSLDOIShuffleMask(SVOp, 1, DAG) != -1 ||
        PPC::isVMRGLShuffleMask(SVOp, 1, 1, DAG) ||
        PPC::isVMRGLShuffleMask(SVOp, 2, 1, DAG) ||
        PPC::isVMRGLShuffleMask(SVOp, 4, 1, DAG) ||
        PPC::isVMRGHShuffleMask(SVOp, 1, 1, DAG) ||
        PPC::isVMRGHShuffleMask(SVOp, 2, 1, DAG) ||
        PPC::isVMRGHShuffleMask(SVOp, 4, 1, DAG) ||
        (Subtarget.hasP8Altivec() && (
         PPC::isVPKUDUMShuffleMask(SVOp, 1, DAG) ||
         PPC::isVMRGEOShuffleMask(SVOp, true, 1, DAG) ||
         PPC::isVMRGEOShuffleMask(SVOp, false, 1, DAG)))) {
      return Op;
    }
  }

  // Altivec has a variety of "shuffle immediates" that take two vector inputs
  // and produce a fixed permutation.  If any of these match, do not lower to
  // VPERM.
  unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
  if (PPC::isVPKUWUMShuffleMask(SVOp, ShuffleKind, DAG) ||
      PPC::isVPKUHUMShuffleMask(SVOp, ShuffleKind, DAG) ||
      PPC::isVSLDOIShuffleMask(SVOp, ShuffleKind, DAG) != -1 ||
      PPC::isVMRGLShuffleMask(SVOp, 1, ShuffleKind, DAG) ||
      PPC::isVMRGLShuffleMask(SVOp, 2, ShuffleKind, DAG) ||
      PPC::isVMRGLShuffleMask(SVOp, 4, ShuffleKind, DAG) ||
      PPC::isVMRGHShuffleMask(SVOp, 1, ShuffleKind, DAG) ||
      PPC::isVMRGHShuffleMask(SVOp, 2, ShuffleKind, DAG) ||
      PPC::isVMRGHShuffleMask(SVOp, 4, ShuffleKind, DAG) ||
      (Subtarget.hasP8Altivec() && (
       PPC::isVPKUDUMShuffleMask(SVOp, ShuffleKind, DAG) ||
       PPC::isVMRGEOShuffleMask(SVOp, true, ShuffleKind, DAG) ||
       PPC::isVMRGEOShuffleMask(SVOp, false, ShuffleKind, DAG))))
    return Op;

  // Check to see if this is a shuffle of 4-byte values.  If so, we can use our
  // perfect shuffle table to emit an optimal matching sequence.
  ArrayRef<int> PermMask = SVOp->getMask();

  if (!DisablePerfectShuffle && !isLittleEndian) {
    unsigned PFIndexes[4];
    bool isFourElementShuffle = true;
    for (unsigned i = 0; i != 4 && isFourElementShuffle;
         ++i) {                           // Element number
      unsigned EltNo = 8;                 // Start out undef.
      for (unsigned j = 0; j != 4; ++j) { // Intra-element byte.
        if (PermMask[i * 4 + j] < 0)
          continue; // Undef, ignore it.

        unsigned ByteSource = PermMask[i * 4 + j];
        if ((ByteSource & 3) != j) {
          isFourElementShuffle = false;
          break;
        }

        if (EltNo == 8) {
          EltNo = ByteSource / 4;
        } else if (EltNo != ByteSource / 4) {
          isFourElementShuffle = false;
          break;
        }
      }
      PFIndexes[i] = EltNo;
    }

    // If this shuffle can be expressed as a shuffle of 4-byte elements, use the
    // perfect shuffle vector to determine if it is cost effective to do this as
    // discrete instructions, or whether we should use a vperm.
    // For now, we skip this for little endian until such time as we have a
    // little-endian perfect shuffle table.
    if (isFourElementShuffle) {
      // Compute the index in the perfect shuffle table.
      unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
                              PFIndexes[2] * 9 + PFIndexes[3];

      unsigned PFEntry = PerfectShuffleTable[PFTableIndex];
      unsigned Cost = (PFEntry >> 30);

      // Determining when to avoid vperm is tricky.  Many things affect the cost
      // of vperm, particularly how many times the perm mask needs to be
      // computed. For example, if the perm mask can be hoisted out of a loop or
      // is already used (perhaps because there are multiple permutes with the
      // same shuffle mask?) the vperm has a cost of 1.  OTOH, hoisting the
      // permute mask out of the loop requires an extra register.
      //
      // As a compromise, we only emit discrete instructions if the shuffle can
      // be generated in 3 or fewer operations.  When we have loop information
      // available, if this block is within a loop, we should avoid using vperm
      // for 3-operation perms and use a constant pool load instead.
      if (Cost < 3)
        return GeneratePerfectShuffle(PFEntry, V1, V2, DAG, dl);
    }
  }

  // Lower this to a VPERM(V1, V2, V3) expression, where V3 is a constant
  // vector that will get spilled to the constant pool.
  if (V2.isUndef()) V2 = V1;

  return LowerVPERM(Op, DAG, PermMask, VT, V1, V2);
}

SDValue PPCTargetLowering::LowerVPERM(SDValue Op, SelectionDAG &DAG,
                                      ArrayRef<int> PermMask, EVT VT,
                                      SDValue V1, SDValue V2) const {
  unsigned Opcode = PPCISD::VPERM;
  EVT ValType = V1.getValueType();
  SDLoc dl(Op);
  bool NeedSwap = false;
  bool isLittleEndian = Subtarget.isLittleEndian();
  bool isPPC64 = Subtarget.isPPC64();

  if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
      (V1->hasOneUse() || V2->hasOneUse())) {
    LLVM_DEBUG(dbgs() << "At least one of two input vectors are dead - using "
                         "XXPERM instead\n");
    Opcode = PPCISD::XXPERM;

    // The second input to XXPERM is also an output so if the second input has
    // multiple uses then copying is necessary, as a result we want the
    // single-use operand to be used as the second input to prevent copying.
    if ((!isLittleEndian && !V2->hasOneUse() && V1->hasOneUse()) ||
        (isLittleEndian && !V1->hasOneUse() && V2->hasOneUse())) {
      std::swap(V1, V2);
      NeedSwap = !NeedSwap;
    }
  }

  // The SHUFFLE_VECTOR mask is almost exactly what we want for vperm, except
  // that it is in input element units, not in bytes.  Convert now.

  // For little endian, the order of the input vectors is reversed, and
  // the permutation mask is complemented with respect to 31.  This is
  // necessary to produce proper semantics with the big-endian-based vperm
  // instruction.
  EVT EltVT = V1.getValueType().getVectorElementType();
  unsigned BytesPerElement = EltVT.getSizeInBits() / 8;

  bool V1HasXXSWAPD = V1->getOperand(0)->getOpcode() == PPCISD::XXSWAPD;
  bool V2HasXXSWAPD = V2->getOperand(0)->getOpcode() == PPCISD::XXSWAPD;

  /*
  Vectors will be appended like so: [ V1 | v2 ]
  XXSWAPD on V1:
  [   A   |   B   |   C   |   D   ] -> [   C   |   D   |   A   |   B   ]
     0-3     4-7     8-11   12-15         0-3     4-7     8-11   12-15
  i.e.  index of A, B += 8, and index of C, D -= 8.
  XXSWAPD on V2:
  [   E   |   F   |   G   |   H   ] -> [   G   |   H   |   E   |   F   ]
    16-19   20-23   24-27   28-31        16-19   20-23   24-27   28-31
  i.e.  index of E, F += 8, index of G, H -= 8
  Swap V1 and V2:
  [   V1   |   V2  ] -> [   V2   |   V1   ]
     0-15     16-31        0-15     16-31
  i.e.  index of V1 += 16, index of V2 -= 16
  */

  SmallVector<SDValue, 16> ResultMask;
  for (unsigned i = 0, e = VT.getVectorNumElements(); i != e; ++i) {
    unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];

    if (V1HasXXSWAPD) {
      if (SrcElt < 8)
        SrcElt += 8;
      else if (SrcElt < 16)
        SrcElt -= 8;
    }
    if (V2HasXXSWAPD) {
      if (SrcElt > 23)
        SrcElt -= 8;
      else if (SrcElt > 15)
        SrcElt += 8;
    }
    if (NeedSwap) {
      if (SrcElt < 16)
        SrcElt += 16;
      else
        SrcElt -= 16;
    }
    for (unsigned j = 0; j != BytesPerElement; ++j)
      if (isLittleEndian)
        ResultMask.push_back(
            DAG.getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
      else
        ResultMask.push_back(
            DAG.getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
  }

  if (V1HasXXSWAPD) {
    dl = SDLoc(V1->getOperand(0));
    V1 = V1->getOperand(0)->getOperand(1);
  }
  if (V2HasXXSWAPD) {
    dl = SDLoc(V2->getOperand(0));
    V2 = V2->getOperand(0)->getOperand(1);
  }

  if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
    if (ValType != MVT::v2f64)
      V1 = DAG.getBitcast(MVT::v2f64, V1);
    if (V2.getValueType() != MVT::v2f64)
      V2 = DAG.getBitcast(MVT::v2f64, V2);
  }

  ShufflesHandledWithVPERM++;
  SDValue VPermMask = DAG.getBuildVector(MVT::v16i8, dl, ResultMask);
  LLVM_DEBUG({
    ShuffleVectorSDNode *SVOp = cast<ShuffleVectorSDNode>(Op);
    if (Opcode == PPCISD::XXPERM) {
      dbgs() << "Emitting a XXPERM for the following shuffle:\n";
    } else {
      dbgs() << "Emitting a VPERM for the following shuffle:\n";
    }
    SVOp->dump();
    dbgs() << "With the following permute control vector:\n";
    VPermMask.dump();
  });

  if (Opcode == PPCISD::XXPERM)
    VPermMask = DAG.getBitcast(MVT::v4i32, VPermMask);

  // Only need to place items backwards in LE,
  // the mask was properly calculated.
  if (isLittleEndian)
    std::swap(V1, V2);

  SDValue VPERMNode =
      DAG.getNode(Opcode, dl, V1.getValueType(), V1, V2, VPermMask);

  VPERMNode = DAG.getBitcast(ValType, VPERMNode);
  return VPERMNode;
}

/// getVectorCompareInfo - Given an intrinsic, return false if it is not a
/// vector comparison.  If it is, return true and fill in Opc/isDot with
/// information about the intrinsic.
static bool getVectorCompareInfo(SDValue Intrin, int &CompareOpc,
                                 bool &isDot, const PPCSubtarget &Subtarget) {
  unsigned IntrinsicID = Intrin.getConstantOperandVal(0);
  CompareOpc = -1;
  isDot = false;
  switch (IntrinsicID) {
  default:
    return false;
  // Comparison predicates.
  case Intrinsic::ppc_altivec_vcmpbfp_p:
    CompareOpc = 966;
    isDot = true;
    break;
  case Intrinsic::ppc_altivec_vcmpeqfp_p:
    CompareOpc = 198;
    isDot = true;
    break;
  case Intrinsic::ppc_altivec_vcmpequb_p:
    CompareOpc = 6;
    isDot = true;
    break;
  case Intrinsic::ppc_altivec_vcmpequh_p:
    CompareOpc = 70;
    isDot = true;
    break;
  case Intrinsic::ppc_altivec_vcmpequw_p:
    CompareOpc = 134;
    isDot = true;
    break;
  case Intrinsic::ppc_altivec_vcmpequd_p:
    if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
      CompareOpc = 199;
      isDot = true;
    } else
      return false;
    break;
  case Intrinsic::ppc_altivec_vcmpneb_p:
  case Intrinsic::ppc_altivec_vcmpneh_p:
  case Intrinsic::ppc_altivec_vcmpnew_p:
  case Intrinsic::ppc_altivec_vcmpnezb_p:
  case Intrinsic::ppc_altivec_vcmpnezh_p:
  case Intrinsic::ppc_altivec_vcmpnezw_p:
    if (Subtarget.hasP9Altivec()) {
      switch (IntrinsicID) {
      default:
        llvm_unreachable("Unknown comparison intrinsic.");
      case Intrinsic::ppc_altivec_vcmpneb_p:
        CompareOpc = 7;
        break;
      case Intrinsic::ppc_altivec_vcmpneh_p:
        CompareOpc = 71;
        break;
      case Intrinsic::ppc_altivec_vcmpnew_p:
        CompareOpc = 135;
        break;
      case Intrinsic::ppc_altivec_vcmpnezb_p:
        CompareOpc = 263;
        break;
      case Intrinsic::ppc_altivec_vcmpnezh_p:
        CompareOpc = 327;
        break;
      case Intrinsic::ppc_altivec_vcmpnezw_p:
        CompareOpc = 391;
        break;
      }
      isDot = true;
    } else
      return false;
    break;
  case Intrinsic::ppc_altivec_vcmpgefp_p:
    CompareOpc = 454;
    isDot = true;
    break;
  case Intrinsic::ppc_altivec_vcmpgtfp_p:
    CompareOpc = 710;
    isDot = true;
    break;
  case Intrinsic::ppc_altivec_vcmpgtsb_p:
    CompareOpc = 774;
    isDot = true;
    break;
  case Intrinsic::ppc_altivec_vcmpgtsh_p:
    CompareOpc = 838;
    isDot = true;
    break;
  case Intrinsic::ppc_altivec_vcmpgtsw_p:
    CompareOpc = 902;
    isDot = true;
    break;
  case Intrinsic::ppc_altivec_vcmpgtsd_p:
    if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
      CompareOpc = 967;
      isDot = true;
    } else
      return false;
    break;
  case Intrinsic::ppc_altivec_vcmpgtub_p:
    CompareOpc = 518;
    isDot = true;
    break;
  case Intrinsic::ppc_altivec_vcmpgtuh_p:
    CompareOpc = 582;
    isDot = true;
    break;
  case Intrinsic::ppc_altivec_vcmpgtuw_p:
    CompareOpc = 646;
    isDot = true;
    break;
  case Intrinsic::ppc_altivec_vcmpgtud_p:
    if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
      CompareOpc = 711;
      isDot = true;
    } else
      return false;
    break;

  case Intrinsic::ppc_altivec_vcmpequq:
  case Intrinsic::ppc_altivec_vcmpgtsq:
  case Intrinsic::ppc_altivec_vcmpgtuq:
    if (!Subtarget.isISA3_1())
      return false;
    switch (IntrinsicID) {
    default:
      llvm_unreachable("Unknown comparison intrinsic.");
    case Intrinsic::ppc_altivec_vcmpequq:
      CompareOpc = 455;
      break;
    case Intrinsic::ppc_altivec_vcmpgtsq:
      CompareOpc = 903;
      break;
    case Intrinsic::ppc_altivec_vcmpgtuq:
      CompareOpc = 647;
      break;
    }
    break;

  // VSX predicate comparisons use the same infrastructure
  case Intrinsic::ppc_vsx_xvcmpeqdp_p:
  case Intrinsic::ppc_vsx_xvcmpgedp_p:
  case Intrinsic::ppc_vsx_xvcmpgtdp_p:
  case Intrinsic::ppc_vsx_xvcmpeqsp_p:
  case Intrinsic::ppc_vsx_xvcmpgesp_p:
  case Intrinsic::ppc_vsx_xvcmpgtsp_p:
    if (Subtarget.hasVSX()) {
      switch (IntrinsicID) {
      case Intrinsic::ppc_vsx_xvcmpeqdp_p:
        CompareOpc = 99;
        break;
      case Intrinsic::ppc_vsx_xvcmpgedp_p:
        CompareOpc = 115;
        break;
      case Intrinsic::ppc_vsx_xvcmpgtdp_p:
        CompareOpc = 107;
        break;
      case Intrinsic::ppc_vsx_xvcmpeqsp_p:
        CompareOpc = 67;
        break;
      case Intrinsic::ppc_vsx_xvcmpgesp_p:
        CompareOpc = 83;
        break;
      case Intrinsic::ppc_vsx_xvcmpgtsp_p:
        CompareOpc = 75;
        break;
      }
      isDot = true;
    } else
      return false;
    break;

  // Normal Comparisons.
  case Intrinsic::ppc_altivec_vcmpbfp:
    CompareOpc = 966;
    break;
  case Intrinsic::ppc_altivec_vcmpeqfp:
    CompareOpc = 198;
    break;
  case Intrinsic::ppc_altivec_vcmpequb:
    CompareOpc = 6;
    break;
  case Intrinsic::ppc_altivec_vcmpequh:
    CompareOpc = 70;
    break;
  case Intrinsic::ppc_altivec_vcmpequw:
    CompareOpc = 134;
    break;
  case Intrinsic::ppc_altivec_vcmpequd:
    if (Subtarget.hasP8Altivec())
      CompareOpc = 199;
    else
      return false;
    break;
  case Intrinsic::ppc_altivec_vcmpneb:
  case Intrinsic::ppc_altivec_vcmpneh:
  case Intrinsic::ppc_altivec_vcmpnew:
  case Intrinsic::ppc_altivec_vcmpnezb:
  case Intrinsic::ppc_altivec_vcmpnezh:
  case Intrinsic::ppc_altivec_vcmpnezw:
    if (Subtarget.hasP9Altivec())
      switch (IntrinsicID) {
      default:
        llvm_unreachable("Unknown comparison intrinsic.");
      case Intrinsic::ppc_altivec_vcmpneb:
        CompareOpc = 7;
        break;
      case Intrinsic::ppc_altivec_vcmpneh:
        CompareOpc = 71;
        break;
      case Intrinsic::ppc_altivec_vcmpnew:
        CompareOpc = 135;
        break;
      case Intrinsic::ppc_altivec_vcmpnezb:
        CompareOpc = 263;
        break;
      case Intrinsic::ppc_altivec_vcmpnezh:
        CompareOpc = 327;
        break;
      case Intrinsic::ppc_altivec_vcmpnezw:
        CompareOpc = 391;
        break;
      }
    else
      return false;
    break;
  case Intrinsic::ppc_altivec_vcmpgefp:
    CompareOpc = 454;
    break;
  case Intrinsic::ppc_altivec_vcmpgtfp:
    CompareOpc = 710;
    break;
  case Intrinsic::ppc_altivec_vcmpgtsb:
    CompareOpc = 774;
    break;
  case Intrinsic::ppc_altivec_vcmpgtsh:
    CompareOpc = 838;
    break;
  case Intrinsic::ppc_altivec_vcmpgtsw:
    CompareOpc = 902;
    break;
  case Intrinsic::ppc_altivec_vcmpgtsd:
    if (Subtarget.hasP8Altivec())
      CompareOpc = 967;
    else
      return false;
    break;
  case Intrinsic::ppc_altivec_vcmpgtub:
    CompareOpc = 518;
    break;
  case Intrinsic::ppc_altivec_vcmpgtuh:
    CompareOpc = 582;
    break;
  case Intrinsic::ppc_altivec_vcmpgtuw:
    CompareOpc = 646;
    break;
  case Intrinsic::ppc_altivec_vcmpgtud:
    if (Subtarget.hasP8Altivec())
      CompareOpc = 711;
    else
      return false;
    break;
  case Intrinsic::ppc_altivec_vcmpequq_p:
  case Intrinsic::ppc_altivec_vcmpgtsq_p:
  case Intrinsic::ppc_altivec_vcmpgtuq_p:
    if (!Subtarget.isISA3_1())
      return false;
    switch (IntrinsicID) {
    default:
      llvm_unreachable("Unknown comparison intrinsic.");
    case Intrinsic::ppc_altivec_vcmpequq_p:
      CompareOpc = 455;
      break;
    case Intrinsic::ppc_altivec_vcmpgtsq_p:
      CompareOpc = 903;
      break;
    case Intrinsic::ppc_altivec_vcmpgtuq_p:
      CompareOpc = 647;
      break;
    }
    isDot = true;
    break;
  }
  return true;
}

/// LowerINTRINSIC_WO_CHAIN - If this is an intrinsic that we want to custom
/// lower, do it, otherwise return null.
SDValue PPCTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
                                                   SelectionDAG &DAG) const {
  unsigned IntrinsicID = Op.getConstantOperandVal(0);

  SDLoc dl(Op);

  switch (IntrinsicID) {
  case Intrinsic::thread_pointer:
    // Reads the thread pointer register, used for __builtin_thread_pointer.
    if (Subtarget.isPPC64())
      return DAG.getRegister(PPC::X13, MVT::i64);
    return DAG.getRegister(PPC::R2, MVT::i32);

  case Intrinsic::ppc_rldimi: {
    assert(Subtarget.isPPC64() && "rldimi is only available in 64-bit!");
    SDValue Src = Op.getOperand(1);
    APInt Mask = Op.getConstantOperandAPInt(4);
    if (Mask.isZero())
      return Op.getOperand(2);
    if (Mask.isAllOnes())
      return DAG.getNode(ISD::ROTL, dl, MVT::i64, Src, Op.getOperand(3));
    uint64_t SH = Op.getConstantOperandVal(3);
    unsigned MB = 0, ME = 0;
    if (!isRunOfOnes64(Mask.getZExtValue(), MB, ME))
      report_fatal_error("invalid rldimi mask!");
    // rldimi requires ME=63-SH, otherwise rotation is needed before rldimi.
    if (ME < 63 - SH) {
      Src = DAG.getNode(ISD::ROTL, dl, MVT::i64, Src,
                        DAG.getConstant(ME + SH + 1, dl, MVT::i32));
    } else if (ME > 63 - SH) {
      Src = DAG.getNode(ISD::ROTL, dl, MVT::i64, Src,
                        DAG.getConstant(ME + SH - 63, dl, MVT::i32));
    }
    return SDValue(
        DAG.getMachineNode(PPC::RLDIMI, dl, MVT::i64,
                           {Op.getOperand(2), Src,
                            DAG.getTargetConstant(63 - ME, dl, MVT::i32),
                            DAG.getTargetConstant(MB, dl, MVT::i32)}),
        0);
  }

  case Intrinsic::ppc_rlwimi: {
    APInt Mask = Op.getConstantOperandAPInt(4);
    if (Mask.isZero())
      return Op.getOperand(2);
    if (Mask.isAllOnes())
      return DAG.getNode(ISD::ROTL, dl, MVT::i32, Op.getOperand(1),
                         Op.getOperand(3));
    unsigned MB = 0, ME = 0;
    if (!isRunOfOnes(Mask.getZExtValue(), MB, ME))
      report_fatal_error("invalid rlwimi mask!");
    return SDValue(DAG.getMachineNode(
                       PPC::RLWIMI, dl, MVT::i32,
                       {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
                        DAG.getTargetConstant(MB, dl, MVT::i32),
                        DAG.getTargetConstant(ME, dl, MVT::i32)}),
                   0);
  }

  case Intrinsic::ppc_rlwnm: {
    if (Op.getConstantOperandVal(3) == 0)
      return DAG.getConstant(0, dl, MVT::i32);
    unsigned MB = 0, ME = 0;
    if (!isRunOfOnes(Op.getConstantOperandVal(3), MB, ME))
      report_fatal_error("invalid rlwnm mask!");
    return SDValue(
        DAG.getMachineNode(PPC::RLWNM, dl, MVT::i32,
                           {Op.getOperand(1), Op.getOperand(2),
                            DAG.getTargetConstant(MB, dl, MVT::i32),
                            DAG.getTargetConstant(ME, dl, MVT::i32)}),
        0);
  }

  case Intrinsic::ppc_mma_disassemble_acc: {
    if (Subtarget.isISAFuture()) {
      EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
      SDValue WideVec =
          SDValue(DAG.getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes,
                                     Op.getOperand(1)),
                  0);
      SmallVector<SDValue, 4> RetOps;
      SDValue Value = SDValue(WideVec.getNode(), 0);
      SDValue Value2 = SDValue(WideVec.getNode(), 1);

      SDValue Extract;
      Extract = DAG.getNode(
          PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
          Subtarget.isLittleEndian() ? Value2 : Value,
          DAG.getConstant(Subtarget.isLittleEndian() ? 1 : 0,
                          dl, getPointerTy(DAG.getDataLayout())));
      RetOps.push_back(Extract);
      Extract = DAG.getNode(
          PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
          Subtarget.isLittleEndian() ? Value2 : Value,
          DAG.getConstant(Subtarget.isLittleEndian() ? 0 : 1,
                          dl, getPointerTy(DAG.getDataLayout())));
      RetOps.push_back(Extract);
      Extract = DAG.getNode(
          PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
          Subtarget.isLittleEndian() ? Value : Value2,
          DAG.getConstant(Subtarget.isLittleEndian() ? 1 : 0,
                          dl, getPointerTy(DAG.getDataLayout())));
      RetOps.push_back(Extract);
      Extract = DAG.getNode(
          PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
          Subtarget.isLittleEndian() ? Value : Value2,
          DAG.getConstant(Subtarget.isLittleEndian() ? 0 : 1,
                          dl, getPointerTy(DAG.getDataLayout())));
      RetOps.push_back(Extract);
      return DAG.getMergeValues(RetOps, dl);
    }
    [[fallthrough]];
  }
  case Intrinsic::ppc_vsx_disassemble_pair: {
    int NumVecs = 2;
    SDValue WideVec = Op.getOperand(1);
    if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
      NumVecs = 4;
      WideVec = DAG.getNode(PPCISD::XXMFACC, dl, MVT::v512i1, WideVec);
    }
    SmallVector<SDValue, 4> RetOps;
    for (int VecNo = 0; VecNo < NumVecs; VecNo++) {
      SDValue Extract = DAG.getNode(
          PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8, WideVec,
          DAG.getConstant(Subtarget.isLittleEndian() ? NumVecs - 1 - VecNo
                                                     : VecNo,
                          dl, getPointerTy(DAG.getDataLayout())));
      RetOps.push_back(Extract);
    }
    return DAG.getMergeValues(RetOps, dl);
  }

  case Intrinsic::ppc_mma_build_dmr: {
    SmallVector<SDValue, 8> Pairs;
    SmallVector<SDValue, 8> Chains;
    for (int i = 1; i < 9; i += 2) {
      SDValue Hi = Op.getOperand(i);
      SDValue Lo = Op.getOperand(i + 1);
      if (Hi->getOpcode() == ISD::LOAD)
        Chains.push_back(Hi.getValue(1));
      if (Lo->getOpcode() == ISD::LOAD)
        Chains.push_back(Lo.getValue(1));
      Pairs.push_back(
          DAG.getNode(PPCISD::PAIR_BUILD, dl, MVT::v256i1, {Hi, Lo}));
    }
    SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Chains);
    SDValue Value = DMFInsert1024(Pairs, SDLoc(Op), DAG);
    return DAG.getMergeValues({Value, TF}, dl);
  }

  case Intrinsic::ppc_mma_dmxxextfdmr512: {
    assert(Subtarget.isISAFuture() && "dmxxextfdmr512 requires ISA Future");
    auto *Idx = dyn_cast<ConstantSDNode>(Op.getOperand(2));
    assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
           "Specify P of 0 or 1 for lower or upper 512 bytes");
    unsigned HiLo = Idx->getSExtValue();
    unsigned Opcode;
    unsigned Subx;
    if (HiLo == 0) {
      Opcode = PPC::DMXXEXTFDMR512;
      Subx = PPC::sub_wacc_lo;
    } else {
      Opcode = PPC::DMXXEXTFDMR512_HI;
      Subx = PPC::sub_wacc_hi;
    }
    SDValue Subreg(
        DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
                           Op.getOperand(1),
                           DAG.getTargetConstant(Subx, dl, MVT::i32)),
        0);
    EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
    return SDValue(DAG.getMachineNode(Opcode, dl, ReturnTypes, Subreg), 0);
  }

  case Intrinsic::ppc_mma_dmxxextfdmr256: {
    assert(Subtarget.isISAFuture() && "dmxxextfdmr256 requires ISA Future");
    auto *Idx = dyn_cast<ConstantSDNode>(Op.getOperand(2));
    assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
           "Specify a dmr row pair 0-3");
    unsigned IdxVal = Idx->getSExtValue();
    unsigned Subx;
    switch (IdxVal) {
    case 0:
      Subx = PPC::sub_dmrrowp0;
      break;
    case 1:
      Subx = PPC::sub_dmrrowp1;
      break;
    case 2:
      Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
      break;
    case 3:
      Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
      break;
    }
    SDValue Subreg(
        DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v256i1,
                           Op.getOperand(1),
                           DAG.getTargetConstant(Subx, dl, MVT::i32)),
        0);
    SDValue P = DAG.getTargetConstant(IdxVal, dl, MVT::i32);
    return SDValue(
        DAG.getMachineNode(PPC::DMXXEXTFDMR256, dl, MVT::v256i1, {Subreg, P}),
        0);
  }

  case Intrinsic::ppc_mma_dmxxinstdmr512: {
    assert(Subtarget.isISAFuture() && "dmxxinstdmr512 requires ISA Future");
    auto *Idx = dyn_cast<ConstantSDNode>(Op.getOperand(4));
    assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
           "Specify P of 0 or 1 for lower or upper 512 bytes");
    unsigned HiLo = Idx->getSExtValue();
    unsigned Opcode;
    unsigned Subx;
    if (HiLo == 0) {
      Opcode = PPCISD::INST512;
      Subx = PPC::sub_wacc_lo;
    } else {
      Opcode = PPCISD::INST512HI;
      Subx = PPC::sub_wacc_hi;
    }
    SDValue Wacc = DAG.getNode(Opcode, dl, MVT::v512i1, Op.getOperand(2),
                               Op.getOperand(3));
    SDValue SubReg = DAG.getTargetConstant(Subx, dl, MVT::i32);
    return SDValue(DAG.getMachineNode(PPC::INSERT_SUBREG, dl, MVT::v1024i1,
                                      Op.getOperand(1), Wacc, SubReg),
                   0);
  }

  case Intrinsic::ppc_mma_dmxxinstdmr256: {
    assert(Subtarget.isISAFuture() && "dmxxinstdmr256 requires ISA Future");
    auto *Idx = dyn_cast<ConstantSDNode>(Op.getOperand(3));
    assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
           "Specify a dmr row pair 0-3");
    unsigned IdxVal = Idx->getSExtValue();
    unsigned Subx;
    switch (IdxVal) {
    case 0:
      Subx = PPC::sub_dmrrowp0;
      break;
    case 1:
      Subx = PPC::sub_dmrrowp1;
      break;
    case 2:
      Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
      break;
    case 3:
      Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
      break;
    }
    SDValue SubReg = DAG.getTargetConstant(Subx, dl, MVT::i32);
    SDValue P = DAG.getTargetConstant(IdxVal, dl, MVT::i32);
    SDValue DMRRowp =
        DAG.getNode(PPCISD::INST256, dl, MVT::v256i1, Op.getOperand(2), P);
    return SDValue(DAG.getMachineNode(PPC::INSERT_SUBREG, dl, MVT::v1024i1,
                                      Op.getOperand(1), DMRRowp, SubReg),
                   0);
  }

  case Intrinsic::ppc_mma_xxmfacc:
  case Intrinsic::ppc_mma_xxmtacc: {
    // Allow pre-isa-future subtargets to lower as normal.
    if (!Subtarget.isISAFuture())
      return SDValue();
    // The intrinsics for xxmtacc and xxmfacc take one argument of
    // type v512i1, for future cpu the corresponding wacc instruction
    // dmxx[inst|extf]dmr512 is always generated for type v512i1, negating
    // the need to produce the xxm[t|f]acc.
    SDValue WideVec = Op.getOperand(1);
    DAG.ReplaceAllUsesWith(Op, WideVec);
    return SDValue();
  }

  case Intrinsic::ppc_unpack_longdouble: {
    auto *Idx = dyn_cast<ConstantSDNode>(Op.getOperand(2));
    assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
           "Argument of long double unpack must be 0 or 1!");
    return DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::f64, Op.getOperand(1),
                       DAG.getConstant(!!(Idx->getSExtValue()), dl,
                                       Idx->getValueType(0)));
  }

  case Intrinsic::ppc_compare_exp_lt:
  case Intrinsic::ppc_compare_exp_gt:
  case Intrinsic::ppc_compare_exp_eq:
  case Intrinsic::ppc_compare_exp_uo: {
    unsigned Pred;
    switch (IntrinsicID) {
    case Intrinsic::ppc_compare_exp_lt:
      Pred = PPC::PRED_LT;
      break;
    case Intrinsic::ppc_compare_exp_gt:
      Pred = PPC::PRED_GT;
      break;
    case Intrinsic::ppc_compare_exp_eq:
      Pred = PPC::PRED_EQ;
      break;
    case Intrinsic::ppc_compare_exp_uo:
      Pred = PPC::PRED_UN;
      break;
    }
    return SDValue(
        DAG.getMachineNode(
            PPC::SELECT_CC_I4, dl, MVT::i32,
            {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
                                        Op.getOperand(1), Op.getOperand(2)),
                     0),
             DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
             DAG.getTargetConstant(Pred, dl, MVT::i32)}),
        0);
  }
  case Intrinsic::ppc_test_data_class: {
    EVT OpVT = Op.getOperand(1).getValueType();
    unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
                                         : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
                                                             : PPC::XSTSTDCSP);
    return SDValue(
        DAG.getMachineNode(
            PPC::SELECT_CC_I4, dl, MVT::i32,
            {SDValue(DAG.getMachineNode(CmprOpc, dl, MVT::i32, Op.getOperand(2),
                                        Op.getOperand(1)),
                     0),
             DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
             DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
        0);
  }
  case Intrinsic::ppc_fnmsub: {
    EVT VT = Op.getOperand(1).getValueType();
    if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
      return DAG.getNode(
          ISD::FNEG, dl, VT,
          DAG.getNode(ISD::FMA, dl, VT, Op.getOperand(1), Op.getOperand(2),
                      DAG.getNode(ISD::FNEG, dl, VT, Op.getOperand(3))));
    return DAG.getNode(PPCISD::FNMSUB, dl, VT, Op.getOperand(1),
                       Op.getOperand(2), Op.getOperand(3));
  }
  case Intrinsic::ppc_convert_f128_to_ppcf128:
  case Intrinsic::ppc_convert_ppcf128_to_f128: {
    RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
                            ? RTLIB::CONVERT_PPCF128_F128
                            : RTLIB::CONVERT_F128_PPCF128;
    MakeLibCallOptions CallOptions;
    std::pair<SDValue, SDValue> Result =
        makeLibCall(DAG, LC, Op.getValueType(), Op.getOperand(1), CallOptions,
                    dl, SDValue());
    return Result.first;
  }
  case Intrinsic::ppc_maxfe:
  case Intrinsic::ppc_maxfl:
  case Intrinsic::ppc_maxfs:
  case Intrinsic::ppc_minfe:
  case Intrinsic::ppc_minfl:
  case Intrinsic::ppc_minfs: {
    EVT VT = Op.getValueType();
    assert(
        all_of(Op->ops().drop_front(4),
               [VT](const SDUse &Use) { return Use.getValueType() == VT; }) &&
        "ppc_[max|min]f[e|l|s] must have uniform type arguments");
    (void)VT;
    ISD::CondCode CC = ISD::SETGT;
    if (IntrinsicID == Intrinsic::ppc_minfe ||
        IntrinsicID == Intrinsic::ppc_minfl ||
        IntrinsicID == Intrinsic::ppc_minfs)
      CC = ISD::SETLT;
    unsigned I = Op.getNumOperands() - 2, Cnt = I;
    SDValue Res = Op.getOperand(I);
    for (--I; Cnt != 0; --Cnt, I = (--I == 0 ? (Op.getNumOperands() - 1) : I)) {
      Res =
          DAG.getSelectCC(dl, Res, Op.getOperand(I), Res, Op.getOperand(I), CC);
    }
    return Res;
  }
  }

  // If this is a lowered altivec predicate compare, CompareOpc is set to the
  // opcode number of the comparison.
  int CompareOpc;
  bool isDot;
  if (!getVectorCompareInfo(Op, CompareOpc, isDot, Subtarget))
    return SDValue();    // Don't custom lower most intrinsics.

  // If this is a non-dot comparison, make the VCMP node and we are done.
  if (!isDot) {
    SDValue Tmp = DAG.getNode(PPCISD::VCMP, dl, Op.getOperand(2).getValueType(),
                              Op.getOperand(1), Op.getOperand(2),
                              DAG.getConstant(CompareOpc, dl, MVT::i32));
    return DAG.getNode(ISD::BITCAST, dl, Op.getValueType(), Tmp);
  }

  // Create the PPCISD altivec 'dot' comparison node.
  SDValue Ops[] = {
    Op.getOperand(2),  // LHS
    Op.getOperand(3),  // RHS
    DAG.getConstant(CompareOpc, dl, MVT::i32)
  };
  EVT VTs[] = { Op.getOperand(2).getValueType(), MVT::Glue };
  SDValue CompNode = DAG.getNode(PPCISD::VCMP_rec, dl, VTs, Ops);

  // Unpack the result based on how the target uses it.
  unsigned BitNo; // Bit # of CR6.
  bool InvertBit; // Invert result?
  unsigned Bitx;
  unsigned SetOp;
  switch (Op.getConstantOperandVal(1)) {
  default: // Can't happen, don't crash on invalid number though.
  case 0:  // Return the value of the EQ bit of CR6.
    BitNo = 0;
    InvertBit = false;
    Bitx = PPC::sub_eq;
    SetOp = PPCISD::SETBC;
    break;
  case 1: // Return the inverted value of the EQ bit of CR6.
    BitNo = 0;
    InvertBit = true;
    Bitx = PPC::sub_eq;
    SetOp = PPCISD::SETBCR;
    break;
  case 2: // Return the value of the LT bit of CR6.
    BitNo = 2;
    InvertBit = false;
    Bitx = PPC::sub_lt;
    SetOp = PPCISD::SETBC;
    break;
  case 3: // Return the inverted value of the LT bit of CR6.
    BitNo = 2;
    InvertBit = true;
    Bitx = PPC::sub_lt;
    SetOp = PPCISD::SETBCR;
    break;
  }

  SDValue GlueOp = CompNode.getValue(1);
  if (Subtarget.isISA3_1()) {
    SDValue SubRegIdx = DAG.getTargetConstant(Bitx, dl, MVT::i32);
    SDValue CR6Reg = DAG.getRegister(PPC::CR6, MVT::i32);
    SDValue CRBit =
        SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
                                   CR6Reg, SubRegIdx, GlueOp),
                0);
    return DAG.getNode(SetOp, dl, MVT::i32, CRBit);
  }

  // Now that we have the comparison, emit a copy from the CR to a GPR.
  // This is flagged to the above dot comparison.
  SDValue Flags = DAG.getNode(PPCISD::MFOCRF, dl, MVT::i32,
                              DAG.getRegister(PPC::CR6, MVT::i32), GlueOp);

  // Shift the bit into the low position.
  Flags = DAG.getNode(ISD::SRL, dl, MVT::i32, Flags,
                      DAG.getConstant(8 - (3 - BitNo), dl, MVT::i32));
  // Isolate the bit.
  Flags = DAG.getNode(ISD::AND, dl, MVT::i32, Flags,
                      DAG.getConstant(1, dl, MVT::i32));

  // If we are supposed to, toggle the bit.
  if (InvertBit)
    Flags = DAG.getNode(ISD::XOR, dl, MVT::i32, Flags,
                        DAG.getConstant(1, dl, MVT::i32));
  return Flags;
}

SDValue PPCTargetLowering::LowerINTRINSIC_VOID(SDValue Op,
                                               SelectionDAG &DAG) const {
  // SelectionDAGBuilder::visitTargetIntrinsic may insert one extra chain to
  // the beginning of the argument list.
  int ArgStart = isa<ConstantSDNode>(Op.getOperand(0)) ? 0 : 1;
  SDLoc DL(Op);
  switch (Op.getConstantOperandVal(ArgStart)) {
  case Intrinsic::ppc_cfence: {
    assert(ArgStart == 1 && "llvm.ppc.cfence must carry a chain argument.");
    SDValue Val = Op.getOperand(ArgStart + 1);
    EVT Ty = Val.getValueType();
    if (Ty == MVT::i128) {
      // FIXME: Testing one of two paired registers is sufficient to guarantee
      // ordering?
      Val = DAG.getNode(ISD::TRUNCATE, DL, MVT::i64, Val);
    }
    unsigned Opcode = Subtarget.isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
    return SDValue(
        DAG.getMachineNode(
            Opcode, DL, MVT::Other,
            DAG.getNode(ISD::ANY_EXTEND, DL, Subtarget.getScalarIntVT(), Val),
            Op.getOperand(0)),
        0);
  }
  case Intrinsic::ppc_mma_disassemble_dmr: {
    return DAG.getStore(DAG.getEntryNode(), DL, Op.getOperand(ArgStart + 2),
                        Op.getOperand(ArgStart + 1), MachinePointerInfo());
  }
  default:
    break;
  }
  return SDValue();
}

// Lower scalar BSWAP64 to xxbrd.
SDValue PPCTargetLowering::LowerBSWAP(SDValue Op, SelectionDAG &DAG) const {
  SDLoc dl(Op);
  if (!Subtarget.isPPC64())
    return Op;
  // MTVSRDD
  Op = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64, Op.getOperand(0),
                   Op.getOperand(0));
  // XXBRD
  Op = DAG.getNode(ISD::BSWAP, dl, MVT::v2i64, Op);
  // MFVSRD
  int VectorIndex = 0;
  if (Subtarget.isLittleEndian())
    VectorIndex = 1;
  Op = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i64, Op,
                   DAG.getTargetConstant(VectorIndex, dl, MVT::i32));
  return Op;
}

// ATOMIC_CMP_SWAP for i8/i16 needs to zero-extend its input since it will be
// compared to a value that is atomically loaded (atomic loads zero-extend).
SDValue PPCTargetLowering::LowerATOMIC_CMP_SWAP(SDValue Op,
                                                SelectionDAG &DAG) const {
  assert(Op.getOpcode() == ISD::ATOMIC_CMP_SWAP &&
         "Expecting an atomic compare-and-swap here.");
  SDLoc dl(Op);
  auto *AtomicNode = cast<AtomicSDNode>(Op.getNode());
  EVT MemVT = AtomicNode->getMemoryVT();
  if (MemVT.getSizeInBits() >= 32)
    return Op;

  SDValue CmpOp = Op.getOperand(2);
  // If this is already correctly zero-extended, leave it alone.
  auto HighBits = APInt::getHighBitsSet(32, 32 - MemVT.getSizeInBits());
  if (DAG.MaskedValueIsZero(CmpOp, HighBits))
    return Op;

  // Clear the high bits of the compare operand.
  unsigned MaskVal = (1 << MemVT.getSizeInBits()) - 1;
  SDValue NewCmpOp =
    DAG.getNode(ISD::AND, dl, MVT::i32, CmpOp,
                DAG.getConstant(MaskVal, dl, MVT::i32));

  // Replace the existing compare operand with the properly zero-extended one.
  SmallVector<SDValue, 4> Ops;
  for (int i = 0, e = AtomicNode->getNumOperands(); i < e; i++)
    Ops.push_back(AtomicNode->getOperand(i));
  Ops[2] = NewCmpOp;
  MachineMemOperand *MMO = AtomicNode->getMemOperand();
  SDVTList Tys = DAG.getVTList(MVT::i32, MVT::Other);
  auto NodeTy =
    (MemVT == MVT::i8) ? PPCISD::ATOMIC_CMP_SWAP_8 : PPCISD::ATOMIC_CMP_SWAP_16;
  return DAG.getMemIntrinsicNode(NodeTy, dl, Tys, Ops, MemVT, MMO);
}

SDValue PPCTargetLowering::LowerATOMIC_LOAD_STORE(SDValue Op,
                                                  SelectionDAG &DAG) const {
  AtomicSDNode *N = cast<AtomicSDNode>(Op.getNode());
  EVT MemVT = N->getMemoryVT();
  assert(MemVT.getSimpleVT() == MVT::i128 &&
         "Expect quadword atomic operations");
  SDLoc dl(N);
  unsigned Opc = N->getOpcode();
  switch (Opc) {
  case ISD::ATOMIC_LOAD: {
    // Lower quadword atomic load to int_ppc_atomic_load_i128 which will be
    // lowered to ppc instructions by pattern matching instruction selector.
    SDVTList Tys = DAG.getVTList(MVT::i64, MVT::i64, MVT::Other);
    SmallVector<SDValue, 4> Ops{
        N->getOperand(0),
        DAG.getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
    for (int I = 1, E = N->getNumOperands(); I < E; ++I)
      Ops.push_back(N->getOperand(I));
    SDValue LoadedVal = DAG.getMemIntrinsicNode(ISD::INTRINSIC_W_CHAIN, dl, Tys,
                                                Ops, MemVT, N->getMemOperand());
    SDValue ValLo = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i128, LoadedVal);
    SDValue ValHi =
        DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i128, LoadedVal.getValue(1));
    ValHi = DAG.getNode(ISD::SHL, dl, MVT::i128, ValHi,
                        DAG.getConstant(64, dl, MVT::i32));
    SDValue Val =
        DAG.getNode(ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
    return DAG.getNode(ISD::MERGE_VALUES, dl, {MVT::i128, MVT::Other},
                       {Val, LoadedVal.getValue(2)});
  }
  case ISD::ATOMIC_STORE: {
    // Lower quadword atomic store to int_ppc_atomic_store_i128 which will be
    // lowered to ppc instructions by pattern matching instruction selector.
    SDVTList Tys = DAG.getVTList(MVT::Other);
    SmallVector<SDValue, 4> Ops{
        N->getOperand(0),
        DAG.getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
    SDValue Val = N->getOperand(1);
    SDValue ValLo = DAG.getNode(ISD::TRUNCATE, dl, MVT::i64, Val);
    SDValue ValHi = DAG.getNode(ISD::SRL, dl, MVT::i128, Val,
                                DAG.getConstant(64, dl, MVT::i32));
    ValHi = DAG.getNode(ISD::TRUNCATE, dl, MVT::i64, ValHi);
    Ops.push_back(ValLo);
    Ops.push_back(ValHi);
    Ops.push_back(N->getOperand(2));
    return DAG.getMemIntrinsicNode(ISD::INTRINSIC_VOID, dl, Tys, Ops, MemVT,
                                   N->getMemOperand());
  }
  default:
    llvm_unreachable("Unexpected atomic opcode");
  }
}

static SDValue getDataClassTest(SDValue Op, FPClassTest Mask, const SDLoc &Dl,
                                SelectionDAG &DAG,
                                const PPCSubtarget &Subtarget) {
  assert(Mask <= fcAllFlags && "Invalid fp_class flags!");

  enum DataClassMask {
    DC_NAN = 1 << 6,
    DC_NEG_INF = 1 << 4,
    DC_POS_INF = 1 << 5,
    DC_NEG_ZERO = 1 << 2,
    DC_POS_ZERO = 1 << 3,
    DC_NEG_SUBNORM = 1,
    DC_POS_SUBNORM = 1 << 1,
  };

  EVT VT = Op.getValueType();

  unsigned TestOp = VT == MVT::f128  ? PPC::XSTSTDCQP
                    : VT == MVT::f64 ? PPC::XSTSTDCDP
                                     : PPC::XSTSTDCSP;

  if (Mask == fcAllFlags)
    return DAG.getBoolConstant(true, Dl, MVT::i1, VT);
  if (Mask == 0)
    return DAG.getBoolConstant(false, Dl, MVT::i1, VT);

  // When it's cheaper or necessary to test reverse flags.
  if ((Mask & fcNormal) == fcNormal || Mask == ~fcQNan || Mask == ~fcSNan) {
    SDValue Rev = getDataClassTest(Op, ~Mask, Dl, DAG, Subtarget);
    return DAG.getNOT(Dl, Rev, MVT::i1);
  }

  // Power doesn't support testing whether a value is 'normal'. Test the rest
  // first, and test if it's 'not not-normal' with expected sign.
  if (Mask & fcNormal) {
    SDValue Rev(DAG.getMachineNode(
                    TestOp, Dl, MVT::i32,
                    DAG.getTargetConstant(DC_NAN | DC_NEG_INF | DC_POS_INF |
                                              DC_NEG_ZERO | DC_POS_ZERO |
                                              DC_NEG_SUBNORM | DC_POS_SUBNORM,
                                          Dl, MVT::i32),
                    Op),
                0);
    // Sign are stored in CR bit 0, result are in CR bit 2.
    SDValue Sign(
        DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
                           DAG.getTargetConstant(PPC::sub_lt, Dl, MVT::i32)),
        0);
    SDValue Normal(DAG.getNOT(
        Dl,
        SDValue(DAG.getMachineNode(
                    TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
                    DAG.getTargetConstant(PPC::sub_eq, Dl, MVT::i32)),
                0),
        MVT::i1));
    if (Mask & fcPosNormal)
      Sign = DAG.getNOT(Dl, Sign, MVT::i1);
    SDValue Result = DAG.getNode(ISD::AND, Dl, MVT::i1, Sign, Normal);
    if (Mask == fcPosNormal || Mask == fcNegNormal)
      return Result;

    return DAG.getNode(
        ISD::OR, Dl, MVT::i1,
        getDataClassTest(Op, Mask & ~fcNormal, Dl, DAG, Subtarget), Result);
  }

  // The instruction doesn't differentiate between signaling or quiet NaN. Test
  // the rest first, and test if it 'is NaN and is signaling/quiet'.
  if ((Mask & fcNan) == fcQNan || (Mask & fcNan) == fcSNan) {
    bool IsQuiet = Mask & fcQNan;
    SDValue NanCheck = getDataClassTest(Op, fcNan, Dl, DAG, Subtarget);

    // Quietness is determined by the first bit in fraction field.
    uint64_t QuietMask = 0;
    SDValue HighWord;
    if (VT == MVT::f128) {
      HighWord = DAG.getNode(
          ISD::EXTRACT_VECTOR_ELT, Dl, MVT::i32, DAG.getBitcast(MVT::v4i32, Op),
          DAG.getVectorIdxConstant(Subtarget.isLittleEndian() ? 3 : 0, Dl));
      QuietMask = 0x8000;
    } else if (VT == MVT::f64) {
      if (Subtarget.isPPC64()) {
        HighWord = DAG.getNode(ISD::EXTRACT_ELEMENT, Dl, MVT::i32,
                               DAG.getBitcast(MVT::i64, Op),
                               DAG.getConstant(1, Dl, MVT::i32));
      } else {
        SDValue Vec = DAG.getBitcast(
            MVT::v4i32, DAG.getNode(ISD::SCALAR_TO_VECTOR, Dl, MVT::v2f64, Op));
        HighWord = DAG.getNode(
            ISD::EXTRACT_VECTOR_ELT, Dl, MVT::i32, Vec,
            DAG.getVectorIdxConstant(Subtarget.isLittleEndian() ? 1 : 0, Dl));
      }
      QuietMask = 0x80000;
    } else if (VT == MVT::f32) {
      HighWord = DAG.getBitcast(MVT::i32, Op);
      QuietMask = 0x400000;
    }
    SDValue NanRes = DAG.getSetCC(
        Dl, MVT::i1,
        DAG.getNode(ISD::AND, Dl, MVT::i32, HighWord,
                    DAG.getConstant(QuietMask, Dl, MVT::i32)),
        DAG.getConstant(0, Dl, MVT::i32), IsQuiet ? ISD::SETNE : ISD::SETEQ);
    NanRes = DAG.getNode(ISD::AND, Dl, MVT::i1, NanCheck, NanRes);
    if (Mask == fcQNan || Mask == fcSNan)
      return NanRes;

    return DAG.getNode(ISD::OR, Dl, MVT::i1,
                       getDataClassTest(Op, Mask & ~fcNan, Dl, DAG, Subtarget),
                       NanRes);
  }

  unsigned NativeMask = 0;
  if ((Mask & fcNan) == fcNan)
    NativeMask |= DC_NAN;
  if (Mask & fcNegInf)
    NativeMask |= DC_NEG_INF;
  if (Mask & fcPosInf)
    NativeMask |= DC_POS_INF;
  if (Mask & fcNegZero)
    NativeMask |= DC_NEG_ZERO;
  if (Mask & fcPosZero)
    NativeMask |= DC_POS_ZERO;
  if (Mask & fcNegSubnormal)
    NativeMask |= DC_NEG_SUBNORM;
  if (Mask & fcPosSubnormal)
    NativeMask |= DC_POS_SUBNORM;
  return SDValue(
      DAG.getMachineNode(
          TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
          SDValue(DAG.getMachineNode(
                      TestOp, Dl, MVT::i32,
                      DAG.getTargetConstant(NativeMask, Dl, MVT::i32), Op),
                  0),
          DAG.getTargetConstant(PPC::sub_eq, Dl, MVT::i32)),
      0);
}

SDValue PPCTargetLowering::LowerIS_FPCLASS(SDValue Op,
                                           SelectionDAG &DAG) const {
  assert(Subtarget.hasP9Vector() && "Test data class requires Power9");
  SDValue LHS = Op.getOperand(0);
  uint64_t RHSC = Op.getConstantOperandVal(1);
  SDLoc Dl(Op);
  FPClassTest Category = static_cast<FPClassTest>(RHSC);
  if (LHS.getValueType() == MVT::ppcf128) {
    // The higher part determines the value class.
    LHS = DAG.getNode(ISD::EXTRACT_ELEMENT, Dl, MVT::f64, LHS,
                      DAG.getConstant(1, Dl, MVT::i32));
  }

  return getDataClassTest(LHS, Category, Dl, DAG, Subtarget);
}

// Adjust the length value for a load/store with length to account for the
// instructions requiring a left justified length, and for non-byte element
// types requiring scaling by element size.
static SDValue AdjustLength(SDValue Val, unsigned Bits, bool Left,
                            SelectionDAG &DAG) {
  SDLoc dl(Val);
  EVT VT = Val->getValueType(0);
  unsigned LeftAdj = Left ? VT.getSizeInBits() - 8 : 0;
  unsigned TypeAdj = llvm::countr_zero<uint32_t>(Bits / 8);
  SDValue SHLAmt = DAG.getConstant(LeftAdj + TypeAdj, dl, VT);
  return DAG.getNode(ISD::SHL, dl, VT, Val, SHLAmt);
}

SDValue PPCTargetLowering::LowerVP_LOAD(SDValue Op, SelectionDAG &DAG) const {
  auto VPLD = cast<VPLoadSDNode>(Op);
  bool Future = Subtarget.isISAFuture();
  SDLoc dl(Op);
  assert(ISD::isConstantSplatVectorAllOnes(Op->getOperand(3).getNode(), true) &&
         "Mask predication not supported");
  EVT PtrVT = getPointerTy(DAG.getDataLayout());
  SDValue Len = DAG.getNode(ISD::ANY_EXTEND, dl, PtrVT, VPLD->getOperand(4));
  unsigned IID = Future ? Intrinsic::ppc_vsx_lxvrl : Intrinsic::ppc_vsx_lxvl;
  unsigned EltBits = Op->getValueType(0).getScalarType().getSizeInBits();
  Len = AdjustLength(Len, EltBits, !Future, DAG);
  SDValue Ops[] = {VPLD->getChain(), DAG.getConstant(IID, dl, MVT::i32),
                   VPLD->getOperand(1), Len};
  SDVTList Tys = DAG.getVTList(Op->getValueType(0), MVT::Other);
  SDValue VPL =
      DAG.getMemIntrinsicNode(ISD::INTRINSIC_W_CHAIN, dl, Tys, Ops,
                              VPLD->getMemoryVT(), VPLD->getMemOperand());
  return VPL;
}

SDValue PPCTargetLowering::LowerVP_STORE(SDValue Op, SelectionDAG &DAG) const {
  auto VPST = cast<VPStoreSDNode>(Op);
  assert(ISD::isConstantSplatVectorAllOnes(Op->getOperand(4).getNode(), true) &&
         "Mask predication not supported");
  EVT PtrVT = getPointerTy(DAG.getDataLayout());
  SDLoc dl(Op);
  SDValue Len = DAG.getNode(ISD::ANY_EXTEND, dl, PtrVT, VPST->getOperand(5));
  unsigned EltBits =
      Op->getOperand(1).getValueType().getScalarType().getSizeInBits();
  bool Future = Subtarget.isISAFuture();
  unsigned IID = Future ? Intrinsic::ppc_vsx_stxvrl : Intrinsic::ppc_vsx_stxvl;
  Len = AdjustLength(Len, EltBits, !Future, DAG);
  SDValue Ops[] = {
      VPST->getChain(), DAG.getConstant(IID, dl, MVT::i32),
      DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, VPST->getOperand(1)),
      VPST->getOperand(2), Len};
  SDVTList Tys = DAG.getVTList(MVT::Other);
  SDValue VPS =
      DAG.getMemIntrinsicNode(ISD::INTRINSIC_VOID, dl, Tys, Ops,
                              VPST->getMemoryVT(), VPST->getMemOperand());
  return VPS;
}

SDValue PPCTargetLowering::LowerSCALAR_TO_VECTOR(SDValue Op,
                                                 SelectionDAG &DAG) const {
  SDLoc dl(Op);

  MachineFunction &MF = DAG.getMachineFunction();
  SDValue Op0 = Op.getOperand(0);
  EVT ValVT = Op0.getValueType();
  unsigned EltSize = Op.getValueType().getScalarSizeInBits();
  if (isa<ConstantSDNode>(Op0) && EltSize <= 32) {
    int64_t IntVal = Op.getConstantOperandVal(0);
    if (IntVal >= -16 && IntVal <= 15)
      return getCanonicalConstSplat(IntVal, EltSize / 8, Op.getValueType(), DAG,
                                    dl);
  }

  ReuseLoadInfo RLI;
  if (Subtarget.hasLFIWAX() && Subtarget.hasVSX() &&
      Op.getValueType() == MVT::v4i32 && Op0.getOpcode() == ISD::LOAD &&
      Op0.getValueType() == MVT::i32 && Op0.hasOneUse() &&
      canReuseLoadAddress(Op0, MVT::i32, RLI, DAG, ISD::NON_EXTLOAD)) {

    MachineMemOperand *MMO =
        MF.getMachineMemOperand(RLI.MPI, MachineMemOperand::MOLoad, 4,
                                RLI.Alignment, RLI.AAInfo, RLI.Ranges);
    SDValue Ops[] = {RLI.Chain, RLI.Ptr, DAG.getValueType(Op.getValueType())};
    SDValue Bits = DAG.getMemIntrinsicNode(
        PPCISD::LD_SPLAT, dl, DAG.getVTList(MVT::v4i32, MVT::Other), Ops,
        MVT::i32, MMO);
    if (RLI.ResChain)
      DAG.makeEquivalentMemoryOrdering(RLI.ResChain, Bits.getValue(1));
    return Bits.getValue(0);
  }

  // Create a stack slot that is 16-byte aligned.
  MachineFrameInfo &MFI = MF.getFrameInfo();
  int FrameIdx = MFI.CreateStackObject(16, Align(16), false);
  EVT PtrVT = getPointerTy(DAG.getDataLayout());
  SDValue FIdx = DAG.getFrameIndex(FrameIdx, PtrVT);

  SDValue Val = Op0;
  // P10 hardware store forwarding requires that a single store contains all
  // the data for the load. P10 is able to merge a pair of adjacent stores. Try
  // to avoid load hit store on P10 when running binaries compiled for older
  // processors by generating two mergeable scalar stores to forward with the
  // vector load.
  if (!DisableP10StoreForward && Subtarget.isPPC64() &&
      !Subtarget.isLittleEndian() && ValVT.isInteger() &&
      ValVT.getSizeInBits() <= 64) {
    Val = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i64, Val);
    EVT ShiftAmountTy = getShiftAmountTy(MVT::i64, DAG.getDataLayout());
    SDValue ShiftBy = DAG.getConstant(
        64 - Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
    Val = DAG.getNode(ISD::SHL, dl, MVT::i64, Val, ShiftBy);
    SDValue Plus8 =
        DAG.getNode(ISD::ADD, dl, PtrVT, FIdx, DAG.getConstant(8, dl, PtrVT));
    SDValue Store2 =
        DAG.getStore(DAG.getEntryNode(), dl, Val, Plus8, MachinePointerInfo());
    SDValue Store = DAG.getStore(Store2, dl, Val, FIdx, MachinePointerInfo());
    return DAG.getLoad(Op.getValueType(), dl, Store, FIdx,
                       MachinePointerInfo());
  }

  // Store the input value into Value#0 of the stack slot.
  SDValue Store =
      DAG.getStore(DAG.getEntryNode(), dl, Val, FIdx, MachinePointerInfo());
  // Load it out.
  return DAG.getLoad(Op.getValueType(), dl, Store, FIdx, MachinePointerInfo());
}

SDValue PPCTargetLowering::LowerINSERT_VECTOR_ELT(SDValue Op,
                                                  SelectionDAG &DAG) const {
  assert(Op.getOpcode() == ISD::INSERT_VECTOR_ELT &&
         "Should only be called for ISD::INSERT_VECTOR_ELT");

  ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(2));

  EVT VT = Op.getValueType();
  SDLoc dl(Op);
  SDValue V1 = Op.getOperand(0);
  SDValue V2 = Op.getOperand(1);

  if (VT == MVT::v2f64 && C)
    return Op;

  if (Subtarget.hasP9Vector()) {
    // A f32 load feeding into a v4f32 insert_vector_elt is handled in this way
    // because on P10, it allows this specific insert_vector_elt load pattern to
    // utilize the refactored load and store infrastructure in order to exploit
    // prefixed loads.
    // On targets with inexpensive direct moves (Power9 and up), a
    // (insert_vector_elt v4f32:$vec, (f32 load)) is always better as an integer
    // load since a single precision load will involve conversion to double
    // precision on the load followed by another conversion to single precision.
    if ((VT == MVT::v4f32) && (V2.getValueType() == MVT::f32) &&
        (isa<LoadSDNode>(V2))) {
      SDValue BitcastVector = DAG.getBitcast(MVT::v4i32, V1);
      SDValue BitcastLoad = DAG.getBitcast(MVT::i32, V2);
      SDValue InsVecElt =
          DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v4i32, BitcastVector,
                      BitcastLoad, Op.getOperand(2));
      return DAG.getBitcast(MVT::v4f32, InsVecElt);
    }
  }

  if (Subtarget.isISA3_1()) {
    if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.isPPC64())
      return SDValue();
    // On P10, we have legal lowering for constant and variable indices for
    // all vectors.
    if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
        VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
      return Op;
  }

  // Before P10, we have legal lowering for constant indices but not for
  // variable ones.
  if (!C)
    return SDValue();

  // We can use MTVSRZ + VECINSERT for v8i16 and v16i8 types.
  if (VT == MVT::v8i16 || VT == MVT::v16i8) {
    SDValue Mtvsrz = DAG.getNode(PPCISD::MTVSRZ, dl, VT, V2);
    unsigned BytesInEachElement = VT.getVectorElementType().getSizeInBits() / 8;
    unsigned InsertAtElement = C->getZExtValue();
    unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
    if (Subtarget.isLittleEndian()) {
      InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
    }
    return DAG.getNode(PPCISD::VECINSERT, dl, VT, V1, Mtvsrz,
                       DAG.getConstant(InsertAtByte, dl, MVT::i32));
  }
  return Op;
}

SDValue PPCTargetLowering::LowerDMFVectorLoad(SDValue Op,
                                              SelectionDAG &DAG) const {
  SDLoc dl(Op);
  LoadSDNode *LN = cast<LoadSDNode>(Op.getNode());
  SDValue LoadChain = LN->getChain();
  SDValue BasePtr = LN->getBasePtr();
  EVT VT = Op.getValueType();
  bool IsV1024i1 = VT == MVT::v1024i1;
  bool IsV2048i1 = VT == MVT::v2048i1;

  // The types v1024i1 and v2048i1 are used for Dense Math dmr registers and
  // Dense Math dmr pair registers, respectively.
  assert((IsV1024i1 || IsV2048i1) && "Unsupported type.");
  (void)IsV2048i1;
  assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
         "Dense Math support required.");
  assert(Subtarget.pairedVectorMemops() && "Vector pair support required.");

  SmallVector<SDValue, 8> Loads;
  SmallVector<SDValue, 8> LoadChains;

  SDValue IntrinID = DAG.getConstant(Intrinsic::ppc_vsx_lxvp, dl, MVT::i32);
  SDValue LoadOps[] = {LoadChain, IntrinID, BasePtr};
  MachineMemOperand *MMO = LN->getMemOperand();
  unsigned NumVecs = VT.getSizeInBits() / 256;
  for (unsigned Idx = 0; Idx < NumVecs; ++Idx) {
    MachineMemOperand *NewMMO =
        DAG.getMachineFunction().getMachineMemOperand(MMO, Idx * 32, 32);
    if (Idx > 0) {
      BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr,
                            DAG.getConstant(32, dl, BasePtr.getValueType()));
      LoadOps[2] = BasePtr;
    }
    SDValue Ld = DAG.getMemIntrinsicNode(ISD::INTRINSIC_W_CHAIN, dl,
                                         DAG.getVTList(MVT::v256i1, MVT::Other),
                                         LoadOps, MVT::v256i1, NewMMO);
    LoadChains.push_back(Ld.getValue(1));
    Loads.push_back(Ld);
  }

  if (Subtarget.isLittleEndian()) {
    std::reverse(Loads.begin(), Loads.end());
    std::reverse(LoadChains.begin(), LoadChains.end());
  }

  SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, LoadChains);
  SDValue Lo =
      DAG.getNode(PPCISD::INST512, dl, MVT::v512i1, Loads[0], Loads[1]);
  SDValue LoSub = DAG.getTargetConstant(PPC::sub_wacc_lo, dl, MVT::i32);
  SDValue Hi =
      DAG.getNode(PPCISD::INST512HI, dl, MVT::v512i1, Loads[2], Loads[3]);
  SDValue HiSub = DAG.getTargetConstant(PPC::sub_wacc_hi, dl, MVT::i32);
  SDValue RC = DAG.getTargetConstant(PPC::DMRRCRegClassID, dl, MVT::i32);
  const SDValue Ops[] = {RC, Lo, LoSub, Hi, HiSub};

  SDValue Value =
      SDValue(DAG.getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v1024i1, Ops), 0);

  if (IsV1024i1) {
    return DAG.getMergeValues({Value, TF}, dl);
  }

  // Handle Loads for V2048i1 which represents a dmr pair.
  SDValue DmrPValue;
  SDValue Dmr1Lo =
      DAG.getNode(PPCISD::INST512, dl, MVT::v512i1, Loads[4], Loads[5]);
  SDValue Dmr1Hi =
      DAG.getNode(PPCISD::INST512HI, dl, MVT::v512i1, Loads[6], Loads[7]);
  const SDValue Dmr1Ops[] = {RC, Dmr1Lo, LoSub, Dmr1Hi, HiSub};
  SDValue Dmr1Value = SDValue(
      DAG.getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v1024i1, Dmr1Ops), 0);

  SDValue Dmr0Sub = DAG.getTargetConstant(PPC::sub_dmr0, dl, MVT::i32);
  SDValue Dmr1Sub = DAG.getTargetConstant(PPC::sub_dmr1, dl, MVT::i32);

  SDValue DmrPRC = DAG.getTargetConstant(PPC::DMRpRCRegClassID, dl, MVT::i32);
  const SDValue DmrPOps[] = {DmrPRC, Value, Dmr0Sub, Dmr1Value, Dmr1Sub};

  DmrPValue = SDValue(
      DAG.getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v2048i1, DmrPOps), 0);

  return DAG.getMergeValues({DmrPValue, TF}, dl);
}

SDValue PPCTargetLowering::DMFInsert1024(const SmallVectorImpl<SDValue> &Pairs,
                                         const SDLoc &dl,
                                         SelectionDAG &DAG) const {
  SDValue Lo =
      DAG.getNode(PPCISD::INST512, dl, MVT::v512i1, Pairs[0], Pairs[1]);
  SDValue LoSub = DAG.getTargetConstant(PPC::sub_wacc_lo, dl, MVT::i32);
  SDValue Hi =
      DAG.getNode(PPCISD::INST512HI, dl, MVT::v512i1, Pairs[2], Pairs[3]);
  SDValue HiSub = DAG.getTargetConstant(PPC::sub_wacc_hi, dl, MVT::i32);
  SDValue RC = DAG.getTargetConstant(PPC::DMRRCRegClassID, dl, MVT::i32);

  return SDValue(DAG.getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v1024i1,
                                    {RC, Lo, LoSub, Hi, HiSub}),
                 0);
}

SDValue PPCTargetLowering::LowerVectorLoad(SDValue Op,
                                           SelectionDAG &DAG) const {
  SDLoc dl(Op);
  LoadSDNode *LN = cast<LoadSDNode>(Op.getNode());
  SDValue LoadChain = LN->getChain();
  SDValue BasePtr = LN->getBasePtr();
  EVT VT = Op.getValueType();

  if (VT == MVT::v1024i1 || VT == MVT::v2048i1)
    return LowerDMFVectorLoad(Op, DAG);

  if (VT != MVT::v256i1 && VT != MVT::v512i1)
    return Op;

  // Type v256i1 is used for pairs and v512i1 is used for accumulators.
  // Here we create 2 or 4 v16i8 loads to load the pair or accumulator value in
  // 2 or 4 vsx registers.
  assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
         "Type unsupported without MMA");
  assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
         "Type unsupported without paired vector support");
  Align Alignment = LN->getAlign();
  SmallVector<SDValue, 4> Loads;
  SmallVector<SDValue, 4> LoadChains;
  unsigned NumVecs = VT.getSizeInBits() / 128;
  for (unsigned Idx = 0; Idx < NumVecs; ++Idx) {
    SDValue Load =
        DAG.getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
                    LN->getPointerInfo().getWithOffset(Idx * 16),
                    commonAlignment(Alignment, Idx * 16),
                    LN->getMemOperand()->getFlags(), LN->getAAInfo());
    BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr,
                          DAG.getConstant(16, dl, BasePtr.getValueType()));
    Loads.push_back(Load);
    LoadChains.push_back(Load.getValue(1));
  }
  if (Subtarget.isLittleEndian()) {
    std::reverse(Loads.begin(), Loads.end());
    std::reverse(LoadChains.begin(), LoadChains.end());
  }
  SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, LoadChains);
  SDValue Value =
      DAG.getNode(VT == MVT::v512i1 ? PPCISD::ACC_BUILD : PPCISD::PAIR_BUILD,
                  dl, VT, Loads);
  SDValue RetOps[] = {Value, TF};
  return DAG.getMergeValues(RetOps, dl);
}

SDValue PPCTargetLowering::LowerDMFVectorStore(SDValue Op,
                                               SelectionDAG &DAG) const {

  SDLoc dl(Op);
  StoreSDNode *SN = cast<StoreSDNode>(Op.getNode());
  SDValue StoreChain = SN->getChain();
  SDValue BasePtr = SN->getBasePtr();
  SmallVector<SDValue, 8> Values;
  SmallVector<SDValue, 8> Stores;
  EVT VT = SN->getValue().getValueType();
  bool IsV1024i1 = VT == MVT::v1024i1;
  bool IsV2048i1 = VT == MVT::v2048i1;

  // The types v1024i1 and v2048i1 are used for Dense Math dmr registers and
  // Dense Math dmr pair registers, respectively.
  assert((IsV1024i1 || IsV2048i1) && "Unsupported type.");
  (void)IsV2048i1;
  assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
         "Dense Math support required.");
  assert(Subtarget.pairedVectorMemops() && "Vector pair support required.");

  EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
  if (IsV1024i1) {
    SDValue Lo(DAG.getMachineNode(
                   TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
                   Op.getOperand(1),
                   DAG.getTargetConstant(PPC::sub_wacc_lo, dl, MVT::i32)),
               0);
    SDValue Hi(DAG.getMachineNode(
                   TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
                   Op.getOperand(1),
                   DAG.getTargetConstant(PPC::sub_wacc_hi, dl, MVT::i32)),
               0);
    MachineSDNode *ExtNode =
        DAG.getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Lo);
    Values.push_back(SDValue(ExtNode, 0));
    Values.push_back(SDValue(ExtNode, 1));
    ExtNode = DAG.getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Hi);
    Values.push_back(SDValue(ExtNode, 0));
    Values.push_back(SDValue(ExtNode, 1));
  } else {
    // This corresponds to v2048i1 which represents a dmr pair.
    SDValue Dmr0(
        DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
                           Op.getOperand(1),
                           DAG.getTargetConstant(PPC::sub_dmr0, dl, MVT::i32)),
        0);

    SDValue Dmr1(
        DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
                           Op.getOperand(1),
                           DAG.getTargetConstant(PPC::sub_dmr1, dl, MVT::i32)),
        0);

    SDValue Dmr0Lo(DAG.getMachineNode(
                       TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
                       DAG.getTargetConstant(PPC::sub_wacc_lo, dl, MVT::i32)),
                   0);

    SDValue Dmr0Hi(DAG.getMachineNode(
                       TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
                       DAG.getTargetConstant(PPC::sub_wacc_hi, dl, MVT::i32)),
                   0);

    SDValue Dmr1Lo(DAG.getMachineNode(
                       TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
                       DAG.getTargetConstant(PPC::sub_wacc_lo, dl, MVT::i32)),
                   0);

    SDValue Dmr1Hi(DAG.getMachineNode(
                       TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
                       DAG.getTargetConstant(PPC::sub_wacc_hi, dl, MVT::i32)),
                   0);

    MachineSDNode *ExtNode =
        DAG.getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr0Lo);
    Values.push_back(SDValue(ExtNode, 0));
    Values.push_back(SDValue(ExtNode, 1));
    ExtNode =
        DAG.getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr0Hi);
    Values.push_back(SDValue(ExtNode, 0));
    Values.push_back(SDValue(ExtNode, 1));
    ExtNode = DAG.getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr1Lo);
    Values.push_back(SDValue(ExtNode, 0));
    Values.push_back(SDValue(ExtNode, 1));
    ExtNode =
        DAG.getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr1Hi);
    Values.push_back(SDValue(ExtNode, 0));
    Values.push_back(SDValue(ExtNode, 1));
  }

  if (Subtarget.isLittleEndian())
    std::reverse(Values.begin(), Values.end());

  SDVTList Tys = DAG.getVTList(MVT::Other);
  SmallVector<SDValue, 4> Ops{
      StoreChain, DAG.getConstant(Intrinsic::ppc_vsx_stxvp, dl, MVT::i32),
      Values[0], BasePtr};
  MachineMemOperand *MMO = SN->getMemOperand();
  unsigned NumVecs = VT.getSizeInBits() / 256;
  for (unsigned Idx = 0; Idx < NumVecs; ++Idx) {
    MachineMemOperand *NewMMO =
        DAG.getMachineFunction().getMachineMemOperand(MMO, Idx * 32, 32);
    if (Idx > 0) {
      BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr,
                            DAG.getConstant(32, dl, BasePtr.getValueType()));
      Ops[3] = BasePtr;
    }
    Ops[2] = Values[Idx];
    SDValue St = DAG.getMemIntrinsicNode(ISD::INTRINSIC_VOID, dl, Tys, Ops,
                                         MVT::v256i1, NewMMO);
    Stores.push_back(St);
  }

  SDValue TF = DAG.getTokenFactor(dl, Stores);
  return TF;
}

SDValue PPCTargetLowering::LowerVectorStore(SDValue Op,
                                            SelectionDAG &DAG) const {
  SDLoc dl(Op);
  StoreSDNode *SN = cast<StoreSDNode>(Op.getNode());
  SDValue StoreChain = SN->getChain();
  SDValue BasePtr = SN->getBasePtr();
  SDValue Value = SN->getValue();
  SDValue Value2 = SN->getValue();
  EVT StoreVT = Value.getValueType();

  if (StoreVT == MVT::v1024i1 || StoreVT == MVT::v2048i1)
    return LowerDMFVectorStore(Op, DAG);

  if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
    return Op;

  // Type v256i1 is used for pairs and v512i1 is used for accumulators.
  // Here we create 2 or 4 v16i8 stores to store the pair or accumulator
  // underlying registers individually.
  assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
         "Type unsupported without MMA");
  assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
         "Type unsupported without paired vector support");
  Align Alignment = SN->getAlign();
  SmallVector<SDValue, 4> Stores;
  unsigned NumVecs = 2;
  if (StoreVT == MVT::v512i1) {
    if (Subtarget.isISAFuture()) {
      EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
      MachineSDNode *ExtNode = DAG.getMachineNode(
          PPC::DMXXEXTFDMR512, dl, ReturnTypes, Op.getOperand(1));

      Value = SDValue(ExtNode, 0);
      Value2 = SDValue(ExtNode, 1);
    } else
      Value = DAG.getNode(PPCISD::XXMFACC, dl, MVT::v512i1, Value);
    NumVecs = 4;
  }
  for (unsigned Idx = 0; Idx < NumVecs; ++Idx) {
    unsigned VecNum = Subtarget.isLittleEndian() ? NumVecs - 1 - Idx : Idx;
    SDValue Elt;
    if (Subtarget.isISAFuture()) {
      VecNum = Subtarget.isLittleEndian() ? 1 - (Idx % 2) : (Idx % 2);
      Elt = DAG.getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
                        Idx > 1 ? Value2 : Value,
                        DAG.getConstant(VecNum, dl, getPointerTy(DAG.getDataLayout())));
    } else
      Elt = DAG.getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8, Value,
                        DAG.getConstant(VecNum, dl, getPointerTy(DAG.getDataLayout())));

    SDValue Store =
        DAG.getStore(StoreChain, dl, Elt, BasePtr,
                     SN->getPointerInfo().getWithOffset(Idx * 16),
                     commonAlignment(Alignment, Idx * 16),
                     SN->getMemOperand()->getFlags(), SN->getAAInfo());
    BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr,
                          DAG.getConstant(16, dl, BasePtr.getValueType()));
    Stores.push_back(Store);
  }
  SDValue TF = DAG.getTokenFactor(dl, Stores);
  return TF;
}

SDValue PPCTargetLowering::LowerMUL(SDValue Op, SelectionDAG &DAG) const {
  SDLoc dl(Op);
  if (Op.getValueType() == MVT::v4i32) {
    SDValue LHS = Op.getOperand(0), RHS = Op.getOperand(1);

    SDValue Zero = getCanonicalConstSplat(0, 1, MVT::v4i32, DAG, dl);
    // +16 as shift amt.
    SDValue Neg16 = getCanonicalConstSplat(-16, 4, MVT::v4i32, DAG, dl);
    SDValue RHSSwap =   // = vrlw RHS, 16
      BuildIntrinsicOp(Intrinsic::ppc_altivec_vrlw, RHS, Neg16, DAG, dl);

    // Shrinkify inputs to v8i16.
    LHS = DAG.getNode(ISD::BITCAST, dl, MVT::v8i16, LHS);
    RHS = DAG.getNode(ISD::BITCAST, dl, MVT::v8i16, RHS);
    RHSSwap = DAG.getNode(ISD::BITCAST, dl, MVT::v8i16, RHSSwap);

    // Low parts multiplied together, generating 32-bit results (we ignore the
    // top parts).
    SDValue LoProd = BuildIntrinsicOp(Intrinsic::ppc_altivec_vmulouh,
                                        LHS, RHS, DAG, dl, MVT::v4i32);

    SDValue HiProd = BuildIntrinsicOp(Intrinsic::ppc_altivec_vmsumuhm,
                                      LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
    // Shift the high parts up 16 bits.
    HiProd = BuildIntrinsicOp(Intrinsic::ppc_altivec_vslw, HiProd,
                              Neg16, DAG, dl);
    return DAG.getNode(ISD::ADD, dl, MVT::v4i32, LoProd, HiProd);
  } else if (Op.getValueType() == MVT::v16i8) {
    SDValue LHS = Op.getOperand(0), RHS = Op.getOperand(1);
    bool isLittleEndian = Subtarget.isLittleEndian();

    // Multiply the even 8-bit parts, producing 16-bit sums.
    SDValue EvenParts = BuildIntrinsicOp(Intrinsic::ppc_altivec_vmuleub,
                                           LHS, RHS, DAG, dl, MVT::v8i16);
    EvenParts = DAG.getNode(ISD::BITCAST, dl, MVT::v16i8, EvenParts);

    // Multiply the odd 8-bit parts, producing 16-bit sums.
    SDValue OddParts = BuildIntrinsicOp(Intrinsic::ppc_altivec_vmuloub,
                                          LHS, RHS, DAG, dl, MVT::v8i16);
    OddParts = DAG.getNode(ISD::BITCAST, dl, MVT::v16i8, OddParts);

    // Merge the results together.  Because vmuleub and vmuloub are
    // instructions with a big-endian bias, we must reverse the
    // element numbering and reverse the meaning of "odd" and "even"
    // when generating little endian code.
    int Ops[16];
    for (unsigned i = 0; i != 8; ++i) {
      if (isLittleEndian) {
        Ops[i*2  ] = 2*i;
        Ops[i*2+1] = 2*i+16;
      } else {
        Ops[i*2  ] = 2*i+1;
        Ops[i*2+1] = 2*i+1+16;
      }
    }
    if (isLittleEndian)
      return DAG.getVectorShuffle(MVT::v16i8, dl, OddParts, EvenParts, Ops);
    else
      return DAG.getVectorShuffle(MVT::v16i8, dl, EvenParts, OddParts, Ops);
  } else {
    llvm_unreachable("Unknown mul to lower!");
  }
}

SDValue PPCTargetLowering::LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const {
  bool IsStrict = Op->isStrictFPOpcode();
  if (Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
      !Subtarget.hasP9Vector())
    return SDValue();

  return Op;
}

// Custom lowering for fpext vf32 to v2f64
SDValue PPCTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {

  assert(Op.getOpcode() == ISD::FP_EXTEND &&
         "Should only be called for ISD::FP_EXTEND");

  // FIXME: handle extends from half precision float vectors on P9.
  // We only want to custom lower an extend from v2f32 to v2f64.
  if (Op.getValueType() != MVT::v2f64 ||
      Op.getOperand(0).getValueType() != MVT::v2f32)
    return SDValue();

  SDLoc dl(Op);
  SDValue Op0 = Op.getOperand(0);

  switch (Op0.getOpcode()) {
  default:
    return SDValue();
  case ISD::EXTRACT_SUBVECTOR: {
    assert(Op0.getNumOperands() == 2 &&
           isa<ConstantSDNode>(Op0->getOperand(1)) &&
           "Node should have 2 operands with second one being a constant!");

    if (Op0.getOperand(0).getValueType() != MVT::v4f32)
      return SDValue();

    // Custom lower is only done for high or low doubleword.
    int Idx = Op0.getConstantOperandVal(1);
    if (Idx % 2 != 0)
      return SDValue();

    // Since input is v4f32, at this point Idx is either 0 or 2.
    // Shift to get the doubleword position we want.
    int DWord = Idx >> 1;

    // High and low word positions are different on little endian.
    if (Subtarget.isLittleEndian())
      DWord ^= 0x1;

    return DAG.getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64,
                       Op0.getOperand(0), DAG.getConstant(DWord, dl, MVT::i32));
  }
  case ISD::FADD:
  case ISD::FMUL:
  case ISD::FSUB: {
    SDValue NewLoad[2];
    for (unsigned i = 0, ie = Op0.getNumOperands(); i != ie; ++i) {
      // Ensure both input are loads.
      SDValue LdOp = Op0.getOperand(i);
      if (LdOp.getOpcode() != ISD::LOAD)
        return SDValue();
      // Generate new load node.
      LoadSDNode *LD = cast<LoadSDNode>(LdOp);
      SDValue LoadOps[] = {LD->getChain(), LD->getBasePtr()};
      NewLoad[i] = DAG.getMemIntrinsicNode(
          PPCISD::LD_VSX_LH, dl, DAG.getVTList(MVT::v4f32, MVT::Other), LoadOps,
          LD->getMemoryVT(), LD->getMemOperand());
    }
    SDValue NewOp =
        DAG.getNode(Op0.getOpcode(), SDLoc(Op0), MVT::v4f32, NewLoad[0],
                    NewLoad[1], Op0.getNode()->getFlags());
    return DAG.getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewOp,
                       DAG.getConstant(0, dl, MVT::i32));
  }
  case ISD::LOAD: {
    LoadSDNode *LD = cast<LoadSDNode>(Op0);
    SDValue LoadOps[] = {LD->getChain(), LD->getBasePtr()};
    SDValue NewLd = DAG.getMemIntrinsicNode(
        PPCISD::LD_VSX_LH, dl, DAG.getVTList(MVT::v4f32, MVT::Other), LoadOps,
        LD->getMemoryVT(), LD->getMemOperand());
    return DAG.getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewLd,
                       DAG.getConstant(0, dl, MVT::i32));
  }
  }
  llvm_unreachable("ERROR:Should return for all cases within swtich.");
}

static SDValue ConvertCarryValueToCarryFlag(EVT SumType, SDValue Value,
                                            SelectionDAG &DAG,
                                            const PPCSubtarget &STI) {
  SDLoc DL(Value);
  if (STI.useCRBits())
    Value = DAG.getNode(ISD::SELECT, DL, SumType, Value,
                        DAG.getConstant(1, DL, SumType),
                        DAG.getConstant(0, DL, SumType));
  else
    Value = DAG.getZExtOrTrunc(Value, DL, SumType);
  SDValue Sum = DAG.getNode(PPCISD::ADDC, DL, DAG.getVTList(SumType, MVT::i32),
                            Value, DAG.getAllOnesConstant(DL, SumType));
  return Sum.getValue(1);
}

static SDValue ConvertCarryFlagToCarryValue(EVT SumType, SDValue Flag,
                                            EVT CarryType, SelectionDAG &DAG,
                                            const PPCSubtarget &STI) {
  SDLoc DL(Flag);
  SDValue Zero = DAG.getConstant(0, DL, SumType);
  SDValue Carry = DAG.getNode(
      PPCISD::ADDE, DL, DAG.getVTList(SumType, MVT::i32), Zero, Zero, Flag);
  if (STI.useCRBits())
    return DAG.getSetCC(DL, CarryType, Carry, Zero, ISD::SETNE);
  return DAG.getZExtOrTrunc(Carry, DL, CarryType);
}

SDValue PPCTargetLowering::LowerADDSUBO(SDValue Op, SelectionDAG &DAG) const {

  SDLoc DL(Op);
  SDNode *N = Op.getNode();
  EVT VT = N->getValueType(0);
  EVT CarryType = N->getValueType(1);
  unsigned Opc = N->getOpcode();
  bool IsAdd = Opc == ISD::UADDO;
  Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
  SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
                            N->getOperand(0), N->getOperand(1));
  SDValue Carry = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType,
                                               DAG, Subtarget);
  if (!IsAdd)
    Carry = DAG.getNode(ISD::XOR, DL, CarryType, Carry,
                        DAG.getConstant(1UL, DL, CarryType));
  return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, Carry);
}

SDValue PPCTargetLowering::LowerADDSUBO_CARRY(SDValue Op,
                                              SelectionDAG &DAG) const {
  SDLoc DL(Op);
  SDNode *N = Op.getNode();
  unsigned Opc = N->getOpcode();
  EVT VT = N->getValueType(0);
  EVT CarryType = N->getValueType(1);
  SDValue CarryOp = N->getOperand(2);
  bool IsAdd = Opc == ISD::UADDO_CARRY;
  Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
  if (!IsAdd)
    CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
                          DAG.getConstant(1UL, DL, CarryOp.getValueType()));
  CarryOp = ConvertCarryValueToCarryFlag(VT, CarryOp, DAG, Subtarget);
  SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
                            Op.getOperand(0), Op.getOperand(1), CarryOp);
  CarryOp = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType, DAG,
                                         Subtarget);
  if (!IsAdd)
    CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
                          DAG.getConstant(1UL, DL, CarryOp.getValueType()));
  return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, CarryOp);
}

SDValue PPCTargetLowering::LowerSSUBO(SDValue Op, SelectionDAG &DAG) const {

  SDLoc dl(Op);
  SDValue LHS = Op.getOperand(0);
  SDValue RHS = Op.getOperand(1);
  EVT VT = Op.getNode()->getValueType(0);

  SDValue Sub = DAG.getNode(ISD::SUB, dl, VT, LHS, RHS);

  SDValue Xor1 = DAG.getNode(ISD::XOR, dl, VT, RHS, LHS);
  SDValue Xor2 = DAG.getNode(ISD::XOR, dl, VT, Sub, LHS);

  SDValue And = DAG.getNode(ISD::AND, dl, VT, Xor1, Xor2);

  SDValue Overflow =
      DAG.getNode(ISD::SRL, dl, VT, And,
                  DAG.getConstant(VT.getSizeInBits() - 1, dl, MVT::i32));

  SDValue OverflowTrunc =
      DAG.getNode(ISD::TRUNCATE, dl, Op.getNode()->getValueType(1), Overflow);

  return DAG.getMergeValues({Sub, OverflowTrunc}, dl);
}

/// Implements signed add with overflow detection using the rule:
/// (x eqv y) & (sum xor x), where the overflow bit is extracted from the sign
SDValue PPCTargetLowering::LowerSADDO(SDValue Op, SelectionDAG &DAG) const {

  SDLoc dl(Op);
  SDValue LHS = Op.getOperand(0);
  SDValue RHS = Op.getOperand(1);
  EVT VT = Op.getNode()->getValueType(0);

  SDValue Sum = DAG.getNode(ISD::ADD, dl, VT, LHS, RHS);

  // Compute ~(x xor y)
  SDValue XorXY = DAG.getNode(ISD::XOR, dl, VT, LHS, RHS);
  SDValue EqvXY = DAG.getNOT(dl, XorXY, VT);
  // Compute (s xor x)
  SDValue SumXorX = DAG.getNode(ISD::XOR, dl, VT, Sum, LHS);

  // overflow = (x eqv y) & (s xor x)
  SDValue OverflowInSign = DAG.getNode(ISD::AND, dl, VT, EqvXY, SumXorX);

  // Shift sign bit down to LSB
  SDValue Overflow =
      DAG.getNode(ISD::SRL, dl, VT, OverflowInSign,
                  DAG.getConstant(VT.getSizeInBits() - 1, dl, MVT::i32));
  // Truncate to the overflow type (i1)
  SDValue OverflowTrunc =
      DAG.getNode(ISD::TRUNCATE, dl, Op.getNode()->getValueType(1), Overflow);

  return DAG.getMergeValues({Sum, OverflowTrunc}, dl);
}

// Lower unsigned 3-way compare producing -1/0/1.
SDValue PPCTargetLowering::LowerUCMP(SDValue Op, SelectionDAG &DAG) const {
  SDLoc DL(Op);
  SDValue A = DAG.getFreeze(Op.getOperand(0));
  SDValue B = DAG.getFreeze(Op.getOperand(1));
  EVT OpVT = A.getValueType();
  EVT ResVT = Op.getValueType();

  // On PPC64, i32 carries are affected by the upper 32 bits of the registers.
  // We must zero-extend to i64 to ensure the carry reflects the 32-bit unsigned
  // comparison.
  if (Subtarget.isPPC64() && OpVT == MVT::i32) {
    A = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, A);
    B = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, B);
    OpVT = MVT::i64;
  }

  // First compute diff = A - B.
  SDValue Diff = DAG.getNode(ISD::SUB, DL, OpVT, A, B);

  // Generate B - A using SUBC to capture carry.
  SDVTList VTs = DAG.getVTList(OpVT, MVT::i32);
  SDValue SubC = DAG.getNode(PPCISD::SUBC, DL, VTs, B, A);
  SDValue CA0 = SubC.getValue(1);

  // t2 = A - B + CA0 using SUBE.
  SDValue SubE1 = DAG.getNode(PPCISD::SUBE, DL, VTs, A, B, CA0);
  SDValue CA1 = SubE1.getValue(1);

  // res = diff - t2 + CA1 using SUBE (produces desired -1/0/1).
  SDValue ResPair = DAG.getNode(PPCISD::SUBE, DL, VTs, Diff, SubE1, CA1);

  // Extract the first result and truncate to result type if needed.
  return DAG.getSExtOrTrunc(ResPair.getValue(0), DL, ResVT);
}

/// LowerOperation - Provide custom lowering hooks for some operations.
///
SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
  switch (Op.getOpcode()) {
  default:
    llvm_unreachable("Wasn't expecting to be able to lower this!");
  case ISD::FPOW:               return lowerPow(Op, DAG);
  case ISD::FSIN:               return lowerSin(Op, DAG);
  case ISD::FCOS:               return lowerCos(Op, DAG);
  case ISD::FLOG:               return lowerLog(Op, DAG);
  case ISD::FLOG10:             return lowerLog10(Op, DAG);
  case ISD::FEXP:               return lowerExp(Op, DAG);
  case ISD::ConstantPool:       return LowerConstantPool(Op, DAG);
  case ISD::BlockAddress:       return LowerBlockAddress(Op, DAG);
  case ISD::GlobalAddress:      return LowerGlobalAddress(Op, DAG);
  case ISD::GlobalTLSAddress:   return LowerGlobalTLSAddress(Op, DAG);
  case ISD::JumpTable:          return LowerJumpTable(Op, DAG);
  case ISD::STRICT_FSETCC:
  case ISD::STRICT_FSETCCS:
  case ISD::SETCC:              return LowerSETCC(Op, DAG);
  case ISD::INIT_TRAMPOLINE:    return LowerINIT_TRAMPOLINE(Op, DAG);
  case ISD::ADJUST_TRAMPOLINE:  return LowerADJUST_TRAMPOLINE(Op, DAG);
  case ISD::SSUBO:
    return LowerSSUBO(Op, DAG);
  case ISD::SADDO:
    return LowerSADDO(Op, DAG);

  case ISD::INLINEASM:
  case ISD::INLINEASM_BR:       return LowerINLINEASM(Op, DAG);
  // Variable argument lowering.
  case ISD::VASTART:            return LowerVASTART(Op, DAG);
  case ISD::VAARG:              return LowerVAARG(Op, DAG);
  case ISD::VACOPY:             return LowerVACOPY(Op, DAG);

  case ISD::STACKRESTORE:       return LowerSTACKRESTORE(Op, DAG);
  case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
  case ISD::GET_DYNAMIC_AREA_OFFSET:
    return LowerGET_DYNAMIC_AREA_OFFSET(Op, DAG);

  // Exception handling lowering.
  case ISD::EH_DWARF_CFA:       return LowerEH_DWARF_CFA(Op, DAG);
  case ISD::EH_SJLJ_SETJMP:     return lowerEH_SJLJ_SETJMP(Op, DAG);
  case ISD::EH_SJLJ_LONGJMP:    return lowerEH_SJLJ_LONGJMP(Op, DAG);

  case ISD::LOAD:               return LowerLOAD(Op, DAG);
  case ISD::STORE:              return LowerSTORE(Op, DAG);
  case ISD::TRUNCATE:           return LowerTRUNCATE(Op, DAG);
  case ISD::SELECT_CC:          return LowerSELECT_CC(Op, DAG);
  case ISD::STRICT_FP_TO_UINT:
  case ISD::STRICT_FP_TO_SINT:
  case ISD::FP_TO_UINT:
  case ISD::FP_TO_SINT:         return LowerFP_TO_INT(Op, DAG, SDLoc(Op));
  case ISD::STRICT_UINT_TO_FP:
  case ISD::STRICT_SINT_TO_FP:
  case ISD::UINT_TO_FP:
  case ISD::SINT_TO_FP:         return LowerINT_TO_FP(Op, DAG);
  case ISD::GET_ROUNDING:       return LowerGET_ROUNDING(Op, DAG);
  case ISD::SET_ROUNDING:
    return LowerSET_ROUNDING(Op, DAG);

  // Lower 64-bit shifts.
  case ISD::SHL_PARTS:          return LowerSHL_PARTS(Op, DAG);
  case ISD::SRL_PARTS:          return LowerSRL_PARTS(Op, DAG);
  case ISD::SRA_PARTS:          return LowerSRA_PARTS(Op, DAG);

  case ISD::FSHL:               return LowerFunnelShift(Op, DAG);
  case ISD::FSHR:               return LowerFunnelShift(Op, DAG);

  // Vector-related lowering.
  case ISD::BUILD_VECTOR:       return LowerBUILD_VECTOR(Op, DAG);
  case ISD::VECTOR_SHUFFLE:     return LowerVECTOR_SHUFFLE(Op, DAG);
  case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
  case ISD::SCALAR_TO_VECTOR:   return LowerSCALAR_TO_VECTOR(Op, DAG);
  case ISD::INSERT_VECTOR_ELT:  return LowerINSERT_VECTOR_ELT(Op, DAG);
  case ISD::MUL:                return LowerMUL(Op, DAG);
  case ISD::FP_EXTEND:          return LowerFP_EXTEND(Op, DAG);
  case ISD::STRICT_FP_ROUND:
  case ISD::FP_ROUND:
    return LowerFP_ROUND(Op, DAG);
  case ISD::ROTL:               return LowerROTL(Op, DAG);

  // For counter-based loop handling.
  case ISD::INTRINSIC_W_CHAIN:
    return SDValue();

  case ISD::BITCAST:            return LowerBITCAST(Op, DAG);

  // Frame & Return address.
  case ISD::RETURNADDR:         return LowerRETURNADDR(Op, DAG);
  case ISD::FRAMEADDR:          return LowerFRAMEADDR(Op, DAG);

  case ISD::INTRINSIC_VOID:
    return LowerINTRINSIC_VOID(Op, DAG);
  case ISD::BSWAP:
    return LowerBSWAP(Op, DAG);
  case ISD::ATOMIC_CMP_SWAP:
    return LowerATOMIC_CMP_SWAP(Op, DAG);
  case ISD::ATOMIC_STORE:
    return LowerATOMIC_LOAD_STORE(Op, DAG);
  case ISD::IS_FPCLASS:
    return LowerIS_FPCLASS(Op, DAG);
  case ISD::UADDO:
  case ISD::USUBO:
    return LowerADDSUBO(Op, DAG);
  case ISD::UADDO_CARRY:
  case ISD::USUBO_CARRY:
    return LowerADDSUBO_CARRY(Op, DAG);
  case ISD::UCMP:
    return LowerUCMP(Op, DAG);
  case ISD::STRICT_LRINT:
  case ISD::STRICT_LLRINT:
  case ISD::STRICT_LROUND:
  case ISD::STRICT_LLROUND:
  case ISD::STRICT_FNEARBYINT:
    if (Op->getFlags().hasNoFPExcept())
      return Op;
    return SDValue();
  case ISD::VP_LOAD:
    return LowerVP_LOAD(Op, DAG);
  case ISD::VP_STORE:
    return LowerVP_STORE(Op, DAG);
  }
}

void PPCTargetLowering::ReplaceNodeResults(SDNode *N,
                                           SmallVectorImpl<SDValue>&Results,
                                           SelectionDAG &DAG) const {
  SDLoc dl(N);
  switch (N->getOpcode()) {
  default:
    llvm_unreachable("Do not know how to custom type legalize this operation!");
  case ISD::ATOMIC_LOAD: {
    SDValue Res = LowerATOMIC_LOAD_STORE(SDValue(N, 0), DAG);
    Results.push_back(Res);
    Results.push_back(Res.getValue(1));
    break;
  }
  case ISD::READCYCLECOUNTER: {
    SDVTList VTs = DAG.getVTList(MVT::i32, MVT::i32, MVT::Other);
    SDValue RTB = DAG.getNode(PPCISD::READ_TIME_BASE, dl, VTs, N->getOperand(0));

    Results.push_back(
        DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, RTB, RTB.getValue(1)));
    Results.push_back(RTB.getValue(2));
    break;
  }
  case ISD::INTRINSIC_W_CHAIN: {
    if (N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
      break;

    assert(N->getValueType(0) == MVT::i1 &&
           "Unexpected result type for CTR decrement intrinsic");
    EVT SVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
                                 N->getValueType(0));
    SDVTList VTs = DAG.getVTList(SVT, MVT::Other);
    SDValue NewInt = DAG.getNode(N->getOpcode(), dl, VTs, N->getOperand(0),
                                 N->getOperand(1));

    Results.push_back(DAG.getNode(ISD::TRUNCATE, dl, MVT::i1, NewInt));
    Results.push_back(NewInt.getValue(1));
    break;
  }
  case ISD::INTRINSIC_WO_CHAIN: {
    switch (N->getConstantOperandVal(0)) {
    case Intrinsic::ppc_pack_longdouble:
      Results.push_back(DAG.getNode(ISD::BUILD_PAIR, dl, MVT::ppcf128,
                                    N->getOperand(2), N->getOperand(1)));
      break;
    case Intrinsic::ppc_maxfe:
    case Intrinsic::ppc_minfe:
    case Intrinsic::ppc_fnmsub:
    case Intrinsic::ppc_convert_f128_to_ppcf128:
      Results.push_back(LowerINTRINSIC_WO_CHAIN(SDValue(N, 0), DAG));
      break;
    }
    break;
  }
  case ISD::VAARG: {
    if (!Subtarget.isSVR4ABI() || Subtarget.isPPC64())
      return;

    EVT VT = N->getValueType(0);

    if (VT == MVT::i64) {
      SDValue NewNode = LowerVAARG(SDValue(N, 1), DAG);

      Results.push_back(NewNode);
      Results.push_back(NewNode.getValue(1));
    }
    return;
  }
  case ISD::STRICT_FP_TO_SINT:
  case ISD::STRICT_FP_TO_UINT:
  case ISD::FP_TO_SINT:
  case ISD::FP_TO_UINT: {
    // LowerFP_TO_INT() can only handle f32 and f64.
    if (N->getOperand(N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
        MVT::ppcf128)
      return;
    SDValue LoweredValue = LowerFP_TO_INT(SDValue(N, 0), DAG, dl);
    Results.push_back(LoweredValue);
    if (N->isStrictFPOpcode())
      Results.push_back(LoweredValue.getValue(1));
    return;
  }
  case ISD::TRUNCATE: {
    if (!N->getValueType(0).isVector())
      return;
    SDValue Lowered = LowerTRUNCATEVector(SDValue(N, 0), DAG);
    if (Lowered)
      Results.push_back(Lowered);
    return;
  }
  case ISD::SCALAR_TO_VECTOR: {
    SDValue Lowered = LowerSCALAR_TO_VECTOR(SDValue(N, 0), DAG);
    if (Lowered)
      Results.push_back(Lowered);
    return;
  }
  case ISD::FSHL:
  case ISD::FSHR:
    // Don't handle funnel shifts here.
    return;
  case ISD::BITCAST:
    // Don't handle bitcast here.
    return;
  case ISD::FP_EXTEND:
    SDValue Lowered = LowerFP_EXTEND(SDValue(N, 0), DAG);
    if (Lowered)
      Results.push_back(Lowered);
    return;
  }
}

//===----------------------------------------------------------------------===//
//  Other Lowering Code
//===----------------------------------------------------------------------===//

static Instruction *callIntrinsic(IRBuilderBase &Builder, Intrinsic::ID Id) {
  return Builder.CreateIntrinsic(Id, {});
}

Value *PPCTargetLowering::emitLoadLinked(IRBuilderBase &Builder, Type *ValueTy,
                                         Value *Addr,
                                         AtomicOrdering Ord) const {
  unsigned SZ = ValueTy->getPrimitiveSizeInBits();

  assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
         "Only 8/16/32/64-bit atomic loads supported");
  Intrinsic::ID IntID;
  switch (SZ) {
  default:
    llvm_unreachable("Unexpected PrimitiveSize");
  case 8:
    IntID = Intrinsic::ppc_lbarx;
    assert(Subtarget.hasPartwordAtomics() && "No support partword atomics.");
    break;
  case 16:
    IntID = Intrinsic::ppc_lharx;
    assert(Subtarget.hasPartwordAtomics() && "No support partword atomics.");
    break;
  case 32:
    IntID = Intrinsic::ppc_lwarx;
    break;
  case 64:
    IntID = Intrinsic::ppc_ldarx;
    break;
  }
  Value *Call =
      Builder.CreateIntrinsic(IntID, Addr, /*FMFSource=*/nullptr, "larx");

  return Builder.CreateTruncOrBitCast(Call, ValueTy);
}

// Perform a store-conditional operation to Addr. Return the status of the
// store. This should be 0 if the store succeeded, non-zero otherwise.
Value *PPCTargetLowering::emitStoreConditional(IRBuilderBase &Builder,
                                               Value *Val, Value *Addr,
                                               AtomicOrdering Ord) const {
  Type *Ty = Val->getType();
  unsigned SZ = Ty->getPrimitiveSizeInBits();

  assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
         "Only 8/16/32/64-bit atomic loads supported");
  Intrinsic::ID IntID;
  switch (SZ) {
  default:
    llvm_unreachable("Unexpected PrimitiveSize");
  case 8:
    IntID = Intrinsic::ppc_stbcx;
    assert(Subtarget.hasPartwordAtomics() && "No support partword atomics.");
    break;
  case 16:
    IntID = Intrinsic::ppc_sthcx;
    assert(Subtarget.hasPartwordAtomics() && "No support partword atomics.");
    break;
  case 32:
    IntID = Intrinsic::ppc_stwcx;
    break;
  case 64:
    IntID = Intrinsic::ppc_stdcx;
    break;
  }

  if (SZ == 8 || SZ == 16)
    Val = Builder.CreateZExt(Val, Builder.getInt32Ty());

  Value *Call = Builder.CreateIntrinsic(IntID, {Addr, Val},
                                        /*FMFSource=*/nullptr, "stcx");
  return Builder.CreateXor(Call, Builder.getInt32(1));
}

// The mappings for emitLeading/TrailingFence is taken from
// http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html
Instruction *PPCTargetLowering::emitLeadingFence(IRBuilderBase &Builder,
                                                 Instruction *Inst,
                                                 AtomicOrdering Ord) const {
  if (Ord == AtomicOrdering::SequentiallyConsistent)
    return callIntrinsic(Builder, Intrinsic::ppc_sync);
  if (isReleaseOrStronger(Ord))
    return callIntrinsic(Builder, Intrinsic::ppc_lwsync);
  return nullptr;
}

Instruction *PPCTargetLowering::emitTrailingFence(IRBuilderBase &Builder,
                                                  Instruction *Inst,
                                                  AtomicOrdering Ord) const {
  if (Inst->hasAtomicLoad() && isAcquireOrStronger(Ord)) {
    // See http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html and
    // http://www.rdrop.com/users/paulmck/scalability/paper/N2745r.2011.03.04a.html
    // and http://www.cl.cam.ac.uk/~pes20/cppppc/ for justification.
    if (isa<LoadInst>(Inst))
      return Builder.CreateIntrinsic(Intrinsic::ppc_cfence, {Inst->getType()},
                                     {Inst});
    // FIXME: Can use isync for rmw operation.
    return callIntrinsic(Builder, Intrinsic::ppc_lwsync);
  }
  return nullptr;
}

MachineBasicBlock *
PPCTargetLowering::EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *BB,
                                    unsigned AtomicSize,
                                    unsigned BinOpcode,
                                    unsigned CmpOpcode,
                                    unsigned CmpPred) const {
  // This also handles ATOMIC_SWAP, indicated by BinOpcode==0.
  const TargetInstrInfo *TII = Subtarget.getInstrInfo();

  auto LoadMnemonic = PPC::LDARX;
  auto StoreMnemonic = PPC::STDCX;
  switch (AtomicSize) {
  default:
    llvm_unreachable("Unexpected size of atomic entity");
  case 1:
    LoadMnemonic = PPC::LBARX;
    StoreMnemonic = PPC::STBCX;
    assert(Subtarget.hasPartwordAtomics() && "Call this only with size >=4");
    break;
  case 2:
    LoadMnemonic = PPC::LHARX;
    StoreMnemonic = PPC::STHCX;
    assert(Subtarget.hasPartwordAtomics() && "Call this only with size >=4");
    break;
  case 4:
    LoadMnemonic = PPC::LWARX;
    StoreMnemonic = PPC::STWCX;
    break;
  case 8:
    LoadMnemonic = PPC::LDARX;
    StoreMnemonic = PPC::STDCX;
    break;
  }

  const BasicBlock *LLVM_BB = BB->getBasicBlock();
  MachineFunction *F = BB->getParent();
  MachineFunction::iterator It = ++BB->getIterator();

  Register dest = MI.getOperand(0).getReg();
  Register ptrA = MI.getOperand(1).getReg();
  Register ptrB = MI.getOperand(2).getReg();
  Register incr = MI.getOperand(3).getReg();
  DebugLoc dl = MI.getDebugLoc();

  MachineBasicBlock *loopMBB = F->CreateMachineBasicBlock(LLVM_BB);
  MachineBasicBlock *loop2MBB =
    CmpOpcode ? F->CreateMachineBasicBlock(LLVM_BB) : nullptr;
  MachineBasicBlock *exitMBB = F->CreateMachineBasicBlock(LLVM_BB);
  F->insert(It, loopMBB);
  if (CmpOpcode)
    F->insert(It, loop2MBB);
  F->insert(It, exitMBB);
  exitMBB->splice(exitMBB->begin(), BB,
                  std::next(MachineBasicBlock::iterator(MI)), BB->end());
  exitMBB->transferSuccessorsAndUpdatePHIs(BB);

  MachineRegisterInfo &RegInfo = F->getRegInfo();
  Register TmpReg = (!BinOpcode) ? incr :
    RegInfo.createVirtualRegister( AtomicSize == 8 ? &PPC::G8RCRegClass
                                           : &PPC::GPRCRegClass);

  //  thisMBB:
  //   ...
  //   fallthrough --> loopMBB
  BB->addSuccessor(loopMBB);

  //  loopMBB:
  //   l[wd]arx dest, ptr
  //   add r0, dest, incr
  //   st[wd]cx. r0, ptr
  //   bne- loopMBB
  //   fallthrough --> exitMBB

  // For max/min...
  //  loopMBB:
  //   l[wd]arx dest, ptr
  //   cmpl?[wd] dest, incr
  //   bgt exitMBB
  //  loop2MBB:
  //   st[wd]cx. dest, ptr
  //   bne- loopMBB
  //   fallthrough --> exitMBB

  BB = loopMBB;
  BuildMI(BB, dl, TII->get(LoadMnemonic), dest)
    .addReg(ptrA).addReg(ptrB);
  if (BinOpcode)
    BuildMI(BB, dl, TII->get(BinOpcode), TmpReg).addReg(incr).addReg(dest);
  if (CmpOpcode) {
    Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
    // Signed comparisons of byte or halfword values must be sign-extended.
    if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
      Register ExtReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
      BuildMI(BB, dl, TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
              ExtReg).addReg(dest);
      BuildMI(BB, dl, TII->get(CmpOpcode), CrReg).addReg(ExtReg).addReg(incr);
    } else
      BuildMI(BB, dl, TII->get(CmpOpcode), CrReg).addReg(dest).addReg(incr);

    BuildMI(BB, dl, TII->get(PPC::BCC))
        .addImm(CmpPred)
        .addReg(CrReg)
        .addMBB(exitMBB);
    BB->addSuccessor(loop2MBB);
    BB->addSuccessor(exitMBB);
    BB = loop2MBB;
  }
  BuildMI(BB, dl, TII->get(StoreMnemonic))
    .addReg(TmpReg).addReg(ptrA).addReg(ptrB);
  BuildMI(BB, dl, TII->get(PPC::BCC))
      .addImm(PPC::PRED_NE_MINUS)
      .addReg(PPC::CR0)
      .addMBB(loopMBB);
  BB->addSuccessor(loopMBB);
  BB->addSuccessor(exitMBB);

  //  exitMBB:
  //   ...
  BB = exitMBB;
  return BB;
}

static bool isSignExtended(MachineInstr &MI, const PPCInstrInfo *TII) {
  switch(MI.getOpcode()) {
  default:
    return false;
  case PPC::COPY:
    return TII->isSignExtended(MI.getOperand(1).getReg(),
                               &MI.getMF()->getRegInfo());
  case PPC::LHA:
  case PPC::LHA8:
  case PPC::LHAU:
  case PPC::LHAU8:
  case PPC::LHAUX:
  case PPC::LHAUX8:
  case PPC::LHAX:
  case PPC::LHAX8:
  case PPC::LWA:
  case PPC::LWAUX:
  case PPC::LWAX:
  case PPC::LWAX_32:
  case PPC::LWA_32:
  case PPC::PLHA:
  case PPC::PLHA8:
  case PPC::PLHA8pc:
  case PPC::PLHApc:
  case PPC::PLWA:
  case PPC::PLWA8:
  case PPC::PLWA8pc:
  case PPC::PLWApc:
  case PPC::EXTSB:
  case PPC::EXTSB8:
  case PPC::EXTSB8_32_64:
  case PPC::EXTSB8_rec:
  case PPC::EXTSB_rec:
  case PPC::EXTSH:
  case PPC::EXTSH8:
  case PPC::EXTSH8_32_64:
  case PPC::EXTSH8_rec:
  case PPC::EXTSH_rec:
  case PPC::EXTSW:
  case PPC::EXTSWSLI:
  case PPC::EXTSWSLI_32_64:
  case PPC::EXTSWSLI_32_64_rec:
  case PPC::EXTSWSLI_rec:
  case PPC::EXTSW_32:
  case PPC::EXTSW_32_64:
  case PPC::EXTSW_32_64_rec:
  case PPC::EXTSW_rec:
  case PPC::SRAW:
  case PPC::SRAWI:
  case PPC::SRAWI_rec:
  case PPC::SRAW_rec:
    return true;
  }
  return false;
}

MachineBasicBlock *PPCTargetLowering::EmitPartwordAtomicBinary(
    MachineInstr &MI, MachineBasicBlock *BB,
    bool is8bit, // operation
    unsigned BinOpcode, unsigned CmpOpcode, unsigned CmpPred) const {
  // This also handles ATOMIC_SWAP, indicated by BinOpcode==0.
  const PPCInstrInfo *TII = Subtarget.getInstrInfo();

  // If this is a signed comparison and the value being compared is not known
  // to be sign extended, sign extend it here.
  DebugLoc dl = MI.getDebugLoc();
  MachineFunction *F = BB->getParent();
  MachineRegisterInfo &RegInfo = F->getRegInfo();
  Register incr = MI.getOperand(3).getReg();
  bool IsSignExtended =
      incr.isVirtual() && isSignExtended(*RegInfo.getVRegDef(incr), TII);

  if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
    Register ValueReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
    BuildMI(*BB, MI, dl, TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
        .addReg(MI.getOperand(3).getReg());
    MI.getOperand(3).setReg(ValueReg);
    incr = ValueReg;
  }
  // If we support part-word atomic mnemonics, just use them
  if (Subtarget.hasPartwordAtomics())
    return EmitAtomicBinary(MI, BB, is8bit ? 1 : 2, BinOpcode, CmpOpcode,
                            CmpPred);

  // In 64 bit mode we have to use 64 bits for addresses, even though the
  // lwarx/stwcx are 32 bits.  With the 32-bit atomics we can use address
  // registers without caring whether they're 32 or 64, but here we're
  // doing actual arithmetic on the addresses.
  bool is64bit = Subtarget.isPPC64();
  bool isLittleEndian = Subtarget.isLittleEndian();
  unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;

  const BasicBlock *LLVM_BB = BB->getBasicBlock();
  MachineFunction::iterator It = ++BB->getIterator();

  Register dest = MI.getOperand(0).getReg();
  Register ptrA = MI.getOperand(1).getReg();
  Register ptrB = MI.getOperand(2).getReg();

  MachineBasicBlock *loopMBB = F->CreateMachineBasicBlock(LLVM_BB);
  MachineBasicBlock *loop2MBB =
      CmpOpcode ? F->CreateMachineBasicBlock(LLVM_BB) : nullptr;
  MachineBasicBlock *exitMBB = F->CreateMachineBasicBlock(LLVM_BB);
  F->insert(It, loopMBB);
  if (CmpOpcode)
    F->insert(It, loop2MBB);
  F->insert(It, exitMBB);
  exitMBB->splice(exitMBB->begin(), BB,
                  std::next(MachineBasicBlock::iterator(MI)), BB->end());
  exitMBB->transferSuccessorsAndUpdatePHIs(BB);

  const TargetRegisterClass *RC =
      is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
  const TargetRegisterClass *GPRC = &PPC::GPRCRegClass;

  Register PtrReg = RegInfo.createVirtualRegister(RC);
  Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
  Register ShiftReg =
      isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
  Register Incr2Reg = RegInfo.createVirtualRegister(GPRC);
  Register MaskReg = RegInfo.createVirtualRegister(GPRC);
  Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
  Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
  Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
  Register Tmp3Reg = RegInfo.createVirtualRegister(GPRC);
  Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
  Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
  Register SrwDestReg = RegInfo.createVirtualRegister(GPRC);
  Register Ptr1Reg;
  Register TmpReg =
      (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(GPRC);

  //  thisMBB:
  //   ...
  //   fallthrough --> loopMBB
  BB->addSuccessor(loopMBB);

  // The 4-byte load must be aligned, while a char or short may be
  // anywhere in the word.  Hence all this nasty bookkeeping code.
  //   add ptr1, ptrA, ptrB [copy if ptrA==0]
  //   rlwinm shift1, ptr1, 3, 27, 28 [3, 27, 27]
  //   xori shift, shift1, 24 [16]
  //   rlwinm ptr, ptr1, 0, 0, 29
  //   slw incr2, incr, shift
  //   li mask2, 255 [li mask3, 0; ori mask2, mask3, 65535]
  //   slw mask, mask2, shift
  //  loopMBB:
  //   lwarx tmpDest, ptr
  //   add tmp, tmpDest, incr2
  //   andc tmp2, tmpDest, mask
  //   and tmp3, tmp, mask
  //   or tmp4, tmp3, tmp2
  //   stwcx. tmp4, ptr
  //   bne- loopMBB
  //   fallthrough --> exitMBB
  //   srw SrwDest, tmpDest, shift
  //   rlwinm SrwDest, SrwDest, 0, 24 [16], 31
  if (ptrA != ZeroReg) {
    Ptr1Reg = RegInfo.createVirtualRegister(RC);
    BuildMI(BB, dl, TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
        .addReg(ptrA)
        .addReg(ptrB);
  } else {
    Ptr1Reg = ptrB;
  }
  // We need use 32-bit subregister to avoid mismatch register class in 64-bit
  // mode.
  BuildMI(BB, dl, TII->get(PPC::RLWINM), Shift1Reg)
      .addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
      .addImm(3)
      .addImm(27)
      .addImm(is8bit ? 28 : 27);
  if (!isLittleEndian)
    BuildMI(BB, dl, TII->get(PPC::XORI), ShiftReg)
        .addReg(Shift1Reg)
        .addImm(is8bit ? 24 : 16);
  if (is64bit)
    BuildMI(BB, dl, TII->get(PPC::RLDICR), PtrReg)
        .addReg(Ptr1Reg)
        .addImm(0)
        .addImm(61);
  else
    BuildMI(BB, dl, TII->get(PPC::RLWINM), PtrReg)
        .addReg(Ptr1Reg)
        .addImm(0)
        .addImm(0)
        .addImm(29);
  BuildMI(BB, dl, TII->get(PPC::SLW), Incr2Reg).addReg(incr).addReg(ShiftReg);
  if (is8bit)
    BuildMI(BB, dl, TII->get(PPC::LI), Mask2Reg).addImm(255);
  else {
    BuildMI(BB, dl, TII->get(PPC::LI), Mask3Reg).addImm(0);
    BuildMI(BB, dl, TII->get(PPC::ORI), Mask2Reg)
        .addReg(Mask3Reg)
        .addImm(65535);
  }
  BuildMI(BB, dl, TII->get(PPC::SLW), MaskReg)
      .addReg(Mask2Reg)
      .addReg(ShiftReg);

  BB = loopMBB;
  BuildMI(BB, dl, TII->get(PPC::LWARX), TmpDestReg)
      .addReg(ZeroReg)
      .addReg(PtrReg);
  if (BinOpcode)
    BuildMI(BB, dl, TII->get(BinOpcode), TmpReg)
        .addReg(Incr2Reg)
        .addReg(TmpDestReg);
  BuildMI(BB, dl, TII->get(PPC::ANDC), Tmp2Reg)
      .addReg(TmpDestReg)
      .addReg(MaskReg);
  BuildMI(BB, dl, TII->get(PPC::AND), Tmp3Reg).addReg(TmpReg).addReg(MaskReg);
  if (CmpOpcode) {
    // For unsigned comparisons, we can directly compare the shifted values.
    // For signed comparisons we shift and sign extend.
    Register SReg = RegInfo.createVirtualRegister(GPRC);
    Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
    BuildMI(BB, dl, TII->get(PPC::AND), SReg)
        .addReg(TmpDestReg)
        .addReg(MaskReg);
    unsigned ValueReg = SReg;
    unsigned CmpReg = Incr2Reg;
    if (CmpOpcode == PPC::CMPW) {
      ValueReg = RegInfo.createVirtualRegister(GPRC);
      BuildMI(BB, dl, TII->get(PPC::SRW), ValueReg)
          .addReg(SReg)
          .addReg(ShiftReg);
      Register ValueSReg = RegInfo.createVirtualRegister(GPRC);
      BuildMI(BB, dl, TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
          .addReg(ValueReg);
      ValueReg = ValueSReg;
      CmpReg = incr;
    }
    BuildMI(BB, dl, TII->get(CmpOpcode), CrReg).addReg(ValueReg).addReg(CmpReg);
    BuildMI(BB, dl, TII->get(PPC::BCC))
        .addImm(CmpPred)
        .addReg(CrReg)
        .addMBB(exitMBB);
    BB->addSuccessor(loop2MBB);
    BB->addSuccessor(exitMBB);
    BB = loop2MBB;
  }
  BuildMI(BB, dl, TII->get(PPC::OR), Tmp4Reg).addReg(Tmp3Reg).addReg(Tmp2Reg);
  BuildMI(BB, dl, TII->get(PPC::STWCX))
      .addReg(Tmp4Reg)
      .addReg(ZeroReg)
      .addReg(PtrReg);
  BuildMI(BB, dl, TII->get(PPC::BCC))
      .addImm(PPC::PRED_NE_MINUS)
      .addReg(PPC::CR0)
      .addMBB(loopMBB);
  BB->addSuccessor(loopMBB);
  BB->addSuccessor(exitMBB);

  //  exitMBB:
  //   ...
  BB = exitMBB;
  // Since the shift amount is not a constant, we need to clear
  // the upper bits with a separate RLWINM.
  BuildMI(*BB, BB->begin(), dl, TII->get(PPC::RLWINM), dest)
      .addReg(SrwDestReg)
      .addImm(0)
      .addImm(is8bit ? 24 : 16)
      .addImm(31);
  BuildMI(*BB, BB->begin(), dl, TII->get(PPC::SRW), SrwDestReg)
      .addReg(TmpDestReg)
      .addReg(ShiftReg);
  return BB;
}

llvm::MachineBasicBlock *
PPCTargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
                                    MachineBasicBlock *MBB) const {
  DebugLoc DL = MI.getDebugLoc();
  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
  const PPCRegisterInfo *TRI = Subtarget.getRegisterInfo();

  MachineFunction *MF = MBB->getParent();
  MachineRegisterInfo &MRI = MF->getRegInfo();

  const BasicBlock *BB = MBB->getBasicBlock();
  MachineFunction::iterator I = ++MBB->getIterator();

  Register DstReg = MI.getOperand(0).getReg();
  const TargetRegisterClass *RC = MRI.getRegClass(DstReg);
  assert(TRI->isTypeLegalForClass(*RC, MVT::i32) && "Invalid destination!");
  Register mainDstReg = MRI.createVirtualRegister(RC);
  Register restoreDstReg = MRI.createVirtualRegister(RC);

  MVT PVT = getPointerTy(MF->getDataLayout());
  assert((PVT == MVT::i64 || PVT == MVT::i32) &&
         "Invalid Pointer Size!");
  // For v = setjmp(buf), we generate
  //
  // thisMBB:
  //  SjLjSetup mainMBB
  //  bl mainMBB
  //  v_restore = 1
  //  b sinkMBB
  //
  // mainMBB:
  //  buf[LabelOffset] = LR
  //  v_main = 0
  //
  // sinkMBB:
  //  v = phi(main, restore)
  //

  MachineBasicBlock *thisMBB = MBB;
  MachineBasicBlock *mainMBB = MF->CreateMachineBasicBlock(BB);
  MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(BB);
  MF->insert(I, mainMBB);
  MF->insert(I, sinkMBB);

  MachineInstrBuilder MIB;

  // Transfer the remainder of BB and its successor edges to sinkMBB.
  sinkMBB->splice(sinkMBB->begin(), MBB,
                  std::next(MachineBasicBlock::iterator(MI)), MBB->end());
  sinkMBB->transferSuccessorsAndUpdatePHIs(MBB);

  // Note that the structure of the jmp_buf used here is not compatible
  // with that used by libc, and is not designed to be. Specifically, it
  // stores only those 'reserved' registers that LLVM does not otherwise
  // understand how to spill. Also, by convention, by the time this
  // intrinsic is called, Clang has already stored the frame address in the
  // first slot of the buffer and stack address in the third. Following the
  // X86 target code, we'll store the jump address in the second slot. We also
  // need to save the TOC pointer (R2) to handle jumps between shared
  // libraries, and that will be stored in the fourth slot. The thread
  // identifier (R13) is not affected.

  // thisMBB:
  const int64_t LabelOffset = 1 * PVT.getStoreSize();
  const int64_t TOCOffset   = 3 * PVT.getStoreSize();
  const int64_t BPOffset    = 4 * PVT.getStoreSize();

  // Prepare IP either in reg.
  const TargetRegisterClass *PtrRC = getRegClassFor(PVT);
  Register LabelReg = MRI.createVirtualRegister(PtrRC);
  Register BufReg = MI.getOperand(1).getReg();

  if (Subtarget.is64BitELFABI()) {
    setUsesTOCBasePtr(*MBB->getParent());
    MIB = BuildMI(*thisMBB, MI, DL, TII->get(PPC::STD))
              .addReg(PPC::X2)
              .addImm(TOCOffset)
              .addReg(BufReg)
              .cloneMemRefs(MI);
  }

  // Naked functions never have a base pointer, and so we use r1. For all
  // other functions, this decision must be delayed until during PEI.
  unsigned BaseReg;
  if (MF->getFunction().hasFnAttribute(Attribute::Naked))
    BaseReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;
  else
    BaseReg = Subtarget.isPPC64() ? PPC::BP8 : PPC::BP;

  MIB = BuildMI(*thisMBB, MI, DL,
                TII->get(Subtarget.isPPC64() ? PPC::STD : PPC::STW))
            .addReg(BaseReg)
            .addImm(BPOffset)
            .addReg(BufReg)
            .cloneMemRefs(MI);

  // Setup
  MIB = BuildMI(*thisMBB, MI, DL, TII->get(PPC::BCLalways)).addMBB(mainMBB);
  MIB.addRegMask(TRI->getNoPreservedMask());

  BuildMI(*thisMBB, MI, DL, TII->get(PPC::LI), restoreDstReg).addImm(1);

  MIB = BuildMI(*thisMBB, MI, DL, TII->get(PPC::EH_SjLj_Setup))
          .addMBB(mainMBB);
  MIB = BuildMI(*thisMBB, MI, DL, TII->get(PPC::B)).addMBB(sinkMBB);

  thisMBB->addSuccessor(mainMBB, BranchProbability::getZero());
  thisMBB->addSuccessor(sinkMBB, BranchProbability::getOne());

  // mainMBB:
  //  mainDstReg = 0
  MIB =
      BuildMI(mainMBB, DL,
              TII->get(Subtarget.isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);

  // Store IP
  if (Subtarget.isPPC64()) {
    MIB = BuildMI(mainMBB, DL, TII->get(PPC::STD))
            .addReg(LabelReg)
            .addImm(LabelOffset)
            .addReg(BufReg);
  } else {
    MIB = BuildMI(mainMBB, DL, TII->get(PPC::STW))
            .addReg(LabelReg)
            .addImm(LabelOffset)
            .addReg(BufReg);
  }
  MIB.cloneMemRefs(MI);

  BuildMI(mainMBB, DL, TII->get(PPC::LI), mainDstReg).addImm(0);
  mainMBB->addSuccessor(sinkMBB);

  // sinkMBB:
  BuildMI(*sinkMBB, sinkMBB->begin(), DL,
          TII->get(PPC::PHI), DstReg)
    .addReg(mainDstReg).addMBB(mainMBB)
    .addReg(restoreDstReg).addMBB(thisMBB);

  MI.eraseFromParent();
  return sinkMBB;
}

MachineBasicBlock *
PPCTargetLowering::emitEHSjLjLongJmp(MachineInstr &MI,
                                     MachineBasicBlock *MBB) const {
  DebugLoc DL = MI.getDebugLoc();
  const TargetInstrInfo *TII = Subtarget.getInstrInfo();

  MachineFunction *MF = MBB->getParent();
  MachineRegisterInfo &MRI = MF->getRegInfo();

  MVT PVT = getPointerTy(MF->getDataLayout());
  assert((PVT == MVT::i64 || PVT == MVT::i32) &&
         "Invalid Pointer Size!");

  const TargetRegisterClass *RC =
    (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
  Register Tmp = MRI.createVirtualRegister(RC);
  // Since FP is only updated here but NOT referenced, it's treated as GPR.
  unsigned FP  = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
  unsigned SP  = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
  unsigned BP =
      (PVT == MVT::i64)
          ? PPC::X30
          : (Subtarget.isSVR4ABI() && isPositionIndependent() ? PPC::R29
                                                              : PPC::R30);

  MachineInstrBuilder MIB;

  const int64_t LabelOffset = 1 * PVT.getStoreSize();
  const int64_t SPOffset    = 2 * PVT.getStoreSize();
  const int64_t TOCOffset   = 3 * PVT.getStoreSize();
  const int64_t BPOffset    = 4 * PVT.getStoreSize();

  Register BufReg = MI.getOperand(0).getReg();

  // Reload FP (the jumped-to function may not have had a
  // frame pointer, and if so, then its r31 will be restored
  // as necessary).
  if (PVT == MVT::i64) {
    MIB = BuildMI(*MBB, MI, DL, TII->get(PPC::LD), FP)
            .addImm(0)
            .addReg(BufReg);
  } else {
    MIB = BuildMI(*MBB, MI, DL, TII->get(PPC::LWZ), FP)
            .addImm(0)
            .addReg(BufReg);
  }
  MIB.cloneMemRefs(MI);

  // Reload IP
  if (PVT == MVT::i64) {
    MIB = BuildMI(*MBB, MI, DL, TII->get(PPC::LD), Tmp)
            .addImm(LabelOffset)
            .addReg(BufReg);
  } else {
    MIB = BuildMI(*MBB, MI, DL, TII->get(PPC::LWZ), Tmp)
            .addImm(LabelOffset)
            .addReg(BufReg);
  }
  MIB.cloneMemRefs(MI);

  // Reload SP
  if (PVT == MVT::i64) {
    MIB = BuildMI(*MBB, MI, DL, TII->get(PPC::LD), SP)
            .addImm(SPOffset)
            .addReg(BufReg);
  } else {
    MIB = BuildMI(*MBB, MI, DL, TII->get(PPC::LWZ), SP)
            .addImm(SPOffset)
            .addReg(BufReg);
  }
  MIB.cloneMemRefs(MI);

  // Reload BP
  if (PVT == MVT::i64) {
    MIB = BuildMI(*MBB, MI, DL, TII->get(PPC::LD), BP)
            .addImm(BPOffset)
            .addReg(BufReg);
  } else {
    MIB = BuildMI(*MBB, MI, DL, TII->get(PPC::LWZ), BP)
            .addImm(BPOffset)
            .addReg(BufReg);
  }
  MIB.cloneMemRefs(MI);

  // Reload TOC
  if (PVT == MVT::i64 && Subtarget.isSVR4ABI()) {
    setUsesTOCBasePtr(*MBB->getParent());
    MIB = BuildMI(*MBB, MI, DL, TII->get(PPC::LD), PPC::X2)
              .addImm(TOCOffset)
              .addReg(BufReg)
              .cloneMemRefs(MI);
  }

  // Jump
  BuildMI(*MBB, MI, DL,
          TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).addReg(Tmp);
  BuildMI(*MBB, MI, DL, TII->get(PVT == MVT::i64 ? PPC::BCTR8 : PPC::BCTR));

  MI.eraseFromParent();
  return MBB;
}

bool PPCTargetLowering::hasInlineStackProbe(const MachineFunction &MF) const {
  // If the function specifically requests inline stack probes, emit them.
  if (MF.getFunction().hasFnAttribute("probe-stack"))
    return MF.getFunction().getFnAttribute("probe-stack").getValueAsString() ==
           "inline-asm";
  return false;
}

unsigned PPCTargetLowering::getStackProbeSize(const MachineFunction &MF) const {
  const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
  unsigned StackAlign = TFI->getStackAlignment();
  assert(StackAlign >= 1 && isPowerOf2_32(StackAlign) &&
         "Unexpected stack alignment");
  // The default stack probe size is 4096 if the function has no
  // stack-probe-size attribute.
  const Function &Fn = MF.getFunction();
  unsigned StackProbeSize =
      Fn.getFnAttributeAsParsedInteger("stack-probe-size", 4096);
  // Round down to the stack alignment.
  StackProbeSize &= ~(StackAlign - 1);
  return StackProbeSize ? StackProbeSize : StackAlign;
}

// Lower dynamic stack allocation with probing. `emitProbedAlloca` is splitted
// into three phases. In the first phase, it uses pseudo instruction
// PREPARE_PROBED_ALLOCA to get the future result of actual FramePointer and
// FinalStackPtr. In the second phase, it generates a loop for probing blocks.
// At last, it uses pseudo instruction DYNAREAOFFSET to get the future result of
// MaxCallFrameSize so that it can calculate correct data area pointer.
MachineBasicBlock *
PPCTargetLowering::emitProbedAlloca(MachineInstr &MI,
                                    MachineBasicBlock *MBB) const {
  const bool isPPC64 = Subtarget.isPPC64();
  MachineFunction *MF = MBB->getParent();
  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
  DebugLoc DL = MI.getDebugLoc();
  const unsigned ProbeSize = getStackProbeSize(*MF);
  const BasicBlock *ProbedBB = MBB->getBasicBlock();
  MachineRegisterInfo &MRI = MF->getRegInfo();
  // The CFG of probing stack looks as
  //         +-----+
  //         | MBB |
  //         +--+--+
  //            |
  //       +----v----+
  //  +--->+ TestMBB +---+
  //  |    +----+----+   |
  //  |         |        |
  //  |   +-----v----+   |
  //  +---+ BlockMBB |   |
  //      +----------+   |
  //                     |
  //       +---------+   |
  //       | TailMBB +<--+
  //       +---------+
  // In MBB, calculate previous frame pointer and final stack pointer.
  // In TestMBB, test if sp is equal to final stack pointer, if so, jump to
  // TailMBB. In BlockMBB, update the sp atomically and jump back to TestMBB.
  // TailMBB is spliced via \p MI.
  MachineBasicBlock *TestMBB = MF->CreateMachineBasicBlock(ProbedBB);
  MachineBasicBlock *TailMBB = MF->CreateMachineBasicBlock(ProbedBB);
  MachineBasicBlock *BlockMBB = MF->CreateMachineBasicBlock(ProbedBB);

  MachineFunction::iterator MBBIter = ++MBB->getIterator();
  MF->insert(MBBIter, TestMBB);
  MF->insert(MBBIter, BlockMBB);
  MF->insert(MBBIter, TailMBB);

  const TargetRegisterClass *G8RC = &PPC::G8RCRegClass;
  const TargetRegisterClass *GPRC = &PPC::GPRCRegClass;

  Register DstReg = MI.getOperand(0).getReg();
  Register NegSizeReg = MI.getOperand(1).getReg();
  Register SPReg = isPPC64 ? PPC::X1 : PPC::R1;
  Register FinalStackPtr = MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
  Register FramePointer = MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
  Register ActualNegSizeReg = MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);

  // Since value of NegSizeReg might be realigned in prologepilog, insert a
  // PREPARE_PROBED_ALLOCA pseudo instruction to get actual FramePointer and
  // NegSize.
  unsigned ProbeOpc;
  if (!MRI.hasOneNonDBGUse(NegSizeReg))
    ProbeOpc =
        isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
  else
    // By introducing PREPARE_PROBED_ALLOCA_NEGSIZE_OPT, ActualNegSizeReg
    // and NegSizeReg will be allocated in the same phyreg to avoid
    // redundant copy when NegSizeReg has only one use which is current MI and
    // will be replaced by PREPARE_PROBED_ALLOCA then.
    ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
                       : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
  BuildMI(*MBB, {MI}, DL, TII->get(ProbeOpc), FramePointer)
      .addDef(ActualNegSizeReg)
      .addReg(NegSizeReg)
      .add(MI.getOperand(2))
      .add(MI.getOperand(3));

  // Calculate final stack pointer, which equals to SP + ActualNegSize.
  BuildMI(*MBB, {MI}, DL, TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4),
          FinalStackPtr)
      .addReg(SPReg)
      .addReg(ActualNegSizeReg);

  // Materialize a scratch register for update.
  int64_t NegProbeSize = -(int64_t)ProbeSize;
  assert(isInt<32>(NegProbeSize) && "Unhandled probe size!");
  Register ScratchReg = MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
  if (!isInt<16>(NegProbeSize)) {
    Register TempReg = MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
    BuildMI(*MBB, {MI}, DL, TII->get(isPPC64 ? PPC::LIS8 : PPC::LIS), TempReg)
        .addImm(NegProbeSize >> 16);
    BuildMI(*MBB, {MI}, DL, TII->get(isPPC64 ? PPC::ORI8 : PPC::ORI),
            ScratchReg)
        .addReg(TempReg)
        .addImm(NegProbeSize & 0xFFFF);
  } else
    BuildMI(*MBB, {MI}, DL, TII->get(isPPC64 ? PPC::LI8 : PPC::LI), ScratchReg)
        .addImm(NegProbeSize);

  {
    // Probing leading residual part.
    Register Div = MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
    BuildMI(*MBB, {MI}, DL, TII->get(isPPC64 ? PPC::DIVD : PPC::DIVW), Div)
        .addReg(ActualNegSizeReg)
        .addReg(ScratchReg);
    Register Mul = MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
    BuildMI(*MBB, {MI}, DL, TII->get(isPPC64 ? PPC::MULLD : PPC::MULLW), Mul)
        .addReg(Div)
        .addReg(ScratchReg);
    Register NegMod = MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
    BuildMI(*MBB, {MI}, DL, TII->get(isPPC64 ? PPC::SUBF8 : PPC::SUBF), NegMod)
        .addReg(Mul)
        .addReg(ActualNegSizeReg);
    BuildMI(*MBB, {MI}, DL, TII->get(isPPC64 ? PPC::STDUX : PPC::STWUX), SPReg)
        .addReg(FramePointer)
        .addReg(SPReg)
        .addReg(NegMod);
  }

  {
    // Remaining part should be multiple of ProbeSize.
    Register CmpResult = MRI.createVirtualRegister(&PPC::CRRCRegClass);
    BuildMI(TestMBB, DL, TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
        .addReg(SPReg)
        .addReg(FinalStackPtr);
    BuildMI(TestMBB, DL, TII->get(PPC::BCC))
        .addImm(PPC::PRED_EQ)
        .addReg(CmpResult)
        .addMBB(TailMBB);
    TestMBB->addSuccessor(BlockMBB);
    TestMBB->addSuccessor(TailMBB);
  }

  {
    // Touch the block.
    // |P...|P...|P...
    BuildMI(BlockMBB, DL, TII->get(isPPC64 ? PPC::STDUX : PPC::STWUX), SPReg)
        .addReg(FramePointer)
        .addReg(SPReg)
        .addReg(ScratchReg);
    BuildMI(BlockMBB, DL, TII->get(PPC::B)).addMBB(TestMBB);
    BlockMBB->addSuccessor(TestMBB);
  }

  // Calculation of MaxCallFrameSize is deferred to prologepilog, use
  // DYNAREAOFFSET pseudo instruction to get the future result.
  Register MaxCallFrameSizeReg =
      MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
  BuildMI(TailMBB, DL,
          TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
          MaxCallFrameSizeReg)
      .add(MI.getOperand(2))
      .add(MI.getOperand(3));
  BuildMI(TailMBB, DL, TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
      .addReg(SPReg)
      .addReg(MaxCallFrameSizeReg);

  // Splice instructions after MI to TailMBB.
  TailMBB->splice(TailMBB->end(), MBB,
                  std::next(MachineBasicBlock::iterator(MI)), MBB->end());
  TailMBB->transferSuccessorsAndUpdatePHIs(MBB);
  MBB->addSuccessor(TestMBB);

  // Delete the pseudo instruction.
  MI.eraseFromParent();

  ++NumDynamicAllocaProbed;
  return TailMBB;
}

static bool IsSelectCC(MachineInstr &MI) {
  switch (MI.getOpcode()) {
  case PPC::SELECT_CC_I4:
  case PPC::SELECT_CC_I8:
  case PPC::SELECT_CC_F4:
  case PPC::SELECT_CC_F8:
  case PPC::SELECT_CC_F16:
  case PPC::SELECT_CC_VRRC:
  case PPC::SELECT_CC_VSFRC:
  case PPC::SELECT_CC_VSSRC:
  case PPC::SELECT_CC_VSRC:
  case PPC::SELECT_CC_SPE4:
  case PPC::SELECT_CC_SPE:
    return true;
  default:
    return false;
  }
}

static bool IsSelect(MachineInstr &MI) {
  switch (MI.getOpcode()) {
  case PPC::SELECT_I4:
  case PPC::SELECT_I8:
  case PPC::SELECT_F4:
  case PPC::SELECT_F8:
  case PPC::SELECT_F16:
  case PPC::SELECT_SPE:
  case PPC::SELECT_SPE4:
  case PPC::SELECT_VRRC:
  case PPC::SELECT_VSFRC:
  case PPC::SELECT_VSSRC:
  case PPC::SELECT_VSRC:
    return true;
  default:
    return false;
  }
}

MachineBasicBlock *
PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
                                               MachineBasicBlock *BB) const {
  if (MI.getOpcode() == TargetOpcode::STACKMAP ||
      MI.getOpcode() == TargetOpcode::PATCHPOINT) {
    if (Subtarget.is64BitELFABI() &&
        MI.getOpcode() == TargetOpcode::PATCHPOINT &&
        !Subtarget.isUsingPCRelativeCalls()) {
      // Call lowering should have added an r2 operand to indicate a dependence
      // on the TOC base pointer value. It can't however, because there is no
      // way to mark the dependence as implicit there, and so the stackmap code
      // will confuse it with a regular operand. Instead, add the dependence
      // here.
      MI.addOperand(MachineOperand::CreateReg(PPC::X2, false, true));
    }

    return emitPatchPoint(MI, BB);
  }

  if (MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
      MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
    return emitEHSjLjSetJmp(MI, BB);
  } else if (MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
             MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
    return emitEHSjLjLongJmp(MI, BB);
  }

  const TargetInstrInfo *TII = Subtarget.getInstrInfo();

  // To "insert" these instructions we actually have to insert their
  // control-flow patterns.
  const BasicBlock *LLVM_BB = BB->getBasicBlock();
  MachineFunction::iterator It = ++BB->getIterator();

  MachineFunction *F = BB->getParent();
  MachineRegisterInfo &MRI = F->getRegInfo();

  if (Subtarget.hasISEL() &&
      (MI.getOpcode() == PPC::SELECT_CC_I4 ||
       MI.getOpcode() == PPC::SELECT_CC_I8 ||
       MI.getOpcode() == PPC::SELECT_I4 || MI.getOpcode() == PPC::SELECT_I8)) {
    SmallVector<MachineOperand, 2> Cond;
    if (MI.getOpcode() == PPC::SELECT_CC_I4 ||
        MI.getOpcode() == PPC::SELECT_CC_I8)
      Cond.push_back(MI.getOperand(4));
    else
      Cond.push_back(MachineOperand::CreateImm(PPC::PRED_BIT_SET));
    Cond.push_back(MI.getOperand(1));

    DebugLoc dl = MI.getDebugLoc();
    TII->insertSelect(*BB, MI, dl, MI.getOperand(0).getReg(), Cond,
                      MI.getOperand(2).getReg(), MI.getOperand(3).getReg());
  } else if (IsSelectCC(MI) || IsSelect(MI)) {
    // The incoming instruction knows the destination vreg to set, the
    // condition code register to branch on, the true/false values to
    // select between, and a branch opcode to use.

    //  thisMBB:
    //  ...
    //   TrueVal = ...
    //   cmpTY ccX, r1, r2
    //   bCC sinkMBB
    //   fallthrough --> copy0MBB
    MachineBasicBlock *thisMBB = BB;
    MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
    MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
    DebugLoc dl = MI.getDebugLoc();
    F->insert(It, copy0MBB);
    F->insert(It, sinkMBB);

    if (isPhysRegUsedAfter(PPC::CARRY, MI.getIterator())) {
      copy0MBB->addLiveIn(PPC::CARRY);
      sinkMBB->addLiveIn(PPC::CARRY);
    }

    // Set the call frame size on entry to the new basic blocks.
    // See https://reviews.llvm.org/D156113.
    unsigned CallFrameSize = TII->getCallFrameSizeAt(MI);
    copy0MBB->setCallFrameSize(CallFrameSize);
    sinkMBB->setCallFrameSize(CallFrameSize);

    // Transfer the remainder of BB and its successor edges to sinkMBB.
    sinkMBB->splice(sinkMBB->begin(), BB,
                    std::next(MachineBasicBlock::iterator(MI)), BB->end());
    sinkMBB->transferSuccessorsAndUpdatePHIs(BB);

    // Next, add the true and fallthrough blocks as its successors.
    BB->addSuccessor(copy0MBB);
    BB->addSuccessor(sinkMBB);

    if (IsSelect(MI)) {
      BuildMI(BB, dl, TII->get(PPC::BC))
          .addReg(MI.getOperand(1).getReg())
          .addMBB(sinkMBB);
    } else {
      unsigned SelectPred = MI.getOperand(4).getImm();
      BuildMI(BB, dl, TII->get(PPC::BCC))
          .addImm(SelectPred)
          .addReg(MI.getOperand(1).getReg())
          .addMBB(sinkMBB);
    }

    //  copy0MBB:
    //   %FalseValue = ...
    //   # fallthrough to sinkMBB
    BB = copy0MBB;

    // Update machine-CFG edges
    BB->addSuccessor(sinkMBB);

    //  sinkMBB:
    //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
    //  ...
    BB = sinkMBB;
    BuildMI(*BB, BB->begin(), dl, TII->get(PPC::PHI), MI.getOperand(0).getReg())
        .addReg(MI.getOperand(3).getReg())
        .addMBB(copy0MBB)
        .addReg(MI.getOperand(2).getReg())
        .addMBB(thisMBB);
  } else if (MI.getOpcode() == PPC::ReadTB) {
    // To read the 64-bit time-base register on a 32-bit target, we read the
    // two halves. Should the counter have wrapped while it was being read, we
    // need to try again.
    // ...
    // readLoop:
    // mfspr Rx,TBU # load from TBU
    // mfspr Ry,TB  # load from TB
    // mfspr Rz,TBU # load from TBU
    // cmpw crX,Rx,Rz # check if 'old'='new'
    // bne readLoop   # branch if they're not equal
    // ...

    MachineBasicBlock *readMBB = F->CreateMachineBasicBlock(LLVM_BB);
    MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
    DebugLoc dl = MI.getDebugLoc();
    F->insert(It, readMBB);
    F->insert(It, sinkMBB);

    // Transfer the remainder of BB and its successor edges to sinkMBB.
    sinkMBB->splice(sinkMBB->begin(), BB,
                    std::next(MachineBasicBlock::iterator(MI)), BB->end());
    sinkMBB->transferSuccessorsAndUpdatePHIs(BB);

    BB->addSuccessor(readMBB);
    BB = readMBB;

    MachineRegisterInfo &RegInfo = F->getRegInfo();
    Register ReadAgainReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
    Register LoReg = MI.getOperand(0).getReg();
    Register HiReg = MI.getOperand(1).getReg();

    BuildMI(BB, dl, TII->get(PPC::MFSPR), HiReg).addImm(269);
    BuildMI(BB, dl, TII->get(PPC::MFSPR), LoReg).addImm(268);
    BuildMI(BB, dl, TII->get(PPC::MFSPR), ReadAgainReg).addImm(269);

    Register CmpReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);

    BuildMI(BB, dl, TII->get(PPC::CMPW), CmpReg)
        .addReg(HiReg)
        .addReg(ReadAgainReg);
    BuildMI(BB, dl, TII->get(PPC::BCC))
        .addImm(PPC::PRED_NE)
        .addReg(CmpReg)
        .addMBB(readMBB);

    BB->addSuccessor(readMBB);
    BB->addSuccessor(sinkMBB);
  } else if (MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
    BB = EmitPartwordAtomicBinary(MI, BB, true, PPC::ADD4);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
    BB = EmitPartwordAtomicBinary(MI, BB, false, PPC::ADD4);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
    BB = EmitAtomicBinary(MI, BB, 4, PPC::ADD4);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
    BB = EmitAtomicBinary(MI, BB, 8, PPC::ADD8);

  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
    BB = EmitPartwordAtomicBinary(MI, BB, true, PPC::AND);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
    BB = EmitPartwordAtomicBinary(MI, BB, false, PPC::AND);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
    BB = EmitAtomicBinary(MI, BB, 4, PPC::AND);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
    BB = EmitAtomicBinary(MI, BB, 8, PPC::AND8);

  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
    BB = EmitPartwordAtomicBinary(MI, BB, true, PPC::OR);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
    BB = EmitPartwordAtomicBinary(MI, BB, false, PPC::OR);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
    BB = EmitAtomicBinary(MI, BB, 4, PPC::OR);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
    BB = EmitAtomicBinary(MI, BB, 8, PPC::OR8);

  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
    BB = EmitPartwordAtomicBinary(MI, BB, true, PPC::XOR);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
    BB = EmitPartwordAtomicBinary(MI, BB, false, PPC::XOR);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
    BB = EmitAtomicBinary(MI, BB, 4, PPC::XOR);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
    BB = EmitAtomicBinary(MI, BB, 8, PPC::XOR8);

  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
    BB = EmitPartwordAtomicBinary(MI, BB, true, PPC::NAND);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
    BB = EmitPartwordAtomicBinary(MI, BB, false, PPC::NAND);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
    BB = EmitAtomicBinary(MI, BB, 4, PPC::NAND);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
    BB = EmitAtomicBinary(MI, BB, 8, PPC::NAND8);

  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
    BB = EmitPartwordAtomicBinary(MI, BB, true, PPC::SUBF);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
    BB = EmitPartwordAtomicBinary(MI, BB, false, PPC::SUBF);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
    BB = EmitAtomicBinary(MI, BB, 4, PPC::SUBF);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
    BB = EmitAtomicBinary(MI, BB, 8, PPC::SUBF8);

  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
    BB = EmitPartwordAtomicBinary(MI, BB, true, 0, PPC::CMPW, PPC::PRED_LT);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
    BB = EmitPartwordAtomicBinary(MI, BB, false, 0, PPC::CMPW, PPC::PRED_LT);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
    BB = EmitAtomicBinary(MI, BB, 4, 0, PPC::CMPW, PPC::PRED_LT);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
    BB = EmitAtomicBinary(MI, BB, 8, 0, PPC::CMPD, PPC::PRED_LT);

  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
    BB = EmitPartwordAtomicBinary(MI, BB, true, 0, PPC::CMPW, PPC::PRED_GT);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
    BB = EmitPartwordAtomicBinary(MI, BB, false, 0, PPC::CMPW, PPC::PRED_GT);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
    BB = EmitAtomicBinary(MI, BB, 4, 0, PPC::CMPW, PPC::PRED_GT);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
    BB = EmitAtomicBinary(MI, BB, 8, 0, PPC::CMPD, PPC::PRED_GT);

  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
    BB = EmitPartwordAtomicBinary(MI, BB, true, 0, PPC::CMPLW, PPC::PRED_LT);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
    BB = EmitPartwordAtomicBinary(MI, BB, false, 0, PPC::CMPLW, PPC::PRED_LT);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
    BB = EmitAtomicBinary(MI, BB, 4, 0, PPC::CMPLW, PPC::PRED_LT);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
    BB = EmitAtomicBinary(MI, BB, 8, 0, PPC::CMPLD, PPC::PRED_LT);

  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
    BB = EmitPartwordAtomicBinary(MI, BB, true, 0, PPC::CMPLW, PPC::PRED_GT);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
    BB = EmitPartwordAtomicBinary(MI, BB, false, 0, PPC::CMPLW, PPC::PRED_GT);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
    BB = EmitAtomicBinary(MI, BB, 4, 0, PPC::CMPLW, PPC::PRED_GT);
  else if (MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
    BB = EmitAtomicBinary(MI, BB, 8, 0, PPC::CMPLD, PPC::PRED_GT);

  else if (MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
    BB = EmitPartwordAtomicBinary(MI, BB, true, 0);
  else if (MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
    BB = EmitPartwordAtomicBinary(MI, BB, false, 0);
  else if (MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
    BB = EmitAtomicBinary(MI, BB, 4, 0);
  else if (MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
    BB = EmitAtomicBinary(MI, BB, 8, 0);
  else if (MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
           MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
           (Subtarget.hasPartwordAtomics() &&
            MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
           (Subtarget.hasPartwordAtomics() &&
            MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
    bool is64bit = MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;

    auto LoadMnemonic = PPC::LDARX;
    auto StoreMnemonic = PPC::STDCX;
    switch (MI.getOpcode()) {
    default:
      llvm_unreachable("Compare and swap of unknown size");
    case PPC::ATOMIC_CMP_SWAP_I8:
      LoadMnemonic = PPC::LBARX;
      StoreMnemonic = PPC::STBCX;
      assert(Subtarget.hasPartwordAtomics() && "No support partword atomics.");
      break;
    case PPC::ATOMIC_CMP_SWAP_I16:
      LoadMnemonic = PPC::LHARX;
      StoreMnemonic = PPC::STHCX;
      assert(Subtarget.hasPartwordAtomics() && "No support partword atomics.");
      break;
    case PPC::ATOMIC_CMP_SWAP_I32:
      LoadMnemonic = PPC::LWARX;
      StoreMnemonic = PPC::STWCX;
      break;
    case PPC::ATOMIC_CMP_SWAP_I64:
      LoadMnemonic = PPC::LDARX;
      StoreMnemonic = PPC::STDCX;
      break;
    }
    MachineRegisterInfo &RegInfo = F->getRegInfo();
    Register dest = MI.getOperand(0).getReg();
    Register ptrA = MI.getOperand(1).getReg();
    Register ptrB = MI.getOperand(2).getReg();
    Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
    Register oldval = MI.getOperand(3).getReg();
    Register newval = MI.getOperand(4).getReg();
    DebugLoc dl = MI.getDebugLoc();

    MachineBasicBlock *loop1MBB = F->CreateMachineBasicBlock(LLVM_BB);
    MachineBasicBlock *loop2MBB = F->CreateMachineBasicBlock(LLVM_BB);
    MachineBasicBlock *exitMBB = F->CreateMachineBasicBlock(LLVM_BB);
    F->insert(It, loop1MBB);
    F->insert(It, loop2MBB);
    F->insert(It, exitMBB);
    exitMBB->splice(exitMBB->begin(), BB,
                    std::next(MachineBasicBlock::iterator(MI)), BB->end());
    exitMBB->transferSuccessorsAndUpdatePHIs(BB);

    //  thisMBB:
    //   ...
    //   fallthrough --> loopMBB
    BB->addSuccessor(loop1MBB);

    // loop1MBB:
    //   l[bhwd]arx dest, ptr
    //   cmp[wd] dest, oldval
    //   bne- exitBB
    // loop2MBB:
    //   st[bhwd]cx. newval, ptr
    //   bne- loopMBB
    //   b exitBB
    // exitBB:
    BB = loop1MBB;
    BuildMI(BB, dl, TII->get(LoadMnemonic), dest).addReg(ptrA).addReg(ptrB);
    BuildMI(BB, dl, TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
        .addReg(dest)
        .addReg(oldval);
    BuildMI(BB, dl, TII->get(PPC::BCC))
        .addImm(PPC::PRED_NE_MINUS)
        .addReg(CrReg)
        .addMBB(exitMBB);
    BB->addSuccessor(loop2MBB);
    BB->addSuccessor(exitMBB);

    BB = loop2MBB;
    BuildMI(BB, dl, TII->get(StoreMnemonic))
        .addReg(newval)
        .addReg(ptrA)
        .addReg(ptrB);
    BuildMI(BB, dl, TII->get(PPC::BCC))
        .addImm(PPC::PRED_NE_MINUS)
        .addReg(PPC::CR0)
        .addMBB(loop1MBB);
    BuildMI(BB, dl, TII->get(PPC::B)).addMBB(exitMBB);
    BB->addSuccessor(loop1MBB);
    BB->addSuccessor(exitMBB);

    //  exitMBB:
    //   ...
    BB = exitMBB;
  } else if (MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
             MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
    // We must use 64-bit registers for addresses when targeting 64-bit,
    // since we're actually doing arithmetic on them.  Other registers
    // can be 32-bit.
    bool is64bit = Subtarget.isPPC64();
    bool isLittleEndian = Subtarget.isLittleEndian();
    bool is8bit = MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;

    Register dest = MI.getOperand(0).getReg();
    Register ptrA = MI.getOperand(1).getReg();
    Register ptrB = MI.getOperand(2).getReg();
    Register oldval = MI.getOperand(3).getReg();
    Register newval = MI.getOperand(4).getReg();
    DebugLoc dl = MI.getDebugLoc();

    MachineBasicBlock *loop1MBB = F->CreateMachineBasicBlock(LLVM_BB);
    MachineBasicBlock *loop2MBB = F->CreateMachineBasicBlock(LLVM_BB);
    MachineBasicBlock *exitMBB = F->CreateMachineBasicBlock(LLVM_BB);
    F->insert(It, loop1MBB);
    F->insert(It, loop2MBB);
    F->insert(It, exitMBB);
    exitMBB->splice(exitMBB->begin(), BB,
                    std::next(MachineBasicBlock::iterator(MI)), BB->end());
    exitMBB->transferSuccessorsAndUpdatePHIs(BB);

    MachineRegisterInfo &RegInfo = F->getRegInfo();
    const TargetRegisterClass *RC =
        is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
    const TargetRegisterClass *GPRC = &PPC::GPRCRegClass;

    Register PtrReg = RegInfo.createVirtualRegister(RC);
    Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
    Register ShiftReg =
        isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
    Register NewVal2Reg = RegInfo.createVirtualRegister(GPRC);
    Register NewVal3Reg = RegInfo.createVirtualRegister(GPRC);
    Register OldVal2Reg = RegInfo.createVirtualRegister(GPRC);
    Register OldVal3Reg = RegInfo.createVirtualRegister(GPRC);
    Register MaskReg = RegInfo.createVirtualRegister(GPRC);
    Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
    Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
    Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
    Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
    Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
    Register Ptr1Reg;
    Register TmpReg = RegInfo.createVirtualRegister(GPRC);
    Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
    Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
    //  thisMBB:
    //   ...
    //   fallthrough --> loopMBB
    BB->addSuccessor(loop1MBB);

    // The 4-byte load must be aligned, while a char or short may be
    // anywhere in the word.  Hence all this nasty bookkeeping code.
    //   add ptr1, ptrA, ptrB [copy if ptrA==0]
    //   rlwinm shift1, ptr1, 3, 27, 28 [3, 27, 27]
    //   xori shift, shift1, 24 [16]
    //   rlwinm ptr, ptr1, 0, 0, 29
    //   slw newval2, newval, shift
    //   slw oldval2, oldval,shift
    //   li mask2, 255 [li mask3, 0; ori mask2, mask3, 65535]
    //   slw mask, mask2, shift
    //   and newval3, newval2, mask
    //   and oldval3, oldval2, mask
    // loop1MBB:
    //   lwarx tmpDest, ptr
    //   and tmp, tmpDest, mask
    //   cmpw tmp, oldval3
    //   bne- exitBB
    // loop2MBB:
    //   andc tmp2, tmpDest, mask
    //   or tmp4, tmp2, newval3
    //   stwcx. tmp4, ptr
    //   bne- loop1MBB
    //   b exitBB
    // exitBB:
    //   srw dest, tmpDest, shift
    if (ptrA != ZeroReg) {
      Ptr1Reg = RegInfo.createVirtualRegister(RC);
      BuildMI(BB, dl, TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
          .addReg(ptrA)
          .addReg(ptrB);
    } else {
      Ptr1Reg = ptrB;
    }

    // We need use 32-bit subregister to avoid mismatch register class in 64-bit
    // mode.
    BuildMI(BB, dl, TII->get(PPC::RLWINM), Shift1Reg)
        .addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
        .addImm(3)
        .addImm(27)
        .addImm(is8bit ? 28 : 27);
    if (!isLittleEndian)
      BuildMI(BB, dl, TII->get(PPC::XORI), ShiftReg)
          .addReg(Shift1Reg)
          .addImm(is8bit ? 24 : 16);
    if (is64bit)
      BuildMI(BB, dl, TII->get(PPC::RLDICR), PtrReg)
          .addReg(Ptr1Reg)
          .addImm(0)
          .addImm(61);
    else
      BuildMI(BB, dl, TII->get(PPC::RLWINM), PtrReg)
          .addReg(Ptr1Reg)
          .addImm(0)
          .addImm(0)
          .addImm(29);
    BuildMI(BB, dl, TII->get(PPC::SLW), NewVal2Reg)
        .addReg(newval)
        .addReg(ShiftReg);
    BuildMI(BB, dl, TII->get(PPC::SLW), OldVal2Reg)
        .addReg(oldval)
        .addReg(ShiftReg);
    if (is8bit)
      BuildMI(BB, dl, TII->get(PPC::LI), Mask2Reg).addImm(255);
    else {
      BuildMI(BB, dl, TII->get(PPC::LI), Mask3Reg).addImm(0);
      BuildMI(BB, dl, TII->get(PPC::ORI), Mask2Reg)
          .addReg(Mask3Reg)
          .addImm(65535);
    }
    BuildMI(BB, dl, TII->get(PPC::SLW), MaskReg)
        .addReg(Mask2Reg)
        .addReg(ShiftReg);
    BuildMI(BB, dl, TII->get(PPC::AND), NewVal3Reg)
        .addReg(NewVal2Reg)
        .addReg(MaskReg);
    BuildMI(BB, dl, TII->get(PPC::AND), OldVal3Reg)
        .addReg(OldVal2Reg)
        .addReg(MaskReg);

    BB = loop1MBB;
    BuildMI(BB, dl, TII->get(PPC::LWARX), TmpDestReg)
        .addReg(ZeroReg)
        .addReg(PtrReg);
    BuildMI(BB, dl, TII->get(PPC::AND), TmpReg)
        .addReg(TmpDestReg)
        .addReg(MaskReg);
    BuildMI(BB, dl, TII->get(PPC::CMPW), CrReg)
        .addReg(TmpReg)
        .addReg(OldVal3Reg);
    BuildMI(BB, dl, TII->get(PPC::BCC))
        .addImm(PPC::PRED_NE)
        .addReg(CrReg)
        .addMBB(exitMBB);
    BB->addSuccessor(loop2MBB);
    BB->addSuccessor(exitMBB);

    BB = loop2MBB;
    BuildMI(BB, dl, TII->get(PPC::ANDC), Tmp2Reg)
        .addReg(TmpDestReg)
        .addReg(MaskReg);
    BuildMI(BB, dl, TII->get(PPC::OR), Tmp4Reg)
        .addReg(Tmp2Reg)
        .addReg(NewVal3Reg);
    BuildMI(BB, dl, TII->get(PPC::STWCX))
        .addReg(Tmp4Reg)
        .addReg(ZeroReg)
        .addReg(PtrReg);
    BuildMI(BB, dl, TII->get(PPC::BCC))
        .addImm(PPC::PRED_NE)
        .addReg(PPC::CR0)
        .addMBB(loop1MBB);
    BuildMI(BB, dl, TII->get(PPC::B)).addMBB(exitMBB);
    BB->addSuccessor(loop1MBB);
    BB->addSuccessor(exitMBB);

    //  exitMBB:
    //   ...
    BB = exitMBB;
    BuildMI(*BB, BB->begin(), dl, TII->get(PPC::SRW), dest)
        .addReg(TmpReg)
        .addReg(ShiftReg);
  } else if (MI.getOpcode() == PPC::FADDrtz) {
    // This pseudo performs an FADD with rounding mode temporarily forced
    // to round-to-zero.  We emit this via custom inserter since the FPSCR
    // is not modeled at the SelectionDAG level.
    Register Dest = MI.getOperand(0).getReg();
    Register Src1 = MI.getOperand(1).getReg();
    Register Src2 = MI.getOperand(2).getReg();
    DebugLoc dl = MI.getDebugLoc();

    MachineRegisterInfo &RegInfo = F->getRegInfo();
    Register MFFSReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);

    // Save FPSCR value.
    BuildMI(*BB, MI, dl, TII->get(PPC::MFFS), MFFSReg);

    // Set rounding mode to round-to-zero.
    BuildMI(*BB, MI, dl, TII->get(PPC::MTFSB1))
        .addImm(31)
        .addReg(PPC::RM, RegState::ImplicitDefine);

    BuildMI(*BB, MI, dl, TII->get(PPC::MTFSB0))
        .addImm(30)
        .addReg(PPC::RM, RegState::ImplicitDefine);

    // Perform addition.
    auto MIB = BuildMI(*BB, MI, dl, TII->get(PPC::FADD), Dest)
                   .addReg(Src1)
                   .addReg(Src2);
    if (MI.getFlag(MachineInstr::NoFPExcept))
      MIB.setMIFlag(MachineInstr::NoFPExcept);

    // Restore FPSCR value.
    BuildMI(*BB, MI, dl, TII->get(PPC::MTFSFb)).addImm(1).addReg(MFFSReg);
  } else if (MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
             MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
             MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
             MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
    unsigned Opcode = (MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
                       MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
                          ? PPC::ANDI8_rec
                          : PPC::ANDI_rec;
    bool IsEQ = (MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
                 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);

    MachineRegisterInfo &RegInfo = F->getRegInfo();
    Register Dest = RegInfo.createVirtualRegister(
        Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);

    DebugLoc Dl = MI.getDebugLoc();
    BuildMI(*BB, MI, Dl, TII->get(Opcode), Dest)
        .addReg(MI.getOperand(1).getReg())
        .addImm(1);
    BuildMI(*BB, MI, Dl, TII->get(TargetOpcode::COPY),
            MI.getOperand(0).getReg())
        .addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
  } else if (MI.getOpcode() == PPC::TCHECK_RET) {
    DebugLoc Dl = MI.getDebugLoc();
    MachineRegisterInfo &RegInfo = F->getRegInfo();
    Register CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
    BuildMI(*BB, MI, Dl, TII->get(PPC::TCHECK), CRReg);
    BuildMI(*BB, MI, Dl, TII->get(TargetOpcode::COPY),
            MI.getOperand(0).getReg())
        .addReg(CRReg);
  } else if (MI.getOpcode() == PPC::TBEGIN_RET) {
    DebugLoc Dl = MI.getDebugLoc();
    unsigned Imm = MI.getOperand(1).getImm();
    BuildMI(*BB, MI, Dl, TII->get(PPC::TBEGIN)).addImm(Imm);
    BuildMI(*BB, MI, Dl, TII->get(TargetOpcode::COPY),
            MI.getOperand(0).getReg())
        .addReg(PPC::CR0EQ);
  } else if (MI.getOpcode() == PPC::SETRNDi) {
    DebugLoc dl = MI.getDebugLoc();
    Register OldFPSCRReg = MI.getOperand(0).getReg();

    // Save FPSCR value.
    if (MRI.use_empty(OldFPSCRReg))
      BuildMI(*BB, MI, dl, TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
    else
      BuildMI(*BB, MI, dl, TII->get(PPC::MFFS), OldFPSCRReg);

    // The floating point rounding mode is in the bits 62:63 of FPCSR, and has
    // the following settings:
    //   00 Round to nearest
    //   01 Round to 0
    //   10 Round to +inf
    //   11 Round to -inf

    // When the operand is immediate, using the two least significant bits of
    // the immediate to set the bits 62:63 of FPSCR.
    unsigned Mode = MI.getOperand(1).getImm();
    BuildMI(*BB, MI, dl, TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
        .addImm(31)
        .addReg(PPC::RM, RegState::ImplicitDefine);

    BuildMI(*BB, MI, dl, TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
        .addImm(30)
        .addReg(PPC::RM, RegState::ImplicitDefine);
  } else if (MI.getOpcode() == PPC::SETRND) {
    DebugLoc dl = MI.getDebugLoc();

    // Copy register from F8RCRegClass::SrcReg to G8RCRegClass::DestReg
    // or copy register from G8RCRegClass::SrcReg to F8RCRegClass::DestReg.
    // If the target doesn't have DirectMove, we should use stack to do the
    // conversion, because the target doesn't have the instructions like mtvsrd
    // or mfvsrd to do this conversion directly.
    auto copyRegFromG8RCOrF8RC = [&] (unsigned DestReg, unsigned SrcReg) {
      if (Subtarget.hasDirectMove()) {
        BuildMI(*BB, MI, dl, TII->get(TargetOpcode::COPY), DestReg)
          .addReg(SrcReg);
      } else {
        // Use stack to do the register copy.
        unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
        MachineRegisterInfo &RegInfo = F->getRegInfo();
        const TargetRegisterClass *RC = RegInfo.getRegClass(SrcReg);
        if (RC == &PPC::F8RCRegClass) {
          // Copy register from F8RCRegClass to G8RCRegclass.
          assert((RegInfo.getRegClass(DestReg) == &PPC::G8RCRegClass) &&
                 "Unsupported RegClass.");

          StoreOp = PPC::STFD;
          LoadOp = PPC::LD;
        } else {
          // Copy register from G8RCRegClass to F8RCRegclass.
          assert((RegInfo.getRegClass(SrcReg) == &PPC::G8RCRegClass) &&
                 (RegInfo.getRegClass(DestReg) == &PPC::F8RCRegClass) &&
                 "Unsupported RegClass.");
        }

        MachineFrameInfo &MFI = F->getFrameInfo();
        int FrameIdx = MFI.CreateStackObject(8, Align(8), false);

        MachineMemOperand *MMOStore = F->getMachineMemOperand(
            MachinePointerInfo::getFixedStack(*F, FrameIdx, 0),
            MachineMemOperand::MOStore, MFI.getObjectSize(FrameIdx),
            MFI.getObjectAlign(FrameIdx));

        // Store the SrcReg into the stack.
        BuildMI(*BB, MI, dl, TII->get(StoreOp))
          .addReg(SrcReg)
          .addImm(0)
          .addFrameIndex(FrameIdx)
          .addMemOperand(MMOStore);

        MachineMemOperand *MMOLoad = F->getMachineMemOperand(
            MachinePointerInfo::getFixedStack(*F, FrameIdx, 0),
            MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIdx),
            MFI.getObjectAlign(FrameIdx));

        // Load from the stack where SrcReg is stored, and save to DestReg,
        // so we have done the RegClass conversion from RegClass::SrcReg to
        // RegClass::DestReg.
        BuildMI(*BB, MI, dl, TII->get(LoadOp), DestReg)
          .addImm(0)
          .addFrameIndex(FrameIdx)
          .addMemOperand(MMOLoad);
      }
    };

    Register OldFPSCRReg = MI.getOperand(0).getReg();

    // Save FPSCR value.
    BuildMI(*BB, MI, dl, TII->get(PPC::MFFS), OldFPSCRReg);

    // When the operand is gprc register, use two least significant bits of the
    // register and mtfsf instruction to set the bits 62:63 of FPSCR.
    //
    // copy OldFPSCRTmpReg, OldFPSCRReg
    // (INSERT_SUBREG ExtSrcReg, (IMPLICIT_DEF ImDefReg), SrcOp, 1)
    // rldimi NewFPSCRTmpReg, ExtSrcReg, OldFPSCRReg, 0, 62
    // copy NewFPSCRReg, NewFPSCRTmpReg
    // mtfsf 255, NewFPSCRReg
    MachineOperand SrcOp = MI.getOperand(1);
    MachineRegisterInfo &RegInfo = F->getRegInfo();
    Register OldFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);

    copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);

    Register ImDefReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
    Register ExtSrcReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);

    // The first operand of INSERT_SUBREG should be a register which has
    // subregisters, we only care about its RegClass, so we should use an
    // IMPLICIT_DEF register.
    BuildMI(*BB, MI, dl, TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
    BuildMI(*BB, MI, dl, TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
      .addReg(ImDefReg)
      .add(SrcOp)
      .addImm(1);

    Register NewFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
    BuildMI(*BB, MI, dl, TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
      .addReg(OldFPSCRTmpReg)
      .addReg(ExtSrcReg)
      .addImm(0)
      .addImm(62);

    Register NewFPSCRReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
    copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);

    // The mask 255 means that put the 32:63 bits of NewFPSCRReg to the 32:63
    // bits of FPSCR.
    BuildMI(*BB, MI, dl, TII->get(PPC::MTFSF))
      .addImm(255)
      .addReg(NewFPSCRReg)
      .addImm(0)
      .addImm(0);
  } else if (MI.getOpcode() == PPC::SETFLM) {
    DebugLoc Dl = MI.getDebugLoc();

    // Result of setflm is previous FPSCR content, so we need to save it first.
    Register OldFPSCRReg = MI.getOperand(0).getReg();
    if (MRI.use_empty(OldFPSCRReg))
      BuildMI(*BB, MI, Dl, TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
    else
      BuildMI(*BB, MI, Dl, TII->get(PPC::MFFS), OldFPSCRReg);

    // Put bits in 32:63 to FPSCR.
    Register NewFPSCRReg = MI.getOperand(1).getReg();
    BuildMI(*BB, MI, Dl, TII->get(PPC::MTFSF))
        .addImm(255)
        .addReg(NewFPSCRReg)
        .addImm(0)
        .addImm(0);
  } else if (MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
             MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
    return emitProbedAlloca(MI, BB);
  } else if (MI.getOpcode() == PPC::SPLIT_QUADWORD) {
    DebugLoc DL = MI.getDebugLoc();
    Register Src = MI.getOperand(2).getReg();
    Register Lo = MI.getOperand(0).getReg();
    Register Hi = MI.getOperand(1).getReg();
    BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY))
        .addDef(Lo)
        .addUse(Src, 0, PPC::sub_gp8_x1);
    BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY))
        .addDef(Hi)
        .addUse(Src, 0, PPC::sub_gp8_x0);
  } else if (MI.getOpcode() == PPC::LQX_PSEUDO ||
             MI.getOpcode() == PPC::STQX_PSEUDO) {
    DebugLoc DL = MI.getDebugLoc();
    // Ptr is used as the ptr_rc_no_r0 part
    // of LQ/STQ's memory operand and adding result of RA and RB,
    // so it has to be g8rc_and_g8rc_nox0.
    Register Ptr =
        F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
    Register Val = MI.getOperand(0).getReg();
    Register RA = MI.getOperand(1).getReg();
    Register RB = MI.getOperand(2).getReg();
    BuildMI(*BB, MI, DL, TII->get(PPC::ADD8), Ptr).addReg(RA).addReg(RB);
    BuildMI(*BB, MI, DL,
            MI.getOpcode() == PPC::LQX_PSEUDO ? TII->get(PPC::LQ)
                                              : TII->get(PPC::STQ))
        .addReg(Val, MI.getOpcode() == PPC::LQX_PSEUDO ? RegState::Define : 0)
        .addImm(0)
        .addReg(Ptr);
  } else if (MI.getOpcode() == PPC::LWAT_PSEUDO ||
             MI.getOpcode() == PPC::LDAT_PSEUDO) {
    DebugLoc DL = MI.getDebugLoc();
    Register DstReg = MI.getOperand(0).getReg();
    Register PtrReg = MI.getOperand(1).getReg();
    Register ValReg = MI.getOperand(2).getReg();
    unsigned FC = MI.getOperand(3).getImm();
    bool IsLwat = MI.getOpcode() == PPC::LWAT_PSEUDO;
    Register Val64 = MRI.createVirtualRegister(&PPC::G8RCRegClass);
    if (IsLwat)
      BuildMI(*BB, MI, DL, TII->get(TargetOpcode::SUBREG_TO_REG), Val64)
          .addImm(0)
          .addReg(ValReg)
          .addImm(PPC::sub_32);
    else
      Val64 = ValReg;

    Register G8rPair = MRI.createVirtualRegister(&PPC::G8pRCRegClass);
    Register UndefG8r = MRI.createVirtualRegister(&PPC::G8RCRegClass);
    BuildMI(*BB, MI, DL, TII->get(TargetOpcode::IMPLICIT_DEF), UndefG8r);
    BuildMI(*BB, MI, DL, TII->get(PPC::REG_SEQUENCE), G8rPair)
        .addReg(UndefG8r)
        .addImm(PPC::sub_gp8_x0)
        .addReg(Val64)
        .addImm(PPC::sub_gp8_x1);

    Register PairResult = MRI.createVirtualRegister(&PPC::G8pRCRegClass);
    BuildMI(*BB, MI, DL, TII->get(IsLwat ? PPC::LWAT : PPC::LDAT), PairResult)
        .addReg(G8rPair)
        .addReg(PtrReg)
        .addImm(FC);
    Register Result64 = MRI.createVirtualRegister(&PPC::G8RCRegClass);
    BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), Result64)
        .addReg(PairResult, 0, PPC::sub_gp8_x0);
    if (IsLwat)
      BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), DstReg)
          .addReg(Result64, 0, PPC::sub_32);
    else
      BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), DstReg)
          .addReg(Result64);
  } else {
    llvm_unreachable("Unexpected instr type to insert");
  }

  MI.eraseFromParent(); // The pseudo instruction is gone now.
  return BB;
}

//===----------------------------------------------------------------------===//
// Target Optimization Hooks
//===----------------------------------------------------------------------===//

static int getEstimateRefinementSteps(EVT VT, const PPCSubtarget &Subtarget) {
  // For the estimates, convergence is quadratic, so we essentially double the
  // number of digits correct after every iteration. For both FRE and FRSQRTE,
  // the minimum architected relative accuracy is 2^-5. When hasRecipPrec(),
  // this is 2^-14. IEEE float has 23 digits and double has 52 digits.
  int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
  if (VT.getScalarType() == MVT::f64)
    RefinementSteps++;
  return RefinementSteps;
}

SDValue PPCTargetLowering::getSqrtInputTest(SDValue Op, SelectionDAG &DAG,
                                            const DenormalMode &Mode) const {
  // We only have VSX Vector Test for software Square Root.
  EVT VT = Op.getValueType();
  if (!isTypeLegal(MVT::i1) ||
      (VT != MVT::f64 &&
       ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
    return TargetLowering::getSqrtInputTest(Op, DAG, Mode);

  SDLoc DL(Op);
  // The output register of FTSQRT is CR field.
  SDValue FTSQRT = DAG.getNode(PPCISD::FTSQRT, DL, MVT::i32, Op);
  // ftsqrt BF,FRB
  // Let e_b be the unbiased exponent of the double-precision
  // floating-point operand in register FRB.
  // fe_flag is set to 1 if either of the following conditions occurs.
  //   - The double-precision floating-point operand in register FRB is a zero,
  //     a NaN, or an infinity, or a negative value.
  //   - e_b is less than or equal to -970.
  // Otherwise fe_flag is set to 0.
  // Both VSX and non-VSX versions would set EQ bit in the CR if the number is
  // not eligible for iteration. (zero/negative/infinity/nan or unbiased
  // exponent is less than -970)
  SDValue SRIdxVal = DAG.getTargetConstant(PPC::sub_eq, DL, MVT::i32);
  return SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, MVT::i1,
                                    FTSQRT, SRIdxVal),
                 0);
}

SDValue
PPCTargetLowering::getSqrtResultForDenormInput(SDValue Op,
                                               SelectionDAG &DAG) const {
  // We only have VSX Vector Square Root.
  EVT VT = Op.getValueType();
  if (VT != MVT::f64 &&
      ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
    return TargetLowering::getSqrtResultForDenormInput(Op, DAG);

  return DAG.getNode(PPCISD::FSQRT, SDLoc(Op), VT, Op);
}

SDValue PPCTargetLowering::getSqrtEstimate(SDValue Operand, SelectionDAG &DAG,
                                           int Enabled, int &RefinementSteps,
                                           bool &UseOneConstNR,
                                           bool Reciprocal) const {
  EVT VT = Operand.getValueType();
  if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
      (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
      (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
      (VT == MVT::v2f64 && Subtarget.hasVSX())) {
    if (RefinementSteps == ReciprocalEstimate::Unspecified)
      RefinementSteps = getEstimateRefinementSteps(VT, Subtarget);

    // The Newton-Raphson computation with a single constant does not provide
    // enough accuracy on some CPUs.
    UseOneConstNR = !Subtarget.needsTwoConstNR();
    return DAG.getNode(PPCISD::FRSQRTE, SDLoc(Operand), VT, Operand);
  }
  return SDValue();
}

SDValue PPCTargetLowering::getRecipEstimate(SDValue Operand, SelectionDAG &DAG,
                                            int Enabled,
                                            int &RefinementSteps) const {
  EVT VT = Operand.getValueType();
  if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
      (VT == MVT::f64 && Subtarget.hasFRE()) ||
      (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
      (VT == MVT::v2f64 && Subtarget.hasVSX())) {
    if (RefinementSteps == ReciprocalEstimate::Unspecified)
      RefinementSteps = getEstimateRefinementSteps(VT, Subtarget);
    return DAG.getNode(PPCISD::FRE, SDLoc(Operand), VT, Operand);
  }
  return SDValue();
}

unsigned PPCTargetLowering::combineRepeatedFPDivisors() const {
  // Note: This functionality is used only when arcp is enabled, and
  // on cores with reciprocal estimates (which are used when arcp is
  // enabled for division), this functionality is redundant with the default
  // combiner logic (once the division -> reciprocal/multiply transformation
  // has taken place). As a result, this matters more for older cores than for
  // newer ones.

  // Combine multiple FDIVs with the same divisor into multiple FMULs by the
  // reciprocal if there are two or more FDIVs (for embedded cores with only
  // one FP pipeline) for three or more FDIVs (for generic OOO cores).
  switch (Subtarget.getCPUDirective()) {
  default:
    return 3;
  case PPC::DIR_440:
  case PPC::DIR_A2:
  case PPC::DIR_E500:
  case PPC::DIR_E500mc:
  case PPC::DIR_E5500:
    return 2;
  }
}

// isConsecutiveLSLoc needs to work even if all adds have not yet been
// collapsed, and so we need to look through chains of them.
static void getBaseWithConstantOffset(SDValue Loc, SDValue &Base,
                                     int64_t& Offset, SelectionDAG &DAG) {
  if (DAG.isBaseWithConstantOffset(Loc)) {
    Base = Loc.getOperand(0);
    Offset += cast<ConstantSDNode>(Loc.getOperand(1))->getSExtValue();

    // The base might itself be a base plus an offset, and if so, accumulate
    // that as well.
    getBaseWithConstantOffset(Loc.getOperand(0), Base, Offset, DAG);
  }
}

static bool isConsecutiveLSLoc(SDValue Loc, EVT VT, LSBaseSDNode *Base,
                            unsigned Bytes, int Dist,
                            SelectionDAG &DAG) {
  if (VT.getSizeInBits() / 8 != Bytes)
    return false;

  SDValue BaseLoc = Base->getBasePtr();
  if (Loc.getOpcode() == ISD::FrameIndex) {
    if (BaseLoc.getOpcode() != ISD::FrameIndex)
      return false;
    const MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
    int FI  = cast<FrameIndexSDNode>(Loc)->getIndex();
    int BFI = cast<FrameIndexSDNode>(BaseLoc)->getIndex();
    int FS  = MFI.getObjectSize(FI);
    int BFS = MFI.getObjectSize(BFI);
    if (FS != BFS || FS != (int)Bytes) return false;
    return MFI.getObjectOffset(FI) == (MFI.getObjectOffset(BFI) + Dist*Bytes);
  }

  SDValue Base1 = Loc, Base2 = BaseLoc;
  int64_t Offset1 = 0, Offset2 = 0;
  getBaseWithConstantOffset(Loc, Base1, Offset1, DAG);
  getBaseWithConstantOffset(BaseLoc, Base2, Offset2, DAG);
  if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
    return true;

  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  const GlobalValue *GV1 = nullptr;
  const GlobalValue *GV2 = nullptr;
  Offset1 = 0;
  Offset2 = 0;
  bool isGA1 = TLI.isGAPlusOffset(Loc.getNode(), GV1, Offset1);
  bool isGA2 = TLI.isGAPlusOffset(BaseLoc.getNode(), GV2, Offset2);
  if (isGA1 && isGA2 && GV1 == GV2)
    return Offset1 == (Offset2 + Dist*Bytes);
  return false;
}

// Like SelectionDAG::isConsecutiveLoad, but also works for stores, and does
// not enforce equality of the chain operands.
static bool isConsecutiveLS(SDNode *N, LSBaseSDNode *Base,
                            unsigned Bytes, int Dist,
                            SelectionDAG &DAG) {
  if (LSBaseSDNode *LS = dyn_cast<LSBaseSDNode>(N)) {
    EVT VT = LS->getMemoryVT();
    SDValue Loc = LS->getBasePtr();
    return isConsecutiveLSLoc(Loc, VT, Base, Bytes, Dist, DAG);
  }

  if (N->getOpcode() == ISD::INTRINSIC_W_CHAIN) {
    EVT VT;
    switch (N->getConstantOperandVal(1)) {
    default: return false;
    case Intrinsic::ppc_altivec_lvx:
    case Intrinsic::ppc_altivec_lvxl:
    case Intrinsic::ppc_vsx_lxvw4x:
    case Intrinsic::ppc_vsx_lxvw4x_be:
      VT = MVT::v4i32;
      break;
    case Intrinsic::ppc_vsx_lxvd2x:
    case Intrinsic::ppc_vsx_lxvd2x_be:
      VT = MVT::v2f64;
      break;
    case Intrinsic::ppc_altivec_lvebx:
      VT = MVT::i8;
      break;
    case Intrinsic::ppc_altivec_lvehx:
      VT = MVT::i16;
      break;
    case Intrinsic::ppc_altivec_lvewx:
      VT = MVT::i32;
      break;
    }

    return isConsecutiveLSLoc(N->getOperand(2), VT, Base, Bytes, Dist, DAG);
  }

  if (N->getOpcode() == ISD::INTRINSIC_VOID) {
    EVT VT;
    switch (N->getConstantOperandVal(1)) {
    default: return false;
    case Intrinsic::ppc_altivec_stvx:
    case Intrinsic::ppc_altivec_stvxl:
    case Intrinsic::ppc_vsx_stxvw4x:
      VT = MVT::v4i32;
      break;
    case Intrinsic::ppc_vsx_stxvd2x:
      VT = MVT::v2f64;
      break;
    case Intrinsic::ppc_vsx_stxvw4x_be:
      VT = MVT::v4i32;
      break;
    case Intrinsic::ppc_vsx_stxvd2x_be:
      VT = MVT::v2f64;
      break;
    case Intrinsic::ppc_altivec_stvebx:
      VT = MVT::i8;
      break;
    case Intrinsic::ppc_altivec_stvehx:
      VT = MVT::i16;
      break;
    case Intrinsic::ppc_altivec_stvewx:
      VT = MVT::i32;
      break;
    }

    return isConsecutiveLSLoc(N->getOperand(3), VT, Base, Bytes, Dist, DAG);
  }

  return false;
}

// Return true is there is a nearyby consecutive load to the one provided
// (regardless of alignment). We search up and down the chain, looking though
// token factors and other loads (but nothing else). As a result, a true result
// indicates that it is safe to create a new consecutive load adjacent to the
// load provided.
static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG) {
  SDValue Chain = LD->getChain();
  EVT VT = LD->getMemoryVT();

  SmallPtrSet<SDNode *, 16> LoadRoots;
  SmallVector<SDNode *, 8> Queue(1, Chain.getNode());
  SmallPtrSet<SDNode *, 16> Visited;

  // First, search up the chain, branching to follow all token-factor operands.
  // If we find a consecutive load, then we're done, otherwise, record all
  // nodes just above the top-level loads and token factors.
  while (!Queue.empty()) {
    SDNode *ChainNext = Queue.pop_back_val();
    if (!Visited.insert(ChainNext).second)
      continue;

    if (MemSDNode *ChainLD = dyn_cast<MemSDNode>(ChainNext)) {
      if (isConsecutiveLS(ChainLD, LD, VT.getStoreSize(), 1, DAG))
        return true;

      if (!Visited.count(ChainLD->getChain().getNode()))
        Queue.push_back(ChainLD->getChain().getNode());
    } else if (ChainNext->getOpcode() == ISD::TokenFactor) {
      for (const SDUse &O : ChainNext->ops())
        if (!Visited.count(O.getNode()))
          Queue.push_back(O.getNode());
    } else
      LoadRoots.insert(ChainNext);
  }

  // Second, search down the chain, starting from the top-level nodes recorded
  // in the first phase. These top-level nodes are the nodes just above all
  // loads and token factors. Starting with their uses, recursively look though
  // all loads (just the chain uses) and token factors to find a consecutive
  // load.
  Visited.clear();
  Queue.clear();

  for (SDNode *I : LoadRoots) {
    Queue.push_back(I);

    while (!Queue.empty()) {
      SDNode *LoadRoot = Queue.pop_back_val();
      if (!Visited.insert(LoadRoot).second)
        continue;

      if (MemSDNode *ChainLD = dyn_cast<MemSDNode>(LoadRoot))
        if (isConsecutiveLS(ChainLD, LD, VT.getStoreSize(), 1, DAG))
          return true;

      for (SDNode *U : LoadRoot->users())
        if (((isa<MemSDNode>(U) &&
              cast<MemSDNode>(U)->getChain().getNode() == LoadRoot) ||
             U->getOpcode() == ISD::TokenFactor) &&
            !Visited.count(U))
          Queue.push_back(U);
    }
  }

  return false;
}

/// This function is called when we have proved that a SETCC node can be replaced
/// by subtraction (and other supporting instructions) so that the result of
/// comparison is kept in a GPR instead of CR. This function is purely for
/// codegen purposes and has some flags to guide the codegen process.
static SDValue generateEquivalentSub(SDNode *N, int Size, bool Complement,
                                     bool Swap, SDLoc &DL, SelectionDAG &DAG) {
  assert(N->getOpcode() == ISD::SETCC && "ISD::SETCC Expected.");

  // Zero extend the operands to the largest legal integer. Originally, they
  // must be of a strictly smaller size.
  auto Op0 = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, N->getOperand(0),
                         DAG.getConstant(Size, DL, MVT::i32));
  auto Op1 = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, N->getOperand(1),
                         DAG.getConstant(Size, DL, MVT::i32));

  // Swap if needed. Depends on the condition code.
  if (Swap)
    std::swap(Op0, Op1);

  // Subtract extended integers.
  auto SubNode = DAG.getNode(ISD::SUB, DL, MVT::i64, Op0, Op1);

  // Move the sign bit to the least significant position and zero out the rest.
  // Now the least significant bit carries the result of original comparison.
  auto Shifted = DAG.getNode(ISD::SRL, DL, MVT::i64, SubNode,
                             DAG.getConstant(Size - 1, DL, MVT::i32));
  auto Final = Shifted;

  // Complement the result if needed. Based on the condition code.
  if (Complement)
    Final = DAG.getNode(ISD::XOR, DL, MVT::i64, Shifted,
                        DAG.getConstant(1, DL, MVT::i64));

  return DAG.getNode(ISD::TRUNCATE, DL, MVT::i1, Final);
}

SDValue PPCTargetLowering::ConvertSETCCToSubtract(SDNode *N,
                                                  DAGCombinerInfo &DCI) const {
  assert(N->getOpcode() == ISD::SETCC && "ISD::SETCC Expected.");

  SelectionDAG &DAG = DCI.DAG;
  SDLoc DL(N);

  // Size of integers being compared has a critical role in the following
  // analysis, so we prefer to do this when all types are legal.
  if (!DCI.isAfterLegalizeDAG())
    return SDValue();

  // If all users of SETCC extend its value to a legal integer type
  // then we replace SETCC with a subtraction
  for (const SDNode *U : N->users())
    if (U->getOpcode() != ISD::ZERO_EXTEND)
      return SDValue();

  ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
  auto OpSize = N->getOperand(0).getValueSizeInBits();

  unsigned Size = DAG.getDataLayout().getLargestLegalIntTypeSizeInBits();

  if (OpSize < Size) {
    switch (CC) {
    default: break;
    case ISD::SETULT:
      return generateEquivalentSub(N, Size, false, false, DL, DAG);
    case ISD::SETULE:
      return generateEquivalentSub(N, Size, true, true, DL, DAG);
    case ISD::SETUGT:
      return generateEquivalentSub(N, Size, false, true, DL, DAG);
    case ISD::SETUGE:
      return generateEquivalentSub(N, Size, true, false, DL, DAG);
    }
  }

  return SDValue();
}

SDValue PPCTargetLowering::DAGCombineTruncBoolExt(SDNode *N,
                                                  DAGCombinerInfo &DCI) const {
  SelectionDAG &DAG = DCI.DAG;
  SDLoc dl(N);

  assert(Subtarget.useCRBits() && "Expecting to be tracking CR bits");
  // If we're tracking CR bits, we need to be careful that we don't have:
  //   trunc(binary-ops(zext(x), zext(y)))
  // or
  //   trunc(binary-ops(binary-ops(zext(x), zext(y)), ...)
  // such that we're unnecessarily moving things into GPRs when it would be
  // better to keep them in CR bits.

  // Note that trunc here can be an actual i1 trunc, or can be the effective
  // truncation that comes from a setcc or select_cc.
  if (N->getOpcode() == ISD::TRUNCATE &&
      N->getValueType(0) != MVT::i1)
    return SDValue();

  if (N->getOperand(0).getValueType() != MVT::i32 &&
      N->getOperand(0).getValueType() != MVT::i64)
    return SDValue();

  if (N->getOpcode() == ISD::SETCC ||
      N->getOpcode() == ISD::SELECT_CC) {
    // If we're looking at a comparison, then we need to make sure that the
    // high bits (all except for the first) don't matter the result.
    ISD::CondCode CC =
      cast<CondCodeSDNode>(N->getOperand(
        N->getOpcode() == ISD::SETCC ? 2 : 4))->get();
    unsigned OpBits = N->getOperand(0).getValueSizeInBits();

    if (ISD::isSignedIntSetCC(CC)) {
      if (DAG.ComputeNumSignBits(N->getOperand(0)) != OpBits ||
          DAG.ComputeNumSignBits(N->getOperand(1)) != OpBits)
        return SDValue();
    } else if (ISD::isUnsignedIntSetCC(CC)) {
      if (!DAG.MaskedValueIsZero(N->getOperand(0),
                                 APInt::getHighBitsSet(OpBits, OpBits-1)) ||
          !DAG.MaskedValueIsZero(N->getOperand(1),
                                 APInt::getHighBitsSet(OpBits, OpBits-1)))
        return (N->getOpcode() == ISD::SETCC ? ConvertSETCCToSubtract(N, DCI)
                                             : SDValue());
    } else {
      // This is neither a signed nor an unsigned comparison, just make sure
      // that the high bits are equal.
      KnownBits Op1Known = DAG.computeKnownBits(N->getOperand(0));
      KnownBits Op2Known = DAG.computeKnownBits(N->getOperand(1));

      // We don't really care about what is known about the first bit (if
      // anything), so pretend that it is known zero for both to ensure they can
      // be compared as constants.
      Op1Known.Zero.setBit(0); Op1Known.One.clearBit(0);
      Op2Known.Zero.setBit(0); Op2Known.One.clearBit(0);

      if (!Op1Known.isConstant() || !Op2Known.isConstant() ||
          Op1Known.getConstant() != Op2Known.getConstant())
        return SDValue();
    }
  }

  // We now know that the higher-order bits are irrelevant, we just need to
  // make sure that all of the intermediate operations are bit operations, and
  // all inputs are extensions.
  if (N->getOperand(0).getOpcode() != ISD::AND &&
      N->getOperand(0).getOpcode() != ISD::OR  &&
      N->getOperand(0).getOpcode() != ISD::XOR &&
      N->getOperand(0).getOpcode() != ISD::SELECT &&
      N->getOperand(0).getOpcode() != ISD::SELECT_CC &&
      N->getOperand(0).getOpcode() != ISD::TRUNCATE &&
      N->getOperand(0).getOpcode() != ISD::SIGN_EXTEND &&
      N->getOperand(0).getOpcode() != ISD::ZERO_EXTEND &&
      N->getOperand(0).getOpcode() != ISD::ANY_EXTEND)
    return SDValue();

  if ((N->getOpcode() == ISD::SETCC || N->getOpcode() == ISD::SELECT_CC) &&
      N->getOperand(1).getOpcode() != ISD::AND &&
      N->getOperand(1).getOpcode() != ISD::OR  &&
      N->getOperand(1).getOpcode() != ISD::XOR &&
      N->getOperand(1).getOpcode() != ISD::SELECT &&
      N->getOperand(1).getOpcode() != ISD::SELECT_CC &&
      N->getOperand(1).getOpcode() != ISD::TRUNCATE &&
      N->getOperand(1).getOpcode() != ISD::SIGN_EXTEND &&
      N->getOperand(1).getOpcode() != ISD::ZERO_EXTEND &&
      N->getOperand(1).getOpcode() != ISD::ANY_EXTEND)
    return SDValue();

  SmallVector<SDValue, 4> Inputs;
  SmallVector<SDValue, 8> BinOps, PromOps;
  SmallPtrSet<SDNode *, 16> Visited;

  for (unsigned i = 0; i < 2; ++i) {
    if (((N->getOperand(i).getOpcode() == ISD::SIGN_EXTEND ||
          N->getOperand(i).getOpcode() == ISD::ZERO_EXTEND ||
          N->getOperand(i).getOpcode() == ISD::ANY_EXTEND) &&
          N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
        isa<ConstantSDNode>(N->getOperand(i)))
      Inputs.push_back(N->getOperand(i));
    else
      BinOps.push_back(N->getOperand(i));

    if (N->getOpcode() == ISD::TRUNCATE)
      break;
  }

  // Visit all inputs, collect all binary operations (and, or, xor and
  // select) that are all fed by extensions.
  while (!BinOps.empty()) {
    SDValue BinOp = BinOps.pop_back_val();

    if (!Visited.insert(BinOp.getNode()).second)
      continue;

    PromOps.push_back(BinOp);

    for (unsigned i = 0, ie = BinOp.getNumOperands(); i != ie; ++i) {
      // The condition of the select is not promoted.
      if (BinOp.getOpcode() == ISD::SELECT && i == 0)
        continue;
      if (BinOp.getOpcode() == ISD::SELECT_CC && i != 2 && i != 3)
        continue;

      if (((BinOp.getOperand(i).getOpcode() == ISD::SIGN_EXTEND ||
            BinOp.getOperand(i).getOpcode() == ISD::ZERO_EXTEND ||
            BinOp.getOperand(i).getOpcode() == ISD::ANY_EXTEND) &&
           BinOp.getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
          isa<ConstantSDNode>(BinOp.getOperand(i))) {
        Inputs.push_back(BinOp.getOperand(i));
      } else if (BinOp.getOperand(i).getOpcode() == ISD::AND ||
                 BinOp.getOperand(i).getOpcode() == ISD::OR  ||
                 BinOp.getOperand(i).getOpcode() == ISD::XOR ||
                 BinOp.getOperand(i).getOpcode() == ISD::SELECT ||
                 BinOp.getOperand(i).getOpcode() == ISD::SELECT_CC ||
                 BinOp.getOperand(i).getOpcode() == ISD::TRUNCATE ||
                 BinOp.getOperand(i).getOpcode() == ISD::SIGN_EXTEND ||
                 BinOp.getOperand(i).getOpcode() == ISD::ZERO_EXTEND ||
                 BinOp.getOperand(i).getOpcode() == ISD::ANY_EXTEND) {
        BinOps.push_back(BinOp.getOperand(i));
      } else {
        // We have an input that is not an extension or another binary
        // operation; we'll abort this transformation.
        return SDValue();
      }
    }
  }

  // Make sure that this is a self-contained cluster of operations (which
  // is not quite the same thing as saying that everything has only one
  // use).
  for (unsigned i = 0, ie = Inputs.size(); i != ie; ++i) {
    if (isa<ConstantSDNode>(Inputs[i]))
      continue;

    for (const SDNode *User : Inputs[i].getNode()->users()) {
      if (User != N && !Visited.count(User))
        return SDValue();

      // Make sure that we're not going to promote the non-output-value
      // operand(s) or SELECT or SELECT_CC.
      // FIXME: Although we could sometimes handle this, and it does occur in
      // practice that one of the condition inputs to the select is also one of
      // the outputs, we currently can't deal with this.
      if (User->getOpcode() == ISD::SELECT) {
        if (User->getOperand(0) == Inputs[i])
          return SDValue();
      } else if (User->getOpcode() == ISD::SELECT_CC) {
        if (User->getOperand(0) == Inputs[i] ||
            User->getOperand(1) == Inputs[i])
          return SDValue();
      }
    }
  }

  for (unsigned i = 0, ie = PromOps.size(); i != ie; ++i) {
    for (const SDNode *User : PromOps[i].getNode()->users()) {
      if (User != N && !Visited.count(User))
        return SDValue();

      // Make sure that we're not going to promote the non-output-value
      // operand(s) or SELECT or SELECT_CC.
      // FIXME: Although we could sometimes handle this, and it does occur in
      // practice that one of the condition inputs to the select is also one of
      // the outputs, we currently can't deal with this.
      if (User->getOpcode() == ISD::SELECT) {
        if (User->getOperand(0) == PromOps[i])
          return SDValue();
      } else if (User->getOpcode() == ISD::SELECT_CC) {
        if (User->getOperand(0) == PromOps[i] ||
            User->getOperand(1) == PromOps[i])
          return SDValue();
      }
    }
  }

  // Replace all inputs with the extension operand.
  for (unsigned i = 0, ie = Inputs.size(); i != ie; ++i) {
    // Constants may have users outside the cluster of to-be-promoted nodes,
    // and so we need to replace those as we do the promotions.
    if (isa<ConstantSDNode>(Inputs[i]))
      continue;
    else
      DAG.ReplaceAllUsesOfValueWith(Inputs[i], Inputs[i].getOperand(0));
  }

  std::list<HandleSDNode> PromOpHandles;
  for (auto &PromOp : PromOps)
    PromOpHandles.emplace_back(PromOp);

  // Replace all operations (these are all the same, but have a different
  // (i1) return type). DAG.getNode will validate that the types of
  // a binary operator match, so go through the list in reverse so that
  // we've likely promoted both operands first. Any intermediate truncations or
  // extensions disappear.
  while (!PromOpHandles.empty()) {
    SDValue PromOp = PromOpHandles.back().getValue();
    PromOpHandles.pop_back();

    if (PromOp.getOpcode() == ISD::TRUNCATE ||
        PromOp.getOpcode() == ISD::SIGN_EXTEND ||
        PromOp.getOpcode() == ISD::ZERO_EXTEND ||
        PromOp.getOpcode() == ISD::ANY_EXTEND) {
      if (!isa<ConstantSDNode>(PromOp.getOperand(0)) &&
          PromOp.getOperand(0).getValueType() != MVT::i1) {
        // The operand is not yet ready (see comment below).
        PromOpHandles.emplace_front(PromOp);
        continue;
      }

      SDValue RepValue = PromOp.getOperand(0);
      if (isa<ConstantSDNode>(RepValue))
        RepValue = DAG.getNode(ISD::TRUNCATE, dl, MVT::i1, RepValue);

      DAG.ReplaceAllUsesOfValueWith(PromOp, RepValue);
      continue;
    }

    unsigned C;
    switch (PromOp.getOpcode()) {
    default:             C = 0; break;
    case ISD::SELECT:    C = 1; break;
    case ISD::SELECT_CC: C = 2; break;
    }

    if ((!isa<ConstantSDNode>(PromOp.getOperand(C)) &&
         PromOp.getOperand(C).getValueType() != MVT::i1) ||
        (!isa<ConstantSDNode>(PromOp.getOperand(C+1)) &&
         PromOp.getOperand(C+1).getValueType() != MVT::i1)) {
      // The to-be-promoted operands of this node have not yet been
      // promoted (this should be rare because we're going through the
      // list backward, but if one of the operands has several users in
      // this cluster of to-be-promoted nodes, it is possible).
      PromOpHandles.emplace_front(PromOp);
      continue;
    }

    SmallVector<SDValue, 3> Ops(PromOp.getNode()->ops());

    // If there are any constant inputs, make sure they're replaced now.
    for (unsigned i = 0; i < 2; ++i)
      if (isa<ConstantSDNode>(Ops[C+i]))
        Ops[C+i] = DAG.getNode(ISD::TRUNCATE, dl, MVT::i1, Ops[C+i]);

    DAG.ReplaceAllUsesOfValueWith(PromOp,
      DAG.getNode(PromOp.getOpcode(), dl, MVT::i1, Ops));
  }

  // Now we're left with the initial truncation itself.
  if (N->getOpcode() == ISD::TRUNCATE)
    return N->getOperand(0);

  // Otherwise, this is a comparison. The operands to be compared have just
  // changed type (to i1), but everything else is the same.
  return SDValue(N, 0);
}

SDValue PPCTargetLowering::DAGCombineExtBoolTrunc(SDNode *N,
                                                  DAGCombinerInfo &DCI) const {
  SelectionDAG &DAG = DCI.DAG;
  SDLoc dl(N);

  // If we're tracking CR bits, we need to be careful that we don't have:
  //   zext(binary-ops(trunc(x), trunc(y)))
  // or
  //   zext(binary-ops(binary-ops(trunc(x), trunc(y)), ...)
  // such that we're unnecessarily moving things into CR bits that can more
  // efficiently stay in GPRs. Note that if we're not certain that the high
  // bits are set as required by the final extension, we still may need to do
  // some masking to get the proper behavior.

  // This same functionality is important on PPC64 when dealing with
  // 32-to-64-bit extensions; these occur often when 32-bit values are used as
  // the return values of functions. Because it is so similar, it is handled
  // here as well.

  if (N->getValueType(0) != MVT::i32 &&
      N->getValueType(0) != MVT::i64)
    return SDValue();

  if (!((N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
        (N->getOperand(0).getValueType() == MVT::i32 && Subtarget.isPPC64())))
    return SDValue();

  if (N->getOperand(0).getOpcode() != ISD::AND &&
      N->getOperand(0).getOpcode() != ISD::OR  &&
      N->getOperand(0).getOpcode() != ISD::XOR &&
      N->getOperand(0).getOpcode() != ISD::SELECT &&
      N->getOperand(0).getOpcode() != ISD::SELECT_CC)
    return SDValue();

  SmallVector<SDValue, 4> Inputs;
  SmallVector<SDValue, 8> BinOps(1, N->getOperand(0)), PromOps;
  SmallPtrSet<SDNode *, 16> Visited;

  // Visit all inputs, collect all binary operations (and, or, xor and
  // select) that are all fed by truncations.
  while (!BinOps.empty()) {
    SDValue BinOp = BinOps.pop_back_val();

    if (!Visited.insert(BinOp.getNode()).second)
      continue;

    PromOps.push_back(BinOp);

    for (unsigned i = 0, ie = BinOp.getNumOperands(); i != ie; ++i) {
      // The condition of the select is not promoted.
      if (BinOp.getOpcode() == ISD::SELECT && i == 0)
        continue;
      if (BinOp.getOpcode() == ISD::SELECT_CC && i != 2 && i != 3)
        continue;

      if (BinOp.getOperand(i).getOpcode() == ISD::TRUNCATE ||
          isa<ConstantSDNode>(BinOp.getOperand(i))) {
        Inputs.push_back(BinOp.getOperand(i));
      } else if (BinOp.getOperand(i).getOpcode() == ISD::AND ||
                 BinOp.getOperand(i).getOpcode() == ISD::OR  ||
                 BinOp.getOperand(i).getOpcode() == ISD::XOR ||
                 BinOp.getOperand(i).getOpcode() == ISD::SELECT ||
                 BinOp.getOperand(i).getOpcode() == ISD::SELECT_CC) {
        BinOps.push_back(BinOp.getOperand(i));
      } else {
        // We have an input that is not a truncation or another binary
        // operation; we'll abort this transformation.
        return SDValue();
      }
    }
  }

  // The operands of a select that must be truncated when the select is
  // promoted because the operand is actually part of the to-be-promoted set.
  DenseMap<SDNode *, EVT> SelectTruncOp[2];

  // Make sure that this is a self-contained cluster of operations (which
  // is not quite the same thing as saying that everything has only one
  // use).
  for (unsigned i = 0, ie = Inputs.size(); i != ie; ++i) {
    if (isa<ConstantSDNode>(Inputs[i]))
      continue;

    for (SDNode *User : Inputs[i].getNode()->users()) {
      if (User != N && !Visited.count(User))
        return SDValue();

      // If we're going to promote the non-output-value operand(s) or SELECT or
      // SELECT_CC, record them for truncation.
      if (User->getOpcode() == ISD::SELECT) {
        if (User->getOperand(0) == Inputs[i])
          SelectTruncOp[0].insert(std::make_pair(User,
                                    User->getOperand(0).getValueType()));
      } else if (User->getOpcode() == ISD::SELECT_CC) {
        if (User->getOperand(0) == Inputs[i])
          SelectTruncOp[0].insert(std::make_pair(User,
                                    User->getOperand(0).getValueType()));
        if (User->getOperand(1) == Inputs[i])
          SelectTruncOp[1].insert(std::make_pair(User,
                                    User->getOperand(1).getValueType()));
      }
    }
  }

  for (unsigned i = 0, ie = PromOps.size(); i != ie; ++i) {
    for (SDNode *User : PromOps[i].getNode()->users()) {
      if (User != N && !Visited.count(User))
        return SDValue();

      // If we're going to promote the non-output-value operand(s) or SELECT or
      // SELECT_CC, record them for truncation.
      if (User->getOpcode() == ISD::SELECT) {
        if (User->getOperand(0) == PromOps[i])
          SelectTruncOp[0].insert(std::make_pair(User,
                                    User->getOperand(0).getValueType()));
      } else if (User->getOpcode() == ISD::SELECT_CC) {
        if (User->getOperand(0) == PromOps[i])
          SelectTruncOp[0].insert(std::make_pair(User,
                                    User->getOperand(0).getValueType()));
        if (User->getOperand(1) == PromOps[i])
          SelectTruncOp[1].insert(std::make_pair(User,
                                    User->getOperand(1).getValueType()));
      }
    }
  }

  unsigned PromBits = N->getOperand(0).getValueSizeInBits();
  bool ReallyNeedsExt = false;
  if (N->getOpcode() != ISD::ANY_EXTEND) {
    // If all of the inputs are not already sign/zero extended, then
    // we'll still need to do that at the end.
    for (unsigned i = 0, ie = Inputs.size(); i != ie; ++i) {
      if (isa<ConstantSDNode>(Inputs[i]))
        continue;

      unsigned OpBits =
        Inputs[i].getOperand(0).getValueSizeInBits();
      assert(PromBits < OpBits && "Truncation not to a smaller bit count?");

      if ((N->getOpcode() == ISD::ZERO_EXTEND &&
           !DAG.MaskedValueIsZero(Inputs[i].getOperand(0),
                                  APInt::getHighBitsSet(OpBits,
                                                        OpBits-PromBits))) ||
          (N->getOpcode() == ISD::SIGN_EXTEND &&
           DAG.ComputeNumSignBits(Inputs[i].getOperand(0)) <
             (OpBits-(PromBits-1)))) {
        ReallyNeedsExt = true;
        break;
      }
    }
  }

  // Convert PromOps to handles before doing any RAUW operations, as these
  // may CSE with existing nodes, deleting the originals.
  std::list<HandleSDNode> PromOpHandles;
  for (auto &PromOp : PromOps)
    PromOpHandles.emplace_back(PromOp);

  // Replace all inputs, either with the truncation operand, or a
  // truncation or extension to the final output type.
  for (unsigned i = 0, ie = Inputs.size(); i != ie; ++i) {
    // Constant inputs need to be replaced with the to-be-promoted nodes that
    // use them because they might have users outside of the cluster of
    // promoted nodes.
    if (isa<ConstantSDNode>(Inputs[i]))
      continue;

    SDValue InSrc = Inputs[i].getOperand(0);
    if (Inputs[i].getValueType() == N->getValueType(0))
      DAG.ReplaceAllUsesOfValueWith(Inputs[i], InSrc);
    else if (N->getOpcode() == ISD::SIGN_EXTEND)
      DAG.ReplaceAllUsesOfValueWith(Inputs[i],
        DAG.getSExtOrTrunc(InSrc, dl, N->getValueType(0)));
    else if (N->getOpcode() == ISD::ZERO_EXTEND)
      DAG.ReplaceAllUsesOfValueWith(Inputs[i],
        DAG.getZExtOrTrunc(InSrc, dl, N->getValueType(0)));
    else
      DAG.ReplaceAllUsesOfValueWith(Inputs[i],
        DAG.getAnyExtOrTrunc(InSrc, dl, N->getValueType(0)));
  }

  // Replace all operations (these are all the same, but have a different
  // (promoted) return type). DAG.getNode will validate that the types of
  // a binary operator match, so go through the list in reverse so that
  // we've likely promoted both operands first.
  while (!PromOpHandles.empty()) {
    SDValue PromOp = PromOpHandles.back().getValue();
    PromOpHandles.pop_back();

    unsigned C;
    switch (PromOp.getOpcode()) {
    default:             C = 0; break;
    case ISD::SELECT:    C = 1; break;
    case ISD::SELECT_CC: C = 2; break;
    }

    if ((!isa<ConstantSDNode>(PromOp.getOperand(C)) &&
         PromOp.getOperand(C).getValueType() != N->getValueType(0)) ||
        (!isa<ConstantSDNode>(PromOp.getOperand(C+1)) &&
         PromOp.getOperand(C+1).getValueType() != N->getValueType(0))) {
      // The to-be-promoted operands of this node have not yet been
      // promoted (this should be rare because we're going through the
      // list backward, but if one of the operands has several users in
      // this cluster of to-be-promoted nodes, it is possible).
      PromOpHandles.emplace_front(PromOp);
      continue;
    }

    // For SELECT and SELECT_CC nodes, we do a similar check for any
    // to-be-promoted comparison inputs.
    if (PromOp.getOpcode() == ISD::SELECT ||
        PromOp.getOpcode() == ISD::SELECT_CC) {
      if ((SelectTruncOp[0].count(PromOp.getNode()) &&
           PromOp.getOperand(0).getValueType() != N->getValueType(0)) ||
          (SelectTruncOp[1].count(PromOp.getNode()) &&
           PromOp.getOperand(1).getValueType() != N->getValueType(0))) {
        PromOpHandles.emplace_front(PromOp);
        continue;
      }
    }

    SmallVector<SDValue, 3> Ops(PromOp.getNode()->ops());

    // If this node has constant inputs, then they'll need to be promoted here.
    for (unsigned i = 0; i < 2; ++i) {
      if (!isa<ConstantSDNode>(Ops[C+i]))
        continue;
      if (Ops[C+i].getValueType() == N->getValueType(0))
        continue;

      if (N->getOpcode() == ISD::SIGN_EXTEND)
        Ops[C+i] = DAG.getSExtOrTrunc(Ops[C+i], dl, N->getValueType(0));
      else if (N->getOpcode() == ISD::ZERO_EXTEND)
        Ops[C+i] = DAG.getZExtOrTrunc(Ops[C+i], dl, N->getValueType(0));
      else
        Ops[C+i] = DAG.getAnyExtOrTrunc(Ops[C+i], dl, N->getValueType(0));
    }

    // If we've promoted the comparison inputs of a SELECT or SELECT_CC,
    // truncate them again to the original value type.
    if (PromOp.getOpcode() == ISD::SELECT ||
        PromOp.getOpcode() == ISD::SELECT_CC) {
      auto SI0 = SelectTruncOp[0].find(PromOp.getNode());
      if (SI0 != SelectTruncOp[0].end())
        Ops[0] = DAG.getNode(ISD::TRUNCATE, dl, SI0->second, Ops[0]);
      auto SI1 = SelectTruncOp[1].find(PromOp.getNode());
      if (SI1 != SelectTruncOp[1].end())
        Ops[1] = DAG.getNode(ISD::TRUNCATE, dl, SI1->second, Ops[1]);
    }

    DAG.ReplaceAllUsesOfValueWith(PromOp,
      DAG.getNode(PromOp.getOpcode(), dl, N->getValueType(0), Ops));
  }

  // Now we're left with the initial extension itself.
  if (!ReallyNeedsExt)
    return N->getOperand(0);

  // To zero extend, just mask off everything except for the first bit (in the
  // i1 case).
  if (N->getOpcode() == ISD::ZERO_EXTEND)
    return DAG.getNode(ISD::AND, dl, N->getValueType(0), N->getOperand(0),
                       DAG.getConstant(APInt::getLowBitsSet(
                                         N->getValueSizeInBits(0), PromBits),
                                       dl, N->getValueType(0)));

  assert(N->getOpcode() == ISD::SIGN_EXTEND &&
         "Invalid extension type");
  EVT ShiftAmountTy = getShiftAmountTy(N->getValueType(0), DAG.getDataLayout());
  SDValue ShiftCst =
      DAG.getConstant(N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
  return DAG.getNode(
      ISD::SRA, dl, N->getValueType(0),
      DAG.getNode(ISD::SHL, dl, N->getValueType(0), N->getOperand(0), ShiftCst),
      ShiftCst);
}

// The function check a i128 load can convert to 16i8 load for Vcmpequb.
static bool canConvertToVcmpequb(SDValue &LHS, SDValue &RHS) {

  auto isValidForConvert = [](SDValue &Operand) {
    if (!Operand.hasOneUse())
      return false;

    if (Operand.getValueType() != MVT::i128)
      return false;

    if (Operand.getOpcode() == ISD::Constant)
      return true;

    auto *LoadNode = dyn_cast<LoadSDNode>(Operand);
    if (!LoadNode)
      return false;

    // If memory operation is volatile, do not perform any
    // optimization or transformation. Volatile operations must be preserved
    // as written to ensure correct program behavior, so we return an empty
    // SDValue to indicate no action.

    if (LoadNode->isVolatile())
      return false;

    // Only combine loads if both use the unindexed addressing mode.
    // PowerPC AltiVec/VMX does not support vector loads or stores with
    // pre/post-increment addressing. Indexed modes may imply implicit
    // pointer updates, which are not compatible with AltiVec vector
    // instructions.
    if (LoadNode->getAddressingMode() != ISD::UNINDEXED)
      return false;

    // Only combine loads if both are non-extending loads
    // (ISD::NON_EXTLOAD). Extending loads (such as ISD::ZEXTLOAD or
    // ISD::SEXTLOAD) perform zero or sign extension, which may change the
    // loaded value's semantics and are not compatible with vector loads.
    if (LoadNode->getExtensionType() != ISD::NON_EXTLOAD)
      return false;

    return true;
  };

  return (isValidForConvert(LHS) && isValidForConvert(RHS));
}

SDValue convertTwoLoadsAndCmpToVCMPEQUB(SelectionDAG &DAG, SDNode *N,
                                        const SDLoc &DL) {

  assert(N->getOpcode() == ISD::SETCC && "Should be called with a SETCC node");

  ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
  assert((CC == ISD::SETNE || CC == ISD::SETEQ) &&
         "CC mus be ISD::SETNE or ISD::SETEQ");

  auto getV16i8Load = [&](const SDValue &Operand) {
    if (Operand.getOpcode() == ISD::Constant)
      return DAG.getBitcast(MVT::v16i8, Operand);

    assert(Operand.getOpcode() == ISD::LOAD && "Must be LoadSDNode here.");

    auto *LoadNode = cast<LoadSDNode>(Operand);
    SDValue NewLoad =
        DAG.getLoad(MVT::v16i8, DL, LoadNode->getChain(),
                    LoadNode->getBasePtr(), LoadNode->getMemOperand());
    DAG.ReplaceAllUsesOfValueWith(Operand.getValue(1), NewLoad.getValue(1));
    return NewLoad;
  };

  // Following code transforms the DAG
  // t0: ch,glue = EntryToken
  // t2: i64,ch = CopyFromReg t0, Register:i64 %0
  // t3: i128,ch = load<(load (s128) from %ir.a, align 1)> t0, t2,
  //    undef:i64
  // t4: i64,ch = CopyFromReg t0, Register:i64 %1
  // t5: i128,ch =
  //    load<(load (s128) from %ir.b, align 1)> t0, t4, undef:i64 t6: i1 =
  // setcc t3, t5, setne:ch
  //
  //  ---->
  //
  // t0: ch,glue = EntryToken
  // t2: i64,ch = CopyFromReg t0, Register:i64 %0
  // t3: v16i8,ch = load<(load (s128) from %ir.a, align 1)> t0, t2,
  //    undef:i64
  // t4: i64,ch = CopyFromReg t0, Register:i64 %1
  // t5: v16i8,ch =
  //    load<(load (s128) from %ir.b, align 1)> t0, t4, undef:i64
  // t6: i32 =
  //    llvm.ppc.altivec.vcmpequb.p TargetConstant:i32<10505>,
  //    Constant:i32<2>, t3, t5
  // t7: i1 = setcc t6, Constant:i32<0>, seteq:ch

  // Or transforms the DAG
  //  t5: i128,ch = load<(load (s128) from %ir.X, align 1)> t0, t2, undef:i64
  //  t8: i1 =
  //     setcc Constant:i128<237684487579686500932345921536>, t5, setne:ch
  //
  //  --->
  //
  // t5: v16i8,ch = load<(load (s128) from %ir.X, align 1)> t0, t2, undef:i64
  // t6: v16i8 = bitcast Constant:i128<237684487579686500932345921536>
  // t7: i32 =
  //  llvm.ppc.altivec.vcmpequb.p Constant:i32<10962>, Constant:i32<2>, t5, t2

  SDValue LHSVec = getV16i8Load(N->getOperand(0));
  SDValue RHSVec = getV16i8Load(N->getOperand(1));

  SDValue IntrID =
      DAG.getConstant(Intrinsic::ppc_altivec_vcmpequb_p, DL, MVT::i32);
  SDValue CRSel = DAG.getConstant(2, DL, MVT::i32); // which CR6 predicate field
  SDValue PredResult = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, MVT::i32,
                                   IntrID, CRSel, LHSVec, RHSVec);
  // ppc_altivec_vcmpequb_p returns 1 when two vectors are the same,
  // so we need to invert the CC opcode.
  return DAG.getSetCC(DL, N->getValueType(0), PredResult,
                      DAG.getConstant(0, DL, MVT::i32),
                      CC == ISD::SETNE ? ISD::SETEQ : ISD::SETNE);
}

// Detect whether there is a pattern like (setcc (and X, 1), 0, eq).
// If it is , return true; otherwise return false.
static bool canConvertSETCCToXori(SDNode *N) {
  assert(N->getOpcode() == ISD::SETCC && "Should be SETCC SDNode here.");

  ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
  if (CC != ISD::SETEQ)
    return false;

  SDValue LHS = N->getOperand(0);
  SDValue RHS = N->getOperand(1);

  // Check the `SDValue &V` is from `and` with `1`.
  auto IsAndWithOne = [](SDValue &V) {
    if (V.getOpcode() == ISD::AND) {
      for (const SDValue &Op : V->ops())
        if (auto *C = dyn_cast<ConstantSDNode>(Op))
          if (C->isOne())
            return true;
    }
    return false;
  };

  // Check whether the SETCC compare with zero.
  auto IsCompareWithZero = [](SDValue &V) {
    if (auto *C = dyn_cast<ConstantSDNode>(V))
      if (C->isZero())
        return true;
    return false;
  };

  return (IsAndWithOne(LHS) && IsCompareWithZero(RHS)) ||
         (IsAndWithOne(RHS) && IsCompareWithZero(LHS));
}

// You must check whether the `SDNode* N` can be converted to Xori using
// the function `static bool canConvertSETCCToXori(SDNode *N)`
// before calling the function; otherwise, it may produce incorrect results.
static SDValue ConvertSETCCToXori(SDNode *N, SelectionDAG &DAG) {

  assert(N->getOpcode() == ISD::SETCC && "Should be SETCC SDNode here.");
  SDValue LHS = N->getOperand(0);
  SDValue RHS = N->getOperand(1);
  SDLoc DL(N);

  [[maybe_unused]] ISD::CondCode CC =
      cast<CondCodeSDNode>(N->getOperand(2))->get();
  assert((CC == ISD::SETEQ) && "CC must be ISD::SETEQ.");
  // Rewrite it as XORI (and X, 1), 1.
  auto MakeXor1 = [&](SDValue V) {
    EVT VT = V.getValueType();
    SDValue One = DAG.getConstant(1, DL, VT);
    SDValue Xor = DAG.getNode(ISD::XOR, DL, VT, V, One);
    return DAG.getNode(ISD::TRUNCATE, DL, MVT::i1, Xor);
  };

  if (LHS.getOpcode() == ISD::AND && RHS.getOpcode() != ISD::AND)
    return MakeXor1(LHS);

  if (RHS.getOpcode() == ISD::AND && LHS.getOpcode() != ISD::AND)
    return MakeXor1(RHS);

  llvm_unreachable("Should not reach here.");
}

SDValue PPCTargetLowering::combineSetCC(SDNode *N,
                                        DAGCombinerInfo &DCI) const {
  assert(N->getOpcode() == ISD::SETCC &&
         "Should be called with a SETCC node");

  // Check if the pattern (setcc (and X, 1), 0, eq) is present.
  // If it is, rewrite it as XORI (and X, 1), 1.
  if (canConvertSETCCToXori(N))
    return ConvertSETCCToXori(N, DCI.DAG);

  ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
  if (CC == ISD::SETNE || CC == ISD::SETEQ) {
    SDValue LHS = N->getOperand(0);
    SDValue RHS = N->getOperand(1);

    // If there is a '0 - y' pattern, canonicalize the pattern to the RHS.
    if (LHS.getOpcode() == ISD::SUB && isNullConstant(LHS.getOperand(0)) &&
        LHS.hasOneUse())
      std::swap(LHS, RHS);

    // x == 0-y --> x+y == 0
    // x != 0-y --> x+y != 0
    if (RHS.getOpcode() == ISD::SUB && isNullConstant(RHS.getOperand(0)) &&
        RHS.hasOneUse()) {
      SDLoc DL(N);
      SelectionDAG &DAG = DCI.DAG;
      EVT VT = N->getValueType(0);
      EVT OpVT = LHS.getValueType();
      SDValue Add = DAG.getNode(ISD::ADD, DL, OpVT, LHS, RHS.getOperand(1));
      return DAG.getSetCC(DL, VT, Add, DAG.getConstant(0, DL, OpVT), CC);
    }

    // Optimization: Fold i128 equality/inequality compares of two loads into a
    // vectorized compare using vcmpequb.p when Altivec is available.
    //
    // Rationale:
    //   A scalar i128 SETCC (eq/ne) normally lowers to multiple scalar ops.
    //   On VSX-capable subtargets, we can instead reinterpret the i128 loads
    //   as v16i8 vectors and use the Altive vcmpequb.p instruction to
    //   perform a full 128-bit equality check in a single vector compare.
    //
    // Example Result:
    //   This transformation replaces memcmp(a, b, 16) with two vector loads
    //   and one vector compare instruction.

    if (Subtarget.hasAltivec() && canConvertToVcmpequb(LHS, RHS))
      return convertTwoLoadsAndCmpToVCMPEQUB(DCI.DAG, N, SDLoc(N));
  }

  return DAGCombineTruncBoolExt(N, DCI);
}

// Is this an extending load from an f32 to an f64?
static bool isFPExtLoad(SDValue Op) {
  if (LoadSDNode *LD = dyn_cast<LoadSDNode>(Op.getNode()))
    return LD->getExtensionType() == ISD::EXTLOAD &&
      Op.getValueType() == MVT::f64;
  return false;
}

/// Reduces the number of fp-to-int conversion when building a vector.
///
/// If this vector is built out of floating to integer conversions,
/// transform it to a vector built out of floating point values followed by a
/// single floating to integer conversion of the vector.
/// Namely  (build_vector (fptosi $A), (fptosi $B), ...)
/// becomes (fptosi (build_vector ($A, $B, ...)))
SDValue PPCTargetLowering::
combineElementTruncationToVectorTruncation(SDNode *N,
                                           DAGCombinerInfo &DCI) const {
  assert(N->getOpcode() == ISD::BUILD_VECTOR &&
         "Should be called with a BUILD_VECTOR node");

  SelectionDAG &DAG = DCI.DAG;
  SDLoc dl(N);

  SDValue FirstInput = N->getOperand(0);
  assert(FirstInput.getOpcode() == PPCISD::MFVSR &&
         "The input operand must be an fp-to-int conversion.");

  // This combine happens after legalization so the fp_to_[su]i nodes are
  // already converted to PPCSISD nodes.
  unsigned FirstConversion = FirstInput.getOperand(0).getOpcode();
  if (FirstConversion == PPCISD::FCTIDZ ||
      FirstConversion == PPCISD::FCTIDUZ ||
      FirstConversion == PPCISD::FCTIWZ ||
      FirstConversion == PPCISD::FCTIWUZ) {
    bool IsSplat = true;
    bool Is32Bit = FirstConversion == PPCISD::FCTIWZ ||
      FirstConversion == PPCISD::FCTIWUZ;
    EVT SrcVT = FirstInput.getOperand(0).getValueType();
    SmallVector<SDValue, 4> Ops;
    EVT TargetVT = N->getValueType(0);
    for (int i = 0, e = N->getNumOperands(); i < e; ++i) {
      SDValue NextOp = N->getOperand(i);
      if (NextOp.getOpcode() != PPCISD::MFVSR)
        return SDValue();
      unsigned NextConversion = NextOp.getOperand(0).getOpcode();
      if (NextConversion != FirstConversion)
        return SDValue();
      // If we are converting to 32-bit integers, we need to add an FP_ROUND.
      // This is not valid if the input was originally double precision. It is
      // also not profitable to do unless this is an extending load in which
      // case doing this combine will allow us to combine consecutive loads.
      if (Is32Bit && !isFPExtLoad(NextOp.getOperand(0).getOperand(0)))
        return SDValue();
      if (N->getOperand(i) != FirstInput)
        IsSplat = false;
    }

    // If this is a splat, we leave it as-is since there will be only a single
    // fp-to-int conversion followed by a splat of the integer. This is better
    // for 32-bit and smaller ints and neutral for 64-bit ints.
    if (IsSplat)
      return SDValue();

    // Now that we know we have the right type of node, get its operands
    for (int i = 0, e = N->getNumOperands(); i < e; ++i) {
      SDValue In = N->getOperand(i).getOperand(0);
      if (Is32Bit) {
        // For 32-bit values, we need to add an FP_ROUND node (if we made it
        // here, we know that all inputs are extending loads so this is safe).
        if (In.isUndef())
          Ops.push_back(DAG.getUNDEF(SrcVT));
        else {
          SDValue Trunc =
              DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, In.getOperand(0),
                          DAG.getIntPtrConstant(1, dl, /*isTarget=*/true));
          Ops.push_back(Trunc);
        }
      } else
        Ops.push_back(In.isUndef() ? DAG.getUNDEF(SrcVT) : In.getOperand(0));
    }

    unsigned Opcode;
    if (FirstConversion == PPCISD::FCTIDZ ||
        FirstConversion == PPCISD::FCTIWZ)
      Opcode = ISD::FP_TO_SINT;
    else
      Opcode = ISD::FP_TO_UINT;

    EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
    SDValue BV = DAG.getBuildVector(NewVT, dl, Ops);
    return DAG.getNode(Opcode, dl, TargetVT, BV);
  }
  return SDValue();
}

// LXVKQ instruction load VSX vector with a special quadword value
// based on an immediate value. This helper method returns the details of the
// match as a tuple of {LXVKQ unsigned IMM Value, right_shift_amount}
// to help generate the LXVKQ instruction and the subsequent shift instruction
// required to match the original build vector pattern.

// LXVKQPattern: {LXVKQ unsigned IMM Value, right_shift_amount}
using LXVKQPattern = std::tuple<uint32_t, uint8_t>;

static std::optional<LXVKQPattern> getPatternInfo(const APInt &FullVal) {

  // LXVKQ instruction loads the Quadword value:
  // 0x8000_0000_0000_0000_0000_0000_0000_0000 when imm = 0b10000
  static const APInt BasePattern = APInt(128, 0x8000000000000000ULL) << 64;
  static const uint32_t Uim = 16;

  // Check for direct LXVKQ match (no shift needed)
  if (FullVal == BasePattern)
    return std::make_tuple(Uim, uint8_t{0});

  // Check if FullValue is 1 (the result of the base pattern >> 127)
  if (FullVal == APInt(128, 1))
    return std::make_tuple(Uim, uint8_t{127});

  return std::nullopt;
}

/// Combine vector loads to a single load (using lxvkq) or splat with shift of a
/// constant (xxspltib + vsrq) by recognising patterns in the Build Vector.
/// LXVKQ instruction load VSX vector with a special quadword value based on an
/// immediate value. if UIM=0b10000 then LXVKQ loads VSR[32×TX+T] with value
/// 0x8000_0000_0000_0000_0000_0000_0000_0000.
/// This can be used to inline the build vector constants that have the
/// following patterns:
///
/// 0x8000_0000_0000_0000_0000_0000_0000_0000 (MSB set pattern)
/// 0x0000_0000_0000_0000_0000_0000_0000_0001 (LSB set pattern)
/// MSB pattern can directly loaded using LXVKQ while LSB is loaded using a
/// combination of splatting and right shift instructions.

SDValue PPCTargetLowering::combineBVLoadsSpecialValue(SDValue Op,
                                                      SelectionDAG &DAG) const {

  assert((Op.getNode() && Op.getOpcode() == ISD::BUILD_VECTOR) &&
         "Expected a BuildVectorSDNode in combineBVLoadsSpecialValue");

  // This transformation is only supported if we are loading either a byte,
  // halfword, word, or doubleword.
  EVT VT = Op.getValueType();
  if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
        VT == MVT::v2i64))
    return SDValue();

  LLVM_DEBUG(llvm::dbgs() << "\ncombineBVLoadsSpecialValue: Build vector ("
                          << VT.getEVTString() << "): ";
             Op->dump());

  unsigned NumElems = VT.getVectorNumElements();
  unsigned ElemBits = VT.getScalarSizeInBits();

  bool IsLittleEndian = DAG.getDataLayout().isLittleEndian();

  // Check for Non-constant operand in the build vector.
  for (const SDValue &Operand : Op.getNode()->op_values()) {
    if (!isa<ConstantSDNode>(Operand))
      return SDValue();
  }

  // Assemble build vector operands as a 128-bit register value
  // We need to reconstruct what the 128-bit register pattern would be
  // that produces this vector when interpreted with the current endianness
  APInt FullVal = APInt::getZero(128);

  for (unsigned Index = 0; Index < NumElems; ++Index) {
    auto *C = cast<ConstantSDNode>(Op.getOperand(Index));

    // Get element value as raw bits (zero-extended)
    uint64_t ElemValue = C->getZExtValue();

    // Mask to element size to ensure we only get the relevant bits
    if (ElemBits < 64)
      ElemValue &= ((1ULL << ElemBits) - 1);

    // Calculate bit position for this element in the 128-bit register
    unsigned BitPos =
        (IsLittleEndian) ? (Index * ElemBits) : (128 - (Index + 1) * ElemBits);

    // Create APInt for the element value and shift it to correct position
    APInt ElemAPInt(128, ElemValue);
    ElemAPInt <<= BitPos;

    // Place the element value at the correct bit position
    FullVal |= ElemAPInt;
  }

  if (FullVal.isZero() || FullVal.isAllOnes())
    return SDValue();

  if (auto UIMOpt = getPatternInfo(FullVal)) {
    const auto &[Uim, ShiftAmount] = *UIMOpt;
    SDLoc Dl(Op);

    // Generate LXVKQ instruction if the shift amount is zero.
    if (ShiftAmount == 0) {
      SDValue UimVal = DAG.getTargetConstant(Uim, Dl, MVT::i32);
      SDValue LxvkqInstr =
          SDValue(DAG.getMachineNode(PPC::LXVKQ, Dl, VT, UimVal), 0);
      LLVM_DEBUG(llvm::dbgs()
                     << "combineBVLoadsSpecialValue: Instruction Emitted ";
                 LxvkqInstr.dump());
      return LxvkqInstr;
    }

    assert(ShiftAmount == 127 && "Unexpected lxvkq shift amount value");

    // The right shifted pattern can be constructed using a combination of
    // XXSPLTIB and VSRQ instruction. VSRQ uses the shift amount from the lower
    // 7 bits of byte 15. This can be specified using XXSPLTIB with immediate
    // value 255.
    SDValue ShiftAmountVec =
        SDValue(DAG.getMachineNode(PPC::XXSPLTIB, Dl, MVT::v4i32,
                                   DAG.getTargetConstant(255, Dl, MVT::i32)),
                0);
    // Generate appropriate right shift instruction
    SDValue ShiftVec = SDValue(
        DAG.getMachineNode(PPC::VSRQ, Dl, VT, ShiftAmountVec, ShiftAmountVec),
        0);
    LLVM_DEBUG(llvm::dbgs()
                   << "\n combineBVLoadsSpecialValue: Instruction Emitted ";
               ShiftVec.dump());
    return ShiftVec;
  }
  // No patterns matched for build vectors.
  return SDValue();
}

/// Reduce the number of loads when building a vector.
///
/// Building a vector out of multiple loads can be converted to a load
/// of the vector type if the loads are consecutive. If the loads are
/// consecutive but in descending order, a shuffle is added at the end
/// to reorder the vector.
static SDValue combineBVOfConsecutiveLoads(SDNode *N, SelectionDAG &DAG) {
  assert(N->getOpcode() == ISD::BUILD_VECTOR &&
         "Should be called with a BUILD_VECTOR node");

  SDLoc dl(N);

  // Return early for non byte-sized type, as they can't be consecutive.
  if (!N->getValueType(0).getVectorElementType().isByteSized())
    return SDValue();

  bool InputsAreConsecutiveLoads = true;
  bool InputsAreReverseConsecutive = true;
  unsigned ElemSize = N->getValueType(0).getScalarType().getStoreSize();
  SDValue FirstInput = N->getOperand(0);
  bool IsRoundOfExtLoad = false;
  LoadSDNode *FirstLoad = nullptr;

  if (FirstInput.getOpcode() == ISD::FP_ROUND &&
      FirstInput.getOperand(0).getOpcode() == ISD::LOAD) {
    FirstLoad = cast<LoadSDNode>(FirstInput.getOperand(0));
    IsRoundOfExtLoad = FirstLoad->getExtensionType() == ISD::EXTLOAD;
  }
  // Not a build vector of (possibly fp_rounded) loads.
  if ((!IsRoundOfExtLoad && FirstInput.getOpcode() != ISD::LOAD) ||
      N->getNumOperands() == 1)
    return SDValue();

  if (!IsRoundOfExtLoad)
    FirstLoad = cast<LoadSDNode>(FirstInput);

  SmallVector<LoadSDNode *, 4> InputLoads;
  InputLoads.push_back(FirstLoad);
  for (int i = 1, e = N->getNumOperands(); i < e; ++i) {
    // If any inputs are fp_round(extload), they all must be.
    if (IsRoundOfExtLoad && N->getOperand(i).getOpcode() != ISD::FP_ROUND)
      return SDValue();

    SDValue NextInput = IsRoundOfExtLoad ? N->getOperand(i).getOperand(0) :
      N->getOperand(i);
    if (NextInput.getOpcode() != ISD::LOAD)
      return SDValue();

    SDValue PreviousInput =
      IsRoundOfExtLoad ? N->getOperand(i-1).getOperand(0) : N->getOperand(i-1);
    LoadSDNode *LD1 = cast<LoadSDNode>(PreviousInput);
    LoadSDNode *LD2 = cast<LoadSDNode>(NextInput);

    // If any inputs are fp_round(extload), they all must be.
    if (IsRoundOfExtLoad && LD2->getExtensionType() != ISD::EXTLOAD)
      return SDValue();

    // We only care about regular loads. The PPC-specific load intrinsics
    // will not lead to a merge opportunity.
    if (!DAG.areNonVolatileConsecutiveLoads(LD2, LD1, ElemSize, 1))
      InputsAreConsecutiveLoads = false;
    if (!DAG.areNonVolatileConsecutiveLoads(LD1, LD2, ElemSize, 1))
      InputsAreReverseConsecutive = false;

    // Exit early if the loads are neither consecutive nor reverse consecutive.
    if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
      return SDValue();
    InputLoads.push_back(LD2);
  }

  assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
         "The loads cannot be both consecutive and reverse consecutive.");

  SDValue WideLoad;
  SDValue ReturnSDVal;
  if (InputsAreConsecutiveLoads) {
    assert(FirstLoad && "Input needs to be a LoadSDNode.");
    WideLoad = DAG.getLoad(N->getValueType(0), dl, FirstLoad->getChain(),
                           FirstLoad->getBasePtr(), FirstLoad->getPointerInfo(),
                           FirstLoad->getAlign());
    ReturnSDVal = WideLoad;
  } else if (InputsAreReverseConsecutive) {
    LoadSDNode *LastLoad = InputLoads.back();
    assert(LastLoad && "Input needs to be a LoadSDNode.");
    WideLoad = DAG.getLoad(N->getValueType(0), dl, LastLoad->getChain(),
                           LastLoad->getBasePtr(), LastLoad->getPointerInfo(),
                           LastLoad->getAlign());
    SmallVector<int, 16> Ops;
    for (int i = N->getNumOperands() - 1; i >= 0; i--)
      Ops.push_back(i);

    ReturnSDVal = DAG.getVectorShuffle(N->getValueType(0), dl, WideLoad,
                                       DAG.getUNDEF(N->getValueType(0)), Ops);
  } else
    return SDValue();

  for (auto *LD : InputLoads)
    DAG.makeEquivalentMemoryOrdering(LD, WideLoad);
  return ReturnSDVal;
}

// This function adds the required vector_shuffle needed to get
// the elements of the vector extract in the correct position
// as specified by the CorrectElems encoding.
static SDValue addShuffleForVecExtend(SDNode *N, SelectionDAG &DAG,
                                      SDValue Input, uint64_t Elems,
                                      uint64_t CorrectElems) {
  SDLoc dl(N);

  unsigned NumElems = Input.getValueType().getVectorNumElements();
  SmallVector<int, 16> ShuffleMask(NumElems, -1);

  // Knowing the element indices being extracted from the original
  // vector and the order in which they're being inserted, just put
  // them at element indices required for the instruction.
  for (unsigned i = 0; i < N->getNumOperands(); i++) {
    if (DAG.getDataLayout().isLittleEndian())
      ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
    else
      ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
    CorrectElems = CorrectElems >> 8;
    Elems = Elems >> 8;
  }

  SDValue Shuffle =
      DAG.getVectorShuffle(Input.getValueType(), dl, Input,
                           DAG.getUNDEF(Input.getValueType()), ShuffleMask);

  EVT VT = N->getValueType(0);
  SDValue Conv = DAG.getBitcast(VT, Shuffle);

  EVT ExtVT = EVT::getVectorVT(*DAG.getContext(),
                               Input.getValueType().getVectorElementType(),
                               VT.getVectorNumElements());
  return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT, Conv,
                     DAG.getValueType(ExtVT));
}

// Look for build vector patterns where input operands come from sign
// extended vector_extract elements of specific indices. If the correct indices
// aren't used, add a vector shuffle to fix up the indices and create
// SIGN_EXTEND_INREG node which selects the vector sign extend instructions
// during instruction selection.
static SDValue combineBVOfVecSExt(SDNode *N, SelectionDAG &DAG) {
  // This array encodes the indices that the vector sign extend instructions
  // extract from when extending from one type to another for both BE and LE.
  // The right nibble of each byte corresponds to the LE incides.
  // and the left nibble of each byte corresponds to the BE incides.
  // For example: 0x3074B8FC  byte->word
  // For LE: the allowed indices are: 0x0,0x4,0x8,0xC
  // For BE: the allowed indices are: 0x3,0x7,0xB,0xF
  // For example: 0x000070F8  byte->double word
  // For LE: the allowed indices are: 0x0,0x8
  // For BE: the allowed indices are: 0x7,0xF
  uint64_t TargetElems[] = {
      0x3074B8FC, // b->w
      0x000070F8, // b->d
      0x10325476, // h->w
      0x00003074, // h->d
      0x00001032, // w->d
  };

  uint64_t Elems = 0;
  int Index;
  SDValue Input;

  auto isSExtOfVecExtract = [&](SDValue Op) -> bool {
    if (!Op)
      return false;
    if (Op.getOpcode() != ISD::SIGN_EXTEND &&
        Op.getOpcode() != ISD::SIGN_EXTEND_INREG)
      return false;

    // A SIGN_EXTEND_INREG might be fed by an ANY_EXTEND to produce a value
    // of the right width.
    SDValue Extract = Op.getOperand(0);
    if (Extract.getOpcode() == ISD::ANY_EXTEND)
      Extract = Extract.getOperand(0);
    if (Extract.getOpcode() != ISD::EXTRACT_VECTOR_ELT)
      return false;

    ConstantSDNode *ExtOp = dyn_cast<ConstantSDNode>(Extract.getOperand(1));
    if (!ExtOp)
      return false;

    Index = ExtOp->getZExtValue();
    if (Input && Input != Extract.getOperand(0))
      return false;

    if (!Input)
      Input = Extract.getOperand(0);

    Elems = Elems << 8;
    Index = DAG.getDataLayout().isLittleEndian() ? Index : Index << 4;
    Elems |= Index;

    return true;
  };

  // If the build vector operands aren't sign extended vector extracts,
  // of the same input vector, then return.
  for (unsigned i = 0; i < N->getNumOperands(); i++) {
    if (!isSExtOfVecExtract(N->getOperand(i))) {
      return SDValue();
    }
  }

  // If the vector extract indices are not correct, add the appropriate
  // vector_shuffle.
  int TgtElemArrayIdx;
  int InputSize = Input.getValueType().getScalarSizeInBits();
  int OutputSize = N->getValueType(0).getScalarSizeInBits();
  if (InputSize + OutputSize == 40)
    TgtElemArrayIdx = 0;
  else if (InputSize + OutputSize == 72)
    TgtElemArrayIdx = 1;
  else if (InputSize + OutputSize == 48)
    TgtElemArrayIdx = 2;
  else if (InputSize + OutputSize == 80)
    TgtElemArrayIdx = 3;
  else if (InputSize + OutputSize == 96)
    TgtElemArrayIdx = 4;
  else
    return SDValue();

  uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
  CorrectElems = DAG.getDataLayout().isLittleEndian()
                     ? CorrectElems & 0x0F0F0F0F0F0F0F0F
                     : CorrectElems & 0xF0F0F0F0F0F0F0F0;
  if (Elems != CorrectElems) {
    return addShuffleForVecExtend(N, DAG, Input, Elems, CorrectElems);
  }

  // Regular lowering will catch cases where a shuffle is not needed.
  return SDValue();
}

// Look for the pattern of a load from a narrow width to i128, feeding
// into a BUILD_VECTOR of v1i128. Replace this sequence with a PPCISD node
// (LXVRZX). This node represents a zero extending load that will be matched
// to the Load VSX Vector Rightmost instructions.
static SDValue combineBVZEXTLOAD(SDNode *N, SelectionDAG &DAG) {
  SDLoc DL(N);

  // This combine is only eligible for a BUILD_VECTOR of v1i128.
  if (N->getValueType(0) != MVT::v1i128)
    return SDValue();

  SDValue Operand = N->getOperand(0);
  // Proceed with the transformation if the operand to the BUILD_VECTOR
  // is a load instruction.
  if (Operand.getOpcode() != ISD::LOAD)
    return SDValue();

  auto *LD = cast<LoadSDNode>(Operand);
  EVT MemoryType = LD->getMemoryVT();

  // This transformation is only valid if the we are loading either a byte,
  // halfword, word, or doubleword.
  bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
                     MemoryType == MVT::i32 || MemoryType == MVT::i64;

  // Ensure that the load from the narrow width is being zero extended to i128.
  if (!ValidLDType ||
      (LD->getExtensionType() != ISD::ZEXTLOAD &&
       LD->getExtensionType() != ISD::EXTLOAD))
    return SDValue();

  SDValue LoadOps[] = {
      LD->getChain(), LD->getBasePtr(),
      DAG.getIntPtrConstant(MemoryType.getScalarSizeInBits(), DL)};

  return DAG.getMemIntrinsicNode(PPCISD::LXVRZX, DL,
                                 DAG.getVTList(MVT::v1i128, MVT::Other),
                                 LoadOps, MemoryType, LD->getMemOperand());
}

SDValue PPCTargetLowering::DAGCombineBuildVector(SDNode *N,
                                                 DAGCombinerInfo &DCI) const {
  assert(N->getOpcode() == ISD::BUILD_VECTOR &&
         "Should be called with a BUILD_VECTOR node");

  SelectionDAG &DAG = DCI.DAG;
  SDLoc dl(N);

  if (!Subtarget.hasVSX())
    return SDValue();

  // The target independent DAG combiner will leave a build_vector of
  // float-to-int conversions intact. We can generate MUCH better code for
  // a float-to-int conversion of a vector of floats.
  SDValue FirstInput = N->getOperand(0);
  if (FirstInput.getOpcode() == PPCISD::MFVSR) {
    SDValue Reduced = combineElementTruncationToVectorTruncation(N, DCI);
    if (Reduced)
      return Reduced;
  }

  // If we're building a vector out of consecutive loads, just load that
  // vector type.
  SDValue Reduced = combineBVOfConsecutiveLoads(N, DAG);
  if (Reduced)
    return Reduced;

  // If we're building a vector out of extended elements from another vector
  // we have P9 vector integer extend instructions. The code assumes legal
  // input types (i.e. it can't handle things like v4i16) so do not run before
  // legalization.
  if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
    Reduced = combineBVOfVecSExt(N, DAG);
    if (Reduced)
      return Reduced;
  }

  // On Power10, the Load VSX Vector Rightmost instructions can be utilized
  // if this is a BUILD_VECTOR of v1i128, and if the operand to the BUILD_VECTOR
  // is a load from <valid narrow width> to i128.
  if (Subtarget.isISA3_1()) {
    SDValue BVOfZLoad = combineBVZEXTLOAD(N, DAG);
    if (BVOfZLoad)
      return BVOfZLoad;
  }

  if (N->getValueType(0) != MVT::v2f64)
    return SDValue();

  // Looking for:
  // (build_vector ([su]int_to_fp (extractelt 0)), [su]int_to_fp (extractelt 1))
  if (FirstInput.getOpcode() != ISD::SINT_TO_FP &&
      FirstInput.getOpcode() != ISD::UINT_TO_FP)
    return SDValue();
  if (N->getOperand(1).getOpcode() != ISD::SINT_TO_FP &&
      N->getOperand(1).getOpcode() != ISD::UINT_TO_FP)
    return SDValue();
  if (FirstInput.getOpcode() != N->getOperand(1).getOpcode())
    return SDValue();

  SDValue Ext1 = FirstInput.getOperand(0);
  SDValue Ext2 = N->getOperand(1).getOperand(0);
  if(Ext1.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
     Ext2.getOpcode() != ISD::EXTRACT_VECTOR_ELT)
    return SDValue();

  ConstantSDNode *Ext1Op = dyn_cast<ConstantSDNode>(Ext1.getOperand(1));
  ConstantSDNode *Ext2Op = dyn_cast<ConstantSDNode>(Ext2.getOperand(1));
  if (!Ext1Op || !Ext2Op)
    return SDValue();
  if (Ext1.getOperand(0).getValueType() != MVT::v4i32 ||
      Ext1.getOperand(0) != Ext2.getOperand(0))
    return SDValue();

  int FirstElem = Ext1Op->getZExtValue();
  int SecondElem = Ext2Op->getZExtValue();
  int SubvecIdx;
  if (FirstElem == 0 && SecondElem == 1)
    SubvecIdx = Subtarget.isLittleEndian() ? 1 : 0;
  else if (FirstElem == 2 && SecondElem == 3)
    SubvecIdx = Subtarget.isLittleEndian() ? 0 : 1;
  else
    return SDValue();

  SDValue SrcVec = Ext1.getOperand(0);
  auto NodeType = (N->getOperand(1).getOpcode() == ISD::SINT_TO_FP) ?
    PPCISD::SINT_VEC_TO_FP : PPCISD::UINT_VEC_TO_FP;
  return DAG.getNode(NodeType, dl, MVT::v2f64,
                     SrcVec, DAG.getIntPtrConstant(SubvecIdx, dl));
}

SDValue PPCTargetLowering::combineFPToIntToFP(SDNode *N,
                                              DAGCombinerInfo &DCI) const {
  assert((N->getOpcode() == ISD::SINT_TO_FP ||
          N->getOpcode() == ISD::UINT_TO_FP) &&
         "Need an int -> FP conversion node here");

  if (useSoftFloat() || !Subtarget.has64BitSupport())
    return SDValue();

  SelectionDAG &DAG = DCI.DAG;
  SDLoc dl(N);
  SDValue Op(N, 0);

  // Don't handle ppc_fp128 here or conversions that are out-of-range capable
  // from the hardware.
  if (Op.getValueType() != MVT::f32 && Op.getValueType() != MVT::f64)
    return SDValue();
  if (!Op.getOperand(0).getValueType().isSimple())
    return SDValue();
  if (Op.getOperand(0).getValueType().getSimpleVT() <= MVT(MVT::i1) ||
      Op.getOperand(0).getValueType().getSimpleVT() > MVT(MVT::i64))
    return SDValue();

  SDValue FirstOperand(Op.getOperand(0));
  bool SubWordLoad = FirstOperand.getOpcode() == ISD::LOAD &&
    (FirstOperand.getValueType() == MVT::i8 ||
     FirstOperand.getValueType() == MVT::i16);
  if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
    bool Signed = N->getOpcode() == ISD::SINT_TO_FP;
    bool DstDouble = Op.getValueType() == MVT::f64;
    unsigned ConvOp = Signed ?
      (DstDouble ? PPCISD::FCFID  : PPCISD::FCFIDS) :
      (DstDouble ? PPCISD::FCFIDU : PPCISD::FCFIDUS);
    SDValue WidthConst =
      DAG.getIntPtrConstant(FirstOperand.getValueType() == MVT::i8 ? 1 : 2,
                            dl, false);
    LoadSDNode *LDN = cast<LoadSDNode>(FirstOperand.getNode());
    SDValue Ops[] = { LDN->getChain(), LDN->getBasePtr(), WidthConst };
    SDValue Ld = DAG.getMemIntrinsicNode(PPCISD::LXSIZX, dl,
                                         DAG.getVTList(MVT::f64, MVT::Other),
                                         Ops, MVT::i8, LDN->getMemOperand());
    DAG.makeEquivalentMemoryOrdering(LDN, Ld);

    // For signed conversion, we need to sign-extend the value in the VSR
    if (Signed) {
      SDValue ExtOps[] = { Ld, WidthConst };
      SDValue Ext = DAG.getNode(PPCISD::VEXTS, dl, MVT::f64, ExtOps);
      return DAG.getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
    } else
      return DAG.getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
  }


  // For i32 intermediate values, unfortunately, the conversion functions
  // leave the upper 32 bits of the value are undefined. Within the set of
  // scalar instructions, we have no method for zero- or sign-extending the
  // value. Thus, we cannot handle i32 intermediate values here.
  if (Op.getOperand(0).getValueType() == MVT::i32)
    return SDValue();

  assert((Op.getOpcode() == ISD::SINT_TO_FP || Subtarget.hasFPCVT()) &&
         "UINT_TO_FP is supported only with FPCVT");

  // If we have FCFIDS, then use it when converting to single-precision.
  // Otherwise, convert to double-precision and then round.
  unsigned FCFOp = (Subtarget.hasFPCVT() && Op.getValueType() == MVT::f32)
                       ? (Op.getOpcode() == ISD::UINT_TO_FP ? PPCISD::FCFIDUS
                                                            : PPCISD::FCFIDS)
                       : (Op.getOpcode() == ISD::UINT_TO_FP ? PPCISD::FCFIDU
                                                            : PPCISD::FCFID);
  MVT FCFTy = (Subtarget.hasFPCVT() && Op.getValueType() == MVT::f32)
                  ? MVT::f32
                  : MVT::f64;

  // If we're converting from a float, to an int, and back to a float again,
  // then we don't need the store/load pair at all.
  if ((Op.getOperand(0).getOpcode() == ISD::FP_TO_UINT &&
       Subtarget.hasFPCVT()) ||
      (Op.getOperand(0).getOpcode() == ISD::FP_TO_SINT)) {
    SDValue Src = Op.getOperand(0).getOperand(0);
    if (Src.getValueType() == MVT::f32) {
      Src = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Src);
      DCI.AddToWorklist(Src.getNode());
    } else if (Src.getValueType() != MVT::f64) {
      // Make sure that we don't pick up a ppc_fp128 source value.
      return SDValue();
    }

    unsigned FCTOp =
      Op.getOperand(0).getOpcode() == ISD::FP_TO_SINT ? PPCISD::FCTIDZ :
                                                        PPCISD::FCTIDUZ;

    SDValue Tmp = DAG.getNode(FCTOp, dl, MVT::f64, Src);
    SDValue FP = DAG.getNode(FCFOp, dl, FCFTy, Tmp);

    if (Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
      FP = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, FP,
                       DAG.getIntPtrConstant(0, dl, /*isTarget=*/true));
      DCI.AddToWorklist(FP.getNode());
    }

    return FP;
  }

  return SDValue();
}

// expandVSXLoadForLE - Convert VSX loads (which may be intrinsics for
// builtins) into loads with swaps.
SDValue PPCTargetLowering::expandVSXLoadForLE(SDNode *N,
                                              DAGCombinerInfo &DCI) const {
  // Delay VSX load for LE combine until after LegalizeOps to prioritize other
  // load combines.
  if (DCI.isBeforeLegalizeOps())
    return SDValue();

  SelectionDAG &DAG = DCI.DAG;
  SDLoc dl(N);
  SDValue Chain;
  SDValue Base;
  MachineMemOperand *MMO;

  switch (N->getOpcode()) {
  default:
    llvm_unreachable("Unexpected opcode for little endian VSX load");
  case ISD::LOAD: {
    LoadSDNode *LD = cast<LoadSDNode>(N);
    Chain = LD->getChain();
    Base = LD->getBasePtr();
    MMO = LD->getMemOperand();
    // If the MMO suggests this isn't a load of a full vector, leave
    // things alone.  For a built-in, we have to make the change for
    // correctness, so if there is a size problem that will be a bug.
    if (!MMO->getSize().hasValue() || MMO->getSize().getValue() < 16)
      return SDValue();
    break;
  }
  case ISD::INTRINSIC_W_CHAIN: {
    MemIntrinsicSDNode *Intrin = cast<MemIntrinsicSDNode>(N);
    Chain = Intrin->getChain();
    // Similarly to the store case below, Intrin->getBasePtr() doesn't get
    // us what we want. Get operand 2 instead.
    Base = Intrin->getOperand(2);
    MMO = Intrin->getMemOperand();
    break;
  }
  }

  MVT VecTy = N->getValueType(0).getSimpleVT();

  SDValue LoadOps[] = { Chain, Base };
  SDValue Load = DAG.getMemIntrinsicNode(PPCISD::LXVD2X, dl,
                                         DAG.getVTList(MVT::v2f64, MVT::Other),
                                         LoadOps, MVT::v2f64, MMO);

  DCI.AddToWorklist(Load.getNode());
  Chain = Load.getValue(1);
  SDValue Swap = DAG.getNode(
      PPCISD::XXSWAPD, dl, DAG.getVTList(MVT::v2f64, MVT::Other), Chain, Load);
  DCI.AddToWorklist(Swap.getNode());

  // Add a bitcast if the resulting load type doesn't match v2f64.
  if (VecTy != MVT::v2f64) {
    SDValue N = DAG.getNode(ISD::BITCAST, dl, VecTy, Swap);
    DCI.AddToWorklist(N.getNode());
    // Package {bitcast value, swap's chain} to match Load's shape.
    return DAG.getNode(ISD::MERGE_VALUES, dl, DAG.getVTList(VecTy, MVT::Other),
                       N, Swap.getValue(1));
  }

  return Swap;
}

// expandVSXStoreForLE - Convert VSX stores (which may be intrinsics for
// builtins) into stores with swaps.
SDValue PPCTargetLowering::expandVSXStoreForLE(SDNode *N,
                                               DAGCombinerInfo &DCI) const {
  // Delay VSX store for LE combine until after LegalizeOps to prioritize other
  // store combines.
  if (DCI.isBeforeLegalizeOps())
    return SDValue();

  SelectionDAG &DAG = DCI.DAG;
  SDLoc dl(N);
  SDValue Chain;
  SDValue Base;
  unsigned SrcOpnd;
  MachineMemOperand *MMO;

  switch (N->getOpcode()) {
  default:
    llvm_unreachable("Unexpected opcode for little endian VSX store");
  case ISD::STORE: {
    StoreSDNode *ST = cast<StoreSDNode>(N);
    Chain = ST->getChain();
    Base = ST->getBasePtr();
    MMO = ST->getMemOperand();
    SrcOpnd = 1;
    // If the MMO suggests this isn't a store of a full vector, leave
    // things alone.  For a built-in, we have to make the change for
    // correctness, so if there is a size problem that will be a bug.
    if (!MMO->getSize().hasValue() || MMO->getSize().getValue() < 16)
      return SDValue();
    break;
  }
  case ISD::INTRINSIC_VOID: {
    MemIntrinsicSDNode *Intrin = cast<MemIntrinsicSDNode>(N);
    Chain = Intrin->getChain();
    // Intrin->getBasePtr() oddly does not get what we want.
    Base = Intrin->getOperand(3);
    MMO = Intrin->getMemOperand();
    SrcOpnd = 2;
    break;
  }
  }

  SDValue Src = N->getOperand(SrcOpnd);
  MVT VecTy = Src.getValueType().getSimpleVT();

  // All stores are done as v2f64 and possible bit cast.
  if (VecTy != MVT::v2f64) {
    Src = DAG.getNode(ISD::BITCAST, dl, MVT::v2f64, Src);
    DCI.AddToWorklist(Src.getNode());
  }

  SDValue Swap = DAG.getNode(PPCISD::XXSWAPD, dl,
                             DAG.getVTList(MVT::v2f64, MVT::Other), Chain, Src);
  DCI.AddToWorklist(Swap.getNode());
  Chain = Swap.getValue(1);
  SDValue StoreOps[] = { Chain, Swap, Base };
  SDValue Store = DAG.getMemIntrinsicNode(PPCISD::STXVD2X, dl,
                                          DAG.getVTList(MVT::Other),
                                          StoreOps, VecTy, MMO);
  DCI.AddToWorklist(Store.getNode());
  return Store;
}

// Handle DAG combine for STORE (FP_TO_INT F).
SDValue PPCTargetLowering::combineStoreFPToInt(SDNode *N,
                                               DAGCombinerInfo &DCI) const {
  SelectionDAG &DAG = DCI.DAG;
  SDLoc dl(N);
  unsigned Opcode = N->getOperand(1).getOpcode();
  (void)Opcode;
  bool Strict = N->getOperand(1)->isStrictFPOpcode();

  assert((Opcode == ISD::FP_TO_SINT || Opcode == ISD::FP_TO_UINT ||
          Opcode == ISD::STRICT_FP_TO_SINT || Opcode == ISD::STRICT_FP_TO_UINT)
         && "Not a FP_TO_INT Instruction!");

  SDValue Val = N->getOperand(1).getOperand(Strict ? 1 : 0);
  EVT Op1VT = N->getOperand(1).getValueType();
  EVT ResVT = Val.getValueType();

  if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !isTypeLegal(ResVT))
    return SDValue();

  // Only perform combine for conversion to i64/i32 or power9 i16/i8.
  bool ValidTypeForStoreFltAsInt =
        (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.isPPC64()) ||
         (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));

  // TODO: Lower conversion from f128 on all VSX targets
  if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
    return SDValue();

  if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
      cast<StoreSDNode>(N)->isTruncatingStore() || !ValidTypeForStoreFltAsInt)
    return SDValue();

  Val = convertFPToInt(N->getOperand(1), DAG, Subtarget);

  // Set number of bytes being converted.
  unsigned ByteSize = Op1VT.getScalarSizeInBits() / 8;
  SDValue Ops[] = {N->getOperand(0), Val, N->getOperand(2),
                   DAG.getIntPtrConstant(ByteSize, dl, false),
                   DAG.getValueType(Op1VT)};

  Val = DAG.getMemIntrinsicNode(PPCISD::ST_VSR_SCAL_INT, dl,
          DAG.getVTList(MVT::Other), Ops,
          cast<StoreSDNode>(N)->getMemoryVT(),
          cast<StoreSDNode>(N)->getMemOperand());

  return Val;
}

static bool isAlternatingShuffMask(const ArrayRef<int> &Mask, int NumElts) {
  // Check that the source of the element keeps flipping
  // (i.e. Mask[i] < NumElts -> Mask[i+i] >= NumElts).
  bool PrevElemFromFirstVec = Mask[0] < NumElts;
  for (int i = 1, e = Mask.size(); i < e; i++) {
    if (PrevElemFromFirstVec && Mask[i] < NumElts)
      return false;
    if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
      return false;
    PrevElemFromFirstVec = !PrevElemFromFirstVec;
  }
  return true;
}

static bool isSplatBV(SDValue Op) {
  if (Op.getOpcode() != ISD::BUILD_VECTOR)
    return false;
  SDValue FirstOp;

  // Find first non-undef input.
  for (int i = 0, e = Op.getNumOperands(); i < e; i++) {
    FirstOp = Op.getOperand(i);
    if (!FirstOp.isUndef())
      break;
  }

  // All inputs are undef or the same as the first non-undef input.
  for (int i = 1, e = Op.getNumOperands(); i < e; i++)
    if (Op.getOperand(i) != FirstOp && !Op.getOperand(i).isUndef())
      return false;
  return true;
}

static SDValue isScalarToVec(SDValue Op) {
  if (Op.getOpcode() == ISD::SCALAR_TO_VECTOR)
    return Op;
  if (Op.getOpcode() != ISD::BITCAST)
    return SDValue();
  Op = Op.getOperand(0);
  if (Op.getOpcode() == ISD::SCALAR_TO_VECTOR)
    return Op;
  return SDValue();
}

// Fix up the shuffle mask to account for the fact that the result of
// scalar_to_vector is not in lane zero. This just takes all values in
// the ranges specified by the min/max indices and adds the number of
// elements required to ensure each element comes from the respective
// position in the valid lane.
// On little endian, that's just the corresponding element in the other
// half of the vector. On big endian, it is in the same half but right
// justified rather than left justified in that half.
static void fixupShuffleMaskForPermutedSToV(
    SmallVectorImpl<int> &ShuffV, int LHSFirstElt, int LHSLastElt,
    int RHSFirstElt, int RHSLastElt, int HalfVec, unsigned LHSNumValidElts,
    unsigned RHSNumValidElts, const PPCSubtarget &Subtarget) {
  int LHSEltFixup =
      Subtarget.isLittleEndian() ? HalfVec : HalfVec - LHSNumValidElts;
  int RHSEltFixup =
      Subtarget.isLittleEndian() ? HalfVec : HalfVec - RHSNumValidElts;
  for (int I = 0, E = ShuffV.size(); I < E; ++I) {
    int Idx = ShuffV[I];
    if (Idx >= LHSFirstElt && Idx <= LHSLastElt)
      ShuffV[I] += LHSEltFixup;
    else if (Idx >= RHSFirstElt && Idx <= RHSLastElt)
      ShuffV[I] += RHSEltFixup;
  }
}

// Replace a SCALAR_TO_VECTOR with a SCALAR_TO_VECTOR_PERMUTED except if
// the original is:
// (<n x Ty> (scalar_to_vector (Ty (extract_elt <n x Ty> %a, C))))
// In such a case, just change the shuffle mask to extract the element
// from the permuted index.
static SDValue getSToVPermuted(SDValue OrigSToV, SelectionDAG &DAG,
                               const PPCSubtarget &Subtarget) {
  SDLoc dl(OrigSToV);
  EVT VT = OrigSToV.getValueType();
  assert(OrigSToV.getOpcode() == ISD::SCALAR_TO_VECTOR &&
         "Expecting a SCALAR_TO_VECTOR here");
  SDValue Input = OrigSToV.getOperand(0);

  if (Input.getOpcode() == ISD::EXTRACT_VECTOR_ELT) {
    ConstantSDNode *Idx = dyn_cast<ConstantSDNode>(Input.getOperand(1));
    SDValue OrigVector = Input.getOperand(0);

    // Can't handle non-const element indices or different vector types
    // for the input to the extract and the output of the scalar_to_vector.
    if (Idx && VT == OrigVector.getValueType()) {
      unsigned NumElts = VT.getVectorNumElements();
      assert(
          NumElts > 1 &&
          "Cannot produce a permuted scalar_to_vector for one element vector");
      SmallVector<int, 16> NewMask(NumElts, -1);
      unsigned ResultInElt = NumElts / 2;
      ResultInElt -= Subtarget.isLittleEndian() ? 0 : 1;
      NewMask[ResultInElt] = Idx->getZExtValue();
      return DAG.getVectorShuffle(VT, dl, OrigVector, OrigVector, NewMask);
    }
  }
  return DAG.getNode(PPCISD::SCALAR_TO_VECTOR_PERMUTED, dl, VT,
                     OrigSToV.getOperand(0));
}

static bool isShuffleMaskInRange(const SmallVectorImpl<int> &ShuffV,
                                 int HalfVec, int LHSLastElementDefined,
                                 int RHSLastElementDefined) {
  for (int Index : ShuffV) {
    if (Index < 0) // Skip explicitly undefined mask indices.
      continue;
    // Handle first input vector of the vector_shuffle.
    if ((LHSLastElementDefined >= 0) && (Index < HalfVec) &&
        (Index > LHSLastElementDefined))
      return false;
    // Handle second input vector of the vector_shuffle.
    if ((RHSLastElementDefined >= 0) &&
        (Index > HalfVec + RHSLastElementDefined))
      return false;
  }
  return true;
}

static SDValue generateSToVPermutedForVecShuffle(
    int ScalarSize, uint64_t ShuffleEltWidth, unsigned &NumValidElts,
    int FirstElt, int &LastElt, SDValue VecShuffOperand, SDValue SToVNode,
    SelectionDAG &DAG, const PPCSubtarget &Subtarget) {
  EVT VecShuffOperandType = VecShuffOperand.getValueType();
  // Set up the values for the shuffle vector fixup.
  NumValidElts = ScalarSize / VecShuffOperandType.getScalarSizeInBits();
  // The last element depends on if the input comes from the LHS or RHS.
  //
  // For example:
  // (shuff (s_to_v i32), (bitcast (s_to_v i64), v4i32), ...)
  //
  // For the LHS: The last element that comes from the LHS is actually 0, not 3
  // because elements 1 and higher of a scalar_to_vector are undefined.
  // For the RHS: The last element that comes from the RHS is actually 5, not 7
  // because elements 1 and higher of a scalar_to_vector are undefined.
  // It is also not 4 because the original scalar_to_vector is wider and
  // actually contains two i32 elements.
  LastElt = (uint64_t)ScalarSize > ShuffleEltWidth
                ? ScalarSize / ShuffleEltWidth - 1 + FirstElt
                : FirstElt;
  SDValue SToVPermuted = getSToVPermuted(SToVNode, DAG, Subtarget);
  if (SToVPermuted.getValueType() != VecShuffOperandType)
    SToVPermuted = DAG.getBitcast(VecShuffOperandType, SToVPermuted);
  return SToVPermuted;
}

// On little endian subtargets, combine shuffles such as:
// vector_shuffle<16,1,17,3,18,5,19,7,20,9,21,11,22,13,23,15>, <zero>, %b
// into:
// vector_shuffle<16,0,17,1,18,2,19,3,20,4,21,5,22,6,23,7>, <zero>, %b
// because the latter can be matched to a single instruction merge.
// Furthermore, SCALAR_TO_VECTOR on little endian always involves a permute
// to put the value into element zero. Adjust the shuffle mask so that the
// vector can remain in permuted form (to prevent a swap prior to a shuffle).
// On big endian targets, this is still useful for SCALAR_TO_VECTOR
// nodes with elements smaller than doubleword because all the ways
// of getting scalar data into a vector register put the value in the
// rightmost element of the left half of the vector.
SDValue PPCTargetLowering::combineVectorShuffle(ShuffleVectorSDNode *SVN,
                                                SelectionDAG &DAG) const {
  SDValue LHS = SVN->getOperand(0);
  SDValue RHS = SVN->getOperand(1);
  auto Mask = SVN->getMask();
  int NumElts = LHS.getValueType().getVectorNumElements();
  SDValue Res(SVN, 0);
  SDLoc dl(SVN);
  bool IsLittleEndian = Subtarget.isLittleEndian();

  // On big endian targets this is only useful for subtargets with direct moves.
  // On little endian targets it would be useful for all subtargets with VSX.
  // However adding special handling for LE subtargets without direct moves
  // would be wasted effort since the minimum arch for LE is ISA 2.07 (Power8)
  // which includes direct moves.
  if (!Subtarget.hasDirectMove())
    return Res;

  // If this is not a shuffle of a shuffle and the first element comes from
  // the second vector, canonicalize to the commuted form. This will make it
  // more likely to match one of the single instruction patterns.
  if (Mask[0] >= NumElts && LHS.getOpcode() != ISD::VECTOR_SHUFFLE &&
      RHS.getOpcode() != ISD::VECTOR_SHUFFLE) {
    std::swap(LHS, RHS);
    Res = DAG.getCommutedVectorShuffle(*SVN);

    if (!isa<ShuffleVectorSDNode>(Res))
      return Res;

    Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
  }

  // Adjust the shuffle mask if either input vector comes from a
  // SCALAR_TO_VECTOR and keep the respective input vector in permuted
  // form (to prevent the need for a swap).
  SmallVector<int, 16> ShuffV(Mask);
  SDValue SToVLHS = isScalarToVec(LHS);
  SDValue SToVRHS = isScalarToVec(RHS);
  if (SToVLHS || SToVRHS) {
    EVT VT = SVN->getValueType(0);
    uint64_t ShuffleEltWidth = VT.getVectorElementType().getSizeInBits();
    int ShuffleNumElts = ShuffV.size();
    int HalfVec = ShuffleNumElts / 2;
    // The width of the "valid lane" (i.e. the lane that contains the value that
    // is vectorized) needs to be expressed in terms of the number of elements
    // of the shuffle. It is thereby the ratio of the values before and after
    // any bitcast, which will be set later on if the LHS or RHS are
    // SCALAR_TO_VECTOR nodes.
    unsigned LHSNumValidElts = HalfVec;
    unsigned RHSNumValidElts = HalfVec;

    // Initially assume that neither input is permuted. These will be adjusted
    // accordingly if either input is. Note, that -1 means that all elements
    // are undefined.
    int LHSFirstElt = 0;
    int RHSFirstElt = ShuffleNumElts;
    int LHSLastElt = -1;
    int RHSLastElt = -1;

    // Get the permuted scalar to vector nodes for the source(s) that come from
    // ISD::SCALAR_TO_VECTOR.
    // On big endian systems, this only makes sense for element sizes smaller
    // than 64 bits since for 64-bit elements, all instructions already put
    // the value into element zero. Since scalar size of LHS and RHS may differ
    // after isScalarToVec, this should be checked using their own sizes.
    int LHSScalarSize = 0;
    int RHSScalarSize = 0;
    if (SToVLHS) {
      LHSScalarSize = SToVLHS.getValueType().getScalarSizeInBits();
      if (!IsLittleEndian && LHSScalarSize >= 64)
        return Res;
    }
    if (SToVRHS) {
      RHSScalarSize = SToVRHS.getValueType().getScalarSizeInBits();
      if (!IsLittleEndian && RHSScalarSize >= 64)
        return Res;
    }
    if (LHSScalarSize != 0)
      LHS = generateSToVPermutedForVecShuffle(
          LHSScalarSize, ShuffleEltWidth, LHSNumValidElts, LHSFirstElt,
          LHSLastElt, LHS, SToVLHS, DAG, Subtarget);
    if (RHSScalarSize != 0)
      RHS = generateSToVPermutedForVecShuffle(
          RHSScalarSize, ShuffleEltWidth, RHSNumValidElts, RHSFirstElt,
          RHSLastElt, RHS, SToVRHS, DAG, Subtarget);

    if (!isShuffleMaskInRange(ShuffV, HalfVec, LHSLastElt, RHSLastElt))
      return Res;

    // Fix up the shuffle mask to reflect where the desired element actually is.
    // The minimum and maximum indices that correspond to element zero for both
    // the LHS and RHS are computed and will control which shuffle mask entries
    // are to be changed. For example, if the RHS is permuted, any shuffle mask
    // entries in the range [RHSFirstElt,RHSLastElt] will be adjusted.
    fixupShuffleMaskForPermutedSToV(
        ShuffV, LHSFirstElt, LHSLastElt, RHSFirstElt, RHSLastElt, HalfVec,
        LHSNumValidElts, RHSNumValidElts, Subtarget);
    Res = DAG.getVectorShuffle(SVN->getValueType(0), dl, LHS, RHS, ShuffV);

    // We may have simplified away the shuffle. We won't be able to do anything
    // further with it here.
    if (!isa<ShuffleVectorSDNode>(Res))
      return Res;
    Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
  }

  SDValue TheSplat = IsLittleEndian ? RHS : LHS;
  // The common case after we commuted the shuffle is that the RHS is a splat
  // and we have elements coming in from the splat at indices that are not
  // conducive to using a merge.
  // Example:
  // vector_shuffle<0,17,1,19,2,21,3,23,4,25,5,27,6,29,7,31> t1, <zero>
  if (!isSplatBV(TheSplat))
    return Res;

  // We are looking for a mask such that all even elements are from
  // one vector and all odd elements from the other.
  if (!isAlternatingShuffMask(Mask, NumElts))
    return Res;

  // Adjust the mask so we are pulling in the same index from the splat
  // as the index from the interesting vector in consecutive elements.
  if (IsLittleEndian) {
    // Example (even elements from first vector):
    // vector_shuffle<0,16,1,17,2,18,3,19,4,20,5,21,6,22,7,23> t1, <zero>
    if (Mask[0] < NumElts)
      for (int i = 1, e = Mask.size(); i < e; i += 2) {
        if (ShuffV[i] < 0)
          continue;
        // If element from non-splat is undef, pick first element from splat.
        ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
      }
    // Example (odd elements from first vector):
    // vector_shuffle<16,0,17,1,18,2,19,3,20,4,21,5,22,6,23,7> t1, <zero>
    else
      for (int i = 0, e = Mask.size(); i < e; i += 2) {
        if (ShuffV[i] < 0)
          continue;
        // If element from non-splat is undef, pick first element from splat.
        ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
      }
  } else {
    // Example (even elements from first vector):
    // vector_shuffle<0,16,1,17,2,18,3,19,4,20,5,21,6,22,7,23> <zero>, t1
    if (Mask[0] < NumElts)
      for (int i = 0, e = Mask.size(); i < e; i += 2) {
        if (ShuffV[i] < 0)
          continue;
        // If element from non-splat is undef, pick first element from splat.
        ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
      }
    // Example (odd elements from first vector):
    // vector_shuffle<16,0,17,1,18,2,19,3,20,4,21,5,22,6,23,7> <zero>, t1
    else
      for (int i = 1, e = Mask.size(); i < e; i += 2) {
        if (ShuffV[i] < 0)
          continue;
        // If element from non-splat is undef, pick first element from splat.
        ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
      }
  }

  // If the RHS has undefs, we need to remove them since we may have created
  // a shuffle that adds those instead of the splat value.
  SDValue SplatVal =
      cast<BuildVectorSDNode>(TheSplat.getNode())->getSplatValue();
  TheSplat = DAG.getSplatBuildVector(TheSplat.getValueType(), dl, SplatVal);

  if (IsLittleEndian)
    RHS = TheSplat;
  else
    LHS = TheSplat;
  return DAG.getVectorShuffle(SVN->getValueType(0), dl, LHS, RHS, ShuffV);
}

SDValue PPCTargetLowering::combineVReverseMemOP(ShuffleVectorSDNode *SVN,
                                                LSBaseSDNode *LSBase,
                                                DAGCombinerInfo &DCI) const {
  assert((ISD::isNormalLoad(LSBase) || ISD::isNormalStore(LSBase)) &&
        "Not a reverse memop pattern!");

  auto IsElementReverse = [](const ShuffleVectorSDNode *SVN) -> bool {
    auto Mask = SVN->getMask();
    int i = 0;
    auto I = Mask.rbegin();
    auto E = Mask.rend();

    for (; I != E; ++I) {
      if (*I != i)
        return false;
      i++;
    }
    return true;
  };

  SelectionDAG &DAG = DCI.DAG;
  EVT VT = SVN->getValueType(0);

  if (!isTypeLegal(VT) || !Subtarget.isLittleEndian() || !Subtarget.hasVSX())
    return SDValue();

  // Before P9, we have PPCVSXSwapRemoval pass to hack the element order.
  // See comment in PPCVSXSwapRemoval.cpp.
  // It is conflict with PPCVSXSwapRemoval opt. So we don't do it.
  if (!Subtarget.hasP9Vector())
    return SDValue();

  if(!IsElementReverse(SVN))
    return SDValue();

  if (LSBase->getOpcode() == ISD::LOAD) {
    // If the load return value 0 has more than one user except the
    // shufflevector instruction, it is not profitable to replace the
    // shufflevector with a reverse load.
    for (SDUse &Use : LSBase->uses())
      if (Use.getResNo() == 0 &&
          Use.getUser()->getOpcode() != ISD::VECTOR_SHUFFLE)
        return SDValue();

    SDLoc dl(LSBase);
    SDValue LoadOps[] = {LSBase->getChain(), LSBase->getBasePtr()};
    return DAG.getMemIntrinsicNode(
        PPCISD::LOAD_VEC_BE, dl, DAG.getVTList(VT, MVT::Other), LoadOps,
        LSBase->getMemoryVT(), LSBase->getMemOperand());
  }

  if (LSBase->getOpcode() == ISD::STORE) {
    // If there are other uses of the shuffle, the swap cannot be avoided.
    // Forcing the use of an X-Form (since swapped stores only have
    // X-Forms) without removing the swap is unprofitable.
    if (!SVN->hasOneUse())
      return SDValue();

    SDLoc dl(LSBase);
    SDValue StoreOps[] = {LSBase->getChain(), SVN->getOperand(0),
                          LSBase->getBasePtr()};
    return DAG.getMemIntrinsicNode(
        PPCISD::STORE_VEC_BE, dl, DAG.getVTList(MVT::Other), StoreOps,
        LSBase->getMemoryVT(), LSBase->getMemOperand());
  }

  llvm_unreachable("Expected a load or store node here");
}

static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth) {
  unsigned IntrinsicID = Intrin.getConstantOperandVal(1);
  if (IntrinsicID == Intrinsic::ppc_stdcx)
    StoreWidth = 8;
  else if (IntrinsicID == Intrinsic::ppc_stwcx)
    StoreWidth = 4;
  else if (IntrinsicID == Intrinsic::ppc_sthcx)
    StoreWidth = 2;
  else if (IntrinsicID == Intrinsic::ppc_stbcx)
    StoreWidth = 1;
  else
    return false;
  return true;
}

static SDValue DAGCombineAddc(SDNode *N,
                              llvm::PPCTargetLowering::DAGCombinerInfo &DCI) {
  if (N->getOpcode() == PPCISD::ADDC && N->hasAnyUseOfValue(1)) {
    // (ADDC (ADDE 0, 0, C), -1) -> C
    SDValue LHS = N->getOperand(0);
    SDValue RHS = N->getOperand(1);
    if (LHS->getOpcode() == PPCISD::ADDE &&
        isNullConstant(LHS->getOperand(0)) &&
        isNullConstant(LHS->getOperand(1)) && isAllOnesConstant(RHS)) {
      return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
    }
  }
  return SDValue();
}

SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
                                             DAGCombinerInfo &DCI) const {
  SelectionDAG &DAG = DCI.DAG;
  SDLoc dl(N);
  switch (N->getOpcode()) {
  default: break;
  case ISD::ADD:
    return combineADD(N, DCI);
  case ISD::AND: {
    // We don't want (and (zext (shift...)), C) if C fits in the width of the
    // original input as that will prevent us from selecting optimal rotates.
    // This only matters if the input to the extend is i32 widened to i64.
    SDValue Op1 = N->getOperand(0);
    SDValue Op2 = N->getOperand(1);
    if ((Op1.getOpcode() != ISD::ZERO_EXTEND &&
         Op1.getOpcode() != ISD::ANY_EXTEND) ||
        !isa<ConstantSDNode>(Op2) || N->getValueType(0) != MVT::i64 ||
        Op1.getOperand(0).getValueType() != MVT::i32)
      break;
    SDValue NarrowOp = Op1.getOperand(0);
    if (NarrowOp.getOpcode() != ISD::SHL && NarrowOp.getOpcode() != ISD::SRL &&
        NarrowOp.getOpcode() != ISD::ROTL && NarrowOp.getOpcode() != ISD::ROTR)
      break;

    uint64_t Imm = Op2->getAsZExtVal();
    // Make sure that the constant is narrow enough to fit in the narrow type.
    if (!isUInt<32>(Imm))
      break;
    SDValue ConstOp = DAG.getConstant(Imm, dl, MVT::i32);
    SDValue NarrowAnd = DAG.getNode(ISD::AND, dl, MVT::i32, NarrowOp, ConstOp);
    return DAG.getZExtOrTrunc(NarrowAnd, dl, N->getValueType(0));
  }
  case ISD::SHL:
    return combineSHL(N, DCI);
  case ISD::SRA:
    return combineSRA(N, DCI);
  case ISD::SRL:
    return combineSRL(N, DCI);
  case ISD::MUL:
    return combineMUL(N, DCI);
  case ISD::FMA:
  case PPCISD::FNMSUB:
    return combineFMALike(N, DCI);
  case PPCISD::SHL:
    if (isNullConstant(N->getOperand(0))) // 0 << V -> 0.
        return N->getOperand(0);
    break;
  case PPCISD::SRL:
    if (isNullConstant(N->getOperand(0))) // 0 >>u V -> 0.
        return N->getOperand(0);
    break;
  case PPCISD::SRA:
    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(0))) {
      if (C->isZero() ||  //  0 >>s V -> 0.
          C->isAllOnes()) // -1 >>s V -> -1.
        return N->getOperand(0);
    }
    break;
  case ISD::SIGN_EXTEND:
  case ISD::ZERO_EXTEND:
  case ISD::ANY_EXTEND:
    return DAGCombineExtBoolTrunc(N, DCI);
  case ISD::TRUNCATE:
    return combineTRUNCATE(N, DCI);
  case ISD::SETCC:
    if (SDValue CSCC = combineSetCC(N, DCI))
      return CSCC;
    [[fallthrough]];
  case ISD::SELECT_CC:
    return DAGCombineTruncBoolExt(N, DCI);
  case ISD::SINT_TO_FP:
  case ISD::UINT_TO_FP:
    return combineFPToIntToFP(N, DCI);
  case ISD::VECTOR_SHUFFLE:
    if (ISD::isNormalLoad(N->getOperand(0).getNode())) {
      LSBaseSDNode* LSBase = cast<LSBaseSDNode>(N->getOperand(0));
      return combineVReverseMemOP(cast<ShuffleVectorSDNode>(N), LSBase, DCI);
    }
    return combineVectorShuffle(cast<ShuffleVectorSDNode>(N), DCI.DAG);
  case ISD::STORE: {

    EVT Op1VT = N->getOperand(1).getValueType();
    unsigned Opcode = N->getOperand(1).getOpcode();

    if (Opcode == ISD::FP_TO_SINT || Opcode == ISD::FP_TO_UINT ||
        Opcode == ISD::STRICT_FP_TO_SINT || Opcode == ISD::STRICT_FP_TO_UINT) {
      SDValue Val = combineStoreFPToInt(N, DCI);
      if (Val)
        return Val;
    }

    if (Opcode == ISD::VECTOR_SHUFFLE && ISD::isNormalStore(N)) {
      ShuffleVectorSDNode *SVN = cast<ShuffleVectorSDNode>(N->getOperand(1));
      SDValue Val= combineVReverseMemOP(SVN, cast<LSBaseSDNode>(N), DCI);
      if (Val)
        return Val;
    }

    // Turn STORE (BSWAP) -> sthbrx/stwbrx.
    if (cast<StoreSDNode>(N)->isUnindexed() && Opcode == ISD::BSWAP &&
        N->getOperand(1).getNode()->hasOneUse() &&
        (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
         (Subtarget.hasLDBRX() && Subtarget.isPPC64() && Op1VT == MVT::i64))) {

      // STBRX can only handle simple types and it makes no sense to store less
      // two bytes in byte-reversed order.
      EVT mVT = cast<StoreSDNode>(N)->getMemoryVT();
      if (mVT.isExtended() || mVT.getSizeInBits() < 16)
        break;

      SDValue BSwapOp = N->getOperand(1).getOperand(0);
      // Do an any-extend to 32-bits if this is a half-word input.
      if (BSwapOp.getValueType() == MVT::i16)
        BSwapOp = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, BSwapOp);

      // If the type of BSWAP operand is wider than stored memory width
      // it need to be shifted to the right side before STBRX.
      if (Op1VT.bitsGT(mVT)) {
        int Shift = Op1VT.getSizeInBits() - mVT.getSizeInBits();
        BSwapOp = DAG.getNode(ISD::SRL, dl, Op1VT, BSwapOp,
                              DAG.getConstant(Shift, dl, MVT::i32));
        // Need to truncate if this is a bswap of i64 stored as i32/i16.
        if (Op1VT == MVT::i64)
          BSwapOp = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, BSwapOp);
      }

      SDValue Ops[] = {
        N->getOperand(0), BSwapOp, N->getOperand(2), DAG.getValueType(mVT)
      };
      return
        DAG.getMemIntrinsicNode(PPCISD::STBRX, dl, DAG.getVTList(MVT::Other),
                                Ops, cast<StoreSDNode>(N)->getMemoryVT(),
                                cast<StoreSDNode>(N)->getMemOperand());
    }

    // STORE Constant:i32<0>  ->  STORE<trunc to i32> Constant:i64<0>
    // So it can increase the chance of CSE constant construction.
    if (Subtarget.isPPC64() && !DCI.isBeforeLegalize() &&
        isa<ConstantSDNode>(N->getOperand(1)) && Op1VT == MVT::i32) {
      // Need to sign-extended to 64-bits to handle negative values.
      EVT MemVT = cast<StoreSDNode>(N)->getMemoryVT();
      uint64_t Val64 = SignExtend64(N->getConstantOperandVal(1),
                                    MemVT.getSizeInBits());
      SDValue Const64 = DAG.getConstant(Val64, dl, MVT::i64);

      auto *ST = cast<StoreSDNode>(N);
      SDValue NewST = DAG.getStore(ST->getChain(), dl, Const64,
                                   ST->getBasePtr(), ST->getOffset(), MemVT,
                                   ST->getMemOperand(), ST->getAddressingMode(),
                                   /*IsTruncating=*/true);
      // Note we use CombineTo here to prevent DAGCombiner from visiting the
      // new store which will change the constant by removing non-demanded bits.
      return ST->isUnindexed()
                 ? DCI.CombineTo(N, NewST, /*AddTo=*/false)
                 : DCI.CombineTo(N, NewST, NewST.getValue(1), /*AddTo=*/false);
    }

    // For little endian, VSX stores require generating xxswapd/lxvd2x.
    // Not needed on ISA 3.0 based CPUs since we have a non-permuting store.
    if (Op1VT.isSimple()) {
      MVT StoreVT = Op1VT.getSimpleVT();
      if (Subtarget.needsSwapsForVSXMemOps() &&
          (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
           StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
        return expandVSXStoreForLE(N, DCI);
    }
    break;
  }
  case ISD::LOAD: {
    LoadSDNode *LD = cast<LoadSDNode>(N);
    EVT VT = LD->getValueType(0);

    // For little endian, VSX loads require generating lxvd2x/xxswapd.
    // Not needed on ISA 3.0 based CPUs since we have a non-permuting load.
    if (VT.isSimple()) {
      MVT LoadVT = VT.getSimpleVT();
      if (Subtarget.needsSwapsForVSXMemOps() &&
          (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
           LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
        return expandVSXLoadForLE(N, DCI);
    }

    // We sometimes end up with a 64-bit integer load, from which we extract
    // two single-precision floating-point numbers. This happens with
    // std::complex<float>, and other similar structures, because of the way we
    // canonicalize structure copies. However, if we lack direct moves,
    // then the final bitcasts from the extracted integer values to the
    // floating-point numbers turn into store/load pairs. Even with direct moves,
    // just loading the two floating-point numbers is likely better.
    auto ReplaceTwoFloatLoad = [&]() {
      if (VT != MVT::i64)
        return false;

      if (LD->getExtensionType() != ISD::NON_EXTLOAD ||
          LD->isVolatile())
        return false;

      //  We're looking for a sequence like this:
      //  t13: i64,ch = load<LD8[%ref.tmp]> t0, t6, undef:i64
      //      t16: i64 = srl t13, Constant:i32<32>
      //    t17: i32 = truncate t16
      //  t18: f32 = bitcast t17
      //    t19: i32 = truncate t13
      //  t20: f32 = bitcast t19

      if (!LD->hasNUsesOfValue(2, 0))
        return false;

      auto UI = LD->user_begin();
      while (UI.getUse().getResNo() != 0) ++UI;
      SDNode *Trunc = *UI++;
      while (UI.getUse().getResNo() != 0) ++UI;
      SDNode *RightShift = *UI;
      if (Trunc->getOpcode() != ISD::TRUNCATE)
        std::swap(Trunc, RightShift);

      if (Trunc->getOpcode() != ISD::TRUNCATE ||
          Trunc->getValueType(0) != MVT::i32 ||
          !Trunc->hasOneUse())
        return false;
      if (RightShift->getOpcode() != ISD::SRL ||
          !isa<ConstantSDNode>(RightShift->getOperand(1)) ||
          RightShift->getConstantOperandVal(1) != 32 ||
          !RightShift->hasOneUse())
        return false;

      SDNode *Trunc2 = *RightShift->user_begin();
      if (Trunc2->getOpcode() != ISD::TRUNCATE ||
          Trunc2->getValueType(0) != MVT::i32 ||
          !Trunc2->hasOneUse())
        return false;

      SDNode *Bitcast = *Trunc->user_begin();
      SDNode *Bitcast2 = *Trunc2->user_begin();

      if (Bitcast->getOpcode() != ISD::BITCAST ||
          Bitcast->getValueType(0) != MVT::f32)
        return false;
      if (Bitcast2->getOpcode() != ISD::BITCAST ||
          Bitcast2->getValueType(0) != MVT::f32)
        return false;

      if (Subtarget.isLittleEndian())
        std::swap(Bitcast, Bitcast2);

      // Bitcast has the second float (in memory-layout order) and Bitcast2
      // has the first one.

      SDValue BasePtr = LD->getBasePtr();
      if (LD->isIndexed()) {
        assert(LD->getAddressingMode() == ISD::PRE_INC &&
               "Non-pre-inc AM on PPC?");
        BasePtr =
          DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr,
                      LD->getOffset());
      }

      auto MMOFlags =
          LD->getMemOperand()->getFlags() & ~MachineMemOperand::MOVolatile;
      SDValue FloatLoad = DAG.getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
                                      LD->getPointerInfo(), LD->getAlign(),
                                      MMOFlags, LD->getAAInfo());
      SDValue AddPtr =
        DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(),
                    BasePtr, DAG.getIntPtrConstant(4, dl));
      SDValue FloatLoad2 = DAG.getLoad(
          MVT::f32, dl, SDValue(FloatLoad.getNode(), 1), AddPtr,
          LD->getPointerInfo().getWithOffset(4),
          commonAlignment(LD->getAlign(), 4), MMOFlags, LD->getAAInfo());

      if (LD->isIndexed()) {
        // Note that DAGCombine should re-form any pre-increment load(s) from
        // what is produced here if that makes sense.
        DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), BasePtr);
      }

      DCI.CombineTo(Bitcast2, FloatLoad);
      DCI.CombineTo(Bitcast, FloatLoad2);

      DAG.ReplaceAllUsesOfValueWith(SDValue(LD, LD->isIndexed() ? 2 : 1),
                                    SDValue(FloatLoad2.getNode(), 1));
      return true;
    };

    if (ReplaceTwoFloatLoad())
      return SDValue(N, 0);

    EVT MemVT = LD->getMemoryVT();
    Type *Ty = MemVT.getTypeForEVT(*DAG.getContext());
    Align ABIAlignment = DAG.getDataLayout().getABITypeAlign(Ty);
    if (LD->isUnindexed() && VT.isVector() &&
        ((Subtarget.hasAltivec() && ISD::isNON_EXTLoad(N) &&
          // P8 and later hardware should just use LOAD.
          !Subtarget.hasP8Vector() &&
          (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
           VT == MVT::v4f32))) &&
        LD->getAlign() < ABIAlignment) {
      // This is a type-legal unaligned Altivec load.
      SDValue Chain = LD->getChain();
      SDValue Ptr = LD->getBasePtr();
      bool isLittleEndian = Subtarget.isLittleEndian();

      // This implements the loading of unaligned vectors as described in
      // the venerable Apple Velocity Engine overview. Specifically:
      // https://developer.apple.com/hardwaredrivers/ve/alignment.html
      // https://developer.apple.com/hardwaredrivers/ve/code_optimization.html
      //
      // The general idea is to expand a sequence of one or more unaligned
      // loads into an alignment-based permutation-control instruction (lvsl
      // or lvsr), a series of regular vector loads (which always truncate
      // their input address to an aligned address), and a series of
      // permutations.  The results of these permutations are the requested
      // loaded values.  The trick is that the last "extra" load is not taken
      // from the address you might suspect (sizeof(vector) bytes after the
      // last requested load), but rather sizeof(vector) - 1 bytes after the
      // last requested vector. The point of this is to avoid a page fault if
      // the base address happened to be aligned. This works because if the
      // base address is aligned, then adding less than a full vector length
      // will cause the last vector in the sequence to be (re)loaded.
      // Otherwise, the next vector will be fetched as you might suspect was
      // necessary.

      // We might be able to reuse the permutation generation from
      // a different base address offset from this one by an aligned amount.
      // The INTRINSIC_WO_CHAIN DAG combine will attempt to perform this
      // optimization later.
      Intrinsic::ID Intr, IntrLD, IntrPerm;
      MVT PermCntlTy, PermTy, LDTy;
      Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
                            : Intrinsic::ppc_altivec_lvsl;
      IntrLD = Intrinsic::ppc_altivec_lvx;
      IntrPerm = Intrinsic::ppc_altivec_vperm;
      PermCntlTy = MVT::v16i8;
      PermTy = MVT::v4i32;
      LDTy = MVT::v4i32;

      SDValue PermCntl = BuildIntrinsicOp(Intr, Ptr, DAG, dl, PermCntlTy);

      // Create the new MMO for the new base load. It is like the original MMO,
      // but represents an area in memory almost twice the vector size centered
      // on the original address. If the address is unaligned, we might start
      // reading up to (sizeof(vector)-1) bytes below the address of the
      // original unaligned load.
      MachineFunction &MF = DAG.getMachineFunction();
      MachineMemOperand *BaseMMO =
        MF.getMachineMemOperand(LD->getMemOperand(),
                                -(int64_t)MemVT.getStoreSize()+1,
                                2*MemVT.getStoreSize()-1);

      // Create the new base load.
      SDValue LDXIntID =
          DAG.getTargetConstant(IntrLD, dl, getPointerTy(MF.getDataLayout()));
      SDValue BaseLoadOps[] = { Chain, LDXIntID, Ptr };
      SDValue BaseLoad =
        DAG.getMemIntrinsicNode(ISD::INTRINSIC_W_CHAIN, dl,
                                DAG.getVTList(PermTy, MVT::Other),
                                BaseLoadOps, LDTy, BaseMMO);

      // Note that the value of IncOffset (which is provided to the next
      // load's pointer info offset value, and thus used to calculate the
      // alignment), and the value of IncValue (which is actually used to
      // increment the pointer value) are different! This is because we
      // require the next load to appear to be aligned, even though it
      // is actually offset from the base pointer by a lesser amount.
      int IncOffset = VT.getSizeInBits() / 8;
      int IncValue = IncOffset;

      // Walk (both up and down) the chain looking for another load at the real
      // (aligned) offset (the alignment of the other load does not matter in
      // this case). If found, then do not use the offset reduction trick, as
      // that will prevent the loads from being later combined (as they would
      // otherwise be duplicates).
      if (!findConsecutiveLoad(LD, DAG))
        --IncValue;

      SDValue Increment =
          DAG.getConstant(IncValue, dl, getPointerTy(MF.getDataLayout()));
      Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, Increment);

      MachineMemOperand *ExtraMMO =
        MF.getMachineMemOperand(LD->getMemOperand(),
                                1, 2*MemVT.getStoreSize()-1);
      SDValue ExtraLoadOps[] = { Chain, LDXIntID, Ptr };
      SDValue ExtraLoad =
        DAG.getMemIntrinsicNode(ISD::INTRINSIC_W_CHAIN, dl,
                                DAG.getVTList(PermTy, MVT::Other),
                                ExtraLoadOps, LDTy, ExtraMMO);

      SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
        BaseLoad.getValue(1), ExtraLoad.getValue(1));

      // Because vperm has a big-endian bias, we must reverse the order
      // of the input vectors and complement the permute control vector
      // when generating little endian code.  We have already handled the
      // latter by using lvsr instead of lvsl, so just reverse BaseLoad
      // and ExtraLoad here.
      SDValue Perm;
      if (isLittleEndian)
        Perm = BuildIntrinsicOp(IntrPerm,
                                ExtraLoad, BaseLoad, PermCntl, DAG, dl);
      else
        Perm = BuildIntrinsicOp(IntrPerm,
                                BaseLoad, ExtraLoad, PermCntl, DAG, dl);

      if (VT != PermTy)
        Perm = Subtarget.hasAltivec()
                   ? DAG.getNode(ISD::BITCAST, dl, VT, Perm)
                   : DAG.getNode(ISD::FP_ROUND, dl, VT, Perm,
                                 DAG.getTargetConstant(1, dl, MVT::i64));
                               // second argument is 1 because this rounding
                               // is always exact.

      // The output of the permutation is our loaded result, the TokenFactor is
      // our new chain.
      DCI.CombineTo(N, Perm, TF);
      return SDValue(N, 0);
    }
    }
    break;
    case ISD::INTRINSIC_WO_CHAIN: {
      bool isLittleEndian = Subtarget.isLittleEndian();
      unsigned IID = N->getConstantOperandVal(0);
      Intrinsic::ID Intr = (isLittleEndian ? Intrinsic::ppc_altivec_lvsr
                                           : Intrinsic::ppc_altivec_lvsl);
      if (IID == Intr && N->getOperand(1)->getOpcode() == ISD::ADD) {
        SDValue Add = N->getOperand(1);

        int Bits = 4 /* 16 byte alignment */;

        if (DAG.MaskedValueIsZero(Add->getOperand(1),
                                  APInt::getAllOnes(Bits /* alignment */)
                                      .zext(Add.getScalarValueSizeInBits()))) {
          SDNode *BasePtr = Add->getOperand(0).getNode();
          for (SDNode *U : BasePtr->users()) {
            if (U->getOpcode() == ISD::INTRINSIC_WO_CHAIN &&
                U->getConstantOperandVal(0) == IID) {
              // We've found another LVSL/LVSR, and this address is an aligned
              // multiple of that one. The results will be the same, so use the
              // one we've just found instead.

              return SDValue(U, 0);
            }
          }
        }

        if (isa<ConstantSDNode>(Add->getOperand(1))) {
          SDNode *BasePtr = Add->getOperand(0).getNode();
          for (SDNode *U : BasePtr->users()) {
            if (U->getOpcode() == ISD::ADD &&
                isa<ConstantSDNode>(U->getOperand(1)) &&
                (Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
                        (1ULL << Bits) ==
                    0) {
              SDNode *OtherAdd = U;
              for (SDNode *V : OtherAdd->users()) {
                if (V->getOpcode() == ISD::INTRINSIC_WO_CHAIN &&
                    V->getConstantOperandVal(0) == IID) {
                  return SDValue(V, 0);
                }
              }
            }
          }
        }
      }

      // Combine vmaxsw/h/b(a, a's negation) to abs(a)
      // Expose the vabsduw/h/b opportunity for down stream
      if (!DCI.isAfterLegalizeDAG() && Subtarget.hasP9Altivec() &&
          (IID == Intrinsic::ppc_altivec_vmaxsw ||
           IID == Intrinsic::ppc_altivec_vmaxsh ||
           IID == Intrinsic::ppc_altivec_vmaxsb)) {
        SDValue V1 = N->getOperand(1);
        SDValue V2 = N->getOperand(2);
        if ((V1.getSimpleValueType() == MVT::v4i32 ||
             V1.getSimpleValueType() == MVT::v8i16 ||
             V1.getSimpleValueType() == MVT::v16i8) &&
            V1.getSimpleValueType() == V2.getSimpleValueType()) {
          // (0-a, a)
          if (V1.getOpcode() == ISD::SUB &&
              ISD::isBuildVectorAllZeros(V1.getOperand(0).getNode()) &&
              V1.getOperand(1) == V2) {
            return DAG.getNode(ISD::ABS, dl, V2.getValueType(), V2);
          }
          // (a, 0-a)
          if (V2.getOpcode() == ISD::SUB &&
              ISD::isBuildVectorAllZeros(V2.getOperand(0).getNode()) &&
              V2.getOperand(1) == V1) {
            return DAG.getNode(ISD::ABS, dl, V1.getValueType(), V1);
          }
          // (x-y, y-x)
          if (V1.getOpcode() == ISD::SUB && V2.getOpcode() == ISD::SUB &&
              V1.getOperand(0) == V2.getOperand(1) &&
              V1.getOperand(1) == V2.getOperand(0)) {
            return DAG.getNode(ISD::ABS, dl, V1.getValueType(), V1);
          }
        }
      }
    }

    break;
  case ISD::INTRINSIC_W_CHAIN:
      switch (N->getConstantOperandVal(1)) {
      default:
        break;
      case Intrinsic::ppc_altivec_vsum4sbs:
      case Intrinsic::ppc_altivec_vsum4shs:
      case Intrinsic::ppc_altivec_vsum4ubs: {
        // These sum-across intrinsics only have a chain due to the side effect
        // that they may set the SAT bit. If we know the SAT bit will not be set
        // for some inputs, we can replace any uses of their chain with the
        // input chain.
        if (BuildVectorSDNode *BVN =
                dyn_cast<BuildVectorSDNode>(N->getOperand(3))) {
          APInt APSplatBits, APSplatUndef;
          unsigned SplatBitSize;
          bool HasAnyUndefs;
          bool BVNIsConstantSplat = BVN->isConstantSplat(
              APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
              !Subtarget.isLittleEndian());
          // If the constant splat vector is 0, the SAT bit will not be set.
          if (BVNIsConstantSplat && APSplatBits == 0)
            DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), N->getOperand(0));
        }
        return SDValue();
      }
    case Intrinsic::ppc_vsx_lxvw4x:
    case Intrinsic::ppc_vsx_lxvd2x:
      // For little endian, VSX loads require generating lxvd2x/xxswapd.
      // Not needed on ISA 3.0 based CPUs since we have a non-permuting load.
      if (Subtarget.needsSwapsForVSXMemOps())
        return expandVSXLoadForLE(N, DCI);
      break;
    }
    break;
  case ISD::INTRINSIC_VOID:
    // For little endian, VSX stores require generating xxswapd/stxvd2x.
    // Not needed on ISA 3.0 based CPUs since we have a non-permuting store.
    if (Subtarget.needsSwapsForVSXMemOps()) {
      switch (N->getConstantOperandVal(1)) {
      default:
        break;
      case Intrinsic::ppc_vsx_stxvw4x:
      case Intrinsic::ppc_vsx_stxvd2x:
        return expandVSXStoreForLE(N, DCI);
      }
    }
    break;
  case ISD::BSWAP: {
    // Turn BSWAP (LOAD) -> lhbrx/lwbrx.
    // For subtargets without LDBRX, we can still do better than the default
    // expansion even for 64-bit BSWAP (LOAD).
    bool Is64BitBswapOn64BitTgt =
        Subtarget.isPPC64() && N->getValueType(0) == MVT::i64;
    bool IsSingleUseNormalLd = ISD::isNormalLoad(N->getOperand(0).getNode()) &&
                               N->getOperand(0).hasOneUse();
    if (IsSingleUseNormalLd &&
        (N->getValueType(0) == MVT::i32 || N->getValueType(0) == MVT::i16 ||
         (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
      SDValue Load = N->getOperand(0);
      LoadSDNode *LD = cast<LoadSDNode>(Load);
      // Create the byte-swapping load.
      SDValue Ops[] = {
        LD->getChain(),    // Chain
        LD->getBasePtr(),  // Ptr
        DAG.getValueType(N->getValueType(0)) // VT
      };
      SDValue BSLoad =
        DAG.getMemIntrinsicNode(PPCISD::LBRX, dl,
                                DAG.getVTList(N->getValueType(0) == MVT::i64 ?
                                              MVT::i64 : MVT::i32, MVT::Other),
                                Ops, LD->getMemoryVT(), LD->getMemOperand());

      // If this is an i16 load, insert the truncate.
      SDValue ResVal = BSLoad;
      if (N->getValueType(0) == MVT::i16)
        ResVal = DAG.getNode(ISD::TRUNCATE, dl, MVT::i16, BSLoad);

      // First, combine the bswap away.  This makes the value produced by the
      // load dead.
      DCI.CombineTo(N, ResVal);

      // Next, combine the load away, we give it a bogus result value but a real
      // chain result.  The result value is dead because the bswap is dead.
      DCI.CombineTo(Load.getNode(), ResVal, BSLoad.getValue(1));

      // Return N so it doesn't get rechecked!
      return SDValue(N, 0);
    }
    // Convert this to two 32-bit bswap loads and a BUILD_PAIR. Do this only
    // before legalization so that the BUILD_PAIR is handled correctly.
    if (!DCI.isBeforeLegalize() || !Is64BitBswapOn64BitTgt ||
        !IsSingleUseNormalLd)
      return SDValue();
    LoadSDNode *LD = cast<LoadSDNode>(N->getOperand(0));

    // Can't split volatile or atomic loads.
    if (!LD->isSimple())
      return SDValue();
    SDValue BasePtr = LD->getBasePtr();
    SDValue Lo = DAG.getLoad(MVT::i32, dl, LD->getChain(), BasePtr,
                             LD->getPointerInfo(), LD->getAlign());
    Lo = DAG.getNode(ISD::BSWAP, dl, MVT::i32, Lo);
    BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr,
                          DAG.getIntPtrConstant(4, dl));
    MachineMemOperand *NewMMO = DAG.getMachineFunction().getMachineMemOperand(
        LD->getMemOperand(), 4, 4);
    SDValue Hi = DAG.getLoad(MVT::i32, dl, LD->getChain(), BasePtr, NewMMO);
    Hi = DAG.getNode(ISD::BSWAP, dl, MVT::i32, Hi);
    SDValue Res;
    if (Subtarget.isLittleEndian())
      Res = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Hi, Lo);
    else
      Res = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
    SDValue TF =
        DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
                    Hi.getOperand(0).getValue(1), Lo.getOperand(0).getValue(1));
    DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), TF);
    return Res;
  }
  case PPCISD::VCMP:
    // If a VCMP_rec node already exists with exactly the same operands as this
    // node, use its result instead of this node (VCMP_rec computes both a CR6
    // and a normal output).
    //
    if (!N->getOperand(0).hasOneUse() &&
        !N->getOperand(1).hasOneUse() &&
        !N->getOperand(2).hasOneUse()) {

      // Scan all of the users of the LHS, looking for VCMP_rec's that match.
      SDNode *VCMPrecNode = nullptr;

      SDNode *LHSN = N->getOperand(0).getNode();
      for (SDNode *User : LHSN->users())
        if (User->getOpcode() == PPCISD::VCMP_rec &&
            User->getOperand(1) == N->getOperand(1) &&
            User->getOperand(2) == N->getOperand(2) &&
            User->getOperand(0) == N->getOperand(0)) {
          VCMPrecNode = User;
          break;
        }

      // If there is no VCMP_rec node, or if the flag value has a single use,
      // don't transform this.
      if (!VCMPrecNode || VCMPrecNode->hasNUsesOfValue(0, 1))
        break;

      // Look at the (necessarily single) use of the flag value.  If it has a
      // chain, this transformation is more complex.  Note that multiple things
      // could use the value result, which we should ignore.
      SDNode *FlagUser = nullptr;
      for (SDNode::use_iterator UI = VCMPrecNode->use_begin();
           FlagUser == nullptr; ++UI) {
        assert(UI != VCMPrecNode->use_end() && "Didn't find user!");
        SDNode *User = UI->getUser();
        for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) {
          if (User->getOperand(i) == SDValue(VCMPrecNode, 1)) {
            FlagUser = User;
            break;
          }
        }
      }

      // If the user is a MFOCRF instruction, we know this is safe.
      // Otherwise we give up for right now.
      if (FlagUser->getOpcode() == PPCISD::MFOCRF)
        return SDValue(VCMPrecNode, 0);
    }
    break;
  case ISD::BR_CC: {
    // If this is a branch on an altivec predicate comparison, lower this so
    // that we don't have to do a MFOCRF: instead, branch directly on CR6.  This
    // lowering is done pre-legalize, because the legalizer lowers the predicate
    // compare down to code that is difficult to reassemble.
    // This code also handles branches that depend on the result of a store
    // conditional.
    ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(1))->get();
    SDValue LHS = N->getOperand(2), RHS = N->getOperand(3);

    int CompareOpc;
    bool isDot;

    if (!isa<ConstantSDNode>(RHS) || (CC != ISD::SETEQ && CC != ISD::SETNE))
      break;

    // Since we are doing this pre-legalize, the RHS can be a constant of
    // arbitrary bitwidth which may cause issues when trying to get the value
    // from the underlying APInt.
    auto RHSAPInt = RHS->getAsAPIntVal();
    if (!RHSAPInt.isIntN(64))
      break;

    unsigned Val = RHSAPInt.getZExtValue();
    auto isImpossibleCompare = [&]() {
      // If this is a comparison against something other than 0/1, then we know
      // that the condition is never/always true.
      if (Val != 0 && Val != 1) {
        if (CC == ISD::SETEQ)      // Cond never true, remove branch.
          return N->getOperand(0);
        // Always !=, turn it into an unconditional branch.
        return DAG.getNode(ISD::BR, dl, MVT::Other,
                           N->getOperand(0), N->getOperand(4));
      }
      return SDValue();
    };
    // Combine branches fed by store conditional instructions (st[bhwd]cx).
    unsigned StoreWidth = 0;
    if (LHS.getOpcode() == ISD::INTRINSIC_W_CHAIN &&
        isStoreConditional(LHS, StoreWidth)) {
      if (SDValue Impossible = isImpossibleCompare())
        return Impossible;
      PPC::Predicate CompOpc;
      // eq 0 => ne
      // ne 0 => eq
      // eq 1 => eq
      // ne 1 => ne
      if (Val == 0)
        CompOpc = CC == ISD::SETEQ ? PPC::PRED_NE : PPC::PRED_EQ;
      else
        CompOpc = CC == ISD::SETEQ ? PPC::PRED_EQ : PPC::PRED_NE;

      SDValue Ops[] = {LHS.getOperand(0), LHS.getOperand(2), LHS.getOperand(3),
                       DAG.getConstant(StoreWidth, dl, MVT::i32)};
      auto *MemNode = cast<MemSDNode>(LHS);
      SDValue ConstSt = DAG.getMemIntrinsicNode(
          PPCISD::STORE_COND, dl,
          DAG.getVTList(MVT::i32, MVT::Other, MVT::Glue), Ops,
          MemNode->getMemoryVT(), MemNode->getMemOperand());

      SDValue InChain;
      // Unchain the branch from the original store conditional.
      if (N->getOperand(0) == LHS.getValue(1))
        InChain = LHS.getOperand(0);
      else if (N->getOperand(0).getOpcode() == ISD::TokenFactor) {
        SmallVector<SDValue, 4> InChains;
        SDValue InTF = N->getOperand(0);
        for (int i = 0, e = InTF.getNumOperands(); i < e; i++)
          if (InTF.getOperand(i) != LHS.getValue(1))
            InChains.push_back(InTF.getOperand(i));
        InChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, InChains);
      }

      return DAG.getNode(PPCISD::COND_BRANCH, dl, MVT::Other, InChain,
                         DAG.getConstant(CompOpc, dl, MVT::i32),
                         DAG.getRegister(PPC::CR0, MVT::i32), N->getOperand(4),
                         ConstSt.getValue(2));
    }

    if (LHS.getOpcode() == ISD::INTRINSIC_WO_CHAIN &&
        getVectorCompareInfo(LHS, CompareOpc, isDot, Subtarget)) {
      assert(isDot && "Can't compare against a vector result!");

      if (SDValue Impossible = isImpossibleCompare())
        return Impossible;

      bool BranchOnWhenPredTrue = (CC == ISD::SETEQ) ^ (Val == 0);
      // Create the PPCISD altivec 'dot' comparison node.
      SDValue Ops[] = {
        LHS.getOperand(2),  // LHS of compare
        LHS.getOperand(3),  // RHS of compare
        DAG.getConstant(CompareOpc, dl, MVT::i32)
      };
      EVT VTs[] = { LHS.getOperand(2).getValueType(), MVT::Glue };
      SDValue CompNode = DAG.getNode(PPCISD::VCMP_rec, dl, VTs, Ops);

      // Unpack the result based on how the target uses it.
      PPC::Predicate CompOpc;
      switch (LHS.getConstantOperandVal(1)) {
      default:  // Can't happen, don't crash on invalid number though.
      case 0:   // Branch on the value of the EQ bit of CR6.
        CompOpc = BranchOnWhenPredTrue ? PPC::PRED_EQ : PPC::PRED_NE;
        break;
      case 1:   // Branch on the inverted value of the EQ bit of CR6.
        CompOpc = BranchOnWhenPredTrue ? PPC::PRED_NE : PPC::PRED_EQ;
        break;
      case 2:   // Branch on the value of the LT bit of CR6.
        CompOpc = BranchOnWhenPredTrue ? PPC::PRED_LT : PPC::PRED_GE;
        break;
      case 3:   // Branch on the inverted value of the LT bit of CR6.
        CompOpc = BranchOnWhenPredTrue ? PPC::PRED_GE : PPC::PRED_LT;
        break;
      }

      return DAG.getNode(PPCISD::COND_BRANCH, dl, MVT::Other, N->getOperand(0),
                         DAG.getConstant(CompOpc, dl, MVT::i32),
                         DAG.getRegister(PPC::CR6, MVT::i32),
                         N->getOperand(4), CompNode.getValue(1));
    }
    break;
  }
  case ISD::BUILD_VECTOR:
    return DAGCombineBuildVector(N, DCI);
  case PPCISD::ADDC:
    return DAGCombineAddc(N, DCI);
  }

  return SDValue();
}

SDValue
PPCTargetLowering::BuildSDIVPow2(SDNode *N, const APInt &Divisor,
                                 SelectionDAG &DAG,
                                 SmallVectorImpl<SDNode *> &Created) const {
  // fold (sdiv X, pow2)
  EVT VT = N->getValueType(0);
  if (VT == MVT::i64 && !Subtarget.isPPC64())
    return SDValue();
  if ((VT != MVT::i32 && VT != MVT::i64) ||
      !(Divisor.isPowerOf2() || Divisor.isNegatedPowerOf2()))
    return SDValue();

  SDLoc DL(N);
  SDValue N0 = N->getOperand(0);

  bool IsNegPow2 = Divisor.isNegatedPowerOf2();
  unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).countr_zero();
  SDValue ShiftAmt = DAG.getConstant(Lg2, DL, VT);

  SDValue Op = DAG.getNode(PPCISD::SRA_ADDZE, DL, VT, N0, ShiftAmt);
  Created.push_back(Op.getNode());

  if (IsNegPow2) {
    Op = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), Op);
    Created.push_back(Op.getNode());
  }

  return Op;
}

//===----------------------------------------------------------------------===//
// Inline Assembly Support
//===----------------------------------------------------------------------===//

void PPCTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
                                                      KnownBits &Known,
                                                      const APInt &DemandedElts,
                                                      const SelectionDAG &DAG,
                                                      unsigned Depth) const {
  Known.resetAll();
  switch (Op.getOpcode()) {
  default: break;
  case PPCISD::LBRX: {
    // lhbrx is known to have the top bits cleared out.
    if (cast<VTSDNode>(Op.getOperand(2))->getVT() == MVT::i16)
      Known.Zero = 0xFFFF0000;
    break;
  }
  case PPCISD::ADDE: {
    if (Op.getResNo() == 0) {
      // (0|1), _ = ADDE 0, 0, CARRY
      SDValue LHS = Op.getOperand(0);
      SDValue RHS = Op.getOperand(1);
      if (isNullConstant(LHS) && isNullConstant(RHS))
        Known.Zero = ~1ULL;
    }
    break;
  }
  case ISD::INTRINSIC_WO_CHAIN: {
    switch (Op.getConstantOperandVal(0)) {
    default: break;
    case Intrinsic::ppc_altivec_vcmpbfp_p:
    case Intrinsic::ppc_altivec_vcmpeqfp_p:
    case Intrinsic::ppc_altivec_vcmpequb_p:
    case Intrinsic::ppc_altivec_vcmpequh_p:
    case Intrinsic::ppc_altivec_vcmpequw_p:
    case Intrinsic::ppc_altivec_vcmpequd_p:
    case Intrinsic::ppc_altivec_vcmpequq_p:
    case Intrinsic::ppc_altivec_vcmpgefp_p:
    case Intrinsic::ppc_altivec_vcmpgtfp_p:
    case Intrinsic::ppc_altivec_vcmpgtsb_p:
    case Intrinsic::ppc_altivec_vcmpgtsh_p:
    case Intrinsic::ppc_altivec_vcmpgtsw_p:
    case Intrinsic::ppc_altivec_vcmpgtsd_p:
    case Intrinsic::ppc_altivec_vcmpgtsq_p:
    case Intrinsic::ppc_altivec_vcmpgtub_p:
    case Intrinsic::ppc_altivec_vcmpgtuh_p:
    case Intrinsic::ppc_altivec_vcmpgtuw_p:
    case Intrinsic::ppc_altivec_vcmpgtud_p:
    case Intrinsic::ppc_altivec_vcmpgtuq_p:
      Known.Zero = ~1U;  // All bits but the low one are known to be zero.
      break;
    }
    break;
  }
  case ISD::INTRINSIC_W_CHAIN: {
    switch (Op.getConstantOperandVal(1)) {
    default:
      break;
    case Intrinsic::ppc_load2r:
      // Top bits are cleared for load2r (which is the same as lhbrx).
      Known.Zero = 0xFFFF0000;
      break;
    }
    break;
  }
  }
}

Align PPCTargetLowering::getPrefLoopAlignment(MachineLoop *ML) const {
  switch (Subtarget.getCPUDirective()) {
  default: break;
  case PPC::DIR_970:
  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:
  case PPC::DIR_PWR9:
  case PPC::DIR_PWR10:
  case PPC::DIR_PWR11:
  case PPC::DIR_PWR_FUTURE: {
    if (!ML)
      break;

    if (!DisableInnermostLoopAlign32) {
      // If the nested loop is an innermost loop, prefer to a 32-byte alignment,
      // so that we can decrease cache misses and branch-prediction misses.
      // Actual alignment of the loop will depend on the hotness check and other
      // logic in alignBlocks.
      if (ML->getLoopDepth() > 1 && ML->getSubLoops().empty())
        return Align(32);
    }

    const PPCInstrInfo *TII = Subtarget.getInstrInfo();

    // For small loops (between 5 and 8 instructions), align to a 32-byte
    // boundary so that the entire loop fits in one instruction-cache line.
    uint64_t LoopSize = 0;
    for (auto I = ML->block_begin(), IE = ML->block_end(); I != IE; ++I)
      for (const MachineInstr &J : **I) {
        LoopSize += TII->getInstSizeInBytes(J);
        if (LoopSize > 32)
          break;
      }

    if (LoopSize > 16 && LoopSize <= 32)
      return Align(32);

    break;
  }
  }

  return TargetLowering::getPrefLoopAlignment(ML);
}

/// getConstraintType - Given a constraint, return the type of
/// constraint it is for this target.
PPCTargetLowering::ConstraintType
PPCTargetLowering::getConstraintType(StringRef Constraint) const {
  if (Constraint.size() == 1) {
    switch (Constraint[0]) {
    default: break;
    case 'b':
    case 'r':
    case 'f':
    case 'd':
    case 'v':
    case 'y':
      return C_RegisterClass;
    case 'Z':
      // FIXME: While Z does indicate a memory constraint, it specifically
      // indicates an r+r address (used in conjunction with the 'y' modifier
      // in the replacement string). Currently, we're forcing the base
      // register to be r0 in the asm printer (which is interpreted as zero)
      // and forming the complete address in the second register. This is
      // suboptimal.
      return C_Memory;
    }
  } else if (Constraint == "wc") { // individual CR bits.
    return C_RegisterClass;
  } else if (Constraint == "wa" || Constraint == "wd" ||
             Constraint == "wf" || Constraint == "ws" ||
             Constraint == "wi" || Constraint == "ww") {
    return C_RegisterClass; // VSX registers.
  }
  return TargetLowering::getConstraintType(Constraint);
}

/// Examine constraint type and operand type and determine a weight value.
/// This object must already have been set up with the operand type
/// and the current alternative constraint selected.
TargetLowering::ConstraintWeight
PPCTargetLowering::getSingleConstraintMatchWeight(
    AsmOperandInfo &info, const char *constraint) const {
  ConstraintWeight weight = CW_Invalid;
  Value *CallOperandVal = info.CallOperandVal;
    // If we don't have a value, we can't do a match,
    // but allow it at the lowest weight.
  if (!CallOperandVal)
    return CW_Default;
  Type *type = CallOperandVal->getType();

  // Look at the constraint type.
  if (StringRef(constraint) == "wc" && type->isIntegerTy(1))
    return CW_Register; // an individual CR bit.
  else if ((StringRef(constraint) == "wa" ||
            StringRef(constraint) == "wd" ||
            StringRef(constraint) == "wf") &&
           type->isVectorTy())
    return CW_Register;
  else if (StringRef(constraint) == "wi" && type->isIntegerTy(64))
    return CW_Register; // just hold 64-bit integers data.
  else if (StringRef(constraint) == "ws" && type->isDoubleTy())
    return CW_Register;
  else if (StringRef(constraint) == "ww" && type->isFloatTy())
    return CW_Register;

  switch (*constraint) {
  default:
    weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);
    break;
  case 'b':
    if (type->isIntegerTy())
      weight = CW_Register;
    break;
  case 'f':
    if (type->isFloatTy())
      weight = CW_Register;
    break;
  case 'd':
    if (type->isDoubleTy())
      weight = CW_Register;
    break;
  case 'v':
    if (type->isVectorTy())
      weight = CW_Register;
    break;
  case 'y':
    weight = CW_Register;
    break;
  case 'Z':
    weight = CW_Memory;
    break;
  }
  return weight;
}

std::pair<unsigned, const TargetRegisterClass *>
PPCTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
                                                StringRef Constraint,
                                                MVT VT) const {
  if (Constraint.size() == 1) {
    // GCC RS6000 Constraint Letters
    switch (Constraint[0]) {
    case 'b':   // R1-R31
      if (VT == MVT::i64 && Subtarget.isPPC64())
        return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
      return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
    case 'r':   // R0-R31
      if (VT == MVT::i64 && Subtarget.isPPC64())
        return std::make_pair(0U, &PPC::G8RCRegClass);
      return std::make_pair(0U, &PPC::GPRCRegClass);
    // 'd' and 'f' constraints are both defined to be "the floating point
    // registers", where one is for 32-bit and the other for 64-bit. We don't
    // really care overly much here so just give them all the same reg classes.
    case 'd':
    case 'f':
      if (Subtarget.hasSPE()) {
        if (VT == MVT::f32 || VT == MVT::i32)
          return std::make_pair(0U, &PPC::GPRCRegClass);
        if (VT == MVT::f64 || VT == MVT::i64)
          return std::make_pair(0U, &PPC::SPERCRegClass);
      } else {
        if (VT == MVT::f32 || VT == MVT::i32)
          return std::make_pair(0U, &PPC::F4RCRegClass);
        if (VT == MVT::f64 || VT == MVT::i64)
          return std::make_pair(0U, &PPC::F8RCRegClass);
      }
      break;
    case 'v':
      if (Subtarget.hasAltivec() && VT.isVector())
        return std::make_pair(0U, &PPC::VRRCRegClass);
      else if (Subtarget.hasVSX())
        // Scalars in Altivec registers only make sense with VSX.
        return std::make_pair(0U, &PPC::VFRCRegClass);
      break;
    case 'y':   // crrc
      return std::make_pair(0U, &PPC::CRRCRegClass);
    }
  } else if (Constraint == "wc" && Subtarget.useCRBits()) {
    // An individual CR bit.
    return std::make_pair(0U, &PPC::CRBITRCRegClass);
  } else if ((Constraint == "wa" || Constraint == "wd" ||
             Constraint == "wf" || Constraint == "wi") &&
             Subtarget.hasVSX()) {
    // A VSX register for either a scalar (FP) or vector. There is no
    // support for single precision scalars on subtargets prior to Power8.
    if (VT.isVector())
      return std::make_pair(0U, &PPC::VSRCRegClass);
    if (VT == MVT::f32 && Subtarget.hasP8Vector())
      return std::make_pair(0U, &PPC::VSSRCRegClass);
    return std::make_pair(0U, &PPC::VSFRCRegClass);
  } else if ((Constraint == "ws" || Constraint == "ww") && Subtarget.hasVSX()) {
    if (VT == MVT::f32 && Subtarget.hasP8Vector())
      return std::make_pair(0U, &PPC::VSSRCRegClass);
    else
      return std::make_pair(0U, &PPC::VSFRCRegClass);
  } else if (Constraint == "lr") {
    if (VT == MVT::i64)
      return std::make_pair(0U, &PPC::LR8RCRegClass);
    else
      return std::make_pair(0U, &PPC::LRRCRegClass);
  }

  // Handle special cases of physical registers that are not properly handled
  // by the base class.
  if (Constraint[0] == '{' && Constraint[Constraint.size() - 1] == '}') {
    // If we name a VSX register, we can't defer to the base class because it
    // will not recognize the correct register (their names will be VSL{0-31}
    // and V{0-31} so they won't match). So we match them here.
    if (Constraint.size() > 3 && Constraint[1] == 'v' && Constraint[2] == 's') {
      int VSNum = atoi(Constraint.data() + 3);
      assert(VSNum >= 0 && VSNum <= 63 &&
             "Attempted to access a vsr out of range");
      if (VSNum < 32)
        return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
      return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
    }

    // For float registers, we can't defer to the base class as it will match
    // the SPILLTOVSRRC class.
    if (Constraint.size() > 3 && Constraint[1] == 'f') {
      int RegNum = atoi(Constraint.data() + 2);
      if (RegNum > 31 || RegNum < 0)
        report_fatal_error("Invalid floating point register number");
      if (VT == MVT::f32 || VT == MVT::i32)
        return Subtarget.hasSPE()
                   ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
                   : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
      if (VT == MVT::f64 || VT == MVT::i64)
        return Subtarget.hasSPE()
                   ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
                   : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
    }
  }

  std::pair<unsigned, const TargetRegisterClass *> R =
      TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);

  // r[0-9]+ are used, on PPC64, to refer to the corresponding 64-bit registers
  // (which we call X[0-9]+). If a 64-bit value has been requested, and a
  // 32-bit GPR has been selected, then 'upgrade' it to the 64-bit parent
  // register.
  // FIXME: If TargetLowering::getRegForInlineAsmConstraint could somehow use
  // the AsmName field from *RegisterInfo.td, then this would not be necessary.
  if (R.first && VT == MVT::i64 && Subtarget.isPPC64() &&
      PPC::GPRCRegClass.contains(R.first))
    return std::make_pair(TRI->getMatchingSuperReg(R.first,
                            PPC::sub_32, &PPC::G8RCRegClass),
                          &PPC::G8RCRegClass);

  // GCC accepts 'cc' as an alias for 'cr0', and we need to do the same.
  if (!R.second && StringRef("{cc}").equals_insensitive(Constraint)) {
    R.first = PPC::CR0;
    R.second = &PPC::CRRCRegClass;
  }
  // FIXME: This warning should ideally be emitted in the front end.
  const auto &TM = getTargetMachine();
  if (Subtarget.isAIXABI() && !TM.getAIXExtendedAltivecABI()) {
    if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
         (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
        (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
      errs() << "warning: vector registers 20 to 32 are reserved in the "
                "default AIX AltiVec ABI and cannot be used\n";
  }

  return R;
}

/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
/// vector.  If it is invalid, don't add anything to Ops.
void PPCTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
                                                     StringRef Constraint,
                                                     std::vector<SDValue> &Ops,
                                                     SelectionDAG &DAG) const {
  SDValue Result;

  // Only support length 1 constraints.
  if (Constraint.size() > 1)
    return;

  char Letter = Constraint[0];
  switch (Letter) {
  default: break;
  case 'I':
  case 'J':
  case 'K':
  case 'L':
  case 'M':
  case 'N':
  case 'O':
  case 'P': {
    ConstantSDNode *CST = dyn_cast<ConstantSDNode>(Op);
    if (!CST) return; // Must be an immediate to match.
    SDLoc dl(Op);
    int64_t Value = CST->getSExtValue();
    EVT TCVT = MVT::i64; // All constants taken to be 64 bits so that negative
                         // numbers are printed as such.
    switch (Letter) {
    default: llvm_unreachable("Unknown constraint letter!");
    case 'I':  // "I" is a signed 16-bit constant.
      if (isInt<16>(Value))
        Result = DAG.getTargetConstant(Value, dl, TCVT);
      break;
    case 'J':  // "J" is a constant with only the high-order 16 bits nonzero.
      if (isShiftedUInt<16, 16>(Value))
        Result = DAG.getTargetConstant(Value, dl, TCVT);
      break;
    case 'L':  // "L" is a signed 16-bit constant shifted left 16 bits.
      if (isShiftedInt<16, 16>(Value))
        Result = DAG.getTargetConstant(Value, dl, TCVT);
      break;
    case 'K':  // "K" is a constant with only the low-order 16 bits nonzero.
      if (isUInt<16>(Value))
        Result = DAG.getTargetConstant(Value, dl, TCVT);
      break;
    case 'M':  // "M" is a constant that is greater than 31.
      if (Value > 31)
        Result = DAG.getTargetConstant(Value, dl, TCVT);
      break;
    case 'N':  // "N" is a positive constant that is an exact power of two.
      if (Value > 0 && isPowerOf2_64(Value))
        Result = DAG.getTargetConstant(Value, dl, TCVT);
      break;
    case 'O':  // "O" is the constant zero.
      if (Value == 0)
        Result = DAG.getTargetConstant(Value, dl, TCVT);
      break;
    case 'P':  // "P" is a constant whose negation is a signed 16-bit constant.
      if (isInt<16>(-Value))
        Result = DAG.getTargetConstant(Value, dl, TCVT);
      break;
    }
    break;
  }
  }

  if (Result.getNode()) {
    Ops.push_back(Result);
    return;
  }

  // Handle standard constraint letters.
  TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);
}

void PPCTargetLowering::CollectTargetIntrinsicOperands(const CallInst &I,
                                              SmallVectorImpl<SDValue> &Ops,
                                              SelectionDAG &DAG) const {
  if (I.getNumOperands() <= 1)
    return;
  if (!isa<ConstantSDNode>(Ops[1].getNode()))
    return;
  auto IntrinsicID = Ops[1].getNode()->getAsZExtVal();
  if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
      IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
    return;

  if (MDNode *MDN = I.getMetadata(LLVMContext::MD_annotation))
    Ops.push_back(DAG.getMDNode(MDN));
}

// isLegalAddressingMode - Return true if the addressing mode represented
// by AM is legal for this target, for a load/store of the specified type.
bool PPCTargetLowering::isLegalAddressingMode(const DataLayout &DL,
                                              const AddrMode &AM, Type *Ty,
                                              unsigned AS,
                                              Instruction *I) const {
  // Vector type r+i form is supported since power9 as DQ form. We don't check
  // the offset matching DQ form requirement(off % 16 == 0), because on PowerPC,
  // imm form is preferred and the offset can be adjusted to use imm form later
  // in pass PPCLoopInstrFormPrep. Also in LSR, for one LSRUse, it uses min and
  // max offset to check legal addressing mode, we should be a little aggressive
  // to contain other offsets for that LSRUse.
  if (Ty->isVectorTy() && AM.BaseOffs != 0 && !Subtarget.hasP9Vector())
    return false;

  // PPC allows a sign-extended 16-bit immediate field.
  if (AM.BaseOffs <= -(1LL << 16) || AM.BaseOffs >= (1LL << 16)-1)
    return false;

  // No global is ever allowed as a base.
  if (AM.BaseGV)
    return false;

  // PPC only support r+r,
  switch (AM.Scale) {
  case 0:  // "r+i" or just "i", depending on HasBaseReg.
    break;
  case 1:
    if (AM.HasBaseReg && AM.BaseOffs)  // "r+r+i" is not allowed.
      return false;
    // Otherwise we have r+r or r+i.
    break;
  case 2:
    if (AM.HasBaseReg || AM.BaseOffs)  // 2*r+r  or  2*r+i is not allowed.
      return false;
    // Allow 2*r as r+r.
    break;
  default:
    // No other scales are supported.
    return false;
  }

  return true;
}

SDValue PPCTargetLowering::LowerRETURNADDR(SDValue Op,
                                           SelectionDAG &DAG) const {
  MachineFunction &MF = DAG.getMachineFunction();
  MachineFrameInfo &MFI = MF.getFrameInfo();
  MFI.setReturnAddressIsTaken(true);

  SDLoc dl(Op);
  unsigned Depth = Op.getConstantOperandVal(0);

  // Make sure the function does not optimize away the store of the RA to
  // the stack.
  PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
  FuncInfo->setLRStoreRequired();
  auto PtrVT = getPointerTy(MF.getDataLayout());

  if (Depth > 0) {
    // The link register (return address) is saved in the caller's frame
    // not the callee's stack frame. So we must get the caller's frame
    // address and load the return address at the LR offset from there.
    SDValue FrameAddr =
        DAG.getLoad(Op.getValueType(), dl, DAG.getEntryNode(),
                    LowerFRAMEADDR(Op, DAG), MachinePointerInfo());
    SDValue Offset =
        DAG.getConstant(Subtarget.getFrameLowering()->getReturnSaveOffset(), dl,
                        Subtarget.getScalarIntVT());
    return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(),
                       DAG.getNode(ISD::ADD, dl, PtrVT, FrameAddr, Offset),
                       MachinePointerInfo());
  }

  // Just load the return address off the stack.
  SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
  return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), RetAddrFI,
                     MachinePointerInfo());
}

SDValue PPCTargetLowering::LowerFRAMEADDR(SDValue Op,
                                          SelectionDAG &DAG) const {
  SDLoc dl(Op);
  unsigned Depth = Op.getConstantOperandVal(0);

  MachineFunction &MF = DAG.getMachineFunction();
  MachineFrameInfo &MFI = MF.getFrameInfo();
  MFI.setFrameAddressIsTaken(true);

  EVT PtrVT = getPointerTy(MF.getDataLayout());
  bool isPPC64 = PtrVT == MVT::i64;

  // Naked functions never have a frame pointer, and so we use r1. For all
  // other functions, this decision must be delayed until during PEI.
  unsigned FrameReg;
  if (MF.getFunction().hasFnAttribute(Attribute::Naked))
    FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
  else
    FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;

  SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg,
                                         PtrVT);
  while (Depth--)
    FrameAddr = DAG.getLoad(Op.getValueType(), dl, DAG.getEntryNode(),
                            FrameAddr, MachinePointerInfo());
  return FrameAddr;
}

#define GET_REGISTER_MATCHER
#include "PPCGenAsmMatcher.inc"

Register PPCTargetLowering::getRegisterByName(const char *RegName, LLT VT,
                                              const MachineFunction &MF) const {
  bool IsPPC64 = Subtarget.isPPC64();

  bool Is64Bit = IsPPC64 && VT == LLT::scalar(64);
  if (!Is64Bit && VT != LLT::scalar(32))
    report_fatal_error("Invalid register global variable type");

  Register Reg = MatchRegisterName(RegName);
  if (!Reg)
    return Reg;

  // FIXME: Unable to generate code for `-O2` but okay for `-O0`.
  // Need followup investigation as to why.
  if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0)
    report_fatal_error(Twine("Trying to reserve an invalid register \"" +
                             StringRef(RegName) + "\"."));

  // Convert GPR to GP8R register for 64bit.
  if (Is64Bit && StringRef(RegName).starts_with_insensitive("r"))
    Reg = Reg.id() - PPC::R0 + PPC::X0;

  return Reg;
}

bool PPCTargetLowering::isAccessedAsGotIndirect(SDValue GA) const {
  // 32-bit SVR4 ABI access everything as got-indirect.
  if (Subtarget.is32BitELFABI())
    return true;

  // AIX accesses everything indirectly through the TOC, which is similar to
  // the GOT.
  if (Subtarget.isAIXABI())
    return true;

  CodeModel::Model CModel = getTargetMachine().getCodeModel();
  // If it is small or large code model, module locals are accessed
  // indirectly by loading their address from .toc/.got.
  if (CModel == CodeModel::Small || CModel == CodeModel::Large)
    return true;

  // JumpTable and BlockAddress are accessed as got-indirect.
  if (isa<JumpTableSDNode>(GA) || isa<BlockAddressSDNode>(GA))
    return true;

  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(GA))
    return Subtarget.isGVIndirectSymbol(G->getGlobal());

  return false;
}

bool
PPCTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
  // The PowerPC target isn't yet aware of offsets.
  return false;
}

bool PPCTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
                                           const CallBase &I,
                                           MachineFunction &MF,
                                           unsigned Intrinsic) const {
  switch (Intrinsic) {
  case Intrinsic::ppc_atomicrmw_xchg_i128:
  case Intrinsic::ppc_atomicrmw_add_i128:
  case Intrinsic::ppc_atomicrmw_sub_i128:
  case Intrinsic::ppc_atomicrmw_nand_i128:
  case Intrinsic::ppc_atomicrmw_and_i128:
  case Intrinsic::ppc_atomicrmw_or_i128:
  case Intrinsic::ppc_atomicrmw_xor_i128:
  case Intrinsic::ppc_cmpxchg_i128:
    Info.opc = ISD::INTRINSIC_W_CHAIN;
    Info.memVT = MVT::i128;
    Info.ptrVal = I.getArgOperand(0);
    Info.offset = 0;
    Info.align = Align(16);
    Info.flags = MachineMemOperand::MOLoad | MachineMemOperand::MOStore |
                 MachineMemOperand::MOVolatile;
    return true;
  case Intrinsic::ppc_atomic_load_i128:
    Info.opc = ISD::INTRINSIC_W_CHAIN;
    Info.memVT = MVT::i128;
    Info.ptrVal = I.getArgOperand(0);
    Info.offset = 0;
    Info.align = Align(16);
    Info.flags = MachineMemOperand::MOLoad | MachineMemOperand::MOVolatile;
    return true;
  case Intrinsic::ppc_atomic_store_i128:
    Info.opc = ISD::INTRINSIC_VOID;
    Info.memVT = MVT::i128;
    Info.ptrVal = I.getArgOperand(2);
    Info.offset = 0;
    Info.align = Align(16);
    Info.flags = MachineMemOperand::MOStore | MachineMemOperand::MOVolatile;
    return true;
  case Intrinsic::ppc_altivec_lvx:
  case Intrinsic::ppc_altivec_lvxl:
  case Intrinsic::ppc_altivec_lvebx:
  case Intrinsic::ppc_altivec_lvehx:
  case Intrinsic::ppc_altivec_lvewx:
  case Intrinsic::ppc_vsx_lxvd2x:
  case Intrinsic::ppc_vsx_lxvw4x:
  case Intrinsic::ppc_vsx_lxvd2x_be:
  case Intrinsic::ppc_vsx_lxvw4x_be:
  case Intrinsic::ppc_vsx_lxvl:
  case Intrinsic::ppc_vsx_lxvll: {
    EVT VT;
    switch (Intrinsic) {
    case Intrinsic::ppc_altivec_lvebx:
      VT = MVT::i8;
      break;
    case Intrinsic::ppc_altivec_lvehx:
      VT = MVT::i16;
      break;
    case Intrinsic::ppc_altivec_lvewx:
      VT = MVT::i32;
      break;
    case Intrinsic::ppc_vsx_lxvd2x:
    case Intrinsic::ppc_vsx_lxvd2x_be:
      VT = MVT::v2f64;
      break;
    default:
      VT = MVT::v4i32;
      break;
    }

    Info.opc = ISD::INTRINSIC_W_CHAIN;
    Info.memVT = VT;
    Info.ptrVal = I.getArgOperand(0);
    Info.offset = -VT.getStoreSize()+1;
    Info.size = 2*VT.getStoreSize()-1;
    Info.align = Align(1);
    Info.flags = MachineMemOperand::MOLoad;
    return true;
  }
  case Intrinsic::ppc_altivec_stvx:
  case Intrinsic::ppc_altivec_stvxl:
  case Intrinsic::ppc_altivec_stvebx:
  case Intrinsic::ppc_altivec_stvehx:
  case Intrinsic::ppc_altivec_stvewx:
  case Intrinsic::ppc_vsx_stxvd2x:
  case Intrinsic::ppc_vsx_stxvw4x:
  case Intrinsic::ppc_vsx_stxvd2x_be:
  case Intrinsic::ppc_vsx_stxvw4x_be:
  case Intrinsic::ppc_vsx_stxvl:
  case Intrinsic::ppc_vsx_stxvll: {
    EVT VT;
    switch (Intrinsic) {
    case Intrinsic::ppc_altivec_stvebx:
      VT = MVT::i8;
      break;
    case Intrinsic::ppc_altivec_stvehx:
      VT = MVT::i16;
      break;
    case Intrinsic::ppc_altivec_stvewx:
      VT = MVT::i32;
      break;
    case Intrinsic::ppc_vsx_stxvd2x:
    case Intrinsic::ppc_vsx_stxvd2x_be:
      VT = MVT::v2f64;
      break;
    default:
      VT = MVT::v4i32;
      break;
    }

    Info.opc = ISD::INTRINSIC_VOID;
    Info.memVT = VT;
    Info.ptrVal = I.getArgOperand(1);
    Info.offset = -VT.getStoreSize()+1;
    Info.size = 2*VT.getStoreSize()-1;
    Info.align = Align(1);
    Info.flags = MachineMemOperand::MOStore;
    return true;
  }
  case Intrinsic::ppc_stdcx:
  case Intrinsic::ppc_stwcx:
  case Intrinsic::ppc_sthcx:
  case Intrinsic::ppc_stbcx: {
    EVT VT;
    auto Alignment = Align(8);
    switch (Intrinsic) {
    case Intrinsic::ppc_stdcx:
      VT = MVT::i64;
      break;
    case Intrinsic::ppc_stwcx:
      VT = MVT::i32;
      Alignment = Align(4);
      break;
    case Intrinsic::ppc_sthcx:
      VT = MVT::i16;
      Alignment = Align(2);
      break;
    case Intrinsic::ppc_stbcx:
      VT = MVT::i8;
      Alignment = Align(1);
      break;
    }
    Info.opc = ISD::INTRINSIC_W_CHAIN;
    Info.memVT = VT;
    Info.ptrVal = I.getArgOperand(0);
    Info.offset = 0;
    Info.align = Alignment;
    Info.flags = MachineMemOperand::MOStore | MachineMemOperand::MOVolatile;
    return true;
  }
  default:
    break;
  }

  return false;
}

/// It returns EVT::Other if the type should be determined using generic
/// target-independent logic.
EVT PPCTargetLowering::getOptimalMemOpType(
    LLVMContext &Context, const MemOp &Op,
    const AttributeList &FuncAttributes) const {
  if (getTargetMachine().getOptLevel() != CodeGenOptLevel::None) {
    // We should use Altivec/VSX loads and stores when available. For unaligned
    // addresses, unaligned VSX loads are only fast starting with the P8.
    if (Subtarget.hasAltivec() && Op.size() >= 16) {
      if (Op.isMemset() && Subtarget.hasVSX()) {
        uint64_t TailSize = Op.size() % 16;
        // For memset lowering, EXTRACT_VECTOR_ELT tries to return constant
        // element if vector element type matches tail store. For tail size
        // 3/4, the tail store is i32, v4i32 cannot be used, need a legal one.
        if (TailSize > 2 && TailSize <= 4) {
          return MVT::v8i16;
        }
        return MVT::v4i32;
      }
      if (Op.isAligned(Align(16)) || Subtarget.hasP8Vector())
        return MVT::v4i32;
    }
  }

  if (Subtarget.isPPC64()) {
    return MVT::i64;
  }

  return MVT::i32;
}

/// Returns true if it is beneficial to convert a load of a constant
/// to just the constant itself.
bool PPCTargetLowering::shouldConvertConstantLoadToIntImm(const APInt &Imm,
                                                          Type *Ty) const {
  assert(Ty->isIntegerTy());

  unsigned BitSize = Ty->getPrimitiveSizeInBits();
  return !(BitSize == 0 || BitSize > 64);
}

bool PPCTargetLowering::isTruncateFree(Type *Ty1, Type *Ty2) const {
  if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
    return false;
  unsigned NumBits1 = Ty1->getPrimitiveSizeInBits();
  unsigned NumBits2 = Ty2->getPrimitiveSizeInBits();
  return NumBits1 == 64 && NumBits2 == 32;
}

bool PPCTargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
  if (!VT1.isInteger() || !VT2.isInteger())
    return false;
  unsigned NumBits1 = VT1.getSizeInBits();
  unsigned NumBits2 = VT2.getSizeInBits();
  return NumBits1 == 64 && NumBits2 == 32;
}

bool PPCTargetLowering::isZExtFree(SDValue Val, EVT VT2) const {
  // Generally speaking, zexts are not free, but they are free when they can be
  // folded with other operations.
  if (LoadSDNode *LD = dyn_cast<LoadSDNode>(Val)) {
    EVT MemVT = LD->getMemoryVT();
    if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
         (Subtarget.isPPC64() && MemVT == MVT::i32)) &&
        (LD->getExtensionType() == ISD::NON_EXTLOAD ||
         LD->getExtensionType() == ISD::ZEXTLOAD))
      return true;
  }

  // FIXME: Add other cases...
  //  - 32-bit shifts with a zext to i64
  //  - zext after ctlz, bswap, etc.
  //  - zext after and by a constant mask

  return TargetLowering::isZExtFree(Val, VT2);
}

bool PPCTargetLowering::isFPExtFree(EVT DestVT, EVT SrcVT) const {
  assert(DestVT.isFloatingPoint() && SrcVT.isFloatingPoint() &&
         "invalid fpext types");
  // Extending to float128 is not free.
  if (DestVT == MVT::f128)
    return false;
  return true;
}

bool PPCTargetLowering::isLegalICmpImmediate(int64_t Imm) const {
  return isInt<16>(Imm) || isUInt<16>(Imm);
}

bool PPCTargetLowering::isLegalAddImmediate(int64_t Imm) const {
  return isInt<16>(Imm) || isUInt<16>(Imm);
}

bool PPCTargetLowering::allowsMisalignedMemoryAccesses(EVT VT, unsigned, Align,
                                                       MachineMemOperand::Flags,
                                                       unsigned *Fast) const {
  if (DisablePPCUnaligned)
    return false;

  // PowerPC supports unaligned memory access for simple non-vector types.
  // Although accessing unaligned addresses is not as efficient as accessing
  // aligned addresses, it is generally more efficient than manual expansion,
  // and generally only traps for software emulation when crossing page
  // boundaries.

  if (!VT.isSimple())
    return false;

  if (VT.isFloatingPoint() && !VT.isVector() &&
      !Subtarget.allowsUnalignedFPAccess())
    return false;

  if (VT.getSimpleVT().isVector()) {
    if (Subtarget.hasVSX()) {
      if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
          VT != MVT::v4f32 && VT != MVT::v4i32)
        return false;
    } else {
      return false;
    }
  }

  if (VT == MVT::ppcf128)
    return false;

  if (Fast)
    *Fast = 1;

  return true;
}

bool PPCTargetLowering::decomposeMulByConstant(LLVMContext &Context, EVT VT,
                                               SDValue C) const {
  // Check integral scalar types.
  if (!VT.isScalarInteger())
    return false;
  if (auto *ConstNode = dyn_cast<ConstantSDNode>(C.getNode())) {
    if (!ConstNode->getAPIntValue().isSignedIntN(64))
      return false;
    // This transformation will generate >= 2 operations. But the following
    // cases will generate <= 2 instructions during ISEL. So exclude them.
    // 1. If the constant multiplier fits 16 bits, it can be handled by one
    // HW instruction, ie. MULLI
    // 2. If the multiplier after shifted fits 16 bits, an extra shift
    // instruction is needed than case 1, ie. MULLI and RLDICR
    int64_t Imm = ConstNode->getSExtValue();
    unsigned Shift = llvm::countr_zero<uint64_t>(Imm);
    Imm >>= Shift;
    if (isInt<16>(Imm))
      return false;
    uint64_t UImm = static_cast<uint64_t>(Imm);
    if (isPowerOf2_64(UImm + 1) || isPowerOf2_64(UImm - 1) ||
        isPowerOf2_64(1 - UImm) || isPowerOf2_64(-1 - UImm))
      return true;
  }
  return false;
}

bool PPCTargetLowering::isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
                                                   EVT VT) const {
  return isFMAFasterThanFMulAndFAdd(
      MF.getFunction(), VT.getTypeForEVT(MF.getFunction().getContext()));
}

bool PPCTargetLowering::isFMAFasterThanFMulAndFAdd(const Function &F,
                                                   Type *Ty) const {
  if (Subtarget.hasSPE() || Subtarget.useSoftFloat())
    return false;
  switch (Ty->getScalarType()->getTypeID()) {
  case Type::FloatTyID:
  case Type::DoubleTyID:
    return true;
  case Type::FP128TyID:
    return Subtarget.hasP9Vector();
  default:
    return false;
  }
}

// FIXME: add more patterns which are not profitable to hoist.
bool PPCTargetLowering::isProfitableToHoist(Instruction *I) const {
  if (!I->hasOneUse())
    return true;

  Instruction *User = I->user_back();
  assert(User && "A single use instruction with no uses.");

  switch (I->getOpcode()) {
  case Instruction::FMul: {
    // Don't break FMA, PowerPC prefers FMA.
    if (User->getOpcode() != Instruction::FSub &&
        User->getOpcode() != Instruction::FAdd)
      return true;

    const TargetOptions &Options = getTargetMachine().Options;
    const Function *F = I->getFunction();
    const DataLayout &DL = F->getDataLayout();
    Type *Ty = User->getOperand(0)->getType();
    bool AllowContract = I->getFastMathFlags().allowContract() &&
                         User->getFastMathFlags().allowContract();

    return !(isFMAFasterThanFMulAndFAdd(*F, Ty) &&
             isOperationLegalOrCustom(ISD::FMA, getValueType(DL, Ty)) &&
             (AllowContract || Options.AllowFPOpFusion == FPOpFusion::Fast));
  }
  case Instruction::Load: {
    // Don't break "store (load float*)" pattern, this pattern will be combined
    // to "store (load int32)" in later InstCombine pass. See function
    // combineLoadToOperationType. On PowerPC, loading a float point takes more
    // cycles than loading a 32 bit integer.
    LoadInst *LI = cast<LoadInst>(I);
    // For the loads that combineLoadToOperationType does nothing, like
    // ordered load, it should be profitable to hoist them.
    // For swifterror load, it can only be used for pointer to pointer type, so
    // later type check should get rid of this case.
    if (!LI->isUnordered())
      return true;

    if (User->getOpcode() != Instruction::Store)
      return true;

    if (I->getType()->getTypeID() != Type::FloatTyID)
      return true;

    return false;
  }
  default:
    return true;
  }
  return true;
}

const MCPhysReg *
PPCTargetLowering::getScratchRegisters(CallingConv::ID) const {
  // LR is a callee-save register, but we must treat it as clobbered by any call
  // site. Hence we include LR in the scratch registers, which are in turn added
  // as implicit-defs for stackmaps and patchpoints. The same reasoning applies
  // to CTR, which is used by any indirect call.
  static const MCPhysReg ScratchRegs[] = {
    PPC::X12, PPC::LR8, PPC::CTR8, 0
  };

  return ScratchRegs;
}

Register PPCTargetLowering::getExceptionPointerRegister(
    const Constant *PersonalityFn) const {
  return Subtarget.isPPC64() ? PPC::X3 : PPC::R3;
}

Register PPCTargetLowering::getExceptionSelectorRegister(
    const Constant *PersonalityFn) const {
  return Subtarget.isPPC64() ? PPC::X4 : PPC::R4;
}

bool
PPCTargetLowering::shouldExpandBuildVectorWithShuffles(
                     EVT VT , unsigned DefinedValues) const {
  if (VT == MVT::v2i64)
    return Subtarget.hasDirectMove(); // Don't need stack ops with direct moves

  if (Subtarget.hasVSX())
    return true;

  return TargetLowering::shouldExpandBuildVectorWithShuffles(VT, DefinedValues);
}

Sched::Preference PPCTargetLowering::getSchedulingPreference(SDNode *N) const {
  if (DisableILPPref || Subtarget.enableMachineScheduler())
    return TargetLowering::getSchedulingPreference(N);

  return Sched::ILP;
}

// Create a fast isel object.
FastISel *
PPCTargetLowering::createFastISel(FunctionLoweringInfo &FuncInfo,
                                  const TargetLibraryInfo *LibInfo) const {
  return PPC::createFastISel(FuncInfo, LibInfo);
}

// 'Inverted' means the FMA opcode after negating one multiplicand.
// For example, (fma -a b c) = (fnmsub a b c)
static unsigned invertFMAOpcode(unsigned Opc) {
  switch (Opc) {
  default:
    llvm_unreachable("Invalid FMA opcode for PowerPC!");
  case ISD::FMA:
    return PPCISD::FNMSUB;
  case PPCISD::FNMSUB:
    return ISD::FMA;
  }
}

SDValue PPCTargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
                                                bool LegalOps, bool OptForSize,
                                                NegatibleCost &Cost,
                                                unsigned Depth) const {
  if (Depth > SelectionDAG::MaxRecursionDepth)
    return SDValue();

  unsigned Opc = Op.getOpcode();
  EVT VT = Op.getValueType();
  SDNodeFlags Flags = Op.getNode()->getFlags();

  switch (Opc) {
  case PPCISD::FNMSUB:
    if (!Op.hasOneUse() || !isTypeLegal(VT))
      break;

    const TargetOptions &Options = getTargetMachine().Options;
    SDValue N0 = Op.getOperand(0);
    SDValue N1 = Op.getOperand(1);
    SDValue N2 = Op.getOperand(2);
    SDLoc Loc(Op);

    NegatibleCost N2Cost = NegatibleCost::Expensive;
    SDValue NegN2 =
        getNegatedExpression(N2, DAG, LegalOps, OptForSize, N2Cost, Depth + 1);

    if (!NegN2)
      return SDValue();

    // (fneg (fnmsub a b c)) => (fnmsub (fneg a) b (fneg c))
    // (fneg (fnmsub a b c)) => (fnmsub a (fneg b) (fneg c))
    // These transformations may change sign of zeroes. For example,
    // -(-ab-(-c))=-0 while -(-(ab-c))=+0 when a=b=c=1.
    if (Flags.hasNoSignedZeros() || Options.NoSignedZerosFPMath) {
      // Try and choose the cheaper one to negate.
      NegatibleCost N0Cost = NegatibleCost::Expensive;
      SDValue NegN0 = getNegatedExpression(N0, DAG, LegalOps, OptForSize,
                                           N0Cost, Depth + 1);

      NegatibleCost N1Cost = NegatibleCost::Expensive;
      SDValue NegN1 = getNegatedExpression(N1, DAG, LegalOps, OptForSize,
                                           N1Cost, Depth + 1);

      if (NegN0 && N0Cost <= N1Cost) {
        Cost = std::min(N0Cost, N2Cost);
        return DAG.getNode(Opc, Loc, VT, NegN0, N1, NegN2, Flags);
      } else if (NegN1) {
        Cost = std::min(N1Cost, N2Cost);
        return DAG.getNode(Opc, Loc, VT, N0, NegN1, NegN2, Flags);
      }
    }

    // (fneg (fnmsub a b c)) => (fma a b (fneg c))
    if (isOperationLegal(ISD::FMA, VT)) {
      Cost = N2Cost;
      return DAG.getNode(ISD::FMA, Loc, VT, N0, N1, NegN2, Flags);
    }

    break;
  }

  return TargetLowering::getNegatedExpression(Op, DAG, LegalOps, OptForSize,
                                              Cost, Depth);
}

// Override to enable LOAD_STACK_GUARD lowering on Linux.
bool PPCTargetLowering::useLoadStackGuardNode(const Module &M) const {
  if (M.getStackProtectorGuard() == "tls" || Subtarget.isTargetLinux())
    return true;
  return TargetLowering::useLoadStackGuardNode(M);
}

bool PPCTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
                                     bool ForCodeSize) const {
  if (!VT.isSimple() || !Subtarget.hasVSX())
    return false;

  switch(VT.getSimpleVT().SimpleTy) {
  default:
    // For FP types that are currently not supported by PPC backend, return
    // false. Examples: f16, f80.
    return false;
  case MVT::f32:
  case MVT::f64: {
    if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
      // we can materialize all immediatess via XXSPLTI32DX and XXSPLTIDP.
      return true;
    }
    bool IsExact;
    APSInt IntResult(16, false);
    // The rounding mode doesn't really matter because we only care about floats
    // that can be converted to integers exactly.
    Imm.convertToInteger(IntResult, APFloat::rmTowardZero, &IsExact);
    // For exact values in the range [-16, 15] we can materialize the float.
    if (IsExact && IntResult <= 15 && IntResult >= -16)
      return true;
    return Imm.isZero();
  }
  case MVT::ppcf128:
    return Imm.isPosZero();
  }
}

// For vector shift operation op, fold
// (op x, (and y, ((1 << numbits(x)) - 1))) -> (target op x, y)
static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N,
                                  SelectionDAG &DAG) {
  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);
  EVT VT = N0.getValueType();
  unsigned OpSizeInBits = VT.getScalarSizeInBits();
  unsigned Opcode = N->getOpcode();
  unsigned TargetOpcode;

  switch (Opcode) {
  default:
    llvm_unreachable("Unexpected shift operation");
  case ISD::SHL:
    TargetOpcode = PPCISD::SHL;
    break;
  case ISD::SRL:
    TargetOpcode = PPCISD::SRL;
    break;
  case ISD::SRA:
    TargetOpcode = PPCISD::SRA;
    break;
  }

  if (VT.isVector() && TLI.isOperationLegal(Opcode, VT) &&
      N1->getOpcode() == ISD::AND)
    if (ConstantSDNode *Mask = isConstOrConstSplat(N1->getOperand(1)))
      if (Mask->getZExtValue() == OpSizeInBits - 1)
        return DAG.getNode(TargetOpcode, SDLoc(N), VT, N0, N1->getOperand(0));

  return SDValue();
}

SDValue PPCTargetLowering::combineVectorShift(SDNode *N,
                                              DAGCombinerInfo &DCI) const {
  EVT VT = N->getValueType(0);
  assert(VT.isVector() && "Vector type expected.");

  unsigned Opc = N->getOpcode();
  assert((Opc == ISD::SHL || Opc == ISD::SRL || Opc == ISD::SRA) &&
         "Unexpected opcode.");

  if (!isOperationLegal(Opc, VT))
    return SDValue();

  EVT EltTy = VT.getScalarType();
  unsigned EltBits = EltTy.getSizeInBits();
  if (EltTy != MVT::i64 && EltTy != MVT::i32)
    return SDValue();

  SDValue N1 = N->getOperand(1);
  uint64_t SplatBits = 0;
  bool AddSplatCase = false;
  unsigned OpcN1 = N1.getOpcode();
  if (OpcN1 == PPCISD::VADD_SPLAT &&
      N1.getConstantOperandVal(1) == VT.getVectorNumElements()) {
    AddSplatCase = true;
    SplatBits = N1.getConstantOperandVal(0);
  }

  if (!AddSplatCase) {
    if (OpcN1 != ISD::BUILD_VECTOR)
      return SDValue();

    unsigned SplatBitSize;
    bool HasAnyUndefs;
    APInt APSplatBits, APSplatUndef;
    BuildVectorSDNode *BVN = cast<BuildVectorSDNode>(N1);
    bool BVNIsConstantSplat =
        BVN->isConstantSplat(APSplatBits, APSplatUndef, SplatBitSize,
                             HasAnyUndefs, 0, !Subtarget.isLittleEndian());
    if (!BVNIsConstantSplat || SplatBitSize != EltBits)
      return SDValue();
    SplatBits = APSplatBits.getZExtValue();
  }

  SDLoc DL(N);
  SDValue N0 = N->getOperand(0);
  // PPC vector shifts by word/double look at only the low 5/6 bits of the
  // shift vector, which means the max value is 31/63. A shift vector of all
  // 1s will be truncated to 31/63, which is useful as vspltiw is limited to
  // -16 to 15 range.
  if (SplatBits == (EltBits - 1)) {
    unsigned NewOpc;
    switch (Opc) {
    case ISD::SHL:
      NewOpc = PPCISD::SHL;
      break;
    case ISD::SRL:
      NewOpc = PPCISD::SRL;
      break;
    case ISD::SRA:
      NewOpc = PPCISD::SRA;
      break;
    }
    SDValue SplatOnes = getCanonicalConstSplat(255, 1, VT, DCI.DAG, DL);
    return DCI.DAG.getNode(NewOpc, DL, VT, N0, SplatOnes);
  }

  if (Opc != ISD::SHL || !isOperationLegal(ISD::ADD, VT))
    return SDValue();

  // For 64-bit there is no splat immediate so we want to catch shift by 1 here
  // before the BUILD_VECTOR is replaced by a load.
  if (EltTy != MVT::i64 || SplatBits != 1)
    return SDValue();

  return DCI.DAG.getNode(ISD::ADD, SDLoc(N), VT, N0, N0);
}

SDValue PPCTargetLowering::combineSHL(SDNode *N, DAGCombinerInfo &DCI) const {
  if (auto Value = stripModuloOnShift(*this, N, DCI.DAG))
    return Value;

  if (N->getValueType(0).isVector())
    return combineVectorShift(N, DCI);

  SDValue N0 = N->getOperand(0);
  ConstantSDNode *CN1 = dyn_cast<ConstantSDNode>(N->getOperand(1));
  if (!Subtarget.isISA3_0() || !Subtarget.isPPC64() ||
      N0.getOpcode() != ISD::SIGN_EXTEND ||
      N0.getOperand(0).getValueType() != MVT::i32 || CN1 == nullptr ||
      N->getValueType(0) != MVT::i64)
    return SDValue();

  // We can't save an operation here if the value is already extended, and
  // the existing shift is easier to combine.
  SDValue ExtsSrc = N0.getOperand(0);
  if (ExtsSrc.getOpcode() == ISD::TRUNCATE &&
      ExtsSrc.getOperand(0).getOpcode() == ISD::AssertSext)
    return SDValue();

  SDLoc DL(N0);
  SDValue ShiftBy = SDValue(CN1, 0);
  // We want the shift amount to be i32 on the extswli, but the shift could
  // have an i64.
  if (ShiftBy.getValueType() == MVT::i64)
    ShiftBy = DCI.DAG.getConstant(CN1->getZExtValue(), DL, MVT::i32);

  return DCI.DAG.getNode(PPCISD::EXTSWSLI, DL, MVT::i64, N0->getOperand(0),
                         ShiftBy);
}

SDValue PPCTargetLowering::combineSRA(SDNode *N, DAGCombinerInfo &DCI) const {
  if (auto Value = stripModuloOnShift(*this, N, DCI.DAG))
    return Value;

  if (N->getValueType(0).isVector())
    return combineVectorShift(N, DCI);

  return SDValue();
}

SDValue PPCTargetLowering::combineSRL(SDNode *N, DAGCombinerInfo &DCI) const {
  if (auto Value = stripModuloOnShift(*this, N, DCI.DAG))
    return Value;

  if (N->getValueType(0).isVector())
    return combineVectorShift(N, DCI);

  return SDValue();
}

// Transform (add X, (zext(setne Z, C))) -> (addze X, (addic (addi Z, -C), -1))
// Transform (add X, (zext(sete  Z, C))) -> (addze X, (subfic (addi Z, -C), 0))
// When C is zero, the equation (addi Z, -C) can be simplified to Z
// Requirement: -C in [-32768, 32767], X and Z are MVT::i64 types
static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
                                 const PPCSubtarget &Subtarget) {
  if (!Subtarget.isPPC64())
    return SDValue();

  SDValue LHS = N->getOperand(0);
  SDValue RHS = N->getOperand(1);

  auto isZextOfCompareWithConstant = [](SDValue Op) {
    if (Op.getOpcode() != ISD::ZERO_EXTEND || !Op.hasOneUse() ||
        Op.getValueType() != MVT::i64)
      return false;

    SDValue Cmp = Op.getOperand(0);
    if (Cmp.getOpcode() != ISD::SETCC || !Cmp.hasOneUse() ||
        Cmp.getOperand(0).getValueType() != MVT::i64)
      return false;

    if (auto *Constant = dyn_cast<ConstantSDNode>(Cmp.getOperand(1))) {
      int64_t NegConstant = 0 - Constant->getSExtValue();
      // Due to the limitations of the addi instruction,
      // -C is required to be [-32768, 32767].
      return isInt<16>(NegConstant);
    }

    return false;
  };

  bool LHSHasPattern = isZextOfCompareWithConstant(LHS);
  bool RHSHasPattern = isZextOfCompareWithConstant(RHS);

  // If there is a pattern, canonicalize a zext operand to the RHS.
  if (LHSHasPattern && !RHSHasPattern)
    std::swap(LHS, RHS);
  else if (!LHSHasPattern && !RHSHasPattern)
    return SDValue();

  SDLoc DL(N);
  EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
  SDVTList VTs = DAG.getVTList(MVT::i64, CarryType);
  SDValue Cmp = RHS.getOperand(0);
  SDValue Z = Cmp.getOperand(0);
  auto *Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
  int64_t NegConstant = 0 - Constant->getSExtValue();

  switch(cast<CondCodeSDNode>(Cmp.getOperand(2))->get()) {
  default: break;
  case ISD::SETNE: {
    //                                 when C == 0
    //                             --> addze X, (addic Z, -1).carry
    //                            /
    // add X, (zext(setne Z, C))--
    //                            \    when -32768 <= -C <= 32767 && C != 0
    //                             --> addze X, (addic (addi Z, -C), -1).carry
    SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
                              DAG.getConstant(NegConstant, DL, MVT::i64));
    SDValue AddOrZ = NegConstant != 0 ? Add : Z;
    SDValue Addc =
        DAG.getNode(ISD::UADDO_CARRY, DL, DAG.getVTList(MVT::i64, CarryType),
                    AddOrZ, DAG.getAllOnesConstant(DL, MVT::i64),
                    DAG.getConstant(0, DL, CarryType));
    return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
                       DAG.getConstant(0, DL, MVT::i64),
                       SDValue(Addc.getNode(), 1));
  }
  case ISD::SETEQ: {
    //                                 when C == 0
    //                             --> addze X, (subfic Z, 0).carry
    //                            /
    // add X, (zext(sete  Z, C))--
    //                            \    when -32768 <= -C <= 32767 && C != 0
    //                             --> addze X, (subfic (addi Z, -C), 0).carry
    SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
                              DAG.getConstant(NegConstant, DL, MVT::i64));
    SDValue AddOrZ = NegConstant != 0 ? Add : Z;
    SDValue Subc =
        DAG.getNode(ISD::USUBO_CARRY, DL, DAG.getVTList(MVT::i64, CarryType),
                    DAG.getConstant(0, DL, MVT::i64), AddOrZ,
                    DAG.getConstant(0, DL, CarryType));
    SDValue Invert = DAG.getNode(ISD::XOR, DL, CarryType, Subc.getValue(1),
                                 DAG.getConstant(1UL, DL, CarryType));
    return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
                       DAG.getConstant(0, DL, MVT::i64), Invert);
  }
  }

  return SDValue();
}

// Transform
// (add C1, (MAT_PCREL_ADDR GlobalAddr+C2)) to
// (MAT_PCREL_ADDR GlobalAddr+(C1+C2))
// In this case both C1 and C2 must be known constants.
// C1+C2 must fit into a 34 bit signed integer.
static SDValue combineADDToMAT_PCREL_ADDR(SDNode *N, SelectionDAG &DAG,
                                          const PPCSubtarget &Subtarget) {
  if (!Subtarget.isUsingPCRelativeCalls())
    return SDValue();

  // Check both Operand 0 and Operand 1 of the ADD node for the PCRel node.
  // If we find that node try to cast the Global Address and the Constant.
  SDValue LHS = N->getOperand(0);
  SDValue RHS = N->getOperand(1);

  if (LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
    std::swap(LHS, RHS);

  if (LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
    return SDValue();

  // Operand zero of PPCISD::MAT_PCREL_ADDR is the GA node.
  GlobalAddressSDNode *GSDN = dyn_cast<GlobalAddressSDNode>(LHS.getOperand(0));
  ConstantSDNode* ConstNode = dyn_cast<ConstantSDNode>(RHS);

  // Check that both casts succeeded.
  if (!GSDN || !ConstNode)
    return SDValue();

  int64_t NewOffset = GSDN->getOffset() + ConstNode->getSExtValue();
  SDLoc DL(GSDN);

  // The signed int offset needs to fit in 34 bits.
  if (!isInt<34>(NewOffset))
    return SDValue();

  // The new global address is a copy of the old global address except
  // that it has the updated Offset.
  SDValue GA =
      DAG.getTargetGlobalAddress(GSDN->getGlobal(), DL, GSDN->getValueType(0),
                                 NewOffset, GSDN->getTargetFlags());
  SDValue MatPCRel =
      DAG.getNode(PPCISD::MAT_PCREL_ADDR, DL, GSDN->getValueType(0), GA);
  return MatPCRel;
}

// Transform (add X, (build_vector (T 1), (T 1), ...)) -> (sub X, (XXLEQVOnes))
// XXLEQVOnes creates an all-1s vector (0xFFFFFFFF...) efficiently via xxleqv
// Mathematical identity: X + 1 = X - (-1)
// Applies to v4i32, v2i64, v8i16, v16i8 where all elements are constant 1
// Requirement: VSX feature for efficient xxleqv generation
static SDValue combineADDToSUB(SDNode *N, SelectionDAG &DAG,
                               const PPCSubtarget &Subtarget) {

  EVT VT = N->getValueType(0);
  if (!Subtarget.hasVSX())
    return SDValue();

  // Handle v2i64, v4i32, v8i16 and v16i8 types
  if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
        VT == MVT::v2i64))
    return SDValue();

  SDValue LHS = N->getOperand(0);
  SDValue RHS = N->getOperand(1);

  // Check if RHS is BUILD_VECTOR
  if (RHS.getOpcode() != ISD::BUILD_VECTOR)
    return SDValue();

  // Check if all the elements are 1
  unsigned NumOfEles = RHS.getNumOperands();
  for (unsigned i = 0; i < NumOfEles; ++i) {
    auto *CN = dyn_cast<ConstantSDNode>(RHS.getOperand(i));
    if (!CN || CN->getSExtValue() != 1)
      return SDValue();
  }
  SDLoc DL(N);

  SDValue MinusOne = DAG.getConstant(APInt::getAllOnes(32), DL, MVT::i32);
  SmallVector<SDValue, 4> Ops(4, MinusOne);
  SDValue AllOnesVec = DAG.getBuildVector(MVT::v4i32, DL, Ops);

  // Bitcast to the target vector type
  SDValue Bitcast = DAG.getNode(ISD::BITCAST, DL, VT, AllOnesVec);

  return DAG.getNode(ISD::SUB, DL, VT, LHS, Bitcast);
}

SDValue PPCTargetLowering::combineADD(SDNode *N, DAGCombinerInfo &DCI) const {
  if (auto Value = combineADDToADDZE(N, DCI.DAG, Subtarget))
    return Value;

  if (auto Value = combineADDToMAT_PCREL_ADDR(N, DCI.DAG, Subtarget))
    return Value;

  if (auto Value = combineADDToSUB(N, DCI.DAG, Subtarget))
    return Value;
  return SDValue();
}

// Detect TRUNCATE operations on bitcasts of float128 values.
// What we are looking for here is the situtation where we extract a subset
// of bits from a 128 bit float.
// This can be of two forms:
// 1) BITCAST of f128 feeding TRUNCATE
// 2) BITCAST of f128 feeding SRL (a shift) feeding TRUNCATE
// The reason this is required is because we do not have a legal i128 type
// and so we want to prevent having to store the f128 and then reload part
// of it.
SDValue PPCTargetLowering::combineTRUNCATE(SDNode *N,
                                           DAGCombinerInfo &DCI) const {
  // If we are using CRBits then try that first.
  if (Subtarget.useCRBits()) {
    // Check if CRBits did anything and return that if it did.
    if (SDValue CRTruncValue = DAGCombineTruncBoolExt(N, DCI))
      return CRTruncValue;
  }

  SDLoc dl(N);
  SDValue Op0 = N->getOperand(0);

  // Looking for a truncate of i128 to i64.
  if (Op0.getValueType() != MVT::i128 || N->getValueType(0) != MVT::i64)
    return SDValue();

  int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;

  // SRL feeding TRUNCATE.
  if (Op0.getOpcode() == ISD::SRL) {
    ConstantSDNode *ConstNode = dyn_cast<ConstantSDNode>(Op0.getOperand(1));
    // The right shift has to be by 64 bits.
    if (!ConstNode || ConstNode->getZExtValue() != 64)
      return SDValue();

    // Switch the element number to extract.
    EltToExtract = EltToExtract ? 0 : 1;
    // Update Op0 past the SRL.
    Op0 = Op0.getOperand(0);
  }

  // BITCAST feeding a TRUNCATE possibly via SRL.
  if (Op0.getOpcode() == ISD::BITCAST &&
      Op0.getValueType() == MVT::i128 &&
      Op0.getOperand(0).getValueType() == MVT::f128) {
    SDValue Bitcast = DCI.DAG.getBitcast(MVT::v2i64, Op0.getOperand(0));
    return DCI.DAG.getNode(
        ISD::EXTRACT_VECTOR_ELT, dl, MVT::i64, Bitcast,
        DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
  }
  return SDValue();
}

SDValue PPCTargetLowering::combineMUL(SDNode *N, DAGCombinerInfo &DCI) const {
  SelectionDAG &DAG = DCI.DAG;

  ConstantSDNode *ConstOpOrElement = isConstOrConstSplat(N->getOperand(1));
  if (!ConstOpOrElement)
    return SDValue();

  // An imul is usually smaller than the alternative sequence for legal type.
  if (DAG.getMachineFunction().getFunction().hasMinSize() &&
      isOperationLegal(ISD::MUL, N->getValueType(0)))
    return SDValue();

  auto IsProfitable = [this](bool IsNeg, bool IsAddOne, EVT VT) -> bool {
    switch (this->Subtarget.getCPUDirective()) {
    default:
      // TODO: enhance the condition for subtarget before pwr8
      return false;
    case PPC::DIR_PWR8:
      //  type        mul     add    shl
      // scalar        4       1      1
      // vector        7       2      2
      return true;
    case PPC::DIR_PWR9:
    case PPC::DIR_PWR10:
    case PPC::DIR_PWR11:
    case PPC::DIR_PWR_FUTURE:
      //  type        mul     add    shl
      // scalar        5       2      2
      // vector        7       2      2

      // The cycle RATIO of related operations are showed as a table above.
      // Because mul is 5(scalar)/7(vector), add/sub/shl are all 2 for both
      // scalar and vector type. For 2 instrs patterns, add/sub + shl
      // are 4, it is always profitable; but for 3 instrs patterns
      // (mul x, -(2^N + 1)) => -(add (shl x, N), x), sub + add + shl are 6.
      // So we should only do it for vector type.
      return IsAddOne && IsNeg ? VT.isVector() : true;
    }
  };

  EVT VT = N->getValueType(0);
  SDLoc DL(N);

  const APInt &MulAmt = ConstOpOrElement->getAPIntValue();
  bool IsNeg = MulAmt.isNegative();
  APInt MulAmtAbs = MulAmt.abs();

  if ((MulAmtAbs - 1).isPowerOf2()) {
    // (mul x, 2^N + 1) => (add (shl x, N), x)
    // (mul x, -(2^N + 1)) => -(add (shl x, N), x)

    if (!IsProfitable(IsNeg, true, VT))
      return SDValue();

    SDValue Op0 = N->getOperand(0);
    SDValue Op1 =
        DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
                    DAG.getConstant((MulAmtAbs - 1).logBase2(), DL, VT));
    SDValue Res = DAG.getNode(ISD::ADD, DL, VT, Op0, Op1);

    if (!IsNeg)
      return Res;

    return DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), Res);
  } else if ((MulAmtAbs + 1).isPowerOf2()) {
    // (mul x, 2^N - 1) => (sub (shl x, N), x)
    // (mul x, -(2^N - 1)) => (sub x, (shl x, N))

    if (!IsProfitable(IsNeg, false, VT))
      return SDValue();

    SDValue Op0 = N->getOperand(0);
    SDValue Op1 =
        DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
                    DAG.getConstant((MulAmtAbs + 1).logBase2(), DL, VT));

    if (!IsNeg)
      return DAG.getNode(ISD::SUB, DL, VT, Op1, Op0);
    else
      return DAG.getNode(ISD::SUB, DL, VT, Op0, Op1);

  } else {
    return SDValue();
  }
}

// Combine fma-like op (like fnmsub) with fnegs to appropriate op. Do this
// in combiner since we need to check SD flags and other subtarget features.
SDValue PPCTargetLowering::combineFMALike(SDNode *N,
                                          DAGCombinerInfo &DCI) const {
  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);
  SDValue N2 = N->getOperand(2);
  SDNodeFlags Flags = N->getFlags();
  EVT VT = N->getValueType(0);
  SelectionDAG &DAG = DCI.DAG;
  const TargetOptions &Options = getTargetMachine().Options;
  unsigned Opc = N->getOpcode();
  bool CodeSize = DAG.getMachineFunction().getFunction().hasOptSize();
  bool LegalOps = !DCI.isBeforeLegalizeOps();
  SDLoc Loc(N);

  if (!isOperationLegal(ISD::FMA, VT))
    return SDValue();

  // Allowing transformation to FNMSUB may change sign of zeroes when ab-c=0
  // since (fnmsub a b c)=-0 while c-ab=+0.
  if (!Flags.hasNoSignedZeros() && !Options.NoSignedZerosFPMath)
    return SDValue();

  // (fma (fneg a) b c) => (fnmsub a b c)
  // (fnmsub (fneg a) b c) => (fma a b c)
  if (SDValue NegN0 = getCheaperNegatedExpression(N0, DAG, LegalOps, CodeSize))
    return DAG.getNode(invertFMAOpcode(Opc), Loc, VT, NegN0, N1, N2, Flags);

  // (fma a (fneg b) c) => (fnmsub a b c)
  // (fnmsub a (fneg b) c) => (fma a b c)
  if (SDValue NegN1 = getCheaperNegatedExpression(N1, DAG, LegalOps, CodeSize))
    return DAG.getNode(invertFMAOpcode(Opc), Loc, VT, N0, NegN1, N2, Flags);

  return SDValue();
}

bool PPCTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const {
  // Only duplicate to increase tail-calls for the 64bit SysV ABIs.
  if (!Subtarget.is64BitELFABI())
    return false;

  // If not a tail call then no need to proceed.
  if (!CI->isTailCall())
    return false;

  // If sibling calls have been disabled and tail-calls aren't guaranteed
  // there is no reason to duplicate.
  auto &TM = getTargetMachine();
  if (!TM.Options.GuaranteedTailCallOpt && DisableSCO)
    return false;

  // Can't tail call a function called indirectly, or if it has variadic args.
  const Function *Callee = CI->getCalledFunction();
  if (!Callee || Callee->isVarArg())
    return false;

  // Make sure the callee and caller calling conventions are eligible for tco.
  const Function *Caller = CI->getParent()->getParent();
  if (!areCallingConvEligibleForTCO_64SVR4(Caller->getCallingConv(),
                                           CI->getCallingConv()))
      return false;

  // If the function is local then we have a good chance at tail-calling it
  return getTargetMachine().shouldAssumeDSOLocal(Callee);
}

bool PPCTargetLowering::
isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const {
  const Value *Mask = AndI.getOperand(1);
  // If the mask is suitable for andi. or andis. we should sink the and.
  if (const ConstantInt *CI = dyn_cast<ConstantInt>(Mask)) {
    // Can't handle constants wider than 64-bits.
    if (CI->getBitWidth() > 64)
      return false;
    int64_t ConstVal = CI->getZExtValue();
    return isUInt<16>(ConstVal) ||
      (isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
  }

  // For non-constant masks, we can always use the record-form and.
  return true;
}

/// getAddrModeForFlags - Based on the set of address flags, select the most
/// optimal instruction format to match by.
PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(unsigned Flags) const {
  // This is not a node we should be handling here.
  if (Flags == PPC::MOF_None)
    return PPC::AM_None;
  // Unaligned D-Forms are tried first, followed by the aligned D-Forms.
  for (auto FlagSet : AddrModesMap.at(PPC::AM_DForm))
    if ((Flags & FlagSet) == FlagSet)
      return PPC::AM_DForm;
  for (auto FlagSet : AddrModesMap.at(PPC::AM_DSForm))
    if ((Flags & FlagSet) == FlagSet)
      return PPC::AM_DSForm;
  for (auto FlagSet : AddrModesMap.at(PPC::AM_DQForm))
    if ((Flags & FlagSet) == FlagSet)
      return PPC::AM_DQForm;
  for (auto FlagSet : AddrModesMap.at(PPC::AM_PrefixDForm))
    if ((Flags & FlagSet) == FlagSet)
      return PPC::AM_PrefixDForm;
  // If no other forms are selected, return an X-Form as it is the most
  // general addressing mode.
  return PPC::AM_XForm;
}

/// Set alignment flags based on whether or not the Frame Index is aligned.
/// Utilized when computing flags for address computation when selecting
/// load and store instructions.
static void setAlignFlagsForFI(SDValue N, unsigned &FlagSet,
                               SelectionDAG &DAG) {
  bool IsAdd = ((N.getOpcode() == ISD::ADD) || (N.getOpcode() == ISD::OR));
  FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(IsAdd ? N.getOperand(0) : N);
  if (!FI)
    return;
  const MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
  unsigned FrameIndexAlign = MFI.getObjectAlign(FI->getIndex()).value();
  // If this is (add $FI, $S16Imm), the alignment flags are already set
  // based on the immediate. We just need to clear the alignment flags
  // if the FI alignment is weaker.
  if ((FrameIndexAlign % 4) != 0)
    FlagSet &= ~PPC::MOF_RPlusSImm16Mult4;
  if ((FrameIndexAlign % 16) != 0)
    FlagSet &= ~PPC::MOF_RPlusSImm16Mult16;
  // If the address is a plain FrameIndex, set alignment flags based on
  // FI alignment.
  if (!IsAdd) {
    if ((FrameIndexAlign % 4) == 0)
      FlagSet |= PPC::MOF_RPlusSImm16Mult4;
    if ((FrameIndexAlign % 16) == 0)
      FlagSet |= PPC::MOF_RPlusSImm16Mult16;
  }
}

/// Given a node, compute flags that are used for address computation when
/// selecting load and store instructions. The flags computed are stored in
/// FlagSet. This function takes into account whether the node is a constant,
/// an ADD, OR, or a constant, and computes the address flags accordingly.
static void computeFlagsForAddressComputation(SDValue N, unsigned &FlagSet,
                                              SelectionDAG &DAG) {
  // Set the alignment flags for the node depending on if the node is
  // 4-byte or 16-byte aligned.
  auto SetAlignFlagsForImm = [&](uint64_t Imm) {
    if ((Imm & 0x3) == 0)
      FlagSet |= PPC::MOF_RPlusSImm16Mult4;
    if ((Imm & 0xf) == 0)
      FlagSet |= PPC::MOF_RPlusSImm16Mult16;
  };

  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N)) {
    // All 32-bit constants can be computed as LIS + Disp.
    const APInt &ConstImm = CN->getAPIntValue();
    if (ConstImm.isSignedIntN(32)) { // Flag to handle 32-bit constants.
      FlagSet |= PPC::MOF_AddrIsSImm32;
      SetAlignFlagsForImm(ConstImm.getZExtValue());
      setAlignFlagsForFI(N, FlagSet, DAG);
    }
    if (ConstImm.isSignedIntN(34)) // Flag to handle 34-bit constants.
      FlagSet |= PPC::MOF_RPlusSImm34;
    else // Let constant materialization handle large constants.
      FlagSet |= PPC::MOF_NotAddNorCst;
  } else if (N.getOpcode() == ISD::ADD || provablyDisjointOr(DAG, N)) {
    // This address can be represented as an addition of:
    // - Register + Imm16 (possibly a multiple of 4/16)
    // - Register + Imm34
    // - Register + PPCISD::Lo
    // - Register + Register
    // In any case, we won't have to match this as Base + Zero.
    SDValue RHS = N.getOperand(1);
    if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(RHS)) {
      const APInt &ConstImm = CN->getAPIntValue();
      if (ConstImm.isSignedIntN(16)) {
        FlagSet |= PPC::MOF_RPlusSImm16; // Signed 16-bit immediates.
        SetAlignFlagsForImm(ConstImm.getZExtValue());
        setAlignFlagsForFI(N, FlagSet, DAG);
      }
      if (ConstImm.isSignedIntN(34))
        FlagSet |= PPC::MOF_RPlusSImm34; // Signed 34-bit immediates.
      else
        FlagSet |= PPC::MOF_RPlusR; // Register.
    } else if (RHS.getOpcode() == PPCISD::Lo && !RHS.getConstantOperandVal(1))
      FlagSet |= PPC::MOF_RPlusLo; // PPCISD::Lo.
    else
      FlagSet |= PPC::MOF_RPlusR;
  } else { // The address computation is not a constant or an addition.
    setAlignFlagsForFI(N, FlagSet, DAG);
    FlagSet |= PPC::MOF_NotAddNorCst;
  }
}

static bool isPCRelNode(SDValue N) {
  return (N.getOpcode() == PPCISD::MAT_PCREL_ADDR ||
      isValidPCRelNode<ConstantPoolSDNode>(N) ||
      isValidPCRelNode<GlobalAddressSDNode>(N) ||
      isValidPCRelNode<JumpTableSDNode>(N) ||
      isValidPCRelNode<BlockAddressSDNode>(N));
}

/// computeMOFlags - Given a node N and it's Parent (a MemSDNode), compute
/// the address flags of the load/store instruction that is to be matched.
unsigned PPCTargetLowering::computeMOFlags(const SDNode *Parent, SDValue N,
                                           SelectionDAG &DAG) const {
  unsigned FlagSet = PPC::MOF_None;

  // Compute subtarget flags.
  if (!Subtarget.hasP9Vector())
    FlagSet |= PPC::MOF_SubtargetBeforeP9;
  else
    FlagSet |= PPC::MOF_SubtargetP9;

  if (Subtarget.hasPrefixInstrs())
    FlagSet |= PPC::MOF_SubtargetP10;

  if (Subtarget.hasSPE())
    FlagSet |= PPC::MOF_SubtargetSPE;

  // Check if we have a PCRel node and return early.
  if ((FlagSet & PPC::MOF_SubtargetP10) && isPCRelNode(N))
    return FlagSet;

  // If the node is the paired load/store intrinsics, compute flags for
  // address computation and return early.
  unsigned ParentOp = Parent->getOpcode();
  if (Subtarget.isISA3_1() && ((ParentOp == ISD::INTRINSIC_W_CHAIN) ||
                               (ParentOp == ISD::INTRINSIC_VOID))) {
    unsigned ID = Parent->getConstantOperandVal(1);
    if ((ID == Intrinsic::ppc_vsx_lxvp) || (ID == Intrinsic::ppc_vsx_stxvp)) {
      SDValue IntrinOp = (ID == Intrinsic::ppc_vsx_lxvp)
                             ? Parent->getOperand(2)
                             : Parent->getOperand(3);
      computeFlagsForAddressComputation(IntrinOp, FlagSet, DAG);
      FlagSet |= PPC::MOF_Vector;
      return FlagSet;
    }
  }

  // Mark this as something we don't want to handle here if it is atomic
  // or pre-increment instruction.
  if (const LSBaseSDNode *LSB = dyn_cast<LSBaseSDNode>(Parent))
    if (LSB->isIndexed())
      return PPC::MOF_None;

  // Compute in-memory type flags. This is based on if there are scalars,
  // floats or vectors.
  const MemSDNode *MN = dyn_cast<MemSDNode>(Parent);
  assert(MN && "Parent should be a MemSDNode!");
  EVT MemVT = MN->getMemoryVT();
  unsigned Size = MemVT.getSizeInBits();
  if (MemVT.isScalarInteger()) {
    assert(Size <= 128 &&
           "Not expecting scalar integers larger than 16 bytes!");
    if (Size < 32)
      FlagSet |= PPC::MOF_SubWordInt;
    else if (Size == 32)
      FlagSet |= PPC::MOF_WordInt;
    else
      FlagSet |= PPC::MOF_DoubleWordInt;
  } else if (MemVT.isVector() && !MemVT.isFloatingPoint()) { // Integer vectors.
    if (Size == 128)
      FlagSet |= PPC::MOF_Vector;
    else if (Size == 256) {
      assert(Subtarget.pairedVectorMemops() &&
             "256-bit vectors are only available when paired vector memops is "
             "enabled!");
      FlagSet |= PPC::MOF_Vector;
    } else
      llvm_unreachable("Not expecting illegal vectors!");
  } else { // Floating point type: can be scalar, f128 or vector types.
    if (Size == 32 || Size == 64)
      FlagSet |= PPC::MOF_ScalarFloat;
    else if (MemVT == MVT::f128 || MemVT.isVector())
      FlagSet |= PPC::MOF_Vector;
    else
      llvm_unreachable("Not expecting illegal scalar floats!");
  }

  // Compute flags for address computation.
  computeFlagsForAddressComputation(N, FlagSet, DAG);

  // Compute type extension flags.
  if (const LoadSDNode *LN = dyn_cast<LoadSDNode>(Parent)) {
    switch (LN->getExtensionType()) {
    case ISD::SEXTLOAD:
      FlagSet |= PPC::MOF_SExt;
      break;
    case ISD::EXTLOAD:
    case ISD::ZEXTLOAD:
      FlagSet |= PPC::MOF_ZExt;
      break;
    case ISD::NON_EXTLOAD:
      FlagSet |= PPC::MOF_NoExt;
      break;
    }
  } else
    FlagSet |= PPC::MOF_NoExt;

  // For integers, no extension is the same as zero extension.
  // We set the extension mode to zero extension so we don't have
  // to add separate entries in AddrModesMap for loads and stores.
  if (MemVT.isScalarInteger() && (FlagSet & PPC::MOF_NoExt)) {
    FlagSet |= PPC::MOF_ZExt;
    FlagSet &= ~PPC::MOF_NoExt;
  }

  // If we don't have prefixed instructions, 34-bit constants should be
  // treated as PPC::MOF_NotAddNorCst so they can match D-Forms.
  bool IsNonP1034BitConst =
      ((PPC::MOF_RPlusSImm34 | PPC::MOF_AddrIsSImm32 | PPC::MOF_SubtargetP10) &
       FlagSet) == PPC::MOF_RPlusSImm34;
  if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::OR &&
      IsNonP1034BitConst)
    FlagSet |= PPC::MOF_NotAddNorCst;

  return FlagSet;
}

/// SelectForceXFormMode - Given the specified address, force it to be
/// represented as an indexed [r+r] operation (an XForm instruction).
PPC::AddrMode PPCTargetLowering::SelectForceXFormMode(SDValue N, SDValue &Disp,
                                                      SDValue &Base,
                                                      SelectionDAG &DAG) const {

  PPC::AddrMode Mode = PPC::AM_XForm;
  int16_t ForceXFormImm = 0;
  if (provablyDisjointOr(DAG, N) &&
      !isIntS16Immediate(N.getOperand(1), ForceXFormImm)) {
    Disp = N.getOperand(0);
    Base = N.getOperand(1);
    return Mode;
  }

  // If the address is the result of an add, we will utilize the fact that the
  // address calculation includes an implicit add.  However, we can reduce
  // register pressure if we do not materialize a constant just for use as the
  // index register.  We only get rid of the add if it is not an add of a
  // value and a 16-bit signed constant and both have a single use.
  if (N.getOpcode() == ISD::ADD &&
      (!isIntS16Immediate(N.getOperand(1), ForceXFormImm) ||
       !N.getOperand(1).hasOneUse() || !N.getOperand(0).hasOneUse())) {
    Disp = N.getOperand(0);
    Base = N.getOperand(1);
    return Mode;
  }

  // Otherwise, use R0 as the base register.
  Disp = DAG.getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
                         N.getValueType());
  Base = N;

  return Mode;
}

bool PPCTargetLowering::splitValueIntoRegisterParts(
    SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts,
    unsigned NumParts, MVT PartVT, std::optional<CallingConv::ID> CC) const {
  EVT ValVT = Val.getValueType();
  // If we are splitting a scalar integer into f64 parts (i.e. so they
  // can be placed into VFRC registers), we need to zero extend and
  // bitcast the values. This will ensure the value is placed into a
  // VSR using direct moves or stack operations as needed.
  if (PartVT == MVT::f64 &&
      (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
    Val = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, Val);
    Val = DAG.getNode(ISD::BITCAST, DL, MVT::f64, Val);
    Parts[0] = Val;
    return true;
  }
  return false;
}

SDValue PPCTargetLowering::lowerToLibCall(const char *LibCallName, SDValue Op,
                                          SelectionDAG &DAG) const {
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  TargetLowering::CallLoweringInfo CLI(DAG);
  EVT RetVT = Op.getValueType();
  Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext());
  SDValue Callee =
      DAG.getExternalSymbol(LibCallName, TLI.getPointerTy(DAG.getDataLayout()));
  bool SignExtend = TLI.shouldSignExtendTypeInLibCall(RetTy, false);
  TargetLowering::ArgListTy Args;
  for (const SDValue &N : Op->op_values()) {
    EVT ArgVT = N.getValueType();
    Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext());
    TargetLowering::ArgListEntry Entry(N, ArgTy);
    Entry.IsSExt = TLI.shouldSignExtendTypeInLibCall(ArgTy, SignExtend);
    Entry.IsZExt = !Entry.IsSExt;
    Args.push_back(Entry);
  }

  SDValue InChain = DAG.getEntryNode();
  SDValue TCChain = InChain;
  const Function &F = DAG.getMachineFunction().getFunction();
  bool isTailCall =
      TLI.isInTailCallPosition(DAG, Op.getNode(), TCChain) &&
      (RetTy == F.getReturnType() || F.getReturnType()->isVoidTy());
  if (isTailCall)
    InChain = TCChain;
  CLI.setDebugLoc(SDLoc(Op))
      .setChain(InChain)
      .setLibCallee(CallingConv::C, RetTy, Callee, std::move(Args))
      .setTailCall(isTailCall)
      .setSExtResult(SignExtend)
      .setZExtResult(!SignExtend)
      .setIsPostTypeLegalization(true);
  return TLI.LowerCallTo(CLI).first;
}

SDValue PPCTargetLowering::lowerLibCallBasedOnType(
    const char *LibCallFloatName, const char *LibCallDoubleName, SDValue Op,
    SelectionDAG &DAG) const {
  if (Op.getValueType() == MVT::f32)
    return lowerToLibCall(LibCallFloatName, Op, DAG);

  if (Op.getValueType() == MVT::f64)
    return lowerToLibCall(LibCallDoubleName, Op, DAG);

  return SDValue();
}

bool PPCTargetLowering::isLowringToMASSFiniteSafe(SDValue Op) const {
  SDNodeFlags Flags = Op.getNode()->getFlags();
  return isLowringToMASSSafe(Op) && Flags.hasNoSignedZeros() &&
         Flags.hasNoNaNs() && Flags.hasNoInfs();
}

bool PPCTargetLowering::isLowringToMASSSafe(SDValue Op) const {
  return Op.getNode()->getFlags().hasApproximateFuncs();
}

bool PPCTargetLowering::isScalarMASSConversionEnabled() const {
  return getTargetMachine().Options.PPCGenScalarMASSEntries;
}

SDValue PPCTargetLowering::lowerLibCallBase(const char *LibCallDoubleName,
                                            const char *LibCallFloatName,
                                            const char *LibCallDoubleNameFinite,
                                            const char *LibCallFloatNameFinite,
                                            SDValue Op,
                                            SelectionDAG &DAG) const {
  if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(Op))
    return SDValue();

  if (!isLowringToMASSFiniteSafe(Op))
    return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName, Op,
                                   DAG);

  return lowerLibCallBasedOnType(LibCallFloatNameFinite,
                                 LibCallDoubleNameFinite, Op, DAG);
}

SDValue PPCTargetLowering::lowerPow(SDValue Op, SelectionDAG &DAG) const {
  return lowerLibCallBase("__xl_pow", "__xl_powf", "__xl_pow_finite",
                          "__xl_powf_finite", Op, DAG);
}

SDValue PPCTargetLowering::lowerSin(SDValue Op, SelectionDAG &DAG) const {
  return lowerLibCallBase("__xl_sin", "__xl_sinf", "__xl_sin_finite",
                          "__xl_sinf_finite", Op, DAG);
}

SDValue PPCTargetLowering::lowerCos(SDValue Op, SelectionDAG &DAG) const {
  return lowerLibCallBase("__xl_cos", "__xl_cosf", "__xl_cos_finite",
                          "__xl_cosf_finite", Op, DAG);
}

SDValue PPCTargetLowering::lowerLog(SDValue Op, SelectionDAG &DAG) const {
  return lowerLibCallBase("__xl_log", "__xl_logf", "__xl_log_finite",
                          "__xl_logf_finite", Op, DAG);
}

SDValue PPCTargetLowering::lowerLog10(SDValue Op, SelectionDAG &DAG) const {
  return lowerLibCallBase("__xl_log10", "__xl_log10f", "__xl_log10_finite",
                          "__xl_log10f_finite", Op, DAG);
}

SDValue PPCTargetLowering::lowerExp(SDValue Op, SelectionDAG &DAG) const {
  return lowerLibCallBase("__xl_exp", "__xl_expf", "__xl_exp_finite",
                          "__xl_expf_finite", Op, DAG);
}

// If we happen to match to an aligned D-Form, check if the Frame Index is
// adequately aligned. If it is not, reset the mode to match to X-Form.
static void setXFormForUnalignedFI(SDValue N, unsigned Flags,
                                   PPC::AddrMode &Mode) {
  if (!isa<FrameIndexSDNode>(N))
    return;
  if ((Mode == PPC::AM_DSForm && !(Flags & PPC::MOF_RPlusSImm16Mult4)) ||
      (Mode == PPC::AM_DQForm && !(Flags & PPC::MOF_RPlusSImm16Mult16)))
    Mode = PPC::AM_XForm;
}

/// SelectOptimalAddrMode - Based on a node N and it's Parent (a MemSDNode),
/// compute the address flags of the node, get the optimal address mode based
/// on the flags, and set the Base and Disp based on the address mode.
PPC::AddrMode PPCTargetLowering::SelectOptimalAddrMode(const SDNode *Parent,
                                                       SDValue N, SDValue &Disp,
                                                       SDValue &Base,
                                                       SelectionDAG &DAG,
                                                       MaybeAlign Align) const {
  SDLoc DL(Parent);

  // Compute the address flags.
  unsigned Flags = computeMOFlags(Parent, N, DAG);

  // Get the optimal address mode based on the Flags.
  PPC::AddrMode Mode = getAddrModeForFlags(Flags);

  // If the address mode is DS-Form or DQ-Form, check if the FI is aligned.
  // Select an X-Form load if it is not.
  setXFormForUnalignedFI(N, Flags, Mode);

  // Set the mode to PC-Relative addressing mode if we have a valid PC-Rel node.
  if ((Mode == PPC::AM_XForm) && isPCRelNode(N)) {
    assert(Subtarget.isUsingPCRelativeCalls() &&
           "Must be using PC-Relative calls when a valid PC-Relative node is "
           "present!");
    Mode = PPC::AM_PCRel;
  }

  // Set Base and Disp accordingly depending on the address mode.
  switch (Mode) {
  case PPC::AM_DForm:
  case PPC::AM_DSForm:
  case PPC::AM_DQForm: {
    // This is a register plus a 16-bit immediate. The base will be the
    // register and the displacement will be the immediate unless it
    // isn't sufficiently aligned.
    if (Flags & PPC::MOF_RPlusSImm16) {
      SDValue Op0 = N.getOperand(0);
      SDValue Op1 = N.getOperand(1);
      int16_t Imm = Op1->getAsZExtVal();
      if (!Align || isAligned(*Align, Imm)) {
        Disp = DAG.getSignedTargetConstant(Imm, DL, N.getValueType());
        Base = Op0;
        if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op0)) {
          Base = DAG.getTargetFrameIndex(FI->getIndex(), N.getValueType());
          fixupFuncForFI(DAG, FI->getIndex(), N.getValueType());
        }
        break;
      }
    }
    // This is a register plus the @lo relocation. The base is the register
    // and the displacement is the global address.
    else if (Flags & PPC::MOF_RPlusLo) {
      Disp = N.getOperand(1).getOperand(0); // The global address.
      assert(Disp.getOpcode() == ISD::TargetGlobalAddress ||
             Disp.getOpcode() == ISD::TargetGlobalTLSAddress ||
             Disp.getOpcode() == ISD::TargetConstantPool ||
             Disp.getOpcode() == ISD::TargetJumpTable);
      Base = N.getOperand(0);
      break;
    }
    // This is a constant address at most 32 bits. The base will be
    // zero or load-immediate-shifted and the displacement will be
    // the low 16 bits of the address.
    else if (Flags & PPC::MOF_AddrIsSImm32) {
      auto *CN = cast<ConstantSDNode>(N);
      EVT CNType = CN->getValueType(0);
      uint64_t CNImm = CN->getZExtValue();
      // If this address fits entirely in a 16-bit sext immediate field, codegen
      // this as "d, 0".
      int16_t Imm;
      if (isIntS16Immediate(CN, Imm) && (!Align || isAligned(*Align, Imm))) {
        Disp = DAG.getSignedTargetConstant(Imm, DL, CNType);
        Base = DAG.getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
                               CNType);
        break;
      }
      // Handle 32-bit sext immediate with LIS + Addr mode.
      if ((CNType == MVT::i32 || isInt<32>(CNImm)) &&
          (!Align || isAligned(*Align, CNImm))) {
        int32_t Addr = (int32_t)CNImm;
        // Otherwise, break this down into LIS + Disp.
        Disp = DAG.getSignedTargetConstant((int16_t)Addr, DL, MVT::i32);
        Base = DAG.getSignedTargetConstant((Addr - (int16_t)Addr) >> 16, DL,
                                           MVT::i32);
        uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
        Base = SDValue(DAG.getMachineNode(LIS, DL, CNType, Base), 0);
        break;
      }
    }
    // Otherwise, the PPC:MOF_NotAdd flag is set. Load/Store is Non-foldable.
    Disp = DAG.getTargetConstant(0, DL, getPointerTy(DAG.getDataLayout()));
    if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N)) {
      Base = DAG.getTargetFrameIndex(FI->getIndex(), N.getValueType());
      fixupFuncForFI(DAG, FI->getIndex(), N.getValueType());
    } else
      Base = N;
    break;
  }
  case PPC::AM_PrefixDForm: {
    int64_t Imm34 = 0;
    unsigned Opcode = N.getOpcode();
    if (((Opcode == ISD::ADD) || (Opcode == ISD::OR)) &&
        (isIntS34Immediate(N.getOperand(1), Imm34))) {
      // N is an Add/OR Node, and it's operand is a 34-bit signed immediate.
      Disp = DAG.getSignedTargetConstant(Imm34, DL, N.getValueType());
      if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N.getOperand(0)))
        Base = DAG.getTargetFrameIndex(FI->getIndex(), N.getValueType());
      else
        Base = N.getOperand(0);
    } else if (isIntS34Immediate(N, Imm34)) {
      // The address is a 34-bit signed immediate.
      Disp = DAG.getSignedTargetConstant(Imm34, DL, N.getValueType());
      Base = DAG.getRegister(PPC::ZERO8, N.getValueType());
    }
    break;
  }
  case PPC::AM_PCRel: {
    // When selecting PC-Relative instructions, "Base" is not utilized as
    // we select the address as [PC+imm].
    Disp = N;
    break;
  }
  case PPC::AM_None:
    break;
  default: { // By default, X-Form is always available to be selected.
    // When a frame index is not aligned, we also match by XForm.
    FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N);
    Base = FI ? N : N.getOperand(1);
    Disp = FI ? DAG.getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
                                N.getValueType())
              : N.getOperand(0);
    break;
  }
  }
  return Mode;
}

CCAssignFn *PPCTargetLowering::ccAssignFnForCall(CallingConv::ID CC,
                                                 bool Return,
                                                 bool IsVarArg) const {
  switch (CC) {
  case CallingConv::Cold:
    return (Return ? RetCC_PPC_Cold : CC_PPC64_ELF);
  default:
    return CC_PPC64_ELF;
  }
}

bool PPCTargetLowering::shouldInlineQuadwordAtomics() const {
  return Subtarget.isPPC64() && Subtarget.hasQuadwordAtomics();
}

TargetLowering::AtomicExpansionKind
PPCTargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
  unsigned Size = AI->getType()->getPrimitiveSizeInBits();
  if (shouldInlineQuadwordAtomics() && Size == 128)
    return AtomicExpansionKind::MaskedIntrinsic;

  switch (AI->getOperation()) {
  case AtomicRMWInst::UIncWrap:
  case AtomicRMWInst::UDecWrap:
  case AtomicRMWInst::USubCond:
  case AtomicRMWInst::USubSat:
    return AtomicExpansionKind::CmpXChg;
  default:
    return TargetLowering::shouldExpandAtomicRMWInIR(AI);
  }

  llvm_unreachable("unreachable atomicrmw operation");
}

TargetLowering::AtomicExpansionKind
PPCTargetLowering::shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const {
  unsigned Size = AI->getNewValOperand()->getType()->getPrimitiveSizeInBits();
  if (shouldInlineQuadwordAtomics() && Size == 128)
    return AtomicExpansionKind::MaskedIntrinsic;
  return AtomicExpansionKind::LLSC;
}

static Intrinsic::ID
getIntrinsicForAtomicRMWBinOp128(AtomicRMWInst::BinOp BinOp) {
  switch (BinOp) {
  default:
    llvm_unreachable("Unexpected AtomicRMW BinOp");
  case AtomicRMWInst::Xchg:
    return Intrinsic::ppc_atomicrmw_xchg_i128;
  case AtomicRMWInst::Add:
    return Intrinsic::ppc_atomicrmw_add_i128;
  case AtomicRMWInst::Sub:
    return Intrinsic::ppc_atomicrmw_sub_i128;
  case AtomicRMWInst::And:
    return Intrinsic::ppc_atomicrmw_and_i128;
  case AtomicRMWInst::Or:
    return Intrinsic::ppc_atomicrmw_or_i128;
  case AtomicRMWInst::Xor:
    return Intrinsic::ppc_atomicrmw_xor_i128;
  case AtomicRMWInst::Nand:
    return Intrinsic::ppc_atomicrmw_nand_i128;
  }
}

Value *PPCTargetLowering::emitMaskedAtomicRMWIntrinsic(
    IRBuilderBase &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr,
    Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const {
  assert(shouldInlineQuadwordAtomics() && "Only support quadword now");
  Module *M = Builder.GetInsertBlock()->getParent()->getParent();
  Type *ValTy = Incr->getType();
  assert(ValTy->getPrimitiveSizeInBits() == 128);
  Type *Int64Ty = Type::getInt64Ty(M->getContext());
  Value *IncrLo = Builder.CreateTrunc(Incr, Int64Ty, "incr_lo");
  Value *IncrHi =
      Builder.CreateTrunc(Builder.CreateLShr(Incr, 64), Int64Ty, "incr_hi");
  Value *LoHi = Builder.CreateIntrinsic(
      getIntrinsicForAtomicRMWBinOp128(AI->getOperation()), {},
      {AlignedAddr, IncrLo, IncrHi});
  Value *Lo = Builder.CreateExtractValue(LoHi, 0, "lo");
  Value *Hi = Builder.CreateExtractValue(LoHi, 1, "hi");
  Lo = Builder.CreateZExt(Lo, ValTy, "lo64");
  Hi = Builder.CreateZExt(Hi, ValTy, "hi64");
  return Builder.CreateOr(
      Lo, Builder.CreateShl(Hi, ConstantInt::get(ValTy, 64)), "val64");
}

Value *PPCTargetLowering::emitMaskedAtomicCmpXchgIntrinsic(
    IRBuilderBase &Builder, AtomicCmpXchgInst *CI, Value *AlignedAddr,
    Value *CmpVal, Value *NewVal, Value *Mask, AtomicOrdering Ord) const {
  assert(shouldInlineQuadwordAtomics() && "Only support quadword now");
  Module *M = Builder.GetInsertBlock()->getParent()->getParent();
  Type *ValTy = CmpVal->getType();
  assert(ValTy->getPrimitiveSizeInBits() == 128);
  Function *IntCmpXchg =
      Intrinsic::getOrInsertDeclaration(M, Intrinsic::ppc_cmpxchg_i128);
  Type *Int64Ty = Type::getInt64Ty(M->getContext());
  Value *CmpLo = Builder.CreateTrunc(CmpVal, Int64Ty, "cmp_lo");
  Value *CmpHi =
      Builder.CreateTrunc(Builder.CreateLShr(CmpVal, 64), Int64Ty, "cmp_hi");
  Value *NewLo = Builder.CreateTrunc(NewVal, Int64Ty, "new_lo");
  Value *NewHi =
      Builder.CreateTrunc(Builder.CreateLShr(NewVal, 64), Int64Ty, "new_hi");
  emitLeadingFence(Builder, CI, Ord);
  Value *LoHi =
      Builder.CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
  emitTrailingFence(Builder, CI, Ord);
  Value *Lo = Builder.CreateExtractValue(LoHi, 0, "lo");
  Value *Hi = Builder.CreateExtractValue(LoHi, 1, "hi");
  Lo = Builder.CreateZExt(Lo, ValTy, "lo64");
  Hi = Builder.CreateZExt(Hi, ValTy, "hi64");
  return Builder.CreateOr(
      Lo, Builder.CreateShl(Hi, ConstantInt::get(ValTy, 64)), "val64");
}

bool PPCTargetLowering::hasMultipleConditionRegisters(EVT VT) const {
  return Subtarget.useCRBits();
}
