1// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -emit-llvm -disable-llvm-passes %s -o - | FileCheck %s --check-prefixes=CS,NOINLINE,CHECK 2// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes %s -o - | FileCheck %s --check-prefixes=LIB,NOINLINE,CHECK 3// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -emit-llvm -O0 %s -o - | FileCheck %s --check-prefixes=INLINE,CHECK 4// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -O0 %s -o - | FileCheck %s --check-prefixes=INLINE,CHECK 5 6// Tests that constructors and destructors are appropriately generated for globals 7// and that their calls are inlined when AlwaysInline is run 8// but global variables are retained for the library profiles 9 10// Make sure global variable for ctors/dtors exist for lib profile. 11// LIB:@llvm.global_ctors 12// LIB:@llvm.global_dtors 13// Make sure global variable for ctors/dtors removed for compute profile. 14// CS-NOT:@llvm.global_ctors 15// CS-NOT:@llvm.global_dtors 16 17struct Tail { 18 Tail() { 19 add(1); 20 } 21 22 ~Tail() { 23 add(-1); 24 } 25 26 void add(int V) { 27 static int Count = 0; 28 Count += V; 29 } 30}; 31 32struct Pupper { 33 static int Count; 34 35 Pupper() { 36 Count += 1; // :) 37 } 38 39 ~Pupper() { 40 Count -= 1; // :( 41 } 42} GlobalPup; 43 44void Wag() { 45 static Tail T; 46 T.add(0); 47} 48 49int Pupper::Count = 0; 50 51[numthreads(1,1,1)] 52[shader("compute")] 53void main(unsigned GI : SV_GroupIndex) { 54 Wag(); 55} 56 57// CHECK: define void @main() 58// CHECK-NEXT: entry: 59// Verify destructor is emitted 60// NOINLINE-NEXT: call void @_GLOBAL__sub_I_GlobalDestructors.hlsl() 61// NOINLINE-NEXT: %0 = call i32 @llvm.dx.flattened.thread.id.in.group() 62// NOINLINE-NEXT: call void @_Z4mainj(i32 %0) 63// NOINLINE-NEXT: call void @_GLOBAL__D_a() 64// NOINLINE-NEXT: ret void 65// Verify inlining leaves only calls to "llvm." intrinsics 66// INLINE-NOT: call {{[^@]*}} @{{[^l][^l][^v][^m][^\.]}} 67// INLINE: ret void 68 69// This is really just a sanity check I needed for myself to verify that 70// function scope static variables also get destroyed properly. 71 72// NOINLINE: define internal void @_GLOBAL__D_a() [[IntAttr:\#[0-9]+]] 73// NOINLINE-NEXT: entry: 74// NOINLINE-NEXT: call void @_ZN4TailD1Ev(ptr @_ZZ3WagvE1T) 75// NOINLINE-NEXT: call void @_ZN6PupperD1Ev(ptr @GlobalPup) 76// NOINLINE-NEXT: ret void 77 78// NOINLINE: attributes [[IntAttr]] = {{.*}} alwaysinline 79