| ; RUN: llc -mtriple=i686-linux < %s | FileCheck %s | |
| ; Don't rotate the loop if the number of fall through to exit is not larger | |
| ; than the number of fall through to header. | |
| define void @no_rotate() { | |
| ; CHECK-LABEL: no_rotate | |
| ; CHECK: %entry | |
| ; CHECK: %header | |
| ; CHECK: %middle | |
| ; CHECK: %latch1 | |
| ; CHECK: %latch2 | |
| ; CHECK: %end | |
| entry: | |
| br label %header | |
| header: | |
| %val1 = call i1 @foo() | |
| br i1 %val1, label %middle, label %end | |
| middle: | |
| %val2 = call i1 @foo() | |
| br i1 %val2, label %latch1, label %end | |
| latch1: | |
| %val3 = call i1 @foo() | |
| br i1 %val3, label %latch2, label %header | |
| latch2: | |
| %val4 = call i1 @foo() | |
| br label %header | |
| end: | |
| ret void | |
| } | |
| define void @do_rotate() { | |
| ; CHECK-LABEL: do_rotate | |
| ; CHECK: %entry | |
| ; CHECK: %then | |
| ; CHECK: %else | |
| ; CHECK: %latch1 | |
| ; CHECK: %latch2 | |
| ; CHECK: %header | |
| ; CHECK: %end | |
| entry: | |
| %val0 = call i1 @foo() | |
| br i1 %val0, label %then, label %else | |
| then: | |
| call void @a() | |
| br label %header | |
| else: | |
| call void @b() | |
| br label %header | |
| header: | |
| %val1 = call i1 @foo() | |
| br i1 %val1, label %latch1, label %end | |
| latch1: | |
| %val3 = call i1 @foo() | |
| br i1 %val3, label %latch2, label %header | |
| latch2: | |
| %val4 = call i1 @foo() | |
| br label %header | |
| end: | |
| ret void | |
| } | |
| ; The loop structure is same as in @no_rotate, but the loop header's predecessor | |
| ; doesn't fall through to it, so it should be rotated to get exit fall through. | |
| define void @do_rotate2() { | |
| ; CHECK-LABEL: do_rotate2 | |
| ; CHECK: %entry | |
| ; CHECK: %then | |
| ; CHECK: %middle | |
| ; CHECK: %latch1 | |
| ; CHECK: %latch2 | |
| ; CHECK: %header | |
| ; CHECK: %exit | |
| entry: | |
| %val0 = call i1 @foo() | |
| br i1 %val0, label %then, label %header, !prof !1 | |
| then: | |
| call void @a() | |
| br label %end | |
| header: | |
| %val1 = call i1 @foo() | |
| br i1 %val1, label %middle, label %exit | |
| middle: | |
| %val2 = call i1 @foo() | |
| br i1 %val2, label %latch1, label %exit | |
| latch1: | |
| %val3 = call i1 @foo() | |
| br i1 %val3, label %latch2, label %header | |
| latch2: | |
| %val4 = call i1 @foo() | |
| br label %header | |
| exit: | |
| call void @b() | |
| br label %end | |
| end: | |
| ret void | |
| } | |
| declare i1 @foo() | |
| declare void @a() | |
| declare void @b() | |
| !1 = !{!"branch_weights", i32 10, i32 1} |