1 // RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ \ 2 // RUN: -std=c++2a < %s | \ 3 // RUN: FileCheck --check-prefixes=CHECK,CHECK32 %s 4 5 // RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ \ 6 // RUN: -std=c++2a < %s | \ 7 // RUN: FileCheck --check-prefixes=CHECK,CHECK64 %s 8 9 namespace test1 { 10 struct Test1 { 11 Test1(); 12 ~Test1(); 13 } t1, t2; 14 } // namespace test1 15 16 namespace test2 { 17 int foo() { return 3; } 18 int x = foo(); 19 } // namespace test2 20 21 namespace test3 { 22 struct Test3 { 23 constexpr Test3() {}; 24 ~Test3() {}; 25 }; 26 27 constinit Test3 t; 28 } // namespace test3 29 30 namespace test4 { 31 struct Test4 { 32 Test4(); 33 ~Test4(); 34 }; 35 36 void f() { 37 static Test4 staticLocal; 38 } 39 } // namespace test4 40 41 // CHECK: @_ZGVZN5test41fEvE11staticLocal = internal global i64 0, align 8 42 // CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I__, i8* null }] 43 // CHECK: @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__D_a, i8* null }] 44 45 // CHECK: define internal void @__cxx_global_var_init() [[ATTR:#[0-9]+]] { 46 // CHECK: entry: 47 // CHECK: call void @_ZN5test15Test1C1Ev(%"struct.test1::Test1"* {{[^,]*}} @_ZN5test12t1E) 48 // CHECK: %0 = call i32 @atexit(void ()* @__dtor__ZN5test12t1E) 49 // CHECK: ret void 50 // CHECK: } 51 52 // CHECK: define internal void @__dtor__ZN5test12t1E() [[ATTR:#[0-9]+]] { 53 // CHECK: entry: 54 // CHECK: call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t1E) 55 // CHECK: ret void 56 // CHECK: } 57 58 // CHECK: declare i32 @atexit(void ()*) 59 60 // CHECK: define internal void @__finalize__ZN5test12t1E() [[ATTR:#[0-9]+]] { 61 // CHECK: entry: 62 // CHECK: %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t1E) 63 // CHECK: %needs_destruct = icmp eq i32 %0, 0 64 // CHECK: br i1 %needs_destruct, label %destruct.call, label %destruct.end 65 66 // CHECK: destruct.call: 67 // CHECK: call void @__dtor__ZN5test12t1E() 68 // CHECK: br label %destruct.end 69 70 // CHECK: destruct.end: 71 // CHECK: ret void 72 // CHECK: } 73 74 // CHECK: declare i32 @unatexit(void ()*) 75 76 // CHECK: define internal void @__cxx_global_var_init.1() [[ATTR:#[0-9]+]] { 77 // CHECK: entry: 78 // CHECK: call void @_ZN5test15Test1C1Ev(%"struct.test1::Test1"* {{[^,]*}} @_ZN5test12t2E) 79 // CHECK: %0 = call i32 @atexit(void ()* @__dtor__ZN5test12t2E) 80 // CHECK: ret void 81 // CHECK: } 82 83 // CHECK: define internal void @__dtor__ZN5test12t2E() [[ATTR:#[0-9]+]] { 84 // CHECK: entry: 85 // CHECK: call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t2E) 86 // CHECK: ret void 87 // CHECK: } 88 89 // CHECK: define internal void @__finalize__ZN5test12t2E() [[ATTR:#[0-9]+]] { 90 // CHECK: entry: 91 // CHECK: %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t2E) 92 // CHECK: %needs_destruct = icmp eq i32 %0, 0 93 // CHECK: br i1 %needs_destruct, label %destruct.call, label %destruct.end 94 95 // CHECK: destruct.call: 96 // CHECK: call void @__dtor__ZN5test12t2E() 97 // CHECK: br label %destruct.end 98 99 // CHECK: destruct.end: 100 // CHECK: ret void 101 // CHECK: } 102 103 // CHECK: define internal void @__cxx_global_var_init.2() [[ATTR:#[0-9]+]] { 104 // CHECK: entry: 105 // CHECK32: %call = call i32 @_ZN5test23fooEv() 106 // CHECK64: %call = call signext i32 @_ZN5test23fooEv() 107 // CHECK: store i32 %call, i32* @_ZN5test21xE 108 // CHECK: ret void 109 // CHECK: } 110 111 // CHECK: define internal void @__cxx_global_var_init.3() [[ATTR:#[0-9]+]] { 112 // CHECK: entry: 113 // CHECK: %0 = call i32 @atexit(void ()* @__dtor__ZN5test31tE) 114 // CHECK: ret void 115 // CHECK: } 116 117 // CHECK: define internal void @__dtor__ZN5test31tE() [[ATTR:#[0-9]+]] { 118 // CHECK: entry: 119 // CHECK: call void @_ZN5test35Test3D1Ev(%"struct.test3::Test3"* @_ZN5test31tE) 120 // CHECK: ret void 121 // CHECK: } 122 123 // CHECK: define internal void @__finalize__ZN5test31tE() [[ATTR:#[0-9]+]] { 124 // CHECK: entry: 125 // CHECK: %0 = call i32 @unatexit(void ()* @__dtor__ZN5test31tE) 126 // CHECK: %needs_destruct = icmp eq i32 %0, 0 127 // CHECK: br i1 %needs_destruct, label %destruct.call, label %destruct.end 128 129 // CHECK: destruct.call: 130 // CHECK: call void @__dtor__ZN5test31tE() 131 // CHECK: br label %destruct.end 132 133 // CHECK: destruct.end: 134 // CHECK: ret void 135 // CHECK: } 136 137 // CHECK: define void @_ZN5test41fEv() [[ATTR:#[0-9]+]] { 138 // CHECK: entry: 139 // CHECK: %0 = load atomic i8, i8* bitcast (i64* @_ZGVZN5test41fEvE11staticLocal to i8*) acquire, align 8 140 // CHECK: %guard.uninitialized = icmp eq i8 %0, 0 141 // CHECK: br i1 %guard.uninitialized, label %init.check, label %init.end 142 143 // CHECK: init.check: 144 // CHECK: %1 = call i32 @__cxa_guard_acquire(i64* @_ZGVZN5test41fEvE11staticLocal) 145 // CHECK: %tobool = icmp ne i32 %1, 0 146 // CHECK: br i1 %tobool, label %init, label %init.end 147 148 // CHECK: init: 149 // CHECK: call void @_ZN5test45Test4C1Ev(%"struct.test4::Test4"* {{[^,]*}} @_ZZN5test41fEvE11staticLocal) 150 // CHECK: %2 = call i32 @atexit(void ()* @__dtor__ZZN5test41fEvE11staticLocal) 151 // CHECK: call void @__cxa_guard_release(i64* @_ZGVZN5test41fEvE11staticLocal) 152 // CHECK: br label %init.end 153 154 // CHECK: init.end: 155 // CHECK: ret void 156 // CHECK: } 157 158 // CHECK: define internal void @__dtor__ZZN5test41fEvE11staticLocal() [[ATTR:#[0-9]+]] { 159 // CHECK: entry: 160 // CHECK: call void @_ZN5test45Test4D1Ev(%"struct.test4::Test4"* @_ZZN5test41fEvE11staticLocal) 161 // CHECK: ret void 162 // CHECK: } 163 164 // CHECK: define internal void @__finalize__ZZN5test41fEvE11staticLocal() [[ATTR:#[0-9]+]] { 165 // CHECK: entry: 166 // CHECK: %0 = call i32 @unatexit(void ()* @__dtor__ZZN5test41fEvE11staticLocal) 167 // CHECK: %needs_destruct = icmp eq i32 %0, 0 168 // CHECK: br i1 %needs_destruct, label %destruct.call, label %destruct.end 169 170 // CHECK: destruct.call: 171 // CHECK: call void @__dtor__ZZN5test41fEvE11staticLocal() 172 // CHECK: br label %destruct.end 173 174 // CHECK: destruct.end: 175 // CHECK: ret void 176 // CHECK: } 177 178 // CHECK: define internal void @_GLOBAL__sub_I__() [[ATTR:#[0-9]+]] { 179 // CHECK: entry: 180 // CHECK: call void @__cxx_global_var_init() 181 // CHECK: call void @__cxx_global_var_init.1() 182 // CHECK: call void @__cxx_global_var_init.2() 183 // CHECK: call void @__cxx_global_var_init.3() 184 // CHECK: ret void 185 // CHECK: } 186 187 // CHECK: define internal void @_GLOBAL__D_a() [[ATTR:#[0-9]+]] { 188 // CHECK: entry: 189 // CHECK: call void @__finalize__ZZN5test41fEvE11staticLocal() 190 // CHECK: call void @__finalize__ZN5test31tE() 191 // CHECK: call void @__finalize__ZN5test12t2E() 192 // CHECK: call void @__finalize__ZN5test12t1E() 193 // CHECK: ret void 194 // CHECK: } 195