//===-- X86ISelLowering.cpp - X86 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 defines the interfaces that X86 uses to lower LLVM code into a
// selection DAG.
//
//===----------------------------------------------------------------------===//

#include "X86ISelLowering.h"
#include "Utils/X86ShuffleDecode.h"
#include "X86CallingConv.h"
#include "X86FrameLowering.h"
#include "X86InstrBuilder.h"
#include "X86IntrinsicsInfo.h"
#include "X86MachineFunctionInfo.h"
#include "X86TargetMachine.h"
#include "X86TargetObjectFile.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/CodeGen/IntrinsicLowering.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/WinEHFuncInfo.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetOptions.h"
#include <algorithm>
#include <bitset>
#include <cctype>
#include <numeric>
using namespace llvm;

#define DEBUG_TYPE "x86-isel"

STATISTIC(NumTailCalls, "Number of tail calls");

static cl::opt<int> ExperimentalPrefLoopAlignment(
    "x86-experimental-pref-loop-alignment", cl::init(4),
    cl::desc(
        "Sets the preferable loop alignment for experiments (as log2 bytes)"
        "(the last x86-experimental-pref-loop-alignment bits"
        " of the loop header PC will be 0)."),
    cl::Hidden);

// Added in 10.0.
static cl::opt<bool> EnableOldKNLABI(
    "x86-enable-old-knl-abi", cl::init(false),
    cl::desc("Enables passing v32i16 and v64i8 in 2 YMM registers instead of "
             "one ZMM register on AVX512F, but not AVX512BW targets."),
    cl::Hidden);

static cl::opt<bool> MulConstantOptimization(
    "mul-constant-optimization", cl::init(true),
    cl::desc("Replace 'mul x, Const' with more effective instructions like "
             "SHIFT, LEA, etc."),
    cl::Hidden);

static cl::opt<bool> ExperimentalUnorderedISEL(
    "x86-experimental-unordered-atomic-isel", cl::init(false),
    cl::desc("Use LoadSDNode and StoreSDNode instead of "
             "AtomicSDNode for unordered atomic loads and "
             "stores respectively."),
    cl::Hidden);

/// Call this when the user attempts to do something unsupported, like
/// returning a double without SSE2 enabled on x86_64. This is not fatal, unlike
/// report_fatal_error, so calling code should attempt to recover without
/// crashing.
static void errorUnsupported(SelectionDAG &DAG, const SDLoc &dl,
                             const char *Msg) {
  MachineFunction &MF = DAG.getMachineFunction();
  DAG.getContext()->diagnose(
      DiagnosticInfoUnsupported(MF.getFunction(), Msg, dl.getDebugLoc()));
}

X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
                                     const X86Subtarget &STI)
    : TargetLowering(TM), Subtarget(STI) {
  bool UseX87 = !Subtarget.useSoftFloat() && Subtarget.hasX87();
  X86ScalarSSEf64 = Subtarget.hasSSE2();
  X86ScalarSSEf32 = Subtarget.hasSSE1();
  MVT PtrVT = MVT::getIntegerVT(TM.getPointerSizeInBits(0));

  // Set up the TargetLowering object.

  // X86 is weird. It always uses i8 for shift amounts and setcc results.
  setBooleanContents(ZeroOrOneBooleanContent);
  // X86-SSE is even stranger. It uses -1 or 0 for vector masks.
  setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);

  // For 64-bit, since we have so many registers, use the ILP scheduler.
  // For 32-bit, use the register pressure specific scheduling.
  // For Atom, always use ILP scheduling.
  if (Subtarget.isAtom())
    setSchedulingPreference(Sched::ILP);
  else if (Subtarget.is64Bit())
    setSchedulingPreference(Sched::ILP);
  else
    setSchedulingPreference(Sched::RegPressure);
  const X86RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
  setStackPointerRegisterToSaveRestore(RegInfo->getStackRegister());

  // Bypass expensive divides and use cheaper ones.
  if (TM.getOptLevel() >= CodeGenOpt::Default) {
    if (Subtarget.hasSlowDivide32())
      addBypassSlowDiv(32, 8);
    if (Subtarget.hasSlowDivide64() && Subtarget.is64Bit())
      addBypassSlowDiv(64, 32);
  }

  if (Subtarget.isTargetWindowsMSVC() ||
      Subtarget.isTargetWindowsItanium()) {
    // Setup Windows compiler runtime calls.
    setLibcallName(RTLIB::SDIV_I64, "_alldiv");
    setLibcallName(RTLIB::UDIV_I64, "_aulldiv");
    setLibcallName(RTLIB::SREM_I64, "_allrem");
    setLibcallName(RTLIB::UREM_I64, "_aullrem");
    setLibcallName(RTLIB::MUL_I64, "_allmul");
    setLibcallCallingConv(RTLIB::SDIV_I64, CallingConv::X86_StdCall);
    setLibcallCallingConv(RTLIB::UDIV_I64, CallingConv::X86_StdCall);
    setLibcallCallingConv(RTLIB::SREM_I64, CallingConv::X86_StdCall);
    setLibcallCallingConv(RTLIB::UREM_I64, CallingConv::X86_StdCall);
    setLibcallCallingConv(RTLIB::MUL_I64, CallingConv::X86_StdCall);
  }

  if (Subtarget.getTargetTriple().isOSMSVCRT()) {
    // MSVCRT doesn't have powi; fall back to pow
    setLibcallName(RTLIB::POWI_F32, nullptr);
    setLibcallName(RTLIB::POWI_F64, nullptr);
  }

  // If we don't have cmpxchg8b(meaing this is a 386/486), limit atomic size to
  // 32 bits so the AtomicExpandPass will expand it so we don't need cmpxchg8b.
  // FIXME: Should we be limiting the atomic size on other configs? Default is
  // 1024.
  if (!Subtarget.hasCmpxchg8b())
    setMaxAtomicSizeInBitsSupported(32);

  // Set up the register classes.
  addRegisterClass(MVT::i8, &X86::GR8RegClass);
  addRegisterClass(MVT::i16, &X86::GR16RegClass);
  addRegisterClass(MVT::i32, &X86::GR32RegClass);
  if (Subtarget.is64Bit())
    addRegisterClass(MVT::i64, &X86::GR64RegClass);

  for (MVT VT : MVT::integer_valuetypes())
    setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote);

  // We don't accept any truncstore of integer registers.
  setTruncStoreAction(MVT::i64, MVT::i32, Expand);
  setTruncStoreAction(MVT::i64, MVT::i16, Expand);
  setTruncStoreAction(MVT::i64, MVT::i8 , Expand);
  setTruncStoreAction(MVT::i32, MVT::i16, Expand);
  setTruncStoreAction(MVT::i32, MVT::i8 , Expand);
  setTruncStoreAction(MVT::i16, MVT::i8,  Expand);

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

  // SETOEQ and SETUNE require checking two conditions.
  setCondCodeAction(ISD::SETOEQ, MVT::f32, Expand);
  setCondCodeAction(ISD::SETOEQ, MVT::f64, Expand);
  setCondCodeAction(ISD::SETOEQ, MVT::f80, Expand);
  setCondCodeAction(ISD::SETUNE, MVT::f32, Expand);
  setCondCodeAction(ISD::SETUNE, MVT::f64, Expand);
  setCondCodeAction(ISD::SETUNE, MVT::f80, Expand);

  // Integer absolute.
  if (Subtarget.hasCMov()) {
    setOperationAction(ISD::ABS            , MVT::i16  , Custom);
    setOperationAction(ISD::ABS            , MVT::i32  , Custom);
  }
  setOperationAction(ISD::ABS              , MVT::i64  , Custom);

  // Funnel shifts.
  for (auto ShiftOp : {ISD::FSHL, ISD::FSHR}) {
    // For slow shld targets we only lower for code size.
    LegalizeAction ShiftDoubleAction = Subtarget.isSHLDSlow() ? Custom : Legal;

    setOperationAction(ShiftOp             , MVT::i16  , Custom);
    setOperationAction(ShiftOp             , MVT::i32  , ShiftDoubleAction);
    if (Subtarget.is64Bit())
      setOperationAction(ShiftOp           , MVT::i64  , ShiftDoubleAction);
  }

  if (!Subtarget.useSoftFloat()) {
    // Promote all UINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have this
    // operation.
    setOperationAction(ISD::UINT_TO_FP,        MVT::i8, Promote);
    setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i8, Promote);
    setOperationAction(ISD::UINT_TO_FP,        MVT::i16, Promote);
    setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i16, Promote);
    // We have an algorithm for SSE2, and we turn this into a 64-bit
    // FILD or VCVTUSI2SS/SD for other targets.
    setOperationAction(ISD::UINT_TO_FP,        MVT::i32, Custom);
    setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i32, Custom);
    // We have an algorithm for SSE2->double, and we turn this into a
    // 64-bit FILD followed by conditional FADD for other targets.
    setOperationAction(ISD::UINT_TO_FP,        MVT::i64, Custom);
    setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i64, Custom);

    // Promote i8 SINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have
    // this operation.
    setOperationAction(ISD::SINT_TO_FP,        MVT::i8, Promote);
    setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i8, Promote);
    // SSE has no i16 to fp conversion, only i32. We promote in the handler
    // to allow f80 to use i16 and f64 to use i16 with sse1 only
    setOperationAction(ISD::SINT_TO_FP,        MVT::i16, Custom);
    setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i16, Custom);
    // f32 and f64 cases are Legal with SSE1/SSE2, f80 case is not
    setOperationAction(ISD::SINT_TO_FP,        MVT::i32, Custom);
    setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i32, Custom);
    // In 32-bit mode these are custom lowered.  In 64-bit mode F32 and F64
    // are Legal, f80 is custom lowered.
    setOperationAction(ISD::SINT_TO_FP,        MVT::i64, Custom);
    setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i64, Custom);

    // Promote i8 FP_TO_SINT to larger FP_TO_SINTS's, as X86 doesn't have
    // this operation.
    setOperationAction(ISD::FP_TO_SINT,        MVT::i8,  Promote);
    // FIXME: This doesn't generate invalid exception when it should. PR44019.
    setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i8,  Promote);
    setOperationAction(ISD::FP_TO_SINT,        MVT::i16, Custom);
    setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i16, Custom);
    setOperationAction(ISD::FP_TO_SINT,        MVT::i32, Custom);
    setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i32, Custom);
    // In 32-bit mode these are custom lowered.  In 64-bit mode F32 and F64
    // are Legal, f80 is custom lowered.
    setOperationAction(ISD::FP_TO_SINT,        MVT::i64, Custom);
    setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i64, Custom);

    // Handle FP_TO_UINT by promoting the destination to a larger signed
    // conversion.
    setOperationAction(ISD::FP_TO_UINT,        MVT::i8,  Promote);
    // FIXME: This doesn't generate invalid exception when it should. PR44019.
    setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i8,  Promote);
    setOperationAction(ISD::FP_TO_UINT,        MVT::i16, Promote);
    // FIXME: This doesn't generate invalid exception when it should. PR44019.
    setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i16, Promote);
    setOperationAction(ISD::FP_TO_UINT,        MVT::i32, Custom);
    setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Custom);
    setOperationAction(ISD::FP_TO_UINT,        MVT::i64, Custom);
    setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i64, Custom);

    setOperationAction(ISD::LRINT,             MVT::f32, Custom);
    setOperationAction(ISD::LRINT,             MVT::f64, Custom);
    setOperationAction(ISD::LLRINT,            MVT::f32, Custom);
    setOperationAction(ISD::LLRINT,            MVT::f64, Custom);

    if (!Subtarget.is64Bit()) {
      setOperationAction(ISD::LRINT,  MVT::i64, Custom);
      setOperationAction(ISD::LLRINT, MVT::i64, Custom);
    }
  }

  // Handle address space casts between mixed sized pointers.
  setOperationAction(ISD::ADDRSPACECAST, MVT::i32, Custom);
  setOperationAction(ISD::ADDRSPACECAST, MVT::i64, Custom);

  // TODO: when we have SSE, these could be more efficient, by using movd/movq.
  if (!X86ScalarSSEf64) {
    setOperationAction(ISD::BITCAST        , MVT::f32  , Expand);
    setOperationAction(ISD::BITCAST        , MVT::i32  , Expand);
    if (Subtarget.is64Bit()) {
      setOperationAction(ISD::BITCAST      , MVT::f64  , Expand);
      // Without SSE, i64->f64 goes through memory.
      setOperationAction(ISD::BITCAST      , MVT::i64  , Expand);
    }
  } else if (!Subtarget.is64Bit())
    setOperationAction(ISD::BITCAST      , MVT::i64  , Custom);

  // Scalar integer divide and remainder are lowered to use operations that
  // produce two results, to match the available instructions. This exposes
  // the two-result form to trivial CSE, which is able to combine x/y and x%y
  // into a single instruction.
  //
  // Scalar integer multiply-high is also lowered to use two-result
  // operations, to match the available instructions. However, plain multiply
  // (low) operations are left as Legal, as there are single-result
  // instructions for this in x86. Using the two-result multiply instructions
  // when both high and low results are needed must be arranged by dagcombine.
  for (auto VT : { MVT::i8, MVT::i16, MVT::i32, MVT::i64 }) {
    setOperationAction(ISD::MULHS, VT, Expand);
    setOperationAction(ISD::MULHU, VT, Expand);
    setOperationAction(ISD::SDIV, VT, Expand);
    setOperationAction(ISD::UDIV, VT, Expand);
    setOperationAction(ISD::SREM, VT, Expand);
    setOperationAction(ISD::UREM, VT, Expand);
  }

  setOperationAction(ISD::BR_JT            , MVT::Other, Expand);
  setOperationAction(ISD::BRCOND           , MVT::Other, Custom);
  for (auto VT : { MVT::f32, MVT::f64, MVT::f80, MVT::f128,
                   MVT::i8,  MVT::i16, MVT::i32, MVT::i64 }) {
    setOperationAction(ISD::BR_CC,     VT, Expand);
    setOperationAction(ISD::SELECT_CC, VT, Expand);
  }
  if (Subtarget.is64Bit())
    setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i32, Legal);
  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16  , Legal);
  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8   , Legal);
  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1   , Expand);

  setOperationAction(ISD::FREM             , MVT::f32  , Expand);
  setOperationAction(ISD::FREM             , MVT::f64  , Expand);
  setOperationAction(ISD::FREM             , MVT::f80  , Expand);
  setOperationAction(ISD::FREM             , MVT::f128 , Expand);
  setOperationAction(ISD::FLT_ROUNDS_      , MVT::i32  , Custom);

  // Promote the i8 variants and force them on up to i32 which has a shorter
  // encoding.
  setOperationPromotedToType(ISD::CTTZ           , MVT::i8   , MVT::i32);
  setOperationPromotedToType(ISD::CTTZ_ZERO_UNDEF, MVT::i8   , MVT::i32);
  if (!Subtarget.hasBMI()) {
    setOperationAction(ISD::CTTZ           , MVT::i16  , Custom);
    setOperationAction(ISD::CTTZ           , MVT::i32  , Custom);
    setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i16  , Legal);
    setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32  , Legal);
    if (Subtarget.is64Bit()) {
      setOperationAction(ISD::CTTZ         , MVT::i64  , Custom);
      setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i64, Legal);
    }
  }

  if (Subtarget.hasLZCNT()) {
    // When promoting the i8 variants, force them to i32 for a shorter
    // encoding.
    setOperationPromotedToType(ISD::CTLZ           , MVT::i8   , MVT::i32);
    setOperationPromotedToType(ISD::CTLZ_ZERO_UNDEF, MVT::i8   , MVT::i32);
  } else {
    setOperationAction(ISD::CTLZ           , MVT::i8   , Custom);
    setOperationAction(ISD::CTLZ           , MVT::i16  , Custom);
    setOperationAction(ISD::CTLZ           , MVT::i32  , Custom);
    setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i8   , Custom);
    setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i16  , Custom);
    setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32  , Custom);
    if (Subtarget.is64Bit()) {
      setOperationAction(ISD::CTLZ         , MVT::i64  , Custom);
      setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i64, Custom);
    }
  }

  // Special handling for half-precision floating point conversions.
  // If we don't have F16C support, then lower half float conversions
  // into library calls.
  if (!Subtarget.useSoftFloat() && Subtarget.hasF16C()) {
    setOperationAction(ISD::FP16_TO_FP,        MVT::f32, Custom);
    setOperationAction(ISD::STRICT_FP16_TO_FP, MVT::f32, Custom);
    setOperationAction(ISD::FP_TO_FP16,        MVT::f32, Custom);
    setOperationAction(ISD::STRICT_FP_TO_FP16, MVT::f32, Custom);
  } else {
    setOperationAction(ISD::FP16_TO_FP,        MVT::f32, Expand);
    setOperationAction(ISD::STRICT_FP16_TO_FP, MVT::f32, Expand);
    setOperationAction(ISD::FP_TO_FP16,        MVT::f32, Expand);
    setOperationAction(ISD::STRICT_FP_TO_FP16, MVT::f32, Expand);
  }

  // There's never any support for operations beyond MVT::f32.
  setOperationAction(ISD::FP16_TO_FP, MVT::f64, Expand);
  setOperationAction(ISD::FP16_TO_FP, MVT::f80, Expand);
  setOperationAction(ISD::FP16_TO_FP, MVT::f128, Expand);
  setOperationAction(ISD::STRICT_FP16_TO_FP, MVT::f64, Expand);
  setOperationAction(ISD::STRICT_FP16_TO_FP, MVT::f80, Expand);
  setOperationAction(ISD::STRICT_FP16_TO_FP, MVT::f128, Expand);
  setOperationAction(ISD::FP_TO_FP16, MVT::f64, Expand);
  setOperationAction(ISD::FP_TO_FP16, MVT::f80, Expand);
  setOperationAction(ISD::FP_TO_FP16, MVT::f128, Expand);
  setOperationAction(ISD::STRICT_FP_TO_FP16, MVT::f64, Expand);
  setOperationAction(ISD::STRICT_FP_TO_FP16, MVT::f80, Expand);
  setOperationAction(ISD::STRICT_FP_TO_FP16, MVT::f128, Expand);

  setLoadExtAction(ISD::EXTLOAD, MVT::f32, MVT::f16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::f80, MVT::f16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::f128, MVT::f16, Expand);
  setTruncStoreAction(MVT::f32, MVT::f16, Expand);
  setTruncStoreAction(MVT::f64, MVT::f16, Expand);
  setTruncStoreAction(MVT::f80, MVT::f16, Expand);
  setTruncStoreAction(MVT::f128, MVT::f16, Expand);

  if (Subtarget.hasPOPCNT()) {
    setOperationPromotedToType(ISD::CTPOP, MVT::i8, MVT::i32);
  } else {
    setOperationAction(ISD::CTPOP          , MVT::i8   , Expand);
    setOperationAction(ISD::CTPOP          , MVT::i16  , Expand);
    setOperationAction(ISD::CTPOP          , MVT::i32  , Expand);
    if (Subtarget.is64Bit())
      setOperationAction(ISD::CTPOP        , MVT::i64  , Expand);
    else
      setOperationAction(ISD::CTPOP        , MVT::i64  , Custom);
  }

  setOperationAction(ISD::READCYCLECOUNTER , MVT::i64  , Custom);

  if (!Subtarget.hasMOVBE())
    setOperationAction(ISD::BSWAP          , MVT::i16  , Expand);

  // X86 wants to expand cmov itself.
  for (auto VT : { MVT::f32, MVT::f64, MVT::f80, MVT::f128 }) {
    setOperationAction(ISD::SELECT, VT, Custom);
    setOperationAction(ISD::SETCC, VT, Custom);
    setOperationAction(ISD::STRICT_FSETCC, VT, Custom);
    setOperationAction(ISD::STRICT_FSETCCS, VT, Custom);
  }
  for (auto VT : { MVT::i8, MVT::i16, MVT::i32, MVT::i64 }) {
    if (VT == MVT::i64 && !Subtarget.is64Bit())
      continue;
    setOperationAction(ISD::SELECT, VT, Custom);
    setOperationAction(ISD::SETCC,  VT, Custom);
  }

  // Custom action for SELECT MMX and expand action for SELECT_CC MMX
  setOperationAction(ISD::SELECT, MVT::x86mmx, Custom);
  setOperationAction(ISD::SELECT_CC, MVT::x86mmx, Expand);

  setOperationAction(ISD::EH_RETURN       , MVT::Other, Custom);
  // NOTE: EH_SJLJ_SETJMP/_LONGJMP are not recommended, since
  // LLVM/Clang supports zero-cost DWARF and SEH exception handling.
  setOperationAction(ISD::EH_SJLJ_SETJMP, MVT::i32, Custom);
  setOperationAction(ISD::EH_SJLJ_LONGJMP, MVT::Other, Custom);
  setOperationAction(ISD::EH_SJLJ_SETUP_DISPATCH, MVT::Other, Custom);
  if (TM.Options.ExceptionModel == ExceptionHandling::SjLj)
    setLibcallName(RTLIB::UNWIND_RESUME, "_Unwind_SjLj_Resume");

  // Darwin ABI issue.
  for (auto VT : { MVT::i32, MVT::i64 }) {
    if (VT == MVT::i64 && !Subtarget.is64Bit())
      continue;
    setOperationAction(ISD::ConstantPool    , VT, Custom);
    setOperationAction(ISD::JumpTable       , VT, Custom);
    setOperationAction(ISD::GlobalAddress   , VT, Custom);
    setOperationAction(ISD::GlobalTLSAddress, VT, Custom);
    setOperationAction(ISD::ExternalSymbol  , VT, Custom);
    setOperationAction(ISD::BlockAddress    , VT, Custom);
  }

  // 64-bit shl, sra, srl (iff 32-bit x86)
  for (auto VT : { MVT::i32, MVT::i64 }) {
    if (VT == MVT::i64 && !Subtarget.is64Bit())
      continue;
    setOperationAction(ISD::SHL_PARTS, VT, Custom);
    setOperationAction(ISD::SRA_PARTS, VT, Custom);
    setOperationAction(ISD::SRL_PARTS, VT, Custom);
  }

  if (Subtarget.hasSSEPrefetch() || Subtarget.has3DNow())
    setOperationAction(ISD::PREFETCH      , MVT::Other, Legal);

  setOperationAction(ISD::ATOMIC_FENCE  , MVT::Other, Custom);

  // Expand certain atomics
  for (auto VT : { MVT::i8, MVT::i16, MVT::i32, MVT::i64 }) {
    setOperationAction(ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS, VT, Custom);
    setOperationAction(ISD::ATOMIC_LOAD_SUB, VT, Custom);
    setOperationAction(ISD::ATOMIC_LOAD_ADD, VT, Custom);
    setOperationAction(ISD::ATOMIC_LOAD_OR, VT, Custom);
    setOperationAction(ISD::ATOMIC_LOAD_XOR, VT, Custom);
    setOperationAction(ISD::ATOMIC_LOAD_AND, VT, Custom);
    setOperationAction(ISD::ATOMIC_STORE, VT, Custom);
  }

  if (!Subtarget.is64Bit())
    setOperationAction(ISD::ATOMIC_LOAD, MVT::i64, Custom);

  if (Subtarget.hasCmpxchg16b()) {
    setOperationAction(ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS, MVT::i128, Custom);
  }

  // FIXME - use subtarget debug flags
  if (!Subtarget.isTargetDarwin() && !Subtarget.isTargetELF() &&
      !Subtarget.isTargetCygMing() && !Subtarget.isTargetWin64() &&
      TM.Options.ExceptionModel != ExceptionHandling::SjLj) {
    setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
  }

  setOperationAction(ISD::FRAME_TO_ARGS_OFFSET, MVT::i32, Custom);
  setOperationAction(ISD::FRAME_TO_ARGS_OFFSET, MVT::i64, Custom);

  setOperationAction(ISD::INIT_TRAMPOLINE, MVT::Other, Custom);
  setOperationAction(ISD::ADJUST_TRAMPOLINE, MVT::Other, Custom);

  setOperationAction(ISD::TRAP, MVT::Other, Legal);
  setOperationAction(ISD::DEBUGTRAP, MVT::Other, Legal);

  // VASTART needs to be custom lowered to use the VarArgsFrameIndex
  setOperationAction(ISD::VASTART           , MVT::Other, Custom);
  setOperationAction(ISD::VAEND             , MVT::Other, Expand);
  bool Is64Bit = Subtarget.is64Bit();
  setOperationAction(ISD::VAARG,  MVT::Other, Is64Bit ? Custom : Expand);
  setOperationAction(ISD::VACOPY, MVT::Other, Is64Bit ? Custom : Expand);

  setOperationAction(ISD::STACKSAVE,          MVT::Other, Expand);
  setOperationAction(ISD::STACKRESTORE,       MVT::Other, Expand);

  setOperationAction(ISD::DYNAMIC_STACKALLOC, PtrVT, Custom);

  // GC_TRANSITION_START and GC_TRANSITION_END need custom lowering.
  setOperationAction(ISD::GC_TRANSITION_START, MVT::Other, Custom);
  setOperationAction(ISD::GC_TRANSITION_END, MVT::Other, Custom);

  if (!Subtarget.useSoftFloat() && X86ScalarSSEf64) {
    // f32 and f64 use SSE.
    // Set up the FP register classes.
    addRegisterClass(MVT::f32, Subtarget.hasAVX512() ? &X86::FR32XRegClass
                                                     : &X86::FR32RegClass);
    addRegisterClass(MVT::f64, Subtarget.hasAVX512() ? &X86::FR64XRegClass
                                                     : &X86::FR64RegClass);

    // Disable f32->f64 extload as we can only generate this in one instruction
    // under optsize. So its easier to pattern match (fpext (load)) for that
    // case instead of needing to emit 2 instructions for extload in the
    // non-optsize case.
    setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f32, Expand);

    for (auto VT : { MVT::f32, MVT::f64 }) {
      // Use ANDPD to simulate FABS.
      setOperationAction(ISD::FABS, VT, Custom);

      // Use XORP to simulate FNEG.
      setOperationAction(ISD::FNEG, VT, Custom);

      // Use ANDPD and ORPD to simulate FCOPYSIGN.
      setOperationAction(ISD::FCOPYSIGN, VT, Custom);

      // These might be better off as horizontal vector ops.
      setOperationAction(ISD::FADD, VT, Custom);
      setOperationAction(ISD::FSUB, VT, Custom);

      // We don't support sin/cos/fmod
      setOperationAction(ISD::FSIN   , VT, Expand);
      setOperationAction(ISD::FCOS   , VT, Expand);
      setOperationAction(ISD::FSINCOS, VT, Expand);
    }

    // Lower this to MOVMSK plus an AND.
    setOperationAction(ISD::FGETSIGN, MVT::i64, Custom);
    setOperationAction(ISD::FGETSIGN, MVT::i32, Custom);

  } else if (!Subtarget.useSoftFloat() && X86ScalarSSEf32 &&
             (UseX87 || Is64Bit)) {
    // Use SSE for f32, x87 for f64.
    // Set up the FP register classes.
    addRegisterClass(MVT::f32, &X86::FR32RegClass);
    if (UseX87)
      addRegisterClass(MVT::f64, &X86::RFP64RegClass);

    // Use ANDPS to simulate FABS.
    setOperationAction(ISD::FABS , MVT::f32, Custom);

    // Use XORP to simulate FNEG.
    setOperationAction(ISD::FNEG , MVT::f32, Custom);

    if (UseX87)
      setOperationAction(ISD::UNDEF, MVT::f64, Expand);

    // Use ANDPS and ORPS to simulate FCOPYSIGN.
    if (UseX87)
      setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
    setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom);

    // We don't support sin/cos/fmod
    setOperationAction(ISD::FSIN   , MVT::f32, Expand);
    setOperationAction(ISD::FCOS   , MVT::f32, Expand);
    setOperationAction(ISD::FSINCOS, MVT::f32, Expand);

    if (UseX87) {
      // Always expand sin/cos functions even though x87 has an instruction.
      setOperationAction(ISD::FSIN, MVT::f64, Expand);
      setOperationAction(ISD::FCOS, MVT::f64, Expand);
      setOperationAction(ISD::FSINCOS, MVT::f64, Expand);
    }
  } else if (UseX87) {
    // f32 and f64 in x87.
    // Set up the FP register classes.
    addRegisterClass(MVT::f64, &X86::RFP64RegClass);
    addRegisterClass(MVT::f32, &X86::RFP32RegClass);

    for (auto VT : { MVT::f32, MVT::f64 }) {
      setOperationAction(ISD::UNDEF,     VT, Expand);
      setOperationAction(ISD::FCOPYSIGN, VT, Expand);

      // Always expand sin/cos functions even though x87 has an instruction.
      setOperationAction(ISD::FSIN   , VT, Expand);
      setOperationAction(ISD::FCOS   , VT, Expand);
      setOperationAction(ISD::FSINCOS, VT, Expand);
    }
  }

  // Expand FP32 immediates into loads from the stack, save special cases.
  if (isTypeLegal(MVT::f32)) {
    if (UseX87 && (getRegClassFor(MVT::f32) == &X86::RFP32RegClass)) {
      addLegalFPImmediate(APFloat(+0.0f)); // FLD0
      addLegalFPImmediate(APFloat(+1.0f)); // FLD1
      addLegalFPImmediate(APFloat(-0.0f)); // FLD0/FCHS
      addLegalFPImmediate(APFloat(-1.0f)); // FLD1/FCHS
    } else // SSE immediates.
      addLegalFPImmediate(APFloat(+0.0f)); // xorps
  }
  // Expand FP64 immediates into loads from the stack, save special cases.
  if (isTypeLegal(MVT::f64)) {
    if (UseX87 && getRegClassFor(MVT::f64) == &X86::RFP64RegClass) {
      addLegalFPImmediate(APFloat(+0.0)); // FLD0
      addLegalFPImmediate(APFloat(+1.0)); // FLD1
      addLegalFPImmediate(APFloat(-0.0)); // FLD0/FCHS
      addLegalFPImmediate(APFloat(-1.0)); // FLD1/FCHS
    } else // SSE immediates.
      addLegalFPImmediate(APFloat(+0.0)); // xorpd
  }
  // Handle constrained floating-point operations of scalar.
  setOperationAction(ISD::STRICT_FADD,      MVT::f32, Legal);
  setOperationAction(ISD::STRICT_FADD,      MVT::f64, Legal);
  setOperationAction(ISD::STRICT_FSUB,      MVT::f32, Legal);
  setOperationAction(ISD::STRICT_FSUB,      MVT::f64, Legal);
  setOperationAction(ISD::STRICT_FMUL,      MVT::f32, Legal);
  setOperationAction(ISD::STRICT_FMUL,      MVT::f64, Legal);
  setOperationAction(ISD::STRICT_FDIV,      MVT::f32, Legal);
  setOperationAction(ISD::STRICT_FDIV,      MVT::f64, Legal);
  setOperationAction(ISD::STRICT_FP_EXTEND, MVT::f64, Legal);
  setOperationAction(ISD::STRICT_FP_ROUND,  MVT::f32, Legal);
  setOperationAction(ISD::STRICT_FP_ROUND,  MVT::f64, Legal);
  setOperationAction(ISD::STRICT_FSQRT,     MVT::f32, Legal);
  setOperationAction(ISD::STRICT_FSQRT,     MVT::f64, Legal);

  // We don't support FMA.
  setOperationAction(ISD::FMA, MVT::f64, Expand);
  setOperationAction(ISD::FMA, MVT::f32, Expand);

  // f80 always uses X87.
  if (UseX87) {
    addRegisterClass(MVT::f80, &X86::RFP80RegClass);
    setOperationAction(ISD::UNDEF,     MVT::f80, Expand);
    setOperationAction(ISD::FCOPYSIGN, MVT::f80, Expand);
    {
      APFloat TmpFlt = APFloat::getZero(APFloat::x87DoubleExtended());
      addLegalFPImmediate(TmpFlt);  // FLD0
      TmpFlt.changeSign();
      addLegalFPImmediate(TmpFlt);  // FLD0/FCHS

      bool ignored;
      APFloat TmpFlt2(+1.0);
      TmpFlt2.convert(APFloat::x87DoubleExtended(), APFloat::rmNearestTiesToEven,
                      &ignored);
      addLegalFPImmediate(TmpFlt2);  // FLD1
      TmpFlt2.changeSign();
      addLegalFPImmediate(TmpFlt2);  // FLD1/FCHS
    }

    // Always expand sin/cos functions even though x87 has an instruction.
    setOperationAction(ISD::FSIN   , MVT::f80, Expand);
    setOperationAction(ISD::FCOS   , MVT::f80, Expand);
    setOperationAction(ISD::FSINCOS, MVT::f80, Expand);

    setOperationAction(ISD::FFLOOR, MVT::f80, Expand);
    setOperationAction(ISD::FCEIL,  MVT::f80, Expand);
    setOperationAction(ISD::FTRUNC, MVT::f80, Expand);
    setOperationAction(ISD::FRINT,  MVT::f80, Expand);
    setOperationAction(ISD::FNEARBYINT, MVT::f80, Expand);
    setOperationAction(ISD::FMA, MVT::f80, Expand);
    setOperationAction(ISD::LROUND, MVT::f80, Expand);
    setOperationAction(ISD::LLROUND, MVT::f80, Expand);
    setOperationAction(ISD::LRINT, MVT::f80, Custom);
    setOperationAction(ISD::LLRINT, MVT::f80, Custom);

    // Handle constrained floating-point operations of scalar.
    setOperationAction(ISD::STRICT_FADD     , MVT::f80, Legal);
    setOperationAction(ISD::STRICT_FSUB     , MVT::f80, Legal);
    setOperationAction(ISD::STRICT_FMUL     , MVT::f80, Legal);
    setOperationAction(ISD::STRICT_FDIV     , MVT::f80, Legal);
    setOperationAction(ISD::STRICT_FSQRT    , MVT::f80, Legal);
    setOperationAction(ISD::STRICT_FP_EXTEND, MVT::f80, Legal);
    // FIXME: When the target is 64-bit, STRICT_FP_ROUND will be overwritten
    // as Custom.
    setOperationAction(ISD::STRICT_FP_ROUND, MVT::f80, Legal);
  }

  // f128 uses xmm registers, but most operations require libcalls.
  if (!Subtarget.useSoftFloat() && Subtarget.is64Bit() && Subtarget.hasSSE1()) {
    addRegisterClass(MVT::f128, Subtarget.hasVLX() ? &X86::VR128XRegClass
                                                   : &X86::VR128RegClass);

    addLegalFPImmediate(APFloat::getZero(APFloat::IEEEquad())); // xorps

    setOperationAction(ISD::FADD,        MVT::f128, LibCall);
    setOperationAction(ISD::STRICT_FADD, MVT::f128, LibCall);
    setOperationAction(ISD::FSUB,        MVT::f128, LibCall);
    setOperationAction(ISD::STRICT_FSUB, MVT::f128, LibCall);
    setOperationAction(ISD::FDIV,        MVT::f128, LibCall);
    setOperationAction(ISD::STRICT_FDIV, MVT::f128, LibCall);
    setOperationAction(ISD::FMUL,        MVT::f128, LibCall);
    setOperationAction(ISD::STRICT_FMUL, MVT::f128, LibCall);
    setOperationAction(ISD::FMA,         MVT::f128, LibCall);
    setOperationAction(ISD::STRICT_FMA,  MVT::f128, LibCall);

    setOperationAction(ISD::FABS, MVT::f128, Custom);
    setOperationAction(ISD::FNEG, MVT::f128, Custom);
    setOperationAction(ISD::FCOPYSIGN, MVT::f128, Custom);

    setOperationAction(ISD::FSIN,         MVT::f128, LibCall);
    setOperationAction(ISD::STRICT_FSIN,  MVT::f128, LibCall);
    setOperationAction(ISD::FCOS,         MVT::f128, LibCall);
    setOperationAction(ISD::STRICT_FCOS,  MVT::f128, LibCall);
    setOperationAction(ISD::FSINCOS,      MVT::f128, LibCall);
    // No STRICT_FSINCOS
    setOperationAction(ISD::FSQRT,        MVT::f128, LibCall);
    setOperationAction(ISD::STRICT_FSQRT, MVT::f128, LibCall);

    setOperationAction(ISD::FP_EXTEND,        MVT::f128, Custom);
    setOperationAction(ISD::STRICT_FP_EXTEND, MVT::f128, Custom);
    // We need to custom handle any FP_ROUND with an f128 input, but
    // LegalizeDAG uses the result type to know when to run a custom handler.
    // So we have to list all legal floating point result types here.
    if (isTypeLegal(MVT::f32)) {
      setOperationAction(ISD::FP_ROUND, MVT::f32, Custom);
      setOperationAction(ISD::STRICT_FP_ROUND, MVT::f32, Custom);
    }
    if (isTypeLegal(MVT::f64)) {
      setOperationAction(ISD::FP_ROUND, MVT::f64, Custom);
      setOperationAction(ISD::STRICT_FP_ROUND, MVT::f64, Custom);
    }
    if (isTypeLegal(MVT::f80)) {
      setOperationAction(ISD::FP_ROUND, MVT::f80, Custom);
      setOperationAction(ISD::STRICT_FP_ROUND, MVT::f80, Custom);
    }

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

    setLoadExtAction(ISD::EXTLOAD, MVT::f128, MVT::f32, Expand);
    setLoadExtAction(ISD::EXTLOAD, MVT::f128, MVT::f64, Expand);
    setLoadExtAction(ISD::EXTLOAD, MVT::f128, MVT::f80, Expand);
    setTruncStoreAction(MVT::f128, MVT::f32, Expand);
    setTruncStoreAction(MVT::f128, MVT::f64, Expand);
    setTruncStoreAction(MVT::f128, MVT::f80, Expand);
  }

  // Always use a library call for pow.
  setOperationAction(ISD::FPOW             , MVT::f32  , Expand);
  setOperationAction(ISD::FPOW             , MVT::f64  , Expand);
  setOperationAction(ISD::FPOW             , MVT::f80  , Expand);
  setOperationAction(ISD::FPOW             , MVT::f128 , Expand);

  setOperationAction(ISD::FLOG, MVT::f80, Expand);
  setOperationAction(ISD::FLOG2, MVT::f80, Expand);
  setOperationAction(ISD::FLOG10, MVT::f80, Expand);
  setOperationAction(ISD::FEXP, MVT::f80, Expand);
  setOperationAction(ISD::FEXP2, MVT::f80, Expand);
  setOperationAction(ISD::FMINNUM, MVT::f80, Expand);
  setOperationAction(ISD::FMAXNUM, MVT::f80, Expand);

  // Some FP actions are always expanded for vector types.
  for (auto VT : { MVT::v4f32, MVT::v8f32, MVT::v16f32,
                   MVT::v2f64, MVT::v4f64, MVT::v8f64 }) {
    setOperationAction(ISD::FSIN,      VT, Expand);
    setOperationAction(ISD::FSINCOS,   VT, Expand);
    setOperationAction(ISD::FCOS,      VT, Expand);
    setOperationAction(ISD::FREM,      VT, Expand);
    setOperationAction(ISD::FCOPYSIGN, VT, Expand);
    setOperationAction(ISD::FPOW,      VT, Expand);
    setOperationAction(ISD::FLOG,      VT, Expand);
    setOperationAction(ISD::FLOG2,     VT, Expand);
    setOperationAction(ISD::FLOG10,    VT, Expand);
    setOperationAction(ISD::FEXP,      VT, Expand);
    setOperationAction(ISD::FEXP2,     VT, Expand);
  }

  // First set operation action for all vector types to either promote
  // (for widening) or expand (for scalarization). Then we will selectively
  // turn on ones that can be effectively codegen'd.
  for (MVT VT : MVT::fixedlen_vector_valuetypes()) {
    setOperationAction(ISD::SDIV, VT, Expand);
    setOperationAction(ISD::UDIV, VT, Expand);
    setOperationAction(ISD::SREM, VT, Expand);
    setOperationAction(ISD::UREM, VT, Expand);
    setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT,Expand);
    setOperationAction(ISD::INSERT_VECTOR_ELT, VT, Expand);
    setOperationAction(ISD::EXTRACT_SUBVECTOR, VT,Expand);
    setOperationAction(ISD::INSERT_SUBVECTOR, VT,Expand);
    setOperationAction(ISD::FMA,  VT, Expand);
    setOperationAction(ISD::FFLOOR, VT, Expand);
    setOperationAction(ISD::FCEIL, VT, Expand);
    setOperationAction(ISD::FTRUNC, VT, Expand);
    setOperationAction(ISD::FRINT, VT, Expand);
    setOperationAction(ISD::FNEARBYINT, VT, Expand);
    setOperationAction(ISD::SMUL_LOHI, VT, Expand);
    setOperationAction(ISD::MULHS, VT, Expand);
    setOperationAction(ISD::UMUL_LOHI, VT, Expand);
    setOperationAction(ISD::MULHU, VT, Expand);
    setOperationAction(ISD::SDIVREM, VT, Expand);
    setOperationAction(ISD::UDIVREM, VT, Expand);
    setOperationAction(ISD::CTPOP, VT, Expand);
    setOperationAction(ISD::CTTZ, VT, Expand);
    setOperationAction(ISD::CTLZ, VT, Expand);
    setOperationAction(ISD::ROTL, VT, Expand);
    setOperationAction(ISD::ROTR, VT, Expand);
    setOperationAction(ISD::BSWAP, VT, Expand);
    setOperationAction(ISD::SETCC, VT, Expand);
    setOperationAction(ISD::FP_TO_UINT, VT, Expand);
    setOperationAction(ISD::FP_TO_SINT, VT, Expand);
    setOperationAction(ISD::UINT_TO_FP, VT, Expand);
    setOperationAction(ISD::SINT_TO_FP, VT, Expand);
    setOperationAction(ISD::SIGN_EXTEND_INREG, VT,Expand);
    setOperationAction(ISD::TRUNCATE, VT, Expand);
    setOperationAction(ISD::SIGN_EXTEND, VT, Expand);
    setOperationAction(ISD::ZERO_EXTEND, VT, Expand);
    setOperationAction(ISD::ANY_EXTEND, VT, Expand);
    setOperationAction(ISD::SELECT_CC, VT, Expand);
    for (MVT InnerVT : MVT::fixedlen_vector_valuetypes()) {
      setTruncStoreAction(InnerVT, VT, Expand);

      setLoadExtAction(ISD::SEXTLOAD, InnerVT, VT, Expand);
      setLoadExtAction(ISD::ZEXTLOAD, InnerVT, VT, Expand);

      // N.b. ISD::EXTLOAD legality is basically ignored except for i1-like
      // types, we have to deal with them whether we ask for Expansion or not.
      // Setting Expand causes its own optimisation problems though, so leave
      // them legal.
      if (VT.getVectorElementType() == MVT::i1)
        setLoadExtAction(ISD::EXTLOAD, InnerVT, VT, Expand);

      // EXTLOAD for MVT::f16 vectors is not legal because f16 vectors are
      // split/scalarized right now.
      if (VT.getVectorElementType() == MVT::f16)
        setLoadExtAction(ISD::EXTLOAD, InnerVT, VT, Expand);
    }
  }

  // FIXME: In order to prevent SSE instructions being expanded to MMX ones
  // with -msoft-float, disable use of MMX as well.
  if (!Subtarget.useSoftFloat() && Subtarget.hasMMX()) {
    addRegisterClass(MVT::x86mmx, &X86::VR64RegClass);
    // No operations on x86mmx supported, everything uses intrinsics.
  }

  if (!Subtarget.useSoftFloat() && Subtarget.hasSSE1()) {
    addRegisterClass(MVT::v4f32, Subtarget.hasVLX() ? &X86::VR128XRegClass
                                                    : &X86::VR128RegClass);

    setOperationAction(ISD::FNEG,               MVT::v4f32, Custom);
    setOperationAction(ISD::FABS,               MVT::v4f32, Custom);
    setOperationAction(ISD::FCOPYSIGN,          MVT::v4f32, Custom);
    setOperationAction(ISD::BUILD_VECTOR,       MVT::v4f32, Custom);
    setOperationAction(ISD::VECTOR_SHUFFLE,     MVT::v4f32, Custom);
    setOperationAction(ISD::VSELECT,            MVT::v4f32, Custom);
    setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4f32, Custom);
    setOperationAction(ISD::SELECT,             MVT::v4f32, Custom);

    setOperationAction(ISD::LOAD,               MVT::v2f32, Custom);
    setOperationAction(ISD::STORE,              MVT::v2f32, Custom);

    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_FSQRT,       MVT::v4f32, Legal);
  }

  if (!Subtarget.useSoftFloat() && Subtarget.hasSSE2()) {
    addRegisterClass(MVT::v2f64, Subtarget.hasVLX() ? &X86::VR128XRegClass
                                                    : &X86::VR128RegClass);

    // FIXME: Unfortunately, -soft-float and -no-implicit-float mean XMM
    // registers cannot be used even for integer operations.
    addRegisterClass(MVT::v16i8, Subtarget.hasVLX() ? &X86::VR128XRegClass
                                                    : &X86::VR128RegClass);
    addRegisterClass(MVT::v8i16, Subtarget.hasVLX() ? &X86::VR128XRegClass
                                                    : &X86::VR128RegClass);
    addRegisterClass(MVT::v4i32, Subtarget.hasVLX() ? &X86::VR128XRegClass
                                                    : &X86::VR128RegClass);
    addRegisterClass(MVT::v2i64, Subtarget.hasVLX() ? &X86::VR128XRegClass
                                                    : &X86::VR128RegClass);

    for (auto VT : { MVT::v2i8, MVT::v4i8, MVT::v8i8,
                     MVT::v2i16, MVT::v4i16, MVT::v2i32 }) {
      setOperationAction(ISD::SDIV, VT, Custom);
      setOperationAction(ISD::SREM, VT, Custom);
      setOperationAction(ISD::UDIV, VT, Custom);
      setOperationAction(ISD::UREM, VT, Custom);
    }

    setOperationAction(ISD::MUL,                MVT::v2i8,  Custom);
    setOperationAction(ISD::MUL,                MVT::v4i8,  Custom);
    setOperationAction(ISD::MUL,                MVT::v8i8,  Custom);

    setOperationAction(ISD::MUL,                MVT::v16i8, Custom);
    setOperationAction(ISD::MUL,                MVT::v4i32, Custom);
    setOperationAction(ISD::MUL,                MVT::v2i64, Custom);
    setOperationAction(ISD::MULHU,              MVT::v4i32, Custom);
    setOperationAction(ISD::MULHS,              MVT::v4i32, Custom);
    setOperationAction(ISD::MULHU,              MVT::v16i8, Custom);
    setOperationAction(ISD::MULHS,              MVT::v16i8, Custom);
    setOperationAction(ISD::MULHU,              MVT::v8i16, Legal);
    setOperationAction(ISD::MULHS,              MVT::v8i16, Legal);
    setOperationAction(ISD::MUL,                MVT::v8i16, Legal);
    setOperationAction(ISD::FNEG,               MVT::v2f64, Custom);
    setOperationAction(ISD::FABS,               MVT::v2f64, Custom);
    setOperationAction(ISD::FCOPYSIGN,          MVT::v2f64, Custom);

    for (auto VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64 }) {
      setOperationAction(ISD::SMAX, VT, VT == MVT::v8i16 ? Legal : Custom);
      setOperationAction(ISD::SMIN, VT, VT == MVT::v8i16 ? Legal : Custom);
      setOperationAction(ISD::UMAX, VT, VT == MVT::v16i8 ? Legal : Custom);
      setOperationAction(ISD::UMIN, VT, VT == MVT::v16i8 ? Legal : Custom);
    }

    setOperationAction(ISD::UADDSAT,            MVT::v16i8, Legal);
    setOperationAction(ISD::SADDSAT,            MVT::v16i8, Legal);
    setOperationAction(ISD::USUBSAT,            MVT::v16i8, Legal);
    setOperationAction(ISD::SSUBSAT,            MVT::v16i8, Legal);
    setOperationAction(ISD::UADDSAT,            MVT::v8i16, Legal);
    setOperationAction(ISD::SADDSAT,            MVT::v8i16, Legal);
    setOperationAction(ISD::USUBSAT,            MVT::v8i16, Legal);
    setOperationAction(ISD::SSUBSAT,            MVT::v8i16, Legal);
    setOperationAction(ISD::UADDSAT,            MVT::v4i32, Custom);
    setOperationAction(ISD::USUBSAT,            MVT::v4i32, Custom);
    setOperationAction(ISD::UADDSAT,            MVT::v2i64, Custom);
    setOperationAction(ISD::USUBSAT,            MVT::v2i64, Custom);

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

    for (auto VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64 }) {
      setOperationAction(ISD::SETCC,              VT, Custom);
      setOperationAction(ISD::STRICT_FSETCC,      VT, Custom);
      setOperationAction(ISD::STRICT_FSETCCS,     VT, Custom);
      setOperationAction(ISD::CTPOP,              VT, Custom);
      setOperationAction(ISD::ABS,                VT, Custom);

      // The condition codes aren't legal in SSE/AVX and under AVX512 we use
      // setcc all the way to isel and prefer SETGT in some isel patterns.
      setCondCodeAction(ISD::SETLT, VT, Custom);
      setCondCodeAction(ISD::SETLE, VT, Custom);
    }

    for (auto VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
      setOperationAction(ISD::SCALAR_TO_VECTOR,   VT, Custom);
      setOperationAction(ISD::BUILD_VECTOR,       VT, Custom);
      setOperationAction(ISD::VECTOR_SHUFFLE,     VT, Custom);
      setOperationAction(ISD::VSELECT,            VT, Custom);
      setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT, Custom);
    }

    for (auto VT : { MVT::v2f64, MVT::v2i64 }) {
      setOperationAction(ISD::BUILD_VECTOR,       VT, Custom);
      setOperationAction(ISD::VECTOR_SHUFFLE,     VT, Custom);
      setOperationAction(ISD::VSELECT,            VT, Custom);

      if (VT == MVT::v2i64 && !Subtarget.is64Bit())
        continue;

      setOperationAction(ISD::INSERT_VECTOR_ELT,  VT, Custom);
      setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT, Custom);
    }

    // Custom lower v2i64 and v2f64 selects.
    setOperationAction(ISD::SELECT,             MVT::v2f64, Custom);
    setOperationAction(ISD::SELECT,             MVT::v2i64, Custom);
    setOperationAction(ISD::SELECT,             MVT::v4i32, Custom);
    setOperationAction(ISD::SELECT,             MVT::v8i16, Custom);
    setOperationAction(ISD::SELECT,             MVT::v16i8, Custom);

    setOperationAction(ISD::FP_TO_SINT,         MVT::v4i32, Legal);
    setOperationAction(ISD::FP_TO_SINT,         MVT::v2i32, Custom);
    setOperationAction(ISD::STRICT_FP_TO_SINT,  MVT::v4i32, Legal);
    setOperationAction(ISD::STRICT_FP_TO_SINT,  MVT::v2i32, Custom);

    // Custom legalize these to avoid over promotion or custom promotion.
    for (auto VT : {MVT::v2i8, MVT::v4i8, MVT::v8i8, MVT::v2i16, MVT::v4i16}) {
      setOperationAction(ISD::FP_TO_SINT,        VT, Custom);
      setOperationAction(ISD::FP_TO_UINT,        VT, Custom);
      setOperationAction(ISD::STRICT_FP_TO_SINT, VT, Custom);
      setOperationAction(ISD::STRICT_FP_TO_UINT, VT, Custom);
    }

    setOperationAction(ISD::SINT_TO_FP,         MVT::v4i32, Legal);
    setOperationAction(ISD::STRICT_SINT_TO_FP,  MVT::v4i32, Legal);
    setOperationAction(ISD::SINT_TO_FP,         MVT::v2i32, Custom);
    setOperationAction(ISD::STRICT_SINT_TO_FP,  MVT::v2i32, Custom);

    setOperationAction(ISD::UINT_TO_FP,         MVT::v2i32, Custom);
    setOperationAction(ISD::STRICT_UINT_TO_FP,  MVT::v2i32, Custom);

    setOperationAction(ISD::UINT_TO_FP,         MVT::v4i32, Custom);
    setOperationAction(ISD::STRICT_UINT_TO_FP,  MVT::v4i32, Custom);

    // Fast v2f32 UINT_TO_FP( v2i32 ) custom conversion.
    setOperationAction(ISD::SINT_TO_FP,         MVT::v2f32, Custom);
    setOperationAction(ISD::STRICT_SINT_TO_FP,  MVT::v2f32, Custom);
    setOperationAction(ISD::UINT_TO_FP,         MVT::v2f32, Custom);
    setOperationAction(ISD::STRICT_UINT_TO_FP,  MVT::v2f32, Custom);

    setOperationAction(ISD::FP_EXTEND,          MVT::v2f32, Custom);
    setOperationAction(ISD::STRICT_FP_EXTEND,   MVT::v2f32, Custom);
    setOperationAction(ISD::FP_ROUND,           MVT::v2f32, Custom);
    setOperationAction(ISD::STRICT_FP_ROUND,    MVT::v2f32, Custom);

    // We want to legalize this to an f64 load rather than an i64 load on
    // 64-bit targets and two 32-bit loads on a 32-bit target. Similar for
    // store.
    setOperationAction(ISD::LOAD,               MVT::v2i32, Custom);
    setOperationAction(ISD::LOAD,               MVT::v4i16, Custom);
    setOperationAction(ISD::LOAD,               MVT::v8i8,  Custom);
    setOperationAction(ISD::STORE,              MVT::v2i32, Custom);
    setOperationAction(ISD::STORE,              MVT::v4i16, Custom);
    setOperationAction(ISD::STORE,              MVT::v8i8,  Custom);

    setOperationAction(ISD::BITCAST,            MVT::v2i32, Custom);
    setOperationAction(ISD::BITCAST,            MVT::v4i16, Custom);
    setOperationAction(ISD::BITCAST,            MVT::v8i8,  Custom);
    if (!Subtarget.hasAVX512())
      setOperationAction(ISD::BITCAST, MVT::v16i1, Custom);

    setOperationAction(ISD::SIGN_EXTEND_VECTOR_INREG, MVT::v2i64, Custom);
    setOperationAction(ISD::SIGN_EXTEND_VECTOR_INREG, MVT::v4i32, Custom);
    setOperationAction(ISD::SIGN_EXTEND_VECTOR_INREG, MVT::v8i16, Custom);

    setOperationAction(ISD::SIGN_EXTEND, MVT::v4i64, Custom);

    setOperationAction(ISD::TRUNCATE,    MVT::v2i8,  Custom);
    setOperationAction(ISD::TRUNCATE,    MVT::v2i16, Custom);
    setOperationAction(ISD::TRUNCATE,    MVT::v2i32, Custom);
    setOperationAction(ISD::TRUNCATE,    MVT::v4i8,  Custom);
    setOperationAction(ISD::TRUNCATE,    MVT::v4i16, Custom);
    setOperationAction(ISD::TRUNCATE,    MVT::v8i8,  Custom);

    // In the customized shift lowering, the legal v4i32/v2i64 cases
    // in AVX2 will be recognized.
    for (auto VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64 }) {
      setOperationAction(ISD::SRL,              VT, Custom);
      setOperationAction(ISD::SHL,              VT, Custom);
      setOperationAction(ISD::SRA,              VT, Custom);
    }

    setOperationAction(ISD::ROTL,               MVT::v4i32, Custom);
    setOperationAction(ISD::ROTL,               MVT::v8i16, Custom);

    // With AVX512, expanding (and promoting the shifts) is better.
    if (!Subtarget.hasAVX512())
      setOperationAction(ISD::ROTL,             MVT::v16i8, Custom);

    setOperationAction(ISD::STRICT_FSQRT,       MVT::v2f64, 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);
  }

  if (!Subtarget.useSoftFloat() && Subtarget.hasSSSE3()) {
    setOperationAction(ISD::ABS,                MVT::v16i8, Legal);
    setOperationAction(ISD::ABS,                MVT::v8i16, Legal);
    setOperationAction(ISD::ABS,                MVT::v4i32, Legal);
    setOperationAction(ISD::BITREVERSE,         MVT::v16i8, Custom);
    setOperationAction(ISD::CTLZ,               MVT::v16i8, Custom);
    setOperationAction(ISD::CTLZ,               MVT::v8i16, Custom);
    setOperationAction(ISD::CTLZ,               MVT::v4i32, Custom);
    setOperationAction(ISD::CTLZ,               MVT::v2i64, Custom);

    // These might be better off as horizontal vector ops.
    setOperationAction(ISD::ADD,                MVT::i16, Custom);
    setOperationAction(ISD::ADD,                MVT::i32, Custom);
    setOperationAction(ISD::SUB,                MVT::i16, Custom);
    setOperationAction(ISD::SUB,                MVT::i32, Custom);
  }

  if (!Subtarget.useSoftFloat() && Subtarget.hasSSE41()) {
    for (MVT RoundedTy : {MVT::f32, MVT::f64, MVT::v4f32, MVT::v2f64}) {
      setOperationAction(ISD::FFLOOR,            RoundedTy,  Legal);
      setOperationAction(ISD::STRICT_FFLOOR,     RoundedTy,  Legal);
      setOperationAction(ISD::FCEIL,             RoundedTy,  Legal);
      setOperationAction(ISD::STRICT_FCEIL,      RoundedTy,  Legal);
      setOperationAction(ISD::FTRUNC,            RoundedTy,  Legal);
      setOperationAction(ISD::STRICT_FTRUNC,     RoundedTy,  Legal);
      setOperationAction(ISD::FRINT,             RoundedTy,  Legal);
      setOperationAction(ISD::STRICT_FRINT,      RoundedTy,  Legal);
      setOperationAction(ISD::FNEARBYINT,        RoundedTy,  Legal);
      setOperationAction(ISD::STRICT_FNEARBYINT, RoundedTy,  Legal);

      setOperationAction(ISD::FROUND,            RoundedTy,  Custom);
    }

    setOperationAction(ISD::SMAX,               MVT::v16i8, Legal);
    setOperationAction(ISD::SMAX,               MVT::v4i32, Legal);
    setOperationAction(ISD::UMAX,               MVT::v8i16, Legal);
    setOperationAction(ISD::UMAX,               MVT::v4i32, Legal);
    setOperationAction(ISD::SMIN,               MVT::v16i8, Legal);
    setOperationAction(ISD::SMIN,               MVT::v4i32, Legal);
    setOperationAction(ISD::UMIN,               MVT::v8i16, Legal);
    setOperationAction(ISD::UMIN,               MVT::v4i32, Legal);

    // FIXME: Do we need to handle scalar-to-vector here?
    setOperationAction(ISD::MUL,                MVT::v4i32, Legal);

    // We directly match byte blends in the backend as they match the VSELECT
    // condition form.
    setOperationAction(ISD::VSELECT,            MVT::v16i8, Legal);

    // SSE41 brings specific instructions for doing vector sign extend even in
    // cases where we don't have SRA.
    for (auto VT : { MVT::v8i16, MVT::v4i32, MVT::v2i64 }) {
      setOperationAction(ISD::SIGN_EXTEND_VECTOR_INREG, VT, Legal);
      setOperationAction(ISD::ZERO_EXTEND_VECTOR_INREG, VT, Legal);
    }

    // SSE41 also has vector sign/zero extending loads, PMOV[SZ]X
    for (auto LoadExtOp : { ISD::SEXTLOAD, ISD::ZEXTLOAD }) {
      setLoadExtAction(LoadExtOp, MVT::v8i16, MVT::v8i8,  Legal);
      setLoadExtAction(LoadExtOp, MVT::v4i32, MVT::v4i8,  Legal);
      setLoadExtAction(LoadExtOp, MVT::v2i64, MVT::v2i8,  Legal);
      setLoadExtAction(LoadExtOp, MVT::v4i32, MVT::v4i16, Legal);
      setLoadExtAction(LoadExtOp, MVT::v2i64, MVT::v2i16, Legal);
      setLoadExtAction(LoadExtOp, MVT::v2i64, MVT::v2i32, Legal);
    }

    // i8 vectors are custom because the source register and source
    // source memory operand types are not the same width.
    setOperationAction(ISD::INSERT_VECTOR_ELT,  MVT::v16i8, Custom);

    if (Subtarget.is64Bit() && !Subtarget.hasAVX512()) {
      // We need to scalarize v4i64->v432 uint_to_fp using cvtsi2ss, but we can
      // do the pre and post work in the vector domain.
      setOperationAction(ISD::UINT_TO_FP,        MVT::v4i64, Custom);
      setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v4i64, Custom);
      // We need to mark SINT_TO_FP as Custom even though we want to expand it
      // so that DAG combine doesn't try to turn it into uint_to_fp.
      setOperationAction(ISD::SINT_TO_FP,        MVT::v4i64, Custom);
      setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::v4i64, Custom);
    }
  }

  if (!Subtarget.useSoftFloat() && Subtarget.hasXOP()) {
    for (auto VT : { MVT::v16i8, MVT::v8i16,  MVT::v4i32, MVT::v2i64,
                     MVT::v32i8, MVT::v16i16, MVT::v8i32, MVT::v4i64 })
      setOperationAction(ISD::ROTL, VT, Custom);

    // XOP can efficiently perform BITREVERSE with VPPERM.
    for (auto VT : { MVT::i8, MVT::i16, MVT::i32, MVT::i64 })
      setOperationAction(ISD::BITREVERSE, VT, Custom);

    for (auto VT : { MVT::v16i8, MVT::v8i16,  MVT::v4i32, MVT::v2i64,
                     MVT::v32i8, MVT::v16i16, MVT::v8i32, MVT::v4i64 })
      setOperationAction(ISD::BITREVERSE, VT, Custom);
  }

  if (!Subtarget.useSoftFloat() && Subtarget.hasAVX()) {
    bool HasInt256 = Subtarget.hasInt256();

    addRegisterClass(MVT::v32i8,  Subtarget.hasVLX() ? &X86::VR256XRegClass
                                                     : &X86::VR256RegClass);
    addRegisterClass(MVT::v16i16, Subtarget.hasVLX() ? &X86::VR256XRegClass
                                                     : &X86::VR256RegClass);
    addRegisterClass(MVT::v8i32,  Subtarget.hasVLX() ? &X86::VR256XRegClass
                                                     : &X86::VR256RegClass);
    addRegisterClass(MVT::v8f32,  Subtarget.hasVLX() ? &X86::VR256XRegClass
                                                     : &X86::VR256RegClass);
    addRegisterClass(MVT::v4i64,  Subtarget.hasVLX() ? &X86::VR256XRegClass
                                                     : &X86::VR256RegClass);
    addRegisterClass(MVT::v4f64,  Subtarget.hasVLX() ? &X86::VR256XRegClass
                                                     : &X86::VR256RegClass);

    for (auto VT : { MVT::v8f32, MVT::v4f64 }) {
      setOperationAction(ISD::FFLOOR,            VT, Legal);
      setOperationAction(ISD::STRICT_FFLOOR,     VT, Legal);
      setOperationAction(ISD::FCEIL,             VT, Legal);
      setOperationAction(ISD::STRICT_FCEIL,      VT, Legal);
      setOperationAction(ISD::FTRUNC,            VT, Legal);
      setOperationAction(ISD::STRICT_FTRUNC,     VT, Legal);
      setOperationAction(ISD::FRINT,             VT, Legal);
      setOperationAction(ISD::STRICT_FRINT,      VT, Legal);
      setOperationAction(ISD::FNEARBYINT,        VT, Legal);
      setOperationAction(ISD::STRICT_FNEARBYINT, VT, Legal);

      setOperationAction(ISD::FROUND,            VT, Custom);

      setOperationAction(ISD::FNEG,              VT, Custom);
      setOperationAction(ISD::FABS,              VT, Custom);
      setOperationAction(ISD::FCOPYSIGN,         VT, Custom);
    }

    // (fp_to_int:v8i16 (v8f32 ..)) requires the result type to be promoted
    // even though v8i16 is a legal type.
    setOperationPromotedToType(ISD::FP_TO_SINT,        MVT::v8i16, MVT::v8i32);
    setOperationPromotedToType(ISD::FP_TO_UINT,        MVT::v8i16, MVT::v8i32);
    setOperationPromotedToType(ISD::STRICT_FP_TO_SINT, MVT::v8i16, MVT::v8i32);
    setOperationPromotedToType(ISD::STRICT_FP_TO_UINT, MVT::v8i16, MVT::v8i32);
    setOperationAction(ISD::FP_TO_SINT,                MVT::v8i32, Legal);
    setOperationAction(ISD::STRICT_FP_TO_SINT,         MVT::v8i32, Legal);

    setOperationAction(ISD::SINT_TO_FP,         MVT::v8i32, Legal);
    setOperationAction(ISD::STRICT_SINT_TO_FP,  MVT::v8i32, Legal);

    setOperationAction(ISD::STRICT_FP_ROUND,    MVT::v4f32, Legal);
    setOperationAction(ISD::STRICT_FADD,        MVT::v8f32, Legal);
    setOperationAction(ISD::STRICT_FADD,        MVT::v4f64, Legal);
    setOperationAction(ISD::STRICT_FSUB,        MVT::v8f32, Legal);
    setOperationAction(ISD::STRICT_FSUB,        MVT::v4f64, Legal);
    setOperationAction(ISD::STRICT_FMUL,        MVT::v8f32, Legal);
    setOperationAction(ISD::STRICT_FMUL,        MVT::v4f64, Legal);
    setOperationAction(ISD::STRICT_FDIV,        MVT::v8f32, Legal);
    setOperationAction(ISD::STRICT_FDIV,        MVT::v4f64, Legal);
    setOperationAction(ISD::STRICT_FP_EXTEND,   MVT::v4f64, Legal);
    setOperationAction(ISD::STRICT_FSQRT,       MVT::v8f32, Legal);
    setOperationAction(ISD::STRICT_FSQRT,       MVT::v4f64, Legal);

    if (!Subtarget.hasAVX512())
      setOperationAction(ISD::BITCAST, MVT::v32i1, Custom);

    // In the customized shift lowering, the legal v8i32/v4i64 cases
    // in AVX2 will be recognized.
    for (auto VT : { MVT::v32i8, MVT::v16i16, MVT::v8i32, MVT::v4i64 }) {
      setOperationAction(ISD::SRL, VT, Custom);
      setOperationAction(ISD::SHL, VT, Custom);
      setOperationAction(ISD::SRA, VT, Custom);
    }

    // These types need custom splitting if their input is a 128-bit vector.
    setOperationAction(ISD::SIGN_EXTEND,       MVT::v8i64,  Custom);
    setOperationAction(ISD::SIGN_EXTEND,       MVT::v16i32, Custom);
    setOperationAction(ISD::ZERO_EXTEND,       MVT::v8i64,  Custom);
    setOperationAction(ISD::ZERO_EXTEND,       MVT::v16i32, Custom);

    setOperationAction(ISD::ROTL,              MVT::v8i32,  Custom);
    setOperationAction(ISD::ROTL,              MVT::v16i16, Custom);

    // With BWI, expanding (and promoting the shifts) is the better.
    if (!Subtarget.hasBWI())
      setOperationAction(ISD::ROTL,            MVT::v32i8,  Custom);

    setOperationAction(ISD::SELECT,            MVT::v4f64, Custom);
    setOperationAction(ISD::SELECT,            MVT::v4i64, Custom);
    setOperationAction(ISD::SELECT,            MVT::v8i32, Custom);
    setOperationAction(ISD::SELECT,            MVT::v16i16, Custom);
    setOperationAction(ISD::SELECT,            MVT::v32i8, Custom);
    setOperationAction(ISD::SELECT,            MVT::v8f32, Custom);

    for (auto VT : { MVT::v16i16, MVT::v8i32, MVT::v4i64 }) {
      setOperationAction(ISD::SIGN_EXTEND,     VT, Custom);
      setOperationAction(ISD::ZERO_EXTEND,     VT, Custom);
      setOperationAction(ISD::ANY_EXTEND,      VT, Custom);
    }

    setOperationAction(ISD::TRUNCATE,          MVT::v16i8, Custom);
    setOperationAction(ISD::TRUNCATE,          MVT::v8i16, Custom);
    setOperationAction(ISD::TRUNCATE,          MVT::v4i32, Custom);
    setOperationAction(ISD::BITREVERSE,        MVT::v32i8, Custom);

    for (auto VT : { MVT::v32i8, MVT::v16i16, MVT::v8i32, MVT::v4i64 }) {
      setOperationAction(ISD::SETCC,           VT, Custom);
      setOperationAction(ISD::STRICT_FSETCC,   VT, Custom);
      setOperationAction(ISD::STRICT_FSETCCS,  VT, Custom);
      setOperationAction(ISD::CTPOP,           VT, Custom);
      setOperationAction(ISD::CTLZ,            VT, Custom);

      // The condition codes aren't legal in SSE/AVX and under AVX512 we use
      // setcc all the way to isel and prefer SETGT in some isel patterns.
      setCondCodeAction(ISD::SETLT, VT, Custom);
      setCondCodeAction(ISD::SETLE, VT, Custom);
    }

    if (Subtarget.hasAnyFMA()) {
      for (auto VT : { MVT::f32, MVT::f64, MVT::v4f32, MVT::v8f32,
                       MVT::v2f64, MVT::v4f64 }) {
        setOperationAction(ISD::FMA, VT, Legal);
        setOperationAction(ISD::STRICT_FMA, VT, Legal);
      }
    }

    for (auto VT : { MVT::v32i8, MVT::v16i16, MVT::v8i32, MVT::v4i64 }) {
      setOperationAction(ISD::ADD, VT, HasInt256 ? Legal : Custom);
      setOperationAction(ISD::SUB, VT, HasInt256 ? Legal : Custom);
    }

    setOperationAction(ISD::MUL,       MVT::v4i64,  Custom);
    setOperationAction(ISD::MUL,       MVT::v8i32,  HasInt256 ? Legal : Custom);
    setOperationAction(ISD::MUL,       MVT::v16i16, HasInt256 ? Legal : Custom);
    setOperationAction(ISD::MUL,       MVT::v32i8,  Custom);

    setOperationAction(ISD::MULHU,     MVT::v8i32,  Custom);
    setOperationAction(ISD::MULHS,     MVT::v8i32,  Custom);
    setOperationAction(ISD::MULHU,     MVT::v16i16, HasInt256 ? Legal : Custom);
    setOperationAction(ISD::MULHS,     MVT::v16i16, HasInt256 ? Legal : Custom);
    setOperationAction(ISD::MULHU,     MVT::v32i8,  Custom);
    setOperationAction(ISD::MULHS,     MVT::v32i8,  Custom);

    setOperationAction(ISD::ABS,       MVT::v4i64,  Custom);
    setOperationAction(ISD::SMAX,      MVT::v4i64,  Custom);
    setOperationAction(ISD::UMAX,      MVT::v4i64,  Custom);
    setOperationAction(ISD::SMIN,      MVT::v4i64,  Custom);
    setOperationAction(ISD::UMIN,      MVT::v4i64,  Custom);

    setOperationAction(ISD::UADDSAT,   MVT::v32i8,  HasInt256 ? Legal : Custom);
    setOperationAction(ISD::SADDSAT,   MVT::v32i8,  HasInt256 ? Legal : Custom);
    setOperationAction(ISD::USUBSAT,   MVT::v32i8,  HasInt256 ? Legal : Custom);
    setOperationAction(ISD::SSUBSAT,   MVT::v32i8,  HasInt256 ? Legal : Custom);
    setOperationAction(ISD::UADDSAT,   MVT::v16i16, HasInt256 ? Legal : Custom);
    setOperationAction(ISD::SADDSAT,   MVT::v16i16, HasInt256 ? Legal : Custom);
    setOperationAction(ISD::USUBSAT,   MVT::v16i16, HasInt256 ? Legal : Custom);
    setOperationAction(ISD::SSUBSAT,   MVT::v16i16, HasInt256 ? Legal : Custom);

    for (auto VT : { MVT::v32i8, MVT::v16i16, MVT::v8i32 }) {
      setOperationAction(ISD::ABS,  VT, HasInt256 ? Legal : Custom);
      setOperationAction(ISD::SMAX, VT, HasInt256 ? Legal : Custom);
      setOperationAction(ISD::UMAX, VT, HasInt256 ? Legal : Custom);
      setOperationAction(ISD::SMIN, VT, HasInt256 ? Legal : Custom);
      setOperationAction(ISD::UMIN, VT, HasInt256 ? Legal : Custom);
    }

    for (auto VT : {MVT::v16i16, MVT::v8i32, MVT::v4i64}) {
      setOperationAction(ISD::SIGN_EXTEND_VECTOR_INREG, VT, Custom);
      setOperationAction(ISD::ZERO_EXTEND_VECTOR_INREG, VT, Custom);
    }

    if (HasInt256) {
      // The custom lowering for UINT_TO_FP for v8i32 becomes interesting
      // when we have a 256bit-wide blend with immediate.
      setOperationAction(ISD::UINT_TO_FP, MVT::v8i32, Custom);
      setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v8i32, Custom);

      // AVX2 also has wider vector sign/zero extending loads, VPMOV[SZ]X
      for (auto LoadExtOp : { ISD::SEXTLOAD, ISD::ZEXTLOAD }) {
        setLoadExtAction(LoadExtOp, MVT::v16i16, MVT::v16i8, Legal);
        setLoadExtAction(LoadExtOp, MVT::v8i32,  MVT::v8i8,  Legal);
        setLoadExtAction(LoadExtOp, MVT::v4i64,  MVT::v4i8,  Legal);
        setLoadExtAction(LoadExtOp, MVT::v8i32,  MVT::v8i16, Legal);
        setLoadExtAction(LoadExtOp, MVT::v4i64,  MVT::v4i16, Legal);
        setLoadExtAction(LoadExtOp, MVT::v4i64,  MVT::v4i32, Legal);
      }
    }

    for (auto VT : { MVT::v4i32, MVT::v8i32, MVT::v2i64, MVT::v4i64,
                     MVT::v4f32, MVT::v8f32, MVT::v2f64, MVT::v4f64 }) {
      setOperationAction(ISD::MLOAD,  VT, Subtarget.hasVLX() ? Legal : Custom);
      setOperationAction(ISD::MSTORE, VT, Legal);
    }

    // Extract subvector is special because the value type
    // (result) is 128-bit but the source is 256-bit wide.
    for (auto VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64,
                     MVT::v4f32, MVT::v2f64 }) {
      setOperationAction(ISD::EXTRACT_SUBVECTOR, VT, Legal);
    }

    // Custom lower several nodes for 256-bit types.
    for (MVT VT : { MVT::v32i8, MVT::v16i16, MVT::v8i32, MVT::v4i64,
                    MVT::v8f32, MVT::v4f64 }) {
      setOperationAction(ISD::BUILD_VECTOR,       VT, Custom);
      setOperationAction(ISD::VECTOR_SHUFFLE,     VT, Custom);
      setOperationAction(ISD::VSELECT,            VT, Custom);
      setOperationAction(ISD::INSERT_VECTOR_ELT,  VT, Custom);
      setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT, Custom);
      setOperationAction(ISD::SCALAR_TO_VECTOR,   VT, Custom);
      setOperationAction(ISD::INSERT_SUBVECTOR,   VT, Legal);
      setOperationAction(ISD::CONCAT_VECTORS,     VT, Custom);
      setOperationAction(ISD::STORE,              VT, Custom);
    }

    if (HasInt256) {
      setOperationAction(ISD::VSELECT, MVT::v32i8, Legal);

      // Custom legalize 2x32 to get a little better code.
      setOperationAction(ISD::MGATHER, MVT::v2f32, Custom);
      setOperationAction(ISD::MGATHER, MVT::v2i32, Custom);

      for (auto VT : { MVT::v4i32, MVT::v8i32, MVT::v2i64, MVT::v4i64,
                       MVT::v4f32, MVT::v8f32, MVT::v2f64, MVT::v4f64 })
        setOperationAction(ISD::MGATHER,  VT, Custom);
    }
  }

  // This block controls legalization of the mask vector sizes that are
  // available with AVX512. 512-bit vectors are in a separate block controlled
  // by useAVX512Regs.
  if (!Subtarget.useSoftFloat() && Subtarget.hasAVX512()) {
    addRegisterClass(MVT::v1i1,   &X86::VK1RegClass);
    addRegisterClass(MVT::v2i1,   &X86::VK2RegClass);
    addRegisterClass(MVT::v4i1,   &X86::VK4RegClass);
    addRegisterClass(MVT::v8i1,   &X86::VK8RegClass);
    addRegisterClass(MVT::v16i1,  &X86::VK16RegClass);

    setOperationAction(ISD::SELECT,             MVT::v1i1, Custom);
    setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v1i1, Custom);
    setOperationAction(ISD::BUILD_VECTOR,       MVT::v1i1, Custom);

    setOperationPromotedToType(ISD::FP_TO_SINT,        MVT::v8i1,  MVT::v8i32);
    setOperationPromotedToType(ISD::FP_TO_UINT,        MVT::v8i1,  MVT::v8i32);
    setOperationPromotedToType(ISD::FP_TO_SINT,        MVT::v4i1,  MVT::v4i32);
    setOperationPromotedToType(ISD::FP_TO_UINT,        MVT::v4i1,  MVT::v4i32);
    setOperationPromotedToType(ISD::STRICT_FP_TO_SINT, MVT::v8i1,  MVT::v8i32);
    setOperationPromotedToType(ISD::STRICT_FP_TO_UINT, MVT::v8i1,  MVT::v8i32);
    setOperationPromotedToType(ISD::STRICT_FP_TO_SINT, MVT::v4i1,  MVT::v4i32);
    setOperationPromotedToType(ISD::STRICT_FP_TO_UINT, MVT::v4i1,  MVT::v4i32);
    setOperationAction(ISD::FP_TO_SINT,                MVT::v2i1,  Custom);
    setOperationAction(ISD::FP_TO_UINT,                MVT::v2i1,  Custom);
    setOperationAction(ISD::STRICT_FP_TO_SINT,         MVT::v2i1,  Custom);
    setOperationAction(ISD::STRICT_FP_TO_UINT,         MVT::v2i1,  Custom);

    // There is no byte sized k-register load or store without AVX512DQ.
    if (!Subtarget.hasDQI()) {
      setOperationAction(ISD::LOAD, MVT::v1i1, Custom);
      setOperationAction(ISD::LOAD, MVT::v2i1, Custom);
      setOperationAction(ISD::LOAD, MVT::v4i1, Custom);
      setOperationAction(ISD::LOAD, MVT::v8i1, Custom);

      setOperationAction(ISD::STORE, MVT::v1i1, Custom);
      setOperationAction(ISD::STORE, MVT::v2i1, Custom);
      setOperationAction(ISD::STORE, MVT::v4i1, Custom);
      setOperationAction(ISD::STORE, MVT::v8i1, Custom);
    }

    // Extends of v16i1/v8i1/v4i1/v2i1 to 128-bit vectors.
    for (auto VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64 }) {
      setOperationAction(ISD::SIGN_EXTEND, VT, Custom);
      setOperationAction(ISD::ZERO_EXTEND, VT, Custom);
      setOperationAction(ISD::ANY_EXTEND,  VT, Custom);
    }

    for (auto VT : { MVT::v1i1, MVT::v2i1, MVT::v4i1, MVT::v8i1, MVT::v16i1 }) {
      setOperationAction(ISD::ADD,              VT, Custom);
      setOperationAction(ISD::SUB,              VT, Custom);
      setOperationAction(ISD::MUL,              VT, Custom);
      setOperationAction(ISD::UADDSAT,          VT, Custom);
      setOperationAction(ISD::SADDSAT,          VT, Custom);
      setOperationAction(ISD::USUBSAT,          VT, Custom);
      setOperationAction(ISD::SSUBSAT,          VT, Custom);
      setOperationAction(ISD::VSELECT,          VT,  Expand);
    }

    for (auto VT : { MVT::v2i1, MVT::v4i1, MVT::v8i1, MVT::v16i1 }) {
      setOperationAction(ISD::SETCC,            VT, Custom);
      setOperationAction(ISD::STRICT_FSETCC,    VT, Custom);
      setOperationAction(ISD::STRICT_FSETCCS,   VT, Custom);
      setOperationAction(ISD::SELECT,           VT, Custom);
      setOperationAction(ISD::TRUNCATE,         VT, Custom);

      setOperationAction(ISD::BUILD_VECTOR,     VT, Custom);
      setOperationAction(ISD::CONCAT_VECTORS,   VT, Custom);
      setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT, Custom);
      setOperationAction(ISD::INSERT_SUBVECTOR, VT, Custom);
      setOperationAction(ISD::INSERT_VECTOR_ELT, VT, Custom);
      setOperationAction(ISD::VECTOR_SHUFFLE,   VT,  Custom);
    }

    for (auto VT : { MVT::v1i1, MVT::v2i1, MVT::v4i1, MVT::v8i1 })
      setOperationAction(ISD::EXTRACT_SUBVECTOR, VT, Custom);
  }

  // This block controls legalization for 512-bit operations with 32/64 bit
  // elements. 512-bits can be disabled based on prefer-vector-width and
  // required-vector-width function attributes.
  if (!Subtarget.useSoftFloat() && Subtarget.useAVX512Regs()) {
    addRegisterClass(MVT::v16i32, &X86::VR512RegClass);
    addRegisterClass(MVT::v16f32, &X86::VR512RegClass);
    addRegisterClass(MVT::v8i64,  &X86::VR512RegClass);
    addRegisterClass(MVT::v8f64,  &X86::VR512RegClass);

    for (auto ExtType : {ISD::ZEXTLOAD, ISD::SEXTLOAD}) {
      setLoadExtAction(ExtType, MVT::v16i32, MVT::v16i8,  Legal);
      setLoadExtAction(ExtType, MVT::v16i32, MVT::v16i16, Legal);
      setLoadExtAction(ExtType, MVT::v8i64,  MVT::v8i8,   Legal);
      setLoadExtAction(ExtType, MVT::v8i64,  MVT::v8i16,  Legal);
      setLoadExtAction(ExtType, MVT::v8i64,  MVT::v8i32,  Legal);
    }

    for (MVT VT : { MVT::v16f32, MVT::v8f64 }) {
      setOperationAction(ISD::FNEG,  VT, Custom);
      setOperationAction(ISD::FABS,  VT, Custom);
      setOperationAction(ISD::FMA,   VT, Legal);
      setOperationAction(ISD::STRICT_FMA, VT, Legal);
      setOperationAction(ISD::FCOPYSIGN, VT, Custom);
    }

    for (MVT VT : { MVT::v16i1, MVT::v16i8, MVT::v16i16 }) {
      setOperationPromotedToType(ISD::FP_TO_SINT       , VT, MVT::v16i32);
      setOperationPromotedToType(ISD::FP_TO_UINT       , VT, MVT::v16i32);
      setOperationPromotedToType(ISD::STRICT_FP_TO_SINT, VT, MVT::v16i32);
      setOperationPromotedToType(ISD::STRICT_FP_TO_UINT, VT, MVT::v16i32);
    }
    setOperationAction(ISD::FP_TO_SINT,        MVT::v16i32, Legal);
    setOperationAction(ISD::FP_TO_UINT,        MVT::v16i32, Legal);
    setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::v16i32, Legal);
    setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::v16i32, Legal);
    setOperationAction(ISD::SINT_TO_FP,        MVT::v16i32, Legal);
    setOperationAction(ISD::UINT_TO_FP,        MVT::v16i32, Legal);
    setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::v16i32, Legal);
    setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v16i32, Legal);

    setOperationAction(ISD::STRICT_FADD,      MVT::v16f32, Legal);
    setOperationAction(ISD::STRICT_FADD,      MVT::v8f64,  Legal);
    setOperationAction(ISD::STRICT_FSUB,      MVT::v16f32, Legal);
    setOperationAction(ISD::STRICT_FSUB,      MVT::v8f64,  Legal);
    setOperationAction(ISD::STRICT_FMUL,      MVT::v16f32, Legal);
    setOperationAction(ISD::STRICT_FMUL,      MVT::v8f64,  Legal);
    setOperationAction(ISD::STRICT_FDIV,      MVT::v16f32, Legal);
    setOperationAction(ISD::STRICT_FDIV,      MVT::v8f64,  Legal);
    setOperationAction(ISD::STRICT_FSQRT,     MVT::v16f32, Legal);
    setOperationAction(ISD::STRICT_FSQRT,     MVT::v8f64,  Legal);
    setOperationAction(ISD::STRICT_FP_EXTEND, MVT::v8f64,  Legal);
    setOperationAction(ISD::STRICT_FP_ROUND,  MVT::v8f32,  Legal);

    setTruncStoreAction(MVT::v8i64,   MVT::v8i8,   Legal);
    setTruncStoreAction(MVT::v8i64,   MVT::v8i16,  Legal);
    setTruncStoreAction(MVT::v8i64,   MVT::v8i32,  Legal);
    setTruncStoreAction(MVT::v16i32,  MVT::v16i8,  Legal);
    setTruncStoreAction(MVT::v16i32,  MVT::v16i16, Legal);

    // With 512-bit vectors and no VLX, we prefer to widen MLOAD/MSTORE
    // to 512-bit rather than use the AVX2 instructions so that we can use
    // k-masks.
    if (!Subtarget.hasVLX()) {
      for (auto VT : {MVT::v4i32, MVT::v8i32, MVT::v2i64, MVT::v4i64,
           MVT::v4f32, MVT::v8f32, MVT::v2f64, MVT::v4f64}) {
        setOperationAction(ISD::MLOAD,  VT, Custom);
        setOperationAction(ISD::MSTORE, VT, Custom);
      }
    }

    setOperationAction(ISD::TRUNCATE,           MVT::v8i32, Custom);
    setOperationAction(ISD::TRUNCATE,           MVT::v16i16, Custom);
    setOperationAction(ISD::ZERO_EXTEND,        MVT::v16i32, Custom);
    setOperationAction(ISD::ZERO_EXTEND,        MVT::v8i64, Custom);
    setOperationAction(ISD::ANY_EXTEND,         MVT::v16i32, Custom);
    setOperationAction(ISD::ANY_EXTEND,         MVT::v8i64, Custom);
    setOperationAction(ISD::SIGN_EXTEND,        MVT::v16i32, Custom);
    setOperationAction(ISD::SIGN_EXTEND,        MVT::v8i64, Custom);

    // Need to custom widen this if we don't have AVX512BW.
    setOperationAction(ISD::ANY_EXTEND,         MVT::v8i8, Custom);
    setOperationAction(ISD::ZERO_EXTEND,        MVT::v8i8, Custom);
    setOperationAction(ISD::SIGN_EXTEND,        MVT::v8i8, Custom);

    for (auto VT : { MVT::v16f32, MVT::v8f64 }) {
      setOperationAction(ISD::FFLOOR,            VT, Legal);
      setOperationAction(ISD::STRICT_FFLOOR,     VT, Legal);
      setOperationAction(ISD::FCEIL,             VT, Legal);
      setOperationAction(ISD::STRICT_FCEIL,      VT, Legal);
      setOperationAction(ISD::FTRUNC,            VT, Legal);
      setOperationAction(ISD::STRICT_FTRUNC,     VT, Legal);
      setOperationAction(ISD::FRINT,             VT, Legal);
      setOperationAction(ISD::STRICT_FRINT,      VT, Legal);
      setOperationAction(ISD::FNEARBYINT,        VT, Legal);
      setOperationAction(ISD::STRICT_FNEARBYINT, VT, Legal);

      setOperationAction(ISD::FROUND,            VT, Custom);

      setOperationAction(ISD::SELECT,           VT, Custom);
    }

    // Without BWI we need to use custom lowering to handle MVT::v64i8 input.
    for (auto VT : {MVT::v16i32, MVT::v8i64, MVT::v64i8}) {
      setOperationAction(ISD::SIGN_EXTEND_VECTOR_INREG, VT, Custom);
      setOperationAction(ISD::ZERO_EXTEND_VECTOR_INREG, VT, Custom);
    }

    setOperationAction(ISD::CONCAT_VECTORS,     MVT::v8f64,  Custom);
    setOperationAction(ISD::CONCAT_VECTORS,     MVT::v8i64,  Custom);
    setOperationAction(ISD::CONCAT_VECTORS,     MVT::v16f32,  Custom);
    setOperationAction(ISD::CONCAT_VECTORS,     MVT::v16i32,  Custom);

    setOperationAction(ISD::MUL,                MVT::v8i64, Custom);
    setOperationAction(ISD::MUL,                MVT::v16i32, Legal);

    setOperationAction(ISD::MULHU,              MVT::v16i32,  Custom);
    setOperationAction(ISD::MULHS,              MVT::v16i32,  Custom);

    for (auto VT : { MVT::v16i32, MVT::v8i64 }) {
      setOperationAction(ISD::SMAX,             VT, Legal);
      setOperationAction(ISD::UMAX,             VT, Legal);
      setOperationAction(ISD::SMIN,             VT, Legal);
      setOperationAction(ISD::UMIN,             VT, Legal);
      setOperationAction(ISD::ABS,              VT, Legal);
      setOperationAction(ISD::SRL,              VT, Custom);
      setOperationAction(ISD::SHL,              VT, Custom);
      setOperationAction(ISD::SRA,              VT, Custom);
      setOperationAction(ISD::CTPOP,            VT, Custom);
      setOperationAction(ISD::ROTL,             VT, Custom);
      setOperationAction(ISD::ROTR,             VT, Custom);
      setOperationAction(ISD::SETCC,            VT, Custom);
      setOperationAction(ISD::STRICT_FSETCC,    VT, Custom);
      setOperationAction(ISD::STRICT_FSETCCS,   VT, Custom);
      setOperationAction(ISD::SELECT,           VT, Custom);

      // The condition codes aren't legal in SSE/AVX and under AVX512 we use
      // setcc all the way to isel and prefer SETGT in some isel patterns.
      setCondCodeAction(ISD::SETLT, VT, Custom);
      setCondCodeAction(ISD::SETLE, VT, Custom);
    }

    if (Subtarget.hasDQI()) {
      setOperationAction(ISD::SINT_TO_FP, MVT::v8i64, Legal);
      setOperationAction(ISD::UINT_TO_FP, MVT::v8i64, Legal);
      setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::v8i64, Legal);
      setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v8i64, Legal);
      setOperationAction(ISD::FP_TO_SINT, MVT::v8i64, Legal);
      setOperationAction(ISD::FP_TO_UINT, MVT::v8i64, Legal);
      setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::v8i64, Legal);
      setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::v8i64, Legal);

      setOperationAction(ISD::MUL,        MVT::v8i64, Legal);
    }

    if (Subtarget.hasCDI()) {
      // NonVLX sub-targets extend 128/256 vectors to use the 512 version.
      for (auto VT : { MVT::v16i32, MVT::v8i64} ) {
        setOperationAction(ISD::CTLZ,            VT, Legal);
      }
    } // Subtarget.hasCDI()

    if (Subtarget.hasVPOPCNTDQ()) {
      for (auto VT : { MVT::v16i32, MVT::v8i64 })
        setOperationAction(ISD::CTPOP, VT, Legal);
    }

    // Extract subvector is special because the value type
    // (result) is 256-bit but the source is 512-bit wide.
    // 128-bit was made Legal under AVX1.
    for (auto VT : { MVT::v32i8, MVT::v16i16, MVT::v8i32, MVT::v4i64,
                     MVT::v8f32, MVT::v4f64 })
      setOperationAction(ISD::EXTRACT_SUBVECTOR, VT, Legal);

    for (auto VT : { MVT::v16i32, MVT::v8i64, MVT::v16f32, MVT::v8f64 }) {
      setOperationAction(ISD::VECTOR_SHUFFLE,      VT, Custom);
      setOperationAction(ISD::INSERT_VECTOR_ELT,   VT, Custom);
      setOperationAction(ISD::BUILD_VECTOR,        VT, Custom);
      setOperationAction(ISD::VSELECT,             VT, Custom);
      setOperationAction(ISD::EXTRACT_VECTOR_ELT,  VT, Custom);
      setOperationAction(ISD::SCALAR_TO_VECTOR,    VT, Custom);
      setOperationAction(ISD::INSERT_SUBVECTOR,    VT, Legal);
      setOperationAction(ISD::MLOAD,               VT, Legal);
      setOperationAction(ISD::MSTORE,              VT, Legal);
      setOperationAction(ISD::MGATHER,             VT, Custom);
      setOperationAction(ISD::MSCATTER,            VT, Custom);
    }
    if (!Subtarget.hasBWI()) {
      // Need to custom split v32i16/v64i8 bitcasts.
      setOperationAction(ISD::BITCAST, MVT::v32i16, Custom);
      setOperationAction(ISD::BITCAST, MVT::v64i8,  Custom);

      // Better to split these into two 256-bit ops.
      setOperationAction(ISD::BITREVERSE, MVT::v8i64, Custom);
      setOperationAction(ISD::BITREVERSE, MVT::v16i32, Custom);
    }

    if (Subtarget.hasVBMI2()) {
      for (auto VT : { MVT::v16i32, MVT::v8i64 }) {
        setOperationAction(ISD::FSHL, VT, Custom);
        setOperationAction(ISD::FSHR, VT, Custom);
      }
    }
  }// has  AVX-512

  // This block controls legalization for operations that don't have
  // pre-AVX512 equivalents. Without VLX we use 512-bit operations for
  // narrower widths.
  if (!Subtarget.useSoftFloat() && Subtarget.hasAVX512()) {
    // These operations are handled on non-VLX by artificially widening in
    // isel patterns.

    setOperationAction(ISD::FP_TO_UINT, MVT::v8i32,
                       Subtarget.hasVLX() ? Legal : Custom);
    setOperationAction(ISD::FP_TO_UINT, MVT::v4i32,
                       Subtarget.hasVLX() ? Legal : Custom);
    setOperationAction(ISD::FP_TO_UINT,         MVT::v2i32, Custom);
    setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::v8i32,
                       Subtarget.hasVLX() ? Legal : Custom);
    setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::v4i32,
                       Subtarget.hasVLX() ? Legal : Custom);
    setOperationAction(ISD::STRICT_FP_TO_UINT,  MVT::v2i32, Custom);
    setOperationAction(ISD::UINT_TO_FP, MVT::v8i32,
                       Subtarget.hasVLX() ? Legal : Custom);
    setOperationAction(ISD::UINT_TO_FP, MVT::v4i32,
                       Subtarget.hasVLX() ? Legal : Custom);
    setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v8i32,
                       Subtarget.hasVLX() ? Legal : Custom);
    setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v4i32,
                       Subtarget.hasVLX() ? Legal : Custom);

    for (auto VT : { MVT::v2i64, MVT::v4i64 }) {
      setOperationAction(ISD::SMAX, VT, Legal);
      setOperationAction(ISD::UMAX, VT, Legal);
      setOperationAction(ISD::SMIN, VT, Legal);
      setOperationAction(ISD::UMIN, VT, Legal);
      setOperationAction(ISD::ABS,  VT, Legal);
    }

    for (auto VT : { MVT::v4i32, MVT::v8i32, MVT::v2i64, MVT::v4i64 }) {
      setOperationAction(ISD::ROTL,     VT, Custom);
      setOperationAction(ISD::ROTR,     VT, Custom);
    }

    // Custom legalize 2x32 to get a little better code.
    setOperationAction(ISD::MSCATTER, MVT::v2f32, Custom);
    setOperationAction(ISD::MSCATTER, MVT::v2i32, Custom);

    for (auto VT : { MVT::v4i32, MVT::v8i32, MVT::v2i64, MVT::v4i64,
                     MVT::v4f32, MVT::v8f32, MVT::v2f64, MVT::v4f64 })
      setOperationAction(ISD::MSCATTER, VT, Custom);

    if (Subtarget.hasDQI()) {
      for (auto VT : { MVT::v2i64, MVT::v4i64 }) {
        setOperationAction(ISD::SINT_TO_FP, VT,
                           Subtarget.hasVLX() ? Legal : Custom);
        setOperationAction(ISD::UINT_TO_FP, VT,
                           Subtarget.hasVLX() ? Legal : Custom);
        setOperationAction(ISD::STRICT_SINT_TO_FP, VT,
                           Subtarget.hasVLX() ? Legal : Custom);
        setOperationAction(ISD::STRICT_UINT_TO_FP, VT,
                           Subtarget.hasVLX() ? Legal : Custom);
        setOperationAction(ISD::FP_TO_SINT, VT,
                           Subtarget.hasVLX() ? Legal : Custom);
        setOperationAction(ISD::FP_TO_UINT, VT,
                           Subtarget.hasVLX() ? Legal : Custom);
        setOperationAction(ISD::STRICT_FP_TO_SINT, VT,
                           Subtarget.hasVLX() ? Legal : Custom);
        setOperationAction(ISD::STRICT_FP_TO_UINT, VT,
                           Subtarget.hasVLX() ? Legal : Custom);
        setOperationAction(ISD::MUL,               VT, Legal);
      }
    }

    if (Subtarget.hasCDI()) {
      for (auto VT : { MVT::v4i32, MVT::v8i32, MVT::v2i64, MVT::v4i64 }) {
        setOperationAction(ISD::CTLZ,            VT, Legal);
      }
    } // Subtarget.hasCDI()

    if (Subtarget.hasVPOPCNTDQ()) {
      for (auto VT : { MVT::v4i32, MVT::v8i32, MVT::v2i64, MVT::v4i64 })
        setOperationAction(ISD::CTPOP, VT, Legal);
    }
  }

  // This block control legalization of v32i1/v64i1 which are available with
  // AVX512BW. 512-bit v32i16 and v64i8 vector legalization is controlled with
  // useBWIRegs.
  if (!Subtarget.useSoftFloat() && Subtarget.hasBWI()) {
    addRegisterClass(MVT::v32i1,  &X86::VK32RegClass);
    addRegisterClass(MVT::v64i1,  &X86::VK64RegClass);

    for (auto VT : { MVT::v32i1, MVT::v64i1 }) {
      setOperationAction(ISD::ADD,                VT, Custom);
      setOperationAction(ISD::SUB,                VT, Custom);
      setOperationAction(ISD::MUL,                VT, Custom);
      setOperationAction(ISD::VSELECT,            VT, Expand);
      setOperationAction(ISD::UADDSAT,            VT, Custom);
      setOperationAction(ISD::SADDSAT,            VT, Custom);
      setOperationAction(ISD::USUBSAT,            VT, Custom);
      setOperationAction(ISD::SSUBSAT,            VT, Custom);

      setOperationAction(ISD::TRUNCATE,           VT, Custom);
      setOperationAction(ISD::SETCC,              VT, Custom);
      setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT, Custom);
      setOperationAction(ISD::INSERT_VECTOR_ELT,  VT, Custom);
      setOperationAction(ISD::SELECT,             VT, Custom);
      setOperationAction(ISD::BUILD_VECTOR,       VT, Custom);
      setOperationAction(ISD::VECTOR_SHUFFLE,     VT, Custom);
    }

    setOperationAction(ISD::CONCAT_VECTORS,     MVT::v32i1, Custom);
    setOperationAction(ISD::CONCAT_VECTORS,     MVT::v64i1, Custom);
    setOperationAction(ISD::INSERT_SUBVECTOR,   MVT::v32i1, Custom);
    setOperationAction(ISD::INSERT_SUBVECTOR,   MVT::v64i1, Custom);
    for (auto VT : { MVT::v16i1, MVT::v32i1 })
      setOperationAction(ISD::EXTRACT_SUBVECTOR, VT, Custom);

    // Extends from v32i1 masks to 256-bit vectors.
    setOperationAction(ISD::SIGN_EXTEND,        MVT::v32i8, Custom);
    setOperationAction(ISD::ZERO_EXTEND,        MVT::v32i8, Custom);
    setOperationAction(ISD::ANY_EXTEND,         MVT::v32i8, Custom);
  }

  // This block controls legalization for v32i16 and v64i8. 512-bits can be
  // disabled based on prefer-vector-width and required-vector-width function
  // attributes.
  if (!Subtarget.useSoftFloat() && Subtarget.useBWIRegs()) {
    addRegisterClass(MVT::v32i16, &X86::VR512RegClass);
    addRegisterClass(MVT::v64i8,  &X86::VR512RegClass);

    // Extends from v64i1 masks to 512-bit vectors.
    setOperationAction(ISD::SIGN_EXTEND,        MVT::v64i8, Custom);
    setOperationAction(ISD::ZERO_EXTEND,        MVT::v64i8, Custom);
    setOperationAction(ISD::ANY_EXTEND,         MVT::v64i8, Custom);

    setOperationAction(ISD::MUL,                MVT::v32i16, Legal);
    setOperationAction(ISD::MUL,                MVT::v64i8, Custom);
    setOperationAction(ISD::MULHS,              MVT::v32i16, Legal);
    setOperationAction(ISD::MULHU,              MVT::v32i16, Legal);
    setOperationAction(ISD::MULHS,              MVT::v64i8, Custom);
    setOperationAction(ISD::MULHU,              MVT::v64i8, Custom);
    setOperationAction(ISD::CONCAT_VECTORS,     MVT::v32i16, Custom);
    setOperationAction(ISD::CONCAT_VECTORS,     MVT::v64i8, Custom);
    setOperationAction(ISD::INSERT_SUBVECTOR,   MVT::v32i16, Legal);
    setOperationAction(ISD::INSERT_SUBVECTOR,   MVT::v64i8, Legal);
    setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v32i16, Custom);
    setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v64i8, Custom);
    setOperationAction(ISD::SCALAR_TO_VECTOR,   MVT::v32i16, Custom);
    setOperationAction(ISD::SCALAR_TO_VECTOR,   MVT::v64i8, Custom);
    setOperationAction(ISD::SIGN_EXTEND,        MVT::v32i16, Custom);
    setOperationAction(ISD::ZERO_EXTEND,        MVT::v32i16, Custom);
    setOperationAction(ISD::ANY_EXTEND,         MVT::v32i16, Custom);
    setOperationAction(ISD::VECTOR_SHUFFLE,     MVT::v32i16, Custom);
    setOperationAction(ISD::VECTOR_SHUFFLE,     MVT::v64i8, Custom);
    setOperationAction(ISD::INSERT_VECTOR_ELT,  MVT::v32i16, Custom);
    setOperationAction(ISD::INSERT_VECTOR_ELT,  MVT::v64i8, Custom);
    setOperationAction(ISD::TRUNCATE,           MVT::v32i8, Custom);
    setOperationAction(ISD::BITREVERSE,         MVT::v64i8, Custom);

    setOperationAction(ISD::SIGN_EXTEND_VECTOR_INREG, MVT::v32i16, Custom);
    setOperationAction(ISD::ZERO_EXTEND_VECTOR_INREG, MVT::v32i16, Custom);

    setTruncStoreAction(MVT::v32i16,  MVT::v32i8, Legal);

    for (auto VT : { MVT::v64i8, MVT::v32i16 }) {
      setOperationAction(ISD::BUILD_VECTOR, VT, Custom);
      setOperationAction(ISD::VSELECT,      VT, Custom);
      setOperationAction(ISD::ABS,          VT, Legal);
      setOperationAction(ISD::SRL,          VT, Custom);
      setOperationAction(ISD::SHL,          VT, Custom);
      setOperationAction(ISD::SRA,          VT, Custom);
      setOperationAction(ISD::MLOAD,        VT, Legal);
      setOperationAction(ISD::MSTORE,       VT, Legal);
      setOperationAction(ISD::CTPOP,        VT, Custom);
      setOperationAction(ISD::CTLZ,         VT, Custom);
      setOperationAction(ISD::SMAX,         VT, Legal);
      setOperationAction(ISD::UMAX,         VT, Legal);
      setOperationAction(ISD::SMIN,         VT, Legal);
      setOperationAction(ISD::UMIN,         VT, Legal);
      setOperationAction(ISD::SETCC,        VT, Custom);
      setOperationAction(ISD::UADDSAT,      VT, Legal);
      setOperationAction(ISD::SADDSAT,      VT, Legal);
      setOperationAction(ISD::USUBSAT,      VT, Legal);
      setOperationAction(ISD::SSUBSAT,      VT, Legal);
      setOperationAction(ISD::SELECT,       VT, Custom);

      // The condition codes aren't legal in SSE/AVX and under AVX512 we use
      // setcc all the way to isel and prefer SETGT in some isel patterns.
      setCondCodeAction(ISD::SETLT, VT, Custom);
      setCondCodeAction(ISD::SETLE, VT, Custom);
    }

    for (auto ExtType : {ISD::ZEXTLOAD, ISD::SEXTLOAD}) {
      setLoadExtAction(ExtType, MVT::v32i16, MVT::v32i8, Legal);
    }

    if (Subtarget.hasBITALG()) {
      for (auto VT : { MVT::v64i8, MVT::v32i16 })
        setOperationAction(ISD::CTPOP, VT, Legal);
    }

    if (Subtarget.hasVBMI2()) {
      setOperationAction(ISD::FSHL, MVT::v32i16, Custom);
      setOperationAction(ISD::FSHR, MVT::v32i16, Custom);
    }
  }

  if (!Subtarget.useSoftFloat() && Subtarget.hasBWI()) {
    for (auto VT : { MVT::v32i8, MVT::v16i8, MVT::v16i16, MVT::v8i16 }) {
      setOperationAction(ISD::MLOAD,  VT, Subtarget.hasVLX() ? Legal : Custom);
      setOperationAction(ISD::MSTORE, VT, Subtarget.hasVLX() ? Legal : Custom);
    }

    // These operations are handled on non-VLX by artificially widening in
    // isel patterns.
    // TODO: Custom widen in lowering on non-VLX and drop the isel patterns?

    if (Subtarget.hasBITALG()) {
      for (auto VT : { MVT::v16i8, MVT::v32i8, MVT::v8i16, MVT::v16i16 })
        setOperationAction(ISD::CTPOP, VT, Legal);
    }
  }

  if (!Subtarget.useSoftFloat() && Subtarget.hasVLX()) {
    setTruncStoreAction(MVT::v4i64, MVT::v4i8,  Legal);
    setTruncStoreAction(MVT::v4i64, MVT::v4i16, Legal);
    setTruncStoreAction(MVT::v4i64, MVT::v4i32, Legal);
    setTruncStoreAction(MVT::v8i32, MVT::v8i8,  Legal);
    setTruncStoreAction(MVT::v8i32, MVT::v8i16, Legal);

    setTruncStoreAction(MVT::v2i64, MVT::v2i8,  Legal);
    setTruncStoreAction(MVT::v2i64, MVT::v2i16, Legal);
    setTruncStoreAction(MVT::v2i64, MVT::v2i32, Legal);
    setTruncStoreAction(MVT::v4i32, MVT::v4i8,  Legal);
    setTruncStoreAction(MVT::v4i32, MVT::v4i16, Legal);

    if (Subtarget.hasDQI()) {
      // Fast v2f32 SINT_TO_FP( v2i64 ) custom conversion.
      // v2f32 UINT_TO_FP is already custom under SSE2.
      assert(isOperationCustom(ISD::UINT_TO_FP, MVT::v2f32) &&
             isOperationCustom(ISD::STRICT_UINT_TO_FP, MVT::v2f32) &&
             "Unexpected operation action!");
      // v2i64 FP_TO_S/UINT(v2f32) custom conversion.
      setOperationAction(ISD::FP_TO_SINT,        MVT::v2f32, Custom);
      setOperationAction(ISD::FP_TO_UINT,        MVT::v2f32, Custom);
      setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::v2f32, Custom);
      setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::v2f32, Custom);
    }

    if (Subtarget.hasBWI()) {
      setTruncStoreAction(MVT::v16i16,  MVT::v16i8, Legal);
      setTruncStoreAction(MVT::v8i16,   MVT::v8i8,  Legal);
    }

    if (Subtarget.hasVBMI2()) {
      // TODO: Make these legal even without VLX?
      for (auto VT : { MVT::v8i16,  MVT::v4i32, MVT::v2i64,
                       MVT::v16i16, MVT::v8i32, MVT::v4i64 }) {
        setOperationAction(ISD::FSHL, VT, Custom);
        setOperationAction(ISD::FSHR, VT, Custom);
      }
    }

    setOperationAction(ISD::TRUNCATE, MVT::v16i32, Custom);
    setOperationAction(ISD::TRUNCATE, MVT::v8i64, Custom);
    setOperationAction(ISD::TRUNCATE, MVT::v16i64, Custom);
  }

  // We want to custom lower some of our intrinsics.
  setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
  setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
  setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);
  if (!Subtarget.is64Bit()) {
    setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i64, Custom);
  }

  // Only custom-lower 64-bit SADDO and friends on 64-bit because we don't
  // handle type legalization for these operations here.
  //
  // FIXME: We really should do custom legalization for addition and
  // subtraction on x86-32 once PR3203 is fixed.  We really can't do much better
  // than generic legalization for 64-bit multiplication-with-overflow, though.
  for (auto VT : { MVT::i8, MVT::i16, MVT::i32, MVT::i64 }) {
    if (VT == MVT::i64 && !Subtarget.is64Bit())
      continue;
    // Add/Sub/Mul with overflow operations are custom lowered.
    setOperationAction(ISD::SADDO, VT, Custom);
    setOperationAction(ISD::UADDO, VT, Custom);
    setOperationAction(ISD::SSUBO, VT, Custom);
    setOperationAction(ISD::USUBO, VT, Custom);
    setOperationAction(ISD::SMULO, VT, Custom);
    setOperationAction(ISD::UMULO, VT, Custom);

    // Support carry in as value rather than glue.
    setOperationAction(ISD::ADDCARRY, VT, Custom);
    setOperationAction(ISD::SUBCARRY, VT, Custom);
    setOperationAction(ISD::SETCCCARRY, VT, Custom);
  }

  if (!Subtarget.is64Bit()) {
    // These libcalls are not available in 32-bit.
    setLibcallName(RTLIB::SHL_I128, nullptr);
    setLibcallName(RTLIB::SRL_I128, nullptr);
    setLibcallName(RTLIB::SRA_I128, nullptr);
    setLibcallName(RTLIB::MUL_I128, nullptr);
  }

  // Combine sin / cos into _sincos_stret if it is available.
  if (getLibcallName(RTLIB::SINCOS_STRET_F32) != nullptr &&
      getLibcallName(RTLIB::SINCOS_STRET_F64) != nullptr) {
    setOperationAction(ISD::FSINCOS, MVT::f64, Custom);
    setOperationAction(ISD::FSINCOS, MVT::f32, Custom);
  }

  if (Subtarget.isTargetWin64()) {
    setOperationAction(ISD::SDIV, MVT::i128, Custom);
    setOperationAction(ISD::UDIV, MVT::i128, Custom);
    setOperationAction(ISD::SREM, MVT::i128, Custom);
    setOperationAction(ISD::UREM, MVT::i128, Custom);
    setOperationAction(ISD::SDIVREM, MVT::i128, Custom);
    setOperationAction(ISD::UDIVREM, MVT::i128, Custom);
  }

  // On 32 bit MSVC, `fmodf(f32)` is not defined - only `fmod(f64)`
  // is. We should promote the value to 64-bits to solve this.
  // This is what the CRT headers do - `fmodf` is an inline header
  // function casting to f64 and calling `fmod`.
  if (Subtarget.is32Bit() &&
      (Subtarget.isTargetWindowsMSVC() || Subtarget.isTargetWindowsItanium()))
    for (ISD::NodeType Op :
         {ISD::FCEIL,  ISD::STRICT_FCEIL,
          ISD::FCOS,   ISD::STRICT_FCOS,
          ISD::FEXP,   ISD::STRICT_FEXP,
          ISD::FFLOOR, ISD::STRICT_FFLOOR,
          ISD::FREM,   ISD::STRICT_FREM,
          ISD::FLOG,   ISD::STRICT_FLOG,
          ISD::FLOG10, ISD::STRICT_FLOG10,
          ISD::FPOW,   ISD::STRICT_FPOW,
          ISD::FSIN,   ISD::STRICT_FSIN})
      if (isOperationExpand(Op, MVT::f32))
        setOperationAction(Op, MVT::f32, Promote);

  // We have target-specific dag combine patterns for the following nodes:
  setTargetDAGCombine(ISD::VECTOR_SHUFFLE);
  setTargetDAGCombine(ISD::SCALAR_TO_VECTOR);
  setTargetDAGCombine(ISD::INSERT_VECTOR_ELT);
  setTargetDAGCombine(ISD::EXTRACT_VECTOR_ELT);
  setTargetDAGCombine(ISD::CONCAT_VECTORS);
  setTargetDAGCombine(ISD::INSERT_SUBVECTOR);
  setTargetDAGCombine(ISD::EXTRACT_SUBVECTOR);
  setTargetDAGCombine(ISD::BITCAST);
  setTargetDAGCombine(ISD::VSELECT);
  setTargetDAGCombine(ISD::SELECT);
  setTargetDAGCombine(ISD::SHL);
  setTargetDAGCombine(ISD::SRA);
  setTargetDAGCombine(ISD::SRL);
  setTargetDAGCombine(ISD::OR);
  setTargetDAGCombine(ISD::AND);
  setTargetDAGCombine(ISD::ADD);
  setTargetDAGCombine(ISD::FADD);
  setTargetDAGCombine(ISD::FSUB);
  setTargetDAGCombine(ISD::FNEG);
  setTargetDAGCombine(ISD::FMA);
  setTargetDAGCombine(ISD::STRICT_FMA);
  setTargetDAGCombine(ISD::FMINNUM);
  setTargetDAGCombine(ISD::FMAXNUM);
  setTargetDAGCombine(ISD::SUB);
  setTargetDAGCombine(ISD::LOAD);
  setTargetDAGCombine(ISD::MLOAD);
  setTargetDAGCombine(ISD::STORE);
  setTargetDAGCombine(ISD::MSTORE);
  setTargetDAGCombine(ISD::TRUNCATE);
  setTargetDAGCombine(ISD::ZERO_EXTEND);
  setTargetDAGCombine(ISD::ANY_EXTEND);
  setTargetDAGCombine(ISD::SIGN_EXTEND);
  setTargetDAGCombine(ISD::SIGN_EXTEND_INREG);
  setTargetDAGCombine(ISD::ANY_EXTEND_VECTOR_INREG);
  setTargetDAGCombine(ISD::SIGN_EXTEND_VECTOR_INREG);
  setTargetDAGCombine(ISD::ZERO_EXTEND_VECTOR_INREG);
  setTargetDAGCombine(ISD::SINT_TO_FP);
  setTargetDAGCombine(ISD::UINT_TO_FP);
  setTargetDAGCombine(ISD::STRICT_SINT_TO_FP);
  setTargetDAGCombine(ISD::STRICT_UINT_TO_FP);
  setTargetDAGCombine(ISD::SETCC);
  setTargetDAGCombine(ISD::MUL);
  setTargetDAGCombine(ISD::XOR);
  setTargetDAGCombine(ISD::MSCATTER);
  setTargetDAGCombine(ISD::MGATHER);
  setTargetDAGCombine(ISD::FP16_TO_FP);
  setTargetDAGCombine(ISD::FP_EXTEND);
  setTargetDAGCombine(ISD::STRICT_FP_EXTEND);
  setTargetDAGCombine(ISD::FP_ROUND);

  computeRegisterProperties(Subtarget.getRegisterInfo());

  MaxStoresPerMemset = 16; // For @llvm.memset -> sequence of stores
  MaxStoresPerMemsetOptSize = 8;
  MaxStoresPerMemcpy = 8; // For @llvm.memcpy -> sequence of stores
  MaxStoresPerMemcpyOptSize = 4;
  MaxStoresPerMemmove = 8; // For @llvm.memmove -> sequence of stores
  MaxStoresPerMemmoveOptSize = 4;

  // TODO: These control memcmp expansion in CGP and could be raised higher, but
  // that needs to benchmarked and balanced with the potential use of vector
  // load/store types (PR33329, PR33914).
  MaxLoadsPerMemcmp = 2;
  MaxLoadsPerMemcmpOptSize = 2;

  // Set loop alignment to 2^ExperimentalPrefLoopAlignment bytes (default: 2^4).
  setPrefLoopAlignment(Align(1ULL << ExperimentalPrefLoopAlignment));

  // An out-of-order CPU can speculatively execute past a predictable branch,
  // but a conditional move could be stalled by an expensive earlier operation.
  PredictableSelectIsExpensive = Subtarget.getSchedModel().isOutOfOrder();
  EnableExtLdPromotion = true;
  setPrefFunctionAlignment(Align(16));

  verifyIntrinsicTables();

  // Default to having -disable-strictnode-mutation on
  IsStrictFPEnabled = true;
}

// This has so far only been implemented for 64-bit MachO.
bool X86TargetLowering::useLoadStackGuardNode() const {
  return Subtarget.isTargetMachO() && Subtarget.is64Bit();
}

bool X86TargetLowering::useStackGuardXorFP() const {
  // Currently only MSVC CRTs XOR the frame pointer into the stack guard value.
  return Subtarget.getTargetTriple().isOSMSVCRT() && !Subtarget.isTargetMachO();
}

SDValue X86TargetLowering::emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val,
                                               const SDLoc &DL) const {
  EVT PtrTy = getPointerTy(DAG.getDataLayout());
  unsigned XorOp = Subtarget.is64Bit() ? X86::XOR64_FP : X86::XOR32_FP;
  MachineSDNode *Node = DAG.getMachineNode(XorOp, DL, PtrTy, Val);
  return SDValue(Node, 0);
}

TargetLoweringBase::LegalizeTypeAction
X86TargetLowering::getPreferredVectorAction(MVT VT) const {
  if (VT == MVT::v32i1 && Subtarget.hasAVX512() && !Subtarget.hasBWI())
    return TypeSplitVector;

  if (VT.getVectorNumElements() != 1 &&
      VT.getVectorElementType() != MVT::i1)
    return TypeWidenVector;

  return TargetLoweringBase::getPreferredVectorAction(VT);
}

static std::pair<MVT, unsigned>
handleMaskRegisterForCallingConv(unsigned NumElts, CallingConv::ID CC,
                                 const X86Subtarget &Subtarget) {
  // v2i1/v4i1/v8i1/v16i1 all pass in xmm registers unless the calling
  // convention is one that uses k registers.
  if (NumElts == 2)
    return {MVT::v2i64, 1};
  if (NumElts == 4)
    return {MVT::v4i32, 1};
  if (NumElts == 8 && CC != CallingConv::X86_RegCall &&
      CC != CallingConv::Intel_OCL_BI)
    return {MVT::v8i16, 1};
  if (NumElts == 16 && CC != CallingConv::X86_RegCall &&
      CC != CallingConv::Intel_OCL_BI)
    return {MVT::v16i8, 1};
  // v32i1 passes in ymm unless we have BWI and the calling convention is
  // regcall.
  if (NumElts == 32 && (!Subtarget.hasBWI() || CC != CallingConv::X86_RegCall))
    return {MVT::v32i8, 1};
  // Split v64i1 vectors if we don't have v64i8 available.
  if (NumElts == 64 && Subtarget.hasBWI() && CC != CallingConv::X86_RegCall) {
    if (Subtarget.useAVX512Regs())
      return {MVT::v64i8, 1};
    return {MVT::v32i8, 2};
  }

  // Break wide or odd vXi1 vectors into scalars to match avx2 behavior.
  if (!isPowerOf2_32(NumElts) || (NumElts == 64 && !Subtarget.hasBWI()) ||
      NumElts > 64)
    return {MVT::i8, NumElts};

  return {MVT::INVALID_SIMPLE_VALUE_TYPE, 0};
}

MVT X86TargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context,
                                                     CallingConv::ID CC,
                                                     EVT VT) const {
  if (VT.isVector() && VT.getVectorElementType() == MVT::i1 &&
      Subtarget.hasAVX512()) {
    unsigned NumElts = VT.getVectorNumElements();

    MVT RegisterVT;
    unsigned NumRegisters;
    std::tie(RegisterVT, NumRegisters) =
        handleMaskRegisterForCallingConv(NumElts, CC, Subtarget);
    if (RegisterVT != MVT::INVALID_SIMPLE_VALUE_TYPE)
      return RegisterVT;
  }

  // FIXME: Should we just make these types legal and custom split operations?
  if ((VT == MVT::v32i16 || VT == MVT::v64i8) && !EnableOldKNLABI &&
      Subtarget.useAVX512Regs() && !Subtarget.hasBWI())
    return MVT::v16i32;

  return TargetLowering::getRegisterTypeForCallingConv(Context, CC, VT);
}

unsigned X86TargetLowering::getNumRegistersForCallingConv(LLVMContext &Context,
                                                          CallingConv::ID CC,
                                                          EVT VT) const {
  if (VT.isVector() && VT.getVectorElementType() == MVT::i1 &&
      Subtarget.hasAVX512()) {
    unsigned NumElts = VT.getVectorNumElements();

    MVT RegisterVT;
    unsigned NumRegisters;
    std::tie(RegisterVT, NumRegisters) =
        handleMaskRegisterForCallingConv(NumElts, CC, Subtarget);
    if (RegisterVT != MVT::INVALID_SIMPLE_VALUE_TYPE)
      return NumRegisters;
  }

  // FIXME: Should we just make these types legal and custom split operations?
  if ((VT == MVT::v32i16 || VT == MVT::v64i8) && !EnableOldKNLABI &&
      Subtarget.useAVX512Regs() && !Subtarget.hasBWI())
    return 1;

  return TargetLowering::getNumRegistersForCallingConv(Context, CC, VT);
}

unsigned X86TargetLowering::getVectorTypeBreakdownForCallingConv(
    LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT,
    unsigned &NumIntermediates, MVT &RegisterVT) const {
  // Break wide or odd vXi1 vectors into scalars to match avx2 behavior.
  if (VT.isVector() && VT.getVectorElementType() == MVT::i1 &&
      Subtarget.hasAVX512() &&
      (!isPowerOf2_32(VT.getVectorNumElements()) ||
       (VT.getVectorNumElements() == 64 && !Subtarget.hasBWI()) ||
       VT.getVectorNumElements() > 64)) {
    RegisterVT = MVT::i8;
    IntermediateVT = MVT::i1;
    NumIntermediates = VT.getVectorNumElements();
    return NumIntermediates;
  }

  // Split v64i1 vectors if we don't have v64i8 available.
  if (VT == MVT::v64i1 && Subtarget.hasBWI() && !Subtarget.useAVX512Regs() &&
      CC != CallingConv::X86_RegCall) {
    RegisterVT = MVT::v32i8;
    IntermediateVT = MVT::v32i1;
    NumIntermediates = 2;
    return 2;
  }

  return TargetLowering::getVectorTypeBreakdownForCallingConv(Context, CC, VT, IntermediateVT,
                                              NumIntermediates, RegisterVT);
}

EVT X86TargetLowering::getSetCCResultType(const DataLayout &DL,
                                          LLVMContext& Context,
                                          EVT VT) const {
  if (!VT.isVector())
    return MVT::i8;

  if (Subtarget.hasAVX512()) {
    const unsigned NumElts = VT.getVectorNumElements();

    // Figure out what this type will be legalized to.
    EVT LegalVT = VT;
    while (getTypeAction(Context, LegalVT) != TypeLegal)
      LegalVT = getTypeToTransformTo(Context, LegalVT);

    // If we got a 512-bit vector then we'll definitely have a vXi1 compare.
    if (LegalVT.getSimpleVT().is512BitVector())
      return EVT::getVectorVT(Context, MVT::i1, NumElts);

    if (LegalVT.getSimpleVT().isVector() && Subtarget.hasVLX()) {
      // If we legalized to less than a 512-bit vector, then we will use a vXi1
      // compare for vXi32/vXi64 for sure. If we have BWI we will also support
      // vXi16/vXi8.
      MVT EltVT = LegalVT.getSimpleVT().getVectorElementType();
      if (Subtarget.hasBWI() || EltVT.getSizeInBits() >= 32)
        return EVT::getVectorVT(Context, MVT::i1, NumElts);
    }
  }

  return VT.changeVectorElementTypeToInteger();
}

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

/// Return the desired alignment for ByVal aggregate
/// function arguments in the caller parameter area. For X86, aggregates
/// that contain SSE vectors are placed at 16-byte boundaries while the rest
/// are at 4-byte boundaries.
unsigned X86TargetLowering::getByValTypeAlignment(Type *Ty,
                                                  const DataLayout &DL) const {
  if (Subtarget.is64Bit()) {
    // Max of 8 and alignment of type.
    unsigned TyAlign = DL.getABITypeAlignment(Ty);
    if (TyAlign > 8)
      return TyAlign;
    return 8;
  }

  unsigned Align = 4;
  if (Subtarget.hasSSE1())
    getMaxByValAlign(Ty, Align);
  return Align;
}

/// It returns EVT::Other if the type should be determined using generic
/// target-independent logic.
/// For vector ops we check that the overall size isn't larger than our
/// preferred vector width.
EVT X86TargetLowering::getOptimalMemOpType(
    const MemOp &Op, const AttributeList &FuncAttributes) const {
  if (!FuncAttributes.hasFnAttribute(Attribute::NoImplicitFloat)) {
    if (Op.size() >= 16 &&
        (!Subtarget.isUnalignedMem16Slow() || Op.isAligned(Align(16)))) {
      // FIXME: Check if unaligned 64-byte accesses are slow.
      if (Op.size() >= 64 && Subtarget.hasAVX512() &&
          (Subtarget.getPreferVectorWidth() >= 512)) {
        return Subtarget.hasBWI() ? MVT::v64i8 : MVT::v16i32;
      }
      // FIXME: Check if unaligned 32-byte accesses are slow.
      if (Op.size() >= 32 && Subtarget.hasAVX() &&
          (Subtarget.getPreferVectorWidth() >= 256)) {
        // Although this isn't a well-supported type for AVX1, we'll let
        // legalization and shuffle lowering produce the optimal codegen. If we
        // choose an optimal type with a vector element larger than a byte,
        // getMemsetStores() may create an intermediate splat (using an integer
        // multiply) before we splat as a vector.
        return MVT::v32i8;
      }
      if (Subtarget.hasSSE2() && (Subtarget.getPreferVectorWidth() >= 128))
        return MVT::v16i8;
      // TODO: Can SSE1 handle a byte vector?
      // If we have SSE1 registers we should be able to use them.
      if (Subtarget.hasSSE1() && (Subtarget.is64Bit() || Subtarget.hasX87()) &&
          (Subtarget.getPreferVectorWidth() >= 128))
        return MVT::v4f32;
    } else if (((Op.isMemcpy() && !Op.isMemcpyStrSrc()) || Op.isZeroMemset()) &&
               Op.size() >= 8 && !Subtarget.is64Bit() && Subtarget.hasSSE2()) {
      // Do not use f64 to lower memcpy if source is string constant. It's
      // better to use i32 to avoid the loads.
      // Also, do not use f64 to lower memset unless this is a memset of zeros.
      // The gymnastics of splatting a byte value into an XMM register and then
      // only using 8-byte stores (because this is a CPU with slow unaligned
      // 16-byte accesses) makes that a loser.
      return MVT::f64;
    }
  }
  // This is a compromise. If we reach here, unaligned accesses may be slow on
  // this target. However, creating smaller, aligned accesses could be even
  // slower and would certainly be a lot more code.
  if (Subtarget.is64Bit() && Op.size() >= 8)
    return MVT::i64;
  return MVT::i32;
}

bool X86TargetLowering::isSafeMemOpType(MVT VT) const {
  if (VT == MVT::f32)
    return X86ScalarSSEf32;
  else if (VT == MVT::f64)
    return X86ScalarSSEf64;
  return true;
}

bool X86TargetLowering::allowsMisalignedMemoryAccesses(
    EVT VT, unsigned, unsigned Align, MachineMemOperand::Flags Flags,
    bool *Fast) const {
  if (Fast) {
    switch (VT.getSizeInBits()) {
    default:
      // 8-byte and under are always assumed to be fast.
      *Fast = true;
      break;
    case 128:
      *Fast = !Subtarget.isUnalignedMem16Slow();
      break;
    case 256:
      *Fast = !Subtarget.isUnalignedMem32Slow();
      break;
    // TODO: What about AVX-512 (512-bit) accesses?
    }
  }
  // NonTemporal vector memory ops must be aligned.
  if (!!(Flags & MachineMemOperand::MONonTemporal) && VT.isVector()) {
    // NT loads can only be vector aligned, so if its less aligned than the
    // minimum vector size (which we can split the vector down to), we might as
    // well use a regular unaligned vector load.
    // We don't have any NT loads pre-SSE41.
    if (!!(Flags & MachineMemOperand::MOLoad))
      return (Align < 16 || !Subtarget.hasSSE41());
    return false;
  }
  // Misaligned accesses of any size are always allowed.
  return true;
}

/// Return the entry encoding for a jump table in the
/// current function.  The returned value is a member of the
/// MachineJumpTableInfo::JTEntryKind enum.
unsigned X86TargetLowering::getJumpTableEncoding() const {
  // In GOT pic mode, each entry in the jump table is emitted as a @GOTOFF
  // symbol.
  if (isPositionIndependent() && Subtarget.isPICStyleGOT())
    return MachineJumpTableInfo::EK_Custom32;

  // Otherwise, use the normal jump table encoding heuristics.
  return TargetLowering::getJumpTableEncoding();
}

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

void X86TargetLowering::markLibCallAttributes(MachineFunction *MF, unsigned CC,
                                              ArgListTy &Args) const {

  // Only relabel X86-32 for C / Stdcall CCs.
  if (Subtarget.is64Bit())
    return;
  if (CC != CallingConv::C && CC != CallingConv::X86_StdCall)
    return;
  unsigned ParamRegs = 0;
  if (auto *M = MF->getFunction().getParent())
    ParamRegs = M->getNumberRegisterParameters();

  // Mark the first N int arguments as having reg
  for (unsigned Idx = 0; Idx < Args.size(); Idx++) {
    Type *T = Args[Idx].Ty;
    if (T->isIntOrPtrTy())
      if (MF->getDataLayout().getTypeAllocSize(T) <= 8) {
        unsigned numRegs = 1;
        if (MF->getDataLayout().getTypeAllocSize(T) > 4)
          numRegs = 2;
        if (ParamRegs < numRegs)
          return;
        ParamRegs -= numRegs;
        Args[Idx].IsInReg = true;
      }
  }
}

const MCExpr *
X86TargetLowering::LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI,
                                             const MachineBasicBlock *MBB,
                                             unsigned uid,MCContext &Ctx) const{
  assert(isPositionIndependent() && Subtarget.isPICStyleGOT());
  // In 32-bit ELF systems, our jump table entries are formed with @GOTOFF
  // entries.
  return MCSymbolRefExpr::create(MBB->getSymbol(),
                                 MCSymbolRefExpr::VK_GOTOFF, Ctx);
}

/// Returns relocation base for the given PIC jumptable.
SDValue X86TargetLowering::getPICJumpTableRelocBase(SDValue Table,
                                                    SelectionDAG &DAG) const {
  if (!Subtarget.is64Bit())
    // This doesn't have SDLoc associated with it, but is not really the
    // same as a Register.
    return DAG.getNode(X86ISD::GlobalBaseReg, SDLoc(),
                       getPointerTy(DAG.getDataLayout()));
  return Table;
}

/// This returns the relocation base for the given PIC jumptable,
/// the same as getPICJumpTableRelocBase, but as an MCExpr.
const MCExpr *X86TargetLowering::
getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI,
                             MCContext &Ctx) const {
  // X86-64 uses RIP relative addressing based on the jump table label.
  if (Subtarget.isPICStyleRIPRel())
    return TargetLowering::getPICJumpTableRelocBaseExpr(MF, JTI, Ctx);

  // Otherwise, the reference is relative to the PIC base.
  return MCSymbolRefExpr::create(MF->getPICBaseSymbol(), Ctx);
}

std::pair<const TargetRegisterClass *, uint8_t>
X86TargetLowering::findRepresentativeClass(const TargetRegisterInfo *TRI,
                                           MVT VT) const {
  const TargetRegisterClass *RRC = nullptr;
  uint8_t Cost = 1;
  switch (VT.SimpleTy) {
  default:
    return TargetLowering::findRepresentativeClass(TRI, VT);
  case MVT::i8: case MVT::i16: case MVT::i32: case MVT::i64:
    RRC = Subtarget.is64Bit() ? &X86::GR64RegClass : &X86::GR32RegClass;
    break;
  case MVT::x86mmx:
    RRC = &X86::VR64RegClass;
    break;
  case MVT::f32: case MVT::f64:
  case MVT::v16i8: case MVT::v8i16: case MVT::v4i32: case MVT::v2i64:
  case MVT::v4f32: case MVT::v2f64:
  case MVT::v32i8: case MVT::v16i16: case MVT::v8i32: case MVT::v4i64:
  case MVT::v8f32: case MVT::v4f64:
  case MVT::v64i8: case MVT::v32i16: case MVT::v16i32: case MVT::v8i64:
  case MVT::v16f32: case MVT::v8f64:
    RRC = &X86::VR128XRegClass;
    break;
  }
  return std::make_pair(RRC, Cost);
}

unsigned X86TargetLowering::getAddressSpace() const {
  if (Subtarget.is64Bit())
    return (getTargetMachine().getCodeModel() == CodeModel::Kernel) ? 256 : 257;
  return 256;
}

static bool hasStackGuardSlotTLS(const Triple &TargetTriple) {
  return TargetTriple.isOSGlibc() || TargetTriple.isOSFuchsia() ||
         (TargetTriple.isAndroid() && !TargetTriple.isAndroidVersionLT(17));
}

static Constant* SegmentOffset(IRBuilder<> &IRB,
                               unsigned Offset, unsigned AddressSpace) {
  return ConstantExpr::getIntToPtr(
      ConstantInt::get(Type::getInt32Ty(IRB.getContext()), Offset),
      Type::getInt8PtrTy(IRB.getContext())->getPointerTo(AddressSpace));
}

Value *X86TargetLowering::getIRStackGuard(IRBuilder<> &IRB) const {
  // glibc, bionic, and Fuchsia have a special slot for the stack guard in
  // tcbhead_t; use it instead of the usual global variable (see
  // sysdeps/{i386,x86_64}/nptl/tls.h)
  if (hasStackGuardSlotTLS(Subtarget.getTargetTriple())) {
    if (Subtarget.isTargetFuchsia()) {
      // <zircon/tls.h> defines ZX_TLS_STACK_GUARD_OFFSET with this value.
      return SegmentOffset(IRB, 0x10, getAddressSpace());
    } else {
      // %fs:0x28, unless we're using a Kernel code model, in which case
      // it's %gs:0x28.  gs:0x14 on i386.
      unsigned Offset = (Subtarget.is64Bit()) ? 0x28 : 0x14;
      return SegmentOffset(IRB, Offset, getAddressSpace());
    }
  }

  return TargetLowering::getIRStackGuard(IRB);
}

void X86TargetLowering::insertSSPDeclarations(Module &M) const {
  // MSVC CRT provides functionalities for stack protection.
  if (Subtarget.getTargetTriple().isWindowsMSVCEnvironment() ||
      Subtarget.getTargetTriple().isWindowsItaniumEnvironment()) {
    // MSVC CRT has a global variable holding security cookie.
    M.getOrInsertGlobal("__security_cookie",
                        Type::getInt8PtrTy(M.getContext()));

    // MSVC CRT has a function to validate security cookie.
    FunctionCallee SecurityCheckCookie = M.getOrInsertFunction(
        "__security_check_cookie", Type::getVoidTy(M.getContext()),
        Type::getInt8PtrTy(M.getContext()));
    if (Function *F = dyn_cast<Function>(SecurityCheckCookie.getCallee())) {
      F->setCallingConv(CallingConv::X86_FastCall);
      F->addAttribute(1, Attribute::AttrKind::InReg);
    }
    return;
  }
  // glibc, bionic, and Fuchsia have a special slot for the stack guard.
  if (hasStackGuardSlotTLS(Subtarget.getTargetTriple()))
    return;
  TargetLowering::insertSSPDeclarations(M);
}

Value *X86TargetLowering::getSDagStackGuard(const Module &M) const {
  // MSVC CRT has a global variable holding security cookie.
  if (Subtarget.getTargetTriple().isWindowsMSVCEnvironment() ||
      Subtarget.getTargetTriple().isWindowsItaniumEnvironment()) {
    return M.getGlobalVariable("__security_cookie");
  }
  return TargetLowering::getSDagStackGuard(M);
}

Function *X86TargetLowering::getSSPStackGuardCheck(const Module &M) const {
  // MSVC CRT has a function to validate security cookie.
  if (Subtarget.getTargetTriple().isWindowsMSVCEnvironment() ||
      Subtarget.getTargetTriple().isWindowsItaniumEnvironment()) {
    return M.getFunction("__security_check_cookie");
  }
  return TargetLowering::getSSPStackGuardCheck(M);
}

Value *X86TargetLowering::getSafeStackPointerLocation(IRBuilder<> &IRB) const {
  if (Subtarget.getTargetTriple().isOSContiki())
    return getDefaultSafeStackPointerLocation(IRB, false);

  // Android provides a fixed TLS slot for the SafeStack pointer. See the
  // definition of TLS_SLOT_SAFESTACK in
  // https://android.googlesource.com/platform/bionic/+/master/libc/private/bionic_tls.h
  if (Subtarget.isTargetAndroid()) {
    // %fs:0x48, unless we're using a Kernel code model, in which case it's %gs:
    // %gs:0x24 on i386
    unsigned Offset = (Subtarget.is64Bit()) ? 0x48 : 0x24;
    return SegmentOffset(IRB, Offset, getAddressSpace());
  }

  // Fuchsia is similar.
  if (Subtarget.isTargetFuchsia()) {
    // <zircon/tls.h> defines ZX_TLS_UNSAFE_SP_OFFSET with this value.
    return SegmentOffset(IRB, 0x18, getAddressSpace());
  }

  return TargetLowering::getSafeStackPointerLocation(IRB);
}

bool X86TargetLowering::isNoopAddrSpaceCast(unsigned SrcAS,
                                            unsigned DestAS) const {
  assert(SrcAS != DestAS && "Expected different address spaces!");

  const TargetMachine &TM = getTargetMachine();
  if (TM.getPointerSize(SrcAS) != TM.getPointerSize(DestAS))
    return false;

  return SrcAS < 256 && DestAS < 256;
}

//===----------------------------------------------------------------------===//
//               Return Value Calling Convention Implementation
//===----------------------------------------------------------------------===//

bool X86TargetLowering::CanLowerReturn(
    CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg,
    const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {
  SmallVector<CCValAssign, 16> RVLocs;
  CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
  return CCInfo.CheckReturn(Outs, RetCC_X86);
}

const MCPhysReg *X86TargetLowering::getScratchRegisters(CallingConv::ID) const {
  static const MCPhysReg ScratchRegs[] = { X86::R11, 0 };
  return ScratchRegs;
}

/// Lowers masks values (v*i1) to the local register values
/// \returns DAG node after lowering to register type
static SDValue lowerMasksToReg(const SDValue &ValArg, const EVT &ValLoc,
                               const SDLoc &Dl, SelectionDAG &DAG) {
  EVT ValVT = ValArg.getValueType();

  if (ValVT == MVT::v1i1)
    return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, Dl, ValLoc, ValArg,
                       DAG.getIntPtrConstant(0, Dl));

  if ((ValVT == MVT::v8i1 && (ValLoc == MVT::i8 || ValLoc == MVT::i32)) ||
      (ValVT == MVT::v16i1 && (ValLoc == MVT::i16 || ValLoc == MVT::i32))) {
    // Two stage lowering might be required
    // bitcast:   v8i1 -> i8 / v16i1 -> i16
    // anyextend: i8   -> i32 / i16   -> i32
    EVT TempValLoc = ValVT == MVT::v8i1 ? MVT::i8 : MVT::i16;
    SDValue ValToCopy = DAG.getBitcast(TempValLoc, ValArg);
    if (ValLoc == MVT::i32)
      ValToCopy = DAG.getNode(ISD::ANY_EXTEND, Dl, ValLoc, ValToCopy);
    return ValToCopy;
  }

  if ((ValVT == MVT::v32i1 && ValLoc == MVT::i32) ||
      (ValVT == MVT::v64i1 && ValLoc == MVT::i64)) {
    // One stage lowering is required
    // bitcast:   v32i1 -> i32 / v64i1 -> i64
    return DAG.getBitcast(ValLoc, ValArg);
  }

  return DAG.getNode(ISD::ANY_EXTEND, Dl, ValLoc, ValArg);
}

/// Breaks v64i1 value into two registers and adds the new node to the DAG
static void Passv64i1ArgInRegs(
    const SDLoc &Dl, SelectionDAG &DAG, SDValue &Arg,
    SmallVectorImpl<std::pair<unsigned, SDValue>> &RegsToPass, CCValAssign &VA,
    CCValAssign &NextVA, const X86Subtarget &Subtarget) {
  assert(Subtarget.hasBWI() && "Expected AVX512BW target!");
  assert(Subtarget.is32Bit() && "Expecting 32 bit target");
  assert(Arg.getValueType() == MVT::i64 && "Expecting 64 bit value");
  assert(VA.isRegLoc() && NextVA.isRegLoc() &&
         "The value should reside in two registers");

  // Before splitting the value we cast it to i64
  Arg = DAG.getBitcast(MVT::i64, Arg);

  // Splitting the value into two i32 types
  SDValue Lo, Hi;
  Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, Dl, MVT::i32, Arg,
                   DAG.getConstant(0, Dl, MVT::i32));
  Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, Dl, MVT::i32, Arg,
                   DAG.getConstant(1, Dl, MVT::i32));

  // Attach the two i32 types into corresponding registers
  RegsToPass.push_back(std::make_pair(VA.getLocReg(), Lo));
  RegsToPass.push_back(std::make_pair(NextVA.getLocReg(), Hi));
}

SDValue
X86TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
                               bool isVarArg,
                               const SmallVectorImpl<ISD::OutputArg> &Outs,
                               const SmallVectorImpl<SDValue> &OutVals,
                               const SDLoc &dl, SelectionDAG &DAG) const {
  MachineFunction &MF = DAG.getMachineFunction();
  X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();

  // In some cases we need to disable registers from the default CSR list.
  // For example, when they are used for argument passing.
  bool ShouldDisableCalleeSavedRegister =
      CallConv == CallingConv::X86_RegCall ||
      MF.getFunction().hasFnAttribute("no_caller_saved_registers");

  if (CallConv == CallingConv::X86_INTR && !Outs.empty())
    report_fatal_error("X86 interrupts may not return any value");

  SmallVector<CCValAssign, 16> RVLocs;
  CCState CCInfo(CallConv, isVarArg, MF, RVLocs, *DAG.getContext());
  CCInfo.AnalyzeReturn(Outs, RetCC_X86);

  SmallVector<std::pair<unsigned, SDValue>, 4> RetVals;
  for (unsigned I = 0, OutsIndex = 0, E = RVLocs.size(); I != E;
       ++I, ++OutsIndex) {
    CCValAssign &VA = RVLocs[I];
    assert(VA.isRegLoc() && "Can only return in registers!");

    // Add the register to the CalleeSaveDisableRegs list.
    if (ShouldDisableCalleeSavedRegister)
      MF.getRegInfo().disableCalleeSavedRegister(VA.getLocReg());

    SDValue ValToCopy = OutVals[OutsIndex];
    EVT ValVT = ValToCopy.getValueType();

    // Promote values to the appropriate types.
    if (VA.getLocInfo() == CCValAssign::SExt)
      ValToCopy = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), ValToCopy);
    else if (VA.getLocInfo() == CCValAssign::ZExt)
      ValToCopy = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), ValToCopy);
    else if (VA.getLocInfo() == CCValAssign::AExt) {
      if (ValVT.isVector() && ValVT.getVectorElementType() == MVT::i1)
        ValToCopy = lowerMasksToReg(ValToCopy, VA.getLocVT(), dl, DAG);
      else
        ValToCopy = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), ValToCopy);
    }
    else if (VA.getLocInfo() == CCValAssign::BCvt)
      ValToCopy = DAG.getBitcast(VA.getLocVT(), ValToCopy);

    assert(VA.getLocInfo() != CCValAssign::FPExt &&
           "Unexpected FP-extend for return value.");

    // Report an error if we have attempted to return a value via an XMM
    // register and SSE was disabled.
    if (!Subtarget.hasSSE1() && X86::FR32XRegClass.contains(VA.getLocReg())) {
      errorUnsupported(DAG, dl, "SSE register return with SSE disabled");
      VA.convertToReg(X86::FP0); // Set reg to FP0, avoid hitting asserts.
    } else if (!Subtarget.hasSSE2() &&
               X86::FR64XRegClass.contains(VA.getLocReg()) &&
               ValVT == MVT::f64) {
      // When returning a double via an XMM register, report an error if SSE2 is
      // not enabled.
      errorUnsupported(DAG, dl, "SSE2 register return with SSE2 disabled");
      VA.convertToReg(X86::FP0); // Set reg to FP0, avoid hitting asserts.
    }

    // Returns in ST0/ST1 are handled specially: these are pushed as operands to
    // the RET instruction and handled by the FP Stackifier.
    if (VA.getLocReg() == X86::FP0 ||
        VA.getLocReg() == X86::FP1) {
      // If this is a copy from an xmm register to ST(0), use an FPExtend to
      // change the value to the FP stack register class.
      if (isScalarFPTypeInSSEReg(VA.getValVT()))
        ValToCopy = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f80, ValToCopy);
      RetVals.push_back(std::make_pair(VA.getLocReg(), ValToCopy));
      // Don't emit a copytoreg.
      continue;
    }

    // 64-bit vector (MMX) values are returned in XMM0 / XMM1 except for v1i64
    // which is returned in RAX / RDX.
    if (Subtarget.is64Bit()) {
      if (ValVT == MVT::x86mmx) {
        if (VA.getLocReg() == X86::XMM0 || VA.getLocReg() == X86::XMM1) {
          ValToCopy = DAG.getBitcast(MVT::i64, ValToCopy);
          ValToCopy = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2i64,
                                  ValToCopy);
          // If we don't have SSE2 available, convert to v4f32 so the generated
          // register is legal.
          if (!Subtarget.hasSSE2())
            ValToCopy = DAG.getBitcast(MVT::v4f32, ValToCopy);
        }
      }
    }

    if (VA.needsCustom()) {
      assert(VA.getValVT() == MVT::v64i1 &&
             "Currently the only custom case is when we split v64i1 to 2 regs");

      Passv64i1ArgInRegs(dl, DAG, ValToCopy, RetVals, VA, RVLocs[++I],
                         Subtarget);

      // Add the second register to the CalleeSaveDisableRegs list.
      if (ShouldDisableCalleeSavedRegister)
        MF.getRegInfo().disableCalleeSavedRegister(RVLocs[I].getLocReg());
    } else {
      RetVals.push_back(std::make_pair(VA.getLocReg(), ValToCopy));
    }
  }

  SDValue Flag;
  SmallVector<SDValue, 6> RetOps;
  RetOps.push_back(Chain); // Operand #0 = Chain (updated below)
  // Operand #1 = Bytes To Pop
  RetOps.push_back(DAG.getTargetConstant(FuncInfo->getBytesToPopOnReturn(), dl,
                   MVT::i32));

  // Copy the result values into the output registers.
  for (auto &RetVal : RetVals) {
    if (RetVal.first == X86::FP0 || RetVal.first == X86::FP1) {
      RetOps.push_back(RetVal.second);
      continue; // Don't emit a copytoreg.
    }

    Chain = DAG.getCopyToReg(Chain, dl, RetVal.first, RetVal.second, Flag);
    Flag = Chain.getValue(1);
    RetOps.push_back(
        DAG.getRegister(RetVal.first, RetVal.second.getValueType()));
  }

  // Swift calling convention does not require we copy the sret argument
  // into %rax/%eax for the return, and SRetReturnReg is not set for Swift.

  // All x86 ABIs require that for returning structs by value we copy
  // the sret argument into %rax/%eax (depending on ABI) for the return.
  // We saved the argument into a virtual register in the entry block,
  // so now we copy the value out and into %rax/%eax.
  //
  // Checking Function.hasStructRetAttr() here is insufficient because the IR
  // may not have an explicit sret argument. If FuncInfo.CanLowerReturn is
  // false, then an sret argument may be implicitly inserted in the SelDAG. In
  // either case FuncInfo->setSRetReturnReg() will have been called.
  if (unsigned SRetReg = FuncInfo->getSRetReturnReg()) {
    // When we have both sret and another return value, we should use the
    // original Chain stored in RetOps[0], instead of the current Chain updated
    // in the above loop. If we only have sret, RetOps[0] equals to Chain.

    // For the case of sret and another return value, we have
    //   Chain_0 at the function entry
    //   Chain_1 = getCopyToReg(Chain_0) in the above loop
    // If we use Chain_1 in getCopyFromReg, we will have
    //   Val = getCopyFromReg(Chain_1)
    //   Chain_2 = getCopyToReg(Chain_1, Val) from below

    // getCopyToReg(Chain_0) will be glued together with
    // getCopyToReg(Chain_1, Val) into Unit A, getCopyFromReg(Chain_1) will be
    // in Unit B, and we will have cyclic dependency between Unit A and Unit B:
    //   Data dependency from Unit B to Unit A due to usage of Val in
    //     getCopyToReg(Chain_1, Val)
    //   Chain dependency from Unit A to Unit B

    // So here, we use RetOps[0] (i.e Chain_0) for getCopyFromReg.
    SDValue Val = DAG.getCopyFromReg(RetOps[0], dl, SRetReg,
                                     getPointerTy(MF.getDataLayout()));

    unsigned RetValReg
        = (Subtarget.is64Bit() && !Subtarget.isTarget64BitILP32()) ?
          X86::RAX : X86::EAX;
    Chain = DAG.getCopyToReg(Chain, dl, RetValReg, Val, Flag);
    Flag = Chain.getValue(1);

    // RAX/EAX now acts like a return value.
    RetOps.push_back(
        DAG.getRegister(RetValReg, getPointerTy(DAG.getDataLayout())));

    // Add the returned register to the CalleeSaveDisableRegs list.
    if (ShouldDisableCalleeSavedRegister)
      MF.getRegInfo().disableCalleeSavedRegister(RetValReg);
  }

  const X86RegisterInfo *TRI = Subtarget.getRegisterInfo();
  const MCPhysReg *I =
      TRI->getCalleeSavedRegsViaCopy(&DAG.getMachineFunction());
  if (I) {
    for (; *I; ++I) {
      if (X86::GR64RegClass.contains(*I))
        RetOps.push_back(DAG.getRegister(*I, MVT::i64));
      else
        llvm_unreachable("Unexpected register class in CSRsViaCopy!");
    }
  }

  RetOps[0] = Chain;  // Update chain.

  // Add the flag if we have it.
  if (Flag.getNode())
    RetOps.push_back(Flag);

  X86ISD::NodeType opcode = X86ISD::RET_FLAG;
  if (CallConv == CallingConv::X86_INTR)
    opcode = X86ISD::IRET;
  return DAG.getNode(opcode, dl, MVT::Other, RetOps);
}

bool X86TargetLowering::isUsedByReturnOnly(SDNode *N, SDValue &Chain) const {
  if (N->getNumValues() != 1 || !N->hasNUsesOfValue(1, 0))
    return false;

  SDValue TCChain = Chain;
  SDNode *Copy = *N->use_begin();
  if (Copy->getOpcode() == ISD::CopyToReg) {
    // If the copy has a glue operand, we conservatively assume it isn't safe to
    // perform a tail call.
    if (Copy->getOperand(Copy->getNumOperands()-1).getValueType() == MVT::Glue)
      return false;
    TCChain = Copy->getOperand(0);
  } else if (Copy->getOpcode() != ISD::FP_EXTEND)
    return false;

  bool HasRet = false;
  for (SDNode::use_iterator UI = Copy->use_begin(), UE = Copy->use_end();
       UI != UE; ++UI) {
    if (UI->getOpcode() != X86ISD::RET_FLAG)
      return false;
    // If we are returning more than one value, we can definitely
    // not make a tail call see PR19530
    if (UI->getNumOperands() > 4)
      return false;
    if (UI->getNumOperands() == 4 &&
        UI->getOperand(UI->getNumOperands()-1).getValueType() != MVT::Glue)
      return false;
    HasRet = true;
  }

  if (!HasRet)
    return false;

  Chain = TCChain;
  return true;
}

EVT X86TargetLowering::getTypeForExtReturn(LLVMContext &Context, EVT VT,
                                           ISD::NodeType ExtendKind) const {
  MVT ReturnMVT = MVT::i32;

  bool Darwin = Subtarget.getTargetTriple().isOSDarwin();
  if (VT == MVT::i1 || (!Darwin && (VT == MVT::i8 || VT == MVT::i16))) {
    // The ABI does not require i1, i8 or i16 to be extended.
    //
    // On Darwin, there is code in the wild relying on Clang's old behaviour of
    // always extending i8/i16 return values, so keep doing that for now.
    // (PR26665).
    ReturnMVT = MVT::i8;
  }

  EVT MinVT = getRegisterType(Context, ReturnMVT);
  return VT.bitsLT(MinVT) ? MinVT : VT;
}

/// Reads two 32 bit registers and creates a 64 bit mask value.
/// \param VA The current 32 bit value that need to be assigned.
/// \param NextVA The next 32 bit value that need to be assigned.
/// \param Root The parent DAG node.
/// \param [in,out] InFlag Represents SDvalue in the parent DAG node for
///                        glue purposes. In the case the DAG is already using
///                        physical register instead of virtual, we should glue
///                        our new SDValue to InFlag SDvalue.
/// \return a new SDvalue of size 64bit.
static SDValue getv64i1Argument(CCValAssign &VA, CCValAssign &NextVA,
                                SDValue &Root, SelectionDAG &DAG,
                                const SDLoc &Dl, const X86Subtarget &Subtarget,
                                SDValue *InFlag = nullptr) {
  assert((Subtarget.hasBWI()) && "Expected AVX512BW target!");
  assert(Subtarget.is32Bit() && "Expecting 32 bit target");
  assert(VA.getValVT() == MVT::v64i1 &&
         "Expecting first location of 64 bit width type");
  assert(NextVA.getValVT() == VA.getValVT() &&
         "The locations should have the same type");
  assert(VA.isRegLoc() && NextVA.isRegLoc() &&
         "The values should reside in two registers");

  SDValue Lo, Hi;
  SDValue ArgValueLo, ArgValueHi;

  MachineFunction &MF = DAG.getMachineFunction();
  const TargetRegisterClass *RC = &X86::GR32RegClass;

  // Read a 32 bit value from the registers.
  if (nullptr == InFlag) {
    // When no physical register is present,
    // create an intermediate virtual register.
    unsigned Reg = MF.addLiveIn(VA.getLocReg(), RC);
    ArgValueLo = DAG.getCopyFromReg(Root, Dl, Reg, MVT::i32);
    Reg = MF.addLiveIn(NextVA.getLocReg(), RC);
    ArgValueHi = DAG.getCopyFromReg(Root, Dl, Reg, MVT::i32);
  } else {
    // When a physical register is available read the value from it and glue
    // the reads together.
    ArgValueLo =
      DAG.getCopyFromReg(Root, Dl, VA.getLocReg(), MVT::i32, *InFlag);
    *InFlag = ArgValueLo.getValue(2);
    ArgValueHi =
      DAG.getCopyFromReg(Root, Dl, NextVA.getLocReg(), MVT::i32, *InFlag);
    *InFlag = ArgValueHi.getValue(2);
  }

  // Convert the i32 type into v32i1 type.
  Lo = DAG.getBitcast(MVT::v32i1, ArgValueLo);

  // Convert the i32 type into v32i1 type.
  Hi = DAG.getBitcast(MVT::v32i1, ArgValueHi);

  // Concatenate the two values together.
  return DAG.getNode(ISD::CONCAT_VECTORS, Dl, MVT::v64i1, Lo, Hi);
}

/// The function will lower a register of various sizes (8/16/32/64)
/// to a mask value of the expected size (v8i1/v16i1/v32i1/v64i1)
/// \returns a DAG node contains the operand after lowering to mask type.
static SDValue lowerRegToMasks(const SDValue &ValArg, const EVT &ValVT,
                               const EVT &ValLoc, const SDLoc &Dl,
                               SelectionDAG &DAG) {
  SDValue ValReturned = ValArg;

  if (ValVT == MVT::v1i1)
    return DAG.getNode(ISD::SCALAR_TO_VECTOR, Dl, MVT::v1i1, ValReturned);

  if (ValVT == MVT::v64i1) {
    // In 32 bit machine, this case is handled by getv64i1Argument
    assert(ValLoc == MVT::i64 && "Expecting only i64 locations");
    // In 64 bit machine, There is no need to truncate the value only bitcast
  } else {
    MVT maskLen;
    switch (ValVT.getSimpleVT().SimpleTy) {
    case MVT::v8i1:
      maskLen = MVT::i8;
      break;
    case MVT::v16i1:
      maskLen = MVT::i16;
      break;
    case MVT::v32i1:
      maskLen = MVT::i32;
      break;
    default:
      llvm_unreachable("Expecting a vector of i1 types");
    }

    ValReturned = DAG.getNode(ISD::TRUNCATE, Dl, maskLen, ValReturned);
  }
  return DAG.getBitcast(ValVT, ValReturned);
}

/// Lower the result values of a call into the
/// appropriate copies out of appropriate physical registers.
///
SDValue X86TargetLowering::LowerCallResult(
    SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool isVarArg,
    const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
    SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
    uint32_t *RegMask) const {

  const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
  // Assign locations to each value returned by this call.
  SmallVector<CCValAssign, 16> RVLocs;
  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
                 *DAG.getContext());
  CCInfo.AnalyzeCallResult(Ins, RetCC_X86);

  // Copy all of the result registers out of their specified physreg.
  for (unsigned I = 0, InsIndex = 0, E = RVLocs.size(); I != E;
       ++I, ++InsIndex) {
    CCValAssign &VA = RVLocs[I];
    EVT CopyVT = VA.getLocVT();

    // In some calling conventions we need to remove the used registers
    // from the register mask.
    if (RegMask) {
      for (MCSubRegIterator SubRegs(VA.getLocReg(), TRI, /*IncludeSelf=*/true);
           SubRegs.isValid(); ++SubRegs)
        RegMask[*SubRegs / 32] &= ~(1u << (*SubRegs % 32));
    }

    // Report an error if there was an attempt to return FP values via XMM
    // registers.
    if (!Subtarget.hasSSE1() && X86::FR32XRegClass.contains(VA.getLocReg())) {
      errorUnsupported(DAG, dl, "SSE register return with SSE disabled");
      if (VA.getLocReg() == X86::XMM1)
        VA.convertToReg(X86::FP1); // Set reg to FP1, avoid hitting asserts.
      else
        VA.convertToReg(X86::FP0); // Set reg to FP0, avoid hitting asserts.
    } else if (!Subtarget.hasSSE2() &&
               X86::FR64XRegClass.contains(VA.getLocReg()) &&
               CopyVT == MVT::f64) {
      errorUnsupported(DAG, dl, "SSE2 register return with SSE2 disabled");
      if (VA.getLocReg() == X86::XMM1)
        VA.convertToReg(X86::FP1); // Set reg to FP1, avoid hitting asserts.
      else
        VA.convertToReg(X86::FP0); // Set reg to FP0, avoid hitting asserts.
    }

    // If we prefer to use the value in xmm registers, copy it out as f80 and
    // use a truncate to move it from fp stack reg to xmm reg.
    bool RoundAfterCopy = false;
    if ((VA.getLocReg() == X86::FP0 || VA.getLocReg() == X86::FP1) &&
        isScalarFPTypeInSSEReg(VA.getValVT())) {
      if (!Subtarget.hasX87())
        report_fatal_error("X87 register return with X87 disabled");
      CopyVT = MVT::f80;
      RoundAfterCopy = (CopyVT != VA.getLocVT());
    }

    SDValue Val;
    if (VA.needsCustom()) {
      assert(VA.getValVT() == MVT::v64i1 &&
             "Currently the only custom case is when we split v64i1 to 2 regs");
      Val =
          getv64i1Argument(VA, RVLocs[++I], Chain, DAG, dl, Subtarget, &InFlag);
    } else {
      Chain = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), CopyVT, InFlag)
                  .getValue(1);
      Val = Chain.getValue(0);
      InFlag = Chain.getValue(2);
    }

    if (RoundAfterCopy)
      Val = DAG.getNode(ISD::FP_ROUND, dl, VA.getValVT(), Val,
                        // This truncation won't change the value.
                        DAG.getIntPtrConstant(1, dl));

    if (VA.isExtInLoc() && (VA.getValVT().getScalarType() == MVT::i1)) {
      if (VA.getValVT().isVector() &&
          ((VA.getLocVT() == MVT::i64) || (VA.getLocVT() == MVT::i32) ||
           (VA.getLocVT() == MVT::i16) || (VA.getLocVT() == MVT::i8))) {
        // promoting a mask type (v*i1) into a register of type i64/i32/i16/i8
        Val = lowerRegToMasks(Val, VA.getValVT(), VA.getLocVT(), dl, DAG);
      } else
        Val = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), Val);
    }

    if (VA.getLocInfo() == CCValAssign::BCvt)
      Val = DAG.getBitcast(VA.getValVT(), Val);

    InVals.push_back(Val);
  }

  return Chain;
}

//===----------------------------------------------------------------------===//
//                C & StdCall & Fast Calling Convention implementation
//===----------------------------------------------------------------------===//
//  StdCall calling convention seems to be standard for many Windows' API
//  routines and around. It differs from C calling convention just a little:
//  callee should clean up the stack, not caller. Symbols should be also
//  decorated in some fancy way :) It doesn't support any vector arguments.
//  For info on fast calling convention see Fast Calling Convention (tail call)
//  implementation LowerX86_32FastCCCallTo.

/// CallIsStructReturn - Determines whether a call uses struct return
/// semantics.
enum StructReturnType {
  NotStructReturn,
  RegStructReturn,
  StackStructReturn
};
static StructReturnType
callIsStructReturn(ArrayRef<ISD::OutputArg> Outs, bool IsMCU) {
  if (Outs.empty())
    return NotStructReturn;

  const ISD::ArgFlagsTy &Flags = Outs[0].Flags;
  if (!Flags.isSRet())
    return NotStructReturn;
  if (Flags.isInReg() || IsMCU)
    return RegStructReturn;
  return StackStructReturn;
}

/// Determines whether a function uses struct return semantics.
static StructReturnType
argsAreStructReturn(ArrayRef<ISD::InputArg> Ins, bool IsMCU) {
  if (Ins.empty())
    return NotStructReturn;

  const ISD::ArgFlagsTy &Flags = Ins[0].Flags;
  if (!Flags.isSRet())
    return NotStructReturn;
  if (Flags.isInReg() || IsMCU)
    return RegStructReturn;
  return StackStructReturn;
}

/// Make a copy of an aggregate at address specified by "Src" to address
/// "Dst" with size and alignment information specified by the specific
/// parameter attribute. The copy will be passed as a byval function parameter.
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(),
      /*isVolatile*/ false, /*AlwaysInline=*/true,
      /*isTailCall*/ false, MachinePointerInfo(), MachinePointerInfo());
}

/// Return true if the calling convention is one that we can guarantee TCO for.
static bool canGuaranteeTCO(CallingConv::ID CC) {
  return (CC == CallingConv::Fast || CC == CallingConv::GHC ||
          CC == CallingConv::X86_RegCall || CC == CallingConv::HiPE ||
          CC == CallingConv::HHVM || CC == CallingConv::Tail);
}

/// Return true if we might ever do TCO for calls with this calling convention.
static bool mayTailCallThisCC(CallingConv::ID CC) {
  switch (CC) {
  // C calling conventions:
  case CallingConv::C:
  case CallingConv::Win64:
  case CallingConv::X86_64_SysV:
  // Callee pop conventions:
  case CallingConv::X86_ThisCall:
  case CallingConv::X86_StdCall:
  case CallingConv::X86_VectorCall:
  case CallingConv::X86_FastCall:
  // Swift:
  case CallingConv::Swift:
    return true;
  default:
    return canGuaranteeTCO(CC);
  }
}

/// Return true if the function is being made into a tailcall target by
/// changing its ABI.
static bool shouldGuaranteeTCO(CallingConv::ID CC, bool GuaranteedTailCallOpt) {
  return (GuaranteedTailCallOpt && canGuaranteeTCO(CC)) || CC == CallingConv::Tail;
}

bool X86TargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const {
  if (!CI->isTailCall())
    return false;

  ImmutableCallSite CS(CI);
  CallingConv::ID CalleeCC = CS.getCallingConv();
  if (!mayTailCallThisCC(CalleeCC))
    return false;

  return true;
}

SDValue
X86TargetLowering::LowerMemArgument(SDValue Chain, CallingConv::ID CallConv,
                                    const SmallVectorImpl<ISD::InputArg> &Ins,
                                    const SDLoc &dl, SelectionDAG &DAG,
                                    const CCValAssign &VA,
                                    MachineFrameInfo &MFI, unsigned i) const {
  // Create the nodes corresponding to a load from this parameter slot.
  ISD::ArgFlagsTy Flags = Ins[i].Flags;
  bool AlwaysUseMutable = shouldGuaranteeTCO(
      CallConv, DAG.getTarget().Options.GuaranteedTailCallOpt);
  bool isImmutable = !AlwaysUseMutable && !Flags.isByVal();
  EVT ValVT;
  MVT PtrVT = getPointerTy(DAG.getDataLayout());

  // If value is passed by pointer we have address passed instead of the value
  // itself. No need to extend if the mask value and location share the same
  // absolute size.
  bool ExtendedInMem =
      VA.isExtInLoc() && VA.getValVT().getScalarType() == MVT::i1 &&
      VA.getValVT().getSizeInBits() != VA.getLocVT().getSizeInBits();

  if (VA.getLocInfo() == CCValAssign::Indirect || ExtendedInMem)
    ValVT = VA.getLocVT();
  else
    ValVT = VA.getValVT();

  // FIXME: For now, all byval parameter objects are marked mutable. This can be
  // changed with more analysis.
  // In case of tail call optimization mark all arguments mutable. Since they
  // could be overwritten by lowering of arguments in case of a tail call.
  if (Flags.isByVal()) {
    unsigned Bytes = Flags.getByValSize();
    if (Bytes == 0) Bytes = 1; // Don't create zero-sized stack objects.

    // FIXME: For now, all byval parameter objects are marked as aliasing. This
    // can be improved with deeper analysis.
    int FI = MFI.CreateFixedObject(Bytes, VA.getLocMemOffset(), isImmutable,
                                   /*isAliased=*/true);
    return DAG.getFrameIndex(FI, PtrVT);
  }

  // This is an argument in memory. We might be able to perform copy elision.
  // If the argument is passed directly in memory without any extension, then we
  // can perform copy elision. Large vector types, for example, may be passed
  // indirectly by pointer.
  if (Flags.isCopyElisionCandidate() &&
      VA.getLocInfo() != CCValAssign::Indirect && !ExtendedInMem) {
    EVT ArgVT = Ins[i].ArgVT;
    SDValue PartAddr;
    if (Ins[i].PartOffset == 0) {
      // If this is a one-part value or the first part of a multi-part value,
      // create a stack object for the entire argument value type and return a
      // load from our portion of it. This assumes that if the first part of an
      // argument is in memory, the rest will also be in memory.
      int FI = MFI.CreateFixedObject(ArgVT.getStoreSize(), VA.getLocMemOffset(),
                                     /*IsImmutable=*/false);
      PartAddr = DAG.getFrameIndex(FI, PtrVT);
      return DAG.getLoad(
          ValVT, dl, Chain, PartAddr,
          MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI));
    } else {
      // This is not the first piece of an argument in memory. See if there is
      // already a fixed stack object including this offset. If so, assume it
      // was created by the PartOffset == 0 branch above and create a load from
      // the appropriate offset into it.
      int64_t PartBegin = VA.getLocMemOffset();
      int64_t PartEnd = PartBegin + ValVT.getSizeInBits() / 8;
      int FI = MFI.getObjectIndexBegin();
      for (; MFI.isFixedObjectIndex(FI); ++FI) {
        int64_t ObjBegin = MFI.getObjectOffset(FI);
        int64_t ObjEnd = ObjBegin + MFI.getObjectSize(FI);
        if (ObjBegin <= PartBegin && PartEnd <= ObjEnd)
          break;
      }
      if (MFI.isFixedObjectIndex(FI)) {
        SDValue Addr =
            DAG.getNode(ISD::ADD, dl, PtrVT, DAG.getFrameIndex(FI, PtrVT),
                        DAG.getIntPtrConstant(Ins[i].PartOffset, dl));
        return DAG.getLoad(
            ValVT, dl, Chain, Addr,
            MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI,
                                              Ins[i].PartOffset));
      }
    }
  }

  int FI = MFI.CreateFixedObject(ValVT.getSizeInBits() / 8,
                                 VA.getLocMemOffset(), isImmutable);

  // Set SExt or ZExt flag.
  if (VA.getLocInfo() == CCValAssign::ZExt) {
    MFI.setObjectZExt(FI, true);
  } else if (VA.getLocInfo() == CCValAssign::SExt) {
    MFI.setObjectSExt(FI, true);
  }

  SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
  SDValue Val = DAG.getLoad(
      ValVT, dl, Chain, FIN,
      MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI));
  return ExtendedInMem
             ? (VA.getValVT().isVector()
                    ? DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VA.getValVT(), Val)
                    : DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), Val))
             : Val;
}

// FIXME: Get this from tablegen.
static ArrayRef<MCPhysReg> get64BitArgumentGPRs(CallingConv::ID CallConv,
                                                const X86Subtarget &Subtarget) {
  assert(Subtarget.is64Bit());

  if (Subtarget.isCallingConvWin64(CallConv)) {
    static const MCPhysReg GPR64ArgRegsWin64[] = {
      X86::RCX, X86::RDX, X86::R8,  X86::R9
    };
    return makeArrayRef(std::begin(GPR64ArgRegsWin64), std::end(GPR64ArgRegsWin64));
  }

  static const MCPhysReg GPR64ArgRegs64Bit[] = {
    X86::RDI, X86::RSI, X86::RDX, X86::RCX, X86::R8, X86::R9
  };
  return makeArrayRef(std::begin(GPR64ArgRegs64Bit), std::end(GPR64ArgRegs64Bit));
}

// FIXME: Get this from tablegen.
static ArrayRef<MCPhysReg> get64BitArgumentXMMs(MachineFunction &MF,
                                                CallingConv::ID CallConv,
                                                const X86Subtarget &Subtarget) {
  assert(Subtarget.is64Bit());
  if (Subtarget.isCallingConvWin64(CallConv)) {
    // The XMM registers which might contain var arg parameters are shadowed
    // in their paired GPR.  So we only need to save the GPR to their home
    // slots.
    // TODO: __vectorcall will change this.
    return None;
  }

  const Function &F = MF.getFunction();
  bool NoImplicitFloatOps = F.hasFnAttribute(Attribute::NoImplicitFloat);
  bool isSoftFloat = Subtarget.useSoftFloat();
  assert(!(isSoftFloat && NoImplicitFloatOps) &&
         "SSE register cannot be used when SSE is disabled!");
  if (isSoftFloat || NoImplicitFloatOps || !Subtarget.hasSSE1())
    // Kernel mode asks for SSE to be disabled, so there are no XMM argument
    // registers.
    return None;

  static const MCPhysReg XMMArgRegs64Bit[] = {
    X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
    X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
  };
  return makeArrayRef(std::begin(XMMArgRegs64Bit), std::end(XMMArgRegs64Bit));
}

#ifndef NDEBUG
static bool isSortedByValueNo(ArrayRef<CCValAssign> ArgLocs) {
  return std::is_sorted(ArgLocs.begin(), ArgLocs.end(),
                        [](const CCValAssign &A, const CCValAssign &B) -> bool {
                          return A.getValNo() < B.getValNo();
                        });
}
#endif

SDValue X86TargetLowering::LowerFormalArguments(
    SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
    const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
    SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
  MachineFunction &MF = DAG.getMachineFunction();
  X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();
  const TargetFrameLowering &TFI = *Subtarget.getFrameLowering();

  const Function &F = MF.getFunction();
  if (F.hasExternalLinkage() && Subtarget.isTargetCygMing() &&
      F.getName() == "main")
    FuncInfo->setForceFramePointer(true);

  MachineFrameInfo &MFI = MF.getFrameInfo();
  bool Is64Bit = Subtarget.is64Bit();
  bool IsWin64 = Subtarget.isCallingConvWin64(CallConv);

  assert(
      !(isVarArg && canGuaranteeTCO(CallConv)) &&
      "Var args not supported with calling conv' regcall, fastcc, ghc or hipe");

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

  // Allocate shadow area for Win64.
  if (IsWin64)
    CCInfo.AllocateStack(32, 8);

  CCInfo.AnalyzeArguments(Ins, CC_X86);

  // In vectorcall calling convention a second pass is required for the HVA
  // types.
  if (CallingConv::X86_VectorCall == CallConv) {
    CCInfo.AnalyzeArgumentsSecondPass(Ins, CC_X86);
  }

  // The next loop assumes that the locations are in the same order of the
  // input arguments.
  assert(isSortedByValueNo(ArgLocs) &&
         "Argument Location list must be sorted before lowering");

  SDValue ArgValue;
  for (unsigned I = 0, InsIndex = 0, E = ArgLocs.size(); I != E;
       ++I, ++InsIndex) {
    assert(InsIndex < Ins.size() && "Invalid Ins index");
    CCValAssign &VA = ArgLocs[I];

    if (VA.isRegLoc()) {
      EVT RegVT = VA.getLocVT();
      if (VA.needsCustom()) {
        assert(
            VA.getValVT() == MVT::v64i1 &&
            "Currently the only custom case is when we split v64i1 to 2 regs");

        // v64i1 values, in regcall calling convention, that are
        // compiled to 32 bit arch, are split up into two registers.
        ArgValue =
            getv64i1Argument(VA, ArgLocs[++I], Chain, DAG, dl, Subtarget);
      } else {
        const TargetRegisterClass *RC;
        if (RegVT == MVT::i8)
          RC = &X86::GR8RegClass;
        else if (RegVT == MVT::i16)
          RC = &X86::GR16RegClass;
        else if (RegVT == MVT::i32)
          RC = &X86::GR32RegClass;
        else if (Is64Bit && RegVT == MVT::i64)
          RC = &X86::GR64RegClass;
        else if (RegVT == MVT::f32)
          RC = Subtarget.hasAVX512() ? &X86::FR32XRegClass : &X86::FR32RegClass;
        else if (RegVT == MVT::f64)
          RC = Subtarget.hasAVX512() ? &X86::FR64XRegClass : &X86::FR64RegClass;
        else if (RegVT == MVT::f80)
          RC = &X86::RFP80RegClass;
        else if (RegVT == MVT::f128)
          RC = &X86::VR128RegClass;
        else if (RegVT.is512BitVector())
          RC = &X86::VR512RegClass;
        else if (RegVT.is256BitVector())
          RC = Subtarget.hasVLX() ? &X86::VR256XRegClass : &X86::VR256RegClass;
        else if (RegVT.is128BitVector())
          RC = Subtarget.hasVLX() ? &X86::VR128XRegClass : &X86::VR128RegClass;
        else if (RegVT == MVT::x86mmx)
          RC = &X86::VR64RegClass;
        else if (RegVT == MVT::v1i1)
          RC = &X86::VK1RegClass;
        else if (RegVT == MVT::v8i1)
          RC = &X86::VK8RegClass;
        else if (RegVT == MVT::v16i1)
          RC = &X86::VK16RegClass;
        else if (RegVT == MVT::v32i1)
          RC = &X86::VK32RegClass;
        else if (RegVT == MVT::v64i1)
          RC = &X86::VK64RegClass;
        else
          llvm_unreachable("Unknown argument type!");

        unsigned Reg = MF.addLiveIn(VA.getLocReg(), RC);
        ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT);
      }

      // If this is an 8 or 16-bit value, it is really passed promoted to 32
      // bits.  Insert an assert[sz]ext to capture this, then truncate to the
      // right size.
      if (VA.getLocInfo() == CCValAssign::SExt)
        ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue,
                               DAG.getValueType(VA.getValVT()));
      else if (VA.getLocInfo() == CCValAssign::ZExt)
        ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue,
                               DAG.getValueType(VA.getValVT()));
      else if (VA.getLocInfo() == CCValAssign::BCvt)
        ArgValue = DAG.getBitcast(VA.getValVT(), ArgValue);

      if (VA.isExtInLoc()) {
        // Handle MMX values passed in XMM regs.
        if (RegVT.isVector() && VA.getValVT().getScalarType() != MVT::i1)
          ArgValue = DAG.getNode(X86ISD::MOVDQ2Q, dl, VA.getValVT(), ArgValue);
        else if (VA.getValVT().isVector() &&
                 VA.getValVT().getScalarType() == MVT::i1 &&
                 ((VA.getLocVT() == MVT::i64) || (VA.getLocVT() == MVT::i32) ||
                  (VA.getLocVT() == MVT::i16) || (VA.getLocVT() == MVT::i8))) {
          // Promoting a mask type (v*i1) into a register of type i64/i32/i16/i8
          ArgValue = lowerRegToMasks(ArgValue, VA.getValVT(), RegVT, dl, DAG);
        } else
          ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
      }
    } else {
      assert(VA.isMemLoc());
      ArgValue =
          LowerMemArgument(Chain, CallConv, Ins, dl, DAG, VA, MFI, InsIndex);
    }

    // If value is passed via pointer - do a load.
    if (VA.getLocInfo() == CCValAssign::Indirect && !Ins[I].Flags.isByVal())
      ArgValue =
          DAG.getLoad(VA.getValVT(), dl, Chain, ArgValue, MachinePointerInfo());

    InVals.push_back(ArgValue);
  }

  for (unsigned I = 0, E = Ins.size(); I != E; ++I) {
    // Swift calling convention does not require we copy the sret argument
    // into %rax/%eax for the return. We don't set SRetReturnReg for Swift.
    if (CallConv == CallingConv::Swift)
      continue;

    // All x86 ABIs require that for returning structs by value we copy the
    // sret argument into %rax/%eax (depending on ABI) for the return. Save
    // the argument into a virtual register so that we can access it from the
    // return points.
    if (Ins[I].Flags.isSRet()) {
      unsigned Reg = FuncInfo->getSRetReturnReg();
      if (!Reg) {
        MVT PtrTy = getPointerTy(DAG.getDataLayout());
        Reg = MF.getRegInfo().createVirtualRegister(getRegClassFor(PtrTy));
        FuncInfo->setSRetReturnReg(Reg);
      }
      SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, InVals[I]);
      Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain);
      break;
    }
  }

  unsigned StackSize = CCInfo.getNextStackOffset();
  // Align stack specially for tail calls.
  if (shouldGuaranteeTCO(CallConv,
                         MF.getTarget().Options.GuaranteedTailCallOpt))
    StackSize = GetAlignedArgumentStackSize(StackSize, DAG);

  // 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. We
  // can skip this if there are no va_start calls.
  if (MFI.hasVAStart() &&
      (Is64Bit || (CallConv != CallingConv::X86_FastCall &&
                   CallConv != CallingConv::X86_ThisCall))) {
    FuncInfo->setVarArgsFrameIndex(MFI.CreateFixedObject(1, StackSize, true));
  }

  // Figure out if XMM registers are in use.
  assert(!(Subtarget.useSoftFloat() &&
           F.hasFnAttribute(Attribute::NoImplicitFloat)) &&
         "SSE register cannot be used when SSE is disabled!");

  // 64-bit calling conventions support varargs and register parameters, so we
  // have to do extra work to spill them in the prologue.
  if (Is64Bit && isVarArg && MFI.hasVAStart()) {
    // Find the first unallocated argument registers.
    ArrayRef<MCPhysReg> ArgGPRs = get64BitArgumentGPRs(CallConv, Subtarget);
    ArrayRef<MCPhysReg> ArgXMMs = get64BitArgumentXMMs(MF, CallConv, Subtarget);
    unsigned NumIntRegs = CCInfo.getFirstUnallocated(ArgGPRs);
    unsigned NumXMMRegs = CCInfo.getFirstUnallocated(ArgXMMs);
    assert(!(NumXMMRegs && !Subtarget.hasSSE1()) &&
           "SSE register cannot be used when SSE is disabled!");

    // Gather all the live in physical registers.
    SmallVector<SDValue, 6> LiveGPRs;
    SmallVector<SDValue, 8> LiveXMMRegs;
    SDValue ALVal;
    for (MCPhysReg Reg : ArgGPRs.slice(NumIntRegs)) {
      unsigned GPR = MF.addLiveIn(Reg, &X86::GR64RegClass);
      LiveGPRs.push_back(
          DAG.getCopyFromReg(Chain, dl, GPR, MVT::i64));
    }
    if (!ArgXMMs.empty()) {
      unsigned AL = MF.addLiveIn(X86::AL, &X86::GR8RegClass);
      ALVal = DAG.getCopyFromReg(Chain, dl, AL, MVT::i8);
      for (MCPhysReg Reg : ArgXMMs.slice(NumXMMRegs)) {
        unsigned XMMReg = MF.addLiveIn(Reg, &X86::VR128RegClass);
        LiveXMMRegs.push_back(
            DAG.getCopyFromReg(Chain, dl, XMMReg, MVT::v4f32));
      }
    }

    if (IsWin64) {
      // Get to the caller-allocated home save location.  Add 8 to account
      // for the return address.
      int HomeOffset = TFI.getOffsetOfLocalArea() + 8;
      FuncInfo->setRegSaveFrameIndex(
          MFI.CreateFixedObject(1, NumIntRegs * 8 + HomeOffset, false));
      // Fixup to set vararg frame on shadow area (4 x i64).
      if (NumIntRegs < 4)
        FuncInfo->setVarArgsFrameIndex(FuncInfo->getRegSaveFrameIndex());
    } else {
      // For X86-64, if there are vararg parameters that are passed via
      // registers, then we must store them to their spots on the stack so
      // they may be loaded by dereferencing the result of va_next.
      FuncInfo->setVarArgsGPOffset(NumIntRegs * 8);
      FuncInfo->setVarArgsFPOffset(ArgGPRs.size() * 8 + NumXMMRegs * 16);
      FuncInfo->setRegSaveFrameIndex(MFI.CreateStackObject(
          ArgGPRs.size() * 8 + ArgXMMs.size() * 16, 16, false));
    }

    // Store the integer parameter registers.
    SmallVector<SDValue, 8> MemOps;
    SDValue RSFIN = DAG.getFrameIndex(FuncInfo->getRegSaveFrameIndex(),
                                      getPointerTy(DAG.getDataLayout()));
    unsigned Offset = FuncInfo->getVarArgsGPOffset();
    for (SDValue Val : LiveGPRs) {
      SDValue FIN = DAG.getNode(ISD::ADD, dl, getPointerTy(DAG.getDataLayout()),
                                RSFIN, DAG.getIntPtrConstant(Offset, dl));
      SDValue Store =
          DAG.getStore(Val.getValue(1), dl, Val, FIN,
                       MachinePointerInfo::getFixedStack(
                           DAG.getMachineFunction(),
                           FuncInfo->getRegSaveFrameIndex(), Offset));
      MemOps.push_back(Store);
      Offset += 8;
    }

    if (!ArgXMMs.empty() && NumXMMRegs != ArgXMMs.size()) {
      // Now store the XMM (fp + vector) parameter registers.
      SmallVector<SDValue, 12> SaveXMMOps;
      SaveXMMOps.push_back(Chain);
      SaveXMMOps.push_back(ALVal);
      SaveXMMOps.push_back(DAG.getIntPtrConstant(
                             FuncInfo->getRegSaveFrameIndex(), dl));
      SaveXMMOps.push_back(DAG.getIntPtrConstant(
                             FuncInfo->getVarArgsFPOffset(), dl));
      SaveXMMOps.insert(SaveXMMOps.end(), LiveXMMRegs.begin(),
                        LiveXMMRegs.end());
      MemOps.push_back(DAG.getNode(X86ISD::VASTART_SAVE_XMM_REGS, dl,
                                   MVT::Other, SaveXMMOps));
    }

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

  if (isVarArg && MFI.hasMustTailInVarArgFunc()) {
    // Find the largest legal vector type.
    MVT VecVT = MVT::Other;
    // FIXME: Only some x86_32 calling conventions support AVX512.
    if (Subtarget.useAVX512Regs() &&
        (Is64Bit || (CallConv == CallingConv::X86_VectorCall ||
                     CallConv == CallingConv::Intel_OCL_BI)))
      VecVT = MVT::v16f32;
    else if (Subtarget.hasAVX())
      VecVT = MVT::v8f32;
    else if (Subtarget.hasSSE2())
      VecVT = MVT::v4f32;

    // We forward some GPRs and some vector types.
    SmallVector<MVT, 2> RegParmTypes;
    MVT IntVT = Is64Bit ? MVT::i64 : MVT::i32;
    RegParmTypes.push_back(IntVT);
    if (VecVT != MVT::Other)
      RegParmTypes.push_back(VecVT);

    // Compute the set of forwarded registers. The rest are scratch.
    SmallVectorImpl<ForwardedRegister> &Forwards =
        FuncInfo->getForwardedMustTailRegParms();
    CCInfo.analyzeMustTailForwardedRegisters(Forwards, RegParmTypes, CC_X86);

    // Forward AL for SysV x86_64 targets, since it is used for varargs.
    if (Is64Bit && !IsWin64 && !CCInfo.isAllocated(X86::AL)) {
      unsigned ALVReg = MF.addLiveIn(X86::AL, &X86::GR8RegClass);
      Forwards.push_back(ForwardedRegister(ALVReg, X86::AL, MVT::i8));
    }

    // Copy all forwards from physical to virtual registers.
    for (ForwardedRegister &FR : Forwards) {
      // FIXME: Can we use a less constrained schedule?
      SDValue RegVal = DAG.getCopyFromReg(Chain, dl, FR.VReg, FR.VT);
      FR.VReg = MF.getRegInfo().createVirtualRegister(getRegClassFor(FR.VT));
      Chain = DAG.getCopyToReg(Chain, dl, FR.VReg, RegVal);
    }
  }

  // Some CCs need callee pop.
  if (X86::isCalleePop(CallConv, Is64Bit, isVarArg,
                       MF.getTarget().Options.GuaranteedTailCallOpt)) {
    FuncInfo->setBytesToPopOnReturn(StackSize); // Callee pops everything.
  } else if (CallConv == CallingConv::X86_INTR && Ins.size() == 2) {
    // X86 interrupts must pop the error code (and the alignment padding) if
    // present.
    FuncInfo->setBytesToPopOnReturn(Is64Bit ? 16 : 4);
  } else {
    FuncInfo->setBytesToPopOnReturn(0); // Callee pops nothing.
    // If this is an sret function, the return should pop the hidden pointer.
    if (!Is64Bit && !canGuaranteeTCO(CallConv) &&
        !Subtarget.getTargetTriple().isOSMSVCRT() &&
        argsAreStructReturn(Ins, Subtarget.isTargetMCU()) == StackStructReturn)
      FuncInfo->setBytesToPopOnReturn(4);
  }

  if (!Is64Bit) {
    // RegSaveFrameIndex is X86-64 only.
    FuncInfo->setRegSaveFrameIndex(0xAAAAAAA);
    if (CallConv == CallingConv::X86_FastCall ||
        CallConv == CallingConv::X86_ThisCall)
      // fastcc functions can't have varargs.
      FuncInfo->setVarArgsFrameIndex(0xAAAAAAA);
  }

  FuncInfo->setArgumentStackSize(StackSize);

  if (WinEHFuncInfo *EHInfo = MF.getWinEHFuncInfo()) {
    EHPersonality Personality = classifyEHPersonality(F.getPersonalityFn());
    if (Personality == EHPersonality::CoreCLR) {
      assert(Is64Bit);
      // TODO: Add a mechanism to frame lowering that will allow us to indicate
      // that we'd prefer this slot be allocated towards the bottom of the frame
      // (i.e. near the stack pointer after allocating the frame).  Every
      // funclet needs a copy of this slot in its (mostly empty) frame, and the
      // offset from the bottom of this and each funclet's frame must be the
      // same, so the size of funclets' (mostly empty) frames is dictated by
      // how far this slot is from the bottom (since they allocate just enough
      // space to accommodate holding this slot at the correct offset).
      int PSPSymFI = MFI.CreateStackObject(8, 8, /*isSS=*/false);
      EHInfo->PSPSymFrameIdx = PSPSymFI;
    }
  }

  if (CallConv == CallingConv::X86_RegCall ||
      F.hasFnAttribute("no_caller_saved_registers")) {
    MachineRegisterInfo &MRI = MF.getRegInfo();
    for (std::pair<unsigned, unsigned> Pair : MRI.liveins())
      MRI.disableCalleeSavedRegister(Pair.first);
  }

  return Chain;
}

SDValue X86TargetLowering::LowerMemOpCallTo(SDValue Chain, SDValue StackPtr,
                                            SDValue Arg, const SDLoc &dl,
                                            SelectionDAG &DAG,
                                            const CCValAssign &VA,
                                            ISD::ArgFlagsTy Flags) const {
  unsigned LocMemOffset = VA.getLocMemOffset();
  SDValue PtrOff = DAG.getIntPtrConstant(LocMemOffset, dl);
  PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(DAG.getDataLayout()),
                       StackPtr, PtrOff);
  if (Flags.isByVal())
    return CreateCopyOfByValArgument(Arg, PtrOff, Chain, Flags, DAG, dl);

  return DAG.getStore(
      Chain, dl, Arg, PtrOff,
      MachinePointerInfo::getStack(DAG.getMachineFunction(), LocMemOffset));
}

/// Emit a load of return address if tail call
/// optimization is performed and it is required.
SDValue X86TargetLowering::EmitTailCallLoadRetAddr(
    SelectionDAG &DAG, SDValue &OutRetAddr, SDValue Chain, bool IsTailCall,
    bool Is64Bit, int FPDiff, const SDLoc &dl) const {
  // Adjust the Return address stack slot.
  EVT VT = getPointerTy(DAG.getDataLayout());
  OutRetAddr = getReturnAddressFrameIndex(DAG);

  // Load the "old" Return address.
  OutRetAddr = DAG.getLoad(VT, dl, Chain, OutRetAddr, MachinePointerInfo());
  return SDValue(OutRetAddr.getNode(), 1);
}

/// Emit a store of the return address if tail call
/// optimization is performed and it is required (FPDiff!=0).
static SDValue EmitTailCallStoreRetAddr(SelectionDAG &DAG, MachineFunction &MF,
                                        SDValue Chain, SDValue RetAddrFrIdx,
                                        EVT PtrVT, unsigned SlotSize,
                                        int FPDiff, const SDLoc &dl) {
  // Store the return address to the appropriate stack slot.
  if (!FPDiff) return Chain;
  // Calculate the new stack slot for the return address.
  int NewReturnAddrFI =
    MF.getFrameInfo().CreateFixedObject(SlotSize, (int64_t)FPDiff - SlotSize,
                                         false);
  SDValue NewRetAddrFrIdx = DAG.getFrameIndex(NewReturnAddrFI, PtrVT);
  Chain = DAG.getStore(Chain, dl, RetAddrFrIdx, NewRetAddrFrIdx,
                       MachinePointerInfo::getFixedStack(
                           DAG.getMachineFunction(), NewReturnAddrFI));
  return Chain;
}

/// Returns a vector_shuffle mask for an movs{s|d}, movd
/// operation of specified width.
static SDValue getMOVL(SelectionDAG &DAG, const SDLoc &dl, MVT VT, SDValue V1,
                       SDValue V2) {
  unsigned NumElems = VT.getVectorNumElements();
  SmallVector<int, 8> Mask;
  Mask.push_back(NumElems);
  for (unsigned i = 1; i != NumElems; ++i)
    Mask.push_back(i);
  return DAG.getVectorShuffle(VT, dl, V1, V2, Mask);
}

SDValue
X86TargetLowering::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;
  CallingConv::ID CallConv              = CLI.CallConv;
  bool &isTailCall                      = CLI.IsTailCall;
  bool isVarArg                         = CLI.IsVarArg;

  MachineFunction &MF = DAG.getMachineFunction();
  bool Is64Bit        = Subtarget.is64Bit();
  bool IsWin64        = Subtarget.isCallingConvWin64(CallConv);
  StructReturnType SR = callIsStructReturn(Outs, Subtarget.isTargetMCU());
  bool IsSibcall      = false;
  bool IsGuaranteeTCO = MF.getTarget().Options.GuaranteedTailCallOpt ||
      CallConv == CallingConv::Tail;
  X86MachineFunctionInfo *X86Info = MF.getInfo<X86MachineFunctionInfo>();
  const auto *CI = dyn_cast_or_null<CallInst>(CLI.CS.getInstruction());
  const Function *Fn = CI ? CI->getCalledFunction() : nullptr;
  bool HasNCSR = (CI && CI->hasFnAttr("no_caller_saved_registers")) ||
                 (Fn && Fn->hasFnAttribute("no_caller_saved_registers"));
  const auto *II = dyn_cast_or_null<InvokeInst>(CLI.CS.getInstruction());
  bool HasNoCfCheck =
      (CI && CI->doesNoCfCheck()) || (II && II->doesNoCfCheck());
  const Module *M = MF.getMMI().getModule();
  Metadata *IsCFProtectionSupported = M->getModuleFlag("cf-protection-branch");

  MachineFunction::CallSiteInfo CSInfo;

  if (CallConv == CallingConv::X86_INTR)
    report_fatal_error("X86 interrupts may not be called directly");

  if (Subtarget.isPICStyleGOT() && !IsGuaranteeTCO) {
    // If we are using a GOT, disable tail calls to external symbols with
    // default visibility. Tail calling such a symbol requires using a GOT
    // relocation, which forces early binding of the symbol. This breaks code
    // that require lazy function symbol resolution. Using musttail or
    // GuaranteedTailCallOpt will override this.
    GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee);
    if (!G || (!G->getGlobal()->hasLocalLinkage() &&
               G->getGlobal()->hasDefaultVisibility()))
      isTailCall = false;
  }

  bool IsMustTail = CLI.CS && CLI.CS.isMustTailCall();
  if (IsMustTail) {
    // Force this to be a tail call.  The verifier rules are enough to ensure
    // that we can lower this successfully without moving the return address
    // around.
    isTailCall = true;
  } else if (isTailCall) {
    // Check if it's really possible to do a tail call.
    isTailCall = IsEligibleForTailCallOptimization(Callee, CallConv,
                    isVarArg, SR != NotStructReturn,
                    MF.getFunction().hasStructRetAttr(), CLI.RetTy,
                    Outs, OutVals, Ins, DAG);

    // Sibcalls are automatically detected tailcalls which do not require
    // ABI changes.
    if (!IsGuaranteeTCO && isTailCall)
      IsSibcall = true;

    if (isTailCall)
      ++NumTailCalls;
  }

  assert(!(isVarArg && canGuaranteeTCO(CallConv)) &&
         "Var args not supported with calling convention fastcc, ghc or hipe");

  // Analyze operands of the call, assigning locations to each operand.
  SmallVector<CCValAssign, 16> ArgLocs;
  CCState CCInfo(CallConv, isVarArg, MF, ArgLocs, *DAG.getContext());

  // Allocate shadow area for Win64.
  if (IsWin64)
    CCInfo.AllocateStack(32, 8);

  CCInfo.AnalyzeArguments(Outs, CC_X86);

  // In vectorcall calling convention a second pass is required for the HVA
  // types.
  if (CallingConv::X86_VectorCall == CallConv) {
    CCInfo.AnalyzeArgumentsSecondPass(Outs, CC_X86);
  }

  // Get a count of how many bytes are to be pushed on the stack.
  unsigned NumBytes = CCInfo.getAlignedCallFrameSize();
  if (IsSibcall)
    // This is a sibcall. The memory operands are available in caller's
    // own caller's stack.
    NumBytes = 0;
  else if (IsGuaranteeTCO && canGuaranteeTCO(CallConv))
    NumBytes = GetAlignedArgumentStackSize(NumBytes, DAG);

  int FPDiff = 0;
  if (isTailCall && !IsSibcall && !IsMustTail) {
    // Lower arguments at fp - stackoffset + fpdiff.
    unsigned NumBytesCallerPushed = X86Info->getBytesToPopOnReturn();

    FPDiff = NumBytesCallerPushed - NumBytes;

    // Set the delta of movement of the returnaddr stackslot.
    // But only set if delta is greater than previous delta.
    if (FPDiff < X86Info->getTCReturnAddrDelta())
      X86Info->setTCReturnAddrDelta(FPDiff);
  }

  unsigned NumBytesToPush = NumBytes;
  unsigned NumBytesToPop = NumBytes;

  // If we have an inalloca argument, all stack space has already been allocated
  // for us and be right at the top of the stack.  We don't support multiple
  // arguments passed in memory when using inalloca.
  if (!Outs.empty() && Outs.back().Flags.isInAlloca()) {
    NumBytesToPush = 0;
    if (!ArgLocs.back().isMemLoc())
      report_fatal_error("cannot use inalloca attribute on a register "
                         "parameter");
    if (ArgLocs.back().getLocMemOffset() != 0)
      report_fatal_error("any parameter with the inalloca attribute must be "
                         "the only memory argument");
  }

  if (!IsSibcall && !IsMustTail)
    Chain = DAG.getCALLSEQ_START(Chain, NumBytesToPush,
                                 NumBytes - NumBytesToPush, dl);

  SDValue RetAddrFrIdx;
  // Load return address for tail calls.
  if (isTailCall && FPDiff)
    Chain = EmitTailCallLoadRetAddr(DAG, RetAddrFrIdx, Chain, isTailCall,
                                    Is64Bit, FPDiff, dl);

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

  // The next loop assumes that the locations are in the same order of the
  // input arguments.
  assert(isSortedByValueNo(ArgLocs) &&
         "Argument Location list must be sorted before lowering");

  // Walk the register/memloc assignments, inserting copies/loads.  In the case
  // of tail call optimization arguments are handle later.
  const X86RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
  for (unsigned I = 0, OutIndex = 0, E = ArgLocs.size(); I != E;
       ++I, ++OutIndex) {
    assert(OutIndex < Outs.size() && "Invalid Out index");
    // Skip inalloca arguments, they have already been written.
    ISD::ArgFlagsTy Flags = Outs[OutIndex].Flags;
    if (Flags.isInAlloca())
      continue;

    CCValAssign &VA = ArgLocs[I];
    EVT RegVT = VA.getLocVT();
    SDValue Arg = OutVals[OutIndex];
    bool isByVal = Flags.isByVal();

    // Promote the value if needed.
    switch (VA.getLocInfo()) {
    default: llvm_unreachable("Unknown loc info!");
    case CCValAssign::Full: break;
    case CCValAssign::SExt:
      Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, RegVT, Arg);
      break;
    case CCValAssign::ZExt:
      Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, RegVT, Arg);
      break;
    case CCValAssign::AExt:
      if (Arg.getValueType().isVector() &&
          Arg.getValueType().getVectorElementType() == MVT::i1)
        Arg = lowerMasksToReg(Arg, RegVT, dl, DAG);
      else if (RegVT.is128BitVector()) {
        // Special case: passing MMX values in XMM registers.
        Arg = DAG.getBitcast(MVT::i64, Arg);
        Arg = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2i64, Arg);
        Arg = getMOVL(DAG, dl, MVT::v2i64, DAG.getUNDEF(MVT::v2i64), Arg);
      } else
        Arg = DAG.getNode(ISD::ANY_EXTEND, dl, RegVT, Arg);
      break;
    case CCValAssign::BCvt:
      Arg = DAG.getBitcast(RegVT, Arg);
      break;
    case CCValAssign::Indirect: {
      if (isByVal) {
        // Memcpy the argument to a temporary stack slot to prevent
        // the caller from seeing any modifications the callee may make
        // as guaranteed by the `byval` attribute.
        int FrameIdx = MF.getFrameInfo().CreateStackObject(
            Flags.getByValSize(),
            std::max(Align(16), Flags.getNonZeroByValAlign()), false);
        SDValue StackSlot =
            DAG.getFrameIndex(FrameIdx, getPointerTy(DAG.getDataLayout()));
        Chain =
            CreateCopyOfByValArgument(Arg, StackSlot, Chain, Flags, DAG, dl);
        // From now on treat this as a regular pointer
        Arg = StackSlot;
        isByVal = false;
      } else {
        // Store the argument.
        SDValue SpillSlot = DAG.CreateStackTemporary(VA.getValVT());
        int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex();
        Chain = DAG.getStore(
            Chain, dl, Arg, SpillSlot,
            MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI));
        Arg = SpillSlot;
      }
      break;
    }
    }

    if (VA.needsCustom()) {
      assert(VA.getValVT() == MVT::v64i1 &&
             "Currently the only custom case is when we split v64i1 to 2 regs");
      // Split v64i1 value into two registers
      Passv64i1ArgInRegs(dl, DAG, Arg, RegsToPass, VA, ArgLocs[++I], Subtarget);
    } else if (VA.isRegLoc()) {
      RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
      const TargetOptions &Options = DAG.getTarget().Options;
      if (Options.EmitCallSiteInfo)
        CSInfo.emplace_back(VA.getLocReg(), I);
      if (isVarArg && IsWin64) {
        // Win64 ABI requires argument XMM reg to be copied to the corresponding
        // shadow reg if callee is a varargs function.
        unsigned ShadowReg = 0;
        switch (VA.getLocReg()) {
        case X86::XMM0: ShadowReg = X86::RCX; break;
        case X86::XMM1: ShadowReg = X86::RDX; break;
        case X86::XMM2: ShadowReg = X86::R8; break;
        case X86::XMM3: ShadowReg = X86::R9; break;
        }
        if (ShadowReg)
          RegsToPass.push_back(std::make_pair(ShadowReg, Arg));
      }
    } else if (!IsSibcall && (!isTailCall || isByVal)) {
      assert(VA.isMemLoc());
      if (!StackPtr.getNode())
        StackPtr = DAG.getCopyFromReg(Chain, dl, RegInfo->getStackRegister(),
                                      getPointerTy(DAG.getDataLayout()));
      MemOpChains.push_back(LowerMemOpCallTo(Chain, StackPtr, Arg,
                                             dl, DAG, VA, Flags));
    }
  }

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

  if (Subtarget.isPICStyleGOT()) {
    // ELF / PIC requires GOT in the EBX register before function calls via PLT
    // GOT pointer.
    if (!isTailCall) {
      RegsToPass.push_back(std::make_pair(
          unsigned(X86::EBX), DAG.getNode(X86ISD::GlobalBaseReg, SDLoc(),
                                          getPointerTy(DAG.getDataLayout()))));
    } else {
      // If we are tail calling and generating PIC/GOT style code load the
      // address of the callee into ECX. The value in ecx is used as target of
      // the tail jump. This is done to circumvent the ebx/callee-saved problem
      // for tail calls on PIC/GOT architectures. Normally we would just put the
      // address of GOT into ebx and then call target@PLT. But for tail calls
      // ebx would be restored (since ebx is callee saved) before jumping to the
      // target@PLT.

      // Note: The actual moving to ECX is done further down.
      GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee);
      if (G && !G->getGlobal()->hasLocalLinkage() &&
          G->getGlobal()->hasDefaultVisibility())
        Callee = LowerGlobalAddress(Callee, DAG);
      else if (isa<ExternalSymbolSDNode>(Callee))
        Callee = LowerExternalSymbol(Callee, DAG);
    }
  }

  if (Is64Bit && isVarArg && !IsWin64 && !IsMustTail) {
    // From AMD64 ABI document:
    // For calls that may call functions that use varargs or stdargs
    // (prototype-less calls or calls to functions containing ellipsis (...) in
    // the declaration) %al is used as hidden argument to specify the number
    // of SSE registers used. The contents of %al do not need to match exactly
    // the number of registers, but must be an ubound on the number of SSE
    // registers used and is in the range 0 - 8 inclusive.

    // Count the number of XMM registers allocated.
    static const MCPhysReg XMMArgRegs[] = {
      X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
      X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
    };
    unsigned NumXMMRegs = CCInfo.getFirstUnallocated(XMMArgRegs);
    assert((Subtarget.hasSSE1() || !NumXMMRegs)
           && "SSE registers cannot be used when SSE is disabled");

    RegsToPass.push_back(std::make_pair(unsigned(X86::AL),
                                        DAG.getConstant(NumXMMRegs, dl,
                                                        MVT::i8)));
  }

  if (isVarArg && IsMustTail) {
    const auto &Forwards = X86Info->getForwardedMustTailRegParms();
    for (const auto &F : Forwards) {
      SDValue Val = DAG.getCopyFromReg(Chain, dl, F.VReg, F.VT);
      RegsToPass.push_back(std::make_pair(unsigned(F.PReg), Val));
    }
  }

  // For tail calls lower the arguments to the 'real' stack slots.  Sibcalls
  // don't need this because the eligibility check rejects calls that require
  // shuffling arguments passed in memory.
  if (!IsSibcall && isTailCall) {
    // Force all the incoming stack arguments to be loaded from the stack
    // before any new outgoing arguments are stored to the stack, because the
    // outgoing stack slots may alias the incoming argument stack slots, and
    // the alias isn't otherwise explicit. This is slightly more conservative
    // than necessary, because it means that each store effectively depends
    // on every argument instead of just those arguments it would clobber.
    SDValue ArgChain = DAG.getStackArgumentTokenFactor(Chain);

    SmallVector<SDValue, 8> MemOpChains2;
    SDValue FIN;
    int FI = 0;
    for (unsigned I = 0, OutsIndex = 0, E = ArgLocs.size(); I != E;
         ++I, ++OutsIndex) {
      CCValAssign &VA = ArgLocs[I];

      if (VA.isRegLoc()) {
        if (VA.needsCustom()) {
          assert((CallConv == CallingConv::X86_RegCall) &&
                 "Expecting custom case only in regcall calling convention");
          // This means that we are in special case where one argument was
          // passed through two register locations - Skip the next location
          ++I;
        }

        continue;
      }

      assert(VA.isMemLoc());
      SDValue Arg = OutVals[OutsIndex];
      ISD::ArgFlagsTy Flags = Outs[OutsIndex].Flags;
      // Skip inalloca arguments.  They don't require any work.
      if (Flags.isInAlloca())
        continue;
      // Create frame index.
      int32_t Offset = VA.getLocMemOffset()+FPDiff;
      uint32_t OpSize = (VA.getLocVT().getSizeInBits()+7)/8;
      FI = MF.getFrameInfo().CreateFixedObject(OpSize, Offset, true);
      FIN = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));

      if (Flags.isByVal()) {
        // Copy relative to framepointer.
        SDValue Source = DAG.getIntPtrConstant(VA.getLocMemOffset(), dl);
        if (!StackPtr.getNode())
          StackPtr = DAG.getCopyFromReg(Chain, dl, RegInfo->getStackRegister(),
                                        getPointerTy(DAG.getDataLayout()));
        Source = DAG.getNode(ISD::ADD, dl, getPointerTy(DAG.getDataLayout()),
                             StackPtr, Source);

        MemOpChains2.push_back(CreateCopyOfByValArgument(Source, FIN,
                                                         ArgChain,
                                                         Flags, DAG, dl));
      } else {
        // Store relative to framepointer.
        MemOpChains2.push_back(DAG.getStore(
            ArgChain, dl, Arg, FIN,
            MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI)));
      }
    }

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

    // Store the return address to the appropriate stack slot.
    Chain = EmitTailCallStoreRetAddr(DAG, MF, Chain, RetAddrFrIdx,
                                     getPointerTy(DAG.getDataLayout()),
                                     RegInfo->getSlotSize(), FPDiff, dl);
  }

  // Build a sequence of copy-to-reg nodes chained together with token chain
  // and flag operands which copy the outgoing args into registers.
  SDValue InFlag;
  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
    Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
                             RegsToPass[i].second, InFlag);
    InFlag = Chain.getValue(1);
  }

  if (DAG.getTarget().getCodeModel() == CodeModel::Large) {
    assert(Is64Bit && "Large code model is only legal in 64-bit mode.");
    // In the 64-bit large code model, we have to make all calls
    // through a register, since the call instruction's 32-bit
    // pc-relative offset may not be large enough to hold the whole
    // address.
  } else if (Callee->getOpcode() == ISD::GlobalAddress ||
             Callee->getOpcode() == ISD::ExternalSymbol) {
    // Lower direct calls to global addresses and external symbols. Setting
    // ForCall to true here has the effect of removing WrapperRIP when possible
    // to allow direct calls to be selected without first materializing the
    // address into a register.
    Callee = LowerGlobalOrExternal(Callee, DAG, /*ForCall=*/true);
  } else if (Subtarget.isTarget64BitILP32() &&
             Callee->getValueType(0) == MVT::i32) {
    // Zero-extend the 32-bit Callee address into a 64-bit according to x32 ABI
    Callee = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i64, Callee);
  }

  // Returns a chain & a flag for retval copy to use.
  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
  SmallVector<SDValue, 8> Ops;

  if (!IsSibcall && isTailCall && !IsMustTail) {
    Chain = DAG.getCALLSEQ_END(Chain,
                               DAG.getIntPtrConstant(NumBytesToPop, dl, true),
                               DAG.getIntPtrConstant(0, dl, true), InFlag, dl);
    InFlag = Chain.getValue(1);
  }

  Ops.push_back(Chain);
  Ops.push_back(Callee);

  if (isTailCall)
    Ops.push_back(DAG.getConstant(FPDiff, dl, MVT::i32));

  // Add argument registers to the end of the list so that they are known live
  // into the call.
  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
    Ops.push_back(DAG.getRegister(RegsToPass[i].first,
                                  RegsToPass[i].second.getValueType()));

  // Add a register mask operand representing the call-preserved registers.
  // If HasNCSR is asserted (attribute NoCallerSavedRegisters exists) then we
  // set X86_INTR calling convention because it has the same CSR mask
  // (same preserved registers).
  const uint32_t *Mask = RegInfo->getCallPreservedMask(
      MF, HasNCSR ? (CallingConv::ID)CallingConv::X86_INTR : CallConv);
  assert(Mask && "Missing call preserved mask for calling convention");

  // If this is an invoke in a 32-bit function using a funclet-based
  // personality, assume the function clobbers all registers. If an exception
  // is thrown, the runtime will not restore CSRs.
  // FIXME: Model this more precisely so that we can register allocate across
  // the normal edge and spill and fill across the exceptional edge.
  if (!Is64Bit && CLI.CS && CLI.CS.isInvoke()) {
    const Function &CallerFn = MF.getFunction();
    EHPersonality Pers =
        CallerFn.hasPersonalityFn()
            ? classifyEHPersonality(CallerFn.getPersonalityFn())
            : EHPersonality::Unknown;
    if (isFuncletEHPersonality(Pers))
      Mask = RegInfo->getNoPreservedMask();
  }

  // Define a new register mask from the existing mask.
  uint32_t *RegMask = nullptr;

  // In some calling conventions we need to remove the used physical registers
  // from the reg mask.
  if (CallConv == CallingConv::X86_RegCall || HasNCSR) {
    const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();

    // Allocate a new Reg Mask and copy Mask.
    RegMask = MF.allocateRegMask();
    unsigned RegMaskSize = MachineOperand::getRegMaskSize(TRI->getNumRegs());
    memcpy(RegMask, Mask, sizeof(RegMask[0]) * RegMaskSize);

    // Make sure all sub registers of the argument registers are reset
    // in the RegMask.
    for (auto const &RegPair : RegsToPass)
      for (MCSubRegIterator SubRegs(RegPair.first, TRI, /*IncludeSelf=*/true);
           SubRegs.isValid(); ++SubRegs)
        RegMask[*SubRegs / 32] &= ~(1u << (*SubRegs % 32));

    // Create the RegMask Operand according to our updated mask.
    Ops.push_back(DAG.getRegisterMask(RegMask));
  } else {
    // Create the RegMask Operand according to the static mask.
    Ops.push_back(DAG.getRegisterMask(Mask));
  }

  if (InFlag.getNode())
    Ops.push_back(InFlag);

  if (isTailCall) {
    // We used to do:
    //// If this is the first return lowered for this function, add the regs
    //// to the liveout set for the function.
    // This isn't right, although it's probably harmless on x86; liveouts
    // should be computed from returns not tail calls.  Consider a void
    // function making a tail call to a function returning int.
    MF.getFrameInfo().setHasTailCall();
    SDValue Ret = DAG.getNode(X86ISD::TC_RETURN, dl, NodeTys, Ops);
    DAG.addCallSiteInfo(Ret.getNode(), std::move(CSInfo));
    return Ret;
  }

  if (HasNoCfCheck && IsCFProtectionSupported) {
    Chain = DAG.getNode(X86ISD::NT_CALL, dl, NodeTys, Ops);
  } else {
    Chain = DAG.getNode(X86ISD::CALL, dl, NodeTys, Ops);
  }
  InFlag = Chain.getValue(1);
  DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));

  // Save heapallocsite metadata.
  if (CLI.CS)
    if (MDNode *HeapAlloc = CLI.CS->getMetadata("heapallocsite"))
      DAG.addHeapAllocSite(Chain.getNode(), HeapAlloc);

  // Create the CALLSEQ_END node.
  unsigned NumBytesForCalleeToPop;
  if (X86::isCalleePop(CallConv, Is64Bit, isVarArg,
                       DAG.getTarget().Options.GuaranteedTailCallOpt))
    NumBytesForCalleeToPop = NumBytes;    // Callee pops everything
  else if (!Is64Bit && !canGuaranteeTCO(CallConv) &&
           !Subtarget.getTargetTriple().isOSMSVCRT() &&
           SR == StackStructReturn)
    // If this is a call to a struct-return function, the callee
    // pops the hidden struct pointer, so we have to push it back.
    // This is common for Darwin/X86, Linux & Mingw32 targets.
    // For MSVC Win32 targets, the caller pops the hidden struct pointer.
    NumBytesForCalleeToPop = 4;
  else
    NumBytesForCalleeToPop = 0;  // Callee pops nothing.

  // Returns a flag for retval copy to use.
  if (!IsSibcall) {
    Chain = DAG.getCALLSEQ_END(Chain,
                               DAG.getIntPtrConstant(NumBytesToPop, dl, true),
                               DAG.getIntPtrConstant(NumBytesForCalleeToPop, dl,
                                                     true),
                               InFlag, dl);
    InFlag = Chain.getValue(1);
  }

  // Handle result values, copying them out of physregs into vregs that we
  // return.
  return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl, DAG,
                         InVals, RegMask);
}

//===----------------------------------------------------------------------===//
//                Fast Calling Convention (tail call) implementation
//===----------------------------------------------------------------------===//

//  Like std call, callee cleans arguments, convention except that ECX is
//  reserved for storing the tail called function address. Only 2 registers are
//  free for argument passing (inreg). Tail call optimization is performed
//  provided:
//                * tailcallopt is enabled
//                * caller/callee are fastcc
//  On X86_64 architecture with GOT-style position independent code only local
//  (within module) calls are supported at the moment.
//  To keep the stack aligned according to platform abi the function
//  GetAlignedArgumentStackSize ensures that argument delta is always multiples
//  of stack alignment. (Dynamic linkers need this - Darwin's dyld for example)
//  If a tail called function callee has more arguments than the caller the
//  caller needs to make sure that there is room to move the RETADDR to. This is
//  achieved by reserving an area the size of the argument delta right after the
//  original RETADDR, but before the saved framepointer or the spilled registers
//  e.g. caller(arg1, arg2) calls callee(arg1, arg2,arg3,arg4)
//  stack layout:
//    arg1
//    arg2
//    RETADDR
//    [ new RETADDR
//      move area ]
//    (possible EBP)
//    ESI
//    EDI
//    local1 ..

/// Make the stack size align e.g 16n + 12 aligned for a 16-byte align
/// requirement.
unsigned
X86TargetLowering::GetAlignedArgumentStackSize(const unsigned StackSize,
                                               SelectionDAG &DAG) const {
  const Align StackAlignment = Subtarget.getFrameLowering()->getStackAlign();
  const uint64_t SlotSize = Subtarget.getRegisterInfo()->getSlotSize();
  assert(StackSize % SlotSize == 0 &&
         "StackSize must be a multiple of SlotSize");
  return alignTo(StackSize + SlotSize, StackAlignment) - SlotSize;
}

/// Return true if the given stack call argument is already available in the
/// same position (relatively) of the caller's incoming argument stack.
static
bool MatchingStackOffset(SDValue Arg, unsigned Offset, ISD::ArgFlagsTy Flags,
                         MachineFrameInfo &MFI, const MachineRegisterInfo *MRI,
                         const X86InstrInfo *TII, const CCValAssign &VA) {
  unsigned Bytes = Arg.getValueSizeInBits() / 8;

  for (;;) {
    // Look through nodes that don't alter the bits of the incoming value.
    unsigned Op = Arg.getOpcode();
    if (Op == ISD::ZERO_EXTEND || Op == ISD::ANY_EXTEND || Op == ISD::BITCAST) {
      Arg = Arg.getOperand(0);
      continue;
    }
    if (Op == ISD::TRUNCATE) {
      const SDValue &TruncInput = Arg.getOperand(0);
      if (TruncInput.getOpcode() == ISD::AssertZext &&
          cast<VTSDNode>(TruncInput.getOperand(1))->getVT() ==
              Arg.getValueType()) {
        Arg = TruncInput.getOperand(0);
        continue;
      }
    }
    break;
  }

  int FI = INT_MAX;
  if (Arg.getOpcode() == ISD::CopyFromReg) {
    unsigned VR = cast<RegisterSDNode>(Arg.getOperand(1))->getReg();
    if (!Register::isVirtualRegister(VR))
      return false;
    MachineInstr *Def = MRI->getVRegDef(VR);
    if (!Def)
      return false;
    if (!Flags.isByVal()) {
      if (!TII->isLoadFromStackSlot(*Def, FI))
        return false;
    } else {
      unsigned Opcode = Def->getOpcode();
      if ((Opcode == X86::LEA32r || Opcode == X86::LEA64r ||
           Opcode == X86::LEA64_32r) &&
          Def->getOperand(1).isFI()) {
        FI = Def->getOperand(1).getIndex();
        Bytes = Flags.getByValSize();
      } else
        return false;
    }
  } else if (LoadSDNode *Ld = dyn_cast<LoadSDNode>(Arg)) {
    if (Flags.isByVal())
      // ByVal argument is passed in as a pointer but it's now being
      // dereferenced. e.g.
      // define @foo(%struct.X* %A) {
      //   tail call @bar(%struct.X* byval %A)
      // }
      return false;
    SDValue Ptr = Ld->getBasePtr();
    FrameIndexSDNode *FINode = dyn_cast<FrameIndexSDNode>(Ptr);
    if (!FINode)
      return false;
    FI = FINode->getIndex();
  } else if (Arg.getOpcode() == ISD::FrameIndex && Flags.isByVal()) {
    FrameIndexSDNode *FINode = cast<FrameIndexSDNode>(Arg);
    FI = FINode->getIndex();
    Bytes = Flags.getByValSize();
  } else
    return false;

  assert(FI != INT_MAX);
  if (!MFI.isFixedObjectIndex(FI))
    return false;

  if (Offset != MFI.getObjectOffset(FI))
    return false;

  // If this is not byval, check that the argument stack object is immutable.
  // inalloca and argument copy elision can create mutable argument stack
  // objects. Byval objects can be mutated, but a byval call intends to pass the
  // mutated memory.
  if (!Flags.isByVal() && !MFI.isImmutableObjectIndex(FI))
    return false;

  if (VA.getLocVT().getSizeInBits() > Arg.getValueSizeInBits()) {
    // If the argument location is wider than the argument type, check that any
    // extension flags match.
    if (Flags.isZExt() != MFI.isObjectZExt(FI) ||
        Flags.isSExt() != MFI.isObjectSExt(FI)) {
      return false;
    }
  }

  return Bytes == MFI.getObjectSize(FI);
}

/// Check whether the call is eligible for tail call optimization. Targets
/// that want to do tail call optimization should implement this function.
bool X86TargetLowering::IsEligibleForTailCallOptimization(
    SDValue Callee, CallingConv::ID CalleeCC, bool isVarArg,
    bool isCalleeStructRet, bool isCallerStructRet, Type *RetTy,
    const SmallVectorImpl<ISD::OutputArg> &Outs,
    const SmallVectorImpl<SDValue> &OutVals,
    const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG &DAG) const {
  if (!mayTailCallThisCC(CalleeCC))
    return false;

  // If -tailcallopt is specified, make fastcc functions tail-callable.
  MachineFunction &MF = DAG.getMachineFunction();
  const Function &CallerF = MF.getFunction();

  // If the function return type is x86_fp80 and the callee return type is not,
  // then the FP_EXTEND of the call result is not a nop. It's not safe to
  // perform a tailcall optimization here.
  if (CallerF.getReturnType()->isX86_FP80Ty() && !RetTy->isX86_FP80Ty())
    return false;

  CallingConv::ID CallerCC = CallerF.getCallingConv();
  bool CCMatch = CallerCC == CalleeCC;
  bool IsCalleeWin64 = Subtarget.isCallingConvWin64(CalleeCC);
  bool IsCallerWin64 = Subtarget.isCallingConvWin64(CallerCC);
  bool IsGuaranteeTCO = DAG.getTarget().Options.GuaranteedTailCallOpt ||
      CalleeCC == CallingConv::Tail;

  // Win64 functions have extra shadow space for argument homing. Don't do the
  // sibcall if the caller and callee have mismatched expectations for this
  // space.
  if (IsCalleeWin64 != IsCallerWin64)
    return false;

  if (IsGuaranteeTCO) {
    if (canGuaranteeTCO(CalleeCC) && CCMatch)
      return true;
    return false;
  }

  // Look for obvious safe cases to perform tail call optimization that do not
  // require ABI changes. This is what gcc calls sibcall.

  // Can't do sibcall if stack needs to be dynamically re-aligned. PEI needs to
  // emit a special epilogue.
  const X86RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
  if (RegInfo->needsStackRealignment(MF))
    return false;

  // Also avoid sibcall optimization if either caller or callee uses struct
  // return semantics.
  if (isCalleeStructRet || isCallerStructRet)
    return false;

  // Do not sibcall optimize vararg calls unless all arguments are passed via
  // registers.
  LLVMContext &C = *DAG.getContext();
  if (isVarArg && !Outs.empty()) {
    // Optimizing for varargs on Win64 is unlikely to be safe without
    // additional testing.
    if (IsCalleeWin64 || IsCallerWin64)
      return false;

    SmallVector<CCValAssign, 16> ArgLocs;
    CCState CCInfo(CalleeCC, isVarArg, MF, ArgLocs, C);

    CCInfo.AnalyzeCallOperands(Outs, CC_X86);
    for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i)
      if (!ArgLocs[i].isRegLoc())
        return false;
  }

  // If the call result is in ST0 / ST1, it needs to be popped off the x87
  // stack.  Therefore, if it's not used by the call it is not safe to optimize
  // this into a sibcall.
  bool Unused = false;
  for (unsigned i = 0, e = Ins.size(); i != e; ++i) {
    if (!Ins[i].Used) {
      Unused = true;
      break;
    }
  }
  if (Unused) {
    SmallVector<CCValAssign, 16> RVLocs;
    CCState CCInfo(CalleeCC, false, MF, RVLocs, C);
    CCInfo.AnalyzeCallResult(Ins, RetCC_X86);
    for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
      CCValAssign &VA = RVLocs[i];
      if (VA.getLocReg() == X86::FP0 || VA.getLocReg() == X86::FP1)
        return false;
    }
  }

  // Check that the call results are passed in the same way.
  if (!CCState::resultsCompatible(CalleeCC, CallerCC, MF, C, Ins,
                                  RetCC_X86, RetCC_X86))
    return false;
  // The callee has to preserve all registers the caller needs to preserve.
  const X86RegisterInfo *TRI = Subtarget.getRegisterInfo();
  const uint32_t *CallerPreserved = TRI->getCallPreservedMask(MF, CallerCC);
  if (!CCMatch) {
    const uint32_t *CalleePreserved = TRI->getCallPreservedMask(MF, CalleeCC);
    if (!TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved))
      return false;
  }

  unsigned StackArgsSize = 0;

  // If the callee takes no arguments then go on to check the results of the
  // call.
  if (!Outs.empty()) {
    // Check if stack adjustment is needed. For now, do not do this if any
    // argument is passed on the stack.
    SmallVector<CCValAssign, 16> ArgLocs;
    CCState CCInfo(CalleeCC, isVarArg, MF, ArgLocs, C);

    // Allocate shadow area for Win64
    if (IsCalleeWin64)
      CCInfo.AllocateStack(32, 8);

    CCInfo.AnalyzeCallOperands(Outs, CC_X86);
    StackArgsSize = CCInfo.getNextStackOffset();

    if (CCInfo.getNextStackOffset()) {
      // Check if the arguments are already laid out in the right way as
      // the caller's fixed stack objects.
      MachineFrameInfo &MFI = MF.getFrameInfo();
      const MachineRegisterInfo *MRI = &MF.getRegInfo();
      const X86InstrInfo *TII = Subtarget.getInstrInfo();
      for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
        CCValAssign &VA = ArgLocs[i];
        SDValue Arg = OutVals[i];
        ISD::ArgFlagsTy Flags = Outs[i].Flags;
        if (VA.getLocInfo() == CCValAssign::Indirect)
          return false;
        if (!VA.isRegLoc()) {
          if (!MatchingStackOffset(Arg, VA.getLocMemOffset(), Flags,
                                   MFI, MRI, TII, VA))
            return false;
        }
      }
    }

    bool PositionIndependent = isPositionIndependent();
    // If the tailcall address may be in a register, then make sure it's
    // possible to register allocate for it. In 32-bit, the call address can
    // only target EAX, EDX, or ECX since the tail call must be scheduled after
    // callee-saved registers are restored. These happen to be the same
    // registers used to pass 'inreg' arguments so watch out for those.
    if (!Subtarget.is64Bit() && ((!isa<GlobalAddressSDNode>(Callee) &&
                                  !isa<ExternalSymbolSDNode>(Callee)) ||
                                 PositionIndependent)) {
      unsigned NumInRegs = 0;
      // In PIC we need an extra register to formulate the address computation
      // for the callee.
      unsigned MaxInRegs = PositionIndependent ? 2 : 3;

      for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
        CCValAssign &VA = ArgLocs[i];
        if (!VA.isRegLoc())
          continue;
        Register Reg = VA.getLocReg();
        switch (Reg) {
        default: break;
        case X86::EAX: case X86::EDX: case X86::ECX:
          if (++NumInRegs == MaxInRegs)
            return false;
          break;
        }
      }
    }

    const MachineRegisterInfo &MRI = MF.getRegInfo();
    if (!parametersInCSRMatch(MRI, CallerPreserved, ArgLocs, OutVals))
      return false;
  }

  bool CalleeWillPop =
      X86::isCalleePop(CalleeCC, Subtarget.is64Bit(), isVarArg,
                       MF.getTarget().Options.GuaranteedTailCallOpt);

  if (unsigned BytesToPop =
          MF.getInfo<X86MachineFunctionInfo>()->getBytesToPopOnReturn()) {
    // If we have bytes to pop, the callee must pop them.
    bool CalleePopMatches = CalleeWillPop && BytesToPop == StackArgsSize;
    if (!CalleePopMatches)
      return false;
  } else if (CalleeWillPop && StackArgsSize > 0) {
    // If we don't have bytes to pop, make sure the callee doesn't pop any.
    return false;
  }

  return true;
}

FastISel *
X86TargetLowering::createFastISel(FunctionLoweringInfo &funcInfo,
                                  const TargetLibraryInfo *libInfo) const {
  return X86::createFastISel(funcInfo, libInfo);
}

//===----------------------------------------------------------------------===//
//                           Other Lowering Hooks
//===----------------------------------------------------------------------===//

static bool MayFoldLoad(SDValue Op) {
  return Op.hasOneUse() && ISD::isNormalLoad(Op.getNode());
}

static bool MayFoldIntoStore(SDValue Op) {
  return Op.hasOneUse() && ISD::isNormalStore(*Op.getNode()->use_begin());
}

static bool MayFoldIntoZeroExtend(SDValue Op) {
  if (Op.hasOneUse()) {
    unsigned Opcode = Op.getNode()->use_begin()->getOpcode();
    return (ISD::ZERO_EXTEND == Opcode);
  }
  return false;
}

static bool isTargetShuffle(unsigned Opcode) {
  switch(Opcode) {
  default: return false;
  case X86ISD::BLENDI:
  case X86ISD::PSHUFB:
  case X86ISD::PSHUFD:
  case X86ISD::PSHUFHW:
  case X86ISD::PSHUFLW:
  case X86ISD::SHUFP:
  case X86ISD::INSERTPS:
  case X86ISD::EXTRQI:
  case X86ISD::INSERTQI:
  case X86ISD::VALIGN:
  case X86ISD::PALIGNR:
  case X86ISD::VSHLDQ:
  case X86ISD::VSRLDQ:
  case X86ISD::MOVLHPS:
  case X86ISD::MOVHLPS:
  case X86ISD::MOVSHDUP:
  case X86ISD::MOVSLDUP:
  case X86ISD::MOVDDUP:
  case X86ISD::MOVSS:
  case X86ISD::MOVSD:
  case X86ISD::UNPCKL:
  case X86ISD::UNPCKH:
  case X86ISD::VBROADCAST:
  case X86ISD::VPERMILPI:
  case X86ISD::VPERMILPV:
  case X86ISD::VPERM2X128:
  case X86ISD::SHUF128:
  case X86ISD::VPERMIL2:
  case X86ISD::VPERMI:
  case X86ISD::VPPERM:
  case X86ISD::VPERMV:
  case X86ISD::VPERMV3:
  case X86ISD::VZEXT_MOVL:
    return true;
  }
}

static bool isTargetShuffleVariableMask(unsigned Opcode) {
  switch (Opcode) {
  default: return false;
  // Target Shuffles.
  case X86ISD::PSHUFB:
  case X86ISD::VPERMILPV:
  case X86ISD::VPERMIL2:
  case X86ISD::VPPERM:
  case X86ISD::VPERMV:
  case X86ISD::VPERMV3:
    return true;
  // 'Faux' Target Shuffles.
  case ISD::OR:
  case ISD::AND:
  case X86ISD::ANDNP:
    return true;
  }
}

SDValue X86TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) const {
  MachineFunction &MF = DAG.getMachineFunction();
  const X86RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
  X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();
  int ReturnAddrIndex = FuncInfo->getRAIndex();

  if (ReturnAddrIndex == 0) {
    // Set up a frame object for the return address.
    unsigned SlotSize = RegInfo->getSlotSize();
    ReturnAddrIndex = MF.getFrameInfo().CreateFixedObject(SlotSize,
                                                          -(int64_t)SlotSize,
                                                          false);
    FuncInfo->setRAIndex(ReturnAddrIndex);
  }

  return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy(DAG.getDataLayout()));
}

bool X86::isOffsetSuitableForCodeModel(int64_t Offset, CodeModel::Model M,
                                       bool hasSymbolicDisplacement) {
  // Offset should fit into 32 bit immediate field.
  if (!isInt<32>(Offset))
    return false;

  // If we don't have a symbolic displacement - we don't have any extra
  // restrictions.
  if (!hasSymbolicDisplacement)
    return true;

  // FIXME: Some tweaks might be needed for medium code model.
  if (M != CodeModel::Small && M != CodeModel::Kernel)
    return false;

  // For small code model we assume that latest object is 16MB before end of 31
  // bits boundary. We may also accept pretty large negative constants knowing
  // that all objects are in the positive half of address space.
  if (M == CodeModel::Small && Offset < 16*1024*1024)
    return true;

  // For kernel code model we know that all object resist in the negative half
  // of 32bits address space. We may not accept negative offsets, since they may
  // be just off and we may accept pretty large positive ones.
  if (M == CodeModel::Kernel && Offset >= 0)
    return true;

  return false;
}

/// Determines whether the callee is required to pop its own arguments.
/// Callee pop is necessary to support tail calls.
bool X86::isCalleePop(CallingConv::ID CallingConv,
                      bool is64Bit, bool IsVarArg, bool GuaranteeTCO) {
  // If GuaranteeTCO is true, we force some calls to be callee pop so that we
  // can guarantee TCO.
  if (!IsVarArg && shouldGuaranteeTCO(CallingConv, GuaranteeTCO))
    return true;

  switch (CallingConv) {
  default:
    return false;
  case CallingConv::X86_StdCall:
  case CallingConv::X86_FastCall:
  case CallingConv::X86_ThisCall:
  case CallingConv::X86_VectorCall:
    return !is64Bit;
  }
}

/// Return true if the condition is an signed comparison operation.
static bool isX86CCSigned(unsigned X86CC) {
  switch (X86CC) {
  default:
    llvm_unreachable("Invalid integer condition!");
  case X86::COND_E:
  case X86::COND_NE:
  case X86::COND_B:
  case X86::COND_A:
  case X86::COND_BE:
  case X86::COND_AE:
    return false;
  case X86::COND_G:
  case X86::COND_GE:
  case X86::COND_L:
  case X86::COND_LE:
    return true;
  }
}

static X86::CondCode TranslateIntegerX86CC(ISD::CondCode SetCCOpcode) {
  switch (SetCCOpcode) {
  default: llvm_unreachable("Invalid integer condition!");
  case ISD::SETEQ:  return X86::COND_E;
  case ISD::SETGT:  return X86::COND_G;
  case ISD::SETGE:  return X86::COND_GE;
  case ISD::SETLT:  return X86::COND_L;
  case ISD::SETLE:  return X86::COND_LE;
  case ISD::SETNE:  return X86::COND_NE;
  case ISD::SETULT: return X86::COND_B;
  case ISD::SETUGT: return X86::COND_A;
  case ISD::SETULE: return X86::COND_BE;
  case ISD::SETUGE: return X86::COND_AE;
  }
}

/// Do a one-to-one translation of a ISD::CondCode to the X86-specific
/// condition code, returning the condition code and the LHS/RHS of the
/// comparison to make.
static X86::CondCode TranslateX86CC(ISD::CondCode SetCCOpcode, const SDLoc &DL,
                               bool isFP, SDValue &LHS, SDValue &RHS,
                               SelectionDAG &DAG) {
  if (!isFP) {
    if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) {
      if (SetCCOpcode == ISD::SETGT && RHSC->isAllOnesValue()) {
        // X > -1   -> X == 0, jump !sign.
        RHS = DAG.getConstant(0, DL, RHS.getValueType());
        return X86::COND_NS;
      }
      if (SetCCOpcode == ISD::SETLT && RHSC->isNullValue()) {
        // X < 0   -> X == 0, jump on sign.
        return X86::COND_S;
      }
      if (SetCCOpcode == ISD::SETGE && RHSC->isNullValue()) {
        // X >= 0   -> X == 0, jump on !sign.
        return X86::COND_NS;
      }
      if (SetCCOpcode == ISD::SETLT && RHSC->isOne()) {
        // X < 1   -> X <= 0
        RHS = DAG.getConstant(0, DL, RHS.getValueType());
        return X86::COND_LE;
      }
    }

    return TranslateIntegerX86CC(SetCCOpcode);
  }

  // First determine if it is required or is profitable to flip the operands.

  // If LHS is a foldable load, but RHS is not, flip the condition.
  if (ISD::isNON_EXTLoad(LHS.getNode()) &&
      !ISD::isNON_EXTLoad(RHS.getNode())) {
    SetCCOpcode = getSetCCSwappedOperands(SetCCOpcode);
    std::swap(LHS, RHS);
  }

  switch (SetCCOpcode) {
  default: break;
  case ISD::SETOLT:
  case ISD::SETOLE:
  case ISD::SETUGT:
  case ISD::SETUGE:
    std::swap(LHS, RHS);
    break;
  }

  // On a floating point condition, the flags are set as follows:
  // ZF  PF  CF   op
  //  0 | 0 | 0 | X > Y
  //  0 | 0 | 1 | X < Y
  //  1 | 0 | 0 | X == Y
  //  1 | 1 | 1 | unordered
  switch (SetCCOpcode) {
  default: llvm_unreachable("Condcode should be pre-legalized away");
  case ISD::SETUEQ:
  case ISD::SETEQ:   return X86::COND_E;
  case ISD::SETOLT:              // flipped
  case ISD::SETOGT:
  case ISD::SETGT:   return X86::COND_A;
  case ISD::SETOLE:              // flipped
  case ISD::SETOGE:
  case ISD::SETGE:   return X86::COND_AE;
  case ISD::SETUGT:              // flipped
  case ISD::SETULT:
  case ISD::SETLT:   return X86::COND_B;
  case ISD::SETUGE:              // flipped
  case ISD::SETULE:
  case ISD::SETLE:   return X86::COND_BE;
  case ISD::SETONE:
  case ISD::SETNE:   return X86::COND_NE;
  case ISD::SETUO:   return X86::COND_P;
  case ISD::SETO:    return X86::COND_NP;
  case ISD::SETOEQ:
  case ISD::SETUNE:  return X86::COND_INVALID;
  }
}

/// Is there a floating point cmov for the specific X86 condition code?
/// Current x86 isa includes the following FP cmov instructions:
/// fcmovb, fcomvbe, fcomve, fcmovu, fcmovae, fcmova, fcmovne, fcmovnu.
static bool hasFPCMov(unsigned X86CC) {
  switch (X86CC) {
  default:
    return false;
  case X86::COND_B:
  case X86::COND_BE:
  case X86::COND_E:
  case X86::COND_P:
  case X86::COND_A:
  case X86::COND_AE:
  case X86::COND_NE:
  case X86::COND_NP:
    return true;
  }
}


bool X86TargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
                                           const CallInst &I,
                                           MachineFunction &MF,
                                           unsigned Intrinsic) const {

  const IntrinsicData* IntrData = getIntrinsicWithChain(Intrinsic);
  if (!IntrData)
    return false;

  Info.flags = MachineMemOperand::MONone;
  Info.offset = 0;

  switch (IntrData->Type) {
  case TRUNCATE_TO_MEM_VI8:
  case TRUNCATE_TO_MEM_VI16:
  case TRUNCATE_TO_MEM_VI32: {
    Info.opc = ISD::INTRINSIC_VOID;
    Info.ptrVal = I.getArgOperand(0);
    MVT VT  = MVT::getVT(I.getArgOperand(1)->getType());
    MVT ScalarVT = MVT::INVALID_SIMPLE_VALUE_TYPE;
    if (IntrData->Type == TRUNCATE_TO_MEM_VI8)
      ScalarVT = MVT::i8;
    else if (IntrData->Type == TRUNCATE_TO_MEM_VI16)
      ScalarVT = MVT::i16;
    else if (IntrData->Type == TRUNCATE_TO_MEM_VI32)
      ScalarVT = MVT::i32;

    Info.memVT = MVT::getVectorVT(ScalarVT, VT.getVectorNumElements());
    Info.align = Align(1);
    Info.flags |= MachineMemOperand::MOStore;
    break;
  }
  case GATHER:
  case GATHER_AVX2: {
    Info.opc = ISD::INTRINSIC_W_CHAIN;
    Info.ptrVal = nullptr;
    MVT DataVT = MVT::getVT(I.getType());
    MVT IndexVT = MVT::getVT(I.getArgOperand(2)->getType());
    unsigned NumElts = std::min(DataVT.getVectorNumElements(),
                                IndexVT.getVectorNumElements());
    Info.memVT = MVT::getVectorVT(DataVT.getVectorElementType(), NumElts);
    Info.align = Align(1);
    Info.flags |= MachineMemOperand::MOLoad;
    break;
  }
  case SCATTER: {
    Info.opc = ISD::INTRINSIC_VOID;
    Info.ptrVal = nullptr;
    MVT DataVT = MVT::getVT(I.getArgOperand(3)->getType());
    MVT IndexVT = MVT::getVT(I.getArgOperand(2)->getType());
    unsigned NumElts = std::min(DataVT.getVectorNumElements(),
                                IndexVT.getVectorNumElements());
    Info.memVT = MVT::getVectorVT(DataVT.getVectorElementType(), NumElts);
    Info.align = Align(1);
    Info.flags |= MachineMemOperand::MOStore;
    break;
  }
  default:
    return false;
  }

  return true;
}

/// Returns true if the target can instruction select the
/// specified FP immediate natively. If false, the legalizer will
/// materialize the FP immediate as a load from a constant pool.
bool X86TargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
                                     bool ForCodeSize) const {
  for (unsigned i = 0, e = LegalFPImmediates.size(); i != e; ++i) {
    if (Imm.bitwiseIsEqual(LegalFPImmediates[i]))
      return true;
  }
  return false;
}

bool X86TargetLowering::shouldReduceLoadWidth(SDNode *Load,
                                              ISD::LoadExtType ExtTy,
                                              EVT NewVT) const {
  assert(cast<LoadSDNode>(Load)->isSimple() && "illegal to narrow");
  
  // "ELF Handling for Thread-Local Storage" specifies that R_X86_64_GOTTPOFF
  // relocation target a movq or addq instruction: don't let the load shrink.
  SDValue BasePtr = cast<LoadSDNode>(Load)->getBasePtr();
  if (BasePtr.getOpcode() == X86ISD::WrapperRIP)
    if (const auto *GA = dyn_cast<GlobalAddressSDNode>(BasePtr.getOperand(0)))
      return GA->getTargetFlags() != X86II::MO_GOTTPOFF;

  // If this is an (1) AVX vector load with (2) multiple uses and (3) all of
  // those uses are extracted directly into a store, then the extract + store
  // can be store-folded. Therefore, it's probably not worth splitting the load.
  EVT VT = Load->getValueType(0);
  if ((VT.is256BitVector() || VT.is512BitVector()) && !Load->hasOneUse()) {
    for (auto UI = Load->use_begin(), UE = Load->use_end(); UI != UE; ++UI) {
      // Skip uses of the chain value. Result 0 of the node is the load value.
      if (UI.getUse().getResNo() != 0)
        continue;

      // If this use is not an extract + store, it's probably worth splitting.
      if (UI->getOpcode() != ISD::EXTRACT_SUBVECTOR || !UI->hasOneUse() ||
          UI->use_begin()->getOpcode() != ISD::STORE)
        return true;
    }
    // All non-chain uses are extract + store.
    return false;
  }

  return true;
}

/// Returns true if it is beneficial to convert a load of a constant
/// to just the constant itself.
bool X86TargetLowering::shouldConvertConstantLoadToIntImm(const APInt &Imm,
                                                          Type *Ty) const {
  assert(Ty->isIntegerTy());

  unsigned BitSize = Ty->getPrimitiveSizeInBits();
  if (BitSize == 0 || BitSize > 64)
    return false;
  return true;
}

bool X86TargetLowering::reduceSelectOfFPConstantLoads(EVT CmpOpVT) const {
  // If we are using XMM registers in the ABI and the condition of the select is
  // a floating-point compare and we have blendv or conditional move, then it is
  // cheaper to select instead of doing a cross-register move and creating a
  // load that depends on the compare result.
  bool IsFPSetCC = CmpOpVT.isFloatingPoint() && CmpOpVT != MVT::f128;
  return !IsFPSetCC || !Subtarget.isTarget64BitLP64() || !Subtarget.hasAVX();
}

bool X86TargetLowering::convertSelectOfConstantsToMath(EVT VT) const {
  // TODO: It might be a win to ease or lift this restriction, but the generic
  // folds in DAGCombiner conflict with vector folds for an AVX512 target.
  if (VT.isVector() && Subtarget.hasAVX512())
    return false;

  return true;
}

bool X86TargetLowering::decomposeMulByConstant(LLVMContext &Context, EVT VT,
                                               SDValue C) const {
  // TODO: We handle scalars using custom code, but generic combining could make
  // that unnecessary.
  APInt MulC;
  if (!ISD::isConstantSplatVector(C.getNode(), MulC))
    return false;

  // Find the type this will be legalized too. Otherwise we might prematurely
  // convert this to shl+add/sub and then still have to type legalize those ops.
  // Another choice would be to defer the decision for illegal types until
  // after type legalization. But constant splat vectors of i64 can't make it
  // through type legalization on 32-bit targets so we would need to special
  // case vXi64.
  while (getTypeAction(Context, VT) != TypeLegal)
    VT = getTypeToTransformTo(Context, VT);

  // If vector multiply is legal, assume that's faster than shl + add/sub.
  // TODO: Multiply is a complex op with higher latency and lower throughput in
  //       most implementations, so this check could be loosened based on type
  //       and/or a CPU attribute.
  if (isOperationLegal(ISD::MUL, VT))
    return false;

  // shl+add, shl+sub, shl+add+neg
  return (MulC + 1).isPowerOf2() || (MulC - 1).isPowerOf2() ||
         (1 - MulC).isPowerOf2() || (-(MulC + 1)).isPowerOf2();
}

bool X86TargetLowering::isExtractSubvectorCheap(EVT ResVT, EVT SrcVT,
                                                unsigned Index) const {
  if (!isOperationLegalOrCustom(ISD::EXTRACT_SUBVECTOR, ResVT))
    return false;

  // Mask vectors support all subregister combinations and operations that
  // extract half of vector.
  if (ResVT.getVectorElementType() == MVT::i1)
    return Index == 0 || ((ResVT.getSizeInBits() == SrcVT.getSizeInBits()*2) &&
                          (Index == ResVT.getVectorNumElements()));

  return (Index % ResVT.getVectorNumElements()) == 0;
}

bool X86TargetLowering::shouldScalarizeBinop(SDValue VecOp) const {
  unsigned Opc = VecOp.getOpcode();

  // Assume target opcodes can't be scalarized.
  // TODO - do we have any exceptions?
  if (Opc >= ISD::BUILTIN_OP_END)
    return false;

  // If the vector op is not supported, try to convert to scalar.
  EVT VecVT = VecOp.getValueType();
  if (!isOperationLegalOrCustomOrPromote(Opc, VecVT))
    return true;

  // If the vector op is supported, but the scalar op is not, the transform may
  // not be worthwhile.
  EVT ScalarVT = VecVT.getScalarType();
  return isOperationLegalOrCustomOrPromote(Opc, ScalarVT);
}

bool X86TargetLowering::shouldFormOverflowOp(unsigned Opcode, EVT VT,
                                             bool) const {
  // TODO: Allow vectors?
  if (VT.isVector())
    return false;
  return VT.isSimple() || !isOperationExpand(Opcode, VT);
}

bool X86TargetLowering::isCheapToSpeculateCttz() const {
  // Speculate cttz only if we can directly use TZCNT.
  return Subtarget.hasBMI();
}

bool X86TargetLowering::isCheapToSpeculateCtlz() const {
  // Speculate ctlz only if we can directly use LZCNT.
  return Subtarget.hasLZCNT();
}

bool X86TargetLowering::isLoadBitCastBeneficial(EVT LoadVT, EVT BitcastVT,
                                                const SelectionDAG &DAG,
                                                const MachineMemOperand &MMO) const {
  if (!Subtarget.hasAVX512() && !LoadVT.isVector() && BitcastVT.isVector() &&
      BitcastVT.getVectorElementType() == MVT::i1)
    return false;

  if (!Subtarget.hasDQI() && BitcastVT == MVT::v8i1 && LoadVT == MVT::i8)
    return false;

  // If both types are legal vectors, it's always ok to convert them.
  if (LoadVT.isVector() && BitcastVT.isVector() &&
      isTypeLegal(LoadVT) && isTypeLegal(BitcastVT))
    return true;

  return TargetLowering::isLoadBitCastBeneficial(LoadVT, BitcastVT, DAG, MMO);
}

bool X86TargetLowering::canMergeStoresTo(unsigned AddressSpace, EVT MemVT,
                                         const SelectionDAG &DAG) const {
  // Do not merge to float value size (128 bytes) if no implicit
  // float attribute is set.
  bool NoFloat = DAG.getMachineFunction().getFunction().hasFnAttribute(
      Attribute::NoImplicitFloat);

  if (NoFloat) {
    unsigned MaxIntSize = Subtarget.is64Bit() ? 64 : 32;
    return (MemVT.getSizeInBits() <= MaxIntSize);
  }
  // Make sure we don't merge greater than our preferred vector
  // width.
  if (MemVT.getSizeInBits() > Subtarget.getPreferVectorWidth())
    return false;
  return true;
}

bool X86TargetLowering::isCtlzFast() const {
  return Subtarget.hasFastLZCNT();
}

bool X86TargetLowering::isMaskAndCmp0FoldingBeneficial(
    const Instruction &AndI) const {
  return true;
}

bool X86TargetLowering::hasAndNotCompare(SDValue Y) const {
  EVT VT = Y.getValueType();

  if (VT.isVector())
    return false;

  if (!Subtarget.hasBMI())
    return false;

  // There are only 32-bit and 64-bit forms for 'andn'.
  if (VT != MVT::i32 && VT != MVT::i64)
    return false;

  return !isa<ConstantSDNode>(Y);
}

bool X86TargetLowering::hasAndNot(SDValue Y) const {
  EVT VT = Y.getValueType();

  if (!VT.isVector())
    return hasAndNotCompare(Y);

  // Vector.

  if (!Subtarget.hasSSE1() || VT.getSizeInBits() < 128)
    return false;

  if (VT == MVT::v4i32)
    return true;

  return Subtarget.hasSSE2();
}

bool X86TargetLowering::hasBitTest(SDValue X, SDValue Y) const {
  return X.getValueType().isScalarInteger(); // 'bt'
}

bool X86TargetLowering::
    shouldProduceAndByConstByHoistingConstFromShiftsLHSOfAnd(
        SDValue X, ConstantSDNode *XC, ConstantSDNode *CC, SDValue Y,
        unsigned OldShiftOpcode, unsigned NewShiftOpcode,
        SelectionDAG &DAG) const {
  // Does baseline recommend not to perform the fold by default?
  if (!TargetLowering::shouldProduceAndByConstByHoistingConstFromShiftsLHSOfAnd(
          X, XC, CC, Y, OldShiftOpcode, NewShiftOpcode, DAG))
    return false;
  // For scalars this transform is always beneficial.
  if (X.getValueType().isScalarInteger())
    return true;
  // If all the shift amounts are identical, then transform is beneficial even
  // with rudimentary SSE2 shifts.
  if (DAG.isSplatValue(Y, /*AllowUndefs=*/true))
    return true;
  // If we have AVX2 with it's powerful shift operations, then it's also good.
  if (Subtarget.hasAVX2())
    return true;
  // Pre-AVX2 vector codegen for this pattern is best for variant with 'shl'.
  return NewShiftOpcode == ISD::SHL;
}

bool X86TargetLowering::shouldFoldConstantShiftPairToMask(
    const SDNode *N, CombineLevel Level) const {
  assert(((N->getOpcode() == ISD::SHL &&
           N->getOperand(0).getOpcode() == ISD::SRL) ||
          (N->getOpcode() == ISD::SRL &&
           N->getOperand(0).getOpcode() == ISD::SHL)) &&
         "Expected shift-shift mask");
  EVT VT = N->getValueType(0);
  if ((Subtarget.hasFastVectorShiftMasks() && VT.isVector()) ||
      (Subtarget.hasFastScalarShiftMasks() && !VT.isVector())) {
    // Only fold if the shift values are equal - so it folds to AND.
    // TODO - we should fold if either is a non-uniform vector but we don't do
    // the fold for non-splats yet.
    return N->getOperand(1) == N->getOperand(0).getOperand(1);
  }
  return TargetLoweringBase::shouldFoldConstantShiftPairToMask(N, Level);
}

bool X86TargetLowering::shouldFoldMaskToVariableShiftPair(SDValue Y) const {
  EVT VT = Y.getValueType();

  // For vectors, we don't have a preference, but we probably want a mask.
  if (VT.isVector())
    return false;

  // 64-bit shifts on 32-bit targets produce really bad bloated code.
  if (VT == MVT::i64 && !Subtarget.is64Bit())
    return false;

  return true;
}

bool X86TargetLowering::shouldExpandShift(SelectionDAG &DAG,
                                          SDNode *N) const {
  if (DAG.getMachineFunction().getFunction().hasMinSize() &&
      !Subtarget.isOSWindows())
    return false;
  return true;
}

bool X86TargetLowering::shouldSplatInsEltVarIndex(EVT VT) const {
  // Any legal vector type can be splatted more efficiently than
  // loading/spilling from memory.
  return isTypeLegal(VT);
}

MVT X86TargetLowering::hasFastEqualityCompare(unsigned NumBits) const {
  MVT VT = MVT::getIntegerVT(NumBits);
  if (isTypeLegal(VT))
    return VT;

  // PMOVMSKB can handle this.
  if (NumBits == 128 && isTypeLegal(MVT::v16i8))
    return MVT::v16i8;

  // VPMOVMSKB can handle this.
  if (NumBits == 256 && isTypeLegal(MVT::v32i8))
    return MVT::v32i8;

  // TODO: Allow 64-bit type for 32-bit target.
  // TODO: 512-bit types should be allowed, but make sure that those
  // cases are handled in combineVectorSizedSetCCEquality().

  return MVT::INVALID_SIMPLE_VALUE_TYPE;
}

/// Val is the undef sentinel value or equal to the specified value.
static bool isUndefOrEqual(int Val, int CmpVal) {
  return ((Val == SM_SentinelUndef) || (Val == CmpVal));
}

/// Val is either the undef or zero sentinel value.
static bool isUndefOrZero(int Val) {
  return ((Val == SM_SentinelUndef) || (Val == SM_SentinelZero));
}

/// Return true if every element in Mask, beginning from position Pos and ending
/// in Pos+Size is the undef sentinel value.
static bool isUndefInRange(ArrayRef<int> Mask, unsigned Pos, unsigned Size) {
  return llvm::all_of(Mask.slice(Pos, Size),
                      [](int M) { return M == SM_SentinelUndef; });
}

/// Return true if the mask creates a vector whose lower half is undefined.
static bool isUndefLowerHalf(ArrayRef<int> Mask) {
  unsigned NumElts = Mask.size();
  return isUndefInRange(Mask, 0, NumElts / 2);
}

/// Return true if the mask creates a vector whose upper half is undefined.
static bool isUndefUpperHalf(ArrayRef<int> Mask) {
  unsigned NumElts = Mask.size();
  return isUndefInRange(Mask, NumElts / 2, NumElts / 2);
}

/// Return true if Val falls within the specified range (L, H].
static bool isInRange(int Val, int Low, int Hi) {
  return (Val >= Low && Val < Hi);
}

/// Return true if the value of any element in Mask falls within the specified
/// range (L, H].
static bool isAnyInRange(ArrayRef<int> Mask, int Low, int Hi) {
  return llvm::any_of(Mask, [Low, Hi](int M) { return isInRange(M, Low, Hi); });
}

/// Return true if the value of any element in Mask is the zero sentinel value.
static bool isAnyZero(ArrayRef<int> Mask) {
  return llvm::any_of(Mask, [](int M) { return M == SM_SentinelZero; });
}

/// Return true if Val is undef or if its value falls within the
/// specified range (L, H].
static bool isUndefOrInRange(int Val, int Low, int Hi) {
  return (Val == SM_SentinelUndef) || isInRange(Val, Low, Hi);
}

/// Return true if every element in Mask is undef or if its value
/// falls within the specified range (L, H].
static bool isUndefOrInRange(ArrayRef<int> Mask, int Low, int Hi) {
  return llvm::all_of(
      Mask, [Low, Hi](int M) { return isUndefOrInRange(M, Low, Hi); });
}

/// Return true if Val is undef, zero or if its value falls within the
/// specified range (L, H].
static bool isUndefOrZeroOrInRange(int Val, int Low, int Hi) {
  return isUndefOrZero(Val) || isInRange(Val, Low, Hi);
}

/// Return true if every element in Mask is undef, zero or if its value
/// falls within the specified range (L, H].
static bool isUndefOrZeroOrInRange(ArrayRef<int> Mask, int Low, int Hi) {
  return llvm::all_of(
      Mask, [Low, Hi](int M) { return isUndefOrZeroOrInRange(M, Low, Hi); });
}

/// Return true if every element in Mask, beginning
/// from position Pos and ending in Pos + Size, falls within the specified
/// sequence (Low, Low + Step, ..., Low + (Size - 1) * Step) or is undef.
static bool isSequentialOrUndefInRange(ArrayRef<int> Mask, unsigned Pos,
                                       unsigned Size, int Low, int Step = 1) {
  for (unsigned i = Pos, e = Pos + Size; i != e; ++i, Low += Step)
    if (!isUndefOrEqual(Mask[i], Low))
      return false;
  return true;
}

/// Return true if every element in Mask, beginning
/// from position Pos and ending in Pos+Size, falls within the specified
/// sequential range (Low, Low+Size], or is undef or is zero.
static bool isSequentialOrUndefOrZeroInRange(ArrayRef<int> Mask, unsigned Pos,
                                             unsigned Size, int Low,
                                             int Step = 1) {
  for (unsigned i = Pos, e = Pos + Size; i != e; ++i, Low += Step)
    if (!isUndefOrZero(Mask[i]) && Mask[i] != Low)
      return false;
  return true;
}

/// Return true if every element in Mask, beginning
/// from position Pos and ending in Pos+Size is undef or is zero.
static bool isUndefOrZeroInRange(ArrayRef<int> Mask, unsigned Pos,
                                 unsigned Size) {
  return llvm::all_of(Mask.slice(Pos, Size),
                      [](int M) { return isUndefOrZero(M); });
}

/// Helper function to test whether a shuffle mask could be
/// simplified by widening the elements being shuffled.
///
/// Appends the mask for wider elements in WidenedMask if valid. Otherwise
/// leaves it in an unspecified state.
///
/// NOTE: This must handle normal vector shuffle masks and *target* vector
/// shuffle masks. The latter have the special property of a '-2' representing
/// a zero-ed lane of a vector.
static bool canWidenShuffleElements(ArrayRef<int> Mask,
                                    SmallVectorImpl<int> &WidenedMask) {
  WidenedMask.assign(Mask.size() / 2, 0);
  for (int i = 0, Size = Mask.size(); i < Size; i += 2) {
    int M0 = Mask[i];
    int M1 = Mask[i + 1];

    // If both elements are undef, its trivial.
    if (M0 == SM_SentinelUndef && M1 == SM_SentinelUndef) {
      WidenedMask[i / 2] = SM_SentinelUndef;
      continue;
    }

    // Check for an undef mask and a mask value properly aligned to fit with
    // a pair of values. If we find such a case, use the non-undef mask's value.
    if (M0 == SM_SentinelUndef && M1 >= 0 && (M1 % 2) == 1) {
      WidenedMask[i / 2] = M1 / 2;
      continue;
    }
    if (M1 == SM_SentinelUndef && M0 >= 0 && (M0 % 2) == 0) {
      WidenedMask[i / 2] = M0 / 2;
      continue;
    }

    // When zeroing, we need to spread the zeroing across both lanes to widen.
    if (M0 == SM_SentinelZero || M1 == SM_SentinelZero) {
      if ((M0 == SM_SentinelZero || M0 == SM_SentinelUndef) &&
          (M1 == SM_SentinelZero || M1 == SM_SentinelUndef)) {
        WidenedMask[i / 2] = SM_SentinelZero;
        continue;
      }
      return false;
    }

    // Finally check if the two mask values are adjacent and aligned with
    // a pair.
    if (M0 != SM_SentinelUndef && (M0 % 2) == 0 && (M0 + 1) == M1) {
      WidenedMask[i / 2] = M0 / 2;
      continue;
    }

    // Otherwise we can't safely widen the elements used in this shuffle.
    return false;
  }
  assert(WidenedMask.size() == Mask.size() / 2 &&
         "Incorrect size of mask after widening the elements!");

  return true;
}

static bool canWidenShuffleElements(ArrayRef<int> Mask,
                                    const APInt &Zeroable,
                                    bool V2IsZero,
                                    SmallVectorImpl<int> &WidenedMask) {
  // Create an alternative mask with info about zeroable elements.
  // Here we do not set undef elements as zeroable.
  SmallVector<int, 64> ZeroableMask(Mask.begin(), Mask.end());
  if (V2IsZero) {
    assert(!Zeroable.isNullValue() && "V2's non-undef elements are used?!");
    for (int i = 0, Size = Mask.size(); i != Size; ++i)
      if (Mask[i] != SM_SentinelUndef && Zeroable[i])
        ZeroableMask[i] = SM_SentinelZero;
  }
  return canWidenShuffleElements(ZeroableMask, WidenedMask);
}

static bool canWidenShuffleElements(ArrayRef<int> Mask) {
  SmallVector<int, 32> WidenedMask;
  return canWidenShuffleElements(Mask, WidenedMask);
}

/// Returns true if Elt is a constant zero or a floating point constant +0.0.
bool X86::isZeroNode(SDValue Elt) {
  return isNullConstant(Elt) || isNullFPConstant(Elt);
}

// Build a vector of constants.
// Use an UNDEF node if MaskElt == -1.
// Split 64-bit constants in the 32-bit mode.
static SDValue getConstVector(ArrayRef<int> Values, MVT VT, SelectionDAG &DAG,
                              const SDLoc &dl, bool IsMask = false) {

  SmallVector<SDValue, 32>  Ops;
  bool Split = false;

  MVT ConstVecVT = VT;
  unsigned NumElts = VT.getVectorNumElements();
  bool In64BitMode = DAG.getTargetLoweringInfo().isTypeLegal(MVT::i64);
  if (!In64BitMode && VT.getVectorElementType() == MVT::i64) {
    ConstVecVT = MVT::getVectorVT(MVT::i32, NumElts * 2);
    Split = true;
  }

  MVT EltVT = ConstVecVT.getVectorElementType();
  for (unsigned i = 0; i < NumElts; ++i) {
    bool IsUndef = Values[i] < 0 && IsMask;
    SDValue OpNode = IsUndef ? DAG.getUNDEF(EltVT) :
      DAG.getConstant(Values[i], dl, EltVT);
    Ops.push_back(OpNode);
    if (Split)
      Ops.push_back(IsUndef ? DAG.getUNDEF(EltVT) :
                    DAG.getConstant(0, dl, EltVT));
  }
  SDValue ConstsNode = DAG.getBuildVector(ConstVecVT, dl, Ops);
  if (Split)
    ConstsNode = DAG.getBitcast(VT, ConstsNode);
  return ConstsNode;
}

static SDValue getConstVector(ArrayRef<APInt> Bits, APInt &Undefs,
                              MVT VT, SelectionDAG &DAG, const SDLoc &dl) {
  assert(Bits.size() == Undefs.getBitWidth() &&
         "Unequal constant and undef arrays");
  SmallVector<SDValue, 32> Ops;
  bool Split = false;

  MVT ConstVecVT = VT;
  unsigned NumElts = VT.getVectorNumElements();
  bool In64BitMode = DAG.getTargetLoweringInfo().isTypeLegal(MVT::i64);
  if (!In64BitMode && VT.getVectorElementType() == MVT::i64) {
    ConstVecVT = MVT::getVectorVT(MVT::i32, NumElts * 2);
    Split = true;
  }

  MVT EltVT = ConstVecVT.getVectorElementType();
  for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
    if (Undefs[i]) {
      Ops.append(Split ? 2 : 1, DAG.getUNDEF(EltVT));
      continue;
    }
    const APInt &V = Bits[i];
    assert(V.getBitWidth() == VT.getScalarSizeInBits() && "Unexpected sizes");
    if (Split) {
      Ops.push_back(DAG.getConstant(V.trunc(32), dl, EltVT));
      Ops.push_back(DAG.getConstant(V.lshr(32).trunc(32), dl, EltVT));
    } else if (EltVT == MVT::f32) {
      APFloat FV(APFloat::IEEEsingle(), V);
      Ops.push_back(DAG.getConstantFP(FV, dl, EltVT));
    } else if (EltVT == MVT::f64) {
      APFloat FV(APFloat::IEEEdouble(), V);
      Ops.push_back(DAG.getConstantFP(FV, dl, EltVT));
    } else {
      Ops.push_back(DAG.getConstant(V, dl, EltVT));
    }
  }

  SDValue ConstsNode = DAG.getBuildVector(ConstVecVT, dl, Ops);
  return DAG.getBitcast(VT, ConstsNode);
}

/// Returns a vector of specified type with all zero elements.
static SDValue getZeroVector(MVT VT, const X86Subtarget &Subtarget,
                             SelectionDAG &DAG, const SDLoc &dl) {
  assert((VT.is128BitVector() || VT.is256BitVector() || VT.is512BitVector() ||
          VT.getVectorElementType() == MVT::i1) &&
         "Unexpected vector type");

  // Try to build SSE/AVX zero vectors as <N x i32> bitcasted to their dest
  // type. This ensures they get CSE'd. But if the integer type is not
  // available, use a floating-point +0.0 instead.
  SDValue Vec;
  if (!Subtarget.hasSSE2() && VT.is128BitVector()) {
    Vec = DAG.getConstantFP(+0.0, dl, MVT::v4f32);
  } else if (VT.isFloatingPoint()) {
    Vec = DAG.getConstantFP(+0.0, dl, VT);
  } else if (VT.getVectorElementType() == MVT::i1) {
    assert((Subtarget.hasBWI() || VT.getVectorNumElements() <= 16) &&
           "Unexpected vector type");
    Vec = DAG.getConstant(0, dl, VT);
  } else {
    unsigned Num32BitElts = VT.getSizeInBits() / 32;
    Vec = DAG.getConstant(0, dl, MVT::getVectorVT(MVT::i32, Num32BitElts));
  }
  return DAG.getBitcast(VT, Vec);
}

static SDValue extractSubVector(SDValue Vec, unsigned IdxVal, SelectionDAG &DAG,
                                const SDLoc &dl, unsigned vectorWidth) {
  EVT VT = Vec.getValueType();
  EVT ElVT = VT.getVectorElementType();
  unsigned Factor = VT.getSizeInBits()/vectorWidth;
  EVT ResultVT = EVT::getVectorVT(*DAG.getContext(), ElVT,
                                  VT.getVectorNumElements()/Factor);

  // Extract the relevant vectorWidth bits.  Generate an EXTRACT_SUBVECTOR
  unsigned ElemsPerChunk = vectorWidth / ElVT.getSizeInBits();
  assert(isPowerOf2_32(ElemsPerChunk) && "Elements per chunk not power of 2");

  // This is the index of the first element of the vectorWidth-bit chunk
  // we want. Since ElemsPerChunk is a power of 2 just need to clear bits.
  IdxVal &= ~(ElemsPerChunk - 1);

  // If the input is a buildvector just emit a smaller one.
  if (Vec.getOpcode() == ISD::BUILD_VECTOR)
    return DAG.getBuildVector(ResultVT, dl,
                              Vec->ops().slice(IdxVal, ElemsPerChunk));

  SDValue VecIdx = DAG.getIntPtrConstant(IdxVal, dl);
  return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, ResultVT, Vec, VecIdx);
}

/// Generate a DAG to grab 128-bits from a vector > 128 bits.  This
/// sets things up to match to an AVX VEXTRACTF128 / VEXTRACTI128
/// or AVX-512 VEXTRACTF32x4 / VEXTRACTI32x4
/// instructions or a simple subregister reference. Idx is an index in the
/// 128 bits we want.  It need not be aligned to a 128-bit boundary.  That makes
/// lowering EXTRACT_VECTOR_ELT operations easier.
static SDValue extract128BitVector(SDValue Vec, unsigned IdxVal,
                                   SelectionDAG &DAG, const SDLoc &dl) {
  assert((Vec.getValueType().is256BitVector() ||
          Vec.getValueType().is512BitVector()) && "Unexpected vector size!");
  return extractSubVector(Vec, IdxVal, DAG, dl, 128);
}

/// Generate a DAG to grab 256-bits from a 512-bit vector.
static SDValue extract256BitVector(SDValue Vec, unsigned IdxVal,
                                   SelectionDAG &DAG, const SDLoc &dl) {
  assert(Vec.getValueType().is512BitVector() && "Unexpected vector size!");
  return extractSubVector(Vec, IdxVal, DAG, dl, 256);
}

static SDValue insertSubVector(SDValue Result, SDValue Vec, unsigned IdxVal,
                               SelectionDAG &DAG, const SDLoc &dl,
                               unsigned vectorWidth) {
  assert((vectorWidth == 128 || vectorWidth == 256) &&
         "Unsupported vector width");
  // Inserting UNDEF is Result
  if (Vec.isUndef())
    return Result;
  EVT VT = Vec.getValueType();
  EVT ElVT = VT.getVectorElementType();
  EVT ResultVT = Result.getValueType();

  // Insert the relevant vectorWidth bits.
  unsigned ElemsPerChunk = vectorWidth/ElVT.getSizeInBits();
  assert(isPowerOf2_32(ElemsPerChunk) && "Elements per chunk not power of 2");

  // This is the index of the first element of the vectorWidth-bit chunk
  // we want. Since ElemsPerChunk is a power of 2 just need to clear bits.
  IdxVal &= ~(ElemsPerChunk - 1);

  SDValue VecIdx = DAG.getIntPtrConstant(IdxVal, dl);
  return DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResultVT, Result, Vec, VecIdx);
}

/// Generate a DAG to put 128-bits into a vector > 128 bits.  This
/// sets things up to match to an AVX VINSERTF128/VINSERTI128 or
/// AVX-512 VINSERTF32x4/VINSERTI32x4 instructions or a
/// simple superregister reference.  Idx is an index in the 128 bits
/// we want.  It need not be aligned to a 128-bit boundary.  That makes
/// lowering INSERT_VECTOR_ELT operations easier.
static SDValue insert128BitVector(SDValue Result, SDValue Vec, unsigned IdxVal,
                                  SelectionDAG &DAG, const SDLoc &dl) {
  assert(Vec.getValueType().is128BitVector() && "Unexpected vector size!");
  return insertSubVector(Result, Vec, IdxVal, DAG, dl, 128);
}

/// Widen a vector to a larger size with the same scalar type, with the new
/// elements either zero or undef.
static SDValue widenSubVector(MVT VT, SDValue Vec, bool ZeroNewElements,
                              const X86Subtarget &Subtarget, SelectionDAG &DAG,
                              const SDLoc &dl) {
  assert(Vec.getValueSizeInBits() < VT.getSizeInBits() &&
         Vec.getValueType().getScalarType() == VT.getScalarType() &&
         "Unsupported vector widening type");
  SDValue Res = ZeroNewElements ? getZeroVector(VT, Subtarget, DAG, dl)
                                : DAG.getUNDEF(VT);
  return DAG.getNode(ISD::INSERT_SUBVECTOR, dl, VT, Res, Vec,
                     DAG.getIntPtrConstant(0, dl));
}

/// Widen a vector to a larger size with the same scalar type, with the new
/// elements either zero or undef.
static SDValue widenSubVector(SDValue Vec, bool ZeroNewElements,
                              const X86Subtarget &Subtarget, SelectionDAG &DAG,
                              const SDLoc &dl, unsigned WideSizeInBits) {
  assert(Vec.getValueSizeInBits() < WideSizeInBits &&
         (WideSizeInBits % Vec.getScalarValueSizeInBits()) == 0 &&
         "Unsupported vector widening type");
  unsigned WideNumElts = WideSizeInBits / Vec.getScalarValueSizeInBits();
  MVT SVT = Vec.getSimpleValueType().getScalarType();
  MVT VT = MVT::getVectorVT(SVT, WideNumElts);
  return widenSubVector(VT, Vec, ZeroNewElements, Subtarget, DAG, dl);
}

// Helper function to collect subvector ops that are concatenated together,
// either by ISD::CONCAT_VECTORS or a ISD::INSERT_SUBVECTOR series.
// The subvectors in Ops are guaranteed to be the same type.
static bool collectConcatOps(SDNode *N, SmallVectorImpl<SDValue> &Ops) {
  assert(Ops.empty() && "Expected an empty ops vector");

  if (N->getOpcode() == ISD::CONCAT_VECTORS) {
    Ops.append(N->op_begin(), N->op_end());
    return true;
  }

  if (N->getOpcode() == ISD::INSERT_SUBVECTOR &&
      isa<ConstantSDNode>(N->getOperand(2))) {
    SDValue Src = N->getOperand(0);
    SDValue Sub = N->getOperand(1);
    const APInt &Idx = N->getConstantOperandAPInt(2);
    EVT VT = Src.getValueType();
    EVT SubVT = Sub.getValueType();

    // TODO - Handle more general insert_subvector chains.
    if (VT.getSizeInBits() == (SubVT.getSizeInBits() * 2) &&
        Idx == (VT.getVectorNumElements() / 2) &&
        Src.getOpcode() == ISD::INSERT_SUBVECTOR &&
        Src.getOperand(1).getValueType() == SubVT &&
        isNullConstant(Src.getOperand(2))) {
      Ops.push_back(Src.getOperand(1));
      Ops.push_back(Sub);
      return true;
    }
  }

  return false;
}

// Helper for splitting operands of an operation to legal target size and
// apply a function on each part.
// Useful for operations that are available on SSE2 in 128-bit, on AVX2 in
// 256-bit and on AVX512BW in 512-bit. The argument VT is the type used for
// deciding if/how to split Ops. Ops elements do *not* have to be of type VT.
// The argument Builder is a function that will be applied on each split part:
// SDValue Builder(SelectionDAG&G, SDLoc, ArrayRef<SDValue>)
template <typename F>
SDValue SplitOpsAndApply(SelectionDAG &DAG, const X86Subtarget &Subtarget,
                         const SDLoc &DL, EVT VT, ArrayRef<SDValue> Ops,
                         F Builder, bool CheckBWI = true) {
  assert(Subtarget.hasSSE2() && "Target assumed to support at least SSE2");
  unsigned NumSubs = 1;
  if ((CheckBWI && Subtarget.useBWIRegs()) ||
      (!CheckBWI && Subtarget.useAVX512Regs())) {
    if (VT.getSizeInBits() > 512) {
      NumSubs = VT.getSizeInBits() / 512;
      assert((VT.getSizeInBits() % 512) == 0 && "Illegal vector size");
    }
  } else if (Subtarget.hasAVX2()) {
    if (VT.getSizeInBits() > 256) {
      NumSubs = VT.getSizeInBits() / 256;
      assert((VT.getSizeInBits() % 256) == 0 && "Illegal vector size");
    }
  } else {
    if (VT.getSizeInBits() > 128) {
      NumSubs = VT.getSizeInBits() / 128;
      assert((VT.getSizeInBits() % 128) == 0 && "Illegal vector size");
    }
  }

  if (NumSubs == 1)
    return Builder(DAG, DL, Ops);

  SmallVector<SDValue, 4> Subs;
  for (unsigned i = 0; i != NumSubs; ++i) {
    SmallVector<SDValue, 2> SubOps;
    for (SDValue Op : Ops) {
      EVT OpVT = Op.getValueType();
      unsigned NumSubElts = OpVT.getVectorNumElements() / NumSubs;
      unsigned SizeSub = OpVT.getSizeInBits() / NumSubs;
      SubOps.push_back(extractSubVector(Op, i * NumSubElts, DAG, DL, SizeSub));
    }
    Subs.push_back(Builder(DAG, DL, SubOps));
  }
  return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Subs);
}

/// Insert i1-subvector to i1-vector.
static SDValue insert1BitVector(SDValue Op, SelectionDAG &DAG,
                                const X86Subtarget &Subtarget) {

  SDLoc dl(Op);
  SDValue Vec = Op.getOperand(0);
  SDValue SubVec = Op.getOperand(1);
  SDValue Idx = Op.getOperand(2);

  if (!isa<ConstantSDNode>(Idx))
    return SDValue();

  // Inserting undef is a nop. We can just return the original vector.
  if (SubVec.isUndef())
    return Vec;

  unsigned IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
  if (IdxVal == 0 && Vec.isUndef()) // the operation is legal
    return Op;

  MVT OpVT = Op.getSimpleValueType();
  unsigned NumElems = OpVT.getVectorNumElements();

  SDValue ZeroIdx = DAG.getIntPtrConstant(0, dl);

  // Extend to natively supported kshift.
  MVT WideOpVT = OpVT;
  if ((!Subtarget.hasDQI() && NumElems == 8) || NumElems < 8)
    WideOpVT = Subtarget.hasDQI() ? MVT::v8i1 : MVT::v16i1;

  // Inserting into the lsbs of a zero vector is legal. ISel will insert shifts
  // if necessary.
  if (IdxVal == 0 && ISD::isBuildVectorAllZeros(Vec.getNode())) {
    // May need to promote to a legal type.
    Op = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, WideOpVT,
                     DAG.getConstant(0, dl, WideOpVT),
                     SubVec, Idx);
    return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, OpVT, Op, ZeroIdx);
  }

  MVT SubVecVT = SubVec.getSimpleValueType();
  unsigned SubVecNumElems = SubVecVT.getVectorNumElements();

  assert(IdxVal + SubVecNumElems <= NumElems &&
         IdxVal % SubVecVT.getSizeInBits() == 0 &&
         "Unexpected index value in INSERT_SUBVECTOR");

  SDValue Undef = DAG.getUNDEF(WideOpVT);

  if (IdxVal == 0) {
    // Zero lower bits of the Vec
    SDValue ShiftBits = DAG.getTargetConstant(SubVecNumElems, dl, MVT::i8);
    Vec = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, WideOpVT, Undef, Vec,
                      ZeroIdx);
    Vec = DAG.getNode(X86ISD::KSHIFTR, dl, WideOpVT, Vec, ShiftBits);
    Vec = DAG.getNode(X86ISD::KSHIFTL, dl, WideOpVT, Vec, ShiftBits);
    // Merge them together, SubVec should be zero extended.
    SubVec = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, WideOpVT,
                         DAG.getConstant(0, dl, WideOpVT),
                         SubVec, ZeroIdx);
    Op = DAG.getNode(ISD::OR, dl, WideOpVT, Vec, SubVec);
    return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, OpVT, Op, ZeroIdx);
  }

  SubVec = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, WideOpVT,
                       Undef, SubVec, ZeroIdx);

  if (Vec.isUndef()) {
    assert(IdxVal != 0 && "Unexpected index");
    SubVec = DAG.getNode(X86ISD::KSHIFTL, dl, WideOpVT, SubVec,
                         DAG.getTargetConstant(IdxVal, dl, MVT::i8));
    return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, OpVT, SubVec, ZeroIdx);
  }

  if (ISD::isBuildVectorAllZeros(Vec.getNode())) {
    assert(IdxVal != 0 && "Unexpected index");
    NumElems = WideOpVT.getVectorNumElements();
    unsigned ShiftLeft = NumElems - SubVecNumElems;
    unsigned ShiftRight = NumElems - SubVecNumElems - IdxVal;
    SubVec = DAG.getNode(X86ISD::KSHIFTL, dl, WideOpVT, SubVec,
                         DAG.getTargetConstant(ShiftLeft, dl, MVT::i8));
    if (ShiftRight != 0)
      SubVec = DAG.getNode(X86ISD::KSHIFTR, dl, WideOpVT, SubVec,
                           DAG.getTargetConstant(ShiftRight, dl, MVT::i8));
    return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, OpVT, SubVec, ZeroIdx);
  }

  // Simple case when we put subvector in the upper part
  if (IdxVal + SubVecNumElems == NumElems) {
    SubVec = DAG.getNode(X86ISD::KSHIFTL, dl, WideOpVT, SubVec,
                         DAG.getTargetConstant(IdxVal, dl, MVT::i8));
    if (SubVecNumElems * 2 == NumElems) {
      // Special case, use legal zero extending insert_subvector. This allows
      // isel to optimize when bits are known zero.
      Vec = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, SubVecVT, Vec, ZeroIdx);
      Vec = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, WideOpVT,
                        DAG.getConstant(0, dl, WideOpVT),
                        Vec, ZeroIdx);
    } else {
      // Otherwise use explicit shifts to zero the bits.
      Vec = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, WideOpVT,
                        Undef, Vec, ZeroIdx);
      NumElems = WideOpVT.getVectorNumElements();
      SDValue ShiftBits = DAG.getTargetConstant(NumElems - IdxVal, dl, MVT::i8);
      Vec = DAG.getNode(X86ISD::KSHIFTL, dl, WideOpVT, Vec, ShiftBits);
      Vec = DAG.getNode(X86ISD::KSHIFTR, dl, WideOpVT, Vec, ShiftBits);
    }
    Op = DAG.getNode(ISD::OR, dl, WideOpVT, Vec, SubVec);
    return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, OpVT, Op, ZeroIdx);
  }

  // Inserting into the middle is more complicated.

  NumElems = WideOpVT.getVectorNumElements();

  // Widen the vector if needed.
  Vec = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, WideOpVT, Undef, Vec, ZeroIdx);

  unsigned ShiftLeft = NumElems - SubVecNumElems;
  unsigned ShiftRight = NumElems - SubVecNumElems - IdxVal;

  // Do an optimization for the the most frequently used types.
  if (WideOpVT != MVT::v64i1 || Subtarget.is64Bit()) {
    APInt Mask0 = APInt::getBitsSet(NumElems, IdxVal, IdxVal + SubVecNumElems);
    Mask0.flipAllBits();
    SDValue CMask0 = DAG.getConstant(Mask0, dl, MVT::getIntegerVT(NumElems));
    SDValue VMask0 = DAG.getNode(ISD::BITCAST, dl, WideOpVT, CMask0);
    Vec = DAG.getNode(ISD::AND, dl, WideOpVT, Vec, VMask0);
    SubVec = DAG.getNode(X86ISD::KSHIFTL, dl, WideOpVT, SubVec,
                         DAG.getTargetConstant(ShiftLeft, dl, MVT::i8));
    SubVec = DAG.getNode(X86ISD::KSHIFTR, dl, WideOpVT, SubVec,
                         DAG.getTargetConstant(ShiftRight, dl, MVT::i8));
    Op = DAG.getNode(ISD::OR, dl, WideOpVT, Vec, SubVec);

    // Reduce to original width if needed.
    return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, OpVT, Op, ZeroIdx);
  }

  // Clear the upper bits of the subvector and move it to its insert position.
  SubVec = DAG.getNode(X86ISD::KSHIFTL, dl, WideOpVT, SubVec,
                       DAG.getTargetConstant(ShiftLeft, dl, MVT::i8));
  SubVec = DAG.getNode(X86ISD::KSHIFTR, dl, WideOpVT, SubVec,
                       DAG.getTargetConstant(ShiftRight, dl, MVT::i8));

  // Isolate the bits below the insertion point.
  unsigned LowShift = NumElems - IdxVal;
  SDValue Low = DAG.getNode(X86ISD::KSHIFTL, dl, WideOpVT, Vec,
                            DAG.getTargetConstant(LowShift, dl, MVT::i8));
  Low = DAG.getNode(X86ISD::KSHIFTR, dl, WideOpVT, Low,
                    DAG.getTargetConstant(LowShift, dl, MVT::i8));

  // Isolate the bits after the last inserted bit.
  unsigned HighShift = IdxVal + SubVecNumElems;
  SDValue High = DAG.getNode(X86ISD::KSHIFTR, dl, WideOpVT, Vec,
                            DAG.getTargetConstant(HighShift, dl, MVT::i8));
  High = DAG.getNode(X86ISD::KSHIFTL, dl, WideOpVT, High,
                    DAG.getTargetConstant(HighShift, dl, MVT::i8));

  // Now OR all 3 pieces together.
  Vec = DAG.getNode(ISD::OR, dl, WideOpVT, Low, High);
  SubVec = DAG.getNode(ISD::OR, dl, WideOpVT, SubVec, Vec);

  // Reduce to original width if needed.
  return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, OpVT, SubVec, ZeroIdx);
}

static SDValue concatSubVectors(SDValue V1, SDValue V2, SelectionDAG &DAG,
                                const SDLoc &dl) {
  assert(V1.getValueType() == V2.getValueType() && "subvector type mismatch");
  EVT SubVT = V1.getValueType();
  EVT SubSVT = SubVT.getScalarType();
  unsigned SubNumElts = SubVT.getVectorNumElements();
  unsigned SubVectorWidth = SubVT.getSizeInBits();
  EVT VT = EVT::getVectorVT(*DAG.getContext(), SubSVT, 2 * SubNumElts);
  SDValue V = insertSubVector(DAG.getUNDEF(VT), V1, 0, DAG, dl, SubVectorWidth);
  return insertSubVector(V, V2, SubNumElts, DAG, dl, SubVectorWidth);
}

/// Returns a vector of specified type with all bits set.
/// Always build ones vectors as <4 x i32>, <8 x i32> or <16 x i32>.
/// Then bitcast to their original type, ensuring they get CSE'd.
static SDValue getOnesVector(EVT VT, SelectionDAG &DAG, const SDLoc &dl) {
  assert((VT.is128BitVector() || VT.is256BitVector() || VT.is512BitVector()) &&
         "Expected a 128/256/512-bit vector type");

  APInt Ones = APInt::getAllOnesValue(32);
  unsigned NumElts = VT.getSizeInBits() / 32;
  SDValue Vec = DAG.getConstant(Ones, dl, MVT::getVectorVT(MVT::i32, NumElts));
  return DAG.getBitcast(VT, Vec);
}

// Convert *_EXTEND to *_EXTEND_VECTOR_INREG opcode.
static unsigned getOpcode_EXTEND_VECTOR_INREG(unsigned Opcode) {
  switch (Opcode) {
  case ISD::ANY_EXTEND:
  case ISD::ANY_EXTEND_VECTOR_INREG:
    return ISD::ANY_EXTEND_VECTOR_INREG;
  case ISD::ZERO_EXTEND:
  case ISD::ZERO_EXTEND_VECTOR_INREG:
    return ISD::ZERO_EXTEND_VECTOR_INREG;
  case ISD::SIGN_EXTEND:
  case ISD::SIGN_EXTEND_VECTOR_INREG:
    return ISD::SIGN_EXTEND_VECTOR_INREG;
  }
  llvm_unreachable("Unknown opcode");
}

static SDValue getExtendInVec(unsigned Opcode, const SDLoc &DL, EVT VT,
                              SDValue In, SelectionDAG &DAG) {
  EVT InVT = In.getValueType();
  assert(VT.isVector() && InVT.isVector() && "Expected vector VTs.");
  assert((ISD::ANY_EXTEND == Opcode || ISD::SIGN_EXTEND == Opcode ||
          ISD::ZERO_EXTEND == Opcode) &&
         "Unknown extension opcode");

  // For 256-bit vectors, we only need the lower (128-bit) input half.
  // For 512-bit vectors, we only need the lower input half or quarter.
  if (InVT.getSizeInBits() > 128) {
    assert(VT.getSizeInBits() == InVT.getSizeInBits() &&
           "Expected VTs to be the same size!");
    unsigned Scale = VT.getScalarSizeInBits() / InVT.getScalarSizeInBits();
    In = extractSubVector(In, 0, DAG, DL,
                          std::max(128U, (unsigned)VT.getSizeInBits() / Scale));
    InVT = In.getValueType();
  }

  if (VT.getVectorNumElements() != InVT.getVectorNumElements())
    Opcode = getOpcode_EXTEND_VECTOR_INREG(Opcode);

  return DAG.getNode(Opcode, DL, VT, In);
}

// Match (xor X, -1) -> X.
// Match extract_subvector(xor X, -1) -> extract_subvector(X).
// Match concat_vectors(xor X, -1, xor Y, -1) -> concat_vectors(X, Y).
static SDValue IsNOT(SDValue V, SelectionDAG &DAG) {
  V = peekThroughBitcasts(V);
  if (V.getOpcode() == ISD::XOR &&
      ISD::isBuildVectorAllOnes(V.getOperand(1).getNode()))
    return V.getOperand(0);
  if (V.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
      (isNullConstant(V.getOperand(1)) || V.getOperand(0).hasOneUse())) {
    if (SDValue Not = IsNOT(V.getOperand(0), DAG)) {
      Not = DAG.getBitcast(V.getOperand(0).getValueType(), Not);
      return DAG.getNode(ISD::EXTRACT_SUBVECTOR, SDLoc(Not), V.getValueType(),
                         Not, V.getOperand(1));
    }
  }
  SmallVector<SDValue, 2> CatOps;
  if (collectConcatOps(V.getNode(), CatOps)) {
    for (SDValue &CatOp : CatOps) {
      SDValue NotCat = IsNOT(CatOp, DAG);
      if (!NotCat) return SDValue();
      CatOp = DAG.getBitcast(CatOp.getValueType(), NotCat);
    }
    return DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(V), V.getValueType(), CatOps);
  }
  return SDValue();
}

void llvm::createUnpackShuffleMask(MVT VT, SmallVectorImpl<int> &Mask,
                                   bool Lo, bool Unary) {
  assert(Mask.empty() && "Expected an empty shuffle mask vector");
  int NumElts = VT.getVectorNumElements();
  int NumEltsInLane = 128 / VT.getScalarSizeInBits();
  for (int i = 0; i < NumElts; ++i) {
    unsigned LaneStart = (i / NumEltsInLane) * NumEltsInLane;
    int Pos = (i % NumEltsInLane) / 2 + LaneStart;
    Pos += (Unary ? 0 : NumElts * (i % 2));
    Pos += (Lo ? 0 : NumEltsInLane / 2);
    Mask.push_back(Pos);
  }
}

/// Similar to unpacklo/unpackhi, but without the 128-bit lane limitation
/// imposed by AVX and specific to the unary pattern. Example:
/// v8iX Lo --> <0, 0, 1, 1, 2, 2, 3, 3>
/// v8iX Hi --> <4, 4, 5, 5, 6, 6, 7, 7>
void llvm::createSplat2ShuffleMask(MVT VT, SmallVectorImpl<int> &Mask,
                                   bool Lo) {
  assert(Mask.empty() && "Expected an empty shuffle mask vector");
  int NumElts = VT.getVectorNumElements();
  for (int i = 0; i < NumElts; ++i) {
    int Pos = i / 2;
    Pos += (Lo ? 0 : NumElts / 2);
    Mask.push_back(Pos);
  }
}

/// Returns a vector_shuffle node for an unpackl operation.
static SDValue getUnpackl(SelectionDAG &DAG, const SDLoc &dl, MVT VT,
                          SDValue V1, SDValue V2) {
  SmallVector<int, 8> Mask;
  createUnpackShuffleMask(VT, Mask, /* Lo = */ true, /* Unary = */ false);
  return DAG.getVectorShuffle(VT, dl, V1, V2, Mask);
}

/// Returns a vector_shuffle node for an unpackh operation.
static SDValue getUnpackh(SelectionDAG &DAG, const SDLoc &dl, MVT VT,
                          SDValue V1, SDValue V2) {
  SmallVector<int, 8> Mask;
  createUnpackShuffleMask(VT, Mask, /* Lo = */ false, /* Unary = */ false);
  return DAG.getVectorShuffle(VT, dl, V1, V2, Mask);
}

/// Return a vector_shuffle of the specified vector of zero or undef vector.
/// This produces a shuffle where the low element of V2 is swizzled into the
/// zero/undef vector, landing at element Idx.
/// This produces a shuffle mask like 4,1,2,3 (idx=0) or  0,1,2,4 (idx=3).
static SDValue getShuffleVectorZeroOrUndef(SDValue V2, int Idx,
                                           bool IsZero,
                                           const X86Subtarget &Subtarget,
                                           SelectionDAG &DAG) {
  MVT VT = V2.getSimpleValueType();
  SDValue V1 = IsZero
    ? getZeroVector(VT, Subtarget, DAG, SDLoc(V2)) : DAG.getUNDEF(VT);
  int NumElems = VT.getVectorNumElements();
  SmallVector<int, 16> MaskVec(NumElems);
  for (int i = 0; i != NumElems; ++i)
    // If this is the insertion idx, put the low elt of V2 here.
    MaskVec[i] = (i == Idx) ? NumElems : i;
  return DAG.getVectorShuffle(VT, SDLoc(V2), V1, V2, MaskVec);
}

static const Constant *getTargetConstantFromNode(LoadSDNode *Load) {
  if (!Load || !ISD::isNormalLoad(Load))
    return nullptr;

  SDValue Ptr = Load->getBasePtr();
  if (Ptr->getOpcode() == X86ISD::Wrapper ||
      Ptr->getOpcode() == X86ISD::WrapperRIP)
    Ptr = Ptr->getOperand(0);

  auto *CNode = dyn_cast<ConstantPoolSDNode>(Ptr);
  if (!CNode || CNode->isMachineConstantPoolEntry() || CNode->getOffset() != 0)
    return nullptr;

  return CNode->getConstVal();
}

static const Constant *getTargetConstantFromNode(SDValue Op) {
  Op = peekThroughBitcasts(Op);
  return getTargetConstantFromNode(dyn_cast<LoadSDNode>(Op));
}

const Constant *
X86TargetLowering::getTargetConstantFromLoad(LoadSDNode *LD) const {
  assert(LD && "Unexpected null LoadSDNode");
  return getTargetConstantFromNode(LD);
}

// Extract raw constant bits from constant pools.
static bool getTargetConstantBitsFromNode(SDValue Op, unsigned EltSizeInBits,
                                          APInt &UndefElts,
                                          SmallVectorImpl<APInt> &EltBits,
                                          bool AllowWholeUndefs = true,
                                          bool AllowPartialUndefs = true) {
  assert(EltBits.empty() && "Expected an empty EltBits vector");

  Op = peekThroughBitcasts(Op);

  EVT VT = Op.getValueType();
  unsigned SizeInBits = VT.getSizeInBits();
  assert((SizeInBits % EltSizeInBits) == 0 && "Can't split constant!");
  unsigned NumElts = SizeInBits / EltSizeInBits;

  // Bitcast a source array of element bits to the target size.
  auto CastBitData = [&](APInt &UndefSrcElts, ArrayRef<APInt> SrcEltBits) {
    unsigned NumSrcElts = UndefSrcElts.getBitWidth();
    unsigned SrcEltSizeInBits = SrcEltBits[0].getBitWidth();
    assert((NumSrcElts * SrcEltSizeInBits) == SizeInBits &&
           "Constant bit sizes don't match");

    // Don't split if we don't allow undef bits.
    bool AllowUndefs = AllowWholeUndefs || AllowPartialUndefs;
    if (UndefSrcElts.getBoolValue() && !AllowUndefs)
      return false;

    // If we're already the right size, don't bother bitcasting.
    if (NumSrcElts == NumElts) {
      UndefElts = UndefSrcElts;
      EltBits.assign(SrcEltBits.begin(), SrcEltBits.end());
      return true;
    }

    // Extract all the undef/constant element data and pack into single bitsets.
    APInt UndefBits(SizeInBits, 0);
    APInt MaskBits(SizeInBits, 0);

    for (unsigned i = 0; i != NumSrcElts; ++i) {
      unsigned BitOffset = i * SrcEltSizeInBits;
      if (UndefSrcElts[i])
        UndefBits.setBits(BitOffset, BitOffset + SrcEltSizeInBits);
      MaskBits.insertBits(SrcEltBits[i], BitOffset);
    }

    // Split the undef/constant single bitset data into the target elements.
    UndefElts = APInt(NumElts, 0);
    EltBits.resize(NumElts, APInt(EltSizeInBits, 0));

    for (unsigned i = 0; i != NumElts; ++i) {
      unsigned BitOffset = i * EltSizeInBits;
      APInt UndefEltBits = UndefBits.extractBits(EltSizeInBits, BitOffset);

      // Only treat an element as UNDEF if all bits are UNDEF.
      if (UndefEltBits.isAllOnesValue()) {
        if (!AllowWholeUndefs)
          return false;
        UndefElts.setBit(i);
        continue;
      }

      // If only some bits are UNDEF then treat them as zero (or bail if not
      // supported).
      if (UndefEltBits.getBoolValue() && !AllowPartialUndefs)
        return false;

      EltBits[i] = MaskBits.extractBits(EltSizeInBits, BitOffset);
    }
    return true;
  };

  // Collect constant bits and insert into mask/undef bit masks.
  auto CollectConstantBits = [](const Constant *Cst, APInt &Mask, APInt &Undefs,
                                unsigned UndefBitIndex) {
    if (!Cst)
      return false;
    if (isa<UndefValue>(Cst)) {
      Undefs.setBit(UndefBitIndex);
      return true;
    }
    if (auto *CInt = dyn_cast<ConstantInt>(Cst)) {
      Mask = CInt->getValue();
      return true;
    }
    if (auto *CFP = dyn_cast<ConstantFP>(Cst)) {
      Mask = CFP->getValueAPF().bitcastToAPInt();
      return true;
    }
    return false;
  };

  // Handle UNDEFs.
  if (Op.isUndef()) {
    APInt UndefSrcElts = APInt::getAllOnesValue(NumElts);
    SmallVector<APInt, 64> SrcEltBits(NumElts, APInt(EltSizeInBits, 0));
    return CastBitData(UndefSrcElts, SrcEltBits);
  }

  // Extract scalar constant bits.
  if (auto *Cst = dyn_cast<ConstantSDNode>(Op)) {
    APInt UndefSrcElts = APInt::getNullValue(1);
    SmallVector<APInt, 64> SrcEltBits(1, Cst->getAPIntValue());
    return CastBitData(UndefSrcElts, SrcEltBits);
  }
  if (auto *Cst = dyn_cast<ConstantFPSDNode>(Op)) {
    APInt UndefSrcElts = APInt::getNullValue(1);
    APInt RawBits = Cst->getValueAPF().bitcastToAPInt();
    SmallVector<APInt, 64> SrcEltBits(1, RawBits);
    return CastBitData(UndefSrcElts, SrcEltBits);
  }

  // Extract constant bits from build vector.
  if (ISD::isBuildVectorOfConstantSDNodes(Op.getNode())) {
    unsigned SrcEltSizeInBits = VT.getScalarSizeInBits();
    unsigned NumSrcElts = SizeInBits / SrcEltSizeInBits;

    APInt UndefSrcElts(NumSrcElts, 0);
    SmallVector<APInt, 64> SrcEltBits(NumSrcElts, APInt(SrcEltSizeInBits, 0));
    for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i) {
      const SDValue &Src = Op.getOperand(i);
      if (Src.isUndef()) {
        UndefSrcElts.setBit(i);
        continue;
      }
      auto *Cst = cast<ConstantSDNode>(Src);
      SrcEltBits[i] = Cst->getAPIntValue().zextOrTrunc(SrcEltSizeInBits);
    }
    return CastBitData(UndefSrcElts, SrcEltBits);
  }
  if (ISD::isBuildVectorOfConstantFPSDNodes(Op.getNode())) {
    unsigned SrcEltSizeInBits = VT.getScalarSizeInBits();
    unsigned NumSrcElts = SizeInBits / SrcEltSizeInBits;

    APInt UndefSrcElts(NumSrcElts, 0);
    SmallVector<APInt, 64> SrcEltBits(NumSrcElts, APInt(SrcEltSizeInBits, 0));
    for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i) {
      const SDValue &Src = Op.getOperand(i);
      if (Src.isUndef()) {
        UndefSrcElts.setBit(i);
        continue;
      }
      auto *Cst = cast<ConstantFPSDNode>(Src);
      APInt RawBits = Cst->getValueAPF().bitcastToAPInt();
      SrcEltBits[i] = RawBits.zextOrTrunc(SrcEltSizeInBits);
    }
    return CastBitData(UndefSrcElts, SrcEltBits);
  }

  // Extract constant bits from constant pool vector.
  if (auto *Cst = getTargetConstantFromNode(Op)) {
    Type *CstTy = Cst->getType();
    unsigned CstSizeInBits = CstTy->getPrimitiveSizeInBits();
    if (!CstTy->isVectorTy() || (CstSizeInBits % SizeInBits) != 0)
      return false;

    unsigned SrcEltSizeInBits = CstTy->getScalarSizeInBits();
    unsigned NumSrcElts = SizeInBits / SrcEltSizeInBits;

    APInt UndefSrcElts(NumSrcElts, 0);
    SmallVector<APInt, 64> SrcEltBits(NumSrcElts, APInt(SrcEltSizeInBits, 0));
    for (unsigned i = 0; i != NumSrcElts; ++i)
      if (!CollectConstantBits(Cst->getAggregateElement(i), SrcEltBits[i],
                               UndefSrcElts, i))
        return false;

    return CastBitData(UndefSrcElts, SrcEltBits);
  }

  // Extract constant bits from a broadcasted constant pool scalar.
  if (Op.getOpcode() == X86ISD::VBROADCAST &&
      EltSizeInBits <= VT.getScalarSizeInBits()) {
    if (auto *Broadcast = getTargetConstantFromNode(Op.getOperand(0))) {
      unsigned SrcEltSizeInBits = Broadcast->getType()->getScalarSizeInBits();
      unsigned NumSrcElts = SizeInBits / SrcEltSizeInBits;

      APInt UndefSrcElts(NumSrcElts, 0);
      SmallVector<APInt, 64> SrcEltBits(1, APInt(SrcEltSizeInBits, 0));
      if (CollectConstantBits(Broadcast, SrcEltBits[0], UndefSrcElts, 0)) {
        if (UndefSrcElts[0])
          UndefSrcElts.setBits(0, NumSrcElts);
        SrcEltBits.append(NumSrcElts - 1, SrcEltBits[0]);
        return CastBitData(UndefSrcElts, SrcEltBits);
      }
    }
  }

  if (Op.getOpcode() == X86ISD::VBROADCAST_LOAD &&
      EltSizeInBits <= VT.getScalarSizeInBits()) {
    auto *MemIntr = cast<MemIntrinsicSDNode>(Op);
    if (MemIntr->getMemoryVT().getScalarSizeInBits() != VT.getScalarSizeInBits())
      return false;

    SDValue Ptr = MemIntr->getBasePtr();
    if (Ptr->getOpcode() == X86ISD::Wrapper ||
        Ptr->getOpcode() == X86ISD::WrapperRIP)
      Ptr = Ptr->getOperand(0);

    auto *CNode = dyn_cast<ConstantPoolSDNode>(Ptr);
    if (!CNode || CNode->isMachineConstantPoolEntry() ||
        CNode->getOffset() != 0)
      return false;

    if (const Constant *C = CNode->getConstVal()) {
      unsigned SrcEltSizeInBits = C->getType()->getScalarSizeInBits();
      unsigned NumSrcElts = SizeInBits / SrcEltSizeInBits;

      APInt UndefSrcElts(NumSrcElts, 0);
      SmallVector<APInt, 64> SrcEltBits(1, APInt(SrcEltSizeInBits, 0));
      if (CollectConstantBits(C, SrcEltBits[0], UndefSrcElts, 0)) {
        if (UndefSrcElts[0])
          UndefSrcElts.setBits(0, NumSrcElts);
        SrcEltBits.append(NumSrcElts - 1, SrcEltBits[0]);
        return CastBitData(UndefSrcElts, SrcEltBits);
      }
    }
  }

  // Extract constant bits from a subvector broadcast.
  if (Op.getOpcode() == X86ISD::SUBV_BROADCAST) {
    SmallVector<APInt, 16> SubEltBits;
    if (getTargetConstantBitsFromNode(Op.getOperand(0), EltSizeInBits,
                                      UndefElts, SubEltBits, AllowWholeUndefs,
                                      AllowPartialUndefs)) {
      UndefElts = APInt::getSplat(NumElts, UndefElts);
      while (EltBits.size() < NumElts)
        EltBits.append(SubEltBits.begin(), SubEltBits.end());
      return true;
    }
  }

  // Extract a rematerialized scalar constant insertion.
  if (Op.getOpcode() == X86ISD::VZEXT_MOVL &&
      Op.getOperand(0).getOpcode() == ISD::SCALAR_TO_VECTOR &&
      isa<ConstantSDNode>(Op.getOperand(0).getOperand(0))) {
    unsigned SrcEltSizeInBits = VT.getScalarSizeInBits();
    unsigned NumSrcElts = SizeInBits / SrcEltSizeInBits;

    APInt UndefSrcElts(NumSrcElts, 0);
    SmallVector<APInt, 64> SrcEltBits;
    auto *CN = cast<ConstantSDNode>(Op.getOperand(0).getOperand(0));
    SrcEltBits.push_back(CN->getAPIntValue().zextOrTrunc(SrcEltSizeInBits));
    SrcEltBits.append(NumSrcElts - 1, APInt(SrcEltSizeInBits, 0));
    return CastBitData(UndefSrcElts, SrcEltBits);
  }

  // Insert constant bits from a base and sub vector sources.
  if (Op.getOpcode() == ISD::INSERT_SUBVECTOR &&
      isa<ConstantSDNode>(Op.getOperand(2))) {
    // TODO - support insert_subvector through bitcasts.
    if (EltSizeInBits != VT.getScalarSizeInBits())
      return false;

    APInt UndefSubElts;
    SmallVector<APInt, 32> EltSubBits;
    if (getTargetConstantBitsFromNode(Op.getOperand(1), EltSizeInBits,
                                      UndefSubElts, EltSubBits,
                                      AllowWholeUndefs, AllowPartialUndefs) &&
        getTargetConstantBitsFromNode(Op.getOperand(0), EltSizeInBits,
                                      UndefElts, EltBits, AllowWholeUndefs,
                                      AllowPartialUndefs)) {
      unsigned BaseIdx = Op.getConstantOperandVal(2);
      UndefElts.insertBits(UndefSubElts, BaseIdx);
      for (unsigned i = 0, e = EltSubBits.size(); i != e; ++i)
        EltBits[BaseIdx + i] = EltSubBits[i];
      return true;
    }
  }

  // Extract constant bits from a subvector's source.
  if (Op.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
      isa<ConstantSDNode>(Op.getOperand(1))) {
    // TODO - support extract_subvector through bitcasts.
    if (EltSizeInBits != VT.getScalarSizeInBits())
      return false;

    if (getTargetConstantBitsFromNode(Op.getOperand(0), EltSizeInBits,
                                      UndefElts, EltBits, AllowWholeUndefs,
                                      AllowPartialUndefs)) {
      EVT SrcVT = Op.getOperand(0).getValueType();
      unsigned NumSrcElts = SrcVT.getVectorNumElements();
      unsigned NumSubElts = VT.getVectorNumElements();
      unsigned BaseIdx = Op.getConstantOperandVal(1);
      UndefElts = UndefElts.extractBits(NumSubElts, BaseIdx);
      if ((BaseIdx + NumSubElts) != NumSrcElts)
        EltBits.erase(EltBits.begin() + BaseIdx + NumSubElts, EltBits.end());
      if (BaseIdx != 0)
        EltBits.erase(EltBits.begin(), EltBits.begin() + BaseIdx);
      return true;
    }
  }

  // Extract constant bits from shuffle node sources.
  if (auto *SVN = dyn_cast<ShuffleVectorSDNode>(Op)) {
    // TODO - support shuffle through bitcasts.
    if (EltSizeInBits != VT.getScalarSizeInBits())
      return false;

    ArrayRef<int> Mask = SVN->getMask();
    if ((!AllowWholeUndefs || !AllowPartialUndefs) &&
        llvm::any_of(Mask, [](int M) { return M < 0; }))
      return false;

    APInt UndefElts0, UndefElts1;
    SmallVector<APInt, 32> EltBits0, EltBits1;
    if (isAnyInRange(Mask, 0, NumElts) &&
        !getTargetConstantBitsFromNode(Op.getOperand(0), EltSizeInBits,
                                       UndefElts0, EltBits0, AllowWholeUndefs,
                                       AllowPartialUndefs))
      return false;
    if (isAnyInRange(Mask, NumElts, 2 * NumElts) &&
        !getTargetConstantBitsFromNode(Op.getOperand(1), EltSizeInBits,
                                       UndefElts1, EltBits1, AllowWholeUndefs,
                                       AllowPartialUndefs))
      return false;

    UndefElts = APInt::getNullValue(NumElts);
    for (int i = 0; i != (int)NumElts; ++i) {
      int M = Mask[i];
      if (M < 0) {
        UndefElts.setBit(i);
        EltBits.push_back(APInt::getNullValue(EltSizeInBits));
      } else if (M < (int)NumElts) {
        if (UndefElts0[M])
          UndefElts.setBit(i);
        EltBits.push_back(EltBits0[M]);
      } else {
        if (UndefElts1[M - NumElts])
          UndefElts.setBit(i);
        EltBits.push_back(EltBits1[M - NumElts]);
      }
    }
    return true;
  }

  return false;
}

namespace llvm {
namespace X86 {
bool isConstantSplat(SDValue Op, APInt &SplatVal, bool AllowPartialUndefs) {
  APInt UndefElts;
  SmallVector<APInt, 16> EltBits;
  if (getTargetConstantBitsFromNode(Op, Op.getScalarValueSizeInBits(),
                                    UndefElts, EltBits, true,
                                    AllowPartialUndefs)) {
    int SplatIndex = -1;
    for (int i = 0, e = EltBits.size(); i != e; ++i) {
      if (UndefElts[i])
        continue;
      if (0 <= SplatIndex && EltBits[i] != EltBits[SplatIndex]) {
        SplatIndex = -1;
        break;
      }
      SplatIndex = i;
    }
    if (0 <= SplatIndex) {
      SplatVal = EltBits[SplatIndex];
      return true;
    }
  }

  return false;
}
} // namespace X86
} // namespace llvm

static bool getTargetShuffleMaskIndices(SDValue MaskNode,
                                        unsigned MaskEltSizeInBits,
                                        SmallVectorImpl<uint64_t> &RawMask,
                                        APInt &UndefElts) {
  // Extract the raw target constant bits.
  SmallVector<APInt, 64> EltBits;
  if (!getTargetConstantBitsFromNode(MaskNode, MaskEltSizeInBits, UndefElts,
                                     EltBits, /* AllowWholeUndefs */ true,
                                     /* AllowPartialUndefs */ false))
    return false;

  // Insert the extracted elements into the mask.
  for (APInt Elt : EltBits)
    RawMask.push_back(Elt.getZExtValue());

  return true;
}

/// Create a shuffle mask that matches the PACKSS/PACKUS truncation.
/// Note: This ignores saturation, so inputs must be checked first.
static void createPackShuffleMask(MVT VT, SmallVectorImpl<int> &Mask,
                                  bool Unary) {
  assert(Mask.empty() && "Expected an empty shuffle mask vector");
  unsigned NumElts = VT.getVectorNumElements();
  unsigned NumLanes = VT.getSizeInBits() / 128;
  unsigned NumEltsPerLane = 128 / VT.getScalarSizeInBits();
  unsigned Offset = Unary ? 0 : NumElts;

  for (unsigned Lane = 0; Lane != NumLanes; ++Lane) {
    for (unsigned Elt = 0; Elt != NumEltsPerLane; Elt += 2)
      Mask.push_back(Elt + (Lane * NumEltsPerLane));
    for (unsigned Elt = 0; Elt != NumEltsPerLane; Elt += 2)
      Mask.push_back(Elt + (Lane * NumEltsPerLane) + Offset);
  }
}

// Split the demanded elts of a PACKSS/PACKUS node between its operands.
static void getPackDemandedElts(EVT VT, const APInt &DemandedElts,
                                APInt &DemandedLHS, APInt &DemandedRHS) {
  int NumLanes = VT.getSizeInBits() / 128;
  int NumElts = DemandedElts.getBitWidth();
  int NumInnerElts = NumElts / 2;
  int NumEltsPerLane = NumElts / NumLanes;
  int NumInnerEltsPerLane = NumInnerElts / NumLanes;

  DemandedLHS = APInt::getNullValue(NumInnerElts);
  DemandedRHS = APInt::getNullValue(NumInnerElts);

  // Map DemandedElts to the packed operands.
  for (int Lane = 0; Lane != NumLanes; ++Lane) {
    for (int Elt = 0; Elt != NumInnerEltsPerLane; ++Elt) {
      int OuterIdx = (Lane * NumEltsPerLane) + Elt;
      int InnerIdx = (Lane * NumInnerEltsPerLane) + Elt;
      if (DemandedElts[OuterIdx])
        DemandedLHS.setBit(InnerIdx);
      if (DemandedElts[OuterIdx + NumInnerEltsPerLane])
        DemandedRHS.setBit(InnerIdx);
    }
  }
}

// Split the demanded elts of a HADD/HSUB node between its operands.
static void getHorizDemandedElts(EVT VT, const APInt &DemandedElts,
                                 APInt &DemandedLHS, APInt &DemandedRHS) {
  int NumLanes = VT.getSizeInBits() / 128;
  int NumElts = DemandedElts.getBitWidth();
  int NumEltsPerLane = NumElts / NumLanes;
  int HalfEltsPerLane = NumEltsPerLane / 2;

  DemandedLHS = APInt::getNullValue(NumElts);
  DemandedRHS = APInt::getNullValue(NumElts);

  // Map DemandedElts to the horizontal operands.
  for (int Idx = 0; Idx != NumElts; ++Idx) {
    if (!DemandedElts[Idx])
      continue;
    int LaneIdx = (Idx / NumEltsPerLane) * NumEltsPerLane;
    int LocalIdx = Idx % NumEltsPerLane;
    if (LocalIdx < HalfEltsPerLane) {
      DemandedLHS.setBit(LaneIdx + 2 * LocalIdx + 0);
      DemandedLHS.setBit(LaneIdx + 2 * LocalIdx + 1);
    } else {
      LocalIdx -= HalfEltsPerLane;
      DemandedRHS.setBit(LaneIdx + 2 * LocalIdx + 0);
      DemandedRHS.setBit(LaneIdx + 2 * LocalIdx + 1);
    }
  }
}

/// Calculates the shuffle mask corresponding to the target-specific opcode.
/// If the mask could be calculated, returns it in \p Mask, returns the shuffle
/// operands in \p Ops, and returns true.
/// Sets \p IsUnary to true if only one source is used. Note that this will set
/// IsUnary for shuffles which use a single input multiple times, and in those
/// cases it will adjust the mask to only have indices within that single input.
/// It is an error to call this with non-empty Mask/Ops vectors.
static bool getTargetShuffleMask(SDNode *N, MVT VT, bool AllowSentinelZero,
                                 SmallVectorImpl<SDValue> &Ops,
                                 SmallVectorImpl<int> &Mask, bool &IsUnary) {
  unsigned NumElems = VT.getVectorNumElements();
  unsigned MaskEltSize = VT.getScalarSizeInBits();
  SmallVector<uint64_t, 32> RawMask;
  APInt RawUndefs;
  uint64_t ImmN;

  assert(Mask.empty() && "getTargetShuffleMask expects an empty Mask vector");
  assert(Ops.empty() && "getTargetShuffleMask expects an empty Ops vector");

  IsUnary = false;
  bool IsFakeUnary = false;
  switch (N->getOpcode()) {
  case X86ISD::BLENDI:
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    assert(N->getOperand(1).getValueType() == VT && "Unexpected value type");
    ImmN = N->getConstantOperandVal(N->getNumOperands() - 1);
    DecodeBLENDMask(NumElems, ImmN, Mask);
    IsUnary = IsFakeUnary = N->getOperand(0) == N->getOperand(1);
    break;
  case X86ISD::SHUFP:
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    assert(N->getOperand(1).getValueType() == VT && "Unexpected value type");
    ImmN = N->getConstantOperandVal(N->getNumOperands() - 1);
    DecodeSHUFPMask(NumElems, MaskEltSize, ImmN, Mask);
    IsUnary = IsFakeUnary = N->getOperand(0) == N->getOperand(1);
    break;
  case X86ISD::INSERTPS:
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    assert(N->getOperand(1).getValueType() == VT && "Unexpected value type");
    ImmN = N->getConstantOperandVal(N->getNumOperands() - 1);
    DecodeINSERTPSMask(ImmN, Mask);
    IsUnary = IsFakeUnary = N->getOperand(0) == N->getOperand(1);
    break;
  case X86ISD::EXTRQI:
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    if (isa<ConstantSDNode>(N->getOperand(1)) &&
        isa<ConstantSDNode>(N->getOperand(2))) {
      int BitLen = N->getConstantOperandVal(1);
      int BitIdx = N->getConstantOperandVal(2);
      DecodeEXTRQIMask(NumElems, MaskEltSize, BitLen, BitIdx, Mask);
      IsUnary = true;
    }
    break;
  case X86ISD::INSERTQI:
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    assert(N->getOperand(1).getValueType() == VT && "Unexpected value type");
    if (isa<ConstantSDNode>(N->getOperand(2)) &&
        isa<ConstantSDNode>(N->getOperand(3))) {
      int BitLen = N->getConstantOperandVal(2);
      int BitIdx = N->getConstantOperandVal(3);
      DecodeINSERTQIMask(NumElems, MaskEltSize, BitLen, BitIdx, Mask);
      IsUnary = IsFakeUnary = N->getOperand(0) == N->getOperand(1);
    }
    break;
  case X86ISD::UNPCKH:
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    assert(N->getOperand(1).getValueType() == VT && "Unexpected value type");
    DecodeUNPCKHMask(NumElems, MaskEltSize, Mask);
    IsUnary = IsFakeUnary = N->getOperand(0) == N->getOperand(1);
    break;
  case X86ISD::UNPCKL:
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    assert(N->getOperand(1).getValueType() == VT && "Unexpected value type");
    DecodeUNPCKLMask(NumElems, MaskEltSize, Mask);
    IsUnary = IsFakeUnary = N->getOperand(0) == N->getOperand(1);
    break;
  case X86ISD::MOVHLPS:
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    assert(N->getOperand(1).getValueType() == VT && "Unexpected value type");
    DecodeMOVHLPSMask(NumElems, Mask);
    IsUnary = IsFakeUnary = N->getOperand(0) == N->getOperand(1);
    break;
  case X86ISD::MOVLHPS:
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    assert(N->getOperand(1).getValueType() == VT && "Unexpected value type");
    DecodeMOVLHPSMask(NumElems, Mask);
    IsUnary = IsFakeUnary = N->getOperand(0) == N->getOperand(1);
    break;
  case X86ISD::VALIGN:
    assert((VT.getScalarType() == MVT::i32 || VT.getScalarType() == MVT::i64) &&
           "Only 32-bit and 64-bit elements are supported!");
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    assert(N->getOperand(1).getValueType() == VT && "Unexpected value type");
    ImmN = N->getConstantOperandVal(N->getNumOperands() - 1);
    DecodeVALIGNMask(NumElems, ImmN, Mask);
    IsUnary = IsFakeUnary = N->getOperand(0) == N->getOperand(1);
    Ops.push_back(N->getOperand(1));
    Ops.push_back(N->getOperand(0));
    break;
  case X86ISD::PALIGNR:
    assert(VT.getScalarType() == MVT::i8 && "Byte vector expected");
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    assert(N->getOperand(1).getValueType() == VT && "Unexpected value type");
    ImmN = N->getConstantOperandVal(N->getNumOperands() - 1);
    DecodePALIGNRMask(NumElems, ImmN, Mask);
    IsUnary = IsFakeUnary = N->getOperand(0) == N->getOperand(1);
    Ops.push_back(N->getOperand(1));
    Ops.push_back(N->getOperand(0));
    break;
  case X86ISD::VSHLDQ:
    assert(VT.getScalarType() == MVT::i8 && "Byte vector expected");
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    ImmN = N->getConstantOperandVal(N->getNumOperands() - 1);
    DecodePSLLDQMask(NumElems, ImmN, Mask);
    IsUnary = true;
    break;
  case X86ISD::VSRLDQ:
    assert(VT.getScalarType() == MVT::i8 && "Byte vector expected");
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    ImmN = N->getConstantOperandVal(N->getNumOperands() - 1);
    DecodePSRLDQMask(NumElems, ImmN, Mask);
    IsUnary = true;
    break;
  case X86ISD::PSHUFD:
  case X86ISD::VPERMILPI:
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    ImmN = N->getConstantOperandVal(N->getNumOperands() - 1);
    DecodePSHUFMask(NumElems, MaskEltSize, ImmN, Mask);
    IsUnary = true;
    break;
  case X86ISD::PSHUFHW:
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    ImmN = N->getConstantOperandVal(N->getNumOperands() - 1);
    DecodePSHUFHWMask(NumElems, ImmN, Mask);
    IsUnary = true;
    break;
  case X86ISD::PSHUFLW:
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    ImmN = N->getConstantOperandVal(N->getNumOperands() - 1);
    DecodePSHUFLWMask(NumElems, ImmN, Mask);
    IsUnary = true;
    break;
  case X86ISD::VZEXT_MOVL:
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    DecodeZeroMoveLowMask(NumElems, Mask);
    IsUnary = true;
    break;
  case X86ISD::VBROADCAST: {
    SDValue N0 = N->getOperand(0);
    // See if we're broadcasting from index 0 of an EXTRACT_SUBVECTOR. If so,
    // add the pre-extracted value to the Ops vector.
    if (N0.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
        N0.getOperand(0).getValueType() == VT &&
        N0.getConstantOperandVal(1) == 0)
      Ops.push_back(N0.getOperand(0));

    // We only decode broadcasts of same-sized vectors, unless the broadcast
    // came from an extract from the original width. If we found one, we
    // pushed it the Ops vector above.
    if (N0.getValueType() == VT || !Ops.empty()) {
      DecodeVectorBroadcast(NumElems, Mask);
      IsUnary = true;
      break;
    }
    return false;
  }
  case X86ISD::VPERMILPV: {
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    IsUnary = true;
    SDValue MaskNode = N->getOperand(1);
    if (getTargetShuffleMaskIndices(MaskNode, MaskEltSize, RawMask,
                                    RawUndefs)) {
      DecodeVPERMILPMask(NumElems, MaskEltSize, RawMask, RawUndefs, Mask);
      break;
    }
    return false;
  }
  case X86ISD::PSHUFB: {
    assert(VT.getScalarType() == MVT::i8 && "Byte vector expected");
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    assert(N->getOperand(1).getValueType() == VT && "Unexpected value type");
    IsUnary = true;
    SDValue MaskNode = N->getOperand(1);
    if (getTargetShuffleMaskIndices(MaskNode, 8, RawMask, RawUndefs)) {
      DecodePSHUFBMask(RawMask, RawUndefs, Mask);
      break;
    }
    return false;
  }
  case X86ISD::VPERMI:
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    ImmN = N->getConstantOperandVal(N->getNumOperands() - 1);
    DecodeVPERMMask(NumElems, ImmN, Mask);
    IsUnary = true;
    break;
  case X86ISD::MOVSS:
  case X86ISD::MOVSD:
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    assert(N->getOperand(1).getValueType() == VT && "Unexpected value type");
    DecodeScalarMoveMask(NumElems, /* IsLoad */ false, Mask);
    break;
  case X86ISD::VPERM2X128:
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    assert(N->getOperand(1).getValueType() == VT && "Unexpected value type");
    ImmN = N->getConstantOperandVal(N->getNumOperands() - 1);
    DecodeVPERM2X128Mask(NumElems, ImmN, Mask);
    IsUnary = IsFakeUnary = N->getOperand(0) == N->getOperand(1);
    break;
  case X86ISD::SHUF128:
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    assert(N->getOperand(1).getValueType() == VT && "Unexpected value type");
    ImmN = N->getConstantOperandVal(N->getNumOperands() - 1);
    decodeVSHUF64x2FamilyMask(NumElems, MaskEltSize, ImmN, Mask);
    IsUnary = IsFakeUnary = N->getOperand(0) == N->getOperand(1);
    break;
  case X86ISD::MOVSLDUP:
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    DecodeMOVSLDUPMask(NumElems, Mask);
    IsUnary = true;
    break;
  case X86ISD::MOVSHDUP:
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    DecodeMOVSHDUPMask(NumElems, Mask);
    IsUnary = true;
    break;
  case X86ISD::MOVDDUP:
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    DecodeMOVDDUPMask(NumElems, Mask);
    IsUnary = true;
    break;
  case X86ISD::VPERMIL2: {
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    assert(N->getOperand(1).getValueType() == VT && "Unexpected value type");
    IsUnary = IsFakeUnary = N->getOperand(0) == N->getOperand(1);
    SDValue MaskNode = N->getOperand(2);
    SDValue CtrlNode = N->getOperand(3);
    if (ConstantSDNode *CtrlOp = dyn_cast<ConstantSDNode>(CtrlNode)) {
      unsigned CtrlImm = CtrlOp->getZExtValue();
      if (getTargetShuffleMaskIndices(MaskNode, MaskEltSize, RawMask,
                                      RawUndefs)) {
        DecodeVPERMIL2PMask(NumElems, MaskEltSize, CtrlImm, RawMask, RawUndefs,
                            Mask);
        break;
      }
    }
    return false;
  }
  case X86ISD::VPPERM: {
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    assert(N->getOperand(1).getValueType() == VT && "Unexpected value type");
    IsUnary = IsFakeUnary = N->getOperand(0) == N->getOperand(1);
    SDValue MaskNode = N->getOperand(2);
    if (getTargetShuffleMaskIndices(MaskNode, 8, RawMask, RawUndefs)) {
      DecodeVPPERMMask(RawMask, RawUndefs, Mask);
      break;
    }
    return false;
  }
  case X86ISD::VPERMV: {
    assert(N->getOperand(1).getValueType() == VT && "Unexpected value type");
    IsUnary = true;
    // Unlike most shuffle nodes, VPERMV's mask operand is operand 0.
    Ops.push_back(N->getOperand(1));
    SDValue MaskNode = N->getOperand(0);
    if (getTargetShuffleMaskIndices(MaskNode, MaskEltSize, RawMask,
                                    RawUndefs)) {
      DecodeVPERMVMask(RawMask, RawUndefs, Mask);
      break;
    }
    return false;
  }
  case X86ISD::VPERMV3: {
    assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
    assert(N->getOperand(2).getValueType() == VT && "Unexpected value type");
    IsUnary = IsFakeUnary = N->getOperand(0) == N->getOperand(2);
    // Unlike most shuffle nodes, VPERMV3's mask operand is the middle one.
    Ops.push_back(N->getOperand(0));
    Ops.push_back(N->getOperand(2));
    SDValue MaskNode = N->getOperand(1);
    if (getTargetShuffleMaskIndices(MaskNode, MaskEltSize, RawMask,
                                    RawUndefs)) {
      DecodeVPERMV3Mask(RawMask, RawUndefs, Mask);
      break;
    }
    return false;
  }
  default: llvm_unreachable("unknown target shuffle node");
  }

  // Empty mask indicates the decode failed.
  if (Mask.empty())
    return false;

  // Check if we're getting a shuffle mask with zero'd elements.
  if (!AllowSentinelZero)
    if (any_of(Mask, [](int M) { return M == SM_SentinelZero; }))
      return false;

  // If we have a fake unary shuffle, the shuffle mask is spread across two
  // inputs that are actually the same node. Re-map the mask to always point
  // into the first input.
  if (IsFakeUnary)
    for (int &M : Mask)
      if (M >= (int)Mask.size())
        M -= Mask.size();

  // If we didn't already add operands in the opcode-specific code, default to
  // adding 1 or 2 operands starting at 0.
  if (Ops.empty()) {
    Ops.push_back(N->getOperand(0));
    if (!IsUnary || IsFakeUnary)
      Ops.push_back(N->getOperand(1));
  }

  return true;
}

/// Compute whether each element of a shuffle is zeroable.
///
/// A "zeroable" vector shuffle element is one which can be lowered to zero.
/// Either it is an undef element in the shuffle mask, the element of the input
/// referenced is undef, or the element of the input referenced is known to be
/// zero. Many x86 shuffles can zero lanes cheaply and we often want to handle
/// as many lanes with this technique as possible to simplify the remaining
/// shuffle.
static void computeZeroableShuffleElements(ArrayRef<int> Mask,
                                           SDValue V1, SDValue V2,
                                           APInt &KnownUndef, APInt &KnownZero) {
  int Size = Mask.size();
  KnownUndef = KnownZero = APInt::getNullValue(Size);

  V1 = peekThroughBitcasts(V1);
  V2 = peekThroughBitcasts(V2);

  bool V1IsZero = ISD::isBuildVectorAllZeros(V1.getNode());
  bool V2IsZero = ISD::isBuildVectorAllZeros(V2.getNode());

  int VectorSizeInBits = V1.getValueSizeInBits();
  int ScalarSizeInBits = VectorSizeInBits / Size;
  assert(!(VectorSizeInBits % ScalarSizeInBits) && "Illegal shuffle mask size");

  for (int i = 0; i < Size; ++i) {
    int M = Mask[i];
    // Handle the easy cases.
    if (M < 0) {
      KnownUndef.setBit(i);
      continue;
    }
    if ((M >= 0 && M < Size && V1IsZero) || (M >= Size && V2IsZero)) {
      KnownZero.setBit(i);
      continue;
    }

    // Determine shuffle input and normalize the mask.
    SDValue V = M < Size ? V1 : V2;
    M %= Size;

    // Currently we can only search BUILD_VECTOR for UNDEF/ZERO elements.
    if (V.getOpcode() != ISD::BUILD_VECTOR)
      continue;

    // If the BUILD_VECTOR has fewer elements then the bitcasted portion of
    // the (larger) source element must be UNDEF/ZERO.
    if ((Size % V.getNumOperands()) == 0) {
      int Scale = Size / V->getNumOperands();
      SDValue Op = V.getOperand(M / Scale);
      if (Op.isUndef())
        KnownUndef.setBit(i);
      if (X86::isZeroNode(Op))
        KnownZero.setBit(i);
      else if (ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(Op)) {
        APInt Val = Cst->getAPIntValue();
        Val = Val.extractBits(ScalarSizeInBits, (M % Scale) * ScalarSizeInBits);
        if (Val == 0)
          KnownZero.setBit(i);
      } else if (ConstantFPSDNode *Cst = dyn_cast<ConstantFPSDNode>(Op)) {
        APInt Val = Cst->getValueAPF().bitcastToAPInt();
        Val = Val.extractBits(ScalarSizeInBits, (M % Scale) * ScalarSizeInBits);
        if (Val == 0)
          KnownZero.setBit(i);
      }
      continue;
    }

    // If the BUILD_VECTOR has more elements then all the (smaller) source
    // elements must be UNDEF or ZERO.
    if ((V.getNumOperands() % Size) == 0) {
      int Scale = V->getNumOperands() / Size;
      bool AllUndef = true;
      bool AllZero = true;
      for (int j = 0; j < Scale; ++j) {
        SDValue Op = V.getOperand((M * Scale) + j);
        AllUndef &= Op.isUndef();
        AllZero &= X86::isZeroNode(Op);
      }
      if (AllUndef)
        KnownUndef.setBit(i);
      if (AllZero)
        KnownZero.setBit(i);
      continue;
    }
  }
}

/// Decode a target shuffle mask and inputs and see if any values are
/// known to be undef or zero from their inputs.
/// Returns true if the target shuffle mask was decoded.
/// FIXME: Merge this with computeZeroableShuffleElements?
static bool getTargetShuffleAndZeroables(SDValue N, SmallVectorImpl<int> &Mask,
                                         SmallVectorImpl<SDValue> &Ops,
                                         APInt &KnownUndef, APInt &KnownZero) {
  bool IsUnary;
  if (!isTargetShuffle(N.getOpcode()))
    return false;

  MVT VT = N.getSimpleValueType();
  if (!getTargetShuffleMask(N.getNode(), VT, true, Ops, Mask, IsUnary))
    return false;

  int Size = Mask.size();
  SDValue V1 = Ops[0];
  SDValue V2 = IsUnary ? V1 : Ops[1];
  KnownUndef = KnownZero = APInt::getNullValue(Size);

  V1 = peekThroughBitcasts(V1);
  V2 = peekThroughBitcasts(V2);

  assert((VT.getSizeInBits() % Size) == 0 &&
         "Illegal split of shuffle value type");
  unsigned EltSizeInBits = VT.getSizeInBits() / Size;

  // Extract known constant input data.
  APInt UndefSrcElts[2];
  SmallVector<APInt, 32> SrcEltBits[2];
  bool IsSrcConstant[2] = {
      getTargetConstantBitsFromNode(V1, EltSizeInBits, UndefSrcElts[0],
                                    SrcEltBits[0], true, false),
      getTargetConstantBitsFromNode(V2, EltSizeInBits, UndefSrcElts[1],
                                    SrcEltBits[1], true, false)};

  for (int i = 0; i < Size; ++i) {
    int M = Mask[i];

    // Already decoded as SM_SentinelZero / SM_SentinelUndef.
    if (M < 0) {
      assert(isUndefOrZero(M) && "Unknown shuffle sentinel value!");
      if (SM_SentinelUndef == M)
        KnownUndef.setBit(i);
      if (SM_SentinelZero == M)
        KnownZero.setBit(i);
      continue;
    }

    // Determine shuffle input and normalize the mask.
    unsigned SrcIdx = M / Size;
    SDValue V = M < Size ? V1 : V2;
    M %= Size;

    // We are referencing an UNDEF input.
    if (V.isUndef()) {
      KnownUndef.setBit(i);
      continue;
    }

    // SCALAR_TO_VECTOR - only the first element is defined, and the rest UNDEF.
    // TODO: We currently only set UNDEF for integer types - floats use the same
    // registers as vectors and many of the scalar folded loads rely on the
    // SCALAR_TO_VECTOR pattern.
    if (V.getOpcode() == ISD::SCALAR_TO_VECTOR &&
        (Size % V.getValueType().getVectorNumElements()) == 0) {
      int Scale = Size / V.getValueType().getVectorNumElements();
      int Idx = M / Scale;
      if (Idx != 0 && !VT.isFloatingPoint())
        KnownUndef.setBit(i);
      else if (Idx == 0 && X86::isZeroNode(V.getOperand(0)))
        KnownZero.setBit(i);
      continue;
    }

    // INSERT_SUBVECTOR - to widen vectors we often insert them into UNDEF
    // base vectors.
    if (V.getOpcode() == ISD::INSERT_SUBVECTOR) {
      SDValue Vec = V.getOperand(0);
      int NumVecElts = Vec.getValueType().getVectorNumElements();
      if (Vec.isUndef() && Size == NumVecElts) {
        auto *CIdx = dyn_cast<ConstantSDNode>(V.getOperand(2));
        int NumSubElts = V.getOperand(1).getValueType().getVectorNumElements();
        if (CIdx && CIdx->getAPIntValue().ule(NumVecElts - NumSubElts)) {
          int Idx = CIdx->getZExtValue();
          if (M < Idx || (Idx + NumSubElts) <= M) {
            KnownUndef.setBit(i);
          }
        }
      }
      continue;
    }

    // Attempt to extract from the source's constant bits.
    if (IsSrcConstant[SrcIdx]) {
      if (UndefSrcElts[SrcIdx][M])
        KnownUndef.setBit(i);
      else if (SrcEltBits[SrcIdx][M] == 0)
        KnownZero.setBit(i);
    }
  }

  assert(VT.getVectorNumElements() == (unsigned)Size &&
         "Different mask size from vector size!");
  return true;
}

// Replace target shuffle mask elements with known undef/zero sentinels.
static void resolveTargetShuffleFromZeroables(SmallVectorImpl<int> &Mask,
                                              const APInt &KnownUndef,
                                              const APInt &KnownZero,
                                              bool ResolveKnownZeros= true) {
  unsigned NumElts = Mask.size();
  assert(KnownUndef.getBitWidth() == NumElts &&
         KnownZero.getBitWidth() == NumElts && "Shuffle mask size mismatch");

  for (unsigned i = 0; i != NumElts; ++i) {
    if (KnownUndef[i])
      Mask[i] = SM_SentinelUndef;
    else if (ResolveKnownZeros && KnownZero[i])
      Mask[i] = SM_SentinelZero;
  }
}

// Extract target shuffle mask sentinel elements to known undef/zero bitmasks.
static void resolveZeroablesFromTargetShuffle(const SmallVectorImpl<int> &Mask,
                                              APInt &KnownUndef,
                                              APInt &KnownZero) {
  unsigned NumElts = Mask.size();
  KnownUndef = KnownZero = APInt::getNullValue(NumElts);

  for (unsigned i = 0; i != NumElts; ++i) {
    int M = Mask[i];
    if (SM_SentinelUndef == M)
      KnownUndef.setBit(i);
    if (SM_SentinelZero == M)
      KnownZero.setBit(i);
  }
}

// Forward declaration (for getFauxShuffleMask recursive check).
// TODO: Use DemandedElts variant.
static bool getTargetShuffleInputs(SDValue Op, SmallVectorImpl<SDValue> &Inputs,
                                   SmallVectorImpl<int> &Mask,
                                   SelectionDAG &DAG, unsigned Depth,
                                   bool ResolveKnownElts);

// Attempt to decode ops that could be represented as a shuffle mask.
// The decoded shuffle mask may contain a different number of elements to the
// destination value type.
static bool getFauxShuffleMask(SDValue N, const APInt &DemandedElts,
                               SmallVectorImpl<int> &Mask,
                               SmallVectorImpl<SDValue> &Ops,
                               SelectionDAG &DAG, unsigned Depth,
                               bool ResolveKnownElts) {
  Mask.clear();
  Ops.clear();

  MVT VT = N.getSimpleValueType();
  unsigned NumElts = VT.getVectorNumElements();
  unsigned NumSizeInBits = VT.getSizeInBits();
  unsigned NumBitsPerElt = VT.getScalarSizeInBits();
  if ((NumBitsPerElt % 8) != 0 || (NumSizeInBits % 8) != 0)
    return false;
  assert(NumElts == DemandedElts.getBitWidth() && "Unexpected vector size");
  unsigned NumSizeInBytes = NumSizeInBits / 8;
  unsigned NumBytesPerElt = NumBitsPerElt / 8;

  unsigned Opcode = N.getOpcode();
  switch (Opcode) {
  case ISD::VECTOR_SHUFFLE: {
    // Don't treat ISD::VECTOR_SHUFFLE as a target shuffle so decode it here.
    ArrayRef<int> ShuffleMask = cast<ShuffleVectorSDNode>(N)->getMask();
    if (isUndefOrInRange(ShuffleMask, 0, 2 * NumElts)) {
      Mask.append(ShuffleMask.begin(), ShuffleMask.end());
      Ops.push_back(N.getOperand(0));
      Ops.push_back(N.getOperand(1));
      return true;
    }
    return false;
  }
  case ISD::AND:
  case X86ISD::ANDNP: {
    // Attempt to decode as a per-byte mask.
    APInt UndefElts;
    SmallVector<APInt, 32> EltBits;
    SDValue N0 = N.getOperand(0);
    SDValue N1 = N.getOperand(1);
    bool IsAndN = (X86ISD::ANDNP == Opcode);
    uint64_t ZeroMask = IsAndN ? 255 : 0;
    if (!getTargetConstantBitsFromNode(IsAndN ? N0 : N1, 8, UndefElts, EltBits))
      return false;
    for (int i = 0, e = (int)EltBits.size(); i != e; ++i) {
      if (UndefElts[i]) {
        Mask.push_back(SM_SentinelUndef);
        continue;
      }
      const APInt &ByteBits = EltBits[i];
      if (ByteBits != 0 && ByteBits != 255)
        return false;
      Mask.push_back(ByteBits == ZeroMask ? SM_SentinelZero : i);
    }
    Ops.push_back(IsAndN ? N1 : N0);
    return true;
  }
  case ISD::OR: {
    // Inspect each operand at the byte level. We can merge these into a
    // blend shuffle mask if for each byte at least one is masked out (zero).
    KnownBits Known0 =
        DAG.computeKnownBits(N.getOperand(0), DemandedElts, Depth + 1);
    KnownBits Known1 =
        DAG.computeKnownBits(N.getOperand(1), DemandedElts, Depth + 1);
    if (Known0.One.isNullValue() && Known1.One.isNullValue()) {
      bool IsByteMask = true;
      APInt ZeroMask = APInt::getNullValue(NumBytesPerElt);
      APInt SelectMask = APInt::getNullValue(NumBytesPerElt);
      for (unsigned i = 0; i != NumBytesPerElt && IsByteMask; ++i) {
        unsigned LHS = Known0.Zero.extractBits(8, i * 8).getZExtValue();
        unsigned RHS = Known1.Zero.extractBits(8, i * 8).getZExtValue();
        if (LHS == 255 && RHS == 0)
          SelectMask.setBit(i);
        else if (LHS == 255 && RHS == 255)
          ZeroMask.setBit(i);
        else if (!(LHS == 0 && RHS == 255))
          IsByteMask = false;
      }
      if (IsByteMask) {
        for (unsigned i = 0; i != NumSizeInBytes; i += NumBytesPerElt) {
          for (unsigned j = 0; j != NumBytesPerElt; ++j) {
            unsigned Ofs = (SelectMask[j] ? NumSizeInBytes : 0);
            int Idx = (ZeroMask[j] ? (int)SM_SentinelZero : (i + j + Ofs));
            Mask.push_back(Idx);
          }
        }
        Ops.push_back(N.getOperand(0));
        Ops.push_back(N.getOperand(1));
        return true;
      }
    }

    // Handle OR(SHUFFLE,SHUFFLE) case where one source is zero and the other
    // is a valid shuffle index.
    SDValue N0 = peekThroughOneUseBitcasts(N.getOperand(0));
    SDValue N1 = peekThroughOneUseBitcasts(N.getOperand(1));
    if (!N0.getValueType().isVector() || !N1.getValueType().isVector())
      return false;
    SmallVector<int, 64> SrcMask0, SrcMask1;
    SmallVector<SDValue, 2> SrcInputs0, SrcInputs1;
    if (!getTargetShuffleInputs(N0, SrcInputs0, SrcMask0, DAG, Depth + 1,
                                true) ||
        !getTargetShuffleInputs(N1, SrcInputs1, SrcMask1, DAG, Depth + 1,
                                true))
      return false;

    // Shuffle inputs must be the same size as the result.
    if (llvm::any_of(SrcInputs0, [VT](SDValue Op) {
          return VT.getSizeInBits() != Op.getValueSizeInBits();
        }))
      return false;
    if (llvm::any_of(SrcInputs1, [VT](SDValue Op) {
          return VT.getSizeInBits() != Op.getValueSizeInBits();
        }))
      return false;

    size_t MaskSize = std::max(SrcMask0.size(), SrcMask1.size());
    SmallVector<int, 64> Mask0, Mask1;
    scaleShuffleMask(MaskSize / SrcMask0.size(), SrcMask0, Mask0);
    scaleShuffleMask(MaskSize / SrcMask1.size(), SrcMask1, Mask1);
    for (size_t i = 0; i != MaskSize; ++i) {
      if (Mask0[i] == SM_SentinelUndef && Mask1[i] == SM_SentinelUndef)
        Mask.push_back(SM_SentinelUndef);
      else if (Mask0[i] == SM_SentinelZero && Mask1[i] == SM_SentinelZero)
        Mask.push_back(SM_SentinelZero);
      else if (Mask1[i] == SM_SentinelZero)
        Mask.push_back(Mask0[i]);
      else if (Mask0[i] == SM_SentinelZero)
        Mask.push_back(Mask1[i] + (int)(MaskSize * SrcInputs0.size()));
      else
        return false;
    }
    Ops.append(SrcInputs0.begin(), SrcInputs0.end());
    Ops.append(SrcInputs1.begin(), SrcInputs1.end());
    return true;
  }
  case ISD::INSERT_SUBVECTOR: {
    SDValue Src = N.getOperand(0);
    SDValue Sub = N.getOperand(1);
    EVT SubVT = Sub.getValueType();
    unsigned NumSubElts = SubVT.getVectorNumElements();
    if (!isa<ConstantSDNode>(N.getOperand(2)) ||
        !N->isOnlyUserOf(Sub.getNode()))
      return false;
    uint64_t InsertIdx = N.getConstantOperandVal(2);
    // Handle INSERT_SUBVECTOR(SRC0, EXTRACT_SUBVECTOR(SRC1)).
    if (Sub.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
        Sub.getOperand(0).getValueType() == VT &&
        isa<ConstantSDNode>(Sub.getOperand(1))) {
      uint64_t ExtractIdx = Sub.getConstantOperandVal(1);
      for (int i = 0; i != (int)NumElts; ++i)
        Mask.push_back(i);
      for (int i = 0; i != (int)NumSubElts; ++i)
        Mask[InsertIdx + i] = NumElts + ExtractIdx + i;
      Ops.push_back(Src);
      Ops.push_back(Sub.getOperand(0));
      return true;
    }
    // Handle INSERT_SUBVECTOR(SRC0, SHUFFLE(SRC1)).
    SmallVector<int, 64> SubMask;
    SmallVector<SDValue, 2> SubInputs;
    if (!getTargetShuffleInputs(peekThroughOneUseBitcasts(Sub), SubInputs,
                                SubMask, DAG, Depth + 1, ResolveKnownElts))
      return false;

    // Shuffle inputs must be the same size as the subvector.
    if (llvm::any_of(SubInputs, [SubVT](SDValue Op) {
          return SubVT.getSizeInBits() != Op.getValueSizeInBits();
        }))
      return false;

    if (SubMask.size() != NumSubElts) {
      assert(((SubMask.size() % NumSubElts) == 0 ||
              (NumSubElts % SubMask.size()) == 0) && "Illegal submask scale");
      if ((NumSubElts % SubMask.size()) == 0) {
        int Scale = NumSubElts / SubMask.size();
        SmallVector<int,64> ScaledSubMask;
        scaleShuffleMask(Scale, SubMask, ScaledSubMask);
        SubMask = ScaledSubMask;
      } else {
        int Scale = SubMask.size() / NumSubElts;
        NumSubElts = SubMask.size();
        NumElts *= Scale;
        InsertIdx *= Scale;
      }
    }
    Ops.push_back(Src);
    for (SDValue &SubInput : SubInputs) {
      EVT SubSVT = SubInput.getValueType().getScalarType();
      EVT AltVT = EVT::getVectorVT(*DAG.getContext(), SubSVT,
                                   NumSizeInBits / SubSVT.getSizeInBits());
      Ops.push_back(DAG.getNode(ISD::INSERT_SUBVECTOR, SDLoc(N), AltVT,
                                DAG.getUNDEF(AltVT), SubInput,
                                DAG.getIntPtrConstant(0, SDLoc(N))));
    }
    for (int i = 0; i != (int)NumElts; ++i)
      Mask.push_back(i);
    for (int i = 0; i != (int)NumSubElts; ++i) {
      int M = SubMask[i];
      if (0 <= M) {
        int InputIdx = M / NumSubElts;
        M = (NumElts * (1 + InputIdx)) + (M % NumSubElts);
      }
      Mask[i + InsertIdx] = M;
    }
    return true;
  }
  case X86ISD::PINSRB:
  case X86ISD::PINSRW:
  case ISD::SCALAR_TO_VECTOR:
  case ISD::INSERT_VECTOR_ELT: {
    // Match against a insert_vector_elt/scalar_to_vector of an extract from a
    // vector, for matching src/dst vector types.
    SDValue Scl = N.getOperand(Opcode == ISD::SCALAR_TO_VECTOR ? 0 : 1);

    unsigned DstIdx = 0;
    if (Opcode != ISD::SCALAR_TO_VECTOR) {
      // Check we have an in-range constant insertion index.
      if (!isa<ConstantSDNode>(N.getOperand(2)) ||
          N.getConstantOperandAPInt(2).uge(NumElts))
        return false;
      DstIdx = N.getConstantOperandVal(2);

      // Attempt to recognise an INSERT*(VEC, 0, DstIdx) shuffle pattern.
      if (X86::isZeroNode(Scl)) {
        Ops.push_back(N.getOperand(0));
        for (unsigned i = 0; i != NumElts; ++i)
          Mask.push_back(i == DstIdx ? SM_SentinelZero : (int)i);
        return true;
      }
    }

    // Peek through trunc/aext/zext.
    // TODO: aext shouldn't require SM_SentinelZero padding.
    // TODO: handle shift of scalars.
    while (Scl.getOpcode() == ISD::TRUNCATE ||
           Scl.getOpcode() == ISD::ANY_EXTEND ||
           Scl.getOpcode() == ISD::ZERO_EXTEND)
      Scl = Scl.getOperand(0);

    // Attempt to find the source vector the scalar was extracted from.
    SDValue SrcExtract;
    if ((Scl.getOpcode() == ISD::EXTRACT_VECTOR_ELT ||
         Scl.getOpcode() == X86ISD::PEXTRW ||
         Scl.getOpcode() == X86ISD::PEXTRB) &&
        Scl.getOperand(0).getValueSizeInBits() == NumSizeInBits) {
      SrcExtract = Scl;
    }
    if (!SrcExtract || !isa<ConstantSDNode>(SrcExtract.getOperand(1)))
      return false;

    SDValue SrcVec = SrcExtract.getOperand(0);
    EVT SrcVT = SrcVec.getValueType();
    unsigned NumSrcElts = SrcVT.getVectorNumElements();
    unsigned NumZeros =
        std::max<int>((NumBitsPerElt / SrcVT.getScalarSizeInBits()) - 1, 0);

    if ((NumSrcElts % NumElts) != 0)
      return false;

    unsigned SrcIdx = SrcExtract.getConstantOperandVal(1);
    if (NumSrcElts <= SrcIdx)
      return false;

    if (Opcode == ISD::SCALAR_TO_VECTOR) {
      Ops.push_back(SrcVec);
      Mask.append(NumSrcElts, SM_SentinelUndef);
    } else {
      Ops.push_back(SrcVec);
      Ops.push_back(N.getOperand(0));
      for (int i = 0; i != (int)NumSrcElts; ++i)
        Mask.push_back(NumSrcElts + i);
    }

    int Scale = NumSrcElts / NumElts;
    Mask[Scale * DstIdx] = SrcIdx;
    for (int i = 0; i != (int)NumZeros; ++i)
      Mask[(Scale * DstIdx) + i + 1] = SM_SentinelZero;
    return true;
  }
  case X86ISD::PACKSS:
  case X86ISD::PACKUS: {
    SDValue N0 = N.getOperand(0);
    SDValue N1 = N.getOperand(1);
    assert(N0.getValueType().getVectorNumElements() == (NumElts / 2) &&
           N1.getValueType().getVectorNumElements() == (NumElts / 2) &&
           "Unexpected input value type");

    APInt EltsLHS, EltsRHS;
    getPackDemandedElts(VT, DemandedElts, EltsLHS, EltsRHS);

    // If we know input saturation won't happen we can treat this
    // as a truncation shuffle.
    if (Opcode == X86ISD::PACKSS) {
      if ((!N0.isUndef() &&
           DAG.ComputeNumSignBits(N0, EltsLHS, Depth + 1) <= NumBitsPerElt) ||
          (!N1.isUndef() &&
           DAG.ComputeNumSignBits(N1, EltsRHS, Depth + 1) <= NumBitsPerElt))
        return false;
    } else {
      APInt ZeroMask = APInt::getHighBitsSet(2 * NumBitsPerElt, NumBitsPerElt);
      if ((!N0.isUndef() &&
           !DAG.MaskedValueIsZero(N0, ZeroMask, EltsLHS, Depth + 1)) ||
          (!N1.isUndef() &&
           !DAG.MaskedValueIsZero(N1, ZeroMask, EltsRHS, Depth + 1)))
        return false;
    }

    bool IsUnary = (N0 == N1);

    Ops.push_back(N0);
    if (!IsUnary)
      Ops.push_back(N1);

    createPackShuffleMask(VT, Mask, IsUnary);
    return true;
  }
  case ISD::TRUNCATE:
  case X86ISD::VTRUNC: {
    SDValue Src = N.getOperand(0);
    EVT SrcVT = Src.getValueType();
    // Truncated source must be a simple vector.
    if (!SrcVT.isSimple() || (SrcVT.getSizeInBits() % 128) != 0 ||
        (SrcVT.getScalarSizeInBits() % 8) != 0)
      return false;
    unsigned NumSrcElts = SrcVT.getVectorNumElements();
    unsigned NumBitsPerSrcElt = SrcVT.getScalarSizeInBits();
    unsigned Scale = NumBitsPerSrcElt / NumBitsPerElt;
    assert((NumBitsPerSrcElt % NumBitsPerElt) == 0 && "Illegal truncation");
    for (unsigned i = 0; i != NumSrcElts; ++i)
      Mask.push_back(i * Scale);
    Mask.append(NumElts - NumSrcElts, SM_SentinelZero);
    Ops.push_back(Src);
    return true;
  }
  case X86ISD::VSHLI:
  case X86ISD::VSRLI: {
    uint64_t ShiftVal = N.getConstantOperandVal(1);
    // Out of range bit shifts are guaranteed to be zero.
    if (NumBitsPerElt <= ShiftVal) {
      Mask.append(NumElts, SM_SentinelZero);
      return true;
    }

    // We can only decode 'whole byte' bit shifts as shuffles.
    if ((ShiftVal % 8) != 0)
      break;

    uint64_t ByteShift = ShiftVal / 8;
    Ops.push_back(N.getOperand(0));

    // Clear mask to all zeros and insert the shifted byte indices.
    Mask.append(NumSizeInBytes, SM_SentinelZero);

    if (X86ISD::VSHLI == Opcode) {
      for (unsigned i = 0; i != NumSizeInBytes; i += NumBytesPerElt)
        for (unsigned j = ByteShift; j != NumBytesPerElt; ++j)
          Mask[i + j] = i + j - ByteShift;
    } else {
      for (unsigned i = 0; i != NumSizeInBytes; i += NumBytesPerElt)
        for (unsigned j = ByteShift; j != NumBytesPerElt; ++j)
          Mask[i + j - ByteShift] = i + j;
    }
    return true;
  }
  case X86ISD::VROTLI:
  case X86ISD::VROTRI: {
    // We can only decode 'whole byte' bit rotates as shuffles.
    uint64_t RotateVal = N.getConstantOperandAPInt(1).urem(NumBitsPerElt);
    if ((RotateVal % 8) != 0)
      return false;
    Ops.push_back(N.getOperand(0));
    int Offset = RotateVal / 8;
    Offset = (X86ISD::VROTLI == Opcode ? NumBytesPerElt - Offset : Offset);
    for (int i = 0; i != (int)NumElts; ++i) {
      int BaseIdx = i * NumBytesPerElt;
      for (int j = 0; j != (int)NumBytesPerElt; ++j) {
        Mask.push_back(BaseIdx + ((Offset + j) % NumBytesPerElt));
      }
    }
    return true;
  }
  case X86ISD::VBROADCAST: {
    SDValue Src = N.getOperand(0);
    MVT SrcVT = Src.getSimpleValueType();
    if (!SrcVT.isVector())
      return false;

    if (NumSizeInBits != SrcVT.getSizeInBits()) {
      assert((NumSizeInBits % SrcVT.getSizeInBits()) == 0 &&
             "Illegal broadcast type");
      SrcVT = MVT::getVectorVT(SrcVT.getScalarType(),
                               NumSizeInBits / SrcVT.getScalarSizeInBits());
      Src = DAG.getNode(ISD::INSERT_SUBVECTOR, SDLoc(N), SrcVT,
                        DAG.getUNDEF(SrcVT), Src,
                        DAG.getIntPtrConstant(0, SDLoc(N)));
    }

    Ops.push_back(Src);
    Mask.append(NumElts, 0);
    return true;
  }
  case ISD::ZERO_EXTEND:
  case ISD::ANY_EXTEND:
  case ISD::ZERO_EXTEND_VECTOR_INREG:
  case ISD::ANY_EXTEND_VECTOR_INREG: {
    SDValue Src = N.getOperand(0);
    EVT SrcVT = Src.getValueType();

    // Extended source must be a simple vector.
    if (!SrcVT.isSimple() || (SrcVT.getSizeInBits() % 128) != 0 ||
        (SrcVT.getScalarSizeInBits() % 8) != 0)
      return false;

    unsigned NumSrcBitsPerElt = SrcVT.getScalarSizeInBits();
    bool IsAnyExtend =
        (ISD::ANY_EXTEND == Opcode || ISD::ANY_EXTEND_VECTOR_INREG == Opcode);
    DecodeZeroExtendMask(NumSrcBitsPerElt, NumBitsPerElt, NumElts, IsAnyExtend,
                         Mask);

    if (NumSizeInBits != SrcVT.getSizeInBits()) {
      assert((NumSizeInBits % SrcVT.getSizeInBits()) == 0 &&
             "Illegal zero-extension type");
      SrcVT = MVT::getVectorVT(SrcVT.getSimpleVT().getScalarType(),
                               NumSizeInBits / NumSrcBitsPerElt);
      Src = DAG.getNode(ISD::INSERT_SUBVECTOR, SDLoc(N), SrcVT,
                        DAG.getUNDEF(SrcVT), Src,
                        DAG.getIntPtrConstant(0, SDLoc(N)));
    }

    Ops.push_back(Src);
    return true;
  }
  }

  return false;
}

/// Removes unused/repeated shuffle source inputs and adjusts the shuffle mask.
static void resolveTargetShuffleInputsAndMask(SmallVectorImpl<SDValue> &Inputs,
                                              SmallVectorImpl<int> &Mask) {
  int MaskWidth = Mask.size();
  SmallVector<SDValue, 16> UsedInputs;
  for (int i = 0, e = Inputs.size(); i < e; ++i) {
    int lo = UsedInputs.size() * MaskWidth;
    int hi = lo + MaskWidth;

    // Strip UNDEF input usage.
    if (Inputs[i].isUndef())
      for (int &M : Mask)
        if ((lo <= M) && (M < hi))
          M = SM_SentinelUndef;

    // Check for unused inputs.
    if (none_of(Mask, [lo, hi](int i) { return (lo <= i) && (i < hi); })) {
      for (int &M : Mask)
        if (lo <= M)
          M -= MaskWidth;
      continue;
    }

    // Check for repeated inputs.
    bool IsRepeat = false;
    for (int j = 0, ue = UsedInputs.size(); j != ue; ++j) {
      if (UsedInputs[j] != Inputs[i])
        continue;
      for (int &M : Mask)
        if (lo <= M)
          M = (M < hi) ? ((M - lo) + (j * MaskWidth)) : (M - MaskWidth);
      IsRepeat = true;
      break;
    }
    if (IsRepeat)
      continue;

    UsedInputs.push_back(Inputs[i]);
  }
  Inputs = UsedInputs;
}

/// Calls getTargetShuffleAndZeroables to resolve a target shuffle mask's inputs
/// and then sets the SM_SentinelUndef and SM_SentinelZero values.
/// Returns true if the target shuffle mask was decoded.
static bool getTargetShuffleInputs(SDValue Op, const APInt &DemandedElts,
                                   SmallVectorImpl<SDValue> &Inputs,
                                   SmallVectorImpl<int> &Mask,
                                   APInt &KnownUndef, APInt &KnownZero,
                                   SelectionDAG &DAG, unsigned Depth,
                                   bool ResolveKnownElts) {
  EVT VT = Op.getValueType();
  if (!VT.isSimple() || !VT.isVector())
    return false;

  if (getTargetShuffleAndZeroables(Op, Mask, Inputs, KnownUndef, KnownZero)) {
    if (ResolveKnownElts)
      resolveTargetShuffleFromZeroables(Mask, KnownUndef, KnownZero);
    return true;
  }
  if (getFauxShuffleMask(Op, DemandedElts, Mask, Inputs, DAG, Depth,
                         ResolveKnownElts)) {
    resolveZeroablesFromTargetShuffle(Mask, KnownUndef, KnownZero);
    return true;
  }
  return false;
}

static bool getTargetShuffleInputs(SDValue Op, SmallVectorImpl<SDValue> &Inputs,
                                   SmallVectorImpl<int> &Mask,
                                   SelectionDAG &DAG, unsigned Depth = 0,
                                   bool ResolveKnownElts = true) {
  EVT VT = Op.getValueType();
  if (!VT.isSimple() || !VT.isVector())
    return false;

  APInt KnownUndef, KnownZero;
  unsigned NumElts = Op.getValueType().getVectorNumElements();
  APInt DemandedElts = APInt::getAllOnesValue(NumElts);
  return getTargetShuffleInputs(Op, DemandedElts, Inputs, Mask, KnownUndef,
                                KnownZero, DAG, Depth, ResolveKnownElts);
}

/// Returns the scalar element that will make up the i'th
/// element of the result of the vector shuffle.
static SDValue getShuffleScalarElt(SDNode *N, unsigned Index, SelectionDAG &DAG,
                                   unsigned Depth) {
  if (Depth == 6)
    return SDValue();  // Limit search depth.

  SDValue V = SDValue(N, 0);
  EVT VT = V.getValueType();
  unsigned Opcode = V.getOpcode();

  // Recurse into ISD::VECTOR_SHUFFLE node to find scalars.
  if (const ShuffleVectorSDNode *SV = dyn_cast<ShuffleVectorSDNode>(N)) {
    int Elt = SV->getMaskElt(Index);

    if (Elt < 0)
      return DAG.getUNDEF(VT.getVectorElementType());

    unsigned NumElems = VT.getVectorNumElements();
    SDValue NewV = (Elt < (int)NumElems) ? SV->getOperand(0)
                                         : SV->getOperand(1);
    return getShuffleScalarElt(NewV.getNode(), Elt % NumElems, DAG, Depth+1);
  }

  // Recurse into target specific vector shuffles to find scalars.
  if (isTargetShuffle(Opcode)) {
    MVT ShufVT = V.getSimpleValueType();
    MVT ShufSVT = ShufVT.getVectorElementType();
    int NumElems = (int)ShufVT.getVectorNumElements();
    SmallVector<int, 16> ShuffleMask;
    SmallVector<SDValue, 16> ShuffleOps;
    bool IsUnary;

    if (!getTargetShuffleMask(N, ShufVT, true, ShuffleOps, ShuffleMask, IsUnary))
      return SDValue();

    int Elt = ShuffleMask[Index];
    if (Elt == SM_SentinelZero)
      return ShufSVT.isInteger() ? DAG.getConstant(0, SDLoc(N), ShufSVT)
                                 : DAG.getConstantFP(+0.0, SDLoc(N), ShufSVT);
    if (Elt == SM_SentinelUndef)
      return DAG.getUNDEF(ShufSVT);

    assert(0 <= Elt && Elt < (2*NumElems) && "Shuffle index out of range");
    SDValue NewV = (Elt < NumElems) ? ShuffleOps[0] : ShuffleOps[1];
    return getShuffleScalarElt(NewV.getNode(), Elt % NumElems, DAG,
                               Depth+1);
  }

  // Recurse into insert_subvector base/sub vector to find scalars.
  if (Opcode == ISD::INSERT_SUBVECTOR &&
      isa<ConstantSDNode>(N->getOperand(2))) {
    SDValue Vec = N->getOperand(0);
    SDValue Sub = N->getOperand(1);
    EVT SubVT = Sub.getValueType();
    unsigned NumSubElts = SubVT.getVectorNumElements();
    uint64_t SubIdx = N->getConstantOperandVal(2);

    if (SubIdx <= Index && Index < (SubIdx + NumSubElts))
      return getShuffleScalarElt(Sub.getNode(), Index - SubIdx, DAG, Depth + 1);
    return getShuffleScalarElt(Vec.getNode(), Index, DAG, Depth + 1);
  }

  // Recurse into extract_subvector src vector to find scalars.
  if (Opcode == ISD::EXTRACT_SUBVECTOR &&
      isa<ConstantSDNode>(N->getOperand(1))) {
    SDValue Src = N->getOperand(0);
    uint64_t SrcIdx = N->getConstantOperandVal(1);
    return getShuffleScalarElt(Src.getNode(), Index + SrcIdx, DAG, Depth + 1);
  }

  // Actual nodes that may contain scalar elements
  if (Opcode == ISD::BITCAST) {
    V = V.getOperand(0);
    EVT SrcVT = V.getValueType();
    unsigned NumElems = VT.getVectorNumElements();

    if (!SrcVT.isVector() || SrcVT.getVectorNumElements() != NumElems)
      return SDValue();
  }

  if (V.getOpcode() == ISD::SCALAR_TO_VECTOR)
    return (Index == 0) ? V.getOperand(0)
                        : DAG.getUNDEF(VT.getVectorElementType());

  if (V.getOpcode() == ISD::BUILD_VECTOR)
    return V.getOperand(Index);

  return SDValue();
}

// Use PINSRB/PINSRW/PINSRD to create a build vector.
static SDValue LowerBuildVectorAsInsert(SDValue Op, unsigned NonZeros,
                                        unsigned NumNonZero, unsigned NumZero,
                                        SelectionDAG &DAG,
                                        const X86Subtarget &Subtarget) {
  MVT VT = Op.getSimpleValueType();
  unsigned NumElts = VT.getVectorNumElements();
  assert(((VT == MVT::v8i16 && Subtarget.hasSSE2()) ||
          ((VT == MVT::v16i8 || VT == MVT::v4i32) && Subtarget.hasSSE41())) &&
         "Illegal vector insertion");

  SDLoc dl(Op);
  SDValue V;
  bool First = true;

  for (unsigned i = 0; i < NumElts; ++i) {
    bool IsNonZero = (NonZeros & (1 << i)) != 0;
    if (!IsNonZero)
      continue;

    // If the build vector contains zeros or our first insertion is not the
    // first index then insert into zero vector to break any register
    // dependency else use SCALAR_TO_VECTOR.
    if (First) {
      First = false;
      if (NumZero || 0 != i)
        V = getZeroVector(VT, Subtarget, DAG, dl);
      else {
        assert(0 == i && "Expected insertion into zero-index");
        V = DAG.getAnyExtOrTrunc(Op.getOperand(i), dl, MVT::i32);
        V = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v4i32, V);
        V = DAG.getBitcast(VT, V);
        continue;
      }
    }
    V = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, V, Op.getOperand(i),
                    DAG.getIntPtrConstant(i, dl));
  }

  return V;
}

/// Custom lower build_vector of v16i8.
static SDValue LowerBuildVectorv16i8(SDValue Op, unsigned NonZeros,
                                     unsigned NumNonZero, unsigned NumZero,
                                     SelectionDAG &DAG,
                                     const X86Subtarget &Subtarget) {
  if (NumNonZero > 8 && !Subtarget.hasSSE41())
    return SDValue();

  // SSE4.1 - use PINSRB to insert each byte directly.
  if (Subtarget.hasSSE41())
    return LowerBuildVectorAsInsert(Op, NonZeros, NumNonZero, NumZero, DAG,
                                    Subtarget);

  SDLoc dl(Op);
  SDValue V;

  // Pre-SSE4.1 - merge byte pairs and insert with PINSRW.
  for (unsigned i = 0; i < 16; i += 2) {
    bool ThisIsNonZero = (NonZeros & (1 << i)) != 0;
    bool NextIsNonZero = (NonZeros & (1 << (i + 1))) != 0;
    if (!ThisIsNonZero && !NextIsNonZero)
      continue;

    // FIXME: Investigate combining the first 4 bytes as a i32 instead.
    SDValue Elt;
    if (ThisIsNonZero) {
      if (NumZero || NextIsNonZero)
        Elt = DAG.getZExtOrTrunc(Op.getOperand(i), dl, MVT::i32);
      else
        Elt = DAG.getAnyExtOrTrunc(Op.getOperand(i), dl, MVT::i32);
    }

    if (NextIsNonZero) {
      SDValue NextElt = Op.getOperand(i + 1);
      if (i == 0 && NumZero)
        NextElt = DAG.getZExtOrTrunc(NextElt, dl, MVT::i32);
      else
        NextElt = DAG.getAnyExtOrTrunc(NextElt, dl, MVT::i32);
      NextElt = DAG.getNode(ISD::SHL, dl, MVT::i32, NextElt,
                            DAG.getConstant(8, dl, MVT::i8));
      if (ThisIsNonZero)
        Elt = DAG.getNode(ISD::OR, dl, MVT::i32, NextElt, Elt);
      else
        Elt = NextElt;
    }

    // If our first insertion is not the first index then insert into zero
    // vector to break any register dependency else use SCALAR_TO_VECTOR.
    if (!V) {
      if (i != 0)
        V = getZeroVector(MVT::v8i16, Subtarget, DAG, dl);
      else {
        V = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v4i32, Elt);
        V = DAG.getBitcast(MVT::v8i16, V);
        continue;
      }
    }
    Elt = DAG.getNode(ISD::TRUNCATE, dl, MVT::i16, Elt);
    V = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v8i16, V, Elt,
                    DAG.getIntPtrConstant(i / 2, dl));
  }

  return DAG.getBitcast(MVT::v16i8, V);
}

/// Custom lower build_vector of v8i16.
static SDValue LowerBuildVectorv8i16(SDValue Op, unsigned NonZeros,
                                     unsigned NumNonZero, unsigned NumZero,
                                     SelectionDAG &DAG,
                                     const X86Subtarget &Subtarget) {
  if (NumNonZero > 4 && !Subtarget.hasSSE41())
    return SDValue();

  // Use PINSRW to insert each byte directly.
  return LowerBuildVectorAsInsert(Op, NonZeros, NumNonZero, NumZero, DAG,
                                  Subtarget);
}

/// Custom lower build_vector of v4i32 or v4f32.
static SDValue LowerBuildVectorv4x32(SDValue Op, SelectionDAG &DAG,
                                     const X86Subtarget &Subtarget) {
  // If this is a splat of a pair of elements, use MOVDDUP (unless the target
  // has XOP; in that case defer lowering to potentially use VPERMIL2PS).
  // Because we're creating a less complicated build vector here, we may enable
  // further folding of the MOVDDUP via shuffle transforms.
  if (Subtarget.hasSSE3() && !Subtarget.hasXOP() &&
      Op.getOperand(0) == Op.getOperand(2) &&
      Op.getOperand(1) == Op.getOperand(3) &&
      Op.getOperand(0) != Op.getOperand(1)) {
    SDLoc DL(Op);
    MVT VT = Op.getSimpleValueType();
    MVT EltVT = VT.getVectorElementType();
    // Create a new build vector with the first 2 elements followed by undef
    // padding, bitcast to v2f64, duplicate, and bitcast back.
    SDValue Ops[4] = { Op.getOperand(0), Op.getOperand(1),
                       DAG.getUNDEF(EltVT), DAG.getUNDEF(EltVT) };
    SDValue NewBV = DAG.getBitcast(MVT::v2f64, DAG.getBuildVector(VT, DL, Ops));
    SDValue Dup = DAG.getNode(X86ISD::MOVDDUP, DL, MVT::v2f64, NewBV);
    return DAG.getBitcast(VT, Dup);
  }

  // Find all zeroable elements.
  std::bitset<4> Zeroable, Undefs;
  for (int i = 0; i < 4; ++i) {
    SDValue Elt = Op.getOperand(i);
    Undefs[i] = Elt.isUndef();
    Zeroable[i] = (Elt.isUndef() || X86::isZeroNode(Elt));
  }
  assert(Zeroable.size() - Zeroable.count() > 1 &&
         "We expect at least two non-zero elements!");

  // We only know how to deal with build_vector nodes where elements are either
  // zeroable or extract_vector_elt with constant index.
  SDValue FirstNonZero;
  unsigned FirstNonZeroIdx;
  for (unsigned i = 0; i < 4; ++i) {
    if (Zeroable[i])
      continue;
    SDValue Elt = Op.getOperand(i);
    if (Elt.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
        !isa<ConstantSDNode>(Elt.getOperand(1)))
      return SDValue();
    // Make sure that this node is extracting from a 128-bit vector.
    MVT VT = Elt.getOperand(0).getSimpleValueType();
    if (!VT.is128BitVector())
      return SDValue();
    if (!FirstNonZero.getNode()) {
      FirstNonZero = Elt;
      FirstNonZeroIdx = i;
    }
  }

  assert(FirstNonZero.getNode() && "Unexpected build vector of all zeros!");
  SDValue V1 = FirstNonZero.getOperand(0);
  MVT VT = V1.getSimpleValueType();

  // See if this build_vector can be lowered as a blend with zero.
  SDValue Elt;
  unsigned EltMaskIdx, EltIdx;
  int Mask[4];
  for (EltIdx = 0; EltIdx < 4; ++EltIdx) {
    if (Zeroable[EltIdx]) {
      // The zero vector will be on the right hand side.
      Mask[EltIdx] = EltIdx+4;
      continue;
    }

    Elt = Op->getOperand(EltIdx);
    // By construction, Elt is a EXTRACT_VECTOR_ELT with constant index.
    EltMaskIdx = Elt.getConstantOperandVal(1);
    if (Elt.getOperand(0) != V1 || EltMaskIdx != EltIdx)
      break;
    Mask[EltIdx] = EltIdx;
  }

  if (EltIdx == 4) {
    // Let the shuffle legalizer deal with blend operations.
    SDValue VZeroOrUndef = (Zeroable == Undefs)
                               ? DAG.getUNDEF(VT)
                               : getZeroVector(VT, Subtarget, DAG, SDLoc(Op));
    if (V1.getSimpleValueType() != VT)
      V1 = DAG.getBitcast(VT, V1);
    return DAG.getVectorShuffle(VT, SDLoc(V1), V1, VZeroOrUndef, Mask);
  }

  // See if we can lower this build_vector to a INSERTPS.
  if (!Subtarget.hasSSE41())
    return SDValue();

  SDValue V2 = Elt.getOperand(0);
  if (Elt == FirstNonZero && EltIdx == FirstNonZeroIdx)
    V1 = SDValue();

  bool CanFold = true;
  for (unsigned i = EltIdx + 1; i < 4 && CanFold; ++i) {
    if (Zeroable[i])
      continue;

    SDValue Current = Op->getOperand(i);
    SDValue SrcVector = Current->getOperand(0);
    if (!V1.getNode())
      V1 = SrcVector;
    CanFold = (SrcVector == V1) && (Current.getConstantOperandAPInt(1) == i);
  }

  if (!CanFold)
    return SDValue();

  assert(V1.getNode() && "Expected at least two non-zero elements!");
  if (V1.getSimpleValueType() != MVT::v4f32)
    V1 = DAG.getBitcast(MVT::v4f32, V1);
  if (V2.getSimpleValueType() != MVT::v4f32)
    V2 = DAG.getBitcast(MVT::v4f32, V2);

  // Ok, we can emit an INSERTPS instruction.
  unsigned ZMask = Zeroable.to_ulong();

  unsigned InsertPSMask = EltMaskIdx << 6 | EltIdx << 4 | ZMask;
  assert((InsertPSMask & ~0xFFu) == 0 && "Invalid mask!");
  SDLoc DL(Op);
  SDValue Result = DAG.getNode(X86ISD::INSERTPS, DL, MVT::v4f32, V1, V2,
                               DAG.getIntPtrConstant(InsertPSMask, DL, true));
  return DAG.getBitcast(VT, Result);
}

/// Return a vector logical shift node.
static SDValue getVShift(bool isLeft, EVT VT, SDValue SrcOp, unsigned NumBits,
                         SelectionDAG &DAG, const TargetLowering &TLI,
                         const SDLoc &dl) {
  assert(VT.is128BitVector() && "Unknown type for VShift");
  MVT ShVT = MVT::v16i8;
  unsigned Opc = isLeft ? X86ISD::VSHLDQ : X86ISD::VSRLDQ;
  SrcOp = DAG.getBitcast(ShVT, SrcOp);
  assert(NumBits % 8 == 0 && "Only support byte sized shifts");
  SDValue ShiftVal = DAG.getTargetConstant(NumBits / 8, dl, MVT::i8);
  return DAG.getBitcast(VT, DAG.getNode(Opc, dl, ShVT, SrcOp, ShiftVal));
}

static SDValue LowerAsSplatVectorLoad(SDValue SrcOp, MVT VT, const SDLoc &dl,
                                      SelectionDAG &DAG) {

  // Check if the scalar load can be widened into a vector load. And if
  // the address is "base + cst" see if the cst can be "absorbed" into
  // the shuffle mask.
  if (LoadSDNode *LD = dyn_cast<LoadSDNode>(SrcOp)) {
    SDValue Ptr = LD->getBasePtr();
    if (!ISD::isNormalLoad(LD) || !LD->isSimple())
      return SDValue();
    EVT PVT = LD->getValueType(0);
    if (PVT != MVT::i32 && PVT != MVT::f32)
      return SDValue();

    int FI = -1;
    int64_t Offset = 0;
    if (FrameIndexSDNode *FINode = dyn_cast<FrameIndexSDNode>(Ptr)) {
      FI = FINode->getIndex();
      Offset = 0;
    } else if (DAG.isBaseWithConstantOffset(Ptr) &&
               isa<FrameIndexSDNode>(Ptr.getOperand(0))) {
      FI = cast<FrameIndexSDNode>(Ptr.getOperand(0))->getIndex();
      Offset = Ptr.getConstantOperandVal(1);
      Ptr = Ptr.getOperand(0);
    } else {
      return SDValue();
    }

    // FIXME: 256-bit vector instructions don't require a strict alignment,
    // improve this code to support it better.
    Align RequiredAlign(VT.getSizeInBits() / 8);
    SDValue Chain = LD->getChain();
    // Make sure the stack object alignment is at least 16 or 32.
    MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
    if (DAG.InferPtrAlign(Ptr) < RequiredAlign) {
      if (MFI.isFixedObjectIndex(FI)) {
        // Can't change the alignment. FIXME: It's possible to compute
        // the exact stack offset and reference FI + adjust offset instead.
        // If someone *really* cares about this. That's the way to implement it.
        return SDValue();
      } else {
        MFI.setObjectAlignment(FI, RequiredAlign);
      }
    }

    // (Offset % 16 or 32) must be multiple of 4. Then address is then
    // Ptr + (Offset & ~15).
    if (Offset < 0)
      return SDValue();
    if ((Offset % RequiredAlign.value()) & 3)
      return SDValue();
    int64_t StartOffset = Offset & ~int64_t(RequiredAlign.value() - 1);
    if (StartOffset) {
      SDLoc DL(Ptr);
      Ptr = DAG.getNode(ISD::ADD, DL, Ptr.getValueType(), Ptr,
                        DAG.getConstant(StartOffset, DL, Ptr.getValueType()));
    }

    int EltNo = (Offset - StartOffset) >> 2;
    unsigned NumElems = VT.getVectorNumElements();

    EVT NVT = EVT::getVectorVT(*DAG.getContext(), PVT, NumElems);
    SDValue V1 = DAG.getLoad(NVT, dl, Chain, Ptr,
                             LD->getPointerInfo().getWithOffset(StartOffset));

    SmallVector<int, 8> Mask(NumElems, EltNo);

    return DAG.getVectorShuffle(NVT, dl, V1, DAG.getUNDEF(NVT), Mask);
  }

  return SDValue();
}

// Recurse to find a LoadSDNode source and the accumulated ByteOffest.
static bool findEltLoadSrc(SDValue Elt, LoadSDNode *&Ld, int64_t &ByteOffset) {
  if (ISD::isNON_EXTLoad(Elt.getNode())) {
    auto *BaseLd = cast<LoadSDNode>(Elt);
    if (!BaseLd->isSimple())
      return false;
    Ld = BaseLd;
    ByteOffset = 0;
    return true;
  }

  switch (Elt.getOpcode()) {
  case ISD::BITCAST:
  case ISD::TRUNCATE:
  case ISD::SCALAR_TO_VECTOR:
    return findEltLoadSrc(Elt.getOperand(0), Ld, ByteOffset);
  case ISD::SRL:
    if (isa<ConstantSDNode>(Elt.getOperand(1))) {
      uint64_t Idx = Elt.getConstantOperandVal(1);
      if ((Idx % 8) == 0 && findEltLoadSrc(Elt.getOperand(0), Ld, ByteOffset)) {
        ByteOffset += Idx / 8;
        return true;
      }
    }
    break;
  case ISD::EXTRACT_VECTOR_ELT:
    if (isa<ConstantSDNode>(Elt.getOperand(1))) {
      SDValue Src = Elt.getOperand(0);
      unsigned SrcSizeInBits = Src.getScalarValueSizeInBits();
      unsigned DstSizeInBits = Elt.getScalarValueSizeInBits();
      if (DstSizeInBits == SrcSizeInBits && (SrcSizeInBits % 8) == 0 &&
          findEltLoadSrc(Src, Ld, ByteOffset)) {
        uint64_t Idx = Elt.getConstantOperandVal(1);
        ByteOffset += Idx * (SrcSizeInBits / 8);
        return true;
      }
    }
    break;
  }

  return false;
}

/// Given the initializing elements 'Elts' of a vector of type 'VT', see if the
/// elements can be replaced by a single large load which has the same value as
/// a build_vector or insert_subvector whose loaded operands are 'Elts'.
///
/// Example: <load i32 *a, load i32 *a+4, zero, undef> -> zextload a
static SDValue EltsFromConsecutiveLoads(EVT VT, ArrayRef<SDValue> Elts,
                                        const SDLoc &DL, SelectionDAG &DAG,
                                        const X86Subtarget &Subtarget,
                                        bool isAfterLegalize) {
  if ((VT.getScalarSizeInBits() % 8) != 0)
    return SDValue();

  unsigned NumElems = Elts.size();

  int LastLoadedElt = -1;
  APInt LoadMask = APInt::getNullValue(NumElems);
  APInt ZeroMask = APInt::getNullValue(NumElems);
  APInt UndefMask = APInt::getNullValue(NumElems);

  SmallVector<LoadSDNode*, 8> Loads(NumElems, nullptr);
  SmallVector<int64_t, 8> ByteOffsets(NumElems, 0);

  // For each element in the initializer, see if we've found a load, zero or an
  // undef.
  for (unsigned i = 0; i < NumElems; ++i) {
    SDValue Elt = peekThroughBitcasts(Elts[i]);
    if (!Elt.getNode())
      return SDValue();
    if (Elt.isUndef()) {
      UndefMask.setBit(i);
      continue;
    }
    if (X86::isZeroNode(Elt) || ISD::isBuildVectorAllZeros(Elt.getNode())) {
      ZeroMask.setBit(i);
      continue;
    }

    // Each loaded element must be the correct fractional portion of the
    // requested vector load.
    unsigned EltSizeInBits = Elt.getValueSizeInBits();
    if ((NumElems * EltSizeInBits) != VT.getSizeInBits())
      return SDValue();

    if (!findEltLoadSrc(Elt, Loads[i], ByteOffsets[i]) || ByteOffsets[i] < 0)
      return SDValue();
    unsigned LoadSizeInBits = Loads[i]->getValueSizeInBits(0);
    if (((ByteOffsets[i] * 8) + EltSizeInBits) > LoadSizeInBits)
      return SDValue();

    LoadMask.setBit(i);
    LastLoadedElt = i;
  }
  assert((ZeroMask.countPopulation() + UndefMask.countPopulation() +
          LoadMask.countPopulation()) == NumElems &&
         "Incomplete element masks");

  // Handle Special Cases - all undef or undef/zero.
  if (UndefMask.countPopulation() == NumElems)
    return DAG.getUNDEF(VT);

  // FIXME: Should we return this as a BUILD_VECTOR instead?
  if ((ZeroMask.countPopulation() + UndefMask.countPopulation()) == NumElems)
    return VT.isInteger() ? DAG.getConstant(0, DL, VT)
                          : DAG.getConstantFP(0.0, DL, VT);

  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  int FirstLoadedElt = LoadMask.countTrailingZeros();
  SDValue EltBase = peekThroughBitcasts(Elts[FirstLoadedElt]);
  EVT EltBaseVT = EltBase.getValueType();
  assert(EltBaseVT.getSizeInBits() == EltBaseVT.getStoreSizeInBits() &&
         "Register/Memory size mismatch");
  LoadSDNode *LDBase = Loads[FirstLoadedElt];
  assert(LDBase && "Did not find base load for merging consecutive loads");
  unsigned BaseSizeInBits = EltBaseVT.getStoreSizeInBits();
  unsigned BaseSizeInBytes = BaseSizeInBits / 8;
  int LoadSizeInBits = (1 + LastLoadedElt - FirstLoadedElt) * BaseSizeInBits;
  assert((BaseSizeInBits % 8) == 0 && "Sub-byte element loads detected");

  // TODO: Support offsetting the base load.
  if (ByteOffsets[FirstLoadedElt] != 0)
    return SDValue();

  // Check to see if the element's load is consecutive to the base load
  // or offset from a previous (already checked) load.
  auto CheckConsecutiveLoad = [&](LoadSDNode *Base, int EltIdx) {
    LoadSDNode *Ld = Loads[EltIdx];
    int64_t ByteOffset = ByteOffsets[EltIdx];
    if (ByteOffset && (ByteOffset % BaseSizeInBytes) == 0) {
      int64_t BaseIdx = EltIdx - (ByteOffset / BaseSizeInBytes);
      return (0 <= BaseIdx && BaseIdx < (int)NumElems && LoadMask[BaseIdx] &&
              Loads[BaseIdx] == Ld && ByteOffsets[BaseIdx] == 0);
    }
    return DAG.areNonVolatileConsecutiveLoads(Ld, Base, BaseSizeInBytes,
                                              EltIdx - FirstLoadedElt);
  };

  // Consecutive loads can contain UNDEFS but not ZERO elements.
  // Consecutive loads with UNDEFs and ZEROs elements require a
  // an additional shuffle stage to clear the ZERO elements.
  bool IsConsecutiveLoad = true;
  bool IsConsecutiveLoadWithZeros = true;
  for (int i = FirstLoadedElt + 1; i <= LastLoadedElt; ++i) {
    if (LoadMask[i]) {
      if (!CheckConsecutiveLoad(LDBase, i)) {
        IsConsecutiveLoad = false;
        IsConsecutiveLoadWithZeros = false;
        break;
      }
    } else if (ZeroMask[i]) {
      IsConsecutiveLoad = false;
    }
  }

  auto CreateLoad = [&DAG, &DL, &Loads](EVT VT, LoadSDNode *LDBase) {
    auto MMOFlags = LDBase->getMemOperand()->getFlags();
    assert(LDBase->isSimple() &&
           "Cannot merge volatile or atomic loads.");
    SDValue NewLd =
        DAG.getLoad(VT, DL, LDBase->getChain(), LDBase->getBasePtr(),
                    LDBase->getPointerInfo(), LDBase->getAlignment(), MMOFlags);
    for (auto *LD : Loads)
      if (LD)
        DAG.makeEquivalentMemoryOrdering(LD, NewLd);
    return NewLd;
  };

  // Check if the base load is entirely dereferenceable.
  bool IsDereferenceable = LDBase->getPointerInfo().isDereferenceable(
      VT.getSizeInBits() / 8, *DAG.getContext(), DAG.getDataLayout());

  // LOAD - all consecutive load/undefs (must start/end with a load or be
  // entirely dereferenceable). If we have found an entire vector of loads and
  // undefs, then return a large load of the entire vector width starting at the
  // base pointer. If the vector contains zeros, then attempt to shuffle those
  // elements.
  if (FirstLoadedElt == 0 &&
      (LastLoadedElt == (int)(NumElems - 1) || IsDereferenceable) &&
      (IsConsecutiveLoad || IsConsecutiveLoadWithZeros)) {
    if (isAfterLegalize && !TLI.isOperationLegal(ISD::LOAD, VT))
      return SDValue();

    // Don't create 256-bit non-temporal aligned loads without AVX2 as these
    // will lower to regular temporal loads and use the cache.
    if (LDBase->isNonTemporal() && LDBase->getAlignment() >= 32 &&
        VT.is256BitVector() && !Subtarget.hasInt256())
      return SDValue();

    if (NumElems == 1)
      return DAG.getBitcast(VT, Elts[FirstLoadedElt]);

    if (!ZeroMask)
      return CreateLoad(VT, LDBase);

    // IsConsecutiveLoadWithZeros - we need to create a shuffle of the loaded
    // vector and a zero vector to clear out the zero elements.
    if (!isAfterLegalize && VT.isVector()) {
      unsigned NumMaskElts = VT.getVectorNumElements();
      if ((NumMaskElts % NumElems) == 0) {
        unsigned Scale = NumMaskElts / NumElems;
        SmallVector<int, 4> ClearMask(NumMaskElts, -1);
        for (unsigned i = 0; i < NumElems; ++i) {
          if (UndefMask[i])
            continue;
          int Offset = ZeroMask[i] ? NumMaskElts : 0;
          for (unsigned j = 0; j != Scale; ++j)
            ClearMask[(i * Scale) + j] = (i * Scale) + j + Offset;
        }
        SDValue V = CreateLoad(VT, LDBase);
        SDValue Z = VT.isInteger() ? DAG.getConstant(0, DL, VT)
                                   : DAG.getConstantFP(0.0, DL, VT);
        return DAG.getVectorShuffle(VT, DL, V, Z, ClearMask);
      }
    }
  }

  // If the upper half of a ymm/zmm load is undef then just load the lower half.
  if (VT.is256BitVector() || VT.is512BitVector()) {
    unsigned HalfNumElems = NumElems / 2;
    if (UndefMask.extractBits(HalfNumElems, HalfNumElems).isAllOnesValue()) {
      EVT HalfVT =
          EVT::getVectorVT(*DAG.getContext(), VT.getScalarType(), HalfNumElems);
      SDValue HalfLD =
          EltsFromConsecutiveLoads(HalfVT, Elts.drop_back(HalfNumElems), DL,
                                   DAG, Subtarget, isAfterLegalize);
      if (HalfLD)
        return DAG.getNode(ISD::INSERT_SUBVECTOR, DL, VT, DAG.getUNDEF(VT),
                           HalfLD, DAG.getIntPtrConstant(0, DL));
    }
  }

  // VZEXT_LOAD - consecutive 32/64-bit load/undefs followed by zeros/undefs.
  if (IsConsecutiveLoad && FirstLoadedElt == 0 &&
      (LoadSizeInBits == 32 || LoadSizeInBits == 64) &&
      ((VT.is128BitVector() || VT.is256BitVector() || VT.is512BitVector()))) {
    MVT VecSVT = VT.isFloatingPoint() ? MVT::getFloatingPointVT(LoadSizeInBits)
                                      : MVT::getIntegerVT(LoadSizeInBits);
    MVT VecVT = MVT::getVectorVT(VecSVT, VT.getSizeInBits() / LoadSizeInBits);
    // Allow v4f32 on SSE1 only targets.
    // FIXME: Add more isel patterns so we can just use VT directly.
    if (!Subtarget.hasSSE2() && VT == MVT::v4f32)
      VecVT = MVT::v4f32;
    if (TLI.isTypeLegal(VecVT)) {
      SDVTList Tys = DAG.getVTList(VecVT, MVT::Other);
      SDValue Ops[] = { LDBase->getChain(), LDBase->getBasePtr() };
      SDValue ResNode = DAG.getMemIntrinsicNode(
          X86ISD::VZEXT_LOAD, DL, Tys, Ops, VecSVT, LDBase->getPointerInfo(),
          LDBase->getAlign(), MachineMemOperand::MOLoad);
      for (auto *LD : Loads)
        if (LD)
          DAG.makeEquivalentMemoryOrdering(LD, ResNode);
      return DAG.getBitcast(VT, ResNode);
    }
  }

  // BROADCAST - match the smallest possible repetition pattern, load that
  // scalar/subvector element and then broadcast to the entire vector.
  if (ZeroMask.isNullValue() && isPowerOf2_32(NumElems) && Subtarget.hasAVX() &&
      (VT.is128BitVector() || VT.is256BitVector() || VT.is512BitVector())) {
    for (unsigned SubElems = 1; SubElems < NumElems; SubElems *= 2) {
      unsigned RepeatSize = SubElems * BaseSizeInBits;
      unsigned ScalarSize = std::min(RepeatSize, 64u);
      if (!Subtarget.hasAVX2() && ScalarSize < 32)
        continue;

      bool Match = true;
      SmallVector<SDValue, 8> RepeatedLoads(SubElems, DAG.getUNDEF(EltBaseVT));
      for (unsigned i = 0; i != NumElems && Match; ++i) {
        if (!LoadMask[i])
          continue;
        SDValue Elt = peekThroughBitcasts(Elts[i]);
        if (RepeatedLoads[i % SubElems].isUndef())
          RepeatedLoads[i % SubElems] = Elt;
        else
          Match &= (RepeatedLoads[i % SubElems] == Elt);
      }

      // We must have loads at both ends of the repetition.
      Match &= !RepeatedLoads.front().isUndef();
      Match &= !RepeatedLoads.back().isUndef();
      if (!Match)
        continue;

      EVT RepeatVT =
          VT.isInteger() && (RepeatSize != 64 || TLI.isTypeLegal(MVT::i64))
              ? EVT::getIntegerVT(*DAG.getContext(), ScalarSize)
              : EVT::getFloatingPointVT(ScalarSize);
      if (RepeatSize > ScalarSize)
        RepeatVT = EVT::getVectorVT(*DAG.getContext(), RepeatVT,
                                    RepeatSize / ScalarSize);
      EVT BroadcastVT =
          EVT::getVectorVT(*DAG.getContext(), RepeatVT.getScalarType(),
                           VT.getSizeInBits() / ScalarSize);
      if (TLI.isTypeLegal(BroadcastVT)) {
        if (SDValue RepeatLoad = EltsFromConsecutiveLoads(
                RepeatVT, RepeatedLoads, DL, DAG, Subtarget, isAfterLegalize)) {
          unsigned Opcode = RepeatSize > ScalarSize ? X86ISD::SUBV_BROADCAST
                                                    : X86ISD::VBROADCAST;
          SDValue Broadcast = DAG.getNode(Opcode, DL, BroadcastVT, RepeatLoad);
          return DAG.getBitcast(VT, Broadcast);
        }
      }
    }
  }

  return SDValue();
}

// Combine a vector ops (shuffles etc.) that is equal to build_vector load1,
// load2, load3, load4, <0, 1, 2, 3> into a vector load if the load addresses
// are consecutive, non-overlapping, and in the right order.
static SDValue combineToConsecutiveLoads(EVT VT, SDNode *N, const SDLoc &DL,
                                         SelectionDAG &DAG,
                                         const X86Subtarget &Subtarget,
                                         bool isAfterLegalize) {
  SmallVector<SDValue, 64> Elts;
  for (unsigned i = 0, e = VT.getVectorNumElements(); i != e; ++i) {
    if (SDValue Elt = getShuffleScalarElt(N, i, DAG, 0)) {
      Elts.push_back(Elt);
      continue;
    }
    return SDValue();
  }
  assert(Elts.size() == VT.getVectorNumElements());
  return EltsFromConsecutiveLoads(VT, Elts, DL, DAG, Subtarget,
                                  isAfterLegalize);
}

static Constant *getConstantVector(MVT VT, const APInt &SplatValue,
                                   unsigned SplatBitSize, LLVMContext &C) {
  unsigned ScalarSize = VT.getScalarSizeInBits();
  unsigned NumElm = SplatBitSize / ScalarSize;

  SmallVector<Constant *, 32> ConstantVec;
  for (unsigned i = 0; i < NumElm; i++) {
    APInt Val = SplatValue.extractBits(ScalarSize, ScalarSize * i);
    Constant *Const;
    if (VT.isFloatingPoint()) {
      if (ScalarSize == 32) {
        Const = ConstantFP::get(C, APFloat(APFloat::IEEEsingle(), Val));
      } else {
        assert(ScalarSize == 64 && "Unsupported floating point scalar size");
        Const = ConstantFP::get(C, APFloat(APFloat::IEEEdouble(), Val));
      }
    } else
      Const = Constant::getIntegerValue(Type::getIntNTy(C, ScalarSize), Val);
    ConstantVec.push_back(Const);
  }
  return ConstantVector::get(ArrayRef<Constant *>(ConstantVec));
}

static bool isFoldableUseOfShuffle(SDNode *N) {
  for (auto *U : N->uses()) {
    unsigned Opc = U->getOpcode();
    // VPERMV/VPERMV3 shuffles can never fold their index operands.
    if (Opc == X86ISD::VPERMV && U->getOperand(0).getNode() == N)
      return false;
    if (Opc == X86ISD::VPERMV3 && U->getOperand(1).getNode() == N)
      return false;
    if (isTargetShuffle(Opc))
      return true;
    if (Opc == ISD::BITCAST) // Ignore bitcasts
      return isFoldableUseOfShuffle(U);
    if (N->hasOneUse())
      return true;
  }
  return false;
}

// Check if the current node of build vector is a zero extended vector.
// // If so, return the value extended.
// // For example: (0,0,0,a,0,0,0,a,0,0,0,a,0,0,0,a) returns a.
// // NumElt - return the number of zero extended identical values.
// // EltType - return the type of the value include the zero extend.
static SDValue isSplatZeroExtended(const BuildVectorSDNode *Op,
                                   unsigned &NumElt, MVT &EltType) {
  SDValue ExtValue = Op->getOperand(0);
  unsigned NumElts = Op->getNumOperands();
  unsigned Delta = NumElts;

  for (unsigned i = 1; i < NumElts; i++) {
    if (Op->getOperand(i) == ExtValue) {
      Delta = i;
      break;
    }
    if (!(Op->getOperand(i).isUndef() || isNullConstant(Op->getOperand(i))))
      return SDValue();
  }
  if (!isPowerOf2_32(Delta) || Delta == 1)
    return SDValue();

  for (unsigned i = Delta; i < NumElts; i++) {
    if (i % Delta == 0) {
      if (Op->getOperand(i) != ExtValue)
        return SDValue();
    } else if (!(isNullConstant(Op->getOperand(i)) ||
                 Op->getOperand(i).isUndef()))
      return SDValue();
  }
  unsigned EltSize = Op->getSimpleValueType(0).getScalarSizeInBits();
  unsigned ExtVTSize = EltSize * Delta;
  EltType = MVT::getIntegerVT(ExtVTSize);
  NumElt = NumElts / Delta;
  return ExtValue;
}

/// Attempt to use the vbroadcast instruction to generate a splat value
/// from a splat BUILD_VECTOR which uses:
///  a. A single scalar load, or a constant.
///  b. Repeated pattern of constants (e.g. <0,1,0,1> or <0,1,2,3,0,1,2,3>).
///
/// The VBROADCAST node is returned when a pattern is found,
/// or SDValue() otherwise.
static SDValue lowerBuildVectorAsBroadcast(BuildVectorSDNode *BVOp,
                                           const X86Subtarget &Subtarget,
                                           SelectionDAG &DAG) {
  // VBROADCAST requires AVX.
  // TODO: Splats could be generated for non-AVX CPUs using SSE
  // instructions, but there's less potential gain for only 128-bit vectors.
  if (!Subtarget.hasAVX())
    return SDValue();

  MVT VT = BVOp->getSimpleValueType(0);
  SDLoc dl(BVOp);

  assert((VT.is128BitVector() || VT.is256BitVector() || VT.is512BitVector()) &&
         "Unsupported vector type for broadcast.");

  BitVector UndefElements;
  SDValue Ld = BVOp->getSplatValue(&UndefElements);

  // Attempt to use VBROADCASTM
  // From this pattern:
  // a. t0 = (zext_i64 (bitcast_i8 v2i1 X))
  // b. t1 = (build_vector t0 t0)
  //
  // Create (VBROADCASTM v2i1 X)
  if (Subtarget.hasCDI() && (VT.is512BitVector() || Subtarget.hasVLX())) {
    MVT EltType = VT.getScalarType();
    unsigned NumElts = VT.getVectorNumElements();
    SDValue BOperand;
    SDValue ZeroExtended = isSplatZeroExtended(BVOp, NumElts, EltType);
    if ((ZeroExtended && ZeroExtended.getOpcode() == ISD::BITCAST) ||
        (Ld && Ld.getOpcode() == ISD::ZERO_EXTEND &&
         Ld.getOperand(0).getOpcode() == ISD::BITCAST)) {
      if (ZeroExtended)
        BOperand = ZeroExtended.getOperand(0);
      else
        BOperand = Ld.getOperand(0).getOperand(0);
      MVT MaskVT = BOperand.getSimpleValueType();
      if ((EltType == MVT::i64 && MaskVT == MVT::v8i1) || // for broadcastmb2q
          (EltType == MVT::i32 && MaskVT == MVT::v16i1)) { // for broadcastmw2d
        SDValue Brdcst =
            DAG.getNode(X86ISD::VBROADCASTM, dl,
                        MVT::getVectorVT(EltType, NumElts), BOperand);
        return DAG.getBitcast(VT, Brdcst);
      }
    }
  }

  unsigned NumElts = VT.getVectorNumElements();
  unsigned NumUndefElts = UndefElements.count();
  if (!Ld || (NumElts - NumUndefElts) <= 1) {
    APInt SplatValue, Undef;
    unsigned SplatBitSize;
    bool HasUndef;
    // Check if this is a repeated constant pattern suitable for broadcasting.
    if (BVOp->isConstantSplat(SplatValue, Undef, SplatBitSize, HasUndef) &&
        SplatBitSize > VT.getScalarSizeInBits() &&
        SplatBitSize < VT.getSizeInBits()) {
      // Avoid replacing with broadcast when it's a use of a shuffle
      // instruction to preserve the present custom lowering of shuffles.
      if (isFoldableUseOfShuffle(BVOp))
        return SDValue();
      // replace BUILD_VECTOR with broadcast of the repeated constants.
      const TargetLowering &TLI = DAG.getTargetLoweringInfo();
      LLVMContext *Ctx = DAG.getContext();
      MVT PVT = TLI.getPointerTy(DAG.getDataLayout());
      if (Subtarget.hasAVX()) {
        if (SplatBitSize == 32 || SplatBitSize == 64 ||
            (SplatBitSize < 32 && Subtarget.hasAVX2())) {
          // Splatted value can fit in one INTEGER constant in constant pool.
          // Load the constant and broadcast it.
          MVT CVT = MVT::getIntegerVT(SplatBitSize);
          Type *ScalarTy = Type::getIntNTy(*Ctx, SplatBitSize);
          Constant *C = Constant::getIntegerValue(ScalarTy, SplatValue);
          SDValue CP = DAG.getConstantPool(C, PVT);
          unsigned Repeat = VT.getSizeInBits() / SplatBitSize;

          MaybeAlign Alignment(cast<ConstantPoolSDNode>(CP)->getAlignment());
          SDVTList Tys =
              DAG.getVTList(MVT::getVectorVT(CVT, Repeat), MVT::Other);
          SDValue Ops[] = {DAG.getEntryNode(), CP};
          MachinePointerInfo MPI =
              MachinePointerInfo::getConstantPool(DAG.getMachineFunction());
          SDValue Brdcst = DAG.getMemIntrinsicNode(
              X86ISD::VBROADCAST_LOAD, dl, Tys, Ops, CVT, MPI, Alignment,
              MachineMemOperand::MOLoad);
          return DAG.getBitcast(VT, Brdcst);
        }
        if (SplatBitSize > 64) {
          // Load the vector of constants and broadcast it.
          MVT CVT = VT.getScalarType();
          Constant *VecC = getConstantVector(VT, SplatValue, SplatBitSize,
                                             *Ctx);
          SDValue VCP = DAG.getConstantPool(VecC, PVT);
          unsigned NumElm = SplatBitSize / VT.getScalarSizeInBits();
          unsigned Alignment = cast<ConstantPoolSDNode>(VCP)->getAlignment();
          Ld = DAG.getLoad(
              MVT::getVectorVT(CVT, NumElm), dl, DAG.getEntryNode(), VCP,
              MachinePointerInfo::getConstantPool(DAG.getMachineFunction()),
              Alignment);
          SDValue Brdcst = DAG.getNode(X86ISD::SUBV_BROADCAST, dl, VT, Ld);
          return DAG.getBitcast(VT, Brdcst);
        }
      }
    }

    // If we are moving a scalar into a vector (Ld must be set and all elements
    // but 1 are undef) and that operation is not obviously supported by
    // vmovd/vmovq/vmovss/vmovsd, then keep trying to form a broadcast.
    // That's better than general shuffling and may eliminate a load to GPR and
    // move from scalar to vector register.
    if (!Ld || NumElts - NumUndefElts != 1)
      return SDValue();
    unsigned ScalarSize = Ld.getValueSizeInBits();
    if (!(UndefElements[0] || (ScalarSize != 32 && ScalarSize != 64)))
      return SDValue();
  }

  bool ConstSplatVal =
      (Ld.getOpcode() == ISD::Constant || Ld.getOpcode() == ISD::ConstantFP);
  bool IsLoad = ISD::isNormalLoad(Ld.getNode());

  // Make sure that all of the users of a non-constant load are from the
  // BUILD_VECTOR node.
  // FIXME: Is the use count needed for non-constant, non-load case?
  if (!ConstSplatVal && !IsLoad && !BVOp->isOnlyUserOf(Ld.getNode()))
    return SDValue();

  unsigned ScalarSize = Ld.getValueSizeInBits();
  bool IsGE256 = (VT.getSizeInBits() >= 256);

  // When optimizing for size, generate up to 5 extra bytes for a broadcast
  // instruction to save 8 or more bytes of constant pool data.
  // TODO: If multiple splats are generated to load the same constant,
  // it may be detrimental to overall size. There needs to be a way to detect
  // that condition to know if this is truly a size win.
  bool OptForSize = DAG.shouldOptForSize();

  // Handle broadcasting a single constant scalar from the constant pool
  // into a vector.
  // On Sandybridge (no AVX2), it is still better to load a constant vector
  // from the constant pool and not to broadcast it from a scalar.
  // But override that restriction when optimizing for size.
  // TODO: Check if splatting is recommended for other AVX-capable CPUs.
  if (ConstSplatVal && (Subtarget.hasAVX2() || OptForSize)) {
    EVT CVT = Ld.getValueType();
    assert(!CVT.isVector() && "Must not broadcast a vector type");

    // Splat f32, i32, v4f64, v4i64 in all cases with AVX2.
    // For size optimization, also splat v2f64 and v2i64, and for size opt
    // with AVX2, also splat i8 and i16.
    // With pattern matching, the VBROADCAST node may become a VMOVDDUP.
    if (ScalarSize == 32 || (IsGE256 && ScalarSize == 64) ||
        (OptForSize && (ScalarSize == 64 || Subtarget.hasAVX2()))) {
      const Constant *C = nullptr;
      if (ConstantSDNode *CI = dyn_cast<ConstantSDNode>(Ld))
        C = CI->getConstantIntValue();
      else if (ConstantFPSDNode *CF = dyn_cast<ConstantFPSDNode>(Ld))
        C = CF->getConstantFPValue();

      assert(C && "Invalid constant type");

      const TargetLowering &TLI = DAG.getTargetLoweringInfo();
      SDValue CP =
          DAG.getConstantPool(C, TLI.getPointerTy(DAG.getDataLayout()));
      MaybeAlign Alignment(cast<ConstantPoolSDNode>(CP)->getAlignment());

      SDVTList Tys = DAG.getVTList(VT, MVT::Other);
      SDValue Ops[] = {DAG.getEntryNode(), CP};
      MachinePointerInfo MPI =
          MachinePointerInfo::getConstantPool(DAG.getMachineFunction());
      return DAG.getMemIntrinsicNode(X86ISD::VBROADCAST_LOAD, dl, Tys, Ops, CVT,
                                     MPI, Alignment, MachineMemOperand::MOLoad);
    }
  }

  // Handle AVX2 in-register broadcasts.
  if (!IsLoad && Subtarget.hasInt256() &&
      (ScalarSize == 32 || (IsGE256 && ScalarSize == 64)))
    return DAG.getNode(X86ISD::VBROADCAST, dl, VT, Ld);

  // The scalar source must be a normal load.
  if (!IsLoad)
    return SDValue();

  // Make sure the non-chain result is only used by this build vector.
  if (!Ld->hasNUsesOfValue(NumElts - NumUndefElts, 0))
    return SDValue();

  if (ScalarSize == 32 || (IsGE256 && ScalarSize == 64) ||
      (Subtarget.hasVLX() && ScalarSize == 64)) {
    auto *LN = cast<LoadSDNode>(Ld);
    SDVTList Tys = DAG.getVTList(VT, MVT::Other);
    SDValue Ops[] = {LN->getChain(), LN->getBasePtr()};
    SDValue BCast =
        DAG.getMemIntrinsicNode(X86ISD::VBROADCAST_LOAD, dl, Tys, Ops,
                                LN->getMemoryVT(), LN->getMemOperand());
    DAG.ReplaceAllUsesOfValueWith(SDValue(LN, 1), BCast.getValue(1));
    return BCast;
  }

  // The integer check is needed for the 64-bit into 128-bit so it doesn't match
  // double since there is no vbroadcastsd xmm
  if (Subtarget.hasInt256() && Ld.getValueType().isInteger() &&
      (ScalarSize == 8 || ScalarSize == 16 || ScalarSize == 64)) {
    auto *LN = cast<LoadSDNode>(Ld);
    SDVTList Tys = DAG.getVTList(VT, MVT::Other);
    SDValue Ops[] = {LN->getChain(), LN->getBasePtr()};
    SDValue BCast =
        DAG.getMemIntrinsicNode(X86ISD::VBROADCAST_LOAD, dl, Tys, Ops,
                                LN->getMemoryVT(), LN->getMemOperand());
    DAG.ReplaceAllUsesOfValueWith(SDValue(LN, 1), BCast.getValue(1));
    return BCast;
  }

  // Unsupported broadcast.
  return SDValue();
}

/// For an EXTRACT_VECTOR_ELT with a constant index return the real
/// underlying vector and index.
///
/// Modifies \p ExtractedFromVec to the real vector and returns the real
/// index.
static int getUnderlyingExtractedFromVec(SDValue &ExtractedFromVec,
                                         SDValue ExtIdx) {
  int Idx = cast<ConstantSDNode>(ExtIdx)->getZExtValue();
  if (!isa<ShuffleVectorSDNode>(ExtractedFromVec))
    return Idx;

  // For 256-bit vectors, LowerEXTRACT_VECTOR_ELT_SSE4 may have already
  // lowered this:
  //   (extract_vector_elt (v8f32 %1), Constant<6>)
  // to:
  //   (extract_vector_elt (vector_shuffle<2,u,u,u>
  //                           (extract_subvector (v8f32 %0), Constant<4>),
  //                           undef)
  //                       Constant<0>)
  // In this case the vector is the extract_subvector expression and the index
  // is 2, as specified by the shuffle.
  ShuffleVectorSDNode *SVOp = cast<ShuffleVectorSDNode>(ExtractedFromVec);
  SDValue ShuffleVec = SVOp->getOperand(0);
  MVT ShuffleVecVT = ShuffleVec.getSimpleValueType();
  assert(ShuffleVecVT.getVectorElementType() ==
         ExtractedFromVec.getSimpleValueType().getVectorElementType());

  int ShuffleIdx = SVOp->getMaskElt(Idx);
  if (isUndefOrInRange(ShuffleIdx, 0, ShuffleVecVT.getVectorNumElements())) {
    ExtractedFromVec = ShuffleVec;
    return ShuffleIdx;
  }
  return Idx;
}

static SDValue buildFromShuffleMostly(SDValue Op, SelectionDAG &DAG) {
  MVT VT = Op.getSimpleValueType();

  // Skip if insert_vec_elt is not supported.
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  if (!TLI.isOperationLegalOrCustom(ISD::INSERT_VECTOR_ELT, VT))
    return SDValue();

  SDLoc DL(Op);
  unsigned NumElems = Op.getNumOperands();

  SDValue VecIn1;
  SDValue VecIn2;
  SmallVector<unsigned, 4> InsertIndices;
  SmallVector<int, 8> Mask(NumElems, -1);

  for (unsigned i = 0; i != NumElems; ++i) {
    unsigned Opc = Op.getOperand(i).getOpcode();

    if (Opc == ISD::UNDEF)
      continue;

    if (Opc != ISD::EXTRACT_VECTOR_ELT) {
      // Quit if more than 1 elements need inserting.
      if (InsertIndices.size() > 1)
        return SDValue();

      InsertIndices.push_back(i);
      continue;
    }

    SDValue ExtractedFromVec = Op.getOperand(i).getOperand(0);
    SDValue ExtIdx = Op.getOperand(i).getOperand(1);

    // Quit if non-constant index.
    if (!isa<ConstantSDNode>(ExtIdx))
      return SDValue();
    int Idx = getUnderlyingExtractedFromVec(ExtractedFromVec, ExtIdx);

    // Quit if extracted from vector of different type.
    if (ExtractedFromVec.getValueType() != VT)
      return SDValue();

    if (!VecIn1.getNode())
      VecIn1 = ExtractedFromVec;
    else if (VecIn1 != ExtractedFromVec) {
      if (!VecIn2.getNode())
        VecIn2 = ExtractedFromVec;
      else if (VecIn2 != ExtractedFromVec)
        // Quit if more than 2 vectors to shuffle
        return SDValue();
    }

    if (ExtractedFromVec == VecIn1)
      Mask[i] = Idx;
    else if (ExtractedFromVec == VecIn2)
      Mask[i] = Idx + NumElems;
  }

  if (!VecIn1.getNode())
    return SDValue();

  VecIn2 = VecIn2.getNode() ? VecIn2 : DAG.getUNDEF(VT);
  SDValue NV = DAG.getVectorShuffle(VT, DL, VecIn1, VecIn2, Mask);

  for (unsigned Idx : InsertIndices)
    NV = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, VT, NV, Op.getOperand(Idx),
                     DAG.getIntPtrConstant(Idx, DL));

  return NV;
}

// Lower BUILD_VECTOR operation for v8i1 and v16i1 types.
static SDValue LowerBUILD_VECTORvXi1(SDValue Op, SelectionDAG &DAG,
                                     const X86Subtarget &Subtarget) {

  MVT VT = Op.getSimpleValueType();
  assert((VT.getVectorElementType() == MVT::i1) &&
         "Unexpected type in LowerBUILD_VECTORvXi1!");

  SDLoc dl(Op);
  if (ISD::isBuildVectorAllZeros(Op.getNode()) ||
      ISD::isBuildVectorAllOnes(Op.getNode()))
    return Op;

  uint64_t Immediate = 0;
  SmallVector<unsigned, 16> NonConstIdx;
  bool IsSplat = true;
  bool HasConstElts = false;
  int SplatIdx = -1;
  for (unsigned idx = 0, e = Op.getNumOperands(); idx < e; ++idx) {
    SDValue In = Op.getOperand(idx);
    if (In.isUndef())
      continue;
    if (!isa<ConstantSDNode>(In))
      NonConstIdx.push_back(idx);
    else {
      Immediate |= (cast<ConstantSDNode>(In)->getZExtValue() & 0x1) << idx;
      HasConstElts = true;
    }
    if (SplatIdx < 0)
      SplatIdx = idx;
    else if (In != Op.getOperand(SplatIdx))
      IsSplat = false;
  }

  // for splat use " (select i1 splat_elt, all-ones, all-zeroes)"
  if (IsSplat) {
    // The build_vector allows the scalar element to be larger than the vector
    // element type. We need to mask it to use as a condition unless we know
    // the upper bits are zero.
    // FIXME: Use computeKnownBits instead of checking specific opcode?
    SDValue Cond = Op.getOperand(SplatIdx);
    assert(Cond.getValueType() == MVT::i8 && "Unexpected VT!");
    if (Cond.getOpcode() != ISD::SETCC)
      Cond = DAG.getNode(ISD::AND, dl, MVT::i8, Cond,
                         DAG.getConstant(1, dl, MVT::i8));

    // Perform the select in the scalar domain so we can use cmov.
    if (VT == MVT::v64i1 && !Subtarget.is64Bit()) {
      SDValue Select = DAG.getSelect(dl, MVT::i32, Cond,
                                     DAG.getAllOnesConstant(dl, MVT::i32),
                                     DAG.getConstant(0, dl, MVT::i32));
      Select = DAG.getBitcast(MVT::v32i1, Select);
      return DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v64i1, Select, Select);
    } else {
      MVT ImmVT = MVT::getIntegerVT(std::max((unsigned)VT.getSizeInBits(), 8U));
      SDValue Select = DAG.getSelect(dl, ImmVT, Cond,
                                     DAG.getAllOnesConstant(dl, ImmVT),
                                     DAG.getConstant(0, dl, ImmVT));
      MVT VecVT = VT.getSizeInBits() >= 8 ? VT : MVT::v8i1;
      Select = DAG.getBitcast(VecVT, Select);
      return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT, Select,
                         DAG.getIntPtrConstant(0, dl));
    }
  }

  // insert elements one by one
  SDValue DstVec;
  if (HasConstElts) {
    if (VT == MVT::v64i1 && !Subtarget.is64Bit()) {
      SDValue ImmL = DAG.getConstant(Lo_32(Immediate), dl, MVT::i32);
      SDValue ImmH = DAG.getConstant(Hi_32(Immediate), dl, MVT::i32);
      ImmL = DAG.getBitcast(MVT::v32i1, ImmL);
      ImmH = DAG.getBitcast(MVT::v32i1, ImmH);
      DstVec = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v64i1, ImmL, ImmH);
    } else {
      MVT ImmVT = MVT::getIntegerVT(std::max((unsigned)VT.getSizeInBits(), 8U));
      SDValue Imm = DAG.getConstant(Immediate, dl, ImmVT);
      MVT VecVT = VT.getSizeInBits() >= 8 ? VT : MVT::v8i1;
      DstVec = DAG.getBitcast(VecVT, Imm);
      DstVec = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT, DstVec,
                           DAG.getIntPtrConstant(0, dl));
    }
  } else
    DstVec = DAG.getUNDEF(VT);

  for (unsigned i = 0, e = NonConstIdx.size(); i != e; ++i) {
    unsigned InsertIdx = NonConstIdx[i];
    DstVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, DstVec,
                         Op.getOperand(InsertIdx),
                         DAG.getIntPtrConstant(InsertIdx, dl));
  }
  return DstVec;
}

/// This is a helper function of LowerToHorizontalOp().
/// This function checks that the build_vector \p N in input implements a
/// 128-bit partial horizontal operation on a 256-bit vector, but that operation
/// may not match the layout of an x86 256-bit horizontal instruction.
/// In other words, if this returns true, then some extraction/insertion will
/// be required to produce a valid horizontal instruction.
///
/// Parameter \p Opcode defines the kind of horizontal operation to match.
/// For example, if \p Opcode is equal to ISD::ADD, then this function
/// checks if \p N implements a horizontal arithmetic add; if instead \p Opcode
/// is equal to ISD::SUB, then this function checks if this is a horizontal
/// arithmetic sub.
///
/// This function only analyzes elements of \p N whose indices are
/// in range [BaseIdx, LastIdx).
///
/// TODO: This function was originally used to match both real and fake partial
/// horizontal operations, but the index-matching logic is incorrect for that.
/// See the corrected implementation in isHopBuildVector(). Can we reduce this
/// code because it is only used for partial h-op matching now?
static bool isHorizontalBinOpPart(const BuildVectorSDNode *N, unsigned Opcode,
                                  SelectionDAG &DAG,
                                  unsigned BaseIdx, unsigned LastIdx,
                                  SDValue &V0, SDValue &V1) {
  EVT VT = N->getValueType(0);
  assert(VT.is256BitVector() && "Only use for matching partial 256-bit h-ops");
  assert(BaseIdx * 2 <= LastIdx && "Invalid Indices in input!");
  assert(VT.isVector() && VT.getVectorNumElements() >= LastIdx &&
         "Invalid Vector in input!");

  bool IsCommutable = (Opcode == ISD::ADD || Opcode == ISD::FADD);
  bool CanFold = true;
  unsigned ExpectedVExtractIdx = BaseIdx;
  unsigned NumElts = LastIdx - BaseIdx;
  V0 = DAG.getUNDEF(VT);
  V1 = DAG.getUNDEF(VT);

  // Check if N implements a horizontal binop.
  for (unsigned i = 0, e = NumElts; i != e && CanFold; ++i) {
    SDValue Op = N->getOperand(i + BaseIdx);

    // Skip UNDEFs.
    if (Op->isUndef()) {
      // Update the expected vector extract index.
      if (i * 2 == NumElts)
        ExpectedVExtractIdx = BaseIdx;
      ExpectedVExtractIdx += 2;
      continue;
    }

    CanFold = Op->getOpcode() == Opcode && Op->hasOneUse();

    if (!CanFold)
      break;

    SDValue Op0 = Op.getOperand(0);
    SDValue Op1 = Op.getOperand(1);

    // Try to match the following pattern:
    // (BINOP (extract_vector_elt A, I), (extract_vector_elt A, I+1))
    CanFold = (Op0.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
        Op1.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
        Op0.getOperand(0) == Op1.getOperand(0) &&
        isa<ConstantSDNode>(Op0.getOperand(1)) &&
        isa<ConstantSDNode>(Op1.getOperand(1)));
    if (!CanFold)
      break;

    unsigned I0 = cast<ConstantSDNode>(Op0.getOperand(1))->getZExtValue();
    unsigned I1 = cast<ConstantSDNode>(Op1.getOperand(1))->getZExtValue();

    if (i * 2 < NumElts) {
      if (V0.isUndef()) {
        V0 = Op0.getOperand(0);
        if (V0.getValueType() != VT)
          return false;
      }
    } else {
      if (V1.isUndef()) {
        V1 = Op0.getOperand(0);
        if (V1.getValueType() != VT)
          return false;
      }
      if (i * 2 == NumElts)
        ExpectedVExtractIdx = BaseIdx;
    }

    SDValue Expected = (i * 2 < NumElts) ? V0 : V1;
    if (I0 == ExpectedVExtractIdx)
      CanFold = I1 == I0 + 1 && Op0.getOperand(0) == Expected;
    else if (IsCommutable && I1 == ExpectedVExtractIdx) {
      // Try to match the following dag sequence:
      // (BINOP (extract_vector_elt A, I+1), (extract_vector_elt A, I))
      CanFold = I0 == I1 + 1 && Op1.getOperand(0) == Expected;
    } else
      CanFold = false;

    ExpectedVExtractIdx += 2;
  }

  return CanFold;
}

/// Emit a sequence of two 128-bit horizontal add/sub followed by
/// a concat_vector.
///
/// This is a helper function of LowerToHorizontalOp().
/// This function expects two 256-bit vectors called V0 and V1.
/// At first, each vector is split into two separate 128-bit vectors.
/// Then, the resulting 128-bit vectors are used to implement two
/// horizontal binary operations.
///
/// The kind of horizontal binary operation is defined by \p X86Opcode.
///
/// \p Mode specifies how the 128-bit parts of V0 and V1 are passed in input to
/// the two new horizontal binop.
/// When Mode is set, the first horizontal binop dag node would take as input
/// the lower 128-bit of V0 and the upper 128-bit of V0. The second
/// horizontal binop dag node would take as input the lower 128-bit of V1
/// and the upper 128-bit of V1.
///   Example:
///     HADD V0_LO, V0_HI
///     HADD V1_LO, V1_HI
///
/// Otherwise, the first horizontal binop dag node takes as input the lower
/// 128-bit of V0 and the lower 128-bit of V1, and the second horizontal binop
/// dag node takes the upper 128-bit of V0 and the upper 128-bit of V1.
///   Example:
///     HADD V0_LO, V1_LO
///     HADD V0_HI, V1_HI
///
/// If \p isUndefLO is set, then the algorithm propagates UNDEF to the lower
/// 128-bits of the result. If \p isUndefHI is set, then UNDEF is propagated to
/// the upper 128-bits of the result.
static SDValue ExpandHorizontalBinOp(const SDValue &V0, const SDValue &V1,
                                     const SDLoc &DL, SelectionDAG &DAG,
                                     unsigned X86Opcode, bool Mode,
                                     bool isUndefLO, bool isUndefHI) {
  MVT VT = V0.getSimpleValueType();
  assert(VT.is256BitVector() && VT == V1.getSimpleValueType() &&
         "Invalid nodes in input!");

  unsigned NumElts = VT.getVectorNumElements();
  SDValue V0_LO = extract128BitVector(V0, 0, DAG, DL);
  SDValue V0_HI = extract128BitVector(V0, NumElts/2, DAG, DL);
  SDValue V1_LO = extract128BitVector(V1, 0, DAG, DL);
  SDValue V1_HI = extract128BitVector(V1, NumElts/2, DAG, DL);
  MVT NewVT = V0_LO.getSimpleValueType();

  SDValue LO = DAG.getUNDEF(NewVT);
  SDValue HI = DAG.getUNDEF(NewVT);

  if (Mode) {
    // Don't emit a horizontal binop if the result is expected to be UNDEF.
    if (!isUndefLO && !V0->isUndef())
      LO = DAG.getNode(X86Opcode, DL, NewVT, V0_LO, V0_HI);
    if (!isUndefHI && !V1->isUndef())
      HI = DAG.getNode(X86Opcode, DL, NewVT, V1_LO, V1_HI);
  } else {
    // Don't emit a horizontal binop if the result is expected to be UNDEF.
    if (!isUndefLO && (!V0_LO->isUndef() || !V1_LO->isUndef()))
      LO = DAG.getNode(X86Opcode, DL, NewVT, V0_LO, V1_LO);

    if (!isUndefHI && (!V0_HI->isUndef() || !V1_HI->isUndef()))
      HI = DAG.getNode(X86Opcode, DL, NewVT, V0_HI, V1_HI);
  }

  return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, LO, HI);
}

/// Returns true iff \p BV builds a vector with the result equivalent to
/// the result of ADDSUB/SUBADD operation.
/// If true is returned then the operands of ADDSUB = Opnd0 +- Opnd1
/// (SUBADD = Opnd0 -+ Opnd1) operation are written to the parameters
/// \p Opnd0 and \p Opnd1.
static bool isAddSubOrSubAdd(const BuildVectorSDNode *BV,
                             const X86Subtarget &Subtarget, SelectionDAG &DAG,
                             SDValue &Opnd0, SDValue &Opnd1,
                             unsigned &NumExtracts,
                             bool &IsSubAdd) {

  MVT VT = BV->getSimpleValueType(0);
  if (!Subtarget.hasSSE3() || !VT.isFloatingPoint())
    return false;

  unsigned NumElts = VT.getVectorNumElements();
  SDValue InVec0 = DAG.getUNDEF(VT);
  SDValue InVec1 = DAG.getUNDEF(VT);

  NumExtracts = 0;

  // Odd-numbered elements in the input build vector are obtained from
  // adding/subtracting two integer/float elements.
  // Even-numbered elements in the input build vector are obtained from
  // subtracting/adding two integer/float elements.
  unsigned Opc[2] = {0, 0};
  for (unsigned i = 0, e = NumElts; i != e; ++i) {
    SDValue Op = BV->getOperand(i);

    // Skip 'undef' values.
    unsigned Opcode = Op.getOpcode();
    if (Opcode == ISD::UNDEF)
      continue;

    // Early exit if we found an unexpected opcode.
    if (Opcode != ISD::FADD && Opcode != ISD::FSUB)
      return false;

    SDValue Op0 = Op.getOperand(0);
    SDValue Op1 = Op.getOperand(1);

    // Try to match the following pattern:
    // (BINOP (extract_vector_elt A, i), (extract_vector_elt B, i))
    // Early exit if we cannot match that sequence.
    if (Op0.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
        Op1.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
        !isa<ConstantSDNode>(Op0.getOperand(1)) ||
        !isa<ConstantSDNode>(Op1.getOperand(1)) ||
        Op0.getOperand(1) != Op1.getOperand(1))
      return false;

    unsigned I0 = cast<ConstantSDNode>(Op0.getOperand(1))->getZExtValue();
    if (I0 != i)
      return false;

    // We found a valid add/sub node, make sure its the same opcode as previous
    // elements for this parity.
    if (Opc[i % 2] != 0 && Opc[i % 2] != Opcode)
      return false;
    Opc[i % 2] = Opcode;

    // Update InVec0 and InVec1.
    if (InVec0.isUndef()) {
      InVec0 = Op0.getOperand(0);
      if (InVec0.getSimpleValueType() != VT)
        return false;
    }
    if (InVec1.isUndef()) {
      InVec1 = Op1.getOperand(0);
      if (InVec1.getSimpleValueType() != VT)
        return false;
    }

    // Make sure that operands in input to each add/sub node always
    // come from a same pair of vectors.
    if (InVec0 != Op0.getOperand(0)) {
      if (Opcode == ISD::FSUB)
        return false;

      // FADD is commutable. Try to commute the operands
      // and then test again.
      std::swap(Op0, Op1);
      if (InVec0 != Op0.getOperand(0))
        return false;
    }

    if (InVec1 != Op1.getOperand(0))
      return false;

    // Increment the number of extractions done.
    ++NumExtracts;
  }

  // Ensure we have found an opcode for both parities and that they are
  // different. Don't try to fold this build_vector into an ADDSUB/SUBADD if the
  // inputs are undef.
  if (!Opc[0] || !Opc[1] || Opc[0] == Opc[1] ||
      InVec0.isUndef() || InVec1.isUndef())
    return false;

  IsSubAdd = Opc[0] == ISD::FADD;

  Opnd0 = InVec0;
  Opnd1 = InVec1;
  return true;
}

/// Returns true if is possible to fold MUL and an idiom that has already been
/// recognized as ADDSUB/SUBADD(\p Opnd0, \p Opnd1) into
/// FMADDSUB/FMSUBADD(x, y, \p Opnd1). If (and only if) true is returned, the
/// operands of FMADDSUB/FMSUBADD are written to parameters \p Opnd0, \p Opnd1, \p Opnd2.
///
/// Prior to calling this function it should be known that there is some
/// SDNode that potentially can be replaced with an X86ISD::ADDSUB operation
/// using \p Opnd0 and \p Opnd1 as operands. Also, this method is called
/// before replacement of such SDNode with ADDSUB operation. Thus the number
/// of \p Opnd0 uses is expected to be equal to 2.
/// For example, this function may be called for the following IR:
///    %AB = fmul fast <2 x double> %A, %B
///    %Sub = fsub fast <2 x double> %AB, %C
///    %Add = fadd fast <2 x double> %AB, %C
///    %Addsub = shufflevector <2 x double> %Sub, <2 x double> %Add,
///                            <2 x i32> <i32 0, i32 3>
/// There is a def for %Addsub here, which potentially can be replaced by
/// X86ISD::ADDSUB operation:
///    %Addsub = X86ISD::ADDSUB %AB, %C
/// and such ADDSUB can further be replaced with FMADDSUB:
///    %Addsub = FMADDSUB %A, %B, %C.
///
/// The main reason why this method is called before the replacement of the
/// recognized ADDSUB idiom with ADDSUB operation is that such replacement
/// is illegal sometimes. E.g. 512-bit ADDSUB is not available, while 512-bit
/// FMADDSUB is.
static bool isFMAddSubOrFMSubAdd(const X86Subtarget &Subtarget,
                                 SelectionDAG &DAG,
                                 SDValue &Opnd0, SDValue &Opnd1, SDValue &Opnd2,
                                 unsigned ExpectedUses) {
  if (Opnd0.getOpcode() != ISD::FMUL ||
      !Opnd0->hasNUsesOfValue(ExpectedUses, 0) || !Subtarget.hasAnyFMA())
    return false;

  // FIXME: These checks must match the similar ones in
  // DAGCombiner::visitFADDForFMACombine. It would be good to have one
  // function that would answer if it is Ok to fuse MUL + ADD to FMADD
  // or MUL + ADDSUB to FMADDSUB.
  const TargetOptions &Options = DAG.getTarget().Options;
  bool AllowFusion =
      (Options.AllowFPOpFusion == FPOpFusion::Fast || Options.UnsafeFPMath);
  if (!AllowFusion)
    return false;

  Opnd2 = Opnd1;
  Opnd1 = Opnd0.getOperand(1);
  Opnd0 = Opnd0.getOperand(0);

  return true;
}

/// Try to fold a build_vector that performs an 'addsub' or 'fmaddsub' or
/// 'fsubadd' operation accordingly to X86ISD::ADDSUB or X86ISD::FMADDSUB or
/// X86ISD::FMSUBADD node.
static SDValue lowerToAddSubOrFMAddSub(const BuildVectorSDNode *BV,
                                       const X86Subtarget &Subtarget,
                                       SelectionDAG &DAG) {
  SDValue Opnd0, Opnd1;
  unsigned NumExtracts;
  bool IsSubAdd;
  if (!isAddSubOrSubAdd(BV, Subtarget, DAG, Opnd0, Opnd1, NumExtracts,
                        IsSubAdd))
    return SDValue();

  MVT VT = BV->getSimpleValueType(0);
  SDLoc DL(BV);

  // Try to generate X86ISD::FMADDSUB node here.
  SDValue Opnd2;
  if (isFMAddSubOrFMSubAdd(Subtarget, DAG, Opnd0, Opnd1, Opnd2, NumExtracts)) {
    unsigned Opc = IsSubAdd ? X86ISD::FMSUBADD : X86ISD::FMADDSUB;
    return DAG.getNode(Opc, DL, VT, Opnd0, Opnd1, Opnd2);
  }

  // We only support ADDSUB.
  if (IsSubAdd)
    return SDValue();

  // Do not generate X86ISD::ADDSUB node for 512-bit types even though
  // the ADDSUB idiom has been successfully recognized. There are no known
  // X86 targets with 512-bit ADDSUB instructions!
  // 512-bit ADDSUB idiom recognition was needed only as part of FMADDSUB idiom
  // recognition.
  if (VT.is512BitVector())
    return SDValue();

  return DAG.getNode(X86ISD::ADDSUB, DL, VT, Opnd0, Opnd1);
}

static bool isHopBuildVector(const BuildVectorSDNode *BV, SelectionDAG &DAG,
                             unsigned &HOpcode, SDValue &V0, SDValue &V1) {
  // Initialize outputs to known values.
  MVT VT = BV->getSimpleValueType(0);
  HOpcode = ISD::DELETED_NODE;
  V0 = DAG.getUNDEF(VT);
  V1 = DAG.getUNDEF(VT);

  // x86 256-bit horizontal ops are defined in a non-obvious way. Each 128-bit
  // half of the result is calculated independently from the 128-bit halves of
  // the inputs, so that makes the index-checking logic below more complicated.
  unsigned NumElts = VT.getVectorNumElements();
  unsigned GenericOpcode = ISD::DELETED_NODE;
  unsigned Num128BitChunks = VT.is256BitVector() ? 2 : 1;
  unsigned NumEltsIn128Bits = NumElts / Num128BitChunks;
  unsigned NumEltsIn64Bits = NumEltsIn128Bits / 2;
  for (unsigned i = 0; i != Num128BitChunks; ++i) {
    for (unsigned j = 0; j != NumEltsIn128Bits; ++j) {
      // Ignore undef elements.
      SDValue Op = BV->getOperand(i * NumEltsIn128Bits + j);
      if (Op.isUndef())
        continue;

      // If there's an opcode mismatch, we're done.
      if (HOpcode != ISD::DELETED_NODE && Op.getOpcode() != GenericOpcode)
        return false;

      // Initialize horizontal opcode.
      if (HOpcode == ISD::DELETED_NODE) {
        GenericOpcode = Op.getOpcode();
        switch (GenericOpcode) {
        case ISD::ADD: HOpcode = X86ISD::HADD; break;
        case ISD::SUB: HOpcode = X86ISD::HSUB; break;
        case ISD::FADD: HOpcode = X86ISD::FHADD; break;
        case ISD::FSUB: HOpcode = X86ISD::FHSUB; break;
        default: return false;
        }
      }

      SDValue Op0 = Op.getOperand(0);
      SDValue Op1 = Op.getOperand(1);
      if (Op0.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
          Op1.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
          Op0.getOperand(0) != Op1.getOperand(0) ||
          !isa<ConstantSDNode>(Op0.getOperand(1)) ||
          !isa<ConstantSDNode>(Op1.getOperand(1)) || !Op.hasOneUse())
        return false;

      // The source vector is chosen based on which 64-bit half of the
      // destination vector is being calculated.
      if (j < NumEltsIn64Bits) {
        if (V0.isUndef())
          V0 = Op0.getOperand(0);
      } else {
        if (V1.isUndef())
          V1 = Op0.getOperand(0);
      }

      SDValue SourceVec = (j < NumEltsIn64Bits) ? V0 : V1;
      if (SourceVec != Op0.getOperand(0))
        return false;

      // op (extract_vector_elt A, I), (extract_vector_elt A, I+1)
      unsigned ExtIndex0 = Op0.getConstantOperandVal(1);
      unsigned ExtIndex1 = Op1.getConstantOperandVal(1);
      unsigned ExpectedIndex = i * NumEltsIn128Bits +
                               (j % NumEltsIn64Bits) * 2;
      if (ExpectedIndex == ExtIndex0 && ExtIndex1 == ExtIndex0 + 1)
        continue;

      // If this is not a commutative op, this does not match.
      if (GenericOpcode != ISD::ADD && GenericOpcode != ISD::FADD)
        return false;

      // Addition is commutative, so try swapping the extract indexes.
      // op (extract_vector_elt A, I+1), (extract_vector_elt A, I)
      if (ExpectedIndex == ExtIndex1 && ExtIndex0 == ExtIndex1 + 1)
        continue;

      // Extract indexes do not match horizontal requirement.
      return false;
    }
  }
  // We matched. Opcode and operands are returned by reference as arguments.
  return true;
}

static SDValue getHopForBuildVector(const BuildVectorSDNode *BV,
                                    SelectionDAG &DAG, unsigned HOpcode,
                                    SDValue V0, SDValue V1) {
  // If either input vector is not the same size as the build vector,
  // extract/insert the low bits to the correct size.
  // This is free (examples: zmm --> xmm, xmm --> ymm).
  MVT VT = BV->getSimpleValueType(0);
  unsigned Width = VT.getSizeInBits();
  if (V0.getValueSizeInBits() > Width)
    V0 = extractSubVector(V0, 0, DAG, SDLoc(BV), Width);
  else if (V0.getValueSizeInBits() < Width)
    V0 = insertSubVector(DAG.getUNDEF(VT), V0, 0, DAG, SDLoc(BV), Width);

  if (V1.getValueSizeInBits() > Width)
    V1 = extractSubVector(V1, 0, DAG, SDLoc(BV), Width);
  else if (V1.getValueSizeInBits() < Width)
    V1 = insertSubVector(DAG.getUNDEF(VT), V1, 0, DAG, SDLoc(BV), Width);

  unsigned NumElts = VT.getVectorNumElements();
  APInt DemandedElts = APInt::getAllOnesValue(NumElts);
  for (unsigned i = 0; i != NumElts; ++i)
    if (BV->getOperand(i).isUndef())
      DemandedElts.clearBit(i);

  // If we don't need the upper xmm, then perform as a xmm hop.
  unsigned HalfNumElts = NumElts / 2;
  if (VT.is256BitVector() && DemandedElts.lshr(HalfNumElts) == 0) {
    MVT HalfVT = VT.getHalfNumVectorElementsVT();
    V0 = extractSubVector(V0, 0, DAG, SDLoc(BV), 128);
    V1 = extractSubVector(V1, 0, DAG, SDLoc(BV), 128);
    SDValue Half = DAG.getNode(HOpcode, SDLoc(BV), HalfVT, V0, V1);
    return insertSubVector(DAG.getUNDEF(VT), Half, 0, DAG, SDLoc(BV), 256);
  }

  return DAG.getNode(HOpcode, SDLoc(BV), VT, V0, V1);
}

/// Lower BUILD_VECTOR to a horizontal add/sub operation if possible.
static SDValue LowerToHorizontalOp(const BuildVectorSDNode *BV,
                                   const X86Subtarget &Subtarget,
                                   SelectionDAG &DAG) {
  // We need at least 2 non-undef elements to make this worthwhile by default.
  unsigned NumNonUndefs =
      count_if(BV->op_values(), [](SDValue V) { return !V.isUndef(); });
  if (NumNonUndefs < 2)
    return SDValue();

  // There are 4 sets of horizontal math operations distinguished by type:
  // int/FP at 128-bit/256-bit. Each type was introduced with a different
  // subtarget feature. Try to match those "native" patterns first.
  MVT VT = BV->getSimpleValueType(0);
  if (((VT == MVT::v4f32 || VT == MVT::v2f64) && Subtarget.hasSSE3()) ||
      ((VT == MVT::v8i16 || VT == MVT::v4i32) && Subtarget.hasSSSE3()) ||
      ((VT == MVT::v8f32 || VT == MVT::v4f64) && Subtarget.hasAVX()) ||
      ((VT == MVT::v16i16 || VT == MVT::v8i32) && Subtarget.hasAVX2())) {
    unsigned HOpcode;
    SDValue V0, V1;
    if (isHopBuildVector(BV, DAG, HOpcode, V0, V1))
      return getHopForBuildVector(BV, DAG, HOpcode, V0, V1);
  }

  // Try harder to match 256-bit ops by using extract/concat.
  if (!Subtarget.hasAVX() || !VT.is256BitVector())
    return SDValue();

  // Count the number of UNDEF operands in the build_vector in input.
  unsigned NumElts = VT.getVectorNumElements();
  unsigned Half = NumElts / 2;
  unsigned NumUndefsLO = 0;
  unsigned NumUndefsHI = 0;
  for (unsigned i = 0, e = Half; i != e; ++i)
    if (BV->getOperand(i)->isUndef())
      NumUndefsLO++;

  for (unsigned i = Half, e = NumElts; i != e; ++i)
    if (BV->getOperand(i)->isUndef())
      NumUndefsHI++;

  SDLoc DL(BV);
  SDValue InVec0, InVec1;
  if (VT == MVT::v8i32 || VT == MVT::v16i16) {
    SDValue InVec2, InVec3;
    unsigned X86Opcode;
    bool CanFold = true;

    if (isHorizontalBinOpPart(BV, ISD::ADD, DAG, 0, Half, InVec0, InVec1) &&
        isHorizontalBinOpPart(BV, ISD::ADD, DAG, Half, NumElts, InVec2,
                              InVec3) &&
        ((InVec0.isUndef() || InVec2.isUndef()) || InVec0 == InVec2) &&
        ((InVec1.isUndef() || InVec3.isUndef()) || InVec1 == InVec3))
      X86Opcode = X86ISD::HADD;
    else if (isHorizontalBinOpPart(BV, ISD::SUB, DAG, 0, Half, InVec0,
                                   InVec1) &&
             isHorizontalBinOpPart(BV, ISD::SUB, DAG, Half, NumElts, InVec2,
                                   InVec3) &&
             ((InVec0.isUndef() || InVec2.isUndef()) || InVec0 == InVec2) &&
             ((InVec1.isUndef() || InVec3.isUndef()) || InVec1 == InVec3))
      X86Opcode = X86ISD::HSUB;
    else
      CanFold = false;

    if (CanFold) {
      // Do not try to expand this build_vector into a pair of horizontal
      // add/sub if we can emit a pair of scalar add/sub.
      if (NumUndefsLO + 1 == Half || NumUndefsHI + 1 == Half)
        return SDValue();

      // Convert this build_vector into a pair of horizontal binops followed by
      // a concat vector. We must adjust the outputs from the partial horizontal
      // matching calls above to account for undefined vector halves.
      SDValue V0 = InVec0.isUndef() ? InVec2 : InVec0;
      SDValue V1 = InVec1.isUndef() ? InVec3 : InVec1;
      assert((!V0.isUndef() || !V1.isUndef()) && "Horizontal-op of undefs?");
      bool isUndefLO = NumUndefsLO == Half;
      bool isUndefHI = NumUndefsHI == Half;
      return ExpandHorizontalBinOp(V0, V1, DL, DAG, X86Opcode, false, isUndefLO,
                                   isUndefHI);
    }
  }

  if (VT == MVT::v8f32 || VT == MVT::v4f64 || VT == MVT::v8i32 ||
      VT == MVT::v16i16) {
    unsigned X86Opcode;
    if (isHorizontalBinOpPart(BV, ISD::ADD, DAG, 0, NumElts, InVec0, InVec1))
      X86Opcode = X86ISD::HADD;
    else if (isHorizontalBinOpPart(BV, ISD::SUB, DAG, 0, NumElts, InVec0,
                                   InVec1))
      X86Opcode = X86ISD::HSUB;
    else if (isHorizontalBinOpPart(BV, ISD::FADD, DAG, 0, NumElts, InVec0,
                                   InVec1))
      X86Opcode = X86ISD::FHADD;
    else if (isHorizontalBinOpPart(BV, ISD::FSUB, DAG, 0, NumElts, InVec0,
                                   InVec1))
      X86Opcode = X86ISD::FHSUB;
    else
      return SDValue();

    // Don't try to expand this build_vector into a pair of horizontal add/sub
    // if we can simply emit a pair of scalar add/sub.
    if (NumUndefsLO + 1 == Half || NumUndefsHI + 1 == Half)
      return SDValue();

    // Convert this build_vector into two horizontal add/sub followed by
    // a concat vector.
    bool isUndefLO = NumUndefsLO == Half;
    bool isUndefHI = NumUndefsHI == Half;
    return ExpandHorizontalBinOp(InVec0, InVec1, DL, DAG, X86Opcode, true,
                                 isUndefLO, isUndefHI);
  }

  return SDValue();
}

/// If a BUILD_VECTOR's source elements all apply the same bit operation and
/// one of their operands is constant, lower to a pair of BUILD_VECTOR and
/// just apply the bit to the vectors.
/// NOTE: Its not in our interest to start make a general purpose vectorizer
/// from this, but enough scalar bit operations are created from the later
/// legalization + scalarization stages to need basic support.
static SDValue lowerBuildVectorToBitOp(BuildVectorSDNode *Op,
                                       SelectionDAG &DAG) {
  SDLoc DL(Op);
  MVT VT = Op->getSimpleValueType(0);
  unsigned NumElems = VT.getVectorNumElements();
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();

  // Check that all elements have the same opcode.
  // TODO: Should we allow UNDEFS and if so how many?
  unsigned Opcode = Op->getOperand(0).getOpcode();
  for (unsigned i = 1; i < NumElems; ++i)
    if (Opcode != Op->getOperand(i).getOpcode())
      return SDValue();

  // TODO: We may be able to add support for other Ops (ADD/SUB + shifts).
  bool IsShift = false;
  switch (Opcode) {
  default:
    return SDValue();
  case ISD::SHL:
  case ISD::SRL:
  case ISD::SRA:
    IsShift = true;
    break;
  case ISD::AND:
  case ISD::XOR:
  case ISD::OR:
    // Don't do this if the buildvector is a splat - we'd replace one
    // constant with an entire vector.
    if (Op->getSplatValue())
      return SDValue();
    if (!TLI.isOperationLegalOrPromote(Opcode, VT))
      return SDValue();
    break;
  }

  SmallVector<SDValue, 4> LHSElts, RHSElts;
  for (SDValue Elt : Op->ops()) {
    SDValue LHS = Elt.getOperand(0);
    SDValue RHS = Elt.getOperand(1);

    // We expect the canonicalized RHS operand to be the constant.
    if (!isa<ConstantSDNode>(RHS))
      return SDValue();

    // Extend shift amounts.
    if (RHS.getValueSizeInBits() != VT.getScalarSizeInBits()) {
      if (!IsShift)
        return SDValue();
      RHS = DAG.getZExtOrTrunc(RHS, DL, VT.getScalarType());
    }

    LHSElts.push_back(LHS);
    RHSElts.push_back(RHS);
  }

  // Limit to shifts by uniform immediates.
  // TODO: Only accept vXi8/vXi64 special cases?
  // TODO: Permit non-uniform XOP/AVX2/MULLO cases?
  if (IsShift && any_of(RHSElts, [&](SDValue V) { return RHSElts[0] != V; }))
    return SDValue();

  SDValue LHS = DAG.getBuildVector(VT, DL, LHSElts);
  SDValue RHS = DAG.getBuildVector(VT, DL, RHSElts);
  return DAG.getNode(Opcode, DL, VT, LHS, RHS);
}

/// Create a vector constant without a load. SSE/AVX provide the bare minimum
/// functionality to do this, so it's all zeros, all ones, or some derivation
/// that is cheap to calculate.
static SDValue materializeVectorConstant(SDValue Op, SelectionDAG &DAG,
                                         const X86Subtarget &Subtarget) {
  SDLoc DL(Op);
  MVT VT = Op.getSimpleValueType();

  // Vectors containing all zeros can be matched by pxor and xorps.
  if (ISD::isBuildVectorAllZeros(Op.getNode()))
    return Op;

  // Vectors containing all ones can be matched by pcmpeqd on 128-bit width
  // vectors or broken into v4i32 operations on 256-bit vectors. AVX2 can use
  // vpcmpeqd on 256-bit vectors.
  if (Subtarget.hasSSE2() && ISD::isBuildVectorAllOnes(Op.getNode())) {
    if (VT == MVT::v4i32 || VT == MVT::v8i32 || VT == MVT::v16i32)
      return Op;

    return getOnesVector(VT, DAG, DL);
  }

  return SDValue();
}

/// Look for opportunities to create a VPERMV/VPERMILPV/PSHUFB variable permute
/// from a vector of source values and a vector of extraction indices.
/// The vectors might be manipulated to match the type of the permute op.
static SDValue createVariablePermute(MVT VT, SDValue SrcVec, SDValue IndicesVec,
                                     SDLoc &DL, SelectionDAG &DAG,
                                     const X86Subtarget &Subtarget) {
  MVT ShuffleVT = VT;
  EVT IndicesVT = EVT(VT).changeVectorElementTypeToInteger();
  unsigned NumElts = VT.getVectorNumElements();
  unsigned SizeInBits = VT.getSizeInBits();

  // Adjust IndicesVec to match VT size.
  assert(IndicesVec.getValueType().getVectorNumElements() >= NumElts &&
         "Illegal variable permute mask size");
  if (IndicesVec.getValueType().getVectorNumElements() > NumElts)
    IndicesVec = extractSubVector(IndicesVec, 0, DAG, SDLoc(IndicesVec),
                                  NumElts * VT.getScalarSizeInBits());
  IndicesVec = DAG.getZExtOrTrunc(IndicesVec, SDLoc(IndicesVec), IndicesVT);

  // Handle SrcVec that don't match VT type.
  if (SrcVec.getValueSizeInBits() != SizeInBits) {
    if ((SrcVec.getValueSizeInBits() % SizeInBits) == 0) {
      // Handle larger SrcVec by treating it as a larger permute.
      unsigned Scale = SrcVec.getValueSizeInBits() / SizeInBits;
      VT = MVT::getVectorVT(VT.getScalarType(), Scale * NumElts);
      IndicesVT = EVT(VT).changeVectorElementTypeToInteger();
      IndicesVec = widenSubVector(IndicesVT.getSimpleVT(), IndicesVec, false,
                                  Subtarget, DAG, SDLoc(IndicesVec));
      SDValue NewSrcVec =
          createVariablePermute(VT, SrcVec, IndicesVec, DL, DAG, Subtarget);
      if (NewSrcVec)
        return extractSubVector(NewSrcVec, 0, DAG, DL, SizeInBits);
      return SDValue();
    } else if (SrcVec.getValueSizeInBits() < SizeInBits) {
      // Widen smaller SrcVec to match VT.
      SrcVec = widenSubVector(VT, SrcVec, false, Subtarget, DAG, SDLoc(SrcVec));
    } else
      return SDValue();
  }

  auto ScaleIndices = [&DAG](SDValue Idx, uint64_t Scale) {
    assert(isPowerOf2_64(Scale) && "Illegal variable permute shuffle scale");
    EVT SrcVT = Idx.getValueType();
    unsigned NumDstBits = SrcVT.getScalarSizeInBits() / Scale;
    uint64_t IndexScale = 0;
    uint64_t IndexOffset = 0;

    // If we're scaling a smaller permute op, then we need to repeat the
    // indices, scaling and offsetting them as well.
    // e.g. v4i32 -> v16i8 (Scale = 4)
    // IndexScale = v4i32 Splat(4 << 24 | 4 << 16 | 4 << 8 | 4)
    // IndexOffset = v4i32 Splat(3 << 24 | 2 << 16 | 1 << 8 | 0)
    for (uint64_t i = 0; i != Scale; ++i) {
      IndexScale |= Scale << (i * NumDstBits);
      IndexOffset |= i << (i * NumDstBits);
    }

    Idx = DAG.getNode(ISD::MUL, SDLoc(Idx), SrcVT, Idx,
                      DAG.getConstant(IndexScale, SDLoc(Idx), SrcVT));
    Idx = DAG.getNode(ISD::ADD, SDLoc(Idx), SrcVT, Idx,
                      DAG.getConstant(IndexOffset, SDLoc(Idx), SrcVT));
    return Idx;
  };

  unsigned Opcode = 0;
  switch (VT.SimpleTy) {
  default:
    break;
  case MVT::v16i8:
    if (Subtarget.hasSSSE3())
      Opcode = X86ISD::PSHUFB;
    break;
  case MVT::v8i16:
    if (Subtarget.hasVLX() && Subtarget.hasBWI())
      Opcode = X86ISD::VPERMV;
    else if (Subtarget.hasSSSE3()) {
      Opcode = X86ISD::PSHUFB;
      ShuffleVT = MVT::v16i8;
    }
    break;
  case MVT::v4f32:
  case MVT::v4i32:
    if (Subtarget.hasAVX()) {
      Opcode = X86ISD::VPERMILPV;
      ShuffleVT = MVT::v4f32;
    } else if (Subtarget.hasSSSE3()) {
      Opcode = X86ISD::PSHUFB;
      ShuffleVT = MVT::v16i8;
    }
    break;
  case MVT::v2f64:
  case MVT::v2i64:
    if (Subtarget.hasAVX()) {
      // VPERMILPD selects using bit#1 of the index vector, so scale IndicesVec.
      IndicesVec = DAG.getNode(ISD::ADD, DL, IndicesVT, IndicesVec, IndicesVec);
      Opcode = X86ISD::VPERMILPV;
      ShuffleVT = MVT::v2f64;
    } else if (Subtarget.hasSSE41()) {
      // SSE41 can compare v2i64 - select between indices 0 and 1.
      return DAG.getSelectCC(
          DL, IndicesVec,
          getZeroVector(IndicesVT.getSimpleVT(), Subtarget, DAG, DL),
          DAG.getVectorShuffle(VT, DL, SrcVec, SrcVec, {0, 0}),
          DAG.getVectorShuffle(VT, DL, SrcVec, SrcVec, {1, 1}),
          ISD::CondCode::SETEQ);
    }
    break;
  case MVT::v32i8:
    if (Subtarget.hasVLX() && Subtarget.hasVBMI())
      Opcode = X86ISD::VPERMV;
    else if (Subtarget.hasXOP()) {
      SDValue LoSrc = extract128BitVector(SrcVec, 0, DAG, DL);
      SDValue HiSrc = extract128BitVector(SrcVec, 16, DAG, DL);
      SDValue LoIdx = extract128BitVector(IndicesVec, 0, DAG, DL);
      SDValue HiIdx = extract128BitVector(IndicesVec, 16, DAG, DL);
      return DAG.getNode(
          ISD::CONCAT_VECTORS, DL, VT,
          DAG.getNode(X86ISD::VPPERM, DL, MVT::v16i8, LoSrc, HiSrc, LoIdx),
          DAG.getNode(X86ISD::VPPERM, DL, MVT::v16i8, LoSrc, HiSrc, HiIdx));
    } else if (Subtarget.hasAVX()) {
      SDValue Lo = extract128BitVector(SrcVec, 0, DAG, DL);
      SDValue Hi = extract128BitVector(SrcVec, 16, DAG, DL);
      SDValue LoLo = DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Lo, Lo);
      SDValue HiHi = DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Hi, Hi);
      auto PSHUFBBuilder = [](SelectionDAG &DAG, const SDLoc &DL,
                              ArrayRef<SDValue> Ops) {
        // Permute Lo and Hi and then select based on index range.
        // This works as SHUFB uses bits[3:0] to permute elements and we don't
        // care about the bit[7] as its just an index vector.
        SDValue Idx = Ops[2];
        EVT VT = Idx.getValueType();
        return DAG.getSelectCC(DL, Idx, DAG.getConstant(15, DL, VT),
                               DAG.getNode(X86ISD::PSHUFB, DL, VT, Ops[1], Idx),
                               DAG.getNode(X86ISD::PSHUFB, DL, VT, Ops[0], Idx),
                               ISD::CondCode::SETGT);
      };
      SDValue Ops[] = {LoLo, HiHi, IndicesVec};
      return SplitOpsAndApply(DAG, Subtarget, DL, MVT::v32i8, Ops,
                              PSHUFBBuilder);
    }
    break;
  case MVT::v16i16:
    if (Subtarget.hasVLX() && Subtarget.hasBWI())
      Opcode = X86ISD::VPERMV;
    else if (Subtarget.hasAVX()) {
      // Scale to v32i8 and perform as v32i8.
      IndicesVec = ScaleIndices(IndicesVec, 2);
      return DAG.getBitcast(
          VT, createVariablePermute(
                  MVT::v32i8, DAG.getBitcast(MVT::v32i8, SrcVec),
                  DAG.getBitcast(MVT::v32i8, IndicesVec), DL, DAG, Subtarget));
    }
    break;
  case MVT::v8f32:
  case MVT::v8i32:
    if (Subtarget.hasAVX2())
      Opcode = X86ISD::VPERMV;
    else if (Subtarget.hasAVX()) {
      SrcVec = DAG.getBitcast(MVT::v8f32, SrcVec);
      SDValue LoLo = DAG.getVectorShuffle(MVT::v8f32, DL, SrcVec, SrcVec,
                                          {0, 1, 2, 3, 0, 1, 2, 3});
      SDValue HiHi = DAG.getVectorShuffle(MVT::v8f32, DL, SrcVec, SrcVec,
                                          {4, 5, 6, 7, 4, 5, 6, 7});
      if (Subtarget.hasXOP())
        return DAG.getBitcast(
            VT, DAG.getNode(X86ISD::VPERMIL2, DL, MVT::v8f32, LoLo, HiHi,
                            IndicesVec, DAG.getTargetConstant(0, DL, MVT::i8)));
      // Permute Lo and Hi and then select based on index range.
      // This works as VPERMILPS only uses index bits[0:1] to permute elements.
      SDValue Res = DAG.getSelectCC(
          DL, IndicesVec, DAG.getConstant(3, DL, MVT::v8i32),
          DAG.getNode(X86ISD::VPERMILPV, DL, MVT::v8f32, HiHi, IndicesVec),
          DAG.getNode(X86ISD::VPERMILPV, DL, MVT::v8f32, LoLo, IndicesVec),
          ISD::CondCode::SETGT);
      return DAG.getBitcast(VT, Res);
    }
    break;
  case MVT::v4i64:
  case MVT::v4f64:
    if (Subtarget.hasAVX512()) {
      if (!Subtarget.hasVLX()) {
        MVT WidenSrcVT = MVT::getVectorVT(VT.getScalarType(), 8);
        SrcVec = widenSubVector(WidenSrcVT, SrcVec, false, Subtarget, DAG,
                                SDLoc(SrcVec));
        IndicesVec = widenSubVector(MVT::v8i64, IndicesVec, false, Subtarget,
                                    DAG, SDLoc(IndicesVec));
        SDValue Res = createVariablePermute(WidenSrcVT, SrcVec, IndicesVec, DL,
                                            DAG, Subtarget);
        return extract256BitVector(Res, 0, DAG, DL);
      }
      Opcode = X86ISD::VPERMV;
    } else if (Subtarget.hasAVX()) {
      SrcVec = DAG.getBitcast(MVT::v4f64, SrcVec);
      SDValue LoLo =
          DAG.getVectorShuffle(MVT::v4f64, DL, SrcVec, SrcVec, {0, 1, 0, 1});
      SDValue HiHi =
          DAG.getVectorShuffle(MVT::v4f64, DL, SrcVec, SrcVec, {2, 3, 2, 3});
      // VPERMIL2PD selects with bit#1 of the index vector, so scale IndicesVec.
      IndicesVec = DAG.getNode(ISD::ADD, DL, IndicesVT, IndicesVec, IndicesVec);
      if (Subtarget.hasXOP())
        return DAG.getBitcast(
            VT, DAG.getNode(X86ISD::VPERMIL2, DL, MVT::v4f64, LoLo, HiHi,
                            IndicesVec, DAG.getTargetConstant(0, DL, MVT::i8)));
      // Permute Lo and Hi and then select based on index range.
      // This works as VPERMILPD only uses index bit[1] to permute elements.
      SDValue Res = DAG.getSelectCC(
          DL, IndicesVec, DAG.getConstant(2, DL, MVT::v4i64),
          DAG.getNode(X86ISD::VPERMILPV, DL, MVT::v4f64, HiHi, IndicesVec),
          DAG.getNode(X86ISD::VPERMILPV, DL, MVT::v4f64, LoLo, IndicesVec),
          ISD::CondCode::SETGT);
      return DAG.getBitcast(VT, Res);
    }
    break;
  case MVT::v64i8:
    if (Subtarget.hasVBMI())
      Opcode = X86ISD::VPERMV;
    break;
  case MVT::v32i16:
    if (Subtarget.hasBWI())
      Opcode = X86ISD::VPERMV;
    break;
  case MVT::v16f32:
  case MVT::v16i32:
  case MVT::v8f64:
  case MVT::v8i64:
    if (Subtarget.hasAVX512())
      Opcode = X86ISD::VPERMV;
    break;
  }
  if (!Opcode)
    return SDValue();

  assert((VT.getSizeInBits() == ShuffleVT.getSizeInBits()) &&
         (VT.getScalarSizeInBits() % ShuffleVT.getScalarSizeInBits()) == 0 &&
         "Illegal variable permute shuffle type");

  uint64_t Scale = VT.getScalarSizeInBits() / ShuffleVT.getScalarSizeInBits();
  if (Scale > 1)
    IndicesVec = ScaleIndices(IndicesVec, Scale);

  EVT ShuffleIdxVT = EVT(ShuffleVT).changeVectorElementTypeToInteger();
  IndicesVec = DAG.getBitcast(ShuffleIdxVT, IndicesVec);

  SrcVec = DAG.getBitcast(ShuffleVT, SrcVec);
  SDValue Res = Opcode == X86ISD::VPERMV
                    ? DAG.getNode(Opcode, DL, ShuffleVT, IndicesVec, SrcVec)
                    : DAG.getNode(Opcode, DL, ShuffleVT, SrcVec, IndicesVec);
  return DAG.getBitcast(VT, Res);
}

// Tries to lower a BUILD_VECTOR composed of extract-extract chains that can be
// reasoned to be a permutation of a vector by indices in a non-constant vector.
// (build_vector (extract_elt V, (extract_elt I, 0)),
//               (extract_elt V, (extract_elt I, 1)),
//                    ...
// ->
// (vpermv I, V)
//
// TODO: Handle undefs
// TODO: Utilize pshufb and zero mask blending to support more efficient
// construction of vectors with constant-0 elements.
static SDValue
LowerBUILD_VECTORAsVariablePermute(SDValue V, SelectionDAG &DAG,
                                   const X86Subtarget &Subtarget) {
  SDValue SrcVec, IndicesVec;
  // Check for a match of the permute source vector and permute index elements.
  // This is done by checking that the i-th build_vector operand is of the form:
  // (extract_elt SrcVec, (extract_elt IndicesVec, i)).
  for (unsigned Idx = 0, E = V.getNumOperands(); Idx != E; ++Idx) {
    SDValue Op = V.getOperand(Idx);
    if (Op.getOpcode() != ISD::EXTRACT_VECTOR_ELT)
      return SDValue();

    // If this is the first extract encountered in V, set the source vector,
    // otherwise verify the extract is from the previously defined source
    // vector.
    if (!SrcVec)
      SrcVec = Op.getOperand(0);
    else if (SrcVec != Op.getOperand(0))
      return SDValue();
    SDValue ExtractedIndex = Op->getOperand(1);
    // Peek through extends.
    if (ExtractedIndex.getOpcode() == ISD::ZERO_EXTEND ||
        ExtractedIndex.getOpcode() == ISD::SIGN_EXTEND)
      ExtractedIndex = ExtractedIndex.getOperand(0);
    if (ExtractedIndex.getOpcode() != ISD::EXTRACT_VECTOR_ELT)
      return SDValue();

    // If this is the first extract from the index vector candidate, set the
    // indices vector, otherwise verify the extract is from the previously
    // defined indices vector.
    if (!IndicesVec)
      IndicesVec = ExtractedIndex.getOperand(0);
    else if (IndicesVec != ExtractedIndex.getOperand(0))
      return SDValue();

    auto *PermIdx = dyn_cast<ConstantSDNode>(ExtractedIndex.getOperand(1));
    if (!PermIdx || PermIdx->getAPIntValue() != Idx)
      return SDValue();
  }

  SDLoc DL(V);
  MVT VT = V.getSimpleValueType();
  return createVariablePermute(VT, SrcVec, IndicesVec, DL, DAG, Subtarget);
}

SDValue
X86TargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const {
  SDLoc dl(Op);

  MVT VT = Op.getSimpleValueType();
  MVT EltVT = VT.getVectorElementType();
  unsigned NumElems = Op.getNumOperands();

  // Generate vectors for predicate vectors.
  if (VT.getVectorElementType() == MVT::i1 && Subtarget.hasAVX512())
    return LowerBUILD_VECTORvXi1(Op, DAG, Subtarget);

  if (SDValue VectorConstant = materializeVectorConstant(Op, DAG, Subtarget))
    return VectorConstant;

  BuildVectorSDNode *BV = cast<BuildVectorSDNode>(Op.getNode());
  if (SDValue AddSub = lowerToAddSubOrFMAddSub(BV, Subtarget, DAG))
    return AddSub;
  if (SDValue HorizontalOp = LowerToHorizontalOp(BV, Subtarget, DAG))
    return HorizontalOp;
  if (SDValue Broadcast = lowerBuildVectorAsBroadcast(BV, Subtarget, DAG))
    return Broadcast;
  if (SDValue BitOp = lowerBuildVectorToBitOp(BV, DAG))
    return BitOp;

  unsigned EVTBits = EltVT.getSizeInBits();

  unsigned NumZero  = 0;
  unsigned NumNonZero = 0;
  uint64_t NonZeros = 0;
  bool IsAllConstants = true;
  SmallSet<SDValue, 8> Values;
  unsigned NumConstants = NumElems;
  for (unsigned i = 0; i < NumElems; ++i) {
    SDValue Elt = Op.getOperand(i);
    if (Elt.isUndef())
      continue;
    Values.insert(Elt);
    if (!isa<ConstantSDNode>(Elt) && !isa<ConstantFPSDNode>(Elt)) {
      IsAllConstants = false;
      NumConstants--;
    }
    if (X86::isZeroNode(Elt))
      NumZero++;
    else {
      assert(i < sizeof(NonZeros) * 8); // Make sure the shift is within range.
      NonZeros |= ((uint64_t)1 << i);
      NumNonZero++;
    }
  }

  // All undef vector. Return an UNDEF.  All zero vectors were handled above.
  if (NumNonZero == 0)
    return DAG.getUNDEF(VT);

  // If we are inserting one variable into a vector of non-zero constants, try
  // to avoid loading each constant element as a scalar. Load the constants as a
  // vector and then insert the variable scalar element. If insertion is not
  // supported, fall back to a shuffle to get the scalar blended with the
  // constants. Insertion into a zero vector is handled as a special-case
  // somewhere below here.
  if (NumConstants == NumElems - 1 && NumNonZero != 1 &&
      (isOperationLegalOrCustom(ISD::INSERT_VECTOR_ELT, VT) ||
       isOperationLegalOrCustom(ISD::VECTOR_SHUFFLE, VT))) {
    // Create an all-constant vector. The variable element in the old
    // build vector is replaced by undef in the constant vector. Save the
    // variable scalar element and its index for use in the insertelement.
    LLVMContext &Context = *DAG.getContext();
    Type *EltType = Op.getValueType().getScalarType().getTypeForEVT(Context);
    SmallVector<Constant *, 16> ConstVecOps(NumElems, UndefValue::get(EltType));
    SDValue VarElt;
    SDValue InsIndex;
    for (unsigned i = 0; i != NumElems; ++i) {
      SDValue Elt = Op.getOperand(i);
      if (auto *C = dyn_cast<ConstantSDNode>(Elt))
        ConstVecOps[i] = ConstantInt::get(Context, C->getAPIntValue());
      else if (auto *C = dyn_cast<ConstantFPSDNode>(Elt))
        ConstVecOps[i] = ConstantFP::get(Context, C->getValueAPF());
      else if (!Elt.isUndef()) {
        assert(!VarElt.getNode() && !InsIndex.getNode() &&
               "Expected one variable element in this vector");
        VarElt = Elt;
        InsIndex = DAG.getVectorIdxConstant(i, dl);
      }
    }
    Constant *CV = ConstantVector::get(ConstVecOps);
    SDValue DAGConstVec = DAG.getConstantPool(CV, VT);

    // The constants we just created may not be legal (eg, floating point). We
    // must lower the vector right here because we can not guarantee that we'll
    // legalize it before loading it. This is also why we could not just create
    // a new build vector here. If the build vector contains illegal constants,
    // it could get split back up into a series of insert elements.
    // TODO: Improve this by using shorter loads with broadcast/VZEXT_LOAD.
    SDValue LegalDAGConstVec = LowerConstantPool(DAGConstVec, DAG);
    MachineFunction &MF = DAG.getMachineFunction();
    MachinePointerInfo MPI = MachinePointerInfo::getConstantPool(MF);
    SDValue Ld = DAG.getLoad(VT, dl, DAG.getEntryNode(), LegalDAGConstVec, MPI);
    unsigned InsertC = cast<ConstantSDNode>(InsIndex)->getZExtValue();
    unsigned NumEltsInLow128Bits = 128 / VT.getScalarSizeInBits();
    if (InsertC < NumEltsInLow128Bits)
      return DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, Ld, VarElt, InsIndex);

    // There's no good way to insert into the high elements of a >128-bit
    // vector, so use shuffles to avoid an extract/insert sequence.
    assert(VT.getSizeInBits() > 128 && "Invalid insertion index?");
    assert(Subtarget.hasAVX() && "Must have AVX with >16-byte vector");
    SmallVector<int, 8> ShuffleMask;
    unsigned NumElts = VT.getVectorNumElements();
    for (unsigned i = 0; i != NumElts; ++i)
      ShuffleMask.push_back(i == InsertC ? NumElts : i);
    SDValue S2V = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, VarElt);
    return DAG.getVectorShuffle(VT, dl, Ld, S2V, ShuffleMask);
  }

  // Special case for single non-zero, non-undef, element.
  if (NumNonZero == 1) {
    unsigned Idx = countTrailingZeros(NonZeros);
    SDValue Item = Op.getOperand(Idx);

    // If we have a constant or non-constant insertion into the low element of
    // a vector, we can do this with SCALAR_TO_VECTOR + shuffle of zero into
    // the rest of the elements.  This will be matched as movd/movq/movss/movsd
    // depending on what the source datatype is.
    if (Idx == 0) {
      if (NumZero == 0)
        return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Item);

      if (EltVT == MVT::i32 || EltVT == MVT::f32 || EltVT == MVT::f64 ||
          (EltVT == MVT::i64 && Subtarget.is64Bit())) {
        assert((VT.is128BitVector() || VT.is256BitVector() ||
                VT.is512BitVector()) &&
               "Expected an SSE value type!");
        Item = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Item);
        // Turn it into a MOVL (i.e. movss, movsd, or movd) to a zero vector.
        return getShuffleVectorZeroOrUndef(Item, 0, true, Subtarget, DAG);
      }

      // We can't directly insert an i8 or i16 into a vector, so zero extend
      // it to i32 first.
      if (EltVT == MVT::i16 || EltVT == MVT::i8) {
        Item = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, Item);
        MVT ShufVT = MVT::getVectorVT(MVT::i32, VT.getSizeInBits()/32);
        Item = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, ShufVT, Item);
        Item = getShuffleVectorZeroOrUndef(Item, 0, true, Subtarget, DAG);
        return DAG.getBitcast(VT, Item);
      }
    }

    // Is it a vector logical left shift?
    if (NumElems == 2 && Idx == 1 &&
        X86::isZeroNode(Op.getOperand(0)) &&
        !X86::isZeroNode(Op.getOperand(1))) {
      unsigned NumBits = VT.getSizeInBits();
      return getVShift(true, VT,
                       DAG.getNode(ISD::SCALAR_TO_VECTOR, dl,
                                   VT, Op.getOperand(1)),
                       NumBits/2, DAG, *this, dl);
    }

    if (IsAllConstants) // Otherwise, it's better to do a constpool load.
      return SDValue();

    // Otherwise, if this is a vector with i32 or f32 elements, and the element
    // is a non-constant being inserted into an element other than the low one,
    // we can't use a constant pool load.  Instead, use SCALAR_TO_VECTOR (aka
    // movd/movss) to move this into the low element, then shuffle it into
    // place.
    if (EVTBits == 32) {
      Item = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Item);
      return getShuffleVectorZeroOrUndef(Item, Idx, NumZero > 0, Subtarget, DAG);
    }
  }

  // Splat is obviously ok. Let legalizer expand it to a shuffle.
  if (Values.size() == 1) {
    if (EVTBits == 32) {
      // Instead of a shuffle like this:
      // shuffle (scalar_to_vector (load (ptr + 4))), undef, <0, 0, 0, 0>
      // Check if it's possible to issue this instead.
      // shuffle (vload ptr)), undef, <1, 1, 1, 1>
      unsigned Idx = countTrailingZeros(NonZeros);
      SDValue Item = Op.getOperand(Idx);
      if (Op.getNode()->isOnlyUserOf(Item.getNode()))
        return LowerAsSplatVectorLoad(Item, VT, dl, DAG);
    }
    return SDValue();
  }

  // A vector full of immediates; various special cases are already
  // handled, so this is best done with a single constant-pool load.
  if (IsAllConstants)
    return SDValue();

  if (SDValue V = LowerBUILD_VECTORAsVariablePermute(Op, DAG, Subtarget))
      return V;

  // See if we can use a vector load to get all of the elements.
  {
    SmallVector<SDValue, 64> Ops(Op->op_begin(), Op->op_begin() + NumElems);
    if (SDValue LD =
            EltsFromConsecutiveLoads(VT, Ops, dl, DAG, Subtarget, false))
      return LD;
  }

  // If this is a splat of pairs of 32-bit elements, we can use a narrower
  // build_vector and broadcast it.
  // TODO: We could probably generalize this more.
  if (Subtarget.hasAVX2() && EVTBits == 32 && Values.size() == 2) {
    SDValue Ops[4] = { Op.getOperand(0), Op.getOperand(1),
                       DAG.getUNDEF(EltVT), DAG.getUNDEF(EltVT) };
    auto CanSplat = [](SDValue Op, unsigned NumElems, ArrayRef<SDValue> Ops) {
      // Make sure all the even/odd operands match.
      for (unsigned i = 2; i != NumElems; ++i)
        if (Ops[i % 2] != Op.getOperand(i))
          return false;
      return true;
    };
    if (CanSplat(Op, NumElems, Ops)) {
      MVT WideEltVT = VT.isFloatingPoint() ? MVT::f64 : MVT::i64;
      MVT NarrowVT = MVT::getVectorVT(EltVT, 4);
      // Create a new build vector and cast to v2i64/v2f64.
      SDValue NewBV = DAG.getBitcast(MVT::getVectorVT(WideEltVT, 2),
                                     DAG.getBuildVector(NarrowVT, dl, Ops));
      // Broadcast from v2i64/v2f64 and cast to final VT.
      MVT BcastVT = MVT::getVectorVT(WideEltVT, NumElems/2);
      return DAG.getBitcast(VT, DAG.getNode(X86ISD::VBROADCAST, dl, BcastVT,
                                            NewBV));
    }
  }

  // For AVX-length vectors, build the individual 128-bit pieces and use
  // shuffles to put them in place.
  if (VT.getSizeInBits() > 128) {
    MVT HVT = MVT::getVectorVT(EltVT, NumElems/2);

    // Build both the lower and upper subvector.
    SDValue Lower =
        DAG.getBuildVector(HVT, dl, Op->ops().slice(0, NumElems / 2));
    SDValue Upper = DAG.getBuildVector(
        HVT, dl, Op->ops().slice(NumElems / 2, NumElems /2));

    // Recreate the wider vector with the lower and upper part.
    return concatSubVectors(Lower, Upper, DAG, dl);
  }

  // Let legalizer expand 2-wide build_vectors.
  if (EVTBits == 64) {
    if (NumNonZero == 1) {
      // One half is zero or undef.
      unsigned Idx = countTrailingZeros(NonZeros);
      SDValue V2 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT,
                               Op.getOperand(Idx));
      return getShuffleVectorZeroOrUndef(V2, Idx, true, Subtarget, DAG);
    }
    return SDValue();
  }

  // If element VT is < 32 bits, convert it to inserts into a zero vector.
  if (EVTBits == 8 && NumElems == 16)
    if (SDValue V = LowerBuildVectorv16i8(Op, NonZeros, NumNonZero, NumZero,
                                          DAG, Subtarget))
      return V;

  if (EVTBits == 16 && NumElems == 8)
    if (SDValue V = LowerBuildVectorv8i16(Op, NonZeros, NumNonZero, NumZero,
                                          DAG, Subtarget))
      return V;

  // If element VT is == 32 bits and has 4 elems, try to generate an INSERTPS
  if (EVTBits == 32 && NumElems == 4)
    if (SDValue V = LowerBuildVectorv4x32(Op, DAG, Subtarget))
      return V;

  // If element VT is == 32 bits, turn it into a number of shuffles.
  if (NumElems == 4 && NumZero > 0) {
    SmallVector<SDValue, 8> Ops(NumElems);
    for (unsigned i = 0; i < 4; ++i) {
      bool isZero = !(NonZeros & (1ULL << i));
      if (isZero)
        Ops[i] = getZeroVector(VT, Subtarget, DAG, dl);
      else
        Ops[i] = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Op.getOperand(i));
    }

    for (unsigned i = 0; i < 2; ++i) {
      switch ((NonZeros >> (i*2)) & 0x3) {
        default: llvm_unreachable("Unexpected NonZero count");
        case 0:
          Ops[i] = Ops[i*2];  // Must be a zero vector.
          break;
        case 1:
          Ops[i] = getMOVL(DAG, dl, VT, Ops[i*2+1], Ops[i*2]);
          break;
        case 2:
          Ops[i] = getMOVL(DAG, dl, VT, Ops[i*2], Ops[i*2+1]);
          break;
        case 3:
          Ops[i] = getUnpackl(DAG, dl, VT, Ops[i*2], Ops[i*2+1]);
          break;
      }
    }

    bool Reverse1 = (NonZeros & 0x3) == 2;
    bool Reverse2 = ((NonZeros & (0x3 << 2)) >> 2) == 2;
    int MaskVec[] = {
      Reverse1 ? 1 : 0,
      Reverse1 ? 0 : 1,
      static_cast<int>(Reverse2 ? NumElems+1 : NumElems),
      static_cast<int>(Reverse2 ? NumElems   : NumElems+1)
    };
    return DAG.getVectorShuffle(VT, dl, Ops[0], Ops[1], MaskVec);
  }

  assert(Values.size() > 1 && "Expected non-undef and non-splat vector");

  // Check for a build vector from mostly shuffle plus few inserting.
  if (SDValue Sh = buildFromShuffleMostly(Op, DAG))
    return Sh;

  // For SSE 4.1, use insertps to put the high elements into the low element.
  if (Subtarget.hasSSE41()) {
    SDValue Result;
    if (!Op.getOperand(0).isUndef())
      Result = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Op.getOperand(0));
    else
      Result = DAG.getUNDEF(VT);

    for (unsigned i = 1; i < NumElems; ++i) {
      if (Op.getOperand(i).isUndef()) continue;
      Result = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, Result,
                           Op.getOperand(i), DAG.getIntPtrConstant(i, dl));
    }
    return Result;
  }

  // Otherwise, expand into a number of unpckl*, start by extending each of
  // our (non-undef) elements to the full vector width with the element in the
  // bottom slot of the vector (which generates no code for SSE).
  SmallVector<SDValue, 8> Ops(NumElems);
  for (unsigned i = 0; i < NumElems; ++i) {
    if (!Op.getOperand(i).isUndef())
      Ops[i] = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Op.getOperand(i));
    else
      Ops[i] = DAG.getUNDEF(VT);
  }

  // Next, we iteratively mix elements, e.g. for v4f32:
  //   Step 1: unpcklps 0, 1 ==> X: <?, ?, 1, 0>
  //         : unpcklps 2, 3 ==> Y: <?, ?, 3, 2>
  //   Step 2: unpcklpd X, Y ==>    <3, 2, 1, 0>
  for (unsigned Scale = 1; Scale < NumElems; Scale *= 2) {
    // Generate scaled UNPCKL shuffle mask.
    SmallVector<int, 16> Mask;
    for(unsigned i = 0; i != Scale; ++i)
      Mask.push_back(i);
    for (unsigned i = 0; i != Scale; ++i)
      Mask.push_back(NumElems+i);
    Mask.append(NumElems - Mask.size(), SM_SentinelUndef);

    for (unsigned i = 0, e = NumElems / (2 * Scale); i != e; ++i)
      Ops[i] = DAG.getVectorShuffle(VT, dl, Ops[2*i], Ops[(2*i)+1], Mask);
  }
  return Ops[0];
}

// 256-bit AVX can use the vinsertf128 instruction
// to create 256-bit vectors from two other 128-bit ones.
// TODO: Detect subvector broadcast here instead of DAG combine?
static SDValue LowerAVXCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG,
                                      const X86Subtarget &Subtarget) {
  SDLoc dl(Op);
  MVT ResVT = Op.getSimpleValueType();

  assert((ResVT.is256BitVector() ||
          ResVT.is512BitVector()) && "Value type must be 256-/512-bit wide");

  unsigned NumOperands = Op.getNumOperands();
  unsigned NumZero = 0;
  unsigned NumNonZero = 0;
  unsigned NonZeros = 0;
  for (unsigned i = 0; i != NumOperands; ++i) {
    SDValue SubVec = Op.getOperand(i);
    if (SubVec.isUndef())
      continue;
    if (ISD::isBuildVectorAllZeros(SubVec.getNode()))
      ++NumZero;
    else {
      assert(i < sizeof(NonZeros) * CHAR_BIT); // Ensure the shift is in range.
      NonZeros |= 1 << i;
      ++NumNonZero;
    }
  }

  // If we have more than 2 non-zeros, build each half separately.
  if (NumNonZero > 2) {
    MVT HalfVT = ResVT.getHalfNumVectorElementsVT();
    ArrayRef<SDUse> Ops = Op->ops();
    SDValue Lo = DAG.getNode(ISD::CONCAT_VECTORS, dl, HalfVT,
                             Ops.slice(0, NumOperands/2));
    SDValue Hi = DAG.getNode(ISD::CONCAT_VECTORS, dl, HalfVT,
                             Ops.slice(NumOperands/2));
    return DAG.getNode(ISD::CONCAT_VECTORS, dl, ResVT, Lo, Hi);
  }

  // Otherwise, build it up through insert_subvectors.
  SDValue Vec = NumZero ? getZeroVector(ResVT, Subtarget, DAG, dl)
                        : DAG.getUNDEF(ResVT);

  MVT SubVT = Op.getOperand(0).getSimpleValueType();
  unsigned NumSubElems = SubVT.getVectorNumElements();
  for (unsigned i = 0; i != NumOperands; ++i) {
    if ((NonZeros & (1 << i)) == 0)
      continue;

    Vec = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT, Vec,
                      Op.getOperand(i),
                      DAG.getIntPtrConstant(i * NumSubElems, dl));
  }

  return Vec;
}

// Returns true if the given node is a type promotion (by concatenating i1
// zeros) of the result of a node that already zeros all upper bits of
// k-register.
// TODO: Merge this with LowerAVXCONCAT_VECTORS?
static SDValue LowerCONCAT_VECTORSvXi1(SDValue Op,
                                       const X86Subtarget &Subtarget,
                                       SelectionDAG & DAG) {
  SDLoc dl(Op);
  MVT ResVT = Op.getSimpleValueType();
  unsigned NumOperands = Op.getNumOperands();

  assert(NumOperands > 1 && isPowerOf2_32(NumOperands) &&
         "Unexpected number of operands in CONCAT_VECTORS");

  uint64_t Zeros = 0;
  uint64_t NonZeros = 0;
  for (unsigned i = 0; i != NumOperands; ++i) {
    SDValue SubVec = Op.getOperand(i);
    if (SubVec.isUndef())
      continue;
    assert(i < sizeof(NonZeros) * CHAR_BIT); // Ensure the shift is in range.
    if (ISD::isBuildVectorAllZeros(SubVec.getNode()))
      Zeros |= (uint64_t)1 << i;
    else
      NonZeros |= (uint64_t)1 << i;
  }

  unsigned NumElems = ResVT.getVectorNumElements();

  // If we are inserting non-zero vector and there are zeros in LSBs and undef
  // in the MSBs we need to emit a KSHIFTL. The generic lowering to
  // insert_subvector will give us two kshifts.
  if (isPowerOf2_64(NonZeros) && Zeros != 0 && NonZeros > Zeros &&
      Log2_64(NonZeros) != NumOperands - 1) {
    MVT ShiftVT = ResVT;
    if ((!Subtarget.hasDQI() && NumElems == 8) || NumElems < 8)
      ShiftVT = Subtarget.hasDQI() ? MVT::v8i1 : MVT::v16i1;
    unsigned Idx = Log2_64(NonZeros);
    SDValue SubVec = Op.getOperand(Idx);
    unsigned SubVecNumElts = SubVec.getSimpleValueType().getVectorNumElements();
    SubVec = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ShiftVT,
                         DAG.getUNDEF(ShiftVT), SubVec,
                         DAG.getIntPtrConstant(0, dl));
    Op = DAG.getNode(X86ISD::KSHIFTL, dl, ShiftVT, SubVec,
                     DAG.getTargetConstant(Idx * SubVecNumElts, dl, MVT::i8));
    return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, ResVT, Op,
                       DAG.getIntPtrConstant(0, dl));
  }

  // If there are zero or one non-zeros we can handle this very simply.
  if (NonZeros == 0 || isPowerOf2_64(NonZeros)) {
    SDValue Vec = Zeros ? DAG.getConstant(0, dl, ResVT) : DAG.getUNDEF(ResVT);
    if (!NonZeros)
      return Vec;
    unsigned Idx = Log2_64(NonZeros);
    SDValue SubVec = Op.getOperand(Idx);
    unsigned SubVecNumElts = SubVec.getSimpleValueType().getVectorNumElements();
    return DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT, Vec, SubVec,
                       DAG.getIntPtrConstant(Idx * SubVecNumElts, dl));
  }

  if (NumOperands > 2) {
    MVT HalfVT = ResVT.getHalfNumVectorElementsVT();
    ArrayRef<SDUse> Ops = Op->ops();
    SDValue Lo = DAG.getNode(ISD::CONCAT_VECTORS, dl, HalfVT,
                             Ops.slice(0, NumOperands/2));
    SDValue Hi = DAG.getNode(ISD::CONCAT_VECTORS, dl, HalfVT,
                             Ops.slice(NumOperands/2));
    return DAG.getNode(ISD::CONCAT_VECTORS, dl, ResVT, Lo, Hi);
  }

  assert(countPopulation(NonZeros) == 2 && "Simple cases not handled?");

  if (ResVT.getVectorNumElements() >= 16)
    return Op; // The operation is legal with KUNPCK

  SDValue Vec = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT,
                            DAG.getUNDEF(ResVT), Op.getOperand(0),
                            DAG.getIntPtrConstant(0, dl));
  return DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT, Vec, Op.getOperand(1),
                     DAG.getIntPtrConstant(NumElems/2, dl));
}

static SDValue LowerCONCAT_VECTORS(SDValue Op,
                                   const X86Subtarget &Subtarget,
                                   SelectionDAG &DAG) {
  MVT VT = Op.getSimpleValueType();
  if (VT.getVectorElementType() == MVT::i1)
    return LowerCONCAT_VECTORSvXi1(Op, Subtarget, DAG);

  assert((VT.is256BitVector() && Op.getNumOperands() == 2) ||
         (VT.is512BitVector() && (Op.getNumOperands() == 2 ||
          Op.getNumOperands() == 4)));

  // AVX can use the vinsertf128 instruction to create 256-bit vectors
  // from two other 128-bit ones.

  // 512-bit vector may contain 2 256-bit vectors or 4 128-bit vectors
  return LowerAVXCONCAT_VECTORS(Op, DAG, Subtarget);
}

//===----------------------------------------------------------------------===//
// Vector shuffle lowering
//
// This is an experimental code path for lowering vector shuffles on x86. It is
// designed to handle arbitrary vector shuffles and blends, gracefully
// degrading performance as necessary. It works hard to recognize idiomatic
// shuffles and lower them to optimal instruction patterns without leaving
// a framework that allows reasonably efficient handling of all vector shuffle
// patterns.
//===----------------------------------------------------------------------===//

/// Tiny helper function to identify a no-op mask.
///
/// This is a somewhat boring predicate function. It checks whether the mask
/// array input, which is assumed to be a single-input shuffle mask of the kind
/// used by the X86 shuffle instructions (not a fully general
/// ShuffleVectorSDNode mask) requires any shuffles to occur. Both undef and an
/// in-place shuffle are 'no-op's.
static bool isNoopShuffleMask(ArrayRef<int> Mask) {
  for (int i = 0, Size = Mask.size(); i < Size; ++i) {
    assert(Mask[i] >= -1 && "Out of bound mask element!");
    if (Mask[i] >= 0 && Mask[i] != i)
      return false;
  }
  return true;
}

/// Test whether there are elements crossing LaneSizeInBits lanes in this
/// shuffle mask.
///
/// X86 divides up its shuffles into in-lane and cross-lane shuffle operations
/// and we routinely test for these.
static bool isLaneCrossingShuffleMask(unsigned LaneSizeInBits,
                                      unsigned ScalarSizeInBits,
                                      ArrayRef<int> Mask) {
  assert(LaneSizeInBits && ScalarSizeInBits &&
         (LaneSizeInBits % ScalarSizeInBits) == 0 &&
         "Illegal shuffle lane size");
  int LaneSize = LaneSizeInBits / ScalarSizeInBits;
  int Size = Mask.size();
  for (int i = 0; i < Size; ++i)
    if (Mask[i] >= 0 && (Mask[i] % Size) / LaneSize != i / LaneSize)
      return true;
  return false;
}

/// Test whether there are elements crossing 128-bit lanes in this
/// shuffle mask.
static bool is128BitLaneCrossingShuffleMask(MVT VT, ArrayRef<int> Mask) {
  return isLaneCrossingShuffleMask(128, VT.getScalarSizeInBits(), Mask);
}

/// Test whether a shuffle mask is equivalent within each sub-lane.
///
/// This checks a shuffle mask to see if it is performing the same
/// lane-relative shuffle in each sub-lane. This trivially implies
/// that it is also not lane-crossing. It may however involve a blend from the
/// same lane of a second vector.
///
/// The specific repeated shuffle mask is populated in \p RepeatedMask, as it is
/// non-trivial to compute in the face of undef lanes. The representation is
/// suitable for use with existing 128-bit shuffles as entries from the second
/// vector have been remapped to [LaneSize, 2*LaneSize).
static bool isRepeatedShuffleMask(unsigned LaneSizeInBits, MVT VT,
                                  ArrayRef<int> Mask,
                                  SmallVectorImpl<int> &RepeatedMask) {
  auto LaneSize = LaneSizeInBits / VT.getScalarSizeInBits();
  RepeatedMask.assign(LaneSize, -1);
  int Size = Mask.size();
  for (int i = 0; i < Size; ++i) {
    assert(Mask[i] == SM_SentinelUndef || Mask[i] >= 0);
    if (Mask[i] < 0)
      continue;
    if ((Mask[i] % Size) / LaneSize != i / LaneSize)
      // This entry crosses lanes, so there is no way to model this shuffle.
      return false;

    // Ok, handle the in-lane shuffles by detecting if and when they repeat.
    // Adjust second vector indices to start at LaneSize instead of Size.
    int LocalM = Mask[i] < Size ? Mask[i] % LaneSize
                                : Mask[i] % LaneSize + LaneSize;
    if (RepeatedMask[i % LaneSize] < 0)
      // This is the first non-undef entry in this slot of a 128-bit lane.
      RepeatedMask[i % LaneSize] = LocalM;
    else if (RepeatedMask[i % LaneSize] != LocalM)
      // Found a mismatch with the repeated mask.
      return false;
  }
  return true;
}

/// Test whether a shuffle mask is equivalent within each 128-bit lane.
static bool
is128BitLaneRepeatedShuffleMask(MVT VT, ArrayRef<int> Mask,
                                SmallVectorImpl<int> &RepeatedMask) {
  return isRepeatedShuffleMask(128, VT, Mask, RepeatedMask);
}

static bool
is128BitLaneRepeatedShuffleMask(MVT VT, ArrayRef<int> Mask) {
  SmallVector<int, 32> RepeatedMask;
  return isRepeatedShuffleMask(128, VT, Mask, RepeatedMask);
}

/// Test whether a shuffle mask is equivalent within each 256-bit lane.
static bool
is256BitLaneRepeatedShuffleMask(MVT VT, ArrayRef<int> Mask,
                                SmallVectorImpl<int> &RepeatedMask) {
  return isRepeatedShuffleMask(256, VT, Mask, RepeatedMask);
}

/// Test whether a target shuffle mask is equivalent within each sub-lane.
/// Unlike isRepeatedShuffleMask we must respect SM_SentinelZero.
static bool isRepeatedTargetShuffleMask(unsigned LaneSizeInBits, MVT VT,
                                        ArrayRef<int> Mask,
                                        SmallVectorImpl<int> &RepeatedMask) {
  int LaneSize = LaneSizeInBits / VT.getScalarSizeInBits();
  RepeatedMask.assign(LaneSize, SM_SentinelUndef);
  int Size = Mask.size();
  for (int i = 0; i < Size; ++i) {
    assert(isUndefOrZero(Mask[i]) || (Mask[i] >= 0));
    if (Mask[i] == SM_SentinelUndef)
      continue;
    if (Mask[i] == SM_SentinelZero) {
      if (!isUndefOrZero(RepeatedMask[i % LaneSize]))
        return false;
      RepeatedMask[i % LaneSize] = SM_SentinelZero;
      continue;
    }
    if ((Mask[i] % Size) / LaneSize != i / LaneSize)
      // This entry crosses lanes, so there is no way to model this shuffle.
      return false;

    // Ok, handle the in-lane shuffles by detecting if and when they repeat.
    // Adjust second vector indices to start at LaneSize instead of Size.
    int LocalM =
        Mask[i] < Size ? Mask[i] % LaneSize : Mask[i] % LaneSize + LaneSize;
    if (RepeatedMask[i % LaneSize] == SM_SentinelUndef)
      // This is the first non-undef entry in this slot of a 128-bit lane.
      RepeatedMask[i % LaneSize] = LocalM;
    else if (RepeatedMask[i % LaneSize] != LocalM)
      // Found a mismatch with the repeated mask.
      return false;
  }
  return true;
}

/// Checks whether a shuffle mask is equivalent to an explicit list of
/// arguments.
///
/// This is a fast way to test a shuffle mask against a fixed pattern:
///
///   if (isShuffleEquivalent(Mask, 3, 2, {1, 0})) { ... }
///
/// It returns true if the mask is exactly as wide as the argument list, and
/// each element of the mask is either -1 (signifying undef) or the value given
/// in the argument.
static bool isShuffleEquivalent(SDValue V1, SDValue V2, ArrayRef<int> Mask,
                                ArrayRef<int> ExpectedMask) {
  if (Mask.size() != ExpectedMask.size())
    return false;

  int Size = Mask.size();

  // If the values are build vectors, we can look through them to find
  // equivalent inputs that make the shuffles equivalent.
  auto *BV1 = dyn_cast<BuildVectorSDNode>(V1);
  auto *BV2 = dyn_cast<BuildVectorSDNode>(V2);

  for (int i = 0; i < Size; ++i) {
    assert(Mask[i] >= -1 && "Out of bound mask element!");
    if (Mask[i] >= 0 && Mask[i] != ExpectedMask[i]) {
      auto *MaskBV = Mask[i] < Size ? BV1 : BV2;
      auto *ExpectedBV = ExpectedMask[i] < Size ? BV1 : BV2;
      if (!MaskBV || !ExpectedBV ||
          MaskBV->getOperand(Mask[i] % Size) !=
              ExpectedBV->getOperand(ExpectedMask[i] % Size))
        return false;
    }
  }

  return true;
}

/// Checks whether a target shuffle mask is equivalent to an explicit pattern.
///
/// The masks must be exactly the same width.
///
/// If an element in Mask matches SM_SentinelUndef (-1) then the corresponding
/// value in ExpectedMask is always accepted. Otherwise the indices must match.
///
/// SM_SentinelZero is accepted as a valid negative index but must match in
/// both.
static bool isTargetShuffleEquivalent(ArrayRef<int> Mask,
                                      ArrayRef<int> ExpectedMask,
                                      SDValue V1 = SDValue(),
                                      SDValue V2 = SDValue()) {
  int Size = Mask.size();
  if (Size != (int)ExpectedMask.size())
    return false;
  assert(isUndefOrZeroOrInRange(ExpectedMask, 0, 2 * Size) &&
         "Illegal target shuffle mask");

  // Check for out-of-range target shuffle mask indices.
  if (!isUndefOrZeroOrInRange(Mask, 0, 2 * Size))
    return false;

  // If the values are build vectors, we can look through them to find
  // equivalent inputs that make the shuffles equivalent.
  auto *BV1 = dyn_cast_or_null<BuildVectorSDNode>(V1);
  auto *BV2 = dyn_cast_or_null<BuildVectorSDNode>(V2);
  BV1 = ((BV1 && Size != (int)BV1->getNumOperands()) ? nullptr : BV1);
  BV2 = ((BV2 && Size != (int)BV2->getNumOperands()) ? nullptr : BV2);

  for (int i = 0; i < Size; ++i) {
    if (Mask[i] == SM_SentinelUndef || Mask[i] == ExpectedMask[i])
      continue;
    if (0 <= Mask[i] && 0 <= ExpectedMask[i]) {
      auto *MaskBV = Mask[i] < Size ? BV1 : BV2;
      auto *ExpectedBV = ExpectedMask[i] < Size ? BV1 : BV2;
      if (MaskBV && ExpectedBV &&
          MaskBV->getOperand(Mask[i] % Size) ==
              ExpectedBV->getOperand(ExpectedMask[i] % Size))
        continue;
    }
    // TODO - handle SM_Sentinel equivalences.
    return false;
  }
  return true;
}

// Attempt to create a shuffle mask from a VSELECT condition mask.
static bool createShuffleMaskFromVSELECT(SmallVectorImpl<int> &Mask,
                                         SDValue Cond) {
  if (!ISD::isBuildVectorOfConstantSDNodes(Cond.getNode()))
    return false;

  unsigned Size = Cond.getValueType().getVectorNumElements();
  Mask.resize(Size, SM_SentinelUndef);

  for (int i = 0; i != (int)Size; ++i) {
    SDValue CondElt = Cond.getOperand(i);
    Mask[i] = i;
    // Arbitrarily choose from the 2nd operand if the select condition element
    // is undef.
    // TODO: Can we do better by matching patterns such as even/odd?
    if (CondElt.isUndef() || isNullConstant(CondElt))
      Mask[i] += Size;
  }

  return true;
}

// Check if the shuffle mask is suitable for the AVX vpunpcklwd or vpunpckhwd
// instructions.
static bool isUnpackWdShuffleMask(ArrayRef<int> Mask, MVT VT) {
  if (VT != MVT::v8i32 && VT != MVT::v8f32)
    return false;

  SmallVector<int, 8> Unpcklwd;
  createUnpackShuffleMask(MVT::v8i16, Unpcklwd, /* Lo = */ true,
                          /* Unary = */ false);
  SmallVector<int, 8> Unpckhwd;
  createUnpackShuffleMask(MVT::v8i16, Unpckhwd, /* Lo = */ false,
                          /* Unary = */ false);
  bool IsUnpackwdMask = (isTargetShuffleEquivalent(Mask, Unpcklwd) ||
                         isTargetShuffleEquivalent(Mask, Unpckhwd));
  return IsUnpackwdMask;
}

static bool is128BitUnpackShuffleMask(ArrayRef<int> Mask) {
  // Create 128-bit vector type based on mask size.
  MVT EltVT = MVT::getIntegerVT(128 / Mask.size());
  MVT VT = MVT::getVectorVT(EltVT, Mask.size());

  // We can't assume a canonical shuffle mask, so try the commuted version too.
  SmallVector<int, 4> CommutedMask(Mask.begin(), Mask.end());
  ShuffleVectorSDNode::commuteMask(CommutedMask);

  // Match any of unary/binary or low/high.
  for (unsigned i = 0; i != 4; ++i) {
    SmallVector<int, 16> UnpackMask;
    createUnpackShuffleMask(VT, UnpackMask, (i >> 1) % 2, i % 2);
    if (isTargetShuffleEquivalent(Mask, UnpackMask) ||
        isTargetShuffleEquivalent(CommutedMask, UnpackMask))
      return true;
  }
  return false;
}

/// Return true if a shuffle mask chooses elements identically in its top and
/// bottom halves. For example, any splat mask has the same top and bottom
/// halves. If an element is undefined in only one half of the mask, the halves
/// are not considered identical.
static bool hasIdenticalHalvesShuffleMask(ArrayRef<int> Mask) {
  assert(Mask.size() % 2 == 0 && "Expecting even number of elements in mask");
  unsigned HalfSize = Mask.size() / 2;
  for (unsigned i = 0; i != HalfSize; ++i) {
    if (Mask[i] != Mask[i + HalfSize])
      return false;
  }
  return true;
}

/// Get a 4-lane 8-bit shuffle immediate for a mask.
///
/// This helper function produces an 8-bit shuffle immediate corresponding to
/// the ubiquitous shuffle encoding scheme used in x86 instructions for
/// shuffling 4 lanes. It can be used with most of the PSHUF instructions for
/// example.
///
/// NB: We rely heavily on "undef" masks preserving the input lane.
static unsigned getV4X86ShuffleImm(ArrayRef<int> Mask) {
  assert(Mask.size() == 4 && "Only 4-lane shuffle masks");
  assert(Mask[0] >= -1 && Mask[0] < 4 && "Out of bound mask element!");
  assert(Mask[1] >= -1 && Mask[1] < 4 && "Out of bound mask element!");
  assert(Mask[2] >= -1 && Mask[2] < 4 && "Out of bound mask element!");
  assert(Mask[3] >= -1 && Mask[3] < 4 && "Out of bound mask element!");

  unsigned Imm = 0;
  Imm |= (Mask[0] < 0 ? 0 : Mask[0]) << 0;
  Imm |= (Mask[1] < 0 ? 1 : Mask[1]) << 2;
  Imm |= (Mask[2] < 0 ? 2 : Mask[2]) << 4;
  Imm |= (Mask[3] < 0 ? 3 : Mask[3]) << 6;
  return Imm;
}

static SDValue getV4X86ShuffleImm8ForMask(ArrayRef<int> Mask, const SDLoc &DL,
                                          SelectionDAG &DAG) {
  return DAG.getTargetConstant(getV4X86ShuffleImm(Mask), DL, MVT::i8);
}

// The Shuffle result is as follow:
// 0*a[0]0*a[1]...0*a[n] , n >=0 where a[] elements in a ascending order.
// Each Zeroable's element correspond to a particular Mask's element.
// As described in computeZeroableShuffleElements function.
//
// The function looks for a sub-mask that the nonzero elements are in
// increasing order. If such sub-mask exist. The function returns true.
static bool isNonZeroElementsInOrder(const APInt &Zeroable,
                                     ArrayRef<int> Mask, const EVT &VectorType,
                                     bool &IsZeroSideLeft) {
  int NextElement = -1;
  // Check if the Mask's nonzero elements are in increasing order.
  for (int i = 0, e = Mask.size(); i < e; i++) {
    // Checks if the mask's zeros elements are built from only zeros.
    assert(Mask[i] >= -1 && "Out of bound mask element!");
    if (Mask[i] < 0)
      return false;
    if (Zeroable[i])
      continue;
    // Find the lowest non zero element
    if (NextElement < 0) {
      NextElement = Mask[i] != 0 ? VectorType.getVectorNumElements() : 0;
      IsZeroSideLeft = NextElement != 0;
    }
    // Exit if the mask's non zero elements are not in increasing order.
    if (NextElement != Mask[i])
      return false;
    NextElement++;
  }
  return true;
}

/// Try to lower a shuffle with a single PSHUFB of V1 or V2.
static SDValue lowerShuffleWithPSHUFB(const SDLoc &DL, MVT VT,
                                      ArrayRef<int> Mask, SDValue V1,
                                      SDValue V2, const APInt &Zeroable,
                                      const X86Subtarget &Subtarget,
                                      SelectionDAG &DAG) {
  int Size = Mask.size();
  int LaneSize = 128 / VT.getScalarSizeInBits();
  const int NumBytes = VT.getSizeInBits() / 8;
  const int NumEltBytes = VT.getScalarSizeInBits() / 8;

  assert((Subtarget.hasSSSE3() && VT.is128BitVector()) ||
         (Subtarget.hasAVX2() && VT.is256BitVector()) ||
         (Subtarget.hasBWI() && VT.is512BitVector()));

  SmallVector<SDValue, 64> PSHUFBMask(NumBytes);
  // Sign bit set in i8 mask means zero element.
  SDValue ZeroMask = DAG.getConstant(0x80, DL, MVT::i8);

  SDValue V;
  for (int i = 0; i < NumBytes; ++i) {
    int M = Mask[i / NumEltBytes];
    if (M < 0) {
      PSHUFBMask[i] = DAG.getUNDEF(MVT::i8);
      continue;
    }
    if (Zeroable[i / NumEltBytes]) {
      PSHUFBMask[i] = ZeroMask;
      continue;
    }

    // We can only use a single input of V1 or V2.
    SDValue SrcV = (M >= Size ? V2 : V1);
    if (V && V != SrcV)
      return SDValue();
    V = SrcV;
    M %= Size;

    // PSHUFB can't cross lanes, ensure this doesn't happen.
    if ((M / LaneSize) != ((i / NumEltBytes) / LaneSize))
      return SDValue();

    M = M % LaneSize;
    M = M * NumEltBytes + (i % NumEltBytes);
    PSHUFBMask[i] = DAG.getConstant(M, DL, MVT::i8);
  }
  assert(V && "Failed to find a source input");

  MVT I8VT = MVT::getVectorVT(MVT::i8, NumBytes);
  return DAG.getBitcast(
      VT, DAG.getNode(X86ISD::PSHUFB, DL, I8VT, DAG.getBitcast(I8VT, V),
                      DAG.getBuildVector(I8VT, DL, PSHUFBMask)));
}

static SDValue getMaskNode(SDValue Mask, MVT MaskVT,
                           const X86Subtarget &Subtarget, SelectionDAG &DAG,
                           const SDLoc &dl);

// X86 has dedicated shuffle that can be lowered to VEXPAND
static SDValue lowerShuffleToEXPAND(const SDLoc &DL, MVT VT,
                                    const APInt &Zeroable,
                                    ArrayRef<int> Mask, SDValue &V1,
                                    SDValue &V2, SelectionDAG &DAG,
                                    const X86Subtarget &Subtarget) {
  bool IsLeftZeroSide = true;
  if (!isNonZeroElementsInOrder(Zeroable, Mask, V1.getValueType(),
                                IsLeftZeroSide))
    return SDValue();
  unsigned VEXPANDMask = (~Zeroable).getZExtValue();
  MVT IntegerType =
      MVT::getIntegerVT(std::max((int)VT.getVectorNumElements(), 8));
  SDValue MaskNode = DAG.getConstant(VEXPANDMask, DL, IntegerType);
  unsigned NumElts = VT.getVectorNumElements();
  assert((NumElts == 4 || NumElts == 8 || NumElts == 16) &&
         "Unexpected number of vector elements");
  SDValue VMask = getMaskNode(MaskNode, MVT::getVectorVT(MVT::i1, NumElts),
                              Subtarget, DAG, DL);
  SDValue ZeroVector = getZeroVector(VT, Subtarget, DAG, DL);
  SDValue ExpandedVector = IsLeftZeroSide ? V2 : V1;
  return DAG.getNode(X86ISD::EXPAND, DL, VT, ExpandedVector, ZeroVector, VMask);
}

static bool matchShuffleWithUNPCK(MVT VT, SDValue &V1, SDValue &V2,
                                  unsigned &UnpackOpcode, bool IsUnary,
                                  ArrayRef<int> TargetMask, const SDLoc &DL,
                                  SelectionDAG &DAG,
                                  const X86Subtarget &Subtarget) {
  int NumElts = VT.getVectorNumElements();

  bool Undef1 = true, Undef2 = true, Zero1 = true, Zero2 = true;
  for (int i = 0; i != NumElts; i += 2) {
    int M1 = TargetMask[i + 0];
    int M2 = TargetMask[i + 1];
    Undef1 &= (SM_SentinelUndef == M1);
    Undef2 &= (SM_SentinelUndef == M2);
    Zero1 &= isUndefOrZero(M1);
    Zero2 &= isUndefOrZero(M2);
  }
  assert(!((Undef1 || Zero1) && (Undef2 || Zero2)) &&
         "Zeroable shuffle detected");

  // Attempt to match the target mask against the unpack lo/hi mask patterns.
  SmallVector<int, 64> Unpckl, Unpckh;
  createUnpackShuffleMask(VT, Unpckl, /* Lo = */ true, IsUnary);
  if (isTargetShuffleEquivalent(TargetMask, Unpckl)) {
    UnpackOpcode = X86ISD::UNPCKL;
    V2 = (Undef2 ? DAG.getUNDEF(VT) : (IsUnary ? V1 : V2));
    V1 = (Undef1 ? DAG.getUNDEF(VT) : V1);
    return true;
  }

  createUnpackShuffleMask(VT, Unpckh, /* Lo = */ false, IsUnary);
  if (isTargetShuffleEquivalent(TargetMask, Unpckh)) {
    UnpackOpcode = X86ISD::UNPCKH;
    V2 = (Undef2 ? DAG.getUNDEF(VT) : (IsUnary ? V1 : V2));
    V1 = (Undef1 ? DAG.getUNDEF(VT) : V1);
    return true;
  }

  // If an unary shuffle, attempt to match as an unpack lo/hi with zero.
  if (IsUnary && (Zero1 || Zero2)) {
    // Don't bother if we can blend instead.
    if ((Subtarget.hasSSE41() || VT == MVT::v2i64 || VT == MVT::v2f64) &&
        isSequentialOrUndefOrZeroInRange(TargetMask, 0, NumElts, 0))
      return false;

    bool MatchLo = true, MatchHi = true;
    for (int i = 0; (i != NumElts) && (MatchLo || MatchHi); ++i) {
      int M = TargetMask[i];

      // Ignore if the input is known to be zero or the index is undef.
      if ((((i & 1) == 0) && Zero1) || (((i & 1) == 1) && Zero2) ||
          (M == SM_SentinelUndef))
        continue;

      MatchLo &= (M == Unpckl[i]);
      MatchHi &= (M == Unpckh[i]);
    }

    if (MatchLo || MatchHi) {
      UnpackOpcode = MatchLo ? X86ISD::UNPCKL : X86ISD::UNPCKH;
      V2 = Zero2 ? getZeroVector(VT, Subtarget, DAG, DL) : V1;
      V1 = Zero1 ? getZeroVector(VT, Subtarget, DAG, DL) : V1;
      return true;
    }
  }

  // If a binary shuffle, commute and try again.
  if (!IsUnary) {
    ShuffleVectorSDNode::commuteMask(Unpckl);
    if (isTargetShuffleEquivalent(TargetMask, Unpckl)) {
      UnpackOpcode = X86ISD::UNPCKL;
      std::swap(V1, V2);
      return true;
    }

    ShuffleVectorSDNode::commuteMask(Unpckh);
    if (isTargetShuffleEquivalent(TargetMask, Unpckh)) {
      UnpackOpcode = X86ISD::UNPCKH;
      std::swap(V1, V2);
      return true;
    }
  }

  return false;
}

// X86 has dedicated unpack instructions that can handle specific blend
// operations: UNPCKH and UNPCKL.
static SDValue lowerShuffleWithUNPCK(const SDLoc &DL, MVT VT,
                                     ArrayRef<int> Mask, SDValue V1, SDValue V2,
                                     SelectionDAG &DAG) {
  SmallVector<int, 8> Unpckl;
  createUnpackShuffleMask(VT, Unpckl, /* Lo = */ true, /* Unary = */ false);
  if (isShuffleEquivalent(V1, V2, Mask, Unpckl))
    return DAG.getNode(X86ISD::UNPCKL, DL, VT, V1, V2);

  SmallVector<int, 8> Unpckh;
  createUnpackShuffleMask(VT, Unpckh, /* Lo = */ false, /* Unary = */ false);
  if (isShuffleEquivalent(V1, V2, Mask, Unpckh))
    return DAG.getNode(X86ISD::UNPCKH, DL, VT, V1, V2);

  // Commute and try again.
  ShuffleVectorSDNode::commuteMask(Unpckl);
  if (isShuffleEquivalent(V1, V2, Mask, Unpckl))
    return DAG.getNode(X86ISD::UNPCKL, DL, VT, V2, V1);

  ShuffleVectorSDNode::commuteMask(Unpckh);
  if (isShuffleEquivalent(V1, V2, Mask, Unpckh))
    return DAG.getNode(X86ISD::UNPCKH, DL, VT, V2, V1);

  return SDValue();
}

/// Check if the mask can be mapped to a preliminary shuffle (vperm 64-bit)
/// followed by unpack 256-bit.
static SDValue lowerShuffleWithUNPCK256(const SDLoc &DL, MVT VT,
                                        ArrayRef<int> Mask, SDValue V1,
                                        SDValue V2, SelectionDAG &DAG) {
  SmallVector<int, 32> Unpckl, Unpckh;
  createSplat2ShuffleMask(VT, Unpckl, /* Lo */ true);
  createSplat2ShuffleMask(VT, Unpckh, /* Lo */ false);

  unsigned UnpackOpcode;
  if (isShuffleEquivalent(V1, V2, Mask, Unpckl))
    UnpackOpcode = X86ISD::UNPCKL;
  else if (isShuffleEquivalent(V1, V2, Mask, Unpckh))
    UnpackOpcode = X86ISD::UNPCKH;
  else
    return SDValue();

  // This is a "natural" unpack operation (rather than the 128-bit sectored
  // operation implemented by AVX). We need to rearrange 64-bit chunks of the
  // input in order to use the x86 instruction.
  V1 = DAG.getVectorShuffle(MVT::v4f64, DL, DAG.getBitcast(MVT::v4f64, V1),
                            DAG.getUNDEF(MVT::v4f64), {0, 2, 1, 3});
  V1 = DAG.getBitcast(VT, V1);
  return DAG.getNode(UnpackOpcode, DL, VT, V1, V1);
}

// Check if the mask can be mapped to a TRUNCATE or VTRUNC, truncating the
// source into the lower elements and zeroing the upper elements.
// TODO: Merge with matchShuffleAsVPMOV.
static bool matchShuffleAsVTRUNC(MVT &SrcVT, MVT &DstVT, MVT VT,
                                 ArrayRef<int> Mask, const APInt &Zeroable,
                                 const X86Subtarget &Subtarget) {
  if (!VT.is512BitVector() && !Subtarget.hasVLX())
    return false;

  unsigned NumElts = Mask.size();
  unsigned EltSizeInBits = VT.getScalarSizeInBits();
  unsigned MaxScale = 64 / EltSizeInBits;

  for (unsigned Scale = 2; Scale <= MaxScale; Scale += Scale) {
    unsigned SrcEltBits = EltSizeInBits * Scale;
    if (SrcEltBits < 32 && !Subtarget.hasBWI())
      continue;
    unsigned NumSrcElts = NumElts / Scale;
    if (!isSequentialOrUndefInRange(Mask, 0, NumSrcElts, 0, Scale))
      continue;
    unsigned UpperElts = NumElts - NumSrcElts;
    if (!Zeroable.extractBits(UpperElts, NumSrcElts).isAllOnesValue())
      continue;
    SrcVT = MVT::getIntegerVT(EltSizeInBits * Scale);
    SrcVT = MVT::getVectorVT(SrcVT, NumSrcElts);
    DstVT = MVT::getIntegerVT(EltSizeInBits);
    if ((NumSrcElts * EltSizeInBits) >= 128) {
      // ISD::TRUNCATE
      DstVT = MVT::getVectorVT(DstVT, NumSrcElts);
    } else {
      // X86ISD::VTRUNC
      DstVT = MVT::getVectorVT(DstVT, 128 / EltSizeInBits);
    }
    return true;
  }

  return false;
}

static bool matchShuffleAsVPMOV(ArrayRef<int> Mask, bool SwappedOps,
                                int Delta) {
  int Size = (int)Mask.size();
  int Split = Size / Delta;
  int TruncatedVectorStart = SwappedOps ? Size : 0;

  // Match for mask starting with e.g.: <8, 10, 12, 14,... or <0, 2, 4, 6,...
  if (!isSequentialOrUndefInRange(Mask, 0, Split, TruncatedVectorStart, Delta))
    return false;

  // The rest of the mask should not refer to the truncated vector's elements.
  if (isAnyInRange(Mask.slice(Split, Size - Split), TruncatedVectorStart,
                   TruncatedVectorStart + Size))
    return false;

  return true;
}

// Try to lower trunc+vector_shuffle to a vpmovdb or a vpmovdw instruction.
//
// An example is the following:
//
// t0: ch = EntryToken
//           t2: v4i64,ch = CopyFromReg t0, Register:v4i64 %0
//         t25: v4i32 = truncate t2
//       t41: v8i16 = bitcast t25
//       t21: v8i16 = BUILD_VECTOR undef:i16, undef:i16, undef:i16, undef:i16,
//       Constant:i16<0>, Constant:i16<0>, Constant:i16<0>, Constant:i16<0>
//     t51: v8i16 = vector_shuffle<0,2,4,6,12,13,14,15> t41, t21
//   t18: v2i64 = bitcast t51
//
// Without avx512vl, this is lowered to:
//
// vpmovqd %zmm0, %ymm0
// vpshufb {{.*#+}} xmm0 =
// xmm0[0,1,4,5,8,9,12,13],zero,zero,zero,zero,zero,zero,zero,zero
//
// But when avx512vl is available, one can just use a single vpmovdw
// instruction.
static SDValue lowerShuffleWithVPMOV(const SDLoc &DL, ArrayRef<int> Mask,
                                     MVT VT, SDValue V1, SDValue V2,
                                     SelectionDAG &DAG,
                                     const X86Subtarget &Subtarget) {
  if (VT != MVT::v16i8 && VT != MVT::v8i16)
    return SDValue();

  if (Mask.size() != VT.getVectorNumElements())
    return SDValue();

  bool SwappedOps = false;

  if (!ISD::isBuildVectorAllZeros(V2.getNode())) {
    if (!ISD::isBuildVectorAllZeros(V1.getNode()))
      return SDValue();

    std::swap(V1, V2);
    SwappedOps = true;
  }

  // Look for:
  //
  // bitcast (truncate <8 x i32> %vec to <8 x i16>) to <16 x i8>
  // bitcast (truncate <4 x i64> %vec to <4 x i32>) to <8 x i16>
  //
  // and similar ones.
  if (V1.getOpcode() != ISD::BITCAST)
    return SDValue();
  if (V1.getOperand(0).getOpcode() != ISD::TRUNCATE)
    return SDValue();

  SDValue Src = V1.getOperand(0).getOperand(0);
  MVT SrcVT = Src.getSimpleValueType();

  // The vptrunc** instructions truncating 128 bit and 256 bit vectors
  // are only available with avx512vl.
  if (!SrcVT.is512BitVector() && !Subtarget.hasVLX())
    return SDValue();

  // Down Convert Word to Byte is only available with avx512bw. The case with
  // 256-bit output doesn't contain a shuffle and is therefore not handled here.
  if (SrcVT.getVectorElementType() == MVT::i16 && VT == MVT::v16i8 &&
      !Subtarget.hasBWI())
    return SDValue();

  // The first half/quarter of the mask should refer to every second/fourth
  // element of the vector truncated and bitcasted.
  if (!matchShuffleAsVPMOV(Mask, SwappedOps, 2) &&
      !matchShuffleAsVPMOV(Mask, SwappedOps, 4))
    return SDValue();

  return DAG.getNode(X86ISD::VTRUNC, DL, VT, Src);
}

/// Check whether a compaction lowering can be done by dropping even
/// elements and compute how many times even elements must be dropped.
///
/// This handles shuffles which take every Nth element where N is a power of
/// two. Example shuffle masks:
///
///  N = 1:  0,  2,  4,  6,  8, 10, 12, 14,  0,  2,  4,  6,  8, 10, 12, 14
///  N = 1:  0,  2,  4,  6,  8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30
///  N = 2:  0,  4,  8, 12,  0,  4,  8, 12,  0,  4,  8, 12,  0,  4,  8, 12
///  N = 2:  0,  4,  8, 12, 16, 20, 24, 28,  0,  4,  8, 12, 16, 20, 24, 28
///  N = 3:  0,  8,  0,  8,  0,  8,  0,  8,  0,  8,  0,  8,  0,  8,  0,  8
///  N = 3:  0,  8, 16, 24,  0,  8, 16, 24,  0,  8, 16, 24,  0,  8, 16, 24
///
/// Any of these lanes can of course be undef.
///
/// This routine only supports N <= 3.
/// FIXME: Evaluate whether either AVX or AVX-512 have any opportunities here
/// for larger N.
///
/// \returns N above, or the number of times even elements must be dropped if
/// there is such a number. Otherwise returns zero.
static int canLowerByDroppingEvenElements(ArrayRef<int> Mask,
                                          bool IsSingleInput) {
  // The modulus for the shuffle vector entries is based on whether this is
  // a single input or not.
  int ShuffleModulus = Mask.size() * (IsSingleInput ? 1 : 2);
  assert(isPowerOf2_32((uint32_t)ShuffleModulus) &&
         "We should only be called with masks with a power-of-2 size!");

  uint64_t ModMask = (uint64_t)ShuffleModulus - 1;

  // We track whether the input is viable for all power-of-2 strides 2^1, 2^2,
  // and 2^3 simultaneously. This is because we may have ambiguity with
  // partially undef inputs.
  bool ViableForN[3] = {true, true, true};

  for (int i = 0, e = Mask.size(); i < e; ++i) {
    // Ignore undef lanes, we'll optimistically collapse them to the pattern we
    // want.
    if (Mask[i] < 0)
      continue;

    bool IsAnyViable = false;
    for (unsigned j = 0; j != array_lengthof(ViableForN); ++j)
      if (ViableForN[j]) {
        uint64_t N = j + 1;

        // The shuffle mask must be equal to (i * 2^N) % M.
        if ((uint64_t)Mask[i] == (((uint64_t)i << N) & ModMask))
          IsAnyViable = true;
        else
          ViableForN[j] = false;
      }
    // Early exit if we exhaust the possible powers of two.
    if (!IsAnyViable)
      break;
  }

  for (unsigned j = 0; j != array_lengthof(ViableForN); ++j)
    if (ViableForN[j])
      return j + 1;

  // Return 0 as there is no viable power of two.
  return 0;
}

// X86 has dedicated pack instructions that can handle specific truncation
// operations: PACKSS and PACKUS.
// TODO: Add support for matching multiple PACKSS/PACKUS stages.
static bool matchShuffleWithPACK(MVT VT, MVT &SrcVT, SDValue &V1, SDValue &V2,
                                 unsigned &PackOpcode, ArrayRef<int> TargetMask,
                                 SelectionDAG &DAG,
                                 const X86Subtarget &Subtarget) {
  unsigned NumElts = VT.getVectorNumElements();
  unsigned BitSize = VT.getScalarSizeInBits();

  auto MatchPACK = [&](SDValue N1, SDValue N2, MVT PackVT) {
    unsigned NumSrcBits = PackVT.getScalarSizeInBits();
    unsigned NumPackedBits = NumSrcBits - BitSize;
    SDValue VV1 = DAG.getBitcast(PackVT, N1);
    SDValue VV2 = DAG.getBitcast(PackVT, N2);
    if (Subtarget.hasSSE41() || BitSize == 8) {
      APInt ZeroMask = APInt::getHighBitsSet(NumSrcBits, NumPackedBits);
      if ((N1.isUndef() || DAG.MaskedValueIsZero(VV1, ZeroMask)) &&
          (N2.isUndef() || DAG.MaskedValueIsZero(VV2, ZeroMask))) {
        V1 = VV1;
        V2 = VV2;
        SrcVT = PackVT;
        PackOpcode = X86ISD::PACKUS;
        return true;
      }
    }
    if ((N1.isUndef() || DAG.ComputeNumSignBits(VV1) > NumPackedBits) &&
        (N2.isUndef() || DAG.ComputeNumSignBits(VV2) > NumPackedBits)) {
      V1 = VV1;
      V2 = VV2;
      SrcVT = PackVT;
      PackOpcode = X86ISD::PACKSS;
      return true;
    }
    return false;
  };

  MVT PackSVT = MVT::getIntegerVT(BitSize * 2);
  MVT PackVT = MVT::getVectorVT(PackSVT, NumElts / 2);

  // Try binary shuffle.
  SmallVector<int, 32> BinaryMask;
  createPackShuffleMask(VT, BinaryMask, false);
  if (isTargetShuffleEquivalent(TargetMask, BinaryMask, V1, V2))
    if (MatchPACK(V1, V2, PackVT))
      return true;

  // Try unary shuffle.
  SmallVector<int, 32> UnaryMask;
  createPackShuffleMask(VT, UnaryMask, true);
  if (isTargetShuffleEquivalent(TargetMask, UnaryMask, V1))
    if (MatchPACK(V1, V1, PackVT))
      return true;

  return false;
}

static SDValue lowerShuffleWithPACK(const SDLoc &DL, MVT VT, ArrayRef<int> Mask,
                                    SDValue V1, SDValue V2, SelectionDAG &DAG,
                                    const X86Subtarget &Subtarget) {
  MVT PackVT;
  unsigned PackOpcode;
  if (matchShuffleWithPACK(VT, PackVT, V1, V2, PackOpcode, Mask, DAG,
                           Subtarget))
    return DAG.getNode(PackOpcode, DL, VT, DAG.getBitcast(PackVT, V1),
                       DAG.getBitcast(PackVT, V2));

  return SDValue();
}

/// Try to emit a bitmask instruction for a shuffle.
///
/// This handles cases where we can model a blend exactly as a bitmask due to
/// one of the inputs being zeroable.
static SDValue lowerShuffleAsBitMask(const SDLoc &DL, MVT VT, SDValue V1,
                                     SDValue V2, ArrayRef<int> Mask,
                                     const APInt &Zeroable,
                                     const X86Subtarget &Subtarget,
                                     SelectionDAG &DAG) {
  MVT MaskVT = VT;
  MVT EltVT = VT.getVectorElementType();
  SDValue Zero, AllOnes;
  // Use f64 if i64 isn't legal.
  if (EltVT == MVT::i64 && !Subtarget.is64Bit()) {
    EltVT = MVT::f64;
    MaskVT = MVT::getVectorVT(EltVT, Mask.size());
  }

  MVT LogicVT = VT;
  if (EltVT == MVT::f32 || EltVT == MVT::f64) {
    Zero = DAG.getConstantFP(0.0, DL, EltVT);
    AllOnes = DAG.getConstantFP(
        APFloat::getAllOnesValue(EltVT.getSizeInBits(), true), DL, EltVT);
    LogicVT =
        MVT::getVectorVT(EltVT == MVT::f64 ? MVT::i64 : MVT::i32, Mask.size());
  } else {
    Zero = DAG.getConstant(0, DL, EltVT);
    AllOnes = DAG.getAllOnesConstant(DL, EltVT);
  }

  SmallVector<SDValue, 16> VMaskOps(Mask.size(), Zero);
  SDValue V;
  for (int i = 0, Size = Mask.size(); i < Size; ++i) {
    if (Zeroable[i])
      continue;
    if (Mask[i] % Size != i)
      return SDValue(); // Not a blend.
    if (!V)
      V = Mask[i] < Size ? V1 : V2;
    else if (V != (Mask[i] < Size ? V1 : V2))
      return SDValue(); // Can only let one input through the mask.

    VMaskOps[i] = AllOnes;
  }
  if (!V)
    return SDValue(); // No non-zeroable elements!

  SDValue VMask = DAG.getBuildVector(MaskVT, DL, VMaskOps);
  VMask = DAG.getBitcast(LogicVT, VMask);
  V = DAG.getBitcast(LogicVT, V);
  SDValue And = DAG.getNode(ISD::AND, DL, LogicVT, V, VMask);
  return DAG.getBitcast(VT, And);
}

/// Try to emit a blend instruction for a shuffle using bit math.
///
/// This is used as a fallback approach when first class blend instructions are
/// unavailable. Currently it is only suitable for integer vectors, but could
/// be generalized for floating point vectors if desirable.
static SDValue lowerShuffleAsBitBlend(const SDLoc &DL, MVT VT, SDValue V1,
                                      SDValue V2, ArrayRef<int> Mask,
                                      SelectionDAG &DAG) {
  assert(VT.isInteger() && "Only supports integer vector types!");
  MVT EltVT = VT.getVectorElementType();
  SDValue Zero = DAG.getConstant(0, DL, EltVT);
  SDValue AllOnes = DAG.getAllOnesConstant(DL, EltVT);
  SmallVector<SDValue, 16> MaskOps;
  for (int i = 0, Size = Mask.size(); i < Size; ++i) {
    if (Mask[i] >= 0 && Mask[i] != i && Mask[i] != i + Size)
      return SDValue(); // Shuffled input!
    MaskOps.push_back(Mask[i] < Size ? AllOnes : Zero);
  }

  SDValue V1Mask = DAG.getBuildVector(VT, DL, MaskOps);
  V1 = DAG.getNode(ISD::AND, DL, VT, V1, V1Mask);
  V2 = DAG.getNode(X86ISD::ANDNP, DL, VT, V1Mask, V2);
  return DAG.getNode(ISD::OR, DL, VT, V1, V2);
}

static SDValue getVectorMaskingNode(SDValue Op, SDValue Mask,
                                    SDValue PreservedSrc,
                                    const X86Subtarget &Subtarget,
                                    SelectionDAG &DAG);

static bool matchShuffleAsBlend(SDValue V1, SDValue V2,
                                MutableArrayRef<int> Mask,
                                const APInt &Zeroable, bool &ForceV1Zero,
                                bool &ForceV2Zero, uint64_t &BlendMask) {
  bool V1IsZeroOrUndef =
      V1.isUndef() || ISD::isBuildVectorAllZeros(V1.getNode());
  bool V2IsZeroOrUndef =
      V2.isUndef() || ISD::isBuildVectorAllZeros(V2.getNode());

  BlendMask = 0;
  ForceV1Zero = false, ForceV2Zero = false;
  assert(Mask.size() <= 64 && "Shuffle mask too big for blend mask");

  // Attempt to generate the binary blend mask. If an input is zero then
  // we can use any lane.
  for (int i = 0, Size = Mask.size(); i < Size; ++i) {
    int M = Mask[i];
    if (M == SM_SentinelUndef)
      continue;
    if (M == i)
      continue;
    if (M == i + Size) {
      BlendMask |= 1ull << i;
      continue;
    }
    if (Zeroable[i]) {
      if (V1IsZeroOrUndef) {
        ForceV1Zero = true;
        Mask[i] = i;
        continue;
      }
      if (V2IsZeroOrUndef) {
        ForceV2Zero = true;
        BlendMask |= 1ull << i;
        Mask[i] = i + Size;
        continue;
      }
    }
    return false;
  }
  return true;
}

static uint64_t scaleVectorShuffleBlendMask(uint64_t BlendMask, int Size,
                                            int Scale) {
  uint64_t ScaledMask = 0;
  for (int i = 0; i != Size; ++i)
    if (BlendMask & (1ull << i))
      ScaledMask |= ((1ull << Scale) - 1) << (i * Scale);
  return ScaledMask;
}

/// Try to emit a blend instruction for a shuffle.
///
/// This doesn't do any checks for the availability of instructions for blending
/// these values. It relies on the availability of the X86ISD::BLENDI pattern to
/// be matched in the backend with the type given. What it does check for is
/// that the shuffle mask is a blend, or convertible into a blend with zero.
static SDValue lowerShuffleAsBlend(const SDLoc &DL, MVT VT, SDValue V1,
                                   SDValue V2, ArrayRef<int> Original,
                                   const APInt &Zeroable,
                                   const X86Subtarget &Subtarget,
                                   SelectionDAG &DAG) {
  uint64_t BlendMask = 0;
  bool ForceV1Zero = false, ForceV2Zero = false;
  SmallVector<int, 64> Mask(Original.begin(), Original.end());
  if (!matchShuffleAsBlend(V1, V2, Mask, Zeroable, ForceV1Zero, ForceV2Zero,
                           BlendMask))
    return SDValue();

  // Create a REAL zero vector - ISD::isBuildVectorAllZeros allows UNDEFs.
  if (ForceV1Zero)
    V1 = getZeroVector(VT, Subtarget, DAG, DL);
  if (ForceV2Zero)
    V2 = getZeroVector(VT, Subtarget, DAG, DL);

  switch (VT.SimpleTy) {
  case MVT::v4i64:
  case MVT::v8i32:
    assert(Subtarget.hasAVX2() && "256-bit integer blends require AVX2!");
    LLVM_FALLTHROUGH;
  case MVT::v4f64:
  case MVT::v8f32:
    assert(Subtarget.hasAVX() && "256-bit float blends require AVX!");
    LLVM_FALLTHROUGH;
  case MVT::v2f64:
  case MVT::v2i64:
  case MVT::v4f32:
  case MVT::v4i32:
  case MVT::v8i16:
    assert(Subtarget.hasSSE41() && "128-bit blends require SSE41!");
    return DAG.getNode(X86ISD::BLENDI, DL, VT, V1, V2,
                       DAG.getTargetConstant(BlendMask, DL, MVT::i8));
  case MVT::v16i16: {
    assert(Subtarget.hasAVX2() && "v16i16 blends require AVX2!");
    SmallVector<int, 8> RepeatedMask;
    if (is128BitLaneRepeatedShuffleMask(MVT::v16i16, Mask, RepeatedMask)) {
      // We can lower these with PBLENDW which is mirrored across 128-bit lanes.
      assert(RepeatedMask.size() == 8 && "Repeated mask size doesn't match!");
      BlendMask = 0;
      for (int i = 0; i < 8; ++i)
        if (RepeatedMask[i] >= 8)
          BlendMask |= 1ull << i;
      return DAG.getNode(X86ISD::BLENDI, DL, MVT::v16i16, V1, V2,
                         DAG.getTargetConstant(BlendMask, DL, MVT::i8));
    }
    // Use PBLENDW for lower/upper lanes and then blend lanes.
    // TODO - we should allow 2 PBLENDW here and leave shuffle combine to
    // merge to VSELECT where useful.
    uint64_t LoMask = BlendMask & 0xFF;
    uint64_t HiMask = (BlendMask >> 8) & 0xFF;
    if (LoMask == 0 || LoMask == 255 || HiMask == 0 || HiMask == 255) {
      SDValue Lo = DAG.getNode(X86ISD::BLENDI, DL, MVT::v16i16, V1, V2,
                               DAG.getTargetConstant(LoMask, DL, MVT::i8));
      SDValue Hi = DAG.getNode(X86ISD::BLENDI, DL, MVT::v16i16, V1, V2,
                               DAG.getTargetConstant(HiMask, DL, MVT::i8));
      return DAG.getVectorShuffle(
          MVT::v16i16, DL, Lo, Hi,
          {0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31});
    }
    LLVM_FALLTHROUGH;
  }
  case MVT::v32i8:
    assert(Subtarget.hasAVX2() && "256-bit byte-blends require AVX2!");
    LLVM_FALLTHROUGH;
  case MVT::v16i8: {
    assert(Subtarget.hasSSE41() && "128-bit byte-blends require SSE41!");

    // Attempt to lower to a bitmask if we can. VPAND is faster than VPBLENDVB.
    if (SDValue Masked = lowerShuffleAsBitMask(DL, VT, V1, V2, Mask, Zeroable,
                                               Subtarget, DAG))
      return Masked;

    if (Subtarget.hasBWI() && Subtarget.hasVLX()) {
      MVT IntegerType =
          MVT::getIntegerVT(std::max((int)VT.getVectorNumElements(), 8));
      SDValue MaskNode = DAG.getConstant(BlendMask, DL, IntegerType);
      return getVectorMaskingNode(V2, MaskNode, V1, Subtarget, DAG);
    }

    // Scale the blend by the number of bytes per element.
    int Scale = VT.getScalarSizeInBits() / 8;

    // This form of blend is always done on bytes. Compute the byte vector
    // type.
    MVT BlendVT = MVT::getVectorVT(MVT::i8, VT.getSizeInBits() / 8);

    // x86 allows load folding with blendvb from the 2nd source operand. But
    // we are still using LLVM select here (see comment below), so that's V1.
    // If V2 can be load-folded and V1 cannot be load-folded, then commute to
    // allow that load-folding possibility.
    if (!ISD::isNormalLoad(V1.getNode()) && ISD::isNormalLoad(V2.getNode())) {
      ShuffleVectorSDNode::commuteMask(Mask);
      std::swap(V1, V2);
    }

    // Compute the VSELECT mask. Note that VSELECT is really confusing in the
    // mix of LLVM's code generator and the x86 backend. We tell the code
    // generator that boolean values in the elements of an x86 vector register
    // are -1 for true and 0 for false. We then use the LLVM semantics of 'true'
    // mapping a select to operand #1, and 'false' mapping to operand #2. The
    // reality in x86 is that vector masks (pre-AVX-512) use only the high bit
    // of the element (the remaining are ignored) and 0 in that high bit would
    // mean operand #1 while 1 in the high bit would mean operand #2. So while
    // the LLVM model for boolean values in vector elements gets the relevant
    // bit set, it is set backwards and over constrained relative to x86's
    // actual model.
    SmallVector<SDValue, 32> VSELECTMask;
    for (int i = 0, Size = Mask.size(); i < Size; ++i)
      for (int j = 0; j < Scale; ++j)
        VSELECTMask.push_back(
            Mask[i] < 0 ? DAG.getUNDEF(MVT::i8)
                        : DAG.getConstant(Mask[i] < Size ? -1 : 0, DL,
                                          MVT::i8));

    V1 = DAG.getBitcast(BlendVT, V1);
    V2 = DAG.getBitcast(BlendVT, V2);
    return DAG.getBitcast(
        VT,
        DAG.getSelect(DL, BlendVT, DAG.getBuildVector(BlendVT, DL, VSELECTMask),
                      V1, V2));
  }
  case MVT::v16f32:
  case MVT::v8f64:
  case MVT::v8i64:
  case MVT::v16i32:
  case MVT::v32i16:
  case MVT::v64i8: {
    // Attempt to lower to a bitmask if we can. Only if not optimizing for size.
    bool OptForSize = DAG.shouldOptForSize();
    if (!OptForSize) {
      if (SDValue Masked = lowerShuffleAsBitMask(DL, VT, V1, V2, Mask, Zeroable,
                                                 Subtarget, DAG))
        return Masked;
    }

    // Otherwise load an immediate into a GPR, cast to k-register, and use a
    // masked move.
    MVT IntegerType =
        MVT::getIntegerVT(std::max((int)VT.getVectorNumElements(), 8));
    SDValue MaskNode = DAG.getConstant(BlendMask, DL, IntegerType);
    return getVectorMaskingNode(V2, MaskNode, V1, Subtarget, DAG);
  }
  default:
    llvm_unreachable("Not a supported integer vector type!");
  }
}

/// Try to lower as a blend of elements from two inputs followed by
/// a single-input permutation.
///
/// This matches the pattern where we can blend elements from two inputs and
/// then reduce the shuffle to a single-input permutation.
static SDValue lowerShuffleAsBlendAndPermute(const SDLoc &DL, MVT VT,
                                             SDValue V1, SDValue V2,
                                             ArrayRef<int> Mask,
                                             SelectionDAG &DAG,
                                             bool ImmBlends = false) {
  // We build up the blend mask while checking whether a blend is a viable way
  // to reduce the shuffle.
  SmallVector<int, 32> BlendMask(Mask.size(), -1);
  SmallVector<int, 32> PermuteMask(Mask.size(), -1);

  for (int i = 0, Size = Mask.size(); i < Size; ++i) {
    if (Mask[i] < 0)
      continue;

    assert(Mask[i] < Size * 2 && "Shuffle input is out of bounds.");

    if (BlendMask[Mask[i] % Size] < 0)
      BlendMask[Mask[i] % Size] = Mask[i];
    else if (BlendMask[Mask[i] % Size] != Mask[i])
      return SDValue(); // Can't blend in the needed input!

    PermuteMask[i] = Mask[i] % Size;
  }

  // If only immediate blends, then bail if the blend mask can't be widened to
  // i16.
  unsigned EltSize = VT.getScalarSizeInBits();
  if (ImmBlends && EltSize == 8 && !canWidenShuffleElements(BlendMask))
    return SDValue();

  SDValue V = DAG.getVectorShuffle(VT, DL, V1, V2, BlendMask);
  return DAG.getVectorShuffle(VT, DL, V, DAG.getUNDEF(VT), PermuteMask);
}

/// Try to lower as an unpack of elements from two inputs followed by
/// a single-input permutation.
///
/// This matches the pattern where we can unpack elements from two inputs and
/// then reduce the shuffle to a single-input (wider) permutation.
static SDValue lowerShuffleAsUNPCKAndPermute(const SDLoc &DL, MVT VT,
                                             SDValue V1, SDValue V2,
                                             ArrayRef<int> Mask,
                                             SelectionDAG &DAG) {
  int NumElts = Mask.size();
  int NumLanes = VT.getSizeInBits() / 128;
  int NumLaneElts = NumElts / NumLanes;
  int NumHalfLaneElts = NumLaneElts / 2;

  bool MatchLo = true, MatchHi = true;
  SDValue Ops[2] = {DAG.getUNDEF(VT), DAG.getUNDEF(VT)};

  // Determine UNPCKL/UNPCKH type and operand order.
  for (int Lane = 0; Lane != NumElts; Lane += NumLaneElts) {
    for (int Elt = 0; Elt != NumLaneElts; ++Elt) {
      int M = Mask[Lane + Elt];
      if (M < 0)
        continue;

      SDValue &Op = Ops[Elt & 1];
      if (M < NumElts && (Op.isUndef() || Op == V1))
        Op = V1;
      else if (NumElts <= M && (Op.isUndef() || Op == V2))
        Op = V2;
      else
        return SDValue();

      int Lo = Lane, Mid = Lane + NumHalfLaneElts, Hi = Lane + NumLaneElts;
      MatchLo &= isUndefOrInRange(M, Lo, Mid) ||
                 isUndefOrInRange(M, NumElts + Lo, NumElts + Mid);
      MatchHi &= isUndefOrInRange(M, Mid, Hi) ||
                 isUndefOrInRange(M, NumElts + Mid, NumElts + Hi);
      if (!MatchLo && !MatchHi)
        return SDValue();
    }
  }
  assert((MatchLo ^ MatchHi) && "Failed to match UNPCKLO/UNPCKHI");

  // Now check that each pair of elts come from the same unpack pair
  // and set the permute mask based on each pair.
  // TODO - Investigate cases where we permute individual elements.
  SmallVector<int, 32> PermuteMask(NumElts, -1);
  for (int Lane = 0; Lane != NumElts; Lane += NumLaneElts) {
    for (int Elt = 0; Elt != NumLaneElts; Elt += 2) {
      int M0 = Mask[Lane + Elt + 0];
      int M1 = Mask[Lane + Elt + 1];
      if (0 <= M0 && 0 <= M1 &&
          (M0 % NumHalfLaneElts) != (M1 % NumHalfLaneElts))
        return SDValue();
      if (0 <= M0)
        PermuteMask[Lane + Elt + 0] = Lane + (2 * (M0 % NumHalfLaneElts));
      if (0 <= M1)
        PermuteMask[Lane + Elt + 1] = Lane + (2 * (M1 % NumHalfLaneElts)) + 1;
    }
  }

  unsigned UnpckOp = MatchLo ? X86ISD::UNPCKL : X86ISD::UNPCKH;
  SDValue Unpck = DAG.getNode(UnpckOp, DL, VT, Ops);
  return DAG.getVectorShuffle(VT, DL, Unpck, DAG.getUNDEF(VT), PermuteMask);
}

/// Helper to form a PALIGNR-based rotate+permute, merging 2 inputs and then
/// permuting the elements of the result in place.
static SDValue lowerShuffleAsByteRotateAndPermute(
    const SDLoc &DL, MVT VT, SDValue V1, SDValue V2, ArrayRef<int> Mask,
    const X86Subtarget &Subtarget, SelectionDAG &DAG) {
  if ((VT.is128BitVector() && !Subtarget.hasSSSE3()) ||
      (VT.is256BitVector() && !Subtarget.hasAVX2()) ||
      (VT.is512BitVector() && !Subtarget.hasBWI()))
    return SDValue();

  // We don't currently support lane crossing permutes.
  if (is128BitLaneCrossingShuffleMask(VT, Mask))
    return SDValue();

  int Scale = VT.getScalarSizeInBits() / 8;
  int NumLanes = VT.getSizeInBits() / 128;
  int NumElts = VT.getVectorNumElements();
  int NumEltsPerLane = NumElts / NumLanes;

  // Determine range of mask elts.
  bool Blend1 = true;
  bool Blend2 = true;
  std::pair<int, int> Range1 = std::make_pair(INT_MAX, INT_MIN);
  std::pair<int, int> Range2 = std::make_pair(INT_MAX, INT_MIN);
  for (int Lane = 0; Lane != NumElts; Lane += NumEltsPerLane) {
    for (int Elt = 0; Elt != NumEltsPerLane; ++Elt) {
      int M = Mask[Lane + Elt];
      if (M < 0)
        continue;
      if (M < NumElts) {
        Blend1 &= (M == (Lane + Elt));
        assert(Lane <= M && M < (Lane + NumEltsPerLane) && "Out of range mask");
        M = M % NumEltsPerLane;
        Range1.first = std::min(Range1.first, M);
        Range1.second = std::max(Range1.second, M);
      } else {
        M -= NumElts;
        Blend2 &= (M == (Lane + Elt));
        assert(Lane <= M && M < (Lane + NumEltsPerLane) && "Out of range mask");
        M = M % NumEltsPerLane;
        Range2.first = std::min(Range2.first, M);
        Range2.second = std::max(Range2.second, M);
      }
    }
  }

  // Bail if we don't need both elements.
  // TODO - it might be worth doing this for unary shuffles if the permute
  // can be widened.
  if (!(0 <= Range1.first && Range1.second < NumEltsPerLane) ||
      !(0 <= Range2.first && Range2.second < NumEltsPerLane))
    return SDValue();

  if (VT.getSizeInBits() > 128 && (Blend1 || Blend2))
    return SDValue();

  // Rotate the 2 ops so we can access both ranges, then permute the result.
  auto RotateAndPermute = [&](SDValue Lo, SDValue Hi, int RotAmt, int Ofs) {
    MVT ByteVT = MVT::getVectorVT(MVT::i8, VT.getSizeInBits() / 8);
    SDValue Rotate = DAG.getBitcast(
        VT, DAG.getNode(X86ISD::PALIGNR, DL, ByteVT, DAG.getBitcast(ByteVT, Hi),
                        DAG.getBitcast(ByteVT, Lo),
                        DAG.getTargetConstant(Scale * RotAmt, DL, MVT::i8)));
    SmallVector<int, 64> PermMask(NumElts, SM_SentinelUndef);
    for (int Lane = 0; Lane != NumElts; Lane += NumEltsPerLane) {
      for (int Elt = 0; Elt != NumEltsPerLane; ++Elt) {
        int M = Mask[Lane + Elt];
        if (M < 0)
          continue;
        if (M < NumElts)
          PermMask[Lane + Elt] = Lane + ((M + Ofs - RotAmt) % NumEltsPerLane);
        else
          PermMask[Lane + Elt] = Lane + ((M - Ofs - RotAmt) % NumEltsPerLane);
      }
    }
    return DAG.getVectorShuffle(VT, DL, Rotate, DAG.getUNDEF(VT), PermMask);
  };

  // Check if the ranges are small enough to rotate from either direction.
  if (Range2.second < Range1.first)
    return RotateAndPermute(V1, V2, Range1.first, 0);
  if (Range1.second < Range2.first)
    return RotateAndPermute(V2, V1, Range2.first, NumElts);
  return SDValue();
}

/// Generic routine to decompose a shuffle and blend into independent
/// blends and permutes.
///
/// This matches the extremely common pattern for handling combined
/// shuffle+blend operations on newer X86 ISAs where we have very fast blend
/// operations. It will try to pick the best arrangement of shuffles and
/// blends.
static SDValue lowerShuffleAsDecomposedShuffleBlend(
    const SDLoc &DL, MVT VT, SDValue V1, SDValue V2, ArrayRef<int> Mask,
    const X86Subtarget &Subtarget, SelectionDAG &DAG) {
  // Shuffle the input elements into the desired positions in V1 and V2 and
  // blend them together.
  SmallVector<int, 32> V1Mask(Mask.size(), -1);
  SmallVector<int, 32> V2Mask(Mask.size(), -1);
  SmallVector<int, 32> BlendMask(Mask.size(), -1);
  for (int i = 0, Size = Mask.size(); i < Size; ++i)
    if (Mask[i] >= 0 && Mask[i] < Size) {
      V1Mask[i] = Mask[i];
      BlendMask[i] = i;
    } else if (Mask[i] >= Size) {
      V2Mask[i] = Mask[i] - Size;
      BlendMask[i] = i + Size;
    }

  // Try to lower with the simpler initial blend/unpack/rotate strategies unless
  // one of the input shuffles would be a no-op. We prefer to shuffle inputs as
  // the shuffle may be able to fold with a load or other benefit. However, when
  // we'll have to do 2x as many shuffles in order to achieve this, a 2-input
  // pre-shuffle first is a better strategy.
  if (!isNoopShuffleMask(V1Mask) && !isNoopShuffleMask(V2Mask)) {
    // Only prefer immediate blends to unpack/rotate.
    if (SDValue BlendPerm = lowerShuffleAsBlendAndPermute(DL, VT, V1, V2, Mask,
                                                          DAG, true))
      return BlendPerm;
    if (SDValue UnpackPerm = lowerShuffleAsUNPCKAndPermute(DL, VT, V1, V2, Mask,
                                                           DAG))
      return UnpackPerm;
    if (SDValue RotatePerm = lowerShuffleAsByteRotateAndPermute(
            DL, VT, V1, V2, Mask, Subtarget, DAG))
      return RotatePerm;
    // Unpack/rotate failed - try again with variable blends.
    if (SDValue BlendPerm = lowerShuffleAsBlendAndPermute(DL, VT, V1, V2, Mask,
                                                          DAG))
      return BlendPerm;
  }

  V1 = DAG.getVectorShuffle(VT, DL, V1, DAG.getUNDEF(VT), V1Mask);
  V2 = DAG.getVectorShuffle(VT, DL, V2, DAG.getUNDEF(VT), V2Mask);
  return DAG.getVectorShuffle(VT, DL, V1, V2, BlendMask);
}

/// Try to lower a vector shuffle as a bit rotation.
///
/// Look for a repeated rotation pattern in each sub group.
/// Returns a ISD::ROTL element rotation amount or -1 if failed.
static int matchShuffleAsBitRotate(ArrayRef<int> Mask, int NumSubElts) {
  int NumElts = Mask.size();
  assert((NumElts % NumSubElts) == 0 && "Illegal shuffle mask");

  int RotateAmt = -1;
  for (int i = 0; i != NumElts; i += NumSubElts) {
    for (int j = 0; j != NumSubElts; ++j) {
      int M = Mask[i + j];
      if (M < 0)
        continue;
      if (!isInRange(M, i, i + NumSubElts))
        return -1;
      int Offset = (NumSubElts - (M - (i + j))) % NumSubElts;
      if (0 <= RotateAmt && Offset != RotateAmt)
        return -1;
      RotateAmt = Offset;
    }
  }
  return RotateAmt;
}

static int matchShuffleAsBitRotate(MVT &RotateVT, int EltSizeInBits,
                                   const X86Subtarget &Subtarget,
                                   ArrayRef<int> Mask) {
  assert(!isNoopShuffleMask(Mask) && "We shouldn't lower no-op shuffles!");
  assert(EltSizeInBits < 64 && "Can't rotate 64-bit integers");

  // AVX512 only has vXi32/vXi64 rotates, so limit the rotation sub group size.
  int MinSubElts = Subtarget.hasAVX512() ? std::max(32 / EltSizeInBits, 2) : 2;
  int MaxSubElts = 64 / EltSizeInBits;
  for (int NumSubElts = MinSubElts; NumSubElts <= MaxSubElts; NumSubElts *= 2) {
    int RotateAmt = matchShuffleAsBitRotate(Mask, NumSubElts);
    if (RotateAmt < 0)
      continue;

    int NumElts = Mask.size();
    MVT RotateSVT = MVT::getIntegerVT(EltSizeInBits * NumSubElts);
    RotateVT = MVT::getVectorVT(RotateSVT, NumElts / NumSubElts);
    return RotateAmt * EltSizeInBits;
  }

  return -1;
}

/// Lower shuffle using X86ISD::VROTLI rotations.
static SDValue lowerShuffleAsBitRotate(const SDLoc &DL, MVT VT, SDValue V1,
                                       ArrayRef<int> Mask,
                                       const X86Subtarget &Subtarget,
                                       SelectionDAG &DAG) {
  // Only XOP + AVX512 targets have bit rotation instructions.
  // If we at least have SSSE3 (PSHUFB) then we shouldn't attempt to use this.
  bool IsLegal =
      (VT.is128BitVector() && Subtarget.hasXOP()) || Subtarget.hasAVX512();
  if (!IsLegal && Subtarget.hasSSE3())
    return SDValue();

  MVT RotateVT;
  int RotateAmt = matchShuffleAsBitRotate(RotateVT, VT.getScalarSizeInBits(),
                                          Subtarget, Mask);
  if (RotateAmt < 0)
    return SDValue();

  // For pre-SSSE3 targets, if we are shuffling vXi8 elts then ISD::ROTL,
  // expanded to OR(SRL,SHL), will be more efficient, but if they can
  // widen to vXi16 or more then existing lowering should will be better.
  if (!IsLegal) {
    if ((RotateAmt % 16) == 0)
      return SDValue();
    // TODO: Use getTargetVShiftByConstNode.
    unsigned ShlAmt = RotateAmt;
    unsigned SrlAmt = RotateVT.getScalarSizeInBits() - RotateAmt;
    V1 = DAG.getBitcast(RotateVT, V1);
    SDValue SHL = DAG.getNode(X86ISD::VSHLI, DL, RotateVT, V1,
                              DAG.getTargetConstant(ShlAmt, DL, MVT::i8));
    SDValue SRL = DAG.getNode(X86ISD::VSRLI, DL, RotateVT, V1,
                              DAG.getTargetConstant(SrlAmt, DL, MVT::i8));
    SDValue Rot = DAG.getNode(ISD::OR, DL, RotateVT, SHL, SRL);
    return DAG.getBitcast(VT, Rot);
  }

  SDValue Rot =
      DAG.getNode(X86ISD::VROTLI, DL, RotateVT, DAG.getBitcast(RotateVT, V1),
                  DAG.getTargetConstant(RotateAmt, DL, MVT::i8));
  return DAG.getBitcast(VT, Rot);
}

/// Try to match a vector shuffle as an element rotation.
///
/// This is used for support PALIGNR for SSSE3 or VALIGND/Q for AVX512.
static int matchShuffleAsElementRotate(SDValue &V1, SDValue &V2,
                                       ArrayRef<int> Mask) {
  int NumElts = Mask.size();

  // We need to detect various ways of spelling a rotation:
  //   [11, 12, 13, 14, 15,  0,  1,  2]
  //   [-1, 12, 13, 14, -1, -1,  1, -1]
  //   [-1, -1, -1, -1, -1, -1,  1,  2]
  //   [ 3,  4,  5,  6,  7,  8,  9, 10]
  //   [-1,  4,  5,  6, -1, -1,  9, -1]
  //   [-1,  4,  5,  6, -1, -1, -1, -1]
  int Rotation = 0;
  SDValue Lo, Hi;
  for (int i = 0; i < NumElts; ++i) {
    int M = Mask[i];
    assert((M == SM_SentinelUndef || (0 <= M && M < (2*NumElts))) &&
           "Unexpected mask index.");
    if (M < 0)
      continue;

    // Determine where a rotated vector would have started.
    int StartIdx = i - (M % NumElts);
    if (StartIdx == 0)
      // The identity rotation isn't interesting, stop.
      return -1;

    // If we found the tail of a vector the rotation must be the missing
    // front. If we found the head of a vector, it must be how much of the
    // head.
    int CandidateRotation = StartIdx < 0 ? -StartIdx : NumElts - StartIdx;

    if (Rotation == 0)
      Rotation = CandidateRotation;
    else if (Rotation != CandidateRotation)
      // The rotations don't match, so we can't match this mask.
      return -1;

    // Compute which value this mask is pointing at.
    SDValue MaskV = M < NumElts ? V1 : V2;

    // Compute which of the two target values this index should be assigned
    // to. This reflects whether the high elements are remaining or the low
    // elements are remaining.
    SDValue &TargetV = StartIdx < 0 ? Hi : Lo;

    // Either set up this value if we've not encountered it before, or check
    // that it remains consistent.
    if (!TargetV)
      TargetV = MaskV;
    else if (TargetV != MaskV)
      // This may be a rotation, but it pulls from the inputs in some
      // unsupported interleaving.
      return -1;
  }

  // Check that we successfully analyzed the mask, and normalize the results.
  assert(Rotation != 0 && "Failed to locate a viable rotation!");
  assert((Lo || Hi) && "Failed to find a rotated input vector!");
  if (!Lo)
    Lo = Hi;
  else if (!Hi)
    Hi = Lo;

  V1 = Lo;
  V2 = Hi;

  return Rotation;
}

/// Try to lower a vector shuffle as a byte rotation.
///
/// SSSE3 has a generic PALIGNR instruction in x86 that will do an arbitrary
/// byte-rotation of the concatenation of two vectors; pre-SSSE3 can use
/// a PSRLDQ/PSLLDQ/POR pattern to get a similar effect. This routine will
/// try to generically lower a vector shuffle through such an pattern. It
/// does not check for the profitability of lowering either as PALIGNR or
/// PSRLDQ/PSLLDQ/POR, only whether the mask is valid to lower in that form.
/// This matches shuffle vectors that look like:
///
///   v8i16 [11, 12, 13, 14, 15, 0, 1, 2]
///
/// Essentially it concatenates V1 and V2, shifts right by some number of
/// elements, and takes the low elements as the result. Note that while this is
/// specified as a *right shift* because x86 is little-endian, it is a *left
/// rotate* of the vector lanes.
static int matchShuffleAsByteRotate(MVT VT, SDValue &V1, SDValue &V2,
                                    ArrayRef<int> Mask) {
  // Don't accept any shuffles with zero elements.
  if (any_of(Mask, [](int M) { return M == SM_SentinelZero; }))
    return -1;

  // PALIGNR works on 128-bit lanes.
  SmallVector<int, 16> RepeatedMask;
  if (!is128BitLaneRepeatedShuffleMask(VT, Mask, RepeatedMask))
    return -1;

  int Rotation = matchShuffleAsElementRotate(V1, V2, RepeatedMask);
  if (Rotation <= 0)
    return -1;

  // PALIGNR rotates bytes, so we need to scale the
  // rotation based on how many bytes are in the vector lane.
  int NumElts = RepeatedMask.size();
  int Scale = 16 / NumElts;
  return Rotation * Scale;
}

static SDValue lowerShuffleAsByteRotate(const SDLoc &DL, MVT VT, SDValue V1,
                                        SDValue V2, ArrayRef<int> Mask,
                                        const X86Subtarget &Subtarget,
                                        SelectionDAG &DAG) {
  assert(!isNoopShuffleMask(Mask) && "We shouldn't lower no-op shuffles!");

  SDValue Lo = V1, Hi = V2;
  int ByteRotation = matchShuffleAsByteRotate(VT, Lo, Hi, Mask);
  if (ByteRotation <= 0)
    return SDValue();

  // Cast the inputs to i8 vector of correct length to match PALIGNR or
  // PSLLDQ/PSRLDQ.
  MVT ByteVT = MVT::getVectorVT(MVT::i8, VT.getSizeInBits() / 8);
  Lo = DAG.getBitcast(ByteVT, Lo);
  Hi = DAG.getBitcast(ByteVT, Hi);

  // SSSE3 targets can use the palignr instruction.
  if (Subtarget.hasSSSE3()) {
    assert((!VT.is512BitVector() || Subtarget.hasBWI()) &&
           "512-bit PALIGNR requires BWI instructions");
    return DAG.getBitcast(
        VT, DAG.getNode(X86ISD::PALIGNR, DL, ByteVT, Lo, Hi,
                        DAG.getTargetConstant(ByteRotation, DL, MVT::i8)));
  }

  assert(VT.is128BitVector() &&
         "Rotate-based lowering only supports 128-bit lowering!");
  assert(Mask.size() <= 16 &&
         "Can shuffle at most 16 bytes in a 128-bit vector!");
  assert(ByteVT == MVT::v16i8 &&
         "SSE2 rotate lowering only needed for v16i8!");

  // Default SSE2 implementation
  int LoByteShift = 16 - ByteRotation;
  int HiByteShift = ByteRotation;

  SDValue LoShift =
      DAG.getNode(X86ISD::VSHLDQ, DL, MVT::v16i8, Lo,
                  DAG.getTargetConstant(LoByteShift, DL, MVT::i8));
  SDValue HiShift =
      DAG.getNode(X86ISD::VSRLDQ, DL, MVT::v16i8, Hi,
                  DAG.getTargetConstant(HiByteShift, DL, MVT::i8));
  return DAG.getBitcast(VT,
                        DAG.getNode(ISD::OR, DL, MVT::v16i8, LoShift, HiShift));
}

/// Try to lower a vector shuffle as a dword/qword rotation.
///
/// AVX512 has a VALIGND/VALIGNQ instructions that will do an arbitrary
/// rotation of the concatenation of two vectors; This routine will
/// try to generically lower a vector shuffle through such an pattern.
///
/// Essentially it concatenates V1 and V2, shifts right by some number of
/// elements, and takes the low elements as the result. Note that while this is
/// specified as a *right shift* because x86 is little-endian, it is a *left
/// rotate* of the vector lanes.
static SDValue lowerShuffleAsVALIGN(const SDLoc &DL, MVT VT, SDValue V1,
                                    SDValue V2, ArrayRef<int> Mask,
                                    const X86Subtarget &Subtarget,
                                    SelectionDAG &DAG) {
  assert((VT.getScalarType() == MVT::i32 || VT.getScalarType() == MVT::i64) &&
         "Only 32-bit and 64-bit elements are supported!");

  // 128/256-bit vectors are only supported with VLX.
  assert((Subtarget.hasVLX() || (!VT.is128BitVector() && !VT.is256BitVector()))
         && "VLX required for 128/256-bit vectors");

  SDValue Lo = V1, Hi = V2;
  int Rotation = matchShuffleAsElementRotate(Lo, Hi, Mask);
  if (Rotation <= 0)
    return SDValue();

  return DAG.getNode(X86ISD::VALIGN, DL, VT, Lo, Hi,
                     DAG.getTargetConstant(Rotation, DL, MVT::i8));
}

/// Try to lower a vector shuffle as a byte shift sequence.
static SDValue lowerShuffleAsByteShiftMask(const SDLoc &DL, MVT VT, SDValue V1,
                                           SDValue V2, ArrayRef<int> Mask,
                                           const APInt &Zeroable,
                                           const X86Subtarget &Subtarget,
                                           SelectionDAG &DAG) {
  assert(!isNoopShuffleMask(Mask) && "We shouldn't lower no-op shuffles!");
  assert(VT.is128BitVector() && "Only 128-bit vectors supported");

  // We need a shuffle that has zeros at one/both ends and a sequential
  // shuffle from one source within.
  unsigned ZeroLo = Zeroable.countTrailingOnes();
  unsigned ZeroHi = Zeroable.countLeadingOnes();
  if (!ZeroLo && !ZeroHi)
    return SDValue();

  unsigned NumElts = Mask.size();
  unsigned Len = NumElts - (ZeroLo + ZeroHi);
  if (!isSequentialOrUndefInRange(Mask, ZeroLo, Len, Mask[ZeroLo]))
    return SDValue();

  unsigned Scale = VT.getScalarSizeInBits() / 8;
  ArrayRef<int> StubMask = Mask.slice(ZeroLo, Len);
  if (!isUndefOrInRange(StubMask, 0, NumElts) &&
      !isUndefOrInRange(StubMask, NumElts, 2 * NumElts))
    return SDValue();

  SDValue Res = Mask[ZeroLo] < (int)NumElts ? V1 : V2;
  Res = DAG.getBitcast(MVT::v16i8, Res);

  // Use VSHLDQ/VSRLDQ ops to zero the ends of a vector and leave an
  // inner sequential set of elements, possibly offset:
  // 01234567 --> zzzzzz01 --> 1zzzzzzz
  // 01234567 --> 4567zzzz --> zzzzz456
  // 01234567 --> z0123456 --> 3456zzzz --> zz3456zz
  if (ZeroLo == 0) {
    unsigned Shift = (NumElts - 1) - (Mask[ZeroLo + Len - 1] % NumElts);
    Res = DAG.getNode(X86ISD::VSHLDQ, DL, MVT::v16i8, Res,
                      DAG.getTargetConstant(Scale * Shift, DL, MVT::i8));
    Res = DAG.getNode(X86ISD::VSRLDQ, DL, MVT::v16i8, Res,
                      DAG.getTargetConstant(Scale * ZeroHi, DL, MVT::i8));
  } else if (ZeroHi == 0) {
    unsigned Shift = Mask[ZeroLo] % NumElts;
    Res = DAG.getNode(X86ISD::VSRLDQ, DL, MVT::v16i8, Res,
                      DAG.getTargetConstant(Scale * Shift, DL, MVT::i8));
    Res = DAG.getNode(X86ISD::VSHLDQ, DL, MVT::v16i8, Res,
                      DAG.getTargetConstant(Scale * ZeroLo, DL, MVT::i8));
  } else if (!Subtarget.hasSSSE3()) {
    // If we don't have PSHUFB then its worth avoiding an AND constant mask
    // by performing 3 byte shifts. Shuffle combining can kick in above that.
    // TODO: There may be some cases where VSH{LR}DQ+PAND is still better.
    unsigned Shift = (NumElts - 1) - (Mask[ZeroLo + Len - 1] % NumElts);
    Res = DAG.getNode(X86ISD::VSHLDQ, DL, MVT::v16i8, Res,
                      DAG.getTargetConstant(Scale * Shift, DL, MVT::i8));
    Shift += Mask[ZeroLo] % NumElts;
    Res = DAG.getNode(X86ISD::VSRLDQ, DL, MVT::v16i8, Res,
                      DAG.getTargetConstant(Scale * Shift, DL, MVT::i8));
    Res = DAG.getNode(X86ISD::VSHLDQ, DL, MVT::v16i8, Res,
                      DAG.getTargetConstant(Scale * ZeroLo, DL, MVT::i8));
  } else
    return SDValue();

  return DAG.getBitcast(VT, Res);
}

/// Try to lower a vector shuffle as a bit shift (shifts in zeros).
///
/// Attempts to match a shuffle mask against the PSLL(W/D/Q/DQ) and
/// PSRL(W/D/Q/DQ) SSE2 and AVX2 logical bit-shift instructions. The function
/// matches elements from one of the input vectors shuffled to the left or
/// right with zeroable elements 'shifted in'. It handles both the strictly
/// bit-wise element shifts and the byte shift across an entire 128-bit double
/// quad word lane.
///
/// PSHL : (little-endian) left bit shift.
/// [ zz, 0, zz,  2 ]
/// [ -1, 4, zz, -1 ]
/// PSRL : (little-endian) right bit shift.
/// [  1, zz,  3, zz]
/// [ -1, -1,  7, zz]
/// PSLLDQ : (little-endian) left byte shift
/// [ zz,  0,  1,  2,  3,  4,  5,  6]
/// [ zz, zz, -1, -1,  2,  3,  4, -1]
/// [ zz, zz, zz, zz, zz, zz, -1,  1]
/// PSRLDQ : (little-endian) right byte shift
/// [  5, 6,  7, zz, zz, zz, zz, zz]
/// [ -1, 5,  6,  7, zz, zz, zz, zz]
/// [  1, 2, -1, -1, -1, -1, zz, zz]
static int matchShuffleAsShift(MVT &ShiftVT, unsigned &Opcode,
                               unsigned ScalarSizeInBits, ArrayRef<int> Mask,
                               int MaskOffset, const APInt &Zeroable,
                               const X86Subtarget &Subtarget) {
  int Size = Mask.size();
  unsigned SizeInBits = Size * ScalarSizeInBits;

  auto CheckZeros = [&](int Shift, int Scale, bool Left) {
    for (int i = 0; i < Size; i += Scale)
      for (int j = 0; j < Shift; ++j)
        if (!Zeroable[i + j + (Left ? 0 : (Scale - Shift))])
          return false;

    return true;
  };

  auto MatchShift = [&](int Shift, int Scale, bool Left) {
    for (int i = 0; i != Size; i += Scale) {
      unsigned Pos = Left ? i + Shift : i;
      unsigned Low = Left ? i : i + Shift;
      unsigned Len = Scale - Shift;
      if (!isSequentialOrUndefInRange(Mask, Pos, Len, Low + MaskOffset))
        return -1;
    }

    int ShiftEltBits = ScalarSizeInBits * Scale;
    bool ByteShift = ShiftEltBits > 64;
    Opcode = Left ? (ByteShift ? X86ISD::VSHLDQ : X86ISD::VSHLI)
                  : (ByteShift ? X86ISD::VSRLDQ : X86ISD::VSRLI);
    int ShiftAmt = Shift * ScalarSizeInBits / (ByteShift ? 8 : 1);

    // Normalize the scale for byte shifts to still produce an i64 element
    // type.
    Scale = ByteShift ? Scale / 2 : Scale;

    // We need to round trip through the appropriate type for the shift.
    MVT ShiftSVT = MVT::getIntegerVT(ScalarSizeInBits * Scale);
    ShiftVT = ByteShift ? MVT::getVectorVT(MVT::i8, SizeInBits / 8)
                        : MVT::getVectorVT(ShiftSVT, Size / Scale);
    return (int)ShiftAmt;
  };

  // SSE/AVX supports logical shifts up to 64-bit integers - so we can just
  // keep doubling the size of the integer elements up to that. We can
  // then shift the elements of the integer vector by whole multiples of
  // their width within the elements of the larger integer vector. Test each
  // multiple to see if we can find a match with the moved element indices
  // and that the shifted in elements are all zeroable.
  unsigned MaxWidth = ((SizeInBits == 512) && !Subtarget.hasBWI() ? 64 : 128);
  for (int Scale = 2; Scale * ScalarSizeInBits <= MaxWidth; Scale *= 2)
    for (int Shift = 1; Shift != Scale; ++Shift)
      for (bool Left : {true, false})
        if (CheckZeros(Shift, Scale, Left)) {
          int ShiftAmt = MatchShift(Shift, Scale, Left);
          if (0 < ShiftAmt)
            return ShiftAmt;
        }

  // no match
  return -1;
}

static SDValue lowerShuffleAsShift(const SDLoc &DL, MVT VT, SDValue V1,
                                   SDValue V2, ArrayRef<int> Mask,
                                   const APInt &Zeroable,
                                   const X86Subtarget &Subtarget,
                                   SelectionDAG &DAG) {
  int Size = Mask.size();
  assert(Size == (int)VT.getVectorNumElements() && "Unexpected mask size");

  MVT ShiftVT;
  SDValue V = V1;
  unsigned Opcode;

  // Try to match shuffle against V1 shift.
  int ShiftAmt = matchShuffleAsShift(ShiftVT, Opcode, VT.getScalarSizeInBits(),
                                     Mask, 0, Zeroable, Subtarget);

  // If V1 failed, try to match shuffle against V2 shift.
  if (ShiftAmt < 0) {
    ShiftAmt = matchShuffleAsShift(ShiftVT, Opcode, VT.getScalarSizeInBits(),
                                   Mask, Size, Zeroable, Subtarget);
    V = V2;
  }

  if (ShiftAmt < 0)
    return SDValue();

  assert(DAG.getTargetLoweringInfo().isTypeLegal(ShiftVT) &&
         "Illegal integer vector type");
  V = DAG.getBitcast(ShiftVT, V);
  V = DAG.getNode(Opcode, DL, ShiftVT, V,
                  DAG.getTargetConstant(ShiftAmt, DL, MVT::i8));
  return DAG.getBitcast(VT, V);
}

// EXTRQ: Extract Len elements from lower half of source, starting at Idx.
// Remainder of lower half result is zero and upper half is all undef.
static bool matchShuffleAsEXTRQ(MVT VT, SDValue &V1, SDValue &V2,
                                ArrayRef<int> Mask, uint64_t &BitLen,
                                uint64_t &BitIdx, const APInt &Zeroable) {
  int Size = Mask.size();
  int HalfSize = Size / 2;
  assert(Size == (int)VT.getVectorNumElements() && "Unexpected mask size");
  assert(!Zeroable.isAllOnesValue() && "Fully zeroable shuffle mask");

  // Upper half must be undefined.
  if (!isUndefUpperHalf(Mask))
    return false;

  // Determine the extraction length from the part of the
  // lower half that isn't zeroable.
  int Len = HalfSize;
  for (; Len > 0; --Len)
    if (!Zeroable[Len - 1])
      break;
  assert(Len > 0 && "Zeroable shuffle mask");

  // Attempt to match first Len sequential elements from the lower half.
  SDValue Src;
  int Idx = -1;
  for (int i = 0; i != Len; ++i) {
    int M = Mask[i];
    if (M == SM_SentinelUndef)
      continue;
    SDValue &V = (M < Size ? V1 : V2);
    M = M % Size;

    // The extracted elements must start at a valid index and all mask
    // elements must be in the lower half.
    if (i > M || M >= HalfSize)
      return false;

    if (Idx < 0 || (Src == V && Idx == (M - i))) {
      Src = V;
      Idx = M - i;
      continue;
    }
    return false;
  }

  if (!Src || Idx < 0)
    return false;

  assert((Idx + Len) <= HalfSize && "Illegal extraction mask");
  BitLen = (Len * VT.getScalarSizeInBits()) & 0x3f;
  BitIdx = (Idx * VT.getScalarSizeInBits()) & 0x3f;
  V1 = Src;
  return true;
}

// INSERTQ: Extract lowest Len elements from lower half of second source and
// insert over first source, starting at Idx.
// { A[0], .., A[Idx-1], B[0], .., B[Len-1], A[Idx+Len], .., UNDEF, ... }
static bool matchShuffleAsINSERTQ(MVT VT, SDValue &V1, SDValue &V2,
                                  ArrayRef<int> Mask, uint64_t &BitLen,
                                  uint64_t &BitIdx) {
  int Size = Mask.size();
  int HalfSize = Size / 2;
  assert(Size == (int)VT.getVectorNumElements() && "Unexpected mask size");

  // Upper half must be undefined.
  if (!isUndefUpperHalf(Mask))
    return false;

  for (int Idx = 0; Idx != HalfSize; ++Idx) {
    SDValue Base;

    // Attempt to match first source from mask before insertion point.
    if (isUndefInRange(Mask, 0, Idx)) {
      /* EMPTY */
    } else if (isSequentialOrUndefInRange(Mask, 0, Idx, 0)) {
      Base = V1;
    } else if (isSequentialOrUndefInRange(Mask, 0, Idx, Size)) {
      Base = V2;
    } else {
      continue;
    }

    // Extend the extraction length looking to match both the insertion of
    // the second source and the remaining elements of the first.
    for (int Hi = Idx + 1; Hi <= HalfSize; ++Hi) {
      SDValue Insert;
      int Len = Hi - Idx;

      // Match insertion.
      if (isSequentialOrUndefInRange(Mask, Idx, Len, 0)) {
        Insert = V1;
      } else if (isSequentialOrUndefInRange(Mask, Idx, Len, Size)) {
        Insert = V2;
      } else {
        continue;
      }

      // Match the remaining elements of the lower half.
      if (isUndefInRange(Mask, Hi, HalfSize - Hi)) {
        /* EMPTY */
      } else if ((!Base || (Base == V1)) &&
                 isSequentialOrUndefInRange(Mask, Hi, HalfSize - Hi, Hi)) {
        Base = V1;
      } else if ((!Base || (Base == V2)) &&
                 isSequentialOrUndefInRange(Mask, Hi, HalfSize - Hi,
                                            Size + Hi)) {
        Base = V2;
      } else {
        continue;
      }

      BitLen = (Len * VT.getScalarSizeInBits()) & 0x3f;
      BitIdx = (Idx * VT.getScalarSizeInBits()) & 0x3f;
      V1 = Base;
      V2 = Insert;
      return true;
    }
  }

  return false;
}

/// Try to lower a vector shuffle using SSE4a EXTRQ/INSERTQ.
static SDValue lowerShuffleWithSSE4A(const SDLoc &DL, MVT VT, SDValue V1,
                                     SDValue V2, ArrayRef<int> Mask,
                                     const APInt &Zeroable, SelectionDAG &DAG) {
  uint64_t BitLen, BitIdx;
  if (matchShuffleAsEXTRQ(VT, V1, V2, Mask, BitLen, BitIdx, Zeroable))
    return DAG.getNode(X86ISD::EXTRQI, DL, VT, V1,
                       DAG.getTargetConstant(BitLen, DL, MVT::i8),
                       DAG.getTargetConstant(BitIdx, DL, MVT::i8));

  if (matchShuffleAsINSERTQ(VT, V1, V2, Mask, BitLen, BitIdx))
    return DAG.getNode(X86ISD::INSERTQI, DL, VT, V1 ? V1 : DAG.getUNDEF(VT),
                       V2 ? V2 : DAG.getUNDEF(VT),
                       DAG.getTargetConstant(BitLen, DL, MVT::i8),
                       DAG.getTargetConstant(BitIdx, DL, MVT::i8));

  return SDValue();
}

/// Lower a vector shuffle as a zero or any extension.
///
/// Given a specific number of elements, element bit width, and extension
/// stride, produce either a zero or any extension based on the available
/// features of the subtarget. The extended elements are consecutive and
/// begin and can start from an offsetted element index in the input; to
/// avoid excess shuffling the offset must either being in the bottom lane
/// or at the start of a higher lane. All extended elements must be from
/// the same lane.
static SDValue lowerShuffleAsSpecificZeroOrAnyExtend(
    const SDLoc &DL, MVT VT, int Scale, int Offset, bool AnyExt, SDValue InputV,
    ArrayRef<int> Mask, const X86Subtarget &Subtarget, SelectionDAG &DAG) {
  assert(Scale > 1 && "Need a scale to extend.");
  int EltBits = VT.getScalarSizeInBits();
  int NumElements = VT.getVectorNumElements();
  int NumEltsPerLane = 128 / EltBits;
  int OffsetLane = Offset / NumEltsPerLane;
  assert((EltBits == 8 || EltBits == 16 || EltBits == 32) &&
         "Only 8, 16, and 32 bit elements can be extended.");
  assert(Scale * EltBits <= 64 && "Cannot zero extend past 64 bits.");
  assert(0 <= Offset && "Extension offset must be positive.");
  assert((Offset < NumEltsPerLane || Offset % NumEltsPerLane == 0) &&
         "Extension offset must be in the first lane or start an upper lane.");

  // Check that an index is in same lane as the base offset.
  auto SafeOffset = [&](int Idx) {
    return OffsetLane == (Idx / NumEltsPerLane);
  };

  // Shift along an input so that the offset base moves to the first element.
  auto ShuffleOffset = [&](SDValue V) {
    if (!Offset)
      return V;

    SmallVector<int, 8> ShMask((unsigned)NumElements, -1);
    for (int i = 0; i * Scale < NumElements; ++i) {
      int SrcIdx = i + Offset;
      ShMask[i] = SafeOffset(SrcIdx) ? SrcIdx : -1;
    }
    return DAG.getVectorShuffle(VT, DL, V, DAG.getUNDEF(VT), ShMask);
  };

  // Found a valid a/zext mask! Try various lowering strategies based on the
  // input type and available ISA extensions.
  if (Subtarget.hasSSE41()) {
    // Not worth offsetting 128-bit vectors if scale == 2, a pattern using
    // PUNPCK will catch this in a later shuffle match.
    if (Offset && Scale == 2 && VT.is128BitVector())
      return SDValue();
    MVT ExtVT = MVT::getVectorVT(MVT::getIntegerVT(EltBits * Scale),
                                 NumElements / Scale);
    InputV = ShuffleOffset(InputV);
    InputV = getExtendInVec(AnyExt ? ISD::ANY_EXTEND : ISD::ZERO_EXTEND, DL,
                            ExtVT, InputV, DAG);
    return DAG.getBitcast(VT, InputV);
  }

  assert(VT.is128BitVector() && "Only 128-bit vectors can be extended.");

  // For any extends we can cheat for larger element sizes and use shuffle
  // instructions that can fold with a load and/or copy.
  if (AnyExt && EltBits == 32) {
    int PSHUFDMask[4] = {Offset, -1, SafeOffset(Offset + 1) ? Offset + 1 : -1,
                         -1};
    return DAG.getBitcast(
        VT, DAG.getNode(X86ISD::PSHUFD, DL, MVT::v4i32,
                        DAG.getBitcast(MVT::v4i32, InputV),
                        getV4X86ShuffleImm8ForMask(PSHUFDMask, DL, DAG)));
  }
  if (AnyExt && EltBits == 16 && Scale > 2) {
    int PSHUFDMask[4] = {Offset / 2, -1,
                         SafeOffset(Offset + 1) ? (Offset + 1) / 2 : -1, -1};
    InputV = DAG.getNode(X86ISD::PSHUFD, DL, MVT::v4i32,
                         DAG.getBitcast(MVT::v4i32, InputV),
                         getV4X86ShuffleImm8ForMask(PSHUFDMask, DL, DAG));
    int PSHUFWMask[4] = {1, -1, -1, -1};
    unsigned OddEvenOp = (Offset & 1) ? X86ISD::PSHUFLW : X86ISD::PSHUFHW;
    return DAG.getBitcast(
        VT, DAG.getNode(OddEvenOp, DL, MVT::v8i16,
                        DAG.getBitcast(MVT::v8i16, InputV),
                        getV4X86ShuffleImm8ForMask(PSHUFWMask, DL, DAG)));
  }

  // The SSE4A EXTRQ instruction can efficiently extend the first 2 lanes
  // to 64-bits.
  if ((Scale * EltBits) == 64 && EltBits < 32 && Subtarget.hasSSE4A()) {
    assert(NumElements == (int)Mask.size() && "Unexpected shuffle mask size!");
    assert(VT.is128BitVector() && "Unexpected vector width!");

    int LoIdx = Offset * EltBits;
    SDValue Lo = DAG.getBitcast(
        MVT::v2i64, DAG.getNode(X86ISD::EXTRQI, DL, VT, InputV,
                                DAG.getTargetConstant(EltBits, DL, MVT::i8),
                                DAG.getTargetConstant(LoIdx, DL, MVT::i8)));

    if (isUndefUpperHalf(Mask) || !SafeOffset(Offset + 1))
      return DAG.getBitcast(VT, Lo);

    int HiIdx = (Offset + 1) * EltBits;
    SDValue Hi = DAG.getBitcast(
        MVT::v2i64, DAG.getNode(X86ISD::EXTRQI, DL, VT, InputV,
                                DAG.getTargetConstant(EltBits, DL, MVT::i8),
                                DAG.getTargetConstant(HiIdx, DL, MVT::i8)));
    return DAG.getBitcast(VT,
                          DAG.getNode(X86ISD::UNPCKL, DL, MVT::v2i64, Lo, Hi));
  }

  // If this would require more than 2 unpack instructions to expand, use
  // pshufb when available. We can only use more than 2 unpack instructions
  // when zero extending i8 elements which also makes it easier to use pshufb.
  if (Scale > 4 && EltBits == 8 && Subtarget.hasSSSE3()) {
    assert(NumElements == 16 && "Unexpected byte vector width!");
    SDValue PSHUFBMask[16];
    for (int i = 0; i < 16; ++i) {
      int Idx = Offset + (i / Scale);
      if ((i % Scale == 0 && SafeOffset(Idx))) {
        PSHUFBMask[i] = DAG.getConstant(Idx, DL, MVT::i8);
        continue;
      }
      PSHUFBMask[i] =
          AnyExt ? DAG.getUNDEF(MVT::i8) : DAG.getConstant(0x80, DL, MVT::i8);
    }
    InputV = DAG.getBitcast(MVT::v16i8, InputV);
    return DAG.getBitcast(
        VT, DAG.getNode(X86ISD::PSHUFB, DL, MVT::v16i8, InputV,
                        DAG.getBuildVector(MVT::v16i8, DL, PSHUFBMask)));
  }

  // If we are extending from an offset, ensure we start on a boundary that
  // we can unpack from.
  int AlignToUnpack = Offset % (NumElements / Scale);
  if (AlignToUnpack) {
    SmallVector<int, 8> ShMask((unsigned)NumElements, -1);
    for (int i = AlignToUnpack; i < NumElements; ++i)
      ShMask[i - AlignToUnpack] = i;
    InputV = DAG.getVectorShuffle(VT, DL, InputV, DAG.getUNDEF(VT), ShMask);
    Offset -= AlignToUnpack;
  }

  // Otherwise emit a sequence of unpacks.
  do {
    unsigned UnpackLoHi = X86ISD::UNPCKL;
    if (Offset >= (NumElements / 2)) {
      UnpackLoHi = X86ISD::UNPCKH;
      Offset -= (NumElements / 2);
    }

    MVT InputVT = MVT::getVectorVT(MVT::getIntegerVT(EltBits), NumElements);
    SDValue Ext = AnyExt ? DAG.getUNDEF(InputVT)
                         : getZeroVector(InputVT, Subtarget, DAG, DL);
    InputV = DAG.getBitcast(InputVT, InputV);
    InputV = DAG.getNode(UnpackLoHi, DL, InputVT, InputV, Ext);
    Scale /= 2;
    EltBits *= 2;
    NumElements /= 2;
  } while (Scale > 1);
  return DAG.getBitcast(VT, InputV);
}

/// Try to lower a vector shuffle as a zero extension on any microarch.
///
/// This routine will try to do everything in its power to cleverly lower
/// a shuffle which happens to match the pattern of a zero extend. It doesn't
/// check for the profitability of this lowering,  it tries to aggressively
/// match this pattern. It will use all of the micro-architectural details it
/// can to emit an efficient lowering. It handles both blends with all-zero
/// inputs to explicitly zero-extend and undef-lanes (sometimes undef due to
/// masking out later).
///
/// The reason we have dedicated lowering for zext-style shuffles is that they
/// are both incredibly common and often quite performance sensitive.
static SDValue lowerShuffleAsZeroOrAnyExtend(
    const SDLoc &DL, MVT VT, SDValue V1, SDValue V2, ArrayRef<int> Mask,
    const APInt &Zeroable, const X86Subtarget &Subtarget,
    SelectionDAG &DAG) {
  int Bits = VT.getSizeInBits();
  int NumLanes = Bits / 128;
  int NumElements = VT.getVectorNumElements();
  int NumEltsPerLane = NumElements / NumLanes;
  assert(VT.getScalarSizeInBits() <= 32 &&
         "Exceeds 32-bit integer zero extension limit");
  assert((int)Mask.size() == NumElements && "Unexpected shuffle mask size");

  // Define a helper function to check a particular ext-scale and lower to it if
  // valid.
  auto Lower = [&](int Scale) -> SDValue {
    SDValue InputV;
    bool AnyExt = true;
    int Offset = 0;
    int Matches = 0;
    for (int i = 0; i < NumElements; ++i) {
      int M = Mask[i];
      if (M < 0)
        continue; // Valid anywhere but doesn't tell us anything.
      if (i % Scale != 0) {
        // Each of the extended elements need to be zeroable.
        if (!Zeroable[i])
          return SDValue();

        // We no longer are in the anyext case.
        AnyExt = false;
        continue;
      }

      // Each of the base elements needs to be consecutive indices into the
      // same input vector.
      SDValue V = M < NumElements ? V1 : V2;
      M = M % NumElements;
      if (!InputV) {
        InputV = V;
        Offset = M - (i / Scale);
      } else if (InputV != V)
        return SDValue(); // Flip-flopping inputs.

      // Offset must start in the lowest 128-bit lane or at the start of an
      // upper lane.
      // FIXME: Is it ever worth allowing a negative base offset?
      if (!((0 <= Offset && Offset < NumEltsPerLane) ||
            (Offset % NumEltsPerLane) == 0))
        return SDValue();

      // If we are offsetting, all referenced entries must come from the same
      // lane.
      if (Offset && (Offset / NumEltsPerLane) != (M / NumEltsPerLane))
        return SDValue();

      if ((M % NumElements) != (Offset + (i / Scale)))
        return SDValue(); // Non-consecutive strided elements.
      Matches++;
    }

    // If we fail to find an input, we have a zero-shuffle which should always
    // have already been handled.
    // FIXME: Maybe handle this here in case during blending we end up with one?
    if (!InputV)
      return SDValue();

    // If we are offsetting, don't extend if we only match a single input, we
    // can always do better by using a basic PSHUF or PUNPCK.
    if (Offset != 0 && Matches < 2)
      return SDValue();

    return lowerShuffleAsSpecificZeroOrAnyExtend(DL, VT, Scale, Offset, AnyExt,
                                                 InputV, Mask, Subtarget, DAG);
  };

  // The widest scale possible for extending is to a 64-bit integer.
  assert(Bits % 64 == 0 &&
         "The number of bits in a vector must be divisible by 64 on x86!");
  int NumExtElements = Bits / 64;

  // Each iteration, try extending the elements half as much, but into twice as
  // many elements.
  for (; NumExtElements < NumElements; NumExtElements *= 2) {
    assert(NumElements % NumExtElements == 0 &&
           "The input vector size must be divisible by the extended size.");
    if (SDValue V = Lower(NumElements / NumExtElements))
      return V;
  }

  // General extends failed, but 128-bit vectors may be able to use MOVQ.
  if (Bits != 128)
    return SDValue();

  // Returns one of the source operands if the shuffle can be reduced to a
  // MOVQ, copying the lower 64-bits and zero-extending to the upper 64-bits.
  auto CanZExtLowHalf = [&]() {
    for (int i = NumElements / 2; i != NumElements; ++i)
      if (!Zeroable[i])
        return SDValue();
    if (isSequentialOrUndefInRange(Mask, 0, NumElements / 2, 0))
      return V1;
    if (isSequentialOrUndefInRange(Mask, 0, NumElements / 2, NumElements))
      return V2;
    return SDValue();
  };

  if (SDValue V = CanZExtLowHalf()) {
    V = DAG.getBitcast(MVT::v2i64, V);
    V = DAG.getNode(X86ISD::VZEXT_MOVL, DL, MVT::v2i64, V);
    return DAG.getBitcast(VT, V);
  }

  // No viable ext lowering found.
  return SDValue();
}

/// Try to get a scalar value for a specific element of a vector.
///
/// Looks through BUILD_VECTOR and SCALAR_TO_VECTOR nodes to find a scalar.
static SDValue getScalarValueForVectorElement(SDValue V, int Idx,
                                              SelectionDAG &DAG) {
  MVT VT = V.getSimpleValueType();
  MVT EltVT = VT.getVectorElementType();
  V = peekThroughBitcasts(V);

  // If the bitcasts shift the element size, we can't extract an equivalent
  // element from it.
  MVT NewVT = V.getSimpleValueType();
  if (!NewVT.isVector() || NewVT.getScalarSizeInBits() != VT.getScalarSizeInBits())
    return SDValue();

  if (V.getOpcode() == ISD::BUILD_VECTOR ||
      (Idx == 0 && V.getOpcode() == ISD::SCALAR_TO_VECTOR)) {
    // Ensure the scalar operand is the same size as the destination.
    // FIXME: Add support for scalar truncation where possible.
    SDValue S = V.getOperand(Idx);
    if (EltVT.getSizeInBits() == S.getSimpleValueType().getSizeInBits())
      return DAG.getBitcast(EltVT, S);
  }

  return SDValue();
}

/// Helper to test for a load that can be folded with x86 shuffles.
///
/// This is particularly important because the set of instructions varies
/// significantly based on whether the operand is a load or not.
static bool isShuffleFoldableLoad(SDValue V) {
  V = peekThroughBitcasts(V);
  return ISD::isNON_EXTLoad(V.getNode());
}

/// Try to lower insertion of a single element into a zero vector.
///
/// This is a common pattern that we have especially efficient patterns to lower
/// across all subtarget feature sets.
static SDValue lowerShuffleAsElementInsertion(
    const SDLoc &DL, MVT VT, SDValue V1, SDValue V2, ArrayRef<int> Mask,
    const APInt &Zeroable, const X86Subtarget &Subtarget,
    SelectionDAG &DAG) {
  MVT ExtVT = VT;
  MVT EltVT = VT.getVectorElementType();

  int V2Index =
      find_if(Mask, [&Mask](int M) { return M >= (int)Mask.size(); }) -
      Mask.begin();
  bool IsV1Zeroable = true;
  for (int i = 0, Size = Mask.size(); i < Size; ++i)
    if (i != V2Index && !Zeroable[i]) {
      IsV1Zeroable = false;
      break;
    }

  // Check for a single input from a SCALAR_TO_VECTOR node.
  // FIXME: All of this should be canonicalized into INSERT_VECTOR_ELT and
  // all the smarts here sunk into that routine. However, the current
  // lowering of BUILD_VECTOR makes that nearly impossible until the old
  // vector shuffle lowering is dead.
  SDValue V2S = getScalarValueForVectorElement(V2, Mask[V2Index] - Mask.size(),
                                               DAG);
  if (V2S && DAG.getTargetLoweringInfo().isTypeLegal(V2S.getValueType())) {
    // We need to zext the scalar if it is smaller than an i32.
    V2S = DAG.getBitcast(EltVT, V2S);
    if (EltVT == MVT::i8 || EltVT == MVT::i16) {
      // Using zext to expand a narrow element won't work for non-zero
      // insertions.
      if (!IsV1Zeroable)
        return SDValue();

      // Zero-extend directly to i32.
      ExtVT = MVT::getVectorVT(MVT::i32, ExtVT.getSizeInBits() / 32);
      V2S = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i32, V2S);
    }
    V2 = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, ExtVT, V2S);
  } else if (Mask[V2Index] != (int)Mask.size() || EltVT == MVT::i8 ||
             EltVT == MVT::i16) {
    // Either not inserting from the low element of the input or the input
    // element size is too small to use VZEXT_MOVL to clear the high bits.
    return SDValue();
  }

  if (!IsV1Zeroable) {
    // If V1 can't be treated as a zero vector we have fewer options to lower
    // this. We can't support integer vectors or non-zero targets cheaply, and
    // the V1 elements can't be permuted in any way.
    assert(VT == ExtVT && "Cannot change extended type when non-zeroable!");
    if (!VT.isFloatingPoint() || V2Index != 0)
      return SDValue();
    SmallVector<int, 8> V1Mask(Mask.begin(), Mask.end());
    V1Mask[V2Index] = -1;
    if (!isNoopShuffleMask(V1Mask))
      return SDValue();
    if (!VT.is128BitVector())
      return SDValue();

    // Otherwise, use MOVSD or MOVSS.
    assert((EltVT == MVT::f32 || EltVT == MVT::f64) &&
           "Only two types of floating point element types to handle!");
    return DAG.getNode(EltVT == MVT::f32 ? X86ISD::MOVSS : X86ISD::MOVSD, DL,
                       ExtVT, V1, V2);
  }

  // This lowering only works for the low element with floating point vectors.
  if (VT.isFloatingPoint() && V2Index != 0)
    return SDValue();

  V2 = DAG.getNode(X86ISD::VZEXT_MOVL, DL, ExtVT, V2);
  if (ExtVT != VT)
    V2 = DAG.getBitcast(VT, V2);

  if (V2Index != 0) {
    // If we have 4 or fewer lanes we can cheaply shuffle the element into
    // the desired position. Otherwise it is more efficient to do a vector
    // shift left. We know that we can do a vector shift left because all
    // the inputs are zero.
    if (VT.isFloatingPoint() || VT.getVectorNumElements() <= 4) {
      SmallVector<int, 4> V2Shuffle(Mask.size(), 1);
      V2Shuffle[V2Index] = 0;
      V2 = DAG.getVectorShuffle(VT, DL, V2, DAG.getUNDEF(VT), V2Shuffle);
    } else {
      V2 = DAG.getBitcast(MVT::v16i8, V2);
      V2 = DAG.getNode(X86ISD::VSHLDQ, DL, MVT::v16i8, V2,
                       DAG.getTargetConstant(
                           V2Index * EltVT.getSizeInBits() / 8, DL, MVT::i8));
      V2 = DAG.getBitcast(VT, V2);
    }
  }
  return V2;
}

/// Try to lower broadcast of a single - truncated - integer element,
/// coming from a scalar_to_vector/build_vector node \p V0 with larger elements.
///
/// This assumes we have AVX2.
static SDValue lowerShuffleAsTruncBroadcast(const SDLoc &DL, MVT VT, SDValue V0,
                                            int BroadcastIdx,
                                            const X86Subtarget &Subtarget,
                                            SelectionDAG &DAG) {
  assert(Subtarget.hasAVX2() &&
         "We can only lower integer broadcasts with AVX2!");

  MVT EltVT = VT.getVectorElementType();
  MVT V0VT = V0.getSimpleValueType();

  assert(VT.isInteger() && "Unexpected non-integer trunc broadcast!");
  assert(V0VT.isVector() && "Unexpected non-vector vector-sized value!");

  MVT V0EltVT = V0VT.getVectorElementType();
  if (!V0EltVT.isInteger())
    return SDValue();

  const unsigned EltSize = EltVT.getSizeInBits();
  const unsigned V0EltSize = V0EltVT.getSizeInBits();

  // This is only a truncation if the original element type is larger.
  if (V0EltSize <= EltSize)
    return SDValue();

  assert(((V0EltSize % EltSize) == 0) &&
         "Scalar type sizes must all be powers of 2 on x86!");

  const unsigned V0Opc = V0.getOpcode();
  const unsigned Scale = V0EltSize / EltSize;
  const unsigned V0BroadcastIdx = BroadcastIdx / Scale;

  if ((V0Opc != ISD::SCALAR_TO_VECTOR || V0BroadcastIdx != 0) &&
      V0Opc != ISD::BUILD_VECTOR)
    return SDValue();

  SDValue Scalar = V0.getOperand(V0BroadcastIdx);

  // If we're extracting non-least-significant bits, shift so we can truncate.
  // Hopefully, we can fold away the trunc/srl/load into the broadcast.
  // Even if we can't (and !isShuffleFoldableLoad(Scalar)), prefer
  // vpbroadcast+vmovd+shr to vpshufb(m)+vmovd.
  if (const int OffsetIdx = BroadcastIdx % Scale)
    Scalar = DAG.getNode(ISD::SRL, DL, Scalar.getValueType(), Scalar,
                         DAG.getConstant(OffsetIdx * EltSize, DL, MVT::i8));

  return DAG.getNode(X86ISD::VBROADCAST, DL, VT,
                     DAG.getNode(ISD::TRUNCATE, DL, EltVT, Scalar));
}

/// Test whether this can be lowered with a single SHUFPS instruction.
///
/// This is used to disable more specialized lowerings when the shufps lowering
/// will happen to be efficient.
static bool isSingleSHUFPSMask(ArrayRef<int> Mask) {
  // This routine only handles 128-bit shufps.
  assert(Mask.size() == 4 && "Unsupported mask size!");
  assert(Mask[0] >= -1 && Mask[0] < 8 && "Out of bound mask element!");
  assert(Mask[1] >= -1 && Mask[1] < 8 && "Out of bound mask element!");
  assert(Mask[2] >= -1 && Mask[2] < 8 && "Out of bound mask element!");
  assert(Mask[3] >= -1 && Mask[3] < 8 && "Out of bound mask element!");

  // To lower with a single SHUFPS we need to have the low half and high half
  // each requiring a single input.
  if (Mask[0] >= 0 && Mask[1] >= 0 && (Mask[0] < 4) != (Mask[1] < 4))
    return false;
  if (Mask[2] >= 0 && Mask[3] >= 0 && (Mask[2] < 4) != (Mask[3] < 4))
    return false;

  return true;
}

/// If we are extracting two 128-bit halves of a vector and shuffling the
/// result, match that to a 256-bit AVX2 vperm* instruction to avoid a
/// multi-shuffle lowering.
static SDValue lowerShuffleOfExtractsAsVperm(const SDLoc &DL, SDValue N0,
                                             SDValue N1, ArrayRef<int> Mask,
                                             SelectionDAG &DAG) {
  MVT VT = N0.getSimpleValueType();
  assert((VT.is128BitVector() &&
          (VT.getScalarSizeInBits() == 32 || VT.getScalarSizeInBits() == 64)) &&
         "VPERM* family of shuffles requires 32-bit or 64-bit elements");

  // Check that both sources are extracts of the same source vector.
  if (!N0.hasOneUse() || !N1.hasOneUse() ||
      N0.getOpcode() != ISD::EXTRACT_SUBVECTOR ||
      N1.getOpcode() != ISD::EXTRACT_SUBVECTOR ||
      N0.getOperand(0) != N1.getOperand(0))
    return SDValue();

  SDValue WideVec = N0.getOperand(0);
  MVT WideVT = WideVec.getSimpleValueType();
  if (!WideVT.is256BitVector() || !isa<ConstantSDNode>(N0.getOperand(1)) ||
      !isa<ConstantSDNode>(N1.getOperand(1)))
    return SDValue();

  // Match extracts of each half of the wide source vector. Commute the shuffle
  // if the extract of the low half is N1.
  unsigned NumElts = VT.getVectorNumElements();
  SmallVector<int, 4> NewMask(Mask.begin(), Mask.end());
  const APInt &ExtIndex0 = N0.getConstantOperandAPInt(1);
  const APInt &ExtIndex1 = N1.getConstantOperandAPInt(1);
  if (ExtIndex1 == 0 && ExtIndex0 == NumElts)
    ShuffleVectorSDNode::commuteMask(NewMask);
  else if (ExtIndex0 != 0 || ExtIndex1 != NumElts)
    return SDValue();

  // Final bailout: if the mask is simple, we are better off using an extract
  // and a simple narrow shuffle. Prefer extract+unpack(h/l)ps to vpermps
  // because that avoids a constant load from memory.
  if (NumElts == 4 &&
      (isSingleSHUFPSMask(NewMask) || is128BitUnpackShuffleMask(NewMask)))
    return SDValue();

  // Extend the shuffle mask with undef elements.
  NewMask.append(NumElts, -1);

  // shuf (extract X, 0), (extract X, 4), M --> extract (shuf X, undef, M'), 0
  SDValue Shuf = DAG.getVectorShuffle(WideVT, DL, WideVec, DAG.getUNDEF(WideVT),
                                      NewMask);
  // This is free: ymm -> xmm.
  return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, VT, Shuf,
                     DAG.getIntPtrConstant(0, DL));
}

/// Try to lower broadcast of a single element.
///
/// For convenience, this code also bundles all of the subtarget feature set
/// filtering. While a little annoying to re-dispatch on type here, there isn't
/// a convenient way to factor it out.
static SDValue lowerShuffleAsBroadcast(const SDLoc &DL, MVT VT, SDValue V1,
                                       SDValue V2, ArrayRef<int> Mask,
                                       const X86Subtarget &Subtarget,
                                       SelectionDAG &DAG) {
  if (!((Subtarget.hasSSE3() && VT == MVT::v2f64) ||
        (Subtarget.hasAVX() && VT.isFloatingPoint()) ||
        (Subtarget.hasAVX2() && VT.isInteger())))
    return SDValue();

  // With MOVDDUP (v2f64) we can broadcast from a register or a load, otherwise
  // we can only broadcast from a register with AVX2.
  unsigned NumEltBits = VT.getScalarSizeInBits();
  unsigned Opcode = (VT == MVT::v2f64 && !Subtarget.hasAVX2())
                        ? X86ISD::MOVDDUP
                        : X86ISD::VBROADCAST;
  bool BroadcastFromReg = (Opcode == X86ISD::MOVDDUP) || Subtarget.hasAVX2();

  // Check that the mask is a broadcast.
  int BroadcastIdx = getSplatIndex(Mask);
  if (BroadcastIdx < 0)
    return SDValue();
  assert(BroadcastIdx < (int)Mask.size() && "We only expect to be called with "
                                            "a sorted mask where the broadcast "
                                            "comes from V1.");

  // Go up the chain of (vector) values to find a scalar load that we can
  // combine with the broadcast.
  // TODO: Combine this logic with findEltLoadSrc() used by
  //       EltsFromConsecutiveLoads().
  int BitOffset = BroadcastIdx * NumEltBits;
  SDValue V = V1;
  for (;;) {
    switch (V.getOpcode()) {
    case ISD::BITCAST: {
      V = V.getOperand(0);
      continue;
    }
    case ISD::CONCAT_VECTORS: {
      int OpBitWidth = V.getOperand(0).getValueSizeInBits();
      int OpIdx = BitOffset / OpBitWidth;
      V = V.getOperand(OpIdx);
      BitOffset %= OpBitWidth;
      continue;
    }
    case ISD::EXTRACT_SUBVECTOR: {
      auto *ConstantIdx = dyn_cast<ConstantSDNode>(V.getOperand(1));
      if (!ConstantIdx)
        break;

      // The extraction index adds to the existing offset.
      unsigned EltBitWidth = V.getScalarValueSizeInBits();
      unsigned Idx = ConstantIdx->getZExtValue();
      unsigned BeginOffset = Idx * EltBitWidth;
      BitOffset += BeginOffset;
      V = V.getOperand(0);
      continue;
    }
    case ISD::INSERT_SUBVECTOR: {
      SDValue VOuter = V.getOperand(0), VInner = V.getOperand(1);
      auto ConstantIdx = dyn_cast<ConstantSDNode>(V.getOperand(2));
      if (!ConstantIdx)
        break;

      int EltBitWidth = VOuter.getScalarValueSizeInBits();
      int Idx = (int)ConstantIdx->getZExtValue();
      int NumSubElts = (int)VInner.getSimpleValueType().getVectorNumElements();
      int BeginOffset = Idx * EltBitWidth;
      int EndOffset = BeginOffset + NumSubElts * EltBitWidth;
      if (BeginOffset <= BitOffset && BitOffset < EndOffset) {
        BitOffset -= BeginOffset;
        V = VInner;
      } else {
        V = VOuter;
      }
      continue;
    }
    }
    break;
  }
  assert((BitOffset % NumEltBits) == 0 && "Illegal bit-offset");
  BroadcastIdx = BitOffset / NumEltBits;

  // Do we need to bitcast the source to retrieve the original broadcast index?
  bool BitCastSrc = V.getScalarValueSizeInBits() != NumEltBits;

  // Check if this is a broadcast of a scalar. We special case lowering
  // for scalars so that we can more effectively fold with loads.
  // If the original value has a larger element type than the shuffle, the
  // broadcast element is in essence truncated. Make that explicit to ease
  // folding.
  if (BitCastSrc && VT.isInteger())
    if (SDValue TruncBroadcast = lowerShuffleAsTruncBroadcast(
            DL, VT, V, BroadcastIdx, Subtarget, DAG))
      return TruncBroadcast;

  // Also check the simpler case, where we can directly reuse the scalar.
  if (!BitCastSrc &&
      ((V.getOpcode() == ISD::BUILD_VECTOR && V.hasOneUse()) ||
       (V.getOpcode() == ISD::SCALAR_TO_VECTOR && BroadcastIdx == 0))) {
    V = V.getOperand(BroadcastIdx);

    // If we can't broadcast from a register, check that the input is a load.
    if (!BroadcastFromReg && !isShuffleFoldableLoad(V))
      return SDValue();
  } else if (ISD::isNormalLoad(V.getNode()) &&
             cast<LoadSDNode>(V)->isSimple()) {
    // We do not check for one-use of the vector load because a broadcast load
    // is expected to be a win for code size, register pressure, and possibly
    // uops even if the original vector load is not eliminated.

    // Reduce the vector load and shuffle to a broadcasted scalar load.
    LoadSDNode *Ld = cast<LoadSDNode>(V);
    SDValue BaseAddr = Ld->getOperand(1);
    MVT SVT = VT.getScalarType();
    unsigned Offset = BroadcastIdx * SVT.getStoreSize();
    assert((int)(Offset * 8) == BitOffset && "Unexpected bit-offset");
    SDValue NewAddr = DAG.getMemBasePlusOffset(BaseAddr, Offset, DL);

    // Directly form VBROADCAST_LOAD if we're using VBROADCAST opcode rather
    // than MOVDDUP.
    // FIXME: Should we add VBROADCAST_LOAD isel patterns for pre-AVX?
    if (Opcode == X86ISD::VBROADCAST) {
      SDVTList Tys = DAG.getVTList(VT, MVT::Other);
      SDValue Ops[] = {Ld->getChain(), NewAddr};
      V = DAG.getMemIntrinsicNode(
          X86ISD::VBROADCAST_LOAD, DL, Tys, Ops, SVT,
          DAG.getMachineFunction().getMachineMemOperand(
              Ld->getMemOperand(), Offset, SVT.getStoreSize()));
      DAG.makeEquivalentMemoryOrdering(Ld, V);
      return DAG.getBitcast(VT, V);
    }
    assert(SVT == MVT::f64 && "Unexpected VT!");
    V = DAG.getLoad(SVT, DL, Ld->getChain(), NewAddr,
                    DAG.getMachineFunction().getMachineMemOperand(
                        Ld->getMemOperand(), Offset, SVT.getStoreSize()));
    DAG.makeEquivalentMemoryOrdering(Ld, V);
  } else if (!BroadcastFromReg) {
    // We can't broadcast from a vector register.
    return SDValue();
  } else if (BitOffset != 0) {
    // We can only broadcast from the zero-element of a vector register,
    // but it can be advantageous to broadcast from the zero-element of a
    // subvector.
    if (!VT.is256BitVector() && !VT.is512BitVector())
      return SDValue();

    // VPERMQ/VPERMPD can perform the cross-lane shuffle directly.
    if (VT == MVT::v4f64 || VT == MVT::v4i64)
      return SDValue();

    // Only broadcast the zero-element of a 128-bit subvector.
    if ((BitOffset % 128) != 0)
      return SDValue();

    assert((BitOffset % V.getScalarValueSizeInBits()) == 0 &&
           "Unexpected bit-offset");
    assert((V.getValueSizeInBits() == 256 || V.getValueSizeInBits() == 512) &&
           "Unexpected vector size");
    unsigned ExtractIdx = BitOffset / V.getScalarValueSizeInBits();
    V = extract128BitVector(V, ExtractIdx, DAG, DL);
  }

  if (Opcode == X86ISD::MOVDDUP && !V.getValueType().isVector())
    V = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v2f64,
                    DAG.getBitcast(MVT::f64, V));

  // If this is a scalar, do the broadcast on this type and bitcast.
  if (!V.getValueType().isVector()) {
    assert(V.getScalarValueSizeInBits() == NumEltBits &&
           "Unexpected scalar size");
    MVT BroadcastVT = MVT::getVectorVT(V.getSimpleValueType(),
                                       VT.getVectorNumElements());
    return DAG.getBitcast(VT, DAG.getNode(Opcode, DL, BroadcastVT, V));
  }

  // We only support broadcasting from 128-bit vectors to minimize the
  // number of patterns we need to deal with in isel. So extract down to
  // 128-bits, removing as many bitcasts as possible.
  if (V.getValueSizeInBits() > 128)
    V = extract128BitVector(peekThroughBitcasts(V), 0, DAG, DL);

  // Otherwise cast V to a vector with the same element type as VT, but
  // possibly narrower than VT. Then perform the broadcast.
  unsigned NumSrcElts = V.getValueSizeInBits() / NumEltBits;
  MVT CastVT = MVT::getVectorVT(VT.getVectorElementType(), NumSrcElts);
  return DAG.getNode(Opcode, DL, VT, DAG.getBitcast(CastVT, V));
}

// Check for whether we can use INSERTPS to perform the shuffle. We only use
// INSERTPS when the V1 elements are already in the correct locations
// because otherwise we can just always use two SHUFPS instructions which
// are much smaller to encode than a SHUFPS and an INSERTPS. We can also
// perform INSERTPS if a single V1 element is out of place and all V2
// elements are zeroable.
static bool matchShuffleAsInsertPS(SDValue &V1, SDValue &V2,
                                   unsigned &InsertPSMask,
                                   const APInt &Zeroable,
                                   ArrayRef<int> Mask, SelectionDAG &DAG) {
  assert(V1.getSimpleValueType().is128BitVector() && "Bad operand type!");
  assert(V2.getSimpleValueType().is128BitVector() && "Bad operand type!");
  assert(Mask.size() == 4 && "Unexpected mask size for v4 shuffle!");

  // Attempt to match INSERTPS with one element from VA or VB being
  // inserted into VA (or undef). If successful, V1, V2 and InsertPSMask
  // are updated.
  auto matchAsInsertPS = [&](SDValue VA, SDValue VB,
                             ArrayRef<int> CandidateMask) {
    unsigned ZMask = 0;
    int VADstIndex = -1;
    int VBDstIndex = -1;
    bool VAUsedInPlace = false;

    for (int i = 0; i < 4; ++i) {
      // Synthesize a zero mask from the zeroable elements (includes undefs).
      if (Zeroable[i]) {
        ZMask |= 1 << i;
        continue;
      }

      // Flag if we use any VA inputs in place.
      if (i == CandidateMask[i]) {
        VAUsedInPlace = true;
        continue;
      }

      // We can only insert a single non-zeroable element.
      if (VADstIndex >= 0 || VBDstIndex >= 0)
        return false;

      if (CandidateMask[i] < 4) {
        // VA input out of place for insertion.
        VADstIndex = i;
      } else {
        // VB input for insertion.
        VBDstIndex = i;
      }
    }

    // Don't bother if we have no (non-zeroable) element for insertion.
    if (VADstIndex < 0 && VBDstIndex < 0)
      return false;

    // Determine element insertion src/dst indices. The src index is from the
    // start of the inserted vector, not the start of the concatenated vector.
    unsigned VBSrcIndex = 0;
    if (VADstIndex >= 0) {
      // If we have a VA input out of place, we use VA as the V2 element
      // insertion and don't use the original V2 at all.
      VBSrcIndex = CandidateMask[VADstIndex];
      VBDstIndex = VADstIndex;
      VB = VA;
    } else {
      VBSrcIndex = CandidateMask[VBDstIndex] - 4;
    }

    // If no V1 inputs are used in place, then the result is created only from
    // the zero mask and the V2 insertion - so remove V1 dependency.
    if (!VAUsedInPlace)
      VA = DAG.getUNDEF(MVT::v4f32);

    // Update V1, V2 and InsertPSMask accordingly.
    V1 = VA;
    V2 = VB;

    // Insert the V2 element into the desired position.
    InsertPSMask = VBSrcIndex << 6 | VBDstIndex << 4 | ZMask;
    assert((InsertPSMask & ~0xFFu) == 0 && "Invalid mask!");
    return true;
  };

  if (matchAsInsertPS(V1, V2, Mask))
    return true;

  // Commute and try again.
  SmallVector<int, 4> CommutedMask(Mask.begin(), Mask.end());
  ShuffleVectorSDNode::commuteMask(CommutedMask);
  if (matchAsInsertPS(V2, V1, CommutedMask))
    return true;

  return false;
}

static SDValue lowerShuffleAsInsertPS(const SDLoc &DL, SDValue V1, SDValue V2,
                                      ArrayRef<int> Mask, const APInt &Zeroable,
                                      SelectionDAG &DAG) {
  assert(V1.getSimpleValueType() == MVT::v4f32 && "Bad operand type!");
  assert(V2.getSimpleValueType() == MVT::v4f32 && "Bad operand type!");

  // Attempt to match the insertps pattern.
  unsigned InsertPSMask;
  if (!matchShuffleAsInsertPS(V1, V2, InsertPSMask, Zeroable, Mask, DAG))
    return SDValue();

  // Insert the V2 element into the desired position.
  return DAG.getNode(X86ISD::INSERTPS, DL, MVT::v4f32, V1, V2,
                     DAG.getTargetConstant(InsertPSMask, DL, MVT::i8));
}

/// Try to lower a shuffle as a permute of the inputs followed by an
/// UNPCK instruction.
///
/// This specifically targets cases where we end up with alternating between
/// the two inputs, and so can permute them into something that feeds a single
/// UNPCK instruction. Note that this routine only targets integer vectors
/// because for floating point vectors we have a generalized SHUFPS lowering
/// strategy that handles everything that doesn't *exactly* match an unpack,
/// making this clever lowering unnecessary.
static SDValue lowerShuffleAsPermuteAndUnpack(
    const SDLoc &DL, MVT VT, SDValue V1, SDValue V2, ArrayRef<int> Mask,
    const X86Subtarget &Subtarget, SelectionDAG &DAG) {
  assert(!VT.isFloatingPoint() &&
         "This routine only supports integer vectors.");
  assert(VT.is128BitVector() &&
         "This routine only works on 128-bit vectors.");
  assert(!V2.isUndef() &&
         "This routine should only be used when blending two inputs.");
  assert(Mask.size() >= 2 && "Single element masks are invalid.");

  int Size = Mask.size();

  int NumLoInputs =
      count_if(Mask, [Size](int M) { return M >= 0 && M % Size < Size / 2; });
  int NumHiInputs =
      count_if(Mask, [Size](int M) { return M % Size >= Size / 2; });

  bool UnpackLo = NumLoInputs >= NumHiInputs;

  auto TryUnpack = [&](int ScalarSize, int Scale) {
    SmallVector<int, 16> V1Mask((unsigned)Size, -1);
    SmallVector<int, 16> V2Mask((unsigned)Size, -1);

    for (int i = 0; i < Size; ++i) {
      if (Mask[i] < 0)
        continue;

      // Each element of the unpack contains Scale elements from this mask.
      int UnpackIdx = i / Scale;

      // We only handle the case where V1 feeds the first slots of the unpack.
      // We rely on canonicalization to ensure this is the case.
      if ((UnpackIdx % 2 == 0) != (Mask[i] < Size))
        return SDValue();

      // Setup the mask for this input. The indexing is tricky as we have to
      // handle the unpack stride.
      SmallVectorImpl<int> &VMask = (UnpackIdx % 2 == 0) ? V1Mask : V2Mask;
      VMask[(UnpackIdx / 2) * Scale + i % Scale + (UnpackLo ? 0 : Size / 2)] =
          Mask[i] % Size;
    }

    // If we will have to shuffle both inputs to use the unpack, check whether
    // we can just unpack first and shuffle the result. If so, skip this unpack.
    if ((NumLoInputs == 0 || NumHiInputs == 0) && !isNoopShuffleMask(V1Mask) &&
        !isNoopShuffleMask(V2Mask))
      return SDValue();

    // Shuffle the inputs into place.
    V1 = DAG.getVectorShuffle(VT, DL, V1, DAG.getUNDEF(VT), V1Mask);
    V2 = DAG.getVectorShuffle(VT, DL, V2, DAG.getUNDEF(VT), V2Mask);

    // Cast the inputs to the type we will use to unpack them.
    MVT UnpackVT = MVT::getVectorVT(MVT::getIntegerVT(ScalarSize), Size / Scale);
    V1 = DAG.getBitcast(UnpackVT, V1);
    V2 = DAG.getBitcast(UnpackVT, V2);

    // Unpack the inputs and cast the result back to the desired type.
    return DAG.getBitcast(
        VT, DAG.getNode(UnpackLo ? X86ISD::UNPCKL : X86ISD::UNPCKH, DL,
                        UnpackVT, V1, V2));
  };

  // We try each unpack from the largest to the smallest to try and find one
  // that fits this mask.
  int OrigScalarSize = VT.getScalarSizeInBits();
  for (int ScalarSize = 64; ScalarSize >= OrigScalarSize; ScalarSize /= 2)
    if (SDValue Unpack = TryUnpack(ScalarSize, ScalarSize / OrigScalarSize))
      return Unpack;

  // If we're shuffling with a zero vector then we're better off not doing
  // VECTOR_SHUFFLE(UNPCK()) as we lose track of those zero elements.
  if (ISD::isBuildVectorAllZeros(V1.getNode()) ||
      ISD::isBuildVectorAllZeros(V2.getNode()))
    return SDValue();

  // If none of the unpack-rooted lowerings worked (or were profitable) try an
  // initial unpack.
  if (NumLoInputs == 0 || NumHiInputs == 0) {
    assert((NumLoInputs > 0 || NumHiInputs > 0) &&
           "We have to have *some* inputs!");
    int HalfOffset = NumLoInputs == 0 ? Size / 2 : 0;

    // FIXME: We could consider the total complexity of the permute of each
    // possible unpacking. Or at the least we should consider how many
    // half-crossings are created.
    // FIXME: We could consider commuting the unpacks.

    SmallVector<int, 32> PermMask((unsigned)Size, -1);
    for (int i = 0; i < Size; ++i) {
      if (Mask[i] < 0)
        continue;

      assert(Mask[i] % Size >= HalfOffset && "Found input from wrong half!");

      PermMask[i] =
          2 * ((Mask[i] % Size) - HalfOffset) + (Mask[i] < Size ? 0 : 1);
    }
    return DAG.getVectorShuffle(
        VT, DL, DAG.getNode(NumLoInputs == 0 ? X86ISD::UNPCKH : X86ISD::UNPCKL,
                            DL, VT, V1, V2),
        DAG.getUNDEF(VT), PermMask);
  }

  return SDValue();
}

/// Handle lowering of 2-lane 64-bit floating point shuffles.
///
/// This is the basis function for the 2-lane 64-bit shuffles as we have full
/// support for floating point shuffles but not integer shuffles. These
/// instructions will incur a domain crossing penalty on some chips though so
/// it is better to avoid lowering through this for integer vectors where
/// possible.
static SDValue lowerV2F64Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
                                 const APInt &Zeroable, SDValue V1, SDValue V2,
                                 const X86Subtarget &Subtarget,
                                 SelectionDAG &DAG) {
  assert(V1.getSimpleValueType() == MVT::v2f64 && "Bad operand type!");
  assert(V2.getSimpleValueType() == MVT::v2f64 && "Bad operand type!");
  assert(Mask.size() == 2 && "Unexpected mask size for v2 shuffle!");

  if (V2.isUndef()) {
    // Check for being able to broadcast a single element.
    if (SDValue Broadcast = lowerShuffleAsBroadcast(DL, MVT::v2f64, V1, V2,
                                                    Mask, Subtarget, DAG))
      return Broadcast;

    // Straight shuffle of a single input vector. Simulate this by using the
    // single input as both of the "inputs" to this instruction..
    unsigned SHUFPDMask = (Mask[0] == 1) | ((Mask[1] == 1) << 1);

    if (Subtarget.hasAVX()) {
      // If we have AVX, we can use VPERMILPS which will allow folding a load
      // into the shuffle.
      return DAG.getNode(X86ISD::VPERMILPI, DL, MVT::v2f64, V1,
                         DAG.getTargetConstant(SHUFPDMask, DL, MVT::i8));
    }

    return DAG.getNode(
        X86ISD::SHUFP, DL, MVT::v2f64,
        Mask[0] == SM_SentinelUndef ? DAG.getUNDEF(MVT::v2f64) : V1,
        Mask[1] == SM_SentinelUndef ? DAG.getUNDEF(MVT::v2f64) : V1,
        DAG.getTargetConstant(SHUFPDMask, DL, MVT::i8));
  }
  assert(Mask[0] >= 0 && "No undef lanes in multi-input v2 shuffles!");
  assert(Mask[1] >= 0 && "No undef lanes in multi-input v2 shuffles!");
  assert(Mask[0] < 2 && "We sort V1 to be the first input.");
  assert(Mask[1] >= 2 && "We sort V2 to be the second input.");

  if (Subtarget.hasAVX2())
    if (SDValue Extract = lowerShuffleOfExtractsAsVperm(DL, V1, V2, Mask, DAG))
      return Extract;

  // When loading a scalar and then shuffling it into a vector we can often do
  // the insertion cheaply.
  if (SDValue Insertion = lowerShuffleAsElementInsertion(
          DL, MVT::v2f64, V1, V2, Mask, Zeroable, Subtarget, DAG))
    return Insertion;
  // Try inverting the insertion since for v2 masks it is easy to do and we
  // can't reliably sort the mask one way or the other.
  int InverseMask[2] = {Mask[0] < 0 ? -1 : (Mask[0] ^ 2),
                        Mask[1] < 0 ? -1 : (Mask[1] ^ 2)};
  if (SDValue Insertion = lowerShuffleAsElementInsertion(
          DL, MVT::v2f64, V2, V1, InverseMask, Zeroable, Subtarget, DAG))
    return Insertion;

  // Try to use one of the special instruction patterns to handle two common
  // blend patterns if a zero-blend above didn't work.
  if (isShuffleEquivalent(V1, V2, Mask, {0, 3}) ||
      isShuffleEquivalent(V1, V2, Mask, {1, 3}))
    if (SDValue V1S = getScalarValueForVectorElement(V1, Mask[0], DAG))
      // We can either use a special instruction to load over the low double or
      // to move just the low double.
      return DAG.getNode(
          X86ISD::MOVSD, DL, MVT::v2f64, V2,
          DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v2f64, V1S));

  if (Subtarget.hasSSE41())
    if (SDValue Blend = lowerShuffleAsBlend(DL, MVT::v2f64, V1, V2, Mask,
                                            Zeroable, Subtarget, DAG))
      return Blend;

  // Use dedicated unpack instructions for masks that match their pattern.
  if (SDValue V = lowerShuffleWithUNPCK(DL, MVT::v2f64, Mask, V1, V2, DAG))
    return V;

  unsigned SHUFPDMask = (Mask[0] == 1) | (((Mask[1] - 2) == 1) << 1);
  return DAG.getNode(X86ISD::SHUFP, DL, MVT::v2f64, V1, V2,
                     DAG.getTargetConstant(SHUFPDMask, DL, MVT::i8));
}

/// Handle lowering of 2-lane 64-bit integer shuffles.
///
/// Tries to lower a 2-lane 64-bit shuffle using shuffle operations provided by
/// the integer unit to minimize domain crossing penalties. However, for blends
/// it falls back to the floating point shuffle operation with appropriate bit
/// casting.
static SDValue lowerV2I64Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
                                 const APInt &Zeroable, SDValue V1, SDValue V2,
                                 const X86Subtarget &Subtarget,
                                 SelectionDAG &DAG) {
  assert(V1.getSimpleValueType() == MVT::v2i64 && "Bad operand type!");
  assert(V2.getSimpleValueType() == MVT::v2i64 && "Bad operand type!");
  assert(Mask.size() == 2 && "Unexpected mask size for v2 shuffle!");

  if (V2.isUndef()) {
    // Check for being able to broadcast a single element.
    if (SDValue Broadcast = lowerShuffleAsBroadcast(DL, MVT::v2i64, V1, V2,
                                                    Mask, Subtarget, DAG))
      return Broadcast;

    // Straight shuffle of a single input vector. For everything from SSE2
    // onward this has a single fast instruction with no scary immediates.
    // We have to map the mask as it is actually a v4i32 shuffle instruction.
    V1 = DAG.getBitcast(MVT::v4i32, V1);
    int WidenedMask[4] = {
        std::max(Mask[0], 0) * 2, std::max(Mask[0], 0) * 2 + 1,
        std::max(Mask[1], 0) * 2, std::max(Mask[1], 0) * 2 + 1};
    return DAG.getBitcast(
        MVT::v2i64,
        DAG.getNode(X86ISD::PSHUFD, DL, MVT::v4i32, V1,
                    getV4X86ShuffleImm8ForMask(WidenedMask, DL, DAG)));
  }
  assert(Mask[0] != -1 && "No undef lanes in multi-input v2 shuffles!");
  assert(Mask[1] != -1 && "No undef lanes in multi-input v2 shuffles!");
  assert(Mask[0] < 2 && "We sort V1 to be the first input.");
  assert(Mask[1] >= 2 && "We sort V2 to be the second input.");

  if (Subtarget.hasAVX2())
    if (SDValue Extract = lowerShuffleOfExtractsAsVperm(DL, V1, V2, Mask, DAG))
      return Extract;

  // Try to use shift instructions.
  if (SDValue Shift = lowerShuffleAsShift(DL, MVT::v2i64, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Shift;

  // When loading a scalar and then shuffling it into a vector we can often do
  // the insertion cheaply.
  if (SDValue Insertion = lowerShuffleAsElementInsertion(
          DL, MVT::v2i64, V1, V2, Mask, Zeroable, Subtarget, DAG))
    return Insertion;
  // Try inverting the insertion since for v2 masks it is easy to do and we
  // can't reliably sort the mask one way or the other.
  int InverseMask[2] = {Mask[0] ^ 2, Mask[1] ^ 2};
  if (SDValue Insertion = lowerShuffleAsElementInsertion(
          DL, MVT::v2i64, V2, V1, InverseMask, Zeroable, Subtarget, DAG))
    return Insertion;

  // We have different paths for blend lowering, but they all must use the
  // *exact* same predicate.
  bool IsBlendSupported = Subtarget.hasSSE41();
  if (IsBlendSupported)
    if (SDValue Blend = lowerShuffleAsBlend(DL, MVT::v2i64, V1, V2, Mask,
                                            Zeroable, Subtarget, DAG))
      return Blend;

  // Use dedicated unpack instructions for masks that match their pattern.
  if (SDValue V = lowerShuffleWithUNPCK(DL, MVT::v2i64, Mask, V1, V2, DAG))
    return V;

  // Try to use byte rotation instructions.
  // Its more profitable for pre-SSSE3 to use shuffles/unpacks.
  if (Subtarget.hasSSSE3()) {
    if (Subtarget.hasVLX())
      if (SDValue Rotate = lowerShuffleAsVALIGN(DL, MVT::v2i64, V1, V2, Mask,
                                                Subtarget, DAG))
        return Rotate;

    if (SDValue Rotate = lowerShuffleAsByteRotate(DL, MVT::v2i64, V1, V2, Mask,
                                                  Subtarget, DAG))
      return Rotate;
  }

  // If we have direct support for blends, we should lower by decomposing into
  // a permute. That will be faster than the domain cross.
  if (IsBlendSupported)
    return lowerShuffleAsDecomposedShuffleBlend(DL, MVT::v2i64, V1, V2, Mask,
                                                Subtarget, DAG);

  // We implement this with SHUFPD which is pretty lame because it will likely
  // incur 2 cycles of stall for integer vectors on Nehalem and older chips.
  // However, all the alternatives are still more cycles and newer chips don't
  // have this problem. It would be really nice if x86 had better shuffles here.
  V1 = DAG.getBitcast(MVT::v2f64, V1);
  V2 = DAG.getBitcast(MVT::v2f64, V2);
  return DAG.getBitcast(MVT::v2i64,
                        DAG.getVectorShuffle(MVT::v2f64, DL, V1, V2, Mask));
}

/// Lower a vector shuffle using the SHUFPS instruction.
///
/// This is a helper routine dedicated to lowering vector shuffles using SHUFPS.
/// It makes no assumptions about whether this is the *best* lowering, it simply
/// uses it.
static SDValue lowerShuffleWithSHUFPS(const SDLoc &DL, MVT VT,
                                      ArrayRef<int> Mask, SDValue V1,
                                      SDValue V2, SelectionDAG &DAG) {
  SDValue LowV = V1, HighV = V2;
  SmallVector<int, 4> NewMask(Mask.begin(), Mask.end());
  int NumV2Elements = count_if(Mask, [](int M) { return M >= 4; });

  if (NumV2Elements == 1) {
    int V2Index = find_if(Mask, [](int M) { return M >= 4; }) - Mask.begin();

    // Compute the index adjacent to V2Index and in the same half by toggling
    // the low bit.
    int V2AdjIndex = V2Index ^ 1;

    if (Mask[V2AdjIndex] < 0) {
      // Handles all the cases where we have a single V2 element and an undef.
      // This will only ever happen in the high lanes because we commute the
      // vector otherwise.
      if (V2Index < 2)
        std::swap(LowV, HighV);
      NewMask[V2Index] -= 4;
    } else {
      // Handle the case where the V2 element ends up adjacent to a V1 element.
      // To make this work, blend them together as the first step.
      int V1Index = V2AdjIndex;
      int BlendMask[4] = {Mask[V2Index] - 4, 0, Mask[V1Index], 0};
      V2 = DAG.getNode(X86ISD::SHUFP, DL, VT, V2, V1,
                       getV4X86ShuffleImm8ForMask(BlendMask, DL, DAG));

      // Now proceed to reconstruct the final blend as we have the necessary
      // high or low half formed.
      if (V2Index < 2) {
        LowV = V2;
        HighV = V1;
      } else {
        HighV = V2;
      }
      NewMask[V1Index] = 2; // We put the V1 element in V2[2].
      NewMask[V2Index] = 0; // We shifted the V2 element into V2[0].
    }
  } else if (NumV2Elements == 2) {
    if (Mask[0] < 4 && Mask[1] < 4) {
      // Handle the easy case where we have V1 in the low lanes and V2 in the
      // high lanes.
      NewMask[2] -= 4;
      NewMask[3] -= 4;
    } else if (Mask[2] < 4 && Mask[3] < 4) {
      // We also handle the reversed case because this utility may get called
      // when we detect a SHUFPS pattern but can't easily commute the shuffle to
      // arrange things in the right direction.
      NewMask[0] -= 4;
      NewMask[1] -= 4;
      HighV = V1;
      LowV = V2;
    } else {
      // We have a mixture of V1 and V2 in both low and high lanes. Rather than
      // trying to place elements directly, just blend them and set up the final
      // shuffle to place them.

      // The first two blend mask elements are for V1, the second two are for
      // V2.
      int BlendMask[4] = {Mask[0] < 4 ? Mask[0] : Mask[1],
                          Mask[2] < 4 ? Mask[2] : Mask[3],
                          (Mask[0] >= 4 ? Mask[0] : Mask[1]) - 4,
                          (Mask[2] >= 4 ? Mask[2] : Mask[3]) - 4};
      V1 = DAG.getNode(X86ISD::SHUFP, DL, VT, V1, V2,
                       getV4X86ShuffleImm8ForMask(BlendMask, DL, DAG));

      // Now we do a normal shuffle of V1 by giving V1 as both operands to
      // a blend.
      LowV = HighV = V1;
      NewMask[0] = Mask[0] < 4 ? 0 : 2;
      NewMask[1] = Mask[0] < 4 ? 2 : 0;
      NewMask[2] = Mask[2] < 4 ? 1 : 3;
      NewMask[3] = Mask[2] < 4 ? 3 : 1;
    }
  }
  return DAG.getNode(X86ISD::SHUFP, DL, VT, LowV, HighV,
                     getV4X86ShuffleImm8ForMask(NewMask, DL, DAG));
}

/// Lower 4-lane 32-bit floating point shuffles.
///
/// Uses instructions exclusively from the floating point unit to minimize
/// domain crossing penalties, as these are sufficient to implement all v4f32
/// shuffles.
static SDValue lowerV4F32Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
                                 const APInt &Zeroable, SDValue V1, SDValue V2,
                                 const X86Subtarget &Subtarget,
                                 SelectionDAG &DAG) {
  assert(V1.getSimpleValueType() == MVT::v4f32 && "Bad operand type!");
  assert(V2.getSimpleValueType() == MVT::v4f32 && "Bad operand type!");
  assert(Mask.size() == 4 && "Unexpected mask size for v4 shuffle!");

  int NumV2Elements = count_if(Mask, [](int M) { return M >= 4; });

  if (NumV2Elements == 0) {
    // Check for being able to broadcast a single element.
    if (SDValue Broadcast = lowerShuffleAsBroadcast(DL, MVT::v4f32, V1, V2,
                                                    Mask, Subtarget, DAG))
      return Broadcast;

    // Use even/odd duplicate instructions for masks that match their pattern.
    if (Subtarget.hasSSE3()) {
      if (isShuffleEquivalent(V1, V2, Mask, {0, 0, 2, 2}))
        return DAG.getNode(X86ISD::MOVSLDUP, DL, MVT::v4f32, V1);
      if (isShuffleEquivalent(V1, V2, Mask, {1, 1, 3, 3}))
        return DAG.getNode(X86ISD::MOVSHDUP, DL, MVT::v4f32, V1);
    }

    if (Subtarget.hasAVX()) {
      // If we have AVX, we can use VPERMILPS which will allow folding a load
      // into the shuffle.
      return DAG.getNode(X86ISD::VPERMILPI, DL, MVT::v4f32, V1,
                         getV4X86ShuffleImm8ForMask(Mask, DL, DAG));
    }

    // Use MOVLHPS/MOVHLPS to simulate unary shuffles. These are only valid
    // in SSE1 because otherwise they are widened to v2f64 and never get here.
    if (!Subtarget.hasSSE2()) {
      if (isShuffleEquivalent(V1, V2, Mask, {0, 1, 0, 1}))
        return DAG.getNode(X86ISD::MOVLHPS, DL, MVT::v4f32, V1, V1);
      if (isShuffleEquivalent(V1, V2, Mask, {2, 3, 2, 3}))
        return DAG.getNode(X86ISD::MOVHLPS, DL, MVT::v4f32, V1, V1);
    }

    // Otherwise, use a straight shuffle of a single input vector. We pass the
    // input vector to both operands to simulate this with a SHUFPS.
    return DAG.getNode(X86ISD::SHUFP, DL, MVT::v4f32, V1, V1,
                       getV4X86ShuffleImm8ForMask(Mask, DL, DAG));
  }

  if (Subtarget.hasAVX2())
    if (SDValue Extract = lowerShuffleOfExtractsAsVperm(DL, V1, V2, Mask, DAG))
      return Extract;

  // There are special ways we can lower some single-element blends. However, we
  // have custom ways we can lower more complex single-element blends below that
  // we defer to if both this and BLENDPS fail to match, so restrict this to
  // when the V2 input is targeting element 0 of the mask -- that is the fast
  // case here.
  if (NumV2Elements == 1 && Mask[0] >= 4)
    if (SDValue V = lowerShuffleAsElementInsertion(
            DL, MVT::v4f32, V1, V2, Mask, Zeroable, Subtarget, DAG))
      return V;

  if (Subtarget.hasSSE41()) {
    if (SDValue Blend = lowerShuffleAsBlend(DL, MVT::v4f32, V1, V2, Mask,
                                            Zeroable, Subtarget, DAG))
      return Blend;

    // Use INSERTPS if we can complete the shuffle efficiently.
    if (SDValue V = lowerShuffleAsInsertPS(DL, V1, V2, Mask, Zeroable, DAG))
      return V;

    if (!isSingleSHUFPSMask(Mask))
      if (SDValue BlendPerm = lowerShuffleAsBlendAndPermute(DL, MVT::v4f32, V1,
                                                            V2, Mask, DAG))
        return BlendPerm;
  }

  // Use low/high mov instructions. These are only valid in SSE1 because
  // otherwise they are widened to v2f64 and never get here.
  if (!Subtarget.hasSSE2()) {
    if (isShuffleEquivalent(V1, V2, Mask, {0, 1, 4, 5}))
      return DAG.getNode(X86ISD::MOVLHPS, DL, MVT::v4f32, V1, V2);
    if (isShuffleEquivalent(V1, V2, Mask, {2, 3, 6, 7}))
      return DAG.getNode(X86ISD::MOVHLPS, DL, MVT::v4f32, V2, V1);
  }

  // Use dedicated unpack instructions for masks that match their pattern.
  if (SDValue V = lowerShuffleWithUNPCK(DL, MVT::v4f32, Mask, V1, V2, DAG))
    return V;

  // Otherwise fall back to a SHUFPS lowering strategy.
  return lowerShuffleWithSHUFPS(DL, MVT::v4f32, Mask, V1, V2, DAG);
}

/// Lower 4-lane i32 vector shuffles.
///
/// We try to handle these with integer-domain shuffles where we can, but for
/// blends we use the floating point domain blend instructions.
static SDValue lowerV4I32Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
                                 const APInt &Zeroable, SDValue V1, SDValue V2,
                                 const X86Subtarget &Subtarget,
                                 SelectionDAG &DAG) {
  assert(V1.getSimpleValueType() == MVT::v4i32 && "Bad operand type!");
  assert(V2.getSimpleValueType() == MVT::v4i32 && "Bad operand type!");
  assert(Mask.size() == 4 && "Unexpected mask size for v4 shuffle!");

  // Whenever we can lower this as a zext, that instruction is strictly faster
  // than any alternative. It also allows us to fold memory operands into the
  // shuffle in many cases.
  if (SDValue ZExt = lowerShuffleAsZeroOrAnyExtend(DL, MVT::v4i32, V1, V2, Mask,
                                                   Zeroable, Subtarget, DAG))
    return ZExt;

  int NumV2Elements = count_if(Mask, [](int M) { return M >= 4; });

  if (NumV2Elements == 0) {
    // Try to use broadcast unless the mask only has one non-undef element.
    if (count_if(Mask, [](int M) { return M >= 0 && M < 4; }) > 1) {
      if (SDValue Broadcast = lowerShuffleAsBroadcast(DL, MVT::v4i32, V1, V2,
                                                      Mask, Subtarget, DAG))
        return Broadcast;
    }

    // Straight shuffle of a single input vector. For everything from SSE2
    // onward this has a single fast instruction with no scary immediates.
    // We coerce the shuffle pattern to be compatible with UNPCK instructions
    // but we aren't actually going to use the UNPCK instruction because doing
    // so prevents folding a load into this instruction or making a copy.
    const int UnpackLoMask[] = {0, 0, 1, 1};
    const int UnpackHiMask[] = {2, 2, 3, 3};
    if (isShuffleEquivalent(V1, V2, Mask, {0, 0, 1, 1}))
      Mask = UnpackLoMask;
    else if (isShuffleEquivalent(V1, V2, Mask, {2, 2, 3, 3}))
      Mask = UnpackHiMask;

    return DAG.getNode(X86ISD::PSHUFD, DL, MVT::v4i32, V1,
                       getV4X86ShuffleImm8ForMask(Mask, DL, DAG));
  }

  if (Subtarget.hasAVX2())
    if (SDValue Extract = lowerShuffleOfExtractsAsVperm(DL, V1, V2, Mask, DAG))
      return Extract;

  // Try to use shift instructions.
  if (SDValue Shift = lowerShuffleAsShift(DL, MVT::v4i32, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Shift;

  // There are special ways we can lower some single-element blends.
  if (NumV2Elements == 1)
    if (SDValue V = lowerShuffleAsElementInsertion(
            DL, MVT::v4i32, V1, V2, Mask, Zeroable, Subtarget, DAG))
      return V;

  // We have different paths for blend lowering, but they all must use the
  // *exact* same predicate.
  bool IsBlendSupported = Subtarget.hasSSE41();
  if (IsBlendSupported)
    if (SDValue Blend = lowerShuffleAsBlend(DL, MVT::v4i32, V1, V2, Mask,
                                            Zeroable, Subtarget, DAG))
      return Blend;

  if (SDValue Masked = lowerShuffleAsBitMask(DL, MVT::v4i32, V1, V2, Mask,
                                             Zeroable, Subtarget, DAG))
    return Masked;

  // Use dedicated unpack instructions for masks that match their pattern.
  if (SDValue V = lowerShuffleWithUNPCK(DL, MVT::v4i32, Mask, V1, V2, DAG))
    return V;

  // Try to use byte rotation instructions.
  // Its more profitable for pre-SSSE3 to use shuffles/unpacks.
  if (Subtarget.hasSSSE3()) {
    if (Subtarget.hasVLX())
      if (SDValue Rotate = lowerShuffleAsVALIGN(DL, MVT::v4i32, V1, V2, Mask,
                                                Subtarget, DAG))
        return Rotate;

    if (SDValue Rotate = lowerShuffleAsByteRotate(DL, MVT::v4i32, V1, V2, Mask,
                                                  Subtarget, DAG))
      return Rotate;
  }

  // Assume that a single SHUFPS is faster than an alternative sequence of
  // multiple instructions (even if the CPU has a domain penalty).
  // If some CPU is harmed by the domain switch, we can fix it in a later pass.
  if (!isSingleSHUFPSMask(Mask)) {
    // If we have direct support for blends, we should lower by decomposing into
    // a permute. That will be faster than the domain cross.
    if (IsBlendSupported)
      return lowerShuffleAsDecomposedShuffleBlend(DL, MVT::v4i32, V1, V2, Mask,
                                                  Subtarget, DAG);

    // Try to lower by permuting the inputs into an unpack instruction.
    if (SDValue Unpack = lowerShuffleAsPermuteAndUnpack(DL, MVT::v4i32, V1, V2,
                                                        Mask, Subtarget, DAG))
      return Unpack;
  }

  // We implement this with SHUFPS because it can blend from two vectors.
  // Because we're going to eventually use SHUFPS, we use SHUFPS even to build
  // up the inputs, bypassing domain shift penalties that we would incur if we
  // directly used PSHUFD on Nehalem and older. For newer chips, this isn't
  // relevant.
  SDValue CastV1 = DAG.getBitcast(MVT::v4f32, V1);
  SDValue CastV2 = DAG.getBitcast(MVT::v4f32, V2);
  SDValue ShufPS = DAG.getVectorShuffle(MVT::v4f32, DL, CastV1, CastV2, Mask);
  return DAG.getBitcast(MVT::v4i32, ShufPS);
}

/// Lowering of single-input v8i16 shuffles is the cornerstone of SSE2
/// shuffle lowering, and the most complex part.
///
/// The lowering strategy is to try to form pairs of input lanes which are
/// targeted at the same half of the final vector, and then use a dword shuffle
/// to place them onto the right half, and finally unpack the paired lanes into
/// their final position.
///
/// The exact breakdown of how to form these dword pairs and align them on the
/// correct sides is really tricky. See the comments within the function for
/// more of the details.
///
/// This code also handles repeated 128-bit lanes of v8i16 shuffles, but each
/// lane must shuffle the *exact* same way. In fact, you must pass a v8 Mask to
/// this routine for it to work correctly. To shuffle a 256-bit or 512-bit i16
/// vector, form the analogous 128-bit 8-element Mask.
static SDValue lowerV8I16GeneralSingleInputShuffle(
    const SDLoc &DL, MVT VT, SDValue V, MutableArrayRef<int> Mask,
    const X86Subtarget &Subtarget, SelectionDAG &DAG) {
  assert(VT.getVectorElementType() == MVT::i16 && "Bad input type!");
  MVT PSHUFDVT = MVT::getVectorVT(MVT::i32, VT.getVectorNumElements() / 2);

  assert(Mask.size() == 8 && "Shuffle mask length doesn't match!");
  MutableArrayRef<int> LoMask = Mask.slice(0, 4);
  MutableArrayRef<int> HiMask = Mask.slice(4, 4);

  // Attempt to directly match PSHUFLW or PSHUFHW.
  if (isUndefOrInRange(LoMask, 0, 4) &&
      isSequentialOrUndefInRange(HiMask, 0, 4, 4)) {
    return DAG.getNode(X86ISD::PSHUFLW, DL, VT, V,
                       getV4X86ShuffleImm8ForMask(LoMask, DL, DAG));
  }
  if (isUndefOrInRange(HiMask, 4, 8) &&
      isSequentialOrUndefInRange(LoMask, 0, 4, 0)) {
    for (int i = 0; i != 4; ++i)
      HiMask[i] = (HiMask[i] < 0 ? HiMask[i] : (HiMask[i] - 4));
    return DAG.getNode(X86ISD::PSHUFHW, DL, VT, V,
                       getV4X86ShuffleImm8ForMask(HiMask, DL, DAG));
  }

  SmallVector<int, 4> LoInputs;
  copy_if(LoMask, std::back_inserter(LoInputs), [](int M) { return M >= 0; });
  array_pod_sort(LoInputs.begin(), LoInputs.end());
  LoInputs.erase(std::unique(LoInputs.begin(), LoInputs.end()), LoInputs.end());
  SmallVector<int, 4> HiInputs;
  copy_if(HiMask, std::back_inserter(HiInputs), [](int M) { return M >= 0; });
  array_pod_sort(HiInputs.begin(), HiInputs.end());
  HiInputs.erase(std::unique(HiInputs.begin(), HiInputs.end()), HiInputs.end());
  int NumLToL = llvm::lower_bound(LoInputs, 4) - LoInputs.begin();
  int NumHToL = LoInputs.size() - NumLToL;
  int NumLToH = llvm::lower_bound(HiInputs, 4) - HiInputs.begin();
  int NumHToH = HiInputs.size() - NumLToH;
  MutableArrayRef<int> LToLInputs(LoInputs.data(), NumLToL);
  MutableArrayRef<int> LToHInputs(HiInputs.data(), NumLToH);
  MutableArrayRef<int> HToLInputs(LoInputs.data() + NumLToL, NumHToL);
  MutableArrayRef<int> HToHInputs(HiInputs.data() + NumLToH, NumHToH);

  // If we are shuffling values from one half - check how many different DWORD
  // pairs we need to create. If only 1 or 2 then we can perform this as a
  // PSHUFLW/PSHUFHW + PSHUFD instead of the PSHUFD+PSHUFLW+PSHUFHW chain below.
  auto ShuffleDWordPairs = [&](ArrayRef<int> PSHUFHalfMask,
                               ArrayRef<int> PSHUFDMask, unsigned ShufWOp) {
    V = DAG.getNode(ShufWOp, DL, VT, V,
                    getV4X86ShuffleImm8ForMask(PSHUFHalfMask, DL, DAG));
    V = DAG.getBitcast(PSHUFDVT, V);
    V = DAG.getNode(X86ISD::PSHUFD, DL, PSHUFDVT, V,
                    getV4X86ShuffleImm8ForMask(PSHUFDMask, DL, DAG));
    return DAG.getBitcast(VT, V);
  };

  if ((NumHToL + NumHToH) == 0 || (NumLToL + NumLToH) == 0) {
    int PSHUFDMask[4] = { -1, -1, -1, -1 };
    SmallVector<std::pair<int, int>, 4> DWordPairs;
    int DOffset = ((NumHToL + NumHToH) == 0 ? 0 : 2);

    // Collect the different DWORD pairs.
    for (int DWord = 0; DWord != 4; ++DWord) {
      int M0 = Mask[2 * DWord + 0];
      int M1 = Mask[2 * DWord + 1];
      M0 = (M0 >= 0 ? M0 % 4 : M0);
      M1 = (M1 >= 0 ? M1 % 4 : M1);
      if (M0 < 0 && M1 < 0)
        continue;

      bool Match = false;
      for (int j = 0, e = DWordPairs.size(); j < e; ++j) {
        auto &DWordPair = DWordPairs[j];
        if ((M0 < 0 || isUndefOrEqual(DWordPair.first, M0)) &&
            (M1 < 0 || isUndefOrEqual(DWordPair.second, M1))) {
          DWordPair.first = (M0 >= 0 ? M0 : DWordPair.first);
          DWordPair.second = (M1 >= 0 ? M1 : DWordPair.second);
          PSHUFDMask[DWord] = DOffset + j;
          Match = true;
          break;
        }
      }
      if (!Match) {
        PSHUFDMask[DWord] = DOffset + DWordPairs.size();
        DWordPairs.push_back(std::make_pair(M0, M1));
      }
    }

    if (DWordPairs.size() <= 2) {
      DWordPairs.resize(2, std::make_pair(-1, -1));
      int PSHUFHalfMask[4] = {DWordPairs[0].first, DWordPairs[0].second,
                              DWordPairs[1].first, DWordPairs[1].second};
      if ((NumHToL + NumHToH) == 0)
        return ShuffleDWordPairs(PSHUFHalfMask, PSHUFDMask, X86ISD::PSHUFLW);
      if ((NumLToL + NumLToH) == 0)
        return ShuffleDWordPairs(PSHUFHalfMask, PSHUFDMask, X86ISD::PSHUFHW);
    }
  }

  // Simplify the 1-into-3 and 3-into-1 cases with a single pshufd. For all
  // such inputs we can swap two of the dwords across the half mark and end up
  // with <=2 inputs to each half in each half. Once there, we can fall through
  // to the generic code below. For example:
  //
  // Input: [a, b, c, d, e, f, g, h] -PSHUFD[0,2,1,3]-> [a, b, e, f, c, d, g, h]
  // Mask:  [0, 1, 2, 7, 4, 5, 6, 3] -----------------> [0, 1, 4, 7, 2, 3, 6, 5]
  //
  // However in some very rare cases we have a 1-into-3 or 3-into-1 on one half
  // and an existing 2-into-2 on the other half. In this case we may have to
  // pre-shuffle the 2-into-2 half to avoid turning it into a 3-into-1 or
  // 1-into-3 which could cause us to cycle endlessly fixing each side in turn.
  // Fortunately, we don't have to handle anything but a 2-into-2 pattern
  // because any other situation (including a 3-into-1 or 1-into-3 in the other
  // half than the one we target for fixing) will be fixed when we re-enter this
  // path. We will also combine away any sequence of PSHUFD instructions that
  // result into a single instruction. Here is an example of the tricky case:
  //
  // Input: [a, b, c, d, e, f, g, h] -PSHUFD[0,2,1,3]-> [a, b, e, f, c, d, g, h]
  // Mask:  [3, 7, 1, 0, 2, 7, 3, 5] -THIS-IS-BAD!!!!-> [5, 7, 1, 0, 4, 7, 5, 3]
  //
  // This now has a 1-into-3 in the high half! Instead, we do two shuffles:
  //
  // Input: [a, b, c, d, e, f, g, h] PSHUFHW[0,2,1,3]-> [a, b, c, d, e, g, f, h]
  // Mask:  [3, 7, 1, 0, 2, 7, 3, 5] -----------------> [3, 7, 1, 0, 2, 7, 3, 6]
  //
  // Input: [a, b, c, d, e, g, f, h] -PSHUFD[0,2,1,3]-> [a, b, e, g, c, d, f, h]
  // Mask:  [3, 7, 1, 0, 2, 7, 3, 6] -----------------> [5, 7, 1, 0, 4, 7, 5, 6]
  //
  // The result is fine to be handled by the generic logic.
  auto balanceSides = [&](ArrayRef<int> AToAInputs, ArrayRef<int> BToAInputs,
                          ArrayRef<int> BToBInputs, ArrayRef<int> AToBInputs,
                          int AOffset, int BOffset) {
    assert((AToAInputs.size() == 3 || AToAInputs.size() == 1) &&
           "Must call this with A having 3 or 1 inputs from the A half.");
    assert((BToAInputs.size() == 1 || BToAInputs.size() == 3) &&
           "Must call this with B having 1 or 3 inputs from the B half.");
    assert(AToAInputs.size() + BToAInputs.size() == 4 &&
           "Must call this with either 3:1 or 1:3 inputs (summing to 4).");

    bool ThreeAInputs = AToAInputs.size() == 3;

    // Compute the index of dword with only one word among the three inputs in
    // a half by taking the sum of the half with three inputs and subtracting
    // the sum of the actual three inputs. The difference is the remaining
    // slot.
    int ADWord = 0, BDWord = 0;
    int &TripleDWord = ThreeAInputs ? ADWord : BDWord;
    int &OneInputDWord = ThreeAInputs ? BDWord : ADWord;
    int TripleInputOffset = ThreeAInputs ? AOffset : BOffset;
    ArrayRef<int> TripleInputs = ThreeAInputs ? AToAInputs : BToAInputs;
    int OneInput = ThreeAInputs ? BToAInputs[0] : AToAInputs[0];
    int TripleInputSum = 0 + 1 + 2 + 3 + (4 * TripleInputOffset);
    int TripleNonInputIdx =
        TripleInputSum - std::accumulate(TripleInputs.begin(), TripleInputs.end(), 0);
    TripleDWord = TripleNonInputIdx / 2;

    // We use xor with one to compute the adjacent DWord to whichever one the
    // OneInput is in.
    OneInputDWord = (OneInput / 2) ^ 1;

    // Check for one tricky case: We're fixing a 3<-1 or a 1<-3 shuffle for AToA
    // and BToA inputs. If there is also such a problem with the BToB and AToB
    // inputs, we don't try to fix it necessarily -- we'll recurse and see it in
    // the next pass. However, if we have a 2<-2 in the BToB and AToB inputs, it
    // is essential that we don't *create* a 3<-1 as then we might oscillate.
    if (BToBInputs.size() == 2 && AToBInputs.size() == 2) {
      // Compute how many inputs will be flipped by swapping these DWords. We
      // need
      // to balance this to ensure we don't form a 3-1 shuffle in the other
      // half.
      int NumFlippedAToBInputs =
          std::count(AToBInputs.begin(), AToBInputs.end(), 2 * ADWord) +
          std::count(AToBInputs.begin(), AToBInputs.end(), 2 * ADWord + 1);
      int NumFlippedBToBInputs =
          std::count(BToBInputs.begin(), BToBInputs.end(), 2 * BDWord) +
          std::count(BToBInputs.begin(), BToBInputs.end(), 2 * BDWord + 1);
      if ((NumFlippedAToBInputs == 1 &&
           (NumFlippedBToBInputs == 0 || NumFlippedBToBInputs == 2)) ||
          (NumFlippedBToBInputs == 1 &&
           (NumFlippedAToBInputs == 0 || NumFlippedAToBInputs == 2))) {
        // We choose whether to fix the A half or B half based on whether that
        // half has zero flipped inputs. At zero, we may not be able to fix it
        // with that half. We also bias towards fixing the B half because that
        // will more commonly be the high half, and we have to bias one way.
        auto FixFlippedInputs = [&V, &DL, &Mask, &DAG](int PinnedIdx, int DWord,
                                                       ArrayRef<int> Inputs) {
          int FixIdx = PinnedIdx ^ 1; // The adjacent slot to the pinned slot.
          bool IsFixIdxInput = is_contained(Inputs, PinnedIdx ^ 1);
          // Determine whether the free index is in the flipped dword or the
          // unflipped dword based on where the pinned index is. We use this bit
          // in an xor to conditionally select the adjacent dword.
          int FixFreeIdx = 2 * (DWord ^ (PinnedIdx / 2 == DWord));
          bool IsFixFreeIdxInput = is_contained(Inputs, FixFreeIdx);
          if (IsFixIdxInput == IsFixFreeIdxInput)
            FixFreeIdx += 1;
          IsFixFreeIdxInput = is_contained(Inputs, FixFreeIdx);
          assert(IsFixIdxInput != IsFixFreeIdxInput &&
                 "We need to be changing the number of flipped inputs!");
          int PSHUFHalfMask[] = {0, 1, 2, 3};
          std::swap(PSHUFHalfMask[FixFreeIdx % 4], PSHUFHalfMask[FixIdx % 4]);
          V = DAG.getNode(
              FixIdx < 4 ? X86ISD::PSHUFLW : X86ISD::PSHUFHW, DL,
              MVT::getVectorVT(MVT::i16, V.getValueSizeInBits() / 16), V,
              getV4X86ShuffleImm8ForMask(PSHUFHalfMask, DL, DAG));

          for (int &M : Mask)
            if (M >= 0 && M == FixIdx)
              M = FixFreeIdx;
            else if (M >= 0 && M == FixFreeIdx)
              M = FixIdx;
        };
        if (NumFlippedBToBInputs != 0) {
          int BPinnedIdx =
              BToAInputs.size() == 3 ? TripleNonInputIdx : OneInput;
          FixFlippedInputs(BPinnedIdx, BDWord, BToBInputs);
        } else {
          assert(NumFlippedAToBInputs != 0 && "Impossible given predicates!");
          int APinnedIdx = ThreeAInputs ? TripleNonInputIdx : OneInput;
          FixFlippedInputs(APinnedIdx, ADWord, AToBInputs);
        }
      }
    }

    int PSHUFDMask[] = {0, 1, 2, 3};
    PSHUFDMask[ADWord] = BDWord;
    PSHUFDMask[BDWord] = ADWord;
    V = DAG.getBitcast(
        VT,
        DAG.getNode(X86ISD::PSHUFD, DL, PSHUFDVT, DAG.getBitcast(PSHUFDVT, V),
                    getV4X86ShuffleImm8ForMask(PSHUFDMask, DL, DAG)));

    // Adjust the mask to match the new locations of A and B.
    for (int &M : Mask)
      if (M >= 0 && M/2 == ADWord)
        M = 2 * BDWord + M % 2;
      else if (M >= 0 && M/2 == BDWord)
        M = 2 * ADWord + M % 2;

    // Recurse back into this routine to re-compute state now that this isn't
    // a 3 and 1 problem.
    return lowerV8I16GeneralSingleInputShuffle(DL, VT, V, Mask, Subtarget, DAG);
  };
  if ((NumLToL == 3 && NumHToL == 1) || (NumLToL == 1 && NumHToL == 3))
    return balanceSides(LToLInputs, HToLInputs, HToHInputs, LToHInputs, 0, 4);
  if ((NumHToH == 3 && NumLToH == 1) || (NumHToH == 1 && NumLToH == 3))
    return balanceSides(HToHInputs, LToHInputs, LToLInputs, HToLInputs, 4, 0);

  // At this point there are at most two inputs to the low and high halves from
  // each half. That means the inputs can always be grouped into dwords and
  // those dwords can then be moved to the correct half with a dword shuffle.
  // We use at most one low and one high word shuffle to collect these paired
  // inputs into dwords, and finally a dword shuffle to place them.
  int PSHUFLMask[4] = {-1, -1, -1, -1};
  int PSHUFHMask[4] = {-1, -1, -1, -1};
  int PSHUFDMask[4] = {-1, -1, -1, -1};

  // First fix the masks for all the inputs that are staying in their
  // original halves. This will then dictate the targets of the cross-half
  // shuffles.
  auto fixInPlaceInputs =
      [&PSHUFDMask](ArrayRef<int> InPlaceInputs, ArrayRef<int> IncomingInputs,
                    MutableArrayRef<int> SourceHalfMask,
                    MutableArrayRef<int> HalfMask, int HalfOffset) {
    if (InPlaceInputs.empty())
      return;
    if (InPlaceInputs.size() == 1) {
      SourceHalfMask[InPlaceInputs[0] - HalfOffset] =
          InPlaceInputs[0] - HalfOffset;
      PSHUFDMask[InPlaceInputs[0] / 2] = InPlaceInputs[0] / 2;
      return;
    }
    if (IncomingInputs.empty()) {
      // Just fix all of the in place inputs.
      for (int Input : InPlaceInputs) {
        SourceHalfMask[Input - HalfOffset] = Input - HalfOffset;
        PSHUFDMask[Input / 2] = Input / 2;
      }
      return;
    }

    assert(InPlaceInputs.size() == 2 && "Cannot handle 3 or 4 inputs!");
    SourceHalfMask[InPlaceInputs[0] - HalfOffset] =
        InPlaceInputs[0] - HalfOffset;
    // Put the second input next to the first so that they are packed into
    // a dword. We find the adjacent index by toggling the low bit.
    int AdjIndex = InPlaceInputs[0] ^ 1;
    SourceHalfMask[AdjIndex - HalfOffset] = InPlaceInputs[1] - HalfOffset;
    std::replace(HalfMask.begin(), HalfMask.end(), InPlaceInputs[1], AdjIndex);
    PSHUFDMask[AdjIndex / 2] = AdjIndex / 2;
  };
  fixInPlaceInputs(LToLInputs, HToLInputs, PSHUFLMask, LoMask, 0);
  fixInPlaceInputs(HToHInputs, LToHInputs, PSHUFHMask, HiMask, 4);

  // Now gather the cross-half inputs and place them into a free dword of
  // their target half.
  // FIXME: This operation could almost certainly be simplified dramatically to
  // look more like the 3-1 fixing operation.
  auto moveInputsToRightHalf = [&PSHUFDMask](
      MutableArrayRef<int> IncomingInputs, ArrayRef<int> ExistingInputs,
      MutableArrayRef<int> SourceHalfMask, MutableArrayRef<int> HalfMask,
      MutableArrayRef<int> FinalSourceHalfMask, int SourceOffset,
      int DestOffset) {
    auto isWordClobbered = [](ArrayRef<int> SourceHalfMask, int Word) {
      return SourceHalfMask[Word] >= 0 && SourceHalfMask[Word] != Word;
    };
    auto isDWordClobbered = [&isWordClobbered](ArrayRef<int> SourceHalfMask,
                                               int Word) {
      int LowWord = Word & ~1;
      int HighWord = Word | 1;
      return isWordClobbered(SourceHalfMask, LowWord) ||
             isWordClobbered(SourceHalfMask, HighWord);
    };

    if (IncomingInputs.empty())
      return;

    if (ExistingInputs.empty()) {
      // Map any dwords with inputs from them into the right half.
      for (int Input : IncomingInputs) {
        // If the source half mask maps over the inputs, turn those into
        // swaps and use the swapped lane.
        if (isWordClobbered(SourceHalfMask, Input - SourceOffset)) {
          if (SourceHalfMask[SourceHalfMask[Input - SourceOffset]] < 0) {
            SourceHalfMask[SourceHalfMask[Input - SourceOffset]] =
                Input - SourceOffset;
            // We have to swap the uses in our half mask in one sweep.
            for (int &M : HalfMask)
              if (M == SourceHalfMask[Input - SourceOffset] + SourceOffset)
                M = Input;
              else if (M == Input)
                M = SourceHalfMask[Input - SourceOffset] + SourceOffset;
          } else {
            assert(SourceHalfMask[SourceHalfMask[Input - SourceOffset]] ==
                       Input - SourceOffset &&
                   "Previous placement doesn't match!");
          }
          // Note that this correctly re-maps both when we do a swap and when
          // we observe the other side of the swap above. We rely on that to
          // avoid swapping the members of the input list directly.
          Input = SourceHalfMask[Input - SourceOffset] + SourceOffset;
        }

        // Map the input's dword into the correct half.
        if (PSHUFDMask[(Input - SourceOffset + DestOffset) / 2] < 0)
          PSHUFDMask[(Input - SourceOffset + DestOffset) / 2] = Input / 2;
        else
          assert(PSHUFDMask[(Input - SourceOffset + DestOffset) / 2] ==
                     Input / 2 &&
                 "Previous placement doesn't match!");
      }

      // And just directly shift any other-half mask elements to be same-half
      // as we will have mirrored the dword containing the element into the
      // same position within that half.
      for (int &M : HalfMask)
        if (M >= SourceOffset && M < SourceOffset + 4) {
          M = M - SourceOffset + DestOffset;
          assert(M >= 0 && "This should never wrap below zero!");
        }
      return;
    }

    // Ensure we have the input in a viable dword of its current half. This
    // is particularly tricky because the original position may be clobbered
    // by inputs being moved and *staying* in that half.
    if (IncomingInputs.size() == 1) {
      if (isWordClobbered(SourceHalfMask, IncomingInputs[0] - SourceOffset)) {
        int InputFixed = find(SourceHalfMask, -1) - std::begin(SourceHalfMask) +
                         SourceOffset;
        SourceHalfMask[InputFixed - SourceOffset] =
            IncomingInputs[0] - SourceOffset;
        std::replace(HalfMask.begin(), HalfMask.end(), IncomingInputs[0],
                     InputFixed);
        IncomingInputs[0] = InputFixed;
      }
    } else if (IncomingInputs.size() == 2) {
      if (IncomingInputs[0] / 2 != IncomingInputs[1] / 2 ||
          isDWordClobbered(SourceHalfMask, IncomingInputs[0] - SourceOffset)) {
        // We have two non-adjacent or clobbered inputs we need to extract from
        // the source half. To do this, we need to map them into some adjacent
        // dword slot in the source mask.
        int InputsFixed[2] = {IncomingInputs[0] - SourceOffset,
                              IncomingInputs[1] - SourceOffset};

        // If there is a free slot in the source half mask adjacent to one of
        // the inputs, place the other input in it. We use (Index XOR 1) to
        // compute an adjacent index.
        if (!isWordClobbered(SourceHalfMask, InputsFixed[0]) &&
            SourceHalfMask[InputsFixed[0] ^ 1] < 0) {
          SourceHalfMask[InputsFixed[0]] = InputsFixed[0];
          SourceHalfMask[InputsFixed[0] ^ 1] = InputsFixed[1];
          InputsFixed[1] = InputsFixed[0] ^ 1;
        } else if (!isWordClobbered(SourceHalfMask, InputsFixed[1]) &&
                   SourceHalfMask[InputsFixed[1] ^ 1] < 0) {
          SourceHalfMask[InputsFixed[1]] = InputsFixed[1];
          SourceHalfMask[InputsFixed[1] ^ 1] = InputsFixed[0];
          InputsFixed[0] = InputsFixed[1] ^ 1;
        } else if (SourceHalfMask[2 * ((InputsFixed[0] / 2) ^ 1)] < 0 &&
                   SourceHalfMask[2 * ((InputsFixed[0] / 2) ^ 1) + 1] < 0) {
          // The two inputs are in the same DWord but it is clobbered and the
          // adjacent DWord isn't used at all. Move both inputs to the free
          // slot.
          SourceHalfMask[2 * ((InputsFixed[0] / 2) ^ 1)] = InputsFixed[0];
          SourceHalfMask[2 * ((InputsFixed[0] / 2) ^ 1) + 1] = InputsFixed[1];
          InputsFixed[0] = 2 * ((InputsFixed[0] / 2) ^ 1);
          InputsFixed[1] = 2 * ((InputsFixed[0] / 2) ^ 1) + 1;
        } else {
          // The only way we hit this point is if there is no clobbering
          // (because there are no off-half inputs to this half) and there is no
          // free slot adjacent to one of the inputs. In this case, we have to
          // swap an input with a non-input.
          for (int i = 0; i < 4; ++i)
            assert((SourceHalfMask[i] < 0 || SourceHalfMask[i] == i) &&
                   "We can't handle any clobbers here!");
          assert(InputsFixed[1] != (InputsFixed[0] ^ 1) &&
                 "Cannot have adjacent inputs here!");

          SourceHalfMask[InputsFixed[0] ^ 1] = InputsFixed[1];
          SourceHalfMask[InputsFixed[1]] = InputsFixed[0] ^ 1;

          // We also have to update the final source mask in this case because
          // it may need to undo the above swap.
          for (int &M : FinalSourceHalfMask)
            if (M == (InputsFixed[0] ^ 1) + SourceOffset)
              M = InputsFixed[1] + SourceOffset;
            else if (M == InputsFixed[1] + SourceOffset)
              M = (InputsFixed[0] ^ 1) + SourceOffset;

          InputsFixed[1] = InputsFixed[0] ^ 1;
        }

        // Point everything at the fixed inputs.
        for (int &M : HalfMask)
          if (M == IncomingInputs[0])
            M = InputsFixed[0] + SourceOffset;
          else if (M == IncomingInputs[1])
            M = InputsFixed[1] + SourceOffset;

        IncomingInputs[0] = InputsFixed[0] + SourceOffset;
        IncomingInputs[1] = InputsFixed[1] + SourceOffset;
      }
    } else {
      llvm_unreachable("Unhandled input size!");
    }

    // Now hoist the DWord down to the right half.
    int FreeDWord = (PSHUFDMask[DestOffset / 2] < 0 ? 0 : 1) + DestOffset / 2;
    assert(PSHUFDMask[FreeDWord] < 0 && "DWord not free");
    PSHUFDMask[FreeDWord] = IncomingInputs[0] / 2;
    for (int &M : HalfMask)
      for (int Input : IncomingInputs)
        if (M == Input)
          M = FreeDWord * 2 + Input % 2;
  };
  moveInputsToRightHalf(HToLInputs, LToLInputs, PSHUFHMask, LoMask, HiMask,
                        /*SourceOffset*/ 4, /*DestOffset*/ 0);
  moveInputsToRightHalf(LToHInputs, HToHInputs, PSHUFLMask, HiMask, LoMask,
                        /*SourceOffset*/ 0, /*DestOffset*/ 4);

  // Now enact all the shuffles we've computed to move the inputs into their
  // target half.
  if (!isNoopShuffleMask(PSHUFLMask))
    V = DAG.getNode(X86ISD::PSHUFLW, DL, VT, V,
                    getV4X86ShuffleImm8ForMask(PSHUFLMask, DL, DAG));
  if (!isNoopShuffleMask(PSHUFHMask))
    V = DAG.getNode(X86ISD::PSHUFHW, DL, VT, V,
                    getV4X86ShuffleImm8ForMask(PSHUFHMask, DL, DAG));
  if (!isNoopShuffleMask(PSHUFDMask))
    V = DAG.getBitcast(
        VT,
        DAG.getNode(X86ISD::PSHUFD, DL, PSHUFDVT, DAG.getBitcast(PSHUFDVT, V),
                    getV4X86ShuffleImm8ForMask(PSHUFDMask, DL, DAG)));

  // At this point, each half should contain all its inputs, and we can then
  // just shuffle them into their final position.
  assert(count_if(LoMask, [](int M) { return M >= 4; }) == 0 &&
         "Failed to lift all the high half inputs to the low mask!");
  assert(count_if(HiMask, [](int M) { return M >= 0 && M < 4; }) == 0 &&
         "Failed to lift all the low half inputs to the high mask!");

  // Do a half shuffle for the low mask.
  if (!isNoopShuffleMask(LoMask))
    V = DAG.getNode(X86ISD::PSHUFLW, DL, VT, V,
                    getV4X86ShuffleImm8ForMask(LoMask, DL, DAG));

  // Do a half shuffle with the high mask after shifting its values down.
  for (int &M : HiMask)
    if (M >= 0)
      M -= 4;
  if (!isNoopShuffleMask(HiMask))
    V = DAG.getNode(X86ISD::PSHUFHW, DL, VT, V,
                    getV4X86ShuffleImm8ForMask(HiMask, DL, DAG));

  return V;
}

/// Helper to form a PSHUFB-based shuffle+blend, opportunistically avoiding the
/// blend if only one input is used.
static SDValue lowerShuffleAsBlendOfPSHUFBs(
    const SDLoc &DL, MVT VT, SDValue V1, SDValue V2, ArrayRef<int> Mask,
    const APInt &Zeroable, SelectionDAG &DAG, bool &V1InUse, bool &V2InUse) {
  assert(!is128BitLaneCrossingShuffleMask(VT, Mask) &&
         "Lane crossing shuffle masks not supported");

  int NumBytes = VT.getSizeInBits() / 8;
  int Size = Mask.size();
  int Scale = NumBytes / Size;

  SmallVector<SDValue, 64> V1Mask(NumBytes, DAG.getUNDEF(MVT::i8));
  SmallVector<SDValue, 64> V2Mask(NumBytes, DAG.getUNDEF(MVT::i8));
  V1InUse = false;
  V2InUse = false;

  for (int i = 0; i < NumBytes; ++i) {
    int M = Mask[i / Scale];
    if (M < 0)
      continue;

    const int ZeroMask = 0x80;
    int V1Idx = M < Size ? M * Scale + i % Scale : ZeroMask;
    int V2Idx = M < Size ? ZeroMask : (M - Size) * Scale + i % Scale;
    if (Zeroable[i / Scale])
      V1Idx = V2Idx = ZeroMask;

    V1Mask[i] = DAG.getConstant(V1Idx, DL, MVT::i8);
    V2Mask[i] = DAG.getConstant(V2Idx, DL, MVT::i8);
    V1InUse |= (ZeroMask != V1Idx);
    V2InUse |= (ZeroMask != V2Idx);
  }

  MVT ShufVT = MVT::getVectorVT(MVT::i8, NumBytes);
  if (V1InUse)
    V1 = DAG.getNode(X86ISD::PSHUFB, DL, ShufVT, DAG.getBitcast(ShufVT, V1),
                     DAG.getBuildVector(ShufVT, DL, V1Mask));
  if (V2InUse)
    V2 = DAG.getNode(X86ISD::PSHUFB, DL, ShufVT, DAG.getBitcast(ShufVT, V2),
                     DAG.getBuildVector(ShufVT, DL, V2Mask));

  // If we need shuffled inputs from both, blend the two.
  SDValue V;
  if (V1InUse && V2InUse)
    V = DAG.getNode(ISD::OR, DL, ShufVT, V1, V2);
  else
    V = V1InUse ? V1 : V2;

  // Cast the result back to the correct type.
  return DAG.getBitcast(VT, V);
}

/// Generic lowering of 8-lane i16 shuffles.
///
/// This handles both single-input shuffles and combined shuffle/blends with
/// two inputs. The single input shuffles are immediately delegated to
/// a dedicated lowering routine.
///
/// The blends are lowered in one of three fundamental ways. If there are few
/// enough inputs, it delegates to a basic UNPCK-based strategy. If the shuffle
/// of the input is significantly cheaper when lowered as an interleaving of
/// the two inputs, try to interleave them. Otherwise, blend the low and high
/// halves of the inputs separately (making them have relatively few inputs)
/// and then concatenate them.
static SDValue lowerV8I16Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
                                 const APInt &Zeroable, SDValue V1, SDValue V2,
                                 const X86Subtarget &Subtarget,
                                 SelectionDAG &DAG) {
  assert(V1.getSimpleValueType() == MVT::v8i16 && "Bad operand type!");
  assert(V2.getSimpleValueType() == MVT::v8i16 && "Bad operand type!");
  assert(Mask.size() == 8 && "Unexpected mask size for v8 shuffle!");

  // Whenever we can lower this as a zext, that instruction is strictly faster
  // than any alternative.
  if (SDValue ZExt = lowerShuffleAsZeroOrAnyExtend(DL, MVT::v8i16, V1, V2, Mask,
                                                   Zeroable, Subtarget, DAG))
    return ZExt;

  int NumV2Inputs = count_if(Mask, [](int M) { return M >= 8; });

  if (NumV2Inputs == 0) {
    // Try to use shift instructions.
    if (SDValue Shift = lowerShuffleAsShift(DL, MVT::v8i16, V1, V1, Mask,
                                            Zeroable, Subtarget, DAG))
      return Shift;

    // Check for being able to broadcast a single element.
    if (SDValue Broadcast = lowerShuffleAsBroadcast(DL, MVT::v8i16, V1, V2,
                                                    Mask, Subtarget, DAG))
      return Broadcast;

    // Try to use bit rotation instructions.
    if (SDValue Rotate = lowerShuffleAsBitRotate(DL, MVT::v8i16, V1, Mask,
                                                 Subtarget, DAG))
      return Rotate;

    // Use dedicated unpack instructions for masks that match their pattern.
    if (SDValue V = lowerShuffleWithUNPCK(DL, MVT::v8i16, Mask, V1, V2, DAG))
      return V;

    // Use dedicated pack instructions for masks that match their pattern.
    if (SDValue V = lowerShuffleWithPACK(DL, MVT::v8i16, Mask, V1, V2, DAG,
                                         Subtarget))
      return V;

    // Try to use byte rotation instructions.
    if (SDValue Rotate = lowerShuffleAsByteRotate(DL, MVT::v8i16, V1, V1, Mask,
                                                  Subtarget, DAG))
      return Rotate;

    // Make a copy of the mask so it can be modified.
    SmallVector<int, 8> MutableMask(Mask.begin(), Mask.end());
    return lowerV8I16GeneralSingleInputShuffle(DL, MVT::v8i16, V1, MutableMask,
                                               Subtarget, DAG);
  }

  assert(llvm::any_of(Mask, [](int M) { return M >= 0 && M < 8; }) &&
         "All single-input shuffles should be canonicalized to be V1-input "
         "shuffles.");

  // Try to use shift instructions.
  if (SDValue Shift = lowerShuffleAsShift(DL, MVT::v8i16, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Shift;

  // See if we can use SSE4A Extraction / Insertion.
  if (Subtarget.hasSSE4A())
    if (SDValue V = lowerShuffleWithSSE4A(DL, MVT::v8i16, V1, V2, Mask,
                                          Zeroable, DAG))
      return V;

  // There are special ways we can lower some single-element blends.
  if (NumV2Inputs == 1)
    if (SDValue V = lowerShuffleAsElementInsertion(
            DL, MVT::v8i16, V1, V2, Mask, Zeroable, Subtarget, DAG))
      return V;

  // We have different paths for blend lowering, but they all must use the
  // *exact* same predicate.
  bool IsBlendSupported = Subtarget.hasSSE41();
  if (IsBlendSupported)
    if (SDValue Blend = lowerShuffleAsBlend(DL, MVT::v8i16, V1, V2, Mask,
                                            Zeroable, Subtarget, DAG))
      return Blend;

  if (SDValue Masked = lowerShuffleAsBitMask(DL, MVT::v8i16, V1, V2, Mask,
                                             Zeroable, Subtarget, DAG))
    return Masked;

  // Use dedicated unpack instructions for masks that match their pattern.
  if (SDValue V = lowerShuffleWithUNPCK(DL, MVT::v8i16, Mask, V1, V2, DAG))
    return V;

  // Use dedicated pack instructions for masks that match their pattern.
  if (SDValue V = lowerShuffleWithPACK(DL, MVT::v8i16, Mask, V1, V2, DAG,
                                       Subtarget))
    return V;

  // Try to use byte rotation instructions.
  if (SDValue Rotate = lowerShuffleAsByteRotate(DL, MVT::v8i16, V1, V2, Mask,
                                                Subtarget, DAG))
    return Rotate;

  if (SDValue BitBlend =
          lowerShuffleAsBitBlend(DL, MVT::v8i16, V1, V2, Mask, DAG))
    return BitBlend;

  // Try to use byte shift instructions to mask.
  if (SDValue V = lowerShuffleAsByteShiftMask(DL, MVT::v8i16, V1, V2, Mask,
                                              Zeroable, Subtarget, DAG))
    return V;

  // Try to lower by permuting the inputs into an unpack instruction.
  if (SDValue Unpack = lowerShuffleAsPermuteAndUnpack(DL, MVT::v8i16, V1, V2,
                                                      Mask, Subtarget, DAG))
    return Unpack;

  // If we can't directly blend but can use PSHUFB, that will be better as it
  // can both shuffle and set up the inefficient blend.
  if (!IsBlendSupported && Subtarget.hasSSSE3()) {
    bool V1InUse, V2InUse;
    return lowerShuffleAsBlendOfPSHUFBs(DL, MVT::v8i16, V1, V2, Mask,
                                        Zeroable, DAG, V1InUse, V2InUse);
  }

  // We can always bit-blend if we have to so the fallback strategy is to
  // decompose into single-input permutes and blends.
  return lowerShuffleAsDecomposedShuffleBlend(DL, MVT::v8i16, V1, V2,
                                              Mask, Subtarget, DAG);
}

static SDValue lowerShuffleWithPERMV(const SDLoc &DL, MVT VT,
                                     ArrayRef<int> Mask, SDValue V1,
                                     SDValue V2, SelectionDAG &DAG) {
  MVT MaskEltVT = MVT::getIntegerVT(VT.getScalarSizeInBits());
  MVT MaskVecVT = MVT::getVectorVT(MaskEltVT, VT.getVectorNumElements());

  SDValue MaskNode = getConstVector(Mask, MaskVecVT, DAG, DL, true);
  if (V2.isUndef())
    return DAG.getNode(X86ISD::VPERMV, DL, VT, MaskNode, V1);

  return DAG.getNode(X86ISD::VPERMV3, DL, VT, V1, MaskNode, V2);
}

/// Generic lowering of v16i8 shuffles.
///
/// This is a hybrid strategy to lower v16i8 vectors. It first attempts to
/// detect any complexity reducing interleaving. If that doesn't help, it uses
/// UNPCK to spread the i8 elements across two i16-element vectors, and uses
/// the existing lowering for v8i16 blends on each half, finally PACK-ing them
/// back together.
static SDValue lowerV16I8Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
                                 const APInt &Zeroable, SDValue V1, SDValue V2,
                                 const X86Subtarget &Subtarget,
                                 SelectionDAG &DAG) {
  assert(V1.getSimpleValueType() == MVT::v16i8 && "Bad operand type!");
  assert(V2.getSimpleValueType() == MVT::v16i8 && "Bad operand type!");
  assert(Mask.size() == 16 && "Unexpected mask size for v16 shuffle!");

  // Try to use shift instructions.
  if (SDValue Shift = lowerShuffleAsShift(DL, MVT::v16i8, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Shift;

  // Try to use byte rotation instructions.
  if (SDValue Rotate = lowerShuffleAsByteRotate(DL, MVT::v16i8, V1, V2, Mask,
                                                Subtarget, DAG))
    return Rotate;

  // Use dedicated pack instructions for masks that match their pattern.
  if (SDValue V = lowerShuffleWithPACK(DL, MVT::v16i8, Mask, V1, V2, DAG,
                                       Subtarget))
    return V;

  // Try to use a zext lowering.
  if (SDValue ZExt = lowerShuffleAsZeroOrAnyExtend(DL, MVT::v16i8, V1, V2, Mask,
                                                   Zeroable, Subtarget, DAG))
    return ZExt;

  // See if we can use SSE4A Extraction / Insertion.
  if (Subtarget.hasSSE4A())
    if (SDValue V = lowerShuffleWithSSE4A(DL, MVT::v16i8, V1, V2, Mask,
                                          Zeroable, DAG))
      return V;

  int NumV2Elements = count_if(Mask, [](int M) { return M >= 16; });

  // For single-input shuffles, there are some nicer lowering tricks we can use.
  if (NumV2Elements == 0) {
    // Check for being able to broadcast a single element.
    if (SDValue Broadcast = lowerShuffleAsBroadcast(DL, MVT::v16i8, V1, V2,
                                                    Mask, Subtarget, DAG))
      return Broadcast;

    // Try to use bit rotation instructions.
    if (SDValue Rotate = lowerShuffleAsBitRotate(DL, MVT::v16i8, V1, Mask,
                                                 Subtarget, DAG))
      return Rotate;

    if (SDValue V = lowerShuffleWithUNPCK(DL, MVT::v16i8, Mask, V1, V2, DAG))
      return V;

    // Check whether we can widen this to an i16 shuffle by duplicating bytes.
    // Notably, this handles splat and partial-splat shuffles more efficiently.
    // However, it only makes sense if the pre-duplication shuffle simplifies
    // things significantly. Currently, this means we need to be able to
    // express the pre-duplication shuffle as an i16 shuffle.
    //
    // FIXME: We should check for other patterns which can be widened into an
    // i16 shuffle as well.
    auto canWidenViaDuplication = [](ArrayRef<int> Mask) {
      for (int i = 0; i < 16; i += 2)
        if (Mask[i] >= 0 && Mask[i + 1] >= 0 && Mask[i] != Mask[i + 1])
          return false;

      return true;
    };
    auto tryToWidenViaDuplication = [&]() -> SDValue {
      if (!canWidenViaDuplication(Mask))
        return SDValue();
      SmallVector<int, 4> LoInputs;
      copy_if(Mask, std::back_inserter(LoInputs),
              [](int M) { return M >= 0 && M < 8; });
      array_pod_sort(LoInputs.begin(), LoInputs.end());
      LoInputs.erase(std::unique(LoInputs.begin(), LoInputs.end()),
                     LoInputs.end());
      SmallVector<int, 4> HiInputs;
      copy_if(Mask, std::back_inserter(HiInputs), [](int M) { return M >= 8; });
      array_pod_sort(HiInputs.begin(), HiInputs.end());
      HiInputs.erase(std::unique(HiInputs.begin(), HiInputs.end()),
                     HiInputs.end());

      bool TargetLo = LoInputs.size() >= HiInputs.size();
      ArrayRef<int> InPlaceInputs = TargetLo ? LoInputs : HiInputs;
      ArrayRef<int> MovingInputs = TargetLo ? HiInputs : LoInputs;

      int PreDupI16Shuffle[] = {-1, -1, -1, -1, -1, -1, -1, -1};
      SmallDenseMap<int, int, 8> LaneMap;
      for (int I : InPlaceInputs) {
        PreDupI16Shuffle[I/2] = I/2;
        LaneMap[I] = I;
      }
      int j = TargetLo ? 0 : 4, je = j + 4;
      for (int i = 0, ie = MovingInputs.size(); i < ie; ++i) {
        // Check if j is already a shuffle of this input. This happens when
        // there are two adjacent bytes after we move the low one.
        if (PreDupI16Shuffle[j] != MovingInputs[i] / 2) {
          // If we haven't yet mapped the input, search for a slot into which
          // we can map it.
          while (j < je && PreDupI16Shuffle[j] >= 0)
            ++j;

          if (j == je)
            // We can't place the inputs into a single half with a simple i16 shuffle, so bail.
            return SDValue();

          // Map this input with the i16 shuffle.
          PreDupI16Shuffle[j] = MovingInputs[i] / 2;
        }

        // Update the lane map based on the mapping we ended up with.
        LaneMap[MovingInputs[i]] = 2 * j + MovingInputs[i] % 2;
      }
      V1 = DAG.getBitcast(
          MVT::v16i8,
          DAG.getVectorShuffle(MVT::v8i16, DL, DAG.getBitcast(MVT::v8i16, V1),
                               DAG.getUNDEF(MVT::v8i16), PreDupI16Shuffle));

      // Unpack the bytes to form the i16s that will be shuffled into place.
      bool EvenInUse = false, OddInUse = false;
      for (int i = 0; i < 16; i += 2) {
        EvenInUse |= (Mask[i + 0] >= 0);
        OddInUse |= (Mask[i + 1] >= 0);
        if (EvenInUse && OddInUse)
          break;
      }
      V1 = DAG.getNode(TargetLo ? X86ISD::UNPCKL : X86ISD::UNPCKH, DL,
                       MVT::v16i8, EvenInUse ? V1 : DAG.getUNDEF(MVT::v16i8),
                       OddInUse ? V1 : DAG.getUNDEF(MVT::v16i8));

      int PostDupI16Shuffle[8] = {-1, -1, -1, -1, -1, -1, -1, -1};
      for (int i = 0; i < 16; ++i)
        if (Mask[i] >= 0) {
          int MappedMask = LaneMap[Mask[i]] - (TargetLo ? 0 : 8);
          assert(MappedMask < 8 && "Invalid v8 shuffle mask!");
          if (PostDupI16Shuffle[i / 2] < 0)
            PostDupI16Shuffle[i / 2] = MappedMask;
          else
            assert(PostDupI16Shuffle[i / 2] == MappedMask &&
                   "Conflicting entries in the original shuffle!");
        }
      return DAG.getBitcast(
          MVT::v16i8,
          DAG.getVectorShuffle(MVT::v8i16, DL, DAG.getBitcast(MVT::v8i16, V1),
                               DAG.getUNDEF(MVT::v8i16), PostDupI16Shuffle));
    };
    if (SDValue V = tryToWidenViaDuplication())
      return V;
  }

  if (SDValue Masked = lowerShuffleAsBitMask(DL, MVT::v16i8, V1, V2, Mask,
                                             Zeroable, Subtarget, DAG))
    return Masked;

  // Use dedicated unpack instructions for masks that match their pattern.
  if (SDValue V = lowerShuffleWithUNPCK(DL, MVT::v16i8, Mask, V1, V2, DAG))
    return V;

  // Try to use byte shift instructions to mask.
  if (SDValue V = lowerShuffleAsByteShiftMask(DL, MVT::v16i8, V1, V2, Mask,
                                              Zeroable, Subtarget, DAG))
    return V;

  // Check for compaction patterns.
  bool IsSingleInput = V2.isUndef();
  int NumEvenDrops = canLowerByDroppingEvenElements(Mask, IsSingleInput);

  // Check for SSSE3 which lets us lower all v16i8 shuffles much more directly
  // with PSHUFB. It is important to do this before we attempt to generate any
  // blends but after all of the single-input lowerings. If the single input
  // lowerings can find an instruction sequence that is faster than a PSHUFB, we
  // want to preserve that and we can DAG combine any longer sequences into
  // a PSHUFB in the end. But once we start blending from multiple inputs,
  // the complexity of DAG combining bad patterns back into PSHUFB is too high,
  // and there are *very* few patterns that would actually be faster than the
  // PSHUFB approach because of its ability to zero lanes.
  //
  // If the mask is a binary compaction, we can more efficiently perform this
  // as a PACKUS(AND(),AND()) - which is quicker than UNPACK(PSHUFB(),PSHUFB()).
  //
  // FIXME: The only exceptions to the above are blends which are exact
  // interleavings with direct instructions supporting them. We currently don't
  // handle those well here.
  if (Subtarget.hasSSSE3() && (IsSingleInput || NumEvenDrops != 1)) {
    bool V1InUse = false;
    bool V2InUse = false;

    SDValue PSHUFB = lowerShuffleAsBlendOfPSHUFBs(
        DL, MVT::v16i8, V1, V2, Mask, Zeroable, DAG, V1InUse, V2InUse);

    // If both V1 and V2 are in use and we can use a direct blend or an unpack,
    // do so. This avoids using them to handle blends-with-zero which is
    // important as a single pshufb is significantly faster for that.
    if (V1InUse && V2InUse) {
      if (Subtarget.hasSSE41())
        if (SDValue Blend = lowerShuffleAsBlend(DL, MVT::v16i8, V1, V2, Mask,
                                                Zeroable, Subtarget, DAG))
          return Blend;

      // We can use an unpack to do the blending rather than an or in some
      // cases. Even though the or may be (very minorly) more efficient, we
      // preference this lowering because there are common cases where part of
      // the complexity of the shuffles goes away when we do the final blend as
      // an unpack.
      // FIXME: It might be worth trying to detect if the unpack-feeding
      // shuffles will both be pshufb, in which case we shouldn't bother with
      // this.
      if (SDValue Unpack = lowerShuffleAsPermuteAndUnpack(
              DL, MVT::v16i8, V1, V2, Mask, Subtarget, DAG))
        return Unpack;

      // If we have VBMI we can use one VPERM instead of multiple PSHUFBs.
      if (Subtarget.hasVBMI() && Subtarget.hasVLX())
        return lowerShuffleWithPERMV(DL, MVT::v16i8, Mask, V1, V2, DAG);

      // Use PALIGNR+Permute if possible - permute might become PSHUFB but the
      // PALIGNR will be cheaper than the second PSHUFB+OR.
      if (SDValue V = lowerShuffleAsByteRotateAndPermute(
              DL, MVT::v16i8, V1, V2, Mask, Subtarget, DAG))
        return V;
    }

    return PSHUFB;
  }

  // There are special ways we can lower some single-element blends.
  if (NumV2Elements == 1)
    if (SDValue V = lowerShuffleAsElementInsertion(
            DL, MVT::v16i8, V1, V2, Mask, Zeroable, Subtarget, DAG))
      return V;

  if (SDValue Blend = lowerShuffleAsBitBlend(DL, MVT::v16i8, V1, V2, Mask, DAG))
    return Blend;

  // Check whether a compaction lowering can be done. This handles shuffles
  // which take every Nth element for some even N. See the helper function for
  // details.
  //
  // We special case these as they can be particularly efficiently handled with
  // the PACKUSB instruction on x86 and they show up in common patterns of
  // rearranging bytes to truncate wide elements.
  if (NumEvenDrops) {
    // NumEvenDrops is the power of two stride of the elements. Another way of
    // thinking about it is that we need to drop the even elements this many
    // times to get the original input.

    // First we need to zero all the dropped bytes.
    assert(NumEvenDrops <= 3 &&
           "No support for dropping even elements more than 3 times.");
    SmallVector<SDValue, 8> WordClearOps(8, DAG.getConstant(0, DL, MVT::i16));
    for (unsigned i = 0; i != 8; i += 1 << (NumEvenDrops - 1))
      WordClearOps[i] = DAG.getConstant(0xFF, DL, MVT::i16);
    SDValue WordClearMask = DAG.getBuildVector(MVT::v8i16, DL, WordClearOps);
    V1 = DAG.getNode(ISD::AND, DL, MVT::v8i16, DAG.getBitcast(MVT::v8i16, V1),
                     WordClearMask);
    if (!IsSingleInput)
      V2 = DAG.getNode(ISD::AND, DL, MVT::v8i16, DAG.getBitcast(MVT::v8i16, V2),
                       WordClearMask);

    // Now pack things back together.
    SDValue Result = DAG.getNode(X86ISD::PACKUS, DL, MVT::v16i8, V1,
                                 IsSingleInput ? V1 : V2);
    for (int i = 1; i < NumEvenDrops; ++i) {
      Result = DAG.getBitcast(MVT::v8i16, Result);
      Result = DAG.getNode(X86ISD::PACKUS, DL, MVT::v16i8, Result, Result);
    }
    return Result;
  }

  // Handle multi-input cases by blending single-input shuffles.
  if (NumV2Elements > 0)
    return lowerShuffleAsDecomposedShuffleBlend(DL, MVT::v16i8, V1, V2, Mask,
                                                Subtarget, DAG);

  // The fallback path for single-input shuffles widens this into two v8i16
  // vectors with unpacks, shuffles those, and then pulls them back together
  // with a pack.
  SDValue V = V1;

  std::array<int, 8> LoBlendMask = {{-1, -1, -1, -1, -1, -1, -1, -1}};
  std::array<int, 8> HiBlendMask = {{-1, -1, -1, -1, -1, -1, -1, -1}};
  for (int i = 0; i < 16; ++i)
    if (Mask[i] >= 0)
      (i < 8 ? LoBlendMask[i] : HiBlendMask[i % 8]) = Mask[i];

  SDValue VLoHalf, VHiHalf;
  // Check if any of the odd lanes in the v16i8 are used. If not, we can mask
  // them out and avoid using UNPCK{L,H} to extract the elements of V as
  // i16s.
  if (none_of(LoBlendMask, [](int M) { return M >= 0 && M % 2 == 1; }) &&
      none_of(HiBlendMask, [](int M) { return M >= 0 && M % 2 == 1; })) {
    // Use a mask to drop the high bytes.
    VLoHalf = DAG.getBitcast(MVT::v8i16, V);
    VLoHalf = DAG.getNode(ISD::AND, DL, MVT::v8i16, VLoHalf,
                          DAG.getConstant(0x00FF, DL, MVT::v8i16));

    // This will be a single vector shuffle instead of a blend so nuke VHiHalf.
    VHiHalf = DAG.getUNDEF(MVT::v8i16);

    // Squash the masks to point directly into VLoHalf.
    for (int &M : LoBlendMask)
      if (M >= 0)
        M /= 2;
    for (int &M : HiBlendMask)
      if (M >= 0)
        M /= 2;
  } else {
    // Otherwise just unpack the low half of V into VLoHalf and the high half into
    // VHiHalf so that we can blend them as i16s.
    SDValue Zero = getZeroVector(MVT::v16i8, Subtarget, DAG, DL);

    VLoHalf = DAG.getBitcast(
        MVT::v8i16, DAG.getNode(X86ISD::UNPCKL, DL, MVT::v16i8, V, Zero));
    VHiHalf = DAG.getBitcast(
        MVT::v8i16, DAG.getNode(X86ISD::UNPCKH, DL, MVT::v16i8, V, Zero));
  }

  SDValue LoV = DAG.getVectorShuffle(MVT::v8i16, DL, VLoHalf, VHiHalf, LoBlendMask);
  SDValue HiV = DAG.getVectorShuffle(MVT::v8i16, DL, VLoHalf, VHiHalf, HiBlendMask);

  return DAG.getNode(X86ISD::PACKUS, DL, MVT::v16i8, LoV, HiV);
}

/// Dispatching routine to lower various 128-bit x86 vector shuffles.
///
/// This routine breaks down the specific type of 128-bit shuffle and
/// dispatches to the lowering routines accordingly.
static SDValue lower128BitShuffle(const SDLoc &DL, ArrayRef<int> Mask,
                                  MVT VT, SDValue V1, SDValue V2,
                                  const APInt &Zeroable,
                                  const X86Subtarget &Subtarget,
                                  SelectionDAG &DAG) {
  switch (VT.SimpleTy) {
  case MVT::v2i64:
    return lowerV2I64Shuffle(DL, Mask, Zeroable, V1, V2, Subtarget, DAG);
  case MVT::v2f64:
    return lowerV2F64Shuffle(DL, Mask, Zeroable, V1, V2, Subtarget, DAG);
  case MVT::v4i32:
    return lowerV4I32Shuffle(DL, Mask, Zeroable, V1, V2, Subtarget, DAG);
  case MVT::v4f32:
    return lowerV4F32Shuffle(DL, Mask, Zeroable, V1, V2, Subtarget, DAG);
  case MVT::v8i16:
    return lowerV8I16Shuffle(DL, Mask, Zeroable, V1, V2, Subtarget, DAG);
  case MVT::v16i8:
    return lowerV16I8Shuffle(DL, Mask, Zeroable, V1, V2, Subtarget, DAG);

  default:
    llvm_unreachable("Unimplemented!");
  }
}

/// Generic routine to split vector shuffle into half-sized shuffles.
///
/// This routine just extracts two subvectors, shuffles them independently, and
/// then concatenates them back together. This should work effectively with all
/// AVX vector shuffle types.
static SDValue splitAndLowerShuffle(const SDLoc &DL, MVT VT, SDValue V1,
                                    SDValue V2, ArrayRef<int> Mask,
                                    SelectionDAG &DAG) {
  assert(VT.getSizeInBits() >= 256 &&
         "Only for 256-bit or wider vector shuffles!");
  assert(V1.getSimpleValueType() == VT && "Bad operand type!");
  assert(V2.getSimpleValueType() == VT && "Bad operand type!");

  ArrayRef<int> LoMask = Mask.slice(0, Mask.size() / 2);
  ArrayRef<int> HiMask = Mask.slice(Mask.size() / 2);

  int NumElements = VT.getVectorNumElements();
  int SplitNumElements = NumElements / 2;
  MVT ScalarVT = VT.getVectorElementType();
  MVT SplitVT = MVT::getVectorVT(ScalarVT, NumElements / 2);

  // Rather than splitting build-vectors, just build two narrower build
  // vectors. This helps shuffling with splats and zeros.
  auto SplitVector = [&](SDValue V) {
    V = peekThroughBitcasts(V);

    MVT OrigVT = V.getSimpleValueType();
    int OrigNumElements = OrigVT.getVectorNumElements();
    int OrigSplitNumElements = OrigNumElements / 2;
    MVT OrigScalarVT = OrigVT.getVectorElementType();
    MVT OrigSplitVT = MVT::getVectorVT(OrigScalarVT, OrigNumElements / 2);

    SDValue LoV, HiV;

    auto *BV = dyn_cast<BuildVectorSDNode>(V);
    if (!BV) {
      LoV = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, OrigSplitVT, V,
                        DAG.getIntPtrConstant(0, DL));
      HiV = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, OrigSplitVT, V,
                        DAG.getIntPtrConstant(OrigSplitNumElements, DL));
    } else {

      SmallVector<SDValue, 16> LoOps, HiOps;
      for (int i = 0; i < OrigSplitNumElements; ++i) {
        LoOps.push_back(BV->getOperand(i));
        HiOps.push_back(BV->getOperand(i + OrigSplitNumElements));
      }
      LoV = DAG.getBuildVector(OrigSplitVT, DL, LoOps);
      HiV = DAG.getBuildVector(OrigSplitVT, DL, HiOps);
    }
    return std::make_pair(DAG.getBitcast(SplitVT, LoV),
                          DAG.getBitcast(SplitVT, HiV));
  };

  SDValue LoV1, HiV1, LoV2, HiV2;
  std::tie(LoV1, HiV1) = SplitVector(V1);
  std::tie(LoV2, HiV2) = SplitVector(V2);

  // Now create two 4-way blends of these half-width vectors.
  auto HalfBlend = [&](ArrayRef<int> HalfMask) {
    bool UseLoV1 = false, UseHiV1 = false, UseLoV2 = false, UseHiV2 = false;
    SmallVector<int, 32> V1BlendMask((unsigned)SplitNumElements, -1);
    SmallVector<int, 32> V2BlendMask((unsigned)SplitNumElements, -1);
    SmallVector<int, 32> BlendMask((unsigned)SplitNumElements, -1);
    for (int i = 0; i < SplitNumElements; ++i) {
      int M = HalfMask[i];
      if (M >= NumElements) {
        if (M >= NumElements + SplitNumElements)
          UseHiV2 = true;
        else
          UseLoV2 = true;
        V2BlendMask[i] = M - NumElements;
        BlendMask[i] = SplitNumElements + i;
      } else if (M >= 0) {
        if (M >= SplitNumElements)
          UseHiV1 = true;
        else
          UseLoV1 = true;
        V1BlendMask[i] = M;
        BlendMask[i] = i;
      }
    }

    // Because the lowering happens after all combining takes place, we need to
    // manually combine these blend masks as much as possible so that we create
    // a minimal number of high-level vector shuffle nodes.

    // First try just blending the halves of V1 or V2.
    if (!UseLoV1 && !UseHiV1 && !UseLoV2 && !UseHiV2)
      return DAG.getUNDEF(SplitVT);
    if (!UseLoV2 && !UseHiV2)
      return DAG.getVectorShuffle(SplitVT, DL, LoV1, HiV1, V1BlendMask);
    if (!UseLoV1 && !UseHiV1)
      return DAG.getVectorShuffle(SplitVT, DL, LoV2, HiV2, V2BlendMask);

    SDValue V1Blend, V2Blend;
    if (UseLoV1 && UseHiV1) {
      V1Blend =
        DAG.getVectorShuffle(SplitVT, DL, LoV1, HiV1, V1BlendMask);
    } else {
      // We only use half of V1 so map the usage down into the final blend mask.
      V1Blend = UseLoV1 ? LoV1 : HiV1;
      for (int i = 0; i < SplitNumElements; ++i)
        if (BlendMask[i] >= 0 && BlendMask[i] < SplitNumElements)
          BlendMask[i] = V1BlendMask[i] - (UseLoV1 ? 0 : SplitNumElements);
    }
    if (UseLoV2 && UseHiV2) {
      V2Blend =
        DAG.getVectorShuffle(SplitVT, DL, LoV2, HiV2, V2BlendMask);
    } else {
      // We only use half of V2 so map the usage down into the final blend mask.
      V2Blend = UseLoV2 ? LoV2 : HiV2;
      for (int i = 0; i < SplitNumElements; ++i)
        if (BlendMask[i] >= SplitNumElements)
          BlendMask[i] = V2BlendMask[i] + (UseLoV2 ? SplitNumElements : 0);
    }
    return DAG.getVectorShuffle(SplitVT, DL, V1Blend, V2Blend, BlendMask);
  };
  SDValue Lo = HalfBlend(LoMask);
  SDValue Hi = HalfBlend(HiMask);
  return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Lo, Hi);
}

/// Either split a vector in halves or decompose the shuffles and the
/// blend.
///
/// This is provided as a good fallback for many lowerings of non-single-input
/// shuffles with more than one 128-bit lane. In those cases, we want to select
/// between splitting the shuffle into 128-bit components and stitching those
/// back together vs. extracting the single-input shuffles and blending those
/// results.
static SDValue lowerShuffleAsSplitOrBlend(const SDLoc &DL, MVT VT, SDValue V1,
                                          SDValue V2, ArrayRef<int> Mask,
                                          const X86Subtarget &Subtarget,
                                          SelectionDAG &DAG) {
  assert(!V2.isUndef() && "This routine must not be used to lower single-input "
         "shuffles as it could then recurse on itself.");
  int Size = Mask.size();

  // If this can be modeled as a broadcast of two elements followed by a blend,
  // prefer that lowering. This is especially important because broadcasts can
  // often fold with memory operands.
  auto DoBothBroadcast = [&] {
    int V1BroadcastIdx = -1, V2BroadcastIdx = -1;
    for (int M : Mask)
      if (M >= Size) {
        if (V2BroadcastIdx < 0)
          V2BroadcastIdx = M - Size;
        else if (M - Size != V2BroadcastIdx)
          return false;
      } else if (M >= 0) {
        if (V1BroadcastIdx < 0)
          V1BroadcastIdx = M;
        else if (M != V1BroadcastIdx)
          return false;
      }
    return true;
  };
  if (DoBothBroadcast())
    return lowerShuffleAsDecomposedShuffleBlend(DL, VT, V1, V2, Mask,
                                                Subtarget, DAG);

  // If the inputs all stem from a single 128-bit lane of each input, then we
  // split them rather than blending because the split will decompose to
  // unusually few instructions.
  int LaneCount = VT.getSizeInBits() / 128;
  int LaneSize = Size / LaneCount;
  SmallBitVector LaneInputs[2];
  LaneInputs[0].resize(LaneCount, false);
  LaneInputs[1].resize(LaneCount, false);
  for (int i = 0; i < Size; ++i)
    if (Mask[i] >= 0)
      LaneInputs[Mask[i] / Size][(Mask[i] % Size) / LaneSize] = true;
  if (LaneInputs[0].count() <= 1 && LaneInputs[1].count() <= 1)
    return splitAndLowerShuffle(DL, VT, V1, V2, Mask, DAG);

  // Otherwise, just fall back to decomposed shuffles and a blend. This requires
  // that the decomposed single-input shuffles don't end up here.
  return lowerShuffleAsDecomposedShuffleBlend(DL, VT, V1, V2, Mask, Subtarget,
                                              DAG);
}

// Lower as SHUFPD(VPERM2F128(V1, V2), VPERM2F128(V1, V2)).
// TODO: Extend to support v8f32 (+ 512-bit shuffles).
static SDValue lowerShuffleAsLanePermuteAndSHUFP(const SDLoc &DL, MVT VT,
                                                 SDValue V1, SDValue V2,
                                                 ArrayRef<int> Mask,
                                                 SelectionDAG &DAG) {
  assert(VT == MVT::v4f64 && "Only for v4f64 shuffles");

  int LHSMask[4] = {-1, -1, -1, -1};
  int RHSMask[4] = {-1, -1, -1, -1};
  unsigned SHUFPMask = 0;

  // As SHUFPD uses a single LHS/RHS element per lane, we can always
  // perform the shuffle once the lanes have been shuffled in place.
  for (int i = 0; i != 4; ++i) {
    int M = Mask[i];
    if (M < 0)
      continue;
    int LaneBase = i & ~1;
    auto &LaneMask = (i & 1) ? RHSMask : LHSMask;
    LaneMask[LaneBase + (M & 1)] = M;
    SHUFPMask |= (M & 1) << i;
  }

  SDValue LHS = DAG.getVectorShuffle(VT, DL, V1, V2, LHSMask);
  SDValue RHS = DAG.getVectorShuffle(VT, DL, V1, V2, RHSMask);
  return DAG.getNode(X86ISD::SHUFP, DL, VT, LHS, RHS,
                     DAG.getTargetConstant(SHUFPMask, DL, MVT::i8));
}

/// Lower a vector shuffle crossing multiple 128-bit lanes as
/// a lane permutation followed by a per-lane permutation.
///
/// This is mainly for cases where we can have non-repeating permutes
/// in each lane.
///
/// TODO: This is very similar to lowerShuffleAsLanePermuteAndRepeatedMask,
/// we should investigate merging them.
static SDValue lowerShuffleAsLanePermuteAndPermute(
    const SDLoc &DL, MVT VT, SDValue V1, SDValue V2, ArrayRef<int> Mask,
    SelectionDAG &DAG, const X86Subtarget &Subtarget) {
  int NumElts = VT.getVectorNumElements();
  int NumLanes = VT.getSizeInBits() / 128;
  int NumEltsPerLane = NumElts / NumLanes;

  SmallVector<int, 4> SrcLaneMask(NumLanes, SM_SentinelUndef);
  SmallVector<int, 16> PermMask(NumElts, SM_SentinelUndef);

  for (int i = 0; i != NumElts; ++i) {
    int M = Mask[i];
    if (M < 0)
      continue;

    // Ensure that each lane comes from a single source lane.
    int SrcLane = M / NumEltsPerLane;
    int DstLane = i / NumEltsPerLane;
    if (!isUndefOrEqual(SrcLaneMask[DstLane], SrcLane))
      return SDValue();
    SrcLaneMask[DstLane] = SrcLane;

    PermMask[i] = (DstLane * NumEltsPerLane) + (M % NumEltsPerLane);
  }

  // Make sure we set all elements of the lane mask, to avoid undef propagation.
  SmallVector<int, 16> LaneMask(NumElts, SM_SentinelUndef);
  for (int DstLane = 0; DstLane != NumLanes; ++DstLane) {
    int SrcLane = SrcLaneMask[DstLane];
    if (0 <= SrcLane)
      for (int j = 0; j != NumEltsPerLane; ++j) {
        LaneMask[(DstLane * NumEltsPerLane) + j] =
            (SrcLane * NumEltsPerLane) + j;
      }
  }

  // If we're only shuffling a single lowest lane and the rest are identity
  // then don't bother.
  // TODO - isShuffleMaskInputInPlace could be extended to something like this.
  int NumIdentityLanes = 0;
  bool OnlyShuffleLowestLane = true;
  for (int i = 0; i != NumLanes; ++i) {
    if (isSequentialOrUndefInRange(PermMask, i * NumEltsPerLane, NumEltsPerLane,
                                   i * NumEltsPerLane))
      NumIdentityLanes++;
    else if (SrcLaneMask[i] != 0 && SrcLaneMask[i] != NumLanes)
      OnlyShuffleLowestLane = false;
  }
  if (OnlyShuffleLowestLane && NumIdentityLanes == (NumLanes - 1))
    return SDValue();

  SDValue LanePermute = DAG.getVectorShuffle(VT, DL, V1, V2, LaneMask);
  return DAG.getVectorShuffle(VT, DL, LanePermute, DAG.getUNDEF(VT), PermMask);
}

/// Lower a vector shuffle crossing multiple 128-bit lanes by shuffling one
/// source with a lane permutation.
///
/// This lowering strategy results in four instructions in the worst case for a
/// single-input cross lane shuffle which is lower than any other fully general
/// cross-lane shuffle strategy I'm aware of. Special cases for each particular
/// shuffle pattern should be handled prior to trying this lowering.
static SDValue lowerShuffleAsLanePermuteAndShuffle(
    const SDLoc &DL, MVT VT, SDValue V1, SDValue V2, ArrayRef<int> Mask,
    SelectionDAG &DAG, const X86Subtarget &Subtarget) {
  // FIXME: This should probably be generalized for 512-bit vectors as well.
  assert(VT.is256BitVector() && "Only for 256-bit vector shuffles!");
  int Size = Mask.size();
  int LaneSize = Size / 2;

  // Fold to SHUFPD(VPERM2F128(V1, V2), VPERM2F128(V1, V2)).
  // Only do this if the elements aren't all from the lower lane,
  // otherwise we're (probably) better off doing a split.
  if (VT == MVT::v4f64 &&
      !all_of(Mask, [LaneSize](int M) { return M < LaneSize; }))
    if (SDValue V =
            lowerShuffleAsLanePermuteAndSHUFP(DL, VT, V1, V2, Mask, DAG))
      return V;

  // If there are only inputs from one 128-bit lane, splitting will in fact be
  // less expensive. The flags track whether the given lane contains an element
  // that crosses to another lane.
  if (!Subtarget.hasAVX2()) {
    bool LaneCrossing[2] = {false, false};
    for (int i = 0; i < Size; ++i)
      if (Mask[i] >= 0 && ((Mask[i] % Size) / LaneSize) != (i / LaneSize))
        LaneCrossing[(Mask[i] % Size) / LaneSize] = true;
    if (!LaneCrossing[0] || !LaneCrossing[1])
      return splitAndLowerShuffle(DL, VT, V1, V2, Mask, DAG);
  } else {
    bool LaneUsed[2] = {false, false};
    for (int i = 0; i < Size; ++i)
      if (Mask[i] >= 0)
        LaneUsed[(Mask[i] % Size) / LaneSize] = true;
    if (!LaneUsed[0] || !LaneUsed[1])
      return splitAndLowerShuffle(DL, VT, V1, V2, Mask, DAG);
  }

  // TODO - we could support shuffling V2 in the Flipped input.
  assert(V2.isUndef() &&
         "This last part of this routine only works on single input shuffles");

  SmallVector<int, 32> InLaneMask(Mask.begin(), Mask.end());
  for (int i = 0; i < Size; ++i) {
    int &M = InLaneMask[i];
    if (M < 0)
      continue;
    if (((M % Size) / LaneSize) != (i / LaneSize))
      M = (M % LaneSize) + ((i / LaneSize) * LaneSize) + Size;
  }
  assert(!is128BitLaneCrossingShuffleMask(VT, InLaneMask) &&
         "In-lane shuffle mask expected");

  // Flip the lanes, and shuffle the results which should now be in-lane.
  MVT PVT = VT.isFloatingPoint() ? MVT::v4f64 : MVT::v4i64;
  SDValue Flipped = DAG.getBitcast(PVT, V1);
  Flipped =
      DAG.getVectorShuffle(PVT, DL, Flipped, DAG.getUNDEF(PVT), {2, 3, 0, 1});
  Flipped = DAG.getBitcast(VT, Flipped);
  return DAG.getVectorShuffle(VT, DL, V1, Flipped, InLaneMask);
}

/// Handle lowering 2-lane 128-bit shuffles.
static SDValue lowerV2X128Shuffle(const SDLoc &DL, MVT VT, SDValue V1,
                                  SDValue V2, ArrayRef<int> Mask,
                                  const APInt &Zeroable,
                                  const X86Subtarget &Subtarget,
                                  SelectionDAG &DAG) {
  // With AVX2, use VPERMQ/VPERMPD for unary shuffles to allow memory folding.
  if (Subtarget.hasAVX2() && V2.isUndef())
    return SDValue();

  bool V2IsZero = !V2.isUndef() && ISD::isBuildVectorAllZeros(V2.getNode());

  SmallVector<int, 4> WidenedMask;
  if (!canWidenShuffleElements(Mask, Zeroable, V2IsZero, WidenedMask))
    return SDValue();

  bool IsLowZero = (Zeroable & 0x3) == 0x3;
  bool IsHighZero = (Zeroable & 0xc) == 0xc;

  // Try to use an insert into a zero vector.
  if (WidenedMask[0] == 0 && IsHighZero) {
    MVT SubVT = MVT::getVectorVT(VT.getVectorElementType(), 2);
    SDValue LoV = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SubVT, V1,
                              DAG.getIntPtrConstant(0, DL));
    return DAG.getNode(ISD::INSERT_SUBVECTOR, DL, VT,
                       getZeroVector(VT, Subtarget, DAG, DL), LoV,
                       DAG.getIntPtrConstant(0, DL));
  }

  // TODO: If minimizing size and one of the inputs is a zero vector and the
  // the zero vector has only one use, we could use a VPERM2X128 to save the
  // instruction bytes needed to explicitly generate the zero vector.

  // Blends are faster and handle all the non-lane-crossing cases.
  if (SDValue Blend = lowerShuffleAsBlend(DL, VT, V1, V2, Mask, Zeroable,
                                          Subtarget, DAG))
    return Blend;

  // If either input operand is a zero vector, use VPERM2X128 because its mask
  // allows us to replace the zero input with an implicit zero.
  if (!IsLowZero && !IsHighZero) {
    // Check for patterns which can be matched with a single insert of a 128-bit
    // subvector.
    bool OnlyUsesV1 = isShuffleEquivalent(V1, V2, Mask, {0, 1, 0, 1});
    if (OnlyUsesV1 || isShuffleEquivalent(V1, V2, Mask, {0, 1, 4, 5})) {

      // With AVX1, use vperm2f128 (below) to allow load folding. Otherwise,
      // this will likely become vinsertf128 which can't fold a 256-bit memop.
      if (!isa<LoadSDNode>(peekThroughBitcasts(V1))) {
        MVT SubVT = MVT::getVectorVT(VT.getVectorElementType(), 2);
        SDValue SubVec = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SubVT,
                                     OnlyUsesV1 ? V1 : V2,
                                     DAG.getIntPtrConstant(0, DL));
        return DAG.getNode(ISD::INSERT_SUBVECTOR, DL, VT, V1, SubVec,
                           DAG.getIntPtrConstant(2, DL));
      }
    }

    // Try to use SHUF128 if possible.
    if (Subtarget.hasVLX()) {
      if (WidenedMask[0] < 2 && WidenedMask[1] >= 2) {
        unsigned PermMask = ((WidenedMask[0] % 2) << 0) |
                            ((WidenedMask[1] % 2) << 1);
        return DAG.getNode(X86ISD::SHUF128, DL, VT, V1, V2,
                           DAG.getTargetConstant(PermMask, DL, MVT::i8));
      }
    }
  }

  // Otherwise form a 128-bit permutation. After accounting for undefs,
  // convert the 64-bit shuffle mask selection values into 128-bit
  // selection bits by dividing the indexes by 2 and shifting into positions
  // defined by a vperm2*128 instruction's immediate control byte.

  // The immediate permute control byte looks like this:
  //    [1:0] - select 128 bits from sources for low half of destination
  //    [2]   - ignore
  //    [3]   - zero low half of destination
  //    [5:4] - select 128 bits from sources for high half of destination
  //    [6]   - ignore
  //    [7]   - zero high half of destination

  assert((WidenedMask[0] >= 0 || IsLowZero) &&
         (WidenedMask[1] >= 0 || IsHighZero) && "Undef half?");

  unsigned PermMask = 0;
  PermMask |= IsLowZero  ? 0x08 : (WidenedMask[0] << 0);
  PermMask |= IsHighZero ? 0x80 : (WidenedMask[1] << 4);

  // Check the immediate mask and replace unused sources with undef.
  if ((PermMask & 0x0a) != 0x00 && (PermMask & 0xa0) != 0x00)
    V1 = DAG.getUNDEF(VT);
  if ((PermMask & 0x0a) != 0x02 && (PermMask & 0xa0) != 0x20)
    V2 = DAG.getUNDEF(VT);

  return DAG.getNode(X86ISD::VPERM2X128, DL, VT, V1, V2,
                     DAG.getTargetConstant(PermMask, DL, MVT::i8));
}

/// Lower a vector shuffle by first fixing the 128-bit lanes and then
/// shuffling each lane.
///
/// This attempts to create a repeated lane shuffle where each lane uses one
/// or two of the lanes of the inputs. The lanes of the input vectors are
/// shuffled in one or two independent shuffles to get the lanes into the
/// position needed by the final shuffle.
static SDValue lowerShuffleAsLanePermuteAndRepeatedMask(
    const SDLoc &DL, MVT VT, SDValue V1, SDValue V2, ArrayRef<int> Mask,
    const X86Subtarget &Subtarget, SelectionDAG &DAG) {
  assert(!V2.isUndef() && "This is only useful with multiple inputs.");

  if (is128BitLaneRepeatedShuffleMask(VT, Mask))
    return SDValue();

  int NumElts = Mask.size();
  int NumLanes = VT.getSizeInBits() / 128;
  int NumLaneElts = 128 / VT.getScalarSizeInBits();
  SmallVector<int, 16> RepeatMask(NumLaneElts, -1);
  SmallVector<std::array<int, 2>, 2> LaneSrcs(NumLanes, {{-1, -1}});

  // First pass will try to fill in the RepeatMask from lanes that need two
  // sources.
  for (int Lane = 0; Lane != NumLanes; ++Lane) {
    int Srcs[2] = {-1, -1};
    SmallVector<int, 16> InLaneMask(NumLaneElts, -1);
    for (int i = 0; i != NumLaneElts; ++i) {
      int M = Mask[(Lane * NumLaneElts) + i];
      if (M < 0)
        continue;
      // Determine which of the possible input lanes (NumLanes from each source)
      // this element comes from. Assign that as one of the sources for this
      // lane. We can assign up to 2 sources for this lane. If we run out
      // sources we can't do anything.
      int LaneSrc = M / NumLaneElts;
      int Src;
      if (Srcs[0] < 0 || Srcs[0] == LaneSrc)
        Src = 0;
      else if (Srcs[1] < 0 || Srcs[1] == LaneSrc)
        Src = 1;
      else
        return SDValue();

      Srcs[Src] = LaneSrc;
      InLaneMask[i] = (M % NumLaneElts) + Src * NumElts;
    }

    // If this lane has two sources, see if it fits with the repeat mask so far.
    if (Srcs[1] < 0)
      continue;

    LaneSrcs[Lane][0] = Srcs[0];
    LaneSrcs[Lane][1] = Srcs[1];

    auto MatchMasks = [](ArrayRef<int> M1, ArrayRef<int> M2) {
      assert(M1.size() == M2.size() && "Unexpected mask size");
      for (int i = 0, e = M1.size(); i != e; ++i)
        if (M1[i] >= 0 && M2[i] >= 0 && M1[i] != M2[i])
          return false;
      return true;
    };

    auto MergeMasks = [](ArrayRef<int> Mask, MutableArrayRef<int> MergedMask) {
      assert(Mask.size() == MergedMask.size() && "Unexpected mask size");
      for (int i = 0, e = MergedMask.size(); i != e; ++i) {
        int M = Mask[i];
        if (M < 0)
          continue;
        assert((MergedMask[i] < 0 || MergedMask[i] == M) &&
               "Unexpected mask element");
        MergedMask[i] = M;
      }
    };

    if (MatchMasks(InLaneMask, RepeatMask)) {
      // Merge this lane mask into the final repeat mask.
      MergeMasks(InLaneMask, RepeatMask);
      continue;
    }

    // Didn't find a match. Swap the operands and try again.
    std::swap(LaneSrcs[Lane][0], LaneSrcs[Lane][1]);
    ShuffleVectorSDNode::commuteMask(InLaneMask);

    if (MatchMasks(InLaneMask, RepeatMask)) {
      // Merge this lane mask into the final repeat mask.
      MergeMasks(InLaneMask, RepeatMask);
      continue;
    }

    // Couldn't find a match with the operands in either order.
    return SDValue();
  }

  // Now handle any lanes with only one source.
  for (int Lane = 0; Lane != NumLanes; ++Lane) {
    // If this lane has already been processed, skip it.
    if (LaneSrcs[Lane][0] >= 0)
      continue;

    for (int i = 0; i != NumLaneElts; ++i) {
      int M = Mask[(Lane * NumLaneElts) + i];
      if (M < 0)
        continue;

      // If RepeatMask isn't defined yet we can define it ourself.
      if (RepeatMask[i] < 0)
        RepeatMask[i] = M % NumLaneElts;

      if (RepeatMask[i] < NumElts) {
        if (RepeatMask[i] != M % NumLaneElts)
          return SDValue();
        LaneSrcs[Lane][0] = M / NumLaneElts;
      } else {
        if (RepeatMask[i] != ((M % NumLaneElts) + NumElts))
          return SDValue();
        LaneSrcs[Lane][1] = M / NumLaneElts;
      }
    }

    if (LaneSrcs[Lane][0] < 0 && LaneSrcs[Lane][1] < 0)
      return SDValue();
  }

  SmallVector<int, 16> NewMask(NumElts, -1);
  for (int Lane = 0; Lane != NumLanes; ++Lane) {
    int Src = LaneSrcs[Lane][0];
    for (int i = 0; i != NumLaneElts; ++i) {
      int M = -1;
      if (Src >= 0)
        M = Src * NumLaneElts + i;
      NewMask[Lane * NumLaneElts + i] = M;
    }
  }
  SDValue NewV1 = DAG.getVectorShuffle(VT, DL, V1, V2, NewMask);
  // Ensure we didn't get back the shuffle we started with.
  // FIXME: This is a hack to make up for some splat handling code in
  // getVectorShuffle.
  if (isa<ShuffleVectorSDNode>(NewV1) &&
      cast<ShuffleVectorSDNode>(NewV1)->getMask() == Mask)
    return SDValue();

  for (int Lane = 0; Lane != NumLanes; ++Lane) {
    int Src = LaneSrcs[Lane][1];
    for (int i = 0; i != NumLaneElts; ++i) {
      int M = -1;
      if (Src >= 0)
        M = Src * NumLaneElts + i;
      NewMask[Lane * NumLaneElts + i] = M;
    }
  }
  SDValue NewV2 = DAG.getVectorShuffle(VT, DL, V1, V2, NewMask);
  // Ensure we didn't get back the shuffle we started with.
  // FIXME: This is a hack to make up for some splat handling code in
  // getVectorShuffle.
  if (isa<ShuffleVectorSDNode>(NewV2) &&
      cast<ShuffleVectorSDNode>(NewV2)->getMask() == Mask)
    return SDValue();

  for (int i = 0; i != NumElts; ++i) {
    NewMask[i] = RepeatMask[i % NumLaneElts];
    if (NewMask[i] < 0)
      continue;

    NewMask[i] += (i / NumLaneElts) * NumLaneElts;
  }
  return DAG.getVectorShuffle(VT, DL, NewV1, NewV2, NewMask);
}

/// If the input shuffle mask results in a vector that is undefined in all upper
/// or lower half elements and that mask accesses only 2 halves of the
/// shuffle's operands, return true. A mask of half the width with mask indexes
/// adjusted to access the extracted halves of the original shuffle operands is
/// returned in HalfMask. HalfIdx1 and HalfIdx2 return whether the upper or
/// lower half of each input operand is accessed.
static bool
getHalfShuffleMask(ArrayRef<int> Mask, MutableArrayRef<int> HalfMask,
                   int &HalfIdx1, int &HalfIdx2) {
  assert((Mask.size() == HalfMask.size() * 2) &&
         "Expected input mask to be twice as long as output");

  // Exactly one half of the result must be undef to allow narrowing.
  bool UndefLower = isUndefLowerHalf(Mask);
  bool UndefUpper = isUndefUpperHalf(Mask);
  if (UndefLower == UndefUpper)
    return false;

  unsigned HalfNumElts = HalfMask.size();
  unsigned MaskIndexOffset = UndefLower ? HalfNumElts : 0;
  HalfIdx1 = -1;
  HalfIdx2 = -1;
  for (unsigned i = 0; i != HalfNumElts; ++i) {
    int M = Mask[i + MaskIndexOffset];
    if (M < 0) {
      HalfMask[i] = M;
      continue;
    }

    // Determine which of the 4 half vectors this element is from.
    // i.e. 0 = Lower V1, 1 = Upper V1, 2 = Lower V2, 3 = Upper V2.
    int HalfIdx = M / HalfNumElts;

    // Determine the element index into its half vector source.
    int HalfElt = M % HalfNumElts;

    // We can shuffle with up to 2 half vectors, set the new 'half'
    // shuffle mask accordingly.
    if (HalfIdx1 < 0 || HalfIdx1 == HalfIdx) {
      HalfMask[i] = HalfElt;
      HalfIdx1 = HalfIdx;
      continue;
    }
    if (HalfIdx2 < 0 || HalfIdx2 == HalfIdx) {
      HalfMask[i] = HalfElt + HalfNumElts;
      HalfIdx2 = HalfIdx;
      continue;
    }

    // Too many half vectors referenced.
    return false;
  }

  return true;
}

/// Given the output values from getHalfShuffleMask(), create a half width
/// shuffle of extracted vectors followed by an insert back to full width.
static SDValue getShuffleHalfVectors(const SDLoc &DL, SDValue V1, SDValue V2,
                                     ArrayRef<int> HalfMask, int HalfIdx1,
                                     int HalfIdx2, bool UndefLower,
                                     SelectionDAG &DAG, bool UseConcat = false) {
  assert(V1.getValueType() == V2.getValueType() && "Different sized vectors?");
  assert(V1.getValueType().isSimple() && "Expecting only simple types");

  MVT VT = V1.getSimpleValueType();
  MVT HalfVT = VT.getHalfNumVectorElementsVT();
  unsigned HalfNumElts = HalfVT.getVectorNumElements();

  auto getHalfVector = [&](int HalfIdx) {
    if (HalfIdx < 0)
      return DAG.getUNDEF(HalfVT);
    SDValue V = (HalfIdx < 2 ? V1 : V2);
    HalfIdx = (HalfIdx % 2) * HalfNumElts;
    return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, HalfVT, V,
                       DAG.getIntPtrConstant(HalfIdx, DL));
  };

  // ins undef, (shuf (ext V1, HalfIdx1), (ext V2, HalfIdx2), HalfMask), Offset
  SDValue Half1 = getHalfVector(HalfIdx1);
  SDValue Half2 = getHalfVector(HalfIdx2);
  SDValue V = DAG.getVectorShuffle(HalfVT, DL, Half1, Half2, HalfMask);
  if (UseConcat) {
    SDValue Op0 = V;
    SDValue Op1 = DAG.getUNDEF(HalfVT);
    if (UndefLower)
      std::swap(Op0, Op1);
    return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Op0, Op1);
  }

  unsigned Offset = UndefLower ? HalfNumElts : 0;
  return DAG.getNode(ISD::INSERT_SUBVECTOR, DL, VT, DAG.getUNDEF(VT), V,
                     DAG.getIntPtrConstant(Offset, DL));
}

/// Lower shuffles where an entire half of a 256 or 512-bit vector is UNDEF.
/// This allows for fast cases such as subvector extraction/insertion
/// or shuffling smaller vector types which can lower more efficiently.
static SDValue lowerShuffleWithUndefHalf(const SDLoc &DL, MVT VT, SDValue V1,
                                         SDValue V2, ArrayRef<int> Mask,
                                         const X86Subtarget &Subtarget,
                                         SelectionDAG &DAG) {
  assert((VT.is256BitVector() || VT.is512BitVector()) &&
         "Expected 256-bit or 512-bit vector");

  bool UndefLower = isUndefLowerHalf(Mask);
  if (!UndefLower && !isUndefUpperHalf(Mask))
    return SDValue();

  assert((!UndefLower || !isUndefUpperHalf(Mask)) &&
         "Completely undef shuffle mask should have been simplified already");

  // Upper half is undef and lower half is whole upper subvector.
  // e.g. vector_shuffle <4, 5, 6, 7, u, u, u, u> or <2, 3, u, u>
  MVT HalfVT = VT.getHalfNumVectorElementsVT();
  unsigned HalfNumElts = HalfVT.getVectorNumElements();
  if (!UndefLower &&
      isSequentialOrUndefInRange(Mask, 0, HalfNumElts, HalfNumElts)) {
    SDValue Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, HalfVT, V1,
                             DAG.getIntPtrConstant(HalfNumElts, DL));
    return DAG.getNode(ISD::INSERT_SUBVECTOR, DL, VT, DAG.getUNDEF(VT), Hi,
                       DAG.getIntPtrConstant(0, DL));
  }

  // Lower half is undef and upper half is whole lower subvector.
  // e.g. vector_shuffle <u, u, u, u, 0, 1, 2, 3> or <u, u, 0, 1>
  if (UndefLower &&
      isSequentialOrUndefInRange(Mask, HalfNumElts, HalfNumElts, 0)) {
    SDValue Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, HalfVT, V1,
                             DAG.getIntPtrConstant(0, DL));
    return DAG.getNode(ISD::INSERT_SUBVECTOR, DL, VT, DAG.getUNDEF(VT), Hi,
                       DAG.getIntPtrConstant(HalfNumElts, DL));
  }

  int HalfIdx1, HalfIdx2;
  SmallVector<int, 8> HalfMask(HalfNumElts);
  if (!getHalfShuffleMask(Mask, HalfMask, HalfIdx1, HalfIdx2))
    return SDValue();

  assert(HalfMask.size() == HalfNumElts && "Unexpected shuffle mask length");

  // Only shuffle the halves of the inputs when useful.
  unsigned NumLowerHalves =
      (HalfIdx1 == 0 || HalfIdx1 == 2) + (HalfIdx2 == 0 || HalfIdx2 == 2);
  unsigned NumUpperHalves =
      (HalfIdx1 == 1 || HalfIdx1 == 3) + (HalfIdx2 == 1 || HalfIdx2 == 3);
  assert(NumLowerHalves + NumUpperHalves <= 2 && "Only 1 or 2 halves allowed");

  // Determine the larger pattern of undef/halves, then decide if it's worth
  // splitting the shuffle based on subtarget capabilities and types.
  unsigned EltWidth = VT.getVectorElementType().getSizeInBits();
  if (!UndefLower) {
    // XXXXuuuu: no insert is needed.
    // Always extract lowers when setting lower - these are all free subreg ops.
    if (NumUpperHalves == 0)
      return getShuffleHalfVectors(DL, V1, V2, HalfMask, HalfIdx1, HalfIdx2,
                                   UndefLower, DAG);

    if (NumUpperHalves == 1) {
      // AVX2 has efficient 32/64-bit element cross-lane shuffles.
      if (Subtarget.hasAVX2()) {
        // extract128 + vunpckhps/vshufps, is better than vblend + vpermps.
        if (EltWidth == 32 && NumLowerHalves && HalfVT.is128BitVector() &&
            !is128BitUnpackShuffleMask(HalfMask) &&
            (!isSingleSHUFPSMask(HalfMask) ||
             Subtarget.hasFastVariableShuffle()))
          return SDValue();
        // If this is a unary shuffle (assume that the 2nd operand is
        // canonicalized to undef), then we can use vpermpd. Otherwise, we
        // are better off extracting the upper half of 1 operand and using a
        // narrow shuffle.
        if (EltWidth == 64 && V2.isUndef())
          return SDValue();
      }
      // AVX512 has efficient cross-lane shuffles for all legal 512-bit types.
      if (Subtarget.hasAVX512() && VT.is512BitVector())
        return SDValue();
      // Extract + narrow shuffle is better than the wide alternative.
      return getShuffleHalfVectors(DL, V1, V2, HalfMask, HalfIdx1, HalfIdx2,
                                   UndefLower, DAG);
    }

    // Don't extract both uppers, instead shuffle and then extract.
    assert(NumUpperHalves == 2 && "Half vector count went wrong");
    return SDValue();
  }

  // UndefLower - uuuuXXXX: an insert to high half is required if we split this.
  if (NumUpperHalves == 0) {
    // AVX2 has efficient 64-bit element cross-lane shuffles.
    // TODO: Refine to account for unary shuffle, splat, and other masks?
    if (Subtarget.hasAVX2() && EltWidth == 64)
      return SDValue();
    // AVX512 has efficient cross-lane shuffles for all legal 512-bit types.
    if (Subtarget.hasAVX512() && VT.is512BitVector())
      return SDValue();
    // Narrow shuffle + insert is better than the wide alternative.
    return getShuffleHalfVectors(DL, V1, V2, HalfMask, HalfIdx1, HalfIdx2,
                                 UndefLower, DAG);
  }

  // NumUpperHalves != 0: don't bother with extract, shuffle, and then insert.
  return SDValue();
}

/// Test whether the specified input (0 or 1) is in-place blended by the
/// given mask.
///
/// This returns true if the elements from a particular input are already in the
/// slot required by the given mask and require no permutation.
static bool isShuffleMaskInputInPlace(int Input, ArrayRef<int> Mask) {
  assert((Input == 0 || Input == 1) && "Only two inputs to shuffles.");
  int Size = Mask.size();
  for (int i = 0; i < Size; ++i)
    if (Mask[i] >= 0 && Mask[i] / Size == Input && Mask[i] % Size != i)
      return false;

  return true;
}

/// Handle case where shuffle sources are coming from the same 128-bit lane and
/// every lane can be represented as the same repeating mask - allowing us to
/// shuffle the sources with the repeating shuffle and then permute the result
/// to the destination lanes.
static SDValue lowerShuffleAsRepeatedMaskAndLanePermute(
    const SDLoc &DL, MVT VT, SDValue V1, SDValue V2, ArrayRef<int> Mask,
    const X86Subtarget &Subtarget, SelectionDAG &DAG) {
  int NumElts = VT.getVectorNumElements();
  int NumLanes = VT.getSizeInBits() / 128;
  int NumLaneElts = NumElts / NumLanes;

  // On AVX2 we may be able to just shuffle the lowest elements and then
  // broadcast the result.
  if (Subtarget.hasAVX2()) {
    for (unsigned BroadcastSize : {16, 32, 64}) {
      if (BroadcastSize <= VT.getScalarSizeInBits())
        continue;
      int NumBroadcastElts = BroadcastSize / VT.getScalarSizeInBits();

      // Attempt to match a repeating pattern every NumBroadcastElts,
      // accounting for UNDEFs but only references the lowest 128-bit
      // lane of the inputs.
      auto FindRepeatingBroadcastMask = [&](SmallVectorImpl<int> &RepeatMask) {
        for (int i = 0; i != NumElts; i += NumBroadcastElts)
          for (int j = 0; j != NumBroadcastElts; ++j) {
            int M = Mask[i + j];
            if (M < 0)
              continue;
            int &R = RepeatMask[j];
            if (0 != ((M % NumElts) / NumLaneElts))
              return false;
            if (0 <= R && R != M)
              return false;
            R = M;
          }
        return true;
      };

      SmallVector<int, 8> RepeatMask((unsigned)NumElts, -1);
      if (!FindRepeatingBroadcastMask(RepeatMask))
        continue;

      // Shuffle the (lowest) repeated elements in place for broadcast.
      SDValue RepeatShuf = DAG.getVectorShuffle(VT, DL, V1, V2, RepeatMask);

      // Shuffle the actual broadcast.
      SmallVector<int, 8> BroadcastMask((unsigned)NumElts, -1);
      for (int i = 0; i != NumElts; i += NumBroadcastElts)
        for (int j = 0; j != NumBroadcastElts; ++j)
          BroadcastMask[i + j] = j;
      return DAG.getVectorShuffle(VT, DL, RepeatShuf, DAG.getUNDEF(VT),
                                  BroadcastMask);
    }
  }

  // Bail if the shuffle mask doesn't cross 128-bit lanes.
  if (!is128BitLaneCrossingShuffleMask(VT, Mask))
    return SDValue();

  // Bail if we already have a repeated lane shuffle mask.
  SmallVector<int, 8> RepeatedShuffleMask;
  if (is128BitLaneRepeatedShuffleMask(VT, Mask, RepeatedShuffleMask))
    return SDValue();

  // On AVX2 targets we can permute 256-bit vectors as 64-bit sub-lanes
  // (with PERMQ/PERMPD), otherwise we can only permute whole 128-bit lanes.
  int SubLaneScale = Subtarget.hasAVX2() && VT.is256BitVector() ? 2 : 1;
  int NumSubLanes = NumLanes * SubLaneScale;
  int NumSubLaneElts = NumLaneElts / SubLaneScale;

  // Check that all the sources are coming from the same lane and see if we can
  // form a repeating shuffle mask (local to each sub-lane). At the same time,
  // determine the source sub-lane for each destination sub-lane.
  int TopSrcSubLane = -1;
  SmallVector<int, 8> Dst2SrcSubLanes((unsigned)NumSubLanes, -1);
  SmallVector<int, 8> RepeatedSubLaneMasks[2] = {
      SmallVector<int, 8>((unsigned)NumSubLaneElts, SM_SentinelUndef),
      SmallVector<int, 8>((unsigned)NumSubLaneElts, SM_SentinelUndef)};

  for (int DstSubLane = 0; DstSubLane != NumSubLanes; ++DstSubLane) {
    // Extract the sub-lane mask, check that it all comes from the same lane
    // and normalize the mask entries to come from the first lane.
    int SrcLane = -1;
    SmallVector<int, 8> SubLaneMask((unsigned)NumSubLaneElts, -1);
    for (int Elt = 0; Elt != NumSubLaneElts; ++Elt) {
      int M = Mask[(DstSubLane * NumSubLaneElts) + Elt];
      if (M < 0)
        continue;
      int Lane = (M % NumElts) / NumLaneElts;
      if ((0 <= SrcLane) && (SrcLane != Lane))
        return SDValue();
      SrcLane = Lane;
      int LocalM = (M % NumLaneElts) + (M < NumElts ? 0 : NumElts);
      SubLaneMask[Elt] = LocalM;
    }

    // Whole sub-lane is UNDEF.
    if (SrcLane < 0)
      continue;

    // Attempt to match against the candidate repeated sub-lane masks.
    for (int SubLane = 0; SubLane != SubLaneScale; ++SubLane) {
      auto MatchMasks = [NumSubLaneElts](ArrayRef<int> M1, ArrayRef<int> M2) {
        for (int i = 0; i != NumSubLaneElts; ++i) {
          if (M1[i] < 0 || M2[i] < 0)
            continue;
          if (M1[i] != M2[i])
            return false;
        }
        return true;
      };

      auto &RepeatedSubLaneMask = RepeatedSubLaneMasks[SubLane];
      if (!MatchMasks(SubLaneMask, RepeatedSubLaneMask))
        continue;

      // Merge the sub-lane mask into the matching repeated sub-lane mask.
      for (int i = 0; i != NumSubLaneElts; ++i) {
        int M = SubLaneMask[i];
        if (M < 0)
          continue;
        assert((RepeatedSubLaneMask[i] < 0 || RepeatedSubLaneMask[i] == M) &&
               "Unexpected mask element");
        RepeatedSubLaneMask[i] = M;
      }

      // Track the top most source sub-lane - by setting the remaining to UNDEF
      // we can greatly simplify shuffle matching.
      int SrcSubLane = (SrcLane * SubLaneScale) + SubLane;
      TopSrcSubLane = std::max(TopSrcSubLane, SrcSubLane);
      Dst2SrcSubLanes[DstSubLane] = SrcSubLane;
      break;
    }

    // Bail if we failed to find a matching repeated sub-lane mask.
    if (Dst2SrcSubLanes[DstSubLane] < 0)
      return SDValue();
  }
  assert(0 <= TopSrcSubLane && TopSrcSubLane < NumSubLanes &&
         "Unexpected source lane");

  // Create a repeating shuffle mask for the entire vector.
  SmallVector<int, 8> RepeatedMask((unsigned)NumElts, -1);
  for (int SubLane = 0; SubLane <= TopSrcSubLane; ++SubLane) {
    int Lane = SubLane / SubLaneScale;
    auto &RepeatedSubLaneMask = RepeatedSubLaneMasks[SubLane % SubLaneScale];
    for (int Elt = 0; Elt != NumSubLaneElts; ++Elt) {
      int M = RepeatedSubLaneMask[Elt];
      if (M < 0)
        continue;
      int Idx = (SubLane * NumSubLaneElts) + Elt;
      RepeatedMask[Idx] = M + (Lane * NumLaneElts);
    }
  }
  SDValue RepeatedShuffle = DAG.getVectorShuffle(VT, DL, V1, V2, RepeatedMask);

  // Shuffle each source sub-lane to its destination.
  SmallVector<int, 8> SubLaneMask((unsigned)NumElts, -1);
  for (int i = 0; i != NumElts; i += NumSubLaneElts) {
    int SrcSubLane = Dst2SrcSubLanes[i / NumSubLaneElts];
    if (SrcSubLane < 0)
      continue;
    for (int j = 0; j != NumSubLaneElts; ++j)
      SubLaneMask[i + j] = j + (SrcSubLane * NumSubLaneElts);
  }

  return DAG.getVectorShuffle(VT, DL, RepeatedShuffle, DAG.getUNDEF(VT),
                              SubLaneMask);
}

static bool matchShuffleWithSHUFPD(MVT VT, SDValue &V1, SDValue &V2,
                                   bool &ForceV1Zero, bool &ForceV2Zero,
                                   unsigned &ShuffleImm, ArrayRef<int> Mask,
                                   const APInt &Zeroable) {
  int NumElts = VT.getVectorNumElements();
  assert(VT.getScalarSizeInBits() == 64 &&
         (NumElts == 2 || NumElts == 4 || NumElts == 8) &&
         "Unexpected data type for VSHUFPD");
  assert(isUndefOrZeroOrInRange(Mask, 0, 2 * NumElts) &&
         "Illegal shuffle mask");

  bool ZeroLane[2] = { true, true };
  for (int i = 0; i < NumElts; ++i)
    ZeroLane[i & 1] &= Zeroable[i];

  // Mask for V8F64: 0/1,  8/9,  2/3,  10/11, 4/5, ..
  // Mask for V4F64; 0/1,  4/5,  2/3,  6/7..
  ShuffleImm = 0;
  bool ShufpdMask = true;
  bool CommutableMask = true;
  for (int i = 0; i < NumElts; ++i) {
    if (Mask[i] == SM_SentinelUndef || ZeroLane[i & 1])
      continue;
    if (Mask[i] < 0)
      return false;
    int Val = (i & 6) + NumElts * (i & 1);
    int CommutVal = (i & 0xe) + NumElts * ((i & 1) ^ 1);
    if (Mask[i] < Val || Mask[i] > Val + 1)
      ShufpdMask = false;
    if (Mask[i] < CommutVal || Mask[i] > CommutVal + 1)
      CommutableMask = false;
    ShuffleImm |= (Mask[i] % 2) << i;
  }

  if (!ShufpdMask && !CommutableMask)
    return false;

  if (!ShufpdMask && CommutableMask)
    std::swap(V1, V2);

  ForceV1Zero = ZeroLane[0];
  ForceV2Zero = ZeroLane[1];
  return true;
}

static SDValue lowerShuffleWithSHUFPD(const SDLoc &DL, MVT VT, SDValue V1,
                                      SDValue V2, ArrayRef<int> Mask,
                                      const APInt &Zeroable,
                                      const X86Subtarget &Subtarget,
                                      SelectionDAG &DAG) {
  assert((VT == MVT::v2f64 || VT == MVT::v4f64 || VT == MVT::v8f64) &&
         "Unexpected data type for VSHUFPD");

  unsigned Immediate = 0;
  bool ForceV1Zero = false, ForceV2Zero = false;
  if (!matchShuffleWithSHUFPD(VT, V1, V2, ForceV1Zero, ForceV2Zero, Immediate,
                              Mask, Zeroable))
    return SDValue();

  // Create a REAL zero vector - ISD::isBuildVectorAllZeros allows UNDEFs.
  if (ForceV1Zero)
    V1 = getZeroVector(VT, Subtarget, DAG, DL);
  if (ForceV2Zero)
    V2 = getZeroVector(VT, Subtarget, DAG, DL);

  return DAG.getNode(X86ISD::SHUFP, DL, VT, V1, V2,
                     DAG.getTargetConstant(Immediate, DL, MVT::i8));
}

// Look for {0, 8, 16, 24, 32, 40, 48, 56 } in the first 8 elements. Followed
// by zeroable elements in the remaining 24 elements. Turn this into two
// vmovqb instructions shuffled together.
static SDValue lowerShuffleAsVTRUNCAndUnpack(const SDLoc &DL, MVT VT,
                                             SDValue V1, SDValue V2,
                                             ArrayRef<int> Mask,
                                             const APInt &Zeroable,
                                             SelectionDAG &DAG) {
  assert(VT == MVT::v32i8 && "Unexpected type!");

  // The first 8 indices should be every 8th element.
  if (!isSequentialOrUndefInRange(Mask, 0, 8, 0, 8))
    return SDValue();

  // Remaining elements need to be zeroable.
  if (Zeroable.countLeadingOnes() < (Mask.size() - 8))
    return SDValue();

  V1 = DAG.getBitcast(MVT::v4i64, V1);
  V2 = DAG.getBitcast(MVT::v4i64, V2);

  V1 = DAG.getNode(X86ISD::VTRUNC, DL, MVT::v16i8, V1);
  V2 = DAG.getNode(X86ISD::VTRUNC, DL, MVT::v16i8, V2);

  // The VTRUNCs will put 0s in the upper 12 bytes. Use them to put zeroes in
  // the upper bits of the result using an unpckldq.
  SDValue Unpack = DAG.getVectorShuffle(MVT::v16i8, DL, V1, V2,
                                        { 0, 1, 2, 3, 16, 17, 18, 19,
                                          4, 5, 6, 7, 20, 21, 22, 23 });
  // Insert the unpckldq into a zero vector to widen to v32i8.
  return DAG.getNode(ISD::INSERT_SUBVECTOR, DL, MVT::v32i8,
                     DAG.getConstant(0, DL, MVT::v32i8), Unpack,
                     DAG.getIntPtrConstant(0, DL));
}


/// Handle lowering of 4-lane 64-bit floating point shuffles.
///
/// Also ends up handling lowering of 4-lane 64-bit integer shuffles when AVX2
/// isn't available.
static SDValue lowerV4F64Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
                                 const APInt &Zeroable, SDValue V1, SDValue V2,
                                 const X86Subtarget &Subtarget,
                                 SelectionDAG &DAG) {
  assert(V1.getSimpleValueType() == MVT::v4f64 && "Bad operand type!");
  assert(V2.getSimpleValueType() == MVT::v4f64 && "Bad operand type!");
  assert(Mask.size() == 4 && "Unexpected mask size for v4 shuffle!");

  if (SDValue V = lowerV2X128Shuffle(DL, MVT::v4f64, V1, V2, Mask, Zeroable,
                                     Subtarget, DAG))
    return V;

  if (V2.isUndef()) {
    // Check for being able to broadcast a single element.
    if (SDValue Broadcast = lowerShuffleAsBroadcast(DL, MVT::v4f64, V1, V2,
                                                    Mask, Subtarget, DAG))
      return Broadcast;

    // Use low duplicate instructions for masks that match their pattern.
    if (isShuffleEquivalent(V1, V2, Mask, {0, 0, 2, 2}))
      return DAG.getNode(X86ISD::MOVDDUP, DL, MVT::v4f64, V1);

    if (!is128BitLaneCrossingShuffleMask(MVT::v4f64, Mask)) {
      // Non-half-crossing single input shuffles can be lowered with an
      // interleaved permutation.
      unsigned VPERMILPMask = (Mask[0] == 1) | ((Mask[1] == 1) << 1) |
                              ((Mask[2] == 3) << 2) | ((Mask[3] == 3) << 3);
      return DAG.getNode(X86ISD::VPERMILPI, DL, MVT::v4f64, V1,
                         DAG.getTargetConstant(VPERMILPMask, DL, MVT::i8));
    }

    // With AVX2 we have direct support for this permutation.
    if (Subtarget.hasAVX2())
      return DAG.getNode(X86ISD::VPERMI, DL, MVT::v4f64, V1,
                         getV4X86ShuffleImm8ForMask(Mask, DL, DAG));

    // Try to create an in-lane repeating shuffle mask and then shuffle the
    // results into the target lanes.
    if (SDValue V = lowerShuffleAsRepeatedMaskAndLanePermute(
            DL, MVT::v4f64, V1, V2, Mask, Subtarget, DAG))
      return V;

    // Try to permute the lanes and then use a per-lane permute.
    if (SDValue V = lowerShuffleAsLanePermuteAndPermute(DL, MVT::v4f64, V1, V2,
                                                        Mask, DAG, Subtarget))
      return V;

    // Otherwise, fall back.
    return lowerShuffleAsLanePermuteAndShuffle(DL, MVT::v4f64, V1, V2, Mask,
                                               DAG, Subtarget);
  }

  // Use dedicated unpack instructions for masks that match their pattern.
  if (SDValue V = lowerShuffleWithUNPCK(DL, MVT::v4f64, Mask, V1, V2, DAG))
    return V;

  if (SDValue Blend = lowerShuffleAsBlend(DL, MVT::v4f64, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Blend;

  // Check if the blend happens to exactly fit that of SHUFPD.
  if (SDValue Op = lowerShuffleWithSHUFPD(DL, MVT::v4f64, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Op;

  // If we have lane crossing shuffles AND they don't all come from the lower
  // lane elements, lower to SHUFPD(VPERM2F128(V1, V2), VPERM2F128(V1, V2)).
  // TODO: Handle BUILD_VECTOR sources which getVectorShuffle currently
  // canonicalize to a blend of splat which isn't necessary for this combine.
  if (is128BitLaneCrossingShuffleMask(MVT::v4f64, Mask) &&
      !all_of(Mask, [](int M) { return M < 2 || (4 <= M && M < 6); }) &&
      (V1.getOpcode() != ISD::BUILD_VECTOR) &&
      (V2.getOpcode() != ISD::BUILD_VECTOR))
    if (SDValue Op = lowerShuffleAsLanePermuteAndSHUFP(DL, MVT::v4f64, V1, V2,
                                                       Mask, DAG))
      return Op;

  // If we have one input in place, then we can permute the other input and
  // blend the result.
  if (isShuffleMaskInputInPlace(0, Mask) || isShuffleMaskInputInPlace(1, Mask))
    return lowerShuffleAsDecomposedShuffleBlend(DL, MVT::v4f64, V1, V2, Mask,
                                                Subtarget, DAG);

  // Try to create an in-lane repeating shuffle mask and then shuffle the
  // results into the target lanes.
  if (SDValue V = lowerShuffleAsRepeatedMaskAndLanePermute(
          DL, MVT::v4f64, V1, V2, Mask, Subtarget, DAG))
    return V;

  // Try to simplify this by merging 128-bit lanes to enable a lane-based
  // shuffle. However, if we have AVX2 and either inputs are already in place,
  // we will be able to shuffle even across lanes the other input in a single
  // instruction so skip this pattern.
  if (!(Subtarget.hasAVX2() && (isShuffleMaskInputInPlace(0, Mask) ||
                                isShuffleMaskInputInPlace(1, Mask))))
    if (SDValue V = lowerShuffleAsLanePermuteAndRepeatedMask(
            DL, MVT::v4f64, V1, V2, Mask, Subtarget, DAG))
      return V;

  // If we have VLX support, we can use VEXPAND.
  if (Subtarget.hasVLX())
    if (SDValue V = lowerShuffleToEXPAND(DL, MVT::v4f64, Zeroable, Mask, V1, V2,
                                         DAG, Subtarget))
      return V;

  // If we have AVX2 then we always want to lower with a blend because an v4 we
  // can fully permute the elements.
  if (Subtarget.hasAVX2())
    return lowerShuffleAsDecomposedShuffleBlend(DL, MVT::v4f64, V1, V2, Mask,
                                                Subtarget, DAG);

  // Otherwise fall back on generic lowering.
  return lowerShuffleAsSplitOrBlend(DL, MVT::v4f64, V1, V2, Mask,
                                    Subtarget, DAG);
}

/// Handle lowering of 4-lane 64-bit integer shuffles.
///
/// This routine is only called when we have AVX2 and thus a reasonable
/// instruction set for v4i64 shuffling..
static SDValue lowerV4I64Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
                                 const APInt &Zeroable, SDValue V1, SDValue V2,
                                 const X86Subtarget &Subtarget,
                                 SelectionDAG &DAG) {
  assert(V1.getSimpleValueType() == MVT::v4i64 && "Bad operand type!");
  assert(V2.getSimpleValueType() == MVT::v4i64 && "Bad operand type!");
  assert(Mask.size() == 4 && "Unexpected mask size for v4 shuffle!");
  assert(Subtarget.hasAVX2() && "We can only lower v4i64 with AVX2!");

  if (SDValue V = lowerV2X128Shuffle(DL, MVT::v4i64, V1, V2, Mask, Zeroable,
                                     Subtarget, DAG))
    return V;

  if (SDValue Blend = lowerShuffleAsBlend(DL, MVT::v4i64, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Blend;

  // Check for being able to broadcast a single element.
  if (SDValue Broadcast = lowerShuffleAsBroadcast(DL, MVT::v4i64, V1, V2, Mask,
                                                  Subtarget, DAG))
    return Broadcast;

  if (V2.isUndef()) {
    // When the shuffle is mirrored between the 128-bit lanes of the unit, we
    // can use lower latency instructions that will operate on both lanes.
    SmallVector<int, 2> RepeatedMask;
    if (is128BitLaneRepeatedShuffleMask(MVT::v4i64, Mask, RepeatedMask)) {
      SmallVector<int, 4> PSHUFDMask;
      scaleShuffleMask(2, RepeatedMask, PSHUFDMask);
      return DAG.getBitcast(
          MVT::v4i64,
          DAG.getNode(X86ISD::PSHUFD, DL, MVT::v8i32,
                      DAG.getBitcast(MVT::v8i32, V1),
                      getV4X86ShuffleImm8ForMask(PSHUFDMask, DL, DAG)));
    }

    // AVX2 provides a direct instruction for permuting a single input across
    // lanes.
    return DAG.getNode(X86ISD::VPERMI, DL, MVT::v4i64, V1,
                       getV4X86ShuffleImm8ForMask(Mask, DL, DAG));
  }

  // Try to use shift instructions.
  if (SDValue Shift = lowerShuffleAsShift(DL, MVT::v4i64, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Shift;

  // If we have VLX support, we can use VALIGN or VEXPAND.
  if (Subtarget.hasVLX()) {
    if (SDValue Rotate = lowerShuffleAsVALIGN(DL, MVT::v4i64, V1, V2, Mask,
                                              Subtarget, DAG))
      return Rotate;

    if (SDValue V = lowerShuffleToEXPAND(DL, MVT::v4i64, Zeroable, Mask, V1, V2,
                                         DAG, Subtarget))
      return V;
  }

  // Try to use PALIGNR.
  if (SDValue Rotate = lowerShuffleAsByteRotate(DL, MVT::v4i64, V1, V2, Mask,
                                                Subtarget, DAG))
    return Rotate;

  // Use dedicated unpack instructions for masks that match their pattern.
  if (SDValue V = lowerShuffleWithUNPCK(DL, MVT::v4i64, Mask, V1, V2, DAG))
    return V;

  // If we have one input in place, then we can permute the other input and
  // blend the result.
  if (isShuffleMaskInputInPlace(0, Mask) || isShuffleMaskInputInPlace(1, Mask))
    return lowerShuffleAsDecomposedShuffleBlend(DL, MVT::v4i64, V1, V2, Mask,
                                                Subtarget, DAG);

  // Try to create an in-lane repeating shuffle mask and then shuffle the
  // results into the target lanes.
  if (SDValue V = lowerShuffleAsRepeatedMaskAndLanePermute(
          DL, MVT::v4i64, V1, V2, Mask, Subtarget, DAG))
    return V;

  // Try to simplify this by merging 128-bit lanes to enable a lane-based
  // shuffle. However, if we have AVX2 and either inputs are already in place,
  // we will be able to shuffle even across lanes the other input in a single
  // instruction so skip this pattern.
  if (!isShuffleMaskInputInPlace(0, Mask) &&
      !isShuffleMaskInputInPlace(1, Mask))
    if (SDValue Result = lowerShuffleAsLanePermuteAndRepeatedMask(
            DL, MVT::v4i64, V1, V2, Mask, Subtarget, DAG))
      return Result;

  // Otherwise fall back on generic blend lowering.
  return lowerShuffleAsDecomposedShuffleBlend(DL, MVT::v4i64, V1, V2, Mask,
                                              Subtarget, DAG);
}

/// Handle lowering of 8-lane 32-bit floating point shuffles.
///
/// Also ends up handling lowering of 8-lane 32-bit integer shuffles when AVX2
/// isn't available.
static SDValue lowerV8F32Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
                                 const APInt &Zeroable, SDValue V1, SDValue V2,
                                 const X86Subtarget &Subtarget,
                                 SelectionDAG &DAG) {
  assert(V1.getSimpleValueType() == MVT::v8f32 && "Bad operand type!");
  assert(V2.getSimpleValueType() == MVT::v8f32 && "Bad operand type!");
  assert(Mask.size() == 8 && "Unexpected mask size for v8 shuffle!");

  if (SDValue Blend = lowerShuffleAsBlend(DL, MVT::v8f32, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Blend;

  // Check for being able to broadcast a single element.
  if (SDValue Broadcast = lowerShuffleAsBroadcast(DL, MVT::v8f32, V1, V2, Mask,
                                                  Subtarget, DAG))
    return Broadcast;

  // If the shuffle mask is repeated in each 128-bit lane, we have many more
  // options to efficiently lower the shuffle.
  SmallVector<int, 4> RepeatedMask;
  if (is128BitLaneRepeatedShuffleMask(MVT::v8f32, Mask, RepeatedMask)) {
    assert(RepeatedMask.size() == 4 &&
           "Repeated masks must be half the mask width!");

    // Use even/odd duplicate instructions for masks that match their pattern.
    if (isShuffleEquivalent(V1, V2, RepeatedMask, {0, 0, 2, 2}))
      return DAG.getNode(X86ISD::MOVSLDUP, DL, MVT::v8f32, V1);
    if (isShuffleEquivalent(V1, V2, RepeatedMask, {1, 1, 3, 3}))
      return DAG.getNode(X86ISD::MOVSHDUP, DL, MVT::v8f32, V1);

    if (V2.isUndef())
      return DAG.getNode(X86ISD::VPERMILPI, DL, MVT::v8f32, V1,
                         getV4X86ShuffleImm8ForMask(RepeatedMask, DL, DAG));

    // Use dedicated unpack instructions for masks that match their pattern.
    if (SDValue V = lowerShuffleWithUNPCK(DL, MVT::v8f32, Mask, V1, V2, DAG))
      return V;

    // Otherwise, fall back to a SHUFPS sequence. Here it is important that we
    // have already handled any direct blends.
    return lowerShuffleWithSHUFPS(DL, MVT::v8f32, RepeatedMask, V1, V2, DAG);
  }

  // Try to create an in-lane repeating shuffle mask and then shuffle the
  // results into the target lanes.
  if (SDValue V = lowerShuffleAsRepeatedMaskAndLanePermute(
          DL, MVT::v8f32, V1, V2, Mask, Subtarget, DAG))
    return V;

  // If we have a single input shuffle with different shuffle patterns in the
  // two 128-bit lanes use the variable mask to VPERMILPS.
  if (V2.isUndef()) {
    if (!is128BitLaneCrossingShuffleMask(MVT::v8f32, Mask)) {
      SDValue VPermMask = getConstVector(Mask, MVT::v8i32, DAG, DL, true);
      return DAG.getNode(X86ISD::VPERMILPV, DL, MVT::v8f32, V1, VPermMask);
    }
    if (Subtarget.hasAVX2()) {
      SDValue VPermMask = getConstVector(Mask, MVT::v8i32, DAG, DL, true);
      return DAG.getNode(X86ISD::VPERMV, DL, MVT::v8f32, VPermMask, V1);
    }
    // Otherwise, fall back.
    return lowerShuffleAsLanePermuteAndShuffle(DL, MVT::v8f32, V1, V2, Mask,
                                               DAG, Subtarget);
  }

  // Try to simplify this by merging 128-bit lanes to enable a lane-based
  // shuffle.
  if (SDValue Result = lowerShuffleAsLanePermuteAndRepeatedMask(
          DL, MVT::v8f32, V1, V2, Mask, Subtarget, DAG))
    return Result;

  // If we have VLX support, we can use VEXPAND.
  if (Subtarget.hasVLX())
    if (SDValue V = lowerShuffleToEXPAND(DL, MVT::v8f32, Zeroable, Mask, V1, V2,
                                         DAG, Subtarget))
      return V;

  // For non-AVX512 if the Mask is of 16bit elements in lane then try to split
  // since after split we get a more efficient code using vpunpcklwd and
  // vpunpckhwd instrs than vblend.
  if (!Subtarget.hasAVX512() && isUnpackWdShuffleMask(Mask, MVT::v8f32))
    if (SDValue V = lowerShuffleAsSplitOrBlend(DL, MVT::v8f32, V1, V2, Mask,
                                               Subtarget, DAG))
      return V;

  // If we have AVX2 then we always want to lower with a blend because at v8 we
  // can fully permute the elements.
  if (Subtarget.hasAVX2())
    return lowerShuffleAsDecomposedShuffleBlend(DL, MVT::v8f32, V1, V2, Mask,
                                                Subtarget, DAG);

  // Otherwise fall back on generic lowering.
  return lowerShuffleAsSplitOrBlend(DL, MVT::v8f32, V1, V2, Mask,
                                    Subtarget, DAG);
}

/// Handle lowering of 8-lane 32-bit integer shuffles.
///
/// This routine is only called when we have AVX2 and thus a reasonable
/// instruction set for v8i32 shuffling..
static SDValue lowerV8I32Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
                                 const APInt &Zeroable, SDValue V1, SDValue V2,
                                 const X86Subtarget &Subtarget,
                                 SelectionDAG &DAG) {
  assert(V1.getSimpleValueType() == MVT::v8i32 && "Bad operand type!");
  assert(V2.getSimpleValueType() == MVT::v8i32 && "Bad operand type!");
  assert(Mask.size() == 8 && "Unexpected mask size for v8 shuffle!");
  assert(Subtarget.hasAVX2() && "We can only lower v8i32 with AVX2!");

  // Whenever we can lower this as a zext, that instruction is strictly faster
  // than any alternative. It also allows us to fold memory operands into the
  // shuffle in many cases.
  if (SDValue ZExt = lowerShuffleAsZeroOrAnyExtend(DL, MVT::v8i32, V1, V2, Mask,
                                                   Zeroable, Subtarget, DAG))
    return ZExt;

  // For non-AVX512 if the Mask is of 16bit elements in lane then try to split
  // since after split we get a more efficient code than vblend by using
  // vpunpcklwd and vpunpckhwd instrs.
  if (isUnpackWdShuffleMask(Mask, MVT::v8i32) && !V2.isUndef() &&
      !Subtarget.hasAVX512())
    if (SDValue V = lowerShuffleAsSplitOrBlend(DL, MVT::v8i32, V1, V2, Mask,
                                               Subtarget, DAG))
      return V;

  if (SDValue Blend = lowerShuffleAsBlend(DL, MVT::v8i32, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Blend;

  // Check for being able to broadcast a single element.
  if (SDValue Broadcast = lowerShuffleAsBroadcast(DL, MVT::v8i32, V1, V2, Mask,
                                                  Subtarget, DAG))
    return Broadcast;

  // If the shuffle mask is repeated in each 128-bit lane we can use more
  // efficient instructions that mirror the shuffles across the two 128-bit
  // lanes.
  SmallVector<int, 4> RepeatedMask;
  bool Is128BitLaneRepeatedShuffle =
      is128BitLaneRepeatedShuffleMask(MVT::v8i32, Mask, RepeatedMask);
  if (Is128BitLaneRepeatedShuffle) {
    assert(RepeatedMask.size() == 4 && "Unexpected repeated mask size!");
    if (V2.isUndef())
      return DAG.getNode(X86ISD::PSHUFD, DL, MVT::v8i32, V1,
                         getV4X86ShuffleImm8ForMask(RepeatedMask, DL, DAG));

    // Use dedicated unpack instructions for masks that match their pattern.
    if (SDValue V = lowerShuffleWithUNPCK(DL, MVT::v8i32, Mask, V1, V2, DAG))
      return V;
  }

  // Try to use shift instructions.
  if (SDValue Shift = lowerShuffleAsShift(DL, MVT::v8i32, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Shift;

  // If we have VLX support, we can use VALIGN or EXPAND.
  if (Subtarget.hasVLX()) {
    if (SDValue Rotate = lowerShuffleAsVALIGN(DL, MVT::v8i32, V1, V2, Mask,
                                              Subtarget, DAG))
      return Rotate;

    if (SDValue V = lowerShuffleToEXPAND(DL, MVT::v8i32, Zeroable, Mask, V1, V2,
                                         DAG, Subtarget))
      return V;
  }

  // Try to use byte rotation instructions.
  if (SDValue Rotate = lowerShuffleAsByteRotate(DL, MVT::v8i32, V1, V2, Mask,
                                                Subtarget, DAG))
    return Rotate;

  // Try to create an in-lane repeating shuffle mask and then shuffle the
  // results into the target lanes.
  if (SDValue V = lowerShuffleAsRepeatedMaskAndLanePermute(
          DL, MVT::v8i32, V1, V2, Mask, Subtarget, DAG))
    return V;

  if (V2.isUndef()) {
    // Try to produce a fixed cross-128-bit lane permute followed by unpack
    // because that should be faster than the variable permute alternatives.
    if (SDValue V = lowerShuffleWithUNPCK256(DL, MVT::v8i32, Mask, V1, V2, DAG))
      return V;

    // If the shuffle patterns aren't repeated but it's a single input, directly
    // generate a cross-lane VPERMD instruction.
    SDValue VPermMask = getConstVector(Mask, MVT::v8i32, DAG, DL, true);
    return DAG.getNode(X86ISD::VPERMV, DL, MVT::v8i32, VPermMask, V1);
  }

  // Assume that a single SHUFPS is faster than an alternative sequence of
  // multiple instructions (even if the CPU has a domain penalty).
  // If some CPU is harmed by the domain switch, we can fix it in a later pass.
  if (Is128BitLaneRepeatedShuffle && isSingleSHUFPSMask(RepeatedMask)) {
    SDValue CastV1 = DAG.getBitcast(MVT::v8f32, V1);
    SDValue CastV2 = DAG.getBitcast(MVT::v8f32, V2);
    SDValue ShufPS = lowerShuffleWithSHUFPS(DL, MVT::v8f32, RepeatedMask,
                                            CastV1, CastV2, DAG);
    return DAG.getBitcast(MVT::v8i32, ShufPS);
  }

  // Try to simplify this by merging 128-bit lanes to enable a lane-based
  // shuffle.
  if (SDValue Result = lowerShuffleAsLanePermuteAndRepeatedMask(
          DL, MVT::v8i32, V1, V2, Mask, Subtarget, DAG))
    return Result;

  // Otherwise fall back on generic blend lowering.
  return lowerShuffleAsDecomposedShuffleBlend(DL, MVT::v8i32, V1, V2, Mask,
                                              Subtarget, DAG);
}

/// Handle lowering of 16-lane 16-bit integer shuffles.
///
/// This routine is only called when we have AVX2 and thus a reasonable
/// instruction set for v16i16 shuffling..
static SDValue lowerV16I16Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
                                  const APInt &Zeroable, SDValue V1, SDValue V2,
                                  const X86Subtarget &Subtarget,
                                  SelectionDAG &DAG) {
  assert(V1.getSimpleValueType() == MVT::v16i16 && "Bad operand type!");
  assert(V2.getSimpleValueType() == MVT::v16i16 && "Bad operand type!");
  assert(Mask.size() == 16 && "Unexpected mask size for v16 shuffle!");
  assert(Subtarget.hasAVX2() && "We can only lower v16i16 with AVX2!");

  // Whenever we can lower this as a zext, that instruction is strictly faster
  // than any alternative. It also allows us to fold memory operands into the
  // shuffle in many cases.
  if (SDValue ZExt = lowerShuffleAsZeroOrAnyExtend(
          DL, MVT::v16i16, V1, V2, Mask, Zeroable, Subtarget, DAG))
    return ZExt;

  // Check for being able to broadcast a single element.
  if (SDValue Broadcast = lowerShuffleAsBroadcast(DL, MVT::v16i16, V1, V2, Mask,
                                                  Subtarget, DAG))
    return Broadcast;

  if (SDValue Blend = lowerShuffleAsBlend(DL, MVT::v16i16, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Blend;

  // Use dedicated unpack instructions for masks that match their pattern.
  if (SDValue V = lowerShuffleWithUNPCK(DL, MVT::v16i16, Mask, V1, V2, DAG))
    return V;

  // Use dedicated pack instructions for masks that match their pattern.
  if (SDValue V = lowerShuffleWithPACK(DL, MVT::v16i16, Mask, V1, V2, DAG,
                                       Subtarget))
    return V;

  // Try to use shift instructions.
  if (SDValue Shift = lowerShuffleAsShift(DL, MVT::v16i16, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Shift;

  // Try to use byte rotation instructions.
  if (SDValue Rotate = lowerShuffleAsByteRotate(DL, MVT::v16i16, V1, V2, Mask,
                                                Subtarget, DAG))
    return Rotate;

  // Try to create an in-lane repeating shuffle mask and then shuffle the
  // results into the target lanes.
  if (SDValue V = lowerShuffleAsRepeatedMaskAndLanePermute(
          DL, MVT::v16i16, V1, V2, Mask, Subtarget, DAG))
    return V;

  if (V2.isUndef()) {
    // Try to use bit rotation instructions.
    if (SDValue Rotate =
            lowerShuffleAsBitRotate(DL, MVT::v16i16, V1, Mask, Subtarget, DAG))
      return Rotate;

    // Try to produce a fixed cross-128-bit lane permute followed by unpack
    // because that should be faster than the variable permute alternatives.
    if (SDValue V = lowerShuffleWithUNPCK256(DL, MVT::v16i16, Mask, V1, V2, DAG))
      return V;

    // There are no generalized cross-lane shuffle operations available on i16
    // element types.
    if (is128BitLaneCrossingShuffleMask(MVT::v16i16, Mask)) {
      if (SDValue V = lowerShuffleAsLanePermuteAndPermute(
              DL, MVT::v16i16, V1, V2, Mask, DAG, Subtarget))
        return V;

      return lowerShuffleAsLanePermuteAndShuffle(DL, MVT::v16i16, V1, V2, Mask,
                                                 DAG, Subtarget);
    }

    SmallVector<int, 8> RepeatedMask;
    if (is128BitLaneRepeatedShuffleMask(MVT::v16i16, Mask, RepeatedMask)) {
      // As this is a single-input shuffle, the repeated mask should be
      // a strictly valid v8i16 mask that we can pass through to the v8i16
      // lowering to handle even the v16 case.
      return lowerV8I16GeneralSingleInputShuffle(
          DL, MVT::v16i16, V1, RepeatedMask, Subtarget, DAG);
    }
  }

  if (SDValue PSHUFB = lowerShuffleWithPSHUFB(DL, MVT::v16i16, Mask, V1, V2,
                                              Zeroable, Subtarget, DAG))
    return PSHUFB;

  // AVX512BWVL can lower to VPERMW.
  if (Subtarget.hasBWI() && Subtarget.hasVLX())
    return lowerShuffleWithPERMV(DL, MVT::v16i16, Mask, V1, V2, DAG);

  // Try to simplify this by merging 128-bit lanes to enable a lane-based
  // shuffle.
  if (SDValue Result = lowerShuffleAsLanePermuteAndRepeatedMask(
          DL, MVT::v16i16, V1, V2, Mask, Subtarget, DAG))
    return Result;

  // Try to permute the lanes and then use a per-lane permute.
  if (SDValue V = lowerShuffleAsLanePermuteAndPermute(
          DL, MVT::v16i16, V1, V2, Mask, DAG, Subtarget))
    return V;

  // Otherwise fall back on generic lowering.
  return lowerShuffleAsSplitOrBlend(DL, MVT::v16i16, V1, V2, Mask,
                                    Subtarget, DAG);
}

/// Handle lowering of 32-lane 8-bit integer shuffles.
///
/// This routine is only called when we have AVX2 and thus a reasonable
/// instruction set for v32i8 shuffling..
static SDValue lowerV32I8Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
                                 const APInt &Zeroable, SDValue V1, SDValue V2,
                                 const X86Subtarget &Subtarget,
                                 SelectionDAG &DAG) {
  assert(V1.getSimpleValueType() == MVT::v32i8 && "Bad operand type!");
  assert(V2.getSimpleValueType() == MVT::v32i8 && "Bad operand type!");
  assert(Mask.size() == 32 && "Unexpected mask size for v32 shuffle!");
  assert(Subtarget.hasAVX2() && "We can only lower v32i8 with AVX2!");

  // Whenever we can lower this as a zext, that instruction is strictly faster
  // than any alternative. It also allows us to fold memory operands into the
  // shuffle in many cases.
  if (SDValue ZExt = lowerShuffleAsZeroOrAnyExtend(DL, MVT::v32i8, V1, V2, Mask,
                                                   Zeroable, Subtarget, DAG))
    return ZExt;

  // Check for being able to broadcast a single element.
  if (SDValue Broadcast = lowerShuffleAsBroadcast(DL, MVT::v32i8, V1, V2, Mask,
                                                  Subtarget, DAG))
    return Broadcast;

  if (SDValue Blend = lowerShuffleAsBlend(DL, MVT::v32i8, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Blend;

  // Use dedicated unpack instructions for masks that match their pattern.
  if (SDValue V = lowerShuffleWithUNPCK(DL, MVT::v32i8, Mask, V1, V2, DAG))
    return V;

  // Use dedicated pack instructions for masks that match their pattern.
  if (SDValue V = lowerShuffleWithPACK(DL, MVT::v32i8, Mask, V1, V2, DAG,
                                       Subtarget))
    return V;

  // Try to use shift instructions.
  if (SDValue Shift = lowerShuffleAsShift(DL, MVT::v32i8, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Shift;

  // Try to use byte rotation instructions.
  if (SDValue Rotate = lowerShuffleAsByteRotate(DL, MVT::v32i8, V1, V2, Mask,
                                                Subtarget, DAG))
    return Rotate;

  // Try to use bit rotation instructions.
  if (V2.isUndef())
    if (SDValue Rotate =
            lowerShuffleAsBitRotate(DL, MVT::v32i8, V1, Mask, Subtarget, DAG))
      return Rotate;

  // Try to create an in-lane repeating shuffle mask and then shuffle the
  // results into the target lanes.
  if (SDValue V = lowerShuffleAsRepeatedMaskAndLanePermute(
          DL, MVT::v32i8, V1, V2, Mask, Subtarget, DAG))
    return V;

  // There are no generalized cross-lane shuffle operations available on i8
  // element types.
  if (V2.isUndef() && is128BitLaneCrossingShuffleMask(MVT::v32i8, Mask)) {
    // Try to produce a fixed cross-128-bit lane permute followed by unpack
    // because that should be faster than the variable permute alternatives.
    if (SDValue V = lowerShuffleWithUNPCK256(DL, MVT::v32i8, Mask, V1, V2, DAG))
      return V;

    if (SDValue V = lowerShuffleAsLanePermuteAndPermute(
            DL, MVT::v32i8, V1, V2, Mask, DAG, Subtarget))
      return V;

    return lowerShuffleAsLanePermuteAndShuffle(DL, MVT::v32i8, V1, V2, Mask,
                                               DAG, Subtarget);
  }

  if (SDValue PSHUFB = lowerShuffleWithPSHUFB(DL, MVT::v32i8, Mask, V1, V2,
                                              Zeroable, Subtarget, DAG))
    return PSHUFB;

  // AVX512VBMIVL can lower to VPERMB.
  if (Subtarget.hasVBMI() && Subtarget.hasVLX())
    return lowerShuffleWithPERMV(DL, MVT::v32i8, Mask, V1, V2, DAG);

  // Try to simplify this by merging 128-bit lanes to enable a lane-based
  // shuffle.
  if (SDValue Result = lowerShuffleAsLanePermuteAndRepeatedMask(
          DL, MVT::v32i8, V1, V2, Mask, Subtarget, DAG))
    return Result;

  // Try to permute the lanes and then use a per-lane permute.
  if (SDValue V = lowerShuffleAsLanePermuteAndPermute(
          DL, MVT::v32i8, V1, V2, Mask, DAG, Subtarget))
    return V;

  // Look for {0, 8, 16, 24, 32, 40, 48, 56 } in the first 8 elements. Followed
  // by zeroable elements in the remaining 24 elements. Turn this into two
  // vmovqb instructions shuffled together.
  if (Subtarget.hasVLX())
    if (SDValue V = lowerShuffleAsVTRUNCAndUnpack(DL, MVT::v32i8, V1, V2,
                                                  Mask, Zeroable, DAG))
      return V;

  // Otherwise fall back on generic lowering.
  return lowerShuffleAsSplitOrBlend(DL, MVT::v32i8, V1, V2, Mask,
                                    Subtarget, DAG);
}

/// High-level routine to lower various 256-bit x86 vector shuffles.
///
/// This routine either breaks down the specific type of a 256-bit x86 vector
/// shuffle or splits it into two 128-bit shuffles and fuses the results back
/// together based on the available instructions.
static SDValue lower256BitShuffle(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
                                  SDValue V1, SDValue V2, const APInt &Zeroable,
                                  const X86Subtarget &Subtarget,
                                  SelectionDAG &DAG) {
  // If we have a single input to the zero element, insert that into V1 if we
  // can do so cheaply.
  int NumElts = VT.getVectorNumElements();
  int NumV2Elements = count_if(Mask, [NumElts](int M) { return M >= NumElts; });

  if (NumV2Elements == 1 && Mask[0] >= NumElts)
    if (SDValue Insertion = lowerShuffleAsElementInsertion(
            DL, VT, V1, V2, Mask, Zeroable, Subtarget, DAG))
      return Insertion;

  // Handle special cases where the lower or upper half is UNDEF.
  if (SDValue V =
          lowerShuffleWithUndefHalf(DL, VT, V1, V2, Mask, Subtarget, DAG))
    return V;

  // There is a really nice hard cut-over between AVX1 and AVX2 that means we
  // can check for those subtargets here and avoid much of the subtarget
  // querying in the per-vector-type lowering routines. With AVX1 we have
  // essentially *zero* ability to manipulate a 256-bit vector with integer
  // types. Since we'll use floating point types there eventually, just
  // immediately cast everything to a float and operate entirely in that domain.
  if (VT.isInteger() && !Subtarget.hasAVX2()) {
    int ElementBits = VT.getScalarSizeInBits();
    if (ElementBits < 32) {
      // No floating point type available, if we can't use the bit operations
      // for masking/blending then decompose into 128-bit vectors.
      if (SDValue V = lowerShuffleAsBitMask(DL, VT, V1, V2, Mask, Zeroable,
                                            Subtarget, DAG))
        return V;
      if (SDValue V = lowerShuffleAsBitBlend(DL, VT, V1, V2, Mask, DAG))
        return V;
      return splitAndLowerShuffle(DL, VT, V1, V2, Mask, DAG);
    }

    MVT FpVT = MVT::getVectorVT(MVT::getFloatingPointVT(ElementBits),
                                VT.getVectorNumElements());
    V1 = DAG.getBitcast(FpVT, V1);
    V2 = DAG.getBitcast(FpVT, V2);
    return DAG.getBitcast(VT, DAG.getVectorShuffle(FpVT, DL, V1, V2, Mask));
  }

  switch (VT.SimpleTy) {
  case MVT::v4f64:
    return lowerV4F64Shuffle(DL, Mask, Zeroable, V1, V2, Subtarget, DAG);
  case MVT::v4i64:
    return lowerV4I64Shuffle(DL, Mask, Zeroable, V1, V2, Subtarget, DAG);
  case MVT::v8f32:
    return lowerV8F32Shuffle(DL, Mask, Zeroable, V1, V2, Subtarget, DAG);
  case MVT::v8i32:
    return lowerV8I32Shuffle(DL, Mask, Zeroable, V1, V2, Subtarget, DAG);
  case MVT::v16i16:
    return lowerV16I16Shuffle(DL, Mask, Zeroable, V1, V2, Subtarget, DAG);
  case MVT::v32i8:
    return lowerV32I8Shuffle(DL, Mask, Zeroable, V1, V2, Subtarget, DAG);

  default:
    llvm_unreachable("Not a valid 256-bit x86 vector type!");
  }
}

/// Try to lower a vector shuffle as a 128-bit shuffles.
static SDValue lowerV4X128Shuffle(const SDLoc &DL, MVT VT, ArrayRef<int> Mask,
                                  const APInt &Zeroable, SDValue V1, SDValue V2,
                                  const X86Subtarget &Subtarget,
                                  SelectionDAG &DAG) {
  assert(VT.getScalarSizeInBits() == 64 &&
         "Unexpected element type size for 128bit shuffle.");

  // To handle 256 bit vector requires VLX and most probably
  // function lowerV2X128VectorShuffle() is better solution.
  assert(VT.is512BitVector() && "Unexpected vector size for 512bit shuffle.");

  // TODO - use Zeroable like we do for lowerV2X128VectorShuffle?
  SmallVector<int, 4> Widened128Mask;
  if (!canWidenShuffleElements(Mask, Widened128Mask))
    return SDValue();
  assert(Widened128Mask.size() == 4 && "Shuffle widening mismatch");

  // Try to use an insert into a zero vector.
  if (Widened128Mask[0] == 0 && (Zeroable & 0xf0) == 0xf0 &&
      (Widened128Mask[1] == 1 || (Zeroable & 0x0c) == 0x0c)) {
    unsigned NumElts = ((Zeroable & 0x0c) == 0x0c) ? 2 : 4;
    MVT SubVT = MVT::getVectorVT(VT.getVectorElementType(), NumElts);
    SDValue LoV = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SubVT, V1,
                              DAG.getIntPtrConstant(0, DL));
    return DAG.getNode(ISD::INSERT_SUBVECTOR, DL, VT,
                       getZeroVector(VT, Subtarget, DAG, DL), LoV,
                       DAG.getIntPtrConstant(0, DL));
  }

  // Check for patterns which can be matched with a single insert of a 256-bit
  // subvector.
  bool OnlyUsesV1 = isShuffleEquivalent(V1, V2, Mask, {0, 1, 2, 3, 0, 1, 2, 3});
  if (OnlyUsesV1 ||
      isShuffleEquivalent(V1, V2, Mask, {0, 1, 2, 3, 8, 9, 10, 11})) {
    MVT SubVT = MVT::getVectorVT(VT.getVectorElementType(), 4);
    SDValue SubVec =
        DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SubVT, OnlyUsesV1 ? V1 : V2,
                    DAG.getIntPtrConstant(0, DL));
    return DAG.getNode(ISD::INSERT_SUBVECTOR, DL, VT, V1, SubVec,
                       DAG.getIntPtrConstant(4, DL));
  }

  // See if this is an insertion of the lower 128-bits of V2 into V1.
  bool IsInsert = true;
  int V2Index = -1;
  for (int i = 0; i < 4; ++i) {
    assert(Widened128Mask[i] >= -1 && "Illegal shuffle sentinel value");
    if (Widened128Mask[i] < 0)
      continue;

    // Make sure all V1 subvectors are in place.
    if (Widened128Mask[i] < 4) {
      if (Widened128Mask[i] != i) {
        IsInsert = false;
        break;
      }
    } else {
      // Make sure we only have a single V2 index and its the lowest 128-bits.
      if (V2Index >= 0 || Widened128Mask[i] != 4) {
        IsInsert = false;
        break;
      }
      V2Index = i;
    }
  }
  if (IsInsert && V2Index >= 0) {
    MVT SubVT = MVT::getVectorVT(VT.getVectorElementType(), 2);
    SDValue Subvec = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SubVT, V2,
                                 DAG.getIntPtrConstant(0, DL));
    return insert128BitVector(V1, Subvec, V2Index * 2, DAG, DL);
  }

  // See if we can widen to a 256-bit lane shuffle, we're going to lose 128-lane
  // UNDEF info by lowering to X86ISD::SHUF128 anyway, so by widening where
  // possible we at least ensure the lanes stay sequential to help later
  // combines.
  SmallVector<int, 2> Widened256Mask;
  if (canWidenShuffleElements(Widened128Mask, Widened256Mask)) {
    Widened128Mask.clear();
    llvm::scaleShuffleMask(2, Widened256Mask, Widened128Mask);
  }

  // Try to lower to vshuf64x2/vshuf32x4.
  SDValue Ops[2] = {DAG.getUNDEF(VT), DAG.getUNDEF(VT)};
  unsigned PermMask = 0;
  // Insure elements came from the same Op.
  for (int i = 0; i < 4; ++i) {
    assert(Widened128Mask[i] >= -1 && "Illegal shuffle sentinel value");
    if (Widened128Mask[i] < 0)
      continue;

    SDValue Op = Widened128Mask[i] >= 4 ? V2 : V1;
    unsigned OpIndex = i / 2;
    if (Ops[OpIndex].isUndef())
      Ops[OpIndex] = Op;
    else if (Ops[OpIndex] != Op)
      return SDValue();

    // Convert the 128-bit shuffle mask selection values into 128-bit selection
    // bits defined by a vshuf64x2 instruction's immediate control byte.
    PermMask |= (Widened128Mask[i] % 4) << (i * 2);
  }

  return DAG.getNode(X86ISD::SHUF128, DL, VT, Ops[0], Ops[1],
                     DAG.getTargetConstant(PermMask, DL, MVT::i8));
}

/// Handle lowering of 8-lane 64-bit floating point shuffles.
static SDValue lowerV8F64Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
                                 const APInt &Zeroable, SDValue V1, SDValue V2,
                                 const X86Subtarget &Subtarget,
                                 SelectionDAG &DAG) {
  assert(V1.getSimpleValueType() == MVT::v8f64 && "Bad operand type!");
  assert(V2.getSimpleValueType() == MVT::v8f64 && "Bad operand type!");
  assert(Mask.size() == 8 && "Unexpected mask size for v8 shuffle!");

  if (V2.isUndef()) {
    // Use low duplicate instructions for masks that match their pattern.
    if (isShuffleEquivalent(V1, V2, Mask, {0, 0, 2, 2, 4, 4, 6, 6}))
      return DAG.getNode(X86ISD::MOVDDUP, DL, MVT::v8f64, V1);

    if (!is128BitLaneCrossingShuffleMask(MVT::v8f64, Mask)) {
      // Non-half-crossing single input shuffles can be lowered with an
      // interleaved permutation.
      unsigned VPERMILPMask = (Mask[0] == 1) | ((Mask[1] == 1) << 1) |
                              ((Mask[2] == 3) << 2) | ((Mask[3] == 3) << 3) |
                              ((Mask[4] == 5) << 4) | ((Mask[5] == 5) << 5) |
                              ((Mask[6] == 7) << 6) | ((Mask[7] == 7) << 7);
      return DAG.getNode(X86ISD::VPERMILPI, DL, MVT::v8f64, V1,
                         DAG.getTargetConstant(VPERMILPMask, DL, MVT::i8));
    }

    SmallVector<int, 4> RepeatedMask;
    if (is256BitLaneRepeatedShuffleMask(MVT::v8f64, Mask, RepeatedMask))
      return DAG.getNode(X86ISD::VPERMI, DL, MVT::v8f64, V1,
                         getV4X86ShuffleImm8ForMask(RepeatedMask, DL, DAG));
  }

  if (SDValue Shuf128 = lowerV4X128Shuffle(DL, MVT::v8f64, Mask, Zeroable, V1,
                                           V2, Subtarget, DAG))
    return Shuf128;

  if (SDValue Unpck = lowerShuffleWithUNPCK(DL, MVT::v8f64, Mask, V1, V2, DAG))
    return Unpck;

  // Check if the blend happens to exactly fit that of SHUFPD.
  if (SDValue Op = lowerShuffleWithSHUFPD(DL, MVT::v8f64, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Op;

  if (SDValue V = lowerShuffleToEXPAND(DL, MVT::v8f64, Zeroable, Mask, V1, V2,
                                       DAG, Subtarget))
    return V;

  if (SDValue Blend = lowerShuffleAsBlend(DL, MVT::v8f64, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Blend;

  return lowerShuffleWithPERMV(DL, MVT::v8f64, Mask, V1, V2, DAG);
}

/// Handle lowering of 16-lane 32-bit floating point shuffles.
static SDValue lowerV16F32Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
                                  const APInt &Zeroable, SDValue V1, SDValue V2,
                                  const X86Subtarget &Subtarget,
                                  SelectionDAG &DAG) {
  assert(V1.getSimpleValueType() == MVT::v16f32 && "Bad operand type!");
  assert(V2.getSimpleValueType() == MVT::v16f32 && "Bad operand type!");
  assert(Mask.size() == 16 && "Unexpected mask size for v16 shuffle!");

  // If the shuffle mask is repeated in each 128-bit lane, we have many more
  // options to efficiently lower the shuffle.
  SmallVector<int, 4> RepeatedMask;
  if (is128BitLaneRepeatedShuffleMask(MVT::v16f32, Mask, RepeatedMask)) {
    assert(RepeatedMask.size() == 4 && "Unexpected repeated mask size!");

    // Use even/odd duplicate instructions for masks that match their pattern.
    if (isShuffleEquivalent(V1, V2, RepeatedMask, {0, 0, 2, 2}))
      return DAG.getNode(X86ISD::MOVSLDUP, DL, MVT::v16f32, V1);
    if (isShuffleEquivalent(V1, V2, RepeatedMask, {1, 1, 3, 3}))
      return DAG.getNode(X86ISD::MOVSHDUP, DL, MVT::v16f32, V1);

    if (V2.isUndef())
      return DAG.getNode(X86ISD::VPERMILPI, DL, MVT::v16f32, V1,
                         getV4X86ShuffleImm8ForMask(RepeatedMask, DL, DAG));

    // Use dedicated unpack instructions for masks that match their pattern.
    if (SDValue V = lowerShuffleWithUNPCK(DL, MVT::v16f32, Mask, V1, V2, DAG))
      return V;

    if (SDValue Blend = lowerShuffleAsBlend(DL, MVT::v16f32, V1, V2, Mask,
                                            Zeroable, Subtarget, DAG))
      return Blend;

    // Otherwise, fall back to a SHUFPS sequence.
    return lowerShuffleWithSHUFPS(DL, MVT::v16f32, RepeatedMask, V1, V2, DAG);
  }

  // If we have a single input shuffle with different shuffle patterns in the
  // 128-bit lanes and don't lane cross, use variable mask VPERMILPS.
  if (V2.isUndef() &&
      !is128BitLaneCrossingShuffleMask(MVT::v16f32, Mask)) {
    SDValue VPermMask = getConstVector(Mask, MVT::v16i32, DAG, DL, true);
    return DAG.getNode(X86ISD::VPERMILPV, DL, MVT::v16f32, V1, VPermMask);
  }

  // If we have AVX512F support, we can use VEXPAND.
  if (SDValue V = lowerShuffleToEXPAND(DL, MVT::v16f32, Zeroable, Mask,
                                             V1, V2, DAG, Subtarget))
    return V;

  return lowerShuffleWithPERMV(DL, MVT::v16f32, Mask, V1, V2, DAG);
}

/// Handle lowering of 8-lane 64-bit integer shuffles.
static SDValue lowerV8I64Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
                                 const APInt &Zeroable, SDValue V1, SDValue V2,
                                 const X86Subtarget &Subtarget,
                                 SelectionDAG &DAG) {
  assert(V1.getSimpleValueType() == MVT::v8i64 && "Bad operand type!");
  assert(V2.getSimpleValueType() == MVT::v8i64 && "Bad operand type!");
  assert(Mask.size() == 8 && "Unexpected mask size for v8 shuffle!");

  if (V2.isUndef()) {
    // When the shuffle is mirrored between the 128-bit lanes of the unit, we
    // can use lower latency instructions that will operate on all four
    // 128-bit lanes.
    SmallVector<int, 2> Repeated128Mask;
    if (is128BitLaneRepeatedShuffleMask(MVT::v8i64, Mask, Repeated128Mask)) {
      SmallVector<int, 4> PSHUFDMask;
      scaleShuffleMask(2, Repeated128Mask, PSHUFDMask);
      return DAG.getBitcast(
          MVT::v8i64,
          DAG.getNode(X86ISD::PSHUFD, DL, MVT::v16i32,
                      DAG.getBitcast(MVT::v16i32, V1),
                      getV4X86ShuffleImm8ForMask(PSHUFDMask, DL, DAG)));
    }

    SmallVector<int, 4> Repeated256Mask;
    if (is256BitLaneRepeatedShuffleMask(MVT::v8i64, Mask, Repeated256Mask))
      return DAG.getNode(X86ISD::VPERMI, DL, MVT::v8i64, V1,
                         getV4X86ShuffleImm8ForMask(Repeated256Mask, DL, DAG));
  }

  if (SDValue Shuf128 = lowerV4X128Shuffle(DL, MVT::v8i64, Mask, Zeroable, V1,
                                           V2, Subtarget, DAG))
    return Shuf128;

  // Try to use shift instructions.
  if (SDValue Shift = lowerShuffleAsShift(DL, MVT::v8i64, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Shift;

  // Try to use VALIGN.
  if (SDValue Rotate = lowerShuffleAsVALIGN(DL, MVT::v8i64, V1, V2, Mask,
                                            Subtarget, DAG))
    return Rotate;

  // Try to use PALIGNR.
  if (SDValue Rotate = lowerShuffleAsByteRotate(DL, MVT::v8i64, V1, V2, Mask,
                                                Subtarget, DAG))
    return Rotate;

  if (SDValue Unpck = lowerShuffleWithUNPCK(DL, MVT::v8i64, Mask, V1, V2, DAG))
    return Unpck;
  // If we have AVX512F support, we can use VEXPAND.
  if (SDValue V = lowerShuffleToEXPAND(DL, MVT::v8i64, Zeroable, Mask, V1, V2,
                                       DAG, Subtarget))
    return V;

  if (SDValue Blend = lowerShuffleAsBlend(DL, MVT::v8i64, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Blend;

  return lowerShuffleWithPERMV(DL, MVT::v8i64, Mask, V1, V2, DAG);
}

/// Handle lowering of 16-lane 32-bit integer shuffles.
static SDValue lowerV16I32Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
                                  const APInt &Zeroable, SDValue V1, SDValue V2,
                                  const X86Subtarget &Subtarget,
                                  SelectionDAG &DAG) {
  assert(V1.getSimpleValueType() == MVT::v16i32 && "Bad operand type!");
  assert(V2.getSimpleValueType() == MVT::v16i32 && "Bad operand type!");
  assert(Mask.size() == 16 && "Unexpected mask size for v16 shuffle!");

  // Whenever we can lower this as a zext, that instruction is strictly faster
  // than any alternative. It also allows us to fold memory operands into the
  // shuffle in many cases.
  if (SDValue ZExt = lowerShuffleAsZeroOrAnyExtend(
          DL, MVT::v16i32, V1, V2, Mask, Zeroable, Subtarget, DAG))
    return ZExt;

  // If the shuffle mask is repeated in each 128-bit lane we can use more
  // efficient instructions that mirror the shuffles across the four 128-bit
  // lanes.
  SmallVector<int, 4> RepeatedMask;
  bool Is128BitLaneRepeatedShuffle =
      is128BitLaneRepeatedShuffleMask(MVT::v16i32, Mask, RepeatedMask);
  if (Is128BitLaneRepeatedShuffle) {
    assert(RepeatedMask.size() == 4 && "Unexpected repeated mask size!");
    if (V2.isUndef())
      return DAG.getNode(X86ISD::PSHUFD, DL, MVT::v16i32, V1,
                         getV4X86ShuffleImm8ForMask(RepeatedMask, DL, DAG));

    // Use dedicated unpack instructions for masks that match their pattern.
    if (SDValue V = lowerShuffleWithUNPCK(DL, MVT::v16i32, Mask, V1, V2, DAG))
      return V;
  }

  // Try to use shift instructions.
  if (SDValue Shift = lowerShuffleAsShift(DL, MVT::v16i32, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Shift;

  // Try to use VALIGN.
  if (SDValue Rotate = lowerShuffleAsVALIGN(DL, MVT::v16i32, V1, V2, Mask,
                                            Subtarget, DAG))
    return Rotate;

  // Try to use byte rotation instructions.
  if (Subtarget.hasBWI())
    if (SDValue Rotate = lowerShuffleAsByteRotate(DL, MVT::v16i32, V1, V2, Mask,
                                                  Subtarget, DAG))
      return Rotate;

  // Assume that a single SHUFPS is faster than using a permv shuffle.
  // If some CPU is harmed by the domain switch, we can fix it in a later pass.
  if (Is128BitLaneRepeatedShuffle && isSingleSHUFPSMask(RepeatedMask)) {
    SDValue CastV1 = DAG.getBitcast(MVT::v16f32, V1);
    SDValue CastV2 = DAG.getBitcast(MVT::v16f32, V2);
    SDValue ShufPS = lowerShuffleWithSHUFPS(DL, MVT::v16f32, RepeatedMask,
                                            CastV1, CastV2, DAG);
    return DAG.getBitcast(MVT::v16i32, ShufPS);
  }
  // If we have AVX512F support, we can use VEXPAND.
  if (SDValue V = lowerShuffleToEXPAND(DL, MVT::v16i32, Zeroable, Mask, V1, V2,
                                       DAG, Subtarget))
    return V;

  if (SDValue Blend = lowerShuffleAsBlend(DL, MVT::v16i32, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Blend;
  return lowerShuffleWithPERMV(DL, MVT::v16i32, Mask, V1, V2, DAG);
}

/// Handle lowering of 32-lane 16-bit integer shuffles.
static SDValue lowerV32I16Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
                                  const APInt &Zeroable, SDValue V1, SDValue V2,
                                  const X86Subtarget &Subtarget,
                                  SelectionDAG &DAG) {
  assert(V1.getSimpleValueType() == MVT::v32i16 && "Bad operand type!");
  assert(V2.getSimpleValueType() == MVT::v32i16 && "Bad operand type!");
  assert(Mask.size() == 32 && "Unexpected mask size for v32 shuffle!");
  assert(Subtarget.hasBWI() && "We can only lower v32i16 with AVX-512-BWI!");

  // Whenever we can lower this as a zext, that instruction is strictly faster
  // than any alternative. It also allows us to fold memory operands into the
  // shuffle in many cases.
  if (SDValue ZExt = lowerShuffleAsZeroOrAnyExtend(
          DL, MVT::v32i16, V1, V2, Mask, Zeroable, Subtarget, DAG))
    return ZExt;

  // Use dedicated unpack instructions for masks that match their pattern.
  if (SDValue V = lowerShuffleWithUNPCK(DL, MVT::v32i16, Mask, V1, V2, DAG))
    return V;

  // Use dedicated pack instructions for masks that match their pattern.
  if (SDValue V =
          lowerShuffleWithPACK(DL, MVT::v32i16, Mask, V1, V2, DAG, Subtarget))
    return V;

  // Try to use shift instructions.
  if (SDValue Shift = lowerShuffleAsShift(DL, MVT::v32i16, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Shift;

  // Try to use byte rotation instructions.
  if (SDValue Rotate = lowerShuffleAsByteRotate(DL, MVT::v32i16, V1, V2, Mask,
                                                Subtarget, DAG))
    return Rotate;

  if (V2.isUndef()) {
    // Try to use bit rotation instructions.
    if (SDValue Rotate =
            lowerShuffleAsBitRotate(DL, MVT::v32i16, V1, Mask, Subtarget, DAG))
      return Rotate;

    SmallVector<int, 8> RepeatedMask;
    if (is128BitLaneRepeatedShuffleMask(MVT::v32i16, Mask, RepeatedMask)) {
      // As this is a single-input shuffle, the repeated mask should be
      // a strictly valid v8i16 mask that we can pass through to the v8i16
      // lowering to handle even the v32 case.
      return lowerV8I16GeneralSingleInputShuffle(DL, MVT::v32i16, V1,
                                                 RepeatedMask, Subtarget, DAG);
    }
  }

  if (SDValue Blend = lowerShuffleAsBlend(DL, MVT::v32i16, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Blend;

  if (SDValue PSHUFB = lowerShuffleWithPSHUFB(DL, MVT::v32i16, Mask, V1, V2,
                                              Zeroable, Subtarget, DAG))
    return PSHUFB;

  return lowerShuffleWithPERMV(DL, MVT::v32i16, Mask, V1, V2, DAG);
}

/// Handle lowering of 64-lane 8-bit integer shuffles.
static SDValue lowerV64I8Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
                                 const APInt &Zeroable, SDValue V1, SDValue V2,
                                 const X86Subtarget &Subtarget,
                                 SelectionDAG &DAG) {
  assert(V1.getSimpleValueType() == MVT::v64i8 && "Bad operand type!");
  assert(V2.getSimpleValueType() == MVT::v64i8 && "Bad operand type!");
  assert(Mask.size() == 64 && "Unexpected mask size for v64 shuffle!");
  assert(Subtarget.hasBWI() && "We can only lower v64i8 with AVX-512-BWI!");

  // Whenever we can lower this as a zext, that instruction is strictly faster
  // than any alternative. It also allows us to fold memory operands into the
  // shuffle in many cases.
  if (SDValue ZExt = lowerShuffleAsZeroOrAnyExtend(
          DL, MVT::v64i8, V1, V2, Mask, Zeroable, Subtarget, DAG))
    return ZExt;

  // Use dedicated unpack instructions for masks that match their pattern.
  if (SDValue V = lowerShuffleWithUNPCK(DL, MVT::v64i8, Mask, V1, V2, DAG))
    return V;

  // Use dedicated pack instructions for masks that match their pattern.
  if (SDValue V = lowerShuffleWithPACK(DL, MVT::v64i8, Mask, V1, V2, DAG,
                                       Subtarget))
    return V;

  // Try to use shift instructions.
  if (SDValue Shift = lowerShuffleAsShift(DL, MVT::v64i8, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Shift;

  // Try to use byte rotation instructions.
  if (SDValue Rotate = lowerShuffleAsByteRotate(DL, MVT::v64i8, V1, V2, Mask,
                                                Subtarget, DAG))
    return Rotate;

  // Try to use bit rotation instructions.
  if (V2.isUndef())
    if (SDValue Rotate =
            lowerShuffleAsBitRotate(DL, MVT::v64i8, V1, Mask, Subtarget, DAG))
      return Rotate;

  if (SDValue PSHUFB = lowerShuffleWithPSHUFB(DL, MVT::v64i8, Mask, V1, V2,
                                              Zeroable, Subtarget, DAG))
    return PSHUFB;

  // VBMI can use VPERMV/VPERMV3 byte shuffles.
  if (Subtarget.hasVBMI())
    return lowerShuffleWithPERMV(DL, MVT::v64i8, Mask, V1, V2, DAG);

  // Try to create an in-lane repeating shuffle mask and then shuffle the
  // results into the target lanes.
  if (SDValue V = lowerShuffleAsRepeatedMaskAndLanePermute(
          DL, MVT::v64i8, V1, V2, Mask, Subtarget, DAG))
    return V;

  if (SDValue Blend = lowerShuffleAsBlend(DL, MVT::v64i8, V1, V2, Mask,
                                          Zeroable, Subtarget, DAG))
    return Blend;

  // Try to simplify this by merging 128-bit lanes to enable a lane-based
  // shuffle.
  if (!V2.isUndef())
    if (SDValue Result = lowerShuffleAsLanePermuteAndRepeatedMask(
            DL, MVT::v64i8, V1, V2, Mask, Subtarget, DAG))
      return Result;

  // FIXME: Implement direct support for this type!
  return splitAndLowerShuffle(DL, MVT::v64i8, V1, V2, Mask, DAG);
}

/// High-level routine to lower various 512-bit x86 vector shuffles.
///
/// This routine either breaks down the specific type of a 512-bit x86 vector
/// shuffle or splits it into two 256-bit shuffles and fuses the results back
/// together based on the available instructions.
static SDValue lower512BitShuffle(const SDLoc &DL, ArrayRef<int> Mask,
                                  MVT VT, SDValue V1, SDValue V2,
                                  const APInt &Zeroable,
                                  const X86Subtarget &Subtarget,
                                  SelectionDAG &DAG) {
  assert(Subtarget.hasAVX512() &&
         "Cannot lower 512-bit vectors w/ basic ISA!");

  // If we have a single input to the zero element, insert that into V1 if we
  // can do so cheaply.
  int NumElts = Mask.size();
  int NumV2Elements = count_if(Mask, [NumElts](int M) { return M >= NumElts; });

  if (NumV2Elements == 1 && Mask[0] >= NumElts)
    if (SDValue Insertion = lowerShuffleAsElementInsertion(
            DL, VT, V1, V2, Mask, Zeroable, Subtarget, DAG))
      return Insertion;

  // Handle special cases where the lower or upper half is UNDEF.
  if (SDValue V =
          lowerShuffleWithUndefHalf(DL, VT, V1, V2, Mask, Subtarget, DAG))
    return V;

  // Check for being able to broadcast a single element.
  if (SDValue Broadcast = lowerShuffleAsBroadcast(DL, VT, V1, V2, Mask,
                                                  Subtarget, DAG))
    return Broadcast;

  // Dispatch to each element type for lowering. If we don't have support for
  // specific element type shuffles at 512 bits, immediately split them and
  // lower them. Each lowering routine of a given type is allowed to assume that
  // the requisite ISA extensions for that element type are available.
  switch (VT.SimpleTy) {
  case MVT::v8f64:
    return lowerV8F64Shuffle(DL, Mask, Zeroable, V1, V2, Subtarget, DAG);
  case MVT::v16f32:
    return lowerV16F32Shuffle(DL, Mask, Zeroable, V1, V2, Subtarget, DAG);
  case MVT::v8i64:
    return lowerV8I64Shuffle(DL, Mask, Zeroable, V1, V2, Subtarget, DAG);
  case MVT::v16i32:
    return lowerV16I32Shuffle(DL, Mask, Zeroable, V1, V2, Subtarget, DAG);
  case MVT::v32i16:
    return lowerV32I16Shuffle(DL, Mask, Zeroable, V1, V2, Subtarget, DAG);
  case MVT::v64i8:
    return lowerV64I8Shuffle(DL, Mask, Zeroable, V1, V2, Subtarget, DAG);

  default:
    llvm_unreachable("Not a valid 512-bit x86 vector type!");
  }
}

static SDValue lower1BitShuffleAsKSHIFTR(const SDLoc &DL, ArrayRef<int> Mask,
                                         MVT VT, SDValue V1, SDValue V2,
                                         const X86Subtarget &Subtarget,
                                         SelectionDAG &DAG) {
  // Shuffle should be unary.
  if (!V2.isUndef())
    return SDValue();

  int ShiftAmt = -1;
  int NumElts = Mask.size();
  for (int i = 0; i != NumElts; ++i) {
    int M = Mask[i];
    assert((M == SM_SentinelUndef || (0 <= M && M < NumElts)) &&
           "Unexpected mask index.");
    if (M < 0)
      continue;

    // The first non-undef element determines our shift amount.
    if (ShiftAmt < 0) {
      ShiftAmt = M - i;
      // Need to be shifting right.
      if (ShiftAmt <= 0)
        return SDValue();
    }
    // All non-undef elements must shift by the same amount.
    if (ShiftAmt != M - i)
      return SDValue();
  }
  assert(ShiftAmt >= 0 && "All undef?");

  // Great we found a shift right.
  MVT WideVT = VT;
  if ((!Subtarget.hasDQI() && NumElts == 8) || NumElts < 8)
    WideVT = Subtarget.hasDQI() ? MVT::v8i1 : MVT::v16i1;
  SDValue Res = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, WideVT,
                            DAG.getUNDEF(WideVT), V1,
                            DAG.getIntPtrConstant(0, DL));
  Res = DAG.getNode(X86ISD::KSHIFTR, DL, WideVT, Res,
                    DAG.getTargetConstant(ShiftAmt, DL, MVT::i8));
  return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, VT, Res,
                     DAG.getIntPtrConstant(0, DL));
}

// Determine if this shuffle can be implemented with a KSHIFT instruction.
// Returns the shift amount if possible or -1 if not. This is a simplified
// version of matchShuffleAsShift.
static int match1BitShuffleAsKSHIFT(unsigned &Opcode, ArrayRef<int> Mask,
                                    int MaskOffset, const APInt &Zeroable) {
  int Size = Mask.size();

  auto CheckZeros = [&](int Shift, bool Left) {
    for (int j = 0; j < Shift; ++j)
      if (!Zeroable[j + (Left ? 0 : (Size - Shift))])
        return false;

    return true;
  };

  auto MatchShift = [&](int Shift, bool Left) {
    unsigned Pos = Left ? Shift : 0;
    unsigned Low = Left ? 0 : Shift;
    unsigned Len = Size - Shift;
    return isSequentialOrUndefInRange(Mask, Pos, Len, Low + MaskOffset);
  };

  for (int Shift = 1; Shift != Size; ++Shift)
    for (bool Left : {true, false})
      if (CheckZeros(Shift, Left) && MatchShift(Shift, Left)) {
        Opcode = Left ? X86ISD::KSHIFTL : X86ISD::KSHIFTR;
        return Shift;
      }

  return -1;
}


// Lower vXi1 vector shuffles.
// There is no a dedicated instruction on AVX-512 that shuffles the masks.
// The only way to shuffle bits is to sign-extend the mask vector to SIMD
// vector, shuffle and then truncate it back.
static SDValue lower1BitShuffle(const SDLoc &DL, ArrayRef<int> Mask,
                                MVT VT, SDValue V1, SDValue V2,
                                const APInt &Zeroable,
                                const X86Subtarget &Subtarget,
                                SelectionDAG &DAG) {
  assert(Subtarget.hasAVX512() &&
         "Cannot lower 512-bit vectors w/o basic ISA!");

  int NumElts = Mask.size();

  // Try to recognize shuffles that are just padding a subvector with zeros.
  int SubvecElts = 0;
  int Src = -1;
  for (int i = 0; i != NumElts; ++i) {
    if (Mask[i] >= 0) {
      // Grab the source from the first valid mask. All subsequent elements need
      // to use this same source.
      if (Src < 0)
        Src = Mask[i] / NumElts;
      if (Src != (Mask[i] / NumElts) || (Mask[i] % NumElts) != i)
        break;
    }

    ++SubvecElts;
  }
  assert(SubvecElts != NumElts && "Identity shuffle?");

  // Clip to a power 2.
  SubvecElts = PowerOf2Floor(SubvecElts);

  // Make sure the number of zeroable bits in the top at least covers the bits
  // not covered by the subvector.
  if ((int)Zeroable.countLeadingOnes() >= (NumElts - SubvecElts)) {
    assert(Src >= 0 && "Expected a source!");
    MVT ExtractVT = MVT::getVectorVT(MVT::i1, SubvecElts);
    SDValue Extract = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, ExtractVT,
                                  Src == 0 ? V1 : V2,
                                  DAG.getIntPtrConstant(0, DL));
    return DAG.getNode(ISD::INSERT_SUBVECTOR, DL, VT,
                       DAG.getConstant(0, DL, VT),
                       Extract, DAG.getIntPtrConstant(0, DL));
  }

  // Try a simple shift right with undef elements. Later we'll try with zeros.
  if (SDValue Shift = lower1BitShuffleAsKSHIFTR(DL, Mask, VT, V1, V2, Subtarget,
                                                DAG))
    return Shift;

  // Try to match KSHIFTs.
  unsigned Offset = 0;
  for (SDValue V : { V1, V2 }) {
    unsigned Opcode;
    int ShiftAmt = match1BitShuffleAsKSHIFT(Opcode, Mask, Offset, Zeroable);
    if (ShiftAmt >= 0) {
      MVT WideVT = VT;
      if ((!Subtarget.hasDQI() && NumElts == 8) || NumElts < 8)
        WideVT = Subtarget.hasDQI() ? MVT::v8i1 : MVT::v16i1;
      SDValue Res = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, WideVT,
                                DAG.getUNDEF(WideVT), V,
                                DAG.getIntPtrConstant(0, DL));
      // Widened right shifts need two shifts to ensure we shift in zeroes.
      if (Opcode == X86ISD::KSHIFTR && WideVT != VT) {
        int WideElts = WideVT.getVectorNumElements();
        // Shift left to put the original vector in the MSBs of the new size.
        Res = DAG.getNode(X86ISD::KSHIFTL, DL, WideVT, Res,
                          DAG.getTargetConstant(WideElts - NumElts, DL, MVT::i8));
        // Increase the shift amount to account for the left shift.
        ShiftAmt += WideElts - NumElts;
      }

      Res = DAG.getNode(Opcode, DL, WideVT, Res,
                        DAG.getTargetConstant(ShiftAmt, DL, MVT::i8));
      return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, VT, Res,
                         DAG.getIntPtrConstant(0, DL));
    }
    Offset += NumElts; // Increment for next iteration.
  }



  MVT ExtVT;
  switch (VT.SimpleTy) {
  default:
    llvm_unreachable("Expected a vector of i1 elements");
  case MVT::v2i1:
    ExtVT = MVT::v2i64;
    break;
  case MVT::v4i1:
    ExtVT = MVT::v4i32;
    break;
  case MVT::v8i1:
    // Take 512-bit type, more shuffles on KNL. If we have VLX use a 256-bit
    // shuffle.
    ExtVT = Subtarget.hasVLX() ? MVT::v8i32 : MVT::v8i64;
    break;
  case MVT::v16i1:
    // Take 512-bit type, unless we are avoiding 512-bit types and have the
    // 256-bit operation available.
    ExtVT = Subtarget.canExtendTo512DQ() ? MVT::v16i32 : MVT::v16i16;
    break;
  case MVT::v32i1:
    // Take 512-bit type, unless we are avoiding 512-bit types and have the
    // 256-bit operation available.
    assert(Subtarget.hasBWI() && "Expected AVX512BW support");
    ExtVT = Subtarget.canExtendTo512BW() ? MVT::v32i16 : MVT::v32i8;
    break;
  case MVT::v64i1:
    // Fall back to scalarization. FIXME: We can do better if the shuffle
    // can be partitioned cleanly.
    if (!Subtarget.useBWIRegs())
      return SDValue();
    ExtVT = MVT::v64i8;
    break;
  }

  V1 = DAG.getNode(ISD::SIGN_EXTEND, DL, ExtVT, V1);
  V2 = DAG.getNode(ISD::SIGN_EXTEND, DL, ExtVT, V2);

  SDValue Shuffle = DAG.getVectorShuffle(ExtVT, DL, V1, V2, Mask);
  // i1 was sign extended we can use X86ISD::CVT2MASK.
  int NumElems = VT.getVectorNumElements();
  if ((Subtarget.hasBWI() && (NumElems >= 32)) ||
      (Subtarget.hasDQI() && (NumElems < 32)))
    return DAG.getSetCC(DL, VT, DAG.getConstant(0, DL, ExtVT),
                       Shuffle, ISD::SETGT);

  return DAG.getNode(ISD::TRUNCATE, DL, VT, Shuffle);
}

/// Helper function that returns true if the shuffle mask should be
/// commuted to improve canonicalization.
static bool canonicalizeShuffleMaskWithCommute(ArrayRef<int> Mask) {
  int NumElements = Mask.size();

  int NumV1Elements = 0, NumV2Elements = 0;
  for (int M : Mask)
    if (M < 0)
      continue;
    else if (M < NumElements)
      ++NumV1Elements;
    else
      ++NumV2Elements;

  // Commute the shuffle as needed such that more elements come from V1 than
  // V2. This allows us to match the shuffle pattern strictly on how many
  // elements come from V1 without handling the symmetric cases.
  if (NumV2Elements > NumV1Elements)
    return true;

  assert(NumV1Elements > 0 && "No V1 indices");

  if (NumV2Elements == 0)
    return false;

  // When the number of V1 and V2 elements are the same, try to minimize the
  // number of uses of V2 in the low half of the vector. When that is tied,
  // ensure that the sum of indices for V1 is equal to or lower than the sum
  // indices for V2. When those are equal, try to ensure that the number of odd
  // indices for V1 is lower than the number of odd indices for V2.
  if (NumV1Elements == NumV2Elements) {
    int LowV1Elements = 0, LowV2Elements = 0;
    for (int M : Mask.slice(0, NumElements / 2))
      if (M >= NumElements)
        ++LowV2Elements;
      else if (M >= 0)
        ++LowV1Elements;
    if (LowV2Elements > LowV1Elements)
      return true;
    if (LowV2Elements == LowV1Elements) {
      int SumV1Indices = 0, SumV2Indices = 0;
      for (int i = 0, Size = Mask.size(); i < Size; ++i)
        if (Mask[i] >= NumElements)
          SumV2Indices += i;
        else if (Mask[i] >= 0)
          SumV1Indices += i;
      if (SumV2Indices < SumV1Indices)
        return true;
      if (SumV2Indices == SumV1Indices) {
        int NumV1OddIndices = 0, NumV2OddIndices = 0;
        for (int i = 0, Size = Mask.size(); i < Size; ++i)
          if (Mask[i] >= NumElements)
            NumV2OddIndices += i % 2;
          else if (Mask[i] >= 0)
            NumV1OddIndices += i % 2;
        if (NumV2OddIndices < NumV1OddIndices)
          return true;
      }
    }
  }

  return false;
}

/// Top-level lowering for x86 vector shuffles.
///
/// This handles decomposition, canonicalization, and lowering of all x86
/// vector shuffles. Most of the specific lowering strategies are encapsulated
/// above in helper routines. The canonicalization attempts to widen shuffles
/// to involve fewer lanes of wider elements, consolidate symmetric patterns
/// s.t. only one of the two inputs needs to be tested, etc.
static SDValue lowerVECTOR_SHUFFLE(SDValue Op, const X86Subtarget &Subtarget,
                                   SelectionDAG &DAG) {
  ShuffleVectorSDNode *SVOp = cast<ShuffleVectorSDNode>(Op);
  ArrayRef<int> OrigMask = SVOp->getMask();
  SDValue V1 = Op.getOperand(0);
  SDValue V2 = Op.getOperand(1);
  MVT VT = Op.getSimpleValueType();
  int NumElements = VT.getVectorNumElements();
  SDLoc DL(Op);
  bool Is1BitVector = (VT.getVectorElementType() == MVT::i1);

  assert((VT.getSizeInBits() != 64 || Is1BitVector) &&
         "Can't lower MMX shuffles");

  bool V1IsUndef = V1.isUndef();
  bool V2IsUndef = V2.isUndef();
  if (V1IsUndef && V2IsUndef)
    return DAG.getUNDEF(VT);

  // When we create a shuffle node we put the UNDEF node to second operand,
  // but in some cases the first operand may be transformed to UNDEF.
  // In this case we should just commute the node.
  if (V1IsUndef)
    return DAG.getCommutedVectorShuffle(*SVOp);

  // Check for non-undef masks pointing at an undef vector and make the masks
  // undef as well. This makes it easier to match the shuffle based solely on
  // the mask.
  if (V2IsUndef &&
      any_of(OrigMask, [NumElements](int M) { return M >= NumElements; })) {
    SmallVector<int, 8> NewMask(OrigMask.begin(), OrigMask.end());
    for (int &M : NewMask)
      if (M >= NumElements)
        M = -1;
    return DAG.getVectorShuffle(VT, DL, V1, V2, NewMask);
  }

  // Check for illegal shuffle mask element index values.
  int MaskUpperLimit = OrigMask.size() * (V2IsUndef ? 1 : 2);
  (void)MaskUpperLimit;
  assert(llvm::all_of(OrigMask,
                      [&](int M) { return -1 <= M && M < MaskUpperLimit; }) &&
         "Out of bounds shuffle index");

  // We actually see shuffles that are entirely re-arrangements of a set of
  // zero inputs. This mostly happens while decomposing complex shuffles into
  // simple ones. Directly lower these as a buildvector of zeros.
  APInt KnownUndef, KnownZero;
  computeZeroableShuffleElements(OrigMask, V1, V2, KnownUndef, KnownZero);

  APInt Zeroable = KnownUndef | KnownZero;
  if (Zeroable.isAllOnesValue())
    return getZeroVector(VT, Subtarget, DAG, DL);

  bool V2IsZero = !V2IsUndef && ISD::isBuildVectorAllZeros(V2.getNode());

  // Try to collapse shuffles into using a vector type with fewer elements but
  // wider element types. We cap this to not form integers or floating point
  // elements wider than 64 bits, but it might be interesting to form i128
  // integers to handle flipping the low and high halves of AVX 256-bit vectors.
  SmallVector<int, 16> WidenedMask;
  if (VT.getScalarSizeInBits() < 64 && !Is1BitVector &&
      canWidenShuffleElements(OrigMask, Zeroable, V2IsZero, WidenedMask)) {
    // Shuffle mask widening should not interfere with a broadcast opportunity
    // by obfuscating the operands with bitcasts.
    // TODO: Avoid lowering directly from this top-level function: make this
    // a query (canLowerAsBroadcast) and defer lowering to the type-based calls.
    if (SDValue Broadcast = lowerShuffleAsBroadcast(DL, VT, V1, V2, OrigMask,
                                                    Subtarget, DAG))
      return Broadcast;

    MVT NewEltVT = VT.isFloatingPoint()
                       ? MVT::getFloatingPointVT(VT.getScalarSizeInBits() * 2)
                       : MVT::getIntegerVT(VT.getScalarSizeInBits() * 2);
    int NewNumElts = NumElements / 2;
    MVT NewVT = MVT::getVectorVT(NewEltVT, NewNumElts);
    // Make sure that the new vector type is legal. For example, v2f64 isn't
    // legal on SSE1.
    if (DAG.getTargetLoweringInfo().isTypeLegal(NewVT)) {
      if (V2IsZero) {
        // Modify the new Mask to take all zeros from the all-zero vector.
        // Choose indices that are blend-friendly.
        bool UsedZeroVector = false;
        assert(find(WidenedMask, SM_SentinelZero) != WidenedMask.end() &&
               "V2's non-undef elements are used?!");
        for (int i = 0; i != NewNumElts; ++i)
          if (WidenedMask[i] == SM_SentinelZero) {
            WidenedMask[i] = i + NewNumElts;
            UsedZeroVector = true;
          }
        // Ensure all elements of V2 are zero - isBuildVectorAllZeros permits
        // some elements to be undef.
        if (UsedZeroVector)
          V2 = getZeroVector(NewVT, Subtarget, DAG, DL);
      }
      V1 = DAG.getBitcast(NewVT, V1);
      V2 = DAG.getBitcast(NewVT, V2);
      return DAG.getBitcast(
          VT, DAG.getVectorShuffle(NewVT, DL, V1, V2, WidenedMask));
    }
  }

  // Commute the shuffle if it will improve canonicalization.
  SmallVector<int, 64> Mask(OrigMask.begin(), OrigMask.end());
  if (canonicalizeShuffleMaskWithCommute(Mask)) {
    ShuffleVectorSDNode::commuteMask(Mask);
    std::swap(V1, V2);
  }

  if (SDValue V = lowerShuffleWithVPMOV(DL, Mask, VT, V1, V2, DAG, Subtarget))
    return V;

  // For each vector width, delegate to a specialized lowering routine.
  if (VT.is128BitVector())
    return lower128BitShuffle(DL, Mask, VT, V1, V2, Zeroable, Subtarget, DAG);

  if (VT.is256BitVector())
    return lower256BitShuffle(DL, Mask, VT, V1, V2, Zeroable, Subtarget, DAG);

  if (VT.is512BitVector())
    return lower512BitShuffle(DL, Mask, VT, V1, V2, Zeroable, Subtarget, DAG);

  if (Is1BitVector)
    return lower1BitShuffle(DL, Mask, VT, V1, V2, Zeroable, Subtarget, DAG);

  llvm_unreachable("Unimplemented!");
}

/// Try to lower a VSELECT instruction to a vector shuffle.
static SDValue lowerVSELECTtoVectorShuffle(SDValue Op,
                                           const X86Subtarget &Subtarget,
                                           SelectionDAG &DAG) {
  SDValue Cond = Op.getOperand(0);
  SDValue LHS = Op.getOperand(1);
  SDValue RHS = Op.getOperand(2);
  MVT VT = Op.getSimpleValueType();

  // Only non-legal VSELECTs reach this lowering, convert those into generic
  // shuffles and re-use the shuffle lowering path for blends.
  SmallVector<int, 32> Mask;
  if (createShuffleMaskFromVSELECT(Mask, Cond))
    return DAG.getVectorShuffle(VT, SDLoc(Op), LHS, RHS, Mask);

  return SDValue();
}

SDValue X86TargetLowering::LowerVSELECT(SDValue Op, SelectionDAG &DAG) const {
  SDValue Cond = Op.getOperand(0);
  SDValue LHS = Op.getOperand(1);
  SDValue RHS = Op.getOperand(2);

  // A vselect where all conditions and data are constants can be optimized into
  // a single vector load by SelectionDAGLegalize::ExpandBUILD_VECTOR().
  if (ISD::isBuildVectorOfConstantSDNodes(Cond.getNode()) &&
      ISD::isBuildVectorOfConstantSDNodes(LHS.getNode()) &&
      ISD::isBuildVectorOfConstantSDNodes(RHS.getNode()))
    return SDValue();

  // Try to lower this to a blend-style vector shuffle. This can handle all
  // constant condition cases.
  if (SDValue BlendOp = lowerVSELECTtoVectorShuffle(Op, Subtarget, DAG))
    return BlendOp;

  // If this VSELECT has a vector if i1 as a mask, it will be directly matched
  // with patterns on the mask registers on AVX-512.
  MVT CondVT = Cond.getSimpleValueType();
  unsigned CondEltSize = Cond.getScalarValueSizeInBits();
  if (CondEltSize == 1)
    return Op;

  // Variable blends are only legal from SSE4.1 onward.
  if (!Subtarget.hasSSE41())
    return SDValue();

  SDLoc dl(Op);
  MVT VT = Op.getSimpleValueType();
  unsigned EltSize = VT.getScalarSizeInBits();
  unsigned NumElts = VT.getVectorNumElements();

  // If the VSELECT is on a 512-bit type, we have to convert a non-i1 condition
  // into an i1 condition so that we can use the mask-based 512-bit blend
  // instructions.
  if (VT.getSizeInBits() == 512) {
    // Build a mask by testing the condition against zero.
    MVT MaskVT = MVT::getVectorVT(MVT::i1, NumElts);
    SDValue Mask = DAG.getSetCC(dl, MaskVT, Cond,
                                DAG.getConstant(0, dl, CondVT),
                                ISD::SETNE);
    // Now return a new VSELECT using the mask.
    return DAG.getSelect(dl, VT, Mask, LHS, RHS);
  }

  // SEXT/TRUNC cases where the mask doesn't match the destination size.
  if (CondEltSize != EltSize) {
    // If we don't have a sign splat, rely on the expansion.
    if (CondEltSize != DAG.ComputeNumSignBits(Cond))
      return SDValue();

    MVT NewCondSVT = MVT::getIntegerVT(EltSize);
    MVT NewCondVT = MVT::getVectorVT(NewCondSVT, NumElts);
    Cond = DAG.getSExtOrTrunc(Cond, dl, NewCondVT);
    return DAG.getNode(ISD::VSELECT, dl, VT, Cond, LHS, RHS);
  }

  // Only some types will be legal on some subtargets. If we can emit a legal
  // VSELECT-matching blend, return Op, and but if we need to expand, return
  // a null value.
  switch (VT.SimpleTy) {
  default:
    // Most of the vector types have blends past SSE4.1.
    return Op;

  case MVT::v32i8:
    // The byte blends for AVX vectors were introduced only in AVX2.
    if (Subtarget.hasAVX2())
      return Op;

    return SDValue();

  case MVT::v8i16:
  case MVT::v16i16: {
    // Bitcast everything to the vXi8 type and use a vXi8 vselect.
    MVT CastVT = MVT::getVectorVT(MVT::i8, NumElts * 2);
    Cond = DAG.getBitcast(CastVT, Cond);
    LHS = DAG.getBitcast(CastVT, LHS);
    RHS = DAG.getBitcast(CastVT, RHS);
    SDValue Select = DAG.getNode(ISD::VSELECT, dl, CastVT, Cond, LHS, RHS);
    return DAG.getBitcast(VT, Select);
  }
  }
}

static SDValue LowerEXTRACT_VECTOR_ELT_SSE4(SDValue Op, SelectionDAG &DAG) {
  MVT VT = Op.getSimpleValueType();
  SDValue Vec = Op.getOperand(0);
  SDValue Idx = Op.getOperand(1);
  assert(isa<ConstantSDNode>(Idx) && "Constant index expected");
  SDLoc dl(Op);

  if (!Vec.getSimpleValueType().is128BitVector())
    return SDValue();

  if (VT.getSizeInBits() == 8) {
    // If IdxVal is 0, it's cheaper to do a move instead of a pextrb, unless
    // we're going to zero extend the register or fold the store.
    if (llvm::isNullConstant(Idx) && !MayFoldIntoZeroExtend(Op) &&
        !MayFoldIntoStore(Op))
      return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
                         DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32,
                                     DAG.getBitcast(MVT::v4i32, Vec), Idx));

    SDValue Extract = DAG.getNode(X86ISD::PEXTRB, dl, MVT::i32, Vec, Idx);
    return DAG.getNode(ISD::TRUNCATE, dl, VT, Extract);
  }

  if (VT == MVT::f32) {
    // EXTRACTPS outputs to a GPR32 register which will require a movd to copy
    // the result back to FR32 register. It's only worth matching if the
    // result has a single use which is a store or a bitcast to i32.  And in
    // the case of a store, it's not worth it if the index is a constant 0,
    // because a MOVSSmr can be used instead, which is smaller and faster.
    if (!Op.hasOneUse())
      return SDValue();
    SDNode *User = *Op.getNode()->use_begin();
    if ((User->getOpcode() != ISD::STORE || isNullConstant(Idx)) &&
        (User->getOpcode() != ISD::BITCAST ||
         User->getValueType(0) != MVT::i32))
      return SDValue();
    SDValue Extract = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32,
                                  DAG.getBitcast(MVT::v4i32, Vec), Idx);
    return DAG.getBitcast(MVT::f32, Extract);
  }

  if (VT == MVT::i32 || VT == MVT::i64)
      return Op;

  return SDValue();
}

/// Extract one bit from mask vector, like v16i1 or v8i1.
/// AVX-512 feature.
static SDValue ExtractBitFromMaskVector(SDValue Op, SelectionDAG &DAG,
                                        const X86Subtarget &Subtarget) {
  SDValue Vec = Op.getOperand(0);
  SDLoc dl(Vec);
  MVT VecVT = Vec.getSimpleValueType();
  SDValue Idx = Op.getOperand(1);
  MVT EltVT = Op.getSimpleValueType();

  assert((VecVT.getVectorNumElements() <= 16 || Subtarget.hasBWI()) &&
         "Unexpected vector type in ExtractBitFromMaskVector");

  // variable index can't be handled in mask registers,
  // extend vector to VR512/128
  if (!isa<ConstantSDNode>(Idx)) {
    unsigned NumElts = VecVT.getVectorNumElements();
    // Extending v8i1/v16i1 to 512-bit get better performance on KNL
    // than extending to 128/256bit.
    MVT ExtEltVT = (NumElts <= 8) ? MVT::getIntegerVT(128 / NumElts) : MVT::i8;
    MVT ExtVecVT = MVT::getVectorVT(ExtEltVT, NumElts);
    SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND, dl, ExtVecVT, Vec);
    SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ExtEltVT, Ext, Idx);
    return DAG.getNode(ISD::TRUNCATE, dl, EltVT, Elt);
  }

  unsigned IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
  if (IdxVal == 0) // the operation is legal
    return Op;

  // Extend to natively supported kshift.
  unsigned NumElems = VecVT.getVectorNumElements();
  MVT WideVecVT = VecVT;
  if ((!Subtarget.hasDQI() && NumElems == 8) || NumElems < 8) {
    WideVecVT = Subtarget.hasDQI() ? MVT::v8i1 : MVT::v16i1;
    Vec = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, WideVecVT,
                      DAG.getUNDEF(WideVecVT), Vec,
                      DAG.getIntPtrConstant(0, dl));
  }

  // Use kshiftr instruction to move to the lower element.
  Vec = DAG.getNode(X86ISD::KSHIFTR, dl, WideVecVT, Vec,
                    DAG.getTargetConstant(IdxVal, dl, MVT::i8));

  return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, Op.getValueType(), Vec,
                     DAG.getIntPtrConstant(0, dl));
}

SDValue
X86TargetLowering::LowerEXTRACT_VECTOR_ELT(SDValue Op,
                                           SelectionDAG &DAG) const {
  SDLoc dl(Op);
  SDValue Vec = Op.getOperand(0);
  MVT VecVT = Vec.getSimpleValueType();
  SDValue Idx = Op.getOperand(1);

  if (VecVT.getVectorElementType() == MVT::i1)
    return ExtractBitFromMaskVector(Op, DAG, Subtarget);

  if (!isa<ConstantSDNode>(Idx)) {
    // Its more profitable to go through memory (1 cycles throughput)
    // than using VMOVD + VPERMV/PSHUFB sequence ( 2/3 cycles throughput)
    // IACA tool was used to get performance estimation
    // (https://software.intel.com/en-us/articles/intel-architecture-code-analyzer)
    //
    // example : extractelement <16 x i8> %a, i32 %i
    //
    // Block Throughput: 3.00 Cycles
    // Throughput Bottleneck: Port5
    //
    // | Num Of |   Ports pressure in cycles  |    |
    // |  Uops  |  0  - DV  |  5  |  6  |  7  |    |
    // ---------------------------------------------
    // |   1    |           | 1.0 |     |     | CP | vmovd xmm1, edi
    // |   1    |           | 1.0 |     |     | CP | vpshufb xmm0, xmm0, xmm1
    // |   2    | 1.0       | 1.0 |     |     | CP | vpextrb eax, xmm0, 0x0
    // Total Num Of Uops: 4
    //
    //
    // Block Throughput: 1.00 Cycles
    // Throughput Bottleneck: PORT2_AGU, PORT3_AGU, Port4
    //
    // |    |  Ports pressure in cycles   |  |
    // |Uops| 1 | 2 - D  |3 -  D  | 4 | 5 |  |
    // ---------------------------------------------------------
    // |2^  |   | 0.5    | 0.5    |1.0|   |CP| vmovaps xmmword ptr [rsp-0x18], xmm0
    // |1   |0.5|        |        |   |0.5|  | lea rax, ptr [rsp-0x18]
    // |1   |   |0.5, 0.5|0.5, 0.5|   |   |CP| mov al, byte ptr [rdi+rax*1]
    // Total Num Of Uops: 4

    return SDValue();
  }

  unsigned IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();

  // If this is a 256-bit vector result, first extract the 128-bit vector and
  // then extract the element from the 128-bit vector.
  if (VecVT.is256BitVector() || VecVT.is512BitVector()) {
    // Get the 128-bit vector.
    Vec = extract128BitVector(Vec, IdxVal, DAG, dl);
    MVT EltVT = VecVT.getVectorElementType();

    unsigned ElemsPerChunk = 128 / EltVT.getSizeInBits();
    assert(isPowerOf2_32(ElemsPerChunk) && "Elements per chunk not power of 2");

    // Find IdxVal modulo ElemsPerChunk. Since ElemsPerChunk is a power of 2
    // this can be done with a mask.
    IdxVal &= ElemsPerChunk - 1;
    return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, Op.getValueType(), Vec,
                       DAG.getIntPtrConstant(IdxVal, dl));
  }

  assert(VecVT.is128BitVector() && "Unexpected vector length");

  MVT VT = Op.getSimpleValueType();

  if (VT.getSizeInBits() == 16) {
    // If IdxVal is 0, it's cheaper to do a move instead of a pextrw, unless
    // we're going to zero extend the register or fold the store (SSE41 only).
    if (IdxVal == 0 && !MayFoldIntoZeroExtend(Op) &&
        !(Subtarget.hasSSE41() && MayFoldIntoStore(Op)))
      return DAG.getNode(ISD::TRUNCATE, dl, MVT::i16,
                         DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32,
                                     DAG.getBitcast(MVT::v4i32, Vec), Idx));

    SDValue Extract = DAG.getNode(X86ISD::PEXTRW, dl, MVT::i32, Vec, Idx);
    return DAG.getNode(ISD::TRUNCATE, dl, VT, Extract);
  }

  if (Subtarget.hasSSE41())
    if (SDValue Res = LowerEXTRACT_VECTOR_ELT_SSE4(Op, DAG))
      return Res;

  // TODO: We only extract a single element from v16i8, we can probably afford
  // to be more aggressive here before using the default approach of spilling to
  // stack.
  if (VT.getSizeInBits() == 8 && Op->isOnlyUserOf(Vec.getNode())) {
    // Extract either the lowest i32 or any i16, and extract the sub-byte.
    int DWordIdx = IdxVal / 4;
    if (DWordIdx == 0) {
      SDValue Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32,
                                DAG.getBitcast(MVT::v4i32, Vec),
                                DAG.getIntPtrConstant(DWordIdx, dl));
      int ShiftVal = (IdxVal % 4) * 8;
      if (ShiftVal != 0)
        Res = DAG.getNode(ISD::SRL, dl, MVT::i32, Res,
                          DAG.getConstant(ShiftVal, dl, MVT::i8));
      return DAG.getNode(ISD::TRUNCATE, dl, VT, Res);
    }

    int WordIdx = IdxVal / 2;
    SDValue Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i16,
                              DAG.getBitcast(MVT::v8i16, Vec),
                              DAG.getIntPtrConstant(WordIdx, dl));
    int ShiftVal = (IdxVal % 2) * 8;
    if (ShiftVal != 0)
      Res = DAG.getNode(ISD::SRL, dl, MVT::i16, Res,
                        DAG.getConstant(ShiftVal, dl, MVT::i8));
    return DAG.getNode(ISD::TRUNCATE, dl, VT, Res);
  }

  if (VT.getSizeInBits() == 32) {
    if (IdxVal == 0)
      return Op;

    // SHUFPS the element to the lowest double word, then movss.
    int Mask[4] = { static_cast<int>(IdxVal), -1, -1, -1 };
    Vec = DAG.getVectorShuffle(VecVT, dl, Vec, DAG.getUNDEF(VecVT), Mask);
    return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT, Vec,
                       DAG.getIntPtrConstant(0, dl));
  }

  if (VT.getSizeInBits() == 64) {
    // FIXME: .td only matches this for <2 x f64>, not <2 x i64> on 32b
    // FIXME: seems like this should be unnecessary if mov{h,l}pd were taught
    //        to match extract_elt for f64.
    if (IdxVal == 0)
      return Op;

    // UNPCKHPD the element to the lowest double word, then movsd.
    // Note if the lower 64 bits of the result of the UNPCKHPD is then stored
    // to a f64mem, the whole operation is folded into a single MOVHPDmr.
    int Mask[2] = { 1, -1 };
    Vec = DAG.getVectorShuffle(VecVT, dl, Vec, DAG.getUNDEF(VecVT), Mask);
    return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT, Vec,
                       DAG.getIntPtrConstant(0, dl));
  }

  return SDValue();
}

/// Insert one bit to mask vector, like v16i1 or v8i1.
/// AVX-512 feature.
static SDValue InsertBitToMaskVector(SDValue Op, SelectionDAG &DAG,
                                     const X86Subtarget &Subtarget) {
  SDLoc dl(Op);
  SDValue Vec = Op.getOperand(0);
  SDValue Elt = Op.getOperand(1);
  SDValue Idx = Op.getOperand(2);
  MVT VecVT = Vec.getSimpleValueType();

  if (!isa<ConstantSDNode>(Idx)) {
    // Non constant index. Extend source and destination,
    // insert element and then truncate the result.
    unsigned NumElts = VecVT.getVectorNumElements();
    MVT ExtEltVT = (NumElts <= 8) ? MVT::getIntegerVT(128 / NumElts) : MVT::i8;
    MVT ExtVecVT = MVT::getVectorVT(ExtEltVT, NumElts);
    SDValue ExtOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, ExtVecVT,
      DAG.getNode(ISD::SIGN_EXTEND, dl, ExtVecVT, Vec),
      DAG.getNode(ISD::SIGN_EXTEND, dl, ExtEltVT, Elt), Idx);
    return DAG.getNode(ISD::TRUNCATE, dl, VecVT, ExtOp);
  }

  // Copy into a k-register, extract to v1i1 and insert_subvector.
  SDValue EltInVec = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v1i1, Elt);

  return DAG.getNode(ISD::INSERT_SUBVECTOR, dl, VecVT, Vec, EltInVec,
                     Op.getOperand(2));
}

SDValue X86TargetLowering::LowerINSERT_VECTOR_ELT(SDValue Op,
                                                  SelectionDAG &DAG) const {
  MVT VT = Op.getSimpleValueType();
  MVT EltVT = VT.getVectorElementType();
  unsigned NumElts = VT.getVectorNumElements();

  if (EltVT == MVT::i1)
    return InsertBitToMaskVector(Op, DAG, Subtarget);

  SDLoc dl(Op);
  SDValue N0 = Op.getOperand(0);
  SDValue N1 = Op.getOperand(1);
  SDValue N2 = Op.getOperand(2);

  auto *N2C = dyn_cast<ConstantSDNode>(N2);
  if (!N2C || N2C->getAPIntValue().uge(NumElts))
    return SDValue();
  uint64_t IdxVal = N2C->getZExtValue();

  bool IsZeroElt = X86::isZeroNode(N1);
  bool IsAllOnesElt = VT.isInteger() && llvm::isAllOnesConstant(N1);

  // If we are inserting a element, see if we can do this more efficiently with
  // a blend shuffle with a rematerializable vector than a costly integer
  // insertion.
  if ((IsZeroElt || IsAllOnesElt) && Subtarget.hasSSE41() &&
      16 <= EltVT.getSizeInBits()) {
    SmallVector<int, 8> BlendMask;
    for (unsigned i = 0; i != NumElts; ++i)
      BlendMask.push_back(i == IdxVal ? i + NumElts : i);
    SDValue CstVector = IsZeroElt ? getZeroVector(VT, Subtarget, DAG, dl)
                                  : getOnesVector(VT, DAG, dl);
    return DAG.getVectorShuffle(VT, dl, N0, CstVector, BlendMask);
  }

  // If the vector is wider than 128 bits, extract the 128-bit subvector, insert
  // into that, and then insert the subvector back into the result.
  if (VT.is256BitVector() || VT.is512BitVector()) {
    // With a 256-bit vector, we can insert into the zero element efficiently
    // using a blend if we have AVX or AVX2 and the right data type.
    if (VT.is256BitVector() && IdxVal == 0) {
      // TODO: It is worthwhile to cast integer to floating point and back
      // and incur a domain crossing penalty if that's what we'll end up
      // doing anyway after extracting to a 128-bit vector.
      if ((Subtarget.hasAVX() && (EltVT == MVT::f64 || EltVT == MVT::f32)) ||
          (Subtarget.hasAVX2() && EltVT == MVT::i32)) {
        SDValue N1Vec = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, N1);
        return DAG.getNode(X86ISD::BLENDI, dl, VT, N0, N1Vec,
                           DAG.getTargetConstant(1, dl, MVT::i8));
      }
    }

    // Get the desired 128-bit vector chunk.
    SDValue V = extract128BitVector(N0, IdxVal, DAG, dl);

    // Insert the element into the desired chunk.
    unsigned NumEltsIn128 = 128 / EltVT.getSizeInBits();
    assert(isPowerOf2_32(NumEltsIn128));
    // Since NumEltsIn128 is a power of 2 we can use mask instead of modulo.
    unsigned IdxIn128 = IdxVal & (NumEltsIn128 - 1);

    V = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, V.getValueType(), V, N1,
                    DAG.getIntPtrConstant(IdxIn128, dl));

    // Insert the changed part back into the bigger vector
    return insert128BitVector(N0, V, IdxVal, DAG, dl);
  }
  assert(VT.is128BitVector() && "Only 128-bit vector types should be left!");

  // This will be just movd/movq/movss/movsd.
  if (IdxVal == 0 && ISD::isBuildVectorAllZeros(N0.getNode())) {
    if (EltVT == MVT::i32 || EltVT == MVT::f32 || EltVT == MVT::f64 ||
        EltVT == MVT::i64) {
      N1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, N1);
      return getShuffleVectorZeroOrUndef(N1, 0, true, Subtarget, DAG);
    }

    // We can't directly insert an i8 or i16 into a vector, so zero extend
    // it to i32 first.
    if (EltVT == MVT::i16 || EltVT == MVT::i8) {
      N1 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, N1);
      MVT ShufVT = MVT::getVectorVT(MVT::i32, VT.getSizeInBits()/32);
      N1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, ShufVT, N1);
      N1 = getShuffleVectorZeroOrUndef(N1, 0, true, Subtarget, DAG);
      return DAG.getBitcast(VT, N1);
    }
  }

  // Transform it so it match pinsr{b,w} which expects a GR32 as its second
  // argument. SSE41 required for pinsrb.
  if (VT == MVT::v8i16 || (VT == MVT::v16i8 && Subtarget.hasSSE41())) {
    unsigned Opc;
    if (VT == MVT::v8i16) {
      assert(Subtarget.hasSSE2() && "SSE2 required for PINSRW");
      Opc = X86ISD::PINSRW;
    } else {
      assert(VT == MVT::v16i8 && "PINSRB requires v16i8 vector");
      assert(Subtarget.hasSSE41() && "SSE41 required for PINSRB");
      Opc = X86ISD::PINSRB;
    }

    if (N1.getValueType() != MVT::i32)
      N1 = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, N1);
    if (N2.getValueType() != MVT::i32)
      N2 = DAG.getIntPtrConstant(IdxVal, dl);
    return DAG.getNode(Opc, dl, VT, N0, N1, N2);
  }

  if (Subtarget.hasSSE41()) {
    if (EltVT == MVT::f32) {
      // Bits [7:6] of the constant are the source select. This will always be
      //   zero here. The DAG Combiner may combine an extract_elt index into
      //   these bits. For example (insert (extract, 3), 2) could be matched by
      //   putting the '3' into bits [7:6] of X86ISD::INSERTPS.
      // Bits [5:4] of the constant are the destination select. This is the
      //   value of the incoming immediate.
      // Bits [3:0] of the constant are the zero mask. The DAG Combiner may
      //   combine either bitwise AND or insert of float 0.0 to set these bits.

      bool MinSize = DAG.getMachineFunction().getFunction().hasMinSize();
      if (IdxVal == 0 && (!MinSize || !MayFoldLoad(N1))) {
        // If this is an insertion of 32-bits into the low 32-bits of
        // a vector, we prefer to generate a blend with immediate rather
        // than an insertps. Blends are simpler operations in hardware and so
        // will always have equal or better performance than insertps.
        // But if optimizing for size and there's a load folding opportunity,
        // generate insertps because blendps does not have a 32-bit memory
        // operand form.
        N1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v4f32, N1);
        return DAG.getNode(X86ISD::BLENDI, dl, VT, N0, N1,
                           DAG.getTargetConstant(1, dl, MVT::i8));
      }
      // Create this as a scalar to vector..
      N1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v4f32, N1);
      return DAG.getNode(X86ISD::INSERTPS, dl, VT, N0, N1,
                         DAG.getTargetConstant(IdxVal << 4, dl, MVT::i8));
    }

    // PINSR* works with constant index.
    if (EltVT == MVT::i32 || EltVT == MVT::i64)
      return Op;
  }

  return SDValue();
}

static SDValue LowerSCALAR_TO_VECTOR(SDValue Op, const X86Subtarget &Subtarget,
                                     SelectionDAG &DAG) {
  SDLoc dl(Op);
  MVT OpVT = Op.getSimpleValueType();

  // It's always cheaper to replace a xor+movd with xorps and simplifies further
  // combines.
  if (X86::isZeroNode(Op.getOperand(0)))
    return getZeroVector(OpVT, Subtarget, DAG, dl);

  // If this is a 256-bit vector result, first insert into a 128-bit
  // vector and then insert into the 256-bit vector.
  if (!OpVT.is128BitVector()) {
    // Insert into a 128-bit vector.
    unsigned SizeFactor = OpVT.getSizeInBits() / 128;
    MVT VT128 = MVT::getVectorVT(OpVT.getVectorElementType(),
                                 OpVT.getVectorNumElements() / SizeFactor);

    Op = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT128, Op.getOperand(0));

    // Insert the 128-bit vector.
    return insert128BitVector(DAG.getUNDEF(OpVT), Op, 0, DAG, dl);
  }
  assert(OpVT.is128BitVector() && OpVT.isInteger() && OpVT != MVT::v2i64 &&
         "Expected an SSE type!");

  // Pass through a v4i32 SCALAR_TO_VECTOR as that's what we use in tblgen.
  if (OpVT == MVT::v4i32)
    return Op;

  SDValue AnyExt = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, Op.getOperand(0));
  return DAG.getBitcast(
      OpVT, DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v4i32, AnyExt));
}

// Lower a node with an INSERT_SUBVECTOR opcode.  This may result in a
// simple superregister reference or explicit instructions to insert
// the upper bits of a vector.
static SDValue LowerINSERT_SUBVECTOR(SDValue Op, const X86Subtarget &Subtarget,
                                     SelectionDAG &DAG) {
  assert(Op.getSimpleValueType().getVectorElementType() == MVT::i1);

  return insert1BitVector(Op, DAG, Subtarget);
}

static SDValue LowerEXTRACT_SUBVECTOR(SDValue Op, const X86Subtarget &Subtarget,
                                      SelectionDAG &DAG) {
  assert(Op.getSimpleValueType().getVectorElementType() == MVT::i1 &&
         "Only vXi1 extract_subvectors need custom lowering");

  SDLoc dl(Op);
  SDValue Vec = Op.getOperand(0);
  SDValue Idx = Op.getOperand(1);

  if (!isa<ConstantSDNode>(Idx))
    return SDValue();

  unsigned IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
  if (IdxVal == 0) // the operation is legal
    return Op;

  MVT VecVT = Vec.getSimpleValueType();
  unsigned NumElems = VecVT.getVectorNumElements();

  // Extend to natively supported kshift.
  MVT WideVecVT = VecVT;
  if ((!Subtarget.hasDQI() && NumElems == 8) || NumElems < 8) {
    WideVecVT = Subtarget.hasDQI() ? MVT::v8i1 : MVT::v16i1;
    Vec = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, WideVecVT,
                      DAG.getUNDEF(WideVecVT), Vec,
                      DAG.getIntPtrConstant(0, dl));
  }

  // Shift to the LSB.
  Vec = DAG.getNode(X86ISD::KSHIFTR, dl, WideVecVT, Vec,
                    DAG.getTargetConstant(IdxVal, dl, MVT::i8));

  return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, Op.getValueType(), Vec,
                     DAG.getIntPtrConstant(0, dl));
}

// Returns the appropriate wrapper opcode for a global reference.
unsigned X86TargetLowering::getGlobalWrapperKind(
    const GlobalValue *GV, const unsigned char OpFlags) const {
  // References to absolute symbols are never PC-relative.
  if (GV && GV->isAbsoluteSymbolRef())
    return X86ISD::Wrapper;

  CodeModel::Model M = getTargetMachine().getCodeModel();
  if (Subtarget.isPICStyleRIPRel() &&
      (M == CodeModel::Small || M == CodeModel::Kernel))
    return X86ISD::WrapperRIP;

  // GOTPCREL references must always use RIP.
  if (OpFlags == X86II::MO_GOTPCREL)
    return X86ISD::WrapperRIP;

  return X86ISD::Wrapper;
}

// ConstantPool, JumpTable, GlobalAddress, and ExternalSymbol are lowered as
// their target counterpart wrapped in the X86ISD::Wrapper node. Suppose N is
// one of the above mentioned nodes. It has to be wrapped because otherwise
// Select(N) returns N. So the raw TargetGlobalAddress nodes, etc. can only
// be used to form addressing mode. These wrapped nodes will be selected
// into MOV32ri.
SDValue
X86TargetLowering::LowerConstantPool(SDValue Op, SelectionDAG &DAG) const {
  ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);

  // In PIC mode (unless we're in RIPRel PIC mode) we add an offset to the
  // global base reg.
  unsigned char OpFlag = Subtarget.classifyLocalReference(nullptr);

  auto PtrVT = getPointerTy(DAG.getDataLayout());
  SDValue Result = DAG.getTargetConstantPool(
      CP->getConstVal(), PtrVT, CP->getAlignment(), CP->getOffset(), OpFlag);
  SDLoc DL(CP);
  Result = DAG.getNode(getGlobalWrapperKind(), DL, PtrVT, Result);
  // With PIC, the address is actually $g + Offset.
  if (OpFlag) {
    Result =
        DAG.getNode(ISD::ADD, DL, PtrVT,
                    DAG.getNode(X86ISD::GlobalBaseReg, SDLoc(), PtrVT), Result);
  }

  return Result;
}

SDValue X86TargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) const {
  JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);

  // In PIC mode (unless we're in RIPRel PIC mode) we add an offset to the
  // global base reg.
  unsigned char OpFlag = Subtarget.classifyLocalReference(nullptr);

  auto PtrVT = getPointerTy(DAG.getDataLayout());
  SDValue Result = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, OpFlag);
  SDLoc DL(JT);
  Result = DAG.getNode(getGlobalWrapperKind(), DL, PtrVT, Result);

  // With PIC, the address is actually $g + Offset.
  if (OpFlag)
    Result =
        DAG.getNode(ISD::ADD, DL, PtrVT,
                    DAG.getNode(X86ISD::GlobalBaseReg, SDLoc(), PtrVT), Result);

  return Result;
}

SDValue X86TargetLowering::LowerExternalSymbol(SDValue Op,
                                               SelectionDAG &DAG) const {
  return LowerGlobalOrExternal(Op, DAG, /*ForCall=*/false);
}

SDValue
X86TargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const {
  // Create the TargetBlockAddressAddress node.
  unsigned char OpFlags =
    Subtarget.classifyBlockAddressReference();
  const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
  int64_t Offset = cast<BlockAddressSDNode>(Op)->getOffset();
  SDLoc dl(Op);
  auto PtrVT = getPointerTy(DAG.getDataLayout());
  SDValue Result = DAG.getTargetBlockAddress(BA, PtrVT, Offset, OpFlags);
  Result = DAG.getNode(getGlobalWrapperKind(), dl, PtrVT, Result);

  // With PIC, the address is actually $g + Offset.
  if (isGlobalRelativeToPICBase(OpFlags)) {
    Result = DAG.getNode(ISD::ADD, dl, PtrVT,
                         DAG.getNode(X86ISD::GlobalBaseReg, dl, PtrVT), Result);
  }

  return Result;
}

/// Creates target global address or external symbol nodes for calls or
/// other uses.
SDValue X86TargetLowering::LowerGlobalOrExternal(SDValue Op, SelectionDAG &DAG,
                                                 bool ForCall) const {
  // Unpack the global address or external symbol.
  const SDLoc &dl = SDLoc(Op);
  const GlobalValue *GV = nullptr;
  int64_t Offset = 0;
  const char *ExternalSym = nullptr;
  if (const auto *G = dyn_cast<GlobalAddressSDNode>(Op)) {
    GV = G->getGlobal();
    Offset = G->getOffset();
  } else {
    const auto *ES = cast<ExternalSymbolSDNode>(Op);
    ExternalSym = ES->getSymbol();
  }

  // Calculate some flags for address lowering.
  const Module &Mod = *DAG.getMachineFunction().getFunction().getParent();
  unsigned char OpFlags;
  if (ForCall)
    OpFlags = Subtarget.classifyGlobalFunctionReference(GV, Mod);
  else
    OpFlags = Subtarget.classifyGlobalReference(GV, Mod);
  bool HasPICReg = isGlobalRelativeToPICBase(OpFlags);
  bool NeedsLoad = isGlobalStubReference(OpFlags);

  CodeModel::Model M = DAG.getTarget().getCodeModel();
  auto PtrVT = getPointerTy(DAG.getDataLayout());
  SDValue Result;

  if (GV) {
    // Create a target global address if this is a global. If possible, fold the
    // offset into the global address reference. Otherwise, ADD it on later.
    int64_t GlobalOffset = 0;
    if (OpFlags == X86II::MO_NO_FLAG &&
        X86::isOffsetSuitableForCodeModel(Offset, M)) {
      std::swap(GlobalOffset, Offset);
    }
    Result = DAG.getTargetGlobalAddress(GV, dl, PtrVT, GlobalOffset, OpFlags);
  } else {
    // If this is not a global address, this must be an external symbol.
    Result = DAG.getTargetExternalSymbol(ExternalSym, PtrVT, OpFlags);
  }

  // If this is a direct call, avoid the wrapper if we don't need to do any
  // loads or adds. This allows SDAG ISel to match direct calls.
  if (ForCall && !NeedsLoad && !HasPICReg && Offset == 0)
    return Result;

  Result = DAG.getNode(getGlobalWrapperKind(GV, OpFlags), dl, PtrVT, Result);

  // With PIC, the address is actually $g + Offset.
  if (HasPICReg) {
    Result = DAG.getNode(ISD::ADD, dl, PtrVT,
                         DAG.getNode(X86ISD::GlobalBaseReg, dl, PtrVT), Result);
  }

  // For globals that require a load from a stub to get the address, emit the
  // load.
  if (NeedsLoad)
    Result = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Result,
                         MachinePointerInfo::getGOT(DAG.getMachineFunction()));

  // If there was a non-zero offset that we didn't fold, create an explicit
  // addition for it.
  if (Offset != 0)
    Result = DAG.getNode(ISD::ADD, dl, PtrVT, Result,
                         DAG.getConstant(Offset, dl, PtrVT));

  return Result;
}

SDValue
X86TargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const {
  return LowerGlobalOrExternal(Op, DAG, /*ForCall=*/false);
}

static SDValue
GetTLSADDR(SelectionDAG &DAG, SDValue Chain, GlobalAddressSDNode *GA,
           SDValue *InFlag, const EVT PtrVT, unsigned ReturnReg,
           unsigned char OperandFlags, bool LocalDynamic = false) {
  MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
  SDLoc dl(GA);
  SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(), dl,
                                           GA->getValueType(0),
                                           GA->getOffset(),
                                           OperandFlags);

  X86ISD::NodeType CallType = LocalDynamic ? X86ISD::TLSBASEADDR
                                           : X86ISD::TLSADDR;

  if (InFlag) {
    SDValue Ops[] = { Chain,  TGA, *InFlag };
    Chain = DAG.getNode(CallType, dl, NodeTys, Ops);
  } else {
    SDValue Ops[]  = { Chain, TGA };
    Chain = DAG.getNode(CallType, dl, NodeTys, Ops);
  }

  // TLSADDR will be codegen'ed as call. Inform MFI that function has calls.
  MFI.setAdjustsStack(true);
  MFI.setHasCalls(true);

  SDValue Flag = Chain.getValue(1);
  return DAG.getCopyFromReg(Chain, dl, ReturnReg, PtrVT, Flag);
}

// Lower ISD::GlobalTLSAddress using the "general dynamic" model, 32 bit
static SDValue
LowerToTLSGeneralDynamicModel32(GlobalAddressSDNode *GA, SelectionDAG &DAG,
                                const EVT PtrVT) {
  SDValue InFlag;
  SDLoc dl(GA);  // ? function entry point might be better
  SDValue Chain = DAG.getCopyToReg(DAG.getEntryNode(), dl, X86::EBX,
                                   DAG.getNode(X86ISD::GlobalBaseReg,
                                               SDLoc(), PtrVT), InFlag);
  InFlag = Chain.getValue(1);

  return GetTLSADDR(DAG, Chain, GA, &InFlag, PtrVT, X86::EAX, X86II::MO_TLSGD);
}

// Lower ISD::GlobalTLSAddress using the "general dynamic" model, 64 bit
static SDValue
LowerToTLSGeneralDynamicModel64(GlobalAddressSDNode *GA, SelectionDAG &DAG,
                                const EVT PtrVT) {
  return GetTLSADDR(DAG, DAG.getEntryNode(), GA, nullptr, PtrVT,
                    X86::RAX, X86II::MO_TLSGD);
}

static SDValue LowerToTLSLocalDynamicModel(GlobalAddressSDNode *GA,
                                           SelectionDAG &DAG,
                                           const EVT PtrVT,
                                           bool is64Bit) {
  SDLoc dl(GA);

  // Get the start address of the TLS block for this module.
  X86MachineFunctionInfo *MFI = DAG.getMachineFunction()
      .getInfo<X86MachineFunctionInfo>();
  MFI->incNumLocalDynamicTLSAccesses();

  SDValue Base;
  if (is64Bit) {
    Base = GetTLSADDR(DAG, DAG.getEntryNode(), GA, nullptr, PtrVT, X86::RAX,
                      X86II::MO_TLSLD, /*LocalDynamic=*/true);
  } else {
    SDValue InFlag;
    SDValue Chain = DAG.getCopyToReg(DAG.getEntryNode(), dl, X86::EBX,
        DAG.getNode(X86ISD::GlobalBaseReg, SDLoc(), PtrVT), InFlag);
    InFlag = Chain.getValue(1);
    Base = GetTLSADDR(DAG, Chain, GA, &InFlag, PtrVT, X86::EAX,
                      X86II::MO_TLSLDM, /*LocalDynamic=*/true);
  }

  // Note: the CleanupLocalDynamicTLSPass will remove redundant computations
  // of Base.

  // Build x@dtpoff.
  unsigned char OperandFlags = X86II::MO_DTPOFF;
  unsigned WrapperKind = X86ISD::Wrapper;
  SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(), dl,
                                           GA->getValueType(0),
                                           GA->getOffset(), OperandFlags);
  SDValue Offset = DAG.getNode(WrapperKind, dl, PtrVT, TGA);

  // Add x@dtpoff with the base.
  return DAG.getNode(ISD::ADD, dl, PtrVT, Offset, Base);
}

// Lower ISD::GlobalTLSAddress using the "initial exec" or "local exec" model.
static SDValue LowerToTLSExecModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,
                                   const EVT PtrVT, TLSModel::Model model,
                                   bool is64Bit, bool isPIC) {
  SDLoc dl(GA);

  // Get the Thread Pointer, which is %gs:0 (32-bit) or %fs:0 (64-bit).
  Value *Ptr = Constant::getNullValue(Type::getInt8PtrTy(*DAG.getContext(),
                                                         is64Bit ? 257 : 256));

  SDValue ThreadPointer =
      DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), DAG.getIntPtrConstant(0, dl),
                  MachinePointerInfo(Ptr));

  unsigned char OperandFlags = 0;
  // Most TLS accesses are not RIP relative, even on x86-64.  One exception is
  // initialexec.
  unsigned WrapperKind = X86ISD::Wrapper;
  if (model == TLSModel::LocalExec) {
    OperandFlags = is64Bit ? X86II::MO_TPOFF : X86II::MO_NTPOFF;
  } else if (model == TLSModel::InitialExec) {
    if (is64Bit) {
      OperandFlags = X86II::MO_GOTTPOFF;
      WrapperKind = X86ISD::WrapperRIP;
    } else {
      OperandFlags = isPIC ? X86II::MO_GOTNTPOFF : X86II::MO_INDNTPOFF;
    }
  } else {
    llvm_unreachable("Unexpected model");
  }

  // emit "addl x@ntpoff,%eax" (local exec)
  // or "addl x@indntpoff,%eax" (initial exec)
  // or "addl x@gotntpoff(%ebx) ,%eax" (initial exec, 32-bit pic)
  SDValue TGA =
      DAG.getTargetGlobalAddress(GA->getGlobal(), dl, GA->getValueType(0),
                                 GA->getOffset(), OperandFlags);
  SDValue Offset = DAG.getNode(WrapperKind, dl, PtrVT, TGA);

  if (model == TLSModel::InitialExec) {
    if (isPIC && !is64Bit) {
      Offset = DAG.getNode(ISD::ADD, dl, PtrVT,
                           DAG.getNode(X86ISD::GlobalBaseReg, SDLoc(), PtrVT),
                           Offset);
    }

    Offset = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Offset,
                         MachinePointerInfo::getGOT(DAG.getMachineFunction()));
  }

  // The address of the thread local variable is the add of the thread
  // pointer with the offset of the variable.
  return DAG.getNode(ISD::ADD, dl, PtrVT, ThreadPointer, Offset);
}

SDValue
X86TargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {

  GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);

  if (DAG.getTarget().useEmulatedTLS())
    return LowerToTLSEmulatedModel(GA, DAG);

  const GlobalValue *GV = GA->getGlobal();
  auto PtrVT = getPointerTy(DAG.getDataLayout());
  bool PositionIndependent = isPositionIndependent();

  if (Subtarget.isTargetELF()) {
    TLSModel::Model model = DAG.getTarget().getTLSModel(GV);
    switch (model) {
      case TLSModel::GeneralDynamic:
        if (Subtarget.is64Bit())
          return LowerToTLSGeneralDynamicModel64(GA, DAG, PtrVT);
        return LowerToTLSGeneralDynamicModel32(GA, DAG, PtrVT);
      case TLSModel::LocalDynamic:
        return LowerToTLSLocalDynamicModel(GA, DAG, PtrVT,
                                           Subtarget.is64Bit());
      case TLSModel::InitialExec:
      case TLSModel::LocalExec:
        return LowerToTLSExecModel(GA, DAG, PtrVT, model, Subtarget.is64Bit(),
                                   PositionIndependent);
    }
    llvm_unreachable("Unknown TLS model.");
  }

  if (Subtarget.isTargetDarwin()) {
    // Darwin only has one model of TLS.  Lower to that.
    unsigned char OpFlag = 0;
    unsigned WrapperKind = Subtarget.isPICStyleRIPRel() ?
                           X86ISD::WrapperRIP : X86ISD::Wrapper;

    // In PIC mode (unless we're in RIPRel PIC mode) we add an offset to the
    // global base reg.
    bool PIC32 = PositionIndependent && !Subtarget.is64Bit();
    if (PIC32)
      OpFlag = X86II::MO_TLVP_PIC_BASE;
    else
      OpFlag = X86II::MO_TLVP;
    SDLoc DL(Op);
    SDValue Result = DAG.getTargetGlobalAddress(GA->getGlobal(), DL,
                                                GA->getValueType(0),
                                                GA->getOffset(), OpFlag);
    SDValue Offset = DAG.getNode(WrapperKind, DL, PtrVT, Result);

    // With PIC32, the address is actually $g + Offset.
    if (PIC32)
      Offset = DAG.getNode(ISD::ADD, DL, PtrVT,
                           DAG.getNode(X86ISD::GlobalBaseReg, SDLoc(), PtrVT),
                           Offset);

    // Lowering the machine isd will make sure everything is in the right
    // location.
    SDValue Chain = DAG.getEntryNode();
    SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
    Chain = DAG.getCALLSEQ_START(Chain, 0, 0, DL);
    SDValue Args[] = { Chain, Offset };
    Chain = DAG.getNode(X86ISD::TLSCALL, DL, NodeTys, Args);
    Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(0, DL, true),
                               DAG.getIntPtrConstant(0, DL, true),
                               Chain.getValue(1), DL);

    // TLSCALL will be codegen'ed as call. Inform MFI that function has calls.
    MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
    MFI.setAdjustsStack(true);

    // And our return value (tls address) is in the standard call return value
    // location.
    unsigned Reg = Subtarget.is64Bit() ? X86::RAX : X86::EAX;
    return DAG.getCopyFromReg(Chain, DL, Reg, PtrVT, Chain.getValue(1));
  }

  if (Subtarget.isOSWindows()) {
    // Just use the implicit TLS architecture
    // Need to generate something similar to:
    //   mov     rdx, qword [gs:abs 58H]; Load pointer to ThreadLocalStorage
    //                                  ; from TEB
    //   mov     ecx, dword [rel _tls_index]: Load index (from C runtime)
    //   mov     rcx, qword [rdx+rcx*8]
    //   mov     eax, .tls$:tlsvar
    //   [rax+rcx] contains the address
    // Windows 64bit: gs:0x58
    // Windows 32bit: fs:__tls_array

    SDLoc dl(GA);
    SDValue Chain = DAG.getEntryNode();

    // Get the Thread Pointer, which is %fs:__tls_array (32-bit) or
    // %gs:0x58 (64-bit). On MinGW, __tls_array is not available, so directly
    // use its literal value of 0x2C.
    Value *Ptr = Constant::getNullValue(Subtarget.is64Bit()
                                        ? Type::getInt8PtrTy(*DAG.getContext(),
                                                             256)
                                        : Type::getInt32PtrTy(*DAG.getContext(),
                                                              257));

    SDValue TlsArray = Subtarget.is64Bit()
                           ? DAG.getIntPtrConstant(0x58, dl)
                           : (Subtarget.isTargetWindowsGNU()
                                  ? DAG.getIntPtrConstant(0x2C, dl)
                                  : DAG.getExternalSymbol("_tls_array", PtrVT));

    SDValue ThreadPointer =
        DAG.getLoad(PtrVT, dl, Chain, TlsArray, MachinePointerInfo(Ptr));

    SDValue res;
    if (GV->getThreadLocalMode() == GlobalVariable::LocalExecTLSModel) {
      res = ThreadPointer;
    } else {
      // Load the _tls_index variable
      SDValue IDX = DAG.getExternalSymbol("_tls_index", PtrVT);
      if (Subtarget.is64Bit())
        IDX = DAG.getExtLoad(ISD::ZEXTLOAD, dl, PtrVT, Chain, IDX,
                             MachinePointerInfo(), MVT::i32);
      else
        IDX = DAG.getLoad(PtrVT, dl, Chain, IDX, MachinePointerInfo());

      auto &DL = DAG.getDataLayout();
      SDValue Scale =
          DAG.getConstant(Log2_64_Ceil(DL.getPointerSize()), dl, MVT::i8);
      IDX = DAG.getNode(ISD::SHL, dl, PtrVT, IDX, Scale);

      res = DAG.getNode(ISD::ADD, dl, PtrVT, ThreadPointer, IDX);
    }

    res = DAG.getLoad(PtrVT, dl, Chain, res, MachinePointerInfo());

    // Get the offset of start of .tls section
    SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(), dl,
                                             GA->getValueType(0),
                                             GA->getOffset(), X86II::MO_SECREL);
    SDValue Offset = DAG.getNode(X86ISD::Wrapper, dl, PtrVT, TGA);

    // The address of the thread local variable is the add of the thread
    // pointer with the offset of the variable.
    return DAG.getNode(ISD::ADD, dl, PtrVT, res, Offset);
  }

  llvm_unreachable("TLS not implemented for this target.");
}

/// Lower SRA_PARTS and friends, which return two i32 values
/// and take a 2 x i32 value to shift plus a shift amount.
/// TODO: Can this be moved to general expansion code?
static SDValue LowerShiftParts(SDValue Op, SelectionDAG &DAG) {
  assert(Op.getNumOperands() == 3 && "Not a double-shift!");
  MVT VT = Op.getSimpleValueType();
  unsigned VTBits = VT.getSizeInBits();
  SDLoc dl(Op);
  bool isSRA = Op.getOpcode() == ISD::SRA_PARTS;
  SDValue ShOpLo = Op.getOperand(0);
  SDValue ShOpHi = Op.getOperand(1);
  SDValue ShAmt  = Op.getOperand(2);
  // ISD::FSHL and ISD::FSHR have defined overflow behavior but ISD::SHL and
  // ISD::SRA/L nodes haven't. Insert an AND to be safe, it's optimized away
  // during isel.
  SDValue SafeShAmt = DAG.getNode(ISD::AND, dl, MVT::i8, ShAmt,
                                  DAG.getConstant(VTBits - 1, dl, MVT::i8));
  SDValue Tmp1 = isSRA ? DAG.getNode(ISD::SRA, dl, VT, ShOpHi,
                                     DAG.getConstant(VTBits - 1, dl, MVT::i8))
                       : DAG.getConstant(0, dl, VT);

  SDValue Tmp2, Tmp3;
  if (Op.getOpcode() == ISD::SHL_PARTS) {
    Tmp2 = DAG.getNode(ISD::FSHL, dl, VT, ShOpHi, ShOpLo, ShAmt);
    Tmp3 = DAG.getNode(ISD::SHL, dl, VT, ShOpLo, SafeShAmt);
  } else {
    Tmp2 = DAG.getNode(ISD::FSHR, dl, VT, ShOpHi, ShOpLo, ShAmt);
    Tmp3 = DAG.getNode(isSRA ? ISD::SRA : ISD::SRL, dl, VT, ShOpHi, SafeShAmt);
  }

  // If the shift amount is larger or equal than the width of a part we can't
  // rely on the results of shld/shrd. Insert a test and select the appropriate
  // values for large shift amounts.
  SDValue AndNode = DAG.getNode(ISD::AND, dl, MVT::i8, ShAmt,
                                DAG.getConstant(VTBits, dl, MVT::i8));
  SDValue Cond = DAG.getSetCC(dl, MVT::i8, AndNode,
                             DAG.getConstant(0, dl, MVT::i8), ISD::SETNE);

  SDValue Hi, Lo;
  if (Op.getOpcode() == ISD::SHL_PARTS) {
    Hi = DAG.getNode(ISD::SELECT, dl, VT, Cond, Tmp3, Tmp2);
    Lo = DAG.getNode(ISD::SELECT, dl, VT, Cond, Tmp1, Tmp3);
  } else {
    Lo = DAG.getNode(ISD::SELECT, dl, VT, Cond, Tmp3, Tmp2);
    Hi = DAG.getNode(ISD::SELECT, dl, VT, Cond, Tmp1, Tmp3);
  }

  return DAG.getMergeValues({ Lo, Hi }, dl);
}

static SDValue LowerFunnelShift(SDValue Op, const X86Subtarget &Subtarget,
                                SelectionDAG &DAG) {
  MVT VT = Op.getSimpleValueType();
  assert((Op.getOpcode() == ISD::FSHL || Op.getOpcode() == ISD::FSHR) &&
         "Unexpected funnel shift opcode!");

  SDLoc DL(Op);
  SDValue Op0 = Op.getOperand(0);
  SDValue Op1 = Op.getOperand(1);
  SDValue Amt = Op.getOperand(2);

  bool IsFSHR = Op.getOpcode() == ISD::FSHR;

  if (VT.isVector()) {
    assert(Subtarget.hasVBMI2() && "Expected VBMI2");

    if (IsFSHR)
      std::swap(Op0, Op1);

    APInt APIntShiftAmt;
    if (X86::isConstantSplat(Amt, APIntShiftAmt)) {
      uint64_t ShiftAmt = APIntShiftAmt.urem(VT.getScalarSizeInBits());
      return DAG.getNode(IsFSHR ? X86ISD::VSHRD : X86ISD::VSHLD, DL, VT, Op0,
                         Op1, DAG.getTargetConstant(ShiftAmt, DL, MVT::i8));
    }

    return DAG.getNode(IsFSHR ? X86ISD::VSHRDV : X86ISD::VSHLDV, DL, VT,
                       Op0, Op1, Amt);
  }

  assert((VT == MVT::i16 || VT == MVT::i32 || VT == MVT::i64) &&
         "Unexpected funnel shift type!");

  // Expand slow SHLD/SHRD cases if we are not optimizing for size.
  bool OptForSize = DAG.shouldOptForSize();
  if (!OptForSize && Subtarget.isSHLDSlow())
    return SDValue();

  // i16 needs to modulo the shift amount, but i32/i64 have implicit modulo.
  if (VT == MVT::i16) {
    Amt = DAG.getNode(ISD::AND, DL, Amt.getValueType(), Amt,
                      DAG.getConstant(15, DL, Amt.getValueType()));
    unsigned FSHOp = (IsFSHR ? X86ISD::FSHR : X86ISD::FSHL);
    return DAG.getNode(FSHOp, DL, VT, Op0, Op1, Amt);
  }

  return Op;
}

// Try to use a packed vector operation to handle i64 on 32-bit targets when
// AVX512DQ is enabled.
static SDValue LowerI64IntToFP_AVX512DQ(SDValue Op, SelectionDAG &DAG,
                                        const X86Subtarget &Subtarget) {
  assert((Op.getOpcode() == ISD::SINT_TO_FP ||
          Op.getOpcode() == ISD::STRICT_SINT_TO_FP ||
          Op.getOpcode() == ISD::STRICT_UINT_TO_FP ||
          Op.getOpcode() == ISD::UINT_TO_FP) &&
         "Unexpected opcode!");
  bool IsStrict = Op->isStrictFPOpcode();
  unsigned OpNo = IsStrict ? 1 : 0;
  SDValue Src = Op.getOperand(OpNo);
  MVT SrcVT = Src.getSimpleValueType();
  MVT VT = Op.getSimpleValueType();

   if (!Subtarget.hasDQI() || SrcVT != MVT::i64 || Subtarget.is64Bit() ||
       (VT != MVT::f32 && VT != MVT::f64))
    return SDValue();

  // Pack the i64 into a vector, do the operation and extract.

  // Using 256-bit to ensure result is 128-bits for f32 case.
  unsigned NumElts = Subtarget.hasVLX() ? 4 : 8;
  MVT VecInVT = MVT::getVectorVT(MVT::i64, NumElts);
  MVT VecVT = MVT::getVectorVT(VT, NumElts);

  SDLoc dl(Op);
  SDValue InVec = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VecInVT, Src);
  if (IsStrict) {
    SDValue CvtVec = DAG.getNode(Op.getOpcode(), dl, {VecVT, MVT::Other},
                                 {Op.getOperand(0), InVec});
    SDValue Chain = CvtVec.getValue(1);
    SDValue Value = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT, CvtVec,
                                DAG.getIntPtrConstant(0, dl));
    return DAG.getMergeValues({Value, Chain}, dl);
  }

  SDValue CvtVec = DAG.getNode(Op.getOpcode(), dl, VecVT, InVec);

  return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT, CvtVec,
                     DAG.getIntPtrConstant(0, dl));
}

static bool useVectorCast(unsigned Opcode, MVT FromVT, MVT ToVT,
                          const X86Subtarget &Subtarget) {
  switch (Opcode) {
    case ISD::SINT_TO_FP:
      // TODO: Handle wider types with AVX/AVX512.
      if (!Subtarget.hasSSE2() || FromVT != MVT::v4i32)
        return false;
      // CVTDQ2PS or (V)CVTDQ2PD
      return ToVT == MVT::v4f32 || (Subtarget.hasAVX() && ToVT == MVT::v4f64);

    case ISD::UINT_TO_FP:
      // TODO: Handle wider types and i64 elements.
      if (!Subtarget.hasAVX512() || FromVT != MVT::v4i32)
        return false;
      // VCVTUDQ2PS or VCVTUDQ2PD
      return ToVT == MVT::v4f32 || ToVT == MVT::v4f64;

    default:
      return false;
  }
}

/// Given a scalar cast operation that is extracted from a vector, try to
/// vectorize the cast op followed by extraction. This will avoid an expensive
/// round-trip between XMM and GPR.
static SDValue vectorizeExtractedCast(SDValue Cast, SelectionDAG &DAG,
                                      const X86Subtarget &Subtarget) {
  // TODO: This could be enhanced to handle smaller integer types by peeking
  // through an extend.
  SDValue Extract = Cast.getOperand(0);
  MVT DestVT = Cast.getSimpleValueType();
  if (Extract.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
      !isa<ConstantSDNode>(Extract.getOperand(1)))
    return SDValue();

  // See if we have a 128-bit vector cast op for this type of cast.
  SDValue VecOp = Extract.getOperand(0);
  MVT FromVT = VecOp.getSimpleValueType();
  unsigned NumEltsInXMM = 128 / FromVT.getScalarSizeInBits();
  MVT Vec128VT = MVT::getVectorVT(FromVT.getScalarType(), NumEltsInXMM);
  MVT ToVT = MVT::getVectorVT(DestVT, NumEltsInXMM);
  if (!useVectorCast(Cast.getOpcode(), Vec128VT, ToVT, Subtarget))
    return SDValue();

  // If we are extracting from a non-zero element, first shuffle the source
  // vector to allow extracting from element zero.
  SDLoc DL(Cast);
  if (!isNullConstant(Extract.getOperand(1))) {
    SmallVector<int, 16> Mask(FromVT.getVectorNumElements(), -1);
    Mask[0] = Extract.getConstantOperandVal(1);
    VecOp = DAG.getVectorShuffle(FromVT, DL, VecOp, DAG.getUNDEF(FromVT), Mask);
  }
  // If the source vector is wider than 128-bits, extract the low part. Do not
  // create an unnecessarily wide vector cast op.
  if (FromVT != Vec128VT)
    VecOp = extract128BitVector(VecOp, 0, DAG, DL);

  // cast (extelt V, 0) --> extelt (cast (extract_subv V)), 0
  // cast (extelt V, C) --> extelt (cast (extract_subv (shuffle V, [C...]))), 0
  SDValue VCast = DAG.getNode(Cast.getOpcode(), DL, ToVT, VecOp);
  return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, DestVT, VCast,
                     DAG.getIntPtrConstant(0, DL));
}

static SDValue lowerINT_TO_FP_vXi64(SDValue Op, SelectionDAG &DAG,
                                    const X86Subtarget &Subtarget) {
  SDLoc DL(Op);
  bool IsStrict = Op->isStrictFPOpcode();
  MVT VT = Op->getSimpleValueType(0);
  SDValue Src = Op->getOperand(IsStrict ? 1 : 0);

  if (Subtarget.hasDQI()) {
    assert(!Subtarget.hasVLX() && "Unexpected features");

    assert((Src.getSimpleValueType() == MVT::v2i64 ||
            Src.getSimpleValueType() == MVT::v4i64) &&
           "Unsupported custom type");

    // With AVX512DQ, but not VLX we need to widen to get a 512-bit result type.
    assert((VT == MVT::v4f32 || VT == MVT::v2f64 || VT == MVT::v4f64) &&
           "Unexpected VT!");
    MVT WideVT = VT == MVT::v4f32 ? MVT::v8f32 : MVT::v8f64;

    // Need to concat with zero vector for strict fp to avoid spurious
    // exceptions.
    SDValue Tmp = IsStrict ? DAG.getConstant(0, DL, MVT::v8i64)
                           : DAG.getUNDEF(MVT::v8i64);
    Src = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, MVT::v8i64, Tmp, Src,
                      DAG.getIntPtrConstant(0, DL));
    SDValue Res, Chain;
    if (IsStrict) {
      Res = DAG.getNode(Op.getOpcode(), DL, {WideVT, MVT::Other},
                        {Op->getOperand(0), Src});
      Chain = Res.getValue(1);
    } else {
      Res = DAG.getNode(Op.getOpcode(), DL, WideVT, Src);
    }

    Res = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, VT, Res,
                      DAG.getIntPtrConstant(0, DL));

    if (IsStrict)
      return DAG.getMergeValues({Res, Chain}, DL);
    return Res;
  }

  bool IsSigned = Op->getOpcode() == ISD::SINT_TO_FP ||
                  Op->getOpcode() == ISD::STRICT_SINT_TO_FP;
  if (VT != MVT::v4f32 || IsSigned)
    return SDValue();

  SDValue Zero = DAG.getConstant(0, DL, MVT::v4i64);
  SDValue One  = DAG.getConstant(1, DL, MVT::v4i64);
  SDValue Sign = DAG.getNode(ISD::OR, DL, MVT::v4i64,
                             DAG.getNode(ISD::SRL, DL, MVT::v4i64, Src, One),
                             DAG.getNode(ISD::AND, DL, MVT::v4i64, Src, One));
  SDValue IsNeg = DAG.getSetCC(DL, MVT::v4i64, Src, Zero, ISD::SETLT);
  SDValue SignSrc = DAG.getSelect(DL, MVT::v4i64, IsNeg, Sign, Src);
  SmallVector<SDValue, 4> SignCvts(4);
  SmallVector<SDValue, 4> Chains(4);
  for (int i = 0; i != 4; ++i) {
    SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i64, SignSrc,
                              DAG.getIntPtrConstant(i, DL));
    if (IsStrict) {
      SignCvts[i] =
          DAG.getNode(ISD::STRICT_SINT_TO_FP, DL, {MVT::f32, MVT::Other},
                      {Op.getOperand(0), Elt});
      Chains[i] = SignCvts[i].getValue(1);
    } else {
      SignCvts[i] = DAG.getNode(ISD::SINT_TO_FP, DL, MVT::f32, Elt);
    }
  }
  SDValue SignCvt = DAG.getBuildVector(VT, DL, SignCvts);

  SDValue Slow, Chain;
  if (IsStrict) {
    Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
    Slow = DAG.getNode(ISD::STRICT_FADD, DL, {MVT::v4f32, MVT::Other},
                       {Chain, SignCvt, SignCvt});
    Chain = Slow.getValue(1);
  } else {
    Slow = DAG.getNode(ISD::FADD, DL, MVT::v4f32, SignCvt, SignCvt);
  }

  IsNeg = DAG.getNode(ISD::TRUNCATE, DL, MVT::v4i32, IsNeg);
  SDValue Cvt = DAG.getSelect(DL, MVT::v4f32, IsNeg, Slow, SignCvt);

  if (IsStrict)
    return DAG.getMergeValues({Cvt, Chain}, DL);

  return Cvt;
}

SDValue X86TargetLowering::LowerSINT_TO_FP(SDValue Op,
                                           SelectionDAG &DAG) const {
  bool IsStrict = Op->isStrictFPOpcode();
  unsigned OpNo = IsStrict ? 1 : 0;
  SDValue Src = Op.getOperand(OpNo);
  SDValue Chain = IsStrict ? Op->getOperand(0) : DAG.getEntryNode();
  MVT SrcVT = Src.getSimpleValueType();
  MVT VT = Op.getSimpleValueType();
  SDLoc dl(Op);

  if (SDValue Extract = vectorizeExtractedCast(Op, DAG, Subtarget))
    return Extract;

  if (SrcVT.isVector()) {
    if (SrcVT == MVT::v2i32 && VT == MVT::v2f64) {
      // Note: Since v2f64 is a legal type. We don't need to zero extend the
      // source for strict FP.
      if (IsStrict)
        return DAG.getNode(
            X86ISD::STRICT_CVTSI2P, dl, {VT, MVT::Other},
            {Chain, DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v4i32, Src,
                                DAG.getUNDEF(SrcVT))});
      return DAG.getNode(X86ISD::CVTSI2P, dl, VT,
                         DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v4i32, Src,
                                     DAG.getUNDEF(SrcVT)));
    }
    if (SrcVT == MVT::v2i64 || SrcVT == MVT::v4i64)
      return lowerINT_TO_FP_vXi64(Op, DAG, Subtarget);

    return SDValue();
  }

  assert(SrcVT <= MVT::i64 && SrcVT >= MVT::i16 &&
         "Unknown SINT_TO_FP to lower!");

  bool UseSSEReg = isScalarFPTypeInSSEReg(VT);

  // These are really Legal; return the operand so the caller accepts it as
  // Legal.
  if (SrcVT == MVT::i32 && UseSSEReg)
    return Op;
  if (SrcVT == MVT::i64 && UseSSEReg && Subtarget.is64Bit())
    return Op;

  if (SDValue V = LowerI64IntToFP_AVX512DQ(Op, DAG, Subtarget))
    return V;

  // SSE doesn't have an i16 conversion so we need to promote.
  if (SrcVT == MVT::i16 && (UseSSEReg || VT == MVT::f128)) {
    SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i32, Src);
    if (IsStrict)
      return DAG.getNode(ISD::STRICT_SINT_TO_FP, dl, {VT, MVT::Other},
                         {Chain, Ext});

    return DAG.getNode(ISD::SINT_TO_FP, dl, VT, Ext);
  }

  if (VT == MVT::f128)
    return LowerF128Call(Op, DAG, RTLIB::getSINTTOFP(SrcVT, VT));

  SDValue ValueToStore = Src;
  if (SrcVT == MVT::i64 && Subtarget.hasSSE2() && !Subtarget.is64Bit())
    // Bitcasting to f64 here allows us to do a single 64-bit store from
    // an SSE register, avoiding the store forwarding penalty that would come
    // with two 32-bit stores.
    ValueToStore = DAG.getBitcast(MVT::f64, ValueToStore);

  unsigned Size = SrcVT.getStoreSize();
  Align Alignment(Size);
  MachineFunction &MF = DAG.getMachineFunction();
  auto PtrVT = getPointerTy(MF.getDataLayout());
  int SSFI = MF.getFrameInfo().CreateStackObject(Size, Alignment, false);
  MachinePointerInfo MPI =
      MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SSFI);
  SDValue StackSlot = DAG.getFrameIndex(SSFI, PtrVT);
  Chain = DAG.getStore(Chain, dl, ValueToStore, StackSlot, MPI, Alignment);
  std::pair<SDValue, SDValue> Tmp =
      BuildFILD(VT, SrcVT, dl, Chain, StackSlot, MPI, Alignment, DAG);

  if (IsStrict)
    return DAG.getMergeValues({Tmp.first, Tmp.second}, dl);

  return Tmp.first;
}

std::pair<SDValue, SDValue> X86TargetLowering::BuildFILD(
    EVT DstVT, EVT SrcVT, const SDLoc &DL, SDValue Chain, SDValue Pointer,
    MachinePointerInfo PtrInfo, Align Alignment, SelectionDAG &DAG) const {
  // Build the FILD
  SDVTList Tys;
  bool useSSE = isScalarFPTypeInSSEReg(DstVT);
  if (useSSE)
    Tys = DAG.getVTList(MVT::f80, MVT::Other);
  else
    Tys = DAG.getVTList(DstVT, MVT::Other);

  SDValue FILDOps[] = {Chain, Pointer};
  SDValue Result =
      DAG.getMemIntrinsicNode(X86ISD::FILD, DL, Tys, FILDOps, SrcVT, PtrInfo,
                              Alignment, MachineMemOperand::MOLoad);
  Chain = Result.getValue(1);

  if (useSSE) {
    MachineFunction &MF = DAG.getMachineFunction();
    unsigned SSFISize = DstVT.getStoreSize();
    int SSFI = MF.getFrameInfo().CreateStackObject(SSFISize, SSFISize, false);
    auto PtrVT = getPointerTy(MF.getDataLayout());
    SDValue StackSlot = DAG.getFrameIndex(SSFI, PtrVT);
    Tys = DAG.getVTList(MVT::Other);
    SDValue FSTOps[] = {Chain, Result, StackSlot};
    MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
        MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SSFI),
        MachineMemOperand::MOStore, SSFISize, Align(SSFISize));

    Chain =
        DAG.getMemIntrinsicNode(X86ISD::FST, DL, Tys, FSTOps, DstVT, StoreMMO);
    Result = DAG.getLoad(
        DstVT, DL, Chain, StackSlot,
        MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SSFI));
    Chain = Result.getValue(1);
  }

  return { Result, Chain };
}

/// Horizontal vector math instructions may be slower than normal math with
/// shuffles. Limit horizontal op codegen based on size/speed trade-offs, uarch
/// implementation, and likely shuffle complexity of the alternate sequence.
static bool shouldUseHorizontalOp(bool IsSingleSource, SelectionDAG &DAG,
                                  const X86Subtarget &Subtarget) {
  bool IsOptimizingSize = DAG.shouldOptForSize();
  bool HasFastHOps = Subtarget.hasFastHorizontalOps();
  return !IsSingleSource || IsOptimizingSize || HasFastHOps;
}

/// 64-bit unsigned integer to double expansion.
static SDValue LowerUINT_TO_FP_i64(SDValue Op, SelectionDAG &DAG,
                                   const X86Subtarget &Subtarget) {
  // This algorithm is not obvious. Here it is what we're trying to output:
  /*
     movq       %rax,  %xmm0
     punpckldq  (c0),  %xmm0  // c0: (uint4){ 0x43300000U, 0x45300000U, 0U, 0U }
     subpd      (c1),  %xmm0  // c1: (double2){ 0x1.0p52, 0x1.0p52 * 0x1.0p32 }
     #ifdef __SSE3__
       haddpd   %xmm0, %xmm0
     #else
       pshufd   $0x4e, %xmm0, %xmm1
       addpd    %xmm1, %xmm0
     #endif
  */

  bool IsStrict = Op->isStrictFPOpcode();
  unsigned OpNo = IsStrict ? 1 : 0;
  SDLoc dl(Op);
  LLVMContext *Context = DAG.getContext();

  // Build some magic constants.
  static const uint32_t CV0[] = { 0x43300000, 0x45300000, 0, 0 };
  Constant *C0 = ConstantDataVector::get(*Context, CV0);
  auto PtrVT = DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout());
  SDValue CPIdx0 = DAG.getConstantPool(C0, PtrVT, 16);

  SmallVector<Constant*,2> CV1;
  CV1.push_back(
    ConstantFP::get(*Context, APFloat(APFloat::IEEEdouble(),
                                      APInt(64, 0x4330000000000000ULL))));
  CV1.push_back(
    ConstantFP::get(*Context, APFloat(APFloat::IEEEdouble(),
                                      APInt(64, 0x4530000000000000ULL))));
  Constant *C1 = ConstantVector::get(CV1);
  SDValue CPIdx1 = DAG.getConstantPool(C1, PtrVT, 16);

  // Load the 64-bit value into an XMM register.
  SDValue XR1 =
      DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2i64, Op.getOperand(OpNo));
  SDValue CLod0 =
      DAG.getLoad(MVT::v4i32, dl, DAG.getEntryNode(), CPIdx0,
                  MachinePointerInfo::getConstantPool(DAG.getMachineFunction()),
                  /* Alignment = */ 16);
  SDValue Unpck1 =
      getUnpackl(DAG, dl, MVT::v4i32, DAG.getBitcast(MVT::v4i32, XR1), CLod0);

  SDValue CLod1 =
      DAG.getLoad(MVT::v2f64, dl, CLod0.getValue(1), CPIdx1,
                  MachinePointerInfo::getConstantPool(DAG.getMachineFunction()),
                  /* Alignment = */ 16);
  SDValue XR2F = DAG.getBitcast(MVT::v2f64, Unpck1);
  SDValue Sub;
  SDValue Chain;
  // TODO: Are there any fast-math-flags to propagate here?
  if (IsStrict) {
    Sub = DAG.getNode(ISD::STRICT_FSUB, dl, {MVT::v2f64, MVT::Other},
                      {Op.getOperand(0), XR2F, CLod1});
    Chain = Sub.getValue(1);
  } else
    Sub = DAG.getNode(ISD::FSUB, dl, MVT::v2f64, XR2F, CLod1);
  SDValue Result;

  if (!IsStrict && Subtarget.hasSSE3() &&
      shouldUseHorizontalOp(true, DAG, Subtarget)) {
    // FIXME: Do we need a STRICT version of FHADD?
    Result = DAG.getNode(X86ISD::FHADD, dl, MVT::v2f64, Sub, Sub);
  } else {
    SDValue Shuffle = DAG.getVectorShuffle(MVT::v2f64, dl, Sub, Sub, {1,-1});
    if (IsStrict) {
      Result = DAG.getNode(ISD::STRICT_FADD, dl, {MVT::v2f64, MVT::Other},
                           {Chain, Shuffle, Sub});
      Chain = Result.getValue(1);
    } else
      Result = DAG.getNode(ISD::FADD, dl, MVT::v2f64, Shuffle, Sub);
  }
  Result = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Result,
                       DAG.getIntPtrConstant(0, dl));
  if (IsStrict)
    return DAG.getMergeValues({Result, Chain}, dl);

  return Result;
}

/// 32-bit unsigned integer to float expansion.
static SDValue LowerUINT_TO_FP_i32(SDValue Op, SelectionDAG &DAG,
                                   const X86Subtarget &Subtarget) {
  unsigned OpNo = Op.getNode()->isStrictFPOpcode() ? 1 : 0;
  SDLoc dl(Op);
  // FP constant to bias correct the final result.
  SDValue Bias = DAG.getConstantFP(BitsToDouble(0x4330000000000000ULL), dl,
                                   MVT::f64);

  // Load the 32-bit value into an XMM register.
  SDValue Load =
      DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v4i32, Op.getOperand(OpNo));

  // Zero out the upper parts of the register.
  Load = getShuffleVectorZeroOrUndef(Load, 0, true, Subtarget, DAG);

  // Or the load with the bias.
  SDValue Or = DAG.getNode(
      ISD::OR, dl, MVT::v2i64,
      DAG.getBitcast(MVT::v2i64, Load),
      DAG.getBitcast(MVT::v2i64,
                     DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2f64, Bias)));
  Or =
      DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64,
                  DAG.getBitcast(MVT::v2f64, Or), DAG.getIntPtrConstant(0, dl));

  if (Op.getNode()->isStrictFPOpcode()) {
    // Subtract the bias.
    // TODO: Are there any fast-math-flags to propagate here?
    SDValue Chain = Op.getOperand(0);
    SDValue Sub = DAG.getNode(ISD::STRICT_FSUB, dl, {MVT::f64, MVT::Other},
                              {Chain, Or, Bias});

    if (Op.getValueType() == Sub.getValueType())
      return Sub;

    // Handle final rounding.
    std::pair<SDValue, SDValue> ResultPair = DAG.getStrictFPExtendOrRound(
        Sub, Sub.getValue(1), dl, Op.getSimpleValueType());

    return DAG.getMergeValues({ResultPair.first, ResultPair.second}, dl);
  }

  // Subtract the bias.
  // TODO: Are there any fast-math-flags to propagate here?
  SDValue Sub = DAG.getNode(ISD::FSUB, dl, MVT::f64, Or, Bias);

  // Handle final rounding.
  return DAG.getFPExtendOrRound(Sub, dl, Op.getSimpleValueType());
}

static SDValue lowerUINT_TO_FP_v2i32(SDValue Op, SelectionDAG &DAG,
                                     const X86Subtarget &Subtarget,
                                     const SDLoc &DL) {
  if (Op.getSimpleValueType() != MVT::v2f64)
    return SDValue();

  bool IsStrict = Op->isStrictFPOpcode();

  SDValue N0 = Op.getOperand(IsStrict ? 1 : 0);
  assert(N0.getSimpleValueType() == MVT::v2i32 && "Unexpected input type");

  if (Subtarget.hasAVX512()) {
    if (!Subtarget.hasVLX()) {
      // Let generic type legalization widen this.
      if (!IsStrict)
        return SDValue();
      // Otherwise pad the integer input with 0s and widen the operation.
      N0 = DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v4i32, N0,
                       DAG.getConstant(0, DL, MVT::v2i32));
      SDValue Res = DAG.getNode(Op->getOpcode(), DL, {MVT::v4f64, MVT::Other},
                                {Op.getOperand(0), N0});
      SDValue Chain = Res.getValue(1);
      Res = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::v2f64, Res,
                        DAG.getIntPtrConstant(0, DL));
      return DAG.getMergeValues({Res, Chain}, DL);
    }

    // Legalize to v4i32 type.
    N0 = DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v4i32, N0,
                     DAG.getUNDEF(MVT::v2i32));
    if (IsStrict)
      return DAG.getNode(X86ISD::STRICT_CVTUI2P, DL, {MVT::v2f64, MVT::Other},
                         {Op.getOperand(0), N0});
    return DAG.getNode(X86ISD::CVTUI2P, DL, MVT::v2f64, N0);
  }

  // Zero extend to 2i64, OR with the floating point representation of 2^52.
  // This gives us the floating point equivalent of 2^52 + the i32 integer
  // since double has 52-bits of mantissa. Then subtract 2^52 in floating
  // point leaving just our i32 integers in double format.
  SDValue ZExtIn = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::v2i64, N0);
  SDValue VBias =
      DAG.getConstantFP(BitsToDouble(0x4330000000000000ULL), DL, MVT::v2f64);
  SDValue Or = DAG.getNode(ISD::OR, DL, MVT::v2i64, ZExtIn,
                           DAG.getBitcast(MVT::v2i64, VBias));
  Or = DAG.getBitcast(MVT::v2f64, Or);

  if (IsStrict)
    return DAG.getNode(ISD::STRICT_FSUB, DL, {MVT::v2f64, MVT::Other},
                       {Op.getOperand(0), Or, VBias});
  return DAG.getNode(ISD::FSUB, DL, MVT::v2f64, Or, VBias);
}

static SDValue lowerUINT_TO_FP_vXi32(SDValue Op, SelectionDAG &DAG,
                                     const X86Subtarget &Subtarget) {
  SDLoc DL(Op);
  bool IsStrict = Op->isStrictFPOpcode();
  SDValue V = Op->getOperand(IsStrict ? 1 : 0);
  MVT VecIntVT = V.getSimpleValueType();
  assert((VecIntVT == MVT::v4i32 || VecIntVT == MVT::v8i32) &&
         "Unsupported custom type");

  if (Subtarget.hasAVX512()) {
    // With AVX512, but not VLX we need to widen to get a 512-bit result type.
    assert(!Subtarget.hasVLX() && "Unexpected features");
    MVT VT = Op->getSimpleValueType(0);

    // v8i32->v8f64 is legal with AVX512 so just return it.
    if (VT == MVT::v8f64)
      return Op;

    assert((VT == MVT::v4f32 || VT == MVT::v8f32 || VT == MVT::v4f64) &&
           "Unexpected VT!");
    MVT WideVT = VT == MVT::v4f64 ? MVT::v8f64 : MVT::v16f32;
    MVT WideIntVT = VT == MVT::v4f64 ? MVT::v8i32 : MVT::v16i32;
    // Need to concat with zero vector for strict fp to avoid spurious
    // exceptions.
    SDValue Tmp =
        IsStrict ? DAG.getConstant(0, DL, WideIntVT) : DAG.getUNDEF(WideIntVT);
    V = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, WideIntVT, Tmp, V,
                    DAG.getIntPtrConstant(0, DL));
    SDValue Res, Chain;
    if (IsStrict) {
      Res = DAG.getNode(ISD::STRICT_UINT_TO_FP, DL, {WideVT, MVT::Other},
                        {Op->getOperand(0), V});
      Chain = Res.getValue(1);
    } else {
      Res = DAG.getNode(ISD::UINT_TO_FP, DL, WideVT, V);
    }

    Res = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, VT, Res,
                      DAG.getIntPtrConstant(0, DL));

    if (IsStrict)
      return DAG.getMergeValues({Res, Chain}, DL);
    return Res;
  }

  if (Subtarget.hasAVX() && VecIntVT == MVT::v4i32 &&
      Op->getSimpleValueType(0) == MVT::v4f64) {
    SDValue ZExtIn = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::v4i64, V);
    Constant *Bias = ConstantFP::get(
        *DAG.getContext(),
        APFloat(APFloat::IEEEdouble(), APInt(64, 0x4330000000000000ULL)));
    auto PtrVT = DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout());
    SDValue CPIdx = DAG.getConstantPool(Bias, PtrVT, /*Alignment*/ 8);
    SDVTList Tys = DAG.getVTList(MVT::v4f64, MVT::Other);
    SDValue Ops[] = {DAG.getEntryNode(), CPIdx};
    SDValue VBias = DAG.getMemIntrinsicNode(
        X86ISD::VBROADCAST_LOAD, DL, Tys, Ops, MVT::f64,
        MachinePointerInfo::getConstantPool(DAG.getMachineFunction()), Align(8),
        MachineMemOperand::MOLoad);

    SDValue Or = DAG.getNode(ISD::OR, DL, MVT::v4i64, ZExtIn,
                             DAG.getBitcast(MVT::v4i64, VBias));
    Or = DAG.getBitcast(MVT::v4f64, Or);

    if (IsStrict)
      return DAG.getNode(ISD::STRICT_FSUB, DL, {MVT::v4f64, MVT::Other},
                         {Op.getOperand(0), Or, VBias});
    return DAG.getNode(ISD::FSUB, DL, MVT::v4f64, Or, VBias);
  }

  // The algorithm is the following:
  // #ifdef __SSE4_1__
  //     uint4 lo = _mm_blend_epi16( v, (uint4) 0x4b000000, 0xaa);
  //     uint4 hi = _mm_blend_epi16( _mm_srli_epi32(v,16),
  //                                 (uint4) 0x53000000, 0xaa);
  // #else
  //     uint4 lo = (v & (uint4) 0xffff) | (uint4) 0x4b000000;
  //     uint4 hi = (v >> 16) | (uint4) 0x53000000;
  // #endif
  //     float4 fhi = (float4) hi - (0x1.0p39f + 0x1.0p23f);
  //     return (float4) lo + fhi;

  bool Is128 = VecIntVT == MVT::v4i32;
  MVT VecFloatVT = Is128 ? MVT::v4f32 : MVT::v8f32;
  // If we convert to something else than the supported type, e.g., to v4f64,
  // abort early.
  if (VecFloatVT != Op->getSimpleValueType(0))
    return SDValue();

  // In the #idef/#else code, we have in common:
  // - The vector of constants:
  // -- 0x4b000000
  // -- 0x53000000
  // - A shift:
  // -- v >> 16

  // Create the splat vector for 0x4b000000.
  SDValue VecCstLow = DAG.getConstant(0x4b000000, DL, VecIntVT);
  // Create the splat vector for 0x53000000.
  SDValue VecCstHigh = DAG.getConstant(0x53000000, DL, VecIntVT);

  // Create the right shift.
  SDValue VecCstShift = DAG.getConstant(16, DL, VecIntVT);
  SDValue HighShift = DAG.getNode(ISD::SRL, DL, VecIntVT, V, VecCstShift);

  SDValue Low, High;
  if (Subtarget.hasSSE41()) {
    MVT VecI16VT = Is128 ? MVT::v8i16 : MVT::v16i16;
    //     uint4 lo = _mm_blend_epi16( v, (uint4) 0x4b000000, 0xaa);
    SDValue VecCstLowBitcast = DAG.getBitcast(VecI16VT, VecCstLow);
    SDValue VecBitcast = DAG.getBitcast(VecI16VT, V);
    // Low will be bitcasted right away, so do not bother bitcasting back to its
    // original type.
    Low = DAG.getNode(X86ISD::BLENDI, DL, VecI16VT, VecBitcast,
                      VecCstLowBitcast, DAG.getTargetConstant(0xaa, DL, MVT::i8));
    //     uint4 hi = _mm_blend_epi16( _mm_srli_epi32(v,16),
    //                                 (uint4) 0x53000000, 0xaa);
    SDValue VecCstHighBitcast = DAG.getBitcast(VecI16VT, VecCstHigh);
    SDValue VecShiftBitcast = DAG.getBitcast(VecI16VT, HighShift);
    // High will be bitcasted right away, so do not bother bitcasting back to
    // its original type.
    High = DAG.getNode(X86ISD::BLENDI, DL, VecI16VT, VecShiftBitcast,
                       VecCstHighBitcast, DAG.getTargetConstant(0xaa, DL, MVT::i8));
  } else {
    SDValue VecCstMask = DAG.getConstant(0xffff, DL, VecIntVT);
    //     uint4 lo = (v & (uint4) 0xffff) | (uint4) 0x4b000000;
    SDValue LowAnd = DAG.getNode(ISD::AND, DL, VecIntVT, V, VecCstMask);
    Low = DAG.getNode(ISD::OR, DL, VecIntVT, LowAnd, VecCstLow);

    //     uint4 hi = (v >> 16) | (uint4) 0x53000000;
    High = DAG.getNode(ISD::OR, DL, VecIntVT, HighShift, VecCstHigh);
  }

  // Create the vector constant for (0x1.0p39f + 0x1.0p23f).
  SDValue VecCstFSub = DAG.getConstantFP(
      APFloat(APFloat::IEEEsingle(), APInt(32, 0x53000080)), DL, VecFloatVT);

  //     float4 fhi = (float4) hi - (0x1.0p39f + 0x1.0p23f);
  // NOTE: By using fsub of a positive constant instead of fadd of a negative
  // constant, we avoid reassociation in MachineCombiner when unsafe-fp-math is
  // enabled. See PR24512.
  SDValue HighBitcast = DAG.getBitcast(VecFloatVT, High);
  // TODO: Are there any fast-math-flags to propagate here?
  //     (float4) lo;
  SDValue LowBitcast = DAG.getBitcast(VecFloatVT, Low);
  //     return (float4) lo + fhi;
  if (IsStrict) {
    SDValue FHigh = DAG.getNode(ISD::STRICT_FSUB, DL, {VecFloatVT, MVT::Other},
                                {Op.getOperand(0), HighBitcast, VecCstFSub});
    return DAG.getNode(ISD::STRICT_FADD, DL, {VecFloatVT, MVT::Other},
                       {FHigh.getValue(1), LowBitcast, FHigh});
  }

  SDValue FHigh =
      DAG.getNode(ISD::FSUB, DL, VecFloatVT, HighBitcast, VecCstFSub);
  return DAG.getNode(ISD::FADD, DL, VecFloatVT, LowBitcast, FHigh);
}

static SDValue lowerUINT_TO_FP_vec(SDValue Op, SelectionDAG &DAG,
                                   const X86Subtarget &Subtarget) {
  unsigned OpNo = Op.getNode()->isStrictFPOpcode() ? 1 : 0;
  SDValue N0 = Op.getOperand(OpNo);
  MVT SrcVT = N0.getSimpleValueType();
  SDLoc dl(Op);

  switch (SrcVT.SimpleTy) {
  default:
    llvm_unreachable("Custom UINT_TO_FP is not supported!");
  case MVT::v2i32:
    return lowerUINT_TO_FP_v2i32(Op, DAG, Subtarget, dl);
  case MVT::v4i32:
  case MVT::v8i32:
    return lowerUINT_TO_FP_vXi32(Op, DAG, Subtarget);
  case MVT::v2i64:
  case MVT::v4i64:
    return lowerINT_TO_FP_vXi64(Op, DAG, Subtarget);
  }
}

SDValue X86TargetLowering::LowerUINT_TO_FP(SDValue Op,
                                           SelectionDAG &DAG) const {
  bool IsStrict = Op->isStrictFPOpcode();
  unsigned OpNo = IsStrict ? 1 : 0;
  SDValue Src = Op.getOperand(OpNo);
  SDLoc dl(Op);
  auto PtrVT = getPointerTy(DAG.getDataLayout());
  MVT SrcVT = Src.getSimpleValueType();
  MVT DstVT = Op->getSimpleValueType(0);
  SDValue Chain = IsStrict ? Op.getOperand(0) : DAG.getEntryNode();

  if (DstVT == MVT::f128)
    return LowerF128Call(Op, DAG, RTLIB::getUINTTOFP(SrcVT, DstVT));

  if (DstVT.isVector())
    return lowerUINT_TO_FP_vec(Op, DAG, Subtarget);

  if (SDValue Extract = vectorizeExtractedCast(Op, DAG, Subtarget))
    return Extract;

  if (Subtarget.hasAVX512() && isScalarFPTypeInSSEReg(DstVT) &&
      (SrcVT == MVT::i32 || (SrcVT == MVT::i64 && Subtarget.is64Bit()))) {
    // Conversions from unsigned i32 to f32/f64 are legal,
    // using VCVTUSI2SS/SD.  Same for i64 in 64-bit mode.
    return Op;
  }

  // Promote i32 to i64 and use a signed conversion on 64-bit targets.
  if (SrcVT == MVT::i32 && Subtarget.is64Bit()) {
    Src = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i64, Src);
    if (IsStrict)
      return DAG.getNode(ISD::STRICT_SINT_TO_FP, dl, {DstVT, MVT::Other},
                         {Chain, Src});
    return DAG.getNode(ISD::SINT_TO_FP, dl, DstVT, Src);
  }

  if (SDValue V = LowerI64IntToFP_AVX512DQ(Op, DAG, Subtarget))
    return V;

  if (SrcVT == MVT::i64 && DstVT == MVT::f64 && X86ScalarSSEf64)
    return LowerUINT_TO_FP_i64(Op, DAG, Subtarget);
  if (SrcVT == MVT::i32 && X86ScalarSSEf64 && DstVT != MVT::f80)
    return LowerUINT_TO_FP_i32(Op, DAG, Subtarget);
  if (Subtarget.is64Bit() && SrcVT == MVT::i64 && DstVT == MVT::f32)
    return SDValue();

  // Make a 64-bit buffer, and use it to build an FILD.
  SDValue StackSlot = DAG.CreateStackTemporary(MVT::i64, 8);
  int SSFI = cast<FrameIndexSDNode>(StackSlot)->getIndex();
  MachinePointerInfo MPI =
    MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SSFI);
  if (SrcVT == MVT::i32) {
    SDValue OffsetSlot = DAG.getMemBasePlusOffset(StackSlot, 4, dl);
    SDValue Store1 =
        DAG.getStore(Chain, dl, Src, StackSlot, MPI, 8 /*Align*/);
    SDValue Store2 = DAG.getStore(Store1, dl, DAG.getConstant(0, dl, MVT::i32),
                                  OffsetSlot, MPI.getWithOffset(4), 4);
    std::pair<SDValue, SDValue> Tmp =
        BuildFILD(DstVT, MVT::i64, dl, Store2, StackSlot, MPI, Align(8), DAG);
    if (IsStrict)
      return DAG.getMergeValues({Tmp.first, Tmp.second}, dl);

    return Tmp.first;
  }

  assert(SrcVT == MVT::i64 && "Unexpected type in UINT_TO_FP");
  SDValue ValueToStore = Src;
  if (isScalarFPTypeInSSEReg(Op.getValueType()) && !Subtarget.is64Bit()) {
    // Bitcasting to f64 here allows us to do a single 64-bit store from
    // an SSE register, avoiding the store forwarding penalty that would come
    // with two 32-bit stores.
    ValueToStore = DAG.getBitcast(MVT::f64, ValueToStore);
  }
  SDValue Store =
      DAG.getStore(Chain, dl, ValueToStore, StackSlot, MPI, Align(8));
  // For i64 source, we need to add the appropriate power of 2 if the input
  // was negative.  This is the same as the optimization in
  // DAGTypeLegalizer::ExpandIntOp_UNIT_TO_FP, and for it to be safe here,
  // we must be careful to do the computation in x87 extended precision, not
  // in SSE. (The generic code can't know it's OK to do this, or how to.)
  SDVTList Tys = DAG.getVTList(MVT::f80, MVT::Other);
  SDValue Ops[] = { Store, StackSlot };
  SDValue Fild =
      DAG.getMemIntrinsicNode(X86ISD::FILD, dl, Tys, Ops, MVT::i64, MPI,
                              Align(8), MachineMemOperand::MOLoad);
  Chain = Fild.getValue(1);


  // Check whether the sign bit is set.
  SDValue SignSet = DAG.getSetCC(
      dl, getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), MVT::i64),
      Op.getOperand(OpNo), DAG.getConstant(0, dl, MVT::i64), ISD::SETLT);

  // Build a 64 bit pair (FF, 0) in the constant pool, with FF in the hi bits.
  APInt FF(64, 0x5F80000000000000ULL);
  SDValue FudgePtr = DAG.getConstantPool(
      ConstantInt::get(*DAG.getContext(), FF), PtrVT);
  unsigned CPAlignment = cast<ConstantPoolSDNode>(FudgePtr)->getAlignment();

  // Get a pointer to FF if the sign bit was set, or to 0 otherwise.
  SDValue Zero = DAG.getIntPtrConstant(0, dl);
  SDValue Four = DAG.getIntPtrConstant(4, dl);
  SDValue Offset = DAG.getSelect(dl, Zero.getValueType(), SignSet, Four, Zero);
  FudgePtr = DAG.getNode(ISD::ADD, dl, PtrVT, FudgePtr, Offset);

  // Load the value out, extending it from f32 to f80.
  SDValue Fudge = DAG.getExtLoad(
      ISD::EXTLOAD, dl, MVT::f80, Chain, FudgePtr,
      MachinePointerInfo::getConstantPool(DAG.getMachineFunction()), MVT::f32,
      CPAlignment);
  Chain = Fudge.getValue(1);
  // Extend everything to 80 bits to force it to be done on x87.
  // TODO: Are there any fast-math-flags to propagate here?
  if (IsStrict) {
    SDValue Add = DAG.getNode(ISD::STRICT_FADD, dl, {MVT::f80, MVT::Other},
                              {Chain, Fild, Fudge});
    // STRICT_FP_ROUND can't handle equal types.
    if (DstVT == MVT::f80)
      return Add;
    return DAG.getNode(ISD::STRICT_FP_ROUND, dl, {DstVT, MVT::Other},
                       {Add.getValue(1), Add, DAG.getIntPtrConstant(0, dl)});
  }
  SDValue Add = DAG.getNode(ISD::FADD, dl, MVT::f80, Fild, Fudge);
  return DAG.getNode(ISD::FP_ROUND, dl, DstVT, Add,
                     DAG.getIntPtrConstant(0, dl));
}

// If the given FP_TO_SINT (IsSigned) or FP_TO_UINT (!IsSigned) operation
// is legal, or has an fp128 or f16 source (which needs to be promoted to f32),
// just return an SDValue().
// Otherwise it is assumed to be a conversion from one of f32, f64 or f80
// to i16, i32 or i64, and we lower it to a legal sequence and return the
// result.
SDValue
X86TargetLowering::FP_TO_INTHelper(SDValue Op, SelectionDAG &DAG,
                                   bool IsSigned, SDValue &Chain) const {
  bool IsStrict = Op->isStrictFPOpcode();
  SDLoc DL(Op);

  EVT DstTy = Op.getValueType();
  SDValue Value = Op.getOperand(IsStrict ? 1 : 0);
  EVT TheVT = Value.getValueType();
  auto PtrVT = getPointerTy(DAG.getDataLayout());

  if (TheVT != MVT::f32 && TheVT != MVT::f64 && TheVT != MVT::f80) {
    // f16 must be promoted before using the lowering in this routine.
    // fp128 does not use this lowering.
    return SDValue();
  }

  // If using FIST to compute an unsigned i64, we'll need some fixup
  // to handle values above the maximum signed i64.  A FIST is always
  // used for the 32-bit subtarget, but also for f80 on a 64-bit target.
  bool UnsignedFixup = !IsSigned && DstTy == MVT::i64;

  // FIXME: This does not generate an invalid exception if the input does not
  // fit in i32. PR44019
  if (!IsSigned && DstTy != MVT::i64) {
    // Replace the fp-to-uint32 operation with an fp-to-sint64 FIST.
    // The low 32 bits of the fist result will have the correct uint32 result.
    assert(DstTy == MVT::i32 && "Unexpected FP_TO_UINT");
    DstTy = MVT::i64;
  }

  assert(DstTy.getSimpleVT() <= MVT::i64 &&
         DstTy.getSimpleVT() >= MVT::i16 &&
         "Unknown FP_TO_INT to lower!");

  // We lower FP->int64 into FISTP64 followed by a load from a temporary
  // stack slot.
  MachineFunction &MF = DAG.getMachineFunction();
  unsigned MemSize = DstTy.getStoreSize();
  int SSFI = MF.getFrameInfo().CreateStackObject(MemSize, MemSize, false);
  SDValue StackSlot = DAG.getFrameIndex(SSFI, PtrVT);

  Chain = IsStrict ? Op.getOperand(0) : DAG.getEntryNode();

  SDValue Adjust; // 0x0 or 0x80000000, for result sign bit adjustment.

  if (UnsignedFixup) {
    //
    // Conversion to unsigned i64 is implemented with a select,
    // depending on whether the source value fits in the range
    // of a signed i64.  Let Thresh be the FP equivalent of
    // 0x8000000000000000ULL.
    //
    //  Adjust = (Value < Thresh) ? 0 : 0x80000000;
    //  FltOfs = (Value < Thresh) ? 0 : 0x80000000;
    //  FistSrc = (Value - FltOfs);
    //  Fist-to-mem64 FistSrc
    //  Add 0 or 0x800...0ULL to the 64-bit result, which is equivalent
    //  to XOR'ing the high 32 bits with Adjust.
    //
    // Being a power of 2, Thresh is exactly representable in all FP formats.
    // For X87 we'd like to use the smallest FP type for this constant, but
    // for DAG type consistency we have to match the FP operand type.

    APFloat Thresh(APFloat::IEEEsingle(), APInt(32, 0x5f000000));
    LLVM_ATTRIBUTE_UNUSED APFloat::opStatus Status = APFloat::opOK;
    bool LosesInfo = false;
    if (TheVT == MVT::f64)
      // The rounding mode is irrelevant as the conversion should be exact.
      Status = Thresh.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
                              &LosesInfo);
    else if (TheVT == MVT::f80)
      Status = Thresh.convert(APFloat::x87DoubleExtended(),
                              APFloat::rmNearestTiesToEven, &LosesInfo);

    assert(Status == APFloat::opOK && !LosesInfo &&
           "FP conversion should have been exact");

    SDValue ThreshVal = DAG.getConstantFP(Thresh, DL, TheVT);

    EVT ResVT = getSetCCResultType(DAG.getDataLayout(),
                                   *DAG.getContext(), TheVT);
    SDValue Cmp;
    if (IsStrict) {
      Cmp = DAG.getSetCC(DL, ResVT, Value, ThreshVal, ISD::SETLT,
                         Chain, /*IsSignaling*/ true);
      Chain = Cmp.getValue(1);
    } else {
      Cmp = DAG.getSetCC(DL, ResVT, Value, ThreshVal, ISD::SETLT);
    }

    Adjust = DAG.getSelect(DL, MVT::i64, Cmp,
                           DAG.getConstant(0, DL, MVT::i64),
                           DAG.getConstant(APInt::getSignMask(64),
                                           DL, MVT::i64));
    SDValue FltOfs = DAG.getSelect(DL, TheVT, Cmp,
                                   DAG.getConstantFP(0.0, DL, TheVT),
                                   ThreshVal);

    if (IsStrict) {
      Value = DAG.getNode(ISD::STRICT_FSUB, DL, { TheVT, MVT::Other},
                          { Chain, Value, FltOfs });
      Chain = Value.getValue(1);
    } else
      Value = DAG.getNode(ISD::FSUB, DL, TheVT, Value, FltOfs);
  }

  MachinePointerInfo MPI = MachinePointerInfo::getFixedStack(MF, SSFI);

  // FIXME This causes a redundant load/store if the SSE-class value is already
  // in memory, such as if it is on the callstack.
  if (isScalarFPTypeInSSEReg(TheVT)) {
    assert(DstTy == MVT::i64 && "Invalid FP_TO_SINT to lower!");
    Chain = DAG.getStore(Chain, DL, Value, StackSlot, MPI);
    SDVTList Tys = DAG.getVTList(MVT::f80, MVT::Other);
    SDValue Ops[] = { Chain, StackSlot };

    unsigned FLDSize = TheVT.getStoreSize();
    assert(FLDSize <= MemSize && "Stack slot not big enough");
    MachineMemOperand *MMO = MF.getMachineMemOperand(
        MPI, MachineMemOperand::MOLoad, FLDSize, Align(FLDSize));
    Value = DAG.getMemIntrinsicNode(X86ISD::FLD, DL, Tys, Ops, TheVT, MMO);
    Chain = Value.getValue(1);
  }

  // Build the FP_TO_INT*_IN_MEM
  MachineMemOperand *MMO = MF.getMachineMemOperand(
      MPI, MachineMemOperand::MOStore, MemSize, Align(MemSize));
  SDValue Ops[] = { Chain, Value, StackSlot };
  SDValue FIST = DAG.getMemIntrinsicNode(X86ISD::FP_TO_INT_IN_MEM, DL,
                                         DAG.getVTList(MVT::Other),
                                         Ops, DstTy, MMO);

  SDValue Res = DAG.getLoad(Op.getValueType(), SDLoc(Op), FIST, StackSlot, MPI);
  Chain = Res.getValue(1);

  // If we need an unsigned fixup, XOR the result with adjust.
  if (UnsignedFixup)
    Res = DAG.getNode(ISD::XOR, DL, MVT::i64, Res, Adjust);

  return Res;
}

static SDValue LowerAVXExtend(SDValue Op, SelectionDAG &DAG,
                              const X86Subtarget &Subtarget) {
  MVT VT = Op.getSimpleValueType();
  SDValue In = Op.getOperand(0);
  MVT InVT = In.getSimpleValueType();
  SDLoc dl(Op);
  unsigned Opc = Op.getOpcode();

  assert(VT.isVector() && InVT.isVector() && "Expected vector type");
  assert((Opc == ISD::ANY_EXTEND || Opc == ISD::ZERO_EXTEND) &&
         "Unexpected extension opcode");
  assert(VT.getVectorNumElements() == InVT.getVectorNumElements() &&
         "Expected same number of elements");
  assert((VT.getVectorElementType() == MVT::i16 ||
          VT.getVectorElementType() == MVT::i32 ||
          VT.getVectorElementType() == MVT::i64) &&
         "Unexpected element type");
  assert((InVT.getVectorElementType() == MVT::i8 ||
          InVT.getVectorElementType() == MVT::i16 ||
          InVT.getVectorElementType() == MVT::i32) &&
         "Unexpected element type");

  unsigned ExtendInVecOpc = getOpcode_EXTEND_VECTOR_INREG(Opc);

  // Custom legalize v8i8->v8i64 on CPUs without avx512bw.
  if (InVT == MVT::v8i8) {
    if (VT != MVT::v8i64)
      return SDValue();

    In = DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(Op),
                     MVT::v16i8, In, DAG.getUNDEF(MVT::v8i8));
    return DAG.getNode(ExtendInVecOpc, dl, VT, In);
  }

  if (Subtarget.hasInt256())
    return Op;

  // Optimize vectors in AVX mode:
  //
  //   v8i16 -> v8i32
  //   Use vpmovzwd for 4 lower elements  v8i16 -> v4i32.
  //   Use vpunpckhwd for 4 upper elements  v8i16 -> v4i32.
  //   Concat upper and lower parts.
  //
  //   v4i32 -> v4i64
  //   Use vpmovzdq for 4 lower elements  v4i32 -> v2i64.
  //   Use vpunpckhdq for 4 upper elements  v4i32 -> v2i64.
  //   Concat upper and lower parts.
  //
  MVT HalfVT = VT.getHalfNumVectorElementsVT();
  SDValue OpLo = DAG.getNode(ExtendInVecOpc, dl, HalfVT, In);

  // Short-circuit if we can determine that each 128-bit half is the same value.
  // Otherwise, this is difficult to match and optimize.
  if (auto *Shuf = dyn_cast<ShuffleVectorSDNode>(In))
    if (hasIdenticalHalvesShuffleMask(Shuf->getMask()))
      return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, OpLo, OpLo);

  SDValue ZeroVec = DAG.getConstant(0, dl, InVT);
  SDValue Undef = DAG.getUNDEF(InVT);
  bool NeedZero = Opc == ISD::ZERO_EXTEND;
  SDValue OpHi = getUnpackh(DAG, dl, InVT, In, NeedZero ? ZeroVec : Undef);
  OpHi = DAG.getBitcast(HalfVT, OpHi);

  return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, OpLo, OpHi);
}

// Helper to split and extend a v16i1 mask to v16i8 or v16i16.
static SDValue SplitAndExtendv16i1(unsigned ExtOpc, MVT VT, SDValue In,
                                   const SDLoc &dl, SelectionDAG &DAG) {
  assert((VT == MVT::v16i8 || VT == MVT::v16i16) && "Unexpected VT.");
  SDValue Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v8i1, In,
                           DAG.getIntPtrConstant(0, dl));
  SDValue Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v8i1, In,
                           DAG.getIntPtrConstant(8, dl));
  Lo = DAG.getNode(ExtOpc, dl, MVT::v8i16, Lo);
  Hi = DAG.getNode(ExtOpc, dl, MVT::v8i16, Hi);
  SDValue Res = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v16i16, Lo, Hi);
  return DAG.getNode(ISD::TRUNCATE, dl, VT, Res);
}

static  SDValue LowerZERO_EXTEND_Mask(SDValue Op,
                                      const X86Subtarget &Subtarget,
                                      SelectionDAG &DAG) {
  MVT VT = Op->getSimpleValueType(0);
  SDValue In = Op->getOperand(0);
  MVT InVT = In.getSimpleValueType();
  assert(InVT.getVectorElementType() == MVT::i1 && "Unexpected input type!");
  SDLoc DL(Op);
  unsigned NumElts = VT.getVectorNumElements();

  // For all vectors, but vXi8 we can just emit a sign_extend and a shift. This
  // avoids a constant pool load.
  if (VT.getVectorElementType() != MVT::i8) {
    SDValue Extend = DAG.getNode(ISD::SIGN_EXTEND, DL, VT, In);
    return DAG.getNode(ISD::SRL, DL, VT, Extend,
                       DAG.getConstant(VT.getScalarSizeInBits() - 1, DL, VT));
  }

  // Extend VT if BWI is not supported.
  MVT ExtVT = VT;
  if (!Subtarget.hasBWI()) {
    // If v16i32 is to be avoided, we'll need to split and concatenate.
    if (NumElts == 16 && !Subtarget.canExtendTo512DQ())
      return SplitAndExtendv16i1(ISD::ZERO_EXTEND, VT, In, DL, DAG);

    ExtVT = MVT::getVectorVT(MVT::i32, NumElts);
  }

  // Widen to 512-bits if VLX is not supported.
  MVT WideVT = ExtVT;
  if (!ExtVT.is512BitVector() && !Subtarget.hasVLX()) {
    NumElts *= 512 / ExtVT.getSizeInBits();
    InVT = MVT::getVectorVT(MVT::i1, NumElts);
    In = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, InVT, DAG.getUNDEF(InVT),
                     In, DAG.getIntPtrConstant(0, DL));
    WideVT = MVT::getVectorVT(ExtVT.getVectorElementType(),
                              NumElts);
  }

  SDValue One = DAG.getConstant(1, DL, WideVT);
  SDValue Zero = DAG.getConstant(0, DL, WideVT);

  SDValue SelectedVal = DAG.getSelect(DL, WideVT, In, One, Zero);

  // Truncate if we had to extend above.
  if (VT != ExtVT) {
    WideVT = MVT::getVectorVT(MVT::i8, NumElts);
    SelectedVal = DAG.getNode(ISD::TRUNCATE, DL, WideVT, SelectedVal);
  }

  // Extract back to 128/256-bit if we widened.
  if (WideVT != VT)
    SelectedVal = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, VT, SelectedVal,
                              DAG.getIntPtrConstant(0, DL));

  return SelectedVal;
}

static SDValue LowerZERO_EXTEND(SDValue Op, const X86Subtarget &Subtarget,
                                SelectionDAG &DAG) {
  SDValue In = Op.getOperand(0);
  MVT SVT = In.getSimpleValueType();

  if (SVT.getVectorElementType() == MVT::i1)
    return LowerZERO_EXTEND_Mask(Op, Subtarget, DAG);

  assert(Subtarget.hasAVX() && "Expected AVX support");
  return LowerAVXExtend(Op, DAG, Subtarget);
}

/// Helper to recursively truncate vector elements in half with PACKSS/PACKUS.
/// It makes use of the fact that vectors with enough leading sign/zero bits
/// prevent the PACKSS/PACKUS from saturating the results.
/// AVX2 (Int256) sub-targets require extra shuffling as the PACK*S operates
/// within each 128-bit lane.
static SDValue truncateVectorWithPACK(unsigned Opcode, EVT DstVT, SDValue In,
                                      const SDLoc &DL, SelectionDAG &DAG,
                                      const X86Subtarget &Subtarget) {
  assert((Opcode == X86ISD::PACKSS || Opcode == X86ISD::PACKUS) &&
         "Unexpected PACK opcode");
  assert(DstVT.isVector() && "VT not a vector?");

  // Requires SSE2 but AVX512 has fast vector truncate.
  if (!Subtarget.hasSSE2())
    return SDValue();

  EVT SrcVT = In.getValueType();

  // No truncation required, we might get here due to recursive calls.
  if (SrcVT == DstVT)
    return In;

  // We only support vector truncation to 64bits or greater from a
  // 128bits or greater source.
  unsigned DstSizeInBits = DstVT.getSizeInBits();
  unsigned SrcSizeInBits = SrcVT.getSizeInBits();
  if ((DstSizeInBits % 64) != 0 || (SrcSizeInBits % 128) != 0)
    return SDValue();

  unsigned NumElems = SrcVT.getVectorNumElements();
  if (!isPowerOf2_32(NumElems))
    return SDValue();

  LLVMContext &Ctx = *DAG.getContext();
  assert(DstVT.getVectorNumElements() == NumElems && "Illegal truncation");
  assert(SrcSizeInBits > DstSizeInBits && "Illegal truncation");

  EVT PackedSVT = EVT::getIntegerVT(Ctx, SrcVT.getScalarSizeInBits() / 2);

  // Pack to the largest type possible:
  // vXi64/vXi32 -> PACK*SDW and vXi16 -> PACK*SWB.
  EVT InVT = MVT::i16, OutVT = MVT::i8;
  if (SrcVT.getScalarSizeInBits() > 16 &&
      (Opcode == X86ISD::PACKSS || Subtarget.hasSSE41())) {
    InVT = MVT::i32;
    OutVT = MVT::i16;
  }

  // 128bit -> 64bit truncate - PACK 128-bit src in the lower subvector.
  if (SrcVT.is128BitVector()) {
    InVT = EVT::getVectorVT(Ctx, InVT, 128 / InVT.getSizeInBits());
    OutVT = EVT::getVectorVT(Ctx, OutVT, 128 / OutVT.getSizeInBits());
    In = DAG.getBitcast(InVT, In);
    SDValue Res = DAG.getNode(Opcode, DL, OutVT, In, In);
    Res = extractSubVector(Res, 0, DAG, DL, 64);
    return DAG.getBitcast(DstVT, Res);
  }

  // Extract lower/upper subvectors.
  unsigned NumSubElts = NumElems / 2;
  SDValue Lo = extractSubVector(In, 0 * NumSubElts, DAG, DL, SrcSizeInBits / 2);
  SDValue Hi = extractSubVector(In, 1 * NumSubElts, DAG, DL, SrcSizeInBits / 2);

  unsigned SubSizeInBits = SrcSizeInBits / 2;
  InVT = EVT::getVectorVT(Ctx, InVT, SubSizeInBits / InVT.getSizeInBits());
  OutVT = EVT::getVectorVT(Ctx, OutVT, SubSizeInBits / OutVT.getSizeInBits());

  // 256bit -> 128bit truncate - PACK lower/upper 128-bit subvectors.
  if (SrcVT.is256BitVector() && DstVT.is128BitVector()) {
    Lo = DAG.getBitcast(InVT, Lo);
    Hi = DAG.getBitcast(InVT, Hi);
    SDValue Res = DAG.getNode(Opcode, DL, OutVT, Lo, Hi);
    return DAG.getBitcast(DstVT, Res);
  }

  // AVX2: 512bit -> 256bit truncate - PACK lower/upper 256-bit subvectors.
  // AVX2: 512bit -> 128bit truncate - PACK(PACK, PACK).
  if (SrcVT.is512BitVector() && Subtarget.hasInt256()) {
    Lo = DAG.getBitcast(InVT, Lo);
    Hi = DAG.getBitcast(InVT, Hi);
    SDValue Res = DAG.getNode(Opcode, DL, OutVT, Lo, Hi);

    // 256-bit PACK(ARG0, ARG1) leaves us with ((LO0,LO1),(HI0,HI1)),
    // so we need to shuffle to get ((LO0,HI0),(LO1,HI1)).
    // Scale shuffle mask to avoid bitcasts and help ComputeNumSignBits.
    SmallVector<int, 64> Mask;
    int Scale = 64 / OutVT.getScalarSizeInBits();
    scaleShuffleMask(Scale, { 0, 2, 1, 3 }, Mask);
    Res = DAG.getVectorShuffle(OutVT, DL, Res, Res, Mask);

    if (DstVT.is256BitVector())
      return DAG.getBitcast(DstVT, Res);

    // If 512bit -> 128bit truncate another stage.
    EVT PackedVT = EVT::getVectorVT(Ctx, PackedSVT, NumElems);
    Res = DAG.getBitcast(PackedVT, Res);
    return truncateVectorWithPACK(Opcode, DstVT, Res, DL, DAG, Subtarget);
  }

  // Recursively pack lower/upper subvectors, concat result and pack again.
  assert(SrcSizeInBits >= 256 && "Expected 256-bit vector or greater");
  EVT PackedVT = EVT::getVectorVT(Ctx, PackedSVT, NumSubElts);
  Lo = truncateVectorWithPACK(Opcode, PackedVT, Lo, DL, DAG, Subtarget);
  Hi = truncateVectorWithPACK(Opcode, PackedVT, Hi, DL, DAG, Subtarget);

  PackedVT = EVT::getVectorVT(Ctx, PackedSVT, NumElems);
  SDValue Res = DAG.getNode(ISD::CONCAT_VECTORS, DL, PackedVT, Lo, Hi);
  return truncateVectorWithPACK(Opcode, DstVT, Res, DL, DAG, Subtarget);
}

static SDValue LowerTruncateVecI1(SDValue Op, SelectionDAG &DAG,
                                  const X86Subtarget &Subtarget) {

  SDLoc DL(Op);
  MVT VT = Op.getSimpleValueType();
  SDValue In = Op.getOperand(0);
  MVT InVT = In.getSimpleValueType();

  assert(VT.getVectorElementType() == MVT::i1 && "Unexpected vector type.");

  // Shift LSB to MSB and use VPMOVB/W2M or TESTD/Q.
  unsigned ShiftInx = InVT.getScalarSizeInBits() - 1;
  if (InVT.getScalarSizeInBits() <= 16) {
    if (Subtarget.hasBWI()) {
      // legal, will go to VPMOVB2M, VPMOVW2M
      if (DAG.ComputeNumSignBits(In) < InVT.getScalarSizeInBits()) {
        // We need to shift to get the lsb into sign position.
        // Shift packed bytes not supported natively, bitcast to word
        MVT ExtVT = MVT::getVectorVT(MVT::i16, InVT.getSizeInBits()/16);
        In = DAG.getNode(ISD::SHL, DL, ExtVT,
                         DAG.getBitcast(ExtVT, In),
                         DAG.getConstant(ShiftInx, DL, ExtVT));
        In = DAG.getBitcast(InVT, In);
      }
      return DAG.getSetCC(DL, VT, DAG.getConstant(0, DL, InVT),
                          In, ISD::SETGT);
    }
    // Use TESTD/Q, extended vector to packed dword/qword.
    assert((InVT.is256BitVector() || InVT.is128BitVector()) &&
           "Unexpected vector type.");
    unsigned NumElts = InVT.getVectorNumElements();
    assert((NumElts == 8 || NumElts == 16) && "Unexpected number of elements");
    // We need to change to a wider element type that we have support for.
    // For 8 element vectors this is easy, we either extend to v8i32 or v8i64.
    // For 16 element vectors we extend to v16i32 unless we are explicitly
    // trying to avoid 512-bit vectors. If we are avoiding 512-bit vectors
    // we need to split into two 8 element vectors which we can extend to v8i32,
    // truncate and concat the results. There's an additional complication if
    // the original type is v16i8. In that case we can't split the v16i8 so
    // first we pre-extend it to v16i16 which we can split to v8i16, then extend
    // to v8i32, truncate that to v8i1 and concat the two halves.
    if (NumElts == 16 && !Subtarget.canExtendTo512DQ()) {
      if (InVT == MVT::v16i8) {
        // First we need to sign extend up to 256-bits so we can split that.
        InVT = MVT::v16i16;
        In = DAG.getNode(ISD::SIGN_EXTEND, DL, InVT, In);
      }
      SDValue Lo = extract128BitVector(In, 0, DAG, DL);
      SDValue Hi = extract128BitVector(In, 8, DAG, DL);
      // We're split now, just emit two truncates and a concat. The two
      // truncates will trigger legalization to come back to this function.
      Lo = DAG.getNode(ISD::TRUNCATE, DL, MVT::v8i1, Lo);
      Hi = DAG.getNode(ISD::TRUNCATE, DL, MVT::v8i1, Hi);
      return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Lo, Hi);
    }
    // We either have 8 elements or we're allowed to use 512-bit vectors.
    // If we have VLX, we want to use the narrowest vector that can get the
    // job done so we use vXi32.
    MVT EltVT = Subtarget.hasVLX() ? MVT::i32 : MVT::getIntegerVT(512/NumElts);
    MVT ExtVT = MVT::getVectorVT(EltVT, NumElts);
    In = DAG.getNode(ISD::SIGN_EXTEND, DL, ExtVT, In);
    InVT = ExtVT;
    ShiftInx = InVT.getScalarSizeInBits() - 1;
  }

  if (DAG.ComputeNumSignBits(In) < InVT.getScalarSizeInBits()) {
    // We need to shift to get the lsb into sign position.
    In = DAG.getNode(ISD::SHL, DL, InVT, In,
                     DAG.getConstant(ShiftInx, DL, InVT));
  }
  // If we have DQI, emit a pattern that will be iseled as vpmovq2m/vpmovd2m.
  if (Subtarget.hasDQI())
    return DAG.getSetCC(DL, VT, DAG.getConstant(0, DL, InVT), In, ISD::SETGT);
  return DAG.getSetCC(DL, VT, In, DAG.getConstant(0, DL, InVT), ISD::SETNE);
}

SDValue X86TargetLowering::LowerTRUNCATE(SDValue Op, SelectionDAG &DAG) const {
  SDLoc DL(Op);
  MVT VT = Op.getSimpleValueType();
  SDValue In = Op.getOperand(0);
  MVT InVT = In.getSimpleValueType();
  unsigned InNumEltBits = InVT.getScalarSizeInBits();

  assert(VT.getVectorNumElements() == InVT.getVectorNumElements() &&
         "Invalid TRUNCATE operation");

  // If we're called by the type legalizer, handle a few cases.
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  if (!TLI.isTypeLegal(InVT)) {
    if ((InVT == MVT::v8i64 || InVT == MVT::v16i32 || InVT == MVT::v16i64) &&
        VT.is128BitVector()) {
      assert(Subtarget.hasVLX() && "Unexpected subtarget!");
      // The default behavior is to truncate one step, concatenate, and then
      // truncate the remainder. We'd rather produce two 64-bit results and
      // concatenate those.
      SDValue Lo, Hi;
      std::tie(Lo, Hi) = DAG.SplitVector(In, DL);

      EVT LoVT, HiVT;
      std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);

      Lo = DAG.getNode(ISD::TRUNCATE, DL, LoVT, Lo);
      Hi = DAG.getNode(ISD::TRUNCATE, DL, HiVT, Hi);
      return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Lo, Hi);
    }

    // Otherwise let default legalization handle it.
    return SDValue();
  }

  if (VT.getVectorElementType() == MVT::i1)
    return LowerTruncateVecI1(Op, DAG, Subtarget);

  // vpmovqb/w/d, vpmovdb/w, vpmovwb
  if (Subtarget.hasAVX512()) {
    // word to byte only under BWI. Otherwise we have to promoted to v16i32
    // and then truncate that. But we should only do that if we haven't been
    // asked to avoid 512-bit vectors. The actual promotion to v16i32 will be
    // handled by isel patterns.
    if (InVT != MVT::v16i16 || Subtarget.hasBWI() ||
        Subtarget.canExtendTo512DQ())
      return Op;
  }

  unsigned NumPackedSignBits = std::min<unsigned>(VT.getScalarSizeInBits(), 16);
  unsigned NumPackedZeroBits = Subtarget.hasSSE41() ? NumPackedSignBits : 8;

  // Truncate with PACKUS if we are truncating a vector with leading zero bits
  // that extend all the way to the packed/truncated value.
  // Pre-SSE41 we can only use PACKUSWB.
  KnownBits Known = DAG.computeKnownBits(In);
  if ((InNumEltBits - NumPackedZeroBits) <= Known.countMinLeadingZeros())
    if (SDValue V =
            truncateVectorWithPACK(X86ISD::PACKUS, VT, In, DL, DAG, Subtarget))
      return V;

  // Truncate with PACKSS if we are truncating a vector with sign-bits that
  // extend all the way to the packed/truncated value.
  if ((InNumEltBits - NumPackedSignBits) < DAG.ComputeNumSignBits(In))
    if (SDValue V =
            truncateVectorWithPACK(X86ISD::PACKSS, VT, In, DL, DAG, Subtarget))
      return V;

  // Handle truncation of V256 to V128 using shuffles.
  assert(VT.is128BitVector() && InVT.is256BitVector() && "Unexpected types!");

  if ((VT == MVT::v4i32) && (InVT == MVT::v4i64)) {
    // On AVX2, v4i64 -> v4i32 becomes VPERMD.
    if (Subtarget.hasInt256()) {
      static const int ShufMask[] = {0, 2, 4, 6, -1, -1, -1, -1};
      In = DAG.getBitcast(MVT::v8i32, In);
      In = DAG.getVectorShuffle(MVT::v8i32, DL, In, In, ShufMask);
      return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, VT, In,
                         DAG.getIntPtrConstant(0, DL));
    }

    SDValue OpLo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::v2i64, In,
                               DAG.getIntPtrConstant(0, DL));
    SDValue OpHi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::v2i64, In,
                               DAG.getIntPtrConstant(2, DL));
    OpLo = DAG.getBitcast(MVT::v4i32, OpLo);
    OpHi = DAG.getBitcast(MVT::v4i32, OpHi);
    static const int ShufMask[] = {0, 2, 4, 6};
    return DAG.getVectorShuffle(VT, DL, OpLo, OpHi, ShufMask);
  }

  if ((VT == MVT::v8i16) && (InVT == MVT::v8i32)) {
    // On AVX2, v8i32 -> v8i16 becomes PSHUFB.
    if (Subtarget.hasInt256()) {
      In = DAG.getBitcast(MVT::v32i8, In);

      // The PSHUFB mask:
      static const int ShufMask1[] = { 0,  1,  4,  5,  8,  9, 12, 13,
                                      -1, -1, -1, -1, -1, -1, -1, -1,
                                      16, 17, 20, 21, 24, 25, 28, 29,
                                      -1, -1, -1, -1, -1, -1, -1, -1 };
      In = DAG.getVectorShuffle(MVT::v32i8, DL, In, In, ShufMask1);
      In = DAG.getBitcast(MVT::v4i64, In);

      static const int ShufMask2[] = {0,  2,  -1,  -1};
      In = DAG.getVectorShuffle(MVT::v4i64, DL,  In, In, ShufMask2);
      In = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::v2i64, In,
                       DAG.getIntPtrConstant(0, DL));
      return DAG.getBitcast(VT, In);
    }

    SDValue OpLo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::v4i32, In,
                               DAG.getIntPtrConstant(0, DL));

    SDValue OpHi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::v4i32, In,
                               DAG.getIntPtrConstant(4, DL));

    OpLo = DAG.getBitcast(MVT::v16i8, OpLo);
    OpHi = DAG.getBitcast(MVT::v16i8, OpHi);

    // The PSHUFB mask:
    static const int ShufMask1[] = {0,  1,  4,  5,  8,  9, 12, 13,
                                   -1, -1, -1, -1, -1, -1, -1, -1};

    OpLo = DAG.getVectorShuffle(MVT::v16i8, DL, OpLo, OpLo, ShufMask1);
    OpHi = DAG.getVectorShuffle(MVT::v16i8, DL, OpHi, OpHi, ShufMask1);

    OpLo = DAG.getBitcast(MVT::v4i32, OpLo);
    OpHi = DAG.getBitcast(MVT::v4i32, OpHi);

    // The MOVLHPS Mask:
    static const int ShufMask2[] = {0, 1, 4, 5};
    SDValue res = DAG.getVectorShuffle(MVT::v4i32, DL, OpLo, OpHi, ShufMask2);
    return DAG.getBitcast(MVT::v8i16, res);
  }

  if (VT == MVT::v16i8 && InVT == MVT::v16i16) {
    // Use an AND to zero uppper bits for PACKUS.
    In = DAG.getNode(ISD::AND, DL, InVT, In, DAG.getConstant(255, DL, InVT));

    SDValue InLo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::v8i16, In,
                               DAG.getIntPtrConstant(0, DL));
    SDValue InHi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::v8i16, In,
                               DAG.getIntPtrConstant(8, DL));
    return DAG.getNode(X86ISD::PACKUS, DL, VT, InLo, InHi);
  }

  llvm_unreachable("All 256->128 cases should have been handled above!");
}

SDValue X86TargetLowering::LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const {
  bool IsStrict = Op->isStrictFPOpcode();
  bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT ||
                  Op.getOpcode() == ISD::STRICT_FP_TO_SINT;
  MVT VT = Op->getSimpleValueType(0);
  SDValue Src = Op.getOperand(IsStrict ? 1 : 0);
  MVT SrcVT = Src.getSimpleValueType();
  SDLoc dl(Op);

  if (VT.isVector()) {
    if (VT == MVT::v2i1 && SrcVT == MVT::v2f64) {
      MVT ResVT = MVT::v4i32;
      MVT TruncVT = MVT::v4i1;
      unsigned Opc;
      if (IsStrict)
        Opc = IsSigned ? X86ISD::STRICT_CVTTP2SI : X86ISD::STRICT_CVTTP2UI;
      else
        Opc = IsSigned ? X86ISD::CVTTP2SI : X86ISD::CVTTP2UI;

      if (!IsSigned && !Subtarget.hasVLX()) {
        assert(Subtarget.useAVX512Regs() && "Unexpected features!");
        // Widen to 512-bits.
        ResVT = MVT::v8i32;
        TruncVT = MVT::v8i1;
        Opc = Op.getOpcode();
        // Need to concat with zero vector for strict fp to avoid spurious
        // exceptions.
        // TODO: Should we just do this for non-strict as well?
        SDValue Tmp = IsStrict ? DAG.getConstantFP(0.0, dl, MVT::v8f64)
                               : DAG.getUNDEF(MVT::v8f64);
        Src = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, MVT::v8f64, Tmp, Src,
                          DAG.getIntPtrConstant(0, dl));
      }
      SDValue Res, Chain;
      if (IsStrict) {
        Res =
            DAG.getNode(Opc, dl, {ResVT, MVT::Other}, {Op->getOperand(0), Src});
        Chain = Res.getValue(1);
      } else {
        Res = DAG.getNode(Opc, dl, ResVT, Src);
      }

      Res = DAG.getNode(ISD::TRUNCATE, dl, TruncVT, Res);
      Res = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v2i1, Res,
                        DAG.getIntPtrConstant(0, dl));
      if (IsStrict)
        return DAG.getMergeValues({Res, Chain}, dl);
      return Res;
    }

    // v8f64->v8i32 is legal, but we need v8i32 to be custom for v8f32.
    if (VT == MVT::v8i32 && SrcVT == MVT::v8f64) {
      assert(!IsSigned && "Expected unsigned conversion!");
      assert(Subtarget.useAVX512Regs() && "Requires avx512f");
      return Op;
    }

    // Widen vXi32 fp_to_uint with avx512f to 512-bit source.
    if ((VT == MVT::v4i32 || VT == MVT::v8i32) &&
        (SrcVT == MVT::v4f64 || SrcVT == MVT::v4f32 || SrcVT == MVT::v8f32)) {
      assert(!IsSigned && "Expected unsigned conversion!");
      assert(Subtarget.useAVX512Regs() && !Subtarget.hasVLX() &&
             "Unexpected features!");
      MVT WideVT = SrcVT == MVT::v4f64 ? MVT::v8f64 : MVT::v16f32;
      MVT ResVT = SrcVT == MVT::v4f64 ? MVT::v8i32 : MVT::v16i32;
      // Need to concat with zero vector for strict fp to avoid spurious
      // exceptions.
      // TODO: Should we just do this for non-strict as well?
      SDValue Tmp =
          IsStrict ? DAG.getConstantFP(0.0, dl, WideVT) : DAG.getUNDEF(WideVT);
      Src = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, WideVT, Tmp, Src,
                        DAG.getIntPtrConstant(0, dl));

      SDValue Res, Chain;
      if (IsStrict) {
        Res = DAG.getNode(ISD::STRICT_FP_TO_UINT, dl, {ResVT, MVT::Other},
                          {Op->getOperand(0), Src});
        Chain = Res.getValue(1);
      } else {
        Res = DAG.getNode(ISD::FP_TO_UINT, dl, ResVT, Src);
      }

      Res = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT, Res,
                        DAG.getIntPtrConstant(0, dl));

      if (IsStrict)
        return DAG.getMergeValues({Res, Chain}, dl);
      return Res;
    }

    // Widen vXi64 fp_to_uint/fp_to_sint with avx512dq to 512-bit source.
    if ((VT == MVT::v2i64 || VT == MVT::v4i64) &&
        (SrcVT == MVT::v2f64 || SrcVT == MVT::v4f64 || SrcVT == MVT::v4f32)) {
      assert(Subtarget.useAVX512Regs() && Subtarget.hasDQI() &&
             !Subtarget.hasVLX() && "Unexpected features!");
      MVT WideVT = SrcVT == MVT::v4f32 ? MVT::v8f32 : MVT::v8f64;
      // Need to concat with zero vector for strict fp to avoid spurious
      // exceptions.
      // TODO: Should we just do this for non-strict as well?
      SDValue Tmp =
          IsStrict ? DAG.getConstantFP(0.0, dl, WideVT) : DAG.getUNDEF(WideVT);
      Src = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, WideVT, Tmp, Src,
                        DAG.getIntPtrConstant(0, dl));

      SDValue Res, Chain;
      if (IsStrict) {
        Res = DAG.getNode(Op.getOpcode(), dl, {MVT::v8i64, MVT::Other},
                          {Op->getOperand(0), Src});
        Chain = Res.getValue(1);
      } else {
        Res = DAG.getNode(Op.getOpcode(), dl, MVT::v8i64, Src);
      }

      Res = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT, Res,
                        DAG.getIntPtrConstant(0, dl));

      if (IsStrict)
        return DAG.getMergeValues({Res, Chain}, dl);
      return Res;
    }

    if (VT == MVT::v2i64 && SrcVT  == MVT::v2f32) {
      assert(Subtarget.hasDQI() && Subtarget.hasVLX() && "Requires AVX512DQVL");
      SDValue Tmp = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v4f32, Src,
                                DAG.getUNDEF(MVT::v2f32));
      if (IsStrict) {
        unsigned Opc = IsSigned ? X86ISD::STRICT_CVTTP2SI
                                : X86ISD::STRICT_CVTTP2UI;
        return DAG.getNode(Opc, dl, {VT, MVT::Other}, {Op->getOperand(0), Tmp});
      }
      unsigned Opc = IsSigned ? X86ISD::CVTTP2SI : X86ISD::CVTTP2UI;
      return DAG.getNode(Opc, dl, VT, Tmp);
    }

    return SDValue();
  }

  assert(!VT.isVector());

  bool UseSSEReg = isScalarFPTypeInSSEReg(SrcVT);

  if (!IsSigned && UseSSEReg) {
    // Conversions from f32/f64 with AVX512 should be legal.
    if (Subtarget.hasAVX512())
      return Op;

    // Use default expansion for i64.
    if (VT == MVT::i64)
      return SDValue();

    assert(VT == MVT::i32 && "Unexpected VT!");

    // Promote i32 to i64 and use a signed operation on 64-bit targets.
    // FIXME: This does not generate an invalid exception if the input does not
    // fit in i32. PR44019
    if (Subtarget.is64Bit()) {
      SDValue Res, Chain;
      if (IsStrict) {
        Res = DAG.getNode(ISD::STRICT_FP_TO_SINT, dl, { MVT::i64, MVT::Other},
                          { Op.getOperand(0), Src });
        Chain = Res.getValue(1);
      } else
        Res = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i64, Src);

      Res = DAG.getNode(ISD::TRUNCATE, dl, VT, Res);
      if (IsStrict)
        return DAG.getMergeValues({ Res, Chain }, dl);
      return Res;
    }

    // Use default expansion for SSE1/2 targets without SSE3. With SSE3 we can
    // use fisttp which will be handled later.
    if (!Subtarget.hasSSE3())
      return SDValue();
  }

  // Promote i16 to i32 if we can use a SSE operation or the type is f128.
  // FIXME: This does not generate an invalid exception if the input does not
  // fit in i16. PR44019
  if (VT == MVT::i16 && (UseSSEReg || SrcVT == MVT::f128)) {
    assert(IsSigned && "Expected i16 FP_TO_UINT to have been promoted!");
    SDValue Res, Chain;
    if (IsStrict) {
      Res = DAG.getNode(ISD::STRICT_FP_TO_SINT, dl, { MVT::i32, MVT::Other},
                        { Op.getOperand(0), Src });
      Chain = Res.getValue(1);
    } else
      Res = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Src);

    Res = DAG.getNode(ISD::TRUNCATE, dl, VT, Res);
    if (IsStrict)
      return DAG.getMergeValues({ Res, Chain }, dl);
    return Res;
  }

  // If this is a FP_TO_SINT using SSEReg we're done.
  if (UseSSEReg && IsSigned)
    return Op;

  // fp128 needs to use a libcall.
  if (SrcVT == MVT::f128) {
    RTLIB::Libcall LC;
    if (IsSigned)
      LC = RTLIB::getFPTOSINT(SrcVT, VT);
    else
      LC = RTLIB::getFPTOUINT(SrcVT, VT);

    SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
    MakeLibCallOptions CallOptions;
    std::pair<SDValue, SDValue> Tmp = makeLibCall(DAG, LC, VT, Src, CallOptions,
                                                  SDLoc(Op), Chain);

    if (IsStrict)
      return DAG.getMergeValues({ Tmp.first, Tmp.second }, dl);

    return Tmp.first;
  }

  // Fall back to X87.
  SDValue Chain;
  if (SDValue V = FP_TO_INTHelper(Op, DAG, IsSigned, Chain)) {
    if (IsStrict)
      return DAG.getMergeValues({V, Chain}, dl);
    return V;
  }

  llvm_unreachable("Expected FP_TO_INTHelper to handle all remaining cases.");
}

SDValue X86TargetLowering::LowerLRINT_LLRINT(SDValue Op,
                                             SelectionDAG &DAG) const {
  SDValue Src = Op.getOperand(0);
  MVT SrcVT = Src.getSimpleValueType();

  // If the source is in an SSE register, the node is Legal.
  if (isScalarFPTypeInSSEReg(SrcVT))
    return Op;

  return LRINT_LLRINTHelper(Op.getNode(), DAG);
}

SDValue X86TargetLowering::LRINT_LLRINTHelper(SDNode *N,
                                              SelectionDAG &DAG) const {
  EVT DstVT = N->getValueType(0);
  SDValue Src = N->getOperand(0);
  EVT SrcVT = Src.getValueType();

  if (SrcVT != MVT::f32 && SrcVT != MVT::f64 && SrcVT != MVT::f80) {
    // f16 must be promoted before using the lowering in this routine.
    // fp128 does not use this lowering.
    return SDValue();
  }

  SDLoc DL(N);
  SDValue Chain = DAG.getEntryNode();

  bool UseSSE = isScalarFPTypeInSSEReg(SrcVT);

  // If we're converting from SSE, the stack slot needs to hold both types.
  // Otherwise it only needs to hold the DstVT.
  EVT OtherVT = UseSSE ? SrcVT : DstVT;
  SDValue StackPtr = DAG.CreateStackTemporary(DstVT, OtherVT);
  int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
  MachinePointerInfo MPI =
      MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SPFI);

  if (UseSSE) {
    assert(DstVT == MVT::i64 && "Invalid LRINT/LLRINT to lower!");
    Chain = DAG.getStore(Chain, DL, Src, StackPtr, MPI);
    SDVTList Tys = DAG.getVTList(MVT::f80, MVT::Other);
    SDValue Ops[] = { Chain, StackPtr };

    Src = DAG.getMemIntrinsicNode(X86ISD::FLD, DL, Tys, Ops, SrcVT, MPI,
                                  /*Align*/ None, MachineMemOperand::MOLoad);
    Chain = Src.getValue(1);
  }

  SDValue StoreOps[] = { Chain, Src, StackPtr };
  Chain = DAG.getMemIntrinsicNode(X86ISD::FIST, DL, DAG.getVTList(MVT::Other),
                                  StoreOps, DstVT, MPI, /*Align*/ None,
                                  MachineMemOperand::MOStore);

  return DAG.getLoad(DstVT, DL, Chain, StackPtr, MPI);
}

SDValue X86TargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
  bool IsStrict = Op->isStrictFPOpcode();

  SDLoc DL(Op);
  MVT VT = Op.getSimpleValueType();
  SDValue In = Op.getOperand(IsStrict ? 1 : 0);
  MVT SVT = In.getSimpleValueType();

  if (VT == MVT::f128) {
    RTLIB::Libcall LC = RTLIB::getFPEXT(SVT, VT);
    return LowerF128Call(Op, DAG, LC);
  }

  assert(SVT == MVT::v2f32 && "Only customize MVT::v2f32 type legalization!");

  SDValue Res =
      DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v4f32, In, DAG.getUNDEF(SVT));
  if (IsStrict)
    return DAG.getNode(X86ISD::STRICT_VFPEXT, DL, {VT, MVT::Other},
                       {Op->getOperand(0), Res});
  return DAG.getNode(X86ISD::VFPEXT, DL, VT, Res);
}

SDValue X86TargetLowering::LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const {
  bool IsStrict = Op->isStrictFPOpcode();

  MVT VT = Op.getSimpleValueType();
  SDValue In = Op.getOperand(IsStrict ? 1 : 0);
  MVT SVT = In.getSimpleValueType();

  // It's legal except when f128 is involved
  if (SVT != MVT::f128)
    return Op;

  RTLIB::Libcall LC = RTLIB::getFPROUND(SVT, VT);

  // FP_ROUND node has a second operand indicating whether it is known to be
  // precise. That doesn't take part in the LibCall so we can't directly use
  // LowerF128Call.

  SDLoc dl(Op);
  SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
  MakeLibCallOptions CallOptions;
  std::pair<SDValue, SDValue> Tmp = makeLibCall(DAG, LC, VT, In, CallOptions,
                                                dl, Chain);

  if (IsStrict)
    return DAG.getMergeValues({ Tmp.first, Tmp.second }, dl);

  return Tmp.first;
}

static SDValue LowerFP16_TO_FP(SDValue Op, SelectionDAG &DAG) {
  bool IsStrict = Op->isStrictFPOpcode();
  SDValue Src = Op.getOperand(IsStrict ? 1 : 0);
  assert(Src.getValueType() == MVT::i16 && Op.getValueType() == MVT::f32 &&
         "Unexpected VT!");

  SDLoc dl(Op);
  SDValue Res = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v8i16,
                            DAG.getConstant(0, dl, MVT::v8i16), Src,
                            DAG.getIntPtrConstant(0, dl));

  SDValue Chain;
  if (IsStrict) {
    Res = DAG.getNode(X86ISD::STRICT_CVTPH2PS, dl, {MVT::v4f32, MVT::Other},
                      {Op.getOperand(0), Res});
    Chain = Res.getValue(1);
  } else {
    Res = DAG.getNode(X86ISD::CVTPH2PS, dl, MVT::v4f32, Res);
  }

  Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f32, Res,
                    DAG.getIntPtrConstant(0, dl));

  if (IsStrict)
    return DAG.getMergeValues({Res, Chain}, dl);

  return Res;
}

static SDValue LowerFP_TO_FP16(SDValue Op, SelectionDAG &DAG) {
  bool IsStrict = Op->isStrictFPOpcode();
  SDValue Src = Op.getOperand(IsStrict ? 1 : 0);
  assert(Src.getValueType() == MVT::f32 && Op.getValueType() == MVT::i16 &&
         "Unexpected VT!");

  SDLoc dl(Op);
  SDValue Res, Chain;
  if (IsStrict) {
    Res = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v4f32,
                      DAG.getConstantFP(0, dl, MVT::v4f32), Src,
                      DAG.getIntPtrConstant(0, dl));
    Res = DAG.getNode(
        X86ISD::STRICT_CVTPS2PH, dl, {MVT::v8i16, MVT::Other},
        {Op.getOperand(0), Res, DAG.getTargetConstant(4, dl, MVT::i32)});
    Chain = Res.getValue(1);
  } else {
    // FIXME: Should we use zeros for upper elements for non-strict?
    Res = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v4f32, Src);
    Res = DAG.getNode(X86ISD::CVTPS2PH, dl, MVT::v8i16, Res,
                      DAG.getTargetConstant(4, dl, MVT::i32));
  }

  Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i16, Res,
                    DAG.getIntPtrConstant(0, dl));

  if (IsStrict)
    return DAG.getMergeValues({Res, Chain}, dl);

  return Res;
}

/// Depending on uarch and/or optimizing for size, we might prefer to use a
/// vector operation in place of the typical scalar operation.
static SDValue lowerAddSubToHorizontalOp(SDValue Op, SelectionDAG &DAG,
                                         const X86Subtarget &Subtarget) {
  // If both operands have other uses, this is probably not profitable.
  SDValue LHS = Op.getOperand(0);
  SDValue RHS = Op.getOperand(1);
  if (!LHS.hasOneUse() && !RHS.hasOneUse())
    return Op;

  // FP horizontal add/sub were added with SSE3. Integer with SSSE3.
  bool IsFP = Op.getSimpleValueType().isFloatingPoint();
  if (IsFP && !Subtarget.hasSSE3())
    return Op;
  if (!IsFP && !Subtarget.hasSSSE3())
    return Op;

  // Extract from a common vector.
  if (LHS.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
      RHS.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
      LHS.getOperand(0) != RHS.getOperand(0) ||
      !isa<ConstantSDNode>(LHS.getOperand(1)) ||
      !isa<ConstantSDNode>(RHS.getOperand(1)) ||
      !shouldUseHorizontalOp(true, DAG, Subtarget))
    return Op;

  // Allow commuted 'hadd' ops.
  // TODO: Allow commuted (f)sub by negating the result of (F)HSUB?
  unsigned HOpcode;
  switch (Op.getOpcode()) {
    case ISD::ADD: HOpcode = X86ISD::HADD; break;
    case ISD::SUB: HOpcode = X86ISD::HSUB; break;
    case ISD::FADD: HOpcode = X86ISD::FHADD; break;
    case ISD::FSUB: HOpcode = X86ISD::FHSUB; break;
    default:
      llvm_unreachable("Trying to lower unsupported opcode to horizontal op");
  }
  unsigned LExtIndex = LHS.getConstantOperandVal(1);
  unsigned RExtIndex = RHS.getConstantOperandVal(1);
  if ((LExtIndex & 1) == 1 && (RExtIndex & 1) == 0 &&
      (HOpcode == X86ISD::HADD || HOpcode == X86ISD::FHADD))
    std::swap(LExtIndex, RExtIndex);

  if ((LExtIndex & 1) != 0 || RExtIndex != (LExtIndex + 1))
    return Op;

  SDValue X = LHS.getOperand(0);
  EVT VecVT = X.getValueType();
  unsigned BitWidth = VecVT.getSizeInBits();
  unsigned NumLanes = BitWidth / 128;
  unsigned NumEltsPerLane = VecVT.getVectorNumElements() / NumLanes;
  assert((BitWidth == 128 || BitWidth == 256 || BitWidth == 512) &&
         "Not expecting illegal vector widths here");

  // Creating a 256-bit horizontal op would be wasteful, and there is no 512-bit
  // equivalent, so extract the 256/512-bit source op to 128-bit if we can.
  SDLoc DL(Op);
  if (BitWidth == 256 || BitWidth == 512) {
    unsigned LaneIdx = LExtIndex / NumEltsPerLane;
    X = extract128BitVector(X, LaneIdx * NumEltsPerLane, DAG, DL);
    LExtIndex %= NumEltsPerLane;
  }

  // add (extractelt (X, 0), extractelt (X, 1)) --> extractelt (hadd X, X), 0
  // add (extractelt (X, 1), extractelt (X, 0)) --> extractelt (hadd X, X), 0
  // add (extractelt (X, 2), extractelt (X, 3)) --> extractelt (hadd X, X), 1
  // sub (extractelt (X, 0), extractelt (X, 1)) --> extractelt (hsub X, X), 0
  SDValue HOp = DAG.getNode(HOpcode, DL, X.getValueType(), X, X);
  return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, Op.getSimpleValueType(), HOp,
                     DAG.getIntPtrConstant(LExtIndex / 2, DL));
}

/// Depending on uarch and/or optimizing for size, we might prefer to use a
/// vector operation in place of the typical scalar operation.
SDValue X86TargetLowering::lowerFaddFsub(SDValue Op, SelectionDAG &DAG) const {
  assert((Op.getValueType() == MVT::f32 || Op.getValueType() == MVT::f64) &&
         "Only expecting float/double");
  return lowerAddSubToHorizontalOp(Op, DAG, Subtarget);
}

/// ISD::FROUND is defined to round to nearest with ties rounding away from 0.
/// This mode isn't supported in hardware on X86. But as long as we aren't
/// compiling with trapping math, we can emulate this with
/// floor(X + copysign(nextafter(0.5, 0.0), X)).
static SDValue LowerFROUND(SDValue Op, SelectionDAG &DAG) {
  SDValue N0 = Op.getOperand(0);
  SDLoc dl(Op);
  MVT VT = Op.getSimpleValueType();

  // N0 += copysign(nextafter(0.5, 0.0), N0)
  const fltSemantics &Sem = SelectionDAG::EVTToAPFloatSemantics(VT);
  bool Ignored;
  APFloat Point5Pred = APFloat(0.5f);
  Point5Pred.convert(Sem, APFloat::rmNearestTiesToEven, &Ignored);
  Point5Pred.next(/*nextDown*/true);

  SDValue Adder = DAG.getNode(ISD::FCOPYSIGN, dl, VT,
                              DAG.getConstantFP(Point5Pred, dl, VT), N0);
  N0 = DAG.getNode(ISD::FADD, dl, VT, N0, Adder);

  // Truncate the result to remove fraction.
  return DAG.getNode(ISD::FTRUNC, dl, VT, N0);
}

/// The only differences between FABS and FNEG are the mask and the logic op.
/// FNEG also has a folding opportunity for FNEG(FABS(x)).
static SDValue LowerFABSorFNEG(SDValue Op, SelectionDAG &DAG) {
  assert((Op.getOpcode() == ISD::FABS || Op.getOpcode() == ISD::FNEG) &&
         "Wrong opcode for lowering FABS or FNEG.");

  bool IsFABS = (Op.getOpcode() == ISD::FABS);

  // If this is a FABS and it has an FNEG user, bail out to fold the combination
  // into an FNABS. We'll lower the FABS after that if it is still in use.
  if (IsFABS)
    for (SDNode *User : Op->uses())
      if (User->getOpcode() == ISD::FNEG)
        return Op;

  SDLoc dl(Op);
  MVT VT = Op.getSimpleValueType();

  bool IsF128 = (VT == MVT::f128);
  assert((VT == MVT::f64 || VT == MVT::f32 || VT == MVT::f128 ||
          VT == MVT::v2f64 || VT == MVT::v4f64 || VT == MVT::v4f32 ||
          VT == MVT::v8f32 || VT == MVT::v8f64 || VT == MVT::v16f32) &&
         "Unexpected type in LowerFABSorFNEG");

  // FIXME: Use function attribute "OptimizeForSize" and/or CodeGenOpt::Level to
  // decide if we should generate a 16-byte constant mask when we only need 4 or
  // 8 bytes for the scalar case.

  // There are no scalar bitwise logical SSE/AVX instructions, so we
  // generate a 16-byte vector constant and logic op even for the scalar case.
  // Using a 16-byte mask allows folding the load of the mask with
  // the logic op, so it can save (~4 bytes) on code size.
  bool IsFakeVector = !VT.isVector() && !IsF128;
  MVT LogicVT = VT;
  if (IsFakeVector)
    LogicVT = (VT == MVT::f64) ? MVT::v2f64 : MVT::v4f32;

  unsigned EltBits = VT.getScalarSizeInBits();
  // For FABS, mask is 0x7f...; for FNEG, mask is 0x80...
  APInt MaskElt = IsFABS ? APInt::getSignedMaxValue(EltBits) :
                           APInt::getSignMask(EltBits);
  const fltSemantics &Sem = SelectionDAG::EVTToAPFloatSemantics(VT);
  SDValue Mask = DAG.getConstantFP(APFloat(Sem, MaskElt), dl, LogicVT);

  SDValue Op0 = Op.getOperand(0);
  bool IsFNABS = !IsFABS && (Op0.getOpcode() == ISD::FABS);
  unsigned LogicOp = IsFABS  ? X86ISD::FAND :
                     IsFNABS ? X86ISD::FOR  :
                               X86ISD::FXOR;
  SDValue Operand = IsFNABS ? Op0.getOperand(0) : Op0;

  if (VT.isVector() || IsF128)
    return DAG.getNode(LogicOp, dl, LogicVT, Operand, Mask);

  // For the scalar case extend to a 128-bit vector, perform the logic op,
  // and extract the scalar result back out.
  Operand = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, LogicVT, Operand);
  SDValue LogicNode = DAG.getNode(LogicOp, dl, LogicVT, Operand, Mask);
  return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT, LogicNode,
                     DAG.getIntPtrConstant(0, dl));
}

static SDValue LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) {
  SDValue Mag = Op.getOperand(0);
  SDValue Sign = Op.getOperand(1);
  SDLoc dl(Op);

  // If the sign operand is smaller, extend it first.
  MVT VT = Op.getSimpleValueType();
  if (Sign.getSimpleValueType().bitsLT(VT))
    Sign = DAG.getNode(ISD::FP_EXTEND, dl, VT, Sign);

  // And if it is bigger, shrink it first.
  if (Sign.getSimpleValueType().bitsGT(VT))
    Sign = DAG.getNode(ISD::FP_ROUND, dl, VT, Sign, DAG.getIntPtrConstant(1, dl));

  // At this point the operands and the result should have the same
  // type, and that won't be f80 since that is not custom lowered.
  bool IsF128 = (VT == MVT::f128);
  assert((VT == MVT::f64 || VT == MVT::f32 || VT == MVT::f128 ||
          VT == MVT::v2f64 || VT == MVT::v4f64 || VT == MVT::v4f32 ||
          VT == MVT::v8f32 || VT == MVT::v8f64 || VT == MVT::v16f32) &&
         "Unexpected type in LowerFCOPYSIGN");

  const fltSemantics &Sem = SelectionDAG::EVTToAPFloatSemantics(VT);

  // Perform all scalar logic operations as 16-byte vectors because there are no
  // scalar FP logic instructions in SSE.
  // TODO: This isn't necessary. If we used scalar types, we might avoid some
  // unnecessary splats, but we might miss load folding opportunities. Should
  // this decision be based on OptimizeForSize?
  bool IsFakeVector = !VT.isVector() && !IsF128;
  MVT LogicVT = VT;
  if (IsFakeVector)
    LogicVT = (VT == MVT::f64) ? MVT::v2f64 : MVT::v4f32;

  // The mask constants are automatically splatted for vector types.
  unsigned EltSizeInBits = VT.getScalarSizeInBits();
  SDValue SignMask = DAG.getConstantFP(
      APFloat(Sem, APInt::getSignMask(EltSizeInBits)), dl, LogicVT);
  SDValue MagMask = DAG.getConstantFP(
      APFloat(Sem, APInt::getSignedMaxValue(EltSizeInBits)), dl, LogicVT);

  // First, clear all bits but the sign bit from the second operand (sign).
  if (IsFakeVector)
    Sign = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, LogicVT, Sign);
  SDValue SignBit = DAG.getNode(X86ISD::FAND, dl, LogicVT, Sign, SignMask);

  // Next, clear the sign bit from the first operand (magnitude).
  // TODO: If we had general constant folding for FP logic ops, this check
  // wouldn't be necessary.
  SDValue MagBits;
  if (ConstantFPSDNode *Op0CN = isConstOrConstSplatFP(Mag)) {
    APFloat APF = Op0CN->getValueAPF();
    APF.clearSign();
    MagBits = DAG.getConstantFP(APF, dl, LogicVT);
  } else {
    // If the magnitude operand wasn't a constant, we need to AND out the sign.
    if (IsFakeVector)
      Mag = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, LogicVT, Mag);
    MagBits = DAG.getNode(X86ISD::FAND, dl, LogicVT, Mag, MagMask);
  }

  // OR the magnitude value with the sign bit.
  SDValue Or = DAG.getNode(X86ISD::FOR, dl, LogicVT, MagBits, SignBit);
  return !IsFakeVector ? Or : DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT, Or,
                                          DAG.getIntPtrConstant(0, dl));
}

static SDValue LowerFGETSIGN(SDValue Op, SelectionDAG &DAG) {
  SDValue N0 = Op.getOperand(0);
  SDLoc dl(Op);
  MVT VT = Op.getSimpleValueType();

  MVT OpVT = N0.getSimpleValueType();
  assert((OpVT == MVT::f32 || OpVT == MVT::f64) &&
         "Unexpected type for FGETSIGN");

  // Lower ISD::FGETSIGN to (AND (X86ISD::MOVMSK ...) 1).
  MVT VecVT = (OpVT == MVT::f32 ? MVT::v4f32 : MVT::v2f64);
  SDValue Res = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VecVT, N0);
  Res = DAG.getNode(X86ISD::MOVMSK, dl, MVT::i32, Res);
  Res = DAG.getZExtOrTrunc(Res, dl, VT);
  Res = DAG.getNode(ISD::AND, dl, VT, Res, DAG.getConstant(1, dl, VT));
  return Res;
}

/// Helper for creating a X86ISD::SETCC node.
static SDValue getSETCC(X86::CondCode Cond, SDValue EFLAGS, const SDLoc &dl,
                        SelectionDAG &DAG) {
  return DAG.getNode(X86ISD::SETCC, dl, MVT::i8,
                     DAG.getTargetConstant(Cond, dl, MVT::i8), EFLAGS);
}

/// Helper for matching OR(EXTRACTELT(X,0),OR(EXTRACTELT(X,1),...))
/// style scalarized (associative) reduction patterns. Partial reductions
/// are supported when the pointer SrcMask is non-null.
/// TODO - move this to SelectionDAG?
static bool matchScalarReduction(SDValue Op, ISD::NodeType BinOp,
                                 SmallVectorImpl<SDValue> &SrcOps,
                                 SmallVectorImpl<APInt> *SrcMask = nullptr) {
  SmallVector<SDValue, 8> Opnds;
  DenseMap<SDValue, APInt> SrcOpMap;
  EVT VT = MVT::Other;

  // Recognize a special case where a vector is casted into wide integer to
  // test all 0s.
  assert(Op.getOpcode() == unsigned(BinOp) &&
         "Unexpected bit reduction opcode");
  Opnds.push_back(Op.getOperand(0));
  Opnds.push_back(Op.getOperand(1));

  for (unsigned Slot = 0, e = Opnds.size(); Slot < e; ++Slot) {
    SmallVectorImpl<SDValue>::const_iterator I = Opnds.begin() + Slot;
    // BFS traverse all BinOp operands.
    if (I->getOpcode() == unsigned(BinOp)) {
      Opnds.push_back(I->getOperand(0));
      Opnds.push_back(I->getOperand(1));
      // Re-evaluate the number of nodes to be traversed.
      e += 2; // 2 more nodes (LHS and RHS) are pushed.
      continue;
    }

    // Quit if a non-EXTRACT_VECTOR_ELT
    if (I->getOpcode() != ISD::EXTRACT_VECTOR_ELT)
      return false;

    // Quit if without a constant index.
    SDValue Idx = I->getOperand(1);
    if (!isa<ConstantSDNode>(Idx))
      return false;

    SDValue Src = I->getOperand(0);
    DenseMap<SDValue, APInt>::iterator M = SrcOpMap.find(Src);
    if (M == SrcOpMap.end()) {
      VT = Src.getValueType();
      // Quit if not the same type.
      if (SrcOpMap.begin() != SrcOpMap.end() &&
          VT != SrcOpMap.begin()->first.getValueType())
        return false;
      unsigned NumElts = VT.getVectorNumElements();
      APInt EltCount = APInt::getNullValue(NumElts);
      M = SrcOpMap.insert(std::make_pair(Src, EltCount)).first;
      SrcOps.push_back(Src);
    }
    // Quit if element already used.
    unsigned CIdx = cast<ConstantSDNode>(Idx)->getZExtValue();
    if (M->second[CIdx])
      return false;
    M->second.setBit(CIdx);
  }

  if (SrcMask) {
    // Collect the source partial masks.
    for (SDValue &SrcOp : SrcOps)
      SrcMask->push_back(SrcOpMap[SrcOp]);
  } else {
    // Quit if not all elements are used.
    for (DenseMap<SDValue, APInt>::const_iterator I = SrcOpMap.begin(),
                                                  E = SrcOpMap.end();
         I != E; ++I) {
      if (!I->second.isAllOnesValue())
        return false;
    }
  }

  return true;
}

// Check whether an OR'd tree is PTEST-able.
static SDValue LowerVectorAllZeroTest(SDValue Op, ISD::CondCode CC,
                                      const X86Subtarget &Subtarget,
                                      SelectionDAG &DAG, SDValue &X86CC) {
  assert(Op.getOpcode() == ISD::OR && "Only check OR'd tree.");

  if (!Subtarget.hasSSE41() || !Op->hasOneUse())
    return SDValue();

  SmallVector<SDValue, 8> VecIns;
  if (!matchScalarReduction(Op, ISD::OR, VecIns))
    return SDValue();

  // Quit if not 128/256-bit vector.
  EVT VT = VecIns[0].getValueType();
  if (!VT.is128BitVector() && !VT.is256BitVector())
    return SDValue();

  SDLoc DL(Op);
  MVT TestVT = VT.is128BitVector() ? MVT::v2i64 : MVT::v4i64;

  // Cast all vectors into TestVT for PTEST.
  for (unsigned i = 0, e = VecIns.size(); i < e; ++i)
    VecIns[i] = DAG.getBitcast(TestVT, VecIns[i]);

  // If more than one full vector is evaluated, OR them first before PTEST.
  for (unsigned Slot = 0, e = VecIns.size(); e - Slot > 1; Slot += 2, e += 1) {
    // Each iteration will OR 2 nodes and append the result until there is only
    // 1 node left, i.e. the final OR'd value of all vectors.
    SDValue LHS = VecIns[Slot];
    SDValue RHS = VecIns[Slot + 1];
    VecIns.push_back(DAG.getNode(ISD::OR, DL, TestVT, LHS, RHS));
  }

  X86CC = DAG.getTargetConstant(CC == ISD::SETEQ ? X86::COND_E : X86::COND_NE,
                                DL, MVT::i8);
  return DAG.getNode(X86ISD::PTEST, DL, MVT::i32, VecIns.back(), VecIns.back());
}

/// return true if \c Op has a use that doesn't just read flags.
static bool hasNonFlagsUse(SDValue Op) {
  for (SDNode::use_iterator UI = Op->use_begin(), UE = Op->use_end(); UI != UE;
       ++UI) {
    SDNode *User = *UI;
    unsigned UOpNo = UI.getOperandNo();
    if (User->getOpcode() == ISD::TRUNCATE && User->hasOneUse()) {
      // Look pass truncate.
      UOpNo = User->use_begin().getOperandNo();
      User = *User->use_begin();
    }

    if (User->getOpcode() != ISD::BRCOND && User->getOpcode() != ISD::SETCC &&
        !(User->getOpcode() == ISD::SELECT && UOpNo == 0))
      return true;
  }
  return false;
}

// Transform to an x86-specific ALU node with flags if there is a chance of
// using an RMW op or only the flags are used. Otherwise, leave
// the node alone and emit a 'cmp' or 'test' instruction.
static bool isProfitableToUseFlagOp(SDValue Op) {
  for (SDNode *U : Op->uses())
    if (U->getOpcode() != ISD::CopyToReg &&
        U->getOpcode() != ISD::SETCC &&
        U->getOpcode() != ISD::STORE)
      return false;

  return true;
}

/// Emit nodes that will be selected as "test Op0,Op0", or something
/// equivalent.
static SDValue EmitTest(SDValue Op, unsigned X86CC, const SDLoc &dl,
                        SelectionDAG &DAG, const X86Subtarget &Subtarget) {
  // CF and OF aren't always set the way we want. Determine which
  // of these we need.
  bool NeedCF = false;
  bool NeedOF = false;
  switch (X86CC) {
  default: break;
  case X86::COND_A: case X86::COND_AE:
  case X86::COND_B: case X86::COND_BE:
    NeedCF = true;
    break;
  case X86::COND_G: case X86::COND_GE:
  case X86::COND_L: case X86::COND_LE:
  case X86::COND_O: case X86::COND_NO: {
    // Check if we really need to set the
    // Overflow flag. If NoSignedWrap is present
    // that is not actually needed.
    switch (Op->getOpcode()) {
    case ISD::ADD:
    case ISD::SUB:
    case ISD::MUL:
    case ISD::SHL:
      if (Op.getNode()->getFlags().hasNoSignedWrap())
        break;
      LLVM_FALLTHROUGH;
    default:
      NeedOF = true;
      break;
    }
    break;
  }
  }
  // See if we can use the EFLAGS value from the operand instead of
  // doing a separate TEST. TEST always sets OF and CF to 0, so unless
  // we prove that the arithmetic won't overflow, we can't use OF or CF.
  if (Op.getResNo() != 0 || NeedOF || NeedCF) {
    // Emit a CMP with 0, which is the TEST pattern.
    return DAG.getNode(X86ISD::CMP, dl, MVT::i32, Op,
                       DAG.getConstant(0, dl, Op.getValueType()));
  }
  unsigned Opcode = 0;
  unsigned NumOperands = 0;

  SDValue ArithOp = Op;

  // NOTICE: In the code below we use ArithOp to hold the arithmetic operation
  // which may be the result of a CAST.  We use the variable 'Op', which is the
  // non-casted variable when we check for possible users.
  switch (ArithOp.getOpcode()) {
  case ISD::AND:
    // If the primary 'and' result isn't used, don't bother using X86ISD::AND,
    // because a TEST instruction will be better.
    if (!hasNonFlagsUse(Op))
      break;

    LLVM_FALLTHROUGH;
  case ISD::ADD:
  case ISD::SUB:
  case ISD::OR:
  case ISD::XOR:
    if (!isProfitableToUseFlagOp(Op))
      break;

    // Otherwise use a regular EFLAGS-setting instruction.
    switch (ArithOp.getOpcode()) {
    default: llvm_unreachable("unexpected operator!");
    case ISD::ADD: Opcode = X86ISD::ADD; break;
    case ISD::SUB: Opcode = X86ISD::SUB; break;
    case ISD::XOR: Opcode = X86ISD::XOR; break;
    case ISD::AND: Opcode = X86ISD::AND; break;
    case ISD::OR:  Opcode = X86ISD::OR;  break;
    }

    NumOperands = 2;
    break;
  case X86ISD::ADD:
  case X86ISD::SUB:
  case X86ISD::OR:
  case X86ISD::XOR:
  case X86ISD::AND:
    return SDValue(Op.getNode(), 1);
  case ISD::SSUBO:
  case ISD::USUBO: {
    // /USUBO/SSUBO will become a X86ISD::SUB and we can use its Z flag.
    SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::i32);
    return DAG.getNode(X86ISD::SUB, dl, VTs, Op->getOperand(0),
                       Op->getOperand(1)).getValue(1);
  }
  default:
    break;
  }

  if (Opcode == 0) {
    // Emit a CMP with 0, which is the TEST pattern.
    return DAG.getNode(X86ISD::CMP, dl, MVT::i32, Op,
                       DAG.getConstant(0, dl, Op.getValueType()));
  }
  SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::i32);
  SmallVector<SDValue, 4> Ops(Op->op_begin(), Op->op_begin() + NumOperands);

  SDValue New = DAG.getNode(Opcode, dl, VTs, Ops);
  DAG.ReplaceAllUsesOfValueWith(SDValue(Op.getNode(), 0), New);
  return SDValue(New.getNode(), 1);
}

/// Emit nodes that will be selected as "cmp Op0,Op1", or something
/// equivalent.
static SDValue EmitCmp(SDValue Op0, SDValue Op1, unsigned X86CC,
                       const SDLoc &dl, SelectionDAG &DAG,
                       const X86Subtarget &Subtarget) {
  if (isNullConstant(Op1))
    return EmitTest(Op0, X86CC, dl, DAG, Subtarget);

  EVT CmpVT = Op0.getValueType();

  assert((CmpVT == MVT::i8 || CmpVT == MVT::i16 ||
          CmpVT == MVT::i32 || CmpVT == MVT::i64) && "Unexpected VT!");

  // Only promote the compare up to I32 if it is a 16 bit operation
  // with an immediate.  16 bit immediates are to be avoided.
  if (CmpVT == MVT::i16 && !Subtarget.isAtom() &&
      !DAG.getMachineFunction().getFunction().hasMinSize()) {
    ConstantSDNode *COp0 = dyn_cast<ConstantSDNode>(Op0);
    ConstantSDNode *COp1 = dyn_cast<ConstantSDNode>(Op1);
    // Don't do this if the immediate can fit in 8-bits.
    if ((COp0 && !COp0->getAPIntValue().isSignedIntN(8)) ||
        (COp1 && !COp1->getAPIntValue().isSignedIntN(8))) {
      unsigned ExtendOp =
          isX86CCSigned(X86CC) ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
      if (X86CC == X86::COND_E || X86CC == X86::COND_NE) {
        // For equality comparisons try to use SIGN_EXTEND if the input was
        // truncate from something with enough sign bits.
        if (Op0.getOpcode() == ISD::TRUNCATE) {
          SDValue In = Op0.getOperand(0);
          unsigned EffBits =
              In.getScalarValueSizeInBits() - DAG.ComputeNumSignBits(In) + 1;
          if (EffBits <= 16)
            ExtendOp = ISD::SIGN_EXTEND;
        } else if (Op1.getOpcode() == ISD::TRUNCATE) {
          SDValue In = Op1.getOperand(0);
          unsigned EffBits =
              In.getScalarValueSizeInBits() - DAG.ComputeNumSignBits(In) + 1;
          if (EffBits <= 16)
            ExtendOp = ISD::SIGN_EXTEND;
        }
      }

      CmpVT = MVT::i32;
      Op0 = DAG.getNode(ExtendOp, dl, CmpVT, Op0);
      Op1 = DAG.getNode(ExtendOp, dl, CmpVT, Op1);
    }
  }

  // Try to shrink i64 compares if the input has enough zero bits.
  // FIXME: Do this for non-constant compares for constant on LHS?
  if (CmpVT == MVT::i64 && isa<ConstantSDNode>(Op1) && !isX86CCSigned(X86CC) &&
      Op0.hasOneUse() && // Hacky way to not break CSE opportunities with sub.
      cast<ConstantSDNode>(Op1)->getAPIntValue().getActiveBits() <= 32 &&
      DAG.MaskedValueIsZero(Op0, APInt::getHighBitsSet(64, 32))) {
    CmpVT = MVT::i32;
    Op0 = DAG.getNode(ISD::TRUNCATE, dl, CmpVT, Op0);
    Op1 = DAG.getNode(ISD::TRUNCATE, dl, CmpVT, Op1);
  }

  // 0-x == y --> x+y == 0
  // 0-x != y --> x+y != 0
  if (Op0.getOpcode() == ISD::SUB && isNullConstant(Op0.getOperand(0)) &&
      Op0.hasOneUse() && (X86CC == X86::COND_E || X86CC == X86::COND_NE)) {
    SDVTList VTs = DAG.getVTList(CmpVT, MVT::i32);
    SDValue Add = DAG.getNode(X86ISD::ADD, dl, VTs, Op0.getOperand(1), Op1);
    return Add.getValue(1);
  }

  // x == 0-y --> x+y == 0
  // x != 0-y --> x+y != 0
  if (Op1.getOpcode() == ISD::SUB && isNullConstant(Op1.getOperand(0)) &&
      Op1.hasOneUse() && (X86CC == X86::COND_E || X86CC == X86::COND_NE)) {
    SDVTList VTs = DAG.getVTList(CmpVT, MVT::i32);
    SDValue Add = DAG.getNode(X86ISD::ADD, dl, VTs, Op0, Op1.getOperand(1));
    return Add.getValue(1);
  }

  // Use SUB instead of CMP to enable CSE between SUB and CMP.
  SDVTList VTs = DAG.getVTList(CmpVT, MVT::i32);
  SDValue Sub = DAG.getNode(X86ISD::SUB, dl, VTs, Op0, Op1);
  return Sub.getValue(1);
}

/// Check if replacement of SQRT with RSQRT should be disabled.
bool X86TargetLowering::isFsqrtCheap(SDValue Op, SelectionDAG &DAG) const {
  EVT VT = Op.getValueType();

  // We never want to use both SQRT and RSQRT instructions for the same input.
  if (DAG.getNodeIfExists(X86ISD::FRSQRT, DAG.getVTList(VT), Op))
    return false;

  if (VT.isVector())
    return Subtarget.hasFastVectorFSQRT();
  return Subtarget.hasFastScalarFSQRT();
}

/// The minimum architected relative accuracy is 2^-12. We need one
/// Newton-Raphson step to have a good float result (24 bits of precision).
SDValue X86TargetLowering::getSqrtEstimate(SDValue Op,
                                           SelectionDAG &DAG, int Enabled,
                                           int &RefinementSteps,
                                           bool &UseOneConstNR,
                                           bool Reciprocal) const {
  EVT VT = Op.getValueType();

  // SSE1 has rsqrtss and rsqrtps. AVX adds a 256-bit variant for rsqrtps.
  // It is likely not profitable to do this for f64 because a double-precision
  // rsqrt estimate with refinement on x86 prior to FMA requires at least 16
  // instructions: convert to single, rsqrtss, convert back to double, refine
  // (3 steps = at least 13 insts). If an 'rsqrtsd' variant was added to the ISA
  // along with FMA, this could be a throughput win.
  // TODO: SQRT requires SSE2 to prevent the introduction of an illegal v4i32
  // after legalize types.
  if ((VT == MVT::f32 && Subtarget.hasSSE1()) ||
      (VT == MVT::v4f32 && Subtarget.hasSSE1() && Reciprocal) ||
      (VT == MVT::v4f32 && Subtarget.hasSSE2() && !Reciprocal) ||
      (VT == MVT::v8f32 && Subtarget.hasAVX()) ||
      (VT == MVT::v16f32 && Subtarget.useAVX512Regs())) {
    if (RefinementSteps == ReciprocalEstimate::Unspecified)
      RefinementSteps = 1;

    UseOneConstNR = false;
    // There is no FSQRT for 512-bits, but there is RSQRT14.
    unsigned Opcode = VT == MVT::v16f32 ? X86ISD::RSQRT14 : X86ISD::FRSQRT;
    return DAG.getNode(Opcode, SDLoc(Op), VT, Op);
  }
  return SDValue();
}

/// The minimum architected relative accuracy is 2^-12. We need one
/// Newton-Raphson step to have a good float result (24 bits of precision).
SDValue X86TargetLowering::getRecipEstimate(SDValue Op, SelectionDAG &DAG,
                                            int Enabled,
                                            int &RefinementSteps) const {
  EVT VT = Op.getValueType();

  // SSE1 has rcpss and rcpps. AVX adds a 256-bit variant for rcpps.
  // It is likely not profitable to do this for f64 because a double-precision
  // reciprocal estimate with refinement on x86 prior to FMA requires
  // 15 instructions: convert to single, rcpss, convert back to double, refine
  // (3 steps = 12 insts). If an 'rcpsd' variant was added to the ISA
  // along with FMA, this could be a throughput win.

  if ((VT == MVT::f32 && Subtarget.hasSSE1()) ||
      (VT == MVT::v4f32 && Subtarget.hasSSE1()) ||
      (VT == MVT::v8f32 && Subtarget.hasAVX()) ||
      (VT == MVT::v16f32 && Subtarget.useAVX512Regs())) {
    // Enable estimate codegen with 1 refinement step for vector division.
    // Scalar division estimates are disabled because they break too much
    // real-world code. These defaults are intended to match GCC behavior.
    if (VT == MVT::f32 && Enabled == ReciprocalEstimate::Unspecified)
      return SDValue();

    if (RefinementSteps == ReciprocalEstimate::Unspecified)
      RefinementSteps = 1;

    // There is no FSQRT for 512-bits, but there is RCP14.
    unsigned Opcode = VT == MVT::v16f32 ? X86ISD::RCP14 : X86ISD::FRCP;
    return DAG.getNode(Opcode, SDLoc(Op), VT, Op);
  }
  return SDValue();
}

/// If we have at least two divisions that use the same divisor, convert to
/// multiplication by a reciprocal. This may need to be adjusted for a given
/// CPU if a division's cost is not at least twice the cost of a multiplication.
/// This is because we still need one division to calculate the reciprocal and
/// then we need two multiplies by that reciprocal as replacements for the
/// original divisions.
unsigned X86TargetLowering::combineRepeatedFPDivisors() const {
  return 2;
}

SDValue
X86TargetLowering::BuildSDIVPow2(SDNode *N, const APInt &Divisor,
                                 SelectionDAG &DAG,
                                 SmallVectorImpl<SDNode *> &Created) const {
  AttributeList Attr = DAG.getMachineFunction().getFunction().getAttributes();
  if (isIntDivCheap(N->getValueType(0), Attr))
    return SDValue(N,0); // Lower SDIV as SDIV

  assert((Divisor.isPowerOf2() || (-Divisor).isPowerOf2()) &&
         "Unexpected divisor!");

  // Only perform this transform if CMOV is supported otherwise the select
  // below will become a branch.
  if (!Subtarget.hasCMov())
    return SDValue();

  // fold (sdiv X, pow2)
  EVT VT = N->getValueType(0);
  // FIXME: Support i8.
  if (VT != MVT::i16 && VT != MVT::i32 &&
      !(Subtarget.is64Bit() && VT == MVT::i64))
    return SDValue();

  unsigned Lg2 = Divisor.countTrailingZeros();

  // If the divisor is 2 or -2, the default expansion is better.
  if (Lg2 == 1)
    return SDValue();

  SDLoc DL(N);
  SDValue N0 = N->getOperand(0);
  SDValue Zero = DAG.getConstant(0, DL, VT);
  APInt Lg2Mask = APInt::getLowBitsSet(VT.getSizeInBits(), Lg2);
  SDValue Pow2MinusOne = DAG.getConstant(Lg2Mask, DL, VT);

  // If N0 is negative, we need to add (Pow2 - 1) to it before shifting right.
  SDValue Cmp = DAG.getSetCC(DL, MVT::i8, N0, Zero, ISD::SETLT);
  SDValue Add = DAG.getNode(ISD::ADD, DL, VT, N0, Pow2MinusOne);
  SDValue CMov = DAG.getNode(ISD::SELECT, DL, VT, Cmp, Add, N0);

  Created.push_back(Cmp.getNode());
  Created.push_back(Add.getNode());
  Created.push_back(CMov.getNode());

  // Divide by pow2.
  SDValue SRA =
      DAG.getNode(ISD::SRA, DL, VT, CMov, DAG.getConstant(Lg2, DL, MVT::i8));

  // If we're dividing by a positive value, we're done.  Otherwise, we must
  // negate the result.
  if (Divisor.isNonNegative())
    return SRA;

  Created.push_back(SRA.getNode());
  return DAG.getNode(ISD::SUB, DL, VT, Zero, SRA);
}

/// Result of 'and' is compared against zero. Change to a BT node if possible.
/// Returns the BT node and the condition code needed to use it.
static SDValue LowerAndToBT(SDValue And, ISD::CondCode CC,
                            const SDLoc &dl, SelectionDAG &DAG,
                            SDValue &X86CC) {
  assert(And.getOpcode() == ISD::AND && "Expected AND node!");
  SDValue Op0 = And.getOperand(0);
  SDValue Op1 = And.getOperand(1);
  if (Op0.getOpcode() == ISD::TRUNCATE)
    Op0 = Op0.getOperand(0);
  if (Op1.getOpcode() == ISD::TRUNCATE)
    Op1 = Op1.getOperand(0);

  SDValue Src, BitNo;
  if (Op1.getOpcode() == ISD::SHL)
    std::swap(Op0, Op1);
  if (Op0.getOpcode() == ISD::SHL) {
    if (isOneConstant(Op0.getOperand(0))) {
      // If we looked past a truncate, check that it's only truncating away
      // known zeros.
      unsigned BitWidth = Op0.getValueSizeInBits();
      unsigned AndBitWidth = And.getValueSizeInBits();
      if (BitWidth > AndBitWidth) {
        KnownBits Known = DAG.computeKnownBits(Op0);
        if (Known.countMinLeadingZeros() < BitWidth - AndBitWidth)
          return SDValue();
      }
      Src = Op1;
      BitNo = Op0.getOperand(1);
    }
  } else if (Op1.getOpcode() == ISD::Constant) {
    ConstantSDNode *AndRHS = cast<ConstantSDNode>(Op1);
    uint64_t AndRHSVal = AndRHS->getZExtValue();
    SDValue AndLHS = Op0;

    if (AndRHSVal == 1 && AndLHS.getOpcode() == ISD::SRL) {
      Src = AndLHS.getOperand(0);
      BitNo = AndLHS.getOperand(1);
    } else {
      // Use BT if the immediate can't be encoded in a TEST instruction or we
      // are optimizing for size and the immedaite won't fit in a byte.
      bool OptForSize = DAG.shouldOptForSize();
      if ((!isUInt<32>(AndRHSVal) || (OptForSize && !isUInt<8>(AndRHSVal))) &&
          isPowerOf2_64(AndRHSVal)) {
        Src = AndLHS;
        BitNo = DAG.getConstant(Log2_64_Ceil(AndRHSVal), dl,
                                Src.getValueType());
      }
    }
  }

  // No patterns found, give up.
  if (!Src.getNode())
    return SDValue();

  // If Src is i8, promote it to i32 with any_extend.  There is no i8 BT
  // instruction.  Since the shift amount is in-range-or-undefined, we know
  // that doing a bittest on the i32 value is ok.  We extend to i32 because
  // the encoding for the i16 version is larger than the i32 version.
  // Also promote i16 to i32 for performance / code size reason.
  if (Src.getValueType() == MVT::i8 || Src.getValueType() == MVT::i16)
    Src = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, Src);

  // See if we can use the 32-bit instruction instead of the 64-bit one for a
  // shorter encoding. Since the former takes the modulo 32 of BitNo and the
  // latter takes the modulo 64, this is only valid if the 5th bit of BitNo is
  // known to be zero.
  if (Src.getValueType() == MVT::i64 &&
      DAG.MaskedValueIsZero(BitNo, APInt(BitNo.getValueSizeInBits(), 32)))
    Src = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Src);

  // If the operand types disagree, extend the shift amount to match.  Since
  // BT ignores high bits (like shifts) we can use anyextend.
  if (Src.getValueType() != BitNo.getValueType())
    BitNo = DAG.getNode(ISD::ANY_EXTEND, dl, Src.getValueType(), BitNo);

  X86CC = DAG.getTargetConstant(CC == ISD::SETEQ ? X86::COND_AE : X86::COND_B,
                                dl, MVT::i8);
  return DAG.getNode(X86ISD::BT, dl, MVT::i32, Src, BitNo);
}

/// Turns an ISD::CondCode into a value suitable for SSE floating-point mask
/// CMPs.
static unsigned translateX86FSETCC(ISD::CondCode SetCCOpcode, SDValue &Op0,
                                   SDValue &Op1, bool &IsAlwaysSignaling) {
  unsigned SSECC;
  bool Swap = false;

  // SSE Condition code mapping:
  //  0 - EQ
  //  1 - LT
  //  2 - LE
  //  3 - UNORD
  //  4 - NEQ
  //  5 - NLT
  //  6 - NLE
  //  7 - ORD
  switch (SetCCOpcode) {
  default: llvm_unreachable("Unexpected SETCC condition");
  case ISD::SETOEQ:
  case ISD::SETEQ:  SSECC = 0; break;
  case ISD::SETOGT:
  case ISD::SETGT:  Swap = true; LLVM_FALLTHROUGH;
  case ISD::SETLT:
  case ISD::SETOLT: SSECC = 1; break;
  case ISD::SETOGE:
  case ISD::SETGE:  Swap = true; LLVM_FALLTHROUGH;
  case ISD::SETLE:
  case ISD::SETOLE: SSECC = 2; break;
  case ISD::SETUO:  SSECC = 3; break;
  case ISD::SETUNE:
  case ISD::SETNE:  SSECC = 4; break;
  case ISD::SETULE: Swap = true; LLVM_FALLTHROUGH;
  case ISD::SETUGE: SSECC = 5; break;
  case ISD::SETULT: Swap = true; LLVM_FALLTHROUGH;
  case ISD::SETUGT: SSECC = 6; break;
  case ISD::SETO:   SSECC = 7; break;
  case ISD::SETUEQ: SSECC = 8; break;
  case ISD::SETONE: SSECC = 12; break;
  }
  if (Swap)
    std::swap(Op0, Op1);

  switch (SetCCOpcode) {
  default:
    IsAlwaysSignaling = true;
    break;
  case ISD::SETEQ:
  case ISD::SETOEQ:
  case ISD::SETUEQ:
  case ISD::SETNE:
  case ISD::SETONE:
  case ISD::SETUNE:
  case ISD::SETO:
  case ISD::SETUO:
    IsAlwaysSignaling = false;
    break;
  }

  return SSECC;
}

/// Break a VSETCC 256-bit integer VSETCC into two new 128 ones and then
/// concatenate the result back.
static SDValue Lower256IntVSETCC(SDValue Op, SelectionDAG &DAG) {
  MVT VT = Op.getSimpleValueType();

  assert(VT.is256BitVector() && Op.getOpcode() == ISD::SETCC &&
         "Unsupported value type for operation");

  unsigned NumElems = VT.getVectorNumElements();
  SDLoc dl(Op);
  SDValue CC = Op.getOperand(2);

  // Extract the LHS vectors
  SDValue LHS = Op.getOperand(0);
  SDValue LHS1 = extract128BitVector(LHS, 0, DAG, dl);
  SDValue LHS2 = extract128BitVector(LHS, NumElems / 2, DAG, dl);

  // Extract the RHS vectors
  SDValue RHS = Op.getOperand(1);
  SDValue RHS1 = extract128BitVector(RHS, 0, DAG, dl);
  SDValue RHS2 = extract128BitVector(RHS, NumElems / 2, DAG, dl);

  // Issue the operation on the smaller types and concatenate the result back
  MVT EltVT = VT.getVectorElementType();
  MVT NewVT = MVT::getVectorVT(EltVT, NumElems/2);
  return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT,
                     DAG.getNode(Op.getOpcode(), dl, NewVT, LHS1, RHS1, CC),
                     DAG.getNode(Op.getOpcode(), dl, NewVT, LHS2, RHS2, CC));
}

static SDValue LowerIntVSETCC_AVX512(SDValue Op, SelectionDAG &DAG) {

  SDValue Op0 = Op.getOperand(0);
  SDValue Op1 = Op.getOperand(1);
  SDValue CC = Op.getOperand(2);
  MVT VT = Op.getSimpleValueType();
  SDLoc dl(Op);

  assert(VT.getVectorElementType() == MVT::i1 &&
         "Cannot set masked compare for this operation");

  ISD::CondCode SetCCOpcode = cast<CondCodeSDNode>(CC)->get();

  // Prefer SETGT over SETLT.
  if (SetCCOpcode == ISD::SETLT) {
    SetCCOpcode = ISD::getSetCCSwappedOperands(SetCCOpcode);
    std::swap(Op0, Op1);
  }

  return DAG.getSetCC(dl, VT, Op0, Op1, SetCCOpcode);
}

/// Given a buildvector constant, return a new vector constant with each element
/// incremented or decremented. If incrementing or decrementing would result in
/// unsigned overflow or underflow or this is not a simple vector constant,
/// return an empty value.
static SDValue incDecVectorConstant(SDValue V, SelectionDAG &DAG, bool IsInc) {
  auto *BV = dyn_cast<BuildVectorSDNode>(V.getNode());
  if (!BV)
    return SDValue();

  MVT VT = V.getSimpleValueType();
  MVT EltVT = VT.getVectorElementType();
  unsigned NumElts = VT.getVectorNumElements();
  SmallVector<SDValue, 8> NewVecC;
  SDLoc DL(V);
  for (unsigned i = 0; i < NumElts; ++i) {
    auto *Elt = dyn_cast<ConstantSDNode>(BV->getOperand(i));
    if (!Elt || Elt->isOpaque() || Elt->getSimpleValueType(0) != EltVT)
      return SDValue();

    // Avoid overflow/underflow.
    const APInt &EltC = Elt->getAPIntValue();
    if ((IsInc && EltC.isMaxValue()) || (!IsInc && EltC.isNullValue()))
      return SDValue();

    NewVecC.push_back(DAG.getConstant(EltC + (IsInc ? 1 : -1), DL, EltVT));
  }

  return DAG.getBuildVector(VT, DL, NewVecC);
}

/// As another special case, use PSUBUS[BW] when it's profitable. E.g. for
/// Op0 u<= Op1:
///   t = psubus Op0, Op1
///   pcmpeq t, <0..0>
static SDValue LowerVSETCCWithSUBUS(SDValue Op0, SDValue Op1, MVT VT,
                                    ISD::CondCode Cond, const SDLoc &dl,
                                    const X86Subtarget &Subtarget,
                                    SelectionDAG &DAG) {
  if (!Subtarget.hasSSE2())
    return SDValue();

  MVT VET = VT.getVectorElementType();
  if (VET != MVT::i8 && VET != MVT::i16)
    return SDValue();

  switch (Cond) {
  default:
    return SDValue();
  case ISD::SETULT: {
    // If the comparison is against a constant we can turn this into a
    // setule.  With psubus, setule does not require a swap.  This is
    // beneficial because the constant in the register is no longer
    // destructed as the destination so it can be hoisted out of a loop.
    // Only do this pre-AVX since vpcmp* is no longer destructive.
    if (Subtarget.hasAVX())
      return SDValue();
    SDValue ULEOp1 = incDecVectorConstant(Op1, DAG, /*IsInc*/false);
    if (!ULEOp1)
      return SDValue();
    Op1 = ULEOp1;
    break;
  }
  case ISD::SETUGT: {
    // If the comparison is against a constant, we can turn this into a setuge.
    // This is beneficial because materializing a constant 0 for the PCMPEQ is
    // probably cheaper than XOR+PCMPGT using 2 different vector constants:
    // cmpgt (xor X, SignMaskC) CmpC --> cmpeq (usubsat (CmpC+1), X), 0
    SDValue UGEOp1 = incDecVectorConstant(Op1, DAG, /*IsInc*/true);
    if (!UGEOp1)
      return SDValue();
    Op1 = Op0;
    Op0 = UGEOp1;
    break;
  }
  // Psubus is better than flip-sign because it requires no inversion.
  case ISD::SETUGE:
    std::swap(Op0, Op1);
    break;
  case ISD::SETULE:
    break;
  }

  SDValue Result = DAG.getNode(ISD::USUBSAT, dl, VT, Op0, Op1);
  return DAG.getNode(X86ISD::PCMPEQ, dl, VT, Result,
                     DAG.getConstant(0, dl, VT));
}

static SDValue LowerVSETCC(SDValue Op, const X86Subtarget &Subtarget,
                           SelectionDAG &DAG) {
  bool IsStrict = Op.getOpcode() == ISD::STRICT_FSETCC ||
                  Op.getOpcode() == ISD::STRICT_FSETCCS;
  SDValue Op0 = Op.getOperand(IsStrict ? 1 : 0);
  SDValue Op1 = Op.getOperand(IsStrict ? 2 : 1);
  SDValue CC = Op.getOperand(IsStrict ? 3 : 2);
  MVT VT = Op->getSimpleValueType(0);
  ISD::CondCode Cond = cast<CondCodeSDNode>(CC)->get();
  bool isFP = Op1.getSimpleValueType().isFloatingPoint();
  SDLoc dl(Op);

  if (isFP) {
#ifndef NDEBUG
    MVT EltVT = Op0.getSimpleValueType().getVectorElementType();
    assert(EltVT == MVT::f32 || EltVT == MVT::f64);
#endif

    bool IsSignaling = Op.getOpcode() == ISD::STRICT_FSETCCS;
    SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();

    // If we have a strict compare with a vXi1 result and the input is 128/256
    // bits we can't use a masked compare unless we have VLX. If we use a wider
    // compare like we do for non-strict, we might trigger spurious exceptions
    // from the upper elements. Instead emit a AVX compare and convert to mask.
    unsigned Opc;
    if (Subtarget.hasAVX512() && VT.getVectorElementType() == MVT::i1 &&
        (!IsStrict || Subtarget.hasVLX() ||
         Op0.getSimpleValueType().is512BitVector())) {
      assert(VT.getVectorNumElements() <= 16);
      Opc = IsStrict ? X86ISD::STRICT_CMPM : X86ISD::CMPM;
    } else {
      Opc = IsStrict ? X86ISD::STRICT_CMPP : X86ISD::CMPP;
      // The SSE/AVX packed FP comparison nodes are defined with a
      // floating-point vector result that matches the operand type. This allows
      // them to work with an SSE1 target (integer vector types are not legal).
      VT = Op0.getSimpleValueType();
    }

    SDValue Cmp;
    bool IsAlwaysSignaling;
    unsigned SSECC = translateX86FSETCC(Cond, Op0, Op1, IsAlwaysSignaling);
    if (!Subtarget.hasAVX()) {
      // TODO: We could use following steps to handle a quiet compare with
      // signaling encodings.
      // 1. Get ordered masks from a quiet ISD::SETO
      // 2. Use the masks to mask potential unordered elements in operand A, B
      // 3. Get the compare results of masked A, B
      // 4. Calculating final result using the mask and result from 3
      // But currently, we just fall back to scalar operations.
      if (IsStrict && IsAlwaysSignaling && !IsSignaling)
        return SDValue();

      // Insert an extra signaling instruction to raise exception.
      if (IsStrict && !IsAlwaysSignaling && IsSignaling) {
        SDValue SignalCmp = DAG.getNode(
            Opc, dl, {VT, MVT::Other},
            {Chain, Op0, Op1, DAG.getTargetConstant(1, dl, MVT::i8)}); // LT_OS
        // FIXME: It seems we need to update the flags of all new strict nodes.
        // Otherwise, mayRaiseFPException in MI will return false due to
        // NoFPExcept = false by default. However, I didn't find it in other
        // patches.
        SignalCmp->setFlags(Op->getFlags());
        Chain = SignalCmp.getValue(1);
      }

      // In the two cases not handled by SSE compare predicates (SETUEQ/SETONE),
      // emit two comparisons and a logic op to tie them together.
      if (SSECC >= 8) {
        // LLVM predicate is SETUEQ or SETONE.
        unsigned CC0, CC1;
        unsigned CombineOpc;
        if (Cond == ISD::SETUEQ) {
          CC0 = 3; // UNORD
          CC1 = 0; // EQ
          CombineOpc = X86ISD::FOR;
        } else {
          assert(Cond == ISD::SETONE);
          CC0 = 7; // ORD
          CC1 = 4; // NEQ
          CombineOpc = X86ISD::FAND;
        }

        SDValue Cmp0, Cmp1;
        if (IsStrict) {
          Cmp0 = DAG.getNode(
              Opc, dl, {VT, MVT::Other},
              {Chain, Op0, Op1, DAG.getTargetConstant(CC0, dl, MVT::i8)});
          Cmp1 = DAG.getNode(
              Opc, dl, {VT, MVT::Other},
              {Chain, Op0, Op1, DAG.getTargetConstant(CC1, dl, MVT::i8)});
          Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Cmp0.getValue(1),
                              Cmp1.getValue(1));
        } else {
          Cmp0 = DAG.getNode(
              Opc, dl, VT, Op0, Op1, DAG.getTargetConstant(CC0, dl, MVT::i8));
          Cmp1 = DAG.getNode(
              Opc, dl, VT, Op0, Op1, DAG.getTargetConstant(CC1, dl, MVT::i8));
        }
        Cmp = DAG.getNode(CombineOpc, dl, VT, Cmp0, Cmp1);
      } else {
        if (IsStrict) {
          Cmp = DAG.getNode(
              Opc, dl, {VT, MVT::Other},
              {Chain, Op0, Op1, DAG.getTargetConstant(SSECC, dl, MVT::i8)});
          Chain = Cmp.getValue(1);
        } else
          Cmp = DAG.getNode(
              Opc, dl, VT, Op0, Op1, DAG.getTargetConstant(SSECC, dl, MVT::i8));
      }
    } else {
      // Handle all other FP comparisons here.
      if (IsStrict) {
        // Make a flip on already signaling CCs before setting bit 4 of AVX CC.
        SSECC |= (IsAlwaysSignaling ^ IsSignaling) << 4;
        Cmp = DAG.getNode(
            Opc, dl, {VT, MVT::Other},
            {Chain, Op0, Op1, DAG.getTargetConstant(SSECC, dl, MVT::i8)});
        Chain = Cmp.getValue(1);
      } else
        Cmp = DAG.getNode(
            Opc, dl, VT, Op0, Op1, DAG.getTargetConstant(SSECC, dl, MVT::i8));
    }

    if (VT.getSizeInBits() > Op.getSimpleValueType().getSizeInBits()) {
      // We emitted a compare with an XMM/YMM result. Finish converting to a
      // mask register using a vptestm.
      EVT CastVT = EVT(VT).changeVectorElementTypeToInteger();
      Cmp = DAG.getBitcast(CastVT, Cmp);
      Cmp = DAG.getSetCC(dl, Op.getSimpleValueType(), Cmp,
                         DAG.getConstant(0, dl, CastVT), ISD::SETNE);
    } else {
      // If this is SSE/AVX CMPP, bitcast the result back to integer to match
      // the result type of SETCC. The bitcast is expected to be optimized
      // away during combining/isel.
      Cmp = DAG.getBitcast(Op.getSimpleValueType(), Cmp);
    }

    if (IsStrict)
      return DAG.getMergeValues({Cmp, Chain}, dl);

    return Cmp;
  }

  assert(!IsStrict && "Strict SETCC only handles FP operands.");

  MVT VTOp0 = Op0.getSimpleValueType();
  (void)VTOp0;
  assert(VTOp0 == Op1.getSimpleValueType() &&
         "Expected operands with same type!");
  assert(VT.getVectorNumElements() == VTOp0.getVectorNumElements() &&
         "Invalid number of packed elements for source and destination!");

  // The non-AVX512 code below works under the assumption that source and
  // destination types are the same.
  assert((Subtarget.hasAVX512() || (VT == VTOp0)) &&
         "Value types for source and destination must be the same!");

  // The result is boolean, but operands are int/float
  if (VT.getVectorElementType() == MVT::i1) {
    // In AVX-512 architecture setcc returns mask with i1 elements,
    // But there is no compare instruction for i8 and i16 elements in KNL.
    assert((VTOp0.getScalarSizeInBits() >= 32 || Subtarget.hasBWI()) &&
           "Unexpected operand type");
    return LowerIntVSETCC_AVX512(Op, DAG);
  }

  // Lower using XOP integer comparisons.
  if (VT.is128BitVector() && Subtarget.hasXOP()) {
    // Translate compare code to XOP PCOM compare mode.
    unsigned CmpMode = 0;
    switch (Cond) {
    default: llvm_unreachable("Unexpected SETCC condition");
    case ISD::SETULT:
    case ISD::SETLT: CmpMode = 0x00; break;
    case ISD::SETULE:
    case ISD::SETLE: CmpMode = 0x01; break;
    case ISD::SETUGT:
    case ISD::SETGT: CmpMode = 0x02; break;
    case ISD::SETUGE:
    case ISD::SETGE: CmpMode = 0x03; break;
    case ISD::SETEQ: CmpMode = 0x04; break;
    case ISD::SETNE: CmpMode = 0x05; break;
    }

    // Are we comparing unsigned or signed integers?
    unsigned Opc =
        ISD::isUnsignedIntSetCC(Cond) ? X86ISD::VPCOMU : X86ISD::VPCOM;

    return DAG.getNode(Opc, dl, VT, Op0, Op1,
                       DAG.getTargetConstant(CmpMode, dl, MVT::i8));
  }

  // (X & Y) != 0 --> (X & Y) == Y iff Y is power-of-2.
  // Revert part of the simplifySetCCWithAnd combine, to avoid an invert.
  if (Cond == ISD::SETNE && ISD::isBuildVectorAllZeros(Op1.getNode())) {
    SDValue BC0 = peekThroughBitcasts(Op0);
    if (BC0.getOpcode() == ISD::AND) {
      APInt UndefElts;
      SmallVector<APInt, 64> EltBits;
      if (getTargetConstantBitsFromNode(BC0.getOperand(1),
                                        VT.getScalarSizeInBits(), UndefElts,
                                        EltBits, false, false)) {
        if (llvm::all_of(EltBits, [](APInt &V) { return V.isPowerOf2(); })) {
          Cond = ISD::SETEQ;
          Op1 = DAG.getBitcast(VT, BC0.getOperand(1));
        }
      }
    }
  }

  // ICMP_EQ(AND(X,C),C) -> SRA(SHL(X,LOG2(C)),BW-1) iff C is power-of-2.
  if (Cond == ISD::SETEQ && Op0.getOpcode() == ISD::AND &&
      Op0.getOperand(1) == Op1 && Op0.hasOneUse()) {
    ConstantSDNode *C1 = isConstOrConstSplat(Op1);
    if (C1 && C1->getAPIntValue().isPowerOf2()) {
      unsigned BitWidth = VT.getScalarSizeInBits();
      unsigned ShiftAmt = BitWidth - C1->getAPIntValue().logBase2() - 1;

      SDValue Result = Op0.getOperand(0);
      Result = DAG.getNode(ISD::SHL, dl, VT, Result,
                           DAG.getConstant(ShiftAmt, dl, VT));
      Result = DAG.getNode(ISD::SRA, dl, VT, Result,
                           DAG.getConstant(BitWidth - 1, dl, VT));
      return Result;
    }
  }

  // Break 256-bit integer vector compare into smaller ones.
  if (VT.is256BitVector() && !Subtarget.hasInt256())
    return Lower256IntVSETCC(Op, DAG);

  // If this is a SETNE against the signed minimum value, change it to SETGT.
  // If this is a SETNE against the signed maximum value, change it to SETLT.
  // which will be swapped to SETGT.
  // Otherwise we use PCMPEQ+invert.
  APInt ConstValue;
  if (Cond == ISD::SETNE &&
      ISD::isConstantSplatVector(Op1.getNode(), ConstValue)) {
    if (ConstValue.isMinSignedValue())
      Cond = ISD::SETGT;
    else if (ConstValue.isMaxSignedValue())
      Cond = ISD::SETLT;
  }

  // If both operands are known non-negative, then an unsigned compare is the
  // same as a signed compare and there's no need to flip signbits.
  // TODO: We could check for more general simplifications here since we're
  // computing known bits.
  bool FlipSigns = ISD::isUnsignedIntSetCC(Cond) &&
                   !(DAG.SignBitIsZero(Op0) && DAG.SignBitIsZero(Op1));

  // Special case: Use min/max operations for unsigned compares.
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  if (ISD::isUnsignedIntSetCC(Cond) &&
      (FlipSigns || ISD::isTrueWhenEqual(Cond)) &&
      TLI.isOperationLegal(ISD::UMIN, VT)) {
    // If we have a constant operand, increment/decrement it and change the
    // condition to avoid an invert.
    if (Cond == ISD::SETUGT) {
      // X > C --> X >= (C+1) --> X == umax(X, C+1)
      if (SDValue UGTOp1 = incDecVectorConstant(Op1, DAG, /*IsInc*/true)) {
        Op1 = UGTOp1;
        Cond = ISD::SETUGE;
      }
    }
    if (Cond == ISD::SETULT) {
      // X < C --> X <= (C-1) --> X == umin(X, C-1)
      if (SDValue ULTOp1 = incDecVectorConstant(Op1, DAG, /*IsInc*/false)) {
        Op1 = ULTOp1;
        Cond = ISD::SETULE;
      }
    }
    bool Invert = false;
    unsigned Opc;
    switch (Cond) {
    default: llvm_unreachable("Unexpected condition code");
    case ISD::SETUGT: Invert = true; LLVM_FALLTHROUGH;
    case ISD::SETULE: Opc = ISD::UMIN; break;
    case ISD::SETULT: Invert = true; LLVM_FALLTHROUGH;
    case ISD::SETUGE: Opc = ISD::UMAX; break;
    }

    SDValue Result = DAG.getNode(Opc, dl, VT, Op0, Op1);
    Result = DAG.getNode(X86ISD::PCMPEQ, dl, VT, Op0, Result);

    // If the logical-not of the result is required, perform that now.
    if (Invert)
      Result = DAG.getNOT(dl, Result, VT);

    return Result;
  }

  // Try to use SUBUS and PCMPEQ.
  if (SDValue V = LowerVSETCCWithSUBUS(Op0, Op1, VT, Cond, dl, Subtarget, DAG))
    return V;

  // We are handling one of the integer comparisons here. Since SSE only has
  // GT and EQ comparisons for integer, swapping operands and multiple
  // operations may be required for some comparisons.
  unsigned Opc = (Cond == ISD::SETEQ || Cond == ISD::SETNE) ? X86ISD::PCMPEQ
                                                            : X86ISD::PCMPGT;
  bool Swap = Cond == ISD::SETLT || Cond == ISD::SETULT ||
              Cond == ISD::SETGE || Cond == ISD::SETUGE;
  bool Invert = Cond == ISD::SETNE ||
                (Cond != ISD::SETEQ && ISD::isTrueWhenEqual(Cond));

  if (Swap)
    std::swap(Op0, Op1);

  // Check that the operation in question is available (most are plain SSE2,
  // but PCMPGTQ and PCMPEQQ have different requirements).
  if (VT == MVT::v2i64) {
    if (Opc == X86ISD::PCMPGT && !Subtarget.hasSSE42()) {
      assert(Subtarget.hasSSE2() && "Don't know how to lower!");

      // Special case for sign bit test. We can use a v4i32 PCMPGT and shuffle
      // the odd elements over the even elements.
      if (!FlipSigns && !Invert && ISD::isBuildVectorAllZeros(Op0.getNode())) {
        Op0 = DAG.getConstant(0, dl, MVT::v4i32);
        Op1 = DAG.getBitcast(MVT::v4i32, Op1);

        SDValue GT = DAG.getNode(X86ISD::PCMPGT, dl, MVT::v4i32, Op0, Op1);
        static const int MaskHi[] = { 1, 1, 3, 3 };
        SDValue Result = DAG.getVectorShuffle(MVT::v4i32, dl, GT, GT, MaskHi);

        return DAG.getBitcast(VT, Result);
      }

      if (!FlipSigns && !Invert && ISD::isBuildVectorAllOnes(Op1.getNode())) {
        Op0 = DAG.getBitcast(MVT::v4i32, Op0);
        Op1 = DAG.getConstant(-1, dl, MVT::v4i32);

        SDValue GT = DAG.getNode(X86ISD::PCMPGT, dl, MVT::v4i32, Op0, Op1);
        static const int MaskHi[] = { 1, 1, 3, 3 };
        SDValue Result = DAG.getVectorShuffle(MVT::v4i32, dl, GT, GT, MaskHi);

        return DAG.getBitcast(VT, Result);
      }

      // Since SSE has no unsigned integer comparisons, we need to flip the sign
      // bits of the inputs before performing those operations. The lower
      // compare is always unsigned.
      SDValue SB;
      if (FlipSigns) {
        SB = DAG.getConstant(0x8000000080000000ULL, dl, MVT::v2i64);
      } else {
        SB = DAG.getConstant(0x0000000080000000ULL, dl, MVT::v2i64);
      }
      Op0 = DAG.getNode(ISD::XOR, dl, MVT::v2i64, Op0, SB);
      Op1 = DAG.getNode(ISD::XOR, dl, MVT::v2i64, Op1, SB);

      // Cast everything to the right type.
      Op0 = DAG.getBitcast(MVT::v4i32, Op0);
      Op1 = DAG.getBitcast(MVT::v4i32, Op1);

      // Emulate PCMPGTQ with (hi1 > hi2) | ((hi1 == hi2) & (lo1 > lo2))
      SDValue GT = DAG.getNode(X86ISD::PCMPGT, dl, MVT::v4i32, Op0, Op1);
      SDValue EQ = DAG.getNode(X86ISD::PCMPEQ, dl, MVT::v4i32, Op0, Op1);

      // Create masks for only the low parts/high parts of the 64 bit integers.
      static const int MaskHi[] = { 1, 1, 3, 3 };
      static const int MaskLo[] = { 0, 0, 2, 2 };
      SDValue EQHi = DAG.getVectorShuffle(MVT::v4i32, dl, EQ, EQ, MaskHi);
      SDValue GTLo = DAG.getVectorShuffle(MVT::v4i32, dl, GT, GT, MaskLo);
      SDValue GTHi = DAG.getVectorShuffle(MVT::v4i32, dl, GT, GT, MaskHi);

      SDValue Result = DAG.getNode(ISD::AND, dl, MVT::v4i32, EQHi, GTLo);
      Result = DAG.getNode(ISD::OR, dl, MVT::v4i32, Result, GTHi);

      if (Invert)
        Result = DAG.getNOT(dl, Result, MVT::v4i32);

      return DAG.getBitcast(VT, Result);
    }

    if (Opc == X86ISD::PCMPEQ && !Subtarget.hasSSE41()) {
      // If pcmpeqq is missing but pcmpeqd is available synthesize pcmpeqq with
      // pcmpeqd + pshufd + pand.
      assert(Subtarget.hasSSE2() && !FlipSigns && "Don't know how to lower!");

      // First cast everything to the right type.
      Op0 = DAG.getBitcast(MVT::v4i32, Op0);
      Op1 = DAG.getBitcast(MVT::v4i32, Op1);

      // Do the compare.
      SDValue Result = DAG.getNode(Opc, dl, MVT::v4i32, Op0, Op1);

      // Make sure the lower and upper halves are both all-ones.
      static const int Mask[] = { 1, 0, 3, 2 };
      SDValue Shuf = DAG.getVectorShuffle(MVT::v4i32, dl, Result, Result, Mask);
      Result = DAG.getNode(ISD::AND, dl, MVT::v4i32, Result, Shuf);

      if (Invert)
        Result = DAG.getNOT(dl, Result, MVT::v4i32);

      return DAG.getBitcast(VT, Result);
    }
  }

  // Since SSE has no unsigned integer comparisons, we need to flip the sign
  // bits of the inputs before performing those operations.
  if (FlipSigns) {
    MVT EltVT = VT.getVectorElementType();
    SDValue SM = DAG.getConstant(APInt::getSignMask(EltVT.getSizeInBits()), dl,
                                 VT);
    Op0 = DAG.getNode(ISD::XOR, dl, VT, Op0, SM);
    Op1 = DAG.getNode(ISD::XOR, dl, VT, Op1, SM);
  }

  SDValue Result = DAG.getNode(Opc, dl, VT, Op0, Op1);

  // If the logical-not of the result is required, perform that now.
  if (Invert)
    Result = DAG.getNOT(dl, Result, VT);

  return Result;
}

// Try to select this as a KORTEST+SETCC or KTEST+SETCC if possible.
static SDValue EmitAVX512Test(SDValue Op0, SDValue Op1, ISD::CondCode CC,
                              const SDLoc &dl, SelectionDAG &DAG,
                              const X86Subtarget &Subtarget,
                              SDValue &X86CC) {
  // Only support equality comparisons.
  if (CC != ISD::SETEQ && CC != ISD::SETNE)
    return SDValue();

  // Must be a bitcast from vXi1.
  if (Op0.getOpcode() != ISD::BITCAST)
    return SDValue();

  Op0 = Op0.getOperand(0);
  MVT VT = Op0.getSimpleValueType();
  if (!(Subtarget.hasAVX512() && VT == MVT::v16i1) &&
      !(Subtarget.hasDQI() && VT == MVT::v8i1) &&
      !(Subtarget.hasBWI() && (VT == MVT::v32i1 || VT == MVT::v64i1)))
    return SDValue();

  X86::CondCode X86Cond;
  if (isNullConstant(Op1)) {
    X86Cond = CC == ISD::SETEQ ? X86::COND_E : X86::COND_NE;
  } else if (isAllOnesConstant(Op1)) {
    // C flag is set for all ones.
    X86Cond = CC == ISD::SETEQ ? X86::COND_B : X86::COND_AE;
  } else
    return SDValue();

  // If the input is an AND, we can combine it's operands into the KTEST.
  bool KTestable = false;
  if (Subtarget.hasDQI() && (VT == MVT::v8i1 || VT == MVT::v16i1))
    KTestable = true;
  if (Subtarget.hasBWI() && (VT == MVT::v32i1 || VT == MVT::v64i1))
    KTestable = true;
  if (!isNullConstant(Op1))
    KTestable = false;
  if (KTestable && Op0.getOpcode() == ISD::AND && Op0.hasOneUse()) {
    SDValue LHS = Op0.getOperand(0);
    SDValue RHS = Op0.getOperand(1);
    X86CC = DAG.getTargetConstant(X86Cond, dl, MVT::i8);
    return DAG.getNode(X86ISD::KTEST, dl, MVT::i32, LHS, RHS);
  }

  // If the input is an OR, we can combine it's operands into the KORTEST.
  SDValue LHS = Op0;
  SDValue RHS = Op0;
  if (Op0.getOpcode() == ISD::OR && Op0.hasOneUse()) {
    LHS = Op0.getOperand(0);
    RHS = Op0.getOperand(1);
  }

  X86CC = DAG.getTargetConstant(X86Cond, dl, MVT::i8);
  return DAG.getNode(X86ISD::KORTEST, dl, MVT::i32, LHS, RHS);
}

/// Emit flags for the given setcc condition and operands. Also returns the
/// corresponding X86 condition code constant in X86CC.
SDValue X86TargetLowering::emitFlagsForSetcc(SDValue Op0, SDValue Op1,
                                             ISD::CondCode CC, const SDLoc &dl,
                                             SelectionDAG &DAG,
                                             SDValue &X86CC) const {
  // Optimize to BT if possible.
  // Lower (X & (1 << N)) == 0 to BT(X, N).
  // Lower ((X >>u N) & 1) != 0 to BT(X, N).
  // Lower ((X >>s N) & 1) != 0 to BT(X, N).
  if (Op0.getOpcode() == ISD::AND && Op0.hasOneUse() && isNullConstant(Op1) &&
      (CC == ISD::SETEQ || CC == ISD::SETNE)) {
    if (SDValue BT = LowerAndToBT(Op0, CC, dl, DAG, X86CC))
      return BT;
  }

  // Try to use PTEST for a tree ORs equality compared with 0.
  // TODO: We could do AND tree with all 1s as well by using the C flag.
  if (Op0.getOpcode() == ISD::OR && isNullConstant(Op1) &&
      (CC == ISD::SETEQ || CC == ISD::SETNE)) {
    if (SDValue PTEST = LowerVectorAllZeroTest(Op0, CC, Subtarget, DAG, X86CC))
      return PTEST;
  }

  // Try to lower using KORTEST or KTEST.
  if (SDValue Test = EmitAVX512Test(Op0, Op1, CC, dl, DAG, Subtarget, X86CC))
    return Test;

  // Look for X == 0, X == 1, X != 0, or X != 1.  We can simplify some forms of
  // these.
  if ((isOneConstant(Op1) || isNullConstant(Op1)) &&
      (CC == ISD::SETEQ || CC == ISD::SETNE)) {
    // If the input is a setcc, then reuse the input setcc or use a new one with
    // the inverted condition.
    if (Op0.getOpcode() == X86ISD::SETCC) {
      bool Invert = (CC == ISD::SETNE) ^ isNullConstant(Op1);

      X86CC = Op0.getOperand(0);
      if (Invert) {
        X86::CondCode CCode = (X86::CondCode)Op0.getConstantOperandVal(0);
        CCode = X86::GetOppositeBranchCondition(CCode);
        X86CC = DAG.getTargetConstant(CCode, dl, MVT::i8);
      }

      return Op0.getOperand(1);
    }
  }

  // Try to use the carry flag from the add in place of an separate CMP for:
  // (seteq (add X, -1), -1). Similar for setne.
  if (isAllOnesConstant(Op1) && Op0.getOpcode() == ISD::ADD &&
      Op0.getOperand(1) == Op1 && (CC == ISD::SETEQ || CC == ISD::SETNE)) {
    if (isProfitableToUseFlagOp(Op0)) {
      SDVTList VTs = DAG.getVTList(Op0.getValueType(), MVT::i32);

      SDValue New = DAG.getNode(X86ISD::ADD, dl, VTs, Op0.getOperand(0),
                                Op0.getOperand(1));
      DAG.ReplaceAllUsesOfValueWith(SDValue(Op0.getNode(), 0), New);
      X86::CondCode CCode = CC == ISD::SETEQ ? X86::COND_AE : X86::COND_B;
      X86CC = DAG.getTargetConstant(CCode, dl, MVT::i8);
      return SDValue(New.getNode(), 1);
    }
  }

  X86::CondCode CondCode =
      TranslateX86CC(CC, dl, /*IsFP*/ false, Op0, Op1, DAG);
  assert(CondCode != X86::COND_INVALID && "Unexpected condition code!");

  SDValue EFLAGS = EmitCmp(Op0, Op1, CondCode, dl, DAG, Subtarget);
  X86CC = DAG.getTargetConstant(CondCode, dl, MVT::i8);
  return EFLAGS;
}

SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {

  bool IsStrict = Op.getOpcode() == ISD::STRICT_FSETCC ||
                  Op.getOpcode() == ISD::STRICT_FSETCCS;
  MVT VT = Op->getSimpleValueType(0);

  if (VT.isVector()) return LowerVSETCC(Op, Subtarget, DAG);

  assert(VT == MVT::i8 && "SetCC type must be 8-bit integer");
  SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
  SDValue Op0 = Op.getOperand(IsStrict ? 1 : 0);
  SDValue Op1 = Op.getOperand(IsStrict ? 2 : 1);
  SDLoc dl(Op);
  ISD::CondCode CC =
      cast<CondCodeSDNode>(Op.getOperand(IsStrict ? 3 : 2))->get();

  // Handle f128 first, since one possible outcome is a normal integer
  // comparison which gets handled by emitFlagsForSetcc.
  if (Op0.getValueType() == MVT::f128) {
    softenSetCCOperands(DAG, MVT::f128, Op0, Op1, CC, dl, Op0, Op1, Chain,
                        Op.getOpcode() == ISD::STRICT_FSETCCS);

    // If softenSetCCOperands returned a scalar, use it.
    if (!Op1.getNode()) {
      assert(Op0.getValueType() == Op.getValueType() &&
             "Unexpected setcc expansion!");
      if (IsStrict)
        return DAG.getMergeValues({Op0, Chain}, dl);
      return Op0;
    }
  }

  if (Op0.getSimpleValueType().isInteger()) {
    SDValue X86CC;
    SDValue EFLAGS = emitFlagsForSetcc(Op0, Op1, CC, dl, DAG, X86CC);
    SDValue Res = DAG.getNode(X86ISD::SETCC, dl, MVT::i8, X86CC, EFLAGS);
    return IsStrict ? DAG.getMergeValues({Res, Chain}, dl) : Res;
  }

  // Handle floating point.
  X86::CondCode CondCode = TranslateX86CC(CC, dl, /*IsFP*/ true, Op0, Op1, DAG);
  if (CondCode == X86::COND_INVALID)
    return SDValue();

  SDValue EFLAGS;
  if (IsStrict) {
    bool IsSignaling = Op.getOpcode() == ISD::STRICT_FSETCCS;
    EFLAGS =
        DAG.getNode(IsSignaling ? X86ISD::STRICT_FCMPS : X86ISD::STRICT_FCMP,
                    dl, {MVT::i32, MVT::Other}, {Chain, Op0, Op1});
    Chain = EFLAGS.getValue(1);
  } else {
    EFLAGS = DAG.getNode(X86ISD::FCMP, dl, MVT::i32, Op0, Op1);
  }

  SDValue X86CC = DAG.getTargetConstant(CondCode, dl, MVT::i8);
  SDValue Res = DAG.getNode(X86ISD::SETCC, dl, MVT::i8, X86CC, EFLAGS);
  return IsStrict ? DAG.getMergeValues({Res, Chain}, dl) : Res;
}

SDValue X86TargetLowering::LowerSETCCCARRY(SDValue Op, SelectionDAG &DAG) const {
  SDValue LHS = Op.getOperand(0);
  SDValue RHS = Op.getOperand(1);
  SDValue Carry = Op.getOperand(2);
  SDValue Cond = Op.getOperand(3);
  SDLoc DL(Op);

  assert(LHS.getSimpleValueType().isInteger() && "SETCCCARRY is integer only.");
  X86::CondCode CC = TranslateIntegerX86CC(cast<CondCodeSDNode>(Cond)->get());

  // Recreate the carry if needed.
  EVT CarryVT = Carry.getValueType();
  Carry = DAG.getNode(X86ISD::ADD, DL, DAG.getVTList(CarryVT, MVT::i32),
                      Carry, DAG.getAllOnesConstant(DL, CarryVT));

  SDVTList VTs = DAG.getVTList(LHS.getValueType(), MVT::i32);
  SDValue Cmp = DAG.getNode(X86ISD::SBB, DL, VTs, LHS, RHS, Carry.getValue(1));
  return getSETCC(CC, Cmp.getValue(1), DL, DAG);
}

// This function returns three things: the arithmetic computation itself
// (Value), an EFLAGS result (Overflow), and a condition code (Cond).  The
// flag and the condition code define the case in which the arithmetic
// computation overflows.
static std::pair<SDValue, SDValue>
getX86XALUOOp(X86::CondCode &Cond, SDValue Op, SelectionDAG &DAG) {
  assert(Op.getResNo() == 0 && "Unexpected result number!");
  SDValue Value, Overflow;
  SDValue LHS = Op.getOperand(0);
  SDValue RHS = Op.getOperand(1);
  unsigned BaseOp = 0;
  SDLoc DL(Op);
  switch (Op.getOpcode()) {
  default: llvm_unreachable("Unknown ovf instruction!");
  case ISD::SADDO:
    BaseOp = X86ISD::ADD;
    Cond = X86::COND_O;
    break;
  case ISD::UADDO:
    BaseOp = X86ISD::ADD;
    Cond = isOneConstant(RHS) ? X86::COND_E : X86::COND_B;
    break;
  case ISD::SSUBO:
    BaseOp = X86ISD::SUB;
    Cond = X86::COND_O;
    break;
  case ISD::USUBO:
    BaseOp = X86ISD::SUB;
    Cond = X86::COND_B;
    break;
  case ISD::SMULO:
    BaseOp = X86ISD::SMUL;
    Cond = X86::COND_O;
    break;
  case ISD::UMULO:
    BaseOp = X86ISD::UMUL;
    Cond = X86::COND_O;
    break;
  }

  if (BaseOp) {
    // Also sets EFLAGS.
    SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::i32);
    Value = DAG.getNode(BaseOp, DL, VTs, LHS, RHS);
    Overflow = Value.getValue(1);
  }

  return std::make_pair(Value, Overflow);
}

static SDValue LowerXALUO(SDValue Op, SelectionDAG &DAG) {
  // Lower the "add/sub/mul with overflow" instruction into a regular ins plus
  // a "setcc" instruction that checks the overflow flag. The "brcond" lowering
  // looks for this combo and may remove the "setcc" instruction if the "setcc"
  // has only one use.
  SDLoc DL(Op);
  X86::CondCode Cond;
  SDValue Value, Overflow;
  std::tie(Value, Overflow) = getX86XALUOOp(Cond, Op, DAG);

  SDValue SetCC = getSETCC(Cond, Overflow, DL, DAG);
  assert(Op->getValueType(1) == MVT::i8 && "Unexpected VT!");
  return DAG.getNode(ISD::MERGE_VALUES, DL, Op->getVTList(), Value, SetCC);
}

/// Return true if opcode is a X86 logical comparison.
static bool isX86LogicalCmp(SDValue Op) {
  unsigned Opc = Op.getOpcode();
  if (Opc == X86ISD::CMP || Opc == X86ISD::COMI || Opc == X86ISD::UCOMI ||
      Opc == X86ISD::FCMP)
    return true;
  if (Op.getResNo() == 1 &&
      (Opc == X86ISD::ADD || Opc == X86ISD::SUB || Opc == X86ISD::ADC ||
       Opc == X86ISD::SBB || Opc == X86ISD::SMUL || Opc == X86ISD::UMUL ||
       Opc == X86ISD::OR || Opc == X86ISD::XOR || Opc == X86ISD::AND))
    return true;

  return false;
}

static bool isTruncWithZeroHighBitsInput(SDValue V, SelectionDAG &DAG) {
  if (V.getOpcode() != ISD::TRUNCATE)
    return false;

  SDValue VOp0 = V.getOperand(0);
  unsigned InBits = VOp0.getValueSizeInBits();
  unsigned Bits = V.getValueSizeInBits();
  return DAG.MaskedValueIsZero(VOp0, APInt::getHighBitsSet(InBits,InBits-Bits));
}

SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
  bool AddTest = true;
  SDValue Cond  = Op.getOperand(0);
  SDValue Op1 = Op.getOperand(1);
  SDValue Op2 = Op.getOperand(2);
  SDLoc DL(Op);
  MVT VT = Op1.getSimpleValueType();
  SDValue CC;

  // Lower FP selects into a CMP/AND/ANDN/OR sequence when the necessary SSE ops
  // are available or VBLENDV if AVX is available.
  // Otherwise FP cmovs get lowered into a less efficient branch sequence later.
  if (Cond.getOpcode() == ISD::SETCC && isScalarFPTypeInSSEReg(VT) &&
      VT == Cond.getOperand(0).getSimpleValueType() && Cond->hasOneUse()) {
    SDValue CondOp0 = Cond.getOperand(0), CondOp1 = Cond.getOperand(1);
    bool IsAlwaysSignaling;
    unsigned SSECC =
        translateX86FSETCC(cast<CondCodeSDNode>(Cond.getOperand(2))->get(),
                           CondOp0, CondOp1, IsAlwaysSignaling);

    if (Subtarget.hasAVX512()) {
      SDValue Cmp =
          DAG.getNode(X86ISD::FSETCCM, DL, MVT::v1i1, CondOp0, CondOp1,
                      DAG.getTargetConstant(SSECC, DL, MVT::i8));
      assert(!VT.isVector() && "Not a scalar type?");
      return DAG.getNode(X86ISD::SELECTS, DL, VT, Cmp, Op1, Op2);
    }

    if (SSECC < 8 || Subtarget.hasAVX()) {
      SDValue Cmp = DAG.getNode(X86ISD::FSETCC, DL, VT, CondOp0, CondOp1,
                                DAG.getTargetConstant(SSECC, DL, MVT::i8));

      // If we have AVX, we can use a variable vector select (VBLENDV) instead
      // of 3 logic instructions for size savings and potentially speed.
      // Unfortunately, there is no scalar form of VBLENDV.

      // If either operand is a +0.0 constant, don't try this. We can expect to
      // optimize away at least one of the logic instructions later in that
      // case, so that sequence would be faster than a variable blend.

      // BLENDV was introduced with SSE 4.1, but the 2 register form implicitly
      // uses XMM0 as the selection register. That may need just as many
      // instructions as the AND/ANDN/OR sequence due to register moves, so
      // don't bother.
      if (Subtarget.hasAVX() && !isNullFPConstant(Op1) &&
          !isNullFPConstant(Op2)) {
        // Convert to vectors, do a VSELECT, and convert back to scalar.
        // All of the conversions should be optimized away.
        MVT VecVT = VT == MVT::f32 ? MVT::v4f32 : MVT::v2f64;
        SDValue VOp1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VecVT, Op1);
        SDValue VOp2 = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VecVT, Op2);
        SDValue VCmp = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VecVT, Cmp);

        MVT VCmpVT = VT == MVT::f32 ? MVT::v4i32 : MVT::v2i64;
        VCmp = DAG.getBitcast(VCmpVT, VCmp);

        SDValue VSel = DAG.getSelect(DL, VecVT, VCmp, VOp1, VOp2);

        return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT,
                           VSel, DAG.getIntPtrConstant(0, DL));
      }
      SDValue AndN = DAG.getNode(X86ISD::FANDN, DL, VT, Cmp, Op2);
      SDValue And = DAG.getNode(X86ISD::FAND, DL, VT, Cmp, Op1);
      return DAG.getNode(X86ISD::FOR, DL, VT, AndN, And);
    }
  }

  // AVX512 fallback is to lower selects of scalar floats to masked moves.
  if (isScalarFPTypeInSSEReg(VT) && Subtarget.hasAVX512()) {
    SDValue Cmp = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v1i1, Cond);
    return DAG.getNode(X86ISD::SELECTS, DL, VT, Cmp, Op1, Op2);
  }

  if (Cond.getOpcode() == ISD::SETCC) {
    if (SDValue NewCond = LowerSETCC(Cond, DAG)) {
      Cond = NewCond;
      // If the condition was updated, it's possible that the operands of the
      // select were also updated (for example, EmitTest has a RAUW). Refresh
      // the local references to the select operands in case they got stale.
      Op1 = Op.getOperand(1);
      Op2 = Op.getOperand(2);
    }
  }

  // (select (x == 0), -1, y) -> (sign_bit (x - 1)) | y
  // (select (x == 0), y, -1) -> ~(sign_bit (x - 1)) | y
  // (select (x != 0), y, -1) -> (sign_bit (x - 1)) | y
  // (select (x != 0), -1, y) -> ~(sign_bit (x - 1)) | y
  // (select (and (x , 0x1) == 0), y, (z ^ y) ) -> (-(and (x , 0x1)) & z ) ^ y
  // (select (and (x , 0x1) == 0), y, (z | y) ) -> (-(and (x , 0x1)) & z ) | y
  if (Cond.getOpcode() == X86ISD::SETCC &&
      Cond.getOperand(1).getOpcode() == X86ISD::CMP &&
      isNullConstant(Cond.getOperand(1).getOperand(1))) {
    SDValue Cmp = Cond.getOperand(1);
    unsigned CondCode = Cond.getConstantOperandVal(0);

    if ((isAllOnesConstant(Op1) || isAllOnesConstant(Op2)) &&
        (CondCode == X86::COND_E || CondCode == X86::COND_NE)) {
      SDValue Y = isAllOnesConstant(Op2) ? Op1 : Op2;
      SDValue CmpOp0 = Cmp.getOperand(0);

      SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::i32);
      SDVTList CmpVTs = DAG.getVTList(CmpOp0.getValueType(), MVT::i32);

      // Apply further optimizations for special cases
      // (select (x != 0), -1, 0) -> neg & sbb
      // (select (x == 0), 0, -1) -> neg & sbb
      if (isNullConstant(Y) &&
          (isAllOnesConstant(Op1) == (CondCode == X86::COND_NE))) {
        SDValue Zero = DAG.getConstant(0, DL, CmpOp0.getValueType());
        SDValue Neg = DAG.getNode(X86ISD::SUB, DL, CmpVTs, Zero, CmpOp0);
        Zero = DAG.getConstant(0, DL, Op.getValueType());
        return DAG.getNode(X86ISD::SBB, DL, VTs, Zero, Zero, Neg.getValue(1));
      }

      Cmp = DAG.getNode(X86ISD::SUB, DL, CmpVTs,
                        CmpOp0, DAG.getConstant(1, DL, CmpOp0.getValueType()));

      SDValue Zero = DAG.getConstant(0, DL, Op.getValueType());
      SDValue Res =   // Res = 0 or -1.
        DAG.getNode(X86ISD::SBB, DL, VTs, Zero, Zero, Cmp.getValue(1));

      if (isAllOnesConstant(Op1) != (CondCode == X86::COND_E))
        Res = DAG.getNOT(DL, Res, Res.getValueType());

      return DAG.getNode(ISD::OR, DL, Res.getValueType(), Res, Y);
    } else if (!Subtarget.hasCMov() && CondCode == X86::COND_E &&
               Cmp.getOperand(0).getOpcode() == ISD::AND &&
               isOneConstant(Cmp.getOperand(0).getOperand(1))) {
      SDValue CmpOp0 = Cmp.getOperand(0);
      SDValue Src1, Src2;
      // true if Op2 is XOR or OR operator and one of its operands
      // is equal to Op1
      // ( a , a op b) || ( b , a op b)
      auto isOrXorPattern = [&]() {
        if ((Op2.getOpcode() == ISD::XOR || Op2.getOpcode() == ISD::OR) &&
            (Op2.getOperand(0) == Op1 || Op2.getOperand(1) == Op1)) {
          Src1 =
              Op2.getOperand(0) == Op1 ? Op2.getOperand(1) : Op2.getOperand(0);
          Src2 = Op1;
          return true;
        }
        return false;
      };

      if (isOrXorPattern()) {
        SDValue Neg;
        unsigned int CmpSz = CmpOp0.getSimpleValueType().getSizeInBits();
        // we need mask of all zeros or ones with same size of the other
        // operands.
        if (CmpSz > VT.getSizeInBits())
          Neg = DAG.getNode(ISD::TRUNCATE, DL, VT, CmpOp0);
        else if (CmpSz < VT.getSizeInBits())
          Neg = DAG.getNode(ISD::AND, DL, VT,
              DAG.getNode(ISD::ANY_EXTEND, DL, VT, CmpOp0.getOperand(0)),
              DAG.getConstant(1, DL, VT));
        else
          Neg = CmpOp0;
        SDValue Mask = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT),
                                   Neg); // -(and (x, 0x1))
        SDValue And = DAG.getNode(ISD::AND, DL, VT, Mask, Src1); // Mask & z
        return DAG.getNode(Op2.getOpcode(), DL, VT, And, Src2);  // And Op y
      }
    }
  }

  // Look past (and (setcc_carry (cmp ...)), 1).
  if (Cond.getOpcode() == ISD::AND &&
      Cond.getOperand(0).getOpcode() == X86ISD::SETCC_CARRY &&
      isOneConstant(Cond.getOperand(1)))
    Cond = Cond.getOperand(0);

  // If condition flag is set by a X86ISD::CMP, then use it as the condition
  // setting operand in place of the X86ISD::SETCC.
  unsigned CondOpcode = Cond.getOpcode();
  if (CondOpcode == X86ISD::SETCC ||
      CondOpcode == X86ISD::SETCC_CARRY) {
    CC = Cond.getOperand(0);

    SDValue Cmp = Cond.getOperand(1);
    bool IllegalFPCMov = false;
    if (VT.isFloatingPoint() && !VT.isVector() &&
        !isScalarFPTypeInSSEReg(VT) && Subtarget.hasCMov())  // FPStack?
      IllegalFPCMov = !hasFPCMov(cast<ConstantSDNode>(CC)->getSExtValue());

    if ((isX86LogicalCmp(Cmp) && !IllegalFPCMov) ||
        Cmp.getOpcode() == X86ISD::BT) { // FIXME
      Cond = Cmp;
      AddTest = false;
    }
  } else if (CondOpcode == ISD::USUBO || CondOpcode == ISD::SSUBO ||
             CondOpcode == ISD::UADDO || CondOpcode == ISD::SADDO ||
             CondOpcode == ISD::UMULO || CondOpcode == ISD::SMULO) {
    SDValue Value;
    X86::CondCode X86Cond;
    std::tie(Value, Cond) = getX86XALUOOp(X86Cond, Cond.getValue(0), DAG);

    CC = DAG.getTargetConstant(X86Cond, DL, MVT::i8);
    AddTest = false;
  }

  if (AddTest) {
    // Look past the truncate if the high bits are known zero.
    if (isTruncWithZeroHighBitsInput(Cond, DAG))
      Cond = Cond.getOperand(0);

    // We know the result of AND is compared against zero. Try to match
    // it to BT.
    if (Cond.getOpcode() == ISD::AND && Cond.hasOneUse()) {
      SDValue BTCC;
      if (SDValue BT = LowerAndToBT(Cond, ISD::SETNE, DL, DAG, BTCC)) {
        CC = BTCC;
        Cond = BT;
        AddTest = false;
      }
    }
  }

  if (AddTest) {
    CC = DAG.getTargetConstant(X86::COND_NE, DL, MVT::i8);
    Cond = EmitTest(Cond, X86::COND_NE, DL, DAG, Subtarget);
  }

  // a <  b ? -1 :  0 -> RES = ~setcc_carry
  // a <  b ?  0 : -1 -> RES = setcc_carry
  // a >= b ? -1 :  0 -> RES = setcc_carry
  // a >= b ?  0 : -1 -> RES = ~setcc_carry
  if (Cond.getOpcode() == X86ISD::SUB) {
    unsigned CondCode = cast<ConstantSDNode>(CC)->getZExtValue();

    if ((CondCode == X86::COND_AE || CondCode == X86::COND_B) &&
        (isAllOnesConstant(Op1) || isAllOnesConstant(Op2)) &&
        (isNullConstant(Op1) || isNullConstant(Op2))) {
      SDValue Res =
          DAG.getNode(X86ISD::SETCC_CARRY, DL, Op.getValueType(),
                      DAG.getTargetConstant(X86::COND_B, DL, MVT::i8), Cond);
      if (isAllOnesConstant(Op1) != (CondCode == X86::COND_B))
        return DAG.getNOT(DL, Res, Res.getValueType());
      return Res;
    }
  }

  // X86 doesn't have an i8 cmov. If both operands are the result of a truncate
  // widen the cmov and push the truncate through. This avoids introducing a new
  // branch during isel and doesn't add any extensions.
  if (Op.getValueType() == MVT::i8 &&
      Op1.getOpcode() == ISD::TRUNCATE && Op2.getOpcode() == ISD::TRUNCATE) {
    SDValue T1 = Op1.getOperand(0), T2 = Op2.getOperand(0);
    if (T1.getValueType() == T2.getValueType() &&
        // Blacklist CopyFromReg to avoid partial register stalls.
        T1.getOpcode() != ISD::CopyFromReg && T2.getOpcode()!=ISD::CopyFromReg){
      SDValue Cmov = DAG.getNode(X86ISD::CMOV, DL, T1.getValueType(), T2, T1,
                                 CC, Cond);
      return DAG.getNode(ISD::TRUNCATE, DL, Op.getValueType(), Cmov);
    }
  }

  // Or finally, promote i8 cmovs if we have CMOV,
  //                 or i16 cmovs if it won't prevent folding a load.
  // FIXME: we should not limit promotion of i8 case to only when the CMOV is
  //        legal, but EmitLoweredSelect() can not deal with these extensions
  //        being inserted between two CMOV's. (in i16 case too TBN)
  //        https://bugs.llvm.org/show_bug.cgi?id=40974
  if ((Op.getValueType() == MVT::i8 && Subtarget.hasCMov()) ||
      (Op.getValueType() == MVT::i16 && !MayFoldLoad(Op1) &&
       !MayFoldLoad(Op2))) {
    Op1 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i32, Op1);
    Op2 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i32, Op2);
    SDValue Ops[] = { Op2, Op1, CC, Cond };
    SDValue Cmov = DAG.getNode(X86ISD::CMOV, DL, MVT::i32, Ops);
    return DAG.getNode(ISD::TRUNCATE, DL, Op.getValueType(), Cmov);
  }

  // X86ISD::CMOV means set the result (which is operand 1) to the RHS if
  // condition is true.
  SDValue Ops[] = { Op2, Op1, CC, Cond };
  return DAG.getNode(X86ISD::CMOV, DL, Op.getValueType(), Ops);
}

static SDValue LowerSIGN_EXTEND_Mask(SDValue Op,
                                     const X86Subtarget &Subtarget,
                                     SelectionDAG &DAG) {
  MVT VT = Op->getSimpleValueType(0);
  SDValue In = Op->getOperand(0);
  MVT InVT = In.getSimpleValueType();
  assert(InVT.getVectorElementType() == MVT::i1 && "Unexpected input type!");
  MVT VTElt = VT.getVectorElementType();
  SDLoc dl(Op);

  unsigned NumElts = VT.getVectorNumElements();

  // Extend VT if the scalar type is i8/i16 and BWI is not supported.
  MVT ExtVT = VT;
  if (!Subtarget.hasBWI() && VTElt.getSizeInBits() <= 16) {
    // If v16i32 is to be avoided, we'll need to split and concatenate.
    if (NumElts == 16 && !Subtarget.canExtendTo512DQ())
      return SplitAndExtendv16i1(Op.getOpcode(), VT, In, dl, DAG);

    ExtVT = MVT::getVectorVT(MVT::i32, NumElts);
  }

  // Widen to 512-bits if VLX is not supported.
  MVT WideVT = ExtVT;
  if (!ExtVT.is512BitVector() && !Subtarget.hasVLX()) {
    NumElts *= 512 / ExtVT.getSizeInBits();
    InVT = MVT::getVectorVT(MVT::i1, NumElts);
    In = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, InVT, DAG.getUNDEF(InVT),
                     In, DAG.getIntPtrConstant(0, dl));
    WideVT = MVT::getVectorVT(ExtVT.getVectorElementType(), NumElts);
  }

  SDValue V;
  MVT WideEltVT = WideVT.getVectorElementType();
  if ((Subtarget.hasDQI() && WideEltVT.getSizeInBits() >= 32) ||
      (Subtarget.hasBWI() && WideEltVT.getSizeInBits() <= 16)) {
    V = DAG.getNode(Op.getOpcode(), dl, WideVT, In);
  } else {
    SDValue NegOne = DAG.getConstant(-1, dl, WideVT);
    SDValue Zero = DAG.getConstant(0, dl, WideVT);
    V = DAG.getSelect(dl, WideVT, In, NegOne, Zero);
  }

  // Truncate if we had to extend i16/i8 above.
  if (VT != ExtVT) {
    WideVT = MVT::getVectorVT(VTElt, NumElts);
    V = DAG.getNode(ISD::TRUNCATE, dl, WideVT, V);
  }

  // Extract back to 128/256-bit if we widened.
  if (WideVT != VT)
    V = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT, V,
                    DAG.getIntPtrConstant(0, dl));

  return V;
}

static SDValue LowerANY_EXTEND(SDValue Op, const X86Subtarget &Subtarget,
                               SelectionDAG &DAG) {
  SDValue In = Op->getOperand(0);
  MVT InVT = In.getSimpleValueType();

  if (InVT.getVectorElementType() == MVT::i1)
    return LowerSIGN_EXTEND_Mask(Op, Subtarget, DAG);

  assert(Subtarget.hasAVX() && "Expected AVX support");
  return LowerAVXExtend(Op, DAG, Subtarget);
}

// Lowering for SIGN_EXTEND_VECTOR_INREG and ZERO_EXTEND_VECTOR_INREG.
// For sign extend this needs to handle all vector sizes and SSE4.1 and
// non-SSE4.1 targets. For zero extend this should only handle inputs of
// MVT::v64i8 when BWI is not supported, but AVX512 is.
static SDValue LowerEXTEND_VECTOR_INREG(SDValue Op,
                                        const X86Subtarget &Subtarget,
                                        SelectionDAG &DAG) {
  SDValue In = Op->getOperand(0);
  MVT VT = Op->getSimpleValueType(0);
  MVT InVT = In.getSimpleValueType();

  MVT SVT = VT.getVectorElementType();
  MVT InSVT = InVT.getVectorElementType();
  assert(SVT.getSizeInBits() > InSVT.getSizeInBits());

  if (SVT != MVT::i64 && SVT != MVT::i32 && SVT != MVT::i16)
    return SDValue();
  if (InSVT != MVT::i32 && InSVT != MVT::i16 && InSVT != MVT::i8)
    return SDValue();
  if (!(VT.is128BitVector() && Subtarget.hasSSE2()) &&
      !(VT.is256BitVector() && Subtarget.hasAVX()) &&
      !(VT.is512BitVector() && Subtarget.hasAVX512()))
    return SDValue();

  SDLoc dl(Op);
  unsigned Opc = Op.getOpcode();
  unsigned NumElts = VT.getVectorNumElements();

  // For 256-bit vectors, we only need the lower (128-bit) half of the input.
  // For 512-bit vectors, we need 128-bits or 256-bits.
  if (InVT.getSizeInBits() > 128) {
    // Input needs to be at least the same number of elements as output, and
    // at least 128-bits.
    int InSize = InSVT.getSizeInBits() * NumElts;
    In = extractSubVector(In, 0, DAG, dl, std::max(InSize, 128));
    InVT = In.getSimpleValueType();
  }

  // SSE41 targets can use the pmov[sz]x* instructions directly for 128-bit results,
  // so are legal and shouldn't occur here. AVX2/AVX512 pmovsx* instructions still
  // need to be handled here for 256/512-bit results.
  if (Subtarget.hasInt256()) {
    assert(VT.getSizeInBits() > 128 && "Unexpected 128-bit vector extension");

    if (InVT.getVectorNumElements() != NumElts)
      return DAG.getNode(Op.getOpcode(), dl, VT, In);

    // FIXME: Apparently we create inreg operations that could be regular
    // extends.
    unsigned ExtOpc =
        Opc == ISD::SIGN_EXTEND_VECTOR_INREG ? ISD::SIGN_EXTEND
                                             : ISD::ZERO_EXTEND;
    return DAG.getNode(ExtOpc, dl, VT, In);
  }

  // pre-AVX2 256-bit extensions need to be split into 128-bit instructions.
  if (Subtarget.hasAVX()) {
    assert(VT.is256BitVector() && "256-bit vector expected");
    MVT HalfVT = VT.getHalfNumVectorElementsVT();
    int HalfNumElts = HalfVT.getVectorNumElements();

    unsigned NumSrcElts = InVT.getVectorNumElements();
    SmallVector<int, 16> HiMask(NumSrcElts, SM_SentinelUndef);
    for (int i = 0; i != HalfNumElts; ++i)
      HiMask[i] = HalfNumElts + i;

    SDValue Lo = DAG.getNode(Opc, dl, HalfVT, In);
    SDValue Hi = DAG.getVectorShuffle(InVT, dl, In, DAG.getUNDEF(InVT), HiMask);
    Hi = DAG.getNode(Opc, dl, HalfVT, Hi);
    return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, Lo, Hi);
  }

  // We should only get here for sign extend.
  assert(Opc == ISD::SIGN_EXTEND_VECTOR_INREG && "Unexpected opcode!");
  assert(VT.is128BitVector() && InVT.is128BitVector() && "Unexpected VTs");

  // pre-SSE41 targets unpack lower lanes and then sign-extend using SRAI.
  SDValue Curr = In;
  SDValue SignExt = Curr;

  // As SRAI is only available on i16/i32 types, we expand only up to i32
  // and handle i64 separately.
  if (InVT != MVT::v4i32) {
    MVT DestVT = VT == MVT::v2i64 ? MVT::v4i32 : VT;

    unsigned DestWidth = DestVT.getScalarSizeInBits();
    unsigned Scale = DestWidth / InSVT.getSizeInBits();

    unsigned InNumElts = InVT.getVectorNumElements();
    unsigned DestElts = DestVT.getVectorNumElements();

    // Build a shuffle mask that takes each input element and places it in the
    // MSBs of the new element size.
    SmallVector<int, 16> Mask(InNumElts, SM_SentinelUndef);
    for (unsigned i = 0; i != DestElts; ++i)
      Mask[i * Scale + (Scale - 1)] = i;

    Curr = DAG.getVectorShuffle(InVT, dl, In, In, Mask);
    Curr = DAG.getBitcast(DestVT, Curr);

    unsigned SignExtShift = DestWidth - InSVT.getSizeInBits();
    SignExt = DAG.getNode(X86ISD::VSRAI, dl, DestVT, Curr,
                          DAG.getTargetConstant(SignExtShift, dl, MVT::i8));
  }

  if (VT == MVT::v2i64) {
    assert(Curr.getValueType() == MVT::v4i32 && "Unexpected input VT");
    SDValue Zero = DAG.getConstant(0, dl, MVT::v4i32);
    SDValue Sign = DAG.getSetCC(dl, MVT::v4i32, Zero, Curr, ISD::SETGT);
    SignExt = DAG.getVectorShuffle(MVT::v4i32, dl, SignExt, Sign, {0, 4, 1, 5});
    SignExt = DAG.getBitcast(VT, SignExt);
  }

  return SignExt;
}

static SDValue LowerSIGN_EXTEND(SDValue Op, const X86Subtarget &Subtarget,
                                SelectionDAG &DAG) {
  MVT VT = Op->getSimpleValueType(0);
  SDValue In = Op->getOperand(0);
  MVT InVT = In.getSimpleValueType();
  SDLoc dl(Op);

  if (InVT.getVectorElementType() == MVT::i1)
    return LowerSIGN_EXTEND_Mask(Op, Subtarget, DAG);

  assert(VT.isVector() && InVT.isVector() && "Expected vector type");
  assert(VT.getVectorNumElements() == InVT.getVectorNumElements() &&
         "Expected same number of elements");
  assert((VT.getVectorElementType() == MVT::i16 ||
          VT.getVectorElementType() == MVT::i32 ||
          VT.getVectorElementType() == MVT::i64) &&
         "Unexpected element type");
  assert((InVT.getVectorElementType() == MVT::i8 ||
          InVT.getVectorElementType() == MVT::i16 ||
          InVT.getVectorElementType() == MVT::i32) &&
         "Unexpected element type");

  // Custom legalize v8i8->v8i64 on CPUs without avx512bw.
  if (InVT == MVT::v8i8) {
    if (VT != MVT::v8i64)
      return SDValue();

    In = DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(Op),
                     MVT::v16i8, In, DAG.getUNDEF(MVT::v8i8));
    return DAG.getNode(ISD::SIGN_EXTEND_VECTOR_INREG, dl, VT, In);
  }

  if (Subtarget.hasInt256())
    return Op;

  // Optimize vectors in AVX mode
  // Sign extend  v8i16 to v8i32 and
  //              v4i32 to v4i64
  //
  // Divide input vector into two parts
  // for v4i32 the high shuffle mask will be {2, 3, -1, -1}
  // use vpmovsx instruction to extend v4i32 -> v2i64; v8i16 -> v4i32
  // concat the vectors to original VT
  MVT HalfVT = VT.getHalfNumVectorElementsVT();
  SDValue OpLo = DAG.getNode(ISD::SIGN_EXTEND_VECTOR_INREG, dl, HalfVT, In);

  unsigned NumElems = InVT.getVectorNumElements();
  SmallVector<int,8> ShufMask(NumElems, -1);
  for (unsigned i = 0; i != NumElems/2; ++i)
    ShufMask[i] = i + NumElems/2;

  SDValue OpHi = DAG.getVectorShuffle(InVT, dl, In, In, ShufMask);
  OpHi = DAG.getNode(ISD::SIGN_EXTEND_VECTOR_INREG, dl, HalfVT, OpHi);

  return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, OpLo, OpHi);
}

/// Change a vector store into a pair of half-size vector stores.
static SDValue splitVectorStore(StoreSDNode *Store, SelectionDAG &DAG) {
  SDValue StoredVal = Store->getValue();
  assert((StoredVal.getValueType().is256BitVector() ||
          StoredVal.getValueType().is512BitVector()) &&
         "Expecting 256/512-bit op");

  // Splitting volatile memory ops is not allowed unless the operation was not
  // legal to begin with. Assume the input store is legal (this transform is
  // only used for targets with AVX). Note: It is possible that we have an
  // illegal type like v2i128, and so we could allow splitting a volatile store
  // in that case if that is important.
  if (!Store->isSimple())
    return SDValue();

  EVT StoreVT = StoredVal.getValueType();
  unsigned NumElems = StoreVT.getVectorNumElements();
  unsigned HalfSize = StoredVal.getValueSizeInBits() / 2;
  unsigned HalfAlign = (128 == HalfSize ? 16 : 32);

  SDLoc DL(Store);
  SDValue Value0 = extractSubVector(StoredVal, 0, DAG, DL, HalfSize);
  SDValue Value1 = extractSubVector(StoredVal, NumElems / 2, DAG, DL, HalfSize);
  SDValue Ptr0 = Store->getBasePtr();
  SDValue Ptr1 = DAG.getMemBasePlusOffset(Ptr0, HalfAlign, DL);
  unsigned Alignment = Store->getAlignment();
  SDValue Ch0 =
      DAG.getStore(Store->getChain(), DL, Value0, Ptr0, Store->getPointerInfo(),
                   Alignment, Store->getMemOperand()->getFlags());
  SDValue Ch1 = DAG.getStore(Store->getChain(), DL, Value1, Ptr1,
                             Store->getPointerInfo().getWithOffset(HalfAlign),
                             MinAlign(Alignment, HalfAlign),
                             Store->getMemOperand()->getFlags());
  return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Ch0, Ch1);
}

/// Scalarize a vector store, bitcasting to TargetVT to determine the scalar
/// type.
static SDValue scalarizeVectorStore(StoreSDNode *Store, MVT StoreVT,
                                    SelectionDAG &DAG) {
  SDValue StoredVal = Store->getValue();
  assert(StoreVT.is128BitVector() &&
         StoredVal.getValueType().is128BitVector() && "Expecting 128-bit op");
  StoredVal = DAG.getBitcast(StoreVT, StoredVal);

  // Splitting volatile memory ops is not allowed unless the operation was not
  // legal to begin with. We are assuming the input op is legal (this transform
  // is only used for targets with AVX).
  if (!Store->isSimple())
    return SDValue();

  MVT StoreSVT = StoreVT.getScalarType();
  unsigned NumElems = StoreVT.getVectorNumElements();
  unsigned ScalarSize = StoreSVT.getStoreSize();
  unsigned Alignment = Store->getAlignment();

  SDLoc DL(Store);
  SmallVector<SDValue, 4> Stores;
  for (unsigned i = 0; i != NumElems; ++i) {
    unsigned Offset = i * ScalarSize;
    SDValue Ptr = DAG.getMemBasePlusOffset(Store->getBasePtr(), Offset, DL);
    SDValue Scl = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, StoreSVT, StoredVal,
                              DAG.getIntPtrConstant(i, DL));
    SDValue Ch = DAG.getStore(Store->getChain(), DL, Scl, Ptr,
                              Store->getPointerInfo().getWithOffset(Offset),
                              MinAlign(Alignment, Offset),
                              Store->getMemOperand()->getFlags());
    Stores.push_back(Ch);
  }
  return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Stores);
}

static SDValue LowerStore(SDValue Op, const X86Subtarget &Subtarget,
                          SelectionDAG &DAG) {
  StoreSDNode *St = cast<StoreSDNode>(Op.getNode());
  SDLoc dl(St);
  SDValue StoredVal = St->getValue();

  // Without AVX512DQ, we need to use a scalar type for v2i1/v4i1/v8i1 stores.
  if (StoredVal.getValueType().isVector() &&
      StoredVal.getValueType().getVectorElementType() == MVT::i1) {
    assert(StoredVal.getValueType().getVectorNumElements() <= 8 &&
           "Unexpected VT");
    assert(!St->isTruncatingStore() && "Expected non-truncating store");
    assert(Subtarget.hasAVX512() && !Subtarget.hasDQI() &&
           "Expected AVX512F without AVX512DQI");

    StoredVal = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, MVT::v16i1,
                            DAG.getUNDEF(MVT::v16i1), StoredVal,
                            DAG.getIntPtrConstant(0, dl));
    StoredVal = DAG.getBitcast(MVT::i16, StoredVal);
    StoredVal = DAG.getNode(ISD::TRUNCATE, dl, MVT::i8, StoredVal);

    return DAG.getStore(St->getChain(), dl, StoredVal, St->getBasePtr(),
                        St->getPointerInfo(), St->getAlignment(),
                        St->getMemOperand()->getFlags());
  }

  if (St->isTruncatingStore())
    return SDValue();

  // If this is a 256-bit store of concatenated ops, we are better off splitting
  // that store into two 128-bit stores. This avoids spurious use of 256-bit ops
  // and each half can execute independently. Some cores would split the op into
  // halves anyway, so the concat (vinsertf128) is purely an extra op.
  MVT StoreVT = StoredVal.getSimpleValueType();
  if (StoreVT.is256BitVector()) {
    SmallVector<SDValue, 4> CatOps;
    if (StoredVal.hasOneUse() && collectConcatOps(StoredVal.getNode(), CatOps))
      return splitVectorStore(St, DAG);
    return SDValue();
  }

  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  assert(StoreVT.isVector() && StoreVT.getSizeInBits() == 64 &&
         "Unexpected VT");
  assert(TLI.getTypeAction(*DAG.getContext(), StoreVT) ==
             TargetLowering::TypeWidenVector && "Unexpected type action!");

  EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StoreVT);
  StoredVal = DAG.getNode(ISD::CONCAT_VECTORS, dl, WideVT, StoredVal,
                          DAG.getUNDEF(StoreVT));

  if (Subtarget.hasSSE2()) {
    // Widen the vector, cast to a v2x64 type, extract the single 64-bit element
    // and store it.
    MVT StVT = Subtarget.is64Bit() && StoreVT.isInteger() ? MVT::i64 : MVT::f64;
    MVT CastVT = MVT::getVectorVT(StVT, 2);
    StoredVal = DAG.getBitcast(CastVT, StoredVal);
    StoredVal = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, StVT, StoredVal,
                            DAG.getIntPtrConstant(0, dl));

    return DAG.getStore(St->getChain(), dl, StoredVal, St->getBasePtr(),
                        St->getPointerInfo(), St->getAlignment(),
                        St->getMemOperand()->getFlags());
  }
  assert(Subtarget.hasSSE1() && "Expected SSE");
  SDVTList Tys = DAG.getVTList(MVT::Other);
  SDValue Ops[] = {St->getChain(), StoredVal, St->getBasePtr()};
  return DAG.getMemIntrinsicNode(X86ISD::VEXTRACT_STORE, dl, Tys, Ops, MVT::i64,
                                 St->getMemOperand());
}

// Lower vector extended loads using a shuffle. If SSSE3 is not available we
// may emit an illegal shuffle but the expansion is still better than scalar
// code. We generate sext/sext_invec for SEXTLOADs if it's available, otherwise
// we'll emit a shuffle and a arithmetic shift.
// FIXME: Is the expansion actually better than scalar code? It doesn't seem so.
// TODO: It is possible to support ZExt by zeroing the undef values during
// the shuffle phase or after the shuffle.
static SDValue LowerLoad(SDValue Op, const X86Subtarget &Subtarget,
                                 SelectionDAG &DAG) {
  MVT RegVT = Op.getSimpleValueType();
  assert(RegVT.isVector() && "We only custom lower vector loads.");
  assert(RegVT.isInteger() &&
         "We only custom lower integer vector loads.");

  LoadSDNode *Ld = cast<LoadSDNode>(Op.getNode());
  SDLoc dl(Ld);

  // Without AVX512DQ, we need to use a scalar type for v2i1/v4i1/v8i1 loads.
  if (RegVT.getVectorElementType() == MVT::i1) {
    assert(EVT(RegVT) == Ld->getMemoryVT() && "Expected non-extending load");
    assert(RegVT.getVectorNumElements() <= 8 && "Unexpected VT");
    assert(Subtarget.hasAVX512() && !Subtarget.hasDQI() &&
           "Expected AVX512F without AVX512DQI");

    SDValue NewLd = DAG.getLoad(MVT::i8, dl, Ld->getChain(), Ld->getBasePtr(),
                                Ld->getPointerInfo(), Ld->getAlignment(),
                                Ld->getMemOperand()->getFlags());

    // Replace chain users with the new chain.
    assert(NewLd->getNumValues() == 2 && "Loads must carry a chain!");

    SDValue Val = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i16, NewLd);
    Val = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, RegVT,
                      DAG.getBitcast(MVT::v16i1, Val),
                      DAG.getIntPtrConstant(0, dl));
    return DAG.getMergeValues({Val, NewLd.getValue(1)}, dl);
  }

  return SDValue();
}

/// Return true if node is an ISD::AND or ISD::OR of two X86ISD::SETCC nodes
/// each of which has no other use apart from the AND / OR.
static bool isAndOrOfSetCCs(SDValue Op, unsigned &Opc) {
  Opc = Op.getOpcode();
  if (Opc != ISD::OR && Opc != ISD::AND)
    return false;
  return (Op.getOperand(0).getOpcode() == X86ISD::SETCC &&
          Op.getOperand(0).hasOneUse() &&
          Op.getOperand(1).getOpcode() == X86ISD::SETCC &&
          Op.getOperand(1).hasOneUse());
}

SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
  SDValue Chain = Op.getOperand(0);
  SDValue Cond  = Op.getOperand(1);
  SDValue Dest  = Op.getOperand(2);
  SDLoc dl(Op);

  if (Cond.getOpcode() == ISD::SETCC &&
      Cond.getOperand(0).getValueType() != MVT::f128) {
    SDValue LHS = Cond.getOperand(0);
    SDValue RHS = Cond.getOperand(1);
    ISD::CondCode CC = cast<CondCodeSDNode>(Cond.getOperand(2))->get();

    // Special case for
    // setcc([su]{add,sub,mul}o == 0)
    // setcc([su]{add,sub,mul}o != 1)
    if (ISD::isOverflowIntrOpRes(LHS) &&
        (CC == ISD::SETEQ || CC == ISD::SETNE) &&
        (isNullConstant(RHS) || isOneConstant(RHS))) {
      SDValue Value, Overflow;
      X86::CondCode X86Cond;
      std::tie(Value, Overflow) = getX86XALUOOp(X86Cond, LHS.getValue(0), DAG);

      if ((CC == ISD::SETEQ) == isNullConstant(RHS))
        X86Cond = X86::GetOppositeBranchCondition(X86Cond);

      SDValue CCVal = DAG.getTargetConstant(X86Cond, dl, MVT::i8);
      return DAG.getNode(X86ISD::BRCOND, dl, MVT::Other, Chain, Dest, CCVal,
                         Overflow);
    }

    if (LHS.getSimpleValueType().isInteger()) {
      SDValue CCVal;
      SDValue EFLAGS = emitFlagsForSetcc(LHS, RHS, CC, SDLoc(Cond), DAG, CCVal);
      return DAG.getNode(X86ISD::BRCOND, dl, MVT::Other, Chain, Dest, CCVal,
                         EFLAGS);
    }

    if (CC == ISD::SETOEQ) {
      // For FCMP_OEQ, we can emit
      // two branches instead of an explicit AND instruction with a
      // separate test. However, we only do this if this block doesn't
      // have a fall-through edge, because this requires an explicit
      // jmp when the condition is false.
      if (Op.getNode()->hasOneUse()) {
        SDNode *User = *Op.getNode()->use_begin();
        // Look for an unconditional branch following this conditional branch.
        // We need this because we need to reverse the successors in order
        // to implement FCMP_OEQ.
        if (User->getOpcode() == ISD::BR) {
          SDValue FalseBB = User->getOperand(1);
          SDNode *NewBR =
            DAG.UpdateNodeOperands(User, User->getOperand(0), Dest);
          assert(NewBR == User);
          (void)NewBR;
          Dest = FalseBB;

          SDValue Cmp =
              DAG.getNode(X86ISD::FCMP, SDLoc(Cond), MVT::i32, LHS, RHS);
          SDValue CCVal = DAG.getTargetConstant(X86::COND_NE, dl, MVT::i8);
          Chain = DAG.getNode(X86ISD::BRCOND, dl, MVT::Other, Chain, Dest,
                              CCVal, Cmp);
          CCVal = DAG.getTargetConstant(X86::COND_P, dl, MVT::i8);
          return DAG.getNode(X86ISD::BRCOND, dl, MVT::Other, Chain, Dest, CCVal,
                             Cmp);
        }
      }
    } else if (CC == ISD::SETUNE) {
      // For FCMP_UNE, we can emit
      // two branches instead of an explicit OR instruction with a
      // separate test.
      SDValue Cmp = DAG.getNode(X86ISD::FCMP, SDLoc(Cond), MVT::i32, LHS, RHS);
      SDValue CCVal = DAG.getTargetConstant(X86::COND_NE, dl, MVT::i8);
      Chain =
          DAG.getNode(X86ISD::BRCOND, dl, MVT::Other, Chain, Dest, CCVal, Cmp);
      CCVal = DAG.getTargetConstant(X86::COND_P, dl, MVT::i8);
      return DAG.getNode(X86ISD::BRCOND, dl, MVT::Other, Chain, Dest, CCVal,
                         Cmp);
    } else {
      X86::CondCode X86Cond =
          TranslateX86CC(CC, dl, /*IsFP*/ true, LHS, RHS, DAG);
      SDValue Cmp = DAG.getNode(X86ISD::FCMP, SDLoc(Cond), MVT::i32, LHS, RHS);
      SDValue CCVal = DAG.getTargetConstant(X86Cond, dl, MVT::i8);
      return DAG.getNode(X86ISD::BRCOND, dl, MVT::Other, Chain, Dest, CCVal,
                         Cmp);
    }
  }

  if (ISD::isOverflowIntrOpRes(Cond)) {
    SDValue Value, Overflow;
    X86::CondCode X86Cond;
    std::tie(Value, Overflow) = getX86XALUOOp(X86Cond, Cond.getValue(0), DAG);

    SDValue CCVal = DAG.getTargetConstant(X86Cond, dl, MVT::i8);
    return DAG.getNode(X86ISD::BRCOND, dl, MVT::Other, Chain, Dest, CCVal,
                       Overflow);
  }

  // Look past the truncate if the high bits are known zero.
  if (isTruncWithZeroHighBitsInput(Cond, DAG))
    Cond = Cond.getOperand(0);

  EVT CondVT = Cond.getValueType();

  // Add an AND with 1 if we don't already have one.
  if (!(Cond.getOpcode() == ISD::AND && isOneConstant(Cond.getOperand(1))))
    Cond =
        DAG.getNode(ISD::AND, dl, CondVT, Cond, DAG.getConstant(1, dl, CondVT));

  SDValue LHS = Cond;
  SDValue RHS = DAG.getConstant(0, dl, CondVT);

  SDValue CCVal;
  SDValue EFLAGS = emitFlagsForSetcc(LHS, RHS, ISD::SETNE, dl, DAG, CCVal);
  return DAG.getNode(X86ISD::BRCOND, dl, MVT::Other, Chain, Dest, CCVal,
                     EFLAGS);
}

// Lower dynamic stack allocation to _alloca call for Cygwin/Mingw targets.
// Calls to _alloca are needed to probe the stack when allocating more than 4k
// bytes in one go. Touching the stack at 4K increments is necessary to ensure
// that the guard pages used by the OS virtual memory manager are allocated in
// correct sequence.
SDValue
X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
                                           SelectionDAG &DAG) const {
  MachineFunction &MF = DAG.getMachineFunction();
  bool SplitStack = MF.shouldSplitStack();
  bool EmitStackProbeCall = hasStackProbeSymbol(MF);
  bool Lower = (Subtarget.isOSWindows() && !Subtarget.isTargetMachO()) ||
               SplitStack || EmitStackProbeCall;
  SDLoc dl(Op);

  // Get the inputs.
  SDNode *Node = Op.getNode();
  SDValue Chain = Op.getOperand(0);
  SDValue Size  = Op.getOperand(1);
  MaybeAlign Alignment(Op.getConstantOperandVal(2));
  EVT VT = Node->getValueType(0);

  // Chain the dynamic stack allocation so that it doesn't modify the stack
  // pointer when other instructions are using the stack.
  Chain = DAG.getCALLSEQ_START(Chain, 0, 0, dl);

  bool Is64Bit = Subtarget.is64Bit();
  MVT SPTy = getPointerTy(DAG.getDataLayout());

  SDValue Result;
  if (!Lower) {
    const TargetLowering &TLI = DAG.getTargetLoweringInfo();
    unsigned SPReg = TLI.getStackPointerRegisterToSaveRestore();
    assert(SPReg && "Target cannot require DYNAMIC_STACKALLOC expansion and"
                    " not tell us which reg is the stack pointer!");

    const TargetFrameLowering &TFI = *Subtarget.getFrameLowering();
    const Align StackAlign = TFI.getStackAlign();
    if (hasInlineStackProbe(MF)) {
      MachineRegisterInfo &MRI = MF.getRegInfo();

      const TargetRegisterClass *AddrRegClass = getRegClassFor(SPTy);
      Register Vreg = MRI.createVirtualRegister(AddrRegClass);
      Chain = DAG.getCopyToReg(Chain, dl, Vreg, Size);
      Result = DAG.getNode(X86ISD::PROBED_ALLOCA, dl, SPTy, Chain,
                           DAG.getRegister(Vreg, SPTy));
    } else {
      SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, VT);
      Chain = SP.getValue(1);
      Result = DAG.getNode(ISD::SUB, dl, VT, SP, Size); // Value
    }
    if (Alignment && Alignment > StackAlign)
      Result =
          DAG.getNode(ISD::AND, dl, VT, Result,
                      DAG.getConstant(~(Alignment->value() - 1ULL), dl, VT));
    Chain = DAG.getCopyToReg(Chain, dl, SPReg, Result); // Output chain
  } else if (SplitStack) {
    MachineRegisterInfo &MRI = MF.getRegInfo();

    if (Is64Bit) {
      // The 64 bit implementation of segmented stacks needs to clobber both r10
      // r11. This makes it impossible to use it along with nested parameters.
      const Function &F = MF.getFunction();
      for (const auto &A : F.args()) {
        if (A.hasNestAttr())
          report_fatal_error("Cannot use segmented stacks with functions that "
                             "have nested arguments.");
      }
    }

    const TargetRegisterClass *AddrRegClass = getRegClassFor(SPTy);
    Register Vreg = MRI.createVirtualRegister(AddrRegClass);
    Chain = DAG.getCopyToReg(Chain, dl, Vreg, Size);
    Result = DAG.getNode(X86ISD::SEG_ALLOCA, dl, SPTy, Chain,
                                DAG.getRegister(Vreg, SPTy));
  } else {
    SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
    Chain = DAG.getNode(X86ISD::WIN_ALLOCA, dl, NodeTys, Chain, Size);
    MF.getInfo<X86MachineFunctionInfo>()->setHasWinAlloca(true);

    const X86RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
    Register SPReg = RegInfo->getStackRegister();
    SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, SPTy);
    Chain = SP.getValue(1);

    if (Alignment) {
      SP = DAG.getNode(ISD::AND, dl, VT, SP.getValue(0),
                       DAG.getConstant(~(Alignment->value() - 1ULL), dl, VT));
      Chain = DAG.getCopyToReg(Chain, dl, SPReg, SP);
    }

    Result = SP;
  }

  Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(0, dl, true),
                             DAG.getIntPtrConstant(0, dl, true), SDValue(), dl);

  SDValue Ops[2] = {Result, Chain};
  return DAG.getMergeValues(Ops, dl);
}

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

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

  if (!Subtarget.is64Bit() ||
      Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv())) {
    // vastart just stores the address of the VarArgsFrameIndex slot into the
    // memory location argument.
    SDValue FR = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);
    return DAG.getStore(Op.getOperand(0), DL, FR, Op.getOperand(1),
                        MachinePointerInfo(SV));
  }

  // __va_list_tag:
  //   gp_offset         (0 - 6 * 8)
  //   fp_offset         (48 - 48 + 8 * 16)
  //   overflow_arg_area (point to parameters coming in memory).
  //   reg_save_area
  SmallVector<SDValue, 8> MemOps;
  SDValue FIN = Op.getOperand(1);
  // Store gp_offset
  SDValue Store = DAG.getStore(
      Op.getOperand(0), DL,
      DAG.getConstant(FuncInfo->getVarArgsGPOffset(), DL, MVT::i32), FIN,
      MachinePointerInfo(SV));
  MemOps.push_back(Store);

  // Store fp_offset
  FIN = DAG.getMemBasePlusOffset(FIN, 4, DL);
  Store = DAG.getStore(
      Op.getOperand(0), DL,
      DAG.getConstant(FuncInfo->getVarArgsFPOffset(), DL, MVT::i32), FIN,
      MachinePointerInfo(SV, 4));
  MemOps.push_back(Store);

  // Store ptr to overflow_arg_area
  FIN = DAG.getNode(ISD::ADD, DL, PtrVT, FIN, DAG.getIntPtrConstant(4, DL));
  SDValue OVFIN = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);
  Store =
      DAG.getStore(Op.getOperand(0), DL, OVFIN, FIN, MachinePointerInfo(SV, 8));
  MemOps.push_back(Store);

  // Store ptr to reg_save_area.
  FIN = DAG.getNode(ISD::ADD, DL, PtrVT, FIN, DAG.getIntPtrConstant(
      Subtarget.isTarget64BitLP64() ? 8 : 4, DL));
  SDValue RSFIN = DAG.getFrameIndex(FuncInfo->getRegSaveFrameIndex(), PtrVT);
  Store = DAG.getStore(
      Op.getOperand(0), DL, RSFIN, FIN,
      MachinePointerInfo(SV, Subtarget.isTarget64BitLP64() ? 16 : 12));
  MemOps.push_back(Store);
  return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOps);
}

SDValue X86TargetLowering::LowerVAARG(SDValue Op, SelectionDAG &DAG) const {
  assert(Subtarget.is64Bit() &&
         "LowerVAARG only handles 64-bit va_arg!");
  assert(Op.getNumOperands() == 4);

  MachineFunction &MF = DAG.getMachineFunction();
  if (Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv()))
    // The Win64 ABI uses char* instead of a structure.
    return DAG.expandVAArg(Op.getNode());

  SDValue Chain = Op.getOperand(0);
  SDValue SrcPtr = Op.getOperand(1);
  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
  unsigned Align = Op.getConstantOperandVal(3);
  SDLoc dl(Op);

  EVT ArgVT = Op.getNode()->getValueType(0);
  Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext());
  uint32_t ArgSize = DAG.getDataLayout().getTypeAllocSize(ArgTy);
  uint8_t ArgMode = 0;

  // Decide which area this value should be read from.
  // TODO: Implement the AMD64 ABI in its entirety. This simple
  // selection mechanism works only for the basic types.
  if (ArgVT == MVT::f80) {
    llvm_unreachable("va_arg for f80 not yet implemented");
  } else if (ArgVT.isFloatingPoint() && ArgSize <= 16 /*bytes*/) {
    ArgMode = 2;  // Argument passed in XMM register. Use fp_offset.
  } else if (ArgVT.isInteger() && ArgSize <= 32 /*bytes*/) {
    ArgMode = 1;  // Argument passed in GPR64 register(s). Use gp_offset.
  } else {
    llvm_unreachable("Unhandled argument type in LowerVAARG");
  }

  if (ArgMode == 2) {
    // Sanity Check: Make sure using fp_offset makes sense.
    assert(!Subtarget.useSoftFloat() &&
           !(MF.getFunction().hasFnAttribute(Attribute::NoImplicitFloat)) &&
           Subtarget.hasSSE1());
  }

  // Insert VAARG_64 node into the DAG
  // VAARG_64 returns two values: Variable Argument Address, Chain
  SDValue InstOps[] = {Chain, SrcPtr, DAG.getConstant(ArgSize, dl, MVT::i32),
                       DAG.getConstant(ArgMode, dl, MVT::i8),
                       DAG.getConstant(Align, dl, MVT::i32)};
  SDVTList VTs = DAG.getVTList(getPointerTy(DAG.getDataLayout()), MVT::Other);
  SDValue VAARG = DAG.getMemIntrinsicNode(
      X86ISD::VAARG_64, dl, VTs, InstOps, MVT::i64, MachinePointerInfo(SV),
      /*Align=*/None, MachineMemOperand::MOLoad | MachineMemOperand::MOStore);
  Chain = VAARG.getValue(1);

  // Load the next argument and return it
  return DAG.getLoad(ArgVT, dl, Chain, VAARG, MachinePointerInfo());
}

static SDValue LowerVACOPY(SDValue Op, const X86Subtarget &Subtarget,
                           SelectionDAG &DAG) {
  // X86-64 va_list is a struct { i32, i32, i8*, i8* }, except on Windows,
  // where a va_list is still an i8*.
  assert(Subtarget.is64Bit() && "This code only handles 64-bit va_copy!");
  if (Subtarget.isCallingConvWin64(
        DAG.getMachineFunction().getFunction().getCallingConv()))
    // Probably a Win64 va_copy.
    return DAG.expandVACopy(Op.getNode());

  SDValue Chain = Op.getOperand(0);
  SDValue DstPtr = Op.getOperand(1);
  SDValue SrcPtr = Op.getOperand(2);
  const Value *DstSV = cast<SrcValueSDNode>(Op.getOperand(3))->getValue();
  const Value *SrcSV = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
  SDLoc DL(Op);

  return DAG.getMemcpy(Chain, DL, DstPtr, SrcPtr, DAG.getIntPtrConstant(24, DL),
                       Align(8), /*isVolatile*/ false, false, false,
                       MachinePointerInfo(DstSV), MachinePointerInfo(SrcSV));
}

// Helper to get immediate/variable SSE shift opcode from other shift opcodes.
static unsigned getTargetVShiftUniformOpcode(unsigned Opc, bool IsVariable) {
  switch (Opc) {
  case ISD::SHL:
  case X86ISD::VSHL:
  case X86ISD::VSHLI:
    return IsVariable ? X86ISD::VSHL : X86ISD::VSHLI;
  case ISD::SRL:
  case X86ISD::VSRL:
  case X86ISD::VSRLI:
    return IsVariable ? X86ISD::VSRL : X86ISD::VSRLI;
  case ISD::SRA:
  case X86ISD::VSRA:
  case X86ISD::VSRAI:
    return IsVariable ? X86ISD::VSRA : X86ISD::VSRAI;
  }
  llvm_unreachable("Unknown target vector shift node");
}

/// Handle vector element shifts where the shift amount is a constant.
/// Takes immediate version of shift as input.
static SDValue getTargetVShiftByConstNode(unsigned Opc, const SDLoc &dl, MVT VT,
                                          SDValue SrcOp, uint64_t ShiftAmt,
                                          SelectionDAG &DAG) {
  MVT ElementType = VT.getVectorElementType();

  // Bitcast the source vector to the output type, this is mainly necessary for
  // vXi8/vXi64 shifts.
  if (VT != SrcOp.getSimpleValueType())
    SrcOp = DAG.getBitcast(VT, SrcOp);

  // Fold this packed shift into its first operand if ShiftAmt is 0.
  if (ShiftAmt == 0)
    return SrcOp;

  // Check for ShiftAmt >= element width
  if (ShiftAmt >= ElementType.getSizeInBits()) {
    if (Opc == X86ISD::VSRAI)
      ShiftAmt = ElementType.getSizeInBits() - 1;
    else
      return DAG.getConstant(0, dl, VT);
  }

  assert((Opc == X86ISD::VSHLI || Opc == X86ISD::VSRLI || Opc == X86ISD::VSRAI)
         && "Unknown target vector shift-by-constant node");

  // Fold this packed vector shift into a build vector if SrcOp is a
  // vector of Constants or UNDEFs.
  if (ISD::isBuildVectorOfConstantSDNodes(SrcOp.getNode())) {
    SmallVector<SDValue, 8> Elts;
    unsigned NumElts = SrcOp->getNumOperands();

    switch (Opc) {
    default: llvm_unreachable("Unknown opcode!");
    case X86ISD::VSHLI:
      for (unsigned i = 0; i != NumElts; ++i) {
        SDValue CurrentOp = SrcOp->getOperand(i);
        if (CurrentOp->isUndef()) {
          Elts.push_back(CurrentOp);
          continue;
        }
        auto *ND = cast<ConstantSDNode>(CurrentOp);
        const APInt &C = ND->getAPIntValue();
        Elts.push_back(DAG.getConstant(C.shl(ShiftAmt), dl, ElementType));
      }
      break;
    case X86ISD::VSRLI:
      for (unsigned i = 0; i != NumElts; ++i) {
        SDValue CurrentOp = SrcOp->getOperand(i);
        if (CurrentOp->isUndef()) {
          Elts.push_back(CurrentOp);
          continue;
        }
        auto *ND = cast<ConstantSDNode>(CurrentOp);
        const APInt &C = ND->getAPIntValue();
        Elts.push_back(DAG.getConstant(C.lshr(ShiftAmt), dl, ElementType));
      }
      break;
    case X86ISD::VSRAI:
      for (unsigned i = 0; i != NumElts; ++i) {
        SDValue CurrentOp = SrcOp->getOperand(i);
        if (CurrentOp->isUndef()) {
          Elts.push_back(CurrentOp);
          continue;
        }
        auto *ND = cast<ConstantSDNode>(CurrentOp);
        const APInt &C = ND->getAPIntValue();
        Elts.push_back(DAG.getConstant(C.ashr(ShiftAmt), dl, ElementType));
      }
      break;
    }

    return DAG.getBuildVector(VT, dl, Elts);
  }

  return DAG.getNode(Opc, dl, VT, SrcOp,
                     DAG.getTargetConstant(ShiftAmt, dl, MVT::i8));
}

/// Handle vector element shifts where the shift amount may or may not be a
/// constant. Takes immediate version of shift as input.
static SDValue getTargetVShiftNode(unsigned Opc, const SDLoc &dl, MVT VT,
                                   SDValue SrcOp, SDValue ShAmt,
                                   const X86Subtarget &Subtarget,
                                   SelectionDAG &DAG) {
  MVT SVT = ShAmt.getSimpleValueType();
  assert((SVT == MVT::i32 || SVT == MVT::i64) && "Unexpected value type!");

  // Catch shift-by-constant.
  if (ConstantSDNode *CShAmt = dyn_cast<ConstantSDNode>(ShAmt))
    return getTargetVShiftByConstNode(Opc, dl, VT, SrcOp,
                                      CShAmt->getZExtValue(), DAG);

  // Change opcode to non-immediate version.
  Opc = getTargetVShiftUniformOpcode(Opc, true);

  // Need to build a vector containing shift amount.
  // SSE/AVX packed shifts only use the lower 64-bit of the shift count.
  // +====================+============+=======================================+
  // | ShAmt is           | HasSSE4.1? | Construct ShAmt vector as             |
  // +====================+============+=======================================+
  // | i64                | Yes, No    | Use ShAmt as lowest elt               |
  // | i32                | Yes        | zero-extend in-reg                    |
  // | (i32 zext(i16/i8)) | Yes        | zero-extend in-reg                    |
  // | (i32 zext(i16/i8)) | No         | byte-shift-in-reg                     |
  // | i16/i32            | No         | v4i32 build_vector(ShAmt, 0, ud, ud)) |
  // +====================+============+=======================================+

  if (SVT == MVT::i64)
    ShAmt = DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(ShAmt), MVT::v2i64, ShAmt);
  else if (ShAmt.getOpcode() == ISD::ZERO_EXTEND &&
           ShAmt.getOperand(0).getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
           (ShAmt.getOperand(0).getSimpleValueType() == MVT::i16 ||
            ShAmt.getOperand(0).getSimpleValueType() == MVT::i8)) {
    ShAmt = ShAmt.getOperand(0);
    MVT AmtTy = ShAmt.getSimpleValueType() == MVT::i8 ? MVT::v16i8 : MVT::v8i16;
    ShAmt = DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(ShAmt), AmtTy, ShAmt);
    if (Subtarget.hasSSE41())
      ShAmt = DAG.getNode(ISD::ZERO_EXTEND_VECTOR_INREG, SDLoc(ShAmt),
                          MVT::v2i64, ShAmt);
    else {
      SDValue ByteShift = DAG.getTargetConstant(
          (128 - AmtTy.getScalarSizeInBits()) / 8, SDLoc(ShAmt), MVT::i8);
      ShAmt = DAG.getBitcast(MVT::v16i8, ShAmt);
      ShAmt = DAG.getNode(X86ISD::VSHLDQ, SDLoc(ShAmt), MVT::v16i8, ShAmt,
                          ByteShift);
      ShAmt = DAG.getNode(X86ISD::VSRLDQ, SDLoc(ShAmt), MVT::v16i8, ShAmt,
                          ByteShift);
    }
  } else if (Subtarget.hasSSE41() &&
             ShAmt.getOpcode() == ISD::EXTRACT_VECTOR_ELT) {
    ShAmt = DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(ShAmt), MVT::v4i32, ShAmt);
    ShAmt = DAG.getNode(ISD::ZERO_EXTEND_VECTOR_INREG, SDLoc(ShAmt),
                        MVT::v2i64, ShAmt);
  } else {
    SDValue ShOps[4] = {ShAmt, DAG.getConstant(0, dl, SVT), DAG.getUNDEF(SVT),
                        DAG.getUNDEF(SVT)};
    ShAmt = DAG.getBuildVector(MVT::v4i32, dl, ShOps);
  }

  // The return type has to be a 128-bit type with the same element
  // type as the input type.
  MVT EltVT = VT.getVectorElementType();
  MVT ShVT = MVT::getVectorVT(EltVT, 128 / EltVT.getSizeInBits());

  ShAmt = DAG.getBitcast(ShVT, ShAmt);
  return DAG.getNode(Opc, dl, VT, SrcOp, ShAmt);
}

/// Return Mask with the necessary casting or extending
/// for \p Mask according to \p MaskVT when lowering masking intrinsics
static SDValue getMaskNode(SDValue Mask, MVT MaskVT,
                           const X86Subtarget &Subtarget, SelectionDAG &DAG,
                           const SDLoc &dl) {

  if (isAllOnesConstant(Mask))
    return DAG.getConstant(1, dl, MaskVT);
  if (X86::isZeroNode(Mask))
    return DAG.getConstant(0, dl, MaskVT);

  assert(MaskVT.bitsLE(Mask.getSimpleValueType()) && "Unexpected mask size!");

  if (Mask.getSimpleValueType() == MVT::i64 && Subtarget.is32Bit()) {
    assert(MaskVT == MVT::v64i1 && "Expected v64i1 mask!");
    assert(Subtarget.hasBWI() && "Expected AVX512BW target!");
    // In case 32bit mode, bitcast i64 is illegal, extend/split it.
    SDValue Lo, Hi;
    Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Mask,
                        DAG.getConstant(0, dl, MVT::i32));
    Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Mask,
                        DAG.getConstant(1, dl, MVT::i32));

    Lo = DAG.getBitcast(MVT::v32i1, Lo);
    Hi = DAG.getBitcast(MVT::v32i1, Hi);

    return DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v64i1, Lo, Hi);
  } else {
    MVT BitcastVT = MVT::getVectorVT(MVT::i1,
                                     Mask.getSimpleValueType().getSizeInBits());
    // In case when MaskVT equals v2i1 or v4i1, low 2 or 4 elements
    // are extracted by EXTRACT_SUBVECTOR.
    return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MaskVT,
                       DAG.getBitcast(BitcastVT, Mask),
                       DAG.getIntPtrConstant(0, dl));
  }
}

/// Return (and \p Op, \p Mask) for compare instructions or
/// (vselect \p Mask, \p Op, \p PreservedSrc) for others along with the
/// necessary casting or extending for \p Mask when lowering masking intrinsics
static SDValue getVectorMaskingNode(SDValue Op, SDValue Mask,
                  SDValue PreservedSrc,
                  const X86Subtarget &Subtarget,
                  SelectionDAG &DAG) {
  MVT VT = Op.getSimpleValueType();
  MVT MaskVT = MVT::getVectorVT(MVT::i1, VT.getVectorNumElements());
  unsigned OpcodeSelect = ISD::VSELECT;
  SDLoc dl(Op);

  if (isAllOnesConstant(Mask))
    return Op;

  SDValue VMask = getMaskNode(Mask, MaskVT, Subtarget, DAG, dl);

  if (PreservedSrc.isUndef())
    PreservedSrc = getZeroVector(VT, Subtarget, DAG, dl);
  return DAG.getNode(OpcodeSelect, dl, VT, VMask, Op, PreservedSrc);
}

/// Creates an SDNode for a predicated scalar operation.
/// \returns (X86vselect \p Mask, \p Op, \p PreservedSrc).
/// The mask is coming as MVT::i8 and it should be transformed
/// to MVT::v1i1 while lowering masking intrinsics.
/// The main difference between ScalarMaskingNode and VectorMaskingNode is using
/// "X86select" instead of "vselect". We just can't create the "vselect" node
/// for a scalar instruction.
static SDValue getScalarMaskingNode(SDValue Op, SDValue Mask,
                                    SDValue PreservedSrc,
                                    const X86Subtarget &Subtarget,
                                    SelectionDAG &DAG) {

  if (auto *MaskConst = dyn_cast<ConstantSDNode>(Mask))
    if (MaskConst->getZExtValue() & 0x1)
      return Op;

  MVT VT = Op.getSimpleValueType();
  SDLoc dl(Op);

  assert(Mask.getValueType() == MVT::i8 && "Unexpect type");
  SDValue IMask = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v1i1,
                              DAG.getBitcast(MVT::v8i1, Mask),
                              DAG.getIntPtrConstant(0, dl));
  if (Op.getOpcode() == X86ISD::FSETCCM ||
      Op.getOpcode() == X86ISD::FSETCCM_SAE ||
      Op.getOpcode() == X86ISD::VFPCLASSS)
    return DAG.getNode(ISD::AND, dl, VT, Op, IMask);

  if (PreservedSrc.isUndef())
    PreservedSrc = getZeroVector(VT, Subtarget, DAG, dl);
  return DAG.getNode(X86ISD::SELECTS, dl, VT, IMask, Op, PreservedSrc);
}

static int getSEHRegistrationNodeSize(const Function *Fn) {
  if (!Fn->hasPersonalityFn())
    report_fatal_error(
        "querying registration node size for function without personality");
  // The RegNodeSize is 6 32-bit words for SEH and 4 for C++ EH. See
  // WinEHStatePass for the full struct definition.
  switch (classifyEHPersonality(Fn->getPersonalityFn())) {
  case EHPersonality::MSVC_X86SEH: return 24;
  case EHPersonality::MSVC_CXX: return 16;
  default: break;
  }
  report_fatal_error(
      "can only recover FP for 32-bit MSVC EH personality functions");
}

/// When the MSVC runtime transfers control to us, either to an outlined
/// function or when returning to a parent frame after catching an exception, we
/// recover the parent frame pointer by doing arithmetic on the incoming EBP.
/// Here's the math:
///   RegNodeBase = EntryEBP - RegNodeSize
///   ParentFP = RegNodeBase - ParentFrameOffset
/// Subtracting RegNodeSize takes us to the offset of the registration node, and
/// subtracting the offset (negative on x86) takes us back to the parent FP.
static SDValue recoverFramePointer(SelectionDAG &DAG, const Function *Fn,
                                   SDValue EntryEBP) {
  MachineFunction &MF = DAG.getMachineFunction();
  SDLoc dl;

  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());

  // It's possible that the parent function no longer has a personality function
  // if the exceptional code was optimized away, in which case we just return
  // the incoming EBP.
  if (!Fn->hasPersonalityFn())
    return EntryEBP;

  // Get an MCSymbol that will ultimately resolve to the frame offset of the EH
  // registration, or the .set_setframe offset.
  MCSymbol *OffsetSym =
      MF.getMMI().getContext().getOrCreateParentFrameOffsetSymbol(
          GlobalValue::dropLLVMManglingEscape(Fn->getName()));
  SDValue OffsetSymVal = DAG.getMCSymbol(OffsetSym, PtrVT);
  SDValue ParentFrameOffset =
      DAG.getNode(ISD::LOCAL_RECOVER, dl, PtrVT, OffsetSymVal);

  // Return EntryEBP + ParentFrameOffset for x64. This adjusts from RSP after
  // prologue to RBP in the parent function.
  const X86Subtarget &Subtarget =
      static_cast<const X86Subtarget &>(DAG.getSubtarget());
  if (Subtarget.is64Bit())
    return DAG.getNode(ISD::ADD, dl, PtrVT, EntryEBP, ParentFrameOffset);

  int RegNodeSize = getSEHRegistrationNodeSize(Fn);
  // RegNodeBase = EntryEBP - RegNodeSize
  // ParentFP = RegNodeBase - ParentFrameOffset
  SDValue RegNodeBase = DAG.getNode(ISD::SUB, dl, PtrVT, EntryEBP,
                                    DAG.getConstant(RegNodeSize, dl, PtrVT));
  return DAG.getNode(ISD::SUB, dl, PtrVT, RegNodeBase, ParentFrameOffset);
}

SDValue X86TargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
                                                   SelectionDAG &DAG) const {
  // Helper to detect if the operand is CUR_DIRECTION rounding mode.
  auto isRoundModeCurDirection = [](SDValue Rnd) {
    if (auto *C = dyn_cast<ConstantSDNode>(Rnd))
      return C->getAPIntValue() == X86::STATIC_ROUNDING::CUR_DIRECTION;

    return false;
  };
  auto isRoundModeSAE = [](SDValue Rnd) {
    if (auto *C = dyn_cast<ConstantSDNode>(Rnd)) {
      unsigned RC = C->getZExtValue();
      if (RC & X86::STATIC_ROUNDING::NO_EXC) {
        // Clear the NO_EXC bit and check remaining bits.
        RC ^= X86::STATIC_ROUNDING::NO_EXC;
        // As a convenience we allow no other bits or explicitly
        // current direction.
        return RC == 0 || RC == X86::STATIC_ROUNDING::CUR_DIRECTION;
      }
    }

    return false;
  };
  auto isRoundModeSAEToX = [](SDValue Rnd, unsigned &RC) {
    if (auto *C = dyn_cast<ConstantSDNode>(Rnd)) {
      RC = C->getZExtValue();
      if (RC & X86::STATIC_ROUNDING::NO_EXC) {
        // Clear the NO_EXC bit and check remaining bits.
        RC ^= X86::STATIC_ROUNDING::NO_EXC;
        return RC == X86::STATIC_ROUNDING::TO_NEAREST_INT ||
               RC == X86::STATIC_ROUNDING::TO_NEG_INF ||
               RC == X86::STATIC_ROUNDING::TO_POS_INF ||
               RC == X86::STATIC_ROUNDING::TO_ZERO;
      }
    }

    return false;
  };

  SDLoc dl(Op);
  unsigned IntNo = Op.getConstantOperandVal(0);
  MVT VT = Op.getSimpleValueType();
  const IntrinsicData* IntrData = getIntrinsicWithoutChain(IntNo);

  if (IntrData) {
    switch(IntrData->Type) {
    case INTR_TYPE_1OP: {
      // We specify 2 possible opcodes for intrinsics with rounding modes.
      // First, we check if the intrinsic may have non-default rounding mode,
      // (IntrData->Opc1 != 0), then we check the rounding mode operand.
      unsigned IntrWithRoundingModeOpcode = IntrData->Opc1;
      if (IntrWithRoundingModeOpcode != 0) {
        SDValue Rnd = Op.getOperand(2);
        unsigned RC = 0;
        if (isRoundModeSAEToX(Rnd, RC))
          return DAG.getNode(IntrWithRoundingModeOpcode, dl, Op.getValueType(),
                             Op.getOperand(1),
                             DAG.getTargetConstant(RC, dl, MVT::i32));
        if (!isRoundModeCurDirection(Rnd))
          return SDValue();
      }
      return DAG.getNode(IntrData->Opc0, dl, Op.getValueType(),
                         Op.getOperand(1));
    }
    case INTR_TYPE_1OP_SAE: {
      SDValue Sae = Op.getOperand(2);

      unsigned Opc;
      if (isRoundModeCurDirection(Sae))
        Opc = IntrData->Opc0;
      else if (isRoundModeSAE(Sae))
        Opc = IntrData->Opc1;
      else
        return SDValue();

      return DAG.getNode(Opc, dl, Op.getValueType(), Op.getOperand(1));
    }
    case INTR_TYPE_2OP: {
      SDValue Src2 = Op.getOperand(2);

      // We specify 2 possible opcodes for intrinsics with rounding modes.
      // First, we check if the intrinsic may have non-default rounding mode,
      // (IntrData->Opc1 != 0), then we check the rounding mode operand.
      unsigned IntrWithRoundingModeOpcode = IntrData->Opc1;
      if (IntrWithRoundingModeOpcode != 0) {
        SDValue Rnd = Op.getOperand(3);
        unsigned RC = 0;
        if (isRoundModeSAEToX(Rnd, RC))
          return DAG.getNode(IntrWithRoundingModeOpcode, dl, Op.getValueType(),
                             Op.getOperand(1), Src2,
                             DAG.getTargetConstant(RC, dl, MVT::i32));
        if (!isRoundModeCurDirection(Rnd))
          return SDValue();
      }

      return DAG.getNode(IntrData->Opc0, dl, Op.getValueType(),
                         Op.getOperand(1), Src2);
    }
    case INTR_TYPE_2OP_SAE: {
      SDValue Sae = Op.getOperand(3);

      unsigned Opc;
      if (isRoundModeCurDirection(Sae))
        Opc = IntrData->Opc0;
      else if (isRoundModeSAE(Sae))
        Opc = IntrData->Opc1;
      else
        return SDValue();

      return DAG.getNode(Opc, dl, Op.getValueType(), Op.getOperand(1),
                         Op.getOperand(2));
    }
    case INTR_TYPE_3OP:
    case INTR_TYPE_3OP_IMM8: {
      SDValue Src1 = Op.getOperand(1);
      SDValue Src2 = Op.getOperand(2);
      SDValue Src3 = Op.getOperand(3);

      // We specify 2 possible opcodes for intrinsics with rounding modes.
      // First, we check if the intrinsic may have non-default rounding mode,
      // (IntrData->Opc1 != 0), then we check the rounding mode operand.
      unsigned IntrWithRoundingModeOpcode = IntrData->Opc1;
      if (IntrWithRoundingModeOpcode != 0) {
        SDValue Rnd = Op.getOperand(4);
        unsigned RC = 0;
        if (isRoundModeSAEToX(Rnd, RC))
          return DAG.getNode(IntrWithRoundingModeOpcode, dl, Op.getValueType(),
                             Src1, Src2, Src3,
                             DAG.getTargetConstant(RC, dl, MVT::i32));
        if (!isRoundModeCurDirection(Rnd))
          return SDValue();
      }

      return DAG.getNode(IntrData->Opc0, dl, Op.getValueType(),
                         {Src1, Src2, Src3});
    }
    case INTR_TYPE_4OP:
      return DAG.getNode(IntrData->Opc0, dl, Op.getValueType(), Op.getOperand(1),
        Op.getOperand(2), Op.getOperand(3), Op.getOperand(4));
    case INTR_TYPE_1OP_MASK: {
      SDValue Src = Op.getOperand(1);
      SDValue PassThru = Op.getOperand(2);
      SDValue Mask = Op.getOperand(3);
      // We add rounding mode to the Node when
      //   - RC Opcode is specified and
      //   - RC is not "current direction".
      unsigned IntrWithRoundingModeOpcode = IntrData->Opc1;
      if (IntrWithRoundingModeOpcode != 0) {
        SDValue Rnd = Op.getOperand(4);
        unsigned RC = 0;
        if (isRoundModeSAEToX(Rnd, RC))
          return getVectorMaskingNode(
              DAG.getNode(IntrWithRoundingModeOpcode, dl, Op.getValueType(),
                          Src, DAG.getTargetConstant(RC, dl, MVT::i32)),
              Mask, PassThru, Subtarget, DAG);
        if (!isRoundModeCurDirection(Rnd))
          return SDValue();
      }
      return getVectorMaskingNode(
          DAG.getNode(IntrData->Opc0, dl, VT, Src), Mask, PassThru,
          Subtarget, DAG);
    }
    case INTR_TYPE_1OP_MASK_SAE: {
      SDValue Src = Op.getOperand(1);
      SDValue PassThru = Op.getOperand(2);
      SDValue Mask = Op.getOperand(3);
      SDValue Rnd = Op.getOperand(4);

      unsigned Opc;
      if (isRoundModeCurDirection(Rnd))
        Opc = IntrData->Opc0;
      else if (isRoundModeSAE(Rnd))
        Opc = IntrData->Opc1;
      else
        return SDValue();

      return getVectorMaskingNode(DAG.getNode(Opc, dl, VT, Src), Mask, PassThru,
                                  Subtarget, DAG);
    }
    case INTR_TYPE_SCALAR_MASK: {
      SDValue Src1 = Op.getOperand(1);
      SDValue Src2 = Op.getOperand(2);
      SDValue passThru = Op.getOperand(3);
      SDValue Mask = Op.getOperand(4);
      unsigned IntrWithRoundingModeOpcode = IntrData->Opc1;
      // There are 2 kinds of intrinsics in this group:
      // (1) With suppress-all-exceptions (sae) or rounding mode- 6 operands
      // (2) With rounding mode and sae - 7 operands.
      bool HasRounding = IntrWithRoundingModeOpcode != 0;
      if (Op.getNumOperands() == (5U + HasRounding)) {
        if (HasRounding) {
          SDValue Rnd = Op.getOperand(5);
          unsigned RC = 0;
          if (isRoundModeSAEToX(Rnd, RC))
            return getScalarMaskingNode(
                DAG.getNode(IntrWithRoundingModeOpcode, dl, VT, Src1, Src2,
                            DAG.getTargetConstant(RC, dl, MVT::i32)),
                Mask, passThru, Subtarget, DAG);
          if (!isRoundModeCurDirection(Rnd))
            return SDValue();
        }
        return getScalarMaskingNode(DAG.getNode(IntrData->Opc0, dl, VT, Src1,
                                                Src2),
                                    Mask, passThru, Subtarget, DAG);
      }

      assert(Op.getNumOperands() == (6U + HasRounding) &&
             "Unexpected intrinsic form");
      SDValue RoundingMode = Op.getOperand(5);
      unsigned Opc = IntrData->Opc0;
      if (HasRounding) {
        SDValue Sae = Op.getOperand(6);
        if (isRoundModeSAE(Sae))
          Opc = IntrWithRoundingModeOpcode;
        else if (!isRoundModeCurDirection(Sae))
          return SDValue();
      }
      return getScalarMaskingNode(DAG.getNode(Opc, dl, VT, Src1,
                                              Src2, RoundingMode),
                                  Mask, passThru, Subtarget, DAG);
    }
    case INTR_TYPE_SCALAR_MASK_RND: {
      SDValue Src1 = Op.getOperand(1);
      SDValue Src2 = Op.getOperand(2);
      SDValue passThru = Op.getOperand(3);
      SDValue Mask = Op.getOperand(4);
      SDValue Rnd = Op.getOperand(5);

      SDValue NewOp;
      unsigned RC = 0;
      if (isRoundModeCurDirection(Rnd))
        NewOp = DAG.getNode(IntrData->Opc0, dl, VT, Src1, Src2);
      else if (isRoundModeSAEToX(Rnd, RC))
        NewOp = DAG.getNode(IntrData->Opc1, dl, VT, Src1, Src2,
                            DAG.getTargetConstant(RC, dl, MVT::i32));
      else
        return SDValue();

      return getScalarMaskingNode(NewOp, Mask, passThru, Subtarget, DAG);
    }
    case INTR_TYPE_SCALAR_MASK_SAE: {
      SDValue Src1 = Op.getOperand(1);
      SDValue Src2 = Op.getOperand(2);
      SDValue passThru = Op.getOperand(3);
      SDValue Mask = Op.getOperand(4);
      SDValue Sae = Op.getOperand(5);
      unsigned Opc;
      if (isRoundModeCurDirection(Sae))
        Opc = IntrData->Opc0;
      else if (isRoundModeSAE(Sae))
        Opc = IntrData->Opc1;
      else
        return SDValue();

      return getScalarMaskingNode(DAG.getNode(Opc, dl, VT, Src1, Src2),
                                  Mask, passThru, Subtarget, DAG);
    }
    case INTR_TYPE_2OP_MASK: {
      SDValue Src1 = Op.getOperand(1);
      SDValue Src2 = Op.getOperand(2);
      SDValue PassThru = Op.getOperand(3);
      SDValue Mask = Op.getOperand(4);
      SDValue NewOp;
      if (IntrData->Opc1 != 0) {
        SDValue Rnd = Op.getOperand(5);
        unsigned RC = 0;
        if (isRoundModeSAEToX(Rnd, RC))
          NewOp = DAG.getNode(IntrData->Opc1, dl, VT, Src1, Src2,
                              DAG.getTargetConstant(RC, dl, MVT::i32));
        else if (!isRoundModeCurDirection(Rnd))
          return SDValue();
      }
      if (!NewOp)
        NewOp = DAG.getNode(IntrData->Opc0, dl, VT, Src1, Src2);
      return getVectorMaskingNode(NewOp, Mask, PassThru, Subtarget, DAG);
    }
    case INTR_TYPE_2OP_MASK_SAE: {
      SDValue Src1 = Op.getOperand(1);
      SDValue Src2 = Op.getOperand(2);
      SDValue PassThru = Op.getOperand(3);
      SDValue Mask = Op.getOperand(4);

      unsigned Opc = IntrData->Opc0;
      if (IntrData->Opc1 != 0) {
        SDValue Sae = Op.getOperand(5);
        if (isRoundModeSAE(Sae))
          Opc = IntrData->Opc1;
        else if (!isRoundModeCurDirection(Sae))
          return SDValue();
      }

      return getVectorMaskingNode(DAG.getNode(Opc, dl, VT, Src1, Src2),
                                  Mask, PassThru, Subtarget, DAG);
    }
    case INTR_TYPE_3OP_SCALAR_MASK_SAE: {
      SDValue Src1 = Op.getOperand(1);
      SDValue Src2 = Op.getOperand(2);
      SDValue Src3 = Op.getOperand(3);
      SDValue PassThru = Op.getOperand(4);
      SDValue Mask = Op.getOperand(5);
      SDValue Sae = Op.getOperand(6);
      unsigned Opc;
      if (isRoundModeCurDirection(Sae))
        Opc = IntrData->Opc0;
      else if (isRoundModeSAE(Sae))
        Opc = IntrData->Opc1;
      else
        return SDValue();

      return getScalarMaskingNode(DAG.getNode(Opc, dl, VT, Src1, Src2, Src3),
                                  Mask, PassThru, Subtarget, DAG);
    }
    case INTR_TYPE_3OP_MASK_SAE: {
      SDValue Src1 = Op.getOperand(1);
      SDValue Src2 = Op.getOperand(2);
      SDValue Src3 = Op.getOperand(3);
      SDValue PassThru = Op.getOperand(4);
      SDValue Mask = Op.getOperand(5);

      unsigned Opc = IntrData->Opc0;
      if (IntrData->Opc1 != 0) {
        SDValue Sae = Op.getOperand(6);
        if (isRoundModeSAE(Sae))
          Opc = IntrData->Opc1;
        else if (!isRoundModeCurDirection(Sae))
          return SDValue();
      }
      return getVectorMaskingNode(DAG.getNode(Opc, dl, VT, Src1, Src2, Src3),
                                  Mask, PassThru, Subtarget, DAG);
    }
    case BLENDV: {
      SDValue Src1 = Op.getOperand(1);
      SDValue Src2 = Op.getOperand(2);
      SDValue Src3 = Op.getOperand(3);

      EVT MaskVT = Src3.getValueType().changeVectorElementTypeToInteger();
      Src3 = DAG.getBitcast(MaskVT, Src3);

      // Reverse the operands to match VSELECT order.
      return DAG.getNode(IntrData->Opc0, dl, VT, Src3, Src2, Src1);
    }
    case VPERM_2OP : {
      SDValue Src1 = Op.getOperand(1);
      SDValue Src2 = Op.getOperand(2);

      // Swap Src1 and Src2 in the node creation
      return DAG.getNode(IntrData->Opc0, dl, VT,Src2, Src1);
    }
    case IFMA_OP:
      // NOTE: We need to swizzle the operands to pass the multiply operands
      // first.
      return DAG.getNode(IntrData->Opc0, dl, Op.getValueType(),
                         Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
    case FPCLASSS: {
      SDValue Src1 = Op.getOperand(1);
      SDValue Imm = Op.getOperand(2);
      SDValue Mask = Op.getOperand(3);
      SDValue FPclass = DAG.getNode(IntrData->Opc0, dl, MVT::v1i1, Src1, Imm);
      SDValue FPclassMask = getScalarMaskingNode(FPclass, Mask, SDValue(),
                                                 Subtarget, DAG);
      // Need to fill with zeros to ensure the bitcast will produce zeroes
      // for the upper bits. An EXTRACT_ELEMENT here wouldn't guarantee that.
      SDValue Ins = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, MVT::v8i1,
                                DAG.getConstant(0, dl, MVT::v8i1),
                                FPclassMask, DAG.getIntPtrConstant(0, dl));
      return DAG.getBitcast(MVT::i8, Ins);
    }

    case CMP_MASK_CC: {
      MVT MaskVT = Op.getSimpleValueType();
      SDValue CC = Op.getOperand(3);
      // We specify 2 possible opcodes for intrinsics with rounding modes.
      // First, we check if the intrinsic may have non-default rounding mode,
      // (IntrData->Opc1 != 0), then we check the rounding mode operand.
      if (IntrData->Opc1 != 0) {
        SDValue Sae = Op.getOperand(4);
        if (isRoundModeSAE(Sae))
          return DAG.getNode(IntrData->Opc1, dl, MaskVT, Op.getOperand(1),
                             Op.getOperand(2), CC, Sae);
        if (!isRoundModeCurDirection(Sae))
          return SDValue();
      }
      //default rounding mode
      return DAG.getNode(IntrData->Opc0, dl, MaskVT,
                         {Op.getOperand(1), Op.getOperand(2), CC});
    }
    case CMP_MASK_SCALAR_CC: {
      SDValue Src1 = Op.getOperand(1);
      SDValue Src2 = Op.getOperand(2);
      SDValue CC = Op.getOperand(3);
      SDValue Mask = Op.getOperand(4);

      SDValue Cmp;
      if (IntrData->Opc1 != 0) {
        SDValue Sae = Op.getOperand(5);
        if (isRoundModeSAE(Sae))
          Cmp = DAG.getNode(IntrData->Opc1, dl, MVT::v1i1, Src1, Src2, CC, Sae);
        else if (!isRoundModeCurDirection(Sae))
          return SDValue();
      }
      //default rounding mode
      if (!Cmp.getNode())
        Cmp = DAG.getNode(IntrData->Opc0, dl, MVT::v1i1, Src1, Src2, CC);

      SDValue CmpMask = getScalarMaskingNode(Cmp, Mask, SDValue(),
                                             Subtarget, DAG);
      // Need to fill with zeros to ensure the bitcast will produce zeroes
      // for the upper bits. An EXTRACT_ELEMENT here wouldn't guarantee that.
      SDValue Ins = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, MVT::v8i1,
                                DAG.getConstant(0, dl, MVT::v8i1),
                                CmpMask, DAG.getIntPtrConstant(0, dl));
      return DAG.getBitcast(MVT::i8, Ins);
    }
    case COMI: { // Comparison intrinsics
      ISD::CondCode CC = (ISD::CondCode)IntrData->Opc1;
      SDValue LHS = Op.getOperand(1);
      SDValue RHS = Op.getOperand(2);
      // Some conditions require the operands to be swapped.
      if (CC == ISD::SETLT || CC == ISD::SETLE)
        std::swap(LHS, RHS);

      SDValue Comi = DAG.getNode(IntrData->Opc0, dl, MVT::i32, LHS, RHS);
      SDValue SetCC;
      switch (CC) {
      case ISD::SETEQ: { // (ZF = 0 and PF = 0)
        SetCC = getSETCC(X86::COND_E, Comi, dl, DAG);
        SDValue SetNP = getSETCC(X86::COND_NP, Comi, dl, DAG);
        SetCC = DAG.getNode(ISD::AND, dl, MVT::i8, SetCC, SetNP);
        break;
      }
      case ISD::SETNE: { // (ZF = 1 or PF = 1)
        SetCC = getSETCC(X86::COND_NE, Comi, dl, DAG);
        SDValue SetP = getSETCC(X86::COND_P, Comi, dl, DAG);
        SetCC = DAG.getNode(ISD::OR, dl, MVT::i8, SetCC, SetP);
        break;
      }
      case ISD::SETGT: // (CF = 0 and ZF = 0)
      case ISD::SETLT: { // Condition opposite to GT. Operands swapped above.
        SetCC = getSETCC(X86::COND_A, Comi, dl, DAG);
        break;
      }
      case ISD::SETGE: // CF = 0
      case ISD::SETLE: // Condition opposite to GE. Operands swapped above.
        SetCC = getSETCC(X86::COND_AE, Comi, dl, DAG);
        break;
      default:
        llvm_unreachable("Unexpected illegal condition!");
      }
      return DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, SetCC);
    }
    case COMI_RM: { // Comparison intrinsics with Sae
      SDValue LHS = Op.getOperand(1);
      SDValue RHS = Op.getOperand(2);
      unsigned CondVal = Op.getConstantOperandVal(3);
      SDValue Sae = Op.getOperand(4);

      SDValue FCmp;
      if (isRoundModeCurDirection(Sae))
        FCmp = DAG.getNode(X86ISD::FSETCCM, dl, MVT::v1i1, LHS, RHS,
                           DAG.getTargetConstant(CondVal, dl, MVT::i8));
      else if (isRoundModeSAE(Sae))
        FCmp = DAG.getNode(X86ISD::FSETCCM_SAE, dl, MVT::v1i1, LHS, RHS,
                           DAG.getTargetConstant(CondVal, dl, MVT::i8), Sae);
      else
        return SDValue();
      // Need to fill with zeros to ensure the bitcast will produce zeroes
      // for the upper bits. An EXTRACT_ELEMENT here wouldn't guarantee that.
      SDValue Ins = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, MVT::v16i1,
                                DAG.getConstant(0, dl, MVT::v16i1),
                                FCmp, DAG.getIntPtrConstant(0, dl));
      return DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32,
                         DAG.getBitcast(MVT::i16, Ins));
    }
    case VSHIFT:
      return getTargetVShiftNode(IntrData->Opc0, dl, Op.getSimpleValueType(),
                                 Op.getOperand(1), Op.getOperand(2), Subtarget,
                                 DAG);
    case COMPRESS_EXPAND_IN_REG: {
      SDValue Mask = Op.getOperand(3);
      SDValue DataToCompress = Op.getOperand(1);
      SDValue PassThru = Op.getOperand(2);
      if (ISD::isBuildVectorAllOnes(Mask.getNode())) // return data as is
        return Op.getOperand(1);

      // Avoid false dependency.
      if (PassThru.isUndef())
        PassThru = DAG.getConstant(0, dl, VT);

      return DAG.getNode(IntrData->Opc0, dl, VT, DataToCompress, PassThru,
                         Mask);
    }
    case FIXUPIMM:
    case FIXUPIMM_MASKZ: {
      SDValue Src1 = Op.getOperand(1);
      SDValue Src2 = Op.getOperand(2);
      SDValue Src3 = Op.getOperand(3);
      SDValue Imm = Op.getOperand(4);
      SDValue Mask = Op.getOperand(5);
      SDValue Passthru = (IntrData->Type == FIXUPIMM)
                             ? Src1
                             : getZeroVector(VT, Subtarget, DAG, dl);

      unsigned Opc = IntrData->Opc0;
      if (IntrData->Opc1 != 0) {
        SDValue Sae = Op.getOperand(6);
        if (isRoundModeSAE(Sae))
          Opc = IntrData->Opc1;
        else if (!isRoundModeCurDirection(Sae))
          return SDValue();
      }

      SDValue FixupImm = DAG.getNode(Opc, dl, VT, Src1, Src2, Src3, Imm);

      if (Opc == X86ISD::VFIXUPIMM || Opc == X86ISD::VFIXUPIMM_SAE)
        return getVectorMaskingNode(FixupImm, Mask, Passthru, Subtarget, DAG);

      return getScalarMaskingNode(FixupImm, Mask, Passthru, Subtarget, DAG);
    }
    case ROUNDP: {
      assert(IntrData->Opc0 == X86ISD::VRNDSCALE && "Unexpected opcode");
      // Clear the upper bits of the rounding immediate so that the legacy
      // intrinsic can't trigger the scaling behavior of VRNDSCALE.
      auto Round = cast<ConstantSDNode>(Op.getOperand(2));
      SDValue RoundingMode =
          DAG.getTargetConstant(Round->getZExtValue() & 0xf, dl, MVT::i32);
      return DAG.getNode(IntrData->Opc0, dl, Op.getValueType(),
                         Op.getOperand(1), RoundingMode);
    }
    case ROUNDS: {
      assert(IntrData->Opc0 == X86ISD::VRNDSCALES && "Unexpected opcode");
      // Clear the upper bits of the rounding immediate so that the legacy
      // intrinsic can't trigger the scaling behavior of VRNDSCALE.
      auto Round = cast<ConstantSDNode>(Op.getOperand(3));
      SDValue RoundingMode =
          DAG.getTargetConstant(Round->getZExtValue() & 0xf, dl, MVT::i32);
      return DAG.getNode(IntrData->Opc0, dl, Op.getValueType(),
                         Op.getOperand(1), Op.getOperand(2), RoundingMode);
    }
    case BEXTRI: {
      assert(IntrData->Opc0 == X86ISD::BEXTR && "Unexpected opcode");

      // The control is a TargetConstant, but we need to convert it to a
      // ConstantSDNode.
      uint64_t Imm = Op.getConstantOperandVal(2);
      SDValue Control = DAG.getConstant(Imm, dl, Op.getValueType());
      return DAG.getNode(IntrData->Opc0, dl, Op.getValueType(),
                         Op.getOperand(1), Control);
    }
    // ADC/ADCX/SBB
    case ADX: {
      SDVTList CFVTs = DAG.getVTList(Op->getValueType(0), MVT::i32);
      SDVTList VTs = DAG.getVTList(Op.getOperand(2).getValueType(), MVT::i32);

      SDValue Res;
      // If the carry in is zero, then we should just use ADD/SUB instead of
      // ADC/SBB.
      if (isNullConstant(Op.getOperand(1))) {
        Res = DAG.getNode(IntrData->Opc1, dl, VTs, Op.getOperand(2),
                          Op.getOperand(3));
      } else {
        SDValue GenCF = DAG.getNode(X86ISD::ADD, dl, CFVTs, Op.getOperand(1),
                                    DAG.getConstant(-1, dl, MVT::i8));
        Res = DAG.getNode(IntrData->Opc0, dl, VTs, Op.getOperand(2),
                          Op.getOperand(3), GenCF.getValue(1));
      }
      SDValue SetCC = getSETCC(X86::COND_B, Res.getValue(1), dl, DAG);
      SDValue Results[] = { SetCC, Res };
      return DAG.getMergeValues(Results, dl);
    }
    case CVTPD2PS_MASK:
    case CVTPD2DQ_MASK:
    case CVTQQ2PS_MASK:
    case TRUNCATE_TO_REG: {
      SDValue Src = Op.getOperand(1);
      SDValue PassThru = Op.getOperand(2);
      SDValue Mask = Op.getOperand(3);

      if (isAllOnesConstant(Mask))
        return DAG.getNode(IntrData->Opc0, dl, Op.getValueType(), Src);

      MVT SrcVT = Src.getSimpleValueType();
      MVT MaskVT = MVT::getVectorVT(MVT::i1, SrcVT.getVectorNumElements());
      Mask = getMaskNode(Mask, MaskVT, Subtarget, DAG, dl);
      return DAG.getNode(IntrData->Opc1, dl, Op.getValueType(),
                         {Src, PassThru, Mask});
    }
    case CVTPS2PH_MASK: {
      SDValue Src = Op.getOperand(1);
      SDValue Rnd = Op.getOperand(2);
      SDValue PassThru = Op.getOperand(3);
      SDValue Mask = Op.getOperand(4);

      if (isAllOnesConstant(Mask))
        return DAG.getNode(IntrData->Opc0, dl, Op.getValueType(), Src, Rnd);

      MVT SrcVT = Src.getSimpleValueType();
      MVT MaskVT = MVT::getVectorVT(MVT::i1, SrcVT.getVectorNumElements());
      Mask = getMaskNode(Mask, MaskVT, Subtarget, DAG, dl);
      return DAG.getNode(IntrData->Opc1, dl, Op.getValueType(), Src, Rnd,
                         PassThru, Mask);

    }
    case CVTNEPS2BF16_MASK: {
      SDValue Src = Op.getOperand(1);
      SDValue PassThru = Op.getOperand(2);
      SDValue Mask = Op.getOperand(3);

      if (ISD::isBuildVectorAllOnes(Mask.getNode()))
        return DAG.getNode(IntrData->Opc0, dl, Op.getValueType(), Src);

      // Break false dependency.
      if (PassThru.isUndef())
        PassThru = DAG.getConstant(0, dl, PassThru.getValueType());

      return DAG.getNode(IntrData->Opc1, dl, Op.getValueType(), Src, PassThru,
                         Mask);
    }
    default:
      break;
    }
  }

  switch (IntNo) {
  default: return SDValue();    // Don't custom lower most intrinsics.

  // ptest and testp intrinsics. The intrinsic these come from are designed to
  // return an integer value, not just an instruction so lower it to the ptest
  // or testp pattern and a setcc for the result.
  case Intrinsic::x86_avx512_ktestc_b:
  case Intrinsic::x86_avx512_ktestc_w:
  case Intrinsic::x86_avx512_ktestc_d:
  case Intrinsic::x86_avx512_ktestc_q:
  case Intrinsic::x86_avx512_ktestz_b:
  case Intrinsic::x86_avx512_ktestz_w:
  case Intrinsic::x86_avx512_ktestz_d:
  case Intrinsic::x86_avx512_ktestz_q:
  case Intrinsic::x86_sse41_ptestz:
  case Intrinsic::x86_sse41_ptestc:
  case Intrinsic::x86_sse41_ptestnzc:
  case Intrinsic::x86_avx_ptestz_256:
  case Intrinsic::x86_avx_ptestc_256:
  case Intrinsic::x86_avx_ptestnzc_256:
  case Intrinsic::x86_avx_vtestz_ps:
  case Intrinsic::x86_avx_vtestc_ps:
  case Intrinsic::x86_avx_vtestnzc_ps:
  case Intrinsic::x86_avx_vtestz_pd:
  case Intrinsic::x86_avx_vtestc_pd:
  case Intrinsic::x86_avx_vtestnzc_pd:
  case Intrinsic::x86_avx_vtestz_ps_256:
  case Intrinsic::x86_avx_vtestc_ps_256:
  case Intrinsic::x86_avx_vtestnzc_ps_256:
  case Intrinsic::x86_avx_vtestz_pd_256:
  case Intrinsic::x86_avx_vtestc_pd_256:
  case Intrinsic::x86_avx_vtestnzc_pd_256: {
    unsigned TestOpc = X86ISD::PTEST;
    X86::CondCode X86CC;
    switch (IntNo) {
    default: llvm_unreachable("Bad fallthrough in Intrinsic lowering.");
    case Intrinsic::x86_avx512_ktestc_b:
    case Intrinsic::x86_avx512_ktestc_w:
    case Intrinsic::x86_avx512_ktestc_d:
    case Intrinsic::x86_avx512_ktestc_q:
      // CF = 1
      TestOpc = X86ISD::KTEST;
      X86CC = X86::COND_B;
      break;
    case Intrinsic::x86_avx512_ktestz_b:
    case Intrinsic::x86_avx512_ktestz_w:
    case Intrinsic::x86_avx512_ktestz_d:
    case Intrinsic::x86_avx512_ktestz_q:
      TestOpc = X86ISD::KTEST;
      X86CC = X86::COND_E;
      break;
    case Intrinsic::x86_avx_vtestz_ps:
    case Intrinsic::x86_avx_vtestz_pd:
    case Intrinsic::x86_avx_vtestz_ps_256:
    case Intrinsic::x86_avx_vtestz_pd_256:
      TestOpc = X86ISD::TESTP;
      LLVM_FALLTHROUGH;
    case Intrinsic::x86_sse41_ptestz:
    case Intrinsic::x86_avx_ptestz_256:
      // ZF = 1
      X86CC = X86::COND_E;
      break;
    case Intrinsic::x86_avx_vtestc_ps:
    case Intrinsic::x86_avx_vtestc_pd:
    case Intrinsic::x86_avx_vtestc_ps_256:
    case Intrinsic::x86_avx_vtestc_pd_256:
      TestOpc = X86ISD::TESTP;
      LLVM_FALLTHROUGH;
    case Intrinsic::x86_sse41_ptestc:
    case Intrinsic::x86_avx_ptestc_256:
      // CF = 1
      X86CC = X86::COND_B;
      break;
    case Intrinsic::x86_avx_vtestnzc_ps:
    case Intrinsic::x86_avx_vtestnzc_pd:
    case Intrinsic::x86_avx_vtestnzc_ps_256:
    case Intrinsic::x86_avx_vtestnzc_pd_256:
      TestOpc = X86ISD::TESTP;
      LLVM_FALLTHROUGH;
    case Intrinsic::x86_sse41_ptestnzc:
    case Intrinsic::x86_avx_ptestnzc_256:
      // ZF and CF = 0
      X86CC = X86::COND_A;
      break;
    }

    SDValue LHS = Op.getOperand(1);
    SDValue RHS = Op.getOperand(2);
    SDValue Test = DAG.getNode(TestOpc, dl, MVT::i32, LHS, RHS);
    SDValue SetCC = getSETCC(X86CC, Test, dl, DAG);
    return DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, SetCC);
  }

  case Intrinsic::x86_sse42_pcmpistria128:
  case Intrinsic::x86_sse42_pcmpestria128:
  case Intrinsic::x86_sse42_pcmpistric128:
  case Intrinsic::x86_sse42_pcmpestric128:
  case Intrinsic::x86_sse42_pcmpistrio128:
  case Intrinsic::x86_sse42_pcmpestrio128:
  case Intrinsic::x86_sse42_pcmpistris128:
  case Intrinsic::x86_sse42_pcmpestris128:
  case Intrinsic::x86_sse42_pcmpistriz128:
  case Intrinsic::x86_sse42_pcmpestriz128: {
    unsigned Opcode;
    X86::CondCode X86CC;
    switch (IntNo) {
    default: llvm_unreachable("Impossible intrinsic");  // Can't reach here.
    case Intrinsic::x86_sse42_pcmpistria128:
      Opcode = X86ISD::PCMPISTR;
      X86CC = X86::COND_A;
      break;
    case Intrinsic::x86_sse42_pcmpestria128:
      Opcode = X86ISD::PCMPESTR;
      X86CC = X86::COND_A;
      break;
    case Intrinsic::x86_sse42_pcmpistric128:
      Opcode = X86ISD::PCMPISTR;
      X86CC = X86::COND_B;
      break;
    case Intrinsic::x86_sse42_pcmpestric128:
      Opcode = X86ISD::PCMPESTR;
      X86CC = X86::COND_B;
      break;
    case Intrinsic::x86_sse42_pcmpistrio128:
      Opcode = X86ISD::PCMPISTR;
      X86CC = X86::COND_O;
      break;
    case Intrinsic::x86_sse42_pcmpestrio128:
      Opcode = X86ISD::PCMPESTR;
      X86CC = X86::COND_O;
      break;
    case Intrinsic::x86_sse42_pcmpistris128:
      Opcode = X86ISD::PCMPISTR;
      X86CC = X86::COND_S;
      break;
    case Intrinsic::x86_sse42_pcmpestris128:
      Opcode = X86ISD::PCMPESTR;
      X86CC = X86::COND_S;
      break;
    case Intrinsic::x86_sse42_pcmpistriz128:
      Opcode = X86ISD::PCMPISTR;
      X86CC = X86::COND_E;
      break;
    case Intrinsic::x86_sse42_pcmpestriz128:
      Opcode = X86ISD::PCMPESTR;
      X86CC = X86::COND_E;
      break;
    }
    SmallVector<SDValue, 5> NewOps(Op->op_begin()+1, Op->op_end());
    SDVTList VTs = DAG.getVTList(MVT::i32, MVT::v16i8, MVT::i32);
    SDValue PCMP = DAG.getNode(Opcode, dl, VTs, NewOps).getValue(2);
    SDValue SetCC = getSETCC(X86CC, PCMP, dl, DAG);
    return DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, SetCC);
  }

  case Intrinsic::x86_sse42_pcmpistri128:
  case Intrinsic::x86_sse42_pcmpestri128: {
    unsigned Opcode;
    if (IntNo == Intrinsic::x86_sse42_pcmpistri128)
      Opcode = X86ISD::PCMPISTR;
    else
      Opcode = X86ISD::PCMPESTR;

    SmallVector<SDValue, 5> NewOps(Op->op_begin()+1, Op->op_end());
    SDVTList VTs = DAG.getVTList(MVT::i32, MVT::v16i8, MVT::i32);
    return DAG.getNode(Opcode, dl, VTs, NewOps);
  }

  case Intrinsic::x86_sse42_pcmpistrm128:
  case Intrinsic::x86_sse42_pcmpestrm128: {
    unsigned Opcode;
    if (IntNo == Intrinsic::x86_sse42_pcmpistrm128)
      Opcode = X86ISD::PCMPISTR;
    else
      Opcode = X86ISD::PCMPESTR;

    SmallVector<SDValue, 5> NewOps(Op->op_begin()+1, Op->op_end());
    SDVTList VTs = DAG.getVTList(MVT::i32, MVT::v16i8, MVT::i32);
    return DAG.getNode(Opcode, dl, VTs, NewOps).getValue(1);
  }

  case Intrinsic::eh_sjlj_lsda: {
    MachineFunction &MF = DAG.getMachineFunction();
    const TargetLowering &TLI = DAG.getTargetLoweringInfo();
    MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
    auto &Context = MF.getMMI().getContext();
    MCSymbol *S = Context.getOrCreateSymbol(Twine("GCC_except_table") +
                                            Twine(MF.getFunctionNumber()));
    return DAG.getNode(getGlobalWrapperKind(), dl, VT,
                       DAG.getMCSymbol(S, PtrVT));
  }

  case Intrinsic::x86_seh_lsda: {
    // Compute the symbol for the LSDA. We know it'll get emitted later.
    MachineFunction &MF = DAG.getMachineFunction();
    SDValue Op1 = Op.getOperand(1);
    auto *Fn = cast<Function>(cast<GlobalAddressSDNode>(Op1)->getGlobal());
    MCSymbol *LSDASym = MF.getMMI().getContext().getOrCreateLSDASymbol(
        GlobalValue::dropLLVMManglingEscape(Fn->getName()));

    // Generate a simple absolute symbol reference. This intrinsic is only
    // supported on 32-bit Windows, which isn't PIC.
    SDValue Result = DAG.getMCSymbol(LSDASym, VT);
    return DAG.getNode(X86ISD::Wrapper, dl, VT, Result);
  }

  case Intrinsic::eh_recoverfp: {
    SDValue FnOp = Op.getOperand(1);
    SDValue IncomingFPOp = Op.getOperand(2);
    GlobalAddressSDNode *GSD = dyn_cast<GlobalAddressSDNode>(FnOp);
    auto *Fn = dyn_cast_or_null<Function>(GSD ? GSD->getGlobal() : nullptr);
    if (!Fn)
      report_fatal_error(
          "llvm.eh.recoverfp must take a function as the first argument");
    return recoverFramePointer(DAG, Fn, IncomingFPOp);
  }

  case Intrinsic::localaddress: {
    // Returns one of the stack, base, or frame pointer registers, depending on
    // which is used to reference local variables.
    MachineFunction &MF = DAG.getMachineFunction();
    const X86RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
    unsigned Reg;
    if (RegInfo->hasBasePointer(MF))
      Reg = RegInfo->getBaseRegister();
    else { // Handles the SP or FP case.
      bool CantUseFP = RegInfo->needsStackRealignment(MF);
      if (CantUseFP)
        Reg = RegInfo->getPtrSizedStackRegister(MF);
      else
        Reg = RegInfo->getPtrSizedFrameRegister(MF);
    }
    return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, VT);
  }

  case Intrinsic::x86_avx512_vp2intersect_q_512:
  case Intrinsic::x86_avx512_vp2intersect_q_256:
  case Intrinsic::x86_avx512_vp2intersect_q_128:
  case Intrinsic::x86_avx512_vp2intersect_d_512:
  case Intrinsic::x86_avx512_vp2intersect_d_256:
  case Intrinsic::x86_avx512_vp2intersect_d_128: {
    MVT MaskVT = Op.getSimpleValueType();

    SDVTList VTs = DAG.getVTList(MVT::Untyped, MVT::Other);
    SDLoc DL(Op);

    SDValue Operation =
        DAG.getNode(X86ISD::VP2INTERSECT, DL, VTs,
                    Op->getOperand(1), Op->getOperand(2));

    SDValue Result0 = DAG.getTargetExtractSubreg(X86::sub_mask_0, DL,
                                                 MaskVT, Operation);
    SDValue Result1 = DAG.getTargetExtractSubreg(X86::sub_mask_1, DL,
                                                 MaskVT, Operation);
    return DAG.getMergeValues({Result0, Result1}, DL);
  }
  case Intrinsic::x86_mmx_pslli_w:
  case Intrinsic::x86_mmx_pslli_d:
  case Intrinsic::x86_mmx_pslli_q:
  case Intrinsic::x86_mmx_psrli_w:
  case Intrinsic::x86_mmx_psrli_d:
  case Intrinsic::x86_mmx_psrli_q:
  case Intrinsic::x86_mmx_psrai_w:
  case Intrinsic::x86_mmx_psrai_d: {
    SDLoc DL(Op);
    SDValue ShAmt = Op.getOperand(2);
    // If the argument is a constant, convert it to a target constant.
    if (auto *C = dyn_cast<ConstantSDNode>(ShAmt)) {
      // Clamp out of bounds shift amounts since they will otherwise be masked
      // to 8-bits which may make it no longer out of bounds.
      unsigned ShiftAmount = C->getAPIntValue().getLimitedValue(255);
      return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, Op.getValueType(),
                         Op.getOperand(0), Op.getOperand(1),
                         DAG.getTargetConstant(ShiftAmount, DL, MVT::i32));
    }

    unsigned NewIntrinsic;
    switch (IntNo) {
    default: llvm_unreachable("Impossible intrinsic");  // Can't reach here.
    case Intrinsic::x86_mmx_pslli_w:
      NewIntrinsic = Intrinsic::x86_mmx_psll_w;
      break;
    case Intrinsic::x86_mmx_pslli_d:
      NewIntrinsic = Intrinsic::x86_mmx_psll_d;
      break;
    case Intrinsic::x86_mmx_pslli_q:
      NewIntrinsic = Intrinsic::x86_mmx_psll_q;
      break;
    case Intrinsic::x86_mmx_psrli_w:
      NewIntrinsic = Intrinsic::x86_mmx_psrl_w;
      break;
    case Intrinsic::x86_mmx_psrli_d:
      NewIntrinsic = Intrinsic::x86_mmx_psrl_d;
      break;
    case Intrinsic::x86_mmx_psrli_q:
      NewIntrinsic = Intrinsic::x86_mmx_psrl_q;
      break;
    case Intrinsic::x86_mmx_psrai_w:
      NewIntrinsic = Intrinsic::x86_mmx_psra_w;
      break;
    case Intrinsic::x86_mmx_psrai_d:
      NewIntrinsic = Intrinsic::x86_mmx_psra_d;
      break;
    }

    // The vector shift intrinsics with scalars uses 32b shift amounts but
    // the sse2/mmx shift instructions reads 64 bits. Copy the 32 bits to an
    // MMX register.
    ShAmt = DAG.getNode(X86ISD::MMX_MOVW2D, DL, MVT::x86mmx, ShAmt);
    return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, Op.getValueType(),
                       DAG.getConstant(NewIntrinsic, DL, MVT::i32),
                       Op.getOperand(1), ShAmt);

  }
  }
}

static SDValue getAVX2GatherNode(unsigned Opc, SDValue Op, SelectionDAG &DAG,
                                 SDValue Src, SDValue Mask, SDValue Base,
                                 SDValue Index, SDValue ScaleOp, SDValue Chain,
                                 const X86Subtarget &Subtarget) {
  SDLoc dl(Op);
  auto *C = dyn_cast<ConstantSDNode>(ScaleOp);
  // Scale must be constant.
  if (!C)
    return SDValue();
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  SDValue Scale = DAG.getTargetConstant(C->getZExtValue(), dl,
                                        TLI.getPointerTy(DAG.getDataLayout()));
  EVT MaskVT = Mask.getValueType().changeVectorElementTypeToInteger();
  SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Other);
  // If source is undef or we know it won't be used, use a zero vector
  // to break register dependency.
  // TODO: use undef instead and let BreakFalseDeps deal with it?
  if (Src.isUndef() || ISD::isBuildVectorAllOnes(Mask.getNode()))
    Src = getZeroVector(Op.getSimpleValueType(), Subtarget, DAG, dl);

  // Cast mask to an integer type.
  Mask = DAG.getBitcast(MaskVT, Mask);

  MemIntrinsicSDNode *MemIntr = cast<MemIntrinsicSDNode>(Op);

  SDValue Ops[] = {Chain, Src, Mask, Base, Index, Scale };
  SDValue Res =
      DAG.getMemIntrinsicNode(X86ISD::MGATHER, dl, VTs, Ops,
                              MemIntr->getMemoryVT(), MemIntr->getMemOperand());
  return DAG.getMergeValues({Res, Res.getValue(1)}, dl);
}

static SDValue getGatherNode(SDValue Op, SelectionDAG &DAG,
                             SDValue Src, SDValue Mask, SDValue Base,
                             SDValue Index, SDValue ScaleOp, SDValue Chain,
                             const X86Subtarget &Subtarget) {
  MVT VT = Op.getSimpleValueType();
  SDLoc dl(Op);
  auto *C = dyn_cast<ConstantSDNode>(ScaleOp);
  // Scale must be constant.
  if (!C)
    return SDValue();
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  SDValue Scale = DAG.getTargetConstant(C->getZExtValue(), dl,
                                        TLI.getPointerTy(DAG.getDataLayout()));
  unsigned MinElts = std::min(Index.getSimpleValueType().getVectorNumElements(),
                              VT.getVectorNumElements());
  MVT MaskVT = MVT::getVectorVT(MVT::i1, MinElts);

  // We support two versions of the gather intrinsics. One with scalar mask and
  // one with vXi1 mask. Convert scalar to vXi1 if necessary.
  if (Mask.getValueType() != MaskVT)
    Mask = getMaskNode(Mask, MaskVT, Subtarget, DAG, dl);

  SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Other);
  // If source is undef or we know it won't be used, use a zero vector
  // to break register dependency.
  // TODO: use undef instead and let BreakFalseDeps deal with it?
  if (Src.isUndef() || ISD::isBuildVectorAllOnes(Mask.getNode()))
    Src = getZeroVector(Op.getSimpleValueType(), Subtarget, DAG, dl);

  MemIntrinsicSDNode *MemIntr = cast<MemIntrinsicSDNode>(Op);

  SDValue Ops[] = {Chain, Src, Mask, Base, Index, Scale };
  SDValue Res =
      DAG.getMemIntrinsicNode(X86ISD::MGATHER, dl, VTs, Ops,
                              MemIntr->getMemoryVT(), MemIntr->getMemOperand());
  return DAG.getMergeValues({Res, Res.getValue(1)}, dl);
}

static SDValue getScatterNode(unsigned Opc, SDValue Op, SelectionDAG &DAG,
                               SDValue Src, SDValue Mask, SDValue Base,
                               SDValue Index, SDValue ScaleOp, SDValue Chain,
                               const X86Subtarget &Subtarget) {
  SDLoc dl(Op);
  auto *C = dyn_cast<ConstantSDNode>(ScaleOp);
  // Scale must be constant.
  if (!C)
    return SDValue();
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  SDValue Scale = DAG.getTargetConstant(C->getZExtValue(), dl,
                                        TLI.getPointerTy(DAG.getDataLayout()));
  unsigned MinElts = std::min(Index.getSimpleValueType().getVectorNumElements(),
                              Src.getSimpleValueType().getVectorNumElements());
  MVT MaskVT = MVT::getVectorVT(MVT::i1, MinElts);

  // We support two versions of the scatter intrinsics. One with scalar mask and
  // one with vXi1 mask. Convert scalar to vXi1 if necessary.
  if (Mask.getValueType() != MaskVT)
    Mask = getMaskNode(Mask, MaskVT, Subtarget, DAG, dl);

  MemIntrinsicSDNode *MemIntr = cast<MemIntrinsicSDNode>(Op);

  SDVTList VTs = DAG.getVTList(MVT::Other);
  SDValue Ops[] = {Chain, Src, Mask, Base, Index, Scale};
  SDValue Res =
      DAG.getMemIntrinsicNode(X86ISD::MSCATTER, dl, VTs, Ops,
                              MemIntr->getMemoryVT(), MemIntr->getMemOperand());
  return Res;
}

static SDValue getPrefetchNode(unsigned Opc, SDValue Op, SelectionDAG &DAG,
                               SDValue Mask, SDValue Base, SDValue Index,
                               SDValue ScaleOp, SDValue Chain,
                               const X86Subtarget &Subtarget) {
  SDLoc dl(Op);
  auto *C = dyn_cast<ConstantSDNode>(ScaleOp);
  // Scale must be constant.
  if (!C)
    return SDValue();
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  SDValue Scale = DAG.getTargetConstant(C->getZExtValue(), dl,
                                        TLI.getPointerTy(DAG.getDataLayout()));
  SDValue Disp = DAG.getTargetConstant(0, dl, MVT::i32);
  SDValue Segment = DAG.getRegister(0, MVT::i32);
  MVT MaskVT =
    MVT::getVectorVT(MVT::i1, Index.getSimpleValueType().getVectorNumElements());
  SDValue VMask = getMaskNode(Mask, MaskVT, Subtarget, DAG, dl);
  SDValue Ops[] = {VMask, Base, Scale, Index, Disp, Segment, Chain};
  SDNode *Res = DAG.getMachineNode(Opc, dl, MVT::Other, Ops);
  return SDValue(Res, 0);
}

/// Handles the lowering of builtin intrinsics with chain that return their
/// value into registers EDX:EAX.
/// If operand ScrReg is a valid register identifier, then operand 2 of N is
/// copied to SrcReg. The assumption is that SrcReg is an implicit input to
/// TargetOpcode.
/// Returns a Glue value which can be used to add extra copy-from-reg if the
/// expanded intrinsics implicitly defines extra registers (i.e. not just
/// EDX:EAX).
static SDValue expandIntrinsicWChainHelper(SDNode *N, const SDLoc &DL,
                                        SelectionDAG &DAG,
                                        unsigned TargetOpcode,
                                        unsigned SrcReg,
                                        const X86Subtarget &Subtarget,
                                        SmallVectorImpl<SDValue> &Results) {
  SDValue Chain = N->getOperand(0);
  SDValue Glue;

  if (SrcReg) {
    assert(N->getNumOperands() == 3 && "Unexpected number of operands!");
    Chain = DAG.getCopyToReg(Chain, DL, SrcReg, N->getOperand(2), Glue);
    Glue = Chain.getValue(1);
  }

  SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Glue);
  SDValue N1Ops[] = {Chain, Glue};
  SDNode *N1 = DAG.getMachineNode(
      TargetOpcode, DL, Tys, ArrayRef<SDValue>(N1Ops, Glue.getNode() ? 2 : 1));
  Chain = SDValue(N1, 0);

  // Reads the content of XCR and returns it in registers EDX:EAX.
  SDValue LO, HI;
  if (Subtarget.is64Bit()) {
    LO = DAG.getCopyFromReg(Chain, DL, X86::RAX, MVT::i64, SDValue(N1, 1));
    HI = DAG.getCopyFromReg(LO.getValue(1), DL, X86::RDX, MVT::i64,
                            LO.getValue(2));
  } else {
    LO = DAG.getCopyFromReg(Chain, DL, X86::EAX, MVT::i32, SDValue(N1, 1));
    HI = DAG.getCopyFromReg(LO.getValue(1), DL, X86::EDX, MVT::i32,
                            LO.getValue(2));
  }
  Chain = HI.getValue(1);
  Glue = HI.getValue(2);

  if (Subtarget.is64Bit()) {
    // Merge the two 32-bit values into a 64-bit one.
    SDValue Tmp = DAG.getNode(ISD::SHL, DL, MVT::i64, HI,
                              DAG.getConstant(32, DL, MVT::i8));
    Results.push_back(DAG.getNode(ISD::OR, DL, MVT::i64, LO, Tmp));
    Results.push_back(Chain);
    return Glue;
  }

  // Use a buildpair to merge the two 32-bit values into a 64-bit one.
  SDValue Ops[] = { LO, HI };
  SDValue Pair = DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Ops);
  Results.push_back(Pair);
  Results.push_back(Chain);
  return Glue;
}

/// Handles the lowering of builtin intrinsics that read the time stamp counter
/// (x86_rdtsc and x86_rdtscp). This function is also used to custom lower
/// READCYCLECOUNTER nodes.
static void getReadTimeStampCounter(SDNode *N, const SDLoc &DL, unsigned Opcode,
                                    SelectionDAG &DAG,
                                    const X86Subtarget &Subtarget,
                                    SmallVectorImpl<SDValue> &Results) {
  // The processor's time-stamp counter (a 64-bit MSR) is stored into the
  // EDX:EAX registers. EDX is loaded with the high-order 32 bits of the MSR
  // and the EAX register is loaded with the low-order 32 bits.
  SDValue Glue = expandIntrinsicWChainHelper(N, DL, DAG, Opcode,
                                             /* NoRegister */0, Subtarget,
                                             Results);
  if (Opcode != X86::RDTSCP)
    return;

  SDValue Chain = Results[1];
  // Instruction RDTSCP loads the IA32:TSC_AUX_MSR (address C000_0103H) into
  // the ECX register. Add 'ecx' explicitly to the chain.
  SDValue ecx = DAG.getCopyFromReg(Chain, DL, X86::ECX, MVT::i32, Glue);
  Results[1] = ecx;
  Results.push_back(ecx.getValue(1));
}

static SDValue LowerREADCYCLECOUNTER(SDValue Op, const X86Subtarget &Subtarget,
                                     SelectionDAG &DAG) {
  SmallVector<SDValue, 3> Results;
  SDLoc DL(Op);
  getReadTimeStampCounter(Op.getNode(), DL, X86::RDTSC, DAG, Subtarget,
                          Results);
  return DAG.getMergeValues(Results, DL);
}

static SDValue MarkEHRegistrationNode(SDValue Op, SelectionDAG &DAG) {
  MachineFunction &MF = DAG.getMachineFunction();
  SDValue Chain = Op.getOperand(0);
  SDValue RegNode = Op.getOperand(2);
  WinEHFuncInfo *EHInfo = MF.getWinEHFuncInfo();
  if (!EHInfo)
    report_fatal_error("EH registrations only live in functions using WinEH");

  // Cast the operand to an alloca, and remember the frame index.
  auto *FINode = dyn_cast<FrameIndexSDNode>(RegNode);
  if (!FINode)
    report_fatal_error("llvm.x86.seh.ehregnode expects a static alloca");
  EHInfo->EHRegNodeFrameIndex = FINode->getIndex();

  // Return the chain operand without making any DAG nodes.
  return Chain;
}

static SDValue MarkEHGuard(SDValue Op, SelectionDAG &DAG) {
  MachineFunction &MF = DAG.getMachineFunction();
  SDValue Chain = Op.getOperand(0);
  SDValue EHGuard = Op.getOperand(2);
  WinEHFuncInfo *EHInfo = MF.getWinEHFuncInfo();
  if (!EHInfo)
    report_fatal_error("EHGuard only live in functions using WinEH");

  // Cast the operand to an alloca, and remember the frame index.
  auto *FINode = dyn_cast<FrameIndexSDNode>(EHGuard);
  if (!FINode)
    report_fatal_error("llvm.x86.seh.ehguard expects a static alloca");
  EHInfo->EHGuardFrameIndex = FINode->getIndex();

  // Return the chain operand without making any DAG nodes.
  return Chain;
}

/// Emit Truncating Store with signed or unsigned saturation.
static SDValue
EmitTruncSStore(bool SignedSat, SDValue Chain, const SDLoc &Dl, SDValue Val,
                SDValue Ptr, EVT MemVT, MachineMemOperand *MMO,
                SelectionDAG &DAG) {
  SDVTList VTs = DAG.getVTList(MVT::Other);
  SDValue Undef = DAG.getUNDEF(Ptr.getValueType());
  SDValue Ops[] = { Chain, Val, Ptr, Undef };
  unsigned Opc = SignedSat ? X86ISD::VTRUNCSTORES : X86ISD::VTRUNCSTOREUS;
  return DAG.getMemIntrinsicNode(Opc, Dl, VTs, Ops, MemVT, MMO);
}

/// Emit Masked Truncating Store with signed or unsigned saturation.
static SDValue
EmitMaskedTruncSStore(bool SignedSat, SDValue Chain, const SDLoc &Dl,
                      SDValue Val, SDValue Ptr, SDValue Mask, EVT MemVT,
                      MachineMemOperand *MMO, SelectionDAG &DAG) {
  SDVTList VTs = DAG.getVTList(MVT::Other);
  SDValue Ops[] = { Chain, Val, Ptr, Mask };
  unsigned Opc = SignedSat ? X86ISD::VMTRUNCSTORES : X86ISD::VMTRUNCSTOREUS;
  return DAG.getMemIntrinsicNode(Opc, Dl, VTs, Ops, MemVT, MMO);
}

static SDValue LowerINTRINSIC_W_CHAIN(SDValue Op, const X86Subtarget &Subtarget,
                                      SelectionDAG &DAG) {
  unsigned IntNo = Op.getConstantOperandVal(1);
  const IntrinsicData *IntrData = getIntrinsicWithChain(IntNo);
  if (!IntrData) {
    switch (IntNo) {
    case llvm::Intrinsic::x86_seh_ehregnode:
      return MarkEHRegistrationNode(Op, DAG);
    case llvm::Intrinsic::x86_seh_ehguard:
      return MarkEHGuard(Op, DAG);
    case llvm::Intrinsic::x86_rdpkru: {
      SDLoc dl(Op);
      SDVTList VTs = DAG.getVTList(MVT::i32, MVT::Other);
      // Create a RDPKRU node and pass 0 to the ECX parameter.
      return DAG.getNode(X86ISD::RDPKRU, dl, VTs, Op.getOperand(0),
                         DAG.getConstant(0, dl, MVT::i32));
    }
    case llvm::Intrinsic::x86_wrpkru: {
      SDLoc dl(Op);
      // Create a WRPKRU node, pass the input to the EAX parameter,  and pass 0
      // to the EDX and ECX parameters.
      return DAG.getNode(X86ISD::WRPKRU, dl, MVT::Other,
                         Op.getOperand(0), Op.getOperand(2),
                         DAG.getConstant(0, dl, MVT::i32),
                         DAG.getConstant(0, dl, MVT::i32));
    }
    case llvm::Intrinsic::x86_flags_read_u32:
    case llvm::Intrinsic::x86_flags_read_u64:
    case llvm::Intrinsic::x86_flags_write_u32:
    case llvm::Intrinsic::x86_flags_write_u64: {
      // We need a frame pointer because this will get lowered to a PUSH/POP
      // sequence.
      MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
      MFI.setHasCopyImplyingStackAdjustment(true);
      // Don't do anything here, we will expand these intrinsics out later
      // during FinalizeISel in EmitInstrWithCustomInserter.
      return Op;
    }
    case Intrinsic::x86_lwpins32:
    case Intrinsic::x86_lwpins64:
    case Intrinsic::x86_umwait:
    case Intrinsic::x86_tpause: {
      SDLoc dl(Op);
      SDValue Chain = Op->getOperand(0);
      SDVTList VTs = DAG.getVTList(MVT::i32, MVT::Other);
      unsigned Opcode;

      switch (IntNo) {
      default: llvm_unreachable("Impossible intrinsic");
      case Intrinsic::x86_umwait:
        Opcode = X86ISD::UMWAIT;
        break;
      case Intrinsic::x86_tpause:
        Opcode = X86ISD::TPAUSE;
        break;
      case Intrinsic::x86_lwpins32:
      case Intrinsic::x86_lwpins64:
        Opcode = X86ISD::LWPINS;
        break;
      }

      SDValue Operation =
          DAG.getNode(Opcode, dl, VTs, Chain, Op->getOperand(2),
                      Op->getOperand(3), Op->getOperand(4));
      SDValue SetCC = getSETCC(X86::COND_B, Operation.getValue(0), dl, DAG);
      return DAG.getNode(ISD::MERGE_VALUES, dl, Op->getVTList(), SetCC,
                         Operation.getValue(1));
    }
    case Intrinsic::x86_enqcmd:
    case Intrinsic::x86_enqcmds: {
      SDLoc dl(Op);
      SDValue Chain = Op.getOperand(0);
      SDVTList VTs = DAG.getVTList(MVT::i32, MVT::Other);
      unsigned Opcode;
      switch (IntNo) {
      default: llvm_unreachable("Impossible intrinsic!");
      case Intrinsic::x86_enqcmd:
        Opcode = X86ISD::ENQCMD;
        break;
      case Intrinsic::x86_enqcmds:
        Opcode = X86ISD::ENQCMDS;
        break;
      }
      SDValue Operation = DAG.getNode(Opcode, dl, VTs, Chain, Op.getOperand(2),
                                      Op.getOperand(3));
      SDValue SetCC = getSETCC(X86::COND_E, Operation.getValue(0), dl, DAG);
      return DAG.getNode(ISD::MERGE_VALUES, dl, Op->getVTList(), SetCC,
                         Operation.getValue(1));
    }
    }
    return SDValue();
  }

  SDLoc dl(Op);
  switch(IntrData->Type) {
  default: llvm_unreachable("Unknown Intrinsic Type");
  case RDSEED:
  case RDRAND: {
    // Emit the node with the right value type.
    SDVTList VTs = DAG.getVTList(Op->getValueType(0), MVT::i32, MVT::Other);
    SDValue Result = DAG.getNode(IntrData->Opc0, dl, VTs, Op.getOperand(0));

    // If the value returned by RDRAND/RDSEED was valid (CF=1), return 1.
    // Otherwise return the value from Rand, which is always 0, casted to i32.
    SDValue Ops[] = {DAG.getZExtOrTrunc(Result, dl, Op->getValueType(1)),
                     DAG.getConstant(1, dl, Op->getValueType(1)),
                     DAG.getTargetConstant(X86::COND_B, dl, MVT::i8),
                     SDValue(Result.getNode(), 1)};
    SDValue isValid = DAG.getNode(X86ISD::CMOV, dl, Op->getValueType(1), Ops);

    // Return { result, isValid, chain }.
    return DAG.getNode(ISD::MERGE_VALUES, dl, Op->getVTList(), Result, isValid,
                       SDValue(Result.getNode(), 2));
  }
  case GATHER_AVX2: {
    SDValue Chain = Op.getOperand(0);
    SDValue Src   = Op.getOperand(2);
    SDValue Base  = Op.getOperand(3);
    SDValue Index = Op.getOperand(4);
    SDValue Mask  = Op.getOperand(5);
    SDValue Scale = Op.getOperand(6);
    return getAVX2GatherNode(IntrData->Opc0, Op, DAG, Src, Mask, Base, Index,
                             Scale, Chain, Subtarget);
  }
  case GATHER: {
  //gather(v1, mask, index, base, scale);
    SDValue Chain = Op.getOperand(0);
    SDValue Src   = Op.getOperand(2);
    SDValue Base  = Op.getOperand(3);
    SDValue Index = Op.getOperand(4);
    SDValue Mask  = Op.getOperand(5);
    SDValue Scale = Op.getOperand(6);
    return getGatherNode(Op, DAG, Src, Mask, Base, Index, Scale,
                         Chain, Subtarget);
  }
  case SCATTER: {
  //scatter(base, mask, index, v1, scale);
    SDValue Chain = Op.getOperand(0);
    SDValue Base  = Op.getOperand(2);
    SDValue Mask  = Op.getOperand(3);
    SDValue Index = Op.getOperand(4);
    SDValue Src   = Op.getOperand(5);
    SDValue Scale = Op.getOperand(6);
    return getScatterNode(IntrData->Opc0, Op, DAG, Src, Mask, Base, Index,
                          Scale, Chain, Subtarget);
  }
  case PREFETCH: {
    const APInt &HintVal = Op.getConstantOperandAPInt(6);
    assert((HintVal == 2 || HintVal == 3) &&
           "Wrong prefetch hint in intrinsic: should be 2 or 3");
    unsigned Opcode = (HintVal == 2 ? IntrData->Opc1 : IntrData->Opc0);
    SDValue Chain = Op.getOperand(0);
    SDValue Mask  = Op.getOperand(2);
    SDValue Index = Op.getOperand(3);
    SDValue Base  = Op.getOperand(4);
    SDValue Scale = Op.getOperand(5);
    return getPrefetchNode(Opcode, Op, DAG, Mask, Base, Index, Scale, Chain,
                           Subtarget);
  }
  // Read Time Stamp Counter (RDTSC) and Processor ID (RDTSCP).
  case RDTSC: {
    SmallVector<SDValue, 2> Results;
    getReadTimeStampCounter(Op.getNode(), dl, IntrData->Opc0, DAG, Subtarget,
                            Results);
    return DAG.getMergeValues(Results, dl);
  }
  // Read Performance Monitoring Counters.
  case RDPMC:
  // GetExtended Control Register.
  case XGETBV: {
    SmallVector<SDValue, 2> Results;

    // RDPMC uses ECX to select the index of the performance counter to read.
    // XGETBV uses ECX to select the index of the XCR register to return.
    // The result is stored into registers EDX:EAX.
    expandIntrinsicWChainHelper(Op.getNode(), dl, DAG, IntrData->Opc0, X86::ECX,
                                Subtarget, Results);
    return DAG.getMergeValues(Results, dl);
  }
  // XTEST intrinsics.
  case XTEST: {
    SDVTList VTs = DAG.getVTList(Op->getValueType(0), MVT::Other);
    SDValue InTrans = DAG.getNode(IntrData->Opc0, dl, VTs, Op.getOperand(0));

    SDValue SetCC = getSETCC(X86::COND_NE, InTrans, dl, DAG);
    SDValue Ret = DAG.getNode(ISD::ZERO_EXTEND, dl, Op->getValueType(0), SetCC);
    return DAG.getNode(ISD::MERGE_VALUES, dl, Op->getVTList(),
                       Ret, SDValue(InTrans.getNode(), 1));
  }
  case TRUNCATE_TO_MEM_VI8:
  case TRUNCATE_TO_MEM_VI16:
  case TRUNCATE_TO_MEM_VI32: {
    SDValue Mask = Op.getOperand(4);
    SDValue DataToTruncate = Op.getOperand(3);
    SDValue Addr = Op.getOperand(2);
    SDValue Chain = Op.getOperand(0);

    MemIntrinsicSDNode *MemIntr = dyn_cast<MemIntrinsicSDNode>(Op);
    assert(MemIntr && "Expected MemIntrinsicSDNode!");

    EVT MemVT  = MemIntr->getMemoryVT();

    uint16_t TruncationOp = IntrData->Opc0;
    switch (TruncationOp) {
    case X86ISD::VTRUNC: {
      if (isAllOnesConstant(Mask)) // return just a truncate store
        return DAG.getTruncStore(Chain, dl, DataToTruncate, Addr, MemVT,
                                 MemIntr->getMemOperand());

      MVT MaskVT = MVT::getVectorVT(MVT::i1, MemVT.getVectorNumElements());
      SDValue VMask = getMaskNode(Mask, MaskVT, Subtarget, DAG, dl);
      SDValue Offset = DAG.getUNDEF(VMask.getValueType());

      return DAG.getMaskedStore(Chain, dl, DataToTruncate, Addr, Offset, VMask,
                                MemVT, MemIntr->getMemOperand(), ISD::UNINDEXED,
                                true /* truncating */);
    }
    case X86ISD::VTRUNCUS:
    case X86ISD::VTRUNCS: {
      bool IsSigned = (TruncationOp == X86ISD::VTRUNCS);
      if (isAllOnesConstant(Mask))
        return EmitTruncSStore(IsSigned, Chain, dl, DataToTruncate, Addr, MemVT,
                               MemIntr->getMemOperand(), DAG);

      MVT MaskVT = MVT::getVectorVT(MVT::i1, MemVT.getVectorNumElements());
      SDValue VMask = getMaskNode(Mask, MaskVT, Subtarget, DAG, dl);

      return EmitMaskedTruncSStore(IsSigned, Chain, dl, DataToTruncate, Addr,
                                   VMask, MemVT, MemIntr->getMemOperand(), DAG);
    }
    default:
      llvm_unreachable("Unsupported truncstore intrinsic");
    }
  }
  }
}

SDValue X86TargetLowering::LowerRETURNADDR(SDValue Op,
                                           SelectionDAG &DAG) const {
  MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
  MFI.setReturnAddressIsTaken(true);

  if (verifyReturnAddressArgumentIsConstant(Op, DAG))
    return SDValue();

  unsigned Depth = Op.getConstantOperandVal(0);
  SDLoc dl(Op);
  EVT PtrVT = getPointerTy(DAG.getDataLayout());

  if (Depth > 0) {
    SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
    const X86RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
    SDValue Offset = DAG.getConstant(RegInfo->getSlotSize(), dl, PtrVT);
    return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(),
                       DAG.getNode(ISD::ADD, dl, PtrVT, FrameAddr, Offset),
                       MachinePointerInfo());
  }

  // Just load the return address.
  SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
  return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), RetAddrFI,
                     MachinePointerInfo());
}

SDValue X86TargetLowering::LowerADDROFRETURNADDR(SDValue Op,
                                                 SelectionDAG &DAG) const {
  DAG.getMachineFunction().getFrameInfo().setReturnAddressIsTaken(true);
  return getReturnAddressFrameIndex(DAG);
}

SDValue X86TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
  MachineFunction &MF = DAG.getMachineFunction();
  MachineFrameInfo &MFI = MF.getFrameInfo();
  X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();
  const X86RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
  EVT VT = Op.getValueType();

  MFI.setFrameAddressIsTaken(true);

  if (MF.getTarget().getMCAsmInfo()->usesWindowsCFI()) {
    // Depth > 0 makes no sense on targets which use Windows unwind codes.  It
    // is not possible to crawl up the stack without looking at the unwind codes
    // simultaneously.
    int FrameAddrIndex = FuncInfo->getFAIndex();
    if (!FrameAddrIndex) {
      // Set up a frame object for the return address.
      unsigned SlotSize = RegInfo->getSlotSize();
      FrameAddrIndex = MF.getFrameInfo().CreateFixedObject(
          SlotSize, /*SPOffset=*/0, /*IsImmutable=*/false);
      FuncInfo->setFAIndex(FrameAddrIndex);
    }
    return DAG.getFrameIndex(FrameAddrIndex, VT);
  }

  unsigned FrameReg =
      RegInfo->getPtrSizedFrameRegister(DAG.getMachineFunction());
  SDLoc dl(Op);  // FIXME probably not meaningful
  unsigned Depth = Op.getConstantOperandVal(0);
  assert(((FrameReg == X86::RBP && VT == MVT::i64) ||
          (FrameReg == X86::EBP && VT == MVT::i32)) &&
         "Invalid Frame Register!");
  SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
  while (Depth--)
    FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
                            MachinePointerInfo());
  return FrameAddr;
}

// FIXME? Maybe this could be a TableGen attribute on some registers and
// this table could be generated automatically from RegInfo.
Register X86TargetLowering::getRegisterByName(const char* RegName, LLT VT,
                                              const MachineFunction &MF) const {
  const TargetFrameLowering &TFI = *Subtarget.getFrameLowering();

  Register Reg = StringSwitch<unsigned>(RegName)
                       .Case("esp", X86::ESP)
                       .Case("rsp", X86::RSP)
                       .Case("ebp", X86::EBP)
                       .Case("rbp", X86::RBP)
                       .Default(0);

  if (Reg == X86::EBP || Reg == X86::RBP) {
    if (!TFI.hasFP(MF))
      report_fatal_error("register " + StringRef(RegName) +
                         " is allocatable: function has no frame pointer");
#ifndef NDEBUG
    else {
      const X86RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
      Register FrameReg = RegInfo->getPtrSizedFrameRegister(MF);
      assert((FrameReg == X86::EBP || FrameReg == X86::RBP) &&
             "Invalid Frame Register!");
    }
#endif
  }

  if (Reg)
    return Reg;

  report_fatal_error("Invalid register name global variable");
}

SDValue X86TargetLowering::LowerFRAME_TO_ARGS_OFFSET(SDValue Op,
                                                     SelectionDAG &DAG) const {
  const X86RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
  return DAG.getIntPtrConstant(2 * RegInfo->getSlotSize(), SDLoc(Op));
}

unsigned X86TargetLowering::getExceptionPointerRegister(
    const Constant *PersonalityFn) const {
  if (classifyEHPersonality(PersonalityFn) == EHPersonality::CoreCLR)
    return Subtarget.isTarget64BitLP64() ? X86::RDX : X86::EDX;

  return Subtarget.isTarget64BitLP64() ? X86::RAX : X86::EAX;
}

unsigned X86TargetLowering::getExceptionSelectorRegister(
    const Constant *PersonalityFn) const {
  // Funclet personalities don't use selectors (the runtime does the selection).
  assert(!isFuncletEHPersonality(classifyEHPersonality(PersonalityFn)));
  return Subtarget.isTarget64BitLP64() ? X86::RDX : X86::EDX;
}

bool X86TargetLowering::needsFixedCatchObjects() const {
  return Subtarget.isTargetWin64();
}

SDValue X86TargetLowering::LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const {
  SDValue Chain     = Op.getOperand(0);
  SDValue Offset    = Op.getOperand(1);
  SDValue Handler   = Op.getOperand(2);
  SDLoc dl      (Op);

  EVT PtrVT = getPointerTy(DAG.getDataLayout());
  const X86RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
  Register FrameReg = RegInfo->getFrameRegister(DAG.getMachineFunction());
  assert(((FrameReg == X86::RBP && PtrVT == MVT::i64) ||
          (FrameReg == X86::EBP && PtrVT == MVT::i32)) &&
         "Invalid Frame Register!");
  SDValue Frame = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, PtrVT);
  unsigned StoreAddrReg = (PtrVT == MVT::i64) ? X86::RCX : X86::ECX;

  SDValue StoreAddr = DAG.getNode(ISD::ADD, dl, PtrVT, Frame,
                                 DAG.getIntPtrConstant(RegInfo->getSlotSize(),
                                                       dl));
  StoreAddr = DAG.getNode(ISD::ADD, dl, PtrVT, StoreAddr, Offset);
  Chain = DAG.getStore(Chain, dl, Handler, StoreAddr, MachinePointerInfo());
  Chain = DAG.getCopyToReg(Chain, dl, StoreAddrReg, StoreAddr);

  return DAG.getNode(X86ISD::EH_RETURN, dl, MVT::Other, Chain,
                     DAG.getRegister(StoreAddrReg, PtrVT));
}

SDValue X86TargetLowering::lowerEH_SJLJ_SETJMP(SDValue Op,
                                               SelectionDAG &DAG) const {
  SDLoc DL(Op);
  // If the subtarget is not 64bit, we may need the global base reg
  // after isel expand pseudo, i.e., after CGBR pass ran.
  // Therefore, ask for the GlobalBaseReg now, so that the pass
  // inserts the code for us in case we need it.
  // Otherwise, we will end up in a situation where we will
  // reference a virtual register that is not defined!
  if (!Subtarget.is64Bit()) {
    const X86InstrInfo *TII = Subtarget.getInstrInfo();
    (void)TII->getGlobalBaseReg(&DAG.getMachineFunction());
  }
  return DAG.getNode(X86ISD::EH_SJLJ_SETJMP, DL,
                     DAG.getVTList(MVT::i32, MVT::Other),
                     Op.getOperand(0), Op.getOperand(1));
}

SDValue X86TargetLowering::lowerEH_SJLJ_LONGJMP(SDValue Op,
                                                SelectionDAG &DAG) const {
  SDLoc DL(Op);
  return DAG.getNode(X86ISD::EH_SJLJ_LONGJMP, DL, MVT::Other,
                     Op.getOperand(0), Op.getOperand(1));
}

SDValue X86TargetLowering::lowerEH_SJLJ_SETUP_DISPATCH(SDValue Op,
                                                       SelectionDAG &DAG) const {
  SDLoc DL(Op);
  return DAG.getNode(X86ISD::EH_SJLJ_SETUP_DISPATCH, DL, MVT::Other,
                     Op.getOperand(0));
}

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

SDValue X86TargetLowering::LowerINIT_TRAMPOLINE(SDValue Op,
                                                SelectionDAG &DAG) const {
  SDValue Root = 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);

  const Value *TrmpAddr = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
  const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();

  if (Subtarget.is64Bit()) {
    SDValue OutChains[6];

    // Large code-model.
    const unsigned char JMP64r  = 0xFF; // 64-bit jmp through register opcode.
    const unsigned char MOV64ri = 0xB8; // X86::MOV64ri opcode.

    const unsigned char N86R10 = TRI->getEncodingValue(X86::R10) & 0x7;
    const unsigned char N86R11 = TRI->getEncodingValue(X86::R11) & 0x7;

    const unsigned char REX_WB = 0x40 | 0x08 | 0x01; // REX prefix

    // Load the pointer to the nested function into R11.
    unsigned OpCode = ((MOV64ri | N86R11) << 8) | REX_WB; // movabsq r11
    SDValue Addr = Trmp;
    OutChains[0] = DAG.getStore(Root, dl, DAG.getConstant(OpCode, dl, MVT::i16),
                                Addr, MachinePointerInfo(TrmpAddr));

    Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
                       DAG.getConstant(2, dl, MVT::i64));
    OutChains[1] =
        DAG.getStore(Root, dl, FPtr, Addr, MachinePointerInfo(TrmpAddr, 2),
                     /* Alignment = */ 2);

    // Load the 'nest' parameter value into R10.
    // R10 is specified in X86CallingConv.td
    OpCode = ((MOV64ri | N86R10) << 8) | REX_WB; // movabsq r10
    Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
                       DAG.getConstant(10, dl, MVT::i64));
    OutChains[2] = DAG.getStore(Root, dl, DAG.getConstant(OpCode, dl, MVT::i16),
                                Addr, MachinePointerInfo(TrmpAddr, 10));

    Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
                       DAG.getConstant(12, dl, MVT::i64));
    OutChains[3] =
        DAG.getStore(Root, dl, Nest, Addr, MachinePointerInfo(TrmpAddr, 12),
                     /* Alignment = */ 2);

    // Jump to the nested function.
    OpCode = (JMP64r << 8) | REX_WB; // jmpq *...
    Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
                       DAG.getConstant(20, dl, MVT::i64));
    OutChains[4] = DAG.getStore(Root, dl, DAG.getConstant(OpCode, dl, MVT::i16),
                                Addr, MachinePointerInfo(TrmpAddr, 20));

    unsigned char ModRM = N86R11 | (4 << 3) | (3 << 6); // ...r11
    Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
                       DAG.getConstant(22, dl, MVT::i64));
    OutChains[5] = DAG.getStore(Root, dl, DAG.getConstant(ModRM, dl, MVT::i8),
                                Addr, MachinePointerInfo(TrmpAddr, 22));

    return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
  } else {
    const Function *Func =
      cast<Function>(cast<SrcValueSDNode>(Op.getOperand(5))->getValue());
    CallingConv::ID CC = Func->getCallingConv();
    unsigned NestReg;

    switch (CC) {
    default:
      llvm_unreachable("Unsupported calling convention");
    case CallingConv::C:
    case CallingConv::X86_StdCall: {
      // Pass 'nest' parameter in ECX.
      // Must be kept in sync with X86CallingConv.td
      NestReg = X86::ECX;

      // Check that ECX wasn't needed by an 'inreg' parameter.
      FunctionType *FTy = Func->getFunctionType();
      const AttributeList &Attrs = Func->getAttributes();

      if (!Attrs.isEmpty() && !Func->isVarArg()) {
        unsigned InRegCount = 0;
        unsigned Idx = 1;

        for (FunctionType::param_iterator I = FTy->param_begin(),
             E = FTy->param_end(); I != E; ++I, ++Idx)
          if (Attrs.hasAttribute(Idx, Attribute::InReg)) {
            auto &DL = DAG.getDataLayout();
            // FIXME: should only count parameters that are lowered to integers.
            InRegCount += (DL.getTypeSizeInBits(*I) + 31) / 32;
          }

        if (InRegCount > 2) {
          report_fatal_error("Nest register in use - reduce number of inreg"
                             " parameters!");
        }
      }
      break;
    }
    case CallingConv::X86_FastCall:
    case CallingConv::X86_ThisCall:
    case CallingConv::Fast:
    case CallingConv::Tail:
      // Pass 'nest' parameter in EAX.
      // Must be kept in sync with X86CallingConv.td
      NestReg = X86::EAX;
      break;
    }

    SDValue OutChains[4];
    SDValue Addr, Disp;

    Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp,
                       DAG.getConstant(10, dl, MVT::i32));
    Disp = DAG.getNode(ISD::SUB, dl, MVT::i32, FPtr, Addr);

    // This is storing the opcode for MOV32ri.
    const unsigned char MOV32ri = 0xB8; // X86::MOV32ri's opcode byte.
    const unsigned char N86Reg = TRI->getEncodingValue(NestReg) & 0x7;
    OutChains[0] =
        DAG.getStore(Root, dl, DAG.getConstant(MOV32ri | N86Reg, dl, MVT::i8),
                     Trmp, MachinePointerInfo(TrmpAddr));

    Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp,
                       DAG.getConstant(1, dl, MVT::i32));
    OutChains[1] =
        DAG.getStore(Root, dl, Nest, Addr, MachinePointerInfo(TrmpAddr, 1),
                     /* Alignment = */ 1);

    const unsigned char JMP = 0xE9; // jmp <32bit dst> opcode.
    Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp,
                       DAG.getConstant(5, dl, MVT::i32));
    OutChains[2] = DAG.getStore(Root, dl, DAG.getConstant(JMP, dl, MVT::i8),
                                Addr, MachinePointerInfo(TrmpAddr, 5),
                                /* Alignment = */ 1);

    Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp,
                       DAG.getConstant(6, dl, MVT::i32));
    OutChains[3] =
        DAG.getStore(Root, dl, Disp, Addr, MachinePointerInfo(TrmpAddr, 6),
                     /* Alignment = */ 1);

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

SDValue X86TargetLowering::LowerFLT_ROUNDS_(SDValue Op,
                                            SelectionDAG &DAG) const {
  /*
   The rounding mode is in bits 11:10 of FPSR, and has the following
   settings:
     00 Round to nearest
     01 Round to -inf
     10 Round to +inf
     11 Round to 0

  FLT_ROUNDS, 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 use a packed lookup table of the four 2-bit
  values that we can index by FPSP[11:10]
    0x2d --> (0b00,10,11,01) --> (0,2,3,1) >> FPSR[11:10]

    (0x2d >> ((FPSR & 0xc00) >> 9)) & 3
  */

  MachineFunction &MF = DAG.getMachineFunction();
  MVT VT = Op.getSimpleValueType();
  SDLoc DL(Op);

  // Save FP Control Word to stack slot
  int SSFI =
      MF.getFrameInfo().CreateStackObject(2, 2, false);
  SDValue StackSlot =
      DAG.getFrameIndex(SSFI, getPointerTy(DAG.getDataLayout()));

  MachinePointerInfo MPI = MachinePointerInfo::getFixedStack(MF, SSFI);

  SDValue Chain = Op.getOperand(0);
  SDValue Ops[] = {Chain, StackSlot};
  Chain = DAG.getMemIntrinsicNode(X86ISD::FNSTCW16m, DL,
                                  DAG.getVTList(MVT::Other), Ops, MVT::i16, MPI,
                                  Align(2), MachineMemOperand::MOStore);

  // Load FP Control Word from stack slot
  SDValue CWD = DAG.getLoad(MVT::i16, DL, Chain, StackSlot, MPI, Align(2));
  Chain = CWD.getValue(1);

  // Mask and turn the control bits into a shift for the lookup table.
  SDValue Shift =
    DAG.getNode(ISD::SRL, DL, MVT::i16,
                DAG.getNode(ISD::AND, DL, MVT::i16,
                            CWD, DAG.getConstant(0xc00, DL, MVT::i16)),
                DAG.getConstant(9, DL, MVT::i8));
  Shift = DAG.getNode(ISD::TRUNCATE, DL, MVT::i8, Shift);

  SDValue LUT = DAG.getConstant(0x2d, DL, MVT::i32);
  SDValue RetVal =
    DAG.getNode(ISD::AND, DL, MVT::i32,
                DAG.getNode(ISD::SRL, DL, MVT::i32, LUT, Shift),
                DAG.getConstant(3, DL, MVT::i32));

  RetVal = DAG.getZExtOrTrunc(RetVal, DL, VT);

  return DAG.getMergeValues({RetVal, Chain}, DL);
}

// Split an unary integer op into 2 half sized ops.
static SDValue LowerVectorIntUnary(SDValue Op, SelectionDAG &DAG) {
  MVT VT = Op.getSimpleValueType();
  unsigned NumElems = VT.getVectorNumElements();
  unsigned SizeInBits = VT.getSizeInBits();
  MVT EltVT = VT.getVectorElementType();
  SDValue Src = Op.getOperand(0);
  assert(EltVT == Src.getSimpleValueType().getVectorElementType() &&
         "Src and Op should have the same element type!");

  // Extract the Lo/Hi vectors
  SDLoc dl(Op);
  SDValue Lo = extractSubVector(Src, 0, DAG, dl, SizeInBits / 2);
  SDValue Hi = extractSubVector(Src, NumElems / 2, DAG, dl, SizeInBits / 2);

  MVT NewVT = MVT::getVectorVT(EltVT, NumElems / 2);
  return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT,
                     DAG.getNode(Op.getOpcode(), dl, NewVT, Lo),
                     DAG.getNode(Op.getOpcode(), dl, NewVT, Hi));
}

// Decompose 256-bit ops into smaller 128-bit ops.
static SDValue Lower256IntUnary(SDValue Op, SelectionDAG &DAG) {
  assert(Op.getSimpleValueType().is256BitVector() &&
         Op.getSimpleValueType().isInteger() &&
         "Only handle AVX 256-bit vector integer operation");
  return LowerVectorIntUnary(Op, DAG);
}

// Decompose 512-bit ops into smaller 256-bit ops.
static SDValue Lower512IntUnary(SDValue Op, SelectionDAG &DAG) {
  assert(Op.getSimpleValueType().is512BitVector() &&
         Op.getSimpleValueType().isInteger() &&
         "Only handle AVX 512-bit vector integer operation");
  return LowerVectorIntUnary(Op, DAG);
}

/// Lower a vector CTLZ using native supported vector CTLZ instruction.
//
// i8/i16 vector implemented using dword LZCNT vector instruction
// ( sub(trunc(lzcnt(zext32(x)))) ). In case zext32(x) is illegal,
// split the vector, perform operation on it's Lo a Hi part and
// concatenate the results.
static SDValue LowerVectorCTLZ_AVX512CDI(SDValue Op, SelectionDAG &DAG,
                                         const X86Subtarget &Subtarget) {
  assert(Op.getOpcode() == ISD::CTLZ);
  SDLoc dl(Op);
  MVT VT = Op.getSimpleValueType();
  MVT EltVT = VT.getVectorElementType();
  unsigned NumElems = VT.getVectorNumElements();

  assert((EltVT == MVT::i8 || EltVT == MVT::i16) &&
          "Unsupported element type");

  // Split vector, it's Lo and Hi parts will be handled in next iteration.
  if (NumElems > 16 ||
      (NumElems == 16 && !Subtarget.canExtendTo512DQ()))
    return LowerVectorIntUnary(Op, DAG);

  MVT NewVT = MVT::getVectorVT(MVT::i32, NumElems);
  assert((NewVT.is256BitVector() || NewVT.is512BitVector()) &&
          "Unsupported value type for operation");

  // Use native supported vector instruction vplzcntd.
  Op = DAG.getNode(ISD::ZERO_EXTEND, dl, NewVT, Op.getOperand(0));
  SDValue CtlzNode = DAG.getNode(ISD::CTLZ, dl, NewVT, Op);
  SDValue TruncNode = DAG.getNode(ISD::TRUNCATE, dl, VT, CtlzNode);
  SDValue Delta = DAG.getConstant(32 - EltVT.getSizeInBits(), dl, VT);

  return DAG.getNode(ISD::SUB, dl, VT, TruncNode, Delta);
}

// Lower CTLZ using a PSHUFB lookup table implementation.
static SDValue LowerVectorCTLZInRegLUT(SDValue Op, const SDLoc &DL,
                                       const X86Subtarget &Subtarget,
                                       SelectionDAG &DAG) {
  MVT VT = Op.getSimpleValueType();
  int NumElts = VT.getVectorNumElements();
  int NumBytes = NumElts * (VT.getScalarSizeInBits() / 8);
  MVT CurrVT = MVT::getVectorVT(MVT::i8, NumBytes);

  // Per-nibble leading zero PSHUFB lookup table.
  const int LUT[16] = {/* 0 */ 4, /* 1 */ 3, /* 2 */ 2, /* 3 */ 2,
                       /* 4 */ 1, /* 5 */ 1, /* 6 */ 1, /* 7 */ 1,
                       /* 8 */ 0, /* 9 */ 0, /* a */ 0, /* b */ 0,
                       /* c */ 0, /* d */ 0, /* e */ 0, /* f */ 0};

  SmallVector<SDValue, 64> LUTVec;
  for (int i = 0; i < NumBytes; ++i)
    LUTVec.push_back(DAG.getConstant(LUT[i % 16], DL, MVT::i8));
  SDValue InRegLUT = DAG.getBuildVector(CurrVT, DL, LUTVec);

  // Begin by bitcasting the input to byte vector, then split those bytes
  // into lo/hi nibbles and use the PSHUFB LUT to perform CLTZ on each of them.
  // If the hi input nibble is zero then we add both results together, otherwise
  // we just take the hi result (by masking the lo result to zero before the
  // add).
  SDValue Op0 = DAG.getBitcast(CurrVT, Op.getOperand(0));
  SDValue Zero = DAG.getConstant(0, DL, CurrVT);

  SDValue NibbleShift = DAG.getConstant(0x4, DL, CurrVT);
  SDValue Lo = Op0;
  SDValue Hi = DAG.getNode(ISD::SRL, DL, CurrVT, Op0, NibbleShift);
  SDValue HiZ;
  if (CurrVT.is512BitVector()) {
    MVT MaskVT = MVT::getVectorVT(MVT::i1, CurrVT.getVectorNumElements());
    HiZ = DAG.getSetCC(DL, MaskVT, Hi, Zero, ISD::SETEQ);
    HiZ = DAG.getNode(ISD::SIGN_EXTEND, DL, CurrVT, HiZ);
  } else {
    HiZ = DAG.getSetCC(DL, CurrVT, Hi, Zero, ISD::SETEQ);
  }

  Lo = DAG.getNode(X86ISD::PSHUFB, DL, CurrVT, InRegLUT, Lo);
  Hi = DAG.getNode(X86ISD::PSHUFB, DL, CurrVT, InRegLUT, Hi);
  Lo = DAG.getNode(ISD::AND, DL, CurrVT, Lo, HiZ);
  SDValue Res = DAG.getNode(ISD::ADD, DL, CurrVT, Lo, Hi);

  // Merge result back from vXi8 back to VT, working on the lo/hi halves
  // of the current vector width in the same way we did for the nibbles.
  // If the upper half of the input element is zero then add the halves'
  // leading zero counts together, otherwise just use the upper half's.
  // Double the width of the result until we are at target width.
  while (CurrVT != VT) {
    int CurrScalarSizeInBits = CurrVT.getScalarSizeInBits();
    int CurrNumElts = CurrVT.getVectorNumElements();
    MVT NextSVT = MVT::getIntegerVT(CurrScalarSizeInBits * 2);
    MVT NextVT = MVT::getVectorVT(NextSVT, CurrNumElts / 2);
    SDValue Shift = DAG.getConstant(CurrScalarSizeInBits, DL, NextVT);

    // Check if the upper half of the input element is zero.
    if (CurrVT.is512BitVector()) {
      MVT MaskVT = MVT::getVectorVT(MVT::i1, CurrVT.getVectorNumElements());
      HiZ = DAG.getSetCC(DL, MaskVT, DAG.getBitcast(CurrVT, Op0),
                         DAG.getBitcast(CurrVT, Zero), ISD::SETEQ);
      HiZ = DAG.getNode(ISD::SIGN_EXTEND, DL, CurrVT, HiZ);
    } else {
      HiZ = DAG.getSetCC(DL, CurrVT, DAG.getBitcast(CurrVT, Op0),
                         DAG.getBitcast(CurrVT, Zero), ISD::SETEQ);
    }
    HiZ = DAG.getBitcast(NextVT, HiZ);

    // Move the upper/lower halves to the lower bits as we'll be extending to
    // NextVT. Mask the lower result to zero if HiZ is true and add the results
    // together.
    SDValue ResNext = Res = DAG.getBitcast(NextVT, Res);
    SDValue R0 = DAG.getNode(ISD::SRL, DL, NextVT, ResNext, Shift);
    SDValue R1 = DAG.getNode(ISD::SRL, DL, NextVT, HiZ, Shift);
    R1 = DAG.getNode(ISD::AND, DL, NextVT, ResNext, R1);
    Res = DAG.getNode(ISD::ADD, DL, NextVT, R0, R1);
    CurrVT = NextVT;
  }

  return Res;
}

static SDValue LowerVectorCTLZ(SDValue Op, const SDLoc &DL,
                               const X86Subtarget &Subtarget,
                               SelectionDAG &DAG) {
  MVT VT = Op.getSimpleValueType();

  if (Subtarget.hasCDI() &&
      // vXi8 vectors need to be promoted to 512-bits for vXi32.
      (Subtarget.canExtendTo512DQ() || VT.getVectorElementType() != MVT::i8))
    return LowerVectorCTLZ_AVX512CDI(Op, DAG, Subtarget);

  // Decompose 256-bit ops into smaller 128-bit ops.
  if (VT.is256BitVector() && !Subtarget.hasInt256())
    return Lower256IntUnary(Op, DAG);

  // Decompose 512-bit ops into smaller 256-bit ops.
  if (VT.is512BitVector() && !Subtarget.hasBWI())
    return Lower512IntUnary(Op, DAG);

  assert(Subtarget.hasSSSE3() && "Expected SSSE3 support for PSHUFB");
  return LowerVectorCTLZInRegLUT(Op, DL, Subtarget, DAG);
}

static SDValue LowerCTLZ(SDValue Op, const X86Subtarget &Subtarget,
                         SelectionDAG &DAG) {
  MVT VT = Op.getSimpleValueType();
  MVT OpVT = VT;
  unsigned NumBits = VT.getSizeInBits();
  SDLoc dl(Op);
  unsigned Opc = Op.getOpcode();

  if (VT.isVector())
    return LowerVectorCTLZ(Op, dl, Subtarget, DAG);

  Op = Op.getOperand(0);
  if (VT == MVT::i8) {
    // Zero extend to i32 since there is not an i8 bsr.
    OpVT = MVT::i32;
    Op = DAG.getNode(ISD::ZERO_EXTEND, dl, OpVT, Op);
  }

  // Issue a bsr (scan bits in reverse) which also sets EFLAGS.
  SDVTList VTs = DAG.getVTList(OpVT, MVT::i32);
  Op = DAG.getNode(X86ISD::BSR, dl, VTs, Op);

  if (Opc == ISD::CTLZ) {
    // If src is zero (i.e. bsr sets ZF), returns NumBits.
    SDValue Ops[] = {Op, DAG.getConstant(NumBits + NumBits - 1, dl, OpVT),
                     DAG.getTargetConstant(X86::COND_E, dl, MVT::i8),
                     Op.getValue(1)};
    Op = DAG.getNode(X86ISD::CMOV, dl, OpVT, Ops);
  }

  // Finally xor with NumBits-1.
  Op = DAG.getNode(ISD::XOR, dl, OpVT, Op,
                   DAG.getConstant(NumBits - 1, dl, OpVT));

  if (VT == MVT::i8)
    Op = DAG.getNode(ISD::TRUNCATE, dl, MVT::i8, Op);
  return Op;
}

static SDValue LowerCTTZ(SDValue Op, const X86Subtarget &Subtarget,
                         SelectionDAG &DAG) {
  MVT VT = Op.getSimpleValueType();
  unsigned NumBits = VT.getScalarSizeInBits();
  SDValue N0 = Op.getOperand(0);
  SDLoc dl(Op);

  assert(!VT.isVector() && Op.getOpcode() == ISD::CTTZ &&
         "Only scalar CTTZ requires custom lowering");

  // Issue a bsf (scan bits forward) which also sets EFLAGS.
  SDVTList VTs = DAG.getVTList(VT, MVT::i32);
  Op = DAG.getNode(X86ISD::BSF, dl, VTs, N0);

  // If src is zero (i.e. bsf sets ZF), returns NumBits.
  SDValue Ops[] = {Op, DAG.getConstant(NumBits, dl, VT),
                   DAG.getTargetConstant(X86::COND_E, dl, MVT::i8),
                   Op.getValue(1)};
  return DAG.getNode(X86ISD::CMOV, dl, VT, Ops);
}

/// Break a 256-bit integer operation into two new 128-bit ones and then
/// concatenate the result back.
static SDValue split256IntArith(SDValue Op, SelectionDAG &DAG) {
  MVT VT = Op.getSimpleValueType();

  assert(VT.is256BitVector() && VT.isInteger() &&
         "Unsupported value type for operation");

  unsigned NumElems = VT.getVectorNumElements();
  SDLoc dl(Op);

  // Extract the LHS vectors
  SDValue LHS = Op.getOperand(0);
  SDValue LHS1 = extract128BitVector(LHS, 0, DAG, dl);
  SDValue LHS2 = extract128BitVector(LHS, NumElems / 2, DAG, dl);

  // Extract the RHS vectors
  SDValue RHS = Op.getOperand(1);
  SDValue RHS1 = extract128BitVector(RHS, 0, DAG, dl);
  SDValue RHS2 = extract128BitVector(RHS, NumElems / 2, DAG, dl);

  MVT EltVT = VT.getVectorElementType();
  MVT NewVT = MVT::getVectorVT(EltVT, NumElems/2);

  return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT,
                     DAG.getNode(Op.getOpcode(), dl, NewVT, LHS1, RHS1),
                     DAG.getNode(Op.getOpcode(), dl, NewVT, LHS2, RHS2));
}

/// Break a 512-bit integer operation into two new 256-bit ones and then
/// concatenate the result back.
static SDValue split512IntArith(SDValue Op, SelectionDAG &DAG) {
  MVT VT = Op.getSimpleValueType();

  assert(VT.is512BitVector() && VT.isInteger() &&
         "Unsupported value type for operation");

  unsigned NumElems = VT.getVectorNumElements();
  SDLoc dl(Op);

  // Extract the LHS vectors
  SDValue LHS = Op.getOperand(0);
  SDValue LHS1 = extract256BitVector(LHS, 0, DAG, dl);
  SDValue LHS2 = extract256BitVector(LHS, NumElems / 2, DAG, dl);

  // Extract the RHS vectors
  SDValue RHS = Op.getOperand(1);
  SDValue RHS1 = extract256BitVector(RHS, 0, DAG, dl);
  SDValue RHS2 = extract256BitVector(RHS, NumElems / 2, DAG, dl);

  MVT EltVT = VT.getVectorElementType();
  MVT NewVT = MVT::getVectorVT(EltVT, NumElems/2);

  return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT,
                     DAG.getNode(Op.getOpcode(), dl, NewVT, LHS1, RHS1),
                     DAG.getNode(Op.getOpcode(), dl, NewVT, LHS2, RHS2));
}

static SDValue lowerAddSub(SDValue Op, SelectionDAG &DAG,
                           const X86Subtarget &Subtarget) {
  MVT VT = Op.getSimpleValueType();
  if (VT == MVT::i16 || VT == MVT::i32)
    return lowerAddSubToHorizontalOp(Op, DAG, Subtarget);

  if (VT.getScalarType() == MVT::i1)
    return DAG.getNode(ISD::XOR, SDLoc(Op), VT,
                       Op.getOperand(0), Op.getOperand(1));

  assert(Op.getSimpleValueType().is256BitVector() &&
         Op.getSimpleValueType().isInteger() &&
         "Only handle AVX 256-bit vector integer operation");
  return split256IntArith(Op, DAG);
}

static SDValue LowerADDSAT_SUBSAT(SDValue Op, SelectionDAG &DAG,
                                  const X86Subtarget &Subtarget) {
  MVT VT = Op.getSimpleValueType();
  SDValue X = Op.getOperand(0), Y = Op.getOperand(1);
  unsigned Opcode = Op.getOpcode();
  if (VT.getScalarType() == MVT::i1) {
    SDLoc dl(Op);
    switch (Opcode) {
    default: llvm_unreachable("Expected saturated arithmetic opcode");
    case ISD::UADDSAT:
    case ISD::SADDSAT:
      // *addsat i1 X, Y --> X | Y
      return DAG.getNode(ISD::OR, dl, VT, X, Y);
    case ISD::USUBSAT:
    case ISD::SSUBSAT:
      // *subsat i1 X, Y --> X & ~Y
      return DAG.getNode(ISD::AND, dl, VT, X, DAG.getNOT(dl, Y, VT));
    }
  }

  if (VT.is128BitVector()) {
    // Avoid the generic expansion with min/max if we don't have pminu*/pmaxu*.
    const TargetLowering &TLI = DAG.getTargetLoweringInfo();
    EVT SetCCResultType = TLI.getSetCCResultType(DAG.getDataLayout(),
                                                 *DAG.getContext(), VT);
    SDLoc DL(Op);
    if (Opcode == ISD::UADDSAT && !TLI.isOperationLegal(ISD::UMIN, VT)) {
      // uaddsat X, Y --> (X >u (X + Y)) ? -1 : X + Y
      SDValue Add = DAG.getNode(ISD::ADD, DL, VT, X, Y);
      SDValue Cmp = DAG.getSetCC(DL, SetCCResultType, X, Add, ISD::SETUGT);
      return DAG.getSelect(DL, VT, Cmp, DAG.getAllOnesConstant(DL, VT), Add);
    }
    if (Opcode == ISD::USUBSAT && !TLI.isOperationLegal(ISD::UMAX, VT)) {
      // usubsat X, Y --> (X >u Y) ? X - Y : 0
      SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, X, Y);
      SDValue Cmp = DAG.getSetCC(DL, SetCCResultType, X, Y, ISD::SETUGT);
      return DAG.getSelect(DL, VT, Cmp, Sub, DAG.getConstant(0, DL, VT));
    }
    // Use default expansion.
    return SDValue();
  }

  assert(Op.getSimpleValueType().is256BitVector() &&
         Op.getSimpleValueType().isInteger() &&
         "Only handle AVX 256-bit vector integer operation");
  return split256IntArith(Op, DAG);
}

static SDValue LowerABS(SDValue Op, const X86Subtarget &Subtarget,
                        SelectionDAG &DAG) {
  MVT VT = Op.getSimpleValueType();
  if (VT == MVT::i16 || VT == MVT::i32 || VT == MVT::i64) {
    // Since X86 does not have CMOV for 8-bit integer, we don't convert
    // 8-bit integer abs to NEG and CMOV.
    SDLoc DL(Op);
    SDValue N0 = Op.getOperand(0);
    SDValue Neg = DAG.getNode(X86ISD::SUB, DL, DAG.getVTList(VT, MVT::i32),
                              DAG.getConstant(0, DL, VT), N0);
    SDValue Ops[] = {N0, Neg, DAG.getTargetConstant(X86::COND_GE, DL, MVT::i8),
                     SDValue(Neg.getNode(), 1)};
    return DAG.getNode(X86ISD::CMOV, DL, VT, Ops);
  }

  // ABS(vXi64 X) --> VPBLENDVPD(X, 0-X, X).
  if ((VT == MVT::v2i64 || VT == MVT::v4i64) && Subtarget.hasSSE41()) {
    SDLoc DL(Op);
    SDValue Src = Op.getOperand(0);
    SDValue Sub =
        DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), Src);
    return DAG.getNode(X86ISD::BLENDV, DL, VT, Src, Sub, Src);
  }

  if (VT.is256BitVector() && !Subtarget.hasInt256()) {
    assert(VT.isInteger() &&
           "Only handle AVX 256-bit vector integer operation");
    return Lower256IntUnary(Op, DAG);
  }

  // Default to expand.
  return SDValue();
}

static SDValue LowerMINMAX(SDValue Op, SelectionDAG &DAG) {
  MVT VT = Op.getSimpleValueType();

  // For AVX1 cases, split to use legal ops (everything but v4i64).
  if (VT.getScalarType() != MVT::i64 && VT.is256BitVector())
    return split256IntArith(Op, DAG);

  SDLoc DL(Op);
  unsigned Opcode = Op.getOpcode();
  SDValue N0 = Op.getOperand(0);
  SDValue N1 = Op.getOperand(1);

  // For pre-SSE41, we can perform UMIN/UMAX v8i16 by flipping the signbit,
  // using the SMIN/SMAX instructions and flipping the signbit back.
  if (VT == MVT::v8i16) {
    assert((Opcode == ISD::UMIN || Opcode == ISD::UMAX) &&
           "Unexpected MIN/MAX opcode");
    SDValue Sign = DAG.getConstant(APInt::getSignedMinValue(16), DL, VT);
    N0 = DAG.getNode(ISD::XOR, DL, VT, N0, Sign);
    N1 = DAG.getNode(ISD::XOR, DL, VT, N1, Sign);
    Opcode = (Opcode == ISD::UMIN ? ISD::SMIN : ISD::SMAX);
    SDValue Result = DAG.getNode(Opcode, DL, VT, N0, N1);
    return DAG.getNode(ISD::XOR, DL, VT, Result, Sign);
  }

  // Else, expand to a compare/select.
  ISD::CondCode CC;
  switch (Opcode) {
  case ISD::SMIN: CC = ISD::CondCode::SETLT;  break;
  case ISD::SMAX: CC = ISD::CondCode::SETGT;  break;
  case ISD::UMIN: CC = ISD::CondCode::SETULT; break;
  case ISD::UMAX: CC = ISD::CondCode::SETUGT; break;
  default: llvm_unreachable("Unknown MINMAX opcode");
  }

  SDValue Cond = DAG.getSetCC(DL, VT, N0, N1, CC);
  return DAG.getSelect(DL, VT, Cond, N0, N1);
}

static SDValue LowerMUL(SDValue Op, const X86Subtarget &Subtarget,
                        SelectionDAG &DAG) {
  SDLoc dl(Op);
  MVT VT = Op.getSimpleValueType();

  if (VT.getScalarType() == MVT::i1)
    return DAG.getNode(ISD::AND, dl, VT, Op.getOperand(0), Op.getOperand(1));

  // Decompose 256-bit ops into 128-bit ops.
  if (VT.is256BitVector() && !Subtarget.hasInt256())
    return split256IntArith(Op, DAG);

  SDValue A = Op.getOperand(0);
  SDValue B = Op.getOperand(1);

  // Lower v16i8/v32i8/v64i8 mul as sign-extension to v8i16/v16i16/v32i16
  // vector pairs, multiply and truncate.
  if (VT == MVT::v16i8 || VT == MVT::v32i8 || VT == MVT::v64i8) {
    unsigned NumElts = VT.getVectorNumElements();

    if ((VT == MVT::v16i8 && Subtarget.hasInt256()) ||
        (VT == MVT::v32i8 && Subtarget.canExtendTo512BW())) {
      MVT ExVT = MVT::getVectorVT(MVT::i16, VT.getVectorNumElements());
      return DAG.getNode(
          ISD::TRUNCATE, dl, VT,
          DAG.getNode(ISD::MUL, dl, ExVT,
                      DAG.getNode(ISD::ANY_EXTEND, dl, ExVT, A),
                      DAG.getNode(ISD::ANY_EXTEND, dl, ExVT, B)));
    }

    MVT ExVT = MVT::getVectorVT(MVT::i16, NumElts / 2);

    // Extract the lo/hi parts to any extend to i16.
    // We're going to mask off the low byte of each result element of the
    // pmullw, so it doesn't matter what's in the high byte of each 16-bit
    // element.
    SDValue Undef = DAG.getUNDEF(VT);
    SDValue ALo = DAG.getBitcast(ExVT, getUnpackl(DAG, dl, VT, A, Undef));
    SDValue AHi = DAG.getBitcast(ExVT, getUnpackh(DAG, dl, VT, A, Undef));

    SDValue BLo, BHi;
    if (ISD::isBuildVectorOfConstantSDNodes(B.getNode())) {
      // If the LHS is a constant, manually unpackl/unpackh.
      SmallVector<SDValue, 16> LoOps, HiOps;
      for (unsigned i = 0; i != NumElts; i += 16) {
        for (unsigned j = 0; j != 8; ++j) {
          LoOps.push_back(DAG.getAnyExtOrTrunc(B.getOperand(i + j), dl,
                                               MVT::i16));
          HiOps.push_back(DAG.getAnyExtOrTrunc(B.getOperand(i + j + 8), dl,
                                               MVT::i16));
        }
      }

      BLo = DAG.getBuildVector(ExVT, dl, LoOps);
      BHi = DAG.getBuildVector(ExVT, dl, HiOps);
    } else {
      BLo = DAG.getBitcast(ExVT, getUnpackl(DAG, dl, VT, B, Undef));
      BHi = DAG.getBitcast(ExVT, getUnpackh(DAG, dl, VT, B, Undef));
    }

    // Multiply, mask the lower 8bits of the lo/hi results and pack.
    SDValue RLo = DAG.getNode(ISD::MUL, dl, ExVT, ALo, BLo);
    SDValue RHi = DAG.getNode(ISD::MUL, dl, ExVT, AHi, BHi);
    RLo = DAG.getNode(ISD::AND, dl, ExVT, RLo, DAG.getConstant(255, dl, ExVT));
    RHi = DAG.getNode(ISD::AND, dl, ExVT, RHi, DAG.getConstant(255, dl, ExVT));
    return DAG.getNode(X86ISD::PACKUS, dl, VT, RLo, RHi);
  }

  // Lower v4i32 mul as 2x shuffle, 2x pmuludq, 2x shuffle.
  if (VT == MVT::v4i32) {
    assert(Subtarget.hasSSE2() && !Subtarget.hasSSE41() &&
           "Should not custom lower when pmulld is available!");

    // Extract the odd parts.
    static const int UnpackMask[] = { 1, -1, 3, -1 };
    SDValue Aodds = DAG.getVectorShuffle(VT, dl, A, A, UnpackMask);
    SDValue Bodds = DAG.getVectorShuffle(VT, dl, B, B, UnpackMask);

    // Multiply the even parts.
    SDValue Evens = DAG.getNode(X86ISD::PMULUDQ, dl, MVT::v2i64,
                                DAG.getBitcast(MVT::v2i64, A),
                                DAG.getBitcast(MVT::v2i64, B));
    // Now multiply odd parts.
    SDValue Odds = DAG.getNode(X86ISD::PMULUDQ, dl, MVT::v2i64,
                               DAG.getBitcast(MVT::v2i64, Aodds),
                               DAG.getBitcast(MVT::v2i64, Bodds));

    Evens = DAG.getBitcast(VT, Evens);
    Odds = DAG.getBitcast(VT, Odds);

    // Merge the two vectors back together with a shuffle. This expands into 2
    // shuffles.
    static const int ShufMask[] = { 0, 4, 2, 6 };
    return DAG.getVectorShuffle(VT, dl, Evens, Odds, ShufMask);
  }

  assert((VT == MVT::v2i64 || VT == MVT::v4i64 || VT == MVT::v8i64) &&
         "Only know how to lower V2I64/V4I64/V8I64 multiply");
  assert(!Subtarget.hasDQI() && "DQI should use MULLQ");

  //  Ahi = psrlqi(a, 32);
  //  Bhi = psrlqi(b, 32);
  //
  //  AloBlo = pmuludq(a, b);
  //  AloBhi = pmuludq(a, Bhi);
  //  AhiBlo = pmuludq(Ahi, b);
  //
  //  Hi = psllqi(AloBhi + AhiBlo, 32);
  //  return AloBlo + Hi;
  KnownBits AKnown = DAG.computeKnownBits(A);
  KnownBits BKnown = DAG.computeKnownBits(B);

  APInt LowerBitsMask = APInt::getLowBitsSet(64, 32);
  bool ALoIsZero = LowerBitsMask.isSubsetOf(AKnown.Zero);
  bool BLoIsZero = LowerBitsMask.isSubsetOf(BKnown.Zero);

  APInt UpperBitsMask = APInt::getHighBitsSet(64, 32);
  bool AHiIsZero = UpperBitsMask.isSubsetOf(AKnown.Zero);
  bool BHiIsZero = UpperBitsMask.isSubsetOf(BKnown.Zero);

  SDValue Zero = DAG.getConstant(0, dl, VT);

  // Only multiply lo/hi halves that aren't known to be zero.
  SDValue AloBlo = Zero;
  if (!ALoIsZero && !BLoIsZero)
    AloBlo = DAG.getNode(X86ISD::PMULUDQ, dl, VT, A, B);

  SDValue AloBhi = Zero;
  if (!ALoIsZero && !BHiIsZero) {
    SDValue Bhi = getTargetVShiftByConstNode(X86ISD::VSRLI, dl, VT, B, 32, DAG);
    AloBhi = DAG.getNode(X86ISD::PMULUDQ, dl, VT, A, Bhi);
  }

  SDValue AhiBlo = Zero;
  if (!AHiIsZero && !BLoIsZero) {
    SDValue Ahi = getTargetVShiftByConstNode(X86ISD::VSRLI, dl, VT, A, 32, DAG);
    AhiBlo = DAG.getNode(X86ISD::PMULUDQ, dl, VT, Ahi, B);
  }

  SDValue Hi = DAG.getNode(ISD::ADD, dl, VT, AloBhi, AhiBlo);
  Hi = getTargetVShiftByConstNode(X86ISD::VSHLI, dl, VT, Hi, 32, DAG);

  return DAG.getNode(ISD::ADD, dl, VT, AloBlo, Hi);
}

static SDValue LowerMULH(SDValue Op, const X86Subtarget &Subtarget,
                         SelectionDAG &DAG) {
  SDLoc dl(Op);
  MVT VT = Op.getSimpleValueType();
  bool IsSigned = Op->getOpcode() == ISD::MULHS;
  unsigned NumElts = VT.getVectorNumElements();
  SDValue A = Op.getOperand(0);
  SDValue B = Op.getOperand(1);

  // Decompose 256-bit ops into 128-bit ops.
  if (VT.is256BitVector() && !Subtarget.hasInt256())
    return split256IntArith(Op, DAG);

  if (VT == MVT::v4i32 || VT == MVT::v8i32 || VT == MVT::v16i32) {
    assert((VT == MVT::v4i32 && Subtarget.hasSSE2()) ||
           (VT == MVT::v8i32 && Subtarget.hasInt256()) ||
           (VT == MVT::v16i32 && Subtarget.hasAVX512()));

    // PMULxD operations multiply each even value (starting at 0) of LHS with
    // the related value of RHS and produce a widen result.
    // E.g., PMULUDQ <4 x i32> <a|b|c|d>, <4 x i32> <e|f|g|h>
    // => <2 x i64> <ae|cg>
    //
    // In other word, to have all the results, we need to perform two PMULxD:
    // 1. one with the even values.
    // 2. one with the odd values.
    // To achieve #2, with need to place the odd values at an even position.
    //
    // Place the odd value at an even position (basically, shift all values 1
    // step to the left):
    const int Mask[] = {1, -1,  3, -1,  5, -1,  7, -1,
                        9, -1, 11, -1, 13, -1, 15, -1};
    // <a|b|c|d> => <b|undef|d|undef>
    SDValue Odd0 = DAG.getVectorShuffle(VT, dl, A, A,
                                        makeArrayRef(&Mask[0], NumElts));
    // <e|f|g|h> => <f|undef|h|undef>
    SDValue Odd1 = DAG.getVectorShuffle(VT, dl, B, B,
                                        makeArrayRef(&Mask[0], NumElts));

    // Emit two multiplies, one for the lower 2 ints and one for the higher 2
    // ints.
    MVT MulVT = MVT::getVectorVT(MVT::i64, NumElts / 2);
    unsigned Opcode =
        (IsSigned && Subtarget.hasSSE41()) ? X86ISD::PMULDQ : X86ISD::PMULUDQ;
    // PMULUDQ <4 x i32> <a|b|c|d>, <4 x i32> <e|f|g|h>
    // => <2 x i64> <ae|cg>
    SDValue Mul1 = DAG.getBitcast(VT, DAG.getNode(Opcode, dl, MulVT,
                                                  DAG.getBitcast(MulVT, A),
                                                  DAG.getBitcast(MulVT, B)));
    // PMULUDQ <4 x i32> <b|undef|d|undef>, <4 x i32> <f|undef|h|undef>
    // => <2 x i64> <bf|dh>
    SDValue Mul2 = DAG.getBitcast(VT, DAG.getNode(Opcode, dl, MulVT,
                                                  DAG.getBitcast(MulVT, Odd0),
                                                  DAG.getBitcast(MulVT, Odd1)));

    // Shuffle it back into the right order.
    SmallVector<int, 16> ShufMask(NumElts);
    for (int i = 0; i != (int)NumElts; ++i)
      ShufMask[i] = (i / 2) * 2 + ((i % 2) * NumElts) + 1;

    SDValue Res = DAG.getVectorShuffle(VT, dl, Mul1, Mul2, ShufMask);

    // If we have a signed multiply but no PMULDQ fix up the result of an
    // unsigned multiply.
    if (IsSigned && !Subtarget.hasSSE41()) {
      SDValue Zero = DAG.getConstant(0, dl, VT);
      SDValue T1 = DAG.getNode(ISD::AND, dl, VT,
                               DAG.getSetCC(dl, VT, Zero, A, ISD::SETGT), B);
      SDValue T2 = DAG.getNode(ISD::AND, dl, VT,
                               DAG.getSetCC(dl, VT, Zero, B, ISD::SETGT), A);

      SDValue Fixup = DAG.getNode(ISD::ADD, dl, VT, T1, T2);
      Res = DAG.getNode(ISD::SUB, dl, VT, Res, Fixup);
    }

    return Res;
  }

  // Only i8 vectors should need custom lowering after this.
  assert((VT == MVT::v16i8 || (VT == MVT::v32i8 && Subtarget.hasInt256()) ||
         (VT == MVT::v64i8 && Subtarget.hasBWI())) &&
         "Unsupported vector type");

  // Lower v16i8/v32i8 as extension to v8i16/v16i16 vector pairs, multiply,
  // logical shift down the upper half and pack back to i8.

  // With SSE41 we can use sign/zero extend, but for pre-SSE41 we unpack
  // and then ashr/lshr the upper bits down to the lower bits before multiply.
  unsigned ExAVX = IsSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;

  if ((VT == MVT::v16i8 && Subtarget.hasInt256()) ||
      (VT == MVT::v32i8 && Subtarget.canExtendTo512BW())) {
    MVT ExVT = MVT::getVectorVT(MVT::i16, NumElts);
    SDValue ExA = DAG.getNode(ExAVX, dl, ExVT, A);
    SDValue ExB = DAG.getNode(ExAVX, dl, ExVT, B);
    SDValue Mul = DAG.getNode(ISD::MUL, dl, ExVT, ExA, ExB);
    Mul = getTargetVShiftByConstNode(X86ISD::VSRLI, dl, ExVT, Mul, 8, DAG);
    return DAG.getNode(ISD::TRUNCATE, dl, VT, Mul);
  }

  // For signed 512-bit vectors, split into 256-bit vectors to allow the
  // sign-extension to occur.
  if (VT == MVT::v64i8 && IsSigned)
    return split512IntArith(Op, DAG);

  // Signed AVX2 implementation - extend xmm subvectors to ymm.
  if (VT == MVT::v32i8 && IsSigned) {
    MVT ExVT = MVT::v16i16;
    SDValue ALo = extract128BitVector(A, 0, DAG, dl);
    SDValue BLo = extract128BitVector(B, 0, DAG, dl);
    SDValue AHi = extract128BitVector(A, NumElts / 2, DAG, dl);
    SDValue BHi = extract128BitVector(B, NumElts / 2, DAG, dl);
    ALo = DAG.getNode(ExAVX, dl, ExVT, ALo);
    BLo = DAG.getNode(ExAVX, dl, ExVT, BLo);
    AHi = DAG.getNode(ExAVX, dl, ExVT, AHi);
    BHi = DAG.getNode(ExAVX, dl, ExVT, BHi);
    SDValue Lo = DAG.getNode(ISD::MUL, dl, ExVT, ALo, BLo);
    SDValue Hi = DAG.getNode(ISD::MUL, dl, ExVT, AHi, BHi);
    Lo = getTargetVShiftByConstNode(X86ISD::VSRLI, dl, ExVT, Lo, 8, DAG);
    Hi = getTargetVShiftByConstNode(X86ISD::VSRLI, dl, ExVT, Hi, 8, DAG);

    // Bitcast back to VT and then pack all the even elements from Lo and Hi.
    // Shuffle lowering should turn this into PACKUS+PERMQ
    Lo = DAG.getBitcast(VT, Lo);
    Hi = DAG.getBitcast(VT, Hi);
    return DAG.getVectorShuffle(VT, dl, Lo, Hi,
                                { 0,  2,  4,  6,  8, 10, 12, 14,
                                 16, 18, 20, 22, 24, 26, 28, 30,
                                 32, 34, 36, 38, 40, 42, 44, 46,
                                 48, 50, 52, 54, 56, 58, 60, 62});
  }

  // For signed v16i8 and all unsigned vXi8 we will unpack the low and high
  // half of each 128 bit lane to widen to a vXi16 type. Do the multiplies,
  // shift the results and pack the half lane results back together.

  MVT ExVT = MVT::getVectorVT(MVT::i16, NumElts / 2);

  static const int PSHUFDMask[] = { 8,  9, 10, 11, 12, 13, 14, 15,
                                   -1, -1, -1, -1, -1, -1, -1, -1};

  // Extract the lo parts and zero/sign extend to i16.
  // Only use SSE4.1 instructions for signed v16i8 where using unpack requires
  // shifts to sign extend. Using unpack for unsigned only requires an xor to
  // create zeros and a copy due to tied registers contraints pre-avx. But using
  // zero_extend_vector_inreg would require an additional pshufd for the high
  // part.

  SDValue ALo, AHi;
  if (IsSigned && VT == MVT::v16i8 && Subtarget.hasSSE41()) {
    ALo = DAG.getNode(ISD::SIGN_EXTEND_VECTOR_INREG, dl, ExVT, A);

    AHi = DAG.getVectorShuffle(VT, dl, A, A, PSHUFDMask);
    AHi = DAG.getNode(ISD::SIGN_EXTEND_VECTOR_INREG, dl, ExVT, AHi);
  } else if (IsSigned) {
    ALo = DAG.getBitcast(ExVT, getUnpackl(DAG, dl, VT, DAG.getUNDEF(VT), A));
    AHi = DAG.getBitcast(ExVT, getUnpackh(DAG, dl, VT, DAG.getUNDEF(VT), A));

    ALo = getTargetVShiftByConstNode(X86ISD::VSRAI, dl, ExVT, ALo, 8, DAG);
    AHi = getTargetVShiftByConstNode(X86ISD::VSRAI, dl, ExVT, AHi, 8, DAG);
  } else {
    ALo = DAG.getBitcast(ExVT, getUnpackl(DAG, dl, VT, A,
                                          DAG.getConstant(0, dl, VT)));
    AHi = DAG.getBitcast(ExVT, getUnpackh(DAG, dl, VT, A,
                                          DAG.getConstant(0, dl, VT)));
  }

  SDValue BLo, BHi;
  if (ISD::isBuildVectorOfConstantSDNodes(B.getNode())) {
    // If the LHS is a constant, manually unpackl/unpackh and extend.
    SmallVector<SDValue, 16> LoOps, HiOps;
    for (unsigned i = 0; i != NumElts; i += 16) {
      for (unsigned j = 0; j != 8; ++j) {
        SDValue LoOp = B.getOperand(i + j);
        SDValue HiOp = B.getOperand(i + j + 8);

        if (IsSigned) {
          LoOp = DAG.getSExtOrTrunc(LoOp, dl, MVT::i16);
          HiOp = DAG.getSExtOrTrunc(HiOp, dl, MVT::i16);
        } else {
          LoOp = DAG.getZExtOrTrunc(LoOp, dl, MVT::i16);
          HiOp = DAG.getZExtOrTrunc(HiOp, dl, MVT::i16);
        }

        LoOps.push_back(LoOp);
        HiOps.push_back(HiOp);
      }
    }

    BLo = DAG.getBuildVector(ExVT, dl, LoOps);
    BHi = DAG.getBuildVector(ExVT, dl, HiOps);
  } else if (IsSigned && VT == MVT::v16i8 && Subtarget.hasSSE41()) {
    BLo = DAG.getNode(ISD::SIGN_EXTEND_VECTOR_INREG, dl, ExVT, B);

    BHi = DAG.getVectorShuffle(VT, dl, B, B, PSHUFDMask);
    BHi = DAG.getNode(ISD::SIGN_EXTEND_VECTOR_INREG, dl, ExVT, BHi);
  } else if (IsSigned) {
    BLo = DAG.getBitcast(ExVT, getUnpackl(DAG, dl, VT, DAG.getUNDEF(VT), B));
    BHi = DAG.getBitcast(ExVT, getUnpackh(DAG, dl, VT, DAG.getUNDEF(VT), B));

    BLo = getTargetVShiftByConstNode(X86ISD::VSRAI, dl, ExVT, BLo, 8, DAG);
    BHi = getTargetVShiftByConstNode(X86ISD::VSRAI, dl, ExVT, BHi, 8, DAG);
  } else {
    BLo = DAG.getBitcast(ExVT, getUnpackl(DAG, dl, VT, B,
                                          DAG.getConstant(0, dl, VT)));
    BHi = DAG.getBitcast(ExVT, getUnpackh(DAG, dl, VT, B,
                                          DAG.getConstant(0, dl, VT)));
  }

  // Multiply, lshr the upper 8bits to the lower 8bits of the lo/hi results and
  // pack back to vXi8.
  SDValue RLo = DAG.getNode(ISD::MUL, dl, ExVT, ALo, BLo);
  SDValue RHi = DAG.getNode(ISD::MUL, dl, ExVT, AHi, BHi);
  RLo = getTargetVShiftByConstNode(X86ISD::VSRLI, dl, ExVT, RLo, 8, DAG);
  RHi = getTargetVShiftByConstNode(X86ISD::VSRLI, dl, ExVT, RHi, 8, DAG);

  // Bitcast back to VT and then pack all the even elements from Lo and Hi.
  return DAG.getNode(X86ISD::PACKUS, dl, VT, RLo, RHi);
}

SDValue X86TargetLowering::LowerWin64_i128OP(SDValue Op, SelectionDAG &DAG) const {
  assert(Subtarget.isTargetWin64() && "Unexpected target");
  EVT VT = Op.getValueType();
  assert(VT.isInteger() && VT.getSizeInBits() == 128 &&
         "Unexpected return type for lowering");

  RTLIB::Libcall LC;
  bool isSigned;
  switch (Op->getOpcode()) {
  default: llvm_unreachable("Unexpected request for libcall!");
  case ISD::SDIV:      isSigned = true;  LC = RTLIB::SDIV_I128;    break;
  case ISD::UDIV:      isSigned = false; LC = RTLIB::UDIV_I128;    break;
  case ISD::SREM:      isSigned = true;  LC = RTLIB::SREM_I128;    break;
  case ISD::UREM:      isSigned = false; LC = RTLIB::UREM_I128;    break;
  case ISD::SDIVREM:   isSigned = true;  LC = RTLIB::SDIVREM_I128; break;
  case ISD::UDIVREM:   isSigned = false; LC = RTLIB::UDIVREM_I128; break;
  }

  SDLoc dl(Op);
  SDValue InChain = DAG.getEntryNode();

  TargetLowering::ArgListTy Args;
  TargetLowering::ArgListEntry Entry;
  for (unsigned i = 0, e = Op->getNumOperands(); i != e; ++i) {
    EVT ArgVT = Op->getOperand(i).getValueType();
    assert(ArgVT.isInteger() && ArgVT.getSizeInBits() == 128 &&
           "Unexpected argument type for lowering");
    SDValue StackPtr = DAG.CreateStackTemporary(ArgVT, 16);
    int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
    MachinePointerInfo MPI =
        MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SPFI);
    Entry.Node = StackPtr;
    InChain = DAG.getStore(InChain, dl, Op->getOperand(i), StackPtr,
                           MPI, /* Alignment = */ 16);
    Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext());
    Entry.Ty = PointerType::get(ArgTy,0);
    Entry.IsSExt = false;
    Entry.IsZExt = false;
    Args.push_back(Entry);
  }

  SDValue Callee = DAG.getExternalSymbol(getLibcallName(LC),
                                         getPointerTy(DAG.getDataLayout()));

  TargetLowering::CallLoweringInfo CLI(DAG);
  CLI.setDebugLoc(dl)
      .setChain(InChain)
      .setLibCallee(
          getLibcallCallingConv(LC),
          static_cast<EVT>(MVT::v2i64).getTypeForEVT(*DAG.getContext()), Callee,
          std::move(Args))
      .setInRegister()
      .setSExtResult(isSigned)
      .setZExtResult(!isSigned);

  std::pair<SDValue, SDValue> CallInfo = LowerCallTo(CLI);
  return DAG.getBitcast(VT, CallInfo.first);
}

// Return true if the required (according to Opcode) shift-imm form is natively
// supported by the Subtarget
static bool SupportedVectorShiftWithImm(MVT VT, const X86Subtarget &Subtarget,
                                        unsigned Opcode) {
  if (VT.getScalarSizeInBits() < 16)
    return false;

  if (VT.is512BitVector() && Subtarget.hasAVX512() &&
      (VT.getScalarSizeInBits() > 16 || Subtarget.hasBWI()))
    return true;

  bool LShift = (VT.is128BitVector() && Subtarget.hasSSE2()) ||
                (VT.is256BitVector() && Subtarget.hasInt256());

  bool AShift = LShift && (Subtarget.hasAVX512() ||
                           (VT != MVT::v2i64 && VT != MVT::v4i64));
  return (Opcode == ISD::SRA) ? AShift : LShift;
}

// The shift amount is a variable, but it is the same for all vector lanes.
// These instructions are defined together with shift-immediate.
static
bool SupportedVectorShiftWithBaseAmnt(MVT VT, const X86Subtarget &Subtarget,
                                      unsigned Opcode) {
  return SupportedVectorShiftWithImm(VT, Subtarget, Opcode);
}

// Return true if the required (according to Opcode) variable-shift form is
// natively supported by the Subtarget
static bool SupportedVectorVarShift(MVT VT, const X86Subtarget &Subtarget,
                                    unsigned Opcode) {

  if (!Subtarget.hasInt256() || VT.getScalarSizeInBits() < 16)
    return false;

  // vXi16 supported only on AVX-512, BWI
  if (VT.getScalarSizeInBits() == 16 && !Subtarget.hasBWI())
    return false;

  if (Subtarget.hasAVX512())
    return true;

  bool LShift = VT.is128BitVector() || VT.is256BitVector();
  bool AShift = LShift &&  VT != MVT::v2i64 && VT != MVT::v4i64;
  return (Opcode == ISD::SRA) ? AShift : LShift;
}

static SDValue LowerScalarImmediateShift(SDValue Op, SelectionDAG &DAG,
                                         const X86Subtarget &Subtarget) {
  MVT VT = Op.getSimpleValueType();
  SDLoc dl(Op);
  SDValue R = Op.getOperand(0);
  SDValue Amt = Op.getOperand(1);
  unsigned X86Opc = getTargetVShiftUniformOpcode(Op.getOpcode(), false);

  auto ArithmeticShiftRight64 = [&](uint64_t ShiftAmt) {
    assert((VT == MVT::v2i64 || VT == MVT::v4i64) && "Unexpected SRA type");
    MVT ExVT = MVT::getVectorVT(MVT::i32, VT.getVectorNumElements() * 2);
    SDValue Ex = DAG.getBitcast(ExVT, R);

    // ashr(R, 63) === cmp_slt(R, 0)
    if (ShiftAmt == 63 && Subtarget.hasSSE42()) {
      assert((VT != MVT::v4i64 || Subtarget.hasInt256()) &&
             "Unsupported PCMPGT op");
      return DAG.getNode(X86ISD::PCMPGT, dl, VT, DAG.getConstant(0, dl, VT), R);
    }

    if (ShiftAmt >= 32) {
      // Splat sign to upper i32 dst, and SRA upper i32 src to lower i32.
      SDValue Upper =
          getTargetVShiftByConstNode(X86ISD::VSRAI, dl, ExVT, Ex, 31, DAG);
      SDValue Lower = getTargetVShiftByConstNode(X86ISD::VSRAI, dl, ExVT, Ex,
                                                 ShiftAmt - 32, DAG);
      if (VT == MVT::v2i64)
        Ex = DAG.getVectorShuffle(ExVT, dl, Upper, Lower, {5, 1, 7, 3});
      if (VT == MVT::v4i64)
        Ex = DAG.getVectorShuffle(ExVT, dl, Upper, Lower,
                                  {9, 1, 11, 3, 13, 5, 15, 7});
    } else {
      // SRA upper i32, SRL whole i64 and select lower i32.
      SDValue Upper = getTargetVShiftByConstNode(X86ISD::VSRAI, dl, ExVT, Ex,
                                                 ShiftAmt, DAG);
      SDValue Lower =
          getTargetVShiftByConstNode(X86ISD::VSRLI, dl, VT, R, ShiftAmt, DAG);
      Lower = DAG.getBitcast(ExVT, Lower);
      if (VT == MVT::v2i64)
        Ex = DAG.getVectorShuffle(ExVT, dl, Upper, Lower, {4, 1, 6, 3});
      if (VT == MVT::v4i64)
        Ex = DAG.getVectorShuffle(ExVT, dl, Upper, Lower,
                                  {8, 1, 10, 3, 12, 5, 14, 7});
    }
    return DAG.getBitcast(VT, Ex);
  };

  // Optimize shl/srl/sra with constant shift amount.
  APInt APIntShiftAmt;
  if (!X86::isConstantSplat(Amt, APIntShiftAmt))
    return SDValue();

  // If the shift amount is out of range, return undef.
  if (APIntShiftAmt.uge(VT.getScalarSizeInBits()))
    return DAG.getUNDEF(VT);

  uint64_t ShiftAmt = APIntShiftAmt.getZExtValue();

  if (SupportedVectorShiftWithImm(VT, Subtarget, Op.getOpcode()))
    return getTargetVShiftByConstNode(X86Opc, dl, VT, R, ShiftAmt, DAG);

  // i64 SRA needs to be performed as partial shifts.
  if (((!Subtarget.hasXOP() && VT == MVT::v2i64) ||
       (Subtarget.hasInt256() && VT == MVT::v4i64)) &&
      Op.getOpcode() == ISD::SRA)
    return ArithmeticShiftRight64(ShiftAmt);

  if (VT == MVT::v16i8 || (Subtarget.hasInt256() && VT == MVT::v32i8) ||
      VT == MVT::v64i8) {
    unsigned NumElts = VT.getVectorNumElements();
    MVT ShiftVT = MVT::getVectorVT(MVT::i16, NumElts / 2);

    // Simple i8 add case
    if (Op.getOpcode() == ISD::SHL && ShiftAmt == 1)
      return DAG.getNode(ISD::ADD, dl, VT, R, R);

    // ashr(R, 7)  === cmp_slt(R, 0)
    if (Op.getOpcode() == ISD::SRA && ShiftAmt == 7) {
      SDValue Zeros = DAG.getConstant(0, dl, VT);
      if (VT.is512BitVector()) {
        assert(VT == MVT::v64i8 && "Unexpected element type!");
        SDValue CMP = DAG.getSetCC(dl, MVT::v64i1, Zeros, R, ISD::SETGT);
        return DAG.getNode(ISD::SIGN_EXTEND, dl, VT, CMP);
      }
      return DAG.getNode(X86ISD::PCMPGT, dl, VT, Zeros, R);
    }

    // XOP can shift v16i8 directly instead of as shift v8i16 + mask.
    if (VT == MVT::v16i8 && Subtarget.hasXOP())
      return SDValue();

    if (Op.getOpcode() == ISD::SHL) {
      // Make a large shift.
      SDValue SHL = getTargetVShiftByConstNode(X86ISD::VSHLI, dl, ShiftVT, R,
                                               ShiftAmt, DAG);
      SHL = DAG.getBitcast(VT, SHL);
      // Zero out the rightmost bits.
      APInt Mask = APInt::getHighBitsSet(8, 8 - ShiftAmt);
      return DAG.getNode(ISD::AND, dl, VT, SHL, DAG.getConstant(Mask, dl, VT));
    }
    if (Op.getOpcode() == ISD::SRL) {
      // Make a large shift.
      SDValue SRL = getTargetVShiftByConstNode(X86ISD::VSRLI, dl, ShiftVT, R,
                                               ShiftAmt, DAG);
      SRL = DAG.getBitcast(VT, SRL);
      // Zero out the leftmost bits.
      return DAG.getNode(ISD::AND, dl, VT, SRL,
                         DAG.getConstant(uint8_t(-1U) >> ShiftAmt, dl, VT));
    }
    if (Op.getOpcode() == ISD::SRA) {
      // ashr(R, Amt) === sub(xor(lshr(R, Amt), Mask), Mask)
      SDValue Res = DAG.getNode(ISD::SRL, dl, VT, R, Amt);

      SDValue Mask = DAG.getConstant(128 >> ShiftAmt, dl, VT);
      Res = DAG.getNode(ISD::XOR, dl, VT, Res, Mask);
      Res = DAG.getNode(ISD::SUB, dl, VT, Res, Mask);
      return Res;
    }
    llvm_unreachable("Unknown shift opcode.");
  }

  return SDValue();
}

static SDValue LowerScalarVariableShift(SDValue Op, SelectionDAG &DAG,
                                        const X86Subtarget &Subtarget) {
  MVT VT = Op.getSimpleValueType();
  SDLoc dl(Op);
  SDValue R = Op.getOperand(0);
  SDValue Amt = Op.getOperand(1);
  unsigned Opcode = Op.getOpcode();
  unsigned X86OpcI = getTargetVShiftUniformOpcode(Opcode, false);
  unsigned X86OpcV = getTargetVShiftUniformOpcode(Opcode, true);

  if (SDValue BaseShAmt = DAG.getSplatValue(Amt)) {
    if (SupportedVectorShiftWithBaseAmnt(VT, Subtarget, Opcode)) {
      MVT EltVT = VT.getVectorElementType();
      assert(EltVT.bitsLE(MVT::i64) && "Unexpected element type!");
      if (EltVT != MVT::i64 && EltVT.bitsGT(MVT::i32))
        BaseShAmt = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i64, BaseShAmt);
      else if (EltVT.bitsLT(MVT::i32))
        BaseShAmt = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, BaseShAmt);

      return getTargetVShiftNode(X86OpcI, dl, VT, R, BaseShAmt, Subtarget, DAG);
    }

    // vXi8 shifts - shift as v8i16 + mask result.
    if (((VT == MVT::v16i8 && !Subtarget.canExtendTo512DQ()) ||
         (VT == MVT::v32i8 && !Subtarget.canExtendTo512BW()) ||
         VT == MVT::v64i8) &&
        !Subtarget.hasXOP()) {
      unsigned NumElts = VT.getVectorNumElements();
      MVT ExtVT = MVT::getVectorVT(MVT::i16, NumElts / 2);
      if (SupportedVectorShiftWithBaseAmnt(ExtVT, Subtarget, Opcode)) {
        unsigned LogicalOp = (Opcode == ISD::SHL ? ISD::SHL : ISD::SRL);
        unsigned LogicalX86Op = getTargetVShiftUniformOpcode(LogicalOp, false);
        BaseShAmt = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, BaseShAmt);

        // Create the mask using vXi16 shifts. For shift-rights we need to move
        // the upper byte down before splatting the vXi8 mask.
        SDValue BitMask = DAG.getConstant(-1, dl, ExtVT);
        BitMask = getTargetVShiftNode(LogicalX86Op, dl, ExtVT, BitMask,
                                      BaseShAmt, Subtarget, DAG);
        if (Opcode != ISD::SHL)
          BitMask = getTargetVShiftByConstNode(LogicalX86Op, dl, ExtVT, BitMask,
                                               8, DAG);
        BitMask = DAG.getBitcast(VT, BitMask);
        BitMask = DAG.getVectorShuffle(VT, dl, BitMask, BitMask,
                                       SmallVector<int, 64>(NumElts, 0));

        SDValue Res = getTargetVShiftNode(LogicalX86Op, dl, ExtVT,
                                          DAG.getBitcast(ExtVT, R), BaseShAmt,
                                          Subtarget, DAG);
        Res = DAG.getBitcast(VT, Res);
        Res = DAG.getNode(ISD::AND, dl, VT, Res, BitMask);

        if (Opcode == ISD::SRA) {
          // ashr(R, Amt) === sub(xor(lshr(R, Amt), SignMask), SignMask)
          // SignMask = lshr(SignBit, Amt) - safe to do this with PSRLW.
          SDValue SignMask = DAG.getConstant(0x8080, dl, ExtVT);
          SignMask = getTargetVShiftNode(LogicalX86Op, dl, ExtVT, SignMask,
                                         BaseShAmt, Subtarget, DAG);
          SignMask = DAG.getBitcast(VT, SignMask);
          Res = DAG.getNode(ISD::XOR, dl, VT, Res, SignMask);
          Res = DAG.getNode(ISD::SUB, dl, VT, Res, SignMask);
        }
        return Res;
      }
    }
  }

  // Check cases (mainly 32-bit) where i64 is expanded into high and low parts.
  if (VT == MVT::v2i64 && Amt.getOpcode() == ISD::BITCAST &&
      Amt.getOperand(0).getOpcode() == ISD::BUILD_VECTOR) {
    Amt = Amt.getOperand(0);
    unsigned Ratio = 64 / Amt.getScalarValueSizeInBits();
    std::vector<SDValue> Vals(Ratio);
    for (unsigned i = 0; i != Ratio; ++i)
      Vals[i] = Amt.getOperand(i);
    for (unsigned i = Ratio, e = Amt.getNumOperands(); i != e; i += Ratio) {
      for (unsigned j = 0; j != Ratio; ++j)
        if (Vals[j] != Amt.getOperand(i + j))
          return SDValue();
    }

    if (SupportedVectorShiftWithBaseAmnt(VT, Subtarget, Op.getOpcode()))
      return DAG.getNode(X86OpcV, dl, VT, R, Op.getOperand(1));
  }
  return SDValue();
}

// Convert a shift/rotate left amount to a multiplication scale factor.
static SDValue convertShiftLeftToScale(SDValue Amt, const SDLoc &dl,
                                       const X86Subtarget &Subtarget,
                                       SelectionDAG &DAG) {
  MVT VT = Amt.getSimpleValueType();
  if (!(VT == MVT::v8i16 || VT == MVT::v4i32 ||
        (Subtarget.hasInt256() && VT == MVT::v16i16) ||
        (!Subtarget.hasAVX512() && VT == MVT::v16i8)))
    return SDValue();

  if (ISD::isBuildVectorOfConstantSDNodes(Amt.getNode())) {
    SmallVector<SDValue, 8> Elts;
    MVT SVT = VT.getVectorElementType();
    unsigned SVTBits = SVT.getSizeInBits();
    APInt One(SVTBits, 1);
    unsigned NumElems = VT.getVectorNumElements();

    for (unsigned i = 0; i != NumElems; ++i) {
      SDValue Op = Amt->getOperand(i);
      if (Op->isUndef()) {
        Elts.push_back(Op);
        continue;
      }

      ConstantSDNode *ND = cast<ConstantSDNode>(Op);
      APInt C(SVTBits, ND->getZExtValue());
      uint64_t ShAmt = C.getZExtValue();
      if (ShAmt >= SVTBits) {
        Elts.push_back(DAG.getUNDEF(SVT));
        continue;
      }
      Elts.push_back(DAG.getConstant(One.shl(ShAmt), dl, SVT));
    }
    return DAG.getBuildVector(VT, dl, Elts);
  }

  // If the target doesn't support variable shifts, use either FP conversion
  // or integer multiplication to avoid shifting each element individually.
  if (VT == MVT::v4i32) {
    Amt = DAG.getNode(ISD::SHL, dl, VT, Amt, DAG.getConstant(23, dl, VT));
    Amt = DAG.getNode(ISD::ADD, dl, VT, Amt,
                      DAG.getConstant(0x3f800000U, dl, VT));
    Amt = DAG.getBitcast(MVT::v4f32, Amt);
    return DAG.getNode(ISD::FP_TO_SINT, dl, VT, Amt);
  }

  // AVX2 can more effectively perform this as a zext/trunc to/from v8i32.
  if (VT == MVT::v8i16 && !Subtarget.hasAVX2()) {
    SDValue Z = DAG.getConstant(0, dl, VT);
    SDValue Lo = DAG.getBitcast(MVT::v4i32, getUnpackl(DAG, dl, VT, Amt, Z));
    SDValue Hi = DAG.getBitcast(MVT::v4i32, getUnpackh(DAG, dl, VT, Amt, Z));
    Lo = convertShiftLeftToScale(Lo, dl, Subtarget, DAG);
    Hi = convertShiftLeftToScale(Hi, dl, Subtarget, DAG);
    if (Subtarget.hasSSE41())
      return DAG.getNode(X86ISD::PACKUS, dl, VT, Lo, Hi);

    return DAG.getVectorShuffle(VT, dl, DAG.getBitcast(VT, Lo),
                                        DAG.getBitcast(VT, Hi),
                                        {0, 2, 4, 6, 8, 10, 12, 14});
  }

  return SDValue();
}

static SDValue LowerShift(SDValue Op, const X86Subtarget &Subtarget,
                          SelectionDAG &DAG) {
  MVT VT = Op.getSimpleValueType();
  SDLoc dl(Op);
  SDValue R = Op.getOperand(0);
  SDValue Amt = Op.getOperand(1);
  unsigned EltSizeInBits = VT.getScalarSizeInBits();
  bool ConstantAmt = ISD::isBuildVectorOfConstantSDNodes(Amt.getNode());

  unsigned Opc = Op.getOpcode();
  unsigned X86OpcV = getTargetVShiftUniformOpcode(Opc, true);
  unsigned X86OpcI = getTargetVShiftUniformOpcode(Opc, false);

  assert(VT.isVector() && "Custom lowering only for vector shifts!");
  assert(Subtarget.hasSSE2() && "Only custom lower when we have SSE2!");

  if (SDValue V = LowerScalarImmediateShift(Op, DAG, Subtarget))
    return V;

  if (SDValue V = LowerScalarVariableShift(Op, DAG, Subtarget))
    return V;

  if (SupportedVectorVarShift(VT, Subtarget, Opc))
    return Op;

  // XOP has 128-bit variable logical/arithmetic shifts.
  // +ve/-ve Amt = shift left/right.
  if (Subtarget.hasXOP() && (VT == MVT::v2i64 || VT == MVT::v4i32 ||
                             VT == MVT::v8i16 || VT == MVT::v16i8)) {
    if (Opc == ISD::SRL || Opc == ISD::SRA) {
      SDValue Zero = DAG.getConstant(0, dl, VT);
      Amt = DAG.getNode(ISD::SUB, dl, VT, Zero, Amt);
    }
    if (Opc == ISD::SHL || Opc == ISD::SRL)
      return DAG.getNode(X86ISD::VPSHL, dl, VT, R, Amt);
    if (Opc == ISD::SRA)
      return DAG.getNode(X86ISD::VPSHA, dl, VT, R, Amt);
  }

  // 2i64 vector logical shifts can efficiently avoid scalarization - do the
  // shifts per-lane and then shuffle the partial results back together.
  if (VT == MVT::v2i64 && Opc != ISD::SRA) {
    // Splat the shift amounts so the scalar shifts above will catch it.
    SDValue Amt0 = DAG.getVectorShuffle(VT, dl, Amt, Amt, {0, 0});
    SDValue Amt1 = DAG.getVectorShuffle(VT, dl, Amt, Amt, {1, 1});
    SDValue R0 = DAG.getNode(Opc, dl, VT, R, Amt0);
    SDValue R1 = DAG.getNode(Opc, dl, VT, R, Amt1);
    return DAG.getVectorShuffle(VT, dl, R0, R1, {0, 3});
  }

  // i64 vector arithmetic shift can be emulated with the transform:
  // M = lshr(SIGN_MASK, Amt)
  // ashr(R, Amt) === sub(xor(lshr(R, Amt), M), M)
  if ((VT == MVT::v2i64 || (VT == MVT::v4i64 && Subtarget.hasInt256())) &&
      Opc == ISD::SRA) {
    SDValue S = DAG.getConstant(APInt::getSignMask(64), dl, VT);
    SDValue M = DAG.getNode(ISD::SRL, dl, VT, S, Amt);
    R = DAG.getNode(ISD::SRL, dl, VT, R, Amt);
    R = DAG.getNode(ISD::XOR, dl, VT, R, M);
    R = DAG.getNode(ISD::SUB, dl, VT, R, M);
    return R;
  }

  // If possible, lower this shift as a sequence of two shifts by
  // constant plus a BLENDing shuffle instead of scalarizing it.
  // Example:
  //   (v4i32 (srl A, (build_vector < X, Y, Y, Y>)))
  //
  // Could be rewritten as:
  //   (v4i32 (MOVSS (srl A, <Y,Y,Y,Y>), (srl A, <X,X,X,X>)))
  //
  // The advantage is that the two shifts from the example would be
  // lowered as X86ISD::VSRLI nodes in parallel before blending.
  if (ConstantAmt && (VT == MVT::v8i16 || VT == MVT::v4i32 ||
                      (VT == MVT::v16i16 && Subtarget.hasInt256()))) {
    SDValue Amt1, Amt2;
    unsigned NumElts = VT.getVectorNumElements();
    SmallVector<int, 8> ShuffleMask;
    for (unsigned i = 0; i != NumElts; ++i) {
      SDValue A = Amt->getOperand(i);
      if (A.isUndef()) {
        ShuffleMask.push_back(SM_SentinelUndef);
        continue;
      }
      if (!Amt1 || Amt1 == A) {
        ShuffleMask.push_back(i);
        Amt1 = A;
        continue;
      }
      if (!Amt2 || Amt2 == A) {
        ShuffleMask.push_back(i + NumElts);
        Amt2 = A;
        continue;
      }
      break;
    }

    // Only perform this blend if we can perform it without loading a mask.
    if (ShuffleMask.size() == NumElts && Amt1 && Amt2 &&
        (VT != MVT::v16i16 ||
         is128BitLaneRepeatedShuffleMask(VT, ShuffleMask)) &&
        (VT == MVT::v4i32 || Subtarget.hasSSE41() || Opc != ISD::SHL ||
         canWidenShuffleElements(ShuffleMask))) {
      auto *Cst1 = dyn_cast<ConstantSDNode>(Amt1);
      auto *Cst2 = dyn_cast<ConstantSDNode>(Amt2);
      if (Cst1 && Cst2 && Cst1->getAPIntValue().ult(EltSizeInBits) &&
          Cst2->getAPIntValue().ult(EltSizeInBits)) {
        SDValue Shift1 = getTargetVShiftByConstNode(X86OpcI, dl, VT, R,
                                                    Cst1->getZExtValue(), DAG);
        SDValue Shift2 = getTargetVShiftByConstNode(X86OpcI, dl, VT, R,
                                                    Cst2->getZExtValue(), DAG);
        return DAG.getVectorShuffle(VT, dl, Shift1, Shift2, ShuffleMask);
      }
    }
  }

  // If possible, lower this packed shift into a vector multiply instead of
  // expanding it into a sequence of scalar shifts.
  if (Opc == ISD::SHL)
    if (SDValue Scale = convertShiftLeftToScale(Amt, dl, Subtarget, DAG))
      return DAG.getNode(ISD::MUL, dl, VT, R, Scale);

  // Constant ISD::SRL can be performed efficiently on vXi16 vectors as we
  // can replace with ISD::MULHU, creating scale factor from (NumEltBits - Amt).
  if (Opc == ISD::SRL && ConstantAmt &&
      (VT == MVT::v8i16 || (VT == MVT::v16i16 && Subtarget.hasInt256()))) {
    SDValue EltBits = DAG.getConstant(EltSizeInBits, dl, VT);
    SDValue RAmt = DAG.getNode(ISD::SUB, dl, VT, EltBits, Amt);
    if (SDValue Scale = convertShiftLeftToScale(RAmt, dl, Subtarget, DAG)) {
      SDValue Zero = DAG.getConstant(0, dl, VT);
      SDValue ZAmt = DAG.getSetCC(dl, VT, Amt, Zero, ISD::SETEQ);
      SDValue Res = DAG.getNode(ISD::MULHU, dl, VT, R, Scale);
      return DAG.getSelect(dl, VT, ZAmt, R, Res);
    }
  }

  // Constant ISD::SRA can be performed efficiently on vXi16 vectors as we
  // can replace with ISD::MULHS, creating scale factor from (NumEltBits - Amt).
  // TODO: Special case handling for shift by 0/1, really we can afford either
  // of these cases in pre-SSE41/XOP/AVX512 but not both.
  if (Opc == ISD::SRA && ConstantAmt &&
      (VT == MVT::v8i16 || (VT == MVT::v16i16 && Subtarget.hasInt256())) &&
      ((Subtarget.hasSSE41() && !Subtarget.hasXOP() &&
        !Subtarget.hasAVX512()) ||
       DAG.isKnownNeverZero(Amt))) {
    SDValue EltBits = DAG.getConstant(EltSizeInBits, dl, VT);
    SDValue RAmt = DAG.getNode(ISD::SUB, dl, VT, EltBits, Amt);
    if (SDValue Scale = convertShiftLeftToScale(RAmt, dl, Subtarget, DAG)) {
      SDValue Amt0 =
          DAG.getSetCC(dl, VT, Amt, DAG.getConstant(0, dl, VT), ISD::SETEQ);
      SDValue Amt1 =
          DAG.getSetCC(dl, VT, Amt, DAG.getConstant(1, dl, VT), ISD::SETEQ);
      SDValue Sra1 =
          getTargetVShiftByConstNode(X86ISD::VSRAI, dl, VT, R, 1, DAG);
      SDValue Res = DAG.getNode(ISD::MULHS, dl, VT, R, Scale);
      Res = DAG.getSelect(dl, VT, Amt0, R, Res);
      return DAG.getSelect(dl, VT, Amt1, Sra1, Res);
    }
  }

  // v4i32 Non Uniform Shifts.
  // If the shift amount is constant we can shift each lane using the SSE2
  // immediate shifts, else we need to zero-extend each lane to the lower i64
  // and shift using the SSE2 variable shifts.
  // The separate results can then be blended together.
  if (VT == MVT::v4i32) {
    SDValue Amt0, Amt1, Amt2, Amt3;
    if (ConstantAmt) {
      Amt0 = DAG.getVectorShuffle(VT, dl, Amt, DAG.getUNDEF(VT), {0, 0, 0, 0});
      Amt1 = DAG.getVectorShuffle(VT, dl, Amt, DAG.getUNDEF(VT), {1, 1, 1, 1});
      Amt2 = DAG.getVectorShuffle(VT, dl, Amt, DAG.getUNDEF(VT), {2, 2, 2, 2});
      Amt3 = DAG.getVectorShuffle(VT, dl, Amt, DAG.getUNDEF(VT), {3, 3, 3, 3});
    } else {
      // The SSE2 shifts use the lower i64 as the same shift amount for
      // all lanes and the upper i64 is ignored. On AVX we're better off
      // just zero-extending, but for SSE just duplicating the top 16-bits is
      // cheaper and has the same effect for out of range values.
      if (Subtarget.hasAVX()) {
        SDValue Z = DAG.getConstant(0, dl, VT);
        Amt0 = DAG.getVectorShuffle(VT, dl, Amt, Z, {0, 4, -1, -1});
        Amt1 = DAG.getVectorShuffle(VT, dl, Amt, Z, {1, 5, -1, -1});
        Amt2 = DAG.getVectorShuffle(VT, dl, Amt, Z, {2, 6, -1, -1});
        Amt3 = DAG.getVectorShuffle(VT, dl, Amt, Z, {3, 7, -1, -1});
      } else {
        SDValue Amt01 = DAG.getBitcast(MVT::v8i16, Amt);
        SDValue Amt23 = DAG.getVectorShuffle(MVT::v8i16, dl, Amt01, Amt01,
                                             {4, 5, 6, 7, -1, -1, -1, -1});
        Amt0 = DAG.getVectorShuffle(MVT::v8i16, dl, Amt01, Amt01,
                                    {0, 1, 1, 1, -1, -1, -1, -1});
        Amt1 = DAG.getVectorShuffle(MVT::v8i16, dl, Amt01, Amt01,
                                    {2, 3, 3, 3, -1, -1, -1, -1});
        Amt2 = DAG.getVectorShuffle(MVT::v8i16, dl, Amt23, Amt23,
                                    {0, 1, 1, 1, -1, -1, -1, -1});
        Amt3 = DAG.getVectorShuffle(MVT::v8i16, dl, Amt23, Amt23,
                                    {2, 3, 3, 3, -1, -1, -1, -1});
      }
    }

    unsigned ShOpc = ConstantAmt ? Opc : X86OpcV;
    SDValue R0 = DAG.getNode(ShOpc, dl, VT, R, DAG.getBitcast(VT, Amt0));
    SDValue R1 = DAG.getNode(ShOpc, dl, VT, R, DAG.getBitcast(VT, Amt1));
    SDValue R2 = DAG.getNode(ShOpc, dl, VT, R, DAG.getBitcast(VT, Amt2));
    SDValue R3 = DAG.getNode(ShOpc, dl, VT, R, DAG.getBitcast(VT, Amt3));

    // Merge the shifted lane results optimally with/without PBLENDW.
    // TODO - ideally shuffle combining would handle this.
    if (Subtarget.hasSSE41()) {
      SDValue R02 = DAG.getVectorShuffle(VT, dl, R0, R2, {0, -1, 6, -1});
      SDValue R13 = DAG.getVectorShuffle(VT, dl, R1, R3, {-1, 1, -1, 7});
      return DAG.getVectorShuffle(VT, dl, R02, R13, {0, 5, 2, 7});
    }
    SDValue R01 = DAG.getVectorShuffle(VT, dl, R0, R1, {0, -1, -1, 5});
    SDValue R23 = DAG.getVectorShuffle(VT, dl, R2, R3, {2, -1, -1, 7});
    return DAG.getVectorShuffle(VT, dl, R01, R23, {0, 3, 4, 7});
  }

  // It's worth extending once and using the vXi16/vXi32 shifts for smaller
  // types, but without AVX512 the extra overheads to get from vXi8 to vXi32
  // make the existing SSE solution better.
  // NOTE: We honor prefered vector width before promoting to 512-bits.
  if ((Subtarget.hasInt256() && VT == MVT::v8i16) ||
      (Subtarget.canExtendTo512DQ() && VT == MVT::v16i16) ||
      (Subtarget.canExtendTo512DQ() && VT == MVT::v16i8) ||
      (Subtarget.canExtendTo512BW() && VT == MVT::v32i8) ||
      (Subtarget.hasBWI() && Subtarget.hasVLX() && VT == MVT::v16i8)) {
    assert((!Subtarget.hasBWI() || VT == MVT::v32i8 || VT == MVT::v16i8) &&
           "Unexpected vector type");
    MVT EvtSVT = Subtarget.hasBWI() ? MVT::i16 : MVT::i32;
    MVT ExtVT = MVT::getVectorVT(EvtSVT, VT.getVectorNumElements());
    unsigned ExtOpc = Opc == ISD::SRA ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
    R = DAG.getNode(ExtOpc, dl, ExtVT, R);
    Amt = DAG.getNode(ISD::ZERO_EXTEND, dl, ExtVT, Amt);
    return DAG.getNode(ISD::TRUNCATE, dl, VT,
                       DAG.getNode(Opc, dl, ExtVT, R, Amt));
  }

  // Constant ISD::SRA/SRL can be performed efficiently on vXi8 vectors as we
  // extend to vXi16 to perform a MUL scale effectively as a MUL_LOHI.
  if (ConstantAmt && (Opc == ISD::SRA || Opc == ISD::SRL) &&
      (VT == MVT::v16i8 || VT == MVT::v64i8 ||
       (VT == MVT::v32i8 && Subtarget.hasInt256())) &&
      !Subtarget.hasXOP()) {
    int NumElts = VT.getVectorNumElements();
    SDValue Cst8 = DAG.getTargetConstant(8, dl, MVT::i8);

    // Extend constant shift amount to vXi16 (it doesn't matter if the type
    // isn't legal).
    MVT ExVT = MVT::getVectorVT(MVT::i16, NumElts);
    Amt = DAG.getZExtOrTrunc(Amt, dl, ExVT);
    Amt = DAG.getNode(ISD::SUB, dl, ExVT, DAG.getConstant(8, dl, ExVT), Amt);
    Amt = DAG.getNode(ISD::SHL, dl, ExVT, DAG.getConstant(1, dl, ExVT), Amt);
    assert(ISD::isBuildVectorOfConstantSDNodes(Amt.getNode()) &&
           "Constant build vector expected");

    if (VT == MVT::v16i8 && Subtarget.hasInt256()) {
      R = Opc == ISD::SRA ? DAG.getSExtOrTrunc(R, dl, ExVT)
                          : DAG.getZExtOrTrunc(R, dl, ExVT);
      R = DAG.getNode(ISD::MUL, dl, ExVT, R, Amt);
      R = DAG.getNode(X86ISD::VSRLI, dl, ExVT, R, Cst8);
      return DAG.getZExtOrTrunc(R, dl, VT);
    }

    SmallVector<SDValue, 16> LoAmt, HiAmt;
    for (int i = 0; i != NumElts; i += 16) {
      for (int j = 0; j != 8; ++j) {
        LoAmt.push_back(Amt.getOperand(i + j));
        HiAmt.push_back(Amt.getOperand(i + j + 8));
      }
    }

    MVT VT16 = MVT::getVectorVT(MVT::i16, NumElts / 2);
    SDValue LoA = DAG.getBuildVector(VT16, dl, LoAmt);
    SDValue HiA = DAG.getBuildVector(VT16, dl, HiAmt);

    SDValue LoR = DAG.getBitcast(VT16, getUnpackl(DAG, dl, VT, R, R));
    SDValue HiR = DAG.getBitcast(VT16, getUnpackh(DAG, dl, VT, R, R));
    LoR = DAG.getNode(X86OpcI, dl, VT16, LoR, Cst8);
    HiR = DAG.getNode(X86OpcI, dl, VT16, HiR, Cst8);
    LoR = DAG.getNode(ISD::MUL, dl, VT16, LoR, LoA);
    HiR = DAG.getNode(ISD::MUL, dl, VT16, HiR, HiA);
    LoR = DAG.getNode(X86ISD::VSRLI, dl, VT16, LoR, Cst8);
    HiR = DAG.getNode(X86ISD::VSRLI, dl, VT16, HiR, Cst8);
    return DAG.getNode(X86ISD::PACKUS, dl, VT, LoR, HiR);
  }

  if (VT == MVT::v16i8 ||
      (VT == MVT::v32i8 && Subtarget.hasInt256() && !Subtarget.hasXOP()) ||
      (VT == MVT::v64i8 && Subtarget.hasBWI())) {
    MVT ExtVT = MVT::getVectorVT(MVT::i16, VT.getVectorNumElements() / 2);

    auto SignBitSelect = [&](MVT SelVT, SDValue Sel, SDValue V0, SDValue V1) {
      if (VT.is512BitVector()) {
        // On AVX512BW targets we make use of the fact that VSELECT lowers
        // to a masked blend which selects bytes based just on the sign bit
        // extracted to a mask.
        MVT MaskVT = MVT::getVectorVT(MVT::i1, VT.getVectorNumElements());
        V0 = DAG.getBitcast(VT, V0);
        V1 = DAG.getBitcast(VT, V1);
        Sel = DAG.getBitcast(VT, Sel);
        Sel = DAG.getSetCC(dl, MaskVT, DAG.getConstant(0, dl, VT), Sel,
                           ISD::SETGT);
        return DAG.getBitcast(SelVT, DAG.getSelect(dl, VT, Sel, V0, V1));
      } else if (Subtarget.hasSSE41()) {
        // On SSE41 targets we make use of the fact that VSELECT lowers
        // to PBLENDVB which selects bytes based just on the sign bit.
        V0 = DAG.getBitcast(VT, V0);
        V1 = DAG.getBitcast(VT, V1);
        Sel = DAG.getBitcast(VT, Sel);
        return DAG.getBitcast(SelVT, DAG.getSelect(dl, VT, Sel, V0, V1));
      }
      // On pre-SSE41 targets we test for the sign bit by comparing to
      // zero - a negative value will set all bits of the lanes to true
      // and VSELECT uses that in its OR(AND(V0,C),AND(V1,~C)) lowering.
      SDValue Z = DAG.getConstant(0, dl, SelVT);
      SDValue C = DAG.getNode(X86ISD::PCMPGT, dl, SelVT, Z, Sel);
      return DAG.getSelect(dl, SelVT, C, V0, V1);
    };

    // Turn 'a' into a mask suitable for VSELECT: a = a << 5;
    // We can safely do this using i16 shifts as we're only interested in
    // the 3 lower bits of each byte.
    Amt = DAG.getBitcast(ExtVT, Amt);
    Amt = getTargetVShiftByConstNode(X86ISD::VSHLI, dl, ExtVT, Amt, 5, DAG);
    Amt = DAG.getBitcast(VT, Amt);

    if (Opc == ISD::SHL || Opc == ISD::SRL) {
      // r = VSELECT(r, shift(r, 4), a);
      SDValue M = DAG.getNode(Opc, dl, VT, R, DAG.getConstant(4, dl, VT));
      R = SignBitSelect(VT, Amt, M, R);

      // a += a
      Amt = DAG.getNode(ISD::ADD, dl, VT, Amt, Amt);

      // r = VSELECT(r, shift(r, 2), a);
      M = DAG.getNode(Opc, dl, VT, R, DAG.getConstant(2, dl, VT));
      R = SignBitSelect(VT, Amt, M, R);

      // a += a
      Amt = DAG.getNode(ISD::ADD, dl, VT, Amt, Amt);

      // return VSELECT(r, shift(r, 1), a);
      M = DAG.getNode(Opc, dl, VT, R, DAG.getConstant(1, dl, VT));
      R = SignBitSelect(VT, Amt, M, R);
      return R;
    }

    if (Opc == ISD::SRA) {
      // For SRA we need to unpack each byte to the higher byte of a i16 vector
      // so we can correctly sign extend. We don't care what happens to the
      // lower byte.
      SDValue ALo = getUnpackl(DAG, dl, VT, DAG.getUNDEF(VT), Amt);
      SDValue AHi = getUnpackh(DAG, dl, VT, DAG.getUNDEF(VT), Amt);
      SDValue RLo = getUnpackl(DAG, dl, VT, DAG.getUNDEF(VT), R);
      SDValue RHi = getUnpackh(DAG, dl, VT, DAG.getUNDEF(VT), R);
      ALo = DAG.getBitcast(ExtVT, ALo);
      AHi = DAG.getBitcast(ExtVT, AHi);
      RLo = DAG.getBitcast(ExtVT, RLo);
      RHi = DAG.getBitcast(ExtVT, RHi);

      // r = VSELECT(r, shift(r, 4), a);
      SDValue MLo = getTargetVShiftByConstNode(X86OpcI, dl, ExtVT, RLo, 4, DAG);
      SDValue MHi = getTargetVShiftByConstNode(X86OpcI, dl, ExtVT, RHi, 4, DAG);
      RLo = SignBitSelect(ExtVT, ALo, MLo, RLo);
      RHi = SignBitSelect(ExtVT, AHi, MHi, RHi);

      // a += a
      ALo = DAG.getNode(ISD::ADD, dl, ExtVT, ALo, ALo);
      AHi = DAG.getNode(ISD::ADD, dl, ExtVT, AHi, AHi);

      // r = VSELECT(r, shift(r, 2), a);
      MLo = getTargetVShiftByConstNode(X86OpcI, dl, ExtVT, RLo, 2, DAG);
      MHi = getTargetVShiftByConstNode(X86OpcI, dl, ExtVT, RHi, 2, DAG);
      RLo = SignBitSelect(ExtVT, ALo, MLo, RLo);
      RHi = SignBitSelect(ExtVT, AHi, MHi, RHi);

      // a += a
      ALo = DAG.getNode(ISD::ADD, dl, ExtVT, ALo, ALo);
      AHi = DAG.getNode(ISD::ADD, dl, ExtVT, AHi, AHi);

      // r = VSELECT(r, shift(r, 1), a);
      MLo = getTargetVShiftByConstNode(X86OpcI, dl, ExtVT, RLo, 1, DAG);
      MHi = getTargetVShiftByConstNode(X86OpcI, dl, ExtVT, RHi, 1, DAG);
      RLo = SignBitSelect(ExtVT, ALo, MLo, RLo);
      RHi = SignBitSelect(ExtVT, AHi, MHi, RHi);

      // Logical shift the result back to the lower byte, leaving a zero upper
      // byte meaning that we can safely pack with PACKUSWB.
      RLo = getTargetVShiftByConstNode(X86ISD::VSRLI, dl, ExtVT, RLo, 8, DAG);
      RHi = getTargetVShiftByConstNode(X86ISD::VSRLI, dl, ExtVT, RHi, 8, DAG);
      return DAG.getNode(X86ISD::PACKUS, dl, VT, RLo, RHi);
    }
  }

  if (Subtarget.hasInt256() && !Subtarget.hasXOP() && VT == MVT::v16i16) {
    MVT ExtVT = MVT::v8i32;
    SDValue Z = DAG.getConstant(0, dl, VT);
    SDValue ALo = getUnpackl(DAG, dl, VT, Amt, Z);
    SDValue AHi = getUnpackh(DAG, dl, VT, Amt, Z);
    SDValue RLo = getUnpackl(DAG, dl, VT, Z, R);
    SDValue RHi = getUnpackh(DAG, dl, VT, Z, R);
    ALo = DAG.getBitcast(ExtVT, ALo);
    AHi = DAG.getBitcast(ExtVT, AHi);
    RLo = DAG.getBitcast(ExtVT, RLo);
    RHi = DAG.getBitcast(ExtVT, RHi);
    SDValue Lo = DAG.getNode(Opc, dl, ExtVT, RLo, ALo);
    SDValue Hi = DAG.getNode(Opc, dl, ExtVT, RHi, AHi);
    Lo = getTargetVShiftByConstNode(X86ISD::VSRLI, dl, ExtVT, Lo, 16, DAG);
    Hi = getTargetVShiftByConstNode(X86ISD::VSRLI, dl, ExtVT, Hi, 16, DAG);
    return DAG.getNode(X86ISD::PACKUS, dl, VT, Lo, Hi);
  }

  if (VT == MVT::v8i16) {
    // If we have a constant shift amount, the non-SSE41 path is best as
    // avoiding bitcasts make it easier to constant fold and reduce to PBLENDW.
    bool UseSSE41 = Subtarget.hasSSE41() &&
                    !ISD::isBuildVectorOfConstantSDNodes(Amt.getNode());

    auto SignBitSelect = [&](SDValue Sel, SDValue V0, SDValue V1) {
      // On SSE41 targets we make use of the fact that VSELECT lowers
      // to PBLENDVB which selects bytes based just on the sign bit.
      if (UseSSE41) {
        MVT ExtVT = MVT::getVectorVT(MVT::i8, VT.getVectorNumElements() * 2);
        V0 = DAG.getBitcast(ExtVT, V0);
        V1 = DAG.getBitcast(ExtVT, V1);
        Sel = DAG.getBitcast(ExtVT, Sel);
        return DAG.getBitcast(VT, DAG.getSelect(dl, ExtVT, Sel, V0, V1));
      }
      // On pre-SSE41 targets we splat the sign bit - a negative value will
      // set all bits of the lanes to true and VSELECT uses that in
      // its OR(AND(V0,C),AND(V1,~C)) lowering.
      SDValue C =
          getTargetVShiftByConstNode(X86ISD::VSRAI, dl, VT, Sel, 15, DAG);
      return DAG.getSelect(dl, VT, C, V0, V1);
    };

    // Turn 'a' into a mask suitable for VSELECT: a = a << 12;
    if (UseSSE41) {
      // On SSE41 targets we need to replicate the shift mask in both
      // bytes for PBLENDVB.
      Amt = DAG.getNode(
          ISD::OR, dl, VT,
          getTargetVShiftByConstNode(X86ISD::VSHLI, dl, VT, Amt, 4, DAG),
          getTargetVShiftByConstNode(X86ISD::VSHLI, dl, VT, Amt, 12, DAG));
    } else {
      Amt = getTargetVShiftByConstNode(X86ISD::VSHLI, dl, VT, Amt, 12, DAG);
    }

    // r = VSELECT(r, shift(r, 8), a);
    SDValue M = getTargetVShiftByConstNode(X86OpcI, dl, VT, R, 8, DAG);
    R = SignBitSelect(Amt, M, R);

    // a += a
    Amt = DAG.getNode(ISD::ADD, dl, VT, Amt, Amt);

    // r = VSELECT(r, shift(r, 4), a);
    M = getTargetVShiftByConstNode(X86OpcI, dl, VT, R, 4, DAG);
    R = SignBitSelect(Amt, M, R);

    // a += a
    Amt = DAG.getNode(ISD::ADD, dl, VT, Amt, Amt);

    // r = VSELECT(r, shift(r, 2), a);
    M = getTargetVShiftByConstNode(X86OpcI, dl, VT, R, 2, DAG);
    R = SignBitSelect(Amt, M, R);

    // a += a
    Amt = DAG.getNode(ISD::ADD, dl, VT, Amt, Amt);

    // return VSELECT(r, shift(r, 1), a);
    M = getTargetVShiftByConstNode(X86OpcI, dl, VT, R, 1, DAG);
    R = SignBitSelect(Amt, M, R);
    return R;
  }

  // Decompose 256-bit shifts into 128-bit shifts.
  if (VT.is256BitVector())
    return split256IntArith(Op, DAG);

  return SDValue();
}

static SDValue LowerRotate(SDValue Op, const X86Subtarget &Subtarget,
                           SelectionDAG &DAG) {
  MVT VT = Op.getSimpleValueType();
  assert(VT.isVector() && "Custom lowering only for vector rotates!");

  SDLoc DL(Op);
  SDValue R = Op.getOperand(0);
  SDValue Amt = Op.getOperand(1);
  unsigned Opcode = Op.getOpcode();
  unsigned EltSizeInBits = VT.getScalarSizeInBits();
  int NumElts = VT.getVectorNumElements();

  // Check for constant splat rotation amount.
  APInt CstSplatValue;
  bool IsCstSplat = X86::isConstantSplat(Amt, CstSplatValue);

  // Check for splat rotate by zero.
  if (IsCstSplat && CstSplatValue.urem(EltSizeInBits) == 0)
    return R;

  // AVX512 implicitly uses modulo rotation amounts.
  if (Subtarget.hasAVX512() && 32 <= EltSizeInBits) {
    // Attempt to rotate by immediate.
    if (IsCstSplat) {
      unsigned RotOpc = (Opcode == ISD::ROTL ? X86ISD::VROTLI : X86ISD::VROTRI);
      uint64_t RotAmt = CstSplatValue.urem(EltSizeInBits);
      return DAG.getNode(RotOpc, DL, VT, R,
                         DAG.getTargetConstant(RotAmt, DL, MVT::i8));
    }

    // Else, fall-back on VPROLV/VPRORV.
    return Op;
  }

  assert((Opcode == ISD::ROTL) && "Only ROTL supported");

  // XOP has 128-bit vector variable + immediate rotates.
  // +ve/-ve Amt = rotate left/right - just need to handle ISD::ROTL.
  // XOP implicitly uses modulo rotation amounts.
  if (Subtarget.hasXOP()) {
    if (VT.is256BitVector())
      return split256IntArith(Op, DAG);
    assert(VT.is128BitVector() && "Only rotate 128-bit vectors!");

    // Attempt to rotate by immediate.
    if (IsCstSplat) {
      uint64_t RotAmt = CstSplatValue.urem(EltSizeInBits);
      return DAG.getNode(X86ISD::VROTLI, DL, VT, R,
                         DAG.getTargetConstant(RotAmt, DL, MVT::i8));
    }

    // Use general rotate by variable (per-element).
    return Op;
  }

  // Split 256-bit integers on pre-AVX2 targets.
  if (VT.is256BitVector() && !Subtarget.hasAVX2())
    return split256IntArith(Op, DAG);

  assert((VT == MVT::v4i32 || VT == MVT::v8i16 || VT == MVT::v16i8 ||
          ((VT == MVT::v8i32 || VT == MVT::v16i16 || VT == MVT::v32i8) &&
           Subtarget.hasAVX2())) &&
         "Only vXi32/vXi16/vXi8 vector rotates supported");

  // Rotate by an uniform constant - expand back to shifts.
  if (IsCstSplat)
    return SDValue();

  bool IsSplatAmt = DAG.isSplatValue(Amt);

  // v16i8/v32i8: Split rotation into rot4/rot2/rot1 stages and select by
  // the amount bit.
  if (EltSizeInBits == 8 && !IsSplatAmt) {
    if (ISD::isBuildVectorOfConstantSDNodes(Amt.getNode()))
      return SDValue();

    // We don't need ModuloAmt here as we just peek at individual bits.
    MVT ExtVT = MVT::getVectorVT(MVT::i16, NumElts / 2);

    auto SignBitSelect = [&](MVT SelVT, SDValue Sel, SDValue V0, SDValue V1) {
      if (Subtarget.hasSSE41()) {
        // On SSE41 targets we make use of the fact that VSELECT lowers
        // to PBLENDVB which selects bytes based just on the sign bit.
        V0 = DAG.getBitcast(VT, V0);
        V1 = DAG.getBitcast(VT, V1);
        Sel = DAG.getBitcast(VT, Sel);
        return DAG.getBitcast(SelVT, DAG.getSelect(DL, VT, Sel, V0, V1));
      }
      // On pre-SSE41 targets we test for the sign bit by comparing to
      // zero - a negative value will set all bits of the lanes to true
      // and VSELECT uses that in its OR(AND(V0,C),AND(V1,~C)) lowering.
      SDValue Z = DAG.getConstant(0, DL, SelVT);
      SDValue C = DAG.getNode(X86ISD::PCMPGT, DL, SelVT, Z, Sel);
      return DAG.getSelect(DL, SelVT, C, V0, V1);
    };

    // Turn 'a' into a mask suitable for VSELECT: a = a << 5;
    // We can safely do this using i16 shifts as we're only interested in
    // the 3 lower bits of each byte.
    Amt = DAG.getBitcast(ExtVT, Amt);
    Amt = DAG.getNode(ISD::SHL, DL, ExtVT, Amt, DAG.getConstant(5, DL, ExtVT));
    Amt = DAG.getBitcast(VT, Amt);

    // r = VSELECT(r, rot(r, 4), a);
    SDValue M;
    M = DAG.getNode(
        ISD::OR, DL, VT,
        DAG.getNode(ISD::SHL, DL, VT, R, DAG.getConstant(4, DL, VT)),
        DAG.getNode(ISD::SRL, DL, VT, R, DAG.getConstant(4, DL, VT)));
    R = SignBitSelect(VT, Amt, M, R);

    // a += a
    Amt = DAG.getNode(ISD::ADD, DL, VT, Amt, Amt);

    // r = VSELECT(r, rot(r, 2), a);
    M = DAG.getNode(
        ISD::OR, DL, VT,
        DAG.getNode(ISD::SHL, DL, VT, R, DAG.getConstant(2, DL, VT)),
        DAG.getNode(ISD::SRL, DL, VT, R, DAG.getConstant(6, DL, VT)));
    R = SignBitSelect(VT, Amt, M, R);

    // a += a
    Amt = DAG.getNode(ISD::ADD, DL, VT, Amt, Amt);

    // return VSELECT(r, rot(r, 1), a);
    M = DAG.getNode(
        ISD::OR, DL, VT,
        DAG.getNode(ISD::SHL, DL, VT, R, DAG.getConstant(1, DL, VT)),
        DAG.getNode(ISD::SRL, DL, VT, R, DAG.getConstant(7, DL, VT)));
    return SignBitSelect(VT, Amt, M, R);
  }

  // ISD::ROT* uses modulo rotate amounts.
  Amt = DAG.getNode(ISD::AND, DL, VT, Amt,
                    DAG.getConstant(EltSizeInBits - 1, DL, VT));

  bool ConstantAmt = ISD::isBuildVectorOfConstantSDNodes(Amt.getNode());
  bool LegalVarShifts = SupportedVectorVarShift(VT, Subtarget, ISD::SHL) &&
                        SupportedVectorVarShift(VT, Subtarget, ISD::SRL);

  // Fallback for splats + all supported variable shifts.
  // Fallback for non-constants AVX2 vXi16 as well.
  if (IsSplatAmt || LegalVarShifts || (Subtarget.hasAVX2() && !ConstantAmt)) {
    SDValue AmtR = DAG.getConstant(EltSizeInBits, DL, VT);
    AmtR = DAG.getNode(ISD::SUB, DL, VT, AmtR, Amt);
    SDValue SHL = DAG.getNode(ISD::SHL, DL, VT, R, Amt);
    SDValue SRL = DAG.getNode(ISD::SRL, DL, VT, R, AmtR);
    return DAG.getNode(ISD::OR, DL, VT, SHL, SRL);
  }

  // As with shifts, convert the rotation amount to a multiplication factor.
  SDValue Scale = convertShiftLeftToScale(Amt, DL, Subtarget, DAG);
  assert(Scale && "Failed to convert ROTL amount to scale");

  // v8i16/v16i16: perform unsigned multiply hi/lo and OR the results.
  if (EltSizeInBits == 16) {
    SDValue Lo = DAG.getNode(ISD::MUL, DL, VT, R, Scale);
    SDValue Hi = DAG.getNode(ISD::MULHU, DL, VT, R, Scale);
    return DAG.getNode(ISD::OR, DL, VT, Lo, Hi);
  }

  // v4i32: make use of the PMULUDQ instruction to multiply 2 lanes of v4i32
  // to v2i64 results at a time. The upper 32-bits contain the wrapped bits
  // that can then be OR'd with the lower 32-bits.
  assert(VT == MVT::v4i32 && "Only v4i32 vector rotate expected");
  static const int OddMask[] = {1, -1, 3, -1};
  SDValue R13 = DAG.getVectorShuffle(VT, DL, R, R, OddMask);
  SDValue Scale13 = DAG.getVectorShuffle(VT, DL, Scale, Scale, OddMask);

  SDValue Res02 = DAG.getNode(X86ISD::PMULUDQ, DL, MVT::v2i64,
                              DAG.getBitcast(MVT::v2i64, R),
                              DAG.getBitcast(MVT::v2i64, Scale));
  SDValue Res13 = DAG.getNode(X86ISD::PMULUDQ, DL, MVT::v2i64,
                              DAG.getBitcast(MVT::v2i64, R13),
                              DAG.getBitcast(MVT::v2i64, Scale13));
  Res02 = DAG.getBitcast(VT, Res02);
  Res13 = DAG.getBitcast(VT, Res13);

  return DAG.getNode(ISD::OR, DL, VT,
                     DAG.getVectorShuffle(VT, DL, Res02, Res13, {0, 4, 2, 6}),
                     DAG.getVectorShuffle(VT, DL, Res02, Res13, {1, 5, 3, 7}));
}

/// Returns true if the operand type is exactly twice the native width, and
/// the corresponding cmpxchg8b or cmpxchg16b instruction is available.
/// Used to know whether to use cmpxchg8/16b when expanding atomic operations
/// (otherwise we leave them alone to become __sync_fetch_and_... calls).
bool X86TargetLowering::needsCmpXchgNb(Type *MemType) const {
  unsigned OpWidth = MemType->getPrimitiveSizeInBits();

  if (OpWidth == 64)
    return Subtarget.hasCmpxchg8b() && !Subtarget.is64Bit();
  if (OpWidth == 128)
    return Subtarget.hasCmpxchg16b();

  return false;
}

bool X86TargetLowering::shouldExpandAtomicStoreInIR(StoreInst *SI) const {
  Type *MemType = SI->getValueOperand()->getType();

  bool NoImplicitFloatOps =
      SI->getFunction()->hasFnAttribute(Attribute::NoImplicitFloat);
  if (MemType->getPrimitiveSizeInBits() == 64 && !Subtarget.is64Bit() &&
      !Subtarget.useSoftFloat() && !NoImplicitFloatOps &&
      (Subtarget.hasSSE1() || Subtarget.hasX87()))
    return false;

  return needsCmpXchgNb(MemType);
}

// Note: this turns large loads into lock cmpxchg8b/16b.
// TODO: In 32-bit mode, use MOVLPS when SSE1 is available?
TargetLowering::AtomicExpansionKind
X86TargetLowering::shouldExpandAtomicLoadInIR(LoadInst *LI) const {
  Type *MemType = LI->getType();

  // If this a 64 bit atomic load on a 32-bit target and SSE2 is enabled, we
  // can use movq to do the load. If we have X87 we can load into an 80-bit
  // X87 register and store it to a stack temporary.
  bool NoImplicitFloatOps =
      LI->getFunction()->hasFnAttribute(Attribute::NoImplicitFloat);
  if (MemType->getPrimitiveSizeInBits() == 64 && !Subtarget.is64Bit() &&
      !Subtarget.useSoftFloat() && !NoImplicitFloatOps &&
      (Subtarget.hasSSE1() || Subtarget.hasX87()))
    return AtomicExpansionKind::None;

  return needsCmpXchgNb(MemType) ? AtomicExpansionKind::CmpXChg
                                 : AtomicExpansionKind::None;
}

TargetLowering::AtomicExpansionKind
X86TargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
  unsigned NativeWidth = Subtarget.is64Bit() ? 64 : 32;
  Type *MemType = AI->getType();

  // If the operand is too big, we must see if cmpxchg8/16b is available
  // and default to library calls otherwise.
  if (MemType->getPrimitiveSizeInBits() > NativeWidth) {
    return needsCmpXchgNb(MemType) ? AtomicExpansionKind::CmpXChg
                                   : AtomicExpansionKind::None;
  }

  AtomicRMWInst::BinOp Op = AI->getOperation();
  switch (Op) {
  default:
    llvm_unreachable("Unknown atomic operation");
  case AtomicRMWInst::Xchg:
  case AtomicRMWInst::Add:
  case AtomicRMWInst::Sub:
    // It's better to use xadd, xsub or xchg for these in all cases.
    return AtomicExpansionKind::None;
  case AtomicRMWInst::Or:
  case AtomicRMWInst::And:
  case AtomicRMWInst::Xor:
    // If the atomicrmw's result isn't actually used, we can just add a "lock"
    // prefix to a normal instruction for these operations.
    return !AI->use_empty() ? AtomicExpansionKind::CmpXChg
                            : AtomicExpansionKind::None;
  case AtomicRMWInst::Nand:
  case AtomicRMWInst::Max:
  case AtomicRMWInst::Min:
  case AtomicRMWInst::UMax:
  case AtomicRMWInst::UMin:
  case AtomicRMWInst::FAdd:
  case AtomicRMWInst::FSub:
    // These always require a non-trivial set of data operations on x86. We must
    // use a cmpxchg loop.
    return AtomicExpansionKind::CmpXChg;
  }
}

LoadInst *
X86TargetLowering::lowerIdempotentRMWIntoFencedLoad(AtomicRMWInst *AI) const {
  unsigned NativeWidth = Subtarget.is64Bit() ? 64 : 32;
  Type *MemType = AI->getType();
  // Accesses larger than the native width are turned into cmpxchg/libcalls, so
  // there is no benefit in turning such RMWs into loads, and it is actually
  // harmful as it introduces a mfence.
  if (MemType->getPrimitiveSizeInBits() > NativeWidth)
    return nullptr;

  // If this is a canonical idempotent atomicrmw w/no uses, we have a better
  // lowering available in lowerAtomicArith.
  // TODO: push more cases through this path.
  if (auto *C = dyn_cast<ConstantInt>(AI->getValOperand()))
    if (AI->getOperation() == AtomicRMWInst::Or && C->isZero() &&
        AI->use_empty())
      return nullptr;

  IRBuilder<> Builder(AI);
  Module *M = Builder.GetInsertBlock()->getParent()->getParent();
  auto SSID = AI->getSyncScopeID();
  // We must restrict the ordering to avoid generating loads with Release or
  // ReleaseAcquire orderings.
  auto Order = AtomicCmpXchgInst::getStrongestFailureOrdering(AI->getOrdering());

  // Before the load we need a fence. Here is an example lifted from
  // http://www.hpl.hp.com/techreports/2012/HPL-2012-68.pdf showing why a fence
  // is required:
  // Thread 0:
  //   x.store(1, relaxed);
  //   r1 = y.fetch_add(0, release);
  // Thread 1:
  //   y.fetch_add(42, acquire);
  //   r2 = x.load(relaxed);
  // r1 = r2 = 0 is impossible, but becomes possible if the idempotent rmw is
  // lowered to just a load without a fence. A mfence flushes the store buffer,
  // making the optimization clearly correct.
  // FIXME: it is required if isReleaseOrStronger(Order) but it is not clear
  // otherwise, we might be able to be more aggressive on relaxed idempotent
  // rmw. In practice, they do not look useful, so we don't try to be
  // especially clever.
  if (SSID == SyncScope::SingleThread)
    // FIXME: we could just insert an X86ISD::MEMBARRIER here, except we are at
    // the IR level, so we must wrap it in an intrinsic.
    return nullptr;

  if (!Subtarget.hasMFence())
    // FIXME: it might make sense to use a locked operation here but on a
    // different cache-line to prevent cache-line bouncing. In practice it
    // is probably a small win, and x86 processors without mfence are rare
    // enough that we do not bother.
    return nullptr;

  Function *MFence =
      llvm::Intrinsic::getDeclaration(M, Intrinsic::x86_sse2_mfence);
  Builder.CreateCall(MFence, {});

  // Finally we can emit the atomic load.
  LoadInst *Loaded =
      Builder.CreateAlignedLoad(AI->getType(), AI->getPointerOperand(),
                                Align(AI->getType()->getPrimitiveSizeInBits()));
  Loaded->setAtomic(Order, SSID);
  AI->replaceAllUsesWith(Loaded);
  AI->eraseFromParent();
  return Loaded;
}

bool X86TargetLowering::lowerAtomicStoreAsStoreSDNode(const StoreInst &SI) const {
  if (!SI.isUnordered())
    return false;
  return ExperimentalUnorderedISEL;
}
bool X86TargetLowering::lowerAtomicLoadAsLoadSDNode(const LoadInst &LI) const {
  if (!LI.isUnordered())
    return false;
  return ExperimentalUnorderedISEL;
}


/// Emit a locked operation on a stack location which does not change any
/// memory location, but does involve a lock prefix.  Location is chosen to be
/// a) very likely accessed only by a single thread to minimize cache traffic,
/// and b) definitely dereferenceable.  Returns the new Chain result.
static SDValue emitLockedStackOp(SelectionDAG &DAG,
                                 const X86Subtarget &Subtarget,
                                 SDValue Chain, SDLoc DL) {
  // Implementation notes:
  // 1) LOCK prefix creates a full read/write reordering barrier for memory
  // operations issued by the current processor.  As such, the location
  // referenced is not relevant for the ordering properties of the instruction.
  // See: Intel® 64 and IA-32 ArchitecturesSoftware Developer’s Manual,
  // 8.2.3.9  Loads and Stores Are Not Reordered with Locked Instructions
  // 2) Using an immediate operand appears to be the best encoding choice
  // here since it doesn't require an extra register.
  // 3) OR appears to be very slightly faster than ADD. (Though, the difference
  // is small enough it might just be measurement noise.)
  // 4) When choosing offsets, there are several contributing factors:
  //   a) If there's no redzone, we default to TOS.  (We could allocate a cache
  //      line aligned stack object to improve this case.)
  //   b) To minimize our chances of introducing a false dependence, we prefer
  //      to offset the stack usage from TOS slightly.
  //   c) To minimize concerns about cross thread stack usage - in particular,
  //      the idiomatic MyThreadPool.run([&StackVars]() {...}) pattern which
  //      captures state in the TOS frame and accesses it from many threads -
  //      we want to use an offset such that the offset is in a distinct cache
  //      line from the TOS frame.
  //
  // For a general discussion of the tradeoffs and benchmark results, see:
  // https://shipilev.net/blog/2014/on-the-fence-with-dependencies/

  auto &MF = DAG.getMachineFunction();
  auto &TFL = *Subtarget.getFrameLowering();
  const unsigned SPOffset = TFL.has128ByteRedZone(MF) ? -64 : 0;

  if (Subtarget.is64Bit()) {
    SDValue Zero = DAG.getTargetConstant(0, DL, MVT::i32);
    SDValue Ops[] = {
      DAG.getRegister(X86::RSP, MVT::i64),                  // Base
      DAG.getTargetConstant(1, DL, MVT::i8),                // Scale
      DAG.getRegister(0, MVT::i64),                         // Index
      DAG.getTargetConstant(SPOffset, DL, MVT::i32),        // Disp
      DAG.getRegister(0, MVT::i16),                         // Segment.
      Zero,
      Chain};
    SDNode *Res = DAG.getMachineNode(X86::OR32mi8Locked, DL, MVT::i32,
                                     MVT::Other, Ops);
    return SDValue(Res, 1);
  }

  SDValue Zero = DAG.getTargetConstant(0, DL, MVT::i32);
  SDValue Ops[] = {
    DAG.getRegister(X86::ESP, MVT::i32),            // Base
    DAG.getTargetConstant(1, DL, MVT::i8),          // Scale
    DAG.getRegister(0, MVT::i32),                   // Index
    DAG.getTargetConstant(SPOffset, DL, MVT::i32),  // Disp
    DAG.getRegister(0, MVT::i16),                   // Segment.
    Zero,
    Chain
  };
  SDNode *Res = DAG.getMachineNode(X86::OR32mi8Locked, DL, MVT::i32,
                                   MVT::Other, Ops);
  return SDValue(Res, 1);
}

static SDValue LowerATOMIC_FENCE(SDValue Op, const X86Subtarget &Subtarget,
                                 SelectionDAG &DAG) {
  SDLoc dl(Op);
  AtomicOrdering FenceOrdering =
      static_cast<AtomicOrdering>(Op.getConstantOperandVal(1));
  SyncScope::ID FenceSSID =
      static_cast<SyncScope::ID>(Op.getConstantOperandVal(2));

  // The only fence that needs an instruction is a sequentially-consistent
  // cross-thread fence.
  if (FenceOrdering == AtomicOrdering::SequentiallyConsistent &&
      FenceSSID == SyncScope::System) {
    if (Subtarget.hasMFence())
      return DAG.getNode(X86ISD::MFENCE, dl, MVT::Other, Op.getOperand(0));

    SDValue Chain = Op.getOperand(0);
    return emitLockedStackOp(DAG, Subtarget, Chain, dl);
  }

  // MEMBARRIER is a compiler barrier; it codegens to a no-op.
  return DAG.getNode(X86ISD::MEMBARRIER, dl, MVT::Other, Op.getOperand(0));
}

static SDValue LowerCMP_SWAP(SDValue Op, const X86Subtarget &Subtarget,
                             SelectionDAG &DAG) {
  MVT T = Op.getSimpleValueType();
  SDLoc DL(Op);
  unsigned Reg = 0;
  unsigned size = 0;
  switch(T.SimpleTy) {
  default: llvm_unreachable("Invalid value type!");
  case MVT::i8:  Reg = X86::AL;  size = 1; break;
  case MVT::i16: Reg = X86::AX;  size = 2; break;
  case MVT::i32: Reg = X86::EAX; size = 4; break;
  case MVT::i64:
    assert(Subtarget.is64Bit() && "Node not type legal!");
    Reg = X86::RAX; size = 8;
    break;
  }
  SDValue cpIn = DAG.getCopyToReg(Op.getOperand(0), DL, Reg,
                                  Op.getOperand(2), SDValue());
  SDValue Ops[] = { cpIn.getValue(0),
                    Op.getOperand(1),
                    Op.getOperand(3),
                    DAG.getTargetConstant(size, DL, MVT::i8),
                    cpIn.getValue(1) };
  SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Glue);
  MachineMemOperand *MMO = cast<AtomicSDNode>(Op)->getMemOperand();
  SDValue Result = DAG.getMemIntrinsicNode(X86ISD::LCMPXCHG_DAG, DL, Tys,
                                           Ops, T, MMO);

  SDValue cpOut =
    DAG.getCopyFromReg(Result.getValue(0), DL, Reg, T, Result.getValue(1));
  SDValue EFLAGS = DAG.getCopyFromReg(cpOut.getValue(1), DL, X86::EFLAGS,
                                      MVT::i32, cpOut.getValue(2));
  SDValue Success = getSETCC(X86::COND_E, EFLAGS, DL, DAG);

  return DAG.getNode(ISD::MERGE_VALUES, DL, Op->getVTList(),
                     cpOut, Success, EFLAGS.getValue(1));
}

// Create MOVMSKB, taking into account whether we need to split for AVX1.
static SDValue getPMOVMSKB(const SDLoc &DL, SDValue V, SelectionDAG &DAG,
                           const X86Subtarget &Subtarget) {
  MVT InVT = V.getSimpleValueType();

  if (InVT == MVT::v64i8) {
    SDValue Lo, Hi;
    std::tie(Lo, Hi) = DAG.SplitVector(V, DL);
    Lo = getPMOVMSKB(DL, Lo, DAG, Subtarget);
    Hi = getPMOVMSKB(DL, Hi, DAG, Subtarget);
    Lo = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, Lo);
    Hi = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Hi);
    Hi = DAG.getNode(ISD::SHL, DL, MVT::i64, Hi,
                     DAG.getConstant(32, DL, MVT::i8));
    return DAG.getNode(ISD::OR, DL, MVT::i64, Lo, Hi);
  }
  if (InVT == MVT::v32i8 && !Subtarget.hasInt256()) {
    SDValue Lo, Hi;
    std::tie(Lo, Hi) = DAG.SplitVector(V, DL);
    Lo = DAG.getNode(X86ISD::MOVMSK, DL, MVT::i32, Lo);
    Hi = DAG.getNode(X86ISD::MOVMSK, DL, MVT::i32, Hi);
    Hi = DAG.getNode(ISD::SHL, DL, MVT::i32, Hi,
                     DAG.getConstant(16, DL, MVT::i8));
    return DAG.getNode(ISD::OR, DL, MVT::i32, Lo, Hi);
  }

  return DAG.getNode(X86ISD::MOVMSK, DL, MVT::i32, V);
}

static SDValue LowerBITCAST(SDValue Op, const X86Subtarget &Subtarget,
                            SelectionDAG &DAG) {
  SDValue Src = Op.getOperand(0);
  MVT SrcVT = Src.getSimpleValueType();
  MVT DstVT = Op.getSimpleValueType();

  // Legalize (v64i1 (bitcast i64 (X))) by splitting the i64, bitcasting each
  // half to v32i1 and concatenating the result.
  if (SrcVT == MVT::i64 && DstVT == MVT::v64i1) {
    assert(!Subtarget.is64Bit() && "Expected 32-bit mode");
    assert(Subtarget.hasBWI() && "Expected BWI target");
    SDLoc dl(Op);
    SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Src,
                             DAG.getIntPtrConstant(0, dl));
    Lo = DAG.getBitcast(MVT::v32i1, Lo);
    SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Src,
                             DAG.getIntPtrConstant(1, dl));
    Hi = DAG.getBitcast(MVT::v32i1, Hi);
    return DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v64i1, Lo, Hi);
  }

  // Custom splitting for BWI types when AVX512F is available but BWI isn't.
  if ((SrcVT == MVT::v32i16 || SrcVT == MVT::v64i8) && DstVT.isVector() &&
    DAG.getTargetLoweringInfo().isTypeLegal(DstVT)) {
    SDLoc dl(Op);
    SDValue Lo, Hi;
    std::tie(Lo, Hi) = DAG.SplitVector(Op.getOperand(0), dl);
    MVT CastVT = DstVT.getHalfNumVectorElementsVT();
    Lo = DAG.getBitcast(CastVT, Lo);
    Hi = DAG.getBitcast(CastVT, Hi);
    return DAG.getNode(ISD::CONCAT_VECTORS, dl, DstVT, Lo, Hi);
  }

  // Use MOVMSK for vector to scalar conversion to prevent scalarization.
  if ((SrcVT == MVT::v16i1 || SrcVT == MVT::v32i1) && DstVT.isScalarInteger()) {
    assert(!Subtarget.hasAVX512() && "Should use K-registers with AVX512");
    MVT SExtVT = SrcVT == MVT::v16i1 ? MVT::v16i8 : MVT::v32i8;
    SDLoc DL(Op);
    SDValue V = DAG.getSExtOrTrunc(Src, DL, SExtVT);
    V = getPMOVMSKB(DL, V, DAG, Subtarget);
    return DAG.getZExtOrTrunc(V, DL, DstVT);
  }

  assert((SrcVT == MVT::v2i32 || SrcVT == MVT::v4i16 || SrcVT == MVT::v8i8 ||
          SrcVT == MVT::i64) && "Unexpected VT!");

  assert(Subtarget.hasSSE2() && "Requires at least SSE2!");
  if (!(DstVT == MVT::f64 && SrcVT == MVT::i64) &&
      !(DstVT == MVT::x86mmx && SrcVT.isVector()))
    // This conversion needs to be expanded.
    return SDValue();

  SDLoc dl(Op);
  if (SrcVT.isVector()) {
    // Widen the vector in input in the case of MVT::v2i32.
    // Example: from MVT::v2i32 to MVT::v4i32.
    MVT NewVT = MVT::getVectorVT(SrcVT.getVectorElementType(),
                                 SrcVT.getVectorNumElements() * 2);
    Src = DAG.getNode(ISD::CONCAT_VECTORS, dl, NewVT, Src,
                      DAG.getUNDEF(SrcVT));
  } else {
    assert(SrcVT == MVT::i64 && !Subtarget.is64Bit() &&
           "Unexpected source type in LowerBITCAST");
    Src = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2i64, Src);
  }

  MVT V2X64VT = DstVT == MVT::f64 ? MVT::v2f64 : MVT::v2i64;
  Src = DAG.getNode(ISD::BITCAST, dl, V2X64VT, Src);

  if (DstVT == MVT::x86mmx)
    return DAG.getNode(X86ISD::MOVDQ2Q, dl, DstVT, Src);

  return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, DstVT, Src,
                     DAG.getIntPtrConstant(0, dl));
}

/// Compute the horizontal sum of bytes in V for the elements of VT.
///
/// Requires V to be a byte vector and VT to be an integer vector type with
/// wider elements than V's type. The width of the elements of VT determines
/// how many bytes of V are summed horizontally to produce each element of the
/// result.
static SDValue LowerHorizontalByteSum(SDValue V, MVT VT,
                                      const X86Subtarget &Subtarget,
                                      SelectionDAG &DAG) {
  SDLoc DL(V);
  MVT ByteVecVT = V.getSimpleValueType();
  MVT EltVT = VT.getVectorElementType();
  assert(ByteVecVT.getVectorElementType() == MVT::i8 &&
         "Expected value to have byte element type.");
  assert(EltVT != MVT::i8 &&
         "Horizontal byte sum only makes sense for wider elements!");
  unsigned VecSize = VT.getSizeInBits();
  assert(ByteVecVT.getSizeInBits() == VecSize && "Cannot change vector size!");

  // PSADBW instruction horizontally add all bytes and leave the result in i64
  // chunks, thus directly computes the pop count for v2i64 and v4i64.
  if (EltVT == MVT::i64) {
    SDValue Zeros = DAG.getConstant(0, DL, ByteVecVT);
    MVT SadVecVT = MVT::getVectorVT(MVT::i64, VecSize / 64);
    V = DAG.getNode(X86ISD::PSADBW, DL, SadVecVT, V, Zeros);
    return DAG.getBitcast(VT, V);
  }

  if (EltVT == MVT::i32) {
    // We unpack the low half and high half into i32s interleaved with zeros so
    // that we can use PSADBW to horizontally sum them. The most useful part of
    // this is that it lines up the results of two PSADBW instructions to be
    // two v2i64 vectors which concatenated are the 4 population counts. We can
    // then use PACKUSWB to shrink and concatenate them into a v4i32 again.
    SDValue Zeros = DAG.getConstant(0, DL, VT);
    SDValue V32 = DAG.getBitcast(VT, V);
    SDValue Low = getUnpackl(DAG, DL, VT, V32, Zeros);
    SDValue High = getUnpackh(DAG, DL, VT, V32, Zeros);

    // Do the horizontal sums into two v2i64s.
    Zeros = DAG.getConstant(0, DL, ByteVecVT);
    MVT SadVecVT = MVT::getVectorVT(MVT::i64, VecSize / 64);
    Low = DAG.getNode(X86ISD::PSADBW, DL, SadVecVT,
                      DAG.getBitcast(ByteVecVT, Low), Zeros);
    High = DAG.getNode(X86ISD::PSADBW, DL, SadVecVT,
                       DAG.getBitcast(ByteVecVT, High), Zeros);

    // Merge them together.
    MVT ShortVecVT = MVT::getVectorVT(MVT::i16, VecSize / 16);
    V = DAG.getNode(X86ISD::PACKUS, DL, ByteVecVT,
                    DAG.getBitcast(ShortVecVT, Low),
                    DAG.getBitcast(ShortVecVT, High));

    return DAG.getBitcast(VT, V);
  }

  // The only element type left is i16.
  assert(EltVT == MVT::i16 && "Unknown how to handle type");

  // To obtain pop count for each i16 element starting from the pop count for
  // i8 elements, shift the i16s left by 8, sum as i8s, and then shift as i16s
  // right by 8. It is important to shift as i16s as i8 vector shift isn't
  // directly supported.
  SDValue ShifterV = DAG.getConstant(8, DL, VT);
  SDValue Shl = DAG.getNode(ISD::SHL, DL, VT, DAG.getBitcast(VT, V), ShifterV);
  V = DAG.getNode(ISD::ADD, DL, ByteVecVT, DAG.getBitcast(ByteVecVT, Shl),
                  DAG.getBitcast(ByteVecVT, V));
  return DAG.getNode(ISD::SRL, DL, VT, DAG.getBitcast(VT, V), ShifterV);
}

static SDValue LowerVectorCTPOPInRegLUT(SDValue Op, const SDLoc &DL,
                                        const X86Subtarget &Subtarget,
                                        SelectionDAG &DAG) {
  MVT VT = Op.getSimpleValueType();
  MVT EltVT = VT.getVectorElementType();
  int NumElts = VT.getVectorNumElements();
  (void)EltVT;
  assert(EltVT == MVT::i8 && "Only vXi8 vector CTPOP lowering supported.");

  // Implement a lookup table in register by using an algorithm based on:
  // http://wm.ite.pl/articles/sse-popcount.html
  //
  // The general idea is that every lower byte nibble in the input vector is an
  // index into a in-register pre-computed pop count table. We then split up the
  // input vector in two new ones: (1) a vector with only the shifted-right
  // higher nibbles for each byte and (2) a vector with the lower nibbles (and
  // masked out higher ones) for each byte. PSHUFB is used separately with both
  // to index the in-register table. Next, both are added and the result is a
  // i8 vector where each element contains the pop count for input byte.
  const int LUT[16] = {/* 0 */ 0, /* 1 */ 1, /* 2 */ 1, /* 3 */ 2,
                       /* 4 */ 1, /* 5 */ 2, /* 6 */ 2, /* 7 */ 3,
                       /* 8 */ 1, /* 9 */ 2, /* a */ 2, /* b */ 3,
                       /* c */ 2, /* d */ 3, /* e */ 3, /* f */ 4};

  SmallVector<SDValue, 64> LUTVec;
  for (int i = 0; i < NumElts; ++i)
    LUTVec.push_back(DAG.getConstant(LUT[i % 16], DL, MVT::i8));
  SDValue InRegLUT = DAG.getBuildVector(VT, DL, LUTVec);
  SDValue M0F = DAG.getConstant(0x0F, DL, VT);

  // High nibbles
  SDValue FourV = DAG.getConstant(4, DL, VT);
  SDValue HiNibbles = DAG.getNode(ISD::SRL, DL, VT, Op, FourV);

  // Low nibbles
  SDValue LoNibbles = DAG.getNode(ISD::AND, DL, VT, Op, M0F);

  // The input vector is used as the shuffle mask that index elements into the
  // LUT. After counting low and high nibbles, add the vector to obtain the
  // final pop count per i8 element.
  SDValue HiPopCnt = DAG.getNode(X86ISD::PSHUFB, DL, VT, InRegLUT, HiNibbles);
  SDValue LoPopCnt = DAG.getNode(X86ISD::PSHUFB, DL, VT, InRegLUT, LoNibbles);
  return DAG.getNode(ISD::ADD, DL, VT, HiPopCnt, LoPopCnt);
}

// Please ensure that any codegen change from LowerVectorCTPOP is reflected in
// updated cost models in X86TTIImpl::getIntrinsicInstrCost.
static SDValue LowerVectorCTPOP(SDValue Op, const X86Subtarget &Subtarget,
                                SelectionDAG &DAG) {
  MVT VT = Op.getSimpleValueType();
  assert((VT.is512BitVector() || VT.is256BitVector() || VT.is128BitVector()) &&
         "Unknown CTPOP type to handle");
  SDLoc DL(Op.getNode());
  SDValue Op0 = Op.getOperand(0);

  // TRUNC(CTPOP(ZEXT(X))) to make use of vXi32/vXi64 VPOPCNT instructions.
  if (Subtarget.hasVPOPCNTDQ()) {
    unsigned NumElems = VT.getVectorNumElements();
    assert((VT.getVectorElementType() == MVT::i8 ||
            VT.getVectorElementType() == MVT::i16) && "Unexpected type");
    if (NumElems < 16 || (NumElems == 16 && Subtarget.canExtendTo512DQ())) {
      MVT NewVT = MVT::getVectorVT(MVT::i32, NumElems);
      Op = DAG.getNode(ISD::ZERO_EXTEND, DL, NewVT, Op0);
      Op = DAG.getNode(ISD::CTPOP, DL, NewVT, Op);
      return DAG.getNode(ISD::TRUNCATE, DL, VT, Op);
    }
  }

  // Decompose 256-bit ops into smaller 128-bit ops.
  if (VT.is256BitVector() && !Subtarget.hasInt256())
    return Lower256IntUnary(Op, DAG);

  // Decompose 512-bit ops into smaller 256-bit ops.
  if (VT.is512BitVector() && !Subtarget.hasBWI())
    return Lower512IntUnary(Op, DAG);

  // For element types greater than i8, do vXi8 pop counts and a bytesum.
  if (VT.getScalarType() != MVT::i8) {
    MVT ByteVT = MVT::getVectorVT(MVT::i8, VT.getSizeInBits() / 8);
    SDValue ByteOp = DAG.getBitcast(ByteVT, Op0);
    SDValue PopCnt8 = DAG.getNode(ISD::CTPOP, DL, ByteVT, ByteOp);
    return LowerHorizontalByteSum(PopCnt8, VT, Subtarget, DAG);
  }

  // We can't use the fast LUT approach, so fall back on LegalizeDAG.
  if (!Subtarget.hasSSSE3())
    return SDValue();

  return LowerVectorCTPOPInRegLUT(Op0, DL, Subtarget, DAG);
}

static SDValue LowerCTPOP(SDValue Op, const X86Subtarget &Subtarget,
                          SelectionDAG &DAG) {
  assert(Op.getSimpleValueType().isVector() &&
         "We only do custom lowering for vector population count.");
  return LowerVectorCTPOP(Op, Subtarget, DAG);
}

static SDValue LowerBITREVERSE_XOP(SDValue Op, SelectionDAG &DAG) {
  MVT VT = Op.getSimpleValueType();
  SDValue In = Op.getOperand(0);
  SDLoc DL(Op);

  // For scalars, its still beneficial to transfer to/from the SIMD unit to
  // perform the BITREVERSE.
  if (!VT.isVector()) {
    MVT VecVT = MVT::getVectorVT(VT, 128 / VT.getSizeInBits());
    SDValue Res = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VecVT, In);
    Res = DAG.getNode(ISD::BITREVERSE, DL, VecVT, Res);
    return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, Res,
                       DAG.getIntPtrConstant(0, DL));
  }

  int NumElts = VT.getVectorNumElements();
  int ScalarSizeInBytes = VT.getScalarSizeInBits() / 8;

  // Decompose 256-bit ops into smaller 128-bit ops.
  if (VT.is256BitVector())
    return Lower256IntUnary(Op, DAG);

  assert(VT.is128BitVector() &&
         "Only 128-bit vector bitreverse lowering supported.");

  // VPPERM reverses the bits of a byte with the permute Op (2 << 5), and we
  // perform the BSWAP in the shuffle.
  // Its best to shuffle using the second operand as this will implicitly allow
  // memory folding for multiple vectors.
  SmallVector<SDValue, 16> MaskElts;
  for (int i = 0; i != NumElts; ++i) {
    for (int j = ScalarSizeInBytes - 1; j >= 0; --j) {
      int SourceByte = 16 + (i * ScalarSizeInBytes) + j;
      int PermuteByte = SourceByte | (2 << 5);
      MaskElts.push_back(DAG.getConstant(PermuteByte, DL, MVT::i8));
    }
  }

  SDValue Mask = DAG.getBuildVector(MVT::v16i8, DL, MaskElts);
  SDValue Res = DAG.getBitcast(MVT::v16i8, In);
  Res = DAG.getNode(X86ISD::VPPERM, DL, MVT::v16i8, DAG.getUNDEF(MVT::v16i8),
                    Res, Mask);
  return DAG.getBitcast(VT, Res);
}

static SDValue LowerBITREVERSE(SDValue Op, const X86Subtarget &Subtarget,
                               SelectionDAG &DAG) {
  MVT VT = Op.getSimpleValueType();

  if (Subtarget.hasXOP() && !VT.is512BitVector())
    return LowerBITREVERSE_XOP(Op, DAG);

  assert(Subtarget.hasSSSE3() && "SSSE3 required for BITREVERSE");

  SDValue In = Op.getOperand(0);
  SDLoc DL(Op);

  // Split v8i64/v16i32 without BWI so that we can still use the PSHUFB
  // lowering.
  if (VT == MVT::v8i64 || VT == MVT::v16i32) {
    assert(!Subtarget.hasBWI() && "BWI should Expand BITREVERSE");
    return Lower512IntUnary(Op, DAG);
  }

  unsigned NumElts = VT.getVectorNumElements();
  assert(VT.getScalarType() == MVT::i8 &&
         "Only byte vector BITREVERSE supported");

  // Decompose 256-bit ops into smaller 128-bit ops on pre-AVX2.
  if (VT.is256BitVector() && !Subtarget.hasInt256())
    return Lower256IntUnary(Op, DAG);

  // Perform BITREVERSE using PSHUFB lookups. Each byte is split into
  // two nibbles and a PSHUFB lookup to find the bitreverse of each
  // 0-15 value (moved to the other nibble).
  SDValue NibbleMask = DAG.getConstant(0xF, DL, VT);
  SDValue Lo = DAG.getNode(ISD::AND, DL, VT, In, NibbleMask);
  SDValue Hi = DAG.getNode(ISD::SRL, DL, VT, In, DAG.getConstant(4, DL, VT));

  const int LoLUT[16] = {
      /* 0 */ 0x00, /* 1 */ 0x80, /* 2 */ 0x40, /* 3 */ 0xC0,
      /* 4 */ 0x20, /* 5 */ 0xA0, /* 6 */ 0x60, /* 7 */ 0xE0,
      /* 8 */ 0x10, /* 9 */ 0x90, /* a */ 0x50, /* b */ 0xD0,
      /* c */ 0x30, /* d */ 0xB0, /* e */ 0x70, /* f */ 0xF0};
  const int HiLUT[16] = {
      /* 0 */ 0x00, /* 1 */ 0x08, /* 2 */ 0x04, /* 3 */ 0x0C,
      /* 4 */ 0x02, /* 5 */ 0x0A, /* 6 */ 0x06, /* 7 */ 0x0E,
      /* 8 */ 0x01, /* 9 */ 0x09, /* a */ 0x05, /* b */ 0x0D,
      /* c */ 0x03, /* d */ 0x0B, /* e */ 0x07, /* f */ 0x0F};

  SmallVector<SDValue, 16> LoMaskElts, HiMaskElts;
  for (unsigned i = 0; i < NumElts; ++i) {
    LoMaskElts.push_back(DAG.getConstant(LoLUT[i % 16], DL, MVT::i8));
    HiMaskElts.push_back(DAG.getConstant(HiLUT[i % 16], DL, MVT::i8));
  }

  SDValue LoMask = DAG.getBuildVector(VT, DL, LoMaskElts);
  SDValue HiMask = DAG.getBuildVector(VT, DL, HiMaskElts);
  Lo = DAG.getNode(X86ISD::PSHUFB, DL, VT, LoMask, Lo);
  Hi = DAG.getNode(X86ISD::PSHUFB, DL, VT, HiMask, Hi);
  return DAG.getNode(ISD::OR, DL, VT, Lo, Hi);
}

static SDValue lowerAtomicArithWithLOCK(SDValue N, SelectionDAG &DAG,
                                        const X86Subtarget &Subtarget) {
  unsigned NewOpc = 0;
  switch (N->getOpcode()) {
  case ISD::ATOMIC_LOAD_ADD:
    NewOpc = X86ISD::LADD;
    break;
  case ISD::ATOMIC_LOAD_SUB:
    NewOpc = X86ISD::LSUB;
    break;
  case ISD::ATOMIC_LOAD_OR:
    NewOpc = X86ISD::LOR;
    break;
  case ISD::ATOMIC_LOAD_XOR:
    NewOpc = X86ISD::LXOR;
    break;
  case ISD::ATOMIC_LOAD_AND:
    NewOpc = X86ISD::LAND;
    break;
  default:
    llvm_unreachable("Unknown ATOMIC_LOAD_ opcode");
  }

  MachineMemOperand *MMO = cast<MemSDNode>(N)->getMemOperand();

  return DAG.getMemIntrinsicNode(
      NewOpc, SDLoc(N), DAG.getVTList(MVT::i32, MVT::Other),
      {N->getOperand(0), N->getOperand(1), N->getOperand(2)},
      /*MemVT=*/N->getSimpleValueType(0), MMO);
}

/// Lower atomic_load_ops into LOCK-prefixed operations.
static SDValue lowerAtomicArith(SDValue N, SelectionDAG &DAG,
                                const X86Subtarget &Subtarget) {
  AtomicSDNode *AN = cast<AtomicSDNode>(N.getNode());
  SDValue Chain = N->getOperand(0);
  SDValue LHS = N->getOperand(1);
  SDValue RHS = N->getOperand(2);
  unsigned Opc = N->getOpcode();
  MVT VT = N->getSimpleValueType(0);
  SDLoc DL(N);

  // We can lower atomic_load_add into LXADD. However, any other atomicrmw op
  // can only be lowered when the result is unused.  They should have already
  // been transformed into a cmpxchg loop in AtomicExpand.
  if (N->hasAnyUseOfValue(0)) {
    // Handle (atomic_load_sub p, v) as (atomic_load_add p, -v), to be able to
    // select LXADD if LOCK_SUB can't be selected.
    if (Opc == ISD::ATOMIC_LOAD_SUB) {
      RHS = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), RHS);
      return DAG.getAtomic(ISD::ATOMIC_LOAD_ADD, DL, VT, Chain, LHS,
                           RHS, AN->getMemOperand());
    }
    assert(Opc == ISD::ATOMIC_LOAD_ADD &&
           "Used AtomicRMW ops other than Add should have been expanded!");
    return N;
  }

  // Specialized lowering for the canonical form of an idemptotent atomicrmw.
  // The core idea here is that since the memory location isn't actually
  // changing, all we need is a lowering for the *ordering* impacts of the
  // atomicrmw.  As such, we can chose a different operation and memory
  // location to minimize impact on other code.
  if (Opc == ISD::ATOMIC_LOAD_OR && isNullConstant(RHS)) {
    // On X86, the only ordering which actually requires an instruction is
    // seq_cst which isn't SingleThread, everything just needs to be preserved
    // during codegen and then dropped. Note that we expect (but don't assume),
    // that orderings other than seq_cst and acq_rel have been canonicalized to
    // a store or load.
    if (AN->getOrdering() == AtomicOrdering::SequentiallyConsistent &&
        AN->getSyncScopeID() == SyncScope::System) {
      // Prefer a locked operation against a stack location to minimize cache
      // traffic.  This assumes that stack locations are very likely to be
      // accessed only by the owning thread.
      SDValue NewChain = emitLockedStackOp(DAG, Subtarget, Chain, DL);
      assert(!N->hasAnyUseOfValue(0));
      // NOTE: The getUNDEF is needed to give something for the unused result 0.
      return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(),
                         DAG.getUNDEF(VT), NewChain);
    }
    // MEMBARRIER is a compiler barrier; it codegens to a no-op.
    SDValue NewChain = DAG.getNode(X86ISD::MEMBARRIER, DL, MVT::Other, Chain);
    assert(!N->hasAnyUseOfValue(0));
    // NOTE: The getUNDEF is needed to give something for the unused result 0.
    return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(),
                       DAG.getUNDEF(VT), NewChain);
  }

  SDValue LockOp = lowerAtomicArithWithLOCK(N, DAG, Subtarget);
  // RAUW the chain, but don't worry about the result, as it's unused.
  assert(!N->hasAnyUseOfValue(0));
  // NOTE: The getUNDEF is needed to give something for the unused result 0.
  return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(),
                     DAG.getUNDEF(VT), LockOp.getValue(1));
}

static SDValue LowerATOMIC_STORE(SDValue Op, SelectionDAG &DAG,
                                 const X86Subtarget &Subtarget) {
  auto *Node = cast<AtomicSDNode>(Op.getNode());
  SDLoc dl(Node);
  EVT VT = Node->getMemoryVT();

  bool IsSeqCst = Node->getOrdering() == AtomicOrdering::SequentiallyConsistent;
  bool IsTypeLegal = DAG.getTargetLoweringInfo().isTypeLegal(VT);

  // If this store is not sequentially consistent and the type is legal
  // we can just keep it.
  if (!IsSeqCst && IsTypeLegal)
    return Op;

  if (VT == MVT::i64 && !IsTypeLegal) {
    // For illegal i64 atomic_stores, we can try to use MOVQ or MOVLPS if SSE
    // is enabled.
    bool NoImplicitFloatOps =
        DAG.getMachineFunction().getFunction().hasFnAttribute(
            Attribute::NoImplicitFloat);
    if (!Subtarget.useSoftFloat() && !NoImplicitFloatOps) {
      SDValue Chain;
      if (Subtarget.hasSSE1()) {
        SDValue SclToVec = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2i64,
                                       Node->getOperand(2));
        MVT StVT = Subtarget.hasSSE2() ? MVT::v2i64 : MVT::v4f32;
        SclToVec = DAG.getBitcast(StVT, SclToVec);
        SDVTList Tys = DAG.getVTList(MVT::Other);
        SDValue Ops[] = {Node->getChain(), SclToVec, Node->getBasePtr()};
        Chain = DAG.getMemIntrinsicNode(X86ISD::VEXTRACT_STORE, dl, Tys, Ops,
                                        MVT::i64, Node->getMemOperand());
      } else if (Subtarget.hasX87()) {
        // First load this into an 80-bit X87 register using a stack temporary.
        // This will put the whole integer into the significand.
        SDValue StackPtr = DAG.CreateStackTemporary(MVT::i64);
        int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
        MachinePointerInfo MPI =
            MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SPFI);
        Chain =
            DAG.getStore(Node->getChain(), dl, Node->getOperand(2), StackPtr,
                         MPI, /*Align*/ 0, MachineMemOperand::MOStore);
        SDVTList Tys = DAG.getVTList(MVT::f80, MVT::Other);
        SDValue LdOps[] = {Chain, StackPtr};
        SDValue Value =
            DAG.getMemIntrinsicNode(X86ISD::FILD, dl, Tys, LdOps, MVT::i64, MPI,
                                    /*Align*/ None, MachineMemOperand::MOLoad);
        Chain = Value.getValue(1);

        // Now use an FIST to do the atomic store.
        SDValue StoreOps[] = {Chain, Value, Node->getBasePtr()};
        Chain =
            DAG.getMemIntrinsicNode(X86ISD::FIST, dl, DAG.getVTList(MVT::Other),
                                    StoreOps, MVT::i64, Node->getMemOperand());
      }

      if (Chain) {
        // If this is a sequentially consistent store, also emit an appropriate
        // barrier.
        if (IsSeqCst)
          Chain = emitLockedStackOp(DAG, Subtarget, Chain, dl);

        return Chain;
      }
    }
  }

  // Convert seq_cst store -> xchg
  // Convert wide store -> swap (-> cmpxchg8b/cmpxchg16b)
  // FIXME: 16-byte ATOMIC_SWAP isn't actually hooked up at the moment.
  SDValue Swap = DAG.getAtomic(ISD::ATOMIC_SWAP, dl,
                               Node->getMemoryVT(),
                               Node->getOperand(0),
                               Node->getOperand(1), Node->getOperand(2),
                               Node->getMemOperand());
  return Swap.getValue(1);
}

static SDValue LowerADDSUBCARRY(SDValue Op, SelectionDAG &DAG) {
  SDNode *N = Op.getNode();
  MVT VT = N->getSimpleValueType(0);

  // Let legalize expand this if it isn't a legal type yet.
  if (!DAG.getTargetLoweringInfo().isTypeLegal(VT))
    return SDValue();

  SDVTList VTs = DAG.getVTList(VT, MVT::i32);
  SDLoc DL(N);

  // Set the carry flag.
  SDValue Carry = Op.getOperand(2);
  EVT CarryVT = Carry.getValueType();
  Carry = DAG.getNode(X86ISD::ADD, DL, DAG.getVTList(CarryVT, MVT::i32),
                      Carry, DAG.getAllOnesConstant(DL, CarryVT));

  unsigned Opc = Op.getOpcode() == ISD::ADDCARRY ? X86ISD::ADC : X86ISD::SBB;
  SDValue Sum = DAG.getNode(Opc, DL, VTs, Op.getOperand(0),
                            Op.getOperand(1), Carry.getValue(1));

  SDValue SetCC = getSETCC(X86::COND_B, Sum.getValue(1), DL, DAG);
  if (N->getValueType(1) == MVT::i1)
    SetCC = DAG.getNode(ISD::TRUNCATE, DL, MVT::i1, SetCC);

  return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, SetCC);
}

static SDValue LowerFSINCOS(SDValue Op, const X86Subtarget &Subtarget,
                            SelectionDAG &DAG) {
  assert(Subtarget.isTargetDarwin() && Subtarget.is64Bit());

  // For MacOSX, we want to call an alternative entry point: __sincos_stret,
  // which returns the values as { float, float } (in XMM0) or
  // { double, double } (which is returned in XMM0, XMM1).
  SDLoc dl(Op);
  SDValue Arg = Op.getOperand(0);
  EVT ArgVT = Arg.getValueType();
  Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext());

  TargetLowering::ArgListTy Args;
  TargetLowering::ArgListEntry Entry;

  Entry.Node = Arg;
  Entry.Ty = ArgTy;
  Entry.IsSExt = false;
  Entry.IsZExt = false;
  Args.push_back(Entry);

  bool isF64 = ArgVT == MVT::f64;
  // Only optimize x86_64 for now. i386 is a bit messy. For f32,
  // the small struct {f32, f32} is returned in (eax, edx). For f64,
  // the results are returned via SRet in memory.
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  RTLIB::Libcall LC = isF64 ? RTLIB::SINCOS_STRET_F64 : RTLIB::SINCOS_STRET_F32;
  const char *LibcallName = TLI.getLibcallName(LC);
  SDValue Callee =
      DAG.getExternalSymbol(LibcallName, TLI.getPointerTy(DAG.getDataLayout()));

  Type *RetTy = isF64 ? (Type *)StructType::get(ArgTy, ArgTy)
                      : (Type *)VectorType::get(ArgTy, 4);

  TargetLowering::CallLoweringInfo CLI(DAG);
  CLI.setDebugLoc(dl)
      .setChain(DAG.getEntryNode())
      .setLibCallee(CallingConv::C, RetTy, Callee, std::move(Args));

  std::pair<SDValue, SDValue> CallResult = TLI.LowerCallTo(CLI);

  if (isF64)
    // Returned in xmm0 and xmm1.
    return CallResult.first;

  // Returned in bits 0:31 and 32:64 xmm0.
  SDValue SinVal = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ArgVT,
                               CallResult.first, DAG.getIntPtrConstant(0, dl));
  SDValue CosVal = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ArgVT,
                               CallResult.first, DAG.getIntPtrConstant(1, dl));
  SDVTList Tys = DAG.getVTList(ArgVT, ArgVT);
  return DAG.getNode(ISD::MERGE_VALUES, dl, Tys, SinVal, CosVal);
}

/// Widen a vector input to a vector of NVT.  The
/// input vector must have the same element type as NVT.
static SDValue ExtendToType(SDValue InOp, MVT NVT, SelectionDAG &DAG,
                            bool FillWithZeroes = false) {
  // Check if InOp already has the right width.
  MVT InVT = InOp.getSimpleValueType();
  if (InVT == NVT)
    return InOp;

  if (InOp.isUndef())
    return DAG.getUNDEF(NVT);

  assert(InVT.getVectorElementType() == NVT.getVectorElementType() &&
         "input and widen element type must match");

  unsigned InNumElts = InVT.getVectorNumElements();
  unsigned WidenNumElts = NVT.getVectorNumElements();
  assert(WidenNumElts > InNumElts && WidenNumElts % InNumElts == 0 &&
         "Unexpected request for vector widening");

  SDLoc dl(InOp);
  if (InOp.getOpcode() == ISD::CONCAT_VECTORS &&
      InOp.getNumOperands() == 2) {
    SDValue N1 = InOp.getOperand(1);
    if ((ISD::isBuildVectorAllZeros(N1.getNode()) && FillWithZeroes) ||
        N1.isUndef()) {
      InOp = InOp.getOperand(0);
      InVT = InOp.getSimpleValueType();
      InNumElts = InVT.getVectorNumElements();
    }
  }
  if (ISD::isBuildVectorOfConstantSDNodes(InOp.getNode()) ||
      ISD::isBuildVectorOfConstantFPSDNodes(InOp.getNode())) {
    SmallVector<SDValue, 16> Ops;
    for (unsigned i = 0; i < InNumElts; ++i)
      Ops.push_back(InOp.getOperand(i));

    EVT EltVT = InOp.getOperand(0).getValueType();

    SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, EltVT) :
      DAG.getUNDEF(EltVT);
    for (unsigned i = 0; i < WidenNumElts - InNumElts; ++i)
      Ops.push_back(FillVal);
    return DAG.getBuildVector(NVT, dl, Ops);
  }
  SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, NVT) :
    DAG.getUNDEF(NVT);
  return DAG.getNode(ISD::INSERT_SUBVECTOR, dl, NVT, FillVal,
                     InOp, DAG.getIntPtrConstant(0, dl));
}

static SDValue LowerMSCATTER(SDValue Op, const X86Subtarget &Subtarget,
                             SelectionDAG &DAG) {
  assert(Subtarget.hasAVX512() &&
         "MGATHER/MSCATTER are supported on AVX-512 arch only");

  MaskedScatterSDNode *N = cast<MaskedScatterSDNode>(Op.getNode());
  SDValue Src = N->getValue();
  MVT VT = Src.getSimpleValueType();
  assert(VT.getScalarSizeInBits() >= 32 && "Unsupported scatter op");
  SDLoc dl(Op);

  SDValue Scale = N->getScale();
  SDValue Index = N->getIndex();
  SDValue Mask = N->getMask();
  SDValue Chain = N->getChain();
  SDValue BasePtr = N->getBasePtr();

  if (VT == MVT::v2f32 || VT == MVT::v2i32) {
    assert(Mask.getValueType() == MVT::v2i1 && "Unexpected mask type");
    // If the index is v2i64 and we have VLX we can use xmm for data and index.
    if (Index.getValueType() == MVT::v2i64 && Subtarget.hasVLX()) {
      const TargetLowering &TLI = DAG.getTargetLoweringInfo();
      EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
      Src = DAG.getNode(ISD::CONCAT_VECTORS, dl, WideVT, Src, DAG.getUNDEF(VT));
      SDVTList VTs = DAG.getVTList(MVT::Other);
      SDValue Ops[] = {Chain, Src, Mask, BasePtr, Index, Scale};
      return DAG.getMemIntrinsicNode(X86ISD::MSCATTER, dl, VTs, Ops,
                                     N->getMemoryVT(), N->getMemOperand());
    }
    return SDValue();
  }

  MVT IndexVT = Index.getSimpleValueType();

  // If the index is v2i32, we're being called by type legalization and we
  // should just let the default handling take care of it.
  if (IndexVT == MVT::v2i32)
    return SDValue();

  // If we don't have VLX and neither the passthru or index is 512-bits, we
  // need to widen until one is.
  if (!Subtarget.hasVLX() && !VT.is512BitVector() &&
      !Index.getSimpleValueType().is512BitVector()) {
    // Determine how much we need to widen by to get a 512-bit type.
    unsigned Factor = std::min(512/VT.getSizeInBits(),
                               512/IndexVT.getSizeInBits());
    unsigned NumElts = VT.getVectorNumElements() * Factor;

    VT = MVT::getVectorVT(VT.getVectorElementType(), NumElts);
    IndexVT = MVT::getVectorVT(IndexVT.getVectorElementType(), NumElts);
    MVT MaskVT = MVT::getVectorVT(MVT::i1, NumElts);

    Src = ExtendToType(Src, VT, DAG);
    Index = ExtendToType(Index, IndexVT, DAG);
    Mask = ExtendToType(Mask, MaskVT, DAG, true);
  }

  SDVTList VTs = DAG.getVTList(MVT::Other);
  SDValue Ops[] = {Chain, Src, Mask, BasePtr, Index, Scale};
  return DAG.getMemIntrinsicNode(X86ISD::MSCATTER, dl, VTs, Ops,
                                 N->getMemoryVT(), N->getMemOperand());
}

static SDValue LowerMLOAD(SDValue Op, const X86Subtarget &Subtarget,
                          SelectionDAG &DAG) {

  MaskedLoadSDNode *N = cast<MaskedLoadSDNode>(Op.getNode());
  MVT VT = Op.getSimpleValueType();
  MVT ScalarVT = VT.getScalarType();
  SDValue Mask = N->getMask();
  MVT MaskVT = Mask.getSimpleValueType();
  SDValue PassThru = N->getPassThru();
  SDLoc dl(Op);

  // Handle AVX masked loads which don't support passthru other than 0.
  if (MaskVT.getVectorElementType() != MVT::i1) {
    // We also allow undef in the isel pattern.
    if (PassThru.isUndef() || ISD::isBuildVectorAllZeros(PassThru.getNode()))
      return Op;

    SDValue NewLoad = DAG.getMaskedLoad(
        VT, dl, N->getChain(), N->getBasePtr(), N->getOffset(), Mask,
        getZeroVector(VT, Subtarget, DAG, dl), N->getMemoryVT(),
        N->getMemOperand(), N->getAddressingMode(), N->getExtensionType(),
        N->isExpandingLoad());
    // Emit a blend.
    SDValue Select = DAG.getNode(ISD::VSELECT, dl, MaskVT, Mask, NewLoad,
                                 PassThru);
    return DAG.getMergeValues({ Select, NewLoad.getValue(1) }, dl);
  }

  assert((!N->isExpandingLoad() || Subtarget.hasAVX512()) &&
         "Expanding masked load is supported on AVX-512 target only!");

  assert((!N->isExpandingLoad() || ScalarVT.getSizeInBits() >= 32) &&
         "Expanding masked load is supported for 32 and 64-bit types only!");

  assert(Subtarget.hasAVX512() && !Subtarget.hasVLX() && !VT.is512BitVector() &&
         "Cannot lower masked load op.");

  assert((ScalarVT.getSizeInBits() >= 32 ||
          (Subtarget.hasBWI() &&
              (ScalarVT == MVT::i8 || ScalarVT == MVT::i16))) &&
         "Unsupported masked load op.");

  // This operation is legal for targets with VLX, but without
  // VLX the vector should be widened to 512 bit
  unsigned NumEltsInWideVec = 512 / VT.getScalarSizeInBits();
  MVT WideDataVT = MVT::getVectorVT(ScalarVT, NumEltsInWideVec);
  PassThru = ExtendToType(PassThru, WideDataVT, DAG);

  // Mask element has to be i1.
  assert(Mask.getSimpleValueType().getScalarType() == MVT::i1 &&
         "Unexpected mask type");

  MVT WideMaskVT = MVT::getVectorVT(MVT::i1, NumEltsInWideVec);

  Mask = ExtendToType(Mask, WideMaskVT, DAG, true);
  SDValue NewLoad = DAG.getMaskedLoad(
      WideDataVT, dl, N->getChain(), N->getBasePtr(), N->getOffset(), Mask,
      PassThru, N->getMemoryVT(), N->getMemOperand(), N->getAddressingMode(),
      N->getExtensionType(), N->isExpandingLoad());

  SDValue Exract = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT,
                               NewLoad.getValue(0),
                               DAG.getIntPtrConstant(0, dl));
  SDValue RetOps[] = {Exract, NewLoad.getValue(1)};
  return DAG.getMergeValues(RetOps, dl);
}

static SDValue LowerMSTORE(SDValue Op, const X86Subtarget &Subtarget,
                           SelectionDAG &DAG) {
  MaskedStoreSDNode *N = cast<MaskedStoreSDNode>(Op.getNode());
  SDValue DataToStore = N->getValue();
  MVT VT = DataToStore.getSimpleValueType();
  MVT ScalarVT = VT.getScalarType();
  SDValue Mask = N->getMask();
  SDLoc dl(Op);

  assert((!N->isCompressingStore() || Subtarget.hasAVX512()) &&
         "Expanding masked load is supported on AVX-512 target only!");

  assert((!N->isCompressingStore() || ScalarVT.getSizeInBits() >= 32) &&
         "Expanding masked load is supported for 32 and 64-bit types only!");

  assert(Subtarget.hasAVX512() && !Subtarget.hasVLX() && !VT.is512BitVector() &&
         "Cannot lower masked store op.");

  assert((ScalarVT.getSizeInBits() >= 32 ||
          (Subtarget.hasBWI() &&
              (ScalarVT == MVT::i8 || ScalarVT == MVT::i16))) &&
          "Unsupported masked store op.");

  // This operation is legal for targets with VLX, but without
  // VLX the vector should be widened to 512 bit
  unsigned NumEltsInWideVec = 512/VT.getScalarSizeInBits();
  MVT WideDataVT = MVT::getVectorVT(ScalarVT, NumEltsInWideVec);

  // Mask element has to be i1.
  assert(Mask.getSimpleValueType().getScalarType() == MVT::i1 &&
         "Unexpected mask type");

  MVT WideMaskVT = MVT::getVectorVT(MVT::i1, NumEltsInWideVec);

  DataToStore = ExtendToType(DataToStore, WideDataVT, DAG);
  Mask = ExtendToType(Mask, WideMaskVT, DAG, true);
  return DAG.getMaskedStore(N->getChain(), dl, DataToStore, N->getBasePtr(),
                            N->getOffset(), Mask, N->getMemoryVT(),
                            N->getMemOperand(), N->getAddressingMode(),
                            N->isTruncatingStore(), N->isCompressingStore());
}

static SDValue LowerMGATHER(SDValue Op, const X86Subtarget &Subtarget,
                            SelectionDAG &DAG) {
  assert(Subtarget.hasAVX2() &&
         "MGATHER/MSCATTER are supported on AVX-512/AVX-2 arch only");

  MaskedGatherSDNode *N = cast<MaskedGatherSDNode>(Op.getNode());
  SDLoc dl(Op);
  MVT VT = Op.getSimpleValueType();
  SDValue Index = N->getIndex();
  SDValue Mask = N->getMask();
  SDValue PassThru = N->getPassThru();
  MVT IndexVT = Index.getSimpleValueType();

  assert(VT.getScalarSizeInBits() >= 32 && "Unsupported gather op");

  // If the index is v2i32, we're being called by type legalization.
  if (IndexVT == MVT::v2i32)
    return SDValue();

  // If we don't have VLX and neither the passthru or index is 512-bits, we
  // need to widen until one is.
  MVT OrigVT = VT;
  if (Subtarget.hasAVX512() && !Subtarget.hasVLX() && !VT.is512BitVector() &&
      !IndexVT.is512BitVector()) {
    // Determine how much we need to widen by to get a 512-bit type.
    unsigned Factor = std::min(512/VT.getSizeInBits(),
                               512/IndexVT.getSizeInBits());

    unsigned NumElts = VT.getVectorNumElements() * Factor;

    VT = MVT::getVectorVT(VT.getVectorElementType(), NumElts);
    IndexVT = MVT::getVectorVT(IndexVT.getVectorElementType(), NumElts);
    MVT MaskVT = MVT::getVectorVT(MVT::i1, NumElts);

    PassThru = ExtendToType(PassThru, VT, DAG);
    Index = ExtendToType(Index, IndexVT, DAG);
    Mask = ExtendToType(Mask, MaskVT, DAG, true);
  }

  SDValue Ops[] = { N->getChain(), PassThru, Mask, N->getBasePtr(), Index,
                    N->getScale() };
  SDValue NewGather = DAG.getMemIntrinsicNode(
      X86ISD::MGATHER, dl, DAG.getVTList(VT, MVT::Other), Ops, N->getMemoryVT(),
      N->getMemOperand());
  SDValue Extract = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, OrigVT,
                                NewGather, DAG.getIntPtrConstant(0, dl));
  return DAG.getMergeValues({Extract, NewGather.getValue(1)}, dl);
}

static SDValue LowerADDRSPACECAST(SDValue Op, SelectionDAG &DAG) {
  SDLoc dl(Op);
  SDValue Src = Op.getOperand(0);
  MVT DstVT = Op.getSimpleValueType();

  AddrSpaceCastSDNode *N = cast<AddrSpaceCastSDNode>(Op.getNode());
  unsigned SrcAS = N->getSrcAddressSpace();

  assert(SrcAS != N->getDestAddressSpace() &&
         "addrspacecast must be between different address spaces");

  if (SrcAS == X86AS::PTR32_UPTR && DstVT == MVT::i64) {
    Op = DAG.getNode(ISD::ZERO_EXTEND, dl, DstVT, Src);
  } else if (DstVT == MVT::i64) {
    Op = DAG.getNode(ISD::SIGN_EXTEND, dl, DstVT, Src);
  } else if (DstVT == MVT::i32) {
    Op = DAG.getNode(ISD::TRUNCATE, dl, DstVT, Src);
  } else {
    report_fatal_error("Bad address space in addrspacecast");
  }
  return Op;
}

SDValue X86TargetLowering::LowerGC_TRANSITION(SDValue Op,
                                              SelectionDAG &DAG) const {
  // TODO: Eventually, the lowering of these nodes should be informed by or
  // deferred to the GC strategy for the function in which they appear. For
  // now, however, they must be lowered to something. Since they are logically
  // no-ops in the case of a null GC strategy (or a GC strategy which does not
  // require special handling for these nodes), lower them as literal NOOPs for
  // the time being.
  SmallVector<SDValue, 2> Ops;

  Ops.push_back(Op.getOperand(0));
  if (Op->getGluedNode())
    Ops.push_back(Op->getOperand(Op->getNumOperands() - 1));

  SDLoc OpDL(Op);
  SDVTList VTs = DAG.getVTList(MVT::Other, MVT::Glue);
  SDValue NOOP(DAG.getMachineNode(X86::NOOP, SDLoc(Op), VTs, Ops), 0);

  return NOOP;
}

SDValue X86TargetLowering::LowerF128Call(SDValue Op, SelectionDAG &DAG,
                                         RTLIB::Libcall Call) const {

  bool IsStrict = Op->isStrictFPOpcode();
  unsigned Offset = IsStrict ? 1 : 0;
  SmallVector<SDValue, 2> Ops(Op->op_begin() + Offset, Op->op_end());

  SDLoc dl(Op);
  SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
  MakeLibCallOptions CallOptions;
  std::pair<SDValue, SDValue> Tmp = makeLibCall(DAG, Call, MVT::f128, Ops,
                                                CallOptions, dl, Chain);

  if (IsStrict)
    return DAG.getMergeValues({ Tmp.first, Tmp.second }, dl);

  return Tmp.first;
}

// Custom split CVTPS2PH with wide types.
static SDValue LowerCVTPS2PH(SDValue Op, SelectionDAG &DAG) {
  SDLoc dl(Op);
  EVT VT = Op.getValueType();
  SDValue Lo, Hi;
  std::tie(Lo, Hi) = DAG.SplitVectorOperand(Op.getNode(), 0);
  EVT LoVT, HiVT;
  std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
  SDValue RC = Op.getOperand(1);
  Lo = DAG.getNode(X86ISD::CVTPS2PH, dl, LoVT, Lo, RC);
  Hi = DAG.getNode(X86ISD::CVTPS2PH, dl, HiVT, Hi, RC);
  return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, Lo, Hi);
}

/// Provide custom lowering hooks for some operations.
SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
  switch (Op.getOpcode()) {
  default: llvm_unreachable("Should not custom lower this!");
  case ISD::ATOMIC_FENCE:       return LowerATOMIC_FENCE(Op, Subtarget, DAG);
  case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS:
    return LowerCMP_SWAP(Op, Subtarget, DAG);
  case ISD::CTPOP:              return LowerCTPOP(Op, Subtarget, DAG);
  case ISD::ATOMIC_LOAD_ADD:
  case ISD::ATOMIC_LOAD_SUB:
  case ISD::ATOMIC_LOAD_OR:
  case ISD::ATOMIC_LOAD_XOR:
  case ISD::ATOMIC_LOAD_AND:    return lowerAtomicArith(Op, DAG, Subtarget);
  case ISD::ATOMIC_STORE:       return LowerATOMIC_STORE(Op, DAG, Subtarget);
  case ISD::BITREVERSE:         return LowerBITREVERSE(Op, Subtarget, DAG);
  case ISD::BUILD_VECTOR:       return LowerBUILD_VECTOR(Op, DAG);
  case ISD::CONCAT_VECTORS:     return LowerCONCAT_VECTORS(Op, Subtarget, DAG);
  case ISD::VECTOR_SHUFFLE:     return lowerVECTOR_SHUFFLE(Op, Subtarget, DAG);
  case ISD::VSELECT:            return LowerVSELECT(Op, DAG);
  case ISD::EXTRACT_VECTOR_ELT: return LowerEXTRACT_VECTOR_ELT(Op, DAG);
  case ISD::INSERT_VECTOR_ELT:  return LowerINSERT_VECTOR_ELT(Op, DAG);
  case ISD::INSERT_SUBVECTOR:   return LowerINSERT_SUBVECTOR(Op, Subtarget,DAG);
  case ISD::EXTRACT_SUBVECTOR:  return LowerEXTRACT_SUBVECTOR(Op,Subtarget,DAG);
  case ISD::SCALAR_TO_VECTOR:   return LowerSCALAR_TO_VECTOR(Op, Subtarget,DAG);
  case ISD::ConstantPool:       return LowerConstantPool(Op, DAG);
  case ISD::GlobalAddress:      return LowerGlobalAddress(Op, DAG);
  case ISD::GlobalTLSAddress:   return LowerGlobalTLSAddress(Op, DAG);
  case ISD::ExternalSymbol:     return LowerExternalSymbol(Op, DAG);
  case ISD::BlockAddress:       return LowerBlockAddress(Op, DAG);
  case ISD::SHL_PARTS:
  case ISD::SRA_PARTS:
  case ISD::SRL_PARTS:          return LowerShiftParts(Op, DAG);
  case ISD::FSHL:
  case ISD::FSHR:               return LowerFunnelShift(Op, Subtarget, DAG);
  case ISD::STRICT_SINT_TO_FP:
  case ISD::SINT_TO_FP:         return LowerSINT_TO_FP(Op, DAG);
  case ISD::STRICT_UINT_TO_FP:
  case ISD::UINT_TO_FP:         return LowerUINT_TO_FP(Op, DAG);
  case ISD::TRUNCATE:           return LowerTRUNCATE(Op, DAG);
  case ISD::ZERO_EXTEND:        return LowerZERO_EXTEND(Op, Subtarget, DAG);
  case ISD::SIGN_EXTEND:        return LowerSIGN_EXTEND(Op, Subtarget, DAG);
  case ISD::ANY_EXTEND:         return LowerANY_EXTEND(Op, Subtarget, DAG);
  case ISD::ZERO_EXTEND_VECTOR_INREG:
  case ISD::SIGN_EXTEND_VECTOR_INREG:
    return LowerEXTEND_VECTOR_INREG(Op, Subtarget, DAG);
  case ISD::FP_TO_SINT:
  case ISD::STRICT_FP_TO_SINT:
  case ISD::FP_TO_UINT:
  case ISD::STRICT_FP_TO_UINT:  return LowerFP_TO_INT(Op, DAG);
  case ISD::FP_EXTEND:
  case ISD::STRICT_FP_EXTEND:   return LowerFP_EXTEND(Op, DAG);
  case ISD::FP_ROUND:
  case ISD::STRICT_FP_ROUND:    return LowerFP_ROUND(Op, DAG);
  case ISD::FP16_TO_FP:
  case ISD::STRICT_FP16_TO_FP:  return LowerFP16_TO_FP(Op, DAG);
  case ISD::FP_TO_FP16:
  case ISD::STRICT_FP_TO_FP16:  return LowerFP_TO_FP16(Op, DAG);
  case ISD::LOAD:               return LowerLoad(Op, Subtarget, DAG);
  case ISD::STORE:              return LowerStore(Op, Subtarget, DAG);
  case ISD::FADD:
  case ISD::FSUB:               return lowerFaddFsub(Op, DAG);
  case ISD::FROUND:             return LowerFROUND(Op, DAG);
  case ISD::FABS:
  case ISD::FNEG:               return LowerFABSorFNEG(Op, DAG);
  case ISD::FCOPYSIGN:          return LowerFCOPYSIGN(Op, DAG);
  case ISD::FGETSIGN:           return LowerFGETSIGN(Op, DAG);
  case ISD::LRINT:
  case ISD::LLRINT:             return LowerLRINT_LLRINT(Op, DAG);
  case ISD::SETCC:
  case ISD::STRICT_FSETCC:
  case ISD::STRICT_FSETCCS:     return LowerSETCC(Op, DAG);
  case ISD::SETCCCARRY:         return LowerSETCCCARRY(Op, DAG);
  case ISD::SELECT:             return LowerSELECT(Op, DAG);
  case ISD::BRCOND:             return LowerBRCOND(Op, DAG);
  case ISD::JumpTable:          return LowerJumpTable(Op, DAG);
  case ISD::VASTART:            return LowerVASTART(Op, DAG);
  case ISD::VAARG:              return LowerVAARG(Op, DAG);
  case ISD::VACOPY:             return LowerVACOPY(Op, Subtarget, DAG);
  case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
  case ISD::INTRINSIC_VOID:
  case ISD::INTRINSIC_W_CHAIN:  return LowerINTRINSIC_W_CHAIN(Op, Subtarget, DAG);
  case ISD::RETURNADDR:         return LowerRETURNADDR(Op, DAG);
  case ISD::ADDROFRETURNADDR:   return LowerADDROFRETURNADDR(Op, DAG);
  case ISD::FRAMEADDR:          return LowerFRAMEADDR(Op, DAG);
  case ISD::FRAME_TO_ARGS_OFFSET:
                                return LowerFRAME_TO_ARGS_OFFSET(Op, DAG);
  case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
  case ISD::EH_RETURN:          return LowerEH_RETURN(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::EH_SJLJ_SETUP_DISPATCH:
    return lowerEH_SJLJ_SETUP_DISPATCH(Op, DAG);
  case ISD::INIT_TRAMPOLINE:    return LowerINIT_TRAMPOLINE(Op, DAG);
  case ISD::ADJUST_TRAMPOLINE:  return LowerADJUST_TRAMPOLINE(Op, DAG);
  case ISD::FLT_ROUNDS_:        return LowerFLT_ROUNDS_(Op, DAG);
  case ISD::CTLZ:
  case ISD::CTLZ_ZERO_UNDEF:    return LowerCTLZ(Op, Subtarget, DAG);
  case ISD::CTTZ:
  case ISD::CTTZ_ZERO_UNDEF:    return LowerCTTZ(Op, Subtarget, DAG);
  case ISD::MUL:                return LowerMUL(Op, Subtarget, DAG);
  case ISD::MULHS:
  case ISD::MULHU:              return LowerMULH(Op, Subtarget, DAG);
  case ISD::ROTL:
  case ISD::ROTR:               return LowerRotate(Op, Subtarget, DAG);
  case ISD::SRA:
  case ISD::SRL:
  case ISD::SHL:                return LowerShift(Op, Subtarget, DAG);
  case ISD::SADDO:
  case ISD::UADDO:
  case ISD::SSUBO:
  case ISD::USUBO:
  case ISD::SMULO:
  case ISD::UMULO:              return LowerXALUO(Op, DAG);
  case ISD::READCYCLECOUNTER:   return LowerREADCYCLECOUNTER(Op, Subtarget,DAG);
  case ISD::BITCAST:            return LowerBITCAST(Op, Subtarget, DAG);
  case ISD::ADDCARRY:
  case ISD::SUBCARRY:           return LowerADDSUBCARRY(Op, DAG);
  case ISD::ADD:
  case ISD::SUB:                return lowerAddSub(Op, DAG, Subtarget);
  case ISD::UADDSAT:
  case ISD::SADDSAT:
  case ISD::USUBSAT:
  case ISD::SSUBSAT:            return LowerADDSAT_SUBSAT(Op, DAG, Subtarget);
  case ISD::SMAX:
  case ISD::SMIN:
  case ISD::UMAX:
  case ISD::UMIN:               return LowerMINMAX(Op, DAG);
  case ISD::ABS:                return LowerABS(Op, Subtarget, DAG);
  case ISD::FSINCOS:            return LowerFSINCOS(Op, Subtarget, DAG);
  case ISD::MLOAD:              return LowerMLOAD(Op, Subtarget, DAG);
  case ISD::MSTORE:             return LowerMSTORE(Op, Subtarget, DAG);
  case ISD::MGATHER:            return LowerMGATHER(Op, Subtarget, DAG);
  case ISD::MSCATTER:           return LowerMSCATTER(Op, Subtarget, DAG);
  case ISD::GC_TRANSITION_START:
  case ISD::GC_TRANSITION_END:  return LowerGC_TRANSITION(Op, DAG);
  case ISD::ADDRSPACECAST:      return LowerADDRSPACECAST(Op, DAG);
  case X86ISD::CVTPS2PH:        return LowerCVTPS2PH(Op, DAG);
  }
}

/// Places new result values for the node in Results (their number
/// and types must exactly match those of the original return values of
/// the node), or leaves Results empty, which indicates that the node is not
/// to be custom lowered after all.
void X86TargetLowering::LowerOperationWrapper(SDNode *N,
                                              SmallVectorImpl<SDValue> &Results,
                                              SelectionDAG &DAG) const {
  SDValue Res = LowerOperation(SDValue(N, 0), DAG);

  if (!Res.getNode())
    return;

  // If the original node has one result, take the return value from
  // LowerOperation as is. It might not be result number 0.
  if (N->getNumValues() == 1) {
    Results.push_back(Res);
    return;
  }

  // If the original node has multiple results, then the return node should
  // have the same number of results.
  assert((N->getNumValues() == Res->getNumValues()) &&
      "Lowering returned the wrong number of results!");

  // Places new result values base on N result number.
  for (unsigned I = 0, E = N->getNumValues(); I != E; ++I)
    Results.push_back(Res.getValue(I));
}

/// Replace a node with an illegal result type with a new node built out of
/// custom code.
void X86TargetLowering::ReplaceNodeResults(SDNode *N,
                                           SmallVectorImpl<SDValue>&Results,
                                           SelectionDAG &DAG) const {
  SDLoc dl(N);
  switch (N->getOpcode()) {
  default:
#ifndef NDEBUG
    dbgs() << "ReplaceNodeResults: ";
    N->dump(&DAG);
#endif
    llvm_unreachable("Do not know how to custom type legalize this operation!");
  case X86ISD::CVTPH2PS: {
    EVT VT = N->getValueType(0);
    SDValue Lo, Hi;
    std::tie(Lo, Hi) = DAG.SplitVectorOperand(N, 0);
    EVT LoVT, HiVT;
    std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
    Lo = DAG.getNode(X86ISD::CVTPH2PS, dl, LoVT, Lo);
    Hi = DAG.getNode(X86ISD::CVTPH2PS, dl, HiVT, Hi);
    SDValue Res = DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, Lo, Hi);
    Results.push_back(Res);
    return;
  }
  case X86ISD::STRICT_CVTPH2PS: {
    EVT VT = N->getValueType(0);
    SDValue Lo, Hi;
    std::tie(Lo, Hi) = DAG.SplitVectorOperand(N, 1);
    EVT LoVT, HiVT;
    std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
    Lo = DAG.getNode(X86ISD::STRICT_CVTPH2PS, dl, {LoVT, MVT::Other},
                     {N->getOperand(0), Lo});
    Hi = DAG.getNode(X86ISD::STRICT_CVTPH2PS, dl, {HiVT, MVT::Other},
                     {N->getOperand(0), Hi});
    SDValue Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
                                Lo.getValue(1), Hi.getValue(1));
    SDValue Res = DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, Lo, Hi);
    Results.push_back(Res);
    Results.push_back(Chain);
    return;
  }
  case ISD::CTPOP: {
    assert(N->getValueType(0) == MVT::i64 && "Unexpected VT!");
    // Use a v2i64 if possible.
    bool NoImplicitFloatOps =
        DAG.getMachineFunction().getFunction().hasFnAttribute(
            Attribute::NoImplicitFloat);
    if (isTypeLegal(MVT::v2i64) && !NoImplicitFloatOps) {
      SDValue Wide =
          DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2i64, N->getOperand(0));
      Wide = DAG.getNode(ISD::CTPOP, dl, MVT::v2i64, Wide);
      // Bit count should fit in 32-bits, extract it as that and then zero
      // extend to i64. Otherwise we end up extracting bits 63:32 separately.
      Wide = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, Wide);
      Wide = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, Wide,
                         DAG.getIntPtrConstant(0, dl));
      Wide = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i64, Wide);
      Results.push_back(Wide);
    }
    return;
  }
  case ISD::MUL: {
    EVT VT = N->getValueType(0);
    assert(getTypeAction(*DAG.getContext(), VT) == TypeWidenVector &&
           VT.getVectorElementType() == MVT::i8 && "Unexpected VT!");
    // Pre-promote these to vXi16 to avoid op legalization thinking all 16
    // elements are needed.
    MVT MulVT = MVT::getVectorVT(MVT::i16, VT.getVectorNumElements());
    SDValue Op0 = DAG.getNode(ISD::ANY_EXTEND, dl, MulVT, N->getOperand(0));
    SDValue Op1 = DAG.getNode(ISD::ANY_EXTEND, dl, MulVT, N->getOperand(1));
    SDValue Res = DAG.getNode(ISD::MUL, dl, MulVT, Op0, Op1);
    Res = DAG.getNode(ISD::TRUNCATE, dl, VT, Res);
    unsigned NumConcats = 16 / VT.getVectorNumElements();
    SmallVector<SDValue, 8> ConcatOps(NumConcats, DAG.getUNDEF(VT));
    ConcatOps[0] = Res;
    Res = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v16i8, ConcatOps);
    Results.push_back(Res);
    return;
  }
  case X86ISD::VPMADDWD:
  case X86ISD::AVG: {
    // Legalize types for X86ISD::AVG/VPMADDWD by widening.
    assert(Subtarget.hasSSE2() && "Requires at least SSE2!");

    EVT VT = N->getValueType(0);
    EVT InVT = N->getOperand(0).getValueType();
    assert(VT.getSizeInBits() < 128 && 128 % VT.getSizeInBits() == 0 &&
           "Expected a VT that divides into 128 bits.");
    assert(getTypeAction(*DAG.getContext(), VT) == TypeWidenVector &&
           "Unexpected type action!");
    unsigned NumConcat = 128 / InVT.getSizeInBits();

    EVT InWideVT = EVT::getVectorVT(*DAG.getContext(),
                                    InVT.getVectorElementType(),
                                    NumConcat * InVT.getVectorNumElements());
    EVT WideVT = EVT::getVectorVT(*DAG.getContext(),
                                  VT.getVectorElementType(),
                                  NumConcat * VT.getVectorNumElements());

    SmallVector<SDValue, 16> Ops(NumConcat, DAG.getUNDEF(InVT));
    Ops[0] = N->getOperand(0);
    SDValue InVec0 = DAG.getNode(ISD::CONCAT_VECTORS, dl, InWideVT, Ops);
    Ops[0] = N->getOperand(1);
    SDValue InVec1 = DAG.getNode(ISD::CONCAT_VECTORS, dl, InWideVT, Ops);

    SDValue Res = DAG.getNode(N->getOpcode(), dl, WideVT, InVec0, InVec1);
    Results.push_back(Res);
    return;
  }
  case ISD::ABS: {
    assert(N->getValueType(0) == MVT::i64 &&
           "Unexpected type (!= i64) on ABS.");
    MVT HalfT = MVT::i32;
    SDValue Lo, Hi, Tmp;
    SDVTList VTList = DAG.getVTList(HalfT, MVT::i1);

    Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, HalfT, N->getOperand(0),
                     DAG.getConstant(0, dl, HalfT));
    Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, HalfT, N->getOperand(0),
                     DAG.getConstant(1, dl, HalfT));
    Tmp = DAG.getNode(
        ISD::SRA, dl, HalfT, Hi,
        DAG.getShiftAmountConstant(HalfT.getSizeInBits() - 1, HalfT, dl));
    Lo = DAG.getNode(ISD::UADDO, dl, VTList, Tmp, Lo);
    Hi = DAG.getNode(ISD::ADDCARRY, dl, VTList, Tmp, Hi,
                     SDValue(Lo.getNode(), 1));
    Hi = DAG.getNode(ISD::XOR, dl, HalfT, Tmp, Hi);
    Lo = DAG.getNode(ISD::XOR, dl, HalfT, Tmp, Lo);
    Results.push_back(DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi));
    return;
  }
  // We might have generated v2f32 FMIN/FMAX operations. Widen them to v4f32.
  case X86ISD::FMINC:
  case X86ISD::FMIN:
  case X86ISD::FMAXC:
  case X86ISD::FMAX: {
    EVT VT = N->getValueType(0);
    assert(VT == MVT::v2f32 && "Unexpected type (!= v2f32) on FMIN/FMAX.");
    SDValue UNDEF = DAG.getUNDEF(VT);
    SDValue LHS = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v4f32,
                              N->getOperand(0), UNDEF);
    SDValue RHS = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v4f32,
                              N->getOperand(1), UNDEF);
    Results.push_back(DAG.getNode(N->getOpcode(), dl, MVT::v4f32, LHS, RHS));
    return;
  }
  case ISD::SDIV:
  case ISD::UDIV:
  case ISD::SREM:
  case ISD::UREM: {
    EVT VT = N->getValueType(0);
    if (VT.isVector()) {
      assert(getTypeAction(*DAG.getContext(), VT) == TypeWidenVector &&
             "Unexpected type action!");
      // If this RHS is a constant splat vector we can widen this and let
      // division/remainder by constant optimize it.
      // TODO: Can we do something for non-splat?
      APInt SplatVal;
      if (ISD::isConstantSplatVector(N->getOperand(1).getNode(), SplatVal)) {
        unsigned NumConcats = 128 / VT.getSizeInBits();
        SmallVector<SDValue, 8> Ops0(NumConcats, DAG.getUNDEF(VT));
        Ops0[0] = N->getOperand(0);
        EVT ResVT = getTypeToTransformTo(*DAG.getContext(), VT);
        SDValue N0 = DAG.getNode(ISD::CONCAT_VECTORS, dl, ResVT, Ops0);
        SDValue N1 = DAG.getConstant(SplatVal, dl, ResVT);
        SDValue Res = DAG.getNode(N->getOpcode(), dl, ResVT, N0, N1);
        Results.push_back(Res);
      }
      return;
    }

    LLVM_FALLTHROUGH;
  }
  case ISD::SDIVREM:
  case ISD::UDIVREM: {
    SDValue V = LowerWin64_i128OP(SDValue(N,0), DAG);
    Results.push_back(V);
    return;
  }
  case ISD::TRUNCATE: {
    MVT VT = N->getSimpleValueType(0);
    if (getTypeAction(*DAG.getContext(), VT) != TypeWidenVector)
      return;

    // The generic legalizer will try to widen the input type to the same
    // number of elements as the widened result type. But this isn't always
    // the best thing so do some custom legalization to avoid some cases.
    MVT WidenVT = getTypeToTransformTo(*DAG.getContext(), VT).getSimpleVT();
    SDValue In = N->getOperand(0);
    EVT InVT = In.getValueType();

    unsigned InBits = InVT.getSizeInBits();
    if (128 % InBits == 0) {
      // 128 bit and smaller inputs should avoid truncate all together and
      // just use a build_vector that will become a shuffle.
      // TODO: Widen and use a shuffle directly?
      MVT InEltVT = InVT.getSimpleVT().getVectorElementType();
      EVT EltVT = VT.getVectorElementType();
      unsigned WidenNumElts = WidenVT.getVectorNumElements();
      SmallVector<SDValue, 16> Ops(WidenNumElts, DAG.getUNDEF(EltVT));
      // Use the original element count so we don't do more scalar opts than
      // necessary.
      unsigned MinElts = VT.getVectorNumElements();
      for (unsigned i=0; i < MinElts; ++i) {
        SDValue Val = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, InEltVT, In,
                                  DAG.getIntPtrConstant(i, dl));
        Ops[i] = DAG.getNode(ISD::TRUNCATE, dl, EltVT, Val);
      }
      Results.push_back(DAG.getBuildVector(WidenVT, dl, Ops));
      return;
    }
    // With AVX512 there are some cases that can use a target specific
    // truncate node to go from 256/512 to less than 128 with zeros in the
    // upper elements of the 128 bit result.
    if (Subtarget.hasAVX512() && isTypeLegal(InVT)) {
      // We can use VTRUNC directly if for 256 bits with VLX or for any 512.
      if ((InBits == 256 && Subtarget.hasVLX()) || InBits == 512) {
        Results.push_back(DAG.getNode(X86ISD::VTRUNC, dl, WidenVT, In));
        return;
      }
      // There's one case we can widen to 512 bits and use VTRUNC.
      if (InVT == MVT::v4i64 && VT == MVT::v4i8 && isTypeLegal(MVT::v8i64)) {
        In = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v8i64, In,
                         DAG.getUNDEF(MVT::v4i64));
        Results.push_back(DAG.getNode(X86ISD::VTRUNC, dl, WidenVT, In));
        return;
      }
    }
    if (Subtarget.hasVLX() && InVT == MVT::v8i64 && VT == MVT::v8i8 &&
        getTypeAction(*DAG.getContext(), InVT) == TypeSplitVector &&
        isTypeLegal(MVT::v4i64)) {
      // Input needs to be split and output needs to widened. Let's use two
      // VTRUNCs, and shuffle their results together into the wider type.
      SDValue Lo, Hi;
      std::tie(Lo, Hi) = DAG.SplitVector(In, dl);

      Lo = DAG.getNode(X86ISD::VTRUNC, dl, MVT::v16i8, Lo);
      Hi = DAG.getNode(X86ISD::VTRUNC, dl, MVT::v16i8, Hi);
      SDValue Res = DAG.getVectorShuffle(MVT::v16i8, dl, Lo, Hi,
                                         { 0,  1,  2,  3, 16, 17, 18, 19,
                                          -1, -1, -1, -1, -1, -1, -1, -1 });
      Results.push_back(Res);
      return;
    }

    return;
  }
  case ISD::ANY_EXTEND:
    // Right now, only MVT::v8i8 has Custom action for an illegal type.
    // It's intended to custom handle the input type.
    assert(N->getValueType(0) == MVT::v8i8 &&
           "Do not know how to legalize this Node");
    return;
  case ISD::SIGN_EXTEND:
  case ISD::ZERO_EXTEND: {
    EVT VT = N->getValueType(0);
    SDValue In = N->getOperand(0);
    EVT InVT = In.getValueType();
    if (!Subtarget.hasSSE41() && VT == MVT::v4i64 &&
        (InVT == MVT::v4i16 || InVT == MVT::v4i8)){
      assert(getTypeAction(*DAG.getContext(), InVT) == TypeWidenVector &&
             "Unexpected type action!");
      assert(N->getOpcode() == ISD::SIGN_EXTEND && "Unexpected opcode");
      // Custom split this so we can extend i8/i16->i32 invec. This is better
      // since sign_extend_inreg i8/i16->i64 requires an extend to i32 using
      // sra. Then extending from i32 to i64 using pcmpgt. By custom splitting
      // we allow the sra from the extend to i32 to be shared by the split.
      In = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, In);

      // Fill a vector with sign bits for each element.
      SDValue Zero = DAG.getConstant(0, dl, MVT::v4i32);
      SDValue SignBits = DAG.getSetCC(dl, MVT::v4i32, Zero, In, ISD::SETGT);

      // Create an unpackl and unpackh to interleave the sign bits then bitcast
      // to v2i64.
      SDValue Lo = DAG.getVectorShuffle(MVT::v4i32, dl, In, SignBits,
                                        {0, 4, 1, 5});
      Lo = DAG.getNode(ISD::BITCAST, dl, MVT::v2i64, Lo);
      SDValue Hi = DAG.getVectorShuffle(MVT::v4i32, dl, In, SignBits,
                                        {2, 6, 3, 7});
      Hi = DAG.getNode(ISD::BITCAST, dl, MVT::v2i64, Hi);

      SDValue Res = DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, Lo, Hi);
      Results.push_back(Res);
      return;
    }

    if (VT == MVT::v16i32 || VT == MVT::v8i64) {
      if (!InVT.is128BitVector()) {
        // Not a 128 bit vector, but maybe type legalization will promote
        // it to 128 bits.
        if (getTypeAction(*DAG.getContext(), InVT) != TypePromoteInteger)
          return;
        InVT = getTypeToTransformTo(*DAG.getContext(), InVT);
        if (!InVT.is128BitVector())
          return;

        // Promote the input to 128 bits. Type legalization will turn this into
        // zext_inreg/sext_inreg.
        In = DAG.getNode(N->getOpcode(), dl, InVT, In);
      }

      // Perform custom splitting instead of the two stage extend we would get
      // by default.
      EVT LoVT, HiVT;
      std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
      assert(isTypeLegal(LoVT) && "Split VT not legal?");

      SDValue Lo = getExtendInVec(N->getOpcode(), dl, LoVT, In, DAG);

      // We need to shift the input over by half the number of elements.
      unsigned NumElts = InVT.getVectorNumElements();
      unsigned HalfNumElts = NumElts / 2;
      SmallVector<int, 16> ShufMask(NumElts, SM_SentinelUndef);
      for (unsigned i = 0; i != HalfNumElts; ++i)
        ShufMask[i] = i + HalfNumElts;

      SDValue Hi = DAG.getVectorShuffle(InVT, dl, In, In, ShufMask);
      Hi = getExtendInVec(N->getOpcode(), dl, HiVT, Hi, DAG);

      SDValue Res = DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, Lo, Hi);
      Results.push_back(Res);
    }
    return;
  }
  case ISD::FP_TO_SINT:
  case ISD::STRICT_FP_TO_SINT:
  case ISD::FP_TO_UINT:
  case ISD::STRICT_FP_TO_UINT: {
    bool IsStrict = N->isStrictFPOpcode();
    bool IsSigned = N->getOpcode() == ISD::FP_TO_SINT ||
                    N->getOpcode() == ISD::STRICT_FP_TO_SINT;
    EVT VT = N->getValueType(0);
    SDValue Src = N->getOperand(IsStrict ? 1 : 0);
    EVT SrcVT = Src.getValueType();

    if (VT.isVector() && VT.getScalarSizeInBits() < 32) {
      assert(getTypeAction(*DAG.getContext(), VT) == TypeWidenVector &&
             "Unexpected type action!");

      // Try to create a 128 bit vector, but don't exceed a 32 bit element.
      unsigned NewEltWidth = std::min(128 / VT.getVectorNumElements(), 32U);
      MVT PromoteVT = MVT::getVectorVT(MVT::getIntegerVT(NewEltWidth),
                                       VT.getVectorNumElements());
      SDValue Res;
      SDValue Chain;
      if (IsStrict) {
        Res = DAG.getNode(ISD::STRICT_FP_TO_SINT, dl, {PromoteVT, MVT::Other},
                          {N->getOperand(0), Src});
        Chain = Res.getValue(1);
      } else
        Res = DAG.getNode(ISD::FP_TO_SINT, dl, PromoteVT, Src);

      // Preserve what we know about the size of the original result. Except
      // when the result is v2i32 since we can't widen the assert.
      if (PromoteVT != MVT::v2i32)
        Res = DAG.getNode(!IsSigned ? ISD::AssertZext : ISD::AssertSext,
                          dl, PromoteVT, Res,
                          DAG.getValueType(VT.getVectorElementType()));

      // Truncate back to the original width.
      Res = DAG.getNode(ISD::TRUNCATE, dl, VT, Res);

      // Now widen to 128 bits.
      unsigned NumConcats = 128 / VT.getSizeInBits();
      MVT ConcatVT = MVT::getVectorVT(VT.getSimpleVT().getVectorElementType(),
                                      VT.getVectorNumElements() * NumConcats);
      SmallVector<SDValue, 8> ConcatOps(NumConcats, DAG.getUNDEF(VT));
      ConcatOps[0] = Res;
      Res = DAG.getNode(ISD::CONCAT_VECTORS, dl, ConcatVT, ConcatOps);
      Results.push_back(Res);
      if (IsStrict)
        Results.push_back(Chain);
      return;
    }


    if (VT == MVT::v2i32) {
      assert((IsSigned || Subtarget.hasAVX512()) &&
             "Can only handle signed conversion without AVX512");
      assert(Subtarget.hasSSE2() && "Requires at least SSE2!");
      assert(getTypeAction(*DAG.getContext(), VT) == TypeWidenVector &&
             "Unexpected type action!");
      if (Src.getValueType() == MVT::v2f64) {
        unsigned Opc;
        if (IsStrict)
          Opc = IsSigned ? X86ISD::STRICT_CVTTP2SI : X86ISD::STRICT_CVTTP2UI;
        else
          Opc = IsSigned ? X86ISD::CVTTP2SI : X86ISD::CVTTP2UI;

        // If we have VLX we can emit a target specific FP_TO_UINT node,.
        if (!IsSigned && !Subtarget.hasVLX()) {
          // Otherwise we can defer to the generic legalizer which will widen
          // the input as well. This will be further widened during op
          // legalization to v8i32<-v8f64.
          // For strict nodes we'll need to widen ourselves.
          // FIXME: Fix the type legalizer to safely widen strict nodes?
          if (!IsStrict)
            return;
          Src = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v4f64, Src,
                            DAG.getConstantFP(0.0, dl, MVT::v2f64));
          Opc = N->getOpcode();
        }
        SDValue Res;
        SDValue Chain;
        if (IsStrict) {
          Res = DAG.getNode(Opc, dl, {MVT::v4i32, MVT::Other},
                            {N->getOperand(0), Src});
          Chain = Res.getValue(1);
        } else {
          Res = DAG.getNode(Opc, dl, MVT::v4i32, Src);
        }
        Results.push_back(Res);
        if (IsStrict)
          Results.push_back(Chain);
        return;
      }

      // Custom widen strict v2f32->v2i32 by padding with zeros.
      // FIXME: Should generic type legalizer do this?
      if (Src.getValueType() == MVT::v2f32 && IsStrict) {
        Src = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v4f32, Src,
                          DAG.getConstantFP(0.0, dl, MVT::v2f32));
        SDValue Res = DAG.getNode(N->getOpcode(), dl, {MVT::v4i32, MVT::Other},
                                  {N->getOperand(0), Src});
        Results.push_back(Res);
        Results.push_back(Res.getValue(1));
        return;
      }

      // The FP_TO_INTHelper below only handles f32/f64/f80 scalar inputs,
      // so early out here.
      return;
    }

    assert(!VT.isVector() && "Vectors should have been handled above!");

    if (Subtarget.hasDQI() && VT == MVT::i64 &&
        (SrcVT == MVT::f32 || SrcVT == MVT::f64)) {
      assert(!Subtarget.is64Bit() && "i64 should be legal");
      unsigned NumElts = Subtarget.hasVLX() ? 2 : 8;
      // If we use a 128-bit result we might need to use a target specific node.
      unsigned SrcElts =
          std::max(NumElts, 128U / (unsigned)SrcVT.getSizeInBits());
      MVT VecVT = MVT::getVectorVT(MVT::i64, NumElts);
      MVT VecInVT = MVT::getVectorVT(SrcVT.getSimpleVT(), SrcElts);
      unsigned Opc = N->getOpcode();
      if (NumElts != SrcElts) {
        if (IsStrict)
          Opc = IsSigned ? X86ISD::STRICT_CVTTP2SI : X86ISD::STRICT_CVTTP2UI;
        else
          Opc = IsSigned ? X86ISD::CVTTP2SI : X86ISD::CVTTP2UI;
      }

      SDValue ZeroIdx = DAG.getIntPtrConstant(0, dl);
      SDValue Res = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VecInVT,
                                DAG.getConstantFP(0.0, dl, VecInVT), Src,
                                ZeroIdx);
      SDValue Chain;
      if (IsStrict) {
        SDVTList Tys = DAG.getVTList(VecVT, MVT::Other);
        Res = DAG.getNode(Opc, SDLoc(N), Tys, N->getOperand(0), Res);
        Chain = Res.getValue(1);
      } else
        Res = DAG.getNode(Opc, SDLoc(N), VecVT, Res);
      Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT, Res, ZeroIdx);
      Results.push_back(Res);
      if (IsStrict)
        Results.push_back(Chain);
      return;
    }

    SDValue Chain;
    if (SDValue V = FP_TO_INTHelper(SDValue(N, 0), DAG, IsSigned, Chain)) {
      Results.push_back(V);
      if (IsStrict)
        Results.push_back(Chain);
    }
    return;
  }
  case ISD::LRINT:
  case ISD::LLRINT: {
    if (SDValue V = LRINT_LLRINTHelper(N, DAG))
      Results.push_back(V);
    return;
  }

  case ISD::SINT_TO_FP:
  case ISD::STRICT_SINT_TO_FP:
  case ISD::UINT_TO_FP:
  case ISD::STRICT_UINT_TO_FP: {
    bool IsStrict = N->isStrictFPOpcode();
    bool IsSigned = N->getOpcode() == ISD::SINT_TO_FP ||
                    N->getOpcode() == ISD::STRICT_SINT_TO_FP;
    EVT VT = N->getValueType(0);
    if (VT != MVT::v2f32)
      return;
    SDValue Src = N->getOperand(IsStrict ? 1 : 0);
    EVT SrcVT = Src.getValueType();
    if (Subtarget.hasDQI() && Subtarget.hasVLX() && SrcVT == MVT::v2i64) {
      if (IsStrict) {
        unsigned Opc = IsSigned ? X86ISD::STRICT_CVTSI2P
                                : X86ISD::STRICT_CVTUI2P;
        SDValue Res = DAG.getNode(Opc, dl, {MVT::v4f32, MVT::Other},
                                  {N->getOperand(0), Src});
        Results.push_back(Res);
        Results.push_back(Res.getValue(1));
      } else {
        unsigned Opc = IsSigned ? X86ISD::CVTSI2P : X86ISD::CVTUI2P;
        Results.push_back(DAG.getNode(Opc, dl, MVT::v4f32, Src));
      }
      return;
    }
    if (SrcVT == MVT::v2i64 && !IsSigned && Subtarget.is64Bit() &&
        Subtarget.hasSSE41() && !Subtarget.hasAVX512()) {
      SDValue Zero = DAG.getConstant(0, dl, SrcVT);
      SDValue One  = DAG.getConstant(1, dl, SrcVT);
      SDValue Sign = DAG.getNode(ISD::OR, dl, SrcVT,
                                 DAG.getNode(ISD::SRL, dl, SrcVT, Src, One),
                                 DAG.getNode(ISD::AND, dl, SrcVT, Src, One));
      SDValue IsNeg = DAG.getSetCC(dl, MVT::v2i64, Src, Zero, ISD::SETLT);
      SDValue SignSrc = DAG.getSelect(dl, SrcVT, IsNeg, Sign, Src);
      SmallVector<SDValue, 4> SignCvts(4, DAG.getConstantFP(0.0, dl, MVT::f32));
      for (int i = 0; i != 2; ++i) {
        SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i64,
                                  SignSrc, DAG.getIntPtrConstant(i, dl));
        if (IsStrict)
          SignCvts[i] =
              DAG.getNode(ISD::STRICT_SINT_TO_FP, dl, {MVT::f32, MVT::Other},
                          {N->getOperand(0), Elt});
        else
          SignCvts[i] = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, Elt);
      };
      SDValue SignCvt = DAG.getBuildVector(MVT::v4f32, dl, SignCvts);
      SDValue Slow, Chain;
      if (IsStrict) {
        Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
                            SignCvts[0].getValue(1), SignCvts[1].getValue(1));
        Slow = DAG.getNode(ISD::STRICT_FADD, dl, {MVT::v4f32, MVT::Other},
                           {Chain, SignCvt, SignCvt});
        Chain = Slow.getValue(1);
      } else {
        Slow = DAG.getNode(ISD::FADD, dl, MVT::v4f32, SignCvt, SignCvt);
      }
      IsNeg = DAG.getBitcast(MVT::v4i32, IsNeg);
      IsNeg =
          DAG.getVectorShuffle(MVT::v4i32, dl, IsNeg, IsNeg, {1, 3, -1, -1});
      SDValue Cvt = DAG.getSelect(dl, MVT::v4f32, IsNeg, Slow, SignCvt);
      Results.push_back(Cvt);
      if (IsStrict)
        Results.push_back(Chain);
      return;
    }

    if (SrcVT != MVT::v2i32)
      return;

    if (IsSigned || Subtarget.hasAVX512()) {
      if (!IsStrict)
        return;

      // Custom widen strict v2i32->v2f32 to avoid scalarization.
      // FIXME: Should generic type legalizer do this?
      Src = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v4i32, Src,
                        DAG.getConstant(0, dl, MVT::v2i32));
      SDValue Res = DAG.getNode(N->getOpcode(), dl, {MVT::v4f32, MVT::Other},
                                {N->getOperand(0), Src});
      Results.push_back(Res);
      Results.push_back(Res.getValue(1));
      return;
    }

    assert(Subtarget.hasSSE2() && "Requires at least SSE2!");
    SDValue ZExtIn = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::v2i64, Src);
    SDValue VBias =
        DAG.getConstantFP(BitsToDouble(0x4330000000000000ULL), dl, MVT::v2f64);
    SDValue Or = DAG.getNode(ISD::OR, dl, MVT::v2i64, ZExtIn,
                             DAG.getBitcast(MVT::v2i64, VBias));
    Or = DAG.getBitcast(MVT::v2f64, Or);
    if (IsStrict) {
      SDValue Sub = DAG.getNode(ISD::STRICT_FSUB, dl, {MVT::v2f64, MVT::Other},
                                {N->getOperand(0), Or, VBias});
      SDValue Res = DAG.getNode(X86ISD::STRICT_VFPROUND, dl,
                                {MVT::v4f32, MVT::Other},
                                {Sub.getValue(1), Sub});
      Results.push_back(Res);
      Results.push_back(Res.getValue(1));
    } else {
      // TODO: Are there any fast-math-flags to propagate here?
      SDValue Sub = DAG.getNode(ISD::FSUB, dl, MVT::v2f64, Or, VBias);
      Results.push_back(DAG.getNode(X86ISD::VFPROUND, dl, MVT::v4f32, Sub));
    }
    return;
  }
  case ISD::STRICT_FP_ROUND:
  case ISD::FP_ROUND: {
    bool IsStrict = N->isStrictFPOpcode();
    SDValue Src = N->getOperand(IsStrict ? 1 : 0);
    if (!isTypeLegal(Src.getValueType()))
      return;
    SDValue V;
    if (IsStrict)
      V = DAG.getNode(X86ISD::STRICT_VFPROUND, dl, {MVT::v4f32, MVT::Other},
                      {N->getOperand(0), N->getOperand(1)});
    else
      V = DAG.getNode(X86ISD::VFPROUND, dl, MVT::v4f32, N->getOperand(0));
    Results.push_back(V);
    if (IsStrict)
      Results.push_back(V.getValue(1));
    return;
  }
  case ISD::FP_EXTEND:
  case ISD::STRICT_FP_EXTEND: {
    // Right now, only MVT::v2f32 has OperationAction for FP_EXTEND.
    // No other ValueType for FP_EXTEND should reach this point.
    assert(N->getValueType(0) == MVT::v2f32 &&
           "Do not know how to legalize this Node");
    return;
  }
  case ISD::INTRINSIC_W_CHAIN: {
    unsigned IntNo = N->getConstantOperandVal(1);
    switch (IntNo) {
    default : llvm_unreachable("Do not know how to custom type "
                               "legalize this intrinsic operation!");
    case Intrinsic::x86_rdtsc:
      return getReadTimeStampCounter(N, dl, X86::RDTSC, DAG, Subtarget,
                                     Results);
    case Intrinsic::x86_rdtscp:
      return getReadTimeStampCounter(N, dl, X86::RDTSCP, DAG, Subtarget,
                                     Results);
    case Intrinsic::x86_rdpmc:
      expandIntrinsicWChainHelper(N, dl, DAG, X86::RDPMC, X86::ECX, Subtarget,
                                  Results);
      return;
    case Intrinsic::x86_xgetbv:
      expandIntrinsicWChainHelper(N, dl, DAG, X86::XGETBV, X86::ECX, Subtarget,
                                  Results);
      return;
    }
  }
  case ISD::READCYCLECOUNTER: {
    return getReadTimeStampCounter(N, dl, X86::RDTSC, DAG, Subtarget, Results);
  }
  case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS: {
    EVT T = N->getValueType(0);
    assert((T == MVT::i64 || T == MVT::i128) && "can only expand cmpxchg pair");
    bool Regs64bit = T == MVT::i128;
    assert((!Regs64bit || Subtarget.hasCmpxchg16b()) &&
           "64-bit ATOMIC_CMP_SWAP_WITH_SUCCESS requires CMPXCHG16B");
    MVT HalfT = Regs64bit ? MVT::i64 : MVT::i32;
    SDValue cpInL, cpInH;
    cpInL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, HalfT, N->getOperand(2),
                        DAG.getConstant(0, dl, HalfT));
    cpInH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, HalfT, N->getOperand(2),
                        DAG.getConstant(1, dl, HalfT));
    cpInL = DAG.getCopyToReg(N->getOperand(0), dl,
                             Regs64bit ? X86::RAX : X86::EAX,
                             cpInL, SDValue());
    cpInH = DAG.getCopyToReg(cpInL.getValue(0), dl,
                             Regs64bit ? X86::RDX : X86::EDX,
                             cpInH, cpInL.getValue(1));
    SDValue swapInL, swapInH;
    swapInL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, HalfT, N->getOperand(3),
                          DAG.getConstant(0, dl, HalfT));
    swapInH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, HalfT, N->getOperand(3),
                          DAG.getConstant(1, dl, HalfT));
    swapInH =
        DAG.getCopyToReg(cpInH.getValue(0), dl, Regs64bit ? X86::RCX : X86::ECX,
                         swapInH, cpInH.getValue(1));
    // If the current function needs the base pointer, RBX,
    // we shouldn't use cmpxchg directly.
    // Indeed the lowering of that instruction will clobber
    // that register and since RBX will be a reserved register
    // the register allocator will not make sure its value will
    // be properly saved and restored around this live-range.
    const X86RegisterInfo *TRI = Subtarget.getRegisterInfo();
    SDValue Result;
    SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Glue);
    Register BasePtr = TRI->getBaseRegister();
    MachineMemOperand *MMO = cast<AtomicSDNode>(N)->getMemOperand();
    if (TRI->hasBasePointer(DAG.getMachineFunction()) &&
        (BasePtr == X86::RBX || BasePtr == X86::EBX)) {
      // ISel prefers the LCMPXCHG64 variant.
      // If that assert breaks, that means it is not the case anymore,
      // and we need to teach LCMPXCHG8_SAVE_EBX_DAG how to save RBX,
      // not just EBX. This is a matter of accepting i64 input for that
      // pseudo, and restoring into the register of the right wide
      // in expand pseudo. Everything else should just work.
      assert(((Regs64bit == (BasePtr == X86::RBX)) || BasePtr == X86::EBX) &&
             "Saving only half of the RBX");
      unsigned Opcode = Regs64bit ? X86ISD::LCMPXCHG16_SAVE_RBX_DAG
                                  : X86ISD::LCMPXCHG8_SAVE_EBX_DAG;
      SDValue RBXSave = DAG.getCopyFromReg(swapInH.getValue(0), dl,
                                           Regs64bit ? X86::RBX : X86::EBX,
                                           HalfT, swapInH.getValue(1));
      SDValue Ops[] = {/*Chain*/ RBXSave.getValue(1), N->getOperand(1), swapInL,
                       RBXSave,
                       /*Glue*/ RBXSave.getValue(2)};
      Result = DAG.getMemIntrinsicNode(Opcode, dl, Tys, Ops, T, MMO);
    } else {
      unsigned Opcode =
          Regs64bit ? X86ISD::LCMPXCHG16_DAG : X86ISD::LCMPXCHG8_DAG;
      swapInL = DAG.getCopyToReg(swapInH.getValue(0), dl,
                                 Regs64bit ? X86::RBX : X86::EBX, swapInL,
                                 swapInH.getValue(1));
      SDValue Ops[] = {swapInL.getValue(0), N->getOperand(1),
                       swapInL.getValue(1)};
      Result = DAG.getMemIntrinsicNode(Opcode, dl, Tys, Ops, T, MMO);
    }
    SDValue cpOutL = DAG.getCopyFromReg(Result.getValue(0), dl,
                                        Regs64bit ? X86::RAX : X86::EAX,
                                        HalfT, Result.getValue(1));
    SDValue cpOutH = DAG.getCopyFromReg(cpOutL.getValue(1), dl,
                                        Regs64bit ? X86::RDX : X86::EDX,
                                        HalfT, cpOutL.getValue(2));
    SDValue OpsF[] = { cpOutL.getValue(0), cpOutH.getValue(0)};

    SDValue EFLAGS = DAG.getCopyFromReg(cpOutH.getValue(1), dl, X86::EFLAGS,
                                        MVT::i32, cpOutH.getValue(2));
    SDValue Success = getSETCC(X86::COND_E, EFLAGS, dl, DAG);
    Success = DAG.getZExtOrTrunc(Success, dl, N->getValueType(1));

    Results.push_back(DAG.getNode(ISD::BUILD_PAIR, dl, T, OpsF));
    Results.push_back(Success);
    Results.push_back(EFLAGS.getValue(1));
    return;
  }
  case ISD::ATOMIC_LOAD: {
    assert(N->getValueType(0) == MVT::i64 && "Unexpected VT!");
    bool NoImplicitFloatOps =
        DAG.getMachineFunction().getFunction().hasFnAttribute(
            Attribute::NoImplicitFloat);
    if (!Subtarget.useSoftFloat() && !NoImplicitFloatOps) {
      auto *Node = cast<AtomicSDNode>(N);
      if (Subtarget.hasSSE1()) {
        // Use a VZEXT_LOAD which will be selected as MOVQ or XORPS+MOVLPS.
        // Then extract the lower 64-bits.
        MVT LdVT = Subtarget.hasSSE2() ? MVT::v2i64 : MVT::v4f32;
        SDVTList Tys = DAG.getVTList(LdVT, MVT::Other);
        SDValue Ops[] = { Node->getChain(), Node->getBasePtr() };
        SDValue Ld = DAG.getMemIntrinsicNode(X86ISD::VZEXT_LOAD, dl, Tys, Ops,
                                             MVT::i64, Node->getMemOperand());
        if (Subtarget.hasSSE2()) {
          SDValue Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i64, Ld,
                                    DAG.getIntPtrConstant(0, dl));
          Results.push_back(Res);
          Results.push_back(Ld.getValue(1));
          return;
        }
        // We use an alternative sequence for SSE1 that extracts as v2f32 and
        // then casts to i64. This avoids a 128-bit stack temporary being
        // created by type legalization if we were to cast v4f32->v2i64.
        SDValue Res = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v2f32, Ld,
                                  DAG.getIntPtrConstant(0, dl));
        Res = DAG.getBitcast(MVT::i64, Res);
        Results.push_back(Res);
        Results.push_back(Ld.getValue(1));
        return;
      }
      if (Subtarget.hasX87()) {
        // First load this into an 80-bit X87 register. This will put the whole
        // integer into the significand.
        SDVTList Tys = DAG.getVTList(MVT::f80, MVT::Other);
        SDValue Ops[] = { Node->getChain(), Node->getBasePtr() };
        SDValue Result = DAG.getMemIntrinsicNode(X86ISD::FILD,
                                                 dl, Tys, Ops, MVT::i64,
                                                 Node->getMemOperand());
        SDValue Chain = Result.getValue(1);

        // Now store the X87 register to a stack temporary and convert to i64.
        // This store is not atomic and doesn't need to be.
        // FIXME: We don't need a stack temporary if the result of the load
        // is already being stored. We could just directly store there.
        SDValue StackPtr = DAG.CreateStackTemporary(MVT::i64);
        int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
        MachinePointerInfo MPI =
            MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SPFI);
        SDValue StoreOps[] = { Chain, Result, StackPtr };
        Chain = DAG.getMemIntrinsicNode(
            X86ISD::FIST, dl, DAG.getVTList(MVT::Other), StoreOps, MVT::i64,
            MPI, None /*Align*/, MachineMemOperand::MOStore);

        // Finally load the value back from the stack temporary and return it.
        // This load is not atomic and doesn't need to be.
        // This load will be further type legalized.
        Result = DAG.getLoad(MVT::i64, dl, Chain, StackPtr, MPI);
        Results.push_back(Result);
        Results.push_back(Result.getValue(1));
        return;
      }
    }
    // TODO: Use MOVLPS when SSE1 is available?
    // Delegate to generic TypeLegalization. Situations we can really handle
    // should have already been dealt with by AtomicExpandPass.cpp.
    break;
  }
  case ISD::ATOMIC_SWAP:
  case ISD::ATOMIC_LOAD_ADD:
  case ISD::ATOMIC_LOAD_SUB:
  case ISD::ATOMIC_LOAD_AND:
  case ISD::ATOMIC_LOAD_OR:
  case ISD::ATOMIC_LOAD_XOR:
  case ISD::ATOMIC_LOAD_NAND:
  case ISD::ATOMIC_LOAD_MIN:
  case ISD::ATOMIC_LOAD_MAX:
  case ISD::ATOMIC_LOAD_UMIN:
  case ISD::ATOMIC_LOAD_UMAX:
    // Delegate to generic TypeLegalization. Situations we can really handle
    // should have already been dealt with by AtomicExpandPass.cpp.
    break;

  case ISD::BITCAST: {
    assert(Subtarget.hasSSE2() && "Requires at least SSE2!");
    EVT DstVT = N->getValueType(0);
    EVT SrcVT = N->getOperand(0).getValueType();

    // If this is a bitcast from a v64i1 k-register to a i64 on a 32-bit target
    // we can split using the k-register rather than memory.
    if (SrcVT == MVT::v64i1 && DstVT == MVT::i64 && Subtarget.hasBWI()) {
      assert(!Subtarget.is64Bit() && "Expected 32-bit mode");
      SDValue Lo, Hi;
      std::tie(Lo, Hi) = DAG.SplitVectorOperand(N, 0);
      Lo = DAG.getBitcast(MVT::i32, Lo);
      Hi = DAG.getBitcast(MVT::i32, Hi);
      SDValue Res = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
      Results.push_back(Res);
      return;
    }

    // Custom splitting for BWI types when AVX512F is available but BWI isn't.
    if ((DstVT == MVT::v32i16 || DstVT == MVT::v64i8) &&
        SrcVT.isVector() && isTypeLegal(SrcVT)) {
      SDValue Lo, Hi;
      std::tie(Lo, Hi) = DAG.SplitVectorOperand(N, 0);
      MVT CastVT = (DstVT == MVT::v32i16) ? MVT::v16i16 : MVT::v32i8;
      Lo = DAG.getBitcast(CastVT, Lo);
      Hi = DAG.getBitcast(CastVT, Hi);
      SDValue Res = DAG.getNode(ISD::CONCAT_VECTORS, dl, DstVT, Lo, Hi);
      Results.push_back(Res);
      return;
    }

    if (DstVT.isVector() && SrcVT == MVT::x86mmx) {
      assert(getTypeAction(*DAG.getContext(), DstVT) == TypeWidenVector &&
             "Unexpected type action!");
      EVT WideVT = getTypeToTransformTo(*DAG.getContext(), DstVT);
      SDValue Res = DAG.getNode(X86ISD::MOVQ2DQ, dl, WideVT, N->getOperand(0));
      Results.push_back(Res);
      return;
    }

    return;
  }
  case ISD::MGATHER: {
    EVT VT = N->getValueType(0);
    if ((VT == MVT::v2f32 || VT == MVT::v2i32) &&
        (Subtarget.hasVLX() || !Subtarget.hasAVX512())) {
      auto *Gather = cast<MaskedGatherSDNode>(N);
      SDValue Index = Gather->getIndex();
      if (Index.getValueType() != MVT::v2i64)
        return;
      assert(getTypeAction(*DAG.getContext(), VT) == TypeWidenVector &&
             "Unexpected type action!");
      EVT WideVT = getTypeToTransformTo(*DAG.getContext(), VT);
      SDValue Mask = Gather->getMask();
      assert(Mask.getValueType() == MVT::v2i1 && "Unexpected mask type");
      SDValue PassThru = DAG.getNode(ISD::CONCAT_VECTORS, dl, WideVT,
                                     Gather->getPassThru(),
                                     DAG.getUNDEF(VT));
      if (!Subtarget.hasVLX()) {
        // We need to widen the mask, but the instruction will only use 2
        // of its elements. So we can use undef.
        Mask = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v4i1, Mask,
                           DAG.getUNDEF(MVT::v2i1));
        Mask = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, Mask);
      }
      SDValue Ops[] = { Gather->getChain(), PassThru, Mask,
                        Gather->getBasePtr(), Index, Gather->getScale() };
      SDValue Res = DAG.getMemIntrinsicNode(
          X86ISD::MGATHER, dl, DAG.getVTList(WideVT, MVT::Other), Ops,
          Gather->getMemoryVT(), Gather->getMemOperand());
      Results.push_back(Res);
      Results.push_back(Res.getValue(1));
      return;
    }
    return;
  }
  case ISD::LOAD: {
    // Use an f64/i64 load and a scalar_to_vector for v2f32/v2i32 loads. This
    // avoids scalarizing in 32-bit mode. In 64-bit mode this avoids a int->fp
    // cast since type legalization will try to use an i64 load.
    MVT VT = N->getSimpleValueType(0);
    assert(VT.isVector() && VT.getSizeInBits() == 64 && "Unexpected VT");
    assert(getTypeAction(*DAG.getContext(), VT) == TypeWidenVector &&
           "Unexpected type action!");
    if (!ISD::isNON_EXTLoad(N))
      return;
    auto *Ld = cast<LoadSDNode>(N);
    if (Subtarget.hasSSE2()) {
      MVT LdVT = Subtarget.is64Bit() && VT.isInteger() ? MVT::i64 : MVT::f64;
      SDValue Res = DAG.getLoad(LdVT, dl, Ld->getChain(), Ld->getBasePtr(),
                                Ld->getPointerInfo(), Ld->getAlignment(),
                                Ld->getMemOperand()->getFlags());
      SDValue Chain = Res.getValue(1);
      MVT VecVT = MVT::getVectorVT(LdVT, 2);
      Res = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VecVT, Res);
      EVT WideVT = getTypeToTransformTo(*DAG.getContext(), VT);
      Res = DAG.getBitcast(WideVT, Res);
      Results.push_back(Res);
      Results.push_back(Chain);
      return;
    }
    assert(Subtarget.hasSSE1() && "Expected SSE");
    SDVTList Tys = DAG.getVTList(MVT::v4f32, MVT::Other);
    SDValue Ops[] = {Ld->getChain(), Ld->getBasePtr()};
    SDValue Res = DAG.getMemIntrinsicNode(X86ISD::VZEXT_LOAD, dl, Tys, Ops,
                                          MVT::i64, Ld->getMemOperand());
    Results.push_back(Res);
    Results.push_back(Res.getValue(1));
    return;
  }
  case ISD::ADDRSPACECAST: {
    SDValue Src = N->getOperand(0);
    EVT DstVT = N->getValueType(0);
    AddrSpaceCastSDNode *CastN = cast<AddrSpaceCastSDNode>(N);
    unsigned SrcAS = CastN->getSrcAddressSpace();

    assert(SrcAS != CastN->getDestAddressSpace() &&
           "addrspacecast must be between different address spaces");

    SDValue Res;
    if (SrcAS == X86AS::PTR32_UPTR && DstVT == MVT::i64)
      Res = DAG.getNode(ISD::ZERO_EXTEND, dl, DstVT, Src);
    else if (DstVT == MVT::i64)
      Res = DAG.getNode(ISD::SIGN_EXTEND, dl, DstVT, Src);
    else if (DstVT == MVT::i32)
      Res = DAG.getNode(ISD::TRUNCATE, dl, DstVT, Src);
    else
      report_fatal_error("Unrecognized addrspacecast type legalization");

    Results.push_back(Res);
    return;
  }
  }
}

const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
  switch ((X86ISD::NodeType)Opcode) {
  case X86ISD::FIRST_NUMBER:       break;
#define NODE_NAME_CASE(NODE) case X86ISD::NODE: return "X86ISD::" #NODE;
  NODE_NAME_CASE(BSF)
  NODE_NAME_CASE(BSR)
  NODE_NAME_CASE(FSHL)
  NODE_NAME_CASE(FSHR)
  NODE_NAME_CASE(FAND)
  NODE_NAME_CASE(FANDN)
  NODE_NAME_CASE(FOR)
  NODE_NAME_CASE(FXOR)
  NODE_NAME_CASE(FILD)
  NODE_NAME_CASE(FIST)
  NODE_NAME_CASE(FP_TO_INT_IN_MEM)
  NODE_NAME_CASE(FLD)
  NODE_NAME_CASE(FST)
  NODE_NAME_CASE(CALL)
  NODE_NAME_CASE(BT)
  NODE_NAME_CASE(CMP)
  NODE_NAME_CASE(FCMP)
  NODE_NAME_CASE(STRICT_FCMP)
  NODE_NAME_CASE(STRICT_FCMPS)
  NODE_NAME_CASE(COMI)
  NODE_NAME_CASE(UCOMI)
  NODE_NAME_CASE(CMPM)
  NODE_NAME_CASE(STRICT_CMPM)
  NODE_NAME_CASE(CMPM_SAE)
  NODE_NAME_CASE(SETCC)
  NODE_NAME_CASE(SETCC_CARRY)
  NODE_NAME_CASE(FSETCC)
  NODE_NAME_CASE(FSETCCM)
  NODE_NAME_CASE(FSETCCM_SAE)
  NODE_NAME_CASE(CMOV)
  NODE_NAME_CASE(BRCOND)
  NODE_NAME_CASE(RET_FLAG)
  NODE_NAME_CASE(IRET)
  NODE_NAME_CASE(REP_STOS)
  NODE_NAME_CASE(REP_MOVS)
  NODE_NAME_CASE(GlobalBaseReg)
  NODE_NAME_CASE(Wrapper)
  NODE_NAME_CASE(WrapperRIP)
  NODE_NAME_CASE(MOVQ2DQ)
  NODE_NAME_CASE(MOVDQ2Q)
  NODE_NAME_CASE(MMX_MOVD2W)
  NODE_NAME_CASE(MMX_MOVW2D)
  NODE_NAME_CASE(PEXTRB)
  NODE_NAME_CASE(PEXTRW)
  NODE_NAME_CASE(INSERTPS)
  NODE_NAME_CASE(PINSRB)
  NODE_NAME_CASE(PINSRW)
  NODE_NAME_CASE(PSHUFB)
  NODE_NAME_CASE(ANDNP)
  NODE_NAME_CASE(BLENDI)
  NODE_NAME_CASE(BLENDV)
  NODE_NAME_CASE(HADD)
  NODE_NAME_CASE(HSUB)
  NODE_NAME_CASE(FHADD)
  NODE_NAME_CASE(FHSUB)
  NODE_NAME_CASE(CONFLICT)
  NODE_NAME_CASE(FMAX)
  NODE_NAME_CASE(FMAXS)
  NODE_NAME_CASE(FMAX_SAE)
  NODE_NAME_CASE(FMAXS_SAE)
  NODE_NAME_CASE(FMIN)
  NODE_NAME_CASE(FMINS)
  NODE_NAME_CASE(FMIN_SAE)
  NODE_NAME_CASE(FMINS_SAE)
  NODE_NAME_CASE(FMAXC)
  NODE_NAME_CASE(FMINC)
  NODE_NAME_CASE(FRSQRT)
  NODE_NAME_CASE(FRCP)
  NODE_NAME_CASE(EXTRQI)
  NODE_NAME_CASE(INSERTQI)
  NODE_NAME_CASE(TLSADDR)
  NODE_NAME_CASE(TLSBASEADDR)
  NODE_NAME_CASE(TLSCALL)
  NODE_NAME_CASE(EH_SJLJ_SETJMP)
  NODE_NAME_CASE(EH_SJLJ_LONGJMP)
  NODE_NAME_CASE(EH_SJLJ_SETUP_DISPATCH)
  NODE_NAME_CASE(EH_RETURN)
  NODE_NAME_CASE(TC_RETURN)
  NODE_NAME_CASE(FNSTCW16m)
  NODE_NAME_CASE(LCMPXCHG_DAG)
  NODE_NAME_CASE(LCMPXCHG8_DAG)
  NODE_NAME_CASE(LCMPXCHG16_DAG)
  NODE_NAME_CASE(LCMPXCHG8_SAVE_EBX_DAG)
  NODE_NAME_CASE(LCMPXCHG16_SAVE_RBX_DAG)
  NODE_NAME_CASE(LADD)
  NODE_NAME_CASE(LSUB)
  NODE_NAME_CASE(LOR)
  NODE_NAME_CASE(LXOR)
  NODE_NAME_CASE(LAND)
  NODE_NAME_CASE(VZEXT_MOVL)
  NODE_NAME_CASE(VZEXT_LOAD)
  NODE_NAME_CASE(VEXTRACT_STORE)
  NODE_NAME_CASE(VTRUNC)
  NODE_NAME_CASE(VTRUNCS)
  NODE_NAME_CASE(VTRUNCUS)
  NODE_NAME_CASE(VMTRUNC)
  NODE_NAME_CASE(VMTRUNCS)
  NODE_NAME_CASE(VMTRUNCUS)
  NODE_NAME_CASE(VTRUNCSTORES)
  NODE_NAME_CASE(VTRUNCSTOREUS)
  NODE_NAME_CASE(VMTRUNCSTORES)
  NODE_NAME_CASE(VMTRUNCSTOREUS)
  NODE_NAME_CASE(VFPEXT)
  NODE_NAME_CASE(STRICT_VFPEXT)
  NODE_NAME_CASE(VFPEXT_SAE)
  NODE_NAME_CASE(VFPEXTS)
  NODE_NAME_CASE(VFPEXTS_SAE)
  NODE_NAME_CASE(VFPROUND)
  NODE_NAME_CASE(STRICT_VFPROUND)
  NODE_NAME_CASE(VMFPROUND)
  NODE_NAME_CASE(VFPROUND_RND)
  NODE_NAME_CASE(VFPROUNDS)
  NODE_NAME_CASE(VFPROUNDS_RND)
  NODE_NAME_CASE(VSHLDQ)
  NODE_NAME_CASE(VSRLDQ)
  NODE_NAME_CASE(VSHL)
  NODE_NAME_CASE(VSRL)
  NODE_NAME_CASE(VSRA)
  NODE_NAME_CASE(VSHLI)
  NODE_NAME_CASE(VSRLI)
  NODE_NAME_CASE(VSRAI)
  NODE_NAME_CASE(VSHLV)
  NODE_NAME_CASE(VSRLV)
  NODE_NAME_CASE(VSRAV)
  NODE_NAME_CASE(VROTLI)
  NODE_NAME_CASE(VROTRI)
  NODE_NAME_CASE(VPPERM)
  NODE_NAME_CASE(CMPP)
  NODE_NAME_CASE(STRICT_CMPP)
  NODE_NAME_CASE(PCMPEQ)
  NODE_NAME_CASE(PCMPGT)
  NODE_NAME_CASE(PHMINPOS)
  NODE_NAME_CASE(ADD)
  NODE_NAME_CASE(SUB)
  NODE_NAME_CASE(ADC)
  NODE_NAME_CASE(SBB)
  NODE_NAME_CASE(SMUL)
  NODE_NAME_CASE(UMUL)
  NODE_NAME_CASE(OR)
  NODE_NAME_CASE(XOR)
  NODE_NAME_CASE(AND)
  NODE_NAME_CASE(BEXTR)
  NODE_NAME_CASE(BZHI)
  NODE_NAME_CASE(MUL_IMM)
  NODE_NAME_CASE(MOVMSK)
  NODE_NAME_CASE(PTEST)
  NODE_NAME_CASE(TESTP)
  NODE_NAME_CASE(KORTEST)
  NODE_NAME_CASE(KTEST)
  NODE_NAME_CASE(KADD)
  NODE_NAME_CASE(KSHIFTL)
  NODE_NAME_CASE(KSHIFTR)
  NODE_NAME_CASE(PACKSS)
  NODE_NAME_CASE(PACKUS)
  NODE_NAME_CASE(PALIGNR)
  NODE_NAME_CASE(VALIGN)
  NODE_NAME_CASE(VSHLD)
  NODE_NAME_CASE(VSHRD)
  NODE_NAME_CASE(VSHLDV)
  NODE_NAME_CASE(VSHRDV)
  NODE_NAME_CASE(PSHUFD)
  NODE_NAME_CASE(PSHUFHW)
  NODE_NAME_CASE(PSHUFLW)
  NODE_NAME_CASE(SHUFP)
  NODE_NAME_CASE(SHUF128)
  NODE_NAME_CASE(MOVLHPS)
  NODE_NAME_CASE(MOVHLPS)
  NODE_NAME_CASE(MOVDDUP)
  NODE_NAME_CASE(MOVSHDUP)
  NODE_NAME_CASE(MOVSLDUP)
  NODE_NAME_CASE(MOVSD)
  NODE_NAME_CASE(MOVSS)
  NODE_NAME_CASE(UNPCKL)
  NODE_NAME_CASE(UNPCKH)
  NODE_NAME_CASE(VBROADCAST)
  NODE_NAME_CASE(VBROADCAST_LOAD)
  NODE_NAME_CASE(VBROADCASTM)
  NODE_NAME_CASE(SUBV_BROADCAST)
  NODE_NAME_CASE(VPERMILPV)
  NODE_NAME_CASE(VPERMILPI)
  NODE_NAME_CASE(VPERM2X128)
  NODE_NAME_CASE(VPERMV)
  NODE_NAME_CASE(VPERMV3)
  NODE_NAME_CASE(VPERMI)
  NODE_NAME_CASE(VPTERNLOG)
  NODE_NAME_CASE(VFIXUPIMM)
  NODE_NAME_CASE(VFIXUPIMM_SAE)
  NODE_NAME_CASE(VFIXUPIMMS)
  NODE_NAME_CASE(VFIXUPIMMS_SAE)
  NODE_NAME_CASE(VRANGE)
  NODE_NAME_CASE(VRANGE_SAE)
  NODE_NAME_CASE(VRANGES)
  NODE_NAME_CASE(VRANGES_SAE)
  NODE_NAME_CASE(PMULUDQ)
  NODE_NAME_CASE(PMULDQ)
  NODE_NAME_CASE(PSADBW)
  NODE_NAME_CASE(DBPSADBW)
  NODE_NAME_CASE(VASTART_SAVE_XMM_REGS)
  NODE_NAME_CASE(VAARG_64)
  NODE_NAME_CASE(WIN_ALLOCA)
  NODE_NAME_CASE(MEMBARRIER)
  NODE_NAME_CASE(MFENCE)
  NODE_NAME_CASE(SEG_ALLOCA)
  NODE_NAME_CASE(PROBED_ALLOCA)
  NODE_NAME_CASE(RDRAND)
  NODE_NAME_CASE(RDSEED)
  NODE_NAME_CASE(RDPKRU)
  NODE_NAME_CASE(WRPKRU)
  NODE_NAME_CASE(VPMADDUBSW)
  NODE_NAME_CASE(VPMADDWD)
  NODE_NAME_CASE(VPSHA)
  NODE_NAME_CASE(VPSHL)
  NODE_NAME_CASE(VPCOM)
  NODE_NAME_CASE(VPCOMU)
  NODE_NAME_CASE(VPERMIL2)
  NODE_NAME_CASE(FMSUB)
  NODE_NAME_CASE(STRICT_FMSUB)
  NODE_NAME_CASE(FNMADD)
  NODE_NAME_CASE(STRICT_FNMADD)
  NODE_NAME_CASE(FNMSUB)
  NODE_NAME_CASE(STRICT_FNMSUB)
  NODE_NAME_CASE(FMADDSUB)
  NODE_NAME_CASE(FMSUBADD)
  NODE_NAME_CASE(FMADD_RND)
  NODE_NAME_CASE(FNMADD_RND)
  NODE_NAME_CASE(FMSUB_RND)
  NODE_NAME_CASE(FNMSUB_RND)
  NODE_NAME_CASE(FMADDSUB_RND)
  NODE_NAME_CASE(FMSUBADD_RND)
  NODE_NAME_CASE(VPMADD52H)
  NODE_NAME_CASE(VPMADD52L)
  NODE_NAME_CASE(VRNDSCALE)
  NODE_NAME_CASE(STRICT_VRNDSCALE)
  NODE_NAME_CASE(VRNDSCALE_SAE)
  NODE_NAME_CASE(VRNDSCALES)
  NODE_NAME_CASE(VRNDSCALES_SAE)
  NODE_NAME_CASE(VREDUCE)
  NODE_NAME_CASE(VREDUCE_SAE)
  NODE_NAME_CASE(VREDUCES)
  NODE_NAME_CASE(VREDUCES_SAE)
  NODE_NAME_CASE(VGETMANT)
  NODE_NAME_CASE(VGETMANT_SAE)
  NODE_NAME_CASE(VGETMANTS)
  NODE_NAME_CASE(VGETMANTS_SAE)
  NODE_NAME_CASE(PCMPESTR)
  NODE_NAME_CASE(PCMPISTR)
  NODE_NAME_CASE(XTEST)
  NODE_NAME_CASE(COMPRESS)
  NODE_NAME_CASE(EXPAND)
  NODE_NAME_CASE(SELECTS)
  NODE_NAME_CASE(ADDSUB)
  NODE_NAME_CASE(RCP14)
  NODE_NAME_CASE(RCP14S)
  NODE_NAME_CASE(RCP28)
  NODE_NAME_CASE(RCP28_SAE)
  NODE_NAME_CASE(RCP28S)
  NODE_NAME_CASE(RCP28S_SAE)
  NODE_NAME_CASE(EXP2)
  NODE_NAME_CASE(EXP2_SAE)
  NODE_NAME_CASE(RSQRT14)
  NODE_NAME_CASE(RSQRT14S)
  NODE_NAME_CASE(RSQRT28)
  NODE_NAME_CASE(RSQRT28_SAE)
  NODE_NAME_CASE(RSQRT28S)
  NODE_NAME_CASE(RSQRT28S_SAE)
  NODE_NAME_CASE(FADD_RND)
  NODE_NAME_CASE(FADDS)
  NODE_NAME_CASE(FADDS_RND)
  NODE_NAME_CASE(FSUB_RND)
  NODE_NAME_CASE(FSUBS)
  NODE_NAME_CASE(FSUBS_RND)
  NODE_NAME_CASE(FMUL_RND)
  NODE_NAME_CASE(FMULS)
  NODE_NAME_CASE(FMULS_RND)
  NODE_NAME_CASE(FDIV_RND)
  NODE_NAME_CASE(FDIVS)
  NODE_NAME_CASE(FDIVS_RND)
  NODE_NAME_CASE(FSQRT_RND)
  NODE_NAME_CASE(FSQRTS)
  NODE_NAME_CASE(FSQRTS_RND)
  NODE_NAME_CASE(FGETEXP)
  NODE_NAME_CASE(FGETEXP_SAE)
  NODE_NAME_CASE(FGETEXPS)
  NODE_NAME_CASE(FGETEXPS_SAE)
  NODE_NAME_CASE(SCALEF)
  NODE_NAME_CASE(SCALEF_RND)
  NODE_NAME_CASE(SCALEFS)
  NODE_NAME_CASE(SCALEFS_RND)
  NODE_NAME_CASE(AVG)
  NODE_NAME_CASE(MULHRS)
  NODE_NAME_CASE(SINT_TO_FP_RND)
  NODE_NAME_CASE(UINT_TO_FP_RND)
  NODE_NAME_CASE(CVTTP2SI)
  NODE_NAME_CASE(CVTTP2UI)
  NODE_NAME_CASE(STRICT_CVTTP2SI)
  NODE_NAME_CASE(STRICT_CVTTP2UI)
  NODE_NAME_CASE(MCVTTP2SI)
  NODE_NAME_CASE(MCVTTP2UI)
  NODE_NAME_CASE(CVTTP2SI_SAE)
  NODE_NAME_CASE(CVTTP2UI_SAE)
  NODE_NAME_CASE(CVTTS2SI)
  NODE_NAME_CASE(CVTTS2UI)
  NODE_NAME_CASE(CVTTS2SI_SAE)
  NODE_NAME_CASE(CVTTS2UI_SAE)
  NODE_NAME_CASE(CVTSI2P)
  NODE_NAME_CASE(CVTUI2P)
  NODE_NAME_CASE(STRICT_CVTSI2P)
  NODE_NAME_CASE(STRICT_CVTUI2P)
  NODE_NAME_CASE(MCVTSI2P)
  NODE_NAME_CASE(MCVTUI2P)
  NODE_NAME_CASE(VFPCLASS)
  NODE_NAME_CASE(VFPCLASSS)
  NODE_NAME_CASE(MULTISHIFT)
  NODE_NAME_CASE(SCALAR_SINT_TO_FP)
  NODE_NAME_CASE(SCALAR_SINT_TO_FP_RND)
  NODE_NAME_CASE(SCALAR_UINT_TO_FP)
  NODE_NAME_CASE(SCALAR_UINT_TO_FP_RND)
  NODE_NAME_CASE(CVTPS2PH)
  NODE_NAME_CASE(STRICT_CVTPS2PH)
  NODE_NAME_CASE(MCVTPS2PH)
  NODE_NAME_CASE(CVTPH2PS)
  NODE_NAME_CASE(STRICT_CVTPH2PS)
  NODE_NAME_CASE(CVTPH2PS_SAE)
  NODE_NAME_CASE(CVTP2SI)
  NODE_NAME_CASE(CVTP2UI)
  NODE_NAME_CASE(MCVTP2SI)
  NODE_NAME_CASE(MCVTP2UI)
  NODE_NAME_CASE(CVTP2SI_RND)
  NODE_NAME_CASE(CVTP2UI_RND)
  NODE_NAME_CASE(CVTS2SI)
  NODE_NAME_CASE(CVTS2UI)
  NODE_NAME_CASE(CVTS2SI_RND)
  NODE_NAME_CASE(CVTS2UI_RND)
  NODE_NAME_CASE(CVTNE2PS2BF16)
  NODE_NAME_CASE(CVTNEPS2BF16)
  NODE_NAME_CASE(MCVTNEPS2BF16)
  NODE_NAME_CASE(DPBF16PS)
  NODE_NAME_CASE(LWPINS)
  NODE_NAME_CASE(MGATHER)
  NODE_NAME_CASE(MSCATTER)
  NODE_NAME_CASE(VPDPBUSD)
  NODE_NAME_CASE(VPDPBUSDS)
  NODE_NAME_CASE(VPDPWSSD)
  NODE_NAME_CASE(VPDPWSSDS)
  NODE_NAME_CASE(VPSHUFBITQMB)
  NODE_NAME_CASE(GF2P8MULB)
  NODE_NAME_CASE(GF2P8AFFINEQB)
  NODE_NAME_CASE(GF2P8AFFINEINVQB)
  NODE_NAME_CASE(NT_CALL)
  NODE_NAME_CASE(NT_BRIND)
  NODE_NAME_CASE(UMWAIT)
  NODE_NAME_CASE(TPAUSE)
  NODE_NAME_CASE(ENQCMD)
  NODE_NAME_CASE(ENQCMDS)
  NODE_NAME_CASE(VP2INTERSECT)
  }
  return nullptr;
#undef NODE_NAME_CASE
}

/// Return true if the addressing mode represented by AM is legal for this
/// target, for a load/store of the specified type.
bool X86TargetLowering::isLegalAddressingMode(const DataLayout &DL,
                                              const AddrMode &AM, Type *Ty,
                                              unsigned AS,
                                              Instruction *I) const {
  // X86 supports extremely general addressing modes.
  CodeModel::Model M = getTargetMachine().getCodeModel();

  // X86 allows a sign-extended 32-bit immediate field as a displacement.
  if (!X86::isOffsetSuitableForCodeModel(AM.BaseOffs, M, AM.BaseGV != nullptr))
    return false;

  if (AM.BaseGV) {
    unsigned GVFlags = Subtarget.classifyGlobalReference(AM.BaseGV);

    // If a reference to this global requires an extra load, we can't fold it.
    if (isGlobalStubReference(GVFlags))
      return false;

    // If BaseGV requires a register for the PIC base, we cannot also have a
    // BaseReg specified.
    if (AM.HasBaseReg && isGlobalRelativeToPICBase(GVFlags))
      return false;

    // If lower 4G is not available, then we must use rip-relative addressing.
    if ((M != CodeModel::Small || isPositionIndependent()) &&
        Subtarget.is64Bit() && (AM.BaseOffs || AM.Scale > 1))
      return false;
  }

  switch (AM.Scale) {
  case 0:
  case 1:
  case 2:
  case 4:
  case 8:
    // These scales always work.
    break;
  case 3:
  case 5:
  case 9:
    // These scales are formed with basereg+scalereg.  Only accept if there is
    // no basereg yet.
    if (AM.HasBaseReg)
      return false;
    break;
  default:  // Other stuff never works.
    return false;
  }

  return true;
}

bool X86TargetLowering::isVectorShiftByScalarCheap(Type *Ty) const {
  unsigned Bits = Ty->getScalarSizeInBits();

  // 8-bit shifts are always expensive, but versions with a scalar amount aren't
  // particularly cheaper than those without.
  if (Bits == 8)
    return false;

  // XOP has v16i8/v8i16/v4i32/v2i64 variable vector shifts.
  if (Subtarget.hasXOP() && Ty->getPrimitiveSizeInBits() == 128 &&
      (Bits == 8 || Bits == 16 || Bits == 32 || Bits == 64))
    return false;

  // AVX2 has vpsllv[dq] instructions (and other shifts) that make variable
  // shifts just as cheap as scalar ones.
  if (Subtarget.hasAVX2() && (Bits == 32 || Bits == 64))
    return false;

  // AVX512BW has shifts such as vpsllvw.
  if (Subtarget.hasBWI() && Bits == 16)
      return false;

  // Otherwise, it's significantly cheaper to shift by a scalar amount than by a
  // fully general vector.
  return true;
}

bool X86TargetLowering::isBinOp(unsigned Opcode) const {
  switch (Opcode) {
  // These are non-commutative binops.
  // TODO: Add more X86ISD opcodes once we have test coverage.
  case X86ISD::ANDNP:
  case X86ISD::PCMPGT:
  case X86ISD::FMAX:
  case X86ISD::FMIN:
  case X86ISD::FANDN:
    return true;
  }

  return TargetLoweringBase::isBinOp(Opcode);
}

bool X86TargetLowering::isCommutativeBinOp(unsigned Opcode) const {
  switch (Opcode) {
  // TODO: Add more X86ISD opcodes once we have test coverage.
  case X86ISD::PCMPEQ:
  case X86ISD::PMULDQ:
  case X86ISD::PMULUDQ:
  case X86ISD::FMAXC:
  case X86ISD::FMINC:
  case X86ISD::FAND:
  case X86ISD::FOR:
  case X86ISD::FXOR:
    return true;
  }

  return TargetLoweringBase::isCommutativeBinOp(Opcode);
}

bool X86TargetLowering::isTruncateFree(Type *Ty1, Type *Ty2) const {
  if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
    return false;
  unsigned NumBits1 = Ty1->getPrimitiveSizeInBits();
  unsigned NumBits2 = Ty2->getPrimitiveSizeInBits();
  return NumBits1 > NumBits2;
}

bool X86TargetLowering::allowTruncateForTailCall(Type *Ty1, Type *Ty2) const {
  if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
    return false;

  if (!isTypeLegal(EVT::getEVT(Ty1)))
    return false;

  assert(Ty1->getPrimitiveSizeInBits() <= 64 && "i128 is probably not a noop");

  // Assuming the caller doesn't have a zeroext or signext return parameter,
  // truncation all the way down to i1 is valid.
  return true;
}

bool X86TargetLowering::isLegalICmpImmediate(int64_t Imm) const {
  return isInt<32>(Imm);
}

bool X86TargetLowering::isLegalAddImmediate(int64_t Imm) const {
  // Can also use sub to handle negated immediates.
  return isInt<32>(Imm);
}

bool X86TargetLowering::isLegalStoreImmediate(int64_t Imm) const {
  return isInt<32>(Imm);
}

bool X86TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
  if (!VT1.isInteger() || !VT2.isInteger())
    return false;
  unsigned NumBits1 = VT1.getSizeInBits();
  unsigned NumBits2 = VT2.getSizeInBits();
  return NumBits1 > NumBits2;
}

bool X86TargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const {
  // x86-64 implicitly zero-extends 32-bit results in 64-bit registers.
  return Ty1->isIntegerTy(32) && Ty2->isIntegerTy(64) && Subtarget.is64Bit();
}

bool X86TargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
  // x86-64 implicitly zero-extends 32-bit results in 64-bit registers.
  return VT1 == MVT::i32 && VT2 == MVT::i64 && Subtarget.is64Bit();
}

bool X86TargetLowering::isZExtFree(SDValue Val, EVT VT2) const {
  EVT VT1 = Val.getValueType();
  if (isZExtFree(VT1, VT2))
    return true;

  if (Val.getOpcode() != ISD::LOAD)
    return false;

  if (!VT1.isSimple() || !VT1.isInteger() ||
      !VT2.isSimple() || !VT2.isInteger())
    return false;

  switch (VT1.getSimpleVT().SimpleTy) {
  default: break;
  case MVT::i8:
  case MVT::i16:
  case MVT::i32:
    // X86 has 8, 16, and 32-bit zero-extending loads.
    return true;
  }

  return false;
}

bool X86TargetLowering::isVectorLoadExtDesirable(SDValue ExtVal) const {
  if (isa<MaskedLoadSDNode>(ExtVal.getOperand(0)))
    return false;

  EVT SrcVT = ExtVal.getOperand(0).getValueType();

  // There is no extending load for vXi1.
  if (SrcVT.getScalarType() == MVT::i1)
    return false;

  return true;
}

bool X86TargetLowering::isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
                                                   EVT VT) const {
  if (!Subtarget.hasAnyFMA())
    return false;

  VT = VT.getScalarType();

  if (!VT.isSimple())
    return false;

  switch (VT.getSimpleVT().SimpleTy) {
  case MVT::f32:
  case MVT::f64:
    return true;
  default:
    break;
  }

  return false;
}

bool X86TargetLowering::isNarrowingProfitable(EVT VT1, EVT VT2) const {
  // i16 instructions are longer (0x66 prefix) and potentially slower.
  return !(VT1 == MVT::i32 && VT2 == MVT::i16);
}

/// Targets can use this to indicate that they only support *some*
/// VECTOR_SHUFFLE operations, those with specific masks.
/// By default, if a target supports the VECTOR_SHUFFLE node, all mask values
/// are assumed to be legal.
bool X86TargetLowering::isShuffleMaskLegal(ArrayRef<int> Mask, EVT VT) const {
  if (!VT.isSimple())
    return false;

  // Not for i1 vectors
  if (VT.getSimpleVT().getScalarType() == MVT::i1)
    return false;

  // Very little shuffling can be done for 64-bit vectors right now.
  if (VT.getSimpleVT().getSizeInBits() == 64)
    return false;

  // We only care that the types being shuffled are legal. The lowering can
  // handle any possible shuffle mask that results.
  return isTypeLegal(VT.getSimpleVT());
}

bool X86TargetLowering::isVectorClearMaskLegal(ArrayRef<int> Mask,
                                               EVT VT) const {
  // Don't convert an 'and' into a shuffle that we don't directly support.
  // vpblendw and vpshufb for 256-bit vectors are not available on AVX1.
  if (!Subtarget.hasAVX2())
    if (VT == MVT::v32i8 || VT == MVT::v16i16)
      return false;

  // Just delegate to the generic legality, clear masks aren't special.
  return isShuffleMaskLegal(Mask, VT);
}

bool X86TargetLowering::areJTsAllowed(const Function *Fn) const {
  // If the subtarget is using thunks, we need to not generate jump tables.
  if (Subtarget.useIndirectThunkBranches())
    return false;

  // Otherwise, fallback on the generic logic.
  return TargetLowering::areJTsAllowed(Fn);
}

//===----------------------------------------------------------------------===//
//                           X86 Scheduler Hooks
//===----------------------------------------------------------------------===//

/// Utility function to emit xbegin specifying the start of an RTM region.
static MachineBasicBlock *emitXBegin(MachineInstr &MI, MachineBasicBlock *MBB,
                                     const TargetInstrInfo *TII) {
  DebugLoc DL = MI.getDebugLoc();

  const BasicBlock *BB = MBB->getBasicBlock();
  MachineFunction::iterator I = ++MBB->getIterator();

  // For the v = xbegin(), we generate
  //
  // thisMBB:
  //  xbegin sinkMBB
  //
  // mainMBB:
  //  s0 = -1
  //
  // fallBB:
  //  eax = # XABORT_DEF
  //  s1 = eax
  //
  // sinkMBB:
  //  v = phi(s0/mainBB, s1/fallBB)

  MachineBasicBlock *thisMBB = MBB;
  MachineFunction *MF = MBB->getParent();
  MachineBasicBlock *mainMBB = MF->CreateMachineBasicBlock(BB);
  MachineBasicBlock *fallMBB = MF->CreateMachineBasicBlock(BB);
  MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(BB);
  MF->insert(I, mainMBB);
  MF->insert(I, fallMBB);
  MF->insert(I, sinkMBB);

  // 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);

  MachineRegisterInfo &MRI = MF->getRegInfo();
  Register DstReg = MI.getOperand(0).getReg();
  const TargetRegisterClass *RC = MRI.getRegClass(DstReg);
  Register mainDstReg = MRI.createVirtualRegister(RC);
  Register fallDstReg = MRI.createVirtualRegister(RC);

  // thisMBB:
  //  xbegin fallMBB
  //  # fallthrough to mainMBB
  //  # abortion to fallMBB
  BuildMI(thisMBB, DL, TII->get(X86::XBEGIN_4)).addMBB(fallMBB);
  thisMBB->addSuccessor(mainMBB);
  thisMBB->addSuccessor(fallMBB);

  // mainMBB:
  //  mainDstReg := -1
  BuildMI(mainMBB, DL, TII->get(X86::MOV32ri), mainDstReg).addImm(-1);
  BuildMI(mainMBB, DL, TII->get(X86::JMP_1)).addMBB(sinkMBB);
  mainMBB->addSuccessor(sinkMBB);

  // fallMBB:
  //  ; pseudo instruction to model hardware's definition from XABORT
  //  EAX := XABORT_DEF
  //  fallDstReg := EAX
  BuildMI(fallMBB, DL, TII->get(X86::XABORT_DEF));
  BuildMI(fallMBB, DL, TII->get(TargetOpcode::COPY), fallDstReg)
      .addReg(X86::EAX);
  fallMBB->addSuccessor(sinkMBB);

  // sinkMBB:
  //  DstReg := phi(mainDstReg/mainBB, fallDstReg/fallBB)
  BuildMI(*sinkMBB, sinkMBB->begin(), DL, TII->get(X86::PHI), DstReg)
      .addReg(mainDstReg).addMBB(mainMBB)
      .addReg(fallDstReg).addMBB(fallMBB);

  MI.eraseFromParent();
  return sinkMBB;
}



MachineBasicBlock *
X86TargetLowering::EmitVAARG64WithCustomInserter(MachineInstr &MI,
                                                 MachineBasicBlock *MBB) const {
  // Emit va_arg instruction on X86-64.

  // Operands to this pseudo-instruction:
  // 0  ) Output        : destination address (reg)
  // 1-5) Input         : va_list address (addr, i64mem)
  // 6  ) ArgSize       : Size (in bytes) of vararg type
  // 7  ) ArgMode       : 0=overflow only, 1=use gp_offset, 2=use fp_offset
  // 8  ) Align         : Alignment of type
  // 9  ) EFLAGS (implicit-def)

  assert(MI.getNumOperands() == 10 && "VAARG_64 should have 10 operands!");
  static_assert(X86::AddrNumOperands == 5,
                "VAARG_64 assumes 5 address operands");

  Register DestReg = MI.getOperand(0).getReg();
  MachineOperand &Base = MI.getOperand(1);
  MachineOperand &Scale = MI.getOperand(2);
  MachineOperand &Index = MI.getOperand(3);
  MachineOperand &Disp = MI.getOperand(4);
  MachineOperand &Segment = MI.getOperand(5);
  unsigned ArgSize = MI.getOperand(6).getImm();
  unsigned ArgMode = MI.getOperand(7).getImm();
  unsigned Align = MI.getOperand(8).getImm();

  MachineFunction *MF = MBB->getParent();

  // Memory Reference
  assert(MI.hasOneMemOperand() && "Expected VAARG_64 to have one memoperand");

  MachineMemOperand *OldMMO = MI.memoperands().front();

  // Clone the MMO into two separate MMOs for loading and storing
  MachineMemOperand *LoadOnlyMMO = MF->getMachineMemOperand(
      OldMMO, OldMMO->getFlags() & ~MachineMemOperand::MOStore);
  MachineMemOperand *StoreOnlyMMO = MF->getMachineMemOperand(
      OldMMO, OldMMO->getFlags() & ~MachineMemOperand::MOLoad);

  // Machine Information
  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
  MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
  const TargetRegisterClass *AddrRegClass = getRegClassFor(MVT::i64);
  const TargetRegisterClass *OffsetRegClass = getRegClassFor(MVT::i32);
  DebugLoc DL = MI.getDebugLoc();

  // struct va_list {
  //   i32   gp_offset
  //   i32   fp_offset
  //   i64   overflow_area (address)
  //   i64   reg_save_area (address)
  // }
  // sizeof(va_list) = 24
  // alignment(va_list) = 8

  unsigned TotalNumIntRegs = 6;
  unsigned TotalNumXMMRegs = 8;
  bool UseGPOffset = (ArgMode == 1);
  bool UseFPOffset = (ArgMode == 2);
  unsigned MaxOffset = TotalNumIntRegs * 8 +
                       (UseFPOffset ? TotalNumXMMRegs * 16 : 0);

  /* Align ArgSize to a multiple of 8 */
  unsigned ArgSizeA8 = (ArgSize + 7) & ~7;
  bool NeedsAlign = (Align > 8);

  MachineBasicBlock *thisMBB = MBB;
  MachineBasicBlock *overflowMBB;
  MachineBasicBlock *offsetMBB;
  MachineBasicBlock *endMBB;

  unsigned OffsetDestReg = 0;    // Argument address computed by offsetMBB
  unsigned OverflowDestReg = 0;  // Argument address computed by overflowMBB
  unsigned OffsetReg = 0;

  if (!UseGPOffset && !UseFPOffset) {
    // If we only pull from the overflow region, we don't create a branch.
    // We don't need to alter control flow.
    OffsetDestReg = 0; // unused
    OverflowDestReg = DestReg;

    offsetMBB = nullptr;
    overflowMBB = thisMBB;
    endMBB = thisMBB;
  } else {
    // First emit code to check if gp_offset (or fp_offset) is below the bound.
    // If so, pull the argument from reg_save_area. (branch to offsetMBB)
    // If not, pull from overflow_area. (branch to overflowMBB)
    //
    //       thisMBB
    //         |     .
    //         |        .
    //     offsetMBB   overflowMBB
    //         |        .
    //         |     .
    //        endMBB

    // Registers for the PHI in endMBB
    OffsetDestReg = MRI.createVirtualRegister(AddrRegClass);
    OverflowDestReg = MRI.createVirtualRegister(AddrRegClass);

    const BasicBlock *LLVM_BB = MBB->getBasicBlock();
    overflowMBB = MF->CreateMachineBasicBlock(LLVM_BB);
    offsetMBB = MF->CreateMachineBasicBlock(LLVM_BB);
    endMBB = MF->CreateMachineBasicBlock(LLVM_BB);

    MachineFunction::iterator MBBIter = ++MBB->getIterator();

    // Insert the new basic blocks
    MF->insert(MBBIter, offsetMBB);
    MF->insert(MBBIter, overflowMBB);
    MF->insert(MBBIter, endMBB);

    // Transfer the remainder of MBB and its successor edges to endMBB.
    endMBB->splice(endMBB->begin(), thisMBB,
                   std::next(MachineBasicBlock::iterator(MI)), thisMBB->end());
    endMBB->transferSuccessorsAndUpdatePHIs(thisMBB);

    // Make offsetMBB and overflowMBB successors of thisMBB
    thisMBB->addSuccessor(offsetMBB);
    thisMBB->addSuccessor(overflowMBB);

    // endMBB is a successor of both offsetMBB and overflowMBB
    offsetMBB->addSuccessor(endMBB);
    overflowMBB->addSuccessor(endMBB);

    // Load the offset value into a register
    OffsetReg = MRI.createVirtualRegister(OffsetRegClass);
    BuildMI(thisMBB, DL, TII->get(X86::MOV32rm), OffsetReg)
        .add(Base)
        .add(Scale)
        .add(Index)
        .addDisp(Disp, UseFPOffset ? 4 : 0)
        .add(Segment)
        .setMemRefs(LoadOnlyMMO);

    // Check if there is enough room left to pull this argument.
    BuildMI(thisMBB, DL, TII->get(X86::CMP32ri))
      .addReg(OffsetReg)
      .addImm(MaxOffset + 8 - ArgSizeA8);

    // Branch to "overflowMBB" if offset >= max
    // Fall through to "offsetMBB" otherwise
    BuildMI(thisMBB, DL, TII->get(X86::JCC_1))
      .addMBB(overflowMBB).addImm(X86::COND_AE);
  }

  // In offsetMBB, emit code to use the reg_save_area.
  if (offsetMBB) {
    assert(OffsetReg != 0);

    // Read the reg_save_area address.
    Register RegSaveReg = MRI.createVirtualRegister(AddrRegClass);
    BuildMI(offsetMBB, DL, TII->get(X86::MOV64rm), RegSaveReg)
        .add(Base)
        .add(Scale)
        .add(Index)
        .addDisp(Disp, 16)
        .add(Segment)
        .setMemRefs(LoadOnlyMMO);

    // Zero-extend the offset
    Register OffsetReg64 = MRI.createVirtualRegister(AddrRegClass);
    BuildMI(offsetMBB, DL, TII->get(X86::SUBREG_TO_REG), OffsetReg64)
        .addImm(0)
        .addReg(OffsetReg)
        .addImm(X86::sub_32bit);

    // Add the offset to the reg_save_area to get the final address.
    BuildMI(offsetMBB, DL, TII->get(X86::ADD64rr), OffsetDestReg)
      .addReg(OffsetReg64)
      .addReg(RegSaveReg);

    // Compute the offset for the next argument
    Register NextOffsetReg = MRI.createVirtualRegister(OffsetRegClass);
    BuildMI(offsetMBB, DL, TII->get(X86::ADD32ri), NextOffsetReg)
      .addReg(OffsetReg)
      .addImm(UseFPOffset ? 16 : 8);

    // Store it back into the va_list.
    BuildMI(offsetMBB, DL, TII->get(X86::MOV32mr))
        .add(Base)
        .add(Scale)
        .add(Index)
        .addDisp(Disp, UseFPOffset ? 4 : 0)
        .add(Segment)
        .addReg(NextOffsetReg)
        .setMemRefs(StoreOnlyMMO);

    // Jump to endMBB
    BuildMI(offsetMBB, DL, TII->get(X86::JMP_1))
      .addMBB(endMBB);
  }

  //
  // Emit code to use overflow area
  //

  // Load the overflow_area address into a register.
  Register OverflowAddrReg = MRI.createVirtualRegister(AddrRegClass);
  BuildMI(overflowMBB, DL, TII->get(X86::MOV64rm), OverflowAddrReg)
      .add(Base)
      .add(Scale)
      .add(Index)
      .addDisp(Disp, 8)
      .add(Segment)
      .setMemRefs(LoadOnlyMMO);

  // If we need to align it, do so. Otherwise, just copy the address
  // to OverflowDestReg.
  if (NeedsAlign) {
    // Align the overflow address
    assert(isPowerOf2_32(Align) && "Alignment must be a power of 2");
    Register TmpReg = MRI.createVirtualRegister(AddrRegClass);

    // aligned_addr = (addr + (align-1)) & ~(align-1)
    BuildMI(overflowMBB, DL, TII->get(X86::ADD64ri32), TmpReg)
      .addReg(OverflowAddrReg)
      .addImm(Align-1);

    BuildMI(overflowMBB, DL, TII->get(X86::AND64ri32), OverflowDestReg)
      .addReg(TmpReg)
      .addImm(~(uint64_t)(Align-1));
  } else {
    BuildMI(overflowMBB, DL, TII->get(TargetOpcode::COPY), OverflowDestReg)
      .addReg(OverflowAddrReg);
  }

  // Compute the next overflow address after this argument.
  // (the overflow address should be kept 8-byte aligned)
  Register NextAddrReg = MRI.createVirtualRegister(AddrRegClass);
  BuildMI(overflowMBB, DL, TII->get(X86::ADD64ri32), NextAddrReg)
    .addReg(OverflowDestReg)
    .addImm(ArgSizeA8);

  // Store the new overflow address.
  BuildMI(overflowMBB, DL, TII->get(X86::MOV64mr))
      .add(Base)
      .add(Scale)
      .add(Index)
      .addDisp(Disp, 8)
      .add(Segment)
      .addReg(NextAddrReg)
      .setMemRefs(StoreOnlyMMO);

  // If we branched, emit the PHI to the front of endMBB.
  if (offsetMBB) {
    BuildMI(*endMBB, endMBB->begin(), DL,
            TII->get(X86::PHI), DestReg)
      .addReg(OffsetDestReg).addMBB(offsetMBB)
      .addReg(OverflowDestReg).addMBB(overflowMBB);
  }

  // Erase the pseudo instruction
  MI.eraseFromParent();

  return endMBB;
}

MachineBasicBlock *X86TargetLowering::EmitVAStartSaveXMMRegsWithCustomInserter(
    MachineInstr &MI, MachineBasicBlock *MBB) const {
  // Emit code to save XMM registers to the stack. The ABI says that the
  // number of registers to save is given in %al, so it's theoretically
  // possible to do an indirect jump trick to avoid saving all of them,
  // however this code takes a simpler approach and just executes all
  // of the stores if %al is non-zero. It's less code, and it's probably
  // easier on the hardware branch predictor, and stores aren't all that
  // expensive anyway.

  // Create the new basic blocks. One block contains all the XMM stores,
  // and one block is the final destination regardless of whether any
  // stores were performed.
  const BasicBlock *LLVM_BB = MBB->getBasicBlock();
  MachineFunction *F = MBB->getParent();
  MachineFunction::iterator MBBIter = ++MBB->getIterator();
  MachineBasicBlock *XMMSaveMBB = F->CreateMachineBasicBlock(LLVM_BB);
  MachineBasicBlock *EndMBB = F->CreateMachineBasicBlock(LLVM_BB);
  F->insert(MBBIter, XMMSaveMBB);
  F->insert(MBBIter, EndMBB);

  // Transfer the remainder of MBB and its successor edges to EndMBB.
  EndMBB->splice(EndMBB->begin(), MBB,
                 std::next(MachineBasicBlock::iterator(MI)), MBB->end());
  EndMBB->transferSuccessorsAndUpdatePHIs(MBB);

  // The original block will now fall through to the XMM save block.
  MBB->addSuccessor(XMMSaveMBB);
  // The XMMSaveMBB will fall through to the end block.
  XMMSaveMBB->addSuccessor(EndMBB);

  // Now add the instructions.
  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
  DebugLoc DL = MI.getDebugLoc();

  Register CountReg = MI.getOperand(0).getReg();
  int64_t RegSaveFrameIndex = MI.getOperand(1).getImm();
  int64_t VarArgsFPOffset = MI.getOperand(2).getImm();

  if (!Subtarget.isCallingConvWin64(F->getFunction().getCallingConv())) {
    // If %al is 0, branch around the XMM save block.
    BuildMI(MBB, DL, TII->get(X86::TEST8rr)).addReg(CountReg).addReg(CountReg);
    BuildMI(MBB, DL, TII->get(X86::JCC_1)).addMBB(EndMBB).addImm(X86::COND_E);
    MBB->addSuccessor(EndMBB);
  }

  // Make sure the last operand is EFLAGS, which gets clobbered by the branch
  // that was just emitted, but clearly shouldn't be "saved".
  assert((MI.getNumOperands() <= 3 ||
          !MI.getOperand(MI.getNumOperands() - 1).isReg() ||
          MI.getOperand(MI.getNumOperands() - 1).getReg() == X86::EFLAGS) &&
         "Expected last argument to be EFLAGS");
  unsigned MOVOpc = Subtarget.hasAVX() ? X86::VMOVAPSmr : X86::MOVAPSmr;
  // In the XMM save block, save all the XMM argument registers.
  for (int i = 3, e = MI.getNumOperands() - 1; i != e; ++i) {
    int64_t Offset = (i - 3) * 16 + VarArgsFPOffset;
    MachineMemOperand *MMO = F->getMachineMemOperand(
        MachinePointerInfo::getFixedStack(*F, RegSaveFrameIndex, Offset),
        MachineMemOperand::MOStore,
        /*Size=*/16, Align(16));
    BuildMI(XMMSaveMBB, DL, TII->get(MOVOpc))
        .addFrameIndex(RegSaveFrameIndex)
        .addImm(/*Scale=*/1)
        .addReg(/*IndexReg=*/0)
        .addImm(/*Disp=*/Offset)
        .addReg(/*Segment=*/0)
        .addReg(MI.getOperand(i).getReg())
        .addMemOperand(MMO);
  }

  MI.eraseFromParent(); // The pseudo instruction is gone now.

  return EndMBB;
}

// The EFLAGS operand of SelectItr might be missing a kill marker
// because there were multiple uses of EFLAGS, and ISel didn't know
// which to mark. Figure out whether SelectItr should have had a
// kill marker, and set it if it should. Returns the correct kill
// marker value.
static bool checkAndUpdateEFLAGSKill(MachineBasicBlock::iterator SelectItr,
                                     MachineBasicBlock* BB,
                                     const TargetRegisterInfo* TRI) {
  // Scan forward through BB for a use/def of EFLAGS.
  MachineBasicBlock::iterator miI(std::next(SelectItr));
  for (MachineBasicBlock::iterator miE = BB->end(); miI != miE; ++miI) {
    const MachineInstr& mi = *miI;
    if (mi.readsRegister(X86::EFLAGS))
      return false;
    if (mi.definesRegister(X86::EFLAGS))
      break; // Should have kill-flag - update below.
  }

  // If we hit the end of the block, check whether EFLAGS is live into a
  // successor.
  if (miI == BB->end()) {
    for (MachineBasicBlock::succ_iterator sItr = BB->succ_begin(),
                                          sEnd = BB->succ_end();
         sItr != sEnd; ++sItr) {
      MachineBasicBlock* succ = *sItr;
      if (succ->isLiveIn(X86::EFLAGS))
        return false;
    }
  }

  // We found a def, or hit the end of the basic block and EFLAGS wasn't live
  // out. SelectMI should have a kill flag on EFLAGS.
  SelectItr->addRegisterKilled(X86::EFLAGS, TRI);
  return true;
}

// Return true if it is OK for this CMOV pseudo-opcode to be cascaded
// together with other CMOV pseudo-opcodes into a single basic-block with
// conditional jump around it.
static bool isCMOVPseudo(MachineInstr &MI) {
  switch (MI.getOpcode()) {
  case X86::CMOV_FR32:
  case X86::CMOV_FR32X:
  case X86::CMOV_FR64:
  case X86::CMOV_FR64X:
  case X86::CMOV_GR8:
  case X86::CMOV_GR16:
  case X86::CMOV_GR32:
  case X86::CMOV_RFP32:
  case X86::CMOV_RFP64:
  case X86::CMOV_RFP80:
  case X86::CMOV_VR64:
  case X86::CMOV_VR128:
  case X86::CMOV_VR128X:
  case X86::CMOV_VR256:
  case X86::CMOV_VR256X:
  case X86::CMOV_VR512:
  case X86::CMOV_VK1:
  case X86::CMOV_VK2:
  case X86::CMOV_VK4:
  case X86::CMOV_VK8:
  case X86::CMOV_VK16:
  case X86::CMOV_VK32:
  case X86::CMOV_VK64:
    return true;

  default:
    return false;
  }
}

// Helper function, which inserts PHI functions into SinkMBB:
//   %Result(i) = phi [ %FalseValue(i), FalseMBB ], [ %TrueValue(i), TrueMBB ],
// where %FalseValue(i) and %TrueValue(i) are taken from the consequent CMOVs
// in [MIItBegin, MIItEnd) range. It returns the last MachineInstrBuilder for
// the last PHI function inserted.
static MachineInstrBuilder createPHIsForCMOVsInSinkBB(
    MachineBasicBlock::iterator MIItBegin, MachineBasicBlock::iterator MIItEnd,
    MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB,
    MachineBasicBlock *SinkMBB) {
  MachineFunction *MF = TrueMBB->getParent();
  const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
  DebugLoc DL = MIItBegin->getDebugLoc();

  X86::CondCode CC = X86::CondCode(MIItBegin->getOperand(3).getImm());
  X86::CondCode OppCC = X86::GetOppositeBranchCondition(CC);

  MachineBasicBlock::iterator SinkInsertionPoint = SinkMBB->begin();

  // As we are creating the PHIs, we have to be careful if there is more than
  // one.  Later CMOVs may reference the results of earlier CMOVs, but later
  // PHIs have to reference the individual true/false inputs from earlier PHIs.
  // That also means that PHI construction must work forward from earlier to
  // later, and that the code must maintain a mapping from earlier PHI's
  // destination registers, and the registers that went into the PHI.
  DenseMap<unsigned, std::pair<unsigned, unsigned>> RegRewriteTable;
  MachineInstrBuilder MIB;

  for (MachineBasicBlock::iterator MIIt = MIItBegin; MIIt != MIItEnd; ++MIIt) {
    Register DestReg = MIIt->getOperand(0).getReg();
    Register Op1Reg = MIIt->getOperand(1).getReg();
    Register Op2Reg = MIIt->getOperand(2).getReg();

    // If this CMOV we are generating is the opposite condition from
    // the jump we generated, then we have to swap the operands for the
    // PHI that is going to be generated.
    if (MIIt->getOperand(3).getImm() == OppCC)
      std::swap(Op1Reg, Op2Reg);

    if (RegRewriteTable.find(Op1Reg) != RegRewriteTable.end())
      Op1Reg = RegRewriteTable[Op1Reg].first;

    if (RegRewriteTable.find(Op2Reg) != RegRewriteTable.end())
      Op2Reg = RegRewriteTable[Op2Reg].second;

    MIB = BuildMI(*SinkMBB, SinkInsertionPoint, DL, TII->get(X86::PHI), DestReg)
              .addReg(Op1Reg)
              .addMBB(FalseMBB)
              .addReg(Op2Reg)
              .addMBB(TrueMBB);

    // Add this PHI to the rewrite table.
    RegRewriteTable[DestReg] = std::make_pair(Op1Reg, Op2Reg);
  }

  return MIB;
}

// Lower cascaded selects in form of (SecondCmov (FirstCMOV F, T, cc1), T, cc2).
MachineBasicBlock *
X86TargetLowering::EmitLoweredCascadedSelect(MachineInstr &FirstCMOV,
                                             MachineInstr &SecondCascadedCMOV,
                                             MachineBasicBlock *ThisMBB) const {
  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
  DebugLoc DL = FirstCMOV.getDebugLoc();

  // We lower cascaded CMOVs such as
  //
  //   (SecondCascadedCMOV (FirstCMOV F, T, cc1), T, cc2)
  //
  // to two successive branches.
  //
  // Without this, we would add a PHI between the two jumps, which ends up
  // creating a few copies all around. For instance, for
  //
  //    (sitofp (zext (fcmp une)))
  //
  // we would generate:
  //
  //         ucomiss %xmm1, %xmm0
  //         movss  <1.0f>, %xmm0
  //         movaps  %xmm0, %xmm1
  //         jne     .LBB5_2
  //         xorps   %xmm1, %xmm1
  // .LBB5_2:
  //         jp      .LBB5_4
  //         movaps  %xmm1, %xmm0
  // .LBB5_4:
  //         retq
  //
  // because this custom-inserter would have generated:
  //
  //   A
  //   | \
  //   |  B
  //   | /
  //   C
  //   | \
  //   |  D
  //   | /
  //   E
  //
  // A: X = ...; Y = ...
  // B: empty
  // C: Z = PHI [X, A], [Y, B]
  // D: empty
  // E: PHI [X, C], [Z, D]
  //
  // If we lower both CMOVs in a single step, we can instead generate:
  //
  //   A
  //   | \
  //   |  C
  //   | /|
  //   |/ |
  //   |  |
  //   |  D
  //   | /
  //   E
  //
  // A: X = ...; Y = ...
  // D: empty
  // E: PHI [X, A], [X, C], [Y, D]
  //
  // Which, in our sitofp/fcmp example, gives us something like:
  //
  //         ucomiss %xmm1, %xmm0
  //         movss  <1.0f>, %xmm0
  //         jne     .LBB5_4
  //         jp      .LBB5_4
  //         xorps   %xmm0, %xmm0
  // .LBB5_4:
  //         retq
  //

  // We lower cascaded CMOV into two successive branches to the same block.
  // EFLAGS is used by both, so mark it as live in the second.
  const BasicBlock *LLVM_BB = ThisMBB->getBasicBlock();
  MachineFunction *F = ThisMBB->getParent();
  MachineBasicBlock *FirstInsertedMBB = F->CreateMachineBasicBlock(LLVM_BB);
  MachineBasicBlock *SecondInsertedMBB = F->CreateMachineBasicBlock(LLVM_BB);
  MachineBasicBlock *SinkMBB = F->CreateMachineBasicBlock(LLVM_BB);

  MachineFunction::iterator It = ++ThisMBB->getIterator();
  F->insert(It, FirstInsertedMBB);
  F->insert(It, SecondInsertedMBB);
  F->insert(It, SinkMBB);

  // For a cascaded CMOV, we lower it to two successive branches to
  // the same block (SinkMBB).  EFLAGS is used by both, so mark it as live in
  // the FirstInsertedMBB.
  FirstInsertedMBB->addLiveIn(X86::EFLAGS);

  // If the EFLAGS register isn't dead in the terminator, then claim that it's
  // live into the sink and copy blocks.
  const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
  if (!SecondCascadedCMOV.killsRegister(X86::EFLAGS) &&
      !checkAndUpdateEFLAGSKill(SecondCascadedCMOV, ThisMBB, TRI)) {
    SecondInsertedMBB->addLiveIn(X86::EFLAGS);
    SinkMBB->addLiveIn(X86::EFLAGS);
  }

  // Transfer the remainder of ThisMBB and its successor edges to SinkMBB.
  SinkMBB->splice(SinkMBB->begin(), ThisMBB,
                  std::next(MachineBasicBlock::iterator(FirstCMOV)),
                  ThisMBB->end());
  SinkMBB->transferSuccessorsAndUpdatePHIs(ThisMBB);

  // Fallthrough block for ThisMBB.
  ThisMBB->addSuccessor(FirstInsertedMBB);
  // The true block target of the first branch is always SinkMBB.
  ThisMBB->addSuccessor(SinkMBB);
  // Fallthrough block for FirstInsertedMBB.
  FirstInsertedMBB->addSuccessor(SecondInsertedMBB);
  // The true block for the branch of FirstInsertedMBB.
  FirstInsertedMBB->addSuccessor(SinkMBB);
  // This is fallthrough.
  SecondInsertedMBB->addSuccessor(SinkMBB);

  // Create the conditional branch instructions.
  X86::CondCode FirstCC = X86::CondCode(FirstCMOV.getOperand(3).getImm());
  BuildMI(ThisMBB, DL, TII->get(X86::JCC_1)).addMBB(SinkMBB).addImm(FirstCC);

  X86::CondCode SecondCC =
      X86::CondCode(SecondCascadedCMOV.getOperand(3).getImm());
  BuildMI(FirstInsertedMBB, DL, TII->get(X86::JCC_1)).addMBB(SinkMBB).addImm(SecondCC);

  //  SinkMBB:
  //   %Result = phi [ %FalseValue, SecondInsertedMBB ], [ %TrueValue, ThisMBB ]
  Register DestReg = FirstCMOV.getOperand(0).getReg();
  Register Op1Reg = FirstCMOV.getOperand(1).getReg();
  Register Op2Reg = FirstCMOV.getOperand(2).getReg();
  MachineInstrBuilder MIB =
      BuildMI(*SinkMBB, SinkMBB->begin(), DL, TII->get(X86::PHI), DestReg)
          .addReg(Op1Reg)
          .addMBB(SecondInsertedMBB)
          .addReg(Op2Reg)
          .addMBB(ThisMBB);

  // The second SecondInsertedMBB provides the same incoming value as the
  // FirstInsertedMBB (the True operand of the SELECT_CC/CMOV nodes).
  MIB.addReg(FirstCMOV.getOperand(2).getReg()).addMBB(FirstInsertedMBB);
  // Copy the PHI result to the register defined by the second CMOV.
  BuildMI(*SinkMBB, std::next(MachineBasicBlock::iterator(MIB.getInstr())), DL,
          TII->get(TargetOpcode::COPY),
          SecondCascadedCMOV.getOperand(0).getReg())
      .addReg(FirstCMOV.getOperand(0).getReg());

  // Now remove the CMOVs.
  FirstCMOV.eraseFromParent();
  SecondCascadedCMOV.eraseFromParent();

  return SinkMBB;
}

MachineBasicBlock *
X86TargetLowering::EmitLoweredSelect(MachineInstr &MI,
                                     MachineBasicBlock *ThisMBB) const {
  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
  DebugLoc DL = MI.getDebugLoc();

  // To "insert" a SELECT_CC instruction, we actually have to insert the
  // diamond control-flow pattern.  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 copy1MBB
  //   fallthrough --> FalseMBB

  // This code lowers all pseudo-CMOV instructions. Generally it lowers these
  // as described above, by inserting a BB, and then making a PHI at the join
  // point to select the true and false operands of the CMOV in the PHI.
  //
  // The code also handles two different cases of multiple CMOV opcodes
  // in a row.
  //
  // Case 1:
  // In this case, there are multiple CMOVs in a row, all which are based on
  // the same condition setting (or the exact opposite condition setting).
  // In this case we can lower all the CMOVs using a single inserted BB, and
  // then make a number of PHIs at the join point to model the CMOVs. The only
  // trickiness here, is that in a case like:
  //
  // t2 = CMOV cond1 t1, f1
  // t3 = CMOV cond1 t2, f2
  //
  // when rewriting this into PHIs, we have to perform some renaming on the
  // temps since you cannot have a PHI operand refer to a PHI result earlier
  // in the same block.  The "simple" but wrong lowering would be:
  //
  // t2 = PHI t1(BB1), f1(BB2)
  // t3 = PHI t2(BB1), f2(BB2)
  //
  // but clearly t2 is not defined in BB1, so that is incorrect. The proper
  // renaming is to note that on the path through BB1, t2 is really just a
  // copy of t1, and do that renaming, properly generating:
  //
  // t2 = PHI t1(BB1), f1(BB2)
  // t3 = PHI t1(BB1), f2(BB2)
  //
  // Case 2:
  // CMOV ((CMOV F, T, cc1), T, cc2) is checked here and handled by a separate
  // function - EmitLoweredCascadedSelect.

  X86::CondCode CC = X86::CondCode(MI.getOperand(3).getImm());
  X86::CondCode OppCC = X86::GetOppositeBranchCondition(CC);
  MachineInstr *LastCMOV = &MI;
  MachineBasicBlock::iterator NextMIIt = MachineBasicBlock::iterator(MI);

  // Check for case 1, where there are multiple CMOVs with the same condition
  // first.  Of the two cases of multiple CMOV lowerings, case 1 reduces the
  // number of jumps the most.

  if (isCMOVPseudo(MI)) {
    // See if we have a string of CMOVS with the same condition. Skip over
    // intervening debug insts.
    while (NextMIIt != ThisMBB->end() && isCMOVPseudo(*NextMIIt) &&
           (NextMIIt->getOperand(3).getImm() == CC ||
            NextMIIt->getOperand(3).getImm() == OppCC)) {
      LastCMOV = &*NextMIIt;
      ++NextMIIt;
      NextMIIt = skipDebugInstructionsForward(NextMIIt, ThisMBB->end());
    }
  }

  // This checks for case 2, but only do this if we didn't already find
  // case 1, as indicated by LastCMOV == MI.
  if (LastCMOV == &MI && NextMIIt != ThisMBB->end() &&
      NextMIIt->getOpcode() == MI.getOpcode() &&
      NextMIIt->getOperand(2).getReg() == MI.getOperand(2).getReg() &&
      NextMIIt->getOperand(1).getReg() == MI.getOperand(0).getReg() &&
      NextMIIt->getOperand(1).isKill()) {
    return EmitLoweredCascadedSelect(MI, *NextMIIt, ThisMBB);
  }

  const BasicBlock *LLVM_BB = ThisMBB->getBasicBlock();
  MachineFunction *F = ThisMBB->getParent();
  MachineBasicBlock *FalseMBB = F->CreateMachineBasicBlock(LLVM_BB);
  MachineBasicBlock *SinkMBB = F->CreateMachineBasicBlock(LLVM_BB);

  MachineFunction::iterator It = ++ThisMBB->getIterator();
  F->insert(It, FalseMBB);
  F->insert(It, SinkMBB);

  // If the EFLAGS register isn't dead in the terminator, then claim that it's
  // live into the sink and copy blocks.
  const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
  if (!LastCMOV->killsRegister(X86::EFLAGS) &&
      !checkAndUpdateEFLAGSKill(LastCMOV, ThisMBB, TRI)) {
    FalseMBB->addLiveIn(X86::EFLAGS);
    SinkMBB->addLiveIn(X86::EFLAGS);
  }

  // Transfer any debug instructions inside the CMOV sequence to the sunk block.
  auto DbgEnd = MachineBasicBlock::iterator(LastCMOV);
  auto DbgIt = MachineBasicBlock::iterator(MI);
  while (DbgIt != DbgEnd) {
    auto Next = std::next(DbgIt);
    if (DbgIt->isDebugInstr())
      SinkMBB->push_back(DbgIt->removeFromParent());
    DbgIt = Next;
  }

  // Transfer the remainder of ThisMBB and its successor edges to SinkMBB.
  SinkMBB->splice(SinkMBB->end(), ThisMBB,
                  std::next(MachineBasicBlock::iterator(LastCMOV)),
                  ThisMBB->end());
  SinkMBB->transferSuccessorsAndUpdatePHIs(ThisMBB);

  // Fallthrough block for ThisMBB.
  ThisMBB->addSuccessor(FalseMBB);
  // The true block target of the first (or only) branch is always a SinkMBB.
  ThisMBB->addSuccessor(SinkMBB);
  // Fallthrough block for FalseMBB.
  FalseMBB->addSuccessor(SinkMBB);

  // Create the conditional branch instruction.
  BuildMI(ThisMBB, DL, TII->get(X86::JCC_1)).addMBB(SinkMBB).addImm(CC);

  //  SinkMBB:
  //   %Result = phi [ %FalseValue, FalseMBB ], [ %TrueValue, ThisMBB ]
  //  ...
  MachineBasicBlock::iterator MIItBegin = MachineBasicBlock::iterator(MI);
  MachineBasicBlock::iterator MIItEnd =
      std::next(MachineBasicBlock::iterator(LastCMOV));
  createPHIsForCMOVsInSinkBB(MIItBegin, MIItEnd, ThisMBB, FalseMBB, SinkMBB);

  // Now remove the CMOV(s).
  ThisMBB->erase(MIItBegin, MIItEnd);

  return SinkMBB;
}

MachineBasicBlock *
X86TargetLowering::EmitLoweredProbedAlloca(MachineInstr &MI,
                                           MachineBasicBlock *BB) const {
  MachineFunction *MF = BB->getParent();
  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
  const X86FrameLowering &TFI = *Subtarget.getFrameLowering();
  DebugLoc DL = MI.getDebugLoc();
  const BasicBlock *LLVM_BB = BB->getBasicBlock();

  const unsigned ProbeSize = getStackProbeSize(*MF);

  MachineRegisterInfo &MRI = MF->getRegInfo();
  MachineBasicBlock *testMBB = MF->CreateMachineBasicBlock(LLVM_BB);
  MachineBasicBlock *tailMBB = MF->CreateMachineBasicBlock(LLVM_BB);
  MachineBasicBlock *blockMBB = MF->CreateMachineBasicBlock(LLVM_BB);

  MachineFunction::iterator MBBIter = ++BB->getIterator();
  MF->insert(MBBIter, testMBB);
  MF->insert(MBBIter, blockMBB);
  MF->insert(MBBIter, tailMBB);

  unsigned sizeVReg = MI.getOperand(1).getReg();

  const TargetRegisterClass *SizeRegClass = MRI.getRegClass(sizeVReg);

  unsigned tmpSizeVReg = MRI.createVirtualRegister(SizeRegClass);
  unsigned tmpSizeVReg2 = MRI.createVirtualRegister(SizeRegClass);

  unsigned physSPReg = TFI.Uses64BitFramePtr ? X86::RSP : X86::ESP;

  // test rsp size
  BuildMI(testMBB, DL, TII->get(X86::PHI), tmpSizeVReg)
      .addReg(sizeVReg)
      .addMBB(BB)
      .addReg(tmpSizeVReg2)
      .addMBB(blockMBB);

  BuildMI(testMBB, DL,
          TII->get(TFI.Uses64BitFramePtr ? X86::CMP64ri32 : X86::CMP32ri))
      .addReg(tmpSizeVReg)
      .addImm(ProbeSize);

  BuildMI(testMBB, DL, TII->get(X86::JCC_1))
      .addMBB(tailMBB)
      .addImm(X86::COND_L);
  testMBB->addSuccessor(blockMBB);
  testMBB->addSuccessor(tailMBB);

  // allocate a block and touch it

  BuildMI(blockMBB, DL,
          TII->get(TFI.Uses64BitFramePtr ? X86::SUB64ri32 : X86::SUB32ri),
          tmpSizeVReg2)
      .addReg(tmpSizeVReg)
      .addImm(ProbeSize);

  BuildMI(blockMBB, DL,
          TII->get(TFI.Uses64BitFramePtr ? X86::SUB64ri32 : X86::SUB32ri),
          physSPReg)
      .addReg(physSPReg)
      .addImm(ProbeSize);

  const unsigned MovMIOpc =
      TFI.Uses64BitFramePtr ? X86::MOV64mi32 : X86::MOV32mi;
  addRegOffset(BuildMI(blockMBB, DL, TII->get(MovMIOpc)), physSPReg, false, 0)
      .addImm(0);

  BuildMI(blockMBB, DL, TII->get(X86::JMP_1)).addMBB(testMBB);
  blockMBB->addSuccessor(testMBB);

  // allocate the tail and continue
  BuildMI(tailMBB, DL,
          TII->get(TFI.Uses64BitFramePtr ? X86::SUB64rr : X86::SUB32rr),
          physSPReg)
      .addReg(physSPReg)
      .addReg(tmpSizeVReg);
  BuildMI(tailMBB, DL, TII->get(TargetOpcode::COPY), MI.getOperand(0).getReg())
      .addReg(physSPReg);

  tailMBB->splice(tailMBB->end(), BB,
                  std::next(MachineBasicBlock::iterator(MI)), BB->end());
  tailMBB->transferSuccessorsAndUpdatePHIs(BB);
  BB->addSuccessor(testMBB);

  // Delete the original pseudo instruction.
  MI.eraseFromParent();

  // And we're done.
  return tailMBB;
}

MachineBasicBlock *
X86TargetLowering::EmitLoweredSegAlloca(MachineInstr &MI,
                                        MachineBasicBlock *BB) const {
  MachineFunction *MF = BB->getParent();
  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
  DebugLoc DL = MI.getDebugLoc();
  const BasicBlock *LLVM_BB = BB->getBasicBlock();

  assert(MF->shouldSplitStack());

  const bool Is64Bit = Subtarget.is64Bit();
  const bool IsLP64 = Subtarget.isTarget64BitLP64();

  const unsigned TlsReg = Is64Bit ? X86::FS : X86::GS;
  const unsigned TlsOffset = IsLP64 ? 0x70 : Is64Bit ? 0x40 : 0x30;

  // BB:
  //  ... [Till the alloca]
  // If stacklet is not large enough, jump to mallocMBB
  //
  // bumpMBB:
  //  Allocate by subtracting from RSP
  //  Jump to continueMBB
  //
  // mallocMBB:
  //  Allocate by call to runtime
  //
  // continueMBB:
  //  ...
  //  [rest of original BB]
  //

  MachineBasicBlock *mallocMBB = MF->CreateMachineBasicBlock(LLVM_BB);
  MachineBasicBlock *bumpMBB = MF->CreateMachineBasicBlock(LLVM_BB);
  MachineBasicBlock *continueMBB = MF->CreateMachineBasicBlock(LLVM_BB);

  MachineRegisterInfo &MRI = MF->getRegInfo();
  const TargetRegisterClass *AddrRegClass =
      getRegClassFor(getPointerTy(MF->getDataLayout()));

  unsigned mallocPtrVReg = MRI.createVirtualRegister(AddrRegClass),
           bumpSPPtrVReg = MRI.createVirtualRegister(AddrRegClass),
           tmpSPVReg = MRI.createVirtualRegister(AddrRegClass),
           SPLimitVReg = MRI.createVirtualRegister(AddrRegClass),
           sizeVReg = MI.getOperand(1).getReg(),
           physSPReg =
               IsLP64 || Subtarget.isTargetNaCl64() ? X86::RSP : X86::ESP;

  MachineFunction::iterator MBBIter = ++BB->getIterator();

  MF->insert(MBBIter, bumpMBB);
  MF->insert(MBBIter, mallocMBB);
  MF->insert(MBBIter, continueMBB);

  continueMBB->splice(continueMBB->begin(), BB,
                      std::next(MachineBasicBlock::iterator(MI)), BB->end());
  continueMBB->transferSuccessorsAndUpdatePHIs(BB);

  // Add code to the main basic block to check if the stack limit has been hit,
  // and if so, jump to mallocMBB otherwise to bumpMBB.
  BuildMI(BB, DL, TII->get(TargetOpcode::COPY), tmpSPVReg).addReg(physSPReg);
  BuildMI(BB, DL, TII->get(IsLP64 ? X86::SUB64rr:X86::SUB32rr), SPLimitVReg)
    .addReg(tmpSPVReg).addReg(sizeVReg);
  BuildMI(BB, DL, TII->get(IsLP64 ? X86::CMP64mr:X86::CMP32mr))
    .addReg(0).addImm(1).addReg(0).addImm(TlsOffset).addReg(TlsReg)
    .addReg(SPLimitVReg);
  BuildMI(BB, DL, TII->get(X86::JCC_1)).addMBB(mallocMBB).addImm(X86::COND_G);

  // bumpMBB simply decreases the stack pointer, since we know the current
  // stacklet has enough space.
  BuildMI(bumpMBB, DL, TII->get(TargetOpcode::COPY), physSPReg)
    .addReg(SPLimitVReg);
  BuildMI(bumpMBB, DL, TII->get(TargetOpcode::COPY), bumpSPPtrVReg)
    .addReg(SPLimitVReg);
  BuildMI(bumpMBB, DL, TII->get(X86::JMP_1)).addMBB(continueMBB);

  // Calls into a routine in libgcc to allocate more space from the heap.
  const uint32_t *RegMask =
      Subtarget.getRegisterInfo()->getCallPreservedMask(*MF, CallingConv::C);
  if (IsLP64) {
    BuildMI(mallocMBB, DL, TII->get(X86::MOV64rr), X86::RDI)
      .addReg(sizeVReg);
    BuildMI(mallocMBB, DL, TII->get(X86::CALL64pcrel32))
      .addExternalSymbol("__morestack_allocate_stack_space")
      .addRegMask(RegMask)
      .addReg(X86::RDI, RegState::Implicit)
      .addReg(X86::RAX, RegState::ImplicitDefine);
  } else if (Is64Bit) {
    BuildMI(mallocMBB, DL, TII->get(X86::MOV32rr), X86::EDI)
      .addReg(sizeVReg);
    BuildMI(mallocMBB, DL, TII->get(X86::CALL64pcrel32))
      .addExternalSymbol("__morestack_allocate_stack_space")
      .addRegMask(RegMask)
      .addReg(X86::EDI, RegState::Implicit)
      .addReg(X86::EAX, RegState::ImplicitDefine);
  } else {
    BuildMI(mallocMBB, DL, TII->get(X86::SUB32ri), physSPReg).addReg(physSPReg)
      .addImm(12);
    BuildMI(mallocMBB, DL, TII->get(X86::PUSH32r)).addReg(sizeVReg);
    BuildMI(mallocMBB, DL, TII->get(X86::CALLpcrel32))
      .addExternalSymbol("__morestack_allocate_stack_space")
      .addRegMask(RegMask)
      .addReg(X86::EAX, RegState::ImplicitDefine);
  }

  if (!Is64Bit)
    BuildMI(mallocMBB, DL, TII->get(X86::ADD32ri), physSPReg).addReg(physSPReg)
      .addImm(16);

  BuildMI(mallocMBB, DL, TII->get(TargetOpcode::COPY), mallocPtrVReg)
    .addReg(IsLP64 ? X86::RAX : X86::EAX);
  BuildMI(mallocMBB, DL, TII->get(X86::JMP_1)).addMBB(continueMBB);

  // Set up the CFG correctly.
  BB->addSuccessor(bumpMBB);
  BB->addSuccessor(mallocMBB);
  mallocMBB->addSuccessor(continueMBB);
  bumpMBB->addSuccessor(continueMBB);

  // Take care of the PHI nodes.
  BuildMI(*continueMBB, continueMBB->begin(), DL, TII->get(X86::PHI),
          MI.getOperand(0).getReg())
      .addReg(mallocPtrVReg)
      .addMBB(mallocMBB)
      .addReg(bumpSPPtrVReg)
      .addMBB(bumpMBB);

  // Delete the original pseudo instruction.
  MI.eraseFromParent();

  // And we're done.
  return continueMBB;
}

MachineBasicBlock *
X86TargetLowering::EmitLoweredCatchRet(MachineInstr &MI,
                                       MachineBasicBlock *BB) const {
  MachineFunction *MF = BB->getParent();
  const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
  MachineBasicBlock *TargetMBB = MI.getOperand(0).getMBB();
  DebugLoc DL = MI.getDebugLoc();

  assert(!isAsynchronousEHPersonality(
             classifyEHPersonality(MF->getFunction().getPersonalityFn())) &&
         "SEH does not use catchret!");

  // Only 32-bit EH needs to worry about manually restoring stack pointers.
  if (!Subtarget.is32Bit())
    return BB;

  // C++ EH creates a new target block to hold the restore code, and wires up
  // the new block to the return destination with a normal JMP_4.
  MachineBasicBlock *RestoreMBB =
      MF->CreateMachineBasicBlock(BB->getBasicBlock());
  assert(BB->succ_size() == 1);
  MF->insert(std::next(BB->getIterator()), RestoreMBB);
  RestoreMBB->transferSuccessorsAndUpdatePHIs(BB);
  BB->addSuccessor(RestoreMBB);
  MI.getOperand(0).setMBB(RestoreMBB);

  // Marking this as an EH pad but not a funclet entry block causes PEI to
  // restore stack pointers in the block.
  RestoreMBB->setIsEHPad(true);

  auto RestoreMBBI = RestoreMBB->begin();
  BuildMI(*RestoreMBB, RestoreMBBI, DL, TII.get(X86::JMP_4)).addMBB(TargetMBB);
  return BB;
}

MachineBasicBlock *
X86TargetLowering::EmitLoweredTLSAddr(MachineInstr &MI,
                                      MachineBasicBlock *BB) const {
  // So, here we replace TLSADDR with the sequence:
  // adjust_stackdown -> TLSADDR -> adjust_stackup.
  // We need this because TLSADDR is lowered into calls
  // inside MC, therefore without the two markers shrink-wrapping
  // may push the prologue/epilogue pass them.
  const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
  DebugLoc DL = MI.getDebugLoc();
  MachineFunction &MF = *BB->getParent();

  // Emit CALLSEQ_START right before the instruction.
  unsigned AdjStackDown = TII.getCallFrameSetupOpcode();
  MachineInstrBuilder CallseqStart =
    BuildMI(MF, DL, TII.get(AdjStackDown)).addImm(0).addImm(0).addImm(0);
  BB->insert(MachineBasicBlock::iterator(MI), CallseqStart);

  // Emit CALLSEQ_END right after the instruction.
  // We don't call erase from parent because we want to keep the
  // original instruction around.
  unsigned AdjStackUp = TII.getCallFrameDestroyOpcode();
  MachineInstrBuilder CallseqEnd =
    BuildMI(MF, DL, TII.get(AdjStackUp)).addImm(0).addImm(0);
  BB->insertAfter(MachineBasicBlock::iterator(MI), CallseqEnd);

  return BB;
}

MachineBasicBlock *
X86TargetLowering::EmitLoweredTLSCall(MachineInstr &MI,
                                      MachineBasicBlock *BB) const {
  // This is pretty easy.  We're taking the value that we received from
  // our load from the relocation, sticking it in either RDI (x86-64)
  // or EAX and doing an indirect call.  The return value will then
  // be in the normal return register.
  MachineFunction *F = BB->getParent();
  const X86InstrInfo *TII = Subtarget.getInstrInfo();
  DebugLoc DL = MI.getDebugLoc();

  assert(Subtarget.isTargetDarwin() && "Darwin only instr emitted?");
  assert(MI.getOperand(3).isGlobal() && "This should be a global");

  // Get a register mask for the lowered call.
  // FIXME: The 32-bit calls have non-standard calling conventions. Use a
  // proper register mask.
  const uint32_t *RegMask =
      Subtarget.is64Bit() ?
      Subtarget.getRegisterInfo()->getDarwinTLSCallPreservedMask() :
      Subtarget.getRegisterInfo()->getCallPreservedMask(*F, CallingConv::C);
  if (Subtarget.is64Bit()) {
    MachineInstrBuilder MIB =
        BuildMI(*BB, MI, DL, TII->get(X86::MOV64rm), X86::RDI)
            .addReg(X86::RIP)
            .addImm(0)
            .addReg(0)
            .addGlobalAddress(MI.getOperand(3).getGlobal(), 0,
                              MI.getOperand(3).getTargetFlags())
            .addReg(0);
    MIB = BuildMI(*BB, MI, DL, TII->get(X86::CALL64m));
    addDirectMem(MIB, X86::RDI);
    MIB.addReg(X86::RAX, RegState::ImplicitDefine).addRegMask(RegMask);
  } else if (!isPositionIndependent()) {
    MachineInstrBuilder MIB =
        BuildMI(*BB, MI, DL, TII->get(X86::MOV32rm), X86::EAX)
            .addReg(0)
            .addImm(0)
            .addReg(0)
            .addGlobalAddress(MI.getOperand(3).getGlobal(), 0,
                              MI.getOperand(3).getTargetFlags())
            .addReg(0);
    MIB = BuildMI(*BB, MI, DL, TII->get(X86::CALL32m));
    addDirectMem(MIB, X86::EAX);
    MIB.addReg(X86::EAX, RegState::ImplicitDefine).addRegMask(RegMask);
  } else {
    MachineInstrBuilder MIB =
        BuildMI(*BB, MI, DL, TII->get(X86::MOV32rm), X86::EAX)
            .addReg(TII->getGlobalBaseReg(F))
            .addImm(0)
            .addReg(0)
            .addGlobalAddress(MI.getOperand(3).getGlobal(), 0,
                              MI.getOperand(3).getTargetFlags())
            .addReg(0);
    MIB = BuildMI(*BB, MI, DL, TII->get(X86::CALL32m));
    addDirectMem(MIB, X86::EAX);
    MIB.addReg(X86::EAX, RegState::ImplicitDefine).addRegMask(RegMask);
  }

  MI.eraseFromParent(); // The pseudo instruction is gone now.
  return BB;
}

static unsigned getOpcodeForIndirectThunk(unsigned RPOpc) {
  switch (RPOpc) {
  case X86::INDIRECT_THUNK_CALL32:
    return X86::CALLpcrel32;
  case X86::INDIRECT_THUNK_CALL64:
    return X86::CALL64pcrel32;
  case X86::INDIRECT_THUNK_TCRETURN32:
    return X86::TCRETURNdi;
  case X86::INDIRECT_THUNK_TCRETURN64:
    return X86::TCRETURNdi64;
  }
  llvm_unreachable("not indirect thunk opcode");
}

static const char *getIndirectThunkSymbol(const X86Subtarget &Subtarget,
                                          unsigned Reg) {
  if (Subtarget.useRetpolineExternalThunk()) {
    // When using an external thunk for retpolines, we pick names that match the
    // names GCC happens to use as well. This helps simplify the implementation
    // of the thunks for kernels where they have no easy ability to create
    // aliases and are doing non-trivial configuration of the thunk's body. For
    // example, the Linux kernel will do boot-time hot patching of the thunk
    // bodies and cannot easily export aliases of these to loaded modules.
    //
    // Note that at any point in the future, we may need to change the semantics
    // of how we implement retpolines and at that time will likely change the
    // name of the called thunk. Essentially, there is no hard guarantee that
    // LLVM will generate calls to specific thunks, we merely make a best-effort
    // attempt to help out kernels and other systems where duplicating the
    // thunks is costly.
    switch (Reg) {
    case X86::EAX:
      assert(!Subtarget.is64Bit() && "Should not be using a 32-bit thunk!");
      return "__x86_indirect_thunk_eax";
    case X86::ECX:
      assert(!Subtarget.is64Bit() && "Should not be using a 32-bit thunk!");
      return "__x86_indirect_thunk_ecx";
    case X86::EDX:
      assert(!Subtarget.is64Bit() && "Should not be using a 32-bit thunk!");
      return "__x86_indirect_thunk_edx";
    case X86::EDI:
      assert(!Subtarget.is64Bit() && "Should not be using a 32-bit thunk!");
      return "__x86_indirect_thunk_edi";
    case X86::R11:
      assert(Subtarget.is64Bit() && "Should not be using a 64-bit thunk!");
      return "__x86_indirect_thunk_r11";
    }
    llvm_unreachable("unexpected reg for external indirect thunk");
  }

  if (Subtarget.useRetpolineIndirectCalls() ||
      Subtarget.useRetpolineIndirectBranches()) {
    // When targeting an internal COMDAT thunk use an LLVM-specific name.
    switch (Reg) {
    case X86::EAX:
      assert(!Subtarget.is64Bit() && "Should not be using a 32-bit thunk!");
      return "__llvm_retpoline_eax";
    case X86::ECX:
      assert(!Subtarget.is64Bit() && "Should not be using a 32-bit thunk!");
      return "__llvm_retpoline_ecx";
    case X86::EDX:
      assert(!Subtarget.is64Bit() && "Should not be using a 32-bit thunk!");
      return "__llvm_retpoline_edx";
    case X86::EDI:
      assert(!Subtarget.is64Bit() && "Should not be using a 32-bit thunk!");
      return "__llvm_retpoline_edi";
    case X86::R11:
      assert(Subtarget.is64Bit() && "Should not be using a 64-bit thunk!");
      return "__llvm_retpoline_r11";
    }
    llvm_unreachable("unexpected reg for retpoline");
  }
  llvm_unreachable("getIndirectThunkSymbol() invoked without thunk feature");
}

MachineBasicBlock *
X86TargetLowering::EmitLoweredIndirectThunk(MachineInstr &MI,
                                            MachineBasicBlock *BB) const {
  // Copy the virtual register into the R11 physical register and
  // call the retpoline thunk.
  DebugLoc DL = MI.getDebugLoc();
  const X86InstrInfo *TII = Subtarget.getInstrInfo();
  Register CalleeVReg = MI.getOperand(0).getReg();
  unsigned Opc = getOpcodeForIndirectThunk(MI.getOpcode());

  // Find an available scratch register to hold the callee. On 64-bit, we can
  // just use R11, but we scan for uses anyway to ensure we don't generate
  // incorrect code. On 32-bit, we use one of EAX, ECX, or EDX that isn't
  // already a register use operand to the call to hold the callee. If none
  // are available, use EDI instead. EDI is chosen because EBX is the PIC base
  // register and ESI is the base pointer to realigned stack frames with VLAs.
  SmallVector<unsigned, 3> AvailableRegs;
  if (Subtarget.is64Bit())
    AvailableRegs.push_back(X86::R11);
  else
    AvailableRegs.append({X86::EAX, X86::ECX, X86::EDX, X86::EDI});

  // Zero out any registers that are already used.
  for (const auto &MO : MI.operands()) {
    if (MO.isReg() && MO.isUse())
      for (unsigned &Reg : AvailableRegs)
        if (Reg == MO.getReg())
          Reg = 0;
  }

  // Choose the first remaining non-zero available register.
  unsigned AvailableReg = 0;
  for (unsigned MaybeReg : AvailableRegs) {
    if (MaybeReg) {
      AvailableReg = MaybeReg;
      break;
    }
  }
  if (!AvailableReg)
    report_fatal_error("calling convention incompatible with retpoline, no "
                       "available registers");

  const char *Symbol = getIndirectThunkSymbol(Subtarget, AvailableReg);

  BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), AvailableReg)
      .addReg(CalleeVReg);
  MI.getOperand(0).ChangeToES(Symbol);
  MI.setDesc(TII->get(Opc));
  MachineInstrBuilder(*BB->getParent(), &MI)
      .addReg(AvailableReg, RegState::Implicit | RegState::Kill);
  return BB;
}

/// SetJmp implies future control flow change upon calling the corresponding
/// LongJmp.
/// Instead of using the 'return' instruction, the long jump fixes the stack and
/// performs an indirect branch. To do so it uses the registers that were stored
/// in the jump buffer (when calling SetJmp).
/// In case the shadow stack is enabled we need to fix it as well, because some
/// return addresses will be skipped.
/// The function will save the SSP for future fixing in the function
/// emitLongJmpShadowStackFix.
/// \sa emitLongJmpShadowStackFix
/// \param [in] MI The temporary Machine Instruction for the builtin.
/// \param [in] MBB The Machine Basic Block that will be modified.
void X86TargetLowering::emitSetJmpShadowStackFix(MachineInstr &MI,
                                                 MachineBasicBlock *MBB) const {
  DebugLoc DL = MI.getDebugLoc();
  MachineFunction *MF = MBB->getParent();
  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
  MachineRegisterInfo &MRI = MF->getRegInfo();
  MachineInstrBuilder MIB;

  // Memory Reference.
  SmallVector<MachineMemOperand *, 2> MMOs(MI.memoperands_begin(),
                                           MI.memoperands_end());

  // Initialize a register with zero.
  MVT PVT = getPointerTy(MF->getDataLayout());
  const TargetRegisterClass *PtrRC = getRegClassFor(PVT);
  Register ZReg = MRI.createVirtualRegister(PtrRC);
  unsigned XorRROpc = (PVT == MVT::i64) ? X86::XOR64rr : X86::XOR32rr;
  BuildMI(*MBB, MI, DL, TII->get(XorRROpc))
      .addDef(ZReg)
      .addReg(ZReg, RegState::Undef)
      .addReg(ZReg, RegState::Undef);

  // Read the current SSP Register value to the zeroed register.
  Register SSPCopyReg = MRI.createVirtualRegister(PtrRC);
  unsigned RdsspOpc = (PVT == MVT::i64) ? X86::RDSSPQ : X86::RDSSPD;
  BuildMI(*MBB, MI, DL, TII->get(RdsspOpc), SSPCopyReg).addReg(ZReg);

  // Write the SSP register value to offset 3 in input memory buffer.
  unsigned PtrStoreOpc = (PVT == MVT::i64) ? X86::MOV64mr : X86::MOV32mr;
  MIB = BuildMI(*MBB, MI, DL, TII->get(PtrStoreOpc));
  const int64_t SSPOffset = 3 * PVT.getStoreSize();
  const unsigned MemOpndSlot = 1;
  for (unsigned i = 0; i < X86::AddrNumOperands; ++i) {
    if (i == X86::AddrDisp)
      MIB.addDisp(MI.getOperand(MemOpndSlot + i), SSPOffset);
    else
      MIB.add(MI.getOperand(MemOpndSlot + i));
  }
  MIB.addReg(SSPCopyReg);
  MIB.setMemRefs(MMOs);
}

MachineBasicBlock *
X86TargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
                                    MachineBasicBlock *MBB) const {
  DebugLoc DL = MI.getDebugLoc();
  MachineFunction *MF = MBB->getParent();
  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
  const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
  MachineRegisterInfo &MRI = MF->getRegInfo();

  const BasicBlock *BB = MBB->getBasicBlock();
  MachineFunction::iterator I = ++MBB->getIterator();

  // Memory Reference
  SmallVector<MachineMemOperand *, 2> MMOs(MI.memoperands_begin(),
                                           MI.memoperands_end());

  unsigned DstReg;
  unsigned MemOpndSlot = 0;

  unsigned CurOp = 0;

  DstReg = MI.getOperand(CurOp++).getReg();
  const TargetRegisterClass *RC = MRI.getRegClass(DstReg);
  assert(TRI->isTypeLegalForClass(*RC, MVT::i32) && "Invalid destination!");
  (void)TRI;
  Register mainDstReg = MRI.createVirtualRegister(RC);
  Register restoreDstReg = MRI.createVirtualRegister(RC);

  MemOpndSlot = CurOp;

  MVT PVT = getPointerTy(MF->getDataLayout());
  assert((PVT == MVT::i64 || PVT == MVT::i32) &&
         "Invalid Pointer Size!");

  // For v = setjmp(buf), we generate
  //
  // thisMBB:
  //  buf[LabelOffset] = restoreMBB <-- takes address of restoreMBB
  //  SjLjSetup restoreMBB
  //
  // mainMBB:
  //  v_main = 0
  //
  // sinkMBB:
  //  v = phi(main, restore)
  //
  // restoreMBB:
  //  if base pointer being used, load it from frame
  //  v_restore = 1

  MachineBasicBlock *thisMBB = MBB;
  MachineBasicBlock *mainMBB = MF->CreateMachineBasicBlock(BB);
  MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(BB);
  MachineBasicBlock *restoreMBB = MF->CreateMachineBasicBlock(BB);
  MF->insert(I, mainMBB);
  MF->insert(I, sinkMBB);
  MF->push_back(restoreMBB);
  restoreMBB->setHasAddressTaken();

  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);

  // thisMBB:
  unsigned PtrStoreOpc = 0;
  unsigned LabelReg = 0;
  const int64_t LabelOffset = 1 * PVT.getStoreSize();
  bool UseImmLabel = (MF->getTarget().getCodeModel() == CodeModel::Small) &&
                     !isPositionIndependent();

  // Prepare IP either in reg or imm.
  if (!UseImmLabel) {
    PtrStoreOpc = (PVT == MVT::i64) ? X86::MOV64mr : X86::MOV32mr;
    const TargetRegisterClass *PtrRC = getRegClassFor(PVT);
    LabelReg = MRI.createVirtualRegister(PtrRC);
    if (Subtarget.is64Bit()) {
      MIB = BuildMI(*thisMBB, MI, DL, TII->get(X86::LEA64r), LabelReg)
              .addReg(X86::RIP)
              .addImm(0)
              .addReg(0)
              .addMBB(restoreMBB)
              .addReg(0);
    } else {
      const X86InstrInfo *XII = static_cast<const X86InstrInfo*>(TII);
      MIB = BuildMI(*thisMBB, MI, DL, TII->get(X86::LEA32r), LabelReg)
              .addReg(XII->getGlobalBaseReg(MF))
              .addImm(0)
              .addReg(0)
              .addMBB(restoreMBB, Subtarget.classifyBlockAddressReference())
              .addReg(0);
    }
  } else
    PtrStoreOpc = (PVT == MVT::i64) ? X86::MOV64mi32 : X86::MOV32mi;
  // Store IP
  MIB = BuildMI(*thisMBB, MI, DL, TII->get(PtrStoreOpc));
  for (unsigned i = 0; i < X86::AddrNumOperands; ++i) {
    if (i == X86::AddrDisp)
      MIB.addDisp(MI.getOperand(MemOpndSlot + i), LabelOffset);
    else
      MIB.add(MI.getOperand(MemOpndSlot + i));
  }
  if (!UseImmLabel)
    MIB.addReg(LabelReg);
  else
    MIB.addMBB(restoreMBB);
  MIB.setMemRefs(MMOs);

  if (MF->getMMI().getModule()->getModuleFlag("cf-protection-return")) {
    emitSetJmpShadowStackFix(MI, thisMBB);
  }

  // Setup
  MIB = BuildMI(*thisMBB, MI, DL, TII->get(X86::EH_SjLj_Setup))
          .addMBB(restoreMBB);

  const X86RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
  MIB.addRegMask(RegInfo->getNoPreservedMask());
  thisMBB->addSuccessor(mainMBB);
  thisMBB->addSuccessor(restoreMBB);

  // mainMBB:
  //  EAX = 0
  BuildMI(mainMBB, DL, TII->get(X86::MOV32r0), mainDstReg);
  mainMBB->addSuccessor(sinkMBB);

  // sinkMBB:
  BuildMI(*sinkMBB, sinkMBB->begin(), DL,
          TII->get(X86::PHI), DstReg)
    .addReg(mainDstReg).addMBB(mainMBB)
    .addReg(restoreDstReg).addMBB(restoreMBB);

  // restoreMBB:
  if (RegInfo->hasBasePointer(*MF)) {
    const bool Uses64BitFramePtr =
        Subtarget.isTarget64BitLP64() || Subtarget.isTargetNaCl64();
    X86MachineFunctionInfo *X86FI = MF->getInfo<X86MachineFunctionInfo>();
    X86FI->setRestoreBasePointer(MF);
    Register FramePtr = RegInfo->getFrameRegister(*MF);
    Register BasePtr = RegInfo->getBaseRegister();
    unsigned Opm = Uses64BitFramePtr ? X86::MOV64rm : X86::MOV32rm;
    addRegOffset(BuildMI(restoreMBB, DL, TII->get(Opm), BasePtr),
                 FramePtr, true, X86FI->getRestoreBasePointerOffset())
      .setMIFlag(MachineInstr::FrameSetup);
  }
  BuildMI(restoreMBB, DL, TII->get(X86::MOV32ri), restoreDstReg).addImm(1);
  BuildMI(restoreMBB, DL, TII->get(X86::JMP_1)).addMBB(sinkMBB);
  restoreMBB->addSuccessor(sinkMBB);

  MI.eraseFromParent();
  return sinkMBB;
}

/// Fix the shadow stack using the previously saved SSP pointer.
/// \sa emitSetJmpShadowStackFix
/// \param [in] MI The temporary Machine Instruction for the builtin.
/// \param [in] MBB The Machine Basic Block that will be modified.
/// \return The sink MBB that will perform the future indirect branch.
MachineBasicBlock *
X86TargetLowering::emitLongJmpShadowStackFix(MachineInstr &MI,
                                             MachineBasicBlock *MBB) const {
  DebugLoc DL = MI.getDebugLoc();
  MachineFunction *MF = MBB->getParent();
  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
  MachineRegisterInfo &MRI = MF->getRegInfo();

  // Memory Reference
  SmallVector<MachineMemOperand *, 2> MMOs(MI.memoperands_begin(),
                                           MI.memoperands_end());

  MVT PVT = getPointerTy(MF->getDataLayout());
  const TargetRegisterClass *PtrRC = getRegClassFor(PVT);

  // checkSspMBB:
  //         xor vreg1, vreg1
  //         rdssp vreg1
  //         test vreg1, vreg1
  //         je sinkMBB   # Jump if Shadow Stack is not supported
  // fallMBB:
  //         mov buf+24/12(%rip), vreg2
  //         sub vreg1, vreg2
  //         jbe sinkMBB  # No need to fix the Shadow Stack
  // fixShadowMBB:
  //         shr 3/2, vreg2
  //         incssp vreg2  # fix the SSP according to the lower 8 bits
  //         shr 8, vreg2
  //         je sinkMBB
  // fixShadowLoopPrepareMBB:
  //         shl vreg2
  //         mov 128, vreg3
  // fixShadowLoopMBB:
  //         incssp vreg3
  //         dec vreg2
  //         jne fixShadowLoopMBB # Iterate until you finish fixing
  //                              # the Shadow Stack
  // sinkMBB:

  MachineFunction::iterator I = ++MBB->getIterator();
  const BasicBlock *BB = MBB->getBasicBlock();

  MachineBasicBlock *checkSspMBB = MF->CreateMachineBasicBlock(BB);
  MachineBasicBlock *fallMBB = MF->CreateMachineBasicBlock(BB);
  MachineBasicBlock *fixShadowMBB = MF->CreateMachineBasicBlock(BB);
  MachineBasicBlock *fixShadowLoopPrepareMBB = MF->CreateMachineBasicBlock(BB);
  MachineBasicBlock *fixShadowLoopMBB = MF->CreateMachineBasicBlock(BB);
  MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(BB);
  MF->insert(I, checkSspMBB);
  MF->insert(I, fallMBB);
  MF->insert(I, fixShadowMBB);
  MF->insert(I, fixShadowLoopPrepareMBB);
  MF->insert(I, fixShadowLoopMBB);
  MF->insert(I, sinkMBB);

  // Transfer the remainder of BB and its successor edges to sinkMBB.
  sinkMBB->splice(sinkMBB->begin(), MBB, MachineBasicBlock::iterator(MI),
                  MBB->end());
  sinkMBB->transferSuccessorsAndUpdatePHIs(MBB);

  MBB->addSuccessor(checkSspMBB);

  // Initialize a register with zero.
  Register ZReg = MRI.createVirtualRegister(PtrRC);
  unsigned XorRROpc = (PVT == MVT::i64) ? X86::XOR64rr : X86::XOR32rr;
  BuildMI(checkSspMBB, DL, TII->get(XorRROpc))
      .addDef(ZReg)
      .addReg(ZReg, RegState::Undef)
      .addReg(ZReg, RegState::Undef);

  // Read the current SSP Register value to the zeroed register.
  Register SSPCopyReg = MRI.createVirtualRegister(PtrRC);
  unsigned RdsspOpc = (PVT == MVT::i64) ? X86::RDSSPQ : X86::RDSSPD;
  BuildMI(checkSspMBB, DL, TII->get(RdsspOpc), SSPCopyReg).addReg(ZReg);

  // Check whether the result of the SSP register is zero and jump directly
  // to the sink.
  unsigned TestRROpc = (PVT == MVT::i64) ? X86::TEST64rr : X86::TEST32rr;
  BuildMI(checkSspMBB, DL, TII->get(TestRROpc))
      .addReg(SSPCopyReg)
      .addReg(SSPCopyReg);
  BuildMI(checkSspMBB, DL, TII->get(X86::JCC_1)).addMBB(sinkMBB).addImm(X86::COND_E);
  checkSspMBB->addSuccessor(sinkMBB);
  checkSspMBB->addSuccessor(fallMBB);

  // Reload the previously saved SSP register value.
  Register PrevSSPReg = MRI.createVirtualRegister(PtrRC);
  unsigned PtrLoadOpc = (PVT == MVT::i64) ? X86::MOV64rm : X86::MOV32rm;
  const int64_t SPPOffset = 3 * PVT.getStoreSize();
  MachineInstrBuilder MIB =
      BuildMI(fallMBB, DL, TII->get(PtrLoadOpc), PrevSSPReg);
  for (unsigned i = 0; i < X86::AddrNumOperands; ++i) {
    const MachineOperand &MO = MI.getOperand(i);
    if (i == X86::AddrDisp)
      MIB.addDisp(MO, SPPOffset);
    else if (MO.isReg()) // Don't add the whole operand, we don't want to
                         // preserve kill flags.
      MIB.addReg(MO.getReg());
    else
      MIB.add(MO);
  }
  MIB.setMemRefs(MMOs);

  // Subtract the current SSP from the previous SSP.
  Register SspSubReg = MRI.createVirtualRegister(PtrRC);
  unsigned SubRROpc = (PVT == MVT::i64) ? X86::SUB64rr : X86::SUB32rr;
  BuildMI(fallMBB, DL, TII->get(SubRROpc), SspSubReg)
      .addReg(PrevSSPReg)
      .addReg(SSPCopyReg);

  // Jump to sink in case PrevSSPReg <= SSPCopyReg.
  BuildMI(fallMBB, DL, TII->get(X86::JCC_1)).addMBB(sinkMBB).addImm(X86::COND_BE);
  fallMBB->addSuccessor(sinkMBB);
  fallMBB->addSuccessor(fixShadowMBB);

  // Shift right by 2/3 for 32/64 because incssp multiplies the argument by 4/8.
  unsigned ShrRIOpc = (PVT == MVT::i64) ? X86::SHR64ri : X86::SHR32ri;
  unsigned Offset = (PVT == MVT::i64) ? 3 : 2;
  Register SspFirstShrReg = MRI.createVirtualRegister(PtrRC);
  BuildMI(fixShadowMBB, DL, TII->get(ShrRIOpc), SspFirstShrReg)
      .addReg(SspSubReg)
      .addImm(Offset);

  // Increase SSP when looking only on the lower 8 bits of the delta.
  unsigned IncsspOpc = (PVT == MVT::i64) ? X86::INCSSPQ : X86::INCSSPD;
  BuildMI(fixShadowMBB, DL, TII->get(IncsspOpc)).addReg(SspFirstShrReg);

  // Reset the lower 8 bits.
  Register SspSecondShrReg = MRI.createVirtualRegister(PtrRC);
  BuildMI(fixShadowMBB, DL, TII->get(ShrRIOpc), SspSecondShrReg)
      .addReg(SspFirstShrReg)
      .addImm(8);

  // Jump if the result of the shift is zero.
  BuildMI(fixShadowMBB, DL, TII->get(X86::JCC_1)).addMBB(sinkMBB).addImm(X86::COND_E);
  fixShadowMBB->addSuccessor(sinkMBB);
  fixShadowMBB->addSuccessor(fixShadowLoopPrepareMBB);

  // Do a single shift left.
  unsigned ShlR1Opc = (PVT == MVT::i64) ? X86::SHL64r1 : X86::SHL32r1;
  Register SspAfterShlReg = MRI.createVirtualRegister(PtrRC);
  BuildMI(fixShadowLoopPrepareMBB, DL, TII->get(ShlR1Opc), SspAfterShlReg)
      .addReg(SspSecondShrReg);

  // Save the value 128 to a register (will be used next with incssp).
  Register Value128InReg = MRI.createVirtualRegister(PtrRC);
  unsigned MovRIOpc = (PVT == MVT::i64) ? X86::MOV64ri32 : X86::MOV32ri;
  BuildMI(fixShadowLoopPrepareMBB, DL, TII->get(MovRIOpc), Value128InReg)
      .addImm(128);
  fixShadowLoopPrepareMBB->addSuccessor(fixShadowLoopMBB);

  // Since incssp only looks at the lower 8 bits, we might need to do several
  // iterations of incssp until we finish fixing the shadow stack.
  Register DecReg = MRI.createVirtualRegister(PtrRC);
  Register CounterReg = MRI.createVirtualRegister(PtrRC);
  BuildMI(fixShadowLoopMBB, DL, TII->get(X86::PHI), CounterReg)
      .addReg(SspAfterShlReg)
      .addMBB(fixShadowLoopPrepareMBB)
      .addReg(DecReg)
      .addMBB(fixShadowLoopMBB);

  // Every iteration we increase the SSP by 128.
  BuildMI(fixShadowLoopMBB, DL, TII->get(IncsspOpc)).addReg(Value128InReg);

  // Every iteration we decrement the counter by 1.
  unsigned DecROpc = (PVT == MVT::i64) ? X86::DEC64r : X86::DEC32r;
  BuildMI(fixShadowLoopMBB, DL, TII->get(DecROpc), DecReg).addReg(CounterReg);

  // Jump if the counter is not zero yet.
  BuildMI(fixShadowLoopMBB, DL, TII->get(X86::JCC_1)).addMBB(fixShadowLoopMBB).addImm(X86::COND_NE);
  fixShadowLoopMBB->addSuccessor(sinkMBB);
  fixShadowLoopMBB->addSuccessor(fixShadowLoopMBB);

  return sinkMBB;
}

MachineBasicBlock *
X86TargetLowering::emitEHSjLjLongJmp(MachineInstr &MI,
                                     MachineBasicBlock *MBB) const {
  DebugLoc DL = MI.getDebugLoc();
  MachineFunction *MF = MBB->getParent();
  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
  MachineRegisterInfo &MRI = MF->getRegInfo();

  // Memory Reference
  SmallVector<MachineMemOperand *, 2> MMOs(MI.memoperands_begin(),
                                           MI.memoperands_end());

  MVT PVT = getPointerTy(MF->getDataLayout());
  assert((PVT == MVT::i64 || PVT == MVT::i32) &&
         "Invalid Pointer Size!");

  const TargetRegisterClass *RC =
    (PVT == MVT::i64) ? &X86::GR64RegClass : &X86::GR32RegClass;
  Register Tmp = MRI.createVirtualRegister(RC);
  // Since FP is only updated here but NOT referenced, it's treated as GPR.
  const X86RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
  unsigned FP = (PVT == MVT::i64) ? X86::RBP : X86::EBP;
  Register SP = RegInfo->getStackRegister();

  MachineInstrBuilder MIB;

  const int64_t LabelOffset = 1 * PVT.getStoreSize();
  const int64_t SPOffset = 2 * PVT.getStoreSize();

  unsigned PtrLoadOpc = (PVT == MVT::i64) ? X86::MOV64rm : X86::MOV32rm;
  unsigned IJmpOpc = (PVT == MVT::i64) ? X86::JMP64r : X86::JMP32r;

  MachineBasicBlock *thisMBB = MBB;

  // When CET and shadow stack is enabled, we need to fix the Shadow Stack.
  if (MF->getMMI().getModule()->getModuleFlag("cf-protection-return")) {
    thisMBB = emitLongJmpShadowStackFix(MI, thisMBB);
  }

  // Reload FP
  MIB = BuildMI(*thisMBB, MI, DL, TII->get(PtrLoadOpc), FP);
  for (unsigned i = 0; i < X86::AddrNumOperands; ++i) {
    const MachineOperand &MO = MI.getOperand(i);
    if (MO.isReg()) // Don't add the whole operand, we don't want to
                    // preserve kill flags.
      MIB.addReg(MO.getReg());
    else
      MIB.add(MO);
  }
  MIB.setMemRefs(MMOs);

  // Reload IP
  MIB = BuildMI(*thisMBB, MI, DL, TII->get(PtrLoadOpc), Tmp);
  for (unsigned i = 0; i < X86::AddrNumOperands; ++i) {
    const MachineOperand &MO = MI.getOperand(i);
    if (i == X86::AddrDisp)
      MIB.addDisp(MO, LabelOffset);
    else if (MO.isReg()) // Don't add the whole operand, we don't want to
                         // preserve kill flags.
      MIB.addReg(MO.getReg());
    else
      MIB.add(MO);
  }
  MIB.setMemRefs(MMOs);

  // Reload SP
  MIB = BuildMI(*thisMBB, MI, DL, TII->get(PtrLoadOpc), SP);
  for (unsigned i = 0; i < X86::AddrNumOperands; ++i) {
    if (i == X86::AddrDisp)
      MIB.addDisp(MI.getOperand(i), SPOffset);
    else
      MIB.add(MI.getOperand(i)); // We can preserve the kill flags here, it's
                                 // the last instruction of the expansion.
  }
  MIB.setMemRefs(MMOs);

  // Jump
  BuildMI(*thisMBB, MI, DL, TII->get(IJmpOpc)).addReg(Tmp);

  MI.eraseFromParent();
  return thisMBB;
}

void X86TargetLowering::SetupEntryBlockForSjLj(MachineInstr &MI,
                                               MachineBasicBlock *MBB,
                                               MachineBasicBlock *DispatchBB,
                                               int FI) const {
  DebugLoc DL = MI.getDebugLoc();
  MachineFunction *MF = MBB->getParent();
  MachineRegisterInfo *MRI = &MF->getRegInfo();
  const X86InstrInfo *TII = Subtarget.getInstrInfo();

  MVT PVT = getPointerTy(MF->getDataLayout());
  assert((PVT == MVT::i64 || PVT == MVT::i32) && "Invalid Pointer Size!");

  unsigned Op = 0;
  unsigned VR = 0;

  bool UseImmLabel = (MF->getTarget().getCodeModel() == CodeModel::Small) &&
                     !isPositionIndependent();

  if (UseImmLabel) {
    Op = (PVT == MVT::i64) ? X86::MOV64mi32 : X86::MOV32mi;
  } else {
    const TargetRegisterClass *TRC =
        (PVT == MVT::i64) ? &X86::GR64RegClass : &X86::GR32RegClass;
    VR = MRI->createVirtualRegister(TRC);
    Op = (PVT == MVT::i64) ? X86::MOV64mr : X86::MOV32mr;

    if (Subtarget.is64Bit())
      BuildMI(*MBB, MI, DL, TII->get(X86::LEA64r), VR)
          .addReg(X86::RIP)
          .addImm(1)
          .addReg(0)
          .addMBB(DispatchBB)
          .addReg(0);
    else
      BuildMI(*MBB, MI, DL, TII->get(X86::LEA32r), VR)
          .addReg(0) /* TII->getGlobalBaseReg(MF) */
          .addImm(1)
          .addReg(0)
          .addMBB(DispatchBB, Subtarget.classifyBlockAddressReference())
          .addReg(0);
  }

  MachineInstrBuilder MIB = BuildMI(*MBB, MI, DL, TII->get(Op));
  addFrameReference(MIB, FI, Subtarget.is64Bit() ? 56 : 36);
  if (UseImmLabel)
    MIB.addMBB(DispatchBB);
  else
    MIB.addReg(VR);
}

MachineBasicBlock *
X86TargetLowering::EmitSjLjDispatchBlock(MachineInstr &MI,
                                         MachineBasicBlock *BB) const {
  DebugLoc DL = MI.getDebugLoc();
  MachineFunction *MF = BB->getParent();
  MachineRegisterInfo *MRI = &MF->getRegInfo();
  const X86InstrInfo *TII = Subtarget.getInstrInfo();
  int FI = MF->getFrameInfo().getFunctionContextIndex();

  // Get a mapping of the call site numbers to all of the landing pads they're
  // associated with.
  DenseMap<unsigned, SmallVector<MachineBasicBlock *, 2>> CallSiteNumToLPad;
  unsigned MaxCSNum = 0;
  for (auto &MBB : *MF) {
    if (!MBB.isEHPad())
      continue;

    MCSymbol *Sym = nullptr;
    for (const auto &MI : MBB) {
      if (MI.isDebugInstr())
        continue;

      assert(MI.isEHLabel() && "expected EH_LABEL");
      Sym = MI.getOperand(0).getMCSymbol();
      break;
    }

    if (!MF->hasCallSiteLandingPad(Sym))
      continue;

    for (unsigned CSI : MF->getCallSiteLandingPad(Sym)) {
      CallSiteNumToLPad[CSI].push_back(&MBB);
      MaxCSNum = std::max(MaxCSNum, CSI);
    }
  }

  // Get an ordered list of the machine basic blocks for the jump table.
  std::vector<MachineBasicBlock *> LPadList;
  SmallPtrSet<MachineBasicBlock *, 32> InvokeBBs;
  LPadList.reserve(CallSiteNumToLPad.size());

  for (unsigned CSI = 1; CSI <= MaxCSNum; ++CSI) {
    for (auto &LP : CallSiteNumToLPad[CSI]) {
      LPadList.push_back(LP);
      InvokeBBs.insert(LP->pred_begin(), LP->pred_end());
    }
  }

  assert(!LPadList.empty() &&
         "No landing pad destinations for the dispatch jump table!");

  // Create the MBBs for the dispatch code.

  // Shove the dispatch's address into the return slot in the function context.
  MachineBasicBlock *DispatchBB = MF->CreateMachineBasicBlock();
  DispatchBB->setIsEHPad(true);

  MachineBasicBlock *TrapBB = MF->CreateMachineBasicBlock();
  BuildMI(TrapBB, DL, TII->get(X86::TRAP));
  DispatchBB->addSuccessor(TrapBB);

  MachineBasicBlock *DispContBB = MF->CreateMachineBasicBlock();
  DispatchBB->addSuccessor(DispContBB);

  // Insert MBBs.
  MF->push_back(DispatchBB);
  MF->push_back(DispContBB);
  MF->push_back(TrapBB);

  // Insert code into the entry block that creates and registers the function
  // context.
  SetupEntryBlockForSjLj(MI, BB, DispatchBB, FI);

  // Create the jump table and associated information
  unsigned JTE = getJumpTableEncoding();
  MachineJumpTableInfo *JTI = MF->getOrCreateJumpTableInfo(JTE);
  unsigned MJTI = JTI->createJumpTableIndex(LPadList);

  const X86RegisterInfo &RI = TII->getRegisterInfo();
  // Add a register mask with no preserved registers.  This results in all
  // registers being marked as clobbered.
  if (RI.hasBasePointer(*MF)) {
    const bool FPIs64Bit =
        Subtarget.isTarget64BitLP64() || Subtarget.isTargetNaCl64();
    X86MachineFunctionInfo *MFI = MF->getInfo<X86MachineFunctionInfo>();
    MFI->setRestoreBasePointer(MF);

    Register FP = RI.getFrameRegister(*MF);
    Register BP = RI.getBaseRegister();
    unsigned Op = FPIs64Bit ? X86::MOV64rm : X86::MOV32rm;
    addRegOffset(BuildMI(DispatchBB, DL, TII->get(Op), BP), FP, true,
                 MFI->getRestoreBasePointerOffset())
        .addRegMask(RI.getNoPreservedMask());
  } else {
    BuildMI(DispatchBB, DL, TII->get(X86::NOOP))
        .addRegMask(RI.getNoPreservedMask());
  }

  // IReg is used as an index in a memory operand and therefore can't be SP
  Register IReg = MRI->createVirtualRegister(&X86::GR32_NOSPRegClass);
  addFrameReference(BuildMI(DispatchBB, DL, TII->get(X86::MOV32rm), IReg), FI,
                    Subtarget.is64Bit() ? 8 : 4);
  BuildMI(DispatchBB, DL, TII->get(X86::CMP32ri))
      .addReg(IReg)
      .addImm(LPadList.size());
  BuildMI(DispatchBB, DL, TII->get(X86::JCC_1)).addMBB(TrapBB).addImm(X86::COND_AE);

  if (Subtarget.is64Bit()) {
    Register BReg = MRI->createVirtualRegister(&X86::GR64RegClass);
    Register IReg64 = MRI->createVirtualRegister(&X86::GR64_NOSPRegClass);

    // leaq .LJTI0_0(%rip), BReg
    BuildMI(DispContBB, DL, TII->get(X86::LEA64r), BReg)
        .addReg(X86::RIP)
        .addImm(1)
        .addReg(0)
        .addJumpTableIndex(MJTI)
        .addReg(0);
    // movzx IReg64, IReg
    BuildMI(DispContBB, DL, TII->get(TargetOpcode::SUBREG_TO_REG), IReg64)
        .addImm(0)
        .addReg(IReg)
        .addImm(X86::sub_32bit);

    switch (JTE) {
    case MachineJumpTableInfo::EK_BlockAddress:
      // jmpq *(BReg,IReg64,8)
      BuildMI(DispContBB, DL, TII->get(X86::JMP64m))
          .addReg(BReg)
          .addImm(8)
          .addReg(IReg64)
          .addImm(0)
          .addReg(0);
      break;
    case MachineJumpTableInfo::EK_LabelDifference32: {
      Register OReg = MRI->createVirtualRegister(&X86::GR32RegClass);
      Register OReg64 = MRI->createVirtualRegister(&X86::GR64RegClass);
      Register TReg = MRI->createVirtualRegister(&X86::GR64RegClass);

      // movl (BReg,IReg64,4), OReg
      BuildMI(DispContBB, DL, TII->get(X86::MOV32rm), OReg)
          .addReg(BReg)
          .addImm(4)
          .addReg(IReg64)
          .addImm(0)
          .addReg(0);
      // movsx OReg64, OReg
      BuildMI(DispContBB, DL, TII->get(X86::MOVSX64rr32), OReg64).addReg(OReg);
      // addq BReg, OReg64, TReg
      BuildMI(DispContBB, DL, TII->get(X86::ADD64rr), TReg)
          .addReg(OReg64)
          .addReg(BReg);
      // jmpq *TReg
      BuildMI(DispContBB, DL, TII->get(X86::JMP64r)).addReg(TReg);
      break;
    }
    default:
      llvm_unreachable("Unexpected jump table encoding");
    }
  } else {
    // jmpl *.LJTI0_0(,IReg,4)
    BuildMI(DispContBB, DL, TII->get(X86::JMP32m))
        .addReg(0)
        .addImm(4)
        .addReg(IReg)
        .addJumpTableIndex(MJTI)
        .addReg(0);
  }

  // Add the jump table entries as successors to the MBB.
  SmallPtrSet<MachineBasicBlock *, 8> SeenMBBs;
  for (auto &LP : LPadList)
    if (SeenMBBs.insert(LP).second)
      DispContBB->addSuccessor(LP);

  // N.B. the order the invoke BBs are processed in doesn't matter here.
  SmallVector<MachineBasicBlock *, 64> MBBLPads;
  const MCPhysReg *SavedRegs = MF->getRegInfo().getCalleeSavedRegs();
  for (MachineBasicBlock *MBB : InvokeBBs) {
    // Remove the landing pad successor from the invoke block and replace it
    // with the new dispatch block.
    // Keep a copy of Successors since it's modified inside the loop.
    SmallVector<MachineBasicBlock *, 8> Successors(MBB->succ_rbegin(),
                                                   MBB->succ_rend());
    // FIXME: Avoid quadratic complexity.
    for (auto MBBS : Successors) {
      if (MBBS->isEHPad()) {
        MBB->removeSuccessor(MBBS);
        MBBLPads.push_back(MBBS);
      }
    }

    MBB->addSuccessor(DispatchBB);

    // Find the invoke call and mark all of the callee-saved registers as
    // 'implicit defined' so that they're spilled.  This prevents code from
    // moving instructions to before the EH block, where they will never be
    // executed.
    for (auto &II : reverse(*MBB)) {
      if (!II.isCall())
        continue;

      DenseMap<unsigned, bool> DefRegs;
      for (auto &MOp : II.operands())
        if (MOp.isReg())
          DefRegs[MOp.getReg()] = true;

      MachineInstrBuilder MIB(*MF, &II);
      for (unsigned RegIdx = 0; SavedRegs[RegIdx]; ++RegIdx) {
        unsigned Reg = SavedRegs[RegIdx];
        if (!DefRegs[Reg])
          MIB.addReg(Reg, RegState::ImplicitDefine | RegState::Dead);
      }

      break;
    }
  }

  // Mark all former landing pads as non-landing pads.  The dispatch is the only
  // landing pad now.
  for (auto &LP : MBBLPads)
    LP->setIsEHPad(false);

  // The instruction is gone now.
  MI.eraseFromParent();
  return BB;
}

MachineBasicBlock *
X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
                                               MachineBasicBlock *BB) const {
  MachineFunction *MF = BB->getParent();
  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
  DebugLoc DL = MI.getDebugLoc();

  switch (MI.getOpcode()) {
  default: llvm_unreachable("Unexpected instr type to insert");
  case X86::TLS_addr32:
  case X86::TLS_addr64:
  case X86::TLS_base_addr32:
  case X86::TLS_base_addr64:
    return EmitLoweredTLSAddr(MI, BB);
  case X86::INDIRECT_THUNK_CALL32:
  case X86::INDIRECT_THUNK_CALL64:
  case X86::INDIRECT_THUNK_TCRETURN32:
  case X86::INDIRECT_THUNK_TCRETURN64:
    return EmitLoweredIndirectThunk(MI, BB);
  case X86::CATCHRET:
    return EmitLoweredCatchRet(MI, BB);
  case X86::SEG_ALLOCA_32:
  case X86::SEG_ALLOCA_64:
    return EmitLoweredSegAlloca(MI, BB);
  case X86::PROBED_ALLOCA_32:
  case X86::PROBED_ALLOCA_64:
    return EmitLoweredProbedAlloca(MI, BB);
  case X86::TLSCall_32:
  case X86::TLSCall_64:
    return EmitLoweredTLSCall(MI, BB);
  case X86::CMOV_FR32:
  case X86::CMOV_FR32X:
  case X86::CMOV_FR64:
  case X86::CMOV_FR64X:
  case X86::CMOV_GR8:
  case X86::CMOV_GR16:
  case X86::CMOV_GR32:
  case X86::CMOV_RFP32:
  case X86::CMOV_RFP64:
  case X86::CMOV_RFP80:
  case X86::CMOV_VR64:
  case X86::CMOV_VR128:
  case X86::CMOV_VR128X:
  case X86::CMOV_VR256:
  case X86::CMOV_VR256X:
  case X86::CMOV_VR512:
  case X86::CMOV_VK1:
  case X86::CMOV_VK2:
  case X86::CMOV_VK4:
  case X86::CMOV_VK8:
  case X86::CMOV_VK16:
  case X86::CMOV_VK32:
  case X86::CMOV_VK64:
    return EmitLoweredSelect(MI, BB);

  case X86::RDFLAGS32:
  case X86::RDFLAGS64: {
    unsigned PushF =
        MI.getOpcode() == X86::RDFLAGS32 ? X86::PUSHF32 : X86::PUSHF64;
    unsigned Pop = MI.getOpcode() == X86::RDFLAGS32 ? X86::POP32r : X86::POP64r;
    MachineInstr *Push = BuildMI(*BB, MI, DL, TII->get(PushF));
    // Permit reads of the EFLAGS and DF registers without them being defined.
    // This intrinsic exists to read external processor state in flags, such as
    // the trap flag, interrupt flag, and direction flag, none of which are
    // modeled by the backend.
    assert(Push->getOperand(2).getReg() == X86::EFLAGS &&
           "Unexpected register in operand!");
    Push->getOperand(2).setIsUndef();
    assert(Push->getOperand(3).getReg() == X86::DF &&
           "Unexpected register in operand!");
    Push->getOperand(3).setIsUndef();
    BuildMI(*BB, MI, DL, TII->get(Pop), MI.getOperand(0).getReg());

    MI.eraseFromParent(); // The pseudo is gone now.
    return BB;
  }

  case X86::WRFLAGS32:
  case X86::WRFLAGS64: {
    unsigned Push =
        MI.getOpcode() == X86::WRFLAGS32 ? X86::PUSH32r : X86::PUSH64r;
    unsigned PopF =
        MI.getOpcode() == X86::WRFLAGS32 ? X86::POPF32 : X86::POPF64;
    BuildMI(*BB, MI, DL, TII->get(Push)).addReg(MI.getOperand(0).getReg());
    BuildMI(*BB, MI, DL, TII->get(PopF));

    MI.eraseFromParent(); // The pseudo is gone now.
    return BB;
  }

  case X86::FP32_TO_INT16_IN_MEM:
  case X86::FP32_TO_INT32_IN_MEM:
  case X86::FP32_TO_INT64_IN_MEM:
  case X86::FP64_TO_INT16_IN_MEM:
  case X86::FP64_TO_INT32_IN_MEM:
  case X86::FP64_TO_INT64_IN_MEM:
  case X86::FP80_TO_INT16_IN_MEM:
  case X86::FP80_TO_INT32_IN_MEM:
  case X86::FP80_TO_INT64_IN_MEM: {
    // Change the floating point control register to use "round towards zero"
    // mode when truncating to an integer value.
    int OrigCWFrameIdx = MF->getFrameInfo().CreateStackObject(2, 2, false);
    addFrameReference(BuildMI(*BB, MI, DL,
                              TII->get(X86::FNSTCW16m)), OrigCWFrameIdx);

    // Load the old value of the control word...
    Register OldCW = MF->getRegInfo().createVirtualRegister(&X86::GR32RegClass);
    addFrameReference(BuildMI(*BB, MI, DL, TII->get(X86::MOVZX32rm16), OldCW),
                      OrigCWFrameIdx);

    // OR 0b11 into bit 10 and 11. 0b11 is the encoding for round toward zero.
    Register NewCW = MF->getRegInfo().createVirtualRegister(&X86::GR32RegClass);
    BuildMI(*BB, MI, DL, TII->get(X86::OR32ri), NewCW)
      .addReg(OldCW, RegState::Kill).addImm(0xC00);

    // Extract to 16 bits.
    Register NewCW16 =
        MF->getRegInfo().createVirtualRegister(&X86::GR16RegClass);
    BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), NewCW16)
      .addReg(NewCW, RegState::Kill, X86::sub_16bit);

    // Prepare memory for FLDCW.
    int NewCWFrameIdx = MF->getFrameInfo().CreateStackObject(2, 2, false);
    addFrameReference(BuildMI(*BB, MI, DL, TII->get(X86::MOV16mr)),
                      NewCWFrameIdx)
      .addReg(NewCW16, RegState::Kill);

    // Reload the modified control word now...
    addFrameReference(BuildMI(*BB, MI, DL,
                              TII->get(X86::FLDCW16m)), NewCWFrameIdx);

    // Get the X86 opcode to use.
    unsigned Opc;
    switch (MI.getOpcode()) {
    default: llvm_unreachable("illegal opcode!");
    case X86::FP32_TO_INT16_IN_MEM: Opc = X86::IST_Fp16m32; break;
    case X86::FP32_TO_INT32_IN_MEM: Opc = X86::IST_Fp32m32; break;
    case X86::FP32_TO_INT64_IN_MEM: Opc = X86::IST_Fp64m32; break;
    case X86::FP64_TO_INT16_IN_MEM: Opc = X86::IST_Fp16m64; break;
    case X86::FP64_TO_INT32_IN_MEM: Opc = X86::IST_Fp32m64; break;
    case X86::FP64_TO_INT64_IN_MEM: Opc = X86::IST_Fp64m64; break;
    case X86::FP80_TO_INT16_IN_MEM: Opc = X86::IST_Fp16m80; break;
    case X86::FP80_TO_INT32_IN_MEM: Opc = X86::IST_Fp32m80; break;
    case X86::FP80_TO_INT64_IN_MEM: Opc = X86::IST_Fp64m80; break;
    }

    X86AddressMode AM = getAddressFromInstr(&MI, 0);
    addFullAddress(BuildMI(*BB, MI, DL, TII->get(Opc)), AM)
        .addReg(MI.getOperand(X86::AddrNumOperands).getReg());

    // Reload the original control word now.
    addFrameReference(BuildMI(*BB, MI, DL,
                              TII->get(X86::FLDCW16m)), OrigCWFrameIdx);

    MI.eraseFromParent(); // The pseudo instruction is gone now.
    return BB;
  }

  // xbegin
  case X86::XBEGIN:
    return emitXBegin(MI, BB, Subtarget.getInstrInfo());

  case X86::VASTART_SAVE_XMM_REGS:
    return EmitVAStartSaveXMMRegsWithCustomInserter(MI, BB);

  case X86::VAARG_64:
    return EmitVAARG64WithCustomInserter(MI, BB);

  case X86::EH_SjLj_SetJmp32:
  case X86::EH_SjLj_SetJmp64:
    return emitEHSjLjSetJmp(MI, BB);

  case X86::EH_SjLj_LongJmp32:
  case X86::EH_SjLj_LongJmp64:
    return emitEHSjLjLongJmp(MI, BB);

  case X86::Int_eh_sjlj_setup_dispatch:
    return EmitSjLjDispatchBlock(MI, BB);

  case TargetOpcode::STATEPOINT:
    // As an implementation detail, STATEPOINT shares the STACKMAP format at
    // this point in the process.  We diverge later.
    return emitPatchPoint(MI, BB);

  case TargetOpcode::STACKMAP:
  case TargetOpcode::PATCHPOINT:
    return emitPatchPoint(MI, BB);

  case TargetOpcode::PATCHABLE_EVENT_CALL:
    return emitXRayCustomEvent(MI, BB);

  case TargetOpcode::PATCHABLE_TYPED_EVENT_CALL:
    return emitXRayTypedEvent(MI, BB);

  case X86::LCMPXCHG8B: {
    const X86RegisterInfo *TRI = Subtarget.getRegisterInfo();
    // In addition to 4 E[ABCD] registers implied by encoding, CMPXCHG8B
    // requires a memory operand. If it happens that current architecture is
    // i686 and for current function we need a base pointer
    // - which is ESI for i686 - register allocator would not be able to
    // allocate registers for an address in form of X(%reg, %reg, Y)
    // - there never would be enough unreserved registers during regalloc
    // (without the need for base ptr the only option would be X(%edi, %esi, Y).
    // We are giving a hand to register allocator by precomputing the address in
    // a new vreg using LEA.

    // If it is not i686 or there is no base pointer - nothing to do here.
    if (!Subtarget.is32Bit() || !TRI->hasBasePointer(*MF))
      return BB;

    // Even though this code does not necessarily needs the base pointer to
    // be ESI, we check for that. The reason: if this assert fails, there are
    // some changes happened in the compiler base pointer handling, which most
    // probably have to be addressed somehow here.
    assert(TRI->getBaseRegister() == X86::ESI &&
           "LCMPXCHG8B custom insertion for i686 is written with X86::ESI as a "
           "base pointer in mind");

    MachineRegisterInfo &MRI = MF->getRegInfo();
    MVT SPTy = getPointerTy(MF->getDataLayout());
    const TargetRegisterClass *AddrRegClass = getRegClassFor(SPTy);
    Register computedAddrVReg = MRI.createVirtualRegister(AddrRegClass);

    X86AddressMode AM = getAddressFromInstr(&MI, 0);
    // Regalloc does not need any help when the memory operand of CMPXCHG8B
    // does not use index register.
    if (AM.IndexReg == X86::NoRegister)
      return BB;

    // After X86TargetLowering::ReplaceNodeResults CMPXCHG8B is glued to its
    // four operand definitions that are E[ABCD] registers. We skip them and
    // then insert the LEA.
    MachineBasicBlock::reverse_iterator RMBBI(MI.getReverseIterator());
    while (RMBBI != BB->rend() && (RMBBI->definesRegister(X86::EAX) ||
                                   RMBBI->definesRegister(X86::EBX) ||
                                   RMBBI->definesRegister(X86::ECX) ||
                                   RMBBI->definesRegister(X86::EDX))) {
      ++RMBBI;
    }
    MachineBasicBlock::iterator MBBI(RMBBI);
    addFullAddress(
        BuildMI(*BB, *MBBI, DL, TII->get(X86::LEA32r), computedAddrVReg), AM);

    setDirectAddressInInstr(&MI, 0, computedAddrVReg);

    return BB;
  }
  case X86::LCMPXCHG16B:
    return BB;
  case X86::LCMPXCHG8B_SAVE_EBX:
  case X86::LCMPXCHG16B_SAVE_RBX: {
    unsigned BasePtr =
        MI.getOpcode() == X86::LCMPXCHG8B_SAVE_EBX ? X86::EBX : X86::RBX;
    if (!BB->isLiveIn(BasePtr))
      BB->addLiveIn(BasePtr);
    return BB;
  }
  }
}

//===----------------------------------------------------------------------===//
//                           X86 Optimization Hooks
//===----------------------------------------------------------------------===//

bool
X86TargetLowering::targetShrinkDemandedConstant(SDValue Op,
                                                const APInt &Demanded,
                                                TargetLoweringOpt &TLO) const {
  // Only optimize Ands to prevent shrinking a constant that could be
  // matched by movzx.
  if (Op.getOpcode() != ISD::AND)
    return false;

  EVT VT = Op.getValueType();

  // Ignore vectors.
  if (VT.isVector())
    return false;

  unsigned Size = VT.getSizeInBits();

  // Make sure the RHS really is a constant.
  ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1));
  if (!C)
    return false;

  const APInt &Mask = C->getAPIntValue();

  // Clear all non-demanded bits initially.
  APInt ShrunkMask = Mask & Demanded;

  // Find the width of the shrunk mask.
  unsigned Width = ShrunkMask.getActiveBits();

  // If the mask is all 0s there's nothing to do here.
  if (Width == 0)
    return false;

  // Find the next power of 2 width, rounding up to a byte.
  Width = PowerOf2Ceil(std::max(Width, 8U));
  // Truncate the width to size to handle illegal types.
  Width = std::min(Width, Size);

  // Calculate a possible zero extend mask for this constant.
  APInt ZeroExtendMask = APInt::getLowBitsSet(Size, Width);

  // If we aren't changing the mask, just return true to keep it and prevent
  // the caller from optimizing.
  if (ZeroExtendMask == Mask)
    return true;

  // Make sure the new mask can be represented by a combination of mask bits
  // and non-demanded bits.
  if (!ZeroExtendMask.isSubsetOf(Mask | ~Demanded))
    return false;

  // Replace the constant with the zero extend mask.
  SDLoc DL(Op);
  SDValue NewC = TLO.DAG.getConstant(ZeroExtendMask, DL, VT);
  SDValue NewOp = TLO.DAG.getNode(ISD::AND, DL, VT, Op.getOperand(0), NewC);
  return TLO.CombineTo(Op, NewOp);
}

void X86TargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
                                                      KnownBits &Known,
                                                      const APInt &DemandedElts,
                                                      const SelectionDAG &DAG,
                                                      unsigned Depth) const {
  unsigned BitWidth = Known.getBitWidth();
  unsigned Opc = Op.getOpcode();
  EVT VT = Op.getValueType();
  assert((Opc >= ISD::BUILTIN_OP_END ||
          Opc == ISD::INTRINSIC_WO_CHAIN ||
          Opc == ISD::INTRINSIC_W_CHAIN ||
          Opc == ISD::INTRINSIC_VOID) &&
         "Should use MaskedValueIsZero if you don't know whether Op"
         " is a target node!");

  Known.resetAll();
  switch (Opc) {
  default: break;
  case X86ISD::SETCC:
    Known.Zero.setBitsFrom(1);
    break;
  case X86ISD::MOVMSK: {
    unsigned NumLoBits = Op.getOperand(0).getValueType().getVectorNumElements();
    Known.Zero.setBitsFrom(NumLoBits);
    break;
  }
  case X86ISD::PEXTRB:
  case X86ISD::PEXTRW: {
    SDValue Src = Op.getOperand(0);
    EVT SrcVT = Src.getValueType();
    APInt DemandedElt = APInt::getOneBitSet(SrcVT.getVectorNumElements(),
                                            Op.getConstantOperandVal(1));
    Known = DAG.computeKnownBits(Src, DemandedElt, Depth + 1);
    Known = Known.anyextOrTrunc(BitWidth);
    Known.Zero.setBitsFrom(SrcVT.getScalarSizeInBits());
    break;
  }
  case X86ISD::VSRAI:
  case X86ISD::VSHLI:
  case X86ISD::VSRLI: {
    unsigned ShAmt = Op.getConstantOperandVal(1);
    if (ShAmt >= VT.getScalarSizeInBits()) {
      Known.setAllZero();
      break;
    }

    Known = DAG.computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
    if (Opc == X86ISD::VSHLI) {
      Known.Zero <<= ShAmt;
      Known.One <<= ShAmt;
      // Low bits are known zero.
      Known.Zero.setLowBits(ShAmt);
    } else if (Opc == X86ISD::VSRLI) {
      Known.Zero.lshrInPlace(ShAmt);
      Known.One.lshrInPlace(ShAmt);
      // High bits are known zero.
      Known.Zero.setHighBits(ShAmt);
    } else {
      Known.Zero.ashrInPlace(ShAmt);
      Known.One.ashrInPlace(ShAmt);
    }
    break;
  }
  case X86ISD::PACKUS: {
    // PACKUS is just a truncation if the upper half is zero.
    APInt DemandedLHS, DemandedRHS;
    getPackDemandedElts(VT, DemandedElts, DemandedLHS, DemandedRHS);

    Known.One = APInt::getAllOnesValue(BitWidth * 2);
    Known.Zero = APInt::getAllOnesValue(BitWidth * 2);

    KnownBits Known2;
    if (!!DemandedLHS) {
      Known2 = DAG.computeKnownBits(Op.getOperand(0), DemandedLHS, Depth + 1);
      Known.One &= Known2.One;
      Known.Zero &= Known2.Zero;
    }
    if (!!DemandedRHS) {
      Known2 = DAG.computeKnownBits(Op.getOperand(1), DemandedRHS, Depth + 1);
      Known.One &= Known2.One;
      Known.Zero &= Known2.Zero;
    }

    if (Known.countMinLeadingZeros() < BitWidth)
      Known.resetAll();
    Known = Known.trunc(BitWidth);
    break;
  }
  case X86ISD::ANDNP: {
    KnownBits Known2;
    Known = DAG.computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
    Known2 = DAG.computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);

    // ANDNP = (~X & Y);
    Known.One &= Known2.Zero;
    Known.Zero |= Known2.One;
    break;
  }
  case X86ISD::FOR: {
    KnownBits Known2;
    Known = DAG.computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
    Known2 = DAG.computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);

    // Output known-0 bits are only known if clear in both the LHS & RHS.
    Known.Zero &= Known2.Zero;
    // Output known-1 are known to be set if set in either the LHS | RHS.
    Known.One |= Known2.One;
    break;
  }
  case X86ISD::PSADBW: {
    assert(VT.getScalarType() == MVT::i64 &&
           Op.getOperand(0).getValueType().getScalarType() == MVT::i8 &&
           "Unexpected PSADBW types");

    // PSADBW - fills low 16 bits and zeros upper 48 bits of each i64 result.
    Known.Zero.setBitsFrom(16);
    break;
  }
  case X86ISD::CMOV: {
    Known = DAG.computeKnownBits(Op.getOperand(1), Depth + 1);
    // If we don't know any bits, early out.
    if (Known.isUnknown())
      break;
    KnownBits Known2 = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);

    // Only known if known in both the LHS and RHS.
    Known.One &= Known2.One;
    Known.Zero &= Known2.Zero;
    break;
  }
  case X86ISD::BEXTR: {
    SDValue Op0 = Op.getOperand(0);
    SDValue Op1 = Op.getOperand(1);

    if (auto* Cst1 = dyn_cast<ConstantSDNode>(Op1)) {
      unsigned Shift = Cst1->getAPIntValue().extractBitsAsZExtValue(8, 0);
      unsigned Length = Cst1->getAPIntValue().extractBitsAsZExtValue(8, 8);

      // If the length is 0, the result is 0.
      if (Length == 0) {
        Known.setAllZero();
        break;
      }

      if ((Shift + Length) <= BitWidth) {
        Known = DAG.computeKnownBits(Op0, Depth + 1);
        Known = Known.extractBits(Length, Shift);
        Known = Known.zextOrTrunc(BitWidth);
      }
    }
    break;
  }
  }

  // Handle target shuffles.
  // TODO - use resolveTargetShuffleInputs once we can limit recursive depth.
  if (isTargetShuffle(Opc)) {
    bool IsUnary;
    SmallVector<int, 64> Mask;
    SmallVector<SDValue, 2> Ops;
    if (getTargetShuffleMask(Op.getNode(), VT.getSimpleVT(), true, Ops, Mask,
                             IsUnary)) {
      unsigned NumOps = Ops.size();
      unsigned NumElts = VT.getVectorNumElements();
      if (Mask.size() == NumElts) {
        SmallVector<APInt, 2> DemandedOps(NumOps, APInt(NumElts, 0));
        Known.Zero.setAllBits(); Known.One.setAllBits();
        for (unsigned i = 0; i != NumElts; ++i) {
          if (!DemandedElts[i])
            continue;
          int M = Mask[i];
          if (M == SM_SentinelUndef) {
            // For UNDEF elements, we don't know anything about the common state
            // of the shuffle result.
            Known.resetAll();
            break;
          } else if (M == SM_SentinelZero) {
            Known.One.clearAllBits();
            continue;
          }
          assert(0 <= M && (unsigned)M < (NumOps * NumElts) &&
                 "Shuffle index out of range");

          unsigned OpIdx = (unsigned)M / NumElts;
          unsigned EltIdx = (unsigned)M % NumElts;
          if (Ops[OpIdx].getValueType() != VT) {
            // TODO - handle target shuffle ops with different value types.
            Known.resetAll();
            break;
          }
          DemandedOps[OpIdx].setBit(EltIdx);
        }
        // Known bits are the values that are shared by every demanded element.
        for (unsigned i = 0; i != NumOps && !Known.isUnknown(); ++i) {
          if (!DemandedOps[i])
            continue;
          KnownBits Known2 =
              DAG.computeKnownBits(Ops[i], DemandedOps[i], Depth + 1);
          Known.One &= Known2.One;
          Known.Zero &= Known2.Zero;
        }
      }
    }
  }
}

unsigned X86TargetLowering::ComputeNumSignBitsForTargetNode(
    SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
    unsigned Depth) const {
  EVT VT = Op.getValueType();
  unsigned VTBits = VT.getScalarSizeInBits();
  unsigned Opcode = Op.getOpcode();
  switch (Opcode) {
  case X86ISD::SETCC_CARRY:
    // SETCC_CARRY sets the dest to ~0 for true or 0 for false.
    return VTBits;

  case X86ISD::VTRUNC: {
    SDValue Src = Op.getOperand(0);
    MVT SrcVT = Src.getSimpleValueType();
    unsigned NumSrcBits = SrcVT.getScalarSizeInBits();
    assert(VTBits < NumSrcBits && "Illegal truncation input type");
    APInt DemandedSrc = DemandedElts.zextOrTrunc(SrcVT.getVectorNumElements());
    unsigned Tmp = DAG.ComputeNumSignBits(Src, DemandedSrc, Depth + 1);
    if (Tmp > (NumSrcBits - VTBits))
      return Tmp - (NumSrcBits - VTBits);
    return 1;
  }

  case X86ISD::PACKSS: {
    // PACKSS is just a truncation if the sign bits extend to the packed size.
    APInt DemandedLHS, DemandedRHS;
    getPackDemandedElts(Op.getValueType(), DemandedElts, DemandedLHS,
                        DemandedRHS);

    unsigned SrcBits = Op.getOperand(0).getScalarValueSizeInBits();
    unsigned Tmp0 = SrcBits, Tmp1 = SrcBits;
    if (!!DemandedLHS)
      Tmp0 = DAG.ComputeNumSignBits(Op.getOperand(0), DemandedLHS, Depth + 1);
    if (!!DemandedRHS)
      Tmp1 = DAG.ComputeNumSignBits(Op.getOperand(1), DemandedRHS, Depth + 1);
    unsigned Tmp = std::min(Tmp0, Tmp1);
    if (Tmp > (SrcBits - VTBits))
      return Tmp - (SrcBits - VTBits);
    return 1;
  }

  case X86ISD::VSHLI: {
    SDValue Src = Op.getOperand(0);
    const APInt &ShiftVal = Op.getConstantOperandAPInt(1);
    if (ShiftVal.uge(VTBits))
      return VTBits; // Shifted all bits out --> zero.
    unsigned Tmp = DAG.ComputeNumSignBits(Src, DemandedElts, Depth + 1);
    if (ShiftVal.uge(Tmp))
      return 1; // Shifted all sign bits out --> unknown.
    return Tmp - ShiftVal.getZExtValue();
  }

  case X86ISD::VSRAI: {
    SDValue Src = Op.getOperand(0);
    APInt ShiftVal = Op.getConstantOperandAPInt(1);
    if (ShiftVal.uge(VTBits - 1))
      return VTBits; // Sign splat.
    unsigned Tmp = DAG.ComputeNumSignBits(Src, DemandedElts, Depth + 1);
    ShiftVal += Tmp;
    return ShiftVal.uge(VTBits) ? VTBits : ShiftVal.getZExtValue();
  }

  case X86ISD::PCMPGT:
  case X86ISD::PCMPEQ:
  case X86ISD::CMPP:
  case X86ISD::VPCOM:
  case X86ISD::VPCOMU:
    // Vector compares return zero/all-bits result values.
    return VTBits;

  case X86ISD::ANDNP: {
    unsigned Tmp0 =
        DAG.ComputeNumSignBits(Op.getOperand(0), DemandedElts, Depth + 1);
    if (Tmp0 == 1) return 1; // Early out.
    unsigned Tmp1 =
        DAG.ComputeNumSignBits(Op.getOperand(1), DemandedElts, Depth + 1);
    return std::min(Tmp0, Tmp1);
  }

  case X86ISD::CMOV: {
    unsigned Tmp0 = DAG.ComputeNumSignBits(Op.getOperand(0), Depth+1);
    if (Tmp0 == 1) return 1;  // Early out.
    unsigned Tmp1 = DAG.ComputeNumSignBits(Op.getOperand(1), Depth+1);
    return std::min(Tmp0, Tmp1);
  }
  }

  // Handle target shuffles.
  // TODO - use resolveTargetShuffleInputs once we can limit recursive depth.
  if (isTargetShuffle(Opcode)) {
    bool IsUnary;
    SmallVector<int, 64> Mask;
    SmallVector<SDValue, 2> Ops;
    if (getTargetShuffleMask(Op.getNode(), VT.getSimpleVT(), true, Ops, Mask,
                             IsUnary)) {
      unsigned NumOps = Ops.size();
      unsigned NumElts = VT.getVectorNumElements();
      if (Mask.size() == NumElts) {
        SmallVector<APInt, 2> DemandedOps(NumOps, APInt(NumElts, 0));
        for (unsigned i = 0; i != NumElts; ++i) {
          if (!DemandedElts[i])
            continue;
          int M = Mask[i];
          if (M == SM_SentinelUndef) {
            // For UNDEF elements, we don't know anything about the common state
            // of the shuffle result.
            return 1;
          } else if (M == SM_SentinelZero) {
            // Zero = all sign bits.
            continue;
          }
          assert(0 <= M && (unsigned)M < (NumOps * NumElts) &&
                 "Shuffle index out of range");

          unsigned OpIdx = (unsigned)M / NumElts;
          unsigned EltIdx = (unsigned)M % NumElts;
          if (Ops[OpIdx].getValueType() != VT) {
            // TODO - handle target shuffle ops with different value types.
            return 1;
          }
          DemandedOps[OpIdx].setBit(EltIdx);
        }
        unsigned Tmp0 = VTBits;
        for (unsigned i = 0; i != NumOps && Tmp0 > 1; ++i) {
          if (!DemandedOps[i])
            continue;
          unsigned Tmp1 =
              DAG.ComputeNumSignBits(Ops[i], DemandedOps[i], Depth + 1);
          Tmp0 = std::min(Tmp0, Tmp1);
        }
        return Tmp0;
      }
    }
  }

  // Fallback case.
  return 1;
}

SDValue X86TargetLowering::unwrapAddress(SDValue N) const {
  if (N->getOpcode() == X86ISD::Wrapper || N->getOpcode() == X86ISD::WrapperRIP)
    return N->getOperand(0);
  return N;
}

// Attempt to match a combined shuffle mask against supported unary shuffle
// instructions.
// TODO: Investigate sharing more of this with shuffle lowering.
static bool matchUnaryShuffle(MVT MaskVT, ArrayRef<int> Mask,
                              bool AllowFloatDomain, bool AllowIntDomain,
                              SDValue &V1, const SDLoc &DL, SelectionDAG &DAG,
                              const X86Subtarget &Subtarget, unsigned &Shuffle,
                              MVT &SrcVT, MVT &DstVT) {
  unsigned NumMaskElts = Mask.size();
  unsigned MaskEltSize = MaskVT.getScalarSizeInBits();

  // Match against a VZEXT_MOVL vXi32 zero-extending instruction.
  if (MaskEltSize == 32 && isUndefOrEqual(Mask[0], 0) &&
      isUndefOrZero(Mask[1]) && isUndefInRange(Mask, 2, NumMaskElts - 2)) {
    Shuffle = X86ISD::VZEXT_MOVL;
    SrcVT = DstVT = !Subtarget.hasSSE2() ? MVT::v4f32 : MaskVT;
    return true;
  }

  // Match against a ANY/ZERO_EXTEND_VECTOR_INREG instruction.
  // TODO: Add 512-bit vector support (split AVX512F and AVX512BW).
  if (AllowIntDomain && ((MaskVT.is128BitVector() && Subtarget.hasSSE41()) ||
                         (MaskVT.is256BitVector() && Subtarget.hasInt256()))) {
    unsigned MaxScale = 64 / MaskEltSize;
    for (unsigned Scale = 2; Scale <= MaxScale; Scale *= 2) {
      bool MatchAny = true;
      bool MatchZero = true;
      unsigned NumDstElts = NumMaskElts / Scale;
      for (unsigned i = 0; i != NumDstElts && (MatchAny || MatchZero); ++i) {
        if (!isUndefOrEqual(Mask[i * Scale], (int)i)) {
          MatchAny = MatchZero = false;
          break;
        }
        MatchAny &= isUndefInRange(Mask, (i * Scale) + 1, Scale - 1);
        MatchZero &= isUndefOrZeroInRange(Mask, (i * Scale) + 1, Scale - 1);
      }
      if (MatchAny || MatchZero) {
        assert(MatchZero && "Failed to match zext but matched aext?");
        unsigned SrcSize = std::max(128u, NumDstElts * MaskEltSize);
        MVT ScalarTy = MaskVT.isInteger() ? MaskVT.getScalarType() :
                                            MVT::getIntegerVT(MaskEltSize);
        SrcVT = MVT::getVectorVT(ScalarTy, SrcSize / MaskEltSize);

        if (SrcVT.getSizeInBits() != MaskVT.getSizeInBits())
          V1 = extractSubVector(V1, 0, DAG, DL, SrcSize);

        Shuffle = unsigned(MatchAny ? ISD::ANY_EXTEND : ISD::ZERO_EXTEND);
        if (SrcVT.getVectorNumElements() != NumDstElts)
          Shuffle = getOpcode_EXTEND_VECTOR_INREG(Shuffle);

        DstVT = MVT::getIntegerVT(Scale * MaskEltSize);
        DstVT = MVT::getVectorVT(DstVT, NumDstElts);
        return true;
      }
    }
  }

  // Match against a VZEXT_MOVL instruction, SSE1 only supports 32-bits (MOVSS).
  if (((MaskEltSize == 32) || (MaskEltSize == 64 && Subtarget.hasSSE2())) &&
      isUndefOrEqual(Mask[0], 0) &&
      isUndefOrZeroInRange(Mask, 1, NumMaskElts - 1)) {
    Shuffle = X86ISD::VZEXT_MOVL;
    SrcVT = DstVT = !Subtarget.hasSSE2() ? MVT::v4f32 : MaskVT;
    return true;
  }

  // Check if we have SSE3 which will let us use MOVDDUP etc. The
  // instructions are no slower than UNPCKLPD but has the option to
  // fold the input operand into even an unaligned memory load.
  if (MaskVT.is128BitVector() && Subtarget.hasSSE3() && AllowFloatDomain) {
    if (isTargetShuffleEquivalent(Mask, {0, 0})) {
      Shuffle = X86ISD::MOVDDUP;
      SrcVT = DstVT = MVT::v2f64;
      return true;
    }
    if (isTargetShuffleEquivalent(Mask, {0, 0, 2, 2})) {
      Shuffle = X86ISD::MOVSLDUP;
      SrcVT = DstVT = MVT::v4f32;
      return true;
    }
    if (isTargetShuffleEquivalent(Mask, {1, 1, 3, 3})) {
      Shuffle = X86ISD::MOVSHDUP;
      SrcVT = DstVT = MVT::v4f32;
      return true;
    }
  }

  if (MaskVT.is256BitVector() && AllowFloatDomain) {
    assert(Subtarget.hasAVX() && "AVX required for 256-bit vector shuffles");
    if (isTargetShuffleEquivalent(Mask, {0, 0, 2, 2})) {
      Shuffle = X86ISD::MOVDDUP;
      SrcVT = DstVT = MVT::v4f64;
      return true;
    }
    if (isTargetShuffleEquivalent(Mask, {0, 0, 2, 2, 4, 4, 6, 6})) {
      Shuffle = X86ISD::MOVSLDUP;
      SrcVT = DstVT = MVT::v8f32;
      return true;
    }
    if (isTargetShuffleEquivalent(Mask, {1, 1, 3, 3, 5, 5, 7, 7})) {
      Shuffle = X86ISD::MOVSHDUP;
      SrcVT = DstVT = MVT::v8f32;
      return true;
    }
  }

  if (MaskVT.is512BitVector() && AllowFloatDomain) {
    assert(Subtarget.hasAVX512() &&
           "AVX512 required for 512-bit vector shuffles");
    if (isTargetShuffleEquivalent(Mask, {0, 0, 2, 2, 4, 4, 6, 6})) {
      Shuffle = X86ISD::MOVDDUP;
      SrcVT = DstVT = MVT::v8f64;
      return true;
    }
    if (isTargetShuffleEquivalent(
            Mask, {0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14})) {
      Shuffle = X86ISD::MOVSLDUP;
      SrcVT = DstVT = MVT::v16f32;
      return true;
    }
    if (isTargetShuffleEquivalent(
            Mask, {1, 1, 3, 3, 5, 5, 7, 7, 9, 9, 11, 11, 13, 13, 15, 15})) {
      Shuffle = X86ISD::MOVSHDUP;
      SrcVT = DstVT = MVT::v16f32;
      return true;
    }
  }

  return false;
}

// Attempt to match a combined shuffle mask against supported unary immediate
// permute instructions.
// TODO: Investigate sharing more of this with shuffle lowering.
static bool matchUnaryPermuteShuffle(MVT MaskVT, ArrayRef<int> Mask,
                                     const APInt &Zeroable,
                                     bool AllowFloatDomain, bool AllowIntDomain,
                                     const X86Subtarget &Subtarget,
                                     unsigned &Shuffle, MVT &ShuffleVT,
                                     unsigned &PermuteImm) {
  unsigned NumMaskElts = Mask.size();
  unsigned InputSizeInBits = MaskVT.getSizeInBits();
  unsigned MaskScalarSizeInBits = InputSizeInBits / NumMaskElts;
  MVT MaskEltVT = MVT::getIntegerVT(MaskScalarSizeInBits);

  bool ContainsZeros =
      llvm::any_of(Mask, [](int M) { return M == SM_SentinelZero; });

  // Handle VPERMI/VPERMILPD vXi64/vXi64 patterns.
  if (!ContainsZeros && MaskScalarSizeInBits == 64) {
    // Check for lane crossing permutes.
    if (is128BitLaneCrossingShuffleMask(MaskEltVT, Mask)) {
      // PERMPD/PERMQ permutes within a 256-bit vector (AVX2+).
      if (Subtarget.hasAVX2() && MaskVT.is256BitVector()) {
        Shuffle = X86ISD::VPERMI;
        ShuffleVT = (AllowFloatDomain ? MVT::v4f64 : MVT::v4i64);
        PermuteImm = getV4X86ShuffleImm(Mask);
        return true;
      }
      if (Subtarget.hasAVX512() && MaskVT.is512BitVector()) {
        SmallVector<int, 4> RepeatedMask;
        if (is256BitLaneRepeatedShuffleMask(MVT::v8f64, Mask, RepeatedMask)) {
          Shuffle = X86ISD::VPERMI;
          ShuffleVT = (AllowFloatDomain ? MVT::v8f64 : MVT::v8i64);
          PermuteImm = getV4X86ShuffleImm(RepeatedMask);
          return true;
        }
      }
    } else if (AllowFloatDomain && Subtarget.hasAVX()) {
      // VPERMILPD can permute with a non-repeating shuffle.
      Shuffle = X86ISD::VPERMILPI;
      ShuffleVT = MVT::getVectorVT(MVT::f64, Mask.size());
      PermuteImm = 0;
      for (int i = 0, e = Mask.size(); i != e; ++i) {
        int M = Mask[i];
        if (M == SM_SentinelUndef)
          continue;
        assert(((M / 2) == (i / 2)) && "Out of range shuffle mask index");
        PermuteImm |= (M & 1) << i;
      }
      return true;
    }
  }

  // Handle PSHUFD/VPERMILPI vXi32/vXf32 repeated patterns.
  // AVX introduced the VPERMILPD/VPERMILPS float permutes, before then we
  // had to use 2-input SHUFPD/SHUFPS shuffles (not handled here).
  if ((MaskScalarSizeInBits == 64 || MaskScalarSizeInBits == 32) &&
      !ContainsZeros && (AllowIntDomain || Subtarget.hasAVX())) {
    SmallVector<int, 4> RepeatedMask;
    if (is128BitLaneRepeatedShuffleMask(MaskEltVT, Mask, RepeatedMask)) {
      // Narrow the repeated mask to create 32-bit element permutes.
      SmallVector<int, 4> WordMask = RepeatedMask;
      if (MaskScalarSizeInBits == 64)
        scaleShuffleMask(2, RepeatedMask, WordMask);

      Shuffle = (AllowIntDomain ? X86ISD::PSHUFD : X86ISD::VPERMILPI);
      ShuffleVT = (AllowIntDomain ? MVT::i32 : MVT::f32);
      ShuffleVT = MVT::getVectorVT(ShuffleVT, InputSizeInBits / 32);
      PermuteImm = getV4X86ShuffleImm(WordMask);
      return true;
    }
  }

  // Handle PSHUFLW/PSHUFHW vXi16 repeated patterns.
  if (!ContainsZeros && AllowIntDomain && MaskScalarSizeInBits == 16) {
    SmallVector<int, 4> RepeatedMask;
    if (is128BitLaneRepeatedShuffleMask(MaskEltVT, Mask, RepeatedMask)) {
      ArrayRef<int> LoMask(RepeatedMask.data() + 0, 4);
      ArrayRef<int> HiMask(RepeatedMask.data() + 4, 4);

      // PSHUFLW: permute lower 4 elements only.
      if (isUndefOrInRange(LoMask, 0, 4) &&
          isSequentialOrUndefInRange(HiMask, 0, 4, 4)) {
        Shuffle = X86ISD::PSHUFLW;
        ShuffleVT = MVT::getVectorVT(MVT::i16, InputSizeInBits / 16);
        PermuteImm = getV4X86ShuffleImm(LoMask);
        return true;
      }

      // PSHUFHW: permute upper 4 elements only.
      if (isUndefOrInRange(HiMask, 4, 8) &&
          isSequentialOrUndefInRange(LoMask, 0, 4, 0)) {
        // Offset the HiMask so that we can create the shuffle immediate.
        int OffsetHiMask[4];
        for (int i = 0; i != 4; ++i)
          OffsetHiMask[i] = (HiMask[i] < 0 ? HiMask[i] : HiMask[i] - 4);

        Shuffle = X86ISD::PSHUFHW;
        ShuffleVT = MVT::getVectorVT(MVT::i16, InputSizeInBits / 16);
        PermuteImm = getV4X86ShuffleImm(OffsetHiMask);
        return true;
      }
    }
  }

  // Attempt to match against byte/bit shifts.
  if (AllowIntDomain &&
      ((MaskVT.is128BitVector() && Subtarget.hasSSE2()) ||
       (MaskVT.is256BitVector() && Subtarget.hasAVX2()) ||
       (MaskVT.is512BitVector() && Subtarget.hasAVX512()))) {
    int ShiftAmt = matchShuffleAsShift(ShuffleVT, Shuffle, MaskScalarSizeInBits,
                                       Mask, 0, Zeroable, Subtarget);
    if (0 < ShiftAmt && (!ShuffleVT.is512BitVector() || Subtarget.hasBWI() ||
                         32 <= ShuffleVT.getScalarSizeInBits())) {
      PermuteImm = (unsigned)ShiftAmt;
      return true;
    }
  }

  // Attempt to match against bit rotates.
  if (!ContainsZeros && AllowIntDomain && MaskScalarSizeInBits < 64 &&
      ((MaskVT.is128BitVector() && Subtarget.hasXOP()) ||
       Subtarget.hasAVX512())) {
    int RotateAmt = matchShuffleAsBitRotate(ShuffleVT, MaskScalarSizeInBits,
                                            Subtarget, Mask);
    if (0 < RotateAmt) {
      Shuffle = X86ISD::VROTLI;
      PermuteImm = (unsigned)RotateAmt;
      return true;
    }
  }

  return false;
}

// Attempt to match a combined unary shuffle mask against supported binary
// shuffle instructions.
// TODO: Investigate sharing more of this with shuffle lowering.
static bool matchBinaryShuffle(MVT MaskVT, ArrayRef<int> Mask,
                               bool AllowFloatDomain, bool AllowIntDomain,
                               SDValue &V1, SDValue &V2, const SDLoc &DL,
                               SelectionDAG &DAG, const X86Subtarget &Subtarget,
                               unsigned &Shuffle, MVT &SrcVT, MVT &DstVT,
                               bool IsUnary) {
  unsigned EltSizeInBits = MaskVT.getScalarSizeInBits();

  if (MaskVT.is128BitVector()) {
    if (isTargetShuffleEquivalent(Mask, {0, 0}) && AllowFloatDomain) {
      V2 = V1;
      V1 = (SM_SentinelUndef == Mask[0] ? DAG.getUNDEF(MVT::v4f32) : V1);
      Shuffle = Subtarget.hasSSE2() ? X86ISD::UNPCKL : X86ISD::MOVLHPS;
      SrcVT = DstVT = Subtarget.hasSSE2() ? MVT::v2f64 : MVT::v4f32;
      return true;
    }
    if (isTargetShuffleEquivalent(Mask, {1, 1}) && AllowFloatDomain) {
      V2 = V1;
      Shuffle = Subtarget.hasSSE2() ? X86ISD::UNPCKH : X86ISD::MOVHLPS;
      SrcVT = DstVT = Subtarget.hasSSE2() ? MVT::v2f64 : MVT::v4f32;
      return true;
    }
    if (isTargetShuffleEquivalent(Mask, {0, 3}) && Subtarget.hasSSE2() &&
        (AllowFloatDomain || !Subtarget.hasSSE41())) {
      std::swap(V1, V2);
      Shuffle = X86ISD::MOVSD;
      SrcVT = DstVT = MVT::v2f64;
      return true;
    }
    if (isTargetShuffleEquivalent(Mask, {4, 1, 2, 3}) &&
        (AllowFloatDomain || !Subtarget.hasSSE41())) {
      Shuffle = X86ISD::MOVSS;
      SrcVT = DstVT = MVT::v4f32;
      return true;
    }
  }

  // Attempt to match against either an unary or binary PACKSS/PACKUS shuffle.
  if (((MaskVT == MVT::v8i16 || MaskVT == MVT::v16i8) && Subtarget.hasSSE2()) ||
      ((MaskVT == MVT::v16i16 || MaskVT == MVT::v32i8) && Subtarget.hasInt256()) ||
      ((MaskVT == MVT::v32i16 || MaskVT == MVT::v64i8) && Subtarget.hasBWI())) {
    if (matchShuffleWithPACK(MaskVT, SrcVT, V1, V2, Shuffle, Mask, DAG,
                             Subtarget)) {
      DstVT = MaskVT;
      return true;
    }
  }

  // Attempt to match against either a unary or binary UNPCKL/UNPCKH shuffle.
  if ((MaskVT == MVT::v4f32 && Subtarget.hasSSE1()) ||
      (MaskVT.is128BitVector() && Subtarget.hasSSE2()) ||
      (MaskVT.is256BitVector() && 32 <= EltSizeInBits && Subtarget.hasAVX()) ||
      (MaskVT.is256BitVector() && Subtarget.hasAVX2()) ||
      (MaskVT.is512BitVector() && Subtarget.hasAVX512())) {
    if (matchShuffleWithUNPCK(MaskVT, V1, V2, Shuffle, IsUnary, Mask, DL, DAG,
                              Subtarget)) {
      SrcVT = DstVT = MaskVT;
      if (MaskVT.is256BitVector() && !Subtarget.hasAVX2())
        SrcVT = DstVT = (32 == EltSizeInBits ? MVT::v8f32 : MVT::v4f64);
      return true;
    }
  }

  return false;
}

static bool matchBinaryPermuteShuffle(
    MVT MaskVT, ArrayRef<int> Mask, const APInt &Zeroable,
    bool AllowFloatDomain, bool AllowIntDomain, SDValue &V1, SDValue &V2,
    const SDLoc &DL, SelectionDAG &DAG, const X86Subtarget &Subtarget,
    unsigned &Shuffle, MVT &ShuffleVT, unsigned &PermuteImm) {
  unsigned NumMaskElts = Mask.size();
  unsigned EltSizeInBits = MaskVT.getScalarSizeInBits();

  // Attempt to match against PALIGNR byte rotate.
  if (AllowIntDomain && ((MaskVT.is128BitVector() && Subtarget.hasSSSE3()) ||
                         (MaskVT.is256BitVector() && Subtarget.hasAVX2()) ||
                         (MaskVT.is512BitVector() && Subtarget.hasBWI()))) {
    int ByteRotation = matchShuffleAsByteRotate(MaskVT, V1, V2, Mask);
    if (0 < ByteRotation) {
      Shuffle = X86ISD::PALIGNR;
      ShuffleVT = MVT::getVectorVT(MVT::i8, MaskVT.getSizeInBits() / 8);
      PermuteImm = ByteRotation;
      return true;
    }
  }

  // Attempt to combine to X86ISD::BLENDI.
  if ((NumMaskElts <= 8 && ((Subtarget.hasSSE41() && MaskVT.is128BitVector()) ||
                            (Subtarget.hasAVX() && MaskVT.is256BitVector()))) ||
      (MaskVT == MVT::v16i16 && Subtarget.hasAVX2())) {
    uint64_t BlendMask = 0;
    bool ForceV1Zero = false, ForceV2Zero = false;
    SmallVector<int, 8> TargetMask(Mask.begin(), Mask.end());
    if (matchShuffleAsBlend(V1, V2, TargetMask, Zeroable, ForceV1Zero,
                            ForceV2Zero, BlendMask)) {
      if (MaskVT == MVT::v16i16) {
        // We can only use v16i16 PBLENDW if the lanes are repeated.
        SmallVector<int, 8> RepeatedMask;
        if (isRepeatedTargetShuffleMask(128, MaskVT, TargetMask,
                                        RepeatedMask)) {
          assert(RepeatedMask.size() == 8 &&
                 "Repeated mask size doesn't match!");
          PermuteImm = 0;
          for (int i = 0; i < 8; ++i)
            if (RepeatedMask[i] >= 8)
              PermuteImm |= 1 << i;
          V1 = ForceV1Zero ? getZeroVector(MaskVT, Subtarget, DAG, DL) : V1;
          V2 = ForceV2Zero ? getZeroVector(MaskVT, Subtarget, DAG, DL) : V2;
          Shuffle = X86ISD::BLENDI;
          ShuffleVT = MaskVT;
          return true;
        }
      } else {
        V1 = ForceV1Zero ? getZeroVector(MaskVT, Subtarget, DAG, DL) : V1;
        V2 = ForceV2Zero ? getZeroVector(MaskVT, Subtarget, DAG, DL) : V2;
        PermuteImm = (unsigned)BlendMask;
        Shuffle = X86ISD::BLENDI;
        ShuffleVT = MaskVT;
        return true;
      }
    }
  }

  // Attempt to combine to INSERTPS, but only if it has elements that need to
  // be set to zero.
  if (AllowFloatDomain && EltSizeInBits == 32 && Subtarget.hasSSE41() &&
      MaskVT.is128BitVector() &&
      llvm::any_of(Mask, [](int M) { return M == SM_SentinelZero; }) &&
      matchShuffleAsInsertPS(V1, V2, PermuteImm, Zeroable, Mask, DAG)) {
    Shuffle = X86ISD::INSERTPS;
    ShuffleVT = MVT::v4f32;
    return true;
  }

  // Attempt to combine to SHUFPD.
  if (AllowFloatDomain && EltSizeInBits == 64 &&
      ((MaskVT.is128BitVector() && Subtarget.hasSSE2()) ||
       (MaskVT.is256BitVector() && Subtarget.hasAVX()) ||
       (MaskVT.is512BitVector() && Subtarget.hasAVX512()))) {
    bool ForceV1Zero = false, ForceV2Zero = false;
    if (matchShuffleWithSHUFPD(MaskVT, V1, V2, ForceV1Zero, ForceV2Zero,
                               PermuteImm, Mask, Zeroable)) {
      V1 = ForceV1Zero ? getZeroVector(MaskVT, Subtarget, DAG, DL) : V1;
      V2 = ForceV2Zero ? getZeroVector(MaskVT, Subtarget, DAG, DL) : V2;
      Shuffle = X86ISD::SHUFP;
      ShuffleVT = MVT::getVectorVT(MVT::f64, MaskVT.getSizeInBits() / 64);
      return true;
    }
  }

  // Attempt to combine to SHUFPS.
  if (AllowFloatDomain && EltSizeInBits == 32 &&
      ((MaskVT.is128BitVector() && Subtarget.hasSSE1()) ||
       (MaskVT.is256BitVector() && Subtarget.hasAVX()) ||
       (MaskVT.is512BitVector() && Subtarget.hasAVX512()))) {
    SmallVector<int, 4> RepeatedMask;
    if (isRepeatedTargetShuffleMask(128, MaskVT, Mask, RepeatedMask)) {
      // Match each half of the repeated mask, to determine if its just
      // referencing one of the vectors, is zeroable or entirely undef.
      auto MatchHalf = [&](unsigned Offset, int &S0, int &S1) {
        int M0 = RepeatedMask[Offset];
        int M1 = RepeatedMask[Offset + 1];

        if (isUndefInRange(RepeatedMask, Offset, 2)) {
          return DAG.getUNDEF(MaskVT);
        } else if (isUndefOrZeroInRange(RepeatedMask, Offset, 2)) {
          S0 = (SM_SentinelUndef == M0 ? -1 : 0);
          S1 = (SM_SentinelUndef == M1 ? -1 : 1);
          return getZeroVector(MaskVT, Subtarget, DAG, DL);
        } else if (isUndefOrInRange(M0, 0, 4) && isUndefOrInRange(M1, 0, 4)) {
          S0 = (SM_SentinelUndef == M0 ? -1 : M0 & 3);
          S1 = (SM_SentinelUndef == M1 ? -1 : M1 & 3);
          return V1;
        } else if (isUndefOrInRange(M0, 4, 8) && isUndefOrInRange(M1, 4, 8)) {
          S0 = (SM_SentinelUndef == M0 ? -1 : M0 & 3);
          S1 = (SM_SentinelUndef == M1 ? -1 : M1 & 3);
          return V2;
        }

        return SDValue();
      };

      int ShufMask[4] = {-1, -1, -1, -1};
      SDValue Lo = MatchHalf(0, ShufMask[0], ShufMask[1]);
      SDValue Hi = MatchHalf(2, ShufMask[2], ShufMask[3]);

      if (Lo && Hi) {
        V1 = Lo;
        V2 = Hi;
        Shuffle = X86ISD::SHUFP;
        ShuffleVT = MVT::getVectorVT(MVT::f32, MaskVT.getSizeInBits() / 32);
        PermuteImm = getV4X86ShuffleImm(ShufMask);
        return true;
      }
    }
  }

  // Attempt to combine to INSERTPS more generally if X86ISD::SHUFP failed.
  if (AllowFloatDomain && EltSizeInBits == 32 && Subtarget.hasSSE41() &&
      MaskVT.is128BitVector() &&
      matchShuffleAsInsertPS(V1, V2, PermuteImm, Zeroable, Mask, DAG)) {
    Shuffle = X86ISD::INSERTPS;
    ShuffleVT = MVT::v4f32;
    return true;
  }

  return false;
}

static SDValue combineX86ShuffleChainWithExtract(
    ArrayRef<SDValue> Inputs, SDValue Root, ArrayRef<int> BaseMask, int Depth,
    bool HasVariableMask, bool AllowVariableMask, SelectionDAG &DAG,
    const X86Subtarget &Subtarget);

/// Combine an arbitrary chain of shuffles into a single instruction if
/// possible.
///
/// This is the leaf of the recursive combine below. When we have found some
/// chain of single-use x86 shuffle instructions and accumulated the combined
/// shuffle mask represented by them, this will try to pattern match that mask
/// into either a single instruction if there is a special purpose instruction
/// for this operation, or into a PSHUFB instruction which is a fully general
/// instruction but should only be used to replace chains over a certain depth.
static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
                                      ArrayRef<int> BaseMask, int Depth,
                                      bool HasVariableMask,
                                      bool AllowVariableMask, SelectionDAG &DAG,
                                      const X86Subtarget &Subtarget) {
  assert(!BaseMask.empty() && "Cannot combine an empty shuffle mask!");
  assert((Inputs.size() == 1 || Inputs.size() == 2) &&
         "Unexpected number of shuffle inputs!");

  // Find the inputs that enter the chain. Note that multiple uses are OK
  // here, we're not going to remove the operands we find.
  bool UnaryShuffle = (Inputs.size() == 1);
  SDValue V1 = peekThroughBitcasts(Inputs[0]);
  SDValue V2 = (UnaryShuffle ? DAG.getUNDEF(V1.getValueType())
                             : peekThroughBitcasts(Inputs[1]));

  MVT VT1 = V1.getSimpleValueType();
  MVT VT2 = V2.getSimpleValueType();
  MVT RootVT = Root.getSimpleValueType();
  assert(VT1.getSizeInBits() == RootVT.getSizeInBits() &&
         VT2.getSizeInBits() == RootVT.getSizeInBits() &&
         "Vector size mismatch");

  SDLoc DL(Root);
  SDValue Res;

  unsigned NumBaseMaskElts = BaseMask.size();
  if (NumBaseMaskElts == 1) {
    assert(BaseMask[0] == 0 && "Invalid shuffle index found!");
    return DAG.getBitcast(RootVT, V1);
  }

  unsigned RootSizeInBits = RootVT.getSizeInBits();
  unsigned NumRootElts = RootVT.getVectorNumElements();
  unsigned BaseMaskEltSizeInBits = RootSizeInBits / NumBaseMaskElts;
  bool FloatDomain = VT1.isFloatingPoint() || VT2.isFloatingPoint() ||
                     (RootVT.isFloatingPoint() && Depth >= 1) ||
                     (RootVT.is256BitVector() && !Subtarget.hasAVX2());

  // Don't combine if we are a AVX512/EVEX target and the mask element size
  // is different from the root element size - this would prevent writemasks
  // from being reused.
  // TODO - this currently prevents all lane shuffles from occurring.
  // TODO - check for writemasks usage instead of always preventing combining.
  // TODO - attempt to narrow Mask back to writemask size.
  bool IsEVEXShuffle =
      RootSizeInBits == 512 || (Subtarget.hasVLX() && RootSizeInBits >= 128);

  // Attempt to match a subvector broadcast.
  // shuffle(insert_subvector(undef, sub, 0), undef, 0, 0, 0, 0)
  if (UnaryShuffle &&
      (BaseMaskEltSizeInBits == 128 || BaseMaskEltSizeInBits == 256)) {
    SmallVector<int, 64> BroadcastMask(NumBaseMaskElts, 0);
    if (isTargetShuffleEquivalent(BaseMask, BroadcastMask)) {
      SDValue Src = Inputs[0];
      if (Src.getOpcode() == ISD::INSERT_SUBVECTOR &&
          Src.getOperand(0).isUndef() &&
          Src.getOperand(1).getValueSizeInBits() == BaseMaskEltSizeInBits &&
          MayFoldLoad(Src.getOperand(1)) && isNullConstant(Src.getOperand(2))) {
        return DAG.getBitcast(RootVT, DAG.getNode(X86ISD::SUBV_BROADCAST, DL,
                                                  Src.getValueType(),
                                                  Src.getOperand(1)));
      }
    }
  }

  // Handle 128/256-bit lane shuffles of 512-bit vectors.
  if (RootVT.is512BitVector() &&
      (NumBaseMaskElts == 2 || NumBaseMaskElts == 4)) {
    MVT ShuffleVT = (FloatDomain ? MVT::v8f64 : MVT::v8i64);

    // If the upper subvectors are zeroable, then an extract+insert is more
    // optimal than using X86ISD::SHUF128. The insertion is free, even if it has
    // to zero the upper subvectors.
    if (isUndefOrZeroInRange(BaseMask, 1, NumBaseMaskElts - 1)) {
      if (Depth == 0 && Root.getOpcode() == ISD::INSERT_SUBVECTOR)
        return SDValue(); // Nothing to do!
      assert(isInRange(BaseMask[0], 0, NumBaseMaskElts) &&
             "Unexpected lane shuffle");
      Res = DAG.getBitcast(ShuffleVT, V1);
      unsigned SubIdx = BaseMask[0] * (8 / NumBaseMaskElts);
      bool UseZero = isAnyZero(BaseMask);
      Res = extractSubVector(Res, SubIdx, DAG, DL, BaseMaskEltSizeInBits);
      Res = widenSubVector(Res, UseZero, Subtarget, DAG, DL, RootSizeInBits);
      return DAG.getBitcast(RootVT, Res);
    }

    // TODO - handle AVX512 cases with X86ISD::SHUF128.
  }

  // Handle 128-bit lane shuffles of 256-bit vectors.
  if (RootVT.is256BitVector() && NumBaseMaskElts == 2) {
    MVT ShuffleVT = (FloatDomain ? MVT::v4f64 : MVT::v4i64);

    // If the upper half is zeroable, then an extract+insert is more optimal
    // than using X86ISD::VPERM2X128. The insertion is free, even if it has to
    // zero the upper half.
    if (isUndefOrZero(BaseMask[1])) {
      if (Depth == 0 && Root.getOpcode() == ISD::INSERT_SUBVECTOR)
        return SDValue(); // Nothing to do!
      assert(isInRange(BaseMask[0], 0, 2) && "Unexpected lane shuffle");
      Res = DAG.getBitcast(ShuffleVT, V1);
      Res = extract128BitVector(Res, BaseMask[0] * 2, DAG, DL);
      Res = widenSubVector(Res, BaseMask[1] == SM_SentinelZero, Subtarget, DAG,
                           DL, 256);
      return DAG.getBitcast(RootVT, Res);
    }

    if (Depth == 0 && Root.getOpcode() == X86ISD::VPERM2X128)
      return SDValue(); // Nothing to do!

    // If we have AVX2, prefer to use VPERMQ/VPERMPD for unary shuffles unless
    // we need to use the zeroing feature.
    if (UnaryShuffle &&
        !(Subtarget.hasAVX2() && isUndefOrInRange(BaseMask, 0, 2)) &&
        !isSequentialOrUndefOrZeroInRange(BaseMask, 0, 2, 0)) {
      unsigned PermMask = 0;
      PermMask |= ((BaseMask[0] < 0 ? 0x8 : (BaseMask[0] & 1)) << 0);
      PermMask |= ((BaseMask[1] < 0 ? 0x8 : (BaseMask[1] & 1)) << 4);

      Res = DAG.getBitcast(ShuffleVT, V1);
      Res = DAG.getNode(X86ISD::VPERM2X128, DL, ShuffleVT, Res,
                        DAG.getUNDEF(ShuffleVT),
                        DAG.getTargetConstant(PermMask, DL, MVT::i8));
      return DAG.getBitcast(RootVT, Res);
    }

    // TODO - handle AVX512VL cases with X86ISD::SHUF128.
    if (!UnaryShuffle && !IsEVEXShuffle) {
      assert(llvm::all_of(BaseMask, [](int M) { return 0 <= M && M < 4; }) &&
             "Unexpected shuffle sentinel value");
      // Prefer blends to X86ISD::VPERM2X128.
      if (!((BaseMask[0] == 0 && BaseMask[1] == 3) ||
            (BaseMask[0] == 2 && BaseMask[1] == 1))) {
        unsigned PermMask = 0;
        PermMask |= ((BaseMask[0] & 3) << 0);
        PermMask |= ((BaseMask[1] & 3) << 4);

        Res = DAG.getNode(
            X86ISD::VPERM2X128, DL, ShuffleVT,
            DAG.getBitcast(ShuffleVT, isInRange(BaseMask[0], 0, 2) ? V1 : V2),
            DAG.getBitcast(ShuffleVT, isInRange(BaseMask[1], 0, 2) ? V1 : V2),
            DAG.getTargetConstant(PermMask, DL, MVT::i8));
        return DAG.getBitcast(RootVT, Res);
      }
    }
  }

  // For masks that have been widened to 128-bit elements or more,
  // narrow back down to 64-bit elements.
  SmallVector<int, 64> Mask;
  if (BaseMaskEltSizeInBits > 64) {
    assert((BaseMaskEltSizeInBits % 64) == 0 && "Illegal mask size");
    int MaskScale = BaseMaskEltSizeInBits / 64;
    scaleShuffleMask(MaskScale, BaseMask, Mask);
  } else {
    Mask = SmallVector<int, 64>(BaseMask.begin(), BaseMask.end());
  }

  unsigned NumMaskElts = Mask.size();
  unsigned MaskEltSizeInBits = RootSizeInBits / NumMaskElts;

  // Determine the effective mask value type.
  FloatDomain &= (32 <= MaskEltSizeInBits);
  MVT MaskVT = FloatDomain ? MVT::getFloatingPointVT(MaskEltSizeInBits)
                           : MVT::getIntegerVT(MaskEltSizeInBits);
  MaskVT = MVT::getVectorVT(MaskVT, NumMaskElts);

  // Only allow legal mask types.
  if (!DAG.getTargetLoweringInfo().isTypeLegal(MaskVT))
    return SDValue();

  // Attempt to match the mask against known shuffle patterns.
  MVT ShuffleSrcVT, ShuffleVT;
  unsigned Shuffle, PermuteImm;

  // Which shuffle domains are permitted?
  // Permit domain crossing at higher combine depths.
  // TODO: Should we indicate which domain is preferred if both are allowed?
  bool AllowFloatDomain = FloatDomain || (Depth >= 3);
  bool AllowIntDomain = (!FloatDomain || (Depth >= 3)) && Subtarget.hasSSE2() &&
                        (!MaskVT.is256BitVector() || Subtarget.hasAVX2());

  // Determine zeroable mask elements.
  APInt KnownUndef, KnownZero;
  resolveZeroablesFromTargetShuffle(Mask, KnownUndef, KnownZero);
  APInt Zeroable = KnownUndef | KnownZero;

  if (UnaryShuffle) {
    // If we are shuffling a X86ISD::VZEXT_LOAD then we can use the load
    // directly if we don't shuffle the lower element and we shuffle the upper
    // (zero) elements within themselves.
    if (V1.getOpcode() == X86ISD::VZEXT_LOAD &&
        (cast<MemIntrinsicSDNode>(V1)->getMemoryVT().getScalarSizeInBits() %
         MaskEltSizeInBits) == 0) {
      unsigned Scale =
          cast<MemIntrinsicSDNode>(V1)->getMemoryVT().getScalarSizeInBits() /
          MaskEltSizeInBits;
      ArrayRef<int> HiMask(Mask.data() + Scale, NumMaskElts - Scale);
      if (isSequentialOrUndefInRange(Mask, 0, Scale, 0) &&
          isUndefOrZeroOrInRange(HiMask, Scale, NumMaskElts)) {
        return DAG.getBitcast(RootVT, V1);
      }
    }

    // Attempt to match against broadcast-from-vector.
    // Limit AVX1 to cases where we're loading+broadcasting a scalar element.
    if ((Subtarget.hasAVX2() || (Subtarget.hasAVX() && 32 <= MaskEltSizeInBits))
        && (!IsEVEXShuffle || NumRootElts == NumMaskElts)) {
      SmallVector<int, 64> BroadcastMask(NumMaskElts, 0);
      if (isTargetShuffleEquivalent(Mask, BroadcastMask)) {
        if (V1.getValueType() == MaskVT &&
            V1.getOpcode() == ISD::SCALAR_TO_VECTOR &&
            MayFoldLoad(V1.getOperand(0))) {
          if (Depth == 0 && Root.getOpcode() == X86ISD::VBROADCAST)
            return SDValue(); // Nothing to do!
          Res = V1.getOperand(0);
          Res = DAG.getNode(X86ISD::VBROADCAST, DL, MaskVT, Res);
          return DAG.getBitcast(RootVT, Res);
        }
        if (Subtarget.hasAVX2()) {
          if (Depth == 0 && Root.getOpcode() == X86ISD::VBROADCAST)
            return SDValue(); // Nothing to do!
          Res = DAG.getBitcast(MaskVT, V1);
          Res = DAG.getNode(X86ISD::VBROADCAST, DL, MaskVT, Res);
          return DAG.getBitcast(RootVT, Res);
        }
      }
    }

    SDValue NewV1 = V1; // Save operand in case early exit happens.
    if (matchUnaryShuffle(MaskVT, Mask, AllowFloatDomain, AllowIntDomain, NewV1,
                          DL, DAG, Subtarget, Shuffle, ShuffleSrcVT,
                          ShuffleVT) &&
        (!IsEVEXShuffle || (NumRootElts == ShuffleVT.getVectorNumElements()))) {
      if (Depth == 0 && Root.getOpcode() == Shuffle)
        return SDValue(); // Nothing to do!
      Res = DAG.getBitcast(ShuffleSrcVT, NewV1);
      Res = DAG.getNode(Shuffle, DL, ShuffleVT, Res);
      return DAG.getBitcast(RootVT, Res);
    }

    if (matchUnaryPermuteShuffle(MaskVT, Mask, Zeroable, AllowFloatDomain,
                                 AllowIntDomain, Subtarget, Shuffle, ShuffleVT,
                                 PermuteImm) &&
        (!IsEVEXShuffle || (NumRootElts == ShuffleVT.getVectorNumElements()))) {
      if (Depth == 0 && Root.getOpcode() == Shuffle)
        return SDValue(); // Nothing to do!
      Res = DAG.getBitcast(ShuffleVT, V1);
      Res = DAG.getNode(Shuffle, DL, ShuffleVT, Res,
                        DAG.getTargetConstant(PermuteImm, DL, MVT::i8));
      return DAG.getBitcast(RootVT, Res);
    }
  }

  SDValue NewV1 = V1; // Save operands in case early exit happens.
  SDValue NewV2 = V2;
  if (matchBinaryShuffle(MaskVT, Mask, AllowFloatDomain, AllowIntDomain, NewV1,
                         NewV2, DL, DAG, Subtarget, Shuffle, ShuffleSrcVT,
                         ShuffleVT, UnaryShuffle) &&
      (!IsEVEXShuffle || (NumRootElts == ShuffleVT.getVectorNumElements()))) {
    if (Depth == 0 && Root.getOpcode() == Shuffle)
      return SDValue(); // Nothing to do!
    NewV1 = DAG.getBitcast(ShuffleSrcVT, NewV1);
    NewV2 = DAG.getBitcast(ShuffleSrcVT, NewV2);
    Res = DAG.getNode(Shuffle, DL, ShuffleVT, NewV1, NewV2);
    return DAG.getBitcast(RootVT, Res);
  }

  NewV1 = V1; // Save operands in case early exit happens.
  NewV2 = V2;
  if (matchBinaryPermuteShuffle(
          MaskVT, Mask, Zeroable, AllowFloatDomain, AllowIntDomain, NewV1,
          NewV2, DL, DAG, Subtarget, Shuffle, ShuffleVT, PermuteImm) &&
      (!IsEVEXShuffle || (NumRootElts == ShuffleVT.getVectorNumElements()))) {
    if (Depth == 0 && Root.getOpcode() == Shuffle)
      return SDValue(); // Nothing to do!
    NewV1 = DAG.getBitcast(ShuffleVT, NewV1);
    NewV2 = DAG.getBitcast(ShuffleVT, NewV2);
    Res = DAG.getNode(Shuffle, DL, ShuffleVT, NewV1, NewV2,
                      DAG.getTargetConstant(PermuteImm, DL, MVT::i8));
    return DAG.getBitcast(RootVT, Res);
  }

  // Typically from here on, we need an integer version of MaskVT.
  MVT IntMaskVT = MVT::getIntegerVT(MaskEltSizeInBits);
  IntMaskVT = MVT::getVectorVT(IntMaskVT, NumMaskElts);

  // Annoyingly, SSE4A instructions don't map into the above match helpers.
  if (Subtarget.hasSSE4A() && AllowIntDomain && RootSizeInBits == 128) {
    uint64_t BitLen, BitIdx;
    if (matchShuffleAsEXTRQ(IntMaskVT, V1, V2, Mask, BitLen, BitIdx,
                            Zeroable)) {
      if (Depth == 0 && Root.getOpcode() == X86ISD::EXTRQI)
        return SDValue(); // Nothing to do!
      V1 = DAG.getBitcast(IntMaskVT, V1);
      Res = DAG.getNode(X86ISD::EXTRQI, DL, IntMaskVT, V1,
                        DAG.getTargetConstant(BitLen, DL, MVT::i8),
                        DAG.getTargetConstant(BitIdx, DL, MVT::i8));
      return DAG.getBitcast(RootVT, Res);
    }

    if (matchShuffleAsINSERTQ(IntMaskVT, V1, V2, Mask, BitLen, BitIdx)) {
      if (Depth == 0 && Root.getOpcode() == X86ISD::INSERTQI)
        return SDValue(); // Nothing to do!
      V1 = DAG.getBitcast(IntMaskVT, V1);
      V2 = DAG.getBitcast(IntMaskVT, V2);
      Res = DAG.getNode(X86ISD::INSERTQI, DL, IntMaskVT, V1, V2,
                        DAG.getTargetConstant(BitLen, DL, MVT::i8),
                        DAG.getTargetConstant(BitIdx, DL, MVT::i8));
      return DAG.getBitcast(RootVT, Res);
    }
  }

  // Match shuffle against TRUNCATE patterns.
  if (AllowIntDomain && MaskEltSizeInBits < 64 && Subtarget.hasAVX512()) {
    // Match against a VTRUNC instruction, accounting for src/dst sizes.
    if (matchShuffleAsVTRUNC(ShuffleSrcVT, ShuffleVT, IntMaskVT, Mask, Zeroable,
                             Subtarget)) {
      bool IsTRUNCATE = ShuffleVT.getVectorNumElements() ==
                        ShuffleSrcVT.getVectorNumElements();
      unsigned Opc =
          IsTRUNCATE ? (unsigned)ISD::TRUNCATE : (unsigned)X86ISD::VTRUNC;
      if (Depth == 0 && Root.getOpcode() == Opc)
        return SDValue(); // Nothing to do!
      V1 = DAG.getBitcast(ShuffleSrcVT, V1);
      Res = DAG.getNode(Opc, DL, ShuffleVT, V1);
      if (ShuffleVT.getSizeInBits() < RootSizeInBits)
        Res = widenSubVector(Res, true, Subtarget, DAG, DL, RootSizeInBits);
      return DAG.getBitcast(RootVT, Res);
    }

    // Do we need a more general binary truncation pattern?
    if (RootSizeInBits < 512 &&
        ((RootVT.is256BitVector() && Subtarget.useAVX512Regs()) ||
         (RootVT.is128BitVector() && Subtarget.hasVLX())) &&
        (MaskEltSizeInBits > 8 || Subtarget.hasBWI()) &&
        isSequentialOrUndefInRange(Mask, 0, NumMaskElts, 0, 2)) {
      if (Depth == 0 && Root.getOpcode() == ISD::TRUNCATE)
        return SDValue(); // Nothing to do!
      ShuffleSrcVT = MVT::getIntegerVT(MaskEltSizeInBits * 2);
      ShuffleSrcVT = MVT::getVectorVT(ShuffleSrcVT, NumMaskElts / 2);
      V1 = DAG.getBitcast(ShuffleSrcVT, V1);
      V2 = DAG.getBitcast(ShuffleSrcVT, V2);
      ShuffleSrcVT = MVT::getIntegerVT(MaskEltSizeInBits * 2);
      ShuffleSrcVT = MVT::getVectorVT(ShuffleSrcVT, NumMaskElts);
      Res = DAG.getNode(ISD::CONCAT_VECTORS, DL, ShuffleSrcVT, V1, V2);
      Res = DAG.getNode(ISD::TRUNCATE, DL, IntMaskVT, Res);
      return DAG.getBitcast(RootVT, Res);
    }
  }

  // Don't try to re-form single instruction chains under any circumstances now
  // that we've done encoding canonicalization for them.
  if (Depth < 1)
    return SDValue();

  // Depth threshold above which we can efficiently use variable mask shuffles.
  int VariableShuffleDepth = Subtarget.hasFastVariableShuffle() ? 1 : 2;
  AllowVariableMask &= (Depth >= VariableShuffleDepth) || HasVariableMask;

  bool MaskContainsZeros = isAnyZero(Mask);

  if (is128BitLaneCrossingShuffleMask(MaskVT, Mask)) {
    // If we have a single input lane-crossing shuffle then lower to VPERMV.
    if (UnaryShuffle && AllowVariableMask && !MaskContainsZeros &&
        ((Subtarget.hasAVX2() &&
          (MaskVT == MVT::v8f32 || MaskVT == MVT::v8i32)) ||
         (Subtarget.hasAVX512() &&
          (MaskVT == MVT::v8f64 || MaskVT == MVT::v8i64 ||
           MaskVT == MVT::v16f32 || MaskVT == MVT::v16i32)) ||
         (Subtarget.hasBWI() && MaskVT == MVT::v32i16) ||
         (Subtarget.hasBWI() && Subtarget.hasVLX() && MaskVT == MVT::v16i16) ||
         (Subtarget.hasVBMI() && MaskVT == MVT::v64i8) ||
         (Subtarget.hasVBMI() && Subtarget.hasVLX() && MaskVT == MVT::v32i8))) {
      SDValue VPermMask = getConstVector(Mask, IntMaskVT, DAG, DL, true);
      Res = DAG.getBitcast(MaskVT, V1);
      Res = DAG.getNode(X86ISD::VPERMV, DL, MaskVT, VPermMask, Res);
      return DAG.getBitcast(RootVT, Res);
    }

    // Lower a unary+zero lane-crossing shuffle as VPERMV3 with a zero
    // vector as the second source.
    if (UnaryShuffle && AllowVariableMask &&
        ((Subtarget.hasAVX512() &&
          (MaskVT == MVT::v8f64 || MaskVT == MVT::v8i64 ||
           MaskVT == MVT::v16f32 || MaskVT == MVT::v16i32)) ||
         (Subtarget.hasVLX() &&
          (MaskVT == MVT::v4f64 || MaskVT == MVT::v4i64 ||
           MaskVT == MVT::v8f32 || MaskVT == MVT::v8i32)) ||
         (Subtarget.hasBWI() && MaskVT == MVT::v32i16) ||
         (Subtarget.hasBWI() && Subtarget.hasVLX() && MaskVT == MVT::v16i16) ||
         (Subtarget.hasVBMI() && MaskVT == MVT::v64i8) ||
         (Subtarget.hasVBMI() && Subtarget.hasVLX() && MaskVT == MVT::v32i8))) {
      // Adjust shuffle mask - replace SM_SentinelZero with second source index.
      for (unsigned i = 0; i != NumMaskElts; ++i)
        if (Mask[i] == SM_SentinelZero)
          Mask[i] = NumMaskElts + i;

      SDValue VPermMask = getConstVector(Mask, IntMaskVT, DAG, DL, true);
      Res = DAG.getBitcast(MaskVT, V1);
      SDValue Zero = getZeroVector(MaskVT, Subtarget, DAG, DL);
      Res = DAG.getNode(X86ISD::VPERMV3, DL, MaskVT, Res, VPermMask, Zero);
      return DAG.getBitcast(RootVT, Res);
    }

    // If that failed and either input is extracted then try to combine as a
    // shuffle with the larger type.
    if (SDValue WideShuffle = combineX86ShuffleChainWithExtract(
            Inputs, Root, BaseMask, Depth, HasVariableMask, AllowVariableMask,
            DAG, Subtarget))
      return WideShuffle;

    // If we have a dual input lane-crossing shuffle then lower to VPERMV3.
    if (AllowVariableMask && !MaskContainsZeros &&
        ((Subtarget.hasAVX512() &&
          (MaskVT == MVT::v8f64 || MaskVT == MVT::v8i64 ||
           MaskVT == MVT::v16f32 || MaskVT == MVT::v16i32)) ||
         (Subtarget.hasVLX() &&
          (MaskVT == MVT::v4f64 || MaskVT == MVT::v4i64 ||
           MaskVT == MVT::v8f32 || MaskVT == MVT::v8i32)) ||
         (Subtarget.hasBWI() && MaskVT == MVT::v32i16) ||
         (Subtarget.hasBWI() && Subtarget.hasVLX() && MaskVT == MVT::v16i16) ||
         (Subtarget.hasVBMI() && MaskVT == MVT::v64i8) ||
         (Subtarget.hasVBMI() && Subtarget.hasVLX() && MaskVT == MVT::v32i8))) {
      SDValue VPermMask = getConstVector(Mask, IntMaskVT, DAG, DL, true);
      V1 = DAG.getBitcast(MaskVT, V1);
      V2 = DAG.getBitcast(MaskVT, V2);
      Res = DAG.getNode(X86ISD::VPERMV3, DL, MaskVT, V1, VPermMask, V2);
      return DAG.getBitcast(RootVT, Res);
    }
    return SDValue();
  }

  // See if we can combine a single input shuffle with zeros to a bit-mask,
  // which is much simpler than any shuffle.
  if (UnaryShuffle && MaskContainsZeros && AllowVariableMask &&
      isSequentialOrUndefOrZeroInRange(Mask, 0, NumMaskElts, 0) &&
      DAG.getTargetLoweringInfo().isTypeLegal(MaskVT)) {
    APInt Zero = APInt::getNullValue(MaskEltSizeInBits);
    APInt AllOnes = APInt::getAllOnesValue(MaskEltSizeInBits);
    APInt UndefElts(NumMaskElts, 0);
    SmallVector<APInt, 64> EltBits(NumMaskElts, Zero);
    for (unsigned i = 0; i != NumMaskElts; ++i) {
      int M = Mask[i];
      if (M == SM_SentinelUndef) {
        UndefElts.setBit(i);
        continue;
      }
      if (M == SM_SentinelZero)
        continue;
      EltBits[i] = AllOnes;
    }
    SDValue BitMask = getConstVector(EltBits, UndefElts, MaskVT, DAG, DL);
    Res = DAG.getBitcast(MaskVT, V1);
    unsigned AndOpcode =
        MaskVT.isFloatingPoint() ? unsigned(X86ISD::FAND) : unsigned(ISD::AND);
    Res = DAG.getNode(AndOpcode, DL, MaskVT, Res, BitMask);
    return DAG.getBitcast(RootVT, Res);
  }

  // If we have a single input shuffle with different shuffle patterns in the
  // the 128-bit lanes use the variable mask to VPERMILPS.
  // TODO Combine other mask types at higher depths.
  if (UnaryShuffle && AllowVariableMask && !MaskContainsZeros &&
      ((MaskVT == MVT::v8f32 && Subtarget.hasAVX()) ||
       (MaskVT == MVT::v16f32 && Subtarget.hasAVX512()))) {
    SmallVector<SDValue, 16> VPermIdx;
    for (int M : Mask) {
      SDValue Idx =
          M < 0 ? DAG.getUNDEF(MVT::i32) : DAG.getConstant(M % 4, DL, MVT::i32);
      VPermIdx.push_back(Idx);
    }
    SDValue VPermMask = DAG.getBuildVector(IntMaskVT, DL, VPermIdx);
    Res = DAG.getBitcast(MaskVT, V1);
    Res = DAG.getNode(X86ISD::VPERMILPV, DL, MaskVT, Res, VPermMask);
    return DAG.getBitcast(RootVT, Res);
  }

  // With XOP, binary shuffles of 128/256-bit floating point vectors can combine
  // to VPERMIL2PD/VPERMIL2PS.
  if (AllowVariableMask && Subtarget.hasXOP() &&
      (MaskVT == MVT::v2f64 || MaskVT == MVT::v4f64 || MaskVT == MVT::v4f32 ||
       MaskVT == MVT::v8f32)) {
    // VPERMIL2 Operation.
    // Bits[3] - Match Bit.
    // Bits[2:1] - (Per Lane) PD Shuffle Mask.
    // Bits[2:0] - (Per Lane) PS Shuffle Mask.
    unsigned NumLanes = MaskVT.getSizeInBits() / 128;
    unsigned NumEltsPerLane = NumMaskElts / NumLanes;
    SmallVector<int, 8> VPerm2Idx;
    unsigned M2ZImm = 0;
    for (int M : Mask) {
      if (M == SM_SentinelUndef) {
        VPerm2Idx.push_back(-1);
        continue;
      }
      if (M == SM_SentinelZero) {
        M2ZImm = 2;
        VPerm2Idx.push_back(8);
        continue;
      }
      int Index = (M % NumEltsPerLane) + ((M / NumMaskElts) * NumEltsPerLane);
      Index = (MaskVT.getScalarSizeInBits() == 64 ? Index << 1 : Index);
      VPerm2Idx.push_back(Index);
    }
    V1 = DAG.getBitcast(MaskVT, V1);
    V2 = DAG.getBitcast(MaskVT, V2);
    SDValue VPerm2MaskOp = getConstVector(VPerm2Idx, IntMaskVT, DAG, DL, true);
    Res = DAG.getNode(X86ISD::VPERMIL2, DL, MaskVT, V1, V2, VPerm2MaskOp,
                      DAG.getTargetConstant(M2ZImm, DL, MVT::i8));
    return DAG.getBitcast(RootVT, Res);
  }

  // If we have 3 or more shuffle instructions or a chain involving a variable
  // mask, we can replace them with a single PSHUFB instruction profitably.
  // Intel's manuals suggest only using PSHUFB if doing so replacing 5
  // instructions, but in practice PSHUFB tends to be *very* fast so we're
  // more aggressive.
  if (UnaryShuffle && AllowVariableMask &&
      ((RootVT.is128BitVector() && Subtarget.hasSSSE3()) ||
       (RootVT.is256BitVector() && Subtarget.hasAVX2()) ||
       (RootVT.is512BitVector() && Subtarget.hasBWI()))) {
    SmallVector<SDValue, 16> PSHUFBMask;
    int NumBytes = RootVT.getSizeInBits() / 8;
    int Ratio = NumBytes / NumMaskElts;
    for (int i = 0; i < NumBytes; ++i) {
      int M = Mask[i / Ratio];
      if (M == SM_SentinelUndef) {
        PSHUFBMask.push_back(DAG.getUNDEF(MVT::i8));
        continue;
      }
      if (M == SM_SentinelZero) {
        PSHUFBMask.push_back(DAG.getConstant(255, DL, MVT::i8));
        continue;
      }
      M = Ratio * M + i % Ratio;
      assert((M / 16) == (i / 16) && "Lane crossing detected");
      PSHUFBMask.push_back(DAG.getConstant(M, DL, MVT::i8));
    }
    MVT ByteVT = MVT::getVectorVT(MVT::i8, NumBytes);
    Res = DAG.getBitcast(ByteVT, V1);
    SDValue PSHUFBMaskOp = DAG.getBuildVector(ByteVT, DL, PSHUFBMask);
    Res = DAG.getNode(X86ISD::PSHUFB, DL, ByteVT, Res, PSHUFBMaskOp);
    return DAG.getBitcast(RootVT, Res);
  }

  // With XOP, if we have a 128-bit binary input shuffle we can always combine
  // to VPPERM. We match the depth requirement of PSHUFB - VPPERM is never
  // slower than PSHUFB on targets that support both.
  if (AllowVariableMask && RootVT.is128BitVector() && Subtarget.hasXOP()) {
    // VPPERM Mask Operation
    // Bits[4:0] - Byte Index (0 - 31)
    // Bits[7:5] - Permute Operation (0 - Source byte, 4 - ZERO)
    SmallVector<SDValue, 16> VPPERMMask;
    int NumBytes = 16;
    int Ratio = NumBytes / NumMaskElts;
    for (int i = 0; i < NumBytes; ++i) {
      int M = Mask[i / Ratio];
      if (M == SM_SentinelUndef) {
        VPPERMMask.push_back(DAG.getUNDEF(MVT::i8));
        continue;
      }
      if (M == SM_SentinelZero) {
        VPPERMMask.push_back(DAG.getConstant(128, DL, MVT::i8));
        continue;
      }
      M = Ratio * M + i % Ratio;
      VPPERMMask.push_back(DAG.getConstant(M, DL, MVT::i8));
    }
    MVT ByteVT = MVT::v16i8;
    V1 = DAG.getBitcast(ByteVT, V1);
    V2 = DAG.getBitcast(ByteVT, V2);
    SDValue VPPERMMaskOp = DAG.getBuildVector(ByteVT, DL, VPPERMMask);
    Res = DAG.getNode(X86ISD::VPPERM, DL, ByteVT, V1, V2, VPPERMMaskOp);
    return DAG.getBitcast(RootVT, Res);
  }

  // If that failed and either input is extracted then try to combine as a
  // shuffle with the larger type.
  if (SDValue WideShuffle = combineX86ShuffleChainWithExtract(
          Inputs, Root, BaseMask, Depth, HasVariableMask, AllowVariableMask,
          DAG, Subtarget))
    return WideShuffle;

  // If we have a dual input shuffle then lower to VPERMV3.
  if (!UnaryShuffle && AllowVariableMask && !MaskContainsZeros &&
      ((Subtarget.hasAVX512() &&
        (MaskVT == MVT::v8f64 || MaskVT == MVT::v8i64 ||
         MaskVT == MVT::v16f32 || MaskVT == MVT::v16i32)) ||
       (Subtarget.hasVLX() &&
        (MaskVT == MVT::v2f64 || MaskVT == MVT::v2i64 || MaskVT == MVT::v4f64 ||
         MaskVT == MVT::v4i64 || MaskVT == MVT::v4f32 || MaskVT == MVT::v4i32 ||
         MaskVT == MVT::v8f32 || MaskVT == MVT::v8i32)) ||
       (Subtarget.hasBWI() && MaskVT == MVT::v32i16) ||
       (Subtarget.hasBWI() && Subtarget.hasVLX() &&
        (MaskVT == MVT::v8i16 || MaskVT == MVT::v16i16)) ||
       (Subtarget.hasVBMI() && MaskVT == MVT::v64i8) ||
       (Subtarget.hasVBMI() && Subtarget.hasVLX() &&
        (MaskVT == MVT::v16i8 || MaskVT == MVT::v32i8)))) {
    SDValue VPermMask = getConstVector(Mask, IntMaskVT, DAG, DL, true);
    V1 = DAG.getBitcast(MaskVT, V1);
    V2 = DAG.getBitcast(MaskVT, V2);
    Res = DAG.getNode(X86ISD::VPERMV3, DL, MaskVT, V1, VPermMask, V2);
    return DAG.getBitcast(RootVT, Res);
  }

  // Failed to find any combines.
  return SDValue();
}

// Combine an arbitrary chain of shuffles + extract_subvectors into a single
// instruction if possible.
//
// Wrapper for combineX86ShuffleChain that extends the shuffle mask to a larger
// type size to attempt to combine:
// shuffle(extract_subvector(x,c1),extract_subvector(y,c2),m1)
// -->
// extract_subvector(shuffle(x,y,m2),0)
static SDValue combineX86ShuffleChainWithExtract(
    ArrayRef<SDValue> Inputs, SDValue Root, ArrayRef<int> BaseMask, int Depth,
    bool HasVariableMask, bool AllowVariableMask, SelectionDAG &DAG,
    const X86Subtarget &Subtarget) {
  unsigned NumMaskElts = BaseMask.size();
  unsigned NumInputs = Inputs.size();
  if (NumInputs == 0)
    return SDValue();

  SmallVector<SDValue, 4> WideInputs(Inputs.begin(), Inputs.end());
  SmallVector<unsigned, 4> Offsets(NumInputs, 0);

  // Peek through subvectors.
  // TODO: Support inter-mixed EXTRACT_SUBVECTORs + BITCASTs?
  unsigned WideSizeInBits = WideInputs[0].getValueSizeInBits();
  for (unsigned i = 0; i != NumInputs; ++i) {
    SDValue &Src = WideInputs[i];
    unsigned &Offset = Offsets[i];
    Src = peekThroughBitcasts(Src);
    EVT BaseVT = Src.getValueType();
    while (Src.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
           isa<ConstantSDNode>(Src.getOperand(1))) {
      Offset += Src.getConstantOperandVal(1);
      Src = Src.getOperand(0);
    }
    WideSizeInBits = std::max(WideSizeInBits,
                              (unsigned)Src.getValueSizeInBits());
    assert((Offset % BaseVT.getVectorNumElements()) == 0 &&
           "Unexpected subvector extraction");
    Offset /= BaseVT.getVectorNumElements();
    Offset *= NumMaskElts;
  }

  // Bail if we're always extracting from the lowest subvectors,
  // combineX86ShuffleChain should match this for the current width.
  if (llvm::all_of(Offsets, [](unsigned Offset) { return Offset == 0; }))
    return SDValue();

  EVT RootVT = Root.getValueType();
  unsigned RootSizeInBits = RootVT.getSizeInBits();
  unsigned Scale = WideSizeInBits / RootSizeInBits;
  assert((WideSizeInBits % RootSizeInBits) == 0 &&
         "Unexpected subvector extraction");

  // If the src vector types aren't the same, see if we can extend
  // them to match each other.
  // TODO: Support different scalar types?
  EVT WideSVT = WideInputs[0].getValueType().getScalarType();
  if (llvm::any_of(WideInputs, [&WideSVT, &DAG](SDValue Op) {
        return !DAG.getTargetLoweringInfo().isTypeLegal(Op.getValueType()) ||
               Op.getValueType().getScalarType() != WideSVT;
      }))
    return SDValue();

  for (SDValue &NewInput : WideInputs) {
    assert((WideSizeInBits % NewInput.getValueSizeInBits()) == 0 &&
           "Shuffle vector size mismatch");
    if (WideSizeInBits > NewInput.getValueSizeInBits())
      NewInput = widenSubVector(NewInput, false, Subtarget, DAG,
                                SDLoc(NewInput), WideSizeInBits);
    assert(WideSizeInBits == NewInput.getValueSizeInBits() &&
           "Unexpected subvector extraction");
  }

  // Create new mask for larger type.
  for (unsigned i = 1; i != NumInputs; ++i)
    Offsets[i] += i * Scale * NumMaskElts;

  SmallVector<int, 64> WideMask(BaseMask.begin(), BaseMask.end());
  for (int &M : WideMask) {
    if (M < 0)
      continue;
    M = (M % NumMaskElts) + Offsets[M / NumMaskElts];
  }
  WideMask.append((Scale - 1) * NumMaskElts, SM_SentinelUndef);

  // Remove unused/repeated shuffle source ops.
  resolveTargetShuffleInputsAndMask(WideInputs, WideMask);
  assert(!WideInputs.empty() && "Shuffle with no inputs detected");

  if (WideInputs.size() > 2)
    return SDValue();

  // Increase depth for every upper subvector we've peeked through.
  Depth += count_if(Offsets, [](unsigned Offset) { return Offset > 0; });

  // Attempt to combine wider chain.
  // TODO: Can we use a better Root?
  SDValue WideRoot = WideInputs[0];
  if (SDValue WideShuffle = combineX86ShuffleChain(
          WideInputs, WideRoot, WideMask, Depth, HasVariableMask,
          AllowVariableMask, DAG, Subtarget)) {
    WideShuffle =
        extractSubVector(WideShuffle, 0, DAG, SDLoc(Root), RootSizeInBits);
    return DAG.getBitcast(RootVT, WideShuffle);
  }
  return SDValue();
}

// Attempt to constant fold all of the constant source ops.
// Returns true if the entire shuffle is folded to a constant.
// TODO: Extend this to merge multiple constant Ops and update the mask.
static SDValue combineX86ShufflesConstants(ArrayRef<SDValue> Ops,
                                           ArrayRef<int> Mask, SDValue Root,
                                           bool HasVariableMask,
                                           SelectionDAG &DAG,
                                           const X86Subtarget &Subtarget) {
  MVT VT = Root.getSimpleValueType();

  unsigned SizeInBits = VT.getSizeInBits();
  unsigned NumMaskElts = Mask.size();
  unsigned MaskSizeInBits = SizeInBits / NumMaskElts;
  unsigned NumOps = Ops.size();

  // Extract constant bits from each source op.
  bool OneUseConstantOp = false;
  SmallVector<APInt, 16> UndefEltsOps(NumOps);
  SmallVector<SmallVector<APInt, 16>, 16> RawBitsOps(NumOps);
  for (unsigned i = 0; i != NumOps; ++i) {
    SDValue SrcOp = Ops[i];
    OneUseConstantOp |= SrcOp.hasOneUse();
    if (!getTargetConstantBitsFromNode(SrcOp, MaskSizeInBits, UndefEltsOps[i],
                                       RawBitsOps[i]))
      return SDValue();
  }

  // Only fold if at least one of the constants is only used once or
  // the combined shuffle has included a variable mask shuffle, this
  // is to avoid constant pool bloat.
  if (!OneUseConstantOp && !HasVariableMask)
    return SDValue();

  // Shuffle the constant bits according to the mask.
  APInt UndefElts(NumMaskElts, 0);
  APInt ZeroElts(NumMaskElts, 0);
  APInt ConstantElts(NumMaskElts, 0);
  SmallVector<APInt, 8> ConstantBitData(NumMaskElts,
                                        APInt::getNullValue(MaskSizeInBits));
  for (unsigned i = 0; i != NumMaskElts; ++i) {
    int M = Mask[i];
    if (M == SM_SentinelUndef) {
      UndefElts.setBit(i);
      continue;
    } else if (M == SM_SentinelZero) {
      ZeroElts.setBit(i);
      continue;
    }
    assert(0 <= M && M < (int)(NumMaskElts * NumOps));

    unsigned SrcOpIdx = (unsigned)M / NumMaskElts;
    unsigned SrcMaskIdx = (unsigned)M % NumMaskElts;

    auto &SrcUndefElts = UndefEltsOps[SrcOpIdx];
    if (SrcUndefElts[SrcMaskIdx]) {
      UndefElts.setBit(i);
      continue;
    }

    auto &SrcEltBits = RawBitsOps[SrcOpIdx];
    APInt &Bits = SrcEltBits[SrcMaskIdx];
    if (!Bits) {
      ZeroElts.setBit(i);
      continue;
    }

    ConstantElts.setBit(i);
    ConstantBitData[i] = Bits;
  }
  assert((UndefElts | ZeroElts | ConstantElts).isAllOnesValue());

  // Create the constant data.
  MVT MaskSVT;
  if (VT.isFloatingPoint() && (MaskSizeInBits == 32 || MaskSizeInBits == 64))
    MaskSVT = MVT::getFloatingPointVT(MaskSizeInBits);
  else
    MaskSVT = MVT::getIntegerVT(MaskSizeInBits);

  MVT MaskVT = MVT::getVectorVT(MaskSVT, NumMaskElts);

  SDLoc DL(Root);
  SDValue CstOp = getConstVector(ConstantBitData, UndefElts, MaskVT, DAG, DL);
  return DAG.getBitcast(VT, CstOp);
}

/// Fully generic combining of x86 shuffle instructions.
///
/// This should be the last combine run over the x86 shuffle instructions. Once
/// they have been fully optimized, this will recursively consider all chains
/// of single-use shuffle instructions, build a generic model of the cumulative
/// shuffle operation, and check for simpler instructions which implement this
/// operation. We use this primarily for two purposes:
///
/// 1) Collapse generic shuffles to specialized single instructions when
///    equivalent. In most cases, this is just an encoding size win, but
///    sometimes we will collapse multiple generic shuffles into a single
///    special-purpose shuffle.
/// 2) Look for sequences of shuffle instructions with 3 or more total
///    instructions, and replace them with the slightly more expensive SSSE3
///    PSHUFB instruction if available. We do this as the last combining step
///    to ensure we avoid using PSHUFB if we can implement the shuffle with
///    a suitable short sequence of other instructions. The PSHUFB will either
///    use a register or have to read from memory and so is slightly (but only
///    slightly) more expensive than the other shuffle instructions.
///
/// Because this is inherently a quadratic operation (for each shuffle in
/// a chain, we recurse up the chain), the depth is limited to 8 instructions.
/// This should never be an issue in practice as the shuffle lowering doesn't
/// produce sequences of more than 8 instructions.
///
/// FIXME: We will currently miss some cases where the redundant shuffling
/// would simplify under the threshold for PSHUFB formation because of
/// combine-ordering. To fix this, we should do the redundant instruction
/// combining in this recursive walk.
static SDValue combineX86ShufflesRecursively(
    ArrayRef<SDValue> SrcOps, int SrcOpIndex, SDValue Root,
    ArrayRef<int> RootMask, ArrayRef<const SDNode *> SrcNodes, unsigned Depth,
    bool HasVariableMask, bool AllowVariableMask, SelectionDAG &DAG,
    const X86Subtarget &Subtarget) {
  assert(RootMask.size() > 0 &&
         (RootMask.size() > 1 || (RootMask[0] == 0 && SrcOpIndex == 0)) &&
         "Illegal shuffle root mask");

  // Bound the depth of our recursive combine because this is ultimately
  // quadratic in nature.
  const unsigned MaxRecursionDepth = 8;
  if (Depth >= MaxRecursionDepth)
    return SDValue();

  // Directly rip through bitcasts to find the underlying operand.
  SDValue Op = SrcOps[SrcOpIndex];
  Op = peekThroughOneUseBitcasts(Op);

  MVT VT = Op.getSimpleValueType();
  if (!VT.isVector())
    return SDValue(); // Bail if we hit a non-vector.

  assert(Root.getSimpleValueType().isVector() &&
         "Shuffles operate on vector types!");
  assert(VT.getSizeInBits() == Root.getSimpleValueType().getSizeInBits() &&
         "Can only combine shuffles of the same vector register size.");

  // Extract target shuffle mask and resolve sentinels and inputs.
  // TODO - determine Op's demanded elts from RootMask.
  SmallVector<int, 64> OpMask;
  SmallVector<SDValue, 2> OpInputs;
  APInt OpUndef, OpZero;
  APInt OpDemandedElts = APInt::getAllOnesValue(VT.getVectorNumElements());
  bool IsOpVariableMask = isTargetShuffleVariableMask(Op.getOpcode());
  if (!getTargetShuffleInputs(Op, OpDemandedElts, OpInputs, OpMask, OpUndef,
                              OpZero, DAG, Depth, false))
    return SDValue();

  // Shuffle inputs must be the same size as the result.
  if (llvm::any_of(OpInputs, [VT](SDValue Op) {
        return VT.getSizeInBits() != Op.getValueSizeInBits();
      }))
    return SDValue();

  SmallVector<int, 64> Mask;
  SmallVector<SDValue, 16> Ops;

  // We don't need to merge masks if the root is empty.
  bool EmptyRoot = (Depth == 0) && (RootMask.size() == 1);
  if (EmptyRoot) {
    // Only resolve zeros if it will remove an input, otherwise we might end
    // up in an infinite loop.
    bool ResolveKnownZeros = true;
    if (!OpZero.isNullValue()) {
      APInt UsedInputs = APInt::getNullValue(OpInputs.size());
      for (int i = 0, e = OpMask.size(); i != e; ++i) {
        int M = OpMask[i];
        if (OpUndef[i] || OpZero[i] || isUndefOrZero(M))
          continue;
        UsedInputs.setBit(M / OpMask.size());
        if (UsedInputs.isAllOnesValue()) {
          ResolveKnownZeros = false;
          break;
        }
      }
    }
    resolveTargetShuffleFromZeroables(OpMask, OpUndef, OpZero,
                                      ResolveKnownZeros);

    Mask = OpMask;
    Ops.append(OpInputs.begin(), OpInputs.end());
  } else {
    resolveTargetShuffleFromZeroables(OpMask, OpUndef, OpZero);

    // Add the inputs to the Ops list, avoiding duplicates.
    Ops.append(SrcOps.begin(), SrcOps.end());

    auto AddOp = [&Ops](SDValue Input, int InsertionPoint) -> int {
      // Attempt to find an existing match.
      SDValue InputBC = peekThroughBitcasts(Input);
      for (int i = 0, e = Ops.size(); i < e; ++i)
        if (InputBC == peekThroughBitcasts(Ops[i]))
          return i;
      // Match failed - should we replace an existing Op?
      if (InsertionPoint >= 0) {
        Ops[InsertionPoint] = Input;
        return InsertionPoint;
      }
      // Add to the end of the Ops list.
      Ops.push_back(Input);
      return Ops.size() - 1;
    };

    SmallVector<int, 2> OpInputIdx;
    for (SDValue OpInput : OpInputs)
      OpInputIdx.push_back(
          AddOp(OpInput, OpInputIdx.empty() ? SrcOpIndex : -1));

    assert(((RootMask.size() > OpMask.size() &&
             RootMask.size() % OpMask.size() == 0) ||
            (OpMask.size() > RootMask.size() &&
             OpMask.size() % RootMask.size() == 0) ||
            OpMask.size() == RootMask.size()) &&
           "The smaller number of elements must divide the larger.");

    // This function can be performance-critical, so we rely on the power-of-2
    // knowledge that we have about the mask sizes to replace div/rem ops with
    // bit-masks and shifts.
    assert(isPowerOf2_32(RootMask.size()) &&
           "Non-power-of-2 shuffle mask sizes");
    assert(isPowerOf2_32(OpMask.size()) && "Non-power-of-2 shuffle mask sizes");
    unsigned RootMaskSizeLog2 = countTrailingZeros(RootMask.size());
    unsigned OpMaskSizeLog2 = countTrailingZeros(OpMask.size());

    unsigned MaskWidth = std::max<unsigned>(OpMask.size(), RootMask.size());
    unsigned RootRatio =
        std::max<unsigned>(1, OpMask.size() >> RootMaskSizeLog2);
    unsigned OpRatio = std::max<unsigned>(1, RootMask.size() >> OpMaskSizeLog2);
    assert((RootRatio == 1 || OpRatio == 1) &&
           "Must not have a ratio for both incoming and op masks!");

    assert(isPowerOf2_32(MaskWidth) && "Non-power-of-2 shuffle mask sizes");
    assert(isPowerOf2_32(RootRatio) && "Non-power-of-2 shuffle mask sizes");
    assert(isPowerOf2_32(OpRatio) && "Non-power-of-2 shuffle mask sizes");
    unsigned RootRatioLog2 = countTrailingZeros(RootRatio);
    unsigned OpRatioLog2 = countTrailingZeros(OpRatio);

    Mask.resize(MaskWidth, SM_SentinelUndef);

    // Merge this shuffle operation's mask into our accumulated mask. Note that
    // this shuffle's mask will be the first applied to the input, followed by
    // the root mask to get us all the way to the root value arrangement. The
    // reason for this order is that we are recursing up the operation chain.
    for (unsigned i = 0; i < MaskWidth; ++i) {
      unsigned RootIdx = i >> RootRatioLog2;
      if (RootMask[RootIdx] < 0) {
        // This is a zero or undef lane, we're done.
        Mask[i] = RootMask[RootIdx];
        continue;
      }

      unsigned RootMaskedIdx =
          RootRatio == 1
              ? RootMask[RootIdx]
              : (RootMask[RootIdx] << RootRatioLog2) + (i & (RootRatio - 1));

      // Just insert the scaled root mask value if it references an input other
      // than the SrcOp we're currently inserting.
      if ((RootMaskedIdx < (SrcOpIndex * MaskWidth)) ||
          (((SrcOpIndex + 1) * MaskWidth) <= RootMaskedIdx)) {
        Mask[i] = RootMaskedIdx;
        continue;
      }

      RootMaskedIdx = RootMaskedIdx & (MaskWidth - 1);
      unsigned OpIdx = RootMaskedIdx >> OpRatioLog2;
      if (OpMask[OpIdx] < 0) {
        // The incoming lanes are zero or undef, it doesn't matter which ones we
        // are using.
        Mask[i] = OpMask[OpIdx];
        continue;
      }

      // Ok, we have non-zero lanes, map them through to one of the Op's inputs.
      unsigned OpMaskedIdx = OpRatio == 1 ? OpMask[OpIdx]
                                          : (OpMask[OpIdx] << OpRatioLog2) +
                                                (RootMaskedIdx & (OpRatio - 1));

      OpMaskedIdx = OpMaskedIdx & (MaskWidth - 1);
      int InputIdx = OpMask[OpIdx] / (int)OpMask.size();
      assert(0 <= OpInputIdx[InputIdx] && "Unknown target shuffle input");
      OpMaskedIdx += OpInputIdx[InputIdx] * MaskWidth;

      Mask[i] = OpMaskedIdx;
    }
  }

  // Remove unused/repeated shuffle source ops.
  resolveTargetShuffleInputsAndMask(Ops, Mask);

  // Handle the all undef/zero cases early.
  if (all_of(Mask, [](int Idx) { return Idx == SM_SentinelUndef; }))
    return DAG.getUNDEF(Root.getValueType());

  // TODO - should we handle the mixed zero/undef case as well? Just returning
  // a zero mask will lose information on undef elements possibly reducing
  // future combine possibilities.
  if (all_of(Mask, [](int Idx) { return Idx < 0; }))
    return getZeroVector(Root.getSimpleValueType(), Subtarget, DAG,
                         SDLoc(Root));

  assert(!Ops.empty() && "Shuffle with no inputs detected");
  HasVariableMask |= IsOpVariableMask;

  // Update the list of shuffle nodes that have been combined so far.
  SmallVector<const SDNode *, 16> CombinedNodes(SrcNodes.begin(),
                                                SrcNodes.end());
  CombinedNodes.push_back(Op.getNode());

  // See if we can recurse into each shuffle source op (if it's a target
  // shuffle). The source op should only be generally combined if it either has
  // a single use (i.e. current Op) or all its users have already been combined,
  // if not then we can still combine but should prevent generation of variable
  // shuffles to avoid constant pool bloat.
  // Don't recurse if we already have more source ops than we can combine in
  // the remaining recursion depth.
  if (Ops.size() < (MaxRecursionDepth - Depth)) {
    for (int i = 0, e = Ops.size(); i < e; ++i) {
      // For empty roots, we need to resolve zeroable elements before combining
      // them with other shuffles.
      SmallVector<int, 64> ResolvedMask = Mask;
      if (EmptyRoot)
        resolveTargetShuffleFromZeroables(ResolvedMask, OpUndef, OpZero);
      bool AllowVar = false;
      if (Ops[i].getNode()->hasOneUse() ||
          SDNode::areOnlyUsersOf(CombinedNodes, Ops[i].getNode()))
        AllowVar = AllowVariableMask;
      if (SDValue Res = combineX86ShufflesRecursively(
              Ops, i, Root, ResolvedMask, CombinedNodes, Depth + 1,
              HasVariableMask, AllowVar, DAG, Subtarget))
        return Res;
    }
  }

  // Attempt to constant fold all of the constant source ops.
  if (SDValue Cst = combineX86ShufflesConstants(
          Ops, Mask, Root, HasVariableMask, DAG, Subtarget))
    return Cst;

  // We can only combine unary and binary shuffle mask cases.
  if (Ops.size() <= 2) {
    // Minor canonicalization of the accumulated shuffle mask to make it easier
    // to match below. All this does is detect masks with sequential pairs of
    // elements, and shrink them to the half-width mask. It does this in a loop
    // so it will reduce the size of the mask to the minimal width mask which
    // performs an equivalent shuffle.
    SmallVector<int, 64> WidenedMask;
    while (Mask.size() > 1 && canWidenShuffleElements(Mask, WidenedMask)) {
      Mask = std::move(WidenedMask);
    }

    // Canonicalization of binary shuffle masks to improve pattern matching by
    // commuting the inputs.
    if (Ops.size() == 2 && canonicalizeShuffleMaskWithCommute(Mask)) {
      ShuffleVectorSDNode::commuteMask(Mask);
      std::swap(Ops[0], Ops[1]);
    }

    // Finally, try to combine into a single shuffle instruction.
    return combineX86ShuffleChain(Ops, Root, Mask, Depth, HasVariableMask,
                                  AllowVariableMask, DAG, Subtarget);
  }

  // If that failed and any input is extracted then try to combine as a
  // shuffle with the larger type.
  return combineX86ShuffleChainWithExtract(Ops, Root, Mask, Depth,
                                           HasVariableMask, AllowVariableMask,
                                           DAG, Subtarget);
}

/// Helper entry wrapper to combineX86ShufflesRecursively.
static SDValue combineX86ShufflesRecursively(SDValue Op, SelectionDAG &DAG,
                                             const X86Subtarget &Subtarget) {
  return combineX86ShufflesRecursively({Op}, 0, Op, {0}, {}, /*Depth*/ 0,
                                       /*HasVarMask*/ false,
                                       /*AllowVarMask*/ true, DAG, Subtarget);
}

/// Get the PSHUF-style mask from PSHUF node.
///
/// This is a very minor wrapper around getTargetShuffleMask to easy forming v4
/// PSHUF-style masks that can be reused with such instructions.
static SmallVector<int, 4> getPSHUFShuffleMask(SDValue N) {
  MVT VT = N.getSimpleValueType();
  SmallVector<int, 4> Mask;
  SmallVector<SDValue, 2> Ops;
  bool IsUnary;
  bool HaveMask =
      getTargetShuffleMask(N.getNode(), VT, false, Ops, Mask, IsUnary);
  (void)HaveMask;
  assert(HaveMask);

  // If we have more than 128-bits, only the low 128-bits of shuffle mask
  // matter. Check that the upper masks are repeats and remove them.
  if (VT.getSizeInBits() > 128) {
    int LaneElts = 128 / VT.getScalarSizeInBits();
#ifndef NDEBUG
    for (int i = 1, NumLanes = VT.getSizeInBits() / 128; i < NumLanes; ++i)
      for (int j = 0; j < LaneElts; ++j)
        assert(Mask[j] == Mask[i * LaneElts + j] - (LaneElts * i) &&
               "Mask doesn't repeat in high 128-bit lanes!");
#endif
    Mask.resize(LaneElts);
  }

  switch (N.getOpcode()) {
  case X86ISD::PSHUFD:
    return Mask;
  case X86ISD::PSHUFLW:
    Mask.resize(4);
    return Mask;
  case X86ISD::PSHUFHW:
    Mask.erase(Mask.begin(), Mask.begin() + 4);
    for (int &M : Mask)
      M -= 4;
    return Mask;
  default:
    llvm_unreachable("No valid shuffle instruction found!");
  }
}

/// Search for a combinable shuffle across a chain ending in pshufd.
///
/// We walk up the chain and look for a combinable shuffle, skipping over
/// shuffles that we could hoist this shuffle's transformation past without
/// altering anything.
static SDValue
combineRedundantDWordShuffle(SDValue N, MutableArrayRef<int> Mask,
                             SelectionDAG &DAG) {
  assert(N.getOpcode() == X86ISD::PSHUFD &&
         "Called with something other than an x86 128-bit half shuffle!");
  SDLoc DL(N);

  // Walk up a single-use chain looking for a combinable shuffle. Keep a stack
  // of the shuffles in the chain so that we can form a fresh chain to replace
  // this one.
  SmallVector<SDValue, 8> Chain;
  SDValue V = N.getOperand(0);
  for (; V.hasOneUse(); V = V.getOperand(0)) {
    switch (V.getOpcode()) {
    default:
      return SDValue(); // Nothing combined!

    case ISD::BITCAST:
      // Skip bitcasts as we always know the type for the target specific
      // instructions.
      continue;

    case X86ISD::PSHUFD:
      // Found another dword shuffle.
      break;

    case X86ISD::PSHUFLW:
      // Check that the low words (being shuffled) are the identity in the
      // dword shuffle, and the high words are self-contained.
      if (Mask[0] != 0 || Mask[1] != 1 ||
          !(Mask[2] >= 2 && Mask[2] < 4 && Mask[3] >= 2 && Mask[3] < 4))
        return SDValue();

      Chain.push_back(V);
      continue;

    case X86ISD::PSHUFHW:
      // Check that the high words (being shuffled) are the identity in the
      // dword shuffle, and the low words are self-contained.
      if (Mask[2] != 2 || Mask[3] != 3 ||
          !(Mask[0] >= 0 && Mask[0] < 2 && Mask[1] >= 0 && Mask[1] < 2))
        return SDValue();

      Chain.push_back(V);
      continue;

    case X86ISD::UNPCKL:
    case X86ISD::UNPCKH:
      // For either i8 -> i16 or i16 -> i32 unpacks, we can combine a dword
      // shuffle into a preceding word shuffle.
      if (V.getSimpleValueType().getVectorElementType() != MVT::i8 &&
          V.getSimpleValueType().getVectorElementType() != MVT::i16)
        return SDValue();

      // Search for a half-shuffle which we can combine with.
      unsigned CombineOp =
          V.getOpcode() == X86ISD::UNPCKL ? X86ISD::PSHUFLW : X86ISD::PSHUFHW;
      if (V.getOperand(0) != V.getOperand(1) ||
          !V->isOnlyUserOf(V.getOperand(0).getNode()))
        return SDValue();
      Chain.push_back(V);
      V = V.getOperand(0);
      do {
        switch (V.getOpcode()) {
        default:
          return SDValue(); // Nothing to combine.

        case X86ISD::PSHUFLW:
        case X86ISD::PSHUFHW:
          if (V.getOpcode() == CombineOp)
            break;

          Chain.push_back(V);

          LLVM_FALLTHROUGH;
        case ISD::BITCAST:
          V = V.getOperand(0);
          continue;
        }
        break;
      } while (V.hasOneUse());
      break;
    }
    // Break out of the loop if we break out of the switch.
    break;
  }

  if (!V.hasOneUse())
    // We fell out of the loop without finding a viable combining instruction.
    return SDValue();

  // Merge this node's mask and our incoming mask.
  SmallVector<int, 4> VMask = getPSHUFShuffleMask(V);
  for (int &M : Mask)
    M = VMask[M];
  V = DAG.getNode(V.getOpcode(), DL, V.getValueType(), V.getOperand(0),
                  getV4X86ShuffleImm8ForMask(Mask, DL, DAG));

  // Rebuild the chain around this new shuffle.
  while (!Chain.empty()) {
    SDValue W = Chain.pop_back_val();

    if (V.getValueType() != W.getOperand(0).getValueType())
      V = DAG.getBitcast(W.getOperand(0).getValueType(), V);

    switch (W.getOpcode()) {
    default:
      llvm_unreachable("Only PSHUF and UNPCK instructions get here!");

    case X86ISD::UNPCKL:
    case X86ISD::UNPCKH:
      V = DAG.getNode(W.getOpcode(), DL, W.getValueType(), V, V);
      break;

    case X86ISD::PSHUFD:
    case X86ISD::PSHUFLW:
    case X86ISD::PSHUFHW:
      V = DAG.getNode(W.getOpcode(), DL, W.getValueType(), V, W.getOperand(1));
      break;
    }
  }
  if (V.getValueType() != N.getValueType())
    V = DAG.getBitcast(N.getValueType(), V);

  // Return the new chain to replace N.
  return V;
}

// Attempt to commute shufps LHS loads:
// permilps(shufps(load(),x)) --> permilps(shufps(x,load()))
static SDValue combineCommutableSHUFP(SDValue N, MVT VT, const SDLoc &DL,
                                      SelectionDAG &DAG) {
  // TODO: Add vXf64 support.
  if (VT != MVT::v4f32 && VT != MVT::v8f32 && VT != MVT::v16f32)
    return SDValue();

  // SHUFP(LHS, RHS) -> SHUFP(RHS, LHS) iff LHS is foldable + RHS is not.
  auto commuteSHUFP = [&VT, &DL, &DAG](SDValue Parent, SDValue V) {
    if (V.getOpcode() != X86ISD::SHUFP || !Parent->isOnlyUserOf(V.getNode()))
      return SDValue();
    SDValue N0 = V.getOperand(0);
    SDValue N1 = V.getOperand(1);
    unsigned Imm = V.getConstantOperandVal(2);
    if (!MayFoldLoad(peekThroughOneUseBitcasts(N0)) ||
        MayFoldLoad(peekThroughOneUseBitcasts(N1)))
      return SDValue();
    Imm = ((Imm & 0x0F) << 4) | ((Imm & 0xF0) >> 4);
    return DAG.getNode(X86ISD::SHUFP, DL, VT, N1, N0,
                       DAG.getTargetConstant(Imm, DL, MVT::i8));
  };

  switch (N.getOpcode()) {
  case X86ISD::VPERMILPI:
    if (SDValue NewSHUFP = commuteSHUFP(N, N.getOperand(0))) {
      unsigned Imm = N.getConstantOperandVal(1);
      return DAG.getNode(X86ISD::VPERMILPI, DL, VT, NewSHUFP,
                         DAG.getTargetConstant(Imm ^ 0xAA, DL, MVT::i8));
    }
    break;
  case X86ISD::SHUFP: {
    SDValue N0 = N.getOperand(0);
    SDValue N1 = N.getOperand(1);
    unsigned Imm = N.getConstantOperandVal(2);
    if (N0 == N1) {
      if (SDValue NewSHUFP = commuteSHUFP(N, N0))
        return DAG.getNode(X86ISD::SHUFP, DL, VT, NewSHUFP, NewSHUFP,
                           DAG.getTargetConstant(Imm ^ 0xAA, DL, MVT::i8));
    } else if (SDValue NewSHUFP = commuteSHUFP(N, N0)) {
      return DAG.getNode(X86ISD::SHUFP, DL, VT, NewSHUFP, N1,
                         DAG.getTargetConstant(Imm ^ 0x0A, DL, MVT::i8));
    } else if (SDValue NewSHUFP = commuteSHUFP(N, N1)) {
      return DAG.getNode(X86ISD::SHUFP, DL, VT, N0, NewSHUFP,
                         DAG.getTargetConstant(Imm ^ 0xA0, DL, MVT::i8));
    }
    break;
  }
  }

  return SDValue();
}

/// Try to combine x86 target specific shuffles.
static SDValue combineTargetShuffle(SDValue N, SelectionDAG &DAG,
                                    TargetLowering::DAGCombinerInfo &DCI,
                                    const X86Subtarget &Subtarget) {
  SDLoc DL(N);
  MVT VT = N.getSimpleValueType();
  SmallVector<int, 4> Mask;
  unsigned Opcode = N.getOpcode();

  // Combine binary shuffle of 2 similar 'Horizontal' instructions into a
  // single instruction.
  if (VT.getScalarSizeInBits() == 64 &&
      (Opcode == X86ISD::MOVSD || Opcode == X86ISD::UNPCKH ||
       Opcode == X86ISD::UNPCKL)) {
    auto BC0 = peekThroughBitcasts(N.getOperand(0));
    auto BC1 = peekThroughBitcasts(N.getOperand(1));
    EVT VT0 = BC0.getValueType();
    EVT VT1 = BC1.getValueType();
    unsigned Opcode0 = BC0.getOpcode();
    unsigned Opcode1 = BC1.getOpcode();
    if (Opcode0 == Opcode1 && VT0 == VT1 &&
        (Opcode0 == X86ISD::FHADD || Opcode0 == X86ISD::HADD ||
         Opcode0 == X86ISD::FHSUB || Opcode0 == X86ISD::HSUB ||
         Opcode0 == X86ISD::PACKSS || Opcode0 == X86ISD::PACKUS)) {
      SDValue Lo, Hi;
      if (Opcode == X86ISD::MOVSD) {
        Lo = BC1.getOperand(0);
        Hi = BC0.getOperand(1);
      } else {
        Lo = BC0.getOperand(Opcode == X86ISD::UNPCKH ? 1 : 0);
        Hi = BC1.getOperand(Opcode == X86ISD::UNPCKH ? 1 : 0);
      }
      SDValue Horiz = DAG.getNode(Opcode0, DL, VT0, Lo, Hi);
      return DAG.getBitcast(VT, Horiz);
    }
  }

  if (SDValue R = combineCommutableSHUFP(N, VT, DL, DAG))
    return R;

  switch (Opcode) {
  case X86ISD::MOVDDUP: {
    SDValue Src = N.getOperand(0);
    // Turn a 128-bit MOVDDUP of a full vector load into movddup+vzload.
    if (VT == MVT::v2f64 && Src.hasOneUse() &&
        ISD::isNormalLoad(Src.getNode())) {
      LoadSDNode *LN = cast<LoadSDNode>(Src);
      // Unless the load is volatile or atomic.
      if (LN->isSimple()) {
        SDVTList Tys = DAG.getVTList(MVT::v2f64, MVT::Other);
        SDValue Ops[] = { LN->getChain(), LN->getBasePtr() };
        SDValue VZLoad = DAG.getMemIntrinsicNode(
            X86ISD::VZEXT_LOAD, DL, Tys, Ops, MVT::f64, LN->getPointerInfo(),
            LN->getAlign(), LN->getMemOperand()->getFlags());
        SDValue Movddup = DAG.getNode(X86ISD::MOVDDUP, DL, MVT::v2f64, VZLoad);
        DCI.CombineTo(N.getNode(), Movddup);
        DAG.ReplaceAllUsesOfValueWith(SDValue(LN, 1), VZLoad.getValue(1));
        DCI.recursivelyDeleteUnusedNodes(LN);
        return N; // Return N so it doesn't get rechecked!
      }
    }

    return SDValue();
  }
  case X86ISD::VBROADCAST: {
    SDValue Src = N.getOperand(0);
    SDValue BC = peekThroughBitcasts(Src);
    EVT SrcVT = Src.getValueType();
    EVT BCVT = BC.getValueType();

    // If broadcasting from another shuffle, attempt to simplify it.
    // TODO - we really need a general SimplifyDemandedVectorElts mechanism.
    if (isTargetShuffle(BC.getOpcode()) &&
        VT.getScalarSizeInBits() % BCVT.getScalarSizeInBits() == 0) {
      unsigned Scale = VT.getScalarSizeInBits() / BCVT.getScalarSizeInBits();
      SmallVector<int, 16> DemandedMask(BCVT.getVectorNumElements(),
                                        SM_SentinelUndef);
      for (unsigned i = 0; i != Scale; ++i)
        DemandedMask[i] = i;
      if (SDValue Res = combineX86ShufflesRecursively(
              {BC}, 0, BC, DemandedMask, {}, /*Depth*/ 0,
              /*HasVarMask*/ false, /*AllowVarMask*/ true, DAG, Subtarget))
        return DAG.getNode(X86ISD::VBROADCAST, DL, VT,
                           DAG.getBitcast(SrcVT, Res));
    }

    // broadcast(bitcast(src)) -> bitcast(broadcast(src))
    // 32-bit targets have to bitcast i64 to f64, so better to bitcast upward.
    if (Src.getOpcode() == ISD::BITCAST &&
        SrcVT.getScalarSizeInBits() == BCVT.getScalarSizeInBits()) {
      EVT NewVT = EVT::getVectorVT(*DAG.getContext(), BCVT.getScalarType(),
                                   VT.getVectorNumElements());
      return DAG.getBitcast(VT, DAG.getNode(X86ISD::VBROADCAST, DL, NewVT, BC));
    }

    // Reduce broadcast source vector to lowest 128-bits.
    if (SrcVT.getSizeInBits() > 128)
      return DAG.getNode(X86ISD::VBROADCAST, DL, VT,
                         extract128BitVector(Src, 0, DAG, DL));

    // broadcast(scalar_to_vector(x)) -> broadcast(x).
    if (Src.getOpcode() == ISD::SCALAR_TO_VECTOR)
      return DAG.getNode(X86ISD::VBROADCAST, DL, VT, Src.getOperand(0));

    // Share broadcast with the longest vector and extract low subvector (free).
    for (SDNode *User : Src->uses())
      if (User != N.getNode() && User->getOpcode() == X86ISD::VBROADCAST &&
          User->getValueSizeInBits(0) > VT.getSizeInBits()) {
        return extractSubVector(SDValue(User, 0), 0, DAG, DL,
                                VT.getSizeInBits());
      }

    // vbroadcast(scalarload X) -> vbroadcast_load X
    // For float loads, extract other uses of the scalar from the broadcast.
    if (!SrcVT.isVector() && (Src.hasOneUse() || VT.isFloatingPoint()) &&
        ISD::isNormalLoad(Src.getNode())) {
      LoadSDNode *LN = cast<LoadSDNode>(Src);
      SDVTList Tys = DAG.getVTList(VT, MVT::Other);
      SDValue Ops[] = { LN->getChain(), LN->getBasePtr() };
      SDValue BcastLd =
          DAG.getMemIntrinsicNode(X86ISD::VBROADCAST_LOAD, DL, Tys, Ops,
                                  LN->getMemoryVT(), LN->getMemOperand());
      // If the load value is used only by N, replace it via CombineTo N.
      bool NoReplaceExtract = Src.hasOneUse();
      DCI.CombineTo(N.getNode(), BcastLd);
      if (NoReplaceExtract) {
        DAG.ReplaceAllUsesOfValueWith(SDValue(LN, 1), BcastLd.getValue(1));
        DCI.recursivelyDeleteUnusedNodes(LN);
      } else {
        SDValue Scl = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, SrcVT, BcastLd,
                                  DAG.getIntPtrConstant(0, DL));
        DCI.CombineTo(LN, Scl, BcastLd.getValue(1));
      }
      return N; // Return N so it doesn't get rechecked!
    }

    // Due to isTypeDesirableForOp, we won't always shrink a load truncated to
    // i16. So shrink it ourselves if we can make a broadcast_load.
    if (SrcVT == MVT::i16 && Src.getOpcode() == ISD::TRUNCATE &&
        Src.hasOneUse() && Src.getOperand(0).hasOneUse()) {
      assert(Subtarget.hasAVX2() && "Expected AVX2");
      SDValue TruncIn = Src.getOperand(0);

      // If this is a truncate of a non extending load we can just narrow it to
      // use a broadcast_load.
      if (ISD::isNormalLoad(TruncIn.getNode())) {
        LoadSDNode *LN = cast<LoadSDNode>(TruncIn);
        // Unless its volatile or atomic.
        if (LN->isSimple()) {
          SDVTList Tys = DAG.getVTList(VT, MVT::Other);
          SDValue Ops[] = { LN->getChain(), LN->getBasePtr() };
          SDValue BcastLd = DAG.getMemIntrinsicNode(
              X86ISD::VBROADCAST_LOAD, DL, Tys, Ops, MVT::i16,
              LN->getPointerInfo(), LN->getAlign(),
              LN->getMemOperand()->getFlags());
          DCI.CombineTo(N.getNode(), BcastLd);
          DAG.ReplaceAllUsesOfValueWith(SDValue(LN, 1), BcastLd.getValue(1));
          DCI.recursivelyDeleteUnusedNodes(LN);
          return N; // Return N so it doesn't get rechecked!
        }
      }

      // If this is a truncate of an i16 extload, we can directly replace it.
      if (ISD::isUNINDEXEDLoad(Src.getOperand(0).getNode()) &&
          ISD::isEXTLoad(Src.getOperand(0).getNode())) {
        LoadSDNode *LN = cast<LoadSDNode>(Src.getOperand(0));
        if (LN->getMemoryVT().getSizeInBits() == 16) {
          SDVTList Tys = DAG.getVTList(VT, MVT::Other);
          SDValue Ops[] = { LN->getChain(), LN->getBasePtr() };
          SDValue BcastLd =
              DAG.getMemIntrinsicNode(X86ISD::VBROADCAST_LOAD, DL, Tys, Ops,
                                      LN->getMemoryVT(), LN->getMemOperand());
          DCI.CombineTo(N.getNode(), BcastLd);
          DAG.ReplaceAllUsesOfValueWith(SDValue(LN, 1), BcastLd.getValue(1));
          DCI.recursivelyDeleteUnusedNodes(LN);
          return N; // Return N so it doesn't get rechecked!
        }
      }

      // If this is a truncate of load that has been shifted right, we can
      // offset the pointer and use a narrower load.
      if (TruncIn.getOpcode() == ISD::SRL &&
          TruncIn.getOperand(0).hasOneUse() &&
          isa<ConstantSDNode>(TruncIn.getOperand(1)) &&
          ISD::isNormalLoad(TruncIn.getOperand(0).getNode())) {
        LoadSDNode *LN = cast<LoadSDNode>(TruncIn.getOperand(0));
        unsigned ShiftAmt = TruncIn.getConstantOperandVal(1);
        // Make sure the shift amount and the load size are divisible by 16.
        // Don't do this if the load is volatile or atomic.
        if (ShiftAmt % 16 == 0 && TruncIn.getValueSizeInBits() % 16 == 0 &&
            LN->isSimple()) {
          unsigned Offset = ShiftAmt / 8;
          SDVTList Tys = DAG.getVTList(VT, MVT::Other);
          SDValue Ptr = DAG.getMemBasePlusOffset(LN->getBasePtr(), Offset, DL);
          SDValue Ops[] = { LN->getChain(), Ptr };
          SDValue BcastLd = DAG.getMemIntrinsicNode(
              X86ISD::VBROADCAST_LOAD, DL, Tys, Ops, MVT::i16,
              LN->getPointerInfo().getWithOffset(Offset),
              commonAlignment(LN->getAlign(), Offset),
              LN->getMemOperand()->getFlags());
          DCI.CombineTo(N.getNode(), BcastLd);
          DAG.ReplaceAllUsesOfValueWith(SDValue(LN, 1), BcastLd.getValue(1));
          DCI.recursivelyDeleteUnusedNodes(LN);
          return N; // Return N so it doesn't get rechecked!
        }
      }
    }

    // vbroadcast(vzload X) -> vbroadcast_load X
    if (Src.getOpcode() == X86ISD::VZEXT_LOAD && Src.hasOneUse()) {
      MemSDNode *LN = cast<MemIntrinsicSDNode>(Src);
      if (LN->getMemoryVT().getSizeInBits() == VT.getScalarSizeInBits()) {
        SDVTList Tys = DAG.getVTList(VT, MVT::Other);
        SDValue Ops[] = { LN->getChain(), LN->getBasePtr() };
        SDValue BcastLd =
            DAG.getMemIntrinsicNode(X86ISD::VBROADCAST_LOAD, DL, Tys, Ops,
                                    LN->getMemoryVT(), LN->getMemOperand());
        DCI.CombineTo(N.getNode(), BcastLd);
        DAG.ReplaceAllUsesOfValueWith(SDValue(LN, 1), BcastLd.getValue(1));
        DCI.recursivelyDeleteUnusedNodes(LN);
        return N; // Return N so it doesn't get rechecked!
      }
    }

    // vbroadcast(vector load X) -> vbroadcast_load
    if (SrcVT == MVT::v2f64 && Src.hasOneUse() &&
        ISD::isNormalLoad(Src.getNode())) {
      LoadSDNode *LN = cast<LoadSDNode>(Src);
      // Unless the load is volatile or atomic.
      if (LN->isSimple()) {
        SDVTList Tys = DAG.getVTList(VT, MVT::Other);
        SDValue Ops[] = { LN->getChain(), LN->getBasePtr() };
        SDValue BcastLd = DAG.getMemIntrinsicNode(
            X86ISD::VBROADCAST_LOAD, DL, Tys, Ops, MVT::f64,
            LN->getPointerInfo(), LN->getAlign(),
            LN->getMemOperand()->getFlags());
        DCI.CombineTo(N.getNode(), BcastLd);
        DAG.ReplaceAllUsesOfValueWith(SDValue(LN, 1), BcastLd.getValue(1));
        DCI.recursivelyDeleteUnusedNodes(LN);
        return N; // Return N so it doesn't get rechecked!
      }
    }

    return SDValue();
  }
  case X86ISD::BLENDI: {
    SDValue N0 = N.getOperand(0);
    SDValue N1 = N.getOperand(1);

    // blend(bitcast(x),bitcast(y)) -> bitcast(blend(x,y)) to narrower types.
    // TODO: Handle MVT::v16i16 repeated blend mask.
    if (N0.getOpcode() == ISD::BITCAST && N1.getOpcode() == ISD::BITCAST &&
        N0.getOperand(0).getValueType() == N1.getOperand(0).getValueType()) {
      MVT SrcVT = N0.getOperand(0).getSimpleValueType();
      if ((VT.getScalarSizeInBits() % SrcVT.getScalarSizeInBits()) == 0 &&
          SrcVT.getScalarSizeInBits() >= 32) {
        unsigned BlendMask = N.getConstantOperandVal(2);
        unsigned Size = VT.getVectorNumElements();
        unsigned Scale = VT.getScalarSizeInBits() / SrcVT.getScalarSizeInBits();
        BlendMask = scaleVectorShuffleBlendMask(BlendMask, Size, Scale);
        return DAG.getBitcast(
            VT, DAG.getNode(X86ISD::BLENDI, DL, SrcVT, N0.getOperand(0),
                            N1.getOperand(0),
                            DAG.getTargetConstant(BlendMask, DL, MVT::i8)));
      }
    }
    return SDValue();
  }
  case X86ISD::VPERMI: {
    // vpermi(bitcast(x)) -> bitcast(vpermi(x)) for same number of elements.
    // TODO: Remove when we have preferred domains in combineX86ShuffleChain.
    SDValue N0 = N.getOperand(0);
    SDValue N1 = N.getOperand(1);
    unsigned EltSizeInBits = VT.getScalarSizeInBits();
    if (N0.getOpcode() == ISD::BITCAST &&
        N0.getOperand(0).getScalarValueSizeInBits() == EltSizeInBits) {
      SDValue Src = N0.getOperand(0);
      EVT SrcVT = Src.getValueType();
      SDValue Res = DAG.getNode(X86ISD::VPERMI, DL, SrcVT, Src, N1);
      return DAG.getBitcast(VT, Res);
    }
    return SDValue();
  }
  case X86ISD::VPERM2X128: {
    // If both 128-bit values were inserted into high halves of 256-bit values,
    // the shuffle can be reduced to a concatenation of subvectors:
    // vperm2x128 (ins ?, X, C1), (ins ?, Y, C2), 0x31 --> concat X, Y
    // Note: We are only looking for the exact high/high shuffle mask because we
    //       expect to fold other similar patterns before creating this opcode.
    SDValue Ins0 = peekThroughBitcasts(N.getOperand(0));
    SDValue Ins1 = peekThroughBitcasts(N.getOperand(1));
    unsigned Imm = N.getConstantOperandVal(2);
    if (!(Imm == 0x31 &&
          Ins0.getOpcode() == ISD::INSERT_SUBVECTOR &&
          Ins1.getOpcode() == ISD::INSERT_SUBVECTOR &&
          Ins0.getValueType() == Ins1.getValueType() &&
          isa<ConstantSDNode>(Ins0.getOperand(2)) &&
          isa<ConstantSDNode>(Ins1.getOperand(2))))
      return SDValue();

    SDValue X = Ins0.getOperand(1);
    SDValue Y = Ins1.getOperand(1);
    unsigned C1 = Ins0.getConstantOperandVal(2);
    unsigned C2 = Ins1.getConstantOperandVal(2);
    MVT SrcVT = X.getSimpleValueType();
    unsigned SrcElts = SrcVT.getVectorNumElements();
    if (SrcVT != Y.getSimpleValueType() || SrcVT.getSizeInBits() != 128 ||
        C1 != SrcElts || C2 != SrcElts)
      return SDValue();

    return DAG.getBitcast(VT, DAG.getNode(ISD::CONCAT_VECTORS, DL,
                                          Ins1.getValueType(), X, Y));
  }
  case X86ISD::PSHUFD:
  case X86ISD::PSHUFLW:
  case X86ISD::PSHUFHW:
    Mask = getPSHUFShuffleMask(N);
    assert(Mask.size() == 4);
    break;
  case X86ISD::MOVSD:
  case X86ISD::MOVSS: {
    SDValue N0 = N.getOperand(0);
    SDValue N1 = N.getOperand(1);

    // Canonicalize scalar FPOps:
    // MOVS*(N0, OP(N0, N1)) --> MOVS*(N0, SCALAR_TO_VECTOR(OP(N0[0], N1[0])))
    // If commutable, allow OP(N1[0], N0[0]).
    unsigned Opcode1 = N1.getOpcode();
    if (Opcode1 == ISD::FADD || Opcode1 == ISD::FMUL || Opcode1 == ISD::FSUB ||
        Opcode1 == ISD::FDIV) {
      SDValue N10 = N1.getOperand(0);
      SDValue N11 = N1.getOperand(1);
      if (N10 == N0 ||
          (N11 == N0 && (Opcode1 == ISD::FADD || Opcode1 == ISD::FMUL))) {
        if (N10 != N0)
          std::swap(N10, N11);
        MVT SVT = VT.getVectorElementType();
        SDValue ZeroIdx = DAG.getIntPtrConstant(0, DL);
        N10 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, SVT, N10, ZeroIdx);
        N11 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, SVT, N11, ZeroIdx);
        SDValue Scl = DAG.getNode(Opcode1, DL, SVT, N10, N11);
        SDValue SclVec = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VT, Scl);
        return DAG.getNode(Opcode, DL, VT, N0, SclVec);
      }
    }

    return SDValue();
  }
  case X86ISD::INSERTPS: {
    assert(VT == MVT::v4f32 && "INSERTPS ValueType must be MVT::v4f32");
    SDValue Op0 = N.getOperand(0);
    SDValue Op1 = N.getOperand(1);
    SDValue Op2 = N.getOperand(2);
    unsigned InsertPSMask = cast<ConstantSDNode>(Op2)->getZExtValue();
    unsigned SrcIdx = (InsertPSMask >> 6) & 0x3;
    unsigned DstIdx = (InsertPSMask >> 4) & 0x3;
    unsigned ZeroMask = InsertPSMask & 0xF;

    // If we zero out all elements from Op0 then we don't need to reference it.
    if (((ZeroMask | (1u << DstIdx)) == 0xF) && !Op0.isUndef())
      return DAG.getNode(X86ISD::INSERTPS, DL, VT, DAG.getUNDEF(VT), Op1,
                         DAG.getTargetConstant(InsertPSMask, DL, MVT::i8));

    // If we zero out the element from Op1 then we don't need to reference it.
    if ((ZeroMask & (1u << DstIdx)) && !Op1.isUndef())
      return DAG.getNode(X86ISD::INSERTPS, DL, VT, Op0, DAG.getUNDEF(VT),
                         DAG.getTargetConstant(InsertPSMask, DL, MVT::i8));

    // Attempt to merge insertps Op1 with an inner target shuffle node.
    SmallVector<int, 8> TargetMask1;
    SmallVector<SDValue, 2> Ops1;
    APInt KnownUndef1, KnownZero1;
    if (getTargetShuffleAndZeroables(Op1, TargetMask1, Ops1, KnownUndef1,
                                     KnownZero1)) {
      if (KnownUndef1[SrcIdx] || KnownZero1[SrcIdx]) {
        // Zero/UNDEF insertion - zero out element and remove dependency.
        InsertPSMask |= (1u << DstIdx);
        return DAG.getNode(X86ISD::INSERTPS, DL, VT, Op0, DAG.getUNDEF(VT),
                           DAG.getTargetConstant(InsertPSMask, DL, MVT::i8));
      }
      // Update insertps mask srcidx and reference the source input directly.
      int M = TargetMask1[SrcIdx];
      assert(0 <= M && M < 8 && "Shuffle index out of range");
      InsertPSMask = (InsertPSMask & 0x3f) | ((M & 0x3) << 6);
      Op1 = Ops1[M < 4 ? 0 : 1];
      return DAG.getNode(X86ISD::INSERTPS, DL, VT, Op0, Op1,
                         DAG.getTargetConstant(InsertPSMask, DL, MVT::i8));
    }

    // Attempt to merge insertps Op0 with an inner target shuffle node.
    SmallVector<int, 8> TargetMask0;
    SmallVector<SDValue, 2> Ops0;
    APInt KnownUndef0, KnownZero0;
    if (getTargetShuffleAndZeroables(Op0, TargetMask0, Ops0, KnownUndef0,
                                     KnownZero0)) {
      bool Updated = false;
      bool UseInput00 = false;
      bool UseInput01 = false;
      for (int i = 0; i != 4; ++i) {
        if ((InsertPSMask & (1u << i)) || (i == (int)DstIdx)) {
          // No change if element is already zero or the inserted element.
          continue;
        } else if (KnownUndef0[i] || KnownZero0[i]) {
          // If the target mask is undef/zero then we must zero the element.
          InsertPSMask |= (1u << i);
          Updated = true;
          continue;
        }

        // The input vector element must be inline.
        int M = TargetMask0[i];
        if (M != i && M != (i + 4))
          return SDValue();

        // Determine which inputs of the target shuffle we're using.
        UseInput00 |= (0 <= M && M < 4);
        UseInput01 |= (4 <= M);
      }

      // If we're not using both inputs of the target shuffle then use the
      // referenced input directly.
      if (UseInput00 && !UseInput01) {
        Updated = true;
        Op0 = Ops0[0];
      } else if (!UseInput00 && UseInput01) {
        Updated = true;
        Op0 = Ops0[1];
      }

      if (Updated)
        return DAG.getNode(X86ISD::INSERTPS, DL, VT, Op0, Op1,
                           DAG.getTargetConstant(InsertPSMask, DL, MVT::i8));
    }

    // If we're inserting an element from a vbroadcast load, fold the
    // load into the X86insertps instruction. We need to convert the scalar
    // load to a vector and clear the source lane of the INSERTPS control.
    if (Op1.getOpcode() == X86ISD::VBROADCAST_LOAD && Op1.hasOneUse()) {
      auto *MemIntr = cast<MemIntrinsicSDNode>(Op1);
      if (MemIntr->getMemoryVT().getScalarSizeInBits() == 32) {
        SDValue Load = DAG.getLoad(MVT::f32, DL, MemIntr->getChain(),
                                   MemIntr->getBasePtr(),
                                   MemIntr->getMemOperand());
        SDValue Insert = DAG.getNode(X86ISD::INSERTPS, DL, VT, Op0,
                           DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VT,
                                       Load),
                           DAG.getTargetConstant(InsertPSMask & 0x3f, DL, MVT::i8));
        DAG.ReplaceAllUsesOfValueWith(SDValue(MemIntr, 1), Load.getValue(1));
        return Insert;
      }
    }

    return SDValue();
  }
  default:
    return SDValue();
  }

  // Nuke no-op shuffles that show up after combining.
  if (isNoopShuffleMask(Mask))
    return N.getOperand(0);

  // Look for simplifications involving one or two shuffle instructions.
  SDValue V = N.getOperand(0);
  switch (N.getOpcode()) {
  default:
    break;
  case X86ISD::PSHUFLW:
  case X86ISD::PSHUFHW:
    assert(VT.getVectorElementType() == MVT::i16 && "Bad word shuffle type!");

    // See if this reduces to a PSHUFD which is no more expensive and can
    // combine with more operations. Note that it has to at least flip the
    // dwords as otherwise it would have been removed as a no-op.
    if (makeArrayRef(Mask).equals({2, 3, 0, 1})) {
      int DMask[] = {0, 1, 2, 3};
      int DOffset = N.getOpcode() == X86ISD::PSHUFLW ? 0 : 2;
      DMask[DOffset + 0] = DOffset + 1;
      DMask[DOffset + 1] = DOffset + 0;
      MVT DVT = MVT::getVectorVT(MVT::i32, VT.getVectorNumElements() / 2);
      V = DAG.getBitcast(DVT, V);
      V = DAG.getNode(X86ISD::PSHUFD, DL, DVT, V,
                      getV4X86ShuffleImm8ForMask(DMask, DL, DAG));
      return DAG.getBitcast(VT, V);
    }

    // Look for shuffle patterns which can be implemented as a single unpack.
    // FIXME: This doesn't handle the location of the PSHUFD generically, and
    // only works when we have a PSHUFD followed by two half-shuffles.
    if (Mask[0] == Mask[1] && Mask[2] == Mask[3] &&
        (V.getOpcode() == X86ISD::PSHUFLW ||
         V.getOpcode() == X86ISD::PSHUFHW) &&
        V.getOpcode() != N.getOpcode() &&
        V.hasOneUse()) {
      SDValue D = peekThroughOneUseBitcasts(V.getOperand(0));
      if (D.getOpcode() == X86ISD::PSHUFD && D.hasOneUse()) {
        SmallVector<int, 4> VMask = getPSHUFShuffleMask(V);
        SmallVector<int, 4> DMask = getPSHUFShuffleMask(D);
        int NOffset = N.getOpcode() == X86ISD::PSHUFLW ? 0 : 4;
        int VOffset = V.getOpcode() == X86ISD::PSHUFLW ? 0 : 4;
        int WordMask[8];
        for (int i = 0; i < 4; ++i) {
          WordMask[i + NOffset] = Mask[i] + NOffset;
          WordMask[i + VOffset] = VMask[i] + VOffset;
        }
        // Map the word mask through the DWord mask.
        int MappedMask[8];
        for (int i = 0; i < 8; ++i)
          MappedMask[i] = 2 * DMask[WordMask[i] / 2] + WordMask[i] % 2;
        if (makeArrayRef(MappedMask).equals({0, 0, 1, 1, 2, 2, 3, 3}) ||
            makeArrayRef(MappedMask).equals({4, 4, 5, 5, 6, 6, 7, 7})) {
          // We can replace all three shuffles with an unpack.
          V = DAG.getBitcast(VT, D.getOperand(0));
          return DAG.getNode(MappedMask[0] == 0 ? X86ISD::UNPCKL
                                                : X86ISD::UNPCKH,
                             DL, VT, V, V);
        }
      }
    }

    break;

  case X86ISD::PSHUFD:
    if (SDValue NewN = combineRedundantDWordShuffle(N, Mask, DAG))
      return NewN;

    break;
  }

  return SDValue();
}

/// Checks if the shuffle mask takes subsequent elements
/// alternately from two vectors.
/// For example <0, 5, 2, 7> or <8, 1, 10, 3, 12, 5, 14, 7> are both correct.
static bool isAddSubOrSubAddMask(ArrayRef<int> Mask, bool &Op0Even) {

  int ParitySrc[2] = {-1, -1};
  unsigned Size = Mask.size();
  for (unsigned i = 0; i != Size; ++i) {
    int M = Mask[i];
    if (M < 0)
      continue;

    // Make sure we are using the matching element from the input.
    if ((M % Size) != i)
      return false;

    // Make sure we use the same input for all elements of the same parity.
    int Src = M / Size;
    if (ParitySrc[i % 2] >= 0 && ParitySrc[i % 2] != Src)
      return false;
    ParitySrc[i % 2] = Src;
  }

  // Make sure each input is used.
  if (ParitySrc[0] < 0 || ParitySrc[1] < 0 || ParitySrc[0] == ParitySrc[1])
    return false;

  Op0Even = ParitySrc[0] == 0;
  return true;
}

/// Returns true iff the shuffle node \p N can be replaced with ADDSUB(SUBADD)
/// operation. If true is returned then the operands of ADDSUB(SUBADD) operation
/// are written to the parameters \p Opnd0 and \p Opnd1.
///
/// We combine shuffle to ADDSUB(SUBADD) directly on the abstract vector shuffle nodes
/// so it is easier to generically match. We also insert dummy vector shuffle
/// nodes for the operands which explicitly discard the lanes which are unused
/// by this operation to try to flow through the rest of the combiner
/// the fact that they're unused.
static bool isAddSubOrSubAdd(SDNode *N, const X86Subtarget &Subtarget,
                             SelectionDAG &DAG, SDValue &Opnd0, SDValue &Opnd1,
                             bool &IsSubAdd) {

  EVT VT = N->getValueType(0);
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  if (!Subtarget.hasSSE3() || !TLI.isTypeLegal(VT) ||
      !VT.getSimpleVT().isFloatingPoint())
    return false;

  // We only handle target-independent shuffles.
  // FIXME: It would be easy and harmless to use the target shuffle mask
  // extraction tool to support more.
  if (N->getOpcode() != ISD::VECTOR_SHUFFLE)
    return false;

  SDValue V1 = N->getOperand(0);
  SDValue V2 = N->getOperand(1);

  // Make sure we have an FADD and an FSUB.
  if ((V1.getOpcode() != ISD::FADD && V1.getOpcode() != ISD::FSUB) ||
      (V2.getOpcode() != ISD::FADD && V2.getOpcode() != ISD::FSUB) ||
      V1.getOpcode() == V2.getOpcode())
    return false;

  // If there are other uses of these operations we can't fold them.
  if (!V1->hasOneUse() || !V2->hasOneUse())
    return false;

  // Ensure that both operations have the same operands. Note that we can
  // commute the FADD operands.
  SDValue LHS, RHS;
  if (V1.getOpcode() == ISD::FSUB) {
    LHS = V1->getOperand(0); RHS = V1->getOperand(1);
    if ((V2->getOperand(0) != LHS || V2->getOperand(1) != RHS) &&
        (V2->getOperand(0) != RHS || V2->getOperand(1) != LHS))
      return false;
  } else {
    assert(V2.getOpcode() == ISD::FSUB && "Unexpected opcode");
    LHS = V2->getOperand(0); RHS = V2->getOperand(1);
    if ((V1->getOperand(0) != LHS || V1->getOperand(1) != RHS) &&
        (V1->getOperand(0) != RHS || V1->getOperand(1) != LHS))
      return false;
  }

  ArrayRef<int> Mask = cast<ShuffleVectorSDNode>(N)->getMask();
  bool Op0Even;
  if (!isAddSubOrSubAddMask(Mask, Op0Even))
    return false;

  // It's a subadd if the vector in the even parity is an FADD.
  IsSubAdd = Op0Even ? V1->getOpcode() == ISD::FADD
                     : V2->getOpcode() == ISD::FADD;

  Opnd0 = LHS;
  Opnd1 = RHS;
  return true;
}

/// Combine shuffle of two fma nodes into FMAddSub or FMSubAdd.
static SDValue combineShuffleToFMAddSub(SDNode *N,
                                        const X86Subtarget &Subtarget,
                                        SelectionDAG &DAG) {
  // We only handle target-independent shuffles.
  // FIXME: It would be easy and harmless to use the target shuffle mask
  // extraction tool to support more.
  if (N->getOpcode() != ISD::VECTOR_SHUFFLE)
    return SDValue();

  MVT VT = N->getSimpleValueType(0);
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  if (!Subtarget.hasAnyFMA() || !TLI.isTypeLegal(VT))
    return SDValue();

  // We're trying to match (shuffle fma(a, b, c), X86Fmsub(a, b, c).
  SDValue Op0 = N->getOperand(0);
  SDValue Op1 = N->getOperand(1);
  SDValue FMAdd = Op0, FMSub = Op1;
  if (FMSub.getOpcode() != X86ISD::FMSUB)
    std::swap(FMAdd, FMSub);

  if (FMAdd.getOpcode() != ISD::FMA || FMSub.getOpcode() != X86ISD::FMSUB ||
      FMAdd.getOperand(0) != FMSub.getOperand(0) || !FMAdd.hasOneUse() ||
      FMAdd.getOperand(1) != FMSub.getOperand(1) || !FMSub.hasOneUse() ||
      FMAdd.getOperand(2) != FMSub.getOperand(2))
    return SDValue();

  // Check for correct shuffle mask.
  ArrayRef<int> Mask = cast<ShuffleVectorSDNode>(N)->getMask();
  bool Op0Even;
  if (!isAddSubOrSubAddMask(Mask, Op0Even))
    return SDValue();

  // FMAddSub takes zeroth operand from FMSub node.
  SDLoc DL(N);
  bool IsSubAdd = Op0Even ? Op0 == FMAdd : Op1 == FMAdd;
  unsigned Opcode = IsSubAdd ? X86ISD::FMSUBADD : X86ISD::FMADDSUB;
  return DAG.getNode(Opcode, DL, VT, FMAdd.getOperand(0), FMAdd.getOperand(1),
                     FMAdd.getOperand(2));
}

/// Try to combine a shuffle into a target-specific add-sub or
/// mul-add-sub node.
static SDValue combineShuffleToAddSubOrFMAddSub(SDNode *N,
                                                const X86Subtarget &Subtarget,
                                                SelectionDAG &DAG) {
  if (SDValue V = combineShuffleToFMAddSub(N, Subtarget, DAG))
    return V;

  SDValue Opnd0, Opnd1;
  bool IsSubAdd;
  if (!isAddSubOrSubAdd(N, Subtarget, DAG, Opnd0, Opnd1, IsSubAdd))
    return SDValue();

  MVT VT = N->getSimpleValueType(0);
  SDLoc DL(N);

  // Try to generate X86ISD::FMADDSUB node here.
  SDValue Opnd2;
  if (isFMAddSubOrFMSubAdd(Subtarget, DAG, Opnd0, Opnd1, Opnd2, 2)) {
    unsigned Opc = IsSubAdd ? X86ISD::FMSUBADD : X86ISD::FMADDSUB;
    return DAG.getNode(Opc, DL, VT, Opnd0, Opnd1, Opnd2);
  }

  if (IsSubAdd)
    return SDValue();

  // Do not generate X86ISD::ADDSUB node for 512-bit types even though
  // the ADDSUB idiom has been successfully recognized. There are no known
  // X86 targets with 512-bit ADDSUB instructions!
  if (VT.is512BitVector())
    return SDValue();

  return DAG.getNode(X86ISD::ADDSUB, DL, VT, Opnd0, Opnd1);
}

// We are looking for a shuffle where both sources are concatenated with undef
// and have a width that is half of the output's width. AVX2 has VPERMD/Q, so
// if we can express this as a single-source shuffle, that's preferable.
static SDValue combineShuffleOfConcatUndef(SDNode *N, SelectionDAG &DAG,
                                           const X86Subtarget &Subtarget) {
  if (!Subtarget.hasAVX2() || !isa<ShuffleVectorSDNode>(N))
    return SDValue();

  EVT VT = N->getValueType(0);

  // We only care about shuffles of 128/256-bit vectors of 32/64-bit values.
  if (!VT.is128BitVector() && !VT.is256BitVector())
    return SDValue();

  if (VT.getVectorElementType() != MVT::i32 &&
      VT.getVectorElementType() != MVT::i64 &&
      VT.getVectorElementType() != MVT::f32 &&
      VT.getVectorElementType() != MVT::f64)
    return SDValue();

  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);

  // Check that both sources are concats with undef.
  if (N0.getOpcode() != ISD::CONCAT_VECTORS ||
      N1.getOpcode() != ISD::CONCAT_VECTORS || N0.getNumOperands() != 2 ||
      N1.getNumOperands() != 2 || !N0.getOperand(1).isUndef() ||
      !N1.getOperand(1).isUndef())
    return SDValue();

  // Construct the new shuffle mask. Elements from the first source retain their
  // index, but elements from the second source no longer need to skip an undef.
  SmallVector<int, 8> Mask;
  int NumElts = VT.getVectorNumElements();

  ShuffleVectorSDNode *SVOp = cast<ShuffleVectorSDNode>(N);
  for (int Elt : SVOp->getMask())
    Mask.push_back(Elt < NumElts ? Elt : (Elt - NumElts / 2));

  SDLoc DL(N);
  SDValue Concat = DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, N0.getOperand(0),
                               N1.getOperand(0));
  return DAG.getVectorShuffle(VT, DL, Concat, DAG.getUNDEF(VT), Mask);
}

/// Eliminate a redundant shuffle of a horizontal math op.
static SDValue foldShuffleOfHorizOp(SDNode *N, SelectionDAG &DAG) {
  unsigned Opcode = N->getOpcode();
  if (Opcode != X86ISD::MOVDDUP && Opcode != X86ISD::VBROADCAST)
    if (Opcode != ISD::VECTOR_SHUFFLE || !N->getOperand(1).isUndef())
      return SDValue();

  // For a broadcast, peek through an extract element of index 0 to find the
  // horizontal op: broadcast (ext_vec_elt HOp, 0)
  EVT VT = N->getValueType(0);
  if (Opcode == X86ISD::VBROADCAST) {
    SDValue SrcOp = N->getOperand(0);
    if (SrcOp.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
        SrcOp.getValueType() == MVT::f64 &&
        SrcOp.getOperand(0).getValueType() == VT &&
        isNullConstant(SrcOp.getOperand(1)))
      N = SrcOp.getNode();
  }

  SDValue HOp = N->getOperand(0);
  if (HOp.getOpcode() != X86ISD::HADD && HOp.getOpcode() != X86ISD::FHADD &&
      HOp.getOpcode() != X86ISD::HSUB && HOp.getOpcode() != X86ISD::FHSUB)
    return SDValue();

  // 128-bit horizontal math instructions are defined to operate on adjacent
  // lanes of each operand as:
  // v4X32: A[0] + A[1] , A[2] + A[3] , B[0] + B[1] , B[2] + B[3]
  // ...similarly for v2f64 and v8i16.
  if (!HOp.getOperand(0).isUndef() && !HOp.getOperand(1).isUndef() &&
      HOp.getOperand(0) != HOp.getOperand(1))
    return SDValue();

  // The shuffle that we are eliminating may have allowed the horizontal op to
  // have an undemanded (undefined) operand. Duplicate the other (defined)
  // operand to ensure that the results are defined across all lanes without the
  // shuffle.
  auto updateHOp = [](SDValue HorizOp, SelectionDAG &DAG) {
    SDValue X;
    if (HorizOp.getOperand(0).isUndef()) {
      assert(!HorizOp.getOperand(1).isUndef() && "Not expecting foldable h-op");
      X = HorizOp.getOperand(1);
    } else if (HorizOp.getOperand(1).isUndef()) {
      assert(!HorizOp.getOperand(0).isUndef() && "Not expecting foldable h-op");
      X = HorizOp.getOperand(0);
    } else {
      return HorizOp;
    }
    return DAG.getNode(HorizOp.getOpcode(), SDLoc(HorizOp),
                       HorizOp.getValueType(), X, X);
  };

  // When the operands of a horizontal math op are identical, the low half of
  // the result is the same as the high half. If a target shuffle is also
  // replicating low and high halves (and without changing the type/length of
  // the vector), we don't need the shuffle.
  if (Opcode == X86ISD::MOVDDUP || Opcode == X86ISD::VBROADCAST) {
    if (HOp.getScalarValueSizeInBits() == 64 && HOp.getValueType() == VT) {
      // movddup (hadd X, X) --> hadd X, X
      // broadcast (extract_vec_elt (hadd X, X), 0) --> hadd X, X
      assert((HOp.getValueType() == MVT::v2f64 ||
              HOp.getValueType() == MVT::v4f64) && "Unexpected type for h-op");
      return updateHOp(HOp, DAG);
    }
    return SDValue();
  }

  // shuffle (hadd X, X), undef, [low half...high half] --> hadd X, X
  ArrayRef<int> Mask = cast<ShuffleVectorSDNode>(N)->getMask();
  // TODO: Other mask possibilities like {1,1} and {1,0} could be added here,
  // but this should be tied to whatever horizontal op matching and shuffle
  // canonicalization are producing.
  if (HOp.getValueSizeInBits() == 128 &&
      (isTargetShuffleEquivalent(Mask, {0, 0}) ||
       isTargetShuffleEquivalent(Mask, {0, 1, 0, 1}) ||
       isTargetShuffleEquivalent(Mask, {0, 1, 2, 3, 0, 1, 2, 3})))
    return updateHOp(HOp, DAG);

  if (HOp.getValueSizeInBits() == 256 &&
      (isTargetShuffleEquivalent(Mask, {0, 0, 2, 2}) ||
       isTargetShuffleEquivalent(Mask, {0, 1, 0, 1, 4, 5, 4, 5}) ||
       isTargetShuffleEquivalent(
           Mask, {0, 1, 2, 3, 0, 1, 2, 3, 8, 9, 10, 11, 8, 9, 10, 11})))
    return updateHOp(HOp, DAG);

  return SDValue();
}

/// If we have a shuffle of AVX/AVX512 (256/512 bit) vectors that only uses the
/// low half of each source vector and does not set any high half elements in
/// the destination vector, narrow the shuffle to half its original size.
static SDValue narrowShuffle(ShuffleVectorSDNode *Shuf, SelectionDAG &DAG) {
  if (!Shuf->getValueType(0).isSimple())
    return SDValue();
  MVT VT = Shuf->getSimpleValueType(0);
  if (!VT.is256BitVector() && !VT.is512BitVector())
    return SDValue();

  // See if we can ignore all of the high elements of the shuffle.
  ArrayRef<int> Mask = Shuf->getMask();
  if (!isUndefUpperHalf(Mask))
    return SDValue();

  // Check if the shuffle mask accesses only the low half of each input vector
  // (half-index output is 0 or 2).
  int HalfIdx1, HalfIdx2;
  SmallVector<int, 8> HalfMask(Mask.size() / 2);
  if (!getHalfShuffleMask(Mask, HalfMask, HalfIdx1, HalfIdx2) ||
      (HalfIdx1 % 2 == 1) || (HalfIdx2 % 2 == 1))
    return SDValue();

  // Create a half-width shuffle to replace the unnecessarily wide shuffle.
  // The trick is knowing that all of the insert/extract are actually free
  // subregister (zmm<->ymm or ymm<->xmm) ops. That leaves us with a shuffle
  // of narrow inputs into a narrow output, and that is always cheaper than
  // the wide shuffle that we started with.
  return getShuffleHalfVectors(SDLoc(Shuf), Shuf->getOperand(0),
                               Shuf->getOperand(1), HalfMask, HalfIdx1,
                               HalfIdx2, false, DAG, /*UseConcat*/true);
}

static SDValue combineShuffle(SDNode *N, SelectionDAG &DAG,
                              TargetLowering::DAGCombinerInfo &DCI,
                              const X86Subtarget &Subtarget) {
  if (auto *Shuf = dyn_cast<ShuffleVectorSDNode>(N))
    if (SDValue V = narrowShuffle(Shuf, DAG))
      return V;

  // If we have legalized the vector types, look for blends of FADD and FSUB
  // nodes that we can fuse into an ADDSUB, FMADDSUB, or FMSUBADD node.
  SDLoc dl(N);
  EVT VT = N->getValueType(0);
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  if (TLI.isTypeLegal(VT)) {
    if (SDValue AddSub = combineShuffleToAddSubOrFMAddSub(N, Subtarget, DAG))
      return AddSub;

    if (SDValue HAddSub = foldShuffleOfHorizOp(N, DAG))
      return HAddSub;
  }

  // Attempt to combine into a vector load/broadcast.
  if (SDValue LD = combineToConsecutiveLoads(VT, N, dl, DAG, Subtarget, true))
    return LD;

  // For AVX2, we sometimes want to combine
  // (vector_shuffle <mask> (concat_vectors t1, undef)
  //                        (concat_vectors t2, undef))
  // Into:
  // (vector_shuffle <mask> (concat_vectors t1, t2), undef)
  // Since the latter can be efficiently lowered with VPERMD/VPERMQ
  if (SDValue ShufConcat = combineShuffleOfConcatUndef(N, DAG, Subtarget))
    return ShufConcat;

  if (isTargetShuffle(N->getOpcode())) {
    SDValue Op(N, 0);
    if (SDValue Shuffle = combineTargetShuffle(Op, DAG, DCI, Subtarget))
      return Shuffle;

    // Try recursively combining arbitrary sequences of x86 shuffle
    // instructions into higher-order shuffles. We do this after combining
    // specific PSHUF instruction sequences into their minimal form so that we
    // can evaluate how many specialized shuffle instructions are involved in
    // a particular chain.
    if (SDValue Res = combineX86ShufflesRecursively(Op, DAG, Subtarget))
      return Res;

    // Simplify source operands based on shuffle mask.
    // TODO - merge this into combineX86ShufflesRecursively.
    APInt KnownUndef, KnownZero;
    APInt DemandedElts = APInt::getAllOnesValue(VT.getVectorNumElements());
    if (TLI.SimplifyDemandedVectorElts(Op, DemandedElts, KnownUndef, KnownZero, DCI))
      return SDValue(N, 0);
  }

  // Look for a v2i64/v2f64 VZEXT_MOVL of a node that already produces zeros
  // in the upper 64 bits.
  // TODO: Can we generalize this using computeKnownBits.
  if (N->getOpcode() == X86ISD::VZEXT_MOVL &&
      (VT == MVT::v2f64 || VT == MVT::v2i64) &&
      N->getOperand(0).getOpcode() == ISD::BITCAST) {
    SDValue In = N->getOperand(0).getOperand(0);
    EVT InVT = In.getValueType();
    switch (In.getOpcode()) {
    default:
      break;
    case X86ISD::CVTP2SI:   case X86ISD::CVTP2UI:
    case X86ISD::MCVTP2SI:  case X86ISD::MCVTP2UI:
    case X86ISD::CVTTP2SI:  case X86ISD::CVTTP2UI:
    case X86ISD::MCVTTP2SI: case X86ISD::MCVTTP2UI:
    case X86ISD::CVTSI2P:   case X86ISD::CVTUI2P:
    case X86ISD::MCVTSI2P:  case X86ISD::MCVTUI2P:
    case X86ISD::VFPROUND:  case X86ISD::VMFPROUND:
      if ((InVT == MVT::v4f32 || InVT == MVT::v4i32) &&
          (In.getOperand(0).getValueType() == MVT::v2f64 ||
           In.getOperand(0).getValueType() == MVT::v2i64))
        return N->getOperand(0); // return the bitcast
      break;
    case X86ISD::STRICT_CVTTP2SI:
    case X86ISD::STRICT_CVTTP2UI:
    case X86ISD::STRICT_CVTSI2P:
    case X86ISD::STRICT_CVTUI2P:
    case X86ISD::STRICT_VFPROUND:
      if ((InVT == MVT::v4f32 || InVT == MVT::v4i32) &&
          (In.getOperand(1).getValueType() == MVT::v2f64 ||
           In.getOperand(1).getValueType() == MVT::v2i64))
        return N->getOperand(0); // return the bitcast
      break;
    case X86ISD::CVTPS2PH:
    case X86ISD::MCVTPS2PH:
      if (InVT == MVT::v8i16 && In.getOperand(0).getValueType() == MVT::v4f32)
        return N->getOperand(0); // return the bitcast
      break;
    case X86ISD::STRICT_CVTPS2PH:
      if (InVT == MVT::v8i16 && In.getOperand(1).getValueType() == MVT::v4f32)
        return N->getOperand(0); // return the bitcast
      break;
    }
  }

  // Pull subvector inserts into undef through VZEXT_MOVL by making it an
  // insert into a zero vector. This helps get VZEXT_MOVL closer to
  // scalar_to_vectors where 256/512 are canonicalized to an insert and a
  // 128-bit scalar_to_vector. This reduces the number of isel patterns.
  if (N->getOpcode() == X86ISD::VZEXT_MOVL && !DCI.isBeforeLegalizeOps() &&
      N->getOperand(0).getOpcode() == ISD::INSERT_SUBVECTOR &&
      N->getOperand(0).hasOneUse() &&
      N->getOperand(0).getOperand(0).isUndef() &&
      isNullConstant(N->getOperand(0).getOperand(2))) {
    SDValue In = N->getOperand(0).getOperand(1);
    SDValue Movl = DAG.getNode(X86ISD::VZEXT_MOVL, dl, In.getValueType(), In);
    return DAG.getNode(ISD::INSERT_SUBVECTOR, dl, VT,
                       getZeroVector(VT.getSimpleVT(), Subtarget, DAG, dl),
                       Movl, N->getOperand(0).getOperand(2));
  }

  // If this a vzmovl of a full vector load, replace it with a vzload, unless
  // the load is volatile.
  if (N->getOpcode() == X86ISD::VZEXT_MOVL && N->getOperand(0).hasOneUse() &&
      ISD::isNormalLoad(N->getOperand(0).getNode())) {
    LoadSDNode *LN = cast<LoadSDNode>(N->getOperand(0));
    if (LN->isSimple()) {
      SDVTList Tys = DAG.getVTList(VT, MVT::Other);
      SDValue Ops[] = { LN->getChain(), LN->getBasePtr() };
      SDValue VZLoad = DAG.getMemIntrinsicNode(
          X86ISD::VZEXT_LOAD, dl, Tys, Ops, VT.getVectorElementType(),
          LN->getPointerInfo(), LN->getAlign(),
          LN->getMemOperand()->getFlags());
      DCI.CombineTo(N, VZLoad);
      DAG.ReplaceAllUsesOfValueWith(SDValue(LN, 1), VZLoad.getValue(1));
      DCI.recursivelyDeleteUnusedNodes(LN);
      return SDValue(N, 0);
    }
  }

  // If this a VZEXT_MOVL of a VBROADCAST_LOAD, we don't need the broadcast and
  // can just use a VZEXT_LOAD.
  // FIXME: Is there some way to do this with SimplifyDemandedVectorElts?
  if (N->getOpcode() == X86ISD::VZEXT_MOVL && N->getOperand(0).hasOneUse() &&
      N->getOperand(0).getOpcode() == X86ISD::VBROADCAST_LOAD) {
    auto *LN = cast<MemSDNode>(N->getOperand(0));
    if (VT.getScalarSizeInBits() == LN->getMemoryVT().getSizeInBits()) {
      SDVTList Tys = DAG.getVTList(VT, MVT::Other);
      SDValue Ops[] = { LN->getChain(), LN->getBasePtr() };
      SDValue VZLoad =
          DAG.getMemIntrinsicNode(X86ISD::VZEXT_LOAD, dl, Tys, Ops,
                                  LN->getMemoryVT(), LN->getMemOperand());
      DCI.CombineTo(N, VZLoad);
      DAG.ReplaceAllUsesOfValueWith(SDValue(LN, 1), VZLoad.getValue(1));
      DCI.recursivelyDeleteUnusedNodes(LN);
      return SDValue(N, 0);
    }
  }

  // Turn (v2i64 (vzext_movl (scalar_to_vector (i64 X)))) into
  // (v2i64 (bitcast (v4i32 (vzext_movl (scalar_to_vector (i32 (trunc X)))))))
  // if the upper bits of the i64 are zero.
  if (N->getOpcode() == X86ISD::VZEXT_MOVL && N->getOperand(0).hasOneUse() &&
      N->getOperand(0)->getOpcode() == ISD::SCALAR_TO_VECTOR &&
      N->getOperand(0).getOperand(0).hasOneUse() &&
      N->getOperand(0).getOperand(0).getValueType() == MVT::i64) {
    SDValue In = N->getOperand(0).getOperand(0);
    APInt Mask = APInt::getHighBitsSet(64, 32);
    if (DAG.MaskedValueIsZero(In, Mask)) {
      SDValue Trunc = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, In);
      MVT VecVT = MVT::getVectorVT(MVT::i32, VT.getVectorNumElements() * 2);
      SDValue SclVec = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VecVT, Trunc);
      SDValue Movl = DAG.getNode(X86ISD::VZEXT_MOVL, dl, VecVT, SclVec);
      return DAG.getBitcast(VT, Movl);
    }
  }

  return SDValue();
}

bool X86TargetLowering::SimplifyDemandedVectorEltsForTargetNode(
    SDValue Op, const APInt &DemandedElts, APInt &KnownUndef, APInt &KnownZero,
    TargetLoweringOpt &TLO, unsigned Depth) const {
  int NumElts = DemandedElts.getBitWidth();
  unsigned Opc = Op.getOpcode();
  EVT VT = Op.getValueType();

  // Handle special case opcodes.
  switch (Opc) {
  case X86ISD::PMULDQ:
  case X86ISD::PMULUDQ: {
    APInt LHSUndef, LHSZero;
    APInt RHSUndef, RHSZero;
    SDValue LHS = Op.getOperand(0);
    SDValue RHS = Op.getOperand(1);
    if (SimplifyDemandedVectorElts(LHS, DemandedElts, LHSUndef, LHSZero, TLO,
                                   Depth + 1))
      return true;
    if (SimplifyDemandedVectorElts(RHS, DemandedElts, RHSUndef, RHSZero, TLO,
                                   Depth + 1))
      return true;
    // Multiply by zero.
    KnownZero = LHSZero | RHSZero;
    break;
  }
  case X86ISD::VSHL:
  case X86ISD::VSRL:
  case X86ISD::VSRA: {
    // We only need the bottom 64-bits of the (128-bit) shift amount.
    SDValue Amt = Op.getOperand(1);
    MVT AmtVT = Amt.getSimpleValueType();
    assert(AmtVT.is128BitVector() && "Unexpected value type");

    // If we reuse the shift amount just for sse shift amounts then we know that
    // only the bottom 64-bits are only ever used.
    bool AssumeSingleUse = llvm::all_of(Amt->uses(), [&Amt](SDNode *Use) {
      unsigned UseOpc = Use->getOpcode();
      return (UseOpc == X86ISD::VSHL || UseOpc == X86ISD::VSRL ||
              UseOpc == X86ISD::VSRA) &&
             Use->getOperand(0) != Amt;
    });

    APInt AmtUndef, AmtZero;
    unsigned NumAmtElts = AmtVT.getVectorNumElements();
    APInt AmtElts = APInt::getLowBitsSet(NumAmtElts, NumAmtElts / 2);
    if (SimplifyDemandedVectorElts(Amt, AmtElts, AmtUndef, AmtZero, TLO,
                                   Depth + 1, AssumeSingleUse))
      return true;
    LLVM_FALLTHROUGH;
  }
  case X86ISD::VSHLI:
  case X86ISD::VSRLI:
  case X86ISD::VSRAI: {
    SDValue Src = Op.getOperand(0);
    APInt SrcUndef;
    if (SimplifyDemandedVectorElts(Src, DemandedElts, SrcUndef, KnownZero, TLO,
                                   Depth + 1))
      return true;
    // TODO convert SrcUndef to KnownUndef.
    break;
  }
  case X86ISD::KSHIFTL: {
    SDValue Src = Op.getOperand(0);
    auto *Amt = cast<ConstantSDNode>(Op.getOperand(1));
    assert(Amt->getAPIntValue().ult(NumElts) && "Out of range shift amount");
    unsigned ShiftAmt = Amt->getZExtValue();

    if (ShiftAmt == 0)
      return TLO.CombineTo(Op, Src);

    // If this is ((X >>u C1) << ShAmt), see if we can simplify this into a
    // single shift.  We can do this if the bottom bits (which are shifted
    // out) are never demanded.
    if (Src.getOpcode() == X86ISD::KSHIFTR) {
      if (!DemandedElts.intersects(APInt::getLowBitsSet(NumElts, ShiftAmt))) {
        unsigned C1 = Src.getConstantOperandVal(1);
        unsigned NewOpc = X86ISD::KSHIFTL;
        int Diff = ShiftAmt - C1;
        if (Diff < 0) {
          Diff = -Diff;
          NewOpc = X86ISD::KSHIFTR;
        }

        SDLoc dl(Op);
        SDValue NewSA = TLO.DAG.getTargetConstant(Diff, dl, MVT::i8);
        return TLO.CombineTo(
            Op, TLO.DAG.getNode(NewOpc, dl, VT, Src.getOperand(0), NewSA));
      }
    }

    APInt DemandedSrc = DemandedElts.lshr(ShiftAmt);
    if (SimplifyDemandedVectorElts(Src, DemandedSrc, KnownUndef, KnownZero, TLO,
                                   Depth + 1))
      return true;

    KnownUndef <<= ShiftAmt;
    KnownZero <<= ShiftAmt;
    KnownZero.setLowBits(ShiftAmt);
    break;
  }
  case X86ISD::KSHIFTR: {
    SDValue Src = Op.getOperand(0);
    auto *Amt = cast<ConstantSDNode>(Op.getOperand(1));
    assert(Amt->getAPIntValue().ult(NumElts) && "Out of range shift amount");
    unsigned ShiftAmt = Amt->getZExtValue();

    if (ShiftAmt == 0)
      return TLO.CombineTo(Op, Src);

    // If this is ((X << C1) >>u ShAmt), see if we can simplify this into a
    // single shift.  We can do this if the top bits (which are shifted
    // out) are never demanded.
    if (Src.getOpcode() == X86ISD::KSHIFTL) {
      if (!DemandedElts.intersects(APInt::getHighBitsSet(NumElts, ShiftAmt))) {
        unsigned C1 = Src.getConstantOperandVal(1);
        unsigned NewOpc = X86ISD::KSHIFTR;
        int Diff = ShiftAmt - C1;
        if (Diff < 0) {
          Diff = -Diff;
          NewOpc = X86ISD::KSHIFTL;
        }

        SDLoc dl(Op);
        SDValue NewSA = TLO.DAG.getTargetConstant(Diff, dl, MVT::i8);
        return TLO.CombineTo(
            Op, TLO.DAG.getNode(NewOpc, dl, VT, Src.getOperand(0), NewSA));
      }
    }

    APInt DemandedSrc = DemandedElts.shl(ShiftAmt);
    if (SimplifyDemandedVectorElts(Src, DemandedSrc, KnownUndef, KnownZero, TLO,
                                   Depth + 1))
      return true;

    KnownUndef.lshrInPlace(ShiftAmt);
    KnownZero.lshrInPlace(ShiftAmt);
    KnownZero.setHighBits(ShiftAmt);
    break;
  }
  case X86ISD::CVTSI2P:
  case X86ISD::CVTUI2P: {
    SDValue Src = Op.getOperand(0);
    MVT SrcVT = Src.getSimpleValueType();
    APInt SrcUndef, SrcZero;
    APInt SrcElts = DemandedElts.zextOrTrunc(SrcVT.getVectorNumElements());
    if (SimplifyDemandedVectorElts(Src, SrcElts, SrcUndef, SrcZero, TLO,
                                   Depth + 1))
      return true;
    break;
  }
  case X86ISD::PACKSS:
  case X86ISD::PACKUS: {
    SDValue N0 = Op.getOperand(0);
    SDValue N1 = Op.getOperand(1);

    APInt DemandedLHS, DemandedRHS;
    getPackDemandedElts(VT, DemandedElts, DemandedLHS, DemandedRHS);

    APInt SrcUndef, SrcZero;
    if (SimplifyDemandedVectorElts(N0, DemandedLHS, SrcUndef, SrcZero, TLO,
                                   Depth + 1))
      return true;
    if (SimplifyDemandedVectorElts(N1, DemandedRHS, SrcUndef, SrcZero, TLO,
                                   Depth + 1))
      return true;

    // Aggressively peek through ops to get at the demanded elts.
    // TODO - we should do this for all target/faux shuffles ops.
    if (!DemandedElts.isAllOnesValue()) {
      APInt DemandedSrcBits =
          APInt::getAllOnesValue(N0.getScalarValueSizeInBits());
      SDValue NewN0 = SimplifyMultipleUseDemandedBits(
          N0, DemandedSrcBits, DemandedLHS, TLO.DAG, Depth + 1);
      SDValue NewN1 = SimplifyMultipleUseDemandedBits(
          N1, DemandedSrcBits, DemandedRHS, TLO.DAG, Depth + 1);
      if (NewN0 || NewN1) {
        NewN0 = NewN0 ? NewN0 : N0;
        NewN1 = NewN1 ? NewN1 : N1;
        return TLO.CombineTo(Op,
                             TLO.DAG.getNode(Opc, SDLoc(Op), VT, NewN0, NewN1));
      }
    }
    break;
  }
  case X86ISD::HADD:
  case X86ISD::HSUB:
  case X86ISD::FHADD:
  case X86ISD::FHSUB: {
    APInt DemandedLHS, DemandedRHS;
    getHorizDemandedElts(VT, DemandedElts, DemandedLHS, DemandedRHS);

    APInt LHSUndef, LHSZero;
    if (SimplifyDemandedVectorElts(Op.getOperand(0), DemandedLHS, LHSUndef,
                                   LHSZero, TLO, Depth + 1))
      return true;
    APInt RHSUndef, RHSZero;
    if (SimplifyDemandedVectorElts(Op.getOperand(1), DemandedRHS, RHSUndef,
                                   RHSZero, TLO, Depth + 1))
      return true;
    break;
  }
  case X86ISD::VTRUNC:
  case X86ISD::VTRUNCS:
  case X86ISD::VTRUNCUS: {
    SDValue Src = Op.getOperand(0);
    MVT SrcVT = Src.getSimpleValueType();
    APInt DemandedSrc = DemandedElts.zextOrTrunc(SrcVT.getVectorNumElements());
    APInt SrcUndef, SrcZero;
    if (SimplifyDemandedVectorElts(Src, DemandedSrc, SrcUndef, SrcZero, TLO,
                                   Depth + 1))
      return true;
    KnownZero = SrcZero.zextOrTrunc(NumElts);
    KnownUndef = SrcUndef.zextOrTrunc(NumElts);
    break;
  }
  case X86ISD::BLENDV: {
    APInt SelUndef, SelZero;
    if (SimplifyDemandedVectorElts(Op.getOperand(0), DemandedElts, SelUndef,
                                   SelZero, TLO, Depth + 1))
      return true;

    // TODO: Use SelZero to adjust LHS/RHS DemandedElts.
    APInt LHSUndef, LHSZero;
    if (SimplifyDemandedVectorElts(Op.getOperand(1), DemandedElts, LHSUndef,
                                   LHSZero, TLO, Depth + 1))
      return true;

    APInt RHSUndef, RHSZero;
    if (SimplifyDemandedVectorElts(Op.getOperand(2), DemandedElts, RHSUndef,
                                   RHSZero, TLO, Depth + 1))
      return true;

    KnownZero = LHSZero & RHSZero;
    KnownUndef = LHSUndef & RHSUndef;
    break;
  }
  case X86ISD::VBROADCAST: {
    SDValue Src = Op.getOperand(0);
    MVT SrcVT = Src.getSimpleValueType();
    if (!SrcVT.isVector())
      return false;
    // Don't bother broadcasting if we just need the 0'th element.
    if (DemandedElts == 1) {
      if (Src.getValueType() != VT)
        Src = widenSubVector(VT.getSimpleVT(), Src, false, Subtarget, TLO.DAG,
                             SDLoc(Op));
      return TLO.CombineTo(Op, Src);
    }
    APInt SrcUndef, SrcZero;
    APInt SrcElts = APInt::getOneBitSet(SrcVT.getVectorNumElements(), 0);
    if (SimplifyDemandedVectorElts(Src, SrcElts, SrcUndef, SrcZero, TLO,
                                   Depth + 1))
      return true;
    break;
  }
  case X86ISD::VPERMV: {
    SDValue Mask = Op.getOperand(0);
    APInt MaskUndef, MaskZero;
    if (SimplifyDemandedVectorElts(Mask, DemandedElts, MaskUndef, MaskZero, TLO,
                                   Depth + 1))
      return true;
    break;
  }
  case X86ISD::PSHUFB:
  case X86ISD::VPERMV3:
  case X86ISD::VPERMILPV: {
    SDValue Mask = Op.getOperand(1);
    APInt MaskUndef, MaskZero;
    if (SimplifyDemandedVectorElts(Mask, DemandedElts, MaskUndef, MaskZero, TLO,
                                   Depth + 1))
      return true;
    break;
  }
  case X86ISD::VPPERM:
  case X86ISD::VPERMIL2: {
    SDValue Mask = Op.getOperand(2);
    APInt MaskUndef, MaskZero;
    if (SimplifyDemandedVectorElts(Mask, DemandedElts, MaskUndef, MaskZero, TLO,
                                   Depth + 1))
      return true;
    break;
  }
  }

  // For 256/512-bit ops that are 128/256-bit ops glued together, if we do not
  // demand any of the high elements, then narrow the op to 128/256-bits: e.g.
  // (op ymm0, ymm1) --> insert undef, (op xmm0, xmm1), 0
  if ((VT.is256BitVector() || VT.is512BitVector()) &&
      DemandedElts.lshr(NumElts / 2) == 0) {
    unsigned SizeInBits = VT.getSizeInBits();
    unsigned ExtSizeInBits = SizeInBits / 2;

    // See if 512-bit ops only use the bottom 128-bits.
    if (VT.is512BitVector() && DemandedElts.lshr(NumElts / 4) == 0)
      ExtSizeInBits = SizeInBits / 4;

    switch (Opc) {
      // Zero upper elements.
    case X86ISD::VZEXT_MOVL: {
      SDLoc DL(Op);
      SDValue Ext0 =
          extractSubVector(Op.getOperand(0), 0, TLO.DAG, DL, ExtSizeInBits);
      SDValue ExtOp =
          TLO.DAG.getNode(Opc, DL, Ext0.getValueType(), Ext0);
      SDValue UndefVec = TLO.DAG.getUNDEF(VT);
      SDValue Insert =
          insertSubVector(UndefVec, ExtOp, 0, TLO.DAG, DL, ExtSizeInBits);
      return TLO.CombineTo(Op, Insert);
    }
      // Subvector broadcast.
    case X86ISD::SUBV_BROADCAST: {
      SDLoc DL(Op);
      SDValue Src = Op.getOperand(0);
      if (Src.getValueSizeInBits() > ExtSizeInBits)
        Src = extractSubVector(Src, 0, TLO.DAG, DL, ExtSizeInBits);
      else if (Src.getValueSizeInBits() < ExtSizeInBits) {
        MVT SrcSVT = Src.getSimpleValueType().getScalarType();
        MVT SrcVT =
            MVT::getVectorVT(SrcSVT, ExtSizeInBits / SrcSVT.getSizeInBits());
        Src = TLO.DAG.getNode(X86ISD::SUBV_BROADCAST, DL, SrcVT, Src);
      }
      return TLO.CombineTo(Op, insertSubVector(TLO.DAG.getUNDEF(VT), Src, 0,
                                               TLO.DAG, DL, ExtSizeInBits));
    }
      // Byte shifts by immediate.
    case X86ISD::VSHLDQ:
    case X86ISD::VSRLDQ:
      // Shift by uniform.
    case X86ISD::VSHL:
    case X86ISD::VSRL:
    case X86ISD::VSRA:
      // Shift by immediate.
    case X86ISD::VSHLI:
    case X86ISD::VSRLI:
    case X86ISD::VSRAI: {
      SDLoc DL(Op);
      SDValue Ext0 =
          extractSubVector(Op.getOperand(0), 0, TLO.DAG, DL, ExtSizeInBits);
      SDValue ExtOp =
          TLO.DAG.getNode(Opc, DL, Ext0.getValueType(), Ext0, Op.getOperand(1));
      SDValue UndefVec = TLO.DAG.getUNDEF(VT);
      SDValue Insert =
          insertSubVector(UndefVec, ExtOp, 0, TLO.DAG, DL, ExtSizeInBits);
      return TLO.CombineTo(Op, Insert);
    }
    case X86ISD::VPERMI: {
      // Simplify PERMPD/PERMQ to extract_subvector.
      // TODO: This should be done in shuffle combining.
      if (VT == MVT::v4f64 || VT == MVT::v4i64) {
        SmallVector<int, 4> Mask;
        DecodeVPERMMask(NumElts, Op.getConstantOperandVal(1), Mask);
        if (isUndefOrEqual(Mask[0], 2) && isUndefOrEqual(Mask[1], 3)) {
          SDLoc DL(Op);
          SDValue Ext = extractSubVector(Op.getOperand(0), 2, TLO.DAG, DL, 128);
          SDValue UndefVec = TLO.DAG.getUNDEF(VT);
          SDValue Insert = insertSubVector(UndefVec, Ext, 0, TLO.DAG, DL, 128);
          return TLO.CombineTo(Op, Insert);
        }
      }
      break;
    }
      // Target Shuffles.
    case X86ISD::PSHUFB:
    case X86ISD::UNPCKL:
    case X86ISD::UNPCKH:
      // Saturated Packs.
    case X86ISD::PACKSS:
    case X86ISD::PACKUS:
      // Horizontal Ops.
    case X86ISD::HADD:
    case X86ISD::HSUB:
    case X86ISD::FHADD:
    case X86ISD::FHSUB: {
      SDLoc DL(Op);
      MVT ExtVT = VT.getSimpleVT();
      ExtVT = MVT::getVectorVT(ExtVT.getScalarType(),
                               ExtSizeInBits / ExtVT.getScalarSizeInBits());
      SDValue Ext0 =
          extractSubVector(Op.getOperand(0), 0, TLO.DAG, DL, ExtSizeInBits);
      SDValue Ext1 =
          extractSubVector(Op.getOperand(1), 0, TLO.DAG, DL, ExtSizeInBits);
      SDValue ExtOp = TLO.DAG.getNode(Opc, DL, ExtVT, Ext0, Ext1);
      SDValue UndefVec = TLO.DAG.getUNDEF(VT);
      SDValue Insert =
          insertSubVector(UndefVec, ExtOp, 0, TLO.DAG, DL, ExtSizeInBits);
      return TLO.CombineTo(Op, Insert);
    }
      // Vector blend by immediate.
    case X86ISD::BLENDI: {
      SDLoc DL(Op);
      MVT ExtVT = VT.getSimpleVT();
      ExtVT = MVT::getVectorVT(ExtVT.getScalarType(),
                               ExtSizeInBits / ExtVT.getScalarSizeInBits());
      SDValue Ext0 =
          extractSubVector(Op.getOperand(0), 0, TLO.DAG, DL, ExtSizeInBits);
      SDValue Ext1 =
          extractSubVector(Op.getOperand(1), 0, TLO.DAG, DL, ExtSizeInBits);
      SDValue ExtOp =
          TLO.DAG.getNode(Opc, DL, ExtVT, Ext0, Ext1, Op.getOperand(2));
      SDValue UndefVec = TLO.DAG.getUNDEF(VT);
      SDValue Insert =
          insertSubVector(UndefVec, ExtOp, 0, TLO.DAG, DL, ExtSizeInBits);
      return TLO.CombineTo(Op, Insert);
    } 
    }
  }

  // Get target/faux shuffle mask.
  APInt OpUndef, OpZero;
  SmallVector<int, 64> OpMask;
  SmallVector<SDValue, 2> OpInputs;
  if (!getTargetShuffleInputs(Op, DemandedElts, OpInputs, OpMask, OpUndef,
                              OpZero, TLO.DAG, Depth, false))
    return false;

  // Shuffle inputs must be the same size as the result.
  if (OpMask.size() != (unsigned)NumElts ||
      llvm::any_of(OpInputs, [VT](SDValue V) {
        return VT.getSizeInBits() != V.getValueSizeInBits() ||
               !V.getValueType().isVector();
      }))
    return false;

  KnownZero = OpZero;
  KnownUndef = OpUndef;

  // Check if shuffle mask can be simplified to undef/zero/identity.
  int NumSrcs = OpInputs.size();
  for (int i = 0; i != NumElts; ++i)
    if (!DemandedElts[i])
      OpMask[i] = SM_SentinelUndef;

  if (isUndefInRange(OpMask, 0, NumElts)) {
    KnownUndef.setAllBits();
    return TLO.CombineTo(Op, TLO.DAG.getUNDEF(VT));
  }
  if (isUndefOrZeroInRange(OpMask, 0, NumElts)) {
    KnownZero.setAllBits();
    return TLO.CombineTo(
        Op, getZeroVector(VT.getSimpleVT(), Subtarget, TLO.DAG, SDLoc(Op)));
  }
  for (int Src = 0; Src != NumSrcs; ++Src)
    if (isSequentialOrUndefInRange(OpMask, 0, NumElts, Src * NumElts))
      return TLO.CombineTo(Op, TLO.DAG.getBitcast(VT, OpInputs[Src]));

  // Attempt to simplify inputs.
  for (int Src = 0; Src != NumSrcs; ++Src) {
    // TODO: Support inputs of different types.
    if (OpInputs[Src].getValueType() != VT)
      continue;

    int Lo = Src * NumElts;
    APInt SrcElts = APInt::getNullValue(NumElts);
    for (int i = 0; i != NumElts; ++i)
      if (DemandedElts[i]) {
        int M = OpMask[i] - Lo;
        if (0 <= M && M < NumElts)
          SrcElts.setBit(M);
      }

    // TODO - Propagate input undef/zero elts.
    APInt SrcUndef, SrcZero;
    if (SimplifyDemandedVectorElts(OpInputs[Src], SrcElts, SrcUndef, SrcZero,
                                   TLO, Depth + 1))
      return true;
  }

  // If we don't demand all elements, then attempt to combine to a simpler
  // shuffle.
  // TODO: Handle other depths, but first we need to handle the fact that
  // it might combine to the same shuffle.
  if (!DemandedElts.isAllOnesValue() && Depth == 0) {
    SmallVector<int, 64> DemandedMask(NumElts, SM_SentinelUndef);
    for (int i = 0; i != NumElts; ++i)
      if (DemandedElts[i])
        DemandedMask[i] = i;

    SDValue NewShuffle = combineX86ShufflesRecursively(
        {Op}, 0, Op, DemandedMask, {}, Depth, /*HasVarMask*/ false,
        /*AllowVarMask*/ true, TLO.DAG, Subtarget);
    if (NewShuffle)
      return TLO.CombineTo(Op, NewShuffle);
  }

  return false;
}

bool X86TargetLowering::SimplifyDemandedBitsForTargetNode(
    SDValue Op, const APInt &OriginalDemandedBits,
    const APInt &OriginalDemandedElts, KnownBits &Known, TargetLoweringOpt &TLO,
    unsigned Depth) const {
  EVT VT = Op.getValueType();
  unsigned BitWidth = OriginalDemandedBits.getBitWidth();
  unsigned Opc = Op.getOpcode();
  switch(Opc) {
  case X86ISD::PMULDQ:
  case X86ISD::PMULUDQ: {
    // PMULDQ/PMULUDQ only uses lower 32 bits from each vector element.
    KnownBits KnownOp;
    SDValue LHS = Op.getOperand(0);
    SDValue RHS = Op.getOperand(1);
    // FIXME: Can we bound this better?
    APInt DemandedMask = APInt::getLowBitsSet(64, 32);
    if (SimplifyDemandedBits(LHS, DemandedMask, OriginalDemandedElts, KnownOp,
                             TLO, Depth + 1))
      return true;
    if (SimplifyDemandedBits(RHS, DemandedMask, OriginalDemandedElts, KnownOp,
                             TLO, Depth + 1))
      return true;

    // Aggressively peek through ops to get at the demanded low bits.
    SDValue DemandedLHS = SimplifyMultipleUseDemandedBits(
        LHS, DemandedMask, OriginalDemandedElts, TLO.DAG, Depth + 1);
    SDValue DemandedRHS = SimplifyMultipleUseDemandedBits(
        RHS, DemandedMask, OriginalDemandedElts, TLO.DAG, Depth + 1);
    if (DemandedLHS || DemandedRHS) {
      DemandedLHS = DemandedLHS ? DemandedLHS : LHS;
      DemandedRHS = DemandedRHS ? DemandedRHS : RHS;
      return TLO.CombineTo(
          Op, TLO.DAG.getNode(Opc, SDLoc(Op), VT, DemandedLHS, DemandedRHS));
    }
    break;
  }
  case X86ISD::VSHLI: {
    SDValue Op0 = Op.getOperand(0);

    unsigned ShAmt = Op.getConstantOperandVal(1);
    if (ShAmt >= BitWidth)
      break;

    APInt DemandedMask = OriginalDemandedBits.lshr(ShAmt);

    // If this is ((X >>u C1) << ShAmt), see if we can simplify this into a
    // single shift.  We can do this if the bottom bits (which are shifted
    // out) are never demanded.
    if (Op0.getOpcode() == X86ISD::VSRLI &&
        OriginalDemandedBits.countTrailingZeros() >= ShAmt) {
      unsigned Shift2Amt = Op0.getConstantOperandVal(1);
      if (Shift2Amt < BitWidth) {
        int Diff = ShAmt - Shift2Amt;
        if (Diff == 0)
          return TLO.CombineTo(Op, Op0.getOperand(0));

        unsigned NewOpc = Diff < 0 ? X86ISD::VSRLI : X86ISD::VSHLI;
        SDValue NewShift = TLO.DAG.getNode(
            NewOpc, SDLoc(Op), VT, Op0.getOperand(0),
            TLO.DAG.getTargetConstant(std::abs(Diff), SDLoc(Op), MVT::i8));
        return TLO.CombineTo(Op, NewShift);
      }
    }

    if (SimplifyDemandedBits(Op0, DemandedMask, OriginalDemandedElts, Known,
                             TLO, Depth + 1))
      return true;

    assert(!Known.hasConflict() && "Bits known to be one AND zero?");
    Known.Zero <<= ShAmt;
    Known.One <<= ShAmt;

    // Low bits known zero.
    Known.Zero.setLowBits(ShAmt);
    break;
  }
  case X86ISD::VSRLI: {
    unsigned ShAmt = Op.getConstantOperandVal(1);
    if (ShAmt >= BitWidth)
      break;

    APInt DemandedMask = OriginalDemandedBits << ShAmt;

    if (SimplifyDemandedBits(Op.getOperand(0), DemandedMask,
                             OriginalDemandedElts, Known, TLO, Depth + 1))
      return true;

    assert(!Known.hasConflict() && "Bits known to be one AND zero?");
    Known.Zero.lshrInPlace(ShAmt);
    Known.One.lshrInPlace(ShAmt);

    // High bits known zero.
    Known.Zero.setHighBits(ShAmt);
    break;
  }
  case X86ISD::VSRAI: {
    SDValue Op0 = Op.getOperand(0);
    SDValue Op1 = Op.getOperand(1);

    unsigned ShAmt = cast<ConstantSDNode>(Op1)->getZExtValue();
    if (ShAmt >= BitWidth)
      break;

    APInt DemandedMask = OriginalDemandedBits << ShAmt;

    // If we just want the sign bit then we don't need to shift it.
    if (OriginalDemandedBits.isSignMask())
      return TLO.CombineTo(Op, Op0);

    // fold (VSRAI (VSHLI X, C1), C1) --> X iff NumSignBits(X) > C1
    if (Op0.getOpcode() == X86ISD::VSHLI &&
        Op.getOperand(1) == Op0.getOperand(1)) {
      SDValue Op00 = Op0.getOperand(0);
      unsigned NumSignBits =
          TLO.DAG.ComputeNumSignBits(Op00, OriginalDemandedElts);
      if (ShAmt < NumSignBits)
        return TLO.CombineTo(Op, Op00);
    }

    // If any of the demanded bits are produced by the sign extension, we also
    // demand the input sign bit.
    if (OriginalDemandedBits.countLeadingZeros() < ShAmt)
      DemandedMask.setSignBit();

    if (SimplifyDemandedBits(Op0, DemandedMask, OriginalDemandedElts, Known,
                             TLO, Depth + 1))
      return true;

    assert(!Known.hasConflict() && "Bits known to be one AND zero?");
    Known.Zero.lshrInPlace(ShAmt);
    Known.One.lshrInPlace(ShAmt);

    // If the input sign bit is known to be zero, or if none of the top bits
    // are demanded, turn this into an unsigned shift right.
    if (Known.Zero[BitWidth - ShAmt - 1] ||
        OriginalDemandedBits.countLeadingZeros() >= ShAmt)
      return TLO.CombineTo(
          Op, TLO.DAG.getNode(X86ISD::VSRLI, SDLoc(Op), VT, Op0, Op1));

    // High bits are known one.
    if (Known.One[BitWidth - ShAmt - 1])
      Known.One.setHighBits(ShAmt);
    break;
  }
  case X86ISD::PEXTRB:
  case X86ISD::PEXTRW: {
    SDValue Vec = Op.getOperand(0);
    auto *CIdx = dyn_cast<ConstantSDNode>(Op.getOperand(1));
    MVT VecVT = Vec.getSimpleValueType();
    unsigned NumVecElts = VecVT.getVectorNumElements();

    if (CIdx && CIdx->getAPIntValue().ult(NumVecElts)) {
      unsigned Idx = CIdx->getZExtValue();
      unsigned VecBitWidth = VecVT.getScalarSizeInBits();

      // If we demand no bits from the vector then we must have demanded
      // bits from the implict zext - simplify to zero.
      APInt DemandedVecBits = OriginalDemandedBits.trunc(VecBitWidth);
      if (DemandedVecBits == 0)
        return TLO.CombineTo(Op, TLO.DAG.getConstant(0, SDLoc(Op), VT));

      APInt KnownUndef, KnownZero;
      APInt DemandedVecElts = APInt::getOneBitSet(NumVecElts, Idx);
      if (SimplifyDemandedVectorElts(Vec, DemandedVecElts, KnownUndef,
                                     KnownZero, TLO, Depth + 1))
        return true;

      KnownBits KnownVec;
      if (SimplifyDemandedBits(Vec, DemandedVecBits, DemandedVecElts,
                               KnownVec, TLO, Depth + 1))
        return true;

      if (SDValue V = SimplifyMultipleUseDemandedBits(
              Vec, DemandedVecBits, DemandedVecElts, TLO.DAG, Depth + 1))
        return TLO.CombineTo(
            Op, TLO.DAG.getNode(Opc, SDLoc(Op), VT, V, Op.getOperand(1)));

      Known = KnownVec.zext(BitWidth);
      return false;
    }
    break;
  }
  case X86ISD::PINSRB:
  case X86ISD::PINSRW: {
    SDValue Vec = Op.getOperand(0);
    SDValue Scl = Op.getOperand(1);
    auto *CIdx = dyn_cast<ConstantSDNode>(Op.getOperand(2));
    MVT VecVT = Vec.getSimpleValueType();

    if (CIdx && CIdx->getAPIntValue().ult(VecVT.getVectorNumElements())) {
      unsigned Idx = CIdx->getZExtValue();
      if (!OriginalDemandedElts[Idx])
        return TLO.CombineTo(Op, Vec);

      KnownBits KnownVec;
      APInt DemandedVecElts(OriginalDemandedElts);
      DemandedVecElts.clearBit(Idx);
      if (SimplifyDemandedBits(Vec, OriginalDemandedBits, DemandedVecElts,
                               KnownVec, TLO, Depth + 1))
        return true;

      KnownBits KnownScl;
      unsigned NumSclBits = Scl.getScalarValueSizeInBits();
      APInt DemandedSclBits = OriginalDemandedBits.zext(NumSclBits);
      if (SimplifyDemandedBits(Scl, DemandedSclBits, KnownScl, TLO, Depth + 1))
        return true;

      KnownScl = KnownScl.trunc(VecVT.getScalarSizeInBits());
      Known.One = KnownVec.One & KnownScl.One;
      Known.Zero = KnownVec.Zero & KnownScl.Zero;
      return false;
    }
    break;
  }
  case X86ISD::PACKSS:
    // PACKSS saturates to MIN/MAX integer values. So if we just want the
    // sign bit then we can just ask for the source operands sign bit.
    // TODO - add known bits handling.
    if (OriginalDemandedBits.isSignMask()) {
      APInt DemandedLHS, DemandedRHS;
      getPackDemandedElts(VT, OriginalDemandedElts, DemandedLHS, DemandedRHS);

      KnownBits KnownLHS, KnownRHS;
      APInt SignMask = APInt::getSignMask(BitWidth * 2);
      if (SimplifyDemandedBits(Op.getOperand(0), SignMask, DemandedLHS,
                               KnownLHS, TLO, Depth + 1))
        return true;
      if (SimplifyDemandedBits(Op.getOperand(1), SignMask, DemandedRHS,
                               KnownRHS, TLO, Depth + 1))
        return true;

      // Attempt to avoid multi-use ops if we don't need anything from them.
      SDValue DemandedOp0 = SimplifyMultipleUseDemandedBits(
          Op.getOperand(0), SignMask, DemandedLHS, TLO.DAG, Depth + 1);
      SDValue DemandedOp1 = SimplifyMultipleUseDemandedBits(
          Op.getOperand(1), SignMask, DemandedRHS, TLO.DAG, Depth + 1);
      if (DemandedOp0 || DemandedOp1) {
        SDValue Op0 = DemandedOp0 ? DemandedOp0 : Op.getOperand(0);
        SDValue Op1 = DemandedOp1 ? DemandedOp1 : Op.getOperand(1);
        return TLO.CombineTo(Op, TLO.DAG.getNode(Opc, SDLoc(Op), VT, Op0, Op1));
      }
    }
    // TODO - add general PACKSS/PACKUS SimplifyDemandedBits support.
    break;
  case X86ISD::PCMPGT:
    // icmp sgt(0, R) == ashr(R, BitWidth-1).
    // iff we only need the sign bit then we can use R directly.
    if (OriginalDemandedBits.isSignMask() &&
        ISD::isBuildVectorAllZeros(Op.getOperand(0).getNode()))
      return TLO.CombineTo(Op, Op.getOperand(1));
    break;
  case X86ISD::MOVMSK: {
    SDValue Src = Op.getOperand(0);
    MVT SrcVT = Src.getSimpleValueType();
    unsigned SrcBits = SrcVT.getScalarSizeInBits();
    unsigned NumElts = SrcVT.getVectorNumElements();

    // If we don't need the sign bits at all just return zero.
    if (OriginalDemandedBits.countTrailingZeros() >= NumElts)
      return TLO.CombineTo(Op, TLO.DAG.getConstant(0, SDLoc(Op), VT));

    // Only demand the vector elements of the sign bits we need.
    APInt KnownUndef, KnownZero;
    APInt DemandedElts = OriginalDemandedBits.zextOrTrunc(NumElts);
    if (SimplifyDemandedVectorElts(Src, DemandedElts, KnownUndef, KnownZero,
                                   TLO, Depth + 1))
      return true;

    Known.Zero = KnownZero.zextOrSelf(BitWidth);
    Known.Zero.setHighBits(BitWidth - NumElts);

    // MOVMSK only uses the MSB from each vector element.
    KnownBits KnownSrc;
    if (SimplifyDemandedBits(Src, APInt::getSignMask(SrcBits), DemandedElts,
                             KnownSrc, TLO, Depth + 1))
      return true;

    if (KnownSrc.One[SrcBits - 1])
      Known.One.setLowBits(NumElts);
    else if (KnownSrc.Zero[SrcBits - 1])
      Known.Zero.setLowBits(NumElts);
    return false;
  }
  case X86ISD::BEXTR: {
    SDValue Op0 = Op.getOperand(0);
    SDValue Op1 = Op.getOperand(1);

    // Only bottom 16-bits of the control bits are required.
    if (auto *Cst1 = dyn_cast<ConstantSDNode>(Op1)) {
      // NOTE: SimplifyDemandedBits won't do this for constants.
      const APInt &Val1 = Cst1->getAPIntValue();
      APInt MaskedVal1 = Val1 & 0xFFFF;
      if (MaskedVal1 != Val1) {
        SDLoc DL(Op);
        return TLO.CombineTo(
            Op, TLO.DAG.getNode(X86ISD::BEXTR, DL, VT, Op0,
                                TLO.DAG.getConstant(MaskedVal1, DL, VT)));
      }
    }

    KnownBits Known1;
    APInt DemandedMask(APInt::getLowBitsSet(BitWidth, 16));
    if (SimplifyDemandedBits(Op1, DemandedMask, Known1, TLO, Depth + 1))
      return true;

    // If the length is 0, replace with 0.
    KnownBits LengthBits = Known1.extractBits(8, 8);
    if (LengthBits.isZero())
      return TLO.CombineTo(Op, TLO.DAG.getConstant(0, SDLoc(Op), VT));

    break;
  }
  }

  return TargetLowering::SimplifyDemandedBitsForTargetNode(
      Op, OriginalDemandedBits, OriginalDemandedElts, Known, TLO, Depth);
}

SDValue X86TargetLowering::SimplifyMultipleUseDemandedBitsForTargetNode(
    SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts,
    SelectionDAG &DAG, unsigned Depth) const {
  int NumElts = DemandedElts.getBitWidth();
  unsigned Opc = Op.getOpcode();
  EVT VT = Op.getValueType();

  switch (Opc) {
  case X86ISD::PINSRB:
  case X86ISD::PINSRW: {
    // If we don't demand the inserted element, return the base vector.
    SDValue Vec = Op.getOperand(0);
    auto *CIdx = dyn_cast<ConstantSDNode>(Op.getOperand(2));
    MVT VecVT = Vec.getSimpleValueType();
    if (CIdx && CIdx->getAPIntValue().ult(VecVT.getVectorNumElements()) &&
        !DemandedElts[CIdx->getZExtValue()])
      return Vec;
     break;
  }
  case X86ISD::PCMPGT:
    // icmp sgt(0, R) == ashr(R, BitWidth-1).
    // iff we only need the sign bit then we can use R directly.
    if (DemandedBits.isSignMask() &&
        ISD::isBuildVectorAllZeros(Op.getOperand(0).getNode()))
      return Op.getOperand(1);
    break;
  }

  APInt ShuffleUndef, ShuffleZero;
  SmallVector<int, 16> ShuffleMask;
  SmallVector<SDValue, 2> ShuffleOps;
  if (getTargetShuffleInputs(Op, DemandedElts, ShuffleOps, ShuffleMask,
                             ShuffleUndef, ShuffleZero, DAG, Depth, false)) {
    // If all the demanded elts are from one operand and are inline,
    // then we can use the operand directly.
    int NumOps = ShuffleOps.size();
    if (ShuffleMask.size() == (unsigned)NumElts &&
        llvm::all_of(ShuffleOps, [VT](SDValue V) {
          return VT.getSizeInBits() == V.getValueSizeInBits();
        })) {

      if (DemandedElts.isSubsetOf(ShuffleUndef))
        return DAG.getUNDEF(VT);
      if (DemandedElts.isSubsetOf(ShuffleUndef | ShuffleZero))
        return getZeroVector(VT.getSimpleVT(), Subtarget, DAG, SDLoc(Op));

      // Bitmask that indicates which ops have only been accessed 'inline'.
      APInt IdentityOp = APInt::getAllOnesValue(NumOps);
      for (int i = 0; i != NumElts; ++i) {
        int M = ShuffleMask[i];
        if (!DemandedElts[i] || ShuffleUndef[i])
          continue;
        int OpIdx = M / NumElts;
        int EltIdx = M % NumElts;
        if (M < 0 || EltIdx != i) {
          IdentityOp.clearAllBits();
          break;
        }
        IdentityOp &= APInt::getOneBitSet(NumOps, OpIdx);
        if (IdentityOp == 0)
          break;
      }
      assert((IdentityOp == 0 || IdentityOp.countPopulation() == 1) &&
             "Multiple identity shuffles detected");

      if (IdentityOp != 0)
        return DAG.getBitcast(VT, ShuffleOps[IdentityOp.countTrailingZeros()]);
    }
  }

  return TargetLowering::SimplifyMultipleUseDemandedBitsForTargetNode(
      Op, DemandedBits, DemandedElts, DAG, Depth);
}

// Helper to peek through bitops/setcc to determine size of source vector.
// Allows combineBitcastvxi1 to determine what size vector generated a <X x i1>.
static bool checkBitcastSrcVectorSize(SDValue Src, unsigned Size) {
  switch (Src.getOpcode()) {
  case ISD::SETCC:
    return Src.getOperand(0).getValueSizeInBits() == Size;
  case ISD::AND:
  case ISD::XOR:
  case ISD::OR:
    return checkBitcastSrcVectorSize(Src.getOperand(0), Size) &&
           checkBitcastSrcVectorSize(Src.getOperand(1), Size);
  }
  return false;
}

// Helper to flip between AND/OR/XOR opcodes and their X86ISD FP equivalents.
static unsigned getAltBitOpcode(unsigned Opcode) {
  switch(Opcode) {
  case ISD::AND: return X86ISD::FAND;
  case ISD::OR: return X86ISD::FOR;
  case ISD::XOR: return X86ISD::FXOR;
  case X86ISD::ANDNP: return X86ISD::FANDN;
  }
  llvm_unreachable("Unknown bitwise opcode");
}

// Helper to adjust v4i32 MOVMSK expansion to work with SSE1-only targets.
static SDValue adjustBitcastSrcVectorSSE1(SelectionDAG &DAG, SDValue Src,
                                          const SDLoc &DL) {
  EVT SrcVT = Src.getValueType();
  if (SrcVT != MVT::v4i1)
    return SDValue();

  switch (Src.getOpcode()) {
  case ISD::SETCC:
    if (Src.getOperand(0).getValueType() == MVT::v4i32 &&
        ISD::isBuildVectorAllZeros(Src.getOperand(1).getNode()) &&
        cast<CondCodeSDNode>(Src.getOperand(2))->get() == ISD::SETLT) {
      SDValue Op0 = Src.getOperand(0);
      if (ISD::isNormalLoad(Op0.getNode()))
        return DAG.getBitcast(MVT::v4f32, Op0);
      if (Op0.getOpcode() == ISD::BITCAST &&
          Op0.getOperand(0).getValueType() == MVT::v4f32)
        return Op0.getOperand(0);
    }
    break;
  case ISD::AND:
  case ISD::XOR:
  case ISD::OR: {
    SDValue Op0 = adjustBitcastSrcVectorSSE1(DAG, Src.getOperand(0), DL);
    SDValue Op1 = adjustBitcastSrcVectorSSE1(DAG, Src.getOperand(1), DL);
    if (Op0 && Op1)
      return DAG.getNode(getAltBitOpcode(Src.getOpcode()), DL, MVT::v4f32, Op0,
                         Op1);
    break;
  }
  }
  return SDValue();
}

// Helper to push sign extension of vXi1 SETCC result through bitops.
static SDValue signExtendBitcastSrcVector(SelectionDAG &DAG, EVT SExtVT,
                                          SDValue Src, const SDLoc &DL) {
  switch (Src.getOpcode()) {
  case ISD::SETCC:
    return DAG.getNode(ISD::SIGN_EXTEND, DL, SExtVT, Src);
  case ISD::AND:
  case ISD::XOR:
  case ISD::OR:
    return DAG.getNode(
        Src.getOpcode(), DL, SExtVT,
        signExtendBitcastSrcVector(DAG, SExtVT, Src.getOperand(0), DL),
        signExtendBitcastSrcVector(DAG, SExtVT, Src.getOperand(1), DL));
  }
  llvm_unreachable("Unexpected node type for vXi1 sign extension");
}

// Try to match patterns such as
// (i16 bitcast (v16i1 x))
// ->
// (i16 movmsk (16i8 sext (v16i1 x)))
// before the illegal vector is scalarized on subtargets that don't have legal
// vxi1 types.
static SDValue combineBitcastvxi1(SelectionDAG &DAG, EVT VT, SDValue Src,
                                  const SDLoc &DL,
                                  const X86Subtarget &Subtarget) {
  EVT SrcVT = Src.getValueType();
  if (!SrcVT.isSimple() || SrcVT.getScalarType() != MVT::i1)
    return SDValue();

  // Recognize the IR pattern for the movmsk intrinsic under SSE1 before type
  // legalization destroys the v4i32 type.
  if (Subtarget.hasSSE1() && !Subtarget.hasSSE2()) {
    if (SDValue V = adjustBitcastSrcVectorSSE1(DAG, Src, DL)) {
      V = DAG.getNode(X86ISD::MOVMSK, DL, MVT::i32,
                      DAG.getBitcast(MVT::v4f32, V));
      return DAG.getZExtOrTrunc(V, DL, VT);
    }
  }

  // If the input is a truncate from v16i8 or v32i8 go ahead and use a
  // movmskb even with avx512. This will be better than truncating to vXi1 and
  // using a kmov. This can especially help KNL if the input is a v16i8/v32i8
  // vpcmpeqb/vpcmpgtb.
  bool IsTruncated = Src.getOpcode() == ISD::TRUNCATE && Src.hasOneUse() &&
                     (Src.getOperand(0).getValueType() == MVT::v16i8 ||
                      Src.getOperand(0).getValueType() == MVT::v32i8 ||
                      Src.getOperand(0).getValueType() == MVT::v64i8);

  // With AVX512 vxi1 types are legal and we prefer using k-regs.
  // MOVMSK is supported in SSE2 or later.
  if (!Subtarget.hasSSE2() || (Subtarget.hasAVX512() && !IsTruncated))
    return SDValue();

  // There are MOVMSK flavors for types v16i8, v32i8, v4f32, v8f32, v4f64 and
  // v8f64. So all legal 128-bit and 256-bit vectors are covered except for
  // v8i16 and v16i16.
  // For these two cases, we can shuffle the upper element bytes to a
  // consecutive sequence at the start of the vector and treat the results as
  // v16i8 or v32i8, and for v16i8 this is the preferable solution. However,
  // for v16i16 this is not the case, because the shuffle is expensive, so we
  // avoid sign-extending to this type entirely.
  // For example, t0 := (v8i16 sext(v8i1 x)) needs to be shuffled as:
  // (v16i8 shuffle <0,2,4,6,8,10,12,14,u,u,...,u> (v16i8 bitcast t0), undef)
  MVT SExtVT;
  bool PropagateSExt = false;
  switch (SrcVT.getSimpleVT().SimpleTy) {
  default:
    return SDValue();
  case MVT::v2i1:
    SExtVT = MVT::v2i64;
    break;
  case MVT::v4i1:
    SExtVT = MVT::v4i32;
    // For cases such as (i4 bitcast (v4i1 setcc v4i64 v1, v2))
    // sign-extend to a 256-bit operation to avoid truncation.
    if (Subtarget.hasAVX() && checkBitcastSrcVectorSize(Src, 256)) {
      SExtVT = MVT::v4i64;
      PropagateSExt = true;
    }
    break;
  case MVT::v8i1:
    SExtVT = MVT::v8i16;
    // For cases such as (i8 bitcast (v8i1 setcc v8i32 v1, v2)),
    // sign-extend to a 256-bit operation to match the compare.
    // If the setcc operand is 128-bit, prefer sign-extending to 128-bit over
    // 256-bit because the shuffle is cheaper than sign extending the result of
    // the compare.
    if (Subtarget.hasAVX() && (checkBitcastSrcVectorSize(Src, 256) ||
                               checkBitcastSrcVectorSize(Src, 512))) {
      SExtVT = MVT::v8i32;
      PropagateSExt = true;
    }
    break;
  case MVT::v16i1:
    SExtVT = MVT::v16i8;
    // For the case (i16 bitcast (v16i1 setcc v16i16 v1, v2)),
    // it is not profitable to sign-extend to 256-bit because this will
    // require an extra cross-lane shuffle which is more expensive than
    // truncating the result of the compare to 128-bits.
    break;
  case MVT::v32i1:
    SExtVT = MVT::v32i8;
    break;
  case MVT::v64i1:
    // If we have AVX512F, but not AVX512BW and the input is truncated from
    // v64i8 checked earlier. Then split the input and make two pmovmskbs.
    if (Subtarget.hasAVX512()) {
      if (Subtarget.hasBWI())
        return SDValue();
      SExtVT = MVT::v64i8;
      break;
    }
    // Split if this is a <64 x i8> comparison result.
    if (checkBitcastSrcVectorSize(Src, 512)) {
      SExtVT = MVT::v64i8;
      break;
    }
    return SDValue();
  };

  SDValue V = PropagateSExt ? signExtendBitcastSrcVector(DAG, SExtVT, Src, DL)
                            : DAG.getNode(ISD::SIGN_EXTEND, DL, SExtVT, Src);

  if (SExtVT == MVT::v16i8 || SExtVT == MVT::v32i8 || SExtVT == MVT::v64i8) {
    V = getPMOVMSKB(DL, V, DAG, Subtarget);
  } else {
    if (SExtVT == MVT::v8i16)
      V = DAG.getNode(X86ISD::PACKSS, DL, MVT::v16i8, V,
                      DAG.getUNDEF(MVT::v8i16));
    V = DAG.getNode(X86ISD::MOVMSK, DL, MVT::i32, V);
  }

  EVT IntVT =
      EVT::getIntegerVT(*DAG.getContext(), SrcVT.getVectorNumElements());
  V = DAG.getZExtOrTrunc(V, DL, IntVT);
  return DAG.getBitcast(VT, V);
}

// Convert a vXi1 constant build vector to the same width scalar integer.
static SDValue combinevXi1ConstantToInteger(SDValue Op, SelectionDAG &DAG) {
  EVT SrcVT = Op.getValueType();
  assert(SrcVT.getVectorElementType() == MVT::i1 &&
         "Expected a vXi1 vector");
  assert(ISD::isBuildVectorOfConstantSDNodes(Op.getNode()) &&
         "Expected a constant build vector");

  APInt Imm(SrcVT.getVectorNumElements(), 0);
  for (unsigned Idx = 0, e = Op.getNumOperands(); Idx < e; ++Idx) {
    SDValue In = Op.getOperand(Idx);
    if (!In.isUndef() && (cast<ConstantSDNode>(In)->getZExtValue() & 0x1))
      Imm.setBit(Idx);
  }
  EVT IntVT = EVT::getIntegerVT(*DAG.getContext(), Imm.getBitWidth());
  return DAG.getConstant(Imm, SDLoc(Op), IntVT);
}

static SDValue combineCastedMaskArithmetic(SDNode *N, SelectionDAG &DAG,
                                           TargetLowering::DAGCombinerInfo &DCI,
                                           const X86Subtarget &Subtarget) {
  assert(N->getOpcode() == ISD::BITCAST && "Expected a bitcast");

  if (!DCI.isBeforeLegalizeOps())
    return SDValue();

  // Only do this if we have k-registers.
  if (!Subtarget.hasAVX512())
    return SDValue();

  EVT DstVT = N->getValueType(0);
  SDValue Op = N->getOperand(0);
  EVT SrcVT = Op.getValueType();

  if (!Op.hasOneUse())
    return SDValue();

  // Look for logic ops.
  if (Op.getOpcode() != ISD::AND &&
      Op.getOpcode() != ISD::OR &&
      Op.getOpcode() != ISD::XOR)
    return SDValue();

  // Make sure we have a bitcast between mask registers and a scalar type.
  if (!(SrcVT.isVector() && SrcVT.getVectorElementType() == MVT::i1 &&
        DstVT.isScalarInteger()) &&
      !(DstVT.isVector() && DstVT.getVectorElementType() == MVT::i1 &&
        SrcVT.isScalarInteger()))
    return SDValue();

  SDValue LHS = Op.getOperand(0);
  SDValue RHS = Op.getOperand(1);

  if (LHS.hasOneUse() && LHS.getOpcode() == ISD::BITCAST &&
      LHS.getOperand(0).getValueType() == DstVT)
    return DAG.getNode(Op.getOpcode(), SDLoc(N), DstVT, LHS.getOperand(0),
                       DAG.getBitcast(DstVT, RHS));

  if (RHS.hasOneUse() && RHS.getOpcode() == ISD::BITCAST &&
      RHS.getOperand(0).getValueType() == DstVT)
    return DAG.getNode(Op.getOpcode(), SDLoc(N), DstVT,
                       DAG.getBitcast(DstVT, LHS), RHS.getOperand(0));

  // If the RHS is a vXi1 build vector, this is a good reason to flip too.
  // Most of these have to move a constant from the scalar domain anyway.
  if (ISD::isBuildVectorOfConstantSDNodes(RHS.getNode())) {
    RHS = combinevXi1ConstantToInteger(RHS, DAG);
    return DAG.getNode(Op.getOpcode(), SDLoc(N), DstVT,
                       DAG.getBitcast(DstVT, LHS), RHS);
  }

  return SDValue();
}

static SDValue createMMXBuildVector(BuildVectorSDNode *BV, SelectionDAG &DAG,
                                    const X86Subtarget &Subtarget) {
  SDLoc DL(BV);
  unsigned NumElts = BV->getNumOperands();
  SDValue Splat = BV->getSplatValue();

  // Build MMX element from integer GPR or SSE float values.
  auto CreateMMXElement = [&](SDValue V) {
    if (V.isUndef())
      return DAG.getUNDEF(MVT::x86mmx);
    if (V.getValueType().isFloatingPoint()) {
      if (Subtarget.hasSSE1() && !isa<ConstantFPSDNode>(V)) {
        V = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v4f32, V);
        V = DAG.getBitcast(MVT::v2i64, V);
        return DAG.getNode(X86ISD::MOVDQ2Q, DL, MVT::x86mmx, V);
      }
      V = DAG.getBitcast(MVT::i32, V);
    } else {
      V = DAG.getAnyExtOrTrunc(V, DL, MVT::i32);
    }
    return DAG.getNode(X86ISD::MMX_MOVW2D, DL, MVT::x86mmx, V);
  };

  // Convert build vector ops to MMX data in the bottom elements.
  SmallVector<SDValue, 8> Ops;

  // Broadcast - use (PUNPCKL+)PSHUFW to broadcast single element.
  if (Splat) {
    if (Splat.isUndef())
      return DAG.getUNDEF(MVT::x86mmx);

    Splat = CreateMMXElement(Splat);

    if (Subtarget.hasSSE1()) {
      // Unpack v8i8 to splat i8 elements to lowest 16-bits.
      if (NumElts == 8)
        Splat = DAG.getNode(
            ISD::INTRINSIC_WO_CHAIN, DL, MVT::x86mmx,
            DAG.getConstant(Intrinsic::x86_mmx_punpcklbw, DL, MVT::i32), Splat,
            Splat);

      // Use PSHUFW to repeat 16-bit elements.
      unsigned ShufMask = (NumElts > 2 ? 0 : 0x44);
      return DAG.getNode(
          ISD::INTRINSIC_WO_CHAIN, DL, MVT::x86mmx,
          DAG.getTargetConstant(Intrinsic::x86_sse_pshuf_w, DL, MVT::i32),
          Splat, DAG.getTargetConstant(ShufMask, DL, MVT::i8));
    }
    Ops.append(NumElts, Splat);
  } else {
    for (unsigned i = 0; i != NumElts; ++i)
      Ops.push_back(CreateMMXElement(BV->getOperand(i)));
  }

  // Use tree of PUNPCKLs to build up general MMX vector.
  while (Ops.size() > 1) {
    unsigned NumOps = Ops.size();
    unsigned IntrinOp =
        (NumOps == 2 ? Intrinsic::x86_mmx_punpckldq
                     : (NumOps == 4 ? Intrinsic::x86_mmx_punpcklwd
                                    : Intrinsic::x86_mmx_punpcklbw));
    SDValue Intrin = DAG.getConstant(IntrinOp, DL, MVT::i32);
    for (unsigned i = 0; i != NumOps; i += 2)
      Ops[i / 2] = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, MVT::x86mmx, Intrin,
                               Ops[i], Ops[i + 1]);
    Ops.resize(NumOps / 2);
  }

  return Ops[0];
}

static SDValue combineBitcast(SDNode *N, SelectionDAG &DAG,
                              TargetLowering::DAGCombinerInfo &DCI,
                              const X86Subtarget &Subtarget) {
  SDValue N0 = N->getOperand(0);
  EVT VT = N->getValueType(0);
  EVT SrcVT = N0.getValueType();

  // Try to match patterns such as
  // (i16 bitcast (v16i1 x))
  // ->
  // (i16 movmsk (16i8 sext (v16i1 x)))
  // before the setcc result is scalarized on subtargets that don't have legal
  // vxi1 types.
  if (DCI.isBeforeLegalize()) {
    SDLoc dl(N);
    if (SDValue V = combineBitcastvxi1(DAG, VT, N0, dl, Subtarget))
      return V;

    // If this is a bitcast between a MVT::v4i1/v2i1 and an illegal integer
    // type, widen both sides to avoid a trip through memory.
    if ((VT == MVT::v4i1 || VT == MVT::v2i1) && SrcVT.isScalarInteger() &&
        Subtarget.hasAVX512()) {
      N0 = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i8, N0);
      N0 = DAG.getBitcast(MVT::v8i1, N0);
      return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT, N0,
                         DAG.getIntPtrConstant(0, dl));
    }

    // If this is a bitcast between a MVT::v4i1/v2i1 and an illegal integer
    // type, widen both sides to avoid a trip through memory.
    if ((SrcVT == MVT::v4i1 || SrcVT == MVT::v2i1) && VT.isScalarInteger() &&
        Subtarget.hasAVX512()) {
      // Use zeros for the widening if we already have some zeroes. This can
      // allow SimplifyDemandedBits to remove scalar ANDs that may be down
      // stream of this.
      // FIXME: It might make sense to detect a concat_vectors with a mix of
      // zeroes and undef and turn it into insert_subvector for i1 vectors as
      // a separate combine. What we can't do is canonicalize the operands of
      // such a concat or we'll get into a loop with SimplifyDemandedBits.
      if (N0.getOpcode() == ISD::CONCAT_VECTORS) {
        SDValue LastOp = N0.getOperand(N0.getNumOperands() - 1);
        if (ISD::isBuildVectorAllZeros(LastOp.getNode())) {
          SrcVT = LastOp.getValueType();
          unsigned NumConcats = 8 / SrcVT.getVectorNumElements();
          SmallVector<SDValue, 4> Ops(N0->op_begin(), N0->op_end());
          Ops.resize(NumConcats, DAG.getConstant(0, dl, SrcVT));
          N0 = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v8i1, Ops);
          N0 = DAG.getBitcast(MVT::i8, N0);
          return DAG.getNode(ISD::TRUNCATE, dl, VT, N0);
        }
      }

      unsigned NumConcats = 8 / SrcVT.getVectorNumElements();
      SmallVector<SDValue, 4> Ops(NumConcats, DAG.getUNDEF(SrcVT));
      Ops[0] = N0;
      N0 = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v8i1, Ops);
      N0 = DAG.getBitcast(MVT::i8, N0);
      return DAG.getNode(ISD::TRUNCATE, dl, VT, N0);
    }
  }

  // Look for (i8 (bitcast (v8i1 (extract_subvector (v16i1 X), 0)))) and
  // replace with (i8 (trunc (i16 (bitcast (v16i1 X))))). This can occur
  // due to insert_subvector legalization on KNL. By promoting the copy to i16
  // we can help with known bits propagation from the vXi1 domain to the
  // scalar domain.
  if (VT == MVT::i8 && SrcVT == MVT::v8i1 && Subtarget.hasAVX512() &&
      !Subtarget.hasDQI() && N0.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
      N0.getOperand(0).getValueType() == MVT::v16i1 &&
      isNullConstant(N0.getOperand(1)))
    return DAG.getNode(ISD::TRUNCATE, SDLoc(N), VT,
                       DAG.getBitcast(MVT::i16, N0.getOperand(0)));

  // Canonicalize (bitcast (vbroadcast_load)) so that the output of the bitcast
  // and the vbroadcast_load are both integer or both fp. In some cases this
  // will remove the bitcast entirely.
  if (N0.getOpcode() == X86ISD::VBROADCAST_LOAD && N0.hasOneUse() &&
       VT.isFloatingPoint() != SrcVT.isFloatingPoint() && VT.isVector()) {
    auto *BCast = cast<MemIntrinsicSDNode>(N0);
    unsigned SrcVTSize = SrcVT.getScalarSizeInBits();
    unsigned MemSize = BCast->getMemoryVT().getScalarSizeInBits();
    // Don't swap i8/i16 since don't have fp types that size.
    if (MemSize >= 32) {
      MVT MemVT = VT.isFloatingPoint() ? MVT::getFloatingPointVT(MemSize)
                                       : MVT::getIntegerVT(MemSize);
      MVT LoadVT = VT.isFloatingPoint() ? MVT::getFloatingPointVT(SrcVTSize)
                                        : MVT::getIntegerVT(SrcVTSize);
      LoadVT = MVT::getVectorVT(LoadVT, SrcVT.getVectorNumElements());

      SDVTList Tys = DAG.getVTList(LoadVT, MVT::Other);
      SDValue Ops[] = { BCast->getChain(), BCast->getBasePtr() };
      SDValue ResNode =
          DAG.getMemIntrinsicNode(X86ISD::VBROADCAST_LOAD, SDLoc(N), Tys, Ops,
                                  MemVT, BCast->getMemOperand());
      DAG.ReplaceAllUsesOfValueWith(SDValue(BCast, 1), ResNode.getValue(1));
      return DAG.getBitcast(VT, ResNode);
    }
  }

  // Since MMX types are special and don't usually play with other vector types,
  // it's better to handle them early to be sure we emit efficient code by
  // avoiding store-load conversions.
  if (VT == MVT::x86mmx) {
    // Detect MMX constant vectors.
    APInt UndefElts;
    SmallVector<APInt, 1> EltBits;
    if (getTargetConstantBitsFromNode(N0, 64, UndefElts, EltBits)) {
      SDLoc DL(N0);
      // Handle zero-extension of i32 with MOVD.
      if (EltBits[0].countLeadingZeros() >= 32)
        return DAG.getNode(X86ISD::MMX_MOVW2D, DL, VT,
                           DAG.getConstant(EltBits[0].trunc(32), DL, MVT::i32));
      // Else, bitcast to a double.
      // TODO - investigate supporting sext 32-bit immediates on x86_64.
      APFloat F64(APFloat::IEEEdouble(), EltBits[0]);
      return DAG.getBitcast(VT, DAG.getConstantFP(F64, DL, MVT::f64));
    }

    // Detect bitcasts to x86mmx low word.
    if (N0.getOpcode() == ISD::BUILD_VECTOR &&
        (SrcVT == MVT::v2i32 || SrcVT == MVT::v4i16 || SrcVT == MVT::v8i8) &&
        N0.getOperand(0).getValueType() == SrcVT.getScalarType()) {
      bool LowUndef = true, AllUndefOrZero = true;
      for (unsigned i = 1, e = SrcVT.getVectorNumElements(); i != e; ++i) {
        SDValue Op = N0.getOperand(i);
        LowUndef &= Op.isUndef() || (i >= e/2);
        AllUndefOrZero &= (Op.isUndef() || isNullConstant(Op));
      }
      if (AllUndefOrZero) {
        SDValue N00 = N0.getOperand(0);
        SDLoc dl(N00);
        N00 = LowUndef ? DAG.getAnyExtOrTrunc(N00, dl, MVT::i32)
                       : DAG.getZExtOrTrunc(N00, dl, MVT::i32);
        return DAG.getNode(X86ISD::MMX_MOVW2D, dl, VT, N00);
      }
    }

    // Detect bitcasts of 64-bit build vectors and convert to a
    // MMX UNPCK/PSHUFW which takes MMX type inputs with the value in the
    // lowest element.
    if (N0.getOpcode() == ISD::BUILD_VECTOR &&
        (SrcVT == MVT::v2f32 || SrcVT == MVT::v2i32 || SrcVT == MVT::v4i16 ||
         SrcVT == MVT::v8i8))
      return createMMXBuildVector(cast<BuildVectorSDNode>(N0), DAG, Subtarget);

    // Detect bitcasts between element or subvector extraction to x86mmx.
    if ((N0.getOpcode() == ISD::EXTRACT_VECTOR_ELT ||
         N0.getOpcode() == ISD::EXTRACT_SUBVECTOR) &&
        isNullConstant(N0.getOperand(1))) {
      SDValue N00 = N0.getOperand(0);
      if (N00.getValueType().is128BitVector())
        return DAG.getNode(X86ISD::MOVDQ2Q, SDLoc(N00), VT,
                           DAG.getBitcast(MVT::v2i64, N00));
    }

    // Detect bitcasts from FP_TO_SINT to x86mmx.
    if (SrcVT == MVT::v2i32 && N0.getOpcode() == ISD::FP_TO_SINT) {
      SDLoc DL(N0);
      SDValue Res = DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v4i32, N0,
                                DAG.getUNDEF(MVT::v2i32));
      return DAG.getNode(X86ISD::MOVDQ2Q, DL, VT,
                         DAG.getBitcast(MVT::v2i64, Res));
    }
  }

  // Try to remove a bitcast of constant vXi1 vector. We have to legalize
  // most of these to scalar anyway.
  if (Subtarget.hasAVX512() && VT.isScalarInteger() &&
      SrcVT.isVector() && SrcVT.getVectorElementType() == MVT::i1 &&
      ISD::isBuildVectorOfConstantSDNodes(N0.getNode())) {
    return combinevXi1ConstantToInteger(N0, DAG);
  }

  if (Subtarget.hasAVX512() && SrcVT.isScalarInteger() &&
      VT.isVector() && VT.getVectorElementType() == MVT::i1 &&
      isa<ConstantSDNode>(N0)) {
    auto *C = cast<ConstantSDNode>(N0);
    if (C->isAllOnesValue())
      return DAG.getConstant(1, SDLoc(N0), VT);
    if (C->isNullValue())
      return DAG.getConstant(0, SDLoc(N0), VT);
  }

  // Try to remove bitcasts from input and output of mask arithmetic to
  // remove GPR<->K-register crossings.
  if (SDValue V = combineCastedMaskArithmetic(N, DAG, DCI, Subtarget))
    return V;

  // Convert a bitcasted integer logic operation that has one bitcasted
  // floating-point operand into a floating-point logic operation. This may
  // create a load of a constant, but that is cheaper than materializing the
  // constant in an integer register and transferring it to an SSE register or
  // transferring the SSE operand to integer register and back.
  unsigned FPOpcode;
  switch (N0.getOpcode()) {
    case ISD::AND: FPOpcode = X86ISD::FAND; break;
    case ISD::OR:  FPOpcode = X86ISD::FOR;  break;
    case ISD::XOR: FPOpcode = X86ISD::FXOR; break;
    default: return SDValue();
  }

  if (!((Subtarget.hasSSE1() && VT == MVT::f32) ||
        (Subtarget.hasSSE2() && VT == MVT::f64)))
    return SDValue();

  SDValue LogicOp0 = N0.getOperand(0);
  SDValue LogicOp1 = N0.getOperand(1);
  SDLoc DL0(N0);

  // bitcast(logic(bitcast(X), Y)) --> logic'(X, bitcast(Y))
  if (N0.hasOneUse() && LogicOp0.getOpcode() == ISD::BITCAST &&
      LogicOp0.hasOneUse() && LogicOp0.getOperand(0).getValueType() == VT &&
      !isa<ConstantSDNode>(LogicOp0.getOperand(0))) {
    SDValue CastedOp1 = DAG.getBitcast(VT, LogicOp1);
    return DAG.getNode(FPOpcode, DL0, VT, LogicOp0.getOperand(0), CastedOp1);
  }
  // bitcast(logic(X, bitcast(Y))) --> logic'(bitcast(X), Y)
  if (N0.hasOneUse() && LogicOp1.getOpcode() == ISD::BITCAST &&
      LogicOp1.hasOneUse() && LogicOp1.getOperand(0).getValueType() == VT &&
      !isa<ConstantSDNode>(LogicOp1.getOperand(0))) {
    SDValue CastedOp0 = DAG.getBitcast(VT, LogicOp0);
    return DAG.getNode(FPOpcode, DL0, VT, LogicOp1.getOperand(0), CastedOp0);
  }

  return SDValue();
}

// Given a ABS node, detect the following pattern:
// (ABS (SUB (ZERO_EXTEND a), (ZERO_EXTEND b))).
// This is useful as it is the input into a SAD pattern.
static bool detectZextAbsDiff(const SDValue &Abs, SDValue &Op0, SDValue &Op1) {
  SDValue AbsOp1 = Abs->getOperand(0);
  if (AbsOp1.getOpcode() != ISD::SUB)
    return false;

  Op0 = AbsOp1.getOperand(0);
  Op1 = AbsOp1.getOperand(1);

  // Check if the operands of the sub are zero-extended from vectors of i8.
  if (Op0.getOpcode() != ISD::ZERO_EXTEND ||
      Op0.getOperand(0).getValueType().getVectorElementType() != MVT::i8 ||
      Op1.getOpcode() != ISD::ZERO_EXTEND ||
      Op1.getOperand(0).getValueType().getVectorElementType() != MVT::i8)
    return false;

  return true;
}

// Given two zexts of <k x i8> to <k x i32>, create a PSADBW of the inputs
// to these zexts.
static SDValue createPSADBW(SelectionDAG &DAG, const SDValue &Zext0,
                            const SDValue &Zext1, const SDLoc &DL,
                            const X86Subtarget &Subtarget) {
  // Find the appropriate width for the PSADBW.
  EVT InVT = Zext0.getOperand(0).getValueType();
  unsigned RegSize = std::max(128u, (unsigned)InVT.getSizeInBits());

  // "Zero-extend" the i8 vectors. This is not a per-element zext, rather we
  // fill in the missing vector elements with 0.
  unsigned NumConcat = RegSize / InVT.getSizeInBits();
  SmallVector<SDValue, 16> Ops(NumConcat, DAG.getConstant(0, DL, InVT));
  Ops[0] = Zext0.getOperand(0);
  MVT ExtendedVT = MVT::getVectorVT(MVT::i8, RegSize / 8);
  SDValue SadOp0 = DAG.getNode(ISD::CONCAT_VECTORS, DL, ExtendedVT, Ops);
  Ops[0] = Zext1.getOperand(0);
  SDValue SadOp1 = DAG.getNode(ISD::CONCAT_VECTORS, DL, ExtendedVT, Ops);

  // Actually build the SAD, split as 128/256/512 bits for SSE/AVX2/AVX512BW.
  auto PSADBWBuilder = [](SelectionDAG &DAG, const SDLoc &DL,
                          ArrayRef<SDValue> Ops) {
    MVT VT = MVT::getVectorVT(MVT::i64, Ops[0].getValueSizeInBits() / 64);
    return DAG.getNode(X86ISD::PSADBW, DL, VT, Ops);
  };
  MVT SadVT = MVT::getVectorVT(MVT::i64, RegSize / 64);
  return SplitOpsAndApply(DAG, Subtarget, DL, SadVT, { SadOp0, SadOp1 },
                          PSADBWBuilder);
}

// Attempt to replace an min/max v8i16/v16i8 horizontal reduction with
// PHMINPOSUW.
static SDValue combineHorizontalMinMaxResult(SDNode *Extract, SelectionDAG &DAG,
                                             const X86Subtarget &Subtarget) {
  // Bail without SSE41.
  if (!Subtarget.hasSSE41())
    return SDValue();

  EVT ExtractVT = Extract->getValueType(0);
  if (ExtractVT != MVT::i16 && ExtractVT != MVT::i8)
    return SDValue();

  // Check for SMAX/SMIN/UMAX/UMIN horizontal reduction patterns.
  ISD::NodeType BinOp;
  SDValue Src = DAG.matchBinOpReduction(
      Extract, BinOp, {ISD::SMAX, ISD::SMIN, ISD::UMAX, ISD::UMIN}, true);
  if (!Src)
    return SDValue();

  EVT SrcVT = Src.getValueType();
  EVT SrcSVT = SrcVT.getScalarType();
  if (SrcSVT != ExtractVT || (SrcVT.getSizeInBits() % 128) != 0)
    return SDValue();

  SDLoc DL(Extract);
  SDValue MinPos = Src;

  // First, reduce the source down to 128-bit, applying BinOp to lo/hi.
  while (SrcVT.getSizeInBits() > 128) {
    unsigned NumElts = SrcVT.getVectorNumElements();
    unsigned NumSubElts = NumElts / 2;
    SrcVT = EVT::getVectorVT(*DAG.getContext(), SrcSVT, NumSubElts);
    unsigned SubSizeInBits = SrcVT.getSizeInBits();
    SDValue Lo = extractSubVector(MinPos, 0, DAG, DL, SubSizeInBits);
    SDValue Hi = extractSubVector(MinPos, NumSubElts, DAG, DL, SubSizeInBits);
    MinPos = DAG.getNode(BinOp, DL, SrcVT, Lo, Hi);
  }
  assert(((SrcVT == MVT::v8i16 && ExtractVT == MVT::i16) ||
          (SrcVT == MVT::v16i8 && ExtractVT == MVT::i8)) &&
         "Unexpected value type");

  // PHMINPOSUW applies to UMIN(v8i16), for SMIN/SMAX/UMAX we must apply a mask
  // to flip the value accordingly.
  SDValue Mask;
  unsigned MaskEltsBits = ExtractVT.getSizeInBits();
  if (BinOp == ISD::SMAX)
    Mask = DAG.getConstant(APInt::getSignedMaxValue(MaskEltsBits), DL, SrcVT);
  else if (BinOp == ISD::SMIN)
    Mask = DAG.getConstant(APInt::getSignedMinValue(MaskEltsBits), DL, SrcVT);
  else if (BinOp == ISD::UMAX)
    Mask = DAG.getConstant(APInt::getAllOnesValue(MaskEltsBits), DL, SrcVT);

  if (Mask)
    MinPos = DAG.getNode(ISD::XOR, DL, SrcVT, Mask, MinPos);

  // For v16i8 cases we need to perform UMIN on pairs of byte elements,
  // shuffling each upper element down and insert zeros. This means that the
  // v16i8 UMIN will leave the upper element as zero, performing zero-extension
  // ready for the PHMINPOS.
  if (ExtractVT == MVT::i8) {
    SDValue Upper = DAG.getVectorShuffle(
        SrcVT, DL, MinPos, DAG.getConstant(0, DL, MVT::v16i8),
        {1, 16, 3, 16, 5, 16, 7, 16, 9, 16, 11, 16, 13, 16, 15, 16});
    MinPos = DAG.getNode(ISD::UMIN, DL, SrcVT, MinPos, Upper);
  }

  // Perform the PHMINPOS on a v8i16 vector,
  MinPos = DAG.getBitcast(MVT::v8i16, MinPos);
  MinPos = DAG.getNode(X86ISD::PHMINPOS, DL, MVT::v8i16, MinPos);
  MinPos = DAG.getBitcast(SrcVT, MinPos);

  if (Mask)
    MinPos = DAG.getNode(ISD::XOR, DL, SrcVT, Mask, MinPos);

  return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ExtractVT, MinPos,
                     DAG.getIntPtrConstant(0, DL));
}

// Attempt to replace an all_of/any_of/parity style horizontal reduction with a MOVMSK.
static SDValue combineHorizontalPredicateResult(SDNode *Extract,
                                                SelectionDAG &DAG,
                                                const X86Subtarget &Subtarget) {
  // Bail without SSE2.
  if (!Subtarget.hasSSE2())
    return SDValue();

  EVT ExtractVT = Extract->getValueType(0);
  unsigned BitWidth = ExtractVT.getSizeInBits();
  if (ExtractVT != MVT::i64 && ExtractVT != MVT::i32 && ExtractVT != MVT::i16 &&
      ExtractVT != MVT::i8 && ExtractVT != MVT::i1)
    return SDValue();

  // Check for OR(any_of)/AND(all_of)/XOR(parity) horizontal reduction patterns.
  ISD::NodeType BinOp;
  SDValue Match = DAG.matchBinOpReduction(Extract, BinOp, {ISD::OR, ISD::AND});
  if (!Match && ExtractVT == MVT::i1)
    Match = DAG.matchBinOpReduction(Extract, BinOp, {ISD::XOR});
  if (!Match)
    return SDValue();

  // EXTRACT_VECTOR_ELT can require implicit extension of the vector element
  // which we can't support here for now.
  if (Match.getScalarValueSizeInBits() != BitWidth)
    return SDValue();

  SDValue Movmsk;
  SDLoc DL(Extract);
  EVT MatchVT = Match.getValueType();
  unsigned NumElts = MatchVT.getVectorNumElements();
  unsigned MaxElts = Subtarget.hasInt256() ? 32 : 16;
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();

  if (ExtractVT == MVT::i1) {
    // Special case for (pre-legalization) vXi1 reductions.
    if (NumElts > 64 || !isPowerOf2_32(NumElts))
      return SDValue();
    if (TLI.isTypeLegal(MatchVT)) {
      // If this is a legal AVX512 predicate type then we can just bitcast.
      EVT MovmskVT = EVT::getIntegerVT(*DAG.getContext(), NumElts);
      Movmsk = DAG.getBitcast(MovmskVT, Match);
    } else {
      // Use combineBitcastvxi1 to create the MOVMSK.
      while (NumElts > MaxElts) {
        SDValue Lo, Hi;
        std::tie(Lo, Hi) = DAG.SplitVector(Match, DL);
        Match = DAG.getNode(BinOp, DL, Lo.getValueType(), Lo, Hi);
        NumElts /= 2;
      }
      EVT MovmskVT = EVT::getIntegerVT(*DAG.getContext(), NumElts);
      Movmsk = combineBitcastvxi1(DAG, MovmskVT, Match, DL, Subtarget);
    }
    if (!Movmsk)
      return SDValue();
    Movmsk = DAG.getZExtOrTrunc(Movmsk, DL, NumElts > 32 ? MVT::i64 : MVT::i32);
  } else {
    // FIXME: Better handling of k-registers or 512-bit vectors?
    unsigned MatchSizeInBits = Match.getValueSizeInBits();
    if (!(MatchSizeInBits == 128 ||
          (MatchSizeInBits == 256 && Subtarget.hasAVX())))
      return SDValue();

    // Make sure this isn't a vector of 1 element. The perf win from using
    // MOVMSK diminishes with less elements in the reduction, but it is
    // generally better to get the comparison over to the GPRs as soon as
    // possible to reduce the number of vector ops.
    if (Match.getValueType().getVectorNumElements() < 2)
      return SDValue();

    // Check that we are extracting a reduction of all sign bits.
    if (DAG.ComputeNumSignBits(Match) != BitWidth)
      return SDValue();

    if (MatchSizeInBits == 256 && BitWidth < 32 && !Subtarget.hasInt256()) {
      SDValue Lo, Hi;
      std::tie(Lo, Hi) = DAG.SplitVector(Match, DL);
      Match = DAG.getNode(BinOp, DL, Lo.getValueType(), Lo, Hi);
      MatchSizeInBits = Match.getValueSizeInBits();
    }

    // For 32/64 bit comparisons use MOVMSKPS/MOVMSKPD, else PMOVMSKB.
    MVT MaskSrcVT;
    if (64 == BitWidth || 32 == BitWidth)
      MaskSrcVT = MVT::getVectorVT(MVT::getFloatingPointVT(BitWidth),
                                   MatchSizeInBits / BitWidth);
    else
      MaskSrcVT = MVT::getVectorVT(MVT::i8, MatchSizeInBits / 8);

    SDValue BitcastLogicOp = DAG.getBitcast(MaskSrcVT, Match);
    Movmsk = getPMOVMSKB(DL, BitcastLogicOp, DAG, Subtarget);
    NumElts = MaskSrcVT.getVectorNumElements();
  }
  assert((NumElts <= 32 || NumElts == 64) &&
         "Not expecting more than 64 elements");

  MVT CmpVT = NumElts == 64 ? MVT::i64 : MVT::i32;
  if (BinOp == ISD::XOR) {
    // parity -> (AND (CTPOP(MOVMSK X)), 1)
    SDValue Mask = DAG.getConstant(1, DL, CmpVT);
    SDValue Result = DAG.getNode(ISD::CTPOP, DL, CmpVT, Movmsk);
    Result = DAG.getNode(ISD::AND, DL, CmpVT, Result, Mask);
    return DAG.getZExtOrTrunc(Result, DL, ExtractVT);
  }

  SDValue CmpC;
  ISD::CondCode CondCode;
  if (BinOp == ISD::OR) {
    // any_of -> MOVMSK != 0
    CmpC = DAG.getConstant(0, DL, CmpVT);
    CondCode = ISD::CondCode::SETNE;
  } else {
    // all_of -> MOVMSK == ((1 << NumElts) - 1)
    CmpC = DAG.getConstant(APInt::getLowBitsSet(CmpVT.getSizeInBits(), NumElts),
                           DL, CmpVT);
    CondCode = ISD::CondCode::SETEQ;
  }

  // The setcc produces an i8 of 0/1, so extend that to the result width and
  // negate to get the final 0/-1 mask value.
  EVT SetccVT =
      TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), CmpVT);
  SDValue Setcc = DAG.getSetCC(DL, SetccVT, Movmsk, CmpC, CondCode);
  SDValue Zext = DAG.getZExtOrTrunc(Setcc, DL, ExtractVT);
  SDValue Zero = DAG.getConstant(0, DL, ExtractVT);
  return DAG.getNode(ISD::SUB, DL, ExtractVT, Zero, Zext);
}

static SDValue combineBasicSADPattern(SDNode *Extract, SelectionDAG &DAG,
                                      const X86Subtarget &Subtarget) {
  // PSADBW is only supported on SSE2 and up.
  if (!Subtarget.hasSSE2())
    return SDValue();

  EVT ExtractVT = Extract->getValueType(0);
  // Verify the type we're extracting is either i32 or i64.
  // FIXME: Could support other types, but this is what we have coverage for.
  if (ExtractVT != MVT::i32 && ExtractVT != MVT::i64)
    return SDValue();

  EVT VT = Extract->getOperand(0).getValueType();
  if (!isPowerOf2_32(VT.getVectorNumElements()))
    return SDValue();

  // Match shuffle + add pyramid.
  ISD::NodeType BinOp;
  SDValue Root = DAG.matchBinOpReduction(Extract, BinOp, {ISD::ADD});

  // The operand is expected to be zero extended from i8
  // (verified in detectZextAbsDiff).
  // In order to convert to i64 and above, additional any/zero/sign
  // extend is expected.
  // The zero extend from 32 bit has no mathematical effect on the result.
  // Also the sign extend is basically zero extend
  // (extends the sign bit which is zero).
  // So it is correct to skip the sign/zero extend instruction.
  if (Root && (Root.getOpcode() == ISD::SIGN_EXTEND ||
               Root.getOpcode() == ISD::ZERO_EXTEND ||
               Root.getOpcode() == ISD::ANY_EXTEND))
    Root = Root.getOperand(0);

  // If there was a match, we want Root to be a select that is the root of an
  // abs-diff pattern.
  if (!Root || Root.getOpcode() != ISD::ABS)
    return SDValue();

  // Check whether we have an abs-diff pattern feeding into the select.
  SDValue Zext0, Zext1;
  if (!detectZextAbsDiff(Root, Zext0, Zext1))
    return SDValue();

  // Create the SAD instruction.
  SDLoc DL(Extract);
  SDValue SAD = createPSADBW(DAG, Zext0, Zext1, DL, Subtarget);

  // If the original vector was wider than 8 elements, sum over the results
  // in the SAD vector.
  unsigned Stages = Log2_32(VT.getVectorNumElements());
  EVT SadVT = SAD.getValueType();
  if (Stages > 3) {
    unsigned SadElems = SadVT.getVectorNumElements();

    for(unsigned i = Stages - 3; i > 0; --i) {
      SmallVector<int, 16> Mask(SadElems, -1);
      for(unsigned j = 0, MaskEnd = 1 << (i - 1); j < MaskEnd; ++j)
        Mask[j] = MaskEnd + j;

      SDValue Shuffle =
          DAG.getVectorShuffle(SadVT, DL, SAD, DAG.getUNDEF(SadVT), Mask);
      SAD = DAG.getNode(ISD::ADD, DL, SadVT, SAD, Shuffle);
    }
  }

  unsigned ExtractSizeInBits = ExtractVT.getSizeInBits();
  // Return the lowest ExtractSizeInBits bits.
  EVT ResVT = EVT::getVectorVT(*DAG.getContext(), ExtractVT,
                               SadVT.getSizeInBits() / ExtractSizeInBits);
  SAD = DAG.getBitcast(ResVT, SAD);
  return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ExtractVT, SAD,
                     Extract->getOperand(1));
}

// Attempt to peek through a target shuffle and extract the scalar from the
// source.
static SDValue combineExtractWithShuffle(SDNode *N, SelectionDAG &DAG,
                                         TargetLowering::DAGCombinerInfo &DCI,
                                         const X86Subtarget &Subtarget) {
  if (DCI.isBeforeLegalizeOps())
    return SDValue();

  SDLoc dl(N);
  SDValue Src = N->getOperand(0);
  SDValue Idx = N->getOperand(1);

  EVT VT = N->getValueType(0);
  EVT SrcVT = Src.getValueType();
  EVT SrcSVT = SrcVT.getVectorElementType();
  unsigned SrcEltBits = SrcSVT.getSizeInBits();
  unsigned NumSrcElts = SrcVT.getVectorNumElements();

  // Don't attempt this for boolean mask vectors or unknown extraction indices.
  if (SrcSVT == MVT::i1 || !isa<ConstantSDNode>(Idx))
    return SDValue();

  const APInt &IdxC = N->getConstantOperandAPInt(1);
  if (IdxC.uge(NumSrcElts))
    return SDValue();

  SDValue SrcBC = peekThroughBitcasts(Src);

  // Handle extract(bitcast(broadcast(scalar_value))).
  if (X86ISD::VBROADCAST == SrcBC.getOpcode()) {
    SDValue SrcOp = SrcBC.getOperand(0);
    if (SrcOp.getValueSizeInBits() == VT.getSizeInBits())
      return DAG.getBitcast(VT, SrcOp);

    EVT SrcOpVT = SrcOp.getValueType();
    if (SrcOpVT.isScalarInteger() && VT.isInteger() &&
        (SrcOpVT.getSizeInBits() % SrcEltBits) == 0) {
      unsigned Scale = SrcOpVT.getSizeInBits() / SrcEltBits;
      unsigned Offset = IdxC.urem(Scale) * SrcEltBits;
      // TODO support non-zero offsets.
      if (Offset == 0) {
        SrcOp = DAG.getZExtOrTrunc(SrcOp, dl, SrcVT.getScalarType());
        SrcOp = DAG.getZExtOrTrunc(SrcOp, dl, VT);
        return SrcOp;
      }
    }
  }

  // If we're extracting a single element from a broadcast load and there are
  // no other users, just create a single load.
  if (SrcBC.getOpcode() == X86ISD::VBROADCAST_LOAD && SrcBC.hasOneUse()) {
    auto *MemIntr = cast<MemIntrinsicSDNode>(SrcBC);
    unsigned SrcBCWidth = SrcBC.getScalarValueSizeInBits();
    if (MemIntr->getMemoryVT().getSizeInBits() == SrcBCWidth &&
        VT.getSizeInBits() == SrcBCWidth) {
      SDValue Load = DAG.getLoad(VT, dl, MemIntr->getChain(),
                                 MemIntr->getBasePtr(),
                                 MemIntr->getPointerInfo(),
                                 MemIntr->getAlignment(),
                                 MemIntr->getMemOperand()->getFlags());
      DAG.ReplaceAllUsesOfValueWith(SDValue(MemIntr, 1), Load.getValue(1));
      return Load;
    }
  }

  // Handle extract(bitcast(scalar_to_vector(scalar_value))) for integers.
  // TODO: Move to DAGCombine?
  if (SrcBC.getOpcode() == ISD::SCALAR_TO_VECTOR && VT.isInteger() &&
      SrcBC.getValueType().isInteger() &&
      (SrcBC.getScalarValueSizeInBits() % SrcEltBits) == 0 &&
      SrcBC.getScalarValueSizeInBits() ==
          SrcBC.getOperand(0).getValueSizeInBits()) {
    unsigned Scale = SrcBC.getScalarValueSizeInBits() / SrcEltBits;
    if (IdxC.ult(Scale)) {
      unsigned Offset = IdxC.getZExtValue() * SrcVT.getScalarSizeInBits();
      SDValue Scl = SrcBC.getOperand(0);
      EVT SclVT = Scl.getValueType();
      if (Offset) {
        Scl = DAG.getNode(ISD::SRL, dl, SclVT, Scl,
                          DAG.getShiftAmountConstant(Offset, SclVT, dl));
      }
      Scl = DAG.getZExtOrTrunc(Scl, dl, SrcVT.getScalarType());
      Scl = DAG.getZExtOrTrunc(Scl, dl, VT);
      return Scl;
    }
  }

  // Handle extract(truncate(x)) for 0'th index.
  // TODO: Treat this as a faux shuffle?
  // TODO: When can we use this for general indices?
  if (ISD::TRUNCATE == Src.getOpcode() && SrcVT.is128BitVector() && IdxC == 0) {
    Src = extract128BitVector(Src.getOperand(0), 0, DAG, dl);
    Src = DAG.getBitcast(SrcVT, Src);
    return DAG.getNode(N->getOpcode(), dl, VT, Src, Idx);
  }

  // Resolve the target shuffle inputs and mask.
  SmallVector<int, 16> Mask;
  SmallVector<SDValue, 2> Ops;
  if (!getTargetShuffleInputs(SrcBC, Ops, Mask, DAG))
    return SDValue();

  // Shuffle inputs must be the same size as the result.
  if (llvm::any_of(Ops, [SrcVT](SDValue Op) {
        return SrcVT.getSizeInBits() != Op.getValueSizeInBits();
      }))
    return SDValue();

  // Attempt to narrow/widen the shuffle mask to the correct size.
  if (Mask.size() != NumSrcElts) {
    if ((NumSrcElts % Mask.size()) == 0) {
      SmallVector<int, 16> ScaledMask;
      int Scale = NumSrcElts / Mask.size();
      scaleShuffleMask(Scale, Mask, ScaledMask);
      Mask = std::move(ScaledMask);
    } else if ((Mask.size() % NumSrcElts) == 0) {
      // Simplify Mask based on demanded element.
      int ExtractIdx = (int)N->getConstantOperandVal(1);
      int Scale = Mask.size() / NumSrcElts;
      int Lo = Scale * ExtractIdx;
      int Hi = Scale * (ExtractIdx + 1);
      for (int i = 0, e = (int)Mask.size(); i != e; ++i)
        if (i < Lo || Hi <= i)
          Mask[i] = SM_SentinelUndef;

      SmallVector<int, 16> WidenedMask;
      while (Mask.size() > NumSrcElts &&
             canWidenShuffleElements(Mask, WidenedMask))
        Mask = std::move(WidenedMask);
      // TODO - investigate support for wider shuffle masks with known upper
      // undef/zero elements for implicit zero-extension.
    }
  }

  // Check if narrowing/widening failed.
  if (Mask.size() != NumSrcElts)
    return SDValue();

  int SrcIdx = Mask[IdxC.getZExtValue()];

  // If the shuffle source element is undef/zero then we can just accept it.
  if (SrcIdx == SM_SentinelUndef)
    return DAG.getUNDEF(VT);

  if (SrcIdx == SM_SentinelZero)
    return VT.isFloatingPoint() ? DAG.getConstantFP(0.0, dl, VT)
                                : DAG.getConstant(0, dl, VT);

  SDValue SrcOp = Ops[SrcIdx / Mask.size()];
  SrcIdx = SrcIdx % Mask.size();

  // We can only extract other elements from 128-bit vectors and in certain
  // circumstances, depending on SSE-level.
  // TODO: Investigate using extract_subvector for larger vectors.
  // TODO: Investigate float/double extraction if it will be just stored.
  if ((SrcVT == MVT::v4i32 || SrcVT == MVT::v2i64) &&
      ((SrcIdx == 0 && Subtarget.hasSSE2()) || Subtarget.hasSSE41())) {
    assert(SrcSVT == VT && "Unexpected extraction type");
    SrcOp = DAG.getBitcast(SrcVT, SrcOp);
    return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, SrcSVT, SrcOp,
                       DAG.getIntPtrConstant(SrcIdx, dl));
  }

  if ((SrcVT == MVT::v8i16 && Subtarget.hasSSE2()) ||
      (SrcVT == MVT::v16i8 && Subtarget.hasSSE41())) {
    assert(VT.getSizeInBits() >= SrcEltBits && "Unexpected extraction type");
    unsigned OpCode = (SrcVT == MVT::v8i16 ? X86ISD::PEXTRW : X86ISD::PEXTRB);
    SrcOp = DAG.getBitcast(SrcVT, SrcOp);
    SDValue ExtOp = DAG.getNode(OpCode, dl, MVT::i32, SrcOp,
                                DAG.getIntPtrConstant(SrcIdx, dl));
    return DAG.getZExtOrTrunc(ExtOp, dl, VT);
  }

  return SDValue();
}

/// Extracting a scalar FP value from vector element 0 is free, so extract each
/// operand first, then perform the math as a scalar op.
static SDValue scalarizeExtEltFP(SDNode *ExtElt, SelectionDAG &DAG) {
  assert(ExtElt->getOpcode() == ISD::EXTRACT_VECTOR_ELT && "Expected extract");
  SDValue Vec = ExtElt->getOperand(0);
  SDValue Index = ExtElt->getOperand(1);
  EVT VT = ExtElt->getValueType(0);
  EVT VecVT = Vec.getValueType();

  // TODO: If this is a unary/expensive/expand op, allow extraction from a
  // non-zero element because the shuffle+scalar op will be cheaper?
  if (!Vec.hasOneUse() || !isNullConstant(Index) || VecVT.getScalarType() != VT)
    return SDValue();

  // Vector FP compares don't fit the pattern of FP math ops (propagate, not
  // extract, the condition code), so deal with those as a special-case.
  if (Vec.getOpcode() == ISD::SETCC && VT == MVT::i1) {
    EVT OpVT = Vec.getOperand(0).getValueType().getScalarType();
    if (OpVT != MVT::f32 && OpVT != MVT::f64)
      return SDValue();

    // extract (setcc X, Y, CC), 0 --> setcc (extract X, 0), (extract Y, 0), CC
    SDLoc DL(ExtElt);
    SDValue Ext0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, OpVT,
                               Vec.getOperand(0), Index);
    SDValue Ext1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, OpVT,
                               Vec.getOperand(1), Index);
    return DAG.getNode(Vec.getOpcode(), DL, VT, Ext0, Ext1, Vec.getOperand(2));
  }

  if (VT != MVT::f32 && VT != MVT::f64)
    return SDValue();

  // Vector FP selects don't fit the pattern of FP math ops (because the
  // condition has a different type and we have to change the opcode), so deal
  // with those here.
  // FIXME: This is restricted to pre type legalization by ensuring the setcc
  // has i1 elements. If we loosen this we need to convert vector bool to a
  // scalar bool.
  if (Vec.getOpcode() == ISD::VSELECT &&
      Vec.getOperand(0).getOpcode() == ISD::SETCC &&
      Vec.getOperand(0).getValueType().getScalarType() == MVT::i1 &&
      Vec.getOperand(0).getOperand(0).getValueType() == VecVT) {
    // ext (sel Cond, X, Y), 0 --> sel (ext Cond, 0), (ext X, 0), (ext Y, 0)
    SDLoc DL(ExtElt);
    SDValue Ext0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL,
                               Vec.getOperand(0).getValueType().getScalarType(),
                               Vec.getOperand(0), Index);
    SDValue Ext1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT,
                               Vec.getOperand(1), Index);
    SDValue Ext2 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT,
                               Vec.getOperand(2), Index);
    return DAG.getNode(ISD::SELECT, DL, VT, Ext0, Ext1, Ext2);
  }

  // TODO: This switch could include FNEG and the x86-specific FP logic ops
  // (FAND, FANDN, FOR, FXOR). But that may require enhancements to avoid
  // missed load folding and fma+fneg combining.
  switch (Vec.getOpcode()) {
  case ISD::FMA: // Begin 3 operands
  case ISD::FMAD:
  case ISD::FADD: // Begin 2 operands
  case ISD::FSUB:
  case ISD::FMUL:
  case ISD::FDIV:
  case ISD::FREM:
  case ISD::FCOPYSIGN:
  case ISD::FMINNUM:
  case ISD::FMAXNUM:
  case ISD::FMINNUM_IEEE:
  case ISD::FMAXNUM_IEEE:
  case ISD::FMAXIMUM:
  case ISD::FMINIMUM:
  case X86ISD::FMAX:
  case X86ISD::FMIN:
  case ISD::FABS: // Begin 1 operand
  case ISD::FSQRT:
  case ISD::FRINT:
  case ISD::FCEIL:
  case ISD::FTRUNC:
  case ISD::FNEARBYINT:
  case ISD::FROUND:
  case ISD::FFLOOR:
  case X86ISD::FRCP:
  case X86ISD::FRSQRT: {
    // extract (fp X, Y, ...), 0 --> fp (extract X, 0), (extract Y, 0), ...
    SDLoc DL(ExtElt);
    SmallVector<SDValue, 4> ExtOps;
    for (SDValue Op : Vec->ops())
      ExtOps.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, Op, Index));
    return DAG.getNode(Vec.getOpcode(), DL, VT, ExtOps);
  }
  default:
    return SDValue();
  }
  llvm_unreachable("All opcodes should return within switch");
}

/// Try to convert a vector reduction sequence composed of binops and shuffles
/// into horizontal ops.
static SDValue combineReductionToHorizontal(SDNode *ExtElt, SelectionDAG &DAG,
                                            const X86Subtarget &Subtarget) {
  assert(ExtElt->getOpcode() == ISD::EXTRACT_VECTOR_ELT && "Unexpected caller");

  // We need at least SSE2 to anything here.
  if (!Subtarget.hasSSE2())
    return SDValue();

  ISD::NodeType Opc;
  SDValue Rdx =
      DAG.matchBinOpReduction(ExtElt, Opc, {ISD::ADD, ISD::FADD}, true);
  if (!Rdx)
    return SDValue();

  SDValue Index = ExtElt->getOperand(1);
  assert(isNullConstant(Index) &&
         "Reduction doesn't end in an extract from index 0");

  EVT VT = ExtElt->getValueType(0);
  EVT VecVT = Rdx.getValueType();
  if (VecVT.getScalarType() != VT)
    return SDValue();

  SDLoc DL(ExtElt);

  // vXi8 reduction - sub 128-bit vector.
  if (VecVT == MVT::v4i8 || VecVT == MVT::v8i8) {
    if (VecVT == MVT::v4i8) {
      // Pad with zero.
      if (Subtarget.hasSSE41()) {
        Rdx = DAG.getBitcast(MVT::i32, Rdx);
        Rdx = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, MVT::v4i32,
                          DAG.getConstant(0, DL, MVT::v4i32), Rdx,
                          DAG.getIntPtrConstant(0, DL));
        Rdx = DAG.getBitcast(MVT::v16i8, Rdx);
      } else {
        Rdx = DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v8i8, Rdx,
                          DAG.getConstant(0, DL, VecVT));
      }
    }
    if (Rdx.getValueType() == MVT::v8i8) {
      // Pad with undef.
      Rdx = DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v16i8, Rdx,
                        DAG.getUNDEF(MVT::v8i8));
    }
    Rdx = DAG.getNode(X86ISD::PSADBW, DL, MVT::v2i64, Rdx,
                      DAG.getConstant(0, DL, MVT::v16i8));
    Rdx = DAG.getBitcast(MVT::v16i8, Rdx);
    return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, Rdx, Index);
  }

  // Must be a >=128-bit vector with pow2 elements.
  if ((VecVT.getSizeInBits() % 128) != 0 ||
      !isPowerOf2_32(VecVT.getVectorNumElements()))
    return SDValue();

  // vXi8 reduction - sum lo/hi halves then use PSADBW.
  if (VT == MVT::i8) {
    while (Rdx.getValueSizeInBits() > 128) {
      unsigned HalfSize = VecVT.getSizeInBits() / 2;
      unsigned HalfElts = VecVT.getVectorNumElements() / 2;
      SDValue Lo = extractSubVector(Rdx, 0, DAG, DL, HalfSize);
      SDValue Hi = extractSubVector(Rdx, HalfElts, DAG, DL, HalfSize);
      Rdx = DAG.getNode(ISD::ADD, DL, Lo.getValueType(), Lo, Hi);
      VecVT = Rdx.getValueType();
    }
    assert(VecVT == MVT::v16i8 && "v16i8 reduction expected");

    SDValue Hi = DAG.getVectorShuffle(
        MVT::v16i8, DL, Rdx, Rdx,
        {8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1});
    Rdx = DAG.getNode(ISD::ADD, DL, MVT::v16i8, Rdx, Hi);
    Rdx = DAG.getNode(X86ISD::PSADBW, DL, MVT::v2i64, Rdx,
                      getZeroVector(MVT::v16i8, Subtarget, DAG, DL));
    Rdx = DAG.getBitcast(MVT::v16i8, Rdx);
    return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, Rdx, Index);
  }

  // Only use (F)HADD opcodes if they aren't microcoded or minimizes codesize.
  bool OptForSize = DAG.getMachineFunction().getFunction().hasOptSize();
  if (!Subtarget.hasFastHorizontalOps() && !OptForSize)
    return SDValue();

  unsigned HorizOpcode = Opc == ISD::ADD ? X86ISD::HADD : X86ISD::FHADD;

  // 256-bit horizontal instructions operate on 128-bit chunks rather than
  // across the whole vector, so we need an extract + hop preliminary stage.
  // This is the only step where the operands of the hop are not the same value.
  // TODO: We could extend this to handle 512-bit or even longer vectors.
  if (((VecVT == MVT::v16i16 || VecVT == MVT::v8i32) && Subtarget.hasSSSE3()) ||
      ((VecVT == MVT::v8f32 || VecVT == MVT::v4f64) && Subtarget.hasSSE3())) {
    unsigned NumElts = VecVT.getVectorNumElements();
    SDValue Hi = extract128BitVector(Rdx, NumElts / 2, DAG, DL);
    SDValue Lo = extract128BitVector(Rdx, 0, DAG, DL);
    Rdx = DAG.getNode(HorizOpcode, DL, Lo.getValueType(), Hi, Lo);
    VecVT = Rdx.getValueType();
  }
  if (!((VecVT == MVT::v8i16 || VecVT == MVT::v4i32) && Subtarget.hasSSSE3()) &&
      !((VecVT == MVT::v4f32 || VecVT == MVT::v2f64) && Subtarget.hasSSE3()))
    return SDValue();

  // extract (add (shuf X), X), 0 --> extract (hadd X, X), 0
  unsigned ReductionSteps = Log2_32(VecVT.getVectorNumElements());
  for (unsigned i = 0; i != ReductionSteps; ++i)
    Rdx = DAG.getNode(HorizOpcode, DL, VecVT, Rdx, Rdx);

  return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, Rdx, Index);
}

/// Detect vector gather/scatter index generation and convert it from being a
/// bunch of shuffles and extracts into a somewhat faster sequence.
/// For i686, the best sequence is apparently storing the value and loading
/// scalars back, while for x64 we should use 64-bit extracts and shifts.
static SDValue combineExtractVectorElt(SDNode *N, SelectionDAG &DAG,
                                       TargetLowering::DAGCombinerInfo &DCI,
                                       const X86Subtarget &Subtarget) {
  if (SDValue NewOp = combineExtractWithShuffle(N, DAG, DCI, Subtarget))
    return NewOp;

  SDValue InputVector = N->getOperand(0);
  SDValue EltIdx = N->getOperand(1);
  auto *CIdx = dyn_cast<ConstantSDNode>(EltIdx);

  EVT SrcVT = InputVector.getValueType();
  EVT VT = N->getValueType(0);
  SDLoc dl(InputVector);
  bool IsPextr = N->getOpcode() != ISD::EXTRACT_VECTOR_ELT;
  unsigned NumSrcElts = SrcVT.getVectorNumElements();

  if (CIdx && CIdx->getAPIntValue().uge(NumSrcElts))
    return IsPextr ? DAG.getConstant(0, dl, VT) : DAG.getUNDEF(VT);

  // Integer Constant Folding.
  if (CIdx && VT.isInteger()) {
    APInt UndefVecElts;
    SmallVector<APInt, 16> EltBits;
    unsigned VecEltBitWidth = SrcVT.getScalarSizeInBits();
    if (getTargetConstantBitsFromNode(InputVector, VecEltBitWidth, UndefVecElts,
                                      EltBits, true, false)) {
      uint64_t Idx = CIdx->getZExtValue();
      if (UndefVecElts[Idx])
        return IsPextr ? DAG.getConstant(0, dl, VT) : DAG.getUNDEF(VT);
      return DAG.getConstant(EltBits[Idx].zextOrSelf(VT.getScalarSizeInBits()),
                             dl, VT);
    }
  }

  if (IsPextr) {
    const TargetLowering &TLI = DAG.getTargetLoweringInfo();
    if (TLI.SimplifyDemandedBits(
            SDValue(N, 0), APInt::getAllOnesValue(VT.getSizeInBits()), DCI))
      return SDValue(N, 0);

    // PEXTR*(PINSR*(v, s, c), c) -> s (with implicit zext handling).
    if ((InputVector.getOpcode() == X86ISD::PINSRB ||
         InputVector.getOpcode() == X86ISD::PINSRW) &&
        InputVector.getOperand(2) == EltIdx) {
      assert(SrcVT == InputVector.getOperand(0).getValueType() &&
             "Vector type mismatch");
      SDValue Scl = InputVector.getOperand(1);
      Scl = DAG.getNode(ISD::TRUNCATE, dl, SrcVT.getScalarType(), Scl);
      return DAG.getZExtOrTrunc(Scl, dl, VT);
    }

    // TODO - Remove this once we can handle the implicit zero-extension of
    // X86ISD::PEXTRW/X86ISD::PEXTRB in combineHorizontalPredicateResult and
    // combineBasicSADPattern.
    return SDValue();
  }

  // Detect mmx extraction of all bits as a i64. It works better as a bitcast.
  if (InputVector.getOpcode() == ISD::BITCAST && InputVector.hasOneUse() &&
      VT == MVT::i64 && SrcVT == MVT::v1i64 && isNullConstant(EltIdx)) {
    SDValue MMXSrc = InputVector.getOperand(0);

    // The bitcast source is a direct mmx result.
    if (MMXSrc.getValueType() == MVT::x86mmx)
      return DAG.getBitcast(VT, InputVector);
  }

  // Detect mmx to i32 conversion through a v2i32 elt extract.
  if (InputVector.getOpcode() == ISD::BITCAST && InputVector.hasOneUse() &&
      VT == MVT::i32 && SrcVT == MVT::v2i32 && isNullConstant(EltIdx)) {
    SDValue MMXSrc = InputVector.getOperand(0);

    // The bitcast source is a direct mmx result.
    if (MMXSrc.getValueType() == MVT::x86mmx)
      return DAG.getNode(X86ISD::MMX_MOVD2W, dl, MVT::i32, MMXSrc);
  }

  // Check whether this extract is the root of a sum of absolute differences
  // pattern. This has to be done here because we really want it to happen
  // pre-legalization,
  if (SDValue SAD = combineBasicSADPattern(N, DAG, Subtarget))
    return SAD;

  // Attempt to replace an all_of/any_of horizontal reduction with a MOVMSK.
  if (SDValue Cmp = combineHorizontalPredicateResult(N, DAG, Subtarget))
    return Cmp;

  // Attempt to replace min/max v8i16/v16i8 reductions with PHMINPOSUW.
  if (SDValue MinMax = combineHorizontalMinMaxResult(N, DAG, Subtarget))
    return MinMax;

  if (SDValue V = combineReductionToHorizontal(N, DAG, Subtarget))
    return V;

  if (SDValue V = scalarizeExtEltFP(N, DAG))
    return V;

  // Attempt to extract a i1 element by using MOVMSK to extract the signbits
  // and then testing the relevant element.
  if (CIdx && SrcVT.getScalarType() == MVT::i1) {
    SmallVector<SDNode *, 16> BoolExtracts;
    auto IsBoolExtract = [&BoolExtracts](SDNode *Use) {
      if (Use->getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
          isa<ConstantSDNode>(Use->getOperand(1)) &&
          Use->getValueType(0) == MVT::i1) {
        BoolExtracts.push_back(Use);
        return true;
      }
      return false;
    };
    if (all_of(InputVector->uses(), IsBoolExtract) &&
        BoolExtracts.size() > 1) {
      EVT BCVT = EVT::getIntegerVT(*DAG.getContext(), NumSrcElts);
      if (SDValue BC =
              combineBitcastvxi1(DAG, BCVT, InputVector, dl, Subtarget)) {
        for (SDNode *Use : BoolExtracts) {
          // extractelement vXi1 X, MaskIdx --> ((movmsk X) & Mask) == Mask
          unsigned MaskIdx = Use->getConstantOperandVal(1);
          APInt MaskBit = APInt::getOneBitSet(NumSrcElts, MaskIdx);
          SDValue Mask = DAG.getConstant(MaskBit, dl, BCVT);
          SDValue Res = DAG.getNode(ISD::AND, dl, BCVT, BC, Mask);
          Res = DAG.getSetCC(dl, MVT::i1, Res, Mask, ISD::SETEQ);
          DCI.CombineTo(Use, Res);
        }
        return SDValue(N, 0);
      }
    }
  }

  return SDValue();
}

/// If a vector select has an operand that is -1 or 0, try to simplify the
/// select to a bitwise logic operation.
/// TODO: Move to DAGCombiner, possibly using TargetLowering::hasAndNot()?
static SDValue
combineVSelectWithAllOnesOrZeros(SDNode *N, SelectionDAG &DAG,
                                 TargetLowering::DAGCombinerInfo &DCI,
                                 const X86Subtarget &Subtarget) {
  SDValue Cond = N->getOperand(0);
  SDValue LHS = N->getOperand(1);
  SDValue RHS = N->getOperand(2);
  EVT VT = LHS.getValueType();
  EVT CondVT = Cond.getValueType();
  SDLoc DL(N);
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();

  if (N->getOpcode() != ISD::VSELECT)
    return SDValue();

  assert(CondVT.isVector() && "Vector select expects a vector selector!");

  // TODO: Use isNullOrNullSplat() to distinguish constants with undefs?
  // TODO: Can we assert that both operands are not zeros (because that should
  //       get simplified at node creation time)?
  bool TValIsAllZeros = ISD::isBuildVectorAllZeros(LHS.getNode());
  bool FValIsAllZeros = ISD::isBuildVectorAllZeros(RHS.getNode());

  // If both inputs are 0/undef, create a complete zero vector.
  // FIXME: As noted above this should be handled by DAGCombiner/getNode.
  if (TValIsAllZeros && FValIsAllZeros) {
    if (VT.isFloatingPoint())
      return DAG.getConstantFP(0.0, DL, VT);
    return DAG.getConstant(0, DL, VT);
  }

  // To use the condition operand as a bitwise mask, it must have elements that
  // are the same size as the select elements. Ie, the condition operand must
  // have already been promoted from the IR select condition type <N x i1>.
  // Don't check if the types themselves are equal because that excludes
  // vector floating-point selects.
  if (CondVT.getScalarSizeInBits() != VT.getScalarSizeInBits())
    return SDValue();

  // Try to invert the condition if true value is not all 1s and false value is
  // not all 0s. Only do this if the condition has one use.
  bool TValIsAllOnes = ISD::isBuildVectorAllOnes(LHS.getNode());
  if (!TValIsAllOnes && !FValIsAllZeros && Cond.hasOneUse() &&
      // Check if the selector will be produced by CMPP*/PCMP*.
      Cond.getOpcode() == ISD::SETCC &&
      // Check if SETCC has already been promoted.
      TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT) ==
          CondVT) {
    bool FValIsAllOnes = ISD::isBuildVectorAllOnes(RHS.getNode());

    if (TValIsAllZeros || FValIsAllOnes) {
      SDValue CC = Cond.getOperand(2);
      ISD::CondCode NewCC = ISD::getSetCCInverse(
          cast<CondCodeSDNode>(CC)->get(), Cond.getOperand(0).getValueType());
      Cond = DAG.getSetCC(DL, CondVT, Cond.getOperand(0), Cond.getOperand(1),
                          NewCC);
      std::swap(LHS, RHS);
      TValIsAllOnes = FValIsAllOnes;
      FValIsAllZeros = TValIsAllZeros;
    }
  }

  // Cond value must be 'sign splat' to be converted to a logical op.
  if (DAG.ComputeNumSignBits(Cond) != CondVT.getScalarSizeInBits())
    return SDValue();

  // vselect Cond, 111..., 000... -> Cond
  if (TValIsAllOnes && FValIsAllZeros)
    return DAG.getBitcast(VT, Cond);

  if (!DCI.isBeforeLegalize() && !TLI.isTypeLegal(CondVT))
    return SDValue();

  // vselect Cond, 111..., X -> or Cond, X
  if (TValIsAllOnes) {
    SDValue CastRHS = DAG.getBitcast(CondVT, RHS);
    SDValue Or = DAG.getNode(ISD::OR, DL, CondVT, Cond, CastRHS);
    return DAG.getBitcast(VT, Or);
  }

  // vselect Cond, X, 000... -> and Cond, X
  if (FValIsAllZeros) {
    SDValue CastLHS = DAG.getBitcast(CondVT, LHS);
    SDValue And = DAG.getNode(ISD::AND, DL, CondVT, Cond, CastLHS);
    return DAG.getBitcast(VT, And);
  }

  // vselect Cond, 000..., X -> andn Cond, X
  if (TValIsAllZeros) {
    MVT AndNVT = MVT::getVectorVT(MVT::i64, CondVT.getSizeInBits() / 64);
    SDValue CastCond = DAG.getBitcast(AndNVT, Cond);
    SDValue CastRHS = DAG.getBitcast(AndNVT, RHS);
    SDValue AndN = DAG.getNode(X86ISD::ANDNP, DL, AndNVT, CastCond, CastRHS);
    return DAG.getBitcast(VT, AndN);
  }

  return SDValue();
}

/// If both arms of a vector select are concatenated vectors, split the select,
/// and concatenate the result to eliminate a wide (256-bit) vector instruction:
///   vselect Cond, (concat T0, T1), (concat F0, F1) -->
///   concat (vselect (split Cond), T0, F0), (vselect (split Cond), T1, F1)
static SDValue narrowVectorSelect(SDNode *N, SelectionDAG &DAG,
                                  const X86Subtarget &Subtarget) {
  unsigned Opcode = N->getOpcode();
  if (Opcode != X86ISD::BLENDV && Opcode != ISD::VSELECT)
    return SDValue();

  // TODO: Split 512-bit vectors too?
  EVT VT = N->getValueType(0);
  if (!VT.is256BitVector())
    return SDValue();

  // TODO: Split as long as any 2 of the 3 operands are concatenated?
  SDValue Cond = N->getOperand(0);
  SDValue TVal = N->getOperand(1);
  SDValue FVal = N->getOperand(2);
  SmallVector<SDValue, 4> CatOpsT, CatOpsF;
  if (!TVal.hasOneUse() || !FVal.hasOneUse() ||
      !collectConcatOps(TVal.getNode(), CatOpsT) ||
      !collectConcatOps(FVal.getNode(), CatOpsF))
    return SDValue();

  auto makeBlend = [Opcode](SelectionDAG &DAG, const SDLoc &DL,
                            ArrayRef<SDValue> Ops) {
    return DAG.getNode(Opcode, DL, Ops[1].getValueType(), Ops);
  };
  return SplitOpsAndApply(DAG, Subtarget, SDLoc(N), VT, { Cond, TVal, FVal },
                          makeBlend, /*CheckBWI*/ false);
}

static SDValue combineSelectOfTwoConstants(SDNode *N, SelectionDAG &DAG) {
  SDValue Cond = N->getOperand(0);
  SDValue LHS = N->getOperand(1);
  SDValue RHS = N->getOperand(2);
  SDLoc DL(N);

  auto *TrueC = dyn_cast<ConstantSDNode>(LHS);
  auto *FalseC = dyn_cast<ConstantSDNode>(RHS);
  if (!TrueC || !FalseC)
    return SDValue();

  // Don't do this for crazy integer types.
  EVT VT = N->getValueType(0);
  if (!DAG.getTargetLoweringInfo().isTypeLegal(VT))
    return SDValue();

  // We're going to use the condition bit in math or logic ops. We could allow
  // this with a wider condition value (post-legalization it becomes an i8),
  // but if nothing is creating selects that late, it doesn't matter.
  if (Cond.getValueType() != MVT::i1)
    return SDValue();

  // A power-of-2 multiply is just a shift. LEA also cheaply handles multiply by
  // 3, 5, or 9 with i32/i64, so those get transformed too.
  // TODO: For constants that overflow or do not differ by power-of-2 or small
  // multiplier, convert to 'and' + 'add'.
  const APInt &TrueVal = TrueC->getAPIntValue();
  const APInt &FalseVal = FalseC->getAPIntValue();
  bool OV;
  APInt Diff = TrueVal.ssub_ov(FalseVal, OV);
  if (OV)
    return SDValue();

  APInt AbsDiff = Diff.abs();
  if (AbsDiff.isPowerOf2() ||
      ((VT == MVT::i32 || VT == MVT::i64) &&
       (AbsDiff == 3 || AbsDiff == 5 || AbsDiff == 9))) {

    // We need a positive multiplier constant for shift/LEA codegen. The 'not'
    // of the condition can usually be folded into a compare predicate, but even
    // without that, the sequence should be cheaper than a CMOV alternative.
    if (TrueVal.slt(FalseVal)) {
      Cond = DAG.getNOT(DL, Cond, MVT::i1);
      std::swap(TrueC, FalseC);
    }

    // select Cond, TC, FC --> (zext(Cond) * (TC - FC)) + FC
    SDValue R = DAG.getNode(ISD::ZERO_EXTEND, DL, VT, Cond);

    // Multiply condition by the difference if non-one.
    if (!AbsDiff.isOneValue())
      R = DAG.getNode(ISD::MUL, DL, VT, R, DAG.getConstant(AbsDiff, DL, VT));

    // Add the base if non-zero.
    if (!FalseC->isNullValue())
      R = DAG.getNode(ISD::ADD, DL, VT, R, SDValue(FalseC, 0));

    return R;
  }

  return SDValue();
}

/// If this is a *dynamic* select (non-constant condition) and we can match
/// this node with one of the variable blend instructions, restructure the
/// condition so that blends can use the high (sign) bit of each element.
/// This function will also call SimplifyDemandedBits on already created
/// BLENDV to perform additional simplifications.
static SDValue combineVSelectToBLENDV(SDNode *N, SelectionDAG &DAG,
                                           TargetLowering::DAGCombinerInfo &DCI,
                                           const X86Subtarget &Subtarget) {
  SDValue Cond = N->getOperand(0);
  if ((N->getOpcode() != ISD::VSELECT &&
       N->getOpcode() != X86ISD::BLENDV) ||
      ISD::isBuildVectorOfConstantSDNodes(Cond.getNode()))
    return SDValue();

  // Don't optimize before the condition has been transformed to a legal type
  // and don't ever optimize vector selects that map to AVX512 mask-registers.
  unsigned BitWidth = Cond.getScalarValueSizeInBits();
  if (BitWidth < 8 || BitWidth > 64)
    return SDValue();

  // We can only handle the cases where VSELECT is directly legal on the
  // subtarget. We custom lower VSELECT nodes with constant conditions and
  // this makes it hard to see whether a dynamic VSELECT will correctly
  // lower, so we both check the operation's status and explicitly handle the
  // cases where a *dynamic* blend will fail even though a constant-condition
  // blend could be custom lowered.
  // FIXME: We should find a better way to handle this class of problems.
  // Potentially, we should combine constant-condition vselect nodes
  // pre-legalization into shuffles and not mark as many types as custom
  // lowered.
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  EVT VT = N->getValueType(0);
  if (!TLI.isOperationLegalOrCustom(ISD::VSELECT, VT))
    return SDValue();
  // FIXME: We don't support i16-element blends currently. We could and
  // should support them by making *all* the bits in the condition be set
  // rather than just the high bit and using an i8-element blend.
  if (VT.getVectorElementType() == MVT::i16)
    return SDValue();
  // Dynamic blending was only available from SSE4.1 onward.
  if (VT.is128BitVector() && !Subtarget.hasSSE41())
    return SDValue();
  // Byte blends are only available in AVX2
  if (VT == MVT::v32i8 && !Subtarget.hasAVX2())
    return SDValue();
  // There are no 512-bit blend instructions that use sign bits.
  if (VT.is512BitVector())
    return SDValue();

  auto OnlyUsedAsSelectCond = [](SDValue Cond) {
    for (SDNode::use_iterator UI = Cond->use_begin(), UE = Cond->use_end();
         UI != UE; ++UI)
      if ((UI->getOpcode() != ISD::VSELECT &&
           UI->getOpcode() != X86ISD::BLENDV) ||
          UI.getOperandNo() != 0)
        return false;

    return true;
  };

  if (OnlyUsedAsSelectCond(Cond)) {
    APInt DemandedMask(APInt::getSignMask(BitWidth));
    KnownBits Known;
    TargetLowering::TargetLoweringOpt TLO(DAG, !DCI.isBeforeLegalize(),
                                          !DCI.isBeforeLegalizeOps());
    if (!TLI.SimplifyDemandedBits(Cond, DemandedMask, Known, TLO, 0, true))
      return SDValue();

    // If we changed the computation somewhere in the DAG, this change will
    // affect all users of Cond. Update all the nodes so that we do not use
    // the generic VSELECT anymore. Otherwise, we may perform wrong
    // optimizations as we messed with the actual expectation for the vector
    // boolean values.
    for (SDNode *U : Cond->uses()) {
      if (U->getOpcode() == X86ISD::BLENDV)
        continue;

      SDValue SB = DAG.getNode(X86ISD::BLENDV, SDLoc(U), U->getValueType(0),
                               Cond, U->getOperand(1), U->getOperand(2));
      DAG.ReplaceAllUsesOfValueWith(SDValue(U, 0), SB);
      DCI.AddToWorklist(U);
    }
    DCI.CommitTargetLoweringOpt(TLO);
    return SDValue(N, 0);
  }

  // Otherwise we can still at least try to simplify multiple use bits.
  APInt DemandedBits(APInt::getSignMask(BitWidth));
  if (SDValue V = TLI.SimplifyMultipleUseDemandedBits(Cond, DemandedBits, DAG))
    return DAG.getNode(X86ISD::BLENDV, SDLoc(N), N->getValueType(0), V,
                       N->getOperand(1), N->getOperand(2));

  return SDValue();
}

// Try to match:
//   (or (and (M, (sub 0, X)), (pandn M, X)))
// which is a special case of:
//   (select M, (sub 0, X), X)
// Per:
// http://graphics.stanford.edu/~seander/bithacks.html#ConditionalNegate
// We know that, if fNegate is 0 or 1:
//   (fNegate ? -v : v) == ((v ^ -fNegate) + fNegate)
//
// Here, we have a mask, M (all 1s or 0), and, similarly, we know that:
//   ((M & 1) ? -X : X) == ((X ^ -(M & 1)) + (M & 1))
//   ( M      ? -X : X) == ((X ^   M     ) + (M & 1))
// This lets us transform our vselect to:
//   (add (xor X, M), (and M, 1))
// And further to:
//   (sub (xor X, M), M)
static SDValue combineLogicBlendIntoConditionalNegate(
    EVT VT, SDValue Mask, SDValue X, SDValue Y, const SDLoc &DL,
    SelectionDAG &DAG, const X86Subtarget &Subtarget) {
  EVT MaskVT = Mask.getValueType();
  assert(MaskVT.isInteger() &&
         DAG.ComputeNumSignBits(Mask) == MaskVT.getScalarSizeInBits() &&
         "Mask must be zero/all-bits");

  if (X.getValueType() != MaskVT || Y.getValueType() != MaskVT)
    return SDValue();
  if (!DAG.getTargetLoweringInfo().isOperationLegal(ISD::SUB, MaskVT))
    return SDValue();

  auto IsNegV = [](SDNode *N, SDValue V) {
    return N->getOpcode() == ISD::SUB && N->getOperand(1) == V &&
           ISD::isBuildVectorAllZeros(N->getOperand(0).getNode());
  };

  SDValue V;
  if (IsNegV(Y.getNode(), X))
    V = X;
  else if (IsNegV(X.getNode(), Y))
    V = Y;
  else
    return SDValue();

  SDValue SubOp1 = DAG.getNode(ISD::XOR, DL, MaskVT, V, Mask);
  SDValue SubOp2 = Mask;

  // If the negate was on the false side of the select, then
  // the operands of the SUB need to be swapped. PR 27251.
  // This is because the pattern being matched above is
  // (vselect M, (sub (0, X), X)  -> (sub (xor X, M), M)
  // but if the pattern matched was
  // (vselect M, X, (sub (0, X))), that is really negation of the pattern
  // above, -(vselect M, (sub 0, X), X), and therefore the replacement
  // pattern also needs to be a negation of the replacement pattern above.
  // And -(sub X, Y) is just sub (Y, X), so swapping the operands of the
  // sub accomplishes the negation of the replacement pattern.
  if (V == Y)
    std::swap(SubOp1, SubOp2);

  SDValue Res = DAG.getNode(ISD::SUB, DL, MaskVT, SubOp1, SubOp2);
  return DAG.getBitcast(VT, Res);
}

/// Do target-specific dag combines on SELECT and VSELECT nodes.
static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
                             TargetLowering::DAGCombinerInfo &DCI,
                             const X86Subtarget &Subtarget) {
  SDLoc DL(N);
  SDValue Cond = N->getOperand(0);
  SDValue LHS = N->getOperand(1);
  SDValue RHS = N->getOperand(2);

  // Try simplification again because we use this function to optimize
  // BLENDV nodes that are not handled by the generic combiner.
  if (SDValue V = DAG.simplifySelect(Cond, LHS, RHS))
    return V;

  EVT VT = LHS.getValueType();
  EVT CondVT = Cond.getValueType();
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  bool CondConstantVector = ISD::isBuildVectorOfConstantSDNodes(Cond.getNode());

  // Attempt to combine (select M, (sub 0, X), X) -> (sub (xor X, M), M).
  // Limit this to cases of non-constant masks that createShuffleMaskFromVSELECT
  // can't catch, plus vXi8 cases where we'd likely end up with BLENDV.
  if (CondVT.isVector() && CondVT.isInteger() &&
      CondVT.getScalarSizeInBits() == VT.getScalarSizeInBits() &&
      (!CondConstantVector || CondVT.getScalarType() == MVT::i8) &&
      DAG.ComputeNumSignBits(Cond) == CondVT.getScalarSizeInBits())
    if (SDValue V = combineLogicBlendIntoConditionalNegate(VT, Cond, RHS, LHS,
                                                           DL, DAG, Subtarget))
      return V;

  // Convert vselects with constant condition into shuffles.
  if (CondConstantVector && DCI.isBeforeLegalizeOps()) {
    SmallVector<int, 64> Mask;
    if (createShuffleMaskFromVSELECT(Mask, Cond))
      return DAG.getVectorShuffle(VT, DL, LHS, RHS, Mask);
  }

  // If we have SSE[12] support, try to form min/max nodes. SSE min/max
  // instructions match the semantics of the common C idiom x<y?x:y but not
  // x<=y?x:y, because of how they handle negative zero (which can be
  // ignored in unsafe-math mode).
  // We also try to create v2f32 min/max nodes, which we later widen to v4f32.
  if (Cond.getOpcode() == ISD::SETCC && VT.isFloatingPoint() &&
      VT != MVT::f80 && VT != MVT::f128 &&
      (TLI.isTypeLegal(VT) || VT == MVT::v2f32) &&
      (Subtarget.hasSSE2() ||
       (Subtarget.hasSSE1() && VT.getScalarType() == MVT::f32))) {
    ISD::CondCode CC = cast<CondCodeSDNode>(Cond.getOperand(2))->get();

    unsigned Opcode = 0;
    // Check for x CC y ? x : y.
    if (DAG.isEqualTo(LHS, Cond.getOperand(0)) &&
        DAG.isEqualTo(RHS, Cond.getOperand(1))) {
      switch (CC) {
      default: break;
      case ISD::SETULT:
        // Converting this to a min would handle NaNs incorrectly, and swapping
        // the operands would cause it to handle comparisons between positive
        // and negative zero incorrectly.
        if (!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS)) {
          if (!DAG.getTarget().Options.NoSignedZerosFPMath &&
              !(DAG.isKnownNeverZeroFloat(LHS) ||
                DAG.isKnownNeverZeroFloat(RHS)))
            break;
          std::swap(LHS, RHS);
        }
        Opcode = X86ISD::FMIN;
        break;
      case ISD::SETOLE:
        // Converting this to a min would handle comparisons between positive
        // and negative zero incorrectly.
        if (!DAG.getTarget().Options.NoSignedZerosFPMath &&
            !DAG.isKnownNeverZeroFloat(LHS) && !DAG.isKnownNeverZeroFloat(RHS))
          break;
        Opcode = X86ISD::FMIN;
        break;
      case ISD::SETULE:
        // Converting this to a min would handle both negative zeros and NaNs
        // incorrectly, but we can swap the operands to fix both.
        std::swap(LHS, RHS);
        LLVM_FALLTHROUGH;
      case ISD::SETOLT:
      case ISD::SETLT:
      case ISD::SETLE:
        Opcode = X86ISD::FMIN;
        break;

      case ISD::SETOGE:
        // Converting this to a max would handle comparisons between positive
        // and negative zero incorrectly.
        if (!DAG.getTarget().Options.NoSignedZerosFPMath &&
            !DAG.isKnownNeverZeroFloat(LHS) && !DAG.isKnownNeverZeroFloat(RHS))
          break;
        Opcode = X86ISD::FMAX;
        break;
      case ISD::SETUGT:
        // Converting this to a max would handle NaNs incorrectly, and swapping
        // the operands would cause it to handle comparisons between positive
        // and negative zero incorrectly.
        if (!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS)) {
          if (!DAG.getTarget().Options.NoSignedZerosFPMath &&
              !(DAG.isKnownNeverZeroFloat(LHS) ||
                DAG.isKnownNeverZeroFloat(RHS)))
            break;
          std::swap(LHS, RHS);
        }
        Opcode = X86ISD::FMAX;
        break;
      case ISD::SETUGE:
        // Converting this to a max would handle both negative zeros and NaNs
        // incorrectly, but we can swap the operands to fix both.
        std::swap(LHS, RHS);
        LLVM_FALLTHROUGH;
      case ISD::SETOGT:
      case ISD::SETGT:
      case ISD::SETGE:
        Opcode = X86ISD::FMAX;
        break;
      }
    // Check for x CC y ? y : x -- a min/max with reversed arms.
    } else if (DAG.isEqualTo(LHS, Cond.getOperand(1)) &&
               DAG.isEqualTo(RHS, Cond.getOperand(0))) {
      switch (CC) {
      default: break;
      case ISD::SETOGE:
        // Converting this to a min would handle comparisons between positive
        // and negative zero incorrectly, and swapping the operands would
        // cause it to handle NaNs incorrectly.
        if (!DAG.getTarget().Options.NoSignedZerosFPMath &&
            !(DAG.isKnownNeverZeroFloat(LHS) ||
              DAG.isKnownNeverZeroFloat(RHS))) {
          if (!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS))
            break;
          std::swap(LHS, RHS);
        }
        Opcode = X86ISD::FMIN;
        break;
      case ISD::SETUGT:
        // Converting this to a min would handle NaNs incorrectly.
        if (!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS))
          break;
        Opcode = X86ISD::FMIN;
        break;
      case ISD::SETUGE:
        // Converting this to a min would handle both negative zeros and NaNs
        // incorrectly, but we can swap the operands to fix both.
        std::swap(LHS, RHS);
        LLVM_FALLTHROUGH;
      case ISD::SETOGT:
      case ISD::SETGT:
      case ISD::SETGE:
        Opcode = X86ISD::FMIN;
        break;

      case ISD::SETULT:
        // Converting this to a max would handle NaNs incorrectly.
        if (!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS))
          break;
        Opcode = X86ISD::FMAX;
        break;
      case ISD::SETOLE:
        // Converting this to a max would handle comparisons between positive
        // and negative zero incorrectly, and swapping the operands would
        // cause it to handle NaNs incorrectly.
        if (!DAG.getTarget().Options.NoSignedZerosFPMath &&
            !DAG.isKnownNeverZeroFloat(LHS) &&
            !DAG.isKnownNeverZeroFloat(RHS)) {
          if (!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS))
            break;
          std::swap(LHS, RHS);
        }
        Opcode = X86ISD::FMAX;
        break;
      case ISD::SETULE:
        // Converting this to a max would handle both negative zeros and NaNs
        // incorrectly, but we can swap the operands to fix both.
        std::swap(LHS, RHS);
        LLVM_FALLTHROUGH;
      case ISD::SETOLT:
      case ISD::SETLT:
      case ISD::SETLE:
        Opcode = X86ISD::FMAX;
        break;
      }
    }

    if (Opcode)
      return DAG.getNode(Opcode, DL, N->getValueType(0), LHS, RHS);
  }

  // Some mask scalar intrinsics rely on checking if only one bit is set
  // and implement it in C code like this:
  // A[0] = (U & 1) ? A[0] : W[0];
  // This creates some redundant instructions that break pattern matching.
  // fold (select (setcc (and (X, 1), 0, seteq), Y, Z)) -> select(and(X, 1),Z,Y)
  if (Subtarget.hasAVX512() && N->getOpcode() == ISD::SELECT &&
      Cond.getOpcode() == ISD::SETCC && (VT == MVT::f32 || VT == MVT::f64)) {
    ISD::CondCode CC = cast<CondCodeSDNode>(Cond.getOperand(2))->get();
    SDValue AndNode = Cond.getOperand(0);
    if (AndNode.getOpcode() == ISD::AND && CC == ISD::SETEQ &&
        isNullConstant(Cond.getOperand(1)) &&
        isOneConstant(AndNode.getOperand(1))) {
      // LHS and RHS swapped due to
      // setcc outputting 1 when AND resulted in 0 and vice versa.
      AndNode = DAG.getZExtOrTrunc(AndNode, DL, MVT::i8);
      return DAG.getNode(ISD::SELECT, DL, VT, AndNode, RHS, LHS);
    }
  }

  // v16i8 (select v16i1, v16i8, v16i8) does not have a proper
  // lowering on KNL. In this case we convert it to
  // v16i8 (select v16i8, v16i8, v16i8) and use AVX instruction.
  // The same situation all vectors of i8 and i16 without BWI.
  // Make sure we extend these even before type legalization gets a chance to
  // split wide vectors.
  // Since SKX these selects have a proper lowering.
  if (Subtarget.hasAVX512() && !Subtarget.hasBWI() && CondVT.isVector() &&
      CondVT.getVectorElementType() == MVT::i1 &&
      (VT.getVectorElementType() == MVT::i8 ||
       VT.getVectorElementType() == MVT::i16)) {
    Cond = DAG.getNode(ISD::SIGN_EXTEND, DL, VT, Cond);
    return DAG.getNode(N->getOpcode(), DL, VT, Cond, LHS, RHS);
  }

  // AVX512 - Extend select with zero to merge with target shuffle.
  // select(mask, extract_subvector(shuffle(x)), zero) -->
  // extract_subvector(select(insert_subvector(mask), shuffle(x), zero))
  // TODO - support non target shuffles as well.
  if (Subtarget.hasAVX512() && CondVT.isVector() &&
      CondVT.getVectorElementType() == MVT::i1) {
    auto SelectableOp = [&TLI](SDValue Op) {
      return Op.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
             isTargetShuffle(Op.getOperand(0).getOpcode()) &&
             isNullConstant(Op.getOperand(1)) &&
             TLI.isTypeLegal(Op.getOperand(0).getValueType()) &&
             Op.hasOneUse() && Op.getOperand(0).hasOneUse();
    };

    bool SelectableLHS = SelectableOp(LHS);
    bool SelectableRHS = SelectableOp(RHS);
    bool ZeroLHS = ISD::isBuildVectorAllZeros(LHS.getNode());
    bool ZeroRHS = ISD::isBuildVectorAllZeros(RHS.getNode());

    if ((SelectableLHS && ZeroRHS) || (SelectableRHS && ZeroLHS)) {
      EVT SrcVT = SelectableLHS ? LHS.getOperand(0).getValueType()
                                : RHS.getOperand(0).getValueType();
      unsigned NumSrcElts = SrcVT.getVectorNumElements();
      EVT SrcCondVT = EVT::getVectorVT(*DAG.getContext(), MVT::i1, NumSrcElts);
      LHS = insertSubVector(DAG.getUNDEF(SrcVT), LHS, 0, DAG, DL,
                            VT.getSizeInBits());
      RHS = insertSubVector(DAG.getUNDEF(SrcVT), RHS, 0, DAG, DL,
                            VT.getSizeInBits());
      Cond = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, SrcCondVT,
                         DAG.getUNDEF(SrcCondVT), Cond,
                         DAG.getIntPtrConstant(0, DL));
      SDValue Res = DAG.getSelect(DL, SrcVT, Cond, LHS, RHS);
      return extractSubVector(Res, 0, DAG, DL, VT.getSizeInBits());
    }
  }

  if (SDValue V = combineSelectOfTwoConstants(N, DAG))
    return V;

  // Canonicalize max and min:
  // (x > y) ? x : y -> (x >= y) ? x : y
  // (x < y) ? x : y -> (x <= y) ? x : y
  // This allows use of COND_S / COND_NS (see TranslateX86CC) which eliminates
  // the need for an extra compare
  // against zero. e.g.
  // (x - y) > 0 : (x - y) ? 0 -> (x - y) >= 0 : (x - y) ? 0
  // subl   %esi, %edi
  // testl  %edi, %edi
  // movl   $0, %eax
  // cmovgl %edi, %eax
  // =>
  // xorl   %eax, %eax
  // subl   %esi, $edi
  // cmovsl %eax, %edi
  if (N->getOpcode() == ISD::SELECT && Cond.getOpcode() == ISD::SETCC &&
      Cond.hasOneUse() &&
      DAG.isEqualTo(LHS, Cond.getOperand(0)) &&
      DAG.isEqualTo(RHS, Cond.getOperand(1))) {
    ISD::CondCode CC = cast<CondCodeSDNode>(Cond.getOperand(2))->get();
    switch (CC) {
    default: break;
    case ISD::SETLT:
    case ISD::SETGT: {
      ISD::CondCode NewCC = (CC == ISD::SETLT) ? ISD::SETLE : ISD::SETGE;
      Cond = DAG.getSetCC(SDLoc(Cond), Cond.getValueType(),
                          Cond.getOperand(0), Cond.getOperand(1), NewCC);
      return DAG.getSelect(DL, VT, Cond, LHS, RHS);
    }
    }
  }

  // Match VSELECTs into subs with unsigned saturation.
  if (N->getOpcode() == ISD::VSELECT && Cond.getOpcode() == ISD::SETCC &&
      // psubus is available in SSE2 for i8 and i16 vectors.
      Subtarget.hasSSE2() && VT.getVectorNumElements() >= 2 &&
      isPowerOf2_32(VT.getVectorNumElements()) &&
      (VT.getVectorElementType() == MVT::i8 ||
       VT.getVectorElementType() == MVT::i16)) {
    ISD::CondCode CC = cast<CondCodeSDNode>(Cond.getOperand(2))->get();

    // Check if one of the arms of the VSELECT is a zero vector. If it's on the
    // left side invert the predicate to simplify logic below.
    SDValue Other;
    if (ISD::isBuildVectorAllZeros(LHS.getNode())) {
      Other = RHS;
      CC = ISD::getSetCCInverse(CC, VT.getVectorElementType());
    } else if (ISD::isBuildVectorAllZeros(RHS.getNode())) {
      Other = LHS;
    }

    if (Other.getNode() && Other->getNumOperands() == 2 &&
        Other->getOperand(0) == Cond.getOperand(0)) {
      SDValue OpLHS = Other->getOperand(0), OpRHS = Other->getOperand(1);
      SDValue CondRHS = Cond->getOperand(1);

      // Look for a general sub with unsigned saturation first.
      // x >= y ? x-y : 0 --> subus x, y
      // x >  y ? x-y : 0 --> subus x, y
      if ((CC == ISD::SETUGE || CC == ISD::SETUGT) &&
          Other->getOpcode() == ISD::SUB && OpRHS == CondRHS)
        return DAG.getNode(ISD::USUBSAT, DL, VT, OpLHS, OpRHS);

      if (auto *OpRHSBV = dyn_cast<BuildVectorSDNode>(OpRHS)) {
        if (isa<BuildVectorSDNode>(CondRHS)) {
          // If the RHS is a constant we have to reverse the const
          // canonicalization.
          // x > C-1 ? x+-C : 0 --> subus x, C
          auto MatchUSUBSAT = [](ConstantSDNode *Op, ConstantSDNode *Cond) {
            return (!Op && !Cond) ||
                   (Op && Cond &&
                    Cond->getAPIntValue() == (-Op->getAPIntValue() - 1));
          };
          if (CC == ISD::SETUGT && Other->getOpcode() == ISD::ADD &&
              ISD::matchBinaryPredicate(OpRHS, CondRHS, MatchUSUBSAT,
                                        /*AllowUndefs*/ true)) {
            OpRHS = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT),
                                OpRHS);
            return DAG.getNode(ISD::USUBSAT, DL, VT, OpLHS, OpRHS);
          }

          // Another special case: If C was a sign bit, the sub has been
          // canonicalized into a xor.
          // FIXME: Would it be better to use computeKnownBits to determine
          //        whether it's safe to decanonicalize the xor?
          // x s< 0 ? x^C : 0 --> subus x, C
          if (auto *OpRHSConst = OpRHSBV->getConstantSplatNode()) {
            if (CC == ISD::SETLT && Other.getOpcode() == ISD::XOR &&
                ISD::isBuildVectorAllZeros(CondRHS.getNode()) &&
                OpRHSConst->getAPIntValue().isSignMask()) {
              // Note that we have to rebuild the RHS constant here to ensure we
              // don't rely on particular values of undef lanes.
              OpRHS = DAG.getConstant(OpRHSConst->getAPIntValue(), DL, VT);
              return DAG.getNode(ISD::USUBSAT, DL, VT, OpLHS, OpRHS);
            }
          }
        }
      }
    }
  }

  // Match VSELECTs into add with unsigned saturation.
  if (N->getOpcode() == ISD::VSELECT && Cond.getOpcode() == ISD::SETCC &&
      // paddus is available in SSE2 for i8 and i16 vectors.
      Subtarget.hasSSE2() && VT.getVectorNumElements() >= 2 &&
      isPowerOf2_32(VT.getVectorNumElements()) &&
      (VT.getVectorElementType() == MVT::i8 ||
       VT.getVectorElementType() == MVT::i16)) {
    ISD::CondCode CC = cast<CondCodeSDNode>(Cond.getOperand(2))->get();

    SDValue CondLHS = Cond->getOperand(0);
    SDValue CondRHS = Cond->getOperand(1);

    // Check if one of the arms of the VSELECT is vector with all bits set.
    // If it's on the left side invert the predicate to simplify logic below.
    SDValue Other;
    if (ISD::isBuildVectorAllOnes(LHS.getNode())) {
      Other = RHS;
      CC = ISD::getSetCCInverse(CC, VT.getVectorElementType());
    } else if (ISD::isBuildVectorAllOnes(RHS.getNode())) {
      Other = LHS;
    }

    if (Other.getNode() && Other.getOpcode() == ISD::ADD) {
      SDValue OpLHS = Other.getOperand(0), OpRHS = Other.getOperand(1);

      // Canonicalize condition operands.
      if (CC == ISD::SETUGE) {
        std::swap(CondLHS, CondRHS);
        CC = ISD::SETULE;
      }

      // We can test against either of the addition operands.
      // x <= x+y ? x+y : ~0 --> addus x, y
      // x+y >= x ? x+y : ~0 --> addus x, y
      if (CC == ISD::SETULE && Other == CondRHS &&
          (OpLHS == CondLHS || OpRHS == CondLHS))
        return DAG.getNode(ISD::UADDSAT, DL, VT, OpLHS, OpRHS);

      if (isa<BuildVectorSDNode>(OpRHS) && isa<BuildVectorSDNode>(CondRHS) &&
          CondLHS == OpLHS) {
        // If the RHS is a constant we have to reverse the const
        // canonicalization.
        // x > ~C ? x+C : ~0 --> addus x, C
        auto MatchUADDSAT = [](ConstantSDNode *Op, ConstantSDNode *Cond) {
          return Cond->getAPIntValue() == ~Op->getAPIntValue();
        };
        if (CC == ISD::SETULE &&
            ISD::matchBinaryPredicate(OpRHS, CondRHS, MatchUADDSAT))
          return DAG.getNode(ISD::UADDSAT, DL, VT, OpLHS, OpRHS);
      }
    }
  }

  // Check if the first operand is all zeros and Cond type is vXi1.
  // If this an avx512 target we can improve the use of zero masking by
  // swapping the operands and inverting the condition.
  if (N->getOpcode() == ISD::VSELECT && Cond.hasOneUse() &&
       Subtarget.hasAVX512() && CondVT.getVectorElementType() == MVT::i1 &&
      ISD::isBuildVectorAllZeros(LHS.getNode()) &&
      !ISD::isBuildVectorAllZeros(RHS.getNode())) {
    // Invert the cond to not(cond) : xor(op,allones)=not(op)
    SDValue CondNew = DAG.getNOT(DL, Cond, CondVT);
    // Vselect cond, op1, op2 = Vselect not(cond), op2, op1
    return DAG.getSelect(DL, VT, CondNew, RHS, LHS);
  }

  // Early exit check
  if (!TLI.isTypeLegal(VT))
    return SDValue();

  if (SDValue V = combineVSelectWithAllOnesOrZeros(N, DAG, DCI, Subtarget))
    return V;

  if (SDValue V = combineVSelectToBLENDV(N, DAG, DCI, Subtarget))
    return V;

  if (SDValue V = narrowVectorSelect(N, DAG, Subtarget))
    return V;

  // select(~Cond, X, Y) -> select(Cond, Y, X)
  if (CondVT.getScalarType() != MVT::i1)
    if (SDValue CondNot = IsNOT(Cond, DAG))
      return DAG.getNode(N->getOpcode(), DL, VT,
                         DAG.getBitcast(CondVT, CondNot), RHS, LHS);

  // Try to optimize vXi1 selects if both operands are either all constants or
  // bitcasts from scalar integer type. In that case we can convert the operands
  // to integer and use an integer select which will be converted to a CMOV.
  // We need to take a little bit of care to avoid creating an i64 type after
  // type legalization.
  if (N->getOpcode() == ISD::SELECT && VT.isVector() &&
      VT.getVectorElementType() == MVT::i1 &&
      (DCI.isBeforeLegalize() || (VT != MVT::v64i1 || Subtarget.is64Bit()))) {
    MVT IntVT = MVT::getIntegerVT(VT.getVectorNumElements());
    bool LHSIsConst = ISD::isBuildVectorOfConstantSDNodes(LHS.getNode());
    bool RHSIsConst = ISD::isBuildVectorOfConstantSDNodes(RHS.getNode());

    if ((LHSIsConst ||
         (LHS.getOpcode() == ISD::BITCAST &&
          LHS.getOperand(0).getValueType() == IntVT)) &&
        (RHSIsConst ||
         (RHS.getOpcode() == ISD::BITCAST &&
          RHS.getOperand(0).getValueType() == IntVT))) {
      if (LHSIsConst)
        LHS = combinevXi1ConstantToInteger(LHS, DAG);
      else
        LHS = LHS.getOperand(0);

      if (RHSIsConst)
        RHS = combinevXi1ConstantToInteger(RHS, DAG);
      else
        RHS = RHS.getOperand(0);

      SDValue Select = DAG.getSelect(DL, IntVT, Cond, LHS, RHS);
      return DAG.getBitcast(VT, Select);
    }
  }

  return SDValue();
}

/// Combine:
///   (brcond/cmov/setcc .., (cmp (atomic_load_add x, 1), 0), COND_S)
/// to:
///   (brcond/cmov/setcc .., (LADD x, 1), COND_LE)
/// i.e., reusing the EFLAGS produced by the LOCKed instruction.
/// Note that this is only legal for some op/cc combinations.
static SDValue combineSetCCAtomicArith(SDValue Cmp, X86::CondCode &CC,
                                       SelectionDAG &DAG,
                                       const X86Subtarget &Subtarget) {
  // This combine only operates on CMP-like nodes.
  if (!(Cmp.getOpcode() == X86ISD::CMP ||
        (Cmp.getOpcode() == X86ISD::SUB && !Cmp->hasAnyUseOfValue(0))))
    return SDValue();

  // Can't replace the cmp if it has more uses than the one we're looking at.
  // FIXME: We would like to be able to handle this, but would need to make sure
  // all uses were updated.
  if (!Cmp.hasOneUse())
    return SDValue();

  // This only applies to variations of the common case:
  //   (icmp slt x, 0) -> (icmp sle (add x, 1), 0)
  //   (icmp sge x, 0) -> (icmp sgt (add x, 1), 0)
  //   (icmp sle x, 0) -> (icmp slt (sub x, 1), 0)
  //   (icmp sgt x, 0) -> (icmp sge (sub x, 1), 0)
  // Using the proper condcodes (see below), overflow is checked for.

  // FIXME: We can generalize both constraints:
  // - XOR/OR/AND (if they were made to survive AtomicExpand)
  // - LHS != 1
  // if the result is compared.

  SDValue CmpLHS = Cmp.getOperand(0);
  SDValue CmpRHS = Cmp.getOperand(1);

  if (!CmpLHS.hasOneUse())
    return SDValue();

  unsigned Opc = CmpLHS.getOpcode();
  if (Opc != ISD::ATOMIC_LOAD_ADD && Opc != ISD::ATOMIC_LOAD_SUB)
    return SDValue();

  SDValue OpRHS = CmpLHS.getOperand(2);
  auto *OpRHSC = dyn_cast<ConstantSDNode>(OpRHS);
  if (!OpRHSC)
    return SDValue();

  APInt Addend = OpRHSC->getAPIntValue();
  if (Opc == ISD::ATOMIC_LOAD_SUB)
    Addend = -Addend;

  auto *CmpRHSC = dyn_cast<ConstantSDNode>(CmpRHS);
  if (!CmpRHSC)
    return SDValue();

  APInt Comparison = CmpRHSC->getAPIntValue();

  // If the addend is the negation of the comparison value, then we can do
  // a full comparison by emitting the atomic arithmetic as a locked sub.
  if (Comparison == -Addend) {
    // The CC is fine, but we need to rewrite the LHS of the comparison as an
    // atomic sub.
    auto *AN = cast<AtomicSDNode>(CmpLHS.getNode());
    auto AtomicSub = DAG.getAtomic(
        ISD::ATOMIC_LOAD_SUB, SDLoc(CmpLHS), CmpLHS.getValueType(),
        /*Chain*/ CmpLHS.getOperand(0), /*LHS*/ CmpLHS.getOperand(1),
        /*RHS*/ DAG.getConstant(-Addend, SDLoc(CmpRHS), CmpRHS.getValueType()),
        AN->getMemOperand());
    auto LockOp = lowerAtomicArithWithLOCK(AtomicSub, DAG, Subtarget);
    DAG.ReplaceAllUsesOfValueWith(CmpLHS.getValue(0),
                                  DAG.getUNDEF(CmpLHS.getValueType()));
    DAG.ReplaceAllUsesOfValueWith(CmpLHS.getValue(1), LockOp.getValue(1));
    return LockOp;
  }

  // We can handle comparisons with zero in a number of cases by manipulating
  // the CC used.
  if (!Comparison.isNullValue())
    return SDValue();

  if (CC == X86::COND_S && Addend == 1)
    CC = X86::COND_LE;
  else if (CC == X86::COND_NS && Addend == 1)
    CC = X86::COND_G;
  else if (CC == X86::COND_G && Addend == -1)
    CC = X86::COND_GE;
  else if (CC == X86::COND_LE && Addend == -1)
    CC = X86::COND_L;
  else
    return SDValue();

  SDValue LockOp = lowerAtomicArithWithLOCK(CmpLHS, DAG, Subtarget);
  DAG.ReplaceAllUsesOfValueWith(CmpLHS.getValue(0),
                                DAG.getUNDEF(CmpLHS.getValueType()));
  DAG.ReplaceAllUsesOfValueWith(CmpLHS.getValue(1), LockOp.getValue(1));
  return LockOp;
}

// Check whether a boolean test is testing a boolean value generated by
// X86ISD::SETCC. If so, return the operand of that SETCC and proper condition
// code.
//
// Simplify the following patterns:
// (Op (CMP (SETCC Cond EFLAGS) 1) EQ) or
// (Op (CMP (SETCC Cond EFLAGS) 0) NEQ)
// to (Op EFLAGS Cond)
//
// (Op (CMP (SETCC Cond EFLAGS) 0) EQ) or
// (Op (CMP (SETCC Cond EFLAGS) 1) NEQ)
// to (Op EFLAGS !Cond)
//
// where Op could be BRCOND or CMOV.
//
static SDValue checkBoolTestSetCCCombine(SDValue Cmp, X86::CondCode &CC) {
  // This combine only operates on CMP-like nodes.
  if (!(Cmp.getOpcode() == X86ISD::CMP ||
        (Cmp.getOpcode() == X86ISD::SUB && !Cmp->hasAnyUseOfValue(0))))
    return SDValue();

  // Quit if not used as a boolean value.
  if (CC != X86::COND_E && CC != X86::COND_NE)
    return SDValue();

  // Check CMP operands. One of them should be 0 or 1 and the other should be
  // an SetCC or extended from it.
  SDValue Op1 = Cmp.getOperand(0);
  SDValue Op2 = Cmp.getOperand(1);

  SDValue SetCC;
  const ConstantSDNode* C = nullptr;
  bool needOppositeCond = (CC == X86::COND_E);
  bool checkAgainstTrue = false; // Is it a comparison against 1?

  if ((C = dyn_cast<ConstantSDNode>(Op1)))
    SetCC = Op2;
  else if ((C = dyn_cast<ConstantSDNode>(Op2)))
    SetCC = Op1;
  else // Quit if all operands are not constants.
    return SDValue();

  if (C->getZExtValue() == 1) {
    needOppositeCond = !needOppositeCond;
    checkAgainstTrue = true;
  } else if (C->getZExtValue() != 0)
    // Quit if the constant is neither 0 or 1.
    return SDValue();

  bool truncatedToBoolWithAnd = false;
  // Skip (zext $x), (trunc $x), or (and $x, 1) node.
  while (SetCC.getOpcode() == ISD::ZERO_EXTEND ||
         SetCC.getOpcode() == ISD::TRUNCATE ||
         SetCC.getOpcode() == ISD::AND) {
    if (SetCC.getOpcode() == ISD::AND) {
      int OpIdx = -1;
      if (isOneConstant(SetCC.getOperand(0)))
        OpIdx = 1;
      if (isOneConstant(SetCC.getOperand(1)))
        OpIdx = 0;
      if (OpIdx < 0)
        break;
      SetCC = SetCC.getOperand(OpIdx);
      truncatedToBoolWithAnd = true;
    } else
      SetCC = SetCC.getOperand(0);
  }

  switch (SetCC.getOpcode()) {
  case X86ISD::SETCC_CARRY:
    // Since SETCC_CARRY gives output based on R = CF ? ~0 : 0, it's unsafe to
    // simplify it if the result of SETCC_CARRY is not canonicalized to 0 or 1,
    // i.e. it's a comparison against true but the result of SETCC_CARRY is not
    // truncated to i1 using 'and'.
    if (checkAgainstTrue && !truncatedToBoolWithAnd)
      break;
    assert(X86::CondCode(SetCC.getConstantOperandVal(0)) == X86::COND_B &&
           "Invalid use of SETCC_CARRY!");
    LLVM_FALLTHROUGH;
  case X86ISD::SETCC:
    // Set the condition code or opposite one if necessary.
    CC = X86::CondCode(SetCC.getConstantOperandVal(0));
    if (needOppositeCond)
      CC = X86::GetOppositeBranchCondition(CC);
    return SetCC.getOperand(1);
  case X86ISD::CMOV: {
    // Check whether false/true value has canonical one, i.e. 0 or 1.
    ConstantSDNode *FVal = dyn_cast<ConstantSDNode>(SetCC.getOperand(0));
    ConstantSDNode *TVal = dyn_cast<ConstantSDNode>(SetCC.getOperand(1));
    // Quit if true value is not a constant.
    if (!TVal)
      return SDValue();
    // Quit if false value is not a constant.
    if (!FVal) {
      SDValue Op = SetCC.getOperand(0);
      // Skip 'zext' or 'trunc' node.
      if (Op.getOpcode() == ISD::ZERO_EXTEND ||
          Op.getOpcode() == ISD::TRUNCATE)
        Op = Op.getOperand(0);
      // A special case for rdrand/rdseed, where 0 is set if false cond is
      // found.
      if ((Op.getOpcode() != X86ISD::RDRAND &&
           Op.getOpcode() != X86ISD::RDSEED) || Op.getResNo() != 0)
        return SDValue();
    }
    // Quit if false value is not the constant 0 or 1.
    bool FValIsFalse = true;
    if (FVal && FVal->getZExtValue() != 0) {
      if (FVal->getZExtValue() != 1)
        return SDValue();
      // If FVal is 1, opposite cond is needed.
      needOppositeCond = !needOppositeCond;
      FValIsFalse = false;
    }
    // Quit if TVal is not the constant opposite of FVal.
    if (FValIsFalse && TVal->getZExtValue() != 1)
      return SDValue();
    if (!FValIsFalse && TVal->getZExtValue() != 0)
      return SDValue();
    CC = X86::CondCode(SetCC.getConstantOperandVal(2));
    if (needOppositeCond)
      CC = X86::GetOppositeBranchCondition(CC);
    return SetCC.getOperand(3);
  }
  }

  return SDValue();
}

/// Check whether Cond is an AND/OR of SETCCs off of the same EFLAGS.
/// Match:
///   (X86or (X86setcc) (X86setcc))
///   (X86cmp (and (X86setcc) (X86setcc)), 0)
static bool checkBoolTestAndOrSetCCCombine(SDValue Cond, X86::CondCode &CC0,
                                           X86::CondCode &CC1, SDValue &Flags,
                                           bool &isAnd) {
  if (Cond->getOpcode() == X86ISD::CMP) {
    if (!isNullConstant(Cond->getOperand(1)))
      return false;

    Cond = Cond->getOperand(0);
  }

  isAnd = false;

  SDValue SetCC0, SetCC1;
  switch (Cond->getOpcode()) {
  default: return false;
  case ISD::AND:
  case X86ISD::AND:
    isAnd = true;
    LLVM_FALLTHROUGH;
  case ISD::OR:
  case X86ISD::OR:
    SetCC0 = Cond->getOperand(0);
    SetCC1 = Cond->getOperand(1);
    break;
  };

  // Make sure we have SETCC nodes, using the same flags value.
  if (SetCC0.getOpcode() != X86ISD::SETCC ||
      SetCC1.getOpcode() != X86ISD::SETCC ||
      SetCC0->getOperand(1) != SetCC1->getOperand(1))
    return false;

  CC0 = (X86::CondCode)SetCC0->getConstantOperandVal(0);
  CC1 = (X86::CondCode)SetCC1->getConstantOperandVal(0);
  Flags = SetCC0->getOperand(1);
  return true;
}

// When legalizing carry, we create carries via add X, -1
// If that comes from an actual carry, via setcc, we use the
// carry directly.
static SDValue combineCarryThroughADD(SDValue EFLAGS, SelectionDAG &DAG) {
  if (EFLAGS.getOpcode() == X86ISD::ADD) {
    if (isAllOnesConstant(EFLAGS.getOperand(1))) {
      SDValue Carry = EFLAGS.getOperand(0);
      while (Carry.getOpcode() == ISD::TRUNCATE ||
             Carry.getOpcode() == ISD::ZERO_EXTEND ||
             Carry.getOpcode() == ISD::SIGN_EXTEND ||
             Carry.getOpcode() == ISD::ANY_EXTEND ||
             (Carry.getOpcode() == ISD::AND &&
              isOneConstant(Carry.getOperand(1))))
        Carry = Carry.getOperand(0);
      if (Carry.getOpcode() == X86ISD::SETCC ||
          Carry.getOpcode() == X86ISD::SETCC_CARRY) {
        // TODO: Merge this code with equivalent in combineAddOrSubToADCOrSBB?
        uint64_t CarryCC = Carry.getConstantOperandVal(0);
        SDValue CarryOp1 = Carry.getOperand(1);
        if (CarryCC == X86::COND_B)
          return CarryOp1;
        if (CarryCC == X86::COND_A) {
          // Try to convert COND_A into COND_B in an attempt to facilitate
          // materializing "setb reg".
          //
          // Do not flip "e > c", where "c" is a constant, because Cmp
          // instruction cannot take an immediate as its first operand.
          //
          if (CarryOp1.getOpcode() == X86ISD::SUB &&
              CarryOp1.getNode()->hasOneUse() &&
              CarryOp1.getValueType().isInteger() &&
              !isa<ConstantSDNode>(CarryOp1.getOperand(1))) {
            SDValue SubCommute =
                DAG.getNode(X86ISD::SUB, SDLoc(CarryOp1), CarryOp1->getVTList(),
                            CarryOp1.getOperand(1), CarryOp1.getOperand(0));
            return SDValue(SubCommute.getNode(), CarryOp1.getResNo());
          }
        }
        // If this is a check of the z flag of an add with 1, switch to the
        // C flag.
        if (CarryCC == X86::COND_E &&
            CarryOp1.getOpcode() == X86ISD::ADD &&
            isOneConstant(CarryOp1.getOperand(1)))
          return CarryOp1;
      }
    }
  }

  return SDValue();
}

/// If we are inverting an PTEST/TESTP operand, attempt to adjust the CC
/// to avoid the inversion.
static SDValue combinePTESTCC(SDValue EFLAGS, X86::CondCode &CC,
                              SelectionDAG &DAG) {
  // TODO: Handle X86ISD::KTEST/X86ISD::KORTEST.
  if (EFLAGS.getOpcode() != X86ISD::PTEST &&
      EFLAGS.getOpcode() != X86ISD::TESTP)
    return SDValue();

  // PTEST/TESTP sets EFLAGS as:
  // TESTZ: ZF = (Op0 & Op1) == 0
  // TESTC: CF = (~Op0 & Op1) == 0
  // TESTNZC: ZF == 0 && CF == 0
  EVT VT = EFLAGS.getValueType();
  SDValue Op0 = EFLAGS.getOperand(0);
  SDValue Op1 = EFLAGS.getOperand(1);
  EVT OpVT = Op0.getValueType();

  // TEST*(~X,Y) == TEST*(X,Y)
  if (SDValue NotOp0 = IsNOT(Op0, DAG)) {
    X86::CondCode InvCC;
    switch (CC) {
    case X86::COND_B:
      // testc -> testz.
      InvCC = X86::COND_E;
      break;
    case X86::COND_AE:
      // !testc -> !testz.
      InvCC = X86::COND_NE;
      break;
    case X86::COND_E:
      // testz -> testc.
      InvCC = X86::COND_B;
      break;
    case X86::COND_NE:
      // !testz -> !testc.
      InvCC = X86::COND_AE;
      break;
    case X86::COND_A:
    case X86::COND_BE:
      // testnzc -> testnzc (no change).
      InvCC = CC;
      break;
    default:
      InvCC = X86::COND_INVALID;
      break;
    }

    if (InvCC != X86::COND_INVALID) {
      CC = InvCC;
      return DAG.getNode(EFLAGS.getOpcode(), SDLoc(EFLAGS), VT,
                         DAG.getBitcast(OpVT, NotOp0), Op1);
    }
  }

  if (CC == X86::COND_E || CC == X86::COND_NE) {
    // TESTZ(X,~Y) == TESTC(Y,X)
    if (SDValue NotOp1 = IsNOT(Op1, DAG)) {
      CC = (CC == X86::COND_E ? X86::COND_B : X86::COND_AE);
      return DAG.getNode(EFLAGS.getOpcode(), SDLoc(EFLAGS), VT,
                         DAG.getBitcast(OpVT, NotOp1), Op0);
    }

    // TESTZ(-1,X) == TESTZ(X,X)
    if (ISD::isBuildVectorAllOnes(Op0.getNode()))
      return DAG.getNode(EFLAGS.getOpcode(), SDLoc(EFLAGS), VT, Op1, Op1);

    // TESTZ(X,-1) == TESTZ(X,X)
    if (ISD::isBuildVectorAllOnes(Op1.getNode()))
      return DAG.getNode(EFLAGS.getOpcode(), SDLoc(EFLAGS), VT, Op0, Op0);
  }

  return SDValue();
}

/// Optimize an EFLAGS definition used according to the condition code \p CC
/// into a simpler EFLAGS value, potentially returning a new \p CC and replacing
/// uses of chain values.
static SDValue combineSetCCEFLAGS(SDValue EFLAGS, X86::CondCode &CC,
                                  SelectionDAG &DAG,
                                  const X86Subtarget &Subtarget) {
  if (CC == X86::COND_B)
    if (SDValue Flags = combineCarryThroughADD(EFLAGS, DAG))
      return Flags;

  if (SDValue R = checkBoolTestSetCCCombine(EFLAGS, CC))
    return R;

  if (SDValue R = combinePTESTCC(EFLAGS, CC, DAG))
    return R;

  return combineSetCCAtomicArith(EFLAGS, CC, DAG, Subtarget);
}

/// Optimize X86ISD::CMOV [LHS, RHS, CONDCODE (e.g. X86::COND_NE), CONDVAL]
static SDValue combineCMov(SDNode *N, SelectionDAG &DAG,
                           TargetLowering::DAGCombinerInfo &DCI,
                           const X86Subtarget &Subtarget) {
  SDLoc DL(N);

  SDValue FalseOp = N->getOperand(0);
  SDValue TrueOp = N->getOperand(1);
  X86::CondCode CC = (X86::CondCode)N->getConstantOperandVal(2);
  SDValue Cond = N->getOperand(3);

  // cmov X, X, ?, ? --> X
  if (TrueOp == FalseOp)
    return TrueOp;

  // Try to simplify the EFLAGS and condition code operands.
  // We can't always do this as FCMOV only supports a subset of X86 cond.
  if (SDValue Flags = combineSetCCEFLAGS(Cond, CC, DAG, Subtarget)) {
    if (!(FalseOp.getValueType() == MVT::f80 ||
          (FalseOp.getValueType() == MVT::f64 && !Subtarget.hasSSE2()) ||
          (FalseOp.getValueType() == MVT::f32 && !Subtarget.hasSSE1())) ||
        !Subtarget.hasCMov() || hasFPCMov(CC)) {
      SDValue Ops[] = {FalseOp, TrueOp, DAG.getTargetConstant(CC, DL, MVT::i8),
                       Flags};
      return DAG.getNode(X86ISD::CMOV, DL, N->getValueType(0), Ops);
    }
  }

  // If this is a select between two integer constants, try to do some
  // optimizations.  Note that the operands are ordered the opposite of SELECT
  // operands.
  if (ConstantSDNode *TrueC = dyn_cast<ConstantSDNode>(TrueOp)) {
    if (ConstantSDNode *FalseC = dyn_cast<ConstantSDNode>(FalseOp)) {
      // Canonicalize the TrueC/FalseC values so that TrueC (the true value) is
      // larger than FalseC (the false value).
      if (TrueC->getAPIntValue().ult(FalseC->getAPIntValue())) {
        CC = X86::GetOppositeBranchCondition(CC);
        std::swap(TrueC, FalseC);
        std::swap(TrueOp, FalseOp);
      }

      // Optimize C ? 8 : 0 -> zext(setcc(C)) << 3.  Likewise for any pow2/0.
      // This is efficient for any integer data type (including i8/i16) and
      // shift amount.
      if (FalseC->getAPIntValue() == 0 && TrueC->getAPIntValue().isPowerOf2()) {
        Cond = getSETCC(CC, Cond, DL, DAG);

        // Zero extend the condition if needed.
        Cond = DAG.getNode(ISD::ZERO_EXTEND, DL, TrueC->getValueType(0), Cond);

        unsigned ShAmt = TrueC->getAPIntValue().logBase2();
        Cond = DAG.getNode(ISD::SHL, DL, Cond.getValueType(), Cond,
                           DAG.getConstant(ShAmt, DL, MVT::i8));
        return Cond;
      }

      // Optimize Cond ? cst+1 : cst -> zext(setcc(C)+cst.  This is efficient
      // for any integer data type, including i8/i16.
      if (FalseC->getAPIntValue()+1 == TrueC->getAPIntValue()) {
        Cond = getSETCC(CC, Cond, DL, DAG);

        // Zero extend the condition if needed.
        Cond = DAG.getNode(ISD::ZERO_EXTEND, DL,
                           FalseC->getValueType(0), Cond);
        Cond = DAG.getNode(ISD::ADD, DL, Cond.getValueType(), Cond,
                           SDValue(FalseC, 0));
        return Cond;
      }

      // Optimize cases that will turn into an LEA instruction.  This requires
      // an i32 or i64 and an efficient multiplier (1, 2, 3, 4, 5, 8, 9).
      if (N->getValueType(0) == MVT::i32 || N->getValueType(0) == MVT::i64) {
        APInt Diff = TrueC->getAPIntValue() - FalseC->getAPIntValue();
        assert(Diff.getBitWidth() == N->getValueType(0).getSizeInBits() &&
               "Implicit constant truncation");

        bool isFastMultiplier = false;
        if (Diff.ult(10)) {
          switch (Diff.getZExtValue()) {
          default: break;
          case 1:  // result = add base, cond
          case 2:  // result = lea base(    , cond*2)
          case 3:  // result = lea base(cond, cond*2)
          case 4:  // result = lea base(    , cond*4)
          case 5:  // result = lea base(cond, cond*4)
          case 8:  // result = lea base(    , cond*8)
          case 9:  // result = lea base(cond, cond*8)
            isFastMultiplier = true;
            break;
          }
        }

        if (isFastMultiplier) {
          Cond = getSETCC(CC, Cond, DL ,DAG);
          // Zero extend the condition if needed.
          Cond = DAG.getNode(ISD::ZERO_EXTEND, DL, FalseC->getValueType(0),
                             Cond);
          // Scale the condition by the difference.
          if (Diff != 1)
            Cond = DAG.getNode(ISD::MUL, DL, Cond.getValueType(), Cond,
                               DAG.getConstant(Diff, DL, Cond.getValueType()));

          // Add the base if non-zero.
          if (FalseC->getAPIntValue() != 0)
            Cond = DAG.getNode(ISD::ADD, DL, Cond.getValueType(), Cond,
                               SDValue(FalseC, 0));
          return Cond;
        }
      }
    }
  }

  // Handle these cases:
  //   (select (x != c), e, c) -> select (x != c), e, x),
  //   (select (x == c), c, e) -> select (x == c), x, e)
  // where the c is an integer constant, and the "select" is the combination
  // of CMOV and CMP.
  //
  // The rationale for this change is that the conditional-move from a constant
  // needs two instructions, however, conditional-move from a register needs
  // only one instruction.
  //
  // CAVEAT: By replacing a constant with a symbolic value, it may obscure
  //  some instruction-combining opportunities. This opt needs to be
  //  postponed as late as possible.
  //
  if (!DCI.isBeforeLegalize() && !DCI.isBeforeLegalizeOps()) {
    // the DCI.xxxx conditions are provided to postpone the optimization as
    // late as possible.

    ConstantSDNode *CmpAgainst = nullptr;
    if ((Cond.getOpcode() == X86ISD::CMP || Cond.getOpcode() == X86ISD::SUB) &&
        (CmpAgainst = dyn_cast<ConstantSDNode>(Cond.getOperand(1))) &&
        !isa<ConstantSDNode>(Cond.getOperand(0))) {

      if (CC == X86::COND_NE &&
          CmpAgainst == dyn_cast<ConstantSDNode>(FalseOp)) {
        CC = X86::GetOppositeBranchCondition(CC);
        std::swap(TrueOp, FalseOp);
      }

      if (CC == X86::COND_E &&
          CmpAgainst == dyn_cast<ConstantSDNode>(TrueOp)) {
        SDValue Ops[] = {FalseOp, Cond.getOperand(0),
                         DAG.getTargetConstant(CC, DL, MVT::i8), Cond};
        return DAG.getNode(X86ISD::CMOV, DL, N->getValueType(0), Ops);
      }
    }
  }

  // Fold and/or of setcc's to double CMOV:
  //   (CMOV F, T, ((cc1 | cc2) != 0)) -> (CMOV (CMOV F, T, cc1), T, cc2)
  //   (CMOV F, T, ((cc1 & cc2) != 0)) -> (CMOV (CMOV T, F, !cc1), F, !cc2)
  //
  // This combine lets us generate:
  //   cmovcc1 (jcc1 if we don't have CMOV)
  //   cmovcc2 (same)
  // instead of:
  //   setcc1
  //   setcc2
  //   and/or
  //   cmovne (jne if we don't have CMOV)
  // When we can't use the CMOV instruction, it might increase branch
  // mispredicts.
  // When we can use CMOV, or when there is no mispredict, this improves
  // throughput and reduces register pressure.
  //
  if (CC == X86::COND_NE) {
    SDValue Flags;
    X86::CondCode CC0, CC1;
    bool isAndSetCC;
    if (checkBoolTestAndOrSetCCCombine(Cond, CC0, CC1, Flags, isAndSetCC)) {
      if (isAndSetCC) {
        std::swap(FalseOp, TrueOp);
        CC0 = X86::GetOppositeBranchCondition(CC0);
        CC1 = X86::GetOppositeBranchCondition(CC1);
      }

      SDValue LOps[] = {FalseOp, TrueOp,
                        DAG.getTargetConstant(CC0, DL, MVT::i8), Flags};
      SDValue LCMOV = DAG.getNode(X86ISD::CMOV, DL, N->getValueType(0), LOps);
      SDValue Ops[] = {LCMOV, TrueOp, DAG.getTargetConstant(CC1, DL, MVT::i8),
                       Flags};
      SDValue CMOV = DAG.getNode(X86ISD::CMOV, DL, N->getValueType(0), Ops);
      return CMOV;
    }
  }

  // Fold (CMOV C1, (ADD (CTTZ X), C2), (X != 0)) ->
  //      (ADD (CMOV C1-C2, (CTTZ X), (X != 0)), C2)
  // Or (CMOV (ADD (CTTZ X), C2), C1, (X == 0)) ->
  //    (ADD (CMOV (CTTZ X), C1-C2, (X == 0)), C2)
  if ((CC == X86::COND_NE || CC == X86::COND_E) &&
      Cond.getOpcode() == X86ISD::CMP && isNullConstant(Cond.getOperand(1))) {
    SDValue Add = TrueOp;
    SDValue Const = FalseOp;
    // Canonicalize the condition code for easier matching and output.
    if (CC == X86::COND_E)
      std::swap(Add, Const);

    // We might have replaced the constant in the cmov with the LHS of the
    // compare. If so change it to the RHS of the compare.
    if (Const == Cond.getOperand(0))
      Const = Cond.getOperand(1);

    // Ok, now make sure that Add is (add (cttz X), C2) and Const is a constant.
    if (isa<ConstantSDNode>(Const) && Add.getOpcode() == ISD::ADD &&
        Add.hasOneUse() && isa<ConstantSDNode>(Add.getOperand(1)) &&
        (Add.getOperand(0).getOpcode() == ISD::CTTZ_ZERO_UNDEF ||
         Add.getOperand(0).getOpcode() == ISD::CTTZ) &&
        Add.getOperand(0).getOperand(0) == Cond.getOperand(0)) {
      EVT VT = N->getValueType(0);
      // This should constant fold.
      SDValue Diff = DAG.getNode(ISD::SUB, DL, VT, Const, Add.getOperand(1));
      SDValue CMov =
          DAG.getNode(X86ISD::CMOV, DL, VT, Diff, Add.getOperand(0),
                      DAG.getTargetConstant(X86::COND_NE, DL, MVT::i8), Cond);
      return DAG.getNode(ISD::ADD, DL, VT, CMov, Add.getOperand(1));
    }
  }

  return SDValue();
}

/// Different mul shrinking modes.
enum class ShrinkMode { MULS8, MULU8, MULS16, MULU16 };

static bool canReduceVMulWidth(SDNode *N, SelectionDAG &DAG, ShrinkMode &Mode) {
  EVT VT = N->getOperand(0).getValueType();
  if (VT.getScalarSizeInBits() != 32)
    return false;

  assert(N->getNumOperands() == 2 && "NumOperands of Mul are 2");
  unsigned SignBits[2] = {1, 1};
  bool IsPositive[2] = {false, false};
  for (unsigned i = 0; i < 2; i++) {
    SDValue Opd = N->getOperand(i);

    SignBits[i] = DAG.ComputeNumSignBits(Opd);
    IsPositive[i] = DAG.SignBitIsZero(Opd);
  }

  bool AllPositive = IsPositive[0] && IsPositive[1];
  unsigned MinSignBits = std::min(SignBits[0], SignBits[1]);
  // When ranges are from -128 ~ 127, use MULS8 mode.
  if (MinSignBits >= 25)
    Mode = ShrinkMode::MULS8;
  // When ranges are from 0 ~ 255, use MULU8 mode.
  else if (AllPositive && MinSignBits >= 24)
    Mode = ShrinkMode::MULU8;
  // When ranges are from -32768 ~ 32767, use MULS16 mode.
  else if (MinSignBits >= 17)
    Mode = ShrinkMode::MULS16;
  // When ranges are from 0 ~ 65535, use MULU16 mode.
  else if (AllPositive && MinSignBits >= 16)
    Mode = ShrinkMode::MULU16;
  else
    return false;
  return true;
}

/// When the operands of vector mul are extended from smaller size values,
/// like i8 and i16, the type of mul may be shrinked to generate more
/// efficient code. Two typical patterns are handled:
/// Pattern1:
///     %2 = sext/zext <N x i8> %1 to <N x i32>
///     %4 = sext/zext <N x i8> %3 to <N x i32>
//   or %4 = build_vector <N x i32> %C1, ..., %CN (%C1..%CN are constants)
///     %5 = mul <N x i32> %2, %4
///
/// Pattern2:
///     %2 = zext/sext <N x i16> %1 to <N x i32>
///     %4 = zext/sext <N x i16> %3 to <N x i32>
///  or %4 = build_vector <N x i32> %C1, ..., %CN (%C1..%CN are constants)
///     %5 = mul <N x i32> %2, %4
///
/// There are four mul shrinking modes:
/// If %2 == sext32(trunc8(%2)), i.e., the scalar value range of %2 is
/// -128 to 128, and the scalar value range of %4 is also -128 to 128,
/// generate pmullw+sext32 for it (MULS8 mode).
/// If %2 == zext32(trunc8(%2)), i.e., the scalar value range of %2 is
/// 0 to 255, and the scalar value range of %4 is also 0 to 255,
/// generate pmullw+zext32 for it (MULU8 mode).
/// If %2 == sext32(trunc16(%2)), i.e., the scalar value range of %2 is
/// -32768 to 32767, and the scalar value range of %4 is also -32768 to 32767,
/// generate pmullw+pmulhw for it (MULS16 mode).
/// If %2 == zext32(trunc16(%2)), i.e., the scalar value range of %2 is
/// 0 to 65535, and the scalar value range of %4 is also 0 to 65535,
/// generate pmullw+pmulhuw for it (MULU16 mode).
static SDValue reduceVMULWidth(SDNode *N, SelectionDAG &DAG,
                               const X86Subtarget &Subtarget) {
  // Check for legality
  // pmullw/pmulhw are not supported by SSE.
  if (!Subtarget.hasSSE2())
    return SDValue();

  // Check for profitability
  // pmulld is supported since SSE41. It is better to use pmulld
  // instead of pmullw+pmulhw, except for subtargets where pmulld is slower than
  // the expansion.
  bool OptForMinSize = DAG.getMachineFunction().getFunction().hasMinSize();
  if (Subtarget.hasSSE41() && (OptForMinSize || !Subtarget.isPMULLDSlow()))
    return SDValue();

  ShrinkMode Mode;
  if (!canReduceVMulWidth(N, DAG, Mode))
    return SDValue();

  SDLoc DL(N);
  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);
  EVT VT = N->getOperand(0).getValueType();
  unsigned NumElts = VT.getVectorNumElements();
  if ((NumElts % 2) != 0)
    return SDValue();

  EVT ReducedVT = EVT::getVectorVT(*DAG.getContext(), MVT::i16, NumElts);

  // Shrink the operands of mul.
  SDValue NewN0 = DAG.getNode(ISD::TRUNCATE, DL, ReducedVT, N0);
  SDValue NewN1 = DAG.getNode(ISD::TRUNCATE, DL, ReducedVT, N1);

  // Generate the lower part of mul: pmullw. For MULU8/MULS8, only the
  // lower part is needed.
  SDValue MulLo = DAG.getNode(ISD::MUL, DL, ReducedVT, NewN0, NewN1);
  if (Mode == ShrinkMode::MULU8 || Mode == ShrinkMode::MULS8)
    return DAG.getNode((Mode == ShrinkMode::MULU8) ? ISD::ZERO_EXTEND
                                                   : ISD::SIGN_EXTEND,
                       DL, VT, MulLo);

  EVT ResVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32, NumElts / 2);
  // Generate the higher part of mul: pmulhw/pmulhuw. For MULU16/MULS16,
  // the higher part is also needed.
  SDValue MulHi =
      DAG.getNode(Mode == ShrinkMode::MULS16 ? ISD::MULHS : ISD::MULHU, DL,
                  ReducedVT, NewN0, NewN1);

  // Repack the lower part and higher part result of mul into a wider
  // result.
  // Generate shuffle functioning as punpcklwd.
  SmallVector<int, 16> ShuffleMask(NumElts);
  for (unsigned i = 0, e = NumElts / 2; i < e; i++) {
    ShuffleMask[2 * i] = i;
    ShuffleMask[2 * i + 1] = i + NumElts;
  }
  SDValue ResLo =
      DAG.getVectorShuffle(ReducedVT, DL, MulLo, MulHi, ShuffleMask);
  ResLo = DAG.getBitcast(ResVT, ResLo);
  // Generate shuffle functioning as punpckhwd.
  for (unsigned i = 0, e = NumElts / 2; i < e; i++) {
    ShuffleMask[2 * i] = i + NumElts / 2;
    ShuffleMask[2 * i + 1] = i + NumElts * 3 / 2;
  }
  SDValue ResHi =
      DAG.getVectorShuffle(ReducedVT, DL, MulLo, MulHi, ShuffleMask);
  ResHi = DAG.getBitcast(ResVT, ResHi);
  return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, ResLo, ResHi);
}

static SDValue combineMulSpecial(uint64_t MulAmt, SDNode *N, SelectionDAG &DAG,
                                 EVT VT, const SDLoc &DL) {

  auto combineMulShlAddOrSub = [&](int Mult, int Shift, bool isAdd) {
    SDValue Result = DAG.getNode(X86ISD::MUL_IMM, DL, VT, N->getOperand(0),
                                 DAG.getConstant(Mult, DL, VT));
    Result = DAG.getNode(ISD::SHL, DL, VT, Result,
                         DAG.getConstant(Shift, DL, MVT::i8));
    Result = DAG.getNode(isAdd ? ISD::ADD : ISD::SUB, DL, VT, Result,
                         N->getOperand(0));
    return Result;
  };

  auto combineMulMulAddOrSub = [&](int Mul1, int Mul2, bool isAdd) {
    SDValue Result = DAG.getNode(X86ISD::MUL_IMM, DL, VT, N->getOperand(0),
                                 DAG.getConstant(Mul1, DL, VT));
    Result = DAG.getNode(X86ISD::MUL_IMM, DL, VT, Result,
                         DAG.getConstant(Mul2, DL, VT));
    Result = DAG.getNode(isAdd ? ISD::ADD : ISD::SUB, DL, VT, Result,
                         N->getOperand(0));
    return Result;
  };

  switch (MulAmt) {
  default:
    break;
  case 11:
    // mul x, 11 => add ((shl (mul x, 5), 1), x)
    return combineMulShlAddOrSub(5, 1, /*isAdd*/ true);
  case 21:
    // mul x, 21 => add ((shl (mul x, 5), 2), x)
    return combineMulShlAddOrSub(5, 2, /*isAdd*/ true);
  case 41:
    // mul x, 41 => add ((shl (mul x, 5), 3), x)
    return combineMulShlAddOrSub(5, 3, /*isAdd*/ true);
  case 22:
    // mul x, 22 => add (add ((shl (mul x, 5), 2), x), x)
    return DAG.getNode(ISD::ADD, DL, VT, N->getOperand(0),
                       combineMulShlAddOrSub(5, 2, /*isAdd*/ true));
  case 19:
    // mul x, 19 => add ((shl (mul x, 9), 1), x)
    return combineMulShlAddOrSub(9, 1, /*isAdd*/ true);
  case 37:
    // mul x, 37 => add ((shl (mul x, 9), 2), x)
    return combineMulShlAddOrSub(9, 2, /*isAdd*/ true);
  case 73:
    // mul x, 73 => add ((shl (mul x, 9), 3), x)
    return combineMulShlAddOrSub(9, 3, /*isAdd*/ true);
  case 13:
    // mul x, 13 => add ((shl (mul x, 3), 2), x)
    return combineMulShlAddOrSub(3, 2, /*isAdd*/ true);
  case 23:
    // mul x, 23 => sub ((shl (mul x, 3), 3), x)
    return combineMulShlAddOrSub(3, 3, /*isAdd*/ false);
  case 26:
    // mul x, 26 => add ((mul (mul x, 5), 5), x)
    return combineMulMulAddOrSub(5, 5, /*isAdd*/ true);
  case 28:
    // mul x, 28 => add ((mul (mul x, 9), 3), x)
    return combineMulMulAddOrSub(9, 3, /*isAdd*/ true);
  case 29:
    // mul x, 29 => add (add ((mul (mul x, 9), 3), x), x)
    return DAG.getNode(ISD::ADD, DL, VT, N->getOperand(0),
                       combineMulMulAddOrSub(9, 3, /*isAdd*/ true));
  }

  // Another trick. If this is a power 2 + 2/4/8, we can use a shift followed
  // by a single LEA.
  // First check if this a sum of two power of 2s because that's easy. Then
  // count how many zeros are up to the first bit.
  // TODO: We can do this even without LEA at a cost of two shifts and an add.
  if (isPowerOf2_64(MulAmt & (MulAmt - 1))) {
    unsigned ScaleShift = countTrailingZeros(MulAmt);
    if (ScaleShift >= 1 && ScaleShift < 4) {
      unsigned ShiftAmt = Log2_64((MulAmt & (MulAmt - 1)));
      SDValue Shift1 = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
                                   DAG.getConstant(ShiftAmt, DL, MVT::i8));
      SDValue Shift2 = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
                                   DAG.getConstant(ScaleShift, DL, MVT::i8));
      return DAG.getNode(ISD::ADD, DL, VT, Shift1, Shift2);
    }
  }

  return SDValue();
}

// If the upper 17 bits of each element are zero then we can use PMADDWD,
// which is always at least as quick as PMULLD, except on KNL.
static SDValue combineMulToPMADDWD(SDNode *N, SelectionDAG &DAG,
                                   const X86Subtarget &Subtarget) {
  if (!Subtarget.hasSSE2())
    return SDValue();

  if (Subtarget.isPMADDWDSlow())
    return SDValue();

  EVT VT = N->getValueType(0);

  // Only support vXi32 vectors.
  if (!VT.isVector() || VT.getVectorElementType() != MVT::i32)
    return SDValue();

  // Make sure the vXi16 type is legal. This covers the AVX512 without BWI case.
  // Also allow v2i32 if it will be widened.
  MVT WVT = MVT::getVectorVT(MVT::i16, 2 * VT.getVectorNumElements());
  if (VT != MVT::v2i32 && !DAG.getTargetLoweringInfo().isTypeLegal(WVT))
    return SDValue();

  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);

  // If we are zero extending two steps without SSE4.1, its better to reduce
  // the vmul width instead.
  if (!Subtarget.hasSSE41() &&
      (N0.getOpcode() == ISD::ZERO_EXTEND &&
       N0.getOperand(0).getScalarValueSizeInBits() <= 8) &&
      (N1.getOpcode() == ISD::ZERO_EXTEND &&
       N1.getOperand(0).getScalarValueSizeInBits() <= 8))
    return SDValue();

  APInt Mask17 = APInt::getHighBitsSet(32, 17);
  if (!DAG.MaskedValueIsZero(N1, Mask17) ||
      !DAG.MaskedValueIsZero(N0, Mask17))
    return SDValue();

  // Use SplitOpsAndApply to handle AVX splitting.
  auto PMADDWDBuilder = [](SelectionDAG &DAG, const SDLoc &DL,
                           ArrayRef<SDValue> Ops) {
    MVT OpVT = MVT::getVectorVT(MVT::i32, Ops[0].getValueSizeInBits() / 32);
    return DAG.getNode(X86ISD::VPMADDWD, DL, OpVT, Ops);
  };
  return SplitOpsAndApply(DAG, Subtarget, SDLoc(N), VT,
                          { DAG.getBitcast(WVT, N0), DAG.getBitcast(WVT, N1) },
                          PMADDWDBuilder);
}

static SDValue combineMulToPMULDQ(SDNode *N, SelectionDAG &DAG,
                                  const X86Subtarget &Subtarget) {
  if (!Subtarget.hasSSE2())
    return SDValue();

  EVT VT = N->getValueType(0);

  // Only support vXi64 vectors.
  if (!VT.isVector() || VT.getVectorElementType() != MVT::i64 ||
      VT.getVectorNumElements() < 2 ||
      !isPowerOf2_32(VT.getVectorNumElements()))
    return SDValue();

  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);

  // MULDQ returns the 64-bit result of the signed multiplication of the lower
  // 32-bits. We can lower with this if the sign bits stretch that far.
  if (Subtarget.hasSSE41() && DAG.ComputeNumSignBits(N0) > 32 &&
      DAG.ComputeNumSignBits(N1) > 32) {
    auto PMULDQBuilder = [](SelectionDAG &DAG, const SDLoc &DL,
                            ArrayRef<SDValue> Ops) {
      return DAG.getNode(X86ISD::PMULDQ, DL, Ops[0].getValueType(), Ops);
    };
    return SplitOpsAndApply(DAG, Subtarget, SDLoc(N), VT, { N0, N1 },
                            PMULDQBuilder, /*CheckBWI*/false);
  }

  // If the upper bits are zero we can use a single pmuludq.
  APInt Mask = APInt::getHighBitsSet(64, 32);
  if (DAG.MaskedValueIsZero(N0, Mask) && DAG.MaskedValueIsZero(N1, Mask)) {
    auto PMULUDQBuilder = [](SelectionDAG &DAG, const SDLoc &DL,
                             ArrayRef<SDValue> Ops) {
      return DAG.getNode(X86ISD::PMULUDQ, DL, Ops[0].getValueType(), Ops);
    };
    return SplitOpsAndApply(DAG, Subtarget, SDLoc(N), VT, { N0, N1 },
                            PMULUDQBuilder, /*CheckBWI*/false);
  }

  return SDValue();
}

/// Optimize a single multiply with constant into two operations in order to
/// implement it with two cheaper instructions, e.g. LEA + SHL, LEA + LEA.
static SDValue combineMul(SDNode *N, SelectionDAG &DAG,
                          TargetLowering::DAGCombinerInfo &DCI,
                          const X86Subtarget &Subtarget) {
  EVT VT = N->getValueType(0);

  if (SDValue V = combineMulToPMADDWD(N, DAG, Subtarget))
    return V;

  if (SDValue V = combineMulToPMULDQ(N, DAG, Subtarget))
    return V;

  if (DCI.isBeforeLegalize() && VT.isVector())
    return reduceVMULWidth(N, DAG, Subtarget);

  if (!MulConstantOptimization)
    return SDValue();
  // An imul is usually smaller than the alternative sequence.
  if (DAG.getMachineFunction().getFunction().hasMinSize())
    return SDValue();

  if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
    return SDValue();

  if (VT != MVT::i64 && VT != MVT::i32)
    return SDValue();

  ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1));
  if (!C)
    return SDValue();
  if (isPowerOf2_64(C->getZExtValue()))
    return SDValue();

  int64_t SignMulAmt = C->getSExtValue();
  assert(SignMulAmt != INT64_MIN && "Int min should have been handled!");
  uint64_t AbsMulAmt = SignMulAmt < 0 ? -SignMulAmt : SignMulAmt;

  SDLoc DL(N);
  if (AbsMulAmt == 3 || AbsMulAmt == 5 || AbsMulAmt == 9) {
    SDValue NewMul = DAG.getNode(X86ISD::MUL_IMM, DL, VT, N->getOperand(0),
                                 DAG.getConstant(AbsMulAmt, DL, VT));
    if (SignMulAmt < 0)
      NewMul = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT),
                           NewMul);

    return NewMul;
  }

  uint64_t MulAmt1 = 0;
  uint64_t MulAmt2 = 0;
  if ((AbsMulAmt % 9) == 0) {
    MulAmt1 = 9;
    MulAmt2 = AbsMulAmt / 9;
  } else if ((AbsMulAmt % 5) == 0) {
    MulAmt1 = 5;
    MulAmt2 = AbsMulAmt / 5;
  } else if ((AbsMulAmt % 3) == 0) {
    MulAmt1 = 3;
    MulAmt2 = AbsMulAmt / 3;
  }

  SDValue NewMul;
  // For negative multiply amounts, only allow MulAmt2 to be a power of 2.
  if (MulAmt2 &&
      (isPowerOf2_64(MulAmt2) ||
       (SignMulAmt >= 0 && (MulAmt2 == 3 || MulAmt2 == 5 || MulAmt2 == 9)))) {

    if (isPowerOf2_64(MulAmt2) &&
        !(SignMulAmt >= 0 && N->hasOneUse() &&
          N->use_begin()->getOpcode() == ISD::ADD))
      // If second multiplifer is pow2, issue it first. We want the multiply by
      // 3, 5, or 9 to be folded into the addressing mode unless the lone use
      // is an add. Only do this for positive multiply amounts since the
      // negate would prevent it from being used as an address mode anyway.
      std::swap(MulAmt1, MulAmt2);

    if (isPowerOf2_64(MulAmt1))
      NewMul = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
                           DAG.getConstant(Log2_64(MulAmt1), DL, MVT::i8));
    else
      NewMul = DAG.getNode(X86ISD::MUL_IMM, DL, VT, N->getOperand(0),
                           DAG.getConstant(MulAmt1, DL, VT));

    if (isPowerOf2_64(MulAmt2))
      NewMul = DAG.getNode(ISD::SHL, DL, VT, NewMul,
                           DAG.getConstant(Log2_64(MulAmt2), DL, MVT::i8));
    else
      NewMul = DAG.getNode(X86ISD::MUL_IMM, DL, VT, NewMul,
                           DAG.getConstant(MulAmt2, DL, VT));

    // Negate the result.
    if (SignMulAmt < 0)
      NewMul = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT),
                           NewMul);
  } else if (!Subtarget.slowLEA())
    NewMul = combineMulSpecial(C->getZExtValue(), N, DAG, VT, DL);

  if (!NewMul) {
    assert(C->getZExtValue() != 0 &&
           C->getZExtValue() != (VT == MVT::i64 ? UINT64_MAX : UINT32_MAX) &&
           "Both cases that could cause potential overflows should have "
           "already been handled.");
    if (isPowerOf2_64(AbsMulAmt - 1)) {
      // (mul x, 2^N + 1) => (add (shl x, N), x)
      NewMul = DAG.getNode(
          ISD::ADD, DL, VT, N->getOperand(0),
          DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
                      DAG.getConstant(Log2_64(AbsMulAmt - 1), DL,
                                      MVT::i8)));
      // To negate, subtract the number from zero
      if (SignMulAmt < 0)
        NewMul = DAG.getNode(ISD::SUB, DL, VT,
                             DAG.getConstant(0, DL, VT), NewMul);
    } else if (isPowerOf2_64(AbsMulAmt + 1)) {
      // (mul x, 2^N - 1) => (sub (shl x, N), x)
      NewMul = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
                           DAG.getConstant(Log2_64(AbsMulAmt + 1),
                                           DL, MVT::i8));
      // To negate, reverse the operands of the subtract.
      if (SignMulAmt < 0)
        NewMul = DAG.getNode(ISD::SUB, DL, VT, N->getOperand(0), NewMul);
      else
        NewMul = DAG.getNode(ISD::SUB, DL, VT, NewMul, N->getOperand(0));
    } else if (SignMulAmt >= 0 && isPowerOf2_64(AbsMulAmt - 2)) {
      // (mul x, 2^N + 2) => (add (add (shl x, N), x), x)
      NewMul = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
                           DAG.getConstant(Log2_64(AbsMulAmt - 2),
                                           DL, MVT::i8));
      NewMul = DAG.getNode(ISD::ADD, DL, VT, NewMul, N->getOperand(0));
      NewMul = DAG.getNode(ISD::ADD, DL, VT, NewMul, N->getOperand(0));
    } else if (SignMulAmt >= 0 && isPowerOf2_64(AbsMulAmt + 2)) {
      // (mul x, 2^N - 2) => (sub (sub (shl x, N), x), x)
      NewMul = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
                           DAG.getConstant(Log2_64(AbsMulAmt + 2),
                                           DL, MVT::i8));
      NewMul = DAG.getNode(ISD::SUB, DL, VT, NewMul, N->getOperand(0));
      NewMul = DAG.getNode(ISD::SUB, DL, VT, NewMul, N->getOperand(0));
    }
  }

  return NewMul;
}

static SDValue combineShiftLeft(SDNode *N, SelectionDAG &DAG) {
  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);
  ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
  EVT VT = N0.getValueType();

  // fold (shl (and (setcc_c), c1), c2) -> (and setcc_c, (c1 << c2))
  // since the result of setcc_c is all zero's or all ones.
  if (VT.isInteger() && !VT.isVector() &&
      N1C && N0.getOpcode() == ISD::AND &&
      N0.getOperand(1).getOpcode() == ISD::Constant) {
    SDValue N00 = N0.getOperand(0);
    APInt Mask = N0.getConstantOperandAPInt(1);
    Mask <<= N1C->getAPIntValue();
    bool MaskOK = false;
    // We can handle cases concerning bit-widening nodes containing setcc_c if
    // we carefully interrogate the mask to make sure we are semantics
    // preserving.
    // The transform is not safe if the result of C1 << C2 exceeds the bitwidth
    // of the underlying setcc_c operation if the setcc_c was zero extended.
    // Consider the following example:
    //   zext(setcc_c)                 -> i32 0x0000FFFF
    //   c1                            -> i32 0x0000FFFF
    //   c2                            -> i32 0x00000001
    //   (shl (and (setcc_c), c1), c2) -> i32 0x0001FFFE
    //   (and setcc_c, (c1 << c2))     -> i32 0x0000FFFE
    if (N00.getOpcode() == X86ISD::SETCC_CARRY) {
      MaskOK = true;
    } else if (N00.getOpcode() == ISD::SIGN_EXTEND &&
               N00.getOperand(0).getOpcode() == X86ISD::SETCC_CARRY) {
      MaskOK = true;
    } else if ((N00.getOpcode() == ISD::ZERO_EXTEND ||
                N00.getOpcode() == ISD::ANY_EXTEND) &&
               N00.getOperand(0).getOpcode() == X86ISD::SETCC_CARRY) {
      MaskOK = Mask.isIntN(N00.getOperand(0).getValueSizeInBits());
    }
    if (MaskOK && Mask != 0) {
      SDLoc DL(N);
      return DAG.getNode(ISD::AND, DL, VT, N00, DAG.getConstant(Mask, DL, VT));
    }
  }

  // Hardware support for vector shifts is sparse which makes us scalarize the
  // vector operations in many cases. Also, on sandybridge ADD is faster than
  // shl.
  // (shl V, 1) -> add V,V
  if (auto *N1BV = dyn_cast<BuildVectorSDNode>(N1))
    if (auto *N1SplatC = N1BV->getConstantSplatNode()) {
      assert(N0.getValueType().isVector() && "Invalid vector shift type");
      // We shift all of the values by one. In many cases we do not have
      // hardware support for this operation. This is better expressed as an ADD
      // of two values.
      if (N1SplatC->isOne())
        return DAG.getNode(ISD::ADD, SDLoc(N), VT, N0, N0);
    }

  return SDValue();
}

static SDValue combineShiftRightArithmetic(SDNode *N, SelectionDAG &DAG) {
  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);
  EVT VT = N0.getValueType();
  unsigned Size = VT.getSizeInBits();

  // fold (ashr (shl, a, [56,48,32,24,16]), SarConst)
  // into (shl, (sext (a), [56,48,32,24,16] - SarConst)) or
  // into (lshr, (sext (a), SarConst - [56,48,32,24,16]))
  // depending on sign of (SarConst - [56,48,32,24,16])

  // sexts in X86 are MOVs. The MOVs have the same code size
  // as above SHIFTs (only SHIFT on 1 has lower code size).
  // However the MOVs have 2 advantages to a SHIFT:
  // 1. MOVs can write to a register that differs from source
  // 2. MOVs accept memory operands

  if (VT.isVector() || N1.getOpcode() != ISD::Constant ||
      N0.getOpcode() != ISD::SHL || !N0.hasOneUse() ||
      N0.getOperand(1).getOpcode() != ISD::Constant)
    return SDValue();

  SDValue N00 = N0.getOperand(0);
  SDValue N01 = N0.getOperand(1);
  APInt ShlConst = (cast<ConstantSDNode>(N01))->getAPIntValue();
  APInt SarConst = (cast<ConstantSDNode>(N1))->getAPIntValue();
  EVT CVT = N1.getValueType();

  if (SarConst.isNegative())
    return SDValue();

  for (MVT SVT : { MVT::i8, MVT::i16, MVT::i32 }) {
    unsigned ShiftSize = SVT.getSizeInBits();
    // skipping types without corresponding sext/zext and
    // ShlConst that is not one of [56,48,32,24,16]
    if (ShiftSize >= Size || ShlConst != Size - ShiftSize)
      continue;
    SDLoc DL(N);
    SDValue NN =
        DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, N00, DAG.getValueType(SVT));
    SarConst = SarConst - (Size - ShiftSize);
    if (SarConst == 0)
      return NN;
    else if (SarConst.isNegative())
      return DAG.getNode(ISD::SHL, DL, VT, NN,
                         DAG.getConstant(-SarConst, DL, CVT));
    else
      return DAG.getNode(ISD::SRA, DL, VT, NN,
                         DAG.getConstant(SarConst, DL, CVT));
  }
  return SDValue();
}

static SDValue combineShiftRightLogical(SDNode *N, SelectionDAG &DAG,
                                        TargetLowering::DAGCombinerInfo &DCI) {
  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);
  EVT VT = N0.getValueType();

  // Only do this on the last DAG combine as it can interfere with other
  // combines.
  if (!DCI.isAfterLegalizeDAG())
    return SDValue();

  // Try to improve a sequence of srl (and X, C1), C2 by inverting the order.
  // TODO: This is a generic DAG combine that became an x86-only combine to
  // avoid shortcomings in other folds such as bswap, bit-test ('bt'), and
  // and-not ('andn').
  if (N0.getOpcode() != ISD::AND || !N0.hasOneUse())
    return SDValue();

  auto *ShiftC = dyn_cast<ConstantSDNode>(N1);
  auto *AndC = dyn_cast<ConstantSDNode>(N0.getOperand(1));
  if (!ShiftC || !AndC)
    return SDValue();

  // If we can shrink the constant mask below 8-bits or 32-bits, then this
  // transform should reduce code size. It may also enable secondary transforms
  // from improved known-bits analysis or instruction selection.
  APInt MaskVal = AndC->getAPIntValue();

  // If this can be matched by a zero extend, don't optimize.
  if (MaskVal.isMask()) {
    unsigned TO = MaskVal.countTrailingOnes();
    if (TO >= 8 && isPowerOf2_32(TO))
      return SDValue();
  }

  APInt NewMaskVal = MaskVal.lshr(ShiftC->getAPIntValue());
  unsigned OldMaskSize = MaskVal.getMinSignedBits();
  unsigned NewMaskSize = NewMaskVal.getMinSignedBits();
  if ((OldMaskSize > 8 && NewMaskSize <= 8) ||
      (OldMaskSize > 32 && NewMaskSize <= 32)) {
    // srl (and X, AndC), ShiftC --> and (srl X, ShiftC), (AndC >> ShiftC)
    SDLoc DL(N);
    SDValue NewMask = DAG.getConstant(NewMaskVal, DL, VT);
    SDValue NewShift = DAG.getNode(ISD::SRL, DL, VT, N0.getOperand(0), N1);
    return DAG.getNode(ISD::AND, DL, VT, NewShift, NewMask);
  }
  return SDValue();
}

static SDValue combineVectorPack(SDNode *N, SelectionDAG &DAG,
                                 TargetLowering::DAGCombinerInfo &DCI,
                                 const X86Subtarget &Subtarget) {
  unsigned Opcode = N->getOpcode();
  assert((X86ISD::PACKSS == Opcode || X86ISD::PACKUS == Opcode) &&
         "Unexpected shift opcode");

  EVT VT = N->getValueType(0);
  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);
  unsigned DstBitsPerElt = VT.getScalarSizeInBits();
  unsigned SrcBitsPerElt = 2 * DstBitsPerElt;
  assert(N0.getScalarValueSizeInBits() == SrcBitsPerElt &&
         N1.getScalarValueSizeInBits() == SrcBitsPerElt &&
         "Unexpected PACKSS/PACKUS input type");

  bool IsSigned = (X86ISD::PACKSS == Opcode);

  // Constant Folding.
  APInt UndefElts0, UndefElts1;
  SmallVector<APInt, 32> EltBits0, EltBits1;
  if ((N0.isUndef() || N->isOnlyUserOf(N0.getNode())) &&
      (N1.isUndef() || N->isOnlyUserOf(N1.getNode())) &&
      getTargetConstantBitsFromNode(N0, SrcBitsPerElt, UndefElts0, EltBits0) &&
      getTargetConstantBitsFromNode(N1, SrcBitsPerElt, UndefElts1, EltBits1)) {
    unsigned NumLanes = VT.getSizeInBits() / 128;
    unsigned NumDstElts = VT.getVectorNumElements();
    unsigned NumSrcElts = NumDstElts / 2;
    unsigned NumDstEltsPerLane = NumDstElts / NumLanes;
    unsigned NumSrcEltsPerLane = NumSrcElts / NumLanes;

    APInt Undefs(NumDstElts, 0);
    SmallVector<APInt, 32> Bits(NumDstElts, APInt::getNullValue(DstBitsPerElt));
    for (unsigned Lane = 0; Lane != NumLanes; ++Lane) {
      for (unsigned Elt = 0; Elt != NumDstEltsPerLane; ++Elt) {
        unsigned SrcIdx = Lane * NumSrcEltsPerLane + Elt % NumSrcEltsPerLane;
        auto &UndefElts = (Elt >= NumSrcEltsPerLane ? UndefElts1 : UndefElts0);
        auto &EltBits = (Elt >= NumSrcEltsPerLane ? EltBits1 : EltBits0);

        if (UndefElts[SrcIdx]) {
          Undefs.setBit(Lane * NumDstEltsPerLane + Elt);
          continue;
        }

        APInt &Val = EltBits[SrcIdx];
        if (IsSigned) {
          // PACKSS: Truncate signed value with signed saturation.
          // Source values less than dst minint are saturated to minint.
          // Source values greater than dst maxint are saturated to maxint.
          if (Val.isSignedIntN(DstBitsPerElt))
            Val = Val.trunc(DstBitsPerElt);
          else if (Val.isNegative())
            Val = APInt::getSignedMinValue(DstBitsPerElt);
          else
            Val = APInt::getSignedMaxValue(DstBitsPerElt);
        } else {
          // PACKUS: Truncate signed value with unsigned saturation.
          // Source values less than zero are saturated to zero.
          // Source values greater than dst maxuint are saturated to maxuint.
          if (Val.isIntN(DstBitsPerElt))
            Val = Val.trunc(DstBitsPerElt);
          else if (Val.isNegative())
            Val = APInt::getNullValue(DstBitsPerElt);
          else
            Val = APInt::getAllOnesValue(DstBitsPerElt);
        }
        Bits[Lane * NumDstEltsPerLane + Elt] = Val;
      }
    }

    return getConstVector(Bits, Undefs, VT.getSimpleVT(), DAG, SDLoc(N));
  }

  // Try to combine a PACKUSWB/PACKSSWB implemented truncate with a regular
  // truncate to create a larger truncate.
  if (Subtarget.hasAVX512() &&
      N0.getOpcode() == ISD::TRUNCATE && N1.isUndef() && VT == MVT::v16i8 &&
      N0.getOperand(0).getValueType() == MVT::v8i32) {
    if ((IsSigned && DAG.ComputeNumSignBits(N0) > 8) ||
        (!IsSigned &&
         DAG.MaskedValueIsZero(N0, APInt::getHighBitsSet(16, 8)))) {
      if (Subtarget.hasVLX())
        return DAG.getNode(X86ISD::VTRUNC, SDLoc(N), VT, N0.getOperand(0));

      // Widen input to v16i32 so we can truncate that.
      SDLoc dl(N);
      SDValue Concat = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v16i32,
                                   N0.getOperand(0), DAG.getUNDEF(MVT::v8i32));
      return DAG.getNode(ISD::TRUNCATE, SDLoc(N), VT, Concat);
    }
  }

  // Attempt to combine as shuffle.
  SDValue Op(N, 0);
  if (SDValue Res = combineX86ShufflesRecursively(Op, DAG, Subtarget))
    return Res;

  return SDValue();
}

static SDValue combineVectorShiftVar(SDNode *N, SelectionDAG &DAG,
                                     TargetLowering::DAGCombinerInfo &DCI,
                                     const X86Subtarget &Subtarget) {
  assert((X86ISD::VSHL == N->getOpcode() || X86ISD::VSRA == N->getOpcode() ||
          X86ISD::VSRL == N->getOpcode()) &&
         "Unexpected shift opcode");
  EVT VT = N->getValueType(0);
  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);

  // Shift zero -> zero.
  if (ISD::isBuildVectorAllZeros(N0.getNode()))
    return DAG.getConstant(0, SDLoc(N), VT);

  // Detect constant shift amounts.
  APInt UndefElts;
  SmallVector<APInt, 32> EltBits;
  if (getTargetConstantBitsFromNode(N1, 64, UndefElts, EltBits, true, false)) {
    unsigned X86Opc = getTargetVShiftUniformOpcode(N->getOpcode(), false);
    return getTargetVShiftByConstNode(X86Opc, SDLoc(N), VT.getSimpleVT(), N0,
                                      EltBits[0].getZExtValue(), DAG);
  }

  APInt KnownUndef, KnownZero;
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  APInt DemandedElts = APInt::getAllOnesValue(VT.getVectorNumElements());
  if (TLI.SimplifyDemandedVectorElts(SDValue(N, 0), DemandedElts, KnownUndef,
                                     KnownZero, DCI))
    return SDValue(N, 0);

  return SDValue();
}

static SDValue combineVectorShiftImm(SDNode *N, SelectionDAG &DAG,
                                     TargetLowering::DAGCombinerInfo &DCI,
                                     const X86Subtarget &Subtarget) {
  unsigned Opcode = N->getOpcode();
  assert((X86ISD::VSHLI == Opcode || X86ISD::VSRAI == Opcode ||
          X86ISD::VSRLI == Opcode) &&
         "Unexpected shift opcode");
  bool LogicalShift = X86ISD::VSHLI == Opcode || X86ISD::VSRLI == Opcode;
  EVT VT = N->getValueType(0);
  SDValue N0 = N->getOperand(0);
  unsigned NumBitsPerElt = VT.getScalarSizeInBits();
  assert(VT == N0.getValueType() && (NumBitsPerElt % 8) == 0 &&
         "Unexpected value type");
  assert(N->getOperand(1).getValueType() == MVT::i8 &&
         "Unexpected shift amount type");

  // Out of range logical bit shifts are guaranteed to be zero.
  // Out of range arithmetic bit shifts splat the sign bit.
  unsigned ShiftVal = N->getConstantOperandVal(1);
  if (ShiftVal >= NumBitsPerElt) {
    if (LogicalShift)
      return DAG.getConstant(0, SDLoc(N), VT);
    else
      ShiftVal = NumBitsPerElt - 1;
  }

  // Shift N0 by zero -> N0.
  if (!ShiftVal)
    return N0;

  // Shift zero -> zero.
  if (ISD::isBuildVectorAllZeros(N0.getNode()))
    return DAG.getConstant(0, SDLoc(N), VT);

  // Fold (VSRAI (VSRAI X, C1), C2) --> (VSRAI X, (C1 + C2)) with (C1 + C2)
  // clamped to (NumBitsPerElt - 1).
  if (Opcode == X86ISD::VSRAI && N0.getOpcode() == X86ISD::VSRAI) {
    unsigned ShiftVal2 = cast<ConstantSDNode>(N0.getOperand(1))->getZExtValue();
    unsigned NewShiftVal = ShiftVal + ShiftVal2;
    if (NewShiftVal >= NumBitsPerElt)
      NewShiftVal = NumBitsPerElt - 1;
    return DAG.getNode(X86ISD::VSRAI, SDLoc(N), VT, N0.getOperand(0),
                       DAG.getTargetConstant(NewShiftVal, SDLoc(N), MVT::i8));
  }

  // We can decode 'whole byte' logical bit shifts as shuffles.
  if (LogicalShift && (ShiftVal % 8) == 0) {
    SDValue Op(N, 0);
    if (SDValue Res = combineX86ShufflesRecursively(Op, DAG, Subtarget))
      return Res;
  }

  // Constant Folding.
  APInt UndefElts;
  SmallVector<APInt, 32> EltBits;
  if (N->isOnlyUserOf(N0.getNode()) &&
      getTargetConstantBitsFromNode(N0, NumBitsPerElt, UndefElts, EltBits)) {
    assert(EltBits.size() == VT.getVectorNumElements() &&
           "Unexpected shift value type");
    for (APInt &Elt : EltBits) {
      if (X86ISD::VSHLI == Opcode)
        Elt <<= ShiftVal;
      else if (X86ISD::VSRAI == Opcode)
        Elt.ashrInPlace(ShiftVal);
      else
        Elt.lshrInPlace(ShiftVal);
    }
    return getConstVector(EltBits, UndefElts, VT.getSimpleVT(), DAG, SDLoc(N));
  }

  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  if (TLI.SimplifyDemandedBits(SDValue(N, 0),
                               APInt::getAllOnesValue(NumBitsPerElt), DCI))
    return SDValue(N, 0);

  return SDValue();
}

static SDValue combineVectorInsert(SDNode *N, SelectionDAG &DAG,
                                   TargetLowering::DAGCombinerInfo &DCI,
                                   const X86Subtarget &Subtarget) {
  EVT VT = N->getValueType(0);
  assert(((N->getOpcode() == X86ISD::PINSRB && VT == MVT::v16i8) ||
          (N->getOpcode() == X86ISD::PINSRW && VT == MVT::v8i16) ||
          N->getOpcode() == ISD::INSERT_VECTOR_ELT) &&
         "Unexpected vector insertion");

  if (N->getOpcode() == X86ISD::PINSRB || N->getOpcode() == X86ISD::PINSRW) {
    unsigned NumBitsPerElt = VT.getScalarSizeInBits();
    const TargetLowering &TLI = DAG.getTargetLoweringInfo();
    if (TLI.SimplifyDemandedBits(SDValue(N, 0),
                                 APInt::getAllOnesValue(NumBitsPerElt), DCI))
      return SDValue(N, 0);
  }

  // Attempt to combine insertion patterns to a shuffle.
  if (VT.isSimple() && DCI.isAfterLegalizeDAG()) {
    SDValue Op(N, 0);
    if (SDValue Res = combineX86ShufflesRecursively(Op, DAG, Subtarget))
      return Res;
  }

  return SDValue();
}

/// Recognize the distinctive (AND (setcc ...) (setcc ..)) where both setccs
/// reference the same FP CMP, and rewrite for CMPEQSS and friends. Likewise for
/// OR -> CMPNEQSS.
static SDValue combineCompareEqual(SDNode *N, SelectionDAG &DAG,
                                   TargetLowering::DAGCombinerInfo &DCI,
                                   const X86Subtarget &Subtarget) {
  unsigned opcode;

  // SSE1 supports CMP{eq|ne}SS, and SSE2 added CMP{eq|ne}SD, but
  // we're requiring SSE2 for both.
  if (Subtarget.hasSSE2() && isAndOrOfSetCCs(SDValue(N, 0U), opcode)) {
    SDValue N0 = N->getOperand(0);
    SDValue N1 = N->getOperand(1);
    SDValue CMP0 = N0.getOperand(1);
    SDValue CMP1 = N1.getOperand(1);
    SDLoc DL(N);

    // The SETCCs should both refer to the same CMP.
    if (CMP0.getOpcode() != X86ISD::FCMP || CMP0 != CMP1)
      return SDValue();

    SDValue CMP00 = CMP0->getOperand(0);
    SDValue CMP01 = CMP0->getOperand(1);
    EVT     VT    = CMP00.getValueType();

    if (VT == MVT::f32 || VT == MVT::f64) {
      bool ExpectingFlags = false;
      // Check for any users that want flags:
      for (SDNode::use_iterator UI = N->use_begin(), UE = N->use_end();
           !ExpectingFlags && UI != UE; ++UI)
        switch (UI->getOpcode()) {
        default:
        case ISD::BR_CC:
        case ISD::BRCOND:
        case ISD::SELECT:
          ExpectingFlags = true;
          break;
        case ISD::CopyToReg:
        case ISD::SIGN_EXTEND:
        case ISD::ZERO_EXTEND:
        case ISD::ANY_EXTEND:
          break;
        }

      if (!ExpectingFlags) {
        enum X86::CondCode cc0 = (enum X86::CondCode)N0.getConstantOperandVal(0);
        enum X86::CondCode cc1 = (enum X86::CondCode)N1.getConstantOperandVal(0);

        if (cc1 == X86::COND_E || cc1 == X86::COND_NE) {
          X86::CondCode tmp = cc0;
          cc0 = cc1;
          cc1 = tmp;
        }

        if ((cc0 == X86::COND_E  && cc1 == X86::COND_NP) ||
            (cc0 == X86::COND_NE && cc1 == X86::COND_P)) {
          // FIXME: need symbolic constants for these magic numbers.
          // See X86ATTInstPrinter.cpp:printSSECC().
          unsigned x86cc = (cc0 == X86::COND_E) ? 0 : 4;
          if (Subtarget.hasAVX512()) {
            SDValue FSetCC =
                DAG.getNode(X86ISD::FSETCCM, DL, MVT::v1i1, CMP00, CMP01,
                            DAG.getTargetConstant(x86cc, DL, MVT::i8));
            // Need to fill with zeros to ensure the bitcast will produce zeroes
            // for the upper bits. An EXTRACT_ELEMENT here wouldn't guarantee that.
            SDValue Ins = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, MVT::v16i1,
                                      DAG.getConstant(0, DL, MVT::v16i1),
                                      FSetCC, DAG.getIntPtrConstant(0, DL));
            return DAG.getZExtOrTrunc(DAG.getBitcast(MVT::i16, Ins), DL,
                                      N->getSimpleValueType(0));
          }
          SDValue OnesOrZeroesF =
              DAG.getNode(X86ISD::FSETCC, DL, CMP00.getValueType(), CMP00,
                          CMP01, DAG.getTargetConstant(x86cc, DL, MVT::i8));

          bool is64BitFP = (CMP00.getValueType() == MVT::f64);
          MVT IntVT = is64BitFP ? MVT::i64 : MVT::i32;

          if (is64BitFP && !Subtarget.is64Bit()) {
            // On a 32-bit target, we cannot bitcast the 64-bit float to a
            // 64-bit integer, since that's not a legal type. Since
            // OnesOrZeroesF is all ones of all zeroes, we don't need all the
            // bits, but can do this little dance to extract the lowest 32 bits
            // and work with those going forward.
            SDValue Vector64 = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v2f64,
                                           OnesOrZeroesF);
            SDValue Vector32 = DAG.getBitcast(MVT::v4f32, Vector64);
            OnesOrZeroesF = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32,
                                        Vector32, DAG.getIntPtrConstant(0, DL));
            IntVT = MVT::i32;
          }

          SDValue OnesOrZeroesI = DAG.getBitcast(IntVT, OnesOrZeroesF);
          SDValue ANDed = DAG.getNode(ISD::AND, DL, IntVT, OnesOrZeroesI,
                                      DAG.getConstant(1, DL, IntVT));
          SDValue OneBitOfTruth = DAG.getNode(ISD::TRUNCATE, DL, MVT::i8,
                                              ANDed);
          return OneBitOfTruth;
        }
      }
    }
  }
  return SDValue();
}

/// Try to fold: (and (xor X, -1), Y) -> (andnp X, Y).
static SDValue combineANDXORWithAllOnesIntoANDNP(SDNode *N, SelectionDAG &DAG) {
  assert(N->getOpcode() == ISD::AND);

  MVT VT = N->getSimpleValueType(0);
  if (!VT.is128BitVector() && !VT.is256BitVector() && !VT.is512BitVector())
    return SDValue();

  SDValue X, Y;
  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);

  if (SDValue Not = IsNOT(N0, DAG)) {
    X = Not;
    Y = N1;
  } else if (SDValue Not = IsNOT(N1, DAG)) {
    X = Not;
    Y = N0;
  } else
    return SDValue();

  X = DAG.getBitcast(VT, X);
  Y = DAG.getBitcast(VT, Y);
  return DAG.getNode(X86ISD::ANDNP, SDLoc(N), VT, X, Y);
}

// Try to widen AND, OR and XOR nodes to VT in order to remove casts around
// logical operations, like in the example below.
//   or (and (truncate x, truncate y)),
//      (xor (truncate z, build_vector (constants)))
// Given a target type \p VT, we generate
//   or (and x, y), (xor z, zext(build_vector (constants)))
// given x, y and z are of type \p VT. We can do so, if operands are either
// truncates from VT types, the second operand is a vector of constants or can
// be recursively promoted.
static SDValue PromoteMaskArithmetic(SDNode *N, EVT VT, SelectionDAG &DAG,
                                     unsigned Depth) {
  // Limit recursion to avoid excessive compile times.
  if (Depth >= SelectionDAG::MaxRecursionDepth)
    return SDValue();

  if (N->getOpcode() != ISD::XOR && N->getOpcode() != ISD::AND &&
      N->getOpcode() != ISD::OR)
    return SDValue();

  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);
  SDLoc DL(N);

  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  if (!TLI.isOperationLegalOrPromote(N->getOpcode(), VT))
    return SDValue();

  if (SDValue NN0 = PromoteMaskArithmetic(N0.getNode(), VT, DAG, Depth + 1))
    N0 = NN0;
  else {
    // The Left side has to be a trunc.
    if (N0.getOpcode() != ISD::TRUNCATE)
      return SDValue();

    // The type of the truncated inputs.
    if (N0.getOperand(0).getValueType() != VT)
      return SDValue();

    N0 = N0.getOperand(0);
  }

  if (SDValue NN1 = PromoteMaskArithmetic(N1.getNode(), VT, DAG, Depth + 1))
    N1 = NN1;
  else {
    // The right side has to be a 'trunc' or a constant vector.
    bool RHSTrunc = N1.getOpcode() == ISD::TRUNCATE &&
                    N1.getOperand(0).getValueType() == VT;
    if (!RHSTrunc && !ISD::isBuildVectorOfConstantSDNodes(N1.getNode()))
      return SDValue();

    if (RHSTrunc)
      N1 = N1.getOperand(0);
    else
      N1 = DAG.getNode(ISD::ZERO_EXTEND, DL, VT, N1);
  }

  return DAG.getNode(N->getOpcode(), DL, VT, N0, N1);
}

// On AVX/AVX2 the type v8i1 is legalized to v8i16, which is an XMM sized
// register. In most cases we actually compare or select YMM-sized registers
// and mixing the two types creates horrible code. This method optimizes
// some of the transition sequences.
// Even with AVX-512 this is still useful for removing casts around logical
// operations on vXi1 mask types.
static SDValue PromoteMaskArithmetic(SDNode *N, SelectionDAG &DAG,
                                     const X86Subtarget &Subtarget) {
  EVT VT = N->getValueType(0);
  assert(VT.isVector() && "Expected vector type");

  SDLoc DL(N);
  assert((N->getOpcode() == ISD::ANY_EXTEND ||
          N->getOpcode() == ISD::ZERO_EXTEND ||
          N->getOpcode() == ISD::SIGN_EXTEND) && "Invalid Node");

  SDValue Narrow = N->getOperand(0);
  EVT NarrowVT = Narrow.getValueType();

  // Generate the wide operation.
  SDValue Op = PromoteMaskArithmetic(Narrow.getNode(), VT, DAG, 0);
  if (!Op)
    return SDValue();
  switch (N->getOpcode()) {
  default: llvm_unreachable("Unexpected opcode");
  case ISD::ANY_EXTEND:
    return Op;
  case ISD::ZERO_EXTEND:
    return DAG.getZeroExtendInReg(Op, DL, NarrowVT.getScalarType());
  case ISD::SIGN_EXTEND:
    return DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT,
                       Op, DAG.getValueType(NarrowVT));
  }
}

/// If both input operands of a logic op are being cast from floating point
/// types, try to convert this into a floating point logic node to avoid
/// unnecessary moves from SSE to integer registers.
static SDValue convertIntLogicToFPLogic(SDNode *N, SelectionDAG &DAG,
                                        const X86Subtarget &Subtarget) {
  EVT VT = N->getValueType(0);
  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);
  SDLoc DL(N);

  if (N0.getOpcode() != ISD::BITCAST || N1.getOpcode() != ISD::BITCAST)
    return SDValue();

  SDValue N00 = N0.getOperand(0);
  SDValue N10 = N1.getOperand(0);
  EVT N00Type = N00.getValueType();
  EVT N10Type = N10.getValueType();

  // Ensure that both types are the same and are legal scalar fp types.
  if (N00Type != N10Type ||
      !((Subtarget.hasSSE1() && N00Type == MVT::f32) ||
        (Subtarget.hasSSE2() && N00Type == MVT::f64)))
    return SDValue();

  unsigned FPOpcode;
  switch (N->getOpcode()) {
  default: llvm_unreachable("Unexpected input node for FP logic conversion");
  case ISD::AND: FPOpcode = X86ISD::FAND; break;
  case ISD::OR:  FPOpcode = X86ISD::FOR;  break;
  case ISD::XOR: FPOpcode = X86ISD::FXOR; break;
  }

  SDValue FPLogic = DAG.getNode(FPOpcode, DL, N00Type, N00, N10);
  return DAG.getBitcast(VT, FPLogic);
}

/// If this is a zero/all-bits result that is bitwise-anded with a low bits
/// mask. (Mask == 1 for the x86 lowering of a SETCC + ZEXT), replace the 'and'
/// with a shift-right to eliminate loading the vector constant mask value.
static SDValue combineAndMaskToShift(SDNode *N, SelectionDAG &DAG,
                                     const X86Subtarget &Subtarget) {
  SDValue Op0 = peekThroughBitcasts(N->getOperand(0));
  SDValue Op1 = peekThroughBitcasts(N->getOperand(1));
  EVT VT0 = Op0.getValueType();
  EVT VT1 = Op1.getValueType();

  if (VT0 != VT1 || !VT0.isSimple() || !VT0.isInteger())
    return SDValue();

  APInt SplatVal;
  if (!ISD::isConstantSplatVector(Op1.getNode(), SplatVal) ||
      !SplatVal.isMask())
    return SDValue();

  // Don't prevent creation of ANDN.
  if (isBitwiseNot(Op0))
    return SDValue();

  if (!SupportedVectorShiftWithImm(VT0.getSimpleVT(), Subtarget, ISD::SRL))
    return SDValue();

  unsigned EltBitWidth = VT0.getScalarSizeInBits();
  if (EltBitWidth != DAG.ComputeNumSignBits(Op0))
    return SDValue();

  SDLoc DL(N);
  unsigned ShiftVal = SplatVal.countTrailingOnes();
  SDValue ShAmt = DAG.getTargetConstant(EltBitWidth - ShiftVal, DL, MVT::i8);
  SDValue Shift = DAG.getNode(X86ISD::VSRLI, DL, VT0, Op0, ShAmt);
  return DAG.getBitcast(N->getValueType(0), Shift);
}

// Get the index node from the lowered DAG of a GEP IR instruction with one
// indexing dimension.
static SDValue getIndexFromUnindexedLoad(LoadSDNode *Ld) {
  if (Ld->isIndexed())
    return SDValue();

  SDValue Base = Ld->getBasePtr();

  if (Base.getOpcode() != ISD::ADD)
    return SDValue();

  SDValue ShiftedIndex = Base.getOperand(0);

  if (ShiftedIndex.getOpcode() != ISD::SHL)
    return SDValue();

  return ShiftedIndex.getOperand(0);

}

static bool hasBZHI(const X86Subtarget &Subtarget, MVT VT) {
  if (Subtarget.hasBMI2() && VT.isScalarInteger()) {
    switch (VT.getSizeInBits()) {
    default: return false;
    case 64: return Subtarget.is64Bit() ? true : false;
    case 32: return true;
    }
  }
  return false;
}

// This function recognizes cases where X86 bzhi instruction can replace and
// 'and-load' sequence.
// In case of loading integer value from an array of constants which is defined
// as follows:
//
//   int array[SIZE] = {0x0, 0x1, 0x3, 0x7, 0xF ..., 2^(SIZE-1) - 1}
//
// then applying a bitwise and on the result with another input.
// It's equivalent to performing bzhi (zero high bits) on the input, with the
// same index of the load.
static SDValue combineAndLoadToBZHI(SDNode *Node, SelectionDAG &DAG,
                                    const X86Subtarget &Subtarget) {
  MVT VT = Node->getSimpleValueType(0);
  SDLoc dl(Node);

  // Check if subtarget has BZHI instruction for the node's type
  if (!hasBZHI(Subtarget, VT))
    return SDValue();

  // Try matching the pattern for both operands.
  for (unsigned i = 0; i < 2; i++) {
    SDValue N = Node->getOperand(i);
    LoadSDNode *Ld = dyn_cast<LoadSDNode>(N.getNode());

     // continue if the operand is not a load instruction
    if (!Ld)
      return SDValue();

    const Value *MemOp = Ld->getMemOperand()->getValue();

    if (!MemOp)
      return SDValue();

    if (const GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(MemOp)) {
      if (GlobalVariable *GV = dyn_cast<GlobalVariable>(GEP->getOperand(0))) {
        if (GV->isConstant() && GV->hasDefinitiveInitializer()) {

          Constant *Init = GV->getInitializer();
          Type *Ty = Init->getType();
          if (!isa<ConstantDataArray>(Init) ||
              !Ty->getArrayElementType()->isIntegerTy() ||
              Ty->getArrayElementType()->getScalarSizeInBits() !=
                  VT.getSizeInBits() ||
              Ty->getArrayNumElements() >
                  Ty->getArrayElementType()->getScalarSizeInBits())
            continue;

          // Check if the array's constant elements are suitable to our case.
          uint64_t ArrayElementCount = Init->getType()->getArrayNumElements();
          bool ConstantsMatch = true;
          for (uint64_t j = 0; j < ArrayElementCount; j++) {
            ConstantInt *Elem =
                dyn_cast<ConstantInt>(Init->getAggregateElement(j));
            if (Elem->getZExtValue() != (((uint64_t)1 << j) - 1)) {
              ConstantsMatch = false;
              break;
            }
          }
          if (!ConstantsMatch)
            continue;

          // Do the transformation (For 32-bit type):
          // -> (and (load arr[idx]), inp)
          // <- (and (srl 0xFFFFFFFF, (sub 32, idx)))
          //    that will be replaced with one bzhi instruction.
          SDValue Inp = (i == 0) ? Node->getOperand(1) : Node->getOperand(0);
          SDValue SizeC = DAG.getConstant(VT.getSizeInBits(), dl, MVT::i32);

          // Get the Node which indexes into the array.
          SDValue Index = getIndexFromUnindexedLoad(Ld);
          if (!Index)
            return SDValue();
          Index = DAG.getZExtOrTrunc(Index, dl, MVT::i32);

          SDValue Sub = DAG.getNode(ISD::SUB, dl, MVT::i32, SizeC, Index);
          Sub = DAG.getNode(ISD::TRUNCATE, dl, MVT::i8, Sub);

          SDValue AllOnes = DAG.getAllOnesConstant(dl, VT);
          SDValue LShr = DAG.getNode(ISD::SRL, dl, VT, AllOnes, Sub);

          return DAG.getNode(ISD::AND, dl, VT, Inp, LShr);
        }
      }
    }
  }
  return SDValue();
}

// Look for (and (ctpop X), 1) which is the IR form of __builtin_parity.
// Turn it into series of XORs and a setnp.
static SDValue combineParity(SDNode *N, SelectionDAG &DAG,
                             const X86Subtarget &Subtarget) {
  EVT VT = N->getValueType(0);

  // We only support 64-bit and 32-bit. 64-bit requires special handling
  // unless the 64-bit popcnt instruction is legal.
  if (VT != MVT::i32 && VT != MVT::i64)
    return SDValue();

  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  if (TLI.isTypeLegal(VT) && TLI.isOperationLegal(ISD::CTPOP, VT))
    return SDValue();

  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);

  // LHS needs to be a single use CTPOP.
  if (N0.getOpcode() != ISD::CTPOP || !N0.hasOneUse())
    return SDValue();

  // RHS needs to be 1.
  if (!isOneConstant(N1))
    return SDValue();

  SDLoc DL(N);
  SDValue X = N0.getOperand(0);

  // If this is 64-bit, its always best to xor the two 32-bit pieces together
  // even if we have popcnt.
  if (VT == MVT::i64) {
    SDValue Hi = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32,
                             DAG.getNode(ISD::SRL, DL, VT, X,
                                         DAG.getConstant(32, DL, MVT::i8)));
    SDValue Lo = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, X);
    X = DAG.getNode(ISD::XOR, DL, MVT::i32, Lo, Hi);
    // Generate a 32-bit parity idiom. This will bring us back here if we need
    // to expand it too.
    SDValue Parity = DAG.getNode(ISD::AND, DL, MVT::i32,
                                 DAG.getNode(ISD::CTPOP, DL, MVT::i32, X),
                                 DAG.getConstant(1, DL, MVT::i32));
    return DAG.getNode(ISD::ZERO_EXTEND, DL, VT, Parity);
  }
  assert(VT == MVT::i32 && "Unexpected VT!");

  // Xor the high and low 16-bits together using a 32-bit operation.
  SDValue Hi16 = DAG.getNode(ISD::SRL, DL, VT, X,
                             DAG.getConstant(16, DL, MVT::i8));
  X = DAG.getNode(ISD::XOR, DL, VT, X, Hi16);

  // Finally xor the low 2 bytes together and use a 8-bit flag setting xor.
  // This should allow an h-reg to be used to save a shift.
  // FIXME: We only get an h-reg in 32-bit mode.
  SDValue Hi = DAG.getNode(ISD::TRUNCATE, DL, MVT::i8,
                           DAG.getNode(ISD::SRL, DL, VT, X,
                                       DAG.getConstant(8, DL, MVT::i8)));
  SDValue Lo = DAG.getNode(ISD::TRUNCATE, DL, MVT::i8, X);
  SDVTList VTs = DAG.getVTList(MVT::i8, MVT::i32);
  SDValue Flags = DAG.getNode(X86ISD::XOR, DL, VTs, Lo, Hi).getValue(1);

  // Copy the inverse of the parity flag into a register with setcc.
  SDValue Setnp = getSETCC(X86::COND_NP, Flags, DL, DAG);
  // Zero extend to original type.
  return DAG.getNode(ISD::ZERO_EXTEND, DL, N->getValueType(0), Setnp);
}


// Look for (and (bitcast (vXi1 (concat_vectors (vYi1 setcc), undef,))), C)
// Where C is a mask containing the same number of bits as the setcc and
// where the setcc will freely 0 upper bits of k-register. We can replace the
// undef in the concat with 0s and remove the AND. This mainly helps with
// v2i1/v4i1 setcc being casted to scalar.
static SDValue combineScalarAndWithMaskSetcc(SDNode *N, SelectionDAG &DAG,
                                             const X86Subtarget &Subtarget) {
  assert(N->getOpcode() == ISD::AND && "Unexpected opcode!");

  EVT VT = N->getValueType(0);

  // Make sure this is an AND with constant. We will check the value of the
  // constant later.
  if (!isa<ConstantSDNode>(N->getOperand(1)))
    return SDValue();

  // This is implied by the ConstantSDNode.
  assert(!VT.isVector() && "Expected scalar VT!");

  if (N->getOperand(0).getOpcode() != ISD::BITCAST ||
      !N->getOperand(0).hasOneUse() ||
      !N->getOperand(0).getOperand(0).hasOneUse())
    return SDValue();

  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  SDValue Src = N->getOperand(0).getOperand(0);
  EVT SrcVT = Src.getValueType();
  if (!SrcVT.isVector() || SrcVT.getVectorElementType() != MVT::i1 ||
      !TLI.isTypeLegal(SrcVT))
    return SDValue();

  if (Src.getOpcode() != ISD::CONCAT_VECTORS)
    return SDValue();

  // We only care about the first subvector of the concat, we expect the
  // other subvectors to be ignored due to the AND if we make the change.
  SDValue SubVec = Src.getOperand(0);
  EVT SubVecVT = SubVec.getValueType();

  // First subvector should be a setcc with a legal result type. The RHS of the
  // AND should be a mask with this many bits.
  if (SubVec.getOpcode() != ISD::SETCC || !TLI.isTypeLegal(SubVecVT) ||
      !N->getConstantOperandAPInt(1).isMask(SubVecVT.getVectorNumElements()))
    return SDValue();

  EVT SetccVT = SubVec.getOperand(0).getValueType();
  if (!TLI.isTypeLegal(SetccVT) ||
      !(Subtarget.hasVLX() || SetccVT.is512BitVector()))
    return SDValue();

  if (!(Subtarget.hasBWI() || SetccVT.getScalarSizeInBits() >= 32))
    return SDValue();

  // We passed all the checks. Rebuild the concat_vectors with zeroes
  // and cast it back to VT.
  SDLoc dl(N);
  SmallVector<SDValue, 4> Ops(Src.getNumOperands(),
                              DAG.getConstant(0, dl, SubVecVT));
  Ops[0] = SubVec;
  SDValue Concat = DAG.getNode(ISD::CONCAT_VECTORS, dl, SrcVT,
                               Ops);
  return DAG.getBitcast(VT, Concat);
}

static SDValue combineAnd(SDNode *N, SelectionDAG &DAG,
                          TargetLowering::DAGCombinerInfo &DCI,
                          const X86Subtarget &Subtarget) {
  EVT VT = N->getValueType(0);

  // If this is SSE1 only convert to FAND to avoid scalarization.
  if (Subtarget.hasSSE1() && !Subtarget.hasSSE2() && VT == MVT::v4i32) {
    return DAG.getBitcast(
        MVT::v4i32, DAG.getNode(X86ISD::FAND, SDLoc(N), MVT::v4f32,
                                DAG.getBitcast(MVT::v4f32, N->getOperand(0)),
                                DAG.getBitcast(MVT::v4f32, N->getOperand(1))));
  }

  // Use a 32-bit and+zext if upper bits known zero.
  if (VT == MVT::i64 && Subtarget.is64Bit() &&
      !isa<ConstantSDNode>(N->getOperand(1))) {
    APInt HiMask = APInt::getHighBitsSet(64, 32);
    if (DAG.MaskedValueIsZero(N->getOperand(1), HiMask) ||
        DAG.MaskedValueIsZero(N->getOperand(0), HiMask)) {
      SDLoc dl(N);
      SDValue LHS = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, N->getOperand(0));
      SDValue RHS = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, N->getOperand(1));
      return DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i64,
                         DAG.getNode(ISD::AND, dl, MVT::i32, LHS, RHS));
    }
  }

  // This must be done before legalization has expanded the ctpop.
  if (SDValue V = combineParity(N, DAG, Subtarget))
    return V;

  // Match all-of bool scalar reductions into a bitcast/movmsk + cmp.
  // TODO: Support multiple SrcOps.
  if (VT == MVT::i1) {
    SmallVector<SDValue, 2> SrcOps;
    SmallVector<APInt, 2> SrcPartials;
    if (matchScalarReduction(SDValue(N, 0), ISD::AND, SrcOps, &SrcPartials) &&
        SrcOps.size() == 1) {
      SDLoc dl(N);
      const TargetLowering &TLI = DAG.getTargetLoweringInfo();
      unsigned NumElts = SrcOps[0].getValueType().getVectorNumElements();
      EVT MaskVT = EVT::getIntegerVT(*DAG.getContext(), NumElts);
      SDValue Mask = combineBitcastvxi1(DAG, MaskVT, SrcOps[0], dl, Subtarget);
      if (!Mask && TLI.isTypeLegal(SrcOps[0].getValueType()))
        Mask = DAG.getBitcast(MaskVT, SrcOps[0]);
      if (Mask) {
        assert(SrcPartials[0].getBitWidth() == NumElts &&
               "Unexpected partial reduction mask");
        SDValue PartialBits = DAG.getConstant(SrcPartials[0], dl, MaskVT);
        Mask = DAG.getNode(ISD::AND, dl, MaskVT, Mask, PartialBits);
        return DAG.getSetCC(dl, MVT::i1, Mask, PartialBits, ISD::SETEQ);
      }
    }
  }

  if (SDValue V = combineScalarAndWithMaskSetcc(N, DAG, Subtarget))
    return V;

  if (DCI.isBeforeLegalizeOps())
    return SDValue();

  if (SDValue R = combineCompareEqual(N, DAG, DCI, Subtarget))
    return R;

  if (SDValue FPLogic = convertIntLogicToFPLogic(N, DAG, Subtarget))
    return FPLogic;

  if (SDValue R = combineANDXORWithAllOnesIntoANDNP(N, DAG))
    return R;

  if (SDValue ShiftRight = combineAndMaskToShift(N, DAG, Subtarget))
    return ShiftRight;

  if (SDValue R = combineAndLoadToBZHI(N, DAG, Subtarget))
    return R;

  // Attempt to recursively combine a bitmask AND with shuffles.
  if (VT.isVector() && (VT.getScalarSizeInBits() % 8) == 0) {
    SDValue Op(N, 0);
    if (SDValue Res = combineX86ShufflesRecursively(Op, DAG, Subtarget))
      return Res;
  }

  // Attempt to combine a scalar bitmask AND with an extracted shuffle.
  if ((VT.getScalarSizeInBits() % 8) == 0 &&
      N->getOperand(0).getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
      isa<ConstantSDNode>(N->getOperand(0).getOperand(1))) {
    SDValue BitMask = N->getOperand(1);
    SDValue SrcVec = N->getOperand(0).getOperand(0);
    EVT SrcVecVT = SrcVec.getValueType();

    // Check that the constant bitmask masks whole bytes.
    APInt UndefElts;
    SmallVector<APInt, 64> EltBits;
    if (VT == SrcVecVT.getScalarType() &&
        N->getOperand(0)->isOnlyUserOf(SrcVec.getNode()) &&
        getTargetConstantBitsFromNode(BitMask, 8, UndefElts, EltBits) &&
        llvm::all_of(EltBits, [](APInt M) {
          return M.isNullValue() || M.isAllOnesValue();
        })) {
      unsigned NumElts = SrcVecVT.getVectorNumElements();
      unsigned Scale = SrcVecVT.getScalarSizeInBits() / 8;
      unsigned Idx = N->getOperand(0).getConstantOperandVal(1);

      // Create a root shuffle mask from the byte mask and the extracted index.
      SmallVector<int, 16> ShuffleMask(NumElts * Scale, SM_SentinelUndef);
      for (unsigned i = 0; i != Scale; ++i) {
        if (UndefElts[i])
          continue;
        int VecIdx = Scale * Idx + i;
        ShuffleMask[VecIdx] =
            EltBits[i].isNullValue() ? SM_SentinelZero : VecIdx;
      }

      if (SDValue Shuffle = combineX86ShufflesRecursively(
              {SrcVec}, 0, SrcVec, ShuffleMask, {}, /*Depth*/ 1,
              /*HasVarMask*/ false, /*AllowVarMask*/ true, DAG, Subtarget))
        return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N), VT, Shuffle,
                           N->getOperand(0).getOperand(1));
    }
  }

  return SDValue();
}

// Canonicalize OR(AND(X,C),AND(Y,~C)) -> OR(AND(X,C),ANDNP(C,Y))
static SDValue canonicalizeBitSelect(SDNode *N, SelectionDAG &DAG,
                                     const X86Subtarget &Subtarget) {
  assert(N->getOpcode() == ISD::OR && "Unexpected Opcode");

  MVT VT = N->getSimpleValueType(0);
  if (!VT.isVector() || (VT.getScalarSizeInBits() % 8) != 0)
    return SDValue();

  SDValue N0 = peekThroughBitcasts(N->getOperand(0));
  SDValue N1 = peekThroughBitcasts(N->getOperand(1));
  if (N0.getOpcode() != ISD::AND || N1.getOpcode() != ISD::AND)
    return SDValue();

  // On XOP we'll lower to PCMOV so accept one use. With AVX512, we can use
  // VPTERNLOG. Otherwise only do this if either mask has multiple uses already.
  bool UseVPTERNLOG = (Subtarget.hasAVX512() && VT.is512BitVector()) ||
                      Subtarget.hasVLX();
  if (!(Subtarget.hasXOP() || UseVPTERNLOG ||
        !N0.getOperand(1).hasOneUse() || !N1.getOperand(1).hasOneUse()))
    return SDValue();

  // Attempt to extract constant byte masks.
  APInt UndefElts0, UndefElts1;
  SmallVector<APInt, 32> EltBits0, EltBits1;
  if (!getTargetConstantBitsFromNode(N0.getOperand(1), 8, UndefElts0, EltBits0,
                                     false, false))
    return SDValue();
  if (!getTargetConstantBitsFromNode(N1.getOperand(1), 8, UndefElts1, EltBits1,
                                     false, false))
    return SDValue();

  for (unsigned i = 0, e = EltBits0.size(); i != e; ++i) {
    // TODO - add UNDEF elts support.
    if (UndefElts0[i] || UndefElts1[i])
      return SDValue();
    if (EltBits0[i] != ~EltBits1[i])
      return SDValue();
  }

  SDLoc DL(N);
  SDValue X = N->getOperand(0);
  SDValue Y =
      DAG.getNode(X86ISD::ANDNP, DL, VT, DAG.getBitcast(VT, N0.getOperand(1)),
                  DAG.getBitcast(VT, N1.getOperand(0)));
  return DAG.getNode(ISD::OR, DL, VT, X, Y);
}

// Try to match OR(AND(~MASK,X),AND(MASK,Y)) logic pattern.
static bool matchLogicBlend(SDNode *N, SDValue &X, SDValue &Y, SDValue &Mask) {
  if (N->getOpcode() != ISD::OR)
    return false;

  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);

  // Canonicalize AND to LHS.
  if (N1.getOpcode() == ISD::AND)
    std::swap(N0, N1);

  // Attempt to match OR(AND(M,Y),ANDNP(M,X)).
  if (N0.getOpcode() != ISD::AND || N1.getOpcode() != X86ISD::ANDNP)
    return false;

  Mask = N1.getOperand(0);
  X = N1.getOperand(1);

  // Check to see if the mask appeared in both the AND and ANDNP.
  if (N0.getOperand(0) == Mask)
    Y = N0.getOperand(1);
  else if (N0.getOperand(1) == Mask)
    Y = N0.getOperand(0);
  else
    return false;

  // TODO: Attempt to match against AND(XOR(-1,M),Y) as well, waiting for
  // ANDNP combine allows other combines to happen that prevent matching.
  return true;
}

// Try to fold:
//   (or (and (m, y), (pandn m, x)))
// into:
//   (vselect m, x, y)
// As a special case, try to fold:
//   (or (and (m, (sub 0, x)), (pandn m, x)))
// into:
//   (sub (xor X, M), M)
static SDValue combineLogicBlendIntoPBLENDV(SDNode *N, SelectionDAG &DAG,
                                            const X86Subtarget &Subtarget) {
  assert(N->getOpcode() == ISD::OR && "Unexpected Opcode");

  EVT VT = N->getValueType(0);
  if (!((VT.is128BitVector() && Subtarget.hasSSE2()) ||
        (VT.is256BitVector() && Subtarget.hasInt256())))
    return SDValue();

  SDValue X, Y, Mask;
  if (!matchLogicBlend(N, X, Y, Mask))
    return SDValue();

  // Validate that X, Y, and Mask are bitcasts, and see through them.
  Mask = peekThroughBitcasts(Mask);
  X = peekThroughBitcasts(X);
  Y = peekThroughBitcasts(Y);

  EVT MaskVT = Mask.getValueType();
  unsigned EltBits = MaskVT.getScalarSizeInBits();

  // TODO: Attempt to handle floating point cases as well?
  if (!MaskVT.isInteger() || DAG.ComputeNumSignBits(Mask) != EltBits)
    return SDValue();

  SDLoc DL(N);

  // Attempt to combine to conditional negate: (sub (xor X, M), M)
  if (SDValue Res = combineLogicBlendIntoConditionalNegate(VT, Mask, X, Y, DL,
                                                           DAG, Subtarget))
    return Res;

  // PBLENDVB is only available on SSE 4.1.
  if (!Subtarget.hasSSE41())
    return SDValue();

  MVT BlendVT = VT.is256BitVector() ? MVT::v32i8 : MVT::v16i8;

  X = DAG.getBitcast(BlendVT, X);
  Y = DAG.getBitcast(BlendVT, Y);
  Mask = DAG.getBitcast(BlendVT, Mask);
  Mask = DAG.getSelect(DL, BlendVT, Mask, Y, X);
  return DAG.getBitcast(VT, Mask);
}

// Helper function for combineOrCmpEqZeroToCtlzSrl
// Transforms:
//   seteq(cmp x, 0)
//   into:
//   srl(ctlz x), log2(bitsize(x))
// Input pattern is checked by caller.
static SDValue lowerX86CmpEqZeroToCtlzSrl(SDValue Op, EVT ExtTy,
                                          SelectionDAG &DAG) {
  SDValue Cmp = Op.getOperand(1);
  EVT VT = Cmp.getOperand(0).getValueType();
  unsigned Log2b = Log2_32(VT.getSizeInBits());
  SDLoc dl(Op);
  SDValue Clz = DAG.getNode(ISD::CTLZ, dl, VT, Cmp->getOperand(0));
  // The result of the shift is true or false, and on X86, the 32-bit
  // encoding of shr and lzcnt is more desirable.
  SDValue Trunc = DAG.getZExtOrTrunc(Clz, dl, MVT::i32);
  SDValue Scc = DAG.getNode(ISD::SRL, dl, MVT::i32, Trunc,
                            DAG.getConstant(Log2b, dl, MVT::i8));
  return DAG.getZExtOrTrunc(Scc, dl, ExtTy);
}

// Try to transform:
//   zext(or(setcc(eq, (cmp x, 0)), setcc(eq, (cmp y, 0))))
//   into:
//   srl(or(ctlz(x), ctlz(y)), log2(bitsize(x))
// Will also attempt to match more generic cases, eg:
//   zext(or(or(setcc(eq, cmp 0), setcc(eq, cmp 0)), setcc(eq, cmp 0)))
// Only applies if the target supports the FastLZCNT feature.
static SDValue combineOrCmpEqZeroToCtlzSrl(SDNode *N, SelectionDAG &DAG,
                                           TargetLowering::DAGCombinerInfo &DCI,
                                           const X86Subtarget &Subtarget) {
  if (DCI.isBeforeLegalize() || !Subtarget.getTargetLowering()->isCtlzFast())
    return SDValue();

  auto isORCandidate = [](SDValue N) {
    return (N->getOpcode() == ISD::OR && N->hasOneUse());
  };

  // Check the zero extend is extending to 32-bit or more. The code generated by
  // srl(ctlz) for 16-bit or less variants of the pattern would require extra
  // instructions to clear the upper bits.
  if (!N->hasOneUse() || !N->getSimpleValueType(0).bitsGE(MVT::i32) ||
      !isORCandidate(N->getOperand(0)))
    return SDValue();

  // Check the node matches: setcc(eq, cmp 0)
  auto isSetCCCandidate = [](SDValue N) {
    return N->getOpcode() == X86ISD::SETCC && N->hasOneUse() &&
           X86::CondCode(N->getConstantOperandVal(0)) == X86::COND_E &&
           N->getOperand(1).getOpcode() == X86ISD::CMP &&
           isNullConstant(N->getOperand(1).getOperand(1)) &&
           N->getOperand(1).getValueType().bitsGE(MVT::i32);
  };

  SDNode *OR = N->getOperand(0).getNode();
  SDValue LHS = OR->getOperand(0);
  SDValue RHS = OR->getOperand(1);

  // Save nodes matching or(or, setcc(eq, cmp 0)).
  SmallVector<SDNode *, 2> ORNodes;
  while (((isORCandidate(LHS) && isSetCCCandidate(RHS)) ||
          (isORCandidate(RHS) && isSetCCCandidate(LHS)))) {
    ORNodes.push_back(OR);
    OR = (LHS->getOpcode() == ISD::OR) ? LHS.getNode() : RHS.getNode();
    LHS = OR->getOperand(0);
    RHS = OR->getOperand(1);
  }

  // The last OR node should match or(setcc(eq, cmp 0), setcc(eq, cmp 0)).
  if (!(isSetCCCandidate(LHS) && isSetCCCandidate(RHS)) ||
      !isORCandidate(SDValue(OR, 0)))
    return SDValue();

  // We have a or(setcc(eq, cmp 0), setcc(eq, cmp 0)) pattern, try to lower it
  // to
  // or(srl(ctlz),srl(ctlz)).
  // The dag combiner can then fold it into:
  // srl(or(ctlz, ctlz)).
  EVT VT = OR->getValueType(0);
  SDValue NewLHS = lowerX86CmpEqZeroToCtlzSrl(LHS, VT, DAG);
  SDValue Ret, NewRHS;
  if (NewLHS && (NewRHS = lowerX86CmpEqZeroToCtlzSrl(RHS, VT, DAG)))
    Ret = DAG.getNode(ISD::OR, SDLoc(OR), VT, NewLHS, NewRHS);

  if (!Ret)
    return SDValue();

  // Try to lower nodes matching the or(or, setcc(eq, cmp 0)) pattern.
  while (ORNodes.size() > 0) {
    OR = ORNodes.pop_back_val();
    LHS = OR->getOperand(0);
    RHS = OR->getOperand(1);
    // Swap rhs with lhs to match or(setcc(eq, cmp, 0), or).
    if (RHS->getOpcode() == ISD::OR)
      std::swap(LHS, RHS);
    NewRHS = lowerX86CmpEqZeroToCtlzSrl(RHS, VT, DAG);
    if (!NewRHS)
      return SDValue();
    Ret = DAG.getNode(ISD::OR, SDLoc(OR), VT, Ret, NewRHS);
  }

  if (Ret)
    Ret = DAG.getNode(ISD::ZERO_EXTEND, SDLoc(N), N->getValueType(0), Ret);

  return Ret;
}

static SDValue combineOrShiftToFunnelShift(SDNode *N, SelectionDAG &DAG,
                                           const X86Subtarget &Subtarget) {
  assert(N->getOpcode() == ISD::OR && "Expected ISD::OR node");
  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);
  EVT VT = N->getValueType(0);
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();

  if (!TLI.isOperationLegalOrCustom(ISD::FSHL, VT) ||
      !TLI.isOperationLegalOrCustom(ISD::FSHR, VT))
    return SDValue();

  // fold (or (x << c) | (y >> (64 - c))) ==> (shld64 x, y, c)
  bool OptForSize = DAG.shouldOptForSize();
  unsigned Bits = VT.getScalarSizeInBits();

  // SHLD/SHRD instructions have lower register pressure, but on some
  // platforms they have higher latency than the equivalent
  // series of shifts/or that would otherwise be generated.
  // Don't fold (or (x << c) | (y >> (64 - c))) if SHLD/SHRD instructions
  // have higher latencies and we are not optimizing for size.
  if (!OptForSize && Subtarget.isSHLDSlow())
    return SDValue();

  if (N0.getOpcode() == ISD::SRL && N1.getOpcode() == ISD::SHL)
    std::swap(N0, N1);
  if (N0.getOpcode() != ISD::SHL || N1.getOpcode() != ISD::SRL)
    return SDValue();
  if (!N0.hasOneUse() || !N1.hasOneUse())
    return SDValue();

  EVT ShiftVT = TLI.getShiftAmountTy(VT, DAG.getDataLayout());

  SDValue ShAmt0 = N0.getOperand(1);
  if (ShAmt0.getValueType() != ShiftVT)
    return SDValue();
  SDValue ShAmt1 = N1.getOperand(1);
  if (ShAmt1.getValueType() != ShiftVT)
    return SDValue();

  // Peek through any modulo shift masks.
  SDValue ShMsk0;
  if (ShAmt0.getOpcode() == ISD::AND &&
      isa<ConstantSDNode>(ShAmt0.getOperand(1)) &&
      ShAmt0.getConstantOperandAPInt(1) == (Bits - 1)) {
    ShMsk0 = ShAmt0;
    ShAmt0 = ShAmt0.getOperand(0);
  }
  SDValue ShMsk1;
  if (ShAmt1.getOpcode() == ISD::AND &&
      isa<ConstantSDNode>(ShAmt1.getOperand(1)) &&
      ShAmt1.getConstantOperandAPInt(1) == (Bits - 1)) {
    ShMsk1 = ShAmt1;
    ShAmt1 = ShAmt1.getOperand(0);
  }

  if (ShAmt0.getOpcode() == ISD::TRUNCATE)
    ShAmt0 = ShAmt0.getOperand(0);
  if (ShAmt1.getOpcode() == ISD::TRUNCATE)
    ShAmt1 = ShAmt1.getOperand(0);

  SDLoc DL(N);
  unsigned Opc = ISD::FSHL;
  SDValue Op0 = N0.getOperand(0);
  SDValue Op1 = N1.getOperand(0);
  if (ShAmt0.getOpcode() == ISD::SUB || ShAmt0.getOpcode() == ISD::XOR) {
    Opc = ISD::FSHR;
    std::swap(Op0, Op1);
    std::swap(ShAmt0, ShAmt1);
    std::swap(ShMsk0, ShMsk1);
  }

  auto GetFunnelShift = [&DAG, &DL, VT, Opc, &ShiftVT](SDValue Op0, SDValue Op1,
                                                       SDValue Amt) {
    if (Opc == ISD::FSHR)
      std::swap(Op0, Op1);
    return DAG.getNode(Opc, DL, VT, Op0, Op1,
                       DAG.getNode(ISD::TRUNCATE, DL, ShiftVT, Amt));
  };

  // OR( SHL( X, C ), SRL( SRL( Y, 1 ), XOR( C, 31 ) ) ) -> FSHL( X, Y, C )
  // OR( SRL( X, C ), SHL( SHL( Y, 1 ), XOR( C, 31 ) ) ) -> FSHR( Y, X, C )
  if (ShAmt1.getOpcode() == ISD::XOR) {
    SDValue Mask = ShAmt1.getOperand(1);
    if (auto *MaskC = dyn_cast<ConstantSDNode>(Mask)) {
      unsigned InnerShift = (ISD::FSHL == Opc ? ISD::SRL : ISD::SHL);
      SDValue ShAmt1Op0 = ShAmt1.getOperand(0);
      if (ShAmt1Op0.getOpcode() == ISD::TRUNCATE)
        ShAmt1Op0 = ShAmt1Op0.getOperand(0);
      if (MaskC->getSExtValue() == (Bits - 1) &&
          (ShAmt1Op0 == ShAmt0 || ShAmt1Op0 == ShMsk0)) {
        if (Op1.getOpcode() == InnerShift &&
            isa<ConstantSDNode>(Op1.getOperand(1)) &&
            Op1.getConstantOperandAPInt(1).isOneValue()) {
          return GetFunnelShift(Op0, Op1.getOperand(0), ShAmt0);
        }
        // Test for ADD( Y, Y ) as an equivalent to SHL( Y, 1 ).
        if (InnerShift == ISD::SHL && Op1.getOpcode() == ISD::ADD &&
            Op1.getOperand(0) == Op1.getOperand(1)) {
          return GetFunnelShift(Op0, Op1.getOperand(0), ShAmt0);
        }
      }
    }
  }

  return SDValue();
}

static SDValue combineOr(SDNode *N, SelectionDAG &DAG,
                         TargetLowering::DAGCombinerInfo &DCI,
                         const X86Subtarget &Subtarget) {
  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);
  EVT VT = N->getValueType(0);

  // If this is SSE1 only convert to FOR to avoid scalarization.
  if (Subtarget.hasSSE1() && !Subtarget.hasSSE2() && VT == MVT::v4i32) {
    return DAG.getBitcast(MVT::v4i32,
                          DAG.getNode(X86ISD::FOR, SDLoc(N), MVT::v4f32,
                                      DAG.getBitcast(MVT::v4f32, N0),
                                      DAG.getBitcast(MVT::v4f32, N1)));
  }

  // Match any-of bool scalar reductions into a bitcast/movmsk + cmp.
  // TODO: Support multiple SrcOps.
  if (VT == MVT::i1) {
    SmallVector<SDValue, 2> SrcOps;
    SmallVector<APInt, 2> SrcPartials;
    if (matchScalarReduction(SDValue(N, 0), ISD::OR, SrcOps, &SrcPartials) &&
        SrcOps.size() == 1) {
      SDLoc dl(N);
      const TargetLowering &TLI = DAG.getTargetLoweringInfo();
      unsigned NumElts = SrcOps[0].getValueType().getVectorNumElements();
      EVT MaskVT = EVT::getIntegerVT(*DAG.getContext(), NumElts);
      SDValue Mask = combineBitcastvxi1(DAG, MaskVT, SrcOps[0], dl, Subtarget);
      if (!Mask && TLI.isTypeLegal(SrcOps[0].getValueType()))
        Mask = DAG.getBitcast(MaskVT, SrcOps[0]);
      if (Mask) {
        assert(SrcPartials[0].getBitWidth() == NumElts &&
               "Unexpected partial reduction mask");
        SDValue ZeroBits = DAG.getConstant(0, dl, MaskVT);
        SDValue PartialBits = DAG.getConstant(SrcPartials[0], dl, MaskVT);
        Mask = DAG.getNode(ISD::AND, dl, MaskVT, Mask, PartialBits);
        return DAG.getSetCC(dl, MVT::i1, Mask, ZeroBits, ISD::SETNE);
      }
    }
  }

  if (DCI.isBeforeLegalizeOps())
    return SDValue();

  if (SDValue R = combineCompareEqual(N, DAG, DCI, Subtarget))
    return R;

  if (SDValue FPLogic = convertIntLogicToFPLogic(N, DAG, Subtarget))
    return FPLogic;

  if (SDValue R = canonicalizeBitSelect(N, DAG, Subtarget))
    return R;

  if (SDValue R = combineLogicBlendIntoPBLENDV(N, DAG, Subtarget))
    return R;

  if (SDValue R = combineOrShiftToFunnelShift(N, DAG, Subtarget))
    return R;

  // Attempt to recursively combine an OR of shuffles.
  if (VT.isVector() && (VT.getScalarSizeInBits() % 8) == 0) {
    SDValue Op(N, 0);
    if (SDValue Res = combineX86ShufflesRecursively(Op, DAG, Subtarget))
      return Res;
  }

  return SDValue();
}

/// Try to turn tests against the signbit in the form of:
///   XOR(TRUNCATE(SRL(X, size(X)-1)), 1)
/// into:
///   SETGT(X, -1)
static SDValue foldXorTruncShiftIntoCmp(SDNode *N, SelectionDAG &DAG) {
  // This is only worth doing if the output type is i8 or i1.
  EVT ResultType = N->getValueType(0);
  if (ResultType != MVT::i8 && ResultType != MVT::i1)
    return SDValue();

  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);

  // We should be performing an xor against a truncated shift.
  if (N0.getOpcode() != ISD::TRUNCATE || !N0.hasOneUse())
    return SDValue();

  // Make sure we are performing an xor against one.
  if (!isOneConstant(N1))
    return SDValue();

  // SetCC on x86 zero extends so only act on this if it's a logical shift.
  SDValue Shift = N0.getOperand(0);
  if (Shift.getOpcode() != ISD::SRL || !Shift.hasOneUse())
    return SDValue();

  // Make sure we are truncating from one of i16, i32 or i64.
  EVT ShiftTy = Shift.getValueType();
  if (ShiftTy != MVT::i16 && ShiftTy != MVT::i32 && ShiftTy != MVT::i64)
    return SDValue();

  // Make sure the shift amount extracts the sign bit.
  if (!isa<ConstantSDNode>(Shift.getOperand(1)) ||
      Shift.getConstantOperandAPInt(1) != (ShiftTy.getSizeInBits() - 1))
    return SDValue();

  // Create a greater-than comparison against -1.
  // N.B. Using SETGE against 0 works but we want a canonical looking
  // comparison, using SETGT matches up with what TranslateX86CC.
  SDLoc DL(N);
  SDValue ShiftOp = Shift.getOperand(0);
  EVT ShiftOpTy = ShiftOp.getValueType();
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  EVT SetCCResultType = TLI.getSetCCResultType(DAG.getDataLayout(),
                                               *DAG.getContext(), ResultType);
  SDValue Cond = DAG.getSetCC(DL, SetCCResultType, ShiftOp,
                              DAG.getConstant(-1, DL, ShiftOpTy), ISD::SETGT);
  if (SetCCResultType != ResultType)
    Cond = DAG.getNode(ISD::ZERO_EXTEND, DL, ResultType, Cond);
  return Cond;
}

/// Turn vector tests of the signbit in the form of:
///   xor (sra X, elt_size(X)-1), -1
/// into:
///   pcmpgt X, -1
///
/// This should be called before type legalization because the pattern may not
/// persist after that.
static SDValue foldVectorXorShiftIntoCmp(SDNode *N, SelectionDAG &DAG,
                                         const X86Subtarget &Subtarget) {
  EVT VT = N->getValueType(0);
  if (!VT.isSimple())
    return SDValue();

  switch (VT.getSimpleVT().SimpleTy) {
  default: return SDValue();
  case MVT::v16i8:
  case MVT::v8i16:
  case MVT::v4i32:
  case MVT::v2i64: if (!Subtarget.hasSSE2()) return SDValue(); break;
  case MVT::v32i8:
  case MVT::v16i16:
  case MVT::v8i32:
  case MVT::v4i64: if (!Subtarget.hasAVX2()) return SDValue(); break;
  }

  // There must be a shift right algebraic before the xor, and the xor must be a
  // 'not' operation.
  SDValue Shift = N->getOperand(0);
  SDValue Ones = N->getOperand(1);
  if (Shift.getOpcode() != ISD::SRA || !Shift.hasOneUse() ||
      !ISD::isBuildVectorAllOnes(Ones.getNode()))
    return SDValue();

  // The shift should be smearing the sign bit across each vector element.
  auto *ShiftAmt =
      isConstOrConstSplat(Shift.getOperand(1), /*AllowUndefs*/ true);
  if (!ShiftAmt ||
      ShiftAmt->getAPIntValue() != (Shift.getScalarValueSizeInBits() - 1))
    return SDValue();

  // Create a greater-than comparison against -1. We don't use the more obvious
  // greater-than-or-equal-to-zero because SSE/AVX don't have that instruction.
  return DAG.getSetCC(SDLoc(N), VT, Shift.getOperand(0), Ones, ISD::SETGT);
}

/// Detect patterns of truncation with unsigned saturation:
///
/// 1. (truncate (umin (x, unsigned_max_of_dest_type)) to dest_type).
///   Return the source value x to be truncated or SDValue() if the pattern was
///   not matched.
///
/// 2. (truncate (smin (smax (x, C1), C2)) to dest_type),
///   where C1 >= 0 and C2 is unsigned max of destination type.
///
///    (truncate (smax (smin (x, C2), C1)) to dest_type)
///   where C1 >= 0, C2 is unsigned max of destination type and C1 <= C2.
///
///   These two patterns are equivalent to:
///   (truncate (umin (smax(x, C1), unsigned_max_of_dest_type)) to dest_type)
///   So return the smax(x, C1) value to be truncated or SDValue() if the
///   pattern was not matched.
static SDValue detectUSatPattern(SDValue In, EVT VT, SelectionDAG &DAG,
                                 const SDLoc &DL) {
  EVT InVT = In.getValueType();

  // Saturation with truncation. We truncate from InVT to VT.
  assert(InVT.getScalarSizeInBits() > VT.getScalarSizeInBits() &&
         "Unexpected types for truncate operation");

  // Match min/max and return limit value as a parameter.
  auto MatchMinMax = [](SDValue V, unsigned Opcode, APInt &Limit) -> SDValue {
    if (V.getOpcode() == Opcode &&
        ISD::isConstantSplatVector(V.getOperand(1).getNode(), Limit))
      return V.getOperand(0);
    return SDValue();
  };

  APInt C1, C2;
  if (SDValue UMin = MatchMinMax(In, ISD::UMIN, C2))
    // C2 should be equal to UINT32_MAX / UINT16_MAX / UINT8_MAX according
    // the element size of the destination type.
    if (C2.isMask(VT.getScalarSizeInBits()))
      return UMin;

  if (SDValue SMin = MatchMinMax(In, ISD::SMIN, C2))
    if (MatchMinMax(SMin, ISD::SMAX, C1))
      if (C1.isNonNegative() && C2.isMask(VT.getScalarSizeInBits()))
        return SMin;

  if (SDValue SMax = MatchMinMax(In, ISD::SMAX, C1))
    if (SDValue SMin = MatchMinMax(SMax, ISD::SMIN, C2))
      if (C1.isNonNegative() && C2.isMask(VT.getScalarSizeInBits()) &&
          C2.uge(C1)) {
        return DAG.getNode(ISD::SMAX, DL, InVT, SMin, In.getOperand(1));
      }

  return SDValue();
}

/// Detect patterns of truncation with signed saturation:
/// (truncate (smin ((smax (x, signed_min_of_dest_type)),
///                  signed_max_of_dest_type)) to dest_type)
/// or:
/// (truncate (smax ((smin (x, signed_max_of_dest_type)),
///                  signed_min_of_dest_type)) to dest_type).
/// With MatchPackUS, the smax/smin range is [0, unsigned_max_of_dest_type].
/// Return the source value to be truncated or SDValue() if the pattern was not
/// matched.
static SDValue detectSSatPattern(SDValue In, EVT VT, bool MatchPackUS = false) {
  unsigned NumDstBits = VT.getScalarSizeInBits();
  unsigned NumSrcBits = In.getScalarValueSizeInBits();
  assert(NumSrcBits > NumDstBits && "Unexpected types for truncate operation");

  auto MatchMinMax = [](SDValue V, unsigned Opcode,
                        const APInt &Limit) -> SDValue {
    APInt C;
    if (V.getOpcode() == Opcode &&
        ISD::isConstantSplatVector(V.getOperand(1).getNode(), C) && C == Limit)
      return V.getOperand(0);
    return SDValue();
  };

  APInt SignedMax, SignedMin;
  if (MatchPackUS) {
    SignedMax = APInt::getAllOnesValue(NumDstBits).zext(NumSrcBits);
    SignedMin = APInt(NumSrcBits, 0);
  } else {
    SignedMax = APInt::getSignedMaxValue(NumDstBits).sext(NumSrcBits);
    SignedMin = APInt::getSignedMinValue(NumDstBits).sext(NumSrcBits);
  }

  if (SDValue SMin = MatchMinMax(In, ISD::SMIN, SignedMax))
    if (SDValue SMax = MatchMinMax(SMin, ISD::SMAX, SignedMin))
      return SMax;

  if (SDValue SMax = MatchMinMax(In, ISD::SMAX, SignedMin))
    if (SDValue SMin = MatchMinMax(SMax, ISD::SMIN, SignedMax))
      return SMin;

  return SDValue();
}

static SDValue combineTruncateWithSat(SDValue In, EVT VT, const SDLoc &DL,
                                      SelectionDAG &DAG,
                                      const X86Subtarget &Subtarget) {
  if (!Subtarget.hasSSE2() || !VT.isVector())
    return SDValue();

  EVT SVT = VT.getVectorElementType();
  EVT InVT = In.getValueType();
  EVT InSVT = InVT.getVectorElementType();

  // If we're clamping a signed 32-bit vector to 0-255 and the 32-bit vector is
  // split across two registers. We can use a packusdw+perm to clamp to 0-65535
  // and concatenate at the same time. Then we can use a final vpmovuswb to
  // clip to 0-255.
  if (Subtarget.hasBWI() && !Subtarget.useAVX512Regs() &&
      InVT == MVT::v16i32 && VT == MVT::v16i8) {
    if (auto USatVal = detectSSatPattern(In, VT, true)) {
      // Emit a VPACKUSDW+VPERMQ followed by a VPMOVUSWB.
      SDValue Mid = truncateVectorWithPACK(X86ISD::PACKUS, MVT::v16i16, USatVal,
                                           DL, DAG, Subtarget);
      assert(Mid && "Failed to pack!");
      return DAG.getNode(X86ISD::VTRUNCUS, DL, VT, Mid);
    }
  }

  // vXi32 truncate instructions are available with AVX512F.
  // vXi16 truncate instructions are only available with AVX512BW.
  // For 256-bit or smaller vectors, we require VLX.
  // FIXME: We could widen truncates to 512 to remove the VLX restriction.
  // If the result type is 256-bits or larger and we have disable 512-bit
  // registers, we should go ahead and use the pack instructions if possible.
  bool PreferAVX512 = ((Subtarget.hasAVX512() && InSVT == MVT::i32) ||
                       (Subtarget.hasBWI() && InSVT == MVT::i16)) &&
                      (InVT.getSizeInBits() > 128) &&
                      (Subtarget.hasVLX() || InVT.getSizeInBits() > 256) &&
                      !(!Subtarget.useAVX512Regs() && VT.getSizeInBits() >= 256);

  if (isPowerOf2_32(VT.getVectorNumElements()) && !PreferAVX512 &&
      VT.getSizeInBits() >= 64 &&
      (SVT == MVT::i8 || SVT == MVT::i16) &&
      (InSVT == MVT::i16 || InSVT == MVT::i32)) {
    if (auto USatVal = detectSSatPattern(In, VT, true)) {
      // vXi32 -> vXi8 must be performed as PACKUSWB(PACKSSDW,PACKSSDW).
      // Only do this when the result is at least 64 bits or we'll leaving
      // dangling PACKSSDW nodes.
      if (SVT == MVT::i8 && InSVT == MVT::i32) {
        EVT MidVT = EVT::getVectorVT(*DAG.getContext(), MVT::i16,
                                     VT.getVectorNumElements());
        SDValue Mid = truncateVectorWithPACK(X86ISD::PACKSS, MidVT, USatVal, DL,
                                             DAG, Subtarget);
        assert(Mid && "Failed to pack!");
        SDValue V = truncateVectorWithPACK(X86ISD::PACKUS, VT, Mid, DL, DAG,
                                           Subtarget);
        assert(V && "Failed to pack!");
        return V;
      } else if (SVT == MVT::i8 || Subtarget.hasSSE41())
        return truncateVectorWithPACK(X86ISD::PACKUS, VT, USatVal, DL, DAG,
                                      Subtarget);
    }
    if (auto SSatVal = detectSSatPattern(In, VT))
      return truncateVectorWithPACK(X86ISD::PACKSS, VT, SSatVal, DL, DAG,
                                    Subtarget);
  }

  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  if (TLI.isTypeLegal(InVT) && InVT.isVector() && SVT != MVT::i1 &&
      Subtarget.hasAVX512() && (InSVT != MVT::i16 || Subtarget.hasBWI())) {
    unsigned TruncOpc = 0;
    SDValue SatVal;
    if (auto SSatVal = detectSSatPattern(In, VT)) {
      SatVal = SSatVal;
      TruncOpc = X86ISD::VTRUNCS;
    } else if (auto USatVal = detectUSatPattern(In, VT, DAG, DL)) {
      SatVal = USatVal;
      TruncOpc = X86ISD::VTRUNCUS;
    }
    if (SatVal) {
      unsigned ResElts = VT.getVectorNumElements();
      // If the input type is less than 512 bits and we don't have VLX, we need
      // to widen to 512 bits.
      if (!Subtarget.hasVLX() && !InVT.is512BitVector()) {
        unsigned NumConcats = 512 / InVT.getSizeInBits();
        ResElts *= NumConcats;
        SmallVector<SDValue, 4> ConcatOps(NumConcats, DAG.getUNDEF(InVT));
        ConcatOps[0] = SatVal;
        InVT = EVT::getVectorVT(*DAG.getContext(), InSVT,
                                NumConcats * InVT.getVectorNumElements());
        SatVal = DAG.getNode(ISD::CONCAT_VECTORS, DL, InVT, ConcatOps);
      }
      // Widen the result if its narrower than 128 bits.
      if (ResElts * SVT.getSizeInBits() < 128)
        ResElts = 128 / SVT.getSizeInBits();
      EVT TruncVT = EVT::getVectorVT(*DAG.getContext(), SVT, ResElts);
      SDValue Res = DAG.getNode(TruncOpc, DL, TruncVT, SatVal);
      return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, VT, Res,
                         DAG.getIntPtrConstant(0, DL));
    }
  }

  return SDValue();
}

/// This function detects the AVG pattern between vectors of unsigned i8/i16,
/// which is c = (a + b + 1) / 2, and replace this operation with the efficient
/// X86ISD::AVG instruction.
static SDValue detectAVGPattern(SDValue In, EVT VT, SelectionDAG &DAG,
                                const X86Subtarget &Subtarget,
                                const SDLoc &DL) {
  if (!VT.isVector())
    return SDValue();
  EVT InVT = In.getValueType();
  unsigned NumElems = VT.getVectorNumElements();

  EVT ScalarVT = VT.getVectorElementType();
  if (!((ScalarVT == MVT::i8 || ScalarVT == MVT::i16) &&
        NumElems >= 2 && isPowerOf2_32(NumElems)))
    return SDValue();

  // InScalarVT is the intermediate type in AVG pattern and it should be greater
  // than the original input type (i8/i16).
  EVT InScalarVT = InVT.getVectorElementType();
  if (InScalarVT.getSizeInBits() <= ScalarVT.getSizeInBits())
    return SDValue();

  if (!Subtarget.hasSSE2())
    return SDValue();

  // Detect the following pattern:
  //
  //   %1 = zext <N x i8> %a to <N x i32>
  //   %2 = zext <N x i8> %b to <N x i32>
  //   %3 = add nuw nsw <N x i32> %1, <i32 1 x N>
  //   %4 = add nuw nsw <N x i32> %3, %2
  //   %5 = lshr <N x i32> %N, <i32 1 x N>
  //   %6 = trunc <N x i32> %5 to <N x i8>
  //
  // In AVX512, the last instruction can also be a trunc store.
  if (In.getOpcode() != ISD::SRL)
    return SDValue();

  // A lambda checking the given SDValue is a constant vector and each element
  // is in the range [Min, Max].
  auto IsConstVectorInRange = [](SDValue V, unsigned Min, unsigned Max) {
    BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(V);
    if (!BV || !BV->isConstant())
      return false;
    for (SDValue Op : V->ops()) {
      ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
      if (!C)
        return false;
      const APInt &Val = C->getAPIntValue();
      if (Val.ult(Min) || Val.ugt(Max))
        return false;
    }
    return true;
  };

  // Check if each element of the vector is right-shifted by one.
  auto LHS = In.getOperand(0);
  auto RHS = In.getOperand(1);
  if (!IsConstVectorInRange(RHS, 1, 1))
    return SDValue();
  if (LHS.getOpcode() != ISD::ADD)
    return SDValue();

  // Detect a pattern of a + b + 1 where the order doesn't matter.
  SDValue Operands[3];
  Operands[0] = LHS.getOperand(0);
  Operands[1] = LHS.getOperand(1);

  auto AVGBuilder = [](SelectionDAG &DAG, const SDLoc &DL,
                       ArrayRef<SDValue> Ops) {
    return DAG.getNode(X86ISD::AVG, DL, Ops[0].getValueType(), Ops);
  };

  // Take care of the case when one of the operands is a constant vector whose
  // element is in the range [1, 256].
  if (IsConstVectorInRange(Operands[1], 1, ScalarVT == MVT::i8 ? 256 : 65536) &&
      Operands[0].getOpcode() == ISD::ZERO_EXTEND &&
      Operands[0].getOperand(0).getValueType() == VT) {
    // The pattern is detected. Subtract one from the constant vector, then
    // demote it and emit X86ISD::AVG instruction.
    SDValue VecOnes = DAG.getConstant(1, DL, InVT);
    Operands[1] = DAG.getNode(ISD::SUB, DL, InVT, Operands[1], VecOnes);
    Operands[1] = DAG.getNode(ISD::TRUNCATE, DL, VT, Operands[1]);
    return SplitOpsAndApply(DAG, Subtarget, DL, VT,
                            { Operands[0].getOperand(0), Operands[1] },
                            AVGBuilder);
  }

  // Matches 'add like' patterns: add(Op0,Op1) + zext(or(Op0,Op1)).
  // Match the or case only if its 'add-like' - can be replaced by an add.
  auto FindAddLike = [&](SDValue V, SDValue &Op0, SDValue &Op1) {
    if (ISD::ADD == V.getOpcode()) {
      Op0 = V.getOperand(0);
      Op1 = V.getOperand(1);
      return true;
    }
    if (ISD::ZERO_EXTEND != V.getOpcode())
      return false;
    V = V.getOperand(0);
    if (V.getValueType() != VT || ISD::OR != V.getOpcode() ||
        !DAG.haveNoCommonBitsSet(V.getOperand(0), V.getOperand(1)))
      return false;
    Op0 = V.getOperand(0);
    Op1 = V.getOperand(1);
    return true;
  };

  SDValue Op0, Op1;
  if (FindAddLike(Operands[0], Op0, Op1))
    std::swap(Operands[0], Operands[1]);
  else if (!FindAddLike(Operands[1], Op0, Op1))
    return SDValue();
  Operands[2] = Op0;
  Operands[1] = Op1;

  // Now we have three operands of two additions. Check that one of them is a
  // constant vector with ones, and the other two can be promoted from i8/i16.
  for (int i = 0; i < 3; ++i) {
    if (!IsConstVectorInRange(Operands[i], 1, 1))
      continue;
    std::swap(Operands[i], Operands[2]);

    // Check if Operands[0] and Operands[1] are results of type promotion.
    for (int j = 0; j < 2; ++j)
      if (Operands[j].getValueType() != VT) {
        if (Operands[j].getOpcode() != ISD::ZERO_EXTEND ||
            Operands[j].getOperand(0).getValueType() != VT)
          return SDValue();
        Operands[j] = Operands[j].getOperand(0);
      }

    // The pattern is detected, emit X86ISD::AVG instruction(s).
    return SplitOpsAndApply(DAG, Subtarget, DL, VT, {Operands[0], Operands[1]},
                            AVGBuilder);
  }

  return SDValue();
}

static SDValue combineLoad(SDNode *N, SelectionDAG &DAG,
                           TargetLowering::DAGCombinerInfo &DCI,
                           const X86Subtarget &Subtarget) {
  LoadSDNode *Ld = cast<LoadSDNode>(N);
  EVT RegVT = Ld->getValueType(0);
  EVT MemVT = Ld->getMemoryVT();
  SDLoc dl(Ld);
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();

  // For chips with slow 32-byte unaligned loads, break the 32-byte operation
  // into two 16-byte operations. Also split non-temporal aligned loads on
  // pre-AVX2 targets as 32-byte loads will lower to regular temporal loads.
  ISD::LoadExtType Ext = Ld->getExtensionType();
  bool Fast;
  unsigned Alignment = Ld->getAlignment();
  if (RegVT.is256BitVector() && !DCI.isBeforeLegalizeOps() &&
      Ext == ISD::NON_EXTLOAD &&
      ((Ld->isNonTemporal() && !Subtarget.hasInt256() && Alignment >= 16) ||
       (TLI.allowsMemoryAccess(*DAG.getContext(), DAG.getDataLayout(), RegVT,
                               *Ld->getMemOperand(), &Fast) &&
        !Fast))) {
    unsigned NumElems = RegVT.getVectorNumElements();
    if (NumElems < 2)
      return SDValue();

    unsigned HalfAlign = 16;
    SDValue Ptr1 = Ld->getBasePtr();
    SDValue Ptr2 = DAG.getMemBasePlusOffset(Ptr1, HalfAlign, dl);
    EVT HalfVT = EVT::getVectorVT(*DAG.getContext(), MemVT.getScalarType(),
                                  NumElems / 2);
    SDValue Load1 =
        DAG.getLoad(HalfVT, dl, Ld->getChain(), Ptr1, Ld->getPointerInfo(),
                    Alignment, Ld->getMemOperand()->getFlags());
    SDValue Load2 = DAG.getLoad(HalfVT, dl, Ld->getChain(), Ptr2,
                                Ld->getPointerInfo().getWithOffset(HalfAlign),
                                MinAlign(Alignment, HalfAlign),
                                Ld->getMemOperand()->getFlags());
    SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
                             Load1.getValue(1), Load2.getValue(1));

    SDValue NewVec = DAG.getNode(ISD::CONCAT_VECTORS, dl, RegVT, Load1, Load2);
    return DCI.CombineTo(N, NewVec, TF, true);
  }

  // Bool vector load - attempt to cast to an integer, as we have good
  // (vXiY *ext(vXi1 bitcast(iX))) handling.
  if (Ext == ISD::NON_EXTLOAD && !Subtarget.hasAVX512() && RegVT.isVector() &&
      RegVT.getScalarType() == MVT::i1 && DCI.isBeforeLegalize()) {
    unsigned NumElts = RegVT.getVectorNumElements();
    EVT IntVT = EVT::getIntegerVT(*DAG.getContext(), NumElts);
    if (TLI.isTypeLegal(IntVT)) {
      SDValue IntLoad = DAG.getLoad(IntVT, dl, Ld->getChain(), Ld->getBasePtr(),
                                    Ld->getPointerInfo(), Alignment,
                                    Ld->getMemOperand()->getFlags());
      SDValue BoolVec = DAG.getBitcast(RegVT, IntLoad);
      return DCI.CombineTo(N, BoolVec, IntLoad.getValue(1), true);
    }
  }

  return SDValue();
}

/// If V is a build vector of boolean constants and exactly one of those
/// constants is true, return the operand index of that true element.
/// Otherwise, return -1.
static int getOneTrueElt(SDValue V) {
  // This needs to be a build vector of booleans.
  // TODO: Checking for the i1 type matches the IR definition for the mask,
  // but the mask check could be loosened to i8 or other types. That might
  // also require checking more than 'allOnesValue'; eg, the x86 HW
  // instructions only require that the MSB is set for each mask element.
  // The ISD::MSTORE comments/definition do not specify how the mask operand
  // is formatted.
  auto *BV = dyn_cast<BuildVectorSDNode>(V);
  if (!BV || BV->getValueType(0).getVectorElementType() != MVT::i1)
    return -1;

  int TrueIndex = -1;
  unsigned NumElts = BV->getValueType(0).getVectorNumElements();
  for (unsigned i = 0; i < NumElts; ++i) {
    const SDValue &Op = BV->getOperand(i);
    if (Op.isUndef())
      continue;
    auto *ConstNode = dyn_cast<ConstantSDNode>(Op);
    if (!ConstNode)
      return -1;
    if (ConstNode->getAPIntValue().isAllOnesValue()) {
      // If we already found a one, this is too many.
      if (TrueIndex >= 0)
        return -1;
      TrueIndex = i;
    }
  }
  return TrueIndex;
}

/// Given a masked memory load/store operation, return true if it has one mask
/// bit set. If it has one mask bit set, then also return the memory address of
/// the scalar element to load/store, the vector index to insert/extract that
/// scalar element, and the alignment for the scalar memory access.
static bool getParamsForOneTrueMaskedElt(MaskedLoadStoreSDNode *MaskedOp,
                                         SelectionDAG &DAG, SDValue &Addr,
                                         SDValue &Index, unsigned &Alignment) {
  int TrueMaskElt = getOneTrueElt(MaskedOp->getMask());
  if (TrueMaskElt < 0)
    return false;

  // Get the address of the one scalar element that is specified by the mask
  // using the appropriate offset from the base pointer.
  EVT EltVT = MaskedOp->getMemoryVT().getVectorElementType();
  Addr = MaskedOp->getBasePtr();
  if (TrueMaskElt != 0) {
    unsigned Offset = TrueMaskElt * EltVT.getStoreSize();
    Addr = DAG.getMemBasePlusOffset(Addr, Offset, SDLoc(MaskedOp));
  }

  Index = DAG.getIntPtrConstant(TrueMaskElt, SDLoc(MaskedOp));
  Alignment = MinAlign(MaskedOp->getAlignment(), EltVT.getStoreSize());
  return true;
}

/// If exactly one element of the mask is set for a non-extending masked load,
/// it is a scalar load and vector insert.
/// Note: It is expected that the degenerate cases of an all-zeros or all-ones
/// mask have already been optimized in IR, so we don't bother with those here.
static SDValue
reduceMaskedLoadToScalarLoad(MaskedLoadSDNode *ML, SelectionDAG &DAG,
                             TargetLowering::DAGCombinerInfo &DCI) {
  assert(ML->isUnindexed() && "Unexpected indexed masked load!");
  // TODO: This is not x86-specific, so it could be lifted to DAGCombiner.
  // However, some target hooks may need to be added to know when the transform
  // is profitable. Endianness would also have to be considered.

  SDValue Addr, VecIndex;
  unsigned Alignment;
  if (!getParamsForOneTrueMaskedElt(ML, DAG, Addr, VecIndex, Alignment))
    return SDValue();

  // Load the one scalar element that is specified by the mask using the
  // appropriate offset from the base pointer.
  SDLoc DL(ML);
  EVT VT = ML->getValueType(0);
  EVT EltVT = VT.getVectorElementType();
  SDValue Load =
      DAG.getLoad(EltVT, DL, ML->getChain(), Addr, ML->getPointerInfo(),
                  Alignment, ML->getMemOperand()->getFlags());

  // Insert the loaded element into the appropriate place in the vector.
  SDValue Insert = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, VT,
                               ML->getPassThru(), Load, VecIndex);
  return DCI.CombineTo(ML, Insert, Load.getValue(1), true);
}

static SDValue
combineMaskedLoadConstantMask(MaskedLoadSDNode *ML, SelectionDAG &DAG,
                              TargetLowering::DAGCombinerInfo &DCI) {
  assert(ML->isUnindexed() && "Unexpected indexed masked load!");
  if (!ISD::isBuildVectorOfConstantSDNodes(ML->getMask().getNode()))
    return SDValue();

  SDLoc DL(ML);
  EVT VT = ML->getValueType(0);

  // If we are loading the first and last elements of a vector, it is safe and
  // always faster to load the whole vector. Replace the masked load with a
  // vector load and select.
  unsigned NumElts = VT.getVectorNumElements();
  BuildVectorSDNode *MaskBV = cast<BuildVectorSDNode>(ML->getMask());
  bool LoadFirstElt = !isNullConstant(MaskBV->getOperand(0));
  bool LoadLastElt = !isNullConstant(MaskBV->getOperand(NumElts - 1));
  if (LoadFirstElt && LoadLastElt) {
    SDValue VecLd = DAG.getLoad(VT, DL, ML->getChain(), ML->getBasePtr(),
                                ML->getMemOperand());
    SDValue Blend = DAG.getSelect(DL, VT, ML->getMask(), VecLd,
                                  ML->getPassThru());
    return DCI.CombineTo(ML, Blend, VecLd.getValue(1), true);
  }

  // Convert a masked load with a constant mask into a masked load and a select.
  // This allows the select operation to use a faster kind of select instruction
  // (for example, vblendvps -> vblendps).

  // Don't try this if the pass-through operand is already undefined. That would
  // cause an infinite loop because that's what we're about to create.
  if (ML->getPassThru().isUndef())
    return SDValue();

  if (ISD::isBuildVectorAllZeros(ML->getPassThru().getNode()))
    return SDValue();

  // The new masked load has an undef pass-through operand. The select uses the
  // original pass-through operand.
  SDValue NewML = DAG.getMaskedLoad(
      VT, DL, ML->getChain(), ML->getBasePtr(), ML->getOffset(), ML->getMask(),
      DAG.getUNDEF(VT), ML->getMemoryVT(), ML->getMemOperand(),
      ML->getAddressingMode(), ML->getExtensionType());
  SDValue Blend = DAG.getSelect(DL, VT, ML->getMask(), NewML,
                                ML->getPassThru());

  return DCI.CombineTo(ML, Blend, NewML.getValue(1), true);
}

static SDValue combineMaskedLoad(SDNode *N, SelectionDAG &DAG,
                                 TargetLowering::DAGCombinerInfo &DCI,
                                 const X86Subtarget &Subtarget) {
  MaskedLoadSDNode *Mld = cast<MaskedLoadSDNode>(N);

  // TODO: Expanding load with constant mask may be optimized as well.
  if (Mld->isExpandingLoad())
    return SDValue();

  if (Mld->getExtensionType() == ISD::NON_EXTLOAD) {
    if (SDValue ScalarLoad = reduceMaskedLoadToScalarLoad(Mld, DAG, DCI))
      return ScalarLoad;
    // TODO: Do some AVX512 subsets benefit from this transform?
    if (!Subtarget.hasAVX512())
      if (SDValue Blend = combineMaskedLoadConstantMask(Mld, DAG, DCI))
        return Blend;
  }

  return SDValue();
}

/// If exactly one element of the mask is set for a non-truncating masked store,
/// it is a vector extract and scalar store.
/// Note: It is expected that the degenerate cases of an all-zeros or all-ones
/// mask have already been optimized in IR, so we don't bother with those here.
static SDValue reduceMaskedStoreToScalarStore(MaskedStoreSDNode *MS,
                                              SelectionDAG &DAG) {
  // TODO: This is not x86-specific, so it could be lifted to DAGCombiner.
  // However, some target hooks may need to be added to know when the transform
  // is profitable. Endianness would also have to be considered.

  SDValue Addr, VecIndex;
  unsigned Alignment;
  if (!getParamsForOneTrueMaskedElt(MS, DAG, Addr, VecIndex, Alignment))
    return SDValue();

  // Extract the one scalar element that is actually being stored.
  SDLoc DL(MS);
  EVT VT = MS->getValue().getValueType();
  EVT EltVT = VT.getVectorElementType();
  SDValue Extract = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltVT,
                                MS->getValue(), VecIndex);

  // Store that element at the appropriate offset from the base pointer.
  return DAG.getStore(MS->getChain(), DL, Extract, Addr, MS->getPointerInfo(),
                      Alignment, MS->getMemOperand()->getFlags());
}

static SDValue combineMaskedStore(SDNode *N, SelectionDAG &DAG,
                                  TargetLowering::DAGCombinerInfo &DCI,
                                  const X86Subtarget &Subtarget) {
  MaskedStoreSDNode *Mst = cast<MaskedStoreSDNode>(N);
  if (Mst->isCompressingStore())
    return SDValue();

  EVT VT = Mst->getValue().getValueType();
  SDLoc dl(Mst);
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();

  if (Mst->isTruncatingStore())
    return SDValue();

  if (SDValue ScalarStore = reduceMaskedStoreToScalarStore(Mst, DAG))
    return ScalarStore;

  // If the mask value has been legalized to a non-boolean vector, try to
  // simplify ops leading up to it. We only demand the MSB of each lane.
  SDValue Mask = Mst->getMask();
  if (Mask.getScalarValueSizeInBits() != 1) {
    APInt DemandedBits(APInt::getSignMask(VT.getScalarSizeInBits()));
    if (TLI.SimplifyDemandedBits(Mask, DemandedBits, DCI)) {
      if (N->getOpcode() != ISD::DELETED_NODE)
        DCI.AddToWorklist(N);
      return SDValue(N, 0);
    }
    if (SDValue NewMask =
            TLI.SimplifyMultipleUseDemandedBits(Mask, DemandedBits, DAG))
      return DAG.getMaskedStore(Mst->getChain(), SDLoc(N), Mst->getValue(),
                                Mst->getBasePtr(), Mst->getOffset(), NewMask,
                                Mst->getMemoryVT(), Mst->getMemOperand(),
                                Mst->getAddressingMode());
  }

  SDValue Value = Mst->getValue();
  if (Value.getOpcode() == ISD::TRUNCATE && Value.getNode()->hasOneUse() &&
      TLI.isTruncStoreLegal(Value.getOperand(0).getValueType(),
                            Mst->getMemoryVT())) {
    return DAG.getMaskedStore(Mst->getChain(), SDLoc(N), Value.getOperand(0),
                              Mst->getBasePtr(), Mst->getOffset(), Mask,
                              Mst->getMemoryVT(), Mst->getMemOperand(),
                              Mst->getAddressingMode(), true);
  }

  return SDValue();
}

static SDValue combineStore(SDNode *N, SelectionDAG &DAG,
                            TargetLowering::DAGCombinerInfo &DCI,
                            const X86Subtarget &Subtarget) {
  StoreSDNode *St = cast<StoreSDNode>(N);
  EVT StVT = St->getMemoryVT();
  SDLoc dl(St);
  unsigned Alignment = St->getAlignment();
  SDValue StoredVal = St->getValue();
  EVT VT = StoredVal.getValueType();
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();

  // Convert a store of vXi1 into a store of iX and a bitcast.
  if (!Subtarget.hasAVX512() && VT == StVT && VT.isVector() &&
      VT.getVectorElementType() == MVT::i1) {

    EVT NewVT = EVT::getIntegerVT(*DAG.getContext(), VT.getVectorNumElements());
    StoredVal = DAG.getBitcast(NewVT, StoredVal);

    return DAG.getStore(St->getChain(), dl, StoredVal, St->getBasePtr(),
                        St->getPointerInfo(), St->getAlignment(),
                        St->getMemOperand()->getFlags());
  }

  // If this is a store of a scalar_to_vector to v1i1, just use a scalar store.
  // This will avoid a copy to k-register.
  if (VT == MVT::v1i1 && VT == StVT && Subtarget.hasAVX512() &&
      StoredVal.getOpcode() == ISD::SCALAR_TO_VECTOR &&
      StoredVal.getOperand(0).getValueType() == MVT::i8) {
    return DAG.getStore(St->getChain(), dl, StoredVal.getOperand(0),
                        St->getBasePtr(), St->getPointerInfo(),
                        St->getAlignment(), St->getMemOperand()->getFlags());
  }

  // Widen v2i1/v4i1 stores to v8i1.
  if ((VT == MVT::v2i1 || VT == MVT::v4i1) && VT == StVT &&
      Subtarget.hasAVX512()) {
    unsigned NumConcats = 8 / VT.getVectorNumElements();
    SmallVector<SDValue, 4> Ops(NumConcats, DAG.getUNDEF(VT));
    Ops[0] = StoredVal;
    StoredVal = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v8i1, Ops);
    return DAG.getStore(St->getChain(), dl, StoredVal, St->getBasePtr(),
                        St->getPointerInfo(), St->getAlignment(),
                        St->getMemOperand()->getFlags());
  }

  // Turn vXi1 stores of constants into a scalar store.
  if ((VT == MVT::v8i1 || VT == MVT::v16i1 || VT == MVT::v32i1 ||
       VT == MVT::v64i1) && VT == StVT && TLI.isTypeLegal(VT) &&
      ISD::isBuildVectorOfConstantSDNodes(StoredVal.getNode())) {
    // If its a v64i1 store without 64-bit support, we need two stores.
    if (!DCI.isBeforeLegalize() && VT == MVT::v64i1 && !Subtarget.is64Bit()) {
      SDValue Lo = DAG.getBuildVector(MVT::v32i1, dl,
                                      StoredVal->ops().slice(0, 32));
      Lo = combinevXi1ConstantToInteger(Lo, DAG);
      SDValue Hi = DAG.getBuildVector(MVT::v32i1, dl,
                                      StoredVal->ops().slice(32, 32));
      Hi = combinevXi1ConstantToInteger(Hi, DAG);

      SDValue Ptr0 = St->getBasePtr();
      SDValue Ptr1 = DAG.getMemBasePlusOffset(Ptr0, 4, dl);

      SDValue Ch0 =
          DAG.getStore(St->getChain(), dl, Lo, Ptr0, St->getPointerInfo(),
                       Alignment, St->getMemOperand()->getFlags());
      SDValue Ch1 =
          DAG.getStore(St->getChain(), dl, Hi, Ptr1,
                       St->getPointerInfo().getWithOffset(4),
                       MinAlign(Alignment, 4U),
                       St->getMemOperand()->getFlags());
      return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Ch0, Ch1);
    }

    StoredVal = combinevXi1ConstantToInteger(StoredVal, DAG);
    return DAG.getStore(St->getChain(), dl, StoredVal, St->getBasePtr(),
                        St->getPointerInfo(), St->getAlignment(),
                        St->getMemOperand()->getFlags());
  }

  // If we are saving a 32-byte vector and 32-byte stores are slow, such as on
  // Sandy Bridge, perform two 16-byte stores.
  bool Fast;
  if (VT.is256BitVector() && StVT == VT &&
      TLI.allowsMemoryAccess(*DAG.getContext(), DAG.getDataLayout(), VT,
                             *St->getMemOperand(), &Fast) &&
      !Fast) {
    unsigned NumElems = VT.getVectorNumElements();
    if (NumElems < 2)
      return SDValue();

    return splitVectorStore(St, DAG);
  }

  // Split under-aligned vector non-temporal stores.
  if (St->isNonTemporal() && StVT == VT && Alignment < VT.getStoreSize()) {
    // ZMM/YMM nt-stores - either it can be stored as a series of shorter
    // vectors or the legalizer can scalarize it to use MOVNTI.
    if (VT.is256BitVector() || VT.is512BitVector()) {
      unsigned NumElems = VT.getVectorNumElements();
      if (NumElems < 2)
        return SDValue();
      return splitVectorStore(St, DAG);
    }

    // XMM nt-stores - scalarize this to f64 nt-stores on SSE4A, else i32/i64
    // to use MOVNTI.
    if (VT.is128BitVector() && Subtarget.hasSSE2()) {
      MVT NTVT = Subtarget.hasSSE4A()
                     ? MVT::v2f64
                     : (TLI.isTypeLegal(MVT::i64) ? MVT::v2i64 : MVT::v4i32);
      return scalarizeVectorStore(St, NTVT, DAG);
    }
  }

  // Try to optimize v16i16->v16i8 truncating stores when BWI is not
  // supported, but avx512f is by extending to v16i32 and truncating.
  if (!St->isTruncatingStore() && VT == MVT::v16i8 && !Subtarget.hasBWI() &&
      St->getValue().getOpcode() == ISD::TRUNCATE &&
      St->getValue().getOperand(0).getValueType() == MVT::v16i16 &&
      TLI.isTruncStoreLegal(MVT::v16i32, MVT::v16i8) &&
      St->getValue().hasOneUse() && !DCI.isBeforeLegalizeOps()) {
    SDValue Ext = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::v16i32, St->getValue());
    return DAG.getTruncStore(St->getChain(), dl, Ext, St->getBasePtr(),
                             MVT::v16i8, St->getMemOperand());
  }

  // Try to fold a VTRUNCUS or VTRUNCS into a truncating store.
  if (!St->isTruncatingStore() && StoredVal.hasOneUse() &&
      (StoredVal.getOpcode() == X86ISD::VTRUNCUS ||
       StoredVal.getOpcode() == X86ISD::VTRUNCS) &&
      TLI.isTruncStoreLegal(StoredVal.getOperand(0).getValueType(), VT)) {
    bool IsSigned = StoredVal.getOpcode() == X86ISD::VTRUNCS;
    return EmitTruncSStore(IsSigned, St->getChain(),
                           dl, StoredVal.getOperand(0), St->getBasePtr(),
                           VT, St->getMemOperand(), DAG);
  }

  // Optimize trunc store (of multiple scalars) to shuffle and store.
  // First, pack all of the elements in one place. Next, store to memory
  // in fewer chunks.
  if (St->isTruncatingStore() && VT.isVector()) {
    // Check if we can detect an AVG pattern from the truncation. If yes,
    // replace the trunc store by a normal store with the result of X86ISD::AVG
    // instruction.
    if (DCI.isBeforeLegalize() || TLI.isTypeLegal(St->getMemoryVT()))
      if (SDValue Avg = detectAVGPattern(St->getValue(), St->getMemoryVT(), DAG,
                                         Subtarget, dl))
        return DAG.getStore(St->getChain(), dl, Avg, St->getBasePtr(),
                            St->getPointerInfo(), St->getAlignment(),
                            St->getMemOperand()->getFlags());

    if (TLI.isTruncStoreLegal(VT, StVT)) {
      if (SDValue Val = detectSSatPattern(St->getValue(), St->getMemoryVT()))
        return EmitTruncSStore(true /* Signed saturation */, St->getChain(),
                               dl, Val, St->getBasePtr(),
                               St->getMemoryVT(), St->getMemOperand(), DAG);
      if (SDValue Val = detectUSatPattern(St->getValue(), St->getMemoryVT(),
                                          DAG, dl))
        return EmitTruncSStore(false /* Unsigned saturation */, St->getChain(),
                               dl, Val, St->getBasePtr(),
                               St->getMemoryVT(), St->getMemOperand(), DAG);
    }

    return SDValue();
  }

  // Turn load->store of MMX types into GPR load/stores.  This avoids clobbering
  // the FP state in cases where an emms may be missing.
  // A preferable solution to the general problem is to figure out the right
  // places to insert EMMS.  This qualifies as a quick hack.

  // Similarly, turn load->store of i64 into double load/stores in 32-bit mode.
  if (VT.getSizeInBits() != 64)
    return SDValue();

  const Function &F = DAG.getMachineFunction().getFunction();
  bool NoImplicitFloatOps = F.hasFnAttribute(Attribute::NoImplicitFloat);
  bool F64IsLegal =
      !Subtarget.useSoftFloat() && !NoImplicitFloatOps && Subtarget.hasSSE2();
  if ((VT == MVT::i64 && F64IsLegal && !Subtarget.is64Bit()) &&
      isa<LoadSDNode>(St->getValue()) &&
      cast<LoadSDNode>(St->getValue())->isSimple() &&
      St->getChain().hasOneUse() && St->isSimple()) {
    LoadSDNode *Ld = cast<LoadSDNode>(St->getValue().getNode());

    if (!ISD::isNormalLoad(Ld))
      return SDValue();

    // Avoid the transformation if there are multiple uses of the loaded value.
    if (!Ld->hasNUsesOfValue(1, 0))
      return SDValue();

    SDLoc LdDL(Ld);
    SDLoc StDL(N);
    // Lower to a single movq load/store pair.
    SDValue NewLd = DAG.getLoad(MVT::f64, LdDL, Ld->getChain(),
                                Ld->getBasePtr(), Ld->getMemOperand());

    // Make sure new load is placed in same chain order.
    DAG.makeEquivalentMemoryOrdering(Ld, NewLd);
    return DAG.getStore(St->getChain(), StDL, NewLd, St->getBasePtr(),
                        St->getMemOperand());
  }

  // This is similar to the above case, but here we handle a scalar 64-bit
  // integer store that is extracted from a vector on a 32-bit target.
  // If we have SSE2, then we can treat it like a floating-point double
  // to get past legalization. The execution dependencies fixup pass will
  // choose the optimal machine instruction for the store if this really is
  // an integer or v2f32 rather than an f64.
  if (VT == MVT::i64 && F64IsLegal && !Subtarget.is64Bit() &&
      St->getOperand(1).getOpcode() == ISD::EXTRACT_VECTOR_ELT) {
    SDValue OldExtract = St->getOperand(1);
    SDValue ExtOp0 = OldExtract.getOperand(0);
    unsigned VecSize = ExtOp0.getValueSizeInBits();
    EVT VecVT = EVT::getVectorVT(*DAG.getContext(), MVT::f64, VecSize / 64);
    SDValue BitCast = DAG.getBitcast(VecVT, ExtOp0);
    SDValue NewExtract = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64,
                                     BitCast, OldExtract.getOperand(1));
    return DAG.getStore(St->getChain(), dl, NewExtract, St->getBasePtr(),
                        St->getPointerInfo(), St->getAlignment(),
                        St->getMemOperand()->getFlags());
  }

  return SDValue();
}

static SDValue combineVEXTRACT_STORE(SDNode *N, SelectionDAG &DAG,
                                     TargetLowering::DAGCombinerInfo &DCI,
                                     const X86Subtarget &Subtarget) {
  auto *St = cast<MemIntrinsicSDNode>(N);

  SDValue StoredVal = N->getOperand(1);
  MVT VT = StoredVal.getSimpleValueType();
  EVT MemVT = St->getMemoryVT();

  // Figure out which elements we demand.
  unsigned StElts = MemVT.getSizeInBits() / VT.getScalarSizeInBits();
  APInt DemandedElts = APInt::getLowBitsSet(VT.getVectorNumElements(), StElts);

  APInt KnownUndef, KnownZero;
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  if (TLI.SimplifyDemandedVectorElts(StoredVal, DemandedElts, KnownUndef,
                                     KnownZero, DCI)) {
    if (N->getOpcode() != ISD::DELETED_NODE)
      DCI.AddToWorklist(N);
    return SDValue(N, 0);
  }

  return SDValue();
}

/// Return 'true' if this vector operation is "horizontal"
/// and return the operands for the horizontal operation in LHS and RHS.  A
/// horizontal operation performs the binary operation on successive elements
/// of its first operand, then on successive elements of its second operand,
/// returning the resulting values in a vector.  For example, if
///   A = < float a0, float a1, float a2, float a3 >
/// and
///   B = < float b0, float b1, float b2, float b3 >
/// then the result of doing a horizontal operation on A and B is
///   A horizontal-op B = < a0 op a1, a2 op a3, b0 op b1, b2 op b3 >.
/// In short, LHS and RHS are inspected to see if LHS op RHS is of the form
/// A horizontal-op B, for some already available A and B, and if so then LHS is
/// set to A, RHS to B, and the routine returns 'true'.
static bool isHorizontalBinOp(SDValue &LHS, SDValue &RHS, SelectionDAG &DAG,
                              const X86Subtarget &Subtarget,
                              bool IsCommutative) {
  // If either operand is undef, bail out. The binop should be simplified.
  if (LHS.isUndef() || RHS.isUndef())
    return false;

  // Look for the following pattern:
  //   A = < float a0, float a1, float a2, float a3 >
  //   B = < float b0, float b1, float b2, float b3 >
  // and
  //   LHS = VECTOR_SHUFFLE A, B, <0, 2, 4, 6>
  //   RHS = VECTOR_SHUFFLE A, B, <1, 3, 5, 7>
  // then LHS op RHS = < a0 op a1, a2 op a3, b0 op b1, b2 op b3 >
  // which is A horizontal-op B.

  MVT VT = LHS.getSimpleValueType();
  assert((VT.is128BitVector() || VT.is256BitVector()) &&
         "Unsupported vector type for horizontal add/sub");
  unsigned NumElts = VT.getVectorNumElements();

  // TODO - can we make a general helper method that does all of this for us?
  auto GetShuffle = [&](SDValue Op, SDValue &N0, SDValue &N1,
                        SmallVectorImpl<int> &ShuffleMask) {
    if (Op.getOpcode() == ISD::VECTOR_SHUFFLE) {
      if (!Op.getOperand(0).isUndef())
        N0 = Op.getOperand(0);
      if (!Op.getOperand(1).isUndef())
        N1 = Op.getOperand(1);
      ArrayRef<int> Mask = cast<ShuffleVectorSDNode>(Op)->getMask();
      ShuffleMask.append(Mask.begin(), Mask.end());
      return;
    }
    bool UseSubVector = false;
    if (Op.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
        Op.getOperand(0).getValueType().is256BitVector() &&
        llvm::isNullConstant(Op.getOperand(1))) {
      Op = Op.getOperand(0);
      UseSubVector = true;
    }
    bool IsUnary;
    SmallVector<SDValue, 2> SrcOps;
    SmallVector<int, 16> SrcShuffleMask;
    SDValue BC = peekThroughBitcasts(Op);
    if (isTargetShuffle(BC.getOpcode()) &&
        getTargetShuffleMask(BC.getNode(), BC.getSimpleValueType(), false,
                             SrcOps, SrcShuffleMask, IsUnary)) {
      if (!UseSubVector && SrcShuffleMask.size() == NumElts &&
          SrcOps.size() <= 2) {
        N0 = SrcOps.size() > 0 ? SrcOps[0] : SDValue();
        N1 = SrcOps.size() > 1 ? SrcOps[1] : SDValue();
        ShuffleMask.append(SrcShuffleMask.begin(), SrcShuffleMask.end());
      }
      if (UseSubVector && (SrcShuffleMask.size() == (NumElts * 2)) &&
          SrcOps.size() == 1) {
        N0 = extract128BitVector(SrcOps[0], 0, DAG, SDLoc(Op));
        N1 = extract128BitVector(SrcOps[0], NumElts, DAG, SDLoc(Op));
        ArrayRef<int> Mask = ArrayRef<int>(SrcShuffleMask).slice(0, NumElts);
        ShuffleMask.append(Mask.begin(), Mask.end());
      }
    }
  };

  // View LHS in the form
  //   LHS = VECTOR_SHUFFLE A, B, LMask
  // If LHS is not a shuffle, then pretend it is the identity shuffle:
  //   LHS = VECTOR_SHUFFLE LHS, undef, <0, 1, ..., N-1>
  // NOTE: A default initialized SDValue represents an UNDEF of type VT.
  SDValue A, B;
  SmallVector<int, 16> LMask;
  GetShuffle(LHS, A, B, LMask);

  // Likewise, view RHS in the form
  //   RHS = VECTOR_SHUFFLE C, D, RMask
  SDValue C, D;
  SmallVector<int, 16> RMask;
  GetShuffle(RHS, C, D, RMask);

  // At least one of the operands should be a vector shuffle.
  unsigned NumShuffles = (LMask.empty() ? 0 : 1) + (RMask.empty() ? 0 : 1);
  if (NumShuffles == 0)
    return false;

  if (LMask.empty()) {
    A = LHS;
    for (unsigned i = 0; i != NumElts; ++i)
      LMask.push_back(i);
  }

  if (RMask.empty()) {
    C = RHS;
    for (unsigned i = 0; i != NumElts; ++i)
      RMask.push_back(i);
  }

  // If A and B occur in reverse order in RHS, then canonicalize by commuting
  // RHS operands and shuffle mask.
  if (A != C) {
    std::swap(C, D);
    ShuffleVectorSDNode::commuteMask(RMask);
  }
  // Check that the shuffles are both shuffling the same vectors.
  if (!(A == C && B == D))
    return false;

  // LHS and RHS are now:
  //   LHS = shuffle A, B, LMask
  //   RHS = shuffle A, B, RMask
  // Check that the masks correspond to performing a horizontal operation.
  // AVX defines horizontal add/sub to operate independently on 128-bit lanes,
  // so we just repeat the inner loop if this is a 256-bit op.
  unsigned Num128BitChunks = VT.getSizeInBits() / 128;
  unsigned NumEltsPer128BitChunk = NumElts / Num128BitChunks;
  assert((NumEltsPer128BitChunk % 2 == 0) &&
         "Vector type should have an even number of elements in each lane");
  for (unsigned j = 0; j != NumElts; j += NumEltsPer128BitChunk) {
    for (unsigned i = 0; i != NumEltsPer128BitChunk; ++i) {
      // Ignore undefined components.
      int LIdx = LMask[i + j], RIdx = RMask[i + j];
      if (LIdx < 0 || RIdx < 0 ||
          (!A.getNode() && (LIdx < (int)NumElts || RIdx < (int)NumElts)) ||
          (!B.getNode() && (LIdx >= (int)NumElts || RIdx >= (int)NumElts)))
        continue;

      // The  low half of the 128-bit result must choose from A.
      // The high half of the 128-bit result must choose from B,
      // unless B is undef. In that case, we are always choosing from A.
      unsigned NumEltsPer64BitChunk = NumEltsPer128BitChunk / 2;
      unsigned Src = B.getNode() ? i >= NumEltsPer64BitChunk : 0;

      // Check that successive elements are being operated on. If not, this is
      // not a horizontal operation.
      int Index = 2 * (i % NumEltsPer64BitChunk) + NumElts * Src + j;
      if (!(LIdx == Index && RIdx == Index + 1) &&
          !(IsCommutative && LIdx == Index + 1 && RIdx == Index))
        return false;
    }
  }

  LHS = A.getNode() ? A : B; // If A is 'UNDEF', use B for it.
  RHS = B.getNode() ? B : A; // If B is 'UNDEF', use A for it.

  if (!shouldUseHorizontalOp(LHS == RHS && NumShuffles < 2, DAG, Subtarget))
    return false;

  LHS = DAG.getBitcast(VT, LHS);
  RHS = DAG.getBitcast(VT, RHS);
  return true;
}

/// Do target-specific dag combines on floating-point adds/subs.
static SDValue combineFaddFsub(SDNode *N, SelectionDAG &DAG,
                               const X86Subtarget &Subtarget) {
  EVT VT = N->getValueType(0);
  SDValue LHS = N->getOperand(0);
  SDValue RHS = N->getOperand(1);
  bool IsFadd = N->getOpcode() == ISD::FADD;
  auto HorizOpcode = IsFadd ? X86ISD::FHADD : X86ISD::FHSUB;
  assert((IsFadd || N->getOpcode() == ISD::FSUB) && "Wrong opcode");

  // Try to synthesize horizontal add/sub from adds/subs of shuffles.
  if (((Subtarget.hasSSE3() && (VT == MVT::v4f32 || VT == MVT::v2f64)) ||
       (Subtarget.hasAVX() && (VT == MVT::v8f32 || VT == MVT::v4f64))) &&
      isHorizontalBinOp(LHS, RHS, DAG, Subtarget, IsFadd))
    return DAG.getNode(HorizOpcode, SDLoc(N), VT, LHS, RHS);

  return SDValue();
}

/// Attempt to pre-truncate inputs to arithmetic ops if it will simplify
/// the codegen.
/// e.g. TRUNC( BINOP( X, Y ) ) --> BINOP( TRUNC( X ), TRUNC( Y ) )
/// TODO: This overlaps with the generic combiner's visitTRUNCATE. Remove
///       anything that is guaranteed to be transformed by DAGCombiner.
static SDValue combineTruncatedArithmetic(SDNode *N, SelectionDAG &DAG,
                                          const X86Subtarget &Subtarget,
                                          const SDLoc &DL) {
  assert(N->getOpcode() == ISD::TRUNCATE && "Wrong opcode");
  SDValue Src = N->getOperand(0);
  unsigned SrcOpcode = Src.getOpcode();
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();

  EVT VT = N->getValueType(0);
  EVT SrcVT = Src.getValueType();

  auto IsFreeTruncation = [VT](SDValue Op) {
    unsigned TruncSizeInBits = VT.getScalarSizeInBits();

    // See if this has been extended from a smaller/equal size to
    // the truncation size, allowing a truncation to combine with the extend.
    unsigned Opcode = Op.getOpcode();
    if ((Opcode == ISD::ANY_EXTEND || Opcode == ISD::SIGN_EXTEND ||
         Opcode == ISD::ZERO_EXTEND) &&
        Op.getOperand(0).getScalarValueSizeInBits() <= TruncSizeInBits)
      return true;

    // See if this is a single use constant which can be constant folded.
    // NOTE: We don't peek throught bitcasts here because there is currently
    // no support for constant folding truncate+bitcast+vector_of_constants. So
    // we'll just send up with a truncate on both operands which will
    // get turned back into (truncate (binop)) causing an infinite loop.
    return ISD::isBuildVectorOfConstantSDNodes(Op.getNode());
  };

  auto TruncateArithmetic = [&](SDValue N0, SDValue N1) {
    SDValue Trunc0 = DAG.getNode(ISD::TRUNCATE, DL, VT, N0);
    SDValue Trunc1 = DAG.getNode(ISD::TRUNCATE, DL, VT, N1);
    return DAG.getNode(SrcOpcode, DL, VT, Trunc0, Trunc1);
  };

  // Don't combine if the operation has other uses.
  if (!Src.hasOneUse())
    return SDValue();

  // Only support vector truncation for now.
  // TODO: i64 scalar math would benefit as well.
  if (!VT.isVector())
    return SDValue();

  // In most cases its only worth pre-truncating if we're only facing the cost
  // of one truncation.
  // i.e. if one of the inputs will constant fold or the input is repeated.
  switch (SrcOpcode) {
  case ISD::AND:
  case ISD::XOR:
  case ISD::OR: {
    SDValue Op0 = Src.getOperand(0);
    SDValue Op1 = Src.getOperand(1);
    if (TLI.isOperationLegalOrPromote(SrcOpcode, VT) &&
        (Op0 == Op1 || IsFreeTruncation(Op0) || IsFreeTruncation(Op1)))
      return TruncateArithmetic(Op0, Op1);
    break;
  }

  case ISD::MUL:
    // X86 is rubbish at scalar and vector i64 multiplies (until AVX512DQ) - its
    // better to truncate if we have the chance.
    if (SrcVT.getScalarType() == MVT::i64 &&
        TLI.isOperationLegal(SrcOpcode, VT) &&
        !TLI.isOperationLegal(SrcOpcode, SrcVT))
      return TruncateArithmetic(Src.getOperand(0), Src.getOperand(1));
    LLVM_FALLTHROUGH;
  case ISD::ADD: {
    SDValue Op0 = Src.getOperand(0);
    SDValue Op1 = Src.getOperand(1);
    if (TLI.isOperationLegal(SrcOpcode, VT) &&
        (Op0 == Op1 || IsFreeTruncation(Op0) || IsFreeTruncation(Op1)))
      return TruncateArithmetic(Op0, Op1);
    break;
  }
  case ISD::SUB: {
    // TODO: ISD::SUB We are conservative and require both sides to be freely
    // truncatable to avoid interfering with combineSubToSubus.
    SDValue Op0 = Src.getOperand(0);
    SDValue Op1 = Src.getOperand(1);
    if (TLI.isOperationLegal(SrcOpcode, VT) &&
        (Op0 == Op1 || (IsFreeTruncation(Op0) && IsFreeTruncation(Op1))))
      return TruncateArithmetic(Op0, Op1);
    break;
  }
  }

  return SDValue();
}

/// Truncate using ISD::AND mask and X86ISD::PACKUS.
/// e.g. trunc <8 x i32> X to <8 x i16> -->
/// MaskX = X & 0xffff (clear high bits to prevent saturation)
/// packus (extract_subv MaskX, 0), (extract_subv MaskX, 1)
static SDValue combineVectorTruncationWithPACKUS(SDNode *N, const SDLoc &DL,
                                                 const X86Subtarget &Subtarget,
                                                 SelectionDAG &DAG) {
  SDValue In = N->getOperand(0);
  EVT InVT = In.getValueType();
  EVT OutVT = N->getValueType(0);

  APInt Mask = APInt::getLowBitsSet(InVT.getScalarSizeInBits(),
                                    OutVT.getScalarSizeInBits());
  In = DAG.getNode(ISD::AND, DL, InVT, In, DAG.getConstant(Mask, DL, InVT));
  return truncateVectorWithPACK(X86ISD::PACKUS, OutVT, In, DL, DAG, Subtarget);
}

/// Truncate a group of v4i32 into v8i16 using X86ISD::PACKSS.
static SDValue combineVectorTruncationWithPACKSS(SDNode *N, const SDLoc &DL,
                                                 const X86Subtarget &Subtarget,
                                                 SelectionDAG &DAG) {
  SDValue In = N->getOperand(0);
  EVT InVT = In.getValueType();
  EVT OutVT = N->getValueType(0);
  In = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, InVT, In,
                   DAG.getValueType(OutVT));
  return truncateVectorWithPACK(X86ISD::PACKSS, OutVT, In, DL, DAG, Subtarget);
}

/// This function transforms truncation from vXi32/vXi64 to vXi8/vXi16 into
/// X86ISD::PACKUS/X86ISD::PACKSS operations. We do it here because after type
/// legalization the truncation will be translated into a BUILD_VECTOR with each
/// element that is extracted from a vector and then truncated, and it is
/// difficult to do this optimization based on them.
static SDValue combineVectorTruncation(SDNode *N, SelectionDAG &DAG,
                                       const X86Subtarget &Subtarget) {
  EVT OutVT = N->getValueType(0);
  if (!OutVT.isVector())
    return SDValue();

  SDValue In = N->getOperand(0);
  if (!In.getValueType().isSimple())
    return SDValue();

  EVT InVT = In.getValueType();
  unsigned NumElems = OutVT.getVectorNumElements();

  // TODO: On AVX2, the behavior of X86ISD::PACKUS is different from that on
  // SSE2, and we need to take care of it specially.
  // AVX512 provides vpmovdb.
  if (!Subtarget.hasSSE2() || Subtarget.hasAVX2())
    return SDValue();

  EVT OutSVT = OutVT.getVectorElementType();
  EVT InSVT = InVT.getVectorElementType();
  if (!((InSVT == MVT::i32 || InSVT == MVT::i64) &&
        (OutSVT == MVT::i8 || OutSVT == MVT::i16) && isPowerOf2_32(NumElems) &&
        NumElems >= 8))
    return SDValue();

  // SSSE3's pshufb results in less instructions in the cases below.
  if (Subtarget.hasSSSE3() && NumElems == 8 &&
      ((OutSVT == MVT::i8 && InSVT != MVT::i64) ||
       (InSVT == MVT::i32 && OutSVT == MVT::i16)))
    return SDValue();

  SDLoc DL(N);
  // SSE2 provides PACKUS for only 2 x v8i16 -> v16i8 and SSE4.1 provides PACKUS
  // for 2 x v4i32 -> v8i16. For SSSE3 and below, we need to use PACKSS to
  // truncate 2 x v4i32 to v8i16.
  if (Subtarget.hasSSE41() || OutSVT == MVT::i8)
    return combineVectorTruncationWithPACKUS(N, DL, Subtarget, DAG);
  if (InSVT == MVT::i32)
    return combineVectorTruncationWithPACKSS(N, DL, Subtarget, DAG);

  return SDValue();
}

/// This function transforms vector truncation of 'extended sign-bits' or
/// 'extended zero-bits' values.
/// vXi16/vXi32/vXi64 to vXi8/vXi16/vXi32 into X86ISD::PACKSS/PACKUS operations.
static SDValue combineVectorSignBitsTruncation(SDNode *N, const SDLoc &DL,
                                               SelectionDAG &DAG,
                                               const X86Subtarget &Subtarget) {
  // Requires SSE2.
  if (!Subtarget.hasSSE2())
    return SDValue();

  if (!N->getValueType(0).isVector() || !N->getValueType(0).isSimple())
    return SDValue();

  SDValue In = N->getOperand(0);
  if (!In.getValueType().isSimple())
    return SDValue();

  MVT VT = N->getValueType(0).getSimpleVT();
  MVT SVT = VT.getScalarType();

  MVT InVT = In.getValueType().getSimpleVT();
  MVT InSVT = InVT.getScalarType();

  // Check we have a truncation suited for PACKSS/PACKUS.
  if (!VT.is128BitVector() && !VT.is256BitVector())
    return SDValue();
  if (SVT != MVT::i8 && SVT != MVT::i16 && SVT != MVT::i32)
    return SDValue();
  if (InSVT != MVT::i16 && InSVT != MVT::i32 && InSVT != MVT::i64)
    return SDValue();

  // AVX512 has fast truncate, but if the input is already going to be split,
  // there's no harm in trying pack.
  if (Subtarget.hasAVX512() &&
      !(!Subtarget.useAVX512Regs() && VT.is256BitVector() &&
        InVT.is512BitVector()))
    return SDValue();

  unsigned NumPackedSignBits = std::min<unsigned>(SVT.getSizeInBits(), 16);
  unsigned NumPackedZeroBits = Subtarget.hasSSE41() ? NumPackedSignBits : 8;

  // Use PACKUS if the input has zero-bits that extend all the way to the
  // packed/truncated value. e.g. masks, zext_in_reg, etc.
  KnownBits Known = DAG.computeKnownBits(In);
  unsigned NumLeadingZeroBits = Known.countMinLeadingZeros();
  if (NumLeadingZeroBits >= (InSVT.getSizeInBits() - NumPackedZeroBits))
    return truncateVectorWithPACK(X86ISD::PACKUS, VT, In, DL, DAG, Subtarget);

  // Use PACKSS if the input has sign-bits that extend all the way to the
  // packed/truncated value. e.g. Comparison result, sext_in_reg, etc.
  unsigned NumSignBits = DAG.ComputeNumSignBits(In);
  if (NumSignBits > (InSVT.getSizeInBits() - NumPackedSignBits))
    return truncateVectorWithPACK(X86ISD::PACKSS, VT, In, DL, DAG, Subtarget);

  return SDValue();
}

// Try to form a MULHU or MULHS node by looking for
// (trunc (srl (mul ext, ext), 16))
// TODO: This is X86 specific because we want to be able to handle wide types
// before type legalization. But we can only do it if the vector will be
// legalized via widening/splitting. Type legalization can't handle promotion
// of a MULHU/MULHS. There isn't a way to convey this to the generic DAG
// combiner.
static SDValue combinePMULH(SDValue Src, EVT VT, const SDLoc &DL,
                            SelectionDAG &DAG, const X86Subtarget &Subtarget) {
  // First instruction should be a right shift of a multiply.
  if (Src.getOpcode() != ISD::SRL ||
      Src.getOperand(0).getOpcode() != ISD::MUL)
    return SDValue();

  if (!Subtarget.hasSSE2())
    return SDValue();

  // Only handle vXi16 types that are at least 128-bits unless they will be
  // widened.
  if (!VT.isVector() || VT.getVectorElementType() != MVT::i16)
    return SDValue();

  // Input type should be vXi32.
  EVT InVT = Src.getValueType();
  if (InVT.getVectorElementType() != MVT::i32)
    return SDValue();

  // Need a shift by 16.
  APInt ShiftAmt;
  if (!ISD::isConstantSplatVector(Src.getOperand(1).getNode(), ShiftAmt) ||
      ShiftAmt != 16)
    return SDValue();

  SDValue LHS = Src.getOperand(0).getOperand(0);
  SDValue RHS = Src.getOperand(0).getOperand(1);

  unsigned ExtOpc = LHS.getOpcode();
  if ((ExtOpc != ISD::SIGN_EXTEND && ExtOpc != ISD::ZERO_EXTEND) ||
      RHS.getOpcode() != ExtOpc)
    return SDValue();

  // Peek through the extends.
  LHS = LHS.getOperand(0);
  RHS = RHS.getOperand(0);

  // Ensure the input types match.
  if (LHS.getValueType() != VT || RHS.getValueType() != VT)
    return SDValue();

  unsigned Opc = ExtOpc == ISD::SIGN_EXTEND ? ISD::MULHS : ISD::MULHU;
  return DAG.getNode(Opc, DL, VT, LHS, RHS);
}

// Attempt to match PMADDUBSW, which multiplies corresponding unsigned bytes
// from one vector with signed bytes from another vector, adds together
// adjacent pairs of 16-bit products, and saturates the result before
// truncating to 16-bits.
//
// Which looks something like this:
// (i16 (ssat (add (mul (zext (even elts (i8 A))), (sext (even elts (i8 B)))),
//                 (mul (zext (odd elts (i8 A)), (sext (odd elts (i8 B))))))))
static SDValue detectPMADDUBSW(SDValue In, EVT VT, SelectionDAG &DAG,
                               const X86Subtarget &Subtarget,
                               const SDLoc &DL) {
  if (!VT.isVector() || !Subtarget.hasSSSE3())
    return SDValue();

  unsigned NumElems = VT.getVectorNumElements();
  EVT ScalarVT = VT.getVectorElementType();
  if (ScalarVT != MVT::i16 || NumElems < 8 || !isPowerOf2_32(NumElems))
    return SDValue();

  SDValue SSatVal = detectSSatPattern(In, VT);
  if (!SSatVal || SSatVal.getOpcode() != ISD::ADD)
    return SDValue();

  // Ok this is a signed saturation of an ADD. See if this ADD is adding pairs
  // of multiplies from even/odd elements.
  SDValue N0 = SSatVal.getOperand(0);
  SDValue N1 = SSatVal.getOperand(1);

  if (N0.getOpcode() != ISD::MUL || N1.getOpcode() != ISD::MUL)
    return SDValue();

  SDValue N00 = N0.getOperand(0);
  SDValue N01 = N0.getOperand(1);
  SDValue N10 = N1.getOperand(0);
  SDValue N11 = N1.getOperand(1);

  // TODO: Handle constant vectors and use knownbits/computenumsignbits?
  // Canonicalize zero_extend to LHS.
  if (N01.getOpcode() == ISD::ZERO_EXTEND)
    std::swap(N00, N01);
  if (N11.getOpcode() == ISD::ZERO_EXTEND)
    std::swap(N10, N11);

  // Ensure we have a zero_extend and a sign_extend.
  if (N00.getOpcode() != ISD::ZERO_EXTEND ||
      N01.getOpcode() != ISD::SIGN_EXTEND ||
      N10.getOpcode() != ISD::ZERO_EXTEND ||
      N11.getOpcode() != ISD::SIGN_EXTEND)
    return SDValue();

  // Peek through the extends.
  N00 = N00.getOperand(0);
  N01 = N01.getOperand(0);
  N10 = N10.getOperand(0);
  N11 = N11.getOperand(0);

  // Ensure the extend is from vXi8.
  if (N00.getValueType().getVectorElementType() != MVT::i8 ||
      N01.getValueType().getVectorElementType() != MVT::i8 ||
      N10.getValueType().getVectorElementType() != MVT::i8 ||
      N11.getValueType().getVectorElementType() != MVT::i8)
    return SDValue();

  // All inputs should be build_vectors.
  if (N00.getOpcode() != ISD::BUILD_VECTOR ||
      N01.getOpcode() != ISD::BUILD_VECTOR ||
      N10.getOpcode() != ISD::BUILD_VECTOR ||
      N11.getOpcode() != ISD::BUILD_VECTOR)
    return SDValue();

  // N00/N10 are zero extended. N01/N11 are sign extended.

  // For each element, we need to ensure we have an odd element from one vector
  // multiplied by the odd element of another vector and the even element from
  // one of the same vectors being multiplied by the even element from the
  // other vector. So we need to make sure for each element i, this operator
  // is being performed:
  //  A[2 * i] * B[2 * i] + A[2 * i + 1] * B[2 * i + 1]
  SDValue ZExtIn, SExtIn;
  for (unsigned i = 0; i != NumElems; ++i) {
    SDValue N00Elt = N00.getOperand(i);
    SDValue N01Elt = N01.getOperand(i);
    SDValue N10Elt = N10.getOperand(i);
    SDValue N11Elt = N11.getOperand(i);
    // TODO: Be more tolerant to undefs.
    if (N00Elt.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
        N01Elt.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
        N10Elt.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
        N11Elt.getOpcode() != ISD::EXTRACT_VECTOR_ELT)
      return SDValue();
    auto *ConstN00Elt = dyn_cast<ConstantSDNode>(N00Elt.getOperand(1));
    auto *ConstN01Elt = dyn_cast<ConstantSDNode>(N01Elt.getOperand(1));
    auto *ConstN10Elt = dyn_cast<ConstantSDNode>(N10Elt.getOperand(1));
    auto *ConstN11Elt = dyn_cast<ConstantSDNode>(N11Elt.getOperand(1));
    if (!ConstN00Elt || !ConstN01Elt || !ConstN10Elt || !ConstN11Elt)
      return SDValue();
    unsigned IdxN00 = ConstN00Elt->getZExtValue();
    unsigned IdxN01 = ConstN01Elt->getZExtValue();
    unsigned IdxN10 = ConstN10Elt->getZExtValue();
    unsigned IdxN11 = ConstN11Elt->getZExtValue();
    // Add is commutative so indices can be reordered.
    if (IdxN00 > IdxN10) {
      std::swap(IdxN00, IdxN10);
      std::swap(IdxN01, IdxN11);
    }
    // N0 indices be the even element. N1 indices must be the next odd element.
    if (IdxN00 != 2 * i || IdxN10 != 2 * i + 1 ||
        IdxN01 != 2 * i || IdxN11 != 2 * i + 1)
      return SDValue();
    SDValue N00In = N00Elt.getOperand(0);
    SDValue N01In = N01Elt.getOperand(0);
    SDValue N10In = N10Elt.getOperand(0);
    SDValue N11In = N11Elt.getOperand(0);
    // First time we find an input capture it.
    if (!ZExtIn) {
      ZExtIn = N00In;
      SExtIn = N01In;
    }
    if (ZExtIn != N00In || SExtIn != N01In ||
        ZExtIn != N10In || SExtIn != N11In)
      return SDValue();
  }

  auto PMADDBuilder = [](SelectionDAG &DAG, const SDLoc &DL,
                         ArrayRef<SDValue> Ops) {
    // Shrink by adding truncate nodes and let DAGCombine fold with the
    // sources.
    EVT InVT = Ops[0].getValueType();
    assert(InVT.getScalarType() == MVT::i8 &&
           "Unexpected scalar element type");
    assert(InVT == Ops[1].getValueType() && "Operands' types mismatch");
    EVT ResVT = EVT::getVectorVT(*DAG.getContext(), MVT::i16,
                                 InVT.getVectorNumElements() / 2);
    return DAG.getNode(X86ISD::VPMADDUBSW, DL, ResVT, Ops[0], Ops[1]);
  };
  return SplitOpsAndApply(DAG, Subtarget, DL, VT, { ZExtIn, SExtIn },
                          PMADDBuilder);
}

static SDValue combineTruncate(SDNode *N, SelectionDAG &DAG,
                               const X86Subtarget &Subtarget) {
  EVT VT = N->getValueType(0);
  SDValue Src = N->getOperand(0);
  SDLoc DL(N);

  // Attempt to pre-truncate inputs to arithmetic ops instead.
  if (SDValue V = combineTruncatedArithmetic(N, DAG, Subtarget, DL))
    return V;

  // Try to detect AVG pattern first.
  if (SDValue Avg = detectAVGPattern(Src, VT, DAG, Subtarget, DL))
    return Avg;

  // Try to detect PMADD
  if (SDValue PMAdd = detectPMADDUBSW(Src, VT, DAG, Subtarget, DL))
    return PMAdd;

  // Try to combine truncation with signed/unsigned saturation.
  if (SDValue Val = combineTruncateWithSat(Src, VT, DL, DAG, Subtarget))
    return Val;

  // Try to combine PMULHUW/PMULHW for vXi16.
  if (SDValue V = combinePMULH(Src, VT, DL, DAG, Subtarget))
    return V;

  // The bitcast source is a direct mmx result.
  // Detect bitcasts between i32 to x86mmx
  if (Src.getOpcode() == ISD::BITCAST && VT == MVT::i32) {
    SDValue BCSrc = Src.getOperand(0);
    if (BCSrc.getValueType() == MVT::x86mmx)
      return DAG.getNode(X86ISD::MMX_MOVD2W, DL, MVT::i32, BCSrc);
  }

  // Try to truncate extended sign/zero bits with PACKSS/PACKUS.
  if (SDValue V = combineVectorSignBitsTruncation(N, DL, DAG, Subtarget))
    return V;

  return combineVectorTruncation(N, DAG, Subtarget);
}

static SDValue combineVTRUNC(SDNode *N, SelectionDAG &DAG) {
  EVT VT = N->getValueType(0);
  SDValue In = N->getOperand(0);
  SDLoc DL(N);

  if (auto SSatVal = detectSSatPattern(In, VT))
    return DAG.getNode(X86ISD::VTRUNCS, DL, VT, SSatVal);
  if (auto USatVal = detectUSatPattern(In, VT, DAG, DL))
    return DAG.getNode(X86ISD::VTRUNCUS, DL, VT, USatVal);

  return SDValue();
}

/// Returns the negated value if the node \p N flips sign of FP value.
///
/// FP-negation node may have different forms: FNEG(x), FXOR (x, 0x80000000)
/// or FSUB(0, x)
/// AVX512F does not have FXOR, so FNEG is lowered as
/// (bitcast (xor (bitcast x), (bitcast ConstantFP(0x80000000)))).
/// In this case we go though all bitcasts.
/// This also recognizes splat of a negated value and returns the splat of that
/// value.
static SDValue isFNEG(SelectionDAG &DAG, SDNode *N, unsigned Depth = 0) {
  if (N->getOpcode() == ISD::FNEG)
    return N->getOperand(0);

  // Don't recurse exponentially.
  if (Depth > SelectionDAG::MaxRecursionDepth)
    return SDValue();

  unsigned ScalarSize = N->getValueType(0).getScalarSizeInBits();

  SDValue Op = peekThroughBitcasts(SDValue(N, 0));
  EVT VT = Op->getValueType(0);

  // Make sure the element size doesn't change.
  if (VT.getScalarSizeInBits() != ScalarSize)
    return SDValue();

  unsigned Opc = Op.getOpcode();
  switch (Opc) {
  case ISD::VECTOR_SHUFFLE: {
    // For a VECTOR_SHUFFLE(VEC1, VEC2), if the VEC2 is undef, then the negate
    // of this is VECTOR_SHUFFLE(-VEC1, UNDEF).  The mask can be anything here.
    if (!Op.getOperand(1).isUndef())
      return SDValue();
    if (SDValue NegOp0 = isFNEG(DAG, Op.getOperand(0).getNode(), Depth + 1))
      if (NegOp0.getValueType() == VT) // FIXME: Can we do better?
        return DAG.getVectorShuffle(VT, SDLoc(Op), NegOp0, DAG.getUNDEF(VT),
                                    cast<ShuffleVectorSDNode>(Op)->getMask());
    break;
  }
  case ISD::INSERT_VECTOR_ELT: {
    // Negate of INSERT_VECTOR_ELT(UNDEF, V, INDEX) is INSERT_VECTOR_ELT(UNDEF,
    // -V, INDEX).
    SDValue InsVector = Op.getOperand(0);
    SDValue InsVal = Op.getOperand(1);
    if (!InsVector.isUndef())
      return SDValue();
    if (SDValue NegInsVal = isFNEG(DAG, InsVal.getNode(), Depth + 1))
      if (NegInsVal.getValueType() == VT.getVectorElementType()) // FIXME
        return DAG.getNode(ISD::INSERT_VECTOR_ELT, SDLoc(Op), VT, InsVector,
                           NegInsVal, Op.getOperand(2));
    break;
  }
  case ISD::FSUB:
  case ISD::XOR:
  case X86ISD::FXOR: {
    SDValue Op1 = Op.getOperand(1);
    SDValue Op0 = Op.getOperand(0);

    // For XOR and FXOR, we want to check if constant
    // bits of Op1 are sign bit masks. For FSUB, we
    // have to check if constant bits of Op0 are sign
    // bit masks and hence we swap the operands.
    if (Opc == ISD::FSUB)
      std::swap(Op0, Op1);

    APInt UndefElts;
    SmallVector<APInt, 16> EltBits;
    // Extract constant bits and see if they are all
    // sign bit masks. Ignore the undef elements.
    if (getTargetConstantBitsFromNode(Op1, ScalarSize, UndefElts, EltBits,
                                      /* AllowWholeUndefs */ true,
                                      /* AllowPartialUndefs */ false)) {
      for (unsigned I = 0, E = EltBits.size(); I < E; I++)
        if (!UndefElts[I] && !EltBits[I].isSignMask())
          return SDValue();

      return peekThroughBitcasts(Op0);
    }
  }
  }

  return SDValue();
}

static unsigned negateFMAOpcode(unsigned Opcode, bool NegMul, bool NegAcc,
                                bool NegRes) {
  if (NegMul) {
    switch (Opcode) {
    default: llvm_unreachable("Unexpected opcode");
    case ISD::FMA:              Opcode = X86ISD::FNMADD;        break;
    case ISD::STRICT_FMA:       Opcode = X86ISD::STRICT_FNMADD; break;
    case X86ISD::FMADD_RND:     Opcode = X86ISD::FNMADD_RND;    break;
    case X86ISD::FMSUB:         Opcode = X86ISD::FNMSUB;        break;
    case X86ISD::STRICT_FMSUB:  Opcode = X86ISD::STRICT_FNMSUB; break;
    case X86ISD::FMSUB_RND:     Opcode = X86ISD::FNMSUB_RND;    break;
    case X86ISD::FNMADD:        Opcode = ISD::FMA;              break;
    case X86ISD::STRICT_FNMADD: Opcode = ISD::STRICT_FMA;       break;
    case X86ISD::FNMADD_RND:    Opcode = X86ISD::FMADD_RND;     break;
    case X86ISD::FNMSUB:        Opcode = X86ISD::FMSUB;         break;
    case X86ISD::STRICT_FNMSUB: Opcode = X86ISD::STRICT_FMSUB;  break;
    case X86ISD::FNMSUB_RND:    Opcode = X86ISD::FMSUB_RND;     break;
    }
  }

  if (NegAcc) {
    switch (Opcode) {
    default: llvm_unreachable("Unexpected opcode");
    case ISD::FMA:              Opcode = X86ISD::FMSUB;         break;
    case ISD::STRICT_FMA:       Opcode = X86ISD::STRICT_FMSUB;  break;
    case X86ISD::FMADD_RND:     Opcode = X86ISD::FMSUB_RND;     break;
    case X86ISD::FMSUB:         Opcode = ISD::FMA;              break;
    case X86ISD::STRICT_FMSUB:  Opcode = ISD::STRICT_FMA;       break;
    case X86ISD::FMSUB_RND:     Opcode = X86ISD::FMADD_RND;     break;
    case X86ISD::FNMADD:        Opcode = X86ISD::FNMSUB;        break;
    case X86ISD::STRICT_FNMADD: Opcode = X86ISD::STRICT_FNMSUB; break;
    case X86ISD::FNMADD_RND:    Opcode = X86ISD::FNMSUB_RND;    break;
    case X86ISD::FNMSUB:        Opcode = X86ISD::FNMADD;        break;
    case X86ISD::STRICT_FNMSUB: Opcode = X86ISD::STRICT_FNMADD; break;
    case X86ISD::FNMSUB_RND:    Opcode = X86ISD::FNMADD_RND;    break;
    case X86ISD::FMADDSUB:      Opcode = X86ISD::FMSUBADD;      break;
    case X86ISD::FMADDSUB_RND:  Opcode = X86ISD::FMSUBADD_RND;  break;
    case X86ISD::FMSUBADD:      Opcode = X86ISD::FMADDSUB;      break;
    case X86ISD::FMSUBADD_RND:  Opcode = X86ISD::FMADDSUB_RND;  break;
    }
  }

  if (NegRes) {
    switch (Opcode) {
    // For accuracy reason, we never combine fneg and fma under strict FP.
    default: llvm_unreachable("Unexpected opcode");
    case ISD::FMA:             Opcode = X86ISD::FNMSUB;       break;
    case X86ISD::FMADD_RND:    Opcode = X86ISD::FNMSUB_RND;   break;
    case X86ISD::FMSUB:        Opcode = X86ISD::FNMADD;       break;
    case X86ISD::FMSUB_RND:    Opcode = X86ISD::FNMADD_RND;   break;
    case X86ISD::FNMADD:       Opcode = X86ISD::FMSUB;        break;
    case X86ISD::FNMADD_RND:   Opcode = X86ISD::FMSUB_RND;    break;
    case X86ISD::FNMSUB:       Opcode = ISD::FMA;             break;
    case X86ISD::FNMSUB_RND:   Opcode = X86ISD::FMADD_RND;    break;
    }
  }

  return Opcode;
}

/// Do target-specific dag combines on floating point negations.
static SDValue combineFneg(SDNode *N, SelectionDAG &DAG,
                           TargetLowering::DAGCombinerInfo &DCI,
                           const X86Subtarget &Subtarget) {
  EVT OrigVT = N->getValueType(0);
  SDValue Arg = isFNEG(DAG, N);
  if (!Arg)
    return SDValue();

  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  EVT VT = Arg.getValueType();
  EVT SVT = VT.getScalarType();
  SDLoc DL(N);

  // Let legalize expand this if it isn't a legal type yet.
  if (!TLI.isTypeLegal(VT))
    return SDValue();

  // If we're negating a FMUL node on a target with FMA, then we can avoid the
  // use of a constant by performing (-0 - A*B) instead.
  // FIXME: Check rounding control flags as well once it becomes available.
  if (Arg.getOpcode() == ISD::FMUL && (SVT == MVT::f32 || SVT == MVT::f64) &&
      Arg->getFlags().hasNoSignedZeros() && Subtarget.hasAnyFMA()) {
    SDValue Zero = DAG.getConstantFP(0.0, DL, VT);
    SDValue NewNode = DAG.getNode(X86ISD::FNMSUB, DL, VT, Arg.getOperand(0),
                                  Arg.getOperand(1), Zero);
    return DAG.getBitcast(OrigVT, NewNode);
  }

  bool CodeSize = DAG.getMachineFunction().getFunction().hasOptSize();
  bool LegalOperations = !DCI.isBeforeLegalizeOps();
  if (TLI.getNegatibleCost(Arg, DAG, LegalOperations, CodeSize) !=
      TargetLowering::NegatibleCost::Expensive)
    return DAG.getBitcast(
        OrigVT, TLI.getNegatedExpression(Arg, DAG, LegalOperations, CodeSize));

  return SDValue();
}

TargetLowering::NegatibleCost
X86TargetLowering::getNegatibleCost(SDValue Op, SelectionDAG &DAG,
                                    bool LegalOperations, bool ForCodeSize,
                                    unsigned Depth) const {
  // fneg patterns are removable even if they have multiple uses.
  if (isFNEG(DAG, Op.getNode(), Depth))
    return NegatibleCost::Cheaper;

  // Don't recurse exponentially.
  if (Depth > SelectionDAG::MaxRecursionDepth)
    return NegatibleCost::Expensive;

  EVT VT = Op.getValueType();
  EVT SVT = VT.getScalarType();
  switch (Op.getOpcode()) {
  case ISD::FMA:
  case X86ISD::FMSUB:
  case X86ISD::FNMADD:
  case X86ISD::FNMSUB:
  case X86ISD::FMADD_RND:
  case X86ISD::FMSUB_RND:
  case X86ISD::FNMADD_RND:
  case X86ISD::FNMSUB_RND: {
    if (!Op.hasOneUse() || !Subtarget.hasAnyFMA() || !isTypeLegal(VT) ||
        !(SVT == MVT::f32 || SVT == MVT::f64) ||
        !isOperationLegal(ISD::FMA, VT))
      break;

    // This is always negatible for free but we might be able to remove some
    // extra operand negations as well.
    for (int i = 0; i != 3; ++i) {
      NegatibleCost V = getNegatibleCost(Op.getOperand(i), DAG, LegalOperations,
                                         ForCodeSize, Depth + 1);
      if (V == NegatibleCost::Cheaper)
        return V;
    }
    return NegatibleCost::Neutral;
  }
  case X86ISD::FRCP:
    return getNegatibleCost(Op.getOperand(0), DAG, LegalOperations, ForCodeSize,
                            Depth + 1);
  }

  return TargetLowering::getNegatibleCost(Op, DAG, LegalOperations, ForCodeSize,
                                          Depth);
}

SDValue X86TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
                                                bool LegalOperations,
                                                bool ForCodeSize,
                                                unsigned Depth) const {
  // fneg patterns are removable even if they have multiple uses.
  if (SDValue Arg = isFNEG(DAG, Op.getNode(), Depth))
    return DAG.getBitcast(Op.getValueType(), Arg);

  EVT VT = Op.getValueType();
  EVT SVT = VT.getScalarType();
  unsigned Opc = Op.getOpcode();
  switch (Opc) {
  case ISD::FMA:
  case X86ISD::FMSUB:
  case X86ISD::FNMADD:
  case X86ISD::FNMSUB:
  case X86ISD::FMADD_RND:
  case X86ISD::FMSUB_RND:
  case X86ISD::FNMADD_RND:
  case X86ISD::FNMSUB_RND: {
    if (!Op.hasOneUse() || !Subtarget.hasAnyFMA() || !isTypeLegal(VT) ||
        !(SVT == MVT::f32 || SVT == MVT::f64) ||
        !isOperationLegal(ISD::FMA, VT))
      break;

    // This is always negatible for free but we might be able to remove some
    // extra operand negations as well.
    SmallVector<SDValue, 4> NewOps(Op.getNumOperands(), SDValue());
    for (int i = 0; i != 3; ++i) {
      NegatibleCost V = getNegatibleCost(Op.getOperand(i), DAG, LegalOperations,
                                         ForCodeSize, Depth + 1);
      if (V == NegatibleCost::Cheaper)
        NewOps[i] = getNegatedExpression(Op.getOperand(i), DAG, LegalOperations,
                                         ForCodeSize, Depth + 1);
    }

    bool NegA = !!NewOps[0];
    bool NegB = !!NewOps[1];
    bool NegC = !!NewOps[2];
    unsigned NewOpc = negateFMAOpcode(Opc, NegA != NegB, NegC, true);

    // Fill in the non-negated ops with the original values.
    for (int i = 0, e = Op.getNumOperands(); i != e; ++i)
      if (!NewOps[i])
        NewOps[i] = Op.getOperand(i);
    return DAG.getNode(NewOpc, SDLoc(Op), VT, NewOps);
  }
  case X86ISD::FRCP:
    return DAG.getNode(Opc, SDLoc(Op), VT,
                       getNegatedExpression(Op.getOperand(0), DAG,
                                            LegalOperations, ForCodeSize,
                                            Depth + 1));
  }

  return TargetLowering::getNegatedExpression(Op, DAG, LegalOperations,
                                              ForCodeSize, Depth);
}

static SDValue lowerX86FPLogicOp(SDNode *N, SelectionDAG &DAG,
                                 const X86Subtarget &Subtarget) {
  MVT VT = N->getSimpleValueType(0);
  // If we have integer vector types available, use the integer opcodes.
  if (!VT.isVector() || !Subtarget.hasSSE2())
    return SDValue();

  SDLoc dl(N);

  unsigned IntBits = VT.getScalarSizeInBits();
  MVT IntSVT = MVT::getIntegerVT(IntBits);
  MVT IntVT = MVT::getVectorVT(IntSVT, VT.getSizeInBits() / IntBits);

  SDValue Op0 = DAG.getBitcast(IntVT, N->getOperand(0));
  SDValue Op1 = DAG.getBitcast(IntVT, N->getOperand(1));
  unsigned IntOpcode;
  switch (N->getOpcode()) {
  default: llvm_unreachable("Unexpected FP logic op");
  case X86ISD::FOR:   IntOpcode = ISD::OR; break;
  case X86ISD::FXOR:  IntOpcode = ISD::XOR; break;
  case X86ISD::FAND:  IntOpcode = ISD::AND; break;
  case X86ISD::FANDN: IntOpcode = X86ISD::ANDNP; break;
  }
  SDValue IntOp = DAG.getNode(IntOpcode, dl, IntVT, Op0, Op1);
  return DAG.getBitcast(VT, IntOp);
}


/// Fold a xor(setcc cond, val), 1 --> setcc (inverted(cond), val)
static SDValue foldXor1SetCC(SDNode *N, SelectionDAG &DAG) {
  if (N->getOpcode() != ISD::XOR)
    return SDValue();

  SDValue LHS = N->getOperand(0);
  if (!isOneConstant(N->getOperand(1)) || LHS->getOpcode() != X86ISD::SETCC)
    return SDValue();

  X86::CondCode NewCC = X86::GetOppositeBranchCondition(
      X86::CondCode(LHS->getConstantOperandVal(0)));
  SDLoc DL(N);
  return getSETCC(NewCC, LHS->getOperand(1), DL, DAG);
}

static SDValue combineXor(SDNode *N, SelectionDAG &DAG,
                          TargetLowering::DAGCombinerInfo &DCI,
                          const X86Subtarget &Subtarget) {
  // If this is SSE1 only convert to FXOR to avoid scalarization.
  if (Subtarget.hasSSE1() && !Subtarget.hasSSE2() &&
      N->getValueType(0) == MVT::v4i32) {
    return DAG.getBitcast(
        MVT::v4i32, DAG.getNode(X86ISD::FXOR, SDLoc(N), MVT::v4f32,
                                DAG.getBitcast(MVT::v4f32, N->getOperand(0)),
                                DAG.getBitcast(MVT::v4f32, N->getOperand(1))));
  }

  if (SDValue Cmp = foldVectorXorShiftIntoCmp(N, DAG, Subtarget))
    return Cmp;

  if (DCI.isBeforeLegalizeOps())
    return SDValue();

  if (SDValue SetCC = foldXor1SetCC(N, DAG))
    return SetCC;

  if (SDValue RV = foldXorTruncShiftIntoCmp(N, DAG))
    return RV;

  if (SDValue FPLogic = convertIntLogicToFPLogic(N, DAG, Subtarget))
    return FPLogic;

  return combineFneg(N, DAG, DCI, Subtarget);
}

static SDValue combineBEXTR(SDNode *N, SelectionDAG &DAG,
                            TargetLowering::DAGCombinerInfo &DCI,
                            const X86Subtarget &Subtarget) {
  EVT VT = N->getValueType(0);
  unsigned NumBits = VT.getSizeInBits();

  // TODO - Constant Folding.

  // Simplify the inputs.
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  APInt DemandedMask(APInt::getAllOnesValue(NumBits));
  if (TLI.SimplifyDemandedBits(SDValue(N, 0), DemandedMask, DCI))
    return SDValue(N, 0);

  return SDValue();
}

static bool isNullFPScalarOrVectorConst(SDValue V) {
  return isNullFPConstant(V) || ISD::isBuildVectorAllZeros(V.getNode());
}

/// If a value is a scalar FP zero or a vector FP zero (potentially including
/// undefined elements), return a zero constant that may be used to fold away
/// that value. In the case of a vector, the returned constant will not contain
/// undefined elements even if the input parameter does. This makes it suitable
/// to be used as a replacement operand with operations (eg, bitwise-and) where
/// an undef should not propagate.
static SDValue getNullFPConstForNullVal(SDValue V, SelectionDAG &DAG,
                                        const X86Subtarget &Subtarget) {
  if (!isNullFPScalarOrVectorConst(V))
    return SDValue();

  if (V.getValueType().isVector())
    return getZeroVector(V.getSimpleValueType(), Subtarget, DAG, SDLoc(V));

  return V;
}

static SDValue combineFAndFNotToFAndn(SDNode *N, SelectionDAG &DAG,
                                      const X86Subtarget &Subtarget) {
  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);
  EVT VT = N->getValueType(0);
  SDLoc DL(N);

  // Vector types are handled in combineANDXORWithAllOnesIntoANDNP().
  if (!((VT == MVT::f32 && Subtarget.hasSSE1()) ||
        (VT == MVT::f64 && Subtarget.hasSSE2()) ||
        (VT == MVT::v4f32 && Subtarget.hasSSE1() && !Subtarget.hasSSE2())))
    return SDValue();

  auto isAllOnesConstantFP = [](SDValue V) {
    if (V.getSimpleValueType().isVector())
      return ISD::isBuildVectorAllOnes(V.getNode());
    auto *C = dyn_cast<ConstantFPSDNode>(V);
    return C && C->getConstantFPValue()->isAllOnesValue();
  };

  // fand (fxor X, -1), Y --> fandn X, Y
  if (N0.getOpcode() == X86ISD::FXOR && isAllOnesConstantFP(N0.getOperand(1)))
    return DAG.getNode(X86ISD::FANDN, DL, VT, N0.getOperand(0), N1);

  // fand X, (fxor Y, -1) --> fandn Y, X
  if (N1.getOpcode() == X86ISD::FXOR && isAllOnesConstantFP(N1.getOperand(1)))
    return DAG.getNode(X86ISD::FANDN, DL, VT, N1.getOperand(0), N0);

  return SDValue();
}

/// Do target-specific dag combines on X86ISD::FAND nodes.
static SDValue combineFAnd(SDNode *N, SelectionDAG &DAG,
                           const X86Subtarget &Subtarget) {
  // FAND(0.0, x) -> 0.0
  if (SDValue V = getNullFPConstForNullVal(N->getOperand(0), DAG, Subtarget))
    return V;

  // FAND(x, 0.0) -> 0.0
  if (SDValue V = getNullFPConstForNullVal(N->getOperand(1), DAG, Subtarget))
    return V;

  if (SDValue V = combineFAndFNotToFAndn(N, DAG, Subtarget))
    return V;

  return lowerX86FPLogicOp(N, DAG, Subtarget);
}

/// Do target-specific dag combines on X86ISD::FANDN nodes.
static SDValue combineFAndn(SDNode *N, SelectionDAG &DAG,
                            const X86Subtarget &Subtarget) {
  // FANDN(0.0, x) -> x
  if (isNullFPScalarOrVectorConst(N->getOperand(0)))
    return N->getOperand(1);

  // FANDN(x, 0.0) -> 0.0
  if (SDValue V = getNullFPConstForNullVal(N->getOperand(1), DAG, Subtarget))
    return V;

  return lowerX86FPLogicOp(N, DAG, Subtarget);
}

/// Do target-specific dag combines on X86ISD::FOR and X86ISD::FXOR nodes.
static SDValue combineFOr(SDNode *N, SelectionDAG &DAG,
                          TargetLowering::DAGCombinerInfo &DCI,
                          const X86Subtarget &Subtarget) {
  assert(N->getOpcode() == X86ISD::FOR || N->getOpcode() == X86ISD::FXOR);

  // F[X]OR(0.0, x) -> x
  if (isNullFPScalarOrVectorConst(N->getOperand(0)))
    return N->getOperand(1);

  // F[X]OR(x, 0.0) -> x
  if (isNullFPScalarOrVectorConst(N->getOperand(1)))
    return N->getOperand(0);

  if (SDValue NewVal = combineFneg(N, DAG, DCI, Subtarget))
    return NewVal;

  return lowerX86FPLogicOp(N, DAG, Subtarget);
}

/// Do target-specific dag combines on X86ISD::FMIN and X86ISD::FMAX nodes.
static SDValue combineFMinFMax(SDNode *N, SelectionDAG &DAG) {
  assert(N->getOpcode() == X86ISD::FMIN || N->getOpcode() == X86ISD::FMAX);

  // FMIN/FMAX are commutative if no NaNs and no negative zeros are allowed.
  if (!DAG.getTarget().Options.NoNaNsFPMath ||
      !DAG.getTarget().Options.NoSignedZerosFPMath)
    return SDValue();

  // If we run in unsafe-math mode, then convert the FMAX and FMIN nodes
  // into FMINC and FMAXC, which are Commutative operations.
  unsigned NewOp = 0;
  switch (N->getOpcode()) {
    default: llvm_unreachable("unknown opcode");
    case X86ISD::FMIN:  NewOp = X86ISD::FMINC; break;
    case X86ISD::FMAX:  NewOp = X86ISD::FMAXC; break;
  }

  return DAG.getNode(NewOp, SDLoc(N), N->getValueType(0),
                     N->getOperand(0), N->getOperand(1));
}

static SDValue combineFMinNumFMaxNum(SDNode *N, SelectionDAG &DAG,
                                     const X86Subtarget &Subtarget) {
  if (Subtarget.useSoftFloat())
    return SDValue();

  const TargetLowering &TLI = DAG.getTargetLoweringInfo();

  EVT VT = N->getValueType(0);
  if (!((Subtarget.hasSSE1() && VT == MVT::f32) ||
        (Subtarget.hasSSE2() && VT == MVT::f64) ||
        (VT.isVector() && TLI.isTypeLegal(VT))))
    return SDValue();

  SDValue Op0 = N->getOperand(0);
  SDValue Op1 = N->getOperand(1);
  SDLoc DL(N);
  auto MinMaxOp = N->getOpcode() == ISD::FMAXNUM ? X86ISD::FMAX : X86ISD::FMIN;

  // If we don't have to respect NaN inputs, this is a direct translation to x86
  // min/max instructions.
  if (DAG.getTarget().Options.NoNaNsFPMath || N->getFlags().hasNoNaNs())
    return DAG.getNode(MinMaxOp, DL, VT, Op0, Op1, N->getFlags());

  // If one of the operands is known non-NaN use the native min/max instructions
  // with the non-NaN input as second operand.
  if (DAG.isKnownNeverNaN(Op1))
    return DAG.getNode(MinMaxOp, DL, VT, Op0, Op1, N->getFlags());
  if (DAG.isKnownNeverNaN(Op0))
    return DAG.getNode(MinMaxOp, DL, VT, Op1, Op0, N->getFlags());

  // If we have to respect NaN inputs, this takes at least 3 instructions.
  // Favor a library call when operating on a scalar and minimizing code size.
  if (!VT.isVector() && DAG.getMachineFunction().getFunction().hasMinSize())
    return SDValue();

  EVT SetCCType = TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
                                         VT);

  // There are 4 possibilities involving NaN inputs, and these are the required
  // outputs:
  //                   Op1
  //               Num     NaN
  //            ----------------
  //       Num  |  Max  |  Op0 |
  // Op0        ----------------
  //       NaN  |  Op1  |  NaN |
  //            ----------------
  //
  // The SSE FP max/min instructions were not designed for this case, but rather
  // to implement:
  //   Min = Op1 < Op0 ? Op1 : Op0
  //   Max = Op1 > Op0 ? Op1 : Op0
  //
  // So they always return Op0 if either input is a NaN. However, we can still
  // use those instructions for fmaxnum by selecting away a NaN input.

  // If either operand is NaN, the 2nd source operand (Op0) is passed through.
  SDValue MinOrMax = DAG.getNode(MinMaxOp, DL, VT, Op1, Op0);
  SDValue IsOp0Nan = DAG.getSetCC(DL, SetCCType, Op0, Op0, ISD::SETUO);

  // If Op0 is a NaN, select Op1. Otherwise, select the max. If both operands
  // are NaN, the NaN value of Op1 is the result.
  return DAG.getSelect(DL, VT, IsOp0Nan, Op1, MinOrMax);
}

static SDValue combineX86INT_TO_FP(SDNode *N, SelectionDAG &DAG,
                                   TargetLowering::DAGCombinerInfo &DCI) {
  EVT VT = N->getValueType(0);
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();

  APInt KnownUndef, KnownZero;
  APInt DemandedElts = APInt::getAllOnesValue(VT.getVectorNumElements());
  if (TLI.SimplifyDemandedVectorElts(SDValue(N, 0), DemandedElts, KnownUndef,
                                     KnownZero, DCI))
    return SDValue(N, 0);

  // Convert a full vector load into vzload when not all bits are needed.
  SDValue In = N->getOperand(0);
  MVT InVT = In.getSimpleValueType();
  if (VT.getVectorNumElements() < InVT.getVectorNumElements() &&
      ISD::isNormalLoad(In.getNode()) && In.hasOneUse()) {
    assert(InVT.is128BitVector() && "Expected 128-bit input vector");
    LoadSDNode *LN = cast<LoadSDNode>(N->getOperand(0));
    // Unless the load is volatile or atomic.
    if (LN->isSimple()) {
      SDLoc dl(N);
      unsigned NumBits = InVT.getScalarSizeInBits() * VT.getVectorNumElements();
      MVT MemVT = MVT::getIntegerVT(NumBits);
      MVT LoadVT = MVT::getVectorVT(MemVT, 128 / NumBits);
      SDVTList Tys = DAG.getVTList(LoadVT, MVT::Other);
      SDValue Ops[] = { LN->getChain(), LN->getBasePtr() };
      SDValue VZLoad = DAG.getMemIntrinsicNode(
          X86ISD::VZEXT_LOAD, dl, Tys, Ops, MemVT, LN->getPointerInfo(),
          LN->getAlign(), LN->getMemOperand()->getFlags());
      SDValue Convert = DAG.getNode(N->getOpcode(), dl, VT,
                                    DAG.getBitcast(InVT, VZLoad));
      DCI.CombineTo(N, Convert);
      DAG.ReplaceAllUsesOfValueWith(SDValue(LN, 1), VZLoad.getValue(1));
      return SDValue(N, 0);
    }
  }

  return SDValue();
}

static SDValue combineCVTP2I_CVTTP2I(SDNode *N, SelectionDAG &DAG,
                                     TargetLowering::DAGCombinerInfo &DCI) {
  // FIXME: Handle strict fp nodes.
  EVT VT = N->getValueType(0);

  // Convert a full vector load into vzload when not all bits are needed.
  SDValue In = N->getOperand(0);
  MVT InVT = In.getSimpleValueType();
  if (VT.getVectorNumElements() < InVT.getVectorNumElements() &&
      ISD::isNormalLoad(In.getNode()) && In.hasOneUse()) {
    assert(InVT.is128BitVector() && "Expected 128-bit input vector");
    LoadSDNode *LN = cast<LoadSDNode>(In);
    // Unless the load is volatile or atomic.
    if (LN->isSimple()) {
      SDLoc dl(N);
      unsigned NumBits = InVT.getScalarSizeInBits() * VT.getVectorNumElements();
      MVT MemVT = MVT::getFloatingPointVT(NumBits);
      MVT LoadVT = MVT::getVectorVT(MemVT, 128 / NumBits);
      SDVTList Tys = DAG.getVTList(LoadVT, MVT::Other);
      SDValue Ops[] = { LN->getChain(), LN->getBasePtr() };
      SDValue VZLoad = DAG.getMemIntrinsicNode(
          X86ISD::VZEXT_LOAD, dl, Tys, Ops, MemVT, LN->getPointerInfo(),
          LN->getAlign(), LN->getMemOperand()->getFlags());
      SDValue Convert = DAG.getNode(N->getOpcode(), dl, VT,
                                    DAG.getBitcast(InVT, VZLoad));
      DCI.CombineTo(N, Convert);
      DAG.ReplaceAllUsesOfValueWith(SDValue(LN, 1), VZLoad.getValue(1));
      return SDValue(N, 0);
    }
  }

  return SDValue();
}

/// Do target-specific dag combines on X86ISD::ANDNP nodes.
static SDValue combineAndnp(SDNode *N, SelectionDAG &DAG,
                            TargetLowering::DAGCombinerInfo &DCI,
                            const X86Subtarget &Subtarget) {
  MVT VT = N->getSimpleValueType(0);

  // ANDNP(0, x) -> x
  if (ISD::isBuildVectorAllZeros(N->getOperand(0).getNode()))
    return N->getOperand(1);

  // ANDNP(x, 0) -> 0
  if (ISD::isBuildVectorAllZeros(N->getOperand(1).getNode()))
    return DAG.getConstant(0, SDLoc(N), VT);

  // Turn ANDNP back to AND if input is inverted.
  if (SDValue Not = IsNOT(N->getOperand(0), DAG))
    return DAG.getNode(ISD::AND, SDLoc(N), VT, DAG.getBitcast(VT, Not),
                       N->getOperand(1));

  // Attempt to recursively combine a bitmask ANDNP with shuffles.
  if (VT.isVector() && (VT.getScalarSizeInBits() % 8) == 0) {
    SDValue Op(N, 0);
    if (SDValue Res = combineX86ShufflesRecursively(Op, DAG, Subtarget))
      return Res;
  }

  return SDValue();
}

static SDValue combineBT(SDNode *N, SelectionDAG &DAG,
                         TargetLowering::DAGCombinerInfo &DCI) {
  SDValue N1 = N->getOperand(1);

  // BT ignores high bits in the bit index operand.
  unsigned BitWidth = N1.getValueSizeInBits();
  APInt DemandedMask = APInt::getLowBitsSet(BitWidth, Log2_32(BitWidth));
  if (DAG.getTargetLoweringInfo().SimplifyDemandedBits(N1, DemandedMask, DCI)) {
    if (N->getOpcode() != ISD::DELETED_NODE)
      DCI.AddToWorklist(N);
    return SDValue(N, 0);
  }

  return SDValue();
}

static SDValue combineCVTPH2PS(SDNode *N, SelectionDAG &DAG,
                               TargetLowering::DAGCombinerInfo &DCI) {
  bool IsStrict = N->getOpcode() == X86ISD::STRICT_CVTPH2PS;
  SDValue Src = N->getOperand(IsStrict ? 1 : 0);

  if (N->getValueType(0) == MVT::v4f32 && Src.getValueType() == MVT::v8i16) {
    APInt KnownUndef, KnownZero;
    const TargetLowering &TLI = DAG.getTargetLoweringInfo();
    APInt DemandedElts = APInt::getLowBitsSet(8, 4);
    if (TLI.SimplifyDemandedVectorElts(Src, DemandedElts, KnownUndef, KnownZero,
                                       DCI)) {
      if (N->getOpcode() != ISD::DELETED_NODE)
        DCI.AddToWorklist(N);
      return SDValue(N, 0);
    }

    // FIXME: Shrink vector loads.
    if (IsStrict)
      return SDValue();

    // Convert a full vector load into vzload when not all bits are needed.
    if (ISD::isNormalLoad(Src.getNode()) && Src.hasOneUse()) {
      LoadSDNode *LN = cast<LoadSDNode>(N->getOperand(0));
      // Unless the load is volatile or atomic.
      if (LN->isSimple()) {
        SDLoc dl(N);
        SDVTList Tys = DAG.getVTList(MVT::v2i64, MVT::Other);
        SDValue Ops[] = { LN->getChain(), LN->getBasePtr() };
        SDValue VZLoad = DAG.getMemIntrinsicNode(
            X86ISD::VZEXT_LOAD, dl, Tys, Ops, MVT::i64, LN->getPointerInfo(),
            LN->getAlign(), LN->getMemOperand()->getFlags());
        SDValue Convert = DAG.getNode(N->getOpcode(), dl, MVT::v4f32,
                                      DAG.getBitcast(MVT::v8i16, VZLoad));
        DCI.CombineTo(N, Convert);
        DAG.ReplaceAllUsesOfValueWith(SDValue(LN, 1), VZLoad.getValue(1));
        return SDValue(N, 0);
      }
    }
  }

  return SDValue();
}

// Try to combine sext_in_reg of a cmov of constants by extending the constants.
static SDValue combineSextInRegCmov(SDNode *N, SelectionDAG &DAG) {
  assert(N->getOpcode() == ISD::SIGN_EXTEND_INREG);

  EVT DstVT = N->getValueType(0);

  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);
  EVT ExtraVT = cast<VTSDNode>(N1)->getVT();

  if (ExtraVT != MVT::i8 && ExtraVT != MVT::i16)
    return SDValue();

  // Look through single use any_extends / truncs.
  SDValue IntermediateBitwidthOp;
  if ((N0.getOpcode() == ISD::ANY_EXTEND || N0.getOpcode() == ISD::TRUNCATE) &&
      N0.hasOneUse()) {
    IntermediateBitwidthOp = N0;
    N0 = N0.getOperand(0);
  }

  // See if we have a single use cmov.
  if (N0.getOpcode() != X86ISD::CMOV || !N0.hasOneUse())
    return SDValue();

  SDValue CMovOp0 = N0.getOperand(0);
  SDValue CMovOp1 = N0.getOperand(1);

  // Make sure both operands are constants.
  if (!isa<ConstantSDNode>(CMovOp0.getNode()) ||
      !isa<ConstantSDNode>(CMovOp1.getNode()))
    return SDValue();

  SDLoc DL(N);

  // If we looked through an any_extend/trunc above, add one to the constants.
  if (IntermediateBitwidthOp) {
    unsigned IntermediateOpc = IntermediateBitwidthOp.getOpcode();
    CMovOp0 = DAG.getNode(IntermediateOpc, DL, DstVT, CMovOp0);
    CMovOp1 = DAG.getNode(IntermediateOpc, DL, DstVT, CMovOp1);
  }

  CMovOp0 = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, DstVT, CMovOp0, N1);
  CMovOp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, DstVT, CMovOp1, N1);

  EVT CMovVT = DstVT;
  // We do not want i16 CMOV's. Promote to i32 and truncate afterwards.
  if (DstVT == MVT::i16) {
    CMovVT = MVT::i32;
    CMovOp0 = DAG.getNode(ISD::ZERO_EXTEND, DL, CMovVT, CMovOp0);
    CMovOp1 = DAG.getNode(ISD::ZERO_EXTEND, DL, CMovVT, CMovOp1);
  }

  SDValue CMov = DAG.getNode(X86ISD::CMOV, DL, CMovVT, CMovOp0, CMovOp1,
                             N0.getOperand(2), N0.getOperand(3));

  if (CMovVT != DstVT)
    CMov = DAG.getNode(ISD::TRUNCATE, DL, DstVT, CMov);

  return CMov;
}

static SDValue combineSignExtendInReg(SDNode *N, SelectionDAG &DAG,
                                      const X86Subtarget &Subtarget) {
  assert(N->getOpcode() == ISD::SIGN_EXTEND_INREG);

  if (SDValue V = combineSextInRegCmov(N, DAG))
    return V;

  EVT VT = N->getValueType(0);
  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);
  EVT ExtraVT = cast<VTSDNode>(N1)->getVT();
  SDLoc dl(N);

  // The SIGN_EXTEND_INREG to v4i64 is expensive operation on the
  // both SSE and AVX2 since there is no sign-extended shift right
  // operation on a vector with 64-bit elements.
  //(sext_in_reg (v4i64 anyext (v4i32 x )), ExtraVT) ->
  // (v4i64 sext (v4i32 sext_in_reg (v4i32 x , ExtraVT)))
  if (VT == MVT::v4i64 && (N0.getOpcode() == ISD::ANY_EXTEND ||
      N0.getOpcode() == ISD::SIGN_EXTEND)) {
    SDValue N00 = N0.getOperand(0);

    // EXTLOAD has a better solution on AVX2,
    // it may be replaced with X86ISD::VSEXT node.
    if (N00.getOpcode() == ISD::LOAD && Subtarget.hasInt256())
      if (!ISD::isNormalLoad(N00.getNode()))
        return SDValue();

    if (N00.getValueType() == MVT::v4i32 && ExtraVT.getSizeInBits() < 128) {
        SDValue Tmp = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, MVT::v4i32,
                                  N00, N1);
      return DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i64, Tmp);
    }
  }
  return SDValue();
}

/// sext(add_nsw(x, C)) --> add(sext(x), C_sext)
/// zext(add_nuw(x, C)) --> add(zext(x), C_zext)
/// Promoting a sign/zero extension ahead of a no overflow 'add' exposes
/// opportunities to combine math ops, use an LEA, or use a complex addressing
/// mode. This can eliminate extend, add, and shift instructions.
static SDValue promoteExtBeforeAdd(SDNode *Ext, SelectionDAG &DAG,
                                   const X86Subtarget &Subtarget) {
  if (Ext->getOpcode() != ISD::SIGN_EXTEND &&
      Ext->getOpcode() != ISD::ZERO_EXTEND)
    return SDValue();

  // TODO: This should be valid for other integer types.
  EVT VT = Ext->getValueType(0);
  if (VT != MVT::i64)
    return SDValue();

  SDValue Add = Ext->getOperand(0);
  if (Add.getOpcode() != ISD::ADD)
    return SDValue();

  bool Sext = Ext->getOpcode() == ISD::SIGN_EXTEND;
  bool NSW = Add->getFlags().hasNoSignedWrap();
  bool NUW = Add->getFlags().hasNoUnsignedWrap();

  // We need an 'add nsw' feeding into the 'sext' or 'add nuw' feeding
  // into the 'zext'
  if ((Sext && !NSW) || (!Sext && !NUW))
    return SDValue();

  // Having a constant operand to the 'add' ensures that we are not increasing
  // the instruction count because the constant is extended for free below.
  // A constant operand can also become the displacement field of an LEA.
  auto *AddOp1 = dyn_cast<ConstantSDNode>(Add.getOperand(1));
  if (!AddOp1)
    return SDValue();

  // Don't make the 'add' bigger if there's no hope of combining it with some
  // other 'add' or 'shl' instruction.
  // TODO: It may be profitable to generate simpler LEA instructions in place
  // of single 'add' instructions, but the cost model for selecting an LEA
  // currently has a high threshold.
  bool HasLEAPotential = false;
  for (auto *User : Ext->uses()) {
    if (User->getOpcode() == ISD::ADD || User->getOpcode() == ISD::SHL) {
      HasLEAPotential = true;
      break;
    }
  }
  if (!HasLEAPotential)
    return SDValue();

  // Everything looks good, so pull the '{s|z}ext' ahead of the 'add'.
  int64_t AddConstant = Sext ? AddOp1->getSExtValue() : AddOp1->getZExtValue();
  SDValue AddOp0 = Add.getOperand(0);
  SDValue NewExt = DAG.getNode(Ext->getOpcode(), SDLoc(Ext), VT, AddOp0);
  SDValue NewConstant = DAG.getConstant(AddConstant, SDLoc(Add), VT);

  // The wider add is guaranteed to not wrap because both operands are
  // sign-extended.
  SDNodeFlags Flags;
  Flags.setNoSignedWrap(NSW);
  Flags.setNoUnsignedWrap(NUW);
  return DAG.getNode(ISD::ADD, SDLoc(Add), VT, NewExt, NewConstant, Flags);
}

// If we face {ANY,SIGN,ZERO}_EXTEND that is applied to a CMOV with constant
// operands and the result of CMOV is not used anywhere else - promote CMOV
// itself instead of promoting its result. This could be beneficial, because:
//     1) X86TargetLowering::EmitLoweredSelect later can do merging of two
//        (or more) pseudo-CMOVs only when they go one-after-another and
//        getting rid of result extension code after CMOV will help that.
//     2) Promotion of constant CMOV arguments is free, hence the
//        {ANY,SIGN,ZERO}_EXTEND will just be deleted.
//     3) 16-bit CMOV encoding is 4 bytes, 32-bit CMOV is 3-byte, so this
//        promotion is also good in terms of code-size.
//        (64-bit CMOV is 4-bytes, that's why we don't do 32-bit => 64-bit
//         promotion).
static SDValue combineToExtendCMOV(SDNode *Extend, SelectionDAG &DAG) {
  SDValue CMovN = Extend->getOperand(0);
  if (CMovN.getOpcode() != X86ISD::CMOV || !CMovN.hasOneUse())
    return SDValue();

  EVT TargetVT = Extend->getValueType(0);
  unsigned ExtendOpcode = Extend->getOpcode();
  SDLoc DL(Extend);

  EVT VT = CMovN.getValueType();
  SDValue CMovOp0 = CMovN.getOperand(0);
  SDValue CMovOp1 = CMovN.getOperand(1);

  if (!isa<ConstantSDNode>(CMovOp0.getNode()) ||
      !isa<ConstantSDNode>(CMovOp1.getNode()))
    return SDValue();

  // Only extend to i32 or i64.
  if (TargetVT != MVT::i32 && TargetVT != MVT::i64)
    return SDValue();

  // Only extend from i16 unless its a sign_extend from i32. Zext/aext from i32
  // are free.
  if (VT != MVT::i16 && !(ExtendOpcode == ISD::SIGN_EXTEND && VT == MVT::i32))
    return SDValue();

  // If this a zero extend to i64, we should only extend to i32 and use a free
  // zero extend to finish.
  EVT ExtendVT = TargetVT;
  if (TargetVT == MVT::i64 && ExtendOpcode != ISD::SIGN_EXTEND)
    ExtendVT = MVT::i32;

  CMovOp0 = DAG.getNode(ExtendOpcode, DL, ExtendVT, CMovOp0);
  CMovOp1 = DAG.getNode(ExtendOpcode, DL, ExtendVT, CMovOp1);

  SDValue Res = DAG.getNode(X86ISD::CMOV, DL, ExtendVT, CMovOp0, CMovOp1,
                            CMovN.getOperand(2), CMovN.getOperand(3));

  // Finish extending if needed.
  if (ExtendVT != TargetVT)
    Res = DAG.getNode(ExtendOpcode, DL, TargetVT, Res);

  return Res;
}

// Convert (vXiY *ext(vXi1 bitcast(iX))) to extend_in_reg(broadcast(iX)).
// This is more or less the reverse of combineBitcastvxi1.
static SDValue
combineToExtendBoolVectorInReg(SDNode *N, SelectionDAG &DAG,
                               TargetLowering::DAGCombinerInfo &DCI,
                               const X86Subtarget &Subtarget) {
  unsigned Opcode = N->getOpcode();
  if (Opcode != ISD::SIGN_EXTEND && Opcode != ISD::ZERO_EXTEND &&
      Opcode != ISD::ANY_EXTEND)
    return SDValue();
  if (!DCI.isBeforeLegalizeOps())
    return SDValue();
  if (!Subtarget.hasSSE2() || Subtarget.hasAVX512())
    return SDValue();

  SDValue N0 = N->getOperand(0);
  EVT VT = N->getValueType(0);
  EVT SVT = VT.getScalarType();
  EVT InSVT = N0.getValueType().getScalarType();
  unsigned EltSizeInBits = SVT.getSizeInBits();

  // Input type must be extending a bool vector (bit-casted from a scalar
  // integer) to legal integer types.
  if (!VT.isVector())
    return SDValue();
  if (SVT != MVT::i64 && SVT != MVT::i32 && SVT != MVT::i16 && SVT != MVT::i8)
    return SDValue();
  if (InSVT != MVT::i1 || N0.getOpcode() != ISD::BITCAST)
    return SDValue();

  SDValue N00 = N0.getOperand(0);
  EVT SclVT = N0.getOperand(0).getValueType();
  if (!SclVT.isScalarInteger())
    return SDValue();

  SDLoc DL(N);
  SDValue Vec;
  SmallVector<int, 32> ShuffleMask;
  unsigned NumElts = VT.getVectorNumElements();
  assert(NumElts == SclVT.getSizeInBits() && "Unexpected bool vector size");

  // Broadcast the scalar integer to the vector elements.
  if (NumElts > EltSizeInBits) {
    // If the scalar integer is greater than the vector element size, then we
    // must split it down into sub-sections for broadcasting. For example:
    //   i16 -> v16i8 (i16 -> v8i16 -> v16i8) with 2 sub-sections.
    //   i32 -> v32i8 (i32 -> v8i32 -> v32i8) with 4 sub-sections.
    assert((NumElts % EltSizeInBits) == 0 && "Unexpected integer scale");
    unsigned Scale = NumElts / EltSizeInBits;
    EVT BroadcastVT =
        EVT::getVectorVT(*DAG.getContext(), SclVT, EltSizeInBits);
    Vec = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, BroadcastVT, N00);
    Vec = DAG.getBitcast(VT, Vec);

    for (unsigned i = 0; i != Scale; ++i)
      ShuffleMask.append(EltSizeInBits, i);
    Vec = DAG.getVectorShuffle(VT, DL, Vec, Vec, ShuffleMask);
  } else if (Subtarget.hasAVX2() && NumElts < EltSizeInBits &&
             (SclVT == MVT::i8 || SclVT == MVT::i16 || SclVT == MVT::i32)) {
    // If we have register broadcast instructions, use the scalar size as the
    // element type for the shuffle. Then cast to the wider element type. The
    // widened bits won't be used, and this might allow the use of a broadcast
    // load.
    assert((EltSizeInBits % NumElts) == 0 && "Unexpected integer scale");
    unsigned Scale = EltSizeInBits / NumElts;
    EVT BroadcastVT =
        EVT::getVectorVT(*DAG.getContext(), SclVT, NumElts * Scale);
    Vec = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, BroadcastVT, N00);
    ShuffleMask.append(NumElts * Scale, 0);
    Vec = DAG.getVectorShuffle(BroadcastVT, DL, Vec, Vec, ShuffleMask);
    Vec = DAG.getBitcast(VT, Vec);
  } else {
    // For smaller scalar integers, we can simply any-extend it to the vector
    // element size (we don't care about the upper bits) and broadcast it to all
    // elements.
    SDValue Scl = DAG.getAnyExtOrTrunc(N00, DL, SVT);
    Vec = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VT, Scl);
    ShuffleMask.append(NumElts, 0);
    Vec = DAG.getVectorShuffle(VT, DL, Vec, Vec, ShuffleMask);
  }

  // Now, mask the relevant bit in each element.
  SmallVector<SDValue, 32> Bits;
  for (unsigned i = 0; i != NumElts; ++i) {
    int BitIdx = (i % EltSizeInBits);
    APInt Bit = APInt::getBitsSet(EltSizeInBits, BitIdx, BitIdx + 1);
    Bits.push_back(DAG.getConstant(Bit, DL, SVT));
  }
  SDValue BitMask = DAG.getBuildVector(VT, DL, Bits);
  Vec = DAG.getNode(ISD::AND, DL, VT, Vec, BitMask);

  // Compare against the bitmask and extend the result.
  EVT CCVT = EVT::getVectorVT(*DAG.getContext(), MVT::i1, NumElts);
  Vec = DAG.getSetCC(DL, CCVT, Vec, BitMask, ISD::SETEQ);
  Vec = DAG.getSExtOrTrunc(Vec, DL, VT);

  // For SEXT, this is now done, otherwise shift the result down for
  // zero-extension.
  if (Opcode == ISD::SIGN_EXTEND)
    return Vec;
  return DAG.getNode(ISD::SRL, DL, VT, Vec,
                     DAG.getConstant(EltSizeInBits - 1, DL, VT));
}

// Attempt to combine a (sext/zext (setcc)) to a setcc with a xmm/ymm/zmm
// result type.
static SDValue combineExtSetcc(SDNode *N, SelectionDAG &DAG,
                               const X86Subtarget &Subtarget) {
  SDValue N0 = N->getOperand(0);
  EVT VT = N->getValueType(0);
  SDLoc dl(N);

  // Only do this combine with AVX512 for vector extends.
  if (!Subtarget.hasAVX512() || !VT.isVector() || N0.getOpcode() != ISD::SETCC)
    return SDValue();

  // Only combine legal element types.
  EVT SVT = VT.getVectorElementType();
  if (SVT != MVT::i8 && SVT != MVT::i16 && SVT != MVT::i32 &&
      SVT != MVT::i64 && SVT != MVT::f32 && SVT != MVT::f64)
    return SDValue();

  // We can only do this if the vector size in 256 bits or less.
  unsigned Size = VT.getSizeInBits();
  if (Size > 256 && Subtarget.useAVX512Regs())
    return SDValue();

  // Don't fold if the condition code can't be handled by PCMPEQ/PCMPGT since
  // that's the only integer compares with we have.
  ISD::CondCode CC = cast<CondCodeSDNode>(N0.getOperand(2))->get();
  if (ISD::isUnsignedIntSetCC(CC))
    return SDValue();

  // Only do this combine if the extension will be fully consumed by the setcc.
  EVT N00VT = N0.getOperand(0).getValueType();
  EVT MatchingVecType = N00VT.changeVectorElementTypeToInteger();
  if (Size != MatchingVecType.getSizeInBits())
    return SDValue();

  SDValue Res = DAG.getSetCC(dl, VT, N0.getOperand(0), N0.getOperand(1), CC);

  if (N->getOpcode() == ISD::ZERO_EXTEND)
    Res = DAG.getZeroExtendInReg(Res, dl, N0.getValueType().getScalarType());

  return Res;
}

static SDValue combineSext(SDNode *N, SelectionDAG &DAG,
                           TargetLowering::DAGCombinerInfo &DCI,
                           const X86Subtarget &Subtarget) {
  SDValue N0 = N->getOperand(0);
  EVT VT = N->getValueType(0);
  EVT InVT = N0.getValueType();
  SDLoc DL(N);

  // (i32 (sext (i8 (x86isd::setcc_carry)))) -> (i32 (x86isd::setcc_carry))
  if (!DCI.isBeforeLegalizeOps() &&
      N0.getOpcode() == X86ISD::SETCC_CARRY) {
    SDValue Setcc = DAG.getNode(X86ISD::SETCC_CARRY, DL, VT, N0->getOperand(0),
                                 N0->getOperand(1));
    bool ReplaceOtherUses = !N0.hasOneUse();
    DCI.CombineTo(N, Setcc);
    // Replace other uses with a truncate of the widened setcc_carry.
    if (ReplaceOtherUses) {
      SDValue Trunc = DAG.getNode(ISD::TRUNCATE, SDLoc(N0),
                                  N0.getValueType(), Setcc);
      DCI.CombineTo(N0.getNode(), Trunc);
    }

    return SDValue(N, 0);
  }

  if (SDValue NewCMov = combineToExtendCMOV(N, DAG))
    return NewCMov;

  if (!DCI.isBeforeLegalizeOps())
    return SDValue();

  if (SDValue V = combineExtSetcc(N, DAG, Subtarget))
    return V;

  if (InVT == MVT::i1 && N0.getOpcode() == ISD::XOR &&
      isAllOnesConstant(N0.getOperand(1)) && N0.hasOneUse()) {
    // Invert and sign-extend a boolean is the same as zero-extend and subtract
    // 1 because 0 becomes -1 and 1 becomes 0. The subtract is efficiently
    // lowered with an LEA or a DEC. This is the same as: select Bool, 0, -1.
    // sext (xor Bool, -1) --> sub (zext Bool), 1
    SDValue Zext = DAG.getNode(ISD::ZERO_EXTEND, DL, VT, N0.getOperand(0));
    return DAG.getNode(ISD::SUB, DL, VT, Zext, DAG.getConstant(1, DL, VT));
  }

  if (SDValue V = combineToExtendBoolVectorInReg(N, DAG, DCI, Subtarget))
    return V;

  if (VT.isVector())
    if (SDValue R = PromoteMaskArithmetic(N, DAG, Subtarget))
      return R;

  if (SDValue NewAdd = promoteExtBeforeAdd(N, DAG, Subtarget))
    return NewAdd;

  return SDValue();
}

static SDValue combineFMA(SDNode *N, SelectionDAG &DAG,
                          TargetLowering::DAGCombinerInfo &DCI,
                          const X86Subtarget &Subtarget) {
  SDLoc dl(N);
  EVT VT = N->getValueType(0);
  bool IsStrict = N->isStrictFPOpcode() || N->isTargetStrictFPOpcode();

  // Let legalize expand this if it isn't a legal type yet.
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  if (!TLI.isTypeLegal(VT))
    return SDValue();

  EVT ScalarVT = VT.getScalarType();
  if ((ScalarVT != MVT::f32 && ScalarVT != MVT::f64) || !Subtarget.hasAnyFMA())
    return SDValue();

  SDValue A = N->getOperand(IsStrict ? 1 : 0);
  SDValue B = N->getOperand(IsStrict ? 2 : 1);
  SDValue C = N->getOperand(IsStrict ? 3 : 2);

  auto invertIfNegative = [&DAG, &TLI, &DCI](SDValue &V) {
    bool CodeSize = DAG.getMachineFunction().getFunction().hasOptSize();
    bool LegalOperations = !DCI.isBeforeLegalizeOps();
    if (TLI.getNegatibleCost(V, DAG, LegalOperations, CodeSize) ==
        TargetLowering::NegatibleCost::Cheaper) {
      V = TLI.getNegatedExpression(V, DAG, LegalOperations, CodeSize);
      return true;
    }
    // Look through extract_vector_elts. If it comes from an FNEG, create a
    // new extract from the FNEG input.
    if (V.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
        isNullConstant(V.getOperand(1))) {
      SDValue Vec = V.getOperand(0);
      if (TLI.getNegatibleCost(Vec, DAG, LegalOperations, CodeSize) ==
          TargetLowering::NegatibleCost::Cheaper) {
        SDValue NegVal =
            TLI.getNegatedExpression(Vec, DAG, LegalOperations, CodeSize);
        V = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(V), V.getValueType(),
                        NegVal, V.getOperand(1));
        return true;
      }
    }

    return false;
  };

  // Do not convert the passthru input of scalar intrinsics.
  // FIXME: We could allow negations of the lower element only.
  bool NegA = invertIfNegative(A);
  bool NegB = invertIfNegative(B);
  bool NegC = invertIfNegative(C);

  if (!NegA && !NegB && !NegC)
    return SDValue();

  unsigned NewOpcode =
      negateFMAOpcode(N->getOpcode(), NegA != NegB, NegC, false);

  if (IsStrict) {
    assert(N->getNumOperands() == 4 && "Shouldn't be greater than 4");
    return DAG.getNode(NewOpcode, dl, {VT, MVT::Other},
                       {N->getOperand(0), A, B, C});
  } else {
    if (N->getNumOperands() == 4)
      return DAG.getNode(NewOpcode, dl, VT, A, B, C, N->getOperand(3));
    return DAG.getNode(NewOpcode, dl, VT, A, B, C);
  }
}

// Combine FMADDSUB(A, B, FNEG(C)) -> FMSUBADD(A, B, C)
// Combine FMSUBADD(A, B, FNEG(C)) -> FMADDSUB(A, B, C)
static SDValue combineFMADDSUB(SDNode *N, SelectionDAG &DAG,
                               TargetLowering::DAGCombinerInfo &DCI) {
  SDLoc dl(N);
  EVT VT = N->getValueType(0);
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  bool CodeSize = DAG.getMachineFunction().getFunction().hasOptSize();
  bool LegalOperations = !DCI.isBeforeLegalizeOps();

  SDValue N2 = N->getOperand(2);
  if (TLI.getNegatibleCost(N2, DAG, LegalOperations, CodeSize) !=
      TargetLowering::NegatibleCost::Cheaper)
    return SDValue();

  SDValue NegN2 = TLI.getNegatedExpression(N2, DAG, LegalOperations, CodeSize);
  unsigned NewOpcode = negateFMAOpcode(N->getOpcode(), false, true, false);

  if (N->getNumOperands() == 4)
    return DAG.getNode(NewOpcode, dl, VT, N->getOperand(0), N->getOperand(1),
                       NegN2, N->getOperand(3));
  return DAG.getNode(NewOpcode, dl, VT, N->getOperand(0), N->getOperand(1),
                     NegN2);
}

static SDValue combineZext(SDNode *N, SelectionDAG &DAG,
                           TargetLowering::DAGCombinerInfo &DCI,
                           const X86Subtarget &Subtarget) {
  SDLoc dl(N);
  SDValue N0 = N->getOperand(0);
  EVT VT = N->getValueType(0);

  // (i32 (aext (i8 (x86isd::setcc_carry)))) -> (i32 (x86isd::setcc_carry))
  // FIXME: Is this needed? We don't seem to have any tests for it.
  if (!DCI.isBeforeLegalizeOps() && N->getOpcode() == ISD::ANY_EXTEND &&
      N0.getOpcode() == X86ISD::SETCC_CARRY) {
    SDValue Setcc = DAG.getNode(X86ISD::SETCC_CARRY, dl, VT, N0->getOperand(0),
                                 N0->getOperand(1));
    bool ReplaceOtherUses = !N0.hasOneUse();
    DCI.CombineTo(N, Setcc);
    // Replace other uses with a truncate of the widened setcc_carry.
    if (ReplaceOtherUses) {
      SDValue Trunc = DAG.getNode(ISD::TRUNCATE, SDLoc(N0),
                                  N0.getValueType(), Setcc);
      DCI.CombineTo(N0.getNode(), Trunc);
    }

    return SDValue(N, 0);
  }

  if (SDValue NewCMov = combineToExtendCMOV(N, DAG))
    return NewCMov;

  if (DCI.isBeforeLegalizeOps())
    if (SDValue V = combineExtSetcc(N, DAG, Subtarget))
      return V;

  if (SDValue V = combineToExtendBoolVectorInReg(N, DAG, DCI, Subtarget))
    return V;

  if (VT.isVector())
    if (SDValue R = PromoteMaskArithmetic(N, DAG, Subtarget))
      return R;

  if (SDValue NewAdd = promoteExtBeforeAdd(N, DAG, Subtarget))
    return NewAdd;

  if (SDValue R = combineOrCmpEqZeroToCtlzSrl(N, DAG, DCI, Subtarget))
    return R;

  // TODO: Combine with any target/faux shuffle.
  if (N0.getOpcode() == X86ISD::PACKUS && N0.getValueSizeInBits() == 128 &&
      VT.getScalarSizeInBits() == N0.getOperand(0).getScalarValueSizeInBits()) {
    SDValue N00 = N0.getOperand(0);
    SDValue N01 = N0.getOperand(1);
    unsigned NumSrcEltBits = N00.getScalarValueSizeInBits();
    APInt ZeroMask = APInt::getHighBitsSet(NumSrcEltBits, NumSrcEltBits / 2);
    if ((N00.isUndef() || DAG.MaskedValueIsZero(N00, ZeroMask)) &&
        (N01.isUndef() || DAG.MaskedValueIsZero(N01, ZeroMask))) {
      return concatSubVectors(N00, N01, DAG, dl);
    }
  }

  return SDValue();
}

/// Recursive helper for combineVectorSizedSetCCEquality() to see if we have a
/// recognizable memcmp expansion.
static bool isOrXorXorTree(SDValue X, bool Root = true) {
  if (X.getOpcode() == ISD::OR)
    return isOrXorXorTree(X.getOperand(0), false) &&
           isOrXorXorTree(X.getOperand(1), false);
  if (Root)
    return false;
  return X.getOpcode() == ISD::XOR;
}

/// Recursive helper for combineVectorSizedSetCCEquality() to emit the memcmp
/// expansion.
template<typename F>
static SDValue emitOrXorXorTree(SDValue X, SDLoc &DL, SelectionDAG &DAG,
                                EVT VecVT, EVT CmpVT, bool HasPT, F SToV) {
  SDValue Op0 = X.getOperand(0);
  SDValue Op1 = X.getOperand(1);
  if (X.getOpcode() == ISD::OR) {
    SDValue A = emitOrXorXorTree(Op0, DL, DAG, VecVT, CmpVT, HasPT, SToV);
    SDValue B = emitOrXorXorTree(Op1, DL, DAG, VecVT, CmpVT, HasPT, SToV);
    if (VecVT != CmpVT)
      return DAG.getNode(ISD::OR, DL, CmpVT, A, B);
    if (HasPT)
      return DAG.getNode(ISD::OR, DL, VecVT, A, B);
    return DAG.getNode(ISD::AND, DL, CmpVT, A, B);
  } else if (X.getOpcode() == ISD::XOR) {
    SDValue A = SToV(Op0);
    SDValue B = SToV(Op1);
    if (VecVT != CmpVT)
      return DAG.getSetCC(DL, CmpVT, A, B, ISD::SETNE);
    if (HasPT)
      return DAG.getNode(ISD::XOR, DL, VecVT, A, B);
    return DAG.getSetCC(DL, CmpVT, A, B, ISD::SETEQ);
  }
  llvm_unreachable("Impossible");
}

/// Try to map a 128-bit or larger integer comparison to vector instructions
/// before type legalization splits it up into chunks.
static SDValue combineVectorSizedSetCCEquality(SDNode *SetCC, SelectionDAG &DAG,
                                               const X86Subtarget &Subtarget) {
  ISD::CondCode CC = cast<CondCodeSDNode>(SetCC->getOperand(2))->get();
  assert((CC == ISD::SETNE || CC == ISD::SETEQ) && "Bad comparison predicate");

  // We're looking for an oversized integer equality comparison.
  SDValue X = SetCC->getOperand(0);
  SDValue Y = SetCC->getOperand(1);
  EVT OpVT = X.getValueType();
  unsigned OpSize = OpVT.getSizeInBits();
  if (!OpVT.isScalarInteger() || OpSize < 128)
    return SDValue();

  // Ignore a comparison with zero because that gets special treatment in
  // EmitTest(). But make an exception for the special case of a pair of
  // logically-combined vector-sized operands compared to zero. This pattern may
  // be generated by the memcmp expansion pass with oversized integer compares
  // (see PR33325).
  bool IsOrXorXorTreeCCZero = isNullConstant(Y) && isOrXorXorTree(X);
  if (isNullConstant(Y) && !IsOrXorXorTreeCCZero)
    return SDValue();

  // Don't perform this combine if constructing the vector will be expensive.
  auto IsVectorBitCastCheap = [](SDValue X) {
    X = peekThroughBitcasts(X);
    return isa<ConstantSDNode>(X) || X.getValueType().isVector() ||
           X.getOpcode() == ISD::LOAD;
  };
  if ((!IsVectorBitCastCheap(X) || !IsVectorBitCastCheap(Y)) &&
      !IsOrXorXorTreeCCZero)
    return SDValue();

  EVT VT = SetCC->getValueType(0);
  SDLoc DL(SetCC);
  bool HasAVX = Subtarget.hasAVX();

  // Use XOR (plus OR) and PTEST after SSE4.1 for 128/256-bit operands.
  // Use PCMPNEQ (plus OR) and KORTEST for 512-bit operands.
  // Otherwise use PCMPEQ (plus AND) and mask testing.
  if ((OpSize == 128 && Subtarget.hasSSE2()) ||
      (OpSize == 256 && HasAVX) ||
      (OpSize == 512 && Subtarget.useAVX512Regs())) {
    bool HasPT = Subtarget.hasSSE41();

    // PTEST and MOVMSK are slow on Knights Landing and Knights Mill and widened
    // vector registers are essentially free. (Technically, widening registers
    // prevents load folding, but the tradeoff is worth it.)
    bool PreferKOT = Subtarget.preferMaskRegisters();
    bool NeedZExt = PreferKOT && !Subtarget.hasVLX() && OpSize != 512;

    EVT VecVT = MVT::v16i8;
    EVT CmpVT = PreferKOT ? MVT::v16i1 : VecVT;
    if (OpSize == 256) {
      VecVT = MVT::v32i8;
      CmpVT = PreferKOT ? MVT::v32i1 : VecVT;
    }
    EVT CastVT = VecVT;
    bool NeedsAVX512FCast = false;
    if (OpSize == 512 || NeedZExt) {
      if (Subtarget.hasBWI()) {
        VecVT = MVT::v64i8;
        CmpVT = MVT::v64i1;
        if (OpSize == 512)
          CastVT = VecVT;
      } else {
        VecVT = MVT::v16i32;
        CmpVT = MVT::v16i1;
        CastVT = OpSize == 512 ? VecVT :
                 OpSize == 256 ? MVT::v8i32 : MVT::v4i32;
        NeedsAVX512FCast = true;
      }
    }

    auto ScalarToVector = [&](SDValue X) -> SDValue {
      bool TmpZext = false;
      EVT TmpCastVT = CastVT;
      if (X.getOpcode() == ISD::ZERO_EXTEND) {
        SDValue OrigX = X.getOperand(0);
        unsigned OrigSize = OrigX.getScalarValueSizeInBits();
        if (OrigSize < OpSize) {
          if (OrigSize == 128) {
            TmpCastVT = NeedsAVX512FCast ? MVT::v4i32 : MVT::v16i8;
            X = OrigX;
            TmpZext = true;
          } else if (OrigSize == 256) {
            TmpCastVT = NeedsAVX512FCast ? MVT::v8i32 : MVT::v32i8;
            X = OrigX;
            TmpZext = true;
          }
        }
      }
      X = DAG.getBitcast(TmpCastVT, X);
      if (!NeedZExt && !TmpZext)
        return X;
      return DAG.getNode(ISD::INSERT_SUBVECTOR, DL, VecVT,
                         DAG.getConstant(0, DL, VecVT), X,
                         DAG.getVectorIdxConstant(0, DL));
    };

    SDValue Cmp;
    if (IsOrXorXorTreeCCZero) {
      // This is a bitwise-combined equality comparison of 2 pairs of vectors:
      // setcc i128 (or (xor A, B), (xor C, D)), 0, eq|ne
      // Use 2 vector equality compares and 'and' the results before doing a
      // MOVMSK.
      Cmp = emitOrXorXorTree(X, DL, DAG, VecVT, CmpVT, HasPT, ScalarToVector);
    } else {
      SDValue VecX = ScalarToVector(X);
      SDValue VecY = ScalarToVector(Y);
      if (VecVT != CmpVT) {
        Cmp = DAG.getSetCC(DL, CmpVT, VecX, VecY, ISD::SETNE);
      } else if (HasPT) {
        Cmp = DAG.getNode(ISD::XOR, DL, VecVT, VecX, VecY);
      } else {
        Cmp = DAG.getSetCC(DL, CmpVT, VecX, VecY, ISD::SETEQ);
      }
    }
    // AVX512 should emit a setcc that will lower to kortest.
    if (VecVT != CmpVT) {
      EVT KRegVT = CmpVT == MVT::v64i1 ? MVT::i64 :
                   CmpVT == MVT::v32i1 ? MVT::i32 : MVT::i16;
      return DAG.getSetCC(DL, VT, DAG.getBitcast(KRegVT, Cmp),
                          DAG.getConstant(0, DL, KRegVT), CC);
    }
    if (HasPT) {
      SDValue BCCmp = DAG.getBitcast(OpSize == 256 ? MVT::v4i64 : MVT::v2i64,
                                     Cmp);
      SDValue PT = DAG.getNode(X86ISD::PTEST, DL, MVT::i32, BCCmp, BCCmp);
      X86::CondCode X86CC = CC == ISD::SETEQ ? X86::COND_E : X86::COND_NE;
      SDValue X86SetCC = getSETCC(X86CC, PT, DL, DAG);
      return DAG.getNode(ISD::TRUNCATE, DL, VT, X86SetCC.getValue(0));
    }
    // If all bytes match (bitmask is 0x(FFFF)FFFF), that's equality.
    // setcc i128 X, Y, eq --> setcc (pmovmskb (pcmpeqb X, Y)), 0xFFFF, eq
    // setcc i128 X, Y, ne --> setcc (pmovmskb (pcmpeqb X, Y)), 0xFFFF, ne
    // setcc i256 X, Y, eq --> setcc (vpmovmskb (vpcmpeqb X, Y)), 0xFFFFFFFF, eq
    // setcc i256 X, Y, ne --> setcc (vpmovmskb (vpcmpeqb X, Y)), 0xFFFFFFFF, ne
    SDValue MovMsk = DAG.getNode(X86ISD::MOVMSK, DL, MVT::i32, Cmp);
    SDValue FFFFs = DAG.getConstant(OpSize == 128 ? 0xFFFF : 0xFFFFFFFF, DL,
                                    MVT::i32);
    return DAG.getSetCC(DL, VT, MovMsk, FFFFs, CC);
  }

  return SDValue();
}

static SDValue combineSetCC(SDNode *N, SelectionDAG &DAG,
                            const X86Subtarget &Subtarget) {
  const ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
  const SDValue LHS = N->getOperand(0);
  const SDValue RHS = N->getOperand(1);
  EVT VT = N->getValueType(0);
  EVT OpVT = LHS.getValueType();
  SDLoc DL(N);

  if (CC == ISD::SETNE || CC == ISD::SETEQ) {
    if (SDValue V = combineVectorSizedSetCCEquality(N, DAG, Subtarget))
      return V;
  }

  if (VT.isVector() && VT.getVectorElementType() == MVT::i1 &&
      (CC == ISD::SETNE || CC == ISD::SETEQ || ISD::isSignedIntSetCC(CC))) {
    // Using temporaries to avoid messing up operand ordering for later
    // transformations if this doesn't work.
    SDValue Op0 = LHS;
    SDValue Op1 = RHS;
    ISD::CondCode TmpCC = CC;
    // Put build_vector on the right.
    if (Op0.getOpcode() == ISD::BUILD_VECTOR) {
      std::swap(Op0, Op1);
      TmpCC = ISD::getSetCCSwappedOperands(TmpCC);
    }

    bool IsSEXT0 =
        (Op0.getOpcode() == ISD::SIGN_EXTEND) &&
        (Op0.getOperand(0).getValueType().getVectorElementType() == MVT::i1);
    bool IsVZero1 = ISD::isBuildVectorAllZeros(Op1.getNode());

    if (IsSEXT0 && IsVZero1) {
      assert(VT == Op0.getOperand(0).getValueType() &&
             "Uexpected operand type");
      if (TmpCC == ISD::SETGT)
        return DAG.getConstant(0, DL, VT);
      if (TmpCC == ISD::SETLE)
        return DAG.getConstant(1, DL, VT);
      if (TmpCC == ISD::SETEQ || TmpCC == ISD::SETGE)
        return DAG.getNOT(DL, Op0.getOperand(0), VT);

      assert((TmpCC == ISD::SETNE || TmpCC == ISD::SETLT) &&
             "Unexpected condition code!");
      return Op0.getOperand(0);
    }
  }

  // If we have AVX512, but not BWI and this is a vXi16/vXi8 setcc, just
  // pre-promote its result type since vXi1 vectors don't get promoted
  // during type legalization.
  // NOTE: The element count check is to ignore operand types that need to
  // go through type promotion to a 128-bit vector.
  if (Subtarget.hasAVX512() && !Subtarget.hasBWI() && VT.isVector() &&
      VT.getVectorElementType() == MVT::i1 &&
      (OpVT.getVectorElementType() == MVT::i8 ||
       OpVT.getVectorElementType() == MVT::i16)) {
    SDValue Setcc = DAG.getSetCC(DL, OpVT, LHS, RHS, CC);
    return DAG.getNode(ISD::TRUNCATE, DL, VT, Setcc);
  }

  // For an SSE1-only target, lower a comparison of v4f32 to X86ISD::CMPP early
  // to avoid scalarization via legalization because v4i32 is not a legal type.
  if (Subtarget.hasSSE1() && !Subtarget.hasSSE2() && VT == MVT::v4i32 &&
      LHS.getValueType() == MVT::v4f32)
    return LowerVSETCC(SDValue(N, 0), Subtarget, DAG);

  return SDValue();
}

static SDValue combineMOVMSK(SDNode *N, SelectionDAG &DAG,
                             TargetLowering::DAGCombinerInfo &DCI,
                             const X86Subtarget &Subtarget) {
  SDValue Src = N->getOperand(0);
  MVT SrcVT = Src.getSimpleValueType();
  MVT VT = N->getSimpleValueType(0);
  unsigned NumBits = VT.getScalarSizeInBits();
  unsigned NumElts = SrcVT.getVectorNumElements();

  // Perform constant folding.
  if (ISD::isBuildVectorOfConstantSDNodes(Src.getNode())) {
    assert(VT == MVT::i32 && "Unexpected result type");
    APInt Imm(32, 0);
    for (unsigned Idx = 0, e = Src.getNumOperands(); Idx < e; ++Idx) {
      if (!Src.getOperand(Idx).isUndef() &&
          Src.getConstantOperandAPInt(Idx).isNegative())
        Imm.setBit(Idx);
    }
    return DAG.getConstant(Imm, SDLoc(N), VT);
  }

  // Look through int->fp bitcasts that don't change the element width.
  unsigned EltWidth = SrcVT.getScalarSizeInBits();
  if (Subtarget.hasSSE2() && Src.getOpcode() == ISD::BITCAST &&
      Src.getOperand(0).getScalarValueSizeInBits() == EltWidth)
    return DAG.getNode(X86ISD::MOVMSK, SDLoc(N), VT, Src.getOperand(0));

  // Fold movmsk(not(x)) -> not(movmsk) to improve folding of movmsk results
  // with scalar comparisons.
  if (SDValue NotSrc = IsNOT(Src, DAG)) {
    SDLoc DL(N);
    APInt NotMask = APInt::getLowBitsSet(NumBits, NumElts);
    NotSrc = DAG.getBitcast(SrcVT, NotSrc);
    return DAG.getNode(ISD::XOR, DL, VT,
                       DAG.getNode(X86ISD::MOVMSK, DL, VT, NotSrc),
                       DAG.getConstant(NotMask, DL, VT));
  }

  // Simplify the inputs.
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  APInt DemandedMask(APInt::getAllOnesValue(NumBits));
  if (TLI.SimplifyDemandedBits(SDValue(N, 0), DemandedMask, DCI))
    return SDValue(N, 0);

  return SDValue();
}

static SDValue combineX86GatherScatter(SDNode *N, SelectionDAG &DAG,
                                       TargetLowering::DAGCombinerInfo &DCI) {
  // With vector masks we only demand the upper bit of the mask.
  SDValue Mask = cast<X86MaskedGatherScatterSDNode>(N)->getMask();
  if (Mask.getScalarValueSizeInBits() != 1) {
    const TargetLowering &TLI = DAG.getTargetLoweringInfo();
    APInt DemandedMask(APInt::getSignMask(Mask.getScalarValueSizeInBits()));
    if (TLI.SimplifyDemandedBits(Mask, DemandedMask, DCI)) {
      if (N->getOpcode() != ISD::DELETED_NODE)
        DCI.AddToWorklist(N);
      return SDValue(N, 0);
    }
  }

  return SDValue();
}

static SDValue rebuildGatherScatter(MaskedGatherScatterSDNode *GorS,
                                    SDValue Index, SDValue Base, SDValue Scale,
                                    SelectionDAG &DAG) {
  SDLoc DL(GorS);

  if (auto *Gather = dyn_cast<MaskedGatherSDNode>(GorS)) {
    SDValue Ops[] = { Gather->getChain(), Gather->getPassThru(),
                      Gather->getMask(), Base, Index, Scale } ;
    return DAG.getMaskedGather(Gather->getVTList(),
                               Gather->getMemoryVT(), DL, Ops,
                               Gather->getMemOperand(),
                               Gather->getIndexType());
  }
  auto *Scatter = cast<MaskedScatterSDNode>(GorS);
  SDValue Ops[] = { Scatter->getChain(), Scatter->getValue(),
                    Scatter->getMask(), Base, Index, Scale };
  return DAG.getMaskedScatter(Scatter->getVTList(),
                              Scatter->getMemoryVT(), DL,
                              Ops, Scatter->getMemOperand(),
                              Scatter->getIndexType());
}

static SDValue combineGatherScatter(SDNode *N, SelectionDAG &DAG,
                                    TargetLowering::DAGCombinerInfo &DCI) {
  SDLoc DL(N);
  auto *GorS = cast<MaskedGatherScatterSDNode>(N);
  SDValue Index = GorS->getIndex();
  SDValue Base = GorS->getBasePtr();
  SDValue Scale = GorS->getScale();

  if (DCI.isBeforeLegalize()) {
    unsigned IndexWidth = Index.getScalarValueSizeInBits();

    // Shrink constant indices if they are larger than 32-bits.
    // Only do this before legalize types since v2i64 could become v2i32.
    // FIXME: We could check that the type is legal if we're after legalize
    // types, but then we would need to construct test cases where that happens.
    // FIXME: We could support more than just constant vectors, but we need to
    // careful with costing. A truncate that can be optimized out would be fine.
    // Otherwise we might only want to create a truncate if it avoids a split.
    if (auto *BV = dyn_cast<BuildVectorSDNode>(Index)) {
      if (BV->isConstant() && IndexWidth > 32 &&
          DAG.ComputeNumSignBits(Index) > (IndexWidth - 32)) {
        unsigned NumElts = Index.getValueType().getVectorNumElements();
        EVT NewVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32, NumElts);
        Index = DAG.getNode(ISD::TRUNCATE, DL, NewVT, Index);
        return rebuildGatherScatter(GorS, Index, Base, Scale, DAG);
      }
    }

    // Shrink any sign/zero extends from 32 or smaller to larger than 32 if
    // there are sufficient sign bits. Only do this before legalize types to
    // avoid creating illegal types in truncate.
    if ((Index.getOpcode() == ISD::SIGN_EXTEND ||
         Index.getOpcode() == ISD::ZERO_EXTEND) &&
        IndexWidth > 32 &&
        Index.getOperand(0).getScalarValueSizeInBits() <= 32 &&
        DAG.ComputeNumSignBits(Index) > (IndexWidth - 32)) {
      unsigned NumElts = Index.getValueType().getVectorNumElements();
      EVT NewVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32, NumElts);
      Index = DAG.getNode(ISD::TRUNCATE, DL, NewVT, Index);
      return rebuildGatherScatter(GorS, Index, Base, Scale, DAG);
    }
  }

  if (DCI.isBeforeLegalizeOps()) {
    unsigned IndexWidth = Index.getScalarValueSizeInBits();

    // Make sure the index is either i32 or i64
    if (IndexWidth != 32 && IndexWidth != 64) {
      MVT EltVT = IndexWidth > 32 ? MVT::i64 : MVT::i32;
      EVT IndexVT = EVT::getVectorVT(*DAG.getContext(), EltVT,
                                   Index.getValueType().getVectorNumElements());
      Index = DAG.getSExtOrTrunc(Index, DL, IndexVT);
      return rebuildGatherScatter(GorS, Index, Base, Scale, DAG);
    }
  }

  // With vector masks we only demand the upper bit of the mask.
  SDValue Mask = GorS->getMask();
  if (Mask.getScalarValueSizeInBits() != 1) {
    const TargetLowering &TLI = DAG.getTargetLoweringInfo();
    APInt DemandedMask(APInt::getSignMask(Mask.getScalarValueSizeInBits()));
    if (TLI.SimplifyDemandedBits(Mask, DemandedMask, DCI)) {
      if (N->getOpcode() != ISD::DELETED_NODE)
        DCI.AddToWorklist(N);
      return SDValue(N, 0);
    }
  }

  return SDValue();
}

// Optimize  RES = X86ISD::SETCC CONDCODE, EFLAG_INPUT
static SDValue combineX86SetCC(SDNode *N, SelectionDAG &DAG,
                               const X86Subtarget &Subtarget) {
  SDLoc DL(N);
  X86::CondCode CC = X86::CondCode(N->getConstantOperandVal(0));
  SDValue EFLAGS = N->getOperand(1);

  // Try to simplify the EFLAGS and condition code operands.
  if (SDValue Flags = combineSetCCEFLAGS(EFLAGS, CC, DAG, Subtarget))
    return getSETCC(CC, Flags, DL, DAG);

  return SDValue();
}

/// Optimize branch condition evaluation.
static SDValue combineBrCond(SDNode *N, SelectionDAG &DAG,
                             const X86Subtarget &Subtarget) {
  SDLoc DL(N);
  SDValue EFLAGS = N->getOperand(3);
  X86::CondCode CC = X86::CondCode(N->getConstantOperandVal(2));

  // Try to simplify the EFLAGS and condition code operands.
  // Make sure to not keep references to operands, as combineSetCCEFLAGS can
  // RAUW them under us.
  if (SDValue Flags = combineSetCCEFLAGS(EFLAGS, CC, DAG, Subtarget)) {
    SDValue Cond = DAG.getTargetConstant(CC, DL, MVT::i8);
    return DAG.getNode(X86ISD::BRCOND, DL, N->getVTList(), N->getOperand(0),
                       N->getOperand(1), Cond, Flags);
  }

  return SDValue();
}

static SDValue combineVectorCompareAndMaskUnaryOp(SDNode *N,
                                                  SelectionDAG &DAG) {
  // Take advantage of vector comparisons producing 0 or -1 in each lane to
  // optimize away operation when it's from a constant.
  //
  // The general transformation is:
  //    UNARYOP(AND(VECTOR_CMP(x,y), constant)) -->
  //       AND(VECTOR_CMP(x,y), constant2)
  //    constant2 = UNARYOP(constant)

  // Early exit if this isn't a vector operation, the operand of the
  // unary operation isn't a bitwise AND, or if the sizes of the operations
  // aren't the same.
  EVT VT = N->getValueType(0);
  bool IsStrict = N->isStrictFPOpcode();
  SDValue Op0 = N->getOperand(IsStrict ? 1 : 0);
  if (!VT.isVector() || Op0->getOpcode() != ISD::AND ||
      Op0->getOperand(0)->getOpcode() != ISD::SETCC ||
      VT.getSizeInBits() != Op0.getValueSizeInBits())
    return SDValue();

  // Now check that the other operand of the AND is a constant. We could
  // make the transformation for non-constant splats as well, but it's unclear
  // that would be a benefit as it would not eliminate any operations, just
  // perform one more step in scalar code before moving to the vector unit.
  if (auto *BV = dyn_cast<BuildVectorSDNode>(Op0.getOperand(1))) {
    // Bail out if the vector isn't a constant.
    if (!BV->isConstant())
      return SDValue();

    // Everything checks out. Build up the new and improved node.
    SDLoc DL(N);
    EVT IntVT = BV->getValueType(0);
    // Create a new constant of the appropriate type for the transformed
    // DAG.
    SDValue SourceConst;
    if (IsStrict)
      SourceConst = DAG.getNode(N->getOpcode(), DL, {VT, MVT::Other},
                                {N->getOperand(0), SDValue(BV, 0)});
    else
      SourceConst = DAG.getNode(N->getOpcode(), DL, VT, SDValue(BV, 0));
    // The AND node needs bitcasts to/from an integer vector type around it.
    SDValue MaskConst = DAG.getBitcast(IntVT, SourceConst);
    SDValue NewAnd = DAG.getNode(ISD::AND, DL, IntVT, Op0->getOperand(0),
                                 MaskConst);
    SDValue Res = DAG.getBitcast(VT, NewAnd);
    if (IsStrict)
      return DAG.getMergeValues({Res, SourceConst.getValue(1)}, DL);
    return Res;
  }

  return SDValue();
}

/// If we are converting a value to floating-point, try to replace scalar
/// truncate of an extracted vector element with a bitcast. This tries to keep
/// the sequence on XMM registers rather than moving between vector and GPRs.
static SDValue combineToFPTruncExtElt(SDNode *N, SelectionDAG &DAG) {
  // TODO: This is currently only used by combineSIntToFP, but it is generalized
  //       to allow being called by any similar cast opcode.
  // TODO: Consider merging this into lowering: vectorizeExtractedCast().
  SDValue Trunc = N->getOperand(0);
  if (!Trunc.hasOneUse() || Trunc.getOpcode() != ISD::TRUNCATE)
    return SDValue();

  SDValue ExtElt = Trunc.getOperand(0);
  if (!ExtElt.hasOneUse() || ExtElt.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
      !isNullConstant(ExtElt.getOperand(1)))
    return SDValue();

  EVT TruncVT = Trunc.getValueType();
  EVT SrcVT = ExtElt.getValueType();
  unsigned DestWidth = TruncVT.getSizeInBits();
  unsigned SrcWidth = SrcVT.getSizeInBits();
  if (SrcWidth % DestWidth != 0)
    return SDValue();

  // inttofp (trunc (extelt X, 0)) --> inttofp (extelt (bitcast X), 0)
  EVT SrcVecVT = ExtElt.getOperand(0).getValueType();
  unsigned VecWidth = SrcVecVT.getSizeInBits();
  unsigned NumElts = VecWidth / DestWidth;
  EVT BitcastVT = EVT::getVectorVT(*DAG.getContext(), TruncVT, NumElts);
  SDValue BitcastVec = DAG.getBitcast(BitcastVT, ExtElt.getOperand(0));
  SDLoc DL(N);
  SDValue NewExtElt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, TruncVT,
                                  BitcastVec, ExtElt.getOperand(1));
  return DAG.getNode(N->getOpcode(), DL, N->getValueType(0), NewExtElt);
}

static SDValue combineUIntToFP(SDNode *N, SelectionDAG &DAG,
                               const X86Subtarget &Subtarget) {
  bool IsStrict = N->isStrictFPOpcode();
  SDValue Op0 = N->getOperand(IsStrict ? 1 : 0);
  EVT VT = N->getValueType(0);
  EVT InVT = Op0.getValueType();

  // UINT_TO_FP(vXi1) -> SINT_TO_FP(ZEXT(vXi1 to vXi32))
  // UINT_TO_FP(vXi8) -> SINT_TO_FP(ZEXT(vXi8 to vXi32))
  // UINT_TO_FP(vXi16) -> SINT_TO_FP(ZEXT(vXi16 to vXi32))
  if (InVT.isVector() && InVT.getScalarSizeInBits() < 32) {
    SDLoc dl(N);
    EVT DstVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32,
                                 InVT.getVectorNumElements());
    SDValue P = DAG.getNode(ISD::ZERO_EXTEND, dl, DstVT, Op0);

    // UINT_TO_FP isn't legal without AVX512 so use SINT_TO_FP.
    if (IsStrict)
      return DAG.getNode(ISD::STRICT_SINT_TO_FP, dl, {VT, MVT::Other},
                         {N->getOperand(0), P});
    return DAG.getNode(ISD::SINT_TO_FP, dl, VT, P);
  }

  // Since UINT_TO_FP is legal (it's marked custom), dag combiner won't
  // optimize it to a SINT_TO_FP when the sign bit is known zero. Perform
  // the optimization here.
  if (DAG.SignBitIsZero(Op0)) {
    if (IsStrict)
      return DAG.getNode(ISD::STRICT_SINT_TO_FP, SDLoc(N), {VT, MVT::Other},
                         {N->getOperand(0), Op0});
    return DAG.getNode(ISD::SINT_TO_FP, SDLoc(N), VT, Op0);
  }

  return SDValue();
}

static SDValue combineSIntToFP(SDNode *N, SelectionDAG &DAG,
                               TargetLowering::DAGCombinerInfo &DCI,
                               const X86Subtarget &Subtarget) {
  // First try to optimize away the conversion entirely when it's
  // conditionally from a constant. Vectors only.
  bool IsStrict = N->isStrictFPOpcode();
  if (SDValue Res = combineVectorCompareAndMaskUnaryOp(N, DAG))
    return Res;

  // Now move on to more general possibilities.
  SDValue Op0 = N->getOperand(IsStrict ? 1 : 0);
  EVT VT = N->getValueType(0);
  EVT InVT = Op0.getValueType();

  // SINT_TO_FP(vXi1) -> SINT_TO_FP(SEXT(vXi1 to vXi32))
  // SINT_TO_FP(vXi8) -> SINT_TO_FP(SEXT(vXi8 to vXi32))
  // SINT_TO_FP(vXi16) -> SINT_TO_FP(SEXT(vXi16 to vXi32))
  if (InVT.isVector() && InVT.getScalarSizeInBits() < 32) {
    SDLoc dl(N);
    EVT DstVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32,
                                 InVT.getVectorNumElements());
    SDValue P = DAG.getNode(ISD::SIGN_EXTEND, dl, DstVT, Op0);
    if (IsStrict)
      return DAG.getNode(ISD::STRICT_SINT_TO_FP, dl, {VT, MVT::Other},
                         {N->getOperand(0), P});
    return DAG.getNode(ISD::SINT_TO_FP, dl, VT, P);
  }

  // Without AVX512DQ we only support i64 to float scalar conversion. For both
  // vectors and scalars, see if we know that the upper bits are all the sign
  // bit, in which case we can truncate the input to i32 and convert from that.
  if (InVT.getScalarSizeInBits() > 32 && !Subtarget.hasDQI()) {
    unsigned BitWidth = InVT.getScalarSizeInBits();
    unsigned NumSignBits = DAG.ComputeNumSignBits(Op0);
    if (NumSignBits >= (BitWidth - 31)) {
      EVT TruncVT = MVT::i32;
      if (InVT.isVector())
        TruncVT = EVT::getVectorVT(*DAG.getContext(), TruncVT,
                                   InVT.getVectorNumElements());
      SDLoc dl(N);
      if (DCI.isBeforeLegalize() || TruncVT != MVT::v2i32) {
        SDValue Trunc = DAG.getNode(ISD::TRUNCATE, dl, TruncVT, Op0);
        if (IsStrict)
          return DAG.getNode(ISD::STRICT_SINT_TO_FP, dl, {VT, MVT::Other},
                             {N->getOperand(0), Trunc});
        return DAG.getNode(ISD::SINT_TO_FP, dl, VT, Trunc);
      }
      // If we're after legalize and the type is v2i32 we need to shuffle and
      // use CVTSI2P.
      assert(InVT == MVT::v2i64 && "Unexpected VT!");
      SDValue Cast = DAG.getBitcast(MVT::v4i32, Op0);
      SDValue Shuf = DAG.getVectorShuffle(MVT::v4i32, dl, Cast, Cast,
                                          { 0, 2, -1, -1 });
      if (IsStrict)
        return DAG.getNode(X86ISD::STRICT_CVTSI2P, dl, {VT, MVT::Other},
                           {N->getOperand(0), Shuf});
      return DAG.getNode(X86ISD::CVTSI2P, dl, VT, Shuf);
    }
  }

  // Transform (SINT_TO_FP (i64 ...)) into an x87 operation if we have
  // a 32-bit target where SSE doesn't support i64->FP operations.
  if (!Subtarget.useSoftFloat() && Subtarget.hasX87() &&
      Op0.getOpcode() == ISD::LOAD) {
    LoadSDNode *Ld = cast<LoadSDNode>(Op0.getNode());

    // This transformation is not supported if the result type is f16 or f128.
    if (VT == MVT::f16 || VT == MVT::f128)
      return SDValue();

    // If we have AVX512DQ we can use packed conversion instructions unless
    // the VT is f80.
    if (Subtarget.hasDQI() && VT != MVT::f80)
      return SDValue();

    if (Ld->isSimple() && !VT.isVector() && ISD::isNormalLoad(Op0.getNode()) &&
        Op0.hasOneUse() && !Subtarget.is64Bit() && InVT == MVT::i64) {
      std::pair<SDValue, SDValue> Tmp =
          Subtarget.getTargetLowering()->BuildFILD(
              VT, InVT, SDLoc(N), Ld->getChain(), Ld->getBasePtr(),
              Ld->getPointerInfo(), Ld->getAlign(), DAG);
      DAG.ReplaceAllUsesOfValueWith(Op0.getValue(1), Tmp.second);
      return Tmp.first;
    }
  }

  if (IsStrict)
    return SDValue();

  if (SDValue V = combineToFPTruncExtElt(N, DAG))
    return V;

  return SDValue();
}

static bool needCarryOrOverflowFlag(SDValue Flags) {
  assert(Flags.getValueType() == MVT::i32 && "Unexpected VT!");

  for (SDNode::use_iterator UI = Flags->use_begin(), UE = Flags->use_end();
         UI != UE; ++UI) {
    SDNode *User = *UI;

    X86::CondCode CC;
    switch (User->getOpcode()) {
    default:
      // Be conservative.
      return true;
    case X86ISD::SETCC:
    case X86ISD::SETCC_CARRY:
      CC = (X86::CondCode)User->getConstantOperandVal(0);
      break;
    case X86ISD::BRCOND:
      CC = (X86::CondCode)User->getConstantOperandVal(2);
      break;
    case X86ISD::CMOV:
      CC = (X86::CondCode)User->getConstantOperandVal(2);
      break;
    }

    switch (CC) {
    default: break;
    case X86::COND_A: case X86::COND_AE:
    case X86::COND_B: case X86::COND_BE:
    case X86::COND_O: case X86::COND_NO:
    case X86::COND_G: case X86::COND_GE:
    case X86::COND_L: case X86::COND_LE:
      return true;
    }
  }

  return false;
}

static bool onlyZeroFlagUsed(SDValue Flags) {
  assert(Flags.getValueType() == MVT::i32 && "Unexpected VT!");

  for (SDNode::use_iterator UI = Flags->use_begin(), UE = Flags->use_end();
         UI != UE; ++UI) {
    SDNode *User = *UI;

    unsigned CCOpNo;
    switch (User->getOpcode()) {
    default:
      // Be conservative.
      return false;
    case X86ISD::SETCC:       CCOpNo = 0; break;
    case X86ISD::SETCC_CARRY: CCOpNo = 0; break;
    case X86ISD::BRCOND:      CCOpNo = 2; break;
    case X86ISD::CMOV:        CCOpNo = 2; break;
    }

    X86::CondCode CC = (X86::CondCode)User->getConstantOperandVal(CCOpNo);
    if (CC != X86::COND_E && CC != X86::COND_NE)
      return false;
  }

  return true;
}

static SDValue combineCMP(SDNode *N, SelectionDAG &DAG) {
  // Only handle test patterns.
  if (!isNullConstant(N->getOperand(1)))
    return SDValue();

  // If we have a CMP of a truncated binop, see if we can make a smaller binop
  // and use its flags directly.
  // TODO: Maybe we should try promoting compares that only use the zero flag
  // first if we can prove the upper bits with computeKnownBits?
  SDLoc dl(N);
  SDValue Op = N->getOperand(0);
  EVT VT = Op.getValueType();

  // If we have a constant logical shift that's only used in a comparison
  // against zero turn it into an equivalent AND. This allows turning it into
  // a TEST instruction later.
  if ((Op.getOpcode() == ISD::SRL || Op.getOpcode() == ISD::SHL) &&
      Op.hasOneUse() && isa<ConstantSDNode>(Op.getOperand(1)) &&
      onlyZeroFlagUsed(SDValue(N, 0))) {
    unsigned BitWidth = VT.getSizeInBits();
    const APInt &ShAmt = Op.getConstantOperandAPInt(1);
    if (ShAmt.ult(BitWidth)) { // Avoid undefined shifts.
      unsigned MaskBits = BitWidth - ShAmt.getZExtValue();
      APInt Mask = Op.getOpcode() == ISD::SRL
                       ? APInt::getHighBitsSet(BitWidth, MaskBits)
                       : APInt::getLowBitsSet(BitWidth, MaskBits);
      if (Mask.isSignedIntN(32)) {
        Op = DAG.getNode(ISD::AND, dl, VT, Op.getOperand(0),
                         DAG.getConstant(Mask, dl, VT));
        return DAG.getNode(X86ISD::CMP, dl, MVT::i32, Op,
                           DAG.getConstant(0, dl, VT));
      }
    }
  }

  // Look for a truncate with a single use.
  if (Op.getOpcode() != ISD::TRUNCATE || !Op.hasOneUse())
    return SDValue();

  Op = Op.getOperand(0);

  // Arithmetic op can only have one use.
  if (!Op.hasOneUse())
    return SDValue();

  unsigned NewOpc;
  switch (Op.getOpcode()) {
  default: return SDValue();
  case ISD::AND:
    // Skip and with constant. We have special handling for and with immediate
    // during isel to generate test instructions.
    if (isa<ConstantSDNode>(Op.getOperand(1)))
      return SDValue();
    NewOpc = X86ISD::AND;
    break;
  case ISD::OR:  NewOpc = X86ISD::OR;  break;
  case ISD::XOR: NewOpc = X86ISD::XOR; break;
  case ISD::ADD:
    // If the carry or overflow flag is used, we can't truncate.
    if (needCarryOrOverflowFlag(SDValue(N, 0)))
      return SDValue();
    NewOpc = X86ISD::ADD;
    break;
  case ISD::SUB:
    // If the carry or overflow flag is used, we can't truncate.
    if (needCarryOrOverflowFlag(SDValue(N, 0)))
      return SDValue();
    NewOpc = X86ISD::SUB;
    break;
  }

  // We found an op we can narrow. Truncate its inputs.
  SDValue Op0 = DAG.getNode(ISD::TRUNCATE, dl, VT, Op.getOperand(0));
  SDValue Op1 = DAG.getNode(ISD::TRUNCATE, dl, VT, Op.getOperand(1));

  // Use a X86 specific opcode to avoid DAG combine messing with it.
  SDVTList VTs = DAG.getVTList(VT, MVT::i32);
  Op = DAG.getNode(NewOpc, dl, VTs, Op0, Op1);

  // For AND, keep a CMP so that we can match the test pattern.
  if (NewOpc == X86ISD::AND)
    return DAG.getNode(X86ISD::CMP, dl, MVT::i32, Op,
                       DAG.getConstant(0, dl, VT));

  // Return the flags.
  return Op.getValue(1);
}

static SDValue combineX86AddSub(SDNode *N, SelectionDAG &DAG,
                                TargetLowering::DAGCombinerInfo &DCI) {
  assert((X86ISD::ADD == N->getOpcode() || X86ISD::SUB == N->getOpcode()) &&
         "Expected X86ISD::ADD or X86ISD::SUB");

  SDLoc DL(N);
  SDValue LHS = N->getOperand(0);
  SDValue RHS = N->getOperand(1);
  MVT VT = LHS.getSimpleValueType();
  unsigned GenericOpc = X86ISD::ADD == N->getOpcode() ? ISD::ADD : ISD::SUB;

  // If we don't use the flag result, simplify back to a generic ADD/SUB.
  if (!N->hasAnyUseOfValue(1)) {
    SDValue Res = DAG.getNode(GenericOpc, DL, VT, LHS, RHS);
    return DAG.getMergeValues({Res, DAG.getConstant(0, DL, MVT::i32)}, DL);
  }

  // Fold any similar generic ADD/SUB opcodes to reuse this node.
  auto MatchGeneric = [&](SDValue N0, SDValue N1, bool Negate) {
    SDValue Ops[] = {N0, N1};
    SDVTList VTs = DAG.getVTList(N->getValueType(0));
    if (SDNode *GenericAddSub = DAG.getNodeIfExists(GenericOpc, VTs, Ops)) {
      SDValue Op(N, 0);
      if (Negate)
        Op = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), Op);
      DCI.CombineTo(GenericAddSub, Op);
    }
  };
  MatchGeneric(LHS, RHS, false);
  MatchGeneric(RHS, LHS, X86ISD::SUB == N->getOpcode());

  return SDValue();
}

static SDValue combineSBB(SDNode *N, SelectionDAG &DAG) {
  if (SDValue Flags = combineCarryThroughADD(N->getOperand(2), DAG)) {
    MVT VT = N->getSimpleValueType(0);
    SDVTList VTs = DAG.getVTList(VT, MVT::i32);
    return DAG.getNode(X86ISD::SBB, SDLoc(N), VTs,
                       N->getOperand(0), N->getOperand(1),
                       Flags);
  }

  // Fold SBB(SUB(X,Y),0,Carry) -> SBB(X,Y,Carry)
  // iff the flag result is dead.
  SDValue Op0 = N->getOperand(0);
  SDValue Op1 = N->getOperand(1);
  if (Op0.getOpcode() == ISD::SUB && isNullConstant(Op1) &&
      !N->hasAnyUseOfValue(1))
    return DAG.getNode(X86ISD::SBB, SDLoc(N), N->getVTList(), Op0.getOperand(0),
                       Op0.getOperand(1), N->getOperand(2));

  return SDValue();
}

// Optimize RES, EFLAGS = X86ISD::ADC LHS, RHS, EFLAGS
static SDValue combineADC(SDNode *N, SelectionDAG &DAG,
                          TargetLowering::DAGCombinerInfo &DCI) {
  // If the LHS and RHS of the ADC node are zero, then it can't overflow and
  // the result is either zero or one (depending on the input carry bit).
  // Strength reduce this down to a "set on carry" aka SETCC_CARRY&1.
  if (X86::isZeroNode(N->getOperand(0)) &&
      X86::isZeroNode(N->getOperand(1)) &&
      // We don't have a good way to replace an EFLAGS use, so only do this when
      // dead right now.
      SDValue(N, 1).use_empty()) {
    SDLoc DL(N);
    EVT VT = N->getValueType(0);
    SDValue CarryOut = DAG.getConstant(0, DL, N->getValueType(1));
    SDValue Res1 =
        DAG.getNode(ISD::AND, DL, VT,
                    DAG.getNode(X86ISD::SETCC_CARRY, DL, VT,
                                DAG.getTargetConstant(X86::COND_B, DL, MVT::i8),
                                N->getOperand(2)),
                    DAG.getConstant(1, DL, VT));
    return DCI.CombineTo(N, Res1, CarryOut);
  }

  if (SDValue Flags = combineCarryThroughADD(N->getOperand(2), DAG)) {
    MVT VT = N->getSimpleValueType(0);
    SDVTList VTs = DAG.getVTList(VT, MVT::i32);
    return DAG.getNode(X86ISD::ADC, SDLoc(N), VTs,
                       N->getOperand(0), N->getOperand(1),
                       Flags);
  }

  return SDValue();
}

/// If this is an add or subtract where one operand is produced by a cmp+setcc,
/// then try to convert it to an ADC or SBB. This replaces TEST+SET+{ADD/SUB}
/// with CMP+{ADC, SBB}.
static SDValue combineAddOrSubToADCOrSBB(SDNode *N, SelectionDAG &DAG) {
  bool IsSub = N->getOpcode() == ISD::SUB;
  SDValue X = N->getOperand(0);
  SDValue Y = N->getOperand(1);

  // If this is an add, canonicalize a zext operand to the RHS.
  // TODO: Incomplete? What if both sides are zexts?
  if (!IsSub && X.getOpcode() == ISD::ZERO_EXTEND &&
      Y.getOpcode() != ISD::ZERO_EXTEND)
    std::swap(X, Y);

  // Look through a one-use zext.
  bool PeekedThroughZext = false;
  if (Y.getOpcode() == ISD::ZERO_EXTEND && Y.hasOneUse()) {
    Y = Y.getOperand(0);
    PeekedThroughZext = true;
  }

  // If this is an add, canonicalize a setcc operand to the RHS.
  // TODO: Incomplete? What if both sides are setcc?
  // TODO: Should we allow peeking through a zext of the other operand?
  if (!IsSub && !PeekedThroughZext && X.getOpcode() == X86ISD::SETCC &&
      Y.getOpcode() != X86ISD::SETCC)
    std::swap(X, Y);

  if (Y.getOpcode() != X86ISD::SETCC || !Y.hasOneUse())
    return SDValue();

  SDLoc DL(N);
  EVT VT = N->getValueType(0);
  X86::CondCode CC = (X86::CondCode)Y.getConstantOperandVal(0);

  // If X is -1 or 0, then we have an opportunity to avoid constants required in
  // the general case below.
  auto *ConstantX = dyn_cast<ConstantSDNode>(X);
  if (ConstantX) {
    if ((!IsSub && CC == X86::COND_AE && ConstantX->isAllOnesValue()) ||
        (IsSub && CC == X86::COND_B && ConstantX->isNullValue())) {
      // This is a complicated way to get -1 or 0 from the carry flag:
      // -1 + SETAE --> -1 + (!CF) --> CF ? -1 : 0 --> SBB %eax, %eax
      //  0 - SETB  -->  0 -  (CF) --> CF ? -1 : 0 --> SBB %eax, %eax
      return DAG.getNode(X86ISD::SETCC_CARRY, DL, VT,
                         DAG.getTargetConstant(X86::COND_B, DL, MVT::i8),
                         Y.getOperand(1));
    }

    if ((!IsSub && CC == X86::COND_BE && ConstantX->isAllOnesValue()) ||
        (IsSub && CC == X86::COND_A && ConstantX->isNullValue())) {
      SDValue EFLAGS = Y->getOperand(1);
      if (EFLAGS.getOpcode() == X86ISD::SUB && EFLAGS.hasOneUse() &&
          EFLAGS.getValueType().isInteger() &&
          !isa<ConstantSDNode>(EFLAGS.getOperand(1))) {
        // Swap the operands of a SUB, and we have the same pattern as above.
        // -1 + SETBE (SUB A, B) --> -1 + SETAE (SUB B, A) --> SUB + SBB
        //  0 - SETA  (SUB A, B) -->  0 - SETB  (SUB B, A) --> SUB + SBB
        SDValue NewSub = DAG.getNode(
            X86ISD::SUB, SDLoc(EFLAGS), EFLAGS.getNode()->getVTList(),
            EFLAGS.getOperand(1), EFLAGS.getOperand(0));
        SDValue NewEFLAGS = SDValue(NewSub.getNode(), EFLAGS.getResNo());
        return DAG.getNode(X86ISD::SETCC_CARRY, DL, VT,
                           DAG.getTargetConstant(X86::COND_B, DL, MVT::i8),
                           NewEFLAGS);
      }
    }
  }

  if (CC == X86::COND_B) {
    // X + SETB Z --> adc X, 0
    // X - SETB Z --> sbb X, 0
    return DAG.getNode(IsSub ? X86ISD::SBB : X86ISD::ADC, DL,
                       DAG.getVTList(VT, MVT::i32), X,
                       DAG.getConstant(0, DL, VT), Y.getOperand(1));
  }

  if (CC == X86::COND_A) {
    SDValue EFLAGS = Y->getOperand(1);
    // Try to convert COND_A into COND_B in an attempt to facilitate
    // materializing "setb reg".
    //
    // Do not flip "e > c", where "c" is a constant, because Cmp instruction
    // cannot take an immediate as its first operand.
    //
    if (EFLAGS.getOpcode() == X86ISD::SUB && EFLAGS.getNode()->hasOneUse() &&
        EFLAGS.getValueType().isInteger() &&
        !isa<ConstantSDNode>(EFLAGS.getOperand(1))) {
      SDValue NewSub = DAG.getNode(X86ISD::SUB, SDLoc(EFLAGS),
                                   EFLAGS.getNode()->getVTList(),
                                   EFLAGS.getOperand(1), EFLAGS.getOperand(0));
      SDValue NewEFLAGS = SDValue(NewSub.getNode(), EFLAGS.getResNo());
      return DAG.getNode(IsSub ? X86ISD::SBB : X86ISD::ADC, DL,
                         DAG.getVTList(VT, MVT::i32), X,
                         DAG.getConstant(0, DL, VT), NewEFLAGS);
    }
  }

  if (CC != X86::COND_E && CC != X86::COND_NE)
    return SDValue();

  SDValue Cmp = Y.getOperand(1);
  if (Cmp.getOpcode() != X86ISD::CMP || !Cmp.hasOneUse() ||
      !X86::isZeroNode(Cmp.getOperand(1)) ||
      !Cmp.getOperand(0).getValueType().isInteger())
    return SDValue();

  SDValue Z = Cmp.getOperand(0);
  EVT ZVT = Z.getValueType();

  // If X is -1 or 0, then we have an opportunity to avoid constants required in
  // the general case below.
  if (ConstantX) {
    // 'neg' sets the carry flag when Z != 0, so create 0 or -1 using 'sbb' with
    // fake operands:
    //  0 - (Z != 0) --> sbb %eax, %eax, (neg Z)
    // -1 + (Z == 0) --> sbb %eax, %eax, (neg Z)
    if ((IsSub && CC == X86::COND_NE && ConstantX->isNullValue()) ||
        (!IsSub && CC == X86::COND_E && ConstantX->isAllOnesValue())) {
      SDValue Zero = DAG.getConstant(0, DL, ZVT);
      SDVTList X86SubVTs = DAG.getVTList(ZVT, MVT::i32);
      SDValue Neg = DAG.getNode(X86ISD::SUB, DL, X86SubVTs, Zero, Z);
      return DAG.getNode(X86ISD::SETCC_CARRY, DL, VT,
                         DAG.getTargetConstant(X86::COND_B, DL, MVT::i8),
                         SDValue(Neg.getNode(), 1));
    }

    // cmp with 1 sets the carry flag when Z == 0, so create 0 or -1 using 'sbb'
    // with fake operands:
    //  0 - (Z == 0) --> sbb %eax, %eax, (cmp Z, 1)
    // -1 + (Z != 0) --> sbb %eax, %eax, (cmp Z, 1)
    if ((IsSub && CC == X86::COND_E && ConstantX->isNullValue()) ||
        (!IsSub && CC == X86::COND_NE && ConstantX->isAllOnesValue())) {
      SDValue One = DAG.getConstant(1, DL, ZVT);
      SDVTList X86SubVTs = DAG.getVTList(ZVT, MVT::i32);
      SDValue Cmp1 = DAG.getNode(X86ISD::SUB, DL, X86SubVTs, Z, One);
      return DAG.getNode(X86ISD::SETCC_CARRY, DL, VT,
                         DAG.getTargetConstant(X86::COND_B, DL, MVT::i8),
                         Cmp1.getValue(1));
    }
  }

  // (cmp Z, 1) sets the carry flag if Z is 0.
  SDValue One = DAG.getConstant(1, DL, ZVT);
  SDVTList X86SubVTs = DAG.getVTList(ZVT, MVT::i32);
  SDValue Cmp1 = DAG.getNode(X86ISD::SUB, DL, X86SubVTs, Z, One);

  // Add the flags type for ADC/SBB nodes.
  SDVTList VTs = DAG.getVTList(VT, MVT::i32);

  // X - (Z != 0) --> sub X, (zext(setne Z, 0)) --> adc X, -1, (cmp Z, 1)
  // X + (Z != 0) --> add X, (zext(setne Z, 0)) --> sbb X, -1, (cmp Z, 1)
  if (CC == X86::COND_NE)
    return DAG.getNode(IsSub ? X86ISD::ADC : X86ISD::SBB, DL, VTs, X,
                       DAG.getConstant(-1ULL, DL, VT), Cmp1.getValue(1));

  // X - (Z == 0) --> sub X, (zext(sete  Z, 0)) --> sbb X, 0, (cmp Z, 1)
  // X + (Z == 0) --> add X, (zext(sete  Z, 0)) --> adc X, 0, (cmp Z, 1)
  return DAG.getNode(IsSub ? X86ISD::SBB : X86ISD::ADC, DL, VTs, X,
                     DAG.getConstant(0, DL, VT), Cmp1.getValue(1));
}

static SDValue matchPMADDWD(SelectionDAG &DAG, SDValue Op0, SDValue Op1,
                            const SDLoc &DL, EVT VT,
                            const X86Subtarget &Subtarget) {
  // Example of pattern we try to detect:
  // t := (v8i32 mul (sext (v8i16 x0), (sext (v8i16 x1))))
  //(add (build_vector (extract_elt t, 0),
  //                   (extract_elt t, 2),
  //                   (extract_elt t, 4),
  //                   (extract_elt t, 6)),
  //     (build_vector (extract_elt t, 1),
  //                   (extract_elt t, 3),
  //                   (extract_elt t, 5),
  //                   (extract_elt t, 7)))

  if (!Subtarget.hasSSE2())
    return SDValue();

  if (Op0.getOpcode() != ISD::BUILD_VECTOR ||
      Op1.getOpcode() != ISD::BUILD_VECTOR)
    return SDValue();

  if (!VT.isVector() || VT.getVectorElementType() != MVT::i32 ||
      VT.getVectorNumElements() < 4 ||
      !isPowerOf2_32(VT.getVectorNumElements()))
    return SDValue();

  // Check if one of Op0,Op1 is of the form:
  // (build_vector (extract_elt Mul, 0),
  //               (extract_elt Mul, 2),
  //               (extract_elt Mul, 4),
  //                   ...
  // the other is of the form:
  // (build_vector (extract_elt Mul, 1),
  //               (extract_elt Mul, 3),
  //               (extract_elt Mul, 5),
  //                   ...
  // and identify Mul.
  SDValue Mul;
  for (unsigned i = 0, e = VT.getVectorNumElements(); i != e; i += 2) {
    SDValue Op0L = Op0->getOperand(i), Op1L = Op1->getOperand(i),
            Op0H = Op0->getOperand(i + 1), Op1H = Op1->getOperand(i + 1);
    // TODO: Be more tolerant to undefs.
    if (Op0L.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
        Op1L.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
        Op0H.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
        Op1H.getOpcode() != ISD::EXTRACT_VECTOR_ELT)
      return SDValue();
    auto *Const0L = dyn_cast<ConstantSDNode>(Op0L->getOperand(1));
    auto *Const1L = dyn_cast<ConstantSDNode>(Op1L->getOperand(1));
    auto *Const0H = dyn_cast<ConstantSDNode>(Op0H->getOperand(1));
    auto *Const1H = dyn_cast<ConstantSDNode>(Op1H->getOperand(1));
    if (!Const0L || !Const1L || !Const0H || !Const1H)
      return SDValue();
    unsigned Idx0L = Const0L->getZExtValue(), Idx1L = Const1L->getZExtValue(),
             Idx0H = Const0H->getZExtValue(), Idx1H = Const1H->getZExtValue();
    // Commutativity of mul allows factors of a product to reorder.
    if (Idx0L > Idx1L)
      std::swap(Idx0L, Idx1L);
    if (Idx0H > Idx1H)
      std::swap(Idx0H, Idx1H);
    // Commutativity of add allows pairs of factors to reorder.
    if (Idx0L > Idx0H) {
      std::swap(Idx0L, Idx0H);
      std::swap(Idx1L, Idx1H);
    }
    if (Idx0L != 2 * i || Idx1L != 2 * i + 1 || Idx0H != 2 * i + 2 ||
        Idx1H != 2 * i + 3)
      return SDValue();
    if (!Mul) {
      // First time an extract_elt's source vector is visited. Must be a MUL
      // with 2X number of vector elements than the BUILD_VECTOR.
      // Both extracts must be from same MUL.
      Mul = Op0L->getOperand(0);
      if (Mul->getOpcode() != ISD::MUL ||
          Mul.getValueType().getVectorNumElements() != 2 * e)
        return SDValue();
    }
    // Check that the extract is from the same MUL previously seen.
    if (Mul != Op0L->getOperand(0) || Mul != Op1L->getOperand(0) ||
        Mul != Op0H->getOperand(0) || Mul != Op1H->getOperand(0))
      return SDValue();
  }

  // Check if the Mul source can be safely shrunk.
  ShrinkMode Mode;
  if (!canReduceVMulWidth(Mul.getNode(), DAG, Mode) ||
      Mode == ShrinkMode::MULU16)
    return SDValue();

  EVT TruncVT = EVT::getVectorVT(*DAG.getContext(), MVT::i16,
                                 VT.getVectorNumElements() * 2);
  SDValue N0 = DAG.getNode(ISD::TRUNCATE, DL, TruncVT, Mul.getOperand(0));
  SDValue N1 = DAG.getNode(ISD::TRUNCATE, DL, TruncVT, Mul.getOperand(1));

  auto PMADDBuilder = [](SelectionDAG &DAG, const SDLoc &DL,
                         ArrayRef<SDValue> Ops) {
    EVT InVT = Ops[0].getValueType();
    assert(InVT == Ops[1].getValueType() && "Operands' types mismatch");
    EVT ResVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32,
                                 InVT.getVectorNumElements() / 2);
    return DAG.getNode(X86ISD::VPMADDWD, DL, ResVT, Ops[0], Ops[1]);
  };
  return SplitOpsAndApply(DAG, Subtarget, DL, VT, { N0, N1 }, PMADDBuilder);
}

// Attempt to turn this pattern into PMADDWD.
// (add (mul (sext (build_vector)), (sext (build_vector))),
//      (mul (sext (build_vector)), (sext (build_vector)))
static SDValue matchPMADDWD_2(SelectionDAG &DAG, SDValue N0, SDValue N1,
                              const SDLoc &DL, EVT VT,
                              const X86Subtarget &Subtarget) {
  if (!Subtarget.hasSSE2())
    return SDValue();

  if (N0.getOpcode() != ISD::MUL || N1.getOpcode() != ISD::MUL)
    return SDValue();

  if (!VT.isVector() || VT.getVectorElementType() != MVT::i32 ||
      VT.getVectorNumElements() < 4 ||
      !isPowerOf2_32(VT.getVectorNumElements()))
    return SDValue();

  SDValue N00 = N0.getOperand(0);
  SDValue N01 = N0.getOperand(1);
  SDValue N10 = N1.getOperand(0);
  SDValue N11 = N1.getOperand(1);

  // All inputs need to be sign extends.
  // TODO: Support ZERO_EXTEND from known positive?
  if (N00.getOpcode() != ISD::SIGN_EXTEND ||
      N01.getOpcode() != ISD::SIGN_EXTEND ||
      N10.getOpcode() != ISD::SIGN_EXTEND ||
      N11.getOpcode() != ISD::SIGN_EXTEND)
    return SDValue();

  // Peek through the extends.
  N00 = N00.getOperand(0);
  N01 = N01.getOperand(0);
  N10 = N10.getOperand(0);
  N11 = N11.getOperand(0);

  // Must be extending from vXi16.
  EVT InVT = N00.getValueType();
  if (InVT.getVectorElementType() != MVT::i16 || N01.getValueType() != InVT ||
      N10.getValueType() != InVT || N11.getValueType() != InVT)
    return SDValue();

  // All inputs should be build_vectors.
  if (N00.getOpcode() != ISD::BUILD_VECTOR ||
      N01.getOpcode() != ISD::BUILD_VECTOR ||
      N10.getOpcode() != ISD::BUILD_VECTOR ||
      N11.getOpcode() != ISD::BUILD_VECTOR)
    return SDValue();

  // For each element, we need to ensure we have an odd element from one vector
  // multiplied by the odd element of another vector and the even element from
  // one of the same vectors being multiplied by the even element from the
  // other vector. So we need to make sure for each element i, this operator
  // is being performed:
  //  A[2 * i] * B[2 * i] + A[2 * i + 1] * B[2 * i + 1]
  SDValue In0, In1;
  for (unsigned i = 0; i != N00.getNumOperands(); ++i) {
    SDValue N00Elt = N00.getOperand(i);
    SDValue N01Elt = N01.getOperand(i);
    SDValue N10Elt = N10.getOperand(i);
    SDValue N11Elt = N11.getOperand(i);
    // TODO: Be more tolerant to undefs.
    if (N00Elt.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
        N01Elt.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
        N10Elt.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
        N11Elt.getOpcode() != ISD::EXTRACT_VECTOR_ELT)
      return SDValue();
    auto *ConstN00Elt = dyn_cast<ConstantSDNode>(N00Elt.getOperand(1));
    auto *ConstN01Elt = dyn_cast<ConstantSDNode>(N01Elt.getOperand(1));
    auto *ConstN10Elt = dyn_cast<ConstantSDNode>(N10Elt.getOperand(1));
    auto *ConstN11Elt = dyn_cast<ConstantSDNode>(N11Elt.getOperand(1));
    if (!ConstN00Elt || !ConstN01Elt || !ConstN10Elt || !ConstN11Elt)
      return SDValue();
    unsigned IdxN00 = ConstN00Elt->getZExtValue();
    unsigned IdxN01 = ConstN01Elt->getZExtValue();
    unsigned IdxN10 = ConstN10Elt->getZExtValue();
    unsigned IdxN11 = ConstN11Elt->getZExtValue();
    // Add is commutative so indices can be reordered.
    if (IdxN00 > IdxN10) {
      std::swap(IdxN00, IdxN10);
      std::swap(IdxN01, IdxN11);
    }
    // N0 indices be the even element. N1 indices must be the next odd element.
    if (IdxN00 != 2 * i || IdxN10 != 2 * i + 1 ||
        IdxN01 != 2 * i || IdxN11 != 2 * i + 1)
      return SDValue();
    SDValue N00In = N00Elt.getOperand(0);
    SDValue N01In = N01Elt.getOperand(0);
    SDValue N10In = N10Elt.getOperand(0);
    SDValue N11In = N11Elt.getOperand(0);
    // First time we find an input capture it.
    if (!In0) {
      In0 = N00In;
      In1 = N01In;
    }
    // Mul is commutative so the input vectors can be in any order.
    // Canonicalize to make the compares easier.
    if (In0 != N00In)
      std::swap(N00In, N01In);
    if (In0 != N10In)
      std::swap(N10In, N11In);
    if (In0 != N00In || In1 != N01In || In0 != N10In || In1 != N11In)
      return SDValue();
  }

  auto PMADDBuilder = [](SelectionDAG &DAG, const SDLoc &DL,
                         ArrayRef<SDValue> Ops) {
    // Shrink by adding truncate nodes and let DAGCombine fold with the
    // sources.
    EVT OpVT = Ops[0].getValueType();
    assert(OpVT.getScalarType() == MVT::i16 &&
           "Unexpected scalar element type");
    assert(OpVT == Ops[1].getValueType() && "Operands' types mismatch");
    EVT ResVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32,
                                 OpVT.getVectorNumElements() / 2);
    return DAG.getNode(X86ISD::VPMADDWD, DL, ResVT, Ops[0], Ops[1]);
  };
  return SplitOpsAndApply(DAG, Subtarget, DL, VT, { In0, In1 },
                          PMADDBuilder);
}

static SDValue combineAdd(SDNode *N, SelectionDAG &DAG,
                          TargetLowering::DAGCombinerInfo &DCI,
                          const X86Subtarget &Subtarget) {
  EVT VT = N->getValueType(0);
  SDValue Op0 = N->getOperand(0);
  SDValue Op1 = N->getOperand(1);

  if (SDValue MAdd = matchPMADDWD(DAG, Op0, Op1, SDLoc(N), VT, Subtarget))
    return MAdd;
  if (SDValue MAdd = matchPMADDWD_2(DAG, Op0, Op1, SDLoc(N), VT, Subtarget))
    return MAdd;

  // Try to synthesize horizontal adds from adds of shuffles.
  if ((VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v16i16 ||
       VT == MVT::v8i32) &&
      Subtarget.hasSSSE3() &&
      isHorizontalBinOp(Op0, Op1, DAG, Subtarget, true)) {
    auto HADDBuilder = [](SelectionDAG &DAG, const SDLoc &DL,
                          ArrayRef<SDValue> Ops) {
      return DAG.getNode(X86ISD::HADD, DL, Ops[0].getValueType(), Ops);
    };
    return SplitOpsAndApply(DAG, Subtarget, SDLoc(N), VT, {Op0, Op1},
                            HADDBuilder);
  }

  // If vectors of i1 are legal, turn (add (zext (vXi1 X)), Y) into
  // (sub Y, (sext (vXi1 X))).
  // FIXME: We have the (sub Y, (zext (vXi1 X))) -> (add (sext (vXi1 X)), Y) in
  // generic DAG combine without a legal type check, but adding this there
  // caused regressions.
  if (VT.isVector()) {
    const TargetLowering &TLI = DAG.getTargetLoweringInfo();
    if (Op0.getOpcode() == ISD::ZERO_EXTEND &&
        Op0.getOperand(0).getValueType().getVectorElementType() == MVT::i1 &&
        TLI.isTypeLegal(Op0.getOperand(0).getValueType())) {
      SDLoc DL(N);
      SDValue SExt = DAG.getNode(ISD::SIGN_EXTEND, DL, VT, Op0.getOperand(0));
      return DAG.getNode(ISD::SUB, DL, VT, Op1, SExt);
    }

    if (Op1.getOpcode() == ISD::ZERO_EXTEND &&
        Op1.getOperand(0).getValueType().getVectorElementType() == MVT::i1 &&
        TLI.isTypeLegal(Op1.getOperand(0).getValueType())) {
      SDLoc DL(N);
      SDValue SExt = DAG.getNode(ISD::SIGN_EXTEND, DL, VT, Op1.getOperand(0));
      return DAG.getNode(ISD::SUB, DL, VT, Op0, SExt);
    }
  }

  return combineAddOrSubToADCOrSBB(N, DAG);
}

static SDValue combineSubToSubus(SDNode *N, SelectionDAG &DAG,
                                 const X86Subtarget &Subtarget) {
  SDValue Op0 = N->getOperand(0);
  SDValue Op1 = N->getOperand(1);
  EVT VT = N->getValueType(0);

  if (!VT.isVector())
    return SDValue();

  // PSUBUS is supported, starting from SSE2, but truncation for v8i32
  // is only worth it with SSSE3 (PSHUFB).
  EVT EltVT = VT.getVectorElementType();
  if (!(Subtarget.hasSSE2() && (EltVT == MVT::i8 || EltVT == MVT::i16)) &&
      !(Subtarget.hasSSSE3() && (VT == MVT::v8i32 || VT == MVT::v8i64)) &&
      !(Subtarget.useBWIRegs() && (VT == MVT::v16i32)))
    return SDValue();

  SDValue SubusLHS, SubusRHS;
  // Try to find umax(a,b) - b or a - umin(a,b) patterns
  // they may be converted to subus(a,b).
  // TODO: Need to add IR canonicalization for this code.
  if (Op0.getOpcode() == ISD::UMAX) {
    SubusRHS = Op1;
    SDValue MaxLHS = Op0.getOperand(0);
    SDValue MaxRHS = Op0.getOperand(1);
    if (MaxLHS == Op1)
      SubusLHS = MaxRHS;
    else if (MaxRHS == Op1)
      SubusLHS = MaxLHS;
    else
      return SDValue();
  } else if (Op1.getOpcode() == ISD::UMIN) {
    SubusLHS = Op0;
    SDValue MinLHS = Op1.getOperand(0);
    SDValue MinRHS = Op1.getOperand(1);
    if (MinLHS == Op0)
      SubusRHS = MinRHS;
    else if (MinRHS == Op0)
      SubusRHS = MinLHS;
    else
      return SDValue();
  } else
    return SDValue();

  // PSUBUS doesn't support v8i32/v8i64/v16i32, but it can be enabled with
  // special preprocessing in some cases.
  if (EltVT == MVT::i8 || EltVT == MVT::i16)
    return DAG.getNode(ISD::USUBSAT, SDLoc(N), VT, SubusLHS, SubusRHS);

  assert((VT == MVT::v8i32 || VT == MVT::v16i32 || VT == MVT::v8i64) &&
         "Unexpected VT!");

  // Special preprocessing case can be only applied
  // if the value was zero extended from 16 bit,
  // so we require first 16 bits to be zeros for 32 bit
  // values, or first 48 bits for 64 bit values.
  KnownBits Known = DAG.computeKnownBits(SubusLHS);
  unsigned NumZeros = Known.countMinLeadingZeros();
  if ((VT == MVT::v8i64 && NumZeros < 48) || NumZeros < 16)
    return SDValue();

  EVT ExtType = SubusLHS.getValueType();
  EVT ShrinkedType;
  if (VT == MVT::v8i32 || VT == MVT::v8i64)
    ShrinkedType = MVT::v8i16;
  else
    ShrinkedType = NumZeros >= 24 ? MVT::v16i8 : MVT::v16i16;

  // If SubusLHS is zeroextended - truncate SubusRHS to it's
  // size SubusRHS = umin(0xFFF.., SubusRHS).
  SDValue SaturationConst =
      DAG.getConstant(APInt::getLowBitsSet(ExtType.getScalarSizeInBits(),
                                           ShrinkedType.getScalarSizeInBits()),
                      SDLoc(SubusLHS), ExtType);
  SDValue UMin = DAG.getNode(ISD::UMIN, SDLoc(SubusLHS), ExtType, SubusRHS,
                             SaturationConst);
  SDValue NewSubusLHS =
      DAG.getZExtOrTrunc(SubusLHS, SDLoc(SubusLHS), ShrinkedType);
  SDValue NewSubusRHS = DAG.getZExtOrTrunc(UMin, SDLoc(SubusRHS), ShrinkedType);
  SDValue Psubus = DAG.getNode(ISD::USUBSAT, SDLoc(N), ShrinkedType,
                               NewSubusLHS, NewSubusRHS);

  // Zero extend the result, it may be used somewhere as 32 bit,
  // if not zext and following trunc will shrink.
  return DAG.getZExtOrTrunc(Psubus, SDLoc(N), ExtType);
}

static SDValue combineSub(SDNode *N, SelectionDAG &DAG,
                          TargetLowering::DAGCombinerInfo &DCI,
                          const X86Subtarget &Subtarget) {
  SDValue Op0 = N->getOperand(0);
  SDValue Op1 = N->getOperand(1);

  // X86 can't encode an immediate LHS of a sub. See if we can push the
  // negation into a preceding instruction.
  if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op0)) {
    // If the RHS of the sub is a XOR with one use and a constant, invert the
    // immediate. Then add one to the LHS of the sub so we can turn
    // X-Y -> X+~Y+1, saving one register.
    if (Op1->hasOneUse() && Op1.getOpcode() == ISD::XOR &&
        isa<ConstantSDNode>(Op1.getOperand(1))) {
      const APInt &XorC = Op1.getConstantOperandAPInt(1);
      EVT VT = Op0.getValueType();
      SDValue NewXor = DAG.getNode(ISD::XOR, SDLoc(Op1), VT,
                                   Op1.getOperand(0),
                                   DAG.getConstant(~XorC, SDLoc(Op1), VT));
      return DAG.getNode(ISD::ADD, SDLoc(N), VT, NewXor,
                         DAG.getConstant(C->getAPIntValue() + 1, SDLoc(N), VT));
    }
  }

  // Try to synthesize horizontal subs from subs of shuffles.
  EVT VT = N->getValueType(0);
  if ((VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v16i16 ||
       VT == MVT::v8i32) &&
      Subtarget.hasSSSE3() &&
      isHorizontalBinOp(Op0, Op1, DAG, Subtarget, false)) {
    auto HSUBBuilder = [](SelectionDAG &DAG, const SDLoc &DL,
                          ArrayRef<SDValue> Ops) {
      return DAG.getNode(X86ISD::HSUB, DL, Ops[0].getValueType(), Ops);
    };
    return SplitOpsAndApply(DAG, Subtarget, SDLoc(N), VT, {Op0, Op1},
                            HSUBBuilder);
  }

  // Try to create PSUBUS if SUB's argument is max/min
  if (SDValue V = combineSubToSubus(N, DAG, Subtarget))
    return V;

  return combineAddOrSubToADCOrSBB(N, DAG);
}

static SDValue combineVectorCompare(SDNode *N, SelectionDAG &DAG,
                                    const X86Subtarget &Subtarget) {
  MVT VT = N->getSimpleValueType(0);
  SDLoc DL(N);

  if (N->getOperand(0) == N->getOperand(1)) {
    if (N->getOpcode() == X86ISD::PCMPEQ)
      return DAG.getConstant(-1, DL, VT);
    if (N->getOpcode() == X86ISD::PCMPGT)
      return DAG.getConstant(0, DL, VT);
  }

  return SDValue();
}

/// Helper that combines an array of subvector ops as if they were the operands
/// of a ISD::CONCAT_VECTORS node, but may have come from another source (e.g.
/// ISD::INSERT_SUBVECTOR). The ops are assumed to be of the same type.
static SDValue combineConcatVectorOps(const SDLoc &DL, MVT VT,
                                      ArrayRef<SDValue> Ops, SelectionDAG &DAG,
                                      TargetLowering::DAGCombinerInfo &DCI,
                                      const X86Subtarget &Subtarget) {
  assert(Subtarget.hasAVX() && "AVX assumed for concat_vectors");
  unsigned EltSizeInBits = VT.getScalarSizeInBits();

  if (llvm::all_of(Ops, [](SDValue Op) { return Op.isUndef(); }))
    return DAG.getUNDEF(VT);

  if (llvm::all_of(Ops, [](SDValue Op) {
        return ISD::isBuildVectorAllZeros(Op.getNode());
      }))
    return getZeroVector(VT, Subtarget, DAG, DL);

  SDValue Op0 = Ops[0];
  bool IsSplat = llvm::all_of(Ops, [&Op0](SDValue Op) { return Op == Op0; });

  // Fold subvector loads into one.
  // If needed, look through bitcasts to get to the load.
  if (auto *FirstLd = dyn_cast<LoadSDNode>(peekThroughBitcasts(Op0))) {
    bool Fast;
    const X86TargetLowering *TLI = Subtarget.getTargetLowering();
    if (TLI->allowsMemoryAccess(*DAG.getContext(), DAG.getDataLayout(), VT,
                                *FirstLd->getMemOperand(), &Fast) &&
        Fast) {
      if (SDValue Ld =
              EltsFromConsecutiveLoads(VT, Ops, DL, DAG, Subtarget, false))
        return Ld;
    }
  }

  // Repeated subvectors.
  if (IsSplat) {
    // If this broadcast/subv_broadcast is inserted into both halves, use a
    // larger broadcast/subv_broadcast.
    if (Op0.getOpcode() == X86ISD::VBROADCAST ||
        Op0.getOpcode() == X86ISD::SUBV_BROADCAST)
      return DAG.getNode(Op0.getOpcode(), DL, VT, Op0.getOperand(0));

    // concat_vectors(movddup(x),movddup(x)) -> broadcast(x)
    if (Op0.getOpcode() == X86ISD::MOVDDUP && VT == MVT::v4f64 &&
        (Subtarget.hasAVX2() || MayFoldLoad(Op0.getOperand(0))))
      return DAG.getNode(X86ISD::VBROADCAST, DL, VT,
                         DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f64,
                                     Op0.getOperand(0),
                                     DAG.getIntPtrConstant(0, DL)));

    // concat_vectors(scalar_to_vector(x),scalar_to_vector(x)) -> broadcast(x)
    if (Op0.getOpcode() == ISD::SCALAR_TO_VECTOR &&
        (Subtarget.hasAVX2() ||
         (EltSizeInBits >= 32 && MayFoldLoad(Op0.getOperand(0)))) &&
        Op0.getOperand(0).getValueType() == VT.getScalarType())
      return DAG.getNode(X86ISD::VBROADCAST, DL, VT, Op0.getOperand(0));
  }

  // Repeated opcode.
  // TODO - combineX86ShufflesRecursively should handle shuffle concatenation
  // but it currently struggles with different vector widths.
  if (llvm::all_of(Ops, [Op0](SDValue Op) {
        return Op.getOpcode() == Op0.getOpcode();
      })) {
    unsigned NumOps = Ops.size();
    switch (Op0.getOpcode()) {
    case X86ISD::SHUFP: {
      // Add SHUFPD support if/when necessary.
      if (!IsSplat && VT.getScalarType() == MVT::f32 &&
          llvm::all_of(Ops, [Op0](SDValue Op) {
            return Op.getOperand(2) == Op0.getOperand(2);
          })) {
        SmallVector<SDValue, 2> LHS, RHS;
        for (unsigned i = 0; i != NumOps; ++i) {
          LHS.push_back(Ops[i].getOperand(0));
          RHS.push_back(Ops[i].getOperand(1));
        }
        return DAG.getNode(Op0.getOpcode(), DL, VT,
                           DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, LHS),
                           DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, RHS),
                           Op0.getOperand(2));
      }
      break;
    }
    case X86ISD::PSHUFHW:
    case X86ISD::PSHUFLW:
    case X86ISD::PSHUFD:
      if (!IsSplat && NumOps == 2 && VT.is256BitVector() &&
          Subtarget.hasInt256() && Op0.getOperand(1) == Ops[1].getOperand(1)) {
        SmallVector<SDValue, 2> Src;
        for (unsigned i = 0; i != NumOps; ++i)
          Src.push_back(Ops[i].getOperand(0));
        return DAG.getNode(Op0.getOpcode(), DL, VT,
                           DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Src),
                           Op0.getOperand(1));
      }
      LLVM_FALLTHROUGH;
    case X86ISD::VPERMILPI:
      // TODO - add support for vXf64/vXi64 shuffles.
      if (!IsSplat && NumOps == 2 && (VT == MVT::v8f32 || VT == MVT::v8i32) &&
          Subtarget.hasAVX() && Op0.getOperand(1) == Ops[1].getOperand(1)) {
        SmallVector<SDValue, 2> Src;
        for (unsigned i = 0; i != NumOps; ++i)
          Src.push_back(DAG.getBitcast(MVT::v4f32, Ops[i].getOperand(0)));
        SDValue Res = DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v8f32, Src);
        Res = DAG.getNode(X86ISD::VPERMILPI, DL, MVT::v8f32, Res,
                          Op0.getOperand(1));
        return DAG.getBitcast(VT, Res);
      }
      break;
    case X86ISD::VSHLI:
    case X86ISD::VSRAI:
    case X86ISD::VSRLI:
      if (((VT.is256BitVector() && Subtarget.hasInt256()) ||
           (VT.is512BitVector() && Subtarget.useAVX512Regs() &&
            (EltSizeInBits >= 32 || Subtarget.useBWIRegs()))) &&
          llvm::all_of(Ops, [Op0](SDValue Op) {
            return Op0.getOperand(1) == Op.getOperand(1);
          })) {
        SmallVector<SDValue, 2> Src;
        for (unsigned i = 0; i != NumOps; ++i)
          Src.push_back(Ops[i].getOperand(0));
        return DAG.getNode(Op0.getOpcode(), DL, VT,
                           DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Src),
                           Op0.getOperand(1));
      }
      break;
    case X86ISD::VPERMI:
    case X86ISD::VROTLI:
    case X86ISD::VROTRI:
      if (VT.is512BitVector() && Subtarget.useAVX512Regs() &&
          llvm::all_of(Ops, [Op0](SDValue Op) {
            return Op0.getOperand(1) == Op.getOperand(1);
          })) {
        SmallVector<SDValue, 2> Src;
        for (unsigned i = 0; i != NumOps; ++i)
          Src.push_back(Ops[i].getOperand(0));
        return DAG.getNode(Op0.getOpcode(), DL, VT,
                           DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Src),
                           Op0.getOperand(1));
      }
      break;
    case X86ISD::PACKSS:
    case X86ISD::PACKUS:
      if (!IsSplat && NumOps == 2 && VT.is256BitVector() &&
          Subtarget.hasInt256()) {
        SmallVector<SDValue, 2> LHS, RHS;
        for (unsigned i = 0; i != NumOps; ++i) {
          LHS.push_back(Ops[i].getOperand(0));
          RHS.push_back(Ops[i].getOperand(1));
        }
        MVT SrcVT = Op0.getOperand(0).getSimpleValueType();
        SrcVT = MVT::getVectorVT(SrcVT.getScalarType(),
                                 NumOps * SrcVT.getVectorNumElements());
        return DAG.getNode(Op0.getOpcode(), DL, VT,
                           DAG.getNode(ISD::CONCAT_VECTORS, DL, SrcVT, LHS),
                           DAG.getNode(ISD::CONCAT_VECTORS, DL, SrcVT, RHS));
      }
      break;
    case X86ISD::PALIGNR:
      if (!IsSplat &&
          ((VT.is256BitVector() && Subtarget.hasInt256()) ||
           (VT.is512BitVector() && Subtarget.useBWIRegs())) &&
          llvm::all_of(Ops, [Op0](SDValue Op) {
            return Op0.getOperand(2) == Op.getOperand(2);
          })) {
        SmallVector<SDValue, 2> LHS, RHS;
        for (unsigned i = 0; i != NumOps; ++i) {
          LHS.push_back(Ops[i].getOperand(0));
          RHS.push_back(Ops[i].getOperand(1));
        }
        return DAG.getNode(Op0.getOpcode(), DL, VT,
                           DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, LHS),
                           DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, RHS),
                           Op0.getOperand(2));
      }
      break;
    }
  }

  return SDValue();
}

static SDValue combineConcatVectors(SDNode *N, SelectionDAG &DAG,
                                    TargetLowering::DAGCombinerInfo &DCI,
                                    const X86Subtarget &Subtarget) {
  EVT VT = N->getValueType(0);
  EVT SrcVT = N->getOperand(0).getValueType();
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();

  // Don't do anything for i1 vectors.
  if (VT.getVectorElementType() == MVT::i1)
    return SDValue();

  if (Subtarget.hasAVX() && TLI.isTypeLegal(VT) && TLI.isTypeLegal(SrcVT)) {
    SmallVector<SDValue, 4> Ops(N->op_begin(), N->op_end());
    if (SDValue R = combineConcatVectorOps(SDLoc(N), VT.getSimpleVT(), Ops, DAG,
                                           DCI, Subtarget))
      return R;
  }

  return SDValue();
}

static SDValue combineInsertSubvector(SDNode *N, SelectionDAG &DAG,
                                      TargetLowering::DAGCombinerInfo &DCI,
                                      const X86Subtarget &Subtarget) {
  if (DCI.isBeforeLegalizeOps())
    return SDValue();

  MVT OpVT = N->getSimpleValueType(0);

  bool IsI1Vector = OpVT.getVectorElementType() == MVT::i1;

  SDLoc dl(N);
  SDValue Vec = N->getOperand(0);
  SDValue SubVec = N->getOperand(1);

  uint64_t IdxVal = N->getConstantOperandVal(2);
  MVT SubVecVT = SubVec.getSimpleValueType();

  if (Vec.isUndef() && SubVec.isUndef())
    return DAG.getUNDEF(OpVT);

  // Inserting undefs/zeros into zeros/undefs is a zero vector.
  if ((Vec.isUndef() || ISD::isBuildVectorAllZeros(Vec.getNode())) &&
      (SubVec.isUndef() || ISD::isBuildVectorAllZeros(SubVec.getNode())))
    return getZeroVector(OpVT, Subtarget, DAG, dl);

  if (ISD::isBuildVectorAllZeros(Vec.getNode())) {
    // If we're inserting into a zero vector and then into a larger zero vector,
    // just insert into the larger zero vector directly.
    if (SubVec.getOpcode() == ISD::INSERT_SUBVECTOR &&
        ISD::isBuildVectorAllZeros(SubVec.getOperand(0).getNode())) {
      uint64_t Idx2Val = SubVec.getConstantOperandVal(2);
      return DAG.getNode(ISD::INSERT_SUBVECTOR, dl, OpVT,
                         getZeroVector(OpVT, Subtarget, DAG, dl),
                         SubVec.getOperand(1),
                         DAG.getIntPtrConstant(IdxVal + Idx2Val, dl));
    }

    // If we're inserting into a zero vector and our input was extracted from an
    // insert into a zero vector of the same type and the extraction was at
    // least as large as the original insertion. Just insert the original
    // subvector into a zero vector.
    if (SubVec.getOpcode() == ISD::EXTRACT_SUBVECTOR && IdxVal == 0 &&
        isNullConstant(SubVec.getOperand(1)) &&
        SubVec.getOperand(0).getOpcode() == ISD::INSERT_SUBVECTOR) {
      SDValue Ins = SubVec.getOperand(0);
      if (isNullConstant(Ins.getOperand(2)) &&
          ISD::isBuildVectorAllZeros(Ins.getOperand(0).getNode()) &&
          Ins.getOperand(1).getValueSizeInBits() <= SubVecVT.getSizeInBits())
        return DAG.getNode(ISD::INSERT_SUBVECTOR, dl, OpVT,
                           getZeroVector(OpVT, Subtarget, DAG, dl),
                           Ins.getOperand(1), N->getOperand(2));
    }
  }

  // Stop here if this is an i1 vector.
  if (IsI1Vector)
    return SDValue();

  // If this is an insert of an extract, combine to a shuffle. Don't do this
  // if the insert or extract can be represented with a subregister operation.
  if (SubVec.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
      SubVec.getOperand(0).getSimpleValueType() == OpVT &&
      (IdxVal != 0 ||
       !(Vec.isUndef() || ISD::isBuildVectorAllZeros(Vec.getNode())))) {
    int ExtIdxVal = SubVec.getConstantOperandVal(1);
    if (ExtIdxVal != 0) {
      int VecNumElts = OpVT.getVectorNumElements();
      int SubVecNumElts = SubVecVT.getVectorNumElements();
      SmallVector<int, 64> Mask(VecNumElts);
      // First create an identity shuffle mask.
      for (int i = 0; i != VecNumElts; ++i)
        Mask[i] = i;
      // Now insert the extracted portion.
      for (int i = 0; i != SubVecNumElts; ++i)
        Mask[i + IdxVal] = i + ExtIdxVal + VecNumElts;

      return DAG.getVectorShuffle(OpVT, dl, Vec, SubVec.getOperand(0), Mask);
    }
  }

  // Match concat_vector style patterns.
  SmallVector<SDValue, 2> SubVectorOps;
  if (collectConcatOps(N, SubVectorOps)) {
    if (SDValue Fold =
            combineConcatVectorOps(dl, OpVT, SubVectorOps, DAG, DCI, Subtarget))
      return Fold;

    // If we're inserting all zeros into the upper half, change this to
    // a concat with zero. We will match this to a move
    // with implicit upper bit zeroing during isel.
    // We do this here because we don't want combineConcatVectorOps to
    // create INSERT_SUBVECTOR from CONCAT_VECTORS.
    if (SubVectorOps.size() == 2 &&
        ISD::isBuildVectorAllZeros(SubVectorOps[1].getNode()))
      return DAG.getNode(ISD::INSERT_SUBVECTOR, dl, OpVT,
                         getZeroVector(OpVT, Subtarget, DAG, dl),
                         SubVectorOps[0], DAG.getIntPtrConstant(0, dl));
  }

  // If this is a broadcast insert into an upper undef, use a larger broadcast.
  if (Vec.isUndef() && IdxVal != 0 && SubVec.getOpcode() == X86ISD::VBROADCAST)
    return DAG.getNode(X86ISD::VBROADCAST, dl, OpVT, SubVec.getOperand(0));

  // If this is a broadcast load inserted into an upper undef, use a larger
  // broadcast load.
  if (Vec.isUndef() && IdxVal != 0 && SubVec.hasOneUse() &&
      SubVec.getOpcode() == X86ISD::VBROADCAST_LOAD) {
    auto *MemIntr = cast<MemIntrinsicSDNode>(SubVec);
    SDVTList Tys = DAG.getVTList(OpVT, MVT::Other);
    SDValue Ops[] = { MemIntr->getChain(), MemIntr->getBasePtr() };
    SDValue BcastLd =
        DAG.getMemIntrinsicNode(X86ISD::VBROADCAST_LOAD, dl, Tys, Ops,
                                MemIntr->getMemoryVT(),
                                MemIntr->getMemOperand());
    DAG.ReplaceAllUsesOfValueWith(SDValue(MemIntr, 1), BcastLd.getValue(1));
    return BcastLd;
  }

  return SDValue();
}

/// If we are extracting a subvector of a vector select and the select condition
/// is composed of concatenated vectors, try to narrow the select width. This
/// is a common pattern for AVX1 integer code because 256-bit selects may be
/// legal, but there is almost no integer math/logic available for 256-bit.
/// This function should only be called with legal types (otherwise, the calls
/// to get simple value types will assert).
static SDValue narrowExtractedVectorSelect(SDNode *Ext, SelectionDAG &DAG) {
  SDValue Sel = peekThroughBitcasts(Ext->getOperand(0));
  SmallVector<SDValue, 4> CatOps;
  if (Sel.getOpcode() != ISD::VSELECT ||
      !collectConcatOps(Sel.getOperand(0).getNode(), CatOps))
    return SDValue();

  // Note: We assume simple value types because this should only be called with
  //       legal operations/types.
  // TODO: This can be extended to handle extraction to 256-bits.
  MVT VT = Ext->getSimpleValueType(0);
  if (!VT.is128BitVector())
    return SDValue();

  MVT SelCondVT = Sel.getOperand(0).getSimpleValueType();
  if (!SelCondVT.is256BitVector() && !SelCondVT.is512BitVector())
    return SDValue();

  MVT WideVT = Ext->getOperand(0).getSimpleValueType();
  MVT SelVT = Sel.getSimpleValueType();
  assert((SelVT.is256BitVector() || SelVT.is512BitVector()) &&
         "Unexpected vector type with legal operations");

  unsigned SelElts = SelVT.getVectorNumElements();
  unsigned CastedElts = WideVT.getVectorNumElements();
  unsigned ExtIdx = cast<ConstantSDNode>(Ext->getOperand(1))->getZExtValue();
  if (SelElts % CastedElts == 0) {
    // The select has the same or more (narrower) elements than the extract
    // operand. The extraction index gets scaled by that factor.
    ExtIdx *= (SelElts / CastedElts);
  } else if (CastedElts % SelElts == 0) {
    // The select has less (wider) elements than the extract operand. Make sure
    // that the extraction index can be divided evenly.
    unsigned IndexDivisor = CastedElts / SelElts;
    if (ExtIdx % IndexDivisor != 0)
      return SDValue();
    ExtIdx /= IndexDivisor;
  } else {
    llvm_unreachable("Element count of simple vector types are not divisible?");
  }

  unsigned NarrowingFactor = WideVT.getSizeInBits() / VT.getSizeInBits();
  unsigned NarrowElts = SelElts / NarrowingFactor;
  MVT NarrowSelVT = MVT::getVectorVT(SelVT.getVectorElementType(), NarrowElts);
  SDLoc DL(Ext);
  SDValue ExtCond = extract128BitVector(Sel.getOperand(0), ExtIdx, DAG, DL);
  SDValue ExtT = extract128BitVector(Sel.getOperand(1), ExtIdx, DAG, DL);
  SDValue ExtF = extract128BitVector(Sel.getOperand(2), ExtIdx, DAG, DL);
  SDValue NarrowSel = DAG.getSelect(DL, NarrowSelVT, ExtCond, ExtT, ExtF);
  return DAG.getBitcast(VT, NarrowSel);
}

static SDValue combineExtractSubvector(SDNode *N, SelectionDAG &DAG,
                                       TargetLowering::DAGCombinerInfo &DCI,
                                       const X86Subtarget &Subtarget) {
  // For AVX1 only, if we are extracting from a 256-bit and+not (which will
  // eventually get combined/lowered into ANDNP) with a concatenated operand,
  // split the 'and' into 128-bit ops to avoid the concatenate and extract.
  // We let generic combining take over from there to simplify the
  // insert/extract and 'not'.
  // This pattern emerges during AVX1 legalization. We handle it before lowering
  // to avoid complications like splitting constant vector loads.

  // Capture the original wide type in the likely case that we need to bitcast
  // back to this type.
  if (!N->getValueType(0).isSimple())
    return SDValue();

  MVT VT = N->getSimpleValueType(0);
  SDValue InVec = N->getOperand(0);
  SDValue InVecBC = peekThroughBitcasts(InVec);
  EVT InVecVT = InVec.getValueType();
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();

  if (Subtarget.hasAVX() && !Subtarget.hasAVX2() &&
      TLI.isTypeLegal(InVecVT) &&
      InVecVT.getSizeInBits() == 256 && InVecBC.getOpcode() == ISD::AND) {
    auto isConcatenatedNot = [] (SDValue V) {
      V = peekThroughBitcasts(V);
      if (!isBitwiseNot(V))
        return false;
      SDValue NotOp = V->getOperand(0);
      return peekThroughBitcasts(NotOp).getOpcode() == ISD::CONCAT_VECTORS;
    };
    if (isConcatenatedNot(InVecBC.getOperand(0)) ||
        isConcatenatedNot(InVecBC.getOperand(1))) {
      // extract (and v4i64 X, (not (concat Y1, Y2))), n -> andnp v2i64 X(n), Y1
      SDValue Concat = split256IntArith(InVecBC, DAG);
      return DAG.getNode(ISD::EXTRACT_SUBVECTOR, SDLoc(N), VT,
                         DAG.getBitcast(InVecVT, Concat), N->getOperand(1));
    }
  }

  if (DCI.isBeforeLegalizeOps())
    return SDValue();

  if (SDValue V = narrowExtractedVectorSelect(N, DAG))
    return V;

  unsigned IdxVal = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();

  if (ISD::isBuildVectorAllZeros(InVec.getNode()))
    return getZeroVector(VT, Subtarget, DAG, SDLoc(N));

  if (ISD::isBuildVectorAllOnes(InVec.getNode())) {
    if (VT.getScalarType() == MVT::i1)
      return DAG.getConstant(1, SDLoc(N), VT);
    return getOnesVector(VT, DAG, SDLoc(N));
  }

  if (InVec.getOpcode() == ISD::BUILD_VECTOR)
    return DAG.getBuildVector(
        VT, SDLoc(N),
        InVec.getNode()->ops().slice(IdxVal, VT.getVectorNumElements()));

  // If we are extracting from an insert into a zero vector, replace with a
  // smaller insert into zero if we don't access less than the original
  // subvector. Don't do this for i1 vectors.
  if (VT.getVectorElementType() != MVT::i1 &&
      InVec.getOpcode() == ISD::INSERT_SUBVECTOR && IdxVal == 0 &&
      InVec.hasOneUse() && isNullConstant(InVec.getOperand(2)) &&
      ISD::isBuildVectorAllZeros(InVec.getOperand(0).getNode()) &&
      InVec.getOperand(1).getValueSizeInBits() <= VT.getSizeInBits()) {
    SDLoc DL(N);
    return DAG.getNode(ISD::INSERT_SUBVECTOR, DL, VT,
                       getZeroVector(VT, Subtarget, DAG, DL),
                       InVec.getOperand(1), InVec.getOperand(2));
  }

  // If we're extracting from a broadcast then we're better off just
  // broadcasting to the smaller type directly, assuming this is the only use.
  // As its a broadcast we don't care about the extraction index.
  if (InVec.getOpcode() == X86ISD::VBROADCAST && InVec.hasOneUse() &&
      InVec.getOperand(0).getValueSizeInBits() <= VT.getSizeInBits())
    return DAG.getNode(X86ISD::VBROADCAST, SDLoc(N), VT, InVec.getOperand(0));

  if (InVec.getOpcode() == X86ISD::VBROADCAST_LOAD && InVec.hasOneUse()) {
    auto *MemIntr = cast<MemIntrinsicSDNode>(InVec);
    if (MemIntr->getMemoryVT().getSizeInBits() <= VT.getSizeInBits()) {
      SDVTList Tys = DAG.getVTList(VT, MVT::Other);
      SDValue Ops[] = { MemIntr->getChain(), MemIntr->getBasePtr() };
      SDValue BcastLd =
          DAG.getMemIntrinsicNode(X86ISD::VBROADCAST_LOAD, SDLoc(N), Tys, Ops,
                                  MemIntr->getMemoryVT(),
                                  MemIntr->getMemOperand());
      DAG.ReplaceAllUsesOfValueWith(SDValue(MemIntr, 1), BcastLd.getValue(1));
      return BcastLd;
    }
  }

  // If we're extracting the lowest subvector and we're the only user,
  // we may be able to perform this with a smaller vector width.
  if (IdxVal == 0 && InVec.hasOneUse()) {
    unsigned InOpcode = InVec.getOpcode();
    if (VT == MVT::v2f64 && InVecVT == MVT::v4f64) {
      // v2f64 CVTDQ2PD(v4i32).
      if (InOpcode == ISD::SINT_TO_FP &&
          InVec.getOperand(0).getValueType() == MVT::v4i32) {
        return DAG.getNode(X86ISD::CVTSI2P, SDLoc(N), VT, InVec.getOperand(0));
      }
      // v2f64 CVTUDQ2PD(v4i32).
      if (InOpcode == ISD::UINT_TO_FP && Subtarget.hasVLX() &&
          InVec.getOperand(0).getValueType() == MVT::v4i32) {
        return DAG.getNode(X86ISD::CVTUI2P, SDLoc(N), VT, InVec.getOperand(0));
      }
      // v2f64 CVTPS2PD(v4f32).
      if (InOpcode == ISD::FP_EXTEND &&
          InVec.getOperand(0).getValueType() == MVT::v4f32) {
        return DAG.getNode(X86ISD::VFPEXT, SDLoc(N), VT, InVec.getOperand(0));
      }
    }
    if ((InOpcode == ISD::ANY_EXTEND ||
         InOpcode == ISD::ANY_EXTEND_VECTOR_INREG ||
         InOpcode == ISD::ZERO_EXTEND ||
         InOpcode == ISD::ZERO_EXTEND_VECTOR_INREG ||
         InOpcode == ISD::SIGN_EXTEND ||
         InOpcode == ISD::SIGN_EXTEND_VECTOR_INREG) &&
        VT.is128BitVector() &&
        InVec.getOperand(0).getSimpleValueType().is128BitVector()) {
      unsigned ExtOp = getOpcode_EXTEND_VECTOR_INREG(InOpcode);
      return DAG.getNode(ExtOp, SDLoc(N), VT, InVec.getOperand(0));
    }
    if (InOpcode == ISD::VSELECT &&
        InVec.getOperand(0).getValueType().is256BitVector() &&
        InVec.getOperand(1).getValueType().is256BitVector() &&
        InVec.getOperand(2).getValueType().is256BitVector()) {
      SDLoc DL(N);
      SDValue Ext0 = extractSubVector(InVec.getOperand(0), 0, DAG, DL, 128);
      SDValue Ext1 = extractSubVector(InVec.getOperand(1), 0, DAG, DL, 128);
      SDValue Ext2 = extractSubVector(InVec.getOperand(2), 0, DAG, DL, 128);
      return DAG.getNode(InOpcode, DL, VT, Ext0, Ext1, Ext2);
    }
  }

  return SDValue();
}

static SDValue combineScalarToVector(SDNode *N, SelectionDAG &DAG) {
  EVT VT = N->getValueType(0);
  SDValue Src = N->getOperand(0);
  SDLoc DL(N);

  // If this is a scalar to vector to v1i1 from an AND with 1, bypass the and.
  // This occurs frequently in our masked scalar intrinsic code and our
  // floating point select lowering with AVX512.
  // TODO: SimplifyDemandedBits instead?
  if (VT == MVT::v1i1 && Src.getOpcode() == ISD::AND && Src.hasOneUse())
    if (auto *C = dyn_cast<ConstantSDNode>(Src.getOperand(1)))
      if (C->getAPIntValue().isOneValue())
        return DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v1i1,
                           Src.getOperand(0));

  // Combine scalar_to_vector of an extract_vector_elt into an extract_subvec.
  if (VT == MVT::v1i1 && Src.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
      Src.hasOneUse() && Src.getOperand(0).getValueType().isVector() &&
      Src.getOperand(0).getValueType().getVectorElementType() == MVT::i1)
    if (auto *C = dyn_cast<ConstantSDNode>(Src.getOperand(1)))
      if (C->isNullValue())
        return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, VT, Src.getOperand(0),
                           Src.getOperand(1));

  // Reduce v2i64 to v4i32 if we don't need the upper bits.
  // TODO: Move to DAGCombine?
  if (VT == MVT::v2i64 && Src.getOpcode() == ISD::ANY_EXTEND &&
      Src.getValueType() == MVT::i64 && Src.hasOneUse() &&
      Src.getOperand(0).getScalarValueSizeInBits() <= 32)
    return DAG.getBitcast(
        VT, DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v4i32,
                        DAG.getAnyExtOrTrunc(Src.getOperand(0), DL, MVT::i32)));

  return SDValue();
}

// Simplify PMULDQ and PMULUDQ operations.
static SDValue combinePMULDQ(SDNode *N, SelectionDAG &DAG,
                             TargetLowering::DAGCombinerInfo &DCI,
                             const X86Subtarget &Subtarget) {
  SDValue LHS = N->getOperand(0);
  SDValue RHS = N->getOperand(1);

  // Canonicalize constant to RHS.
  if (DAG.isConstantIntBuildVectorOrConstantInt(LHS) &&
      !DAG.isConstantIntBuildVectorOrConstantInt(RHS))
    return DAG.getNode(N->getOpcode(), SDLoc(N), N->getValueType(0), RHS, LHS);

  // Multiply by zero.
  // Don't return RHS as it may contain UNDEFs.
  if (ISD::isBuildVectorAllZeros(RHS.getNode()))
    return DAG.getConstant(0, SDLoc(N), N->getValueType(0));

  // PMULDQ/PMULUDQ only uses lower 32 bits from each vector element.
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  if (TLI.SimplifyDemandedBits(SDValue(N, 0), APInt::getAllOnesValue(64), DCI))
    return SDValue(N, 0);

  // If the input is an extend_invec and the SimplifyDemandedBits call didn't
  // convert it to any_extend_invec, due to the LegalOperations check, do the
  // conversion directly to a vector shuffle manually. This exposes combine
  // opportunities missed by combineExtInVec not calling
  // combineX86ShufflesRecursively on SSE4.1 targets.
  // FIXME: This is basically a hack around several other issues related to
  // ANY_EXTEND_VECTOR_INREG.
  if (N->getValueType(0) == MVT::v2i64 && LHS.hasOneUse() &&
      (LHS.getOpcode() == ISD::ZERO_EXTEND_VECTOR_INREG ||
       LHS.getOpcode() == ISD::SIGN_EXTEND_VECTOR_INREG) &&
      LHS.getOperand(0).getValueType() == MVT::v4i32) {
    SDLoc dl(N);
    LHS = DAG.getVectorShuffle(MVT::v4i32, dl, LHS.getOperand(0),
                               LHS.getOperand(0), { 0, -1, 1, -1 });
    LHS = DAG.getBitcast(MVT::v2i64, LHS);
    return DAG.getNode(N->getOpcode(), dl, MVT::v2i64, LHS, RHS);
  }
  if (N->getValueType(0) == MVT::v2i64 && RHS.hasOneUse() &&
      (RHS.getOpcode() == ISD::ZERO_EXTEND_VECTOR_INREG ||
       RHS.getOpcode() == ISD::SIGN_EXTEND_VECTOR_INREG) &&
      RHS.getOperand(0).getValueType() == MVT::v4i32) {
    SDLoc dl(N);
    RHS = DAG.getVectorShuffle(MVT::v4i32, dl, RHS.getOperand(0),
                               RHS.getOperand(0), { 0, -1, 1, -1 });
    RHS = DAG.getBitcast(MVT::v2i64, RHS);
    return DAG.getNode(N->getOpcode(), dl, MVT::v2i64, LHS, RHS);
  }

  return SDValue();
}

static SDValue combineExtInVec(SDNode *N, SelectionDAG &DAG,
                               TargetLowering::DAGCombinerInfo &DCI,
                               const X86Subtarget &Subtarget) {
  EVT VT = N->getValueType(0);
  SDValue In = N->getOperand(0);
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();

  // Try to merge vector loads and extend_inreg to an extload.
  if (!DCI.isBeforeLegalizeOps() && ISD::isNormalLoad(In.getNode()) &&
      In.hasOneUse()) {
    auto *Ld = cast<LoadSDNode>(In);
    if (Ld->isSimple()) {
      MVT SVT = In.getSimpleValueType().getVectorElementType();
      ISD::LoadExtType Ext = N->getOpcode() == ISD::SIGN_EXTEND_VECTOR_INREG ? ISD::SEXTLOAD : ISD::ZEXTLOAD;
      EVT MemVT = EVT::getVectorVT(*DAG.getContext(), SVT,
                                   VT.getVectorNumElements());
      if (TLI.isLoadExtLegal(Ext, VT, MemVT)) {
        SDValue Load =
            DAG.getExtLoad(Ext, SDLoc(N), VT, Ld->getChain(), Ld->getBasePtr(),
                           Ld->getPointerInfo(), MemVT, Ld->getAlignment(),
                           Ld->getMemOperand()->getFlags());
        DAG.ReplaceAllUsesOfValueWith(SDValue(Ld, 1), Load.getValue(1));
        return Load;
      }
    }
  }

  // Attempt to combine as a shuffle.
  // TODO: SSE41 support
  if (Subtarget.hasAVX() && N->getOpcode() != ISD::SIGN_EXTEND_VECTOR_INREG) {
    SDValue Op(N, 0);
    if (TLI.isTypeLegal(VT) && TLI.isTypeLegal(In.getValueType()))
      if (SDValue Res = combineX86ShufflesRecursively(Op, DAG, Subtarget))
        return Res;
  }

  return SDValue();
}

static SDValue combineKSHIFT(SDNode *N, SelectionDAG &DAG,
                             TargetLowering::DAGCombinerInfo &DCI) {
  EVT VT = N->getValueType(0);

  if (ISD::isBuildVectorAllZeros(N->getOperand(0).getNode()))
    return DAG.getConstant(0, SDLoc(N), VT);

  APInt KnownUndef, KnownZero;
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  APInt DemandedElts = APInt::getAllOnesValue(VT.getVectorNumElements());
  if (TLI.SimplifyDemandedVectorElts(SDValue(N, 0), DemandedElts, KnownUndef,
                                     KnownZero, DCI))
    return SDValue(N, 0);

  return SDValue();
}

// Optimize (fp16_to_fp (fp_to_fp16 X)) to VCVTPS2PH followed by VCVTPH2PS.
// Done as a combine because the lowering for fp16_to_fp and fp_to_fp16 produce
// extra instructions between the conversion due to going to scalar and back.
static SDValue combineFP16_TO_FP(SDNode *N, SelectionDAG &DAG,
                                 const X86Subtarget &Subtarget) {
  if (Subtarget.useSoftFloat() || !Subtarget.hasF16C())
    return SDValue();

  if (N->getOperand(0).getOpcode() != ISD::FP_TO_FP16)
    return SDValue();

  if (N->getValueType(0) != MVT::f32 ||
      N->getOperand(0).getOperand(0).getValueType() != MVT::f32)
    return SDValue();

  SDLoc dl(N);
  SDValue Res = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v4f32,
                            N->getOperand(0).getOperand(0));
  Res = DAG.getNode(X86ISD::CVTPS2PH, dl, MVT::v8i16, Res,
                    DAG.getTargetConstant(4, dl, MVT::i32));
  Res = DAG.getNode(X86ISD::CVTPH2PS, dl, MVT::v4f32, Res);
  return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f32, Res,
                     DAG.getIntPtrConstant(0, dl));
}

static SDValue combineFP_EXTEND(SDNode *N, SelectionDAG &DAG,
                                const X86Subtarget &Subtarget) {
  if (!Subtarget.hasF16C() || Subtarget.useSoftFloat())
    return SDValue();

  bool IsStrict = N->isStrictFPOpcode();
  EVT VT = N->getValueType(0);
  SDValue Src = N->getOperand(IsStrict ? 1 : 0);
  EVT SrcVT = Src.getValueType();

  if (!SrcVT.isVector() || SrcVT.getVectorElementType() != MVT::f16)
    return SDValue();

  if (VT.getVectorElementType() != MVT::f32 &&
      VT.getVectorElementType() != MVT::f64)
    return SDValue();

  unsigned NumElts = VT.getVectorNumElements();
  if (NumElts == 1 || !isPowerOf2_32(NumElts))
    return SDValue();

  SDLoc dl(N);

  // Convert the input to vXi16.
  EVT IntVT = SrcVT.changeVectorElementTypeToInteger();
  Src = DAG.getBitcast(IntVT, Src);

  // Widen to at least 8 input elements.
  if (NumElts < 8) {
    unsigned NumConcats = 8 / NumElts;
    SDValue Fill = NumElts == 4 ? DAG.getUNDEF(IntVT)
                                : DAG.getConstant(0, dl, IntVT);
    SmallVector<SDValue, 4> Ops(NumConcats, Fill);
    Ops[0] = Src;
    Src = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v8i16, Ops);
  }

  // Destination is vXf32 with at least 4 elements.
  EVT CvtVT = EVT::getVectorVT(*DAG.getContext(), MVT::f32,
                               std::max(4U, NumElts));
  SDValue Cvt, Chain;
  if (IsStrict) {
    Cvt = DAG.getNode(X86ISD::STRICT_CVTPH2PS, dl, {CvtVT, MVT::Other},
                      {N->getOperand(0), Src});
    Chain = Cvt.getValue(1);
  } else {
    Cvt = DAG.getNode(X86ISD::CVTPH2PS, dl, CvtVT, Src);
  }

  if (NumElts < 4) {
    assert(NumElts == 2 && "Unexpected size");
    Cvt = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v2f32, Cvt,
                      DAG.getIntPtrConstant(0, dl));
  }

  if (IsStrict) {
    // Extend to the original VT if necessary.
    if (Cvt.getValueType() != VT) {
      Cvt = DAG.getNode(ISD::STRICT_FP_EXTEND, dl, {VT, MVT::Other},
                        {Chain, Cvt});
      Chain = Cvt.getValue(1);
    }
    return DAG.getMergeValues({Cvt, Chain}, dl);
  }

  // Extend to the original VT if necessary.
  return DAG.getNode(ISD::FP_EXTEND, dl, VT, Cvt);
}

// Try to find a larger VBROADCAST_LOAD that we can extract from. Limit this to
// cases where the loads have the same input chain and the output chains are
// unused. This avoids any memory ordering issues.
static SDValue combineVBROADCAST_LOAD(SDNode *N, SelectionDAG &DAG,
                                      TargetLowering::DAGCombinerInfo &DCI) {
  // Only do this if the chain result is unused.
  if (N->hasAnyUseOfValue(1))
    return SDValue();

  auto *MemIntrin = cast<MemIntrinsicSDNode>(N);

  SDValue Ptr = MemIntrin->getBasePtr();
  SDValue Chain = MemIntrin->getChain();
  EVT VT = N->getSimpleValueType(0);
  EVT MemVT = MemIntrin->getMemoryVT();

  // Look at other users of our base pointer and try to find a wider broadcast.
  // The input chain and the size of the memory VT must match.
  for (SDNode *User : Ptr->uses())
    if (User != N && User->getOpcode() == X86ISD::VBROADCAST_LOAD &&
        cast<MemIntrinsicSDNode>(User)->getBasePtr() == Ptr &&
        cast<MemIntrinsicSDNode>(User)->getChain() == Chain &&
        cast<MemIntrinsicSDNode>(User)->getMemoryVT().getSizeInBits() ==
            MemVT.getSizeInBits() &&
        !User->hasAnyUseOfValue(1) &&
        User->getValueSizeInBits(0) > VT.getSizeInBits()) {
      SDValue Extract = extractSubVector(SDValue(User, 0), 0, DAG, SDLoc(N),
                                         VT.getSizeInBits());
      Extract = DAG.getBitcast(VT, Extract);
      return DCI.CombineTo(N, Extract, SDValue(User, 1));
    }

  return SDValue();
}

static SDValue combineFP_ROUND(SDNode *N, SelectionDAG &DAG,
                               const X86Subtarget &Subtarget) {
  if (!Subtarget.hasF16C() || Subtarget.useSoftFloat())
    return SDValue();

  EVT VT = N->getValueType(0);
  SDValue Src = N->getOperand(0);
  EVT SrcVT = Src.getValueType();

  if (!VT.isVector() || VT.getVectorElementType() != MVT::f16 ||
      SrcVT.getVectorElementType() != MVT::f32)
    return SDValue();

  unsigned NumElts = VT.getVectorNumElements();
  if (NumElts == 1 || !isPowerOf2_32(NumElts))
    return SDValue();

  SDLoc dl(N);

  // Widen to at least 4 input elements.
  if (NumElts < 4)
    Src = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v4f32, Src,
                      DAG.getConstantFP(0.0, dl, SrcVT));

  // Destination is v8i16 with at least 8 elements.
  EVT CvtVT = EVT::getVectorVT(*DAG.getContext(), MVT::i16,
                               std::max(8U, NumElts));
  SDValue Cvt = DAG.getNode(X86ISD::CVTPS2PH, dl, CvtVT, Src,
                            DAG.getTargetConstant(4, dl, MVT::i32));

  // Extract down to real number of elements.
  if (NumElts < 8) {
    EVT IntVT = VT.changeVectorElementTypeToInteger();
    Cvt = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, IntVT, Cvt,
                      DAG.getIntPtrConstant(0, dl));
  }

  return DAG.getBitcast(VT, Cvt);
}

SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
                                             DAGCombinerInfo &DCI) const {
  SelectionDAG &DAG = DCI.DAG;
  switch (N->getOpcode()) {
  default: break;
  case ISD::SCALAR_TO_VECTOR:
    return combineScalarToVector(N, DAG);
  case ISD::EXTRACT_VECTOR_ELT:
  case X86ISD::PEXTRW:
  case X86ISD::PEXTRB:
    return combineExtractVectorElt(N, DAG, DCI, Subtarget);
  case ISD::CONCAT_VECTORS:
    return combineConcatVectors(N, DAG, DCI, Subtarget);
  case ISD::INSERT_SUBVECTOR:
    return combineInsertSubvector(N, DAG, DCI, Subtarget);
  case ISD::EXTRACT_SUBVECTOR:
    return combineExtractSubvector(N, DAG, DCI, Subtarget);
  case ISD::VSELECT:
  case ISD::SELECT:
  case X86ISD::BLENDV:      return combineSelect(N, DAG, DCI, Subtarget);
  case ISD::BITCAST:        return combineBitcast(N, DAG, DCI, Subtarget);
  case X86ISD::CMOV:        return combineCMov(N, DAG, DCI, Subtarget);
  case X86ISD::CMP:         return combineCMP(N, DAG);
  case ISD::ADD:            return combineAdd(N, DAG, DCI, Subtarget);
  case ISD::SUB:            return combineSub(N, DAG, DCI, Subtarget);
  case X86ISD::ADD:
  case X86ISD::SUB:         return combineX86AddSub(N, DAG, DCI);
  case X86ISD::SBB:         return combineSBB(N, DAG);
  case X86ISD::ADC:         return combineADC(N, DAG, DCI);
  case ISD::MUL:            return combineMul(N, DAG, DCI, Subtarget);
  case ISD::SHL:            return combineShiftLeft(N, DAG);
  case ISD::SRA:            return combineShiftRightArithmetic(N, DAG);
  case ISD::SRL:            return combineShiftRightLogical(N, DAG, DCI);
  case ISD::AND:            return combineAnd(N, DAG, DCI, Subtarget);
  case ISD::OR:             return combineOr(N, DAG, DCI, Subtarget);
  case ISD::XOR:            return combineXor(N, DAG, DCI, Subtarget);
  case X86ISD::BEXTR:       return combineBEXTR(N, DAG, DCI, Subtarget);
  case ISD::LOAD:           return combineLoad(N, DAG, DCI, Subtarget);
  case ISD::MLOAD:          return combineMaskedLoad(N, DAG, DCI, Subtarget);
  case ISD::STORE:          return combineStore(N, DAG, DCI, Subtarget);
  case ISD::MSTORE:         return combineMaskedStore(N, DAG, DCI, Subtarget);
  case X86ISD::VEXTRACT_STORE:
    return combineVEXTRACT_STORE(N, DAG, DCI, Subtarget);
  case ISD::SINT_TO_FP:
  case ISD::STRICT_SINT_TO_FP:
    return combineSIntToFP(N, DAG, DCI, Subtarget);
  case ISD::UINT_TO_FP:
  case ISD::STRICT_UINT_TO_FP:
    return combineUIntToFP(N, DAG, Subtarget);
  case ISD::FADD:
  case ISD::FSUB:           return combineFaddFsub(N, DAG, Subtarget);
  case ISD::FNEG:           return combineFneg(N, DAG, DCI, Subtarget);
  case ISD::TRUNCATE:       return combineTruncate(N, DAG, Subtarget);
  case X86ISD::VTRUNC:      return combineVTRUNC(N, DAG);
  case X86ISD::ANDNP:       return combineAndnp(N, DAG, DCI, Subtarget);
  case X86ISD::FAND:        return combineFAnd(N, DAG, Subtarget);
  case X86ISD::FANDN:       return combineFAndn(N, DAG, Subtarget);
  case X86ISD::FXOR:
  case X86ISD::FOR:         return combineFOr(N, DAG, DCI, Subtarget);
  case X86ISD::FMIN:
  case X86ISD::FMAX:        return combineFMinFMax(N, DAG);
  case ISD::FMINNUM:
  case ISD::FMAXNUM:        return combineFMinNumFMaxNum(N, DAG, Subtarget);
  case X86ISD::CVTSI2P:
  case X86ISD::CVTUI2P:     return combineX86INT_TO_FP(N, DAG, DCI);
  case X86ISD::CVTP2SI:
  case X86ISD::CVTP2UI:
  case X86ISD::CVTTP2SI:
  case X86ISD::CVTTP2UI:    return combineCVTP2I_CVTTP2I(N, DAG, DCI);
  case X86ISD::STRICT_CVTPH2PS:
  case X86ISD::CVTPH2PS:    return combineCVTPH2PS(N, DAG, DCI);
  case X86ISD::BT:          return combineBT(N, DAG, DCI);
  case ISD::ANY_EXTEND:
  case ISD::ZERO_EXTEND:    return combineZext(N, DAG, DCI, Subtarget);
  case ISD::SIGN_EXTEND:    return combineSext(N, DAG, DCI, Subtarget);
  case ISD::SIGN_EXTEND_INREG: return combineSignExtendInReg(N, DAG, Subtarget);
  case ISD::ANY_EXTEND_VECTOR_INREG:
  case ISD::SIGN_EXTEND_VECTOR_INREG:
  case ISD::ZERO_EXTEND_VECTOR_INREG: return combineExtInVec(N, DAG, DCI,
                                                             Subtarget);
  case ISD::SETCC:          return combineSetCC(N, DAG, Subtarget);
  case X86ISD::SETCC:       return combineX86SetCC(N, DAG, Subtarget);
  case X86ISD::BRCOND:      return combineBrCond(N, DAG, Subtarget);
  case X86ISD::PACKSS:
  case X86ISD::PACKUS:      return combineVectorPack(N, DAG, DCI, Subtarget);
  case X86ISD::VSHL:
  case X86ISD::VSRA:
  case X86ISD::VSRL:
    return combineVectorShiftVar(N, DAG, DCI, Subtarget);
  case X86ISD::VSHLI:
  case X86ISD::VSRAI:
  case X86ISD::VSRLI:
    return combineVectorShiftImm(N, DAG, DCI, Subtarget);
  case ISD::INSERT_VECTOR_ELT:
  case X86ISD::PINSRB:
  case X86ISD::PINSRW:      return combineVectorInsert(N, DAG, DCI, Subtarget);
  case X86ISD::SHUFP:       // Handle all target specific shuffles
  case X86ISD::INSERTPS:
  case X86ISD::EXTRQI:
  case X86ISD::INSERTQI:
  case X86ISD::VALIGN:
  case X86ISD::PALIGNR:
  case X86ISD::VSHLDQ:
  case X86ISD::VSRLDQ:
  case X86ISD::BLENDI:
  case X86ISD::UNPCKH:
  case X86ISD::UNPCKL:
  case X86ISD::MOVHLPS:
  case X86ISD::MOVLHPS:
  case X86ISD::PSHUFB:
  case X86ISD::PSHUFD:
  case X86ISD::PSHUFHW:
  case X86ISD::PSHUFLW:
  case X86ISD::MOVSHDUP:
  case X86ISD::MOVSLDUP:
  case X86ISD::MOVDDUP:
  case X86ISD::MOVSS:
  case X86ISD::MOVSD:
  case X86ISD::VBROADCAST:
  case X86ISD::VPPERM:
  case X86ISD::VPERMI:
  case X86ISD::VPERMV:
  case X86ISD::VPERMV3:
  case X86ISD::VPERMIL2:
  case X86ISD::VPERMILPI:
  case X86ISD::VPERMILPV:
  case X86ISD::VPERM2X128:
  case X86ISD::SHUF128:
  case X86ISD::VZEXT_MOVL:
  case ISD::VECTOR_SHUFFLE: return combineShuffle(N, DAG, DCI,Subtarget);
  case X86ISD::FMADD_RND:
  case X86ISD::FMSUB:
  case X86ISD::STRICT_FMSUB:
  case X86ISD::FMSUB_RND:
  case X86ISD::FNMADD:
  case X86ISD::STRICT_FNMADD:
  case X86ISD::FNMADD_RND:
  case X86ISD::FNMSUB:
  case X86ISD::STRICT_FNMSUB:
  case X86ISD::FNMSUB_RND:
  case ISD::FMA:
  case ISD::STRICT_FMA:     return combineFMA(N, DAG, DCI, Subtarget);
  case X86ISD::FMADDSUB_RND:
  case X86ISD::FMSUBADD_RND:
  case X86ISD::FMADDSUB:
  case X86ISD::FMSUBADD:    return combineFMADDSUB(N, DAG, DCI);
  case X86ISD::MOVMSK:      return combineMOVMSK(N, DAG, DCI, Subtarget);
  case X86ISD::MGATHER:
  case X86ISD::MSCATTER:    return combineX86GatherScatter(N, DAG, DCI);
  case ISD::MGATHER:
  case ISD::MSCATTER:       return combineGatherScatter(N, DAG, DCI);
  case X86ISD::PCMPEQ:
  case X86ISD::PCMPGT:      return combineVectorCompare(N, DAG, Subtarget);
  case X86ISD::PMULDQ:
  case X86ISD::PMULUDQ:     return combinePMULDQ(N, DAG, DCI, Subtarget);
  case X86ISD::KSHIFTL:
  case X86ISD::KSHIFTR:     return combineKSHIFT(N, DAG, DCI);
  case ISD::FP16_TO_FP:     return combineFP16_TO_FP(N, DAG, Subtarget);
  case ISD::STRICT_FP_EXTEND:
  case ISD::FP_EXTEND:      return combineFP_EXTEND(N, DAG, Subtarget);
  case ISD::FP_ROUND:       return combineFP_ROUND(N, DAG, Subtarget);
  case X86ISD::VBROADCAST_LOAD: return combineVBROADCAST_LOAD(N, DAG, DCI);
  }

  return SDValue();
}

bool X86TargetLowering::isTypeDesirableForOp(unsigned Opc, EVT VT) const {
  if (!isTypeLegal(VT))
    return false;

  // There are no vXi8 shifts.
  if (Opc == ISD::SHL && VT.isVector() && VT.getVectorElementType() == MVT::i8)
    return false;

  // TODO: Almost no 8-bit ops are desirable because they have no actual
  //       size/speed advantages vs. 32-bit ops, but they do have a major
  //       potential disadvantage by causing partial register stalls.
  //
  // 8-bit multiply/shl is probably not cheaper than 32-bit multiply/shl, and
  // we have specializations to turn 32-bit multiply/shl into LEA or other ops.
  // Also, see the comment in "IsDesirableToPromoteOp" - where we additionally
  // check for a constant operand to the multiply.
  if ((Opc == ISD::MUL || Opc == ISD::SHL) && VT == MVT::i8)
    return false;

  // i16 instruction encodings are longer and some i16 instructions are slow,
  // so those are not desirable.
  if (VT == MVT::i16) {
    switch (Opc) {
    default:
      break;
    case ISD::LOAD:
    case ISD::SIGN_EXTEND:
    case ISD::ZERO_EXTEND:
    case ISD::ANY_EXTEND:
    case ISD::SHL:
    case ISD::SRA:
    case ISD::SRL:
    case ISD::SUB:
    case ISD::ADD:
    case ISD::MUL:
    case ISD::AND:
    case ISD::OR:
    case ISD::XOR:
      return false;
    }
  }

  // Any legal type not explicitly accounted for above here is desirable.
  return true;
}

SDValue X86TargetLowering::expandIndirectJTBranch(const SDLoc& dl,
                                                  SDValue Value, SDValue Addr,
                                                  SelectionDAG &DAG) const {
  const Module *M = DAG.getMachineFunction().getMMI().getModule();
  Metadata *IsCFProtectionSupported = M->getModuleFlag("cf-protection-branch");
  if (IsCFProtectionSupported) {
    // In case control-flow branch protection is enabled, we need to add
    // notrack prefix to the indirect branch.
    // In order to do that we create NT_BRIND SDNode.
    // Upon ISEL, the pattern will convert it to jmp with NoTrack prefix.
    return DAG.getNode(X86ISD::NT_BRIND, dl, MVT::Other, Value, Addr);
  }

  return TargetLowering::expandIndirectJTBranch(dl, Value, Addr, DAG);
}

bool X86TargetLowering::IsDesirableToPromoteOp(SDValue Op, EVT &PVT) const {
  EVT VT = Op.getValueType();
  bool Is8BitMulByConstant = VT == MVT::i8 && Op.getOpcode() == ISD::MUL &&
                             isa<ConstantSDNode>(Op.getOperand(1));

  // i16 is legal, but undesirable since i16 instruction encodings are longer
  // and some i16 instructions are slow.
  // 8-bit multiply-by-constant can usually be expanded to something cheaper
  // using LEA and/or other ALU ops.
  if (VT != MVT::i16 && !Is8BitMulByConstant)
    return false;

  auto IsFoldableRMW = [](SDValue Load, SDValue Op) {
    if (!Op.hasOneUse())
      return false;
    SDNode *User = *Op->use_begin();
    if (!ISD::isNormalStore(User))
      return false;
    auto *Ld = cast<LoadSDNode>(Load);
    auto *St = cast<StoreSDNode>(User);
    return Ld->getBasePtr() == St->getBasePtr();
  };

  auto IsFoldableAtomicRMW = [](SDValue Load, SDValue Op) {
    if (!Load.hasOneUse() || Load.getOpcode() != ISD::ATOMIC_LOAD)
      return false;
    if (!Op.hasOneUse())
      return false;
    SDNode *User = *Op->use_begin();
    if (User->getOpcode() != ISD::ATOMIC_STORE)
      return false;
    auto *Ld = cast<AtomicSDNode>(Load);
    auto *St = cast<AtomicSDNode>(User);
    return Ld->getBasePtr() == St->getBasePtr();
  };

  bool Commute = false;
  switch (Op.getOpcode()) {
  default: return false;
  case ISD::SIGN_EXTEND:
  case ISD::ZERO_EXTEND:
  case ISD::ANY_EXTEND:
    break;
  case ISD::SHL:
  case ISD::SRA:
  case ISD::SRL: {
    SDValue N0 = Op.getOperand(0);
    // Look out for (store (shl (load), x)).
    if (MayFoldLoad(N0) && IsFoldableRMW(N0, Op))
      return false;
    break;
  }
  case ISD::ADD:
  case ISD::MUL:
  case ISD::AND:
  case ISD::OR:
  case ISD::XOR:
    Commute = true;
    LLVM_FALLTHROUGH;
  case ISD::SUB: {
    SDValue N0 = Op.getOperand(0);
    SDValue N1 = Op.getOperand(1);
    // Avoid disabling potential load folding opportunities.
    if (MayFoldLoad(N1) &&
        (!Commute || !isa<ConstantSDNode>(N0) ||
         (Op.getOpcode() != ISD::MUL && IsFoldableRMW(N1, Op))))
      return false;
    if (MayFoldLoad(N0) &&
        ((Commute && !isa<ConstantSDNode>(N1)) ||
         (Op.getOpcode() != ISD::MUL && IsFoldableRMW(N0, Op))))
      return false;
    if (IsFoldableAtomicRMW(N0, Op) ||
        (Commute && IsFoldableAtomicRMW(N1, Op)))
      return false;
  }
  }

  PVT = MVT::i32;
  return true;
}

//===----------------------------------------------------------------------===//
//                           X86 Inline Assembly Support
//===----------------------------------------------------------------------===//

// Helper to match a string separated by whitespace.
static bool matchAsm(StringRef S, ArrayRef<const char *> Pieces) {
  S = S.substr(S.find_first_not_of(" \t")); // Skip leading whitespace.

  for (StringRef Piece : Pieces) {
    if (!S.startswith(Piece)) // Check if the piece matches.
      return false;

    S = S.substr(Piece.size());
    StringRef::size_type Pos = S.find_first_not_of(" \t");
    if (Pos == 0) // We matched a prefix.
      return false;

    S = S.substr(Pos);
  }

  return S.empty();
}

static bool clobbersFlagRegisters(const SmallVector<StringRef, 4> &AsmPieces) {

  if (AsmPieces.size() == 3 || AsmPieces.size() == 4) {
    if (std::count(AsmPieces.begin(), AsmPieces.end(), "~{cc}") &&
        std::count(AsmPieces.begin(), AsmPieces.end(), "~{flags}") &&
        std::count(AsmPieces.begin(), AsmPieces.end(), "~{fpsr}")) {

      if (AsmPieces.size() == 3)
        return true;
      else if (std::count(AsmPieces.begin(), AsmPieces.end(), "~{dirflag}"))
        return true;
    }
  }
  return false;
}

bool X86TargetLowering::ExpandInlineAsm(CallInst *CI) const {
  InlineAsm *IA = cast<InlineAsm>(CI->getCalledValue());

  const std::string &AsmStr = IA->getAsmString();

  IntegerType *Ty = dyn_cast<IntegerType>(CI->getType());
  if (!Ty || Ty->getBitWidth() % 16 != 0)
    return false;

  // TODO: should remove alternatives from the asmstring: "foo {a|b}" -> "foo a"
  SmallVector<StringRef, 4> AsmPieces;
  SplitString(AsmStr, AsmPieces, ";\n");

  switch (AsmPieces.size()) {
  default: return false;
  case 1:
    // FIXME: this should verify that we are targeting a 486 or better.  If not,
    // we will turn this bswap into something that will be lowered to logical
    // ops instead of emitting the bswap asm.  For now, we don't support 486 or
    // lower so don't worry about this.
    // bswap $0
    if (matchAsm(AsmPieces[0], {"bswap", "$0"}) ||
        matchAsm(AsmPieces[0], {"bswapl", "$0"}) ||
        matchAsm(AsmPieces[0], {"bswapq", "$0"}) ||
        matchAsm(AsmPieces[0], {"bswap", "${0:q}"}) ||
        matchAsm(AsmPieces[0], {"bswapl", "${0:q}"}) ||
        matchAsm(AsmPieces[0], {"bswapq", "${0:q}"})) {
      // No need to check constraints, nothing other than the equivalent of
      // "=r,0" would be valid here.
      return IntrinsicLowering::LowerToByteSwap(CI);
    }

    // rorw $$8, ${0:w}  -->  llvm.bswap.i16
    if (CI->getType()->isIntegerTy(16) &&
        IA->getConstraintString().compare(0, 5, "=r,0,") == 0 &&
        (matchAsm(AsmPieces[0], {"rorw", "$$8,", "${0:w}"}) ||
         matchAsm(AsmPieces[0], {"rolw", "$$8,", "${0:w}"}))) {
      AsmPieces.clear();
      StringRef ConstraintsStr = IA->getConstraintString();
      SplitString(StringRef(ConstraintsStr).substr(5), AsmPieces, ",");
      array_pod_sort(AsmPieces.begin(), AsmPieces.end());
      if (clobbersFlagRegisters(AsmPieces))
        return IntrinsicLowering::LowerToByteSwap(CI);
    }
    break;
  case 3:
    if (CI->getType()->isIntegerTy(32) &&
        IA->getConstraintString().compare(0, 5, "=r,0,") == 0 &&
        matchAsm(AsmPieces[0], {"rorw", "$$8,", "${0:w}"}) &&
        matchAsm(AsmPieces[1], {"rorl", "$$16,", "$0"}) &&
        matchAsm(AsmPieces[2], {"rorw", "$$8,", "${0:w}"})) {
      AsmPieces.clear();
      StringRef ConstraintsStr = IA->getConstraintString();
      SplitString(StringRef(ConstraintsStr).substr(5), AsmPieces, ",");
      array_pod_sort(AsmPieces.begin(), AsmPieces.end());
      if (clobbersFlagRegisters(AsmPieces))
        return IntrinsicLowering::LowerToByteSwap(CI);
    }

    if (CI->getType()->isIntegerTy(64)) {
      InlineAsm::ConstraintInfoVector Constraints = IA->ParseConstraints();
      if (Constraints.size() >= 2 &&
          Constraints[0].Codes.size() == 1 && Constraints[0].Codes[0] == "A" &&
          Constraints[1].Codes.size() == 1 && Constraints[1].Codes[0] == "0") {
        // bswap %eax / bswap %edx / xchgl %eax, %edx  -> llvm.bswap.i64
        if (matchAsm(AsmPieces[0], {"bswap", "%eax"}) &&
            matchAsm(AsmPieces[1], {"bswap", "%edx"}) &&
            matchAsm(AsmPieces[2], {"xchgl", "%eax,", "%edx"}))
          return IntrinsicLowering::LowerToByteSwap(CI);
      }
    }
    break;
  }
  return false;
}

static X86::CondCode parseConstraintCode(llvm::StringRef Constraint) {
  X86::CondCode Cond = StringSwitch<X86::CondCode>(Constraint)
                           .Case("{@cca}", X86::COND_A)
                           .Case("{@ccae}", X86::COND_AE)
                           .Case("{@ccb}", X86::COND_B)
                           .Case("{@ccbe}", X86::COND_BE)
                           .Case("{@ccc}", X86::COND_B)
                           .Case("{@cce}", X86::COND_E)
                           .Case("{@ccz}", X86::COND_E)
                           .Case("{@ccg}", X86::COND_G)
                           .Case("{@ccge}", X86::COND_GE)
                           .Case("{@ccl}", X86::COND_L)
                           .Case("{@ccle}", X86::COND_LE)
                           .Case("{@ccna}", X86::COND_BE)
                           .Case("{@ccnae}", X86::COND_B)
                           .Case("{@ccnb}", X86::COND_AE)
                           .Case("{@ccnbe}", X86::COND_A)
                           .Case("{@ccnc}", X86::COND_AE)
                           .Case("{@ccne}", X86::COND_NE)
                           .Case("{@ccnz}", X86::COND_NE)
                           .Case("{@ccng}", X86::COND_LE)
                           .Case("{@ccnge}", X86::COND_L)
                           .Case("{@ccnl}", X86::COND_GE)
                           .Case("{@ccnle}", X86::COND_G)
                           .Case("{@ccno}", X86::COND_NO)
                           .Case("{@ccnp}", X86::COND_P)
                           .Case("{@ccns}", X86::COND_NS)
                           .Case("{@cco}", X86::COND_O)
                           .Case("{@ccp}", X86::COND_P)
                           .Case("{@ccs}", X86::COND_S)
                           .Default(X86::COND_INVALID);
  return Cond;
}

/// Given a constraint letter, return the type of constraint for this target.
X86TargetLowering::ConstraintType
X86TargetLowering::getConstraintType(StringRef Constraint) const {
  if (Constraint.size() == 1) {
    switch (Constraint[0]) {
    case 'R':
    case 'q':
    case 'Q':
    case 'f':
    case 't':
    case 'u':
    case 'y':
    case 'x':
    case 'v':
    case 'Y':
    case 'l':
    case 'k': // AVX512 masking registers.
      return C_RegisterClass;
    case 'a':
    case 'b':
    case 'c':
    case 'd':
    case 'S':
    case 'D':
    case 'A':
      return C_Register;
    case 'I':
    case 'J':
    case 'K':
    case 'N':
    case 'G':
    case 'L':
    case 'M':
      return C_Immediate;
    case 'C':
    case 'e':
    case 'Z':
      return C_Other;
    default:
      break;
    }
  }
  else if (Constraint.size() == 2) {
    switch (Constraint[0]) {
    default:
      break;
    case 'Y':
      switch (Constraint[1]) {
      default:
        break;
      case 'z':
      case '0':
        return C_Register;
      case 'i':
      case 'm':
      case 'k':
      case 't':
      case '2':
        return C_RegisterClass;
      }
    }
  } else if (parseConstraintCode(Constraint) != X86::COND_INVALID)
    return C_Other;
  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
  X86TargetLowering::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.
  switch (*constraint) {
  default:
    weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);
    LLVM_FALLTHROUGH;
  case 'R':
  case 'q':
  case 'Q':
  case 'a':
  case 'b':
  case 'c':
  case 'd':
  case 'S':
  case 'D':
  case 'A':
    if (CallOperandVal->getType()->isIntegerTy())
      weight = CW_SpecificReg;
    break;
  case 'f':
  case 't':
  case 'u':
    if (type->isFloatingPointTy())
      weight = CW_SpecificReg;
    break;
  case 'y':
    if (type->isX86_MMXTy() && Subtarget.hasMMX())
      weight = CW_SpecificReg;
    break;
  case 'Y': {
    unsigned Size = StringRef(constraint).size();
    // Pick 'i' as the next char as 'Yi' and 'Y' are synonymous, when matching 'Y'
    char NextChar = Size == 2 ? constraint[1] : 'i';
    if (Size > 2)
      break;
    switch (NextChar) {
      default:
        return CW_Invalid;
      // XMM0
      case 'z':
      case '0':
        if ((type->getPrimitiveSizeInBits() == 128) && Subtarget.hasSSE1())
          return CW_SpecificReg;
        return CW_Invalid;
      // Conditional OpMask regs (AVX512)
      case 'k':
        if ((type->getPrimitiveSizeInBits() == 64) && Subtarget.hasAVX512())
          return CW_Register;
        return CW_Invalid;
      // Any MMX reg
      case 'm':
        if (type->isX86_MMXTy() && Subtarget.hasMMX())
          return weight;
        return CW_Invalid;
      // Any SSE reg when ISA >= SSE2, same as 'Y'
      case 'i':
      case 't':
      case '2':
        if (!Subtarget.hasSSE2())
          return CW_Invalid;
        break;
    }
    // Fall through (handle "Y" constraint).
    LLVM_FALLTHROUGH;
  }
  case 'v':
    if ((type->getPrimitiveSizeInBits() == 512) && Subtarget.hasAVX512())
      weight = CW_Register;
    LLVM_FALLTHROUGH;
  case 'x':
    if (((type->getPrimitiveSizeInBits() == 128) && Subtarget.hasSSE1()) ||
        ((type->getPrimitiveSizeInBits() == 256) && Subtarget.hasAVX()))
      weight = CW_Register;
    break;
  case 'k':
    // Enable conditional vector operations using %k<#> registers.
    if ((type->getPrimitiveSizeInBits() == 64) && Subtarget.hasAVX512())
      weight = CW_Register;
    break;
  case 'I':
    if (ConstantInt *C = dyn_cast<ConstantInt>(info.CallOperandVal)) {
      if (C->getZExtValue() <= 31)
        weight = CW_Constant;
    }
    break;
  case 'J':
    if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) {
      if (C->getZExtValue() <= 63)
        weight = CW_Constant;
    }
    break;
  case 'K':
    if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) {
      if ((C->getSExtValue() >= -0x80) && (C->getSExtValue() <= 0x7f))
        weight = CW_Constant;
    }
    break;
  case 'L':
    if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) {
      if ((C->getZExtValue() == 0xff) || (C->getZExtValue() == 0xffff))
        weight = CW_Constant;
    }
    break;
  case 'M':
    if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) {
      if (C->getZExtValue() <= 3)
        weight = CW_Constant;
    }
    break;
  case 'N':
    if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) {
      if (C->getZExtValue() <= 0xff)
        weight = CW_Constant;
    }
    break;
  case 'G':
  case 'C':
    if (isa<ConstantFP>(CallOperandVal)) {
      weight = CW_Constant;
    }
    break;
  case 'e':
    if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) {
      if ((C->getSExtValue() >= -0x80000000LL) &&
          (C->getSExtValue() <= 0x7fffffffLL))
        weight = CW_Constant;
    }
    break;
  case 'Z':
    if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) {
      if (C->getZExtValue() <= 0xffffffff)
        weight = CW_Constant;
    }
    break;
  }
  return weight;
}

/// Try to replace an X constraint, which matches anything, with another that
/// has more specific requirements based on the type of the corresponding
/// operand.
const char *X86TargetLowering::
LowerXConstraint(EVT ConstraintVT) const {
  // FP X constraints get lowered to SSE1/2 registers if available, otherwise
  // 'f' like normal targets.
  if (ConstraintVT.isFloatingPoint()) {
    if (Subtarget.hasSSE2())
      return "Y";
    if (Subtarget.hasSSE1())
      return "x";
  }

  return TargetLowering::LowerXConstraint(ConstraintVT);
}

// Lower @cc targets via setcc.
SDValue X86TargetLowering::LowerAsmOutputForConstraint(
    SDValue &Chain, SDValue &Flag, SDLoc DL, const AsmOperandInfo &OpInfo,
    SelectionDAG &DAG) const {
  X86::CondCode Cond = parseConstraintCode(OpInfo.ConstraintCode);
  if (Cond == X86::COND_INVALID)
    return SDValue();
  // Check that return type is valid.
  if (OpInfo.ConstraintVT.isVector() || !OpInfo.ConstraintVT.isInteger() ||
      OpInfo.ConstraintVT.getSizeInBits() < 8)
    report_fatal_error("Flag output operand is of invalid type");

  // Get EFLAGS register. Only update chain when copyfrom is glued.
  if (Flag.getNode()) {
    Flag = DAG.getCopyFromReg(Chain, DL, X86::EFLAGS, MVT::i32, Flag);
    Chain = Flag.getValue(1);
  } else
    Flag = DAG.getCopyFromReg(Chain, DL, X86::EFLAGS, MVT::i32);
  // Extract CC code.
  SDValue CC = getSETCC(Cond, Flag, DL, DAG);
  // Extend to 32-bits
  SDValue Result = DAG.getNode(ISD::ZERO_EXTEND, DL, OpInfo.ConstraintVT, CC);

  return Result;
}

/// Lower the specified operand into the Ops vector.
/// If it is invalid, don't add anything to Ops.
void X86TargetLowering::LowerAsmOperandForConstraint(SDValue Op,
                                                     std::string &Constraint,
                                                     std::vector<SDValue>&Ops,
                                                     SelectionDAG &DAG) const {
  SDValue Result;

  // Only support length 1 constraints for now.
  if (Constraint.length() > 1) return;

  char ConstraintLetter = Constraint[0];
  switch (ConstraintLetter) {
  default: break;
  case 'I':
    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
      if (C->getZExtValue() <= 31) {
        Result = DAG.getTargetConstant(C->getZExtValue(), SDLoc(Op),
                                       Op.getValueType());
        break;
      }
    }
    return;
  case 'J':
    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
      if (C->getZExtValue() <= 63) {
        Result = DAG.getTargetConstant(C->getZExtValue(), SDLoc(Op),
                                       Op.getValueType());
        break;
      }
    }
    return;
  case 'K':
    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
      if (isInt<8>(C->getSExtValue())) {
        Result = DAG.getTargetConstant(C->getZExtValue(), SDLoc(Op),
                                       Op.getValueType());
        break;
      }
    }
    return;
  case 'L':
    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
      if (C->getZExtValue() == 0xff || C->getZExtValue() == 0xffff ||
          (Subtarget.is64Bit() && C->getZExtValue() == 0xffffffff)) {
        Result = DAG.getTargetConstant(C->getSExtValue(), SDLoc(Op),
                                       Op.getValueType());
        break;
      }
    }
    return;
  case 'M':
    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
      if (C->getZExtValue() <= 3) {
        Result = DAG.getTargetConstant(C->getZExtValue(), SDLoc(Op),
                                       Op.getValueType());
        break;
      }
    }
    return;
  case 'N':
    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
      if (C->getZExtValue() <= 255) {
        Result = DAG.getTargetConstant(C->getZExtValue(), SDLoc(Op),
                                       Op.getValueType());
        break;
      }
    }
    return;
  case 'O':
    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
      if (C->getZExtValue() <= 127) {
        Result = DAG.getTargetConstant(C->getZExtValue(), SDLoc(Op),
                                       Op.getValueType());
        break;
      }
    }
    return;
  case 'e': {
    // 32-bit signed value
    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
      if (ConstantInt::isValueValidForType(Type::getInt32Ty(*DAG.getContext()),
                                           C->getSExtValue())) {
        // Widen to 64 bits here to get it sign extended.
        Result = DAG.getTargetConstant(C->getSExtValue(), SDLoc(Op), MVT::i64);
        break;
      }
    // FIXME gcc accepts some relocatable values here too, but only in certain
    // memory models; it's complicated.
    }
    return;
  }
  case 'Z': {
    // 32-bit unsigned value
    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
      if (ConstantInt::isValueValidForType(Type::getInt32Ty(*DAG.getContext()),
                                           C->getZExtValue())) {
        Result = DAG.getTargetConstant(C->getZExtValue(), SDLoc(Op),
                                       Op.getValueType());
        break;
      }
    }
    // FIXME gcc accepts some relocatable values here too, but only in certain
    // memory models; it's complicated.
    return;
  }
  case 'i': {
    // Literal immediates are always ok.
    if (ConstantSDNode *CST = dyn_cast<ConstantSDNode>(Op)) {
      bool IsBool = CST->getConstantIntValue()->getBitWidth() == 1;
      BooleanContent BCont = getBooleanContents(MVT::i64);
      ISD::NodeType ExtOpc = IsBool ? getExtendForContent(BCont)
                                    : ISD::SIGN_EXTEND;
      int64_t ExtVal = ExtOpc == ISD::ZERO_EXTEND ? CST->getZExtValue()
                                                  : CST->getSExtValue();
      Result = DAG.getTargetConstant(ExtVal, SDLoc(Op), MVT::i64);
      break;
    }

    // In any sort of PIC mode addresses need to be computed at runtime by
    // adding in a register or some sort of table lookup.  These can't
    // be used as immediates.
    if (Subtarget.isPICStyleGOT() || Subtarget.isPICStyleStubPIC())
      return;

    // If we are in non-pic codegen mode, we allow the address of a global (with
    // an optional displacement) to be used with 'i'.
    if (auto *GA = dyn_cast<GlobalAddressSDNode>(Op))
      // If we require an extra load to get this address, as in PIC mode, we
      // can't accept it.
      if (isGlobalStubReference(
              Subtarget.classifyGlobalReference(GA->getGlobal())))
        return;
    break;
  }
  }

  if (Result.getNode()) {
    Ops.push_back(Result);
    return;
  }
  return TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);
}

/// Check if \p RC is a general purpose register class.
/// I.e., GR* or one of their variant.
static bool isGRClass(const TargetRegisterClass &RC) {
  return RC.hasSuperClassEq(&X86::GR8RegClass) ||
         RC.hasSuperClassEq(&X86::GR16RegClass) ||
         RC.hasSuperClassEq(&X86::GR32RegClass) ||
         RC.hasSuperClassEq(&X86::GR64RegClass) ||
         RC.hasSuperClassEq(&X86::LOW32_ADDR_ACCESS_RBPRegClass);
}

/// Check if \p RC is a vector register class.
/// I.e., FR* / VR* or one of their variant.
static bool isFRClass(const TargetRegisterClass &RC) {
  return RC.hasSuperClassEq(&X86::FR32XRegClass) ||
         RC.hasSuperClassEq(&X86::FR64XRegClass) ||
         RC.hasSuperClassEq(&X86::VR128XRegClass) ||
         RC.hasSuperClassEq(&X86::VR256XRegClass) ||
         RC.hasSuperClassEq(&X86::VR512RegClass);
}

/// Check if \p RC is a mask register class.
/// I.e., VK* or one of their variant.
static bool isVKClass(const TargetRegisterClass &RC) {
  return RC.hasSuperClassEq(&X86::VK1RegClass) ||
         RC.hasSuperClassEq(&X86::VK2RegClass) ||
         RC.hasSuperClassEq(&X86::VK4RegClass) ||
         RC.hasSuperClassEq(&X86::VK8RegClass) ||
         RC.hasSuperClassEq(&X86::VK16RegClass) ||
         RC.hasSuperClassEq(&X86::VK32RegClass) ||
         RC.hasSuperClassEq(&X86::VK64RegClass);
}

std::pair<unsigned, const TargetRegisterClass *>
X86TargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
                                                StringRef Constraint,
                                                MVT VT) const {
  // First, see if this is a constraint that directly corresponds to an LLVM
  // register class.
  if (Constraint.size() == 1) {
    // GCC Constraint Letters
    switch (Constraint[0]) {
    default: break;
    // 'A' means [ER]AX + [ER]DX.
    case 'A':
      if (Subtarget.is64Bit())
        return std::make_pair(X86::RAX, &X86::GR64_ADRegClass);
      assert((Subtarget.is32Bit() || Subtarget.is16Bit()) &&
             "Expecting 64, 32 or 16 bit subtarget");
      return std::make_pair(X86::EAX, &X86::GR32_ADRegClass);

      // TODO: Slight differences here in allocation order and leaving
      // RIP in the class. Do they matter any more here than they do
      // in the normal allocation?
    case 'k':
      if (Subtarget.hasAVX512()) {
        if (VT == MVT::i1)
          return std::make_pair(0U, &X86::VK1RegClass);
        if (VT == MVT::i8)
          return std::make_pair(0U, &X86::VK8RegClass);
        if (VT == MVT::i16)
          return std::make_pair(0U, &X86::VK16RegClass);
      }
      if (Subtarget.hasBWI()) {
        if (VT == MVT::i32)
          return std::make_pair(0U, &X86::VK32RegClass);
        if (VT == MVT::i64)
          return std::make_pair(0U, &X86::VK64RegClass);
      }
      break;
    case 'q':   // GENERAL_REGS in 64-bit mode, Q_REGS in 32-bit mode.
      if (Subtarget.is64Bit()) {
        if (VT == MVT::i32 || VT == MVT::f32)
          return std::make_pair(0U, &X86::GR32RegClass);
        if (VT == MVT::i16)
          return std::make_pair(0U, &X86::GR16RegClass);
        if (VT == MVT::i8 || VT == MVT::i1)
          return std::make_pair(0U, &X86::GR8RegClass);
        if (VT == MVT::i64 || VT == MVT::f64)
          return std::make_pair(0U, &X86::GR64RegClass);
        break;
      }
      LLVM_FALLTHROUGH;
      // 32-bit fallthrough
    case 'Q':   // Q_REGS
      if (VT == MVT::i32 || VT == MVT::f32)
        return std::make_pair(0U, &X86::GR32_ABCDRegClass);
      if (VT == MVT::i16)
        return std::make_pair(0U, &X86::GR16_ABCDRegClass);
      if (VT == MVT::i8 || VT == MVT::i1)
        return std::make_pair(0U, &X86::GR8_ABCD_LRegClass);
      if (VT == MVT::i64)
        return std::make_pair(0U, &X86::GR64_ABCDRegClass);
      break;
    case 'r':   // GENERAL_REGS
    case 'l':   // INDEX_REGS
      if (VT == MVT::i8 || VT == MVT::i1)
        return std::make_pair(0U, &X86::GR8RegClass);
      if (VT == MVT::i16)
        return std::make_pair(0U, &X86::GR16RegClass);
      if (VT == MVT::i32 || VT == MVT::f32 || !Subtarget.is64Bit())
        return std::make_pair(0U, &X86::GR32RegClass);
      return std::make_pair(0U, &X86::GR64RegClass);
    case 'R':   // LEGACY_REGS
      if (VT == MVT::i8 || VT == MVT::i1)
        return std::make_pair(0U, &X86::GR8_NOREXRegClass);
      if (VT == MVT::i16)
        return std::make_pair(0U, &X86::GR16_NOREXRegClass);
      if (VT == MVT::i32 || !Subtarget.is64Bit())
        return std::make_pair(0U, &X86::GR32_NOREXRegClass);
      return std::make_pair(0U, &X86::GR64_NOREXRegClass);
    case 'f':  // FP Stack registers.
      // If SSE is enabled for this VT, use f80 to ensure the isel moves the
      // value to the correct fpstack register class.
      if (VT == MVT::f32 && !isScalarFPTypeInSSEReg(VT))
        return std::make_pair(0U, &X86::RFP32RegClass);
      if (VT == MVT::f64 && !isScalarFPTypeInSSEReg(VT))
        return std::make_pair(0U, &X86::RFP64RegClass);
      return std::make_pair(0U, &X86::RFP80RegClass);
    case 'y':   // MMX_REGS if MMX allowed.
      if (!Subtarget.hasMMX()) break;
      return std::make_pair(0U, &X86::VR64RegClass);
    case 'Y':   // SSE_REGS if SSE2 allowed
      if (!Subtarget.hasSSE2()) break;
      LLVM_FALLTHROUGH;
    case 'v':
    case 'x':   // SSE_REGS if SSE1 allowed or AVX_REGS if AVX allowed
      if (!Subtarget.hasSSE1()) break;
      bool VConstraint = (Constraint[0] == 'v');

      switch (VT.SimpleTy) {
      default: break;
      // Scalar SSE types.
      case MVT::f32:
      case MVT::i32:
        if (VConstraint && Subtarget.hasVLX())
          return std::make_pair(0U, &X86::FR32XRegClass);
        return std::make_pair(0U, &X86::FR32RegClass);
      case MVT::f64:
      case MVT::i64:
        if (VConstraint && Subtarget.hasVLX())
          return std::make_pair(0U, &X86::FR64XRegClass);
        return std::make_pair(0U, &X86::FR64RegClass);
      // TODO: Handle i128 in FR128RegClass after it is tested well.
      // Vector types and fp128.
      case MVT::f128:
      case MVT::v16i8:
      case MVT::v8i16:
      case MVT::v4i32:
      case MVT::v2i64:
      case MVT::v4f32:
      case MVT::v2f64:
        if (VConstraint && Subtarget.hasVLX())
          return std::make_pair(0U, &X86::VR128XRegClass);
        return std::make_pair(0U, &X86::VR128RegClass);
      // AVX types.
      case MVT::v32i8:
      case MVT::v16i16:
      case MVT::v8i32:
      case MVT::v4i64:
      case MVT::v8f32:
      case MVT::v4f64:
        if (VConstraint && Subtarget.hasVLX())
          return std::make_pair(0U, &X86::VR256XRegClass);
        if (Subtarget.hasAVX())
          return std::make_pair(0U, &X86::VR256RegClass);
        break;
      case MVT::v8f64:
      case MVT::v16f32:
      case MVT::v16i32:
      case MVT::v8i64:
        if (!Subtarget.hasAVX512()) break;
        if (VConstraint)
          return std::make_pair(0U, &X86::VR512RegClass);
        return std::make_pair(0U, &X86::VR512_0_15RegClass);
      }
      break;
    }
  } else if (Constraint.size() == 2 && Constraint[0] == 'Y') {
    switch (Constraint[1]) {
    default:
      break;
    case 'i':
    case 't':
    case '2':
      return getRegForInlineAsmConstraint(TRI, "Y", VT);
    case 'm':
      if (!Subtarget.hasMMX()) break;
      return std::make_pair(0U, &X86::VR64RegClass);
    case 'z':
    case '0':
      if (!Subtarget.hasSSE1()) break;
      return std::make_pair(X86::XMM0, &X86::VR128RegClass);
    case 'k':
      // This register class doesn't allocate k0 for masked vector operation.
      if (Subtarget.hasAVX512()) {
        if (VT == MVT::i1)
          return std::make_pair(0U, &X86::VK1WMRegClass);
        if (VT == MVT::i8)
          return std::make_pair(0U, &X86::VK8WMRegClass);
        if (VT == MVT::i16)
          return std::make_pair(0U, &X86::VK16WMRegClass);
      }
      if (Subtarget.hasBWI()) {
        if (VT == MVT::i32)
          return std::make_pair(0U, &X86::VK32WMRegClass);
        if (VT == MVT::i64)
          return std::make_pair(0U, &X86::VK64WMRegClass);
      }
      break;
    }
  }

  if (parseConstraintCode(Constraint) != X86::COND_INVALID)
    return std::make_pair(0U, &X86::GR32RegClass);

  // Use the default implementation in TargetLowering to convert the register
  // constraint into a member of a register class.
  std::pair<unsigned, const TargetRegisterClass*> Res;
  Res = TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);

  // Not found as a standard register?
  if (!Res.second) {
    // Map st(0) -> st(7) -> ST0
    if (Constraint.size() == 7 && Constraint[0] == '{' &&
        tolower(Constraint[1]) == 's' && tolower(Constraint[2]) == 't' &&
        Constraint[3] == '(' &&
        (Constraint[4] >= '0' && Constraint[4] <= '7') &&
        Constraint[5] == ')' && Constraint[6] == '}') {
      // st(7) is not allocatable and thus not a member of RFP80. Return
      // singleton class in cases where we have a reference to it.
      if (Constraint[4] == '7')
        return std::make_pair(X86::FP7, &X86::RFP80_7RegClass);
      return std::make_pair(X86::FP0 + Constraint[4] - '0',
                            &X86::RFP80RegClass);
    }

    // GCC allows "st(0)" to be called just plain "st".
    if (StringRef("{st}").equals_lower(Constraint))
      return std::make_pair(X86::FP0, &X86::RFP80RegClass);

    // flags -> EFLAGS
    if (StringRef("{flags}").equals_lower(Constraint))
      return std::make_pair(X86::EFLAGS, &X86::CCRRegClass);

    // dirflag -> DF
    if (StringRef("{dirflag}").equals_lower(Constraint))
      return std::make_pair(X86::DF, &X86::DFCCRRegClass);

    // fpsr -> FPSW
    if (StringRef("{fpsr}").equals_lower(Constraint))
      return std::make_pair(X86::FPSW, &X86::FPCCRRegClass);

    return Res;
  }

  // Make sure it isn't a register that requires 64-bit mode.
  if (!Subtarget.is64Bit() &&
      (isFRClass(*Res.second) || isGRClass(*Res.second)) &&
      TRI->getEncodingValue(Res.first) >= 8) {
    // Register requires REX prefix, but we're in 32-bit mode.
    return std::make_pair(0, nullptr);
  }

  // Make sure it isn't a register that requires AVX512.
  if (!Subtarget.hasAVX512() && isFRClass(*Res.second) &&
      TRI->getEncodingValue(Res.first) & 0x10) {
    // Register requires EVEX prefix.
    return std::make_pair(0, nullptr);
  }

  // Otherwise, check to see if this is a register class of the wrong value
  // type.  For example, we want to map "{ax},i32" -> {eax}, we don't want it to
  // turn into {ax},{dx}.
  // MVT::Other is used to specify clobber names.
  if (TRI->isTypeLegalForClass(*Res.second, VT) || VT == MVT::Other)
    return Res;   // Correct type already, nothing to do.

  // Get a matching integer of the correct size. i.e. "ax" with MVT::32 should
  // return "eax". This should even work for things like getting 64bit integer
  // registers when given an f64 type.
  const TargetRegisterClass *Class = Res.second;
  // The generic code will match the first register class that contains the
  // given register. Thus, based on the ordering of the tablegened file,
  // the "plain" GR classes might not come first.
  // Therefore, use a helper method.
  if (isGRClass(*Class)) {
    unsigned Size = VT.getSizeInBits();
    if (Size == 1) Size = 8;
    unsigned DestReg = getX86SubSuperRegisterOrZero(Res.first, Size);
    if (DestReg > 0) {
      bool is64Bit = Subtarget.is64Bit();
      const TargetRegisterClass *RC =
          Size == 8 ? (is64Bit ? &X86::GR8RegClass : &X86::GR8_NOREXRegClass)
        : Size == 16 ? (is64Bit ? &X86::GR16RegClass : &X86::GR16_NOREXRegClass)
        : Size == 32 ? (is64Bit ? &X86::GR32RegClass : &X86::GR32_NOREXRegClass)
        : Size == 64 ? (is64Bit ? &X86::GR64RegClass : nullptr)
        : nullptr;
      if (Size == 64 && !is64Bit) {
        // Model GCC's behavior here and select a fixed pair of 32-bit
        // registers.
        switch (DestReg) {
        case X86::RAX:
          return std::make_pair(X86::EAX, &X86::GR32_ADRegClass);
        case X86::RDX:
          return std::make_pair(X86::EDX, &X86::GR32_DCRegClass);
        case X86::RCX:
          return std::make_pair(X86::ECX, &X86::GR32_CBRegClass);
        case X86::RBX:
          return std::make_pair(X86::EBX, &X86::GR32_BSIRegClass);
        case X86::RSI:
          return std::make_pair(X86::ESI, &X86::GR32_SIDIRegClass);
        case X86::RDI:
          return std::make_pair(X86::EDI, &X86::GR32_DIBPRegClass);
        case X86::RBP:
          return std::make_pair(X86::EBP, &X86::GR32_BPSPRegClass);
        default:
          return std::make_pair(0, nullptr);
        }
      }
      if (RC && RC->contains(DestReg))
        return std::make_pair(DestReg, RC);
      return Res;
    }
    // No register found/type mismatch.
    return std::make_pair(0, nullptr);
  } else if (isFRClass(*Class)) {
    // Handle references to XMM physical registers that got mapped into the
    // wrong class.  This can happen with constraints like {xmm0} where the
    // target independent register mapper will just pick the first match it can
    // find, ignoring the required type.

    // TODO: Handle f128 and i128 in FR128RegClass after it is tested well.
    if (VT == MVT::f32 || VT == MVT::i32)
      Res.second = &X86::FR32XRegClass;
    else if (VT == MVT::f64 || VT == MVT::i64)
      Res.second = &X86::FR64XRegClass;
    else if (TRI->isTypeLegalForClass(X86::VR128XRegClass, VT))
      Res.second = &X86::VR128XRegClass;
    else if (TRI->isTypeLegalForClass(X86::VR256XRegClass, VT))
      Res.second = &X86::VR256XRegClass;
    else if (TRI->isTypeLegalForClass(X86::VR512RegClass, VT))
      Res.second = &X86::VR512RegClass;
    else {
      // Type mismatch and not a clobber: Return an error;
      Res.first = 0;
      Res.second = nullptr;
    }
  } else if (isVKClass(*Class)) {
    if (VT == MVT::i1)
      Res.second = &X86::VK1RegClass;
    else if (VT == MVT::i8)
      Res.second = &X86::VK8RegClass;
    else if (VT == MVT::i16)
      Res.second = &X86::VK16RegClass;
    else if (VT == MVT::i32)
      Res.second = &X86::VK32RegClass;
    else if (VT == MVT::i64)
      Res.second = &X86::VK64RegClass;
    else {
      // Type mismatch and not a clobber: Return an error;
      Res.first = 0;
      Res.second = nullptr;
    }
  }

  return Res;
}

int X86TargetLowering::getScalingFactorCost(const DataLayout &DL,
                                            const AddrMode &AM, Type *Ty,
                                            unsigned AS) const {
  // Scaling factors are not free at all.
  // An indexed folded instruction, i.e., inst (reg1, reg2, scale),
  // will take 2 allocations in the out of order engine instead of 1
  // for plain addressing mode, i.e. inst (reg1).
  // E.g.,
  // vaddps (%rsi,%rdx), %ymm0, %ymm1
  // Requires two allocations (one for the load, one for the computation)
  // whereas:
  // vaddps (%rsi), %ymm0, %ymm1
  // Requires just 1 allocation, i.e., freeing allocations for other operations
  // and having less micro operations to execute.
  //
  // For some X86 architectures, this is even worse because for instance for
  // stores, the complex addressing mode forces the instruction to use the
  // "load" ports instead of the dedicated "store" port.
  // E.g., on Haswell:
  // vmovaps %ymm1, (%r8, %rdi) can use port 2 or 3.
  // vmovaps %ymm1, (%r8) can use port 2, 3, or 7.
  if (isLegalAddressingMode(DL, AM, Ty, AS))
    // Scale represents reg2 * scale, thus account for 1
    // as soon as we use a second register.
    return AM.Scale != 0;
  return -1;
}

bool X86TargetLowering::isIntDivCheap(EVT VT, AttributeList Attr) const {
  // Integer division on x86 is expensive. However, when aggressively optimizing
  // for code size, we prefer to use a div instruction, as it is usually smaller
  // than the alternative sequence.
  // The exception to this is vector division. Since x86 doesn't have vector
  // integer division, leaving the division as-is is a loss even in terms of
  // size, because it will have to be scalarized, while the alternative code
  // sequence can be performed in vector form.
  bool OptSize =
      Attr.hasAttribute(AttributeList::FunctionIndex, Attribute::MinSize);
  return OptSize && !VT.isVector();
}

void X86TargetLowering::initializeSplitCSR(MachineBasicBlock *Entry) const {
  if (!Subtarget.is64Bit())
    return;

  // Update IsSplitCSR in X86MachineFunctionInfo.
  X86MachineFunctionInfo *AFI =
      Entry->getParent()->getInfo<X86MachineFunctionInfo>();
  AFI->setIsSplitCSR(true);
}

void X86TargetLowering::insertCopiesSplitCSR(
    MachineBasicBlock *Entry,
    const SmallVectorImpl<MachineBasicBlock *> &Exits) const {
  const X86RegisterInfo *TRI = Subtarget.getRegisterInfo();
  const MCPhysReg *IStart = TRI->getCalleeSavedRegsViaCopy(Entry->getParent());
  if (!IStart)
    return;

  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
  MachineRegisterInfo *MRI = &Entry->getParent()->getRegInfo();
  MachineBasicBlock::iterator MBBI = Entry->begin();
  for (const MCPhysReg *I = IStart; *I; ++I) {
    const TargetRegisterClass *RC = nullptr;
    if (X86::GR64RegClass.contains(*I))
      RC = &X86::GR64RegClass;
    else
      llvm_unreachable("Unexpected register class in CSRsViaCopy!");

    Register NewVR = MRI->createVirtualRegister(RC);
    // Create copy from CSR to a virtual register.
    // FIXME: this currently does not emit CFI pseudo-instructions, it works
    // fine for CXX_FAST_TLS since the C++-style TLS access functions should be
    // nounwind. If we want to generalize this later, we may need to emit
    // CFI pseudo-instructions.
    assert(
        Entry->getParent()->getFunction().hasFnAttribute(Attribute::NoUnwind) &&
        "Function should be nounwind in insertCopiesSplitCSR!");
    Entry->addLiveIn(*I);
    BuildMI(*Entry, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY), NewVR)
        .addReg(*I);

    // Insert the copy-back instructions right before the terminator.
    for (auto *Exit : Exits)
      BuildMI(*Exit, Exit->getFirstTerminator(), DebugLoc(),
              TII->get(TargetOpcode::COPY), *I)
          .addReg(NewVR);
  }
}

bool X86TargetLowering::supportSwiftError() const {
  return Subtarget.is64Bit();
}

/// Returns true if stack probing through a function call is requested.
bool X86TargetLowering::hasStackProbeSymbol(MachineFunction &MF) const {
  return !getStackProbeSymbolName(MF).empty();
}

/// Returns true if stack probing through inline assembly is requested.
bool X86TargetLowering::hasInlineStackProbe(MachineFunction &MF) const {

  // No inline stack probe for Windows, they have their own mechanism.
  if (Subtarget.isOSWindows() ||
      MF.getFunction().hasFnAttribute("no-stack-arg-probe"))
    return false;

  // 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;
}

/// Returns the name of the symbol used to emit stack probes or the empty
/// string if not applicable.
StringRef
X86TargetLowering::getStackProbeSymbolName(MachineFunction &MF) const {
  // Inline Stack probes disable stack probe call
  if (hasInlineStackProbe(MF))
    return "";

  // If the function specifically requests stack probes, emit them.
  if (MF.getFunction().hasFnAttribute("probe-stack"))
    return MF.getFunction().getFnAttribute("probe-stack").getValueAsString();

  // Generally, if we aren't on Windows, the platform ABI does not include
  // support for stack probes, so don't emit them.
  if (!Subtarget.isOSWindows() || Subtarget.isTargetMachO() ||
      MF.getFunction().hasFnAttribute("no-stack-arg-probe"))
    return "";

  // We need a stack probe to conform to the Windows ABI. Choose the right
  // symbol.
  if (Subtarget.is64Bit())
    return Subtarget.isTargetCygMing() ? "___chkstk_ms" : "__chkstk";
  return Subtarget.isTargetCygMing() ? "_alloca" : "_chkstk";
}

unsigned
X86TargetLowering::getStackProbeSize(MachineFunction &MF) const {
  // The default stack probe size is 4096 if the function has no stackprobesize
  // attribute.
  unsigned StackProbeSize = 4096;
  const Function &Fn = MF.getFunction();
  if (Fn.hasFnAttribute("stack-probe-size"))
    Fn.getFnAttribute("stack-probe-size")
        .getValueAsString()
        .getAsInteger(0, StackProbeSize);
  return StackProbeSize;
}
