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
8 // Tests that user functions will always be inlined.
9 // This includes exported functions and mangled entry point implementation functions.
10 // The unmangled entry functions must not be alwaysinlined.
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]+]]
20 // Swap the values of Buf at indices ix1 and ix2
21 void swap(unsigned Buf[MAX], unsigned ix1, unsigned ix2) {
27 // NOINLINE: Function Attrs: alwaysinline
28 // NOINLINE: define void @_Z10BubbleSortA100_jj(ptr noundef byval([100 x i32]) align 4 %Buf, i32 noundef %size) [[IntAttr]]
30 // Inefficiently sort Buf in place
31 void BubbleSort(unsigned Buf[MAX], unsigned size) {
35 for (unsigned i = 1; i < size; i++) {
36 if (Buf[i] < Buf[i-1]) {
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]+]]
48 // Sort Buf and remove any duplicate values
49 // returns the number of values left
51 unsigned RemoveDupes(unsigned Buf[MAX], unsigned size) {
52 BubbleSort(Buf, size);
53 unsigned insertPt = 0;
54 for (unsigned i = 1; i < size; i++) {
55 if (Buf[i] == Buf[i-1])
58 Buf[insertPt] = Buf[i];
64 RWBuffer<unsigned> Indices;
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]]
73 // 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][^\.]}}
83 void main(unsigned int GI : SV_GroupIndex) {
84 unsigned tmpIndices[MAX];
86 for (unsigned i = 1; i < GI; i++)
87 tmpIndices[i] = Indices[i];
88 RemoveDupes(tmpIndices, GI);
89 for (unsigned i = 1; i < GI; i++)
90 tmpIndices[i] = Indices[i];
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]]
100 // 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][^\.]}}
114 // NOINLINE: attributes [[IntAttr]] = {{.*}} alwaysinline
115 // CHECK: attributes [[ExtAttr]] = {{.*}} alwaysinline
116 // CHECK: attributes [[EntryAttr]] = {{.*}} noinline