
Implements https://github.com/llvm/wg-hlsl/blob/main/proposals/0026-symbol-visibility.md. The change is to stop using the `hlsl.export` attribute. Instead, symbols with "program linkage" in HLSL will have export linkage with default visibility, and symbols with "external linkage" in HLSL will have export linkage with hidden visibility.
202 lines
5.9 KiB
LLVM
202 lines
5.9 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 marked hidden or internal.
|
|
|
|
; Is hidden, and uncalled, this should be removed.
|
|
; CHECK-NOT: define {{.*}}doNothingUncalled
|
|
define hidden void @"?doNothingUncalled@@YAXXZ"() #2 {
|
|
entry:
|
|
ret void
|
|
}
|
|
|
|
; Alwaysinline, hidden and uncalled, this should be removed.
|
|
; CHECK-NOT: define {{.*}}doAlwaysInlineUncalled
|
|
define hidden void @"?doAlwaysInlineUncalled@@YAXXZ"() #0 {
|
|
entry:
|
|
ret void
|
|
}
|
|
|
|
; Noinline, hidden and uncalled, this should be removed.
|
|
; CHECK-NOT: define {{.*}}doNoinlineUncalled
|
|
define hidden 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, hidden and uncalled, this should become internal and be removed.
|
|
; CHECK-NOT: define {{.*}}doExternalUncalled
|
|
define external hidden void @"?doExternalUncalled@@YAXXZ"() #2 {
|
|
entry:
|
|
ret void
|
|
}
|
|
|
|
; Alwaysinline, external, hidden and uncalled, this should become internal and be removed.
|
|
; CHECK-NOT: define {{.*}}doAlwaysInlineExternalUncalled
|
|
define external hidden void @"?doAlwaysInlineExternalUncalled@@YAXXZ"() #0 {
|
|
entry:
|
|
ret void
|
|
}
|
|
|
|
; Noinline, external, hidden and uncalled, this should become internal and be removed.
|
|
; CHECK-NOT: define {{.*}}doNoinlineExternalUncalled
|
|
define external hidden void @"?doNoinlineExternalUncalled@@YAXXZ"() #4 {
|
|
entry:
|
|
ret void
|
|
}
|
|
|
|
; No inlining attribute, hidden and called, this should stay.
|
|
; CHECK: define {{.*}}doNothingCalled
|
|
define hidden void @"?doNothingCalled@@YAXXZ"() #2 {
|
|
entry:
|
|
ret void
|
|
}
|
|
|
|
; Alwaysinline, hidden and called, this should stay.
|
|
; CHECK: define {{.*}}doAlwaysInlineCalled
|
|
define hidden void @"?doAlwaysInlineCalled@@YAXXZ"() #0 {
|
|
entry:
|
|
ret void
|
|
}
|
|
|
|
; Noinline, hidden and called, this should stay.
|
|
; CHECK: define {{.*}}doNoinlineCalled
|
|
define hidden 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, hidden and called, this should become internal and stay.
|
|
; CHECK: define {{.*}}doExternalCalled
|
|
define external hidden void @"?doExternalCalled@@YAXXZ"() #2 {
|
|
entry:
|
|
ret void
|
|
}
|
|
|
|
; Always inlined, external, hidden and called, this should become internal and stay.
|
|
; CHECK: define {{.*}}doAlwaysInlineExternalCalled
|
|
define external hidden void @"?doAlwaysInlineExternalCalled@@YAXXZ"() #0 {
|
|
entry:
|
|
ret void
|
|
}
|
|
|
|
; Noinline, external, hidden and called, this should become internal and stay.
|
|
; CHECK: define {{.*}}doNoinlineExternalCalled
|
|
define external hidden 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
|
|
}
|
|
|
|
; 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 }
|
|
attributes #2 = { convergent norecurse nounwind }
|
|
attributes #3 = { convergent norecurse nounwind }
|
|
attributes #4 = { convergent noinline norecurse nounwind }
|
|
attributes #5 = { convergent noinline norecurse nounwind }
|
|
attributes #6 = { convergent noinline norecurse "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
|
|
attributes #7 = { convergent }
|