//===-- 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 "MCTargetDesc/X86ShuffleDecode.h"
#include "X86.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/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/WinEHFuncInfo.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);

static cl::opt<int> ExperimentalPrefInnermostLoopAlignment(
    "x86-experimental-pref-innermost-loop-alignment", cl::init(4),
    cl::desc(
        "Sets the preferable loop alignment for experiments (as log2 bytes) "
        "for innermost loops only. If specified, this option overrides "
        "alignment set by x86-experimental-pref-loop-alignment."),
    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);
  }

  // Setup Windows compiler runtime calls.
  if (Subtarget.isTargetWindowsMSVC() || Subtarget.isTargetWindowsItanium()) {
    static const struct {
      const RTLIB::Libcall Op;
      const char * const Name;
      const CallingConv::ID CC;
    } LibraryCalls[] = {
      { RTLIB::SDIV_I64, "_alldiv", CallingConv::X86_StdCall },
      { RTLIB::UDIV_I64, "_aulldiv", CallingConv::X86_StdCall },
      { RTLIB::SREM_I64, "_allrem", CallingConv::X86_StdCall },
      { RTLIB::UREM_I64, "_aullrem", CallingConv::X86_StdCall },
      { RTLIB::MUL_I64, "_allmul", CallingConv::X86_StdCall },
    };

    for (const auto &LC : LibraryCalls) {
      setLibcallName(LC.Op, LC.Name);
      setLibcallCallingConv(LC.Op, LC.CC);
    }
  }

  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.
  for (auto VT : {MVT::f32, MVT::f64, MVT::f80}) {
    setCondCodeAction(ISD::SETOEQ, VT, Expand);
    setCondCodeAction(ISD::SETUNE, VT, Expand);
  }

  // Integer absolute.
  if (Subtarget.hasCMov()) {
    setOperationAction(ISD::ABS            , MVT::i16  , Custom);
    setOperationAction(ISD::ABS            , MVT::i32  , Custom);
    if (Subtarget.is64Bit())
      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::i8   , Custom);
    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);
    }
  }

  if (Subtarget.hasSSE2()) {
    // Custom lowering for saturating float to int conversions.
    // We handle promotion to larger result types manually.
    for (MVT VT : { MVT::i8, MVT::i16, MVT::i32 }) {
      setOperationAction(ISD::FP_TO_UINT_SAT, VT, Custom);
      setOperationAction(ISD::FP_TO_SINT_SAT, VT, Custom);
    }
    if (Subtarget.is64Bit()) {
      setOperationAction(ISD::FP_TO_UINT_SAT, MVT::i64, Custom);
      setOperationAction(ISD::FP_TO_SINT_SAT, 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 {
    for (auto VT : {MVT::i8, MVT::i16, MVT::i32, MVT::i64}) {
      if (VT == MVT::i64 && !Subtarget.is64Bit())
        continue;
      setOperationAction(ISD::CTLZ           , VT, Custom);
      setOperationAction(ISD::CTLZ_ZERO_UNDEF, VT, Custom);
    }
  }

  for (auto Op : {ISD::FP16_TO_FP, ISD::STRICT_FP16_TO_FP, ISD::FP_TO_FP16,
                  ISD::STRICT_FP_TO_FP16}) {
    // Special handling for half-precision floating point conversions.
    // If we don't have F16C support, then lower half float conversions
    // into library calls.
    setOperationAction(
        Op, MVT::f32,
        (!Subtarget.useSoftFloat() && Subtarget.hasF16C()) ? Custom : Expand);
    // There's never any support for operations beyond MVT::f32.
    setOperationAction(Op, MVT::f64, Expand);
    setOperationAction(Op, MVT::f80, Expand);
    setOperationAction(Op, 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);

  setOperationAction(ISD::PARITY, MVT::i8, Custom);
  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::PARITY, MVT::i16, Custom);
    setOperationAction(ISD::PARITY, MVT::i32, Custom);
    if (Subtarget.is64Bit())
      setOperationAction(ISD::PARITY, 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);
  setOperationAction(ISD::UBSANTRAP, 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::USUBSAT,            MVT::v4i32, 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 512-bit registers or AVX512VL+BW, expanding (and promoting the
    // shifts) is better.
    if (!Subtarget.useAVX512Regs() &&
        !(Subtarget.hasBWI() && Subtarget.hasVLX()))
      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::FROUNDEVEN,        RoundedTy,  Legal);
      setOperationAction(ISD::STRICT_FROUNDEVEN, 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);

    setOperationAction(ISD::UADDSAT,            MVT::v4i32, Custom);

    // 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.hasSSE42()) {
    setOperationAction(ISD::UADDSAT,            MVT::v2i64, 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::FROUNDEVEN,        VT, Legal);
      setOperationAction(ISD::STRICT_FROUNDEVEN, 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.useBWIRegs())
      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);
    setOperationAction(ISD::UADDSAT,   MVT::v8i32, Custom);
    setOperationAction(ISD::USUBSAT,   MVT::v8i32, Custom);
    setOperationAction(ISD::UADDSAT,   MVT::v4i64, Custom);
    setOperationAction(ISD::USUBSAT,   MVT::v4i64, 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()) {
    bool HasBWI = Subtarget.hasBWI();

    addRegisterClass(MVT::v16i32, &X86::VR512RegClass);
    addRegisterClass(MVT::v16f32, &X86::VR512RegClass);
    addRegisterClass(MVT::v8i64,  &X86::VR512RegClass);
    addRegisterClass(MVT::v8f64,  &X86::VR512RegClass);
    addRegisterClass(MVT::v32i16, &X86::VR512RegClass);
    addRegisterClass(MVT::v64i8,  &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);
      if (HasBWI)
        setLoadExtAction(ExtType, MVT::v32i16, MVT::v32i8, 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);
    if (HasBWI)
      setTruncStoreAction(MVT::v32i16,  MVT::v32i8, 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,  Legal);
    setOperationAction(ISD::TRUNCATE,    MVT::v16i16, Legal);
    setOperationAction(ISD::TRUNCATE,    MVT::v32i8,  HasBWI ? Legal : Custom);
    setOperationAction(ISD::TRUNCATE,    MVT::v16i64, Custom);
    setOperationAction(ISD::ZERO_EXTEND, MVT::v32i16, Custom);
    setOperationAction(ISD::ZERO_EXTEND, MVT::v16i32, Custom);
    setOperationAction(ISD::ZERO_EXTEND, MVT::v8i64,  Custom);
    setOperationAction(ISD::ANY_EXTEND,  MVT::v32i16, Custom);
    setOperationAction(ISD::ANY_EXTEND,  MVT::v16i32, Custom);
    setOperationAction(ISD::ANY_EXTEND,  MVT::v8i64,  Custom);
    setOperationAction(ISD::SIGN_EXTEND, MVT::v32i16, Custom);
    setOperationAction(ISD::SIGN_EXTEND, MVT::v16i32, Custom);
    setOperationAction(ISD::SIGN_EXTEND, MVT::v8i64,  Custom);

    if (HasBWI) {
      // 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);
    }

    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::FROUNDEVEN,        VT, Legal);
      setOperationAction(ISD::STRICT_FROUNDEVEN, VT, Legal);

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

    for (auto VT : {MVT::v32i16, MVT::v16i32, MVT::v8i64}) {
      setOperationAction(ISD::SIGN_EXTEND_VECTOR_INREG, VT, Custom);
      setOperationAction(ISD::ZERO_EXTEND_VECTOR_INREG, VT, Custom);
    }

    setOperationAction(ISD::ADD, MVT::v32i16, HasBWI ? Legal : Custom);
    setOperationAction(ISD::SUB, MVT::v32i16, HasBWI ? Legal : Custom);
    setOperationAction(ISD::ADD, MVT::v64i8,  HasBWI ? Legal : Custom);
    setOperationAction(ISD::SUB, MVT::v64i8,  HasBWI ? Legal : Custom);

    setOperationAction(ISD::MUL, MVT::v8i64,  Custom);
    setOperationAction(ISD::MUL, MVT::v16i32, Legal);
    setOperationAction(ISD::MUL, MVT::v32i16, HasBWI ? Legal : Custom);
    setOperationAction(ISD::MUL, MVT::v64i8,  Custom);

    setOperationAction(ISD::MULHU, MVT::v16i32, Custom);
    setOperationAction(ISD::MULHS, MVT::v16i32, Custom);
    setOperationAction(ISD::MULHS, MVT::v32i16, HasBWI ? Legal : Custom);
    setOperationAction(ISD::MULHU, MVT::v32i16, HasBWI ? Legal : Custom);
    setOperationAction(ISD::MULHS, MVT::v64i8,  Custom);
    setOperationAction(ISD::MULHU, MVT::v64i8,  Custom);

    setOperationAction(ISD::BITREVERSE, MVT::v64i8,  Custom);

    for (auto VT : { MVT::v64i8, MVT::v32i16, MVT::v16i32, MVT::v8i64 }) {
      setOperationAction(ISD::SRL,              VT, Custom);
      setOperationAction(ISD::SHL,              VT, Custom);
      setOperationAction(ISD::SRA,              VT, Custom);
      setOperationAction(ISD::SETCC,            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::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::CTPOP,            VT, Custom);
      setOperationAction(ISD::ROTL,             VT, Custom);
      setOperationAction(ISD::ROTR,             VT, Custom);
      setOperationAction(ISD::STRICT_FSETCC,    VT, Custom);
      setOperationAction(ISD::STRICT_FSETCCS,   VT, Custom);
    }

    for (auto VT : { MVT::v64i8, MVT::v32i16 }) {
      setOperationAction(ISD::ABS,     VT, HasBWI ? Legal : Custom);
      setOperationAction(ISD::CTPOP,   VT, Subtarget.hasBITALG() ? Legal : Custom);
      setOperationAction(ISD::CTLZ,    VT, Custom);
      setOperationAction(ISD::SMAX,    VT, HasBWI ? Legal : Custom);
      setOperationAction(ISD::UMAX,    VT, HasBWI ? Legal : Custom);
      setOperationAction(ISD::SMIN,    VT, HasBWI ? Legal : Custom);
      setOperationAction(ISD::UMIN,    VT, HasBWI ? Legal : Custom);
      setOperationAction(ISD::UADDSAT, VT, HasBWI ? Legal : Custom);
      setOperationAction(ISD::SADDSAT, VT, HasBWI ? Legal : Custom);
      setOperationAction(ISD::USUBSAT, VT, HasBWI ? Legal : Custom);
      setOperationAction(ISD::SSUBSAT, VT, HasBWI ? Legal : 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::v64i8, MVT::v32i16, MVT::v16i32, MVT::v8i64,
                     MVT::v16f32, MVT::v8f64 }) {
      setOperationAction(ISD::CONCAT_VECTORS,     VT, Custom);
      setOperationAction(ISD::INSERT_SUBVECTOR,   VT, Legal);
      setOperationAction(ISD::SELECT,             VT, Custom);
      setOperationAction(ISD::VSELECT,            VT, Custom);
      setOperationAction(ISD::BUILD_VECTOR,       VT, Custom);
      setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT, Custom);
      setOperationAction(ISD::VECTOR_SHUFFLE,     VT, Custom);
      setOperationAction(ISD::SCALAR_TO_VECTOR,   VT, Custom);
      setOperationAction(ISD::INSERT_VECTOR_ELT,  VT, Custom);
    }

    for (auto VT : { MVT::v16i32, MVT::v8i64, MVT::v16f32, MVT::v8f64 }) {
      setOperationAction(ISD::MLOAD,               VT, Legal);
      setOperationAction(ISD::MSTORE,              VT, Legal);
      setOperationAction(ISD::MGATHER,             VT, Custom);
      setOperationAction(ISD::MSCATTER,            VT, Custom);
    }
    if (HasBWI) {
      for (auto VT : { MVT::v64i8, MVT::v32i16 }) {
        setOperationAction(ISD::MLOAD,        VT, Legal);
        setOperationAction(ISD::MSTORE,       VT, Legal);
      }
    } else {
      setOperationAction(ISD::STORE, MVT::v32i16, Custom);
      setOperationAction(ISD::STORE, MVT::v64i8,  Custom);
    }

    if (Subtarget.hasVBMI2()) {
      for (auto VT : { MVT::v8i16, MVT::v4i32, MVT::v2i64,
                       MVT::v16i16, MVT::v8i32, MVT::v4i64,
                       MVT::v32i16, MVT::v16i32, MVT::v8i64 }) {
        setOperationAction(ISD::FSHL, VT, Custom);
        setOperationAction(ISD::FSHR, VT, Custom);
      }

      setOperationAction(ISD::ROTL, MVT::v32i16, Custom);
      setOperationAction(ISD::ROTR, MVT::v8i16,  Custom);
      setOperationAction(ISD::ROTR, MVT::v16i16, Custom);
      setOperationAction(ISD::ROTR, MVT::v32i16, Custom);
    }
  }// useAVX512Regs

  // 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);

    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);
    }

    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,     VT, Custom);
      setOperationAction(ISD::INSERT_SUBVECTOR,   VT, 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);

    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.hasBWI()) {
      setTruncStoreAction(MVT::v16i16,  MVT::v16i8, Legal);
      setTruncStoreAction(MVT::v8i16,   MVT::v8i8,  Legal);
    }

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

  if (Subtarget.hasAMXTILE()) {
    addRegisterClass(MVT::x86amx, &X86::TILERegClass);
  }

  // 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);
    setOperationAction(ISD::SADDO_CARRY, VT, Custom);
    setOperationAction(ISD::SSUBO_CARRY, 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);
  }

  // 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 || VT == MVT::v64i1) && 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;
  }

  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;
  }

  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()) {
    // 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 VT.changeVectorElementType(MVT::i1);

    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 VT.changeVectorElementType(MVT::i1);
    }
  }

  return VT.changeVectorElementTypeToInteger();
}

/// Helper for getByValTypeAlignment to determine
/// the desired ByVal argument alignment.
static void getMaxByValAlign(Type *Ty, Align &MaxAlign) {
  if (MaxAlign == 16)
    return;
  if (VectorType *VTy = dyn_cast<VectorType>(Ty)) {
    if (VTy->getPrimitiveSizeInBits().getFixedSize() == 128)
      MaxAlign = Align(16);
  } else if (ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
    Align EltAlign;
    getMaxByValAlign(ATy->getElementType(), EltAlign);
    if (EltAlign > MaxAlign)
      MaxAlign = EltAlign;
  } else if (StructType *STy = dyn_cast<StructType>(Ty)) {
    for (auto *EltTy : STy->elements()) {
      Align EltAlign;
      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.
    Align TyAlign = DL.getABITypeAlign(Ty);
    if (TyAlign > 8)
      return TyAlign.value();
    return 8;
  }

  Align Alignment(4);
  if (Subtarget.hasSSE1())
    getMaxByValAlign(Ty, Alignment);
  return Alignment.value();
}

/// 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, Align Alignment, 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 (Alignment < 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 {
      unsigned AddressSpace = getAddressSpace();
      // Specially, some users may customize the base reg and offset.
      unsigned Offset = getTargetMachine().Options.StackProtectorGuardOffset;
      // If we don't set -stack-protector-guard-offset value:
      // %fs:0x28, unless we're using a Kernel code model, in which case
      // it's %gs:0x28.  gs:0x14 on i386.
      if (Offset == (unsigned)-1)
        Offset = (Subtarget.is64Bit()) ? 0x28 : 0x14;

      const auto &GuardReg = getTargetMachine().Options.StackProtectorGuardReg;
      if (GuardReg == "fs")
        AddressSpace = X86AS::FS;
      else if (GuardReg == "gs")
        AddressSpace = X86AS::GS;
      return SegmentOffset(IRB, Offset, AddressSpace);
    }
  }
  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;
  }

  auto GuardMode = getTargetMachine().Options.StackProtectorGuard;

  // glibc, bionic, and Fuchsia have a special slot for the stack guard.
  if ((GuardMode == llvm::StackProtectorGuards::TLS ||
       GuardMode == llvm::StackProtectorGuards::None)
      && 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);
}

//===----------------------------------------------------------------------===//
//               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<Register, 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<Register, 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 (Register 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()));

    Register 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.
    Register 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()) {
      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
        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.getIntPtrConstant(Flags.getByValSize(), dl);

  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;

  CallingConv::ID CalleeCC = CI->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);
  }

  EVT ArgVT = Ins[i].ArgVT;

  // If this is a vector that has been split into multiple parts, and the
  // scalar size of the parts don't match the vector element size, then we can't
  // elide the copy. The parts will have padding between them instead of being
  // packed like a vector.
  bool ScalarizedAndExtendedVector =
      ArgVT.isVector() && !VA.getLocVT().isVector() &&
      VA.getLocVT().getSizeInBits() != ArgVT.getScalarSizeInBits();

  // 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 &&
      !ScalarizedAndExtendedVector) {
    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 llvm::is_sorted(
      ArgLocs, [](const CCValAssign &A, const CCValAssign &B) -> bool {
        return A.getValNo() < B.getValNo();
      });
}
#endif

namespace {
/// This is a helper class for lowering variable arguments parameters.
class VarArgsLoweringHelper {
public:
  VarArgsLoweringHelper(X86MachineFunctionInfo *FuncInfo, const SDLoc &Loc,
                        SelectionDAG &DAG, const X86Subtarget &Subtarget,
                        CallingConv::ID CallConv, CCState &CCInfo)
      : FuncInfo(FuncInfo), DL(Loc), DAG(DAG), Subtarget(Subtarget),
        TheMachineFunction(DAG.getMachineFunction()),
        TheFunction(TheMachineFunction.getFunction()),
        FrameInfo(TheMachineFunction.getFrameInfo()),
        FrameLowering(*Subtarget.getFrameLowering()),
        TargLowering(DAG.getTargetLoweringInfo()), CallConv(CallConv),
        CCInfo(CCInfo) {}

  // Lower variable arguments parameters.
  void lowerVarArgsParameters(SDValue &Chain, unsigned StackSize);

private:
  void createVarArgAreaAndStoreRegisters(SDValue &Chain, unsigned StackSize);

  void forwardMustTailParameters(SDValue &Chain);

  bool is64Bit() const { return Subtarget.is64Bit(); }
  bool isWin64() const { return Subtarget.isCallingConvWin64(CallConv); }

  X86MachineFunctionInfo *FuncInfo;
  const SDLoc &DL;
  SelectionDAG &DAG;
  const X86Subtarget &Subtarget;
  MachineFunction &TheMachineFunction;
  const Function &TheFunction;
  MachineFrameInfo &FrameInfo;
  const TargetFrameLowering &FrameLowering;
  const TargetLowering &TargLowering;
  CallingConv::ID CallConv;
  CCState &CCInfo;
};
} // namespace

void VarArgsLoweringHelper::createVarArgAreaAndStoreRegisters(
    SDValue &Chain, unsigned StackSize) {
  // 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 (is64Bit() || (CallConv != CallingConv::X86_FastCall &&
                    CallConv != CallingConv::X86_ThisCall)) {
    FuncInfo->setVarArgsFrameIndex(
        FrameInfo.CreateFixedObject(1, StackSize, true));
  }

  // Figure out if XMM registers are in use.
  assert(!(Subtarget.useSoftFloat() &&
           TheFunction.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()) {
    // Find the first unallocated argument registers.
    ArrayRef<MCPhysReg> ArgGPRs = get64BitArgumentGPRs(CallConv, Subtarget);
    ArrayRef<MCPhysReg> ArgXMMs =
        get64BitArgumentXMMs(TheMachineFunction, 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!");

    if (isWin64()) {
      // Get to the caller-allocated home save location.  Add 8 to account
      // for the return address.
      int HomeOffset = FrameLowering.getOffsetOfLocalArea() + 8;
      FuncInfo->setRegSaveFrameIndex(
          FrameInfo.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(FrameInfo.CreateStackObject(
          ArgGPRs.size() * 8 + ArgXMMs.size() * 16, Align(16), false));
    }

    SmallVector<SDValue, 6>
        LiveGPRs; // list of SDValue for GPR registers keeping live input value
    SmallVector<SDValue, 8> LiveXMMRegs; // list of SDValue for XMM registers
                                         // keeping live input value
    SDValue ALVal; // if applicable keeps SDValue for %al register

    // Gather all the live in physical registers.
    for (MCPhysReg Reg : ArgGPRs.slice(NumIntRegs)) {
      Register GPR = TheMachineFunction.addLiveIn(Reg, &X86::GR64RegClass);
      LiveGPRs.push_back(DAG.getCopyFromReg(Chain, DL, GPR, MVT::i64));
    }
    const auto &AvailableXmms = ArgXMMs.slice(NumXMMRegs);
    if (!AvailableXmms.empty()) {
      Register AL = TheMachineFunction.addLiveIn(X86::AL, &X86::GR8RegClass);
      ALVal = DAG.getCopyFromReg(Chain, DL, AL, MVT::i8);
      for (MCPhysReg Reg : AvailableXmms) {
        Register XMMReg = TheMachineFunction.addLiveIn(Reg, &X86::VR128RegClass);
        LiveXMMRegs.push_back(
            DAG.getCopyFromReg(Chain, DL, XMMReg, MVT::v4f32));
      }
    }

    // Store the integer parameter registers.
    SmallVector<SDValue, 8> MemOps;
    SDValue RSFIN =
        DAG.getFrameIndex(FuncInfo->getRegSaveFrameIndex(),
                          TargLowering.getPointerTy(DAG.getDataLayout()));
    unsigned Offset = FuncInfo->getVarArgsGPOffset();
    for (SDValue Val : LiveGPRs) {
      SDValue FIN = DAG.getNode(ISD::ADD, DL,
                                TargLowering.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;
    }

    // Now store the XMM (fp + vector) parameter registers.
    if (!LiveXMMRegs.empty()) {
      SmallVector<SDValue, 12> SaveXMMOps;
      SaveXMMOps.push_back(Chain);
      SaveXMMOps.push_back(ALVal);
      SaveXMMOps.push_back(
          DAG.getTargetConstant(FuncInfo->getRegSaveFrameIndex(), DL, MVT::i32));
      SaveXMMOps.push_back(
          DAG.getTargetConstant(FuncInfo->getVarArgsFPOffset(), DL, MVT::i32));
      llvm::append_range(SaveXMMOps, LiveXMMRegs);
      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);
  }
}

void VarArgsLoweringHelper::forwardMustTailParameters(SDValue &Chain) {
  // 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)) {
    Register ALVReg = TheMachineFunction.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 = TheMachineFunction.getRegInfo().createVirtualRegister(
        TargLowering.getRegClassFor(FR.VT));
    Chain = DAG.getCopyToReg(Chain, DL, FR.VReg, RegVal);
  }
}

void VarArgsLoweringHelper::lowerVarArgsParameters(SDValue &Chain,
                                                   unsigned StackSize) {
  // Set FrameIndex to the 0xAAAAAAA value to mark unset state.
  // If necessary, it would be set into the correct value later.
  FuncInfo->setVarArgsFrameIndex(0xAAAAAAA);
  FuncInfo->setRegSaveFrameIndex(0xAAAAAAA);

  if (FrameInfo.hasVAStart())
    createVarArgAreaAndStoreRegisters(Chain, StackSize);

  if (FrameInfo.hasMustTailInVarArgFunc())
    forwardMustTailParameters(Chain);
}

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 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, Align(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!");

        Register 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()) {
      Register 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 (IsVarArg)
    VarArgsLoweringHelper(FuncInfo, dl, DAG, Subtarget, CallConv, CCInfo)
        .lowerVarArgsParameters(Chain, StackSize);

  // 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);
  }

  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, Align(8), /*isSpillSlot=*/false);
      EHInfo->PSPSymFrameIdx = PSPSymFI;
    }
  }

  if (CallConv == CallingConv::X86_RegCall ||
      F.hasFnAttribute("no_caller_saved_registers")) {
    MachineRegisterInfo &MRI = MF.getRegInfo();
    for (std::pair<Register, Register> 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,
                                            bool isByVal) const {
  unsigned LocMemOffset = VA.getLocMemOffset();
  SDValue PtrOff = DAG.getIntPtrConstant(LocMemOffset, dl);
  PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(DAG.getDataLayout()),
                       StackPtr, PtrOff);
  if (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;
  const auto *CB                        = CLI.CB;

  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>();
  bool HasNCSR = (CB && isa<CallInst>(CB) &&
                  CB->hasFnAttr("no_caller_saved_registers"));
  bool HasNoCfCheck = (CB && CB->doesNoCfCheck());
  bool IsIndirectCall = (CB && isa<CallInst>(CB) && CB->isIndirectCall());
  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.CB && CLI.CB->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, Align(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");
  } else if (CLI.IsPreallocated) {
    assert(ArgLocs.back().isMemLoc() &&
           "cannot use preallocated attribute on a register "
           "parameter");
    SmallVector<size_t, 4> PreallocatedOffsets;
    for (size_t i = 0; i < CLI.OutVals.size(); ++i) {
      if (CLI.CB->paramHasAttr(i, Attribute::Preallocated)) {
        PreallocatedOffsets.push_back(ArgLocs[i].getLocMemOffset());
      }
    }
    auto *MFI = DAG.getMachineFunction().getInfo<X86MachineFunctionInfo>();
    size_t PreallocatedId = MFI->getPreallocatedIdForCallSite(CLI.CB);
    MFI->setPreallocatedStackSize(PreallocatedId, NumBytes);
    MFI->setPreallocatedArgOffsets(PreallocatedId, PreallocatedOffsets);
    NumBytesToPush = 0;
  }

  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<Register, 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/preallocated arguments, they have already been written.
    ISD::ArgFlagsTy Flags = Outs[OutIndex].Flags;
    if (Flags.isInAlloca() || Flags.isPreallocated())
      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.
        Register ShadowReg;
        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, isByVal));
    }
  }

  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 (except regcall).
    if (!isTailCall) {
      // Indirect call with RegCall calling convertion may use up all the
      // general registers, so it is not suitable to bind EBX reister for
      // GOT address, just let register allocator handle it.
      if (CallConv != CallingConv::X86_RegCall)
        RegsToPass.push_back(std::make_pair(
          Register(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(Register(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(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/preallocated arguments.  They don't require any work.
      if (Flags.isInAlloca() || Flags.isPreallocated())
        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.getTargetConstant(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.
  const uint32_t *Mask = [&]() {
    auto AdaptedCC = CallConv;
    // If HasNCSR is asserted (attribute NoCallerSavedRegisters exists),
    // use X86_INTR calling convention because it has the same CSR mask
    // (same preserved registers).
    if (HasNCSR)
      AdaptedCC = (CallingConv::ID)CallingConv::X86_INTR;
    // If NoCalleeSavedRegisters is requested, than use GHC since it happens
    // to use the CSR_NoRegs_RegMask.
    if (CB && CB->hasFnAttr("no_callee_saved_registers"))
      AdaptedCC = (CallingConv::ID)CallingConv::GHC;
    return RegInfo->getCallPreservedMask(MF, AdaptedCC);
  }();
  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.CB && isa<InvokeInst>(CLI.CB)) {
    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 && IsIndirectCall) {
    Chain = DAG.getNode(X86ISD::NT_CALL, dl, NodeTys, Ops);
  } else {
    Chain = DAG.getNode(X86ISD::CALL, dl, NodeTys, Ops);
  }
  InFlag = Chain.getValue(1);
  DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
  DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));

  // Save heapallocsite metadata.
  if (CLI.CB)
    if (MDNode *HeapAlloc = CLI.CB->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) {
    Register VR = cast<RegisterSDNode>(Arg.getOperand(1))->getReg();
    if (!VR.isVirtual())
      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().getFixedSizeInBits() >
      Arg.getValueSizeInBits().getFixedSize()) {
    // 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, Align(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;
  }
}

static bool isTargetShuffleSplat(SDValue Op) {
  unsigned Opcode = Op.getOpcode();
  if (Opcode == ISD::EXTRACT_SUBVECTOR)
    return isTargetShuffleSplat(Op.getOperand(0));
  return Opcode == X86ISD::VBROADCAST || Opcode == X86ISD::VBROADCAST_LOAD;
}

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 {
  Info.flags = MachineMemOperand::MONone;
  Info.offset = 0;

  const IntrinsicData* IntrData = getIntrinsicWithChain(Intrinsic);
  if (!IntrData) {
    switch (Intrinsic) {
    case Intrinsic::x86_aesenc128kl:
    case Intrinsic::x86_aesdec128kl:
      Info.opc = ISD::INTRINSIC_W_CHAIN;
      Info.ptrVal = I.getArgOperand(1);
      Info.memVT = EVT::getIntegerVT(I.getType()->getContext(), 48);
      Info.align = Align(1);
      Info.flags |= MachineMemOperand::MOLoad;
      return true;
    case Intrinsic::x86_aesenc256kl:
    case Intrinsic::x86_aesdec256kl:
      Info.opc = ISD::INTRINSIC_W_CHAIN;
      Info.ptrVal = I.getArgOperand(1);
      Info.memVT = EVT::getIntegerVT(I.getType()->getContext(), 64);
      Info.align = Align(1);
      Info.flags |= MachineMemOperand::MOLoad;
      return true;
    case Intrinsic::x86_aesencwide128kl:
    case Intrinsic::x86_aesdecwide128kl:
      Info.opc = ISD::INTRINSIC_W_CHAIN;
      Info.ptrVal = I.getArgOperand(0);
      Info.memVT = EVT::getIntegerVT(I.getType()->getContext(), 48);
      Info.align = Align(1);
      Info.flags |= MachineMemOperand::MOLoad;
      return true;
    case Intrinsic::x86_aesencwide256kl:
    case Intrinsic::x86_aesdecwide256kl:
      Info.opc = ISD::INTRINSIC_W_CHAIN;
      Info.ptrVal = I.getArgOperand(0);
      Info.memVT = EVT::getIntegerVT(I.getType()->getContext(), 64);
      Info.align = Align(1);
      Info.flags |= MachineMemOperand::MOLoad;
      return true;
    }
    return false;
  }

  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));
}

/// Return true if every element in Mask is the undef sentinel value or equal to
/// the specified value..
static bool isUndefOrEqual(ArrayRef<int> Mask, int CmpVal) {
  return llvm::all_of(Mask, [CmpVal](int M) {
    return (M == SM_SentinelUndef) || (M == 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 the value of any element in Mask is the zero or undef
/// sentinel values.
static bool isAnyZeroOrUndef(ArrayRef<int> Mask) {
  return llvm::any_of(Mask, [](int M) {
    return M == SM_SentinelZero || M == SM_SentinelUndef;
  });
}

/// 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);
}

// Attempt to narrow/widen shuffle mask until it matches the target number of
// elements.
static bool scaleShuffleElements(ArrayRef<int> Mask, unsigned NumDstElts,
                                 SmallVectorImpl<int> &ScaledMask) {
  unsigned NumSrcElts = Mask.size();
  assert(((NumSrcElts % NumDstElts) == 0 || (NumDstElts % NumSrcElts) == 0) &&
         "Illegal shuffle scale factor");

  // Narrowing is guaranteed to work.
  if (NumDstElts >= NumSrcElts) {
    int Scale = NumDstElts / NumSrcElts;
    llvm::narrowShuffleMaskElts(Scale, Mask, ScaledMask);
    return true;
  }

  // We have to repeat the widening until we reach the target size, but we can
  // split out the first widening as it sets up ScaledMask for us.
  if (canWidenShuffleElements(Mask, ScaledMask)) {
    while (ScaledMask.size() > NumDstElts) {
      SmallVector<int, 16> WidenedMask;
      if (!canWidenShuffleElements(ScaledMask, WidenedMask))
        return false;
      ScaledMask = std::move(WidenedMask);
    }
    return true;
  }

  return false;
}

/// 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().getFixedSize() < VT.getFixedSizeInBits() &&
         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) {
    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)) {
      // insert_subvector(insert_subvector(undef, x, lo), y, hi)
      if (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;
      }
      // insert_subvector(x, extract_subvector(x, lo), hi)
      if (Sub.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
          Sub.getOperand(0) == Src && isNullConstant(Sub.getOperand(1))) {
        Ops.append(2, Sub);
        return true;
      }
    }
  }

  return false;
}

static std::pair<SDValue, SDValue> splitVector(SDValue Op, SelectionDAG &DAG,
                                               const SDLoc &dl) {
  EVT VT = Op.getValueType();
  unsigned NumElems = VT.getVectorNumElements();
  unsigned SizeInBits = VT.getSizeInBits();
  assert((NumElems % 2) == 0 && (SizeInBits % 2) == 0 &&
         "Can't split odd sized vector");

  SDValue Lo = extractSubVector(Op, 0, DAG, dl, SizeInBits / 2);
  SDValue Hi = extractSubVector(Op, NumElems / 2, DAG, dl, SizeInBits / 2);
  return std::make_pair(Lo, Hi);
}

// Split an unary integer op into 2 half sized ops.
static SDValue splitVectorIntUnary(SDValue Op, SelectionDAG &DAG) {
  EVT VT = Op.getValueType();

  // Make sure we only try to split 256/512-bit types to avoid creating
  // narrow vectors.
  assert((Op.getOperand(0).getValueType().is256BitVector() ||
          Op.getOperand(0).getValueType().is512BitVector()) &&
         (VT.is256BitVector() || VT.is512BitVector()) && "Unsupported VT!");
  assert(Op.getOperand(0).getValueType().getVectorNumElements() ==
             VT.getVectorNumElements() &&
         "Unexpected VTs!");

  SDLoc dl(Op);

  // Extract the Lo/Hi vectors
  SDValue Lo, Hi;
  std::tie(Lo, Hi) = splitVector(Op.getOperand(0), DAG, dl);

  EVT LoVT, HiVT;
  std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
  return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT,
                     DAG.getNode(Op.getOpcode(), dl, LoVT, Lo),
                     DAG.getNode(Op.getOpcode(), dl, HiVT, Hi));
}

/// Break a binary integer operation into 2 half sized ops and then
/// concatenate the result back.
static SDValue splitVectorIntBinary(SDValue Op, SelectionDAG &DAG) {
  EVT VT = Op.getValueType();

  // Sanity check that all the types match.
  assert(Op.getOperand(0).getValueType() == VT &&
         Op.getOperand(1).getValueType() == VT && "Unexpected VTs!");
  assert((VT.is256BitVector() || VT.is512BitVector()) && "Unsupported VT!");

  SDLoc dl(Op);

  // Extract the LHS Lo/Hi vectors
  SDValue LHS1, LHS2;
  std::tie(LHS1, LHS2) = splitVector(Op.getOperand(0), DAG, dl);

  // Extract the RHS Lo/Hi vectors
  SDValue RHS1, RHS2;
  std::tie(RHS1, RHS2) = splitVector(Op.getOperand(1), DAG, dl);

  EVT LoVT, HiVT;
  std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
  return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT,
                     DAG.getNode(Op.getOpcode(), dl, LoVT, LHS1, RHS1),
                     DAG.getNode(Op.getOpcode(), dl, HiVT, LHS2, RHS2));
}

// 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);
  unsigned IdxVal = Op.getConstantOperandVal(2);

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

  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_VECTOR_INREG to *_EXTEND opcode.
static unsigned getOpcode_EXTEND(unsigned Opcode) {
  switch (Opcode) {
  case ISD::ANY_EXTEND:
  case ISD::ANY_EXTEND_VECTOR_INREG:
    return ISD::ANY_EXTEND;
  case ISD::ZERO_EXTEND:
  case ISD::ZERO_EXTEND_VECTOR_INREG:
    return ISD::ZERO_EXTEND;
  case ISD::SIGN_EXTEND:
  case ISD::SIGN_EXTEND_VECTOR_INREG:
    return ISD::SIGN_EXTEND;
  }
  llvm_unreachable("Unknown opcode");
}

// 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 getEXTEND_VECTOR_INREG(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, bool OneUse = false) {
  V = OneUse ? peekThroughOneUseBitcasts(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(EVT VT, SmallVectorImpl<int> &Mask,
                                   bool Lo, bool Unary) {
  assert(VT.getScalarType().isSimple() && (VT.getSizeInBits() % 128) == 0 &&
         "Illegal vector type to unpack");
  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, EVT 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, EVT 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 *getTargetConstantFromBasePtr(SDValue Ptr) {
  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(LoadSDNode *Load) {
  if (!Load || !ISD::isNormalLoad(Load))
    return nullptr;
  return getTargetConstantFromBasePtr(Load->getBasePtr());
}

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_LOAD &&
      EltSizeInBits <= VT.getScalarSizeInBits()) {
    auto *MemIntr = cast<MemIntrinsicSDNode>(Op);
    if (MemIntr->getMemoryVT().getScalarSizeInBits() != VT.getScalarSizeInBits())
      return false;

    SDValue Ptr = MemIntr->getBasePtr();
    if (const Constant *C = getTargetConstantFromBasePtr(Ptr)) {
      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_LOAD) {
    auto *MemIntr = cast<MemIntrinsicSDNode>(Op);
    SDValue Ptr = MemIntr->getBasePtr();
    if (const Constant *Cst = getTargetConstantFromBasePtr(Ptr)) {
      Type *CstTy = Cst->getType();
      unsigned CstSizeInBits = CstTy->getPrimitiveSizeInBits();
      if (!CstTy->isVectorTy() || (SizeInBits % CstSizeInBits) != 0)
        return false;
      unsigned SubEltSizeInBits = CstTy->getScalarSizeInBits();
      unsigned NumSubElts = CstSizeInBits / SubEltSizeInBits;
      unsigned NumSubVecs = SizeInBits / CstSizeInBits;
      APInt UndefSubElts(NumSubElts, 0);
      SmallVector<APInt, 64> SubEltBits(NumSubElts * NumSubVecs,
                                        APInt(SubEltSizeInBits, 0));
      for (unsigned i = 0; i != NumSubElts; ++i) {
        if (!CollectConstantBits(Cst->getAggregateElement(i), SubEltBits[i],
                                 UndefSubElts, i))
          return false;
        for (unsigned j = 1; j != NumSubVecs; ++j)
          SubEltBits[i + (j * NumSubElts)] = SubEltBits[i];
      }
      UndefSubElts = APInt::getSplat(NumSubVecs * UndefSubElts.getBitWidth(),
                                     UndefSubElts);
      return CastBitData(UndefSubElts, SubEltBits);
    }
  }

  // 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) {
    // If bitcasts to larger elements we might lose track of undefs - don't
    // allow any to be safe.
    unsigned SrcEltSizeInBits = VT.getScalarSizeInBits();
    bool AllowUndefs = EltSizeInBits >= SrcEltSizeInBits;

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

  // Extract constant bits from a subvector's source.
  if (Op.getOpcode() == ISD::EXTRACT_SUBVECTOR) {
    // 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 (const APInt &Elt : EltBits)
    RawMask.push_back(Elt.getZExtValue());

  return true;
}

/// Create a shuffle mask that matches the PACKSS/PACKUS truncation.
/// A multi-stage pack shuffle mask is created by specifying NumStages > 1.
/// Note: This ignores saturation, so inputs must be checked first.
static void createPackShuffleMask(MVT VT, SmallVectorImpl<int> &Mask,
                                  bool Unary, unsigned NumStages = 1) {
  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;
  unsigned Repetitions = 1u << (NumStages - 1);
  unsigned Increment = 1u << NumStages;
  assert((NumEltsPerLane >> NumStages) > 0 && "Illegal packing compaction");

  for (unsigned Lane = 0; Lane != NumLanes; ++Lane) {
    for (unsigned Stage = 0; Stage != Repetitions; ++Stage) {
      for (unsigned Elt = 0; Elt != NumEltsPerLane; Elt += Increment)
        Mask.push_back(Elt + (Lane * NumEltsPerLane));
      for (unsigned Elt = 0; Elt != NumEltsPerLane; Elt += Increment)
        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:
    // We only decode broadcasts of same-sized vectors, peeking through to
    // extracted subvectors is likely to cause hasOneUse issues with
    // SimplifyDemandedBits etc.
    if (N->getOperand(0).getValueType() == VT) {
      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 && isAnyZero(Mask))
    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) {
        int Idx = V.getConstantOperandVal(2);
        int NumSubElts = V.getOperand(1).getValueType().getVectorNumElements();
        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,
                                   const 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,
                               const 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: {
    // Handle OR(SHUFFLE,SHUFFLE) case where one source is zero and the other
    // is a valid shuffle index.
    SDValue N0 = peekThroughBitcasts(N.getOperand(0));
    SDValue N1 = peekThroughBitcasts(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;

    size_t MaskSize = std::max(SrcMask0.size(), SrcMask1.size());
    SmallVector<int, 64> Mask0, Mask1;
    narrowShuffleMaskElts(MaskSize / SrcMask0.size(), SrcMask0, Mask0);
    narrowShuffleMaskElts(MaskSize / SrcMask1.size(), SrcMask1, Mask1);
    for (int i = 0; i != (int)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(i);
      else if (Mask0[i] == SM_SentinelZero)
        Mask.push_back(i + MaskSize);
      else
        return false;
    }
    Ops.push_back(N0);
    Ops.push_back(N1);
    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 (!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) {
      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;

    // Subvector shuffle inputs must not be larger than the subvector.
    if (llvm::any_of(SubInputs, [SubVT](SDValue SubInput) {
          return SubVT.getFixedSizeInBits() <
                 SubInput.getValueSizeInBits().getFixedSize();
        }))
      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;
        narrowShuffleMaskElts(Scale, SubMask, ScaledSubMask);
        SubMask = ScaledSubMask;
      } else {
        int Scale = SubMask.size() / NumSubElts;
        NumSubElts = SubMask.size();
        NumElts *= Scale;
        InsertIdx *= Scale;
      }
    }
    Ops.push_back(Src);
    Ops.append(SubInputs.begin(), SubInputs.end());
    if (ISD::isBuildVectorAllZeros(Src.getNode()))
      Mask.append(NumElts, SM_SentinelZero);
    else
      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.
    unsigned MinBitsPerElt = Scl.getScalarValueSizeInBits();
    while (Scl.getOpcode() == ISD::TRUNCATE ||
           Scl.getOpcode() == ISD::ANY_EXTEND ||
           Scl.getOpcode() == ISD::ZERO_EXTEND) {
      Scl = Scl.getOperand(0);
      MinBitsPerElt =
          std::min<unsigned>(MinBitsPerElt, Scl.getScalarValueSizeInBits());
    }
    if ((MinBitsPerElt % 8) != 0)
      return false;

    // 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();
    if (!SrcVT.getScalarType().isByteSized())
      return false;
    unsigned SrcIdx = SrcExtract.getConstantOperandVal(1);
    unsigned SrcByte = SrcIdx * (SrcVT.getScalarSizeInBits() / 8);
    unsigned DstByte = DstIdx * NumBytesPerElt;
    MinBitsPerElt =
        std::min<unsigned>(MinBitsPerElt, SrcVT.getScalarSizeInBits());

    // Create 'identity' byte level shuffle mask and then add inserted bytes.
    if (Opcode == ISD::SCALAR_TO_VECTOR) {
      Ops.push_back(SrcVec);
      Mask.append(NumSizeInBytes, SM_SentinelUndef);
    } else {
      Ops.push_back(SrcVec);
      Ops.push_back(N.getOperand(0));
      for (int i = 0; i != (int)NumSizeInBytes; ++i)
        Mask.push_back(NumSizeInBytes + i);
    }

    unsigned MinBytesPerElts = MinBitsPerElt / 8;
    MinBytesPerElts = std::min(MinBytesPerElts, NumBytesPerElt);
    for (unsigned i = 0; i != MinBytesPerElts; ++i)
      Mask[DstByte + i] = SrcByte + i;
    for (unsigned i = MinBytesPerElts; i < NumBytesPerElt; ++i)
      Mask[DstByte + i] = 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 (or we don't care for particular
    // lanes), we can treat this as a truncation shuffle.
    bool Offset0 = false, Offset1 = false;
    if (Opcode == X86ISD::PACKSS) {
      if ((!(N0.isUndef() || EltsLHS.isNullValue()) &&
           DAG.ComputeNumSignBits(N0, EltsLHS, Depth + 1) <= NumBitsPerElt) ||
          (!(N1.isUndef() || EltsRHS.isNullValue()) &&
           DAG.ComputeNumSignBits(N1, EltsRHS, Depth + 1) <= NumBitsPerElt))
        return false;
      // We can't easily fold ASHR into a shuffle, but if it was feeding a
      // PACKSS then it was likely being used for sign-extension for a
      // truncation, so just peek through and adjust the mask accordingly.
      if (N0.getOpcode() == X86ISD::VSRAI && N->isOnlyUserOf(N0.getNode()) &&
          N0.getConstantOperandAPInt(1) == NumBitsPerElt) {
        Offset0 = true;
        N0 = N0.getOperand(0);
      }
      if (N1.getOpcode() == X86ISD::VSRAI && N->isOnlyUserOf(N1.getNode()) &&
          N1.getConstantOperandAPInt(1) == NumBitsPerElt) {
        Offset1 = true;
        N1 = N1.getOperand(0);
      }
    } else {
      APInt ZeroMask = APInt::getHighBitsSet(2 * NumBitsPerElt, NumBitsPerElt);
      if ((!(N0.isUndef() || EltsLHS.isNullValue()) &&
           !DAG.MaskedValueIsZero(N0, ZeroMask, EltsLHS, Depth + 1)) ||
          (!(N1.isUndef() || EltsRHS.isNullValue()) &&
           !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);

    if (Offset0 || Offset1) {
      for (int &M : Mask)
        if ((Offset0 && isInRange(M, 0, NumElts)) ||
            (Offset1 && isInRange(M, NumElts, 2 * NumElts)))
          ++M;
    }
    return true;
  }
  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);
    if (!Src.getSimpleValueType().isVector())
      return false;
    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;

    bool IsAnyExtend =
        (ISD::ANY_EXTEND == Opcode || ISD::ANY_EXTEND_VECTOR_INREG == Opcode);
    DecodeZeroExtendMask(SrcVT.getScalarSizeInBits(), NumBitsPerElt, NumElts,
                         IsAnyExtend, Mask);
    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,
                                   const 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,
                                   const 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(SDValue Op, unsigned Index,
                                   SelectionDAG &DAG, unsigned Depth) {
  if (Depth >= SelectionDAG::MaxRecursionDepth)
    return SDValue(); // Limit search depth.

  EVT VT = Op.getValueType();
  unsigned Opcode = Op.getOpcode();
  unsigned NumElems = VT.getVectorNumElements();

  // Recurse into ISD::VECTOR_SHUFFLE node to find scalars.
  if (auto *SV = dyn_cast<ShuffleVectorSDNode>(Op)) {
    int Elt = SV->getMaskElt(Index);

    if (Elt < 0)
      return DAG.getUNDEF(VT.getVectorElementType());

    SDValue Src = (Elt < (int)NumElems) ? SV->getOperand(0) : SV->getOperand(1);
    return getShuffleScalarElt(Src, Elt % NumElems, DAG, Depth + 1);
  }

  // Recurse into target specific vector shuffles to find scalars.
  if (isTargetShuffle(Opcode)) {
    MVT ShufVT = VT.getSimpleVT();
    MVT ShufSVT = ShufVT.getVectorElementType();
    int NumElems = (int)ShufVT.getVectorNumElements();
    SmallVector<int, 16> ShuffleMask;
    SmallVector<SDValue, 16> ShuffleOps;
    bool IsUnary;

    if (!getTargetShuffleMask(Op.getNode(), ShufVT, true, ShuffleOps,
                              ShuffleMask, IsUnary))
      return SDValue();

    int Elt = ShuffleMask[Index];
    if (Elt == SM_SentinelZero)
      return ShufSVT.isInteger() ? DAG.getConstant(0, SDLoc(Op), ShufSVT)
                                 : DAG.getConstantFP(+0.0, SDLoc(Op), ShufSVT);
    if (Elt == SM_SentinelUndef)
      return DAG.getUNDEF(ShufSVT);

    assert(0 <= Elt && Elt < (2 * NumElems) && "Shuffle index out of range");
    SDValue Src = (Elt < NumElems) ? ShuffleOps[0] : ShuffleOps[1];
    return getShuffleScalarElt(Src, Elt % NumElems, DAG, Depth + 1);
  }

  // Recurse into insert_subvector base/sub vector to find scalars.
  if (Opcode == ISD::INSERT_SUBVECTOR) {
    SDValue Vec = Op.getOperand(0);
    SDValue Sub = Op.getOperand(1);
    uint64_t SubIdx = Op.getConstantOperandVal(2);
    unsigned NumSubElts = Sub.getValueType().getVectorNumElements();

    if (SubIdx <= Index && Index < (SubIdx + NumSubElts))
      return getShuffleScalarElt(Sub, Index - SubIdx, DAG, Depth + 1);
    return getShuffleScalarElt(Vec, Index, DAG, Depth + 1);
  }

  // Recurse into concat_vectors sub vector to find scalars.
  if (Opcode == ISD::CONCAT_VECTORS) {
    EVT SubVT = Op.getOperand(0).getValueType();
    unsigned NumSubElts = SubVT.getVectorNumElements();
    uint64_t SubIdx = Index / NumSubElts;
    uint64_t SubElt = Index % NumSubElts;
    return getShuffleScalarElt(Op.getOperand(SubIdx), SubElt, DAG, Depth + 1);
  }

  // Recurse into extract_subvector src vector to find scalars.
  if (Opcode == ISD::EXTRACT_SUBVECTOR) {
    SDValue Src = Op.getOperand(0);
    uint64_t SrcIdx = Op.getConstantOperandVal(1);
    return getShuffleScalarElt(Src, Index + SrcIdx, DAG, Depth + 1);
  }

  // We only peek through bitcasts of the same vector width.
  if (Opcode == ISD::BITCAST) {
    SDValue Src = Op.getOperand(0);
    EVT SrcVT = Src.getValueType();
    if (SrcVT.isVector() && SrcVT.getVectorNumElements() == NumElems)
      return getShuffleScalarElt(Src, Index, DAG, Depth + 1);
    return SDValue();
  }

  // Actual nodes that may contain scalar elements

  // For insert_vector_elt - either return the index matching scalar or recurse
  // into the base vector.
  if (Opcode == ISD::INSERT_VECTOR_ELT &&
      isa<ConstantSDNode>(Op.getOperand(2))) {
    if (Op.getConstantOperandAPInt(2) == Index)
      return Op.getOperand(1);
    return getShuffleScalarElt(Op.getOperand(0), Index, DAG, Depth + 1);
  }

  if (Opcode == ISD::SCALAR_TO_VECTOR)
    return (Index == 0) ? Op.getOperand(0)
                        : DAG.getUNDEF(VT.getVectorElementType());

  if (Opcode == ISD::BUILD_VECTOR)
    return Op.getOperand(Index);

  return SDValue();
}

// Use PINSRB/PINSRW/PINSRD to create a build vector.
static SDValue LowerBuildVectorAsInsert(SDValue Op, const APInt &NonZeroMask,
                                        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 = NonZeroMask[i];
    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, const APInt &NonZeroMask,
                                     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, NonZeroMask, 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 = NonZeroMask[i];
    bool NextIsNonZero = NonZeroMask[i + 1];
    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 or zeros are needed, then
    // insert into zero vector. Otherwise, use SCALAR_TO_VECTOR (leaves high
    // elements undefined).
    if (!V) {
      if (i != 0 || NumZero)
        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, const APInt &NonZeroMask,
                                     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, NonZeroMask, 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();
    MaybeAlign InferredAlign = DAG.InferPtrAlign(Ptr);
    if (!InferredAlign || *InferredAlign < 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 (auto *IdxC = dyn_cast<ConstantSDNode>(Elt.getOperand(1))) {
      uint64_t Idx = IdxC->getZExtValue();
      if ((Idx % 8) == 0 && findEltLoadSrc(Elt.getOperand(0), Ld, ByteOffset)) {
        ByteOffset += Idx / 8;
        return true;
      }
    }
    break;
  case ISD::EXTRACT_VECTOR_ELT:
    if (auto *IdxC = dyn_cast<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 = IdxC->getZExtValue();
        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);
  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 NumLoadedElts = (1 + LastLoadedElt - FirstLoadedElt);
  int LoadSizeInBits = NumLoadedElts * 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->getOriginalAlign(),
                    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 &&
      (NumLoadedElts == (int)NumElems || 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->getOriginalAlign(), 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;

      // Don't attempt a 1:N subvector broadcast - it should be caught by
      // combineConcatVectorOps, else will cause infinite loops.
      if (RepeatSize > ScalarSize && SubElems == 1)
        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)) {
          SDValue Broadcast = RepeatLoad;
          if (RepeatSize > ScalarSize) {
            while (Broadcast.getValueSizeInBits() < VT.getSizeInBits())
              Broadcast = concatSubVectors(Broadcast, Broadcast, DAG, DL);
          } else {
            Broadcast =
                DAG.getNode(X86ISD::VBROADCAST, 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, SDValue Op, 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(Op, 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;
}

/// 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);
  unsigned NumElts = VT.getVectorNumElements();
  SDLoc dl(BVOp);

  assert((VT.is128BitVector() || VT.is256BitVector() || VT.is512BitVector()) &&
         "Unsupported vector type for broadcast.");

  // See if the build vector is a repeating sequence of scalars (inc. splat).
  SDValue Ld;
  BitVector UndefElements;
  SmallVector<SDValue, 16> Sequence;
  if (BVOp->getRepeatedSequence(Sequence, &UndefElements)) {
    assert((NumElts % Sequence.size()) == 0 && "Sequence doesn't fit.");
    if (Sequence.size() == 1)
      Ld = Sequence[0];
  }

  // 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 (!Sequence.empty() && Subtarget.hasCDI()) {
    // If not a splat, are the upper sequence values zeroable?
    unsigned SeqLen = Sequence.size();
    bool UpperZeroOrUndef =
        SeqLen == 1 ||
        llvm::all_of(makeArrayRef(Sequence).drop_front(), [](SDValue V) {
          return !V || V.isUndef() || isNullConstant(V);
        });
    SDValue Op0 = Sequence[0];
    if (UpperZeroOrUndef && ((Op0.getOpcode() == ISD::BITCAST) ||
                             (Op0.getOpcode() == ISD::ZERO_EXTEND &&
                              Op0.getOperand(0).getOpcode() == ISD::BITCAST))) {
      SDValue BOperand = Op0.getOpcode() == ISD::BITCAST
                             ? Op0.getOperand(0)
                             : Op0.getOperand(0).getOperand(0);
      MVT MaskVT = BOperand.getSimpleValueType();
      MVT EltType = MVT::getIntegerVT(VT.getScalarSizeInBits() * SeqLen);
      if ((EltType == MVT::i64 && MaskVT == MVT::v8i1) ||  // for broadcastmb2q
          (EltType == MVT::i32 && MaskVT == MVT::v16i1)) { // for broadcastmw2d
        MVT BcstVT = MVT::getVectorVT(EltType, NumElts / SeqLen);
        if (!VT.is512BitVector() && !Subtarget.hasVLX()) {
          unsigned Scale = 512 / VT.getSizeInBits();
          BcstVT = MVT::getVectorVT(EltType, Scale * (NumElts / SeqLen));
        }
        SDValue Bcst = DAG.getNode(X86ISD::VBROADCASTM, dl, BcstVT, BOperand);
        if (BcstVT.getSizeInBits() != VT.getSizeInBits())
          Bcst = extractSubVector(Bcst, 0, DAG, dl, VT.getSizeInBits());
        return DAG.getBitcast(VT, Bcst);
      }
    }
  }

  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;

          Align Alignment = cast<ConstantPoolSDNode>(CP)->getAlign();
          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.
          Constant *VecC = getConstantVector(VT, SplatValue, SplatBitSize,
                                             *Ctx);
          SDValue VCP = DAG.getConstantPool(VecC, PVT);
          unsigned NumElm = SplatBitSize / VT.getScalarSizeInBits();
          MVT VVT = MVT::getVectorVT(VT.getScalarType(), NumElm);
          Align Alignment = cast<ConstantPoolSDNode>(VCP)->getAlign();
          SDVTList Tys = DAG.getVTList(VT, MVT::Other);
          SDValue Ops[] = {DAG.getEntryNode(), VCP};
          MachinePointerInfo MPI =
              MachinePointerInfo::getConstantPool(DAG.getMachineFunction());
          return DAG.getMemIntrinsicNode(
              X86ISD::SUBV_BROADCAST_LOAD, dl, Tys, Ops, VVT, MPI, Alignment,
              MachineMemOperand::MOLoad);
        }
      }
    }

    // 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());

  // TODO: Handle broadcasts of non-constant sequences.

  // 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()));
      Align Alignment = cast<ConstantPoolSDNode>(CP)->getAlign();

      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 (auto *InC = dyn_cast<ConstantSDNode>(In)) {
      Immediate |= (InC->getZExtValue() & 0x1) << idx;
      HasConstElts = true;
    } else {
      NonConstIdx.push_back(idx);
    }
    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 = Op0.getConstantOperandVal(1);
    unsigned I1 = Op1.getConstantOperandVal(1);

    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)) ||
        Op0.getOperand(1) != Op1.getOperand(1))
      return false;

    unsigned I0 = Op0.getConstantOperandVal(1);
    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();
}

static SDValue LowerShift(SDValue Op, const X86Subtarget &Subtarget,
                          SelectionDAG &DAG);

/// 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,
                                       const X86Subtarget &Subtarget,
                                       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);
  SDValue Res = DAG.getNode(Opcode, DL, VT, LHS, RHS);

  if (!IsShift)
    return Res;

  // Immediately lower the shift to ensure the constant build vector doesn't
  // get converted to a constant pool before the shift is lowered.
  return LowerShift(Res, Subtarget, DAG);
}

/// 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;

  unsigned EVTBits = EltVT.getSizeInBits();
  APInt UndefMask = APInt::getNullValue(NumElems);
  APInt ZeroMask = APInt::getNullValue(NumElems);
  APInt NonZeroMask = APInt::getNullValue(NumElems);
  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()) {
      UndefMask.setBit(i);
      continue;
    }
    Values.insert(Elt);
    if (!isa<ConstantSDNode>(Elt) && !isa<ConstantFPSDNode>(Elt)) {
      IsAllConstants = false;
      NumConstants--;
    }
    if (X86::isZeroNode(Elt)) {
      ZeroMask.setBit(i);
    } else {
      NonZeroMask.setBit(i);
    }
  }

  // All undef vector. Return an UNDEF. All zero vectors were handled above.
  if (NonZeroMask == 0) {
    assert(UndefMask.isAllOnesValue() && "Fully undef mask expected");
    return DAG.getUNDEF(VT);
  }

  BuildVectorSDNode *BV = cast<BuildVectorSDNode>(Op.getNode());

  // If the upper elts of a ymm/zmm are undef/zero then we might be better off
  // lowering to a smaller build vector and padding with undef/zero.
  if ((VT.is256BitVector() || VT.is512BitVector()) &&
      !isFoldableUseOfShuffle(BV)) {
    unsigned UpperElems = NumElems / 2;
    APInt UndefOrZeroMask = UndefMask | ZeroMask;
    unsigned NumUpperUndefsOrZeros = UndefOrZeroMask.countLeadingOnes();
    if (NumUpperUndefsOrZeros >= UpperElems) {
      if (VT.is512BitVector() &&
          NumUpperUndefsOrZeros >= (NumElems - (NumElems / 4)))
        UpperElems = NumElems - (NumElems / 4);
      bool UndefUpper = UndefMask.countLeadingOnes() >= UpperElems;
      MVT LowerVT = MVT::getVectorVT(EltVT, NumElems - UpperElems);
      SDValue NewBV =
          DAG.getBuildVector(LowerVT, dl, Op->ops().drop_back(UpperElems));
      return widenSubVector(VT, NewBV, !UndefUpper, Subtarget, DAG, dl);
    }
  }

  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, Subtarget, DAG))
    return BitOp;

  unsigned NumZero = ZeroMask.countPopulation();
  unsigned NumNonZero = NonZeroMask.countPopulation();

  // 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 = NonZeroMask.countTrailingZeros();
    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 = NonZeroMask.countTrailingZeros();
      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 = NonZeroMask.countTrailingZeros();
      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, NonZeroMask, NumNonZero, NumZero,
                                          DAG, Subtarget))
      return V;

  if (EVTBits == 16 && NumElems == 8)
    if (SDValue V = LowerBuildVectorv8i16(Op, NonZeroMask, 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 = !NonZeroMask[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 (NonZeroMask.extractBitsAsZExtValue(2, i * 2)) {
        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 = NonZeroMask.extractBitsAsZExtValue(2, 0) == 2;
    bool Reverse2 = NonZeroMask.extractBitsAsZExtValue(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 elements in each LaneSizeInBits lane in this shuffle mask come
/// from multiple lanes - this is different to isLaneCrossingShuffleMask to
/// better support 'repeated mask + lane permute' style shuffles.
static bool isMultiLaneShuffleMask(unsigned LaneSizeInBits,
                                   unsigned ScalarSizeInBits,
                                   ArrayRef<int> Mask) {
  assert(LaneSizeInBits && ScalarSizeInBits &&
         (LaneSizeInBits % ScalarSizeInBits) == 0 &&
         "Illegal shuffle lane size");
  int NumElts = Mask.size();
  int NumEltsPerLane = LaneSizeInBits / ScalarSizeInBits;
  int NumLanes = NumElts / NumEltsPerLane;
  if (NumLanes > 1) {
    for (int i = 0; i != NumLanes; ++i) {
      int SrcLane = -1;
      for (int j = 0; j != NumEltsPerLane; ++j) {
        int M = Mask[(i * NumEltsPerLane) + j];
        if (M < 0)
          continue;
        int Lane = (M % NumElts) / NumEltsPerLane;
        if (SrcLane >= 0 && SrcLane != Lane)
          return true;
        SrcLane = Lane;
      }
    }
  }
  return false;
}

/// 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,
                                        unsigned EltSizeInBits,
                                        ArrayRef<int> Mask,
                                        SmallVectorImpl<int> &RepeatedMask) {
  int LaneSize = LaneSizeInBits / EltSizeInBits;
  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;
}

/// 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) {
  return isRepeatedTargetShuffleMask(LaneSizeInBits, VT.getScalarSizeInBits(),
                                     Mask, RepeatedMask);
}

/// Checks whether the vector elements referenced by two shuffle masks are
/// equivalent.
static bool IsElementEquivalent(int MaskSize, SDValue Op, SDValue ExpectedOp,
                                int Idx, int ExpectedIdx) {
  assert(0 <= Idx && Idx < MaskSize && 0 <= ExpectedIdx &&
         ExpectedIdx < MaskSize && "Out of range element index");
  if (!Op || !ExpectedOp || Op.getOpcode() != ExpectedOp.getOpcode())
    return false;

  switch (Op.getOpcode()) {
  case ISD::BUILD_VECTOR:
    // If the values are build vectors, we can look through them to find
    // equivalent inputs that make the shuffles equivalent.
    // TODO: Handle MaskSize != Op.getNumOperands()?
    if (MaskSize == (int)Op.getNumOperands() &&
        MaskSize == (int)ExpectedOp.getNumOperands())
      return Op.getOperand(Idx) == ExpectedOp.getOperand(ExpectedIdx);
    break;
  case X86ISD::VBROADCAST:
  case X86ISD::VBROADCAST_LOAD:
    // TODO: Handle MaskSize != Op.getValueType().getVectorNumElements()?
    return (Op == ExpectedOp &&
            (int)Op.getValueType().getVectorNumElements() == MaskSize);
  case X86ISD::HADD:
  case X86ISD::HSUB:
  case X86ISD::FHADD:
  case X86ISD::FHSUB:
  case X86ISD::PACKSS:
  case X86ISD::PACKUS:
    // HOP(X,X) can refer to the elt from the lower/upper half of a lane.
    // TODO: Handle MaskSize != NumElts?
    // TODO: Handle HOP(X,Y) vs HOP(Y,X) equivalence cases.
    if (Op == ExpectedOp && Op.getOperand(0) == Op.getOperand(1)) {
      MVT VT = Op.getSimpleValueType();
      int NumElts = VT.getVectorNumElements();
      if (MaskSize == NumElts) {
        int NumLanes = VT.getSizeInBits() / 128;
        int NumEltsPerLane = NumElts / NumLanes;
        int NumHalfEltsPerLane = NumEltsPerLane / 2;
        bool SameLane =
            (Idx / NumEltsPerLane) == (ExpectedIdx / NumEltsPerLane);
        bool SameElt =
            (Idx % NumHalfEltsPerLane) == (ExpectedIdx % NumHalfEltsPerLane);
        return SameLane && SameElt;
      }
    }
    break;
  }

  return false;
}

/// 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(ArrayRef<int> Mask, ArrayRef<int> ExpectedMask,
                                SDValue V1 = SDValue(),
                                SDValue V2 = SDValue()) {
  int Size = Mask.size();
  if (Size != (int)ExpectedMask.size())
    return false;

  for (int i = 0; i < Size; ++i) {
    assert(Mask[i] >= -1 && "Out of bound mask element!");
    int MaskIdx = Mask[i];
    int ExpectedIdx = ExpectedMask[i];
    if (0 <= MaskIdx && MaskIdx != ExpectedIdx) {
      SDValue MaskV = MaskIdx < Size ? V1 : V2;
      SDValue ExpectedV = ExpectedIdx < Size ? V1 : V2;
      MaskIdx = MaskIdx < Size ? MaskIdx : (MaskIdx - Size);
      ExpectedIdx = ExpectedIdx < Size ? ExpectedIdx : (ExpectedIdx - Size);
      if (!IsElementEquivalent(Size, MaskV, ExpectedV, MaskIdx, ExpectedIdx))
        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(MVT VT, 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;

  // Don't use V1/V2 if they're not the same size as the shuffle mask type.
  if (V1 && V1.getValueSizeInBits() != VT.getSizeInBits())
    V1 = SDValue();
  if (V2 && V2.getValueSizeInBits() != VT.getSizeInBits())
    V2 = SDValue();

  for (int i = 0; i < Size; ++i) {
    int MaskIdx = Mask[i];
    int ExpectedIdx = ExpectedMask[i];
    if (MaskIdx == SM_SentinelUndef || MaskIdx == ExpectedIdx)
      continue;
    if (0 <= MaskIdx && 0 <= ExpectedIdx) {
      SDValue MaskV = MaskIdx < Size ? V1 : V2;
      SDValue ExpectedV = ExpectedIdx < Size ? V1 : V2;
      MaskIdx = MaskIdx < Size ? MaskIdx : (MaskIdx - Size);
      ExpectedIdx = ExpectedIdx < Size ? ExpectedIdx : (ExpectedIdx - Size);
      if (IsElementEquivalent(Size, MaskV, ExpectedV, MaskIdx, ExpectedIdx))
        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) {
  EVT CondVT = Cond.getValueType();
  unsigned EltSizeInBits = CondVT.getScalarSizeInBits();
  unsigned NumElts = CondVT.getVectorNumElements();

  APInt UndefElts;
  SmallVector<APInt, 32> EltBits;
  if (!getTargetConstantBitsFromNode(Cond, EltSizeInBits, UndefElts, EltBits,
                                     true, false))
    return false;

  Mask.resize(NumElts, SM_SentinelUndef);

  for (int i = 0; i != (int)NumElts; ++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 (UndefElts[i] || EltBits[i].isNullValue())
      Mask[i] += NumElts;
  }

  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(VT, Mask, Unpcklwd) ||
                         isTargetShuffleEquivalent(VT, 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(VT, Mask, UnpackMask) ||
        isTargetShuffleEquivalent(VT, 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!");

  // If the mask only uses one non-undef element, then fully 'splat' it to
  // improve later broadcast matching.
  int FirstIndex = find_if(Mask, [](int M) { return M >= 0; }) - Mask.begin();
  assert(0 <= FirstIndex && FirstIndex < 4 && "All undef shuffle mask");

  int FirstElt = Mask[FirstIndex];
  if (all_of(Mask, [FirstElt](int M) { return M < 0 || M == FirstElt; }))
    return (FirstElt << 6) | (FirstElt << 4) | (FirstElt << 2) | FirstElt;

  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(VT, TargetMask, Unpckl, V1,
                                (IsUnary ? V1 : V2))) {
    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(VT, TargetMask, Unpckh, V1,
                                (IsUnary ? V1 : V2))) {
    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(VT, TargetMask, Unpckl)) {
      UnpackOpcode = X86ISD::UNPCKL;
      std::swap(V1, V2);
      return true;
    }

    ShuffleVectorSDNode::commuteMask(Unpckh);
    if (isTargetShuffleEquivalent(VT, 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(Mask, Unpckl, V1, V2))
    return DAG.getNode(X86ISD::UNPCKL, DL, VT, V1, V2);

  SmallVector<int, 8> Unpckh;
  createUnpackShuffleMask(VT, Unpckh, /* Lo = */ false, /* Unary = */ false);
  if (isShuffleEquivalent(Mask, Unpckh, V1, V2))
    return DAG.getNode(X86ISD::UNPCKH, DL, VT, V1, V2);

  // Commute and try again.
  ShuffleVectorSDNode::commuteMask(Unpckl);
  if (isShuffleEquivalent(Mask, Unpckl, V1, V2))
    return DAG.getNode(X86ISD::UNPCKL, DL, VT, V2, V1);

  ShuffleVectorSDNode::commuteMask(Unpckh);
  if (isShuffleEquivalent(Mask, Unpckh, V1, V2))
    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(Mask, Unpckl, V1, V2))
    UnpackOpcode = X86ISD::UNPCKL;
  else if (isShuffleEquivalent(Mask, Unpckh, V1, V2))
    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.
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;
}

// Helper to create TRUNCATE/VTRUNC nodes, optionally with zero/undef upper
// element padding to the final DstVT.
static SDValue getAVX512TruncNode(const SDLoc &DL, MVT DstVT, SDValue Src,
                                  const X86Subtarget &Subtarget,
                                  SelectionDAG &DAG, bool ZeroUppers) {
  MVT SrcVT = Src.getSimpleValueType();
  MVT DstSVT = DstVT.getScalarType();
  unsigned NumDstElts = DstVT.getVectorNumElements();
  unsigned NumSrcElts = SrcVT.getVectorNumElements();
  unsigned DstEltSizeInBits = DstVT.getScalarSizeInBits();

  if (!DAG.getTargetLoweringInfo().isTypeLegal(SrcVT))
    return SDValue();

  // Perform a direct ISD::TRUNCATE if possible.
  if (NumSrcElts == NumDstElts)
    return DAG.getNode(ISD::TRUNCATE, DL, DstVT, Src);

  if (NumSrcElts > NumDstElts) {
    MVT TruncVT = MVT::getVectorVT(DstSVT, NumSrcElts);
    SDValue Trunc = DAG.getNode(ISD::TRUNCATE, DL, TruncVT, Src);
    return extractSubVector(Trunc, 0, DAG, DL, DstVT.getSizeInBits());
  }

  if ((NumSrcElts * DstEltSizeInBits) >= 128) {
    MVT TruncVT = MVT::getVectorVT(DstSVT, NumSrcElts);
    SDValue Trunc = DAG.getNode(ISD::TRUNCATE, DL, TruncVT, Src);
    return widenSubVector(Trunc, ZeroUppers, Subtarget, DAG, DL,
                          DstVT.getSizeInBits());
  }

  // Non-VLX targets must truncate from a 512-bit type, so we need to
  // widen, truncate and then possibly extract the original subvector.
  if (!Subtarget.hasVLX() && !SrcVT.is512BitVector()) {
    SDValue NewSrc = widenSubVector(Src, ZeroUppers, Subtarget, DAG, DL, 512);
    return getAVX512TruncNode(DL, DstVT, NewSrc, Subtarget, DAG, ZeroUppers);
  }

  // Fallback to a X86ISD::VTRUNC, padding if necessary.
  MVT TruncVT = MVT::getVectorVT(DstSVT, 128 / DstEltSizeInBits);
  SDValue Trunc = DAG.getNode(X86ISD::VTRUNC, DL, TruncVT, Src);
  if (DstVT != TruncVT)
    Trunc = widenSubVector(Trunc, ZeroUppers, Subtarget, DAG, DL,
                           DstVT.getSizeInBits());
  return Trunc;
}

// 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
//
// One can just use a single vpmovdw instruction, without avx512vl we need to
// use the zmm variant and extract the lower subvector, padding with zeroes.
// TODO: Merge with lowerShuffleAsVTRUNC.
static SDValue lowerShuffleWithVPMOV(const SDLoc &DL, MVT VT, SDValue V1,
                                     SDValue V2, ArrayRef<int> Mask,
                                     const APInt &Zeroable,
                                     const X86Subtarget &Subtarget,
                                     SelectionDAG &DAG) {
  assert((VT == MVT::v16i8 || VT == MVT::v8i16) && "Unexpected VTRUNC type");
  if (!Subtarget.hasAVX512())
    return SDValue();

  unsigned NumElts = VT.getVectorNumElements();
  unsigned EltSizeInBits = VT.getScalarSizeInBits();
  unsigned MaxScale = 64 / EltSizeInBits;
  for (unsigned Scale = 2; Scale <= MaxScale; Scale += Scale) {
    unsigned NumSrcElts = NumElts / Scale;
    unsigned UpperElts = NumElts - NumSrcElts;
    if (!isSequentialOrUndefInRange(Mask, 0, NumSrcElts, 0, Scale) ||
        !Zeroable.extractBits(UpperElts, NumSrcElts).isAllOnesValue())
      continue;

    SDValue Src = V1;
    if (!Src.hasOneUse())
      return SDValue();

    Src = peekThroughOneUseBitcasts(Src);
    if (Src.getOpcode() != ISD::TRUNCATE ||
        Src.getScalarValueSizeInBits() != (EltSizeInBits * Scale))
      return SDValue();
    Src = Src.getOperand(0);

    // VPMOVWB is only available with avx512bw.
    MVT SrcVT = Src.getSimpleValueType();
    if (SrcVT.getVectorElementType() == MVT::i16 && VT == MVT::v16i8 &&
        !Subtarget.hasBWI())
      return SDValue();

    bool UndefUppers = isUndefInRange(Mask, NumSrcElts, UpperElts);
    return getAVX512TruncNode(DL, VT, Src, Subtarget, DAG, !UndefUppers);
  }

  return SDValue();
}

// Attempt to match binary shuffle patterns as a truncate.
static SDValue lowerShuffleAsVTRUNC(const SDLoc &DL, MVT VT, SDValue V1,
                                    SDValue V2, ArrayRef<int> Mask,
                                    const APInt &Zeroable,
                                    const X86Subtarget &Subtarget,
                                    SelectionDAG &DAG) {
  assert((VT.is128BitVector() || VT.is256BitVector()) &&
         "Unexpected VTRUNC type");
  if (!Subtarget.hasAVX512())
    return SDValue();

  unsigned NumElts = VT.getVectorNumElements();
  unsigned EltSizeInBits = VT.getScalarSizeInBits();
  unsigned MaxScale = 64 / EltSizeInBits;
  for (unsigned Scale = 2; Scale <= MaxScale; Scale += Scale) {
    // TODO: Support non-BWI VPMOVWB truncations?
    unsigned SrcEltBits = EltSizeInBits * Scale;
    if (SrcEltBits < 32 && !Subtarget.hasBWI())
      continue;

    // Match shuffle <0,Scale,2*Scale,..,undef_or_zero,undef_or_zero,...>
    // Bail if the V2 elements are undef.
    unsigned NumHalfSrcElts = NumElts / Scale;
    unsigned NumSrcElts = 2 * NumHalfSrcElts;
    if (!isSequentialOrUndefInRange(Mask, 0, NumSrcElts, 0, Scale) ||
        isUndefInRange(Mask, NumHalfSrcElts, NumHalfSrcElts))
      continue;

    // The elements beyond the truncation must be undef/zero.
    unsigned UpperElts = NumElts - NumSrcElts;
    if (UpperElts > 0 &&
        !Zeroable.extractBits(UpperElts, NumSrcElts).isAllOnesValue())
      continue;
    bool UndefUppers =
        UpperElts > 0 && isUndefInRange(Mask, NumSrcElts, UpperElts);

    // As we're using both sources then we need to concat them together
    // and truncate from the double-sized src.
    MVT ConcatVT = MVT::getVectorVT(VT.getScalarType(), NumElts * 2);
    SDValue Src = DAG.getNode(ISD::CONCAT_VECTORS, DL, ConcatVT, V1, V2);

    MVT SrcSVT = MVT::getIntegerVT(SrcEltBits);
    MVT SrcVT = MVT::getVectorVT(SrcSVT, NumSrcElts);
    Src = DAG.getBitcast(SrcVT, Src);
    return getAVX512TruncNode(DL, VT, Src, Subtarget, DAG, !UndefUppers);
  }

  return SDValue();
}

/// 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.
// Checks for compaction shuffle masks if MaxStages > 1.
// 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 MaxStages = 1) {
  unsigned NumElts = VT.getVectorNumElements();
  unsigned BitSize = VT.getScalarSizeInBits();
  assert(0 < MaxStages && MaxStages <= 3 && (BitSize << MaxStages) <= 64 &&
         "Illegal maximum compaction");

  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;
  };

  // Attempt to match against wider and wider compaction patterns.
  for (unsigned NumStages = 1; NumStages <= MaxStages; ++NumStages) {
    MVT PackSVT = MVT::getIntegerVT(BitSize << NumStages);
    MVT PackVT = MVT::getVectorVT(PackSVT, NumElts >> NumStages);

    // Try binary shuffle.
    SmallVector<int, 32> BinaryMask;
    createPackShuffleMask(VT, BinaryMask, false, NumStages);
    if (isTargetShuffleEquivalent(VT, TargetMask, BinaryMask, V1, V2))
      if (MatchPACK(V1, V2, PackVT))
        return true;

    // Try unary shuffle.
    SmallVector<int, 32> UnaryMask;
    createPackShuffleMask(VT, UnaryMask, true, NumStages);
    if (isTargetShuffleEquivalent(VT, 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;
  unsigned SizeBits = VT.getSizeInBits();
  unsigned EltBits = VT.getScalarSizeInBits();
  unsigned MaxStages = Log2_32(64 / EltBits);
  if (!matchShuffleWithPACK(VT, PackVT, V1, V2, PackOpcode, Mask, DAG,
                            Subtarget, MaxStages))
    return SDValue();

  unsigned CurrentEltBits = PackVT.getScalarSizeInBits();
  unsigned NumStages = Log2_32(CurrentEltBits / EltBits);

  // Don't lower multi-stage packs on AVX512, truncation is better.
  if (NumStages != 1 && SizeBits == 128 && Subtarget.hasVLX())
    return SDValue();

  // Pack to the largest type possible:
  // vXi64/vXi32 -> PACK*SDW and vXi16 -> PACK*SWB.
  unsigned MaxPackBits = 16;
  if (CurrentEltBits > 16 &&
      (PackOpcode == X86ISD::PACKSS || Subtarget.hasSSE41()))
    MaxPackBits = 32;

  // Repeatedly pack down to the target size.
  SDValue Res;
  for (unsigned i = 0; i != NumStages; ++i) {
    unsigned SrcEltBits = std::min(MaxPackBits, CurrentEltBits);
    unsigned NumSrcElts = SizeBits / SrcEltBits;
    MVT SrcSVT = MVT::getIntegerVT(SrcEltBits);
    MVT DstSVT = MVT::getIntegerVT(SrcEltBits / 2);
    MVT SrcVT = MVT::getVectorVT(SrcSVT, NumSrcElts);
    MVT DstVT = MVT::getVectorVT(DstSVT, NumSrcElts * 2);
    Res = DAG.getNode(PackOpcode, DL, DstVT, DAG.getBitcast(SrcVT, V1),
                      DAG.getBitcast(SrcVT, V2));
    V1 = V2 = Res;
    CurrentEltBits /= 2;
  }
  assert(Res && Res.getValueType() == VT &&
         "Failed to lower compaction shuffle");
  return Res;
}

/// 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);
    APFloat AllOnesValue = APFloat::getAllOnesValue(
        SelectionDAG::EVTToAPFloatSemantics(EltVT), EltVT.getSizeInBits());
    AllOnes = DAG.getConstantFP(AllOnesValue, 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);
    }

    // If we have VPTERNLOG, we can use that as a bit blend.
    if (Subtarget.hasVLX())
      if (SDValue BitBlend =
              lowerShuffleAsBitBlend(DL, VT, V1, V2, Mask, DAG))
        return BitBlend;

    // 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. For vXi8/vXi16 shuffles we may use unpack instead of blend.
static SDValue lowerShuffleAsDecomposedShuffleMerge(
    const SDLoc &DL, MVT VT, SDValue V1, SDValue V2, ArrayRef<int> Mask,
    const X86Subtarget &Subtarget, SelectionDAG &DAG) {
  int NumElts = Mask.size();
  int NumLanes = VT.getSizeInBits() / 128;
  int NumEltsPerLane = NumElts / NumLanes;

  // Shuffle the input elements into the desired positions in V1 and V2 and
  // unpack/blend them together.
  bool IsAlternating = true;
  SmallVector<int, 32> V1Mask(NumElts, -1);
  SmallVector<int, 32> V2Mask(NumElts, -1);
  SmallVector<int, 32> FinalMask(NumElts, -1);
  for (int i = 0; i < NumElts; ++i) {
    int M = Mask[i];
    if (M >= 0 && M < NumElts) {
      V1Mask[i] = M;
      FinalMask[i] = i;
      IsAlternating &= (i & 1) == 0;
    } else if (M >= NumElts) {
      V2Mask[i] = M - NumElts;
      FinalMask[i] = i + NumElts;
      IsAlternating &= (i & 1) == 1;
    }
  }

  // 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;
  }

  // If the final mask is an alternating blend of vXi8/vXi16, convert to an
  // UNPCKL(SHUFFLE, SHUFFLE) pattern.
  // TODO: It doesn't have to be alternating - but each lane mustn't have more
  // than half the elements coming from each source.
  if (IsAlternating && VT.getScalarSizeInBits() < 32) {
    V1Mask.assign(NumElts, -1);
    V2Mask.assign(NumElts, -1);
    FinalMask.assign(NumElts, -1);
    for (int i = 0; i != NumElts; i += NumEltsPerLane)
      for (int j = 0; j != NumEltsPerLane; ++j) {
        int M = Mask[i + j];
        if (M >= 0 && M < NumElts) {
          V1Mask[i + (j / 2)] = M;
          FinalMask[i + j] = i + (j / 2);
        } else if (M >= NumElts) {
          V2Mask[i + (j / 2)] = M - NumElts;
          FinalMask[i + j] = i + (j / 2) + NumElts;
        }
      }
  }

  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, FinalMask);
}

/// 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 (isAnyZero(Mask))
    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 = getEXTEND_VECTOR_INREG(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())
    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: {
      // The extraction index adds to the existing offset.
      unsigned EltBitWidth = V.getScalarValueSizeInBits();
      unsigned Idx = V.getConstantOperandVal(1);
      unsigned BeginOffset = Idx * EltBitWidth;
      BitOffset += BeginOffset;
      V = V.getOperand(0);
      continue;
    }
    case ISD::INSERT_SUBVECTOR: {
      SDValue VOuter = V.getOperand(0), VInner = V.getOperand(1);
      int EltBitWidth = VOuter.getScalarValueSizeInBits();
      int Idx = (int)V.getConstantOperandVal(2);
      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, TypeSize::Fixed(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 = 0;
  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(Mask, {0, 3}, V1, V2) ||
      isShuffleEquivalent(Mask, {1, 3}, V1, V2))
    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] = {Mask[0] < 0 ? -1 : (Mask[0] * 2),
                          Mask[0] < 0 ? -1 : ((Mask[0] * 2) + 1),
                          Mask[1] < 0 ? -1 : (Mask[1] * 2),
                          Mask[1] < 0 ? -1 : ((Mask[1] * 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 lowerShuffleAsDecomposedShuffleMerge(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;
    }
  } else if (NumV2Elements == 3) {
    // Ideally canonicalizeShuffleMaskWithCommute should have caught this, but
    // we can get here due to other paths (e.g repeated mask matching) that we
    // don't want to do another round of lowerVECTOR_SHUFFLE.
    ShuffleVectorSDNode::commuteMask(NewMask);
    return lowerShuffleWithSHUFPS(DL, VT, NewMask, V2, V1, DAG);
  }
  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(Mask, {0, 0, 2, 2}, V1, V2))
        return DAG.getNode(X86ISD::MOVSLDUP, DL, MVT::v4f32, V1);
      if (isShuffleEquivalent(Mask, {1, 1, 3, 3}, V1, V2))
        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(Mask, {0, 1, 0, 1}, V1, V2))
        return DAG.getNode(X86ISD::MOVLHPS, DL, MVT::v4f32, V1, V1);
      if (isShuffleEquivalent(Mask, {2, 3, 2, 3}, V1, V2))
        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(Mask, {0, 1, 4, 5}, V1, V2))
      return DAG.getNode(X86ISD::MOVLHPS, DL, MVT::v4f32, V1, V2);
    if (isShuffleEquivalent(Mask, {2, 3, 6, 7}, V1, V2))
      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(Mask, {0, 0, 1, 1}, V1, V2))
      Mask = UnpackLoMask;
    else if (isShuffleEquivalent(Mask, {2, 2, 3, 3}, V1, V2))
      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 lowerShuffleAsDecomposedShuffleMerge(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;

  // Try to use lower using a truncation.
  if (SDValue V = lowerShuffleWithVPMOV(DL, MVT::v8i16, V1, V2, Mask, Zeroable,
                                        Subtarget, DAG))
    return V;

  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 lower using a truncation.
  if (SDValue V = lowerShuffleAsVTRUNC(DL, MVT::v8i16, V1, V2, Mask, Zeroable,
                                       Subtarget, DAG))
    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;

  // Attempt to lower using compaction, SSE41 is necessary for PACKUSDW.
  // We could use SIGN_EXTEND_INREG+PACKSSDW for older targets but this seems to
  // be slower than a PSHUFLW+PSHUFHW+PSHUFD chain.
  int NumEvenDrops = canLowerByDroppingEvenElements(Mask, false);
  if ((NumEvenDrops == 1 || NumEvenDrops == 2) && Subtarget.hasSSE41() &&
      !Subtarget.hasVLX()) {
    SmallVector<SDValue, 8> DWordClearOps(4, DAG.getConstant(0, DL, MVT::i32));
    for (unsigned i = 0; i != 4; i += 1 << (NumEvenDrops - 1))
      DWordClearOps[i] = DAG.getConstant(0xFFFF, DL, MVT::i32);
    SDValue DWordClearMask = DAG.getBuildVector(MVT::v4i32, DL, DWordClearOps);
    V1 = DAG.getNode(ISD::AND, DL, MVT::v4i32, DAG.getBitcast(MVT::v4i32, V1),
                     DWordClearMask);
    V2 = DAG.getNode(ISD::AND, DL, MVT::v4i32, DAG.getBitcast(MVT::v4i32, V2),
                     DWordClearMask);
    // Now pack things back together.
    SDValue Result = DAG.getNode(X86ISD::PACKUS, DL, MVT::v8i16, V1, V2);
    if (NumEvenDrops == 2) {
      Result = DAG.getBitcast(MVT::v4i32, Result);
      Result = DAG.getNode(X86ISD::PACKUS, DL, MVT::v8i16, Result, Result);
    }
    return Result;
  }

  // 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/unpacks.
  return lowerShuffleAsDecomposedShuffleMerge(DL, MVT::v8i16, V1, V2,
                                              Mask, Subtarget, DAG);
}

// Lowers unary/binary shuffle as VPERMV/VPERMV3, for non-VLX targets,
// sub-512-bit shuffles are padded to 512-bits for the shuffle and then
// the active subvector is extracted.
static SDValue lowerShuffleWithPERMV(const SDLoc &DL, MVT VT,
                                     ArrayRef<int> Mask, SDValue V1, SDValue V2,
                                     const X86Subtarget &Subtarget,
                                     SelectionDAG &DAG) {
  MVT MaskVT = VT.changeTypeToInteger();
  SDValue MaskNode;
  MVT ShuffleVT = VT;
  if (!VT.is512BitVector() && !Subtarget.hasVLX()) {
    V1 = widenSubVector(V1, false, Subtarget, DAG, DL, 512);
    V2 = widenSubVector(V2, false, Subtarget, DAG, DL, 512);
    ShuffleVT = V1.getSimpleValueType();

    // Adjust mask to correct indices for the second input.
    int NumElts = VT.getVectorNumElements();
    unsigned Scale = 512 / VT.getSizeInBits();
    SmallVector<int, 32> AdjustedMask(Mask.begin(), Mask.end());
    for (int &M : AdjustedMask)
      if (NumElts <= M)
        M += (Scale - 1) * NumElts;
    MaskNode = getConstVector(AdjustedMask, MaskVT, DAG, DL, true);
    MaskNode = widenSubVector(MaskNode, false, Subtarget, DAG, DL, 512);
  } else {
    MaskNode = getConstVector(Mask, MaskVT, DAG, DL, true);
  }

  SDValue Result;
  if (V2.isUndef())
    Result = DAG.getNode(X86ISD::VPERMV, DL, ShuffleVT, MaskNode, V1);
  else
    Result = DAG.getNode(X86ISD::VPERMV3, DL, ShuffleVT, V1, MaskNode, V2);

  if (VT != ShuffleVT)
    Result = extractSubVector(Result, 0, DAG, DL, VT.getSizeInBits());

  return Result;
}

/// 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;

  // Try to use lower using a truncation.
  if (SDValue V = lowerShuffleWithVPMOV(DL, MVT::v16i8, V1, V2, Mask, Zeroable,
                                        Subtarget, DAG))
    return V;

  if (SDValue V = lowerShuffleAsVTRUNC(DL, MVT::v16i8, V1, V2, Mask, Zeroable,
                                       Subtarget, DAG))
    return V;

  // 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;

      // AVX512VBMI can lower to VPERMB (non-VLX will pad to v64i8).
      if (Subtarget.hasVBMI())
        return lowerShuffleWithPERMV(DL, MVT::v16i8, Mask, V1, V2, Subtarget,
                                     DAG);

      // If we have XOP we can use one VPPERM instead of multiple PSHUFBs.
      if (Subtarget.hasXOP()) {
        SDValue MaskNode = getConstVector(Mask, MVT::v16i8, DAG, DL, true);
        return DAG.getNode(X86ISD::VPPERM, DL, MVT::v16i8, V1, V2, MaskNode);
      }

      // 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/unpacking single-input shuffles.
  if (NumV2Elements > 0)
    return lowerShuffleAsDecomposedShuffleMerge(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, SplitNumElements);

  // Use splitVector/extractSubVector so that split build-vectors just build two
  // narrower build vectors. This helps shuffling with splats and zeros.
  auto SplitVector = [&](SDValue V) {
    SDValue LoV, HiV;
    std::tie(LoV, HiV) = splitVector(peekThroughBitcasts(V), DAG, DL);
    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/unpack.
///
/// 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 lowerShuffleAsDecomposedShuffleMerge(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/unpack. This
  // requires that the decomposed single-input shuffles don't end up here.
  return lowerShuffleAsDecomposedShuffleMerge(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;
  bool CanUseSublanes = Subtarget.hasAVX2() && V2.isUndef();

  /// Attempts to find a sublane permute with the given size
  /// that gets all elements into their target lanes.
  ///
  /// If successful, fills CrossLaneMask and InLaneMask and returns true.
  /// If unsuccessful, returns false and may overwrite InLaneMask.
  auto getSublanePermute = [&](int NumSublanes) -> SDValue {
    int NumSublanesPerLane = NumSublanes / NumLanes;
    int NumEltsPerSublane = NumElts / NumSublanes;

    SmallVector<int, 16> CrossLaneMask;
    SmallVector<int, 16> InLaneMask(NumElts, SM_SentinelUndef);
    // CrossLaneMask but one entry == one sublane.
    SmallVector<int, 16> CrossLaneMaskLarge(NumSublanes, SM_SentinelUndef);

    for (int i = 0; i != NumElts; ++i) {
      int M = Mask[i];
      if (M < 0)
        continue;

      int SrcSublane = M / NumEltsPerSublane;
      int DstLane = i / NumEltsPerLane;

      // We only need to get the elements into the right lane, not sublane.
      // So search all sublanes that make up the destination lane.
      bool Found = false;
      int DstSubStart = DstLane * NumSublanesPerLane;
      int DstSubEnd = DstSubStart + NumSublanesPerLane;
      for (int DstSublane = DstSubStart; DstSublane < DstSubEnd; ++DstSublane) {
        if (!isUndefOrEqual(CrossLaneMaskLarge[DstSublane], SrcSublane))
          continue;

        Found = true;
        CrossLaneMaskLarge[DstSublane] = SrcSublane;
        int DstSublaneOffset = DstSublane * NumEltsPerSublane;
        InLaneMask[i] = DstSublaneOffset + M % NumEltsPerSublane;
        break;
      }
      if (!Found)
        return SDValue();
    }

    // Fill CrossLaneMask using CrossLaneMaskLarge.
    narrowShuffleMaskElts(NumEltsPerSublane, CrossLaneMaskLarge, CrossLaneMask);

    if (!CanUseSublanes) {
      // 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) {
        int LaneOffset = i * NumEltsPerLane;
        if (isSequentialOrUndefInRange(InLaneMask, LaneOffset, NumEltsPerLane,
                                       i * NumEltsPerLane))
          NumIdentityLanes++;
        else if (CrossLaneMask[LaneOffset] != 0)
          OnlyShuffleLowestLane = false;
      }
      if (OnlyShuffleLowestLane && NumIdentityLanes == (NumLanes - 1))
        return SDValue();
    }

    SDValue CrossLane = DAG.getVectorShuffle(VT, DL, V1, V2, CrossLaneMask);
    return DAG.getVectorShuffle(VT, DL, CrossLane, DAG.getUNDEF(VT),
                                InLaneMask);
  };

  // First attempt a solution with full lanes.
  if (SDValue V = getSublanePermute(/*NumSublanes=*/NumLanes))
    return V;

  // The rest of the solutions use sublanes.
  if (!CanUseSublanes)
    return SDValue();

  // Then attempt a solution with 64-bit sublanes (vpermq).
  if (SDValue V = getSublanePermute(/*NumSublanes=*/NumLanes * 2))
    return V;

  // If that doesn't work and we have fast variable shuffle,
  // attempt 32-bit sublanes (vpermd).
  if (!Subtarget.hasFastVariableShuffle())
    return SDValue();

  return getSublanePermute(/*NumSublanes=*/NumLanes * 4);
}

/// 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(Mask, {0, 1, 0, 1}, V1, V2);
    if (OnlyUsesV1 || isShuffleEquivalent(Mask, {0, 1, 4, 5}, V1, V2)) {

      // 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(Mask, {0, 0, 2, 2}, V1, V2))
      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 lowerShuffleAsDecomposedShuffleMerge(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 lowerShuffleAsDecomposedShuffleMerge(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;
      narrowShuffleMaskElts(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 lowerShuffleAsDecomposedShuffleMerge(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 lowerShuffleAsDecomposedShuffleMerge(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(RepeatedMask, {0, 0, 2, 2}, V1, V2))
      return DAG.getNode(X86ISD::MOVSLDUP, DL, MVT::v8f32, V1);
    if (isShuffleEquivalent(RepeatedMask, {1, 1, 3, 3}, V1, V2))
      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))
    return lowerShuffleAsSplitOrBlend(DL, MVT::v8f32, V1, V2, Mask, Subtarget,
                                      DAG);

  // 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 lowerShuffleAsDecomposedShuffleMerge(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())
    return lowerShuffleAsSplitOrBlend(DL, MVT::v8i32, V1, V2, Mask, Subtarget,
                                      DAG);

  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 lowerShuffleAsDecomposedShuffleMerge(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 lower using a truncation.
  if (SDValue V = lowerShuffleAsVTRUNC(DL, MVT::v16i16, V1, V2, Mask, Zeroable,
                                       Subtarget, DAG))
    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;

  // AVX512BW can lower to VPERMW (non-VLX will pad to v32i16).
  if (Subtarget.hasBWI())
    return lowerShuffleWithPERMV(DL, MVT::v16i16, Mask, V1, V2, Subtarget, 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 lower using a truncation.
  if (SDValue V = lowerShuffleAsVTRUNC(DL, MVT::v32i8, V1, V2, Mask, Zeroable,
                                       Subtarget, DAG))
    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;

  // AVX512VBMI can lower to VPERMB (non-VLX will pad to v64i8).
  if (Subtarget.hasVBMI())
    return lowerShuffleWithPERMV(DL, MVT::v32i8, Mask, V1, V2, Subtarget, 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(Mask, {0, 1, 2, 3, 0, 1, 2, 3}, V1, V2);
  if (OnlyUsesV1 ||
      isShuffleEquivalent(Mask, {0, 1, 2, 3, 8, 9, 10, 11}, V1, V2)) {
    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();
    narrowShuffleMaskElts(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(Mask, {0, 0, 2, 2, 4, 4, 6, 6}, V1, V2))
      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, Subtarget, 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(RepeatedMask, {0, 0, 2, 2}, V1, V2))
      return DAG.getNode(X86ISD::MOVSLDUP, DL, MVT::v16f32, V1);
    if (isShuffleEquivalent(RepeatedMask, {1, 1, 3, 3}, V1, V2))
      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);
  }

  // Try to create an in-lane repeating shuffle mask and then shuffle the
  // results into the target lanes.
  if (SDValue V = lowerShuffleAsRepeatedMaskAndLanePermute(
          DL, MVT::v16f32, V1, V2, Mask, Subtarget, DAG))
    return V;

  // 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, Subtarget, 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;
      narrowShuffleMaskElts(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 (Subtarget.hasBWI())
    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, Subtarget, 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);
  }

  // Try to create an in-lane repeating shuffle mask and then shuffle the
  // results into the target lanes.
  if (SDValue V = lowerShuffleAsRepeatedMaskAndLanePermute(
          DL, MVT::v16i32, V1, V2, Mask, Subtarget, DAG))
    return V;

  // 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, Subtarget, 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, Subtarget, 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;

  // Lower as AND if possible.
  if (SDValue Masked = lowerShuffleAsBitMask(DL, MVT::v64i8, V1, V2, Mask,
                                             Zeroable, Subtarget, DAG))
    return Masked;

  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, 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::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;

  if ((VT == MVT::v32i16 || VT == MVT::v64i8) && !Subtarget.hasBWI()) {
    // Try using bit ops for masking and blending before falling back to
    // splitting.
    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);
  }

  // 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(is_contained(WidenedMask, SM_SentinelZero) &&
               "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);
  }

  // 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.
  if (ISD::isBuildVectorOfConstantSDNodes(Cond.getNode())) {
    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();

  // Expand v32i16/v64i8 without BWI.
  if ((VT == MVT::v32i16 || VT == MVT::v64i8) && !Subtarget.hasBWI())
    return SDValue();

  // 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));

    unsigned IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
    SDValue Extract = DAG.getNode(X86ISD::PEXTRB, dl, MVT::i32, Vec,
                                  DAG.getTargetConstant(IdxVal, dl, MVT::i8));
    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);
  auto* IdxC = dyn_cast<ConstantSDNode>(Idx);
  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 (!IdxC) {
    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 = IdxC->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);
  auto* IdxC = dyn_cast<ConstantSDNode>(Idx);

  if (VecVT.getVectorElementType() == MVT::i1)
    return ExtractBitFromMaskVector(Op, DAG, Subtarget);

  if (!IdxC) {
    // 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 = IdxC->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,
                                  DAG.getTargetConstant(IdxVal, dl, MVT::i8));
    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, Idx);
}

SDValue X86TargetLowering::LowerINSERT_VECTOR_ELT(SDValue Op,
                                                  SelectionDAG &DAG) const {
  MVT VT = Op.getSimpleValueType();
  MVT EltVT = VT.getVectorElementType();
  unsigned NumElts = VT.getVectorNumElements();
  unsigned EltSizeInBits = EltVT.getScalarSizeInBits();

  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) {
    // Variable insertion indices, usually we're better off spilling to stack,
    // but AVX512 can use a variable compare+select by comparing against all
    // possible vector indices, and FP insertion has less gpr->simd traffic.
    if (!(Subtarget.hasBWI() ||
          (Subtarget.hasAVX512() && EltSizeInBits >= 32) ||
          (Subtarget.hasSSE41() && VT.isFloatingPoint())))
      return SDValue();

    MVT IdxSVT = MVT::getIntegerVT(EltSizeInBits);
    MVT IdxVT = MVT::getVectorVT(IdxSVT, NumElts);
    SDValue IdxExt = DAG.getZExtOrTrunc(N2, dl, IdxSVT);
    SDValue IdxSplat = DAG.getSplatBuildVector(IdxVT, dl, IdxExt);
    SDValue EltSplat = DAG.getSplatBuildVector(VT, dl, N1);

    SmallVector<SDValue, 16> RawIndices;
    for (unsigned I = 0; I != NumElts; ++I)
      RawIndices.push_back(DAG.getConstant(I, dl, IdxSVT));
    SDValue Indices = DAG.getBuildVector(IdxVT, dl, RawIndices);

    // inselt N0, N1, N2 --> select (SplatN2 == {0,1,2...}) ? SplatN1 : N0.
    return DAG.getSelectCC(dl, IdxSplat, Indices, EltSplat, N0,
                           ISD::CondCode::SETEQ);
  }

  if (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 <= EltSizeInBits) {
    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 / EltSizeInBits;
    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;
    }

    assert(N1.getValueType() != MVT::i32 && "Unexpected VT");
    N1 = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, N1);
    N2 = DAG.getTargetConstant(IdxVal, dl, MVT::i8);
    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);
  uint64_t IdxVal = Op.getConstantOperandVal(1);

  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->getAlign(), 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.
    // Suppress the folding if Offset is negative: movl foo-1, %eax is not
    // allowed because if the address of foo is 0, the ELF R_X86_64_32
    // relocation will compute to a negative value, which is invalid.
    int64_t GlobalOffset = 0;
    if (OpFlags == X86II::MO_NO_FLAG && Offset >= 0 &&
        X86::isOffsetSuitableForCodeModel(Offset, M, true)) {
      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 LP64
static SDValue
LowerToTLSGeneralDynamicModel64(GlobalAddressSDNode *GA, SelectionDAG &DAG,
                                const EVT PtrVT) {
  return GetTLSADDR(DAG, DAG.getEntryNode(), GA, nullptr, PtrVT,
                    X86::RAX, X86II::MO_TLSGD);
}

// Lower ISD::GlobalTLSAddress using the "general dynamic" model, 64 bit ILP32
static SDValue
LowerToTLSGeneralDynamicModelX32(GlobalAddressSDNode *GA, SelectionDAG &DAG,
                                 const EVT PtrVT) {
  return GetTLSADDR(DAG, DAG.getEntryNode(), GA, nullptr, PtrVT,
                    X86::EAX, X86II::MO_TLSGD);
}

static SDValue LowerToTLSLocalDynamicModel(GlobalAddressSDNode *GA,
                                           SelectionDAG &DAG, const EVT PtrVT,
                                           bool Is64Bit, bool Is64BitLP64) {
  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) {
    unsigned ReturnReg = Is64BitLP64 ? X86::RAX : X86::EAX;
    Base = GetTLSADDR(DAG, DAG.getEntryNode(), GA, nullptr, PtrVT, ReturnReg,
                      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()) {
          if (Subtarget.isTarget64BitLP64())
            return LowerToTLSGeneralDynamicModel64(GA, DAG, PtrVT);
          return LowerToTLSGeneralDynamicModelX32(GA, DAG, PtrVT);
        }
        return LowerToTLSGeneralDynamicModel32(GA, DAG, PtrVT);
      case TLSModel::LocalDynamic:
        return LowerToTLSLocalDynamicModel(GA, DAG, PtrVT, Subtarget.is64Bit(),
                                           Subtarget.isTarget64BitLP64());
      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());

      const DataLayout &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);

    // With AVX512, but not VLX we need to widen to get a 512-bit result type.
    if (!Subtarget.hasVLX() && !VT.is512BitVector()) {
      Op0 = widenSubVector(Op0, false, Subtarget, DAG, DL, 512);
      Op1 = widenSubVector(Op1, false, Subtarget, DAG, DL, 512);
    }

    SDValue Funnel;
    APInt APIntShiftAmt;
    MVT ResultVT = Op0.getSimpleValueType();
    if (X86::isConstantSplat(Amt, APIntShiftAmt)) {
      uint64_t ShiftAmt = APIntShiftAmt.urem(VT.getScalarSizeInBits());
      Funnel =
          DAG.getNode(IsFSHR ? X86ISD::VSHRD : X86ISD::VSHLD, DL, ResultVT, Op0,
                      Op1, DAG.getTargetConstant(ShiftAmt, DL, MVT::i8));
    } else {
      if (!Subtarget.hasVLX() && !VT.is512BitVector())
        Amt = widenSubVector(Amt, false, Subtarget, DAG, DL, 512);
      Funnel = DAG.getNode(IsFSHR ? X86ISD::VSHRDV : X86ISD::VSHLDV, DL,
                           ResultVT, Op0, Op1, Amt);
    }
    if (!Subtarget.hasVLX() && !VT.is512BitVector())
      Funnel = extractSubVector(Funnel, 0, DAG, DL, VT.getSizeInBits());
    return Funnel;
  }
  assert(
      (VT == MVT::i8 || 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();
  bool ExpandFunnel = !OptForSize && Subtarget.isSHLDSlow();

  // fshl(x,y,z) -> (((aext(x) << bw) | zext(y)) << (z & (bw-1))) >> bw.
  // fshr(x,y,z) -> (((aext(x) << bw) | zext(y)) >> (z & (bw-1))).
  if ((VT == MVT::i8 || (ExpandFunnel && VT == MVT::i16)) &&
      !isa<ConstantSDNode>(Amt)) {
    unsigned EltSizeInBits = VT.getScalarSizeInBits();
    SDValue Mask = DAG.getConstant(EltSizeInBits - 1, DL, Amt.getValueType());
    SDValue HiShift = DAG.getConstant(EltSizeInBits, DL, Amt.getValueType());
    Op0 = DAG.getAnyExtOrTrunc(Op0, DL, MVT::i32);
    Op1 = DAG.getZExtOrTrunc(Op1, DL, MVT::i32);
    Amt = DAG.getNode(ISD::AND, DL, Amt.getValueType(), Amt, Mask);
    SDValue Res = DAG.getNode(ISD::SHL, DL, MVT::i32, Op0, HiShift);
    Res = DAG.getNode(ISD::OR, DL, MVT::i32, Res, Op1);
    if (IsFSHR) {
      Res = DAG.getNode(ISD::SRL, DL, MVT::i32, Res, Amt);
    } else {
      Res = DAG.getNode(ISD::SHL, DL, MVT::i32, Res, Amt);
      Res = DAG.getNode(ISD::SRL, DL, MVT::i32, Res, HiShift);
    }
    return DAG.getZExtOrTrunc(Res, DL, VT);
  }

  if (VT == MVT::i8 || ExpandFunnel)
    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));
}

/// Given a scalar cast to FP with a cast to integer operand (almost an ftrunc),
/// try to vectorize the cast ops. This will avoid an expensive round-trip
/// between XMM and GPR.
static SDValue lowerFPToIntToFP(SDValue CastToFP, SelectionDAG &DAG,
                                const X86Subtarget &Subtarget) {
  // TODO: Allow FP_TO_UINT.
  SDValue CastToInt = CastToFP.getOperand(0);
  MVT VT = CastToFP.getSimpleValueType();
  if (CastToInt.getOpcode() != ISD::FP_TO_SINT || VT.isVector())
    return SDValue();

  MVT IntVT = CastToInt.getSimpleValueType();
  SDValue X = CastToInt.getOperand(0);
  MVT SrcVT = X.getSimpleValueType();
  if (SrcVT != MVT::f32 && SrcVT != MVT::f64)
    return SDValue();

  // See if we have 128-bit vector cast instructions for this type of cast.
  // We need cvttps2dq/cvttpd2dq and cvtdq2ps/cvtdq2pd.
  if (!Subtarget.hasSSE2() || (VT != MVT::f32 && VT != MVT::f64) ||
      IntVT != MVT::i32)
    return SDValue();

  unsigned SrcSize = SrcVT.getSizeInBits();
  unsigned IntSize = IntVT.getSizeInBits();
  unsigned VTSize = VT.getSizeInBits();
  MVT VecSrcVT = MVT::getVectorVT(SrcVT, 128 / SrcSize);
  MVT VecIntVT = MVT::getVectorVT(IntVT, 128 / IntSize);
  MVT VecVT = MVT::getVectorVT(VT, 128 / VTSize);

  // We need target-specific opcodes if this is v2f64 -> v4i32 -> v2f64.
  unsigned ToIntOpcode =
      SrcSize != IntSize ? X86ISD::CVTTP2SI : (unsigned)ISD::FP_TO_SINT;
  unsigned ToFPOpcode =
      IntSize != VTSize ? X86ISD::CVTSI2P : (unsigned)ISD::SINT_TO_FP;

  // sint_to_fp (fp_to_sint X) --> extelt (sint_to_fp (fp_to_sint (s2v X))), 0
  //
  // We are not defining the high elements (for example, zero them) because
  // that could nullify any performance advantage that we hoped to gain from
  // this vector op hack. We do not expect any adverse effects (like denorm
  // penalties) with cast ops.
  SDLoc DL(CastToFP);
  SDValue ZeroIdx = DAG.getIntPtrConstant(0, DL);
  SDValue VecX = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VecSrcVT, X);
  SDValue VCastToInt = DAG.getNode(ToIntOpcode, DL, VecIntVT, VecX);
  SDValue VCastToFP = DAG.getNode(ToFPOpcode, DL, VecVT, VCastToInt);
  return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, VCastToFP, ZeroIdx);
}

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 (SDValue R = lowerFPToIntToFP(Op, DAG, Subtarget))
    return R;

  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 SDValue();

  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, Align(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) {
  // We can't use this algorithm for strict fp. It produces -0.0 instead of +0.0
  // when converting 0 when rounding toward negative infinity. Caller will
  // fall back to Expand for when i64 or is legal or use FILD in 32-bit mode.
  assert(!Op->isStrictFPOpcode() && "Expected non-strict uint_to_fp!");
  // 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
  */

  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, Align(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, Align(16));

  // Load the 64-bit value into an XMM register.
  SDValue XR1 =
      DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2i64, Op.getOperand(0));
  SDValue CLod0 = DAG.getLoad(
      MVT::v4i32, dl, DAG.getEntryNode(), CPIdx0,
      MachinePointerInfo::getConstantPool(DAG.getMachineFunction()), Align(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()), Align(16));
  SDValue XR2F = DAG.getBitcast(MVT::v2f64, Unpck1);
  // TODO: Are there any fast-math-flags to propagate here?
  SDValue Sub = DAG.getNode(ISD::FSUB, dl, MVT::v2f64, XR2F, CLod1);
  SDValue Result;

  if (Subtarget.hasSSE3() &&
      shouldUseHorizontalOp(true, DAG, Subtarget)) {
    Result = DAG.getNode(X86ISD::FHADD, dl, MVT::v2f64, Sub, Sub);
  } else {
    SDValue Shuffle = DAG.getVectorShuffle(MVT::v2f64, dl, Sub, Sub, {1,-1});
    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));
  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, Align(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 SDValue();

  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;

  // The transform for i64->f64 isn't correct for 0 when rounding to negative
  // infinity. It produces -0.0, so disable under strictfp.
  if (SrcVT == MVT::i64 && DstVT == MVT::f64 && X86ScalarSSEf64 && !IsStrict)
    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 || DstVT == MVT::f64))
    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();
  Align SlotAlign(8);
  MachinePointerInfo MPI =
    MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SSFI);
  if (SrcVT == MVT::i32) {
    SDValue OffsetSlot =
        DAG.getMemBasePlusOffset(StackSlot, TypeSize::Fixed(4), dl);
    SDValue Store1 = DAG.getStore(Chain, dl, Src, StackSlot, MPI, SlotAlign);
    SDValue Store2 = DAG.getStore(Store1, dl, DAG.getConstant(0, dl, MVT::i32),
                                  OffsetSlot, MPI.getWithOffset(4), SlotAlign);
    std::pair<SDValue, SDValue> Tmp =
        BuildFILD(DstVT, MVT::i64, dl, Store2, StackSlot, MPI, SlotAlign, 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, SlotAlign);
  // For i64 source, we need to add the appropriate power of 2 if the input
  // was negative. We must be careful to do the computation in x87 extended
  // precision, not in SSE.
  SDVTList Tys = DAG.getVTList(MVT::f80, MVT::Other);
  SDValue Ops[] = { Store, StackSlot };
  SDValue Fild =
      DAG.getMemIntrinsicNode(X86ISD::FILD, dl, Tys, Ops, MVT::i64, MPI,
                              SlotAlign, 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);
  Align CPAlignment = cast<ConstantPoolSDNode>(FudgePtr)->getAlign();

  // 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, Align(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) ? 0x80000000 : 0;
    //  FltOfs = (Value >= Thresh) ? 0x80000000 : 0;
    //  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::SETGE, Chain,
                         /*IsSignaling*/ true);
      Chain = Cmp.getValue(1);
    } else {
      Cmp = DAG.getSetCC(DL, ResVT, Value, ThreshVal, ISD::SETGE);
    }

    // Our preferred lowering of
    //
    // (Value >= Thresh) ? 0x8000000000000000ULL : 0
    //
    // is
    //
    // (Value >= Thresh) << 63
    //
    // but since we can get here after LegalOperations, DAGCombine might do the
    // wrong thing if we create a select. So, directly create the preferred
    // version.
    SDValue Zext = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, Cmp);
    SDValue Const63 = DAG.getConstant(63, DL, MVT::i8);
    Adjust = DAG.getNode(ISD::SHL, DL, MVT::i64, Zext, Const63);

    SDValue FltOfs = DAG.getSelect(DL, TheVT, Cmp, ThreshVal,
                                   DAG.getConstantFP(0.0, DL, TheVT));

    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);

  if (VT == MVT::v32i16 && !Subtarget.hasBWI()) {
    assert(InVT == MVT::v32i8 && "Unexpected VT!");
    return splitVectorIntUnary(Op, DAG);
  }

  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 for PACKSS (SSE41 PACKUSDW is handled below).
  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, DAG.getUNDEF(InVT));
    Res = extractSubVector(Res, 0, DAG, DL, 64);
    return DAG.getBitcast(DstVT, Res);
  }

  // Split lower/upper subvectors.
  SDValue Lo, Hi;
  std::tie(Lo, Hi) = splitVector(In, DAG, DL);

  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();
    narrowShuffleMaskElts(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, NumElems / 2);
  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
    // directly, so we need to shuffle high elements to low and use
    // sign_extend_vector_inreg.
    if (NumElts == 16 && !Subtarget.canExtendTo512DQ()) {
      SDValue Lo, Hi;
      if (InVT == MVT::v16i8) {
        Lo = DAG.getNode(ISD::SIGN_EXTEND_VECTOR_INREG, DL, MVT::v8i32, In);
        Hi = DAG.getVectorShuffle(
            InVT, DL, In, In,
            {8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1});
        Hi = DAG.getNode(ISD::SIGN_EXTEND_VECTOR_INREG, DL, MVT::v8i32, Hi);
      } else {
        assert(InVT == MVT::v16i16 && "Unexpected VT!");
        Lo = extract128BitVector(In, 0, DAG, DL);
        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((InVT == MVT::v16i64 || 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()) {
    if (InVT == MVT::v32i16 && !Subtarget.hasBWI()) {
      assert(VT == MVT::v32i8 && "Unexpected VT!");
      return splitVectorIntUnary(Op, DAG);
    }

    // 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)) {
    In = DAG.getBitcast(MVT::v8i32, In);

    // On AVX2, v4i64 -> v4i32 becomes VPERMD.
    if (Subtarget.hasInt256()) {
      static const int ShufMask[] = {0, 2, 4, 6, -1, -1, -1, -1};
      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::v4i32, In,
                               DAG.getIntPtrConstant(0, DL));
    SDValue OpHi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::v4i32, In,
                               DAG.getIntPtrConstant(4, DL));
    static const int ShufMask[] = {0, 2, 4, 6};
    return DAG.getVectorShuffle(VT, DL, OpLo, OpHi, ShufMask);
  }

  if ((VT == MVT::v8i16) && (InVT == MVT::v8i32)) {
    In = DAG.getBitcast(MVT::v32i8, In);

    // On AVX2, v8i32 -> v8i16 becomes PSHUFB.
    if (Subtarget.hasInt256()) {
      // 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);
      return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::v8i16,
                         DAG.getBitcast(MVT::v16i16, In),
                         DAG.getIntPtrConstant(0, DL));
    }

    SDValue OpLo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::v16i8, In,
                               DAG.getIntPtrConstant(0, DL));
    SDValue OpHi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::v16i8, In,
                               DAG.getIntPtrConstant(16, DL));

    // 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) {
      if (!Subtarget.hasVLX()) {
        // Non-strict nodes without VLX can we widened to v4f32->v4i64 by type
        // legalizer and then widened again by vector op legalization.
        if (!IsStrict)
          return SDValue();

        SDValue Zero = DAG.getConstantFP(0.0, dl, MVT::v2f32);
        SDValue Tmp = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v8f32,
                                  {Src, Zero, Zero, Zero});
        Tmp = DAG.getNode(Op.getOpcode(), dl, {MVT::v8i64, MVT::Other},
                          {Op->getOperand(0), Tmp});
        SDValue Chain = Tmp.getValue(1);
        Tmp = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v2i64, Tmp,
                          DAG.getIntPtrConstant(0, dl));
        if (IsStrict)
          return DAG.getMergeValues({Tmp, Chain}, dl);
        return Tmp;
      }

      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_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
  // This is based on the TargetLowering::expandFP_TO_INT_SAT implementation,
  // but making use of X86 specifics to produce better instruction sequences.
  SDNode *Node = Op.getNode();
  bool IsSigned = Node->getOpcode() == ISD::FP_TO_SINT_SAT;
  unsigned FpToIntOpcode = IsSigned ? ISD::FP_TO_SINT : ISD::FP_TO_UINT;
  SDLoc dl(SDValue(Node, 0));
  SDValue Src = Node->getOperand(0);

  // There are three types involved here: SrcVT is the source floating point
  // type, DstVT is the type of the result, and TmpVT is the result of the
  // intermediate FP_TO_*INT operation we'll use (which may be a promotion of
  // DstVT).
  EVT SrcVT = Src.getValueType();
  EVT DstVT = Node->getValueType(0);
  EVT TmpVT = DstVT;

  // This code is only for floats and doubles. Fall back to generic code for
  // anything else.
  if (!isScalarFPTypeInSSEReg(SrcVT))
    return SDValue();

  unsigned SatWidth = Node->getConstantOperandVal(1);
  unsigned DstWidth = DstVT.getScalarSizeInBits();
  unsigned TmpWidth = TmpVT.getScalarSizeInBits();
  assert(SatWidth <= DstWidth && SatWidth <= TmpWidth &&
         "Expected saturation width smaller than result width");

  // Promote result of FP_TO_*INT to at least 32 bits.
  if (TmpWidth < 32) {
    TmpVT = MVT::i32;
    TmpWidth = 32;
  }

  // Promote conversions to unsigned 32-bit to 64-bit, because it will allow
  // us to use a native signed conversion instead.
  if (SatWidth == 32 && !IsSigned && Subtarget.is64Bit()) {
    TmpVT = MVT::i64;
    TmpWidth = 64;
  }

  // If the saturation width is smaller than the size of the temporary result,
  // we can always use signed conversion, which is native.
  if (SatWidth < TmpWidth)
    FpToIntOpcode = ISD::FP_TO_SINT;

  // Determine minimum and maximum integer values and their corresponding
  // floating-point values.
  APInt MinInt, MaxInt;
  if (IsSigned) {
    MinInt = APInt::getSignedMinValue(SatWidth).sextOrSelf(DstWidth);
    MaxInt = APInt::getSignedMaxValue(SatWidth).sextOrSelf(DstWidth);
  } else {
    MinInt = APInt::getMinValue(SatWidth).zextOrSelf(DstWidth);
    MaxInt = APInt::getMaxValue(SatWidth).zextOrSelf(DstWidth);
  }

  APFloat MinFloat(DAG.EVTToAPFloatSemantics(SrcVT));
  APFloat MaxFloat(DAG.EVTToAPFloatSemantics(SrcVT));

  APFloat::opStatus MinStatus = MinFloat.convertFromAPInt(
    MinInt, IsSigned, APFloat::rmTowardZero);
  APFloat::opStatus MaxStatus = MaxFloat.convertFromAPInt(
    MaxInt, IsSigned, APFloat::rmTowardZero);
  bool AreExactFloatBounds = !(MinStatus & APFloat::opStatus::opInexact)
                          && !(MaxStatus & APFloat::opStatus::opInexact);

  SDValue MinFloatNode = DAG.getConstantFP(MinFloat, dl, SrcVT);
  SDValue MaxFloatNode = DAG.getConstantFP(MaxFloat, dl, SrcVT);

  // If the integer bounds are exactly representable as floats, emit a
  // min+max+fptoi sequence. Otherwise use comparisons and selects.
  if (AreExactFloatBounds) {
    if (DstVT != TmpVT) {
      // Clamp by MinFloat from below. If Src is NaN, propagate NaN.
      SDValue MinClamped = DAG.getNode(
        X86ISD::FMAX, dl, SrcVT, MinFloatNode, Src);
      // Clamp by MaxFloat from above. If Src is NaN, propagate NaN.
      SDValue BothClamped = DAG.getNode(
        X86ISD::FMIN, dl, SrcVT, MaxFloatNode, MinClamped);
      // Convert clamped value to integer.
      SDValue FpToInt = DAG.getNode(FpToIntOpcode, dl, TmpVT, BothClamped);

      // NaN will become INDVAL, with the top bit set and the rest zero.
      // Truncation will discard the top bit, resulting in zero.
      return DAG.getNode(ISD::TRUNCATE, dl, DstVT, FpToInt);
    }

    // Clamp by MinFloat from below. If Src is NaN, the result is MinFloat.
    SDValue MinClamped = DAG.getNode(
      X86ISD::FMAX, dl, SrcVT, Src, MinFloatNode);
    // Clamp by MaxFloat from above. NaN cannot occur.
    SDValue BothClamped = DAG.getNode(
      X86ISD::FMINC, dl, SrcVT, MinClamped, MaxFloatNode);
    // Convert clamped value to integer.
    SDValue FpToInt = DAG.getNode(FpToIntOpcode, dl, DstVT, BothClamped);

    if (!IsSigned) {
      // In the unsigned case we're done, because we mapped NaN to MinFloat,
      // which is zero.
      return FpToInt;
    }

    // Otherwise, select zero if Src is NaN.
    SDValue ZeroInt = DAG.getConstant(0, dl, DstVT);
    return DAG.getSelectCC(
      dl, Src, Src, ZeroInt, FpToInt, ISD::CondCode::SETUO);
  }

  SDValue MinIntNode = DAG.getConstant(MinInt, dl, DstVT);
  SDValue MaxIntNode = DAG.getConstant(MaxInt, dl, DstVT);

  // Result of direct conversion, which may be selected away.
  SDValue FpToInt = DAG.getNode(FpToIntOpcode, dl, TmpVT, Src);

  if (DstVT != TmpVT) {
    // NaN will become INDVAL, with the top bit set and the rest zero.
    // Truncation will discard the top bit, resulting in zero.
    FpToInt = DAG.getNode(ISD::TRUNCATE, dl, DstVT, FpToInt);
  }

  SDValue Select = FpToInt;
  // For signed conversions where we saturate to the same size as the
  // result type of the fptoi instructions, INDVAL coincides with integer
  // minimum, so we don't need to explicitly check it.
  if (!IsSigned || SatWidth != TmpVT.getScalarSizeInBits()) {
    // If Src ULT MinFloat, select MinInt. In particular, this also selects
    // MinInt if Src is NaN.
    Select = DAG.getSelectCC(
      dl, Src, MinFloatNode, MinIntNode, Select, ISD::CondCode::SETULT);
  }

  // If Src OGT MaxFloat, select MaxInt.
  Select = DAG.getSelectCC(
    dl, Src, MaxFloatNode, MaxIntNode, Select, ISD::CondCode::SETOGT);

  // In the unsigned case we are done, because we mapped NaN to MinInt, which
  // is already zero. The promoted case was already handled above.
  if (!IsSigned || DstVT != TmpVT) {
    return Select;
  }

  // Otherwise, select 0 if Src is NaN.
  SDValue ZeroInt = DAG.getConstant(0, dl, DstVT);
  return DAG.getSelectCC(
    dl, Src, Src, ZeroInt, Select, ISD::CondCode::SETUO);
}

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)
    return SDValue();

  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();
  SDValue In = Op.getOperand(IsStrict ? 1 : 0);
  // It's legal except when f128 is involved
  if (In.getSimpleValueType() != MVT::f128)
    return Op;

  return SDValue();
}

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(0, 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.
    auto *Idx = dyn_cast<ConstantSDNode>(I->getOperand(1));
    if (!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.empty() && 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 = 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;
}

// Helper function for comparing all bits of a vector against zero.
static SDValue LowerVectorAllZero(const SDLoc &DL, SDValue V, ISD::CondCode CC,
                                  const APInt &Mask,
                                  const X86Subtarget &Subtarget,
                                  SelectionDAG &DAG, X86::CondCode &X86CC) {
  EVT VT = V.getValueType();
  unsigned ScalarSize = VT.getScalarSizeInBits();
  if (Mask.getBitWidth() != ScalarSize) {
    assert(ScalarSize == 1 && "Element Mask vs Vector bitwidth mismatch");
    return SDValue();
  }

  assert((CC == ISD::SETEQ || CC == ISD::SETNE) && "Unsupported ISD::CondCode");
  X86CC = (CC == ISD::SETEQ ? X86::COND_E : X86::COND_NE);

  auto MaskBits = [&](SDValue Src) {
    if (Mask.isAllOnesValue())
      return Src;
    EVT SrcVT = Src.getValueType();
    SDValue MaskValue = DAG.getConstant(Mask, DL, SrcVT);
    return DAG.getNode(ISD::AND, DL, SrcVT, Src, MaskValue);
  };

  // For sub-128-bit vector, cast to (legal) integer and compare with zero.
  if (VT.getSizeInBits() < 128) {
    EVT IntVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits());
    if (!DAG.getTargetLoweringInfo().isTypeLegal(IntVT))
      return SDValue();
    return DAG.getNode(X86ISD::CMP, DL, MVT::i32,
                       DAG.getBitcast(IntVT, MaskBits(V)),
                       DAG.getConstant(0, DL, IntVT));
  }

  // Quit if not splittable to 128/256-bit vector.
  if (!isPowerOf2_32(VT.getSizeInBits()))
    return SDValue();

  // Split down to 128/256-bit vector.
  unsigned TestSize = Subtarget.hasAVX() ? 256 : 128;
  while (VT.getSizeInBits() > TestSize) {
    auto Split = DAG.SplitVector(V, DL);
    VT = Split.first.getValueType();
    V = DAG.getNode(ISD::OR, DL, VT, Split.first, Split.second);
  }

  bool UsePTEST = Subtarget.hasSSE41();
  if (UsePTEST) {
    MVT TestVT = VT.is128BitVector() ? MVT::v2i64 : MVT::v4i64;
    V = DAG.getBitcast(TestVT, MaskBits(V));
    return DAG.getNode(X86ISD::PTEST, DL, MVT::i32, V, V);
  }

  // Without PTEST, a masked v2i64 or-reduction is not faster than
  // scalarization.
  if (!Mask.isAllOnesValue() && VT.getScalarSizeInBits() > 32)
      return SDValue();

  V = DAG.getBitcast(MVT::v16i8, MaskBits(V));
  V = DAG.getNode(X86ISD::PCMPEQ, DL, MVT::v16i8, V,
                  getZeroVector(MVT::v16i8, Subtarget, DAG, DL));
  V = DAG.getNode(X86ISD::MOVMSK, DL, MVT::i32, V);
  return DAG.getNode(X86ISD::CMP, DL, MVT::i32, V,
                     DAG.getConstant(0xFFFF, DL, MVT::i32));
}

// Check whether an OR'd reduction tree is PTEST-able, or if we can fallback to
// CMP(MOVMSK(PCMPEQB(X,0))).
static SDValue MatchVectorAllZeroTest(SDValue Op, ISD::CondCode CC,
                                      const SDLoc &DL,
                                      const X86Subtarget &Subtarget,
                                      SelectionDAG &DAG, SDValue &X86CC) {
  assert((CC == ISD::SETEQ || CC == ISD::SETNE) && "Unsupported ISD::CondCode");

  if (!Subtarget.hasSSE2() || !Op->hasOneUse())
    return SDValue();

  // Check whether we're masking/truncating an OR-reduction result, in which
  // case track the masked bits.
  APInt Mask = APInt::getAllOnesValue(Op.getScalarValueSizeInBits());
  switch (Op.getOpcode()) {
  case ISD::TRUNCATE: {
    SDValue Src = Op.getOperand(0);
    Mask = APInt::getLowBitsSet(Src.getScalarValueSizeInBits(),
                                Op.getScalarValueSizeInBits());
    Op = Src;
    break;
  }
  case ISD::AND: {
    if (auto *Cst = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
      Mask = Cst->getAPIntValue();
      Op = Op.getOperand(0);
    }
    break;
  }
  }

  SmallVector<SDValue, 8> VecIns;
  if (Op.getOpcode() == ISD::OR && matchScalarReduction(Op, ISD::OR, VecIns)) {
    EVT VT = VecIns[0].getValueType();
    assert(llvm::all_of(VecIns,
                        [VT](SDValue V) { return VT == V.getValueType(); }) &&
           "Reduction source vector mismatch");

    // Quit if less than 128-bits or not splittable to 128/256-bit vector.
    if (VT.getSizeInBits() < 128 || !isPowerOf2_32(VT.getSizeInBits()))
      return SDValue();

    // 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, VT, LHS, RHS));
    }

    X86::CondCode CCode;
    if (SDValue V = LowerVectorAllZero(DL, VecIns.back(), CC, Mask, Subtarget,
                                       DAG, CCode)) {
      X86CC = DAG.getTargetConstant(CCode, DL, MVT::i8);
      return V;
    }
  }

  if (Op.getOpcode() == ISD::EXTRACT_VECTOR_ELT) {
    ISD::NodeType BinOp;
    if (SDValue Match =
            DAG.matchBinOpReduction(Op.getNode(), BinOp, {ISD::OR})) {
      X86::CondCode CCode;
      if (SDValue V =
              LowerVectorAllZero(DL, Match, CC, Mask, Subtarget, DAG, CCode)) {
        X86CC = DAG.getTargetConstant(CCode, DL, MVT::i8);
        return V;
      }
    }
  }

  return SDValue();
}

/// 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 splitIntVSETCC(SDValue Op, SelectionDAG &DAG) {
  EVT VT = Op.getValueType();

  assert(Op.getOpcode() == ISD::SETCC && "Unsupported operation");
  assert(Op.getOperand(0).getValueType().isInteger() &&
         VT == Op.getOperand(0).getValueType() && "Unsupported VTs!");

  SDLoc dl(Op);
  SDValue CC = Op.getOperand(2);

  // Extract the LHS Lo/Hi vectors
  SDValue LHS1, LHS2;
  std::tie(LHS1, LHS2) = splitVector(Op.getOperand(0), DAG, dl);

  // Extract the RHS Lo/Hi vectors
  SDValue RHS1, RHS2;
  std::tie(RHS1, RHS2) = splitVector(Op.getOperand(1), DAG, dl);

  // Issue the operation on the smaller types and concatenate the result back
  EVT LoVT, HiVT;
  std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
  return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT,
                     DAG.getNode(ISD::SETCC, dl, LoVT, LHS1, RHS1, CC),
                     DAG.getNode(ISD::SETCC, dl, HiVT, 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.getFixedSizeInBits() >
        Op.getSimpleValueType().getFixedSizeInBits()) {
      // 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 splitIntVSETCC(Op, DAG);

  if (VT == MVT::v32i16 || VT == MVT::v64i8) {
    assert(!Subtarget.hasBWI() && "Unexpected VT with AVX512BW!");
    return splitIntVSETCC(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 (FlipSigns)
    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/PMOVMSKB 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 (isNullConstant(Op1) && (CC == ISD::SETEQ || CC == ISD::SETNE))
    if (SDValue CmpZ =
            MatchVectorAllZeroTest(Op0, CC, dl, Subtarget, DAG, X86CC))
      return CmpZ;

  // 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);
    SDValue CmpOp0 = Cmp.getOperand(0);
    unsigned CondCode = Cond.getConstantOperandVal(0);

    // Special handling for __builtin_ffs(X) - 1 pattern which looks like
    // (select (seteq X, 0), -1, (cttz_zero_undef X)). Disable the special
    // handle to keep the CMP with 0. This should be removed by
    // optimizeCompareInst by using the flags from the BSR/TZCNT used for the
    // cttz_zero_undef.
    auto MatchFFSMinus1 = [&](SDValue Op1, SDValue Op2) {
      return (Op1.getOpcode() == ISD::CTTZ_ZERO_UNDEF && Op1.hasOneUse() &&
              Op1.getOperand(0) == CmpOp0 && isAllOnesConstant(Op2));
    };
    if (Subtarget.hasCMov() && (VT == MVT::i32 || VT == MVT::i64) &&
        ((CondCode == X86::COND_NE && MatchFFSMinus1(Op1, Op2)) ||
         (CondCode == X86::COND_E && MatchFFSMinus1(Op2, Op1)))) {
      // Keep Cmp.
    } else if ((isAllOnesConstant(Op1) || isAllOnesConstant(Op2)) &&
        (CondCode == X86::COND_E || CondCode == X86::COND_NE)) {
      SDValue Y = isAllOnesConstant(Op2) ? Op1 : Op2;

      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 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() &&
        // Exclude 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.getFixedSizeInBits() > InSVT.getFixedSizeInBits());

  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");

  if (VT == MVT::v32i16 && !Subtarget.hasBWI()) {
    assert(InVT == MVT::v32i8 && "Unexpected VT!");
    return splitVectorIntUnary(Op, DAG);
  }

  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();

  SDLoc DL(Store);
  SDValue Value0, Value1;
  std::tie(Value0, Value1) = splitVector(StoredVal, DAG, DL);
  unsigned HalfOffset = Value0.getValueType().getStoreSize();
  SDValue Ptr0 = Store->getBasePtr();
  SDValue Ptr1 =
      DAG.getMemBasePlusOffset(Ptr0, TypeSize::Fixed(HalfOffset), DL);
  SDValue Ch0 =
      DAG.getStore(Store->getChain(), DL, Value0, Ptr0, Store->getPointerInfo(),
                   Store->getOriginalAlign(),
                   Store->getMemOperand()->getFlags());
  SDValue Ch1 = DAG.getStore(Store->getChain(), DL, Value1, Ptr1,
                             Store->getPointerInfo().getWithOffset(HalfOffset),
                             Store->getOriginalAlign(),
                             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();

  SDLoc DL(Store);
  SmallVector<SDValue, 4> Stores;
  for (unsigned i = 0; i != NumElems; ++i) {
    unsigned Offset = i * ScalarSize;
    SDValue Ptr = DAG.getMemBasePlusOffset(Store->getBasePtr(),
                                           TypeSize::Fixed(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),
                              Store->getOriginalAlign(),
                              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) {
    unsigned NumElts = StoredVal.getValueType().getVectorNumElements();
    assert(NumElts <= 8 && "Unexpected VT");
    assert(!St->isTruncatingStore() && "Expected non-truncating store");
    assert(Subtarget.hasAVX512() && !Subtarget.hasDQI() &&
           "Expected AVX512F without AVX512DQI");

    // We must pad with zeros to ensure we store zeroes to any unused bits.
    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);
    // Make sure we store zeros in the extra bits.
    if (NumElts < 8)
      StoredVal = DAG.getZeroExtendInReg(
          StoredVal, dl, EVT::getIntegerVT(*DAG.getContext(), NumElts));

    return DAG.getStore(St->getChain(), dl, StoredVal, St->getBasePtr(),
                        St->getPointerInfo(), St->getOriginalAlign(),
                        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() ||
      ((StoreVT == MVT::v32i16 || StoreVT == MVT::v64i8) &&
       !Subtarget.hasBWI())) {
    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->getOriginalAlign(),
                        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->getOriginalAlign(),
                                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();
    Register 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, TypeSize::Fixed(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;

  // 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.
  assert(ArgVT != MVT::f80 && "va_arg for f80 not yet implemented");
  if (ArgVT.isFloatingPoint() && ArgSize <= 16 /*bytes*/) {
    ArgMode = 2;  // Argument passed in XMM register. Use fp_offset.
  } else {
    assert(ArgVT.isInteger() && ArgSize <= 32 /*bytes*/ &&
           "Unhandled argument type in LowerVAARG");
    ArgMode = 1;  // Argument passed in GPR64 register(s). Use gp_offset.
  }

  if (ArgMode == 2) {
    // Sanity Check: Make sure using fp_offset makes sense.
    assert(!Subtarget.useSoftFloat() &&
           !(MF.getFunction().hasFnAttribute(Attribute::NoImplicitFloat)) &&
           Subtarget.hasSSE1());
  }

  // Insert VAARG node into the DAG
  // VAARG returns two values: Variable Argument Address, Chain
  SDValue InstOps[] = {Chain, SrcPtr,
                       DAG.getTargetConstant(ArgSize, dl, MVT::i32),
                       DAG.getTargetConstant(ArgMode, dl, MVT::i8),
                       DAG.getTargetConstant(Align, dl, MVT::i32)};
  SDVTList VTs = DAG.getVTList(getPointerTy(DAG.getDataLayout()), MVT::Other);
  SDValue VAARG = DAG.getMemIntrinsicNode(
      Subtarget.isTarget64BitLP64() ? X86ISD::VAARG_64 : X86ISD::VAARG_X32, dl,
      VTs, InstOps, MVT::i64, MachinePointerInfo(SV),
      /*Alignment=*/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(Subtarget.isTarget64BitLP64() ? 24 : 16, DL),
      Align(Subtarget.isTarget64BitLP64() ? 8 : 4), /*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()) {
          // Must produce 0s in the correct bits.
          Elts.push_back(DAG.getConstant(0, dl, ElementType));
          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()) {
          // Must produce 0s in the correct bits.
          Elts.push_back(DAG.getConstant(0, dl, ElementType));
          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()) {
          // All shifted in bits must be the same so use 0.
          Elts.push_back(DAG.getConstant(0, dl, ElementType));
          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);

      if (IntrData->Type == INTR_TYPE_3OP_IMM8 &&
          Src3.getValueType() != MVT::i8) {
        Src3 = DAG.getTargetConstant(
            cast<ConstantSDNode>(Src3)->getZExtValue() & 0xff, dl, MVT::i8);
      }

      // 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_IMM8: {
      assert(Op.getOperand(4)->getOpcode() == ISD::TargetConstant);
      SDValue Src4 = Op.getOperand(4);
      if (Src4.getValueType() != MVT::i8) {
        Src4 = DAG.getTargetConstant(
            cast<ConstantSDNode>(Src4)->getZExtValue() & 0xff, dl, MVT::i8);
      }

      return DAG.getNode(IntrData->Opc0, dl, Op.getValueType(),
                         Op.getOperand(1), Op.getOperand(2), Op.getOperand(3),
                         Src4);
    }
    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);
      SDValue Mask = Op.getOperand(4);
      // 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(5);
        if (isRoundModeSAE(Sae))
          return DAG.getNode(IntrData->Opc1, dl, MaskVT, Op.getOperand(1),
                             Op.getOperand(2), CC, Mask, Sae);
        if (!isRoundModeCurDirection(Sae))
          return SDValue();
      }
      //default rounding mode
      return DAG.getNode(IntrData->Opc0, dl, MaskVT,
                         {Op.getOperand(1), Op.getOperand(2), CC, Mask});
    }
    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::BEXTRI && "Unexpected opcode");

      uint64_t Imm = Op.getConstantOperandVal(2);
      SDValue Control = DAG.getTargetConstant(Imm & 0xffff, 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);
      if (ShiftAmount == 0)
        return Op.getOperand(1);

      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.getTargetConstant(NewIntrinsic, DL,
                                             getPointerTy(DAG.getDataLayout())),
                       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));
    }
    case Intrinsic::x86_aesenc128kl:
    case Intrinsic::x86_aesdec128kl:
    case Intrinsic::x86_aesenc256kl:
    case Intrinsic::x86_aesdec256kl: {
      SDLoc DL(Op);
      SDVTList VTs = DAG.getVTList(MVT::v2i64, MVT::i32, MVT::Other);
      SDValue Chain = Op.getOperand(0);
      unsigned Opcode;

      switch (IntNo) {
      default: llvm_unreachable("Impossible intrinsic");
      case Intrinsic::x86_aesenc128kl:
        Opcode = X86ISD::AESENC128KL;
        break;
      case Intrinsic::x86_aesdec128kl:
        Opcode = X86ISD::AESDEC128KL;
        break;
      case Intrinsic::x86_aesenc256kl:
        Opcode = X86ISD::AESENC256KL;
        break;
      case Intrinsic::x86_aesdec256kl:
        Opcode = X86ISD::AESDEC256KL;
        break;
      }

      MemIntrinsicSDNode *MemIntr = cast<MemIntrinsicSDNode>(Op);
      MachineMemOperand *MMO = MemIntr->getMemOperand();
      EVT MemVT = MemIntr->getMemoryVT();
      SDValue Operation = DAG.getMemIntrinsicNode(
          Opcode, DL, VTs, {Chain, Op.getOperand(2), Op.getOperand(3)}, MemVT,
          MMO);
      SDValue ZF = getSETCC(X86::COND_E, Operation.getValue(1), DL, DAG);

      return DAG.getNode(ISD::MERGE_VALUES, DL, Op->getVTList(),
                         {ZF, Operation.getValue(0), Operation.getValue(2)});
    }
    case Intrinsic::x86_aesencwide128kl:
    case Intrinsic::x86_aesdecwide128kl:
    case Intrinsic::x86_aesencwide256kl:
    case Intrinsic::x86_aesdecwide256kl: {
      SDLoc DL(Op);
      SDVTList VTs = DAG.getVTList(
          {MVT::i32, MVT::v2i64, MVT::v2i64, MVT::v2i64, MVT::v2i64, MVT::v2i64,
           MVT::v2i64, MVT::v2i64, MVT::v2i64, MVT::Other});
      SDValue Chain = Op.getOperand(0);
      unsigned Opcode;

      switch (IntNo) {
      default: llvm_unreachable("Impossible intrinsic");
      case Intrinsic::x86_aesencwide128kl:
        Opcode = X86ISD::AESENCWIDE128KL;
        break;
      case Intrinsic::x86_aesdecwide128kl:
        Opcode = X86ISD::AESDECWIDE128KL;
        break;
      case Intrinsic::x86_aesencwide256kl:
        Opcode = X86ISD::AESENCWIDE256KL;
        break;
      case Intrinsic::x86_aesdecwide256kl:
        Opcode = X86ISD::AESDECWIDE256KL;
        break;
      }

      MemIntrinsicSDNode *MemIntr = cast<MemIntrinsicSDNode>(Op);
      MachineMemOperand *MMO = MemIntr->getMemOperand();
      EVT MemVT = MemIntr->getMemoryVT();
      SDValue Operation = DAG.getMemIntrinsicNode(
          Opcode, DL, VTs,
          {Chain, Op.getOperand(2), Op.getOperand(3), Op.getOperand(4),
           Op.getOperand(5), Op.getOperand(6), Op.getOperand(7),
           Op.getOperand(8), Op.getOperand(9), Op.getOperand(10)},
          MemVT, MMO);
      SDValue ZF = getSETCC(X86::COND_E, Operation.getValue(0), DL, DAG);

      return DAG.getNode(ISD::MERGE_VALUES, DL, Op->getVTList(),
                         {ZF, Operation.getValue(1), Operation.getValue(2),
                          Operation.getValue(3), Operation.getValue(4),
                          Operation.getValue(5), Operation.getValue(6),
                          Operation.getValue(7), Operation.getValue(8),
                          Operation.getValue(9)});
    }
    case Intrinsic::x86_testui: {
      SDLoc dl(Op);
      SDValue Chain = Op.getOperand(0);
      SDVTList VTs = DAG.getVTList(MVT::i32, MVT::Other);
      SDValue Operation = DAG.getNode(X86ISD::TESTUI, dl, VTs, Chain);
      SDValue SetCC = getSETCC(X86::COND_B, 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));
}

Register 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;
}

Register 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);
  Register 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), Align(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), Align(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)) {
            const DataLayout &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), Align(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), Align(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), Align(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, Align(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);
}

/// 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 splitVectorIntUnary(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 splitVectorIntUnary(Op, DAG);

  // Decompose 512-bit ops into smaller 256-bit ops.
  if (VT.is512BitVector() && !Subtarget.hasBWI())
    return splitVectorIntUnary(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);
}

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));

  if (VT == MVT::v32i16 || VT == MVT::v64i8)
    return splitVectorIntBinary(Op, DAG);

  assert(Op.getSimpleValueType().is256BitVector() &&
         Op.getSimpleValueType().isInteger() &&
         "Only handle AVX 256-bit vector integer operation");
  return splitVectorIntBinary(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();
  SDLoc DL(Op);

  if (VT.getScalarType() == MVT::i1) {
    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 == MVT::v32i16 || VT == MVT::v64i8 ||
      (VT.is256BitVector() && !Subtarget.hasInt256())) {
    assert(Op.getSimpleValueType().isInteger() &&
           "Only handle AVX vector integer operation");
    return splitVectorIntBinary(Op, DAG);
  }

  // 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);

  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);
    // TODO: Move this to DAGCombiner?
    if (SetCCResultType == VT &&
        DAG.ComputeNumSignBits(Cmp) == VT.getScalarSizeInBits())
      return DAG.getNode(ISD::AND, DL, VT, Cmp, Sub);
    return DAG.getSelect(DL, VT, Cmp, Sub, DAG.getConstant(0, DL, VT));
  }

  // Use default expansion.
  return SDValue();
}

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 splitVectorIntUnary(Op, DAG);
  }

  if ((VT == MVT::v32i16 || VT == MVT::v64i8) && !Subtarget.hasBWI())
    return splitVectorIntUnary(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 splitVectorIntBinary(Op, DAG);

  if (VT == MVT::v32i16 || VT == MVT::v64i8)
    return splitVectorIntBinary(Op, DAG);

  // Default to expand.
  return SDValue();
}

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 splitVectorIntBinary(Op, DAG);

  if ((VT == MVT::v32i16 || VT == MVT::v64i8) && !Subtarget.hasBWI())
    return splitVectorIntBinary(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 splitVectorIntBinary(Op, DAG);

  if ((VT == MVT::v32i16 || VT == MVT::v64i8) && !Subtarget.hasBWI())
    return splitVectorIntBinary(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 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;
  }

  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, Align(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) ||
      (Subtarget.hasBWI() && 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.
      APInt Mask = APInt::getLowBitsSet(8, 8 - ShiftAmt);
      return DAG.getNode(ISD::AND, dl, VT, SRL, DAG.getConstant(Mask, 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.hasVBMI2() && VT == MVT::v32i16) ||
        (!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::v32i8 && Subtarget.hasInt256()) ||
       (VT == MVT::v64i8 && Subtarget.hasBWI())) &&
      !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 can use 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.getNode(X86ISD::BLENDV, 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 can use 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.getNode(X86ISD::BLENDV, 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 splitVectorIntBinary(Op, DAG);

  if (VT == MVT::v32i16 || VT == MVT::v64i8)
    return splitVectorIntBinary(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;
  }

  // AVX512 VBMI2 vXi16 - lower to funnel shifts.
  if (Subtarget.hasVBMI2() && 16 == EltSizeInBits) {
    unsigned FunnelOpc = (Opcode == ISD::ROTL ? ISD::FSHL : ISD::FSHR);
    return DAG.getNode(FunnelOpc, DL, VT, R, R, Amt);
  }

  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 splitVectorIntBinary(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 splitVectorIntBinary(Op, DAG);

  assert((VT == MVT::v4i32 || VT == MVT::v8i16 || VT == MVT::v16i8 ||
          ((VT == MVT::v8i32 || VT == MVT::v16i16 || VT == MVT::v32i8 ||
            VT == MVT::v32i16) &&
           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 can use 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.getNode(X86ISD::BLENDV, 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,
                                 const 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);
  }

  // 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 splitVectorIntUnary(Op, DAG);

  // Decompose 512-bit ops into smaller 256-bit ops.
  if (VT.is512BitVector() && !Subtarget.hasBWI())
    return splitVectorIntUnary(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 splitVectorIntUnary(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);

  assert(VT.getScalarType() == MVT::i8 &&
         "Only byte vector BITREVERSE supported");

  // Split v64i8 without BWI so that we can still use the PSHUFB lowering.
  if (VT == MVT::v64i8 && !Subtarget.hasBWI())
    return splitVectorIntUnary(Op, DAG);

  // Decompose 256-bit ops into smaller 128-bit ops on pre-AVX2.
  if (VT == MVT::v32i8 && !Subtarget.hasInt256())
    return splitVectorIntUnary(Op, DAG);

  unsigned NumElts = VT.getVectorNumElements();

  // If we have GFNI, we can use GF2P8AFFINEQB to reverse the bits.
  if (Subtarget.hasGFNI()) {
    MVT MatrixVT = MVT::getVectorVT(MVT::i64, NumElts / 8);
    SDValue Matrix = DAG.getConstant(0x8040201008040201ULL, DL, MatrixVT);
    Matrix = DAG.getBitcast(VT, Matrix);
    return DAG.getNode(X86ISD::GF2P8AFFINEQB, DL, VT, In, Matrix,
                       DAG.getTargetConstant(0, DL, MVT::i8));
  }

  // 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 LowerPARITY(SDValue Op, const X86Subtarget &Subtarget,
                           SelectionDAG &DAG) {
  SDLoc DL(Op);
  SDValue X = Op.getOperand(0);
  MVT VT = Op.getSimpleValueType();

  // Special case. If the input fits in 8-bits we can use a single 8-bit TEST.
  if (VT == MVT::i8 ||
      DAG.MaskedValueIsZero(X, APInt::getBitsSetFrom(VT.getSizeInBits(), 8))) {
    X = DAG.getNode(ISD::TRUNCATE, DL, MVT::i8, X);
    SDValue Flags = DAG.getNode(X86ISD::CMP, DL, MVT::i32, X,
                                DAG.getConstant(0, DL, MVT::i8));
    // Copy the inverse of the parity flag into a register with setcc.
    SDValue Setnp = getSETCC(X86::COND_NP, Flags, DL, DAG);
    // Extend to the original type.
    return DAG.getNode(ISD::ZERO_EXTEND, DL, VT, Setnp);
  }

  if (VT == MVT::i64) {
    // Xor the high and low 16-bits together using a 32-bit operation.
    SDValue Hi = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32,
                             DAG.getNode(ISD::SRL, DL, MVT::i64, 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);
  }

  if (VT != MVT::i16) {
    // Xor the high and low 16-bits together using a 32-bit operation.
    SDValue Hi16 = DAG.getNode(ISD::SRL, DL, MVT::i32, X,
                               DAG.getConstant(16, DL, MVT::i8));
    X = DAG.getNode(ISD::XOR, DL, MVT::i32, X, Hi16);
  } else {
    // If the input is 16-bits, we need to extend to use an i32 shift below.
    X = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i32, X);
  }

  // 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.
  SDValue Hi = DAG.getNode(
      ISD::TRUNCATE, DL, MVT::i8,
      DAG.getNode(ISD::SRL, DL, MVT::i32, 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);
  // Extend to the original type.
  return DAG.getNode(ISD::ZERO_EXTEND, DL, VT, Setnp);
}

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, MaybeAlign(), 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);
  unsigned Opc = Op.getOpcode();

  // 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));

  bool IsAdd = Opc == ISD::ADDCARRY || Opc == ISD::SADDO_CARRY;
  SDValue Sum = DAG.getNode(IsAdd ? X86ISD::ADC : X86ISD::SBB, DL, VTs,
                            Op.getOperand(0), Op.getOperand(1),
                            Carry.getValue(1));

  bool IsSigned = Opc == ISD::SADDO_CARRY || Opc == ISD::SSUBO_CARRY;
  SDValue SetCC = getSETCC(IsSigned ? X86::COND_O : 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 *)FixedVectorType::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, VT, 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 Extract =
      DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT, NewLoad.getValue(0),
                  DAG.getIntPtrConstant(0, dl));
  SDValue RetOps[] = {Extract, 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;
}

// 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::PARITY:             return LowerPARITY(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_TO_SINT_SAT:
  case ISD::FP_TO_UINT_SAT:     return LowerFP_TO_INT_SAT(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::SADDO_CARRY:
  case ISD::SSUBO_CARRY:
  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);
  }
}

/// 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 X86ISD::CVTPS2PH:
    Results.push_back(LowerCVTPS2PH(SDValue(N, 0), DAG));
    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;
  }
  // 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;
    }

    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 = getEXTEND_VECTOR_INREG(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 = getEXTEND_VECTOR_INREG(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));

    // In 64-bit mode we might need the base pointer in RBX, but we can't know
    // until later. So we keep the RBX input in a vreg and use a custom
    // inserter.
    // 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.
    SDValue Result;
    SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Glue);
    MachineMemOperand *MMO = cast<AtomicSDNode>(N)->getMemOperand();
    if (Regs64bit) {
      SDValue Ops[] = {swapInH.getValue(0), N->getOperand(1), swapInL,
                       swapInH.getValue(1)};
      Result =
          DAG.getMemIntrinsicNode(X86ISD::LCMPXCHG16_DAG, dl, Tys, Ops, T, MMO);
    } else {
      swapInL = DAG.getCopyToReg(swapInH.getValue(0), dl, X86::EBX, swapInL,
                                 swapInH.getValue(1));
      SDValue Ops[] = {swapInL.getValue(0), N->getOperand(1),
                       swapInL.getValue(1)};
      Result =
          DAG.getMemIntrinsicNode(X86ISD::LCMPXCHG8_DAG, 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;
    }

    if (DstVT.isVector() && SrcVT == MVT::x86mmx) {
      // FIXME: Use v4f32 for SSE1?
      assert(Subtarget.hasSSE2() && "Requires SSE2");
      assert(getTypeAction(*DAG.getContext(), DstVT) == TypeWidenVector &&
             "Unexpected type action!");
      EVT WideVT = getTypeToTransformTo(*DAG.getContext(), DstVT);
      SDValue Res = DAG.getNode(X86ISD::MOVQ2DQ, dl, MVT::v2i64,
                                N->getOperand(0));
      Res = DAG.getBitcast(WideVT, Res);
      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->getOriginalAlign(),
                                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 V = LowerADDRSPACECAST(SDValue(N,0), DAG);
    Results.push_back(V);
    return;
  }
  case ISD::BITREVERSE:
    assert(N->getValueType(0) == MVT::i64 && "Unexpected VT!");
    assert(Subtarget.hasXOP() && "Expected XOP");
    // We can use VPPERM by copying to a vector register and back. We'll need
    // to move the scalar in two i32 pieces.
    Results.push_back(LowerBITREVERSE(SDValue(N, 0), Subtarget, DAG));
    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(CMPMM)
  NODE_NAME_CASE(STRICT_CMPM)
  NODE_NAME_CASE(CMPMM_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(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(BEXTRI)
  NODE_NAME_CASE(BZHI)
  NODE_NAME_CASE(PDEP)
  NODE_NAME_CASE(PEXT)
  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_LOAD)
  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(VAARG_X32)
  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)
  NODE_NAME_CASE(AESENC128KL)
  NODE_NAME_CASE(AESDEC128KL)
  NODE_NAME_CASE(AESENC256KL)
  NODE_NAME_CASE(AESDEC256KL)
  NODE_NAME_CASE(AESENCWIDE128KL)
  NODE_NAME_CASE(AESDECWIDE128KL)
  NODE_NAME_CASE(AESENCWIDE256KL)
  NODE_NAME_CASE(AESDECWIDE256KL)
  NODE_NAME_CASE(TESTUI)
  }
  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.
  // Splitting for v32i8/v16i16 on XOP+AVX2 targets is still preferred.
  if (Subtarget.hasXOP() &&
      (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.isScalarInteger() || !VT2.isScalarInteger())
    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::shouldSinkOperands(Instruction *I,
                                           SmallVectorImpl<Use *> &Ops) const {
  // A uniform shift amount in a vector shift or funnel shift may be much
  // cheaper than a generic variable vector shift, so make that pattern visible
  // to SDAG by sinking the shuffle instruction next to the shift.
  int ShiftAmountOpNum = -1;
  if (I->isShift())
    ShiftAmountOpNum = 1;
  else if (auto *II = dyn_cast<IntrinsicInst>(I)) {
    if (II->getIntrinsicID() == Intrinsic::fshl ||
        II->getIntrinsicID() == Intrinsic::fshr)
      ShiftAmountOpNum = 2;
  }

  if (ShiftAmountOpNum == -1)
    return false;

  auto *Shuf = dyn_cast<ShuffleVectorInst>(I->getOperand(ShiftAmountOpNum));
  if (Shuf && getSplatIndex(Shuf->getShuffleMask()) >= 0 &&
      isVectorShiftByScalarCheap(I->getType())) {
    Ops.push_back(&I->getOperandUse(ShiftAmountOpNum));
    return true;
  }

  return false;
}

bool X86TargetLowering::shouldConvertPhiType(Type *From, Type *To) const {
  if (!Subtarget.is64Bit())
    return false;
  return TargetLowering::shouldConvertPhiType(From, To);
}

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
//===----------------------------------------------------------------------===//

// Returns true if EFLAG is consumed after this iterator in the rest of the
// basic block or any successors of the basic block.
static bool isEFLAGSLiveAfter(MachineBasicBlock::iterator Itr,
                              MachineBasicBlock *BB) {
  // Scan forward through BB for a use/def of EFLAGS.
  for (MachineBasicBlock::iterator miI = std::next(Itr), miE = BB->end();
         miI != miE; ++miI) {
    const MachineInstr& mi = *miI;
    if (mi.readsRegister(X86::EFLAGS))
      return true;
    // If we found a def, we can stop searching.
    if (mi.definesRegister(X86::EFLAGS))
      return false;
  }

  // If we hit the end of the block, check whether EFLAGS is live into a
  // successor.
  for (MachineBasicBlock::succ_iterator sItr = BB->succ_begin(),
                                        sEnd = BB->succ_end();
       sItr != sEnd; ++sItr) {
    MachineBasicBlock* succ = *sItr;
    if (succ->isLiveIn(X86::EFLAGS))
      return true;
  }

  return false;
}

/// Utility function to emit xbegin specifying the start of an RTM region.
static MachineBasicBlock *emitXBegin(MachineInstr &MI, MachineBasicBlock *MBB,
                                     const TargetInstrInfo *TII) {
  const 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);

  if (isEFLAGSLiveAfter(MI, MBB)) {
    mainMBB->addLiveIn(X86::EFLAGS);
    fallMBB->addLiveIn(X86::EFLAGS);
    sinkMBB->addLiveIn(X86::EFLAGS);
  }

  // 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::EmitVAARGWithCustomInserter(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 should have 10 operands!");
  static_assert(X86::AddrNumOperands == 5, "VAARG 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();
  Align Alignment = Align(MI.getOperand(8).getImm());

  MachineFunction *MF = MBB->getParent();

  // Memory Reference
  assert(MI.hasOneMemOperand() && "Expected VAARG 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(getPointerTy(MBB->getParent()->getDataLayout()));
  const TargetRegisterClass *OffsetRegClass = getRegClassFor(MVT::i32);
  const 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 = (Alignment > 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(Subtarget.isTarget64BitLP64() ? X86::MOV64rm : X86::MOV32rm),
        RegSaveReg)
        .add(Base)
        .add(Scale)
        .add(Index)
        .addDisp(Disp, Subtarget.isTarget64BitLP64() ? 16 : 12)
        .add(Segment)
        .setMemRefs(LoadOnlyMMO);

    if (Subtarget.isTarget64BitLP64()) {
      // 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);
    } else {
      // Add the offset to the reg_save_area to get the final address.
      BuildMI(offsetMBB, DL, TII->get(X86::ADD32rr), OffsetDestReg)
          .addReg(OffsetReg)
          .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(Subtarget.isTarget64BitLP64() ? X86::MOV64rm : X86::MOV32rm),
          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
    Register TmpReg = MRI.createVirtualRegister(AddrRegClass);

    // aligned_addr = (addr + (align-1)) & ~(align-1)
    BuildMI(
        overflowMBB, DL,
        TII->get(Subtarget.isTarget64BitLP64() ? X86::ADD64ri32 : X86::ADD32ri),
        TmpReg)
        .addReg(OverflowAddrReg)
        .addImm(Alignment.value() - 1);

    BuildMI(
        overflowMBB, DL,
        TII->get(Subtarget.isTarget64BitLP64() ? X86::AND64ri32 : X86::AND32ri),
        OverflowDestReg)
        .addReg(TmpReg)
        .addImm(~(uint64_t)(Alignment.value() - 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(Subtarget.isTarget64BitLP64() ? X86::ADD64ri32 : X86::ADD32ri),
      NextAddrReg)
      .addReg(OverflowDestReg)
      .addImm(ArgSizeA8);

  // Store the new overflow address.
  BuildMI(overflowMBB, DL,
          TII->get(Subtarget.isTarget64BitLP64() ? X86::MOV64mr : X86::MOV32mr))
      .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();
  const DebugLoc &DL = MI.getDebugLoc();

  Register CountReg = MI.getOperand(0).getReg();
  int 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) {
  if (isEFLAGSLiveAfter(SelectItr, BB))
    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();
  const 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 = next_nodbg(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;
}

static unsigned getSUBriOpcode(bool IsLP64, int64_t Imm) {
  if (IsLP64) {
    if (isInt<8>(Imm))
      return X86::SUB64ri8;
    return X86::SUB64ri32;
  } else {
    if (isInt<8>(Imm))
      return X86::SUB32ri8;
    return X86::SUB32ri;
  }
}

MachineBasicBlock *
X86TargetLowering::EmitLoweredProbedAlloca(MachineInstr &MI,
                                           MachineBasicBlock *MBB) const {
  MachineFunction *MF = MBB->getParent();
  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
  const X86FrameLowering &TFI = *Subtarget.getFrameLowering();
  const DebugLoc &DL = MI.getDebugLoc();
  const BasicBlock *LLVM_BB = MBB->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 = ++MBB->getIterator();
  MF->insert(MBBIter, testMBB);
  MF->insert(MBBIter, blockMBB);
  MF->insert(MBBIter, tailMBB);

  Register sizeVReg = MI.getOperand(1).getReg();

  Register physSPReg = TFI.Uses64BitFramePtr ? X86::RSP : X86::ESP;

  Register TmpStackPtr = MRI.createVirtualRegister(
      TFI.Uses64BitFramePtr ? &X86::GR64RegClass : &X86::GR32RegClass);
  Register FinalStackPtr = MRI.createVirtualRegister(
      TFI.Uses64BitFramePtr ? &X86::GR64RegClass : &X86::GR32RegClass);

  BuildMI(*MBB, {MI}, DL, TII->get(TargetOpcode::COPY), TmpStackPtr)
      .addReg(physSPReg);
  {
    const unsigned Opc = TFI.Uses64BitFramePtr ? X86::SUB64rr : X86::SUB32rr;
    BuildMI(*MBB, {MI}, DL, TII->get(Opc), FinalStackPtr)
        .addReg(TmpStackPtr)
        .addReg(sizeVReg);
  }

  // test rsp size

  BuildMI(testMBB, DL,
          TII->get(TFI.Uses64BitFramePtr ? X86::CMP64rr : X86::CMP32rr))
      .addReg(FinalStackPtr)
      .addReg(physSPReg);

  BuildMI(testMBB, DL, TII->get(X86::JCC_1))
      .addMBB(tailMBB)
      .addImm(X86::COND_GE);
  testMBB->addSuccessor(blockMBB);
  testMBB->addSuccessor(tailMBB);

  // Touch the block then extend it. This is done on the opposite side of
  // static probe where we allocate then touch, to avoid the need of probing the
  // tail of the static alloca. Possible scenarios are:
  //
  //       + ---- <- ------------ <- ------------- <- ------------ +
  //       |                                                       |
  // [free probe] -> [page alloc] -> [alloc probe] -> [tail alloc] + -> [dyn probe] -> [page alloc] -> [dyn probe] -> [tail alloc] +
  //                                                               |                                                               |
  //                                                               + <- ----------- <- ------------ <- ----------- <- ------------ +
  //
  // The property we want to enforce is to never have more than [page alloc] between two probes.

  const unsigned XORMIOpc =
      TFI.Uses64BitFramePtr ? X86::XOR64mi8 : X86::XOR32mi8;
  addRegOffset(BuildMI(blockMBB, DL, TII->get(XORMIOpc)), physSPReg, false, 0)
      .addImm(0);

  BuildMI(blockMBB, DL,
          TII->get(getSUBriOpcode(TFI.Uses64BitFramePtr, ProbeSize)), physSPReg)
      .addReg(physSPReg)
      .addImm(ProbeSize);


  BuildMI(blockMBB, DL, TII->get(X86::JMP_1)).addMBB(testMBB);
  blockMBB->addSuccessor(testMBB);

  // Replace original instruction by the expected stack ptr
  BuildMI(tailMBB, DL, TII->get(TargetOpcode::COPY), MI.getOperand(0).getReg())
      .addReg(FinalStackPtr);

  tailMBB->splice(tailMBB->end(), MBB,
                  std::next(MachineBasicBlock::iterator(MI)), MBB->end());
  tailMBB->transferSuccessorsAndUpdatePHIs(MBB);
  MBB->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();
  const 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()));

  Register 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();
  const 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();
  const 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();
  const 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");
  }

  if (Subtarget.useLVIControlFlowIntegrity()) {
    assert(Subtarget.is64Bit() && "Should not be using a 64-bit thunk!");
    return "__llvm_lvi_thunk_r11";
  }
  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.
  const 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 {
  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 {
  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 {
  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(&X86::GR32RegClass);
  BuildMI(checkSspMBB, DL, TII->get(X86::MOV32r0), ZReg);

  if (PVT == MVT::i64) {
    Register TmpZReg = MRI.createVirtualRegister(PtrRC);
    BuildMI(checkSspMBB, DL, TII->get(X86::SUBREG_TO_REG), TmpZReg)
      .addImm(0)
      .addReg(ZReg)
      .addImm(X86::sub_32bit);
    ZReg = TmpZReg;
  }

  // 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 {
  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();
  Register 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 {
  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 {
  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();
  const DebugLoc &DL = MI.getDebugLoc();

  auto TMMImmToTMMReg = [](unsigned Imm) {
    assert (Imm < 8 && "Illegal tmm index");
    return X86::TMM0 + Imm;
  };
  switch (MI.getOpcode()) {
  default: llvm_unreachable("Unexpected instr type to insert");
  case X86::TLS_addr32:
  case X86::TLS_addr64:
  case X86::TLS_addrX32:
  case X86::TLS_base_addr32:
  case X86::TLS_base_addr64:
  case X86::TLS_base_addrX32:
    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, Align(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, Align(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:
  case X86::VAARG_X32:
    return EmitVAARGWithCustomInserter(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:
  case TargetOpcode::PATCHABLE_TYPED_EVENT_CALL:
    return 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_NO_RBX: {
    const X86RegisterInfo *TRI = Subtarget.getRegisterInfo();
    Register BasePtr = TRI->getBaseRegister();
    if (TRI->hasBasePointer(*MF) &&
        (BasePtr == X86::RBX || BasePtr == X86::EBX)) {
      if (!BB->isLiveIn(BasePtr))
        BB->addLiveIn(BasePtr);
      // Save RBX into a virtual register.
      Register SaveRBX =
          MF->getRegInfo().createVirtualRegister(&X86::GR64RegClass);
      BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), SaveRBX)
          .addReg(X86::RBX);
      Register Dst = MF->getRegInfo().createVirtualRegister(&X86::GR64RegClass);
      MachineInstrBuilder MIB =
          BuildMI(*BB, MI, DL, TII->get(X86::LCMPXCHG16B_SAVE_RBX), Dst);
      for (unsigned Idx = 0; Idx < X86::AddrNumOperands; ++Idx)
        MIB.add(MI.getOperand(Idx));
      MIB.add(MI.getOperand(X86::AddrNumOperands));
      MIB.addReg(SaveRBX);
    } else {
      // Simple case, just copy the virtual register to RBX.
      BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), X86::RBX)
          .add(MI.getOperand(X86::AddrNumOperands));
      MachineInstrBuilder MIB =
          BuildMI(*BB, MI, DL, TII->get(X86::LCMPXCHG16B));
      for (unsigned Idx = 0; Idx < X86::AddrNumOperands; ++Idx)
        MIB.add(MI.getOperand(Idx));
    }
    MI.eraseFromParent();
    return BB;
  }
  case X86::MWAITX: {
    const X86RegisterInfo *TRI = Subtarget.getRegisterInfo();
    Register BasePtr = TRI->getBaseRegister();
    bool IsRBX = (BasePtr == X86::RBX || BasePtr == X86::EBX);
    // If no need to save the base pointer, we generate MWAITXrrr,
    // else we generate pseudo MWAITX_SAVE_RBX.
    if (!IsRBX || !TRI->hasBasePointer(*MF)) {
      BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), X86::ECX)
          .addReg(MI.getOperand(0).getReg());
      BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), X86::EAX)
          .addReg(MI.getOperand(1).getReg());
      BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), X86::EBX)
          .addReg(MI.getOperand(2).getReg());
      BuildMI(*BB, MI, DL, TII->get(X86::MWAITXrrr));
      MI.eraseFromParent();
    } else {
      if (!BB->isLiveIn(BasePtr)) {
        BB->addLiveIn(BasePtr);
      }
      // Parameters can be copied into ECX and EAX but not EBX yet.
      BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), X86::ECX)
          .addReg(MI.getOperand(0).getReg());
      BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), X86::EAX)
          .addReg(MI.getOperand(1).getReg());
      assert(Subtarget.is64Bit() && "Expected 64-bit mode!");
      // Save RBX into a virtual register.
      Register SaveRBX =
          MF->getRegInfo().createVirtualRegister(&X86::GR64RegClass);
      BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), SaveRBX)
          .addReg(X86::RBX);
      // Generate mwaitx pseudo.
      Register Dst = MF->getRegInfo().createVirtualRegister(&X86::GR64RegClass);
      BuildMI(*BB, MI, DL, TII->get(X86::MWAITX_SAVE_RBX))
          .addDef(Dst) // Destination tied in with SaveRBX.
          .addReg(MI.getOperand(2).getReg()) // input value of EBX.
          .addUse(SaveRBX);                  // Save of base pointer.
      MI.eraseFromParent();
    }
    return BB;
  }
  case TargetOpcode::PREALLOCATED_SETUP: {
    assert(Subtarget.is32Bit() && "preallocated only used in 32-bit");
    auto MFI = MF->getInfo<X86MachineFunctionInfo>();
    MFI->setHasPreallocatedCall(true);
    int64_t PreallocatedId = MI.getOperand(0).getImm();
    size_t StackAdjustment = MFI->getPreallocatedStackSize(PreallocatedId);
    assert(StackAdjustment != 0 && "0 stack adjustment");
    LLVM_DEBUG(dbgs() << "PREALLOCATED_SETUP stack adjustment "
                      << StackAdjustment << "\n");
    BuildMI(*BB, MI, DL, TII->get(X86::SUB32ri), X86::ESP)
        .addReg(X86::ESP)
        .addImm(StackAdjustment);
    MI.eraseFromParent();
    return BB;
  }
  case TargetOpcode::PREALLOCATED_ARG: {
    assert(Subtarget.is32Bit() && "preallocated calls only used in 32-bit");
    int64_t PreallocatedId = MI.getOperand(1).getImm();
    int64_t ArgIdx = MI.getOperand(2).getImm();
    auto MFI = MF->getInfo<X86MachineFunctionInfo>();
    size_t ArgOffset = MFI->getPreallocatedArgOffsets(PreallocatedId)[ArgIdx];
    LLVM_DEBUG(dbgs() << "PREALLOCATED_ARG arg index " << ArgIdx
                      << ", arg offset " << ArgOffset << "\n");
    // stack pointer + offset
    addRegOffset(
        BuildMI(*BB, MI, DL, TII->get(X86::LEA32r), MI.getOperand(0).getReg()),
        X86::ESP, false, ArgOffset);
    MI.eraseFromParent();
    return BB;
  }
  case X86::PTDPBSSD:
  case X86::PTDPBSUD:
  case X86::PTDPBUSD:
  case X86::PTDPBUUD:
  case X86::PTDPBF16PS: {
    unsigned Opc;
    switch (MI.getOpcode()) {
    case X86::PTDPBSSD: Opc = X86::TDPBSSD; break;
    case X86::PTDPBSUD: Opc = X86::TDPBSUD; break;
    case X86::PTDPBUSD: Opc = X86::TDPBUSD; break;
    case X86::PTDPBUUD: Opc = X86::TDPBUUD; break;
    case X86::PTDPBF16PS: Opc = X86::TDPBF16PS; break;
    }

    MachineInstrBuilder MIB = BuildMI(*BB, MI, DL, TII->get(Opc));
    MIB.addReg(TMMImmToTMMReg(MI.getOperand(0).getImm()), RegState::Define);
    MIB.addReg(TMMImmToTMMReg(MI.getOperand(0).getImm()), RegState::Undef);
    MIB.addReg(TMMImmToTMMReg(MI.getOperand(1).getImm()), RegState::Undef);
    MIB.addReg(TMMImmToTMMReg(MI.getOperand(2).getImm()), RegState::Undef);

    MI.eraseFromParent(); // The pseudo is gone now.
    return BB;
  }
  case X86::PTILEZERO: {
    unsigned Imm = MI.getOperand(0).getImm();
    BuildMI(*BB, MI, DL, TII->get(X86::TILEZERO), TMMImmToTMMReg(Imm));
    MI.eraseFromParent(); // The pseudo is gone now.
    return BB;
  }
  case X86::PTILELOADD:
  case X86::PTILELOADDT1:
  case X86::PTILESTORED: {
    unsigned Opc;
    switch (MI.getOpcode()) {
    case X86::PTILELOADD:   Opc = X86::TILELOADD;   break;
    case X86::PTILELOADDT1: Opc = X86::TILELOADDT1; break;
    case X86::PTILESTORED:  Opc = X86::TILESTORED;  break;
    }

    MachineInstrBuilder MIB = BuildMI(*BB, MI, DL, TII->get(Opc));
    unsigned CurOp = 0;
    if (Opc != X86::TILESTORED)
      MIB.addReg(TMMImmToTMMReg(MI.getOperand(CurOp++).getImm()),
                 RegState::Define);

    MIB.add(MI.getOperand(CurOp++)); // base
    MIB.add(MI.getOperand(CurOp++)); // scale
    MIB.add(MI.getOperand(CurOp++)); // index -- stride
    MIB.add(MI.getOperand(CurOp++)); // displacement
    MIB.add(MI.getOperand(CurOp++)); // segment

    if (Opc == X86::TILESTORED)
      MIB.addReg(TMMImmToTMMReg(MI.getOperand(CurOp++).getImm()),
                 RegState::Undef);

    MI.eraseFromParent(); // The pseudo is gone now.
    return BB;
  }
  }
}

//===----------------------------------------------------------------------===//
//                           X86 Optimization Hooks
//===----------------------------------------------------------------------===//

bool
X86TargetLowering::targetShrinkDemandedConstant(SDValue Op,
                                                const APInt &DemandedBits,
                                                const APInt &DemandedElts,
                                                TargetLoweringOpt &TLO) const {
  EVT VT = Op.getValueType();
  unsigned Opcode = Op.getOpcode();
  unsigned EltSize = VT.getScalarSizeInBits();

  if (VT.isVector()) {
    // If the constant is only all signbits in the active bits, then we should
    // extend it to the entire constant to allow it act as a boolean constant
    // vector.
    auto NeedsSignExtension = [&](SDValue V, unsigned ActiveBits) {
      if (!ISD::isBuildVectorOfConstantSDNodes(V.getNode()))
        return false;
      for (unsigned i = 0, e = V.getNumOperands(); i != e; ++i) {
        if (!DemandedElts[i] || V.getOperand(i).isUndef())
          continue;
        const APInt &Val = V.getConstantOperandAPInt(i);
        if (Val.getBitWidth() > Val.getNumSignBits() &&
            Val.trunc(ActiveBits).getNumSignBits() == ActiveBits)
          return true;
      }
      return false;
    };
    // For vectors - if we have a constant, then try to sign extend.
    // TODO: Handle AND/ANDN cases.
    unsigned ActiveBits = DemandedBits.getActiveBits();
    if (EltSize > ActiveBits && EltSize > 1 && isTypeLegal(VT) &&
        (Opcode == ISD::OR || Opcode == ISD::XOR) &&
        NeedsSignExtension(Op.getOperand(1), ActiveBits)) {
      EVT ExtSVT = EVT::getIntegerVT(*TLO.DAG.getContext(), ActiveBits);
      EVT ExtVT = EVT::getVectorVT(*TLO.DAG.getContext(), ExtSVT,
                                    VT.getVectorNumElements());
      SDValue NewC =
          TLO.DAG.getNode(ISD::SIGN_EXTEND_INREG, SDLoc(Op), VT,
                          Op.getOperand(1), TLO.DAG.getValueType(ExtVT));
      SDValue NewOp =
          TLO.DAG.getNode(Opcode, SDLoc(Op), VT, Op.getOperand(0), NewC);
      return TLO.CombineTo(Op, NewOp);
    }
    return false;
  }

  // Only optimize Ands to prevent shrinking a constant that could be
  // matched by movzx.
  if (Opcode != ISD::AND)
    return false;

  // 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 & DemandedBits;

  // 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, EltSize);

  // Calculate a possible zero extend mask for this constant.
  APInt ZeroExtendMask = APInt::getLowBitsSet(EltSize, 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 | ~DemandedBits))
    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 NumElts = DemandedElts.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 = KnownBits::commonBits(Known, Known2);
    }
    if (!!DemandedRHS) {
      Known2 = DAG.computeKnownBits(Op.getOperand(1), DemandedRHS, Depth + 1);
      Known = KnownBits::commonBits(Known, Known2);
    }

    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);

    Known |= Known2;
    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 = KnownBits::commonBits(Known, Known2);
    break;
  }
  case X86ISD::BEXTR:
  case X86ISD::BEXTRI: {
    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;
  }
  case X86ISD::PDEP: {
    KnownBits Known2;
    Known = DAG.computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
    Known2 = DAG.computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
    // Zeros are retained from the mask operand. But not ones.
    Known.One.clearAllBits();
    // The result will have at least as many trailing zeros as the non-mask
    // operand since bits can only map to the same or higher bit position.
    Known.Zero.setLowBits(Known2.countMinTrailingZeros());
    break;
  }
  case X86ISD::PEXT: {
    Known = DAG.computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
    // The result has as many leading zeros as the number of zeroes in the mask.
    unsigned Count = Known.Zero.countPopulation();
    Known.Zero = APInt::getHighBitsSet(BitWidth, Count);
    Known.One.clearAllBits();
    break;
  }
  case X86ISD::VTRUNC:
  case X86ISD::VTRUNCS:
  case X86ISD::VTRUNCUS:
  case X86ISD::CVTSI2P:
  case X86ISD::CVTUI2P:
  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::MCVTSI2P:
  case X86ISD::MCVTUI2P:
  case X86ISD::VFPROUND:
  case X86ISD::VMFPROUND:
  case X86ISD::CVTPS2PH:
  case X86ISD::MCVTPS2PH: {
    // Truncations/Conversions - upper elements are known zero.
    EVT SrcVT = Op.getOperand(0).getValueType();
    if (SrcVT.isVector()) {
      unsigned NumSrcElts = SrcVT.getVectorNumElements();
      if (NumElts > NumSrcElts &&
          DemandedElts.countTrailingZeros() >= NumSrcElts)
        Known.setAllZero();
    }
    break;
  }
  case X86ISD::STRICT_CVTTP2SI:
  case X86ISD::STRICT_CVTTP2UI:
  case X86ISD::STRICT_CVTSI2P:
  case X86ISD::STRICT_CVTUI2P:
  case X86ISD::STRICT_VFPROUND:
  case X86ISD::STRICT_CVTPS2PH: {
    // Strict Conversions - upper elements are known zero.
    EVT SrcVT = Op.getOperand(1).getValueType();
    if (SrcVT.isVector()) {
      unsigned NumSrcElts = SrcVT.getVectorNumElements();
      if (NumElts > NumSrcElts &&
          DemandedElts.countTrailingZeros() >= NumSrcElts)
        Known.setAllZero();
    }
    break;
  }
  case X86ISD::MOVQ2DQ: {
    // Move from MMX to XMM. Upper half of XMM should be 0.
    if (DemandedElts.countTrailingZeros() >= (NumElts / 2))
      Known.setAllZero();
    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 = KnownBits::commonBits(Known, Known2);
        }
      }
    }
  }
}

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;
}

// Helper to look for a normal load that can be narrowed into a vzload with the
// specified VT and memory VT. Returns SDValue() on failure.
static SDValue narrowLoadToVZLoad(LoadSDNode *LN, MVT MemVT, MVT VT,
                                  SelectionDAG &DAG) {
  // Can't if the load is volatile or atomic.
  if (!LN->isSimple())
    return SDValue();

  SDVTList Tys = DAG.getVTList(VT, MVT::Other);
  SDValue Ops[] = {LN->getChain(), LN->getBasePtr()};
  return DAG.getMemIntrinsicNode(X86ISD::VZEXT_LOAD, SDLoc(LN), Tys, Ops, MemVT,
                                 LN->getPointerInfo(), LN->getOriginalAlign(),
                                 LN->getMemOperand()->getFlags());
}

// 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 && Mask[0] == 0) {
    if (isUndefOrZero(Mask[1]) && isUndefInRange(Mask, 2, NumMaskElts - 2)) {
      Shuffle = X86ISD::VZEXT_MOVL;
      SrcVT = DstVT = !Subtarget.hasSSE2() ? MVT::v4f32 : MaskVT;
      return true;
    }
    if (V1.getOpcode() == ISD::SCALAR_TO_VECTOR &&
        isUndefOrZeroInRange(Mask, 1, NumMaskElts - 1)) {
      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(MaskVT, Mask, {0, 0}, V1)) {
      Shuffle = X86ISD::MOVDDUP;
      SrcVT = DstVT = MVT::v2f64;
      return true;
    }
    if (isTargetShuffleEquivalent(MaskVT, Mask, {0, 0, 2, 2}, V1)) {
      Shuffle = X86ISD::MOVSLDUP;
      SrcVT = DstVT = MVT::v4f32;
      return true;
    }
    if (isTargetShuffleEquivalent(MaskVT, Mask, {1, 1, 3, 3}, V1)) {
      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(MaskVT, Mask, {0, 0, 2, 2}, V1)) {
      Shuffle = X86ISD::MOVDDUP;
      SrcVT = DstVT = MVT::v4f64;
      return true;
    }
    if (isTargetShuffleEquivalent(MaskVT, Mask, {0, 0, 2, 2, 4, 4, 6, 6}, V1)) {
      Shuffle = X86ISD::MOVSLDUP;
      SrcVT = DstVT = MVT::v8f32;
      return true;
    }
    if (isTargetShuffleEquivalent(MaskVT, Mask, {1, 1, 3, 3, 5, 5, 7, 7}, V1)) {
      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(MaskVT, Mask, {0, 0, 2, 2, 4, 4, 6, 6}, V1)) {
      Shuffle = X86ISD::MOVDDUP;
      SrcVT = DstVT = MVT::v8f64;
      return true;
    }
    if (isTargetShuffleEquivalent(
            MaskVT, Mask,
            {0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14}, V1)) {
      Shuffle = X86ISD::MOVSLDUP;
      SrcVT = DstVT = MVT::v16f32;
      return true;
    }
    if (isTargetShuffleEquivalent(
            MaskVT, Mask,
            {1, 1, 3, 3, 5, 5, 7, 7, 9, 9, 11, 11, 13, 13, 15, 15}, V1)) {
      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 = isAnyZero(Mask);

  // 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)
        narrowShuffleMaskElts(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 &&
      ((MaskVT.is128BitVector() && Subtarget.hasSSE2()) ||
       (MaskVT.is256BitVector() && Subtarget.hasAVX2()) ||
       (MaskVT.is512BitVector() && Subtarget.hasBWI()))) {
    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 NumMaskElts = Mask.size();
  unsigned EltSizeInBits = MaskVT.getScalarSizeInBits();

  if (MaskVT.is128BitVector()) {
    if (isTargetShuffleEquivalent(MaskVT, 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(MaskVT, 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(MaskVT, Mask, {0, 3}) &&
        Subtarget.hasSSE2() && (AllowFloatDomain || !Subtarget.hasSSE41())) {
      std::swap(V1, V2);
      Shuffle = X86ISD::MOVSD;
      SrcVT = DstVT = MVT::v2f64;
      return true;
    }
    if (isTargetShuffleEquivalent(MaskVT, 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;
    }
  }

  // Attempt to match against a OR if we're performing a blend shuffle and the
  // non-blended source element is zero in each case.
  if ((EltSizeInBits % V1.getScalarValueSizeInBits()) == 0 &&
      (EltSizeInBits % V2.getScalarValueSizeInBits()) == 0) {
    bool IsBlend = true;
    unsigned NumV1Elts = V1.getValueType().getVectorNumElements();
    unsigned NumV2Elts = V2.getValueType().getVectorNumElements();
    unsigned Scale1 = NumV1Elts / NumMaskElts;
    unsigned Scale2 = NumV2Elts / NumMaskElts;
    APInt DemandedZeroV1 = APInt::getNullValue(NumV1Elts);
    APInt DemandedZeroV2 = APInt::getNullValue(NumV2Elts);
    for (unsigned i = 0; i != NumMaskElts; ++i) {
      int M = Mask[i];
      if (M == SM_SentinelUndef)
        continue;
      if (M == SM_SentinelZero) {
        DemandedZeroV1.setBits(i * Scale1, (i + 1) * Scale1);
        DemandedZeroV2.setBits(i * Scale2, (i + 1) * Scale2);
        continue;
      }
      if (M == (int)i) {
        DemandedZeroV2.setBits(i * Scale2, (i + 1) * Scale2);
        continue;
      }
      if (M == (int)(i + NumMaskElts)) {
        DemandedZeroV1.setBits(i * Scale1, (i + 1) * Scale1);
        continue;
      }
      IsBlend = false;
      break;
    }
    if (IsBlend &&
        DAG.computeKnownBits(V1, DemandedZeroV1).isZero() &&
        DAG.computeKnownBits(V2, DemandedZeroV2).isZero()) {
      Shuffle = ISD::OR;
      SrcVT = DstVT = MaskVT.changeTypeToInteger();
      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 VALIGND/VALIGNQ rotate.
  if (AllowIntDomain && (EltSizeInBits == 64 || EltSizeInBits == 32) &&
      ((MaskVT.is128BitVector() && Subtarget.hasVLX()) ||
       (MaskVT.is256BitVector() && Subtarget.hasVLX()) ||
       (MaskVT.is512BitVector() && Subtarget.hasAVX512()))) {
    if (!isAnyZero(Mask)) {
      int Rotation = matchShuffleAsElementRotate(V1, V2, Mask);
      if (0 < Rotation) {
        Shuffle = X86ISD::VALIGN;
        if (EltSizeInBits == 64)
          ShuffleVT = MVT::getVectorVT(MVT::i64, MaskVT.getSizeInBits() / 64);
        else
          ShuffleVT = MVT::getVectorVT(MVT::i32, MaskVT.getSizeInBits() / 32);
        PermuteImm = Rotation;
        return true;
      }
    }
  }

  // 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() && isAnyZero(Mask) &&
      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!");

  MVT RootVT = Root.getSimpleValueType();
  unsigned RootSizeInBits = RootVT.getSizeInBits();
  unsigned NumRootElts = RootVT.getVectorNumElements();

  // Canonicalize shuffle input op to the requested type.
  // TODO: Support cases where Op is smaller than VT.
  auto CanonicalizeShuffleInput = [&](MVT VT, SDValue Op) {
    return DAG.getBitcast(VT, Op);
  };

  // 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();
  assert(VT1.getSizeInBits() == RootSizeInBits &&
         VT2.getSizeInBits() == RootSizeInBits && "Vector size mismatch");

  SDLoc DL(Root);
  SDValue Res;

  unsigned NumBaseMaskElts = BaseMask.size();
  if (NumBaseMaskElts == 1) {
    assert(BaseMask[0] == 0 && "Invalid shuffle index found!");
    return CanonicalizeShuffleInput(RootVT, V1);
  }

  bool OptForSize = DAG.shouldOptForSize();
  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.
  bool IsMaskedShuffle = false;
  if (RootSizeInBits == 512 || (Subtarget.hasVLX() && RootSizeInBits >= 128)) {
    if (Root.hasOneUse() && Root->use_begin()->getOpcode() == ISD::VSELECT &&
        Root->use_begin()->getOperand(0).getScalarValueSizeInBits() == 1) {
      IsMaskedShuffle = true;
    }
  }

  // If we are shuffling a broadcast (and not introducing zeros) then
  // we can just use the broadcast directly. This works for smaller broadcast
  // elements as well as they already repeat across each mask element
  if (UnaryShuffle && isTargetShuffleSplat(V1) && !isAnyZero(BaseMask) &&
      (BaseMaskEltSizeInBits % V1.getScalarValueSizeInBits()) == 0 &&
      V1.getValueSizeInBits() >= RootSizeInBits) {
    return CanonicalizeShuffleInput(RootVT, V1);
  }

  // Handle 128/256-bit lane shuffles of 512-bit vectors.
  if (RootVT.is512BitVector() &&
      (NumBaseMaskElts == 2 || NumBaseMaskElts == 4)) {
    // 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 = CanonicalizeShuffleInput(RootVT, V1);
      unsigned SubIdx = BaseMask[0] * (NumRootElts / NumBaseMaskElts);
      bool UseZero = isAnyZero(BaseMask);
      Res = extractSubVector(Res, SubIdx, DAG, DL, BaseMaskEltSizeInBits);
      return widenSubVector(Res, UseZero, Subtarget, DAG, DL, RootSizeInBits);
    }

    // Narrow shuffle mask to v4x128.
    SmallVector<int, 4> Mask;
    assert((BaseMaskEltSizeInBits % 128) == 0 && "Illegal mask size");
    narrowShuffleMaskElts(BaseMaskEltSizeInBits / 128, BaseMask, Mask);

    // Try to lower to vshuf64x2/vshuf32x4.
    auto MatchSHUF128 = [&](MVT ShuffleVT, const SDLoc &DL, ArrayRef<int> Mask,
                            SDValue V1, SDValue V2, SelectionDAG &DAG) {
      unsigned PermMask = 0;
      // Insure elements came from the same Op.
      SDValue Ops[2] = {DAG.getUNDEF(ShuffleVT), DAG.getUNDEF(ShuffleVT)};
      for (int i = 0; i < 4; ++i) {
        assert(Mask[i] >= -1 && "Illegal shuffle sentinel value");
        if (Mask[i] < 0)
          continue;

        SDValue Op = Mask[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 |= (Mask[i] % 4) << (i * 2);
      }

      return DAG.getNode(X86ISD::SHUF128, DL, ShuffleVT,
                         CanonicalizeShuffleInput(ShuffleVT, Ops[0]),
                         CanonicalizeShuffleInput(ShuffleVT, Ops[1]),
                         DAG.getTargetConstant(PermMask, DL, MVT::i8));
    };

    // FIXME: Is there a better way to do this? is256BitLaneRepeatedShuffleMask
    // doesn't work because our mask is for 128 bits and we don't have an MVT
    // to match that.
    bool PreferPERMQ =
        UnaryShuffle && isUndefOrInRange(Mask[0], 0, 2) &&
        isUndefOrInRange(Mask[1], 0, 2) && isUndefOrInRange(Mask[2], 2, 4) &&
        isUndefOrInRange(Mask[3], 2, 4) &&
        (Mask[0] < 0 || Mask[2] < 0 || Mask[0] == (Mask[2] % 2)) &&
        (Mask[1] < 0 || Mask[3] < 0 || Mask[1] == (Mask[3] % 2));

    if (!isAnyZero(Mask) && !PreferPERMQ) {
      if (Depth == 0 && Root.getOpcode() == X86ISD::SHUF128)
        return SDValue(); // Nothing to do!
      MVT ShuffleVT = (FloatDomain ? MVT::v8f64 : MVT::v8i64);
      if (SDValue V = MatchSHUF128(ShuffleVT, DL, Mask, V1, V2, DAG))
        return DAG.getBitcast(RootVT, V);
    }
  }

  // Handle 128-bit lane shuffles of 256-bit vectors.
  if (RootVT.is256BitVector() && NumBaseMaskElts == 2) {
    // 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 = CanonicalizeShuffleInput(RootVT, V1);
      Res = extract128BitVector(Res, BaseMask[0] * (NumRootElts / 2), DAG, DL);
      return widenSubVector(Res, BaseMask[1] == SM_SentinelZero, Subtarget, DAG,
                            DL, 256);
    }

    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.
    // Prefer blends for sequential shuffles unless we are optimizing for size.
    if (UnaryShuffle &&
        !(Subtarget.hasAVX2() && isUndefOrInRange(BaseMask, 0, 2)) &&
        (OptForSize || !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);
      return DAG.getNode(
          X86ISD::VPERM2X128, DL, RootVT, CanonicalizeShuffleInput(RootVT, V1),
          DAG.getUNDEF(RootVT), DAG.getTargetConstant(PermMask, DL, MVT::i8));
    }

    if (Depth == 0 && Root.getOpcode() == X86ISD::SHUF128)
      return SDValue(); // Nothing to do!

    // TODO - handle AVX512VL cases with X86ISD::SHUF128.
    if (!UnaryShuffle && !IsMaskedShuffle) {
      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);
        SDValue LHS = isInRange(BaseMask[0], 0, 2) ? V1 : V2;
        SDValue RHS = isInRange(BaseMask[1], 0, 2) ? V1 : V2;
        return DAG.getNode(X86ISD::VPERM2X128, DL, RootVT,
                          CanonicalizeShuffleInput(RootVT, LHS),
                          CanonicalizeShuffleInput(RootVT, RHS),
                          DAG.getTargetConstant(PermMask, DL, MVT::i8));
      }
    }
  }

  // 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;
    narrowShuffleMaskElts(MaskScale, BaseMask, Mask);
  } else {
    Mask.assign(BaseMask.begin(), BaseMask.end());
  }

  // For masked shuffles, we're trying to match the root width for better
  // writemask folding, attempt to scale the mask.
  // TODO - variable shuffles might need this to be widened again.
  if (IsMaskedShuffle && NumRootElts > Mask.size()) {
    assert((NumRootElts % Mask.size()) == 0 && "Illegal mask size");
    int MaskScale = NumRootElts / Mask.size();
    SmallVector<int, 64> ScaledMask;
    narrowShuffleMaskElts(MaskScale, Mask, ScaledMask);
    Mask = std::move(ScaledMask);
  }

  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) {
    // 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)) &&
        (!IsMaskedShuffle || NumRootElts == NumMaskElts)) {
      if (isUndefOrEqual(Mask, 0)) {
        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 = CanonicalizeShuffleInput(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) &&
        (!IsMaskedShuffle ||
         (NumRootElts == ShuffleVT.getVectorNumElements()))) {
      if (Depth == 0 && Root.getOpcode() == Shuffle)
        return SDValue(); // Nothing to do!
      Res = CanonicalizeShuffleInput(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) &&
        (!IsMaskedShuffle ||
         (NumRootElts == ShuffleVT.getVectorNumElements()))) {
      if (Depth == 0 && Root.getOpcode() == Shuffle)
        return SDValue(); // Nothing to do!
      Res = CanonicalizeShuffleInput(ShuffleVT, V1);
      Res = DAG.getNode(Shuffle, DL, ShuffleVT, Res,
                        DAG.getTargetConstant(PermuteImm, DL, MVT::i8));
      return DAG.getBitcast(RootVT, Res);
    }
  }

  // Attempt to combine to INSERTPS, but only if the inserted element has come
  // from a scalar.
  // TODO: Handle other insertions here as well?
  if (!UnaryShuffle && AllowFloatDomain && RootSizeInBits == 128 &&
      Subtarget.hasSSE41() &&
      !isTargetShuffleEquivalent(MaskVT, Mask, {4, 1, 2, 3})) {
    if (MaskEltSizeInBits == 32) {
      SDValue SrcV1 = V1, SrcV2 = V2;
      if (matchShuffleAsInsertPS(SrcV1, SrcV2, PermuteImm, Zeroable, Mask,
                                 DAG) &&
          SrcV2.getOpcode() == ISD::SCALAR_TO_VECTOR) {
        if (Depth == 0 && Root.getOpcode() == X86ISD::INSERTPS)
          return SDValue(); // Nothing to do!
        Res = DAG.getNode(X86ISD::INSERTPS, DL, MVT::v4f32,
                          CanonicalizeShuffleInput(MVT::v4f32, SrcV1),
                          CanonicalizeShuffleInput(MVT::v4f32, SrcV2),
                          DAG.getTargetConstant(PermuteImm, DL, MVT::i8));
        return DAG.getBitcast(RootVT, Res);
      }
    }
    if (MaskEltSizeInBits == 64 &&
        isTargetShuffleEquivalent(MaskVT, Mask, {0, 2}) &&
        V2.getOpcode() == ISD::SCALAR_TO_VECTOR &&
        V2.getScalarValueSizeInBits() <= 32) {
      if (Depth == 0 && Root.getOpcode() == X86ISD::INSERTPS)
        return SDValue(); // Nothing to do!
      PermuteImm = (/*DstIdx*/2 << 4) | (/*SrcIdx*/0 << 0);
      Res = DAG.getNode(X86ISD::INSERTPS, DL, MVT::v4f32,
                        CanonicalizeShuffleInput(MVT::v4f32, V1),
                        CanonicalizeShuffleInput(MVT::v4f32, V2),
                        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) &&
      (!IsMaskedShuffle || (NumRootElts == ShuffleVT.getVectorNumElements()))) {
    if (Depth == 0 && Root.getOpcode() == Shuffle)
      return SDValue(); // Nothing to do!
    NewV1 = CanonicalizeShuffleInput(ShuffleSrcVT, NewV1);
    NewV2 = CanonicalizeShuffleInput(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) &&
      (!IsMaskedShuffle || (NumRootElts == ShuffleVT.getVectorNumElements()))) {
    if (Depth == 0 && Root.getOpcode() == Shuffle)
      return SDValue(); // Nothing to do!
    NewV1 = CanonicalizeShuffleInput(ShuffleVT, NewV1);
    NewV2 = CanonicalizeShuffleInput(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 = CanonicalizeShuffleInput(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 = CanonicalizeShuffleInput(IntMaskVT, V1);
      V2 = CanonicalizeShuffleInput(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 = CanonicalizeShuffleInput(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 = CanonicalizeShuffleInput(ShuffleSrcVT, V1);
      V2 = CanonicalizeShuffleInput(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;
  // VPERMI2W/VPERMI2B are 3 uops on Skylake and Icelake so we require a
  // higher depth before combining them.
  bool AllowBWIVPERMV3 = (Depth >= 2 || 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) {
      if (Subtarget.hasAVX2() &&
          (MaskVT == MVT::v8f32 || MaskVT == MVT::v8i32)) {
        SDValue VPermMask = getConstVector(Mask, IntMaskVT, DAG, DL, true);
        Res = CanonicalizeShuffleInput(MaskVT, V1);
        Res = DAG.getNode(X86ISD::VPERMV, DL, MaskVT, VPermMask, Res);
        return DAG.getBitcast(RootVT, Res);
      }
      // AVX512 variants (non-VLX will pad to 512-bit shuffles).
      if ((Subtarget.hasAVX512() &&
           (MaskVT == MVT::v8f64 || MaskVT == MVT::v8i64 ||
            MaskVT == MVT::v16f32 || MaskVT == MVT::v16i32)) ||
          (Subtarget.hasBWI() &&
           (MaskVT == MVT::v16i16 || MaskVT == MVT::v32i16)) ||
          (Subtarget.hasVBMI() &&
           (MaskVT == MVT::v32i8 || MaskVT == MVT::v64i8))) {
        V1 = CanonicalizeShuffleInput(MaskVT, V1);
        V2 = DAG.getUNDEF(MaskVT);
        Res = lowerShuffleWithPERMV(DL, MaskVT, Mask, V1, V2, Subtarget, DAG);
        return DAG.getBitcast(RootVT, Res);
      }
    }

    // Lower a unary+zero lane-crossing shuffle as VPERMV3 with a zero
    // vector as the second source (non-VLX will pad to 512-bit shuffles).
    if (UnaryShuffle && AllowVariableMask &&
        ((Subtarget.hasAVX512() &&
          (MaskVT == MVT::v8f64 || MaskVT == MVT::v8i64 ||
           MaskVT == MVT::v4f64 || MaskVT == MVT::v4i64 ||
           MaskVT == MVT::v8f32 || MaskVT == MVT::v8i32 ||
           MaskVT == MVT::v16f32 || MaskVT == MVT::v16i32)) ||
         (Subtarget.hasBWI() && AllowBWIVPERMV3 &&
          (MaskVT == MVT::v16i16 || MaskVT == MVT::v32i16)) ||
         (Subtarget.hasVBMI() && AllowBWIVPERMV3 &&
          (MaskVT == MVT::v32i8 || MaskVT == MVT::v64i8)))) {
      // 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;
      V1 = CanonicalizeShuffleInput(MaskVT, V1);
      V2 = getZeroVector(MaskVT, Subtarget, DAG, DL);
      Res = lowerShuffleWithPERMV(DL, MaskVT, Mask, V1, V2, Subtarget, DAG);
      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,
    // (non-VLX will pad to 512-bit shuffles).
    if (AllowVariableMask && !MaskContainsZeros &&
        ((Subtarget.hasAVX512() &&
          (MaskVT == MVT::v8f64 || MaskVT == MVT::v8i64 ||
           MaskVT == MVT::v4f64 || MaskVT == MVT::v4i64 ||
           MaskVT == MVT::v16f32 || MaskVT == MVT::v16i32 ||
           MaskVT == MVT::v8f32 || MaskVT == MVT::v8i32)) ||
         (Subtarget.hasBWI() && AllowBWIVPERMV3 &&
          (MaskVT == MVT::v16i16 || MaskVT == MVT::v32i16)) ||
         (Subtarget.hasVBMI() && AllowBWIVPERMV3 &&
          (MaskVT == MVT::v32i8 || MaskVT == MVT::v64i8)))) {
      V1 = CanonicalizeShuffleInput(MaskVT, V1);
      V2 = CanonicalizeShuffleInput(MaskVT, V2);
      Res = lowerShuffleWithPERMV(DL, MaskVT, Mask, V1, V2, Subtarget, DAG);
      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 = CanonicalizeShuffleInput(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 = CanonicalizeShuffleInput(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 = CanonicalizeShuffleInput(MaskVT, V1);
    V2 = CanonicalizeShuffleInput(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(0x80, 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 = CanonicalizeShuffleInput(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(0x80, DL, MVT::i8));
        continue;
      }
      M = Ratio * M + i % Ratio;
      VPPERMMask.push_back(DAG.getConstant(M, DL, MVT::i8));
    }
    MVT ByteVT = MVT::v16i8;
    V1 = CanonicalizeShuffleInput(ByteVT, V1);
    V2 = CanonicalizeShuffleInput(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,
  // (non-VLX will pad to 512-bit shuffles)
  if (!UnaryShuffle && AllowVariableMask && !MaskContainsZeros &&
      ((Subtarget.hasAVX512() &&
        (MaskVT == MVT::v2f64 || MaskVT == MVT::v4f64 || MaskVT == MVT::v8f64 ||
         MaskVT == MVT::v2i64 || MaskVT == MVT::v4i64 || MaskVT == MVT::v8i64 ||
         MaskVT == MVT::v4f32 || MaskVT == MVT::v4i32 || MaskVT == MVT::v8f32 ||
         MaskVT == MVT::v8i32 || MaskVT == MVT::v16f32 ||
         MaskVT == MVT::v16i32)) ||
       (Subtarget.hasBWI() && AllowBWIVPERMV3 &&
        (MaskVT == MVT::v8i16 || MaskVT == MVT::v16i16 || MaskVT == MVT::v32i16)) ||
       (Subtarget.hasVBMI() && AllowBWIVPERMV3 &&
        (MaskVT == MVT::v16i8 || MaskVT == MVT::v32i8 || MaskVT == MVT::v64i8)))) {
    V1 = CanonicalizeShuffleInput(MaskVT, V1);
    V2 = CanonicalizeShuffleInput(MaskVT, V2);
    Res = lowerShuffleWithPERMV(DL, MaskVT, Mask, V1, V2, Subtarget, DAG);
    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();

  EVT RootVT = Root.getValueType();
  unsigned RootSizeInBits = RootVT.getSizeInBits();
  assert((RootSizeInBits % NumMaskElts) == 0 && "Unexpected root shuffle mask");

  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 = RootSizeInBits;
  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) {
      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();

  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();
}

// Canonicalize the combined shuffle mask chain with horizontal ops.
// NOTE: This may update the Ops and Mask.
static SDValue canonicalizeShuffleMaskWithHorizOp(
    MutableArrayRef<SDValue> Ops, MutableArrayRef<int> Mask,
    unsigned RootSizeInBits, const SDLoc &DL, SelectionDAG &DAG,
    const X86Subtarget &Subtarget) {
  if (Mask.empty() || Ops.empty())
    return SDValue();

  SmallVector<SDValue> BC;
  for (SDValue Op : Ops)
    BC.push_back(peekThroughBitcasts(Op));

  // All ops must be the same horizop + type.
  SDValue BC0 = BC[0];
  EVT VT0 = BC0.getValueType();
  unsigned Opcode0 = BC0.getOpcode();
  if (VT0.getSizeInBits() != RootSizeInBits || llvm::any_of(BC, [&](SDValue V) {
        return V.getOpcode() != Opcode0 || V.getValueType() != VT0;
      }))
    return SDValue();

  bool isHoriz = (Opcode0 == X86ISD::FHADD || Opcode0 == X86ISD::HADD ||
                  Opcode0 == X86ISD::FHSUB || Opcode0 == X86ISD::HSUB);
  bool isPack = (Opcode0 == X86ISD::PACKSS || Opcode0 == X86ISD::PACKUS);
  if (!isHoriz && !isPack)
    return SDValue();

  int NumElts = VT0.getVectorNumElements();
  int NumLanes = VT0.getSizeInBits() / 128;
  int NumEltsPerLane = NumElts / NumLanes;
  int NumHalfEltsPerLane = NumEltsPerLane / 2;

  // See if we can remove the shuffle by resorting the HOP chain so that
  // the HOP args are pre-shuffled.
  // TODO: Generalize to any sized/depth chain.
  // TODO: Add support for PACKSS/PACKUS.
  if (isHoriz && NumEltsPerLane == 4 && VT0.is128BitVector() &&
      shouldUseHorizontalOp(Ops.size() == 1, DAG, Subtarget)) {
    SmallVector<int> ScaledMask;
    if (scaleShuffleElements(Mask, 4, ScaledMask)) {
      // Attempt to find a HOP(HOP(X,Y),HOP(Z,W)) source operand.
      auto GetHOpSrc = [&](int M) {
        if (M == SM_SentinelUndef)
          return DAG.getUNDEF(VT0);
        if (M == SM_SentinelZero)
          return getZeroVector(VT0.getSimpleVT(), Subtarget, DAG, DL);
        SDValue Src0 = BC[M / NumElts];
        SDValue Src1 = Src0.getOperand((M % 4) >= 2);
        if (Src1.getOpcode() == Opcode0 && Src0->isOnlyUserOf(Src1.getNode()))
          return Src1.getOperand(M % 2);
        return SDValue();
      };
      SDValue M0 = GetHOpSrc(ScaledMask[0]);
      SDValue M1 = GetHOpSrc(ScaledMask[1]);
      SDValue M2 = GetHOpSrc(ScaledMask[2]);
      SDValue M3 = GetHOpSrc(ScaledMask[3]);
      if (M0 && M1 && M2 && M3) {
        SDValue LHS = DAG.getNode(Opcode0, DL, VT0, M0, M1);
        SDValue RHS = DAG.getNode(Opcode0, DL, VT0, M2, M3);
        return DAG.getNode(Opcode0, DL, VT0, LHS, RHS);
      }
    }
  }

  if (2 < Ops.size())
    return SDValue();

  SDValue BC1 = BC[BC.size() - 1];
  if (Mask.size() == VT0.getVectorNumElements()) {
    // Canonicalize binary shuffles of horizontal ops that use the
    // same sources to an unary shuffle.
    // TODO: Try to perform this fold even if the shuffle remains.
    if (Ops.size() == 2) {
      auto ContainsOps = [](SDValue HOp, SDValue Op) {
        return Op == HOp.getOperand(0) || Op == HOp.getOperand(1);
      };
      // Commute if all BC0's ops are contained in BC1.
      if (ContainsOps(BC1, BC0.getOperand(0)) &&
          ContainsOps(BC1, BC0.getOperand(1))) {
        ShuffleVectorSDNode::commuteMask(Mask);
        std::swap(Ops[0], Ops[1]);
        std::swap(BC0, BC1);
      }

      // If BC1 can be represented by BC0, then convert to unary shuffle.
      if (ContainsOps(BC0, BC1.getOperand(0)) &&
          ContainsOps(BC0, BC1.getOperand(1))) {
        for (int &M : Mask) {
          if (M < NumElts) // BC0 element or UNDEF/Zero sentinel.
            continue;
          int SubLane = ((M % NumEltsPerLane) >= NumHalfEltsPerLane) ? 1 : 0;
          M -= NumElts + (SubLane * NumHalfEltsPerLane);
          if (BC1.getOperand(SubLane) != BC0.getOperand(0))
            M += NumHalfEltsPerLane;
        }
      }
    }

    // Canonicalize unary horizontal ops to only refer to lower halves.
    for (int i = 0; i != NumElts; ++i) {
      int &M = Mask[i];
      if (isUndefOrZero(M))
        continue;
      if (M < NumElts && BC0.getOperand(0) == BC0.getOperand(1) &&
          (M % NumEltsPerLane) >= NumHalfEltsPerLane)
        M -= NumHalfEltsPerLane;
      if (NumElts <= M && BC1.getOperand(0) == BC1.getOperand(1) &&
          (M % NumEltsPerLane) >= NumHalfEltsPerLane)
        M -= NumHalfEltsPerLane;
    }
  }

  // Combine binary shuffle of 2 similar 'Horizontal' instructions into a
  // single instruction. Attempt to match a v2X64 repeating shuffle pattern that
  // represents the LHS/RHS inputs for the lower/upper halves.
  unsigned EltSizeInBits = RootSizeInBits / Mask.size();
  SmallVector<int, 16> TargetMask128, WideMask128;
  if (isRepeatedTargetShuffleMask(128, EltSizeInBits, Mask, TargetMask128) &&
      scaleShuffleElements(TargetMask128, 2, WideMask128)) {
    assert(isUndefOrZeroOrInRange(WideMask128, 0, 4) && "Illegal shuffle");
    bool SingleOp = (Ops.size() == 1);
    if (!isHoriz || shouldUseHorizontalOp(SingleOp, DAG, Subtarget)) {
      SDValue Lo = isInRange(WideMask128[0], 0, 2) ? BC0 : BC1;
      SDValue Hi = isInRange(WideMask128[1], 0, 2) ? BC0 : BC1;
      Lo = Lo.getOperand(WideMask128[0] & 1);
      Hi = Hi.getOperand(WideMask128[1] & 1);
      if (SingleOp) {
        MVT SrcVT = BC0.getOperand(0).getSimpleValueType();
        SDValue Undef = DAG.getUNDEF(SrcVT);
        SDValue Zero = getZeroVector(SrcVT, Subtarget, DAG, DL);
        Lo = (WideMask128[0] == SM_SentinelZero ? Zero : Lo);
        Hi = (WideMask128[1] == SM_SentinelZero ? Zero : Hi);
        Lo = (WideMask128[0] == SM_SentinelUndef ? Undef : Lo);
        Hi = (WideMask128[1] == SM_SentinelUndef ? Undef : Hi);
      }
      return DAG.getNode(Opcode0, DL, VT0, Lo, Hi);
    }
  }

  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.
  SDLoc DL(Root);
  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());

  // Attempt to create a zero vector.
  if ((UndefElts | ZeroElts).isAllOnesValue())
    return getZeroVector(Root.getSimpleValueType(), Subtarget, DAG, DL);

  // 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);
  if (!DAG.getTargetLoweringInfo().isTypeLegal(MaskVT))
    return SDValue();

  SDValue CstOp = getConstVector(ConstantBitData, UndefElts, MaskVT, DAG, DL);
  return DAG.getBitcast(VT, CstOp);
}

namespace llvm {
  namespace X86 {
    enum {
      MaxShuffleCombineDepth = 8
    };
  }
} // namespace llvm

/// 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,
    unsigned MaxDepth, 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");
  assert(Root.getSimpleValueType().isVector() &&
         "Shuffles operate on vector types!");
  unsigned RootSizeInBits = Root.getSimpleValueType().getSizeInBits();

  // Bound the depth of our recursive combine because this is ultimately
  // quadratic in nature.
  if (Depth >= MaxDepth)
    return SDValue();

  // Directly rip through bitcasts to find the underlying operand.
  SDValue Op = SrcOps[SrcOpIndex];
  Op = peekThroughOneUseBitcasts(Op);

  EVT VT = Op.getValueType();
  if (!VT.isVector() || !VT.isSimple())
    return SDValue(); // Bail if we hit a non-simple non-vector.

  assert((RootSizeInBits % VT.getSizeInBits()) == 0 &&
         "Can only combine shuffles upto size of the root op.");

  // 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 not be larger than the shuffle result.
  // TODO: Relax this for single input faux shuffles (trunc/extract_subvector).
  if (llvm::any_of(OpInputs, [VT](SDValue OpInput) {
        return OpInput.getValueSizeInBits() > VT.getSizeInBits();
      }))
    return SDValue();

  // If the shuffle result was smaller than the root, we need to adjust the
  // mask indices and pad the mask with undefs.
  if (RootSizeInBits > VT.getSizeInBits()) {
    unsigned NumSubVecs = RootSizeInBits / VT.getSizeInBits();
    unsigned OpMaskSize = OpMask.size();
    if (OpInputs.size() > 1) {
      unsigned PaddedMaskSize = NumSubVecs * OpMaskSize;
      for (int &M : OpMask) {
        if (M < 0)
          continue;
        int EltIdx = M % OpMaskSize;
        int OpIdx = M / OpMaskSize;
        M = (PaddedMaskSize * OpIdx) + EltIdx;
      }
    }
    OpZero = OpZero.zext(NumSubVecs * OpMaskSize);
    OpUndef = OpUndef.zext(NumSubVecs * OpMaskSize);
    OpMask.append((NumSubVecs - 1) * OpMaskSize, SM_SentinelUndef);
  }

  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());
  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() < (MaxDepth - 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, MaxDepth,
              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;

  // Canonicalize the combined shuffle mask chain with horizontal ops.
  // NOTE: This will update the Ops and Mask.
  if (SDValue HOp = canonicalizeShuffleMaskWithHorizOp(
          Ops, Mask, RootSizeInBits, SDLoc(Root), DAG, Subtarget))
    return DAG.getBitcast(Root.getValueType(), HOp);

  // Widen any subvector shuffle inputs we've collected.
  if (any_of(Ops, [RootSizeInBits](SDValue Op) {
        return Op.getValueSizeInBits() < RootSizeInBits;
      })) {
    for (SDValue &Op : Ops)
      if (Op.getValueSizeInBits() < RootSizeInBits)
        Op = widenSubVector(Op, false, Subtarget, DAG, SDLoc(Op),
                            RootSizeInBits);
    // Reresolve - we might have repeated subvector sources.
    resolveTargetShuffleInputsAndMask(Ops, Mask);
  }

  // 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.
    while (Mask.size() > 1) {
      SmallVector<int, 64> WidenedMask;
      if (!canWidenShuffleElements(Mask, WidenedMask))
        break;
      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,
                                       X86::MaxShuffleCombineDepth,
                                       /*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();
}

/// Attempt to fold vpermf128(op(),op()) -> op(vpermf128(),vpermf128()).
static SDValue canonicalizeLaneShuffleWithRepeatedOps(SDValue V,
                                                      SelectionDAG &DAG,
                                                      const SDLoc &DL) {
  assert(V.getOpcode() == X86ISD::VPERM2X128 && "Unknown lane shuffle");

  MVT VT = V.getSimpleValueType();
  SDValue Src0 = peekThroughBitcasts(V.getOperand(0));
  SDValue Src1 = peekThroughBitcasts(V.getOperand(1));
  unsigned SrcOpc0 = Src0.getOpcode();
  unsigned SrcOpc1 = Src1.getOpcode();
  EVT SrcVT0 = Src0.getValueType();
  EVT SrcVT1 = Src1.getValueType();

  if (!Src1.isUndef() && (SrcVT0 != SrcVT1 || SrcOpc0 != SrcOpc1))
    return SDValue();

  switch (SrcOpc0) {
  case X86ISD::MOVDDUP: {
    SDValue LHS = DAG.getBitcast(VT, Src0.getOperand(0));
    SDValue RHS =
        DAG.getBitcast(VT, Src1.isUndef() ? Src1 : Src1.getOperand(0));
    SDValue Res =
        DAG.getNode(X86ISD::VPERM2X128, DL, VT, LHS, RHS, V.getOperand(2));
    Res = DAG.getNode(SrcOpc0, DL, SrcVT0, DAG.getBitcast(SrcVT0, Res));
    return DAG.getBitcast(VT, Res);
  }
  case X86ISD::VPERMILPI:
    // TODO: Handle v4f64 permutes with different low/high lane masks.
    if (SrcVT0 == MVT::v4f64) {
      uint64_t Mask = Src0.getConstantOperandVal(1);
      if ((Mask & 0x3) != ((Mask >> 2) & 0x3))
        break;
    }
    LLVM_FALLTHROUGH;
  case X86ISD::VSHLI:
  case X86ISD::VSRLI:
  case X86ISD::VSRAI:
  case X86ISD::PSHUFD:
    if (Src1.isUndef() || Src0.getOperand(1) == Src1.getOperand(1)) {
      SDValue LHS = DAG.getBitcast(VT, Src0.getOperand(0));
      SDValue RHS =
          DAG.getBitcast(VT, Src1.isUndef() ? Src1 : Src1.getOperand(0));
      SDValue Res =
          DAG.getNode(X86ISD::VPERM2X128, DL, VT, LHS, RHS, V.getOperand(2));
      Res = DAG.getNode(SrcOpc0, DL, SrcVT0, DAG.getBitcast(SrcVT0, Res),
                        Src0.getOperand(1));
      return DAG.getBitcast(VT, Res);
    }
    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();

  if (SDValue R = combineCommutableSHUFP(N, VT, DL, DAG))
    return R;

  // Canonicalize UNARYSHUFFLE(XOR(X,-1) -> XOR(UNARYSHUFFLE(X),-1) to
  // help expose the 'NOT' pattern further up the DAG.
  // TODO: This might be beneficial for any binop with a 'splattable' operand.
  switch (Opcode) {
  case X86ISD::MOVDDUP:
  case X86ISD::PSHUFD: {
    SDValue Src = N.getOperand(0);
    if (Src.hasOneUse() && Src.getValueType() == VT) {
      if (SDValue Not = IsNOT(Src, DAG, /*OneUse*/ true)) {
        Not = DAG.getBitcast(VT, Not);
        Not = Opcode == X86ISD::MOVDDUP
                  ? DAG.getNode(Opcode, DL, VT, Not)
                  : DAG.getNode(Opcode, DL, VT, Not, N.getOperand(1));
        EVT IntVT = Not.getValueType().changeTypeToInteger();
        SDValue AllOnes = DAG.getConstant(-1, DL, IntVT);
        Not = DAG.getBitcast(IntVT, Not);
        Not = DAG.getNode(ISD::XOR, DL, IntVT, Not, AllOnes);
        return DAG.getBitcast(VT, Not);
      }
    }
    break;
  }
  }

  // Handle specific target shuffles.
  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);
      if (SDValue VZLoad = narrowLoadToVZLoad(LN, MVT::f64, MVT::v2f64, DAG)) {
        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,
              X86::MaxShuffleCombineDepth,
              /*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() &&
        DAG.getTargetLoweringInfo().isTypeLegal(BCVT)) {
      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).
    // Ensure the same SDValue from the SDNode use is being used.
    for (SDNode *User : Src->uses())
      if (User != N.getNode() && User->getOpcode() == X86ISD::VBROADCAST &&
          Src == User->getOperand(0) &&
          User->getValueSizeInBits(0).getFixedSize() >
              VT.getFixedSizeInBits()) {
        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->getOriginalAlign(),
              LN->getMemOperand()->getFlags());
          DCI.CombineTo(N.getNode(), BcastLd);
          DAG.ReplaceAllUsesOfValueWith(SDValue(LN, 1), BcastLd.getValue(1));
          DCI.recursivelyDeleteUnusedNodes(Src.getNode());
          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(Src.getNode());
          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(),
                                                 TypeSize::Fixed(Offset), DL);
          SDValue Ops[] = { LN->getChain(), Ptr };
          SDValue BcastLd = DAG.getMemIntrinsicNode(
              X86ISD::VBROADCAST_LOAD, DL, Tys, Ops, MVT::i16,
              LN->getPointerInfo().getWithOffset(Offset),
              LN->getOriginalAlign(),
              LN->getMemOperand()->getFlags());
          DCI.CombineTo(N.getNode(), BcastLd);
          DAG.ReplaceAllUsesOfValueWith(SDValue(LN, 1), BcastLd.getValue(1));
          DCI.recursivelyDeleteUnusedNodes(Src.getNode());
          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 || SrcVT == MVT::v4f32 || SrcVT == MVT::v2i64 ||
         SrcVT == MVT::v4i32) &&
        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, SrcVT.getScalarType(),
            LN->getPointerInfo(), LN->getOriginalAlign(),
            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::VZEXT_MOVL: {
    SDValue N0 = N.getOperand(0);

    // If this a vzmovl of a full vector load, replace it with a vzload, unless
    // the load is volatile.
    if (N0.hasOneUse() && ISD::isNormalLoad(N0.getNode())) {
      auto *LN = cast<LoadSDNode>(N0);
      if (SDValue VZLoad =
              narrowLoadToVZLoad(LN, VT.getVectorElementType(), VT, DAG)) {
        DCI.CombineTo(N.getNode(), VZLoad);
        DAG.ReplaceAllUsesOfValueWith(SDValue(LN, 1), VZLoad.getValue(1));
        DCI.recursivelyDeleteUnusedNodes(LN);
        return N;
      }
    }

    // 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 (N0.hasOneUse() && N0.getOpcode() == X86ISD::VBROADCAST_LOAD) {
      auto *LN = cast<MemSDNode>(N0);
      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.getNode(), VZLoad);
        DAG.ReplaceAllUsesOfValueWith(SDValue(LN, 1), VZLoad.getValue(1));
        DCI.recursivelyDeleteUnusedNodes(LN);
        return N;
      }
    }

    // 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 (N0.hasOneUse() && N0.getOpcode() == ISD::SCALAR_TO_VECTOR &&
        N0.getOperand(0).hasOneUse() &&
        N0.getOperand(0).getValueType() == MVT::i64) {
      SDValue In = N0.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);
      }
    }

    // Load a scalar integer constant directly to XMM instead of transferring an
    // immediate value from GPR.
    // vzext_movl (scalar_to_vector C) --> load [C,0...]
    if (N0.getOpcode() == ISD::SCALAR_TO_VECTOR) {
      if (auto *C = dyn_cast<ConstantSDNode>(N0.getOperand(0))) {
        // Create a vector constant - scalar constant followed by zeros.
        EVT ScalarVT = N0.getOperand(0).getValueType();
        Type *ScalarTy = ScalarVT.getTypeForEVT(*DAG.getContext());
        unsigned NumElts = VT.getVectorNumElements();
        Constant *Zero = ConstantInt::getNullValue(ScalarTy);
        SmallVector<Constant *, 32> ConstantVec(NumElts, Zero);
        ConstantVec[0] = const_cast<ConstantInt *>(C->getConstantIntValue());

        // Load the vector constant from constant pool.
        MVT PVT = DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout());
        SDValue CP = DAG.getConstantPool(ConstantVector::get(ConstantVec), PVT);
        MachinePointerInfo MPI =
            MachinePointerInfo::getConstantPool(DAG.getMachineFunction());
        Align Alignment = cast<ConstantPoolSDNode>(CP)->getAlign();
        return DAG.getLoad(VT, DL, DAG.getEntryNode(), CP, MPI, Alignment,
                           MachineMemOperand::MOLoad);
      }
    }

    // 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 (!DCI.isBeforeLegalizeOps() && N0.hasOneUse()) {
      SDValue V = peekThroughOneUseBitcasts(N0);

      if (V.getOpcode() == ISD::INSERT_SUBVECTOR && V.getOperand(0).isUndef() &&
          isNullConstant(V.getOperand(2))) {
        SDValue In = V.getOperand(1);
        MVT SubVT = MVT::getVectorVT(VT.getVectorElementType(),
                                     In.getValueSizeInBits() /
                                         VT.getScalarSizeInBits());
        In = DAG.getBitcast(SubVT, In);
        SDValue Movl = DAG.getNode(X86ISD::VZEXT_MOVL, DL, SubVT, In);
        return DAG.getNode(ISD::INSERT_SUBVECTOR, DL, VT,
                           getZeroVector(VT, Subtarget, DAG, DL), Movl,
                           V.getOperand(2));
      }
    }

    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: {
    // Fold vperm2x128(bitcast(x),bitcast(y),c) -> bitcast(vperm2x128(x,y,c)).
    SDValue LHS = N->getOperand(0);
    SDValue RHS = N->getOperand(1);
    if (LHS.getOpcode() == ISD::BITCAST &&
        (RHS.getOpcode() == ISD::BITCAST || RHS.isUndef())) {
      EVT SrcVT = LHS.getOperand(0).getValueType();
      if (RHS.isUndef() || SrcVT == RHS.getOperand(0).getValueType()) {
        return DAG.getBitcast(VT, DAG.getNode(X86ISD::VPERM2X128, DL, SrcVT,
                                              DAG.getBitcast(SrcVT, LHS),
                                              DAG.getBitcast(SrcVT, RHS),
                                              N->getOperand(2)));
      }
    }

    // Fold vperm2x128(op(),op()) -> op(vperm2x128(),vperm2x128()).
    if (SDValue Res = canonicalizeLaneShuffleWithRepeatedOps(N, DAG, DL))
      return Res;

    // Fold vperm2x128 subvector shuffle with an inner concat pattern.
    // vperm2x128(concat(X,Y),concat(Z,W)) --> concat X,Y etc.  
    auto FindSubVector128 = [&](unsigned Idx) {
      if (Idx > 3)
        return SDValue();
      SDValue Src = peekThroughBitcasts(N.getOperand(Idx < 2 ? 0 : 1));
      SmallVector<SDValue> SubOps;
      if (collectConcatOps(Src.getNode(), SubOps) && SubOps.size() == 2)
        return SubOps[Idx & 1];
      unsigned NumElts = Src.getValueType().getVectorNumElements();
      if ((Idx & 1) == 1 && Src.getOpcode() == ISD::INSERT_SUBVECTOR &&
          Src.getOperand(1).getValueSizeInBits() == 128 &&
          Src.getConstantOperandAPInt(2) == (NumElts / 2)) {
        return Src.getOperand(1);
      }
      return SDValue();
    };
    unsigned Imm = N.getConstantOperandVal(2);
    if (SDValue SubLo = FindSubVector128(Imm & 0x0F)) {
      if (SDValue SubHi = FindSubVector128((Imm & 0xF0) >> 4)) {
        MVT SubVT = VT.getHalfNumVectorElementsVT();
        SubLo = DAG.getBitcast(SubVT, SubLo);
        SubHi = DAG.getBitcast(SubVT, SubHi);
        return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, SubLo, SubHi);
      }
    }
    return SDValue();
  }
  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);
    unsigned InsertPSMask = N.getConstantOperandVal(2);
    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() && V.getOperand(0).hasOneUse()) {
      SDValue D = peekThroughOneUseBitcasts(V.getOperand(0));
      if (D.getOpcode() == X86ISD::PSHUFD) {
        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) {
  // TODO: Can we use getTargetShuffleInputs instead?
  unsigned Opcode = N->getOpcode();
  if (Opcode != X86ISD::MOVDDUP && Opcode != X86ISD::VBROADCAST)
    if (Opcode != X86ISD::UNPCKL && Opcode != X86ISD::UNPCKH)
      if (Opcode != X86ISD::SHUFP)
        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();

  // unpcklo(hop(x,y),hop(z,w)) -> permute(hop(x,z)).
  // unpckhi(hop(x,y),hop(z,w)) -> permute(hop(y,w)).
  // Don't fold if hop(x,y) == hop(z,w).
  if (Opcode == X86ISD::UNPCKL || Opcode == X86ISD::UNPCKH) {
    SDValue HOp2 = N->getOperand(1);
    if (HOp.getOpcode() != HOp2.getOpcode() || VT.getScalarSizeInBits() != 32)
      return SDValue();
    if (HOp == HOp2)
      return SDValue();
    SDLoc DL(HOp);
    unsigned LoHi = Opcode == X86ISD::UNPCKL ? 0 : 1;
    SDValue Res = DAG.getNode(HOp.getOpcode(), DL, VT, HOp.getOperand(LoHi),
                              HOp2.getOperand(LoHi));
    // Use SHUFPS for the permute so this will work on SSE3 targets, shuffle
    // combining and domain handling will simplify this later on.
    EVT ShuffleVT = VT.changeVectorElementType(MVT::f32);
    Res = DAG.getBitcast(ShuffleVT, Res);
    Res = DAG.getNode(X86ISD::SHUFP, DL, ShuffleVT, Res, Res,
                      getV4X86ShuffleImm8ForMask({0, 2, 1, 3}, DL, DAG));
    return DAG.getBitcast(VT, Res);
  }

  // shufps(hop(x,y),hop(z,w)) -> permute(hop(x,z)) etc.
  // Don't fold if hop(x,y) == hop(z,w).
  if (Opcode == X86ISD::SHUFP) {
    SDValue HOp2 = N->getOperand(1);
    if (HOp.getOpcode() != HOp2.getOpcode() || VT != MVT::v4f32 || HOp == HOp2)
      return SDValue();
    SmallVector<int> RepeatedMask;
    DecodeSHUFPMask(4, 32, N->getConstantOperandVal(2), RepeatedMask);
    SDValue Op0 = HOp.getOperand(RepeatedMask[0] >= 2 ? 1 : 0);
    SDValue Op1 = HOp.getOperand(RepeatedMask[1] >= 2 ? 1 : 0);
    SDValue Op2 = HOp2.getOperand(RepeatedMask[2] >= 6 ? 1 : 0);
    SDValue Op3 = HOp2.getOperand(RepeatedMask[3] >= 6 ? 1 : 0);
    if ((Op0 == Op1) && (Op2 == Op3)) {
      int NewMask[4] = {RepeatedMask[0] % 2, RepeatedMask[1] % 2,
                        ((RepeatedMask[2] - 4) % 2) + 2,
                        ((RepeatedMask[3] - 4) % 2) + 2};
      SDLoc DL(HOp);
      SDValue Res = DAG.getNode(HOp.getOpcode(), DL, VT, Op0, Op2);
      // Use SHUFPS for the permute so this will work on SSE3 targets, shuffle
      // combining and domain handling will simplify this later on.
      return DAG.getNode(X86ISD::SHUFP, DL, VT, Res, Res,
                         getV4X86ShuffleImm8ForMask(NewMask, DL, DAG));
    }
    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 &&
      (isShuffleEquivalent(Mask, {0, 0}) ||
       isShuffleEquivalent(Mask, {0, 1, 0, 1}) ||
       isShuffleEquivalent(Mask, {0, 1, 2, 3, 0, 1, 2, 3})))
    return updateHOp(HOp, DAG);

  if (HOp.getValueSizeInBits() == 256 &&
      (isShuffleEquivalent(Mask, {0, 0, 2, 2}) ||
       isShuffleEquivalent(Mask, {0, 1, 0, 1, 4, 5, 4, 5}) ||
       isShuffleEquivalent(
           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, SDValue(N, 0), 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);
  }

  return SDValue();
}

// Simplify variable target shuffle masks based on the demanded elements.
// TODO: Handle DemandedBits in mask indices as well?
bool X86TargetLowering::SimplifyDemandedVectorEltsForTargetShuffle(
    SDValue Op, const APInt &DemandedElts, unsigned MaskIndex,
    TargetLowering::TargetLoweringOpt &TLO, unsigned Depth) const {
  // If we're demanding all elements don't bother trying to simplify the mask.
  unsigned NumElts = DemandedElts.getBitWidth();
  if (DemandedElts.isAllOnesValue())
    return false;

  SDValue Mask = Op.getOperand(MaskIndex);
  if (!Mask.hasOneUse())
    return false;

  // Attempt to generically simplify the variable shuffle mask.
  APInt MaskUndef, MaskZero;
  if (SimplifyDemandedVectorElts(Mask, DemandedElts, MaskUndef, MaskZero, TLO,
                                 Depth + 1))
    return true;

  // Attempt to extract+simplify a (constant pool load) shuffle mask.
  // TODO: Support other types from getTargetShuffleMaskIndices?
  SDValue BC = peekThroughOneUseBitcasts(Mask);
  EVT BCVT = BC.getValueType();
  auto *Load = dyn_cast<LoadSDNode>(BC);
  if (!Load)
    return false;

  const Constant *C = getTargetConstantFromNode(Load);
  if (!C)
    return false;

  Type *CTy = C->getType();
  if (!CTy->isVectorTy() ||
      CTy->getPrimitiveSizeInBits() != Mask.getValueSizeInBits())
    return false;

  // Handle scaling for i64 elements on 32-bit targets.
  unsigned NumCstElts = cast<FixedVectorType>(CTy)->getNumElements();
  if (NumCstElts != NumElts && NumCstElts != (NumElts * 2))
    return false;
  unsigned Scale = NumCstElts / NumElts;

  // Simplify mask if we have an undemanded element that is not undef.
  bool Simplified = false;
  SmallVector<Constant *, 32> ConstVecOps;
  for (unsigned i = 0; i != NumCstElts; ++i) {
    Constant *Elt = C->getAggregateElement(i);
    if (!DemandedElts[i / Scale] && !isa<UndefValue>(Elt)) {
      ConstVecOps.push_back(UndefValue::get(Elt->getType()));
      Simplified = true;
      continue;
    }
    ConstVecOps.push_back(Elt);
  }
  if (!Simplified)
    return false;

  // Generate new constant pool entry + legalize immediately for the load.
  SDLoc DL(Op);
  SDValue CV = TLO.DAG.getConstantPool(ConstantVector::get(ConstVecOps), BCVT);
  SDValue LegalCV = LowerConstantPool(CV, TLO.DAG);
  SDValue NewMask = TLO.DAG.getLoad(
      BCVT, DL, TLO.DAG.getEntryNode(), LegalCV,
      MachinePointerInfo::getConstantPool(TLO.DAG.getMachineFunction()),
      Load->getAlign());
  return TLO.CombineTo(Mask, TLO.DAG.getBitcast(Mask.getValueType(), NewMask));
}

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;

    // Aggressively peek through ops to get at the demanded elts.
    if (!DemandedElts.isAllOnesValue())
      if (SDValue NewSrc = SimplifyMultipleUseDemandedVectorElts(
              Src, DemandedElts, TLO.DAG, Depth + 1))
        return TLO.CombineTo(
            Op, TLO.DAG.getNode(Opc, SDLoc(Op), VT, NewSrc, Op.getOperand(1)));
    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()) {
      SDValue NewN0 = SimplifyMultipleUseDemandedVectorElts(N0, DemandedLHS,
                                                            TLO.DAG, Depth + 1);
      SDValue NewN1 = SimplifyMultipleUseDemandedVectorElts(N1, 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::VZEXT_MOVL: {
    // If upper demanded elements are already zero then we have nothing to do.
    SDValue Src = Op.getOperand(0);
    APInt DemandedUpperElts = DemandedElts;
    DemandedUpperElts.clearLowBits(1);
    if (TLO.DAG.computeKnownBits(Src, DemandedUpperElts, Depth + 1).isZero())
      return TLO.CombineTo(Op, Src);
    break;
  }
  case X86ISD::VBROADCAST: {
    SDValue Src = Op.getOperand(0);
    MVT SrcVT = Src.getSimpleValueType();
    if (!SrcVT.isVector())
      break;
    // 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;
    // Aggressively peek through src to get at the demanded elt.
    // TODO - we should do this for all target/faux shuffles ops.
    if (SDValue NewSrc = SimplifyMultipleUseDemandedVectorElts(
            Src, SrcElts, TLO.DAG, Depth + 1))
      return TLO.CombineTo(Op, TLO.DAG.getNode(Opc, SDLoc(Op), VT, NewSrc));
    break;
  }
  case X86ISD::VPERMV:
    if (SimplifyDemandedVectorEltsForTargetShuffle(Op, DemandedElts, 0, TLO,
                                                   Depth))
      return true;
    break;
  case X86ISD::PSHUFB:
  case X86ISD::VPERMV3:
  case X86ISD::VPERMILPV:
    if (SimplifyDemandedVectorEltsForTargetShuffle(Op, DemandedElts, 1, TLO,
                                                   Depth))
      return true;
    break;
  case X86ISD::VPPERM:
  case X86ISD::VPERMIL2:
    if (SimplifyDemandedVectorEltsForTargetShuffle(Op, DemandedElts, 2, TLO,
                                                   Depth))
      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) {
      // Scalar broadcast.
    case X86ISD::VBROADCAST: {
      SDLoc DL(Op);
      SDValue Src = Op.getOperand(0);
      if (Src.getValueSizeInBits() > ExtSizeInBits)
        Src = extractSubVector(Src, 0, TLO.DAG, DL, ExtSizeInBits);
      EVT BcstVT = EVT::getVectorVT(*TLO.DAG.getContext(), VT.getScalarType(),
                                    ExtSizeInBits / VT.getScalarSizeInBits());
      SDValue Bcst = TLO.DAG.getNode(X86ISD::VBROADCAST, DL, BcstVT, Src);
      return TLO.CombineTo(Op, insertSubVector(TLO.DAG.getUNDEF(VT), Bcst, 0,
                                               TLO.DAG, DL, ExtSizeInBits));
    }
    case X86ISD::VBROADCAST_LOAD: {
      SDLoc DL(Op);
      auto *MemIntr = cast<MemIntrinsicSDNode>(Op);
      EVT BcstVT = EVT::getVectorVT(*TLO.DAG.getContext(), VT.getScalarType(),
                                    ExtSizeInBits / VT.getScalarSizeInBits());
      SDVTList Tys = TLO.DAG.getVTList(BcstVT, MVT::Other);
      SDValue Ops[] = {MemIntr->getOperand(0), MemIntr->getOperand(1)};
      SDValue Bcst = TLO.DAG.getMemIntrinsicNode(
          X86ISD::VBROADCAST_LOAD, DL, Tys, Ops, MemIntr->getMemoryVT(),
          MemIntr->getMemOperand());
      TLO.DAG.makeEquivalentMemoryOrdering(SDValue(MemIntr, 1),
                                           Bcst.getValue(1));
      return TLO.CombineTo(Op, insertSubVector(TLO.DAG.getUNDEF(VT), Bcst, 0,
                                               TLO.DAG, DL, ExtSizeInBits));
    }
      // Subvector broadcast.
    case X86ISD::SUBV_BROADCAST_LOAD: {
      auto *MemIntr = cast<MemIntrinsicSDNode>(Op);
      EVT MemVT = MemIntr->getMemoryVT();
      if (ExtSizeInBits == MemVT.getStoreSizeInBits()) {
        SDLoc DL(Op);
        SDValue Ld =
            TLO.DAG.getLoad(MemVT, DL, MemIntr->getChain(),
                            MemIntr->getBasePtr(), MemIntr->getMemOperand());
        TLO.DAG.makeEquivalentMemoryOrdering(SDValue(MemIntr, 1),
                                             Ld.getValue(1));
        return TLO.CombineTo(Op, insertSubVector(TLO.DAG.getUNDEF(VT), Ld, 0,
                                                 TLO.DAG, DL, ExtSizeInBits));
      } else if ((ExtSizeInBits % MemVT.getStoreSizeInBits()) == 0) {
        SDLoc DL(Op);
        EVT BcstVT = EVT::getVectorVT(*TLO.DAG.getContext(), VT.getScalarType(),
                                      ExtSizeInBits / VT.getScalarSizeInBits());
        SDVTList Tys = TLO.DAG.getVTList(BcstVT, MVT::Other);
        SDValue Ops[] = {MemIntr->getOperand(0), MemIntr->getOperand(1)};
        SDValue Bcst =
            TLO.DAG.getMemIntrinsicNode(X86ISD::SUBV_BROADCAST_LOAD, DL, Tys,
                                        Ops, MemVT, MemIntr->getMemOperand());
        TLO.DAG.makeEquivalentMemoryOrdering(SDValue(MemIntr, 1),
                                             Bcst.getValue(1));
        return TLO.CombineTo(Op, insertSubVector(TLO.DAG.getUNDEF(VT), Bcst, 0,
                                                 TLO.DAG, DL, ExtSizeInBits));
      }
      break;
    }
      // 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;
    }
      // Zero upper elements.
    case X86ISD::VZEXT_MOVL:
      // Target unary shuffles by immediate:
    case X86ISD::PSHUFD:
    case X86ISD::PSHUFLW:
    case X86ISD::PSHUFHW:
    case X86ISD::VPERMILPI:
      // (Non-Lane Crossing) Target Shuffles.
    case X86ISD::VPERMILPV:
    case X86ISD::VPERMIL2:
    case X86ISD::PSHUFB:
    case X86ISD::UNPCKL:
    case X86ISD::UNPCKH:
    case X86ISD::BLENDI:
      // Integer ops.
    case X86ISD::AVG:
    case X86ISD::PACKSS:
    case X86ISD::PACKUS:
      // Horizontal Ops.
    case X86ISD::HADD:
    case X86ISD::HSUB:
    case X86ISD::FHADD:
    case X86ISD::FHSUB: {
      SDLoc DL(Op);
      SmallVector<SDValue, 4> Ops;
      for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i) {
        SDValue SrcOp = Op.getOperand(i);
        EVT SrcVT = SrcOp.getValueType();
        assert((!SrcVT.isVector() || SrcVT.getSizeInBits() == SizeInBits) &&
               "Unsupported vector size");
        Ops.push_back(SrcVT.isVector() ? extractSubVector(SrcOp, 0, TLO.DAG, DL,
                                                          ExtSizeInBits)
                                       : SrcOp);
      }
      MVT ExtVT = VT.getSimpleVT();
      ExtVT = MVT::getVectorVT(ExtVT.getScalarType(),
                               ExtSizeInBits / ExtVT.getScalarSizeInBits());
      SDValue ExtOp = TLO.DAG.getNode(Opc, DL, ExtVT, Ops);
      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.
  // We need to convert the depth to something combineX86ShufflesRecursively
  // can handle - so pretend its Depth == 0 again, and reduce the max depth
  // to match. This prevents combineX86ShuffleChain from returning a
  // combined shuffle that's the same as the original root, causing an
  // infinite loop.
  if (!DemandedElts.isAllOnesValue()) {
    assert(Depth < X86::MaxShuffleCombineDepth && "Depth out of range");

    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, {}, 0, X86::MaxShuffleCombineDepth - 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::VTRUNC: {
    KnownBits KnownOp;
    SDValue Src = Op.getOperand(0);
    MVT SrcVT = Src.getSimpleValueType();

    // Simplify the input, using demanded bit information.
    APInt TruncMask = OriginalDemandedBits.zext(SrcVT.getScalarSizeInBits());
    APInt DemandedElts = OriginalDemandedElts.trunc(SrcVT.getVectorNumElements());
    if (SimplifyDemandedBits(Src, TruncMask, DemandedElts, KnownOp, TLO, Depth + 1))
      return true;
    break;
  }
  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 we are only demanding sign bits then we can use the shift source directly.
    unsigned NumSignBits =
        TLO.DAG.ComputeNumSignBits(Op0, OriginalDemandedElts, Depth + 1);
    unsigned UpperDemandedBits =
        BitWidth - OriginalDemandedBits.countTrailingZeros();
    if (NumSignBits > ShAmt && (NumSignBits - ShAmt) >= UpperDemandedBits)
      return TLO.CombineTo(Op, Op0);

    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);
    return false;
  }
  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);
    return false;
  }
  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);
    return false;
  }
  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 = KnownBits::commonBits(KnownVec, KnownScl);
      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;
    APInt DemandedSrcBits = APInt::getSignMask(SrcBits);
    if (SimplifyDemandedBits(Src, DemandedSrcBits, 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);

    // Attempt to avoid multi-use os if we don't need anything from it.
    if (SDValue NewSrc = SimplifyMultipleUseDemandedBits(
            Src, DemandedSrcBits, DemandedElts, TLO.DAG, Depth + 1))
      return TLO.CombineTo(Op, TLO.DAG.getNode(Opc, SDLoc(Op), VT, NewSrc));
    return false;
  }
  case X86ISD::BEXTR:
  case X86ISD::BEXTRI: {
    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.
      uint64_t Val1 = Cst1->getZExtValue();
      uint64_t MaskedVal1 = Val1 & 0xFFFF;
      if (Opc == X86ISD::BEXTR && MaskedVal1 != Val1) {
        SDLoc DL(Op);
        return TLO.CombineTo(
            Op, TLO.DAG.getNode(X86ISD::BEXTR, DL, VT, Op0,
                                TLO.DAG.getConstant(MaskedVal1, DL, VT)));
      }

      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();
        return false;
      }

      if ((Shift + Length) <= BitWidth) {
        APInt DemandedMask = APInt::getBitsSet(BitWidth, Shift, Shift + Length);
        if (SimplifyDemandedBits(Op0, DemandedMask, Known, TLO, Depth + 1))
          return true;

        Known = Known.extractBits(Length, Shift);
        Known = Known.zextOrTrunc(BitWidth);
        return false;
      }
    } else {
      assert(Opc == X86ISD::BEXTR && "Unexpected opcode!");
      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;
  }
  case X86ISD::PDEP: {
    SDValue Op0 = Op.getOperand(0);
    SDValue Op1 = Op.getOperand(1);

    unsigned DemandedBitsLZ = OriginalDemandedBits.countLeadingZeros();
    APInt LoMask = APInt::getLowBitsSet(BitWidth, BitWidth - DemandedBitsLZ);

    // If the demanded bits has leading zeroes, we don't demand those from the
    // mask.
    if (SimplifyDemandedBits(Op1, LoMask, Known, TLO, Depth + 1))
      return true;

    // The number of possible 1s in the mask determines the number of LSBs of
    // operand 0 used. Undemanded bits from the mask don't matter so filter
    // them before counting.
    KnownBits Known2;
    uint64_t Count = (~Known.Zero & LoMask).countPopulation();
    APInt DemandedMask(APInt::getLowBitsSet(BitWidth, Count));
    if (SimplifyDemandedBits(Op0, DemandedMask, Known2, TLO, Depth + 1))
      return true;

    // Zeroes are retained from the mask, but not ones.
    Known.One.clearAllBits();
    // The result will have at least as many trailing zeros as the non-mask
    // operand since bits can only map to the same or higher bit position.
    Known.Zero.setLowBits(Known2.countMinTrailingZeros());
    return false;
  }
  }

  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::VSHLI: {
    // If we are only demanding sign bits then we can use the shift source
    // directly.
    SDValue Op0 = Op.getOperand(0);
    unsigned ShAmt = Op.getConstantOperandVal(1);
    unsigned BitWidth = DemandedBits.getBitWidth();
    unsigned NumSignBits = DAG.ComputeNumSignBits(Op0, DemandedElts, Depth + 1);
    unsigned UpperDemandedBits = BitWidth - DemandedBits.countTrailingZeros();
    if (NumSignBits > ShAmt && (NumSignBits - ShAmt) >= UpperDemandedBits)
      return Op0;
    break;
  }
  case X86ISD::VSRAI:
    // iff we only need the sign bit then we can use the source directly.
    // TODO: generalize where we only demand extended signbits.
    if (DemandedBits.isSignMask())
      return Op.getOperand(0);
    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 PreferMovMsk = Src.getOpcode() == ISD::TRUNCATE && Src.hasOneUse() &&
                      (Src.getOperand(0).getValueType() == MVT::v16i8 ||
                       Src.getOperand(0).getValueType() == MVT::v32i8 ||
                       Src.getOperand(0).getValueType() == MVT::v64i8);

  // Prefer movmsk for AVX512 for (bitcast (setlt X, 0)) which can be handled
  // directly with vpmovmskb/vmovmskps/vmovmskpd.
  if (Src.getOpcode() == ISD::SETCC && Src.hasOneUse() &&
      cast<CondCodeSDNode>(Src.getOperand(2))->get() == ISD::SETLT &&
      ISD::isBuildVectorAllZeros(Src.getOperand(1).getNode())) {
    EVT CmpVT = Src.getOperand(0).getValueType();
    EVT EltVT = CmpVT.getVectorElementType();
    if (CmpVT.getSizeInBits() <= 256 &&
        (EltVT == MVT::i8 || EltVT == MVT::i32 || EltVT == MVT::i64))
      PreferMovMsk = true;
  }

  // With AVX512 vxi1 types are legal and we prefer using k-regs.
  // MOVMSK is supported in SSE2 or later.
  if (!Subtarget.hasSSE2() || (Subtarget.hasAVX512() && !PreferMovMsk))
    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;

  const TargetLowering &TLI = DAG.getTargetLoweringInfo();

  // 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.getTargetConstant(Intrinsic::x86_mmx_punpcklbw, DL,
                                  TLI.getPointerTy(DAG.getDataLayout())),
            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,
                                TLI.getPointerTy(DAG.getDataLayout())),
          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.getTargetConstant(
        IntrinOp, DL, TLI.getPointerTy(DAG.getDataLayout()));
    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];
}

// Recursive function that attempts to find if a bool vector node was originally
// a vector/float/double that got truncated/extended/bitcast to/from a scalar
// integer. If so, replace the scalar ops with bool vector equivalents back down
// the chain.
static SDValue combineBitcastToBoolVector(EVT VT, SDValue V, const SDLoc &DL,
                                          SelectionDAG &DAG,
                                          const X86Subtarget &Subtarget) {
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  unsigned Opc = V.getOpcode();
  switch (Opc) {
  case ISD::BITCAST: {
    // Bitcast from a vector/float/double, we can cheaply bitcast to VT.
    SDValue Src = V.getOperand(0);
    EVT SrcVT = Src.getValueType();
    if (SrcVT.isVector() || SrcVT.isFloatingPoint())
      return DAG.getBitcast(VT, Src);
    break;
  }
  case ISD::TRUNCATE: {
    // If we find a suitable source, a truncated scalar becomes a subvector.
    SDValue Src = V.getOperand(0);
    EVT NewSrcVT =
        EVT::getVectorVT(*DAG.getContext(), MVT::i1, Src.getValueSizeInBits());
    if (TLI.isTypeLegal(NewSrcVT))
      if (SDValue N0 =
              combineBitcastToBoolVector(NewSrcVT, Src, DL, DAG, Subtarget))
        return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, VT, N0,
                           DAG.getIntPtrConstant(0, DL));
    break;
  }
  case ISD::ANY_EXTEND:
  case ISD::ZERO_EXTEND: {
    // If we find a suitable source, an extended scalar becomes a subvector.
    SDValue Src = V.getOperand(0);
    EVT NewSrcVT = EVT::getVectorVT(*DAG.getContext(), MVT::i1,
                                    Src.getScalarValueSizeInBits());
    if (TLI.isTypeLegal(NewSrcVT))
      if (SDValue N0 =
              combineBitcastToBoolVector(NewSrcVT, Src, DL, DAG, Subtarget))
        return DAG.getNode(ISD::INSERT_SUBVECTOR, DL, VT,
                           Opc == ISD::ANY_EXTEND ? DAG.getUNDEF(VT)
                                                  : DAG.getConstant(0, DL, VT),
                           N0, DAG.getIntPtrConstant(0, DL));
    break;
  }
  case ISD::OR: {
    // If we find suitable sources, we can just move an OR to the vector domain.
    SDValue Src0 = V.getOperand(0);
    SDValue Src1 = V.getOperand(1);
    if (SDValue N0 = combineBitcastToBoolVector(VT, Src0, DL, DAG, Subtarget))
      if (SDValue N1 = combineBitcastToBoolVector(VT, Src1, DL, DAG, Subtarget))
        return DAG.getNode(Opc, DL, VT, N0, N1);
    break;
  }
  case ISD::SHL: {
    // If we find a suitable source, a SHL becomes a KSHIFTL.
    SDValue Src0 = V.getOperand(0);
    if ((VT == MVT::v8i1 && !Subtarget.hasDQI()) ||
        ((VT == MVT::v32i1 || VT == MVT::v64i1) && !Subtarget.hasBWI()))
      break;

    if (auto *Amt = dyn_cast<ConstantSDNode>(V.getOperand(1)))
      if (SDValue N0 = combineBitcastToBoolVector(VT, Src0, DL, DAG, Subtarget))
        return DAG.getNode(
            X86ISD::KSHIFTL, DL, VT, N0,
            DAG.getTargetConstant(Amt->getZExtValue(), DL, MVT::i8));
    break;
  }
  }
  return SDValue();
}

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);
    }
  } else {
    // If we're bitcasting from iX to vXi1, see if the integer originally
    // began as a vXi1 and whether we can remove the bitcast entirely.
    if (VT.isVector() && VT.getScalarType() == MVT::i1 &&
        SrcVT.isScalarInteger() &&
        DAG.getTargetLoweringInfo().isTypeLegal(VT)) {
      if (SDValue V =
              combineBitcastToBoolVector(VT, N0, SDLoc(N), DAG, Subtarget))
        return V;
    }
  }

  // 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);
  }

  // Look for MOVMSK that is maybe truncated and then bitcasted to vXi1.
  // Turn it into a sign bit compare that produces a k-register. This avoids
  // a trip through a GPR.
  if (Subtarget.hasAVX512() && SrcVT.isScalarInteger() &&
      VT.isVector() && VT.getVectorElementType() == MVT::i1 &&
      isPowerOf2_32(VT.getVectorNumElements())) {
    unsigned NumElts = VT.getVectorNumElements();
    SDValue Src = N0;

    // Peek through truncate.
    if (N0.getOpcode() == ISD::TRUNCATE && N0.hasOneUse())
      Src = N0.getOperand(0);

    if (Src.getOpcode() == X86ISD::MOVMSK && Src.hasOneUse()) {
      SDValue MovmskIn = Src.getOperand(0);
      MVT MovmskVT = MovmskIn.getSimpleValueType();
      unsigned MovMskElts = MovmskVT.getVectorNumElements();

      // We allow extra bits of the movmsk to be used since they are known zero.
      // We can't convert a VPMOVMSKB without avx512bw.
      if (MovMskElts <= NumElts &&
          (Subtarget.hasBWI() || MovmskVT.getVectorElementType() != MVT::i8)) {
        EVT IntVT = EVT(MovmskVT).changeVectorElementTypeToInteger();
        MovmskIn = DAG.getBitcast(IntVT, MovmskIn);
        SDLoc dl(N);
        MVT CmpVT = MVT::getVectorVT(MVT::i1, MovMskElts);
        SDValue Cmp = DAG.getSetCC(dl, CmpVT, MovmskIn,
                                   DAG.getConstant(0, dl, IntVT), ISD::SETLT);
        if (EVT(CmpVT) == VT)
          return Cmp;

        // Pad with zeroes up to original VT to replace the zeroes that were
        // being used from the MOVMSK.
        unsigned NumConcats = NumElts / MovMskElts;
        SmallVector<SDValue, 4> Ops(NumConcats, DAG.getConstant(0, dl, CmpVT));
        Ops[0] = Cmp;
        return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, Ops);
      }
    }
  }

  // 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 combineMinMaxReduction(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) {
    SDValue Lo, Hi;
    std::tie(Lo, Hi) = splitVector(MinPos, DAG, DL);
    SrcVT = Lo.getValueType();
    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 combinePredicateReduction(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 {
      // For all_of(setcc(vec,0,eq)) - avoid vXi64 comparisons if we don't have
      // PCMPEQQ (SSE41+), use PCMPEQD instead.
      if (BinOp == ISD::AND && !Subtarget.hasSSE41() &&
          Match.getOpcode() == ISD::SETCC &&
          ISD::isBuildVectorAllZeros(Match.getOperand(1).getNode()) &&
          cast<CondCodeSDNode>(Match.getOperand(2))->get() ==
              ISD::CondCode::SETEQ) {
        SDValue Vec = Match.getOperand(0);
        if (Vec.getValueType().getScalarType() == MVT::i64 &&
            (2 * NumElts) <= MaxElts) {
          NumElts *= 2;
          EVT CmpVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32, NumElts);
          MatchVT = EVT::getVectorVT(*DAG.getContext(), MVT::i1, NumElts);
          Match = DAG.getSetCC(
              DL, MatchVT, DAG.getBitcast(CmpVT, Match.getOperand(0)),
              DAG.getBitcast(CmpVT, Match.getOperand(1)), ISD::CondCode::SETEQ);
        }
      }

      // 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 -> (PARITY(MOVMSK X))
    SDValue Result = DAG.getNode(ISD::PARITY, DL, CmpVT, Movmsk);
    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);
    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 && SrcEltBits == SrcBCWidth) {
      SDValue Load = DAG.getLoad(VT, dl, MemIntr->getChain(),
                                 MemIntr->getBasePtr(),
                                 MemIntr->getPointerInfo(),
                                 MemIntr->getOriginalAlign(),
                                 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() && IdxC == 0 &&
      (SrcVT.getSizeInBits() % 128) == 0) {
    Src = extract128BitVector(Src.getOperand(0), 0, DAG, dl);
    MVT ExtractVT = MVT::getVectorVT(SrcSVT.getSimpleVT(), 128 / SrcEltBits);
    return DAG.getNode(N->getOpcode(), dl, VT, DAG.getBitcast(ExtractVT, Src),
                       Idx);
  }

  // We can only legally extract other elements from 128-bit vectors and in
  // certain circumstances, depending on SSE-level.
  // TODO: Investigate float/double extraction if it will be just stored.
  auto GetLegalExtract = [&Subtarget, &DAG, &dl](SDValue Vec, EVT VecVT,
                                                 unsigned Idx) {
    EVT VecSVT = VecVT.getScalarType();
    if ((VecVT.is256BitVector() || VecVT.is512BitVector()) &&
        (VecSVT == MVT::i8 || VecSVT == MVT::i16 || VecSVT == MVT::i32 ||
         VecSVT == MVT::i64)) {
      unsigned EltSizeInBits = VecSVT.getSizeInBits();
      unsigned NumEltsPerLane = 128 / EltSizeInBits;
      unsigned LaneOffset = (Idx & ~(NumEltsPerLane - 1)) * EltSizeInBits;
      unsigned LaneIdx = LaneOffset / Vec.getScalarValueSizeInBits();
      VecVT = EVT::getVectorVT(*DAG.getContext(), VecSVT, NumEltsPerLane);
      Vec = extract128BitVector(Vec, LaneIdx, DAG, dl);
      Idx &= (NumEltsPerLane - 1);
    }
    if ((VecVT == MVT::v4i32 || VecVT == MVT::v2i64) &&
        ((Idx == 0 && Subtarget.hasSSE2()) || Subtarget.hasSSE41())) {
      return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VecVT.getScalarType(),
                         DAG.getBitcast(VecVT, Vec),
                         DAG.getIntPtrConstant(Idx, dl));
    }
    if ((VecVT == MVT::v8i16 && Subtarget.hasSSE2()) ||
        (VecVT == MVT::v16i8 && Subtarget.hasSSE41())) {
      unsigned OpCode = (VecVT == MVT::v8i16 ? X86ISD::PEXTRW : X86ISD::PEXTRB);
      return DAG.getNode(OpCode, dl, MVT::i32, DAG.getBitcast(VecVT, Vec),
                         DAG.getTargetConstant(Idx, dl, MVT::i8));
    }
    return SDValue();
  };

  // 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();
      narrowShuffleMaskElts(Scale, Mask, ScaledMask);
      Mask = std::move(ScaledMask);
    } else if ((Mask.size() % NumSrcElts) == 0) {
      // Simplify Mask based on demanded element.
      int ExtractIdx = (int)IdxC.getZExtValue();
      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);
    }
  }

  // If narrowing/widening failed, see if we can extract+zero-extend.
  int ExtractIdx;
  EVT ExtractVT;
  if (Mask.size() == NumSrcElts) {
    ExtractIdx = Mask[IdxC.getZExtValue()];
    ExtractVT = SrcVT;
  } else {
    unsigned Scale = Mask.size() / NumSrcElts;
    if ((Mask.size() % NumSrcElts) != 0 || SrcVT.isFloatingPoint())
      return SDValue();
    unsigned ScaledIdx = Scale * IdxC.getZExtValue();
    if (!isUndefOrZeroInRange(Mask, ScaledIdx + 1, Scale - 1))
      return SDValue();
    ExtractIdx = Mask[ScaledIdx];
    EVT ExtractSVT = EVT::getIntegerVT(*DAG.getContext(), SrcEltBits / Scale);
    ExtractVT = EVT::getVectorVT(*DAG.getContext(), ExtractSVT, Mask.size());
    assert(SrcVT.getSizeInBits() == ExtractVT.getSizeInBits() &&
           "Failed to widen vector type");
  }

  // If the shuffle source element is undef/zero then we can just accept it.
  if (ExtractIdx == SM_SentinelUndef)
    return DAG.getUNDEF(VT);

  if (ExtractIdx == SM_SentinelZero)
    return VT.isFloatingPoint() ? DAG.getConstantFP(0.0, dl, VT)
                                : DAG.getConstant(0, dl, VT);

  SDValue SrcOp = Ops[ExtractIdx / Mask.size()];
  ExtractIdx = ExtractIdx % Mask.size();
  if (SDValue V = GetLegalExtract(SrcOp, ExtractVT, ExtractIdx))
    return DAG.getZExtOrTrunc(V, 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 combineArithReduction(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::MUL, 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 mul reduction - promote to vXi16 mul reduction.
  if (Opc == ISD::MUL) {
    unsigned NumElts = VecVT.getVectorNumElements();
    if (VT != MVT::i8 || NumElts < 4 || !isPowerOf2_32(NumElts))
      return SDValue();
    if (VecVT.getSizeInBits() >= 128) {
      EVT WideVT = EVT::getVectorVT(*DAG.getContext(), MVT::i16, NumElts / 2);
      SDValue Lo = getUnpackl(DAG, DL, VecVT, Rdx, DAG.getUNDEF(VecVT));
      SDValue Hi = getUnpackh(DAG, DL, VecVT, Rdx, DAG.getUNDEF(VecVT));
      Lo = DAG.getBitcast(WideVT, Lo);
      Hi = DAG.getBitcast(WideVT, Hi);
      Rdx = DAG.getNode(Opc, DL, WideVT, Lo, Hi);
      while (Rdx.getValueSizeInBits() > 128) {
        std::tie(Lo, Hi) = splitVector(Rdx, DAG, DL);
        Rdx = DAG.getNode(Opc, DL, Lo.getValueType(), Lo, Hi);
      }
    } else {
      if (VecVT == MVT::v4i8)
        Rdx = DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v8i8, Rdx,
                          DAG.getUNDEF(MVT::v4i8));
      Rdx = DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v16i8, Rdx,
                        DAG.getUNDEF(MVT::v8i8));
      Rdx = getUnpackl(DAG, DL, MVT::v16i8, Rdx, DAG.getUNDEF(MVT::v16i8));
      Rdx = DAG.getBitcast(MVT::v8i16, Rdx);
    }
    if (NumElts >= 8)
      Rdx = DAG.getNode(Opc, DL, MVT::v8i16, Rdx,
                        DAG.getVectorShuffle(MVT::v8i16, DL, Rdx, Rdx,
                                             {4, 5, 6, 7, -1, -1, -1, -1}));
    Rdx = DAG.getNode(Opc, DL, MVT::v8i16, Rdx,
                      DAG.getVectorShuffle(MVT::v8i16, DL, Rdx, Rdx,
                                           {2, 3, -1, -1, -1, -1, -1, -1}));
    Rdx = DAG.getNode(Opc, DL, MVT::v8i16, Rdx,
                      DAG.getVectorShuffle(MVT::v8i16, DL, Rdx, Rdx,
                                           {1, -1, -1, -1, -1, -1, -1, -1}));
    Rdx = DAG.getBitcast(MVT::v16i8, Rdx);
    return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, Rdx, Index);
  }

  // vXi8 add 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 add reduction - sum lo/hi halves then use PSADBW.
  if (VT == MVT::i8) {
    while (Rdx.getValueSizeInBits() > 128) {
      SDValue Lo, Hi;
      std::tie(Lo, Hi) = splitVector(Rdx, DAG, DL);
      VecVT = Lo.getValueType();
      Rdx = DAG.getNode(ISD::ADD, DL, VecVT, Lo, Hi);
    }
    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.
  if (!shouldUseHorizontalOp(true, DAG, Subtarget))
    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 combinePredicateReduction 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 = combinePredicateReduction(N, DAG, Subtarget))
    return Cmp;

  // Attempt to replace min/max v8i16/v16i8 reductions with PHMINPOSUW.
  if (SDValue MinMax = combineMinMaxReduction(N, DAG, Subtarget))
    return MinMax;

  // Attempt to optimize ADD/FADD/MUL reductions with HADD, promotion etc..
  if (SDValue V = combineArithReduction(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.
  //
  // Note that we only combine extracts on the *same* result number, i.e.
  //   t0 = merge_values a0, a1, a2, a3
  //   i1 = extract_vector_elt t0, Constant:i64<2>
  //   i1 = extract_vector_elt t0, Constant:i64<3>
  // but not
  //   i1 = extract_vector_elt t0:1, Constant:i64<2>
  // since the latter would need its own MOVMSK.
  if (CIdx && SrcVT.getScalarType() == MVT::i1) {
    SmallVector<SDNode *, 16> BoolExtracts;
    unsigned ResNo = InputVector.getResNo();
    auto IsBoolExtract = [&BoolExtracts, &ResNo](SDNode *Use) {
      if (Use->getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
          isa<ConstantSDNode>(Use->getOperand(1)) &&
          Use->getOperand(0).getResNo() == ResNo &&
          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 (!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) {
    SDValue CastRHS = DAG.getBitcast(CondVT, RHS);
    SDValue AndN;
    // The canonical form differs for i1 vectors - x86andnp is not used
    if (CondVT.getScalarType() == MVT::i1)
      AndN = DAG.getNode(ISD::AND, DL, CondVT, DAG.getNOT(DL, Cond, CondVT),
                         CastRHS);
    else
      AndN = DAG.getNode(X86ISD::ANDNP, DL, CondVT, Cond, 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;
  };

  APInt DemandedBits(APInt::getSignMask(BitWidth));

  if (OnlyUsedAsSelectCond(Cond)) {
    KnownBits Known;
    TargetLowering::TargetLoweringOpt TLO(DAG, !DCI.isBeforeLegalize(),
                                          !DCI.isBeforeLegalizeOps());
    if (!TLI.SimplifyDemandedBits(Cond, DemandedBits, 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.
  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);
  }

  // fold vselect(cond, pshufb(x), pshufb(y)) -> or (pshufb(x), pshufb(y))
  // by forcing the unselected elements to zero.
  // TODO: Can we handle more shuffles with this?
  if (N->getOpcode() == ISD::VSELECT && CondVT.isVector() &&
      LHS.getOpcode() == X86ISD::PSHUFB && RHS.getOpcode() == X86ISD::PSHUFB &&
      LHS.hasOneUse() && RHS.hasOneUse()) {
    MVT SimpleVT = VT.getSimpleVT();
    bool LHSUnary, RHSUnary;
    SmallVector<SDValue, 1> LHSOps, RHSOps;
    SmallVector<int, 64> LHSMask, RHSMask, CondMask;
    if (createShuffleMaskFromVSELECT(CondMask, Cond) &&
        getTargetShuffleMask(LHS.getNode(), SimpleVT, true, LHSOps, LHSMask,
                             LHSUnary) &&
        getTargetShuffleMask(RHS.getNode(), SimpleVT, true, RHSOps, RHSMask,
                             RHSUnary)) {
      int NumElts = VT.getVectorNumElements();
      for (int i = 0; i != NumElts; ++i) {
        if (CondMask[i] < NumElts)
          RHSMask[i] = 0x80;
        else
          LHSMask[i] = 0x80;
      }
      LHS = DAG.getNode(X86ISD::PSHUFB, DL, VT, LHS.getOperand(0),
                        getConstVector(LHSMask, SimpleVT, DAG, DL, true));
      RHS = DAG.getNode(X86ISD::PSHUFB, DL, VT, RHS.getOperand(0),
                        getConstVector(RHSMask, SimpleVT, DAG, DL, true));
      return DAG.getNode(ISD::OR, DL, VT, LHS, RHS);
    }
  }

  // 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();
      EVT SrcCondVT = SrcVT.changeVectorElementType(MVT::i1);
      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 min/max:
  // (x > 0) ? x : 0 -> (x >= 0) ? x : 0
  // (x < -1) ? x : -1 -> (x <= -1) ? x : -1
  // This allows use of COND_S / COND_NS (see TranslateX86CC) which eliminates
  // the need for an extra compare against zero. e.g.
  // (a - b) > 0 : (a - b) ? 0 -> (a - b) >= 0 : (a - b) ? 0
  // subl   %esi, %edi
  // testl  %edi, %edi
  // movl   $0, %eax
  // cmovgl %edi, %eax
  // =>
  // xorl   %eax, %eax
  // subl   %esi, $edi
  // cmovsl %eax, %edi
  //
  // We can also canonicalize
  //  (x s> 1) ? x : 1 -> (x s>= 1) ? x : 1 -> (x s> 0) ? x : 1
  //  (x u> 1) ? x : 1 -> (x u>= 1) ? x : 1 -> (x != 0) ? x : 1
  // This allows the use of a test instruction for the compare.
  if (N->getOpcode() == ISD::SELECT && Cond.getOpcode() == ISD::SETCC &&
      Cond.hasOneUse() &&
      LHS == Cond.getOperand(0) && RHS == Cond.getOperand(1)) {
    ISD::CondCode CC = cast<CondCodeSDNode>(Cond.getOperand(2))->get();
    if ((CC == ISD::SETGT && (isNullConstant(RHS) || isOneConstant(RHS))) ||
        (CC == ISD::SETLT && isAllOnesConstant(RHS))) {
      ISD::CondCode NewCC = CC == ISD::SETGT ? ISD::SETGE : ISD::SETLE;
      Cond = DAG.getSetCC(SDLoc(Cond), Cond.getValueType(),
                          Cond.getOperand(0), Cond.getOperand(1), NewCC);
      return DAG.getSelect(DL, VT, Cond, LHS, RHS);
    }
    if (CC == ISD::SETUGT && isOneConstant(RHS)) {
      ISD::CondCode NewCC = ISD::SETUGE;
      Cond = DAG.getSetCC(SDLoc(Cond), Cond.getValueType(),
                          Cond.getOperand(0), Cond.getOperand(1), NewCC);
      return DAG.getSelect(DL, VT, Cond, LHS, RHS);
    }
  }

  // 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);
    // pcmpgt(X, -1) -> pcmpgt(0, X) to help select/blendv just use the signbit.
    if (Cond.getOpcode() == X86ISD::PCMPGT && Cond.hasOneUse() &&
        ISD::isBuildVectorAllOnes(Cond.getOperand(1).getNode())) {
      Cond = DAG.getNode(X86ISD::PCMPGT, DL, CondVT,
                         DAG.getConstant(0, DL, CondVT), Cond.getOperand(0));
      return DAG.getNode(N->getOpcode(), DL, VT, Cond, 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()))) {
    EVT IntVT = EVT::getIntegerVT(*DAG.getContext(), 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);
    }
  }

  // If this is "((X & C) == 0) ? Y : Z" and C is a constant mask vector of
  // single bits, then invert the predicate and swap the select operands.
  // This can lower using a vector shift bit-hack rather than mask and compare.
  if (DCI.isBeforeLegalize() && !Subtarget.hasAVX512() &&
      N->getOpcode() == ISD::VSELECT && Cond.getOpcode() == ISD::SETCC &&
      Cond.hasOneUse() && CondVT.getVectorElementType() == MVT::i1 &&
      Cond.getOperand(0).getOpcode() == ISD::AND &&
      isNullOrNullSplat(Cond.getOperand(1)) &&
      cast<CondCodeSDNode>(Cond.getOperand(2))->get() == ISD::SETEQ &&
      Cond.getOperand(0).getValueType() == VT) {
    // The 'and' mask must be composed of power-of-2 constants.
    SDValue And = Cond.getOperand(0);
    auto *C = isConstOrConstSplat(And.getOperand(1));
    if (C && C->getAPIntValue().isPowerOf2()) {
      // vselect (X & C == 0), LHS, RHS --> vselect (X & C != 0), RHS, LHS
      SDValue NotCond =
          DAG.getSetCC(DL, CondVT, And, Cond.getOperand(1), ISD::SETNE);
      return DAG.getSelect(DL, VT, NotCond, RHS, LHS);
    }

    // If we have a non-splat but still powers-of-2 mask, AVX1 can use pmulld
    // and AVX2 can use vpsllv{dq}. 8-bit lacks a proper shift or multiply.
    // 16-bit lacks a proper blendv.
    unsigned EltBitWidth = VT.getScalarSizeInBits();
    bool CanShiftBlend =
        TLI.isTypeLegal(VT) && ((Subtarget.hasAVX() && EltBitWidth == 32) ||
                                (Subtarget.hasAVX2() && EltBitWidth == 64) ||
                                (Subtarget.hasXOP()));
    if (CanShiftBlend &&
        ISD::matchUnaryPredicate(And.getOperand(1), [](ConstantSDNode *C) {
          return C->getAPIntValue().isPowerOf2();
        })) {
      // Create a left-shift constant to get the mask bits over to the sign-bit.
      SDValue Mask = And.getOperand(1);
      SmallVector<int, 32> ShlVals;
      for (unsigned i = 0, e = VT.getVectorNumElements(); i != e; ++i) {
        auto *MaskVal = cast<ConstantSDNode>(Mask.getOperand(i));
        ShlVals.push_back(EltBitWidth - 1 -
                          MaskVal->getAPIntValue().exactLogBase2());
      }
      // vsel ((X & C) == 0), LHS, RHS --> vsel ((shl X, C') < 0), RHS, LHS
      SDValue ShlAmt = getConstVector(ShlVals, VT.getSimpleVT(), DAG, DL);
      SDValue Shl = DAG.getNode(ISD::SHL, DL, VT, And.getOperand(0), ShlAmt);
      SDValue NewCond =
          DAG.getSetCC(DL, CondVT, Shl, Cond.getOperand(1), ISD::SETLT);
      return DAG.getSelect(DL, VT, NewCond, RHS, LHS);
    }
  }

  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,
                              const X86Subtarget &Subtarget) {
  // 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);
    }

    if (Op0 == Op1) {
      SDValue BC = peekThroughBitcasts(Op0);
      EVT BCVT = BC.getValueType();
      assert(BCVT.isVector() && DAG.getTargetLoweringInfo().isTypeLegal(BCVT) &&
             "Unexpected vector type");

      // TESTZ(AND(X,Y),AND(X,Y)) == TESTZ(X,Y)
      if (BC.getOpcode() == ISD::AND || BC.getOpcode() == X86ISD::FAND) {
        return DAG.getNode(EFLAGS.getOpcode(), SDLoc(EFLAGS), VT,
                           DAG.getBitcast(OpVT, BC.getOperand(0)),
                           DAG.getBitcast(OpVT, BC.getOperand(1)));
      }

      // TESTZ(AND(~X,Y),AND(~X,Y)) == TESTC(X,Y)
      if (BC.getOpcode() == X86ISD::ANDNP || BC.getOpcode() == X86ISD::FANDN) {
        CC = (CC == X86::COND_E ? X86::COND_B : X86::COND_AE);
        return DAG.getNode(EFLAGS.getOpcode(), SDLoc(EFLAGS), VT,
                           DAG.getBitcast(OpVT, BC.getOperand(0)),
                           DAG.getBitcast(OpVT, BC.getOperand(1)));
      }

      // If every element is an all-sign value, see if we can use MOVMSK to
      // more efficiently extract the sign bits and compare that.
      // TODO: Handle TESTC with comparison inversion.
      // TODO: Can we remove SimplifyMultipleUseDemandedBits and rely on
      // MOVMSK combines to make sure its never worse than PTEST?
      unsigned EltBits = BCVT.getScalarSizeInBits();
      if (DAG.ComputeNumSignBits(BC) == EltBits) {
        assert(VT == MVT::i32 && "Expected i32 EFLAGS comparison result");
        APInt SignMask = APInt::getSignMask(EltBits);
        const TargetLowering &TLI = DAG.getTargetLoweringInfo();
        if (SDValue Res =
                TLI.SimplifyMultipleUseDemandedBits(BC, SignMask, DAG)) {
          // For vXi16 cases we need to use pmovmksb and extract every other
          // sign bit.
          SDLoc DL(EFLAGS);
          if (EltBits == 16) {
            MVT MovmskVT = BCVT.is128BitVector() ? MVT::v16i8 : MVT::v32i8;
            Res = DAG.getBitcast(MovmskVT, Res);
            Res = getPMOVMSKB(DL, Res, DAG, Subtarget);
            Res = DAG.getNode(ISD::AND, DL, MVT::i32, Res,
                              DAG.getConstant(0xAAAAAAAA, DL, MVT::i32));
          } else {
            Res = getPMOVMSKB(DL, Res, DAG, Subtarget);
          }
          return DAG.getNode(X86ISD::CMP, DL, MVT::i32, Res,
                             DAG.getConstant(0, DL, MVT::i32));
        }
      }
    }

    // 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();
}

// Attempt to simplify the MOVMSK input based on the comparison type.
static SDValue combineSetCCMOVMSK(SDValue EFLAGS, X86::CondCode &CC,
                                  SelectionDAG &DAG,
                                  const X86Subtarget &Subtarget) {
  // Handle eq/ne against zero (any_of).
  // Handle eq/ne against -1 (all_of).
  if (!(CC == X86::COND_E || CC == X86::COND_NE))
    return SDValue();
  if (EFLAGS.getValueType() != MVT::i32)
    return SDValue();
  unsigned CmpOpcode = EFLAGS.getOpcode();
  if (CmpOpcode != X86ISD::CMP && CmpOpcode != X86ISD::SUB)
    return SDValue();
  auto *CmpConstant = dyn_cast<ConstantSDNode>(EFLAGS.getOperand(1));
  if (!CmpConstant)
    return SDValue();
  const APInt &CmpVal = CmpConstant->getAPIntValue();

  SDValue CmpOp = EFLAGS.getOperand(0);
  unsigned CmpBits = CmpOp.getValueSizeInBits();
  assert(CmpBits == CmpVal.getBitWidth() && "Value size mismatch");

  // Peek through any truncate.
  if (CmpOp.getOpcode() == ISD::TRUNCATE)
    CmpOp = CmpOp.getOperand(0);

  // Bail if we don't find a MOVMSK.
  if (CmpOp.getOpcode() != X86ISD::MOVMSK)
    return SDValue();

  SDValue Vec = CmpOp.getOperand(0);
  MVT VecVT = Vec.getSimpleValueType();
  assert((VecVT.is128BitVector() || VecVT.is256BitVector()) &&
         "Unexpected MOVMSK operand");
  unsigned NumElts = VecVT.getVectorNumElements();
  unsigned NumEltBits = VecVT.getScalarSizeInBits();

  bool IsAnyOf = CmpOpcode == X86ISD::CMP && CmpVal.isNullValue();
  bool IsAllOf = CmpOpcode == X86ISD::SUB && NumElts <= CmpBits &&
                 CmpVal.isMask(NumElts);
  if (!IsAnyOf && !IsAllOf)
    return SDValue();

  // See if we can peek through to a vector with a wider element type, if the
  // signbits extend down to all the sub-elements as well.
  // Calling MOVMSK with the wider type, avoiding the bitcast, helps expose
  // potential SimplifyDemandedBits/Elts cases.
  if (Vec.getOpcode() == ISD::BITCAST) {
    SDValue BC = peekThroughBitcasts(Vec);
    MVT BCVT = BC.getSimpleValueType();
    unsigned BCNumElts = BCVT.getVectorNumElements();
    unsigned BCNumEltBits = BCVT.getScalarSizeInBits();
    if ((BCNumEltBits == 32 || BCNumEltBits == 64) &&
        BCNumEltBits > NumEltBits &&
        DAG.ComputeNumSignBits(BC) > (BCNumEltBits - NumEltBits)) {
      SDLoc DL(EFLAGS);
      unsigned CmpMask = IsAnyOf ? 0 : ((1 << BCNumElts) - 1);
      return DAG.getNode(X86ISD::CMP, DL, MVT::i32,
                         DAG.getNode(X86ISD::MOVMSK, DL, MVT::i32, BC),
                         DAG.getConstant(CmpMask, DL, MVT::i32));
    }
  }

  // MOVMSK(PCMPEQ(X,0)) == -1 -> PTESTZ(X,X).
  // MOVMSK(PCMPEQ(X,0)) != -1 -> !PTESTZ(X,X).
  if (IsAllOf && Subtarget.hasSSE41()) {
    SDValue BC = peekThroughBitcasts(Vec);
    if (BC.getOpcode() == X86ISD::PCMPEQ &&
        ISD::isBuildVectorAllZeros(BC.getOperand(1).getNode())) {
      MVT TestVT = VecVT.is128BitVector() ? MVT::v2i64 : MVT::v4i64;
      SDValue V = DAG.getBitcast(TestVT, BC.getOperand(0));
      return DAG.getNode(X86ISD::PTEST, SDLoc(EFLAGS), MVT::i32, V, V);
    }
  }

  // See if we can avoid a PACKSS by calling MOVMSK on the sources.
  // For vXi16 cases we can use a v2Xi8 PMOVMSKB. We must mask out
  // sign bits prior to the comparison with zero unless we know that
  // the vXi16 splats the sign bit down to the lower i8 half.
  // TODO: Handle all_of patterns.
  if (Vec.getOpcode() == X86ISD::PACKSS && VecVT == MVT::v16i8) {
    SDValue VecOp0 = Vec.getOperand(0);
    SDValue VecOp1 = Vec.getOperand(1);
    bool SignExt0 = DAG.ComputeNumSignBits(VecOp0) > 8;
    bool SignExt1 = DAG.ComputeNumSignBits(VecOp1) > 8;
    // PMOVMSKB(PACKSSBW(X, undef)) -> PMOVMSKB(BITCAST_v16i8(X)) & 0xAAAA.
    if (IsAnyOf && CmpBits == 8 && VecOp1.isUndef()) {
      SDLoc DL(EFLAGS);
      SDValue Result = DAG.getBitcast(MVT::v16i8, VecOp0);
      Result = DAG.getNode(X86ISD::MOVMSK, DL, MVT::i32, Result);
      Result = DAG.getZExtOrTrunc(Result, DL, MVT::i16);
      if (!SignExt0) {
        Result = DAG.getNode(ISD::AND, DL, MVT::i16, Result,
                             DAG.getConstant(0xAAAA, DL, MVT::i16));
      }
      return DAG.getNode(X86ISD::CMP, DL, MVT::i32, Result,
                         DAG.getConstant(0, DL, MVT::i16));
    }
    // PMOVMSKB(PACKSSBW(LO(X), HI(X)))
    // -> PMOVMSKB(BITCAST_v32i8(X)) & 0xAAAAAAAA.
    if (CmpBits == 16 && Subtarget.hasInt256() &&
        VecOp0.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
        VecOp1.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
        VecOp0.getOperand(0) == VecOp1.getOperand(0) &&
        VecOp0.getConstantOperandAPInt(1) == 0 &&
        VecOp1.getConstantOperandAPInt(1) == 8 &&
        (IsAnyOf || (SignExt0 && SignExt1))) {
      SDLoc DL(EFLAGS);
      SDValue Result = DAG.getBitcast(MVT::v32i8, VecOp0.getOperand(0));
      Result = DAG.getNode(X86ISD::MOVMSK, DL, MVT::i32, Result);
      unsigned CmpMask = IsAnyOf ? 0 : 0xFFFFFFFF;
      if (!SignExt0 || !SignExt1) {
        assert(IsAnyOf && "Only perform v16i16 signmasks for any_of patterns");
        Result = DAG.getNode(ISD::AND, DL, MVT::i32, Result,
                             DAG.getConstant(0xAAAAAAAA, DL, MVT::i32));
      }
      return DAG.getNode(X86ISD::CMP, DL, MVT::i32, Result,
                         DAG.getConstant(CmpMask, DL, MVT::i32));
    }
  }

  // MOVMSK(SHUFFLE(X,u)) -> MOVMSK(X) iff every element is referenced.
  SmallVector<int, 32> ShuffleMask;
  SmallVector<SDValue, 2> ShuffleInputs;
  if (NumElts == CmpBits &&
      getTargetShuffleInputs(peekThroughBitcasts(Vec), ShuffleInputs,
                             ShuffleMask, DAG) &&
      ShuffleInputs.size() == 1 && !isAnyZeroOrUndef(ShuffleMask) &&
      ShuffleInputs[0].getValueSizeInBits() == VecVT.getSizeInBits()) {
    unsigned NumShuffleElts = ShuffleMask.size();
    APInt DemandedElts = APInt::getNullValue(NumShuffleElts);
    for (int M : ShuffleMask) {
      assert(0 <= M && M < (int)NumShuffleElts && "Bad unary shuffle index");
      DemandedElts.setBit(M);
    }
    if (DemandedElts.isAllOnesValue()) {
      SDLoc DL(EFLAGS);
      SDValue Result = DAG.getBitcast(VecVT, ShuffleInputs[0]);
      Result = DAG.getNode(X86ISD::MOVMSK, DL, MVT::i32, Result);
      Result =
          DAG.getZExtOrTrunc(Result, DL, EFLAGS.getOperand(0).getValueType());
      return DAG.getNode(X86ISD::CMP, DL, MVT::i32, Result,
                         EFLAGS.getOperand(1));
    }
  }

  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, Subtarget))
    return R;

  if (SDValue R = combineSetCCMOVMSK(EFLAGS, CC, DAG, Subtarget))
    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 = VT.changeVectorElementType(MVT::i16);

  // 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 type is legal or will be widened to a legal type.
  if (VT != MVT::v2i32 && !DAG.getTargetLoweringInfo().isTypeLegal(VT))
    return SDValue();

  MVT WVT = MVT::getVectorVT(MVT::i16, 2 * VT.getVectorNumElements());

  // Without BWI, we would need to split v32i16.
  if (WVT == MVT::v32i16 && !Subtarget.hasBWI())
    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;
}

// Try to form a MULHU or MULHS node by looking for
// (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 combineShiftToPMULH(SDNode *N, SelectionDAG &DAG,
                                   const X86Subtarget &Subtarget) {
  assert((N->getOpcode() == ISD::SRL || N->getOpcode() == ISD::SRA) &&
           "SRL or SRA node is required here!");
  SDLoc DL(N);

  // Only do this with SSE4.1. On earlier targets reduceVMULWidth will expand
  // the multiply.
  if (!Subtarget.hasSSE41())
    return SDValue();

  // The operation feeding into the shift must be a multiply.
  SDValue ShiftOperand = N->getOperand(0);
  if (ShiftOperand.getOpcode() != ISD::MUL || !ShiftOperand.hasOneUse())
    return SDValue();

  // Input type should be at least vXi32.
  EVT VT = N->getValueType(0);
  if (!VT.isVector() || VT.getVectorElementType().getSizeInBits() < 32)
    return SDValue();

  // Need a shift by 16.
  APInt ShiftAmt;
  if (!ISD::isConstantSplatVector(N->getOperand(1).getNode(), ShiftAmt) ||
      ShiftAmt != 16)
    return SDValue();

  SDValue LHS = ShiftOperand.getOperand(0);
  SDValue RHS = ShiftOperand.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.
  EVT MulVT = LHS.getValueType();
  if (MulVT.getVectorElementType() != MVT::i16 || RHS.getValueType() != MulVT)
    return SDValue();

  unsigned Opc = ExtOpc == ISD::SIGN_EXTEND ? ISD::MULHS : ISD::MULHU;
  SDValue Mulh = DAG.getNode(Opc, DL, MulVT, LHS, RHS);

  ExtOpc = N->getOpcode() == ISD::SRA ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
  return DAG.getNode(ExtOpc, DL, VT, Mulh);
}

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,
                                           const X86Subtarget &Subtarget) {
  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);
  EVT VT = N0.getValueType();
  unsigned Size = VT.getSizeInBits();

  if (SDValue V = combineShiftToPMULH(N, DAG, Subtarget))
    return V;

  // 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,
                                        const X86Subtarget &Subtarget) {
  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);
  EVT VT = N0.getValueType();

  if (SDValue V = combineShiftToPMULH(N, DAG, Subtarget))
    return V;

  // 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 combineHorizOpWithShuffle(SDNode *N, SelectionDAG &DAG,
                                         const X86Subtarget &Subtarget) {
  unsigned Opcode = N->getOpcode();
  assert((X86ISD::HADD == Opcode || X86ISD::FHADD == Opcode ||
          X86ISD::HSUB == Opcode || X86ISD::FHSUB == Opcode ||
          X86ISD::PACKSS == Opcode || X86ISD::PACKUS == Opcode) &&
         "Unexpected hadd/hsub/pack opcode");

  EVT VT = N->getValueType(0);
  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);
  EVT SrcVT = N0.getValueType();

  // Attempt to fold HOP(LOSUBVECTOR(SHUFFLE(X)),HISUBVECTOR(SHUFFLE(X)))
  // to SHUFFLE(HOP(LOSUBVECTOR(X),HISUBVECTOR(X))), this is mainly for
  // truncation trees that help us avoid lane crossing shuffles.
  // TODO: There's a lot more we can do for PACK/HADD style shuffle combines.
  // TODO: We don't handle vXf64 shuffles yet.
  if (N0.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
      N1.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
      N0.getConstantOperandAPInt(1) == 0 &&
      N1.getConstantOperandAPInt(1) == SrcVT.getVectorNumElements() &&
      N0.getOperand(0) == N1.getOperand(0) && VT.is128BitVector() &&
      N0.getOperand(0).getValueType().is256BitVector() &&
      SrcVT.getScalarSizeInBits() <= 32) {
    // TODO - support target/faux shuffles.
    SDValue Vec = peekThroughBitcasts(N0.getOperand(0));
    if (auto *SVN = dyn_cast<ShuffleVectorSDNode>(Vec)) {
      // To keep the HOP LHS/RHS coherency, we must be able to scale the unary
      // shuffle to a vXi64 width - we can probably relax this in the future.
      SmallVector<int, 4> ShuffleMask;
      if (SVN->getOperand(1).isUndef() &&
          scaleShuffleElements(SVN->getMask(), 4, ShuffleMask)) {
        SDLoc DL(N);
        SDValue Lo, Hi;
        MVT ShufVT = VT.isFloatingPoint() ? MVT::v4f32 : MVT::v4i32;
        std::tie(Lo, Hi) = DAG.SplitVector(SVN->getOperand(0), DL);
        Lo = DAG.getBitcast(N0.getValueType(), Lo);
        Hi = DAG.getBitcast(N1.getValueType(), Hi);
        SDValue Res = DAG.getNode(Opcode, DL, VT, Lo, Hi);
        Res = DAG.getBitcast(ShufVT, Res);
        Res = DAG.getVectorShuffle(ShufVT, DL, Res, Res, ShuffleMask);
        return DAG.getBitcast(VT, Res);
      }
    }
  }

  // Attempt to fold HOP(SHUFFLE(X),SHUFFLE(Y)) -> SHUFFLE(HOP(X,Y)).
  // TODO: Merge with binary shuffle folds below.
  if (VT.is128BitVector() && SrcVT.getScalarSizeInBits() <= 32) {
    int PostShuffle[4] = {0, 1, 2, 3};

    // If the op is an unary shuffle that can scale to v2x64,
    // then we can perform this as a v4x32 post shuffle.
    auto AdjustOp = [&](SDValue V, int Offset) {
      auto *SVN = dyn_cast<ShuffleVectorSDNode>(V);
      SmallVector<int, 2> ScaledMask;
      if (!SVN || !SVN->getOperand(1).isUndef() ||
          !scaleShuffleElements(SVN->getMask(), 2, ScaledMask) ||
          !N->isOnlyUserOf(V.getNode()))
        return SDValue();
      PostShuffle[Offset + 0] = ScaledMask[0] < 0 ? -1 : Offset + ScaledMask[0];
      PostShuffle[Offset + 1] = ScaledMask[1] < 0 ? -1 : Offset + ScaledMask[1];
      return SVN->getOperand(0);
    };

    SDValue Src0 = AdjustOp(N0, 0);
    SDValue Src1 = AdjustOp(N1, 2);
    if (Src0 || Src1) {
      Src0 = Src0 ? Src0 : N0;
      Src1 = Src1 ? Src1 : N1;
      SDLoc DL(N);
      MVT ShufVT = VT.isFloatingPoint() ? MVT::v4f32 : MVT::v4i32;
      SDValue Res = DAG.getNode(Opcode, DL, VT, Src0, Src1);
      Res = DAG.getBitcast(ShufVT, Res);
      Res = DAG.getVectorShuffle(ShufVT, DL, Res, Res, PostShuffle);
      return DAG.getBitcast(VT, Res);
    }
  }

  // Attempt to fold HOP(SHUFFLE(X,Y),SHUFFLE(X,Y)) -> SHUFFLE(HOP(X,Y)).
  // TODO: Relax shuffle scaling to support sub-128-bit subvector shuffles.
  if (VT.is256BitVector() && Subtarget.hasInt256()) {
    SmallVector<int> Mask0, Mask1;
    SmallVector<SDValue> Ops0, Ops1;
    if (getTargetShuffleInputs(N0, Ops0, Mask0, DAG) && !isAnyZero(Mask0) &&
        getTargetShuffleInputs(N1, Ops1, Mask1, DAG) && !isAnyZero(Mask1) &&
        !Ops0.empty() && !Ops1.empty()) {
      SDValue Op00 = Ops0.front(), Op01 = Ops0.back();
      SDValue Op10 = Ops1.front(), Op11 = Ops1.back();
      SmallVector<int, 2> ShuffleMask0, ShuffleMask1;
      if (Op00.getValueType() == SrcVT && Op01.getValueType() == SrcVT &&
          Op10.getValueType() == SrcVT && Op11.getValueType() == SrcVT &&
          scaleShuffleElements(Mask0, 2, ShuffleMask0) &&
          scaleShuffleElements(Mask1, 2, ShuffleMask1)) {
        if ((Op00 == Op11) && (Op01 == Op10)) {
          std::swap(Op10, Op11);
          ShuffleVectorSDNode::commuteMask(ShuffleMask1);
        }
        if ((Op00 == Op10) && (Op01 == Op11)) {
          SmallVector<int, 4> ShuffleMask;
          ShuffleMask.append(ShuffleMask0.begin(), ShuffleMask0.end());
          ShuffleMask.append(ShuffleMask1.begin(), ShuffleMask1.end());
          SDLoc DL(N);
          MVT ShufVT = VT.isFloatingPoint() ? MVT::v4f64 : MVT::v4i64;
          SDValue Res = DAG.getNode(Opcode, DL, VT, Op00, Op01);
          Res = DAG.getBitcast(ShufVT, Res);
          Res = DAG.getVectorShuffle(ShufVT, DL, Res, Res, ShuffleMask);
          return DAG.getBitcast(VT, Res);
        }
      }
    }
  }

  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 pack opcode");

  EVT VT = N->getValueType(0);
  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);
  unsigned NumDstElts = VT.getVectorNumElements();
  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 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 fold PACK(SHUFFLE(),SHUFFLE()) -> SHUFFLE(PACK()).
  if (SDValue V = combineHorizOpWithShuffle(N, DAG, Subtarget))
    return V;

  // 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);
    }
  }

  // Try to fold PACK(EXTEND(X),EXTEND(Y)) -> CONCAT(X,Y) subvectors.
  if (VT.is128BitVector()) {
    unsigned ExtOpc = IsSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
    SDValue Src0, Src1;
    if (N0.getOpcode() == ExtOpc &&
        N0.getOperand(0).getValueType().is64BitVector() &&
        N0.getOperand(0).getScalarValueSizeInBits() == DstBitsPerElt) {
      Src0 = N0.getOperand(0);
    }
    if (N1.getOpcode() == ExtOpc &&
        N1.getOperand(0).getValueType().is64BitVector() &&
        N1.getOperand(0).getScalarValueSizeInBits() == DstBitsPerElt) {
      Src1 = N1.getOperand(0);
    }
    if ((Src0 || N0.isUndef()) && (Src1 || N1.isUndef())) {
      assert((Src0 || Src1) && "Found PACK(UNDEF,UNDEF)");
      Src0 = Src0 ? Src0 : DAG.getUNDEF(Src1.getValueType());
      Src1 = Src1 ? Src1 : DAG.getUNDEF(Src0.getValueType());
      return DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(N), VT, Src0, Src1);
    }
  }

  // Attempt to combine as shuffle.
  SDValue Op(N, 0);
  if (SDValue Res = combineX86ShufflesRecursively(Op, DAG, Subtarget))
    return Res;

  return SDValue();
}

static SDValue combineVectorHADDSUB(SDNode *N, SelectionDAG &DAG,
                                    TargetLowering::DAGCombinerInfo &DCI,
                                    const X86Subtarget &Subtarget) {
  assert((X86ISD::HADD == N->getOpcode() || X86ISD::FHADD == N->getOpcode() ||
          X86ISD::HSUB == N->getOpcode() || X86ISD::FHSUB == N->getOpcode()) &&
         "Unexpected horizontal add/sub opcode");

  // Try to fold HOP(SHUFFLE(),SHUFFLE()) -> SHUFFLE(HOP()).
  if (SDValue V = combineHorizOpWithShuffle(N, DAG, Subtarget))
    return V;

  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);
    ShiftVal = NumBitsPerElt - 1;
  }

  // (shift X, 0) -> X
  if (!ShiftVal)
    return N0;

  // (shift 0, C) -> 0
  if (ISD::isBuildVectorAllZeros(N0.getNode()))
    // N0 is all zeros or undef. We guarantee that the bits shifted into the
    // result are all zeros, not undef.
    return DAG.getConstant(0, SDLoc(N), VT);

  // (VSRAI -1, C) -> -1
  if (!LogicalShift && ISD::isBuildVectorAllOnes(N0.getNode()))
    // N0 is all ones or undef. We guarantee that the bits shifted into the
    // result are all ones, not undef.
    return DAG.getConstant(-1, SDLoc(N), VT);

  // (shift (shift X, C2), C1) -> (shift X, (C1 + C2))
  if (Opcode == N0.getOpcode()) {
    unsigned ShiftVal2 = cast<ConstantSDNode>(N0.getOperand(1))->getZExtValue();
    unsigned NewShiftVal = ShiftVal + ShiftVal2;
    if (NewShiftVal >= NumBitsPerElt) {
      // Out of range logical bit shifts are guaranteed to be zero.
      // Out of range arithmetic bit shifts splat the sign bit.
      if (LogicalShift)
        return DAG.getConstant(0, SDLoc(N), VT);
      NewShiftVal = NumBitsPerElt - 1;
    }
    return DAG.getNode(Opcode, 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");
    // Undef elements need to fold to 0. It's possible SimplifyDemandedBits
    // created an undef input due to no input bits being demanded, but user
    // still expects 0 in other bits.
    for (unsigned i = 0, e = EltBits.size(); i != e; ++i) {
      APInt &Elt = EltBits[i];
      if (UndefElts[i])
        Elt = 0;
      else if (X86ISD::VSHLI == Opcode)
        Elt <<= ShiftVal;
      else if (X86ISD::VSRAI == Opcode)
        Elt.ashrInPlace(ShiftVal);
      else
        Elt.lshrInPlace(ShiftVal);
    }
    // Reset undef elements since they were zeroed above.
    UndefElts = 0;
    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);

  auto GetNot = [&VT, &DAG](SDValue V) {
    // Basic X = NOT(Y) detection.
    if (SDValue Not = IsNOT(V, DAG))
      return Not;
    // Fold BROADCAST(NOT(Y)) -> BROADCAST(Y).
    if (V.getOpcode() == X86ISD::VBROADCAST) {
      SDValue Src = V.getOperand(0);
      EVT SrcVT = Src.getValueType();
      if (!SrcVT.isVector())
        return SDValue();
      if (SDValue Not = IsNOT(Src, DAG))
        return DAG.getNode(X86ISD::VBROADCAST, SDLoc(V), VT,
                           DAG.getBitcast(SrcVT, Not));
    }
    return SDValue();
  };

  if (SDValue Not = GetNot(N0)) {
    X = Not;
    Y = N1;
  } else if (SDValue Not = GetNot(N1)) {
    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);
  case ISD::SIGN_EXTEND:
    return DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT,
                       Op, DAG.getValueType(NarrowVT));
  }
}

static unsigned convertIntLogicToFPLogicOpcode(unsigned Opcode) {
  unsigned FPOpcode;
  switch (Opcode) {
  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;
  }
  return FPOpcode;
}

/// 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 = convertIntLogicToFPLogicOpcode(N->getOpcode());
  SDValue FPLogic = DAG.getNode(FPOpcode, DL, N00Type, N00, N10);
  return DAG.getBitcast(VT, FPLogic);
}

// Attempt to fold BITOP(MOVMSK(X),MOVMSK(Y)) -> MOVMSK(BITOP(X,Y))
// to reduce XMM->GPR traffic.
static SDValue combineBitOpWithMOVMSK(SDNode *N, SelectionDAG &DAG) {
  unsigned Opc = N->getOpcode();
  assert((Opc == ISD::OR || Opc == ISD::AND || Opc == ISD::XOR) &&
         "Unexpected bit opcode");

  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);

  // Both operands must be single use MOVMSK.
  if (N0.getOpcode() != X86ISD::MOVMSK || !N0.hasOneUse() ||
      N1.getOpcode() != X86ISD::MOVMSK || !N1.hasOneUse())
    return SDValue();

  SDValue Vec0 = N0.getOperand(0);
  SDValue Vec1 = N1.getOperand(0);
  EVT VecVT0 = Vec0.getValueType();
  EVT VecVT1 = Vec1.getValueType();

  // Both MOVMSK operands must be from vectors of the same size and same element
  // size, but its OK for a fp/int diff.
  if (VecVT0.getSizeInBits() != VecVT1.getSizeInBits() ||
      VecVT0.getScalarSizeInBits() != VecVT1.getScalarSizeInBits())
    return SDValue();

  SDLoc DL(N);
  unsigned VecOpc =
      VecVT0.isFloatingPoint() ? convertIntLogicToFPLogicOpcode(Opc) : Opc;
  SDValue Result =
      DAG.getNode(VecOpc, DL, VecVT0, Vec0, DAG.getBitcast(VecVT0, Vec1));
  return DAG.getNode(X86ISD::MOVMSK, DL, MVT::i32, Result);
}

/// 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 (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));
    }
  }

  // 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 (SDValue R = combineBitOpWithMOVMSK(N, DAG))
    return R;

  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, [](const 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,
              X86::MaxShuffleCombineDepth,
              /*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);

  if (UseVPTERNLOG) {
    // Emit a VPTERNLOG node directly.
    SDValue A = DAG.getBitcast(VT, N0.getOperand(1));
    SDValue B = DAG.getBitcast(VT, N0.getOperand(0));
    SDValue C = DAG.getBitcast(VT, N1.getOperand(0));
    SDValue Imm = DAG.getTargetConstant(0xCA, DL, MVT::i8);
    return DAG.getNode(X86ISD::VPTERNLOG, DL, VT, A, B, C, Imm);
  }

  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();

  // If we have VPTERNLOG we should prefer that since PBLENDVB is multiple uops.
  if (Subtarget.hasVLX())
    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 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 (SDValue R = combineBitOpWithMOVMSK(N, DAG))
    return R;

  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;

  // Combine OR(X,KSHIFTL(Y,Elts/2)) -> CONCAT_VECTORS(X,Y) == KUNPCK(X,Y).
  // Combine OR(KSHIFTL(X,Elts/2),Y) -> CONCAT_VECTORS(Y,X) == KUNPCK(Y,X).
  // iff the upper elements of the non-shifted arg are zero.
  // KUNPCK require 16+ bool vector elements.
  if (N0.getOpcode() == X86ISD::KSHIFTL || N1.getOpcode() == X86ISD::KSHIFTL) {
    unsigned NumElts = VT.getVectorNumElements();
    unsigned HalfElts = NumElts / 2;
    APInt UpperElts = APInt::getHighBitsSet(NumElts, HalfElts);
    if (NumElts >= 16 && N1.getOpcode() == X86ISD::KSHIFTL &&
        N1.getConstantOperandAPInt(1) == HalfElts &&
        DAG.MaskedValueIsZero(N0, APInt(1, 1), UpperElts)) {
      SDLoc dl(N);
      return DAG.getNode(
          ISD::CONCAT_VECTORS, dl, VT,
          extractSubVector(N0, 0, DAG, dl, HalfElts),
          extractSubVector(N1.getOperand(0), 0, DAG, dl, HalfElts));
    }
    if (NumElts >= 16 && N0.getOpcode() == X86ISD::KSHIFTL &&
        N0.getConstantOperandAPInt(1) == HalfElts &&
        DAG.MaskedValueIsZero(N1, APInt(1, 1), UpperElts)) {
      SDLoc dl(N);
      return DAG.getNode(
          ISD::CONCAT_VECTORS, dl, VT,
          extractSubVector(N1, 0, DAG, dl, HalfElts),
          extractSubVector(N0.getOperand(0), 0, DAG, dl, HalfElts));
    }
  }

  // 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 = VT.changeVectorElementType(MVT::i16);
        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))
    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.getFixedSizeInBits() <= ScalarVT.getFixedSizeInBits())
    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) {
    return ISD::matchUnaryPredicate(V, [Min, Max](ConstantSDNode *C) {
      return !(C->getAPIntValue().ult(Min) || C->getAPIntValue().ugt(Max));
    });
  };

  // Check if each element of the vector is right-shifted by one.
  SDValue LHS = In.getOperand(0);
  SDValue 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);
  };

  auto AVGSplitter = [&](SDValue Op0, SDValue Op1) {
    // Pad to a power-of-2 vector, split+apply and extract the original vector.
    unsigned NumElemsPow2 = PowerOf2Ceil(NumElems);
    EVT Pow2VT = EVT::getVectorVT(*DAG.getContext(), ScalarVT, NumElemsPow2);
    if (NumElemsPow2 != NumElems) {
      SmallVector<SDValue, 32> Ops0(NumElemsPow2, DAG.getUNDEF(ScalarVT));
      SmallVector<SDValue, 32> Ops1(NumElemsPow2, DAG.getUNDEF(ScalarVT));
      for (unsigned i = 0; i != NumElems; ++i) {
        SDValue Idx = DAG.getIntPtrConstant(i, DL);
        Ops0[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ScalarVT, Op0, Idx);
        Ops1[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ScalarVT, Op1, Idx);
      }
      Op0 = DAG.getBuildVector(Pow2VT, DL, Ops0);
      Op1 = DAG.getBuildVector(Pow2VT, DL, Ops1);
    }
    SDValue Res =
        SplitOpsAndApply(DAG, Subtarget, DL, Pow2VT, {Op0, Op1}, AVGBuilder);
    if (NumElemsPow2 == NumElems)
      return Res;
    return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, VT, Res,
                       DAG.getIntPtrConstant(0, DL));
  };

  // 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 AVGSplitter(Operands[0].getOperand(0), Operands[1]);
  }

  // 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 AVGSplitter(Operands[0], Operands[1]);
  }

  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;
  if (RegVT.is256BitVector() && !DCI.isBeforeLegalizeOps() &&
      Ext == ISD::NON_EXTLOAD &&
      ((Ld->isNonTemporal() && !Subtarget.hasInt256() &&
        Ld->getAlignment() >= 16) ||
       (TLI.allowsMemoryAccess(*DAG.getContext(), DAG.getDataLayout(), RegVT,
                               *Ld->getMemOperand(), &Fast) &&
        !Fast))) {
    unsigned NumElems = RegVT.getVectorNumElements();
    if (NumElems < 2)
      return SDValue();

    unsigned HalfOffset = 16;
    SDValue Ptr1 = Ld->getBasePtr();
    SDValue Ptr2 =
        DAG.getMemBasePlusOffset(Ptr1, TypeSize::Fixed(HalfOffset), dl);
    EVT HalfVT = EVT::getVectorVT(*DAG.getContext(), MemVT.getScalarType(),
                                  NumElems / 2);
    SDValue Load1 =
        DAG.getLoad(HalfVT, dl, Ld->getChain(), Ptr1, Ld->getPointerInfo(),
                    Ld->getOriginalAlign(),
                    Ld->getMemOperand()->getFlags());
    SDValue Load2 = DAG.getLoad(HalfVT, dl, Ld->getChain(), Ptr2,
                                Ld->getPointerInfo().getWithOffset(HalfOffset),
                                Ld->getOriginalAlign(),
                                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(),
                                    Ld->getOriginalAlign(),
                                    Ld->getMemOperand()->getFlags());
      SDValue BoolVec = DAG.getBitcast(RegVT, IntLoad);
      return DCI.CombineTo(N, BoolVec, IntLoad.getValue(1), true);
    }
  }

  // If we also broadcast this as a subvector to a wider type, then just extract
  // the lowest subvector.
  if (Ext == ISD::NON_EXTLOAD && Subtarget.hasAVX() && Ld->isSimple() &&
      (RegVT.is128BitVector() || RegVT.is256BitVector())) {
    SDValue Ptr = Ld->getBasePtr();
    SDValue Chain = Ld->getChain();
    for (SDNode *User : Ptr->uses()) {
      if (User != N && User->getOpcode() == X86ISD::SUBV_BROADCAST_LOAD &&
          cast<MemIntrinsicSDNode>(User)->getBasePtr() == Ptr &&
          cast<MemIntrinsicSDNode>(User)->getChain() == Chain &&
          cast<MemIntrinsicSDNode>(User)->getMemoryVT().getSizeInBits() ==
              MemVT.getSizeInBits() &&
          !User->hasAnyUseOfValue(1) &&
          User->getValueSizeInBits(0).getFixedSize() >
              RegVT.getFixedSizeInBits()) {
        SDValue Extract = extractSubVector(SDValue(User, 0), 0, DAG, SDLoc(N),
                                           RegVT.getSizeInBits());
        Extract = DAG.getBitcast(RegVT, Extract);
        return DCI.CombineTo(N, Extract, SDValue(User, 1));
      }
    }
  }

  // Cast ptr32 and ptr64 pointers to the default address space before a load.
  unsigned AddrSpace = Ld->getAddressSpace();
  if (AddrSpace == X86AS::PTR64 || AddrSpace == X86AS::PTR32_SPTR ||
      AddrSpace == X86AS::PTR32_UPTR) {
    MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
    if (PtrVT != Ld->getBasePtr().getSimpleValueType()) {
      SDValue Cast =
          DAG.getAddrSpaceCast(dl, PtrVT, Ld->getBasePtr(), AddrSpace, 0);
      return DAG.getLoad(RegVT, dl, Ld->getChain(), Cast, Ld->getPointerInfo(),
                         Ld->getOriginalAlign(),
                         Ld->getMemOperand()->getFlags());
    }
  }

  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().countTrailingOnes() >= 1) {
      // 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, Align &Alignment,
                                         unsigned &Offset) {
  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();
  Offset = 0;
  Addr = MaskedOp->getBasePtr();
  if (TrueMaskElt != 0) {
    Offset = TrueMaskElt * EltVT.getStoreSize();
    Addr = DAG.getMemBasePlusOffset(Addr, TypeSize::Fixed(Offset),
                                    SDLoc(MaskedOp));
  }

  Index = DAG.getIntPtrConstant(TrueMaskElt, SDLoc(MaskedOp));
  Alignment = commonAlignment(MaskedOp->getOriginalAlign(),
                              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,
                             const X86Subtarget &Subtarget) {
  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;
  Align Alignment;
  unsigned Offset;
  if (!getParamsForOneTrueMaskedElt(ML, DAG, Addr, VecIndex, Alignment, Offset))
    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();

  EVT CastVT = VT;
  if (EltVT == MVT::i64 && !Subtarget.is64Bit()) {
    EltVT = MVT::f64;
    CastVT = VT.changeVectorElementType(EltVT);
  }

  SDValue Load =
      DAG.getLoad(EltVT, DL, ML->getChain(), Addr,
                  ML->getPointerInfo().getWithOffset(Offset),
                  Alignment, ML->getMemOperand()->getFlags());

  SDValue PassThru = DAG.getBitcast(CastVT, ML->getPassThru());

  // Insert the loaded element into the appropriate place in the vector.
  SDValue Insert =
      DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, CastVT, PassThru, Load, VecIndex);
  Insert = DAG.getBitcast(VT, Insert);
  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) {
  auto *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, Subtarget))
      return ScalarLoad;

    // TODO: Do some AVX512 subsets benefit from this transform?
    if (!Subtarget.hasAVX512())
      if (SDValue Blend = combineMaskedLoadConstantMask(Mld, DAG, DCI))
        return Blend;
  }

  // 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 = Mld->getMask();
  if (Mask.getScalarValueSizeInBits() != 1) {
    EVT VT = Mld->getValueType(0);
    const TargetLowering &TLI = DAG.getTargetLoweringInfo();
    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.getMaskedLoad(
          VT, SDLoc(N), Mld->getChain(), Mld->getBasePtr(), Mld->getOffset(),
          NewMask, Mld->getPassThru(), Mld->getMemoryVT(), Mld->getMemOperand(),
          Mld->getAddressingMode(), Mld->getExtensionType());
  }

  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,
                                              const X86Subtarget &Subtarget) {
  // 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;
  Align Alignment;
  unsigned Offset;
  if (!getParamsForOneTrueMaskedElt(MS, DAG, Addr, VecIndex, Alignment, Offset))
    return SDValue();

  // Extract the one scalar element that is actually being stored.
  SDLoc DL(MS);
  SDValue Value = MS->getValue();
  EVT VT = Value.getValueType();
  EVT EltVT = VT.getVectorElementType();
  if (EltVT == MVT::i64 && !Subtarget.is64Bit()) {
    EltVT = MVT::f64;
    EVT CastVT = VT.changeVectorElementType(EltVT);
    Value = DAG.getBitcast(CastVT, Value);
  }
  SDValue Extract =
      DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltVT, Value, VecIndex);

  // Store that element at the appropriate offset from the base pointer.
  return DAG.getStore(MS->getChain(), DL, Extract, Addr,
                      MS->getPointerInfo().getWithOffset(Offset),
                      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, Subtarget))
    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);
  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->getOriginalAlign(),
                        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) {
    SDValue Val = StoredVal.getOperand(0);
    // We must store zeros to the unused bits.
    Val = DAG.getZeroExtendInReg(Val, dl, MVT::i1);
    return DAG.getStore(St->getChain(), dl, Val,
                        St->getBasePtr(), St->getPointerInfo(),
                        St->getOriginalAlign(),
                        St->getMemOperand()->getFlags());
  }

  // Widen v2i1/v4i1 stores to v8i1.
  if ((VT == MVT::v1i1 || VT == MVT::v2i1 || VT == MVT::v4i1) && VT == StVT &&
      Subtarget.hasAVX512()) {
    unsigned NumConcats = 8 / VT.getVectorNumElements();
    // We must store zeros to the unused bits.
    SmallVector<SDValue, 4> Ops(NumConcats, DAG.getConstant(0, dl, 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->getOriginalAlign(),
                        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, TypeSize::Fixed(4), dl);

      SDValue Ch0 =
          DAG.getStore(St->getChain(), dl, Lo, Ptr0, St->getPointerInfo(),
                       St->getOriginalAlign(),
                       St->getMemOperand()->getFlags());
      SDValue Ch1 =
          DAG.getStore(St->getChain(), dl, Hi, Ptr1,
                       St->getPointerInfo().getWithOffset(4),
                       St->getOriginalAlign(),
                       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->getOriginalAlign(),
                        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 &&
      St->getAlignment() < 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);
  }

  // Try to fold a extract_element(VTRUNC) pattern into a truncating store.
  if (!St->isTruncatingStore() && StoredVal.hasOneUse()) {
    auto IsExtractedElement = [](SDValue V) {
      if (V.getOpcode() == ISD::TRUNCATE && V.getOperand(0).hasOneUse())
        V = V.getOperand(0);
      unsigned Opc = V.getOpcode();
      if (Opc == ISD::EXTRACT_VECTOR_ELT || Opc == X86ISD::PEXTRW) {
        if (V.getOperand(0).hasOneUse() && isNullConstant(V.getOperand(1)))
          return V.getOperand(0);
      }
      return SDValue();
    };
    if (SDValue Extract = IsExtractedElement(StoredVal)) {
      SDValue Trunc = peekThroughOneUseBitcasts(Extract);
      if (Trunc.getOpcode() == X86ISD::VTRUNC) {
        SDValue Src = Trunc.getOperand(0);
        MVT DstVT = Trunc.getSimpleValueType();
        MVT SrcVT = Src.getSimpleValueType();
        unsigned NumSrcElts = SrcVT.getVectorNumElements();
        unsigned NumTruncBits = DstVT.getScalarSizeInBits() * NumSrcElts;
        MVT TruncVT = MVT::getVectorVT(DstVT.getScalarType(), NumSrcElts);
        if (NumTruncBits == VT.getSizeInBits() &&
            TLI.isTruncStoreLegal(SrcVT, TruncVT)) {
          return DAG.getTruncStore(St->getChain(), dl, Src, St->getBasePtr(),
                                   TruncVT, St->getMemOperand());
        }
      }
    }
  }

  // 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->getOriginalAlign(),
                            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();
  }

  // Cast ptr32 and ptr64 pointers to the default address space before a store.
  unsigned AddrSpace = St->getAddressSpace();
  if (AddrSpace == X86AS::PTR64 || AddrSpace == X86AS::PTR32_SPTR ||
      AddrSpace == X86AS::PTR32_UPTR) {
    MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
    if (PtrVT != St->getBasePtr().getSimpleValueType()) {
      SDValue Cast =
          DAG.getAddrSpaceCast(dl, PtrVT, St->getBasePtr(), AddrSpace, 0);
      return DAG.getStore(St->getChain(), dl, StoredVal, Cast,
                          St->getPointerInfo(), St->getOriginalAlign(),
                          St->getMemOperand()->getFlags(), St->getAAInfo());
    }
  }

  // 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->getOriginalAlign(),
                        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(unsigned HOpcode, SDValue &LHS, SDValue &RHS,
                              SelectionDAG &DAG, const X86Subtarget &Subtarget,
                              bool IsCommutative,
                              SmallVectorImpl<int> &PostShuffleMask) {
  // 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;

  PostShuffleMask.clear();
  PostShuffleMask.append(NumElts, SM_SentinelUndef);

  // 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;
  unsigned NumEltsPer64BitChunk = NumEltsPer128BitChunk / 2;
  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;

      // Check that successive odd/even elements are being operated on. If not,
      // this is not a horizontal operation.
      if (!((RIdx & 1) == 1 && (LIdx + 1) == RIdx) &&
          !((LIdx & 1) == 1 && (RIdx + 1) == LIdx && IsCommutative))
        return false;

      // Compute the post-shuffle mask index based on where the element
      // is stored in the HOP result, and where it needs to be moved to.
      int Base = LIdx & ~1u;
      int Index = ((Base % NumEltsPer128BitChunk) / 2) +
                  ((Base % NumElts) & ~(NumEltsPer128BitChunk - 1));

      // 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.
      if ((B && Base >= (int)NumElts) || (!B && i >= NumEltsPer64BitChunk))
        Index += NumEltsPer64BitChunk;
      PostShuffleMask[i + j] = Index;
    }
  }

  SDValue NewLHS = A.getNode() ? A : B; // If A is 'UNDEF', use B for it.
  SDValue NewRHS = B.getNode() ? B : A; // If B is 'UNDEF', use A for it.

  bool IsIdentityPostShuffle =
      isSequentialOrUndefInRange(PostShuffleMask, 0, NumElts, 0);
  if (IsIdentityPostShuffle)
    PostShuffleMask.clear();

  // Avoid 128-bit multi lane shuffles if pre-AVX2 and FP (integer will split).
  if (!IsIdentityPostShuffle && !Subtarget.hasAVX2() && VT.isFloatingPoint() &&
      isMultiLaneShuffleMask(128, VT.getScalarSizeInBits(), PostShuffleMask))
    return false;

  // If the source nodes are already used in HorizOps then always accept this.
  // Shuffle folding should merge these back together.
  bool FoundHorizLHS = llvm::any_of(NewLHS->uses(), [&](SDNode *User) {
    return User->getOpcode() == HOpcode && User->getValueType(0) == VT;
  });
  bool FoundHorizRHS = llvm::any_of(NewRHS->uses(), [&](SDNode *User) {
    return User->getOpcode() == HOpcode && User->getValueType(0) == VT;
  });
  bool ForceHorizOp = FoundHorizLHS && FoundHorizRHS;

  // Assume a SingleSource HOP if we only shuffle one input and don't need to
  // shuffle the result.
  if (!ForceHorizOp &&
      !shouldUseHorizontalOp(NewLHS == NewRHS &&
                                 (NumShuffles < 2 || !IsIdentityPostShuffle),
                             DAG, Subtarget))
    return false;

  LHS = DAG.getBitcast(VT, NewLHS);
  RHS = DAG.getBitcast(VT, NewRHS);
  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.
  SmallVector<int, 8> PostShuffleMask;
  if (((Subtarget.hasSSE3() && (VT == MVT::v4f32 || VT == MVT::v2f64)) ||
       (Subtarget.hasAVX() && (VT == MVT::v8f32 || VT == MVT::v4f64))) &&
      isHorizontalBinOp(HorizOpcode, LHS, RHS, DAG, Subtarget, IsFadd,
                        PostShuffleMask)) {
    SDValue HorizBinOp = DAG.getNode(HorizOpcode, SDLoc(N), VT, LHS, RHS);
    if (!PostShuffleMask.empty())
      HorizBinOp = DAG.getVectorShuffle(VT, SDLoc(HorizBinOp), HorizBinOp,
                                        DAG.getUNDEF(VT), PostShuffleMask);
    return HorizBinOp;
  }

  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::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::AND:
  case ISD::XOR:
  case ISD::OR:
  case ISD::ADD:
  case ISD::SUB: {
    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::i16 || 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 (!isPowerOf2_32(VT.getVectorNumElements()))
    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();

  // Truncation to sub-128bit vXi32 can be better handled with shuffles.
  if (SVT == MVT::i32 && VT.getSizeInBits() < 128)
    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())) {
    // PACK should still be worth it for 128-bit vectors if the sources were
    // originally concatenated from subvectors.
    SmallVector<SDValue> ConcatOps;
    if (VT.getSizeInBits() > 128 || !collectConcatOps(In.getNode(), ConcatOps))
    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);

  // Don't use PACKSS for vXi64 -> vXi32 truncations unless we're dealing with
  // a sign splat. ComputeNumSignBits struggles to see through BITCASTs later
  // on and combines/simplifications can't then use it.
  if (SVT == MVT::i32 && NumSignBits != InSVT.getSizeInBits())
    return SDValue();

  unsigned MinSignBits = InSVT.getSizeInBits() - NumPackedSignBits;
  if (NumSignBits > MinSignBits)
    return truncateVectorWithPACK(X86ISD::PACKSS, VT, In, DL, DAG, Subtarget);

  // If we have a srl that only generates signbits that we will discard in
  // the truncation then we can use PACKSS by converting the srl to a sra.
  // SimplifyDemandedBits often relaxes sra to srl so we need to reverse it.
  if (In.getOpcode() == ISD::SRL && N->isOnlyUserOf(In.getNode()))
    if (const APInt *ShAmt = DAG.getValidShiftAmountConstant(
            In, APInt::getAllOnesValue(VT.getVectorNumElements()))) {
      if (*ShAmt == MinSignBits) {
        SDValue NewIn = DAG.getNode(ISD::SRA, DL, InVT, In->ops());
        return truncateVectorWithPACK(X86ISD::PACKSS, VT, NewIn, 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 at least vXi32.
  EVT InVT = Src.getValueType();
  if (InVT.getVectorElementType().getSizeInBits() < 32)
    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,
                             TargetLowering::DAGCombinerInfo &DCI) {
  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);

  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  APInt DemandedMask(APInt::getAllOnesValue(VT.getScalarSizeInBits()));
  if (TLI.SimplifyDemandedBits(SDValue(N, 0), DemandedMask, DCI))
    return SDValue(N, 0);

  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 (SDValue NegArg =
          TLI.getNegatedExpression(Arg, DAG, LegalOperations, CodeSize))
    return DAG.getBitcast(OrigVT, NegArg);

  return SDValue();
}

SDValue X86TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
                                                bool LegalOperations,
                                                bool ForCodeSize,
                                                NegatibleCost &Cost,
                                                unsigned Depth) const {
  // fneg patterns are removable even if they have multiple uses.
  if (SDValue Arg = isFNEG(DAG, Op.getNode(), Depth)) {
    Cost = NegatibleCost::Cheaper;
    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)
      NewOps[i] = getCheaperNegatedExpression(
          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);

    Cost = (NegA || NegB || NegC) ? NegatibleCost::Cheaper
                                  : NegatibleCost::Neutral;

    // 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:
    if (SDValue NegOp0 =
            getNegatedExpression(Op.getOperand(0), DAG, LegalOperations,
                                 ForCodeSize, Cost, Depth + 1))
      return DAG.getNode(Opc, SDLoc(Op), VT, NegOp0);
    break;
  }

  return TargetLowering::getNegatedExpression(Op, DAG, LegalOperations,
                                              ForCodeSize, Cost, 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 (SDValue R = combineBitOpWithMOVMSK(N, DAG))
    return R;

  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));
    unsigned NumBits = InVT.getScalarSizeInBits() * VT.getVectorNumElements();
    MVT MemVT = MVT::getIntegerVT(NumBits);
    MVT LoadVT = MVT::getVectorVT(MemVT, 128 / NumBits);
    if (SDValue VZLoad = narrowLoadToVZLoad(LN, MemVT, LoadVT, DAG)) {
      SDLoc dl(N);
      SDValue Convert = DAG.getNode(N->getOpcode(), dl, VT,
                                    DAG.getBitcast(InVT, VZLoad));
      DCI.CombineTo(N, Convert);
      DAG.ReplaceAllUsesOfValueWith(SDValue(LN, 1), VZLoad.getValue(1));
      DCI.recursivelyDeleteUnusedNodes(LN);
      return SDValue(N, 0);
    }
  }

  return SDValue();
}

static SDValue combineCVTP2I_CVTTP2I(SDNode *N, SelectionDAG &DAG,
                                     TargetLowering::DAGCombinerInfo &DCI) {
  bool IsStrict = N->isTargetStrictFPOpcode();
  EVT VT = N->getValueType(0);

  // Convert a full vector load into vzload when not all bits are needed.
  SDValue In = N->getOperand(IsStrict ? 1 : 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);
    unsigned NumBits = InVT.getScalarSizeInBits() * VT.getVectorNumElements();
    MVT MemVT = MVT::getFloatingPointVT(NumBits);
    MVT LoadVT = MVT::getVectorVT(MemVT, 128 / NumBits);
    if (SDValue VZLoad = narrowLoadToVZLoad(LN, MemVT, LoadVT, DAG)) {
      SDLoc dl(N);
      if (IsStrict) {
        SDValue Convert =
            DAG.getNode(N->getOpcode(), dl, {VT, MVT::Other},
                        {N->getOperand(0), DAG.getBitcast(InVT, VZLoad)});
        DCI.CombineTo(N, Convert, Convert.getValue(1));
      } else {
        SDValue Convert =
            DAG.getNode(N->getOpcode(), dl, VT, DAG.getBitcast(InVT, VZLoad));
        DCI.CombineTo(N, Convert);
      }
      DAG.ReplaceAllUsesOfValueWith(SDValue(LN, 1), VZLoad.getValue(1));
      DCI.recursivelyDeleteUnusedNodes(LN);
      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);
    }

    // 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(IsStrict ? 1 : 0));
      if (SDValue VZLoad = narrowLoadToVZLoad(LN, MVT::i64, MVT::v2i64, DAG)) {
        SDLoc dl(N);
        if (IsStrict) {
          SDValue Convert = DAG.getNode(
              N->getOpcode(), dl, {MVT::v4f32, MVT::Other},
              {N->getOperand(0), DAG.getBitcast(MVT::v8i16, VZLoad)});
          DCI.CombineTo(N, Convert, Convert.getValue(1));
        } else {
          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));
        DCI.recursivelyDeleteUnusedNodes(LN);
        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();

    // Attempt to promote any comparison mask ops before moving the
    // SIGN_EXTEND_INREG in the way.
    if (SDValue Promote = PromoteMaskArithmetic(N0.getNode(), DAG, Subtarget))
      return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT, Promote, N1);

    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 = VT.changeVectorElementType(MVT::i1);
  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());

  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);
  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 (SDValue V = combineToExtendBoolVectorInReg(N, DAG, DCI, Subtarget))
    return V;

  if (VT.isVector()) {
    if (SDValue R = PromoteMaskArithmetic(N, DAG, Subtarget))
      return R;

    if (N0.getOpcode() == ISD::SIGN_EXTEND_VECTOR_INREG)
      return DAG.getNode(N0.getOpcode(), DL, VT, N0.getOperand(0));
  }

  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();

  SDValue A = N->getOperand(IsStrict ? 1 : 0);
  SDValue B = N->getOperand(IsStrict ? 2 : 1);
  SDValue C = N->getOperand(IsStrict ? 3 : 2);

  // If the operation allows fast-math and the target does not support FMA,
  // split this into mul+add to avoid libcall(s).
  SDNodeFlags Flags = N->getFlags();
  if (!IsStrict && Flags.hasAllowReassociation() &&
      TLI.isOperationExpand(ISD::FMA, VT)) {
    SDValue Fmul = DAG.getNode(ISD::FMUL, dl, VT, A, B, Flags);
    return DAG.getNode(ISD::FADD, dl, VT, Fmul, C, Flags);
  }

  EVT ScalarVT = VT.getScalarType();
  if ((ScalarVT != MVT::f32 && ScalarVT != MVT::f64) || !Subtarget.hasAnyFMA())
    return SDValue();

  auto invertIfNegative = [&DAG, &TLI, &DCI](SDValue &V) {
    bool CodeSize = DAG.getMachineFunction().getFunction().hasOptSize();
    bool LegalOperations = !DCI.isBeforeLegalizeOps();
    if (SDValue NegV = TLI.getCheaperNegatedExpression(V, DAG, LegalOperations,
                                                       CodeSize)) {
      V = NegV;
      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 (SDValue NegV = TLI.getCheaperNegatedExpression(
              Vec, DAG, LegalOperations, CodeSize)) {
        V = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(V), V.getValueType(),
                        NegV, 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);

  SDValue NegN2 =
      TLI.getCheaperNegatedExpression(N2, DAG, LegalOperations, CodeSize);
  if (!NegN2)
    return SDValue();
  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);

  // 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 && Subtarget.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
    assert(Cmp.getValueType() == MVT::v16i8 &&
           "Non 128-bit vector on pre-SSE41 target");
    SDValue MovMsk = DAG.getNode(X86ISD::MOVMSK, DL, MVT::i32, Cmp);
    SDValue FFFFs = DAG.getConstant(0xFFFF, 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 == MVT::i1 && isNullConstant(RHS)) {
      SDValue X86CC;
      if (SDValue V =
              MatchVectorAllZeroTest(LHS, CC, DL, Subtarget, DAG, X86CC))
        return DAG.getNode(ISD::TRUNCATE, DL, VT,
                           DAG.getNode(X86ISD::SETCC, DL, MVT::i8, X86CC, 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() &&
             "Unexpected 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(x)) 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));
  }

  // Fold movmsk(icmp_sgt(x,-1)) -> not(movmsk(x)) to improve folding of movmsk
  // results with scalar comparisons.
  if (Src.getOpcode() == X86ISD::PCMPGT &&
      ISD::isBuildVectorAllOnes(Src.getOperand(1).getNode())) {
    SDLoc DL(N);
    APInt NotMask = APInt::getLowBitsSet(NumBits, NumElts);
    return DAG.getNode(ISD::XOR, DL, VT,
                       DAG.getNode(X86ISD::MOVMSK, DL, VT, Src.getOperand(0)),
                       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(),
                               Gather->getExtensionType());
  }
  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(),
                              Scatter->isTruncatingStore());
}

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)) {
        EVT NewVT = Index.getValueType().changeVectorElementType(MVT::i32);
        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)) {
      EVT NewVT = Index.getValueType().changeVectorElementType(MVT::i32);
      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 = Index.getValueType().changeVectorElementType(EltVT);
      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();
}

// TODO: Could we move this to DAGCombine?
static SDValue combineVectorCompareAndMaskUnaryOp(SDNode *N,
                                                  SelectionDAG &DAG) {
  // Take advantage of vector comparisons (etc.) 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();
  unsigned NumEltBits = VT.getScalarSizeInBits();
  SDValue Op0 = N->getOperand(IsStrict ? 1 : 0);
  if (!VT.isVector() || Op0.getOpcode() != ISD::AND ||
      DAG.ComputeNumSignBits(Op0.getOperand(0)) != NumEltBits ||
      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 = InVT.changeVectorElementType(MVT::i32);
    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 = InVT.changeVectorElementType(MVT::i32);
    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 = InVT.changeVectorElementType(TruncVT);
      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->getOriginalAlign(), 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 = NewSub.getValue(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_AE) {
    // X + SETAE --> sbb X, -1
    // X - SETAE --> adc X, -1
    return DAG.getNode(IsSub ? X86ISD::ADC : X86ISD::SBB, DL,
                       DAG.getVTList(VT, MVT::i32), X,
                       DAG.getConstant(-1, DL, VT), Y.getOperand(1));
  }

  if (CC == X86::COND_BE) {
    // X + SETBE --> sbb X, -1
    // X - SETBE --> adc X, -1
    SDValue EFLAGS = Y.getOperand(1);
    // Try to convert COND_BE into COND_AE in an attempt to facilitate
    // materializing "setae 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 = NewSub.getValue(EFLAGS.getResNo());
      return DAG.getNode(IsSub ? X86ISD::ADC : X86ISD::SBB, DL,
                         DAG.getVTList(VT, MVT::i32), X,
                         DAG.getConstant(-1, 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 combineAddOrSubToHADDorHSUB(SDNode *N, SelectionDAG &DAG,
                                           const X86Subtarget &Subtarget) {
  EVT VT = N->getValueType(0);
  SDValue Op0 = N->getOperand(0);
  SDValue Op1 = N->getOperand(1);
  bool IsAdd = N->getOpcode() == ISD::ADD;
  auto HorizOpcode = IsAdd ? X86ISD::HADD : X86ISD::HSUB;
  assert((IsAdd || N->getOpcode() == ISD::SUB) && "Wrong opcode");

  SmallVector<int, 8> PostShuffleMask;
  if ((VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v16i16 ||
       VT == MVT::v8i32) &&
      Subtarget.hasSSSE3() &&
      isHorizontalBinOp(HorizOpcode, Op0, Op1, DAG, Subtarget, IsAdd,
                        PostShuffleMask)) {
    auto HOpBuilder = [HorizOpcode](SelectionDAG &DAG, const SDLoc &DL,
                                    ArrayRef<SDValue> Ops) {
      return DAG.getNode(HorizOpcode, DL, Ops[0].getValueType(), Ops);
    };
    SDValue HorizBinOp =
        SplitOpsAndApply(DAG, Subtarget, SDLoc(N), VT, {Op0, Op1}, HOpBuilder);
    if (!PostShuffleMask.empty())
      HorizBinOp = DAG.getVectorShuffle(VT, SDLoc(HorizBinOp), HorizBinOp,
                                        DAG.getUNDEF(VT), PostShuffleMask);
    return HorizBinOp;
  }

  return SDValue();
}

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 (SDValue V = combineAddOrSubToHADDorHSUB(N, DAG, Subtarget))
    return V;

  // 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.
  EVT EltVT = VT.getVectorElementType();
  if (!(Subtarget.hasSSE2() &&
        (EltVT == MVT::i8 || EltVT == MVT::i16 || VT == MVT::v8i32 ||
         VT == MVT::v8i64 || VT == MVT::v16i32)))
    return SDValue();

  SDValue SubusLHS, SubusRHS;
  if (Op1.getOpcode() == ISD::TRUNCATE &&
      Op1.getOperand(0).getOpcode() == ISD::UMIN &&
      (EltVT == MVT::i8 || EltVT == MVT::i16)) {
    // Special case where the UMIN has been truncated. Try to push the truncate
    // further up. This is similar to the i32/i64 special processing.
    SubusLHS = Op0;
    SDValue MinLHS = Op1.getOperand(0).getOperand(0);
    SDValue MinRHS = Op1.getOperand(0).getOperand(1);
    EVT TruncVT = Op1.getOperand(0).getValueType();
    if (!(Subtarget.hasSSE2() &&
          (TruncVT == MVT::v8i32 || TruncVT == MVT::v8i64 ||
           TruncVT == MVT::v16i32)))
      return SDValue();
    SDValue OpToSaturate;
    if (MinLHS.getOpcode() == ISD::ZERO_EXTEND &&
        MinLHS.getOperand(0) == Op0)
      OpToSaturate = MinRHS;
    else if (MinRHS.getOpcode() == ISD::ZERO_EXTEND &&
             MinRHS.getOperand(0) == Op0)
      OpToSaturate = MinLHS;
    else
      return SDValue();

    // Saturate the non-extended input and then truncate it.
    SDLoc DL(N);
    SDValue SaturationConst =
        DAG.getConstant(APInt::getLowBitsSet(TruncVT.getScalarSizeInBits(),
                                             VT.getScalarSizeInBits()),
                        DL, TruncVT);
    SDValue UMin = DAG.getNode(ISD::UMIN, DL, TruncVT, OpToSaturate,
                               SaturationConst);
    SubusRHS = DAG.getNode(ISD::TRUNCATE, DL, VT, UMin);
  } 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 (NumZeros < (VT.getScalarSizeInBits() - 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.
  if (SDValue V = combineAddOrSubToHADDorHSUB(N, DAG, Subtarget))
    return V;

  // 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; });

  // Repeated subvectors.
  if (IsSplat &&
      (VT.is256BitVector() || (VT.is512BitVector() && Subtarget.hasAVX512()))) {
    // If this broadcast is inserted into both halves, use a larger broadcast.
    if (Op0.getOpcode() == X86ISD::VBROADCAST)
      return DAG.getNode(Op0.getOpcode(), DL, VT, Op0.getOperand(0));

    // If this scalar/subvector broadcast_load is inserted into both halves, use
    // a larger broadcast_load. Update other uses to use an extracted subvector.
    if (Op0.getOpcode() == X86ISD::VBROADCAST_LOAD ||
        Op0.getOpcode() == X86ISD::SUBV_BROADCAST_LOAD) {
      auto *MemIntr = cast<MemIntrinsicSDNode>(Op0);
      SDVTList Tys = DAG.getVTList(VT, MVT::Other);
      SDValue Ops[] = {MemIntr->getChain(), MemIntr->getBasePtr()};
      SDValue BcastLd = DAG.getMemIntrinsicNode(Op0.getOpcode(), DL, Tys, Ops,
                                                MemIntr->getMemoryVT(),
                                                MemIntr->getMemOperand());
      DAG.ReplaceAllUsesOfValueWith(
          Op0, extractSubVector(BcastLd, 0, DAG, DL, Op0.getValueSizeInBits()));
      DAG.ReplaceAllUsesOfValueWith(SDValue(MemIntr, 1), BcastLd.getValue(1));
      return BcastLd;
    }

    // If this is a simple subvector load repeated across multiple lanes, then
    // broadcast the load. Update other uses to use an extracted subvector.
    if (auto *Ld = dyn_cast<LoadSDNode>(Op0)) {
      if (Ld->isSimple() && !Ld->isNonTemporal() &&
          Ld->getExtensionType() == ISD::NON_EXTLOAD) {
        SDVTList Tys = DAG.getVTList(VT, MVT::Other);
        SDValue Ops[] = {Ld->getChain(), Ld->getBasePtr()};
        SDValue BcastLd =
            DAG.getMemIntrinsicNode(X86ISD::SUBV_BROADCAST_LOAD, DL, Tys, Ops,
                                    Ld->getMemoryVT(), Ld->getMemOperand());
        DAG.ReplaceAllUsesOfValueWith(
            Op0,
            extractSubVector(BcastLd, 0, DAG, DL, Op0.getValueSizeInBits()));
        DAG.ReplaceAllUsesOfValueWith(SDValue(Ld, 1), BcastLd.getValue(1));
        return BcastLd;
      }
    }

    // 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));

    // concat_vectors(extract_subvector(broadcast(x)),
    //                extract_subvector(broadcast(x))) -> broadcast(x)
    if (Op0.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
        Op0.getOperand(0).getValueType() == VT) {
      if (Op0.getOperand(0).getOpcode() == X86ISD::VBROADCAST ||
          Op0.getOperand(0).getOpcode() == X86ISD::VBROADCAST_LOAD)
        return 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::VPERMV3:
      if (!IsSplat && NumOps == 2 && VT.is512BitVector()) {
        MVT OpVT = Op0.getSimpleValueType();
        int NumSrcElts = OpVT.getVectorNumElements();
        SmallVector<int, 64> ConcatMask;
        for (unsigned i = 0; i != NumOps; ++i) {
          bool IsUnary;
          SmallVector<int, 64> SubMask;
          SmallVector<SDValue, 2> SubOps;
          if (!getTargetShuffleMask(Ops[i].getNode(), OpVT, false, SubOps,
                                    SubMask, IsUnary))
            break;
          for (int M : SubMask) {
            if (0 <= M) {
              M += M < NumSrcElts ? 0 : NumSrcElts;
              M += i * NumSrcElts;
            }
            ConcatMask.push_back(M);
          }
        }
        if (ConcatMask.size() == (NumOps * NumSrcElts)) {
          SDValue Src0 = concatSubVectors(Ops[0].getOperand(0),
                                          Ops[1].getOperand(0), DAG, DL);
          SDValue Src1 = concatSubVectors(Ops[0].getOperand(2),
                                          Ops[1].getOperand(2), DAG, DL);
          MVT IntMaskSVT = MVT::getIntegerVT(VT.getScalarSizeInBits());
          MVT IntMaskVT = MVT::getVectorVT(IntMaskSVT, NumOps * NumSrcElts);
          SDValue Mask = getConstVector(ConcatMask, IntMaskVT, DAG, DL, true);
          return DAG.getNode(X86ISD::VPERMV3, DL, VT, Src0, Mask, Src1);
        }
      }
      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 ISD::AND:
    case ISD::OR:
    case ISD::XOR:
    case X86ISD::ANDNP:
      // TODO: Add 256-bit support.
      if (!IsSplat && VT.is512BitVector()) {
        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::HADD:
    case X86ISD::HSUB:
    case X86ISD::FHADD:
    case X86ISD::FHSUB:
    case X86ISD::PACKSS:
    case X86ISD::PACKUS:
      if (!IsSplat && VT.is256BitVector() &&
          (VT.isFloatingPoint() || 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;
    }
  }

  // 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;
    }
  }

  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().getFixedSize() <=
              SubVecVT.getFixedSizeInBits())
        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 = Ext->getConstantOperandVal(1);
  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);
  unsigned IdxVal = N->getConstantOperandVal(1);
  SDValue InVecBC = peekThroughBitcasts(InVec);
  EVT InVecVT = InVec.getValueType();
  unsigned SizeInBits = VT.getSizeInBits();
  unsigned InSizeInBits = InVecVT.getSizeInBits();
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();

  if (Subtarget.hasAVX() && !Subtarget.hasAVX2() &&
      TLI.isTypeLegal(InVecVT) &&
      InSizeInBits == 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 = splitVectorIntBinary(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;

  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() <= SizeInBits) {
    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 an upper subvector from a broadcast we should just
  // extract the lowest subvector instead which should allow
  // SimplifyDemandedVectorElts do more simplifications.
  if (IdxVal != 0 && (InVec.getOpcode() == X86ISD::VBROADCAST ||
                      InVec.getOpcode() == X86ISD::VBROADCAST_LOAD ||
                      DAG.isSplatValue(InVec, /*AllowUndefs*/ false)))
    return extractSubVector(InVec, 0, DAG, SDLoc(N), SizeInBits);

  // If we're extracting a broadcasted subvector, just use the lowest subvector.
  if (IdxVal != 0 && InVec.getOpcode() == X86ISD::SUBV_BROADCAST_LOAD &&
      cast<MemIntrinsicSDNode>(InVec)->getMemoryVT() == VT)
    return extractSubVector(InVec, 0, DAG, SDLoc(N), SizeInBits);

  // Attempt to extract from the source of a shuffle vector.
  if ((InSizeInBits % SizeInBits) == 0 &&
      (IdxVal % VT.getVectorNumElements()) == 0) {
    SmallVector<int, 32> ShuffleMask;
    SmallVector<int, 32> ScaledMask;
    SmallVector<SDValue, 2> ShuffleInputs;
    unsigned NumSubVecs = InSizeInBits / SizeInBits;
    // Decode the shuffle mask and scale it so its shuffling subvectors.
    if (getTargetShuffleInputs(InVecBC, ShuffleInputs, ShuffleMask, DAG) &&
        scaleShuffleElements(ShuffleMask, NumSubVecs, ScaledMask)) {
      unsigned SubVecIdx = IdxVal / VT.getVectorNumElements();
      if (ScaledMask[SubVecIdx] == SM_SentinelUndef)
        return DAG.getUNDEF(VT);
      if (ScaledMask[SubVecIdx] == SM_SentinelZero)
        return getZeroVector(VT, Subtarget, DAG, SDLoc(N));
      SDValue Src = ShuffleInputs[ScaledMask[SubVecIdx] / NumSubVecs];
      if (Src.getValueSizeInBits() == InSizeInBits) {
        unsigned SrcSubVecIdx = ScaledMask[SubVecIdx] % NumSubVecs;
        unsigned SrcEltIdx = SrcSubVecIdx * VT.getVectorNumElements();
        return extractSubVector(DAG.getBitcast(InVecVT, Src), SrcEltIdx, DAG,
                                SDLoc(N), SizeInBits);
      }
    }
  }

  // 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.
  unsigned InOpcode = InVec.getOpcode();
  if (IdxVal == 0 && InVec.hasOneUse()) {
    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) &&
        (SizeInBits == 128 || SizeInBits == 256) &&
        InVec.getOperand(0).getValueSizeInBits() >= SizeInBits) {
      SDLoc DL(N);
      SDValue Ext = InVec.getOperand(0);
      if (Ext.getValueSizeInBits() > SizeInBits)
        Ext = extractSubVector(Ext, 0, DAG, DL, SizeInBits);
      unsigned ExtOp = getOpcode_EXTEND_VECTOR_INREG(InOpcode);
      return DAG.getNode(ExtOp, DL, VT, Ext);
    }
    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);
    }
    if (InOpcode == ISD::TRUNCATE && Subtarget.hasVLX() &&
        (VT.is128BitVector() || VT.is256BitVector())) {
      SDLoc DL(N);
      SDValue InVecSrc = InVec.getOperand(0);
      unsigned Scale = InVecSrc.getValueSizeInBits() / InSizeInBits;
      SDValue Ext = extractSubVector(InVecSrc, 0, DAG, DL, Scale * SizeInBits);
      return DAG.getNode(InOpcode, DL, VT, Ext);
    }
  }

  // Always split vXi64 logical shifts where we're extracting the upper 32-bits
  // as this is very likely to fold into a shuffle/truncation.
  if ((InOpcode == X86ISD::VSHLI || InOpcode == X86ISD::VSRLI) &&
      InVecVT.getScalarSizeInBits() == 64 &&
      InVec.getConstantOperandAPInt(1) == 32) {
    SDLoc DL(N);
    SDValue Ext =
        extractSubVector(InVec.getOperand(0), IdxVal, DAG, DL, SizeInBits);
    return DAG.getNode(InOpcode, DL, VT, Ext, InVec.getOperand(1));
  }

  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/SimplifyDemandedBits?
  if (VT == MVT::v2i64 || VT == MVT::v2f64) {
    auto IsAnyExt64 = [](SDValue Op) {
      if (Op.getValueType() != MVT::i64 || !Op.hasOneUse())
        return SDValue();
      if (Op.getOpcode() == ISD::ANY_EXTEND &&
          Op.getOperand(0).getScalarValueSizeInBits() <= 32)
        return Op.getOperand(0);
      if (auto *Ld = dyn_cast<LoadSDNode>(Op))
        if (Ld->getExtensionType() == ISD::EXTLOAD &&
            Ld->getMemoryVT().getScalarSizeInBits() <= 32)
          return Op;
      return SDValue();
    };
    if (SDValue ExtSrc = IsAnyExt64(peekThroughOneUseBitcasts(Src)))
      return DAG.getBitcast(
          VT, DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v4i32,
                          DAG.getAnyExtOrTrunc(ExtSrc, DL, MVT::i32)));
  }

  // Combine (v2i64 (scalar_to_vector (i64 (bitconvert (mmx))))) to MOVQ2DQ.
  if (VT == MVT::v2i64 && Src.getOpcode() == ISD::BITCAST &&
      Src.getOperand(0).getValueType() == MVT::x86mmx)
    return DAG.getNode(X86ISD::MOVQ2DQ, DL, VT, Src.getOperand(0));

  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 combineEXTEND_VECTOR_INREG 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 combineEXTEND_VECTOR_INREG(SDNode *N, SelectionDAG &DAG,
                                          TargetLowering::DAGCombinerInfo &DCI,
                                          const X86Subtarget &Subtarget) {
  EVT VT = N->getValueType(0);
  SDValue In = N->getOperand(0);
  unsigned Opcode = N->getOpcode();
  unsigned InOpcode = In.getOpcode();
  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 = Opcode == ISD::SIGN_EXTEND_VECTOR_INREG
                                 ? ISD::SEXTLOAD
                                 : ISD::ZEXTLOAD;
      EVT MemVT = VT.changeVectorElementType(SVT);
      if (TLI.isLoadExtLegal(Ext, VT, MemVT)) {
        SDValue Load =
            DAG.getExtLoad(Ext, SDLoc(N), VT, Ld->getChain(), Ld->getBasePtr(),
                           Ld->getPointerInfo(), MemVT, Ld->getOriginalAlign(),
                           Ld->getMemOperand()->getFlags());
        DAG.ReplaceAllUsesOfValueWith(SDValue(Ld, 1), Load.getValue(1));
        return Load;
      }
    }
  }

  // Fold EXTEND_VECTOR_INREG(EXTEND_VECTOR_INREG(X)) -> EXTEND_VECTOR_INREG(X).
  if (Opcode == InOpcode)
    return DAG.getNode(Opcode, SDLoc(N), VT, In.getOperand(0));

  // Fold EXTEND_VECTOR_INREG(EXTRACT_SUBVECTOR(EXTEND(X),0))
  // -> EXTEND_VECTOR_INREG(X).
  // TODO: Handle non-zero subvector indices.
  if (InOpcode == ISD::EXTRACT_SUBVECTOR && In.getConstantOperandVal(1) == 0 &&
      In.getOperand(0).getOpcode() == getOpcode_EXTEND(Opcode) &&
      In.getOperand(0).getOperand(0).getValueSizeInBits() ==
          In.getValueSizeInBits())
    return DAG.getNode(Opcode, SDLoc(N), VT, In.getOperand(0).getOperand(0));

  // Attempt to combine as a shuffle.
  // TODO: General ZERO_EXTEND_VECTOR_INREG support.
  if (Opcode == ISD::ANY_EXTEND_VECTOR_INREG ||
      (Opcode == ISD::ZERO_EXTEND_VECTOR_INREG && Subtarget.hasSSE41())) {
    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/SUBV_BROADCAST_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 combineBROADCAST_LOAD(SDNode *N, SelectionDAG &DAG,
                                     TargetLowering::DAGCombinerInfo &DCI) {
  assert((N->getOpcode() == X86ISD::VBROADCAST_LOAD ||
          N->getOpcode() == X86ISD::SUBV_BROADCAST_LOAD) &&
         "Unknown broadcast load type");

  // 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() == N->getOpcode() &&
        cast<MemIntrinsicSDNode>(User)->getBasePtr() == Ptr &&
        cast<MemIntrinsicSDNode>(User)->getChain() == Chain &&
        cast<MemIntrinsicSDNode>(User)->getMemoryVT().getSizeInBits() ==
            MemVT.getSizeInBits() &&
        !User->hasAnyUseOfValue(1) &&
        User->getValueSizeInBits(0).getFixedSize() > VT.getFixedSizeInBits()) {
      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);
}

static SDValue combineMOVDQ2Q(SDNode *N, SelectionDAG &DAG) {
  SDValue Src = N->getOperand(0);

  // Turn MOVDQ2Q+simple_load into an mmx load.
  if (ISD::isNormalLoad(Src.getNode()) && Src.hasOneUse()) {
    LoadSDNode *LN = cast<LoadSDNode>(Src.getNode());

    if (LN->isSimple()) {
      SDValue NewLd = DAG.getLoad(MVT::x86mmx, SDLoc(N), LN->getChain(),
                                  LN->getBasePtr(),
                                  LN->getPointerInfo(),
                                  LN->getOriginalAlign(),
                                  LN->getMemOperand()->getFlags());
      DAG.ReplaceAllUsesOfValueWith(SDValue(LN, 1), NewLd.getValue(1));
      return NewLd;
    }
  }

  return SDValue();
}

static SDValue combinePDEP(SDNode *N, SelectionDAG &DAG,
                           TargetLowering::DAGCombinerInfo &DCI) {
  unsigned NumBits = N->getSimpleValueType(0).getSizeInBits();
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  if (TLI.SimplifyDemandedBits(SDValue(N, 0),
                               APInt::getAllOnesValue(NumBits), DCI))
    return SDValue(N, 0);

  return SDValue();
}

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, Subtarget);
  case ISD::SRL:            return combineShiftRightLogical(N, DAG, DCI, Subtarget);
  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:
  case X86ISD::BEXTRI:      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, DCI);
  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::STRICT_CVTTP2SI:
  case X86ISD::CVTTP2SI:
  case X86ISD::STRICT_CVTTP2UI:
  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 combineEXTEND_VECTOR_INREG(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::HADD:
  case X86ISD::HSUB:
  case X86ISD::FHADD:
  case X86ISD::FHSUB:       return combineVectorHADDSUB(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:
  case X86ISD::SUBV_BROADCAST_LOAD: return combineBROADCAST_LOAD(N, DAG, DCI);
  case X86ISD::MOVDQ2Q:     return combineMOVDQ2Q(N, DAG);
  case X86ISD::PDEP:        return combinePDEP(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->getCalledOperand());

  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_NP)
                           .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 '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':
        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':
    if (StringRef(constraint).size() != 2)
      break;
    switch (constraint[1]) {
      default:
        return CW_Invalid;
      // XMM0
      case 'z':
        if (((type->getPrimitiveSizeInBits() == 128) && Subtarget.hasSSE1()) ||
            ((type->getPrimitiveSizeInBits() == 256) && Subtarget.hasAVX()) ||
            ((type->getPrimitiveSizeInBits() == 512) && Subtarget.hasAVX512()))
          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 'x'
      case 'i':
      case 't':
      case '2':
        if (!Subtarget.hasSSE2())
          return CW_Invalid;
        break;
    }
    break;
  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.hasSSE1())
      return "x";
  }

  return TargetLowering::LowerXConstraint(ConstraintVT);
}

// Lower @cc targets via setcc.
SDValue X86TargetLowering::LowerAsmOutputForConstraint(
    SDValue &Chain, SDValue &Flag, const 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::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)
          return std::make_pair(0U, &X86::GR32RegClass);
        if (VT != MVT::f80)
          return std::make_pair(0U, &X86::GR64RegClass);
        break;
      }
      LLVM_FALLTHROUGH;
      // 32-bit fallthrough
    case 'Q':   // Q_REGS
      if (VT == MVT::i8 || VT == MVT::i1)
        return std::make_pair(0U, &X86::GR8_ABCD_LRegClass);
      if (VT == MVT::i16)
        return std::make_pair(0U, &X86::GR16_ABCDRegClass);
      if (VT == MVT::i32 || VT == MVT::f32 || !Subtarget.is64Bit())
        return std::make_pair(0U, &X86::GR32_ABCDRegClass);
      if (VT != MVT::f80)
        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);
      if (VT != MVT::f80)
        return std::make_pair(0U, &X86::GR64RegClass);
      break;
    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 || VT == MVT::f32 || !Subtarget.is64Bit())
        return std::make_pair(0U, &X86::GR32_NOREXRegClass);
      if (VT != MVT::f80)
        return std::make_pair(0U, &X86::GR64_NOREXRegClass);
      break;
    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);
      if (VT == MVT::f32 || VT == MVT::f64 || VT == MVT::f80)
        return std::make_pair(0U, &X86::RFP80RegClass);
      break;
    case 'y':   // MMX_REGS if MMX allowed.
      if (!Subtarget.hasMMX()) break;
      return std::make_pair(0U, &X86::VR64RegClass);
    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);
      case MVT::i128:
        if (Subtarget.is64Bit()) {
          if (VConstraint && Subtarget.hasVLX())
            return std::make_pair(0U, &X86::VR128XRegClass);
          return std::make_pair(0U, &X86::VR128RegClass);
        }
        break;
      // 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::v64i8:
      case MVT::v32i16:
      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, "x", VT);
    case 'm':
      if (!Subtarget.hasMMX()) break;
      return std::make_pair(0U, &X86::VR64RegClass);
    case 'z':
      if (!Subtarget.hasSSE1()) break;
      switch (VT.SimpleTy) {
      default: break;
      // Scalar SSE types.
      case MVT::f32:
      case MVT::i32:
        return std::make_pair(X86::XMM0, &X86::FR32RegClass);
      case MVT::f64:
      case MVT::i64:
        return std::make_pair(X86::XMM0, &X86::FR64RegClass);
      case MVT::f128:
      case MVT::v16i8:
      case MVT::v8i16:
      case MVT::v4i32:
      case MVT::v2i64:
      case MVT::v4f32:
      case MVT::v2f64:
        return std::make_pair(X86::XMM0, &X86::VR128RegClass);
      // AVX types.
      case MVT::v32i8:
      case MVT::v16i16:
      case MVT::v8i32:
      case MVT::v4i64:
      case MVT::v8f32:
      case MVT::v4f64:
        if (Subtarget.hasAVX())
          return std::make_pair(X86::YMM0, &X86::VR256RegClass);
        break;
      case MVT::v64i8:
      case MVT::v32i16:
      case MVT::v8f64:
      case MVT::v16f32:
      case MVT::v16i32:
      case MVT::v8i64:
        if (Subtarget.hasAVX512())
          return std::make_pair(X86::ZMM0, &X86::VR512_0_15RegClass);
        break;
      }
      break;
    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<Register, const TargetRegisterClass*> Res;
  Res = TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);

  // Not found as a standard register?
  if (!Res.second) {
    // Only match x87 registers if the VT is one SelectionDAGBuilder can convert
    // to/from f80.
    if (VT == MVT::Other || VT == MVT::f32 || VT == MVT::f64 || VT == MVT::f80) {
      // 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
    // Only allow for clobber.
    if (StringRef("{dirflag}").equals_lower(Constraint) && VT == MVT::Other)
      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;
    Register 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.hasFnAttribute(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;
}

Align X86TargetLowering::getPrefLoopAlignment(MachineLoop *ML) const {
  if (ML->isInnermost() &&
      ExperimentalPrefInnermostLoopAlignment.getNumOccurrences())
    return Align(1ULL << ExperimentalPrefInnermostLoopAlignment);
  return TargetLowering::getPrefLoopAlignment();
}
