1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -loop-unroll -S < %s | FileCheck %s 3 4declare void @bar() 5 6define void @test1() { 7; CHECK-LABEL: @test1( 8; CHECK-NEXT: entry: 9; CHECK-NEXT: br label [[LOOP:%.*]] 10; CHECK: loop: 11; CHECK-NEXT: call void @bar() 12; CHECK-NEXT: br i1 true, label [[LATCH:%.*]], label [[EXIT:%.*]] 13; CHECK: latch: 14; CHECK-NEXT: call void @bar() 15; CHECK-NEXT: call void @bar() 16; CHECK-NEXT: br i1 true, label [[LATCH_1:%.*]], label [[EXIT]] 17; CHECK: exit: 18; CHECK-NEXT: ret void 19; CHECK: latch.1: 20; CHECK-NEXT: call void @bar() 21; CHECK-NEXT: call void @bar() 22; CHECK-NEXT: br i1 true, label [[LATCH_2:%.*]], label [[EXIT]] 23; CHECK: latch.2: 24; CHECK-NEXT: call void @bar() 25; CHECK-NEXT: call void @bar() 26; CHECK-NEXT: br i1 true, label [[LATCH_3:%.*]], label [[EXIT]] 27; CHECK: latch.3: 28; CHECK-NEXT: call void @bar() 29; CHECK-NEXT: call void @bar() 30; CHECK-NEXT: br i1 true, label [[LATCH_4:%.*]], label [[EXIT]] 31; CHECK: latch.4: 32; CHECK-NEXT: call void @bar() 33; CHECK-NEXT: call void @bar() 34; CHECK-NEXT: br i1 true, label [[LATCH_5:%.*]], label [[EXIT]] 35; CHECK: latch.5: 36; CHECK-NEXT: call void @bar() 37; CHECK-NEXT: call void @bar() 38; CHECK-NEXT: br i1 true, label [[LATCH_6:%.*]], label [[EXIT]] 39; CHECK: latch.6: 40; CHECK-NEXT: call void @bar() 41; CHECK-NEXT: call void @bar() 42; CHECK-NEXT: br i1 true, label [[LATCH_7:%.*]], label [[EXIT]] 43; CHECK: latch.7: 44; CHECK-NEXT: call void @bar() 45; CHECK-NEXT: call void @bar() 46; CHECK-NEXT: br i1 true, label [[LATCH_8:%.*]], label [[EXIT]] 47; CHECK: latch.8: 48; CHECK-NEXT: call void @bar() 49; CHECK-NEXT: call void @bar() 50; CHECK-NEXT: br i1 true, label [[LATCH_9:%.*]], label [[EXIT]] 51; CHECK: latch.9: 52; CHECK-NEXT: call void @bar() 53; CHECK-NEXT: call void @bar() 54; CHECK-NEXT: br i1 false, label [[LATCH_10:%.*]], label [[EXIT]] 55; CHECK: latch.10: 56; CHECK-NEXT: call void @bar() 57; CHECK-NEXT: br label [[EXIT]] 58; 59entry: 60 br label %loop 61loop: 62 %iv = phi i64 [0, %entry], [%iv.next, %latch] 63 %iv.next = add i64 %iv, 1 64 call void @bar() 65 %cmp1 = icmp ult i64 %iv, 10 66 br i1 %cmp1, label %latch, label %exit 67latch: 68 call void @bar() 69 %cmp2 = icmp ult i64 %iv, 20 70 br i1 %cmp2, label %loop, label %exit 71exit: 72 ret void 73} 74 75; TODO: We should fully unroll this by 10, leave the unrolled latch 76; tests since we don't know if %N < 10, and break the backedge. 77define void @test2(i64 %N) { 78; CHECK-LABEL: @test2( 79; CHECK-NEXT: entry: 80; CHECK-NEXT: br label [[LOOP:%.*]] 81; CHECK: loop: 82; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ] 83; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 84; CHECK-NEXT: call void @bar() 85; CHECK-NEXT: [[CMP1:%.*]] = icmp ule i64 [[IV]], 10 86; CHECK-NEXT: br i1 [[CMP1]], label [[LATCH]], label [[EXIT:%.*]] 87; CHECK: latch: 88; CHECK-NEXT: call void @bar() 89; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i64 [[IV]], [[N:%.*]] 90; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP]], label [[EXIT]] 91; CHECK: exit: 92; CHECK-NEXT: ret void 93; 94entry: 95 br label %loop 96loop: 97 %iv = phi i64 [0, %entry], [%iv.next, %latch] 98 %iv.next = add i64 %iv, 1 99 call void @bar() 100 %cmp1 = icmp ule i64 %iv, 10 101 br i1 %cmp1, label %latch, label %exit 102latch: 103 call void @bar() 104 %cmp2 = icmp ule i64 %iv, %N 105 br i1 %cmp2, label %loop, label %exit 106exit: 107 ret void 108} 109 110 111; TODO: We could partially unroll this by 2. 112define void @test3(i64 %N, i64 %M) { 113; CHECK-LABEL: @test3( 114; CHECK-NEXT: entry: 115; CHECK-NEXT: [[N_MASKED:%.*]] = and i64 [[N:%.*]], 65520 116; CHECK-NEXT: [[M_MASKED:%.*]] = and i64 [[M:%.*]], 65520 117; CHECK-NEXT: br label [[LOOP:%.*]] 118; CHECK: loop: 119; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ] 120; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 121; CHECK-NEXT: call void @bar() 122; CHECK-NEXT: [[CMP1:%.*]] = icmp ule i64 [[IV]], [[N_MASKED]] 123; CHECK-NEXT: br i1 [[CMP1]], label [[LATCH]], label [[EXIT:%.*]] 124; CHECK: latch: 125; CHECK-NEXT: call void @bar() 126; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i64 [[IV]], [[M_MASKED]] 127; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP]], label [[EXIT]] 128; CHECK: exit: 129; CHECK-NEXT: ret void 130; 131entry: 132 %N.masked = and i64 %N, 65520 ; 0xfff0 133 %M.masked = and i64 %M, 65520 ; 0xfff0 134 br label %loop 135loop: 136 %iv = phi i64 [0, %entry], [%iv.next, %latch] 137 %iv.next = add i64 %iv, 1 138 call void @bar() 139 %cmp1 = icmp ule i64 %iv, %N.masked 140 br i1 %cmp1, label %latch, label %exit 141latch: 142 call void @bar() 143 %cmp2 = icmp ule i64 %iv, %M.masked 144 br i1 %cmp2, label %loop, label %exit 145exit: 146 ret void 147} 148