Просмотр исходного кода

Strip function parameter for entry and patch constant function. (#20)

Strip function parameter for entry and patch constant function

* Update error message for ValidationTest::MultiDimArray

* Merge remote-tracking branch 'origin/master'

# Conflicts:
#	lib/HLSL/DxilValidation.cpp
#	tools/clang/unittests/HLSL/ValidationTest.cpp

* Update error message for ValidationTest::MultiDimArray

Update error message for ValidationTest::MultiDimArray

* Fix merge error. (#3)

* Delete local file (#4)

* Fix merge error.

* Delete local file

* Strip function parameter for entry and patch constant function. (#5)
Xiang Li 8 лет назад
Родитель
Сommit
5623234187

+ 1 - 1
docs/DXIL.rst

@@ -2124,7 +2124,7 @@ DECL.NOTUSEDEXTERNAL                  External declaration should not be used
 DECL.USEDEXTERNALFUNCTION             External function must be used
 DECL.USEDEXTERNALFUNCTION             External function must be used
 DECL.USEDINTERNAL                     Internal declaration must be used
 DECL.USEDINTERNAL                     Internal declaration must be used
 FLOW.DEADLOOP                         Loop must have break
 FLOW.DEADLOOP                         Loop must have break
-FLOW.FUNCTIONCALL                     Function call on user defined function with parameter is not permitted
+FLOW.FUNCTIONCALL                     Function with parameter is not permitted
 FLOW.NORECUSION                       Recursion is not permitted
 FLOW.NORECUSION                       Recursion is not permitted
 FLOW.REDUCIBLE                        Execution flow must be reducible
 FLOW.REDUCIBLE                        Execution flow must be reducible
 INSTR.ALLOWED                         Instructions must be of an allowed type
 INSTR.ALLOWED                         Instructions must be of an allowed type

+ 1 - 1
include/dxc/HLSL/DxilValidation.h

@@ -147,7 +147,7 @@ enum class ValidationRule : unsigned {
 
 
   // Program flow
   // Program flow
   FlowDeadLoop, // Loop must have break
   FlowDeadLoop, // Loop must have break
-  FlowFunctionCall, // Function call on user defined function with parameter is not permitted
+  FlowFunctionCall, // Function with parameter is not permitted
   FlowNoRecusion, // Recursion is not permitted
   FlowNoRecusion, // Recursion is not permitted
   FlowReducible, // Execution flow must be reducible
   FlowReducible, // Execution flow must be reducible
 
 

+ 53 - 2
lib/HLSL/DxilGenerationPass.cpp

@@ -2496,6 +2496,39 @@ INITIALIZE_PASS(HLEnsureMetadata, "hlsl-hlensure", "HLSL High-Level Metadata Ens
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 
 
 namespace {
 namespace {
+
+Function *StripFunctionParameter(Function *F, DxilModule &DM,
+    DenseMap<const Function *, DISubprogram *> &FunctionDIs) {
+  Module &M = *DM.GetModule();
+  Type *VoidTy = Type::getVoidTy(M.getContext());
+  FunctionType *FT = FunctionType::get(VoidTy, false);
+  for (auto &arg : F->args()) {
+    if (!arg.user_empty())
+      return nullptr;
+  }
+
+  Function *NewFunc = Function::Create(FT, F->getLinkage(), F->getName());
+  M.getFunctionList().insert(F, NewFunc);
+  // Splice the body of the old function right into the new function.
+  NewFunc->getBasicBlockList().splice(NewFunc->begin(), F->getBasicBlockList());
+
+  // Patch the pointer to LLVM function in debug info descriptor.
+  auto DI = FunctionDIs.find(F);
+  if (DI != FunctionDIs.end()) {
+    DISubprogram *SP = DI->second;
+    SP->replaceFunction(NewFunc);
+    // Ensure the map is updated so it can be reused on subsequent argument
+    // promotions of the same function.
+    FunctionDIs.erase(DI);
+    FunctionDIs[NewFunc] = SP;
+  }
+  NewFunc->takeName(F);
+  DM.GetTypeSystem().EraseFunctionAnnotation(F);
+  F->eraseFromParent();
+  DM.GetTypeSystem().AddFunctionAnnotation(NewFunc);
+  return NewFunc;
+}
+
 class DxilEmitMetadata : public ModulePass {
 class DxilEmitMetadata : public ModulePass {
 public:
 public:
   static char ID; // Pass identification, replacement for typeid
   static char ID; // Pass identification, replacement for typeid
@@ -2586,8 +2619,26 @@ public:
         }
         }
       }
       }
 
 
-      M.GetDxilModule().CollectShaderFlags(); // Update flags to reflect any changes.
-      M.GetDxilModule().EmitDxilMetadata();
+      DxilModule &DM = M.GetDxilModule();
+      DenseMap<const Function *, DISubprogram *> FunctionDIs =
+          makeSubprogramMap(M);
+      if (Function *PatchConstantFunc = DM.GetPatchConstantFunction()) {
+        PatchConstantFunc =
+            StripFunctionParameter(PatchConstantFunc, DM, FunctionDIs);
+        if (PatchConstantFunc)
+          DM.SetPatchConstantFunction(PatchConstantFunc);
+      }
+
+      if (Function *EntryFunc = DM.GetEntryFunction()) {
+        StringRef Name = DM.GetEntryFunctionName();
+        EntryFunc->setName(Name);
+        EntryFunc = StripFunctionParameter(EntryFunc, DM, FunctionDIs);
+        if (EntryFunc)
+          DM.SetEntryFunction(EntryFunc);
+      }
+
+      DM.CollectShaderFlags(); // Update flags to reflect any changes.
+      DM.EmitDxilMetadata();
       return true;
       return true;
     }
     }
 
 

+ 4 - 7
lib/HLSL/DxilValidation.cpp

@@ -216,7 +216,7 @@ const char *hlsl::GetValidationRuleText(ValidationRule value) {
     case hlsl::ValidationRule::FlowReducible: return "Execution flow must be reducible";
     case hlsl::ValidationRule::FlowReducible: return "Execution flow must be reducible";
     case hlsl::ValidationRule::FlowNoRecusion: return "Recursion is not permitted";
     case hlsl::ValidationRule::FlowNoRecusion: return "Recursion is not permitted";
     case hlsl::ValidationRule::FlowDeadLoop: return "Loop must have break";
     case hlsl::ValidationRule::FlowDeadLoop: return "Loop must have break";
-    case hlsl::ValidationRule::FlowFunctionCall: return "Function call on user defined function with parameter %0 is not permitted, it should be inlined";
+    case hlsl::ValidationRule::FlowFunctionCall: return "Function %0 with parameter is not permitted, it should be inlined";
     case hlsl::ValidationRule::DeclDxilNsReserved: return "Declaration '%0' uses a reserved prefix";
     case hlsl::ValidationRule::DeclDxilNsReserved: return "Declaration '%0' uses a reserved prefix";
     case hlsl::ValidationRule::DeclDxilFnExtern: return "External function '%0' is not a DXIL function";
     case hlsl::ValidationRule::DeclDxilFnExtern: return "External function '%0' is not a DXIL function";
     case hlsl::ValidationRule::DeclUsedInternal: return "Internal declaration '%0' is unused";
     case hlsl::ValidationRule::DeclUsedInternal: return "Internal declaration '%0' is unused";
@@ -2529,12 +2529,9 @@ static void ValidateFunction(Function &F, ValidationContext &ValCtx) {
   if (F.isDeclaration()) {
   if (F.isDeclaration()) {
     ValidateExternalFunction(&F, ValCtx);
     ValidateExternalFunction(&F, ValCtx);
   } else {
   } else {
-    if (&F != ValCtx.DxilMod.GetEntryFunction() &&
-        &F != ValCtx.DxilMod.GetPatchConstantFunction()) {
-      if (!F.arg_empty())
-        ValCtx.EmitFormatError(ValidationRule::FlowFunctionCall,
-                               {F.getName().str().c_str()});
-    }
+    if (!F.arg_empty())
+      ValCtx.EmitFormatError(ValidationRule::FlowFunctionCall,
+                             {F.getName().str().c_str()});
 
 
     DxilFunctionAnnotation *funcAnnotation =
     DxilFunctionAnnotation *funcAnnotation =
         ValCtx.DxilMod.GetTypeSystem().GetFunctionAnnotation(&F);
         ValCtx.DxilMod.GetTypeSystem().GetFunctionAnnotation(&F);

+ 13 - 25
lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp

@@ -4133,35 +4133,23 @@ void SROA_Parameter_HLSL::flattenArgument(
 void SROA_Parameter_HLSL::moveFunctionBody(Function *F, Function *flatF) {
 void SROA_Parameter_HLSL::moveFunctionBody(Function *F, Function *flatF) {
   bool updateRetType = F->getReturnType() != flatF->getReturnType();
   bool updateRetType = F->getReturnType() != flatF->getReturnType();
 
 
-  // Clone blocks and move instructions.
-  std::unordered_map<Value *, Value *> VMap;
-  Function::BasicBlockListType &blockList = F->getBasicBlockList();
-  for (BasicBlock &BB : blockList) {
-    BasicBlock *NewBB = BasicBlock::Create(BB.getContext(), "", flatF);
-    if (BB.hasName()) NewBB->setName(BB.getName());
-    // Add basic block mapping.
-    VMap[&BB] = NewBB;
-    // Update block uses.
-    BB.replaceAllUsesWith(NewBB);
-    // Move intrinsictions to NewBB.
-    NewBB->getInstList().splice(NewBB->begin(), BB.getInstList());
-  }
+  // Splice the body of the old function right into the new function.
+  flatF->getBasicBlockList().splice(flatF->begin(), F->getBasicBlockList());
+
   // Update Block uses.
   // Update Block uses.
-  for (BasicBlock &BB : blockList) {
-    BasicBlock *NewBB = cast<BasicBlock>(VMap[&BB]);
-    if (updateRetType) {
-      // Replace ret with ret void.
-      if (ReturnInst *RI = dyn_cast<ReturnInst>(NewBB->getTerminator())) {
-        // Create store for return.
-        IRBuilder<> Builder(RI);
-        Builder.CreateRetVoid();
-        RI->eraseFromParent();
+  if (updateRetType) {
+    for (BasicBlock &BB : flatF->getBasicBlockList()) {
+      if (updateRetType) {
+        // Replace ret with ret void.
+        if (ReturnInst *RI = dyn_cast<ReturnInst>(BB.getTerminator())) {
+          // Create store for return.
+          IRBuilder<> Builder(RI);
+          Builder.CreateRetVoid();
+          RI->eraseFromParent();
+        }
       }
       }
     }
     }
   }
   }
-
-  // Cleanup the original function.
-  F->getBasicBlockList().clear();  
 }
 }
 
 
 static void SplitArrayCopy(Value *V) {
 static void SplitArrayCopy(Value *V) {

+ 1 - 1
tools/clang/test/CodeGenHLSL/recursive.hlsl

@@ -1,7 +1,7 @@
 // RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
 // RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
 
 
 // CHECK: Recursion is not permitted
 // CHECK: Recursion is not permitted
-// CHECK: Function call on user defined function
+// CHECK: with parameter is not permitted
 
 
 void test_inout(inout float4 m, float4 a) 
 void test_inout(inout float4 m, float4 a) 
 {
 {

+ 1 - 1
tools/clang/unittests/HLSL/ExtensionTest.cpp

@@ -455,7 +455,7 @@ TEST_F(ExtensionTest, IntrinsicWhenAvailableThenUsed) {
   // - second argument is float, ie it got scalarized
   // - second argument is float, ie it got scalarized
   VERIFY_IS_TRUE(
   VERIFY_IS_TRUE(
     disassembly.npos !=
     disassembly.npos !=
-    disassembly.find("call void @\"test.\\01?test_proc@hlsl@@YAXV?$vector@M$01@@@Z.r\"(i32 2, float %6)"));
+    disassembly.find("call void @\"test.\\01?test_proc@hlsl@@YAXV?$vector@M$01@@@Z.r\"(i32 2, float"));
   VERIFY_IS_TRUE(
   VERIFY_IS_TRUE(
     disassembly.npos !=
     disassembly.npos !=
     disassembly.find("call float @\"test.\\01?test_fn@hlsl@@YA?AV?$vector@M$01@@V2@@Z.r\"(i32 1, float"));
     disassembly.find("call float @\"test.\\01?test_fn@hlsl@@YA?AV?$vector@M$01@@V2@@Z.r\"(i32 1, float"));

+ 79 - 62
tools/clang/unittests/HLSL/ValidationTest.cpp

@@ -15,6 +15,7 @@
 
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Regex.h"
 #include "llvm/Support/Regex.h"
+#include "llvm/ADT/ArrayRef.h"
 
 
 #include <atlbase.h>
 #include <atlbase.h>
 
 
@@ -120,6 +121,7 @@ public:
   TEST_METHOD(MinPrecisionBitCast)
   TEST_METHOD(MinPrecisionBitCast)
   TEST_METHOD(StructBitCast)
   TEST_METHOD(StructBitCast)
   TEST_METHOD(MultiDimArray)
   TEST_METHOD(MultiDimArray)
+  TEST_METHOD(NoFunctionParam)
 
 
   TEST_METHOD(ClipCullMaxComponents)
   TEST_METHOD(ClipCullMaxComponents)
   TEST_METHOD(ClipCullMaxRows)
   TEST_METHOD(ClipCullMaxRows)
@@ -281,7 +283,7 @@ public:
   }
   }
 
 
   void RewriteAssemblyCheckMsg(LPCSTR pSource, LPCSTR pShaderModel,
   void RewriteAssemblyCheckMsg(LPCSTR pSource, LPCSTR pShaderModel,
-                               LPCSTR pLookFor, LPCSTR pReplacement,
+                               llvm::ArrayRef<LPCSTR> pLookFors, llvm::ArrayRef<LPCSTR> pReplacements,
                                LPCSTR pErrorMsg, bool bRegex = false) {
                                LPCSTR pErrorMsg, bool bRegex = false) {
     CComPtr<IDxcBlob> pText;
     CComPtr<IDxcBlob> pText;
     CComPtr<IDxcBlobEncoding> pSourceBlob;
     CComPtr<IDxcBlobEncoding> pSourceBlob;
@@ -292,7 +294,7 @@ public:
 
 
     Utf8ToBlob(m_dllSupport, pSource, &pSourceBlob);
     Utf8ToBlob(m_dllSupport, pSource, &pSourceBlob);
 
 
-    RewriteAssemblyToText(pSourceBlob, pShaderModel, pLookFor, pReplacement, &pText, bRegex);
+    RewriteAssemblyToText(pSourceBlob, pShaderModel, pLookFors, pReplacements, &pText, bRegex);
 
 
     CComPtr<IDxcAssembler> pAssembler;
     CComPtr<IDxcAssembler> pAssembler;
     CComPtr<IDxcOperationResult> pAssembleResult;
     CComPtr<IDxcOperationResult> pAssembleResult;
@@ -309,42 +311,46 @@ public:
   }
   }
 
 
   void RewriteAssemblyToText(IDxcBlobEncoding *pSource, LPCSTR pShaderModel,
   void RewriteAssemblyToText(IDxcBlobEncoding *pSource, LPCSTR pShaderModel,
-                             LPCSTR pLookFor, LPCSTR pReplacement,
+                             llvm::ArrayRef<LPCSTR> pLookFors, llvm::ArrayRef<LPCSTR> pReplacements,
                              IDxcBlob **pBlob, bool bRegex = false) {
                              IDxcBlob **pBlob, bool bRegex = false) {
     CComPtr<IDxcBlob> pProgram;
     CComPtr<IDxcBlob> pProgram;
     std::string disassembly;
     std::string disassembly;
     CompileSource(pSource, pShaderModel, &pProgram);
     CompileSource(pSource, pShaderModel, &pProgram);
     DisassembleProgram(pProgram, &disassembly);
     DisassembleProgram(pProgram, &disassembly);
-    if (pLookFor && *pLookFor) {
-      if (bRegex) {
-        llvm::Regex RE(pLookFor);
-        std::string reErrors;
-        VERIFY_IS_TRUE(RE.isValid(reErrors));
-        std::string replaced = RE.sub(pReplacement, disassembly, &reErrors);
-        VERIFY_ARE_NOT_EQUAL(disassembly, replaced);
-        VERIFY_IS_TRUE(reErrors.empty());
-        disassembly = std::move(replaced);
-      } else {
-        bool found = false;
-        size_t pos = 0;
-        size_t lookForLen = strlen(pLookFor);
-        size_t replaceLen = strlen(pReplacement);
-        for (;;) {
-          pos = disassembly.find(pLookFor, pos);
-          if (pos == std::string::npos)
-            break;
-          found = true; // at least once
-          disassembly.replace(pos, lookForLen, pReplacement);
-          pos += replaceLen;
+    for (unsigned i = 0; i < pLookFors.size(); ++i) {
+      LPCSTR pLookFor = pLookFors[i];
+      LPCSTR pReplacement = pReplacements[i];
+      if (pLookFor && *pLookFor) {
+        if (bRegex) {
+          llvm::Regex RE(pLookFor);
+          std::string reErrors;
+          VERIFY_IS_TRUE(RE.isValid(reErrors));
+          std::string replaced = RE.sub(pReplacement, disassembly, &reErrors);
+          VERIFY_ARE_NOT_EQUAL(disassembly, replaced);
+          VERIFY_IS_TRUE(reErrors.empty());
+          disassembly = std::move(replaced);
+        } else {
+          bool found = false;
+          size_t pos = 0;
+          size_t lookForLen = strlen(pLookFor);
+          size_t replaceLen = strlen(pReplacement);
+          for (;;) {
+            pos = disassembly.find(pLookFor, pos);
+            if (pos == std::string::npos)
+              break;
+            found = true; // at least once
+            disassembly.replace(pos, lookForLen, pReplacement);
+            pos += replaceLen;
+          }
+          VERIFY_IS_TRUE(found);
         }
         }
-        VERIFY_IS_TRUE(found);
       }
       }
     }
     }
     Utf8ToBlob(m_dllSupport, disassembly.c_str(), pBlob);
     Utf8ToBlob(m_dllSupport, disassembly.c_str(), pBlob);
   }
   }
   
   
   void RewriteAssemblyCheckMsg(LPCWSTR name, LPCSTR pShaderModel,
   void RewriteAssemblyCheckMsg(LPCWSTR name, LPCSTR pShaderModel,
-                               LPCSTR pLookFor, LPCSTR pReplacement,
+                               llvm::ArrayRef<LPCSTR> pLookFors, llvm::ArrayRef<LPCSTR> pReplacements,
                                LPCSTR pErrorMsg, bool bRegex = false) {
                                LPCSTR pErrorMsg, bool bRegex = false) {
     std::wstring fullPath = hlsl_test::GetPathToHlslDataFile(name);
     std::wstring fullPath = hlsl_test::GetPathToHlslDataFile(name);
     CComPtr<IDxcLibrary> pLibrary;
     CComPtr<IDxcLibrary> pLibrary;
@@ -358,7 +364,7 @@ public:
 
 
     CComPtr<IDxcBlob> pText;
     CComPtr<IDxcBlob> pText;
 
 
-    RewriteAssemblyToText(pSource, pShaderModel, pLookFor, pReplacement, &pText);
+    RewriteAssemblyToText(pSource, pShaderModel, pLookFors, pReplacements, &pText);
 
 
     CComPtr<IDxcAssembler> pAssembler;
     CComPtr<IDxcAssembler> pAssembler;
     CComPtr<IDxcOperationResult> pAssembleResult;
     CComPtr<IDxcOperationResult> pAssembleResult;
@@ -553,7 +559,8 @@ TEST_F(ValidationTest, WhenIncorrectPSThenFail) {
 
 
 TEST_F(ValidationTest, WhenSmUnknownThenFail) {
 TEST_F(ValidationTest, WhenSmUnknownThenFail) {
   RewriteAssemblyCheckMsg("float4 main() : SV_Target { return 1; }", "ps_6_0",
   RewriteAssemblyCheckMsg("float4 main() : SV_Target { return 1; }", "ps_6_0",
-                          "{!\"ps\", i32 6, i32 0}", "{!\"ps\", i32 1, i32 2}",
+                          {"{!\"ps\", i32 6, i32 0}"},
+                          {"{!\"ps\", i32 1, i32 2}"},
                           "Unknown shader model 'ps_1_2'");
                           "Unknown shader model 'ps_1_2'");
 }
 }
 
 
@@ -857,15 +864,15 @@ TEST_F(ValidationTest, PsOutputSemantic) {
 TEST_F(ValidationTest, ArrayOfSVTarget) {
 TEST_F(ValidationTest, ArrayOfSVTarget) {
     RewriteAssemblyCheckMsg(
     RewriteAssemblyCheckMsg(
       L"..\\CodeGenHLSL\\targetArray.hlsl", "ps_6_0",
       L"..\\CodeGenHLSL\\targetArray.hlsl", "ps_6_0",
-      "i32 6, !\"SV_Target\", i8 9, i8 16, !36, i8 0, i32 1",
-      "i32 6, !\"SV_Target\", i8 9, i8 16, !36, i8 0, i32 2",
+      "i32 6, !\"SV_Target\", i8 9, i8 16, !32, i8 0, i32 1",
+      "i32 6, !\"SV_Target\", i8 9, i8 16, !32, i8 0, i32 2",
       "Pixel shader output registers are not indexable.");
       "Pixel shader output registers are not indexable.");
 }
 }
 
 
 TEST_F(ValidationTest, InfiniteLog) {
 TEST_F(ValidationTest, InfiniteLog) {
     RewriteAssemblyCheckMsg(
     RewriteAssemblyCheckMsg(
       L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_6_0",
       L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_6_0",
-      "op.unary.f32(i32 22, float %3)",
+      "op.unary.f32(i32 22, float %1)",
       "op.unary.f32(i32 22, float 0x7FF0000000000000)",
       "op.unary.f32(i32 22, float 0x7FF0000000000000)",
       "No indefinite logarithm");
       "No indefinite logarithm");
 }
 }
@@ -873,7 +880,7 @@ TEST_F(ValidationTest, InfiniteLog) {
 TEST_F(ValidationTest, InfiniteAsin) {
 TEST_F(ValidationTest, InfiniteAsin) {
     RewriteAssemblyCheckMsg(
     RewriteAssemblyCheckMsg(
       L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_6_0",
       L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_6_0",
-      "op.unary.f32(i32 16, float %3)",
+      "op.unary.f32(i32 16, float %1)",
       "op.unary.f32(i32 16, float 0x7FF0000000000000)",
       "op.unary.f32(i32 16, float 0x7FF0000000000000)",
       "No indefinite arcsine");
       "No indefinite arcsine");
 }
 }
@@ -881,7 +888,7 @@ TEST_F(ValidationTest, InfiniteAsin) {
 TEST_F(ValidationTest, InfiniteAcos) {
 TEST_F(ValidationTest, InfiniteAcos) {
     RewriteAssemblyCheckMsg(
     RewriteAssemblyCheckMsg(
       L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_6_0",
       L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_6_0",
-      "op.unary.f32(i32 15, float %3)",
+      "op.unary.f32(i32 15, float %1)",
       "op.unary.f32(i32 15, float 0x7FF0000000000000)",
       "op.unary.f32(i32 15, float 0x7FF0000000000000)",
       "No indefinite arccosine");
       "No indefinite arccosine");
 }
 }
@@ -889,7 +896,7 @@ TEST_F(ValidationTest, InfiniteAcos) {
 TEST_F(ValidationTest, InfiniteDdxDdy) {
 TEST_F(ValidationTest, InfiniteDdxDdy) {
     RewriteAssemblyCheckMsg(
     RewriteAssemblyCheckMsg(
       L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_6_0",
       L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_6_0",
-      "op.unary.f32(i32 86, float %3)",
+      "op.unary.f32(i32 86, float %1)",
       "op.unary.f32(i32 86, float 0x7FF0000000000000)",
       "op.unary.f32(i32 86, float 0x7FF0000000000000)",
       "No indefinite derivative calculation");
       "No indefinite derivative calculation");
 }
 }
@@ -897,16 +904,16 @@ TEST_F(ValidationTest, InfiniteDdxDdy) {
 TEST_F(ValidationTest, IDivByZero) {
 TEST_F(ValidationTest, IDivByZero) {
     RewriteAssemblyCheckMsg(
     RewriteAssemblyCheckMsg(
       L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_6_0",
       L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_6_0",
-      "sdiv i32 %8, %9",
-      "sdiv i32 %8, 0",
+      "sdiv i32 %6, %7",
+      "sdiv i32 %6, 0",
       "No signed integer division by zero");
       "No signed integer division by zero");
 }
 }
 
 
 TEST_F(ValidationTest, UDivByZero) {
 TEST_F(ValidationTest, UDivByZero) {
     RewriteAssemblyCheckMsg(
     RewriteAssemblyCheckMsg(
       L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_6_0",
       L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_6_0",
-      "udiv i32 %5, %6",
-      "udiv i32 %5, 0",
+      "udiv i32 %3, %4",
+      "udiv i32 %3, 0",
       "No unsigned integer division by zero");
       "No unsigned integer division by zero");
 }
 }
 
 
@@ -919,59 +926,66 @@ TEST_F(ValidationTest, UnusedMetadata) {
 
 
 TEST_F(ValidationTest, MemoryOutOfBound) {
 TEST_F(ValidationTest, MemoryOutOfBound) {
   RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\targetArray.hlsl", "ps_6_0",
   RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\targetArray.hlsl", "ps_6_0",
-                          "getelementptr [4 x float], [4 x float]* %12, i32 0, i32 3",
-                          "getelementptr [4 x float], [4 x float]* %12, i32 0, i32 10",
+                          "getelementptr [4 x float], [4 x float]* %7, i32 0, i32 3",
+                          "getelementptr [4 x float], [4 x float]* %7, i32 0, i32 10",
                           "Access to out-of-bounds memory is disallowed");
                           "Access to out-of-bounds memory is disallowed");
 }
 }
 
 
 TEST_F(ValidationTest, AddrSpaceCast) {
 TEST_F(ValidationTest, AddrSpaceCast) {
   RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\staticGlobals.hlsl", "ps_6_0",
   RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\staticGlobals.hlsl", "ps_6_0",
-                          "%12 = getelementptr [4 x float], [4 x float]* %1, i32 0, i32 0\n"
-                          "  store float %11, float* %12, align 4",
-                          "%12 = getelementptr [4 x float], [4 x float]* %1, i32 0, i32 0\n"
-                          "  %X = addrspacecast float* %12 to float addrspace(1)*    \n"
-                          "  store float %11, float addrspace(1)* %X, align 4",
+                          "%11 = getelementptr [4 x float], [4 x float]* %0, i32 0, i32 0\n"
+                          "  store float %10, float* %11, align 4",
+                          "%11 = getelementptr [4 x float], [4 x float]* %0, i32 0, i32 0\n"
+                          "  %X = addrspacecast float* %11 to float addrspace(1)*    \n"
+                          "  store float %10, float addrspace(1)* %X, align 4",
                           "generic address space");
                           "generic address space");
 }
 }
 
 
 TEST_F(ValidationTest, PtrBitCast) {
 TEST_F(ValidationTest, PtrBitCast) {
   RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\staticGlobals.hlsl", "ps_6_0",
   RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\staticGlobals.hlsl", "ps_6_0",
-                          "%12 = getelementptr [4 x float], [4 x float]* %1, i32 0, i32 0\n"
-                          "  store float %11, float* %12, align 4",
-                          "%12 = getelementptr [4 x float], [4 x float]* %1, i32 0, i32 0\n"
-                          "  %X = bitcast float* %12 to double*    \n"
-                          "  store float %11, float* %12, align 4",
+                          "%11 = getelementptr [4 x float], [4 x float]* %0, i32 0, i32 0\n"
+                          "  store float %10, float* %11, align 4",
+                          "%11 = getelementptr [4 x float], [4 x float]* %0, i32 0, i32 0\n"
+                          "  %X = bitcast float* %11 to double*    \n"
+                          "  store float %10, float* %11, align 4",
                           "Pointer type bitcast must be have same size");
                           "Pointer type bitcast must be have same size");
 }
 }
 
 
 TEST_F(ValidationTest, MinPrecisionBitCast) {
 TEST_F(ValidationTest, MinPrecisionBitCast) {
   RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\staticGlobals.hlsl", "ps_6_0",
   RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\staticGlobals.hlsl", "ps_6_0",
-                          "%12 = getelementptr [4 x float], [4 x float]* %1, i32 0, i32 0\n"
-                          "  store float %11, float* %12, align 4",
-                          "%12 = getelementptr [4 x float], [4 x float]* %1, i32 0, i32 0\n"
-                          "  %X = bitcast float* %12 to [2 x half]*    \n"
-                          "  store float %11, float* %12, align 4",
+                          "%11 = getelementptr [4 x float], [4 x float]* %0, i32 0, i32 0\n"
+                          "  store float %10, float* %11, align 4",
+                          "%11 = getelementptr [4 x float], [4 x float]* %0, i32 0, i32 0\n"
+                          "  %X = bitcast float* %11 to [2 x half]*    \n"
+                          "  store float %10, float* %11, align 4",
                           "Bitcast on minprecison types is not allowed");
                           "Bitcast on minprecison types is not allowed");
 }
 }
 
 
 TEST_F(ValidationTest, StructBitCast) {
 TEST_F(ValidationTest, StructBitCast) {
   RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\staticGlobals.hlsl", "ps_6_0",
   RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\staticGlobals.hlsl", "ps_6_0",
-                          "%12 = getelementptr [4 x float], [4 x float]* %1, i32 0, i32 0\n"
-                          "  store float %11, float* %12, align 4",
-                          "%12 = getelementptr [4 x float], [4 x float]* %1, i32 0, i32 0\n"
-                          "  %X = bitcast float* %12 to %dx.types.Handle*    \n"
-                          "  store float %11, float* %12, align 4",
+                          "%11 = getelementptr [4 x float], [4 x float]* %0, i32 0, i32 0\n"
+                          "  store float %10, float* %11, align 4",
+                          "%11 = getelementptr [4 x float], [4 x float]* %0, i32 0, i32 0\n"
+                          "  %X = bitcast float* %11 to %dx.types.Handle*    \n"
+                          "  store float %10, float* %11, align 4",
                           "Bitcast on struct types is not allowed");
                           "Bitcast on struct types is not allowed");
 }
 }
 
 
 TEST_F(ValidationTest, MultiDimArray) {
 TEST_F(ValidationTest, MultiDimArray) {
   RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\staticGlobals.hlsl", "ps_6_0",
   RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\staticGlobals.hlsl", "ps_6_0",
-                          "%1 = alloca [4 x float]",
-                          "%1 = alloca [4 x float]\n"
+                          "%0 = alloca [4 x float]",
+                          "%0 = alloca [4 x float]\n"
                           "  %md = alloca [2 x [4 x float]]",
                           "  %md = alloca [2 x [4 x float]]",
                           "Only one dimension allowed for array type");
                           "Only one dimension allowed for array type");
 }
 }
 
 
+TEST_F(ValidationTest, NoFunctionParam) {
+  RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\abs2.hlsl", "ps_6_0",
+                          {"define void @main()", "void ()* @main", "!5 = !{!6}"},
+                          {"define void @main(<4 x i32> %mainArg)", "void (<4 x i32>)* @main", "!5 = !{!6, !6}"},
+                          "with parameter is not permitted");
+}
+
 TEST_F(ValidationTest, WhenWaveAffectsGradientThenFail) {
 TEST_F(ValidationTest, WhenWaveAffectsGradientThenFail) {
   TestCheck(L"val-wave-failures-ps.hlsl");
   TestCheck(L"val-wave-failures-ps.hlsl");
 }
 }
@@ -1630,9 +1644,11 @@ void main( \
     "vs_6_0",
     "vs_6_0",
 
 
     "!{i32 1, !\"Array\", i8 5, i8 0, !([0-9]+), i8 1, i32 2, i8 1, i32 1, i8 0, null}\n"
     "!{i32 1, !\"Array\", i8 5, i8 0, !([0-9]+), i8 1, i32 2, i8 1, i32 1, i8 0, null}\n"
+    "!17 = !{i32 0, i32 1}\n"
     "!([0-9]+) = !{i32 2, !\"Value\", i8 5, i8 0, !([0-9]+), i8 1, i32 1, i8 3, i32 1, i8 1, null}",
     "!([0-9]+) = !{i32 2, !\"Value\", i8 5, i8 0, !([0-9]+), i8 1, i32 1, i8 3, i32 1, i8 1, null}",
 
 
     "!{i32 1, !\"Array\", i8 5, i8 0, !\\1, i8 1, i32 2, i8 1, i32 1, i8 1, null}\n"
     "!{i32 1, !\"Array\", i8 5, i8 0, !\\1, i8 1, i32 2, i8 1, i32 1, i8 1, null}\n"
+    "!17 = !{i32 0, i32 1}\n"
     "!\\2 = !{i32 2, !\"Value\", i8 5, i8 0, !\\3, i8 1, i32 1, i8 3, i32 2, i8 0, null}",
     "!\\2 = !{i32 2, !\"Value\", i8 5, i8 0, !\\3, i8 1, i32 1, i8 3, i32 2, i8 0, null}",
 
 
     "signature element Value at location \\(2,0\\) size \\(1,3\\) overlaps another signature element.",
     "signature element Value at location \\(2,0\\) size \\(1,3\\) overlaps another signature element.",
@@ -1647,6 +1663,7 @@ float4 main(float4 f4 : Input, out float d0 : SV_Depth, out float d1 : SV_Target
     "ps_6_0",
     "ps_6_0",
 
 
     "!{i32 1, !\"SV_Target\", i8 9, i8 16, !([0-9]+), i8 0, i32 1, i8 1, i32 1, i8 0, null}\n"
     "!{i32 1, !\"SV_Target\", i8 9, i8 16, !([0-9]+), i8 0, i32 1, i8 1, i32 1, i8 0, null}\n"
+    "!16 = !{i32 1}\n"
     "!([0-9]+) = !{i32 2, !\"SV_Target\", i8 9, i8 16, !([0-9]+), i8 0, i32 1, i8 4, i32 0, i8 0, null}",
     "!([0-9]+) = !{i32 2, !\"SV_Target\", i8 9, i8 16, !([0-9]+), i8 0, i32 1, i8 4, i32 0, i8 0, null}",
 
 
     "!{i32 1, !\"SV_DepthGreaterEqual\", i8 9, i8 19, !\\3, i8 0, i32 1, i8 1, i32 -1, i8 -1, null}\n"
     "!{i32 1, !\"SV_DepthGreaterEqual\", i8 9, i8 19, !\\3, i8 0, i32 1, i8 1, i32 -1, i8 -1, null}\n"

+ 1 - 1
utils/hct/hctdb.py

@@ -1563,7 +1563,7 @@ class db_dxil(object):
         self.add_valrule("Flow.Reducible", "Execution flow must be reducible")
         self.add_valrule("Flow.Reducible", "Execution flow must be reducible")
         self.add_valrule("Flow.NoRecusion", "Recursion is not permitted")
         self.add_valrule("Flow.NoRecusion", "Recursion is not permitted")
         self.add_valrule("Flow.DeadLoop", "Loop must have break")
         self.add_valrule("Flow.DeadLoop", "Loop must have break")
-        self.add_valrule_msg("Flow.FunctionCall", "Function call on user defined function with parameter is not permitted", "Function call on user defined function with parameter %0 is not permitted, it should be inlined")
+        self.add_valrule_msg("Flow.FunctionCall", "Function with parameter is not permitted", "Function %0 with parameter is not permitted, it should be inlined")
 
 
         self.add_valrule_msg("Decl.DxilNsReserved", "The DXIL reserved prefixes must only be used by built-in functions and types", "Declaration '%0' uses a reserved prefix")
         self.add_valrule_msg("Decl.DxilNsReserved", "The DXIL reserved prefixes must only be used by built-in functions and types", "Declaration '%0' uses a reserved prefix")
         self.add_valrule_msg("Decl.DxilFnExtern", "External function must be a DXIL function", "External function '%0' is not a DXIL function")
         self.add_valrule_msg("Decl.DxilFnExtern", "External function must be a DXIL function", "External function '%0' is not a DXIL function")