Files
clang-p2996/llvm/test/CodeGen/DirectX/finalize-linkage-remove-dead-lib.ll
Greg Roth ab75180501 [DirectX] Remove trivially dead functions at linkage finalize (#106146)
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
2024-10-17 12:54:52 -06:00

223 lines
6.4 KiB
LLVM

; RUN: opt -S -dxil-finalize-linkage -mtriple=dxil-unknown-shadermodel6.5-library %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 export and is not an entry point.
; Has no specified inlining/linking behavior and is uncalled, this should be removed.
; CHECK-NOT: define {{.*}}doNothingUncalled
define void @"?doNothingUncalled@@YAXXZ"() #2 {
entry:
ret void
}
; Alwaysinline and uncalled, this should be removed.
; CHECK-NOT: define {{.*}}doAlwaysInlineUncalled
define void @"?doAlwaysInlineUncalled@@YAXXZ"() #0 {
entry:
ret void
}
; Noinline and uncalled, this should be removed.
; CHECK-NOT: define {{.*}}doNoinlineUncalled
define void @"?doNoinlineUncalled@@YAXXZ"() #4 {
entry:
ret void
}
; No inlining attribute, internal, and uncalled; this should be removed.
; CHECK-NOT: define {{.*}}doInternalUncalled
define internal void @"?doInternalUncalled@@YAXXZ"() #2 {
entry:
ret void
}
; Alwaysinline, internal, and uncalled; this should be removed.
; CHECK-NOT: define {{.*}}doAlwaysInlineInternalUncalled
define internal void @"?doAlwaysInlineInternalUncalled@@YAXXZ"() #0 {
entry:
ret void
}
; Noinline, internal, and uncalled; this should be removed.
; CHECK-NOT: define {{.*}}doNoinlineInternalUncalled
define internal void @"?doNoinlineInternalUncalled@@YAXXZ"() #4 {
entry:
ret void
}
; Marked external and uncalled, this should become internal and be removed.
; CHECK-NOT: define {{.*}}doExternalUncalled
define external void @"?doExternalUncalled@@YAXXZ"() #2 {
entry:
ret void
}
; Alwaysinline, external and uncalled, this should become internal and be removed.
; CHECK-NOT: define {{.*}}doAlwaysInlineExternalUncalled
define external void @"?doAlwaysInlineExternalUncalled@@YAXXZ"() #0 {
entry:
ret void
}
; Noinline, external and uncalled, this should become internal and be removed.
; CHECK-NOT: define {{.*}}doNoinlineExternalUncalled
define external void @"?doNoinlineExternalUncalled@@YAXXZ"() #4 {
entry:
ret void
}
; No inlining attribute and called, this should stay.
; CHECK: define {{.*}}doNothingCalled
define void @"?doNothingCalled@@YAXXZ"() #2 {
entry:
ret void
}
; Alwaysinline and called, this should stay.
; CHECK: define {{.*}}doAlwaysInlineCalled
define void @"?doAlwaysInlineCalled@@YAXXZ"() #0 {
entry:
ret void
}
; Noinline and called, this should stay.
; CHECK: define {{.*}}doNoinlineCalled
define void @"?doNoinlineCalled@@YAXXZ"() #4 {
entry:
ret void
}
; No inlining attribute, internal, and called; this should stay.
; CHECK: define {{.*}}doInternalCalled
define internal void @"?doInternalCalled@@YAXXZ"() #2 {
entry:
ret void
}
; Alwaysinline, internal, and called; this should stay.
; CHECK: define {{.*}}doAlwaysInlineInternalCalled
define internal void @"?doAlwaysInlineInternalCalled@@YAXXZ"() #0 {
entry:
ret void
}
; Noinline, internal, and called; this should stay.
; CHECK: define {{.*}}doNoinlineInternalCalled
define internal void @"?doNoinlineInternalCalled@@YAXXZ"() #4 {
entry:
ret void
}
; Marked external and called, this should become internal and stay.
; CHECK: define {{.*}}doExternalCalled
define external void @"?doExternalCalled@@YAXXZ"() #2 {
entry:
ret void
}
; Always inlined, external and called, this should become internal and stay.
; CHECK: define {{.*}}doAlwaysInlineExternalCalled
define external void @"?doAlwaysInlineExternalCalled@@YAXXZ"() #0 {
entry:
ret void
}
; Noinline, external and called, this should become internal and stay.
; CHECK: define {{.*}}doNoinlineExternalCalled
define external void @"?doNoinlineExternalCalled@@YAXXZ"() #4 {
entry:
ret void
}
; No inlining attribute and exported, this should stay.
; CHECK: define {{.*}}doNothingExported
define void @"?doNothingExported@@YAXXZ"() #3 {
entry:
ret void
}
; Alwaysinline and exported, this should stay.
; CHECK: define {{.*}}doAlwaysInlineExported
define void @"?doAlwaysInlineExported@@YAXXZ"() #1 {
entry:
ret void
}
; Noinline attribute and exported, this should stay.
; CHECK: define {{.*}}doNoinlineExported
define void @"?doNoinlineExported@@YAXXZ"() #5 {
entry:
ret void
}
; No inlining attribute, internal, and exported; this should stay.
; CHECK: define {{.*}}doInternalExported
define internal void @"?doInternalExported@@YAXXZ"() #3 {
entry:
ret void
}
; Alwaysinline, internal, and exported; this should stay.
; CHECK: define {{.*}}doAlwaysInlineInternalExported
define internal void @"?doAlwaysInlineInternalExported@@YAXXZ"() #1 {
entry:
ret void
}
; Noinline, internal, and exported; this should stay.
; CHECK: define {{.*}}doNoinlineInternalExported
define internal void @"?doNoinlineInternalExported@@YAXXZ"() #5 {
entry:
ret void
}
; Marked external and exported, this should stay.
; CHECK: define {{.*}}doExternalExported
define external void @"?doExternalExported@@YAXXZ"() #3 {
entry:
ret void
}
; Alwaysinline, external and exported, this should stay.
; CHECK: define {{.*}}doAlwaysInlineExternalExported
define external void @"?doAlwaysInlineExternalExported@@YAXXZ"() #1 {
entry:
ret void
}
; Noinline, external and exported, this should stay.
; CHECK: define {{.*}}doNoinlineExternalExported
define external void @"?doNoinlineExternalExported@@YAXXZ"() #5 {
entry:
ret void
}
; Entry point function, this should stay.
; CHECK: define void @main()
define void @main() #6 {
entry:
call void @"?doNothingCalled@@YAXXZ"() #7
call void @"?doAlwaysInlineCalled@@YAXXZ"() #7
call void @"?doNoinlineCalled@@YAXXZ"() #7
call void @"?doInternalCalled@@YAXXZ"() #7
call void @"?doAlwaysInlineInternalCalled@@YAXXZ"() #7
call void @"?doNoinlineInternalCalled@@YAXXZ"() #7
call void @"?doExternalCalled@@YAXXZ"() #7
call void @"?doAlwaysInlineExternalCalled@@YAXXZ"() #7
call void @"?doNoinlineExternalCalled@@YAXXZ"() #7
ret void
}
attributes #0 = { alwaysinline convergent norecurse nounwind }
attributes #1 = { alwaysinline convergent norecurse nounwind "hlsl.export"}
attributes #2 = { convergent norecurse nounwind }
attributes #3 = { convergent norecurse nounwind "hlsl.export"}
attributes #4 = { convergent noinline norecurse nounwind }
attributes #5 = { convergent noinline norecurse nounwind "hlsl.export"}
attributes #6 = { convergent noinline norecurse "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
attributes #7 = { convergent }