240 lines · plain
1; RUN: llc -mcpu=corei7 -mtriple=x86_64-linux < %s | FileCheck %s2 3; The block latch should be moved before header.4;CHECK-LABEL: test1:5;CHECK: %latch6;CHECK: %header7;CHECK: %false8define i32 @test1(ptr %p) {9entry:10 br label %header11 12header:13 %x1 = phi i64 [0, %entry], [%x2, %latch]14 %count1 = phi i32 [0, %entry], [%count4, %latch]15 %0 = ptrtoint ptr %p to i6416 %1 = add i64 %0, %x117 %2 = inttoptr i64 %1 to ptr18 %data = load i32, ptr %219 %3 = icmp eq i32 %data, 020 br i1 %3, label %latch, label %false21 22false:23 %count2 = add i32 %count1, 124 br label %latch25 26latch:27 %count4 = phi i32 [%count2, %false], [%count1, %header]28 %x2 = add i64 %x1, 129 %4 = icmp eq i64 %x2, 10030 br i1 %4, label %exit, label %header31 32exit:33 ret i32 %count434}35 36; The block latch and one of false/true should be moved before header.37;CHECK-LABEL: test2:38;CHECK: %true39;CHECK: %latch40;CHECK: %header41;CHECK: %false42define i32 @test2(ptr %p) {43entry:44 br label %header45 46header:47 %x1 = phi i64 [0, %entry], [%x2, %latch]48 %count1 = phi i32 [0, %entry], [%count4, %latch]49 %0 = ptrtoint ptr %p to i6450 %1 = add i64 %0, %x151 %2 = inttoptr i64 %1 to ptr52 %data = load i32, ptr %253 %3 = icmp eq i32 %data, 054 br i1 %3, label %true, label %false55 56false:57 %count2 = add i32 %count1, 158 br label %latch59 60true:61 %count3 = add i32 %count1, 262 br label %latch63 64latch:65 %count4 = phi i32 [%count2, %false], [%count3, %true]66 %x2 = add i64 %x1, 167 %4 = icmp eq i64 %x2, 10068 br i1 %4, label %exit, label %header69 70exit:71 ret i32 %count472}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; exit101;102; Blocks true3,endif3,latch should be moved before header.103;104;CHECK-LABEL: test3:105;CHECK: %true3106;CHECK: %endif3107;CHECK: %latch108;CHECK: %header109;CHECK: %false110define i32 @test3(ptr %p) {111entry:112 br label %header113 114header:115 %x1 = phi i64 [0, %entry], [%x2, %latch]116 %count1 = phi i32 [0, %entry], [%count12, %latch]117 %0 = ptrtoint ptr %p to i64118 %1 = add i64 %0, %x1119 %2 = inttoptr i64 %1 to ptr120 %data = load i32, ptr %2121 %3 = icmp eq i32 %data, 0122 br i1 %3, label %true, label %false, !prof !3123 124false:125 %count2 = add i32 %count1, 1126 %cond = icmp sgt i32 %count2, 10127 br i1 %cond, label %true2, label %false2128 129false2:130 %count3 = and i32 %count2, 7131 br label %endif2132 133true2:134 %count4 = mul i32 %count2, 3135 br label %endif2136 137endif2:138 %count5 = phi i32 [%count3, %false2], [%count4, %true2]139 %count6 = sub i32 %count5, 5140 br label %latch141 142true:143 %count7 = add i32 %count1, 2144 %cond2 = icmp slt i32 %count7, 20145 br i1 %cond2, label %true3, label %false3146 147false3:148 %count8 = or i32 %count7, 3149 br label %endif3150 151true3:152 %count9 = xor i32 %count7, 55153 br label %endif3154 155endif3:156 %count10 = phi i32 [%count8, %false3], [%count9, %true3]157 %count11 = add i32 %count10, 3158 br label %latch159 160latch:161 %count12 = phi i32 [%count6, %endif2], [%count11, %endif3]162 %x2 = add i64 %x1, 1163 %4 = icmp eq i64 %x2, 100164 br i1 %4, label %exit, label %header165 166exit:167 ret i32 %count12168}169 170; The exit block has higher frequency than false block, so latch block171; should not moved before header.172;CHECK-LABEL: test4:173;CHECK: %header174;CHECK: %true175;CHECK: %latch176;CHECK: %false177;CHECK: %exit178define i32 @test4(i32 %t, ptr %p) {179entry:180 br label %header181 182header:183 %x1 = phi i64 [0, %entry], [%x2, %latch]184 %count1 = phi i32 [0, %entry], [%count4, %latch]185 %0 = ptrtoint ptr %p to i64186 %1 = add i64 %0, %x1187 %2 = inttoptr i64 %1 to ptr188 %data = load i32, ptr %2189 %3 = icmp eq i32 %data, 0190 br i1 %3, label %true, label %false, !prof !1191 192false:193 %count2 = add i32 %count1, 1194 br label %latch195 196true:197 %count3 = add i32 %count1, 2198 br label %latch199 200latch:201 %count4 = phi i32 [%count2, %false], [%count3, %true]202 %x2 = add i64 %x1, 1203 %4 = icmp eq i64 %x2, 100204 br i1 %4, label %exit, label %header, !prof !2205 206exit:207 ret i32 %count4208}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: %entry217;CHECK: %header218;CHECK: %latch219define void @test5(ptr %p) {220entry:221 br label %header222 223header:224 %x1 = phi i64 [0, %entry], [%x1, %header], [%x2, %latch]225 %0 = ptrtoint ptr %p to i64226 %1 = add i64 %0, %x1227 %2 = inttoptr i64 %1 to ptr228 %data = load i32, ptr %2229 %3 = icmp eq i32 %data, 0230 br i1 %3, label %latch, label %header231 232latch:233 %x2 = add i64 %x1, 1234 br label %header235 236exit:237 ret void238}239 240