瀏覽代碼

Remove dx.temp metadata. (#5011)

To fix validation error when noinline enabled.

Also add DxilModuleInit init pass for opt to test pass which require dxil module exist.
Xiang Li 2 年之前
父節點
當前提交
e30afd2995

+ 3 - 0
include/dxc/HLSL/DxilGenerationPass.h

@@ -140,4 +140,7 @@ void initializeDxilDeleteRedundantDebugValuesPass(llvm::PassRegistry&);
 FunctionPass *createDxilSimpleGVNEliminateRegionPass();
 void initializeDxilSimpleGVNEliminateRegionPass(llvm::PassRegistry&);
 
+ModulePass *createDxilModuleInitPass();
+void initializeDxilModuleInitPass(llvm::PassRegistry &);
+
 }

+ 56 - 19
lib/HLSL/DxilPreparePasses.cpp

@@ -34,6 +34,7 @@
 #include "llvm/IR/PassManager.h"
 #include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/Pass.h"
 #include "llvm/Transforms/Utils/Local.h"
 #include "llvm/Analysis/AssumptionCache.h"
@@ -343,26 +344,18 @@ public:
 
   StringRef getPassName() const override { return "HLSL DXIL Finalize Module"; }
 
-  void patchValidation_1_1(Module &M) {
-    for (iplist<Function>::iterator F : M.getFunctionList()) {
-      for (Function::iterator BBI = F->begin(), BBE = F->end(); BBI != BBE;
-           ++BBI) {
-        BasicBlock *BB = BBI;
-        for (BasicBlock::iterator II = BB->begin(), IE = BB->end(); II != IE;
-             ++II) {
-          Instruction *I = II;
-          if (I->hasMetadataOtherThanDebugLoc()) {
-            SmallVector<std::pair<unsigned, MDNode*>, 2> MDs;
-            I->getAllMetadataOtherThanDebugLoc(MDs);
+  void patchInstructionMetadata(Module &M, DenseSet<unsigned> &IllegalMDSet) {
+    for (auto &F : M.getFunctionList()) {
+      for (auto &BB : F) {
+        for (auto &I : BB) {
+          if (I.hasMetadataOtherThanDebugLoc()) {
+            SmallVector<std::pair<unsigned, MDNode *>, 2> MDs;
+            I.getAllMetadataOtherThanDebugLoc(MDs);
             for (auto &MD : MDs) {
               unsigned kind = MD.first;
-              // Remove Metadata which validation_1_0 not allowed.
-              bool bNeedPatch = kind == LLVMContext::MD_tbaa ||
-                  kind == LLVMContext::MD_prof ||
-                  (kind > LLVMContext::MD_fpmath &&
-                  kind <= LLVMContext::MD_dereferenceable_or_null);
-              if (bNeedPatch)
-                I->setMetadata(kind, nullptr);
+              // Remove illegal metadata.
+              if (IllegalMDSet.count(kind))
+                I.setMetadata(kind, nullptr);
             }
           }
         }
@@ -774,8 +767,22 @@ public:
       bool IsLib = DM.GetShaderModel()->IsLib();
       // Skip validation patch for lib.
       if (!IsLib) {
+        unsigned DxilTempMDKind =
+            M.getContext().getMDKindID(DxilMDHelper::kDxilTempAllocaMDName);
         if (DXIL::CompareVersions(ValMajor, ValMinor, 1, 1) <= 0) {
-          patchValidation_1_1(M);
+          DenseSet<unsigned> IllegalMDSet;
+          IllegalMDSet.insert(LLVMContext::MD_tbaa);
+          IllegalMDSet.insert(LLVMContext::MD_prof);
+          for (unsigned I = LLVMContext::MD_fpmath + 1;
+               I <= LLVMContext::MD_dereferenceable_or_null; ++I) {
+            IllegalMDSet.insert(I);
+          }
+          IllegalMDSet.insert(DxilTempMDKind);
+          patchInstructionMetadata(M, IllegalMDSet);
+        } else {
+          DenseSet<unsigned> IllegalMDSet;
+          IllegalMDSet.insert(DxilTempMDKind);
+          patchInstructionMetadata(M, IllegalMDSet);
         }
       }
 
@@ -1713,3 +1720,33 @@ INITIALIZE_PASS_END(CleanupDxBreak, "hlsl-cleanup-dxbreak", "HLSL Remove unneces
 FunctionPass *llvm::createCleanupDxBreakPass() {
   return new CleanupDxBreak();
 }
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace {
+
+class DxilModuleInit : public ModulePass {
+public:
+  static char ID; // Pass identification, replacement for typeid
+  explicit DxilModuleInit() : ModulePass(ID) {}
+
+  StringRef getPassName() const override {
+    return "Create DXIL Module for opt tests";
+  }
+
+  bool runOnModule(Module &M) override {
+    M.GetOrCreateDxilModule();
+    return true;
+  }
+};
+
+} // namespace
+
+char DxilModuleInit::ID = 0;
+
+ModulePass *llvm::createDxilModuleInitPass() { return new DxilModuleInit(); }
+
+INITIALIZE_PASS(DxilModuleInit, "hlsl-dxil-module-init",
+                "Create DXIL Module for opt tests", false, false)
+
+///////////////////////////////////////////////////////////////////////////////

+ 39 - 0
tools/clang/test/HLSLFileCheckLit/passes/dxil/dxilfinalize/illegal_metadata.ll

@@ -0,0 +1,39 @@
+; RUN: opt -hlsl-dxil-module-init -hlsl-dxilfinalize %s -S | FileCheck %s
+
+; Make sure !dx.temp is removed.
+
+; CHECK-LABEL:define void @main()
+; CHECK-NOT:!dx.temp
+
+target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
+target triple = "dxil-ms-dx"
+
+define void @main() {
+  call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float 0.000000e+00), !dx.temp !11
+  ret void
+}
+
+; Function Attrs: nounwind
+declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #0
+
+attributes #0 = { nounwind }
+
+!llvm.ident = !{!0}
+!dx.version = !{!1}
+!dx.valver = !{!2}
+!dx.shaderModel = !{!3}
+!dx.viewIdState = !{!4}
+!dx.entryPoints = !{!5}
+
+!0 = !{!"dxc(private) 1.7.0.3820 (lit_by_default, 316176e78-dirty)"}
+!1 = !{i32 1, i32 0}
+!2 = !{i32 1, i32 7}
+!3 = !{!"ps", i32 6, i32 0}
+!4 = !{[2 x i32] [i32 0, i32 1]}
+!5 = !{void ()* @main, !"main", !6, null, null}
+!6 = !{null, !7, null}
+!7 = !{!8}
+!8 = !{i32 0, !"SV_Target", i8 9, i8 16, !9, i8 0, i32 1, i8 1, i32 0, i8 0, !10}
+!9 = !{i32 0}
+!10 = !{i32 3, i32 1}
+!11 = !{}

+ 3 - 0
tools/opt/opt.cpp

@@ -54,6 +54,7 @@
 
 // HLSL Change Starts
 #include "dxc/HLSL/ComputeViewIdState.h"
+#include "dxc/HLSL/DxilGenerationPass.h"
 #include "dxc/Support/Global.h"
 #include "llvm/Analysis/ReducibilityAnalysis.h"
 #include "dxc/Support/WinIncludes.h"
@@ -362,6 +363,8 @@ int __cdecl main(int argc, char **argv) {
   // HLSL Change Starts
   initializeReducibilityAnalysisPass(Registry);
   initializeComputeViewIdStatePass(Registry);
+  initializeDxilFinalizeModulePass(Registry);
+  initializeDxilModuleInitPass(Registry);
 #ifdef HAS_DXILCONV
   initializeDxilConvPasses(Registry);
 #endif