1; REQUIRES: x86_64-linux
2; RUN: opt < %s -passes='pseudo-probe,jump-threading' -S -o %t
3; RUN: FileCheck %s < %t --check-prefix=JT
4; RUN: llc -pseudo-probe-for-profiling -function-sections <%t -filetype=asm | FileCheck %s --check-prefix=ASM
5; RUN: opt < %s -passes='pseudo-probe' -S -o %t1
6; RUN: llc -pseudo-probe-for-profiling -stop-after=tailduplication <%t1 | FileCheck %s --check-prefix=MIR-tail
7; RUN: opt < %s -passes='pseudo-probe,simplifycfg' -S | FileCheck %s --check-prefix=SC
8
9declare i32 @f1()
10
11define i32 @foo(i1 %cond) {
12; JT-LABEL: @foo(
13; JT: call void @llvm.pseudoprobe(i64 [[#GUID:]], i64 1, i32 0, i64 -1)
14; ASM: pseudoprobe	6699318081062747564 1 0 0
15	%call = call i32 @f1()
16	br i1 %cond, label %T, label %F
17T:
18	br label %Merge
19F:
20	br label %Merge
21Merge:
22;; Check branch T and F are gone, and their probes (probe 2 and 3) are dangling.
23; JT-LABEL-NO: T
24; JT-LABEL-NO: F
25; JT-LABEL: Merge
26; JT: call void @llvm.pseudoprobe(i64 [[#GUID:]], i64 3, i32 2, i64 -1)
27; JT: call void @llvm.pseudoprobe(i64 [[#GUID:]], i64 2, i32 2, i64 -1)
28; JT: call void @llvm.pseudoprobe(i64 [[#GUID:]], i64 4, i32 0, i64 -1)
29; ASM: .pseudoprobe	6699318081062747564 3 0 2
30; ASM: .pseudoprobe	6699318081062747564 2 0 2
31; ASM: .pseudoprobe	6699318081062747564 4 0 0
32	ret i32 %call
33}
34
35;; Check block T and F are gone, and their probes (probe 2 and 3) are dangling.
36; MIR-tail: bb.0
37; MIR-tail: PSEUDO_PROBE [[#GUID:]], 1, 0, 0
38; MIR-tail: PSEUDO_PROBE [[#GUID:]], 2, 0, 2
39; MIR-tail: PSEUDO_PROBE [[#GUID:]], 3, 0, 2
40; MIR-tail: PSEUDO_PROBE [[#GUID:]], 4, 0, 0
41
42
43define void @foo2() {
44bb:
45  %tmp = call i32 @f1()
46  %tmp1 = icmp eq i32 %tmp, 1
47  br i1 %tmp1, label %bb5, label %bb8
48
49bb2:
50  %tmp4 = icmp ne i32 %tmp, 1
51  switch i1 %tmp4, label %bb2 [
52  i1 0, label %bb5
53  i1 1, label %bb8
54  ]
55
56bb5:
57;; Check the pseudo probe with id 3 only has one copy.
58; JT-COUNT-1: call void @llvm.pseudoprobe(i64 [[#GUID2:]], i64 3, i32 2, i64 -1)
59; JT-NOT: call void @llvm.pseudoprobe(i64 [[#GUID2:]], i64 3, i32 2, i64 -1)
60  %tmp6 = phi i1 [ %tmp1, %bb ], [ false, %bb2 ]
61  br i1 %tmp6, label %bb8, label %bb7
62
63bb7:
64  br label %bb8
65
66bb8:
67  ret void
68}
69
70define i32 @test(i32 %a, i32 %b, i32 %c) {
71;; Check block bb1 and bb2 are gone, and their probes (probe 2 and 3) are dangling.
72; SC-LABEL: @test(
73; SC-LABEL-NO: bb1
74; SC-LABEL-NO: bb2
75; SC:    [[T1:%.*]] = icmp eq i32 [[B:%.*]], 0
76; SC-DAG:    call void @llvm.pseudoprobe(i64 [[#GUID3:]], i64 2, i32 2, i64 -1)
77; SC-DAG:    call void @llvm.pseudoprobe(i64 [[#GUID3]], i64 3, i32 2, i64 -1)
78; SC:    [[T2:%.*]] = icmp sgt i32 [[C:%.*]], 1
79; SC:    [[T3:%.*]] = add i32 [[A:%.*]], 1
80; SC:    [[SPEC_SELECT:%.*]] = select i1 [[T2]], i32 [[T3]], i32 [[A]]
81; SC:    [[T4:%.*]] = select i1 [[T1]], i32 [[SPEC_SELECT]], i32 [[B]]
82; SC:    [[T5:%.*]] = sub i32 [[T4]], 1
83; SC:    ret i32 [[T5]]
84
85entry:
86  %t1 = icmp eq i32 %b, 0
87  br i1 %t1, label %bb1, label %bb3
88
89bb1:
90  %t2 = icmp sgt i32 %c, 1
91  br i1 %t2, label %bb2, label %bb3
92
93bb2:
94  %t3 = add i32 %a, 1
95  br label %bb3
96
97bb3:
98  %t4 = phi i32 [ %b, %entry ], [ %a, %bb1 ], [ %t3, %bb2 ]
99  %t5 = sub i32 %t4, 1
100  ret i32 %t5
101}
102