diff --git a/llvm/lib/Target/DirectX/DxilEmitMetadata.cpp b/llvm/lib/Target/DirectX/DxilEmitMetadata.cpp index 126db57c87671..ffe8916e52f18 100644 --- a/llvm/lib/Target/DirectX/DxilEmitMetadata.cpp +++ b/llvm/lib/Target/DirectX/DxilEmitMetadata.cpp @@ -25,28 +25,35 @@ ConstantAsMetadata *Uint32ToConstMD(unsigned v, LLVMContext &Ctx) { return ConstantAsMetadata::get( Constant::getIntegerValue(IntegerType::get(Ctx, 32), APInt(32, v))); } + const StringRef ValVerKey = "dx.valver"; +const StringRef DxilVerKey = "dx.version"; const unsigned DxilVersionNumFields = 2; const unsigned DxilVersionMajorIdx = 0; // DXIL version major. const unsigned DxilVersionMinorIdx = 1; // DXIL version minor. -void emitDxilValidatorVersion(Module &M, VersionTuple &ValidatorVer) { - NamedMDNode *DxilValidatorVersionMD = M.getNamedMetadata(ValVerKey); - - // Allow re-writing the validator version, since this can be changed at - // later points. - if (DxilValidatorVersionMD) - M.eraseNamedMetadata(DxilValidatorVersionMD); +const unsigned OfflineLibMinor = 0xF; +const unsigned MaxDXILMinor = 7; - DxilValidatorVersionMD = M.getOrInsertNamedMetadata(ValVerKey); - - auto &Ctx = M.getContext(); +void emitVersion(NamedMDNode *MD, VersionTuple &Ver, LLVMContext &Ctx) { Metadata *MDVals[DxilVersionNumFields]; - MDVals[DxilVersionMajorIdx] = Uint32ToConstMD(ValidatorVer.getMajor(), Ctx); + MDVals[DxilVersionMajorIdx] = Uint32ToConstMD(Ver.getMajor(), Ctx); MDVals[DxilVersionMinorIdx] = - Uint32ToConstMD(ValidatorVer.getMinor().getValueOr(0), Ctx); + Uint32ToConstMD(Ver.getMinor().getValueOr(0), Ctx); + + MD->addOperand(MDNode::get(Ctx, MDVals)); +} + +void emitDxilVersion(Module &M, StringRef Key, VersionTuple &DxilVer) { + NamedMDNode *DxilVersionMD = M.getNamedMetadata(Key); + // Clear if already exist. + if (DxilVersionMD) + M.eraseNamedMetadata(DxilVersionMD); - DxilValidatorVersionMD->addOperand(MDNode::get(Ctx, MDVals)); + DxilVersionMD = M.getOrInsertNamedMetadata(Key); + + auto &Ctx = M.getContext(); + emitVersion(DxilVersionMD, DxilVer, Ctx); } VersionTuple loadDxilValidatorVersion(MDNode *ValVerMD) { @@ -58,6 +65,15 @@ VersionTuple loadDxilValidatorVersion(MDNode *ValVerMD) { return VersionTuple(Major, Minor); } +VersionTuple getDxilVersion(VersionTuple &ShaderModel) { + unsigned Major = 1; + unsigned Minor = ShaderModel.getMinor().getValueOr(0); + if (Minor == OfflineLibMinor) { + Minor = MaxDXILMinor; + } + return VersionTuple(Major, Minor); +} + void cleanModule(Module &M) { M.getOrInsertModuleFlagsMetadata()->eraseFromParent(); } @@ -67,24 +83,34 @@ namespace { class DxilEmitMetadata : public ModulePass { public: static char ID; // Pass identification, replacement for typeid - explicit DxilEmitMetadata() : ModulePass(ID), ValidatorVer(1, 0) {} + explicit DxilEmitMetadata() : ModulePass(ID) {} StringRef getPassName() const override { return "HLSL DXIL Metadata Emit"; } bool runOnModule(Module &M) override; private: - VersionTuple ValidatorVer; void emitDXILVersion(Module &M); }; bool DxilEmitMetadata::runOnModule(Module &M) { + Triple Triple(M.getTargetTriple()); + VersionTuple ShaderModel = Triple.getOSVersion(); + VersionTuple DxilVer = getDxilVersion(ShaderModel); + emitDxilVersion(M, DxilVerKey, DxilVer); + VersionTuple ValidatorVer(1, 0); if (MDNode *ValVerMD = cast_or_null(M.getModuleFlag(ValVerKey))) { auto ValVer = loadDxilValidatorVersion(ValVerMD); if (!ValVer.empty()) ValidatorVer = ValVer; } - emitDxilValidatorVersion(M, ValidatorVer); + unsigned ShaderModelMinor = ShaderModel.getMinor().getValueOr(0); + if (ShaderModelMinor == OfflineLibMinor) { + ValidatorVer = VersionTuple(0, 0); + } else if (ValidatorVer < DxilVer) { + ValidatorVer = DxilVer; + } + emitDxilVersion(M, ValVerKey, ValidatorVer); cleanModule(M); return false; } diff --git a/llvm/test/CodeGen/DirectX/dxil_ver.ll b/llvm/test/CodeGen/DirectX/dxil_ver.ll index 8e3ba5646c7b3..145b6f3127cb0 100644 --- a/llvm/test/CodeGen/DirectX/dxil_ver.ll +++ b/llvm/test/CodeGen/DirectX/dxil_ver.ll @@ -3,12 +3,12 @@ target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32 target triple = "dxil-pc-shadermodel6.3-library" ; CHECK:!dx.valver = !{![[valver:[0-9]+]]} -; CHECK:![[valver]] = !{i32 1, i32 1} +; CHECK:![[valver]] = !{i32 1, i32 5} !llvm.module.flags = !{!0, !1} !llvm.ident = !{!3} !0 = !{i32 1, !"wchar_size", i32 4} !1 = !{i32 6, !"dx.valver", !2} -!2 = !{i32 1, i32 1} +!2 = !{i32 1, i32 5} !3 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project 71de12113a0661649ecb2f533fba4a2818a1ad68)"} \ No newline at end of file diff --git a/llvm/test/CodeGen/DirectX/dxil_ver_lib6x.ll b/llvm/test/CodeGen/DirectX/dxil_ver_lib6x.ll new file mode 100644 index 0000000000000..cee44359bde9c --- /dev/null +++ b/llvm/test/CodeGen/DirectX/dxil_ver_lib6x.ll @@ -0,0 +1,15 @@ +; RUN: llc %s -mtriple dxil-pc-shadermodel6.15-library --filetype=asm -o - | FileCheck %s +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" + +; CHECK:!dx.version = !{![[ver:[0-9]+]]} +; CHECK:!dx.valver = !{![[valver:[0-9]+]]} +; CHECK-DAG:![[ver]] = !{i32 1, i32 7} +; CHECK-DAG:![[valver]] = !{i32 0, i32 0} + +!llvm.module.flags = !{!0, !1} +!llvm.ident = !{!3} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 6, !"dx.valver", !2} +!2 = !{i32 1, i32 5} +!3 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project 71de12113a0661649ecb2f533fba4a2818a1ad68)"} \ No newline at end of file