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