1
+ ; REQUIRES: asserts && x86_64-linux
2
+ ; Check that the profile annotator works: we hit an exit and non-zero paths to
3
+ ; already visited blocks count as taken (i.e. the flow continues through them).
4
+ ;
5
+ ; RUN: split-file %s %t
6
+ ; RUN: llvm-ctxprof-util fromJSON --input=%t/profile_ok.json --output=%t/profile_ok.ctxprofdata
7
+ ; RUN: llvm-ctxprof-util fromJSON --input=%t/profile_pump.json --output=%t/profile_pump.ctxprofdata
8
+ ; RUN: llvm-ctxprof-util fromJSON --input=%t/profile_unreachable.json --output=%t/profile_unreachable.ctxprofdata
9
+ ;
10
+ ; RUN: opt -passes=ctx-prof-flatten %t/example_ok.ll -use-ctx-profile=%t/profile_ok.ctxprofdata -S -o - | FileCheck %s
11
+ ; RUN: not --crash opt -passes=ctx-prof-flatten %t/message_pump.ll -use-ctx-profile=%t/profile_pump.ctxprofdata -S 2>&1 | FileCheck %s --check-prefix=ASSERTION
12
+ ; RUN: not --crash opt -passes=ctx-prof-flatten %t/unreachable.ll -use-ctx-profile=%t/profile_unreachable.ctxprofdata -S 2>&1 | FileCheck %s --check-prefix=ASSERTION
13
+
14
+ ; CHECK: br i1 %x, label %b1, label %exit, !prof ![[PROF1:[0-9]+]]
15
+ ; CHECK: br i1 %y, label %blk, label %exit, !prof ![[PROF2:[0-9]+]]
16
+ ; CHECK: ![[PROF1]] = !{!"branch_weights", i32 1, i32 1}
17
+ ; CHECK: ![[PROF2]] = !{!"branch_weights", i32 0, i32 1}
18
+ ; ASSERTION: Assertion `allTakenPathsExit()
19
+
20
+ ; b1->exit is the only way out from b1, but the exit block would have been
21
+ ; already visited from blk. That should not result in an assertion, though.
22
+ ;--- example_ok.ll
23
+ define void @foo (i32 %t ) !guid !0 {
24
+ entry:
25
+ call void @llvm.instrprof.increment (ptr @foo , i64 42 , i32 42 , i32 0 )
26
+ br label %blk
27
+ blk:
28
+ call void @llvm.instrprof.increment (ptr @foo , i64 42 , i32 42 , i32 1 )
29
+ %x = icmp eq i32 %t , 0
30
+ br i1 %x , label %b1 , label %exit
31
+ b1:
32
+ call void @llvm.instrprof.increment (ptr @foo , i64 42 , i32 42 , i32 2 )
33
+ %y = icmp eq i32 %t , 0
34
+ br i1 %y , label %blk , label %exit
35
+ exit:
36
+ call void @llvm.instrprof.increment (ptr @foo , i64 42 , i32 42 , i32 3 )
37
+ ret void
38
+ }
39
+ !0 = !{i64 1234 }
40
+
41
+ ;--- profile_ok.json
42
+ [{"Guid" :1234 , "Counters" :[2 , 2 , 1 , 2 ]}]
43
+
44
+ ;--- message_pump.ll
45
+ ; This is a message pump: the loop never exits. This should result in an
46
+ ; assertion because we can't reach an exit BB
47
+
48
+ define void @foo (i32 %t ) !guid !0 {
49
+ entry:
50
+ call void @llvm.instrprof.increment (ptr @foo , i64 42 , i32 42 , i32 0 )
51
+ br label %blk
52
+ blk:
53
+ call void @llvm.instrprof.increment (ptr @foo , i64 42 , i32 42 , i32 1 )
54
+ %x = icmp eq i32 %t , 0
55
+ br i1 %x , label %blk , label %exit
56
+ exit:
57
+ call void @llvm.instrprof.increment (ptr @foo , i64 42 , i32 42 , i32 2 )
58
+ ret void
59
+ }
60
+ !0 = !{i64 1234 }
61
+
62
+ ;--- profile_pump.json
63
+ [{"Guid" :1234 , "Counters" :[2 , 10 , 0 ]}]
64
+
65
+ ;--- unreachable.ll
66
+ ; An unreachable block is reached, that's an error
67
+ define void @foo (i32 %t ) !guid !0 {
68
+ entry:
69
+ call void @llvm.instrprof.increment (ptr @foo , i64 42 , i32 42 , i32 0 )
70
+ br label %blk
71
+ blk:
72
+ call void @llvm.instrprof.increment (ptr @foo , i64 42 , i32 42 , i32 1 )
73
+ %x = icmp eq i32 %t , 0
74
+ br i1 %x , label %b1 , label %exit
75
+ b1:
76
+ call void @llvm.instrprof.increment (ptr @foo , i64 42 , i32 42 , i32 2 )
77
+ unreachable
78
+ exit:
79
+ call void @llvm.instrprof.increment (ptr @foo , i64 42 , i32 42 , i32 3 )
80
+ ret void
81
+ }
82
+ !0 = !{i64 1234 }
83
+
84
+ ;--- profile_unreachable.json
85
+ [{"Guid" :1234 , "Counters" :[2 , 1 , 1 , 2 ]}]
0 commit comments