From e75e9bf034cf30068bc76b6973831bbe42219a75 Mon Sep 17 00:00:00 2001 From: Natalie Chouinard Date: Mon, 2 May 2022 19:39:09 +0000 Subject: [PATCH 1/4] [dxil2spv] Add FileCheck-style testing Add FileCheck-style testing to dxil2spv, and a first static vertex shader test case to test #4426. Also includes documentation for how to add additional tests. --- tools/clang/test/Dxil2Spv/static-vertex.hlsl | 10 ++ tools/clang/test/Dxil2Spv/static-vertex.ll | 113 +++++++++++++++++ tools/clang/unittests/Dxil2Spv/CMakeLists.txt | 13 +- .../unittests/Dxil2Spv/FileTestFixture.cpp | 114 ++++++++++++++++++ .../unittests/Dxil2Spv/FileTestFixture.h | 64 ++++++++++ tools/clang/unittests/Dxil2Spv/LitTest.cpp | 4 + tools/clang/unittests/Dxil2Spv/README.md | 73 +++++++++++ .../Dxil2Spv/WholeFileTestFixture.cpp | 2 +- 8 files changed, 386 insertions(+), 7 deletions(-) create mode 100644 tools/clang/test/Dxil2Spv/static-vertex.hlsl create mode 100644 tools/clang/test/Dxil2Spv/static-vertex.ll create mode 100644 tools/clang/unittests/Dxil2Spv/FileTestFixture.cpp create mode 100644 tools/clang/unittests/Dxil2Spv/FileTestFixture.h create mode 100644 tools/clang/unittests/Dxil2Spv/README.md diff --git a/tools/clang/test/Dxil2Spv/static-vertex.hlsl b/tools/clang/test/Dxil2Spv/static-vertex.hlsl new file mode 100644 index 0000000000..8c067f729e --- /dev/null +++ b/tools/clang/test/Dxil2Spv/static-vertex.hlsl @@ -0,0 +1,10 @@ +// dxc -T ps_6_0 static-vertex.hlsl -Fc static-vertex.ll +struct VSOutput { + float4 Position : SV_POSITION; + float3 Color : COLOR; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + return float4(input.Color, 1); +}; diff --git a/tools/clang/test/Dxil2Spv/static-vertex.ll b/tools/clang/test/Dxil2Spv/static-vertex.ll new file mode 100644 index 0000000000..0032882e16 --- /dev/null +++ b/tools/clang/test/Dxil2Spv/static-vertex.ll @@ -0,0 +1,113 @@ +; RUN: %dxil2spv +; +; Input signature: +; +; Name Index Mask Register SysValue Format Used +; -------------------- ----- ------ -------- -------- ------- ------ +; SV_Position 0 xyzw 0 POS float +; COLOR 0 xyz 1 NONE float xyz +; +; +; Output signature: +; +; Name Index Mask Register SysValue Format Used +; -------------------- ----- ------ -------- -------- ------- ------ +; SV_Target 0 xyzw 0 TARGET float xyzw +; +; shader hash: c23cfb9164637d35921d87c5895173ea +; +; Pipeline Runtime Information: +; +; Pixel Shader +; DepthOutput=0 +; SampleFrequency=0 +; +; +; Input signature: +; +; Name Index InterpMode DynIdx +; -------------------- ----- ---------------------- ------ +; SV_Position 0 noperspective +; COLOR 0 linear +; +; Output signature: +; +; Name Index InterpMode DynIdx +; -------------------- ----- ---------------------- ------ +; SV_Target 0 +; +; Buffer Definitions: +; +; +; Resource Bindings: +; +; Name Type Format Dim ID HLSL Bind Count +; ------------------------------ ---------- ------- ----------- ------- -------------- ------ +; +; +; ViewId state: +; +; Number of inputs: 7, outputs: 4 +; Outputs dependent on ViewId: { } +; Inputs contributing to computation of Outputs: +; output 0 depends on inputs: { 4 } +; output 1 depends on inputs: { 5 } +; output 2 depends on inputs: { 6 } +; +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" + +; CHECK: %float_1 = OpConstant %float 1 + +define void @main() { +; CHECK: %gl_Position = OpVariable %_ptr_Input_v4float Input + %1 = call float @dx.op.loadInput.f32(i32 4, i32 1, i32 0, i8 0, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis) + +; CHECK: %COLOR = OpVariable %_ptr_Input_v3float Input + %2 = call float @dx.op.loadInput.f32(i32 4, i32 1, i32 0, i8 1, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis) + +; CHECK: %SV_Target = OpVariable %_ptr_Output_v4float Output + %3 = call float @dx.op.loadInput.f32(i32 4, i32 1, i32 0, i8 2, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis) + + call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %1) ; StoreOutput(outputSigId,rowIndex,colIndex,value) + call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float %2) ; StoreOutput(outputSigId,rowIndex,colIndex,value) + call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float %3) ; StoreOutput(outputSigId,rowIndex,colIndex,value) + +; CHECK: [[v0:%\d+]] = OpAccessChain %_ptr_Output_float %SV_Target %uint_3 +; CHECK: OpStore [[v0]] %float_1 + call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float 1.000000e+00) ; StoreOutput(outputSigId,rowIndex,colIndex,value) + ret void +} + +; Function Attrs: nounwind readnone +declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #0 + +; Function Attrs: nounwind +declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #1 + +attributes #0 = { nounwind readnone } +attributes #1 = { nounwind } + +!llvm.ident = !{!0} +!dx.version = !{!1} +!dx.valver = !{!2} +!dx.shaderModel = !{!3} +!dx.viewIdState = !{!4} +!dx.entryPoints = !{!5} + +!0 = !{!"clang version 3.7 (tags/RELEASE_370/final)"} +!1 = !{i32 1, i32 0} +!2 = !{i32 1, i32 7} +!3 = !{!"ps", i32 6, i32 0} +!4 = !{[9 x i32] [i32 7, i32 4, i32 0, i32 0, i32 0, i32 0, i32 1, i32 2, i32 4]} +!5 = !{void ()* @main, !"main", !6, null, null} +!6 = !{!7, !12, null} +!7 = !{!8, !10} +!8 = !{i32 0, !"SV_Position", i8 9, i8 3, !9, i8 4, i32 1, i8 4, i32 0, i8 0, null} +!9 = !{i32 0} +!10 = !{i32 1, !"COLOR", i8 9, i8 0, !9, i8 2, i32 1, i8 3, i32 1, i8 0, !11} +!11 = !{i32 3, i32 7} +!12 = !{!13} +!13 = !{i32 0, !"SV_Target", i8 9, i8 16, !9, i8 0, i32 1, i8 4, i32 0, i8 0, !14} +!14 = !{i32 3, i32 15} + diff --git a/tools/clang/unittests/Dxil2Spv/CMakeLists.txt b/tools/clang/unittests/Dxil2Spv/CMakeLists.txt index e21601396e..58977f6259 100644 --- a/tools/clang/unittests/Dxil2Spv/CMakeLists.txt +++ b/tools/clang/unittests/Dxil2Spv/CMakeLists.txt @@ -1,20 +1,21 @@ set(LLVM_LINK_COMPONENTS - Support dxcsupport dxil dxilrootsignature hlsl + Support ) add_clang_unittest(clang-dxil2spv-tests - TestMain.cpp + Dxil2SpvTestOptions.cpp + Dxil2SpvTestOptions.h + FileTestFixture.cpp + FileTestUtils.cpp + FileTestUtils.h LitTest.cpp + TestMain.cpp WholeFileTestFixture.cpp WholeFileTestFixture.h - FileTestUtils.cpp - FileTestUtils.h - Dxil2SpvTestOptions.cpp - Dxil2SpvTestOptions.h ) target_link_libraries(clang-dxil2spv-tests diff --git a/tools/clang/unittests/Dxil2Spv/FileTestFixture.cpp b/tools/clang/unittests/Dxil2Spv/FileTestFixture.cpp new file mode 100644 index 0000000000..ba1986e69e --- /dev/null +++ b/tools/clang/unittests/Dxil2Spv/FileTestFixture.cpp @@ -0,0 +1,114 @@ +//===- FileTestFixture.cpp ------------- File Test Fixture Implementation -===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "FileTestFixture.h" + +#include + +#include "FileTestUtils.h" +#include "effcee/effcee.h" + +namespace clang { +namespace dxil2spv { + +bool FileTest::parseInputFile() { + std::stringstream inputSS; + std::ifstream inputFile; + inputFile.exceptions(std::ifstream::failbit); + + try { + inputFile.open(inputFilePath); + inputSS << inputFile.rdbuf(); + } catch (...) { + fprintf( + stderr, + "Error: Exception occurred while opening/reading the input file %s\n", + inputFilePath.c_str()); + return false; + } + + // Close the input file. + inputFile.close(); + checkCommands = inputSS.str(); + return parseCommand(); +} + +bool FileTest::parseCommand() { + // Effcee skips any input line which doesn't have a CHECK directive, therefore + // we can pass the entire input to effcee. This way, any warning/error message + // provided by effcee also reflects the correct line number in the input file. + const char dxilStartLabel[] = "; RUN:"; + const auto runCmdStartPos = checkCommands.find(dxilStartLabel); + if (runCmdStartPos == std::string::npos) { + fprintf(stderr, "Error: Missing \"RUN:\" command.\n"); + return false; + } + + // Everything was successful. + return true; +} + +void FileTest::runFileTest(llvm::StringRef filename, Expect expect) { + inputFilePath = utils::getAbsPathOfInputDataFile(filename); + + // Parse the input file. + ASSERT_TRUE(parseInputFile()); + + // Feed DXIL source into the translator. + std::string errorMessages; + const bool compileOk = utils::translateFileWithDxil2Spv( + inputFilePath, &generatedSpirvAsm, &errorMessages); + + checkTestResult(filename, compileOk, errorMessages, expect); +} + +void FileTest::checkTestResult(llvm::StringRef filename, const bool compileOk, + const std::string &errorMessages, + Expect expect) { + effcee::Result result(effcee::Result::Status::Ok); + + if (expect == Expect::Success) { + ASSERT_TRUE(compileOk); + + auto options = effcee::Options() + .SetChecksName(filename.str()) + .SetInputName(""); + + // Run CHECK commands via effcee on disassembly. + result = effcee::Match(generatedSpirvAsm, checkCommands, options); + + // Print effcee's error message (if any). + if (result.status() != effcee::Result::Status::Ok) { + fprintf(stderr, "%s\n", result.message().c_str()); + } + + // All checks must have passed. + ASSERT_EQ(result.status(), effcee::Result::Status::Ok); + } else { + ASSERT_FALSE(compileOk); + + auto options = effcee::Options() + .SetChecksName(filename.str()) + .SetInputName(""); + + // Run CHECK commands via effcee on error messages. + result = effcee::Match(errorMessages, checkCommands, options); + + // Print effcee's error message (if any). + if (result.status() != effcee::Result::Status::Ok) { + fprintf(stderr, "%s\n", result.message().c_str()); + } + + // All checks must have passed. + ASSERT_EQ(result.status(), effcee::Result::Status::Ok); + } +} + +} // end namespace dxil2spv +} // end namespace clang diff --git a/tools/clang/unittests/Dxil2Spv/FileTestFixture.h b/tools/clang/unittests/Dxil2Spv/FileTestFixture.h new file mode 100644 index 0000000000..2878d2f297 --- /dev/null +++ b/tools/clang/unittests/Dxil2Spv/FileTestFixture.h @@ -0,0 +1,64 @@ +//===- FileTestFixute.h ---- Test Fixture for File Check style tests ------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_UNITTESTS_DXIL2SPV_FILE_TEST_FIXTURE_H +#define LLVM_CLANG_UNITTESTS_DXIL2SPV_FILE_TEST_FIXTURE_H + +#include "spirv-tools/libspirv.h" +#include "llvm/ADT/StringRef.h" +#include "gtest/gtest.h" + +namespace clang { +namespace dxil2spv { + +class FileTest : public ::testing::Test { +public: + // Expected test result to be + enum class Expect { + Success, // Success (with or without warnings) - check disassembly + Failure, // Failure (with errors) - check error message + }; + + FileTest() {} + + // Runs a test with the given input DXIL file. + // + // The first line of code must start with "; RUN:". Next lines must be proper + // DXIL code for the test. It uses file check style output check e.g., "; + // CHECK: ...". + void runFileTest(llvm::StringRef path, Expect expect = Expect::Success); + +private: + // Reads in the given input file and parses the command to get + // arguments to run dxil2spv. + bool parseInputFile(); + + // Parses the command and gets arguments to run dxil2spv. + bool parseCommand(); + + // Checks the compile result. Reports whether the expected compile + // result matches the actual result and whether the expected validation + // result matches the actual one or not. + void checkTestResult(llvm::StringRef filename, const bool compileOk, + const std::string &errorMessages, Expect expect); + + // Path to the input test file + std::string inputFilePath; + + // CHECK commands that verify output + std::string checkCommands; + + // Disassembled binary (SPIR-V code) + std::string generatedSpirvAsm; +}; + +} // end namespace dxil2spv +} // end namespace clang + +#endif diff --git a/tools/clang/unittests/Dxil2Spv/LitTest.cpp b/tools/clang/unittests/Dxil2Spv/LitTest.cpp index 86c38ceb44..59f763423a 100644 --- a/tools/clang/unittests/Dxil2Spv/LitTest.cpp +++ b/tools/clang/unittests/Dxil2Spv/LitTest.cpp @@ -7,9 +7,11 @@ // //===----------------------------------------------------------------------===// +#include "FileTestFixture.h" #include "WholeFileTestFixture.h" namespace { +using clang::dxil2spv::FileTest; using clang::dxil2spv::WholeFileTest; TEST_F(WholeFileTest, PassThruPixelShader) { @@ -24,4 +26,6 @@ TEST_F(WholeFileTest, PassThruComputeShader) { runWholeFileTest("passthru-cs.ll"); } +TEST_F(FileTest, StaticVertexShader) { runFileTest("static-vertex.ll"); } + } // namespace diff --git a/tools/clang/unittests/Dxil2Spv/README.md b/tools/clang/unittests/Dxil2Spv/README.md new file mode 100644 index 0000000000..9034671a55 --- /dev/null +++ b/tools/clang/unittests/Dxil2Spv/README.md @@ -0,0 +1,73 @@ +# `dxil2spv` Tests + +## How to Add a Test + +These instructions assume the new test will be generated from HLSL source, +rather than hand-writing DXIL directly. Whenever this is the case, the HLSL +source should be preserved to aid in regenerating tests in future as needed +(i.e. if changes are made to `dxc` that warrant recompiling, or a new test needs +to be created as a modified version of an existing test). + +1. Create a new HLSL source file in `tools/clang/test/Dxil2Spv/`. + + For example, `my-new-test.hlsl`: + + ``` + struct VSOutput { + float4 Position : SV_POSITION; + float3 Color : COLOR; + }; + + float4 main(VSOutput input) : SV_TARGET + { + return float4(input.Color, 1); + }; + ``` + +2. Compile HLSL source file to DXIL. + + Use the appropriate `dxc` command to compile the HLSL source and output the + disassembled DXIL to a file with the same name and a `.ll` extension using + the option `-Fc`. + + For example: `dxc -T ps_6_0 my-new-test.hlsl -Fc my-new-test.ll` + +3. Add a comment the to the top of your HLSL source file with the compile + command used. + + `my-new-test.hlsl`: + + ``` + // dxc -T ps_6_0 my-new-test.hlsl -Fc my-new-test.ll + struct VSOutput { + [...] + ``` + +4. Add a `; RUN: %dxil2spv` command to the top of your DXIL test file. + + `my-new-test.ll`: + + ``` + ; RUN: %dxil2spv + ; + ; Input signature: + [...] + ``` + +5. Add `CHECK` lines to test the generated SPIR-V. + + As needed for your test, add `CHECK` lines throughout the DXIL test file. + These tests are run with `effcee`, which supports pattern matching of + strings inspired by LLVM's FileCheck command. See the `effcee` documentation + for more information about the `CHECK` types supported and pattern matching + syntax. + +6. Add the test to `tools/clang/unittests/Dxil2Spv/LitTest.cpp`. + + For example: + + ``` + TEST_F(FileTest, MyNewTest) { + runFileTest("my-new-test.ll"); + } + ``` diff --git a/tools/clang/unittests/Dxil2Spv/WholeFileTestFixture.cpp b/tools/clang/unittests/Dxil2Spv/WholeFileTestFixture.cpp index 7eb63c5c6c..5319be5c67 100644 --- a/tools/clang/unittests/Dxil2Spv/WholeFileTestFixture.cpp +++ b/tools/clang/unittests/Dxil2Spv/WholeFileTestFixture.cpp @@ -106,7 +106,7 @@ void WholeFileTest::runWholeFileTest(llvm::StringRef filename) { // Parse the input file. ASSERT_TRUE(parseInputFile()); - // Feed the HLSL source into the Compiler. + // Feed the DXIL source into the translator. ASSERT_TRUE(utils::translateFileWithDxil2Spv( inputFilePath, &generatedSpirvAsm, &generatedErrors)); From 2464dd60d4f1c6ac11067bee74a3e8f91e6982c7 Mon Sep 17 00:00:00 2001 From: Natalie Chouinard Date: Wed, 4 May 2022 20:35:29 +0000 Subject: [PATCH 2/4] Switch from effcee to FileCheck --- CMakeLists.txt | 3 + include/dxc/Test/DxcTestUtils.h | 4 + .../dxc/Test}/HLSLTestOptions.h | 21 ++-- tools/clang/test/Dxil2Spv/static-vertex.ll | 4 +- tools/clang/unittests/Dxil2Spv/CMakeLists.txt | 3 +- .../unittests/Dxil2Spv/FileTestFixture.cpp | 114 ------------------ .../unittests/Dxil2Spv/FileTestFixture.h | 64 ---------- tools/clang/unittests/Dxil2Spv/LitTest.cpp | 46 ++++++- tools/clang/unittests/Dxil2Spv/README.md | 13 +- tools/clang/unittests/HLSL/CMakeLists.txt | 2 - tools/clang/unittests/HLSL/TestMain.cpp | 2 +- .../unittests/HLSLTestLib/CMakeLists.txt | 17 +++ .../unittests/HLSLTestLib/FileCheckerTest.cpp | 81 +++++++++++-- .../{HLSL => HLSLTestLib}/HLSLTestOptions.cpp | 4 +- 14 files changed, 162 insertions(+), 216 deletions(-) rename {tools/clang/unittests/HLSL => include/dxc/Test}/HLSLTestOptions.h (63%) delete mode 100644 tools/clang/unittests/Dxil2Spv/FileTestFixture.cpp delete mode 100644 tools/clang/unittests/Dxil2Spv/FileTestFixture.h rename tools/clang/unittests/{HLSL => HLSLTestLib}/HLSLTestOptions.cpp (97%) diff --git a/CMakeLists.txt b/CMakeLists.txt index b5b1917c04..5107499a50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,6 +132,9 @@ endif() # Building dxil2spv off by default while it's in early development. option(ENABLE_DXIL2SPV "Enables DXIL to SPIR-V translation." OFF) +if (${ENABLE_DXIL2SPV}) + add_definitions(-DENABLE_DXIL2SPV) +endif() # SPIRV change ends include(VersionFromVCS) diff --git a/include/dxc/Test/DxcTestUtils.h b/include/dxc/Test/DxcTestUtils.h index 1b056bb1bf..194a64507e 100644 --- a/include/dxc/Test/DxcTestUtils.h +++ b/include/dxc/Test/DxcTestUtils.h @@ -126,6 +126,10 @@ class FileRunCommandPart { FileRunCommandResult RunTee(const FileRunCommandResult *Prior); FileRunCommandResult RunXFail(const FileRunCommandResult *Prior); FileRunCommandResult RunDxilVer(dxc::DxcDllSupport& DllSupport, const FileRunCommandResult* Prior); +#ifdef ENABLE_DXIL2SPV + FileRunCommandResult RunDxil2Spv(dxc::DxcDllSupport &DllSupport, + const FileRunCommandResult *Prior); +#endif FileRunCommandResult RunDxcHashTest(dxc::DxcDllSupport &DllSupport); FileRunCommandResult RunFromPath(const std::string &path, const FileRunCommandResult *Prior); FileRunCommandResult RunFileCompareText(const FileRunCommandResult *Prior); diff --git a/tools/clang/unittests/HLSL/HLSLTestOptions.h b/include/dxc/Test/HLSLTestOptions.h similarity index 63% rename from tools/clang/unittests/HLSL/HLSLTestOptions.h rename to include/dxc/Test/HLSLTestOptions.h index 8e05c2fa9f..6320ed515a 100644 --- a/tools/clang/unittests/HLSL/HLSLTestOptions.h +++ b/include/dxc/Test/HLSLTestOptions.h @@ -26,18 +26,19 @@ namespace hlsl { namespace testOptions { /// \brief Command line option that specifies the path to the directory that -/// contains files that have the HLSL source code (used for the CodeGen test flow). +/// contains files that have the HLSL source code (used for the CodeGen test +/// flow). #define ARG_DECLARE(argname) extern std::string argname; -#define ARG_LIST(ARGOP)\ - ARGOP(HlslDataDir)\ - ARGOP(TestName)\ - ARGOP(DXBC)\ - ARGOP(SaveImages)\ - ARGOP(ExperimentalShaders)\ - ARGOP(DebugLayer)\ - ARGOP(SuitePath)\ - ARGOP(InputPath) +#define ARG_LIST(ARGOP) \ + ARGOP(HlslDataDir) \ + ARGOP(TestName) \ + ARGOP(DXBC) \ + ARGOP(SaveImages) \ + ARGOP(ExperimentalShaders) \ + ARGOP(DebugLayer) \ + ARGOP(SuitePath) \ + ARGOP(InputPath) ARG_LIST(ARG_DECLARE) diff --git a/tools/clang/test/Dxil2Spv/static-vertex.ll b/tools/clang/test/Dxil2Spv/static-vertex.ll index 0032882e16..a3a5d5f7b3 100644 --- a/tools/clang/test/Dxil2Spv/static-vertex.ll +++ b/tools/clang/test/Dxil2Spv/static-vertex.ll @@ -1,4 +1,4 @@ -; RUN: %dxil2spv +; RUN: %dxil2spv %s | %FileCheck %s ; ; Input signature: ; @@ -73,7 +73,7 @@ define void @main() { call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float %2) ; StoreOutput(outputSigId,rowIndex,colIndex,value) call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float %3) ; StoreOutput(outputSigId,rowIndex,colIndex,value) -; CHECK: [[v0:%\d+]] = OpAccessChain %_ptr_Output_float %SV_Target %uint_3 +; CHECK: [[v0:%[0-9]+]] = OpAccessChain %_ptr_Output_float %SV_Target %uint_3 ; CHECK: OpStore [[v0]] %float_1 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float 1.000000e+00) ; StoreOutput(outputSigId,rowIndex,colIndex,value) ret void diff --git a/tools/clang/unittests/Dxil2Spv/CMakeLists.txt b/tools/clang/unittests/Dxil2Spv/CMakeLists.txt index 58977f6259..687821a955 100644 --- a/tools/clang/unittests/Dxil2Spv/CMakeLists.txt +++ b/tools/clang/unittests/Dxil2Spv/CMakeLists.txt @@ -9,7 +9,6 @@ set(LLVM_LINK_COMPONENTS add_clang_unittest(clang-dxil2spv-tests Dxil2SpvTestOptions.cpp Dxil2SpvTestOptions.h - FileTestFixture.cpp FileTestUtils.cpp FileTestUtils.h LitTest.cpp @@ -22,7 +21,7 @@ target_link_libraries(clang-dxil2spv-tests clangSPIRV dxcompiler dxil2spvlib - effcee + HLSLTestLib ) include_directories(${LLVM_SOURCE_DIR}/tools/clang/tools) diff --git a/tools/clang/unittests/Dxil2Spv/FileTestFixture.cpp b/tools/clang/unittests/Dxil2Spv/FileTestFixture.cpp deleted file mode 100644 index ba1986e69e..0000000000 --- a/tools/clang/unittests/Dxil2Spv/FileTestFixture.cpp +++ /dev/null @@ -1,114 +0,0 @@ -//===- FileTestFixture.cpp ------------- File Test Fixture Implementation -===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "FileTestFixture.h" - -#include - -#include "FileTestUtils.h" -#include "effcee/effcee.h" - -namespace clang { -namespace dxil2spv { - -bool FileTest::parseInputFile() { - std::stringstream inputSS; - std::ifstream inputFile; - inputFile.exceptions(std::ifstream::failbit); - - try { - inputFile.open(inputFilePath); - inputSS << inputFile.rdbuf(); - } catch (...) { - fprintf( - stderr, - "Error: Exception occurred while opening/reading the input file %s\n", - inputFilePath.c_str()); - return false; - } - - // Close the input file. - inputFile.close(); - checkCommands = inputSS.str(); - return parseCommand(); -} - -bool FileTest::parseCommand() { - // Effcee skips any input line which doesn't have a CHECK directive, therefore - // we can pass the entire input to effcee. This way, any warning/error message - // provided by effcee also reflects the correct line number in the input file. - const char dxilStartLabel[] = "; RUN:"; - const auto runCmdStartPos = checkCommands.find(dxilStartLabel); - if (runCmdStartPos == std::string::npos) { - fprintf(stderr, "Error: Missing \"RUN:\" command.\n"); - return false; - } - - // Everything was successful. - return true; -} - -void FileTest::runFileTest(llvm::StringRef filename, Expect expect) { - inputFilePath = utils::getAbsPathOfInputDataFile(filename); - - // Parse the input file. - ASSERT_TRUE(parseInputFile()); - - // Feed DXIL source into the translator. - std::string errorMessages; - const bool compileOk = utils::translateFileWithDxil2Spv( - inputFilePath, &generatedSpirvAsm, &errorMessages); - - checkTestResult(filename, compileOk, errorMessages, expect); -} - -void FileTest::checkTestResult(llvm::StringRef filename, const bool compileOk, - const std::string &errorMessages, - Expect expect) { - effcee::Result result(effcee::Result::Status::Ok); - - if (expect == Expect::Success) { - ASSERT_TRUE(compileOk); - - auto options = effcee::Options() - .SetChecksName(filename.str()) - .SetInputName(""); - - // Run CHECK commands via effcee on disassembly. - result = effcee::Match(generatedSpirvAsm, checkCommands, options); - - // Print effcee's error message (if any). - if (result.status() != effcee::Result::Status::Ok) { - fprintf(stderr, "%s\n", result.message().c_str()); - } - - // All checks must have passed. - ASSERT_EQ(result.status(), effcee::Result::Status::Ok); - } else { - ASSERT_FALSE(compileOk); - - auto options = effcee::Options() - .SetChecksName(filename.str()) - .SetInputName(""); - - // Run CHECK commands via effcee on error messages. - result = effcee::Match(errorMessages, checkCommands, options); - - // Print effcee's error message (if any). - if (result.status() != effcee::Result::Status::Ok) { - fprintf(stderr, "%s\n", result.message().c_str()); - } - - // All checks must have passed. - ASSERT_EQ(result.status(), effcee::Result::Status::Ok); - } -} - -} // end namespace dxil2spv -} // end namespace clang diff --git a/tools/clang/unittests/Dxil2Spv/FileTestFixture.h b/tools/clang/unittests/Dxil2Spv/FileTestFixture.h deleted file mode 100644 index 2878d2f297..0000000000 --- a/tools/clang/unittests/Dxil2Spv/FileTestFixture.h +++ /dev/null @@ -1,64 +0,0 @@ -//===- FileTestFixute.h ---- Test Fixture for File Check style tests ------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_UNITTESTS_DXIL2SPV_FILE_TEST_FIXTURE_H -#define LLVM_CLANG_UNITTESTS_DXIL2SPV_FILE_TEST_FIXTURE_H - -#include "spirv-tools/libspirv.h" -#include "llvm/ADT/StringRef.h" -#include "gtest/gtest.h" - -namespace clang { -namespace dxil2spv { - -class FileTest : public ::testing::Test { -public: - // Expected test result to be - enum class Expect { - Success, // Success (with or without warnings) - check disassembly - Failure, // Failure (with errors) - check error message - }; - - FileTest() {} - - // Runs a test with the given input DXIL file. - // - // The first line of code must start with "; RUN:". Next lines must be proper - // DXIL code for the test. It uses file check style output check e.g., "; - // CHECK: ...". - void runFileTest(llvm::StringRef path, Expect expect = Expect::Success); - -private: - // Reads in the given input file and parses the command to get - // arguments to run dxil2spv. - bool parseInputFile(); - - // Parses the command and gets arguments to run dxil2spv. - bool parseCommand(); - - // Checks the compile result. Reports whether the expected compile - // result matches the actual result and whether the expected validation - // result matches the actual one or not. - void checkTestResult(llvm::StringRef filename, const bool compileOk, - const std::string &errorMessages, Expect expect); - - // Path to the input test file - std::string inputFilePath; - - // CHECK commands that verify output - std::string checkCommands; - - // Disassembled binary (SPIR-V code) - std::string generatedSpirvAsm; -}; - -} // end namespace dxil2spv -} // end namespace clang - -#endif diff --git a/tools/clang/unittests/Dxil2Spv/LitTest.cpp b/tools/clang/unittests/Dxil2Spv/LitTest.cpp index 59f763423a..9a10a14d6c 100644 --- a/tools/clang/unittests/Dxil2Spv/LitTest.cpp +++ b/tools/clang/unittests/Dxil2Spv/LitTest.cpp @@ -7,13 +7,51 @@ // //===----------------------------------------------------------------------===// -#include "FileTestFixture.h" +#include "FileTestUtils.h" #include "WholeFileTestFixture.h" +#include "dxc/Test/DxcTestUtils.h" +#include "dxc/Test/WEXAdapter.h" -namespace { -using clang::dxil2spv::FileTest; using clang::dxil2spv::WholeFileTest; +namespace { + +#ifdef _WIN32 +class FileTest { +#else +class FileTest : public ::testing::Test { +#endif +public: + BEGIN_TEST_CLASS(FileTest) + TEST_CLASS_PROPERTY(L"Parallel", L"true") + TEST_METHOD_PROPERTY(L"Priority", L"0") + END_TEST_CLASS() + + TEST_CLASS_SETUP(InitSupport); + + dxc::DxcDllSupport m_dllSupport; + VersionSupportInfo m_ver; + + void runFileTest(std::string name) { + std::string fullPath = + clang::dxil2spv::utils::getAbsPathOfInputDataFile(name); + FileRunTestResult t = + FileRunTestResult::RunFromFileCommands(CA2W(fullPath.c_str())); + if (t.RunResult != 0) { + WEX::Logging::Log::Error(L"FileTest failed"); + WEX::Logging::Log::Error(CA2W(t.ErrorMessage.c_str(), CP_UTF8)); + } + } +}; + +bool FileTest::InitSupport() { + if (!m_dllSupport.IsEnabled()) { + VERIFY_SUCCEEDED(m_dllSupport.Initialize()); + m_ver.Initialize(m_dllSupport); + } + return true; +} + TEST_F(WholeFileTest, PassThruPixelShader) { runWholeFileTest("passthru-ps.ll"); } @@ -26,6 +64,6 @@ TEST_F(WholeFileTest, PassThruComputeShader) { runWholeFileTest("passthru-cs.ll"); } -TEST_F(FileTest, StaticVertexShader) { runFileTest("static-vertex.ll"); } +TEST_F(FileTest, StaticVertex) { runFileTest("static-vertex.ll"); } } // namespace diff --git a/tools/clang/unittests/Dxil2Spv/README.md b/tools/clang/unittests/Dxil2Spv/README.md index 9034671a55..0839cdcb72 100644 --- a/tools/clang/unittests/Dxil2Spv/README.md +++ b/tools/clang/unittests/Dxil2Spv/README.md @@ -43,12 +43,13 @@ to be created as a modified version of an existing test). [...] ``` -4. Add a `; RUN: %dxil2spv` command to the top of your DXIL test file. +4. Add a `; RUN: %dxil2spv %s | %FileCheck %s` command to the top of your DXIL + test file. `my-new-test.ll`: ``` - ; RUN: %dxil2spv + ; RUN: %dxil2spv %s | %FileCheck %s ; ; Input signature: [...] @@ -56,11 +57,9 @@ to be created as a modified version of an existing test). 5. Add `CHECK` lines to test the generated SPIR-V. - As needed for your test, add `CHECK` lines throughout the DXIL test file. - These tests are run with `effcee`, which supports pattern matching of - strings inspired by LLVM's FileCheck command. See the `effcee` documentation - for more information about the `CHECK` types supported and pattern matching - syntax. + As needed for your test, add `CHECK` lines throughout the DXIL test file. See + the LLVM FileCheck documentation for more information about the `CHECK` types + supported and pattern matching syntax. 6. Add the test to `tools/clang/unittests/Dxil2Spv/LitTest.cpp`. diff --git a/tools/clang/unittests/HLSL/CMakeLists.txt b/tools/clang/unittests/HLSL/CMakeLists.txt index c7648b8ea4..ac648741ad 100644 --- a/tools/clang/unittests/HLSL/CMakeLists.txt +++ b/tools/clang/unittests/HLSL/CMakeLists.txt @@ -26,7 +26,6 @@ set( LLVM_LINK_COMPONENTS if(WIN32) set(HLSL_IGNORE_SOURCES TestMain.cpp - HLSLTestOptions.cpp ) add_clang_library(clang-hlsl-tests SHARED AllocatorTest.cpp @@ -70,7 +69,6 @@ add_clang_unittest(clang-hlsl-tests DXIsenseTest.cpp ExtensionTest.cpp FunctionTest.cpp - HLSLTestOptions.cpp Objects.cpp OptimizerTest.cpp OptionsTest.cpp diff --git a/tools/clang/unittests/HLSL/TestMain.cpp b/tools/clang/unittests/HLSL/TestMain.cpp index 8346f55390..cbb04c299c 100644 --- a/tools/clang/unittests/HLSL/TestMain.cpp +++ b/tools/clang/unittests/HLSL/TestMain.cpp @@ -12,7 +12,7 @@ #include "llvm/Support/Signals.h" -#include "HLSLTestOptions.h" +#include "dxc/Test/HLSLTestOptions.h" #include "dxc/Test/WEXAdapter.h" #if defined(_WIN32) diff --git a/tools/clang/unittests/HLSLTestLib/CMakeLists.txt b/tools/clang/unittests/HLSLTestLib/CMakeLists.txt index b1108f8d0b..b22e95b252 100644 --- a/tools/clang/unittests/HLSLTestLib/CMakeLists.txt +++ b/tools/clang/unittests/HLSLTestLib/CMakeLists.txt @@ -1,5 +1,8 @@ if(WIN32) +set(HLSL_IGNORE_SOURCES + HLSLTestOptions.cpp +) find_package(TAEF REQUIRED) include_directories(${TAEF_INCLUDE_DIRS}) @@ -19,10 +22,24 @@ add_clang_library(HLSLTestLib DxcTestUtils.cpp FileCheckerTest.cpp FileCheckForTest.cpp + HLSLTestOptions.cpp ) include_directories(${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest/include) include_directories(${LLVM_MAIN_SRC_DIR}/utils/unittest/googlemock/include) +if(ENABLE_DXIL2SPV) +include_directories( + ${LLVM_SOURCE_DIR}/tools/clang/tools + ${SPIRV_TOOLS_INCLUDE_DIR} + ${SPIRV_HEADER_INCLUDE_DIR} + ) +target_link_libraries(HLSLTestLib + clangSPIRV + dxcompiler + dxil2spvlib + ) +endif(ENABLE_DXIL2SPV) + endif(WIN32) add_dependencies(HLSLTestLib TablegenHLSLOptions) diff --git a/tools/clang/unittests/HLSLTestLib/FileCheckerTest.cpp b/tools/clang/unittests/HLSLTestLib/FileCheckerTest.cpp index 8d9974b1f1..8edc9f43bd 100644 --- a/tools/clang/unittests/HLSLTestLib/FileCheckerTest.cpp +++ b/tools/clang/unittests/HLSLTestLib/FileCheckerTest.cpp @@ -29,18 +29,21 @@ #include "dxc/Test/HlslTestUtils.h" #include "dxc/Test/DxcTestUtils.h" -#include "llvm/Support/raw_os_ostream.h" -#include "llvm/Support/MD5.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/raw_ostream.h" +#include "dxc/DxilContainer/DxilContainer.h" #include "dxc/Support/Global.h" -#include "dxc/Support/dxcapi.use.h" -#include "dxc/dxctools.h" #include "dxc/Support/HLSLOptions.h" #include "dxc/Support/Unicode.h" +#include "dxc/Support/dxcapi.use.h" #include "dxc/Support/microcom.h" -#include "dxc/DxilContainer/DxilContainer.h" +#include "dxc/dxctools.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/TextDiagnosticPrinter.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/MD5.h" +#include "llvm/Support/MSFileSystem.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/raw_os_ostream.h" +#include "llvm/Support/raw_ostream.h" #ifdef _WIN32 // Reflection unsupported #include "dxc/Test/D3DReflectionDumper.h" @@ -51,6 +54,10 @@ using namespace hlsl::dump; #endif // WIN32 - Reflection unsupported +#ifdef ENABLE_DXIL2SPV +#include "dxil2spv/lib/dxil2spv.h" +#endif // ENABLE_DXIL2SPV + using namespace std; using namespace hlsl_test; @@ -137,6 +144,11 @@ FileRunCommandResult FileRunCommandPart::Run(dxc::DxcDllSupport &DllSupport, con return result; #endif // WIN32 - Linking unsupported } +#ifdef ENABLE_DXIL2SPV + else if (0 == _stricmp(Command.c_str(), "%dxil2spv")) { + return RunDxil2Spv(DllSupport, Prior); + } +#endif // ENABLE_DXIL2SPV else if (pPluginToolsPaths != nullptr) { auto it = pPluginToolsPaths->find(Command.c_str()); if (it != pPluginToolsPaths->end()) { @@ -1091,6 +1103,59 @@ FileRunCommandResult FileRunCommandPart::RunDxilVer(dxc::DxcDllSupport& DllSuppo return CheckDxilVer(DllSupport, RequiredDxilMajor, RequiredDxilMinor); } +#ifdef ENABLE_DXIL2SPV +FileRunCommandResult +FileRunCommandPart::RunDxil2Spv(dxc::DxcDllSupport &DllSupport, + const FileRunCommandResult *Prior) { + // Support piping stdin from prior if needed. + UNREFERENCED_PARAMETER(Prior); + bool success = true; + + std::string stdoutString; + std::string stderrString; + llvm::raw_string_ostream stdoutStream(stdoutString); + llvm::raw_string_ostream stderrStream(stderrString); + + try { + // Configure filesystem. + llvm::sys::fs::MSFileSystem *msf; + HRESULT hr; + if (SUCCEEDED(hr = CreateMSFileSystemForDisk(&msf))) { + llvm::sys::fs::AutoPerThreadSystem pts(msf); + IFTLLVM(pts.error_code()); + + // Set up diagnostics. + clang::CompilerInstance instance; + auto *diagnosticPrinter = new clang::TextDiagnosticPrinter( + stderrStream, new clang::DiagnosticOptions()); + instance.createDiagnostics(diagnosticPrinter, false); + instance.setOutStream(&stdoutStream); + + // Set compiler options. + instance.getCodeGenOpts().MainFileName = CW2A(CommandFileName, CP_UTF8); + instance.getCodeGenOpts().SpirvOptions.targetEnv = "vulkan1.0"; + + clang::dxil2spv::Translator translator(instance); + translator.Run(); + } else { + success = false; + } + } catch (...) { + success = false; + } + + stdoutStream.flush(); + stderrStream.flush(); + + FileRunCommandResult result = {}; + result.StdOut = stdoutString; + result.StdErr = stderrString; + result.ExitCode = success ? 0 : 1; + + return result; +} +#endif // ENABLE_DXIL2SPV + #ifndef _WIN32 FileRunCommandResult FileRunCommandPart::RunFromPath(const std::string &toolPath, const FileRunCommandResult *Prior) { return FileRunCommandResult::Error("RunFromPath not supported"); diff --git a/tools/clang/unittests/HLSL/HLSLTestOptions.cpp b/tools/clang/unittests/HLSLTestLib/HLSLTestOptions.cpp similarity index 97% rename from tools/clang/unittests/HLSL/HLSLTestOptions.cpp rename to tools/clang/unittests/HLSLTestLib/HLSLTestOptions.cpp index a56dc161cd..121e2a4cbd 100644 --- a/tools/clang/unittests/HLSL/HLSLTestOptions.cpp +++ b/tools/clang/unittests/HLSLTestLib/HLSLTestOptions.cpp @@ -12,9 +12,9 @@ // //===----------------------------------------------------------------------===// -#include "HLSLTestOptions.h" -#include "dxc/Test/WEXAdapter.h" +#include "dxc/Test/HLSLTestOptions.h" #include "dxc/Support/WinAdapter.h" +#include "dxc/Test/WEXAdapter.h" namespace clang { namespace hlsl { From 44593055ded8b6494f741980dd7fc1432fdb59d8 Mon Sep 17 00:00:00 2001 From: Natalie Chouinard Date: Wed, 4 May 2022 20:43:30 +0000 Subject: [PATCH 3/4] Replace WholeFileTest with FileCheck test --- tools/clang/test/Dxil2Spv/passthru-cs.ll | 183 +++++++++--------- tools/clang/test/Dxil2Spv/passthru-ps.ll | 105 +++++----- tools/clang/test/Dxil2Spv/passthru-vs.ll | 141 +++++++------- tools/clang/unittests/Dxil2Spv/CMakeLists.txt | 2 - tools/clang/unittests/Dxil2Spv/LitTest.cpp | 15 +- .../Dxil2Spv/WholeFileTestFixture.cpp | 121 ------------ .../unittests/Dxil2Spv/WholeFileTestFixture.h | 63 ------ 7 files changed, 216 insertions(+), 414 deletions(-) delete mode 100644 tools/clang/unittests/Dxil2Spv/WholeFileTestFixture.cpp delete mode 100644 tools/clang/unittests/Dxil2Spv/WholeFileTestFixture.h diff --git a/tools/clang/test/Dxil2Spv/passthru-cs.ll b/tools/clang/test/Dxil2Spv/passthru-cs.ll index e7aa76407b..3fc2fd279a 100644 --- a/tools/clang/test/Dxil2Spv/passthru-cs.ll +++ b/tools/clang/test/Dxil2Spv/passthru-cs.ll @@ -1,4 +1,4 @@ -; RUN: %dxil2spv +; RUN: %dxil2spv | %FileCheck %s ; ; Input signature: ; @@ -82,94 +82,93 @@ attributes #2 = { nounwind } !10 = !{i32 0, i64 16, i32 4, !11} !11 = !{i32 1, i32 1, i32 1} -; CHECK-WHOLE-SPIR-V: -; ; SPIR-V -; ; Version: 1.0 -; ; Generator: Google spiregg; 0 -; ; Bound: 59 -; ; Schema: 0 -; OpCapability Shader -; OpMemoryModel Logical GLSL450 -; OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID -; OpExecutionMode %main LocalSize 1 1 1 -; OpName %type_ByteAddressBuffer "type.ByteAddressBuffer" -; OpName %type_RWByteAddressBuffer "type.RWByteAddressBuffer" -; OpName %main "main" -; OpName %dx_types_ResRet_i32 "dx.types.ResRet.i32" -; OpDecorate %3 DescriptorSet 0 -; OpDecorate %3 Binding 0 -; OpDecorate %4 DescriptorSet 0 -; OpDecorate %4 Binding 1 -; OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId -; OpDecorate %_runtimearr_uint ArrayStride 4 -; OpMemberDecorate %type_ByteAddressBuffer 0 Offset 0 -; OpMemberDecorate %type_ByteAddressBuffer 0 NonWritable -; OpDecorate %type_ByteAddressBuffer BufferBlock -; OpMemberDecorate %type_RWByteAddressBuffer 0 Offset 0 -; OpDecorate %type_RWByteAddressBuffer BufferBlock -; %uint = OpTypeInt 32 0 -; %uint_0 = OpConstant %uint 0 -; %uint_2 = OpConstant %uint 2 -; %uint_1 = OpConstant %uint 1 -; %uint_3 = OpConstant %uint 3 -; %uint_4 = OpConstant %uint 4 -; %_runtimearr_uint = OpTypeRuntimeArray %uint -; %type_ByteAddressBuffer = OpTypeStruct %_runtimearr_uint -; %_ptr_Uniform_type_ByteAddressBuffer = OpTypePointer Uniform %type_ByteAddressBuffer -; %type_RWByteAddressBuffer = OpTypeStruct %_runtimearr_uint -; %_ptr_Uniform_type_RWByteAddressBuffer = OpTypePointer Uniform %type_RWByteAddressBuffer -; %v3uint = OpTypeVector %uint 3 -; %_ptr_Input_v3uint = OpTypePointer Input %v3uint -; %void = OpTypeVoid -; %19 = OpTypeFunction %void -; %int = OpTypeInt 32 1 -; %dx_types_ResRet_i32 = OpTypeStruct %int %int %int %int %int -; %_ptr_Function_dx_types_ResRet_i32 = OpTypePointer Function %dx_types_ResRet_i32 -; %_ptr_Input_uint = OpTypePointer Input %uint -; %_ptr_Uniform_uint = OpTypePointer Uniform %uint -; %_ptr_Function_int = OpTypePointer Function %int -; %3 = OpVariable %_ptr_Uniform_type_ByteAddressBuffer Uniform -; %4 = OpVariable %_ptr_Uniform_type_RWByteAddressBuffer Uniform -; %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input -; %main = OpFunction %void None %19 -; %20 = OpLabel -; %24 = OpVariable %_ptr_Function_dx_types_ResRet_i32 Function -; %26 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0 -; %27 = OpLoad %uint %26 -; %28 = OpShiftLeftLogical %uint %27 %uint_2 -; %29 = OpIAdd %uint %28 %uint_0 -; %31 = OpAccessChain %_ptr_Uniform_uint %3 %uint_0 %29 -; %32 = OpLoad %uint %31 -; %34 = OpAccessChain %_ptr_Function_int %24 %uint_0 -; %35 = OpBitcast %int %32 -; OpStore %34 %35 -; %36 = OpIAdd %uint %28 %uint_1 -; %37 = OpAccessChain %_ptr_Uniform_uint %3 %uint_0 %36 -; %38 = OpLoad %uint %37 -; %39 = OpAccessChain %_ptr_Function_int %24 %uint_1 -; %40 = OpBitcast %int %38 -; OpStore %39 %40 -; %41 = OpIAdd %uint %28 %uint_2 -; %42 = OpAccessChain %_ptr_Uniform_uint %3 %uint_0 %41 -; %43 = OpLoad %uint %42 -; %44 = OpAccessChain %_ptr_Function_int %24 %uint_2 -; %45 = OpBitcast %int %43 -; OpStore %44 %45 -; %46 = OpIAdd %uint %28 %uint_3 -; %47 = OpAccessChain %_ptr_Uniform_uint %3 %uint_0 %46 -; %48 = OpLoad %uint %47 -; %49 = OpAccessChain %_ptr_Function_int %24 %uint_3 -; %50 = OpBitcast %int %48 -; OpStore %49 %50 -; %51 = OpIAdd %uint %28 %uint_4 -; %52 = OpAccessChain %_ptr_Uniform_uint %3 %uint_0 %51 -; %53 = OpLoad %uint %52 -; %54 = OpAccessChain %_ptr_Function_int %24 %uint_4 -; %55 = OpBitcast %int %53 -; OpStore %54 %55 -; %56 = OpAccessChain %_ptr_Function_int %24 %uint_0 -; %57 = OpAccessChain %_ptr_Uniform_uint %4 %uint_0 %28 -; %58 = OpBitcast %uint %56 -; OpStore %57 %58 -; OpReturn -; OpFunctionEnd +; CHECK: ; SPIR-V +; CHECK-NEXT: ; Version: 1.0 +; CHECK-NEXT: ; Generator: Google spiregg; 0 +; CHECK-NEXT: ; Bound: 59 +; CHECK-NEXT: ; Schema: 0 +; CHECK-NEXT: OpCapability Shader +; CHECK-NEXT: OpMemoryModel Logical GLSL450 +; CHECK-NEXT: OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID +; CHECK-NEXT: OpExecutionMode %main LocalSize 1 1 1 +; CHECK-NEXT: OpName %type_ByteAddressBuffer "type.ByteAddressBuffer" +; CHECK-NEXT: OpName %type_RWByteAddressBuffer "type.RWByteAddressBuffer" +; CHECK-NEXT: OpName %main "main" +; CHECK-NEXT: OpName %dx_types_ResRet_i32 "dx.types.ResRet.i32" +; CHECK-NEXT: OpDecorate %3 DescriptorSet 0 +; CHECK-NEXT: OpDecorate %3 Binding 0 +; CHECK-NEXT: OpDecorate %4 DescriptorSet 0 +; CHECK-NEXT: OpDecorate %4 Binding 1 +; CHECK-NEXT: OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId +; CHECK-NEXT: OpDecorate %_runtimearr_uint ArrayStride 4 +; CHECK-NEXT: OpMemberDecorate %type_ByteAddressBuffer 0 Offset 0 +; CHECK-NEXT: OpMemberDecorate %type_ByteAddressBuffer 0 NonWritable +; CHECK-NEXT: OpDecorate %type_ByteAddressBuffer BufferBlock +; CHECK-NEXT: OpMemberDecorate %type_RWByteAddressBuffer 0 Offset 0 +; CHECK-NEXT: OpDecorate %type_RWByteAddressBuffer BufferBlock +; CHECK-NEXT: %uint = OpTypeInt 32 0 +; CHECK-NEXT: %uint_0 = OpConstant %uint 0 +; CHECK-NEXT: %uint_2 = OpConstant %uint 2 +; CHECK-NEXT: %uint_1 = OpConstant %uint 1 +; CHECK-NEXT: %uint_3 = OpConstant %uint 3 +; CHECK-NEXT: %uint_4 = OpConstant %uint 4 +; CHECK-NEXT: %_runtimearr_uint = OpTypeRuntimeArray %uint +; CHECK-NEXT: %type_ByteAddressBuffer = OpTypeStruct %_runtimearr_uint +; CHECK-NEXT: %_ptr_Uniform_type_ByteAddressBuffer = OpTypePointer Uniform %type_ByteAddressBuffer +; CHECK-NEXT: %type_RWByteAddressBuffer = OpTypeStruct %_runtimearr_uint +; CHECK-NEXT: %_ptr_Uniform_type_RWByteAddressBuffer = OpTypePointer Uniform %type_RWByteAddressBuffer +; CHECK-NEXT: %v3uint = OpTypeVector %uint 3 +; CHECK-NEXT: %_ptr_Input_v3uint = OpTypePointer Input %v3uint +; CHECK-NEXT: %void = OpTypeVoid +; CHECK-NEXT: %19 = OpTypeFunction %void +; CHECK-NEXT: %int = OpTypeInt 32 1 +; CHECK-NEXT: %dx_types_ResRet_i32 = OpTypeStruct %int %int %int %int %int +; CHECK-NEXT: %_ptr_Function_dx_types_ResRet_i32 = OpTypePointer Function %dx_types_ResRet_i32 +; CHECK-NEXT: %_ptr_Input_uint = OpTypePointer Input %uint +; CHECK-NEXT: %_ptr_Uniform_uint = OpTypePointer Uniform %uint +; CHECK-NEXT: %_ptr_Function_int = OpTypePointer Function %int +; CHECK-NEXT: %3 = OpVariable %_ptr_Uniform_type_ByteAddressBuffer Uniform +; CHECK-NEXT: %4 = OpVariable %_ptr_Uniform_type_RWByteAddressBuffer Uniform +; CHECK-NEXT: %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +; CHECK-NEXT: %main = OpFunction %void None %19 +; CHECK-NEXT: %20 = OpLabel +; CHECK-NEXT: %24 = OpVariable %_ptr_Function_dx_types_ResRet_i32 Function +; CHECK-NEXT: %26 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0 +; CHECK-NEXT: %27 = OpLoad %uint %26 +; CHECK-NEXT: %28 = OpShiftLeftLogical %uint %27 %uint_2 +; CHECK-NEXT: %29 = OpIAdd %uint %28 %uint_0 +; CHECK-NEXT: %31 = OpAccessChain %_ptr_Uniform_uint %3 %uint_0 %29 +; CHECK-NEXT: %32 = OpLoad %uint %31 +; CHECK-NEXT: %34 = OpAccessChain %_ptr_Function_int %24 %uint_0 +; CHECK-NEXT: %35 = OpBitcast %int %32 +; CHECK-NEXT: OpStore %34 %35 +; CHECK-NEXT: %36 = OpIAdd %uint %28 %uint_1 +; CHECK-NEXT: %37 = OpAccessChain %_ptr_Uniform_uint %3 %uint_0 %36 +; CHECK-NEXT: %38 = OpLoad %uint %37 +; CHECK-NEXT: %39 = OpAccessChain %_ptr_Function_int %24 %uint_1 +; CHECK-NEXT: %40 = OpBitcast %int %38 +; CHECK-NEXT: OpStore %39 %40 +; CHECK-NEXT: %41 = OpIAdd %uint %28 %uint_2 +; CHECK-NEXT: %42 = OpAccessChain %_ptr_Uniform_uint %3 %uint_0 %41 +; CHECK-NEXT: %43 = OpLoad %uint %42 +; CHECK-NEXT: %44 = OpAccessChain %_ptr_Function_int %24 %uint_2 +; CHECK-NEXT: %45 = OpBitcast %int %43 +; CHECK-NEXT: OpStore %44 %45 +; CHECK-NEXT: %46 = OpIAdd %uint %28 %uint_3 +; CHECK-NEXT: %47 = OpAccessChain %_ptr_Uniform_uint %3 %uint_0 %46 +; CHECK-NEXT: %48 = OpLoad %uint %47 +; CHECK-NEXT: %49 = OpAccessChain %_ptr_Function_int %24 %uint_3 +; CHECK-NEXT: %50 = OpBitcast %int %48 +; CHECK-NEXT: OpStore %49 %50 +; CHECK-NEXT: %51 = OpIAdd %uint %28 %uint_4 +; CHECK-NEXT: %52 = OpAccessChain %_ptr_Uniform_uint %3 %uint_0 %51 +; CHECK-NEXT: %53 = OpLoad %uint %52 +; CHECK-NEXT: %54 = OpAccessChain %_ptr_Function_int %24 %uint_4 +; CHECK-NEXT: %55 = OpBitcast %int %53 +; CHECK-NEXT: OpStore %54 %55 +; CHECK-NEXT: %56 = OpAccessChain %_ptr_Function_int %24 %uint_0 +; CHECK-NEXT: %57 = OpAccessChain %_ptr_Uniform_uint %4 %uint_0 %28 +; CHECK-NEXT: %58 = OpBitcast %uint %56 +; CHECK-NEXT: OpStore %57 %58 +; CHECK-NEXT: OpReturn +; CHECK-NEXT: OpFunctionEnd diff --git a/tools/clang/test/Dxil2Spv/passthru-ps.ll b/tools/clang/test/Dxil2Spv/passthru-ps.ll index 3e4c88e1e9..6ba7114354 100644 --- a/tools/clang/test/Dxil2Spv/passthru-ps.ll +++ b/tools/clang/test/Dxil2Spv/passthru-ps.ll @@ -1,4 +1,4 @@ -; RUN: %dxil2spv +; RUN: %dxil2spv | %FileCheck %s ; ; Input signature: ; @@ -101,55 +101,54 @@ attributes #1 = { nounwind } !12 = !{!13} !13 = !{i32 0, !"SV_Target", i8 9, i8 16, !9, i8 0, i32 1, i8 4, i32 0, i8 0, !11} -; CHECK-WHOLE-SPIR-V: -; ; SPIR-V -; ; Version: 1.0 -; ; Generator: Google spiregg; 0 -; ; Bound: 31 -; ; Schema: 0 -; OpCapability Shader -; OpMemoryModel Logical GLSL450 -; OpEntryPoint Fragment %PSMain "PSMain" %gl_Position %COLOR %SV_Target -; OpExecutionMode %PSMain OriginUpperLeft -; OpName %COLOR "COLOR" -; OpName %SV_Target "SV_Target" -; OpName %PSMain "PSMain" -; OpDecorate %gl_Position BuiltIn Position -; OpDecorate %COLOR Location 1 -; OpDecorate %SV_Target Location 0 -; %uint = OpTypeInt 32 0 -; %uint_0 = OpConstant %uint 0 -; %uint_1 = OpConstant %uint 1 -; %uint_2 = OpConstant %uint 2 -; %uint_3 = OpConstant %uint 3 -; %float = OpTypeFloat 32 -; %v4float = OpTypeVector %float 4 -; %_ptr_Input_v4float = OpTypePointer Input %v4float -; %_ptr_Output_v4float = OpTypePointer Output %v4float -; %void = OpTypeVoid -; %15 = OpTypeFunction %void -; %_ptr_Input_float = OpTypePointer Input %float -; %_ptr_Output_float = OpTypePointer Output %float -; %gl_Position = OpVariable %_ptr_Input_v4float Input -; %COLOR = OpVariable %_ptr_Input_v4float Input -; %SV_Target = OpVariable %_ptr_Output_v4float Output -; %PSMain = OpFunction %void None %15 -; %16 = OpLabel -; %18 = OpAccessChain %_ptr_Input_float %COLOR %uint_0 -; %19 = OpLoad %float %18 -; %20 = OpAccessChain %_ptr_Input_float %COLOR %uint_1 -; %21 = OpLoad %float %20 -; %22 = OpAccessChain %_ptr_Input_float %COLOR %uint_2 -; %23 = OpLoad %float %22 -; %24 = OpAccessChain %_ptr_Input_float %COLOR %uint_3 -; %25 = OpLoad %float %24 -; %27 = OpAccessChain %_ptr_Output_float %SV_Target %uint_0 -; OpStore %27 %19 -; %28 = OpAccessChain %_ptr_Output_float %SV_Target %uint_1 -; OpStore %28 %21 -; %29 = OpAccessChain %_ptr_Output_float %SV_Target %uint_2 -; OpStore %29 %23 -; %30 = OpAccessChain %_ptr_Output_float %SV_Target %uint_3 -; OpStore %30 %25 -; OpReturn -; OpFunctionEnd +; CHECK: ; SPIR-V +; CHECK-NEXT: ; Version: 1.0 +; CHECK-NEXT: ; Generator: Google spiregg; 0 +; CHECK-NEXT: ; Bound: 31 +; CHECK-NEXT: ; Schema: 0 +; CHECK-NEXT: OpCapability Shader +; CHECK-NEXT: OpMemoryModel Logical GLSL450 +; CHECK-NEXT: OpEntryPoint Fragment %PSMain "PSMain" %gl_Position %COLOR %SV_Target +; CHECK-NEXT: OpExecutionMode %PSMain OriginUpperLeft +; CHECK-NEXT: OpName %COLOR "COLOR" +; CHECK-NEXT: OpName %SV_Target "SV_Target" +; CHECK-NEXT: OpName %PSMain "PSMain" +; CHECK-NEXT: OpDecorate %gl_Position BuiltIn Position +; CHECK-NEXT: OpDecorate %COLOR Location 1 +; CHECK-NEXT: OpDecorate %SV_Target Location 0 +; CHECK-NEXT: %uint = OpTypeInt 32 0 +; CHECK-NEXT: %uint_0 = OpConstant %uint 0 +; CHECK-NEXT: %uint_1 = OpConstant %uint 1 +; CHECK-NEXT: %uint_2 = OpConstant %uint 2 +; CHECK-NEXT: %uint_3 = OpConstant %uint 3 +; CHECK-NEXT: %float = OpTypeFloat 32 +; CHECK-NEXT: %v4float = OpTypeVector %float 4 +; CHECK-NEXT: %_ptr_Input_v4float = OpTypePointer Input %v4float +; CHECK-NEXT: %_ptr_Output_v4float = OpTypePointer Output %v4float +; CHECK-NEXT: %void = OpTypeVoid +; CHECK-NEXT: %15 = OpTypeFunction %void +; CHECK-NEXT: %_ptr_Input_float = OpTypePointer Input %float +; CHECK-NEXT: %_ptr_Output_float = OpTypePointer Output %float +; CHECK-NEXT: %gl_Position = OpVariable %_ptr_Input_v4float Input +; CHECK-NEXT: %COLOR = OpVariable %_ptr_Input_v4float Input +; CHECK-NEXT: %SV_Target = OpVariable %_ptr_Output_v4float Output +; CHECK-NEXT: %PSMain = OpFunction %void None %15 +; CHECK-NEXT: %16 = OpLabel +; CHECK-NEXT: %18 = OpAccessChain %_ptr_Input_float %COLOR %uint_0 +; CHECK-NEXT: %19 = OpLoad %float %18 +; CHECK-NEXT: %20 = OpAccessChain %_ptr_Input_float %COLOR %uint_1 +; CHECK-NEXT: %21 = OpLoad %float %20 +; CHECK-NEXT: %22 = OpAccessChain %_ptr_Input_float %COLOR %uint_2 +; CHECK-NEXT: %23 = OpLoad %float %22 +; CHECK-NEXT: %24 = OpAccessChain %_ptr_Input_float %COLOR %uint_3 +; CHECK-NEXT: %25 = OpLoad %float %24 +; CHECK-NEXT: %27 = OpAccessChain %_ptr_Output_float %SV_Target %uint_0 +; CHECK-NEXT: OpStore %27 %19 +; CHECK-NEXT: %28 = OpAccessChain %_ptr_Output_float %SV_Target %uint_1 +; CHECK-NEXT: OpStore %28 %21 +; CHECK-NEXT: %29 = OpAccessChain %_ptr_Output_float %SV_Target %uint_2 +; CHECK-NEXT: OpStore %29 %23 +; CHECK-NEXT: %30 = OpAccessChain %_ptr_Output_float %SV_Target %uint_3 +; CHECK-NEXT: OpStore %30 %25 +; CHECK-NEXT: OpReturn +; CHECK-NEXT: OpFunctionEnd diff --git a/tools/clang/test/Dxil2Spv/passthru-vs.ll b/tools/clang/test/Dxil2Spv/passthru-vs.ll index 1ebdcff231..b4081ec102 100644 --- a/tools/clang/test/Dxil2Spv/passthru-vs.ll +++ b/tools/clang/test/Dxil2Spv/passthru-vs.ll @@ -1,4 +1,4 @@ -; RUN: %dxil2spv +; RUN: %dxil2spv | %FileCheck %s ; ; Input signature: ; @@ -115,73 +115,72 @@ attributes #1 = { nounwind } !13 = !{i32 0, !"SV_Position", i8 9, i8 3, !9, i8 4, i32 1, i8 4, i32 0, i8 0, !10} !14 = !{i32 1, !"COLOR", i8 9, i8 0, !9, i8 2, i32 1, i8 4, i32 1, i8 0, !10} -; CHECK-WHOLE-SPIR-V: -; ; SPIR-V -; ; Version: 1.0 -; ; Generator: Google spiregg; 0 -; ; Bound: 44 -; ; Schema: 0 -; OpCapability Shader -; OpMemoryModel Logical GLSL450 -; OpEntryPoint Vertex %VSMain "VSMain" %POSITION %COLOR %gl_Position %COLOR_0 -; OpName %POSITION "POSITION" -; OpName %COLOR "COLOR" -; OpName %COLOR_0 "COLOR" -; OpName %VSMain "VSMain" -; OpDecorate %POSITION Location 0 -; OpDecorate %COLOR Location 1 -; OpDecorate %gl_Position BuiltIn Position -; OpDecorate %COLOR_0 Location 1 -; %uint = OpTypeInt 32 0 -; %uint_0 = OpConstant %uint 0 -; %uint_1 = OpConstant %uint 1 -; %uint_2 = OpConstant %uint 2 -; %uint_3 = OpConstant %uint 3 -; %float = OpTypeFloat 32 -; %v4float = OpTypeVector %float 4 -; %_ptr_Input_v4float = OpTypePointer Input %v4float -; %_ptr_Output_v4float = OpTypePointer Output %v4float -; %void = OpTypeVoid -; %16 = OpTypeFunction %void -; %_ptr_Input_float = OpTypePointer Input %float -; %_ptr_Output_float = OpTypePointer Output %float -; %POSITION = OpVariable %_ptr_Input_v4float Input -; %COLOR = OpVariable %_ptr_Input_v4float Input -; %gl_Position = OpVariable %_ptr_Output_v4float Output -; %COLOR_0 = OpVariable %_ptr_Output_v4float Output -; %VSMain = OpFunction %void None %16 -; %17 = OpLabel -; %19 = OpAccessChain %_ptr_Input_float %COLOR %uint_0 -; %20 = OpLoad %float %19 -; %21 = OpAccessChain %_ptr_Input_float %COLOR %uint_1 -; %22 = OpLoad %float %21 -; %23 = OpAccessChain %_ptr_Input_float %COLOR %uint_2 -; %24 = OpLoad %float %23 -; %25 = OpAccessChain %_ptr_Input_float %COLOR %uint_3 -; %26 = OpLoad %float %25 -; %27 = OpAccessChain %_ptr_Input_float %POSITION %uint_0 -; %28 = OpLoad %float %27 -; %29 = OpAccessChain %_ptr_Input_float %POSITION %uint_1 -; %30 = OpLoad %float %29 -; %31 = OpAccessChain %_ptr_Input_float %POSITION %uint_2 -; %32 = OpLoad %float %31 -; %33 = OpAccessChain %_ptr_Input_float %POSITION %uint_3 -; %34 = OpLoad %float %33 -; %36 = OpAccessChain %_ptr_Output_float %gl_Position %uint_0 -; OpStore %36 %28 -; %37 = OpAccessChain %_ptr_Output_float %gl_Position %uint_1 -; OpStore %37 %30 -; %38 = OpAccessChain %_ptr_Output_float %gl_Position %uint_2 -; OpStore %38 %32 -; %39 = OpAccessChain %_ptr_Output_float %gl_Position %uint_3 -; OpStore %39 %34 -; %40 = OpAccessChain %_ptr_Output_float %COLOR_0 %uint_0 -; OpStore %40 %20 -; %41 = OpAccessChain %_ptr_Output_float %COLOR_0 %uint_1 -; OpStore %41 %22 -; %42 = OpAccessChain %_ptr_Output_float %COLOR_0 %uint_2 -; OpStore %42 %24 -; %43 = OpAccessChain %_ptr_Output_float %COLOR_0 %uint_3 -; OpStore %43 %26 -; OpReturn -; OpFunctionEnd +; CHECK: ; SPIR-V +; CHECK-NEXT: ; Version: 1.0 +; CHECK-NEXT: ; Generator: Google spiregg; 0 +; CHECK-NEXT: ; Bound: 44 +; CHECK-NEXT: ; Schema: 0 +; CHECK-NEXT: OpCapability Shader +; CHECK-NEXT: OpMemoryModel Logical GLSL450 +; CHECK-NEXT: OpEntryPoint Vertex %VSMain "VSMain" %POSITION %COLOR %gl_Position %COLOR_0 +; CHECK-NEXT: OpName %POSITION "POSITION" +; CHECK-NEXT: OpName %COLOR "COLOR" +; CHECK-NEXT: OpName %COLOR_0 "COLOR" +; CHECK-NEXT: OpName %VSMain "VSMain" +; CHECK-NEXT: OpDecorate %POSITION Location 0 +; CHECK-NEXT: OpDecorate %COLOR Location 1 +; CHECK-NEXT: OpDecorate %gl_Position BuiltIn Position +; CHECK-NEXT: OpDecorate %COLOR_0 Location 1 +; CHECK-NEXT: %uint = OpTypeInt 32 0 +; CHECK-NEXT: %uint_0 = OpConstant %uint 0 +; CHECK-NEXT: %uint_1 = OpConstant %uint 1 +; CHECK-NEXT: %uint_2 = OpConstant %uint 2 +; CHECK-NEXT: %uint_3 = OpConstant %uint 3 +; CHECK-NEXT: %float = OpTypeFloat 32 +; CHECK-NEXT: %v4float = OpTypeVector %float 4 +; CHECK-NEXT: %_ptr_Input_v4float = OpTypePointer Input %v4float +; CHECK-NEXT: %_ptr_Output_v4float = OpTypePointer Output %v4float +; CHECK-NEXT: %void = OpTypeVoid +; CHECK-NEXT: %16 = OpTypeFunction %void +; CHECK-NEXT: %_ptr_Input_float = OpTypePointer Input %float +; CHECK-NEXT: %_ptr_Output_float = OpTypePointer Output %float +; CHECK-NEXT: %POSITION = OpVariable %_ptr_Input_v4float Input +; CHECK-NEXT: %COLOR = OpVariable %_ptr_Input_v4float Input +; CHECK-NEXT: %gl_Position = OpVariable %_ptr_Output_v4float Output +; CHECK-NEXT: %COLOR_0 = OpVariable %_ptr_Output_v4float Output +; CHECK-NEXT: %VSMain = OpFunction %void None %16 +; CHECK-NEXT: %17 = OpLabel +; CHECK-NEXT: %19 = OpAccessChain %_ptr_Input_float %COLOR %uint_0 +; CHECK-NEXT: %20 = OpLoad %float %19 +; CHECK-NEXT: %21 = OpAccessChain %_ptr_Input_float %COLOR %uint_1 +; CHECK-NEXT: %22 = OpLoad %float %21 +; CHECK-NEXT: %23 = OpAccessChain %_ptr_Input_float %COLOR %uint_2 +; CHECK-NEXT: %24 = OpLoad %float %23 +; CHECK-NEXT: %25 = OpAccessChain %_ptr_Input_float %COLOR %uint_3 +; CHECK-NEXT: %26 = OpLoad %float %25 +; CHECK-NEXT: %27 = OpAccessChain %_ptr_Input_float %POSITION %uint_0 +; CHECK-NEXT: %28 = OpLoad %float %27 +; CHECK-NEXT: %29 = OpAccessChain %_ptr_Input_float %POSITION %uint_1 +; CHECK-NEXT: %30 = OpLoad %float %29 +; CHECK-NEXT: %31 = OpAccessChain %_ptr_Input_float %POSITION %uint_2 +; CHECK-NEXT: %32 = OpLoad %float %31 +; CHECK-NEXT: %33 = OpAccessChain %_ptr_Input_float %POSITION %uint_3 +; CHECK-NEXT: %34 = OpLoad %float %33 +; CHECK-NEXT: %36 = OpAccessChain %_ptr_Output_float %gl_Position %uint_0 +; CHECK-NEXT: OpStore %36 %28 +; CHECK-NEXT: %37 = OpAccessChain %_ptr_Output_float %gl_Position %uint_1 +; CHECK-NEXT: OpStore %37 %30 +; CHECK-NEXT: %38 = OpAccessChain %_ptr_Output_float %gl_Position %uint_2 +; CHECK-NEXT: OpStore %38 %32 +; CHECK-NEXT: %39 = OpAccessChain %_ptr_Output_float %gl_Position %uint_3 +; CHECK-NEXT: OpStore %39 %34 +; CHECK-NEXT: %40 = OpAccessChain %_ptr_Output_float %COLOR_0 %uint_0 +; CHECK-NEXT: OpStore %40 %20 +; CHECK-NEXT: %41 = OpAccessChain %_ptr_Output_float %COLOR_0 %uint_1 +; CHECK-NEXT: OpStore %41 %22 +; CHECK-NEXT: %42 = OpAccessChain %_ptr_Output_float %COLOR_0 %uint_2 +; CHECK-NEXT: OpStore %42 %24 +; CHECK-NEXT: %43 = OpAccessChain %_ptr_Output_float %COLOR_0 %uint_3 +; CHECK-NEXT: OpStore %43 %26 +; CHECK-NEXT: OpReturn +; CHECK-NEXT: OpFunctionEnd diff --git a/tools/clang/unittests/Dxil2Spv/CMakeLists.txt b/tools/clang/unittests/Dxil2Spv/CMakeLists.txt index 687821a955..76aed8717d 100644 --- a/tools/clang/unittests/Dxil2Spv/CMakeLists.txt +++ b/tools/clang/unittests/Dxil2Spv/CMakeLists.txt @@ -13,8 +13,6 @@ add_clang_unittest(clang-dxil2spv-tests FileTestUtils.h LitTest.cpp TestMain.cpp - WholeFileTestFixture.cpp - WholeFileTestFixture.h ) target_link_libraries(clang-dxil2spv-tests diff --git a/tools/clang/unittests/Dxil2Spv/LitTest.cpp b/tools/clang/unittests/Dxil2Spv/LitTest.cpp index 9a10a14d6c..13f8a7659b 100644 --- a/tools/clang/unittests/Dxil2Spv/LitTest.cpp +++ b/tools/clang/unittests/Dxil2Spv/LitTest.cpp @@ -8,12 +8,9 @@ //===----------------------------------------------------------------------===// #include "FileTestUtils.h" -#include "WholeFileTestFixture.h" #include "dxc/Test/DxcTestUtils.h" #include "dxc/Test/WEXAdapter.h" -using clang::dxil2spv::WholeFileTest; - namespace { #ifdef _WIN32 @@ -52,17 +49,11 @@ bool FileTest::InitSupport() { return true; } -TEST_F(WholeFileTest, PassThruPixelShader) { - runWholeFileTest("passthru-ps.ll"); -} +TEST_F(FileTest, PassThruPixelShader) { runFileTest("passthru-ps.ll"); } -TEST_F(WholeFileTest, PassThruVertexShader) { - runWholeFileTest("passthru-vs.ll"); -} +TEST_F(FileTest, PassThruVertexShader) { runFileTest("passthru-vs.ll"); } -TEST_F(WholeFileTest, PassThruComputeShader) { - runWholeFileTest("passthru-cs.ll"); -} +TEST_F(FileTest, PassThruComputeShader) { runFileTest("passthru-cs.ll"); } TEST_F(FileTest, StaticVertex) { runFileTest("static-vertex.ll"); } diff --git a/tools/clang/unittests/Dxil2Spv/WholeFileTestFixture.cpp b/tools/clang/unittests/Dxil2Spv/WholeFileTestFixture.cpp deleted file mode 100644 index 5319be5c67..0000000000 --- a/tools/clang/unittests/Dxil2Spv/WholeFileTestFixture.cpp +++ /dev/null @@ -1,121 +0,0 @@ -//===- WholeFileTestFixture.cpp - WholeFileTest impl-----------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include - -#include "FileTestUtils.h" -#include "WholeFileTestFixture.h" - -namespace clang { -namespace dxil2spv { - -namespace { -const char dxilStartLabel[] = "; RUN:"; -const char spirvStartLabel[] = "; CHECK-WHOLE-SPIR-V:"; -const char errorStartLabel[] = "; CHECK-ERRORS:"; - -enum class ParsingStage : unsigned { - None = 0, - DXIL = 1, - SPIRV = 2, - ERRORS = 3 -}; -} // namespace - -bool WholeFileTest::parseInputFile() { - ParsingStage stage = ParsingStage::None; - bool foundRunCommand = false; - bool foundCheckCommand = false; - std::ostringstream outString; - std::ostringstream errString; - std::ifstream inputFile; - inputFile.exceptions(std::ifstream::failbit); - try { - inputFile.open(inputFilePath); - for (std::string line; std::getline(inputFile, line);) { - if (line.find(dxilStartLabel) != std::string::npos) { - stage = ParsingStage::DXIL; - foundRunCommand = true; - } else if (line.find(spirvStartLabel) != std::string::npos) { - // SPIR-V source starts on the next line. - stage = ParsingStage::SPIRV; - foundCheckCommand = true; - } else if (line.find(errorStartLabel) != std::string::npos) { - // Expected errors starts on the next line. - stage = ParsingStage::ERRORS; - foundCheckCommand = true; - } else if (stage == ParsingStage::SPIRV) { - // Strip the leading "; " from the SPIR-V assembly (skip 1 characters) - if (line.size() > 2u) { - line = line.substr(2); - } - if (line[line.size() - 1] == '\r') - line = line.substr(0, line.size() - 1); - outString << line << std::endl; - } else if (stage == ParsingStage::ERRORS) { - // Strip the leading "; " (skip 1 characters) - if (line.size() > 2u) { - line = line.substr(2); - } - if (line[line.size() - 1] == '\r') - line = line.substr(0, line.size() - 1); - errString << line << std::endl; - } - } - } catch (...) { - if (!inputFile.eof()) { - fprintf( - stderr, - "Error: Exception occurred while opening/reading the input file %s\n", - inputFilePath.c_str()); - return false; - } - } - - if (!foundRunCommand) { - fprintf(stderr, "Error: Missing \"RUN:\" command.\n"); - return false; - } - if (!foundCheckCommand) { - fprintf(stderr, "Error: Missing \"CHECK-WHOLE-SPIR-V:\" and/or " - "\"CHECK-ERRORS:\" command.\n"); - return false; - } - - // Reached the end of the file. SPIR-V source has ended. Store it for - // comparison. - expectedSpirvAsm = outString.str(); - expectedErrors = errString.str(); - - // Close the input file. - inputFile.close(); - - // Everything was successful. - return true; -} - -void WholeFileTest::runWholeFileTest(llvm::StringRef filename) { - inputFilePath = utils::getAbsPathOfInputDataFile(filename); - - // Parse the input file. - ASSERT_TRUE(parseInputFile()); - - // Feed the DXIL source into the translator. - ASSERT_TRUE(utils::translateFileWithDxil2Spv( - inputFilePath, &generatedSpirvAsm, &generatedErrors)); - - // Compare the expected and the generted SPIR-V code. - EXPECT_EQ(expectedSpirvAsm, generatedSpirvAsm); - - // Compare the expected and the generted errors. - EXPECT_EQ(expectedErrors, generatedErrors); -} - -} // end namespace dxil2spv -} // end namespace clang diff --git a/tools/clang/unittests/Dxil2Spv/WholeFileTestFixture.h b/tools/clang/unittests/Dxil2Spv/WholeFileTestFixture.h deleted file mode 100644 index f93d1b48a2..0000000000 --- a/tools/clang/unittests/Dxil2Spv/WholeFileTestFixture.h +++ /dev/null @@ -1,63 +0,0 @@ -//===- WholeFileTestFixture.h - Whole file test Fixture--------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_UNITTESTS_DXIL2SPV_WHOLEFILETESTFIXTURE_H -#define LLVM_CLANG_UNITTESTS_DXIL2SPV_WHOLEFILETESTFIXTURE_H - -#include "llvm/ADT/StringRef.h" -#include "gtest/gtest.h" - -namespace clang { -namespace dxil2spv { - -/// \brief The purpose of the this test class is to take in an input file with -/// the following format: -/// -/// ; Comments... -/// ; More comments... -/// ; RUN: %dxil2spv -/// ... -/// -/// ... -/// ; CHECK-WHOLE-SPIR-V: -/// ; ... -/// ; -/// ; ... -/// -/// This file is fully read in as the DXIL source (therefore any non-DXIL must -/// be commented out). It is fed to dxil2spv to translate to SPIR-V. The -/// resulting SPIR-V assembly text is compared to the second part of the input -/// file (after the directive). If these match, the test -/// is marked as a PASS, and marked as a FAILED otherwise. -class WholeFileTest : public ::testing::Test { -public: - /// \brief Runs a WHOLE-FILE-TEST! (See class description for more info) - /// Returns true if the test passes; false otherwise. - void runWholeFileTest(llvm::StringRef path); - - WholeFileTest() {} - -private: - /// \brief Reads in the given input file. - /// Stores the SPIR-V portion of the file into the - /// member variable. - /// Returns true on success, and false on failure. - bool parseInputFile(); - - std::string inputFilePath; ///< Path to the input test file - std::string expectedSpirvAsm; ///< Expected SPIR-V parsed from input - std::string generatedSpirvAsm; ///< Disassembled binary (SPIR-V code) - std::string expectedErrors; ///< Expected errors parsed from input - std::string generatedErrors; ///< Actual errors from running -}; - -} // end namespace dxil2spv -} // end namespace clang - -#endif From d368510caebd694bbbc024f58f350e26c558850d Mon Sep 17 00:00:00 2001 From: Natalie Chouinard Date: Thu, 5 May 2022 16:09:40 +0000 Subject: [PATCH 4/4] Address review comments --- CMakeLists.txt | 3 --- tools/clang/unittests/Dxil2Spv/LitTest.cpp | 10 +++++----- tools/clang/unittests/HLSLTestLib/CMakeLists.txt | 4 +++- tools/clang/unittests/HLSLTestLib/FileCheckerTest.cpp | 9 +++------ 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5107499a50..b5b1917c04 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,9 +132,6 @@ endif() # Building dxil2spv off by default while it's in early development. option(ENABLE_DXIL2SPV "Enables DXIL to SPIR-V translation." OFF) -if (${ENABLE_DXIL2SPV}) - add_definitions(-DENABLE_DXIL2SPV) -endif() # SPIRV change ends include(VersionFromVCS) diff --git a/tools/clang/unittests/Dxil2Spv/LitTest.cpp b/tools/clang/unittests/Dxil2Spv/LitTest.cpp index 13f8a7659b..59b534cb80 100644 --- a/tools/clang/unittests/Dxil2Spv/LitTest.cpp +++ b/tools/clang/unittests/Dxil2Spv/LitTest.cpp @@ -27,16 +27,16 @@ class FileTest : public ::testing::Test { TEST_CLASS_SETUP(InitSupport); dxc::DxcDllSupport m_dllSupport; - VersionSupportInfo m_ver; + VersionSupportInfo m_version; void runFileTest(std::string name) { std::string fullPath = clang::dxil2spv::utils::getAbsPathOfInputDataFile(name); - FileRunTestResult t = + FileRunTestResult result = FileRunTestResult::RunFromFileCommands(CA2W(fullPath.c_str())); - if (t.RunResult != 0) { + if (result.RunResult != 0) { WEX::Logging::Log::Error(L"FileTest failed"); - WEX::Logging::Log::Error(CA2W(t.ErrorMessage.c_str(), CP_UTF8)); + WEX::Logging::Log::Error(CA2W(result.ErrorMessage.c_str(), CP_UTF8)); } } }; @@ -44,7 +44,7 @@ class FileTest : public ::testing::Test { bool FileTest::InitSupport() { if (!m_dllSupport.IsEnabled()) { VERIFY_SUCCEEDED(m_dllSupport.Initialize()); - m_ver.Initialize(m_dllSupport); + m_version.Initialize(m_dllSupport); } return true; } diff --git a/tools/clang/unittests/HLSLTestLib/CMakeLists.txt b/tools/clang/unittests/HLSLTestLib/CMakeLists.txt index b22e95b252..64caf5c4f9 100644 --- a/tools/clang/unittests/HLSLTestLib/CMakeLists.txt +++ b/tools/clang/unittests/HLSLTestLib/CMakeLists.txt @@ -28,7 +28,9 @@ include_directories(${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest/include) include_directories(${LLVM_MAIN_SRC_DIR}/utils/unittest/googlemock/include) if(ENABLE_DXIL2SPV) -include_directories( +target_compile_definitions(HLSLTestLib PRIVATE ENABLE_DXIL2SPV) + +target_include_directories(HLSLTestLib PRIVATE ${LLVM_SOURCE_DIR}/tools/clang/tools ${SPIRV_TOOLS_INCLUDE_DIR} ${SPIRV_HEADER_INCLUDE_DIR} diff --git a/tools/clang/unittests/HLSLTestLib/FileCheckerTest.cpp b/tools/clang/unittests/HLSLTestLib/FileCheckerTest.cpp index 8edc9f43bd..59818815a8 100644 --- a/tools/clang/unittests/HLSLTestLib/FileCheckerTest.cpp +++ b/tools/clang/unittests/HLSLTestLib/FileCheckerTest.cpp @@ -1118,7 +1118,7 @@ FileRunCommandPart::RunDxil2Spv(dxc::DxcDllSupport &DllSupport, try { // Configure filesystem. - llvm::sys::fs::MSFileSystem *msf; + llvm::sys::fs::MSFileSystem *msf = nullptr; HRESULT hr; if (SUCCEEDED(hr = CreateMSFileSystemForDisk(&msf))) { llvm::sys::fs::AutoPerThreadSystem pts(msf); @@ -1144,12 +1144,9 @@ FileRunCommandPart::RunDxil2Spv(dxc::DxcDllSupport &DllSupport, success = false; } - stdoutStream.flush(); - stderrStream.flush(); - FileRunCommandResult result = {}; - result.StdOut = stdoutString; - result.StdErr = stderrString; + result.StdOut = stdoutStream.str(); + result.StdErr = stderrStream.str(); result.ExitCode = success ? 0 : 1; return result;