1 ; RUN: llc < %s -march=x86-64 -mtriple=x86_64-unknown-linux-gnu -asm-verbose=false | FileCheck %s
3 ; These tests check for loop branching structure, and that the loop align
4 ; directive is placed in the expected place.
6 ; CodeGen should insert a branch into the middle of the loop in
7 ; order to avoid a branch within the loop.
12 ; CHECK-NEXT: .LBB0_2:
13 ; CHECK-NEXT: callq loop_latch
14 ; CHECK-NEXT: .LBB0_1:
15 ; CHECK-NEXT: callq loop_header
17 define void @simple() nounwind {
22 call void @loop_header()
23 %t0 = tail call i32 @get()
24 %t1 = icmp slt i32 %t0, 0
25 br i1 %t1, label %done, label %bb
28 call void @loop_latch()
36 ; CodeGen should move block_a to the top of the loop so that it
37 ; falls through into the loop, avoiding a branch within the loop.
39 ; CHECK: slightly_more_involved:
42 ; CHECK-NEXT: .LBB1_4:
43 ; CHECK-NEXT: callq bar99
45 ; CHECK-NEXT: .LBB1_1:
46 ; CHECK-NEXT: callq body
48 define void @slightly_more_involved() nounwind {
55 %t1 = icmp slt i32 %t0, 2
56 br i1 %t1, label %block_a, label %bb
60 %t3 = icmp slt i32 %t2, 99
61 br i1 %t3, label %exit, label %loop
72 ; Same as slightly_more_involved, but block_a is now a CFG diamond with
73 ; fallthrough edges which should be preserved.
74 ; "callq block_a_merge_func" is tail duped.
76 ; CHECK: yet_more_involved:
79 ; CHECK-NEXT: .LBB2_5:
80 ; CHECK-NEXT: callq block_a_true_func
81 ; CHECK-NEXT: callq block_a_merge_func
83 ; CHECK-NEXT: .LBB2_1:
84 ; CHECK-NEXT: callq body
88 ; CHECK-NEXT: callq get
89 ; CHECK-NEXT: cmpl $2999, %eax
90 ; CHECK-NEXT: jle .LBB2_5
91 ; CHECK-NEXT: callq block_a_false_func
92 ; CHECK-NEXT: callq block_a_merge_func
93 ; CHECK-NEXT: jmp .LBB2_1
95 define void @yet_more_involved() nounwind {
101 %t0 = call i32 @get()
102 %t1 = icmp slt i32 %t0, 2
103 br i1 %t1, label %block_a, label %bb
106 %t2 = call i32 @get()
107 %t3 = icmp slt i32 %t2, 99
108 br i1 %t3, label %exit, label %loop
112 %z0 = call i32 @get()
113 %z1 = icmp slt i32 %z0, 3000
114 br i1 %z1, label %block_a_true, label %block_a_false
117 call void @block_a_true_func()
118 br label %block_a_merge
121 call void @block_a_false_func()
122 br label %block_a_merge
125 call void @block_a_merge_func()
133 ; CodeGen should move the CFG islands that are part of the loop but don't
134 ; conveniently fit anywhere so that they are at least contiguous with the
137 ; CHECK: cfg_islands:
140 ; CHECK-NEXT: .LBB3_7:
141 ; CHECK-NEXT: callq bar100
143 ; CHECK-NEXT: .LBB3_1:
144 ; CHECK-NEXT: callq loop_header
147 ; CHECK-NEXT: callq bar101
148 ; CHECK-NEXT: jmp .LBB3_1
149 ; CHECK-NEXT: .LBB3_3:
151 ; CHECK-NEXT: callq bar102
152 ; CHECK-NEXT: jmp .LBB3_1
153 ; CHECK-NEXT: .LBB3_4:
155 ; CHECK-NEXT: callq loop_latch
156 ; CHECK-NEXT: jmp .LBB3_1
157 ; CHECK-NEXT: .LBB3_6:
159 define void @cfg_islands() nounwind {
164 call void @loop_header()
165 %t0 = call i32 @get()
166 %t1 = icmp slt i32 %t0, 100
167 br i1 %t1, label %block100, label %bb
170 %t2 = call i32 @get()
171 %t3 = icmp slt i32 %t2, 101
172 br i1 %t3, label %block101, label %bb1
175 %t4 = call i32 @get()
176 %t5 = icmp slt i32 %t4, 102
177 br i1 %t5, label %block102, label %bb2
180 %t6 = call i32 @get()
181 %t7 = icmp slt i32 %t6, 103
182 br i1 %t7, label %exit, label %bb3
185 call void @loop_latch()
205 declare void @bar99() nounwind
206 declare void @bar100() nounwind
207 declare void @bar101() nounwind
208 declare void @bar102() nounwind
209 declare void @body() nounwind
210 declare void @exit() nounwind
211 declare void @loop_header() nounwind
212 declare void @loop_latch() nounwind
213 declare i32 @get() nounwind
214 declare void @block_a_true_func() nounwind
215 declare void @block_a_false_func() nounwind
216 declare void @block_a_merge_func() nounwind