1; RUN: llc -mcpu=corei7 -mtriple=x86_64-linux < %s | FileCheck %s 2 3; The block latch should be moved before header. 4;CHECK-LABEL: test1: 5;CHECK: %latch 6;CHECK: %header 7;CHECK: %false 8define i32 @test1(ptr %p) { 9entry: 10 br label %header 11 12header: 13 %x1 = phi i64 [0, %entry], [%x2, %latch] 14 %count1 = phi i32 [0, %entry], [%count4, %latch] 15 %0 = ptrtoint ptr %p to i64 16 %1 = add i64 %0, %x1 17 %2 = inttoptr i64 %1 to ptr 18 %data = load i32, ptr %2 19 %3 = icmp eq i32 %data, 0 20 br i1 %3, label %latch, label %false 21 22false: 23 %count2 = add i32 %count1, 1 24 br label %latch 25 26latch: 27 %count4 = phi i32 [%count2, %false], [%count1, %header] 28 %x2 = add i64 %x1, 1 29 %4 = icmp eq i64 %x2, 100 30 br i1 %4, label %exit, label %header 31 32exit: 33 ret i32 %count4 34} 35 36; The block latch and one of false/true should be moved before header. 37;CHECK-LABEL: test2: 38;CHECK: %true 39;CHECK: %latch 40;CHECK: %header 41;CHECK: %false 42define i32 @test2(ptr %p) { 43entry: 44 br label %header 45 46header: 47 %x1 = phi i64 [0, %entry], [%x2, %latch] 48 %count1 = phi i32 [0, %entry], [%count4, %latch] 49 %0 = ptrtoint ptr %p to i64 50 %1 = add i64 %0, %x1 51 %2 = inttoptr i64 %1 to ptr 52 %data = load i32, ptr %2 53 %3 = icmp eq i32 %data, 0 54 br i1 %3, label %true, label %false 55 56false: 57 %count2 = add i32 %count1, 1 58 br label %latch 59 60true: 61 %count3 = add i32 %count1, 2 62 br label %latch 63 64latch: 65 %count4 = phi i32 [%count2, %false], [%count3, %true] 66 %x2 = add i64 %x1, 1 67 %4 = icmp eq i64 %x2, 100 68 br i1 %4, label %exit, label %header 69 70exit: 71 ret i32 %count4 72} 73 74; More blocks can be moved before header. 75; header <------------ 76; /\ | 77; / \ | 78; / \ | 79; / \ | 80; / \ | 81; true false | 82; /\ /\ | 83; / \ / \ | 84; / \ / \ | 85; true3 false3 / \ | 86; \ / true2 false2 | 87; \ / \ / | 88; \/ \ / | 89; endif3 \ / | 90; \ \/ | 91; \ endif2 | 92; \ / | 93; \ / | 94; \ / | 95; \ / | 96; \/ | 97; latch------------- 98; | 99; | 100; exit 101; 102; Blocks true3,endif3,latch should be moved before header. 103; 104;CHECK-LABEL: test3: 105;CHECK: %true3 106;CHECK: %endif3 107;CHECK: %latch 108;CHECK: %header 109;CHECK: %false 110define i32 @test3(ptr %p) { 111entry: 112 br label %header 113 114header: 115 %x1 = phi i64 [0, %entry], [%x2, %latch] 116 %count1 = phi i32 [0, %entry], [%count12, %latch] 117 %0 = ptrtoint ptr %p to i64 118 %1 = add i64 %0, %x1 119 %2 = inttoptr i64 %1 to ptr 120 %data = load i32, ptr %2 121 %3 = icmp eq i32 %data, 0 122 br i1 %3, label %true, label %false, !prof !3 123 124false: 125 %count2 = add i32 %count1, 1 126 %cond = icmp sgt i32 %count2, 10 127 br i1 %cond, label %true2, label %false2 128 129false2: 130 %count3 = and i32 %count2, 7 131 br label %endif2 132 133true2: 134 %count4 = mul i32 %count2, 3 135 br label %endif2 136 137endif2: 138 %count5 = phi i32 [%count3, %false2], [%count4, %true2] 139 %count6 = sub i32 %count5, 5 140 br label %latch 141 142true: 143 %count7 = add i32 %count1, 2 144 %cond2 = icmp slt i32 %count7, 20 145 br i1 %cond2, label %true3, label %false3 146 147false3: 148 %count8 = or i32 %count7, 3 149 br label %endif3 150 151true3: 152 %count9 = xor i32 %count7, 55 153 br label %endif3 154 155endif3: 156 %count10 = phi i32 [%count8, %false3], [%count9, %true3] 157 %count11 = add i32 %count10, 3 158 br label %latch 159 160latch: 161 %count12 = phi i32 [%count6, %endif2], [%count11, %endif3] 162 %x2 = add i64 %x1, 1 163 %4 = icmp eq i64 %x2, 100 164 br i1 %4, label %exit, label %header 165 166exit: 167 ret i32 %count12 168} 169 170; The exit block has higher frequency than false block, so latch block 171; should not moved before header. 172;CHECK-LABEL: test4: 173;CHECK: %header 174;CHECK: %true 175;CHECK: %latch 176;CHECK: %false 177;CHECK: %exit 178define i32 @test4(i32 %t, ptr %p) { 179entry: 180 br label %header 181 182header: 183 %x1 = phi i64 [0, %entry], [%x2, %latch] 184 %count1 = phi i32 [0, %entry], [%count4, %latch] 185 %0 = ptrtoint ptr %p to i64 186 %1 = add i64 %0, %x1 187 %2 = inttoptr i64 %1 to ptr 188 %data = load i32, ptr %2 189 %3 = icmp eq i32 %data, 0 190 br i1 %3, label %true, label %false, !prof !1 191 192false: 193 %count2 = add i32 %count1, 1 194 br label %latch 195 196true: 197 %count3 = add i32 %count1, 2 198 br label %latch 199 200latch: 201 %count4 = phi i32 [%count2, %false], [%count3, %true] 202 %x2 = add i64 %x1, 1 203 %4 = icmp eq i64 %x2, 100 204 br i1 %4, label %exit, label %header, !prof !2 205 206exit: 207 ret i32 %count4 208} 209 210!1 = !{!"branch_weights", i32 100, i32 1} 211!2 = !{!"branch_weights", i32 16, i32 16} 212!3 = !{!"branch_weights", i32 51, i32 49} 213 214; If move latch to loop top doesn't reduce taken branch, don't do it. 215;CHECK-LABEL: test5: 216;CHECK: %entry 217;CHECK: %header 218;CHECK: %latch 219define void @test5(ptr %p) { 220entry: 221 br label %header 222 223header: 224 %x1 = phi i64 [0, %entry], [%x1, %header], [%x2, %latch] 225 %0 = ptrtoint ptr %p to i64 226 %1 = add i64 %0, %x1 227 %2 = inttoptr i64 %1 to ptr 228 %data = load i32, ptr %2 229 %3 = icmp eq i32 %data, 0 230 br i1 %3, label %latch, label %header 231 232latch: 233 %x2 = add i64 %x1, 1 234 br label %header 235 236exit: 237 ret void 238} 239 240