xref: /llvm-project/llvm/test/Analysis/ScalarEvolution/symbolic_max_exit_count.ll (revision 0d38f21e4ab7fe7cebe76a9d7c218ec54dba1e98)
1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
2; RUN: opt -disable-output "-passes=print<scalar-evolution>" < %s 2>&1 | FileCheck %s
3
4declare i1 @cond()
5
6define i32 @test_simple_case(i32 %start, i32 %len) {
7; CHECK-LABEL: 'test_simple_case'
8; CHECK-NEXT:  Classifying expressions for: @test_simple_case
9; CHECK-NEXT:    %iv = phi i32 [ %start, %entry ], [ %iv.next, %backedge ]
10; CHECK-NEXT:    --> {%start,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
11; CHECK-NEXT:    %iv.minus.1 = add i32 %iv, -1
12; CHECK-NEXT:    --> {(-1 + %start),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
13; CHECK-NEXT:    %iv.next = add i32 %iv, -1
14; CHECK-NEXT:    --> {(-1 + %start),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
15; CHECK-NEXT:    %loop_cond = call i1 @cond()
16; CHECK-NEXT:    --> %loop_cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
17; CHECK-NEXT:  Determining loop execution counts for: @test_simple_case
18; CHECK-NEXT:  Loop %loop: <multiple exits> Unpredictable backedge-taken count.
19; CHECK-NEXT:    exit count for loop: %start
20; CHECK-NEXT:    exit count for range_check_block: ***COULDNOTCOMPUTE***
21; CHECK-NEXT:    exit count for backedge: ***COULDNOTCOMPUTE***
22; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i32 -1
23; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is %start
24; CHECK-NEXT:    symbolic max exit count for loop: %start
25; CHECK-NEXT:    symbolic max exit count for range_check_block: ***COULDNOTCOMPUTE***
26; CHECK-NEXT:    symbolic max exit count for backedge: ***COULDNOTCOMPUTE***
27;
28entry:
29  br label %loop
30
31loop:
32  %iv = phi i32 [%start, %entry], [%iv.next, %backedge]
33  %zero_check = icmp ne i32 %iv, 0
34  br i1 %zero_check, label %range_check_block, label %failed_1
35
36range_check_block:
37  %iv.minus.1 = add i32 %iv, -1
38  %range_check = icmp ult i32 %iv.minus.1, %len
39  br i1 %range_check, label %backedge, label %failed_2
40
41backedge:
42  %iv.next = add i32 %iv, -1
43  %loop_cond = call i1 @cond()
44  br i1 %loop_cond, label %done, label %loop
45
46done:
47  ret i32 %iv
48
49failed_1:
50  ret i32 -1
51
52failed_2:
53  ret i32 -2
54}
55
56define i32 @test_litter_conditions(i32 %start, i32 %len) {
57; CHECK-LABEL: 'test_litter_conditions'
58; CHECK-NEXT:  Classifying expressions for: @test_litter_conditions
59; CHECK-NEXT:    %iv = phi i32 [ %start, %entry ], [ %iv.next, %backedge ]
60; CHECK-NEXT:    --> {%start,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
61; CHECK-NEXT:    %fake_1 = call i1 @cond()
62; CHECK-NEXT:    --> %fake_1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
63; CHECK-NEXT:    %and_1 = and i1 %zero_check, %fake_1
64; CHECK-NEXT:    --> (%zero_check umin %fake_1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
65; CHECK-NEXT:    %iv.minus.1 = add i32 %iv, -1
66; CHECK-NEXT:    --> {(-1 + %start),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
67; CHECK-NEXT:    %fake_2 = call i1 @cond()
68; CHECK-NEXT:    --> %fake_2 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
69; CHECK-NEXT:    %and_2 = and i1 %range_check, %fake_2
70; CHECK-NEXT:    --> (%range_check umin %fake_2) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
71; CHECK-NEXT:    %iv.next = add i32 %iv, -1
72; CHECK-NEXT:    --> {(-1 + %start),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
73; CHECK-NEXT:    %loop_cond = call i1 @cond()
74; CHECK-NEXT:    --> %loop_cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
75; CHECK-NEXT:  Determining loop execution counts for: @test_litter_conditions
76; CHECK-NEXT:  Loop %loop: <multiple exits> Unpredictable backedge-taken count.
77; CHECK-NEXT:    exit count for loop: ***COULDNOTCOMPUTE***
78; CHECK-NEXT:    exit count for range_check_block: ***COULDNOTCOMPUTE***
79; CHECK-NEXT:    exit count for backedge: ***COULDNOTCOMPUTE***
80; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i32 -1
81; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is %start
82; CHECK-NEXT:    symbolic max exit count for loop: %start
83; CHECK-NEXT:    symbolic max exit count for range_check_block: ***COULDNOTCOMPUTE***
84; CHECK-NEXT:    symbolic max exit count for backedge: ***COULDNOTCOMPUTE***
85;
86entry:
87  br label %loop
88
89loop:
90  %iv = phi i32 [%start, %entry], [%iv.next, %backedge]
91  %zero_check = icmp ne i32 %iv, 0
92  %fake_1 = call i1 @cond()
93  %and_1 = and i1 %zero_check, %fake_1
94  br i1 %and_1, label %range_check_block, label %failed_1
95
96range_check_block:
97  %iv.minus.1 = add i32 %iv, -1
98  %range_check = icmp ult i32 %iv.minus.1, %len
99  %fake_2 = call i1 @cond()
100  %and_2 = and i1 %range_check, %fake_2
101  br i1 %and_2, label %backedge, label %failed_2
102
103backedge:
104  %iv.next = add i32 %iv, -1
105  %loop_cond = call i1 @cond()
106  br i1 %loop_cond, label %done, label %loop
107
108done:
109  ret i32 %iv
110
111failed_1:
112  ret i32 -1
113
114failed_2:
115  ret i32 -2
116}
117
118define i32 @test_litter_conditions_bad_context(i32 %start, i32 %len) {
119; CHECK-LABEL: 'test_litter_conditions_bad_context'
120; CHECK-NEXT:  Classifying expressions for: @test_litter_conditions_bad_context
121; CHECK-NEXT:    %iv = phi i32 [ %start, %entry ], [ %iv.next, %backedge ]
122; CHECK-NEXT:    --> {%start,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
123; CHECK-NEXT:    %fake_1 = call i1 @cond()
124; CHECK-NEXT:    --> %fake_1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
125; CHECK-NEXT:    %and_1 = and i1 %zero_check, %fake_1
126; CHECK-NEXT:    --> (%zero_check umin %fake_1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
127; CHECK-NEXT:    %iv.minus.1 = add i32 %iv, -1
128; CHECK-NEXT:    --> {(-1 + %start),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
129; CHECK-NEXT:    %fake_2 = call i1 @cond()
130; CHECK-NEXT:    --> %fake_2 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
131; CHECK-NEXT:    %and_2 = and i1 %range_check, %fake_2
132; CHECK-NEXT:    --> (%range_check umin %fake_2) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
133; CHECK-NEXT:    %iv.next = add i32 %iv, -1
134; CHECK-NEXT:    --> {(-1 + %start),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
135; CHECK-NEXT:    %loop_cond = call i1 @cond()
136; CHECK-NEXT:    --> %loop_cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
137; CHECK-NEXT:  Determining loop execution counts for: @test_litter_conditions_bad_context
138; CHECK-NEXT:  Loop %loop: <multiple exits> Unpredictable backedge-taken count.
139; CHECK-NEXT:    exit count for loop: ***COULDNOTCOMPUTE***
140; CHECK-NEXT:    exit count for range_check_block: ***COULDNOTCOMPUTE***
141; CHECK-NEXT:    exit count for backedge: ***COULDNOTCOMPUTE***
142; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i32 -1
143; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is %start
144; CHECK-NEXT:    symbolic max exit count for loop: %start
145; CHECK-NEXT:    symbolic max exit count for range_check_block: ***COULDNOTCOMPUTE***
146; CHECK-NEXT:    symbolic max exit count for backedge: ***COULDNOTCOMPUTE***
147;
148entry:
149  br label %loop
150
151loop:
152  %iv = phi i32 [%start, %entry], [%iv.next, %backedge]
153  %zero_check = icmp ne i32 %iv, 0
154  %fake_1 = call i1 @cond()
155  %and_1 = and i1 %zero_check, %fake_1
156  %iv.minus.1 = add i32 %iv, -1
157  %range_check = icmp ult i32 %iv.minus.1, %len
158  %fake_2 = call i1 @cond()
159  %and_2 = and i1 %range_check, %fake_2
160  br i1 %and_1, label %range_check_block, label %failed_1
161
162range_check_block:
163  br i1 %and_2, label %backedge, label %failed_2
164
165backedge:
166  %iv.next = add i32 %iv, -1
167  %loop_cond = call i1 @cond()
168  br i1 %loop_cond, label %done, label %loop
169
170done:
171  ret i32 %iv
172
173failed_1:
174  ret i32 -1
175
176failed_2:
177  ret i32 -2
178}
179
180define i32 @test_and_conditions(i32 %start, i32 %len) {
181; CHECK-LABEL: 'test_and_conditions'
182; CHECK-NEXT:  Classifying expressions for: @test_and_conditions
183; CHECK-NEXT:    %iv = phi i32 [ %start, %entry ], [ %iv.next, %backedge ]
184; CHECK-NEXT:    --> {%start,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
185; CHECK-NEXT:    %iv.minus.1 = add i32 %iv, -1
186; CHECK-NEXT:    --> {(-1 + %start),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
187; CHECK-NEXT:    %both_checks = and i1 %zero_check, %range_check
188; CHECK-NEXT:    --> (%range_check umin %zero_check) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
189; CHECK-NEXT:    %iv.next = add i32 %iv, -1
190; CHECK-NEXT:    --> {(-1 + %start),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
191; CHECK-NEXT:    %loop_cond = call i1 @cond()
192; CHECK-NEXT:    --> %loop_cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
193; CHECK-NEXT:  Determining loop execution counts for: @test_and_conditions
194; CHECK-NEXT:  Loop %loop: <multiple exits> Unpredictable backedge-taken count.
195; CHECK-NEXT:    exit count for loop: ***COULDNOTCOMPUTE***
196; CHECK-NEXT:    exit count for backedge: ***COULDNOTCOMPUTE***
197; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i32 -1
198; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is %start
199; CHECK-NEXT:    symbolic max exit count for loop: %start
200; CHECK-NEXT:    symbolic max exit count for backedge: ***COULDNOTCOMPUTE***
201;
202entry:
203  br label %loop
204
205loop:
206  %iv = phi i32 [%start, %entry], [%iv.next, %backedge]
207  %zero_check = icmp ne i32 %iv, 0
208  %iv.minus.1 = add i32 %iv, -1
209  %range_check = icmp ult i32 %iv.minus.1, %len
210  %both_checks = and i1 %zero_check, %range_check
211  br i1 %both_checks, label %backedge, label %failed
212
213backedge:
214  %iv.next = add i32 %iv, -1
215  %loop_cond = call i1 @cond()
216  br i1 %loop_cond, label %done, label %loop
217
218done:
219  ret i32 %iv
220
221failed:
222  ret i32 -3
223}
224
225define i32 @test_mixup_constant_symbolic(i32 %end, i32 %len) {
226; CHECK-LABEL: 'test_mixup_constant_symbolic'
227; CHECK-NEXT:  Classifying expressions for: @test_mixup_constant_symbolic
228; CHECK-NEXT:    %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
229; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,1001) S: [0,1001) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
230; CHECK-NEXT:    %iv.next = add i32 %iv, 1
231; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,1002) S: [1,1002) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
232; CHECK-NEXT:    %loop_cond = call i1 @cond()
233; CHECK-NEXT:    --> %loop_cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
234; CHECK-NEXT:  Determining loop execution counts for: @test_mixup_constant_symbolic
235; CHECK-NEXT:  Loop %loop: <multiple exits> Unpredictable backedge-taken count.
236; CHECK-NEXT:    exit count for loop: %end
237; CHECK-NEXT:    exit count for range_check_block: i32 1000
238; CHECK-NEXT:    exit count for backedge: ***COULDNOTCOMPUTE***
239; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i32 1000
240; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (1000 umin %end)
241; CHECK-NEXT:    symbolic max exit count for loop: %end
242; CHECK-NEXT:    symbolic max exit count for range_check_block: i32 1000
243; CHECK-NEXT:    symbolic max exit count for backedge: ***COULDNOTCOMPUTE***
244;
245entry:
246  br label %loop
247
248loop:
249  %iv = phi i32 [0, %entry], [%iv.next, %backedge]
250  %zero_check = icmp ne i32 %iv, %end
251  br i1 %zero_check, label %range_check_block, label %failed_1
252
253range_check_block:
254  %range_check = icmp ult i32 %iv, 1000
255  br i1 %range_check, label %backedge, label %failed_2
256
257backedge:
258  %iv.next = add i32 %iv, 1
259  %loop_cond = call i1 @cond()
260  br i1 %loop_cond, label %done, label %loop
261
262done:
263  ret i32 %iv
264
265failed_1:
266  ret i32 -1
267
268failed_2:
269  ret i32 -2
270}
271
272define i32 @test_mixup_constant_symbolic_merged(i32 %end, i32 %len) {
273; CHECK-LABEL: 'test_mixup_constant_symbolic_merged'
274; CHECK-NEXT:  Classifying expressions for: @test_mixup_constant_symbolic_merged
275; CHECK-NEXT:    %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
276; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,1001) S: [0,1001) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
277; CHECK-NEXT:    %and = and i1 %zero_check, %range_check
278; CHECK-NEXT:    --> (%range_check umin %zero_check) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
279; CHECK-NEXT:    %iv.next = add i32 %iv, 1
280; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,1002) S: [1,1002) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
281; CHECK-NEXT:    %loop_cond = call i1 @cond()
282; CHECK-NEXT:    --> %loop_cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
283; CHECK-NEXT:  Determining loop execution counts for: @test_mixup_constant_symbolic_merged
284; CHECK-NEXT:  Loop %loop: <multiple exits> Unpredictable backedge-taken count.
285; CHECK-NEXT:    exit count for loop: (1000 umin %end)
286; CHECK-NEXT:    exit count for backedge: ***COULDNOTCOMPUTE***
287; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i32 1000
288; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (1000 umin %end)
289; CHECK-NEXT:    symbolic max exit count for loop: (1000 umin %end)
290; CHECK-NEXT:    symbolic max exit count for backedge: ***COULDNOTCOMPUTE***
291;
292entry:
293  br label %loop
294
295loop:
296  %iv = phi i32 [0, %entry], [%iv.next, %backedge]
297  %zero_check = icmp ne i32 %iv, %end
298  %range_check = icmp ult i32 %iv, 1000
299  %and = and i1 %zero_check, %range_check
300  br i1 %and, label %backedge, label %failed_1
301
302backedge:
303  %iv.next = add i32 %iv, 1
304  %loop_cond = call i1 @cond()
305  br i1 %loop_cond, label %done, label %loop
306
307done:
308  ret i32 %iv
309
310failed_1:
311  ret i32 -1
312}
313
314define i32 @test_two_phis(i32 %start_1, i32 %start_2, i32 %len) {
315; CHECK-LABEL: 'test_two_phis'
316; CHECK-NEXT:  Classifying expressions for: @test_two_phis
317; CHECK-NEXT:    %iv_1 = phi i32 [ %start_1, %entry ], [ %iv_1.next, %backedge ]
318; CHECK-NEXT:    --> {%start_1,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
319; CHECK-NEXT:    %iv_2 = phi i32 [ %start_2, %entry ], [ %iv_2.next, %backedge ]
320; CHECK-NEXT:    --> {%start_2,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
321; CHECK-NEXT:    %scam_1 = call i1 @cond()
322; CHECK-NEXT:    --> %scam_1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
323; CHECK-NEXT:    %c1 = and i1 %zero_check_1, %scam_1
324; CHECK-NEXT:    --> (%zero_check_1 umin %scam_1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
325; CHECK-NEXT:    %scam_2 = call i1 @cond()
326; CHECK-NEXT:    --> %scam_2 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
327; CHECK-NEXT:    %c2 = and i1 %zero_check_2, %scam_2
328; CHECK-NEXT:    --> (%zero_check_2 umin %scam_2) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
329; CHECK-NEXT:    %iv.minus.1 = add i32 %iv_1, -1
330; CHECK-NEXT:    --> {(-1 + %start_1),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
331; CHECK-NEXT:    %iv_1.next = add i32 %iv_1, -1
332; CHECK-NEXT:    --> {(-1 + %start_1),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
333; CHECK-NEXT:    %iv_2.next = add i32 %iv_2, -1
334; CHECK-NEXT:    --> {(-1 + %start_2),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
335; CHECK-NEXT:    %loop_cond = call i1 @cond()
336; CHECK-NEXT:    --> %loop_cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
337; CHECK-NEXT:  Determining loop execution counts for: @test_two_phis
338; CHECK-NEXT:  Loop %loop: <multiple exits> Unpredictable backedge-taken count.
339; CHECK-NEXT:    exit count for loop: ***COULDNOTCOMPUTE***
340; CHECK-NEXT:    exit count for zero_check_block: ***COULDNOTCOMPUTE***
341; CHECK-NEXT:    exit count for range_check_block: ***COULDNOTCOMPUTE***
342; CHECK-NEXT:    exit count for backedge: ***COULDNOTCOMPUTE***
343; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i32 -1
344; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (%start_1 umin_seq %start_2)
345; CHECK-NEXT:    symbolic max exit count for loop: %start_1
346; CHECK-NEXT:    symbolic max exit count for zero_check_block: %start_2
347; CHECK-NEXT:    symbolic max exit count for range_check_block: ***COULDNOTCOMPUTE***
348; CHECK-NEXT:    symbolic max exit count for backedge: ***COULDNOTCOMPUTE***
349;
350entry:
351  br label %loop
352
353loop:
354  %iv_1 = phi i32 [%start_1, %entry], [%iv_1.next, %backedge]
355  %iv_2 = phi i32 [%start_2, %entry], [%iv_2.next, %backedge]
356  %scam_1 = call i1 @cond()
357  %zero_check_1 = icmp ne i32 %iv_1, 0
358  %c1 = and i1 %zero_check_1, %scam_1
359  br i1 %c1, label %zero_check_block, label %failed_1
360
361zero_check_block:
362  %scam_2 = call i1 @cond()
363  %zero_check_2 = icmp ne i32 %iv_2, 0
364  %c2 = and i1 %zero_check_2, %scam_2
365  br i1 %c2, label %range_check_block, label %failed_1
366
367range_check_block:
368  %iv.minus.1 = add i32 %iv_1, -1
369  %range_check = icmp ult i32 %iv.minus.1, %len
370  br i1 %range_check, label %backedge, label %failed_2
371
372backedge:
373  %iv_1.next = add i32 %iv_1, -1
374  %iv_2.next = add i32 %iv_2, -1
375  %loop_cond = call i1 @cond()
376  br i1 %loop_cond, label %done, label %loop
377
378done:
379  ret i32 %iv_2
380
381failed_1:
382  ret i32 -1
383
384failed_2:
385  ret i32 -2
386}
387
388define i32 @test_two_phis_simple(i32 %start_1, i32 %start_2, i32 %len) {
389; CHECK-LABEL: 'test_two_phis_simple'
390; CHECK-NEXT:  Classifying expressions for: @test_two_phis_simple
391; CHECK-NEXT:    %iv_1 = phi i32 [ %start_1, %entry ], [ %iv_1.next, %backedge ]
392; CHECK-NEXT:    --> {%start_1,+,-1}<%loop> U: full-set S: full-set Exits: ((-1 * (%start_1 umin_seq %start_2)) + %start_1) LoopDispositions: { %loop: Computable }
393; CHECK-NEXT:    %iv_2 = phi i32 [ %start_2, %entry ], [ %iv_2.next, %backedge ]
394; CHECK-NEXT:    --> {%start_2,+,-1}<%loop> U: full-set S: full-set Exits: ((-1 * (%start_1 umin_seq %start_2)) + %start_2) LoopDispositions: { %loop: Computable }
395; CHECK-NEXT:    %iv_1.next = add i32 %iv_1, -1
396; CHECK-NEXT:    --> {(-1 + %start_1),+,-1}<%loop> U: full-set S: full-set Exits: (-1 + (-1 * (%start_1 umin_seq %start_2)) + %start_1) LoopDispositions: { %loop: Computable }
397; CHECK-NEXT:    %iv_2.next = add i32 %iv_2, -1
398; CHECK-NEXT:    --> {(-1 + %start_2),+,-1}<%loop> U: full-set S: full-set Exits: (-1 + (-1 * (%start_1 umin_seq %start_2)) + %start_2) LoopDispositions: { %loop: Computable }
399; CHECK-NEXT:  Determining loop execution counts for: @test_two_phis_simple
400; CHECK-NEXT:  Loop %loop: <multiple exits> backedge-taken count is (%start_1 umin_seq %start_2)
401; CHECK-NEXT:    exit count for loop: %start_1
402; CHECK-NEXT:    exit count for backedge: %start_2
403; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i32 -1
404; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (%start_1 umin_seq %start_2)
405; CHECK-NEXT:    symbolic max exit count for loop: %start_1
406; CHECK-NEXT:    symbolic max exit count for backedge: %start_2
407; CHECK-NEXT:  Loop %loop: Trip multiple is 1
408;
409entry:
410  br label %loop
411
412loop:
413  %iv_1 = phi i32 [%start_1, %entry], [%iv_1.next, %backedge]
414  %iv_2 = phi i32 [%start_2, %entry], [%iv_2.next, %backedge]
415  %zero_check_1 = icmp ne i32 %iv_1, 0
416  br i1 %zero_check_1, label %backedge, label %exit
417
418backedge:
419  %zero_check_2 = icmp ne i32 %iv_2, 0
420  %iv_1.next = add i32 %iv_1, -1
421  %iv_2.next = add i32 %iv_2, -1
422  br i1 %zero_check_2, label %loop, label %exit
423
424exit:
425  ret i32 0
426}
427
428define i32 @test_two_phis_arithmetic_and(i32 %start_1, i32 %start_2, i32 %len) {
429; CHECK-LABEL: 'test_two_phis_arithmetic_and'
430; CHECK-NEXT:  Classifying expressions for: @test_two_phis_arithmetic_and
431; CHECK-NEXT:    %iv_1 = phi i32 [ %start_1, %entry ], [ %iv_1.next, %backedge ]
432; CHECK-NEXT:    --> {%start_1,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
433; CHECK-NEXT:    %iv_2 = phi i32 [ %start_2, %entry ], [ %iv_2.next, %backedge ]
434; CHECK-NEXT:    --> {%start_2,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
435; CHECK-NEXT:    %scam_1 = call i1 @cond()
436; CHECK-NEXT:    --> %scam_1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
437; CHECK-NEXT:    %c1 = and i1 %zero_check_1, %scam_1
438; CHECK-NEXT:    --> (%zero_check_1 umin %scam_1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
439; CHECK-NEXT:    %scam_2 = call i1 @cond()
440; CHECK-NEXT:    --> %scam_2 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
441; CHECK-NEXT:    %c2 = and i1 %zero_check_2, %scam_2
442; CHECK-NEXT:    --> (%zero_check_2 umin %scam_2) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
443; CHECK-NEXT:    %merged_cond = and i1 %c1, %c2
444; CHECK-NEXT:    --> (%zero_check_1 umin %zero_check_2 umin %scam_1 umin %scam_2) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
445; CHECK-NEXT:    %iv.minus.1 = add i32 %iv_1, -1
446; CHECK-NEXT:    --> {(-1 + %start_1),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
447; CHECK-NEXT:    %iv_1.next = add i32 %iv_1, -1
448; CHECK-NEXT:    --> {(-1 + %start_1),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
449; CHECK-NEXT:    %iv_2.next = add i32 %iv_2, -1
450; CHECK-NEXT:    --> {(-1 + %start_2),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
451; CHECK-NEXT:    %loop_cond = call i1 @cond()
452; CHECK-NEXT:    --> %loop_cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
453; CHECK-NEXT:  Determining loop execution counts for: @test_two_phis_arithmetic_and
454; CHECK-NEXT:  Loop %loop: <multiple exits> Unpredictable backedge-taken count.
455; CHECK-NEXT:    exit count for loop: ***COULDNOTCOMPUTE***
456; CHECK-NEXT:    exit count for range_check_block: ***COULDNOTCOMPUTE***
457; CHECK-NEXT:    exit count for backedge: ***COULDNOTCOMPUTE***
458; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i32 -1
459; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (%start_1 umin %start_2)
460; CHECK-NEXT:    symbolic max exit count for loop: (%start_1 umin %start_2)
461; CHECK-NEXT:    symbolic max exit count for range_check_block: ***COULDNOTCOMPUTE***
462; CHECK-NEXT:    symbolic max exit count for backedge: ***COULDNOTCOMPUTE***
463;
464entry:
465  br label %loop
466
467loop:
468  %iv_1 = phi i32 [%start_1, %entry], [%iv_1.next, %backedge]
469  %iv_2 = phi i32 [%start_2, %entry], [%iv_2.next, %backedge]
470  %scam_1 = call i1 @cond()
471  %zero_check_1 = icmp ne i32 %iv_1, 0
472  %c1 = and i1 %zero_check_1, %scam_1
473  %scam_2 = call i1 @cond()
474  %zero_check_2 = icmp ne i32 %iv_2, 0
475  %c2 = and i1 %zero_check_2, %scam_2
476  %merged_cond = and i1 %c1, %c2
477  br i1 %merged_cond, label %range_check_block, label %failed_1
478
479range_check_block:
480  %iv.minus.1 = add i32 %iv_1, -1
481  %range_check = icmp ult i32 %iv.minus.1, %len
482  br i1 %range_check, label %backedge, label %failed_2
483
484backedge:
485  %iv_1.next = add i32 %iv_1, -1
486  %iv_2.next = add i32 %iv_2, -1
487  %loop_cond = call i1 @cond()
488  br i1 %loop_cond, label %done, label %loop
489
490done:
491  ret i32 %iv_2
492
493failed_1:
494  ret i32 -1
495
496failed_2:
497  ret i32 -2
498}
499
500; TODO: Symbolic max can be start1 umax_seq start2
501define i32 @test_two_phis_logical_or(i32 %start_1, i32 %start_2, i32 %len) {
502; CHECK-LABEL: 'test_two_phis_logical_or'
503; CHECK-NEXT:  Classifying expressions for: @test_two_phis_logical_or
504; CHECK-NEXT:    %iv_1 = phi i32 [ %start_1, %entry ], [ %iv_1.next, %backedge ]
505; CHECK-NEXT:    --> {%start_1,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
506; CHECK-NEXT:    %iv_2 = phi i32 [ %start_2, %entry ], [ %iv_2.next, %backedge ]
507; CHECK-NEXT:    --> {%start_2,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
508; CHECK-NEXT:    %scam_1 = call i1 @cond()
509; CHECK-NEXT:    --> %scam_1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
510; CHECK-NEXT:    %c1 = and i1 %zero_check_1, %scam_1
511; CHECK-NEXT:    --> (%zero_check_1 umin %scam_1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
512; CHECK-NEXT:    %scam_2 = call i1 @cond()
513; CHECK-NEXT:    --> %scam_2 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
514; CHECK-NEXT:    %c2 = and i1 %zero_check_2, %scam_2
515; CHECK-NEXT:    --> (%zero_check_2 umin %scam_2) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
516; CHECK-NEXT:    %merged_cond = select i1 %c1, i1 true, i1 %c2
517; CHECK-NEXT:    --> (true + ((true + (%zero_check_1 umin %scam_1)) umin_seq (true + (%zero_check_2 umin %scam_2)))) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
518; CHECK-NEXT:    %iv.minus.1 = add i32 %iv_1, -1
519; CHECK-NEXT:    --> {(-1 + %start_1),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
520; CHECK-NEXT:    %iv_1.next = add i32 %iv_1, -1
521; CHECK-NEXT:    --> {(-1 + %start_1),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
522; CHECK-NEXT:    %iv_2.next = add i32 %iv_2, -1
523; CHECK-NEXT:    --> {(-1 + %start_2),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
524; CHECK-NEXT:    %loop_cond = call i1 @cond()
525; CHECK-NEXT:    --> %loop_cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
526; CHECK-NEXT:  Determining loop execution counts for: @test_two_phis_logical_or
527; CHECK-NEXT:  Loop %loop: <multiple exits> Unpredictable backedge-taken count.
528; CHECK-NEXT:    exit count for loop: ***COULDNOTCOMPUTE***
529; CHECK-NEXT:    exit count for range_check_block: ***COULDNOTCOMPUTE***
530; CHECK-NEXT:    exit count for backedge: ***COULDNOTCOMPUTE***
531; CHECK-NEXT:  Loop %loop: Unpredictable constant max backedge-taken count.
532; CHECK-NEXT:  Loop %loop: Unpredictable symbolic max backedge-taken count.
533; CHECK-NEXT:    symbolic max exit count for loop: ***COULDNOTCOMPUTE***
534; CHECK-NEXT:    symbolic max exit count for range_check_block: ***COULDNOTCOMPUTE***
535; CHECK-NEXT:    symbolic max exit count for backedge: ***COULDNOTCOMPUTE***
536;
537entry:
538  br label %loop
539
540loop:
541  %iv_1 = phi i32 [%start_1, %entry], [%iv_1.next, %backedge]
542  %iv_2 = phi i32 [%start_2, %entry], [%iv_2.next, %backedge]
543  %scam_1 = call i1 @cond()
544  %zero_check_1 = icmp ne i32 %iv_1, 0
545  %c1 = and i1 %zero_check_1, %scam_1
546  %scam_2 = call i1 @cond()
547  %zero_check_2 = icmp ne i32 %iv_2, 0
548  %c2 = and i1 %zero_check_2, %scam_2
549  %merged_cond = select i1 %c1, i1 true, i1 %c2
550  br i1 %merged_cond, label %range_check_block, label %failed_1
551
552range_check_block:
553  %iv.minus.1 = add i32 %iv_1, -1
554  %range_check = icmp ult i32 %iv.minus.1, %len
555  br i1 %range_check, label %backedge, label %failed_2
556
557backedge:
558  %iv_1.next = add i32 %iv_1, -1
559  %iv_2.next = add i32 %iv_2, -1
560  %loop_cond = call i1 @cond()
561  br i1 %loop_cond, label %done, label %loop
562
563done:
564  ret i32 %iv_2
565
566failed_1:
567  ret i32 -1
568
569failed_2:
570  ret i32 -2
571}
572
573define i32 @test_two_phis_logical_and(i32 %start_1, i32 %start_2, i32 %len) {
574; CHECK-LABEL: 'test_two_phis_logical_and'
575; CHECK-NEXT:  Classifying expressions for: @test_two_phis_logical_and
576; CHECK-NEXT:    %iv_1 = phi i32 [ %start_1, %entry ], [ %iv_1.next, %backedge ]
577; CHECK-NEXT:    --> {%start_1,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
578; CHECK-NEXT:    %iv_2 = phi i32 [ %start_2, %entry ], [ %iv_2.next, %backedge ]
579; CHECK-NEXT:    --> {%start_2,+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
580; CHECK-NEXT:    %scam_1 = call i1 @cond()
581; CHECK-NEXT:    --> %scam_1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
582; CHECK-NEXT:    %c1 = and i1 %zero_check_1, %scam_1
583; CHECK-NEXT:    --> (%zero_check_1 umin %scam_1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
584; CHECK-NEXT:    %scam_2 = call i1 @cond()
585; CHECK-NEXT:    --> %scam_2 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
586; CHECK-NEXT:    %c2 = and i1 %zero_check_2, %scam_2
587; CHECK-NEXT:    --> (%zero_check_2 umin %scam_2) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
588; CHECK-NEXT:    %merged_cond = select i1 %c1, i1 %c2, i1 false
589; CHECK-NEXT:    --> ((%zero_check_1 umin %scam_1) umin_seq (%zero_check_2 umin %scam_2)) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
590; CHECK-NEXT:    %iv.minus.1 = add i32 %iv_1, -1
591; CHECK-NEXT:    --> {(-1 + %start_1),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
592; CHECK-NEXT:    %iv_1.next = add i32 %iv_1, -1
593; CHECK-NEXT:    --> {(-1 + %start_1),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
594; CHECK-NEXT:    %iv_2.next = add i32 %iv_2, -1
595; CHECK-NEXT:    --> {(-1 + %start_2),+,-1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
596; CHECK-NEXT:    %loop_cond = call i1 @cond()
597; CHECK-NEXT:    --> %loop_cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
598; CHECK-NEXT:  Determining loop execution counts for: @test_two_phis_logical_and
599; CHECK-NEXT:  Loop %loop: <multiple exits> Unpredictable backedge-taken count.
600; CHECK-NEXT:    exit count for loop: ***COULDNOTCOMPUTE***
601; CHECK-NEXT:    exit count for range_check_block: ***COULDNOTCOMPUTE***
602; CHECK-NEXT:    exit count for backedge: ***COULDNOTCOMPUTE***
603; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i32 -1
604; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (%start_1 umin_seq %start_2)
605; CHECK-NEXT:    symbolic max exit count for loop: (%start_1 umin_seq %start_2)
606; CHECK-NEXT:    symbolic max exit count for range_check_block: ***COULDNOTCOMPUTE***
607; CHECK-NEXT:    symbolic max exit count for backedge: ***COULDNOTCOMPUTE***
608;
609entry:
610  br label %loop
611
612loop:
613  %iv_1 = phi i32 [%start_1, %entry], [%iv_1.next, %backedge]
614  %iv_2 = phi i32 [%start_2, %entry], [%iv_2.next, %backedge]
615  %scam_1 = call i1 @cond()
616  %zero_check_1 = icmp ne i32 %iv_1, 0
617  %c1 = and i1 %zero_check_1, %scam_1
618  %scam_2 = call i1 @cond()
619  %zero_check_2 = icmp ne i32 %iv_2, 0
620  %c2 = and i1 %zero_check_2, %scam_2
621  %merged_cond = select i1 %c1, i1 %c2, i1 false
622  br i1 %merged_cond, label %range_check_block, label %failed_1
623
624range_check_block:
625  %iv.minus.1 = add i32 %iv_1, -1
626  %range_check = icmp ult i32 %iv.minus.1, %len
627  br i1 %range_check, label %backedge, label %failed_2
628
629backedge:
630  %iv_1.next = add i32 %iv_1, -1
631  %iv_2.next = add i32 %iv_2, -1
632  %loop_cond = call i1 @cond()
633  br i1 %loop_cond, label %done, label %loop
634
635done:
636  ret i32 %iv_2
637
638failed_1:
639  ret i32 -1
640
641failed_2:
642  ret i32 -2
643}
644