• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt -jump-threading -S -verify < %s | FileCheck %s
2
3declare i32 @f1()
4declare i32 @f2()
5declare void @f3()
6declare void @f4(i32)
7
8
9; Make sure we update the phi node properly.
10;
11; CHECK-LABEL: define void @test_br_folding_not_threading_update_phi(
12; CHECK: br label %L1
13; Make sure we update the phi node properly here, i.e. we only have 2 predecessors, entry and L0
14; CHECK: %res.0 = phi i32 [ 0, %L0 ], [ 1, %entry ]
15define void @test_br_folding_not_threading_update_phi(i32 %val) nounwind {
16entry:
17  %cmp = icmp eq i32 %val, 32
18  br i1 %cmp, label %L0, label %L1
19L0:
20  call i32 @f2()
21  call i32 @f2()
22  call i32 @f2()
23  call i32 @f2()
24  call i32 @f2()
25  call i32 @f2()
26  call i32 @f2()
27  call i32 @f2()
28  call i32 @f2()
29  call i32 @f2()
30  call i32 @f2()
31  call i32 @f2()
32  call i32 @f2()
33  switch i32 %val, label %L2 [
34    i32 0, label %L1
35    i32 32, label %L1
36  ]
37
38L1:
39	%res.0 = phi i32 [ 0, %L0 ], [ 0, %L0 ], [1, %entry]
40  call void @f4(i32 %res.0)
41  ret void
42L2:
43  call void @f3()
44  ret void
45}
46
47; Make sure we can fold this branch ... We will not be able to thread it as
48; L0 is too big to duplicate. L2 is the unreachable block here.
49;
50; CHECK-LABEL: @test_br_folding_not_threading(
51; CHECK: L1:
52; CHECK: call i32 @f2()
53; CHECK: call void @f3()
54; CHECK-NEXT: ret void
55; CHECK-NOT: br
56; CHECK: L3:
57define void @test_br_folding_not_threading(i1 %cond) nounwind {
58entry:
59  br i1 %cond, label %L0, label %L3
60L0:
61  call i32 @f2()
62  call i32 @f2()
63  call i32 @f2()
64  call i32 @f2()
65  call i32 @f2()
66  call i32 @f2()
67  call i32 @f2()
68  call i32 @f2()
69  call i32 @f2()
70  call i32 @f2()
71  call i32 @f2()
72  call i32 @f2()
73  call i32 @f2()
74  br i1 %cond, label %L1, label %L2
75
76L1:
77  call void @f3()
78  ret void
79L2:
80  call void @f3()
81  ret void
82L3:
83  call void @f3()
84  ret void
85}
86
87
88; Make sure we can fold this branch ... We will not be able to thread it as
89; L0 is too big to duplicate. L2 is the unreachable block here.
90; With more than 1 predecessors.
91;
92; CHECK-LABEL: @test_br_folding_not_threading_multiple_preds(
93; CHECK: L1:
94; CHECK: call i32 @f2()
95; CHECK: call void @f3()
96; CHECK-NEXT: ret void
97; CHECK-NOT: br
98; CHECK: L3:
99define void @test_br_folding_not_threading_multiple_preds(i1 %condx, i1 %cond) nounwind {
100entry:
101  br i1 %condx, label %X0, label %X1
102
103X0:
104  br i1 %cond, label %L0, label %L3
105
106X1:
107  br i1 %cond, label %L0, label %L3
108
109L0:
110  call i32 @f2()
111  call i32 @f2()
112  call i32 @f2()
113  call i32 @f2()
114  call i32 @f2()
115  call i32 @f2()
116  call i32 @f2()
117  call i32 @f2()
118  call i32 @f2()
119  call i32 @f2()
120  call i32 @f2()
121  call i32 @f2()
122  call i32 @f2()
123  br i1 %cond, label %L1, label %L2
124
125L1:
126  call void @f3()
127  ret void
128L2:
129  call void @f3()
130  ret void
131L3:
132  call void @f3()
133  ret void
134}
135
136; Make sure we can do the RAUW for %add...
137;
138; CHECK-LABEL: @rauw_if_possible(
139; CHECK: call void @f4(i32 96)
140define void @rauw_if_possible(i32 %value) nounwind {
141entry:
142  %cmp = icmp eq i32 %value, 32
143  br i1 %cmp, label %L0, label %L3
144L0:
145  call i32 @f2()
146  call i32 @f2()
147  %add = add i32 %value, 64
148  switch i32 %add, label %L3 [
149    i32 32, label %L1
150    i32 96, label %L2
151    ]
152
153L1:
154  call void @f3()
155  ret void
156L2:
157  call void @f4(i32 %add)
158  ret void
159L3:
160  call void @f3()
161  ret void
162}
163
164; Make sure we can NOT do the RAUW for %add...
165;
166; CHECK-LABEL: @rauw_if_possible2(
167; CHECK: call void @f4(i32 %add)
168define void @rauw_if_possible2(i32 %value) nounwind {
169entry:
170  %cmp = icmp eq i32 %value, 32
171  %add = add i32 %value, 64
172  br i1 %cmp, label %L0, label %L2
173L0:
174  call i32 @f2()
175  call i32 @f2()
176  switch i32 %add, label %L3 [
177    i32 32, label %L1
178    i32 96, label %L2
179    ]
180
181L1:
182  call void @f3()
183  ret void
184L2:
185  call void @f4(i32 %add)
186  ret void
187L3:
188  call void @f3()
189  ret void
190}
191
192; Make sure we can fold this branch ... We will not be able to thread it as
193; L0 is too big to duplicate.
194; We do not attempt to rewrite the indirectbr target here, but we still take
195; its target after L0 into account and that enables us to fold.
196;
197; L2 is the unreachable block here.
198;
199; CHECK-LABEL: @test_br_folding_not_threading_indirect_branch(
200; CHECK: L1:
201; CHECK: call i32 @f2()
202; CHECK: call void @f3()
203; CHECK-NEXT: ret void
204; CHECK-NOT: br
205; CHECK: L3:
206define void @test_br_folding_not_threading_indirect_branch(i1 %condx, i1 %cond) nounwind {
207entry:
208  br i1 %condx, label %X0, label %X1
209
210X0:
211  br i1 %cond, label %L0, label %L3
212
213X1:
214  br i1 %cond, label %XX1, label %L3
215
216XX1:
217  indirectbr i8* blockaddress(@test_br_folding_not_threading_indirect_branch, %L0), [label %L0]
218
219L0:
220  call i32 @f2()
221  call i32 @f2()
222  call i32 @f2()
223  call i32 @f2()
224  call i32 @f2()
225  call i32 @f2()
226  call i32 @f2()
227  call i32 @f2()
228  call i32 @f2()
229  call i32 @f2()
230  call i32 @f2()
231  call i32 @f2()
232  call i32 @f2()
233  br i1 %cond, label %L1, label %L2
234
235L1:
236  call void @f3()
237  ret void
238
239L2:
240  call void @f3()
241  ret void
242
243L3:
244  call void @f3()
245  ret void
246}
247