1; RUN: opt < %s -S -loop-unroll -unroll-threshold=30 | FileCheck %s 2; RUN: opt < %s -S -loop-unroll -unroll-threshold=30 -unroll-allow-peeling=false | FileCheck %s --check-prefix=DISABLE 3 4define i32 @invariant_backedge_1(i32 %a, i32 %b) { 5; CHECK-LABEL: @invariant_backedge_1 6; CHECK-NOT: %plus = phi 7; CHECK: loop.peel: 8; CHECK: loop: 9; CHECK: %i = phi 10; CHECK: %sum = phi 11; DISABLE-LABEL: @invariant_backedge_1 12; DISABLE-NOT: loop.peel: 13entry: 14 br label %loop 15 16loop: 17 %i = phi i32 [ 0, %entry ], [ %inc, %loop ] 18 %sum = phi i32 [ 0, %entry ], [ %incsum, %loop ] 19 %plus = phi i32 [ %a, %entry ], [ %b, %loop ] 20 21 %incsum = add i32 %sum, %plus 22 %inc = add i32 %i, 1 23 %cmp = icmp slt i32 %i, 1000 24 25 br i1 %cmp, label %loop, label %exit 26 27exit: 28 ret i32 %sum 29} 30 31define i32 @invariant_backedge_2(i32 %a, i32 %b) { 32; This loop should be peeled twice because it has a Phi which becomes invariant 33; starting from 3rd iteration. 34; CHECK-LABEL: @invariant_backedge_2 35; CHECK: loop.peel{{.*}}: 36; CHECK: loop.peel{{.*}}: 37; CHECK: %i = phi 38; CHECK: %sum = phi 39; CHECK-NOT: %half.inv = phi 40; CHECK-NOT: %plus = phi 41entry: 42 br label %loop 43 44loop: 45 %i = phi i32 [ 0, %entry ], [ %inc, %loop ] 46 %sum = phi i32 [ 0, %entry ], [ %incsum, %loop ] 47 %half.inv = phi i32 [ %a, %entry ], [ %b, %loop ] 48 %plus = phi i32 [ %a, %entry ], [ %half.inv, %loop ] 49 50 %incsum = add i32 %sum, %plus 51 %inc = add i32 %i, 1 52 %cmp = icmp slt i32 %i, 1000 53 54 br i1 %cmp, label %loop, label %exit 55 56exit: 57 ret i32 %sum 58} 59 60define i32 @invariant_backedge_3(i32 %a, i32 %b) { 61; This loop should be peeled thrice because it has a Phi which becomes invariant 62; starting from 4th iteration. 63; CHECK-LABEL: @invariant_backedge_3 64; CHECK: loop.peel{{.*}}: 65; CHECK: loop.peel{{.*}}: 66; CHECK: loop.peel{{.*}}: 67; CHECK: %i = phi 68; CHECK: %sum = phi 69; CHECK-NOT: %half.inv = phi 70; CHECK-NOT: %half.inv.2 = phi 71; CHECK-NOT: %plus = phi 72entry: 73 br label %loop 74 75loop: 76 %i = phi i32 [ 0, %entry ], [ %inc, %loop ] 77 %sum = phi i32 [ 0, %entry ], [ %incsum, %loop ] 78 %half.inv = phi i32 [ %a, %entry ], [ %b, %loop ] 79 %half.inv.2 = phi i32 [ %a, %entry ], [ %half.inv, %loop ] 80 %plus = phi i32 [ %a, %entry ], [ %half.inv.2, %loop ] 81 82 %incsum = add i32 %sum, %plus 83 %inc = add i32 %i, 1 84 %cmp = icmp slt i32 %i, 1000 85 86 br i1 %cmp, label %loop, label %exit 87 88exit: 89 ret i32 %sum 90} 91 92define i32 @invariant_backedge_limited_by_size(i32 %a, i32 %b) { 93; This loop should normally be peeled thrice because it has a Phi which becomes 94; invariant starting from 4th iteration, but the size of the loop only allows 95; us to peel twice because we are restricted to 30 instructions in resulting 96; code. Thus, %plus Phi node should stay in loop even despite its backedge 97; input is an invariant. 98; CHECK-LABEL: @invariant_backedge_limited_by_size 99; CHECK: loop.peel{{.*}}: 100; CHECK: loop.peel{{.*}}: 101; CHECK: %i = phi 102; CHECK: %sum = phi 103; CHECK: %plus = phi i32 [ %a, {{.*}} ], [ %b, %loop ] 104; CHECK-NOT: %half.inv = phi 105; CHECK-NOT: %half.inv.2 = phi 106entry: 107 br label %loop 108 109loop: 110 %i = phi i32 [ 0, %entry ], [ %inc, %loop ] 111 %sum = phi i32 [ 0, %entry ], [ %incsum, %loop ] 112 %half.inv = phi i32 [ %a, %entry ], [ %b, %loop ] 113 %half.inv.2 = phi i32 [ %a, %entry ], [ %half.inv, %loop ] 114 %plus = phi i32 [ %a, %entry ], [ %half.inv.2, %loop ] 115 116 %incsum = add i32 %sum, %plus 117 %inc = add i32 %i, 1 118 %cmp = icmp slt i32 %i, 1000 119 120 %incsum2 = add i32 %incsum, %plus 121 %incsum3 = add i32 %incsum, %plus 122 %incsum4 = add i32 %incsum, %plus 123 %incsum5 = add i32 %incsum, %plus 124 %incsum6 = add i32 %incsum, %plus 125 %incsum7 = add i32 %incsum, %plus 126 127 br i1 %cmp, label %loop, label %exit 128 129exit: 130 ret i32 %sum 131} 132 133; Peeling should fail due to method size. 134define i32 @invariant_backedge_negative(i32 %a, i32 %b) { 135; CHECK-LABEL: @invariant_backedge_negative 136; CHECK-NOT: loop.peel{{.*}}: 137; CHECK: loop: 138; CHECK: %i = phi 139; CHECK: %sum = phi 140; CHECK: %plus = phi 141entry: 142 br label %loop 143 144loop: 145 %i = phi i32 [ 0, %entry ], [ %inc, %loop ] 146 %sum = phi i32 [ 0, %entry ], [ %incsum2, %loop ] 147 %plus = phi i32 [ %a, %entry ], [ %b, %loop ] 148 149 %incsum = add i32 %sum, %plus 150 %incsum2 = add i32 %incsum, %plus 151 %incsum3 = add i32 %incsum, %plus 152 %incsum4 = add i32 %incsum, %plus 153 %incsum5 = add i32 %incsum, %plus 154 %incsum6 = add i32 %incsum, %plus 155 %incsum7 = add i32 %incsum, %plus 156 %incsum8 = add i32 %incsum, %plus 157 %incsum9 = add i32 %incsum, %plus 158 %incsum10 = add i32 %incsum, %plus 159 %incsum11 = add i32 %incsum, %plus 160 %incsum12 = add i32 %incsum, %plus 161 %incsum13 = add i32 %incsum, %plus 162 %incsum14 = add i32 %incsum, %plus 163 %incsum15 = add i32 %incsum, %plus 164 %inc = add i32 %i, 1 165 %cmp = icmp slt i32 %i, 1000 166 167 br i1 %cmp, label %loop, label %exit 168 169exit: 170 ret i32 %sum 171} 172 173define i32 @cycled_phis(i32 %a, i32 %b) { 174; Make sure that we do not crash working with cycled Phis and don't peel it. 175; TODO: Actually this loop should be partially unrolled with factor 2. 176; CHECK-LABEL: @cycled_phis 177; CHECK-NOT: loop.peel{{.*}}: 178; CHECK: loop: 179; CHECK: %i = phi 180; CHECK: %phi.a = phi 181; CHECK: %phi.b = phi 182; CHECK: %sum = phi 183entry: 184 br label %loop 185 186loop: 187 %i = phi i32 [ 0, %entry ], [ %inc, %loop ] 188 %phi.a = phi i32 [ %a, %entry ], [ %phi.b, %loop ] 189 %phi.b = phi i32 [ %b, %entry ], [ %phi.a, %loop ] 190 %sum = phi i32 [ 0, %entry], [ %incsum, %loop ] 191 %incsum = add i32 %sum, %phi.a 192 %inc = add i32 %i, 1 193 %cmp = icmp slt i32 %i, 1000 194 195 br i1 %cmp, label %loop, label %exit 196 197exit: 198 ret i32 %sum 199} 200