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: .LBB1_2:
13
; CHECK-NEXT: callq loop_latch
14
; CHECK-NEXT: .LBB1_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: .LBB2_4:
43
; CHECK-NEXT: callq bar99
44
; CHECK-NEXT: .LBB2_1:
45
; CHECK-NEXT: callq body
47
define void @slightly_more_involved() nounwind {
54
%t1 = icmp slt i32 %t0, 2
55
br i1 %t1, label %block_a, label %bb
59
%t3 = icmp slt i32 %t2, 99
60
br i1 %t3, label %exit, label %loop
71
; Same as slightly_more_involved, but block_a is now a CFG diamond with
72
; fallthrough edges which should be preserved.
74
; CHECK: yet_more_involved:
77
; CHECK-NEXT: .LBB3_4:
78
; CHECK-NEXT: callq bar99
79
; CHECK-NEXT: callq get
80
; CHECK-NEXT: cmpl $2999, %eax
81
; CHECK-NEXT: jg .LBB3_6
82
; CHECK-NEXT: callq block_a_true_func
83
; CHECK-NEXT: jmp .LBB3_7
84
; CHECK-NEXT: .LBB3_6:
85
; CHECK-NEXT: callq block_a_false_func
86
; CHECK-NEXT: .LBB3_7:
87
; CHECK-NEXT: callq block_a_merge_func
88
; CHECK-NEXT: .LBB3_1:
89
; CHECK-NEXT: callq body
91
define void @yet_more_involved() nounwind {
98
%t1 = icmp slt i32 %t0, 2
99
br i1 %t1, label %block_a, label %bb
102
%t2 = call i32 @get()
103
%t3 = icmp slt i32 %t2, 99
104
br i1 %t3, label %exit, label %loop
108
%z0 = call i32 @get()
109
%z1 = icmp slt i32 %z0, 3000
110
br i1 %z1, label %block_a_true, label %block_a_false
113
call void @block_a_true_func()
114
br label %block_a_merge
117
call void @block_a_false_func()
118
br label %block_a_merge
121
call void @block_a_merge_func()
129
; CodeGen should move the CFG islands that are part of the loop but don't
130
; conveniently fit anywhere so that they are at least contiguous with the
133
; CHECK: cfg_islands:
136
; CHECK-NEXT: .LBB4_7:
137
; CHECK-NEXT: callq bar100
138
; CHECK-NEXT: jmp .LBB4_1
139
; CHECK-NEXT: .LBB4_8:
140
; CHECK-NEXT: callq bar101
141
; CHECK-NEXT: jmp .LBB4_1
142
; CHECK-NEXT: .LBB4_9:
143
; CHECK-NEXT: callq bar102
144
; CHECK-NEXT: jmp .LBB4_1
145
; CHECK-NEXT: .LBB4_5:
146
; CHECK-NEXT: callq loop_latch
147
; CHECK-NEXT: .LBB4_1:
148
; CHECK-NEXT: callq loop_header
150
define void @cfg_islands() nounwind {
155
call void @loop_header()
156
%t0 = call i32 @get()
157
%t1 = icmp slt i32 %t0, 100
158
br i1 %t1, label %block100, label %bb
161
%t2 = call i32 @get()
162
%t3 = icmp slt i32 %t2, 101
163
br i1 %t3, label %block101, label %bb1
166
%t4 = call i32 @get()
167
%t5 = icmp slt i32 %t4, 102
168
br i1 %t5, label %block102, label %bb2
171
%t6 = call i32 @get()
172
%t7 = icmp slt i32 %t6, 103
173
br i1 %t7, label %exit, label %bb3
176
call void @loop_latch()
196
declare void @bar99() nounwind
197
declare void @bar100() nounwind
198
declare void @bar101() nounwind
199
declare void @bar102() nounwind
200
declare void @body() nounwind
201
declare void @exit() nounwind
202
declare void @loop_header() nounwind
203
declare void @loop_latch() nounwind
204
declare i32 @get() nounwind
205
declare void @block_a_true_func() nounwind
206
declare void @block_a_false_func() nounwind
207
declare void @block_a_merge_func() nounwind