Преглед изворни кода

Prepare to support handle as parameter. (#231)

1. Add resource attribute to FieldAnnotation.
2. Find resource arribute from Argument in FindCreateHandleResourceBase.
3. Remove limitation handle must be instruction.
4. Add HandleToResCast to help lower resource parameter to handle parameter.
Xiang Li пре 8 година
родитељ
комит
4c22ec7802

+ 4 - 0
include/dxc/HLSL/DxilMetadataHelper.h

@@ -291,6 +291,10 @@ public:
   void LoadDxilCBuffer(const llvm::MDOperand &MDO, DxilCBuffer &CB);
   llvm::MDTuple *EmitDxilSampler(const DxilSampler &S);
   void LoadDxilSampler(const llvm::MDOperand &MDO, DxilSampler &S);
+  const llvm::MDOperand &GetResourceClass(llvm::MDNode *MD, DXIL::ResourceClass &RC);
+  void LoadDxilResourceBaseFromMDNode(llvm::MDNode *MD, DxilResourceBase &R);
+  void LoadDxilResourceFromMDNode(llvm::MDNode *MD, DxilResource &R);
+  void LoadDxilSamplerFromMDNode(llvm::MDNode *MD, DxilSampler &S);
 
   // Type system.
   void EmitDxilTypeSystem(DxilTypeSystem &TypeSystem, std::vector<llvm::GlobalVariable *> &LLVMUsed);

+ 4 - 0
include/dxc/HLSL/DxilModule.h

@@ -86,6 +86,10 @@ public:
   const DxilResource &GetUAV(unsigned idx) const;
   const std::vector<std::unique_ptr<DxilResource> > &GetUAVs() const;
 
+  void LoadDxilResourceBaseFromMDNode(llvm::MDNode *MD, DxilResourceBase &R);
+  void LoadDxilResourceFromMDNode(llvm::MDNode *MD, DxilResource &R);
+  void LoadDxilSamplerFromMDNode(llvm::MDNode *MD, DxilSampler &S);
+
   void RemoveUnusedResources();
   void RemoveFunction(llvm::Function *F);
 

+ 6 - 0
include/dxc/HLSL/DxilTypeSystem.h

@@ -23,6 +23,7 @@ namespace llvm {
 class LLVMContext;
 class Module;
 class Function;
+class MDNode;
 class Type;
 class StructType;
 class StringRef;
@@ -53,6 +54,10 @@ public:
   const DxilMatrixAnnotation &GetMatrixAnnotation() const;
   void SetMatrixAnnotation(const DxilMatrixAnnotation &MA);
 
+  bool HasResourceAttribute() const;
+  llvm::MDNode *GetResourceAttribute() const;
+  void SetResourceAttribute(llvm::MDNode *MD);
+
   bool HasCBufferOffset() const;
   unsigned GetCBufferOffset() const;
   void SetCBufferOffset(unsigned Offset);
@@ -78,6 +83,7 @@ private:
   bool m_bPrecise;
   CompType m_CompType;
   DxilMatrixAnnotation m_Matrix;
+  llvm::MDNode *m_ResourceAttribute;
   unsigned m_CBufferOffset;
   std::string m_Semantic;
   InterpolationMode m_InterpMode;

+ 4 - 1
include/dxc/HLSL/HLModule.h

@@ -187,7 +187,7 @@ public:
   llvm::MDNode *DxilSRVToMDNode(const DxilResource &SRV);
   llvm::MDNode *DxilUAVToMDNode(const DxilResource &UAV);
   llvm::MDNode *DxilCBufferToMDNode(const DxilCBuffer &CB);
-  DxilResourceBase LoadDxilResourceBaseFromMDNode(llvm::MDNode *MD);
+  void LoadDxilResourceBaseFromMDNode(llvm::MDNode *MD, DxilResourceBase &R);
   void AddResourceWithGlobalVariableAndMDNode(llvm::Constant *GV,
                                               llvm::MDNode *MD);
 
@@ -231,6 +231,9 @@ public:
   // Resource attribute.
   static void  MarkDxilResourceAttrib(llvm::Function *F, llvm::MDNode *MD);
   static llvm::MDNode *GetDxilResourceAttrib(llvm::Function *F);
+  void MarkDxilResourceAttrib(llvm::Argument *Arg, llvm::MDNode *MD);
+  llvm::MDNode *GetDxilResourceAttrib(llvm::Argument *Arg);
+  static llvm::MDNode *GetDxilResourceAttrib(llvm::Type *Ty, llvm::Module &M);
 
   // DXIL type system.
   DxilTypeSystem &GetTypeSystem();

+ 1 - 0
include/dxc/HLSL/HLOperations.h

@@ -100,6 +100,7 @@ enum class HLCastOpcode {
   ToUnsignedCast,
   ColMatrixToVecCast,
   RowMatrixToVecCast,
+  HandleToResCast,
 };
 
 enum class HLMatLoadStoreOpcode {

+ 46 - 0
lib/HLSL/DxilGenerationPass.cpp

@@ -3115,6 +3115,21 @@ public:
     // Promote static global variables.
     PromoteStaticGlobalResources(M);
 
+    // Lower handle cast.
+    for (Function &F : M.functions()) {
+      if (!F.isDeclaration())
+        continue;
+      HLOpcodeGroup group = hlsl::GetHLOpcodeGroupByName(&F);
+      if (group != HLOpcodeGroup::HLCast)
+        continue;
+      Type *Ty = F.getFunctionType()->getReturnType();
+      if (Ty->isPointerTy())
+        Ty = Ty->getPointerElementType();
+      if (HLModule::IsHLSLObjectType(Ty)) {
+        TransformHandleCast(F);
+      }
+    }
+
     // Transform PHINode/SelectInst on resource into PHINode/SelectInst on
     // Handle. This will make sure resource only have ld/st/gep use.
     TransformResourcePHINodeToHandlePHINode(M);
@@ -3124,6 +3139,7 @@ public:
 private:
   void PromoteStaticGlobalResources(Module &M);
   void TransformResourcePHINodeToHandlePHINode(Module &M);
+  void TransformHandleCast(Function &F);
 };
 
 char DxilLegalizeStaticResourceUsePass::ID = 0;
@@ -3362,6 +3378,36 @@ void DxilLegalizeStaticResourceUsePass::TransformResourcePHINodeToHandlePHINode(
   }
 }
 
+static void ReplaceResUseWithHandle(Instruction *Res, Value *Handle) {
+  Type *HandleTy = Handle->getType();
+  for (auto ResU = Res->user_begin(); ResU != Res->user_end();) {
+    Instruction *I = cast<Instruction>(*(ResU++));
+    if (isa<LoadInst>(I)) {
+      ReplaceResUseWithHandle(I, Handle);
+    } else if (isa<CallInst>(I)) {
+      if (I->getType() == HandleTy)
+        I->replaceAllUsesWith(Handle);
+      else
+        DXASSERT(0, "must createHandle here");
+    } else {
+      DXASSERT(0, "should only used by load and createHandle");
+    }
+    if (I->user_empty()) {
+      I->eraseFromParent();
+    }
+  }
+}
+
+void DxilLegalizeStaticResourceUsePass::TransformHandleCast(Function &F) {
+  for (auto U = F.user_begin(); U != F.user_end(); ) {
+    CallInst *CI = cast<CallInst>(*(U++));
+    Value *Handle = CI->getArgOperand(HLOperandIndex::kUnaryOpSrc0Idx);
+    ReplaceResUseWithHandle(CI, Handle);
+    if (CI->user_empty())
+      CI->eraseFromParent();
+  }
+}
+
 ModulePass *llvm::createDxilLegalizeStaticResourceUsePass() {
   return new DxilLegalizeStaticResourceUsePass();
 }

+ 70 - 0
lib/HLSL/DxilMetadataHelper.cpp

@@ -863,6 +863,76 @@ void DxilMDHelper::LoadDxilSampler(const MDOperand &MDO, DxilSampler &S) {
   m_ExtraPropertyHelper->LoadSamplerProperties(pTupleMD->getOperand(kDxilSamplerNameValueList), S);
 }
 
+const MDOperand &DxilMDHelper::GetResourceClass(llvm::MDNode *MD,
+                                                DXIL::ResourceClass &RC) {
+  IFTBOOL(MD->getNumOperands() >=
+              DxilMDHelper::kHLDxilResourceAttributeNumFields,
+          DXC_E_INCORRECT_DXIL_METADATA);
+  RC = static_cast<DxilResource::Class>(ConstMDToUint32(
+      MD->getOperand(DxilMDHelper::kHLDxilResourceAttributeClass)));
+  return MD->getOperand(DxilMDHelper::kHLDxilResourceAttributeMeta);
+}
+
+void DxilMDHelper::LoadDxilResourceBaseFromMDNode(llvm::MDNode *MD,
+                                                  DxilResourceBase &R) {
+  DxilResource::Class RC = DxilResource::Class::Invalid;
+  const MDOperand &Meta = GetResourceClass(MD, RC);
+
+  switch (RC) {
+  case DxilResource::Class::CBuffer: {
+    DxilCBuffer CB;
+    LoadDxilCBuffer(Meta, CB);
+    R = CB;
+  } break;
+  case DxilResource::Class::Sampler: {
+    DxilSampler S;
+    LoadDxilSampler(Meta, S);
+    R = S;
+  } break;
+  case DxilResource::Class::SRV: {
+    DxilResource Res;
+    LoadDxilSRV(Meta, Res);
+    R = Res;
+  } break;
+  case DxilResource::Class::UAV: {
+    DxilResource Res;
+    LoadDxilUAV(Meta, Res);
+    R = Res;
+  } break;
+  default:
+    DXASSERT(0, "Invalid metadata");
+  }
+}
+
+void DxilMDHelper::LoadDxilResourceFromMDNode(llvm::MDNode *MD,
+                                              DxilResource &R) {
+  DxilResource::Class RC = DxilResource::Class::Invalid;
+  const MDOperand &Meta = GetResourceClass(MD, RC);
+
+  switch (RC) {
+  case DxilResource::Class::SRV: {
+    LoadDxilSRV(Meta, R);
+  } break;
+  case DxilResource::Class::UAV: {
+    LoadDxilUAV(Meta, R);
+  } break;
+  default:
+    DXASSERT(0, "Invalid metadata");
+  }
+}
+
+void DxilMDHelper::LoadDxilSamplerFromMDNode(llvm::MDNode *MD, DxilSampler &S) {
+  DxilResource::Class RC = DxilResource::Class::Invalid;
+  const MDOperand &Meta = GetResourceClass(MD, RC);
+
+  switch (RC) {
+  case DxilResource::Class::Sampler: {
+    LoadDxilSampler(Meta, S);
+  } break;
+  default:
+    DXASSERT(0, "Invalid metadata");
+  }
+}
 
 //
 // DxilExtraPropertyHelper shader-specific methods.

+ 10 - 0
lib/HLSL/DxilModule.cpp

@@ -695,6 +695,16 @@ const vector<unique_ptr<DxilResource> > &DxilModule::GetUAVs() const {
   return m_UAVs;
 }
 
+void DxilModule::LoadDxilResourceBaseFromMDNode(MDNode *MD, DxilResourceBase &R) {
+  return m_pMDHelper->LoadDxilResourceBaseFromMDNode(MD, R);
+}
+void DxilModule::LoadDxilResourceFromMDNode(llvm::MDNode *MD, DxilResource &R) {
+  return m_pMDHelper->LoadDxilResourceFromMDNode(MD, R);
+}
+void DxilModule::LoadDxilSamplerFromMDNode(llvm::MDNode *MD, DxilSampler &S) {
+  return m_pMDHelper->LoadDxilSamplerFromMDNode(MD, S);
+}
+
 template <typename TResource>
 static void RemoveResources(std::vector<std::unique_ptr<TResource>> &vec,
                     std::unordered_set<unsigned> &immResID) {

+ 10 - 0
lib/HLSL/DxilTypeSystem.cpp

@@ -40,6 +40,7 @@ DxilMatrixAnnotation::DxilMatrixAnnotation()
 //
 DxilFieldAnnotation::DxilFieldAnnotation()
 : m_bPrecise(false)
+, m_ResourceAttribute(nullptr)
 , m_CBufferOffset(UINT_MAX) {
 }
 
@@ -48,6 +49,15 @@ void DxilFieldAnnotation::SetPrecise(bool b) { m_bPrecise = b; }
 bool DxilFieldAnnotation::HasMatrixAnnotation() const { return m_Matrix.Cols != 0; }
 const DxilMatrixAnnotation &DxilFieldAnnotation::GetMatrixAnnotation() const { return m_Matrix; }
 void DxilFieldAnnotation::SetMatrixAnnotation(const DxilMatrixAnnotation &MA) { m_Matrix = MA; }
+bool DxilFieldAnnotation::HasResourceAttribute() const {
+  return m_ResourceAttribute;
+}
+llvm::MDNode *DxilFieldAnnotation::GetResourceAttribute() const {
+  return m_ResourceAttribute;
+}
+void DxilFieldAnnotation::SetResourceAttribute(llvm::MDNode *MD) {
+  m_ResourceAttribute = MD;
+}
 bool DxilFieldAnnotation::HasCBufferOffset() const { return m_CBufferOffset != UINT_MAX; }
 unsigned DxilFieldAnnotation::GetCBufferOffset() const { return m_CBufferOffset; }
 void DxilFieldAnnotation::SetCBufferOffset(unsigned Offset) { m_CBufferOffset = Offset; }

+ 36 - 36
lib/HLSL/HLModule.cpp

@@ -740,42 +740,8 @@ MDNode *HLModule::DxilCBufferToMDNode(const DxilCBuffer &CB) {
   return MDNode::get(m_Ctx, {ResClass, MD});
 }
 
-DxilResourceBase HLModule::LoadDxilResourceBaseFromMDNode(
-                                              MDNode *MD) {
-  IFTBOOL(MD->getNumOperands() >= DxilMDHelper::kHLDxilResourceAttributeNumFields,
-          DXC_E_INCORRECT_DXIL_METADATA);
-
-  DxilResource::Class RC =
-      static_cast<DxilResource::Class>(m_pMDHelper->ConstMDToUint32(
-          MD->getOperand(DxilMDHelper::kHLDxilResourceAttributeClass)));
-  const MDOperand &Meta =
-      MD->getOperand(DxilMDHelper::kHLDxilResourceAttributeMeta);
-
-  switch (RC) {
-  case DxilResource::Class::CBuffer: {
-    DxilCBuffer CB;
-    m_pMDHelper->LoadDxilCBuffer(Meta, CB);
-    return CB;
-  } break;
-  case DxilResource::Class::Sampler: {
-    DxilSampler S;
-    m_pMDHelper->LoadDxilSampler(Meta, S);
-    return S;
-  } break;
-  case DxilResource::Class::SRV: {
-    DxilResource Res;
-    m_pMDHelper->LoadDxilSRV(Meta, Res);
-    return Res;
-  } break;
-  case DxilResource::Class::UAV: {
-    DxilResource Res;
-    m_pMDHelper->LoadDxilUAV(Meta, Res);
-    return Res;
-  } break;
-  default:
-    DXASSERT(0, "Invalid metadata");
-    return DxilResourceBase(DXIL::ResourceClass::Invalid);
-  }
+void HLModule::LoadDxilResourceBaseFromMDNode(MDNode *MD, DxilResourceBase &R) {
+  return m_pMDHelper->LoadDxilResourceBaseFromMDNode(MD, R);
 }
 
 void HLModule::AddResourceWithGlobalVariableAndMDNode(llvm::Constant *GV,
@@ -1269,6 +1235,40 @@ MDNode *HLModule::GetDxilResourceAttrib(llvm::Function *F) {
   return F->getMetadata(DxilMDHelper::kHLDxilResourceAttributeMDName);
 }
 
+void HLModule::MarkDxilResourceAttrib(llvm::Argument *Arg, llvm::MDNode *MD) {
+  unsigned i = Arg->getArgNo();
+  Function *F = Arg->getParent();
+  DxilFunctionAnnotation *FuncAnnot = m_pTypeSystem->GetFunctionAnnotation(F);
+  if (!FuncAnnot) {
+    DXASSERT(0, "Invalid function");
+    return;
+  }
+  DxilParameterAnnotation &ParamAnnot = FuncAnnot->GetParameterAnnotation(i);
+  ParamAnnot.SetResourceAttribute(MD);
+}
+
+MDNode *HLModule::GetDxilResourceAttrib(llvm::Argument *Arg) {
+  unsigned i = Arg->getArgNo();
+  Function *F = Arg->getParent();
+  DxilFunctionAnnotation *FuncAnnot = m_pTypeSystem->GetFunctionAnnotation(F);
+  if (!FuncAnnot)
+    return nullptr;
+  DxilParameterAnnotation &ParamAnnot = FuncAnnot->GetParameterAnnotation(i);
+  return ParamAnnot.GetResourceAttribute();
+}
+
+MDNode *HLModule::GetDxilResourceAttrib(Type *Ty, Module &M) {
+  for (Function &F : M.functions()) {
+    if (hlsl::GetHLOpcodeGroupByName(&F) == HLOpcodeGroup::HLCreateHandle) {
+      Type *ResTy = F.getFunctionType()->getParamType(
+          HLOperandIndex::kCreateHandleResourceOpIdx);
+      if (ResTy == Ty)
+        return GetDxilResourceAttrib(&F);
+    }
+  }
+  return nullptr;
+}
+
 DIGlobalVariable *
 HLModule::FindGlobalVariableDebugInfo(GlobalVariable *GV,
                                       DebugInfoFinder &DbgInfoFinder) {

+ 33 - 41
lib/HLSL/HLOperationLower.cpp

@@ -149,14 +149,29 @@ private:
     HandleMetaMap[Handle] = {DXIL::ResourceClass::Invalid,
                              DXIL::ResourceKind::Invalid,
                              StructType::get(Type::getVoidTy(HLM.GetCtx()))};
+    if (Argument *Arg = dyn_cast<Argument>(Handle)) {
+      MDNode *MD = HLM.GetDxilResourceAttrib(Arg);
+      if (!MD) {
+        Handle->getContext().emitError("cannot map resource to handle");
+        return HandleMetaMap[Handle];
+      }
+      DxilResourceBase Res(DxilResource::Class::Invalid);
+      HLM.LoadDxilResourceBaseFromMDNode(MD, Res);
+
+      ResAttribute Attrib = {Res.GetClass(), Res.GetKind(),
+                             Res.GetGlobalSymbol()->getType()};
 
+      HandleMetaMap[Handle] = Attrib;
+      return HandleMetaMap[Handle];
+    }
     if (CallInst *CI = dyn_cast<CallInst>(Handle)) {
       MDNode *MD = HLM.GetDxilResourceAttrib(CI->getCalledFunction());
       if (!MD) {
         Handle->getContext().emitError("cannot map resource to handle");
         return HandleMetaMap[Handle];
       }
-      DxilResourceBase Res = HLM.LoadDxilResourceBaseFromMDNode(MD);
+      DxilResourceBase Res(DxilResource::Class::Invalid);
+      HLM.LoadDxilResourceBaseFromMDNode(MD, Res);
 
       ResAttribute Attrib = {Res.GetClass(), Res.GetKind(),
                              Res.GetGlobalSymbol()->getType()};
@@ -1975,9 +1990,7 @@ namespace {
 Value *TranslateGetSamplePosition(CallInst *CI, IntrinsicOp IOP, OP::OpCode op,
                                   HLOperationLowerHelper &helper,  HLObjectOperationLowerHelper *pObjHelper, bool &Translated) {
   hlsl::OP *hlslOP = &helper.hlslOP;
-  Instruction *thisArg =
-      cast<Instruction>(CI->getArgOperand(HLOperandIndex::kHandleOpIdx));
-  Value *handle = thisArg;
+  Value *handle = CI->getArgOperand(HLOperandIndex::kHandleOpIdx);
 
   IRBuilder<> Builder(CI);
   Value *sampleIdx =
@@ -2003,10 +2016,7 @@ Value *TranslateGetDimensions(CallInst *CI, IntrinsicOp IOP, OP::OpCode op,
                               HLOperationLowerHelper &helper,  HLObjectOperationLowerHelper *pObjHelper, bool &Translated) {
   hlsl::OP *hlslOP = &helper.hlslOP;
 
-  Instruction *thisArg =
-      cast<Instruction>(CI->getArgOperand(HLOperandIndex::kHandleOpIdx));
-
-  Value *handle = thisArg;
+  Value *handle = CI->getArgOperand(HLOperandIndex::kHandleOpIdx);
   DxilResource::Kind RK = pObjHelper->GetRK(handle);
 
   IRBuilder<> Builder(CI);
@@ -2103,10 +2113,8 @@ Value *TranslateGetDimensions(CallInst *CI, IntrinsicOp IOP, OP::OpCode op,
 Value *GenerateUpdateCounter(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
                              HLOperationLowerHelper &helper,  HLObjectOperationLowerHelper *pObjHelper, bool &Translated) {
   hlsl::OP *hlslOP = &helper.hlslOP;
-  Instruction *thisArg =
-      cast<Instruction>(CI->getArgOperand(HLOperandIndex::kHandleOpIdx));
-  Value *handle = thisArg;
-  pObjHelper->MarkHasCounter(thisArg->getType(), handle);
+  Value *handle = CI->getArgOperand(HLOperandIndex::kHandleOpIdx);
+  pObjHelper->MarkHasCounter(handle->getType(), handle);
 
   bool bInc = IOP == IntrinsicOp::MOP_IncrementCounter;
   IRBuilder<> Builder(CI);
@@ -2243,13 +2251,10 @@ SampleHelper::SampleHelper(
   const unsigned thisIdx =
       HLOperandIndex::kHandleOpIdx; // opcode takes arg0, this pointer is arg1.
   const unsigned kSamplerArgIndex = HLOperandIndex::kSampleSamplerArgIndex;
-  Instruction *texArg = cast<Instruction>(CI->getArgOperand(thisIdx));
-  Instruction *samplerArg =
-      cast<Instruction>(CI->getArgOperand(kSamplerArgIndex));
 
   IRBuilder<> Builder(CI);
-  texHandle = texArg;
-  samplerHandle = samplerArg;
+  texHandle = CI->getArgOperand(thisIdx);
+  samplerHandle = CI->getArgOperand(kSamplerArgIndex);
 
   DXIL::ResourceKind RK = pObjHelper->GetRK(texHandle);
   unsigned coordDimensions = DxilResource::GetNumCoords(RK);
@@ -2565,9 +2570,6 @@ GatherHelper::GatherHelper(
   const unsigned thisIdx =
       HLOperandIndex::kHandleOpIdx; // opcode takes arg0, this pointer is arg1.
   const unsigned kSamplerArgIndex = HLOperandIndex::kSampleSamplerArgIndex;
-  Instruction *texArg = cast<Instruction>(CI->getArgOperand(thisIdx));
-  Instruction *samplerArg =
-      cast<Instruction>(CI->getArgOperand(kSamplerArgIndex));
 
   switch (ch) {
   case GatherChannel::GatherAll:
@@ -2588,8 +2590,8 @@ GatherHelper::GatherHelper(
   }
 
   IRBuilder<> Builder(CI);
-  texHandle = texArg;
-  samplerHandle = samplerArg;
+  texHandle = CI->getArgOperand(thisIdx);
+  samplerHandle = CI->getArgOperand(kSamplerArgIndex);
 
   DXIL::ResourceKind RK = pObjHelper->GetRK(texHandle);
   unsigned coordSize = DxilResource::GetNumCoords(RK);
@@ -3021,9 +3023,7 @@ void TranslateLoad(ResLoadHelper &helper, HLResource::Kind RK,
 Value *TranslateResourceLoad(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
                              HLOperationLowerHelper &helper,  HLObjectOperationLowerHelper *pObjHelper, bool &Translated) {
   hlsl::OP *hlslOP = &helper.hlslOP;
-  Instruction *thisArg =
-      cast<Instruction>(CI->getArgOperand(HLOperandIndex::kHandleOpIdx));
-  Value *handle = thisArg;
+  Value *handle = CI->getArgOperand(HLOperandIndex::kHandleOpIdx);
   IRBuilder<> Builder(CI);
 
   DXIL::ResourceClass RC = pObjHelper->GetRC(handle);
@@ -3217,9 +3217,7 @@ Value *TranslateResourceStore(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
                               HLOperationLowerHelper &helper, 
                               HLObjectOperationLowerHelper *pObjHelper, bool &Translated) {
   hlsl::OP *hlslOP = &helper.hlslOP;
-  Instruction *thisArg =
-      cast<Instruction>(CI->getArgOperand(HLOperandIndex::kHandleOpIdx));
-  Value *handle = thisArg;
+  Value *handle = CI->getArgOperand(HLOperandIndex::kHandleOpIdx);
   IRBuilder<> Builder(CI);
   DXIL::ResourceKind RK = pObjHelper->GetRK(handle);
 
@@ -3334,10 +3332,8 @@ Value *TranslateMopAtomicBinaryOperation(CallInst *CI, IntrinsicOp IOP,
                                          OP::OpCode opcode,
                                          HLOperationLowerHelper &helper,  HLObjectOperationLowerHelper *pObjHelper, bool &Translated) {
   hlsl::OP *hlslOP = &helper.hlslOP;
-  Instruction *thisArg =
-      cast<Instruction>(CI->getArgOperand(HLOperandIndex::kHandleOpIdx));
 
-  Value *handle = thisArg;
+  Value *handle = CI->getArgOperand(HLOperandIndex::kHandleOpIdx);
   IRBuilder<> Builder(CI);
 
   switch (IOP) {
@@ -3435,10 +3431,8 @@ Value *TranslateMopAtomicCmpXChg(CallInst *CI, IntrinsicOp IOP,
                                  OP::OpCode opcode,
                                  HLOperationLowerHelper &helper,  HLObjectOperationLowerHelper *pObjHelper, bool &Translated) {
   hlsl::OP *hlslOP = &helper.hlslOP;
-  Instruction *thisArg =
-      cast<Instruction>(CI->getArgOperand(HLOperandIndex::kHandleOpIdx));
 
-  Value *handle = thisArg;
+  Value *handle = CI->getArgOperand(HLOperandIndex::kHandleOpIdx);
   IRBuilder<> Builder(CI);
   AtomicHelper atomicHelper(CI, OP::OpCode::AtomicCompareExchange, handle);
   TranslateAtomicCmpXChg(atomicHelper, Builder, hlslOP);
@@ -5989,11 +5983,10 @@ void TranslateDefaultSubscript(CallInst *CI, HLOperationLowerHelper &helper,  HL
   auto U = CI->user_begin();
 
   Value *ptr = CI->getArgOperand(HLOperandIndex::kSubscriptObjectOpIdx);
-  Instruction *ptrInst = dyn_cast<Instruction>(ptr);
 
   hlsl::OP *hlslOP = &helper.hlslOP;
   // Resource ptr.
-  Value *handle = ptrInst;
+  Value *handle = ptr;
   DXIL::ResourceClass RC = pObjHelper->GetRC(handle);
   DXIL::ResourceKind RK = pObjHelper->GetRK(handle);
 
@@ -6226,9 +6219,8 @@ void TranslateHLSubscript(CallInst *CI, HLSubscriptOpcode opcode,
     Translated = true;
     return;
   } else if (opcode == HLSubscriptOpcode::DoubleSubscript) {
-    Instruction *ptrInst = dyn_cast<Instruction>(ptr);
     // Resource ptr.
-    Value *handle = ptrInst;
+    Value *handle = ptr;
     DXIL::ResourceKind RK = pObjHelper->GetRK(handle);
     Value *coord = CI->getArgOperand(HLOperandIndex::kSubscriptIndexOpIdx);
     Value *mipLevel =
@@ -6244,11 +6236,11 @@ void TranslateHLSubscript(CallInst *CI, HLSubscriptOpcode opcode,
     ldInst->eraseFromParent();
     Translated = true;
     return;
-  } else if (Instruction *ptrInst = dyn_cast<Instruction>(ptr)) {
+  } else {
     Type *HandleTy = hlslOP->GetHandleType();
-    if (ptrInst->getType() == HandleTy) {
+    if (ptr->getType() == HandleTy) {
       // Resource ptr.
-      Value *handle = ptrInst;
+      Value *handle = ptr;
       DXIL::ResourceKind RK = pObjHelper->GetRK(handle);
       if (RK == DxilResource::Kind::Invalid) {
         Translated = false;

+ 12 - 3
lib/HLSL/HLOperations.cpp

@@ -243,6 +243,8 @@ llvm::StringRef GetHLOpcodeName(HLCastOpcode Op) {
     return "colMatToVec";
   case HLCastOpcode::RowMatrixToVecCast:
     return "rowMatToVec";
+  case HLCastOpcode::HandleToResCast:
+    return "handleToRes";
   }
   return "";
 }
@@ -394,23 +396,30 @@ static void SetHLFunctionAttribute(Function *F, HLOpcodeGroup group,
   case HLOpcodeGroup::HLBinOp:
   case HLOpcodeGroup::HLCast:
   case HLOpcodeGroup::HLSubscript:
-    if (!F->hasFnAttribute(Attribute::ReadNone))
+    if (!F->hasFnAttribute(Attribute::ReadNone)) {
       F->addFnAttr(Attribute::ReadNone);
+      F->addFnAttr(Attribute::NoUnwind);
+    }
     break;
   case HLOpcodeGroup::HLInit:
     if (!F->hasFnAttribute(Attribute::ReadNone))
-      if (!F->getReturnType()->isVoidTy())
+      if (!F->getReturnType()->isVoidTy()) {
         F->addFnAttr(Attribute::ReadNone);
+        F->addFnAttr(Attribute::NoUnwind);
+      }
     break;
   case HLOpcodeGroup::HLMatLoadStore: {
     HLMatLoadStoreOpcode matOp = static_cast<HLMatLoadStoreOpcode>(opcode);
     if (matOp == HLMatLoadStoreOpcode::ColMatLoad ||
         matOp == HLMatLoadStoreOpcode::RowMatLoad)
-      if (!F->hasFnAttribute(Attribute::ReadOnly))
+      if (!F->hasFnAttribute(Attribute::ReadOnly)) {
         F->addFnAttr(Attribute::ReadOnly);
+        F->addFnAttr(Attribute::NoUnwind);
+      }
   } break;
   case HLOpcodeGroup::HLCreateHandle: {
     F->addFnAttr(Attribute::ReadNone);
+    F->addFnAttr(Attribute::NoUnwind);
     F->addFnAttr(Attribute::NoInline);
     F->setLinkage(llvm::GlobalValue::LinkageTypes::InternalLinkage);
   } break;