-
Notifications
You must be signed in to change notification settings - Fork 14.5k
[DirectX] Fix DXIL part header version encoding #91506
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Move MinorVersion be the lower 8 bit. Set DXIL version in DXContainerObjectWriter::writeObject. Also always normalize target triple in llc to get DXIL version from subArch. Fixes llvm#89952
@llvm/pr-subscribers-mc @llvm/pr-subscribers-backend-directx Author: Xiang Li (python3kgae) ChangesMove MinorVersion be the lower 8 bit. Also always normalize target triple in llc to get DXIL version from subArch. Fixes #89952 Full diff: https://github.com/llvm/llvm-project/pull/91506.diff 5 Files Affected:
diff --git a/llvm/include/llvm/BinaryFormat/DXContainer.h b/llvm/include/llvm/BinaryFormat/DXContainer.h
index e8d03f806715f..e5fcda63910d4 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainer.h
+++ b/llvm/include/llvm/BinaryFormat/DXContainer.h
@@ -103,8 +103,8 @@ struct PartHeader {
struct BitcodeHeader {
uint8_t Magic[4]; // ACSII "DXIL".
- uint8_t MajorVersion; // DXIL version.
uint8_t MinorVersion; // DXIL version.
+ uint8_t MajorVersion; // DXIL version.
uint16_t Unused;
uint32_t Offset; // Offset to LLVM bitcode (from start of header).
uint32_t Size; // Size of LLVM bitcode (in bytes).
diff --git a/llvm/lib/MC/MCDXContainerWriter.cpp b/llvm/lib/MC/MCDXContainerWriter.cpp
index 0580dc7e42826..015899278f379 100644
--- a/llvm/lib/MC/MCDXContainerWriter.cpp
+++ b/llvm/lib/MC/MCDXContainerWriter.cpp
@@ -127,6 +127,9 @@ uint64_t DXContainerObjectWriter::writeObject(MCAssembler &Asm,
// The program header's size field is in 32-bit words.
Header.Size = (SectionSize + sizeof(dxbc::ProgramHeader) + 3) / 4;
memcpy(Header.Bitcode.Magic, "DXIL", 4);
+ VersionTuple DXILVersion = TT.getDXILVersion();
+ Header.Bitcode.MajorVersion = DXILVersion.getMajor();
+ Header.Bitcode.MinorVersion = DXILVersion.getMinor().value_or(0);
Header.Bitcode.Offset = sizeof(dxbc::BitcodeHeader);
Header.Bitcode.Size = SectionSize;
if (sys::IsBigEndianHost)
diff --git a/llvm/test/CodeGen/DirectX/embed-dxil.ll b/llvm/test/CodeGen/DirectX/embed-dxil.ll
index 306e5c385b5a3..9f4fb19d86fa0 100644
--- a/llvm/test/CodeGen/DirectX/embed-dxil.ll
+++ b/llvm/test/CodeGen/DirectX/embed-dxil.ll
@@ -42,8 +42,8 @@ define i32 @add(i32 %a, i32 %b) {
; DXC-NEXT: MinorVersion: 5
; DXC-NEXT: ShaderKind: 6
; DXC-NEXT: Size: [[#div(SIZE,4)]]
-; DXC-NEXT: DXILMajorVersion: [[#]]
-; DXC-NEXT: DXILMinorVersion: [[#]]
+; DXC-NEXT: DXILMajorVersion: 1
+; DXC-NEXT: DXILMinorVersion: 5
; DXC-NEXT: DXILSize: [[#SIZE - 24]]
; DXC-NEXT: DXIL: [ 0x42, 0x43, 0xC0, 0xDE,
; DXC: - Name: SFI0
diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp
index b292f70ba89de..5825e79156774 100644
--- a/llvm/tools/llc/llc.cpp
+++ b/llvm/tools/llc/llc.cpp
@@ -537,8 +537,8 @@ static int compileModule(char **argv, LLVMContext &Context) {
// If we are supposed to override the target triple, do so now.
std::string IRTargetTriple = DataLayoutTargetTriple.str();
if (!TargetTriple.empty())
- IRTargetTriple = Triple::normalize(TargetTriple);
- TheTriple = Triple(IRTargetTriple);
+ IRTargetTriple = TargetTriple;
+ TheTriple = Triple(Triple::normalize(IRTargetTriple));
if (TheTriple.getTriple().empty())
TheTriple.setTriple(sys::getDefaultTargetTriple());
diff --git a/llvm/unittests/Object/DXContainerTest.cpp b/llvm/unittests/Object/DXContainerTest.cpp
index da640225617d4..28df84578113d 100644
--- a/llvm/unittests/Object/DXContainerTest.cpp
+++ b/llvm/unittests/Object/DXContainerTest.cpp
@@ -126,6 +126,51 @@ TEST(DXCFile, ParseOverlappingParts) {
"Part offset for part 1 begins before the previous part ends"));
}
+// This test verify DXILMajorVersion and DXILMinorVersion are correctly parsed.
+// This test is based on the binary output constructed from this yaml.
+// --- !dxcontainer
+// Header:
+// Hash: [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+// 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]
+// Version:
+// Major: 1
+// Minor: 0
+// PartCount: 1
+// Parts:
+// - Name: DXIL
+// Size: 28
+// Program:
+// MajorVersion: 6
+// MinorVersion: 5
+// ShaderKind: 5
+// Size: 8
+// DXILMajorVersion: 1
+// DXILMinorVersion: 5
+// DXILSize: 4
+// DXIL: [ 0x42, 0x43, 0xC0, 0xDE, ]
+// ...
+TEST(DXCFile, ParseDXILPart) {
+ uint8_t Buffer[] = {
+ 0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+ 0x44, 0x58, 0x49, 0x4c, 0x1c, 0x00, 0x00, 0x00, 0x65, 0x00, 0x05, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x05, 0x01, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde};
+ DXContainer C =
+ llvm::cantFail(DXContainer::create(getMemoryBuffer<116>(Buffer)));
+ EXPECT_EQ(C.getHeader().PartCount, 1u);
+ const std::optional<object::DXContainer::DXILData> &DXIL = C.getDXIL();
+ EXPECT_TRUE(DXIL.has_value());
+ dxbc::ProgramHeader Header = DXIL->first;
+ EXPECT_EQ(Header.MajorVersion, 6u);
+ EXPECT_EQ(Header.MinorVersion, 5u);
+ EXPECT_EQ(Header.ShaderKind, 5u);
+ EXPECT_EQ(Header.Size, 8u);
+ EXPECT_EQ(Header.Bitcode.MajorVersion, 1u);
+ EXPECT_EQ(Header.Bitcode.MinorVersion, 5u);
+}
+
TEST(DXCFile, ParseEmptyParts) {
uint8_t Buffer[] = {
0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -240,8 +285,8 @@ TEST(DXCFile, PSVResourceIterators) {
MinorVersion: 0
ShaderKind: 14
Size: 6
- DXILMajorVersion: 0
- DXILMinorVersion: 1
+ DXILMajorVersion: 1
+ DXILMinorVersion: 0
DXILSize: 0
...
)";
@@ -361,8 +406,8 @@ TEST(DXCFile, PSVResourceIterators) {
// MinorVersion: 0
// ShaderKind: 14
// Size: 6
-// DXILMajorVersion: 0
-// DXILMinorVersion: 1
+// DXILMajorVersion: 1
+// DXILMinorVersion: 0
// DXILSize: 0
// - Name: PSV0
// Size: 36
@@ -491,8 +536,8 @@ TEST(DXCFile, MaliciousFiles) {
// MinorVersion: 0
// ShaderKind: 14
// Size: 6
-// DXILMajorVersion: 0
-// DXILMinorVersion: 1
+// DXILMajorVersion: 1
+// DXILMinorVersion: 0
// DXILSize: 0
// - Name: PSV0
// Size: 100
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see failures of LLVM regression tests (target check-llvm
) with these changes.
Total Discovered Tests: 59475
Skipped : 346 (0.58%)
Unsupported : 27503 (46.24%)
Passed : 31174 (52.42%)
Expectedly Failed: 63 (0.11%)
Failed : 389 (0.65%)
FAILED: test/CMakeFiles/check-llvm /workspace/github/oss/llvm-build/hlsl/Debug/test/CMakeFiles/check-llvm
No such failures without this change (i.e., commit set to 8d9b154)
Total Discovered Tests: 59474
Skipped : 346 (0.58%)
Unsupported : 27503 (46.24%)
Passed : 31562 (53.07%)
Expectedly Failed: 63 (0.11%)
Failures appear to be related to changes in llvm/tools/llc/llc.cpp
Please double check. Thanks!
Thanks. Looking at it. |
llvm/tools/llc/llc.cpp
Outdated
IRTargetTriple = Triple::normalize(TargetTriple); | ||
IRTargetTriple = TargetTriple; | ||
if (!IRTargetTriple.empty()) | ||
IRTargetTriple = Triple::normalize(IRTargetTriple); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should be changing llc
to choose to always normalize triples buried in a DirectX change like this. This is a pretty significant change to the behaviour of llc when a module has an non-normalized triple, and if we really want to normalize the triple unconditionally I think that's a bigger change that needs wider discussion. Note that the Triple class deliberately does not normalize on construction, so that non-normalized triples can be worked with when appropriate (such as if it's intentionally broken for testing purposes, or something along those lines)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.
llvm/tools/llc/llc.cpp
Outdated
IRTargetTriple = TargetTriple; | ||
if (!IRTargetTriple.empty()) | ||
IRTargetTriple = Triple::normalize(IRTargetTriple); | ||
IRTargetTriple = Triple::normalize(TargetTriple); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this change still needed? Is it possible to avoid making changes to this file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. There's no change in llc.cpp now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a reminder to make sure the sentence
"Also always normalize target triple in llc to get DXIL version from subArch."
is edited out of the "Squash and Merge" commit message.
llvm/lib/TargetParser/Triple.cpp
Outdated
@@ -1510,6 +1510,8 @@ VersionTuple Triple::getDXILVersion() const { | |||
if (getArch() != dxil || getOS() != ShaderModel) | |||
llvm_unreachable("invalid DXIL triple"); | |||
StringRef Arch = getArchName(); | |||
if (Arch == "dxil") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can say getSubArch() == NoSubArch
here instead of using string comparison
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
|
Test failures on big endian bots after this change. Reverts #91506
Move MinorVersion be the lower 8 bit.
Set DXIL version in DXContainerObjectWriter::writeObject.
Fixes #89952