Skip to content

Commit a027eb4

Browse files
authored
[HLSL] Use hidden visibility for external linkage. (#140292)
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.
1 parent 34be09a commit a027eb4

File tree

113 files changed

+1101
-1140
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

113 files changed

+1101
-1140
lines changed

clang/lib/CodeGen/CGHLSLRuntime.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -471,14 +471,6 @@ void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD,
471471
}
472472
}
473473

474-
void CGHLSLRuntime::setHLSLFunctionAttributes(const FunctionDecl *FD,
475-
llvm::Function *Fn) {
476-
if (FD->isInExportDeclContext()) {
477-
const StringRef ExportAttrKindStr = "hlsl.export";
478-
Fn->addFnAttr(ExportAttrKindStr);
479-
}
480-
}
481-
482474
static void gatherFunctions(SmallVectorImpl<Function *> &Fns, llvm::Module &M,
483475
bool CtorOrDtor) {
484476
const auto *GV =

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1267,7 +1267,6 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
12671267
if (FD->hasAttr<HLSLShaderAttr>()) {
12681268
CGM.getHLSLRuntime().emitEntryFunction(FD, Fn);
12691269
}
1270-
CGM.getHLSLRuntime().setHLSLFunctionAttributes(FD, Fn);
12711270
}
12721271

12731272
EmitFunctionProlog(*CurFnInfo, CurFn, Args);

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1666,6 +1666,11 @@ void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV,
16661666
return;
16671667
}
16681668

1669+
if (Context.getLangOpts().HLSL && !D->isInExportDeclContext()) {
1670+
GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1671+
return;
1672+
}
1673+
16691674
if (GV->hasDLLExportStorageClass() || GV->hasDLLImportStorageClass()) {
16701675
// Reject incompatible dlllstorage and visibility annotations.
16711676
if (!LV.isVisibilityExplicit())

clang/test/CodeGenHLSL/ArrayAssignable.hlsl

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ struct S {
77

88
// CHECK: [[CBLayout:%.*]] = type <{ [2 x float], [2 x <4 x i32>], [2 x [2 x i32]], [1 x target("dx.Layout", %S, 8, 0, 4)] }>
99
// CHECK: @CBArrays.cb = global target("dx.CBuffer", target("dx.Layout", [[CBLayout]], 136, 0, 32, 64, 128))
10-
// CHECK: @c1 = external addrspace(2) global [2 x float], align 4
11-
// CHECK: @c2 = external addrspace(2) global [2 x <4 x i32>], align 16
12-
// CHECK: @c3 = external addrspace(2) global [2 x [2 x i32]], align 4
13-
// CHECK: @c4 = external addrspace(2) global [1 x target("dx.Layout", %S, 8, 0, 4)], align 1
10+
// CHECK: @c1 = external hidden addrspace(2) global [2 x float], align 4
11+
// CHECK: @c2 = external hidden addrspace(2) global [2 x <4 x i32>], align 16
12+
// CHECK: @c3 = external hidden addrspace(2) global [2 x [2 x i32]], align 4
13+
// CHECK: @c4 = external hidden addrspace(2) global [1 x target("dx.Layout", %S, 8, 0, 4)], align 1
1414

1515
cbuffer CBArrays : register(b0) {
1616
float c1[2];
@@ -19,7 +19,7 @@ cbuffer CBArrays : register(b0) {
1919
S c4[1];
2020
}
2121

22-
// CHECK-LABEL: define void {{.*}}arr_assign1
22+
// CHECK-LABEL: define hidden void {{.*}}arr_assign1
2323
// CHECK: [[Arr:%.*]] = alloca [2 x i32], align 4
2424
// CHECK-NEXT: [[Arr2:%.*]] = alloca [2 x i32], align 4
2525
// CHECK-NOT: alloca
@@ -33,7 +33,7 @@ void arr_assign1() {
3333
Arr = Arr2;
3434
}
3535

36-
// CHECK-LABEL: define void {{.*}}arr_assign2
36+
// CHECK-LABEL: define hidden void {{.*}}arr_assign2
3737
// CHECK: [[Arr:%.*]] = alloca [2 x i32], align 4
3838
// CHECK-NEXT: [[Arr2:%.*]] = alloca [2 x i32], align 4
3939
// CHECK-NEXT: [[Arr3:%.*]] = alloca [2 x i32], align 4
@@ -51,7 +51,7 @@ void arr_assign2() {
5151
Arr = Arr2 = Arr3;
5252
}
5353

54-
// CHECK-LABEL: define void {{.*}}arr_assign3
54+
// CHECK-LABEL: define hidden void {{.*}}arr_assign3
5555
// CHECK: [[Arr3:%.*]] = alloca [2 x [2 x i32]], align 4
5656
// CHECK-NEXT: [[Arr4:%.*]] = alloca [2 x [2 x i32]], align 4
5757
// CHECK-NOT: alloca
@@ -65,7 +65,7 @@ void arr_assign3() {
6565
Arr2 = Arr3;
6666
}
6767

68-
// CHECK-LABEL: define void {{.*}}arr_assign4
68+
// CHECK-LABEL: define hidden void {{.*}}arr_assign4
6969
// CHECK: [[Arr:%.*]] = alloca [2 x i32], align 4
7070
// CHECK-NEXT: [[Arr2:%.*]] = alloca [2 x i32], align 4
7171
// CHECK-NOT: alloca
@@ -81,7 +81,7 @@ void arr_assign4() {
8181
(Arr = Arr2)[0] = 6;
8282
}
8383

84-
// CHECK-LABEL: define void {{.*}}arr_assign5
84+
// CHECK-LABEL: define hidden void {{.*}}arr_assign5
8585
// CHECK: [[Arr:%.*]] = alloca [2 x i32], align 4
8686
// CHECK-NEXT: [[Arr2:%.*]] = alloca [2 x i32], align 4
8787
// CHECK-NEXT: [[Arr3:%.*]] = alloca [2 x i32], align 4
@@ -101,7 +101,7 @@ void arr_assign5() {
101101
(Arr = Arr2 = Arr3)[0] = 6;
102102
}
103103

104-
// CHECK-LABEL: define void {{.*}}arr_assign6
104+
// CHECK-LABEL: define hidden void {{.*}}arr_assign6
105105
// CHECK: [[Arr3:%.*]] = alloca [2 x [2 x i32]], align 4
106106
// CHECK-NEXT: [[Arr4:%.*]] = alloca [2 x [2 x i32]], align 4
107107
// CHECK-NOT: alloca
@@ -118,7 +118,7 @@ void arr_assign6() {
118118
(Arr = Arr2)[0][0] = 6;
119119
}
120120

121-
// CHECK-LABEL: define void {{.*}}arr_assign7
121+
// CHECK-LABEL: define hidden void {{.*}}arr_assign7
122122
// CHECK: [[Arr:%.*]] = alloca [2 x [2 x i32]], align 4
123123
// CHECK-NEXT: [[Arr2:%.*]] = alloca [2 x [2 x i32]], align 4
124124
// CHECK-NOT: alloca
@@ -138,7 +138,7 @@ void arr_assign7() {
138138

139139
// Verify you can assign from a cbuffer array
140140

141-
// CHECK-LABEL: define void {{.*}}arr_assign8
141+
// CHECK-LABEL: define hidden void {{.*}}arr_assign8
142142
// CHECK: [[C:%.*]] = alloca [2 x float], align 4
143143
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[C]], ptr align 4 {{.*}}, i32 8, i1 false)
144144
// CHECK-NEXT: call void @llvm.memcpy.p0.p2.i32(ptr align 4 [[C]], ptr addrspace(2) align 4 @c1, i32 8, i1 false)
@@ -148,7 +148,7 @@ void arr_assign8() {
148148
C = c1;
149149
}
150150

151-
// CHECK-LABEL: define void {{.*}}arr_assign9
151+
// CHECK-LABEL: define hidden void {{.*}}arr_assign9
152152
// CHECK: [[C:%.*]] = alloca [2 x <4 x i32>], align 16
153153
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 16 [[C]], ptr align 16 {{.*}}, i32 32, i1 false)
154154
// CHECK-NEXT: call void @llvm.memcpy.p0.p2.i32(ptr align 16 [[C]], ptr addrspace(2) align 16 @c2, i32 32, i1 false)
@@ -158,7 +158,7 @@ void arr_assign9() {
158158
C = c2;
159159
}
160160

161-
// CHECK-LABEL: define void {{.*}}arr_assign10
161+
// CHECK-LABEL: define hidden void {{.*}}arr_assign10
162162
// CHECK: [[C:%.*]] = alloca [2 x [2 x i32]], align 4
163163
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[C]], ptr align 4 {{.*}}, i32 16, i1 false)
164164
// CHECK-NEXT: call void @llvm.memcpy.p0.p2.i32(ptr align 4 [[C]], ptr addrspace(2) align 4 @c3, i32 16, i1 false)
@@ -168,7 +168,7 @@ void arr_assign10() {
168168
C = c3;
169169
}
170170

171-
// CHECK-LABEL: define void {{.*}}arr_assign11
171+
// CHECK-LABEL: define hidden void {{.*}}arr_assign11
172172
// CHECK: [[C:%.*]] = alloca [1 x %struct.S], align 1
173173
// CHECK: call void @llvm.memcpy.p0.p2.i32(ptr align 1 [[C]], ptr addrspace(2) align 1 @c4, i32 8, i1 false)
174174
// CHECK-NEXT: ret void

clang/test/CodeGenHLSL/ArrayTemporary.hlsl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
void fn(float x[2]) { }
55

6-
// CHECK-LABEL: define void {{.*}}call{{.*}}
6+
// CHECK-LABEL: define hidden void {{.*}}call{{.*}}
77
// CHECK: [[Arr:%.*]] = alloca [2 x float]
88
// CHECK: [[Tmp:%.*]] = alloca [2 x float]
99
// CHECK: call void @llvm.memset.p0.i32(ptr align 4 [[Arr]], i8 0, i32 8, i1 false)
@@ -21,7 +21,7 @@ struct Obj {
2121

2222
void fn2(Obj O[4]) { }
2323

24-
// CHECK-LABEL: define void {{.*}}call2{{.*}}
24+
// CHECK-LABEL: define hidden void {{.*}}call2{{.*}}
2525
// CHECK: [[Arr:%.*]] = alloca [4 x %struct.Obj]
2626
// CHECK: [[Tmp:%.*]] = alloca [4 x %struct.Obj]
2727
// CHECK: call void @llvm.memset.p0.i32(ptr align 1 [[Arr]], i8 0, i32 32, i1 false)
@@ -35,7 +35,7 @@ void call2() {
3535

3636
void fn3(float x[2][2]) { }
3737

38-
// CHECK-LABEL: define void {{.*}}call3{{.*}}
38+
// CHECK-LABEL: define hidden void {{.*}}call3{{.*}}
3939
// CHECK: [[Arr:%.*]] = alloca [2 x [2 x float]]
4040
// CHECK: [[Tmp:%.*]] = alloca [2 x [2 x float]]
4141
// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr]], ptr align 4 {{.*}}, i32 16, i1 false)
@@ -46,7 +46,7 @@ void call3() {
4646
fn3(Arr);
4747
}
4848

49-
// CHECK-LABEL: define void {{.*}}call4{{.*}}(ptr
49+
// CHECK-LABEL: define hidden void {{.*}}call4{{.*}}(ptr
5050
// CHECK-SAME: noundef byval([2 x [2 x float]]) align 4 [[Arr:%.*]])
5151
// CHECK: [[Tmp:%.*]] = alloca [2 x [2 x float]]
5252
// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[Arr]], i32 16, i1 false)
@@ -59,7 +59,7 @@ void call4(float Arr[2][2]) {
5959
// Verify that each template instantiation codegens to a unique and correctly
6060
// mangled function name.
6161

62-
// CHECK-LABEL: define void {{.*}}template_call{{.*}}(ptr
62+
// CHECK-LABEL: define hidden void {{.*}}template_call{{.*}}(ptr
6363

6464
// CHECK-SAME: noundef byval([2 x float]) align 4 [[FA2:%[0-9A-Z]+]],
6565
// CHECK-SAME: ptr noundef byval([4 x float]) align 4 [[FA4:%[0-9A-Z]+]],
@@ -86,7 +86,7 @@ void template_call(float FA2[2], float FA4[4], int IA3[3]) {
8686

8787

8888
// Verify that Array parameter element access correctly codegens.
89-
// CHECK-LABEL: define void {{.*}}element_access{{.*}}(ptr
89+
// CHECK-LABEL: define hidden void {{.*}}element_access{{.*}}(ptr
9090
// CHECK-SAME: noundef byval([2 x float]) align 4 [[FA2:%[0-9A-Z]+]]
9191

9292
// CHECK: [[Addr:%.*]] = getelementptr inbounds [2 x float], ptr [[FA2]], i32 0, i32 0

clang/test/CodeGenHLSL/BasicFeatures/ArrayOutputArguments.hlsl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ void increment(inout int Arr[2]) {
1111
// CHECK-NEXT: [[Tmp:%.*]] = alloca [2 x i32], align 4
1212
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 @{{.*}}, i32 8, i1 false)
1313
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[A]], i32 8, i1 false)
14-
// CHECK-NEXT: call void @{{.*}}increment{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]]) #3
14+
// CHECK-NEXT: call void @{{.*}}increment{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]])
1515
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 [[Tmp]], i32 8, i1 false)
1616
// CHECK-NEXT: [[Idx:%.*]] = getelementptr inbounds [2 x i32], ptr [[A]], i32 0, i32 0
1717
// CHECK-NEXT: [[B:%.*]] = load i32, ptr [[Idx]], align 4
@@ -32,7 +32,7 @@ void fn2(out int Arr[2]) {
3232
// CHECK: [[A:%.*]] = alloca [2 x i32], align 4
3333
// CHECK-NEXT: [[Tmp:%.*]] = alloca [2 x i32], align 4
3434
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 @{{.*}}, i32 8, i1 false)
35-
// CHECK-NEXT: call void @{{.*}}fn2{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]]) #3
35+
// CHECK-NEXT: call void @{{.*}}fn2{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]])
3636
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 [[Tmp]], i32 8, i1 false)
3737
// CHECK-NEXT: [[Idx:%.*]] = getelementptr inbounds [2 x i32], ptr [[A]], i32 0, i32 0
3838
// CHECK-NEXT: [[B:%.*]] = load i32, ptr [[Idx]], align 4
@@ -56,7 +56,7 @@ void nestedCall(inout int Arr[2], uint index) {
5656
// CHECK-NEXT: [[Tmp:%.*]] = alloca [2 x i32], align 4
5757
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 @{{.*}}, i32 8, i1 false)
5858
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[A]], i32 8, i1 false)
59-
// CHECK-NEXT: call void @{{.*}}nestedCall{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]], i32 noundef 0) #3
59+
// CHECK-NEXT: call void @{{.*}}nestedCall{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]], i32 noundef 0)
6060
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 [[Tmp]], i32 8, i1 false)
6161
// CHECK-NEXT: [[Idx:%.*]] = getelementptr inbounds [2 x i32], ptr [[A]], i32 0, i32 1
6262
// CHECK-NEXT: [[B:%.*]] = load i32, ptr [[Idx]], align 4
@@ -70,7 +70,7 @@ export int arrayCall3() {
7070
// CHECK-LABEL: outerCall
7171
// CHECK: [[Tmp:%.*]] = alloca [2 x i32], align 4
7272
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 %{{.*}}, i32 8, i1 false)
73-
// CHECK-NEXT: call void {{.*}}increment{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]]) #3
73+
// CHECK-NEXT: call void {{.*}}increment{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]])
7474
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 {{.*}}, ptr align 4 [[Tmp]], i32 8, i1 false)
7575
// CHECK-NEXT: ret void
7676
void outerCall(inout int Arr[2]) {
@@ -82,7 +82,7 @@ void outerCall(inout int Arr[2]) {
8282
// CHECK-NEXT: [[Tmp:%.*]] = alloca [2 x i32], align 4
8383
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 @{{.*}}, i32 8, i1 false)
8484
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[A]], i32 8, i1 false)
85-
// CHECK-NEXT: call void @{{.*}}outerCall{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]]) #3
85+
// CHECK-NEXT: call void @{{.*}}outerCall{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]])
8686
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 [[Tmp]], i32 8, i1 false)
8787
// CHECK-NEXT: [[Idx:%.*]] = getelementptr inbounds [2 x i32], ptr [[A]], i32 0, i32 0
8888
// CHECK-NEXT: [[B:%.*]] = load i32, ptr [[Idx]], align 4
@@ -99,7 +99,7 @@ void fn3(int Arr[2]) {}
9999
// CHECK-LABEL: outerCall2
100100
// CHECK: [[Tmp:%.*]] = alloca [2 x i32], align 4
101101
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 {{.*}}, i32 8, i1 false)
102-
// CHECK-NEXT: call void {{.*}}fn3{{.*}}(ptr noundef byval([2 x i32]) align 4 [[Tmp]]) #3
102+
// CHECK-NEXT: call void {{.*}}fn3{{.*}}(ptr noundef byval([2 x i32]) align 4 [[Tmp]])
103103
// CHECK-NEXT: ret void
104104
void outerCall2(inout int Arr[2]) {
105105
fn3(Arr);
@@ -110,7 +110,7 @@ void outerCall2(inout int Arr[2]) {
110110
// CHECK-NEXT: [[Tmp:%.*]] = alloca [2 x i32], align 4
111111
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 @{{.*}}, i32 8, i1 false)
112112
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[A]], i32 8, i1 false)
113-
// CHECK-NEXT: call void @{{.*}}outerCall2{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]]) #3
113+
// CHECK-NEXT: call void @{{.*}}outerCall2{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]])
114114
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 [[Tmp]], i32 8, i1 false)
115115
// CHECK-NEXT: [[Idx:%.*]] = getelementptr inbounds [2 x i32], ptr [[A]], i32 0, i32 0
116116
// CHECK-NEXT: [[B:%.*]] = load i32, ptr [[Idx]], align 4

0 commit comments

Comments
 (0)