1cee313d2SEric Christopher; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2cee313d2SEric Christopher; RUN: opt -S -loop-predication < %s 2>&1 | FileCheck %s
355bdb140SAnna Thomas; RUN: opt -S -passes='require<scalar-evolution>,loop-mssa(loop-predication)' -verify-memoryssa < %s 2>&1 | FileCheck %s
4cee313d2SEric Christopher
5cee313d2SEric Christopherdeclare void @llvm.experimental.guard(i1, ...)
6cee313d2SEric Christopher
7cee313d2SEric Christopherdefine i32 @unsigned_loop_0_to_n_ult_check(i32* %array, i32 %length, i32 %n) {
8cee313d2SEric Christopher; CHECK-LABEL: @unsigned_loop_0_to_n_ult_check(
9cee313d2SEric Christopher; CHECK-NEXT:  entry:
10cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
11cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
12cee313d2SEric Christopher; CHECK:       loop.preheader:
13cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]
14cee313d2SEric Christopher; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
15cee313d2SEric Christopher; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
16cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
17cee313d2SEric Christopher; CHECK:       loop:
18cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
19cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
20cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
21cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
22cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
23cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
24cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
25cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
26cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
27cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
28cee313d2SEric Christopher; CHECK:       exit.loopexit:
29cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
30cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
31cee313d2SEric Christopher; CHECK:       exit:
32cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
33cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
34cee313d2SEric Christopher;
35cee313d2SEric Christopherentry:
36cee313d2SEric Christopher  %tmp5 = icmp eq i32 %n, 0
37cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
38cee313d2SEric Christopher
39cee313d2SEric Christopherloop.preheader:
40cee313d2SEric Christopher  br label %loop
41cee313d2SEric Christopher
42cee313d2SEric Christopherloop:
43cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
44cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
45cee313d2SEric Christopher  %within.bounds = icmp ult i32 %i, %length
46cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
47cee313d2SEric Christopher
48cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
49cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
50cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
51cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
52cee313d2SEric Christopher
53cee313d2SEric Christopher  %i.next = add nuw i32 %i, 1
54cee313d2SEric Christopher  %continue = icmp ult i32 %i.next, %n
55cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
56cee313d2SEric Christopher
57cee313d2SEric Christopherexit:
58cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
59cee313d2SEric Christopher  ret i32 %result
60cee313d2SEric Christopher}
61cee313d2SEric Christopher
62cee313d2SEric Christopherdefine i32 @unsigned_loop_0_to_n_ule_latch_ult_check(i32* %array, i32 %length, i32 %n) {
63cee313d2SEric Christopher; CHECK-LABEL: @unsigned_loop_0_to_n_ule_latch_ult_check(
64cee313d2SEric Christopher; CHECK-NEXT:  entry:
65cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
66cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
67cee313d2SEric Christopher; CHECK:       loop.preheader:
68cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 [[N]], [[LENGTH:%.*]]
69cee313d2SEric Christopher; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
70cee313d2SEric Christopher; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
71cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
72cee313d2SEric Christopher; CHECK:       loop:
73cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
74cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
75cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
76cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
77cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
78cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
79cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
80cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
81cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ule i32 [[I_NEXT]], [[N]]
82cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
83cee313d2SEric Christopher; CHECK:       exit.loopexit:
84cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
85cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
86cee313d2SEric Christopher; CHECK:       exit:
87cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
88cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
89cee313d2SEric Christopher;
90cee313d2SEric Christopherentry:
91cee313d2SEric Christopher  %tmp5 = icmp eq i32 %n, 0
92cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
93cee313d2SEric Christopher
94cee313d2SEric Christopherloop.preheader:
95cee313d2SEric Christopher  br label %loop
96cee313d2SEric Christopher
97cee313d2SEric Christopherloop:
98cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
99cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
100cee313d2SEric Christopher  %within.bounds = icmp ult i32 %i, %length
101cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
102cee313d2SEric Christopher
103cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
104cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
105cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
106cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
107cee313d2SEric Christopher
108cee313d2SEric Christopher  %i.next = add nuw i32 %i, 1
109cee313d2SEric Christopher  %continue = icmp ule i32 %i.next, %n
110cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
111cee313d2SEric Christopher
112cee313d2SEric Christopherexit:
113cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
114cee313d2SEric Christopher  ret i32 %result
115cee313d2SEric Christopher}
116cee313d2SEric Christopher
117cee313d2SEric Christopherdefine i32 @unsigned_loop_0_to_n_ugt_check(i32* %array, i32 %length, i32 %n) {
118cee313d2SEric Christopher; CHECK-LABEL: @unsigned_loop_0_to_n_ugt_check(
119cee313d2SEric Christopher; CHECK-NEXT:  entry:
120cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
121cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
122cee313d2SEric Christopher; CHECK:       loop.preheader:
123cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]
124cee313d2SEric Christopher; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
125cee313d2SEric Christopher; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
126cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
127cee313d2SEric Christopher; CHECK:       loop:
128cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
129cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
130cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
131cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
132cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
133cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
134cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
135cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
136cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
137cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
138cee313d2SEric Christopher; CHECK:       exit.loopexit:
139cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
140cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
141cee313d2SEric Christopher; CHECK:       exit:
142cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
143cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
144cee313d2SEric Christopher;
145cee313d2SEric Christopherentry:
146cee313d2SEric Christopher  %tmp5 = icmp eq i32 %n, 0
147cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
148cee313d2SEric Christopher
149cee313d2SEric Christopherloop.preheader:
150cee313d2SEric Christopher  br label %loop
151cee313d2SEric Christopher
152cee313d2SEric Christopherloop:
153cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
154cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
155cee313d2SEric Christopher  %within.bounds = icmp ugt i32 %length, %i
156cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
157cee313d2SEric Christopher
158cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
159cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
160cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
161cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
162cee313d2SEric Christopher
163cee313d2SEric Christopher  %i.next = add nuw i32 %i, 1
164cee313d2SEric Christopher  %continue = icmp ult i32 %i.next, %n
165cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
166cee313d2SEric Christopher
167cee313d2SEric Christopherexit:
168cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
169cee313d2SEric Christopher  ret i32 %result
170cee313d2SEric Christopher}
171cee313d2SEric Christopher
172cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_ult_check(i32* %array, i32 %length, i32 %n) {
173cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_ult_check(
174cee313d2SEric Christopher; CHECK-NEXT:  entry:
175cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
176cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
177cee313d2SEric Christopher; CHECK:       loop.preheader:
178cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]]
179cee313d2SEric Christopher; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
180cee313d2SEric Christopher; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
181cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
182cee313d2SEric Christopher; CHECK:       loop:
183cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
184cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
185cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
186cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
187cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
188cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
189cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
190cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
191cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
192cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
193cee313d2SEric Christopher; CHECK:       exit.loopexit:
194cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
195cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
196cee313d2SEric Christopher; CHECK:       exit:
197cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
198cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
199cee313d2SEric Christopher;
200cee313d2SEric Christopherentry:
201cee313d2SEric Christopher  %tmp5 = icmp sle i32 %n, 0
202cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
203cee313d2SEric Christopher
204cee313d2SEric Christopherloop.preheader:
205cee313d2SEric Christopher  br label %loop
206cee313d2SEric Christopher
207cee313d2SEric Christopherloop:
208cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
209cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
210cee313d2SEric Christopher  %within.bounds = icmp ult i32 %i, %length
211cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
212cee313d2SEric Christopher
213cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
214cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
215cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
216cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
217cee313d2SEric Christopher
218cee313d2SEric Christopher  %i.next = add nuw i32 %i, 1
219cee313d2SEric Christopher  %continue = icmp slt i32 %i.next, %n
220cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
221cee313d2SEric Christopher
222cee313d2SEric Christopherexit:
223cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
224cee313d2SEric Christopher  ret i32 %result
225cee313d2SEric Christopher}
226cee313d2SEric Christopher
227cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_ult_check_length_range_known(i32* %array, i32* %length.ptr, i32 %n) {
228cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_ult_check_length_range_known(
229cee313d2SEric Christopher; CHECK-NEXT:  entry:
230cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
2315a8a7b3bSRoman Lebedev; CHECK-NEXT:    [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], align 4, !range [[RNG0:![0-9]+]]
232cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
233cee313d2SEric Christopher; CHECK:       loop.preheader:
234cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH]]
235b2915971SRoman Lebedev; CHECK-NEXT:    [[TMP1:%.*]] = and i1 true, [[TMP0]]
236cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
237cee313d2SEric Christopher; CHECK:       loop:
238cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
239cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
240b2915971SRoman Lebedev; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP1]], i32 9) [ "deopt"() ]
241cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
242cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
243cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
244cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
245cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
246cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
247cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
248cee313d2SEric Christopher; CHECK:       exit.loopexit:
249cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
250cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
251cee313d2SEric Christopher; CHECK:       exit:
252cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
253cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
254cee313d2SEric Christopher;
255cee313d2SEric Christopherentry:
256cee313d2SEric Christopher  %tmp5 = icmp sle i32 %n, 0
257cee313d2SEric Christopher  %length = load i32, i32* %length.ptr, !range !{i32 1, i32 2147483648}
258cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
259cee313d2SEric Christopher
260cee313d2SEric Christopherloop.preheader:
261cee313d2SEric Christopher  br label %loop
262cee313d2SEric Christopher
263cee313d2SEric Christopherloop:
264cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
265cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
266cee313d2SEric Christopher  %within.bounds = icmp ult i32 %i, %length
267cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
268cee313d2SEric Christopher
269cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
270cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
271cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
272cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
273cee313d2SEric Christopher
274cee313d2SEric Christopher  %i.next = add nuw i32 %i, 1
275cee313d2SEric Christopher  %continue = icmp slt i32 %i.next, %n
276cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
277cee313d2SEric Christopher
278cee313d2SEric Christopherexit:
279cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
280cee313d2SEric Christopher  ret i32 %result
281cee313d2SEric Christopher}
282cee313d2SEric Christopher
283cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_inverse_latch_predicate(i32* %array, i32 %length, i32 %n) {
284cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_inverse_latch_predicate(
285cee313d2SEric Christopher; CHECK-NEXT:  entry:
286cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
287cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
288cee313d2SEric Christopher; CHECK:       loop.preheader:
289cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]
290cee313d2SEric Christopher; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
291cee313d2SEric Christopher; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
292cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
293cee313d2SEric Christopher; CHECK:       loop:
294cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
295cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
296cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
297cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
298cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
299cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
300cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
301cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
302cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp sgt i32 [[I_NEXT]], [[N]]
303cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP]]
304cee313d2SEric Christopher; CHECK:       exit.loopexit:
305cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
306cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
307cee313d2SEric Christopher; CHECK:       exit:
308cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
309cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
310cee313d2SEric Christopher;
311cee313d2SEric Christopherentry:
312cee313d2SEric Christopher  %tmp5 = icmp sle i32 %n, 0
313cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
314cee313d2SEric Christopher
315cee313d2SEric Christopherloop.preheader:
316cee313d2SEric Christopher  br label %loop
317cee313d2SEric Christopher
318cee313d2SEric Christopherloop:
319cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
320cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
321cee313d2SEric Christopher  %within.bounds = icmp ult i32 %i, %length
322cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
323cee313d2SEric Christopher
324cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
325cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
326cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
327cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
328cee313d2SEric Christopher
329cee313d2SEric Christopher  %i.next = add nuw i32 %i, 1
330cee313d2SEric Christopher  %continue = icmp sgt i32 %i.next, %n
331cee313d2SEric Christopher  br i1 %continue, label %exit, label %loop
332cee313d2SEric Christopher
333cee313d2SEric Christopherexit:
334cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
335cee313d2SEric Christopher  ret i32 %result
336cee313d2SEric Christopher}
337cee313d2SEric Christopher
338cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_sle_latch_ult_check(i32* %array, i32 %length, i32 %n) {
339cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_ult_check(
340cee313d2SEric Christopher; CHECK-NEXT:  entry:
341cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
342cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
343cee313d2SEric Christopher; CHECK:       loop.preheader:
344cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]
345cee313d2SEric Christopher; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
346cee313d2SEric Christopher; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
347cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
348cee313d2SEric Christopher; CHECK:       loop:
349cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
350cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
351cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
352cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
353cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
354cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
355cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
356cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
357cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT]], [[N]]
358cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
359cee313d2SEric Christopher; CHECK:       exit.loopexit:
360cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
361cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
362cee313d2SEric Christopher; CHECK:       exit:
363cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
364cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
365cee313d2SEric Christopher;
366cee313d2SEric Christopherentry:
367cee313d2SEric Christopher  %tmp5 = icmp sle i32 %n, 0
368cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
369cee313d2SEric Christopher
370cee313d2SEric Christopherloop.preheader:
371cee313d2SEric Christopher  br label %loop
372cee313d2SEric Christopher
373cee313d2SEric Christopherloop:
374cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
375cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
376cee313d2SEric Christopher  %within.bounds = icmp ult i32 %i, %length
377cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
378cee313d2SEric Christopher
379cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
380cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
381cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
382cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
383cee313d2SEric Christopher
384cee313d2SEric Christopher  %i.next = add nuw i32 %i, 1
385cee313d2SEric Christopher  %continue = icmp sle i32 %i.next, %n
386cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
387cee313d2SEric Christopher
388cee313d2SEric Christopherexit:
389cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
390cee313d2SEric Christopher  ret i32 %result
391cee313d2SEric Christopher}
392cee313d2SEric Christopher
393cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_preincrement_latch_check(i32* %array, i32 %length, i32 %n) {
394cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check(
395cee313d2SEric Christopher; CHECK-NEXT:  entry:
396cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
397cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
398cee313d2SEric Christopher; CHECK:       loop.preheader:
399cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1
400cee313d2SEric Christopher; CHECK-NEXT:    [[TMP1:%.*]] = icmp sle i32 [[N]], [[TMP0]]
401cee313d2SEric Christopher; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 0, [[LENGTH]]
402cee313d2SEric Christopher; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
403cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
404cee313d2SEric Christopher; CHECK:       loop:
405cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
406cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
407cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
408cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
409cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
410cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
411cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
412cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
413cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I]], [[N]]
414cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
415cee313d2SEric Christopher; CHECK:       exit.loopexit:
416cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
417cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
418cee313d2SEric Christopher; CHECK:       exit:
419cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
420cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
421cee313d2SEric Christopher;
422cee313d2SEric Christopherentry:
423cee313d2SEric Christopher  %tmp5 = icmp sle i32 %n, 0
424cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
425cee313d2SEric Christopher
426cee313d2SEric Christopherloop.preheader:
427cee313d2SEric Christopher  br label %loop
428cee313d2SEric Christopher
429cee313d2SEric Christopherloop:
430cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
431cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
432cee313d2SEric Christopher  %within.bounds = icmp ult i32 %i, %length
433cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
434cee313d2SEric Christopher
435cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
436cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
437cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
438cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
439cee313d2SEric Christopher
440cee313d2SEric Christopher  %i.next = add i32 %i, 1
441cee313d2SEric Christopher  %continue = icmp slt i32 %i, %n
442cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
443cee313d2SEric Christopher
444cee313d2SEric Christopherexit:
445cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
446cee313d2SEric Christopher  ret i32 %result
447cee313d2SEric Christopher}
448cee313d2SEric Christopher
449cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check(i32* %array, i32 %length, i32 %n) {
450cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check(
451cee313d2SEric Christopher; CHECK-NEXT:  entry:
452cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
453cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
454cee313d2SEric Christopher; CHECK:       loop.preheader:
455cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -2
456cee313d2SEric Christopher; CHECK-NEXT:    [[TMP1:%.*]] = icmp sle i32 [[N]], [[TMP0]]
457cee313d2SEric Christopher; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 1, [[LENGTH]]
458cee313d2SEric Christopher; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
459cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
460cee313d2SEric Christopher; CHECK:       loop:
461cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
462cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
463cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
464cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
465cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
466cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
467cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
468cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
469cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I]], [[N]]
470cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
471cee313d2SEric Christopher; CHECK:       exit.loopexit:
472cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
473cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
474cee313d2SEric Christopher; CHECK:       exit:
475cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
476cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
477cee313d2SEric Christopher;
478cee313d2SEric Christopherentry:
479cee313d2SEric Christopher  %tmp5 = icmp sle i32 %n, 0
480cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
481cee313d2SEric Christopher
482cee313d2SEric Christopherloop.preheader:
483cee313d2SEric Christopher  br label %loop
484cee313d2SEric Christopher
485cee313d2SEric Christopherloop:
486cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
487cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
488cee313d2SEric Christopher
489cee313d2SEric Christopher  %i.next = add i32 %i, 1
490cee313d2SEric Christopher  %within.bounds = icmp ult i32 %i.next, %length
491cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
492cee313d2SEric Christopher
493cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
494cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
495cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
496cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
497cee313d2SEric Christopher
498cee313d2SEric Christopher  %continue = icmp slt i32 %i, %n
499cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
500cee313d2SEric Christopher
501cee313d2SEric Christopherexit:
502cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
503cee313d2SEric Christopher  ret i32 %result
504cee313d2SEric Christopher}
505cee313d2SEric Christopher
506cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_sle_latch_offset_ult_check(i32* %array, i32 %length, i32 %n) {
507cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_offset_ult_check(
508cee313d2SEric Christopher; CHECK-NEXT:  entry:
509cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
510cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
511cee313d2SEric Christopher; CHECK:       loop.preheader:
512cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1
513cee313d2SEric Christopher; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[N]], [[TMP0]]
514cee313d2SEric Christopher; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 1, [[LENGTH]]
515cee313d2SEric Christopher; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
516cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
517cee313d2SEric Christopher; CHECK:       loop:
518cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
519cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
520cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
521cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
522cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
523cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
524cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
525cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
526cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT]], [[N]]
527cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
528cee313d2SEric Christopher; CHECK:       exit.loopexit:
529cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
530cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
531cee313d2SEric Christopher; CHECK:       exit:
532cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
533cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
534cee313d2SEric Christopher;
535cee313d2SEric Christopherentry:
536cee313d2SEric Christopher  %tmp5 = icmp sle i32 %n, 0
537cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
538cee313d2SEric Christopher
539cee313d2SEric Christopherloop.preheader:
540cee313d2SEric Christopher  br label %loop
541cee313d2SEric Christopher
542cee313d2SEric Christopherloop:
543cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
544cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
545cee313d2SEric Christopher  %i.offset = add i32 %i, 1
546cee313d2SEric Christopher  %within.bounds = icmp ult i32 %i.offset, %length
547cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
548cee313d2SEric Christopher
549cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
550cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
551cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
552cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
553cee313d2SEric Christopher
554cee313d2SEric Christopher  %i.next = add i32 %i, 1
555cee313d2SEric Christopher  %continue = icmp sle i32 %i.next, %n
556cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
557cee313d2SEric Christopher
558cee313d2SEric Christopherexit:
559cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
560cee313d2SEric Christopher  ret i32 %result
561cee313d2SEric Christopher}
562cee313d2SEric Christopher
563cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_offset_sle_latch_offset_ult_check(i32* %array, i32 %length, i32 %n) {
564cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_offset_sle_latch_offset_ult_check(
565cee313d2SEric Christopher; CHECK-NEXT:  entry:
566cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
567cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
568cee313d2SEric Christopher; CHECK:       loop.preheader:
569cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]
570cee313d2SEric Christopher; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 1, [[LENGTH]]
571cee313d2SEric Christopher; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
572cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
573cee313d2SEric Christopher; CHECK:       loop:
574cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
575cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
576cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
577cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
578cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
579cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
580cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
581cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
582cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT_OFFSET:%.*]] = add i32 [[I_NEXT]], 1
583cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT_OFFSET]], [[N]]
584cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
585cee313d2SEric Christopher; CHECK:       exit.loopexit:
586cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
587cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
588cee313d2SEric Christopher; CHECK:       exit:
589cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
590cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
591cee313d2SEric Christopher;
592cee313d2SEric Christopherentry:
593cee313d2SEric Christopher  %tmp5 = icmp sle i32 %n, 0
594cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
595cee313d2SEric Christopher
596cee313d2SEric Christopherloop.preheader:
597cee313d2SEric Christopher  br label %loop
598cee313d2SEric Christopher
599cee313d2SEric Christopherloop:
600cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
601cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
602cee313d2SEric Christopher  %i.offset = add i32 %i, 1
603cee313d2SEric Christopher  %within.bounds = icmp ult i32 %i.offset, %length
604cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
605cee313d2SEric Christopher
606cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
607cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
608cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
609cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
610cee313d2SEric Christopher
611cee313d2SEric Christopher  %i.next = add i32 %i, 1
612cee313d2SEric Christopher  %i.next.offset = add i32 %i.next, 1
613cee313d2SEric Christopher  %continue = icmp sle i32 %i.next.offset, %n
614cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
615cee313d2SEric Christopher
616cee313d2SEric Christopherexit:
617cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
618cee313d2SEric Christopher  ret i32 %result
619cee313d2SEric Christopher}
620cee313d2SEric Christopher
621cee313d2SEric Christopherdefine i32 @unsupported_latch_pred_loop_0_to_n(i32* %array, i32 %length, i32 %n) {
622cee313d2SEric Christopher; CHECK-LABEL: @unsupported_latch_pred_loop_0_to_n(
623cee313d2SEric Christopher; CHECK-NEXT:  entry:
624cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
625cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
626cee313d2SEric Christopher; CHECK:       loop.preheader:
627cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
628cee313d2SEric Christopher; CHECK:       loop:
629cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
630cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
631cee313d2SEric Christopher; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
632cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
633cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
634cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
635cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
636cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
637cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
638cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[N]]
639cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
640cee313d2SEric Christopher; CHECK:       exit.loopexit:
641cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
642cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
643cee313d2SEric Christopher; CHECK:       exit:
644cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
645cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
646cee313d2SEric Christopher;
647cee313d2SEric Christopherentry:
648cee313d2SEric Christopher  %tmp5 = icmp sle i32 %n, 0
649cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
650cee313d2SEric Christopher
651cee313d2SEric Christopherloop.preheader:
652cee313d2SEric Christopher  br label %loop
653cee313d2SEric Christopher
654cee313d2SEric Christopherloop:
655cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
656cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
657cee313d2SEric Christopher  %within.bounds = icmp ult i32 %i, %length
658cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
659cee313d2SEric Christopher
660cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
661cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
662cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
663cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
664cee313d2SEric Christopher
665cee313d2SEric Christopher  %i.next = add nsw i32 %i, 1
666cee313d2SEric Christopher  %continue = icmp ne i32 %i.next, %n
667cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
668cee313d2SEric Christopher
669cee313d2SEric Christopherexit:
670cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
671cee313d2SEric Christopher  ret i32 %result
672cee313d2SEric Christopher}
673cee313d2SEric Christopher
674cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_unsupported_iv_step(i32* %array, i32 %length, i32 %n) {
675cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_unsupported_iv_step(
676cee313d2SEric Christopher; CHECK-NEXT:  entry:
677cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
678cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
679cee313d2SEric Christopher; CHECK:       loop.preheader:
680cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
681cee313d2SEric Christopher; CHECK:       loop:
682cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
683cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
684cee313d2SEric Christopher; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
685cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
686cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
687cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
688cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
689cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
690cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 2
691cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
692cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
693cee313d2SEric Christopher; CHECK:       exit.loopexit:
694cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
695cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
696cee313d2SEric Christopher; CHECK:       exit:
697cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
698cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
699cee313d2SEric Christopher;
700cee313d2SEric Christopherentry:
701cee313d2SEric Christopher  %tmp5 = icmp sle i32 %n, 0
702cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
703cee313d2SEric Christopher
704cee313d2SEric Christopherloop.preheader:
705cee313d2SEric Christopher  br label %loop
706cee313d2SEric Christopher
707cee313d2SEric Christopherloop:
708cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
709cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
710cee313d2SEric Christopher  %within.bounds = icmp ult i32 %i, %length
711cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
712cee313d2SEric Christopher
713cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
714cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
715cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
716cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
717cee313d2SEric Christopher
718cee313d2SEric Christopher  %i.next = add nsw i32 %i, 2
719cee313d2SEric Christopher  %continue = icmp slt i32 %i.next, %n
720cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
721cee313d2SEric Christopher
722cee313d2SEric Christopherexit:
723cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
724cee313d2SEric Christopher  ret i32 %result
725cee313d2SEric Christopher}
726cee313d2SEric Christopher
727cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_equal_iv_range_check(i32* %array, i32 %length, i32 %n) {
728cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_equal_iv_range_check(
729cee313d2SEric Christopher; CHECK-NEXT:  entry:
730cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
731cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
732cee313d2SEric Christopher; CHECK:       loop.preheader:
733cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]]
734cee313d2SEric Christopher; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
735cee313d2SEric Christopher; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
736cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
737cee313d2SEric Christopher; CHECK:       loop:
738cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
739cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
740cee313d2SEric Christopher; CHECK-NEXT:    [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
741cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
742cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
743cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
744cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
745cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
746cee313d2SEric Christopher; CHECK-NEXT:    [[J_NEXT]] = add nsw i32 [[J]], 1
747cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
748cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
749cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
750cee313d2SEric Christopher; CHECK:       exit.loopexit:
751cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
752cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
753cee313d2SEric Christopher; CHECK:       exit:
754cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
755cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
756cee313d2SEric Christopher;
757cee313d2SEric Christopherentry:
758cee313d2SEric Christopher  %tmp5 = icmp sle i32 %n, 0
759cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
760cee313d2SEric Christopher
761cee313d2SEric Christopherloop.preheader:
762cee313d2SEric Christopher  br label %loop
763cee313d2SEric Christopher
764cee313d2SEric Christopherloop:
765cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
766cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
767cee313d2SEric Christopher  %j = phi i32 [ %j.next, %loop ], [ 0, %loop.preheader ]
768cee313d2SEric Christopher
769cee313d2SEric Christopher  %within.bounds = icmp ult i32 %j, %length
770cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
771cee313d2SEric Christopher
772cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
773cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
774cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
775cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
776cee313d2SEric Christopher
777cee313d2SEric Christopher  %j.next = add nsw i32 %j, 1
778cee313d2SEric Christopher  %i.next = add nsw i32 %i, 1
779cee313d2SEric Christopher  %continue = icmp slt i32 %i.next, %n
780cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
781cee313d2SEric Christopher
782cee313d2SEric Christopherexit:
783cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
784cee313d2SEric Christopher  ret i32 %result
785cee313d2SEric Christopher}
786cee313d2SEric Christopher
787cee313d2SEric Christopherdefine i32 @signed_loop_start_to_n_offset_iv_range_check(i32* %array, i32 %start.i,
788cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_start_to_n_offset_iv_range_check(
789cee313d2SEric Christopher; CHECK-NEXT:  entry:
790cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
791cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
792cee313d2SEric Christopher; CHECK:       loop.preheader:
793cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], [[START_I:%.*]]
794cee313d2SEric Christopher; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[TMP0]], [[START_J:%.*]]
795cee313d2SEric Christopher; CHECK-NEXT:    [[TMP2:%.*]] = icmp sle i32 [[N]], [[TMP1]]
796cee313d2SEric Christopher; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i32 [[START_J]], [[LENGTH]]
797cee313d2SEric Christopher; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[TMP2]]
798cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
799cee313d2SEric Christopher; CHECK:       loop:
800cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
801cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[START_I]], [[LOOP_PREHEADER]] ]
802cee313d2SEric Christopher; CHECK-NEXT:    [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[LOOP]] ], [ [[START_J]], [[LOOP_PREHEADER]] ]
803cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP4]], i32 9) [ "deopt"() ]
804cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
805cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
806cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
807cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
808cee313d2SEric Christopher; CHECK-NEXT:    [[J_NEXT]] = add i32 [[J]], 1
809cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
810cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
811cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
812cee313d2SEric Christopher; CHECK:       exit.loopexit:
813cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
814cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
815cee313d2SEric Christopher; CHECK:       exit:
816cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
817cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
818cee313d2SEric Christopher;
819cee313d2SEric Christopher  i32 %start.j, i32 %length,
820cee313d2SEric Christopher  i32 %n) {
821cee313d2SEric Christopherentry:
822cee313d2SEric Christopher  %tmp5 = icmp sle i32 %n, 0
823cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
824cee313d2SEric Christopher
825cee313d2SEric Christopherloop.preheader:
826cee313d2SEric Christopher  br label %loop
827cee313d2SEric Christopher
828cee313d2SEric Christopherloop:
829cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
830cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ %start.i, %loop.preheader ]
831cee313d2SEric Christopher  %j = phi i32 [ %j.next, %loop ], [ %start.j, %loop.preheader ]
832cee313d2SEric Christopher
833cee313d2SEric Christopher  %within.bounds = icmp ult i32 %j, %length
834cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
835cee313d2SEric Christopher
836cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
837cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
838cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
839cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
840cee313d2SEric Christopher
841cee313d2SEric Christopher  %j.next = add i32 %j, 1
842cee313d2SEric Christopher  %i.next = add i32 %i, 1
843cee313d2SEric Christopher  %continue = icmp slt i32 %i.next, %n
844cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
845cee313d2SEric Christopher
846cee313d2SEric Christopherexit:
847cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
848cee313d2SEric Christopher  ret i32 %result
849cee313d2SEric Christopher}
850cee313d2SEric Christopher
851cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_different_iv_types(i32* %array, i16 %length, i32 %n) {
852cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_different_iv_types(
853cee313d2SEric Christopher; CHECK-NEXT:  entry:
854cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
855cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
856cee313d2SEric Christopher; CHECK:       loop.preheader:
857cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
858cee313d2SEric Christopher; CHECK:       loop:
859cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
860cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
861cee313d2SEric Christopher; CHECK-NEXT:    [[J:%.*]] = phi i16 [ [[J_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
862cee313d2SEric Christopher; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i16 [[J]], [[LENGTH:%.*]]
863cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
864cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
865cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
866cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
867cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
868cee313d2SEric Christopher; CHECK-NEXT:    [[J_NEXT]] = add i16 [[J]], 1
869cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
870cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
871cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
872cee313d2SEric Christopher; CHECK:       exit.loopexit:
873cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
874cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
875cee313d2SEric Christopher; CHECK:       exit:
876cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
877cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
878cee313d2SEric Christopher;
879cee313d2SEric Christopherentry:
880cee313d2SEric Christopher  %tmp5 = icmp sle i32 %n, 0
881cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
882cee313d2SEric Christopher
883cee313d2SEric Christopherloop.preheader:
884cee313d2SEric Christopher  br label %loop
885cee313d2SEric Christopher
886cee313d2SEric Christopherloop:
887cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
888cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
889cee313d2SEric Christopher  %j = phi i16 [ %j.next, %loop ], [ 0, %loop.preheader ]
890cee313d2SEric Christopher
891cee313d2SEric Christopher  %within.bounds = icmp ult i16 %j, %length
892cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
893cee313d2SEric Christopher
894cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
895cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
896cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
897cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
898cee313d2SEric Christopher
899cee313d2SEric Christopher  %j.next = add i16 %j, 1
900cee313d2SEric Christopher  %i.next = add i32 %i, 1
901cee313d2SEric Christopher  %continue = icmp slt i32 %i.next, %n
902cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
903cee313d2SEric Christopher
904cee313d2SEric Christopherexit:
905cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
906cee313d2SEric Christopher  ret i32 %result
907cee313d2SEric Christopher}
908cee313d2SEric Christopher
909cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_different_iv_strides(i32* %array, i32 %length, i32 %n) {
910cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_different_iv_strides(
911cee313d2SEric Christopher; CHECK-NEXT:  entry:
912cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
913cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
914cee313d2SEric Christopher; CHECK:       loop.preheader:
915cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
916cee313d2SEric Christopher; CHECK:       loop:
917cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
918cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
919cee313d2SEric Christopher; CHECK-NEXT:    [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
920cee313d2SEric Christopher; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH:%.*]]
921cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
922cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
923cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
924cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
925cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
926cee313d2SEric Christopher; CHECK-NEXT:    [[J_NEXT]] = add nsw i32 [[J]], 2
927cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
928cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
929cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
930cee313d2SEric Christopher; CHECK:       exit.loopexit:
931cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
932cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
933cee313d2SEric Christopher; CHECK:       exit:
934cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
935cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
936cee313d2SEric Christopher;
937cee313d2SEric Christopherentry:
938cee313d2SEric Christopher  %tmp5 = icmp sle i32 %n, 0
939cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
940cee313d2SEric Christopher
941cee313d2SEric Christopherloop.preheader:
942cee313d2SEric Christopher  br label %loop
943cee313d2SEric Christopher
944cee313d2SEric Christopherloop:
945cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
946cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
947cee313d2SEric Christopher  %j = phi i32 [ %j.next, %loop ], [ 0, %loop.preheader ]
948cee313d2SEric Christopher
949cee313d2SEric Christopher  %within.bounds = icmp ult i32 %j, %length
950cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
951cee313d2SEric Christopher
952cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
953cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
954cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
955cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
956cee313d2SEric Christopher
957cee313d2SEric Christopher  %j.next = add nsw i32 %j, 2
958cee313d2SEric Christopher  %i.next = add nsw i32 %i, 1
959cee313d2SEric Christopher  %continue = icmp slt i32 %i.next, %n
960cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
961cee313d2SEric Christopher
962cee313d2SEric Christopherexit:
963cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
964cee313d2SEric Christopher  ret i32 %result
965cee313d2SEric Christopher}
966cee313d2SEric Christopher
967cee313d2SEric Christopherdefine i32 @two_range_checks(i32* %array.1, i32 %length.1,
968cee313d2SEric Christopher; CHECK-LABEL: @two_range_checks(
969cee313d2SEric Christopher; CHECK-NEXT:  entry:
970cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
971cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
972cee313d2SEric Christopher; CHECK:       loop.preheader:
973cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]
974cee313d2SEric Christopher; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_2]]
975cee313d2SEric Christopher; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
976cee313d2SEric Christopher; CHECK-NEXT:    [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]
977cee313d2SEric Christopher; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_1]]
978cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]]
979cee313d2SEric Christopher; CHECK-NEXT:    [[TMP6:%.*]] = and i1 [[TMP2]], [[TMP5]]
980cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
981cee313d2SEric Christopher; CHECK:       loop:
982cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
983cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
984cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP6]], i32 9) [ "deopt"() ]
985cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
986cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]]
987cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4
988cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
989cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]]
990cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4
991cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
992cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
993cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
994cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
995cee313d2SEric Christopher; CHECK:       exit.loopexit:
996cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
997cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
998cee313d2SEric Christopher; CHECK:       exit:
999cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1000cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
1001cee313d2SEric Christopher;
1002cee313d2SEric Christopher  i32* %array.2, i32 %length.2, i32 %n) {
1003cee313d2SEric Christopherentry:
1004cee313d2SEric Christopher  %tmp5 = icmp eq i32 %n, 0
1005cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
1006cee313d2SEric Christopher
1007cee313d2SEric Christopherloop.preheader:
1008cee313d2SEric Christopher  br label %loop
1009cee313d2SEric Christopher
1010cee313d2SEric Christopherloop:
1011cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1012cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1013cee313d2SEric Christopher  %within.bounds.1 = icmp ult i32 %i, %length.1
1014cee313d2SEric Christopher  %within.bounds.2 = icmp ult i32 %i, %length.2
1015cee313d2SEric Christopher  %within.bounds = and i1 %within.bounds.1, %within.bounds.2
1016cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1017cee313d2SEric Christopher
1018cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
1019cee313d2SEric Christopher  %array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64
1020cee313d2SEric Christopher  %array.1.i = load i32, i32* %array.1.i.ptr, align 4
1021cee313d2SEric Christopher  %loop.acc.1 = add i32 %loop.acc, %array.1.i
1022cee313d2SEric Christopher
1023cee313d2SEric Christopher  %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64
1024cee313d2SEric Christopher  %array.2.i = load i32, i32* %array.2.i.ptr, align 4
1025cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc.1, %array.2.i
1026cee313d2SEric Christopher
1027cee313d2SEric Christopher  %i.next = add nuw i32 %i, 1
1028cee313d2SEric Christopher  %continue = icmp ult i32 %i.next, %n
1029cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
1030cee313d2SEric Christopher
1031cee313d2SEric Christopherexit:
1032cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
1033cee313d2SEric Christopher  ret i32 %result
1034cee313d2SEric Christopher}
1035cee313d2SEric Christopher
1036cee313d2SEric Christopherdefine i32 @three_range_checks(i32* %array.1, i32 %length.1,
1037cee313d2SEric Christopher; CHECK-LABEL: @three_range_checks(
1038cee313d2SEric Christopher; CHECK-NEXT:  entry:
1039cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1040cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1041cee313d2SEric Christopher; CHECK:       loop.preheader:
1042cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_3:%.*]]
1043cee313d2SEric Christopher; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_3]]
1044cee313d2SEric Christopher; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
1045cee313d2SEric Christopher; CHECK-NEXT:    [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]
1046cee313d2SEric Christopher; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_2]]
1047cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]]
1048cee313d2SEric Christopher; CHECK-NEXT:    [[TMP6:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]
1049cee313d2SEric Christopher; CHECK-NEXT:    [[TMP7:%.*]] = icmp ult i32 0, [[LENGTH_1]]
1050cee313d2SEric Christopher; CHECK-NEXT:    [[TMP8:%.*]] = and i1 [[TMP7]], [[TMP6]]
1051cee313d2SEric Christopher; CHECK-NEXT:    [[TMP9:%.*]] = and i1 [[TMP2]], [[TMP5]]
1052cee313d2SEric Christopher; CHECK-NEXT:    [[TMP10:%.*]] = and i1 [[TMP9]], [[TMP8]]
1053cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
1054cee313d2SEric Christopher; CHECK:       loop:
1055cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1056cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1057cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP10]], i32 9) [ "deopt"() ]
1058cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1059cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]]
1060cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4
1061cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
1062cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]]
1063cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4
1064cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
1065cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_3:%.*]], i64 [[I_I64]]
1066cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_3_I:%.*]] = load i32, i32* [[ARRAY_3_I_PTR]], align 4
1067cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]]
1068cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1069cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1070cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1071cee313d2SEric Christopher; CHECK:       exit.loopexit:
1072cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1073cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
1074cee313d2SEric Christopher; CHECK:       exit:
1075cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1076cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
1077cee313d2SEric Christopher;
1078cee313d2SEric Christopher  i32* %array.2, i32 %length.2,
1079cee313d2SEric Christopher  i32* %array.3, i32 %length.3, i32 %n) {
1080cee313d2SEric Christopherentry:
1081cee313d2SEric Christopher  %tmp5 = icmp eq i32 %n, 0
1082cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
1083cee313d2SEric Christopher
1084cee313d2SEric Christopherloop.preheader:
1085cee313d2SEric Christopher  br label %loop
1086cee313d2SEric Christopher
1087cee313d2SEric Christopherloop:
1088cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1089cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1090cee313d2SEric Christopher  %within.bounds.1 = icmp ult i32 %i, %length.1
1091cee313d2SEric Christopher  %within.bounds.2 = icmp ult i32 %i, %length.2
1092cee313d2SEric Christopher  %within.bounds.3 = icmp ult i32 %i, %length.3
1093cee313d2SEric Christopher  %within.bounds.1.and.2 = and i1 %within.bounds.1, %within.bounds.2
1094cee313d2SEric Christopher  %within.bounds = and i1 %within.bounds.1.and.2, %within.bounds.3
1095cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1096cee313d2SEric Christopher
1097cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
1098cee313d2SEric Christopher  %array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64
1099cee313d2SEric Christopher  %array.1.i = load i32, i32* %array.1.i.ptr, align 4
1100cee313d2SEric Christopher  %loop.acc.1 = add i32 %loop.acc, %array.1.i
1101cee313d2SEric Christopher
1102cee313d2SEric Christopher  %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64
1103cee313d2SEric Christopher  %array.2.i = load i32, i32* %array.2.i.ptr, align 4
1104cee313d2SEric Christopher  %loop.acc.2 = add i32 %loop.acc.1, %array.2.i
1105cee313d2SEric Christopher
1106cee313d2SEric Christopher  %array.3.i.ptr = getelementptr inbounds i32, i32* %array.3, i64 %i.i64
1107cee313d2SEric Christopher  %array.3.i = load i32, i32* %array.3.i.ptr, align 4
1108cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc.2, %array.3.i
1109cee313d2SEric Christopher
1110cee313d2SEric Christopher  %i.next = add nuw i32 %i, 1
1111cee313d2SEric Christopher  %continue = icmp ult i32 %i.next, %n
1112cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
1113cee313d2SEric Christopher
1114cee313d2SEric Christopherexit:
1115cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
1116cee313d2SEric Christopher  ret i32 %result
1117cee313d2SEric Christopher}
1118cee313d2SEric Christopher
1119cee313d2SEric Christopherdefine i32 @three_guards(i32* %array.1, i32 %length.1,
1120cee313d2SEric Christopher; CHECK-LABEL: @three_guards(
1121cee313d2SEric Christopher; CHECK-NEXT:  entry:
1122cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1123cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1124cee313d2SEric Christopher; CHECK:       loop.preheader:
1125cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]
1126cee313d2SEric Christopher; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_1]]
1127cee313d2SEric Christopher; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
1128cee313d2SEric Christopher; CHECK-NEXT:    [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]
1129cee313d2SEric Christopher; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_2]]
1130cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]]
1131cee313d2SEric Christopher; CHECK-NEXT:    [[TMP6:%.*]] = icmp ule i32 [[N]], [[LENGTH_3:%.*]]
1132cee313d2SEric Christopher; CHECK-NEXT:    [[TMP7:%.*]] = icmp ult i32 0, [[LENGTH_3]]
1133cee313d2SEric Christopher; CHECK-NEXT:    [[TMP8:%.*]] = and i1 [[TMP7]], [[TMP6]]
1134cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
1135cee313d2SEric Christopher; CHECK:       loop:
1136cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1137cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1138cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
1139cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1140cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]]
1141cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4
1142cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
1143cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP5]], i32 9) [ "deopt"() ]
1144cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]]
1145cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4
1146cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
1147cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP8]], i32 9) [ "deopt"() ]
1148cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_3:%.*]], i64 [[I_I64]]
1149cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_3_I:%.*]] = load i32, i32* [[ARRAY_3_I_PTR]], align 4
1150cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]]
1151cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1152cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1153cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1154cee313d2SEric Christopher; CHECK:       exit.loopexit:
1155cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1156cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
1157cee313d2SEric Christopher; CHECK:       exit:
1158cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1159cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
1160cee313d2SEric Christopher;
1161cee313d2SEric Christopher  i32* %array.2, i32 %length.2,
1162cee313d2SEric Christopher  i32* %array.3, i32 %length.3, i32 %n) {
1163cee313d2SEric Christopherentry:
1164cee313d2SEric Christopher  %tmp5 = icmp eq i32 %n, 0
1165cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
1166cee313d2SEric Christopher
1167cee313d2SEric Christopherloop.preheader:
1168cee313d2SEric Christopher  br label %loop
1169cee313d2SEric Christopher
1170cee313d2SEric Christopherloop:
1171cee313d2SEric Christopher
1172cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1173cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1174cee313d2SEric Christopher
1175cee313d2SEric Christopher  %within.bounds.1 = icmp ult i32 %i, %length.1
1176cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.1, i32 9) [ "deopt"() ]
1177cee313d2SEric Christopher
1178cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
1179cee313d2SEric Christopher  %array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64
1180cee313d2SEric Christopher  %array.1.i = load i32, i32* %array.1.i.ptr, align 4
1181cee313d2SEric Christopher  %loop.acc.1 = add i32 %loop.acc, %array.1.i
1182cee313d2SEric Christopher
1183cee313d2SEric Christopher  %within.bounds.2 = icmp ult i32 %i, %length.2
1184cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.2, i32 9) [ "deopt"() ]
1185cee313d2SEric Christopher
1186cee313d2SEric Christopher  %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64
1187cee313d2SEric Christopher  %array.2.i = load i32, i32* %array.2.i.ptr, align 4
1188cee313d2SEric Christopher  %loop.acc.2 = add i32 %loop.acc.1, %array.2.i
1189cee313d2SEric Christopher
1190cee313d2SEric Christopher  %within.bounds.3 = icmp ult i32 %i, %length.3
1191cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.3, i32 9) [ "deopt"() ]
1192cee313d2SEric Christopher
1193cee313d2SEric Christopher  %array.3.i.ptr = getelementptr inbounds i32, i32* %array.3, i64 %i.i64
1194cee313d2SEric Christopher  %array.3.i = load i32, i32* %array.3.i.ptr, align 4
1195cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc.2, %array.3.i
1196cee313d2SEric Christopher
1197cee313d2SEric Christopher  %i.next = add nuw i32 %i, 1
1198cee313d2SEric Christopher  %continue = icmp ult i32 %i.next, %n
1199cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
1200cee313d2SEric Christopher
1201cee313d2SEric Christopherexit:
1202cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
1203cee313d2SEric Christopher  ret i32 %result
1204cee313d2SEric Christopher}
1205cee313d2SEric Christopher
1206cee313d2SEric Christopherdefine i32 @unsigned_loop_0_to_n_unrelated_condition(i32* %array, i32 %length, i32 %n, i32 %x) {
1207cee313d2SEric Christopher; CHECK-LABEL: @unsigned_loop_0_to_n_unrelated_condition(
1208cee313d2SEric Christopher; CHECK-NEXT:  entry:
1209cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1210cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1211cee313d2SEric Christopher; CHECK:       loop.preheader:
1212cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]
1213cee313d2SEric Christopher; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
1214cee313d2SEric Christopher; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
1215cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
1216cee313d2SEric Christopher; CHECK:       loop:
1217cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1218cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1219cee313d2SEric Christopher; CHECK-NEXT:    [[UNRELATED_COND:%.*]] = icmp ult i32 [[X:%.*]], [[LENGTH]]
1220cee313d2SEric Christopher; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[UNRELATED_COND]], [[TMP2]]
1221cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
1222cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1223cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1224cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1225cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1226cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1227cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1228cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1229cee313d2SEric Christopher; CHECK:       exit.loopexit:
1230cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1231cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
1232cee313d2SEric Christopher; CHECK:       exit:
1233cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1234cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
1235cee313d2SEric Christopher;
1236cee313d2SEric Christopherentry:
1237cee313d2SEric Christopher  %tmp5 = icmp eq i32 %n, 0
1238cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
1239cee313d2SEric Christopher
1240cee313d2SEric Christopherloop.preheader:
1241cee313d2SEric Christopher  br label %loop
1242cee313d2SEric Christopher
1243cee313d2SEric Christopherloop:
1244cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1245cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1246cee313d2SEric Christopher  %within.bounds = icmp ult i32 %i, %length
1247cee313d2SEric Christopher  %unrelated.cond = icmp ult i32 %x, %length
1248cee313d2SEric Christopher  %guard.cond = and i1 %within.bounds, %unrelated.cond
1249cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ]
1250cee313d2SEric Christopher
1251cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
1252cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1253cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
1254cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
1255cee313d2SEric Christopher
1256cee313d2SEric Christopher  %i.next = add nuw i32 %i, 1
1257cee313d2SEric Christopher  %continue = icmp ult i32 %i.next, %n
1258cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
1259cee313d2SEric Christopher
1260cee313d2SEric Christopherexit:
1261cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
1262cee313d2SEric Christopher  ret i32 %result
1263cee313d2SEric Christopher}
1264cee313d2SEric Christopher
1265cee313d2SEric Christopher; Don't change the guard condition if there were no widened subconditions
1266cee313d2SEric Christopherdefine i32 @test_no_widened_conditions(i32* %array, i32 %length, i32 %n, i32 %x1, i32 %x2, i32 %x3) {
1267cee313d2SEric Christopher; CHECK-LABEL: @test_no_widened_conditions(
1268cee313d2SEric Christopher; CHECK-NEXT:  entry:
1269cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1270cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1271cee313d2SEric Christopher; CHECK:       loop.preheader:
1272cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
1273cee313d2SEric Christopher; CHECK:       loop:
1274cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1275cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1276cee313d2SEric Christopher; CHECK-NEXT:    [[UNRELATED_COND_1:%.*]] = icmp eq i32 [[X1:%.*]], [[I]]
1277cee313d2SEric Christopher; CHECK-NEXT:    [[UNRELATED_COND_2:%.*]] = icmp eq i32 [[X2:%.*]], [[I]]
1278cee313d2SEric Christopher; CHECK-NEXT:    [[UNRELATED_COND_3:%.*]] = icmp eq i32 [[X3:%.*]], [[I]]
1279cee313d2SEric Christopher; CHECK-NEXT:    [[UNRELATED_COND_AND_1:%.*]] = and i1 [[UNRELATED_COND_1]], [[UNRELATED_COND_2]]
1280cee313d2SEric Christopher; CHECK-NEXT:    [[GUARD_COND:%.*]] = and i1 [[UNRELATED_COND_AND_1]], [[UNRELATED_COND_3]]
1281cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[GUARD_COND]], i32 9) [ "deopt"() ]
1282cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1283cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1284cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1285cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1286cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1287cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1288cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1289cee313d2SEric Christopher; CHECK:       exit.loopexit:
1290cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1291cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
1292cee313d2SEric Christopher; CHECK:       exit:
1293cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1294cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
1295cee313d2SEric Christopher;
1296cee313d2SEric Christopherentry:
1297cee313d2SEric Christopher  %tmp5 = icmp eq i32 %n, 0
1298cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
1299cee313d2SEric Christopher
1300cee313d2SEric Christopherloop.preheader:
1301cee313d2SEric Christopher  br label %loop
1302cee313d2SEric Christopher
1303cee313d2SEric Christopherloop:
1304cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1305cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1306cee313d2SEric Christopher  %unrelated.cond.1 = icmp eq i32 %x1, %i
1307cee313d2SEric Christopher  %unrelated.cond.2 = icmp eq i32 %x2, %i
1308cee313d2SEric Christopher  %unrelated.cond.3 = icmp eq i32 %x3, %i
1309cee313d2SEric Christopher  %unrelated.cond.and.1 = and i1 %unrelated.cond.1, %unrelated.cond.2
1310cee313d2SEric Christopher  %guard.cond = and i1 %unrelated.cond.and.1, %unrelated.cond.3
1311cee313d2SEric Christopher
1312cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ]
1313cee313d2SEric Christopher
1314cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
1315cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1316cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
1317cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
1318cee313d2SEric Christopher
1319cee313d2SEric Christopher  %i.next = add nuw i32 %i, 1
1320cee313d2SEric Christopher  %continue = icmp ult i32 %i.next, %n
1321cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
1322cee313d2SEric Christopher
1323cee313d2SEric Christopherexit:
1324cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
1325cee313d2SEric Christopher  ret i32 %result
1326cee313d2SEric Christopher}
1327cee313d2SEric Christopher
1328cee313d2SEric Christopherdefine i32 @signed_loop_start_to_n_loop_variant_bound(i32* %array, i32 %x, i32 %start, i32 %n) {
1329cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_start_to_n_loop_variant_bound(
1330cee313d2SEric Christopher; CHECK-NEXT:  entry:
1331cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
1332cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1333cee313d2SEric Christopher; CHECK:       loop.preheader:
1334cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
1335cee313d2SEric Christopher; CHECK:       loop:
1336cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1337cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ]
1338cee313d2SEric Christopher; CHECK-NEXT:    [[BOUND:%.*]] = add i32 [[I]], [[X:%.*]]
1339cee313d2SEric Christopher; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[BOUND]]
1340cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
1341cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1342cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1343cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1344cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1345cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
1346cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1347cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1348cee313d2SEric Christopher; CHECK:       exit.loopexit:
1349cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1350cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
1351cee313d2SEric Christopher; CHECK:       exit:
1352cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1353cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
1354cee313d2SEric Christopher;
1355cee313d2SEric Christopherentry:
1356cee313d2SEric Christopher  %tmp5 = icmp sle i32 %n, 0
1357cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
1358cee313d2SEric Christopher
1359cee313d2SEric Christopherloop.preheader:
1360cee313d2SEric Christopher  br label %loop
1361cee313d2SEric Christopher
1362cee313d2SEric Christopherloop:
1363cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1364cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ %start, %loop.preheader ]
1365cee313d2SEric Christopher  %bound = add i32 %i, %x
1366cee313d2SEric Christopher  %within.bounds = icmp ult i32 %i, %bound
1367cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1368cee313d2SEric Christopher
1369cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
1370cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1371cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
1372cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
1373cee313d2SEric Christopher
1374cee313d2SEric Christopher  %i.next = add nsw i32 %i, 1
1375cee313d2SEric Christopher  %continue = icmp slt i32 %i.next, %n
1376cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
1377cee313d2SEric Christopher
1378cee313d2SEric Christopherexit:
1379cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
1380cee313d2SEric Christopher  ret i32 %result
1381cee313d2SEric Christopher}
1382cee313d2SEric Christopher
1383cee313d2SEric Christopherdefine i32 @signed_loop_start_to_n_non_monotonic_predicate(i32* %array, i32 %x, i32 %start, i32 %n) {
1384cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_start_to_n_non_monotonic_predicate(
1385cee313d2SEric Christopher; CHECK-NEXT:  entry:
1386cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
1387cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1388cee313d2SEric Christopher; CHECK:       loop.preheader:
1389cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
1390cee313d2SEric Christopher; CHECK:       loop:
1391cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1392cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ]
1393cee313d2SEric Christopher; CHECK-NEXT:    [[GUARD_COND:%.*]] = icmp eq i32 [[I]], [[X:%.*]]
1394cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[GUARD_COND]], i32 9) [ "deopt"() ]
1395cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1396cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1397cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1398cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1399cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
1400cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1401cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1402cee313d2SEric Christopher; CHECK:       exit.loopexit:
1403cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1404cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
1405cee313d2SEric Christopher; CHECK:       exit:
1406cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1407cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
1408cee313d2SEric Christopher;
1409cee313d2SEric Christopherentry:
1410cee313d2SEric Christopher  %tmp5 = icmp sle i32 %n, 0
1411cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
1412cee313d2SEric Christopher
1413cee313d2SEric Christopherloop.preheader:
1414cee313d2SEric Christopher  br label %loop
1415cee313d2SEric Christopher
1416cee313d2SEric Christopherloop:
1417cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1418cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ %start, %loop.preheader ]
1419cee313d2SEric Christopher  %guard.cond = icmp eq i32 %i, %x
1420cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ]
1421cee313d2SEric Christopher
1422cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
1423cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1424cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
1425cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
1426cee313d2SEric Christopher
1427cee313d2SEric Christopher  %i.next = add nsw i32 %i, 1
1428cee313d2SEric Christopher  %continue = icmp slt i32 %i.next, %n
1429cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
1430cee313d2SEric Christopher
1431cee313d2SEric Christopherexit:
1432cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
1433cee313d2SEric Christopher  ret i32 %result
1434cee313d2SEric Christopher}
1435cee313d2SEric Christopher
1436cee313d2SEric Christopherdefine i32 @unsigned_loop_0_to_n_hoist_length(i32* %array, i16 %length.i16, i32 %n) {
1437cee313d2SEric Christopher; CHECK-LABEL: @unsigned_loop_0_to_n_hoist_length(
1438cee313d2SEric Christopher; CHECK-NEXT:  entry:
1439cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1440cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1441cee313d2SEric Christopher; CHECK:       loop.preheader:
1442cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = zext i16 [[LENGTH_I16:%.*]] to i32
1443cee313d2SEric Christopher; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i32 [[N]], [[TMP0]]
1444cee313d2SEric Christopher; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 0, [[TMP0]]
1445cee313d2SEric Christopher; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
1446cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
1447cee313d2SEric Christopher; CHECK:       loop:
1448cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1449cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1450cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
1451cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1452cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1453cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1454cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1455cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1456cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1457cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1458cee313d2SEric Christopher; CHECK:       exit.loopexit:
1459cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1460cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
1461cee313d2SEric Christopher; CHECK:       exit:
1462cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1463cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
1464cee313d2SEric Christopher;
1465cee313d2SEric Christopherentry:
1466cee313d2SEric Christopher  %tmp5 = icmp eq i32 %n, 0
1467cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
1468cee313d2SEric Christopher
1469cee313d2SEric Christopherloop.preheader:
1470cee313d2SEric Christopher  br label %loop
1471cee313d2SEric Christopher
1472cee313d2SEric Christopherloop:
1473cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1474cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1475cee313d2SEric Christopher  %length = zext i16 %length.i16 to i32
1476cee313d2SEric Christopher  %within.bounds = icmp ult i32 %i, %length
1477cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1478cee313d2SEric Christopher
1479cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
1480cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1481cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
1482cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
1483cee313d2SEric Christopher
1484cee313d2SEric Christopher  %i.next = add nuw i32 %i, 1
1485cee313d2SEric Christopher  %continue = icmp ult i32 %i.next, %n
1486cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
1487cee313d2SEric Christopher
1488cee313d2SEric Christopherexit:
1489cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
1490cee313d2SEric Christopher  ret i32 %result
1491cee313d2SEric Christopher}
1492cee313d2SEric Christopher
1493cee313d2SEric Christopherdefine i32 @unsigned_loop_0_to_n_cant_hoist_length(i32* %array, i32 %length, i32 %divider, i32 %n) {
1494cee313d2SEric Christopher; CHECK-LABEL: @unsigned_loop_0_to_n_cant_hoist_length(
1495cee313d2SEric Christopher; CHECK-NEXT:  entry:
1496cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1497cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1498cee313d2SEric Christopher; CHECK:       loop.preheader:
1499cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
1500cee313d2SEric Christopher; CHECK:       loop:
1501cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1502cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1503cee313d2SEric Christopher; CHECK-NEXT:    [[LENGTH_UDIV:%.*]] = udiv i32 [[LENGTH:%.*]], [[DIVIDER:%.*]]
150492a7177eSPhilip Reames; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_UDIV]]
150592a7177eSPhilip Reames; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_UDIV]]
150692a7177eSPhilip Reames; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
150792a7177eSPhilip Reames; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
1508cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1509cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1510cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1511cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1512cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1513cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1514cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1515cee313d2SEric Christopher; CHECK:       exit.loopexit:
1516cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1517cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
1518cee313d2SEric Christopher; CHECK:       exit:
1519cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1520cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
1521cee313d2SEric Christopher;
1522cee313d2SEric Christopherentry:
1523cee313d2SEric Christopher  %tmp5 = icmp eq i32 %n, 0
1524cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %loop.preheader
1525cee313d2SEric Christopher
1526cee313d2SEric Christopherloop.preheader:
1527cee313d2SEric Christopher  br label %loop
1528cee313d2SEric Christopher
1529cee313d2SEric Christopherloop:
1530cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1531cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1532cee313d2SEric Christopher  %length.udiv = udiv i32 %length, %divider
1533cee313d2SEric Christopher  %within.bounds = icmp ult i32 %i, %length.udiv
1534cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1535cee313d2SEric Christopher
1536cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
1537cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1538cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
1539cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
1540cee313d2SEric Christopher
1541cee313d2SEric Christopher  %i.next = add nuw i32 %i, 1
1542cee313d2SEric Christopher  %continue = icmp ult i32 %i.next, %n
1543cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
1544cee313d2SEric Christopher
1545cee313d2SEric Christopherexit:
1546cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
1547cee313d2SEric Christopher  ret i32 %result
1548cee313d2SEric Christopher}
1549cee313d2SEric Christopher
1550cee313d2SEric Christopher
1551cee313d2SEric Christopher; This is a case where the length information tells us that the guard
1552cee313d2SEric Christopher; must trigger on some iteration.
1553cee313d2SEric Christopherdefine i32 @provably_taken(i32* %array, i32* %length.ptr) {
1554cee313d2SEric Christopher; CHECK-LABEL: @provably_taken(
1555cee313d2SEric Christopher; CHECK-NEXT:  loop.preheader:
15565a8a7b3bSRoman Lebedev; CHECK-NEXT:    [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], align 4, !range [[RNG1:![0-9]+]]
1557cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 0, [[LENGTH]]
1558b2915971SRoman Lebedev; CHECK-NEXT:    [[TMP1:%.*]] = and i1 [[TMP0]], false
1559cee313d2SEric Christopher; CHECK-NEXT:    br label [[LOOP:%.*]]
1560cee313d2SEric Christopher; CHECK:       loop:
1561cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
1562cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1563b2915971SRoman Lebedev; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP1]], i32 9) [ "deopt"() ]
1564cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1565cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1566cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1567cee313d2SEric Christopher; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1568cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1569cee313d2SEric Christopher; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], 200
1570cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
1571cee313d2SEric Christopher; CHECK:       exit:
1572cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1573cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
1574cee313d2SEric Christopher;
1575cee313d2SEric Christopherloop.preheader:
1576cee313d2SEric Christopher  %length = load i32, i32* %length.ptr, !range !{i32 0, i32 50}
1577cee313d2SEric Christopher  br label %loop
1578cee313d2SEric Christopher
1579cee313d2SEric Christopherloop:
1580cee313d2SEric Christopher  %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1581cee313d2SEric Christopher  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1582cee313d2SEric Christopher  %within.bounds = icmp ult i32 %i, %length
1583cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1584cee313d2SEric Christopher
1585cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
1586cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1587cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
1588cee313d2SEric Christopher  %loop.acc.next = add i32 %loop.acc, %array.i
1589cee313d2SEric Christopher
1590cee313d2SEric Christopher  %i.next = add nuw i32 %i, 1
1591cee313d2SEric Christopher  %continue = icmp slt i32 %i.next, 200
1592cee313d2SEric Christopher  br i1 %continue, label %loop, label %exit
1593cee313d2SEric Christopher
1594cee313d2SEric Christopherexit:
1595cee313d2SEric Christopher  %result = phi i32 [ %loop.acc.next, %loop ]
1596cee313d2SEric Christopher  ret i32 %result
1597cee313d2SEric Christopher}
15988dda4a16SPhilip Reames
15998dda4a16SPhilip Reames; NE Check (as produced by LFTR) where we can prove Start < End via simple
16008dda4a16SPhilip Reames; instruction analysis
16018dda4a16SPhilip Reamesdefine i32 @ne_latch_zext(i32* %array, i32 %length, i16 %n16) {
16028dda4a16SPhilip Reames; CHECK-LABEL: @ne_latch_zext(
16038dda4a16SPhilip Reames; CHECK-NEXT:  loop.preheader:
16048dda4a16SPhilip Reames; CHECK-NEXT:    [[N:%.*]] = zext i16 [[N16:%.*]] to i32
1605*8906a0feSPhilip Reames; CHECK-NEXT:    [[NPLUS1:%.*]] = add i32 [[N]], 1
1606099eca83SPhilip Reames; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[NPLUS1]], [[LENGTH:%.*]]
1607099eca83SPhilip Reames; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
1608099eca83SPhilip Reames; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
16098dda4a16SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
16108dda4a16SPhilip Reames; CHECK:       loop:
16118dda4a16SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
1612099eca83SPhilip Reames; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
1613fa6bcd0bSPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1
1614fa6bcd0bSPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[NPLUS1]]
16158dda4a16SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
16168dda4a16SPhilip Reames; CHECK:       exit:
16178dda4a16SPhilip Reames; CHECK-NEXT:    ret i32 0
16188dda4a16SPhilip Reames;
16198dda4a16SPhilip Reamesloop.preheader:
16208dda4a16SPhilip Reames  %n = zext i16 %n16 to i32
1621fa6bcd0bSPhilip Reames  %nplus1 = add nsw nuw i32 %n, 1
16228dda4a16SPhilip Reames  br label %loop
16238dda4a16SPhilip Reames
16248dda4a16SPhilip Reamesloop:
16258dda4a16SPhilip Reames  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
16268dda4a16SPhilip Reames  %within.bounds = icmp ult i32 %i, %length
16278dda4a16SPhilip Reames  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
16288dda4a16SPhilip Reames
1629fa6bcd0bSPhilip Reames  %i.next = add nsw nuw i32 %i, 1
1630fa6bcd0bSPhilip Reames  %continue = icmp ne i32 %i.next, %nplus1
16318dda4a16SPhilip Reames  br i1 %continue, label %loop, label %exit
16328dda4a16SPhilip Reames
16338dda4a16SPhilip Reamesexit:
16348dda4a16SPhilip Reames  ret i32 0
16358dda4a16SPhilip Reames}
16368dda4a16SPhilip Reames
1637f711d594SPhilip Reames; Same as previous, but with a pre-increment test since this is easier to match
1638f711d594SPhilip Reamesdefine i32 @ne_latch_zext_preinc(i32* %array, i32 %length, i16 %n16) {
1639f711d594SPhilip Reames; CHECK-LABEL: @ne_latch_zext_preinc(
1640f711d594SPhilip Reames; CHECK-NEXT:  loop.preheader:
1641f711d594SPhilip Reames; CHECK-NEXT:    [[N:%.*]] = zext i16 [[N16:%.*]] to i32
1642099eca83SPhilip Reames; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1
1643099eca83SPhilip Reames; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i32 [[N]], [[TMP0]]
1644099eca83SPhilip Reames; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 0, [[LENGTH]]
1645099eca83SPhilip Reames; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
1646f711d594SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
1647f711d594SPhilip Reames; CHECK:       loop:
1648f711d594SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
1649099eca83SPhilip Reames; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
1650f711d594SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1651f711d594SPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ne i32 [[I]], [[N]]
1652f711d594SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
1653f711d594SPhilip Reames; CHECK:       exit:
1654f711d594SPhilip Reames; CHECK-NEXT:    ret i32 0
1655f711d594SPhilip Reames;
1656f711d594SPhilip Reamesloop.preheader:
1657f711d594SPhilip Reames  %n = zext i16 %n16 to i32
1658f711d594SPhilip Reames  br label %loop
1659f711d594SPhilip Reames
1660f711d594SPhilip Reamesloop:
1661f711d594SPhilip Reames  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1662f711d594SPhilip Reames  %within.bounds = icmp ult i32 %i, %length
1663f711d594SPhilip Reames  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1664f711d594SPhilip Reames
1665f711d594SPhilip Reames  %i.next = add nuw i32 %i, 1
1666f711d594SPhilip Reames  %continue = icmp ne i32 %i, %n
1667f711d594SPhilip Reames  br i1 %continue, label %loop, label %exit
1668f711d594SPhilip Reames
1669f711d594SPhilip Reamesexit:
1670f711d594SPhilip Reames  ret i32 0
1671f711d594SPhilip Reames}
1672f711d594SPhilip Reames
16738dda4a16SPhilip Reames; NE Check (as produced by LFTR) where we can prove Start < End via the
16748dda4a16SPhilip Reames; condition guarding the loop entry.
16758dda4a16SPhilip Reamesdefine i32 @ne_latch_dom_check(i32* %array, i32 %length, i32 %n) {
16768dda4a16SPhilip Reames; CHECK-LABEL: @ne_latch_dom_check(
16778dda4a16SPhilip Reames; CHECK-NEXT:  entry:
16788dda4a16SPhilip Reames; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
1679fa6bcd0bSPhilip Reames; CHECK-NEXT:    [[NPLUS1:%.*]] = add nuw i32 [[N]], 1
16808dda4a16SPhilip Reames; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
16818dda4a16SPhilip Reames; CHECK:       loop.preheader:
16828dda4a16SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
16838dda4a16SPhilip Reames; CHECK:       loop:
16848dda4a16SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
16858dda4a16SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
16868dda4a16SPhilip Reames; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
1687fa6bcd0bSPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1
1688fa6bcd0bSPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[NPLUS1]]
16898dda4a16SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
16908dda4a16SPhilip Reames; CHECK:       exit.loopexit:
16918dda4a16SPhilip Reames; CHECK-NEXT:    br label [[EXIT]]
16928dda4a16SPhilip Reames; CHECK:       exit:
16938dda4a16SPhilip Reames; CHECK-NEXT:    ret i32 0
16948dda4a16SPhilip Reames;
16958dda4a16SPhilip Reamesentry:
16968dda4a16SPhilip Reames  %tmp5 = icmp sle i32 %n, 0
1697fa6bcd0bSPhilip Reames  %nplus1 = add nuw i32 %n, 1
16988dda4a16SPhilip Reames  br i1 %tmp5, label %exit, label %loop.preheader
16998dda4a16SPhilip Reames
17008dda4a16SPhilip Reamesloop.preheader:
17018dda4a16SPhilip Reames  br label %loop
17028dda4a16SPhilip Reames
17038dda4a16SPhilip Reamesloop:
17048dda4a16SPhilip Reames  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
17058dda4a16SPhilip Reames  %within.bounds = icmp ult i32 %i, %length
17068dda4a16SPhilip Reames  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
17078dda4a16SPhilip Reames
1708fa6bcd0bSPhilip Reames  %i.next = add nsw nuw i32 %i, 1
1709fa6bcd0bSPhilip Reames  %continue = icmp ne i32 %i.next, %nplus1
17108dda4a16SPhilip Reames  br i1 %continue, label %loop, label %exit
17118dda4a16SPhilip Reames
17128dda4a16SPhilip Reamesexit:
17138dda4a16SPhilip Reames  ret i32 0
17148dda4a16SPhilip Reames}
17158dda4a16SPhilip Reames
1716f711d594SPhilip Reames; Same as previous, but easier to match
1717f711d594SPhilip Reamesdefine i32 @ne_latch_dom_check_preinc(i32* %array, i32 %length, i32 %n) {
1718f711d594SPhilip Reames; CHECK-LABEL: @ne_latch_dom_check_preinc(
1719f711d594SPhilip Reames; CHECK-NEXT:  entry:
1720f711d594SPhilip Reames; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
1721f711d594SPhilip Reames; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1722f711d594SPhilip Reames; CHECK:       loop.preheader:
1723099eca83SPhilip Reames; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1
1724099eca83SPhilip Reames; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i32 [[N]], [[TMP0]]
1725099eca83SPhilip Reames; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 0, [[LENGTH]]
1726099eca83SPhilip Reames; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
1727f711d594SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
1728f711d594SPhilip Reames; CHECK:       loop:
1729f711d594SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1730099eca83SPhilip Reames; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
1731f711d594SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1732f711d594SPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ne i32 [[I]], [[N]]
1733f711d594SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1734f711d594SPhilip Reames; CHECK:       exit.loopexit:
1735f711d594SPhilip Reames; CHECK-NEXT:    br label [[EXIT]]
1736f711d594SPhilip Reames; CHECK:       exit:
1737f711d594SPhilip Reames; CHECK-NEXT:    ret i32 0
1738f711d594SPhilip Reames;
1739f711d594SPhilip Reamesentry:
1740f711d594SPhilip Reames  %tmp5 = icmp sle i32 %n, 0
1741f711d594SPhilip Reames  br i1 %tmp5, label %exit, label %loop.preheader
1742f711d594SPhilip Reames
1743f711d594SPhilip Reamesloop.preheader:
1744f711d594SPhilip Reames  br label %loop
1745f711d594SPhilip Reames
1746f711d594SPhilip Reamesloop:
1747f711d594SPhilip Reames  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1748f711d594SPhilip Reames  %within.bounds = icmp ult i32 %i, %length
1749f711d594SPhilip Reames  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1750f711d594SPhilip Reames
1751f711d594SPhilip Reames  %i.next = add nuw i32 %i, 1
1752f711d594SPhilip Reames  %continue = icmp ne i32 %i, %n
1753f711d594SPhilip Reames  br i1 %continue, label %loop, label %exit
1754f711d594SPhilip Reames
1755f711d594SPhilip Reamesexit:
1756f711d594SPhilip Reames  ret i32 0
1757f711d594SPhilip Reames}
1758f711d594SPhilip Reames
17595a637cbdSPhilip Reames; Same as previous, except swapped br/cmp
17605a637cbdSPhilip Reamesdefine i32 @eq_latch_dom_check_preinc(i32* %array, i32 %length, i32 %n) {
17615a637cbdSPhilip Reames; CHECK-LABEL: @eq_latch_dom_check_preinc(
17625a637cbdSPhilip Reames; CHECK-NEXT:  entry:
17635a637cbdSPhilip Reames; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
17645a637cbdSPhilip Reames; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
17655a637cbdSPhilip Reames; CHECK:       loop.preheader:
17665a637cbdSPhilip Reames; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1
17675a637cbdSPhilip Reames; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i32 [[N]], [[TMP0]]
17685a637cbdSPhilip Reames; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 0, [[LENGTH]]
17695a637cbdSPhilip Reames; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
17705a637cbdSPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
17715a637cbdSPhilip Reames; CHECK:       loop:
17725a637cbdSPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
17735a637cbdSPhilip Reames; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
17745a637cbdSPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
17755a637cbdSPhilip Reames; CHECK-NEXT:    [[DONE:%.*]] = icmp eq i32 [[I]], [[N]]
17765a637cbdSPhilip Reames; CHECK-NEXT:    br i1 [[DONE]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP]]
17775a637cbdSPhilip Reames; CHECK:       exit.loopexit:
17785a637cbdSPhilip Reames; CHECK-NEXT:    br label [[EXIT]]
17795a637cbdSPhilip Reames; CHECK:       exit:
17805a637cbdSPhilip Reames; CHECK-NEXT:    ret i32 0
17815a637cbdSPhilip Reames;
17825a637cbdSPhilip Reamesentry:
17835a637cbdSPhilip Reames  %tmp5 = icmp sle i32 %n, 0
17845a637cbdSPhilip Reames  br i1 %tmp5, label %exit, label %loop.preheader
17855a637cbdSPhilip Reames
17865a637cbdSPhilip Reamesloop.preheader:
17875a637cbdSPhilip Reames  br label %loop
17885a637cbdSPhilip Reames
17895a637cbdSPhilip Reamesloop:
17905a637cbdSPhilip Reames  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
17915a637cbdSPhilip Reames  %within.bounds = icmp ult i32 %i, %length
17925a637cbdSPhilip Reames  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
17935a637cbdSPhilip Reames
17945a637cbdSPhilip Reames  %i.next = add nuw i32 %i, 1
17955a637cbdSPhilip Reames  %done = icmp eq i32 %i, %n
17965a637cbdSPhilip Reames  br i1 %done, label %exit, label %loop
17975a637cbdSPhilip Reames
17985a637cbdSPhilip Reamesexit:
17995a637cbdSPhilip Reames  ret i32 0
18005a637cbdSPhilip Reames}
18015a637cbdSPhilip Reames
1802f711d594SPhilip Reames
18038dda4a16SPhilip Reames; NE latch - can't prove (end-start) mod step == 0 (i.e. might wrap
18048dda4a16SPhilip Reames; around several times or even be infinite)
18058dda4a16SPhilip Reamesdefine i32 @neg_ne_latch_mod_step(i32* %array, i32 %length, i16 %n16) {
18068dda4a16SPhilip Reames; CHECK-LABEL: @neg_ne_latch_mod_step(
18078dda4a16SPhilip Reames; CHECK-NEXT:  loop.preheader:
18088dda4a16SPhilip Reames; CHECK-NEXT:    [[N:%.*]] = zext i16 [[N16:%.*]] to i32
18098dda4a16SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
18108dda4a16SPhilip Reames; CHECK:       loop:
18118dda4a16SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
18128dda4a16SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
18138dda4a16SPhilip Reames; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
18148dda4a16SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 3
1815f711d594SPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ne i32 [[I]], [[N]]
18168dda4a16SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
18178dda4a16SPhilip Reames; CHECK:       exit:
18188dda4a16SPhilip Reames; CHECK-NEXT:    ret i32 0
18198dda4a16SPhilip Reames;
18208dda4a16SPhilip Reamesloop.preheader:
18218dda4a16SPhilip Reames  %n = zext i16 %n16 to i32
18228dda4a16SPhilip Reames  br label %loop
18238dda4a16SPhilip Reames
18248dda4a16SPhilip Reamesloop:
18258dda4a16SPhilip Reames  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
18268dda4a16SPhilip Reames  %within.bounds = icmp ult i32 %i, %length
18278dda4a16SPhilip Reames  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
18288dda4a16SPhilip Reames
18298dda4a16SPhilip Reames  %i.next = add i32 %i, 3
1830f711d594SPhilip Reames  %continue = icmp ne i32 %i, %n
18318dda4a16SPhilip Reames  br i1 %continue, label %loop, label %exit
18328dda4a16SPhilip Reames
18338dda4a16SPhilip Reamesexit:
18348dda4a16SPhilip Reames  ret i32 0
18358dda4a16SPhilip Reames}
18368dda4a16SPhilip Reames
18378dda4a16SPhilip Reames; NE latch - TODO: could prove (end-start) mod step == 0
18388dda4a16SPhilip Reamesdefine i32 @ne_latch_mod_step(i32* %array, i32 %length) {
18398dda4a16SPhilip Reames; CHECK-LABEL: @ne_latch_mod_step(
18408dda4a16SPhilip Reames; CHECK-NEXT:  loop.preheader:
18418dda4a16SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
18428dda4a16SPhilip Reames; CHECK:       loop:
18438dda4a16SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
18448dda4a16SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
18458dda4a16SPhilip Reames; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
18468dda4a16SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 2
1847f711d594SPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ne i32 [[I]], 400
18488dda4a16SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
18498dda4a16SPhilip Reames; CHECK:       exit:
18508dda4a16SPhilip Reames; CHECK-NEXT:    ret i32 0
18518dda4a16SPhilip Reames;
18528dda4a16SPhilip Reamesloop.preheader:
18538dda4a16SPhilip Reames  br label %loop
18548dda4a16SPhilip Reames
18558dda4a16SPhilip Reamesloop:
18568dda4a16SPhilip Reames  %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
18578dda4a16SPhilip Reames  %within.bounds = icmp ult i32 %i, %length
18588dda4a16SPhilip Reames  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
18598dda4a16SPhilip Reames
18608dda4a16SPhilip Reames  %i.next = add nuw i32 %i, 2
1861f711d594SPhilip Reames  %continue = icmp ne i32 %i, 400
18628dda4a16SPhilip Reames  br i1 %continue, label %loop, label %exit
18638dda4a16SPhilip Reames
18648dda4a16SPhilip Reamesexit:
18658dda4a16SPhilip Reames  ret i32 0
18668dda4a16SPhilip Reames}
18678dda4a16SPhilip Reames
18688dda4a16SPhilip Reames; NE Latch - but end > start so wraps around and not equivelent to a ult
18698dda4a16SPhilip Reamesdefine i32 @neg_ne_latch_swapped_order(i32* %array, i32 %length) {
18708dda4a16SPhilip Reames; CHECK-LABEL: @neg_ne_latch_swapped_order(
18718dda4a16SPhilip Reames; CHECK-NEXT:  loop.preheader:
18728dda4a16SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
18738dda4a16SPhilip Reames; CHECK:       loop:
18748dda4a16SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 400, [[LOOP_PREHEADER:%.*]] ]
18758dda4a16SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
18768dda4a16SPhilip Reames; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
18778dda4a16SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
1878f711d594SPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ne i32 [[I]], 0
18798dda4a16SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
18808dda4a16SPhilip Reames; CHECK:       exit:
18818dda4a16SPhilip Reames; CHECK-NEXT:    ret i32 0
18828dda4a16SPhilip Reames;
18838dda4a16SPhilip Reamesloop.preheader:
18848dda4a16SPhilip Reames  br label %loop
18858dda4a16SPhilip Reames
18868dda4a16SPhilip Reamesloop:
18878dda4a16SPhilip Reames  %i = phi i32 [ %i.next, %loop ], [ 400, %loop.preheader ]
18888dda4a16SPhilip Reames  %within.bounds = icmp ult i32 %i, %length
18898dda4a16SPhilip Reames  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
18908dda4a16SPhilip Reames
18918dda4a16SPhilip Reames  %i.next = add i32 %i, 1
1892f711d594SPhilip Reames  %continue = icmp ne i32 %i, 0
18938dda4a16SPhilip Reames  br i1 %continue, label %loop, label %exit
18948dda4a16SPhilip Reames
18958dda4a16SPhilip Reamesexit:
18968dda4a16SPhilip Reames  ret i32 0
18978dda4a16SPhilip Reames}
18988dda4a16SPhilip Reames
1899101915cfSPhilip Reames; Negative test, make sure we don't crash on unconditional latches
1900101915cfSPhilip Reames; TODO: there's no reason we shouldn't be able to predicate the
1901101915cfSPhilip Reames; condition for an statically infinite loop.
1902101915cfSPhilip Reamesdefine i32 @unconditional_latch(i32* %a, i32 %length) {
1903101915cfSPhilip Reames; CHECK-LABEL: @unconditional_latch(
1904101915cfSPhilip Reames; CHECK-NEXT:  loop.preheader:
1905101915cfSPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
1906101915cfSPhilip Reames; CHECK:       loop:
1907101915cfSPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 400, [[LOOP_PREHEADER:%.*]] ]
1908101915cfSPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
1909101915cfSPhilip Reames; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
19105a8a7b3bSRoman Lebedev; CHECK-NEXT:    store volatile i32 0, i32* [[A:%.*]], align 4
1911101915cfSPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
1912101915cfSPhilip Reames; CHECK-NEXT:    br label [[LOOP]]
1913101915cfSPhilip Reames;
1914101915cfSPhilip Reamesloop.preheader:
1915101915cfSPhilip Reames  br label %loop
1916101915cfSPhilip Reames
1917101915cfSPhilip Reamesloop:
1918101915cfSPhilip Reames  %i = phi i32 [ %i.next, %loop ], [ 400, %loop.preheader ]
1919101915cfSPhilip Reames  %within.bounds = icmp ult i32 %i, %length
1920101915cfSPhilip Reames  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1921101915cfSPhilip Reames  store volatile i32 0, i32* %a
1922101915cfSPhilip Reames  %i.next = add i32 %i, 1
1923101915cfSPhilip Reames  br label %loop
1924101915cfSPhilip Reames}
1925