| ; RUN: llc  -mcpu=corei7 -mtriple=x86_64-linux < %s | FileCheck %s | 
 |  | 
 | ; The block latch should be moved before header. | 
 | ;CHECK-LABEL: test1: | 
 | ;CHECK:       %latch | 
 | ;CHECK:       %header | 
 | ;CHECK:       %false | 
 | define i32 @test1(ptr %p) { | 
 | entry: | 
 |   br label %header | 
 |  | 
 | header: | 
 |   %x1 = phi i64 [0, %entry], [%x2, %latch] | 
 |   %count1 = phi i32 [0, %entry], [%count4, %latch] | 
 |   %0 = ptrtoint ptr %p to i64 | 
 |   %1 = add i64 %0, %x1 | 
 |   %2 = inttoptr i64 %1 to ptr | 
 |   %data = load i32, ptr %2 | 
 |   %3 = icmp eq i32 %data, 0 | 
 |   br i1 %3, label %latch, label %false | 
 |  | 
 | false: | 
 |   %count2 = add i32 %count1, 1 | 
 |   br label %latch | 
 |  | 
 | latch: | 
 |   %count4 = phi i32 [%count2, %false], [%count1, %header] | 
 |   %x2 = add i64 %x1, 1 | 
 |   %4 = icmp eq i64 %x2, 100 | 
 |   br i1 %4, label %exit, label %header | 
 |  | 
 | exit: | 
 |   ret i32 %count4 | 
 | } | 
 |  | 
 | ; The block latch and one of false/true should be moved before header. | 
 | ;CHECK-LABEL: test2: | 
 | ;CHECK:       %true | 
 | ;CHECK:       %latch | 
 | ;CHECK:       %header | 
 | ;CHECK:       %false | 
 | define i32 @test2(ptr %p) { | 
 | entry: | 
 |   br label %header | 
 |  | 
 | header: | 
 |   %x1 = phi i64 [0, %entry], [%x2, %latch] | 
 |   %count1 = phi i32 [0, %entry], [%count4, %latch] | 
 |   %0 = ptrtoint ptr %p to i64 | 
 |   %1 = add i64 %0, %x1 | 
 |   %2 = inttoptr i64 %1 to ptr | 
 |   %data = load i32, ptr %2 | 
 |   %3 = icmp eq i32 %data, 0 | 
 |   br i1 %3, label %true, label %false | 
 |  | 
 | false: | 
 |   %count2 = add i32 %count1, 1 | 
 |   br label %latch | 
 |  | 
 | true: | 
 |   %count3 = add i32 %count1, 2 | 
 |   br label %latch | 
 |  | 
 | latch: | 
 |   %count4 = phi i32 [%count2, %false], [%count3, %true] | 
 |   %x2 = add i64 %x1, 1 | 
 |   %4 = icmp eq i64 %x2, 100 | 
 |   br i1 %4, label %exit, label %header | 
 |  | 
 | exit: | 
 |   ret i32 %count4 | 
 | } | 
 |  | 
 | ; More blocks can be moved before header. | 
 | ;            header <------------ | 
 | ;              /\               | | 
 | ;             /  \              | | 
 | ;            /    \             | | 
 | ;           /      \            | | 
 | ;          /        \           | | 
 | ;        true      false        | | 
 | ;         /\         /\         | | 
 | ;        /  \       /  \        | | 
 | ;       /    \     /    \       | | 
 | ;    true3 false3 /      \      | | 
 | ;      \    /   true2  false2   | | 
 | ;       \  /      \      /      | | 
 | ;        \/        \    /       | | 
 | ;      endif3       \  /        | | 
 | ;         \          \/         | | 
 | ;          \       endif2       | | 
 | ;           \        /          | | 
 | ;            \      /           | | 
 | ;             \    /            | | 
 | ;              \  /             | | 
 | ;               \/              | | 
 | ;              latch------------- | 
 | ;                | | 
 | ;                | | 
 | ;              exit | 
 | ; | 
 | ; Blocks true3,endif3,latch should be moved before header. | 
 | ; | 
 | ;CHECK-LABEL: test3: | 
 | ;CHECK:       %true3 | 
 | ;CHECK:       %endif3 | 
 | ;CHECK:       %latch | 
 | ;CHECK:       %header | 
 | ;CHECK:       %false | 
 | define i32 @test3(ptr %p) { | 
 | entry: | 
 |   br label %header | 
 |  | 
 | header: | 
 |   %x1 = phi i64 [0, %entry], [%x2, %latch] | 
 |   %count1 = phi i32 [0, %entry], [%count12, %latch] | 
 |   %0 = ptrtoint ptr %p to i64 | 
 |   %1 = add i64 %0, %x1 | 
 |   %2 = inttoptr i64 %1 to ptr | 
 |   %data = load i32, ptr %2 | 
 |   %3 = icmp eq i32 %data, 0 | 
 |   br i1 %3, label %true, label %false, !prof !3 | 
 |  | 
 | false: | 
 |   %count2 = add i32 %count1, 1 | 
 |   %cond = icmp sgt i32 %count2, 10 | 
 |   br i1 %cond, label %true2, label %false2 | 
 |  | 
 | false2: | 
 |   %count3 = and i32 %count2, 7 | 
 |   br label %endif2 | 
 |  | 
 | true2: | 
 |   %count4 = mul i32 %count2, 3 | 
 |   br label %endif2 | 
 |  | 
 | endif2: | 
 |   %count5 = phi i32 [%count3, %false2], [%count4, %true2] | 
 |   %count6 = sub i32 %count5, 5 | 
 |   br label %latch | 
 |  | 
 | true: | 
 |   %count7 = add i32 %count1, 2 | 
 |   %cond2 = icmp slt i32 %count7, 20 | 
 |   br i1 %cond2, label %true3, label %false3 | 
 |  | 
 | false3: | 
 |   %count8 = or i32 %count7, 3 | 
 |   br label %endif3 | 
 |  | 
 | true3: | 
 |   %count9 = xor i32 %count7, 55 | 
 |   br label %endif3 | 
 |  | 
 | endif3: | 
 |   %count10 = phi i32 [%count8, %false3], [%count9, %true3] | 
 |   %count11 = add i32 %count10, 3 | 
 |   br label %latch | 
 |  | 
 | latch: | 
 |   %count12 = phi i32 [%count6, %endif2], [%count11, %endif3] | 
 |   %x2 = add i64 %x1, 1 | 
 |   %4 = icmp eq i64 %x2, 100 | 
 |   br i1 %4, label %exit, label %header | 
 |  | 
 | exit: | 
 |   ret i32 %count12 | 
 | } | 
 |  | 
 | ; The exit block has higher frequency than false block, so latch block | 
 | ; should not moved before header. | 
 | ;CHECK-LABEL: test4: | 
 | ;CHECK:       %header | 
 | ;CHECK:       %true | 
 | ;CHECK:       %latch | 
 | ;CHECK:       %false | 
 | ;CHECK:       %exit | 
 | define i32 @test4(i32 %t, ptr %p) { | 
 | entry: | 
 |   br label %header | 
 |  | 
 | header: | 
 |   %x1 = phi i64 [0, %entry], [%x2, %latch] | 
 |   %count1 = phi i32 [0, %entry], [%count4, %latch] | 
 |   %0 = ptrtoint ptr %p to i64 | 
 |   %1 = add i64 %0, %x1 | 
 |   %2 = inttoptr i64 %1 to ptr | 
 |   %data = load i32, ptr %2 | 
 |   %3 = icmp eq i32 %data, 0 | 
 |   br i1 %3, label %true, label %false, !prof !1 | 
 |  | 
 | false: | 
 |   %count2 = add i32 %count1, 1 | 
 |   br label %latch | 
 |  | 
 | true: | 
 |   %count3 = add i32 %count1, 2 | 
 |   br label %latch | 
 |  | 
 | latch: | 
 |   %count4 = phi i32 [%count2, %false], [%count3, %true] | 
 |   %x2 = add i64 %x1, 1 | 
 |   %4 = icmp eq i64 %x2, 100 | 
 |   br i1 %4, label %exit, label %header, !prof !2 | 
 |  | 
 | exit: | 
 |   ret i32 %count4 | 
 | } | 
 |  | 
 | !1 = !{!"branch_weights", i32 100, i32 1} | 
 | !2 = !{!"branch_weights", i32 16, i32 16} | 
 | !3 = !{!"branch_weights", i32 51, i32 49} | 
 |  | 
 | ; If move latch to loop top doesn't reduce taken branch, don't do it. | 
 | ;CHECK-LABEL: test5: | 
 | ;CHECK:       %entry | 
 | ;CHECK:       %header | 
 | ;CHECK:       %latch | 
 | define void @test5(ptr %p) { | 
 | entry: | 
 |   br label %header | 
 |  | 
 | header: | 
 |   %x1 = phi i64 [0, %entry], [%x1, %header], [%x2, %latch] | 
 |   %0 = ptrtoint ptr %p to i64 | 
 |   %1 = add i64 %0, %x1 | 
 |   %2 = inttoptr i64 %1 to ptr | 
 |   %data = load i32, ptr %2 | 
 |   %3 = icmp eq i32 %data, 0 | 
 |   br i1 %3, label %latch, label %header | 
 |  | 
 | latch: | 
 |   %x2 = add i64 %x1, 1 | 
 |   br label %header | 
 |  | 
 | exit: | 
 |   ret void | 
 | } | 
 |  |