[clang][Driver] Support simplified triple versions for config files (#111387)
[llvm-project.git] / llvm / test / ThinLTO / X86 / memprof-icp.ll
blob3e2912da576f46006cb7de2a6b3b59f742c64941
1 ;; Test that cloning of an indirect call works. We should perform ICP and update
2 ;; promoted call to the correct clone.
4 ;; This was created from the following source code, for which both memprof and
5 ;; instrumentation PGO was collected and then applied, then the IR was reduced
6 ;; using llvm-reduce with the expected FileCheck input.
7 ;; TODO: Consider adding a sample PGO based test, however, that uses the same VP
8 ;; metadata and should behave the same.
10 ;; -- virtfunc.h: --
11 ;; void external(int *x);
13 ;; class B0 {
14 ;;  public:
15 ;;   virtual int bar(unsigned s);
16 ;; };
18 ;; class B : public B0 {
19 ;;  public:
20 ;;   int bar(unsigned s) override;
21 ;; };
23 ;; int foo(B0 &b, unsigned s);
25 ;; -- virtfunc.cc: --
26 ;; #include "virtfunc.h"
28 ;; int foo(B0 &b, unsigned s) {
29 ;;   return b.bar(s);
30 ;; }
32 ;; -- virtfunc_main.cc: --
33 ;; #include "virtfunc.h"
34 ;; #include <stdio.h>
35 ;; #include <unistd.h>
37 ;; int main() {
38 ;;   B b;
39 ;;   int x = foo(b, 1);
40 ;;   printf("%d\n", x);
41 ;;   int y = foo(b, 10);
42 ;;   printf("%d\n", y);
43 ;;   B0 b0;
44 ;;   x = foo(b0, 1);
45 ;;   printf("%d\n", x);
46 ;;   y = foo(b0, 10);
47 ;;   printf("%d\n", y);
48 ;;   return 0;
49 ;; }
51 ;; int B0::bar(unsigned s) {
52 ;;   int *x = new int;
53 ;;   sleep(s);
54 ;;   external(x);
55 ;;   delete x;
56 ;;   return 1;
57 ;; }
59 ;; int B::bar(unsigned s) {
60 ;;   int *x = new int;
61 ;;   sleep(s);
62 ;;   external(x);
63 ;;   delete x;
64 ;;   return 2;
65 ;; }
67 ;; -stats requires asserts
68 ; REQUIRES: asserts
70 ; RUN: split-file %s %t
72 ;; For now explicitly turn on this handling, which is off by default.
73 ; RUN: opt -thinlto-bc %t/main.ll -enable-memprof-indirect-call-support=true >%t/main.o
74 ; RUN: opt -thinlto-bc %t/foo.ll -enable-memprof-indirect-call-support=true >%t/foo.o
76 ;; Check that we get the synthesized callsite records. There should be 2, one
77 ;; for each profiled target in the VP metadata. They will have the same stackIds
78 ;; since the debug information for the callsite is the same.
79 ; RUN: llvm-dis %t/foo.o -o - | FileCheck %s --check-prefix=CALLSITES
80 ; CALLSITES: gv: (name: "_Z3fooR2B0j", {{.*}} callsites: ((callee: ^{{[0-9]+}}, clones: (0), stackIds: (16345663650247127235)), (callee: ^{{[0-9]+}}, clones: (0), stackIds: (16345663650247127235))
82 ;; Make sure that we don't get the synthesized callsite records if the
83 ;; -enable-memprof-indirect-call-support flag is false.
84 ; RUN: opt -thinlto-bc %t/foo.ll -enable-memprof-indirect-call-support=false >%t/foo.noicp.o
85 ; RUN: llvm-dis %t/foo.noicp.o -o - | FileCheck %s --implicit-check-not "stackIds: (16345663650247127235)"
86 ;; Currently this should be off by default as well.
87 ; RUN: opt -thinlto-bc %t/foo.ll -o - | llvm-dis -o - | FileCheck %s --implicit-check-not "stackIds: (16345663650247127235)"
89 ;; First perform in-process ThinLTO
90 ; RUN: llvm-lto2 run %t/main.o %t/foo.o -enable-memprof-context-disambiguation \
91 ; RUN:  -enable-memprof-indirect-call-support=true \
92 ; RUN:  -supports-hot-cold-new \
93 ; RUN:  -r=%t/foo.o,_Z3fooR2B0j,plx \
94 ; RUN:  -r=%t/foo.o,_ZN2B03barEj.abc,plx \
95 ; RUN:  -r=%t/foo.o,_Z3xyzR2B0j, \
96 ; RUN:  -r=%t/foo.o,_ZN2B03barEj, \
97 ; RUN:  -r=%t/foo.o,_ZN1B3barEj, \
98 ; RUN:  -r=%t/main.o,_Z3fooR2B0j, \
99 ; RUN:  -r=%t/main.o,_Znwm, \
100 ; RUN:  -r=%t/main.o,_ZdlPvm, \
101 ; RUN:  -r=%t/main.o,_Z8externalPi, \
102 ; RUN:  -r=%t/main.o,main,plx \
103 ; RUN:  -r=%t/main.o,_ZN2B03barEj,plx \
104 ; RUN:  -r=%t/main.o,_ZN1B3barEj,plx \
105 ; RUN:  -r=%t/main.o,_ZTV1B,plx \
106 ; RUN:  -r=%t/main.o,_ZTVN10__cxxabiv120__si_class_type_infoE,plx \
107 ; RUN:  -r=%t/main.o,_ZTS1B,plx \
108 ; RUN:  -r=%t/main.o,_ZTVN10__cxxabiv117__class_type_infoE,plx \
109 ; RUN:  -r=%t/main.o,_ZTS2B0,plx \
110 ; RUN:  -r=%t/main.o,_ZTI2B0,plx \
111 ; RUN:  -r=%t/main.o,_ZTI1B,plx \
112 ; RUN:  -r=%t/main.o,_ZTV2B0,plx \
113 ; RUN:  -thinlto-threads=1 \
114 ; RUN:  -memprof-verify-ccg -memprof-verify-nodes -stats \
115 ; RUN:  -pass-remarks=. -save-temps \
116 ; RUN:  -o %t.out 2>&1 | FileCheck %s --check-prefix=STATS \
117 ; RUN:  --check-prefix=STATS-BE --check-prefix=REMARKS-MAIN \
118 ; RUN:  --check-prefix=REMARKS-FOO --check-prefix=REMARKS-FOO-IMPORT
120 ; RUN: llvm-dis %t.out.2.4.opt.bc -o - | FileCheck %s --check-prefix=IR --check-prefix=IR-IMPORT
122 ;; Try again but with distributed ThinLTO
123 ; RUN: llvm-lto2 run %t/main.o %t/foo.o -enable-memprof-context-disambiguation \
124 ; RUN:  -supports-hot-cold-new \
125 ; RUN:  -thinlto-distributed-indexes \
126 ; RUN:  -r=%t/foo.o,_Z3fooR2B0j,plx \
127 ; RUN:  -r=%t/foo.o,_ZN2B03barEj.abc,plx \
128 ; RUN:  -r=%t/foo.o,_Z3xyzR2B0j, \
129 ; RUN:  -r=%t/foo.o,_ZN2B03barEj, \
130 ; RUN:  -r=%t/foo.o,_ZN1B3barEj, \
131 ; RUN:  -r=%t/main.o,_Z3fooR2B0j, \
132 ; RUN:  -r=%t/main.o,_Znwm, \
133 ; RUN:  -r=%t/main.o,_ZdlPvm, \
134 ; RUN:  -r=%t/main.o,_Z8externalPi, \
135 ; RUN:  -r=%t/main.o,main,plx \
136 ; RUN:  -r=%t/main.o,_ZN2B03barEj,plx \
137 ; RUN:  -r=%t/main.o,_ZN1B3barEj,plx \
138 ; RUN:  -r=%t/main.o,_ZTV1B,plx \
139 ; RUN:  -r=%t/main.o,_ZTVN10__cxxabiv120__si_class_type_infoE,plx \
140 ; RUN:  -r=%t/main.o,_ZTS1B,plx \
141 ; RUN:  -r=%t/main.o,_ZTVN10__cxxabiv117__class_type_infoE,plx \
142 ; RUN:  -r=%t/main.o,_ZTS2B0,plx \
143 ; RUN:  -r=%t/main.o,_ZTI2B0,plx \
144 ; RUN:  -r=%t/main.o,_ZTI1B,plx \
145 ; RUN:  -r=%t/main.o,_ZTV2B0,plx \
146 ; RUN:  -memprof-verify-ccg -memprof-verify-nodes -stats \
147 ; RUN:  -o %t.out 2>&1 | FileCheck %s --check-prefix=STATS
149 ;; Run ThinLTO backend
150 ; RUN: opt -import-all-index -passes=function-import,memprof-context-disambiguation,inline \
151 ; RUN:  -enable-memprof-indirect-call-support=true \
152 ; RUN:  -summary-file=%t/foo.o.thinlto.bc -memprof-import-summary=%t/foo.o.thinlto.bc \
153 ; RUN:  -enable-import-metadata -stats -pass-remarks=. \
154 ; RUN:  %t/foo.o -S 2>&1 | FileCheck %s --check-prefix=IR --check-prefix=IR-IMPORT \
155 ; RUN:  --check-prefix=STATS-BE-DISTRIB --check-prefix=REMARKS-FOO \
156 ; RUN:  --check-prefix=REMARKS-FOO-IMPORT
158 ;; Retry with the ICP-disabled object file, and make sure we disable it again
159 ;; so we don't look for the synthesized callsite records when applying imports.
160 ;; We should not get any cloning.
161 ; RUN: llvm-lto2 run %t/main.o %t/foo.noicp.o -enable-memprof-context-disambiguation \
162 ; RUN:  -enable-memprof-indirect-call-support=false \
163 ; RUN:  -supports-hot-cold-new \
164 ; RUN:  -r=%t/foo.noicp.o,_Z3fooR2B0j,plx \
165 ; RUN:  -r=%t/foo.noicp.o,_ZN2B03barEj.abc,plx \
166 ; RUN:  -r=%t/foo.noicp.o,_Z3xyzR2B0j, \
167 ; RUN:  -r=%t/foo.noicp.o,_ZN2B03barEj, \
168 ; RUN:  -r=%t/foo.noicp.o,_ZN1B3barEj, \
169 ; RUN:  -r=%t/main.o,_Z3fooR2B0j, \
170 ; RUN:  -r=%t/main.o,_Znwm, \
171 ; RUN:  -r=%t/main.o,_ZdlPvm, \
172 ; RUN:  -r=%t/main.o,_Z8externalPi, \
173 ; RUN:  -r=%t/main.o,main,plx \
174 ; RUN:  -r=%t/main.o,_ZN2B03barEj,plx \
175 ; RUN:  -r=%t/main.o,_ZN1B3barEj,plx \
176 ; RUN:  -r=%t/main.o,_ZTV1B,plx \
177 ; RUN:  -r=%t/main.o,_ZTVN10__cxxabiv120__si_class_type_infoE,plx \
178 ; RUN:  -r=%t/main.o,_ZTS1B,plx \
179 ; RUN:  -r=%t/main.o,_ZTVN10__cxxabiv117__class_type_infoE,plx \
180 ; RUN:  -r=%t/main.o,_ZTS2B0,plx \
181 ; RUN:  -r=%t/main.o,_ZTI2B0,plx \
182 ; RUN:  -r=%t/main.o,_ZTI1B,plx \
183 ; RUN:  -r=%t/main.o,_ZTV2B0,plx \
184 ; RUN:  -thinlto-threads=1 \
185 ; RUN:  -memprof-verify-ccg -memprof-verify-nodes \
186 ; RUN:  -pass-remarks=. -save-temps \
187 ; RUN:  -o %t.noicp.out 2>&1 | FileCheck %s --implicit-check-not "created clone"
189 ;; Verify that we did not do any cloning of the function with the indirect call
190 ;; when memprof ICP is off. However, we should still have removed the callsite
191 ;; metadata.
192 ; RUN: llvm-dis %t.noicp.out.2.4.opt.bc -o - | FileCheck %s --implicit-check-not "_Z3fooR2B0j.memprof" --implicit-check-not "!callsite"
194 ;; Run in-process ThinLTO again, but with importing disabled by setting the
195 ;; instruction limit to 0. Ensure that the existing declarations of B::bar
196 ;; and B0::bar are sufficient to allow for the promotion and cloning.
197 ; RUN: llvm-lto2 run %t/main.o %t/foo.o -enable-memprof-context-disambiguation \
198 ; RUN:  -import-instr-limit=0 \
199 ; RUN:  -enable-memprof-indirect-call-support=true \
200 ; RUN:  -supports-hot-cold-new \
201 ; RUN:  -r=%t/foo.o,_Z3fooR2B0j,plx \
202 ; RUN:  -r=%t/foo.o,_ZN2B03barEj.abc,plx \
203 ; RUN:  -r=%t/foo.o,_Z3xyzR2B0j, \
204 ; RUN:  -r=%t/foo.o,_ZN2B03barEj, \
205 ; RUN:  -r=%t/foo.o,_ZN1B3barEj, \
206 ; RUN:  -r=%t/main.o,_Z3fooR2B0j, \
207 ; RUN:  -r=%t/main.o,_Znwm, \
208 ; RUN:  -r=%t/main.o,_ZdlPvm, \
209 ; RUN:  -r=%t/main.o,_Z8externalPi, \
210 ; RUN:  -r=%t/main.o,main,plx \
211 ; RUN:  -r=%t/main.o,_ZN2B03barEj,plx \
212 ; RUN:  -r=%t/main.o,_ZN1B3barEj,plx \
213 ; RUN:  -r=%t/main.o,_ZTV1B,plx \
214 ; RUN:  -r=%t/main.o,_ZTVN10__cxxabiv120__si_class_type_infoE,plx \
215 ; RUN:  -r=%t/main.o,_ZTS1B,plx \
216 ; RUN:  -r=%t/main.o,_ZTVN10__cxxabiv117__class_type_infoE,plx \
217 ; RUN:  -r=%t/main.o,_ZTS2B0,plx \
218 ; RUN:  -r=%t/main.o,_ZTI2B0,plx \
219 ; RUN:  -r=%t/main.o,_ZTI1B,plx \
220 ; RUN:  -r=%t/main.o,_ZTV2B0,plx \
221 ; RUN:  -thinlto-threads=1 \
222 ; RUN:  -memprof-verify-ccg -memprof-verify-nodes -stats \
223 ; RUN:  -pass-remarks=. -save-temps \
224 ; RUN:  -o %t.out 2>&1 | FileCheck %s --check-prefix=STATS \
225 ; RUN:  --check-prefix=STATS-BE-NOIMPORT --check-prefix=REMARKS-MAIN \
226 ; RUN:  --check-prefix=REMARKS-FOO
228 ; RUN: llvm-dis %t.out.2.4.opt.bc -o - | FileCheck %s --check-prefix=IR --check-prefix=IR-NOIMPORT
230 ;; Run it gain but with -memprof-require-definition-for-promotion, and confirm
231 ;; that no promotions occur.
232 ; RUN: llvm-lto2 run %t/main.o %t/foo.o -enable-memprof-context-disambiguation \
233 ; RUN:  -import-instr-limit=0 \
234 ; RUN:  -memprof-require-definition-for-promotion \
235 ; RUN:  -enable-memprof-indirect-call-support=true \
236 ; RUN:  -supports-hot-cold-new \
237 ; RUN:  -r=%t/foo.o,_Z3fooR2B0j,plx \
238 ; RUN:  -r=%t/foo.o,_ZN2B03barEj.abc,plx \
239 ; RUN:  -r=%t/foo.o,_Z3xyzR2B0j, \
240 ; RUN:  -r=%t/foo.o,_ZN2B03barEj, \
241 ; RUN:  -r=%t/foo.o,_ZN1B3barEj, \
242 ; RUN:  -r=%t/main.o,_Z3fooR2B0j, \
243 ; RUN:  -r=%t/main.o,_Znwm, \
244 ; RUN:  -r=%t/main.o,_ZdlPvm, \
245 ; RUN:  -r=%t/main.o,_Z8externalPi, \
246 ; RUN:  -r=%t/main.o,main,plx \
247 ; RUN:  -r=%t/main.o,_ZN2B03barEj,plx \
248 ; RUN:  -r=%t/main.o,_ZN1B3barEj,plx \
249 ; RUN:  -r=%t/main.o,_ZTV1B,plx \
250 ; RUN:  -r=%t/main.o,_ZTVN10__cxxabiv120__si_class_type_infoE,plx \
251 ; RUN:  -r=%t/main.o,_ZTS1B,plx \
252 ; RUN:  -r=%t/main.o,_ZTVN10__cxxabiv117__class_type_infoE,plx \
253 ; RUN:  -r=%t/main.o,_ZTS2B0,plx \
254 ; RUN:  -r=%t/main.o,_ZTI2B0,plx \
255 ; RUN:  -r=%t/main.o,_ZTI1B,plx \
256 ; RUN:  -r=%t/main.o,_ZTV2B0,plx \
257 ; RUN:  -thinlto-threads=1 \
258 ; RUN:  -memprof-verify-ccg -memprof-verify-nodes \
259 ; RUN:  -pass-remarks=. \
260 ; RUN:  -o %t.out 2>&1 | FileCheck %s --implicit-check-not Promote
262 ; REMARKS-MAIN: call in clone main assigned to call function clone _Z3fooR2B0j.memprof.1
263 ; REMARKS-MAIN: call in clone main assigned to call function clone _Z3fooR2B0j.memprof.1
264 ; REMARKS-MAIN: created clone _ZN2B03barEj.memprof.1
265 ; REMARKS-MAIN: call in clone _ZN2B03barEj marked with memprof allocation attribute notcold
266 ; REMARKS-MAIN: call in clone _ZN2B03barEj.memprof.1 marked with memprof allocation attribute cold
267 ; REMARKS-MAIN: call in clone _ZN2B03barEj marked with memprof allocation attribute notcold
268 ; REMARKS-MAIN: call in clone _ZN2B03barEj.memprof.1 marked with memprof allocation attribute cold
269 ; REMARKS-MAIN: created clone _ZN1B3barEj.memprof.1
270 ; REMARKS-MAIN: call in clone _ZN1B3barEj marked with memprof allocation attribute notcold
271 ; REMARKS-MAIN: call in clone _ZN1B3barEj.memprof.1 marked with memprof allocation attribute cold
272 ; REMARKS-MAIN: call in clone _ZN1B3barEj marked with memprof allocation attribute notcold
273 ; REMARKS-MAIN: call in clone _ZN1B3barEj.memprof.1 marked with memprof allocation attribute cold
274 ; REMARKS-FOO: created clone _Z3fooR2B0j.memprof.1
275 ;; In each version of foo we should have promoted the indirect call to two conditional
276 ;; direct calls, one to B::bar and one to B0::bar. The cloned version of foo should call
277 ;; the cloned versions of bar for both promotions.
278 ; REMARKS-FOO: Promote indirect call to _ZN1B3barEj with count 2 out of 4
279 ; REMARKS-FOO: call in clone _Z3fooR2B0j promoted and assigned to call function clone _ZN1B3barEj
280 ; REMARKS-FOO: Promote indirect call to _ZN1B3barEj with count 2 out of 4
281 ; REMARKS-FOO: call in clone _Z3fooR2B0j.memprof.1 promoted and assigned to call function clone _ZN1B3barEj.memprof.1
282 ; REMARKS-FOO: Promote indirect call to _ZN2B03barEj with count 2 out of 2
283 ; REMARKS-FOO: call in clone _Z3fooR2B0j promoted and assigned to call function clone _ZN2B03barEj
284 ; REMARKS-FOO: Promote indirect call to _ZN2B03barEj with count 2 out of 2
285 ; REMARKS-FOO: call in clone _Z3fooR2B0j.memprof.1 promoted and assigned to call function clone _ZN2B03barEj.memprof.1
286 ; REMARKS-FOO-IMPORT: created clone _ZN2B03barEj.memprof.1
287 ; REMARKS-FOO-IMPORT: call in clone _ZN2B03barEj marked with memprof allocation attribute notcold
288 ; REMARKS-FOO-IMPORT: call in clone _ZN2B03barEj.memprof.1 marked with memprof allocation attribute cold
289 ; REMARKS-FOO-IMPORT: created clone _ZN1B3barEj.memprof.1
290 ; REMARKS-FOO-IMPORT: call in clone _ZN1B3barEj marked with memprof allocation attribute notcold
291 ; REMARKS-FOO-IMPORT: call in clone _ZN1B3barEj.memprof.1 marked with memprof allocation attribute cold
293 ; STATS: 4 memprof-context-disambiguation - Number of cold static allocations (possibly cloned) during whole program analysis
294 ; STATS-BE: 8 memprof-context-disambiguation - Number of cold static allocations (possibly cloned) during ThinLTO backend
295 ; STATS-BE-NOIMPORT: 4 memprof-context-disambiguation - Number of cold static allocations (possibly cloned) during ThinLTO backend
296 ; STATS: 4 memprof-context-disambiguation - Number of not cold static allocations (possibly cloned) during whole program analysis
297 ; STATS-BE: 8 memprof-context-disambiguation - Number of not cold static allocations (possibly cloned) during ThinLTO backend
298 ; STATS-BE-NOIMPORT: 4 memprof-context-disambiguation - Number of not cold static allocations (possibly cloned) during ThinLTO backend
299 ; STATS: 3 memprof-context-disambiguation - Number of function clones created during whole program analysis
300 ; STATS-BE: 5 memprof-context-disambiguation - Number of function clones created during ThinLTO backend
301 ; STATS-BE-NOIMPORT: 3 memprof-context-disambiguation - Number of function clones created during ThinLTO backend
303 ; IR-NOIMPORT: foo
304 ; IR: define {{.*}} @_Z3fooR2B0j(
305 ; IR:   %[[R1:[0-9]+]] = icmp eq ptr %0, @_ZN1B3barEj
306 ; IR:   br i1 %[[R1]], label %if.true.direct_targ, label %if.false.orig_indirect
307 ; IR: if.true.direct_targ:
308 ; IR-IMPORT:   call {{.*}} @_Znwm(i64 noundef 4) #[[NOTCOLD:[0-9]+]]
309 ; IR-NOIMPORT: call {{.*}} @_ZN1B3barEj(
310 ; IR: if.false.orig_indirect:
311 ; IR:   %[[R2:[0-9]+]] = icmp eq ptr %0, @_ZN2B03barEj
312 ; IR:   br i1 %[[R2]], label %if.true.direct_targ1, label %if.false.orig_indirect2
313 ; IR: if.true.direct_targ1:
314 ; IR-IMPORT:   call {{.*}} @_Znwm(i64 noundef 4) #[[NOTCOLD]]
315 ; IR-NOIMPORT: call {{.*}} @_ZN2B03barEj(
316 ; IR: if.false.orig_indirect2:
317 ; IR:   call {{.*}} %0
319 ; IR: define {{.*}} @_Z3fooR2B0j.memprof.1(
320 ;; We should still compare against the original versions of bar since that is
321 ;; what is in the vtable. However, we should have called the cloned versions
322 ;; that perform cold allocations, which were subsequently inlined.
323 ; IR:   %[[R3:[0-9]+]] = icmp eq ptr %0, @_ZN1B3barEj
324 ; IR:   br i1 %[[R3]], label %if.true.direct_targ, label %if.false.orig_indirect
325 ; IR: if.true.direct_targ:
326 ; IR-IMPORT:   call {{.*}} @_Znwm(i64 noundef 4) #[[COLD:[0-9]+]]
327 ; IR-NOIMPORT: call {{.*}} @_ZN1B3barEj.memprof.1(
328 ; IR: if.false.orig_indirect:
329 ; IR:   %[[R4:[0-9]+]] = icmp eq ptr %0, @_ZN2B03barEj
330 ; IR:   br i1 %[[R4]], label %if.true.direct_targ1, label %if.false.orig_indirect2
331 ; IR: if.true.direct_targ1:
332 ; IR-IMPORT:   call {{.*}} @_Znwm(i64 noundef 4) #[[COLD]]
333 ; IR-NOIMPORT: call {{.*}} @_ZN2B03barEj.memprof.1(
334 ; IR: if.false.orig_indirect2:
335 ; IR:   call {{.*}} %0
337 ; IR-IMPORT: attributes #[[NOTCOLD]] = {{.*}} "memprof"="notcold"
338 ; IR-IMPORT: attributes #[[COLD]] = {{.*}} "memprof"="cold"
340 ; STATS-BE-DISTRIB: 4 memprof-context-disambiguation - Number of cold static allocations (possibly cloned) during ThinLTO backend
341 ; STATS-BE-DISTRIB: 4 memprof-context-disambiguation - Number of not cold static allocations (possibly cloned) during ThinLTO backend
342 ; STATS-BE-DISTRIB: 3 memprof-context-disambiguation - Number of function clones created during ThinLTO backend
344 ;--- foo.ll
345 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
346 target triple = "x86_64-unknown-linux-gnu"
348 declare i32 @_Z3xyzR2B0j(ptr %b)
350 ;; Add a function that has the same name as one of the indirect callees, but
351 ;; with a suffix, to make sure we don't incorrectly pick the wrong one as the
352 ;; promoted target (which happens if we attempt to canonicalize the names
353 ;; when building the ICP symtab).
354 define i32 @_ZN2B03barEj.abc(ptr %this, i32 %s) {
355   ret i32 0
358 declare i32 @_ZN2B03barEj(ptr %this, i32 %s)
359 declare i32 @_ZN1B3barEj(ptr %this, i32 %s)
361 define i32 @_Z3fooR2B0j(ptr %b) {
362 entry:
363   %0 = load ptr, ptr %b, align 8
364   %call = tail call i32 %0(ptr null, i32 0), !prof !0, !callsite !1
365   ;; Add a dummy call to ensure that we have some callsite metadata,
366   ;; which triggers callsite record checking in the ThinLTO backend
367   ;; even with -enable-memprof-indirect-call-support=false.
368   %call2 = call i32 @_Z3xyzR2B0j(ptr null, i32 0), !callsite !2
369   ret i32 0
372 !0 = !{!"VP", i32 0, i64 4, i64 4445083295448962937, i64 2, i64 -2718743882639408571, i64 2}
373 !1 = !{i64 -2101080423462424381}
374 !2 = !{i64 1234}
376 ;--- main.ll
377 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
378 target triple = "x86_64-unknown-linux-gnu"
380 @_ZTV1B = external constant { [3 x ptr] }
381 @_ZTVN10__cxxabiv120__si_class_type_infoE = external global [0 x ptr]
382 @_ZTS1B = external constant [3 x i8]
383 @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr]
384 @_ZTS2B0 = external constant [4 x i8]
385 @_ZTI2B0 = external constant { ptr, ptr }
386 @_ZTI1B = external constant { ptr, ptr, ptr }
387 @_ZTV2B0 = external constant { [3 x ptr] }
389 define i32 @main() !prof !29 {
390 entry:
391   %call2 = call i32 @_Z3fooR2B0j(ptr null, i32 0), !callsite !30
392   %call4 = call i32 @_Z3fooR2B0j(ptr null, i32 0), !callsite !31
393   %call6 = call i32 @_Z3fooR2B0j(ptr null, i32 0), !callsite !32
394   ret i32 0
397 declare i32 @_Z3fooR2B0j(ptr, i32)
399 define i32 @_ZN2B03barEj(ptr %this, i32 %s) {
400 entry:
401   %call = tail call ptr @_Znwm(i64 noundef 4) #0, !memprof !33, !callsite !38
402   ;; Second allocation in this function, to ensure that indirect edges to the
403   ;; same callee are partitioned correctly.
404   %call2 = tail call ptr @_Znwm(i64 noundef 4) #0, !memprof !45, !callsite !50
405   store volatile i32 0, ptr %call, align 4
406   ret i32 0
409 declare ptr @_Znwm(i64)
411 declare void @_Z8externalPi()
413 declare void @_ZdlPvm()
415 define i32 @_ZN1B3barEj(ptr %this, i32 %s) {
416 entry:
417   %call = tail call ptr @_Znwm(i64 noundef 4) #0, !memprof !39, !callsite !44
418   ;; Second allocation in this function, to ensure that indirect edges to the
419   ;; same callee are partitioned correctly.
420   %call2 = tail call ptr @_Znwm(i64 noundef 4) #0, !memprof !51, !callsite !56
421   store volatile i32 0, ptr %call, align 4
422   ret i32 0
425 ; uselistorder directives
426 uselistorder ptr @_Z3fooR2B0j, { 2, 1, 0 }
428 attributes #0 = { builtin allocsize(0) }
430 !llvm.module.flags = !{!0}
432 !0 = !{i32 1, !"ProfileSummary", !1}
433 !1 = !{!2, !3, !4, !5, !6, !7, !8, !9, !10, !11}
434 !2 = !{!"ProfileFormat", !"InstrProf"}
435 !3 = !{!"TotalCount", i64 13}
436 !4 = !{!"MaxCount", i64 4}
437 !5 = !{!"MaxInternalCount", i64 0}
438 !6 = !{!"MaxFunctionCount", i64 4}
439 !7 = !{!"NumCounts", i64 5}
440 !8 = !{!"NumFunctions", i64 5}
441 !9 = !{!"IsPartialProfile", i64 0}
442 !10 = !{!"PartialProfileRatio", double 0.000000e+00}
443 !11 = !{!"DetailedSummary", !12}
444 !12 = !{!13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28}
445 !13 = !{i32 10000, i64 0, i32 0}
446 !14 = !{i32 100000, i64 4, i32 2}
447 !15 = !{i32 200000, i64 4, i32 2}
448 !16 = !{i32 300000, i64 4, i32 2}
449 !17 = !{i32 400000, i64 4, i32 2}
450 !18 = !{i32 500000, i64 4, i32 2}
451 !19 = !{i32 600000, i64 4, i32 2}
452 !20 = !{i32 700000, i64 2, i32 4}
453 !21 = !{i32 800000, i64 2, i32 4}
454 !22 = !{i32 900000, i64 2, i32 4}
455 !23 = !{i32 950000, i64 2, i32 4}
456 !24 = !{i32 990000, i64 2, i32 4}
457 !25 = !{i32 999000, i64 2, i32 4}
458 !26 = !{i32 999900, i64 2, i32 4}
459 !27 = !{i32 999990, i64 2, i32 4}
460 !28 = !{i32 999999, i64 2, i32 4}
461 !29 = !{!"function_entry_count", i64 1}
462 !30 = !{i64 -6490791336773930154}
463 !31 = !{i64 5188446645037944434}
464 !32 = !{i64 5583420417449503557}
465 !33 = !{!34, !36}
466 !34 = !{!35, !"notcold"}
467 !35 = !{i64 -852997907418798798, i64 -2101080423462424381, i64 5188446645037944434}
468 !36 = !{!37, !"cold"}
469 !37 = !{i64 -852997907418798798, i64 -2101080423462424381, i64 5583420417449503557}
470 !38 = !{i64 -852997907418798798}
471 !39 = !{!40, !42}
472 !40 = !{!41, !"notcold"}
473 !41 = !{i64 4457553070050523782, i64 -2101080423462424381, i64 132626519179914298}
474 !42 = !{!43, !"cold"}
475 !43 = !{i64 4457553070050523782, i64 -2101080423462424381, i64 -6490791336773930154}
476 !44 = !{i64 4457553070050523782}
477 !45 = !{!46, !48}
478 !46 = !{!47, !"notcold"}
479 !47 = !{i64 456, i64 -2101080423462424381, i64 5188446645037944434}
480 !48 = !{!49, !"cold"}
481 !49 = !{i64 456, i64 -2101080423462424381, i64 5583420417449503557}
482 !50 = !{i64 456}
483 !51 = !{!52, !54}
484 !52 = !{!53, !"notcold"}
485 !53 = !{i64 789, i64 -2101080423462424381, i64 132626519179914298}
486 !54 = !{!55, !"cold"}
487 !55 = !{i64 789, i64 -2101080423462424381, i64 -6490791336773930154}
488 !56 = !{i64 789}