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