diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a9a60c2ee..1f6e06d1f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -608,6 +608,7 @@ endif() include_directories( ${LLVM_INCLUDE_DIR} ${LLVM_MAIN_INCLUDE_DIR}) +include_directories( ${LLVM_MAIN_INCLUDE_DIR}/dxc/Support) # HLSL Change include_directories( ${LLVM_INCLUDE_DIR}/dxc/Tracing) # HLSL Change # when crosscompiling import the executable targets from a file diff --git a/cmake/caches/PredefinedParams.cmake b/cmake/caches/PredefinedParams.cmake index 3313d8ebae..2a2c63a58f 100644 --- a/cmake/caches/PredefinedParams.cmake +++ b/cmake/caches/PredefinedParams.cmake @@ -22,19 +22,20 @@ set(LLVM_INCLUDE_TESTS ${LLVM_TEST_VALUE} CACHE BOOL "") set(CLANG_INCLUDE_TESTS ${LLVM_TEST_VALUE} CACHE BOOL "") set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE BOOL "") -set(LLVM_APPEND_VC_REV ON CACHE BOOL "") +set(LLVM_APPEND_VC_REV ON CACHE BOOL "") set(LLVM_DEFAULT_TARGET_TRIPLE "dxil-ms-dx" CACHE STRING "") -set(LLVM_ENABLE_EH ON CACHE BOOL "") -set(LLVM_ENABLE_RTTI ON CACHE BOOL "") -set(LLVM_INCLUDE_DOCS OFF CACHE BOOL "") -set(LLVM_INCLUDE_EXAMPLES OFF CACHE BOOL "") -set(LLVM_OPTIMIZED_TABLEGEN OFF CACHE BOOL "") +set(LLVM_ENABLE_EH ON CACHE BOOL "") +set(LLVM_ENABLE_RTTI ON CACHE BOOL "") +set(LLVM_INCLUDE_DOCS OFF CACHE BOOL "") +set(LLVM_INCLUDE_EXAMPLES OFF CACHE BOOL "") +set(LLVM_OPTIMIZED_TABLEGEN OFF CACHE BOOL "") set(LLVM_TARGETS_TO_BUILD "None" CACHE STRING "") -set(LIBCLANG_BUILD_STATIC ON CACHE BOOL "") -set(CLANG_BUILD_EXAMPLES OFF CACHE BOOL "") -set(CLANG_CL OFF CACHE BOOL "") -set(CLANG_ENABLE_ARCMT OFF CACHE BOOL "") -set(CLANG_ENABLE_STATIC_ANALYZER OFF CACHE BOOL "") -set(HLSL_INCLUDE_TESTS ON CACHE BOOL "") -set(ENABLE_SPIRV_CODEGEN ON CACHE BOOL "") +set(LIBCLANG_BUILD_STATIC ON CACHE BOOL "") +set(CLANG_BUILD_EXAMPLES OFF CACHE BOOL "") +set(CLANG_CL OFF CACHE BOOL "") +set(CLANG_ENABLE_ARCMT OFF CACHE BOOL "") +set(CLANG_ENABLE_STATIC_ANALYZER OFF CACHE BOOL "") +set(HLSL_INCLUDE_TESTS ON CACHE BOOL "") +set(ENABLE_SPIRV_CODEGEN ON CACHE BOOL "") set(SPIRV_BUILD_TESTS ON CACHE BOOL "") +set(LLVM_ENABLE_TERMINFO OFF CACHE BOOL "") diff --git a/cmake/modules/AddLLVM.cmake b/cmake/modules/AddLLVM.cmake index a6dc7464e6..d600ec7263 100644 --- a/cmake/modules/AddLLVM.cmake +++ b/cmake/modules/AddLLVM.cmake @@ -446,10 +446,20 @@ function(llvm_add_library name) ) endif() + # HLSL Change Begin - Don't generate so versioned files. set_target_properties(${name} PROPERTIES SOVERSION ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR} - VERSION ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}${LLVM_VERSION_SUFFIX}) + VERSION ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}${LLVM_VERSION_SUFFIX} + NO_SONAME On) + if (APPLE) + set_property(TARGET ${name} APPEND_STRING PROPERTY + LINK_FLAGS " -Wl,-install_name,@rpath/${CMAKE_SHARED_LIBRARY_PREFIX}${name}${CMAKE_SHARED_LIBRARY_SUFFIX}") + elseif(UNIX) + set_property(TARGET ${name} APPEND_STRING PROPERTY + LINK_FLAGS " -Wl,-soname,${CMAKE_SHARED_LIBRARY_PREFIX}${name}${CMAKE_SHARED_LIBRARY_SUFFIX}") + endif() + # HLSL Change End - Don't generate so versioned files. endif() if(ARG_MODULE OR ARG_SHARED) diff --git a/include/dxc/Support/dxcapi.use.h b/include/dxc/Support/dxcapi.use.h index be2209a348..b47686bed0 100644 --- a/include/dxc/Support/dxcapi.use.h +++ b/include/dxc/Support/dxcapi.use.h @@ -16,6 +16,9 @@ namespace dxc { + extern const char* kDxCompilerLib; + extern const char* kDxilLib; + // Helper class to dynamically load the dxcompiler or a compatible libraries. class DxcDllSupport { protected: @@ -23,35 +26,31 @@ class DxcDllSupport { DxcCreateInstanceProc m_createFn; DxcCreateInstance2Proc m_createFn2; - HRESULT InitializeInternal(LPCWSTR dllName, LPCSTR fnName) { + HRESULT InitializeInternal(LPCSTR dllName, LPCSTR fnName) { if (m_dll != nullptr) return S_OK; #ifdef _WIN32 - m_dll = LoadLibraryW(dllName); -#else - char nameStr[256]; - std::wcstombs(nameStr, dllName, 256); - m_dll = ::dlopen(nameStr, RTLD_LAZY); -#endif - + m_dll = LoadLibraryA(dllName); if (m_dll == nullptr) return HRESULT_FROM_WIN32(GetLastError()); - -#ifdef _WIN32 m_createFn = (DxcCreateInstanceProc)GetProcAddress(m_dll, fnName); -#else - m_createFn = (DxcCreateInstanceProc)::dlsym(m_dll, fnName); -#endif - + if (m_createFn == nullptr) { HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); -#ifdef _WIN32 FreeLibrary(m_dll); + m_dll = nullptr; + return hr; + } #else + m_dll = ::dlopen(dllName, RTLD_LAZY); + if (m_dll == nullptr) return E_FAIL; + m_createFn = (DxcCreateInstanceProc)::dlsym(m_dll, fnName); + + if (m_createFn == nullptr) { ::dlclose(m_dll); -#endif m_dll = nullptr; - return hr; + return E_FAIL; } +#endif // Only basic functions used to avoid requiring additional headers. m_createFn2 = nullptr; @@ -86,16 +85,10 @@ class DxcDllSupport { } HRESULT Initialize() { - #ifdef _WIN32 - return InitializeInternal(L"dxcompiler.dll", "DxcCreateInstance"); - #elif __APPLE__ - return InitializeInternal(L"libdxcompiler.dylib", "DxcCreateInstance"); - #else - return InitializeInternal(L"libdxcompiler.so", "DxcCreateInstance"); - #endif + return InitializeInternal(kDxCompilerLib, "DxcCreateInstance"); } - HRESULT InitializeForDll(_In_z_ const wchar_t* dll, _In_z_ const char* entryPoint) { + HRESULT InitializeForDll(_In_z_ LPCSTR dll, _In_z_ LPCSTR entryPoint) { return InitializeInternal(dll, entryPoint); } diff --git a/include/dxc/dxcapi.h b/include/dxc/dxcapi.h index 045700310b..8f72b380c4 100644 --- a/include/dxc/dxcapi.h +++ b/include/dxc/dxcapi.h @@ -34,7 +34,7 @@ #else #include -#include "dxc/Support/WinAdapter.h" +#include "WinAdapter.h" #endif struct IMalloc; diff --git a/include/dxc/dxcisense.h b/include/dxc/dxcisense.h index 04b5e9b2c9..de1a7ea5c3 100644 --- a/include/dxc/dxcisense.h +++ b/include/dxc/dxcisense.h @@ -14,7 +14,7 @@ #include "dxcapi.h" #ifndef _WIN32 -#include "Support/WinAdapter.h" +#include "WinAdapter.h" #endif typedef enum DxcGlobalOptions diff --git a/lib/DxcSupport/CMakeLists.txt b/lib/DxcSupport/CMakeLists.txt index beaf97c967..5496ee05f8 100644 --- a/lib/DxcSupport/CMakeLists.txt +++ b/lib/DxcSupport/CMakeLists.txt @@ -11,4 +11,12 @@ add_llvm_library(LLVMDxcSupport WinFunctions.cpp ) +#generate header with platform-specific library name +configure_file( +${LLVM_MAIN_SRC_DIR}/lib/DxcSupport/SharedLibAffix.inc +SharedLibAffix.h +) + +include_directories( ${LLVM_INCLUDE_DIR}/DxcSupport) #needed to find the generated header + add_dependencies(LLVMDxcSupport TablegenHLSLOptions) diff --git a/lib/DxcSupport/HLSLOptions.cpp b/lib/DxcSupport/HLSLOptions.cpp index 5f99dc98cf..f643ca416e 100644 --- a/lib/DxcSupport/HLSLOptions.cpp +++ b/lib/DxcSupport/HLSLOptions.cpp @@ -1183,9 +1183,8 @@ int SetupDxcDllSupport(const DxcOpts &opts, dxc::DxcDllSupport &dxcSupport, llvm::raw_ostream &errors) { if (!opts.ExternalLib.empty()) { DXASSERT(!opts.ExternalFn.empty(), "else ReadDxcOpts should have failed"); - StringRefWide externalLib(opts.ExternalLib); HRESULT hrLoad = - dxcSupport.InitializeForDll(externalLib, opts.ExternalFn.data()); + dxcSupport.InitializeForDll(opts.ExternalLib.data(), opts.ExternalFn.data()); if (DXC_FAILED(hrLoad)) { errors << "Unable to load support for external DLL " << opts.ExternalLib << " with function " << opts.ExternalFn << " - error 0x"; diff --git a/lib/DxcSupport/SharedLibAffix.inc b/lib/DxcSupport/SharedLibAffix.inc new file mode 100644 index 0000000000..06137796fd --- /dev/null +++ b/lib/DxcSupport/SharedLibAffix.inc @@ -0,0 +1,24 @@ +/////////////////////////////////////////////////////////////////////////////// +// // +// SharedLibAffix.inc // +// Copyright (C) Microsoft Corporation. All rights reserved. // +// This file is distributed under the University of Illinois Open Source // +// License. See LICENSE.TXT for details. // +// // +// Defines shared library prefixes and suffixes for the build platform. // +// // +/////////////////////////////////////////////////////////////////////////////// + + +#pragma once + +#cmakedefine CMAKE_SHARED_LIBRARY_PREFIX "@CMAKE_SHARED_LIBRARY_PREFIX@" +#cmakedefine CMAKE_SHARED_LIBRARY_SUFFIX "@CMAKE_SHARED_LIBRARY_SUFFIX@" + +#ifndef CMAKE_SHARED_LIBRARY_PREFIX +#define CMAKE_SHARED_LIBRARY_PREFIX +#endif + +#ifndef CMAKE_SHARED_LIBRARY_SUFFIX +#define CMAKE_SHARED_LIBRARY_SUFFIX +#endif \ No newline at end of file diff --git a/lib/DxcSupport/dxcapi.use.cpp b/lib/DxcSupport/dxcapi.use.cpp index 1b1c3a657f..927174a1be 100644 --- a/lib/DxcSupport/dxcapi.use.cpp +++ b/lib/DxcSupport/dxcapi.use.cpp @@ -15,9 +15,13 @@ #include "dxc/Support/Unicode.h" #include "dxc/Support/FileIOHelper.h" #include "dxc/Support/WinFunctions.h" +#include "SharedLibAffix.h" namespace dxc { +const char* kDxCompilerLib = CMAKE_SHARED_LIBRARY_PREFIX "dxcompiler" CMAKE_SHARED_LIBRARY_SUFFIX; +const char* kDxilLib = CMAKE_SHARED_LIBRARY_PREFIX "dxil" CMAKE_SHARED_LIBRARY_SUFFIX; + #ifdef _WIN32 static void TrimEOL(_Inout_z_ char *pMsg) { char *pEnd = pMsg + strlen(pMsg); diff --git a/lib/DxilDia/DxcPixDxilDebugInfo.cpp b/lib/DxilDia/DxcPixDxilDebugInfo.cpp index 5242d8ae2b..3f2e024dcf 100644 --- a/lib/DxilDia/DxcPixDxilDebugInfo.cpp +++ b/lib/DxilDia/DxcPixDxilDebugInfo.cpp @@ -9,12 +9,15 @@ // // /////////////////////////////////////////////////////////////////////////////// +#include "dxc/DXIL/DxilOperations.h" + #include "dxc/Support/WinIncludes.h" #include "dxc/Support/exception.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/DebugInfo.h" #include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/Module.h" #include "DxcPixLiveVariables.h" #include "DxcPixDxilDebugInfo.h" @@ -172,24 +175,25 @@ dxil_debug_info::DxcPixDxilInstructionOffsets::DxcPixDxilInstructionOffsets( { assert(SourceColumn == 0); (void)SourceColumn; - auto Fn = pSession->DxilModuleRef().GetEntryFunction(); - auto &Blocks = Fn->getBasicBlockList(); - for (auto& CurrentBlock : Blocks) { - auto& Is = CurrentBlock.getInstList(); - for (auto& Inst : Is) { - auto & debugLoc = Inst.getDebugLoc(); - if (debugLoc) - { - unsigned line = debugLoc.getLine(); - if (line == SourceLine) - { - auto file = debugLoc.get()->getFilename(); - if (CompareFilenames(FileName, file.str().c_str())) - { - std::uint32_t InstructionNumber; - if (pix_dxil::PixDxilInstNum::FromInst(&Inst, &InstructionNumber)) - { - m_offsets.push_back(InstructionNumber); + for (llvm::Function &Fn : + pSession->DxilModuleRef().GetModule()->functions()) { + if (Fn.isDeclaration() || Fn.isIntrinsic() || hlsl::OP::IsDxilOpFunc(&Fn)) + continue; + auto &Blocks = Fn.getBasicBlockList(); + for (auto &CurrentBlock : Blocks) { + auto &Is = CurrentBlock.getInstList(); + for (auto &Inst : Is) { + auto &debugLoc = Inst.getDebugLoc(); + if (debugLoc) { + unsigned line = debugLoc.getLine(); + if (line == SourceLine) { + auto file = debugLoc.get()->getFilename(); + if (CompareFilenames(FileName, file.str().c_str())) { + std::uint32_t InstructionNumber; + if (pix_dxil::PixDxilInstNum::FromInst(&Inst, + &InstructionNumber)) { + m_offsets.push_back(InstructionNumber); + } } } } diff --git a/lib/DxilDia/DxilDiaSymbolManager.cpp b/lib/DxilDia/DxilDiaSymbolManager.cpp index 3efced6ffd..bc1cfcc39d 100644 --- a/lib/DxilDia/DxilDiaSymbolManager.cpp +++ b/lib/DxilDia/DxilDiaSymbolManager.cpp @@ -1570,6 +1570,11 @@ HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateCompositeType(DWORD dwP } else { for (llvm::DINode *N : CT->getElements()) { if (auto *Field = llvm::dyn_cast(N)) { + std::unique_ptr UDTScopeOverride; + if (Field->isStaticMember()) { + // Static members do not contribute to sizes or offsets. + UDTScopeOverride.reset(new UDTScope(&m_pCurUDT, nullptr)); + } DWORD dwUnusedFieldID; IFR(CreateType(Field, &dwUnusedFieldID)); if (Field->getTag() == llvm::dwarf::DW_TAG_inheritance) { diff --git a/lib/HLSL/DxilValidation.cpp b/lib/HLSL/DxilValidation.cpp index 72bf204a1c..16787eef2f 100644 --- a/lib/HLSL/DxilValidation.cpp +++ b/lib/HLSL/DxilValidation.cpp @@ -5563,7 +5563,7 @@ static void VerifyRDATMatches(_In_ ValidationContext &ValCtx, VerifyBlobPartMatches(ValCtx, PartName, pWriter.get(), pRDATData, RDATSize); // Verify no errors when runtime reflection from RDAT: - RDAT::DxilRuntimeReflection *pReflection = RDAT::CreateDxilRuntimeReflection(); + unique_ptr pReflection(RDAT::CreateDxilRuntimeReflection()); if (!pReflection->InitFromRDAT(pRDATData, RDATSize)) { ValCtx.EmitFormatError(ValidationRule::ContainerPartMatches, { PartName }); return; diff --git a/lib/Transforms/Scalar/Scalarizer.cpp b/lib/Transforms/Scalar/Scalarizer.cpp index 2872ad0850..729771c7c7 100644 --- a/lib/Transforms/Scalar/Scalarizer.cpp +++ b/lib/Transforms/Scalar/Scalarizer.cpp @@ -633,7 +633,7 @@ bool Scalarizer::visitShuffleVectorInst(ShuffleVectorInst &SVI) { // instruction is processed, it will be replaced without updating our // Gather entry. This dead instruction will be accessed by finish(), // causing assert or crash. - Res[I] = IRBuilder<>(SVI.getNextNode()).Insert(EA->clone()); + Res[I] = IRBuilder<>(&SVI).Insert(EA->clone()); } // HLSL Change Ends } diff --git a/projects/dxilconv/unittests/DxilConvTests.cpp b/projects/dxilconv/unittests/DxilConvTests.cpp index 1284fc65e4..233a8a277f 100644 --- a/projects/dxilconv/unittests/DxilConvTests.cpp +++ b/projects/dxilconv/unittests/DxilConvTests.cpp @@ -166,7 +166,7 @@ class DxilConvTest { bool DxilConvTest::InitSupport() { if (!m_dllSupport.IsEnabled()) { - VERIFY_SUCCEEDED(m_dllSupport.InitializeForDll(L"dxilconv.dll", "DxcCreateInstance")); + VERIFY_SUCCEEDED(m_dllSupport.InitializeForDll("dxilconv.dll", "DxcCreateInstance")); } if (!FindToolInBinDir("%dxbc2dxil", "dxbc2dxil.exe")) { diff --git a/tools/clang/include/clang/Basic/DiagnosticGroups.td b/tools/clang/include/clang/Basic/DiagnosticGroups.td index ca84158902..9f4973b59e 100644 --- a/tools/clang/include/clang/Basic/DiagnosticGroups.td +++ b/tools/clang/include/clang/Basic/DiagnosticGroups.td @@ -798,4 +798,5 @@ def HLSLPayloadAccessQualifer: DiagGroup<"payload-access-qualifier", [ HLSLPayloadAccessQualiferCall ]>; def HLSLSemanticIdentifierCollision : DiagGroup<"semantic-identifier-collision">; +def HLSLStructurizeExitsLifetimeMarkersConflict: DiagGroup<"structurize-exits-lifetime-markers-conflict">; // HLSL Change Ends diff --git a/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td b/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td index b3fe510f2e..c97501e084 100644 --- a/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7754,6 +7754,9 @@ def err_hlsl_logical_binop_scalar : Error< "operands for short-circuiting logical binary operator must be scalar, for non-scalar types use '%select{and|or}0'">; def err_hlsl_ternary_scalar : Error< "condition for short-circuiting ternary operator must be scalar, for non-scalar types use 'select'">; +def warn_hlsl_structurize_exits_lifetime_markers_conflict : Warning < + "structurize-returns skipped function '%0' due to incompatibility with lifetime markers. Use -disable-lifetime-markers to enable structurize-exits on this function.">, + InGroup< HLSLStructurizeExitsLifetimeMarkersConflict >; // HLSL Change Ends // SPIRV Change Starts diff --git a/tools/clang/include/clang/SPIRV/SpirvBuilder.h b/tools/clang/include/clang/SPIRV/SpirvBuilder.h index 1e19d80ed4..c2f20ce4a4 100644 --- a/tools/clang/include/clang/SPIRV/SpirvBuilder.h +++ b/tools/clang/include/clang/SPIRV/SpirvBuilder.h @@ -26,10 +26,10 @@ namespace spirv { struct StringMapInfo { static inline std::string getEmptyKey() { return ""; } static inline std::string getTombstoneKey() { return ""; } - static unsigned getHashValue(const std::string Val) { + static unsigned getHashValue(const std::string& Val) { return llvm::hash_combine(Val); } - static bool isEqual(const std::string LHS, const std::string RHS) { + static bool isEqual(const std::string& LHS, const std::string& RHS) { // Either both are null, or both should have the same underlying type. return LHS == RHS; } @@ -851,7 +851,7 @@ class SpirvBuilder { // kept track of separately. This is because the empty string is used // as the EmptyKey and TombstoneKey for the map, prohibiting insertion // of the empty string as a contained value. - llvm::DenseMap stringLiterals; + llvm::DenseMap stringLiterals; SpirvString *emptyString; /// Mapping of CTBuffers including matrix 1xN with FXC memory layout to their diff --git a/tools/clang/lib/CodeGen/CGCleanup.cpp b/tools/clang/lib/CodeGen/CGCleanup.cpp index 9bc88cb3cd..988ff07954 100644 --- a/tools/clang/lib/CodeGen/CGCleanup.cpp +++ b/tools/clang/lib/CodeGen/CGCleanup.cpp @@ -19,6 +19,7 @@ #include "CGCleanup.h" #include "CodeGenFunction.h" +#include "CGHLSLRuntime.h" // HLSL Change using namespace clang; using namespace CodeGen; @@ -435,6 +436,7 @@ static llvm::BasicBlock *CreateNormalEntry(CodeGenFunction &CGF, if (!Entry) { Entry = CGF.createBasicBlock("cleanup"); Scope.setNormalBlock(Entry); + CGF.CGM.getHLSLRuntime().MarkCleanupBlock(CGF, Entry); // HLSL Change } return Entry; } diff --git a/tools/clang/lib/CodeGen/CGHLSLMS.cpp b/tools/clang/lib/CodeGen/CGHLSLMS.cpp index 8b76120627..c60e146045 100644 --- a/tools/clang/lib/CodeGen/CGHLSLMS.cpp +++ b/tools/clang/lib/CodeGen/CGHLSLMS.cpp @@ -304,6 +304,7 @@ class CGMSHLSLRuntime : public CGHLSLRuntime { void MarkSwitchStmt(CodeGenFunction &CGF, SwitchInst *switchInst, BasicBlock *endSwitch) override; void MarkReturnStmt(CodeGenFunction &CGF, BasicBlock *bbWithRet) override; + void MarkCleanupBlock(CodeGenFunction &CGF, llvm::BasicBlock *cleanupBB) override; void MarkLoopStmt(CodeGenFunction &CGF, BasicBlock *loopContinue, BasicBlock *loopExit) override; CGHLSLMSHelper::Scope* MarkScopeEnd(CodeGenFunction &CGF) override; @@ -2393,7 +2394,7 @@ void CGMSHLSLRuntime::AddHLSLFunctionInfo(Function *F, const FunctionDecl *FD) { F->addFnAttr(Twine("exp-", Attr->getName()).str(), Attr->getValue()); } - m_ScopeMap[F] = ScopeInfo(F); + m_ScopeMap[F] = ScopeInfo(F, FD->getLocation()); } void CGMSHLSLRuntime::RemapObsoleteSemantic(DxilParameterAnnotation ¶mInfo, bool isPatchConstantFunction) { @@ -6233,6 +6234,10 @@ void CGMSHLSLRuntime::MarkIfStmt(CodeGenFunction &CGF, BasicBlock *endIfBB) { Scope->AddIf(endIfBB); } +void CGMSHLSLRuntime::MarkCleanupBlock(CodeGenFunction &CGF, llvm::BasicBlock *cleanupBB) { + if (ScopeInfo *Scope = GetScopeInfo(CGF.CurFn)) + Scope->AddCleanupBB(cleanupBB); +} void CGMSHLSLRuntime::MarkSwitchStmt(CodeGenFunction &CGF, SwitchInst *switchInst, diff --git a/tools/clang/lib/CodeGen/CGHLSLMSFinishCodeGen.cpp b/tools/clang/lib/CodeGen/CGHLSLMSFinishCodeGen.cpp index cfc3ec8481..a3bb1e8299 100644 --- a/tools/clang/lib/CodeGen/CGHLSLMSFinishCodeGen.cpp +++ b/tools/clang/lib/CodeGen/CGHLSLMSFinishCodeGen.cpp @@ -29,6 +29,7 @@ #include "clang/Basic/LangOptions.h" #include "clang/Frontend/CodeGenOptions.h" #include "clang/Parse/ParseHLSL.h" // root sig would be in Parser if part of lang +#include "clang/Sema/SemaDiagnostic.h" #include "CodeGenFunction.h" #include "dxc/DXIL/DxilConstants.h" @@ -3309,7 +3310,7 @@ void AddDxBreak(Module &M, namespace CGHLSLMSHelper { -ScopeInfo::ScopeInfo(Function *F) : maxRetLevel(0), bAllReturnsInIf(true) { +ScopeInfo::ScopeInfo(Function *F, clang::SourceLocation loc) : maxRetLevel(0), bAllReturnsInIf(true), sourceLoc(loc) { Scope FuncScope; FuncScope.kind = Scope::ScopeKind::FunctionScope; FuncScope.EndScopeBB = nullptr; @@ -3549,12 +3550,21 @@ static void ChangePredBranch(BasicBlock *BB, BasicBlock *NewBB) { // } // return vRet; // } -void StructurizeMultiRetFunction(Function *F, ScopeInfo &ScopeInfo, +void StructurizeMultiRetFunction(Function *F, clang::DiagnosticsEngine &Diags, ScopeInfo &ScopeInfo, bool bWaveEnabledStage, SmallVector &DxBreaks) { if (ScopeInfo.CanSkipStructurize()) return; + + // If there are cleanup blocks generated for lifetime markers, do + // not structurize returns. The scope info recorded is no longer correct. + if (ScopeInfo.HasCleanupBlocks()) { + Diags.Report(ScopeInfo.GetSourceLocation(), clang::diag::warn_hlsl_structurize_exits_lifetime_markers_conflict) + << F->getName(); + return; + } + // Get bbWithRets. auto &rets = ScopeInfo.GetRetScopes(); @@ -3722,7 +3732,8 @@ void StructurizeMultiRet(Module &M, clang::CodeGen::CodeGenModule &CGM, auto it = ScopeMap.find(&F); if (it == ScopeMap.end()) continue; - StructurizeMultiRetFunction(&F, it->second, bWaveEnabledStage, DxBreaks); + + StructurizeMultiRetFunction(&F, CGM.getDiags(), it->second, bWaveEnabledStage, DxBreaks); } } diff --git a/tools/clang/lib/CodeGen/CGHLSLMSHelper.h b/tools/clang/lib/CodeGen/CGHLSLMSHelper.h index 1c0cf76eb1..b2937434ea 100644 --- a/tools/clang/lib/CodeGen/CGHLSLMSHelper.h +++ b/tools/clang/lib/CodeGen/CGHLSLMSHelper.h @@ -122,11 +122,12 @@ struct Scope { class ScopeInfo { public: ScopeInfo(){} - ScopeInfo(llvm::Function *F); + ScopeInfo(llvm::Function *F, clang::SourceLocation loc); void AddIf(llvm::BasicBlock *endIfBB); void AddSwitch(llvm::BasicBlock *endSwitchBB); void AddLoop(llvm::BasicBlock *loopContinue, llvm::BasicBlock *endLoopBB); void AddRet(llvm::BasicBlock *bbWithRet); + void AddCleanupBB(llvm::BasicBlock *cleanupBB) { hasCleanupBlocks = true; } Scope &EndScope(bool bScopeFinishedWithRet); Scope &GetScope(unsigned i); const llvm::SmallVector &GetRetScopes() { return rets; } @@ -134,15 +135,19 @@ class ScopeInfo { llvm::SmallVector &GetScopes() { return scopes; } bool CanSkipStructurize(); void dump(); + bool HasCleanupBlocks() const { return hasCleanupBlocks; } + clang::SourceLocation GetSourceLocation() const { return sourceLoc; } private: void AddScope(Scope::ScopeKind k, llvm::BasicBlock *endScopeBB); + bool hasCleanupBlocks = false; llvm::SmallVector rets; unsigned maxRetLevel; bool bAllReturnsInIf; llvm::SmallVector scopeStack; // save all scopes. llvm::SmallVector scopes; + clang::SourceLocation sourceLoc; }; // Map from value to resource properties. diff --git a/tools/clang/lib/CodeGen/CGHLSLRuntime.h b/tools/clang/lib/CodeGen/CGHLSLRuntime.h index aa841a3c9c..6f8ec2b02e 100644 --- a/tools/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/tools/clang/lib/CodeGen/CGHLSLRuntime.h @@ -140,6 +140,7 @@ class CGHLSLRuntime { clang::QualType FnRetTy, const std::function &TmpArgMap) = 0; virtual void MarkIfStmt(CodeGenFunction &CGF, llvm::BasicBlock *endIfBB) = 0; + virtual void MarkCleanupBlock(CodeGenFunction &CGF, llvm::BasicBlock *cleanupBB) = 0; virtual void MarkSwitchStmt(CodeGenFunction &CGF, llvm::SwitchInst *switchInst, llvm::BasicBlock *endSwitch) = 0; diff --git a/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp b/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp index e569637a52..3edce78b91 100644 --- a/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp +++ b/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp @@ -2095,7 +2095,7 @@ bool DeclResultIdMapper::finalizeStageIOLocations(bool forInput) { // If alphabetical ordering was requested, sort by semantic string. if (spirvOptions.stageIoOrder == "alpha") { // Sort stage input/output variables alphabetically - std::sort(vars.begin(), vars.end(), + std::stable_sort(vars.begin(), vars.end(), [](const StageVar *a, const StageVar *b) { return a->getSemanticStr() < b->getSemanticStr(); }); @@ -2117,7 +2117,7 @@ bool DeclResultIdMapper::finalizeStageIOLocations(bool forInput) { // alphabetical ordering. if ((!forInput && spvContext.isHS()) || (forInput && spvContext.isDS())) { // Sort stage input/output variables alphabetically - std::sort(vars.begin(), vars.end(), + std::stable_sort(vars.begin(), vars.end(), [](const StageVar *a, const StageVar *b) { return a->getSemanticStr() < b->getSemanticStr(); }); diff --git a/tools/clang/test/HLSLFileCheck/hlsl/control_flow/return/lifetime-markers.hlsl b/tools/clang/test/HLSLFileCheck/hlsl/control_flow/return/lifetime-markers.hlsl new file mode 100644 index 0000000000..5eb07a7b61 --- /dev/null +++ b/tools/clang/test/HLSLFileCheck/hlsl/control_flow/return/lifetime-markers.hlsl @@ -0,0 +1,68 @@ +// RUN: %dxc -fdisable-loc-tracking -E main -opt-enable structurize-returns -T cs_6_0 -enable-lifetime-markers -fcgl %s | FileCheck %s -check-prefix=FCGL +// RUN: %dxc -fdisable-loc-tracking -E main -opt-enable structurize-returns -T cs_6_0 -enable-lifetime-markers %s | FileCheck %s +// RUN: %dxc -fdisable-loc-tracking -E main -opt-enable structurize-returns -T cs_6_0 -enable-lifetime-markers %s | FileCheck %s -check-prefix=WARNING -input-file=stderr +// RUN: %dxc -fdisable-loc-tracking -E main -opt-enable structurize-returns -T cs_6_0 -disable-lifetime-markers -fcgl %s | FileCheck %s -check-prefix=NO-LIFETIME + +// Regression test for a bug where program structure is completely messed up when lifetime-markers are enabled and +// -opt-enable structurize-returns is on. The scope information recorded during codegen that structurize-returns uses +// to modify the control flow is incorrect if lifetime-markers are enabled. This test checks that + +//================================= +// The fcgl test checks the return condition alloca bReturn is not generated and the cleanup code for lifetime-markers +// is present. +// FCGL-NOT: bReturned +// FCGL: %cleanup.dest + +//================================= +// The non-fcgl test checks the shader is compiled correctly (the bug causes irreducible flow) +// CHECK-DAG: @main + +//================================= +// Check a warning was emitted. +// WARNING: structurize-returns skipped function 'main' due to incompatibility with lifetime markers. Use -disable-lifetime-markers to enable structurize-exits on this function. + +//================================= +// The last test makes sure structurize-returns runs as expected +// NO-LIFETIME: @main +// NO-LIFETIME: %bReturned = alloca + +struct D { + float3 d_member; +}; + +struct A { + float4 a_member; +}; + +struct B { + uint flags; +} ; + +struct C { + uint c_member; +}; + +StructuredBuffer srv0 : register(t0) ; +StructuredBuffer srv1 : register(t1) ; +RWStructuredBuffer uav0 : register(u0) ; + +[RootSignature("DescriptorTable(SRV(t0,numDescriptors=10)),DescriptorTable(UAV(u0,numDescriptors=10))")] +[numthreads (64, 1, 1)] +void main(uint3 dtid : SV_DispatchThreadID) { + if (dtid.x < 10) { + A decal = (A)0; + { + const D d = srv0[0]; + if (!d.d_member.x) + return; + } + B b = srv1[0]; + if (b.flags & 1) { + InterlockedMax(uav0[0].c_member, 10) ; + return; + } + + InterlockedMax(uav0[0].c_member, 20) ; + } + InterlockedMax(uav0[0].c_member, 30) ; +} diff --git a/tools/clang/test/HLSLFileCheckLit/passes/llvm/scalarizer/shuffle_use_extract_elt.ll b/tools/clang/test/HLSLFileCheckLit/passes/llvm/scalarizer/shuffle_use_extract_elt.ll new file mode 100644 index 0000000000..e40e252c26 --- /dev/null +++ b/tools/clang/test/HLSLFileCheckLit/passes/llvm/scalarizer/shuffle_use_extract_elt.ll @@ -0,0 +1,33 @@ +; RUN: opt -S -scalarizer -dce %s | FileCheck %s + +; CHECK: %[[B:.+]] = load <2 x float>, <2 x float>* %b, align 4 +; CHECK: %[[BX0:.+]] = extractelement <2 x float> %[[B]], i32 0 +; CHECK: %[[BY0:.+]] = extractelement <2 x float> %[[B]], i32 1 +; CHECK: %[[BX1:.+]] = extractelement <2 x float> %[[B]], i32 0 +; CHECK: %[[BY1:.+]] = extractelement <2 x float> %[[B]], i32 1 + +; CHECK: %[[X:.+]] = insertelement <4 x float> undef, float %[[BX0]], i32 0 +; CHECK: %[[Y:.+]] = insertelement <4 x float> %[[X]], float %[[BY0]], i32 1 +; CHECK: %[[Z:.+]] = insertelement <4 x float> %[[Y]], float %[[BX1]], i32 2 +; CHECK: %[[W:.+]] = insertelement <4 x float> %[[Z]], float %[[BY1]], i32 3 +; CHECK: ret <4 x float> %[[W]] + +declare void @foo(<2 x float>, <2 x float>* dereferenceable(8)) + +; Function Attrs: noinline nounwind +define internal <4 x float> @bar(<3 x float> %v) #0 { +entry: + %0 = alloca <2 x float> + %b = alloca <2 x float>, align 4 + store <2 x float> zeroinitializer, <2 x float>* %b, align 4 + %1 = insertelement <3 x float> %v, float 1.000000e+00, i32 0 + %2 = shufflevector <3 x float> %1, <3 x float> undef, <2 x i32> + store <2 x float> %2, <2 x float>* %0 + ;call void @foo(<2 x float>* dereferenceable(8) %0, <2 x float>* dereferenceable(8) %b) + %3 = load <2 x float>, <2 x float>* %b, align 4 + %4 = shufflevector <2 x float> %3, <2 x float> undef, <4 x i32> + ret <4 x float> %4 +} + +attributes #0 = { noinline nounwind } + diff --git a/tools/clang/tools/dxclib/dxc.cpp b/tools/clang/tools/dxclib/dxc.cpp index e9de115bd6..5a7801970f 100644 --- a/tools/clang/tools/dxclib/dxc.cpp +++ b/tools/clang/tools/dxclib/dxc.cpp @@ -1189,7 +1189,7 @@ void WriteDxCompilerVersionInfo(llvm::raw_ostream &OS, CComPtr VerInfo2; #endif // SUPPORT_QUERY_GIT_COMMIT_INFO - const char *dllName = !ExternalLib ? "dxcompiler.dll" : ExternalLib; + const char *dllName = !ExternalLib ? kDxCompilerLib : ExternalLib; std::string compilerName(dllName); if (ExternalFn) compilerName = compilerName + "!" + ExternalFn; @@ -1244,17 +1244,17 @@ void WriteDXILVersionInfo(llvm::raw_ostream &OS, UINT32 validatorMajor, validatorMinor = 0; VerInfo->GetVersion(&validatorMajor, &validatorMinor); OS << "; " - << "dxil.dll" + << kDxilLib << ": " << validatorMajor << "." << validatorMinor; } // dxil.dll 1.0 did not support IdxcVersionInfo else { OS << "; " - << "dxil.dll: " << 1 << "." << 0; + << kDxilLib << ": " << 1 << "." << 0; } unsigned int version[4]; - if (GetDLLFileVersionInfo("dxil.dll", version)) { + if (GetDLLFileVersionInfo(kDxilLib, version)) { OS << "(" << version[0] << "." << version[1] << "." << version[2] << "." << version[3] << ")"; } @@ -1272,7 +1272,7 @@ void DxcContext::GetCompilerVersionInfo(llvm::raw_string_ostream &OS) { // Print validator if exists DxcDllSupport DxilSupport; - DxilSupport.InitializeForDll(L"dxil.dll", "DxcCreateInstance"); + DxilSupport.InitializeForDll(kDxilLib, "DxcCreateInstance"); WriteDXILVersionInfo(OS, DxilSupport); } diff --git a/tools/clang/tools/dxcompiler/dxcpdbutils.cpp b/tools/clang/tools/dxcompiler/dxcpdbutils.cpp index 24cbaa25c2..892c9a97f7 100644 --- a/tools/clang/tools/dxcompiler/dxcpdbutils.cpp +++ b/tools/clang/tools/dxcompiler/dxcpdbutils.cpp @@ -716,6 +716,10 @@ struct DxcPdbUtils : public IDxcPdbUtils2, public IDxcPixDxilDebugInfoFactory HRESULT AddArgPair(StringRef name, StringRef value) { const llvm::opt::OptTable *optTable = hlsl::options::getHlslOptTable(); + // If the value for define is somehow empty, do not add it. + if (name == "D" && value.empty()) + return S_OK; + SmallVector fusedArgStorage; if (name.size() && value.size()) { // Handling case where old positional arguments used to have diff --git a/tools/clang/tools/dxcompiler/dxcutil.cpp b/tools/clang/tools/dxcompiler/dxcutil.cpp index 9732c10f65..863fe04c5f 100644 --- a/tools/clang/tools/dxcompiler/dxcutil.cpp +++ b/tools/clang/tools/dxcompiler/dxcutil.cpp @@ -176,7 +176,7 @@ HRESULT ValidateAndAssembleToContainer(AssembleInputs &inputs) { if (inputs.pDiag) { unsigned diagID = inputs.pDiag->getCustomDiagID(clang::DiagnosticsEngine::Level::Warning, - "DXIL.dll not found. Resulting DXIL will not be " + "DXIL signing library (dxil.dll,libdxil.so) not found. Resulting DXIL will not be " "signed for use in release environments.\r\n"); inputs.pDiag->Report(diagID); } diff --git a/tools/clang/tools/dxcompiler/dxillib.cpp b/tools/clang/tools/dxcompiler/dxillib.cpp index e1e7f9f4ad..30975c3288 100644 --- a/tools/clang/tools/dxcompiler/dxillib.cpp +++ b/tools/clang/tools/dxcompiler/dxillib.cpp @@ -25,11 +25,9 @@ static llvm::sys::Mutex *cs = nullptr; // This function is to prevent multiple attempts to load dxil.dll HRESULT DxilLibInitialize() { cs = new llvm::sys::Mutex; -#if LLVM_ON_WIN32 cs->lock(); - g_DllLibResult = g_DllSupport.InitializeForDll(L"dxil.dll", "DxcCreateInstance"); + g_DllLibResult = g_DllSupport.InitializeForDll(kDxilLib, "DxcCreateInstance"); cs->unlock(); -#endif return S_OK; } @@ -53,19 +51,14 @@ HRESULT DxilLibCleanup(DxilLibCleanUpType type) { // If we fail to load dxil.dll, set g_DllLibResult to E_FAIL so that we don't // have multiple attempts to load dxil.dll bool DxilLibIsEnabled() { -#if LLVM_ON_WIN32 cs->lock(); if (SUCCEEDED(g_DllLibResult)) { if (!g_DllSupport.IsEnabled()) { - g_DllLibResult = g_DllSupport.InitializeForDll(L"dxil.dll", "DxcCreateInstance"); + g_DllLibResult = g_DllSupport.InitializeForDll(kDxilLib, "DxcCreateInstance"); } } cs->unlock(); return SUCCEEDED(g_DllLibResult); -#else - g_DllLibResult = (HRESULT)-1; - return false; -#endif } diff --git a/tools/clang/tools/dxopt/dxopt.cpp b/tools/clang/tools/dxopt/dxopt.cpp index bea996e2a4..c622eec6a0 100644 --- a/tools/clang/tools/dxopt/dxopt.cpp +++ b/tools/clang/tools/dxopt/dxopt.cpp @@ -300,7 +300,8 @@ int __cdecl wmain(int argc, const wchar_t **argv_) { if (externalLib) { CW2A externalFnA(externalFn, CP_UTF8); - IFT(g_DxcSupport.InitializeForDll(externalLib, externalFnA)); + CW2A externalLibA(externalLib, CP_UTF8); + IFT(g_DxcSupport.InitializeForDll(externalLibA, externalFnA)); } else { IFT(g_DxcSupport.Initialize()); diff --git a/tools/clang/tools/dxrfallbackcompiler/dxcutil.cpp b/tools/clang/tools/dxrfallbackcompiler/dxcutil.cpp index 2d68a28243..1effdf8ac4 100644 --- a/tools/clang/tools/dxrfallbackcompiler/dxcutil.cpp +++ b/tools/clang/tools/dxrfallbackcompiler/dxcutil.cpp @@ -156,7 +156,7 @@ HRESULT ValidateAndAssembleToContainer(AssembleInputs &inputs) { if (inputs.pDiag) { unsigned diagID = inputs.pDiag->getCustomDiagID(clang::DiagnosticsEngine::Level::Warning, - "DXIL.dll not found. Resulting DXIL will not be " + "DXIL signing library (dxil.dll,libdxil.so) not found. Resulting DXIL will not be " "signed for use in release environments.\r\n"); inputs.pDiag->Report(diagID); } diff --git a/tools/clang/tools/dxrfallbackcompiler/dxillib.cpp b/tools/clang/tools/dxrfallbackcompiler/dxillib.cpp index 1bb1103355..cdfb08527f 100644 --- a/tools/clang/tools/dxrfallbackcompiler/dxillib.cpp +++ b/tools/clang/tools/dxrfallbackcompiler/dxillib.cpp @@ -48,7 +48,7 @@ bool DxilLibIsEnabled() { EnterCriticalSection(&cs); if (SUCCEEDED(g_DllLibResult)) { if (!g_DllSupport.IsEnabled()) { - g_DllLibResult = g_DllSupport.InitializeForDll(L"dxil.dll", "DxcCreateInstance"); + g_DllLibResult = g_DllSupport.InitializeForDll(kDxilLib, "DxcCreateInstance"); } } LeaveCriticalSection(&cs); @@ -65,4 +65,4 @@ HRESULT DxilLibCreateInstance(_In_ REFCLSID rclsid, _In_ REFIID riid, _In_ IUnkn LeaveCriticalSection(&cs); } return hr; -} \ No newline at end of file +} diff --git a/tools/clang/unittests/DxrFallback/test_DxrFallback.cpp b/tools/clang/unittests/DxrFallback/test_DxrFallback.cpp index 96bf9f91b6..af92b25b89 100644 --- a/tools/clang/unittests/DxrFallback/test_DxrFallback.cpp +++ b/tools/clang/unittests/DxrFallback/test_DxrFallback.cpp @@ -157,7 +157,7 @@ class Tester , m_path(path) { dxc::EnsureEnabled(m_dxcSupport); - m_dxrFallbackSupport.InitializeForDll(L"DxrFallbackCompiler.dll", "DxcCreateDxrFallbackCompiler"); + m_dxrFallbackSupport.InitializeForDll("DxrFallbackCompiler.dll", "DxcCreateDxrFallbackCompiler"); } void setFiles(const std::vector& files) diff --git a/tools/clang/unittests/HLSL/CompilerTest.cpp b/tools/clang/unittests/HLSL/CompilerTest.cpp index 18689386b8..65a75034b3 100644 --- a/tools/clang/unittests/HLSL/CompilerTest.cpp +++ b/tools/clang/unittests/HLSL/CompilerTest.cpp @@ -150,6 +150,7 @@ class CompilerTest : public ::testing::Test { TEST_METHOD(CompileThenSetRootSignatureThenValidate) TEST_METHOD(CompileSetPrivateThenWithStripPrivate) TEST_METHOD(CompileWithMultiplePrivateOptionsThenFail) + TEST_METHOD(TestPdbUtilsWithEmptyDefine) void CompileThenTestReflectionThreadSize(const char *source, const WCHAR *target, UINT expectedX, UINT expectedY, UINT expectedZ); @@ -2008,6 +2009,26 @@ TEST_F(CompilerTest, CompileThenTestPdbUtilsEmptyEntry) { VERIFY_ARE_EQUAL(pEntryName, L"main"); } +TEST_F(CompilerTest, TestPdbUtilsWithEmptyDefine) { +#include "TestHeaders/TestDxilWithEmptyDefine.h" + CComPtr pUtils; + VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcUtils, &pUtils)); + + CComPtr pBlob; + VERIFY_SUCCEEDED(pUtils->CreateBlobFromPinned(g_TestDxilWithEmptyDefine, sizeof(g_TestDxilWithEmptyDefine), CP_ACP, &pBlob)); + + CComPtr pPdbUtils; + VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcPdbUtils, &pPdbUtils)); + VERIFY_SUCCEEDED(pPdbUtils->Load(pBlob)); + + UINT32 uCount = 0; + VERIFY_SUCCEEDED(pPdbUtils->GetDefineCount(&uCount)); + for (UINT i = 0; i < uCount; i++) { + CComBSTR pDefine; + VERIFY_SUCCEEDED(pPdbUtils->GetDefine(i, &pDefine)); + } +} + #endif // _WIN32 - No PDBUtil support void CompilerTest::TestResourceBindingImpl( diff --git a/tools/clang/unittests/HLSL/PixTest.cpp b/tools/clang/unittests/HLSL/PixTest.cpp index 0b75bc8e9b..cd7dcbcaa6 100644 --- a/tools/clang/unittests/HLSL/PixTest.cpp +++ b/tools/clang/unittests/HLSL/PixTest.cpp @@ -227,8 +227,11 @@ class PixTest { TEST_METHOD(PixTypeManager_InheritancePointerTypedef) TEST_METHOD(PixTypeManager_MatricesInBase) TEST_METHOD(PixTypeManager_SamplersAndResources) + TEST_METHOD(PixTypeManager_XBoxDiaAssert) - TEST_METHOD(VirtualRegisters_InstructionCounts) + TEST_METHOD(DxcPixDxilDebugInfo_InstructionOffsets) + + TEST_METHOD(VirtualRegisters_InstructionCounts) TEST_METHOD(VirtualRegisters_AlignedOffsets) TEST_METHOD(RootSignatureUpgrade_SubObjects) @@ -1802,6 +1805,8 @@ TEST_F(PixTest, PixDebugCompileInfo) { VERIFY_ARE_EQUAL(std::wstring(profile), std::wstring(hlslTarget)); } +static LPCWSTR defaultFilename = L"source.hlsl"; + static void CompileAndLogErrors(dxc::DxcDllSupport &dllSupport, LPCSTR pText, LPWSTR pTargetProfile, std::vector &args, _Outptr_ IDxcBlob **ppResult) { @@ -1812,7 +1817,7 @@ static void CompileAndLogErrors(dxc::DxcDllSupport &dllSupport, LPCSTR pText, *ppResult = nullptr; VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler)); Utf8ToBlob(dllSupport, pText, &pSource); - VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"source.hlsl", L"main", + VERIFY_SUCCEEDED(pCompiler->Compile(pSource, defaultFilename, L"main", pTargetProfile, args.data(), args.size(), nullptr, 0, nullptr, &pResult)); @@ -2088,6 +2093,232 @@ void main() VERIFY_SUCCEEDED(pDiaDataSource->openSession(&pDiaSession)); } +TEST_F(PixTest, PixTypeManager_XBoxDiaAssert) { + if (m_ver.SkipDxilVersion(1, 5)) + return; + + const char *hlsl = R"( +struct VSOut +{ + float4 vPosition : SV_POSITION; + float4 vLightAndFog : COLOR0_center; + float4 vTexCoords : TEXCOORD1; +}; + +struct HSPatchData +{ + float edges[3] : SV_TessFactor; + float inside : SV_InsideTessFactor; +}; + +HSPatchData HSPatchFunc(const InputPatch tri) +{ + + float dist = (tri[0].vPosition.w + tri[1].vPosition.w + tri[2].vPosition.w) / 3; + + + float tf = max(1, dist / 100.f); + + HSPatchData pd; + pd.edges[0] = pd.edges[1] = pd.edges[2] = tf; + pd.inside = tf; + + return pd; +} + +[domain("tri")] +[partitioning("fractional_odd")] +[outputtopology("triangle_cw")] +[patchconstantfunc("HSPatchFunc")] +[outputcontrolpoints(3)] +[RootSignature("RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), " "DescriptorTable(SRV(t0, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL)," "DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_PIXEL)," "DescriptorTable(CBV(b0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)," "DescriptorTable(CBV(b1, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)," "DescriptorTable(CBV(b2, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)," "DescriptorTable(SRV(t3, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)," "DescriptorTable(UAV(u9, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL),")] +VSOut main( const uint id : SV_OutputControlPointID, + const InputPatch< VSOut, 3 > triIn ) +{ + return triIn[id]; +} +)"; + + CComPtr pDiaDataSource; + CComPtr pDiaSession; + CompileAndRunAnnotationAndLoadDiaSource(m_dllSupport, hlsl, L"hs_6_0", + &pDiaDataSource); + + VERIFY_SUCCEEDED(pDiaDataSource->openSession(&pDiaSession)); +} + +std::vector SplitAndPreserveEmptyLines(std::string const & str, char delimeter) { + std::vector lines; + + auto const *p = str.data(); + auto const *justPastPreviousDelimiter = p; + while (p < str.data() + str.length()) { + if (*p == delimeter) { + lines.emplace_back(justPastPreviousDelimiter, p - justPastPreviousDelimiter); + justPastPreviousDelimiter = p + 1; + p = justPastPreviousDelimiter; + } else { + p++; + } + } + + lines.emplace_back(std::string(justPastPreviousDelimiter, + p - justPastPreviousDelimiter)); + + return lines; +} + +TEST_F(PixTest, DxcPixDxilDebugInfo_InstructionOffsets) { + + if (m_ver.SkipDxilVersion(1, 5)) + return; + + const char *hlsl = R"(RaytracingAccelerationStructure Scene : register(t0, space0); +RWTexture2D RenderTarget : register(u0); + +struct SceneConstantBuffer +{ + float4x4 projectionToWorld; + float4 cameraPosition; + float4 lightPosition; + float4 lightAmbientColor; + float4 lightDiffuseColor; +}; + +ConstantBuffer g_sceneCB : register(b0); + +struct RayPayload +{ + float4 color; +}; + +inline void GenerateCameraRay(uint2 index, out float3 origin, out float3 direction) +{ + float2 xy = index + 0.5f; // center in the middle of the pixel. + float2 screenPos = xy;// / DispatchRaysDimensions().xy * 2.0 - 1.0; + + // Invert Y for DirectX-style coordinates. + screenPos.y = -screenPos.y; + + // Unproject the pixel coordinate into a ray. + float4 world = /*mul(*/float4(screenPos, 0, 1)/*, g_sceneCB.projectionToWorld)*/; + + //world.xyz /= world.w; + origin = world.xyz; //g_sceneCB.cameraPosition.xyz; + direction = float3(1,0,0);//normalize(world.xyz - origin); +} + +void RaygenCommon() +{ + float3 rayDir; + float3 origin; + + // Generate a ray for a camera pixel corresponding to an index from the dispatched 2D grid. + GenerateCameraRay(DispatchRaysIndex().xy, origin, rayDir); + + // Trace the ray. + // Set the ray's extents. + RayDesc ray; + ray.Origin = origin; + ray.Direction = rayDir; + // Set TMin to a non-zero small value to avoid aliasing issues due to floating - point errors. + // TMin should be kept small to prevent missing geometry at close contact areas. + ray.TMin = 0.001; + ray.TMax = 10000.0; + RayPayload payload = { float4(0, 0, 0, 0) }; + TraceRay(Scene, RAY_FLAG_CULL_BACK_FACING_TRIANGLES, ~0, 0, 1, 0, ray, payload); + + // Write the raytraced color to the output texture. + // RenderTarget[DispatchRaysIndex().xy] = payload.color; +} + +[shader("raygeneration")] +void Raygen() +{ + RaygenCommon(); +} + +typedef BuiltInTriangleIntersectionAttributes MyAttributes; + +[shader("closesthit")] +void InnerClosestHitShader(inout RayPayload payload, in MyAttributes attr) +{ + payload.color = float4(0,1,0,0); +} + + +[shader("miss")] +void MyMissShader(inout RayPayload payload) +{ + payload.color = float4(1, 0, 0, 0); +})"; + + auto lines = SplitAndPreserveEmptyLines(std::string(hlsl), '\n'); + DWORD countOfSourceLines = static_cast(lines.size()); + + CComPtr pDiaDataSource; + CompileAndRunAnnotationAndLoadDiaSource(m_dllSupport, hlsl, L"lib_6_6", + &pDiaDataSource); + + CComPtr session; + VERIFY_SUCCEEDED(pDiaDataSource->openSession(&session)); + + CComPtr Factory; + VERIFY_SUCCEEDED(session->QueryInterface(IID_PPV_ARGS(&Factory))); + + CComPtr dxilDebugger; + VERIFY_SUCCEEDED(Factory->NewDxcPixDxilDebugInfo(&dxilDebugger)); + + // Quick crash test for wrong filename: + CComPtr garbageOffsets; + dxilDebugger->InstructionOffsetsFromSourceLocation(L"garbage", 0, 0, + &garbageOffsets); + + // Since the API offers both source-from-instruction and + // instruction-from-source, we'll compare them against each other: + for (size_t line = 0; line < lines.size(); ++line) { + + auto lineNumber = static_cast(line); + + constexpr DWORD sourceLocationReaderOnlySupportsColumnZero = 0; + CComPtr offsets; + dxilDebugger->InstructionOffsetsFromSourceLocation( + defaultFilename, lineNumber, sourceLocationReaderOnlySupportsColumnZero, + &offsets); + + auto offsetCount = offsets->GetCount(); + for (DWORD offsetOrdinal = 0; offsetOrdinal < offsetCount; + ++offsetOrdinal) { + + DWORD instructionOffsetFromSource = + offsets->GetOffsetByIndex(offsetOrdinal); + + CComPtr sourceLocations; + VERIFY_SUCCEEDED(dxilDebugger->SourceLocationsFromInstructionOffset( + instructionOffsetFromSource, &sourceLocations)); + + auto count = sourceLocations->GetCount(); + for (DWORD sourceLocationOrdinal = 0; sourceLocationOrdinal < count; + ++sourceLocationOrdinal) { + DWORD lineNumber = + sourceLocations->GetLineNumberByIndex(sourceLocationOrdinal); + DWORD column = sourceLocations->GetColumnByIndex(sourceLocationOrdinal); + CComBSTR filename; + VERIFY_SUCCEEDED(sourceLocations->GetFileNameByIndex( + sourceLocationOrdinal, &filename)); + + VERIFY_IS_TRUE(lineNumber < countOfSourceLines); + + constexpr DWORD lineNumbersAndColumnsStartAtOne = 1; + VERIFY_IS_TRUE( + column - lineNumbersAndColumnsStartAtOne <= + static_cast(lines.at(lineNumber - lineNumbersAndColumnsStartAtOne).size())); + VERIFY_IS_TRUE(0 == wcscmp(filename, defaultFilename)); + } + } + } +} + CComPtr PixTest::RunShaderAccessTrackingPass(IDxcBlob *blob) { CComPtr pOptimizer; VERIFY_SUCCEEDED( diff --git a/tools/clang/unittests/HLSL/ShaderOpTest.cpp b/tools/clang/unittests/HLSL/ShaderOpTest.cpp index 7d19149245..ead34ab3ea 100644 --- a/tools/clang/unittests/HLSL/ShaderOpTest.cpp +++ b/tools/clang/unittests/HLSL/ShaderOpTest.cpp @@ -38,6 +38,14 @@ #include #pragma comment(lib, "xmllite.lib") + +// Duplicate definition of kDxCompilerLib to that in dxcapi.use.cpp +// These tests need the header, but don't want to depend on the source +// Since this is windows only, we only need the windows variant +namespace dxc { +const char* kDxCompilerLib = "dxcompiler.dll"; +} + /////////////////////////////////////////////////////////////////////////////// // Useful helper functions. diff --git a/tools/clang/unittests/HLSL/TestHeaders/TestDxilWithEmptyDefine.h b/tools/clang/unittests/HLSL/TestHeaders/TestDxilWithEmptyDefine.h new file mode 100644 index 0000000000..b58f283817 --- /dev/null +++ b/tools/clang/unittests/HLSL/TestHeaders/TestDxilWithEmptyDefine.h @@ -0,0 +1,354 @@ +#if 0 +; +; Input signature: +; +; Name Index Mask Register SysValue Format Used +; -------------------- ----- ------ -------- -------- ------- ------ +; no parameters +; +; Output signature: +; +; Name Index Mask Register SysValue Format Used +; -------------------- ----- ------ -------- -------- ------- ------ +; SV_Target 0 x 0 TARGET float x +; +; shader debug name: 21c11f2029d870c04dedb3fe6b46bf27.pdb +; shader hash: 21c11f2029d870c04dedb3fe6b46bf27 +; +; Pipeline Runtime Information: +; +; Pixel Shader +; DepthOutput=0 +; SampleFrequency=0 +; +; +; 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: 0, outputs: 1 +; Outputs dependent on ViewId: { } +; Inputs contributing to computation of Outputs: +; +target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64" +target triple = "dxil-ms-dx" + +define void @main() { +entry: + call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float 0.000000e+00), !dbg !28 ; line:1 col:28 ; StoreOutput(outputSigId,rowIndex,colIndex,value) + ret void, !dbg !28 ; line:1 col:28 +} + +; Function Attrs: nounwind +declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #0 + +attributes #0 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!8, !9} +!llvm.ident = !{!10} +!dx.source.contents = !{!11} +!dx.source.defines = !{!12} +!dx.source.mainFileName = !{!13} +!dx.source.args = !{!14} +!dx.version = !{!15} +!dx.valver = !{!16} +!dx.shaderModel = !{!17} +!dx.typeAnnotations = !{!18} +!dx.viewIdState = !{!21} +!dx.entryPoints = !{!22} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "dxc(private) 1.7.0.13784 (main, e93cb6343)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3) +!1 = !DIFile(filename: "F:\5Ctest\5Cbad.hlsl", directory: "") +!2 = !{} +!3 = !{!4} +!4 = !DISubprogram(name: "main", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, function: void ()* @main) +!5 = !DISubroutineType(types: !6) +!6 = !{!7} +!7 = !DIBasicType(name: "float", size: 32, align: 32, encoding: DW_ATE_float) +!8 = !{i32 2, !"Dwarf Version", i32 4} +!9 = !{i32 2, !"Debug Info Version", i32 3} +!10 = !{!"dxc(private) 1.7.0.13784 (main, e93cb6343)"} +!11 = !{!"F:\5Ctest\5Cbad.hlsl", !"float main() : SV_Target { return 0; }\0D\0A"} +!12 = !{!"OTHER_DEFINE=1", !"OTHER_DEFINE=1"} +!13 = !{!"F:\5Ctest\5Cbad.hlsl"} +!14 = !{!"-E", !"main", !"-T", !"ps_6_0", !"/Zi", !"/Qstrip_reflect", !"/Qembed_debug", !"/D", !"", !"/D", !"OTHER_DEFINE=1", !"-D", !"OTHER_DEFINE=1"} +!15 = !{i32 1, i32 0} +!16 = !{i32 1, i32 5} +!17 = !{!"ps", i32 6, i32 0} +!18 = !{i32 1, void ()* @main, !19} +!19 = !{!20} +!20 = !{i32 0, !2, !2} +!21 = !{[2 x i32] [i32 0, i32 1]} +!22 = !{void ()* @main, !"main", !23, null, null} +!23 = !{null, !24, null} +!24 = !{!25} +!25 = !{i32 0, !"SV_Target", i8 9, i8 16, !26, i8 0, i32 1, i8 1, i32 0, i8 0, !27} +!26 = !{i32 0} +!27 = !{i32 3, i32 1} +!28 = !DILocation(line: 1, column: 28, scope: !4) + +#endif + +const unsigned char g_TestDxilWithEmptyDefine[] = { + 0x44, 0x58, 0x42, 0x43, 0x3a, 0x12, 0x2e, 0xe6, 0x05, 0x8d, 0xbf, 0xab, + 0xa6, 0xa9, 0x93, 0x31, 0x0d, 0xf0, 0x60, 0x11, 0x01, 0x00, 0x00, 0x00, + 0x8e, 0x0b, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, + 0xf2, 0x00, 0x00, 0x00, 0x02, 0x07, 0x00, 0x00, 0x36, 0x07, 0x00, 0x00, + 0x52, 0x07, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x4f, 0x53, 0x47, 0x31, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0x50, 0x53, + 0x56, 0x30, 0x50, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x41, 0x10, 0x03, 0x00, + 0x00, 0x00, 0x49, 0x4c, 0x44, 0x42, 0x08, 0x06, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x00, 0x82, 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xf0, 0x05, 0x00, 0x00, 0x42, 0x43, + 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x79, 0x01, 0x00, 0x00, 0x0b, 0x82, + 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, + 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, + 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x10, + 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0x84, 0x10, 0x32, 0x14, 0x38, 0x08, + 0x18, 0x4b, 0x0a, 0x32, 0x42, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, + 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x11, 0x22, + 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x21, + 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1b, 0x88, + 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0x00, 0x00, 0x49, 0x18, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x82, 0x00, 0x00, 0x89, 0x20, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, + 0x85, 0x04, 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, + 0x90, 0x14, 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x28, + 0x23, 0x00, 0x25, 0x00, 0x8a, 0x39, 0x02, 0x30, 0x98, 0x23, 0x40, 0x66, + 0x00, 0x8a, 0x01, 0x33, 0x43, 0x45, 0x36, 0x10, 0x90, 0x02, 0x03, 0x00, + 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, + 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, + 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, + 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, + 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x06, + 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x81, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, + 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x9a, 0x22, 0x28, + 0x84, 0x32, 0x28, 0x81, 0x11, 0x80, 0x52, 0x28, 0x06, 0xa2, 0x92, 0x28, + 0x90, 0x11, 0x80, 0x12, 0xa0, 0x1c, 0x4b, 0x00, 0x02, 0x00, 0x79, 0x18, + 0x00, 0x00, 0xad, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, + 0x13, 0x44, 0xc8, 0x48, 0x87, 0x8b, 0xae, 0x6c, 0x8e, 0x8e, 0x4b, 0x2c, + 0x8c, 0xcc, 0x05, 0x8d, 0x6d, 0x8e, 0x6d, 0xd0, 0x00, 0x04, 0x00, 0xd5, + 0x80, 0x0c, 0x6f, 0x0c, 0x05, 0x4e, 0x2e, 0xcd, 0x2e, 0x8c, 0xae, 0x2c, + 0x05, 0x24, 0xc6, 0xe5, 0xc6, 0x05, 0xc6, 0x25, 0x66, 0xe6, 0x06, 0x87, + 0x06, 0x04, 0xa5, 0x2d, 0x2c, 0xcd, 0x8d, 0x05, 0xa4, 0x2c, 0x67, 0x66, + 0x4c, 0xcc, 0x66, 0x86, 0x66, 0x26, 0x65, 0x03, 0x40, 0xa2, 0x2d, 0x2c, + 0xcd, 0x8d, 0x85, 0x19, 0xdb, 0x5b, 0x18, 0xdd, 0x1e, 0x03, 0x20, 0x03, + 0x03, 0x0c, 0xc0, 0x80, 0xd8, 0x10, 0x1c, 0x9b, 0x06, 0x00, 0x40, 0x26, + 0x08, 0x02, 0xb0, 0x6a, 0x02, 0x84, 0x02, 0x10, 0x82, 0x04, 0x08, 0x02, + 0x00, 0x00, 0x40, 0x04, 0x50, 0x00, 0x00, 0xd8, 0x10, 0x2c, 0xa3, 0x9e, + 0x80, 0x10, 0x06, 0x00, 0x00, 0x80, 0x80, 0x00, 0x18, 0x00, 0x00, 0x26, + 0x08, 0x83, 0xc0, 0x86, 0xe8, 0x2e, 0x4c, 0xce, 0x0c, 0xc4, 0xaa, 0x4c, + 0x6e, 0x2e, 0xed, 0xcd, 0x6d, 0x82, 0x30, 0x0c, 0x1b, 0x06, 0xe7, 0x81, + 0x28, 0x11, 0x95, 0x89, 0xd5, 0x9d, 0x81, 0x24, 0xb9, 0x99, 0xbd, 0x81, + 0x58, 0x95, 0xc9, 0xcd, 0xa5, 0xbd, 0xb9, 0x4d, 0x10, 0x06, 0x62, 0xc3, + 0xe0, 0x48, 0xd3, 0x86, 0x60, 0x20, 0x1a, 0x98, 0xb1, 0xbd, 0x85, 0xd1, + 0x81, 0xb4, 0x85, 0xa5, 0xb9, 0xa1, 0xa4, 0x80, 0xe8, 0x80, 0x4c, 0x59, + 0x7d, 0x51, 0x85, 0xc9, 0x9d, 0x95, 0xd1, 0x81, 0xec, 0x81, 0xc8, 0x95, + 0xd1, 0xd5, 0xc9, 0xb9, 0x81, 0xc0, 0xec, 0x80, 0xf4, 0x35, 0x28, 0x6c, + 0x10, 0x02, 0x8b, 0xce, 0x13, 0x15, 0x52, 0x91, 0xd4, 0x17, 0x51, 0x91, + 0x51, 0x92, 0x53, 0x51, 0x4f, 0xcc, 0x06, 0x01, 0xc3, 0x36, 0x04, 0x01, + 0x85, 0x96, 0x22, 0x0a, 0x2d, 0x54, 0x34, 0xe0, 0xe6, 0xbe, 0x6c, 0xbe, + 0x60, 0x38, 0xbc, 0x68, 0xa5, 0xf1, 0x79, 0x89, 0x9a, 0xa3, 0x93, 0x4b, + 0x83, 0xfb, 0x92, 0x2b, 0x33, 0x63, 0x2b, 0x1b, 0xa3, 0x63, 0xf3, 0x12, + 0x55, 0xd6, 0x26, 0x56, 0x46, 0xf6, 0x45, 0x56, 0x26, 0x56, 0x77, 0x46, + 0xe1, 0x85, 0x88, 0x00, 0x85, 0x16, 0xa2, 0x0d, 0xcd, 0x56, 0x70, 0x9d, + 0xf7, 0x81, 0x41, 0x18, 0x88, 0x41, 0x18, 0x60, 0x63, 0x80, 0x4d, 0x10, + 0x86, 0x62, 0x82, 0x30, 0x18, 0x1b, 0x84, 0x32, 0x30, 0x83, 0x09, 0xc2, + 0x70, 0x6c, 0x10, 0xca, 0x00, 0x0d, 0x28, 0xc0, 0xcd, 0x4d, 0x10, 0x06, + 0x64, 0xc3, 0xa0, 0x06, 0x6b, 0x60, 0x06, 0x1b, 0x06, 0x33, 0x20, 0x88, + 0x0d, 0x41, 0x1b, 0x6c, 0x18, 0xca, 0x40, 0x71, 0x83, 0x09, 0x42, 0xd2, + 0x6c, 0x08, 0xe0, 0x80, 0xc9, 0x94, 0xd5, 0x17, 0x55, 0x98, 0xdc, 0x59, + 0x19, 0xdd, 0x04, 0x81, 0x48, 0x26, 0x08, 0x84, 0xb2, 0x21, 0x30, 0x83, + 0x09, 0x02, 0xb1, 0x4c, 0x10, 0x08, 0x66, 0x83, 0x30, 0x95, 0xc1, 0x86, + 0xc5, 0x0c, 0xe4, 0x60, 0x0e, 0xe8, 0xa0, 0x0e, 0xec, 0xa0, 0x0c, 0xee, + 0xc0, 0x0c, 0xec, 0x00, 0x0f, 0x36, 0x04, 0x79, 0xb0, 0x61, 0x00, 0xf4, + 0x00, 0xd8, 0x50, 0x28, 0xc5, 0x1e, 0x00, 0x40, 0x17, 0x36, 0x36, 0xbb, + 0x36, 0x17, 0x32, 0xb1, 0x33, 0x97, 0xb1, 0xba, 0x29, 0x01, 0xd3, 0x88, + 0x8d, 0xcd, 0xae, 0xcd, 0xa5, 0xed, 0x8d, 0xac, 0x8e, 0xad, 0xcc, 0xc5, + 0x8c, 0x2d, 0xec, 0x6c, 0x6e, 0x8a, 0x00, 0x4d, 0x55, 0xd8, 0xd8, 0xec, + 0xda, 0x5c, 0xd2, 0xc8, 0xca, 0xdc, 0xe8, 0xa6, 0x04, 0x54, 0x25, 0x32, + 0x3c, 0x97, 0xb9, 0xb7, 0x3a, 0xb9, 0xb1, 0x32, 0x97, 0xb1, 0x37, 0x37, + 0xba, 0x32, 0x37, 0xba, 0xb9, 0x29, 0x81, 0xd5, 0x88, 0x0c, 0xcf, 0x65, + 0xee, 0xad, 0x4e, 0x6e, 0xac, 0xcc, 0x85, 0xac, 0xcc, 0x2c, 0xcd, 0xad, + 0x6c, 0x6e, 0x4a, 0x80, 0xd5, 0x22, 0xc3, 0x73, 0x99, 0x7b, 0xab, 0x93, + 0x1b, 0x2b, 0x73, 0x69, 0x0b, 0x4b, 0x73, 0x33, 0x4a, 0x63, 0x2b, 0x73, + 0x0a, 0x6b, 0x2b, 0x9b, 0x12, 0x64, 0x75, 0xc8, 0xf0, 0x5c, 0xe6, 0xde, + 0xea, 0xe4, 0xc6, 0xca, 0x5c, 0xc2, 0xe4, 0xce, 0xe6, 0xa6, 0x04, 0x63, + 0x50, 0x85, 0x0c, 0xcf, 0xc5, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x6d, + 0x4a, 0x60, 0x06, 0x4d, 0xc8, 0xf0, 0x5c, 0xec, 0xc2, 0xd8, 0xec, 0xca, + 0xe4, 0xa6, 0x04, 0x68, 0x50, 0x87, 0x0c, 0xcf, 0x65, 0x0e, 0x2d, 0x8c, + 0xac, 0x4c, 0xae, 0xe9, 0x8d, 0xac, 0x8c, 0x6d, 0x4a, 0xb0, 0x06, 0x95, + 0xc8, 0xf0, 0x5c, 0xe8, 0xf2, 0xe0, 0xca, 0x82, 0xdc, 0xdc, 0xde, 0xe8, + 0xc2, 0xe8, 0xd2, 0xde, 0xdc, 0xe6, 0xa6, 0x04, 0x6e, 0x50, 0x87, 0x0c, + 0xcf, 0xc5, 0x2e, 0xad, 0xec, 0x2e, 0x89, 0x6c, 0x8a, 0x2e, 0x8c, 0xae, + 0x6c, 0x4a, 0x00, 0x07, 0x75, 0xc8, 0xf0, 0x5c, 0xca, 0xdc, 0xe8, 0xe4, + 0xf2, 0xa0, 0xde, 0xd2, 0xdc, 0xe8, 0xe6, 0xa6, 0x04, 0x7b, 0x00, 0x00, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, + 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, + 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, + 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, + 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, + 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, + 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, + 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, + 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, + 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, + 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, + 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, + 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, + 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, + 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, + 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, + 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, + 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, + 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, + 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, + 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, + 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x00, + 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16, 0x50, + 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x34, 0x39, 0x11, 0x81, 0x52, 0xd3, 0x43, + 0x4d, 0x7e, 0x71, 0xdb, 0x06, 0x40, 0x30, 0x00, 0xd2, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x54, 0x23, 0x00, 0x00, 0x23, 0x06, + 0x09, 0x00, 0x82, 0x60, 0x60, 0x38, 0x48, 0x92, 0x10, 0xc1, 0x8c, 0x01, + 0x11, 0x70, 0x0b, 0x80, 0x13, 0x06, 0x40, 0x38, 0x10, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x07, 0x50, 0x10, 0xcd, 0x14, 0x61, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x4c, 0x44, 0x4e, 0x2c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x32, 0x31, 0x63, 0x31, 0x31, 0x66, + 0x32, 0x30, 0x32, 0x39, 0x64, 0x38, 0x37, 0x30, 0x63, 0x30, 0x34, 0x64, + 0x65, 0x64, 0x62, 0x33, 0x66, 0x65, 0x36, 0x62, 0x34, 0x36, 0x62, 0x66, + 0x32, 0x37, 0x2e, 0x70, 0x64, 0x62, 0x00, 0x00, 0x00, 0x00, 0x48, 0x41, + 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xc1, + 0x1f, 0x20, 0x29, 0xd8, 0x70, 0xc0, 0x4d, 0xed, 0xb3, 0xfe, 0x6b, 0x46, + 0xbf, 0x27, 0x44, 0x58, 0x49, 0x4c, 0x34, 0x04, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x00, 0x0d, 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1c, 0x04, 0x00, 0x00, 0x42, 0x43, + 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x0b, 0x82, + 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, + 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, + 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x10, + 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0x84, 0x10, 0x32, 0x14, 0x38, 0x08, + 0x18, 0x4b, 0x0a, 0x32, 0x42, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, + 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x11, 0x22, + 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x21, + 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1b, 0x88, + 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0x00, 0x00, 0x49, 0x18, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x82, 0x00, 0x00, 0x89, 0x20, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, + 0x85, 0x04, 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, + 0x90, 0x14, 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x28, + 0x23, 0x00, 0x25, 0x00, 0x8a, 0x39, 0x02, 0x30, 0x98, 0x23, 0x40, 0x66, + 0x00, 0x8a, 0x01, 0x33, 0x43, 0x45, 0x36, 0x10, 0x90, 0x02, 0x03, 0x00, + 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, + 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, + 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, + 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, + 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x06, + 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x81, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, + 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x9a, 0x12, 0x18, + 0x01, 0x28, 0x85, 0x62, 0x28, 0x03, 0xa2, 0x92, 0x28, 0x90, 0x11, 0x80, + 0x12, 0xa0, 0x1c, 0x4b, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, + 0x13, 0x44, 0x35, 0x20, 0xc3, 0x1b, 0x43, 0x81, 0x93, 0x4b, 0xb3, 0x0b, + 0xa3, 0x2b, 0x4b, 0x01, 0x89, 0x71, 0xb9, 0x71, 0x81, 0x71, 0x89, 0x99, + 0xb9, 0xc1, 0xa1, 0x01, 0x41, 0x69, 0x0b, 0x4b, 0x73, 0x63, 0x01, 0x29, + 0xcb, 0x99, 0x19, 0x13, 0xb3, 0x99, 0xa1, 0x99, 0x49, 0xd9, 0x10, 0x04, + 0x13, 0x84, 0x41, 0x98, 0x20, 0x0c, 0xc3, 0x06, 0x61, 0x20, 0x26, 0x08, + 0x03, 0xb1, 0x41, 0x18, 0x0c, 0x0a, 0x70, 0x73, 0x13, 0x84, 0xa1, 0xd8, + 0x30, 0x20, 0x09, 0x31, 0x41, 0x48, 0x96, 0x0d, 0xc1, 0x32, 0x41, 0x10, + 0x00, 0x12, 0x6d, 0x61, 0x69, 0x6e, 0x4c, 0xa6, 0xac, 0xbe, 0xa8, 0xc2, + 0xe4, 0xce, 0xca, 0xe8, 0x26, 0x08, 0xc4, 0x31, 0x41, 0x20, 0x90, 0x0d, + 0x01, 0x31, 0x41, 0x20, 0x92, 0x09, 0x02, 0xa1, 0x4c, 0x10, 0x06, 0x63, + 0x83, 0x50, 0x0d, 0x1b, 0x16, 0xe2, 0x81, 0x22, 0x69, 0x1a, 0x28, 0x62, + 0xb2, 0x36, 0x04, 0xd7, 0x86, 0x01, 0xc0, 0x80, 0x0d, 0x45, 0xe3, 0x64, + 0x00, 0x50, 0x85, 0x8d, 0xcd, 0xae, 0xcd, 0x25, 0x8d, 0xac, 0xcc, 0x8d, + 0x6e, 0x4a, 0x10, 0x54, 0x21, 0xc3, 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, + 0x7b, 0x73, 0x9b, 0x12, 0x10, 0x4d, 0xc8, 0xf0, 0x5c, 0xec, 0xc2, 0xd8, + 0xec, 0xca, 0xe4, 0xa6, 0x04, 0x46, 0x1d, 0x32, 0x3c, 0x97, 0x39, 0xb4, + 0x30, 0xb2, 0x32, 0xb9, 0xa6, 0x37, 0xb2, 0x32, 0xb6, 0x29, 0x41, 0x52, + 0x87, 0x0c, 0xcf, 0xc5, 0x2e, 0xad, 0xec, 0x2e, 0x89, 0x6c, 0x8a, 0x2e, + 0x8c, 0xae, 0x6c, 0x4a, 0xb0, 0xd4, 0x21, 0xc3, 0x73, 0x29, 0x73, 0xa3, + 0x93, 0xcb, 0x83, 0x7a, 0x4b, 0x73, 0xa3, 0x9b, 0x9b, 0x12, 0x64, 0x00, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, + 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, + 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, + 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, + 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, + 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, + 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, + 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, + 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, + 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, + 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, + 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, + 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, + 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, + 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, + 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, + 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, + 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, + 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, + 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, + 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, + 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x00, + 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16, 0x50, + 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x34, 0x39, 0x11, 0x81, 0x52, 0xd3, 0x43, + 0x4d, 0x7e, 0x71, 0xdb, 0x06, 0x40, 0x30, 0x00, 0xd2, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x54, 0x23, 0x00, 0x00, 0x23, 0x06, + 0x09, 0x00, 0x82, 0x60, 0x60, 0x30, 0x89, 0xa2, 0x10, 0x01, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +};