@@ -160,6 +160,228 @@ exit:
160
160
ret void
161
161
}
162
162
163
+ define void @test_monotonic_ptr_iv_inc_1_different_element_types (ptr %start , i16 %len ) {
164
+ ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_different_element_types(
165
+ ; CHECK-NEXT: entry:
166
+ ; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]
167
+ ; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
168
+ ; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]
169
+ ; CHECK: loop.ph:
170
+ ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
171
+ ; CHECK: loop.header:
172
+ ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
173
+ ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
174
+ ; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]
175
+ ; CHECK: for.body:
176
+ ; CHECK-NEXT: [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]
177
+ ; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]
178
+ ; CHECK-NEXT: [[AND:%.*]] = and i1 [[T_1]], [[T_2]]
179
+ ; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
180
+ ; CHECK: loop.latch:
181
+ ; CHECK-NEXT: call void @use(ptr [[PTR_IV]])
182
+ ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 1
183
+ ; CHECK-NEXT: br label [[LOOP_HEADER]]
184
+ ; CHECK: exit:
185
+ ; CHECK-NEXT: ret void
186
+ ;
187
+ entry:
188
+ %upper = getelementptr inbounds i32 , ptr %start , i16 %len
189
+ %len.neg = icmp slt i16 %len , 0
190
+ br i1 %len.neg , label %exit , label %loop.ph
191
+
192
+ loop.ph:
193
+ br label %loop.header
194
+
195
+ loop.header:
196
+ %ptr.iv = phi ptr [ %start , %loop.ph ], [ %ptr.iv.next , %loop.latch ]
197
+ %c = icmp eq ptr %ptr.iv , %upper
198
+ br i1 %c , label %exit , label %for.body
199
+
200
+ for.body:
201
+ %t.1 = icmp uge ptr %ptr.iv , %start
202
+ %t.2 = icmp ult ptr %ptr.iv , %upper
203
+ %and = and i1 %t.1 , %t.2
204
+ br i1 %and , label %loop.latch , label %exit
205
+
206
+ loop.latch:
207
+ call void @use (ptr %ptr.iv )
208
+ %ptr.iv.next = getelementptr inbounds i8 , ptr %ptr.iv , i16 1
209
+ br label %loop.header
210
+
211
+ exit:
212
+ ret void
213
+ }
214
+
215
+ define void @test_monotonic_ptr_iv_inc_1_different_element_types_2 (ptr %start , i16 %len ) {
216
+ ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_different_element_types_2(
217
+ ; CHECK-NEXT: entry:
218
+ ; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 [[LEN:%.*]]
219
+ ; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
220
+ ; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]
221
+ ; CHECK: loop.ph:
222
+ ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
223
+ ; CHECK: loop.header:
224
+ ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
225
+ ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
226
+ ; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]
227
+ ; CHECK: for.body:
228
+ ; CHECK-NEXT: [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]
229
+ ; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]
230
+ ; CHECK-NEXT: [[AND:%.*]] = and i1 [[T_1]], [[T_2]]
231
+ ; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
232
+ ; CHECK: loop.latch:
233
+ ; CHECK-NEXT: call void @use(ptr [[PTR_IV]])
234
+ ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1
235
+ ; CHECK-NEXT: br label [[LOOP_HEADER]]
236
+ ; CHECK: exit:
237
+ ; CHECK-NEXT: ret void
238
+ ;
239
+ entry:
240
+ %upper = getelementptr inbounds i8 , ptr %start , i16 %len
241
+ %len.neg = icmp slt i16 %len , 0
242
+ br i1 %len.neg , label %exit , label %loop.ph
243
+
244
+ loop.ph:
245
+ br label %loop.header
246
+
247
+ loop.header:
248
+ %ptr.iv = phi ptr [ %start , %loop.ph ], [ %ptr.iv.next , %loop.latch ]
249
+ %c = icmp eq ptr %ptr.iv , %upper
250
+ br i1 %c , label %exit , label %for.body
251
+
252
+ for.body:
253
+ %t.1 = icmp uge ptr %ptr.iv , %start
254
+ %t.2 = icmp ult ptr %ptr.iv , %upper
255
+ %and = and i1 %t.1 , %t.2
256
+ br i1 %and , label %loop.latch , label %exit
257
+
258
+ loop.latch:
259
+ call void @use (ptr %ptr.iv )
260
+ %ptr.iv.next = getelementptr inbounds i32 , ptr %ptr.iv , i16 1
261
+ br label %loop.header
262
+
263
+ exit:
264
+ ret void
265
+ }
266
+
267
+ define void @test_monotonic_ptr_iv_inc_1_different_element_types_1_with_early_exit (ptr %start , i16 %len ) {
268
+ ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_different_element_types_1_with_early_exit(
269
+ ; CHECK-NEXT: entry:
270
+ ; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]
271
+ ; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
272
+ ; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]
273
+ ; CHECK: loop.ph:
274
+ ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
275
+ ; CHECK: loop.header:
276
+ ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
277
+ ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
278
+ ; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]
279
+ ; CHECK: for.body:
280
+ ; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()
281
+ ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
282
+ ; CHECK: loop.next:
283
+ ; CHECK-NEXT: [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]
284
+ ; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]
285
+ ; CHECK-NEXT: [[AND:%.*]] = and i1 [[T_1]], [[T_2]]
286
+ ; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
287
+ ; CHECK: loop.latch:
288
+ ; CHECK-NEXT: call void @use(ptr [[PTR_IV]])
289
+ ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 1
290
+ ; CHECK-NEXT: br label [[LOOP_HEADER]]
291
+ ; CHECK: exit:
292
+ ; CHECK-NEXT: ret void
293
+ ;
294
+ entry:
295
+ %upper = getelementptr inbounds i32 , ptr %start , i16 %len
296
+ %len.neg = icmp slt i16 %len , 0
297
+ br i1 %len.neg , label %exit , label %loop.ph
298
+
299
+ loop.ph:
300
+ br label %loop.header
301
+
302
+ loop.header:
303
+ %ptr.iv = phi ptr [ %start , %loop.ph ], [ %ptr.iv.next , %loop.latch ]
304
+ %c = icmp eq ptr %ptr.iv , %upper
305
+ br i1 %c , label %exit , label %for.body
306
+
307
+ for.body:
308
+ %c.1 = call i1 @cond ()
309
+ br i1 %c.1 , label %loop.next , label %exit
310
+
311
+ loop.next:
312
+ %t.1 = icmp uge ptr %ptr.iv , %start
313
+ %t.2 = icmp ult ptr %ptr.iv , %upper
314
+ %and = and i1 %t.1 , %t.2
315
+ br i1 %and , label %loop.latch , label %exit
316
+
317
+ loop.latch:
318
+ call void @use (ptr %ptr.iv )
319
+ %ptr.iv.next = getelementptr inbounds i8 , ptr %ptr.iv , i16 1
320
+ br label %loop.header
321
+
322
+ exit:
323
+ ret void
324
+ }
325
+
326
+ define void @test_monotonic_ptr_iv_inc_2_different_element_types_1_with_early_exit (ptr %start , i16 %len ) {
327
+ ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_2_different_element_types_1_with_early_exit(
328
+ ; CHECK-NEXT: entry:
329
+ ; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 [[LEN:%.*]]
330
+ ; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
331
+ ; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]
332
+ ; CHECK: loop.ph:
333
+ ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
334
+ ; CHECK: loop.header:
335
+ ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
336
+ ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
337
+ ; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]
338
+ ; CHECK: for.body:
339
+ ; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()
340
+ ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
341
+ ; CHECK: loop.next:
342
+ ; CHECK-NEXT: [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]
343
+ ; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]
344
+ ; CHECK-NEXT: [[AND:%.*]] = and i1 [[T_1]], [[T_2]]
345
+ ; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
346
+ ; CHECK: loop.latch:
347
+ ; CHECK-NEXT: call void @use(ptr [[PTR_IV]])
348
+ ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1
349
+ ; CHECK-NEXT: br label [[LOOP_HEADER]]
350
+ ; CHECK: exit:
351
+ ; CHECK-NEXT: ret void
352
+ ;
353
+ entry:
354
+ %upper = getelementptr inbounds i8 , ptr %start , i16 %len
355
+ %len.neg = icmp slt i16 %len , 0
356
+ br i1 %len.neg , label %exit , label %loop.ph
357
+
358
+ loop.ph:
359
+ br label %loop.header
360
+
361
+ loop.header:
362
+ %ptr.iv = phi ptr [ %start , %loop.ph ], [ %ptr.iv.next , %loop.latch ]
363
+ %c = icmp eq ptr %ptr.iv , %upper
364
+ br i1 %c , label %exit , label %for.body
365
+
366
+ for.body:
367
+ %c.1 = call i1 @cond ()
368
+ br i1 %c.1 , label %loop.next , label %exit
369
+
370
+ loop.next:
371
+ %t.1 = icmp uge ptr %ptr.iv , %start
372
+ %t.2 = icmp ult ptr %ptr.iv , %upper
373
+ %and = and i1 %t.1 , %t.2
374
+ br i1 %and , label %loop.latch , label %exit
375
+
376
+ loop.latch:
377
+ call void @use (ptr %ptr.iv )
378
+ %ptr.iv.next = getelementptr inbounds i32 , ptr %ptr.iv , i16 1
379
+ br label %loop.header
380
+
381
+ exit:
382
+ ret void
383
+ }
384
+
163
385
define void @test_ptr_iv_upper_may_be_less_than_start (ptr %start , i16 %len ) {
164
386
; CHECK-LABEL: @test_ptr_iv_upper_may_be_less_than_start(
165
387
; CHECK-NEXT: entry:
0 commit comments