1; Test the profile summary for context sensitive PGO (CSPGO)
2
3; RUN: llvm-profdata merge %S/Inputs/cspgo.proftext -o %t.profdata
4; RUN: opt < %s -O2 -disable-preinline -pgo-kind=pgo-instr-use-pipeline -profile-file=%t.profdata -S | FileCheck %s --check-prefix=PGOSUMMARY
5; RUN: opt < %s -O2 -disable-preinline -pgo-kind=pgo-instr-use-pipeline -profile-file=%t.profdata -S -cspgo-kind=cspgo-instr-use-pipeline| FileCheck %s --check-prefix=CSPGOSUMMARY
6
7target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
8target triple = "x86_64-unknown-linux-gnu"
9
10@odd = common dso_local global i32 0, align 4
11@even = common dso_local global i32 0, align 4
12@not_six = common dso_local global i32 0, align 4
13
14define dso_local i32 @goo(i32 %n) {
15entry:
16  %i = alloca i32, align 4
17  %i.0..sroa_cast = bitcast i32* %i to i8*
18  store volatile i32 %n, i32* %i, align 4
19  %i.0. = load volatile i32, i32* %i, align 4
20  ret i32 %i.0.
21}
22
23define dso_local void @bar(i32 %n) {
24entry:
25  %call = call fastcc i32 @cond(i32 %n)
26  %tobool = icmp eq i32 %call, 0
27  br i1 %tobool, label %if.else, label %if.then
28
29if.then:
30  %0 = load i32, i32* @odd, align 4
31  %inc = add i32 %0, 1
32  store i32 %inc, i32* @odd, align 4
33  br label %if.end
34
35if.else:
36  %1 = load i32, i32* @even, align 4
37  %inc1 = add i32 %1, 1
38  store i32 %inc1, i32* @even, align 4
39  br label %if.end
40
41if.end:
42  br label %for.cond
43
44for.cond:
45  %i.0 = phi i32 [ 0, %if.end ], [ %inc6, %for.inc ]
46  %cmp = icmp ult i32 %i.0, 4
47  br i1 %cmp, label %for.body, label %for.end
48
49for.body:
50  %mul = mul nsw i32 %i.0, %n
51  %rem = srem i32 %mul, 6
52  %tobool2 = icmp eq i32 %rem, 0
53  br i1 %tobool2, label %for.inc, label %if.then3
54
55if.then3:
56  %2 = load i32, i32* @not_six, align 4
57  %inc4 = add i32 %2, 1
58  store i32 %inc4, i32* @not_six, align 4
59  br label %for.inc
60
61for.inc:
62  %inc6 = add nuw nsw i32 %i.0, 1
63  br label %for.cond
64
65for.end:
66  ret void
67}
68; PGOSUMMARY-LABEL: @bar
69; PGOSUMMARY: %odd.sink{{[0-9]*}} = select i1 %tobool{{[0-9]*}}, i32* @even, i32* @odd
70; PGOSUMMARY-SAME: !prof ![[BW_PGO_BAR:[0-9]+]]
71; CSPGOSUMMARY-LABEL: @bar
72; CSPGOSUMMARY: %odd.sink{{[0-9]*}} = select i1 %tobool{{[0-9]*}}, i32* @even, i32* @odd
73; CSPGOSUMMARY-SAME: !prof ![[BW_CSPGO_BAR:[0-9]+]]
74
75define internal fastcc i32 @cond(i32 %i) {
76entry:
77  %rem = srem i32 %i, 2
78  ret i32 %rem
79}
80
81define dso_local void @foo() {
82entry:
83  br label %for.cond
84
85for.cond:
86  %i.0 = phi i32 [ 0, %entry ], [ %add4, %for.body ]
87  %cmp = icmp slt i32 %i.0, 200000
88  br i1 %cmp, label %for.body, label %for.end
89
90for.body:
91  %call = call i32 @goo(i32 %i.0)
92  call void @bar(i32 %call)
93  %add = add nsw i32 %call, 1
94  call void @bar(i32 %add)
95  %call1 = call i32 @bar_m(i32 %call) #4
96  %call3 = call i32 @bar_m2(i32 %add) #4
97  call fastcc void @barbar()
98  %add4 = add nsw i32 %call, 2
99  br label %for.cond
100
101for.end:
102  ret void
103}
104; CSPGOSUMMARY-LABEL: @foo
105; CSPGOSUMMARY: %even.sink{{[0-9]*}} = select i1 %tobool.i{{[0-9]*}}, i32* @even, i32* @odd
106; CSPGOSUMMARY-SAME: !prof ![[BW1_CSPGO_FOO:[0-9]+]]
107; CSPGOSUMMARY: %even.sink{{[0-9]*}} = select i1 %tobool.i{{[0-9]*}}, i32* @even, i32* @odd
108; CSPGOSUMMARY-SAME: !prof ![[BW2_CSPGO_FOO:[0-9]+]]
109
110declare dso_local i32 @bar_m(i32)
111declare dso_local i32 @bar_m2(i32)
112
113define internal fastcc void @barbar() {
114entry:
115  %0 = load i32, i32* @odd, align 4
116  %inc = add i32 %0, 1
117  store i32 %inc, i32* @odd, align 4
118  ret void
119}
120
121define dso_local i32 @main() {
122entry:
123  call void @foo()
124  ret i32 0
125}
126
127; PGOSUMMARY: {{![0-9]+}} = !{i32 1, !"ProfileSummary", !{{[0-9]+}}}
128; PGOSUMMARY: {{![0-9]+}} = !{!"ProfileFormat", !"InstrProf"}
129; PGOSUMMARY: {{![0-9]+}} = !{!"TotalCount", i64 2100001}
130; PGOSUMMARY: {{![0-9]+}} = !{!"MaxCount", i64 800000}
131; PGOSUMMARY: {{![0-9]+}} = !{!"MaxInternalCount", i64 399999}
132; PGOSUMMARY: {{![0-9]+}} = !{!"MaxFunctionCount", i64 800000}
133; PGOSUMMARY: {{![0-9]+}} = !{!"NumCounts", i64 14}
134; PGOSUMMARY: {{![0-9]+}} = !{!"NumFunctions", i64 8}
135; PGOSUMMARY-DAG: ![[BW_PGO_BAR]] = !{!"branch_weights", i32 100000, i32 100000}
136
137; CSPGOSUMMARY: {{![0-9]+}} = !{i32 1, !"ProfileSummary", !1}
138; CSPGOSUMMARY: {{![0-9]+}} = !{!"ProfileFormat", !"InstrProf"}
139; CSPGOSUMMARY: {{![0-9]+}} = !{!"TotalCount", i64 2100001}
140; CSPGOSUMMARY: {{![0-9]+}} = !{!"MaxCount", i64 800000}
141; CSPGOSUMMARY: {{![0-9]+}} = !{!"MaxInternalCount", i64 399999}
142; CSPGOSUMMARY: {{![0-9]+}} = !{!"MaxFunctionCount", i64 800000}
143; CSPGOSUMMARY: {{![0-9]+}} = !{!"NumCounts", i64 14}
144; CSPGOSUMMARY: {{![0-9]+}} = !{!"NumFunctions", i64 8}
145; CSPGOSUMMARY: {{![0-9]+}} = !{!"DetailedSummary", !{{[0-9]+}}}
146; CSPGOSUMMARY: {{![0-9]+}} = !{i32 1, !"CSProfileSummary", !{{[0-9]+}}}
147; CSPGOSUMMARY: {{![0-9]+}} = !{!"ProfileFormat", !"CSInstrProf"}
148; CSPGOSUMMARY: {{![0-9]+}} = !{!"TotalCount", i64 1299950}
149; CSPGOSUMMARY: {{![0-9]+}} = !{!"MaxCount", i64 200000}
150; CSPGOSUMMARY: {{![0-9]+}} = !{!"MaxInternalCount", i64 100000}
151; CSPGOSUMMARY: {{![0-9]+}} = !{!"MaxFunctionCount", i64 200000}
152; CSPGOSUMMARY: {{![0-9]+}} = !{!"NumCounts", i64 23}
153; CSPGOSUMMARY-DAG: ![[BW_CSPGO_BAR]] = !{!"branch_weights", i32 100000, i32 100000}
154; CSPGOSUMMARY-DAG: ![[BW1_CSPGO_FOO]] = !{!"branch_weights", i32 100000, i32 0}
155; CSPGOSUMMARY-DAG: ![[BW2_CSPGO_FOO]] = !{!"branch_weights", i32 0, i32 100000}
156