Forráskód Böngészése

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 éve
szülő
commit
4c22ec7802

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

@@ -291,6 +291,10 @@ public:
   void LoadDxilCBuffer(const llvm::MDOperand &MDO, DxilCBuffer &CB);
   void LoadDxilCBuffer(const llvm::MDOperand &MDO, DxilCBuffer &CB);
   llvm::MDTuple *EmitDxilSampler(const DxilSampler &S);
   llvm::MDTuple *EmitDxilSampler(const DxilSampler &S);
   void LoadDxilSampler(const llvm::MDOperand &MDO, 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.
   // Type system.
   void EmitDxilTypeSystem(DxilTypeSystem &TypeSystem, std::vector<llvm::GlobalVariable *> &LLVMUsed);
   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 DxilResource &GetUAV(unsigned idx) const;
   const std::vector<std::unique_ptr<DxilResource> > &GetUAVs() 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 RemoveUnusedResources();
   void RemoveFunction(llvm::Function *F);
   void RemoveFunction(llvm::Function *F);
 
 

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

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

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

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

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

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

+ 46 - 0
lib/HLSL/DxilGenerationPass.cpp

@@ -3115,6 +3115,21 @@ public:
     // Promote static global variables.
     // Promote static global variables.
     PromoteStaticGlobalResources(M);
     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
     // Transform PHINode/SelectInst on resource into PHINode/SelectInst on
     // Handle. This will make sure resource only have ld/st/gep use.
     // Handle. This will make sure resource only have ld/st/gep use.
     TransformResourcePHINodeToHandlePHINode(M);
     TransformResourcePHINodeToHandlePHINode(M);
@@ -3124,6 +3139,7 @@ public:
 private:
 private:
   void PromoteStaticGlobalResources(Module &M);
   void PromoteStaticGlobalResources(Module &M);
   void TransformResourcePHINodeToHandlePHINode(Module &M);
   void TransformResourcePHINodeToHandlePHINode(Module &M);
+  void TransformHandleCast(Function &F);
 };
 };
 
 
 char DxilLegalizeStaticResourceUsePass::ID = 0;
 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() {
 ModulePass *llvm::createDxilLegalizeStaticResourceUsePass() {
   return new DxilLegalizeStaticResourceUsePass();
   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);
   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.
 // 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;
   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>
 template <typename TResource>
 static void RemoveResources(std::vector<std::unique_ptr<TResource>> &vec,
 static void RemoveResources(std::vector<std::unique_ptr<TResource>> &vec,
                     std::unordered_set<unsigned> &immResID) {
                     std::unordered_set<unsigned> &immResID) {

+ 10 - 0
lib/HLSL/DxilTypeSystem.cpp

@@ -40,6 +40,7 @@ DxilMatrixAnnotation::DxilMatrixAnnotation()
 //
 //
 DxilFieldAnnotation::DxilFieldAnnotation()
 DxilFieldAnnotation::DxilFieldAnnotation()
 : m_bPrecise(false)
 : m_bPrecise(false)
+, m_ResourceAttribute(nullptr)
 , m_CBufferOffset(UINT_MAX) {
 , 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; }
 bool DxilFieldAnnotation::HasMatrixAnnotation() const { return m_Matrix.Cols != 0; }
 const DxilMatrixAnnotation &DxilFieldAnnotation::GetMatrixAnnotation() const { return m_Matrix; }
 const DxilMatrixAnnotation &DxilFieldAnnotation::GetMatrixAnnotation() const { return m_Matrix; }
 void DxilFieldAnnotation::SetMatrixAnnotation(const DxilMatrixAnnotation &MA) { m_Matrix = MA; }
 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; }
 bool DxilFieldAnnotation::HasCBufferOffset() const { return m_CBufferOffset != UINT_MAX; }
 unsigned DxilFieldAnnotation::GetCBufferOffset() const { return m_CBufferOffset; }
 unsigned DxilFieldAnnotation::GetCBufferOffset() const { return m_CBufferOffset; }
 void DxilFieldAnnotation::SetCBufferOffset(unsigned Offset) { m_CBufferOffset = Offset; }
 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});
   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,
 void HLModule::AddResourceWithGlobalVariableAndMDNode(llvm::Constant *GV,
@@ -1269,6 +1235,40 @@ MDNode *HLModule::GetDxilResourceAttrib(llvm::Function *F) {
   return F->getMetadata(DxilMDHelper::kHLDxilResourceAttributeMDName);
   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 *
 DIGlobalVariable *
 HLModule::FindGlobalVariableDebugInfo(GlobalVariable *GV,
 HLModule::FindGlobalVariableDebugInfo(GlobalVariable *GV,
                                       DebugInfoFinder &DbgInfoFinder) {
                                       DebugInfoFinder &DbgInfoFinder) {

+ 33 - 41
lib/HLSL/HLOperationLower.cpp

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

+ 12 - 3
lib/HLSL/HLOperations.cpp

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