xref: /llvm-project/llvm/test/Transforms/SCCP/indirectbr.ll (revision 16bb8c16aab32e2ee623a2b64d976548be247180)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes=ipsccp < %s | FileCheck %s
3
4declare void @BB0_f()
5declare void @BB1_f()
6
7; Make sure we can eliminate what is in BB0 as we know that the indirectbr is going to BB1.
8;
9define void @indbrtest1() {
10; CHECK-LABEL: @indbrtest1(
11; CHECK-NEXT:  entry:
12; CHECK-NEXT:    br label [[BB1:%.*]]
13; CHECK:       BB1:
14; CHECK-NEXT:    call void @BB1_f()
15; CHECK-NEXT:    ret void
16;
17entry:
18  indirectbr ptr blockaddress(@indbrtest1, %BB1), [label %BB0, label %BB1]
19BB0:
20  call void @BB0_f()
21  br label %BB1
22BB1:
23  call void @BB1_f()
24  ret void
25}
26
27; Make sure we can eliminate what is in BB0 as we know that the indirectbr is going to BB1
28; by looking through the casts. The casts should be folded away when they are visited
29; before the indirectbr instruction.
30;
31define void @indbrtest2() {
32; CHECK-LABEL: @indbrtest2(
33; CHECK-NEXT:  entry:
34; CHECK-NEXT:    br label [[BB1:%.*]]
35; CHECK:       BB1:
36; CHECK-NEXT:    call void @BB1_f()
37; CHECK-NEXT:    ret void
38;
39entry:
40  %a = ptrtoint ptr blockaddress(@indbrtest2, %BB1) to i64
41  %b = inttoptr i64 %a to ptr
42  indirectbr ptr %b, [label %BB0, label %BB1]
43BB0:
44  call void @BB0_f()
45  br label %BB1
46BB1:
47  call void @BB1_f()
48  ret void
49}
50
51; Make sure we can not eliminate BB0 as we do not know the target of the indirectbr.
52
53define void @indbrtest3(ptr %Q) {
54; CHECK-LABEL: @indbrtest3(
55; CHECK-NEXT:  entry:
56; CHECK-NEXT:    [[T:%.*]] = load ptr, ptr [[Q:%.*]], align 8
57; CHECK-NEXT:    indirectbr ptr [[T]], [label [[BB0:%.*]], label %BB1]
58; CHECK:       BB0:
59; CHECK-NEXT:    call void @BB0_f()
60; CHECK-NEXT:    br label [[BB1:%.*]]
61; CHECK:       BB1:
62; CHECK-NEXT:    call void @BB1_f()
63; CHECK-NEXT:    ret void
64;
65entry:
66  %t = load ptr, ptr %Q
67  indirectbr ptr %t, [label %BB0, label %BB1]
68BB0:
69  call void @BB0_f()
70  br label %BB1
71BB1:
72  call void @BB1_f()
73  ret void
74}
75
76; Branch on undef is UB, so we can convert the indirectbr to unreachable.
77
78define void @indbrtest4(ptr %Q) {
79; CHECK-LABEL: @indbrtest4(
80; CHECK-NEXT:  entry:
81; CHECK-NEXT:    unreachable
82;
83entry:
84  indirectbr ptr undef, [label %BB0, label %BB1]
85BB0:
86  call void @BB0_f()
87  ret void
88BB1:
89  call void @BB1_f()
90  ret void
91}
92
93define internal i32 @indbrtest5(i1 %c) {
94; CHECK-LABEL: @indbrtest5(
95; CHECK-NEXT:  entry:
96; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
97; CHECK:       bb1:
98; CHECK-NEXT:    br label [[BRANCH_BLOCK:%.*]]
99; CHECK:       bb2:
100; CHECK-NEXT:    br label [[BRANCH_BLOCK]]
101; CHECK:       branch.block:
102; CHECK-NEXT:    [[ADDR:%.*]] = phi ptr [ blockaddress(@indbrtest5, [[TARGET1:%.*]]), [[BB1]] ], [ blockaddress(@indbrtest5, [[TARGET2:%.*]]), [[BB2]] ]
103; CHECK-NEXT:    indirectbr ptr [[ADDR]], [label [[TARGET1]], label %target2]
104; CHECK:       target1:
105; CHECK-NEXT:    br label [[TARGET2]]
106; CHECK:       target2:
107; CHECK-NEXT:    ret i32 poison
108;
109entry:
110  br i1 %c, label %bb1, label %bb2
111
112bb1:
113  br label %branch.block
114
115
116bb2:
117  br label %branch.block
118
119branch.block:
120  %addr = phi ptr [blockaddress(@indbrtest5, %target1), %bb1], [blockaddress(@indbrtest5, %target2), %bb2]
121  indirectbr ptr %addr, [label %target1, label %target2]
122
123target1:
124  br label %target2
125
126target2:
127  ret i32 10
128}
129
130
131define i32 @indbrtest5_callee(i1 %c) {
132; CHECK-LABEL: @indbrtest5_callee(
133; CHECK-NEXT:    [[R:%.*]] = call i32 @indbrtest5(i1 [[C:%.*]])
134; CHECK-NEXT:    ret i32 10
135;
136  %r = call i32 @indbrtest5(i1 %c)
137  ret i32 %r
138}
139
140define i32 @indbr_duplicate_successors_phi(i1 %c, i32 %x) {
141; CHECK-LABEL: @indbr_duplicate_successors_phi(
142; CHECK-NEXT:  entry:
143; CHECK-NEXT:    br i1 [[C:%.*]], label [[INDBR:%.*]], label [[BB0:%.*]]
144; CHECK:       indbr:
145; CHECK-NEXT:    br label [[BB0]]
146; CHECK:       BB0:
147; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ 0, [[INDBR]] ]
148; CHECK-NEXT:    ret i32 [[PHI]]
149;
150entry:
151  br i1 %c, label %indbr, label %BB0
152
153indbr:
154  indirectbr ptr blockaddress(@indbr_duplicate_successors_phi, %BB0), [label %BB0, label %BB0, label %BB1]
155
156BB0:
157  %phi = phi i32 [ %x, %entry ], [ 0, %indbr ], [ 0, %indbr ]
158  ret i32 %phi
159
160BB1:
161  ret i32 0
162}
163