xref: /llvm-project/llvm/test/Transforms/PGOProfile/misexpect-switch.ll (revision 9ff36df5a4a7d52c51e950522870bb64912688d2)
1; Test misexpect diagnostics handle swich statements, and report source locations correctly
2
3; RUN: llvm-profdata merge %S/Inputs/misexpect-switch.proftext -o %t.profdata
4; RUN: llvm-profdata merge %S/Inputs/misexpect-switch-correct.proftext -o %t.c.profdata
5
6; RUN: opt < %s -passes="function(lower-expect),pgo-instr-use" -pgo-test-profile-file=%t.profdata -pgo-warn-misexpect -S 2>&1 | FileCheck %s --check-prefix=WARNING
7; RUN: opt < %s -passes="function(lower-expect),pgo-instr-use" -pgo-test-profile-file=%t.profdata -pass-remarks=misexpect -S 2>&1 | FileCheck %s --check-prefix=REMARK
8; RUN: opt < %s -passes="function(lower-expect),pgo-instr-use" -pgo-test-profile-file=%t.profdata -pgo-warn-misexpect -pass-remarks=misexpect -S 2>&1 | FileCheck %s --check-prefix=BOTH
9; RUN: opt < %s -passes="function(lower-expect),pgo-instr-use" -pgo-test-profile-file=%t.profdata -S 2>&1 | FileCheck %s --check-prefix=DISABLED
10
11; RUN: opt < %s -passes="function(lower-expect),pgo-instr-use" -pgo-test-profile-file=%t.c.profdata -pgo-warn-misexpect -pass-remarks=misexpect -S 2>&1 | FileCheck %s --check-prefix=CORRECT
12
13; WARNING-DAG: warning: misexpect-switch.c:26:30: 0.00%
14; WARNING-NOT: remark: misexpect-switch.c:26:30: Potential performance regression from use of the llvm.expect intrinsic: Annotation was correct on 0.00% (0 / 8112) of profiled executions.
15
16; REMARK-NOT: warning: misexpect-switch.c:26:30: 0.00%
17; REMARK-DAG: remark: misexpect-switch.c:26:30: Potential performance regression from use of the llvm.expect intrinsic: Annotation was correct on 0.00% (0 / 8112) of profiled executions.
18
19; BOTH-DAG: warning: misexpect-switch.c:26:30: 0.00%
20; BOTH-DAG: remark: misexpect-switch.c:26:30: Potential performance regression from use of the llvm.expect intrinsic: Annotation was correct on 0.00% (0 / 8112) of profiled executions.
21
22; DISABLED-NOT: warning: misexpect-switch.c:26:30: 0.00%
23; DISABLED-NOT: remark: misexpect-switch.c:26:30: Potential performance regression from use of the llvm.expect intrinsic: Annotation was correct on 0.00% (0 / 8112) of profiled executions.
24
25; DISABLED-NOT: warning: misexpect-switch.c:26:30: 0.00%
26; DISABLED-NOT: remark: misexpect-switch.c:26:30: Potential performance regression from use of the llvm.expect intrinsic: Annotation was correct on 0.00% (0 / 8112) of profiled executions.
27
28; CORRECT-NOT: warning: {{.*}}
29; CORRECT-NOT: remark: {{.*}}
30
31
32; ModuleID = 'misexpect-switch.c'
33source_filename = "misexpect-switch.c"
34target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
35target triple = "x86_64-unknown-linux-gnu"
36
37@inner_loop = dso_local constant i32 1000, align 4, !dbg !0
38@outer_loop = dso_local constant i32 20, align 4, !dbg !6
39@arry_size = dso_local constant i32 25, align 4, !dbg !10
40@arry = dso_local global [25 x i32] zeroinitializer, align 16, !dbg !12
41
42; Function Attrs: nounwind uwtable
43define dso_local void @init_arry() #0 !dbg !21 {
44entry:
45  %i = alloca i32, align 4
46  call void @llvm.lifetime.start.p0(i64 4, ptr %i) #6, !dbg !26
47  call void @llvm.dbg.declare(metadata ptr %i, metadata !25, metadata !DIExpression()), !dbg !27
48  store i32 0, ptr %i, align 4, !dbg !28, !tbaa !30
49  br label %for.cond, !dbg !34
50
51for.cond:                                         ; preds = %for.inc, %entry
52  %0 = load i32, ptr %i, align 4, !dbg !35, !tbaa !30
53  %cmp = icmp slt i32 %0, 25, !dbg !37
54  br i1 %cmp, label %for.body, label %for.end, !dbg !38
55
56for.body:                                         ; preds = %for.cond
57  %call = call i32 @rand() #6, !dbg !39
58  %rem = srem i32 %call, 10, !dbg !41
59  %1 = load i32, ptr %i, align 4, !dbg !42, !tbaa !30
60  %idxprom = sext i32 %1 to i64, !dbg !43
61  %arrayidx = getelementptr inbounds [25 x i32], ptr @arry, i64 0, i64 %idxprom, !dbg !43
62  store i32 %rem, ptr %arrayidx, align 4, !dbg !44, !tbaa !30
63  br label %for.inc, !dbg !45
64
65for.inc:                                          ; preds = %for.body
66  %2 = load i32, ptr %i, align 4, !dbg !46, !tbaa !30
67  %inc = add nsw i32 %2, 1, !dbg !46
68  store i32 %inc, ptr %i, align 4, !dbg !46, !tbaa !30
69  br label %for.cond, !dbg !47, !llvm.loop !48
70
71for.end:                                          ; preds = %for.cond
72  call void @llvm.lifetime.end.p0(i64 4, ptr %i) #6, !dbg !50
73  ret void, !dbg !50
74}
75
76; Function Attrs: argmemonly nounwind willreturn
77declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1
78
79; Function Attrs: nounwind readnone speculatable willreturn
80declare void @llvm.dbg.declare(metadata, metadata, metadata) #2
81
82; Function Attrs: nounwind
83declare dso_local i32 @rand() #3
84
85; Function Attrs: argmemonly nounwind willreturn
86declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1
87
88; Function Attrs: nounwind uwtable
89define dso_local i32 @main() #0 !dbg !51 {
90entry:
91  %retval = alloca i32, align 4
92  %val = alloca i32, align 4
93  %j = alloca i32, align 4
94  %condition = alloca i32, align 4
95  store i32 0, ptr %retval, align 4
96  call void @init_arry(), !dbg !62
97  call void @llvm.lifetime.start.p0(i64 4, ptr %val) #6, !dbg !63
98  call void @llvm.dbg.declare(metadata ptr %val, metadata !55, metadata !DIExpression()), !dbg !64
99  store i32 0, ptr %val, align 4, !dbg !64, !tbaa !30
100  call void @llvm.lifetime.start.p0(i64 4, ptr %j) #6, !dbg !65
101  call void @llvm.dbg.declare(metadata ptr %j, metadata !56, metadata !DIExpression()), !dbg !66
102  store i32 0, ptr %j, align 4, !dbg !67, !tbaa !30
103  br label %for.cond, !dbg !68
104
105for.cond:                                         ; preds = %for.inc, %entry
106  %0 = load i32, ptr %j, align 4, !dbg !69, !tbaa !30
107  %cmp = icmp slt i32 %0, 20000, !dbg !70
108  br i1 %cmp, label %for.body, label %for.end, !dbg !71
109
110for.body:                                         ; preds = %for.cond
111  call void @llvm.lifetime.start.p0(i64 4, ptr %condition) #6, !dbg !72
112  call void @llvm.dbg.declare(metadata ptr %condition, metadata !57, metadata !DIExpression()), !dbg !73
113  %call = call i32 @rand() #6, !dbg !74
114  %rem = srem i32 %call, 5, !dbg !75
115  store i32 %rem, ptr %condition, align 4, !dbg !73, !tbaa !30
116  %1 = load i32, ptr %condition, align 4, !dbg !76, !tbaa !30
117  %conv = zext i32 %1 to i64, !dbg !76
118  %expval = call i64 @llvm.expect.i64(i64 %conv, i64 0), !dbg !77
119  switch i64 %expval, label %sw.default [
120    i64 0, label %sw.bb
121    i64 1, label %sw.bb2
122    i64 2, label %sw.bb2
123    i64 3, label %sw.bb2
124    i64 4, label %sw.bb3
125  ], !dbg !78
126
127sw.bb:                                            ; preds = %for.body
128  %call1 = call i32 @sum(ptr @arry, i32 25), !dbg !79
129  %2 = load i32, ptr %val, align 4, !dbg !81, !tbaa !30
130  %add = add nsw i32 %2, %call1, !dbg !81
131  store i32 %add, ptr %val, align 4, !dbg !81, !tbaa !30
132  br label %sw.epilog, !dbg !82
133
134sw.bb2:                                           ; preds = %for.body, %for.body, %for.body
135  br label %sw.epilog, !dbg !83
136
137sw.bb3:                                           ; preds = %for.body
138  %call4 = call i32 @random_sample(ptr @arry, i32 25), !dbg !84
139  %3 = load i32, ptr %val, align 4, !dbg !85, !tbaa !30
140  %add5 = add nsw i32 %3, %call4, !dbg !85
141  store i32 %add5, ptr %val, align 4, !dbg !85, !tbaa !30
142  br label %sw.epilog, !dbg !86
143
144sw.default:                                       ; preds = %for.body
145  unreachable, !dbg !87
146
147sw.epilog:                                        ; preds = %sw.bb3, %sw.bb2, %sw.bb
148  call void @llvm.lifetime.end.p0(i64 4, ptr %condition) #6, !dbg !88
149  br label %for.inc, !dbg !89
150
151for.inc:                                          ; preds = %sw.epilog
152  %4 = load i32, ptr %j, align 4, !dbg !90, !tbaa !30
153  %inc = add nsw i32 %4, 1, !dbg !90
154  store i32 %inc, ptr %j, align 4, !dbg !90, !tbaa !30
155  br label %for.cond, !dbg !91, !llvm.loop !92
156
157for.end:                                          ; preds = %for.cond
158  call void @llvm.lifetime.end.p0(i64 4, ptr %j) #6, !dbg !94
159  call void @llvm.lifetime.end.p0(i64 4, ptr %val) #6, !dbg !94
160  ret i32 0, !dbg !95
161}
162
163; Function Attrs: nounwind readnone willreturn
164declare i64 @llvm.expect.i64(i64, i64) #4
165
166declare dso_local i32 @sum(ptr, i32) #5
167
168declare dso_local i32 @random_sample(ptr, i32) #5
169
170attributes #0 = { nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
171attributes #1 = { argmemonly nounwind willreturn }
172attributes #2 = { nounwind readnone speculatable willreturn }
173attributes #3 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
174attributes #4 = { nounwind readnone willreturn }
175attributes #5 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
176attributes #6 = { nounwind }
177
178!llvm.dbg.cu = !{!2}
179!llvm.module.flags = !{!17, !18, !19}
180!llvm.ident = !{!20}
181
182!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
183!1 = distinct !DIGlobalVariable(name: "inner_loop", scope: !2, file: !3, line: 7, type: !8, isLocal: false, isDefinition: true)
184!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 10.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None)
185!3 = !DIFile(filename: "misexpect-switch.c", directory: ".")
186!4 = !{}
187!5 = !{!0, !6, !10, !12}
188!6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression())
189!7 = distinct !DIGlobalVariable(name: "outer_loop", scope: !2, file: !3, line: 8, type: !8, isLocal: false, isDefinition: true)
190!8 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !9)
191!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
192!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression())
193!11 = distinct !DIGlobalVariable(name: "arry_size", scope: !2, file: !3, line: 9, type: !8, isLocal: false, isDefinition: true)
194!12 = !DIGlobalVariableExpression(var: !13, expr: !DIExpression())
195!13 = distinct !DIGlobalVariable(name: "arry", scope: !2, file: !3, line: 11, type: !14, isLocal: false, isDefinition: true)
196!14 = !DICompositeType(tag: DW_TAG_array_type, baseType: !9, size: 800, elements: !15)
197!15 = !{!16}
198!16 = !DISubrange(count: 25)
199!17 = !{i32 2, !"Dwarf Version", i32 4}
200!18 = !{i32 2, !"Debug Info Version", i32 3}
201!19 = !{i32 1, !"wchar_size", i32 4}
202!20 = !{!"clang version 10.0.0"}
203!21 = distinct !DISubprogram(name: "init_arry", scope: !3, file: !3, line: 13, type: !22, scopeLine: 13, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !24)
204!22 = !DISubroutineType(types: !23)
205!23 = !{null}
206!24 = !{!25}
207!25 = !DILocalVariable(name: "i", scope: !21, file: !3, line: 14, type: !9)
208!26 = !DILocation(line: 14, column: 3, scope: !21)
209!27 = !DILocation(line: 14, column: 7, scope: !21)
210!28 = !DILocation(line: 15, column: 10, scope: !29)
211!29 = distinct !DILexicalBlock(scope: !21, file: !3, line: 15, column: 3)
212!30 = !{!31, !31, i64 0}
213!31 = !{!"int", !32, i64 0}
214!32 = !{!"omnipotent char", !33, i64 0}
215!33 = !{!"Simple C/C++ TBAA"}
216!34 = !DILocation(line: 15, column: 8, scope: !29)
217!35 = !DILocation(line: 15, column: 15, scope: !36)
218!36 = distinct !DILexicalBlock(scope: !29, file: !3, line: 15, column: 3)
219!37 = !DILocation(line: 15, column: 17, scope: !36)
220!38 = !DILocation(line: 15, column: 3, scope: !29)
221!39 = !DILocation(line: 16, column: 15, scope: !40)
222!40 = distinct !DILexicalBlock(scope: !36, file: !3, line: 15, column: 35)
223!41 = !DILocation(line: 16, column: 22, scope: !40)
224!42 = !DILocation(line: 16, column: 10, scope: !40)
225!43 = !DILocation(line: 16, column: 5, scope: !40)
226!44 = !DILocation(line: 16, column: 13, scope: !40)
227!45 = !DILocation(line: 17, column: 3, scope: !40)
228!46 = !DILocation(line: 15, column: 30, scope: !36)
229!47 = !DILocation(line: 15, column: 3, scope: !36)
230!48 = distinct !{!48, !38, !49}
231!49 = !DILocation(line: 17, column: 3, scope: !29)
232!50 = !DILocation(line: 18, column: 1, scope: !21)
233!51 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line: 20, type: !52, scopeLine: 20, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !54)
234!52 = !DISubroutineType(types: !53)
235!53 = !{!9}
236!54 = !{!55, !56, !57}
237!55 = !DILocalVariable(name: "val", scope: !51, file: !3, line: 22, type: !9)
238!56 = !DILocalVariable(name: "j", scope: !51, file: !3, line: 23, type: !9)
239!57 = !DILocalVariable(name: "condition", scope: !58, file: !3, line: 25, type: !61)
240!58 = distinct !DILexicalBlock(scope: !59, file: !3, line: 24, column: 49)
241!59 = distinct !DILexicalBlock(scope: !60, file: !3, line: 24, column: 3)
242!60 = distinct !DILexicalBlock(scope: !51, file: !3, line: 24, column: 3)
243!61 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned)
244!62 = !DILocation(line: 21, column: 3, scope: !51)
245!63 = !DILocation(line: 22, column: 3, scope: !51)
246!64 = !DILocation(line: 22, column: 7, scope: !51)
247!65 = !DILocation(line: 23, column: 3, scope: !51)
248!66 = !DILocation(line: 23, column: 7, scope: !51)
249!67 = !DILocation(line: 24, column: 10, scope: !60)
250!68 = !DILocation(line: 24, column: 8, scope: !60)
251!69 = !DILocation(line: 24, column: 15, scope: !59)
252!70 = !DILocation(line: 24, column: 17, scope: !59)
253!71 = !DILocation(line: 24, column: 3, scope: !60)
254!72 = !DILocation(line: 25, column: 5, scope: !58)
255!73 = !DILocation(line: 25, column: 14, scope: !58)
256!74 = !DILocation(line: 25, column: 26, scope: !58)
257!75 = !DILocation(line: 25, column: 33, scope: !58)
258!76 = !DILocation(line: 26, column: 30, scope: !58)
259!77 = !DILocation(line: 26, column: 13, scope: !58)
260!78 = !DILocation(line: 26, column: 5, scope: !58)
261!79 = !DILocation(line: 28, column: 14, scope: !80)
262!80 = distinct !DILexicalBlock(scope: !58, file: !3, line: 26, column: 45)
263!81 = !DILocation(line: 28, column: 11, scope: !80)
264!82 = !DILocation(line: 29, column: 7, scope: !80)
265!83 = !DILocation(line: 33, column: 7, scope: !80)
266!84 = !DILocation(line: 35, column: 14, scope: !80)
267!85 = !DILocation(line: 35, column: 11, scope: !80)
268!86 = !DILocation(line: 36, column: 7, scope: !80)
269!87 = !DILocation(line: 38, column: 7, scope: !80)
270!88 = !DILocation(line: 40, column: 3, scope: !59)
271!89 = !DILocation(line: 40, column: 3, scope: !58)
272!90 = !DILocation(line: 24, column: 44, scope: !59)
273!91 = !DILocation(line: 24, column: 3, scope: !59)
274!92 = distinct !{!92, !71, !93}
275!93 = !DILocation(line: 40, column: 3, scope: !60)
276!94 = !DILocation(line: 43, column: 1, scope: !51)
277!95 = !DILocation(line: 42, column: 3, scope: !51)
278