1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -indvars -S < %s | FileCheck %s 3; RUN: opt -passes=indvars -S < %s | FileCheck %s 4 5declare i1 @cond() 6 7define i32 @test_01(i32* %p, i32* %s) { 8; CHECK-LABEL: @test_01( 9; CHECK-NEXT: entry: 10; CHECK-NEXT: [[START:%.*]] = load i32, i32* [[P:%.*]], align 4, !range [[RNG0:![0-9]+]] 11; CHECK-NEXT: [[END:%.*]] = load i32, i32* [[S:%.*]], align 4, !range [[RNG0]] 12; CHECK-NEXT: br label [[LOOP:%.*]] 13; CHECK: loop: 14; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[START]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] 15; CHECK-NEXT: [[C1:%.*]] = icmp slt i32 [[IV]], [[END]] 16; CHECK-NEXT: br i1 [[C1]], label [[GUARDED:%.*]], label [[SIDE_EXIT:%.*]] 17; CHECK: guarded: 18; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[SIDE_EXIT]] 19; CHECK: backedge: 20; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 21; CHECK-NEXT: [[LOOP_COND:%.*]] = call i1 @cond() 22; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]] 23; CHECK: exit: 24; CHECK-NEXT: ret i32 1 25; CHECK: side_exit: 26; CHECK-NEXT: ret i32 0 27; 28entry: 29 %start = load i32, i32* %p, !range !0 30 %end = load i32, i32* %s, !range !0 31 br label %loop 32 33loop: 34 %iv = phi i32 [%start, %entry], [%iv.next, %backedge] 35 %c1 = icmp slt i32 %iv, %end 36 br i1 %c1, label %guarded, label %side_exit 37 38guarded: 39 %c2 = icmp ult i32 %iv, %end 40 br i1 %c2, label %backedge, label %side_exit 41 42backedge: 43 %iv.next = add nuw nsw i32 %iv, 1 44 %loop.cond = call i1 @cond() 45 br i1 %loop.cond, label %loop, label %exit 46 47exit: 48 ret i32 1 49 50side_exit: 51 ret i32 0 52} 53 54define i32 @test_02(i32* %p, i32* %s) { 55; CHECK-LABEL: @test_02( 56; CHECK-NEXT: entry: 57; CHECK-NEXT: [[START:%.*]] = load i32, i32* [[P:%.*]], align 4, !range [[RNG0]] 58; CHECK-NEXT: [[END:%.*]] = load i32, i32* [[S:%.*]], align 4, !range [[RNG0]] 59; CHECK-NEXT: br label [[LOOP:%.*]] 60; CHECK: loop: 61; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[START]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] 62; CHECK-NEXT: [[C1:%.*]] = icmp ult i32 [[IV]], [[END]] 63; CHECK-NEXT: br i1 [[C1]], label [[GUARDED:%.*]], label [[SIDE_EXIT:%.*]] 64; CHECK: guarded: 65; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[SIDE_EXIT]] 66; CHECK: backedge: 67; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 68; CHECK-NEXT: [[LOOP_COND:%.*]] = call i1 @cond() 69; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]] 70; CHECK: exit: 71; CHECK-NEXT: ret i32 1 72; CHECK: side_exit: 73; CHECK-NEXT: ret i32 0 74; 75entry: 76 %start = load i32, i32* %p, !range !0 77 %end = load i32, i32* %s, !range !0 78 br label %loop 79 80loop: 81 %iv = phi i32 [%start, %entry], [%iv.next, %backedge] 82 %c1 = icmp ult i32 %iv, %end 83 br i1 %c1, label %guarded, label %side_exit 84 85guarded: 86 %c2 = icmp slt i32 %iv, %end 87 br i1 %c2, label %backedge, label %side_exit 88 89backedge: 90 %iv.next = add nuw nsw i32 %iv, 1 91 %loop.cond = call i1 @cond() 92 br i1 %loop.cond, label %loop, label %exit 93 94exit: 95 ret i32 1 96 97side_exit: 98 ret i32 0 99} 100 101!0 = !{i32 -1000, i32 0} 102