//===- DXILOpLowering.cpp - Lowering to DXIL operations -------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "DXILOpLowering.h"
#include "DXILConstants.h"
#include "DXILOpBuilder.h"
#include "DXILRootSignature.h"
#include "DXILShaderFlags.h"
#include "DirectX.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/DXILMetadataAnalysis.h"
#include "llvm/Analysis/DXILResource.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsDirectX.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/Use.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormatVariadic.h"

#define DEBUG_TYPE "dxil-op-lower"

using namespace llvm;
using namespace llvm::dxil;

namespace {
class OpLowerer {
  Module &M;
  DXILOpBuilder OpBuilder;
  DXILResourceMap &DRM;
  DXILResourceTypeMap &DRTM;
  const ModuleMetadataInfo &MMDI;
  SmallVector<CallInst *> CleanupCasts;
  Function *CleanupNURI = nullptr;

public:
  OpLowerer(Module &M, DXILResourceMap &DRM, DXILResourceTypeMap &DRTM,
            const ModuleMetadataInfo &MMDI)
      : M(M), OpBuilder(M), DRM(DRM), DRTM(DRTM), MMDI(MMDI) {}

  /// Replace every call to \c F using \c ReplaceCall, and then erase \c F. If
  /// there is an error replacing a call, we emit a diagnostic and return true.
  [[nodiscard]] bool
  replaceFunction(Function &F,
                  llvm::function_ref<Error(CallInst *CI)> ReplaceCall) {
    for (User *U : make_early_inc_range(F.users())) {
      CallInst *CI = dyn_cast<CallInst>(U);
      if (!CI)
        continue;

      if (Error E = ReplaceCall(CI)) {
        std::string Message(toString(std::move(E)));
        M.getContext().diagnose(DiagnosticInfoUnsupported(
            *CI->getFunction(), Message, CI->getDebugLoc()));

        return true;
      }
    }
    if (F.user_empty())
      F.eraseFromParent();
    return false;
  }

  struct IntrinArgSelect {
    enum class Type {
#define DXIL_OP_INTRINSIC_ARG_SELECT_TYPE(name) name,
#include "DXILOperation.inc"
    };
    Type Type;
    int Value;
  };

  /// Replaces uses of a struct with uses of an equivalent named struct.
  ///
  /// DXIL operations that return structs give them well known names, so we need
  /// to update uses when we switch from an LLVM intrinsic to an op.
  Error replaceNamedStructUses(CallInst *Intrin, CallInst *DXILOp) {
    auto *IntrinTy = cast<StructType>(Intrin->getType());
    auto *DXILOpTy = cast<StructType>(DXILOp->getType());
    if (!IntrinTy->isLayoutIdentical(DXILOpTy))
      return make_error<StringError>(
          "Type mismatch between intrinsic and DXIL op",
          inconvertibleErrorCode());

    for (Use &U : make_early_inc_range(Intrin->uses()))
      if (auto *EVI = dyn_cast<ExtractValueInst>(U.getUser()))
        EVI->setOperand(0, DXILOp);
      else if (auto *IVI = dyn_cast<InsertValueInst>(U.getUser()))
        IVI->setOperand(0, DXILOp);
      else
        return make_error<StringError>("DXIL ops that return structs may only "
                                       "be used by insert- and extractvalue",
                                       inconvertibleErrorCode());
    return Error::success();
  }

  bool isFast(FastMathFlags Flags) {
    // HLSL Fast Math doesn't enable AllowContract flag; This can be
    // removed when we enable it in the future.
    return Flags.allowReassoc() && Flags.noNaNs() && Flags.noInfs() &&
           Flags.noSignedZeros() && Flags.allowReciprocal() &&
           Flags.approxFunc();
  }

  void setDxPrecise(CallInst *CI) {
    const StringRef Key = "dx.precise";
    Module *M = CI->getModule();

    LLVMContext &Ctx = M->getContext();
    MDNode *One =
        llvm::MDNode::get(Ctx, ConstantAsMetadata::get(ConstantInt::get(
                                   llvm::Type::getInt32Ty(Ctx), 1)));

    CI->setMetadata(Key, One);
  }

  [[nodiscard]] bool
  replaceFunctionWithOp(Function &F, dxil::OpCode DXILOp,
                        ArrayRef<IntrinArgSelect> ArgSelects) {
    return replaceFunction(F, [&](CallInst *CI) -> Error {
      OpBuilder.getIRB().SetInsertPoint(CI);
      SmallVector<Value *> Args;
      if (ArgSelects.size()) {
        for (const IntrinArgSelect &A : ArgSelects) {
          switch (A.Type) {
          case IntrinArgSelect::Type::Index:
            Args.push_back(CI->getArgOperand(A.Value));
            break;
          case IntrinArgSelect::Type::I8:
            Args.push_back(OpBuilder.getIRB().getInt8((uint8_t)A.Value));
            break;
          case IntrinArgSelect::Type::I32:
            Args.push_back(OpBuilder.getIRB().getInt32(A.Value));
            break;
          }
        }
      } else {
        Args.append(CI->arg_begin(), CI->arg_end());
      }

      Expected<CallInst *> OpCall =
          OpBuilder.tryCreateOp(DXILOp, Args, CI->getName(), F.getReturnType());
      if (Error E = OpCall.takeError())
        return E;

      if (isa<FPMathOperator>(CI) &&
          !isFast(cast<FPMathOperator>(CI)->getFastMathFlags()))
        setDxPrecise(*OpCall);

      if (isa<StructType>(CI->getType())) {
        if (Error E = replaceNamedStructUses(CI, *OpCall))
          return E;
      } else
        CI->replaceAllUsesWith(*OpCall);

      CI->eraseFromParent();
      return Error::success();
    });
  }

  /// Create a cast between a `target("dx")` type and `dx.types.Handle`, which
  /// is intended to be removed by the end of lowering. This is used to allow
  /// lowering of ops which need to change their return or argument types in a
  /// piecemeal way - we can add the casts in to avoid updating all of the uses
  /// or defs, and by the end all of the casts will be redundant.
  Value *createTmpHandleCast(Value *V, Type *Ty) {
    CallInst *Cast = OpBuilder.getIRB().CreateIntrinsic(
        Intrinsic::dx_resource_casthandle, {Ty, V->getType()}, {V});
    CleanupCasts.push_back(Cast);
    return Cast;
  }

  void cleanupHandleCasts() {
    SmallVector<CallInst *> ToRemove;
    SmallVector<Function *> CastFns;

    for (CallInst *Cast : CleanupCasts) {
      // These casts were only put in to ease the move from `target("dx")` types
      // to `dx.types.Handle in a piecemeal way. At this point, all of the
      // non-cast uses should now be `dx.types.Handle`, and remaining casts
      // should all form pairs to and from the now unused `target("dx")` type.
      CastFns.push_back(Cast->getCalledFunction());

      // If the cast is not to `dx.types.Handle`, it should be the first part of
      // the pair. Keep track so we can remove it once it has no more uses.
      if (Cast->getType() != OpBuilder.getHandleType()) {
        ToRemove.push_back(Cast);
        continue;
      }
      // Otherwise, we're the second handle in a pair. Forward the arguments and
      // remove the (second) cast.
      CallInst *Def = cast<CallInst>(Cast->getOperand(0));
      assert(Def->getIntrinsicID() == Intrinsic::dx_resource_casthandle &&
             "Unbalanced pair of temporary handle casts");
      Cast->replaceAllUsesWith(Def->getOperand(0));
      Cast->eraseFromParent();
    }
    for (CallInst *Cast : ToRemove) {
      assert(Cast->user_empty() && "Temporary handle cast still has users");
      Cast->eraseFromParent();
    }

    // Deduplicate the cast functions so that we only erase each one once.
    llvm::sort(CastFns);
    CastFns.erase(llvm::unique(CastFns), CastFns.end());
    for (Function *F : CastFns)
      F->eraseFromParent();

    CleanupCasts.clear();
  }

  void cleanupNonUniformResourceIndexCalls() {
    // Replace all NonUniformResourceIndex calls with their argument.
    if (!CleanupNURI)
      return;
    for (User *U : make_early_inc_range(CleanupNURI->users())) {
      CallInst *CI = dyn_cast<CallInst>(U);
      if (!CI)
        continue;
      CI->replaceAllUsesWith(CI->getArgOperand(0));
      CI->eraseFromParent();
    }
    CleanupNURI->eraseFromParent();
    CleanupNURI = nullptr;
  }

  // Remove the resource global associated with the handleFromBinding call
  // instruction and their uses as they aren't needed anymore.
  // TODO: We should verify that all the globals get removed.
  // It's expected we'll need a custom pass in the future that will eliminate
  // the need for this here.
  void removeResourceGlobals(CallInst *CI) {
    for (User *User : make_early_inc_range(CI->users())) {
      if (StoreInst *Store = dyn_cast<StoreInst>(User)) {
        Value *V = Store->getOperand(1);
        Store->eraseFromParent();
        if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
          if (GV->use_empty()) {
            GV->removeDeadConstantUsers();
            GV->eraseFromParent();
          }
      }
    }
  }

  void replaceHandleFromBindingCall(CallInst *CI, Value *Replacement) {
    assert(CI->getCalledFunction()->getIntrinsicID() ==
           Intrinsic::dx_resource_handlefrombinding);

    removeResourceGlobals(CI);

    auto *NameGlobal = dyn_cast<llvm::GlobalVariable>(CI->getArgOperand(4));

    CI->replaceAllUsesWith(Replacement);
    CI->eraseFromParent();

    if (NameGlobal && NameGlobal->use_empty())
      NameGlobal->removeFromParent();
  }

  bool hasNonUniformIndex(Value *IndexOp) {
    if (isa<llvm::Constant>(IndexOp))
      return false;

    SmallVector<Value *, 16> Worklist;
    SmallPtrSet<Value *, 16> Visited;
    Worklist.push_back(IndexOp);

    while (!Worklist.empty()) {
      Value *V = Worklist.pop_back_val();

      if (isa<llvm::Constant>(V))
        continue;

      if (!Visited.insert(V).second)
        continue;

      if (auto *CI = dyn_cast<CallInst>(V))
        if (CI->getIntrinsicID() == Intrinsic::dx_resource_nonuniformindex)
          return true;

      // If it's a PHI node, check ALL incoming values —
      // taint from ANY predecessor counts
      if (auto *Phi = dyn_cast<PHINode>(V)) {
        for (Value *Incoming : Phi->incoming_values())
          Worklist.push_back(Incoming);
        continue;
      }

      if (auto *Inst = dyn_cast<Instruction>(V))
        if (Inst->getNumOperands() > 0 && !Inst->isTerminator())
          for (Value *Op : Inst->operands())
            Worklist.push_back(Op);
    }
    return false;
  }

  Error validateRawBufferElementIndex(Value *Resource, Value *ElementIndex) {
    bool IsStructured =
        cast<RawBufferExtType>(Resource->getType())->isStructured();
    bool IsPoison = isa<PoisonValue>(ElementIndex);

    if (IsStructured && IsPoison)
      return make_error<StringError>(
          "Element index of structured buffer may not be poison",
          inconvertibleErrorCode());

    if (!IsStructured && !IsPoison)
      return make_error<StringError>(
          "Element index of raw buffer must be poison",
          inconvertibleErrorCode());

    return Error::success();
  }

  [[nodiscard]] bool lowerToCreateHandle(Function &F) {
    IRBuilder<> &IRB = OpBuilder.getIRB();
    Type *Int8Ty = IRB.getInt8Ty();
    Type *Int32Ty = IRB.getInt32Ty();
    Type *Int1Ty = IRB.getInt1Ty();

    return replaceFunction(F, [&](CallInst *CI) -> Error {
      IRB.SetInsertPoint(CI);

      auto *It = DRM.find(CI);
      assert(It != DRM.end() && "Resource not in map?");
      dxil::ResourceInfo &RI = *It;

      const auto &Binding = RI.getBinding();
      dxil::ResourceClass RC = DRTM[RI.getHandleTy()].getResourceClass();

      Value *IndexOp = CI->getArgOperand(3);
      if (Binding.LowerBound != 0)
        IndexOp = IRB.CreateAdd(IndexOp,
                                ConstantInt::get(Int32Ty, Binding.LowerBound));

      bool HasNonUniformIndex =
          (Binding.Size == 1) ? false : hasNonUniformIndex(IndexOp);
      std::array<Value *, 4> Args{
          ConstantInt::get(Int8Ty, llvm::to_underlying(RC)),
          ConstantInt::get(Int32Ty, Binding.RecordID), IndexOp,
          ConstantInt::get(Int1Ty, HasNonUniformIndex)};
      Expected<CallInst *> OpCall =
          OpBuilder.tryCreateOp(OpCode::CreateHandle, Args, CI->getName());
      if (Error E = OpCall.takeError())
        return E;

      Value *Cast = createTmpHandleCast(*OpCall, CI->getType());
      replaceHandleFromBindingCall(CI, Cast);
      return Error::success();
    });
  }

  [[nodiscard]] bool lowerToBindAndAnnotateHandle(Function &F) {
    IRBuilder<> &IRB = OpBuilder.getIRB();
    Type *Int32Ty = IRB.getInt32Ty();
    Type *Int1Ty = IRB.getInt1Ty();

    return replaceFunction(F, [&](CallInst *CI) -> Error {
      IRB.SetInsertPoint(CI);

      auto *It = DRM.find(CI);
      assert(It != DRM.end() && "Resource not in map?");
      dxil::ResourceInfo &RI = *It;

      const auto &Binding = RI.getBinding();
      dxil::ResourceTypeInfo &RTI = DRTM[RI.getHandleTy()];
      dxil::ResourceClass RC = RTI.getResourceClass();

      Value *IndexOp = CI->getArgOperand(3);
      if (Binding.LowerBound != 0)
        IndexOp = IRB.CreateAdd(IndexOp,
                                ConstantInt::get(Int32Ty, Binding.LowerBound));

      std::pair<uint32_t, uint32_t> Props =
          RI.getAnnotateProps(*F.getParent(), RTI);

      // For `CreateHandleFromBinding` we need the upper bound rather than the
      // size, so we need to be careful about the difference for "unbounded".
      uint32_t UpperBound = Binding.Size == 0
                                ? std::numeric_limits<uint32_t>::max()
                                : Binding.LowerBound + Binding.Size - 1;
      Constant *ResBind = OpBuilder.getResBind(Binding.LowerBound, UpperBound,
                                               Binding.Space, RC);
      bool NonUniformIndex =
          (Binding.Size == 1) ? false : hasNonUniformIndex(IndexOp);
      Constant *NonUniformOp = ConstantInt::get(Int1Ty, NonUniformIndex);
      std::array<Value *, 3> BindArgs{ResBind, IndexOp, NonUniformOp};
      Expected<CallInst *> OpBind = OpBuilder.tryCreateOp(
          OpCode::CreateHandleFromBinding, BindArgs, CI->getName());
      if (Error E = OpBind.takeError())
        return E;

      std::array<Value *, 2> AnnotateArgs{
          *OpBind, OpBuilder.getResProps(Props.first, Props.second)};
      Expected<CallInst *> OpAnnotate = OpBuilder.tryCreateOp(
          OpCode::AnnotateHandle, AnnotateArgs,
          CI->hasName() ? CI->getName() + "_annot" : Twine());
      if (Error E = OpAnnotate.takeError())
        return E;

      Value *Cast = createTmpHandleCast(*OpAnnotate, CI->getType());
      replaceHandleFromBindingCall(CI, Cast);
      return Error::success();
    });
  }

  /// Lower `dx.resource.handlefrombinding` intrinsics depending on the shader
  /// model and taking into account binding information from
  /// DXILResourceAnalysis.
  bool lowerHandleFromBinding(Function &F) {
    if (MMDI.DXILVersion < VersionTuple(1, 6))
      return lowerToCreateHandle(F);
    return lowerToBindAndAnnotateHandle(F);
  }

  /// Replace uses of \c Intrin with the values in the `dx.ResRet` of \c Op.
  /// Since we expect to be post-scalarization, make an effort to avoid vectors.
  Error replaceResRetUses(CallInst *Intrin, CallInst *Op, bool HasCheckBit) {
    IRBuilder<> &IRB = OpBuilder.getIRB();

    Instruction *OldResult = Intrin;
    Type *OldTy = Intrin->getType();

    if (HasCheckBit) {
      auto *ST = cast<StructType>(OldTy);

      Value *CheckOp = nullptr;
      Type *Int32Ty = IRB.getInt32Ty();
      for (Use &U : make_early_inc_range(OldResult->uses())) {
        if (auto *EVI = dyn_cast<ExtractValueInst>(U.getUser())) {
          ArrayRef<unsigned> Indices = EVI->getIndices();
          assert(Indices.size() == 1);
          // We're only interested in uses of the check bit for now.
          if (Indices[0] != 1)
            continue;
          if (!CheckOp) {
            Value *NewEVI = IRB.CreateExtractValue(Op, 4);
            Expected<CallInst *> OpCall = OpBuilder.tryCreateOp(
                OpCode::CheckAccessFullyMapped, {NewEVI},
                OldResult->hasName() ? OldResult->getName() + "_check"
                                     : Twine(),
                Int32Ty);
            if (Error E = OpCall.takeError())
              return E;
            CheckOp = *OpCall;
          }
          EVI->replaceAllUsesWith(CheckOp);
          EVI->eraseFromParent();
        }
      }

      if (OldResult->use_empty()) {
        // Only the check bit was used, so we're done here.
        OldResult->eraseFromParent();
        return Error::success();
      }

      assert(OldResult->hasOneUse() &&
             isa<ExtractValueInst>(*OldResult->user_begin()) &&
             "Expected only use to be extract of first element");
      OldResult = cast<Instruction>(*OldResult->user_begin());
      OldTy = ST->getElementType(0);
    }

    // For scalars, we just extract the first element.
    if (!isa<FixedVectorType>(OldTy)) {
      Value *EVI = IRB.CreateExtractValue(Op, 0);
      OldResult->replaceAllUsesWith(EVI);
      OldResult->eraseFromParent();
      if (OldResult != Intrin) {
        assert(Intrin->use_empty() && "Intrinsic still has uses?");
        Intrin->eraseFromParent();
      }
      return Error::success();
    }

    std::array<Value *, 4> Extracts = {};
    SmallVector<ExtractElementInst *> DynamicAccesses;

    // The users of the operation should all be scalarized, so we attempt to
    // replace the extractelements with extractvalues directly.
    for (Use &U : make_early_inc_range(OldResult->uses())) {
      if (auto *EEI = dyn_cast<ExtractElementInst>(U.getUser())) {
        if (auto *IndexOp = dyn_cast<ConstantInt>(EEI->getIndexOperand())) {
          size_t IndexVal = IndexOp->getZExtValue();
          assert(IndexVal < 4 && "Index into buffer load out of range");
          if (!Extracts[IndexVal])
            Extracts[IndexVal] = IRB.CreateExtractValue(Op, IndexVal);
          EEI->replaceAllUsesWith(Extracts[IndexVal]);
          EEI->eraseFromParent();
        } else {
          DynamicAccesses.push_back(EEI);
        }
      }
    }

    const auto *VecTy = cast<FixedVectorType>(OldTy);
    const unsigned N = VecTy->getNumElements();

    // If there's a dynamic access we need to round trip through stack memory so
    // that we don't leave vectors around.
    if (!DynamicAccesses.empty()) {
      Type *Int32Ty = IRB.getInt32Ty();
      Constant *Zero = ConstantInt::get(Int32Ty, 0);

      Type *ElTy = VecTy->getElementType();
      Type *ArrayTy = ArrayType::get(ElTy, N);
      Value *Alloca = IRB.CreateAlloca(ArrayTy);

      for (int I = 0, E = N; I != E; ++I) {
        if (!Extracts[I])
          Extracts[I] = IRB.CreateExtractValue(Op, I);
        Value *GEP = IRB.CreateInBoundsGEP(
            ArrayTy, Alloca, {Zero, ConstantInt::get(Int32Ty, I)});
        IRB.CreateStore(Extracts[I], GEP);
      }

      for (ExtractElementInst *EEI : DynamicAccesses) {
        Value *GEP = IRB.CreateInBoundsGEP(ArrayTy, Alloca,
                                           {Zero, EEI->getIndexOperand()});
        Value *Load = IRB.CreateLoad(ElTy, GEP);
        EEI->replaceAllUsesWith(Load);
        EEI->eraseFromParent();
      }
    }

    // If we still have uses, then we're not fully scalarized and need to
    // recreate the vector. This should only happen for things like exported
    // functions from libraries.
    if (!OldResult->use_empty()) {
      for (int I = 0, E = N; I != E; ++I)
        if (!Extracts[I])
          Extracts[I] = IRB.CreateExtractValue(Op, I);

      Value *Vec = PoisonValue::get(OldTy);
      for (int I = 0, E = N; I != E; ++I)
        Vec = IRB.CreateInsertElement(Vec, Extracts[I], I);
      OldResult->replaceAllUsesWith(Vec);
    }

    OldResult->eraseFromParent();
    if (OldResult != Intrin) {
      assert(Intrin->use_empty() && "Intrinsic still has uses?");
      Intrin->eraseFromParent();
    }

    return Error::success();
  }

  [[nodiscard]] bool lowerTypedBufferLoad(Function &F, bool HasCheckBit) {
    IRBuilder<> &IRB = OpBuilder.getIRB();
    Type *Int32Ty = IRB.getInt32Ty();

    return replaceFunction(F, [&](CallInst *CI) -> Error {
      IRB.SetInsertPoint(CI);

      Value *Handle =
          createTmpHandleCast(CI->getArgOperand(0), OpBuilder.getHandleType());
      Value *Index0 = CI->getArgOperand(1);
      Value *Index1 = UndefValue::get(Int32Ty);

      Type *OldTy = CI->getType();
      if (HasCheckBit)
        OldTy = cast<StructType>(OldTy)->getElementType(0);
      Type *NewRetTy = OpBuilder.getResRetType(OldTy->getScalarType());

      std::array<Value *, 3> Args{Handle, Index0, Index1};
      Expected<CallInst *> OpCall = OpBuilder.tryCreateOp(
          OpCode::BufferLoad, Args, CI->getName(), NewRetTy);
      if (Error E = OpCall.takeError())
        return E;
      if (Error E = replaceResRetUses(CI, *OpCall, HasCheckBit))
        return E;

      return Error::success();
    });
  }

  // Copies `Src` into `Args` starting at `ArgIdx`. If `Src` is a vector, its
  // elements are extracted and stored in consecutive slots; otherwise `Src`
  // is stored directly. At most `MaxElements` elements are expected.
  static void extractElementsIntoArgs(IRBuilder<> &IRB,
                                      MutableArrayRef<Value *> Args,
                                      unsigned ArgIdx, Value *Src,
                                      unsigned MaxElements) {
    Type *Ty = Src->getType();
    if (auto *VecTy = dyn_cast<FixedVectorType>(Ty)) {
      unsigned Count = VecTy->getNumElements();
      assert(Count <= MaxElements && "Expected at most 3 elements in vector");
      for (unsigned I = 0; I < Count; ++I)
        Args[ArgIdx + I] = IRB.CreateExtractElement(Src, uint64_t(I));
    } else {
      Args[ArgIdx] = Src;
    }
  }

  [[nodiscard]] bool lowerTextureLoad(Function &F) {
    IRBuilder<> &IRB = OpBuilder.getIRB();
    Type *Int32Ty = IRB.getInt32Ty();

    return replaceFunction(F, [&](CallInst *CI) -> Error {
      IRB.SetInsertPoint(CI);

      Value *Handle =
          createTmpHandleCast(CI->getArgOperand(0), OpBuilder.getHandleType());
      Value *Coords = CI->getArgOperand(1);
      Value *MipLevel = CI->getArgOperand(2);
      Value *Offsets = CI->getArgOperand(3);

      Type *OldTy = CI->getType();
      Type *NewRetTy = OpBuilder.getResRetType(OldTy->getScalarType());

      Value *Undef = UndefValue::get(Int32Ty);
      std::array<Value *, 8> Args{Handle, MipLevel, Undef, Undef,
                                  Undef,  Undef,    Undef, Undef};

      // Copy coordinates and offsets into Args.
      extractElementsIntoArgs(IRB, Args, 2, Coords, 3);
      if (auto *C = dyn_cast<Constant>(Offsets); !C || !C->isNullValue())
        extractElementsIntoArgs(IRB, Args, 5, Offsets, 3);

      Expected<CallInst *> OpCall = OpBuilder.tryCreateOp(
          OpCode::TextureLoad, Args, CI->getName(), NewRetTy);
      if (Error E = OpCall.takeError())
        return E;
      if (Error E = replaceResRetUses(CI, *OpCall, /*HasCheckBit=*/false))
        return E;

      return Error::success();
    });
  }

  [[nodiscard]] bool lowerRawBufferLoad(Function &F) {
    const DataLayout &DL = F.getDataLayout();
    IRBuilder<> &IRB = OpBuilder.getIRB();
    Type *Int8Ty = IRB.getInt8Ty();
    Type *Int32Ty = IRB.getInt32Ty();

    return replaceFunction(F, [&](CallInst *CI) -> Error {
      IRB.SetInsertPoint(CI);

      Type *OldTy = cast<StructType>(CI->getType())->getElementType(0);
      Type *ScalarTy = OldTy->getScalarType();
      Type *NewRetTy = OpBuilder.getResRetType(ScalarTy);

      Value *Handle =
          createTmpHandleCast(CI->getArgOperand(0), OpBuilder.getHandleType());
      Value *Index0 = CI->getArgOperand(1);
      Value *Index1 = CI->getArgOperand(2);
      uint64_t NumElements =
          DL.getTypeSizeInBits(OldTy) / DL.getTypeSizeInBits(ScalarTy);
      Value *Mask = ConstantInt::get(Int8Ty, ~(~0U << NumElements));
      Value *Align =
          ConstantInt::get(Int32Ty, DL.getPrefTypeAlign(ScalarTy).value());

      if (Error E = validateRawBufferElementIndex(CI->getOperand(0), Index1))
        return E;
      if (isa<PoisonValue>(Index1))
        Index1 = UndefValue::get(Index1->getType());

      Expected<CallInst *> OpCall =
          MMDI.DXILVersion >= VersionTuple(1, 2)
              ? OpBuilder.tryCreateOp(OpCode::RawBufferLoad,
                                      {Handle, Index0, Index1, Mask, Align},
                                      CI->getName(), NewRetTy)
              : OpBuilder.tryCreateOp(OpCode::BufferLoad,
                                      {Handle, Index0, Index1}, CI->getName(),
                                      NewRetTy);
      if (Error E = OpCall.takeError())
        return E;
      if (Error E = replaceResRetUses(CI, *OpCall, /*HasCheckBit=*/true))
        return E;

      return Error::success();
    });
  }

  [[nodiscard]] bool lowerCBufferLoad(Function &F) {
    IRBuilder<> &IRB = OpBuilder.getIRB();

    return replaceFunction(F, [&](CallInst *CI) -> Error {
      IRB.SetInsertPoint(CI);

      Type *OldTy = cast<StructType>(CI->getType())->getElementType(0);
      Type *ScalarTy = OldTy->getScalarType();
      Type *NewRetTy = OpBuilder.getCBufRetType(ScalarTy);

      Value *Handle =
          createTmpHandleCast(CI->getArgOperand(0), OpBuilder.getHandleType());
      Value *Index = CI->getArgOperand(1);

      Expected<CallInst *> OpCall = OpBuilder.tryCreateOp(
          OpCode::CBufferLoadLegacy, {Handle, Index}, CI->getName(), NewRetTy);
      if (Error E = OpCall.takeError())
        return E;
      if (Error E = replaceNamedStructUses(CI, *OpCall))
        return E;

      CI->eraseFromParent();
      return Error::success();
    });
  }

  [[nodiscard]] bool lowerUpdateCounter(Function &F) {
    IRBuilder<> &IRB = OpBuilder.getIRB();
    Type *Int32Ty = IRB.getInt32Ty();

    return replaceFunction(F, [&](CallInst *CI) -> Error {
      IRB.SetInsertPoint(CI);
      Value *Handle =
          createTmpHandleCast(CI->getArgOperand(0), OpBuilder.getHandleType());
      Value *Op1 = CI->getArgOperand(1);

      std::array<Value *, 2> Args{Handle, Op1};

      Expected<CallInst *> OpCall = OpBuilder.tryCreateOp(
          OpCode::UpdateCounter, Args, CI->getName(), Int32Ty);

      if (Error E = OpCall.takeError())
        return E;

      CI->replaceAllUsesWith(*OpCall);
      CI->eraseFromParent();
      return Error::success();
    });
  }

  [[nodiscard]] bool lowerGetDimensionsX(Function &F) {
    IRBuilder<> &IRB = OpBuilder.getIRB();
    Type *Int32Ty = IRB.getInt32Ty();

    return replaceFunction(F, [&](CallInst *CI) -> Error {
      IRB.SetInsertPoint(CI);
      Value *Handle =
          createTmpHandleCast(CI->getArgOperand(0), OpBuilder.getHandleType());
      Value *Undef = UndefValue::get(Int32Ty);

      Expected<CallInst *> OpCall = OpBuilder.tryCreateOp(
          OpCode::GetDimensions, {Handle, Undef}, CI->getName(), Int32Ty);
      if (Error E = OpCall.takeError())
        return E;
      Value *Dim = IRB.CreateExtractValue(*OpCall, 0);

      CI->replaceAllUsesWith(Dim);
      CI->eraseFromParent();
      return Error::success();
    });
  }

  [[nodiscard]] bool lowerGetPointer(Function &F) {
    // These should have already been handled in DXILResourceAccess, so we can
    // just clean up the dead prototype.
    assert(F.user_empty() && "getpointer operations should have been removed");
    F.eraseFromParent();
    return false;
  }

  [[nodiscard]] bool lowerBufferStore(Function &F, bool IsRaw) {
    const DataLayout &DL = F.getDataLayout();
    IRBuilder<> &IRB = OpBuilder.getIRB();
    Type *Int8Ty = IRB.getInt8Ty();
    Type *Int32Ty = IRB.getInt32Ty();

    return replaceFunction(F, [&](CallInst *CI) -> Error {
      IRB.SetInsertPoint(CI);

      Value *Handle =
          createTmpHandleCast(CI->getArgOperand(0), OpBuilder.getHandleType());
      Value *Index0 = CI->getArgOperand(1);
      Value *Index1 = IsRaw ? CI->getArgOperand(2) : UndefValue::get(Int32Ty);

      if (IsRaw) {
        if (Error E = validateRawBufferElementIndex(CI->getOperand(0), Index1))
          return E;
        if (isa<PoisonValue>(Index1))
          Index1 = UndefValue::get(Index1->getType());
      }

      Value *Data = CI->getArgOperand(IsRaw ? 3 : 2);
      Type *DataTy = Data->getType();
      Type *ScalarTy = DataTy->getScalarType();

      uint64_t NumElements =
          DL.getTypeSizeInBits(DataTy) / DL.getTypeSizeInBits(ScalarTy);
      Value *Mask =
          ConstantInt::get(Int8Ty, IsRaw ? ~(~0U << NumElements) : 15U);

      // TODO: check that we only have vector or scalar...
      if (NumElements > 4)
        return make_error<StringError>(
            "Buffer store data must have at most 4 elements",
            inconvertibleErrorCode());

      std::array<Value *, 4> DataElements{nullptr, nullptr, nullptr, nullptr};
      if (DataTy == ScalarTy)
        DataElements[0] = Data;
      else {
        // Since we're post-scalarizer, if we see a vector here it's likely
        // constructed solely for the argument of the store. Just use the scalar
        // values from before they're inserted into the temporary.
        auto *IEI = dyn_cast<InsertElementInst>(Data);
        while (IEI) {
          auto *IndexOp = dyn_cast<ConstantInt>(IEI->getOperand(2));
          if (!IndexOp)
            break;
          size_t IndexVal = IndexOp->getZExtValue();
          assert(IndexVal < 4 && "Too many elements for buffer store");
          DataElements[IndexVal] = IEI->getOperand(1);
          IEI = dyn_cast<InsertElementInst>(IEI->getOperand(0));
        }
      }

      // If for some reason we weren't able to forward the arguments from the
      // scalarizer artifact, then we may need to actually extract elements from
      // the vector.
      for (int I = 0, E = NumElements; I < E; ++I)
        if (DataElements[I] == nullptr)
          DataElements[I] =
              IRB.CreateExtractElement(Data, ConstantInt::get(Int32Ty, I));

      // For any elements beyond the length of the vector, we should fill it up
      // with undef - however, for typed buffers we repeat the first element to
      // match DXC.
      for (int I = NumElements, E = 4; I < E; ++I)
        if (DataElements[I] == nullptr)
          DataElements[I] = IsRaw ? UndefValue::get(ScalarTy) : DataElements[0];

      dxil::OpCode Op = OpCode::BufferStore;
      SmallVector<Value *, 9> Args{
          Handle,          Index0,          Index1,          DataElements[0],
          DataElements[1], DataElements[2], DataElements[3], Mask};
      if (IsRaw && MMDI.DXILVersion >= VersionTuple(1, 2)) {
        Op = OpCode::RawBufferStore;
        // RawBufferStore requires the alignment
        Args.push_back(
            ConstantInt::get(Int32Ty, DL.getPrefTypeAlign(ScalarTy).value()));
      }
      Expected<CallInst *> OpCall =
          OpBuilder.tryCreateOp(Op, Args, CI->getName());
      if (Error E = OpCall.takeError())
        return E;

      CI->eraseFromParent();
      // Clean up any leftover `insertelement`s
      auto *IEI = dyn_cast<InsertElementInst>(Data);
      while (IEI && IEI->use_empty()) {
        InsertElementInst *Tmp = IEI;
        IEI = dyn_cast<InsertElementInst>(IEI->getOperand(0));
        Tmp->eraseFromParent();
      }

      return Error::success();
    });
  }

  [[nodiscard]] bool lowerCtpopToCountBits(Function &F) {
    IRBuilder<> &IRB = OpBuilder.getIRB();
    Type *Int32Ty = IRB.getInt32Ty();

    return replaceFunction(F, [&](CallInst *CI) -> Error {
      IRB.SetInsertPoint(CI);
      SmallVector<Value *> Args;
      Args.append(CI->arg_begin(), CI->arg_end());

      Type *RetTy = Int32Ty;
      Type *FRT = F.getReturnType();
      if (const auto *VT = dyn_cast<VectorType>(FRT))
        RetTy = VectorType::get(RetTy, VT);

      Expected<CallInst *> OpCall = OpBuilder.tryCreateOp(
          dxil::OpCode::CountBits, Args, CI->getName(), RetTy);
      if (Error E = OpCall.takeError())
        return E;

      // If the result type is 32 bits we can do a direct replacement.
      if (FRT->isIntOrIntVectorTy(32)) {
        CI->replaceAllUsesWith(*OpCall);
        CI->eraseFromParent();
        return Error::success();
      }

      unsigned CastOp;
      unsigned CastOp2;
      if (FRT->isIntOrIntVectorTy(16)) {
        CastOp = Instruction::ZExt;
        CastOp2 = Instruction::SExt;
      } else { // must be 64 bits
        assert(FRT->isIntOrIntVectorTy(64) &&
               "Currently only lowering 16, 32, or 64 bit ctpop to CountBits \
                is supported.");
        CastOp = Instruction::Trunc;
        CastOp2 = Instruction::Trunc;
      }

      // It is correct to replace the ctpop with the dxil op and
      // remove all casts to i32
      bool NeedsCast = false;
      for (User *User : make_early_inc_range(CI->users())) {
        Instruction *I = dyn_cast<Instruction>(User);
        if (I && (I->getOpcode() == CastOp || I->getOpcode() == CastOp2) &&
            I->getType() == RetTy) {
          I->replaceAllUsesWith(*OpCall);
          I->eraseFromParent();
        } else
          NeedsCast = true;
      }

      // It is correct to replace a ctpop with the dxil op and
      // a cast from i32 to the return type of the ctpop
      // the cast is emitted here if there is a non-cast to i32
      // instr which uses the ctpop
      if (NeedsCast) {
        Value *Cast =
            IRB.CreateZExtOrTrunc(*OpCall, F.getReturnType(), "ctpop.cast");
        CI->replaceAllUsesWith(Cast);
      }

      CI->eraseFromParent();
      return Error::success();
    });
  }

  [[nodiscard]] bool lowerLifetimeIntrinsic(Function &F) {
    IRBuilder<> &IRB = OpBuilder.getIRB();
    return replaceFunction(F, [&](CallInst *CI) -> Error {
      IRB.SetInsertPoint(CI);
      Value *Ptr = CI->getArgOperand(0);
      assert(Ptr->getType()->isPointerTy() &&
             "Expected operand of lifetime intrinsic to be a pointer");

      auto ZeroOrUndef = [&](Type *Ty) {
        return MMDI.ValidatorVersion < VersionTuple(1, 6)
                   ? Constant::getNullValue(Ty)
                   : UndefValue::get(Ty);
      };

      Value *Val = nullptr;
      if (auto *GV = dyn_cast<GlobalVariable>(Ptr)) {
        if (GV->hasInitializer() || GV->isExternallyInitialized())
          return Error::success();
        Val = ZeroOrUndef(GV->getValueType());
      } else if (auto *AI = dyn_cast<AllocaInst>(Ptr))
        Val = ZeroOrUndef(AI->getAllocatedType());

      assert(Val && "Expected operand of lifetime intrinsic to be a global "
                    "variable or alloca instruction");
      IRB.CreateStore(Val, Ptr, false);

      CI->eraseFromParent();
      return Error::success();
    });
  }

  [[nodiscard]] bool lowerIsFPClass(Function &F) {
    IRBuilder<> &IRB = OpBuilder.getIRB();
    Type *RetTy = IRB.getInt1Ty();

    return replaceFunction(F, [&](CallInst *CI) -> Error {
      IRB.SetInsertPoint(CI);
      SmallVector<Value *> Args;
      Value *Fl = CI->getArgOperand(0);
      Args.push_back(Fl);

      dxil::OpCode OpCode;
      Value *T = CI->getArgOperand(1);
      auto *TCI = dyn_cast<ConstantInt>(T);
      switch (TCI->getZExtValue()) {
      case FPClassTest::fcInf:
        OpCode = dxil::OpCode::IsInf;
        break;
      case FPClassTest::fcNan:
        OpCode = dxil::OpCode::IsNaN;
        break;
      case FPClassTest::fcNormal:
        OpCode = dxil::OpCode::IsNormal;
        break;
      case FPClassTest::fcFinite:
        OpCode = dxil::OpCode::IsFinite;
        break;
      default:
        SmallString<128> Msg =
            formatv("Unsupported FPClassTest {0} for DXIL Op Lowering",
                    TCI->getZExtValue());
        return make_error<StringError>(Msg, inconvertibleErrorCode());
      }

      Expected<CallInst *> OpCall =
          OpBuilder.tryCreateOp(OpCode, Args, CI->getName(), RetTy);
      if (Error E = OpCall.takeError())
        return E;

      CI->replaceAllUsesWith(*OpCall);
      CI->eraseFromParent();
      return Error::success();
    });
  }

  bool lowerIntrinsics() {
    bool Updated = false;
    bool HasErrors = false;

    for (Function &F : make_early_inc_range(M.functions())) {
      if (!F.isDeclaration())
        continue;
      Intrinsic::ID ID = F.getIntrinsicID();
      switch (ID) {
      // NOTE: Skip dx_resource_casthandle here. They are
      // resolved after this loop in cleanupHandleCasts.
      case Intrinsic::dx_resource_casthandle:
      // NOTE: llvm.dbg.value is supported as is in DXIL.
      case Intrinsic::dbg_value:
      case Intrinsic::not_intrinsic:
        if (F.use_empty())
          F.eraseFromParent();
        continue;
      default:
        if (F.use_empty())
          F.eraseFromParent();
        else {
          SmallString<128> Msg = formatv(
              "Unsupported intrinsic {0} for DXIL lowering", F.getName());
          M.getContext().emitError(Msg);
          HasErrors |= true;
        }
        break;

#define DXIL_OP_INTRINSIC(OpCode, Intrin, ...)                                 \
  case Intrin:                                                                 \
    HasErrors |= replaceFunctionWithOp(                                        \
        F, OpCode, ArrayRef<IntrinArgSelect>{__VA_ARGS__});                    \
    break;
#include "DXILOperation.inc"
      case Intrinsic::dx_resource_handlefrombinding:
        HasErrors |= lowerHandleFromBinding(F);
        break;
      case Intrinsic::dx_resource_getpointer:
        HasErrors |= lowerGetPointer(F);
        break;
      case Intrinsic::dx_resource_nonuniformindex:
        assert(!CleanupNURI &&
               "overloaded llvm.dx.resource.nonuniformindex intrinsics?");
        CleanupNURI = &F;
        break;
      case Intrinsic::dx_resource_load_typedbuffer:
        HasErrors |= lowerTypedBufferLoad(F, /*HasCheckBit=*/true);
        break;
      case Intrinsic::dx_resource_load_level:
        HasErrors |= lowerTextureLoad(F);
        break;
      case Intrinsic::dx_resource_store_typedbuffer:
        HasErrors |= lowerBufferStore(F, /*IsRaw=*/false);
        break;
      case Intrinsic::dx_resource_load_rawbuffer:
        HasErrors |= lowerRawBufferLoad(F);
        break;
      case Intrinsic::dx_resource_store_rawbuffer:
        HasErrors |= lowerBufferStore(F, /*IsRaw=*/true);
        break;
      case Intrinsic::dx_resource_load_cbufferrow_2:
      case Intrinsic::dx_resource_load_cbufferrow_4:
      case Intrinsic::dx_resource_load_cbufferrow_8:
        HasErrors |= lowerCBufferLoad(F);
        break;
      case Intrinsic::dx_resource_updatecounter:
        HasErrors |= lowerUpdateCounter(F);
        break;
      case Intrinsic::dx_resource_getdimensions_x:
        HasErrors |= lowerGetDimensionsX(F);
        break;
      case Intrinsic::ctpop:
        HasErrors |= lowerCtpopToCountBits(F);
        break;
      case Intrinsic::lifetime_start:
      case Intrinsic::lifetime_end:
        if (F.use_empty())
          F.eraseFromParent();
        else {
          if (MMDI.DXILVersion < VersionTuple(1, 6))
            HasErrors |= lowerLifetimeIntrinsic(F);
          else
            continue;
        }
        break;
      case Intrinsic::is_fpclass:
        HasErrors |= lowerIsFPClass(F);
        break;
      }
      Updated = true;
    }
    if (Updated && !HasErrors) {
      cleanupHandleCasts();
      cleanupNonUniformResourceIndexCalls();
    }

    return Updated;
  }
};
} // namespace

PreservedAnalyses DXILOpLowering::run(Module &M, ModuleAnalysisManager &MAM) {
  DXILResourceMap &DRM = MAM.getResult<DXILResourceAnalysis>(M);
  DXILResourceTypeMap &DRTM = MAM.getResult<DXILResourceTypeAnalysis>(M);
  const ModuleMetadataInfo MMDI = MAM.getResult<DXILMetadataAnalysis>(M);

  const bool MadeChanges = OpLowerer(M, DRM, DRTM, MMDI).lowerIntrinsics();
  if (!MadeChanges)
    return PreservedAnalyses::all();
  PreservedAnalyses PA;
  PA.preserve<DXILResourceAnalysis>();
  PA.preserve<DXILMetadataAnalysis>();
  PA.preserve<ShaderFlagsAnalysis>();
  PA.preserve<RootSignatureAnalysis>();
  return PA;
}

namespace {
class DXILOpLoweringLegacy : public ModulePass {
public:
  bool runOnModule(Module &M) override {
    DXILResourceMap &DRM =
        getAnalysis<DXILResourceWrapperPass>().getResourceMap();
    DXILResourceTypeMap &DRTM =
        getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap();
    const ModuleMetadataInfo MMDI =
        getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata();

    return OpLowerer(M, DRM, DRTM, MMDI).lowerIntrinsics();
  }
  StringRef getPassName() const override { return "DXIL Op Lowering"; }
  DXILOpLoweringLegacy() : ModulePass(ID) {}

  static char ID; // Pass identification.
  void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {
    AU.addRequired<DXILResourceTypeWrapperPass>();
    AU.addRequired<DXILResourceWrapperPass>();
    AU.addRequired<DXILMetadataAnalysisWrapperPass>();
    AU.addPreserved<DXILResourceWrapperPass>();
    AU.addPreserved<DXILMetadataAnalysisWrapperPass>();
    AU.addPreserved<ShaderFlagsAnalysisWrapper>();
    AU.addPreserved<RootSignatureAnalysisWrapper>();
  }
};
char DXILOpLoweringLegacy::ID = 0;
} // end anonymous namespace

INITIALIZE_PASS_BEGIN(DXILOpLoweringLegacy, DEBUG_TYPE, "DXIL Op Lowering",
                      false, false)
INITIALIZE_PASS_DEPENDENCY(DXILResourceTypeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DXILResourceWrapperPass)
INITIALIZE_PASS_END(DXILOpLoweringLegacy, DEBUG_TYPE, "DXIL Op Lowering", false,
                    false)

ModulePass *llvm::createDXILOpLoweringLegacyPass() {
  return new DXILOpLoweringLegacy();
}
