1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -print-predicateinfo -disable-output < %s 2>&1 | FileCheck %s
3
4declare void @foo(i1)
5declare void @bar(i32)
6declare void @llvm.assume(i1)
7
8define void @test_or(i32 %x, i32 %y) {
9; CHECK-LABEL: @test_or(
10; CHECK-NEXT:    [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
11; CHECK-NEXT:    [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
12; CHECK-NEXT:    [[Z:%.*]] = or i1 [[XZ]], [[YZ]]
13; CHECK:         [[Z_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
14; CHECK:         [[XZ_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[XZ]])
15; CHECK:         [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
16; CHECK:         [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[YZ]])
17; CHECK:         [[Y_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
18; CHECK-NEXT:    br i1 [[Z]], label [[ONEOF:%.*]], label [[NEITHER:%.*]]
19; CHECK:       oneof:
20; CHECK-NEXT:    call void @foo(i1 [[XZ]])
21; CHECK-NEXT:    call void @foo(i1 [[YZ]])
22; CHECK-NEXT:    call void @bar(i32 [[X]])
23; CHECK-NEXT:    call void @bar(i32 [[Y]])
24; CHECK-NEXT:    ret void
25; CHECK:       neither:
26; CHECK-NEXT:    call void @foo(i1 [[XZ_0]])
27; CHECK-NEXT:    call void @foo(i1 [[YZ_0]])
28; CHECK-NEXT:    call void @bar(i32 [[X_0]])
29; CHECK-NEXT:    call void @bar(i32 [[Y_0]])
30; CHECK-NEXT:    call void @foo(i1 [[Z_0]])
31; CHECK-NEXT:    ret void
32;
33  %xz = icmp eq i32 %x, 0
34  %yz = icmp eq i32 %y, 0
35  %z = or i1 %xz, %yz
36  br i1 %z, label %oneof, label %neither
37oneof:
38;; Should not insert on the true edge for or
39  call void @foo(i1 %xz)
40  call void @foo(i1 %yz)
41  call void @bar(i32 %x)
42  call void @bar(i32 %y)
43  ret void
44neither:
45  call void @foo(i1 %xz)
46  call void @foo(i1 %yz)
47  call void @bar(i32 %x)
48  call void @bar(i32 %y)
49  call void @foo(i1 %z)
50  ret void
51}
52
53define void @test_or_logical(i32 %x, i32 %y) {
54; CHECK-LABEL: @test_or_logical(
55; CHECK-NEXT:    [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
56; CHECK-NEXT:    [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
57; CHECK-NEXT:    [[Z:%.*]] = select i1 [[XZ]], i1 true, i1 [[YZ]]
58; CHECK:         [[Z_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
59; CHECK:         [[XZ_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[XZ]])
60; CHECK:         [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
61; CHECK:         [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[YZ]])
62; CHECK:         [[Y_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
63; CHECK-NEXT:    br i1 [[Z]], label [[ONEOF:%.*]], label [[NEITHER:%.*]]
64; CHECK:       oneof:
65; CHECK-NEXT:    call void @foo(i1 [[XZ]])
66; CHECK-NEXT:    call void @foo(i1 [[YZ]])
67; CHECK-NEXT:    call void @bar(i32 [[X]])
68; CHECK-NEXT:    call void @bar(i32 [[Y]])
69; CHECK-NEXT:    ret void
70; CHECK:       neither:
71; CHECK-NEXT:    call void @foo(i1 [[XZ_0]])
72; CHECK-NEXT:    call void @foo(i1 [[YZ_0]])
73; CHECK-NEXT:    call void @bar(i32 [[X_0]])
74; CHECK-NEXT:    call void @bar(i32 [[Y_0]])
75; CHECK-NEXT:    call void @foo(i1 [[Z_0]])
76; CHECK-NEXT:    ret void
77;
78  %xz = icmp eq i32 %x, 0
79  %yz = icmp eq i32 %y, 0
80  %z = select i1 %xz, i1 true, i1 %yz
81  br i1 %z, label %oneof, label %neither
82oneof:
83;; Should not insert on the true edge for or
84  call void @foo(i1 %xz)
85  call void @foo(i1 %yz)
86  call void @bar(i32 %x)
87  call void @bar(i32 %y)
88  ret void
89neither:
90  call void @foo(i1 %xz)
91  call void @foo(i1 %yz)
92  call void @bar(i32 %x)
93  call void @bar(i32 %y)
94  call void @foo(i1 %z)
95  ret void
96}
97
98define void @test_and(i32 %x, i32 %y) {
99; CHECK-LABEL: @test_and(
100; CHECK-NEXT:    [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
101; CHECK-NEXT:    [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
102; CHECK-NEXT:    [[Z:%.*]] = and i1 [[XZ]], [[YZ]]
103; CHECK:         [[Z_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
104; CHECK:         [[XZ_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[XZ]])
105; CHECK:         [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
106; CHECK:         [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[YZ]])
107; CHECK:         [[Y_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
108; CHECK-NEXT:    br i1 [[Z]], label [[BOTH:%.*]], label [[NOPE:%.*]]
109; CHECK:       both:
110; CHECK-NEXT:    call void @foo(i1 [[XZ_0]])
111; CHECK-NEXT:    call void @foo(i1 [[YZ_0]])
112; CHECK-NEXT:    call void @bar(i32 [[X_0]])
113; CHECK-NEXT:    call void @bar(i32 [[Y_0]])
114; CHECK-NEXT:    ret void
115; CHECK:       nope:
116; CHECK-NEXT:    call void @foo(i1 [[XZ]])
117; CHECK-NEXT:    call void @foo(i1 [[YZ]])
118; CHECK-NEXT:    call void @bar(i32 [[X]])
119; CHECK-NEXT:    call void @bar(i32 [[Y]])
120; CHECK-NEXT:    call void @foo(i1 [[Z_0]])
121; CHECK-NEXT:    ret void
122;
123  %xz = icmp eq i32 %x, 0
124  %yz = icmp eq i32 %y, 0
125  %z = and i1 %xz, %yz
126  br i1 %z, label %both, label %nope
127both:
128  call void @foo(i1 %xz)
129  call void @foo(i1 %yz)
130  call void @bar(i32 %x)
131  call void @bar(i32 %y)
132  ret void
133nope:
134;; Should not insert on the false edge for and
135  call void @foo(i1 %xz)
136  call void @foo(i1 %yz)
137  call void @bar(i32 %x)
138  call void @bar(i32 %y)
139  call void @foo(i1 %z)
140  ret void
141}
142
143define void @test_and_logical(i32 %x, i32 %y) {
144; CHECK-LABEL: @test_and_logical(
145; CHECK-NEXT:    [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
146; CHECK-NEXT:    [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
147; CHECK-NEXT:    [[Z:%.*]] = select i1 [[XZ]], i1 [[YZ]], i1 false
148; CHECK:         [[Z_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
149; CHECK:         [[XZ_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[XZ]])
150; CHECK:         [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
151; CHECK:         [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[YZ]])
152; CHECK:         [[Y_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
153; CHECK-NEXT:    br i1 [[Z]], label [[BOTH:%.*]], label [[NOPE:%.*]]
154; CHECK:       both:
155; CHECK-NEXT:    call void @foo(i1 [[XZ_0]])
156; CHECK-NEXT:    call void @foo(i1 [[YZ_0]])
157; CHECK-NEXT:    call void @bar(i32 [[X_0]])
158; CHECK-NEXT:    call void @bar(i32 [[Y_0]])
159; CHECK-NEXT:    ret void
160; CHECK:       nope:
161; CHECK-NEXT:    call void @foo(i1 [[XZ]])
162; CHECK-NEXT:    call void @foo(i1 [[YZ]])
163; CHECK-NEXT:    call void @bar(i32 [[X]])
164; CHECK-NEXT:    call void @bar(i32 [[Y]])
165; CHECK-NEXT:    call void @foo(i1 [[Z_0]])
166; CHECK-NEXT:    ret void
167;
168  %xz = icmp eq i32 %x, 0
169  %yz = icmp eq i32 %y, 0
170  %z = select i1 %xz, i1 %yz, i1 false
171  br i1 %z, label %both, label %nope
172both:
173  call void @foo(i1 %xz)
174  call void @foo(i1 %yz)
175  call void @bar(i32 %x)
176  call void @bar(i32 %y)
177  ret void
178nope:
179;; Should not insert on the false edge for and
180  call void @foo(i1 %xz)
181  call void @foo(i1 %yz)
182  call void @bar(i32 %x)
183  call void @bar(i32 %y)
184  call void @foo(i1 %z)
185  ret void
186}
187
188define void @testandsame(i32 %x, i32 %y) {
189; CHECK-LABEL: @testandsame(
190; CHECK-NEXT:    [[XGT:%.*]] = icmp sgt i32 [[X:%.*]], 0
191; CHECK-NEXT:    [[XLT:%.*]] = icmp slt i32 [[X]], 100
192; CHECK-NEXT:    [[Z:%.*]] = and i1 [[XGT]], [[XLT]]
193; CHECK:         [[Z_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
194; CHECK:         [[XGT_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[XGT]])
195; CHECK:         [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
196; CHECK:         [[X_0_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X_0]])
197; CHECK:         [[XLT_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[XLT]])
198; CHECK-NEXT:    br i1 [[Z]], label [[BOTH:%.*]], label [[NOPE:%.*]]
199; CHECK:       both:
200; CHECK-NEXT:    call void @foo(i1 [[XGT_0]])
201; CHECK-NEXT:    call void @foo(i1 [[XLT_0]])
202; CHECK-NEXT:    call void @bar(i32 [[X_0_1]])
203; CHECK-NEXT:    ret void
204; CHECK:       nope:
205; CHECK-NEXT:    call void @foo(i1 [[XGT]])
206; CHECK-NEXT:    call void @foo(i1 [[XLT]])
207; CHECK-NEXT:    call void @foo(i1 [[Z_0]])
208; CHECK-NEXT:    ret void
209;
210  %xgt = icmp sgt i32 %x, 0
211  %xlt = icmp slt i32 %x, 100
212  %z = and i1 %xgt, %xlt
213  br i1 %z, label %both, label %nope
214both:
215  call void @foo(i1 %xgt)
216  call void @foo(i1 %xlt)
217  call void @bar(i32 %x)
218  ret void
219nope:
220  call void @foo(i1 %xgt)
221  call void @foo(i1 %xlt)
222  call void @foo(i1 %z)
223  ret void
224}
225
226define void @testandassume(i32 %x, i32 %y) {
227; CHECK-LABEL: @testandassume(
228; CHECK-NEXT:    [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
229; CHECK-NEXT:    [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
230; CHECK-NEXT:    [[Z:%.*]] = and i1 [[XZ]], [[YZ]]
231; CHECK-NEXT:    call void @llvm.assume(i1 [[Z]])
232; CHECK:         [[TMP1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
233; CHECK:         [[TMP2:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[YZ]])
234; CHECK:         [[TMP3:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
235; CHECK:         [[TMP4:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[XZ]])
236; CHECK:         [[TMP5:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
237; CHECK:         [[DOT0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[TMP5]])
238; CHECK:         [[DOT01:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[TMP4]])
239; CHECK:         [[DOT02:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[TMP3]])
240; CHECK:         [[DOT03:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[TMP2]])
241; CHECK:         [[DOT04:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[TMP1]])
242; CHECK-NEXT:    br i1 [[TMP5]], label [[BOTH:%.*]], label [[NOPE:%.*]]
243; CHECK:       both:
244; CHECK-NEXT:    call void @foo(i1 [[DOT01]])
245; CHECK-NEXT:    call void @foo(i1 [[DOT03]])
246; CHECK-NEXT:    call void @bar(i32 [[DOT02]])
247; CHECK-NEXT:    call void @bar(i32 [[DOT04]])
248; CHECK-NEXT:    ret void
249; CHECK:       nope:
250; CHECK-NEXT:    call void @foo(i1 [[DOT0]])
251; CHECK-NEXT:    ret void
252;
253  %xz = icmp eq i32 %x, 0
254  %yz = icmp eq i32 %y, 0
255  %z = and i1 %xz, %yz
256  call void @llvm.assume(i1 %z)
257  br i1 %z, label %both, label %nope
258both:
259  call void @foo(i1 %xz)
260  call void @foo(i1 %yz)
261  call void @bar(i32 %x)
262  call void @bar(i32 %y)
263  ret void
264nope:
265  call void @foo(i1 %z)
266  ret void
267}
268
269;; Unlike and/or for branches, assume is *always* true, so we only match and for it
270define void @testorassume(i32 %x, i32 %y) {
271;
272; CHECK-LABEL: @testorassume(
273; CHECK-NEXT:    [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
274; CHECK-NEXT:    [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
275; CHECK-NEXT:    [[Z:%.*]] = or i1 [[XZ]], [[YZ]]
276; CHECK-NEXT:    call void @llvm.assume(i1 [[Z]])
277; CHECK:         [[TMP1:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
278; CHECK:         [[DOT0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[TMP1]])
279; CHECK-NEXT:    br i1 [[TMP1]], label [[BOTH:%.*]], label [[NOPE:%.*]]
280; CHECK:       both:
281; CHECK-NEXT:    call void @foo(i1 [[XZ]])
282; CHECK-NEXT:    call void @foo(i1 [[YZ]])
283; CHECK-NEXT:    call void @bar(i32 [[X]])
284; CHECK-NEXT:    call void @bar(i32 [[Y]])
285; CHECK-NEXT:    ret void
286; CHECK:       nope:
287; CHECK-NEXT:    call void @foo(i1 [[DOT0]])
288; CHECK-NEXT:    ret void
289;
290  %xz = icmp eq i32 %x, 0
291  %yz = icmp eq i32 %y, 0
292  %z = or i1 %xz, %yz
293  call void @llvm.assume(i1 %z)
294  br i1 %z, label %both, label %nope
295both:
296  call void @foo(i1 %xz)
297  call void @foo(i1 %yz)
298  call void @bar(i32 %x)
299  call void @bar(i32 %y)
300  ret void
301nope:
302  call void @foo(i1 %z)
303  ret void
304}
305
306define void @test_and_one_unknown_cond(i32 %x, i1 %c1) {
307; CHECK-LABEL: @test_and_one_unknown_cond(
308; CHECK-NEXT:    [[C2:%.*]] = icmp eq i32 [[X:%.*]], 0
309; CHECK-NEXT:    [[A:%.*]] = and i1 [[C1:%.*]], [[C2]]
310; CHECK:         [[A_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A]])
311; CHECK:         [[A_1:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A]])
312; CHECK:         [[C1_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[C1]])
313; CHECK:         [[C2_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[C2]])
314; CHECK:         [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
315; CHECK-NEXT:    br i1 [[A]], label [[BOTH:%.*]], label [[NOPE:%.*]]
316; CHECK:       both:
317; CHECK-NEXT:    call void @bar(i32 [[X_0]])
318; CHECK-NEXT:    call void @foo(i1 [[C1_0]])
319; CHECK-NEXT:    call void @foo(i1 [[C2_0]])
320; CHECK-NEXT:    call void @foo(i1 [[A_0]])
321; CHECK-NEXT:    ret void
322; CHECK:       nope:
323; CHECK-NEXT:    call void @bar(i32 [[X]])
324; CHECK-NEXT:    call void @foo(i1 [[C1]])
325; CHECK-NEXT:    call void @foo(i1 [[C2]])
326; CHECK-NEXT:    call void @foo(i1 [[A_1]])
327; CHECK-NEXT:    ret void
328;
329  %c2 = icmp eq i32 %x, 0
330  %a = and i1 %c1, %c2
331  br i1 %a, label %both, label %nope
332
333both:
334  call void @bar(i32 %x)
335  call void @foo(i1 %c1)
336  call void @foo(i1 %c2)
337  call void @foo(i1 %a)
338  ret void
339
340nope:
341  call void @bar(i32 %x)
342  call void @foo(i1 %c1)
343  call void @foo(i1 %c2)
344  call void @foo(i1 %a)
345  ret void
346}
347
348define void @test_or_one_unknown_cond(i32 %x, i1 %c1) {
349; CHECK-LABEL: @test_or_one_unknown_cond(
350; CHECK-NEXT:    [[C2:%.*]] = icmp eq i32 [[X:%.*]], 0
351; CHECK-NEXT:    [[A:%.*]] = or i1 [[C1:%.*]], [[C2]]
352; CHECK:         [[A_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A]])
353; CHECK:         [[A_1:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A]])
354; CHECK:         [[C1_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[C1]])
355; CHECK:         [[C2_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[C2]])
356; CHECK:         [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
357; CHECK-NEXT:    br i1 [[A]], label [[NOPE:%.*]], label [[BOTH_INVERTED:%.*]]
358; CHECK:       both_inverted:
359; CHECK-NEXT:    call void @bar(i32 [[X_0]])
360; CHECK-NEXT:    call void @foo(i1 [[C1_0]])
361; CHECK-NEXT:    call void @foo(i1 [[C2_0]])
362; CHECK-NEXT:    call void @foo(i1 [[A_1]])
363; CHECK-NEXT:    ret void
364; CHECK:       nope:
365; CHECK-NEXT:    call void @bar(i32 [[X]])
366; CHECK-NEXT:    call void @foo(i1 [[C1]])
367; CHECK-NEXT:    call void @foo(i1 [[C2]])
368; CHECK-NEXT:    call void @foo(i1 [[A_0]])
369; CHECK-NEXT:    ret void
370;
371  %c2 = icmp eq i32 %x, 0
372  %a = or i1 %c1, %c2
373  br i1 %a, label %nope, label %both_inverted
374
375both_inverted:
376  call void @bar(i32 %x)
377  call void @foo(i1 %c1)
378  call void @foo(i1 %c2)
379  call void @foo(i1 %a)
380  ret void
381
382nope:
383  call void @bar(i32 %x)
384  call void @foo(i1 %c1)
385  call void @foo(i1 %c2)
386  call void @foo(i1 %a)
387  ret void
388}
389
390define void @test_and_chain(i1 %a, i1 %b, i1 %c) {
391; CHECK-LABEL: @test_and_chain(
392; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[A:%.*]], [[B:%.*]]
393; CHECK-NEXT:    [[AND2:%.*]] = and i1 [[AND1]], [[C:%.*]]
394; CHECK:         [[AND2_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[AND2]])
395; CHECK:         [[AND2_1:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[AND2]])
396; CHECK:         [[AND1_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[AND1]])
397; CHECK:         [[A_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A]])
398; CHECK:         [[B_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[B]])
399; CHECK:         [[C_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[C]])
400; CHECK-NEXT:    br i1 [[AND2]], label [[IF:%.*]], label [[ELSE:%.*]]
401; CHECK:       if:
402; CHECK-NEXT:    call void @foo(i1 [[A_0]])
403; CHECK-NEXT:    call void @foo(i1 [[B_0]])
404; CHECK-NEXT:    call void @foo(i1 [[C_0]])
405; CHECK-NEXT:    call void @foo(i1 [[AND1_0]])
406; CHECK-NEXT:    call void @foo(i1 [[AND2_0]])
407; CHECK-NEXT:    ret void
408; CHECK:       else:
409; CHECK-NEXT:    call void @foo(i1 [[A]])
410; CHECK-NEXT:    call void @foo(i1 [[B]])
411; CHECK-NEXT:    call void @foo(i1 [[C]])
412; CHECK-NEXT:    call void @foo(i1 [[AND1]])
413; CHECK-NEXT:    call void @foo(i1 [[AND2_1]])
414; CHECK-NEXT:    ret void
415;
416  %and1 = and i1 %a, %b
417  %and2 = and i1 %and1, %c
418  br i1 %and2, label %if, label %else
419
420if:
421  call void @foo(i1 %a)
422  call void @foo(i1 %b)
423  call void @foo(i1 %c)
424  call void @foo(i1 %and1)
425  call void @foo(i1 %and2)
426  ret void
427
428else:
429  call void @foo(i1 %a)
430  call void @foo(i1 %b)
431  call void @foo(i1 %c)
432  call void @foo(i1 %and1)
433  call void @foo(i1 %and2)
434  ret void
435}
436
437define void @test_or_chain(i1 %a, i1 %b, i1 %c) {
438; CHECK-LABEL: @test_or_chain(
439; CHECK-NEXT:    [[OR1:%.*]] = or i1 [[A:%.*]], [[B:%.*]]
440; CHECK-NEXT:    [[OR2:%.*]] = or i1 [[OR1]], [[C:%.*]]
441; CHECK:         [[OR2_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[OR2]])
442; CHECK:         [[OR2_1:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[OR2]])
443; CHECK:         [[OR1_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[OR1]])
444; CHECK:         [[A_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A]])
445; CHECK:         [[B_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[B]])
446; CHECK:         [[C_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[C]])
447; CHECK-NEXT:    br i1 [[OR2]], label [[IF:%.*]], label [[ELSE:%.*]]
448; CHECK:       if:
449; CHECK-NEXT:    call void @foo(i1 [[A]])
450; CHECK-NEXT:    call void @foo(i1 [[B]])
451; CHECK-NEXT:    call void @foo(i1 [[C]])
452; CHECK-NEXT:    call void @foo(i1 [[OR1]])
453; CHECK-NEXT:    call void @foo(i1 [[OR2_0]])
454; CHECK-NEXT:    ret void
455; CHECK:       else:
456; CHECK-NEXT:    call void @foo(i1 [[A_0]])
457; CHECK-NEXT:    call void @foo(i1 [[B_0]])
458; CHECK-NEXT:    call void @foo(i1 [[C_0]])
459; CHECK-NEXT:    call void @foo(i1 [[OR1_0]])
460; CHECK-NEXT:    call void @foo(i1 [[OR2_1]])
461; CHECK-NEXT:    ret void
462;
463  %or1 = or i1 %a, %b
464  %or2 = or i1 %or1, %c
465  br i1 %or2, label %if, label %else
466
467if:
468  call void @foo(i1 %a)
469  call void @foo(i1 %b)
470  call void @foo(i1 %c)
471  call void @foo(i1 %or1)
472  call void @foo(i1 %or2)
473  ret void
474
475else:
476  call void @foo(i1 %a)
477  call void @foo(i1 %b)
478  call void @foo(i1 %c)
479  call void @foo(i1 %or1)
480  call void @foo(i1 %or2)
481  ret void
482}
483
484define void @test_and_or_mixed(i1 %a, i1 %b, i1 %c) {
485; CHECK-LABEL: @test_and_or_mixed(
486; CHECK-NEXT:    [[OR:%.*]] = or i1 [[A:%.*]], [[B:%.*]]
487; CHECK-NEXT:    [[AND:%.*]] = and i1 [[OR]], [[C:%.*]]
488; CHECK:         [[AND_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[AND]])
489; CHECK:         [[AND_1:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[AND]])
490; CHECK:         [[OR_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[OR]])
491; CHECK:         [[C_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[C]])
492; CHECK-NEXT:    br i1 [[AND]], label [[IF:%.*]], label [[ELSE:%.*]]
493; CHECK:       if:
494; CHECK-NEXT:    call void @foo(i1 [[A]])
495; CHECK-NEXT:    call void @foo(i1 [[B]])
496; CHECK-NEXT:    call void @foo(i1 [[C_0]])
497; CHECK-NEXT:    call void @foo(i1 [[OR_0]])
498; CHECK-NEXT:    call void @foo(i1 [[AND_0]])
499; CHECK-NEXT:    ret void
500; CHECK:       else:
501; CHECK-NEXT:    call void @foo(i1 [[A]])
502; CHECK-NEXT:    call void @foo(i1 [[B]])
503; CHECK-NEXT:    call void @foo(i1 [[C]])
504; CHECK-NEXT:    call void @foo(i1 [[OR]])
505; CHECK-NEXT:    call void @foo(i1 [[AND_1]])
506; CHECK-NEXT:    ret void
507;
508  %or = or i1 %a, %b
509  %and = and i1 %or, %c
510  br i1 %and, label %if, label %else
511
512if:
513  call void @foo(i1 %a)
514  call void @foo(i1 %b)
515  call void @foo(i1 %c)
516  call void @foo(i1 %or)
517  call void @foo(i1 %and)
518  ret void
519
520else:
521  call void @foo(i1 %a)
522  call void @foo(i1 %b)
523  call void @foo(i1 %c)
524  call void @foo(i1 %or)
525  call void @foo(i1 %and)
526  ret void
527}
528
529define void @test_deep_and_chain(i1 %a1) {
530; CHECK-LABEL: @test_deep_and_chain(
531; CHECK-NEXT:    [[A2:%.*]] = and i1 [[A1:%.*]], true
532; CHECK-NEXT:    [[A3:%.*]] = and i1 [[A2]], true
533; CHECK-NEXT:    [[A4:%.*]] = and i1 [[A3]], true
534; CHECK-NEXT:    [[A5:%.*]] = and i1 [[A4]], true
535; CHECK-NEXT:    [[A6:%.*]] = and i1 [[A5]], true
536; CHECK-NEXT:    [[A7:%.*]] = and i1 [[A6]], true
537; CHECK-NEXT:    [[A8:%.*]] = and i1 [[A7]], true
538; CHECK-NEXT:    [[A9:%.*]] = and i1 [[A8]], true
539; CHECK-NEXT:    [[A10:%.*]] = and i1 [[A9]], true
540; CHECK-NEXT:    [[A11:%.*]] = and i1 [[A10]], true
541; CHECK-NEXT:    [[A12:%.*]] = and i1 [[A11]], true
542; CHECK-NEXT:    [[A13:%.*]] = and i1 [[A12]], true
543; CHECK-NEXT:    [[A14:%.*]] = and i1 [[A13]], true
544; CHECK-NEXT:    [[A15:%.*]] = and i1 [[A14]], true
545; CHECK:         [[A15_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A15]])
546; CHECK:         [[A15_1:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A15]])
547; CHECK:         [[A14_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A14]])
548; CHECK:         [[A13_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A13]])
549; CHECK:         [[A12_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A12]])
550; CHECK:         [[A11_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A11]])
551; CHECK:         [[A10_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A10]])
552; CHECK:         [[A9_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A9]])
553; CHECK:         [[A8_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A8]])
554; CHECK-NEXT:    br i1 [[A15]], label [[IF:%.*]], label [[ELSE:%.*]]
555; CHECK:       if:
556; CHECK-NEXT:    call void @foo(i1 [[A1]])
557; CHECK-NEXT:    call void @foo(i1 [[A2]])
558; CHECK-NEXT:    call void @foo(i1 [[A3]])
559; CHECK-NEXT:    call void @foo(i1 [[A4]])
560; CHECK-NEXT:    call void @foo(i1 [[A5]])
561; CHECK-NEXT:    call void @foo(i1 [[A6]])
562; CHECK-NEXT:    call void @foo(i1 [[A7]])
563; CHECK-NEXT:    call void @foo(i1 [[A8_0]])
564; CHECK-NEXT:    call void @foo(i1 [[A9_0]])
565; CHECK-NEXT:    call void @foo(i1 [[A10_0]])
566; CHECK-NEXT:    call void @foo(i1 [[A11_0]])
567; CHECK-NEXT:    call void @foo(i1 [[A12_0]])
568; CHECK-NEXT:    call void @foo(i1 [[A13_0]])
569; CHECK-NEXT:    call void @foo(i1 [[A14_0]])
570; CHECK-NEXT:    call void @foo(i1 [[A15_0]])
571; CHECK-NEXT:    ret void
572; CHECK:       else:
573; CHECK-NEXT:    call void @foo(i1 [[A1]])
574; CHECK-NEXT:    call void @foo(i1 [[A2]])
575; CHECK-NEXT:    call void @foo(i1 [[A3]])
576; CHECK-NEXT:    call void @foo(i1 [[A4]])
577; CHECK-NEXT:    call void @foo(i1 [[A5]])
578; CHECK-NEXT:    call void @foo(i1 [[A6]])
579; CHECK-NEXT:    call void @foo(i1 [[A7]])
580; CHECK-NEXT:    call void @foo(i1 [[A8]])
581; CHECK-NEXT:    call void @foo(i1 [[A9]])
582; CHECK-NEXT:    call void @foo(i1 [[A10]])
583; CHECK-NEXT:    call void @foo(i1 [[A11]])
584; CHECK-NEXT:    call void @foo(i1 [[A12]])
585; CHECK-NEXT:    call void @foo(i1 [[A13]])
586; CHECK-NEXT:    call void @foo(i1 [[A14]])
587; CHECK-NEXT:    call void @foo(i1 [[A15_1]])
588; CHECK-NEXT:    ret void
589;
590  %a2 = and i1 %a1, true
591  %a3 = and i1 %a2, true
592  %a4 = and i1 %a3, true
593  %a5 = and i1 %a4, true
594  %a6 = and i1 %a5, true
595  %a7 = and i1 %a6, true
596  %a8 = and i1 %a7, true
597  %a9 = and i1 %a8, true
598  %a10 = and i1 %a9, true
599  %a11 = and i1 %a10, true
600  %a12 = and i1 %a11, true
601  %a13 = and i1 %a12, true
602  %a14 = and i1 %a13, true
603  %a15 = and i1 %a14, true
604  br i1 %a15, label %if, label %else
605
606if:
607  call void @foo(i1 %a1)
608  call void @foo(i1 %a2)
609  call void @foo(i1 %a3)
610  call void @foo(i1 %a4)
611  call void @foo(i1 %a5)
612  call void @foo(i1 %a6)
613  call void @foo(i1 %a7)
614  call void @foo(i1 %a8)
615  call void @foo(i1 %a9)
616  call void @foo(i1 %a10)
617  call void @foo(i1 %a11)
618  call void @foo(i1 %a12)
619  call void @foo(i1 %a13)
620  call void @foo(i1 %a14)
621  call void @foo(i1 %a15)
622  ret void
623
624else:
625  call void @foo(i1 %a1)
626  call void @foo(i1 %a2)
627  call void @foo(i1 %a3)
628  call void @foo(i1 %a4)
629  call void @foo(i1 %a5)
630  call void @foo(i1 %a6)
631  call void @foo(i1 %a7)
632  call void @foo(i1 %a8)
633  call void @foo(i1 %a9)
634  call void @foo(i1 %a10)
635  call void @foo(i1 %a11)
636  call void @foo(i1 %a12)
637  call void @foo(i1 %a13)
638  call void @foo(i1 %a14)
639  call void @foo(i1 %a15)
640  ret void
641}
642
643define void @test_deep_and_tree(i1 %a1) {
644; CHECK-LABEL: @test_deep_and_tree(
645; CHECK-NEXT:    [[A2:%.*]] = and i1 [[A1:%.*]], [[A1]]
646; CHECK-NEXT:    [[A3:%.*]] = and i1 [[A2]], [[A2]]
647; CHECK-NEXT:    [[A4:%.*]] = and i1 [[A3]], [[A3]]
648; CHECK-NEXT:    [[A5:%.*]] = and i1 [[A4]], [[A4]]
649; CHECK-NEXT:    [[A6:%.*]] = and i1 [[A5]], [[A5]]
650; CHECK-NEXT:    [[A7:%.*]] = and i1 [[A6]], [[A6]]
651; CHECK-NEXT:    [[A8:%.*]] = and i1 [[A7]], [[A7]]
652; CHECK-NEXT:    [[A9:%.*]] = and i1 [[A8]], [[A8]]
653; CHECK-NEXT:    [[A10:%.*]] = and i1 [[A9]], [[A9]]
654; CHECK-NEXT:    [[A11:%.*]] = and i1 [[A10]], [[A10]]
655; CHECK-NEXT:    [[A12:%.*]] = and i1 [[A11]], [[A11]]
656; CHECK-NEXT:    [[A13:%.*]] = and i1 [[A12]], [[A12]]
657; CHECK-NEXT:    [[A14:%.*]] = and i1 [[A13]], [[A13]]
658; CHECK-NEXT:    [[A15:%.*]] = and i1 [[A14]], [[A14]]
659; CHECK:         [[A15_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A15]])
660; CHECK:         [[A15_1:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A15]])
661; CHECK:         [[A14_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A14]])
662; CHECK:         [[A13_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A13]])
663; CHECK:         [[A12_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A12]])
664; CHECK:         [[A11_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A11]])
665; CHECK:         [[A10_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A10]])
666; CHECK:         [[A9_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A9]])
667; CHECK:         [[A8_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A8]])
668; CHECK-NEXT:    br i1 [[A15]], label [[IF:%.*]], label [[ELSE:%.*]]
669; CHECK:       if:
670; CHECK-NEXT:    call void @foo(i1 [[A1]])
671; CHECK-NEXT:    call void @foo(i1 [[A2]])
672; CHECK-NEXT:    call void @foo(i1 [[A3]])
673; CHECK-NEXT:    call void @foo(i1 [[A4]])
674; CHECK-NEXT:    call void @foo(i1 [[A5]])
675; CHECK-NEXT:    call void @foo(i1 [[A6]])
676; CHECK-NEXT:    call void @foo(i1 [[A7]])
677; CHECK-NEXT:    call void @foo(i1 [[A8_0]])
678; CHECK-NEXT:    call void @foo(i1 [[A9_0]])
679; CHECK-NEXT:    call void @foo(i1 [[A10_0]])
680; CHECK-NEXT:    call void @foo(i1 [[A11_0]])
681; CHECK-NEXT:    call void @foo(i1 [[A12_0]])
682; CHECK-NEXT:    call void @foo(i1 [[A13_0]])
683; CHECK-NEXT:    call void @foo(i1 [[A14_0]])
684; CHECK-NEXT:    call void @foo(i1 [[A15_0]])
685; CHECK-NEXT:    ret void
686; CHECK:       else:
687; CHECK-NEXT:    call void @foo(i1 [[A1]])
688; CHECK-NEXT:    call void @foo(i1 [[A2]])
689; CHECK-NEXT:    call void @foo(i1 [[A3]])
690; CHECK-NEXT:    call void @foo(i1 [[A4]])
691; CHECK-NEXT:    call void @foo(i1 [[A5]])
692; CHECK-NEXT:    call void @foo(i1 [[A6]])
693; CHECK-NEXT:    call void @foo(i1 [[A7]])
694; CHECK-NEXT:    call void @foo(i1 [[A8]])
695; CHECK-NEXT:    call void @foo(i1 [[A9]])
696; CHECK-NEXT:    call void @foo(i1 [[A10]])
697; CHECK-NEXT:    call void @foo(i1 [[A11]])
698; CHECK-NEXT:    call void @foo(i1 [[A12]])
699; CHECK-NEXT:    call void @foo(i1 [[A13]])
700; CHECK-NEXT:    call void @foo(i1 [[A14]])
701; CHECK-NEXT:    call void @foo(i1 [[A15_1]])
702; CHECK-NEXT:    ret void
703;
704  %a2 = and i1 %a1, %a1
705  %a3 = and i1 %a2, %a2
706  %a4 = and i1 %a3, %a3
707  %a5 = and i1 %a4, %a4
708  %a6 = and i1 %a5, %a5
709  %a7 = and i1 %a6, %a6
710  %a8 = and i1 %a7, %a7
711  %a9 = and i1 %a8, %a8
712  %a10 = and i1 %a9, %a9
713  %a11 = and i1 %a10, %a10
714  %a12 = and i1 %a11, %a11
715  %a13 = and i1 %a12, %a12
716  %a14 = and i1 %a13, %a13
717  %a15 = and i1 %a14, %a14
718  br i1 %a15, label %if, label %else
719
720if:
721  call void @foo(i1 %a1)
722  call void @foo(i1 %a2)
723  call void @foo(i1 %a3)
724  call void @foo(i1 %a4)
725  call void @foo(i1 %a5)
726  call void @foo(i1 %a6)
727  call void @foo(i1 %a7)
728  call void @foo(i1 %a8)
729  call void @foo(i1 %a9)
730  call void @foo(i1 %a10)
731  call void @foo(i1 %a11)
732  call void @foo(i1 %a12)
733  call void @foo(i1 %a13)
734  call void @foo(i1 %a14)
735  call void @foo(i1 %a15)
736  ret void
737
738else:
739  call void @foo(i1 %a1)
740  call void @foo(i1 %a2)
741  call void @foo(i1 %a3)
742  call void @foo(i1 %a4)
743  call void @foo(i1 %a5)
744  call void @foo(i1 %a6)
745  call void @foo(i1 %a7)
746  call void @foo(i1 %a8)
747  call void @foo(i1 %a9)
748  call void @foo(i1 %a10)
749  call void @foo(i1 %a11)
750  call void @foo(i1 %a12)
751  call void @foo(i1 %a13)
752  call void @foo(i1 %a14)
753  call void @foo(i1 %a15)
754  ret void
755}
756
757define void @test_deep_or_tree(i1 %a1) {
758; CHECK-LABEL: @test_deep_or_tree(
759; CHECK-NEXT:    [[A2:%.*]] = or i1 [[A1:%.*]], [[A1]]
760; CHECK-NEXT:    [[A3:%.*]] = or i1 [[A2]], [[A2]]
761; CHECK-NEXT:    [[A4:%.*]] = or i1 [[A3]], [[A3]]
762; CHECK-NEXT:    [[A5:%.*]] = or i1 [[A4]], [[A4]]
763; CHECK-NEXT:    [[A6:%.*]] = or i1 [[A5]], [[A5]]
764; CHECK-NEXT:    [[A7:%.*]] = or i1 [[A6]], [[A6]]
765; CHECK-NEXT:    [[A8:%.*]] = or i1 [[A7]], [[A7]]
766; CHECK-NEXT:    [[A9:%.*]] = or i1 [[A8]], [[A8]]
767; CHECK-NEXT:    [[A10:%.*]] = or i1 [[A9]], [[A9]]
768; CHECK-NEXT:    [[A11:%.*]] = or i1 [[A10]], [[A10]]
769; CHECK-NEXT:    [[A12:%.*]] = or i1 [[A11]], [[A11]]
770; CHECK-NEXT:    [[A13:%.*]] = or i1 [[A12]], [[A12]]
771; CHECK-NEXT:    [[A14:%.*]] = or i1 [[A13]], [[A13]]
772; CHECK-NEXT:    [[A15:%.*]] = or i1 [[A14]], [[A14]]
773; CHECK:         [[A15_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A15]])
774; CHECK:         [[A15_1:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A15]])
775; CHECK:         [[A14_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A14]])
776; CHECK:         [[A13_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A13]])
777; CHECK:         [[A12_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A12]])
778; CHECK:         [[A11_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A11]])
779; CHECK:         [[A10_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A10]])
780; CHECK:         [[A9_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A9]])
781; CHECK:         [[A8_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A8]])
782; CHECK-NEXT:    br i1 [[A15]], label [[IF:%.*]], label [[ELSE:%.*]]
783; CHECK:       if:
784; CHECK-NEXT:    call void @foo(i1 [[A1]])
785; CHECK-NEXT:    call void @foo(i1 [[A2]])
786; CHECK-NEXT:    call void @foo(i1 [[A3]])
787; CHECK-NEXT:    call void @foo(i1 [[A4]])
788; CHECK-NEXT:    call void @foo(i1 [[A5]])
789; CHECK-NEXT:    call void @foo(i1 [[A6]])
790; CHECK-NEXT:    call void @foo(i1 [[A7]])
791; CHECK-NEXT:    call void @foo(i1 [[A8]])
792; CHECK-NEXT:    call void @foo(i1 [[A9]])
793; CHECK-NEXT:    call void @foo(i1 [[A10]])
794; CHECK-NEXT:    call void @foo(i1 [[A11]])
795; CHECK-NEXT:    call void @foo(i1 [[A12]])
796; CHECK-NEXT:    call void @foo(i1 [[A13]])
797; CHECK-NEXT:    call void @foo(i1 [[A14]])
798; CHECK-NEXT:    call void @foo(i1 [[A15_0]])
799; CHECK-NEXT:    ret void
800; CHECK:       else:
801; CHECK-NEXT:    call void @foo(i1 [[A1]])
802; CHECK-NEXT:    call void @foo(i1 [[A2]])
803; CHECK-NEXT:    call void @foo(i1 [[A3]])
804; CHECK-NEXT:    call void @foo(i1 [[A4]])
805; CHECK-NEXT:    call void @foo(i1 [[A5]])
806; CHECK-NEXT:    call void @foo(i1 [[A6]])
807; CHECK-NEXT:    call void @foo(i1 [[A7]])
808; CHECK-NEXT:    call void @foo(i1 [[A8_0]])
809; CHECK-NEXT:    call void @foo(i1 [[A9_0]])
810; CHECK-NEXT:    call void @foo(i1 [[A10_0]])
811; CHECK-NEXT:    call void @foo(i1 [[A11_0]])
812; CHECK-NEXT:    call void @foo(i1 [[A12_0]])
813; CHECK-NEXT:    call void @foo(i1 [[A13_0]])
814; CHECK-NEXT:    call void @foo(i1 [[A14_0]])
815; CHECK-NEXT:    call void @foo(i1 [[A15_1]])
816; CHECK-NEXT:    ret void
817;
818  %a2 = or i1 %a1, %a1
819  %a3 = or i1 %a2, %a2
820  %a4 = or i1 %a3, %a3
821  %a5 = or i1 %a4, %a4
822  %a6 = or i1 %a5, %a5
823  %a7 = or i1 %a6, %a6
824  %a8 = or i1 %a7, %a7
825  %a9 = or i1 %a8, %a8
826  %a10 = or i1 %a9, %a9
827  %a11 = or i1 %a10, %a10
828  %a12 = or i1 %a11, %a11
829  %a13 = or i1 %a12, %a12
830  %a14 = or i1 %a13, %a13
831  %a15 = or i1 %a14, %a14
832  br i1 %a15, label %if, label %else
833
834if:
835  call void @foo(i1 %a1)
836  call void @foo(i1 %a2)
837  call void @foo(i1 %a3)
838  call void @foo(i1 %a4)
839  call void @foo(i1 %a5)
840  call void @foo(i1 %a6)
841  call void @foo(i1 %a7)
842  call void @foo(i1 %a8)
843  call void @foo(i1 %a9)
844  call void @foo(i1 %a10)
845  call void @foo(i1 %a11)
846  call void @foo(i1 %a12)
847  call void @foo(i1 %a13)
848  call void @foo(i1 %a14)
849  call void @foo(i1 %a15)
850  ret void
851
852else:
853  call void @foo(i1 %a1)
854  call void @foo(i1 %a2)
855  call void @foo(i1 %a3)
856  call void @foo(i1 %a4)
857  call void @foo(i1 %a5)
858  call void @foo(i1 %a6)
859  call void @foo(i1 %a7)
860  call void @foo(i1 %a8)
861  call void @foo(i1 %a9)
862  call void @foo(i1 %a10)
863  call void @foo(i1 %a11)
864  call void @foo(i1 %a12)
865  call void @foo(i1 %a13)
866  call void @foo(i1 %a14)
867  call void @foo(i1 %a15)
868  ret void
869}
870
871define void @test_assume_and_chain(i1 %a, i1 %b, i1 %c) {
872; CHECK-LABEL: @test_assume_and_chain(
873; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[A:%.*]], [[B:%.*]]
874; CHECK-NEXT:    [[AND2:%.*]] = and i1 [[AND1]], [[C:%.*]]
875; CHECK-NEXT:    call void @llvm.assume(i1 [[AND2]])
876; CHECK:         [[TMP1:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[C]])
877; CHECK:         [[TMP2:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[B]])
878; CHECK:         [[TMP3:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A]])
879; CHECK:         [[TMP4:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[AND1]])
880; CHECK:         [[TMP5:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[AND2]])
881; CHECK-NEXT:    call void @foo(i1 [[TMP3]])
882; CHECK-NEXT:    call void @foo(i1 [[TMP2]])
883; CHECK-NEXT:    call void @foo(i1 [[TMP1]])
884; CHECK-NEXT:    call void @foo(i1 [[TMP4]])
885; CHECK-NEXT:    call void @foo(i1 [[TMP5]])
886; CHECK-NEXT:    ret void
887;
888  %and1 = and i1 %a, %b
889  %and2 = and i1 %and1, %c
890  call void @llvm.assume(i1 %and2)
891  call void @foo(i1 %a)
892  call void @foo(i1 %b)
893  call void @foo(i1 %c)
894  call void @foo(i1 %and1)
895  call void @foo(i1 %and2)
896  ret void
897}
898
899define void @test_assume_or_chain(i1 %a, i1 %b, i1 %c) {
900; CHECK-LABEL: @test_assume_or_chain(
901; CHECK-NEXT:    [[OR1:%.*]] = or i1 [[A:%.*]], [[B:%.*]]
902; CHECK-NEXT:    [[OR2:%.*]] = or i1 [[OR1]], [[C:%.*]]
903; CHECK-NEXT:    call void @llvm.assume(i1 [[OR2]])
904; CHECK:         [[TMP1:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[OR2]])
905; CHECK-NEXT:    call void @foo(i1 [[A]])
906; CHECK-NEXT:    call void @foo(i1 [[B]])
907; CHECK-NEXT:    call void @foo(i1 [[C]])
908; CHECK-NEXT:    call void @foo(i1 [[OR1]])
909; CHECK-NEXT:    call void @foo(i1 [[TMP1]])
910; CHECK-NEXT:    ret void
911;
912  %or1 = or i1 %a, %b
913  %or2 = or i1 %or1, %c
914  call void @llvm.assume(i1 %or2)
915  call void @foo(i1 %a)
916  call void @foo(i1 %b)
917  call void @foo(i1 %c)
918  call void @foo(i1 %or1)
919  call void @foo(i1 %or2)
920  ret void
921}
922
923define void @test_assume_deep_and_tree(i1 %a1) {
924; CHECK-LABEL: @test_assume_deep_and_tree(
925; CHECK-NEXT:    [[A2:%.*]] = and i1 [[A1:%.*]], [[A1]]
926; CHECK-NEXT:    [[A3:%.*]] = and i1 [[A2]], [[A2]]
927; CHECK-NEXT:    [[A4:%.*]] = and i1 [[A3]], [[A3]]
928; CHECK-NEXT:    [[A5:%.*]] = and i1 [[A4]], [[A4]]
929; CHECK-NEXT:    [[A6:%.*]] = and i1 [[A5]], [[A5]]
930; CHECK-NEXT:    [[A7:%.*]] = and i1 [[A6]], [[A6]]
931; CHECK-NEXT:    [[A8:%.*]] = and i1 [[A7]], [[A7]]
932; CHECK-NEXT:    [[A9:%.*]] = and i1 [[A8]], [[A8]]
933; CHECK-NEXT:    [[A10:%.*]] = and i1 [[A9]], [[A9]]
934; CHECK-NEXT:    [[A11:%.*]] = and i1 [[A10]], [[A10]]
935; CHECK-NEXT:    [[A12:%.*]] = and i1 [[A11]], [[A11]]
936; CHECK-NEXT:    [[A13:%.*]] = and i1 [[A12]], [[A12]]
937; CHECK-NEXT:    [[A14:%.*]] = and i1 [[A13]], [[A13]]
938; CHECK-NEXT:    [[A15:%.*]] = and i1 [[A14]], [[A14]]
939; CHECK-NEXT:    call void @llvm.assume(i1 [[A15]])
940; CHECK:         [[TMP1:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A8]])
941; CHECK:         [[TMP2:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A9]])
942; CHECK:         [[TMP3:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A10]])
943; CHECK:         [[TMP4:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A11]])
944; CHECK:         [[TMP5:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A12]])
945; CHECK:         [[TMP6:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A13]])
946; CHECK:         [[TMP7:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A14]])
947; CHECK:         [[TMP8:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[A15]])
948; CHECK-NEXT:    call void @foo(i1 [[A1]])
949; CHECK-NEXT:    call void @foo(i1 [[A2]])
950; CHECK-NEXT:    call void @foo(i1 [[A3]])
951; CHECK-NEXT:    call void @foo(i1 [[A4]])
952; CHECK-NEXT:    call void @foo(i1 [[A5]])
953; CHECK-NEXT:    call void @foo(i1 [[A6]])
954; CHECK-NEXT:    call void @foo(i1 [[A7]])
955; CHECK-NEXT:    call void @foo(i1 [[TMP1]])
956; CHECK-NEXT:    call void @foo(i1 [[TMP2]])
957; CHECK-NEXT:    call void @foo(i1 [[TMP3]])
958; CHECK-NEXT:    call void @foo(i1 [[TMP4]])
959; CHECK-NEXT:    call void @foo(i1 [[TMP5]])
960; CHECK-NEXT:    call void @foo(i1 [[TMP6]])
961; CHECK-NEXT:    call void @foo(i1 [[TMP7]])
962; CHECK-NEXT:    call void @foo(i1 [[TMP8]])
963; CHECK-NEXT:    ret void
964;
965  %a2 = and i1 %a1, %a1
966  %a3 = and i1 %a2, %a2
967  %a4 = and i1 %a3, %a3
968  %a5 = and i1 %a4, %a4
969  %a6 = and i1 %a5, %a5
970  %a7 = and i1 %a6, %a6
971  %a8 = and i1 %a7, %a7
972  %a9 = and i1 %a8, %a8
973  %a10 = and i1 %a9, %a9
974  %a11 = and i1 %a10, %a10
975  %a12 = and i1 %a11, %a11
976  %a13 = and i1 %a12, %a12
977  %a14 = and i1 %a13, %a13
978  %a15 = and i1 %a14, %a14
979  call void @llvm.assume(i1 %a15)
980  call void @foo(i1 %a1)
981  call void @foo(i1 %a2)
982  call void @foo(i1 %a3)
983  call void @foo(i1 %a4)
984  call void @foo(i1 %a5)
985  call void @foo(i1 %a6)
986  call void @foo(i1 %a7)
987  call void @foo(i1 %a8)
988  call void @foo(i1 %a9)
989  call void @foo(i1 %a10)
990  call void @foo(i1 %a11)
991  call void @foo(i1 %a12)
992  call void @foo(i1 %a13)
993  call void @foo(i1 %a14)
994  call void @foo(i1 %a15)
995  ret void
996}
997