11; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
22; RUN: opt < %s -S -passes='loop(indvars),loop-unroll' -verify-loop-info | FileCheck %s
33;
4+ target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
5+
46; Unit tests for loop unrolling using ScalarEvolution to compute trip counts.
57;
68; Indvars is run first to generate an "old" SCEV result. Some unit
@@ -66,30 +68,30 @@ define i64 @earlyLoopTest(ptr %base) nounwind {
6668; CHECK-NEXT: entry:
6769; CHECK-NEXT: br label [[LOOP:%.*]]
6870; CHECK: loop:
69- ; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[BASE:%.*]], align 4
71+ ; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[BASE:%.*]], align 8
7072; CHECK-NEXT: br label [[TAIL:%.*]]
7173; CHECK: tail:
7274; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i64 [[VAL]], 0
7375; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP_1:%.*]], label [[EXIT2:%.*]]
7476; CHECK: loop.1:
7577; CHECK-NEXT: [[ADR_1:%.*]] = getelementptr i64, ptr [[BASE]], i64 1
76- ; CHECK-NEXT: [[VAL_1:%.*]] = load i64, ptr [[ADR_1]], align 4
78+ ; CHECK-NEXT: [[VAL_1:%.*]] = load i64, ptr [[ADR_1]], align 8
7779; CHECK-NEXT: [[S_NEXT_1:%.*]] = add i64 [[VAL]], [[VAL_1]]
7880; CHECK-NEXT: br label [[TAIL_1:%.*]]
7981; CHECK: tail.1:
8082; CHECK-NEXT: [[CMP2_1:%.*]] = icmp ne i64 [[VAL_1]], 0
8183; CHECK-NEXT: br i1 [[CMP2_1]], label [[LOOP_2:%.*]], label [[EXIT2]]
8284; CHECK: loop.2:
8385; CHECK-NEXT: [[ADR_2:%.*]] = getelementptr i64, ptr [[BASE]], i64 2
84- ; CHECK-NEXT: [[VAL_2:%.*]] = load i64, ptr [[ADR_2]], align 4
86+ ; CHECK-NEXT: [[VAL_2:%.*]] = load i64, ptr [[ADR_2]], align 8
8587; CHECK-NEXT: [[S_NEXT_2:%.*]] = add i64 [[S_NEXT_1]], [[VAL_2]]
8688; CHECK-NEXT: br label [[TAIL_2:%.*]]
8789; CHECK: tail.2:
8890; CHECK-NEXT: [[CMP2_2:%.*]] = icmp ne i64 [[VAL_2]], 0
8991; CHECK-NEXT: br i1 [[CMP2_2]], label [[LOOP_3:%.*]], label [[EXIT2]]
9092; CHECK: loop.3:
9193; CHECK-NEXT: [[ADR_3:%.*]] = getelementptr i64, ptr [[BASE]], i64 3
92- ; CHECK-NEXT: [[VAL_3:%.*]] = load i64, ptr [[ADR_3]], align 4
94+ ; CHECK-NEXT: [[VAL_3:%.*]] = load i64, ptr [[ADR_3]], align 8
9395; CHECK-NEXT: [[S_NEXT_3:%.*]] = add i64 [[S_NEXT_2]], [[VAL_3]]
9496; CHECK-NEXT: br i1 false, label [[TAIL_3:%.*]], label [[EXIT1:%.*]]
9597; CHECK: tail.3:
@@ -381,7 +383,7 @@ define i32 @test_pr56044(ptr %src, i32 %a) {
381383; CHECK: loop.2.peel:
382384; CHECK-NEXT: [[IV_2_NEXT_PEEL:%.*]] = add i32 0, [[ADD_2]]
383385; CHECK-NEXT: [[IV_1_NEXT_PEEL:%.*]] = add nuw nsw i32 0, 1
384- ; CHECK-NEXT: [[EC_2_PEEL:%.*]] = icmp ult i32 [[IV_1_NEXT_PEEL]], 12345
386+ ; CHECK-NEXT: [[EC_2_PEEL:%.*]] = icmp ne i32 [[IV_1_NEXT_PEEL]], 12345
385387; CHECK-NEXT: br i1 [[EC_2_PEEL]], label [[LOOP_2_PEEL_NEXT:%.*]], label [[EXIT:%.*]]
386388; CHECK: loop.2.peel.next:
387389; CHECK-NEXT: br label [[LOOP_2_PEEL_NEXT2:%.*]]
@@ -394,8 +396,8 @@ define i32 @test_pr56044(ptr %src, i32 %a) {
394396; CHECK-NEXT: [[IV_2:%.*]] = phi i32 [ [[IV_2_NEXT_PEEL]], [[MID_PEEL_NEWPH]] ], [ [[IV_2_NEXT:%.*]], [[LOOP_2]] ]
395397; CHECK-NEXT: [[IV_2_NEXT]] = add i32 2, [[IV_2]]
396398; CHECK-NEXT: [[IV_1_NEXT]] = add nuw nsw i32 [[IV_1]], 1
397- ; CHECK-NEXT: [[EC_2 :%.*]] = icmp ult i32 [[IV_1_NEXT]], 12345
398- ; CHECK-NEXT: br i1 [[EC_2 ]], label [[LOOP_2]], label [[EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP2:![0-9]+]]
399+ ; CHECK-NEXT: [[EXITCOND :%.*]] = icmp ne i32 [[IV_1_NEXT]], 12345
400+ ; CHECK-NEXT: br i1 [[EXITCOND ]], label [[LOOP_2]], label [[EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP2:![0-9]+]]
399401; CHECK: exit.loopexit:
400402; CHECK-NEXT: [[LCSSA_2_PH:%.*]] = phi i32 [ [[IV_2_NEXT]], [[LOOP_2]] ]
401403; CHECK-NEXT: br label [[EXIT]]
@@ -435,3 +437,65 @@ exit:
435437}
436438
437439declare void @fn (i32 )
440+
441+
442+ define void @peel_int_eq_condition (i32 %start ) {
443+ ; CHECK-LABEL: @peel_int_eq_condition(
444+ ; CHECK-NEXT: entry:
445+ ; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[START:%.*]], i32 100)
446+ ; CHECK-NEXT: [[TMP0:%.*]] = add nuw i32 [[SMAX]], 1
447+ ; CHECK-NEXT: br label [[LOOP_PEEL_BEGIN:%.*]]
448+ ; CHECK: loop.peel.begin:
449+ ; CHECK-NEXT: br label [[LOOP_PEEL:%.*]]
450+ ; CHECK: loop.peel:
451+ ; CHECK-NEXT: [[C_0_PEEL:%.*]] = icmp eq i32 [[START]], [[START]]
452+ ; CHECK-NEXT: br i1 [[C_0_PEEL]], label [[IF_THEN_PEEL:%.*]], label [[LOOP_LATCH_PEEL:%.*]]
453+ ; CHECK: if.then.peel:
454+ ; CHECK-NEXT: call void @fn(i32 [[START]])
455+ ; CHECK-NEXT: br label [[LOOP_LATCH_PEEL]]
456+ ; CHECK: loop.latch.peel:
457+ ; CHECK-NEXT: [[IV_NEXT_PEEL:%.*]] = add i32 [[START]], 1
458+ ; CHECK-NEXT: [[EXITCOND_PEEL:%.*]] = icmp ne i32 [[IV_NEXT_PEEL]], [[TMP0]]
459+ ; CHECK-NEXT: br i1 [[EXITCOND_PEEL]], label [[LOOP_PEEL_NEXT:%.*]], label [[EXIT:%.*]]
460+ ; CHECK: loop.peel.next:
461+ ; CHECK-NEXT: br label [[LOOP_PEEL_NEXT1:%.*]]
462+ ; CHECK: loop.peel.next1:
463+ ; CHECK-NEXT: br label [[ENTRY_PEEL_NEWPH:%.*]]
464+ ; CHECK: entry.peel.newph:
465+ ; CHECK-NEXT: br label [[LOOP:%.*]]
466+ ; CHECK: loop:
467+ ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT_PEEL]], [[ENTRY_PEEL_NEWPH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
468+ ; CHECK-NEXT: [[C_0:%.*]] = icmp eq i32 [[IV]], [[START]]
469+ ; CHECK-NEXT: br i1 [[C_0]], label [[IF_THEN:%.*]], label [[LOOP_LATCH]]
470+ ; CHECK: if.then:
471+ ; CHECK-NEXT: call void @fn(i32 [[IV]])
472+ ; CHECK-NEXT: br label [[LOOP_LATCH]]
473+ ; CHECK: loop.latch:
474+ ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
475+ ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV_NEXT]], [[TMP0]]
476+ ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP3:![0-9]+]]
477+ ; CHECK: exit.loopexit:
478+ ; CHECK-NEXT: br label [[EXIT]]
479+ ; CHECK: exit:
480+ ; CHECK-NEXT: ret void
481+ ;
482+ entry:
483+ br label %loop
484+
485+ loop:
486+ %iv = phi i32 [ %start , %entry ], [ %iv.next , %loop.latch ]
487+ %c.0 = icmp eq i32 %iv , %start
488+ br i1 %c.0 , label %if.then , label %loop.latch
489+
490+ if.then:
491+ call void @fn (i32 %iv )
492+ br label %loop.latch
493+
494+ loop.latch:
495+ %iv.next = add i32 %iv , 1
496+ %ec = icmp slt i32 %iv , 100
497+ br i1 %ec , label %loop , label %exit
498+
499+ exit:
500+ ret void
501+ }
0 commit comments