-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[DirectX] Remove trivially dead functions at linkage finalize #106146
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
20bf1f8
to
6cf9e80
Compare
I'd like to add a test that verifies this removal of used functions that get alwaysinlined, but that requires the inlining fix for #89282 |
✅ With the latest revision this PR passed the C/C++ code formatter. |
6cf9e80
to
e0d9fa7
Compare
1e39029
to
70d4b5d
Compare
Functions are not removed even when made internal by DXILFinalizeLinkage The removal code is called from alwaysinliner and globalopt, which are invoked too early to remove functions made internal by this pass. This adds a check similar to that in alwaysinliner that removes trivially dead functions after being marked internal. It refactors that code a bit to make it simpler including reversing what is stored in the work queue. Tests both the pass in isolation and the full inlining, linkage finalization, and function removal process. Fixes llvm#106139
70d4b5d
to
4022447
Compare
@llvm/pr-subscribers-clang Author: Greg Roth (pow2clk) ChangesFunctions are not removed even when made internal by DXILFinalizeLinkage The removal code is called from alwaysinliner and globalopt, which are invoked too early to remove functions made internal by this pass. This adds a check similar to that in alwaysinliner that removes trivially dead functions after being marked internal. It refactors that code a bit to make it simpler including reversing what is stored in the work queue. Not sure how to test this. To test all the interactions between alwaysinliner, DXILfinalizelinkage and any other optimization passes, it kinda needs to be end-to-end. Fixes #106139 Full diff: https://github.com/llvm/llvm-project/pull/106146.diff 3 Files Affected:
diff --git a/clang/test/CodeGenHLSL/remove-internal-unused.hlsl b/clang/test/CodeGenHLSL/remove-internal-unused.hlsl
new file mode 100644
index 00000000000000..85c114618a1e0e
--- /dev/null
+++ b/clang/test/CodeGenHLSL/remove-internal-unused.hlsl
@@ -0,0 +1,47 @@
+// RUN: %clang -target dxil-pc-shadermodel6.0-compute -S -o - %s | FileCheck %s
+// RUN: %clang -target dxil-pc-shadermodel6.3-library -S -o - %s | FileCheck %s
+
+// Verify that internal linkage unused functions are removed
+
+RWBuffer<unsigned> buf;
+
+// Never called functions should be removed.
+// CHECK-NOT: define{{.*}}uncalledFor
+void uncalledFor() {
+ buf[1] = 1;
+}
+
+// Never called but exported functions should remain.
+// CHECK: define void @"?exported@@YAXXZ"()
+export void exported() {
+ buf[1] = 1;
+}
+
+// Never called but noinlined functions should remain.
+// CHECK: define internal void @"?noinlined@@YAXXZ"()
+__attribute__((noinline)) void noinlined() {
+ buf[1] = 1;
+}
+
+// Called functions marked noinline should remain.
+// CHECK: define internal void @"?calledAndNoinlined@@YAXXZ"()
+__attribute__((noinline)) void calledAndNoinlined() {
+ buf[1] = 1;
+}
+
+// Called functions that get inlined by default should be removed.
+// CHECK-NOT: define{{.*}}calledAndInlined
+void calledAndInlined() {
+ buf[1] = 1;
+}
+
+
+// Entry point functions should remain.
+// CHECK: define{{.*}}main
+[numthreads(1,1,1)]
+[shader("compute")]
+void main() {
+ calledAndInlined();
+ calledAndNoinlined();
+ buf[0] = 0;
+}
\ No newline at end of file
diff --git a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
index d315d9bd16f439..59b30f965bf951 100644
--- a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
+++ b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
@@ -19,20 +19,20 @@
using namespace llvm;
static bool finalizeLinkage(Module &M) {
- SmallPtrSet<Function *, 8> EntriesAndExports;
+ SmallPtrSet<Function *, 8> Funcs;
// Find all entry points and export functions
for (Function &EF : M.functions()) {
- if (!EF.hasFnAttribute("hlsl.shader") && !EF.hasFnAttribute("hlsl.export"))
+ if (EF.hasFnAttribute("hlsl.shader") || EF.hasFnAttribute("hlsl.export"))
continue;
- EntriesAndExports.insert(&EF);
+ Funcs.insert(&EF);
}
- for (Function &F : M.functions()) {
- if (F.getLinkage() == GlobalValue::ExternalLinkage &&
- !EntriesAndExports.contains(&F)) {
- F.setLinkage(GlobalValue::InternalLinkage);
- }
+ for (Function *F : Funcs) {
+ if (F->getLinkage() == GlobalValue::ExternalLinkage)
+ F->setLinkage(GlobalValue::InternalLinkage);
+ if (F->hasFnAttribute(Attribute::AlwaysInline) && F->isDefTriviallyDead())
+ M.getFunctionList().erase(F);
}
return false;
diff --git a/llvm/test/CodeGen/DirectX/finalize-linkage-remove-dead.ll b/llvm/test/CodeGen/DirectX/finalize-linkage-remove-dead.ll
new file mode 100644
index 00000000000000..df5934355664d1
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/finalize-linkage-remove-dead.ll
@@ -0,0 +1,80 @@
+; RUN: opt -S -dxil-finalize-linkage -mtriple=dxil-unknown-shadermodel6.5-compute %s | FileCheck %s
+; RUN: llc %s --filetype=asm -o - | FileCheck %s
+
+target triple = "dxilv1.5-pc-shadermodel6.5-compute"
+
+; Confirm that DXILFinalizeLinkage will remove functions that have compatible
+; linkage and are not called from anywhere. This should be any function that
+; is not explicitly marked noinline or export and is not an entry point.
+
+; Not called nor marked with any linking or inlining attributes.
+; CHECK-NOT: define {{.*}}doNothingNothing
+define void @"?doNothingNothing@@YAXXZ"() #0 {
+entry:
+ ret void
+}
+
+; Marked internal, this should be removed.
+; CHECK-NOT: define {{.*}}doNothingInternally
+define internal void @"?doNothingInternally@@YAXXZ"() #0 {
+entry:
+ ret void
+}
+
+; Marked external, which should become internal and be removed.
+; CHECK-NOT: define {{.*}}doNothingExternally
+define external void @"?doNothingExternally@@YAXXZ"() #0 {
+entry:
+ ret void
+}
+
+; Not called nor marked with any linking or inlining attributes.
+; CHECK: define internal void @"?doSomethingSomething@@YAXXZ"() #0
+define void @"?doSomethingSomething@@YAXXZ"() #0 {
+entry:
+ ret void
+}
+
+; Marked internal, this should be removed.
+; CHECK: define internal void @"?doSomethingInternally@@YAXXZ"() #0
+define internal void @"?doSomethingInternally@@YAXXZ"() #0 {
+entry:
+ ret void
+}
+
+; Marked external, which should become internal and be removed.
+; CHECK: define internal void @"?doSomethingExternally@@YAXXZ"() #0
+define external void @"?doSomethingExternally@@YAXXZ"() #0 {
+entry:
+ ret void
+}
+
+; Lacks alwaysinline attribute. Should remain.
+; CHECK: define internal void @"?doNothingDefault@@YAXXZ"() #1
+define void @"?doNothingDefault@@YAXXZ"() #1 {
+entry:
+ ret void
+}
+
+; Has noinline attribute. Should remain.
+; CHECK: define {{.*}}doNothingNoinline
+define void @"?doNothingNoinline@@YAXXZ"() #2 {
+entry:
+ ret void
+}
+
+; Entry point function should stay.
+; CHECK: define void @main() #3
+define void @main() #3 {
+entry:
+ call void @"?doSomethingSomething@@YAXXZ"() #4
+ call void @"?doSomethingInternally@@YAXXZ"() #4
+ call void @"?doSomethingExternally@@YAXXZ"() #4
+ ret void
+}
+
+attributes #0 = { alwaysinline convergent norecurse nounwind }
+attributes #1 = { convergent norecurse nounwind }
+attributes #2 = { convergent noinline norecurse nounwind }
+attributes #3 = { convergent noinline norecurse "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
+attributes #4 = { convergent }
|
@llvm/pr-subscribers-backend-directx Author: Greg Roth (pow2clk) ChangesFunctions are not removed even when made internal by DXILFinalizeLinkage The removal code is called from alwaysinliner and globalopt, which are invoked too early to remove functions made internal by this pass. This adds a check similar to that in alwaysinliner that removes trivially dead functions after being marked internal. It refactors that code a bit to make it simpler including reversing what is stored in the work queue. Not sure how to test this. To test all the interactions between alwaysinliner, DXILfinalizelinkage and any other optimization passes, it kinda needs to be end-to-end. Fixes #106139 Full diff: https://github.com/llvm/llvm-project/pull/106146.diff 3 Files Affected:
diff --git a/clang/test/CodeGenHLSL/remove-internal-unused.hlsl b/clang/test/CodeGenHLSL/remove-internal-unused.hlsl
new file mode 100644
index 00000000000000..85c114618a1e0e
--- /dev/null
+++ b/clang/test/CodeGenHLSL/remove-internal-unused.hlsl
@@ -0,0 +1,47 @@
+// RUN: %clang -target dxil-pc-shadermodel6.0-compute -S -o - %s | FileCheck %s
+// RUN: %clang -target dxil-pc-shadermodel6.3-library -S -o - %s | FileCheck %s
+
+// Verify that internal linkage unused functions are removed
+
+RWBuffer<unsigned> buf;
+
+// Never called functions should be removed.
+// CHECK-NOT: define{{.*}}uncalledFor
+void uncalledFor() {
+ buf[1] = 1;
+}
+
+// Never called but exported functions should remain.
+// CHECK: define void @"?exported@@YAXXZ"()
+export void exported() {
+ buf[1] = 1;
+}
+
+// Never called but noinlined functions should remain.
+// CHECK: define internal void @"?noinlined@@YAXXZ"()
+__attribute__((noinline)) void noinlined() {
+ buf[1] = 1;
+}
+
+// Called functions marked noinline should remain.
+// CHECK: define internal void @"?calledAndNoinlined@@YAXXZ"()
+__attribute__((noinline)) void calledAndNoinlined() {
+ buf[1] = 1;
+}
+
+// Called functions that get inlined by default should be removed.
+// CHECK-NOT: define{{.*}}calledAndInlined
+void calledAndInlined() {
+ buf[1] = 1;
+}
+
+
+// Entry point functions should remain.
+// CHECK: define{{.*}}main
+[numthreads(1,1,1)]
+[shader("compute")]
+void main() {
+ calledAndInlined();
+ calledAndNoinlined();
+ buf[0] = 0;
+}
\ No newline at end of file
diff --git a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
index d315d9bd16f439..59b30f965bf951 100644
--- a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
+++ b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
@@ -19,20 +19,20 @@
using namespace llvm;
static bool finalizeLinkage(Module &M) {
- SmallPtrSet<Function *, 8> EntriesAndExports;
+ SmallPtrSet<Function *, 8> Funcs;
// Find all entry points and export functions
for (Function &EF : M.functions()) {
- if (!EF.hasFnAttribute("hlsl.shader") && !EF.hasFnAttribute("hlsl.export"))
+ if (EF.hasFnAttribute("hlsl.shader") || EF.hasFnAttribute("hlsl.export"))
continue;
- EntriesAndExports.insert(&EF);
+ Funcs.insert(&EF);
}
- for (Function &F : M.functions()) {
- if (F.getLinkage() == GlobalValue::ExternalLinkage &&
- !EntriesAndExports.contains(&F)) {
- F.setLinkage(GlobalValue::InternalLinkage);
- }
+ for (Function *F : Funcs) {
+ if (F->getLinkage() == GlobalValue::ExternalLinkage)
+ F->setLinkage(GlobalValue::InternalLinkage);
+ if (F->hasFnAttribute(Attribute::AlwaysInline) && F->isDefTriviallyDead())
+ M.getFunctionList().erase(F);
}
return false;
diff --git a/llvm/test/CodeGen/DirectX/finalize-linkage-remove-dead.ll b/llvm/test/CodeGen/DirectX/finalize-linkage-remove-dead.ll
new file mode 100644
index 00000000000000..df5934355664d1
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/finalize-linkage-remove-dead.ll
@@ -0,0 +1,80 @@
+; RUN: opt -S -dxil-finalize-linkage -mtriple=dxil-unknown-shadermodel6.5-compute %s | FileCheck %s
+; RUN: llc %s --filetype=asm -o - | FileCheck %s
+
+target triple = "dxilv1.5-pc-shadermodel6.5-compute"
+
+; Confirm that DXILFinalizeLinkage will remove functions that have compatible
+; linkage and are not called from anywhere. This should be any function that
+; is not explicitly marked noinline or export and is not an entry point.
+
+; Not called nor marked with any linking or inlining attributes.
+; CHECK-NOT: define {{.*}}doNothingNothing
+define void @"?doNothingNothing@@YAXXZ"() #0 {
+entry:
+ ret void
+}
+
+; Marked internal, this should be removed.
+; CHECK-NOT: define {{.*}}doNothingInternally
+define internal void @"?doNothingInternally@@YAXXZ"() #0 {
+entry:
+ ret void
+}
+
+; Marked external, which should become internal and be removed.
+; CHECK-NOT: define {{.*}}doNothingExternally
+define external void @"?doNothingExternally@@YAXXZ"() #0 {
+entry:
+ ret void
+}
+
+; Not called nor marked with any linking or inlining attributes.
+; CHECK: define internal void @"?doSomethingSomething@@YAXXZ"() #0
+define void @"?doSomethingSomething@@YAXXZ"() #0 {
+entry:
+ ret void
+}
+
+; Marked internal, this should be removed.
+; CHECK: define internal void @"?doSomethingInternally@@YAXXZ"() #0
+define internal void @"?doSomethingInternally@@YAXXZ"() #0 {
+entry:
+ ret void
+}
+
+; Marked external, which should become internal and be removed.
+; CHECK: define internal void @"?doSomethingExternally@@YAXXZ"() #0
+define external void @"?doSomethingExternally@@YAXXZ"() #0 {
+entry:
+ ret void
+}
+
+; Lacks alwaysinline attribute. Should remain.
+; CHECK: define internal void @"?doNothingDefault@@YAXXZ"() #1
+define void @"?doNothingDefault@@YAXXZ"() #1 {
+entry:
+ ret void
+}
+
+; Has noinline attribute. Should remain.
+; CHECK: define {{.*}}doNothingNoinline
+define void @"?doNothingNoinline@@YAXXZ"() #2 {
+entry:
+ ret void
+}
+
+; Entry point function should stay.
+; CHECK: define void @main() #3
+define void @main() #3 {
+entry:
+ call void @"?doSomethingSomething@@YAXXZ"() #4
+ call void @"?doSomethingInternally@@YAXXZ"() #4
+ call void @"?doSomethingExternally@@YAXXZ"() #4
+ ret void
+}
+
+attributes #0 = { alwaysinline convergent norecurse nounwind }
+attributes #1 = { convergent norecurse nounwind }
+attributes #2 = { convergent noinline norecurse nounwind }
+attributes #3 = { convergent noinline norecurse "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
+attributes #4 = { convergent }
|
@llvm/pr-subscribers-hlsl Author: Greg Roth (pow2clk) ChangesFunctions are not removed even when made internal by DXILFinalizeLinkage The removal code is called from alwaysinliner and globalopt, which are invoked too early to remove functions made internal by this pass. This adds a check similar to that in alwaysinliner that removes trivially dead functions after being marked internal. It refactors that code a bit to make it simpler including reversing what is stored in the work queue. Not sure how to test this. To test all the interactions between alwaysinliner, DXILfinalizelinkage and any other optimization passes, it kinda needs to be end-to-end. Fixes #106139 Full diff: https://github.com/llvm/llvm-project/pull/106146.diff 3 Files Affected:
diff --git a/clang/test/CodeGenHLSL/remove-internal-unused.hlsl b/clang/test/CodeGenHLSL/remove-internal-unused.hlsl
new file mode 100644
index 00000000000000..85c114618a1e0e
--- /dev/null
+++ b/clang/test/CodeGenHLSL/remove-internal-unused.hlsl
@@ -0,0 +1,47 @@
+// RUN: %clang -target dxil-pc-shadermodel6.0-compute -S -o - %s | FileCheck %s
+// RUN: %clang -target dxil-pc-shadermodel6.3-library -S -o - %s | FileCheck %s
+
+// Verify that internal linkage unused functions are removed
+
+RWBuffer<unsigned> buf;
+
+// Never called functions should be removed.
+// CHECK-NOT: define{{.*}}uncalledFor
+void uncalledFor() {
+ buf[1] = 1;
+}
+
+// Never called but exported functions should remain.
+// CHECK: define void @"?exported@@YAXXZ"()
+export void exported() {
+ buf[1] = 1;
+}
+
+// Never called but noinlined functions should remain.
+// CHECK: define internal void @"?noinlined@@YAXXZ"()
+__attribute__((noinline)) void noinlined() {
+ buf[1] = 1;
+}
+
+// Called functions marked noinline should remain.
+// CHECK: define internal void @"?calledAndNoinlined@@YAXXZ"()
+__attribute__((noinline)) void calledAndNoinlined() {
+ buf[1] = 1;
+}
+
+// Called functions that get inlined by default should be removed.
+// CHECK-NOT: define{{.*}}calledAndInlined
+void calledAndInlined() {
+ buf[1] = 1;
+}
+
+
+// Entry point functions should remain.
+// CHECK: define{{.*}}main
+[numthreads(1,1,1)]
+[shader("compute")]
+void main() {
+ calledAndInlined();
+ calledAndNoinlined();
+ buf[0] = 0;
+}
\ No newline at end of file
diff --git a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
index d315d9bd16f439..59b30f965bf951 100644
--- a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
+++ b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
@@ -19,20 +19,20 @@
using namespace llvm;
static bool finalizeLinkage(Module &M) {
- SmallPtrSet<Function *, 8> EntriesAndExports;
+ SmallPtrSet<Function *, 8> Funcs;
// Find all entry points and export functions
for (Function &EF : M.functions()) {
- if (!EF.hasFnAttribute("hlsl.shader") && !EF.hasFnAttribute("hlsl.export"))
+ if (EF.hasFnAttribute("hlsl.shader") || EF.hasFnAttribute("hlsl.export"))
continue;
- EntriesAndExports.insert(&EF);
+ Funcs.insert(&EF);
}
- for (Function &F : M.functions()) {
- if (F.getLinkage() == GlobalValue::ExternalLinkage &&
- !EntriesAndExports.contains(&F)) {
- F.setLinkage(GlobalValue::InternalLinkage);
- }
+ for (Function *F : Funcs) {
+ if (F->getLinkage() == GlobalValue::ExternalLinkage)
+ F->setLinkage(GlobalValue::InternalLinkage);
+ if (F->hasFnAttribute(Attribute::AlwaysInline) && F->isDefTriviallyDead())
+ M.getFunctionList().erase(F);
}
return false;
diff --git a/llvm/test/CodeGen/DirectX/finalize-linkage-remove-dead.ll b/llvm/test/CodeGen/DirectX/finalize-linkage-remove-dead.ll
new file mode 100644
index 00000000000000..df5934355664d1
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/finalize-linkage-remove-dead.ll
@@ -0,0 +1,80 @@
+; RUN: opt -S -dxil-finalize-linkage -mtriple=dxil-unknown-shadermodel6.5-compute %s | FileCheck %s
+; RUN: llc %s --filetype=asm -o - | FileCheck %s
+
+target triple = "dxilv1.5-pc-shadermodel6.5-compute"
+
+; Confirm that DXILFinalizeLinkage will remove functions that have compatible
+; linkage and are not called from anywhere. This should be any function that
+; is not explicitly marked noinline or export and is not an entry point.
+
+; Not called nor marked with any linking or inlining attributes.
+; CHECK-NOT: define {{.*}}doNothingNothing
+define void @"?doNothingNothing@@YAXXZ"() #0 {
+entry:
+ ret void
+}
+
+; Marked internal, this should be removed.
+; CHECK-NOT: define {{.*}}doNothingInternally
+define internal void @"?doNothingInternally@@YAXXZ"() #0 {
+entry:
+ ret void
+}
+
+; Marked external, which should become internal and be removed.
+; CHECK-NOT: define {{.*}}doNothingExternally
+define external void @"?doNothingExternally@@YAXXZ"() #0 {
+entry:
+ ret void
+}
+
+; Not called nor marked with any linking or inlining attributes.
+; CHECK: define internal void @"?doSomethingSomething@@YAXXZ"() #0
+define void @"?doSomethingSomething@@YAXXZ"() #0 {
+entry:
+ ret void
+}
+
+; Marked internal, this should be removed.
+; CHECK: define internal void @"?doSomethingInternally@@YAXXZ"() #0
+define internal void @"?doSomethingInternally@@YAXXZ"() #0 {
+entry:
+ ret void
+}
+
+; Marked external, which should become internal and be removed.
+; CHECK: define internal void @"?doSomethingExternally@@YAXXZ"() #0
+define external void @"?doSomethingExternally@@YAXXZ"() #0 {
+entry:
+ ret void
+}
+
+; Lacks alwaysinline attribute. Should remain.
+; CHECK: define internal void @"?doNothingDefault@@YAXXZ"() #1
+define void @"?doNothingDefault@@YAXXZ"() #1 {
+entry:
+ ret void
+}
+
+; Has noinline attribute. Should remain.
+; CHECK: define {{.*}}doNothingNoinline
+define void @"?doNothingNoinline@@YAXXZ"() #2 {
+entry:
+ ret void
+}
+
+; Entry point function should stay.
+; CHECK: define void @main() #3
+define void @main() #3 {
+entry:
+ call void @"?doSomethingSomething@@YAXXZ"() #4
+ call void @"?doSomethingInternally@@YAXXZ"() #4
+ call void @"?doSomethingExternally@@YAXXZ"() #4
+ ret void
+}
+
+attributes #0 = { alwaysinline convergent norecurse nounwind }
+attributes #1 = { convergent norecurse nounwind }
+attributes #2 = { convergent noinline norecurse nounwind }
+attributes #3 = { convergent noinline norecurse "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
+attributes #4 = { convergent }
|
calledAndInlined(); | ||
calledAndNoinlined(); | ||
buf[0] = 0; | ||
} |
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.
new line at EOF
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
@@ -19,20 +19,20 @@ | |||
using namespace llvm; | |||
|
|||
static bool finalizeLinkage(Module &M) { | |||
SmallPtrSet<Function *, 8> EntriesAndExports; | |||
SmallPtrSet<Function *, 8> Funcs; | |||
|
|||
// Find all entry points and export functions |
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.
This comment may be better updated to something like:
Collect all non-entry point and non-exported functions to possibly set to internal linkage later.
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
The consensus of the reviewers agreed with this approach Adds better testing too
; CHECK-COUNT-8: load i32, ptr addrspace(3) {{(.*@groushared2dArrayofVectors.scalarized.*|%.*)}}, align 4 | ||
; CHECK-NOT: load i32, ptr addrspace(3) {{.*}}, align 4 | ||
%1 = load <4 x i32>, <4 x i32> addrspace(3)* getelementptr inbounds ([3 x [3 x <4 x i32>]], [3 x [3 x <4 x i32>]] addrspace(3)* @"groushared2dArrayofVectors", i32 0, i32 0, i32 0), align 4 | ||
%2 = load <4 x i32>, <4 x i32> addrspace(3)* getelementptr inbounds ([3 x [3 x <4 x i32>]], [3 x [3 x <4 x i32>]] addrspace(3)* @"groushared2dArrayofVectors", i32 0, i32 1, i32 1), align 4 | ||
%3 = add <4 x i32> %1, %2 | ||
ret <4 x i32> %3 | ||
} | ||
|
||
attributes #0 = { convergent norecurse nounwind "hlsl.export"} |
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.
Why are we add attributes we don't test?
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.
With this change, any functions lacking this attribute will be removed because they are not called. The attribute is aded so they don't get removed and cause this and other tests to fail.
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.
LGTM!
since compute shaders shouldn't have exported functions, we won't test them that way
In ab75180 "[DirectX] Remove trivially dead functions at linkage finalize (llvm#106146)" we updated the compiler to remove DXIL functions that aren't marked with the "hlsl.export" attribute, but it seems we forgot to add this attribute to the tests in `tools/dxil-dis`.
Functions are not removed even when made internal by DXILFinalizeLinkage. The removal code is called from alwaysinliner and globalopt, which are invoked too early to remove functions made internal by this pass.
This adds a check similar to that in alwaysinliner that removes trivially dead functions after being marked internal. It refactors that code a bit to make it simpler including reversing what is stored int he work queue.
Tests both the pass in isolation and the full i0nlining, linkage finalization and function removal steps.
Fixes #106139