1; RUN: llc -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s
2
3; This test checks that LLVM can do basic stripping and reapplying of branches
4; to basic blocks.
5
6declare void @test_true()
7declare void @test_false()
8
9; !0 corresponds to a branch being taken, !1 to not being takne.
10!0 = !{!"branch_weights", i32 64, i32 4}
11!1 = !{!"branch_weights", i32 4, i32 64}
12
13define void @test_Bcc_fallthrough_taken(i32 %in) nounwind {
14; CHECK-LABEL: test_Bcc_fallthrough_taken:
15  %tst = icmp eq i32 %in, 42
16  br i1 %tst, label %true, label %false, !prof !0
17
18; CHECK: cmp {{w[0-9]+}}, #42
19
20; CHECK: b.ne [[FALSE:.LBB[0-9]+_[0-9]+]]
21; CHECK-NEXT: // %bb.
22; CHECK-NEXT: bl test_true
23
24; CHECK: [[FALSE]]:
25; CHECK: bl test_false
26
27true:
28  call void @test_true()
29  ret void
30
31false:
32  call void @test_false()
33  ret void
34}
35
36define void @test_Bcc_fallthrough_nottaken(i32 %in) nounwind {
37; CHECK-LABEL: test_Bcc_fallthrough_nottaken:
38  %tst = icmp eq i32 %in, 42
39  br i1 %tst, label %true, label %false, !prof !1
40
41; CHECK: cmp {{w[0-9]+}}, #42
42
43; CHECK: b.eq [[TRUE:.LBB[0-9]+_[0-9]+]]
44; CHECK-NEXT: // %bb.
45; CHECK-NEXT: bl test_false
46
47; CHECK: [[TRUE]]:
48; CHECK: bl test_true
49
50true:
51  call void @test_true()
52  ret void
53
54false:
55  call void @test_false()
56  ret void
57}
58
59define void @test_CBZ_fallthrough_taken(i32 %in) nounwind {
60; CHECK-LABEL: test_CBZ_fallthrough_taken:
61  %tst = icmp eq i32 %in, 0
62  br i1 %tst, label %true, label %false, !prof !0
63
64; CHECK: cbnz {{w[0-9]+}}, [[FALSE:.LBB[0-9]+_[0-9]+]]
65; CHECK-NEXT: // %bb.
66; CHECK-NEXT: bl test_true
67
68; CHECK: [[FALSE]]:
69; CHECK: bl test_false
70
71true:
72  call void @test_true()
73  ret void
74
75false:
76  call void @test_false()
77  ret void
78}
79
80define void @test_CBZ_fallthrough_nottaken(i64 %in) nounwind {
81; CHECK-LABEL: test_CBZ_fallthrough_nottaken:
82  %tst = icmp eq i64 %in, 0
83  br i1 %tst, label %true, label %false, !prof !1
84
85; CHECK: cbz {{x[0-9]+}}, [[TRUE:.LBB[0-9]+_[0-9]+]]
86; CHECK-NEXT: // %bb.
87; CHECK-NEXT: bl test_false
88
89; CHECK: [[TRUE]]:
90; CHECK: bl test_true
91
92true:
93  call void @test_true()
94  ret void
95
96false:
97  call void @test_false()
98  ret void
99}
100
101define void @test_CBNZ_fallthrough_taken(i32 %in) nounwind {
102; CHECK-LABEL: test_CBNZ_fallthrough_taken:
103  %tst = icmp ne i32 %in, 0
104  br i1 %tst, label %true, label %false, !prof !0
105
106; CHECK: cbz {{w[0-9]+}}, [[FALSE:.LBB[0-9]+_[0-9]+]]
107; CHECK-NEXT: // %bb.
108; CHECK-NEXT: bl test_true
109
110; CHECK: [[FALSE]]:
111; CHECK: bl test_false
112
113true:
114  call void @test_true()
115  ret void
116
117false:
118  call void @test_false()
119  ret void
120}
121
122define void @test_CBNZ_fallthrough_nottaken(i64 %in) nounwind {
123; CHECK-LABEL: test_CBNZ_fallthrough_nottaken:
124  %tst = icmp ne i64 %in, 0
125  br i1 %tst, label %true, label %false, !prof !1
126
127; CHECK: cbnz {{x[0-9]+}}, [[TRUE:.LBB[0-9]+_[0-9]+]]
128; CHECK-NEXT: // %bb.
129; CHECK-NEXT: bl test_false
130
131; CHECK: [[TRUE]]:
132; CHECK: bl test_true
133
134true:
135  call void @test_true()
136  ret void
137
138false:
139  call void @test_false()
140  ret void
141}
142
143define void @test_TBZ_fallthrough_taken(i32 %in) nounwind {
144; CHECK-LABEL: test_TBZ_fallthrough_taken:
145  %bit = and i32 %in, 32768
146  %tst = icmp eq i32 %bit, 0
147  br i1 %tst, label %true, label %false, !prof !0
148
149; CHECK: tbnz {{w[0-9]+}}, #15, [[FALSE:.LBB[0-9]+_[0-9]+]]
150; CHECK-NEXT: // %bb.
151; CHECK-NEXT: bl test_true
152
153; CHECK: [[FALSE]]:
154; CHECK: bl test_false
155
156true:
157  call void @test_true()
158  ret void
159
160false:
161  call void @test_false()
162  ret void
163}
164
165define void @test_TBZ_fallthrough_nottaken(i64 %in) nounwind {
166; CHECK-LABEL: test_TBZ_fallthrough_nottaken:
167  %bit = and i64 %in, 32768
168  %tst = icmp eq i64 %bit, 0
169  br i1 %tst, label %true, label %false, !prof !1
170
171; CHECK: tbz {{[wx][0-9]+}}, #15, [[TRUE:.LBB[0-9]+_[0-9]+]]
172; CHECK-NEXT: // %bb.
173; CHECK-NEXT: bl test_false
174
175; CHECK: [[TRUE]]:
176; CHECK: bl test_true
177
178true:
179  call void @test_true()
180  ret void
181
182false:
183  call void @test_false()
184  ret void
185}
186
187
188define void @test_TBNZ_fallthrough_taken(i32 %in) nounwind {
189; CHECK-LABEL: test_TBNZ_fallthrough_taken:
190  %bit = and i32 %in, 32768
191  %tst = icmp ne i32 %bit, 0
192  br i1 %tst, label %true, label %false, !prof !0
193
194; CHECK: tbz {{w[0-9]+}}, #15, [[FALSE:.LBB[0-9]+_[0-9]+]]
195; CHECK-NEXT: // %bb.
196; CHECK-NEXT: bl test_true
197
198; CHECK: [[FALSE]]:
199; CHECK: bl test_false
200
201true:
202  call void @test_true()
203  ret void
204
205false:
206  call void @test_false()
207  ret void
208}
209
210define void @test_TBNZ_fallthrough_nottaken(i64 %in) nounwind {
211; CHECK-LABEL: test_TBNZ_fallthrough_nottaken:
212  %bit = and i64 %in, 32768
213  %tst = icmp ne i64 %bit, 0
214  br i1 %tst, label %true, label %false, !prof !1
215
216; CHECK: tbnz {{[wx][0-9]+}}, #15, [[TRUE:.LBB[0-9]+_[0-9]+]]
217; CHECK-NEXT: // %bb.
218; CHECK-NEXT: bl test_false
219
220; CHECK: [[TRUE]]:
221; CHECK: bl test_true
222
223true:
224  call void @test_true()
225  ret void
226
227false:
228  call void @test_false()
229  ret void
230}
231
232