1e25eb143SFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2e25eb143SFlorian Hahn; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
3e25eb143SFlorian Hahn
4e25eb143SFlorian Hahntarget datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
5e25eb143SFlorian Hahn
6e25eb143SFlorian Hahndeclare void @use(ptr)
7e25eb143SFlorian Hahndeclare i1 @cond()
8e25eb143SFlorian Hahn
9e25eb143SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_different_element_types_1_chain_of_2_exit_condition_unrelated_condition_in_header(ptr %start, i16 %len, i16 %x) {
10e25eb143SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_different_element_types_1_chain_of_2_exit_condition_unrelated_condition_in_header(
11e25eb143SFlorian Hahn; CHECK-NEXT:  entry:
12e25eb143SFlorian Hahn; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]
13e25eb143SFlorian Hahn; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
14e25eb143SFlorian Hahn; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]
15e25eb143SFlorian Hahn; CHECK:       loop.ph:
16e25eb143SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
17e25eb143SFlorian Hahn; CHECK:       loop.header:
18e25eb143SFlorian Hahn; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
19e25eb143SFlorian Hahn; CHECK-NEXT:    [[C_0:%.*]] = icmp eq i16 [[X:%.*]], 1
20e25eb143SFlorian Hahn; CHECK-NEXT:    br i1 [[C_0]], label [[EXIT]], label [[THEN:%.*]]
21e25eb143SFlorian Hahn; CHECK:       then:
22e25eb143SFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
23e25eb143SFlorian Hahn; CHECK-NEXT:    br i1 [[C_1]], label [[EXIT]], label [[FOR_BODY:%.*]]
24e25eb143SFlorian Hahn; CHECK:       for.body:
25e25eb143SFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = call i1 @cond()
26e25eb143SFlorian Hahn; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
27e25eb143SFlorian Hahn; CHECK:       loop.next:
28e25eb143SFlorian Hahn; CHECK-NEXT:    [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]
29e25eb143SFlorian Hahn; CHECK-NEXT:    [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]
30e25eb143SFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 [[T_1]], [[T_2]]
31e25eb143SFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
32e25eb143SFlorian Hahn; CHECK:       loop.latch:
33e25eb143SFlorian Hahn; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])
34e25eb143SFlorian Hahn; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 1
35e25eb143SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER]]
36e25eb143SFlorian Hahn; CHECK:       exit:
37e25eb143SFlorian Hahn; CHECK-NEXT:    ret void
38e25eb143SFlorian Hahn;
39e25eb143SFlorian Hahnentry:
40e25eb143SFlorian Hahn  %upper = getelementptr inbounds i32, ptr %start, i16 %len
41e25eb143SFlorian Hahn  %len.neg = icmp slt i16 %len, 0
42e25eb143SFlorian Hahn  br i1 %len.neg, label %exit, label %loop.ph
43e25eb143SFlorian Hahn
44e25eb143SFlorian Hahnloop.ph:
45e25eb143SFlorian Hahn  br label %loop.header
46e25eb143SFlorian Hahn
47e25eb143SFlorian Hahnloop.header:
48e25eb143SFlorian Hahn  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
49e25eb143SFlorian Hahn  %c.0 = icmp eq i16 %x, 1
50e25eb143SFlorian Hahn  br i1 %c.0, label %exit, label %then
51e25eb143SFlorian Hahn
52e25eb143SFlorian Hahnthen:
53e25eb143SFlorian Hahn  %c.1 = icmp eq ptr %ptr.iv, %upper
54e25eb143SFlorian Hahn  br i1 %c.1, label %exit, label %for.body
55e25eb143SFlorian Hahn
56e25eb143SFlorian Hahnfor.body:
57e25eb143SFlorian Hahn  %c.2 = call i1 @cond()
58e25eb143SFlorian Hahn  br i1 %c.2, label %loop.next, label %exit
59e25eb143SFlorian Hahn
60e25eb143SFlorian Hahnloop.next:
61e25eb143SFlorian Hahn  %t.1 = icmp uge ptr %ptr.iv, %start
62e25eb143SFlorian Hahn  %t.2 = icmp ult ptr %ptr.iv, %upper
63e25eb143SFlorian Hahn  %and = and i1 %t.1, %t.2
64e25eb143SFlorian Hahn  br i1 %and, label %loop.latch, label %exit
65e25eb143SFlorian Hahn
66e25eb143SFlorian Hahnloop.latch:
67e25eb143SFlorian Hahn  call void @use(ptr %ptr.iv)
68e25eb143SFlorian Hahn  %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 1
69e25eb143SFlorian Hahn  br label %loop.header
70e25eb143SFlorian Hahn
71e25eb143SFlorian Hahnexit:
72e25eb143SFlorian Hahn  ret void
73e25eb143SFlorian Hahn}
74e25eb143SFlorian Hahn
75e25eb143SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_different_element_types_1_chain_of_3_exit_condition_unrelated_condition_in_header(ptr %start, i16 %len, i16 %x) {
76e25eb143SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_different_element_types_1_chain_of_3_exit_condition_unrelated_condition_in_header(
77e25eb143SFlorian Hahn; CHECK-NEXT:  entry:
78e25eb143SFlorian Hahn; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]
79e25eb143SFlorian Hahn; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
80e25eb143SFlorian Hahn; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]
81e25eb143SFlorian Hahn; CHECK:       loop.ph:
82e25eb143SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
83e25eb143SFlorian Hahn; CHECK:       loop.header:
84e25eb143SFlorian Hahn; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
85e25eb143SFlorian Hahn; CHECK-NEXT:    [[C_0:%.*]] = icmp eq i16 [[X:%.*]], 1
86e25eb143SFlorian Hahn; CHECK-NEXT:    br i1 [[C_0]], label [[EXIT]], label [[THEN_1:%.*]]
87e25eb143SFlorian Hahn; CHECK:       then.1:
88e25eb143SFlorian Hahn; CHECK-NEXT:    [[C_00:%.*]] = icmp ult i16 [[X]], 100
89e25eb143SFlorian Hahn; CHECK-NEXT:    br i1 [[C_0]], label [[EXIT]], label [[THEN_2:%.*]]
90e25eb143SFlorian Hahn; CHECK:       then.2:
91e25eb143SFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
92e25eb143SFlorian Hahn; CHECK-NEXT:    br i1 [[C_1]], label [[EXIT]], label [[FOR_BODY:%.*]]
93e25eb143SFlorian Hahn; CHECK:       for.body:
94e25eb143SFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = call i1 @cond()
95e25eb143SFlorian Hahn; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
96e25eb143SFlorian Hahn; CHECK:       loop.next:
97e25eb143SFlorian Hahn; CHECK-NEXT:    [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]
98e25eb143SFlorian Hahn; CHECK-NEXT:    [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]
99e25eb143SFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 [[T_1]], [[T_2]]
100e25eb143SFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
101e25eb143SFlorian Hahn; CHECK:       loop.latch:
102e25eb143SFlorian Hahn; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])
103e25eb143SFlorian Hahn; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 1
104e25eb143SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER]]
105e25eb143SFlorian Hahn; CHECK:       exit:
106e25eb143SFlorian Hahn; CHECK-NEXT:    ret void
107e25eb143SFlorian Hahn;
108e25eb143SFlorian Hahnentry:
109e25eb143SFlorian Hahn  %upper = getelementptr inbounds i32, ptr %start, i16 %len
110e25eb143SFlorian Hahn  %len.neg = icmp slt i16 %len, 0
111e25eb143SFlorian Hahn  br i1 %len.neg, label %exit, label %loop.ph
112e25eb143SFlorian Hahn
113e25eb143SFlorian Hahnloop.ph:
114e25eb143SFlorian Hahn  br label %loop.header
115e25eb143SFlorian Hahn
116e25eb143SFlorian Hahnloop.header:
117e25eb143SFlorian Hahn  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
118e25eb143SFlorian Hahn  %c.0 = icmp eq i16 %x, 1
119e25eb143SFlorian Hahn  br i1 %c.0, label %exit, label %then.1
120e25eb143SFlorian Hahn
121e25eb143SFlorian Hahnthen.1:
122e25eb143SFlorian Hahn  %c.00 = icmp ult i16 %x, 100
123e25eb143SFlorian Hahn  br i1 %c.0, label %exit, label %then.2
124e25eb143SFlorian Hahn
125e25eb143SFlorian Hahnthen.2:
126e25eb143SFlorian Hahn  %c.1 = icmp eq ptr %ptr.iv, %upper
127e25eb143SFlorian Hahn  br i1 %c.1, label %exit, label %for.body
128e25eb143SFlorian Hahn
129e25eb143SFlorian Hahnfor.body:
130e25eb143SFlorian Hahn  %c.2 = call i1 @cond()
131e25eb143SFlorian Hahn  br i1 %c.2, label %loop.next, label %exit
132e25eb143SFlorian Hahn
133e25eb143SFlorian Hahnloop.next:
134e25eb143SFlorian Hahn  %t.1 = icmp uge ptr %ptr.iv, %start
135e25eb143SFlorian Hahn  %t.2 = icmp ult ptr %ptr.iv, %upper
136e25eb143SFlorian Hahn  %and = and i1 %t.1, %t.2
137e25eb143SFlorian Hahn  br i1 %and, label %loop.latch, label %exit
138e25eb143SFlorian Hahn
139e25eb143SFlorian Hahnloop.latch:
140e25eb143SFlorian Hahn  call void @use(ptr %ptr.iv)
141e25eb143SFlorian Hahn  %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 1
142e25eb143SFlorian Hahn  br label %loop.header
143e25eb143SFlorian Hahn
144e25eb143SFlorian Hahnexit:
145e25eb143SFlorian Hahn  ret void
146e25eb143SFlorian Hahn}
147e25eb143SFlorian Hahn
148e25eb143SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_different_element_types_1_chain_of_2_exit_conditions_with_slt_in_header(ptr %start, i16 %len, i16 %x) {
149e25eb143SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_different_element_types_1_chain_of_2_exit_conditions_with_slt_in_header(
150e25eb143SFlorian Hahn; CHECK-NEXT:  entry:
151e25eb143SFlorian Hahn; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]
152e25eb143SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_PH:%.*]]
153e25eb143SFlorian Hahn; CHECK:       loop.ph:
154e25eb143SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
155e25eb143SFlorian Hahn; CHECK:       loop.header:
156e25eb143SFlorian Hahn; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
157e25eb143SFlorian Hahn; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
158e25eb143SFlorian Hahn; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[THEN:%.*]]
159e25eb143SFlorian Hahn; CHECK:       then:
160e25eb143SFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
161e25eb143SFlorian Hahn; CHECK-NEXT:    br i1 [[C_1]], label [[EXIT]], label [[FOR_BODY:%.*]]
162e25eb143SFlorian Hahn; CHECK:       for.body:
163e25eb143SFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = call i1 @cond()
164e25eb143SFlorian Hahn; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
165e25eb143SFlorian Hahn; CHECK:       loop.next:
166e25eb143SFlorian Hahn; CHECK-NEXT:    [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]
167e25eb143SFlorian Hahn; CHECK-NEXT:    [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]
168e25eb143SFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 [[T_1]], [[T_2]]
169e25eb143SFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
170e25eb143SFlorian Hahn; CHECK:       loop.latch:
171e25eb143SFlorian Hahn; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])
172e25eb143SFlorian Hahn; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 1
173e25eb143SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER]]
174e25eb143SFlorian Hahn; CHECK:       exit:
175e25eb143SFlorian Hahn; CHECK-NEXT:    ret void
176e25eb143SFlorian Hahn;
177e25eb143SFlorian Hahnentry:
178e25eb143SFlorian Hahn  %upper = getelementptr inbounds i32, ptr %start, i16 %len
179e25eb143SFlorian Hahn  br label %loop.ph
180e25eb143SFlorian Hahn
181e25eb143SFlorian Hahnloop.ph:
182e25eb143SFlorian Hahn  br label %loop.header
183e25eb143SFlorian Hahn
184e25eb143SFlorian Hahnloop.header:
185e25eb143SFlorian Hahn  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
186e25eb143SFlorian Hahn  %len.neg = icmp slt i16 %len, 0
187e25eb143SFlorian Hahn  br i1 %len.neg, label %exit, label %then
188e25eb143SFlorian Hahn
189e25eb143SFlorian Hahnthen:
190e25eb143SFlorian Hahn  %c.1 = icmp eq ptr %ptr.iv, %upper
191e25eb143SFlorian Hahn  br i1 %c.1, label %exit, label %for.body
192e25eb143SFlorian Hahn
193e25eb143SFlorian Hahnfor.body:
194e25eb143SFlorian Hahn  %c.2 = call i1 @cond()
195e25eb143SFlorian Hahn  br i1 %c.2, label %loop.next, label %exit
196e25eb143SFlorian Hahn
197e25eb143SFlorian Hahnloop.next:
198e25eb143SFlorian Hahn  %t.1 = icmp uge ptr %ptr.iv, %start
199e25eb143SFlorian Hahn  %t.2 = icmp ult ptr %ptr.iv, %upper
200e25eb143SFlorian Hahn  %and = and i1 %t.1, %t.2
201e25eb143SFlorian Hahn  br i1 %and, label %loop.latch, label %exit
202e25eb143SFlorian Hahn
203e25eb143SFlorian Hahnloop.latch:
204e25eb143SFlorian Hahn  call void @use(ptr %ptr.iv)
205e25eb143SFlorian Hahn  %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 1
206e25eb143SFlorian Hahn  br label %loop.header
207e25eb143SFlorian Hahn
208e25eb143SFlorian Hahnexit:
209e25eb143SFlorian Hahn  ret void
210e25eb143SFlorian Hahn}
211e25eb143SFlorian Hahn
212e25eb143SFlorian Hahndefine void @test_header_not_exiting(ptr %start, i16 %len, i16 %x) {
213e25eb143SFlorian Hahn; CHECK-LABEL: @test_header_not_exiting(
214e25eb143SFlorian Hahn; CHECK-NEXT:  entry:
215e25eb143SFlorian Hahn; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]
216e25eb143SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_PH:%.*]]
217e25eb143SFlorian Hahn; CHECK:       loop.ph:
218e25eb143SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
219e25eb143SFlorian Hahn; CHECK:       loop.header:
220e25eb143SFlorian Hahn; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
221e25eb143SFlorian Hahn; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
222e25eb143SFlorian Hahn; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[THEN:%.*]], label [[FOR_BODY:%.*]]
223e25eb143SFlorian Hahn; CHECK:       then:
224e25eb143SFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
225e25eb143SFlorian Hahn; CHECK-NEXT:    br i1 [[C_1]], label [[EXIT:%.*]], label [[FOR_BODY]]
226e25eb143SFlorian Hahn; CHECK:       for.body:
227e25eb143SFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = call i1 @cond()
228e25eb143SFlorian Hahn; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
229e25eb143SFlorian Hahn; CHECK:       loop.next:
230e25eb143SFlorian Hahn; CHECK-NEXT:    [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]
231e25eb143SFlorian Hahn; CHECK-NEXT:    [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]
232e25eb143SFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 [[T_1]], [[T_2]]
233e25eb143SFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
234e25eb143SFlorian Hahn; CHECK:       loop.latch:
235e25eb143SFlorian Hahn; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])
236e25eb143SFlorian Hahn; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 1
237e25eb143SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER]]
238e25eb143SFlorian Hahn; CHECK:       exit:
239e25eb143SFlorian Hahn; CHECK-NEXT:    ret void
240e25eb143SFlorian Hahn;
241e25eb143SFlorian Hahnentry:
242e25eb143SFlorian Hahn  %upper = getelementptr inbounds i32, ptr %start, i16 %len
243e25eb143SFlorian Hahn  br label %loop.ph
244e25eb143SFlorian Hahn
245e25eb143SFlorian Hahnloop.ph:
246e25eb143SFlorian Hahn  br label %loop.header
247e25eb143SFlorian Hahn
248e25eb143SFlorian Hahnloop.header:
249e25eb143SFlorian Hahn  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
250e25eb143SFlorian Hahn  %len.neg = icmp slt i16 %len, 0
251e25eb143SFlorian Hahn  br i1 %len.neg, label %then, label %for.body
252e25eb143SFlorian Hahn
253e25eb143SFlorian Hahnthen:
254e25eb143SFlorian Hahn  %c.1 = icmp eq ptr %ptr.iv, %upper
255e25eb143SFlorian Hahn  br i1 %c.1, label %exit, label %for.body
256e25eb143SFlorian Hahn
257e25eb143SFlorian Hahnfor.body:
258e25eb143SFlorian Hahn  %c.2 = call i1 @cond()
259e25eb143SFlorian Hahn  br i1 %c.2, label %loop.next, label %exit
260e25eb143SFlorian Hahn
261e25eb143SFlorian Hahnloop.next:
262e25eb143SFlorian Hahn  %t.1 = icmp uge ptr %ptr.iv, %start
263e25eb143SFlorian Hahn  %t.2 = icmp ult ptr %ptr.iv, %upper
264e25eb143SFlorian Hahn  %and = and i1 %t.1, %t.2
265e25eb143SFlorian Hahn  br i1 %and, label %loop.latch, label %exit
266e25eb143SFlorian Hahn
267e25eb143SFlorian Hahnloop.latch:
268e25eb143SFlorian Hahn  call void @use(ptr %ptr.iv)
269e25eb143SFlorian Hahn  %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 1
270e25eb143SFlorian Hahn  br label %loop.header
271e25eb143SFlorian Hahn
272e25eb143SFlorian Hahnexit:
273e25eb143SFlorian Hahn  ret void
274e25eb143SFlorian Hahn}
275*f58312efSFlorian Hahn
276*f58312efSFlorian Hahndeclare void @foo()
277*f58312efSFlorian Hahn
278*f58312efSFlorian Hahndefine i32 @test_latch_exiting1(i32 %N) {
279*f58312efSFlorian Hahn; CHECK-LABEL: @test_latch_exiting1(
280*f58312efSFlorian Hahn; CHECK-NEXT:  entry:
281*f58312efSFlorian Hahn; CHECK-NEXT:    br label [[LOOP:%.*]]
282*f58312efSFlorian Hahn; CHECK:       loop:
283*f58312efSFlorian Hahn; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
284*f58312efSFlorian Hahn; CHECK-NEXT:    call void @foo()
285*f58312efSFlorian Hahn; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
286*f58312efSFlorian Hahn; CHECK-NEXT:    [[EC:%.*]] = icmp eq i32 [[IV]], [[N:%.*]]
287*f58312efSFlorian Hahn; CHECK-NEXT:    br i1 [[EC]], label [[EXIT_1:%.*]], label [[LOOP]]
288*f58312efSFlorian Hahn; CHECK:       exit.1:
289*f58312efSFlorian Hahn; CHECK-NEXT:    ret i32 10
290*f58312efSFlorian Hahn;
291*f58312efSFlorian Hahnentry:
292*f58312efSFlorian Hahn  br label %loop
293*f58312efSFlorian Hahn
294*f58312efSFlorian Hahnloop:
295*f58312efSFlorian Hahn  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
296*f58312efSFlorian Hahn  call void @foo()
297*f58312efSFlorian Hahn  %iv.next = add i32 %iv, 1
298*f58312efSFlorian Hahn  %ec = icmp eq i32 %iv, %N
299*f58312efSFlorian Hahn  br i1 %ec, label %exit.1, label %loop
300*f58312efSFlorian Hahn
301*f58312efSFlorian Hahnexit.1:
302*f58312efSFlorian Hahn  ret i32 10
303*f58312efSFlorian Hahn}
304*f58312efSFlorian Hahn
305*f58312efSFlorian Hahndefine i32 @test_latch_exiting2(i1 %c, i32 %N) {
306*f58312efSFlorian Hahn; CHECK-LABEL: @test_latch_exiting2(
307*f58312efSFlorian Hahn; CHECK-NEXT:  entry:
308*f58312efSFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
309*f58312efSFlorian Hahn; CHECK:       loop.header:
310*f58312efSFlorian Hahn; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
311*f58312efSFlorian Hahn; CHECK-NEXT:    br i1 [[C:%.*]], label [[LOOP_LATCH]], label [[EXIT_1:%.*]]
312*f58312efSFlorian Hahn; CHECK:       loop.latch:
313*f58312efSFlorian Hahn; CHECK-NEXT:    call void @foo()
314*f58312efSFlorian Hahn; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
315*f58312efSFlorian Hahn; CHECK-NEXT:    [[EC:%.*]] = icmp eq i32 [[IV]], [[N:%.*]]
316*f58312efSFlorian Hahn; CHECK-NEXT:    br i1 [[EC]], label [[EXIT_2:%.*]], label [[LOOP_HEADER]]
317*f58312efSFlorian Hahn; CHECK:       exit.1:
318*f58312efSFlorian Hahn; CHECK-NEXT:    ret i32 10
319*f58312efSFlorian Hahn; CHECK:       exit.2:
320*f58312efSFlorian Hahn; CHECK-NEXT:    ret i32 0
321*f58312efSFlorian Hahn;
322*f58312efSFlorian Hahnentry:
323*f58312efSFlorian Hahn  br label %loop.header
324*f58312efSFlorian Hahn
325*f58312efSFlorian Hahnloop.header:
326*f58312efSFlorian Hahn  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
327*f58312efSFlorian Hahn  br i1 %c, label %loop.latch, label %exit.1
328*f58312efSFlorian Hahn
329*f58312efSFlorian Hahnloop.latch:
330*f58312efSFlorian Hahn  call void @foo()
331*f58312efSFlorian Hahn  %iv.next = add i32 %iv, 1
332*f58312efSFlorian Hahn  %ec = icmp eq i32 %iv, %N
333*f58312efSFlorian Hahn  br i1 %ec, label %exit.2, label %loop.header
334*f58312efSFlorian Hahn
335*f58312efSFlorian Hahnexit.1:
336*f58312efSFlorian Hahn  ret i32 10
337*f58312efSFlorian Hahn
338*f58312efSFlorian Hahnexit.2:
339*f58312efSFlorian Hahn  ret i32 0
340*f58312efSFlorian Hahn}
341