1- // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s --check-prefixes=CHECK,NOINLINE
2- // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library %s -emit-llvm -O0 -o - | FileCheck %s --check-prefixes=CHECK,INLINE
3- // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library %s -emit-llvm -O1 -o - | FileCheck %s --check-prefixes=CHECK,INLINE
4- // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s --check-prefixes=CHECK,NOINLINE
5- // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute %s -emit-llvm -O0 -o - | FileCheck %s --check-prefixes=CHECK,INLINE
6- // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute %s -emit-llvm -O1 -o - | FileCheck %s --check-prefixes=CHECK,INLINE
7-
8- // Tests that user functions will always be inlined .
1+ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s --check-prefixes=CHECK,CHECK_LIB_OPTNONE
2+ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library %s -emit-llvm -O0 -o - | FileCheck %s --check-prefixes=CHECK,CHECK_LIB_OPTNONE
3+ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library %s -emit-llvm -O1 -o - | FileCheck %s --check-prefixes=CHECK,CHECK_OPT
4+ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s --check-prefixes=CHECK,CHECK_CS_OPTNONE_NOPASS
5+ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute %s -emit-llvm -O0 -o - | FileCheck %s --check-prefixes=CHECK,CHECK_CS_OPTNONE_PASS
6+ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute %s -emit-llvm -O1 -o - | FileCheck %s --check-prefixes=CHECK,CHECK_OPT
7+
8+ // Tests inlining of user functions based on specified optimization options .
99// This includes exported functions and mangled entry point implementation functions.
10- // The unmangled entry functions must not be alwaysinlined.
1110
1211#define MAX 100
1312
1413float nums[MAX ];
1514
16- // Verify that all functions have the alwaysinline attribute
17- // NOINLINE: Function Attrs: alwaysinline
18- // NOINLINE: define void @_Z4swapA100_jjj(ptr noundef byval([100 x i32]) align 4 %Buf, i32 noundef %ix1, i32 noundef %ix2) [[IntAttr:\#[0-9]+]]
19- // NOINLINE: ret void
15+ // Check optnone attribute for library target compilation
16+ // CHECK_LIB_OPTNONE: Function Attrs:{{.*}}optnone
17+ // CHECK_LIB_OPTNONE: define void @_Z4swapA100_jjj(ptr noundef byval([100 x i32]) align 4 %Buf, i32 noundef %ix1, i32 noundef %ix2) [[ExtAttr:\#[0-9]+]]
18+
19+ // Check alwaysinline attribute for non-entry functions of compute target compilation
20+ // CHECK_CS_OPTNONE_NOPASS: Function Attrs: alwaysinline
21+ // CHECK_CS_OPTNONE_NOPASS: define void @_Z4swapA100_jjj(ptr noundef byval([100 x i32]) align 4 %Buf, i32 noundef %ix1, i32 noundef %ix2) [[ExtAttr:\#[0-9]+]]
22+
23+ // Check alwaysinline attribute for non-entry functions of compute target compilation
24+ // CHECK_CS_OPTNONE_PASS: Function Attrs: alwaysinline
25+ // CHECK_CS_OPTNONE_PASS: define void @_Z4swapA100_jjj(ptr noundef byval([100 x i32]) align 4 %Buf, i32 noundef %ix1, i32 noundef %ix2) [[ExtAttr:\#[0-9]+]]
26+
27+ // Check alwaysinline attribute for opt compilation to library target
28+ // CHECK_OPT: Function Attrs: alwaysinline
29+ // CHECK_OPT: define void @_Z4swapA100_jjj(ptr noundef byval([100 x i32]) align 4 captures(none) %Buf, i32 noundef %ix1, i32 noundef %ix2) {{[a-z_ ]*}} [[SwapOptAttr:\#[0-9]+]]
30+
31+ // CHECK: ret void
32+
2033// Swap the values of Buf at indices ix1 and ix2
2134void swap (unsigned Buf[MAX ], unsigned ix1, unsigned ix2) {
2235 float tmp = Buf[ix1];
2336 Buf[ix1] = Buf[ix2];
2437 Buf[ix2] = tmp;
2538}
2639
27- // NOINLINE: Function Attrs: alwaysinline
28- // NOINLINE: define void @_Z10BubbleSortA100_jj(ptr noundef byval([100 x i32]) align 4 %Buf, i32 noundef %size) [[IntAttr]]
29- // NOINLINE: ret void
40+ // Check optnone attribute for library target compilation
41+ // CHECK_LIB_OPTNONE: Function Attrs:{{.*}}optnone
42+ // CHECK_LIB_OPTNONE: define void @_Z10BubbleSortA100_jj(ptr noundef byval([100 x i32]) align 4 %Buf, i32 noundef %size) [[ExtAttr]]
43+
44+ // Check alwaysinline attribute for non-entry functions of compute target compilation
45+ // CHECK_CS_OPTNONE_NOPASS: Function Attrs: alwaysinline
46+ // CHECK_CS_OPTNONE_NOPASS: define void @_Z10BubbleSortA100_jj(ptr noundef byval([100 x i32]) align 4 %Buf, i32 noundef %size) [[ExtAttr]]
47+
48+ // Check alwaysinline attribute for non-entry functions of compute target compilation
49+ // CHECK_CS_OPTNONE_PASS: Function Attrs: alwaysinline
50+ // CHECK_CS_OPTNONE_PASS: define void @_Z10BubbleSortA100_jj(ptr noundef byval([100 x i32]) align 4 %Buf, i32 noundef %size) [[ExtAttr]]
51+
52+ // Check alwaysinline attribute for opt compilation to library target
53+ // CHECK_OPT: Function Attrs: alwaysinline
54+ // CHECK_OPT: define void @_Z10BubbleSortA100_jj(ptr noundef readonly byval([100 x i32]) align 4 captures(none) %Buf, i32 noundef %size) {{[a-z_ ]*}} [[BubOptAttr:\#[0-9]+]]
55+
56+ // CHECK: ret void
57+
3058// Inefficiently sort Buf in place
3159void BubbleSort (unsigned Buf[MAX ], unsigned size) {
3260 bool swapped = true ;
@@ -41,12 +69,26 @@ void BubbleSort(unsigned Buf[MAX], unsigned size) {
4169 }
4270}
4371
44- // Note ExtAttr is the inlined export set of attribs
45- // CHECK: Function Attrs: alwaysinline
46- // CHECK: define noundef i32 @_Z11RemoveDupesA100_jj(ptr {{[a-z_ ]*}}noundef byval([100 x i32]) align 4 {{.*}}%Buf, i32 noundef %size) {{[a-z_ ]*}}[[ExtAttr:\#[0-9]+]]
47- // CHECK: ret i32
72+ // Check optnone attribute for library target compilation of exported function
73+ // CHECK_LIB_OPTNONE: Function Attrs:{{.*}}optnone
74+ // CHECK_LIB_OPTNONE: define noundef i32 @_Z11RemoveDupesA100_jj(ptr {{[a-z_ ]*}}noundef byval([100 x i32]) align 4 {{.*}}%Buf, i32 noundef %size) [[ExportAttr:\#[0-9]+]]
4875// Sort Buf and remove any duplicate values
4976// returns the number of values left
77+
78+ // Check alwaysinline attribute for exported function of compute target compilation
79+ // CHECK_CS_OPTNONE_NOPASS: Function Attrs: alwaysinline
80+ // CHECK_CS_OPTNONE_NOPASS: define noundef i32 @_Z11RemoveDupesA100_jj(ptr {{[a-z_ ]*}}noundef byval([100 x i32]) align 4 {{.*}}%Buf, i32 noundef %size) [[ExportAttr:\#[0-9]+]]
81+
82+ // Check alwaysinline attribute for exported function of compute target compilation
83+ // CHECK_CS_OPTNONE_PASS: Function Attrs: alwaysinline
84+ // CHECK_CS_OPTNONE_PASS: define noundef i32 @_Z11RemoveDupesA100_jj(ptr {{[a-z_ ]*}}noundef byval([100 x i32]) align 4 {{.*}}%Buf, i32 noundef %size) [[ExportAttr:\#[0-9]+]]
85+
86+ // Check alwaysinline attribute for exported function of library target compilation
87+ // CHECK_OPT: Function Attrs: alwaysinline
88+ // CHECK_OPT: define noundef i32 @_Z11RemoveDupesA100_jj(ptr noundef byval([100 x i32]) align 4 captures(none) %Buf, i32 noundef %size) {{[a-z_ ]*}} [[RemOptAttr:\#[0-9]+]]
89+
90+ // CHECK: ret i32
91+
5092export
5193unsigned RemoveDupes (unsigned Buf[MAX ], unsigned size) {
5294 BubbleSort (Buf, size);
@@ -63,19 +105,44 @@ unsigned RemoveDupes(unsigned Buf[MAX], unsigned size) {
63105
64106RWBuffer <unsigned > Indices;
65107
66- // The mangled version of main only remains without inlining
67- // because it has internal linkage from the start
68- // Note main functions get the norecurse attrib, which IntAttr reflects
69- // NOINLINE: Function Attrs: alwaysinline
70- // NOINLINE: define internal void @_Z4mainj(i32 noundef %GI) [[IntAttr]]
71- // NOINLINE: ret void
108+ // CHECK_LIB_OPTNONE: Function Attrs:{{.*}}optnone
109+ // Internal function attributes are the same as those of source function's
110+ // CHECK_LIB_OPTNONE: define internal void @_Z4mainj(i32 noundef %GI) [[ExtAttr]]
111+ // CHECK_LIB_OPTNONE: ret void
112+
113+ // CHECK_CS_OPTNONE_NOPASS: Function Attrs: alwaysinline
114+ // Internal function attributes are different from those of source function's
115+ // CHECK_CS_OPTNONE_NOPASS: define internal void @_Z4mainj(i32 noundef %GI) [[ExtAttr]]
116+ // CHECK_CS_OPTNONE_NOPASS: ret void
117+
118+ // Check internal function @_Z4mainj is not generated when LLVM passes enabled
119+ // CHECK_CS_OPTNONE_PASS-NOT: define internal void @_Z4mainj
120+
121+ // Check internal function @_Z4mainj is not generated as it should be inlined
122+ // for opt builds
123+ // CHECK_OPT-NOT: define internal void @_Z4mainj
72124
73125// The unmangled version is not inlined, EntryAttr reflects that
74- // CHECK: Function Attrs: {{.*}}noinline
75- // CHECK: define void @main() {{[a-z_ ]*}}[[EntryAttr:\#[0-9]+]]
76- // Make sure function calls are inlined when AlwaysInline is run
77- // This only leaves calls to llvm. intrinsics
78- // INLINE-NOT: call {{[^@]*}} @{{[^l][^l][^v][^m][^\.]}}
126+ // CHECK_LIB_OPTNONE: Function Attrs: {{.*}}noinline
127+ // CHECK_LIB_OPTNONE: define void @main() {{[a-z_ ]*}}[[EntryAttr:\#[0-9]+]]
128+ // Make sure internal function is not inlined when optimization is disabled
129+ // CHECK_LIB_OPTNONE: call void @_Z4mainj
130+
131+ // CHECK_CS_OPTNONE_NOPASS: Function Attrs:{{.*}}optnone
132+ // CHECK_CS_OPTNONE_NOPASS: define void @main() {{[a-z_ ]*}}[[EntryAttr:\#[0-9]+]]
133+ // Make sure internal function is not inlined when optimization is disabled
134+ // CHECK_CS_OPTNONE_NOPASS: call void @_Z4mainj
135+
136+ // CHECK_CS_OPTNONE_PASS: Function Attrs: {{.*}}noinline
137+ // CHECK_CS_OPTNONE_PASS: define void @main() {{[a-z_ ]*}}[[EntryAttr:\#[0-9]+]]
138+ // Make sure internal function is inlined when LLVM passes are enabled
139+ // CHECK_CS_OPTNONE_PASS: _Z4mainj.exit:
140+
141+ // CHECK_OPT: Function Attrs: {{.*}}noinline
142+ // CHECK_OPT: define void @main() {{[a-z_ ]*}}[[EntryAttr:\#[0-9]+]]
143+ // Make sure internal function is inlined as optimization is enabled
144+ // CHECK_OPT: _Z4mainj.exit:
145+
79146// CHECK: ret void
80147
81148[numthreads (1 ,1 ,1 )]
@@ -90,19 +157,41 @@ void main(unsigned int GI : SV_GroupIndex) {
90157 tmpIndices[i] = Indices[i];
91158}
92159
93- // The mangled version of main only remains without inlining
94- // because it has internal linkage from the start
95- // Note main functions get the norecurse attrib, which IntAttr reflects
96- // NOINLINE: Function Attrs: alwaysinline
97- // NOINLINE: define internal void @_Z6main10v() [[IntAttr]]
98- // NOINLINE: ret void
160+ // CHECK_LIB_OPTNONE: Function Attrs:{{.*}}optnone
161+ // CHECK_LIB_OPTNONE: define internal void @_Z6main10v() [[ExtAttr]]
162+ // CHECK_LIB_OPTNONE: ret void
163+
164+ // CHECK_CS_OPTNONE_NOPASS: Function Attrs:{{.*}}alwaysinline
165+ // CHECK_CS_OPTNONE_NOPASS: define internal void @_Z6main10v() [[ExtAttr]]
166+ // CHECK_CS_OPTNONE_NOPASS: ret void
167+
168+ // Check internal function @_Z6main10v is not generated when LLVM passes are enabled
169+ // CHECK_CS_OPTNONE_PASS-NOT: define internal void @_Z6main10v
170+
171+ // Check internal function @_Z6main10v is not generated as it should be inlined
172+ // CHECK_OPT-NOT: define internal void @_Z6main10v
99173
100174// The unmangled version is not inlined, EntryAttr reflects that
101- // CHECK: Function Attrs: {{.*}}noinline
102- // CHECK: define void @main10() {{[a-z_ ]*}}[[EntryAttr]]
103- // Make sure function calls are inlined when AlwaysInline is run
104- // This only leaves calls to llvm. intrinsics
105- // INLINE-NOT: call {{[^@]*}} @{{[^l][^l][^v][^m][^\.]}}
175+ // CHECK_LIB_OPTNONE: Function Attrs: {{.*}}noinline
176+ // CHECK_LIB_OPTNONE: define void @main10() {{[a-z_ ]*}}[[EntryAttr]]
177+ // Make sure internal function is not inlined when optimization is disabled
178+ // CHECK_LIB_OPTNONE: call void @_Z6main10v
179+
180+ // CHECK_CS_OPTNONE_NOPASS: Function Attrs: {{.*}}noinline
181+ // CHECK_CS_OPTNONE_NOPASS: define void @main10() {{[a-z_ ]*}}[[EntryAttr]]
182+ // Make sure internal function is not inlined when optimization is disabled
183+ // CHECK_CS_OPTNONE_NOPASS: call void @_Z6main10v
184+
185+ // CHECK_CS_OPTNONE_PASS: Function Attrs: {{.*}}noinline
186+ // CHECK_CS_OPTNONE_PASS: define void @main10() {{[a-z_ ]*}}[[EntryAttr]]
187+ // Check internal function is inlined as optimization is enabled when LLVM passes
188+ // are enabled
189+ // CHECK_CS_OPTNONE_PASS: _Z6main10v.exit:
190+
191+ // CHECK_OPT: Function Attrs: {{.*}}noinline
192+ // CHECK_OPT: define void @main10() {{[a-z_ ]*}}[[EntryAttr]]
193+ // Make sure internal function is inlined as optimization is enabled
194+ // CHECK_OPT: _Z6main10v.exit:
106195// CHECK: ret void
107196
108197[numthreads (1 ,1 ,1 )]
@@ -111,6 +200,16 @@ void main10() {
111200 main (10 );
112201}
113202
114- // NOINLINE: attributes [[IntAttr]] = {{.*}} alwaysinline
115- // CHECK: attributes [[ExtAttr]] = {{.*}} alwaysinline
116- // CHECK: attributes [[EntryAttr]] = {{.*}} noinline
203+ // CHECK_LIB_OPTNONE: attributes [[ExtAttr]] = {{.*}} optnone
204+ // CHECK_LIB_OPTNONE: attributes [[ExportAttr]] = {{.*}} optnone
205+
206+ // CHECK_CS_OPTNONE_NOPASS: attributes [[ExtAttr]] ={{.*}} alwaysinline
207+ // CHECK_CS_OPTNONE_NOPASS: attributes [[EntryAttr]] = {{.*}} noinline
208+
209+ // CHECK_CS_OPTNONE_PASS: attributes [[ExtAttr]] ={{.*}} alwaysinline
210+ // CHECK_CS_OPTNONE_PASS: attributes [[EntryAttr]] = {{.*}} noinline
211+
212+ // CHECK_OPT: attributes [[SwapOptAttr]] ={{.*}} alwaysinline
213+ // CHECK_OPT: attributes [[BubOptAttr]] ={{.*}} alwaysinline
214+ // CHECK_OPT: attributes [[RemOptAttr]] ={{.*}} alwaysinline
215+ // CHECK_OPT: attributes [[EntryAttr]] ={{.*}} noinline
0 commit comments