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
3*55bdb140SAnna 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 @signed_loop_0_to_n_nested_0_to_l_inner_index_check(i32* %array, i32 %length, i32 %n, i32 %l) {
8cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_nested_0_to_l_inner_index_check(
9cee313d2SEric Christopher; CHECK-NEXT:  entry:
10cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
11cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[OUTER_LOOP_PREHEADER:%.*]]
12cee313d2SEric Christopher; CHECK:       outer.loop.preheader:
13cee313d2SEric Christopher; CHECK-NEXT:    br label [[OUTER_LOOP:%.*]]
14cee313d2SEric Christopher; CHECK:       outer.loop:
15cee313d2SEric Christopher; CHECK-NEXT:    [[OUTER_LOOP_ACC:%.*]] = phi i32 [ [[OUTER_LOOP_ACC_NEXT:%.*]], [[OUTER_LOOP_INC:%.*]] ], [ 0, [[OUTER_LOOP_PREHEADER]] ]
16cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[OUTER_LOOP_INC]] ], [ 0, [[OUTER_LOOP_PREHEADER]] ]
17cee313d2SEric Christopher; CHECK-NEXT:    [[TMP6:%.*]] = icmp sle i32 [[L:%.*]], 0
18cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP6]], label [[OUTER_LOOP_INC]], label [[INNER_LOOP_PREHEADER:%.*]]
19cee313d2SEric Christopher; CHECK:       inner.loop.preheader:
20cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = icmp sle i32 [[L]], [[LENGTH:%.*]]
21cee313d2SEric Christopher; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
22cee313d2SEric Christopher; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
23cee313d2SEric Christopher; CHECK-NEXT:    br label [[INNER_LOOP:%.*]]
24cee313d2SEric Christopher; CHECK:       inner.loop:
25cee313d2SEric Christopher; CHECK-NEXT:    [[INNER_LOOP_ACC:%.*]] = phi i32 [ [[INNER_LOOP_ACC_NEXT:%.*]], [[INNER_LOOP]] ], [ [[OUTER_LOOP_ACC]], [[INNER_LOOP_PREHEADER]] ]
26cee313d2SEric Christopher; CHECK-NEXT:    [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[INNER_LOOP]] ], [ 0, [[INNER_LOOP_PREHEADER]] ]
27cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
28cee313d2SEric Christopher; CHECK-NEXT:    [[J_I64:%.*]] = zext i32 [[J]] to i64
29cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_J_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[J_I64]]
30cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_J:%.*]] = load i32, i32* [[ARRAY_J_PTR]], align 4
31cee313d2SEric Christopher; CHECK-NEXT:    [[INNER_LOOP_ACC_NEXT]] = add i32 [[INNER_LOOP_ACC]], [[ARRAY_J]]
32cee313d2SEric Christopher; CHECK-NEXT:    [[J_NEXT]] = add nsw i32 [[J]], 1
33cee313d2SEric Christopher; CHECK-NEXT:    [[INNER_CONTINUE:%.*]] = icmp slt i32 [[J_NEXT]], [[L]]
34cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[INNER_CONTINUE]], label [[INNER_LOOP]], label [[OUTER_LOOP_INC_LOOPEXIT:%.*]]
35cee313d2SEric Christopher; CHECK:       outer.loop.inc.loopexit:
36cee313d2SEric Christopher; CHECK-NEXT:    [[INNER_LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[INNER_LOOP_ACC_NEXT]], [[INNER_LOOP]] ]
37cee313d2SEric Christopher; CHECK-NEXT:    br label [[OUTER_LOOP_INC]]
38cee313d2SEric Christopher; CHECK:       outer.loop.inc:
39cee313d2SEric Christopher; CHECK-NEXT:    [[OUTER_LOOP_ACC_NEXT]] = phi i32 [ [[OUTER_LOOP_ACC]], [[OUTER_LOOP]] ], [ [[INNER_LOOP_ACC_NEXT_LCSSA]], [[OUTER_LOOP_INC_LOOPEXIT]] ]
40cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
41cee313d2SEric Christopher; CHECK-NEXT:    [[OUTER_CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
42cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[OUTER_CONTINUE]], label [[OUTER_LOOP]], label [[EXIT_LOOPEXIT:%.*]]
43cee313d2SEric Christopher; CHECK:       exit.loopexit:
44cee313d2SEric Christopher; CHECK-NEXT:    [[OUTER_LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[OUTER_LOOP_ACC_NEXT]], [[OUTER_LOOP_INC]] ]
45cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
46cee313d2SEric Christopher; CHECK:       exit:
47cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[OUTER_LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
48cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
49cee313d2SEric Christopher;
50cee313d2SEric Christopherentry:
51cee313d2SEric Christopher  %tmp5 = icmp sle i32 %n, 0
52cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %outer.loop.preheader
53cee313d2SEric Christopher
54cee313d2SEric Christopherouter.loop.preheader:
55cee313d2SEric Christopher  br label %outer.loop
56cee313d2SEric Christopher
57cee313d2SEric Christopherouter.loop:
58cee313d2SEric Christopher  %outer.loop.acc = phi i32 [ %outer.loop.acc.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
59cee313d2SEric Christopher  %i = phi i32 [ %i.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
60cee313d2SEric Christopher  %tmp6 = icmp sle i32 %l, 0
61cee313d2SEric Christopher  br i1 %tmp6, label %outer.loop.inc, label %inner.loop.preheader
62cee313d2SEric Christopher
63cee313d2SEric Christopherinner.loop.preheader:
64cee313d2SEric Christopher  br label %inner.loop
65cee313d2SEric Christopher
66cee313d2SEric Christopherinner.loop:
67cee313d2SEric Christopher  %inner.loop.acc = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %inner.loop.preheader ]
68cee313d2SEric Christopher  %j = phi i32 [ %j.next, %inner.loop ], [ 0, %inner.loop.preheader ]
69cee313d2SEric Christopher
70cee313d2SEric Christopher  %within.bounds = icmp ult i32 %j, %length
71cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
72cee313d2SEric Christopher
73cee313d2SEric Christopher  %j.i64 = zext i32 %j to i64
74cee313d2SEric Christopher  %array.j.ptr = getelementptr inbounds i32, i32* %array, i64 %j.i64
75cee313d2SEric Christopher  %array.j = load i32, i32* %array.j.ptr, align 4
76cee313d2SEric Christopher  %inner.loop.acc.next = add i32 %inner.loop.acc, %array.j
77cee313d2SEric Christopher
78cee313d2SEric Christopher  %j.next = add nsw i32 %j, 1
79cee313d2SEric Christopher  %inner.continue = icmp slt i32 %j.next, %l
80cee313d2SEric Christopher  br i1 %inner.continue, label %inner.loop, label %outer.loop.inc
81cee313d2SEric Christopher
82cee313d2SEric Christopherouter.loop.inc:
83cee313d2SEric Christopher  %outer.loop.acc.next = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %outer.loop ]
84cee313d2SEric Christopher  %i.next = add nsw i32 %i, 1
85cee313d2SEric Christopher  %outer.continue = icmp slt i32 %i.next, %n
86cee313d2SEric Christopher  br i1 %outer.continue, label %outer.loop, label %exit
87cee313d2SEric Christopher
88cee313d2SEric Christopherexit:
89cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %outer.loop.acc.next, %outer.loop.inc ]
90cee313d2SEric Christopher  ret i32 %result
91cee313d2SEric Christopher}
92cee313d2SEric Christopher
93cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_nested_0_to_l_outer_index_check(i32* %array, i32 %length, i32 %n, i32 %l) {
94cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_nested_0_to_l_outer_index_check(
95cee313d2SEric Christopher; CHECK-NEXT:  entry:
96cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
97cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[OUTER_LOOP_PREHEADER:%.*]]
98cee313d2SEric Christopher; CHECK:       outer.loop.preheader:
99cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]]
100cee313d2SEric Christopher; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
101cee313d2SEric Christopher; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
102cee313d2SEric Christopher; CHECK-NEXT:    br label [[OUTER_LOOP:%.*]]
103cee313d2SEric Christopher; CHECK:       outer.loop:
104cee313d2SEric Christopher; CHECK-NEXT:    [[OUTER_LOOP_ACC:%.*]] = phi i32 [ [[OUTER_LOOP_ACC_NEXT:%.*]], [[OUTER_LOOP_INC:%.*]] ], [ 0, [[OUTER_LOOP_PREHEADER]] ]
105cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[OUTER_LOOP_INC]] ], [ 0, [[OUTER_LOOP_PREHEADER]] ]
106cee313d2SEric Christopher; CHECK-NEXT:    [[TMP6:%.*]] = icmp sle i32 [[L:%.*]], 0
107cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP6]], label [[OUTER_LOOP_INC]], label [[INNER_LOOP_PREHEADER:%.*]]
108cee313d2SEric Christopher; CHECK:       inner.loop.preheader:
109cee313d2SEric Christopher; CHECK-NEXT:    br label [[INNER_LOOP:%.*]]
110cee313d2SEric Christopher; CHECK:       inner.loop:
111cee313d2SEric Christopher; CHECK-NEXT:    [[INNER_LOOP_ACC:%.*]] = phi i32 [ [[INNER_LOOP_ACC_NEXT:%.*]], [[INNER_LOOP]] ], [ [[OUTER_LOOP_ACC]], [[INNER_LOOP_PREHEADER]] ]
112cee313d2SEric Christopher; CHECK-NEXT:    [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[INNER_LOOP]] ], [ 0, [[INNER_LOOP_PREHEADER]] ]
113cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
114cee313d2SEric Christopher; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
115cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
116cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
117cee313d2SEric Christopher; CHECK-NEXT:    [[INNER_LOOP_ACC_NEXT]] = add i32 [[INNER_LOOP_ACC]], [[ARRAY_I]]
118cee313d2SEric Christopher; CHECK-NEXT:    [[J_NEXT]] = add nsw i32 [[J]], 1
119cee313d2SEric Christopher; CHECK-NEXT:    [[INNER_CONTINUE:%.*]] = icmp slt i32 [[J_NEXT]], [[L]]
120cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[INNER_CONTINUE]], label [[INNER_LOOP]], label [[OUTER_LOOP_INC_LOOPEXIT:%.*]]
121cee313d2SEric Christopher; CHECK:       outer.loop.inc.loopexit:
122cee313d2SEric Christopher; CHECK-NEXT:    [[INNER_LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[INNER_LOOP_ACC_NEXT]], [[INNER_LOOP]] ]
123cee313d2SEric Christopher; CHECK-NEXT:    br label [[OUTER_LOOP_INC]]
124cee313d2SEric Christopher; CHECK:       outer.loop.inc:
125cee313d2SEric Christopher; CHECK-NEXT:    [[OUTER_LOOP_ACC_NEXT]] = phi i32 [ [[OUTER_LOOP_ACC]], [[OUTER_LOOP]] ], [ [[INNER_LOOP_ACC_NEXT_LCSSA]], [[OUTER_LOOP_INC_LOOPEXIT]] ]
126cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
127cee313d2SEric Christopher; CHECK-NEXT:    [[OUTER_CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
128cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[OUTER_CONTINUE]], label [[OUTER_LOOP]], label [[EXIT_LOOPEXIT:%.*]]
129cee313d2SEric Christopher; CHECK:       exit.loopexit:
130cee313d2SEric Christopher; CHECK-NEXT:    [[OUTER_LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[OUTER_LOOP_ACC_NEXT]], [[OUTER_LOOP_INC]] ]
131cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
132cee313d2SEric Christopher; CHECK:       exit:
133cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[OUTER_LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
134cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
135cee313d2SEric Christopher;
136cee313d2SEric Christopherentry:
137cee313d2SEric Christopher  %tmp5 = icmp sle i32 %n, 0
138cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %outer.loop.preheader
139cee313d2SEric Christopher
140cee313d2SEric Christopherouter.loop.preheader:
141cee313d2SEric Christopher  br label %outer.loop
142cee313d2SEric Christopher
143cee313d2SEric Christopherouter.loop:
144cee313d2SEric Christopher  %outer.loop.acc = phi i32 [ %outer.loop.acc.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
145cee313d2SEric Christopher  %i = phi i32 [ %i.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
146cee313d2SEric Christopher  %tmp6 = icmp sle i32 %l, 0
147cee313d2SEric Christopher  br i1 %tmp6, label %outer.loop.inc, label %inner.loop.preheader
148cee313d2SEric Christopher
149cee313d2SEric Christopherinner.loop.preheader:
150cee313d2SEric Christopher  br label %inner.loop
151cee313d2SEric Christopher
152cee313d2SEric Christopherinner.loop:
153cee313d2SEric Christopher
154cee313d2SEric Christopher  %inner.loop.acc = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %inner.loop.preheader ]
155cee313d2SEric Christopher  %j = phi i32 [ %j.next, %inner.loop ], [ 0, %inner.loop.preheader ]
156cee313d2SEric Christopher
157cee313d2SEric Christopher  %within.bounds = icmp ult i32 %i, %length
158cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
159cee313d2SEric Christopher
160cee313d2SEric Christopher  %i.i64 = zext i32 %i to i64
161cee313d2SEric Christopher  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
162cee313d2SEric Christopher  %array.i = load i32, i32* %array.i.ptr, align 4
163cee313d2SEric Christopher  %inner.loop.acc.next = add i32 %inner.loop.acc, %array.i
164cee313d2SEric Christopher
165cee313d2SEric Christopher  %j.next = add nsw i32 %j, 1
166cee313d2SEric Christopher  %inner.continue = icmp slt i32 %j.next, %l
167cee313d2SEric Christopher  br i1 %inner.continue, label %inner.loop, label %outer.loop.inc
168cee313d2SEric Christopher
169cee313d2SEric Christopherouter.loop.inc:
170cee313d2SEric Christopher  %outer.loop.acc.next = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %outer.loop ]
171cee313d2SEric Christopher  %i.next = add nsw i32 %i, 1
172cee313d2SEric Christopher  %outer.continue = icmp slt i32 %i.next, %n
173cee313d2SEric Christopher  br i1 %outer.continue, label %outer.loop, label %exit
174cee313d2SEric Christopher
175cee313d2SEric Christopherexit:
176cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %outer.loop.acc.next, %outer.loop.inc ]
177cee313d2SEric Christopher  ret i32 %result
178cee313d2SEric Christopher}
179cee313d2SEric Christopher
180cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_nested_i_to_l_inner_index_check(i32* %array, i32 %length, i32 %n, i32 %l) {
181cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_nested_i_to_l_inner_index_check(
182cee313d2SEric Christopher; CHECK-NEXT:  entry:
183cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
184cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[OUTER_LOOP_PREHEADER:%.*]]
185cee313d2SEric Christopher; CHECK:       outer.loop.preheader:
186cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]]
187cee313d2SEric Christopher; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
188cee313d2SEric Christopher; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
189cee313d2SEric Christopher; CHECK-NEXT:    br label [[OUTER_LOOP:%.*]]
190cee313d2SEric Christopher; CHECK:       outer.loop:
191cee313d2SEric Christopher; CHECK-NEXT:    [[OUTER_LOOP_ACC:%.*]] = phi i32 [ [[OUTER_LOOP_ACC_NEXT:%.*]], [[OUTER_LOOP_INC:%.*]] ], [ 0, [[OUTER_LOOP_PREHEADER]] ]
192cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[OUTER_LOOP_INC]] ], [ 0, [[OUTER_LOOP_PREHEADER]] ]
193cee313d2SEric Christopher; CHECK-NEXT:    [[TMP6:%.*]] = icmp sle i32 [[L:%.*]], 0
194cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP6]], label [[OUTER_LOOP_INC]], label [[INNER_LOOP_PREHEADER:%.*]]
195cee313d2SEric Christopher; CHECK:       inner.loop.preheader:
196cee313d2SEric Christopher; CHECK-NEXT:    [[TMP3:%.*]] = icmp sle i32 [[L]], [[LENGTH]]
197cee313d2SEric Christopher; CHECK-NEXT:    br label [[INNER_LOOP:%.*]]
198cee313d2SEric Christopher; CHECK:       inner.loop:
199cee313d2SEric Christopher; CHECK-NEXT:    [[INNER_LOOP_ACC:%.*]] = phi i32 [ [[INNER_LOOP_ACC_NEXT:%.*]], [[INNER_LOOP]] ], [ [[OUTER_LOOP_ACC]], [[INNER_LOOP_PREHEADER]] ]
200cee313d2SEric Christopher; CHECK-NEXT:    [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[INNER_LOOP]] ], [ [[I]], [[INNER_LOOP_PREHEADER]] ]
201cee313d2SEric Christopher; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[TMP2]]
202cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP4]], i32 9) [ "deopt"() ]
203cee313d2SEric Christopher; CHECK-NEXT:    [[J_I64:%.*]] = zext i32 [[J]] to i64
204cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_J_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[J_I64]]
205cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_J:%.*]] = load i32, i32* [[ARRAY_J_PTR]], align 4
206cee313d2SEric Christopher; CHECK-NEXT:    [[INNER_LOOP_ACC_NEXT]] = add i32 [[INNER_LOOP_ACC]], [[ARRAY_J]]
207cee313d2SEric Christopher; CHECK-NEXT:    [[J_NEXT]] = add nsw i32 [[J]], 1
208cee313d2SEric Christopher; CHECK-NEXT:    [[INNER_CONTINUE:%.*]] = icmp slt i32 [[J_NEXT]], [[L]]
209cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[INNER_CONTINUE]], label [[INNER_LOOP]], label [[OUTER_LOOP_INC_LOOPEXIT:%.*]]
210cee313d2SEric Christopher; CHECK:       outer.loop.inc.loopexit:
211cee313d2SEric Christopher; CHECK-NEXT:    [[INNER_LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[INNER_LOOP_ACC_NEXT]], [[INNER_LOOP]] ]
212cee313d2SEric Christopher; CHECK-NEXT:    br label [[OUTER_LOOP_INC]]
213cee313d2SEric Christopher; CHECK:       outer.loop.inc:
214cee313d2SEric Christopher; CHECK-NEXT:    [[OUTER_LOOP_ACC_NEXT]] = phi i32 [ [[OUTER_LOOP_ACC]], [[OUTER_LOOP]] ], [ [[INNER_LOOP_ACC_NEXT_LCSSA]], [[OUTER_LOOP_INC_LOOPEXIT]] ]
215cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
216cee313d2SEric Christopher; CHECK-NEXT:    [[OUTER_CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
217cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[OUTER_CONTINUE]], label [[OUTER_LOOP]], label [[EXIT_LOOPEXIT:%.*]]
218cee313d2SEric Christopher; CHECK:       exit.loopexit:
219cee313d2SEric Christopher; CHECK-NEXT:    [[OUTER_LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[OUTER_LOOP_ACC_NEXT]], [[OUTER_LOOP_INC]] ]
220cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
221cee313d2SEric Christopher; CHECK:       exit:
222cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[OUTER_LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
223cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
224cee313d2SEric Christopher;
225cee313d2SEric Christopherentry:
226cee313d2SEric Christopher  %tmp5 = icmp sle i32 %n, 0
227cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %outer.loop.preheader
228cee313d2SEric Christopher
229cee313d2SEric Christopherouter.loop.preheader:
230cee313d2SEric Christopher  br label %outer.loop
231cee313d2SEric Christopher
232cee313d2SEric Christopherouter.loop:
233cee313d2SEric Christopher  %outer.loop.acc = phi i32 [ %outer.loop.acc.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
234cee313d2SEric Christopher  %i = phi i32 [ %i.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
235cee313d2SEric Christopher  %tmp6 = icmp sle i32 %l, 0
236cee313d2SEric Christopher  br i1 %tmp6, label %outer.loop.inc, label %inner.loop.preheader
237cee313d2SEric Christopher
238cee313d2SEric Christopherinner.loop.preheader:
239cee313d2SEric Christopher  br label %inner.loop
240cee313d2SEric Christopher
241cee313d2SEric Christopherinner.loop:
242cee313d2SEric Christopher  %inner.loop.acc = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %inner.loop.preheader ]
243cee313d2SEric Christopher  %j = phi i32 [ %j.next, %inner.loop ], [ %i, %inner.loop.preheader ]
244cee313d2SEric Christopher
245cee313d2SEric Christopher  %within.bounds = icmp ult i32 %j, %length
246cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
247cee313d2SEric Christopher
248cee313d2SEric Christopher  %j.i64 = zext i32 %j to i64
249cee313d2SEric Christopher  %array.j.ptr = getelementptr inbounds i32, i32* %array, i64 %j.i64
250cee313d2SEric Christopher  %array.j = load i32, i32* %array.j.ptr, align 4
251cee313d2SEric Christopher  %inner.loop.acc.next = add i32 %inner.loop.acc, %array.j
252cee313d2SEric Christopher
253cee313d2SEric Christopher  %j.next = add nsw i32 %j, 1
254cee313d2SEric Christopher  %inner.continue = icmp slt i32 %j.next, %l
255cee313d2SEric Christopher  br i1 %inner.continue, label %inner.loop, label %outer.loop.inc
256cee313d2SEric Christopher
257cee313d2SEric Christopherouter.loop.inc:
258cee313d2SEric Christopher  %outer.loop.acc.next = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %outer.loop ]
259cee313d2SEric Christopher  %i.next = add nsw i32 %i, 1
260cee313d2SEric Christopher  %outer.continue = icmp slt i32 %i.next, %n
261cee313d2SEric Christopher  br i1 %outer.continue, label %outer.loop, label %exit
262cee313d2SEric Christopher
263cee313d2SEric Christopherexit:
264cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %outer.loop.acc.next, %outer.loop.inc ]
265cee313d2SEric Christopher  ret i32 %result
266cee313d2SEric Christopher}
267cee313d2SEric Christopher
268cee313d2SEric Christopherdefine i32 @cant_expand_guard_check_start(i32* %array, i32 %length, i32 %n, i32 %l, i32 %maybezero) {
269cee313d2SEric Christopher; CHECK-LABEL: @cant_expand_guard_check_start(
270cee313d2SEric Christopher; CHECK-NEXT:  entry:
271cee313d2SEric Christopher; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
272cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[OUTER_LOOP_PREHEADER:%.*]]
273cee313d2SEric Christopher; CHECK:       outer.loop.preheader:
274cee313d2SEric Christopher; CHECK-NEXT:    br label [[OUTER_LOOP:%.*]]
275cee313d2SEric Christopher; CHECK:       outer.loop:
276cee313d2SEric Christopher; CHECK-NEXT:    [[OUTER_LOOP_ACC:%.*]] = phi i32 [ [[OUTER_LOOP_ACC_NEXT:%.*]], [[OUTER_LOOP_INC:%.*]] ], [ 0, [[OUTER_LOOP_PREHEADER]] ]
277cee313d2SEric Christopher; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[OUTER_LOOP_INC]] ], [ 0, [[OUTER_LOOP_PREHEADER]] ]
278cee313d2SEric Christopher; CHECK-NEXT:    [[TMP6:%.*]] = icmp sle i32 [[L:%.*]], 0
279cee313d2SEric Christopher; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[I]], [[MAYBEZERO:%.*]]
280cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP6]], label [[OUTER_LOOP_INC]], label [[INNER_LOOP_PREHEADER:%.*]]
281cee313d2SEric Christopher; CHECK:       inner.loop.preheader:
282cee313d2SEric Christopher; CHECK-NEXT:    br label [[INNER_LOOP:%.*]]
283cee313d2SEric Christopher; CHECK:       inner.loop:
284cee313d2SEric Christopher; CHECK-NEXT:    [[INNER_LOOP_ACC:%.*]] = phi i32 [ [[INNER_LOOP_ACC_NEXT:%.*]], [[INNER_LOOP]] ], [ [[OUTER_LOOP_ACC]], [[INNER_LOOP_PREHEADER]] ]
285cee313d2SEric Christopher; CHECK-NEXT:    [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[INNER_LOOP]] ], [ [[DIV]], [[INNER_LOOP_PREHEADER]] ]
286cee313d2SEric Christopher; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH:%.*]]
287cee313d2SEric Christopher; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
288cee313d2SEric Christopher; CHECK-NEXT:    [[J_I64:%.*]] = zext i32 [[J]] to i64
289cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_J_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[J_I64]]
290cee313d2SEric Christopher; CHECK-NEXT:    [[ARRAY_J:%.*]] = load i32, i32* [[ARRAY_J_PTR]], align 4
291cee313d2SEric Christopher; CHECK-NEXT:    [[INNER_LOOP_ACC_NEXT]] = add i32 [[INNER_LOOP_ACC]], [[ARRAY_J]]
292cee313d2SEric Christopher; CHECK-NEXT:    [[J_NEXT]] = add nsw i32 [[J]], 1
293cee313d2SEric Christopher; CHECK-NEXT:    [[INNER_CONTINUE:%.*]] = icmp slt i32 [[J_NEXT]], [[L]]
294cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[INNER_CONTINUE]], label [[INNER_LOOP]], label [[OUTER_LOOP_INC_LOOPEXIT:%.*]]
295cee313d2SEric Christopher; CHECK:       outer.loop.inc.loopexit:
296cee313d2SEric Christopher; CHECK-NEXT:    [[INNER_LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[INNER_LOOP_ACC_NEXT]], [[INNER_LOOP]] ]
297cee313d2SEric Christopher; CHECK-NEXT:    br label [[OUTER_LOOP_INC]]
298cee313d2SEric Christopher; CHECK:       outer.loop.inc:
299cee313d2SEric Christopher; CHECK-NEXT:    [[OUTER_LOOP_ACC_NEXT]] = phi i32 [ [[OUTER_LOOP_ACC]], [[OUTER_LOOP]] ], [ [[INNER_LOOP_ACC_NEXT_LCSSA]], [[OUTER_LOOP_INC_LOOPEXIT]] ]
300cee313d2SEric Christopher; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
301cee313d2SEric Christopher; CHECK-NEXT:    [[OUTER_CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
302cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[OUTER_CONTINUE]], label [[OUTER_LOOP]], label [[EXIT_LOOPEXIT:%.*]]
303cee313d2SEric Christopher; CHECK:       exit.loopexit:
304cee313d2SEric Christopher; CHECK-NEXT:    [[OUTER_LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[OUTER_LOOP_ACC_NEXT]], [[OUTER_LOOP_INC]] ]
305cee313d2SEric Christopher; CHECK-NEXT:    br label [[EXIT]]
306cee313d2SEric Christopher; CHECK:       exit:
307cee313d2SEric Christopher; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[OUTER_LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
308cee313d2SEric Christopher; CHECK-NEXT:    ret i32 [[RESULT]]
309cee313d2SEric Christopher;
310cee313d2SEric Christopherentry:
311cee313d2SEric Christopher  %tmp5 = icmp sle i32 %n, 0
312cee313d2SEric Christopher  br i1 %tmp5, label %exit, label %outer.loop.preheader
313cee313d2SEric Christopher
314cee313d2SEric Christopherouter.loop.preheader:
315cee313d2SEric Christopher  br label %outer.loop
316cee313d2SEric Christopher
317cee313d2SEric Christopherouter.loop:
318cee313d2SEric Christopher  %outer.loop.acc = phi i32 [ %outer.loop.acc.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
319cee313d2SEric Christopher  %i = phi i32 [ %i.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
320cee313d2SEric Christopher  %tmp6 = icmp sle i32 %l, 0
321cee313d2SEric Christopher  %div = udiv i32 %i, %maybezero
322cee313d2SEric Christopher  br i1 %tmp6, label %outer.loop.inc, label %inner.loop.preheader
323cee313d2SEric Christopher
324cee313d2SEric Christopherinner.loop.preheader:
325cee313d2SEric Christopher  br label %inner.loop
326cee313d2SEric Christopher
327cee313d2SEric Christopherinner.loop:
328cee313d2SEric Christopher  %inner.loop.acc = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %inner.loop.preheader ]
329cee313d2SEric Christopher  %j = phi i32 [ %j.next, %inner.loop ], [ %div, %inner.loop.preheader ]
330cee313d2SEric Christopher
331cee313d2SEric Christopher  %within.bounds = icmp ult i32 %j, %length
332cee313d2SEric Christopher  call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
333cee313d2SEric Christopher
334cee313d2SEric Christopher  %j.i64 = zext i32 %j to i64
335cee313d2SEric Christopher  %array.j.ptr = getelementptr inbounds i32, i32* %array, i64 %j.i64
336cee313d2SEric Christopher  %array.j = load i32, i32* %array.j.ptr, align 4
337cee313d2SEric Christopher  %inner.loop.acc.next = add i32 %inner.loop.acc, %array.j
338cee313d2SEric Christopher
339cee313d2SEric Christopher  %j.next = add nsw i32 %j, 1
340cee313d2SEric Christopher  %inner.continue = icmp slt i32 %j.next, %l
341cee313d2SEric Christopher  br i1 %inner.continue, label %inner.loop, label %outer.loop.inc
342cee313d2SEric Christopher
343cee313d2SEric Christopherouter.loop.inc:
344cee313d2SEric Christopher  %outer.loop.acc.next = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %outer.loop ]
345cee313d2SEric Christopher  %i.next = add nsw i32 %i, 1
346cee313d2SEric Christopher  %outer.continue = icmp slt i32 %i.next, %n
347cee313d2SEric Christopher  br i1 %outer.continue, label %outer.loop, label %exit
348cee313d2SEric Christopher
349cee313d2SEric Christopherexit:
350cee313d2SEric Christopher  %result = phi i32 [ 0, %entry ], [ %outer.loop.acc.next, %outer.loop.inc ]
351cee313d2SEric Christopher  ret i32 %result
352cee313d2SEric Christopher}
353