//===-- AutoUpgrade.cpp - Implement auto-upgrade helper functions ---------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the auto-upgrade helper functions.
// This is where deprecated IR intrinsics and other IR features are updated to
// current specifications.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/AutoUpgrade.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/IR/AttributeMask.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstVisitor.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsAArch64.h"
#include "llvm/IR/IntrinsicsAMDGPU.h"
#include "llvm/IR/IntrinsicsARM.h"
#include "llvm/IR/IntrinsicsNVPTX.h"
#include "llvm/IR/IntrinsicsRISCV.h"
#include "llvm/IR/IntrinsicsWebAssembly.h"
#include "llvm/IR/IntrinsicsX86.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/AMDGPUAddrSpace.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/NVPTXAddrSpace.h"
#include "llvm/Support/NVVMAttributes.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/TimeProfiler.h"
#include "llvm/TargetParser/Triple.h"
#include <cstdint>
#include <cstring>
#include <numeric>

using namespace llvm;

static cl::opt<bool>
    DisableAutoUpgradeDebugInfo("disable-auto-upgrade-debug-info",
                                cl::desc("Disable autoupgrade of debug info"));

static void rename(GlobalValue *GV) { GV->setName(GV->getName() + ".old"); }

// Report a fatal error along with the
// Call Instruction which caused the error
[[noreturn]] static void reportFatalUsageErrorWithCI(StringRef reason,
                                                     CallBase *CI) {
  CI->print(llvm::errs());
  llvm::errs() << "\n";
  reportFatalUsageError(reason);
}

// Upgrade the declarations of the SSE4.1 ptest intrinsics whose arguments have
// changed their type from v4f32 to v2i64.
static bool upgradePTESTIntrinsic(Function *F, Intrinsic::ID IID,
                                  Function *&NewFn) {
  // Check whether this is an old version of the function, which received
  // v4f32 arguments.
  Type *Arg0Type = F->getFunctionType()->getParamType(0);
  if (Arg0Type != FixedVectorType::get(Type::getFloatTy(F->getContext()), 4))
    return false;

  // Yes, it's old, replace it with new version.
  rename(F);
  NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), IID);
  return true;
}

// Upgrade the declarations of intrinsic functions whose 8-bit immediate mask
// arguments have changed their type from i32 to i8.
static bool upgradeX86IntrinsicsWith8BitMask(Function *F, Intrinsic::ID IID,
                                             Function *&NewFn) {
  // Check that the last argument is an i32.
  Type *LastArgType = F->getFunctionType()->getParamType(
     F->getFunctionType()->getNumParams() - 1);
  if (!LastArgType->isIntegerTy(32))
    return false;

  // Move this function aside and map down.
  rename(F);
  NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), IID);
  return true;
}

// Upgrade the declaration of fp compare intrinsics that change return type
// from scalar to vXi1 mask.
static bool upgradeX86MaskedFPCompare(Function *F, Intrinsic::ID IID,
                                      Function *&NewFn) {
  // Check if the return type is a vector.
  if (F->getReturnType()->isVectorTy())
    return false;

  rename(F);
  NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), IID);
  return true;
}

// Upgrade the declaration of multiply and add bytes intrinsics whose input
// arguments' types have changed from vectors of i32 to vectors of i8
static bool upgradeX86MultiplyAddBytes(Function *F, Intrinsic::ID IID,
                                       Function *&NewFn) {
  // check if input argument type is a vector of i8
  Type *Arg1Type = F->getFunctionType()->getParamType(1);
  Type *Arg2Type = F->getFunctionType()->getParamType(2);
  if (Arg1Type->isVectorTy() &&
      cast<VectorType>(Arg1Type)->getElementType()->isIntegerTy(8) &&
      Arg2Type->isVectorTy() &&
      cast<VectorType>(Arg2Type)->getElementType()->isIntegerTy(8))
    return false;

  rename(F);
  NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), IID);
  return true;
}

// Upgrade the declaration of multipy and add words intrinsics whose input
// arguments' types have changed to vectors of i32 to vectors of i16
static bool upgradeX86MultiplyAddWords(Function *F, Intrinsic::ID IID,
                                       Function *&NewFn) {
  // check if input argument type is a vector of i16
  Type *Arg1Type = F->getFunctionType()->getParamType(1);
  Type *Arg2Type = F->getFunctionType()->getParamType(2);
  if (Arg1Type->isVectorTy() &&
      cast<VectorType>(Arg1Type)->getElementType()->isIntegerTy(16) &&
      Arg2Type->isVectorTy() &&
      cast<VectorType>(Arg2Type)->getElementType()->isIntegerTy(16))
    return false;

  rename(F);
  NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), IID);
  return true;
}

static bool upgradeX86BF16Intrinsic(Function *F, Intrinsic::ID IID,
                                    Function *&NewFn) {
  if (F->getReturnType()->getScalarType()->isBFloatTy())
    return false;

  rename(F);
  NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), IID);
  return true;
}

static bool upgradeX86BF16DPIntrinsic(Function *F, Intrinsic::ID IID,
                                      Function *&NewFn) {
  if (F->getFunctionType()->getParamType(1)->getScalarType()->isBFloatTy())
    return false;

  rename(F);
  NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), IID);
  return true;
}

static bool shouldUpgradeX86Intrinsic(Function *F, StringRef Name) {
  // All of the intrinsics matches below should be marked with which llvm
  // version started autoupgrading them. At some point in the future we would
  // like to use this information to remove upgrade code for some older
  // intrinsics. It is currently undecided how we will determine that future
  // point.
  if (Name.consume_front("avx."))
    return (Name.starts_with("blend.p") ||        // Added in 3.7
            Name == "cvt.ps2.pd.256" ||           // Added in 3.9
            Name == "cvtdq2.pd.256" ||            // Added in 3.9
            Name == "cvtdq2.ps.256" ||            // Added in 7.0
            Name.starts_with("movnt.") ||         // Added in 3.2
            Name.starts_with("sqrt.p") ||         // Added in 7.0
            Name.starts_with("storeu.") ||        // Added in 3.9
            Name.starts_with("vbroadcast.s") ||   // Added in 3.5
            Name.starts_with("vbroadcastf128") || // Added in 4.0
            Name.starts_with("vextractf128.") ||  // Added in 3.7
            Name.starts_with("vinsertf128.") ||   // Added in 3.7
            Name.starts_with("vperm2f128.") ||    // Added in 6.0
            Name.starts_with("vpermil."));        // Added in 3.1

  if (Name.consume_front("avx2."))
    return (Name == "movntdqa" ||             // Added in 5.0
            Name.starts_with("pabs.") ||      // Added in 6.0
            Name.starts_with("padds.") ||     // Added in 8.0
            Name.starts_with("paddus.") ||    // Added in 8.0
            Name.starts_with("pblendd.") ||   // Added in 3.7
            Name == "pblendw" ||              // Added in 3.7
            Name.starts_with("pbroadcast") || // Added in 3.8
            Name.starts_with("pcmpeq.") ||    // Added in 3.1
            Name.starts_with("pcmpgt.") ||    // Added in 3.1
            Name.starts_with("pmax") ||       // Added in 3.9
            Name.starts_with("pmin") ||       // Added in 3.9
            Name.starts_with("pmovsx") ||     // Added in 3.9
            Name.starts_with("pmovzx") ||     // Added in 3.9
            Name == "pmul.dq" ||              // Added in 7.0
            Name == "pmulu.dq" ||             // Added in 7.0
            Name.starts_with("psll.dq") ||    // Added in 3.7
            Name.starts_with("psrl.dq") ||    // Added in 3.7
            Name.starts_with("psubs.") ||     // Added in 8.0
            Name.starts_with("psubus.") ||    // Added in 8.0
            Name.starts_with("vbroadcast") || // Added in 3.8
            Name == "vbroadcasti128" ||       // Added in 3.7
            Name == "vextracti128" ||         // Added in 3.7
            Name == "vinserti128" ||          // Added in 3.7
            Name == "vperm2i128");            // Added in 6.0

  if (Name.consume_front("avx512.")) {
    if (Name.consume_front("mask."))
      // 'avx512.mask.*'
      return (Name.starts_with("add.p") ||       // Added in 7.0. 128/256 in 4.0
              Name.starts_with("and.") ||        // Added in 3.9
              Name.starts_with("andn.") ||       // Added in 3.9
              Name.starts_with("broadcast.s") || // Added in 3.9
              Name.starts_with("broadcastf32x4.") || // Added in 6.0
              Name.starts_with("broadcastf32x8.") || // Added in 6.0
              Name.starts_with("broadcastf64x2.") || // Added in 6.0
              Name.starts_with("broadcastf64x4.") || // Added in 6.0
              Name.starts_with("broadcasti32x4.") || // Added in 6.0
              Name.starts_with("broadcasti32x8.") || // Added in 6.0
              Name.starts_with("broadcasti64x2.") || // Added in 6.0
              Name.starts_with("broadcasti64x4.") || // Added in 6.0
              Name.starts_with("cmp.b") ||           // Added in 5.0
              Name.starts_with("cmp.d") ||           // Added in 5.0
              Name.starts_with("cmp.q") ||           // Added in 5.0
              Name.starts_with("cmp.w") ||           // Added in 5.0
              Name.starts_with("compress.b") ||      // Added in 9.0
              Name.starts_with("compress.d") ||      // Added in 9.0
              Name.starts_with("compress.p") ||      // Added in 9.0
              Name.starts_with("compress.q") ||      // Added in 9.0
              Name.starts_with("compress.store.") || // Added in 7.0
              Name.starts_with("compress.w") ||      // Added in 9.0
              Name.starts_with("conflict.") ||       // Added in 9.0
              Name.starts_with("cvtdq2pd.") ||       // Added in 4.0
              Name.starts_with("cvtdq2ps.") ||       // Added in 7.0 updated 9.0
              Name == "cvtpd2dq.256" ||              // Added in 7.0
              Name == "cvtpd2ps.256" ||              // Added in 7.0
              Name == "cvtps2pd.128" ||              // Added in 7.0
              Name == "cvtps2pd.256" ||              // Added in 7.0
              Name.starts_with("cvtqq2pd.") ||       // Added in 7.0 updated 9.0
              Name == "cvtqq2ps.256" ||              // Added in 9.0
              Name == "cvtqq2ps.512" ||              // Added in 9.0
              Name == "cvttpd2dq.256" ||             // Added in 7.0
              Name == "cvttps2dq.128" ||             // Added in 7.0
              Name == "cvttps2dq.256" ||             // Added in 7.0
              Name.starts_with("cvtudq2pd.") ||      // Added in 4.0
              Name.starts_with("cvtudq2ps.") ||      // Added in 7.0 updated 9.0
              Name.starts_with("cvtuqq2pd.") ||      // Added in 7.0 updated 9.0
              Name == "cvtuqq2ps.256" ||             // Added in 9.0
              Name == "cvtuqq2ps.512" ||             // Added in 9.0
              Name.starts_with("dbpsadbw.") ||       // Added in 7.0
              Name.starts_with("div.p") ||    // Added in 7.0. 128/256 in 4.0
              Name.starts_with("expand.b") || // Added in 9.0
              Name.starts_with("expand.d") || // Added in 9.0
              Name.starts_with("expand.load.") || // Added in 7.0
              Name.starts_with("expand.p") ||     // Added in 9.0
              Name.starts_with("expand.q") ||     // Added in 9.0
              Name.starts_with("expand.w") ||     // Added in 9.0
              Name.starts_with("fpclass.p") ||    // Added in 7.0
              Name.starts_with("insert") ||       // Added in 4.0
              Name.starts_with("load.") ||        // Added in 3.9
              Name.starts_with("loadu.") ||       // Added in 3.9
              Name.starts_with("lzcnt.") ||       // Added in 5.0
              Name.starts_with("max.p") ||       // Added in 7.0. 128/256 in 5.0
              Name.starts_with("min.p") ||       // Added in 7.0. 128/256 in 5.0
              Name.starts_with("movddup") ||     // Added in 3.9
              Name.starts_with("move.s") ||      // Added in 4.0
              Name.starts_with("movshdup") ||    // Added in 3.9
              Name.starts_with("movsldup") ||    // Added in 3.9
              Name.starts_with("mul.p") ||       // Added in 7.0. 128/256 in 4.0
              Name.starts_with("or.") ||         // Added in 3.9
              Name.starts_with("pabs.") ||       // Added in 6.0
              Name.starts_with("packssdw.") ||   // Added in 5.0
              Name.starts_with("packsswb.") ||   // Added in 5.0
              Name.starts_with("packusdw.") ||   // Added in 5.0
              Name.starts_with("packuswb.") ||   // Added in 5.0
              Name.starts_with("padd.") ||       // Added in 4.0
              Name.starts_with("padds.") ||      // Added in 8.0
              Name.starts_with("paddus.") ||     // Added in 8.0
              Name.starts_with("palignr.") ||    // Added in 3.9
              Name.starts_with("pand.") ||       // Added in 3.9
              Name.starts_with("pandn.") ||      // Added in 3.9
              Name.starts_with("pavg") ||        // Added in 6.0
              Name.starts_with("pbroadcast") ||  // Added in 6.0
              Name.starts_with("pcmpeq.") ||     // Added in 3.9
              Name.starts_with("pcmpgt.") ||     // Added in 3.9
              Name.starts_with("perm.df.") ||    // Added in 3.9
              Name.starts_with("perm.di.") ||    // Added in 3.9
              Name.starts_with("permvar.") ||    // Added in 7.0
              Name.starts_with("pmaddubs.w.") || // Added in 7.0
              Name.starts_with("pmaddw.d.") ||   // Added in 7.0
              Name.starts_with("pmax") ||        // Added in 4.0
              Name.starts_with("pmin") ||        // Added in 4.0
              Name == "pmov.qd.256" ||           // Added in 9.0
              Name == "pmov.qd.512" ||           // Added in 9.0
              Name == "pmov.wb.256" ||           // Added in 9.0
              Name == "pmov.wb.512" ||           // Added in 9.0
              Name.starts_with("pmovsx") ||      // Added in 4.0
              Name.starts_with("pmovzx") ||      // Added in 4.0
              Name.starts_with("pmul.dq.") ||    // Added in 4.0
              Name.starts_with("pmul.hr.sw.") || // Added in 7.0
              Name.starts_with("pmulh.w.") ||    // Added in 7.0
              Name.starts_with("pmulhu.w.") ||   // Added in 7.0
              Name.starts_with("pmull.") ||      // Added in 4.0
              Name.starts_with("pmultishift.qb.") || // Added in 8.0
              Name.starts_with("pmulu.dq.") ||       // Added in 4.0
              Name.starts_with("por.") ||            // Added in 3.9
              Name.starts_with("prol.") ||           // Added in 8.0
              Name.starts_with("prolv.") ||          // Added in 8.0
              Name.starts_with("pror.") ||           // Added in 8.0
              Name.starts_with("prorv.") ||          // Added in 8.0
              Name.starts_with("pshuf.b.") ||        // Added in 4.0
              Name.starts_with("pshuf.d.") ||        // Added in 3.9
              Name.starts_with("pshufh.w.") ||       // Added in 3.9
              Name.starts_with("pshufl.w.") ||       // Added in 3.9
              Name.starts_with("psll.d") ||          // Added in 4.0
              Name.starts_with("psll.q") ||          // Added in 4.0
              Name.starts_with("psll.w") ||          // Added in 4.0
              Name.starts_with("pslli") ||           // Added in 4.0
              Name.starts_with("psllv") ||           // Added in 4.0
              Name.starts_with("psra.d") ||          // Added in 4.0
              Name.starts_with("psra.q") ||          // Added in 4.0
              Name.starts_with("psra.w") ||          // Added in 4.0
              Name.starts_with("psrai") ||           // Added in 4.0
              Name.starts_with("psrav") ||           // Added in 4.0
              Name.starts_with("psrl.d") ||          // Added in 4.0
              Name.starts_with("psrl.q") ||          // Added in 4.0
              Name.starts_with("psrl.w") ||          // Added in 4.0
              Name.starts_with("psrli") ||           // Added in 4.0
              Name.starts_with("psrlv") ||           // Added in 4.0
              Name.starts_with("psub.") ||           // Added in 4.0
              Name.starts_with("psubs.") ||          // Added in 8.0
              Name.starts_with("psubus.") ||         // Added in 8.0
              Name.starts_with("pternlog.") ||       // Added in 7.0
              Name.starts_with("punpckh") ||         // Added in 3.9
              Name.starts_with("punpckl") ||         // Added in 3.9
              Name.starts_with("pxor.") ||           // Added in 3.9
              Name.starts_with("shuf.f") ||          // Added in 6.0
              Name.starts_with("shuf.i") ||          // Added in 6.0
              Name.starts_with("shuf.p") ||          // Added in 4.0
              Name.starts_with("sqrt.p") ||          // Added in 7.0
              Name.starts_with("store.b.") ||        // Added in 3.9
              Name.starts_with("store.d.") ||        // Added in 3.9
              Name.starts_with("store.p") ||         // Added in 3.9
              Name.starts_with("store.q.") ||        // Added in 3.9
              Name.starts_with("store.w.") ||        // Added in 3.9
              Name == "store.ss" ||                  // Added in 7.0
              Name.starts_with("storeu.") ||         // Added in 3.9
              Name.starts_with("sub.p") ||       // Added in 7.0. 128/256 in 4.0
              Name.starts_with("ucmp.") ||       // Added in 5.0
              Name.starts_with("unpckh.") ||     // Added in 3.9
              Name.starts_with("unpckl.") ||     // Added in 3.9
              Name.starts_with("valign.") ||     // Added in 4.0
              Name == "vcvtph2ps.128" ||         // Added in 11.0
              Name == "vcvtph2ps.256" ||         // Added in 11.0
              Name.starts_with("vextract") ||    // Added in 4.0
              Name.starts_with("vfmadd.") ||     // Added in 7.0
              Name.starts_with("vfmaddsub.") ||  // Added in 7.0
              Name.starts_with("vfnmadd.") ||    // Added in 7.0
              Name.starts_with("vfnmsub.") ||    // Added in 7.0
              Name.starts_with("vpdpbusd.") ||   // Added in 7.0
              Name.starts_with("vpdpbusds.") ||  // Added in 7.0
              Name.starts_with("vpdpwssd.") ||   // Added in 7.0
              Name.starts_with("vpdpwssds.") ||  // Added in 7.0
              Name.starts_with("vpermi2var.") || // Added in 7.0
              Name.starts_with("vpermil.p") ||   // Added in 3.9
              Name.starts_with("vpermilvar.") || // Added in 4.0
              Name.starts_with("vpermt2var.") || // Added in 7.0
              Name.starts_with("vpmadd52") ||    // Added in 7.0
              Name.starts_with("vpshld.") ||     // Added in 7.0
              Name.starts_with("vpshldv.") ||    // Added in 8.0
              Name.starts_with("vpshrd.") ||     // Added in 7.0
              Name.starts_with("vpshrdv.") ||    // Added in 8.0
              Name.starts_with("vpshufbitqmb.") || // Added in 8.0
              Name.starts_with("xor."));           // Added in 3.9

    if (Name.consume_front("mask3."))
      // 'avx512.mask3.*'
      return (Name.starts_with("vfmadd.") ||    // Added in 7.0
              Name.starts_with("vfmaddsub.") || // Added in 7.0
              Name.starts_with("vfmsub.") ||    // Added in 7.0
              Name.starts_with("vfmsubadd.") || // Added in 7.0
              Name.starts_with("vfnmsub."));    // Added in 7.0

    if (Name.consume_front("maskz."))
      // 'avx512.maskz.*'
      return (Name.starts_with("pternlog.") ||   // Added in 7.0
              Name.starts_with("vfmadd.") ||     // Added in 7.0
              Name.starts_with("vfmaddsub.") ||  // Added in 7.0
              Name.starts_with("vpdpbusd.") ||   // Added in 7.0
              Name.starts_with("vpdpbusds.") ||  // Added in 7.0
              Name.starts_with("vpdpwssd.") ||   // Added in 7.0
              Name.starts_with("vpdpwssds.") ||  // Added in 7.0
              Name.starts_with("vpermt2var.") || // Added in 7.0
              Name.starts_with("vpmadd52") ||    // Added in 7.0
              Name.starts_with("vpshldv.") ||    // Added in 8.0
              Name.starts_with("vpshrdv."));     // Added in 8.0

    // 'avx512.*'
    return (Name == "movntdqa" ||               // Added in 5.0
            Name == "pmul.dq.512" ||            // Added in 7.0
            Name == "pmulu.dq.512" ||           // Added in 7.0
            Name.starts_with("broadcastm") ||   // Added in 6.0
            Name.starts_with("cmp.p") ||        // Added in 12.0
            Name.starts_with("cvtb2mask.") ||   // Added in 7.0
            Name.starts_with("cvtd2mask.") ||   // Added in 7.0
            Name.starts_with("cvtmask2") ||     // Added in 5.0
            Name.starts_with("cvtq2mask.") ||   // Added in 7.0
            Name == "cvtusi2sd" ||              // Added in 7.0
            Name.starts_with("cvtw2mask.") ||   // Added in 7.0
            Name == "kand.w" ||                 // Added in 7.0
            Name == "kandn.w" ||                // Added in 7.0
            Name == "knot.w" ||                 // Added in 7.0
            Name == "kor.w" ||                  // Added in 7.0
            Name == "kortestc.w" ||             // Added in 7.0
            Name == "kortestz.w" ||             // Added in 7.0
            Name.starts_with("kunpck") ||       // added in 6.0
            Name == "kxnor.w" ||                // Added in 7.0
            Name == "kxor.w" ||                 // Added in 7.0
            Name.starts_with("padds.") ||       // Added in 8.0
            Name.starts_with("pbroadcast") ||   // Added in 3.9
            Name.starts_with("prol") ||         // Added in 8.0
            Name.starts_with("pror") ||         // Added in 8.0
            Name.starts_with("psll.dq") ||      // Added in 3.9
            Name.starts_with("psrl.dq") ||      // Added in 3.9
            Name.starts_with("psubs.") ||       // Added in 8.0
            Name.starts_with("ptestm") ||       // Added in 6.0
            Name.starts_with("ptestnm") ||      // Added in 6.0
            Name.starts_with("storent.") ||     // Added in 3.9
            Name.starts_with("vbroadcast.s") || // Added in 7.0
            Name.starts_with("vpshld.") ||      // Added in 8.0
            Name.starts_with("vpshrd."));       // Added in 8.0
  }

  if (Name.consume_front("fma."))
    return (Name.starts_with("vfmadd.") ||    // Added in 7.0
            Name.starts_with("vfmsub.") ||    // Added in 7.0
            Name.starts_with("vfmsubadd.") || // Added in 7.0
            Name.starts_with("vfnmadd.") ||   // Added in 7.0
            Name.starts_with("vfnmsub."));    // Added in 7.0

  if (Name.consume_front("fma4."))
    return Name.starts_with("vfmadd.s"); // Added in 7.0

  if (Name.consume_front("sse."))
    return (Name == "add.ss" ||            // Added in 4.0
            Name == "cvtsi2ss" ||          // Added in 7.0
            Name == "cvtsi642ss" ||        // Added in 7.0
            Name == "div.ss" ||            // Added in 4.0
            Name == "mul.ss" ||            // Added in 4.0
            Name.starts_with("sqrt.p") ||  // Added in 7.0
            Name == "sqrt.ss" ||           // Added in 7.0
            Name.starts_with("storeu.") || // Added in 3.9
            Name == "sub.ss");             // Added in 4.0

  if (Name.consume_front("sse2."))
    return (Name == "add.sd" ||            // Added in 4.0
            Name == "cvtdq2pd" ||          // Added in 3.9
            Name == "cvtdq2ps" ||          // Added in 7.0
            Name == "cvtps2pd" ||          // Added in 3.9
            Name == "cvtsi2sd" ||          // Added in 7.0
            Name == "cvtsi642sd" ||        // Added in 7.0
            Name == "cvtss2sd" ||          // Added in 7.0
            Name == "div.sd" ||            // Added in 4.0
            Name == "mul.sd" ||            // Added in 4.0
            Name.starts_with("padds.") ||  // Added in 8.0
            Name.starts_with("paddus.") || // Added in 8.0
            Name.starts_with("pcmpeq.") || // Added in 3.1
            Name.starts_with("pcmpgt.") || // Added in 3.1
            Name == "pmaxs.w" ||           // Added in 3.9
            Name == "pmaxu.b" ||           // Added in 3.9
            Name == "pmins.w" ||           // Added in 3.9
            Name == "pminu.b" ||           // Added in 3.9
            Name == "pmulu.dq" ||          // Added in 7.0
            Name.starts_with("pshuf") ||   // Added in 3.9
            Name.starts_with("psll.dq") || // Added in 3.7
            Name.starts_with("psrl.dq") || // Added in 3.7
            Name.starts_with("psubs.") ||  // Added in 8.0
            Name.starts_with("psubus.") || // Added in 8.0
            Name.starts_with("sqrt.p") ||  // Added in 7.0
            Name == "sqrt.sd" ||           // Added in 7.0
            Name == "storel.dq" ||         // Added in 3.9
            Name.starts_with("storeu.") || // Added in 3.9
            Name == "sub.sd");             // Added in 4.0

  if (Name.consume_front("sse41."))
    return (Name.starts_with("blendp") || // Added in 3.7
            Name == "movntdqa" ||         // Added in 5.0
            Name == "pblendw" ||          // Added in 3.7
            Name == "pmaxsb" ||           // Added in 3.9
            Name == "pmaxsd" ||           // Added in 3.9
            Name == "pmaxud" ||           // Added in 3.9
            Name == "pmaxuw" ||           // Added in 3.9
            Name == "pminsb" ||           // Added in 3.9
            Name == "pminsd" ||           // Added in 3.9
            Name == "pminud" ||           // Added in 3.9
            Name == "pminuw" ||           // Added in 3.9
            Name.starts_with("pmovsx") || // Added in 3.8
            Name.starts_with("pmovzx") || // Added in 3.9
            Name == "pmuldq");            // Added in 7.0

  if (Name.consume_front("sse42."))
    return Name == "crc32.64.8"; // Added in 3.4

  if (Name.consume_front("sse4a."))
    return Name.starts_with("movnt."); // Added in 3.9

  if (Name.consume_front("ssse3."))
    return (Name == "pabs.b.128" || // Added in 6.0
            Name == "pabs.d.128" || // Added in 6.0
            Name == "pabs.w.128");  // Added in 6.0

  if (Name.consume_front("xop."))
    return (Name == "vpcmov" ||          // Added in 3.8
            Name == "vpcmov.256" ||      // Added in 5.0
            Name.starts_with("vpcom") || // Added in 3.2, Updated in 9.0
            Name.starts_with("vprot"));  // Added in 8.0

  return (Name == "addcarry.u32" ||        // Added in 8.0
          Name == "addcarry.u64" ||        // Added in 8.0
          Name == "addcarryx.u32" ||       // Added in 8.0
          Name == "addcarryx.u64" ||       // Added in 8.0
          Name == "subborrow.u32" ||       // Added in 8.0
          Name == "subborrow.u64" ||       // Added in 8.0
          Name.starts_with("vcvtph2ps.")); // Added in 11.0
}

static bool upgradeX86IntrinsicFunction(Function *F, StringRef Name,
                                        Function *&NewFn) {
  // Only handle intrinsics that start with "x86.".
  if (!Name.consume_front("x86."))
    return false;

  if (shouldUpgradeX86Intrinsic(F, Name)) {
    NewFn = nullptr;
    return true;
  }

  if (Name == "rdtscp") { // Added in 8.0
    // If this intrinsic has 0 operands, it's the new version.
    if (F->getFunctionType()->getNumParams() == 0)
      return false;

    rename(F);
    NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(),
                                              Intrinsic::x86_rdtscp);
    return true;
  }

  Intrinsic::ID ID;

  // SSE4.1 ptest functions may have an old signature.
  if (Name.consume_front("sse41.ptest")) { // Added in 3.2
    ID = StringSwitch<Intrinsic::ID>(Name)
             .Case("c", Intrinsic::x86_sse41_ptestc)
             .Case("z", Intrinsic::x86_sse41_ptestz)
             .Case("nzc", Intrinsic::x86_sse41_ptestnzc)
             .Default(Intrinsic::not_intrinsic);
    if (ID != Intrinsic::not_intrinsic)
      return upgradePTESTIntrinsic(F, ID, NewFn);

    return false;
  }

  // Several blend and other instructions with masks used the wrong number of
  // bits.

  // Added in 3.6
  ID = StringSwitch<Intrinsic::ID>(Name)
           .Case("sse41.insertps", Intrinsic::x86_sse41_insertps)
           .Case("sse41.dppd", Intrinsic::x86_sse41_dppd)
           .Case("sse41.dpps", Intrinsic::x86_sse41_dpps)
           .Case("sse41.mpsadbw", Intrinsic::x86_sse41_mpsadbw)
           .Case("avx.dp.ps.256", Intrinsic::x86_avx_dp_ps_256)
           .Case("avx2.mpsadbw", Intrinsic::x86_avx2_mpsadbw)
           .Default(Intrinsic::not_intrinsic);
  if (ID != Intrinsic::not_intrinsic)
    return upgradeX86IntrinsicsWith8BitMask(F, ID, NewFn);

  if (Name.consume_front("avx512.")) {
    if (Name.consume_front("mask.cmp.")) {
      // Added in 7.0
      ID = StringSwitch<Intrinsic::ID>(Name)
               .Case("pd.128", Intrinsic::x86_avx512_mask_cmp_pd_128)
               .Case("pd.256", Intrinsic::x86_avx512_mask_cmp_pd_256)
               .Case("pd.512", Intrinsic::x86_avx512_mask_cmp_pd_512)
               .Case("ps.128", Intrinsic::x86_avx512_mask_cmp_ps_128)
               .Case("ps.256", Intrinsic::x86_avx512_mask_cmp_ps_256)
               .Case("ps.512", Intrinsic::x86_avx512_mask_cmp_ps_512)
               .Default(Intrinsic::not_intrinsic);
      if (ID != Intrinsic::not_intrinsic)
        return upgradeX86MaskedFPCompare(F, ID, NewFn);
    } else if (Name.starts_with("vpdpbusd.") ||
               Name.starts_with("vpdpbusds.")) {
      // Added in 21.1
      ID = StringSwitch<Intrinsic::ID>(Name)
               .Case("vpdpbusd.128", Intrinsic::x86_avx512_vpdpbusd_128)
               .Case("vpdpbusd.256", Intrinsic::x86_avx512_vpdpbusd_256)
               .Case("vpdpbusd.512", Intrinsic::x86_avx512_vpdpbusd_512)
               .Case("vpdpbusds.128", Intrinsic::x86_avx512_vpdpbusds_128)
               .Case("vpdpbusds.256", Intrinsic::x86_avx512_vpdpbusds_256)
               .Case("vpdpbusds.512", Intrinsic::x86_avx512_vpdpbusds_512)
               .Default(Intrinsic::not_intrinsic);
      if (ID != Intrinsic::not_intrinsic)
        return upgradeX86MultiplyAddBytes(F, ID, NewFn);
    } else if (Name.starts_with("vpdpwssd.") ||
               Name.starts_with("vpdpwssds.")) {
      // Added in 21.1
      ID = StringSwitch<Intrinsic::ID>(Name)
               .Case("vpdpwssd.128", Intrinsic::x86_avx512_vpdpwssd_128)
               .Case("vpdpwssd.256", Intrinsic::x86_avx512_vpdpwssd_256)
               .Case("vpdpwssd.512", Intrinsic::x86_avx512_vpdpwssd_512)
               .Case("vpdpwssds.128", Intrinsic::x86_avx512_vpdpwssds_128)
               .Case("vpdpwssds.256", Intrinsic::x86_avx512_vpdpwssds_256)
               .Case("vpdpwssds.512", Intrinsic::x86_avx512_vpdpwssds_512)
               .Default(Intrinsic::not_intrinsic);
      if (ID != Intrinsic::not_intrinsic)
        return upgradeX86MultiplyAddWords(F, ID, NewFn);
    }
    return false; // No other 'x86.avx512.*'.
  }

  if (Name.consume_front("avx2.")) {
    if (Name.consume_front("vpdpb")) {
      // Added in 21.1
      ID = StringSwitch<Intrinsic::ID>(Name)
               .Case("ssd.128", Intrinsic::x86_avx2_vpdpbssd_128)
               .Case("ssd.256", Intrinsic::x86_avx2_vpdpbssd_256)
               .Case("ssds.128", Intrinsic::x86_avx2_vpdpbssds_128)
               .Case("ssds.256", Intrinsic::x86_avx2_vpdpbssds_256)
               .Case("sud.128", Intrinsic::x86_avx2_vpdpbsud_128)
               .Case("sud.256", Intrinsic::x86_avx2_vpdpbsud_256)
               .Case("suds.128", Intrinsic::x86_avx2_vpdpbsuds_128)
               .Case("suds.256", Intrinsic::x86_avx2_vpdpbsuds_256)
               .Case("uud.128", Intrinsic::x86_avx2_vpdpbuud_128)
               .Case("uud.256", Intrinsic::x86_avx2_vpdpbuud_256)
               .Case("uuds.128", Intrinsic::x86_avx2_vpdpbuuds_128)
               .Case("uuds.256", Intrinsic::x86_avx2_vpdpbuuds_256)
               .Default(Intrinsic::not_intrinsic);
      if (ID != Intrinsic::not_intrinsic)
        return upgradeX86MultiplyAddBytes(F, ID, NewFn);
    } else if (Name.consume_front("vpdpw")) {
      // Added in 21.1
      ID = StringSwitch<Intrinsic::ID>(Name)
               .Case("sud.128", Intrinsic::x86_avx2_vpdpwsud_128)
               .Case("sud.256", Intrinsic::x86_avx2_vpdpwsud_256)
               .Case("suds.128", Intrinsic::x86_avx2_vpdpwsuds_128)
               .Case("suds.256", Intrinsic::x86_avx2_vpdpwsuds_256)
               .Case("usd.128", Intrinsic::x86_avx2_vpdpwusd_128)
               .Case("usd.256", Intrinsic::x86_avx2_vpdpwusd_256)
               .Case("usds.128", Intrinsic::x86_avx2_vpdpwusds_128)
               .Case("usds.256", Intrinsic::x86_avx2_vpdpwusds_256)
               .Case("uud.128", Intrinsic::x86_avx2_vpdpwuud_128)
               .Case("uud.256", Intrinsic::x86_avx2_vpdpwuud_256)
               .Case("uuds.128", Intrinsic::x86_avx2_vpdpwuuds_128)
               .Case("uuds.256", Intrinsic::x86_avx2_vpdpwuuds_256)
               .Default(Intrinsic::not_intrinsic);
      if (ID != Intrinsic::not_intrinsic)
        return upgradeX86MultiplyAddWords(F, ID, NewFn);
    }
    return false; // No other 'x86.avx2.*'
  }

  if (Name.consume_front("avx10.")) {
    if (Name.consume_front("vpdpb")) {
      // Added in 21.1
      ID = StringSwitch<Intrinsic::ID>(Name)
               .Case("ssd.512", Intrinsic::x86_avx10_vpdpbssd_512)
               .Case("ssds.512", Intrinsic::x86_avx10_vpdpbssds_512)
               .Case("sud.512", Intrinsic::x86_avx10_vpdpbsud_512)
               .Case("suds.512", Intrinsic::x86_avx10_vpdpbsuds_512)
               .Case("uud.512", Intrinsic::x86_avx10_vpdpbuud_512)
               .Case("uuds.512", Intrinsic::x86_avx10_vpdpbuuds_512)
               .Default(Intrinsic::not_intrinsic);
      if (ID != Intrinsic::not_intrinsic)
        return upgradeX86MultiplyAddBytes(F, ID, NewFn);
    } else if (Name.consume_front("vpdpw")) {
      ID = StringSwitch<Intrinsic::ID>(Name)
               .Case("sud.512", Intrinsic::x86_avx10_vpdpwsud_512)
               .Case("suds.512", Intrinsic::x86_avx10_vpdpwsuds_512)
               .Case("usd.512", Intrinsic::x86_avx10_vpdpwusd_512)
               .Case("usds.512", Intrinsic::x86_avx10_vpdpwusds_512)
               .Case("uud.512", Intrinsic::x86_avx10_vpdpwuud_512)
               .Case("uuds.512", Intrinsic::x86_avx10_vpdpwuuds_512)
               .Default(Intrinsic::not_intrinsic);
      if (ID != Intrinsic::not_intrinsic)
        return upgradeX86MultiplyAddWords(F, ID, NewFn);
    }
    return false; // No other 'x86.avx10.*'
  }

  if (Name.consume_front("avx512bf16.")) {
    // Added in 9.0
    ID = StringSwitch<Intrinsic::ID>(Name)
             .Case("cvtne2ps2bf16.128",
                   Intrinsic::x86_avx512bf16_cvtne2ps2bf16_128)
             .Case("cvtne2ps2bf16.256",
                   Intrinsic::x86_avx512bf16_cvtne2ps2bf16_256)
             .Case("cvtne2ps2bf16.512",
                   Intrinsic::x86_avx512bf16_cvtne2ps2bf16_512)
             .Case("mask.cvtneps2bf16.128",
                   Intrinsic::x86_avx512bf16_mask_cvtneps2bf16_128)
             .Case("cvtneps2bf16.256",
                   Intrinsic::x86_avx512bf16_cvtneps2bf16_256)
             .Case("cvtneps2bf16.512",
                   Intrinsic::x86_avx512bf16_cvtneps2bf16_512)
             .Default(Intrinsic::not_intrinsic);
    if (ID != Intrinsic::not_intrinsic)
      return upgradeX86BF16Intrinsic(F, ID, NewFn);

    // Added in 9.0
    ID = StringSwitch<Intrinsic::ID>(Name)
             .Case("dpbf16ps.128", Intrinsic::x86_avx512bf16_dpbf16ps_128)
             .Case("dpbf16ps.256", Intrinsic::x86_avx512bf16_dpbf16ps_256)
             .Case("dpbf16ps.512", Intrinsic::x86_avx512bf16_dpbf16ps_512)
             .Default(Intrinsic::not_intrinsic);
    if (ID != Intrinsic::not_intrinsic)
      return upgradeX86BF16DPIntrinsic(F, ID, NewFn);
    return false; // No other 'x86.avx512bf16.*'.
  }

  if (Name.consume_front("xop.")) {
    Intrinsic::ID ID = Intrinsic::not_intrinsic;
    if (Name.starts_with("vpermil2")) { // Added in 3.9
      // Upgrade any XOP PERMIL2 index operand still using a float/double
      // vector.
      auto Idx = F->getFunctionType()->getParamType(2);
      if (Idx->isFPOrFPVectorTy()) {
        unsigned IdxSize = Idx->getPrimitiveSizeInBits();
        unsigned EltSize = Idx->getScalarSizeInBits();
        if (EltSize == 64 && IdxSize == 128)
          ID = Intrinsic::x86_xop_vpermil2pd;
        else if (EltSize == 32 && IdxSize == 128)
          ID = Intrinsic::x86_xop_vpermil2ps;
        else if (EltSize == 64 && IdxSize == 256)
          ID = Intrinsic::x86_xop_vpermil2pd_256;
        else
          ID = Intrinsic::x86_xop_vpermil2ps_256;
      }
    } else if (F->arg_size() == 2)
      // frcz.ss/sd may need to have an argument dropped. Added in 3.2
      ID = StringSwitch<Intrinsic::ID>(Name)
               .Case("vfrcz.ss", Intrinsic::x86_xop_vfrcz_ss)
               .Case("vfrcz.sd", Intrinsic::x86_xop_vfrcz_sd)
               .Default(Intrinsic::not_intrinsic);

    if (ID != Intrinsic::not_intrinsic) {
      rename(F);
      NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), ID);
      return true;
    }
    return false; // No other 'x86.xop.*'
  }

  if (Name == "seh.recoverfp") {
    NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(),
                                              Intrinsic::eh_recoverfp);
    return true;
  }

  return false;
}

// Upgrade ARM (IsArm) or Aarch64 (!IsArm) intrinsic fns. Return true iff so.
// IsArm: 'arm.*', !IsArm: 'aarch64.*'.
static bool upgradeArmOrAarch64IntrinsicFunction(bool IsArm, Function *F,
                                                 StringRef Name,
                                                 Function *&NewFn) {
  if (Name.starts_with("rbit")) {
    // '(arm|aarch64).rbit'.
    NewFn = Intrinsic::getOrInsertDeclaration(
        F->getParent(), Intrinsic::bitreverse, F->arg_begin()->getType());
    return true;
  }

  if (Name == "thread.pointer") {
    // '(arm|aarch64).thread.pointer'.
    NewFn = Intrinsic::getOrInsertDeclaration(
        F->getParent(), Intrinsic::thread_pointer, F->getReturnType());
    return true;
  }

  bool Neon = Name.consume_front("neon.");
  if (Neon) {
    // '(arm|aarch64).neon.*'.
    // Changed in 12.0: bfdot accept v4bf16 and v8bf16 instead of v8i8 and
    // v16i8 respectively.
    if (Name.consume_front("bfdot.")) {
      // (arm|aarch64).neon.bfdot.*'.
      Intrinsic::ID ID =
          StringSwitch<Intrinsic::ID>(Name)
              .Cases({"v2f32.v8i8", "v4f32.v16i8"},
                     IsArm ? (Intrinsic::ID)Intrinsic::arm_neon_bfdot
                           : (Intrinsic::ID)Intrinsic::aarch64_neon_bfdot)
              .Default(Intrinsic::not_intrinsic);
      if (ID != Intrinsic::not_intrinsic) {
        size_t OperandWidth = F->getReturnType()->getPrimitiveSizeInBits();
        assert((OperandWidth == 64 || OperandWidth == 128) &&
               "Unexpected operand width");
        LLVMContext &Ctx = F->getParent()->getContext();
        std::array<Type *, 2> Tys{
            {F->getReturnType(),
             FixedVectorType::get(Type::getBFloatTy(Ctx), OperandWidth / 16)}};
        NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), ID, Tys);
        return true;
      }
      return false; // No other '(arm|aarch64).neon.bfdot.*'.
    }

    // Changed in 12.0: bfmmla, bfmlalb and bfmlalt are not polymorphic
    // anymore and accept v8bf16 instead of v16i8.
    if (Name.consume_front("bfm")) {
      // (arm|aarch64).neon.bfm*'.
      if (Name.consume_back(".v4f32.v16i8")) {
        // (arm|aarch64).neon.bfm*.v4f32.v16i8'.
        Intrinsic::ID ID =
            StringSwitch<Intrinsic::ID>(Name)
                .Case("mla",
                      IsArm ? (Intrinsic::ID)Intrinsic::arm_neon_bfmmla
                            : (Intrinsic::ID)Intrinsic::aarch64_neon_bfmmla)
                .Case("lalb",
                      IsArm ? (Intrinsic::ID)Intrinsic::arm_neon_bfmlalb
                            : (Intrinsic::ID)Intrinsic::aarch64_neon_bfmlalb)
                .Case("lalt",
                      IsArm ? (Intrinsic::ID)Intrinsic::arm_neon_bfmlalt
                            : (Intrinsic::ID)Intrinsic::aarch64_neon_bfmlalt)
                .Default(Intrinsic::not_intrinsic);
        if (ID != Intrinsic::not_intrinsic) {
          NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), ID);
          return true;
        }
        return false; // No other '(arm|aarch64).neon.bfm*.v16i8'.
      }
      return false; // No other '(arm|aarch64).neon.bfm*.
    }
    // Continue on to Aarch64 Neon or Arm Neon.
  }
  // Continue on to Arm or Aarch64.

  if (IsArm) {
    // 'arm.*'.
    if (Neon) {
      // 'arm.neon.*'.
      Intrinsic::ID ID = StringSwitch<Intrinsic::ID>(Name)
                             .StartsWith("vclz.", Intrinsic::ctlz)
                             .StartsWith("vcnt.", Intrinsic::ctpop)
                             .StartsWith("vqadds.", Intrinsic::sadd_sat)
                             .StartsWith("vqaddu.", Intrinsic::uadd_sat)
                             .StartsWith("vqsubs.", Intrinsic::ssub_sat)
                             .StartsWith("vqsubu.", Intrinsic::usub_sat)
                             .StartsWith("vrinta.", Intrinsic::round)
                             .StartsWith("vrintn.", Intrinsic::roundeven)
                             .StartsWith("vrintm.", Intrinsic::floor)
                             .StartsWith("vrintp.", Intrinsic::ceil)
                             .StartsWith("vrintx.", Intrinsic::rint)
                             .StartsWith("vrintz.", Intrinsic::trunc)
                             .Default(Intrinsic::not_intrinsic);
      if (ID != Intrinsic::not_intrinsic) {
        NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), ID,
                                                  F->arg_begin()->getType());
        return true;
      }

      if (Name.consume_front("vst")) {
        // 'arm.neon.vst*'.
        static const Regex vstRegex("^([1234]|[234]lane)\\.v[a-z0-9]*$");
        SmallVector<StringRef, 2> Groups;
        if (vstRegex.match(Name, &Groups)) {
          static const Intrinsic::ID StoreInts[] = {
              Intrinsic::arm_neon_vst1, Intrinsic::arm_neon_vst2,
              Intrinsic::arm_neon_vst3, Intrinsic::arm_neon_vst4};

          static const Intrinsic::ID StoreLaneInts[] = {
              Intrinsic::arm_neon_vst2lane, Intrinsic::arm_neon_vst3lane,
              Intrinsic::arm_neon_vst4lane};

          auto fArgs = F->getFunctionType()->params();
          Type *Tys[] = {fArgs[0], fArgs[1]};
          if (Groups[1].size() == 1)
            NewFn = Intrinsic::getOrInsertDeclaration(
                F->getParent(), StoreInts[fArgs.size() - 3], Tys);
          else
            NewFn = Intrinsic::getOrInsertDeclaration(
                F->getParent(), StoreLaneInts[fArgs.size() - 5], Tys);
          return true;
        }
        return false; // No other 'arm.neon.vst*'.
      }

      return false; // No other 'arm.neon.*'.
    }

    if (Name.consume_front("mve.")) {
      // 'arm.mve.*'.
      if (Name == "vctp64") {
        if (cast<FixedVectorType>(F->getReturnType())->getNumElements() == 4) {
          // A vctp64 returning a v4i1 is converted to return a v2i1. Rename
          // the function and deal with it below in UpgradeIntrinsicCall.
          rename(F);
          return true;
        }
        return false; // Not 'arm.mve.vctp64'.
      }

      if (Name.starts_with("vrintn.v")) {
        NewFn = Intrinsic::getOrInsertDeclaration(
            F->getParent(), Intrinsic::roundeven, F->arg_begin()->getType());
        return true;
      }

      // These too are changed to accept a v2i1 instead of the old v4i1.
      if (Name.consume_back(".v4i1")) {
        // 'arm.mve.*.v4i1'.
        if (Name.consume_back(".predicated.v2i64.v4i32"))
          // 'arm.mve.*.predicated.v2i64.v4i32.v4i1'
          return Name == "mull.int" || Name == "vqdmull";

        if (Name.consume_back(".v2i64")) {
          // 'arm.mve.*.v2i64.v4i1'
          bool IsGather = Name.consume_front("vldr.gather.");
          if (IsGather || Name.consume_front("vstr.scatter.")) {
            if (Name.consume_front("base.")) {
              // Optional 'wb.' prefix.
              Name.consume_front("wb.");
              // 'arm.mve.(vldr.gather|vstr.scatter).base.(wb.)?
              // predicated.v2i64.v2i64.v4i1'.
              return Name == "predicated.v2i64";
            }

            if (Name.consume_front("offset.predicated."))
              return Name == (IsGather ? "v2i64.p0i64" : "p0i64.v2i64") ||
                     Name == (IsGather ? "v2i64.p0" : "p0.v2i64");

            // No other 'arm.mve.(vldr.gather|vstr.scatter).*.v2i64.v4i1'.
            return false;
          }

          return false; // No other 'arm.mve.*.v2i64.v4i1'.
        }
        return false; // No other 'arm.mve.*.v4i1'.
      }
      return false; // No other 'arm.mve.*'.
    }

    if (Name.consume_front("cde.vcx")) {
      // 'arm.cde.vcx*'.
      if (Name.consume_back(".predicated.v2i64.v4i1"))
        // 'arm.cde.vcx*.predicated.v2i64.v4i1'.
        return Name == "1q" || Name == "1qa" || Name == "2q" || Name == "2qa" ||
               Name == "3q" || Name == "3qa";

      return false; // No other 'arm.cde.vcx*'.
    }
  } else {
    // 'aarch64.*'.
    if (Neon) {
      // 'aarch64.neon.*'.
      Intrinsic::ID ID = StringSwitch<Intrinsic::ID>(Name)
                             .StartsWith("frintn", Intrinsic::roundeven)
                             .StartsWith("rbit", Intrinsic::bitreverse)
                             .Default(Intrinsic::not_intrinsic);
      if (ID != Intrinsic::not_intrinsic) {
        NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), ID,
                                                  F->arg_begin()->getType());
        return true;
      }

      if (Name.starts_with("addp")) {
        // 'aarch64.neon.addp*'.
        if (F->arg_size() != 2)
          return false; // Invalid IR.
        VectorType *Ty = dyn_cast<VectorType>(F->getReturnType());
        if (Ty && Ty->getElementType()->isFloatingPointTy()) {
          NewFn = Intrinsic::getOrInsertDeclaration(
              F->getParent(), Intrinsic::aarch64_neon_faddp, Ty);
          return true;
        }
      }

      // Changed in 20.0: bfcvt/bfcvtn/bcvtn2 have been replaced with fptrunc.
      if (Name.starts_with("bfcvt")) {
        NewFn = nullptr;
        return true;
      }

      return false; // No other 'aarch64.neon.*'.
    }
    if (Name.consume_front("sve.")) {
      // 'aarch64.sve.*'.
      if (Name.consume_front("bf")) {
        if (Name.consume_back(".lane")) {
          // 'aarch64.sve.bf*.lane'.
          Intrinsic::ID ID =
              StringSwitch<Intrinsic::ID>(Name)
                  .Case("dot", Intrinsic::aarch64_sve_bfdot_lane_v2)
                  .Case("mlalb", Intrinsic::aarch64_sve_bfmlalb_lane_v2)
                  .Case("mlalt", Intrinsic::aarch64_sve_bfmlalt_lane_v2)
                  .Default(Intrinsic::not_intrinsic);
          if (ID != Intrinsic::not_intrinsic) {
            NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), ID);
            return true;
          }
          return false; // No other 'aarch64.sve.bf*.lane'.
        }
        return false; // No other 'aarch64.sve.bf*'.
      }

      // 'aarch64.sve.fcvt.bf16f32' || 'aarch64.sve.fcvtnt.bf16f32'
      if (Name == "fcvt.bf16f32" || Name == "fcvtnt.bf16f32") {
        NewFn = nullptr;
        return true;
      }

      if (Name.consume_front("addqv")) {
        // 'aarch64.sve.addqv'.
        if (!F->getReturnType()->isFPOrFPVectorTy())
          return false;

        auto Args = F->getFunctionType()->params();
        Type *Tys[] = {F->getReturnType(), Args[1]};
        NewFn = Intrinsic::getOrInsertDeclaration(
            F->getParent(), Intrinsic::aarch64_sve_faddqv, Tys);
        return true;
      }

      if (Name.consume_front("ld")) {
        // 'aarch64.sve.ld*'.
        static const Regex LdRegex("^[234](.nxv[a-z0-9]+|$)");
        if (LdRegex.match(Name)) {
          Type *ScalarTy =
              cast<VectorType>(F->getReturnType())->getElementType();
          ElementCount EC =
              cast<VectorType>(F->arg_begin()->getType())->getElementCount();
          assert(F->arg_size() == 2 &&
                 "Expected 2 arguments for ld* intrinsic.");
          Type *PtrTy = F->getArg(1)->getType();
          Type *Ty = VectorType::get(ScalarTy, EC);
          static const Intrinsic::ID LoadIDs[] = {
              Intrinsic::aarch64_sve_ld2_sret,
              Intrinsic::aarch64_sve_ld3_sret,
              Intrinsic::aarch64_sve_ld4_sret,
          };
          NewFn = Intrinsic::getOrInsertDeclaration(
              F->getParent(), LoadIDs[Name[0] - '2'], {Ty, PtrTy});
          return true;
        }
        return false; // No other 'aarch64.sve.ld*'.
      }

      if (Name.consume_front("tuple.")) {
        // 'aarch64.sve.tuple.*'.
        if (Name.starts_with("get")) {
          // 'aarch64.sve.tuple.get*'.
          Type *Tys[] = {F->getReturnType(), F->arg_begin()->getType()};
          NewFn = Intrinsic::getOrInsertDeclaration(
              F->getParent(), Intrinsic::vector_extract, Tys);
          return true;
        }

        if (Name.starts_with("set")) {
          // 'aarch64.sve.tuple.set*'.
          auto Args = F->getFunctionType()->params();
          Type *Tys[] = {Args[0], Args[2], Args[1]};
          NewFn = Intrinsic::getOrInsertDeclaration(
              F->getParent(), Intrinsic::vector_insert, Tys);
          return true;
        }

        static const Regex CreateTupleRegex("^create[234](.nxv[a-z0-9]+|$)");
        if (CreateTupleRegex.match(Name)) {
          // 'aarch64.sve.tuple.create*'.
          auto Args = F->getFunctionType()->params();
          Type *Tys[] = {F->getReturnType(), Args[1]};
          NewFn = Intrinsic::getOrInsertDeclaration(
              F->getParent(), Intrinsic::vector_insert, Tys);
          return true;
        }
        return false; // No other 'aarch64.sve.tuple.*'.
      }

      if (Name.starts_with("rev.nxv")) {
        // 'aarch64.sve.rev.<Ty>'
        NewFn = Intrinsic::getOrInsertDeclaration(
            F->getParent(), Intrinsic::vector_reverse, F->getReturnType());
        return true;
      }

      return false; // No other 'aarch64.sve.*'.
    }
  }
  return false; // No other 'arm.*', 'aarch64.*'.
}

static Intrinsic::ID shouldUpgradeNVPTXTMAG2SIntrinsics(Function *F,
                                                        StringRef Name) {
  if (Name.consume_front("cp.async.bulk.tensor.g2s.")) {
    Intrinsic::ID ID =
        StringSwitch<Intrinsic::ID>(Name)
            .Case("im2col.3d",
                  Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_3d)
            .Case("im2col.4d",
                  Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_4d)
            .Case("im2col.5d",
                  Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_5d)
            .Case("tile.1d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_1d)
            .Case("tile.2d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_2d)
            .Case("tile.3d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_3d)
            .Case("tile.4d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_4d)
            .Case("tile.5d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_5d)
            .Default(Intrinsic::not_intrinsic);

    if (ID == Intrinsic::not_intrinsic)
      return ID;

    // These intrinsics may need upgrade for two reasons:
    // (1) When the address-space of the first argument is shared[AS=3]
    //     (and we upgrade it to use shared_cluster address-space[AS=7])
    if (F->getArg(0)->getType()->getPointerAddressSpace() ==
        NVPTXAS::ADDRESS_SPACE_SHARED)
      return ID;

    // (2) When there are only two boolean flag arguments at the end:
    //
    // The last three parameters of the older version of these
    // intrinsics are: arg1, arg2, .. i64 ch, i1 mc_flag, i1 ch_flag
    //
    // The newer version reads as:
    // arg1, arg2, .. i64 ch, i1 mc_flag, i1 ch_flag, i32 cta_group_flag
    //
    // So, when the type of the [N-3]rd argument is "not i1", then
    // it is the older version and we need to upgrade.
    size_t FlagStartIndex = F->getFunctionType()->getNumParams() - 3;
    Type *ArgType = F->getFunctionType()->getParamType(FlagStartIndex);
    if (!ArgType->isIntegerTy(1))
      return ID;
  }

  return Intrinsic::not_intrinsic;
}

static Intrinsic::ID shouldUpgradeNVPTXSharedClusterIntrinsic(Function *F,
                                                              StringRef Name) {
  if (Name.consume_front("mapa.shared.cluster"))
    if (F->getReturnType()->getPointerAddressSpace() ==
        NVPTXAS::ADDRESS_SPACE_SHARED)
      return Intrinsic::nvvm_mapa_shared_cluster;

  if (Name.consume_front("cp.async.bulk.")) {
    Intrinsic::ID ID =
        StringSwitch<Intrinsic::ID>(Name)
            .Case("global.to.shared.cluster",
                  Intrinsic::nvvm_cp_async_bulk_global_to_shared_cluster)
            .Case("shared.cta.to.cluster",
                  Intrinsic::nvvm_cp_async_bulk_shared_cta_to_cluster)
            .Default(Intrinsic::not_intrinsic);

    if (ID != Intrinsic::not_intrinsic)
      if (F->getArg(0)->getType()->getPointerAddressSpace() ==
          NVPTXAS::ADDRESS_SPACE_SHARED)
        return ID;
  }

  return Intrinsic::not_intrinsic;
}

static Intrinsic::ID shouldUpgradeNVPTXBF16Intrinsic(StringRef Name) {
  if (Name.consume_front("fma.rn."))
    return StringSwitch<Intrinsic::ID>(Name)
        .Case("bf16", Intrinsic::nvvm_fma_rn_bf16)
        .Case("bf16x2", Intrinsic::nvvm_fma_rn_bf16x2)
        .Case("relu.bf16", Intrinsic::nvvm_fma_rn_relu_bf16)
        .Case("relu.bf16x2", Intrinsic::nvvm_fma_rn_relu_bf16x2)
        .Default(Intrinsic::not_intrinsic);

  if (Name.consume_front("fmax."))
    return StringSwitch<Intrinsic::ID>(Name)
        .Case("bf16", Intrinsic::nvvm_fmax_bf16)
        .Case("bf16x2", Intrinsic::nvvm_fmax_bf16x2)
        .Case("ftz.bf16", Intrinsic::nvvm_fmax_ftz_bf16)
        .Case("ftz.bf16x2", Intrinsic::nvvm_fmax_ftz_bf16x2)
        .Case("ftz.nan.bf16", Intrinsic::nvvm_fmax_ftz_nan_bf16)
        .Case("ftz.nan.bf16x2", Intrinsic::nvvm_fmax_ftz_nan_bf16x2)
        .Case("ftz.nan.xorsign.abs.bf16",
              Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_bf16)
        .Case("ftz.nan.xorsign.abs.bf16x2",
              Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_bf16x2)
        .Case("ftz.xorsign.abs.bf16", Intrinsic::nvvm_fmax_ftz_xorsign_abs_bf16)
        .Case("ftz.xorsign.abs.bf16x2",
              Intrinsic::nvvm_fmax_ftz_xorsign_abs_bf16x2)
        .Case("nan.bf16", Intrinsic::nvvm_fmax_nan_bf16)
        .Case("nan.bf16x2", Intrinsic::nvvm_fmax_nan_bf16x2)
        .Case("nan.xorsign.abs.bf16", Intrinsic::nvvm_fmax_nan_xorsign_abs_bf16)
        .Case("nan.xorsign.abs.bf16x2",
              Intrinsic::nvvm_fmax_nan_xorsign_abs_bf16x2)
        .Case("xorsign.abs.bf16", Intrinsic::nvvm_fmax_xorsign_abs_bf16)
        .Case("xorsign.abs.bf16x2", Intrinsic::nvvm_fmax_xorsign_abs_bf16x2)
        .Default(Intrinsic::not_intrinsic);

  if (Name.consume_front("fmin."))
    return StringSwitch<Intrinsic::ID>(Name)
        .Case("bf16", Intrinsic::nvvm_fmin_bf16)
        .Case("bf16x2", Intrinsic::nvvm_fmin_bf16x2)
        .Case("ftz.bf16", Intrinsic::nvvm_fmin_ftz_bf16)
        .Case("ftz.bf16x2", Intrinsic::nvvm_fmin_ftz_bf16x2)
        .Case("ftz.nan.bf16", Intrinsic::nvvm_fmin_ftz_nan_bf16)
        .Case("ftz.nan.bf16x2", Intrinsic::nvvm_fmin_ftz_nan_bf16x2)
        .Case("ftz.nan.xorsign.abs.bf16",
              Intrinsic::nvvm_fmin_ftz_nan_xorsign_abs_bf16)
        .Case("ftz.nan.xorsign.abs.bf16x2",
              Intrinsic::nvvm_fmin_ftz_nan_xorsign_abs_bf16x2)
        .Case("ftz.xorsign.abs.bf16", Intrinsic::nvvm_fmin_ftz_xorsign_abs_bf16)
        .Case("ftz.xorsign.abs.bf16x2",
              Intrinsic::nvvm_fmin_ftz_xorsign_abs_bf16x2)
        .Case("nan.bf16", Intrinsic::nvvm_fmin_nan_bf16)
        .Case("nan.bf16x2", Intrinsic::nvvm_fmin_nan_bf16x2)
        .Case("nan.xorsign.abs.bf16", Intrinsic::nvvm_fmin_nan_xorsign_abs_bf16)
        .Case("nan.xorsign.abs.bf16x2",
              Intrinsic::nvvm_fmin_nan_xorsign_abs_bf16x2)
        .Case("xorsign.abs.bf16", Intrinsic::nvvm_fmin_xorsign_abs_bf16)
        .Case("xorsign.abs.bf16x2", Intrinsic::nvvm_fmin_xorsign_abs_bf16x2)
        .Default(Intrinsic::not_intrinsic);

  if (Name.consume_front("neg."))
    return StringSwitch<Intrinsic::ID>(Name)
        .Case("bf16", Intrinsic::nvvm_neg_bf16)
        .Case("bf16x2", Intrinsic::nvvm_neg_bf16x2)
        .Default(Intrinsic::not_intrinsic);

  return Intrinsic::not_intrinsic;
}

static bool consumeNVVMPtrAddrSpace(StringRef &Name) {
  return Name.consume_front("local") || Name.consume_front("shared") ||
         Name.consume_front("global") || Name.consume_front("constant") ||
         Name.consume_front("param");
}

static bool convertIntrinsicValidType(StringRef Name,
                                      const FunctionType *FuncTy) {
  Type *HalfTy = Type::getHalfTy(FuncTy->getContext());
  if (Name.starts_with("to.fp16")) {
    return CastInst::castIsValid(Instruction::FPTrunc, FuncTy->getParamType(0),
                                 HalfTy) &&
           CastInst::castIsValid(Instruction::BitCast, HalfTy,
                                 FuncTy->getReturnType());
  }

  if (Name.starts_with("from.fp16")) {
    return CastInst::castIsValid(Instruction::BitCast, FuncTy->getParamType(0),
                                 HalfTy) &&
           CastInst::castIsValid(Instruction::FPExt, HalfTy,
                                 FuncTy->getReturnType());
  }

  return false;
}

static bool upgradeIntrinsicFunction1(Function *F, Function *&NewFn,
                                      bool CanUpgradeDebugIntrinsicsToRecords) {
  assert(F && "Illegal to upgrade a non-existent Function.");

  StringRef Name = F->getName();

  // Quickly eliminate it, if it's not a candidate.
  if (!Name.consume_front("llvm.") || Name.empty())
    return false;

  switch (Name[0]) {
  default: break;
  case 'a': {
    bool IsArm = Name.consume_front("arm.");
    if (IsArm || Name.consume_front("aarch64.")) {
      if (upgradeArmOrAarch64IntrinsicFunction(IsArm, F, Name, NewFn))
        return true;
      break;
    }

    if (Name.consume_front("amdgcn.")) {
      if (Name == "alignbit") {
        // Target specific intrinsic became redundant
        NewFn = Intrinsic::getOrInsertDeclaration(
            F->getParent(), Intrinsic::fshr, {F->getReturnType()});
        return true;
      }

      if (Name.consume_front("atomic.")) {
        if (Name.starts_with("inc") || Name.starts_with("dec") ||
            Name.starts_with("cond.sub") || Name.starts_with("csub")) {
          // These were replaced with atomicrmw uinc_wrap, udec_wrap, usub_cond
          // and usub_sat so there's no new declaration.
          NewFn = nullptr;
          return true;
        }
        break; // No other 'amdgcn.atomic.*'
      }

      switch (F->getIntrinsicID()) {
      default:
        break;
      // Legacy wmma iu intrinsics without the optional clamp operand.
      case Intrinsic::amdgcn_wmma_i32_16x16x64_iu8:
        if (F->arg_size() == 7) {
          NewFn = nullptr;
          return true;
        }
        break;
      case Intrinsic::amdgcn_swmmac_i32_16x16x128_iu8:
      case Intrinsic::amdgcn_wmma_f32_16x16x4_f32:
      case Intrinsic::amdgcn_wmma_f32_16x16x32_bf16:
      case Intrinsic::amdgcn_wmma_f32_16x16x32_f16:
      case Intrinsic::amdgcn_wmma_f16_16x16x32_f16:
      case Intrinsic::amdgcn_wmma_bf16_16x16x32_bf16:
      case Intrinsic::amdgcn_wmma_bf16f32_16x16x32_bf16:
        if (F->arg_size() == 8) {
          NewFn = nullptr;
          return true;
        }
        break;
      }

      if (Name.consume_front("ds.") || Name.consume_front("global.atomic.") ||
          Name.consume_front("flat.atomic.")) {
        if (Name.starts_with("fadd") ||
            // FIXME: We should also remove fmin.num and fmax.num intrinsics.
            (Name.starts_with("fmin") && !Name.starts_with("fmin.num")) ||
            (Name.starts_with("fmax") && !Name.starts_with("fmax.num"))) {
          // Replaced with atomicrmw fadd/fmin/fmax, so there's no new
          // declaration.
          NewFn = nullptr;
          return true;
        }
      }

      if (Name.starts_with("ldexp.")) {
        // Target specific intrinsic became redundant
        NewFn = Intrinsic::getOrInsertDeclaration(
            F->getParent(), Intrinsic::ldexp,
            {F->getReturnType(), F->getArg(1)->getType()});
        return true;
      }
      break; // No other 'amdgcn.*'
    }

    break;
  }
  case 'c': {
    if (F->arg_size() == 1) {
      if (Name.consume_front("convert.")) {
        if (convertIntrinsicValidType(Name, F->getFunctionType())) {
          NewFn = nullptr;
          return true;
        }
      }

      Intrinsic::ID ID = StringSwitch<Intrinsic::ID>(Name)
                             .StartsWith("ctlz.", Intrinsic::ctlz)
                             .StartsWith("cttz.", Intrinsic::cttz)
                             .Default(Intrinsic::not_intrinsic);
      if (ID != Intrinsic::not_intrinsic) {
        rename(F);
        NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), ID,
                                                  F->arg_begin()->getType());
        return true;
      }
    }

    if (F->arg_size() == 2 && Name == "coro.end") {
      rename(F);
      NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(),
                                                Intrinsic::coro_end);
      return true;
    }

    break;
  }
  case 'd':
    if (Name.consume_front("dbg.")) {
      // Mark debug intrinsics for upgrade to new debug format.
      if (CanUpgradeDebugIntrinsicsToRecords) {
        if (Name == "addr" || Name == "value" || Name == "assign" ||
            Name == "declare" || Name == "label") {
          // There's no function to replace these with.
          NewFn = nullptr;
          // But we do want these to get upgraded.
          return true;
        }
      }
      // Update llvm.dbg.addr intrinsics even in "new debug mode"; they'll get
      // converted to DbgVariableRecords later.
      if (Name == "addr" || (Name == "value" && F->arg_size() == 4)) {
        rename(F);
        NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(),
                                                  Intrinsic::dbg_value);
        return true;
      }
      break; // No other 'dbg.*'.
    }
    break;
  case 'e':
    if (Name.consume_front("experimental.vector.")) {
      Intrinsic::ID ID =
          StringSwitch<Intrinsic::ID>(Name)
              // Skip over extract.last.active, otherwise it will be 'upgraded'
              // to a regular vector extract which is a different operation.
              .StartsWith("extract.last.active.", Intrinsic::not_intrinsic)
              .StartsWith("extract.", Intrinsic::vector_extract)
              .StartsWith("insert.", Intrinsic::vector_insert)
              .StartsWith("reverse.", Intrinsic::vector_reverse)
              .StartsWith("interleave2.", Intrinsic::vector_interleave2)
              .StartsWith("deinterleave2.", Intrinsic::vector_deinterleave2)
              .StartsWith("partial.reduce.add",
                          Intrinsic::vector_partial_reduce_add)
              .Default(Intrinsic::not_intrinsic);
      if (ID != Intrinsic::not_intrinsic) {
        const auto *FT = F->getFunctionType();
        SmallVector<Type *, 2> Tys;
        if (ID == Intrinsic::vector_extract ||
            ID == Intrinsic::vector_interleave2)
          // Extracting overloads the return type.
          Tys.push_back(FT->getReturnType());
        if (ID != Intrinsic::vector_interleave2)
          Tys.push_back(FT->getParamType(0));
        if (ID == Intrinsic::vector_insert ||
            ID == Intrinsic::vector_partial_reduce_add)
          // Inserting overloads the inserted type.
          Tys.push_back(FT->getParamType(1));
        rename(F);
        NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), ID, Tys);
        return true;
      }

      if (Name.consume_front("reduce.")) {
        SmallVector<StringRef, 2> Groups;
        static const Regex R("^([a-z]+)\\.[a-z][0-9]+");
        if (R.match(Name, &Groups))
          ID = StringSwitch<Intrinsic::ID>(Groups[1])
                   .Case("add", Intrinsic::vector_reduce_add)
                   .Case("mul", Intrinsic::vector_reduce_mul)
                   .Case("and", Intrinsic::vector_reduce_and)
                   .Case("or", Intrinsic::vector_reduce_or)
                   .Case("xor", Intrinsic::vector_reduce_xor)
                   .Case("smax", Intrinsic::vector_reduce_smax)
                   .Case("smin", Intrinsic::vector_reduce_smin)
                   .Case("umax", Intrinsic::vector_reduce_umax)
                   .Case("umin", Intrinsic::vector_reduce_umin)
                   .Case("fmax", Intrinsic::vector_reduce_fmax)
                   .Case("fmin", Intrinsic::vector_reduce_fmin)
                   .Default(Intrinsic::not_intrinsic);

        bool V2 = false;
        if (ID == Intrinsic::not_intrinsic) {
          static const Regex R2("^v2\\.([a-z]+)\\.[fi][0-9]+");
          Groups.clear();
          V2 = true;
          if (R2.match(Name, &Groups))
            ID = StringSwitch<Intrinsic::ID>(Groups[1])
                     .Case("fadd", Intrinsic::vector_reduce_fadd)
                     .Case("fmul", Intrinsic::vector_reduce_fmul)
                     .Default(Intrinsic::not_intrinsic);
        }
        if (ID != Intrinsic::not_intrinsic) {
          rename(F);
          auto Args = F->getFunctionType()->params();
          NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), ID,
                                                    {Args[V2 ? 1 : 0]});
          return true;
        }
        break; // No other 'expermental.vector.reduce.*'.
      }

      if (Name.consume_front("splice"))
        return true;
      break; // No other 'experimental.vector.*'.
    }
    if (Name.consume_front("experimental.stepvector.")) {
      Intrinsic::ID ID = Intrinsic::stepvector;
      rename(F);
      NewFn = Intrinsic::getOrInsertDeclaration(
          F->getParent(), ID, F->getFunctionType()->getReturnType());
      return true;
    }
    break; // No other 'e*'.
  case 'f':
    if (Name.starts_with("flt.rounds")) {
      rename(F);
      NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(),
                                                Intrinsic::get_rounding);
      return true;
    }
    break;
  case 'i':
    if (Name.starts_with("invariant.group.barrier")) {
      // Rename invariant.group.barrier to launder.invariant.group
      auto Args = F->getFunctionType()->params();
      Type* ObjectPtr[1] = {Args[0]};
      rename(F);
      NewFn = Intrinsic::getOrInsertDeclaration(
          F->getParent(), Intrinsic::launder_invariant_group, ObjectPtr);
      return true;
    }
    break;
  case 'l':
    if ((Name.starts_with("lifetime.start") ||
         Name.starts_with("lifetime.end")) &&
        F->arg_size() == 2) {
      Intrinsic::ID IID = Name.starts_with("lifetime.start")
                              ? Intrinsic::lifetime_start
                              : Intrinsic::lifetime_end;
      rename(F);
      NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), IID,
                                                F->getArg(0)->getType());
      return true;
    }
    break;
  case 'm': {
    // Updating the memory intrinsics (memcpy/memmove/memset) that have an
    // alignment parameter to embedding the alignment as an attribute of
    // the pointer args.
    if (unsigned ID = StringSwitch<unsigned>(Name)
                          .StartsWith("memcpy.", Intrinsic::memcpy)
                          .StartsWith("memmove.", Intrinsic::memmove)
                          .Default(0)) {
      if (F->arg_size() == 5) {
        rename(F);
        // Get the types of dest, src, and len
        ArrayRef<Type *> ParamTypes =
            F->getFunctionType()->params().slice(0, 3);
        NewFn =
            Intrinsic::getOrInsertDeclaration(F->getParent(), ID, ParamTypes);
        return true;
      }
    }
    if (Name.starts_with("memset.") && F->arg_size() == 5) {
      rename(F);
      // Get the types of dest, and len
      const auto *FT = F->getFunctionType();
      Type *ParamTypes[2] = {
          FT->getParamType(0), // Dest
          FT->getParamType(2)  // len
      };
      NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(),
                                                Intrinsic::memset, ParamTypes);
      return true;
    }

    unsigned MaskedID =
        StringSwitch<unsigned>(Name)
            .StartsWith("masked.load", Intrinsic::masked_load)
            .StartsWith("masked.gather", Intrinsic::masked_gather)
            .StartsWith("masked.store", Intrinsic::masked_store)
            .StartsWith("masked.scatter", Intrinsic::masked_scatter)
            .Default(0);
    if (MaskedID && F->arg_size() == 4) {
      rename(F);
      if (MaskedID == Intrinsic::masked_load ||
          MaskedID == Intrinsic::masked_gather) {
        NewFn = Intrinsic::getOrInsertDeclaration(
            F->getParent(), MaskedID,
            {F->getReturnType(), F->getArg(0)->getType()});
        return true;
      }
      NewFn = Intrinsic::getOrInsertDeclaration(
          F->getParent(), MaskedID,
          {F->getArg(0)->getType(), F->getArg(1)->getType()});
      return true;
    }
    break;
  }
  case 'n': {
    if (Name.consume_front("nvvm.")) {
      // Check for nvvm intrinsics corresponding exactly to an LLVM intrinsic.
      if (F->arg_size() == 1) {
        Intrinsic::ID IID =
            StringSwitch<Intrinsic::ID>(Name)
                .Cases({"brev32", "brev64"}, Intrinsic::bitreverse)
                .Case("clz.i", Intrinsic::ctlz)
                .Case("popc.i", Intrinsic::ctpop)
                .Default(Intrinsic::not_intrinsic);
        if (IID != Intrinsic::not_intrinsic) {
          NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), IID,
                                                    {F->getReturnType()});
          return true;
        }
      } else if (F->arg_size() == 2) {
        Intrinsic::ID IID =
            StringSwitch<Intrinsic::ID>(Name)
                .Cases({"max.s", "max.i", "max.ll"}, Intrinsic::smax)
                .Cases({"min.s", "min.i", "min.ll"}, Intrinsic::smin)
                .Cases({"max.us", "max.ui", "max.ull"}, Intrinsic::umax)
                .Cases({"min.us", "min.ui", "min.ull"}, Intrinsic::umin)
                .Default(Intrinsic::not_intrinsic);
        if (IID != Intrinsic::not_intrinsic) {
          NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), IID,
                                                    {F->getReturnType()});
          return true;
        }
      }

      // Check for nvvm intrinsics that need a return type adjustment.
      if (!F->getReturnType()->getScalarType()->isBFloatTy()) {
        Intrinsic::ID IID = shouldUpgradeNVPTXBF16Intrinsic(Name);
        if (IID != Intrinsic::not_intrinsic) {
          NewFn = nullptr;
          return true;
        }
      }

      // Upgrade Distributed Shared Memory Intrinsics
      Intrinsic::ID IID = shouldUpgradeNVPTXSharedClusterIntrinsic(F, Name);
      if (IID != Intrinsic::not_intrinsic) {
        rename(F);
        NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), IID);
        return true;
      }

      // Upgrade TMA copy G2S Intrinsics
      IID = shouldUpgradeNVPTXTMAG2SIntrinsics(F, Name);
      if (IID != Intrinsic::not_intrinsic) {
        rename(F);
        NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), IID);
        return true;
      }

      // The following nvvm intrinsics correspond exactly to an LLVM idiom, but
      // not to an intrinsic alone.  We expand them in UpgradeIntrinsicCall.
      //
      // TODO: We could add lohi.i2d.
      bool Expand = false;
      if (Name.consume_front("abs."))
        // nvvm.abs.{i,ii}
        Expand =
            Name == "i" || Name == "ll" || Name == "bf16" || Name == "bf16x2";
      else if (Name.consume_front("fabs."))
        // nvvm.fabs.{f,ftz.f,d}
        Expand = Name == "f" || Name == "ftz.f" || Name == "d";
      else if (Name.consume_front("ex2.approx."))
        // nvvm.ex2.approx.{f,ftz.f,d,f16x2}
        Expand =
            Name == "f" || Name == "ftz.f" || Name == "d" || Name == "f16x2";
      else if (Name.consume_front("atomic.load."))
        // nvvm.atomic.load.add.{f32,f64}.p
        // nvvm.atomic.load.{inc,dec}.32.p
        Expand = StringSwitch<bool>(Name)
                     .StartsWith("add.f32.p", true)
                     .StartsWith("add.f64.p", true)
                     .StartsWith("inc.32.p", true)
                     .StartsWith("dec.32.p", true)
                     .Default(false);
      else if (Name.consume_front("bitcast."))
        // nvvm.bitcast.{f2i,i2f,ll2d,d2ll}
        Expand =
            Name == "f2i" || Name == "i2f" || Name == "ll2d" || Name == "d2ll";
      else if (Name.consume_front("rotate."))
        // nvvm.rotate.{b32,b64,right.b64}
        Expand = Name == "b32" || Name == "b64" || Name == "right.b64";
      else if (Name.consume_front("ptr.gen.to."))
        // nvvm.ptr.gen.to.{local,shared,global,constant,param}
        Expand = consumeNVVMPtrAddrSpace(Name);
      else if (Name.consume_front("ptr."))
        // nvvm.ptr.{local,shared,global,constant,param}.to.gen
        Expand = consumeNVVMPtrAddrSpace(Name) && Name.starts_with(".to.gen");
      else if (Name.consume_front("ldg.global."))
        // nvvm.ldg.global.{i,p,f}
        Expand = (Name.starts_with("i.") || Name.starts_with("f.") ||
                  Name.starts_with("p."));
      else
        Expand = StringSwitch<bool>(Name)
                     .Case("barrier0", true)
                     .Case("barrier.n", true)
                     .Case("barrier.sync.cnt", true)
                     .Case("barrier.sync", true)
                     .Case("barrier", true)
                     .Case("bar.sync", true)
                     .Case("barrier0.popc", true)
                     .Case("barrier0.and", true)
                     .Case("barrier0.or", true)
                     .Case("clz.ll", true)
                     .Case("popc.ll", true)
                     .Case("h2f", true)
                     .Case("swap.lo.hi.b64", true)
                     .Case("tanh.approx.f32", true)
                     .Default(false);

      if (Expand) {
        NewFn = nullptr;
        return true;
      }
      break; // No other 'nvvm.*'.
    }
    break;
  }
  case 'o':
    if (Name.starts_with("objectsize.")) {
      Type *Tys[2] = { F->getReturnType(), F->arg_begin()->getType() };
      if (F->arg_size() == 2 || F->arg_size() == 3) {
        rename(F);
        NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(),
                                                  Intrinsic::objectsize, Tys);
        return true;
      }
    }
    break;

  case 'p':
    if (Name.starts_with("ptr.annotation.") && F->arg_size() == 4) {
      rename(F);
      NewFn = Intrinsic::getOrInsertDeclaration(
          F->getParent(), Intrinsic::ptr_annotation,
          {F->arg_begin()->getType(), F->getArg(1)->getType()});
      return true;
    }
    break;

  case 'r': {
    if (Name.consume_front("riscv.")) {
      Intrinsic::ID ID;
      ID = StringSwitch<Intrinsic::ID>(Name)
               .Case("aes32dsi", Intrinsic::riscv_aes32dsi)
               .Case("aes32dsmi", Intrinsic::riscv_aes32dsmi)
               .Case("aes32esi", Intrinsic::riscv_aes32esi)
               .Case("aes32esmi", Intrinsic::riscv_aes32esmi)
               .Default(Intrinsic::not_intrinsic);
      if (ID != Intrinsic::not_intrinsic) {
        if (!F->getFunctionType()->getParamType(2)->isIntegerTy(32)) {
          rename(F);
          NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), ID);
          return true;
        }
        break; // No other applicable upgrades.
      }

      ID = StringSwitch<Intrinsic::ID>(Name)
               .StartsWith("sm4ks", Intrinsic::riscv_sm4ks)
               .StartsWith("sm4ed", Intrinsic::riscv_sm4ed)
               .Default(Intrinsic::not_intrinsic);
      if (ID != Intrinsic::not_intrinsic) {
        if (!F->getFunctionType()->getParamType(2)->isIntegerTy(32) ||
            F->getFunctionType()->getReturnType()->isIntegerTy(64)) {
          rename(F);
          NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), ID);
          return true;
        }
        break; // No other applicable upgrades.
      }

      ID = StringSwitch<Intrinsic::ID>(Name)
               .StartsWith("sha256sig0", Intrinsic::riscv_sha256sig0)
               .StartsWith("sha256sig1", Intrinsic::riscv_sha256sig1)
               .StartsWith("sha256sum0", Intrinsic::riscv_sha256sum0)
               .StartsWith("sha256sum1", Intrinsic::riscv_sha256sum1)
               .StartsWith("sm3p0", Intrinsic::riscv_sm3p0)
               .StartsWith("sm3p1", Intrinsic::riscv_sm3p1)
               .Default(Intrinsic::not_intrinsic);
      if (ID != Intrinsic::not_intrinsic) {
        if (F->getFunctionType()->getReturnType()->isIntegerTy(64)) {
          rename(F);
          NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), ID);
          return true;
        }
        break; // No other applicable upgrades.
      }

      // Replace llvm.riscv.clmul with llvm.clmul.
      if (Name == "clmul.i32" || Name == "clmul.i64") {
        NewFn = Intrinsic::getOrInsertDeclaration(
            F->getParent(), Intrinsic::clmul, {F->getReturnType()});
        return true;
      }

      break; // No other 'riscv.*' intrinsics
    }
  } break;

  case 's':
    if (Name == "stackprotectorcheck") {
      NewFn = nullptr;
      return true;
    }
    break;

  case 't':
    if (Name == "thread.pointer") {
      NewFn = Intrinsic::getOrInsertDeclaration(
          F->getParent(), Intrinsic::thread_pointer, F->getReturnType());
      return true;
    }
    break;

  case 'v': {
    if (Name == "var.annotation" && F->arg_size() == 4) {
      rename(F);
      NewFn = Intrinsic::getOrInsertDeclaration(
          F->getParent(), Intrinsic::var_annotation,
          {{F->arg_begin()->getType(), F->getArg(1)->getType()}});
      return true;
    }
    if (Name.consume_front("vector.splice")) {
      if (Name.starts_with(".left") || Name.starts_with(".right"))
        break;
      return true;
    }
    break;
  }

  case 'w':
    if (Name.consume_front("wasm.")) {
      Intrinsic::ID ID =
          StringSwitch<Intrinsic::ID>(Name)
              .StartsWith("fma.", Intrinsic::wasm_relaxed_madd)
              .StartsWith("fms.", Intrinsic::wasm_relaxed_nmadd)
              .StartsWith("laneselect.", Intrinsic::wasm_relaxed_laneselect)
              .Default(Intrinsic::not_intrinsic);
      if (ID != Intrinsic::not_intrinsic) {
        rename(F);
        NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), ID,
                                                  F->getReturnType());
        return true;
      }

      if (Name.consume_front("dot.i8x16.i7x16.")) {
        ID = StringSwitch<Intrinsic::ID>(Name)
                 .Case("signed", Intrinsic::wasm_relaxed_dot_i8x16_i7x16_signed)
                 .Case("add.signed",
                       Intrinsic::wasm_relaxed_dot_i8x16_i7x16_add_signed)
                 .Default(Intrinsic::not_intrinsic);
        if (ID != Intrinsic::not_intrinsic) {
          rename(F);
          NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), ID);
          return true;
        }
        break; // No other 'wasm.dot.i8x16.i7x16.*'.
      }
      break; // No other 'wasm.*'.
    }
    break;

  case 'x':
    if (upgradeX86IntrinsicFunction(F, Name, NewFn))
      return true;
  }

  auto *ST = dyn_cast<StructType>(F->getReturnType());
  if (ST && (!ST->isLiteral() || ST->isPacked()) &&
      F->getIntrinsicID() != Intrinsic::not_intrinsic) {
    // Replace return type with literal non-packed struct. Only do this for
    // intrinsics declared to return a struct, not for intrinsics with
    // overloaded return type, in which case the exact struct type will be
    // mangled into the name.
    SmallVector<Intrinsic::IITDescriptor> Desc;
    Intrinsic::getIntrinsicInfoTableEntries(F->getIntrinsicID(), Desc);
    if (Desc.front().Kind == Intrinsic::IITDescriptor::Struct) {
      auto *FT = F->getFunctionType();
      auto *NewST = StructType::get(ST->getContext(), ST->elements());
      auto *NewFT = FunctionType::get(NewST, FT->params(), FT->isVarArg());
      std::string Name = F->getName().str();
      rename(F);
      NewFn = Function::Create(NewFT, F->getLinkage(), F->getAddressSpace(),
                               Name, F->getParent());

      // The new function may also need remangling.
      if (auto Result = llvm::Intrinsic::remangleIntrinsicFunction(NewFn))
        NewFn = *Result;
      return true;
    }
  }

  // Remangle our intrinsic since we upgrade the mangling
  auto Result = llvm::Intrinsic::remangleIntrinsicFunction(F);
  if (Result != std::nullopt) {
    NewFn = *Result;
    return true;
  }

  //  This may not belong here. This function is effectively being overloaded
  //  to both detect an intrinsic which needs upgrading, and to provide the
  //  upgraded form of the intrinsic. We should perhaps have two separate
  //  functions for this.
  return false;
}

bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn,
                                    bool CanUpgradeDebugIntrinsicsToRecords) {
  NewFn = nullptr;
  bool Upgraded =
      upgradeIntrinsicFunction1(F, NewFn, CanUpgradeDebugIntrinsicsToRecords);

  // Upgrade intrinsic attributes.  This does not change the function.
  if (NewFn)
    F = NewFn;
  if (Intrinsic::ID id = F->getIntrinsicID()) {
    // Only do this if the intrinsic signature is valid.
    SmallVector<Type *> OverloadTys;
    if (Intrinsic::getIntrinsicSignature(id, F->getFunctionType(), OverloadTys))
      F->setAttributes(
          Intrinsic::getAttributes(F->getContext(), id, F->getFunctionType()));
  }
  return Upgraded;
}

GlobalVariable *llvm::UpgradeGlobalVariable(GlobalVariable *GV) {
  if (!(GV->hasName() && (GV->getName() == "llvm.global_ctors" ||
                          GV->getName() == "llvm.global_dtors")) ||
      !GV->hasInitializer())
    return nullptr;
  ArrayType *ATy = dyn_cast<ArrayType>(GV->getValueType());
  if (!ATy)
    return nullptr;
  StructType *STy = dyn_cast<StructType>(ATy->getElementType());
  if (!STy || STy->getNumElements() != 2)
    return nullptr;

  LLVMContext &C = GV->getContext();
  IRBuilder<> IRB(C);
  auto EltTy = StructType::get(STy->getElementType(0), STy->getElementType(1),
                               IRB.getPtrTy());
  Constant *Init = GV->getInitializer();
  unsigned N = Init->getNumOperands();
  std::vector<Constant *> NewCtors(N);
  for (unsigned i = 0; i != N; ++i) {
    auto Ctor = cast<Constant>(Init->getOperand(i));
    NewCtors[i] = ConstantStruct::get(EltTy, Ctor->getAggregateElement(0u),
                                      Ctor->getAggregateElement(1),
                                      ConstantPointerNull::get(IRB.getPtrTy()));
  }
  Constant *NewInit = ConstantArray::get(ArrayType::get(EltTy, N), NewCtors);

  return new GlobalVariable(NewInit->getType(), false, GV->getLinkage(),
                            NewInit, GV->getName());
}

// Handles upgrading SSE2/AVX2/AVX512BW PSLLDQ intrinsics by converting them
// to byte shuffles.
static Value *upgradeX86PSLLDQIntrinsics(IRBuilder<> &Builder, Value *Op,
                                         unsigned Shift) {
  auto *ResultTy = cast<FixedVectorType>(Op->getType());
  unsigned NumElts = ResultTy->getNumElements() * 8;

  // Bitcast from a 64-bit element type to a byte element type.
  Type *VecTy = FixedVectorType::get(Builder.getInt8Ty(), NumElts);
  Op = Builder.CreateBitCast(Op, VecTy, "cast");

  // We'll be shuffling in zeroes.
  Value *Res = Constant::getNullValue(VecTy);

  // If shift is less than 16, emit a shuffle to move the bytes. Otherwise,
  // we'll just return the zero vector.
  if (Shift < 16) {
    int Idxs[64];
    // 256/512-bit version is split into 2/4 16-byte lanes.
    for (unsigned l = 0; l != NumElts; l += 16)
      for (unsigned i = 0; i != 16; ++i) {
        unsigned Idx = NumElts + i - Shift;
        if (Idx < NumElts)
          Idx -= NumElts - 16; // end of lane, switch operand.
        Idxs[l + i] = Idx + l;
      }

    Res = Builder.CreateShuffleVector(Res, Op, ArrayRef(Idxs, NumElts));
  }

  // Bitcast back to a 64-bit element type.
  return Builder.CreateBitCast(Res, ResultTy, "cast");
}

// Handles upgrading SSE2/AVX2/AVX512BW PSRLDQ intrinsics by converting them
// to byte shuffles.
static Value *upgradeX86PSRLDQIntrinsics(IRBuilder<> &Builder, Value *Op,
                                         unsigned Shift) {
  auto *ResultTy = cast<FixedVectorType>(Op->getType());
  unsigned NumElts = ResultTy->getNumElements() * 8;

  // Bitcast from a 64-bit element type to a byte element type.
  Type *VecTy = FixedVectorType::get(Builder.getInt8Ty(), NumElts);
  Op = Builder.CreateBitCast(Op, VecTy, "cast");

  // We'll be shuffling in zeroes.
  Value *Res = Constant::getNullValue(VecTy);

  // If shift is less than 16, emit a shuffle to move the bytes. Otherwise,
  // we'll just return the zero vector.
  if (Shift < 16) {
    int Idxs[64];
    // 256/512-bit version is split into 2/4 16-byte lanes.
    for (unsigned l = 0; l != NumElts; l += 16)
      for (unsigned i = 0; i != 16; ++i) {
        unsigned Idx = i + Shift;
        if (Idx >= 16)
          Idx += NumElts - 16; // end of lane, switch operand.
        Idxs[l + i] = Idx + l;
      }

    Res = Builder.CreateShuffleVector(Op, Res, ArrayRef(Idxs, NumElts));
  }

  // Bitcast back to a 64-bit element type.
  return Builder.CreateBitCast(Res, ResultTy, "cast");
}

static Value *getX86MaskVec(IRBuilder<> &Builder, Value *Mask,
                            unsigned NumElts) {
  assert(isPowerOf2_32(NumElts) && "Expected power-of-2 mask elements");
  llvm::VectorType *MaskTy = FixedVectorType::get(
      Builder.getInt1Ty(), cast<IntegerType>(Mask->getType())->getBitWidth());
  Mask = Builder.CreateBitCast(Mask, MaskTy);

  // If we have less than 8 elements (1, 2 or 4), then the starting mask was an
  // i8 and we need to extract down to the right number of elements.
  if (NumElts <= 4) {
    int Indices[4];
    for (unsigned i = 0; i != NumElts; ++i)
      Indices[i] = i;
    Mask = Builder.CreateShuffleVector(Mask, Mask, ArrayRef(Indices, NumElts),
                                       "extract");
  }

  return Mask;
}

static Value *emitX86Select(IRBuilder<> &Builder, Value *Mask, Value *Op0,
                            Value *Op1) {
  // If the mask is all ones just emit the first operation.
  if (const auto *C = dyn_cast<Constant>(Mask))
    if (C->isAllOnesValue())
      return Op0;

  Mask = getX86MaskVec(Builder, Mask,
                       cast<FixedVectorType>(Op0->getType())->getNumElements());
  return Builder.CreateSelect(Mask, Op0, Op1);
}

static Value *emitX86ScalarSelect(IRBuilder<> &Builder, Value *Mask, Value *Op0,
                                  Value *Op1) {
  // If the mask is all ones just emit the first operation.
  if (const auto *C = dyn_cast<Constant>(Mask))
    if (C->isAllOnesValue())
      return Op0;

  auto *MaskTy = FixedVectorType::get(Builder.getInt1Ty(),
                                      Mask->getType()->getIntegerBitWidth());
  Mask = Builder.CreateBitCast(Mask, MaskTy);
  Mask = Builder.CreateExtractElement(Mask, (uint64_t)0);
  return Builder.CreateSelect(Mask, Op0, Op1);
}

// Handle autoupgrade for masked PALIGNR and VALIGND/Q intrinsics.
// PALIGNR handles large immediates by shifting while VALIGN masks the immediate
// so we need to handle both cases. VALIGN also doesn't have 128-bit lanes.
static Value *upgradeX86ALIGNIntrinsics(IRBuilder<> &Builder, Value *Op0,
                                        Value *Op1, Value *Shift,
                                        Value *Passthru, Value *Mask,
                                        bool IsVALIGN) {
  unsigned ShiftVal = cast<llvm::ConstantInt>(Shift)->getZExtValue();

  unsigned NumElts = cast<FixedVectorType>(Op0->getType())->getNumElements();
  assert((IsVALIGN || NumElts % 16 == 0) && "Illegal NumElts for PALIGNR!");
  assert((!IsVALIGN || NumElts <= 16) && "NumElts too large for VALIGN!");
  assert(isPowerOf2_32(NumElts) && "NumElts not a power of 2!");

  // Mask the immediate for VALIGN.
  if (IsVALIGN)
    ShiftVal &= (NumElts - 1);

  // If palignr is shifting the pair of vectors more than the size of two
  // lanes, emit zero.
  if (ShiftVal >= 32)
    return llvm::Constant::getNullValue(Op0->getType());

  // If palignr is shifting the pair of input vectors more than one lane,
  // but less than two lanes, convert to shifting in zeroes.
  if (ShiftVal > 16) {
    ShiftVal -= 16;
    Op1 = Op0;
    Op0 = llvm::Constant::getNullValue(Op0->getType());
  }

  int Indices[64];
  // 256-bit palignr operates on 128-bit lanes so we need to handle that
  for (unsigned l = 0; l < NumElts; l += 16) {
    for (unsigned i = 0; i != 16; ++i) {
      unsigned Idx = ShiftVal + i;
      if (!IsVALIGN && Idx >= 16) // Disable wrap for VALIGN.
        Idx += NumElts - 16; // End of lane, switch operand.
      Indices[l + i] = Idx + l;
    }
  }

  Value *Align = Builder.CreateShuffleVector(
      Op1, Op0, ArrayRef(Indices, NumElts), "palignr");

  return emitX86Select(Builder, Mask, Align, Passthru);
}

static Value *upgradeX86VPERMT2Intrinsics(IRBuilder<> &Builder, CallBase &CI,
                                          bool ZeroMask, bool IndexForm) {
  Type *Ty = CI.getType();
  unsigned VecWidth = Ty->getPrimitiveSizeInBits();
  unsigned EltWidth = Ty->getScalarSizeInBits();
  bool IsFloat = Ty->isFPOrFPVectorTy();
  Intrinsic::ID IID;
  if (VecWidth == 128 && EltWidth == 32 && IsFloat)
    IID = Intrinsic::x86_avx512_vpermi2var_ps_128;
  else if (VecWidth == 128 && EltWidth == 32 && !IsFloat)
    IID = Intrinsic::x86_avx512_vpermi2var_d_128;
  else if (VecWidth == 128 && EltWidth == 64 && IsFloat)
    IID = Intrinsic::x86_avx512_vpermi2var_pd_128;
  else if (VecWidth == 128 && EltWidth == 64 && !IsFloat)
    IID = Intrinsic::x86_avx512_vpermi2var_q_128;
  else if (VecWidth == 256 && EltWidth == 32 && IsFloat)
    IID = Intrinsic::x86_avx512_vpermi2var_ps_256;
  else if (VecWidth == 256 && EltWidth == 32 && !IsFloat)
    IID = Intrinsic::x86_avx512_vpermi2var_d_256;
  else if (VecWidth == 256 && EltWidth == 64 && IsFloat)
    IID = Intrinsic::x86_avx512_vpermi2var_pd_256;
  else if (VecWidth == 256 && EltWidth == 64 && !IsFloat)
    IID = Intrinsic::x86_avx512_vpermi2var_q_256;
  else if (VecWidth == 512 && EltWidth == 32 && IsFloat)
    IID = Intrinsic::x86_avx512_vpermi2var_ps_512;
  else if (VecWidth == 512 && EltWidth == 32 && !IsFloat)
    IID = Intrinsic::x86_avx512_vpermi2var_d_512;
  else if (VecWidth == 512 && EltWidth == 64 && IsFloat)
    IID = Intrinsic::x86_avx512_vpermi2var_pd_512;
  else if (VecWidth == 512 && EltWidth == 64 && !IsFloat)
    IID = Intrinsic::x86_avx512_vpermi2var_q_512;
  else if (VecWidth == 128 && EltWidth == 16)
    IID = Intrinsic::x86_avx512_vpermi2var_hi_128;
  else if (VecWidth == 256 && EltWidth == 16)
    IID = Intrinsic::x86_avx512_vpermi2var_hi_256;
  else if (VecWidth == 512 && EltWidth == 16)
    IID = Intrinsic::x86_avx512_vpermi2var_hi_512;
  else if (VecWidth == 128 && EltWidth == 8)
    IID = Intrinsic::x86_avx512_vpermi2var_qi_128;
  else if (VecWidth == 256 && EltWidth == 8)
    IID = Intrinsic::x86_avx512_vpermi2var_qi_256;
  else if (VecWidth == 512 && EltWidth == 8)
    IID = Intrinsic::x86_avx512_vpermi2var_qi_512;
  else
    llvm_unreachable("Unexpected intrinsic");

  Value *Args[] = { CI.getArgOperand(0) , CI.getArgOperand(1),
                    CI.getArgOperand(2) };

  // If this isn't index form we need to swap operand 0 and 1.
  if (!IndexForm)
    std::swap(Args[0], Args[1]);

  Value *V = Builder.CreateIntrinsic(IID, Args);
  Value *PassThru = ZeroMask ? ConstantAggregateZero::get(Ty)
                             : Builder.CreateBitCast(CI.getArgOperand(1),
                                                     Ty);
  return emitX86Select(Builder, CI.getArgOperand(3), V, PassThru);
}

static Value *upgradeX86BinaryIntrinsics(IRBuilder<> &Builder, CallBase &CI,
                                         Intrinsic::ID IID) {
  Type *Ty = CI.getType();
  Value *Op0 = CI.getOperand(0);
  Value *Op1 = CI.getOperand(1);
  Value *Res = Builder.CreateIntrinsic(IID, Ty, {Op0, Op1});

  if (CI.arg_size() == 4) { // For masked intrinsics.
    Value *VecSrc = CI.getOperand(2);
    Value *Mask = CI.getOperand(3);
    Res = emitX86Select(Builder, Mask, Res, VecSrc);
  }
  return Res;
}

static Value *upgradeX86Rotate(IRBuilder<> &Builder, CallBase &CI,
                               bool IsRotateRight) {
  Type *Ty = CI.getType();
  Value *Src = CI.getArgOperand(0);
  Value *Amt = CI.getArgOperand(1);

  // Amount may be scalar immediate, in which case create a splat vector.
  // Funnel shifts amounts are treated as modulo and types are all power-of-2 so
  // we only care about the lowest log2 bits anyway.
  if (Amt->getType() != Ty) {
    unsigned NumElts = cast<FixedVectorType>(Ty)->getNumElements();
    Amt = Builder.CreateIntCast(Amt, Ty->getScalarType(), false);
    Amt = Builder.CreateVectorSplat(NumElts, Amt);
  }

  Intrinsic::ID IID = IsRotateRight ? Intrinsic::fshr : Intrinsic::fshl;
  Value *Res = Builder.CreateIntrinsic(IID, Ty, {Src, Src, Amt});

  if (CI.arg_size() == 4) { // For masked intrinsics.
    Value *VecSrc = CI.getOperand(2);
    Value *Mask = CI.getOperand(3);
    Res = emitX86Select(Builder, Mask, Res, VecSrc);
  }
  return Res;
}

static Value *upgradeX86vpcom(IRBuilder<> &Builder, CallBase &CI, unsigned Imm,
                              bool IsSigned) {
  Type *Ty = CI.getType();
  Value *LHS = CI.getArgOperand(0);
  Value *RHS = CI.getArgOperand(1);

  CmpInst::Predicate Pred;
  switch (Imm) {
  case 0x0:
    Pred = IsSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;
    break;
  case 0x1:
    Pred = IsSigned ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE;
    break;
  case 0x2:
    Pred = IsSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT;
    break;
  case 0x3:
    Pred = IsSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE;
    break;
  case 0x4:
    Pred = ICmpInst::ICMP_EQ;
    break;
  case 0x5:
    Pred = ICmpInst::ICMP_NE;
    break;
  case 0x6:
    return Constant::getNullValue(Ty); // FALSE
  case 0x7:
    return Constant::getAllOnesValue(Ty); // TRUE
  default:
    llvm_unreachable("Unknown XOP vpcom/vpcomu predicate");
  }

  Value *Cmp = Builder.CreateICmp(Pred, LHS, RHS);
  Value *Ext = Builder.CreateSExt(Cmp, Ty);
  return Ext;
}

static Value *upgradeX86ConcatShift(IRBuilder<> &Builder, CallBase &CI,
                                    bool IsShiftRight, bool ZeroMask) {
  Type *Ty = CI.getType();
  Value *Op0 = CI.getArgOperand(0);
  Value *Op1 = CI.getArgOperand(1);
  Value *Amt = CI.getArgOperand(2);

  if (IsShiftRight)
    std::swap(Op0, Op1);

  // Amount may be scalar immediate, in which case create a splat vector.
  // Funnel shifts amounts are treated as modulo and types are all power-of-2 so
  // we only care about the lowest log2 bits anyway.
  if (Amt->getType() != Ty) {
    unsigned NumElts = cast<FixedVectorType>(Ty)->getNumElements();
    Amt = Builder.CreateIntCast(Amt, Ty->getScalarType(), false);
    Amt = Builder.CreateVectorSplat(NumElts, Amt);
  }

  Intrinsic::ID IID = IsShiftRight ? Intrinsic::fshr : Intrinsic::fshl;
  Value *Res = Builder.CreateIntrinsic(IID, Ty, {Op0, Op1, Amt});

  unsigned NumArgs = CI.arg_size();
  if (NumArgs >= 4) { // For masked intrinsics.
    Value *VecSrc = NumArgs == 5 ? CI.getArgOperand(3) :
                    ZeroMask     ? ConstantAggregateZero::get(CI.getType()) :
                                   CI.getArgOperand(0);
    Value *Mask = CI.getOperand(NumArgs - 1);
    Res = emitX86Select(Builder, Mask, Res, VecSrc);
  }
  return Res;
}

static Value *upgradeMaskedStore(IRBuilder<> &Builder, Value *Ptr, Value *Data,
                                 Value *Mask, bool Aligned) {
  const Align Alignment =
      Aligned
          ? Align(Data->getType()->getPrimitiveSizeInBits().getFixedValue() / 8)
          : Align(1);

  // If the mask is all ones just emit a regular store.
  if (const auto *C = dyn_cast<Constant>(Mask))
    if (C->isAllOnesValue())
      return Builder.CreateAlignedStore(Data, Ptr, Alignment);

  // Convert the mask from an integer type to a vector of i1.
  unsigned NumElts = cast<FixedVectorType>(Data->getType())->getNumElements();
  Mask = getX86MaskVec(Builder, Mask, NumElts);
  return Builder.CreateMaskedStore(Data, Ptr, Alignment, Mask);
}

static Value *upgradeMaskedLoad(IRBuilder<> &Builder, Value *Ptr,
                                Value *Passthru, Value *Mask, bool Aligned) {
  Type *ValTy = Passthru->getType();
  const Align Alignment =
      Aligned
          ? Align(
                Passthru->getType()->getPrimitiveSizeInBits().getFixedValue() /
                8)
          : Align(1);

  // If the mask is all ones just emit a regular store.
  if (const auto *C = dyn_cast<Constant>(Mask))
    if (C->isAllOnesValue())
      return Builder.CreateAlignedLoad(ValTy, Ptr, Alignment);

  // Convert the mask from an integer type to a vector of i1.
  unsigned NumElts = cast<FixedVectorType>(ValTy)->getNumElements();
  Mask = getX86MaskVec(Builder, Mask, NumElts);
  return Builder.CreateMaskedLoad(ValTy, Ptr, Alignment, Mask, Passthru);
}

static Value *upgradeAbs(IRBuilder<> &Builder, CallBase &CI) {
  Type *Ty = CI.getType();
  Value *Op0 = CI.getArgOperand(0);
  Value *Res = Builder.CreateIntrinsic(Intrinsic::abs, Ty,
                                       {Op0, Builder.getInt1(false)});
  if (CI.arg_size() == 3)
    Res = emitX86Select(Builder, CI.getArgOperand(2), Res, CI.getArgOperand(1));
  return Res;
}

static Value *upgradePMULDQ(IRBuilder<> &Builder, CallBase &CI, bool IsSigned) {
  Type *Ty = CI.getType();

  // Arguments have a vXi32 type so cast to vXi64.
  Value *LHS = Builder.CreateBitCast(CI.getArgOperand(0), Ty);
  Value *RHS = Builder.CreateBitCast(CI.getArgOperand(1), Ty);

  if (IsSigned) {
    // Shift left then arithmetic shift right.
    Constant *ShiftAmt = ConstantInt::get(Ty, 32);
    LHS = Builder.CreateShl(LHS, ShiftAmt);
    LHS = Builder.CreateAShr(LHS, ShiftAmt);
    RHS = Builder.CreateShl(RHS, ShiftAmt);
    RHS = Builder.CreateAShr(RHS, ShiftAmt);
  } else {
    // Clear the upper bits.
    Constant *Mask = ConstantInt::get(Ty, 0xffffffff);
    LHS = Builder.CreateAnd(LHS, Mask);
    RHS = Builder.CreateAnd(RHS, Mask);
  }

  Value *Res = Builder.CreateMul(LHS, RHS);

  if (CI.arg_size() == 4)
    Res = emitX86Select(Builder, CI.getArgOperand(3), Res, CI.getArgOperand(2));

  return Res;
}

// Applying mask on vector of i1's and make sure result is at least 8 bits wide.
static Value *applyX86MaskOn1BitsVec(IRBuilder<> &Builder, Value *Vec,
                                     Value *Mask) {
  unsigned NumElts = cast<FixedVectorType>(Vec->getType())->getNumElements();
  if (Mask) {
    const auto *C = dyn_cast<Constant>(Mask);
    if (!C || !C->isAllOnesValue())
      Vec = Builder.CreateAnd(Vec, getX86MaskVec(Builder, Mask, NumElts));
  }

  if (NumElts < 8) {
    int Indices[8];
    for (unsigned i = 0; i != NumElts; ++i)
      Indices[i] = i;
    for (unsigned i = NumElts; i != 8; ++i)
      Indices[i] = NumElts + i % NumElts;
    Vec = Builder.CreateShuffleVector(Vec,
                                      Constant::getNullValue(Vec->getType()),
                                      Indices);
  }
  return Builder.CreateBitCast(Vec, Builder.getIntNTy(std::max(NumElts, 8U)));
}

static Value *upgradeMaskedCompare(IRBuilder<> &Builder, CallBase &CI,
                                   unsigned CC, bool Signed) {
  Value *Op0 = CI.getArgOperand(0);
  unsigned NumElts = cast<FixedVectorType>(Op0->getType())->getNumElements();

  Value *Cmp;
  if (CC == 3) {
    Cmp = Constant::getNullValue(
        FixedVectorType::get(Builder.getInt1Ty(), NumElts));
  } else if (CC == 7) {
    Cmp = Constant::getAllOnesValue(
        FixedVectorType::get(Builder.getInt1Ty(), NumElts));
  } else {
    ICmpInst::Predicate Pred;
    switch (CC) {
    default: llvm_unreachable("Unknown condition code");
    case 0: Pred = ICmpInst::ICMP_EQ;  break;
    case 1: Pred = Signed ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; break;
    case 2: Pred = Signed ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE; break;
    case 4: Pred = ICmpInst::ICMP_NE;  break;
    case 5: Pred = Signed ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE; break;
    case 6: Pred = Signed ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; break;
    }
    Cmp = Builder.CreateICmp(Pred, Op0, CI.getArgOperand(1));
  }

  Value *Mask = CI.getArgOperand(CI.arg_size() - 1);

  return applyX86MaskOn1BitsVec(Builder, Cmp, Mask);
}

// Replace a masked intrinsic with an older unmasked intrinsic.
static Value *upgradeX86MaskedShift(IRBuilder<> &Builder, CallBase &CI,
                                    Intrinsic::ID IID) {
  Value *Rep =
      Builder.CreateIntrinsic(IID, {CI.getArgOperand(0), CI.getArgOperand(1)});
  return emitX86Select(Builder, CI.getArgOperand(3), Rep, CI.getArgOperand(2));
}

static Value *upgradeMaskedMove(IRBuilder<> &Builder, CallBase &CI) {
  Value* A = CI.getArgOperand(0);
  Value* B = CI.getArgOperand(1);
  Value* Src = CI.getArgOperand(2);
  Value* Mask = CI.getArgOperand(3);

  Value* AndNode = Builder.CreateAnd(Mask, APInt(8, 1));
  Value* Cmp = Builder.CreateIsNotNull(AndNode);
  Value* Extract1 = Builder.CreateExtractElement(B, (uint64_t)0);
  Value* Extract2 = Builder.CreateExtractElement(Src, (uint64_t)0);
  Value* Select = Builder.CreateSelect(Cmp, Extract1, Extract2);
  return Builder.CreateInsertElement(A, Select, (uint64_t)0);
}

static Value *upgradeMaskToInt(IRBuilder<> &Builder, CallBase &CI) {
  Value* Op = CI.getArgOperand(0);
  Type* ReturnOp = CI.getType();
  unsigned NumElts = cast<FixedVectorType>(CI.getType())->getNumElements();
  Value *Mask = getX86MaskVec(Builder, Op, NumElts);
  return Builder.CreateSExt(Mask, ReturnOp, "vpmovm2");
}

// Replace intrinsic with unmasked version and a select.
static bool upgradeAVX512MaskToSelect(StringRef Name, IRBuilder<> &Builder,
                                      CallBase &CI, Value *&Rep) {
  Name = Name.substr(12); // Remove avx512.mask.

  unsigned VecWidth = CI.getType()->getPrimitiveSizeInBits();
  unsigned EltWidth = CI.getType()->getScalarSizeInBits();
  Intrinsic::ID IID;
  if (Name.starts_with("max.p")) {
    if (VecWidth == 128 && EltWidth == 32)
      IID = Intrinsic::x86_sse_max_ps;
    else if (VecWidth == 128 && EltWidth == 64)
      IID = Intrinsic::x86_sse2_max_pd;
    else if (VecWidth == 256 && EltWidth == 32)
      IID = Intrinsic::x86_avx_max_ps_256;
    else if (VecWidth == 256 && EltWidth == 64)
      IID = Intrinsic::x86_avx_max_pd_256;
    else
      llvm_unreachable("Unexpected intrinsic");
  } else if (Name.starts_with("min.p")) {
    if (VecWidth == 128 && EltWidth == 32)
      IID = Intrinsic::x86_sse_min_ps;
    else if (VecWidth == 128 && EltWidth == 64)
      IID = Intrinsic::x86_sse2_min_pd;
    else if (VecWidth == 256 && EltWidth == 32)
      IID = Intrinsic::x86_avx_min_ps_256;
    else if (VecWidth == 256 && EltWidth == 64)
      IID = Intrinsic::x86_avx_min_pd_256;
    else
      llvm_unreachable("Unexpected intrinsic");
  } else if (Name.starts_with("pshuf.b.")) {
    if (VecWidth == 128)
      IID = Intrinsic::x86_ssse3_pshuf_b_128;
    else if (VecWidth == 256)
      IID = Intrinsic::x86_avx2_pshuf_b;
    else if (VecWidth == 512)
      IID = Intrinsic::x86_avx512_pshuf_b_512;
    else
      llvm_unreachable("Unexpected intrinsic");
  } else if (Name.starts_with("pmul.hr.sw.")) {
    if (VecWidth == 128)
      IID = Intrinsic::x86_ssse3_pmul_hr_sw_128;
    else if (VecWidth == 256)
      IID = Intrinsic::x86_avx2_pmul_hr_sw;
    else if (VecWidth == 512)
      IID = Intrinsic::x86_avx512_pmul_hr_sw_512;
    else
      llvm_unreachable("Unexpected intrinsic");
  } else if (Name.starts_with("pmulh.w.")) {
    if (VecWidth == 128)
      IID = Intrinsic::x86_sse2_pmulh_w;
    else if (VecWidth == 256)
      IID = Intrinsic::x86_avx2_pmulh_w;
    else if (VecWidth == 512)
      IID = Intrinsic::x86_avx512_pmulh_w_512;
    else
      llvm_unreachable("Unexpected intrinsic");
  } else if (Name.starts_with("pmulhu.w.")) {
    if (VecWidth == 128)
      IID = Intrinsic::x86_sse2_pmulhu_w;
    else if (VecWidth == 256)
      IID = Intrinsic::x86_avx2_pmulhu_w;
    else if (VecWidth == 512)
      IID = Intrinsic::x86_avx512_pmulhu_w_512;
    else
      llvm_unreachable("Unexpected intrinsic");
  } else if (Name.starts_with("pmaddw.d.")) {
    if (VecWidth == 128)
      IID = Intrinsic::x86_sse2_pmadd_wd;
    else if (VecWidth == 256)
      IID = Intrinsic::x86_avx2_pmadd_wd;
    else if (VecWidth == 512)
      IID = Intrinsic::x86_avx512_pmaddw_d_512;
    else
      llvm_unreachable("Unexpected intrinsic");
  } else if (Name.starts_with("pmaddubs.w.")) {
    if (VecWidth == 128)
      IID = Intrinsic::x86_ssse3_pmadd_ub_sw_128;
    else if (VecWidth == 256)
      IID = Intrinsic::x86_avx2_pmadd_ub_sw;
    else if (VecWidth == 512)
      IID = Intrinsic::x86_avx512_pmaddubs_w_512;
    else
      llvm_unreachable("Unexpected intrinsic");
  } else if (Name.starts_with("packsswb.")) {
    if (VecWidth == 128)
      IID = Intrinsic::x86_sse2_packsswb_128;
    else if (VecWidth == 256)
      IID = Intrinsic::x86_avx2_packsswb;
    else if (VecWidth == 512)
      IID = Intrinsic::x86_avx512_packsswb_512;
    else
      llvm_unreachable("Unexpected intrinsic");
  } else if (Name.starts_with("packssdw.")) {
    if (VecWidth == 128)
      IID = Intrinsic::x86_sse2_packssdw_128;
    else if (VecWidth == 256)
      IID = Intrinsic::x86_avx2_packssdw;
    else if (VecWidth == 512)
      IID = Intrinsic::x86_avx512_packssdw_512;
    else
      llvm_unreachable("Unexpected intrinsic");
  } else if (Name.starts_with("packuswb.")) {
    if (VecWidth == 128)
      IID = Intrinsic::x86_sse2_packuswb_128;
    else if (VecWidth == 256)
      IID = Intrinsic::x86_avx2_packuswb;
    else if (VecWidth == 512)
      IID = Intrinsic::x86_avx512_packuswb_512;
    else
      llvm_unreachable("Unexpected intrinsic");
  } else if (Name.starts_with("packusdw.")) {
    if (VecWidth == 128)
      IID = Intrinsic::x86_sse41_packusdw;
    else if (VecWidth == 256)
      IID = Intrinsic::x86_avx2_packusdw;
    else if (VecWidth == 512)
      IID = Intrinsic::x86_avx512_packusdw_512;
    else
      llvm_unreachable("Unexpected intrinsic");
  } else if (Name.starts_with("vpermilvar.")) {
    if (VecWidth == 128 && EltWidth == 32)
      IID = Intrinsic::x86_avx_vpermilvar_ps;
    else if (VecWidth == 128 && EltWidth == 64)
      IID = Intrinsic::x86_avx_vpermilvar_pd;
    else if (VecWidth == 256 && EltWidth == 32)
      IID = Intrinsic::x86_avx_vpermilvar_ps_256;
    else if (VecWidth == 256 && EltWidth == 64)
      IID = Intrinsic::x86_avx_vpermilvar_pd_256;
    else if (VecWidth == 512 && EltWidth == 32)
      IID = Intrinsic::x86_avx512_vpermilvar_ps_512;
    else if (VecWidth == 512 && EltWidth == 64)
      IID = Intrinsic::x86_avx512_vpermilvar_pd_512;
    else
      llvm_unreachable("Unexpected intrinsic");
  } else if (Name == "cvtpd2dq.256") {
    IID = Intrinsic::x86_avx_cvt_pd2dq_256;
  } else if (Name == "cvtpd2ps.256") {
    IID = Intrinsic::x86_avx_cvt_pd2_ps_256;
  } else if (Name == "cvttpd2dq.256") {
    IID = Intrinsic::x86_avx_cvtt_pd2dq_256;
  } else if (Name == "cvttps2dq.128") {
    IID = Intrinsic::x86_sse2_cvttps2dq;
  } else if (Name == "cvttps2dq.256") {
    IID = Intrinsic::x86_avx_cvtt_ps2dq_256;
  } else if (Name.starts_with("permvar.")) {
    bool IsFloat = CI.getType()->isFPOrFPVectorTy();
    if (VecWidth == 256 && EltWidth == 32 && IsFloat)
      IID = Intrinsic::x86_avx2_permps;
    else if (VecWidth == 256 && EltWidth == 32 && !IsFloat)
      IID = Intrinsic::x86_avx2_permd;
    else if (VecWidth == 256 && EltWidth == 64 && IsFloat)
      IID = Intrinsic::x86_avx512_permvar_df_256;
    else if (VecWidth == 256 && EltWidth == 64 && !IsFloat)
      IID = Intrinsic::x86_avx512_permvar_di_256;
    else if (VecWidth == 512 && EltWidth == 32 && IsFloat)
      IID = Intrinsic::x86_avx512_permvar_sf_512;
    else if (VecWidth == 512 && EltWidth == 32 && !IsFloat)
      IID = Intrinsic::x86_avx512_permvar_si_512;
    else if (VecWidth == 512 && EltWidth == 64 && IsFloat)
      IID = Intrinsic::x86_avx512_permvar_df_512;
    else if (VecWidth == 512 && EltWidth == 64 && !IsFloat)
      IID = Intrinsic::x86_avx512_permvar_di_512;
    else if (VecWidth == 128 && EltWidth == 16)
      IID = Intrinsic::x86_avx512_permvar_hi_128;
    else if (VecWidth == 256 && EltWidth == 16)
      IID = Intrinsic::x86_avx512_permvar_hi_256;
    else if (VecWidth == 512 && EltWidth == 16)
      IID = Intrinsic::x86_avx512_permvar_hi_512;
    else if (VecWidth == 128 && EltWidth == 8)
      IID = Intrinsic::x86_avx512_permvar_qi_128;
    else if (VecWidth == 256 && EltWidth == 8)
      IID = Intrinsic::x86_avx512_permvar_qi_256;
    else if (VecWidth == 512 && EltWidth == 8)
      IID = Intrinsic::x86_avx512_permvar_qi_512;
    else
      llvm_unreachable("Unexpected intrinsic");
  } else if (Name.starts_with("dbpsadbw.")) {
    if (VecWidth == 128)
      IID = Intrinsic::x86_avx512_dbpsadbw_128;
    else if (VecWidth == 256)
      IID = Intrinsic::x86_avx512_dbpsadbw_256;
    else if (VecWidth == 512)
      IID = Intrinsic::x86_avx512_dbpsadbw_512;
    else
      llvm_unreachable("Unexpected intrinsic");
  } else if (Name.starts_with("pmultishift.qb.")) {
    if (VecWidth == 128)
      IID = Intrinsic::x86_avx512_pmultishift_qb_128;
    else if (VecWidth == 256)
      IID = Intrinsic::x86_avx512_pmultishift_qb_256;
    else if (VecWidth == 512)
      IID = Intrinsic::x86_avx512_pmultishift_qb_512;
    else
      llvm_unreachable("Unexpected intrinsic");
  } else if (Name.starts_with("conflict.")) {
    if (Name[9] == 'd' && VecWidth == 128)
      IID = Intrinsic::x86_avx512_conflict_d_128;
    else if (Name[9] == 'd' && VecWidth == 256)
      IID = Intrinsic::x86_avx512_conflict_d_256;
    else if (Name[9] == 'd' && VecWidth == 512)
      IID = Intrinsic::x86_avx512_conflict_d_512;
    else if (Name[9] == 'q' && VecWidth == 128)
      IID = Intrinsic::x86_avx512_conflict_q_128;
    else if (Name[9] == 'q' && VecWidth == 256)
      IID = Intrinsic::x86_avx512_conflict_q_256;
    else if (Name[9] == 'q' && VecWidth == 512)
      IID = Intrinsic::x86_avx512_conflict_q_512;
    else
      llvm_unreachable("Unexpected intrinsic");
  } else if (Name.starts_with("pavg.")) {
    if (Name[5] == 'b' && VecWidth == 128)
      IID = Intrinsic::x86_sse2_pavg_b;
    else if (Name[5] == 'b' && VecWidth == 256)
      IID = Intrinsic::x86_avx2_pavg_b;
    else if (Name[5] == 'b' && VecWidth == 512)
      IID = Intrinsic::x86_avx512_pavg_b_512;
    else if (Name[5] == 'w' && VecWidth == 128)
      IID = Intrinsic::x86_sse2_pavg_w;
    else if (Name[5] == 'w' && VecWidth == 256)
      IID = Intrinsic::x86_avx2_pavg_w;
    else if (Name[5] == 'w' && VecWidth == 512)
      IID = Intrinsic::x86_avx512_pavg_w_512;
    else
      llvm_unreachable("Unexpected intrinsic");
  } else
    return false;

  SmallVector<Value *, 4> Args(CI.args());
  Args.pop_back();
  Args.pop_back();
  Rep = Builder.CreateIntrinsic(IID, Args);
  unsigned NumArgs = CI.arg_size();
  Rep = emitX86Select(Builder, CI.getArgOperand(NumArgs - 1), Rep,
                      CI.getArgOperand(NumArgs - 2));
  return true;
}

/// Upgrade comment in call to inline asm that represents an objc retain release
/// marker.
void llvm::UpgradeInlineAsmString(std::string *AsmStr) {
  size_t Pos;
  if (AsmStr->find("mov\tfp") == 0 &&
      AsmStr->find("objc_retainAutoreleaseReturnValue") != std::string::npos &&
      (Pos = AsmStr->find("# marker")) != std::string::npos) {
    AsmStr->replace(Pos, 1, ";");
  }
}

static Value *upgradeNVVMIntrinsicCall(StringRef Name, CallBase *CI,
                                       Function *F, IRBuilder<> &Builder) {
  Value *Rep = nullptr;

  if (Name == "abs.i" || Name == "abs.ll") {
    Value *Arg = CI->getArgOperand(0);
    Value *Neg = Builder.CreateNeg(Arg, "neg");
    Value *Cmp = Builder.CreateICmpSGE(
        Arg, llvm::Constant::getNullValue(Arg->getType()), "abs.cond");
    Rep = Builder.CreateSelect(Cmp, Arg, Neg, "abs");
  } else if (Name == "abs.bf16" || Name == "abs.bf16x2") {
    Type *Ty = (Name == "abs.bf16")
                   ? Builder.getBFloatTy()
                   : FixedVectorType::get(Builder.getBFloatTy(), 2);
    Value *Arg = Builder.CreateBitCast(CI->getArgOperand(0), Ty);
    Value *Abs = Builder.CreateUnaryIntrinsic(Intrinsic::nvvm_fabs, Arg);
    Rep = Builder.CreateBitCast(Abs, CI->getType());
  } else if (Name == "fabs.f" || Name == "fabs.ftz.f" || Name == "fabs.d") {
    Intrinsic::ID IID = (Name == "fabs.ftz.f") ? Intrinsic::nvvm_fabs_ftz
                                               : Intrinsic::nvvm_fabs;
    Rep = Builder.CreateUnaryIntrinsic(IID, CI->getArgOperand(0));
  } else if (Name.consume_front("ex2.approx.")) {
    // nvvm.ex2.approx.{f,ftz.f,d,f16x2}
    Intrinsic::ID IID = Name.starts_with("ftz") ? Intrinsic::nvvm_ex2_approx_ftz
                                                : Intrinsic::nvvm_ex2_approx;
    Rep = Builder.CreateUnaryIntrinsic(IID, CI->getArgOperand(0));
  } else if (Name.starts_with("atomic.load.add.f32.p") ||
             Name.starts_with("atomic.load.add.f64.p")) {
    Value *Ptr = CI->getArgOperand(0);
    Value *Val = CI->getArgOperand(1);
    Rep = Builder.CreateAtomicRMW(AtomicRMWInst::FAdd, Ptr, Val, MaybeAlign(),
                                  AtomicOrdering::Monotonic);
  } else if (Name.starts_with("atomic.load.inc.32.p") ||
             Name.starts_with("atomic.load.dec.32.p")) {
    Value *Ptr = CI->getArgOperand(0);
    Value *Val = CI->getArgOperand(1);
    auto Op = Name.starts_with("atomic.load.inc") ? AtomicRMWInst::UIncWrap
                                                  : AtomicRMWInst::UDecWrap;
    Rep = Builder.CreateAtomicRMW(Op, Ptr, Val, MaybeAlign(),
                                  AtomicOrdering::Monotonic);
  } else if (Name == "clz.ll") {
    // llvm.nvvm.clz.ll returns an i32, but llvm.ctlz.i64 returns an i64.
    Value *Arg = CI->getArgOperand(0);
    Value *Ctlz = Builder.CreateIntrinsic(Intrinsic::ctlz, {Arg->getType()},
                                          {Arg, Builder.getFalse()},
                                          /*FMFSource=*/nullptr, "ctlz");
    Rep = Builder.CreateTrunc(Ctlz, Builder.getInt32Ty(), "ctlz.trunc");
  } else if (Name == "popc.ll") {
    // llvm.nvvm.popc.ll returns an i32, but llvm.ctpop.i64 returns an
    // i64.
    Value *Arg = CI->getArgOperand(0);
    Value *Popc = Builder.CreateIntrinsic(Intrinsic::ctpop, {Arg->getType()},
                                          Arg, /*FMFSource=*/nullptr, "ctpop");
    Rep = Builder.CreateTrunc(Popc, Builder.getInt32Ty(), "ctpop.trunc");
  } else if (Name == "h2f") {
    Value *Cast =
        Builder.CreateBitCast(CI->getArgOperand(0), Builder.getHalfTy());
    Rep = Builder.CreateFPExt(Cast, Builder.getFloatTy());
  } else if (Name.consume_front("bitcast.") &&
             (Name == "f2i" || Name == "i2f" || Name == "ll2d" ||
              Name == "d2ll")) {
    Rep = Builder.CreateBitCast(CI->getArgOperand(0), CI->getType());
  } else if (Name == "rotate.b32") {
    Value *Arg = CI->getOperand(0);
    Value *ShiftAmt = CI->getOperand(1);
    Rep = Builder.CreateIntrinsic(Builder.getInt32Ty(), Intrinsic::fshl,
                                  {Arg, Arg, ShiftAmt});
  } else if (Name == "rotate.b64") {
    Type *Int64Ty = Builder.getInt64Ty();
    Value *Arg = CI->getOperand(0);
    Value *ZExtShiftAmt = Builder.CreateZExt(CI->getOperand(1), Int64Ty);
    Rep = Builder.CreateIntrinsic(Int64Ty, Intrinsic::fshl,
                                  {Arg, Arg, ZExtShiftAmt});
  } else if (Name == "rotate.right.b64") {
    Type *Int64Ty = Builder.getInt64Ty();
    Value *Arg = CI->getOperand(0);
    Value *ZExtShiftAmt = Builder.CreateZExt(CI->getOperand(1), Int64Ty);
    Rep = Builder.CreateIntrinsic(Int64Ty, Intrinsic::fshr,
                                  {Arg, Arg, ZExtShiftAmt});
  } else if (Name == "swap.lo.hi.b64") {
    Type *Int64Ty = Builder.getInt64Ty();
    Value *Arg = CI->getOperand(0);
    Rep = Builder.CreateIntrinsic(Int64Ty, Intrinsic::fshl,
                                  {Arg, Arg, Builder.getInt64(32)});
  } else if ((Name.consume_front("ptr.gen.to.") &&
              consumeNVVMPtrAddrSpace(Name)) ||
             (Name.consume_front("ptr.") && consumeNVVMPtrAddrSpace(Name) &&
              Name.starts_with(".to.gen"))) {
    Rep = Builder.CreateAddrSpaceCast(CI->getArgOperand(0), CI->getType());
  } else if (Name.consume_front("ldg.global")) {
    Value *Ptr = CI->getArgOperand(0);
    Align PtrAlign = cast<ConstantInt>(CI->getArgOperand(1))->getAlignValue();
    // Use addrspace(1) for NVPTX ADDRESS_SPACE_GLOBAL
    Value *ASC = Builder.CreateAddrSpaceCast(Ptr, Builder.getPtrTy(1));
    Instruction *LD = Builder.CreateAlignedLoad(CI->getType(), ASC, PtrAlign);
    MDNode *MD = MDNode::get(Builder.getContext(), {});
    LD->setMetadata(LLVMContext::MD_invariant_load, MD);
    return LD;
  } else if (Name == "tanh.approx.f32") {
    // nvvm.tanh.approx.f32 -> afn llvm.tanh.f32
    FastMathFlags FMF;
    FMF.setApproxFunc();
    Rep = Builder.CreateUnaryIntrinsic(Intrinsic::tanh, CI->getArgOperand(0),
                                       FMF);
  } else if (Name == "barrier0" || Name == "barrier.n" || Name == "bar.sync") {
    Value *Arg =
        Name.ends_with('0') ? Builder.getInt32(0) : CI->getArgOperand(0);
    Rep = Builder.CreateIntrinsic(Intrinsic::nvvm_barrier_cta_sync_aligned_all,
                                  {}, {Arg});
  } else if (Name == "barrier") {
    Rep = Builder.CreateIntrinsic(
        Intrinsic::nvvm_barrier_cta_sync_aligned_count, {},
        {CI->getArgOperand(0), CI->getArgOperand(1)});
  } else if (Name == "barrier.sync") {
    Rep = Builder.CreateIntrinsic(Intrinsic::nvvm_barrier_cta_sync_all, {},
                                  {CI->getArgOperand(0)});
  } else if (Name == "barrier.sync.cnt") {
    Rep = Builder.CreateIntrinsic(Intrinsic::nvvm_barrier_cta_sync_count, {},
                                  {CI->getArgOperand(0), CI->getArgOperand(1)});
  } else if (Name == "barrier0.popc" || Name == "barrier0.and" ||
             Name == "barrier0.or") {
    Value *C = CI->getArgOperand(0);
    C = Builder.CreateICmpNE(C, Builder.getInt32(0));

    Intrinsic::ID IID =
        StringSwitch<Intrinsic::ID>(Name)
            .Case("barrier0.popc",
                  Intrinsic::nvvm_barrier_cta_red_popc_aligned_all)
            .Case("barrier0.and",
                  Intrinsic::nvvm_barrier_cta_red_and_aligned_all)
            .Case("barrier0.or",
                  Intrinsic::nvvm_barrier_cta_red_or_aligned_all);
    Value *Bar = Builder.CreateIntrinsic(IID, {}, {Builder.getInt32(0), C});
    Rep = Builder.CreateZExt(Bar, CI->getType());
  } else {
    Intrinsic::ID IID = shouldUpgradeNVPTXBF16Intrinsic(Name);
    if (IID != Intrinsic::not_intrinsic &&
        !F->getReturnType()->getScalarType()->isBFloatTy()) {
      rename(F);
      Function *NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), IID);
      SmallVector<Value *, 2> Args;
      for (size_t I = 0; I < NewFn->arg_size(); ++I) {
        Value *Arg = CI->getArgOperand(I);
        Type *OldType = Arg->getType();
        Type *NewType = NewFn->getArg(I)->getType();
        Args.push_back(
            (OldType->isIntegerTy() && NewType->getScalarType()->isBFloatTy())
                ? Builder.CreateBitCast(Arg, NewType)
                : Arg);
      }
      Rep = Builder.CreateCall(NewFn, Args);
      if (F->getReturnType()->isIntegerTy())
        Rep = Builder.CreateBitCast(Rep, F->getReturnType());
    }
  }

  return Rep;
}

static Value *upgradeX86IntrinsicCall(StringRef Name, CallBase *CI, Function *F,
                                      IRBuilder<> &Builder) {
  LLVMContext &C = F->getContext();
  Value *Rep = nullptr;

  if (Name.starts_with("sse4a.movnt.")) {
    SmallVector<Metadata *, 1> Elts;
    Elts.push_back(
        ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(C), 1)));
    MDNode *Node = MDNode::get(C, Elts);

    Value *Arg0 = CI->getArgOperand(0);
    Value *Arg1 = CI->getArgOperand(1);

    // Nontemporal (unaligned) store of the 0'th element of the float/double
    // vector.
    Value *Extract =
        Builder.CreateExtractElement(Arg1, (uint64_t)0, "extractelement");

    StoreInst *SI = Builder.CreateAlignedStore(Extract, Arg0, Align(1));
    SI->setMetadata(LLVMContext::MD_nontemporal, Node);
  } else if (Name.starts_with("avx.movnt.") ||
             Name.starts_with("avx512.storent.")) {
    SmallVector<Metadata *, 1> Elts;
    Elts.push_back(
        ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(C), 1)));
    MDNode *Node = MDNode::get(C, Elts);

    Value *Arg0 = CI->getArgOperand(0);
    Value *Arg1 = CI->getArgOperand(1);

    StoreInst *SI = Builder.CreateAlignedStore(
        Arg1, Arg0,
        Align(Arg1->getType()->getPrimitiveSizeInBits().getFixedValue() / 8));
    SI->setMetadata(LLVMContext::MD_nontemporal, Node);
  } else if (Name == "sse2.storel.dq") {
    Value *Arg0 = CI->getArgOperand(0);
    Value *Arg1 = CI->getArgOperand(1);

    auto *NewVecTy = FixedVectorType::get(Type::getInt64Ty(C), 2);
    Value *BC0 = Builder.CreateBitCast(Arg1, NewVecTy, "cast");
    Value *Elt = Builder.CreateExtractElement(BC0, (uint64_t)0);
    Builder.CreateAlignedStore(Elt, Arg0, Align(1));
  } else if (Name.starts_with("sse.storeu.") ||
             Name.starts_with("sse2.storeu.") ||
             Name.starts_with("avx.storeu.")) {
    Value *Arg0 = CI->getArgOperand(0);
    Value *Arg1 = CI->getArgOperand(1);
    Builder.CreateAlignedStore(Arg1, Arg0, Align(1));
  } else if (Name == "avx512.mask.store.ss") {
    Value *Mask = Builder.CreateAnd(CI->getArgOperand(2), Builder.getInt8(1));
    upgradeMaskedStore(Builder, CI->getArgOperand(0), CI->getArgOperand(1),
                       Mask, false);
  } else if (Name.starts_with("avx512.mask.store")) {
    // "avx512.mask.storeu." or "avx512.mask.store."
    bool Aligned = Name[17] != 'u'; // "avx512.mask.storeu".
    upgradeMaskedStore(Builder, CI->getArgOperand(0), CI->getArgOperand(1),
                       CI->getArgOperand(2), Aligned);
  } else if (Name.starts_with("sse2.pcmp") || Name.starts_with("avx2.pcmp")) {
    // Upgrade packed integer vector compare intrinsics to compare instructions.
    // "sse2.pcpmpeq." "sse2.pcmpgt." "avx2.pcmpeq." or "avx2.pcmpgt."
    bool CmpEq = Name[9] == 'e';
    Rep = Builder.CreateICmp(CmpEq ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_SGT,
                             CI->getArgOperand(0), CI->getArgOperand(1));
    Rep = Builder.CreateSExt(Rep, CI->getType(), "");
  } else if (Name.starts_with("avx512.broadcastm")) {
    Type *ExtTy = Type::getInt32Ty(C);
    if (CI->getOperand(0)->getType()->isIntegerTy(8))
      ExtTy = Type::getInt64Ty(C);
    unsigned NumElts = CI->getType()->getPrimitiveSizeInBits() /
                       ExtTy->getPrimitiveSizeInBits();
    Rep = Builder.CreateZExt(CI->getArgOperand(0), ExtTy);
    Rep = Builder.CreateVectorSplat(NumElts, Rep);
  } else if (Name == "sse.sqrt.ss" || Name == "sse2.sqrt.sd") {
    Value *Vec = CI->getArgOperand(0);
    Value *Elt0 = Builder.CreateExtractElement(Vec, (uint64_t)0);
    Elt0 = Builder.CreateIntrinsic(Intrinsic::sqrt, Elt0->getType(), Elt0);
    Rep = Builder.CreateInsertElement(Vec, Elt0, (uint64_t)0);
  } else if (Name.starts_with("avx.sqrt.p") ||
             Name.starts_with("sse2.sqrt.p") ||
             Name.starts_with("sse.sqrt.p")) {
    Rep = Builder.CreateIntrinsic(Intrinsic::sqrt, CI->getType(),
                                  {CI->getArgOperand(0)});
  } else if (Name.starts_with("avx512.mask.sqrt.p")) {
    if (CI->arg_size() == 4 &&
        (!isa<ConstantInt>(CI->getArgOperand(3)) ||
         cast<ConstantInt>(CI->getArgOperand(3))->getZExtValue() != 4)) {
      Intrinsic::ID IID = Name[18] == 's' ? Intrinsic::x86_avx512_sqrt_ps_512
                                          : Intrinsic::x86_avx512_sqrt_pd_512;

      Value *Args[] = {CI->getArgOperand(0), CI->getArgOperand(3)};
      Rep = Builder.CreateIntrinsic(IID, Args);
    } else {
      Rep = Builder.CreateIntrinsic(Intrinsic::sqrt, CI->getType(),
                                    {CI->getArgOperand(0)});
    }
    Rep =
        emitX86Select(Builder, CI->getArgOperand(2), Rep, CI->getArgOperand(1));
  } else if (Name.starts_with("avx512.ptestm") ||
             Name.starts_with("avx512.ptestnm")) {
    Value *Op0 = CI->getArgOperand(0);
    Value *Op1 = CI->getArgOperand(1);
    Value *Mask = CI->getArgOperand(2);
    Rep = Builder.CreateAnd(Op0, Op1);
    llvm::Type *Ty = Op0->getType();
    Value *Zero = llvm::Constant::getNullValue(Ty);
    ICmpInst::Predicate Pred = Name.starts_with("avx512.ptestm")
                                   ? ICmpInst::ICMP_NE
                                   : ICmpInst::ICMP_EQ;
    Rep = Builder.CreateICmp(Pred, Rep, Zero);
    Rep = applyX86MaskOn1BitsVec(Builder, Rep, Mask);
  } else if (Name.starts_with("avx512.mask.pbroadcast")) {
    unsigned NumElts = cast<FixedVectorType>(CI->getArgOperand(1)->getType())
                           ->getNumElements();
    Rep = Builder.CreateVectorSplat(NumElts, CI->getArgOperand(0));
    Rep =
        emitX86Select(Builder, CI->getArgOperand(2), Rep, CI->getArgOperand(1));
  } else if (Name.starts_with("avx512.kunpck")) {
    unsigned NumElts = CI->getType()->getScalarSizeInBits();
    Value *LHS = getX86MaskVec(Builder, CI->getArgOperand(0), NumElts);
    Value *RHS = getX86MaskVec(Builder, CI->getArgOperand(1), NumElts);
    int Indices[64];
    for (unsigned i = 0; i != NumElts; ++i)
      Indices[i] = i;

    // First extract half of each vector. This gives better codegen than
    // doing it in a single shuffle.
    LHS = Builder.CreateShuffleVector(LHS, LHS, ArrayRef(Indices, NumElts / 2));
    RHS = Builder.CreateShuffleVector(RHS, RHS, ArrayRef(Indices, NumElts / 2));
    // Concat the vectors.
    // NOTE: Operands have to be swapped to match intrinsic definition.
    Rep = Builder.CreateShuffleVector(RHS, LHS, ArrayRef(Indices, NumElts));
    Rep = Builder.CreateBitCast(Rep, CI->getType());
  } else if (Name == "avx512.kand.w") {
    Value *LHS = getX86MaskVec(Builder, CI->getArgOperand(0), 16);
    Value *RHS = getX86MaskVec(Builder, CI->getArgOperand(1), 16);
    Rep = Builder.CreateAnd(LHS, RHS);
    Rep = Builder.CreateBitCast(Rep, CI->getType());
  } else if (Name == "avx512.kandn.w") {
    Value *LHS = getX86MaskVec(Builder, CI->getArgOperand(0), 16);
    Value *RHS = getX86MaskVec(Builder, CI->getArgOperand(1), 16);
    LHS = Builder.CreateNot(LHS);
    Rep = Builder.CreateAnd(LHS, RHS);
    Rep = Builder.CreateBitCast(Rep, CI->getType());
  } else if (Name == "avx512.kor.w") {
    Value *LHS = getX86MaskVec(Builder, CI->getArgOperand(0), 16);
    Value *RHS = getX86MaskVec(Builder, CI->getArgOperand(1), 16);
    Rep = Builder.CreateOr(LHS, RHS);
    Rep = Builder.CreateBitCast(Rep, CI->getType());
  } else if (Name == "avx512.kxor.w") {
    Value *LHS = getX86MaskVec(Builder, CI->getArgOperand(0), 16);
    Value *RHS = getX86MaskVec(Builder, CI->getArgOperand(1), 16);
    Rep = Builder.CreateXor(LHS, RHS);
    Rep = Builder.CreateBitCast(Rep, CI->getType());
  } else if (Name == "avx512.kxnor.w") {
    Value *LHS = getX86MaskVec(Builder, CI->getArgOperand(0), 16);
    Value *RHS = getX86MaskVec(Builder, CI->getArgOperand(1), 16);
    LHS = Builder.CreateNot(LHS);
    Rep = Builder.CreateXor(LHS, RHS);
    Rep = Builder.CreateBitCast(Rep, CI->getType());
  } else if (Name == "avx512.knot.w") {
    Rep = getX86MaskVec(Builder, CI->getArgOperand(0), 16);
    Rep = Builder.CreateNot(Rep);
    Rep = Builder.CreateBitCast(Rep, CI->getType());
  } else if (Name == "avx512.kortestz.w" || Name == "avx512.kortestc.w") {
    Value *LHS = getX86MaskVec(Builder, CI->getArgOperand(0), 16);
    Value *RHS = getX86MaskVec(Builder, CI->getArgOperand(1), 16);
    Rep = Builder.CreateOr(LHS, RHS);
    Rep = Builder.CreateBitCast(Rep, Builder.getInt16Ty());
    Value *C;
    if (Name[14] == 'c')
      C = ConstantInt::getAllOnesValue(Builder.getInt16Ty());
    else
      C = ConstantInt::getNullValue(Builder.getInt16Ty());
    Rep = Builder.CreateICmpEQ(Rep, C);
    Rep = Builder.CreateZExt(Rep, Builder.getInt32Ty());
  } else if (Name == "sse.add.ss" || Name == "sse2.add.sd" ||
             Name == "sse.sub.ss" || Name == "sse2.sub.sd" ||
             Name == "sse.mul.ss" || Name == "sse2.mul.sd" ||
             Name == "sse.div.ss" || Name == "sse2.div.sd") {
    Type *I32Ty = Type::getInt32Ty(C);
    Value *Elt0 = Builder.CreateExtractElement(CI->getArgOperand(0),
                                               ConstantInt::get(I32Ty, 0));
    Value *Elt1 = Builder.CreateExtractElement(CI->getArgOperand(1),
                                               ConstantInt::get(I32Ty, 0));
    Value *EltOp;
    if (Name.contains(".add."))
      EltOp = Builder.CreateFAdd(Elt0, Elt1);
    else if (Name.contains(".sub."))
      EltOp = Builder.CreateFSub(Elt0, Elt1);
    else if (Name.contains(".mul."))
      EltOp = Builder.CreateFMul(Elt0, Elt1);
    else
      EltOp = Builder.CreateFDiv(Elt0, Elt1);
    Rep = Builder.CreateInsertElement(CI->getArgOperand(0), EltOp,
                                      ConstantInt::get(I32Ty, 0));
  } else if (Name.starts_with("avx512.mask.pcmp")) {
    // "avx512.mask.pcmpeq." or "avx512.mask.pcmpgt."
    bool CmpEq = Name[16] == 'e';
    Rep = upgradeMaskedCompare(Builder, *CI, CmpEq ? 0 : 6, true);
  } else if (Name.starts_with("avx512.mask.vpshufbitqmb.")) {
    Type *OpTy = CI->getArgOperand(0)->getType();
    unsigned VecWidth = OpTy->getPrimitiveSizeInBits();
    Intrinsic::ID IID;
    switch (VecWidth) {
    default:
      reportFatalUsageErrorWithCI("Unexpected intrinsic", CI);
      break;
    case 128:
      IID = Intrinsic::x86_avx512_vpshufbitqmb_128;
      break;
    case 256:
      IID = Intrinsic::x86_avx512_vpshufbitqmb_256;
      break;
    case 512:
      IID = Intrinsic::x86_avx512_vpshufbitqmb_512;
      break;
    }

    Rep =
        Builder.CreateIntrinsic(IID, {CI->getOperand(0), CI->getArgOperand(1)});
    Rep = applyX86MaskOn1BitsVec(Builder, Rep, CI->getArgOperand(2));
  } else if (Name.starts_with("avx512.mask.fpclass.p")) {
    Type *OpTy = CI->getArgOperand(0)->getType();
    unsigned VecWidth = OpTy->getPrimitiveSizeInBits();
    unsigned EltWidth = OpTy->getScalarSizeInBits();
    Intrinsic::ID IID;
    if (VecWidth == 128 && EltWidth == 32)
      IID = Intrinsic::x86_avx512_fpclass_ps_128;
    else if (VecWidth == 256 && EltWidth == 32)
      IID = Intrinsic::x86_avx512_fpclass_ps_256;
    else if (VecWidth == 512 && EltWidth == 32)
      IID = Intrinsic::x86_avx512_fpclass_ps_512;
    else if (VecWidth == 128 && EltWidth == 64)
      IID = Intrinsic::x86_avx512_fpclass_pd_128;
    else if (VecWidth == 256 && EltWidth == 64)
      IID = Intrinsic::x86_avx512_fpclass_pd_256;
    else if (VecWidth == 512 && EltWidth == 64)
      IID = Intrinsic::x86_avx512_fpclass_pd_512;
    else
      reportFatalUsageErrorWithCI("Unexpected intrinsic", CI);

    Rep =
        Builder.CreateIntrinsic(IID, {CI->getOperand(0), CI->getArgOperand(1)});
    Rep = applyX86MaskOn1BitsVec(Builder, Rep, CI->getArgOperand(2));
  } else if (Name.starts_with("avx512.cmp.p")) {
    SmallVector<Value *, 4> Args(CI->args());
    Type *OpTy = Args[0]->getType();
    unsigned VecWidth = OpTy->getPrimitiveSizeInBits();
    unsigned EltWidth = OpTy->getScalarSizeInBits();
    Intrinsic::ID IID;
    if (VecWidth == 128 && EltWidth == 32)
      IID = Intrinsic::x86_avx512_mask_cmp_ps_128;
    else if (VecWidth == 256 && EltWidth == 32)
      IID = Intrinsic::x86_avx512_mask_cmp_ps_256;
    else if (VecWidth == 512 && EltWidth == 32)
      IID = Intrinsic::x86_avx512_mask_cmp_ps_512;
    else if (VecWidth == 128 && EltWidth == 64)
      IID = Intrinsic::x86_avx512_mask_cmp_pd_128;
    else if (VecWidth == 256 && EltWidth == 64)
      IID = Intrinsic::x86_avx512_mask_cmp_pd_256;
    else if (VecWidth == 512 && EltWidth == 64)
      IID = Intrinsic::x86_avx512_mask_cmp_pd_512;
    else
      reportFatalUsageErrorWithCI("Unexpected intrinsic", CI);

    Value *Mask = Constant::getAllOnesValue(CI->getType());
    if (VecWidth == 512)
      std::swap(Mask, Args.back());
    Args.push_back(Mask);

    Rep = Builder.CreateIntrinsic(IID, Args);
  } else if (Name.starts_with("avx512.mask.cmp.")) {
    // Integer compare intrinsics.
    unsigned Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
    Rep = upgradeMaskedCompare(Builder, *CI, Imm, true);
  } else if (Name.starts_with("avx512.mask.ucmp.")) {
    unsigned Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
    Rep = upgradeMaskedCompare(Builder, *CI, Imm, false);
  } else if (Name.starts_with("avx512.cvtb2mask.") ||
             Name.starts_with("avx512.cvtw2mask.") ||
             Name.starts_with("avx512.cvtd2mask.") ||
             Name.starts_with("avx512.cvtq2mask.")) {
    Value *Op = CI->getArgOperand(0);
    Value *Zero = llvm::Constant::getNullValue(Op->getType());
    Rep = Builder.CreateICmp(ICmpInst::ICMP_SLT, Op, Zero);
    Rep = applyX86MaskOn1BitsVec(Builder, Rep, nullptr);
  } else if (Name == "ssse3.pabs.b.128" || Name == "ssse3.pabs.w.128" ||
             Name == "ssse3.pabs.d.128" || Name.starts_with("avx2.pabs") ||
             Name.starts_with("avx512.mask.pabs")) {
    Rep = upgradeAbs(Builder, *CI);
  } else if (Name == "sse41.pmaxsb" || Name == "sse2.pmaxs.w" ||
             Name == "sse41.pmaxsd" || Name.starts_with("avx2.pmaxs") ||
             Name.starts_with("avx512.mask.pmaxs")) {
    Rep = upgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::smax);
  } else if (Name == "sse2.pmaxu.b" || Name == "sse41.pmaxuw" ||
             Name == "sse41.pmaxud" || Name.starts_with("avx2.pmaxu") ||
             Name.starts_with("avx512.mask.pmaxu")) {
    Rep = upgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::umax);
  } else if (Name == "sse41.pminsb" || Name == "sse2.pmins.w" ||
             Name == "sse41.pminsd" || Name.starts_with("avx2.pmins") ||
             Name.starts_with("avx512.mask.pmins")) {
    Rep = upgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::smin);
  } else if (Name == "sse2.pminu.b" || Name == "sse41.pminuw" ||
             Name == "sse41.pminud" || Name.starts_with("avx2.pminu") ||
             Name.starts_with("avx512.mask.pminu")) {
    Rep = upgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::umin);
  } else if (Name == "sse2.pmulu.dq" || Name == "avx2.pmulu.dq" ||
             Name == "avx512.pmulu.dq.512" ||
             Name.starts_with("avx512.mask.pmulu.dq.")) {
    Rep = upgradePMULDQ(Builder, *CI, /*Signed*/ false);
  } else if (Name == "sse41.pmuldq" || Name == "avx2.pmul.dq" ||
             Name == "avx512.pmul.dq.512" ||
             Name.starts_with("avx512.mask.pmul.dq.")) {
    Rep = upgradePMULDQ(Builder, *CI, /*Signed*/ true);
  } else if (Name == "sse.cvtsi2ss" || Name == "sse2.cvtsi2sd" ||
             Name == "sse.cvtsi642ss" || Name == "sse2.cvtsi642sd") {
    Rep =
        Builder.CreateSIToFP(CI->getArgOperand(1),
                             cast<VectorType>(CI->getType())->getElementType());
    Rep = Builder.CreateInsertElement(CI->getArgOperand(0), Rep, (uint64_t)0);
  } else if (Name == "avx512.cvtusi2sd") {
    Rep =
        Builder.CreateUIToFP(CI->getArgOperand(1),
                             cast<VectorType>(CI->getType())->getElementType());
    Rep = Builder.CreateInsertElement(CI->getArgOperand(0), Rep, (uint64_t)0);
  } else if (Name == "sse2.cvtss2sd") {
    Rep = Builder.CreateExtractElement(CI->getArgOperand(1), (uint64_t)0);
    Rep = Builder.CreateFPExt(
        Rep, cast<VectorType>(CI->getType())->getElementType());
    Rep = Builder.CreateInsertElement(CI->getArgOperand(0), Rep, (uint64_t)0);
  } else if (Name == "sse2.cvtdq2pd" || Name == "sse2.cvtdq2ps" ||
             Name == "avx.cvtdq2.pd.256" || Name == "avx.cvtdq2.ps.256" ||
             Name.starts_with("avx512.mask.cvtdq2pd.") ||
             Name.starts_with("avx512.mask.cvtudq2pd.") ||
             Name.starts_with("avx512.mask.cvtdq2ps.") ||
             Name.starts_with("avx512.mask.cvtudq2ps.") ||
             Name.starts_with("avx512.mask.cvtqq2pd.") ||
             Name.starts_with("avx512.mask.cvtuqq2pd.") ||
             Name == "avx512.mask.cvtqq2ps.256" ||
             Name == "avx512.mask.cvtqq2ps.512" ||
             Name == "avx512.mask.cvtuqq2ps.256" ||
             Name == "avx512.mask.cvtuqq2ps.512" || Name == "sse2.cvtps2pd" ||
             Name == "avx.cvt.ps2.pd.256" ||
             Name == "avx512.mask.cvtps2pd.128" ||
             Name == "avx512.mask.cvtps2pd.256") {
    auto *DstTy = cast<FixedVectorType>(CI->getType());
    Rep = CI->getArgOperand(0);
    auto *SrcTy = cast<FixedVectorType>(Rep->getType());

    unsigned NumDstElts = DstTy->getNumElements();
    if (NumDstElts < SrcTy->getNumElements()) {
      assert(NumDstElts == 2 && "Unexpected vector size");
      Rep = Builder.CreateShuffleVector(Rep, Rep, ArrayRef<int>{0, 1});
    }

    bool IsPS2PD = SrcTy->getElementType()->isFloatTy();
    bool IsUnsigned = Name.contains("cvtu");
    if (IsPS2PD)
      Rep = Builder.CreateFPExt(Rep, DstTy, "cvtps2pd");
    else if (CI->arg_size() == 4 &&
             (!isa<ConstantInt>(CI->getArgOperand(3)) ||
              cast<ConstantInt>(CI->getArgOperand(3))->getZExtValue() != 4)) {
      Intrinsic::ID IID = IsUnsigned ? Intrinsic::x86_avx512_uitofp_round
                                     : Intrinsic::x86_avx512_sitofp_round;
      Rep = Builder.CreateIntrinsic(IID, {DstTy, SrcTy},
                                    {Rep, CI->getArgOperand(3)});
    } else {
      Rep = IsUnsigned ? Builder.CreateUIToFP(Rep, DstTy, "cvt")
                       : Builder.CreateSIToFP(Rep, DstTy, "cvt");
    }

    if (CI->arg_size() >= 3)
      Rep = emitX86Select(Builder, CI->getArgOperand(2), Rep,
                          CI->getArgOperand(1));
  } else if (Name.starts_with("avx512.mask.vcvtph2ps.") ||
             Name.starts_with("vcvtph2ps.")) {
    auto *DstTy = cast<FixedVectorType>(CI->getType());
    Rep = CI->getArgOperand(0);
    auto *SrcTy = cast<FixedVectorType>(Rep->getType());
    unsigned NumDstElts = DstTy->getNumElements();
    if (NumDstElts != SrcTy->getNumElements()) {
      assert(NumDstElts == 4 && "Unexpected vector size");
      Rep = Builder.CreateShuffleVector(Rep, Rep, ArrayRef<int>{0, 1, 2, 3});
    }
    Rep = Builder.CreateBitCast(
        Rep, FixedVectorType::get(Type::getHalfTy(C), NumDstElts));
    Rep = Builder.CreateFPExt(Rep, DstTy, "cvtph2ps");
    if (CI->arg_size() >= 3)
      Rep = emitX86Select(Builder, CI->getArgOperand(2), Rep,
                          CI->getArgOperand(1));
  } else if (Name.starts_with("avx512.mask.load")) {
    // "avx512.mask.loadu." or "avx512.mask.load."
    bool Aligned = Name[16] != 'u'; // "avx512.mask.loadu".
    Rep = upgradeMaskedLoad(Builder, CI->getArgOperand(0), CI->getArgOperand(1),
                            CI->getArgOperand(2), Aligned);
  } else if (Name.starts_with("avx512.mask.expand.load.")) {
    auto *ResultTy = cast<FixedVectorType>(CI->getType());
    Value *MaskVec = getX86MaskVec(Builder, CI->getArgOperand(2),
                                   ResultTy->getNumElements());

    Rep = Builder.CreateIntrinsic(
        Intrinsic::masked_expandload, ResultTy,
        {CI->getOperand(0), MaskVec, CI->getOperand(1)});
  } else if (Name.starts_with("avx512.mask.compress.store.")) {
    auto *ResultTy = cast<VectorType>(CI->getArgOperand(1)->getType());
    Value *MaskVec =
        getX86MaskVec(Builder, CI->getArgOperand(2),
                      cast<FixedVectorType>(ResultTy)->getNumElements());

    Rep = Builder.CreateIntrinsic(
        Intrinsic::masked_compressstore, ResultTy,
        {CI->getArgOperand(1), CI->getArgOperand(0), MaskVec});
  } else if (Name.starts_with("avx512.mask.compress.") ||
             Name.starts_with("avx512.mask.expand.")) {
    auto *ResultTy = cast<FixedVectorType>(CI->getType());

    Value *MaskVec = getX86MaskVec(Builder, CI->getArgOperand(2),
                                   ResultTy->getNumElements());

    bool IsCompress = Name[12] == 'c';
    Intrinsic::ID IID = IsCompress ? Intrinsic::x86_avx512_mask_compress
                                   : Intrinsic::x86_avx512_mask_expand;
    Rep = Builder.CreateIntrinsic(
        IID, ResultTy, {CI->getOperand(0), CI->getOperand(1), MaskVec});
  } else if (Name.starts_with("xop.vpcom")) {
    bool IsSigned;
    if (Name.ends_with("ub") || Name.ends_with("uw") || Name.ends_with("ud") ||
        Name.ends_with("uq"))
      IsSigned = false;
    else if (Name.ends_with("b") || Name.ends_with("w") ||
             Name.ends_with("d") || Name.ends_with("q"))
      IsSigned = true;
    else
      reportFatalUsageErrorWithCI("Intrinsic has unknown suffix", CI);

    unsigned Imm;
    if (CI->arg_size() == 3) {
      Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
    } else {
      Name = Name.substr(9); // strip off "xop.vpcom"
      if (Name.starts_with("lt"))
        Imm = 0;
      else if (Name.starts_with("le"))
        Imm = 1;
      else if (Name.starts_with("gt"))
        Imm = 2;
      else if (Name.starts_with("ge"))
        Imm = 3;
      else if (Name.starts_with("eq"))
        Imm = 4;
      else if (Name.starts_with("ne"))
        Imm = 5;
      else if (Name.starts_with("false"))
        Imm = 6;
      else if (Name.starts_with("true"))
        Imm = 7;
      else
        llvm_unreachable("Unknown condition");
    }

    Rep = upgradeX86vpcom(Builder, *CI, Imm, IsSigned);
  } else if (Name.starts_with("xop.vpcmov")) {
    Value *Sel = CI->getArgOperand(2);
    Value *NotSel = Builder.CreateNot(Sel);
    Value *Sel0 = Builder.CreateAnd(CI->getArgOperand(0), Sel);
    Value *Sel1 = Builder.CreateAnd(CI->getArgOperand(1), NotSel);
    Rep = Builder.CreateOr(Sel0, Sel1);
  } else if (Name.starts_with("xop.vprot") || Name.starts_with("avx512.prol") ||
             Name.starts_with("avx512.mask.prol")) {
    Rep = upgradeX86Rotate(Builder, *CI, false);
  } else if (Name.starts_with("avx512.pror") ||
             Name.starts_with("avx512.mask.pror")) {
    Rep = upgradeX86Rotate(Builder, *CI, true);
  } else if (Name.starts_with("avx512.vpshld.") ||
             Name.starts_with("avx512.mask.vpshld") ||
             Name.starts_with("avx512.maskz.vpshld")) {
    bool ZeroMask = Name[11] == 'z';
    Rep = upgradeX86ConcatShift(Builder, *CI, false, ZeroMask);
  } else if (Name.starts_with("avx512.vpshrd.") ||
             Name.starts_with("avx512.mask.vpshrd") ||
             Name.starts_with("avx512.maskz.vpshrd")) {
    bool ZeroMask = Name[11] == 'z';
    Rep = upgradeX86ConcatShift(Builder, *CI, true, ZeroMask);
  } else if (Name == "sse42.crc32.64.8") {
    Value *Trunc0 =
        Builder.CreateTrunc(CI->getArgOperand(0), Type::getInt32Ty(C));
    Rep = Builder.CreateIntrinsic(Intrinsic::x86_sse42_crc32_32_8,
                                  {Trunc0, CI->getArgOperand(1)});
    Rep = Builder.CreateZExt(Rep, CI->getType(), "");
  } else if (Name.starts_with("avx.vbroadcast.s") ||
             Name.starts_with("avx512.vbroadcast.s")) {
    // Replace broadcasts with a series of insertelements.
    auto *VecTy = cast<FixedVectorType>(CI->getType());
    Type *EltTy = VecTy->getElementType();
    unsigned EltNum = VecTy->getNumElements();
    Value *Load = Builder.CreateLoad(EltTy, CI->getArgOperand(0));
    Type *I32Ty = Type::getInt32Ty(C);
    Rep = PoisonValue::get(VecTy);
    for (unsigned I = 0; I < EltNum; ++I)
      Rep = Builder.CreateInsertElement(Rep, Load, ConstantInt::get(I32Ty, I));
  } else if (Name.starts_with("sse41.pmovsx") ||
             Name.starts_with("sse41.pmovzx") ||
             Name.starts_with("avx2.pmovsx") ||
             Name.starts_with("avx2.pmovzx") ||
             Name.starts_with("avx512.mask.pmovsx") ||
             Name.starts_with("avx512.mask.pmovzx")) {
    auto *DstTy = cast<FixedVectorType>(CI->getType());
    unsigned NumDstElts = DstTy->getNumElements();

    // Extract a subvector of the first NumDstElts lanes and sign/zero extend.
    SmallVector<int, 8> ShuffleMask(NumDstElts);
    for (unsigned i = 0; i != NumDstElts; ++i)
      ShuffleMask[i] = i;

    Value *SV = Builder.CreateShuffleVector(CI->getArgOperand(0), ShuffleMask);

    bool DoSext = Name.contains("pmovsx");
    Rep =
        DoSext ? Builder.CreateSExt(SV, DstTy) : Builder.CreateZExt(SV, DstTy);
    // If there are 3 arguments, it's a masked intrinsic so we need a select.
    if (CI->arg_size() == 3)
      Rep = emitX86Select(Builder, CI->getArgOperand(2), Rep,
                          CI->getArgOperand(1));
  } else if (Name == "avx512.mask.pmov.qd.256" ||
             Name == "avx512.mask.pmov.qd.512" ||
             Name == "avx512.mask.pmov.wb.256" ||
             Name == "avx512.mask.pmov.wb.512") {
    Type *Ty = CI->getArgOperand(1)->getType();
    Rep = Builder.CreateTrunc(CI->getArgOperand(0), Ty);
    Rep =
        emitX86Select(Builder, CI->getArgOperand(2), Rep, CI->getArgOperand(1));
  } else if (Name.starts_with("avx.vbroadcastf128") ||
             Name == "avx2.vbroadcasti128") {
    // Replace vbroadcastf128/vbroadcasti128 with a vector load+shuffle.
    Type *EltTy = cast<VectorType>(CI->getType())->getElementType();
    unsigned NumSrcElts = 128 / EltTy->getPrimitiveSizeInBits();
    auto *VT = FixedVectorType::get(EltTy, NumSrcElts);
    Value *Load = Builder.CreateAlignedLoad(VT, CI->getArgOperand(0), Align(1));
    if (NumSrcElts == 2)
      Rep = Builder.CreateShuffleVector(Load, ArrayRef<int>{0, 1, 0, 1});
    else
      Rep = Builder.CreateShuffleVector(Load,
                                        ArrayRef<int>{0, 1, 2, 3, 0, 1, 2, 3});
  } else if (Name.starts_with("avx512.mask.shuf.i") ||
             Name.starts_with("avx512.mask.shuf.f")) {
    unsigned Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
    Type *VT = CI->getType();
    unsigned NumLanes = VT->getPrimitiveSizeInBits() / 128;
    unsigned NumElementsInLane = 128 / VT->getScalarSizeInBits();
    unsigned ControlBitsMask = NumLanes - 1;
    unsigned NumControlBits = NumLanes / 2;
    SmallVector<int, 8> ShuffleMask(0);

    for (unsigned l = 0; l != NumLanes; ++l) {
      unsigned LaneMask = (Imm >> (l * NumControlBits)) & ControlBitsMask;
      // We actually need the other source.
      if (l >= NumLanes / 2)
        LaneMask += NumLanes;
      for (unsigned i = 0; i != NumElementsInLane; ++i)
        ShuffleMask.push_back(LaneMask * NumElementsInLane + i);
    }
    Rep = Builder.CreateShuffleVector(CI->getArgOperand(0),
                                      CI->getArgOperand(1), ShuffleMask);
    Rep =
        emitX86Select(Builder, CI->getArgOperand(4), Rep, CI->getArgOperand(3));
  } else if (Name.starts_with("avx512.mask.broadcastf") ||
             Name.starts_with("avx512.mask.broadcasti")) {
    unsigned NumSrcElts = cast<FixedVectorType>(CI->getArgOperand(0)->getType())
                              ->getNumElements();
    unsigned NumDstElts =
        cast<FixedVectorType>(CI->getType())->getNumElements();

    SmallVector<int, 8> ShuffleMask(NumDstElts);
    for (unsigned i = 0; i != NumDstElts; ++i)
      ShuffleMask[i] = i % NumSrcElts;

    Rep = Builder.CreateShuffleVector(CI->getArgOperand(0),
                                      CI->getArgOperand(0), ShuffleMask);
    Rep =
        emitX86Select(Builder, CI->getArgOperand(2), Rep, CI->getArgOperand(1));
  } else if (Name.starts_with("avx2.pbroadcast") ||
             Name.starts_with("avx2.vbroadcast") ||
             Name.starts_with("avx512.pbroadcast") ||
             Name.starts_with("avx512.mask.broadcast.s")) {
    // Replace vp?broadcasts with a vector shuffle.
    Value *Op = CI->getArgOperand(0);
    ElementCount EC = cast<VectorType>(CI->getType())->getElementCount();
    Type *MaskTy = VectorType::get(Type::getInt32Ty(C), EC);
    SmallVector<int, 8> M;
    ShuffleVectorInst::getShuffleMask(Constant::getNullValue(MaskTy), M);
    Rep = Builder.CreateShuffleVector(Op, M);

    if (CI->arg_size() == 3)
      Rep = emitX86Select(Builder, CI->getArgOperand(2), Rep,
                          CI->getArgOperand(1));
  } else if (Name.starts_with("sse2.padds.") ||
             Name.starts_with("avx2.padds.") ||
             Name.starts_with("avx512.padds.") ||
             Name.starts_with("avx512.mask.padds.")) {
    Rep = upgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::sadd_sat);
  } else if (Name.starts_with("sse2.psubs.") ||
             Name.starts_with("avx2.psubs.") ||
             Name.starts_with("avx512.psubs.") ||
             Name.starts_with("avx512.mask.psubs.")) {
    Rep = upgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::ssub_sat);
  } else if (Name.starts_with("sse2.paddus.") ||
             Name.starts_with("avx2.paddus.") ||
             Name.starts_with("avx512.mask.paddus.")) {
    Rep = upgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::uadd_sat);
  } else if (Name.starts_with("sse2.psubus.") ||
             Name.starts_with("avx2.psubus.") ||
             Name.starts_with("avx512.mask.psubus.")) {
    Rep = upgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::usub_sat);
  } else if (Name.starts_with("avx512.mask.palignr.")) {
    Rep = upgradeX86ALIGNIntrinsics(Builder, CI->getArgOperand(0),
                                    CI->getArgOperand(1), CI->getArgOperand(2),
                                    CI->getArgOperand(3), CI->getArgOperand(4),
                                    false);
  } else if (Name.starts_with("avx512.mask.valign.")) {
    Rep = upgradeX86ALIGNIntrinsics(
        Builder, CI->getArgOperand(0), CI->getArgOperand(1),
        CI->getArgOperand(2), CI->getArgOperand(3), CI->getArgOperand(4), true);
  } else if (Name == "sse2.psll.dq" || Name == "avx2.psll.dq") {
    // 128/256-bit shift left specified in bits.
    unsigned Shift = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
    Rep = upgradeX86PSLLDQIntrinsics(Builder, CI->getArgOperand(0),
                                     Shift / 8); // Shift is in bits.
  } else if (Name == "sse2.psrl.dq" || Name == "avx2.psrl.dq") {
    // 128/256-bit shift right specified in bits.
    unsigned Shift = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
    Rep = upgradeX86PSRLDQIntrinsics(Builder, CI->getArgOperand(0),
                                     Shift / 8); // Shift is in bits.
  } else if (Name == "sse2.psll.dq.bs" || Name == "avx2.psll.dq.bs" ||
             Name == "avx512.psll.dq.512") {
    // 128/256/512-bit shift left specified in bytes.
    unsigned Shift = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
    Rep = upgradeX86PSLLDQIntrinsics(Builder, CI->getArgOperand(0), Shift);
  } else if (Name == "sse2.psrl.dq.bs" || Name == "avx2.psrl.dq.bs" ||
             Name == "avx512.psrl.dq.512") {
    // 128/256/512-bit shift right specified in bytes.
    unsigned Shift = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
    Rep = upgradeX86PSRLDQIntrinsics(Builder, CI->getArgOperand(0), Shift);
  } else if (Name == "sse41.pblendw" || Name.starts_with("sse41.blendp") ||
             Name.starts_with("avx.blend.p") || Name == "avx2.pblendw" ||
             Name.starts_with("avx2.pblendd.")) {
    Value *Op0 = CI->getArgOperand(0);
    Value *Op1 = CI->getArgOperand(1);
    unsigned Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
    auto *VecTy = cast<FixedVectorType>(CI->getType());
    unsigned NumElts = VecTy->getNumElements();

    SmallVector<int, 16> Idxs(NumElts);
    for (unsigned i = 0; i != NumElts; ++i)
      Idxs[i] = ((Imm >> (i % 8)) & 1) ? i + NumElts : i;

    Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);
  } else if (Name.starts_with("avx.vinsertf128.") ||
             Name == "avx2.vinserti128" ||
             Name.starts_with("avx512.mask.insert")) {
    Value *Op0 = CI->getArgOperand(0);
    Value *Op1 = CI->getArgOperand(1);
    unsigned Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
    unsigned DstNumElts =
        cast<FixedVectorType>(CI->getType())->getNumElements();
    unsigned SrcNumElts =
        cast<FixedVectorType>(Op1->getType())->getNumElements();
    unsigned Scale = DstNumElts / SrcNumElts;

    // Mask off the high bits of the immediate value; hardware ignores those.
    Imm = Imm % Scale;

    // Extend the second operand into a vector the size of the destination.
    SmallVector<int, 8> Idxs(DstNumElts);
    for (unsigned i = 0; i != SrcNumElts; ++i)
      Idxs[i] = i;
    for (unsigned i = SrcNumElts; i != DstNumElts; ++i)
      Idxs[i] = SrcNumElts;
    Rep = Builder.CreateShuffleVector(Op1, Idxs);

    // Insert the second operand into the first operand.

    // Note that there is no guarantee that instruction lowering will actually
    // produce a vinsertf128 instruction for the created shuffles. In
    // particular, the 0 immediate case involves no lane changes, so it can
    // be handled as a blend.

    // Example of shuffle mask for 32-bit elements:
    // Imm = 1  <i32 0, i32 1, i32 2,  i32 3,  i32 8, i32 9, i32 10, i32 11>
    // Imm = 0  <i32 8, i32 9, i32 10, i32 11, i32 4, i32 5, i32 6,  i32 7 >

    // First fill with identify mask.
    for (unsigned i = 0; i != DstNumElts; ++i)
      Idxs[i] = i;
    // Then replace the elements where we need to insert.
    for (unsigned i = 0; i != SrcNumElts; ++i)
      Idxs[i + Imm * SrcNumElts] = i + DstNumElts;
    Rep = Builder.CreateShuffleVector(Op0, Rep, Idxs);

    // If the intrinsic has a mask operand, handle that.
    if (CI->arg_size() == 5)
      Rep = emitX86Select(Builder, CI->getArgOperand(4), Rep,
                          CI->getArgOperand(3));
  } else if (Name.starts_with("avx.vextractf128.") ||
             Name == "avx2.vextracti128" ||
             Name.starts_with("avx512.mask.vextract")) {
    Value *Op0 = CI->getArgOperand(0);
    unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
    unsigned DstNumElts =
        cast<FixedVectorType>(CI->getType())->getNumElements();
    unsigned SrcNumElts =
        cast<FixedVectorType>(Op0->getType())->getNumElements();
    unsigned Scale = SrcNumElts / DstNumElts;

    // Mask off the high bits of the immediate value; hardware ignores those.
    Imm = Imm % Scale;

    // Get indexes for the subvector of the input vector.
    SmallVector<int, 8> Idxs(DstNumElts);
    for (unsigned i = 0; i != DstNumElts; ++i) {
      Idxs[i] = i + (Imm * DstNumElts);
    }
    Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);

    // If the intrinsic has a mask operand, handle that.
    if (CI->arg_size() == 4)
      Rep = emitX86Select(Builder, CI->getArgOperand(3), Rep,
                          CI->getArgOperand(2));
  } else if (Name.starts_with("avx512.mask.perm.df.") ||
             Name.starts_with("avx512.mask.perm.di.")) {
    Value *Op0 = CI->getArgOperand(0);
    unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
    auto *VecTy = cast<FixedVectorType>(CI->getType());
    unsigned NumElts = VecTy->getNumElements();

    SmallVector<int, 8> Idxs(NumElts);
    for (unsigned i = 0; i != NumElts; ++i)
      Idxs[i] = (i & ~0x3) + ((Imm >> (2 * (i & 0x3))) & 3);

    Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);

    if (CI->arg_size() == 4)
      Rep = emitX86Select(Builder, CI->getArgOperand(3), Rep,
                          CI->getArgOperand(2));
  } else if (Name.starts_with("avx.vperm2f128.") || Name == "avx2.vperm2i128") {
    // 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

    uint8_t Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();

    unsigned NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();
    unsigned HalfSize = NumElts / 2;
    SmallVector<int, 8> ShuffleMask(NumElts);

    // Determine which operand(s) are actually in use for this instruction.
    Value *V0 = (Imm & 0x02) ? CI->getArgOperand(1) : CI->getArgOperand(0);
    Value *V1 = (Imm & 0x20) ? CI->getArgOperand(1) : CI->getArgOperand(0);

    // If needed, replace operands based on zero mask.
    V0 = (Imm & 0x08) ? ConstantAggregateZero::get(CI->getType()) : V0;
    V1 = (Imm & 0x80) ? ConstantAggregateZero::get(CI->getType()) : V1;

    // Permute low half of result.
    unsigned StartIndex = (Imm & 0x01) ? HalfSize : 0;
    for (unsigned i = 0; i < HalfSize; ++i)
      ShuffleMask[i] = StartIndex + i;

    // Permute high half of result.
    StartIndex = (Imm & 0x10) ? HalfSize : 0;
    for (unsigned i = 0; i < HalfSize; ++i)
      ShuffleMask[i + HalfSize] = NumElts + StartIndex + i;

    Rep = Builder.CreateShuffleVector(V0, V1, ShuffleMask);

  } else if (Name.starts_with("avx.vpermil.") || Name == "sse2.pshuf.d" ||
             Name.starts_with("avx512.mask.vpermil.p") ||
             Name.starts_with("avx512.mask.pshuf.d.")) {
    Value *Op0 = CI->getArgOperand(0);
    unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
    auto *VecTy = cast<FixedVectorType>(CI->getType());
    unsigned NumElts = VecTy->getNumElements();
    // Calculate the size of each index in the immediate.
    unsigned IdxSize = 64 / VecTy->getScalarSizeInBits();
    unsigned IdxMask = ((1 << IdxSize) - 1);

    SmallVector<int, 8> Idxs(NumElts);
    // Lookup the bits for this element, wrapping around the immediate every
    // 8-bits. Elements are grouped into sets of 2 or 4 elements so we need
    // to offset by the first index of each group.
    for (unsigned i = 0; i != NumElts; ++i)
      Idxs[i] = ((Imm >> ((i * IdxSize) % 8)) & IdxMask) | (i & ~IdxMask);

    Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);

    if (CI->arg_size() == 4)
      Rep = emitX86Select(Builder, CI->getArgOperand(3), Rep,
                          CI->getArgOperand(2));
  } else if (Name == "sse2.pshufl.w" ||
             Name.starts_with("avx512.mask.pshufl.w.")) {
    Value *Op0 = CI->getArgOperand(0);
    unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
    unsigned NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();

    if (Name == "sse2.pshufl.w" && NumElts % 8 != 0)
      reportFatalUsageErrorWithCI("Intrinsic has invalid signature", CI);

    SmallVector<int, 16> Idxs(NumElts);
    for (unsigned l = 0; l != NumElts; l += 8) {
      for (unsigned i = 0; i != 4; ++i)
        Idxs[i + l] = ((Imm >> (2 * i)) & 0x3) + l;
      for (unsigned i = 4; i != 8; ++i)
        Idxs[i + l] = i + l;
    }

    Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);

    if (CI->arg_size() == 4)
      Rep = emitX86Select(Builder, CI->getArgOperand(3), Rep,
                          CI->getArgOperand(2));
  } else if (Name == "sse2.pshufh.w" ||
             Name.starts_with("avx512.mask.pshufh.w.")) {
    Value *Op0 = CI->getArgOperand(0);
    unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
    unsigned NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();

    if (Name == "sse2.pshufh.w" && NumElts % 8 != 0)
      reportFatalUsageErrorWithCI("Intrinsic has invalid signature", CI);

    SmallVector<int, 16> Idxs(NumElts);
    for (unsigned l = 0; l != NumElts; l += 8) {
      for (unsigned i = 0; i != 4; ++i)
        Idxs[i + l] = i + l;
      for (unsigned i = 0; i != 4; ++i)
        Idxs[i + l + 4] = ((Imm >> (2 * i)) & 0x3) + 4 + l;
    }

    Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);

    if (CI->arg_size() == 4)
      Rep = emitX86Select(Builder, CI->getArgOperand(3), Rep,
                          CI->getArgOperand(2));
  } else if (Name.starts_with("avx512.mask.shuf.p")) {
    Value *Op0 = CI->getArgOperand(0);
    Value *Op1 = CI->getArgOperand(1);
    unsigned Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
    unsigned NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();

    unsigned NumLaneElts = 128 / CI->getType()->getScalarSizeInBits();
    unsigned HalfLaneElts = NumLaneElts / 2;

    SmallVector<int, 16> Idxs(NumElts);
    for (unsigned i = 0; i != NumElts; ++i) {
      // Base index is the starting element of the lane.
      Idxs[i] = i - (i % NumLaneElts);
      // If we are half way through the lane switch to the other source.
      if ((i % NumLaneElts) >= HalfLaneElts)
        Idxs[i] += NumElts;
      // Now select the specific element. By adding HalfLaneElts bits from
      // the immediate. Wrapping around the immediate every 8-bits.
      Idxs[i] += (Imm >> ((i * HalfLaneElts) % 8)) & ((1 << HalfLaneElts) - 1);
    }

    Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);

    Rep =
        emitX86Select(Builder, CI->getArgOperand(4), Rep, CI->getArgOperand(3));
  } else if (Name.starts_with("avx512.mask.movddup") ||
             Name.starts_with("avx512.mask.movshdup") ||
             Name.starts_with("avx512.mask.movsldup")) {
    Value *Op0 = CI->getArgOperand(0);
    unsigned NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();
    unsigned NumLaneElts = 128 / CI->getType()->getScalarSizeInBits();

    unsigned Offset = 0;
    if (Name.starts_with("avx512.mask.movshdup."))
      Offset = 1;

    SmallVector<int, 16> Idxs(NumElts);
    for (unsigned l = 0; l != NumElts; l += NumLaneElts)
      for (unsigned i = 0; i != NumLaneElts; i += 2) {
        Idxs[i + l + 0] = i + l + Offset;
        Idxs[i + l + 1] = i + l + Offset;
      }

    Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);

    Rep =
        emitX86Select(Builder, CI->getArgOperand(2), Rep, CI->getArgOperand(1));
  } else if (Name.starts_with("avx512.mask.punpckl") ||
             Name.starts_with("avx512.mask.unpckl.")) {
    Value *Op0 = CI->getArgOperand(0);
    Value *Op1 = CI->getArgOperand(1);
    int NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();
    int NumLaneElts = 128 / CI->getType()->getScalarSizeInBits();

    SmallVector<int, 64> Idxs(NumElts);
    for (int l = 0; l != NumElts; l += NumLaneElts)
      for (int i = 0; i != NumLaneElts; ++i)
        Idxs[i + l] = l + (i / 2) + NumElts * (i % 2);

    Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);

    Rep =
        emitX86Select(Builder, CI->getArgOperand(3), Rep, CI->getArgOperand(2));
  } else if (Name.starts_with("avx512.mask.punpckh") ||
             Name.starts_with("avx512.mask.unpckh.")) {
    Value *Op0 = CI->getArgOperand(0);
    Value *Op1 = CI->getArgOperand(1);
    int NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();
    int NumLaneElts = 128 / CI->getType()->getScalarSizeInBits();

    SmallVector<int, 64> Idxs(NumElts);
    for (int l = 0; l != NumElts; l += NumLaneElts)
      for (int i = 0; i != NumLaneElts; ++i)
        Idxs[i + l] = (NumLaneElts / 2) + l + (i / 2) + NumElts * (i % 2);

    Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);

    Rep =
        emitX86Select(Builder, CI->getArgOperand(3), Rep, CI->getArgOperand(2));
  } else if (Name.starts_with("avx512.mask.and.") ||
             Name.starts_with("avx512.mask.pand.")) {
    VectorType *FTy = cast<VectorType>(CI->getType());
    VectorType *ITy = VectorType::getInteger(FTy);
    Rep = Builder.CreateAnd(Builder.CreateBitCast(CI->getArgOperand(0), ITy),
                            Builder.CreateBitCast(CI->getArgOperand(1), ITy));
    Rep = Builder.CreateBitCast(Rep, FTy);
    Rep =
        emitX86Select(Builder, CI->getArgOperand(3), Rep, CI->getArgOperand(2));
  } else if (Name.starts_with("avx512.mask.andn.") ||
             Name.starts_with("avx512.mask.pandn.")) {
    VectorType *FTy = cast<VectorType>(CI->getType());
    VectorType *ITy = VectorType::getInteger(FTy);
    Rep = Builder.CreateNot(Builder.CreateBitCast(CI->getArgOperand(0), ITy));
    Rep = Builder.CreateAnd(Rep,
                            Builder.CreateBitCast(CI->getArgOperand(1), ITy));
    Rep = Builder.CreateBitCast(Rep, FTy);
    Rep =
        emitX86Select(Builder, CI->getArgOperand(3), Rep, CI->getArgOperand(2));
  } else if (Name.starts_with("avx512.mask.or.") ||
             Name.starts_with("avx512.mask.por.")) {
    VectorType *FTy = cast<VectorType>(CI->getType());
    VectorType *ITy = VectorType::getInteger(FTy);
    Rep = Builder.CreateOr(Builder.CreateBitCast(CI->getArgOperand(0), ITy),
                           Builder.CreateBitCast(CI->getArgOperand(1), ITy));
    Rep = Builder.CreateBitCast(Rep, FTy);
    Rep =
        emitX86Select(Builder, CI->getArgOperand(3), Rep, CI->getArgOperand(2));
  } else if (Name.starts_with("avx512.mask.xor.") ||
             Name.starts_with("avx512.mask.pxor.")) {
    VectorType *FTy = cast<VectorType>(CI->getType());
    VectorType *ITy = VectorType::getInteger(FTy);
    Rep = Builder.CreateXor(Builder.CreateBitCast(CI->getArgOperand(0), ITy),
                            Builder.CreateBitCast(CI->getArgOperand(1), ITy));
    Rep = Builder.CreateBitCast(Rep, FTy);
    Rep =
        emitX86Select(Builder, CI->getArgOperand(3), Rep, CI->getArgOperand(2));
  } else if (Name.starts_with("avx512.mask.padd.")) {
    Rep = Builder.CreateAdd(CI->getArgOperand(0), CI->getArgOperand(1));
    Rep =
        emitX86Select(Builder, CI->getArgOperand(3), Rep, CI->getArgOperand(2));
  } else if (Name.starts_with("avx512.mask.psub.")) {
    Rep = Builder.CreateSub(CI->getArgOperand(0), CI->getArgOperand(1));
    Rep =
        emitX86Select(Builder, CI->getArgOperand(3), Rep, CI->getArgOperand(2));
  } else if (Name.starts_with("avx512.mask.pmull.")) {
    Rep = Builder.CreateMul(CI->getArgOperand(0), CI->getArgOperand(1));
    Rep =
        emitX86Select(Builder, CI->getArgOperand(3), Rep, CI->getArgOperand(2));
  } else if (Name.starts_with("avx512.mask.add.p")) {
    if (Name.ends_with(".512")) {
      Intrinsic::ID IID;
      if (Name[17] == 's')
        IID = Intrinsic::x86_avx512_add_ps_512;
      else
        IID = Intrinsic::x86_avx512_add_pd_512;

      Rep = Builder.CreateIntrinsic(
          IID,
          {CI->getArgOperand(0), CI->getArgOperand(1), CI->getArgOperand(4)});
    } else {
      Rep = Builder.CreateFAdd(CI->getArgOperand(0), CI->getArgOperand(1));
    }
    Rep =
        emitX86Select(Builder, CI->getArgOperand(3), Rep, CI->getArgOperand(2));
  } else if (Name.starts_with("avx512.mask.div.p")) {
    if (Name.ends_with(".512")) {
      Intrinsic::ID IID;
      if (Name[17] == 's')
        IID = Intrinsic::x86_avx512_div_ps_512;
      else
        IID = Intrinsic::x86_avx512_div_pd_512;

      Rep = Builder.CreateIntrinsic(
          IID,
          {CI->getArgOperand(0), CI->getArgOperand(1), CI->getArgOperand(4)});
    } else {
      Rep = Builder.CreateFDiv(CI->getArgOperand(0), CI->getArgOperand(1));
    }
    Rep =
        emitX86Select(Builder, CI->getArgOperand(3), Rep, CI->getArgOperand(2));
  } else if (Name.starts_with("avx512.mask.mul.p")) {
    if (Name.ends_with(".512")) {
      Intrinsic::ID IID;
      if (Name[17] == 's')
        IID = Intrinsic::x86_avx512_mul_ps_512;
      else
        IID = Intrinsic::x86_avx512_mul_pd_512;

      Rep = Builder.CreateIntrinsic(
          IID,
          {CI->getArgOperand(0), CI->getArgOperand(1), CI->getArgOperand(4)});
    } else {
      Rep = Builder.CreateFMul(CI->getArgOperand(0), CI->getArgOperand(1));
    }
    Rep =
        emitX86Select(Builder, CI->getArgOperand(3), Rep, CI->getArgOperand(2));
  } else if (Name.starts_with("avx512.mask.sub.p")) {
    if (Name.ends_with(".512")) {
      Intrinsic::ID IID;
      if (Name[17] == 's')
        IID = Intrinsic::x86_avx512_sub_ps_512;
      else
        IID = Intrinsic::x86_avx512_sub_pd_512;

      Rep = Builder.CreateIntrinsic(
          IID,
          {CI->getArgOperand(0), CI->getArgOperand(1), CI->getArgOperand(4)});
    } else {
      Rep = Builder.CreateFSub(CI->getArgOperand(0), CI->getArgOperand(1));
    }
    Rep =
        emitX86Select(Builder, CI->getArgOperand(3), Rep, CI->getArgOperand(2));
  } else if ((Name.starts_with("avx512.mask.max.p") ||
              Name.starts_with("avx512.mask.min.p")) &&
             Name.drop_front(18) == ".512") {
    bool IsDouble = Name[17] == 'd';
    bool IsMin = Name[13] == 'i';
    static const Intrinsic::ID MinMaxTbl[2][2] = {
        {Intrinsic::x86_avx512_max_ps_512, Intrinsic::x86_avx512_max_pd_512},
        {Intrinsic::x86_avx512_min_ps_512, Intrinsic::x86_avx512_min_pd_512}};
    Intrinsic::ID IID = MinMaxTbl[IsMin][IsDouble];

    Rep = Builder.CreateIntrinsic(
        IID,
        {CI->getArgOperand(0), CI->getArgOperand(1), CI->getArgOperand(4)});
    Rep =
        emitX86Select(Builder, CI->getArgOperand(3), Rep, CI->getArgOperand(2));
  } else if (Name.starts_with("avx512.mask.lzcnt.")) {
    Rep =
        Builder.CreateIntrinsic(Intrinsic::ctlz, CI->getType(),
                                {CI->getArgOperand(0), Builder.getInt1(false)});
    Rep =
        emitX86Select(Builder, CI->getArgOperand(2), Rep, CI->getArgOperand(1));
  } else if (Name.starts_with("avx512.mask.psll")) {
    bool IsImmediate = Name[16] == 'i' || (Name.size() > 18 && Name[18] == 'i');
    bool IsVariable = Name[16] == 'v';
    char Size = Name[16] == '.'   ? Name[17]
                : Name[17] == '.' ? Name[18]
                : Name[18] == '.' ? Name[19]
                                  : Name[20];

    Intrinsic::ID IID;
    if (IsVariable && Name[17] != '.') {
      if (Size == 'd' && Name[17] == '2') // avx512.mask.psllv2.di
        IID = Intrinsic::x86_avx2_psllv_q;
      else if (Size == 'd' && Name[17] == '4') // avx512.mask.psllv4.di
        IID = Intrinsic::x86_avx2_psllv_q_256;
      else if (Size == 's' && Name[17] == '4') // avx512.mask.psllv4.si
        IID = Intrinsic::x86_avx2_psllv_d;
      else if (Size == 's' && Name[17] == '8') // avx512.mask.psllv8.si
        IID = Intrinsic::x86_avx2_psllv_d_256;
      else if (Size == 'h' && Name[17] == '8') // avx512.mask.psllv8.hi
        IID = Intrinsic::x86_avx512_psllv_w_128;
      else if (Size == 'h' && Name[17] == '1') // avx512.mask.psllv16.hi
        IID = Intrinsic::x86_avx512_psllv_w_256;
      else if (Name[17] == '3' && Name[18] == '2') // avx512.mask.psllv32hi
        IID = Intrinsic::x86_avx512_psllv_w_512;
      else
        reportFatalUsageErrorWithCI("Intrinsic has unexpected size", CI);
    } else if (Name.ends_with(".128")) {
      if (Size == 'd') // avx512.mask.psll.d.128, avx512.mask.psll.di.128
        IID = IsImmediate ? Intrinsic::x86_sse2_pslli_d
                          : Intrinsic::x86_sse2_psll_d;
      else if (Size == 'q') // avx512.mask.psll.q.128, avx512.mask.psll.qi.128
        IID = IsImmediate ? Intrinsic::x86_sse2_pslli_q
                          : Intrinsic::x86_sse2_psll_q;
      else if (Size == 'w') // avx512.mask.psll.w.128, avx512.mask.psll.wi.128
        IID = IsImmediate ? Intrinsic::x86_sse2_pslli_w
                          : Intrinsic::x86_sse2_psll_w;
      else
        reportFatalUsageErrorWithCI("Intrinsic has unexpected size", CI);
    } else if (Name.ends_with(".256")) {
      if (Size == 'd') // avx512.mask.psll.d.256, avx512.mask.psll.di.256
        IID = IsImmediate ? Intrinsic::x86_avx2_pslli_d
                          : Intrinsic::x86_avx2_psll_d;
      else if (Size == 'q') // avx512.mask.psll.q.256, avx512.mask.psll.qi.256
        IID = IsImmediate ? Intrinsic::x86_avx2_pslli_q
                          : Intrinsic::x86_avx2_psll_q;
      else if (Size == 'w') // avx512.mask.psll.w.256, avx512.mask.psll.wi.256
        IID = IsImmediate ? Intrinsic::x86_avx2_pslli_w
                          : Intrinsic::x86_avx2_psll_w;
      else
        reportFatalUsageErrorWithCI("Intrinsic has unexpected size", CI);
    } else {
      if (Size == 'd') // psll.di.512, pslli.d, psll.d, psllv.d.512
        IID = IsImmediate  ? Intrinsic::x86_avx512_pslli_d_512
              : IsVariable ? Intrinsic::x86_avx512_psllv_d_512
                           : Intrinsic::x86_avx512_psll_d_512;
      else if (Size == 'q') // psll.qi.512, pslli.q, psll.q, psllv.q.512
        IID = IsImmediate  ? Intrinsic::x86_avx512_pslli_q_512
              : IsVariable ? Intrinsic::x86_avx512_psllv_q_512
                           : Intrinsic::x86_avx512_psll_q_512;
      else if (Size == 'w') // psll.wi.512, pslli.w, psll.w
        IID = IsImmediate ? Intrinsic::x86_avx512_pslli_w_512
                          : Intrinsic::x86_avx512_psll_w_512;
      else
        reportFatalUsageErrorWithCI("Intrinsic has unexpected size", CI);
    }

    Rep = upgradeX86MaskedShift(Builder, *CI, IID);
  } else if (Name.starts_with("avx512.mask.psrl")) {
    bool IsImmediate = Name[16] == 'i' || (Name.size() > 18 && Name[18] == 'i');
    bool IsVariable = Name[16] == 'v';
    char Size = Name[16] == '.'   ? Name[17]
                : Name[17] == '.' ? Name[18]
                : Name[18] == '.' ? Name[19]
                                  : Name[20];

    Intrinsic::ID IID;
    if (IsVariable && Name[17] != '.') {
      if (Size == 'd' && Name[17] == '2') // avx512.mask.psrlv2.di
        IID = Intrinsic::x86_avx2_psrlv_q;
      else if (Size == 'd' && Name[17] == '4') // avx512.mask.psrlv4.di
        IID = Intrinsic::x86_avx2_psrlv_q_256;
      else if (Size == 's' && Name[17] == '4') // avx512.mask.psrlv4.si
        IID = Intrinsic::x86_avx2_psrlv_d;
      else if (Size == 's' && Name[17] == '8') // avx512.mask.psrlv8.si
        IID = Intrinsic::x86_avx2_psrlv_d_256;
      else if (Size == 'h' && Name[17] == '8') // avx512.mask.psrlv8.hi
        IID = Intrinsic::x86_avx512_psrlv_w_128;
      else if (Size == 'h' && Name[17] == '1') // avx512.mask.psrlv16.hi
        IID = Intrinsic::x86_avx512_psrlv_w_256;
      else if (Name[17] == '3' && Name[18] == '2') // avx512.mask.psrlv32hi
        IID = Intrinsic::x86_avx512_psrlv_w_512;
      else
        reportFatalUsageErrorWithCI("Intrinsic has unexpected size", CI);
    } else if (Name.ends_with(".128")) {
      if (Size == 'd') // avx512.mask.psrl.d.128, avx512.mask.psrl.di.128
        IID = IsImmediate ? Intrinsic::x86_sse2_psrli_d
                          : Intrinsic::x86_sse2_psrl_d;
      else if (Size == 'q') // avx512.mask.psrl.q.128, avx512.mask.psrl.qi.128
        IID = IsImmediate ? Intrinsic::x86_sse2_psrli_q
                          : Intrinsic::x86_sse2_psrl_q;
      else if (Size == 'w') // avx512.mask.psrl.w.128, avx512.mask.psrl.wi.128
        IID = IsImmediate ? Intrinsic::x86_sse2_psrli_w
                          : Intrinsic::x86_sse2_psrl_w;
      else
        reportFatalUsageErrorWithCI("Intrinsic has unexpected size", CI);
    } else if (Name.ends_with(".256")) {
      if (Size == 'd') // avx512.mask.psrl.d.256, avx512.mask.psrl.di.256
        IID = IsImmediate ? Intrinsic::x86_avx2_psrli_d
                          : Intrinsic::x86_avx2_psrl_d;
      else if (Size == 'q') // avx512.mask.psrl.q.256, avx512.mask.psrl.qi.256
        IID = IsImmediate ? Intrinsic::x86_avx2_psrli_q
                          : Intrinsic::x86_avx2_psrl_q;
      else if (Size == 'w') // avx512.mask.psrl.w.256, avx512.mask.psrl.wi.256
        IID = IsImmediate ? Intrinsic::x86_avx2_psrli_w
                          : Intrinsic::x86_avx2_psrl_w;
      else
        reportFatalUsageErrorWithCI("Intrinsic has unexpected size", CI);
    } else {
      if (Size == 'd') // psrl.di.512, psrli.d, psrl.d, psrl.d.512
        IID = IsImmediate  ? Intrinsic::x86_avx512_psrli_d_512
              : IsVariable ? Intrinsic::x86_avx512_psrlv_d_512
                           : Intrinsic::x86_avx512_psrl_d_512;
      else if (Size == 'q') // psrl.qi.512, psrli.q, psrl.q, psrl.q.512
        IID = IsImmediate  ? Intrinsic::x86_avx512_psrli_q_512
              : IsVariable ? Intrinsic::x86_avx512_psrlv_q_512
                           : Intrinsic::x86_avx512_psrl_q_512;
      else if (Size == 'w') // psrl.wi.512, psrli.w, psrl.w)
        IID = IsImmediate ? Intrinsic::x86_avx512_psrli_w_512
                          : Intrinsic::x86_avx512_psrl_w_512;
      else
        reportFatalUsageErrorWithCI("Intrinsic has unexpected size", CI);
    }

    Rep = upgradeX86MaskedShift(Builder, *CI, IID);
  } else if (Name.starts_with("avx512.mask.psra")) {
    bool IsImmediate = Name[16] == 'i' || (Name.size() > 18 && Name[18] == 'i');
    bool IsVariable = Name[16] == 'v';
    char Size = Name[16] == '.'   ? Name[17]
                : Name[17] == '.' ? Name[18]
                : Name[18] == '.' ? Name[19]
                                  : Name[20];

    Intrinsic::ID IID;
    if (IsVariable && Name[17] != '.') {
      if (Size == 's' && Name[17] == '4') // avx512.mask.psrav4.si
        IID = Intrinsic::x86_avx2_psrav_d;
      else if (Size == 's' && Name[17] == '8') // avx512.mask.psrav8.si
        IID = Intrinsic::x86_avx2_psrav_d_256;
      else if (Size == 'h' && Name[17] == '8') // avx512.mask.psrav8.hi
        IID = Intrinsic::x86_avx512_psrav_w_128;
      else if (Size == 'h' && Name[17] == '1') // avx512.mask.psrav16.hi
        IID = Intrinsic::x86_avx512_psrav_w_256;
      else if (Name[17] == '3' && Name[18] == '2') // avx512.mask.psrav32hi
        IID = Intrinsic::x86_avx512_psrav_w_512;
      else
        reportFatalUsageErrorWithCI("Intrinsic has unexpected size", CI);
    } else if (Name.ends_with(".128")) {
      if (Size == 'd') // avx512.mask.psra.d.128, avx512.mask.psra.di.128
        IID = IsImmediate ? Intrinsic::x86_sse2_psrai_d
                          : Intrinsic::x86_sse2_psra_d;
      else if (Size == 'q') // avx512.mask.psra.q.128, avx512.mask.psra.qi.128
        IID = IsImmediate  ? Intrinsic::x86_avx512_psrai_q_128
              : IsVariable ? Intrinsic::x86_avx512_psrav_q_128
                           : Intrinsic::x86_avx512_psra_q_128;
      else if (Size == 'w') // avx512.mask.psra.w.128, avx512.mask.psra.wi.128
        IID = IsImmediate ? Intrinsic::x86_sse2_psrai_w
                          : Intrinsic::x86_sse2_psra_w;
      else
        reportFatalUsageErrorWithCI("Intrinsic has unexpected size", CI);
    } else if (Name.ends_with(".256")) {
      if (Size == 'd') // avx512.mask.psra.d.256, avx512.mask.psra.di.256
        IID = IsImmediate ? Intrinsic::x86_avx2_psrai_d
                          : Intrinsic::x86_avx2_psra_d;
      else if (Size == 'q') // avx512.mask.psra.q.256, avx512.mask.psra.qi.256
        IID = IsImmediate  ? Intrinsic::x86_avx512_psrai_q_256
              : IsVariable ? Intrinsic::x86_avx512_psrav_q_256
                           : Intrinsic::x86_avx512_psra_q_256;
      else if (Size == 'w') // avx512.mask.psra.w.256, avx512.mask.psra.wi.256
        IID = IsImmediate ? Intrinsic::x86_avx2_psrai_w
                          : Intrinsic::x86_avx2_psra_w;
      else
        reportFatalUsageErrorWithCI("Intrinsic has unexpected size", CI);
    } else {
      if (Size == 'd') // psra.di.512, psrai.d, psra.d, psrav.d.512
        IID = IsImmediate  ? Intrinsic::x86_avx512_psrai_d_512
              : IsVariable ? Intrinsic::x86_avx512_psrav_d_512
                           : Intrinsic::x86_avx512_psra_d_512;
      else if (Size == 'q') // psra.qi.512, psrai.q, psra.q
        IID = IsImmediate  ? Intrinsic::x86_avx512_psrai_q_512
              : IsVariable ? Intrinsic::x86_avx512_psrav_q_512
                           : Intrinsic::x86_avx512_psra_q_512;
      else if (Size == 'w') // psra.wi.512, psrai.w, psra.w
        IID = IsImmediate ? Intrinsic::x86_avx512_psrai_w_512
                          : Intrinsic::x86_avx512_psra_w_512;
      else
        reportFatalUsageErrorWithCI("Intrinsic has unexpected size", CI);
    }

    Rep = upgradeX86MaskedShift(Builder, *CI, IID);
  } else if (Name.starts_with("avx512.mask.move.s")) {
    Rep = upgradeMaskedMove(Builder, *CI);
  } else if (Name.starts_with("avx512.cvtmask2")) {
    Rep = upgradeMaskToInt(Builder, *CI);
  } else if (Name.ends_with(".movntdqa")) {
    MDNode *Node = MDNode::get(
        C, ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(C), 1)));

    LoadInst *LI = Builder.CreateAlignedLoad(
        CI->getType(), CI->getArgOperand(0),
        Align(CI->getType()->getPrimitiveSizeInBits().getFixedValue() / 8));
    LI->setMetadata(LLVMContext::MD_nontemporal, Node);
    Rep = LI;
  } else if (Name.starts_with("fma.vfmadd.") ||
             Name.starts_with("fma.vfmsub.") ||
             Name.starts_with("fma.vfnmadd.") ||
             Name.starts_with("fma.vfnmsub.")) {
    bool NegMul = Name[6] == 'n';
    bool NegAcc = NegMul ? Name[8] == 's' : Name[7] == 's';
    bool IsScalar = NegMul ? Name[12] == 's' : Name[11] == 's';

    Value *Ops[] = {CI->getArgOperand(0), CI->getArgOperand(1),
                    CI->getArgOperand(2)};

    if (IsScalar) {
      Ops[0] = Builder.CreateExtractElement(Ops[0], (uint64_t)0);
      Ops[1] = Builder.CreateExtractElement(Ops[1], (uint64_t)0);
      Ops[2] = Builder.CreateExtractElement(Ops[2], (uint64_t)0);
    }

    if (NegMul && !IsScalar)
      Ops[0] = Builder.CreateFNeg(Ops[0]);
    if (NegMul && IsScalar)
      Ops[1] = Builder.CreateFNeg(Ops[1]);
    if (NegAcc)
      Ops[2] = Builder.CreateFNeg(Ops[2]);

    Rep = Builder.CreateIntrinsic(Intrinsic::fma, Ops[0]->getType(), Ops);

    if (IsScalar)
      Rep = Builder.CreateInsertElement(CI->getArgOperand(0), Rep, (uint64_t)0);
  } else if (Name.starts_with("fma4.vfmadd.s")) {
    Value *Ops[] = {CI->getArgOperand(0), CI->getArgOperand(1),
                    CI->getArgOperand(2)};

    Ops[0] = Builder.CreateExtractElement(Ops[0], (uint64_t)0);
    Ops[1] = Builder.CreateExtractElement(Ops[1], (uint64_t)0);
    Ops[2] = Builder.CreateExtractElement(Ops[2], (uint64_t)0);

    Rep = Builder.CreateIntrinsic(Intrinsic::fma, Ops[0]->getType(), Ops);

    Rep = Builder.CreateInsertElement(Constant::getNullValue(CI->getType()),
                                      Rep, (uint64_t)0);
  } else if (Name.starts_with("avx512.mask.vfmadd.s") ||
             Name.starts_with("avx512.maskz.vfmadd.s") ||
             Name.starts_with("avx512.mask3.vfmadd.s") ||
             Name.starts_with("avx512.mask3.vfmsub.s") ||
             Name.starts_with("avx512.mask3.vfnmsub.s")) {
    bool IsMask3 = Name[11] == '3';
    bool IsMaskZ = Name[11] == 'z';
    // Drop the "avx512.mask." to make it easier.
    Name = Name.drop_front(IsMask3 || IsMaskZ ? 13 : 12);
    bool NegMul = Name[2] == 'n';
    bool NegAcc = NegMul ? Name[4] == 's' : Name[3] == 's';

    Value *A = CI->getArgOperand(0);
    Value *B = CI->getArgOperand(1);
    Value *C = CI->getArgOperand(2);

    if (NegMul && (IsMask3 || IsMaskZ))
      A = Builder.CreateFNeg(A);
    if (NegMul && !(IsMask3 || IsMaskZ))
      B = Builder.CreateFNeg(B);
    if (NegAcc)
      C = Builder.CreateFNeg(C);

    A = Builder.CreateExtractElement(A, (uint64_t)0);
    B = Builder.CreateExtractElement(B, (uint64_t)0);
    C = Builder.CreateExtractElement(C, (uint64_t)0);

    if (!isa<ConstantInt>(CI->getArgOperand(4)) ||
        cast<ConstantInt>(CI->getArgOperand(4))->getZExtValue() != 4) {
      Value *Ops[] = {A, B, C, CI->getArgOperand(4)};

      Intrinsic::ID IID;
      if (Name.back() == 'd')
        IID = Intrinsic::x86_avx512_vfmadd_f64;
      else
        IID = Intrinsic::x86_avx512_vfmadd_f32;
      Rep = Builder.CreateIntrinsic(IID, Ops);
    } else {
      Rep = Builder.CreateFMA(A, B, C);
    }

    Value *PassThru = IsMaskZ   ? Constant::getNullValue(Rep->getType())
                      : IsMask3 ? C
                                : A;

    // For Mask3 with NegAcc, we need to create a new extractelement that
    // avoids the negation above.
    if (NegAcc && IsMask3)
      PassThru =
          Builder.CreateExtractElement(CI->getArgOperand(2), (uint64_t)0);

    Rep = emitX86ScalarSelect(Builder, CI->getArgOperand(3), Rep, PassThru);
    Rep = Builder.CreateInsertElement(CI->getArgOperand(IsMask3 ? 2 : 0), Rep,
                                      (uint64_t)0);
  } else if (Name.starts_with("avx512.mask.vfmadd.p") ||
             Name.starts_with("avx512.mask.vfnmadd.p") ||
             Name.starts_with("avx512.mask.vfnmsub.p") ||
             Name.starts_with("avx512.mask3.vfmadd.p") ||
             Name.starts_with("avx512.mask3.vfmsub.p") ||
             Name.starts_with("avx512.mask3.vfnmsub.p") ||
             Name.starts_with("avx512.maskz.vfmadd.p")) {
    bool IsMask3 = Name[11] == '3';
    bool IsMaskZ = Name[11] == 'z';
    // Drop the "avx512.mask." to make it easier.
    Name = Name.drop_front(IsMask3 || IsMaskZ ? 13 : 12);
    bool NegMul = Name[2] == 'n';
    bool NegAcc = NegMul ? Name[4] == 's' : Name[3] == 's';

    Value *A = CI->getArgOperand(0);
    Value *B = CI->getArgOperand(1);
    Value *C = CI->getArgOperand(2);

    if (NegMul && (IsMask3 || IsMaskZ))
      A = Builder.CreateFNeg(A);
    if (NegMul && !(IsMask3 || IsMaskZ))
      B = Builder.CreateFNeg(B);
    if (NegAcc)
      C = Builder.CreateFNeg(C);

    if (CI->arg_size() == 5 &&
        (!isa<ConstantInt>(CI->getArgOperand(4)) ||
         cast<ConstantInt>(CI->getArgOperand(4))->getZExtValue() != 4)) {
      Intrinsic::ID IID;
      // Check the character before ".512" in string.
      if (Name[Name.size() - 5] == 's')
        IID = Intrinsic::x86_avx512_vfmadd_ps_512;
      else
        IID = Intrinsic::x86_avx512_vfmadd_pd_512;

      Rep = Builder.CreateIntrinsic(IID, {A, B, C, CI->getArgOperand(4)});
    } else {
      Rep = Builder.CreateFMA(A, B, C);
    }

    Value *PassThru = IsMaskZ   ? llvm::Constant::getNullValue(CI->getType())
                      : IsMask3 ? CI->getArgOperand(2)
                                : CI->getArgOperand(0);

    Rep = emitX86Select(Builder, CI->getArgOperand(3), Rep, PassThru);
  } else if (Name.starts_with("fma.vfmsubadd.p")) {
    unsigned VecWidth = CI->getType()->getPrimitiveSizeInBits();
    unsigned EltWidth = CI->getType()->getScalarSizeInBits();
    Intrinsic::ID IID;
    if (VecWidth == 128 && EltWidth == 32)
      IID = Intrinsic::x86_fma_vfmaddsub_ps;
    else if (VecWidth == 256 && EltWidth == 32)
      IID = Intrinsic::x86_fma_vfmaddsub_ps_256;
    else if (VecWidth == 128 && EltWidth == 64)
      IID = Intrinsic::x86_fma_vfmaddsub_pd;
    else if (VecWidth == 256 && EltWidth == 64)
      IID = Intrinsic::x86_fma_vfmaddsub_pd_256;
    else
      reportFatalUsageErrorWithCI("Unexpected intrinsic", CI);

    Value *Ops[] = {CI->getArgOperand(0), CI->getArgOperand(1),
                    CI->getArgOperand(2)};
    Ops[2] = Builder.CreateFNeg(Ops[2]);
    Rep = Builder.CreateIntrinsic(IID, Ops);
  } else if (Name.starts_with("avx512.mask.vfmaddsub.p") ||
             Name.starts_with("avx512.mask3.vfmaddsub.p") ||
             Name.starts_with("avx512.maskz.vfmaddsub.p") ||
             Name.starts_with("avx512.mask3.vfmsubadd.p")) {
    bool IsMask3 = Name[11] == '3';
    bool IsMaskZ = Name[11] == 'z';
    // Drop the "avx512.mask." to make it easier.
    Name = Name.drop_front(IsMask3 || IsMaskZ ? 13 : 12);
    bool IsSubAdd = Name[3] == 's';
    if (CI->arg_size() == 5) {
      Intrinsic::ID IID;
      // Check the character before ".512" in string.
      if (Name[Name.size() - 5] == 's')
        IID = Intrinsic::x86_avx512_vfmaddsub_ps_512;
      else
        IID = Intrinsic::x86_avx512_vfmaddsub_pd_512;

      Value *Ops[] = {CI->getArgOperand(0), CI->getArgOperand(1),
                      CI->getArgOperand(2), CI->getArgOperand(4)};
      if (IsSubAdd)
        Ops[2] = Builder.CreateFNeg(Ops[2]);

      Rep = Builder.CreateIntrinsic(IID, Ops);
    } else {
      int NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();

      Value *Ops[] = {CI->getArgOperand(0), CI->getArgOperand(1),
                      CI->getArgOperand(2)};

      Function *FMA = Intrinsic::getOrInsertDeclaration(
          CI->getModule(), Intrinsic::fma, Ops[0]->getType());
      Value *Odd = Builder.CreateCall(FMA, Ops);
      Ops[2] = Builder.CreateFNeg(Ops[2]);
      Value *Even = Builder.CreateCall(FMA, Ops);

      if (IsSubAdd)
        std::swap(Even, Odd);

      SmallVector<int, 32> Idxs(NumElts);
      for (int i = 0; i != NumElts; ++i)
        Idxs[i] = i + (i % 2) * NumElts;

      Rep = Builder.CreateShuffleVector(Even, Odd, Idxs);
    }

    Value *PassThru = IsMaskZ   ? llvm::Constant::getNullValue(CI->getType())
                      : IsMask3 ? CI->getArgOperand(2)
                                : CI->getArgOperand(0);

    Rep = emitX86Select(Builder, CI->getArgOperand(3), Rep, PassThru);
  } else if (Name.starts_with("avx512.mask.pternlog.") ||
             Name.starts_with("avx512.maskz.pternlog.")) {
    bool ZeroMask = Name[11] == 'z';
    unsigned VecWidth = CI->getType()->getPrimitiveSizeInBits();
    unsigned EltWidth = CI->getType()->getScalarSizeInBits();
    Intrinsic::ID IID;
    if (VecWidth == 128 && EltWidth == 32)
      IID = Intrinsic::x86_avx512_pternlog_d_128;
    else if (VecWidth == 256 && EltWidth == 32)
      IID = Intrinsic::x86_avx512_pternlog_d_256;
    else if (VecWidth == 512 && EltWidth == 32)
      IID = Intrinsic::x86_avx512_pternlog_d_512;
    else if (VecWidth == 128 && EltWidth == 64)
      IID = Intrinsic::x86_avx512_pternlog_q_128;
    else if (VecWidth == 256 && EltWidth == 64)
      IID = Intrinsic::x86_avx512_pternlog_q_256;
    else if (VecWidth == 512 && EltWidth == 64)
      IID = Intrinsic::x86_avx512_pternlog_q_512;
    else
      reportFatalUsageErrorWithCI("Unexpected intrinsic", CI);

    Value *Args[] = {CI->getArgOperand(0), CI->getArgOperand(1),
                     CI->getArgOperand(2), CI->getArgOperand(3)};
    Rep = Builder.CreateIntrinsic(IID, Args);
    Value *PassThru = ZeroMask ? ConstantAggregateZero::get(CI->getType())
                               : CI->getArgOperand(0);
    Rep = emitX86Select(Builder, CI->getArgOperand(4), Rep, PassThru);
  } else if (Name.starts_with("avx512.mask.vpmadd52") ||
             Name.starts_with("avx512.maskz.vpmadd52")) {
    bool ZeroMask = Name[11] == 'z';
    bool High = Name[20] == 'h' || Name[21] == 'h';
    unsigned VecWidth = CI->getType()->getPrimitiveSizeInBits();
    Intrinsic::ID IID;
    if (VecWidth == 128 && !High)
      IID = Intrinsic::x86_avx512_vpmadd52l_uq_128;
    else if (VecWidth == 256 && !High)
      IID = Intrinsic::x86_avx512_vpmadd52l_uq_256;
    else if (VecWidth == 512 && !High)
      IID = Intrinsic::x86_avx512_vpmadd52l_uq_512;
    else if (VecWidth == 128 && High)
      IID = Intrinsic::x86_avx512_vpmadd52h_uq_128;
    else if (VecWidth == 256 && High)
      IID = Intrinsic::x86_avx512_vpmadd52h_uq_256;
    else if (VecWidth == 512 && High)
      IID = Intrinsic::x86_avx512_vpmadd52h_uq_512;
    else
      reportFatalUsageErrorWithCI("Unexpected intrinsic", CI);

    Value *Args[] = {CI->getArgOperand(0), CI->getArgOperand(1),
                     CI->getArgOperand(2)};
    Rep = Builder.CreateIntrinsic(IID, Args);
    Value *PassThru = ZeroMask ? ConstantAggregateZero::get(CI->getType())
                               : CI->getArgOperand(0);
    Rep = emitX86Select(Builder, CI->getArgOperand(3), Rep, PassThru);
  } else if (Name.starts_with("avx512.mask.vpermi2var.") ||
             Name.starts_with("avx512.mask.vpermt2var.") ||
             Name.starts_with("avx512.maskz.vpermt2var.")) {
    bool ZeroMask = Name[11] == 'z';
    bool IndexForm = Name[17] == 'i';
    Rep = upgradeX86VPERMT2Intrinsics(Builder, *CI, ZeroMask, IndexForm);
  } else if (Name.starts_with("avx512.mask.vpdpbusd.") ||
             Name.starts_with("avx512.maskz.vpdpbusd.") ||
             Name.starts_with("avx512.mask.vpdpbusds.") ||
             Name.starts_with("avx512.maskz.vpdpbusds.")) {
    bool ZeroMask = Name[11] == 'z';
    bool IsSaturating = Name[ZeroMask ? 21 : 20] == 's';
    unsigned VecWidth = CI->getType()->getPrimitiveSizeInBits();
    Intrinsic::ID IID;
    if (VecWidth == 128 && !IsSaturating)
      IID = Intrinsic::x86_avx512_vpdpbusd_128;
    else if (VecWidth == 256 && !IsSaturating)
      IID = Intrinsic::x86_avx512_vpdpbusd_256;
    else if (VecWidth == 512 && !IsSaturating)
      IID = Intrinsic::x86_avx512_vpdpbusd_512;
    else if (VecWidth == 128 && IsSaturating)
      IID = Intrinsic::x86_avx512_vpdpbusds_128;
    else if (VecWidth == 256 && IsSaturating)
      IID = Intrinsic::x86_avx512_vpdpbusds_256;
    else if (VecWidth == 512 && IsSaturating)
      IID = Intrinsic::x86_avx512_vpdpbusds_512;
    else
      reportFatalUsageErrorWithCI("Unexpected intrinsic", CI);

    Value *Args[] = {CI->getArgOperand(0), CI->getArgOperand(1),
                     CI->getArgOperand(2)};

    // Input arguments types were incorrectly set to vectors of i32 before but
    // they should be vectors of i8. Insert bit cast when encountering the old
    // types
    if (Args[1]->getType()->isVectorTy() &&
        cast<VectorType>(Args[1]->getType())
            ->getElementType()
            ->isIntegerTy(32) &&
        Args[2]->getType()->isVectorTy() &&
        cast<VectorType>(Args[2]->getType())
            ->getElementType()
            ->isIntegerTy(32)) {
      Type *NewArgType = nullptr;
      if (VecWidth == 128)
        NewArgType = VectorType::get(Builder.getInt8Ty(), 16, false);
      else if (VecWidth == 256)
        NewArgType = VectorType::get(Builder.getInt8Ty(), 32, false);
      else if (VecWidth == 512)
        NewArgType = VectorType::get(Builder.getInt8Ty(), 64, false);
      else
        reportFatalUsageErrorWithCI("Intrinsic has unexpected vector bit width",
                                    CI);

      Args[1] = Builder.CreateBitCast(Args[1], NewArgType);
      Args[2] = Builder.CreateBitCast(Args[2], NewArgType);
    }

    Rep = Builder.CreateIntrinsic(IID, Args);
    Value *PassThru = ZeroMask ? ConstantAggregateZero::get(CI->getType())
                               : CI->getArgOperand(0);
    Rep = emitX86Select(Builder, CI->getArgOperand(3), Rep, PassThru);
  } else if (Name.starts_with("avx512.mask.vpdpwssd.") ||
             Name.starts_with("avx512.maskz.vpdpwssd.") ||
             Name.starts_with("avx512.mask.vpdpwssds.") ||
             Name.starts_with("avx512.maskz.vpdpwssds.")) {
    bool ZeroMask = Name[11] == 'z';
    bool IsSaturating = Name[ZeroMask ? 21 : 20] == 's';
    unsigned VecWidth = CI->getType()->getPrimitiveSizeInBits();
    Intrinsic::ID IID;
    if (VecWidth == 128 && !IsSaturating)
      IID = Intrinsic::x86_avx512_vpdpwssd_128;
    else if (VecWidth == 256 && !IsSaturating)
      IID = Intrinsic::x86_avx512_vpdpwssd_256;
    else if (VecWidth == 512 && !IsSaturating)
      IID = Intrinsic::x86_avx512_vpdpwssd_512;
    else if (VecWidth == 128 && IsSaturating)
      IID = Intrinsic::x86_avx512_vpdpwssds_128;
    else if (VecWidth == 256 && IsSaturating)
      IID = Intrinsic::x86_avx512_vpdpwssds_256;
    else if (VecWidth == 512 && IsSaturating)
      IID = Intrinsic::x86_avx512_vpdpwssds_512;
    else
      reportFatalUsageErrorWithCI("Unexpected intrinsic", CI);

    Value *Args[] = {CI->getArgOperand(0), CI->getArgOperand(1),
                     CI->getArgOperand(2)};

    // Input arguments types were incorrectly set to vectors of i32 before but
    // they should be vectors of i16. Insert bit cast when encountering the old
    // types
    if (Args[1]->getType()->isVectorTy() &&
        cast<VectorType>(Args[1]->getType())
            ->getElementType()
            ->isIntegerTy(32) &&
        Args[2]->getType()->isVectorTy() &&
        cast<VectorType>(Args[2]->getType())
            ->getElementType()
            ->isIntegerTy(32)) {
      Type *NewArgType = nullptr;
      if (VecWidth == 128)
        NewArgType = VectorType::get(Builder.getInt16Ty(), 8, false);
      else if (VecWidth == 256)
        NewArgType = VectorType::get(Builder.getInt16Ty(), 16, false);
      else if (VecWidth == 512)
        NewArgType = VectorType::get(Builder.getInt16Ty(), 32, false);
      else
        reportFatalUsageErrorWithCI("Intrinsic has unexpected vector bit width",
                                    CI);

      Args[1] = Builder.CreateBitCast(Args[1], NewArgType);
      Args[2] = Builder.CreateBitCast(Args[2], NewArgType);
    }

    Rep = Builder.CreateIntrinsic(IID, Args);
    Value *PassThru = ZeroMask ? ConstantAggregateZero::get(CI->getType())
                               : CI->getArgOperand(0);
    Rep = emitX86Select(Builder, CI->getArgOperand(3), Rep, PassThru);
  } else if (Name == "addcarryx.u32" || Name == "addcarryx.u64" ||
             Name == "addcarry.u32" || Name == "addcarry.u64" ||
             Name == "subborrow.u32" || Name == "subborrow.u64") {
    Intrinsic::ID IID;
    if (Name[0] == 'a' && Name.back() == '2')
      IID = Intrinsic::x86_addcarry_32;
    else if (Name[0] == 'a' && Name.back() == '4')
      IID = Intrinsic::x86_addcarry_64;
    else if (Name[0] == 's' && Name.back() == '2')
      IID = Intrinsic::x86_subborrow_32;
    else if (Name[0] == 's' && Name.back() == '4')
      IID = Intrinsic::x86_subborrow_64;
    else
      reportFatalUsageErrorWithCI("Unexpected intrinsic", CI);

    // Make a call with 3 operands.
    Value *Args[] = {CI->getArgOperand(0), CI->getArgOperand(1),
                     CI->getArgOperand(2)};
    Value *NewCall = Builder.CreateIntrinsic(IID, Args);

    // Extract the second result and store it.
    Value *Data = Builder.CreateExtractValue(NewCall, 1);
    Builder.CreateAlignedStore(Data, CI->getArgOperand(3), Align(1));
    // Replace the original call result with the first result of the new call.
    Value *CF = Builder.CreateExtractValue(NewCall, 0);

    CI->replaceAllUsesWith(CF);
    Rep = nullptr;
  } else if (Name.starts_with("avx512.mask.") &&
             upgradeAVX512MaskToSelect(Name, Builder, *CI, Rep)) {
    // Rep will be updated by the call in the condition.
  } else
    reportFatalUsageErrorWithCI("Unexpected intrinsic", CI);

  return Rep;
}

static Value *upgradeAArch64IntrinsicCall(StringRef Name, CallBase *CI,
                                          Function *F, IRBuilder<> &Builder) {
  if (Name.starts_with("neon.bfcvt")) {
    if (Name.starts_with("neon.bfcvtn2")) {
      SmallVector<int, 32> LoMask(4);
      std::iota(LoMask.begin(), LoMask.end(), 0);
      SmallVector<int, 32> ConcatMask(8);
      std::iota(ConcatMask.begin(), ConcatMask.end(), 0);
      Value *Inactive = Builder.CreateShuffleVector(CI->getOperand(0), LoMask);
      Value *Trunc =
          Builder.CreateFPTrunc(CI->getOperand(1), Inactive->getType());
      return Builder.CreateShuffleVector(Inactive, Trunc, ConcatMask);
    } else if (Name.starts_with("neon.bfcvtn")) {
      SmallVector<int, 32> ConcatMask(8);
      std::iota(ConcatMask.begin(), ConcatMask.end(), 0);
      Type *V4BF16 =
          FixedVectorType::get(Type::getBFloatTy(F->getContext()), 4);
      Value *Trunc = Builder.CreateFPTrunc(CI->getOperand(0), V4BF16);
      dbgs() << "Trunc: " << *Trunc << "\n";
      return Builder.CreateShuffleVector(
          Trunc, ConstantAggregateZero::get(V4BF16), ConcatMask);
    } else {
      return Builder.CreateFPTrunc(CI->getOperand(0),
                                   Type::getBFloatTy(F->getContext()));
    }
  } else if (Name.starts_with("sve.fcvt")) {
    Intrinsic::ID NewID =
        StringSwitch<Intrinsic::ID>(Name)
            .Case("sve.fcvt.bf16f32", Intrinsic::aarch64_sve_fcvt_bf16f32_v2)
            .Case("sve.fcvtnt.bf16f32",
                  Intrinsic::aarch64_sve_fcvtnt_bf16f32_v2)
            .Default(Intrinsic::not_intrinsic);
    if (NewID == Intrinsic::not_intrinsic)
      llvm_unreachable("Unhandled Intrinsic!");

    SmallVector<Value *, 3> Args(CI->args());

    // The original intrinsics incorrectly used a predicate based on the
    // smallest element type rather than the largest.
    Type *BadPredTy = ScalableVectorType::get(Builder.getInt1Ty(), 8);
    Type *GoodPredTy = ScalableVectorType::get(Builder.getInt1Ty(), 4);

    if (Args[1]->getType() != BadPredTy)
      llvm_unreachable("Unexpected predicate type!");

    Args[1] = Builder.CreateIntrinsic(Intrinsic::aarch64_sve_convert_to_svbool,
                                      BadPredTy, Args[1]);
    Args[1] = Builder.CreateIntrinsic(
        Intrinsic::aarch64_sve_convert_from_svbool, GoodPredTy, Args[1]);

    return Builder.CreateIntrinsic(NewID, Args, /*FMFSource=*/nullptr,
                                   CI->getName());
  }

  llvm_unreachable("Unhandled Intrinsic!");
}

static Value *upgradeARMIntrinsicCall(StringRef Name, CallBase *CI, Function *F,
                                      IRBuilder<> &Builder) {
  if (Name == "mve.vctp64.old") {
    // Replace the old v4i1 vctp64 with a v2i1 vctp and predicate-casts to the
    // correct type.
    Value *VCTP = Builder.CreateIntrinsic(Intrinsic::arm_mve_vctp64, {},
                                          CI->getArgOperand(0),
                                          /*FMFSource=*/nullptr, CI->getName());
    Value *C1 = Builder.CreateIntrinsic(
        Intrinsic::arm_mve_pred_v2i,
        {VectorType::get(Builder.getInt1Ty(), 2, false)}, VCTP);
    return Builder.CreateIntrinsic(
        Intrinsic::arm_mve_pred_i2v,
        {VectorType::get(Builder.getInt1Ty(), 4, false)}, C1);
  } else if (Name == "mve.mull.int.predicated.v2i64.v4i32.v4i1" ||
             Name == "mve.vqdmull.predicated.v2i64.v4i32.v4i1" ||
             Name == "mve.vldr.gather.base.predicated.v2i64.v2i64.v4i1" ||
             Name == "mve.vldr.gather.base.wb.predicated.v2i64.v2i64.v4i1" ||
             Name ==
                 "mve.vldr.gather.offset.predicated.v2i64.p0i64.v2i64.v4i1" ||
             Name == "mve.vldr.gather.offset.predicated.v2i64.p0.v2i64.v4i1" ||
             Name == "mve.vstr.scatter.base.predicated.v2i64.v2i64.v4i1" ||
             Name == "mve.vstr.scatter.base.wb.predicated.v2i64.v2i64.v4i1" ||
             Name ==
                 "mve.vstr.scatter.offset.predicated.p0i64.v2i64.v2i64.v4i1" ||
             Name == "mve.vstr.scatter.offset.predicated.p0.v2i64.v2i64.v4i1" ||
             Name == "cde.vcx1q.predicated.v2i64.v4i1" ||
             Name == "cde.vcx1qa.predicated.v2i64.v4i1" ||
             Name == "cde.vcx2q.predicated.v2i64.v4i1" ||
             Name == "cde.vcx2qa.predicated.v2i64.v4i1" ||
             Name == "cde.vcx3q.predicated.v2i64.v4i1" ||
             Name == "cde.vcx3qa.predicated.v2i64.v4i1") {
    std::vector<Type *> Tys;
    unsigned ID = CI->getIntrinsicID();
    Type *V2I1Ty = FixedVectorType::get(Builder.getInt1Ty(), 2);
    switch (ID) {
    case Intrinsic::arm_mve_mull_int_predicated:
    case Intrinsic::arm_mve_vqdmull_predicated:
    case Intrinsic::arm_mve_vldr_gather_base_predicated:
      Tys = {CI->getType(), CI->getOperand(0)->getType(), V2I1Ty};
      break;
    case Intrinsic::arm_mve_vldr_gather_base_wb_predicated:
    case Intrinsic::arm_mve_vstr_scatter_base_predicated:
    case Intrinsic::arm_mve_vstr_scatter_base_wb_predicated:
      Tys = {CI->getOperand(0)->getType(), CI->getOperand(0)->getType(),
             V2I1Ty};
      break;
    case Intrinsic::arm_mve_vldr_gather_offset_predicated:
      Tys = {CI->getType(), CI->getOperand(0)->getType(),
             CI->getOperand(1)->getType(), V2I1Ty};
      break;
    case Intrinsic::arm_mve_vstr_scatter_offset_predicated:
      Tys = {CI->getOperand(0)->getType(), CI->getOperand(1)->getType(),
             CI->getOperand(2)->getType(), V2I1Ty};
      break;
    case Intrinsic::arm_cde_vcx1q_predicated:
    case Intrinsic::arm_cde_vcx1qa_predicated:
    case Intrinsic::arm_cde_vcx2q_predicated:
    case Intrinsic::arm_cde_vcx2qa_predicated:
    case Intrinsic::arm_cde_vcx3q_predicated:
    case Intrinsic::arm_cde_vcx3qa_predicated:
      Tys = {CI->getOperand(1)->getType(), V2I1Ty};
      break;
    default:
      llvm_unreachable("Unhandled Intrinsic!");
    }

    std::vector<Value *> Ops;
    for (Value *Op : CI->args()) {
      Type *Ty = Op->getType();
      if (Ty->getScalarSizeInBits() == 1) {
        Value *C1 = Builder.CreateIntrinsic(
            Intrinsic::arm_mve_pred_v2i,
            {VectorType::get(Builder.getInt1Ty(), 4, false)}, Op);
        Op = Builder.CreateIntrinsic(Intrinsic::arm_mve_pred_i2v, {V2I1Ty}, C1);
      }
      Ops.push_back(Op);
    }

    return Builder.CreateIntrinsic(ID, Tys, Ops, /*FMFSource=*/nullptr,
                                   CI->getName());
  }
  llvm_unreachable("Unknown function for ARM CallBase upgrade.");
}

// These are expected to have the arguments:
// atomic.intrin (ptr, rmw_value, ordering, scope, isVolatile)
//
// Except for int_amdgcn_ds_fadd_v2bf16 which only has (ptr, rmw_value).
//
static Value *upgradeAMDGCNIntrinsicCall(StringRef Name, CallBase *CI,
                                         Function *F, IRBuilder<> &Builder) {
  // Legacy WMMA iu intrinsics missed the optional clamp operand. Append clamp=0
  // for compatibility.
  auto UpgradeLegacyWMMAIUIntrinsicCall =
      [](Function *F, CallBase *CI, IRBuilder<> &Builder,
         ArrayRef<Type *> OverloadTys) -> Value * {
    // Prepare arguments, append clamp=0 for compatibility
    SmallVector<Value *, 10> Args(CI->args().begin(), CI->args().end());
    Args.push_back(Builder.getFalse());

    // Insert the declaration for the right overload types
    Function *NewDecl = Intrinsic::getOrInsertDeclaration(
        F->getParent(), F->getIntrinsicID(), OverloadTys);

    // Copy operand bundles if any
    SmallVector<OperandBundleDef, 1> Bundles;
    CI->getOperandBundlesAsDefs(Bundles);

    // Create the new call and copy calling properties
    auto *NewCall = cast<CallInst>(Builder.CreateCall(NewDecl, Args, Bundles));
    NewCall->setTailCallKind(cast<CallInst>(CI)->getTailCallKind());
    NewCall->setCallingConv(CI->getCallingConv());
    NewCall->setAttributes(CI->getAttributes());
    NewCall->setDebugLoc(CI->getDebugLoc());
    NewCall->copyMetadata(*CI);
    return NewCall;
  };

  if (F->getIntrinsicID() == Intrinsic::amdgcn_wmma_i32_16x16x64_iu8) {
    assert(CI->arg_size() == 7 && "Legacy int_amdgcn_wmma_i32_16x16x64_iu8 "
                                  "intrinsic should have 7 arguments");
    Type *T1 = CI->getArgOperand(4)->getType();
    Type *T2 = CI->getArgOperand(1)->getType();
    return UpgradeLegacyWMMAIUIntrinsicCall(F, CI, Builder, {T1, T2});
  }
  if (F->getIntrinsicID() == Intrinsic::amdgcn_swmmac_i32_16x16x128_iu8) {
    assert(CI->arg_size() == 8 && "Legacy int_amdgcn_swmmac_i32_16x16x128_iu8 "
                                  "intrinsic should have 8 arguments");
    Type *T1 = CI->getArgOperand(4)->getType();
    Type *T2 = CI->getArgOperand(1)->getType();
    Type *T3 = CI->getArgOperand(3)->getType();
    Type *T4 = CI->getArgOperand(5)->getType();
    return UpgradeLegacyWMMAIUIntrinsicCall(F, CI, Builder, {T1, T2, T3, T4});
  }

  switch (F->getIntrinsicID()) {
  default:
    break;
  case Intrinsic::amdgcn_wmma_f32_16x16x4_f32:
  case Intrinsic::amdgcn_wmma_f32_16x16x32_bf16:
  case Intrinsic::amdgcn_wmma_f32_16x16x32_f16:
  case Intrinsic::amdgcn_wmma_f16_16x16x32_f16:
  case Intrinsic::amdgcn_wmma_bf16_16x16x32_bf16:
  case Intrinsic::amdgcn_wmma_bf16f32_16x16x32_bf16: {
    // Drop src0 and src1 modifiers.
    const Value *Op0 = CI->getArgOperand(0);
    const Value *Op2 = CI->getArgOperand(2);
    assert(Op0->getType()->isIntegerTy() && Op2->getType()->isIntegerTy());
    const ConstantInt *ModA = dyn_cast<ConstantInt>(Op0);
    const ConstantInt *ModB = dyn_cast<ConstantInt>(Op2);
    if (!ModA->isZero() || !ModB->isZero())
      reportFatalUsageError(Name + " matrix A and B modifiers shall be zero");

    SmallVector<Value *, 8> Args{CI->getArgOperand(1), CI->getArgOperand(3)};
    for (int I = 4, E = CI->arg_size(); I < E; ++I)
      Args.push_back(CI->getArgOperand(I));

    SmallVector<Type *, 3> Overloads{F->getReturnType(), Args[0]->getType()};
    if (F->getIntrinsicID() == Intrinsic::amdgcn_wmma_bf16f32_16x16x32_bf16)
      Overloads.push_back(Args[3]->getType());
    Function *NewDecl = Intrinsic::getOrInsertDeclaration(
        F->getParent(), F->getIntrinsicID(), Overloads);

    SmallVector<OperandBundleDef, 1> Bundles;
    CI->getOperandBundlesAsDefs(Bundles);

    auto *NewCall = cast<CallInst>(Builder.CreateCall(NewDecl, Args, Bundles));
    NewCall->setTailCallKind(cast<CallInst>(CI)->getTailCallKind());
    NewCall->setCallingConv(CI->getCallingConv());
    NewCall->setAttributes(CI->getAttributes());
    NewCall->setDebugLoc(CI->getDebugLoc());
    NewCall->copyMetadata(*CI);
    NewCall->takeName(CI);
    return NewCall;
  }
  }

  AtomicRMWInst::BinOp RMWOp =
      StringSwitch<AtomicRMWInst::BinOp>(Name)
          .StartsWith("ds.fadd", AtomicRMWInst::FAdd)
          .StartsWith("ds.fmin", AtomicRMWInst::FMin)
          .StartsWith("ds.fmax", AtomicRMWInst::FMax)
          .StartsWith("atomic.inc.", AtomicRMWInst::UIncWrap)
          .StartsWith("atomic.dec.", AtomicRMWInst::UDecWrap)
          .StartsWith("global.atomic.fadd", AtomicRMWInst::FAdd)
          .StartsWith("flat.atomic.fadd", AtomicRMWInst::FAdd)
          .StartsWith("global.atomic.fmin", AtomicRMWInst::FMin)
          .StartsWith("flat.atomic.fmin", AtomicRMWInst::FMin)
          .StartsWith("global.atomic.fmax", AtomicRMWInst::FMax)
          .StartsWith("flat.atomic.fmax", AtomicRMWInst::FMax)
          .StartsWith("atomic.cond.sub", AtomicRMWInst::USubCond)
          .StartsWith("atomic.csub", AtomicRMWInst::USubSat);

  unsigned NumOperands = CI->getNumOperands();
  if (NumOperands < 3) // Malformed bitcode.
    return nullptr;

  Value *Ptr = CI->getArgOperand(0);
  PointerType *PtrTy = dyn_cast<PointerType>(Ptr->getType());
  if (!PtrTy) // Malformed.
    return nullptr;

  Value *Val = CI->getArgOperand(1);
  if (Val->getType() != CI->getType()) // Malformed.
    return nullptr;

  ConstantInt *OrderArg = nullptr;
  bool IsVolatile = false;

  // These should have 5 arguments (plus the callee). A separate version of the
  // ds_fadd intrinsic was defined for bf16 which was missing arguments.
  if (NumOperands > 3)
    OrderArg = dyn_cast<ConstantInt>(CI->getArgOperand(2));

  // Ignore scope argument at 3

  if (NumOperands > 5) {
    ConstantInt *VolatileArg = dyn_cast<ConstantInt>(CI->getArgOperand(4));
    IsVolatile = !VolatileArg || !VolatileArg->isZero();
  }

  AtomicOrdering Order = AtomicOrdering::SequentiallyConsistent;
  if (OrderArg && isValidAtomicOrdering(OrderArg->getZExtValue()))
    Order = static_cast<AtomicOrdering>(OrderArg->getZExtValue());
  if (Order == AtomicOrdering::NotAtomic || Order == AtomicOrdering::Unordered)
    Order = AtomicOrdering::SequentiallyConsistent;

  LLVMContext &Ctx = F->getContext();

  // Handle the v2bf16 intrinsic which used <2 x i16> instead of <2 x bfloat>
  Type *RetTy = CI->getType();
  if (VectorType *VT = dyn_cast<VectorType>(RetTy)) {
    if (VT->getElementType()->isIntegerTy(16)) {
      VectorType *AsBF16 =
          VectorType::get(Type::getBFloatTy(Ctx), VT->getElementCount());
      Val = Builder.CreateBitCast(Val, AsBF16);
    }
  }

  // The scope argument never really worked correctly. Use agent as the most
  // conservative option which should still always produce the instruction.
  SyncScope::ID SSID = Ctx.getOrInsertSyncScopeID("agent");
  AtomicRMWInst *RMW =
      Builder.CreateAtomicRMW(RMWOp, Ptr, Val, std::nullopt, Order, SSID);

  unsigned AddrSpace = PtrTy->getAddressSpace();
  if (AddrSpace != AMDGPUAS::LOCAL_ADDRESS) {
    MDNode *EmptyMD = MDNode::get(F->getContext(), {});
    RMW->setMetadata("amdgpu.no.fine.grained.memory", EmptyMD);
    if (RMWOp == AtomicRMWInst::FAdd && RetTy->isFloatTy())
      RMW->setMetadata("amdgpu.ignore.denormal.mode", EmptyMD);
  }

  if (AddrSpace == AMDGPUAS::FLAT_ADDRESS) {
    MDBuilder MDB(F->getContext());
    MDNode *RangeNotPrivate =
        MDB.createRange(APInt(32, AMDGPUAS::PRIVATE_ADDRESS),
                        APInt(32, AMDGPUAS::PRIVATE_ADDRESS + 1));
    RMW->setMetadata(LLVMContext::MD_noalias_addrspace, RangeNotPrivate);
  }

  if (IsVolatile)
    RMW->setVolatile(true);

  return Builder.CreateBitCast(RMW, RetTy);
}

/// Helper to unwrap intrinsic call MetadataAsValue operands. Return as a
/// plain MDNode, as it's the verifier's job to check these are the correct
/// types later.
static MDNode *unwrapMAVOp(CallBase *CI, unsigned Op) {
  if (Op < CI->arg_size()) {
    if (MetadataAsValue *MAV =
            dyn_cast<MetadataAsValue>(CI->getArgOperand(Op))) {
      Metadata *MD = MAV->getMetadata();
      return dyn_cast_if_present<MDNode>(MD);
    }
  }
  return nullptr;
}

/// Helper to unwrap Metadata MetadataAsValue operands, such as the Value field.
static Metadata *unwrapMAVMetadataOp(CallBase *CI, unsigned Op) {
  if (Op < CI->arg_size())
    if (MetadataAsValue *MAV = dyn_cast<MetadataAsValue>(CI->getArgOperand(Op)))
      return MAV->getMetadata();
  return nullptr;
}

static MDNode *getDebugLocSafe(const Instruction *I) {
  // The MDNode attached to this instruction might not be the correct type,
  // as the verifier has not yet be run. Fetch it as a bare MDNode.
  return I->getDebugLoc().getAsMDNode();
}

/// Convert debug intrinsic calls to non-instruction debug records.
/// \p Name - Final part of the intrinsic name, e.g. 'value' in llvm.dbg.value.
/// \p CI - The debug intrinsic call.
static void upgradeDbgIntrinsicToDbgRecord(StringRef Name, CallBase *CI) {
  DbgRecord *DR = nullptr;
  if (Name == "label") {
    DR = DbgLabelRecord::createUnresolvedDbgLabelRecord(unwrapMAVOp(CI, 0),
                                                        CI->getDebugLoc());
  } else if (Name == "assign") {
    DR = DbgVariableRecord::createUnresolvedDbgVariableRecord(
        DbgVariableRecord::LocationType::Assign, unwrapMAVMetadataOp(CI, 0),
        unwrapMAVOp(CI, 1), unwrapMAVOp(CI, 2), unwrapMAVOp(CI, 3),
        unwrapMAVMetadataOp(CI, 4),
        /*The address is a Value ref, it will be stored as a Metadata */
        unwrapMAVOp(CI, 5), getDebugLocSafe(CI));
  } else if (Name == "declare") {
    DR = DbgVariableRecord::createUnresolvedDbgVariableRecord(
        DbgVariableRecord::LocationType::Declare, unwrapMAVMetadataOp(CI, 0),
        unwrapMAVOp(CI, 1), unwrapMAVOp(CI, 2), nullptr, nullptr, nullptr,
        getDebugLocSafe(CI));
  } else if (Name == "addr") {
    // Upgrade dbg.addr to dbg.value with DW_OP_deref.
    MDNode *ExprNode = unwrapMAVOp(CI, 2);
    // Don't try to add something to the expression if it's not an expression.
    // Instead, allow the verifier to fail later.
    if (DIExpression *Expr = dyn_cast<DIExpression>(ExprNode)) {
      ExprNode = DIExpression::append(Expr, dwarf::DW_OP_deref);
    }
    DR = DbgVariableRecord::createUnresolvedDbgVariableRecord(
        DbgVariableRecord::LocationType::Value, unwrapMAVMetadataOp(CI, 0),
        unwrapMAVOp(CI, 1), ExprNode, nullptr, nullptr, nullptr,
        getDebugLocSafe(CI));
  } else if (Name == "value") {
    // An old version of dbg.value had an extra offset argument.
    unsigned VarOp = 1;
    unsigned ExprOp = 2;
    if (CI->arg_size() == 4) {
      auto *Offset = dyn_cast_or_null<Constant>(CI->getArgOperand(1));
      // Nonzero offset dbg.values get dropped without a replacement.
      if (!Offset || !Offset->isNullValue())
        return;
      VarOp = 2;
      ExprOp = 3;
    }
    DR = DbgVariableRecord::createUnresolvedDbgVariableRecord(
        DbgVariableRecord::LocationType::Value, unwrapMAVMetadataOp(CI, 0),
        unwrapMAVOp(CI, VarOp), unwrapMAVOp(CI, ExprOp), nullptr, nullptr,
        nullptr, getDebugLocSafe(CI));
  }
  assert(DR && "Unhandled intrinsic kind in upgrade to DbgRecord");
  CI->getParent()->insertDbgRecordBefore(DR, CI->getIterator());
}

static Value *upgradeVectorSplice(CallBase *CI, IRBuilder<> &Builder) {
  auto *Offset = dyn_cast<ConstantInt>(CI->getArgOperand(2));
  if (!Offset)
    reportFatalUsageError("Invalid llvm.vector.splice offset argument");
  int64_t OffsetVal = Offset->getSExtValue();
  return Builder.CreateIntrinsic(OffsetVal >= 0
                                     ? Intrinsic::vector_splice_left
                                     : Intrinsic::vector_splice_right,
                                 CI->getType(),
                                 {CI->getArgOperand(0), CI->getArgOperand(1),
                                  Builder.getInt32(std::abs(OffsetVal))});
}

static Value *upgradeConvertIntrinsicCall(StringRef Name, CallBase *CI,
                                          Function *F, IRBuilder<> &Builder) {
  if (Name.starts_with("to.fp16")) {
    Value *Cast =
        Builder.CreateFPTrunc(CI->getArgOperand(0), Builder.getHalfTy());
    return Builder.CreateBitCast(Cast, CI->getType());
  }

  if (Name.starts_with("from.fp16")) {
    Value *Cast =
        Builder.CreateBitCast(CI->getArgOperand(0), Builder.getHalfTy());
    return Builder.CreateFPExt(Cast, CI->getType());
  }

  return nullptr;
}

/// Upgrade a call to an old intrinsic. All argument and return casting must be
/// provided to seamlessly integrate with existing context.
void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) {
  // Note dyn_cast to Function is not quite the same as getCalledFunction, which
  // checks the callee's function type matches. It's likely we need to handle
  // type changes here.
  Function *F = dyn_cast<Function>(CI->getCalledOperand());
  if (!F)
    return;

  LLVMContext &C = CI->getContext();
  IRBuilder<> Builder(C);
  if (isa<FPMathOperator>(CI))
    Builder.setFastMathFlags(CI->getFastMathFlags());
  Builder.SetInsertPoint(CI->getParent(), CI->getIterator());

  if (!NewFn) {
    // Get the Function's name.
    StringRef Name = F->getName();
    if (!Name.consume_front("llvm."))
      llvm_unreachable("intrinsic doesn't start with 'llvm.'");

    bool IsX86 = Name.consume_front("x86.");
    bool IsNVVM = Name.consume_front("nvvm.");
    bool IsAArch64 = Name.consume_front("aarch64.");
    bool IsARM = Name.consume_front("arm.");
    bool IsAMDGCN = Name.consume_front("amdgcn.");
    bool IsDbg = Name.consume_front("dbg.");
    bool IsOldSplice =
        (Name.consume_front("experimental.vector.splice") ||
         Name.consume_front("vector.splice")) &&
        !(Name.starts_with(".left") || Name.starts_with(".right"));
    Value *Rep = nullptr;

    if (!IsX86 && Name == "stackprotectorcheck") {
      Rep = nullptr;
    } else if (IsNVVM) {
      Rep = upgradeNVVMIntrinsicCall(Name, CI, F, Builder);
    } else if (IsX86) {
      Rep = upgradeX86IntrinsicCall(Name, CI, F, Builder);
    } else if (IsAArch64) {
      Rep = upgradeAArch64IntrinsicCall(Name, CI, F, Builder);
    } else if (IsARM) {
      Rep = upgradeARMIntrinsicCall(Name, CI, F, Builder);
    } else if (IsAMDGCN) {
      Rep = upgradeAMDGCNIntrinsicCall(Name, CI, F, Builder);
    } else if (IsDbg) {
      upgradeDbgIntrinsicToDbgRecord(Name, CI);
    } else if (IsOldSplice) {
      Rep = upgradeVectorSplice(CI, Builder);
    } else if (Name.consume_front("convert.")) {
      Rep = upgradeConvertIntrinsicCall(Name, CI, F, Builder);
    } else {
      llvm_unreachable("Unknown function for CallBase upgrade.");
    }

    if (Rep)
      CI->replaceAllUsesWith(Rep);
    CI->eraseFromParent();
    return;
  }

  const auto &DefaultCase = [&]() -> void {
    if (F == NewFn)
      return;

    if (CI->getFunctionType() == NewFn->getFunctionType()) {
      // Handle generic mangling change.
      assert(
          (CI->getCalledFunction()->getName() != NewFn->getName()) &&
          "Unknown function for CallBase upgrade and isn't just a name change");
      CI->setCalledFunction(NewFn);
      return;
    }

    // This must be an upgrade from a named to a literal struct.
    if (auto *OldST = dyn_cast<StructType>(CI->getType())) {
      assert(OldST != NewFn->getReturnType() &&
             "Return type must have changed");
      assert(OldST->getNumElements() ==
                 cast<StructType>(NewFn->getReturnType())->getNumElements() &&
             "Must have same number of elements");

      SmallVector<Value *> Args(CI->args());
      CallInst *NewCI = Builder.CreateCall(NewFn, Args);
      NewCI->setAttributes(CI->getAttributes());
      Value *Res = PoisonValue::get(OldST);
      for (unsigned Idx = 0; Idx < OldST->getNumElements(); ++Idx) {
        Value *Elem = Builder.CreateExtractValue(NewCI, Idx);
        Res = Builder.CreateInsertValue(Res, Elem, Idx);
      }
      CI->replaceAllUsesWith(Res);
      CI->eraseFromParent();
      return;
    }

    // We're probably about to produce something invalid. Let the verifier catch
    // it instead of dying here.
    CI->setCalledOperand(
        ConstantExpr::getPointerCast(NewFn, CI->getCalledOperand()->getType()));
    return;
  };
  CallInst *NewCall = nullptr;
  switch (NewFn->getIntrinsicID()) {
  default: {
    DefaultCase();
    return;
  }
  case Intrinsic::arm_neon_vst1:
  case Intrinsic::arm_neon_vst2:
  case Intrinsic::arm_neon_vst3:
  case Intrinsic::arm_neon_vst4:
  case Intrinsic::arm_neon_vst2lane:
  case Intrinsic::arm_neon_vst3lane:
  case Intrinsic::arm_neon_vst4lane: {
    SmallVector<Value *, 4> Args(CI->args());
    NewCall = Builder.CreateCall(NewFn, Args);
    break;
  }
  case Intrinsic::aarch64_sve_bfmlalb_lane_v2:
  case Intrinsic::aarch64_sve_bfmlalt_lane_v2:
  case Intrinsic::aarch64_sve_bfdot_lane_v2: {
    LLVMContext &Ctx = F->getParent()->getContext();
    SmallVector<Value *, 4> Args(CI->args());
    Args[3] = ConstantInt::get(Type::getInt32Ty(Ctx),
                               cast<ConstantInt>(Args[3])->getZExtValue());
    NewCall = Builder.CreateCall(NewFn, Args);
    break;
  }
  case Intrinsic::aarch64_sve_ld3_sret:
  case Intrinsic::aarch64_sve_ld4_sret:
  case Intrinsic::aarch64_sve_ld2_sret: {
    // Is this a trivial remangle of the name to support ptr address spaces?
    if (isa<StructType>(F->getReturnType())) {
      DefaultCase();
      return;
    }

    StringRef Name = F->getName();
    Name = Name.substr(5);
    unsigned N = StringSwitch<unsigned>(Name)
                     .StartsWith("aarch64.sve.ld2", 2)
                     .StartsWith("aarch64.sve.ld3", 3)
                     .StartsWith("aarch64.sve.ld4", 4)
                     .Default(0);
    auto *RetTy = cast<ScalableVectorType>(F->getReturnType());
    unsigned MinElts = RetTy->getMinNumElements() / N;
    SmallVector<Value *, 2> Args(CI->args());
    Value *NewLdCall = Builder.CreateCall(NewFn, Args);
    Value *Ret = llvm::PoisonValue::get(RetTy);
    for (unsigned I = 0; I < N; I++) {
      Value *SRet = Builder.CreateExtractValue(NewLdCall, I);
      Ret = Builder.CreateInsertVector(RetTy, Ret, SRet, I * MinElts);
    }
    NewCall = dyn_cast<CallInst>(Ret);
    break;
  }

  case Intrinsic::coro_end: {
    SmallVector<Value *, 3> Args(CI->args());
    Args.push_back(ConstantTokenNone::get(CI->getContext()));
    NewCall = Builder.CreateCall(NewFn, Args);
    break;
  }

  case Intrinsic::vector_extract: {
    StringRef Name = F->getName();
    Name = Name.substr(5); // Strip llvm
    if (!Name.starts_with("aarch64.sve.tuple.get")) {
      DefaultCase();
      return;
    }
    auto *RetTy = cast<ScalableVectorType>(F->getReturnType());
    unsigned MinElts = RetTy->getMinNumElements();
    unsigned I = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
    Value *NewIdx = ConstantInt::get(Type::getInt64Ty(C), I * MinElts);
    NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0), NewIdx});
    break;
  }

  case Intrinsic::vector_insert: {
    StringRef Name = F->getName();
    Name = Name.substr(5);
    if (!Name.starts_with("aarch64.sve.tuple")) {
      DefaultCase();
      return;
    }
    if (Name.starts_with("aarch64.sve.tuple.set")) {
      unsigned I = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
      auto *Ty = cast<ScalableVectorType>(CI->getArgOperand(2)->getType());
      Value *NewIdx =
          ConstantInt::get(Type::getInt64Ty(C), I * Ty->getMinNumElements());
      NewCall = Builder.CreateCall(
          NewFn, {CI->getArgOperand(0), CI->getArgOperand(2), NewIdx});
      break;
    }
    if (Name.starts_with("aarch64.sve.tuple.create")) {
      unsigned N = StringSwitch<unsigned>(Name)
                       .StartsWith("aarch64.sve.tuple.create2", 2)
                       .StartsWith("aarch64.sve.tuple.create3", 3)
                       .StartsWith("aarch64.sve.tuple.create4", 4)
                       .Default(0);
      assert(N > 1 && "Create is expected to be between 2-4");
      auto *RetTy = cast<ScalableVectorType>(F->getReturnType());
      Value *Ret = llvm::PoisonValue::get(RetTy);
      unsigned MinElts = RetTy->getMinNumElements() / N;
      for (unsigned I = 0; I < N; I++) {
        Value *V = CI->getArgOperand(I);
        Ret = Builder.CreateInsertVector(RetTy, Ret, V, I * MinElts);
      }
      NewCall = dyn_cast<CallInst>(Ret);
    }
    break;
  }

  case Intrinsic::arm_neon_bfdot:
  case Intrinsic::arm_neon_bfmmla:
  case Intrinsic::arm_neon_bfmlalb:
  case Intrinsic::arm_neon_bfmlalt:
  case Intrinsic::aarch64_neon_bfdot:
  case Intrinsic::aarch64_neon_bfmmla:
  case Intrinsic::aarch64_neon_bfmlalb:
  case Intrinsic::aarch64_neon_bfmlalt: {
    SmallVector<Value *, 3> Args;
    assert(CI->arg_size() == 3 &&
           "Mismatch between function args and call args");
    size_t OperandWidth =
        CI->getArgOperand(1)->getType()->getPrimitiveSizeInBits();
    assert((OperandWidth == 64 || OperandWidth == 128) &&
           "Unexpected operand width");
    Type *NewTy = FixedVectorType::get(Type::getBFloatTy(C), OperandWidth / 16);
    auto Iter = CI->args().begin();
    Args.push_back(*Iter++);
    Args.push_back(Builder.CreateBitCast(*Iter++, NewTy));
    Args.push_back(Builder.CreateBitCast(*Iter++, NewTy));
    NewCall = Builder.CreateCall(NewFn, Args);
    break;
  }

  case Intrinsic::bitreverse:
    NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0)});
    break;

  case Intrinsic::ctlz:
  case Intrinsic::cttz: {
    if (CI->arg_size() != 1) {
      DefaultCase();
      return;
    }

    NewCall =
        Builder.CreateCall(NewFn, {CI->getArgOperand(0), Builder.getFalse()});
    break;
  }

  case Intrinsic::objectsize: {
    Value *NullIsUnknownSize =
        CI->arg_size() == 2 ? Builder.getFalse() : CI->getArgOperand(2);
    Value *Dynamic =
        CI->arg_size() < 4 ? Builder.getFalse() : CI->getArgOperand(3);
    NewCall = Builder.CreateCall(
        NewFn, {CI->getArgOperand(0), CI->getArgOperand(1), NullIsUnknownSize, Dynamic});
    break;
  }

  case Intrinsic::ctpop:
    NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0)});
    break;
  case Intrinsic::dbg_value: {
    StringRef Name = F->getName();
    Name = Name.substr(5); // Strip llvm.
    // Upgrade `dbg.addr` to `dbg.value` with `DW_OP_deref`.
    if (Name.starts_with("dbg.addr")) {
      DIExpression *Expr = cast<DIExpression>(
          cast<MetadataAsValue>(CI->getArgOperand(2))->getMetadata());
      Expr = DIExpression::append(Expr, dwarf::DW_OP_deref);
      NewCall =
          Builder.CreateCall(NewFn, {CI->getArgOperand(0), CI->getArgOperand(1),
                                     MetadataAsValue::get(C, Expr)});
      break;
    }

    // Upgrade from the old version that had an extra offset argument.
    assert(CI->arg_size() == 4);
    // Drop nonzero offsets instead of attempting to upgrade them.
    if (auto *Offset = dyn_cast_or_null<Constant>(CI->getArgOperand(1)))
      if (Offset->isNullValue()) {
        NewCall = Builder.CreateCall(
            NewFn,
            {CI->getArgOperand(0), CI->getArgOperand(2), CI->getArgOperand(3)});
        break;
      }
    CI->eraseFromParent();
    return;
  }

  case Intrinsic::ptr_annotation:
    // Upgrade from versions that lacked the annotation attribute argument.
    if (CI->arg_size() != 4) {
      DefaultCase();
      return;
    }

    // Create a new call with an added null annotation attribute argument.
    NewCall = Builder.CreateCall(
        NewFn,
        {CI->getArgOperand(0), CI->getArgOperand(1), CI->getArgOperand(2),
         CI->getArgOperand(3), ConstantPointerNull::get(Builder.getPtrTy())});
    NewCall->takeName(CI);
    CI->replaceAllUsesWith(NewCall);
    CI->eraseFromParent();
    return;

  case Intrinsic::var_annotation:
    // Upgrade from versions that lacked the annotation attribute argument.
    if (CI->arg_size() != 4) {
      DefaultCase();
      return;
    }
    // Create a new call with an added null annotation attribute argument.
    NewCall = Builder.CreateCall(
        NewFn,
        {CI->getArgOperand(0), CI->getArgOperand(1), CI->getArgOperand(2),
         CI->getArgOperand(3), ConstantPointerNull::get(Builder.getPtrTy())});
    NewCall->takeName(CI);
    CI->replaceAllUsesWith(NewCall);
    CI->eraseFromParent();
    return;

  case Intrinsic::riscv_aes32dsi:
  case Intrinsic::riscv_aes32dsmi:
  case Intrinsic::riscv_aes32esi:
  case Intrinsic::riscv_aes32esmi:
  case Intrinsic::riscv_sm4ks:
  case Intrinsic::riscv_sm4ed: {
    // The last argument to these intrinsics used to be i8 and changed to i32.
    // The type overload for sm4ks and sm4ed was removed.
    Value *Arg2 = CI->getArgOperand(2);
    if (Arg2->getType()->isIntegerTy(32) && !CI->getType()->isIntegerTy(64))
      return;

    Value *Arg0 = CI->getArgOperand(0);
    Value *Arg1 = CI->getArgOperand(1);
    if (CI->getType()->isIntegerTy(64)) {
      Arg0 = Builder.CreateTrunc(Arg0, Builder.getInt32Ty());
      Arg1 = Builder.CreateTrunc(Arg1, Builder.getInt32Ty());
    }

    Arg2 = ConstantInt::get(Type::getInt32Ty(C),
                            cast<ConstantInt>(Arg2)->getZExtValue());

    NewCall = Builder.CreateCall(NewFn, {Arg0, Arg1, Arg2});
    Value *Res = NewCall;
    if (Res->getType() != CI->getType())
      Res = Builder.CreateIntCast(NewCall, CI->getType(), /*isSigned*/ true);
    NewCall->takeName(CI);
    CI->replaceAllUsesWith(Res);
    CI->eraseFromParent();
    return;
  }
  case Intrinsic::nvvm_mapa_shared_cluster: {
    // Create a new call with the correct address space.
    NewCall =
        Builder.CreateCall(NewFn, {CI->getArgOperand(0), CI->getArgOperand(1)});
    Value *Res = NewCall;
    Res = Builder.CreateAddrSpaceCast(
        Res, Builder.getPtrTy(NVPTXAS::ADDRESS_SPACE_SHARED));
    NewCall->takeName(CI);
    CI->replaceAllUsesWith(Res);
    CI->eraseFromParent();
    return;
  }
  case Intrinsic::nvvm_cp_async_bulk_global_to_shared_cluster:
  case Intrinsic::nvvm_cp_async_bulk_shared_cta_to_cluster: {
    // Create a new call with the correct address space.
    SmallVector<Value *, 4> Args(CI->args());
    Args[0] = Builder.CreateAddrSpaceCast(
        Args[0], Builder.getPtrTy(NVPTXAS::ADDRESS_SPACE_SHARED_CLUSTER));

    NewCall = Builder.CreateCall(NewFn, Args);
    NewCall->takeName(CI);
    CI->replaceAllUsesWith(NewCall);
    CI->eraseFromParent();
    return;
  }
  case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_3d:
  case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_4d:
  case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_5d:
  case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_1d:
  case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_2d:
  case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_3d:
  case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_4d:
  case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_5d: {
    SmallVector<Value *, 16> Args(CI->args());

    // Create AddrSpaceCast to shared_cluster if needed.
    // This handles case (1) in shouldUpgradeNVPTXTMAG2SIntrinsics().
    unsigned AS = CI->getArgOperand(0)->getType()->getPointerAddressSpace();
    if (AS == NVPTXAS::ADDRESS_SPACE_SHARED)
      Args[0] = Builder.CreateAddrSpaceCast(
          Args[0], Builder.getPtrTy(NVPTXAS::ADDRESS_SPACE_SHARED_CLUSTER));

    // Attach the flag argument for cta_group, with a
    // default value of 0. This handles case (2) in
    // shouldUpgradeNVPTXTMAG2SIntrinsics().
    size_t NumArgs = CI->arg_size();
    Value *FlagArg = CI->getArgOperand(NumArgs - 3);
    if (!FlagArg->getType()->isIntegerTy(1))
      Args.push_back(ConstantInt::get(Builder.getInt32Ty(), 0));

    NewCall = Builder.CreateCall(NewFn, Args);
    NewCall->takeName(CI);
    CI->replaceAllUsesWith(NewCall);
    CI->eraseFromParent();
    return;
  }
  case Intrinsic::riscv_sha256sig0:
  case Intrinsic::riscv_sha256sig1:
  case Intrinsic::riscv_sha256sum0:
  case Intrinsic::riscv_sha256sum1:
  case Intrinsic::riscv_sm3p0:
  case Intrinsic::riscv_sm3p1: {
    // The last argument to these intrinsics used to be i8 and changed to i32.
    // The type overload for sm4ks and sm4ed was removed.
    if (!CI->getType()->isIntegerTy(64))
      return;

    Value *Arg =
        Builder.CreateTrunc(CI->getArgOperand(0), Builder.getInt32Ty());

    NewCall = Builder.CreateCall(NewFn, Arg);
    Value *Res =
        Builder.CreateIntCast(NewCall, CI->getType(), /*isSigned*/ true);
    NewCall->takeName(CI);
    CI->replaceAllUsesWith(Res);
    CI->eraseFromParent();
    return;
  }

  case Intrinsic::x86_xop_vfrcz_ss:
  case Intrinsic::x86_xop_vfrcz_sd:
    NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(1)});
    break;

  case Intrinsic::x86_xop_vpermil2pd:
  case Intrinsic::x86_xop_vpermil2ps:
  case Intrinsic::x86_xop_vpermil2pd_256:
  case Intrinsic::x86_xop_vpermil2ps_256: {
    SmallVector<Value *, 4> Args(CI->args());
    VectorType *FltIdxTy = cast<VectorType>(Args[2]->getType());
    VectorType *IntIdxTy = VectorType::getInteger(FltIdxTy);
    Args[2] = Builder.CreateBitCast(Args[2], IntIdxTy);
    NewCall = Builder.CreateCall(NewFn, Args);
    break;
  }

  case Intrinsic::x86_sse41_ptestc:
  case Intrinsic::x86_sse41_ptestz:
  case Intrinsic::x86_sse41_ptestnzc: {
    // The arguments for these intrinsics used to be v4f32, and changed
    // to v2i64. This is purely a nop, since those are bitwise intrinsics.
    // So, the only thing required is a bitcast for both arguments.
    // First, check the arguments have the old type.
    Value *Arg0 = CI->getArgOperand(0);
    if (Arg0->getType() != FixedVectorType::get(Type::getFloatTy(C), 4))
      return;

    // Old intrinsic, add bitcasts
    Value *Arg1 = CI->getArgOperand(1);

    auto *NewVecTy = FixedVectorType::get(Type::getInt64Ty(C), 2);

    Value *BC0 = Builder.CreateBitCast(Arg0, NewVecTy, "cast");
    Value *BC1 = Builder.CreateBitCast(Arg1, NewVecTy, "cast");

    NewCall = Builder.CreateCall(NewFn, {BC0, BC1});
    break;
  }

  case Intrinsic::x86_rdtscp: {
    // This used to take 1 arguments. If we have no arguments, it is already
    // upgraded.
    if (CI->getNumOperands() == 0)
      return;

    NewCall = Builder.CreateCall(NewFn);
    // Extract the second result and store it.
    Value *Data = Builder.CreateExtractValue(NewCall, 1);
    Builder.CreateAlignedStore(Data, CI->getArgOperand(0), Align(1));
    // Replace the original call result with the first result of the new call.
    Value *TSC = Builder.CreateExtractValue(NewCall, 0);

    NewCall->takeName(CI);
    CI->replaceAllUsesWith(TSC);
    CI->eraseFromParent();
    return;
  }

  case Intrinsic::x86_sse41_insertps:
  case Intrinsic::x86_sse41_dppd:
  case Intrinsic::x86_sse41_dpps:
  case Intrinsic::x86_sse41_mpsadbw:
  case Intrinsic::x86_avx_dp_ps_256:
  case Intrinsic::x86_avx2_mpsadbw: {
    // Need to truncate the last argument from i32 to i8 -- this argument models
    // an inherently 8-bit immediate operand to these x86 instructions.
    SmallVector<Value *, 4> Args(CI->args());

    // Replace the last argument with a trunc.
    Args.back() = Builder.CreateTrunc(Args.back(), Type::getInt8Ty(C), "trunc");
    NewCall = Builder.CreateCall(NewFn, Args);
    break;
  }

  case Intrinsic::x86_avx512_mask_cmp_pd_128:
  case Intrinsic::x86_avx512_mask_cmp_pd_256:
  case Intrinsic::x86_avx512_mask_cmp_pd_512:
  case Intrinsic::x86_avx512_mask_cmp_ps_128:
  case Intrinsic::x86_avx512_mask_cmp_ps_256:
  case Intrinsic::x86_avx512_mask_cmp_ps_512: {
    SmallVector<Value *, 4> Args(CI->args());
    unsigned NumElts =
        cast<FixedVectorType>(Args[0]->getType())->getNumElements();
    Args[3] = getX86MaskVec(Builder, Args[3], NumElts);

    NewCall = Builder.CreateCall(NewFn, Args);
    Value *Res = applyX86MaskOn1BitsVec(Builder, NewCall, nullptr);

    NewCall->takeName(CI);
    CI->replaceAllUsesWith(Res);
    CI->eraseFromParent();
    return;
  }

  case Intrinsic::x86_avx512bf16_cvtne2ps2bf16_128:
  case Intrinsic::x86_avx512bf16_cvtne2ps2bf16_256:
  case Intrinsic::x86_avx512bf16_cvtne2ps2bf16_512:
  case Intrinsic::x86_avx512bf16_mask_cvtneps2bf16_128:
  case Intrinsic::x86_avx512bf16_cvtneps2bf16_256:
  case Intrinsic::x86_avx512bf16_cvtneps2bf16_512: {
    SmallVector<Value *, 4> Args(CI->args());
    unsigned NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();
    if (NewFn->getIntrinsicID() ==
        Intrinsic::x86_avx512bf16_mask_cvtneps2bf16_128)
      Args[1] = Builder.CreateBitCast(
          Args[1], FixedVectorType::get(Builder.getBFloatTy(), NumElts));

    NewCall = Builder.CreateCall(NewFn, Args);
    Value *Res = Builder.CreateBitCast(
        NewCall, FixedVectorType::get(Builder.getInt16Ty(), NumElts));

    NewCall->takeName(CI);
    CI->replaceAllUsesWith(Res);
    CI->eraseFromParent();
    return;
  }
  case Intrinsic::x86_avx512bf16_dpbf16ps_128:
  case Intrinsic::x86_avx512bf16_dpbf16ps_256:
  case Intrinsic::x86_avx512bf16_dpbf16ps_512:{
    SmallVector<Value *, 4> Args(CI->args());
    unsigned NumElts =
        cast<FixedVectorType>(CI->getType())->getNumElements() * 2;
    Args[1] = Builder.CreateBitCast(
        Args[1], FixedVectorType::get(Builder.getBFloatTy(), NumElts));
    Args[2] = Builder.CreateBitCast(
        Args[2], FixedVectorType::get(Builder.getBFloatTy(), NumElts));

    NewCall = Builder.CreateCall(NewFn, Args);
    break;
  }

  case Intrinsic::thread_pointer: {
    NewCall = Builder.CreateCall(NewFn, {});
    break;
  }

  case Intrinsic::memcpy:
  case Intrinsic::memmove:
  case Intrinsic::memset: {
    // We have to make sure that the call signature is what we're expecting.
    // We only want to change the old signatures by removing the alignment arg:
    //  @llvm.mem[cpy|move]...(i8*, i8*, i[32|i64], i32, i1)
    //    -> @llvm.mem[cpy|move]...(i8*, i8*, i[32|i64], i1)
    //  @llvm.memset...(i8*, i8, i[32|64], i32, i1)
    //    -> @llvm.memset...(i8*, i8, i[32|64], i1)
    // Note: i8*'s in the above can be any pointer type
    if (CI->arg_size() != 5) {
      DefaultCase();
      return;
    }
    // Remove alignment argument (3), and add alignment attributes to the
    // dest/src pointers.
    Value *Args[4] = {CI->getArgOperand(0), CI->getArgOperand(1),
                      CI->getArgOperand(2), CI->getArgOperand(4)};
    NewCall = Builder.CreateCall(NewFn, Args);
    AttributeList OldAttrs = CI->getAttributes();
    AttributeList NewAttrs = AttributeList::get(
        C, OldAttrs.getFnAttrs(), OldAttrs.getRetAttrs(),
        {OldAttrs.getParamAttrs(0), OldAttrs.getParamAttrs(1),
         OldAttrs.getParamAttrs(2), OldAttrs.getParamAttrs(4)});
    NewCall->setAttributes(NewAttrs);
    auto *MemCI = cast<MemIntrinsic>(NewCall);
    // All mem intrinsics support dest alignment.
    const ConstantInt *Align = cast<ConstantInt>(CI->getArgOperand(3));
    MemCI->setDestAlignment(Align->getMaybeAlignValue());
    // Memcpy/Memmove also support source alignment.
    if (auto *MTI = dyn_cast<MemTransferInst>(MemCI))
      MTI->setSourceAlignment(Align->getMaybeAlignValue());
    break;
  }

  case Intrinsic::masked_load:
  case Intrinsic::masked_gather:
  case Intrinsic::masked_store:
  case Intrinsic::masked_scatter: {
    if (CI->arg_size() != 4) {
      DefaultCase();
      return;
    }

    auto GetMaybeAlign = [](Value *Op) {
      if (auto *CI = dyn_cast<ConstantInt>(Op)) {
        uint64_t Val = CI->getZExtValue();
        if (Val == 0)
          return MaybeAlign();
        if (isPowerOf2_64(Val))
          return MaybeAlign(Val);
      }
      reportFatalUsageError("Invalid alignment argument");
    };
    auto GetAlign = [&](Value *Op) {
      MaybeAlign Align = GetMaybeAlign(Op);
      if (Align)
        return *Align;
      reportFatalUsageError("Invalid zero alignment argument");
    };

    const DataLayout &DL = CI->getDataLayout();
    switch (NewFn->getIntrinsicID()) {
    case Intrinsic::masked_load:
      NewCall = Builder.CreateMaskedLoad(
          CI->getType(), CI->getArgOperand(0), GetAlign(CI->getArgOperand(1)),
          CI->getArgOperand(2), CI->getArgOperand(3));
      break;
    case Intrinsic::masked_gather:
      NewCall = Builder.CreateMaskedGather(
          CI->getType(), CI->getArgOperand(0),
          DL.getValueOrABITypeAlignment(GetMaybeAlign(CI->getArgOperand(1)),
                                        CI->getType()->getScalarType()),
          CI->getArgOperand(2), CI->getArgOperand(3));
      break;
    case Intrinsic::masked_store:
      NewCall = Builder.CreateMaskedStore(
          CI->getArgOperand(0), CI->getArgOperand(1),
          GetAlign(CI->getArgOperand(2)), CI->getArgOperand(3));
      break;
    case Intrinsic::masked_scatter:
      NewCall = Builder.CreateMaskedScatter(
          CI->getArgOperand(0), CI->getArgOperand(1),
          DL.getValueOrABITypeAlignment(
              GetMaybeAlign(CI->getArgOperand(2)),
              CI->getArgOperand(0)->getType()->getScalarType()),
          CI->getArgOperand(3));
      break;
    default:
      llvm_unreachable("Unexpected intrinsic ID");
    }
    // Previous metadata is still valid.
    NewCall->copyMetadata(*CI);
    NewCall->setTailCallKind(cast<CallInst>(CI)->getTailCallKind());
    break;
  }

  case Intrinsic::lifetime_start:
  case Intrinsic::lifetime_end: {
    if (CI->arg_size() != 2) {
      DefaultCase();
      return;
    }

    Value *Ptr = CI->getArgOperand(1);
    // Try to strip pointer casts, such that the lifetime works on an alloca.
    Ptr = Ptr->stripPointerCasts();
    if (isa<AllocaInst>(Ptr)) {
      // Don't use NewFn, as we might have looked through an addrspacecast.
      if (NewFn->getIntrinsicID() == Intrinsic::lifetime_start)
        NewCall = Builder.CreateLifetimeStart(Ptr);
      else
        NewCall = Builder.CreateLifetimeEnd(Ptr);
      break;
    }

    // Otherwise remove the lifetime marker.
    CI->eraseFromParent();
    return;
  }

  case Intrinsic::x86_avx512_vpdpbusd_128:
  case Intrinsic::x86_avx512_vpdpbusd_256:
  case Intrinsic::x86_avx512_vpdpbusd_512:
  case Intrinsic::x86_avx512_vpdpbusds_128:
  case Intrinsic::x86_avx512_vpdpbusds_256:
  case Intrinsic::x86_avx512_vpdpbusds_512:
  case Intrinsic::x86_avx2_vpdpbssd_128:
  case Intrinsic::x86_avx2_vpdpbssd_256:
  case Intrinsic::x86_avx10_vpdpbssd_512:
  case Intrinsic::x86_avx2_vpdpbssds_128:
  case Intrinsic::x86_avx2_vpdpbssds_256:
  case Intrinsic::x86_avx10_vpdpbssds_512:
  case Intrinsic::x86_avx2_vpdpbsud_128:
  case Intrinsic::x86_avx2_vpdpbsud_256:
  case Intrinsic::x86_avx10_vpdpbsud_512:
  case Intrinsic::x86_avx2_vpdpbsuds_128:
  case Intrinsic::x86_avx2_vpdpbsuds_256:
  case Intrinsic::x86_avx10_vpdpbsuds_512:
  case Intrinsic::x86_avx2_vpdpbuud_128:
  case Intrinsic::x86_avx2_vpdpbuud_256:
  case Intrinsic::x86_avx10_vpdpbuud_512:
  case Intrinsic::x86_avx2_vpdpbuuds_128:
  case Intrinsic::x86_avx2_vpdpbuuds_256:
  case Intrinsic::x86_avx10_vpdpbuuds_512: {
    unsigned NumElts = CI->getType()->getPrimitiveSizeInBits() / 8;
    Value *Args[] = {CI->getArgOperand(0), CI->getArgOperand(1),
                     CI->getArgOperand(2)};
    Type *NewArgType = VectorType::get(Builder.getInt8Ty(), NumElts, false);
    Args[1] = Builder.CreateBitCast(Args[1], NewArgType);
    Args[2] = Builder.CreateBitCast(Args[2], NewArgType);

    NewCall = Builder.CreateCall(NewFn, Args);
    break;
  }
  case Intrinsic::x86_avx512_vpdpwssd_128:
  case Intrinsic::x86_avx512_vpdpwssd_256:
  case Intrinsic::x86_avx512_vpdpwssd_512:
  case Intrinsic::x86_avx512_vpdpwssds_128:
  case Intrinsic::x86_avx512_vpdpwssds_256:
  case Intrinsic::x86_avx512_vpdpwssds_512:
  case Intrinsic::x86_avx2_vpdpwsud_128:
  case Intrinsic::x86_avx2_vpdpwsud_256:
  case Intrinsic::x86_avx10_vpdpwsud_512:
  case Intrinsic::x86_avx2_vpdpwsuds_128:
  case Intrinsic::x86_avx2_vpdpwsuds_256:
  case Intrinsic::x86_avx10_vpdpwsuds_512:
  case Intrinsic::x86_avx2_vpdpwusd_128:
  case Intrinsic::x86_avx2_vpdpwusd_256:
  case Intrinsic::x86_avx10_vpdpwusd_512:
  case Intrinsic::x86_avx2_vpdpwusds_128:
  case Intrinsic::x86_avx2_vpdpwusds_256:
  case Intrinsic::x86_avx10_vpdpwusds_512:
  case Intrinsic::x86_avx2_vpdpwuud_128:
  case Intrinsic::x86_avx2_vpdpwuud_256:
  case Intrinsic::x86_avx10_vpdpwuud_512:
  case Intrinsic::x86_avx2_vpdpwuuds_128:
  case Intrinsic::x86_avx2_vpdpwuuds_256:
  case Intrinsic::x86_avx10_vpdpwuuds_512:
    unsigned NumElts = CI->getType()->getPrimitiveSizeInBits() / 16;
    Value *Args[] = {CI->getArgOperand(0), CI->getArgOperand(1),
                     CI->getArgOperand(2)};
    Type *NewArgType = VectorType::get(Builder.getInt16Ty(), NumElts, false);
    Args[1] = Builder.CreateBitCast(Args[1], NewArgType);
    Args[2] = Builder.CreateBitCast(Args[2], NewArgType);

    NewCall = Builder.CreateCall(NewFn, Args);
    break;
  }
  assert(NewCall && "Should have either set this variable or returned through "
                    "the default case");
  NewCall->takeName(CI);
  CI->replaceAllUsesWith(NewCall);
  CI->eraseFromParent();
}

void llvm::UpgradeCallsToIntrinsic(Function *F) {
  assert(F && "Illegal attempt to upgrade a non-existent intrinsic.");

  // Check if this function should be upgraded and get the replacement function
  // if there is one.
  Function *NewFn;
  if (UpgradeIntrinsicFunction(F, NewFn)) {
    // Replace all users of the old function with the new function or new
    // instructions. This is not a range loop because the call is deleted.
    for (User *U : make_early_inc_range(F->users()))
      if (CallBase *CB = dyn_cast<CallBase>(U))
        UpgradeIntrinsicCall(CB, NewFn);

    // Remove old function, no longer used, from the module.
    if (F != NewFn)
      F->eraseFromParent();
  }
}

MDNode *llvm::UpgradeTBAANode(MDNode &MD) {
  const unsigned NumOperands = MD.getNumOperands();
  if (NumOperands == 0)
    return &MD; // Invalid, punt to a verifier error.

  // Check if the tag uses struct-path aware TBAA format.
  if (isa<MDNode>(MD.getOperand(0)) && NumOperands >= 3)
    return &MD;

  auto &Context = MD.getContext();
  if (NumOperands == 3) {
    Metadata *Elts[] = {MD.getOperand(0), MD.getOperand(1)};
    MDNode *ScalarType = MDNode::get(Context, Elts);
    // Create a MDNode <ScalarType, ScalarType, offset 0, const>
    Metadata *Elts2[] = {ScalarType, ScalarType,
                         ConstantAsMetadata::get(
                             Constant::getNullValue(Type::getInt64Ty(Context))),
                         MD.getOperand(2)};
    return MDNode::get(Context, Elts2);
  }
  // Create a MDNode <MD, MD, offset 0>
  Metadata *Elts[] = {&MD, &MD, ConstantAsMetadata::get(Constant::getNullValue(
                                    Type::getInt64Ty(Context)))};
  return MDNode::get(Context, Elts);
}

Instruction *llvm::UpgradeBitCastInst(unsigned Opc, Value *V, Type *DestTy,
                                      Instruction *&Temp) {
  if (Opc != Instruction::BitCast)
    return nullptr;

  Temp = nullptr;
  Type *SrcTy = V->getType();
  if (SrcTy->isPtrOrPtrVectorTy() && DestTy->isPtrOrPtrVectorTy() &&
      SrcTy->getPointerAddressSpace() != DestTy->getPointerAddressSpace()) {
    LLVMContext &Context = V->getContext();

    // We have no information about target data layout, so we assume that
    // the maximum pointer size is 64bit.
    Type *MidTy = Type::getInt64Ty(Context);
    Temp = CastInst::Create(Instruction::PtrToInt, V, MidTy);

    return CastInst::Create(Instruction::IntToPtr, Temp, DestTy);
  }

  return nullptr;
}

Constant *llvm::UpgradeBitCastExpr(unsigned Opc, Constant *C, Type *DestTy) {
  if (Opc != Instruction::BitCast)
    return nullptr;

  Type *SrcTy = C->getType();
  if (SrcTy->isPtrOrPtrVectorTy() && DestTy->isPtrOrPtrVectorTy() &&
      SrcTy->getPointerAddressSpace() != DestTy->getPointerAddressSpace()) {
    LLVMContext &Context = C->getContext();

    // We have no information about target data layout, so we assume that
    // the maximum pointer size is 64bit.
    Type *MidTy = Type::getInt64Ty(Context);

    return ConstantExpr::getIntToPtr(ConstantExpr::getPtrToInt(C, MidTy),
                                     DestTy);
  }

  return nullptr;
}

/// Check the debug info version number, if it is out-dated, drop the debug
/// info. Return true if module is modified.
bool llvm::UpgradeDebugInfo(Module &M) {
  if (DisableAutoUpgradeDebugInfo)
    return false;

  llvm::TimeTraceScope timeScope("Upgrade debug info");
  // We need to get metadata before the module is verified (i.e., getModuleFlag
  // makes assumptions that we haven't verified yet). Carefully extract the flag
  // from the metadata.
  unsigned Version = 0;
  if (NamedMDNode *ModFlags = M.getModuleFlagsMetadata()) {
    auto OpIt = find_if(ModFlags->operands(), [](const MDNode *Flag) {
      if (Flag->getNumOperands() < 3)
        return false;
      if (MDString *K = dyn_cast_or_null<MDString>(Flag->getOperand(1)))
        return K->getString() == "Debug Info Version";
      return false;
    });
    if (OpIt != ModFlags->op_end()) {
      const MDOperand &ValOp = (*OpIt)->getOperand(2);
      if (auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(ValOp))
        Version = CI->getZExtValue();
    }
  }

  if (Version == DEBUG_METADATA_VERSION) {
    bool BrokenDebugInfo = false;
    if (verifyModule(M, &llvm::errs(), &BrokenDebugInfo))
      report_fatal_error("Broken module found, compilation aborted!");
    if (!BrokenDebugInfo)
      // Everything is ok.
      return false;
    else {
      // Diagnose malformed debug info.
      DiagnosticInfoIgnoringInvalidDebugMetadata Diag(M);
      M.getContext().diagnose(Diag);
    }
  }
  bool Modified = StripDebugInfo(M);
  if (Modified && Version != DEBUG_METADATA_VERSION) {
    // Diagnose a version mismatch.
    DiagnosticInfoDebugMetadataVersion DiagVersion(M, Version);
    M.getContext().diagnose(DiagVersion);
  }
  return Modified;
}

static void upgradeNVVMFnVectorAttr(const StringRef Attr, const char DimC,
                                    GlobalValue *GV, const Metadata *V) {
  Function *F = cast<Function>(GV);

  constexpr StringLiteral DefaultValue = "1";
  StringRef Vect3[3] = {DefaultValue, DefaultValue, DefaultValue};
  unsigned Length = 0;

  if (F->hasFnAttribute(Attr)) {
    // We expect the existing attribute to have the form "x[,y[,z]]". Here we
    // parse these elements placing them into Vect3
    StringRef S = F->getFnAttribute(Attr).getValueAsString();
    for (; Length < 3 && !S.empty(); Length++) {
      auto [Part, Rest] = S.split(',');
      Vect3[Length] = Part.trim();
      S = Rest;
    }
  }

  const unsigned Dim = DimC - 'x';
  assert(Dim < 3 && "Unexpected dim char");

  const uint64_t VInt = mdconst::extract<ConstantInt>(V)->getZExtValue();

  // local variable required for StringRef in Vect3 to point to.
  const std::string VStr = llvm::utostr(VInt);
  Vect3[Dim] = VStr;
  Length = std::max(Length, Dim + 1);

  const std::string NewAttr = llvm::join(ArrayRef(Vect3, Length), ",");
  F->addFnAttr(Attr, NewAttr);
}

static inline bool isXYZ(StringRef S) {
  return S == "x" || S == "y" || S == "z";
}

bool static upgradeSingleNVVMAnnotation(GlobalValue *GV, StringRef K,
                                        const Metadata *V) {
  if (K == "kernel") {
    if (!mdconst::extract<ConstantInt>(V)->isZero())
      cast<Function>(GV)->setCallingConv(CallingConv::PTX_Kernel);
    return true;
  }
  if (K == "align") {
    // V is a bitfeild specifying two 16-bit values. The alignment value is
    // specfied in low 16-bits, The index is specified in the high bits. For the
    // index, 0 indicates the return value while higher values correspond to
    // each parameter (idx = param + 1).
    const uint64_t AlignIdxValuePair =
        mdconst::extract<ConstantInt>(V)->getZExtValue();
    const unsigned Idx = (AlignIdxValuePair >> 16);
    const Align StackAlign = Align(AlignIdxValuePair & 0xFFFF);
    cast<Function>(GV)->addAttributeAtIndex(
        Idx, Attribute::getWithStackAlignment(GV->getContext(), StackAlign));
    return true;
  }
  if (K == "maxclusterrank" || K == "cluster_max_blocks") {
    const auto CV = mdconst::extract<ConstantInt>(V)->getZExtValue();
    cast<Function>(GV)->addFnAttr(NVVMAttr::MaxClusterRank, llvm::utostr(CV));
    return true;
  }
  if (K == "minctasm") {
    const auto CV = mdconst::extract<ConstantInt>(V)->getZExtValue();
    cast<Function>(GV)->addFnAttr(NVVMAttr::MinCTASm, llvm::utostr(CV));
    return true;
  }
  if (K == "maxnreg") {
    const auto CV = mdconst::extract<ConstantInt>(V)->getZExtValue();
    cast<Function>(GV)->addFnAttr(NVVMAttr::MaxNReg, llvm::utostr(CV));
    return true;
  }
  if (K.consume_front("maxntid") && isXYZ(K)) {
    upgradeNVVMFnVectorAttr(NVVMAttr::MaxNTID, K[0], GV, V);
    return true;
  }
  if (K.consume_front("reqntid") && isXYZ(K)) {
    upgradeNVVMFnVectorAttr(NVVMAttr::ReqNTID, K[0], GV, V);
    return true;
  }
  if (K.consume_front("cluster_dim_") && isXYZ(K)) {
    upgradeNVVMFnVectorAttr(NVVMAttr::ClusterDim, K[0], GV, V);
    return true;
  }
  if (K == "grid_constant") {
    const auto Attr = Attribute::get(GV->getContext(), NVVMAttr::GridConstant);
    for (const auto &Op : cast<MDNode>(V)->operands()) {
      // For some reason, the index is 1-based in the metadata. Good thing we're
      // able to auto-upgrade it!
      const auto Index = mdconst::extract<ConstantInt>(Op)->getZExtValue() - 1;
      cast<Function>(GV)->addParamAttr(Index, Attr);
    }
    return true;
  }

  return false;
}

void llvm::UpgradeNVVMAnnotations(Module &M) {
  NamedMDNode *NamedMD = M.getNamedMetadata("nvvm.annotations");
  if (!NamedMD)
    return;

  SmallVector<MDNode *, 8> NewNodes;
  SmallPtrSet<const MDNode *, 8> SeenNodes;
  for (MDNode *MD : NamedMD->operands()) {
    if (!SeenNodes.insert(MD).second)
      continue;

    auto *GV = mdconst::dyn_extract_or_null<GlobalValue>(MD->getOperand(0));
    if (!GV)
      continue;

    assert((MD->getNumOperands() % 2) == 1 && "Invalid number of operands");

    SmallVector<Metadata *, 8> NewOperands{MD->getOperand(0)};
    // Each nvvm.annotations metadata entry will be of the following form:
    //   !{ ptr @gv, !"key1", value1, !"key2", value2, ... }
    // start index = 1, to skip the global variable key
    // increment = 2, to skip the value for each property-value pairs
    for (unsigned j = 1, je = MD->getNumOperands(); j < je; j += 2) {
      MDString *K = cast<MDString>(MD->getOperand(j));
      const MDOperand &V = MD->getOperand(j + 1);
      bool Upgraded = upgradeSingleNVVMAnnotation(GV, K->getString(), V);
      if (!Upgraded)
        NewOperands.append({K, V});
    }

    if (NewOperands.size() > 1)
      NewNodes.push_back(MDNode::get(M.getContext(), NewOperands));
  }

  NamedMD->clearOperands();
  for (MDNode *N : NewNodes)
    NamedMD->addOperand(N);
}

/// This checks for objc retain release marker which should be upgraded. It
/// returns true if module is modified.
static bool upgradeRetainReleaseMarker(Module &M) {
  bool Changed = false;
  const char *MarkerKey = "clang.arc.retainAutoreleasedReturnValueMarker";
  NamedMDNode *ModRetainReleaseMarker = M.getNamedMetadata(MarkerKey);
  if (ModRetainReleaseMarker) {
    MDNode *Op = ModRetainReleaseMarker->getOperand(0);
    if (Op) {
      MDString *ID = dyn_cast_or_null<MDString>(Op->getOperand(0));
      if (ID) {
        SmallVector<StringRef, 4> ValueComp;
        ID->getString().split(ValueComp, "#");
        if (ValueComp.size() == 2) {
          std::string NewValue = ValueComp[0].str() + ";" + ValueComp[1].str();
          ID = MDString::get(M.getContext(), NewValue);
        }
        M.addModuleFlag(Module::Error, MarkerKey, ID);
        M.eraseNamedMetadata(ModRetainReleaseMarker);
        Changed = true;
      }
    }
  }
  return Changed;
}

void llvm::UpgradeARCRuntime(Module &M) {
  // This lambda converts normal function calls to ARC runtime functions to
  // intrinsic calls.
  auto UpgradeToIntrinsic = [&](const char *OldFunc,
                                llvm::Intrinsic::ID IntrinsicFunc) {
    Function *Fn = M.getFunction(OldFunc);

    if (!Fn)
      return;

    Function *NewFn =
        llvm::Intrinsic::getOrInsertDeclaration(&M, IntrinsicFunc);

    for (User *U : make_early_inc_range(Fn->users())) {
      CallInst *CI = dyn_cast<CallInst>(U);
      if (!CI || CI->getCalledFunction() != Fn)
        continue;

      IRBuilder<> Builder(CI->getParent(), CI->getIterator());
      FunctionType *NewFuncTy = NewFn->getFunctionType();
      SmallVector<Value *, 2> Args;

      // Don't upgrade the intrinsic if it's not valid to bitcast the return
      // value to the return type of the old function.
      if (NewFuncTy->getReturnType() != CI->getType() &&
          !CastInst::castIsValid(Instruction::BitCast, CI,
                                 NewFuncTy->getReturnType()))
        continue;

      bool InvalidCast = false;

      for (unsigned I = 0, E = CI->arg_size(); I != E; ++I) {
        Value *Arg = CI->getArgOperand(I);

        // Bitcast argument to the parameter type of the new function if it's
        // not a variadic argument.
        if (I < NewFuncTy->getNumParams()) {
          // Don't upgrade the intrinsic if it's not valid to bitcast the argument
          // to the parameter type of the new function.
          if (!CastInst::castIsValid(Instruction::BitCast, Arg,
                                     NewFuncTy->getParamType(I))) {
            InvalidCast = true;
            break;
          }
          Arg = Builder.CreateBitCast(Arg, NewFuncTy->getParamType(I));
        }
        Args.push_back(Arg);
      }

      if (InvalidCast)
        continue;

      // Create a call instruction that calls the new function.
      CallInst *NewCall = Builder.CreateCall(NewFuncTy, NewFn, Args);
      NewCall->setTailCallKind(cast<CallInst>(CI)->getTailCallKind());
      NewCall->takeName(CI);

      // Bitcast the return value back to the type of the old call.
      Value *NewRetVal = Builder.CreateBitCast(NewCall, CI->getType());

      if (!CI->use_empty())
        CI->replaceAllUsesWith(NewRetVal);
      CI->eraseFromParent();
    }

    if (Fn->use_empty())
      Fn->eraseFromParent();
  };

  // Unconditionally convert a call to "clang.arc.use" to a call to
  // "llvm.objc.clang.arc.use".
  UpgradeToIntrinsic("clang.arc.use", llvm::Intrinsic::objc_clang_arc_use);

  // Upgrade the retain release marker. If there is no need to upgrade
  // the marker, that means either the module is already new enough to contain
  // new intrinsics or it is not ARC. There is no need to upgrade runtime call.
  if (!upgradeRetainReleaseMarker(M))
    return;

  std::pair<const char *, llvm::Intrinsic::ID> RuntimeFuncs[] = {
      {"objc_autorelease", llvm::Intrinsic::objc_autorelease},
      {"objc_autoreleasePoolPop", llvm::Intrinsic::objc_autoreleasePoolPop},
      {"objc_autoreleasePoolPush", llvm::Intrinsic::objc_autoreleasePoolPush},
      {"objc_autoreleaseReturnValue",
       llvm::Intrinsic::objc_autoreleaseReturnValue},
      {"objc_copyWeak", llvm::Intrinsic::objc_copyWeak},
      {"objc_destroyWeak", llvm::Intrinsic::objc_destroyWeak},
      {"objc_initWeak", llvm::Intrinsic::objc_initWeak},
      {"objc_loadWeak", llvm::Intrinsic::objc_loadWeak},
      {"objc_loadWeakRetained", llvm::Intrinsic::objc_loadWeakRetained},
      {"objc_moveWeak", llvm::Intrinsic::objc_moveWeak},
      {"objc_release", llvm::Intrinsic::objc_release},
      {"objc_retain", llvm::Intrinsic::objc_retain},
      {"objc_retainAutorelease", llvm::Intrinsic::objc_retainAutorelease},
      {"objc_retainAutoreleaseReturnValue",
       llvm::Intrinsic::objc_retainAutoreleaseReturnValue},
      {"objc_retainAutoreleasedReturnValue",
       llvm::Intrinsic::objc_retainAutoreleasedReturnValue},
      {"objc_retainBlock", llvm::Intrinsic::objc_retainBlock},
      {"objc_storeStrong", llvm::Intrinsic::objc_storeStrong},
      {"objc_storeWeak", llvm::Intrinsic::objc_storeWeak},
      {"objc_unsafeClaimAutoreleasedReturnValue",
       llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue},
      {"objc_retainedObject", llvm::Intrinsic::objc_retainedObject},
      {"objc_unretainedObject", llvm::Intrinsic::objc_unretainedObject},
      {"objc_unretainedPointer", llvm::Intrinsic::objc_unretainedPointer},
      {"objc_retain_autorelease", llvm::Intrinsic::objc_retain_autorelease},
      {"objc_sync_enter", llvm::Intrinsic::objc_sync_enter},
      {"objc_sync_exit", llvm::Intrinsic::objc_sync_exit},
      {"objc_arc_annotation_topdown_bbstart",
       llvm::Intrinsic::objc_arc_annotation_topdown_bbstart},
      {"objc_arc_annotation_topdown_bbend",
       llvm::Intrinsic::objc_arc_annotation_topdown_bbend},
      {"objc_arc_annotation_bottomup_bbstart",
       llvm::Intrinsic::objc_arc_annotation_bottomup_bbstart},
      {"objc_arc_annotation_bottomup_bbend",
       llvm::Intrinsic::objc_arc_annotation_bottomup_bbend}};

  for (auto &I : RuntimeFuncs)
    UpgradeToIntrinsic(I.first, I.second);
}

bool llvm::UpgradeModuleFlags(Module &M) {
  NamedMDNode *ModFlags = M.getModuleFlagsMetadata();
  if (!ModFlags)
    return false;

  bool HasObjCFlag = false, HasClassProperties = false, Changed = false;
  bool HasSwiftVersionFlag = false;
  uint8_t SwiftMajorVersion, SwiftMinorVersion;
  uint32_t SwiftABIVersion;
  auto Int8Ty = Type::getInt8Ty(M.getContext());
  auto Int32Ty = Type::getInt32Ty(M.getContext());

  for (unsigned I = 0, E = ModFlags->getNumOperands(); I != E; ++I) {
    MDNode *Op = ModFlags->getOperand(I);
    if (Op->getNumOperands() != 3)
      continue;
    MDString *ID = dyn_cast_or_null<MDString>(Op->getOperand(1));
    if (!ID)
      continue;
    auto SetBehavior = [&](Module::ModFlagBehavior B) {
      Metadata *Ops[3] = {ConstantAsMetadata::get(ConstantInt::get(
                              Type::getInt32Ty(M.getContext()), B)),
                          MDString::get(M.getContext(), ID->getString()),
                          Op->getOperand(2)};
      ModFlags->setOperand(I, MDNode::get(M.getContext(), Ops));
      Changed = true;
    };

    if (ID->getString() == "Objective-C Image Info Version")
      HasObjCFlag = true;
    if (ID->getString() == "Objective-C Class Properties")
      HasClassProperties = true;
    // Upgrade PIC from Error/Max to Min.
    if (ID->getString() == "PIC Level") {
      if (auto *Behavior =
              mdconst::dyn_extract_or_null<ConstantInt>(Op->getOperand(0))) {
        uint64_t V = Behavior->getLimitedValue();
        if (V == Module::Error || V == Module::Max)
          SetBehavior(Module::Min);
      }
    }
    // Upgrade "PIE Level" from Error to Max.
    if (ID->getString() == "PIE Level")
      if (auto *Behavior =
              mdconst::dyn_extract_or_null<ConstantInt>(Op->getOperand(0)))
        if (Behavior->getLimitedValue() == Module::Error)
          SetBehavior(Module::Max);

    // Upgrade branch protection and return address signing module flags. The
    // module flag behavior for these fields were Error and now they are Min.
    if (ID->getString() == "branch-target-enforcement" ||
        ID->getString().starts_with("sign-return-address")) {
      if (auto *Behavior =
              mdconst::dyn_extract_or_null<ConstantInt>(Op->getOperand(0))) {
        if (Behavior->getLimitedValue() == Module::Error) {
          Type *Int32Ty = Type::getInt32Ty(M.getContext());
          Metadata *Ops[3] = {
              ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Module::Min)),
              Op->getOperand(1), Op->getOperand(2)};
          ModFlags->setOperand(I, MDNode::get(M.getContext(), Ops));
          Changed = true;
        }
      }
    }

    // Upgrade Objective-C Image Info Section. Removed the whitespce in the
    // section name so that llvm-lto will not complain about mismatching
    // module flags that is functionally the same.
    if (ID->getString() == "Objective-C Image Info Section") {
      if (auto *Value = dyn_cast_or_null<MDString>(Op->getOperand(2))) {
        SmallVector<StringRef, 4> ValueComp;
        Value->getString().split(ValueComp, " ");
        if (ValueComp.size() != 1) {
          std::string NewValue;
          for (auto &S : ValueComp)
            NewValue += S.str();
          Metadata *Ops[3] = {Op->getOperand(0), Op->getOperand(1),
                              MDString::get(M.getContext(), NewValue)};
          ModFlags->setOperand(I, MDNode::get(M.getContext(), Ops));
          Changed = true;
        }
      }
    }

    // IRUpgrader turns a i32 type "Objective-C Garbage Collection" into i8 value.
    // If the higher bits are set, it adds new module flag for swift info.
    if (ID->getString() == "Objective-C Garbage Collection") {
      auto Md = dyn_cast<ConstantAsMetadata>(Op->getOperand(2));
      if (Md) {
        assert(Md->getValue() && "Expected non-empty metadata");
        auto Type = Md->getValue()->getType();
        if (Type == Int8Ty)
          continue;
        unsigned Val = Md->getValue()->getUniqueInteger().getZExtValue();
        if ((Val & 0xff) != Val) {
          HasSwiftVersionFlag = true;
          SwiftABIVersion = (Val & 0xff00) >> 8;
          SwiftMajorVersion = (Val & 0xff000000) >> 24;
          SwiftMinorVersion = (Val & 0xff0000) >> 16;
        }
        Metadata *Ops[3] = {
          ConstantAsMetadata::get(ConstantInt::get(Int32Ty,Module::Error)),
          Op->getOperand(1),
          ConstantAsMetadata::get(ConstantInt::get(Int8Ty,Val & 0xff))};
        ModFlags->setOperand(I, MDNode::get(M.getContext(), Ops));
        Changed = true;
      }
    }

    if (ID->getString() == "amdgpu_code_object_version") {
      Metadata *Ops[3] = {
          Op->getOperand(0),
          MDString::get(M.getContext(), "amdhsa_code_object_version"),
          Op->getOperand(2)};
      ModFlags->setOperand(I, MDNode::get(M.getContext(), Ops));
      Changed = true;
    }
  }

  // "Objective-C Class Properties" is recently added for Objective-C. We
  // upgrade ObjC bitcodes to contain a "Objective-C Class Properties" module
  // flag of value 0, so we can correclty downgrade this flag when trying to
  // link an ObjC bitcode without this module flag with an ObjC bitcode with
  // this module flag.
  if (HasObjCFlag && !HasClassProperties) {
    M.addModuleFlag(llvm::Module::Override, "Objective-C Class Properties",
                    (uint32_t)0);
    Changed = true;
  }

  if (HasSwiftVersionFlag) {
    M.addModuleFlag(Module::Error, "Swift ABI Version",
                    SwiftABIVersion);
    M.addModuleFlag(Module::Error, "Swift Major Version",
                    ConstantInt::get(Int8Ty, SwiftMajorVersion));
    M.addModuleFlag(Module::Error, "Swift Minor Version",
                    ConstantInt::get(Int8Ty, SwiftMinorVersion));
    Changed = true;
  }

  return Changed;
}

void llvm::UpgradeSectionAttributes(Module &M) {
  auto TrimSpaces = [](StringRef Section) -> std::string {
    SmallVector<StringRef, 5> Components;
    Section.split(Components, ',');

    SmallString<32> Buffer;
    raw_svector_ostream OS(Buffer);

    for (auto Component : Components)
      OS << ',' << Component.trim();

    return std::string(OS.str().substr(1));
  };

  for (auto &GV : M.globals()) {
    if (!GV.hasSection())
      continue;

    StringRef Section = GV.getSection();

    if (!Section.starts_with("__DATA, __objc_catlist"))
      continue;

    // __DATA, __objc_catlist, regular, no_dead_strip
    // __DATA,__objc_catlist,regular,no_dead_strip
    GV.setSection(TrimSpaces(Section));
  }
}

namespace {
// Prior to LLVM 10.0, the strictfp attribute could be used on individual
// callsites within a function that did not also have the strictfp attribute.
// Since 10.0, if strict FP semantics are needed within a function, the
// function must have the strictfp attribute and all calls within the function
// must also have the strictfp attribute. This latter restriction is
// necessary to prevent unwanted libcall simplification when a function is
// being cloned (such as for inlining).
//
// The "dangling" strictfp attribute usage was only used to prevent constant
// folding and other libcall simplification. The nobuiltin attribute on the
// callsite has the same effect.
struct StrictFPUpgradeVisitor : public InstVisitor<StrictFPUpgradeVisitor> {
  StrictFPUpgradeVisitor() = default;

  void visitCallBase(CallBase &Call) {
    if (!Call.isStrictFP())
      return;
    if (isa<ConstrainedFPIntrinsic>(&Call))
      return;
    // If we get here, the caller doesn't have the strictfp attribute
    // but this callsite does. Replace the strictfp attribute with nobuiltin.
    Call.removeFnAttr(Attribute::StrictFP);
    Call.addFnAttr(Attribute::NoBuiltin);
  }
};

/// Replace "amdgpu-unsafe-fp-atomics" metadata with atomicrmw metadata
struct AMDGPUUnsafeFPAtomicsUpgradeVisitor
    : public InstVisitor<AMDGPUUnsafeFPAtomicsUpgradeVisitor> {
  AMDGPUUnsafeFPAtomicsUpgradeVisitor() = default;

  void visitAtomicRMWInst(AtomicRMWInst &RMW) {
    if (!RMW.isFloatingPointOperation())
      return;

    MDNode *Empty = MDNode::get(RMW.getContext(), {});
    RMW.setMetadata("amdgpu.no.fine.grained.host.memory", Empty);
    RMW.setMetadata("amdgpu.no.remote.memory.access", Empty);
    RMW.setMetadata("amdgpu.ignore.denormal.mode", Empty);
  }
};
} // namespace

void llvm::UpgradeFunctionAttributes(Function &F) {
  // If a function definition doesn't have the strictfp attribute,
  // convert any callsite strictfp attributes to nobuiltin.
  if (!F.isDeclaration() && !F.hasFnAttribute(Attribute::StrictFP)) {
    StrictFPUpgradeVisitor SFPV;
    SFPV.visit(F);
  }

  // Remove all incompatibile attributes from function.
  F.removeRetAttrs(AttributeFuncs::typeIncompatible(
      F.getReturnType(), F.getAttributes().getRetAttrs()));
  for (auto &Arg : F.args())
    Arg.removeAttrs(
        AttributeFuncs::typeIncompatible(Arg.getType(), Arg.getAttributes()));

  bool AddingAttrs = false, RemovingAttrs = false;
  AttrBuilder AttrsToAdd(F.getContext());
  AttributeMask AttrsToRemove;

  // Older versions of LLVM treated an "implicit-section-name" attribute
  // similarly to directly setting the section on a Function.
  if (Attribute A = F.getFnAttribute("implicit-section-name");
      A.isValid() && A.isStringAttribute()) {
    F.setSection(A.getValueAsString());
    AttrsToRemove.addAttribute("implicit-section-name");
    RemovingAttrs = true;
  }

  if (Attribute A = F.getFnAttribute("nooutline");
      A.isValid() && A.isStringAttribute()) {
    AttrsToRemove.addAttribute("nooutline");
    AttrsToAdd.addAttribute(Attribute::NoOutline);
    AddingAttrs = RemovingAttrs = true;
  }

  if (Attribute A = F.getFnAttribute("uniform-work-group-size");
      A.isValid() && A.isStringAttribute() && !A.getValueAsString().empty()) {
    AttrsToRemove.addAttribute("uniform-work-group-size");
    RemovingAttrs = true;
    if (A.getValueAsString() == "true") {
      AttrsToAdd.addAttribute("uniform-work-group-size");
      AddingAttrs = true;
    }
  }

  if (!F.empty()) {
    // For some reason this is called twice, and the first time is before any
    // instructions are loaded into the body.

    if (Attribute A = F.getFnAttribute("amdgpu-unsafe-fp-atomics");
        A.isValid()) {

      if (A.getValueAsBool()) {
        AMDGPUUnsafeFPAtomicsUpgradeVisitor Visitor;
        Visitor.visit(F);
      }

      // We will leave behind dead attribute uses on external declarations, but
      // clang never added these to declarations anyway.
      AttrsToRemove.addAttribute("amdgpu-unsafe-fp-atomics");
      RemovingAttrs = true;
    }
  }

  DenormalMode DenormalFPMath = DenormalMode::getIEEE();
  DenormalMode DenormalFPMathF32 = DenormalMode::getInvalid();

  bool HandleDenormalMode = false;

  if (Attribute Attr = F.getFnAttribute("denormal-fp-math"); Attr.isValid()) {
    DenormalMode ParsedMode = parseDenormalFPAttribute(Attr.getValueAsString());
    if (ParsedMode.isValid()) {
      DenormalFPMath = ParsedMode;
      AttrsToRemove.addAttribute("denormal-fp-math");
      AddingAttrs = RemovingAttrs = true;
      HandleDenormalMode = true;
    }
  }

  if (Attribute Attr = F.getFnAttribute("denormal-fp-math-f32");
      Attr.isValid()) {
    DenormalMode ParsedMode = parseDenormalFPAttribute(Attr.getValueAsString());
    if (ParsedMode.isValid()) {
      DenormalFPMathF32 = ParsedMode;
      AttrsToRemove.addAttribute("denormal-fp-math-f32");
      AddingAttrs = RemovingAttrs = true;
      HandleDenormalMode = true;
    }
  }

  if (HandleDenormalMode)
    AttrsToAdd.addDenormalFPEnvAttr(
        DenormalFPEnv(DenormalFPMath, DenormalFPMathF32));

  if (RemovingAttrs)
    F.removeFnAttrs(AttrsToRemove);

  if (AddingAttrs)
    F.addFnAttrs(AttrsToAdd);
}

// Check if the function attribute is not present and set it.
static void setFunctionAttrIfNotSet(Function &F, StringRef FnAttrName,
                                    StringRef Value) {
  if (!F.hasFnAttribute(FnAttrName))
    F.addFnAttr(FnAttrName, Value);
}

// Check if the function attribute is not present and set it if needed.
// If the attribute is "false" then removes it.
// If the attribute is "true" resets it to a valueless attribute.
static void ConvertFunctionAttr(Function &F, bool Set, StringRef FnAttrName) {
  if (!F.hasFnAttribute(FnAttrName)) {
    if (Set)
      F.addFnAttr(FnAttrName);
  } else {
    auto A = F.getFnAttribute(FnAttrName);
    if ("false" == A.getValueAsString())
      F.removeFnAttr(FnAttrName);
    else if ("true" == A.getValueAsString()) {
      F.removeFnAttr(FnAttrName);
      F.addFnAttr(FnAttrName);
    }
  }
}

void llvm::copyModuleAttrToFunctions(Module &M) {
  Triple T(M.getTargetTriple());
  if (!T.isThumb() && !T.isARM() && !T.isAArch64())
    return;

  uint64_t BTEValue = 0;
  uint64_t BPPLRValue = 0;
  uint64_t GCSValue = 0;
  uint64_t SRAValue = 0;
  uint64_t SRAALLValue = 0;
  uint64_t SRABKeyValue = 0;

  NamedMDNode *ModFlags = M.getModuleFlagsMetadata();
  if (ModFlags) {
    for (unsigned I = 0, E = ModFlags->getNumOperands(); I != E; ++I) {
      MDNode *Op = ModFlags->getOperand(I);
      if (Op->getNumOperands() != 3)
        continue;

      MDString *ID = dyn_cast_or_null<MDString>(Op->getOperand(1));
      auto *CI = mdconst::dyn_extract<ConstantInt>(Op->getOperand(2));
      if (!ID || !CI)
        continue;

      StringRef IDStr = ID->getString();
      uint64_t *ValPtr = IDStr == "branch-target-enforcement"    ? &BTEValue
                         : IDStr == "branch-protection-pauth-lr" ? &BPPLRValue
                         : IDStr == "guarded-control-stack"      ? &GCSValue
                         : IDStr == "sign-return-address"        ? &SRAValue
                         : IDStr == "sign-return-address-all"    ? &SRAALLValue
                         : IDStr == "sign-return-address-with-bkey"
                             ? &SRABKeyValue
                             : nullptr;
      if (!ValPtr)
        continue;

      *ValPtr = CI->getZExtValue();
      if (*ValPtr == 2)
        return;
    }
  }

  bool BTE = BTEValue == 1;
  bool BPPLR = BPPLRValue == 1;
  bool GCS = GCSValue == 1;
  bool SRA = SRAValue == 1;

  StringRef SignTypeValue = "non-leaf";
  if (SRA && SRAALLValue == 1)
    SignTypeValue = "all";

  StringRef SignKeyValue = "a_key";
  if (SRA && SRABKeyValue == 1)
    SignKeyValue = "b_key";

  for (Function &F : M.getFunctionList()) {
    if (F.isDeclaration())
      continue;

    if (SRA) {
      setFunctionAttrIfNotSet(F, "sign-return-address", SignTypeValue);
      setFunctionAttrIfNotSet(F, "sign-return-address-key", SignKeyValue);
    } else {
      if (auto A = F.getFnAttribute("sign-return-address");
          A.isValid() && "none" == A.getValueAsString()) {
        F.removeFnAttr("sign-return-address");
        F.removeFnAttr("sign-return-address-key");
      }
    }
    ConvertFunctionAttr(F, BTE, "branch-target-enforcement");
    ConvertFunctionAttr(F, BPPLR, "branch-protection-pauth-lr");
    ConvertFunctionAttr(F, GCS, "guarded-control-stack");
  }

  if (BTE)
    M.setModuleFlag(llvm::Module::Min, "branch-target-enforcement", 2);
  if (BPPLR)
    M.setModuleFlag(llvm::Module::Min, "branch-protection-pauth-lr", 2);
  if (GCS)
    M.setModuleFlag(llvm::Module::Min, "guarded-control-stack", 2);
  if (SRA) {
    M.setModuleFlag(llvm::Module::Min, "sign-return-address", 2);
    if (SRAALLValue == 1)
      M.setModuleFlag(llvm::Module::Min, "sign-return-address-all", 2);
    if (SRABKeyValue == 1)
      M.setModuleFlag(llvm::Module::Min, "sign-return-address-with-bkey", 2);
  }
}

static bool isOldLoopArgument(Metadata *MD) {
  auto *T = dyn_cast_or_null<MDTuple>(MD);
  if (!T)
    return false;
  if (T->getNumOperands() < 1)
    return false;
  auto *S = dyn_cast_or_null<MDString>(T->getOperand(0));
  if (!S)
    return false;
  return S->getString().starts_with("llvm.vectorizer.");
}

static MDString *upgradeLoopTag(LLVMContext &C, StringRef OldTag) {
  StringRef OldPrefix = "llvm.vectorizer.";
  assert(OldTag.starts_with(OldPrefix) && "Expected old prefix");

  if (OldTag == "llvm.vectorizer.unroll")
    return MDString::get(C, "llvm.loop.interleave.count");

  return MDString::get(
      C, (Twine("llvm.loop.vectorize.") + OldTag.drop_front(OldPrefix.size()))
             .str());
}

static Metadata *upgradeLoopArgument(Metadata *MD) {
  auto *T = dyn_cast_or_null<MDTuple>(MD);
  if (!T)
    return MD;
  if (T->getNumOperands() < 1)
    return MD;
  auto *OldTag = dyn_cast_or_null<MDString>(T->getOperand(0));
  if (!OldTag)
    return MD;
  if (!OldTag->getString().starts_with("llvm.vectorizer."))
    return MD;

  // This has an old tag.  Upgrade it.
  SmallVector<Metadata *, 8> Ops;
  Ops.reserve(T->getNumOperands());
  Ops.push_back(upgradeLoopTag(T->getContext(), OldTag->getString()));
  for (unsigned I = 1, E = T->getNumOperands(); I != E; ++I)
    Ops.push_back(T->getOperand(I));

  return MDTuple::get(T->getContext(), Ops);
}

MDNode *llvm::upgradeInstructionLoopAttachment(MDNode &N) {
  auto *T = dyn_cast<MDTuple>(&N);
  if (!T)
    return &N;

  if (none_of(T->operands(), isOldLoopArgument))
    return &N;

  SmallVector<Metadata *, 8> Ops;
  Ops.reserve(T->getNumOperands());
  for (Metadata *MD : T->operands())
    Ops.push_back(upgradeLoopArgument(MD));

  return MDTuple::get(T->getContext(), Ops);
}

std::string llvm::UpgradeDataLayoutString(StringRef DL, StringRef TT) {
  Triple T(TT);
  // The only data layout upgrades needed for pre-GCN, SPIR or SPIRV are setting
  // the address space of globals to 1. This does not apply to SPIRV Logical.
  if ((T.isSPIR() || (T.isSPIRV() && !T.isSPIRVLogical())) &&
      !DL.contains("-G") && !DL.starts_with("G")) {
    return DL.empty() ? std::string("G1") : (DL + "-G1").str();
  }

  if (T.isLoongArch64() || T.isRISCV64()) {
    // Make i32 a native type for 64-bit LoongArch and RISC-V.
    auto I = DL.find("-n64-");
    if (I != StringRef::npos)
      return (DL.take_front(I) + "-n32:64-" + DL.drop_front(I + 5)).str();
    return DL.str();
  }

  // AMDGPU data layout upgrades.
  std::string Res = DL.str();
  if (T.isAMDGPU()) {
    // Define address spaces for constants.
    if (!DL.contains("-G") && !DL.starts_with("G"))
      Res.append(Res.empty() ? "G1" : "-G1");

    // AMDGCN data layout upgrades.
    if (T.isAMDGCN()) {

      // Add missing non-integral declarations.
      // This goes before adding new address spaces to prevent incoherent string
      // values.
      if (!DL.contains("-ni") && !DL.starts_with("ni"))
        Res.append("-ni:7:8:9");
      // Update ni:7 to ni:7:8:9.
      if (DL.ends_with("ni:7"))
        Res.append(":8:9");
      if (DL.ends_with("ni:7:8"))
        Res.append(":9");

      // Add sizing for address spaces 7 and 8 (fat raw buffers and buffer
      // resources) An empty data layout has already been upgraded to G1 by now.
      if (!DL.contains("-p7") && !DL.starts_with("p7"))
        Res.append("-p7:160:256:256:32");
      if (!DL.contains("-p8") && !DL.starts_with("p8"))
        Res.append("-p8:128:128:128:48");
      constexpr StringRef OldP8("-p8:128:128-");
      if (DL.contains(OldP8))
        Res.replace(Res.find(OldP8), OldP8.size(), "-p8:128:128:128:48-");
      if (!DL.contains("-p9") && !DL.starts_with("p9"))
        Res.append("-p9:192:256:256:32");
    }

    // Upgrade the ELF mangling mode.
    if (!DL.contains("m:e"))
      Res = Res.empty() ? "m:e" : "m:e-" + Res;

    return Res;
  }

  if (T.isSystemZ() && !DL.empty()) {
    // Make sure the stack alignment is present.
    if (!DL.contains("-S64"))
      return "E-S64" + DL.drop_front(1).str();
    return DL.str();
  }

  auto AddPtr32Ptr64AddrSpaces = [&DL, &Res]() {
    // If the datalayout matches the expected format, add pointer size address
    // spaces to the datalayout.
    StringRef AddrSpaces{"-p270:32:32-p271:32:32-p272:64:64"};
    if (!DL.contains(AddrSpaces)) {
      SmallVector<StringRef, 4> Groups;
      Regex R("^([Ee]-m:[a-z](-p:32:32)?)(-.*)$");
      if (R.match(Res, &Groups))
        Res = (Groups[1] + AddrSpaces + Groups[3]).str();
    }
  };

  // AArch64 data layout upgrades.
  if (T.isAArch64()) {
    // Add "-Fn32"
    if (!DL.empty() && !DL.contains("-Fn32"))
      Res.append("-Fn32");
    AddPtr32Ptr64AddrSpaces();
    return Res;
  }

  if (T.isSPARC() || (T.isMIPS64() && !DL.contains("m:m")) || T.isPPC64() ||
      T.isWasm()) {
    // Mips64 with o32 ABI did not add "-i128:128".
    // Add "-i128:128"
    std::string I64 = "-i64:64";
    std::string I128 = "-i128:128";
    if (!StringRef(Res).contains(I128)) {
      size_t Pos = Res.find(I64);
      if (Pos != size_t(-1))
        Res.insert(Pos + I64.size(), I128);
    }
  }

  if (T.isPPC() && T.isOSAIX() && !DL.contains("f64:32:64") && !DL.empty()) {
    size_t Pos = Res.find("-S128");
    if (Pos == StringRef::npos)
      Pos = Res.size();
    Res.insert(Pos, "-f64:32:64");
  }

  if (!T.isX86())
    return Res;

  AddPtr32Ptr64AddrSpaces();

  // i128 values need to be 16-byte-aligned. LLVM already called into libgcc
  // for i128 operations prior to this being reflected in the data layout, and
  // clang mostly produced LLVM IR that already aligned i128 to 16 byte
  // boundaries, so although this is a breaking change, the upgrade is expected
  // to fix more IR than it breaks.
  // Intel MCU is an exception and uses 4-byte-alignment.
  if (!T.isOSIAMCU()) {
    std::string I128 = "-i128:128";
    if (StringRef Ref = Res; !Ref.contains(I128)) {
      SmallVector<StringRef, 4> Groups;
      Regex R("^(e(-[mpi][^-]*)*)((-[^mpi][^-]*)*)$");
      if (R.match(Res, &Groups))
        Res = (Groups[1] + I128 + Groups[3]).str();
    }
  }

  // For 32-bit MSVC targets, raise the alignment of f80 values to 16 bytes.
  // Raising the alignment is safe because Clang did not produce f80 values in
  // the MSVC environment before this upgrade was added.
  if (T.isWindowsMSVCEnvironment() && !T.isArch64Bit()) {
    StringRef Ref = Res;
    auto I = Ref.find("-f80:32-");
    if (I != StringRef::npos)
      Res = (Ref.take_front(I) + "-f80:128-" + Ref.drop_front(I + 8)).str();
  }

  return Res;
}

void llvm::UpgradeAttributes(AttrBuilder &B) {
  StringRef FramePointer;
  Attribute A = B.getAttribute("no-frame-pointer-elim");
  if (A.isValid()) {
    // The value can be "true" or "false".
    FramePointer = A.getValueAsString() == "true" ? "all" : "none";
    B.removeAttribute("no-frame-pointer-elim");
  }
  if (B.contains("no-frame-pointer-elim-non-leaf")) {
    // The value is ignored. "no-frame-pointer-elim"="true" takes priority.
    if (FramePointer != "all")
      FramePointer = "non-leaf";
    B.removeAttribute("no-frame-pointer-elim-non-leaf");
  }
  if (!FramePointer.empty())
    B.addAttribute("frame-pointer", FramePointer);

  A = B.getAttribute("null-pointer-is-valid");
  if (A.isValid()) {
    // The value can be "true" or "false".
    bool NullPointerIsValid = A.getValueAsString() == "true";
    B.removeAttribute("null-pointer-is-valid");
    if (NullPointerIsValid)
      B.addAttribute(Attribute::NullPointerIsValid);
  }

  A = B.getAttribute("uniform-work-group-size");
  if (A.isValid()) {
    StringRef Val = A.getValueAsString();
    if (!Val.empty()) {
      bool IsTrue = Val == "true";
      B.removeAttribute("uniform-work-group-size");
      if (IsTrue)
        B.addAttribute("uniform-work-group-size");
    }
  }
}

void llvm::UpgradeOperandBundles(std::vector<OperandBundleDef> &Bundles) {
  // clang.arc.attachedcall bundles are now required to have an operand.
  // If they don't, it's okay to drop them entirely: when there is an operand,
  // the "attachedcall" is meaningful and required, but without an operand,
  // it's just a marker NOP.  Dropping it merely prevents an optimization.
  erase_if(Bundles, [&](OperandBundleDef &OBD) {
    return OBD.getTag() == "clang.arc.attachedcall" &&
           OBD.inputs().empty();
  });
}
