llvm.org GIT mirror llvm / aac3847
[Tests] Highlight impact of multiple exit LFTR (D62625) as requested by reviewer git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363217 91177308-0d34-0410-b5e6-96231b3b80d8 Philip Reames 3 months ago
1 changed file(s) with 158 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
273273 exit:
274274 ret void
275275 }
276
277 ;; Show the value of multiple exit LFTR (being able to eliminate all but
278 ;; one IV when exit tests involve multiple IVs).
279 define void @combine_ivs(i32 %n) {
280 ; CHECK-LABEL: @combine_ivs(
281 ; CHECK-NEXT: entry:
282 ; CHECK-NEXT: br label [[LOOP:%.*]]
283 ; CHECK: loop:
284 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
285 ; CHECK-NEXT: [[IV2:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[IV2_NEXT:%.*]], [[LATCH]] ]
286 ; CHECK-NEXT: [[EARLYCND:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
287 ; CHECK-NEXT: br i1 [[EARLYCND]], label [[LATCH]], label [[EXIT:%.*]]
288 ; CHECK: latch:
289 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
290 ; CHECK-NEXT: [[IV2_NEXT]] = add nuw nsw i32 [[IV2]], 1
291 ; CHECK-NEXT: store volatile i32 [[IV]], i32* @A
292 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV2_NEXT]], 1000
293 ; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[EXIT]]
294 ; CHECK: exit:
295 ; CHECK-NEXT: ret void
296 ;
297 entry:
298 br label %loop
299
300 loop:
301 %iv = phi i32 [ 0, %entry], [ %iv.next, %latch]
302 %iv2 = phi i32 [ 1, %entry], [ %iv2.next, %latch]
303 %earlycnd = icmp ult i32 %iv, %n
304 br i1 %earlycnd, label %latch, label %exit
305
306 latch:
307 %iv.next = add i32 %iv, 1
308 %iv2.next = add i32 %iv2, 1
309 store volatile i32 %iv, i32* @A
310 %c = icmp ult i32 %iv2.next, 1000
311 br i1 %c, label %loop, label %exit
312
313 exit:
314 ret void
315 }
316
317 ; We can remove the decrementing IV entirely
318 define void @combine_ivs2(i32 %n) {
319 ; CHECK-LABEL: @combine_ivs2(
320 ; CHECK-NEXT: entry:
321 ; CHECK-NEXT: br label [[LOOP:%.*]]
322 ; CHECK: loop:
323 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
324 ; CHECK-NEXT: [[IV2:%.*]] = phi i32 [ 1000, [[ENTRY]] ], [ [[IV2_NEXT:%.*]], [[LATCH]] ]
325 ; CHECK-NEXT: [[EARLYCND:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
326 ; CHECK-NEXT: br i1 [[EARLYCND]], label [[LATCH]], label [[EXIT:%.*]]
327 ; CHECK: latch:
328 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
329 ; CHECK-NEXT: [[IV2_NEXT]] = sub nuw nsw i32 [[IV2]], 1
330 ; CHECK-NEXT: store volatile i32 [[IV]], i32* @A
331 ; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[IV2_NEXT]], 0
332 ; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[EXIT]]
333 ; CHECK: exit:
334 ; CHECK-NEXT: ret void
335 ;
336 entry:
337 br label %loop
338
339 loop:
340 %iv = phi i32 [ 0, %entry], [ %iv.next, %latch]
341 %iv2 = phi i32 [ 1000, %entry], [ %iv2.next, %latch]
342 %earlycnd = icmp ult i32 %iv, %n
343 br i1 %earlycnd, label %latch, label %exit
344
345 latch:
346 %iv.next = add i32 %iv, 1
347 %iv2.next = sub i32 %iv2, 1
348 store volatile i32 %iv, i32* @A
349 %c = icmp ugt i32 %iv2.next, 0
350 br i1 %c, label %loop, label %exit
351
352 exit:
353 ret void
354 }
355
356 ; An example where we can eliminate an f(i) computation entirely
357 ; from a multiple exit loop with LFTR.
358 define void @simplify_exit_test(i32 %n) {
359 ; CHECK-LABEL: @simplify_exit_test(
360 ; CHECK-NEXT: entry:
361 ; CHECK-NEXT: br label [[LOOP:%.*]]
362 ; CHECK: loop:
363 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
364 ; CHECK-NEXT: [[EARLYCND:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
365 ; CHECK-NEXT: br i1 [[EARLYCND]], label [[LATCH]], label [[EXIT:%.*]]
366 ; CHECK: latch:
367 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
368 ; CHECK-NEXT: [[FX:%.*]] = shl i32 [[IV]], 4
369 ; CHECK-NEXT: store volatile i32 [[IV]], i32* @A
370 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[FX]], 1024
371 ; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[EXIT]]
372 ; CHECK: exit:
373 ; CHECK-NEXT: ret void
374 ;
375 entry:
376 br label %loop
377
378 loop:
379 %iv = phi i32 [ 0, %entry], [ %iv.next, %latch]
380 %earlycnd = icmp ult i32 %iv, %n
381 br i1 %earlycnd, label %latch, label %exit
382
383 latch:
384 %iv.next = add i32 %iv, 1
385 %fx = shl i32 %iv, 4
386 store volatile i32 %iv, i32* @A
387 %c = icmp ult i32 %fx, 1024
388 br i1 %c, label %loop, label %exit
389
390 exit:
391 ret void
392 }
393
394
395 ; Another example where we can remove an f(i) type computation, but this
396 ; time in a loop w/o a statically computable exit count.
397 define void @simplify_exit_test2(i32 %n) {
398 ; CHECK-LABEL: @simplify_exit_test2(
399 ; CHECK-NEXT: entry:
400 ; CHECK-NEXT: br label [[LOOP:%.*]]
401 ; CHECK: loop:
402 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
403 ; CHECK-NEXT: [[VOL:%.*]] = load volatile i32, i32* @A
404 ; CHECK-NEXT: [[EARLYCND:%.*]] = icmp ne i32 [[VOL]], 0
405 ; CHECK-NEXT: br i1 [[EARLYCND]], label [[LATCH]], label [[EXIT:%.*]]
406 ; CHECK: latch:
407 ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
408 ; CHECK-NEXT: [[FX:%.*]] = udiv i32 [[IV]], 4
409 ; CHECK-NEXT: store volatile i32 [[IV]], i32* @A
410 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[FX]], 1024
411 ; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[EXIT]]
412 ; CHECK: exit:
413 ; CHECK-NEXT: ret void
414 ;
415 entry:
416 br label %loop
417
418 loop:
419 %iv = phi i32 [ 0, %entry], [ %iv.next, %latch]
420 %vol = load volatile i32, i32* @A
421 %earlycnd = icmp ne i32 %vol, 0
422 br i1 %earlycnd, label %latch, label %exit
423
424 latch:
425 %iv.next = add i32 %iv, 1
426 %fx = udiv i32 %iv, 4
427 store volatile i32 %iv, i32* @A
428 %c = icmp ult i32 %fx, 1024
429 br i1 %c, label %loop, label %exit
430
431 exit:
432 ret void
433 }