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:%.*]]) {
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
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:%.*]]
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]]
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]]
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:%.*]]
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
84 %cmp16 = icmp sgt i32 %N, 0
85 br i1 %cmp16, label %for.body, label %for.cond.cleanup
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
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
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
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:%.*]]) {
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
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:%.*]]
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]]
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]]
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:%.*]]
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
198 %cmp16 = icmp sgt i32 %N, 0
199 br i1 %cmp16, label %for.body, label %for.cond.cleanup
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
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
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
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:%.*]]) {
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
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:%.*]]
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]]
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]]
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:%.*]]
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
313 %cmp16 = icmp sgt i32 %N, 0
314 br i1 %cmp16, label %for.body, label %for.cond.cleanup
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
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
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
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:%.*]]) {
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
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:%.*]]
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]]
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]]
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:%.*]]
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
427 %cmp16 = icmp ugt i32 %N, 0
428 br i1 %cmp16, label %for.body, label %for.cond.cleanup
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
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
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
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:%.*]]) {
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
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:%.*]]
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:%.*]]
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]]
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]]
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
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
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
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:%.*]]) {
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
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:%.*]]
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:%.*]]
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]]
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]]
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
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
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
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:%.*]]) {
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
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:%.*]]
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]]
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]]
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
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
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:%.*]]) {
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
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:%.*]]
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:%.*]]
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]]
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]]
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
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
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
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:%.*]]) {
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
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:%.*]]
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:%.*]]
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]]
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]]
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
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
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
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
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:%.*]]
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]]
1097 ; CHECK-NEXT: br label [[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]]
1103 ; CHECK-NEXT: ret void
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
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
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:%.*]]
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]]
1136 ; CHECK-NEXT: br label [[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]]
1142 ; CHECK-NEXT: ret void
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
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