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 .
1+ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s --check-prefixes=CHECK,NOINLINE,OPT_ATTR
2+ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library %s -emit-llvm -O0 -o - | FileCheck %s --check-prefixes=CHECK,INLINE,OPT_ATTR
3+ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library %s -emit-llvm -O1 -o - | FileCheck %s --check-prefixes=CHECK,INLINE,NOOPT_ATTR
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,OPT_ATTR
6+ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute %s -emit-llvm -O1 -o - | FileCheck %s --check-prefixes=CHECK,INLINE,NOOPT_ATTR
7+
8+ // Tests that user functions will always be inlined .
99// This includes exported functions and mangled entry point implementation functions.
10+ // The unmangled entry functions must not be alwaysinlined.
1011
1112#define MAX 100
1213
1314float nums[MAX ];
1415
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-
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
3320// Swap the values of Buf at indices ix1 and ix2
3421void swap (unsigned Buf[MAX ], unsigned ix1, unsigned ix2) {
3522 float tmp = Buf[ix1];
3623 Buf[ix1] = Buf[ix2];
3724 Buf[ix2] = tmp;
3825}
3926
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-
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
5830// Inefficiently sort Buf in place
5931void BubbleSort (unsigned Buf[MAX ], unsigned size) {
6032 bool swapped = true ;
@@ -69,26 +41,12 @@ void BubbleSort(unsigned Buf[MAX], unsigned size) {
6941 }
7042}
7143
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]+]]
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
7548// Sort Buf and remove any duplicate values
7649// 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-
9250export
9351unsigned RemoveDupes (unsigned Buf[MAX ], unsigned size) {
9452 BubbleSort (Buf, size);
@@ -105,44 +63,20 @@ unsigned RemoveDupes(unsigned Buf[MAX], unsigned size) {
10563
10664RWBuffer <unsigned > Indices;
10765
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
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
12472
12573// The unmangled version is not inlined, EntryAttr reflects that
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-
74+ // OPT_ATTR: Function Attrs: {{.*}}optnone
75+ // NOOPT_ATTR-NOT: Function Attrs: {{.*}}optnone
76+ // CHECK: define void @main() {{[a-z_ ]*}}[[EntryAttr:\#[0-9]+]]
77+ // Make sure function calls are inlined when AlwaysInline is run
78+ // This only leaves calls to llvm. intrinsics
79+ // INLINE-NOT: call {{[^@]*}} @{{[^l][^l][^v][^m][^\.]}}
14680// CHECK: ret void
14781
14882[numthreads (1 ,1 ,1 )]
@@ -157,41 +91,20 @@ void main(unsigned int GI : SV_GroupIndex) {
15791 tmpIndices[i] = Indices[i];
15892}
15993
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
94+ // The mangled version of main only remains without inlining
95+ // because it has internal linkage from the start
96+ // Note main functions get the norecurse attrib, which IntAttr reflects
97+ // NOINLINE: Function Attrs: alwaysinline
98+ // NOINLINE: define internal void @_Z6main10v() [[IntAttr]]
99+ // NOINLINE: ret void
173100
174101// The unmangled version is not inlined, EntryAttr reflects that
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:
102+ // OPT_ATTR: Function Attrs: {{.*}}optnone
103+ // NOOPT_ATTR-NOT: Function Attrs: {{.*}}optnone
104+ // CHECK: define void @main10() {{[a-z_ ]*}}[[EntryAttr]]
105+ // Make sure function calls are inlined when AlwaysInline is run
106+ // This only leaves calls to llvm. intrinsics
107+ // INLINE-NOT: call {{[^@]*}} @{{[^l][^l][^v][^m][^\.]}}
195108// CHECK: ret void
196109
197110[numthreads (1 ,1 ,1 )]
@@ -200,16 +113,6 @@ void main10() {
200113 main (10 );
201114}
202115
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
116+ // NOINLINE: attributes [[IntAttr]] = {{.*}} alwaysinline
117+ // CHECK: attributes [[ExtAttr]] = {{.*}} alwaysinline
118+ // CHECK: attributes [[EntryAttr]] = {{.*}} noinline
0 commit comments