xref: /llvm-project/llvm/test/ThinLTO/X86/memprof-icp.ll (revision 3654183afb283c9515a482f07fde730dd458a883)
1;; Test that cloning of an indirect call works. We should perform ICP and update
2;; promoted call to the correct clone.
3
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.
9
10;; -- virtfunc.h: --
11;; void external(int *x);
12;;
13;; class B0 {
14;;  public:
15;;   virtual int bar(unsigned s);
16;; };
17;;
18;; class B : public B0 {
19;;  public:
20;;   int bar(unsigned s) override;
21;; };
22;;
23;; int foo(B0 &b, unsigned s);
24
25;; -- virtfunc.cc: --
26;; #include "virtfunc.h"
27;;
28;; int foo(B0 &b, unsigned s) {
29;;   return b.bar(s);
30;; }
31
32;; -- virtfunc_main.cc: --
33;; #include "virtfunc.h"
34;; #include <stdio.h>
35;; #include <unistd.h>
36;;
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;; }
50;;
51;; int B0::bar(unsigned s) {
52;;   int *x = new int;
53;;   sleep(s);
54;;   external(x);
55;;   delete x;
56;;   return 1;
57;; }
58;;
59;; int B::bar(unsigned s) {
60;;   int *x = new int;
61;;   sleep(s);
62;;   external(x);
63;;   delete x;
64;;   return 2;
65;; }
66
67;; -stats requires asserts
68; REQUIRES: asserts
69
70; RUN: split-file %s %t
71
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
75
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))
81
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)"
88
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
119
120; RUN: llvm-dis %t.out.2.4.opt.bc -o - | FileCheck %s --check-prefix=IR --check-prefix=IR-IMPORT
121
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
148
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
157
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"
188
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"
193
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
227
228; RUN: llvm-dis %t.out.2.4.opt.bc -o - | FileCheck %s --check-prefix=IR --check-prefix=IR-NOIMPORT
229
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
261
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
292
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
302
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
318
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
336
337; IR-IMPORT: attributes #[[NOTCOLD]] = {{.*}} "memprof"="notcold"
338; IR-IMPORT: attributes #[[COLD]] = {{.*}} "memprof"="cold"
339
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
343
344;--- foo.ll
345target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
346target triple = "x86_64-unknown-linux-gnu"
347
348declare i32 @_Z3xyzR2B0j(ptr %b)
349
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).
354define i32 @_ZN2B03barEj.abc(ptr %this, i32 %s) {
355  ret i32 0
356}
357
358declare i32 @_ZN2B03barEj(ptr %this, i32 %s)
359declare i32 @_ZN1B3barEj(ptr %this, i32 %s)
360
361define i32 @_Z3fooR2B0j(ptr %b) {
362entry:
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
370}
371
372!0 = !{!"VP", i32 0, i64 4, i64 4445083295448962937, i64 2, i64 -2718743882639408571, i64 2}
373!1 = !{i64 -2101080423462424381}
374!2 = !{i64 1234}
375
376;--- main.ll
377target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
378target triple = "x86_64-unknown-linux-gnu"
379
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] }
388
389define i32 @main() !prof !29 {
390entry:
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
395}
396
397declare i32 @_Z3fooR2B0j(ptr, i32)
398
399define i32 @_ZN2B03barEj(ptr %this, i32 %s) {
400entry:
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
407}
408
409declare ptr @_Znwm(i64)
410
411declare void @_Z8externalPi()
412
413declare void @_ZdlPvm()
414
415define i32 @_ZN1B3barEj(ptr %this, i32 %s) {
416entry:
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
423}
424
425; uselistorder directives
426uselistorder ptr @_Z3fooR2B0j, { 2, 1, 0 }
427
428attributes #0 = { builtin allocsize(0) }
429
430!llvm.module.flags = !{!0}
431
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}
489