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(int) {} 12 ~Test1() {} 13 }; 14 15 Test1 t0 = 2; 16 17 template <typename T> 18 Test1 t1 = 2; 19 20 inline Test1 t2 = 2; 21 22 void foo() { 23 (void)&t1<int>; 24 } 25 } // namespace test1 26 27 namespace test2 { 28 template <typename = void> 29 struct A { 30 A() {} 31 ~A() {} 32 static A instance; 33 }; 34 35 template <typename T> 36 A<T> A<T>::instance; 37 template A<> A<>::instance; 38 39 A<int> &bar() { 40 A<int> *a = new A<int>; 41 return *a; 42 } 43 template <> 44 A<int> A<int>::instance = bar(); 45 } // namespace test2 46 47 // CHECK: @_ZGVN5test12t2E = linkonce_odr global i64 0, align 8 48 // CHECK: @_ZGVN5test21AIvE8instanceE = weak_odr global i64 0, align 8 49 // CHECK: @_ZGVN5test12t1IiEE = linkonce_odr global i64 0, align 8 50 // CHECK: @llvm.global_ctors = appending global [4 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__cxx_global_var_init.1, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @__cxx_global_var_init.2, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @__cxx_global_var_init.4, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I__, i8* null }] 51 // CHECK: @llvm.global_dtors = appending global [4 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__finalize__ZN5test12t2E, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @__finalize__ZN5test21AIvE8instanceE, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @__finalize__ZN5test12t1IiEE, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__D_a, i8* null }] 52 53 // CHECK: define internal void @__cxx_global_var_init() [[ATTR:#[0-9]+]] { 54 // CHECK: entry: 55 // CHECK32: call void @_ZN5test15Test1C1Ei(%"struct.test1::Test1"* noundef{{[^,]*}} @_ZN5test12t0E, i32 noundef 2) 56 // CHECK64: call void @_ZN5test15Test1C1Ei(%"struct.test1::Test1"* noundef{{[^,]*}} @_ZN5test12t0E, i32 noundef signext 2) 57 // CHECK: %0 = call i32 @atexit(void ()* @__dtor__ZN5test12t0E) 58 // CHECK: ret void 59 // CHECK: } 60 61 // CHECK: define internal void @__dtor__ZN5test12t0E() [[ATTR:#[0-9]+]] { 62 // CHECK: entry: 63 // CHECK: call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t0E) 64 // CHECK: ret void 65 // CHECK: } 66 67 // CHECK: define internal void @__finalize__ZN5test12t0E() [[ATTR:#[0-9]+]] { 68 // CHECK: entry: 69 // CHECK: %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t0E) 70 // CHECK: %needs_destruct = icmp eq i32 %0, 0 71 // CHECK: br i1 %needs_destruct, label %destruct.call, label %destruct.end 72 73 // CHECK: destruct.call: 74 // CHECK: call void @__dtor__ZN5test12t0E() 75 // CHECK: br label %destruct.end 76 77 // CHECK: destruct.end: 78 // CHECK: ret void 79 // CHECK: } 80 81 // CHECK: define internal void @__cxx_global_var_init.1() [[ATTR:#[0-9]+]] { 82 // CHECK: entry: 83 // CHECK: %0 = load atomic i8, i8* bitcast (i64* @_ZGVN5test12t2E to i8*) acquire, align 8 84 // CHECK: %guard.uninitialized = icmp eq i8 %0, 0 85 // CHECK: br i1 %guard.uninitialized, label %init.check, label %init.end 86 87 // CHECK: init.check: 88 // CHECK: %1 = call i32 @__cxa_guard_acquire(i64* @_ZGVN5test12t2E) 89 // CHECK: %tobool = icmp ne i32 %1, 0 90 // CHECK: br i1 %tobool, label %init, label %init.end 91 92 // CHECK: init: 93 // CHECK32: call void @_ZN5test15Test1C1Ei(%"struct.test1::Test1"* noundef{{[^,]*}} @_ZN5test12t2E, i32 noundef 2) 94 // CHECK64: call void @_ZN5test15Test1C1Ei(%"struct.test1::Test1"* noundef{{[^,]*}} @_ZN5test12t2E, i32 noundef signext 2) 95 // CHECK: %2 = call i32 @atexit(void ()* @__dtor__ZN5test12t2E) 96 // CHECK: call void @__cxa_guard_release(i64* @_ZGVN5test12t2E) 97 // CHECK: br label %init.end 98 99 // CHECK: init.end: 100 // CHECK: ret void 101 // CHECK: } 102 103 // CHECK: define internal void @__dtor__ZN5test12t2E() [[ATTR:#[0-9]+]] { 104 // CHECK: entry: 105 // CHECK: call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t2E) 106 // CHECK: ret void 107 // CHECK: } 108 109 // CHECK: define internal void @__finalize__ZN5test12t2E() [[ATTR:#[0-9]+]] { 110 // CHECK: entry: 111 // CHECK: %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t2E) 112 // CHECK: %needs_destruct = icmp eq i32 %0, 0 113 // CHECK: br i1 %needs_destruct, label %destruct.call, label %destruct.end 114 115 // CHECK: destruct.call: 116 // CHECK: call void @__dtor__ZN5test12t2E() 117 // CHECK: br label %destruct.end 118 119 // CHECK: destruct.end: 120 // CHECK: ret void 121 // CHECK: } 122 123 // CHECK: define internal void @__cxx_global_var_init.2() [[ATTR:#[0-9]+]] { 124 // CHECK: entry: 125 // CHECK: %0 = load i8, i8* bitcast (i64* @_ZGVN5test21AIvE8instanceE to i8*), align 8 126 // CHECK: %guard.uninitialized = icmp eq i8 %0, 0 127 // CHECK: br i1 %guard.uninitialized, label %init.check, label %init.end 128 129 // CHECK: init.check: 130 // CHECK: call void @_ZN5test21AIvEC1Ev(%"struct.test2::A"* {{[^,]*}} @_ZN5test21AIvE8instanceE) 131 // CHECK: %1 = call i32 @atexit(void ()* @__dtor__ZN5test21AIvE8instanceE) 132 // CHECK: store i8 1, i8* bitcast (i64* @_ZGVN5test21AIvE8instanceE to i8*), align 8 133 // CHECK: br label %init.end 134 135 // CHECK: init.end: 136 // CHECK: ret void 137 // CHECK: } 138 139 // CHECK: define internal void @__dtor__ZN5test21AIvE8instanceE() [[ATTR:#[0-9]+]] { 140 // CHECK: entry: 141 // CHECK: call void @_ZN5test21AIvED1Ev(%"struct.test2::A"* @_ZN5test21AIvE8instanceE) 142 // CHECK: ret void 143 // CHECK: } 144 145 // CHECK: define internal void @__finalize__ZN5test21AIvE8instanceE() [[ATTR:#[0-9]+]] { 146 // CHECK: entry: 147 // CHECK: %0 = call i32 @unatexit(void ()* @__dtor__ZN5test21AIvE8instanceE) 148 // CHECK: %needs_destruct = icmp eq i32 %0, 0 149 // CHECK: br i1 %needs_destruct, label %destruct.call, label %destruct.end 150 151 // CHECK: destruct.call: 152 // CHECK: call void @__dtor__ZN5test21AIvE8instanceE() 153 // CHECK: br label %destruct.end 154 155 // CHECK: destruct.end: 156 // CHECK: ret void 157 // CHECK: } 158 159 // CHECK: define internal void @__cxx_global_var_init.3() [[ATTR:#[0-9]+]] { 160 // CHECK: entry: 161 // CHECK: %call = call noundef nonnull align 1 dereferenceable(1) %"struct.test2::A.0"* @_ZN5test23barEv() 162 // CHECK: %0 = call i32 @atexit(void ()* @__dtor__ZN5test21AIiE8instanceE) 163 // CHECK: ret void 164 // CHECK: } 165 166 // CHECK: define internal void @__dtor__ZN5test21AIiE8instanceE() [[ATTR:#[0-9]+]] { 167 // CHECK: entry: 168 // CHECK: call void @_ZN5test21AIiED1Ev(%"struct.test2::A.0"* @_ZN5test21AIiE8instanceE) 169 // CHECK: ret void 170 // CHECK: } 171 172 // CHECK: define internal void @__finalize__ZN5test21AIiE8instanceE() [[ATTR:#[0-9]+]] { 173 // CHECK: entry: 174 // CHECK: %0 = call i32 @unatexit(void ()* @__dtor__ZN5test21AIiE8instanceE) 175 // CHECK: %needs_destruct = icmp eq i32 %0, 0 176 // CHECK: br i1 %needs_destruct, label %destruct.call, label %destruct.end 177 178 // CHECK: destruct.call: 179 // CHECK: call void @__dtor__ZN5test21AIiE8instanceE() 180 // CHECK: br label %destruct.end 181 182 // CHECK: destruct.end: 183 // CHECK: ret void 184 // CHECK: } 185 186 // CHECK: define internal void @__cxx_global_var_init.4() [[ATTR:#[0-9]+]] { 187 // CHECK: entry: 188 // CHECK: %0 = load i8, i8* bitcast (i64* @_ZGVN5test12t1IiEE to i8*), align 8 189 // CHECK: %guard.uninitialized = icmp eq i8 %0, 0 190 // CHECK: br i1 %guard.uninitialized, label %init.check, label %init.end 191 192 // CHECK: init.check: 193 // CHECK32: call void @_ZN5test15Test1C1Ei(%"struct.test1::Test1"* {{[^,]*}} @_ZN5test12t1IiEE, i32 noundef 2) 194 // CHECK64: call void @_ZN5test15Test1C1Ei(%"struct.test1::Test1"* {{[^,]*}} @_ZN5test12t1IiEE, i32 noundef signext 2) 195 // CHECK: %1 = call i32 @atexit(void ()* @__dtor__ZN5test12t1IiEE) 196 // CHECK: store i8 1, i8* bitcast (i64* @_ZGVN5test12t1IiEE to i8*), align 8 197 // CHECK: br label %init.end 198 199 // CHECK: init.end: 200 // CHECK: ret void 201 // CHECK: } 202 203 // CHECK: define internal void @__dtor__ZN5test12t1IiEE() [[ATTR:#[0-9]+]] { 204 // CHECK: entry: 205 // CHECK: call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t1IiEE) 206 // CHECK: ret void 207 // CHECK: } 208 209 // CHECK: define internal void @__finalize__ZN5test12t1IiEE() [[ATTR:#[0-9]+]] { 210 // CHECK: entry: 211 // CHECK: %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t1IiEE) 212 // CHECK: %needs_destruct = icmp eq i32 %0, 0 213 // CHECK: br i1 %needs_destruct, label %destruct.call, label %destruct.end 214 215 // CHECK: destruct.call: 216 // CHECK: call void @__dtor__ZN5test12t1IiEE() 217 // CHECK: br label %destruct.end 218 219 // CHECK: destruct.end: 220 // CHECK: ret void 221 // CHECK: } 222 223 // CHECK: define internal void @_GLOBAL__sub_I__() [[ATTR:#[0-9]+]] { 224 // CHECK: entry: 225 // CHECK: call void @__cxx_global_var_init() 226 // CHECK: call void @__cxx_global_var_init.3() 227 // CHECK: ret void 228 // CHECK: } 229 230 // CHECK: define internal void @_GLOBAL__D_a() [[ATTR:#[0-9]+]] { 231 // CHECK: entry: 232 // CHECK: call void @__finalize__ZN5test21AIiE8instanceE() 233 // CHECK: call void @__finalize__ZN5test12t0E() 234 // CHECK: ret void 235 // CHECK: } 236