Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / IRCE / variable-loop-bounds.ll
bloba46bb0f570846628c8007754724d0319a433e931
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
2 ; RUN: opt -passes=irce -S -verify-loop-info -irce-skip-profitability-checks < %s 2>&1 | FileCheck %s
4 define void @test_inc_eq(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %N) {
5 ; CHECK-LABEL: define void @test_inc_eq(
6 ; CHECK-SAME: ptr nocapture [[A:%.*]], ptr nocapture readonly [[B:%.*]], ptr nocapture readonly [[C:%.*]], i32 [[N:%.*]]) {
7 ; CHECK-NEXT:  entry:
8 ; CHECK-NEXT:    [[CMP16:%.*]] = icmp sgt i32 [[N]], 0
9 ; CHECK-NEXT:    br i1 [[CMP16]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
10 ; CHECK:       for.body.preheader:
11 ; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = call i32 @llvm.umin.i32(i32 [[N]], i32 512)
12 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 0, [[EXIT_MAINLOOP_AT]]
13 ; CHECK-NEXT:    br i1 [[TMP0]], label [[FOR_BODY_PREHEADER1:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
14 ; CHECK:       for.body.preheader1:
15 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
16 ; CHECK:       for.cond.cleanup.loopexit.loopexit:
17 ; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
18 ; CHECK:       for.cond.cleanup.loopexit:
19 ; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
20 ; CHECK:       for.cond.cleanup:
21 ; CHECK-NEXT:    ret void
22 ; CHECK:       for.body:
23 ; CHECK-NEXT:    [[I_017:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER1]] ]
24 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[I_017]], 512
25 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017]]
26 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
27 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017]]
28 ; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
29 ; CHECK-NEXT:    br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
30 ; CHECK:       if.then:
31 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[TMP1]], [[TMP2]]
32 ; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]]
33 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4
34 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[SUB]], [[TMP3]]
35 ; CHECK-NEXT:    store i32 [[ADD]], ptr [[ARRAYIDX3]], align 4
36 ; CHECK-NEXT:    br label [[FOR_INC]]
37 ; CHECK:       if.else:
38 ; CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 [[TMP2]], [[TMP1]]
39 ; CHECK-NEXT:    [[ARRAYIDX7:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]]
40 ; CHECK-NEXT:    store i32 [[ADD6]], ptr [[ARRAYIDX7]], align 4
41 ; CHECK-NEXT:    br label [[FOR_INC]]
42 ; CHECK:       for.inc:
43 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_017]], 1
44 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], [[N]]
45 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i32 [[INC]], [[EXIT_MAINLOOP_AT]]
46 ; CHECK-NEXT:    [[TMP5:%.*]] = xor i1 [[TMP4]], true
47 ; CHECK-NEXT:    br i1 [[TMP5]], label [[MAIN_EXIT_SELECTOR:%.*]], label [[FOR_BODY]]
48 ; CHECK:       main.exit.selector:
49 ; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[FOR_INC]] ]
50 ; CHECK-NEXT:    [[TMP6:%.*]] = icmp ult i32 [[INC_LCSSA]], [[N]]
51 ; CHECK-NEXT:    br i1 [[TMP6]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
52 ; CHECK:       main.pseudo.exit:
53 ; CHECK-NEXT:    [[I_017_COPY:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
54 ; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
55 ; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
56 ; CHECK:       postloop:
57 ; CHECK-NEXT:    br label [[FOR_BODY_POSTLOOP:%.*]]
58 ; CHECK:       for.body.postloop:
59 ; CHECK-NEXT:    [[I_017_POSTLOOP:%.*]] = phi i32 [ [[INC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[I_017_COPY]], [[POSTLOOP]] ]
60 ; CHECK-NEXT:    [[CMP1_POSTLOOP:%.*]] = icmp ult i32 [[I_017_POSTLOOP]], 512
61 ; CHECK-NEXT:    [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017_POSTLOOP]]
62 ; CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4
63 ; CHECK-NEXT:    [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017_POSTLOOP]]
64 ; CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4
65 ; CHECK-NEXT:    br i1 [[CMP1_POSTLOOP]], label [[IF_THEN_POSTLOOP:%.*]], label [[IF_ELSE_POSTLOOP:%.*]]
66 ; CHECK:       if.else.postloop:
67 ; CHECK-NEXT:    [[ADD6_POSTLOOP:%.*]] = add nsw i32 [[TMP8]], [[TMP7]]
68 ; CHECK-NEXT:    [[ARRAYIDX7_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]]
69 ; CHECK-NEXT:    store i32 [[ADD6_POSTLOOP]], ptr [[ARRAYIDX7_POSTLOOP]], align 4
70 ; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
71 ; CHECK:       if.then.postloop:
72 ; CHECK-NEXT:    [[SUB_POSTLOOP:%.*]] = sub i32 [[TMP7]], [[TMP8]]
73 ; CHECK-NEXT:    [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]]
74 ; CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4
75 ; CHECK-NEXT:    [[ADD_POSTLOOP:%.*]] = add nsw i32 [[SUB_POSTLOOP]], [[TMP9]]
76 ; CHECK-NEXT:    store i32 [[ADD_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4
77 ; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
78 ; CHECK:       for.inc.postloop:
79 ; CHECK-NEXT:    [[INC_POSTLOOP]] = add nuw nsw i32 [[I_017_POSTLOOP]], 1
80 ; CHECK-NEXT:    [[EXITCOND_POSTLOOP:%.*]] = icmp eq i32 [[INC_POSTLOOP]], [[N]]
81 ; CHECK-NEXT:    br i1 [[EXITCOND_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], label [[FOR_BODY_POSTLOOP]], !llvm.loop [[LOOP0:![0-9]+]], !loop_constrainer.loop.clone !5
83 entry:
84   %cmp16 = icmp sgt i32 %N, 0
85   br i1 %cmp16, label %for.body, label %for.cond.cleanup
87 for.cond.cleanup:
88   ret void
90 for.body:
91   %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ]
92   %cmp1 = icmp ult i32 %i.017, 512
93   %arrayidx = getelementptr inbounds i32, ptr %b, i32 %i.017
94   %0 = load i32, ptr %arrayidx, align 4
95   %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %i.017
96   %1 = load i32, ptr %arrayidx2, align 4
97   br i1 %cmp1, label %if.then, label %if.else
99 if.then:
100   %sub = sub i32 %0, %1
101   %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %i.017
102   %2 = load i32, ptr %arrayidx3, align 4
103   %add = add nsw i32 %sub, %2
104   store i32 %add, ptr %arrayidx3, align 4
105   br label %for.inc
107 if.else:
108   %add6 = add nsw i32 %1, %0
109   %arrayidx7 = getelementptr inbounds i32, ptr %a, i32 %i.017
110   store i32 %add6, ptr %arrayidx7, align 4
111   br label %for.inc
113 for.inc:
114   %inc = add nuw nsw i32 %i.017, 1
115   %exitcond = icmp eq i32 %inc, %N
116   br i1 %exitcond, label %for.cond.cleanup, label %for.body
119 define void @test_inc_ne(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %N) {
120 ; CHECK-LABEL: define void @test_inc_ne(
121 ; CHECK-SAME: ptr nocapture [[A:%.*]], ptr nocapture readonly [[B:%.*]], ptr nocapture readonly [[C:%.*]], i32 [[N:%.*]]) {
122 ; CHECK-NEXT:  entry:
123 ; CHECK-NEXT:    [[CMP16:%.*]] = icmp sgt i32 [[N]], 0
124 ; CHECK-NEXT:    br i1 [[CMP16]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
125 ; CHECK:       for.body.preheader:
126 ; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = call i32 @llvm.umin.i32(i32 [[N]], i32 512)
127 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 0, [[EXIT_MAINLOOP_AT]]
128 ; CHECK-NEXT:    br i1 [[TMP0]], label [[FOR_BODY_PREHEADER1:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
129 ; CHECK:       for.body.preheader1:
130 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
131 ; CHECK:       for.cond.cleanup.loopexit.loopexit:
132 ; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
133 ; CHECK:       for.cond.cleanup.loopexit:
134 ; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
135 ; CHECK:       for.cond.cleanup:
136 ; CHECK-NEXT:    ret void
137 ; CHECK:       for.body:
138 ; CHECK-NEXT:    [[I_017:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER1]] ]
139 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[I_017]], 512
140 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017]]
141 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
142 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017]]
143 ; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
144 ; CHECK-NEXT:    br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
145 ; CHECK:       if.then:
146 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[TMP1]], [[TMP2]]
147 ; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]]
148 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4
149 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[SUB]], [[TMP3]]
150 ; CHECK-NEXT:    store i32 [[ADD]], ptr [[ARRAYIDX3]], align 4
151 ; CHECK-NEXT:    br label [[FOR_INC]]
152 ; CHECK:       if.else:
153 ; CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 [[TMP2]], [[TMP1]]
154 ; CHECK-NEXT:    [[ARRAYIDX7:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]]
155 ; CHECK-NEXT:    store i32 [[ADD6]], ptr [[ARRAYIDX7]], align 4
156 ; CHECK-NEXT:    br label [[FOR_INC]]
157 ; CHECK:       for.inc:
158 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_017]], 1
159 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[INC]], [[N]]
160 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i32 [[INC]], [[EXIT_MAINLOOP_AT]]
161 ; CHECK-NEXT:    br i1 [[TMP4]], label [[FOR_BODY]], label [[MAIN_EXIT_SELECTOR:%.*]]
162 ; CHECK:       main.exit.selector:
163 ; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[FOR_INC]] ]
164 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp ult i32 [[INC_LCSSA]], [[N]]
165 ; CHECK-NEXT:    br i1 [[TMP5]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
166 ; CHECK:       main.pseudo.exit:
167 ; CHECK-NEXT:    [[I_017_COPY:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
168 ; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
169 ; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
170 ; CHECK:       postloop:
171 ; CHECK-NEXT:    br label [[FOR_BODY_POSTLOOP:%.*]]
172 ; CHECK:       for.body.postloop:
173 ; CHECK-NEXT:    [[I_017_POSTLOOP:%.*]] = phi i32 [ [[INC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[I_017_COPY]], [[POSTLOOP]] ]
174 ; CHECK-NEXT:    [[CMP1_POSTLOOP:%.*]] = icmp ult i32 [[I_017_POSTLOOP]], 512
175 ; CHECK-NEXT:    [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017_POSTLOOP]]
176 ; CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4
177 ; CHECK-NEXT:    [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017_POSTLOOP]]
178 ; CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4
179 ; CHECK-NEXT:    br i1 [[CMP1_POSTLOOP]], label [[IF_THEN_POSTLOOP:%.*]], label [[IF_ELSE_POSTLOOP:%.*]]
180 ; CHECK:       if.else.postloop:
181 ; CHECK-NEXT:    [[ADD6_POSTLOOP:%.*]] = add nsw i32 [[TMP7]], [[TMP6]]
182 ; CHECK-NEXT:    [[ARRAYIDX7_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]]
183 ; CHECK-NEXT:    store i32 [[ADD6_POSTLOOP]], ptr [[ARRAYIDX7_POSTLOOP]], align 4
184 ; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
185 ; CHECK:       if.then.postloop:
186 ; CHECK-NEXT:    [[SUB_POSTLOOP:%.*]] = sub i32 [[TMP6]], [[TMP7]]
187 ; CHECK-NEXT:    [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]]
188 ; CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4
189 ; CHECK-NEXT:    [[ADD_POSTLOOP:%.*]] = add nsw i32 [[SUB_POSTLOOP]], [[TMP8]]
190 ; CHECK-NEXT:    store i32 [[ADD_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4
191 ; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
192 ; CHECK:       for.inc.postloop:
193 ; CHECK-NEXT:    [[INC_POSTLOOP]] = add nuw nsw i32 [[I_017_POSTLOOP]], 1
194 ; CHECK-NEXT:    [[EXITCOND_POSTLOOP:%.*]] = icmp ne i32 [[INC_POSTLOOP]], [[N]]
195 ; CHECK-NEXT:    br i1 [[EXITCOND_POSTLOOP]], label [[FOR_BODY_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP6:![0-9]+]], !loop_constrainer.loop.clone !5
197 entry:
198   %cmp16 = icmp sgt i32 %N, 0
199   br i1 %cmp16, label %for.body, label %for.cond.cleanup
201 for.cond.cleanup:
202   ret void
204 for.body:
205   %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ]
206   %cmp1 = icmp ult i32 %i.017, 512
207   %arrayidx = getelementptr inbounds i32, ptr %b, i32 %i.017
208   %0 = load i32, ptr %arrayidx, align 4
209   %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %i.017
210   %1 = load i32, ptr %arrayidx2, align 4
211   br i1 %cmp1, label %if.then, label %if.else
213 if.then:
214   %sub = sub i32 %0, %1
215   %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %i.017
216   %2 = load i32, ptr %arrayidx3, align 4
217   %add = add nsw i32 %sub, %2
218   store i32 %add, ptr %arrayidx3, align 4
219   br label %for.inc
221 if.else:
222   %add6 = add nsw i32 %1, %0
223   %arrayidx7 = getelementptr inbounds i32, ptr %a, i32 %i.017
224   store i32 %add6, ptr %arrayidx7, align 4
225   br label %for.inc
227 for.inc:
228   %inc = add nuw nsw i32 %i.017, 1
229   %exitcond = icmp ne i32 %inc, %N
230   br i1 %exitcond, label %for.body, label %for.cond.cleanup
233 define void @test_inc_slt(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %N) {
234 ; CHECK-LABEL: define void @test_inc_slt(
235 ; CHECK-SAME: ptr nocapture [[A:%.*]], ptr nocapture readonly [[B:%.*]], ptr nocapture readonly [[C:%.*]], i32 [[N:%.*]]) {
236 ; CHECK-NEXT:  entry:
237 ; CHECK-NEXT:    [[CMP16:%.*]] = icmp sgt i32 [[N]], 0
238 ; CHECK-NEXT:    br i1 [[CMP16]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
239 ; CHECK:       for.body.preheader:
240 ; CHECK-NEXT:    [[SMIN:%.*]] = call i32 @llvm.smin.i32(i32 [[N]], i32 512)
241 ; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = call i32 @llvm.smax.i32(i32 [[SMIN]], i32 0)
242 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 0, [[EXIT_MAINLOOP_AT]]
243 ; CHECK-NEXT:    br i1 [[TMP0]], label [[FOR_BODY_PREHEADER1:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
244 ; CHECK:       for.body.preheader1:
245 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
246 ; CHECK:       for.cond.cleanup.loopexit.loopexit:
247 ; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
248 ; CHECK:       for.cond.cleanup.loopexit:
249 ; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
250 ; CHECK:       for.cond.cleanup:
251 ; CHECK-NEXT:    ret void
252 ; CHECK:       for.body:
253 ; CHECK-NEXT:    [[I_017:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER1]] ]
254 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[I_017]], 512
255 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017]]
256 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
257 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017]]
258 ; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
259 ; CHECK-NEXT:    br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
260 ; CHECK:       if.then:
261 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[TMP1]], [[TMP2]]
262 ; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]]
263 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4
264 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[SUB]], [[TMP3]]
265 ; CHECK-NEXT:    store i32 [[ADD]], ptr [[ARRAYIDX3]], align 4
266 ; CHECK-NEXT:    br label [[FOR_INC]]
267 ; CHECK:       if.else:
268 ; CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 [[TMP2]], [[TMP1]]
269 ; CHECK-NEXT:    [[ARRAYIDX7:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]]
270 ; CHECK-NEXT:    store i32 [[ADD6]], ptr [[ARRAYIDX7]], align 4
271 ; CHECK-NEXT:    br label [[FOR_INC]]
272 ; CHECK:       for.inc:
273 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_017]], 1
274 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp slt i32 [[INC]], [[N]]
275 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp slt i32 [[INC]], [[EXIT_MAINLOOP_AT]]
276 ; CHECK-NEXT:    br i1 [[TMP4]], label [[FOR_BODY]], label [[MAIN_EXIT_SELECTOR:%.*]]
277 ; CHECK:       main.exit.selector:
278 ; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[FOR_INC]] ]
279 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp slt i32 [[INC_LCSSA]], [[N]]
280 ; CHECK-NEXT:    br i1 [[TMP5]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
281 ; CHECK:       main.pseudo.exit:
282 ; CHECK-NEXT:    [[I_017_COPY:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
283 ; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
284 ; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
285 ; CHECK:       postloop:
286 ; CHECK-NEXT:    br label [[FOR_BODY_POSTLOOP:%.*]]
287 ; CHECK:       for.body.postloop:
288 ; CHECK-NEXT:    [[I_017_POSTLOOP:%.*]] = phi i32 [ [[INC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[I_017_COPY]], [[POSTLOOP]] ]
289 ; CHECK-NEXT:    [[CMP1_POSTLOOP:%.*]] = icmp ult i32 [[I_017_POSTLOOP]], 512
290 ; CHECK-NEXT:    [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017_POSTLOOP]]
291 ; CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4
292 ; CHECK-NEXT:    [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017_POSTLOOP]]
293 ; CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4
294 ; CHECK-NEXT:    br i1 [[CMP1_POSTLOOP]], label [[IF_THEN_POSTLOOP:%.*]], label [[IF_ELSE_POSTLOOP:%.*]]
295 ; CHECK:       if.else.postloop:
296 ; CHECK-NEXT:    [[ADD6_POSTLOOP:%.*]] = add nsw i32 [[TMP7]], [[TMP6]]
297 ; CHECK-NEXT:    [[ARRAYIDX7_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]]
298 ; CHECK-NEXT:    store i32 [[ADD6_POSTLOOP]], ptr [[ARRAYIDX7_POSTLOOP]], align 4
299 ; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
300 ; CHECK:       if.then.postloop:
301 ; CHECK-NEXT:    [[SUB_POSTLOOP:%.*]] = sub i32 [[TMP6]], [[TMP7]]
302 ; CHECK-NEXT:    [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]]
303 ; CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4
304 ; CHECK-NEXT:    [[ADD_POSTLOOP:%.*]] = add nsw i32 [[SUB_POSTLOOP]], [[TMP8]]
305 ; CHECK-NEXT:    store i32 [[ADD_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4
306 ; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
307 ; CHECK:       for.inc.postloop:
308 ; CHECK-NEXT:    [[INC_POSTLOOP]] = add nuw nsw i32 [[I_017_POSTLOOP]], 1
309 ; CHECK-NEXT:    [[EXITCOND_POSTLOOP:%.*]] = icmp slt i32 [[INC_POSTLOOP]], [[N]]
310 ; CHECK-NEXT:    br i1 [[EXITCOND_POSTLOOP]], label [[FOR_BODY_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP7:![0-9]+]], !loop_constrainer.loop.clone !5
312 entry:
313   %cmp16 = icmp sgt i32 %N, 0
314   br i1 %cmp16, label %for.body, label %for.cond.cleanup
316 for.cond.cleanup:
317   ret void
319 for.body:
320   %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ]
321   %cmp1 = icmp ult i32 %i.017, 512
322   %arrayidx = getelementptr inbounds i32, ptr %b, i32 %i.017
323   %0 = load i32, ptr %arrayidx, align 4
324   %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %i.017
325   %1 = load i32, ptr %arrayidx2, align 4
326   br i1 %cmp1, label %if.then, label %if.else
328 if.then:
329   %sub = sub i32 %0, %1
330   %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %i.017
331   %2 = load i32, ptr %arrayidx3, align 4
332   %add = add nsw i32 %sub, %2
333   store i32 %add, ptr %arrayidx3, align 4
334   br label %for.inc
336 if.else:
337   %add6 = add nsw i32 %1, %0
338   %arrayidx7 = getelementptr inbounds i32, ptr %a, i32 %i.017
339   store i32 %add6, ptr %arrayidx7, align 4
340   br label %for.inc
342 for.inc:
343   %inc = add nuw nsw i32 %i.017, 1
344   %exitcond = icmp slt i32 %inc, %N
345   br i1 %exitcond, label %for.body, label %for.cond.cleanup
348 define void @test_inc_ult(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %N) {
349 ; CHECK-LABEL: define void @test_inc_ult(
350 ; CHECK-SAME: ptr nocapture [[A:%.*]], ptr nocapture readonly [[B:%.*]], ptr nocapture readonly [[C:%.*]], i32 [[N:%.*]]) {
351 ; CHECK-NEXT:  entry:
352 ; CHECK-NEXT:    [[CMP16:%.*]] = icmp ugt i32 [[N]], 0
353 ; CHECK-NEXT:    br i1 [[CMP16]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
354 ; CHECK:       for.body.preheader:
355 ; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = call i32 @llvm.umin.i32(i32 [[N]], i32 512)
356 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 0, [[EXIT_MAINLOOP_AT]]
357 ; CHECK-NEXT:    br i1 [[TMP0]], label [[FOR_BODY_PREHEADER1:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
358 ; CHECK:       for.body.preheader1:
359 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
360 ; CHECK:       for.cond.cleanup.loopexit.loopexit:
361 ; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
362 ; CHECK:       for.cond.cleanup.loopexit:
363 ; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
364 ; CHECK:       for.cond.cleanup:
365 ; CHECK-NEXT:    ret void
366 ; CHECK:       for.body:
367 ; CHECK-NEXT:    [[I_017:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER1]] ]
368 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[I_017]], 512
369 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017]]
370 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
371 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017]]
372 ; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
373 ; CHECK-NEXT:    br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
374 ; CHECK:       if.then:
375 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[TMP1]], [[TMP2]]
376 ; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]]
377 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4
378 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[SUB]], [[TMP3]]
379 ; CHECK-NEXT:    store i32 [[ADD]], ptr [[ARRAYIDX3]], align 4
380 ; CHECK-NEXT:    br label [[FOR_INC]]
381 ; CHECK:       if.else:
382 ; CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 [[TMP2]], [[TMP1]]
383 ; CHECK-NEXT:    [[ARRAYIDX7:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]]
384 ; CHECK-NEXT:    store i32 [[ADD6]], ptr [[ARRAYIDX7]], align 4
385 ; CHECK-NEXT:    br label [[FOR_INC]]
386 ; CHECK:       for.inc:
387 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_017]], 1
388 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ult i32 [[INC]], [[N]]
389 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i32 [[INC]], [[EXIT_MAINLOOP_AT]]
390 ; CHECK-NEXT:    br i1 [[TMP4]], label [[FOR_BODY]], label [[MAIN_EXIT_SELECTOR:%.*]]
391 ; CHECK:       main.exit.selector:
392 ; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[FOR_INC]] ]
393 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp ult i32 [[INC_LCSSA]], [[N]]
394 ; CHECK-NEXT:    br i1 [[TMP5]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
395 ; CHECK:       main.pseudo.exit:
396 ; CHECK-NEXT:    [[I_017_COPY:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
397 ; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
398 ; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
399 ; CHECK:       postloop:
400 ; CHECK-NEXT:    br label [[FOR_BODY_POSTLOOP:%.*]]
401 ; CHECK:       for.body.postloop:
402 ; CHECK-NEXT:    [[I_017_POSTLOOP:%.*]] = phi i32 [ [[INC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[I_017_COPY]], [[POSTLOOP]] ]
403 ; CHECK-NEXT:    [[CMP1_POSTLOOP:%.*]] = icmp ult i32 [[I_017_POSTLOOP]], 512
404 ; CHECK-NEXT:    [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017_POSTLOOP]]
405 ; CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4
406 ; CHECK-NEXT:    [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017_POSTLOOP]]
407 ; CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4
408 ; CHECK-NEXT:    br i1 [[CMP1_POSTLOOP]], label [[IF_THEN_POSTLOOP:%.*]], label [[IF_ELSE_POSTLOOP:%.*]]
409 ; CHECK:       if.else.postloop:
410 ; CHECK-NEXT:    [[ADD6_POSTLOOP:%.*]] = add nsw i32 [[TMP7]], [[TMP6]]
411 ; CHECK-NEXT:    [[ARRAYIDX7_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]]
412 ; CHECK-NEXT:    store i32 [[ADD6_POSTLOOP]], ptr [[ARRAYIDX7_POSTLOOP]], align 4
413 ; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
414 ; CHECK:       if.then.postloop:
415 ; CHECK-NEXT:    [[SUB_POSTLOOP:%.*]] = sub i32 [[TMP6]], [[TMP7]]
416 ; CHECK-NEXT:    [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]]
417 ; CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4
418 ; CHECK-NEXT:    [[ADD_POSTLOOP:%.*]] = add nsw i32 [[SUB_POSTLOOP]], [[TMP8]]
419 ; CHECK-NEXT:    store i32 [[ADD_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4
420 ; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
421 ; CHECK:       for.inc.postloop:
422 ; CHECK-NEXT:    [[INC_POSTLOOP]] = add nuw nsw i32 [[I_017_POSTLOOP]], 1
423 ; CHECK-NEXT:    [[EXITCOND_POSTLOOP:%.*]] = icmp ult i32 [[INC_POSTLOOP]], [[N]]
424 ; CHECK-NEXT:    br i1 [[EXITCOND_POSTLOOP]], label [[FOR_BODY_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP8:![0-9]+]], !loop_constrainer.loop.clone !5
426 entry:
427   %cmp16 = icmp ugt i32 %N, 0
428   br i1 %cmp16, label %for.body, label %for.cond.cleanup
430 for.cond.cleanup:
431   ret void
433 for.body:
434   %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ]
435   %cmp1 = icmp ult i32 %i.017, 512
436   %arrayidx = getelementptr inbounds i32, ptr %b, i32 %i.017
437   %0 = load i32, ptr %arrayidx, align 4
438   %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %i.017
439   %1 = load i32, ptr %arrayidx2, align 4
440   br i1 %cmp1, label %if.then, label %if.else
442 if.then:
443   %sub = sub i32 %0, %1
444   %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %i.017
445   %2 = load i32, ptr %arrayidx3, align 4
446   %add = add nsw i32 %sub, %2
447   store i32 %add, ptr %arrayidx3, align 4
448   br label %for.inc
450 if.else:
451   %add6 = add nsw i32 %1, %0
452   %arrayidx7 = getelementptr inbounds i32, ptr %a, i32 %i.017
453   store i32 %add6, ptr %arrayidx7, align 4
454   br label %for.inc
456 for.inc:
457   %inc = add nuw nsw i32 %i.017, 1
458   %exitcond = icmp ult i32 %inc, %N
459   br i1 %exitcond, label %for.body, label %for.cond.cleanup
462 define void @signed_var_imm_dec_sgt(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %M) {
463 ; CHECK-LABEL: define void @signed_var_imm_dec_sgt(
464 ; CHECK-SAME: ptr nocapture [[A:%.*]], ptr nocapture readonly [[B:%.*]], ptr nocapture readonly [[C:%.*]], i32 [[M:%.*]]) {
465 ; CHECK-NEXT:  entry:
466 ; CHECK-NEXT:    [[CMP14:%.*]] = icmp slt i32 [[M]], 1024
467 ; CHECK-NEXT:    br i1 [[CMP14]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
468 ; CHECK:       for.body.preheader:
469 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[M]], 1
470 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 1024)
471 ; CHECK-NEXT:    [[EXIT_PRELOOP_AT:%.*]] = add nsw i32 [[SMAX]], -1
472 ; CHECK-NEXT:    [[SMAX1:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 0)
473 ; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = add nsw i32 [[SMAX1]], -1
474 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 1024, [[EXIT_PRELOOP_AT]]
475 ; CHECK-NEXT:    br i1 [[TMP1]], label [[FOR_BODY_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]]
476 ; CHECK:       for.body.preloop.preheader:
477 ; CHECK-NEXT:    br label [[FOR_BODY_PRELOOP:%.*]]
478 ; CHECK:       for.cond.cleanup.loopexit.loopexit:
479 ; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
480 ; CHECK:       for.cond.cleanup.loopexit:
481 ; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
482 ; CHECK:       for.cond.cleanup:
483 ; CHECK-NEXT:    ret void
484 ; CHECK:       mainloop:
485 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[INDVAR_END:%.*]], [[EXIT_MAINLOOP_AT]]
486 ; CHECK-NEXT:    br i1 [[TMP2]], label [[FOR_BODY_PREHEADER3:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
487 ; CHECK:       for.body.preheader3:
488 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
489 ; CHECK:       for.body:
490 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[DEC:%.*]], [[FOR_INC:%.*]] ], [ [[IV_PRELOOP_COPY:%.*]], [[FOR_BODY_PREHEADER3]] ]
491 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[IV]], 1024
492 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV]]
493 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
494 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV]]
495 ; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
496 ; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP4]], [[TMP3]]
497 ; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV]]
498 ; CHECK-NEXT:    br i1 true, label [[FOR_INC]], label [[IF_ELSE:%.*]]
499 ; CHECK:       if.else:
500 ; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4
501 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP5]], [[MUL]]
502 ; CHECK-NEXT:    br label [[FOR_INC]]
503 ; CHECK:       for.inc:
504 ; CHECK-NEXT:    [[STOREMERGE:%.*]] = phi i32 [ [[ADD]], [[IF_ELSE]] ], [ [[MUL]], [[FOR_BODY]] ]
505 ; CHECK-NEXT:    store i32 [[STOREMERGE]], ptr [[ARRAYIDX3]], align 4
506 ; CHECK-NEXT:    [[DEC]] = add nsw i32 [[IV]], -1
507 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[M]]
508 ; CHECK-NEXT:    [[TMP6:%.*]] = icmp sgt i32 [[DEC]], [[EXIT_MAINLOOP_AT]]
509 ; CHECK-NEXT:    br i1 [[TMP6]], label [[FOR_BODY]], label [[MAIN_EXIT_SELECTOR:%.*]]
510 ; CHECK:       main.exit.selector:
511 ; CHECK-NEXT:    [[DEC_LCSSA:%.*]] = phi i32 [ [[DEC]], [[FOR_INC]] ]
512 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp sgt i32 [[DEC_LCSSA]], [[M]]
513 ; CHECK-NEXT:    br i1 [[TMP7]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
514 ; CHECK:       main.pseudo.exit:
515 ; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i32 [ [[IV_PRELOOP_COPY]], [[MAINLOOP:%.*]] ], [ [[DEC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
516 ; CHECK-NEXT:    [[INDVAR_END2:%.*]] = phi i32 [ [[INDVAR_END]], [[MAINLOOP]] ], [ [[DEC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
517 ; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
518 ; CHECK:       for.body.preloop:
519 ; CHECK-NEXT:    [[IV_PRELOOP:%.*]] = phi i32 [ [[DEC_PRELOOP:%.*]], [[FOR_INC_PRELOOP:%.*]] ], [ 1024, [[FOR_BODY_PRELOOP_PREHEADER]] ]
520 ; CHECK-NEXT:    [[CMP1_PRELOOP:%.*]] = icmp slt i32 [[IV_PRELOOP]], 1024
521 ; CHECK-NEXT:    [[ARRAYIDX_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_PRELOOP]]
522 ; CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX_PRELOOP]], align 4
523 ; CHECK-NEXT:    [[ARRAYIDX2_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_PRELOOP]]
524 ; CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX2_PRELOOP]], align 4
525 ; CHECK-NEXT:    [[MUL_PRELOOP:%.*]] = mul nsw i32 [[TMP9]], [[TMP8]]
526 ; CHECK-NEXT:    [[ARRAYIDX3_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_PRELOOP]]
527 ; CHECK-NEXT:    br i1 [[CMP1_PRELOOP]], label [[FOR_INC_PRELOOP]], label [[IF_ELSE_PRELOOP:%.*]]
528 ; CHECK:       if.else.preloop:
529 ; CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX3_PRELOOP]], align 4
530 ; CHECK-NEXT:    [[ADD_PRELOOP:%.*]] = add nsw i32 [[TMP10]], [[MUL_PRELOOP]]
531 ; CHECK-NEXT:    br label [[FOR_INC_PRELOOP]]
532 ; CHECK:       for.inc.preloop:
533 ; CHECK-NEXT:    [[STOREMERGE_PRELOOP:%.*]] = phi i32 [ [[ADD_PRELOOP]], [[IF_ELSE_PRELOOP]] ], [ [[MUL_PRELOOP]], [[FOR_BODY_PRELOOP]] ]
534 ; CHECK-NEXT:    store i32 [[STOREMERGE_PRELOOP]], ptr [[ARRAYIDX3_PRELOOP]], align 4
535 ; CHECK-NEXT:    [[DEC_PRELOOP]] = add nsw i32 [[IV_PRELOOP]], -1
536 ; CHECK-NEXT:    [[CMP_PRELOOP:%.*]] = icmp sgt i32 [[DEC_PRELOOP]], [[M]]
537 ; CHECK-NEXT:    [[TMP11:%.*]] = icmp sgt i32 [[DEC_PRELOOP]], [[EXIT_PRELOOP_AT]]
538 ; CHECK-NEXT:    br i1 [[TMP11]], label [[FOR_BODY_PRELOOP]], label [[PRELOOP_EXIT_SELECTOR:%.*]], !llvm.loop [[LOOP9:![0-9]+]], !loop_constrainer.loop.clone !5
539 ; CHECK:       preloop.exit.selector:
540 ; CHECK-NEXT:    [[DEC_PRELOOP_LCSSA:%.*]] = phi i32 [ [[DEC_PRELOOP]], [[FOR_INC_PRELOOP]] ]
541 ; CHECK-NEXT:    [[TMP12:%.*]] = icmp sgt i32 [[DEC_PRELOOP_LCSSA]], [[M]]
542 ; CHECK-NEXT:    br i1 [[TMP12]], label [[PRELOOP_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
543 ; CHECK:       preloop.pseudo.exit:
544 ; CHECK-NEXT:    [[IV_PRELOOP_COPY]] = phi i32 [ 1024, [[FOR_BODY_PREHEADER]] ], [ [[DEC_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
545 ; CHECK-NEXT:    [[INDVAR_END]] = phi i32 [ 1024, [[FOR_BODY_PREHEADER]] ], [ [[DEC_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
546 ; CHECK-NEXT:    br label [[MAINLOOP]]
547 ; CHECK:       postloop:
548 ; CHECK-NEXT:    br label [[FOR_BODY_POSTLOOP:%.*]]
549 ; CHECK:       for.body.postloop:
550 ; CHECK-NEXT:    [[IV_POSTLOOP:%.*]] = phi i32 [ [[DEC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[IV_COPY]], [[POSTLOOP]] ]
551 ; CHECK-NEXT:    [[CMP1_POSTLOOP:%.*]] = icmp slt i32 [[IV_POSTLOOP]], 1024
552 ; CHECK-NEXT:    [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_POSTLOOP]]
553 ; CHECK-NEXT:    [[TMP13:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4
554 ; CHECK-NEXT:    [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_POSTLOOP]]
555 ; CHECK-NEXT:    [[TMP14:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4
556 ; CHECK-NEXT:    [[MUL_POSTLOOP:%.*]] = mul nsw i32 [[TMP14]], [[TMP13]]
557 ; CHECK-NEXT:    [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_POSTLOOP]]
558 ; CHECK-NEXT:    br i1 [[CMP1_POSTLOOP]], label [[FOR_INC_POSTLOOP]], label [[IF_ELSE_POSTLOOP:%.*]]
559 ; CHECK:       if.else.postloop:
560 ; CHECK-NEXT:    [[TMP15:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4
561 ; CHECK-NEXT:    [[ADD_POSTLOOP:%.*]] = add nsw i32 [[TMP15]], [[MUL_POSTLOOP]]
562 ; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
563 ; CHECK:       for.inc.postloop:
564 ; CHECK-NEXT:    [[STOREMERGE_POSTLOOP:%.*]] = phi i32 [ [[ADD_POSTLOOP]], [[IF_ELSE_POSTLOOP]] ], [ [[MUL_POSTLOOP]], [[FOR_BODY_POSTLOOP]] ]
565 ; CHECK-NEXT:    store i32 [[STOREMERGE_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4
566 ; CHECK-NEXT:    [[DEC_POSTLOOP]] = add nsw i32 [[IV_POSTLOOP]], -1
567 ; CHECK-NEXT:    [[CMP_POSTLOOP:%.*]] = icmp sgt i32 [[DEC_POSTLOOP]], [[M]]
568 ; CHECK-NEXT:    br i1 [[CMP_POSTLOOP]], label [[FOR_BODY_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP10:![0-9]+]], !loop_constrainer.loop.clone !5
570 entry:
571   %cmp14 = icmp slt i32 %M, 1024
572   br i1 %cmp14, label %for.body, label %for.cond.cleanup
574 for.cond.cleanup:                                 ; preds = %for.inc, %entry
575   ret void
577 for.body:                                         ; preds = %entry, %for.inc
578   %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ]
579   %cmp1 = icmp slt i32 %iv, 1024
580   %arrayidx = getelementptr inbounds i32, ptr %b, i32 %iv
581   %0 = load i32, ptr %arrayidx, align 4
582   %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %iv
583   %1 = load i32, ptr %arrayidx2, align 4
584   %mul = mul nsw i32 %1, %0
585   %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %iv
586   br i1 %cmp1, label %for.inc, label %if.else
588 if.else:                                          ; preds = %for.body
589   %2 = load i32, ptr %arrayidx3, align 4
590   %add = add nsw i32 %2, %mul
591   br label %for.inc
593 for.inc:                                          ; preds = %for.body, %if.else
594   %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ]
595   store i32 %storemerge, ptr %arrayidx3, align 4
596   %dec = add nsw i32 %iv, -1
597   %cmp = icmp sgt i32 %dec, %M
598   br i1 %cmp, label %for.body, label %for.cond.cleanup
601 define void @signed_var_imm_dec_sge(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %M) {
602 ; CHECK-LABEL: define void @signed_var_imm_dec_sge(
603 ; CHECK-SAME: ptr nocapture [[A:%.*]], ptr nocapture readonly [[B:%.*]], ptr nocapture readonly [[C:%.*]], i32 [[M:%.*]]) {
604 ; CHECK-NEXT:  entry:
605 ; CHECK-NEXT:    [[CMP14:%.*]] = icmp sgt i32 [[M]], 1024
606 ; CHECK-NEXT:    br i1 [[CMP14]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
607 ; CHECK:       for.body.preheader:
608 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[M]], 1
609 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 1025)
610 ; CHECK-NEXT:    [[EXIT_PRELOOP_AT:%.*]] = add nsw i32 [[SMAX]], -1
611 ; CHECK-NEXT:    [[SMAX1:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 1)
612 ; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = add nsw i32 [[SMAX1]], -1
613 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 1025, [[EXIT_PRELOOP_AT]]
614 ; CHECK-NEXT:    br i1 [[TMP1]], label [[FOR_BODY_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]]
615 ; CHECK:       for.body.preloop.preheader:
616 ; CHECK-NEXT:    br label [[FOR_BODY_PRELOOP:%.*]]
617 ; CHECK:       for.cond.cleanup.loopexit.loopexit:
618 ; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
619 ; CHECK:       for.cond.cleanup.loopexit:
620 ; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
621 ; CHECK:       for.cond.cleanup:
622 ; CHECK-NEXT:    ret void
623 ; CHECK:       mainloop:
624 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[INDVAR_END:%.*]], [[EXIT_MAINLOOP_AT]]
625 ; CHECK-NEXT:    br i1 [[TMP2]], label [[FOR_BODY_PREHEADER3:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
626 ; CHECK:       for.body.preheader3:
627 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
628 ; CHECK:       for.body:
629 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[DEC:%.*]], [[FOR_INC:%.*]] ], [ [[IV_PRELOOP_COPY:%.*]], [[FOR_BODY_PREHEADER3]] ]
630 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[IV]], 1024
631 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV]]
632 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
633 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV]]
634 ; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
635 ; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP4]], [[TMP3]]
636 ; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV]]
637 ; CHECK-NEXT:    br i1 true, label [[FOR_INC]], label [[IF_ELSE:%.*]]
638 ; CHECK:       if.else:
639 ; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4
640 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP5]], [[MUL]]
641 ; CHECK-NEXT:    br label [[FOR_INC]]
642 ; CHECK:       for.inc:
643 ; CHECK-NEXT:    [[STOREMERGE:%.*]] = phi i32 [ [[ADD]], [[IF_ELSE]] ], [ [[MUL]], [[FOR_BODY]] ]
644 ; CHECK-NEXT:    store i32 [[STOREMERGE]], ptr [[ARRAYIDX3]], align 4
645 ; CHECK-NEXT:    [[DEC]] = add nsw i32 [[IV]], -1
646 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[IV]], [[M]]
647 ; CHECK-NEXT:    [[TMP6:%.*]] = icmp sgt i32 [[IV]], [[EXIT_MAINLOOP_AT]]
648 ; CHECK-NEXT:    br i1 [[TMP6]], label [[FOR_BODY]], label [[MAIN_EXIT_SELECTOR:%.*]]
649 ; CHECK:       main.exit.selector:
650 ; CHECK-NEXT:    [[DEC_LCSSA:%.*]] = phi i32 [ [[DEC]], [[FOR_INC]] ]
651 ; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[FOR_INC]] ]
652 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp sgt i32 [[IV_LCSSA]], [[M]]
653 ; CHECK-NEXT:    br i1 [[TMP7]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
654 ; CHECK:       main.pseudo.exit:
655 ; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i32 [ [[IV_PRELOOP_COPY]], [[MAINLOOP:%.*]] ], [ [[DEC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
656 ; CHECK-NEXT:    [[INDVAR_END2:%.*]] = phi i32 [ [[INDVAR_END]], [[MAINLOOP]] ], [ [[IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
657 ; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
658 ; CHECK:       for.body.preloop:
659 ; CHECK-NEXT:    [[IV_PRELOOP:%.*]] = phi i32 [ [[DEC_PRELOOP:%.*]], [[FOR_INC_PRELOOP:%.*]] ], [ 1024, [[FOR_BODY_PRELOOP_PREHEADER]] ]
660 ; CHECK-NEXT:    [[CMP1_PRELOOP:%.*]] = icmp slt i32 [[IV_PRELOOP]], 1024
661 ; CHECK-NEXT:    [[ARRAYIDX_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_PRELOOP]]
662 ; CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX_PRELOOP]], align 4
663 ; CHECK-NEXT:    [[ARRAYIDX2_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_PRELOOP]]
664 ; CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX2_PRELOOP]], align 4
665 ; CHECK-NEXT:    [[MUL_PRELOOP:%.*]] = mul nsw i32 [[TMP9]], [[TMP8]]
666 ; CHECK-NEXT:    [[ARRAYIDX3_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_PRELOOP]]
667 ; CHECK-NEXT:    br i1 [[CMP1_PRELOOP]], label [[FOR_INC_PRELOOP]], label [[IF_ELSE_PRELOOP:%.*]]
668 ; CHECK:       if.else.preloop:
669 ; CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX3_PRELOOP]], align 4
670 ; CHECK-NEXT:    [[ADD_PRELOOP:%.*]] = add nsw i32 [[TMP10]], [[MUL_PRELOOP]]
671 ; CHECK-NEXT:    br label [[FOR_INC_PRELOOP]]
672 ; CHECK:       for.inc.preloop:
673 ; CHECK-NEXT:    [[STOREMERGE_PRELOOP:%.*]] = phi i32 [ [[ADD_PRELOOP]], [[IF_ELSE_PRELOOP]] ], [ [[MUL_PRELOOP]], [[FOR_BODY_PRELOOP]] ]
674 ; CHECK-NEXT:    store i32 [[STOREMERGE_PRELOOP]], ptr [[ARRAYIDX3_PRELOOP]], align 4
675 ; CHECK-NEXT:    [[DEC_PRELOOP]] = add nsw i32 [[IV_PRELOOP]], -1
676 ; CHECK-NEXT:    [[CMP_PRELOOP:%.*]] = icmp sgt i32 [[IV_PRELOOP]], [[M]]
677 ; CHECK-NEXT:    [[TMP11:%.*]] = icmp sgt i32 [[IV_PRELOOP]], [[EXIT_PRELOOP_AT]]
678 ; CHECK-NEXT:    br i1 [[TMP11]], label [[FOR_BODY_PRELOOP]], label [[PRELOOP_EXIT_SELECTOR:%.*]], !llvm.loop [[LOOP11:![0-9]+]], !loop_constrainer.loop.clone !5
679 ; CHECK:       preloop.exit.selector:
680 ; CHECK-NEXT:    [[DEC_PRELOOP_LCSSA:%.*]] = phi i32 [ [[DEC_PRELOOP]], [[FOR_INC_PRELOOP]] ]
681 ; CHECK-NEXT:    [[IV_PRELOOP_LCSSA:%.*]] = phi i32 [ [[IV_PRELOOP]], [[FOR_INC_PRELOOP]] ]
682 ; CHECK-NEXT:    [[TMP12:%.*]] = icmp sgt i32 [[IV_PRELOOP_LCSSA]], [[M]]
683 ; CHECK-NEXT:    br i1 [[TMP12]], label [[PRELOOP_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
684 ; CHECK:       preloop.pseudo.exit:
685 ; CHECK-NEXT:    [[IV_PRELOOP_COPY]] = phi i32 [ 1024, [[FOR_BODY_PREHEADER]] ], [ [[DEC_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
686 ; CHECK-NEXT:    [[INDVAR_END]] = phi i32 [ 1025, [[FOR_BODY_PREHEADER]] ], [ [[IV_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
687 ; CHECK-NEXT:    br label [[MAINLOOP]]
688 ; CHECK:       postloop:
689 ; CHECK-NEXT:    br label [[FOR_BODY_POSTLOOP:%.*]]
690 ; CHECK:       for.body.postloop:
691 ; CHECK-NEXT:    [[IV_POSTLOOP:%.*]] = phi i32 [ [[DEC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[IV_COPY]], [[POSTLOOP]] ]
692 ; CHECK-NEXT:    [[CMP1_POSTLOOP:%.*]] = icmp slt i32 [[IV_POSTLOOP]], 1024
693 ; CHECK-NEXT:    [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_POSTLOOP]]
694 ; CHECK-NEXT:    [[TMP13:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4
695 ; CHECK-NEXT:    [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_POSTLOOP]]
696 ; CHECK-NEXT:    [[TMP14:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4
697 ; CHECK-NEXT:    [[MUL_POSTLOOP:%.*]] = mul nsw i32 [[TMP14]], [[TMP13]]
698 ; CHECK-NEXT:    [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_POSTLOOP]]
699 ; CHECK-NEXT:    br i1 [[CMP1_POSTLOOP]], label [[FOR_INC_POSTLOOP]], label [[IF_ELSE_POSTLOOP:%.*]]
700 ; CHECK:       if.else.postloop:
701 ; CHECK-NEXT:    [[TMP15:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4
702 ; CHECK-NEXT:    [[ADD_POSTLOOP:%.*]] = add nsw i32 [[TMP15]], [[MUL_POSTLOOP]]
703 ; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
704 ; CHECK:       for.inc.postloop:
705 ; CHECK-NEXT:    [[STOREMERGE_POSTLOOP:%.*]] = phi i32 [ [[ADD_POSTLOOP]], [[IF_ELSE_POSTLOOP]] ], [ [[MUL_POSTLOOP]], [[FOR_BODY_POSTLOOP]] ]
706 ; CHECK-NEXT:    store i32 [[STOREMERGE_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4
707 ; CHECK-NEXT:    [[DEC_POSTLOOP]] = add nsw i32 [[IV_POSTLOOP]], -1
708 ; CHECK-NEXT:    [[CMP_POSTLOOP:%.*]] = icmp sgt i32 [[IV_POSTLOOP]], [[M]]
709 ; CHECK-NEXT:    br i1 [[CMP_POSTLOOP]], label [[FOR_BODY_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP12:![0-9]+]], !loop_constrainer.loop.clone !5
711 entry:
712   %cmp14 = icmp sgt i32 %M, 1024
713   br i1 %cmp14, label %for.cond.cleanup, label %for.body
715 for.cond.cleanup:                                 ; preds = %for.inc, %entry
716   ret void
718 for.body:                                         ; preds = %entry, %for.inc
719   %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ]
720   %cmp1 = icmp slt i32 %iv, 1024
721   %arrayidx = getelementptr inbounds i32, ptr %b, i32 %iv
722   %0 = load i32, ptr %arrayidx, align 4
723   %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %iv
724   %1 = load i32, ptr %arrayidx2, align 4
725   %mul = mul nsw i32 %1, %0
726   %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %iv
727   br i1 %cmp1, label %for.inc, label %if.else
729 if.else:                                          ; preds = %for.body
730   %2 = load i32, ptr %arrayidx3, align 4
731   %add = add nsw i32 %2, %mul
732   br label %for.inc
734 for.inc:                                          ; preds = %for.body, %if.else
735   %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ]
736   store i32 %storemerge, ptr %arrayidx3, align 4
737   %dec = add nsw i32 %iv, -1
738   %cmp = icmp sgt i32 %iv, %M
739   br i1 %cmp, label %for.body, label %for.cond.cleanup
742 define void @signed_var_imm_dec_slt(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %M) {
743 ; CHECK-LABEL: define void @signed_var_imm_dec_slt(
744 ; CHECK-SAME: ptr nocapture [[A:%.*]], ptr nocapture readonly [[B:%.*]], ptr nocapture readonly [[C:%.*]], i32 [[M:%.*]]) {
745 ; CHECK-NEXT:  entry:
746 ; CHECK-NEXT:    [[CMP14:%.*]] = icmp sgt i32 [[M]], 1024
747 ; CHECK-NEXT:    br i1 [[CMP14]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
748 ; CHECK:       for.body.preheader:
749 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
750 ; CHECK:       for.cond.cleanup.loopexit:
751 ; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
752 ; CHECK:       for.cond.cleanup:
753 ; CHECK-NEXT:    ret void
754 ; CHECK:       for.body:
755 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[DEC:%.*]], [[FOR_INC:%.*]] ], [ 1024, [[FOR_BODY_PREHEADER]] ]
756 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[IV]], 1024
757 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV]]
758 ; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
759 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV]]
760 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
761 ; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP1]], [[TMP0]]
762 ; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV]]
763 ; CHECK-NEXT:    br i1 [[CMP1]], label [[FOR_INC]], label [[IF_ELSE:%.*]]
764 ; CHECK:       if.else:
765 ; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4
766 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP2]], [[MUL]]
767 ; CHECK-NEXT:    br label [[FOR_INC]]
768 ; CHECK:       for.inc:
769 ; CHECK-NEXT:    [[STOREMERGE:%.*]] = phi i32 [ [[ADD]], [[IF_ELSE]] ], [ [[MUL]], [[FOR_BODY]] ]
770 ; CHECK-NEXT:    store i32 [[STOREMERGE]], ptr [[ARRAYIDX3]], align 4
771 ; CHECK-NEXT:    [[DEC]] = add nsw i32 [[IV]], -1
772 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[IV]], [[M]]
773 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY]]
775 entry:
776   %cmp14 = icmp sgt i32 %M, 1024
777   br i1 %cmp14, label %for.cond.cleanup, label %for.body
779 for.cond.cleanup:                                 ; preds = %for.inc, %entry
780   ret void
782 for.body:                                         ; preds = %entry, %for.inc
783   %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ]
784   %cmp1 = icmp slt i32 %iv, 1024
785   %arrayidx = getelementptr inbounds i32, ptr %b, i32 %iv
786   %0 = load i32, ptr %arrayidx, align 4
787   %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %iv
788   %1 = load i32, ptr %arrayidx2, align 4
789   %mul = mul nsw i32 %1, %0
790   %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %iv
791   br i1 %cmp1, label %for.inc, label %if.else
793 if.else:                                          ; preds = %for.body
794   %2 = load i32, ptr %arrayidx3, align 4
795   %add = add nsw i32 %2, %mul
796   br label %for.inc
798 for.inc:                                          ; preds = %for.body, %if.else
799   %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ]
800   store i32 %storemerge, ptr %arrayidx3, align 4
801   %dec = add nsw i32 %iv, -1
802   %cmp = icmp slt i32 %iv, %M
803   br i1 %cmp, label %for.cond.cleanup, label %for.body
806 define void @signed_var_imm_dec_ne(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %M) {
807 ; CHECK-LABEL: define void @signed_var_imm_dec_ne(
808 ; CHECK-SAME: ptr nocapture [[A:%.*]], ptr nocapture readonly [[B:%.*]], ptr nocapture readonly [[C:%.*]], i32 [[M:%.*]]) {
809 ; CHECK-NEXT:  entry:
810 ; CHECK-NEXT:    [[CMP14:%.*]] = icmp slt i32 [[M]], 1024
811 ; CHECK-NEXT:    br i1 [[CMP14]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
812 ; CHECK:       for.body.preheader:
813 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[M]], 1
814 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 1024)
815 ; CHECK-NEXT:    [[EXIT_PRELOOP_AT:%.*]] = add nsw i32 [[SMAX]], -1
816 ; CHECK-NEXT:    [[SMAX1:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 0)
817 ; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = add nsw i32 [[SMAX1]], -1
818 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 1024, [[EXIT_PRELOOP_AT]]
819 ; CHECK-NEXT:    br i1 [[TMP1]], label [[FOR_BODY_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]]
820 ; CHECK:       for.body.preloop.preheader:
821 ; CHECK-NEXT:    br label [[FOR_BODY_PRELOOP:%.*]]
822 ; CHECK:       for.cond.cleanup.loopexit.loopexit:
823 ; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
824 ; CHECK:       for.cond.cleanup.loopexit:
825 ; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
826 ; CHECK:       for.cond.cleanup:
827 ; CHECK-NEXT:    ret void
828 ; CHECK:       mainloop:
829 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[INDVAR_END:%.*]], [[EXIT_MAINLOOP_AT]]
830 ; CHECK-NEXT:    br i1 [[TMP2]], label [[FOR_BODY_PREHEADER3:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
831 ; CHECK:       for.body.preheader3:
832 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
833 ; CHECK:       for.body:
834 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[DEC:%.*]], [[FOR_INC:%.*]] ], [ [[IV_PRELOOP_COPY:%.*]], [[FOR_BODY_PREHEADER3]] ]
835 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[IV]], 1024
836 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV]]
837 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
838 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV]]
839 ; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
840 ; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP4]], [[TMP3]]
841 ; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV]]
842 ; CHECK-NEXT:    br i1 true, label [[FOR_INC]], label [[IF_ELSE:%.*]]
843 ; CHECK:       if.else:
844 ; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4
845 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP5]], [[MUL]]
846 ; CHECK-NEXT:    br label [[FOR_INC]]
847 ; CHECK:       for.inc:
848 ; CHECK-NEXT:    [[STOREMERGE:%.*]] = phi i32 [ [[ADD]], [[IF_ELSE]] ], [ [[MUL]], [[FOR_BODY]] ]
849 ; CHECK-NEXT:    store i32 [[STOREMERGE]], ptr [[ARRAYIDX3]], align 4
850 ; CHECK-NEXT:    [[DEC]] = add nsw i32 [[IV]], -1
851 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[DEC]], [[M]]
852 ; CHECK-NEXT:    [[TMP6:%.*]] = icmp sgt i32 [[DEC]], [[EXIT_MAINLOOP_AT]]
853 ; CHECK-NEXT:    br i1 [[TMP6]], label [[FOR_BODY]], label [[MAIN_EXIT_SELECTOR:%.*]]
854 ; CHECK:       main.exit.selector:
855 ; CHECK-NEXT:    [[DEC_LCSSA:%.*]] = phi i32 [ [[DEC]], [[FOR_INC]] ]
856 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp sgt i32 [[DEC_LCSSA]], [[M]]
857 ; CHECK-NEXT:    br i1 [[TMP7]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
858 ; CHECK:       main.pseudo.exit:
859 ; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i32 [ [[IV_PRELOOP_COPY]], [[MAINLOOP:%.*]] ], [ [[DEC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
860 ; CHECK-NEXT:    [[INDVAR_END2:%.*]] = phi i32 [ [[INDVAR_END]], [[MAINLOOP]] ], [ [[DEC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
861 ; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
862 ; CHECK:       for.body.preloop:
863 ; CHECK-NEXT:    [[IV_PRELOOP:%.*]] = phi i32 [ [[DEC_PRELOOP:%.*]], [[FOR_INC_PRELOOP:%.*]] ], [ 1024, [[FOR_BODY_PRELOOP_PREHEADER]] ]
864 ; CHECK-NEXT:    [[CMP1_PRELOOP:%.*]] = icmp slt i32 [[IV_PRELOOP]], 1024
865 ; CHECK-NEXT:    [[ARRAYIDX_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_PRELOOP]]
866 ; CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX_PRELOOP]], align 4
867 ; CHECK-NEXT:    [[ARRAYIDX2_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_PRELOOP]]
868 ; CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX2_PRELOOP]], align 4
869 ; CHECK-NEXT:    [[MUL_PRELOOP:%.*]] = mul nsw i32 [[TMP9]], [[TMP8]]
870 ; CHECK-NEXT:    [[ARRAYIDX3_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_PRELOOP]]
871 ; CHECK-NEXT:    br i1 [[CMP1_PRELOOP]], label [[FOR_INC_PRELOOP]], label [[IF_ELSE_PRELOOP:%.*]]
872 ; CHECK:       if.else.preloop:
873 ; CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX3_PRELOOP]], align 4
874 ; CHECK-NEXT:    [[ADD_PRELOOP:%.*]] = add nsw i32 [[TMP10]], [[MUL_PRELOOP]]
875 ; CHECK-NEXT:    br label [[FOR_INC_PRELOOP]]
876 ; CHECK:       for.inc.preloop:
877 ; CHECK-NEXT:    [[STOREMERGE_PRELOOP:%.*]] = phi i32 [ [[ADD_PRELOOP]], [[IF_ELSE_PRELOOP]] ], [ [[MUL_PRELOOP]], [[FOR_BODY_PRELOOP]] ]
878 ; CHECK-NEXT:    store i32 [[STOREMERGE_PRELOOP]], ptr [[ARRAYIDX3_PRELOOP]], align 4
879 ; CHECK-NEXT:    [[DEC_PRELOOP]] = add nsw i32 [[IV_PRELOOP]], -1
880 ; CHECK-NEXT:    [[CMP_PRELOOP:%.*]] = icmp ne i32 [[DEC_PRELOOP]], [[M]]
881 ; CHECK-NEXT:    [[TMP11:%.*]] = icmp sgt i32 [[DEC_PRELOOP]], [[EXIT_PRELOOP_AT]]
882 ; CHECK-NEXT:    br i1 [[TMP11]], label [[FOR_BODY_PRELOOP]], label [[PRELOOP_EXIT_SELECTOR:%.*]], !llvm.loop [[LOOP13:![0-9]+]], !loop_constrainer.loop.clone !5
883 ; CHECK:       preloop.exit.selector:
884 ; CHECK-NEXT:    [[DEC_PRELOOP_LCSSA:%.*]] = phi i32 [ [[DEC_PRELOOP]], [[FOR_INC_PRELOOP]] ]
885 ; CHECK-NEXT:    [[TMP12:%.*]] = icmp sgt i32 [[DEC_PRELOOP_LCSSA]], [[M]]
886 ; CHECK-NEXT:    br i1 [[TMP12]], label [[PRELOOP_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
887 ; CHECK:       preloop.pseudo.exit:
888 ; CHECK-NEXT:    [[IV_PRELOOP_COPY]] = phi i32 [ 1024, [[FOR_BODY_PREHEADER]] ], [ [[DEC_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
889 ; CHECK-NEXT:    [[INDVAR_END]] = phi i32 [ 1024, [[FOR_BODY_PREHEADER]] ], [ [[DEC_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
890 ; CHECK-NEXT:    br label [[MAINLOOP]]
891 ; CHECK:       postloop:
892 ; CHECK-NEXT:    br label [[FOR_BODY_POSTLOOP:%.*]]
893 ; CHECK:       for.body.postloop:
894 ; CHECK-NEXT:    [[IV_POSTLOOP:%.*]] = phi i32 [ [[DEC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[IV_COPY]], [[POSTLOOP]] ]
895 ; CHECK-NEXT:    [[CMP1_POSTLOOP:%.*]] = icmp slt i32 [[IV_POSTLOOP]], 1024
896 ; CHECK-NEXT:    [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_POSTLOOP]]
897 ; CHECK-NEXT:    [[TMP13:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4
898 ; CHECK-NEXT:    [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_POSTLOOP]]
899 ; CHECK-NEXT:    [[TMP14:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4
900 ; CHECK-NEXT:    [[MUL_POSTLOOP:%.*]] = mul nsw i32 [[TMP14]], [[TMP13]]
901 ; CHECK-NEXT:    [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_POSTLOOP]]
902 ; CHECK-NEXT:    br i1 [[CMP1_POSTLOOP]], label [[FOR_INC_POSTLOOP]], label [[IF_ELSE_POSTLOOP:%.*]]
903 ; CHECK:       if.else.postloop:
904 ; CHECK-NEXT:    [[TMP15:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4
905 ; CHECK-NEXT:    [[ADD_POSTLOOP:%.*]] = add nsw i32 [[TMP15]], [[MUL_POSTLOOP]]
906 ; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
907 ; CHECK:       for.inc.postloop:
908 ; CHECK-NEXT:    [[STOREMERGE_POSTLOOP:%.*]] = phi i32 [ [[ADD_POSTLOOP]], [[IF_ELSE_POSTLOOP]] ], [ [[MUL_POSTLOOP]], [[FOR_BODY_POSTLOOP]] ]
909 ; CHECK-NEXT:    store i32 [[STOREMERGE_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4
910 ; CHECK-NEXT:    [[DEC_POSTLOOP]] = add nsw i32 [[IV_POSTLOOP]], -1
911 ; CHECK-NEXT:    [[CMP_POSTLOOP:%.*]] = icmp ne i32 [[DEC_POSTLOOP]], [[M]]
912 ; CHECK-NEXT:    br i1 [[CMP_POSTLOOP]], label [[FOR_BODY_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP14:![0-9]+]], !loop_constrainer.loop.clone !5
914 entry:
915   %cmp14 = icmp slt i32 %M, 1024
916   br i1 %cmp14, label %for.body, label %for.cond.cleanup
918 for.cond.cleanup:                                 ; preds = %for.inc, %entry
919   ret void
921 for.body:                                         ; preds = %entry, %for.inc
922   %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ]
923   %cmp1 = icmp slt i32 %iv, 1024
924   %arrayidx = getelementptr inbounds i32, ptr %b, i32 %iv
925   %0 = load i32, ptr %arrayidx, align 4
926   %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %iv
927   %1 = load i32, ptr %arrayidx2, align 4
928   %mul = mul nsw i32 %1, %0
929   %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %iv
930   br i1 %cmp1, label %for.inc, label %if.else
932 if.else:                                          ; preds = %for.body
933   %2 = load i32, ptr %arrayidx3, align 4
934   %add = add nsw i32 %2, %mul
935   br label %for.inc
937 for.inc:                                          ; preds = %for.body, %if.else
938   %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ]
939   store i32 %storemerge, ptr %arrayidx3, align 4
940   %dec = add nsw i32 %iv, -1
941   %cmp = icmp ne i32 %dec, %M
942   br i1 %cmp, label %for.body, label %for.cond.cleanup
945 define void @signed_var_imm_dec_eq(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %M) {
946 ; CHECK-LABEL: define void @signed_var_imm_dec_eq(
947 ; CHECK-SAME: ptr nocapture [[A:%.*]], ptr nocapture readonly [[B:%.*]], ptr nocapture readonly [[C:%.*]], i32 [[M:%.*]]) {
948 ; CHECK-NEXT:  entry:
949 ; CHECK-NEXT:    [[CMP14:%.*]] = icmp slt i32 [[M]], 1024
950 ; CHECK-NEXT:    br i1 [[CMP14]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
951 ; CHECK:       for.body.preheader:
952 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[M]], 1
953 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 1024)
954 ; CHECK-NEXT:    [[EXIT_PRELOOP_AT:%.*]] = add nsw i32 [[SMAX]], -1
955 ; CHECK-NEXT:    [[SMAX1:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 0)
956 ; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = add nsw i32 [[SMAX1]], -1
957 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 1024, [[EXIT_PRELOOP_AT]]
958 ; CHECK-NEXT:    br i1 [[TMP1]], label [[FOR_BODY_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]]
959 ; CHECK:       for.body.preloop.preheader:
960 ; CHECK-NEXT:    br label [[FOR_BODY_PRELOOP:%.*]]
961 ; CHECK:       for.cond.cleanup.loopexit.loopexit:
962 ; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
963 ; CHECK:       for.cond.cleanup.loopexit:
964 ; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
965 ; CHECK:       for.cond.cleanup:
966 ; CHECK-NEXT:    ret void
967 ; CHECK:       mainloop:
968 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[INDVAR_END:%.*]], [[EXIT_MAINLOOP_AT]]
969 ; CHECK-NEXT:    br i1 [[TMP2]], label [[FOR_BODY_PREHEADER3:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
970 ; CHECK:       for.body.preheader3:
971 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
972 ; CHECK:       for.body:
973 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[DEC:%.*]], [[FOR_INC:%.*]] ], [ [[IV_PRELOOP_COPY:%.*]], [[FOR_BODY_PREHEADER3]] ]
974 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[IV]], 1024
975 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV]]
976 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
977 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV]]
978 ; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
979 ; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP4]], [[TMP3]]
980 ; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV]]
981 ; CHECK-NEXT:    br i1 true, label [[FOR_INC]], label [[IF_ELSE:%.*]]
982 ; CHECK:       if.else:
983 ; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4
984 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP5]], [[MUL]]
985 ; CHECK-NEXT:    br label [[FOR_INC]]
986 ; CHECK:       for.inc:
987 ; CHECK-NEXT:    [[STOREMERGE:%.*]] = phi i32 [ [[ADD]], [[IF_ELSE]] ], [ [[MUL]], [[FOR_BODY]] ]
988 ; CHECK-NEXT:    store i32 [[STOREMERGE]], ptr [[ARRAYIDX3]], align 4
989 ; CHECK-NEXT:    [[DEC]] = add nsw i32 [[IV]], -1
990 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[DEC]], [[M]]
991 ; CHECK-NEXT:    [[TMP6:%.*]] = icmp sgt i32 [[DEC]], [[EXIT_MAINLOOP_AT]]
992 ; CHECK-NEXT:    [[TMP7:%.*]] = xor i1 [[TMP6]], true
993 ; CHECK-NEXT:    br i1 [[TMP7]], label [[MAIN_EXIT_SELECTOR:%.*]], label [[FOR_BODY]]
994 ; CHECK:       main.exit.selector:
995 ; CHECK-NEXT:    [[DEC_LCSSA:%.*]] = phi i32 [ [[DEC]], [[FOR_INC]] ]
996 ; CHECK-NEXT:    [[TMP8:%.*]] = icmp sgt i32 [[DEC_LCSSA]], [[M]]
997 ; CHECK-NEXT:    br i1 [[TMP8]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
998 ; CHECK:       main.pseudo.exit:
999 ; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i32 [ [[IV_PRELOOP_COPY]], [[MAINLOOP:%.*]] ], [ [[DEC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
1000 ; CHECK-NEXT:    [[INDVAR_END2:%.*]] = phi i32 [ [[INDVAR_END]], [[MAINLOOP]] ], [ [[DEC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
1001 ; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
1002 ; CHECK:       for.body.preloop:
1003 ; CHECK-NEXT:    [[IV_PRELOOP:%.*]] = phi i32 [ [[DEC_PRELOOP:%.*]], [[FOR_INC_PRELOOP:%.*]] ], [ 1024, [[FOR_BODY_PRELOOP_PREHEADER]] ]
1004 ; CHECK-NEXT:    [[CMP1_PRELOOP:%.*]] = icmp slt i32 [[IV_PRELOOP]], 1024
1005 ; CHECK-NEXT:    [[ARRAYIDX_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_PRELOOP]]
1006 ; CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX_PRELOOP]], align 4
1007 ; CHECK-NEXT:    [[ARRAYIDX2_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_PRELOOP]]
1008 ; CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX2_PRELOOP]], align 4
1009 ; CHECK-NEXT:    [[MUL_PRELOOP:%.*]] = mul nsw i32 [[TMP10]], [[TMP9]]
1010 ; CHECK-NEXT:    [[ARRAYIDX3_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_PRELOOP]]
1011 ; CHECK-NEXT:    br i1 [[CMP1_PRELOOP]], label [[FOR_INC_PRELOOP]], label [[IF_ELSE_PRELOOP:%.*]]
1012 ; CHECK:       if.else.preloop:
1013 ; CHECK-NEXT:    [[TMP11:%.*]] = load i32, ptr [[ARRAYIDX3_PRELOOP]], align 4
1014 ; CHECK-NEXT:    [[ADD_PRELOOP:%.*]] = add nsw i32 [[TMP11]], [[MUL_PRELOOP]]
1015 ; CHECK-NEXT:    br label [[FOR_INC_PRELOOP]]
1016 ; CHECK:       for.inc.preloop:
1017 ; CHECK-NEXT:    [[STOREMERGE_PRELOOP:%.*]] = phi i32 [ [[ADD_PRELOOP]], [[IF_ELSE_PRELOOP]] ], [ [[MUL_PRELOOP]], [[FOR_BODY_PRELOOP]] ]
1018 ; CHECK-NEXT:    store i32 [[STOREMERGE_PRELOOP]], ptr [[ARRAYIDX3_PRELOOP]], align 4
1019 ; CHECK-NEXT:    [[DEC_PRELOOP]] = add nsw i32 [[IV_PRELOOP]], -1
1020 ; CHECK-NEXT:    [[CMP_PRELOOP:%.*]] = icmp eq i32 [[DEC_PRELOOP]], [[M]]
1021 ; CHECK-NEXT:    [[TMP12:%.*]] = icmp sgt i32 [[DEC_PRELOOP]], [[EXIT_PRELOOP_AT]]
1022 ; CHECK-NEXT:    [[TMP13:%.*]] = xor i1 [[TMP12]], true
1023 ; CHECK-NEXT:    br i1 [[TMP13]], label [[PRELOOP_EXIT_SELECTOR:%.*]], label [[FOR_BODY_PRELOOP]], !llvm.loop [[LOOP15:![0-9]+]], !loop_constrainer.loop.clone !5
1024 ; CHECK:       preloop.exit.selector:
1025 ; CHECK-NEXT:    [[DEC_PRELOOP_LCSSA:%.*]] = phi i32 [ [[DEC_PRELOOP]], [[FOR_INC_PRELOOP]] ]
1026 ; CHECK-NEXT:    [[TMP14:%.*]] = icmp sgt i32 [[DEC_PRELOOP_LCSSA]], [[M]]
1027 ; CHECK-NEXT:    br i1 [[TMP14]], label [[PRELOOP_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
1028 ; CHECK:       preloop.pseudo.exit:
1029 ; CHECK-NEXT:    [[IV_PRELOOP_COPY]] = phi i32 [ 1024, [[FOR_BODY_PREHEADER]] ], [ [[DEC_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
1030 ; CHECK-NEXT:    [[INDVAR_END]] = phi i32 [ 1024, [[FOR_BODY_PREHEADER]] ], [ [[DEC_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
1031 ; CHECK-NEXT:    br label [[MAINLOOP]]
1032 ; CHECK:       postloop:
1033 ; CHECK-NEXT:    br label [[FOR_BODY_POSTLOOP:%.*]]
1034 ; CHECK:       for.body.postloop:
1035 ; CHECK-NEXT:    [[IV_POSTLOOP:%.*]] = phi i32 [ [[DEC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[IV_COPY]], [[POSTLOOP]] ]
1036 ; CHECK-NEXT:    [[CMP1_POSTLOOP:%.*]] = icmp slt i32 [[IV_POSTLOOP]], 1024
1037 ; CHECK-NEXT:    [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_POSTLOOP]]
1038 ; CHECK-NEXT:    [[TMP15:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4
1039 ; CHECK-NEXT:    [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_POSTLOOP]]
1040 ; CHECK-NEXT:    [[TMP16:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4
1041 ; CHECK-NEXT:    [[MUL_POSTLOOP:%.*]] = mul nsw i32 [[TMP16]], [[TMP15]]
1042 ; CHECK-NEXT:    [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_POSTLOOP]]
1043 ; CHECK-NEXT:    br i1 [[CMP1_POSTLOOP]], label [[FOR_INC_POSTLOOP]], label [[IF_ELSE_POSTLOOP:%.*]]
1044 ; CHECK:       if.else.postloop:
1045 ; CHECK-NEXT:    [[TMP17:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4
1046 ; CHECK-NEXT:    [[ADD_POSTLOOP:%.*]] = add nsw i32 [[TMP17]], [[MUL_POSTLOOP]]
1047 ; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
1048 ; CHECK:       for.inc.postloop:
1049 ; CHECK-NEXT:    [[STOREMERGE_POSTLOOP:%.*]] = phi i32 [ [[ADD_POSTLOOP]], [[IF_ELSE_POSTLOOP]] ], [ [[MUL_POSTLOOP]], [[FOR_BODY_POSTLOOP]] ]
1050 ; CHECK-NEXT:    store i32 [[STOREMERGE_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4
1051 ; CHECK-NEXT:    [[DEC_POSTLOOP]] = add nsw i32 [[IV_POSTLOOP]], -1
1052 ; CHECK-NEXT:    [[CMP_POSTLOOP:%.*]] = icmp eq i32 [[DEC_POSTLOOP]], [[M]]
1053 ; CHECK-NEXT:    br i1 [[CMP_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], label [[FOR_BODY_POSTLOOP]], !llvm.loop [[LOOP16:![0-9]+]], !loop_constrainer.loop.clone !5
1055 entry:
1056   %cmp14 = icmp slt i32 %M, 1024
1057   br i1 %cmp14, label %for.body, label %for.cond.cleanup
1059 for.cond.cleanup:                                 ; preds = %for.inc, %entry
1060   ret void
1062 for.body:                                         ; preds = %entry, %for.inc
1063   %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ]
1064   %cmp1 = icmp slt i32 %iv, 1024
1065   %arrayidx = getelementptr inbounds i32, ptr %b, i32 %iv
1066   %0 = load i32, ptr %arrayidx, align 4
1067   %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %iv
1068   %1 = load i32, ptr %arrayidx2, align 4
1069   %mul = mul nsw i32 %1, %0
1070   %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %iv
1071   br i1 %cmp1, label %for.inc, label %if.else
1073 if.else:                                          ; preds = %for.body
1074   %2 = load i32, ptr %arrayidx3, align 4
1075   %add = add nsw i32 %2, %mul
1076   br label %for.inc
1078 for.inc:                                          ; preds = %for.body, %if.else
1079   %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ]
1080   store i32 %storemerge, ptr %arrayidx3, align 4
1081   %dec = add nsw i32 %iv, -1
1082   %cmp = icmp eq i32 %dec, %M
1083   br i1 %cmp, label %for.cond.cleanup, label %for.body
1086 ;; Negative test
1087 define void @test_dec_bound_with_smaller_start_than_bound(i64 %0) {
1088 ; CHECK-LABEL: define void @test_dec_bound_with_smaller_start_than_bound(
1089 ; CHECK-SAME: i64 [[TMP0:%.*]]) {
1090 ; CHECK-NEXT:  entry:
1091 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
1092 ; CHECK:       for.body:
1093 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[DEC:%.*]], [[FOR_DEC:%.*]] ], [ 0, [[ENTRY:%.*]] ]
1094 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i64 [[IV]], [[TMP0]]
1095 ; CHECK-NEXT:    br i1 [[TMP1]], label [[IF_ELSE:%.*]], label [[FOR_DEC]]
1096 ; CHECK:       if.else:
1097 ; CHECK-NEXT:    br label [[FOR_DEC]]
1098 ; CHECK:       for.dec:
1099 ; CHECK-NEXT:    [[DEC]] = sub nuw nsw i64 [[IV]], 1
1100 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i64 [[DEC]], 1
1101 ; CHECK-NEXT:    br i1 [[TMP2]], label [[EXIT:%.*]], label [[FOR_BODY]]
1102 ; CHECK:       exit:
1103 ; CHECK-NEXT:    ret void
1105 entry:
1106   br label %for.body
1108 for.body:                                                ; preds = %for.dec, %entry
1109   %iv = phi i64 [ %dec, %for.dec ], [ 0, %entry ]
1110   %1 = icmp slt i64 %iv, %0
1111   br i1 %1, label %if.else, label %for.dec
1113 if.else:                                                ; preds = %for.body
1114   br label %for.dec
1116 for.dec:                                                ; preds = %if.else, %for.body
1117   %dec = sub nuw nsw i64 %iv, 1
1118   %2 = icmp slt i64 %dec, 1
1119   br i1 %2, label %exit, label %for.body
1121 exit:                                               ; preds = %for.dec
1122   ret void
1125 ;; Negative test
1126 define void @test_inc_bound_with_bigger_start_than_bound(i32 %0) {
1127 ; CHECK-LABEL: define void @test_inc_bound_with_bigger_start_than_bound(
1128 ; CHECK-SAME: i32 [[TMP0:%.*]]) {
1129 ; CHECK-NEXT:  entry:
1130 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
1131 ; CHECK:       for.body:
1132 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 200, [[ENTRY:%.*]] ]
1133 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[IV]], [[TMP0]]
1134 ; CHECK-NEXT:    br i1 [[TMP1]], label [[IF_ELSE:%.*]], label [[FOR_INC]]
1135 ; CHECK:       if.else:
1136 ; CHECK-NEXT:    br label [[FOR_INC]]
1137 ; CHECK:       for.inc:
1138 ; CHECK-NEXT:    [[INC]] = add nsw i32 [[IV]], 1
1139 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[INC]], 100
1140 ; CHECK-NEXT:    br i1 [[TMP2]], label [[EXIT:%.*]], label [[FOR_BODY]]
1141 ; CHECK:       exit:
1142 ; CHECK-NEXT:    ret void
1144 entry:
1145   br label %for.body
1147 for.body:                                                ; preds = %for.inc, %entry
1148   %iv = phi i32 [ %inc, %for.inc ], [ 200, %entry ]
1149   %1 = icmp slt i32 %iv, %0
1150   br i1 %1, label %if.else, label %for.inc
1152 if.else:                                                ; preds = %for.body
1153   br label %for.inc
1155 for.inc:                                                ; preds = %if.else, %for.body
1156   %inc = add nsw i32 %iv, 1
1157   %2 = icmp sgt i32 %inc, 100
1158   br i1 %2, label %exit, label %for.body
1160 exit:                                                ; preds = %for.inc
1161   ret void