diff --git a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp --- a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp +++ b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp @@ -49,6 +49,49 @@ DXILValidatorVersionMD->addOperand(MDNode::get(Ctx, MDVals)); } +static void emitDXILVersion(Module &M) { + Triple T = Triple(M.getTargetTriple()); + VersionTuple SMVer = T.getOSVersion(); + + auto &Ctx = M.getContext(); + + constexpr StringLiteral DXILVerKey = "dx.version"; + NamedMDNode *VersionMD = M.getOrInsertNamedMetadata(DXILVerKey); + + Metadata *MDVals[DXILVersionNumFields]; + // DXIL Verison is ShaderModel Version with offset 5. + // ShaderModel 6.1 will get DXIL Version 1.1. + MDVals[0] = Uint32ToConstMD(SMVer.getMajor() - 5, Ctx); + MDVals[1] = Uint32ToConstMD(SMVer.getMinor().value_or(0), Ctx); + + VersionMD->addOperand(MDNode::get(Ctx, MDVals)); +} + +static void emitShaderModel(Module &M) { + constexpr StringLiteral DXILEntryPointsMDName = "dx.shaderModel"; + NamedMDNode *pShaderModelNamedMD = + M.getOrInsertNamedMetadata(DXILEntryPointsMDName); + auto &Ctx = M.getContext(); + + // Shader model. + constexpr unsigned DXILShaderModelNumFields = 3; + // Shader type (vs,ps,cs,gs,ds,hs). + constexpr unsigned DXILShaderModelTypeIdx = 0; + constexpr unsigned DXILShaderModelMajorIdx = 1; // Shader model major. + constexpr unsigned DXILShaderModelMinorIdx = 2; // Shader model minor. + Metadata *MDVals[DXILShaderModelNumFields]; + + Triple T(M.getTargetTriple()); + + MDVals[DXILShaderModelTypeIdx] = MDString::get(Ctx, T.getEnvironmentName()); + VersionTuple Ver = T.getOSVersion(); + MDVals[DXILShaderModelMajorIdx] = Uint32ToConstMD(Ver.getMajor(), Ctx); + MDVals[DXILShaderModelMinorIdx] = + Uint32ToConstMD(Ver.getMinor().value_or(0), Ctx); + + pShaderModelNamedMD->addOperand(MDNode::get(Ctx, MDVals)); +} + static VersionTuple loadDXILValidatorVersion(MDNode *ValVerMD) { if (ValVerMD->getNumOperands() != DXILVersionNumFields) return VersionTuple(); @@ -107,6 +150,8 @@ ValidatorVer = ValVer; } emitDXILValidatorVersion(M, ValidatorVer); + emitDXILVersion(M); + emitShaderModel(M); cleanModule(M); return false; } diff --git a/llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp b/llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp --- a/llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp +++ b/llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp @@ -377,13 +377,11 @@ void dxil::WriteDXILToFile(const Module &M, raw_ostream &Out) { SmallVector Buffer; Buffer.reserve(256 * 1024); - // If this is darwin or another generic macho target, reserve space for the // header. Triple TT(M.getTargetTriple()); if (TT.isOSDarwin() || TT.isOSBinFormatMachO()) Buffer.insert(Buffer.begin(), BWH_HeaderSize, 0); - BitcodeWriter Writer(Buffer, dyn_cast(&Out)); Writer.writeModule(M); Writer.writeSymtab(); diff --git a/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp b/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp --- a/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp +++ b/llvm/lib/Target/DirectX/DXILWriter/DXILWriterPass.cpp @@ -64,8 +64,17 @@ bool runOnModule(Module &M) override { std::string Data; llvm::raw_string_ostream OS(Data); + + const std::string OriginalTriple = M.getTargetTriple(); + // Set to DXIL triple when write to bitcode. + // Only the output bitcode need to be DXIL triple. + M.setTargetTriple("dxil-ms-dx"); + WriteDXILToFile(M, OS); + // Recover triple. + M.setTargetTriple(OriginalTriple); + Constant *ModuleConstant = ConstantDataArray::get(M.getContext(), arrayRefFromStringRef(Data)); auto *GV = new llvm::GlobalVariable(M, ModuleConstant->getType(), true, diff --git a/llvm/test/CodeGen/DirectX/dxil_ver.ll b/llvm/test/CodeGen/DirectX/dxil_metadata_emit.ll rename from llvm/test/CodeGen/DirectX/dxil_ver.ll rename to llvm/test/CodeGen/DirectX/dxil_metadata_emit.ll --- a/llvm/test/CodeGen/DirectX/dxil_ver.ll +++ b/llvm/test/CodeGen/DirectX/dxil_metadata_emit.ll @@ -2,12 +2,20 @@ target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" target triple = "dxil-pc-shadermodel6.3-library" -; Make sure dx.valver metadata is generated. +; Make sure dx.valver/version/shaderModle metadata is generated. ; CHECK:!dx.valver = !{![[valver:[0-9]+]]} +; CHECK:!dx.version = !{![[dxilver:[0-9]+]]} +; CHECK:!dx.shaderModel = !{![[shader_model:[0-9]+]]} + ; Make sure module flags still exist and only have 1 operand left. ; CHECK:!llvm.module.flags = !{{{![0-9]}}} ; Make sure validator version is 1.1. ; CHECK:![[valver]] = !{i32 1, i32 1} +; Make sure dxil version is 1.3. +; CHECK:![[dxilver]] = !{i32 1, i32 3} +; Make sure shader model is lib_6_3. +; CHECK:![[shader_model]] = !{!"library", i32 6, i32 3} + ; Make sure wchar_size still exist. ; CHECK:!{i32 1, !"wchar_size", i32 4} diff --git a/llvm/test/tools/dxil-dis/triple.ll b/llvm/test/tools/dxil-dis/triple.ll new file mode 100644 --- /dev/null +++ b/llvm/test/tools/dxil-dis/triple.ll @@ -0,0 +1,5 @@ +; RUN: llc --filetype=obj %s -o - | dxil-dis -o - | FileCheck %s +target triple = "dxil-unknown-unknown" + +; Make sure triple updated to dxil. +; CHECK:target triple = "dxil-ms-dx"