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

// 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();
          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);
          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("ftz.bf16", Intrinsic::nvvm_fma_rn_ftz_bf16)
        .Case("ftz.bf16x2", Intrinsic::nvvm_fma_rn_ftz_bf16x2)
        .Case("ftz.relu.bf16", Intrinsic::nvvm_fma_rn_ftz_relu_bf16)
        .Case("ftz.relu.bf16x2", Intrinsic::nvvm_fma_rn_ftz_relu_bf16x2)
        .Case("ftz.sat.bf16", Intrinsic::nvvm_fma_rn_ftz_sat_bf16)
        .Case("ftz.sat.bf16x2", Intrinsic::nvvm_fma_rn_ftz_sat_bf16x2)
        .Case("relu.bf16", Intrinsic::nvvm_fma_rn_relu_bf16)
        .Case("relu.bf16x2", Intrinsic::nvvm_fma_rn_relu_bf16x2)
        .Case("sat.bf16", Intrinsic::nvvm_fma_rn_sat_bf16)
        .Case("sat.bf16x2", Intrinsic::nvvm_fma_rn_sat_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 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.*'
      }

      if (F->arg_size() == 7 &&
          F->getIntrinsicID() == Intrinsic::amdgcn_wmma_i32_16x16x64_iu8) {
        // Legacy wmma iu8 intrinsic without the optional clamp operand.
        NewFn = nullptr;
        return true;
      }

      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) {
      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("splice.", Intrinsic::vector_splice)
              .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.*'.
      }
      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;
        }
      }

      // 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("max.") || Name.consume_front("min."))
        // nvvm.{min,max}.{i,ii,ui,ull}
        Expand = Name == "s" || Name == "i" || Name == "ll" || Name == "us" ||
                 Name == "ui" || Name == "ull";
      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.
      }
      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;
    }
    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::SequentiallyConsistent);
  } 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::SequentiallyConsistent);
  } else if (Name.consume_front("max.") &&
             (Name == "s" || Name == "i" || Name == "ll" || Name == "us" ||
              Name == "ui" || Name == "ull")) {
    Value *Arg0 = CI->getArgOperand(0);
    Value *Arg1 = CI->getArgOperand(1);
    Value *Cmp = Name.starts_with("u")
                     ? Builder.CreateICmpUGE(Arg0, Arg1, "max.cond")
                     : Builder.CreateICmpSGE(Arg0, Arg1, "max.cond");
    Rep = Builder.CreateSelect(Cmp, Arg0, Arg1, "max");
  } else if (Name.consume_front("min.") &&
             (Name == "s" || Name == "i" || Name == "ll" || Name == "us" ||
              Name == "ui" || Name == "ull")) {
    Value *Arg0 = CI->getArgOperand(0);
    Value *Arg1 = CI->getArgOperand(1);
    Value *Cmp = Name.starts_with("u")
                     ? Builder.CreateICmpULE(Arg0, Arg1, "min.cond")
                     : Builder.CreateICmpSLE(Arg0, Arg1, "min.cond");
    Rep = Builder.CreateSelect(Cmp, Arg0, Arg1, "min");
  } 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") {
    Rep = Builder.CreateIntrinsic(Intrinsic::convert_from_fp16,
                                  {Builder.getFloatTy()}, CI->getArgOperand(0),
                                  /*FMFSource=*/nullptr, "h2f");
  } 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:
      llvm_unreachable("Unexpected intrinsic");
    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
      llvm_unreachable("Unexpected intrinsic");

    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
      llvm_unreachable("Unexpected intrinsic");

    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
      llvm_unreachable("Unknown suffix");

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

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

    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
        llvm_unreachable("Unexpected size");
    } 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
        llvm_unreachable("Unexpected size");
    } 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
        llvm_unreachable("Unexpected size");
    } 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
        llvm_unreachable("Unexpected size");
    }

    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
        llvm_unreachable("Unexpected size");
    } 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
        llvm_unreachable("Unexpected size");
    } 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
        llvm_unreachable("Unexpected size");
    } 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
        llvm_unreachable("Unexpected size");
    }

    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
        llvm_unreachable("Unexpected size");
    } 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
        llvm_unreachable("Unexpected size");
    } 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
        llvm_unreachable("Unexpected size");
    } 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
        llvm_unreachable("Unexpected size");
    }

    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
      llvm_unreachable("Unexpected intrinsic");

    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
      llvm_unreachable("Unexpected intrinsic");

    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
      llvm_unreachable("Unexpected intrinsic");

    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
      llvm_unreachable("Unexpected intrinsic");

    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
        llvm_unreachable("Unexpected vector bit width");

      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
      llvm_unreachable("Unexpected intrinsic");

    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
        llvm_unreachable("Unexpected vector bit width");

      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
      llvm_unreachable("Unexpected intrinsic");

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

  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) {
  if (CI->arg_size() == 7 &&
      F->getIntrinsicID() == Intrinsic::amdgcn_wmma_i32_16x16x64_iu8) {
    // Legacy WMMA IU8 intrinsic lacked the optional clamp operand. Append
    // clamp=false for compatibility.

    SmallVector<Value *, 8> Args(CI->args().begin(), CI->args().end());
    Args.push_back(Builder.getFalse());

    Function *NewDecl = Intrinsic::getOrInsertDeclaration(
        F->getParent(), Intrinsic::amdgcn_wmma_i32_16x16x64_iu8,
        {CI->getArgOperand(4)->getType(), CI->getArgOperand(1)->getType()});

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

/// 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);
  Builder.SetInsertPoint(CI->getParent(), CI->getIterator());

  if (!NewFn) {
    // Get the Function's name.
    StringRef Name = F->getName();

    assert(Name.starts_with("llvm.") && "Intrinsic doesn't start with 'llvm.'");
    Name = Name.substr(5);

    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.");
    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 {
      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: {
    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::convert_from_fp16:
    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->isZeroValue()) {
        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("nvvm.maxclusterrank", llvm::utostr(CV));
    return true;
  }
  if (K == "minctasm") {
    const auto CV = mdconst::extract<ConstantInt>(V)->getZExtValue();
    cast<Function>(GV)->addFnAttr("nvvm.minctasm", llvm::utostr(CV));
    return true;
  }
  if (K == "maxnreg") {
    const auto CV = mdconst::extract<ConstantInt>(V)->getZExtValue();
    cast<Function>(GV)->addFnAttr("nvvm.maxnreg", llvm::utostr(CV));
    return true;
  }
  if (K.consume_front("maxntid") && isXYZ(K)) {
    upgradeNVVMFnVectorAttr("nvvm.maxntid", K[0], GV, V);
    return true;
  }
  if (K.consume_front("reqntid") && isXYZ(K)) {
    upgradeNVVMFnVectorAttr("nvvm.reqntid", K[0], GV, V);
    return true;
  }
  if (K.consume_front("cluster_dim_") && isXYZ(K)) {
    upgradeNVVMFnVectorAttr("nvvm.cluster_dim", K[0], GV, V);
    return true;
  }
  if (K == "grid_constant") {
    const auto Attr = Attribute::get(GV->getContext(), "nvvm.grid_constant");
    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()));

  // 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());
    F.removeFnAttr("implicit-section-name");
  }

  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.
      F.removeFnAttr("amdgpu-unsafe-fp-atomics");
    }
  }
}

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

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

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