Fix arg flatten issue caused by load before init. (#447)

* Fix arg flatten issue caused by load before init.
* Refine ShaderCompatSuite.
* Remove HLFunctions has body early.
This commit is contained in:
Xiang Li 2017-07-24 18:31:45 -07:00 коммит произвёл GitHub
Родитель bc55cacce2
Коммит 9db715523f
6 изменённых файлов: 165 добавлений и 25 удалений

Просмотреть файл

@ -1031,13 +1031,11 @@ void DxilGenerationPass::GenerateDxilOperations(
// Remove unused HL Operation functions. // Remove unused HL Operation functions.
std::vector<Function *> deadList; std::vector<Function *> deadList;
for (iplist<Function>::iterator F : M.getFunctionList()) { for (iplist<Function>::iterator F : M.getFunctionList()) {
if (F->isDeclaration()) {
hlsl::HLOpcodeGroup group = hlsl::GetHLOpcodeGroupByName(F); hlsl::HLOpcodeGroup group = hlsl::GetHLOpcodeGroupByName(F);
if (group != HLOpcodeGroup::NotHL || F->isIntrinsic()) if (group != HLOpcodeGroup::NotHL || F->isIntrinsic())
if (F->user_empty()) if (F->user_empty())
deadList.emplace_back(F); deadList.emplace_back(F);
} }
}
for (Function *F : deadList) for (Function *F : deadList)
F->eraseFromParent(); F->eraseFromParent();

Просмотреть файл

@ -4829,7 +4829,17 @@ Value *SROA_Parameter_HLSL::castArgumentIfRequired(
// Create load here to make correct type. // Create load here to make correct type.
// The Ptr will be store with correct value in replaceCastParameter and // The Ptr will be store with correct value in replaceCastParameter and
// replaceCastArgument. // replaceCastArgument.
if (Ptr->hasOneUse()) {
// Load after existing user for call arg replace.
// If not, call arg will load undef.
// This will not hurt parameter, new load is only after first load.
// It still before all the load users.
Instruction *User = cast<Instruction>(*(Ptr->user_begin()));
IRBuilder<> CallBuilder(User->getNextNode());
V = CallBuilder.CreateLoad(Ptr);
} else {
V = Builder.CreateLoad(Ptr); V = Builder.CreateLoad(Ptr);
}
castParamMap[V] = std::make_pair(Ptr, inputQual); castParamMap[V] = std::make_pair(Ptr, inputQual);
} }
@ -4877,11 +4887,16 @@ Value *SROA_Parameter_HLSL::castArgumentIfRequired(
vectorEltsMap[V].emplace_back(Elt); vectorEltsMap[V].emplace_back(Elt);
} }
} else { } else {
IRBuilder<> TmpBuilder(Builder.GetInsertPoint());
// Make sure extract element after OldV.
if (Instruction *OldI = dyn_cast<Instruction>(OldV)) {
TmpBuilder.SetInsertPoint(OldI->getNextNode());
}
// Split into scalar. // Split into scalar.
V = Builder.CreateExtractElement(OldV, (uint64_t)0); V = TmpBuilder.CreateExtractElement(OldV, (uint64_t)0);
vectorEltsMap[V].emplace_back(V); vectorEltsMap[V].emplace_back(V);
for (unsigned i = 1; i < vecSize; i++) { for (unsigned i = 1; i < vecSize; i++) {
Value *Elt = Builder.CreateExtractElement(OldV, i); Value *Elt = TmpBuilder.CreateExtractElement(OldV, i);
vectorEltsMap[V].emplace_back(Elt); vectorEltsMap[V].emplace_back(Elt);
} }
} }
@ -5673,6 +5688,9 @@ void SROA_Parameter_HLSL::createFlattenedFunction(Function *F) {
std::unique_ptr<BasicBlock> TmpBlockForFuncDecl; std::unique_ptr<BasicBlock> TmpBlockForFuncDecl;
if (F->isDeclaration()) { if (F->isDeclaration()) {
TmpBlockForFuncDecl.reset(BasicBlock::Create(Ctx)); TmpBlockForFuncDecl.reset(BasicBlock::Create(Ctx));
// Create return as terminator.
IRBuilder<> RetBuilder(TmpBlockForFuncDecl.get());
RetBuilder.CreateRetVoid();
} }
std::vector<Value *> FlatParamList; std::vector<Value *> FlatParamList;
@ -5690,7 +5708,7 @@ void SROA_Parameter_HLSL::createFlattenedFunction(Function *F) {
if (!F->isDeclaration()) { if (!F->isDeclaration()) {
Builder.SetInsertPoint(F->getEntryBlock().getFirstInsertionPt()); Builder.SetInsertPoint(F->getEntryBlock().getFirstInsertionPt());
} else { } else {
Builder.SetInsertPoint(TmpBlockForFuncDecl.get()); Builder.SetInsertPoint(TmpBlockForFuncDecl->getFirstInsertionPt());
} }
unsigned prevFlatParamCount = FlatParamList.size(); unsigned prevFlatParamCount = FlatParamList.size();
@ -5716,7 +5734,7 @@ void SROA_Parameter_HLSL::createFlattenedFunction(Function *F) {
if (!F->isDeclaration()) { if (!F->isDeclaration()) {
Builder.SetInsertPoint(F->getEntryBlock().getFirstInsertionPt()); Builder.SetInsertPoint(F->getEntryBlock().getFirstInsertionPt());
} else { } else {
Builder.SetInsertPoint(TmpBlockForFuncDecl.get()); Builder.SetInsertPoint(TmpBlockForFuncDecl->getFirstInsertionPt());
} }
Value *retValAddr = Builder.CreateAlloca(retType); Value *retValAddr = Builder.CreateAlloca(retType);
DxilParameterAnnotation &retAnnotation = DxilParameterAnnotation &retAnnotation =

Просмотреть файл

@ -0,0 +1,24 @@
// RUN: %dxc -T lib_6_1 %s | FileCheck %s
// Make sure no undef in test3.
// CHECK: define void
// CHECK-NOT: undef
// CHECK: ret void
struct T {
float2 v;
};
cbuffer M {
float2 m;
}
float test(T t);
float4 test3(){
float2 x = m + 2;
T t = { x };
float a = test(t);
t.v.x += 2;
return a + test(t);
}

Просмотреть файл

@ -39,6 +39,11 @@
#include "dia2.h" #include "dia2.h"
#include <fstream> #include <fstream>
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MSFileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
using namespace std; using namespace std;
using namespace hlsl_test; using namespace hlsl_test;
@ -525,7 +530,6 @@ public:
TEST_METHOD(CodeGenIntrinsic5) TEST_METHOD(CodeGenIntrinsic5)
TEST_METHOD(CodeGenInvalidInputOutputTypes) TEST_METHOD(CodeGenInvalidInputOutputTypes)
TEST_METHOD(CodeGenLegacyStruct) TEST_METHOD(CodeGenLegacyStruct)
TEST_METHOD(CodeGenLibArgFlatten)
TEST_METHOD(CodeGenLibCsEntry) TEST_METHOD(CodeGenLibCsEntry)
TEST_METHOD(CodeGenLibCsEntry2) TEST_METHOD(CodeGenLibCsEntry2)
TEST_METHOD(CodeGenLibCsEntry3) TEST_METHOD(CodeGenLibCsEntry3)
@ -1008,6 +1012,10 @@ public:
TEST_METHOD(ConstantFolding) TEST_METHOD(ConstantFolding)
TEST_METHOD(HoistConstantArray) TEST_METHOD(HoistConstantArray)
TEST_METHOD(ViewID) TEST_METHOD(ViewID)
TEST_METHOD(ShaderCompatSuite)
BEGIN_TEST_METHOD(SingleFileCheckTest)
TEST_METHOD_PROPERTY(L"Ignore", L"true")
END_TEST_METHOD()
dxc::DxcDllSupport m_dllSupport; dxc::DxcDllSupport m_dllSupport;
VersionSupportInfo m_ver; VersionSupportInfo m_ver;
@ -1308,9 +1316,8 @@ public:
VERIFY_ARE_NOT_EQUAL(0, disassembleString.size()); VERIFY_ARE_NOT_EQUAL(0, disassembleString.size());
} }
void CodeGenTestCheck(LPCWSTR name) { void CodeGenTestCheckFullPath(LPCWSTR fullPath) {
std::wstring fullPath = hlsl_test::GetPathToHlslDataFile(name); FileRunTestResult t = FileRunTestResult::RunFromFileCommands(fullPath);
FileRunTestResult t = FileRunTestResult::RunFromFileCommands(fullPath.c_str());
if (t.RunResult != 0) { if (t.RunResult != 0) {
CA2W commentWide(t.ErrorMessage.c_str(), CP_UTF8); CA2W commentWide(t.ErrorMessage.c_str(), CP_UTF8);
WEX::Logging::Log::Comment(commentWide); WEX::Logging::Log::Comment(commentWide);
@ -1318,6 +1325,19 @@ public:
} }
} }
void CodeGenTestCheck(LPCWSTR name) {
std::wstring fullPath = hlsl_test::GetPathToHlslDataFile(name);
CodeGenTestCheckFullPath(fullPath.c_str());
}
void CodeGenTestCheckBatch(LPCWSTR name, unsigned option) {
WEX::Logging::Log::StartGroup(name);
CodeGenTestCheckFullPath(name);
WEX::Logging::Log::EndGroup(name);
}
std::string VerifyCompileFailed(LPCSTR pText, LPWSTR pTargetProfile, LPCSTR pErrorMsg) { std::string VerifyCompileFailed(LPCSTR pText, LPWSTR pTargetProfile, LPCSTR pErrorMsg) {
return VerifyCompileFailed(pText, pTargetProfile, pErrorMsg, L"main"); return VerifyCompileFailed(pText, pTargetProfile, pErrorMsg, L"main");
} }
@ -3186,10 +3206,6 @@ TEST_F(CompilerTest, CodeGenLegacyStruct) {
CodeGenTestCheck(L"..\\CodeGenHLSL\\legacy_struct.hlsl"); CodeGenTestCheck(L"..\\CodeGenHLSL\\legacy_struct.hlsl");
} }
TEST_F(CompilerTest, CodeGenLibArgFlatten) {
CodeGenTestCheck(L"..\\CodeGenHLSL\\lib_arg_flatten.hlsl");
}
TEST_F(CompilerTest, CodeGenLibCsEntry) { TEST_F(CompilerTest, CodeGenLibCsEntry) {
CodeGenTestCheck(L"..\\CodeGenHLSL\\lib_cs_entry.hlsl"); CodeGenTestCheck(L"..\\CodeGenHLSL\\lib_cs_entry.hlsl");
} }
@ -5258,3 +5274,59 @@ TEST_F(CompilerTest, ViewID) {
CodeGenTestCheck(L"..\\CodeGenHLSL\\viewid\\viewid17.hlsl"); CodeGenTestCheck(L"..\\CodeGenHLSL\\viewid\\viewid17.hlsl");
CodeGenTestCheck(L"..\\CodeGenHLSL\\viewid\\viewid18.hlsl"); CodeGenTestCheck(L"..\\CodeGenHLSL\\viewid\\viewid18.hlsl");
} }
TEST_F(CompilerTest, ShaderCompatSuite) {
using namespace llvm;
using namespace WEX::TestExecution;
::llvm::sys::fs::MSFileSystem *msfPtr;
VERIFY_SUCCEEDED(CreateMSFileSystemForDisk(&msfPtr));
std::unique_ptr<::llvm::sys::fs::MSFileSystem> msf(msfPtr);
::llvm::sys::fs::AutoPerThreadSystem pts(msf.get());
IFTLLVM(pts.error_code());
std::wstring suitePath = L"..\\CodeGenHLSL\\shader-compat-suite";
WEX::Common::String value;
if (!DXC_FAILED(RuntimeParameters::TryGetValue(L"SuitePath", value)))
{
suitePath = value;
}
CW2A pUtf8Filename(suitePath.c_str());
if (!llvm::sys::path::is_absolute(pUtf8Filename.m_psz)) {
suitePath = hlsl_test::GetPathToHlslDataFile(suitePath.c_str());
}
CW2A utf8SuitePath(suitePath.c_str());
std::error_code EC;
llvm::SmallString<128> DirNative;
llvm::sys::path::native(utf8SuitePath.m_psz, DirNative);
for (llvm::sys::fs::recursive_directory_iterator Dir(DirNative, EC), DirEnd;
Dir != DirEnd && !EC; Dir.increment(EC)) {
// Check whether this entry has an extension typically associated with
// headers.
if (!llvm::StringSwitch<bool>(llvm::sys::path::extension(Dir->path()))
.Cases(".hlsl", ".hlsl", true)
.Default(false))
continue;
StringRef filename = Dir->path();
CA2W wRelPath(filename.data());
CodeGenTestCheckBatch(wRelPath.m_psz, 0);
}
}
TEST_F(CompilerTest, SingleFileCheckTest) {
using namespace llvm;
using namespace WEX::TestExecution;
WEX::Common::String value;
VERIFY_SUCCEEDED(RuntimeParameters::TryGetValue(L"InputFile", value));
std::wstring filename = value;
CW2A pUtf8Filename(filename.c_str());
if (!llvm::sys::path::is_absolute(pUtf8Filename.m_psz)) {
filename = hlsl_test::GetPathToHlslDataFile(filename.c_str());
}
CodeGenTestCheckBatch(filename.c_str(), 0);
}

Просмотреть файл

@ -17,6 +17,10 @@ set TEST_EXEC_REQUIRED=0
set TEST_CLANG_FILTER= /select: "@Priority<1" set TEST_CLANG_FILTER= /select: "@Priority<1"
set TEST_EXEC_FILTER=ExecutionTest::* set TEST_EXEC_FILTER=ExecutionTest::*
set LOG_FILTER=/logOutput:LowWithConsoleBuffering set LOG_FILTER=/logOutput:LowWithConsoleBuffering
set TEST_COMPAT_SUITE=0
set COMPAT_SUIT_PATH=
set TEST_SINGLE_FILE_CHECK=0
set SINGLE_FILE_CHECK_NAME=0
rem Begin SPIRV change rem Begin SPIRV change
set TEST_SPIRV=0 set TEST_SPIRV=0
@ -73,6 +77,16 @@ if "%1"=="-clean" (
set TEST_CLANG=1 set TEST_CLANG=1
set TEST_CLANG_FILTER= /name:%2 set TEST_CLANG_FILTER= /name:%2
shift /1 shift /1
) else if "%1"=="compat-suite" (
set TEST_ALL=0
set TEST_COMPAT_SUITE=1
set COMPAT_SUIT_PATH= /p:"SuitePath=%~2"
shift /1
) else if "%1"=="file-check" (
set TEST_ALL=0
set TEST_SINGLE_FILE_CHECK=1
set COMPAT_SUIT_PATH= /p:"InputFile=%~2"
shift /1
) else if "%1"=="v" ( ) else if "%1"=="v" (
set TEST_ALL=0 set TEST_ALL=0
set TEST_CLANG=1 set TEST_CLANG=1
@ -250,6 +264,16 @@ if exist "%HCT_EXTRAS%\hcttest-after.cmd" (
set RES_HCTTEST_AFTER=!ERRORLEVEL! set RES_HCTTEST_AFTER=!ERRORLEVEL!
) )
if "%TEST_SINGLE_FILE_CHECK%"=="1" (
call :runte clang-hlsl-tests.dll /p:"HlslDataDir=%HLSL_SRC_DIR%\tools\clang\test\HLSL" /name:CompilerTest::SingleFileCheckTest /runIgnoredTests %COMPAT_SUIT_PATH%
set RES_EXEC=!ERRORLEVEL!
)
if "%TEST_COMPAT_SUITE%"=="1" (
call :runte clang-hlsl-tests.dll /p:"HlslDataDir=%HLSL_SRC_DIR%\tools\clang\test\HLSL" /name:CompilerTest::ShaderCompatSuite %COMPAT_SUIT_PATH%
set RES_EXEC=!ERRORLEVEL!
)
echo. echo.
echo ================================== echo ==================================
echo Unit test results: echo Unit test results:
@ -300,6 +324,10 @@ echo -arm targets an ARM build
echo. echo.
echo target(s): echo target(s):
echo clang - run clang tests. echo clang - run clang tests.
echo file-check - run file-check test on single file.
echo - hcttest file-check "..\CodeGenHLSL\shader-compat-suite\lib_arg_flatten\lib_arg_flatten.hlsl"
echo compat-suite - run compat-suite test.
echo - hcttest compat-suite "..\CodeGenHLSL\shader-compat-suite\lib_arg_flatten"
echo cmd - run command line tool tests. echo cmd - run command line tool tests.
echo v - run the subset of clang tests that are verified-based. echo v - run the subset of clang tests that are verified-based.
echo exec - run execution tests. echo exec - run execution tests.