1 ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2 ; RUN: llc -mtriple aarch64 -stop-after=irtranslator -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s
5 define void @or_cond(i32 %X, i32 %Y, i32 %Z) nounwind {
6 ; CHECK-LABEL: name: or_cond
8 ; CHECK: successors: %bb.3(0x20000000), %bb.4(0x60000000)
9 ; CHECK: liveins: $w0, $w1, $w2
10 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
11 ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
12 ; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY $w2
13 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
14 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
15 ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]
16 ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY1]](s32), [[C1]]
17 ; CHECK: [[OR:%[0-9]+]]:_(s1) = G_OR [[ICMP1]], [[ICMP]]
18 ; CHECK: [[ICMP2:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY1]](s32), [[C1]]
19 ; CHECK: G_BRCOND [[ICMP2]](s1), %bb.3
22 ; CHECK: successors: %bb.3(0x2aaaaaab), %bb.2(0x55555555)
23 ; CHECK: [[ICMP3:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]
24 ; CHECK: G_BRCOND [[ICMP3]](s1), %bb.3
26 ; CHECK: bb.2.common.ret:
28 ; CHECK: bb.3.cond_true:
29 ; CHECK: TCRETURNdi @bar, 0, csr_aarch64_aapcs, implicit $sp
31 %tmp1 = icmp eq i32 %X, 0
32 %tmp3 = icmp slt i32 %Y, 5
33 %tmp4 = or i1 %tmp3, %tmp1
34 br i1 %tmp4, label %cond_true, label %UnifiedReturnBlock
37 %tmp5 = tail call i32 (...) @bar( )
44 define void @or_cond_select(i32 %X, i32 %Y, i32 %Z) nounwind {
45 ; CHECK-LABEL: name: or_cond_select
47 ; CHECK: successors: %bb.3(0x20000000), %bb.4(0x60000000)
48 ; CHECK: liveins: $w0, $w1, $w2
49 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
50 ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
51 ; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY $w2
52 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
53 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
54 ; CHECK: [[C2:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
55 ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]
56 ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY1]](s32), [[C1]]
57 ; CHECK: [[SELECT:%[0-9]+]]:_(s1) = G_SELECT [[ICMP1]](s1), [[C2]], [[ICMP]]
58 ; CHECK: [[ICMP2:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY1]](s32), [[C1]]
59 ; CHECK: G_BRCOND [[ICMP2]](s1), %bb.3
62 ; CHECK: successors: %bb.3(0x2aaaaaab), %bb.2(0x55555555)
63 ; CHECK: [[ICMP3:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]
64 ; CHECK: G_BRCOND [[ICMP3]](s1), %bb.3
66 ; CHECK: bb.2.common.ret:
68 ; CHECK: bb.3.cond_true:
69 ; CHECK: TCRETURNdi @bar, 0, csr_aarch64_aapcs, implicit $sp
71 %tmp1 = icmp eq i32 %X, 0
72 %tmp3 = icmp slt i32 %Y, 5
73 %tmp4 = select i1 %tmp3, i1 true, i1 %tmp1
74 br i1 %tmp4, label %cond_true, label %UnifiedReturnBlock
77 %tmp5 = tail call i32 (...) @bar( )
84 define void @and_cond(i32 %X, i32 %Y, i32 %Z) nounwind {
85 ; CHECK-LABEL: name: and_cond
87 ; CHECK: successors: %bb.4(0x60000000), %bb.2(0x20000000)
88 ; CHECK: liveins: $w0, $w1, $w2
89 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
90 ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
91 ; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY $w2
92 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
93 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
94 ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]
95 ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY1]](s32), [[C1]]
96 ; CHECK: [[AND:%[0-9]+]]:_(s1) = G_AND [[ICMP1]], [[ICMP]]
97 ; CHECK: [[ICMP2:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY1]](s32), [[C1]]
98 ; CHECK: G_BRCOND [[ICMP2]](s1), %bb.4
101 ; CHECK: successors: %bb.3(0x55555555), %bb.2(0x2aaaaaab)
102 ; CHECK: [[ICMP3:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]
103 ; CHECK: G_BRCOND [[ICMP3]](s1), %bb.3
105 ; CHECK: bb.2.common.ret:
106 ; CHECK: RET_ReallyLR
107 ; CHECK: bb.3.cond_true:
108 ; CHECK: TCRETURNdi @bar, 0, csr_aarch64_aapcs, implicit $sp
110 %tmp1 = icmp eq i32 %X, 0
111 %tmp3 = icmp slt i32 %Y, 5
112 %tmp4 = and i1 %tmp3, %tmp1
113 br i1 %tmp4, label %cond_true, label %UnifiedReturnBlock
116 %tmp5 = tail call i32 (...) @bar( )
123 define void @and_cond_select(i32 %X, i32 %Y, i32 %Z) nounwind {
124 ; CHECK-LABEL: name: and_cond_select
126 ; CHECK: successors: %bb.4(0x60000000), %bb.2(0x20000000)
127 ; CHECK: liveins: $w0, $w1, $w2
128 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
129 ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
130 ; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY $w2
131 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
132 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
133 ; CHECK: [[C2:%[0-9]+]]:_(s1) = G_CONSTANT i1 false
134 ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]
135 ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY1]](s32), [[C1]]
136 ; CHECK: [[SELECT:%[0-9]+]]:_(s1) = G_SELECT [[ICMP1]](s1), [[ICMP]], [[C2]]
137 ; CHECK: [[ICMP2:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY1]](s32), [[C1]]
138 ; CHECK: G_BRCOND [[ICMP2]](s1), %bb.4
141 ; CHECK: successors: %bb.3(0x55555555), %bb.2(0x2aaaaaab)
142 ; CHECK: [[ICMP3:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]
143 ; CHECK: G_BRCOND [[ICMP3]](s1), %bb.3
145 ; CHECK: bb.2.common.ret:
146 ; CHECK: RET_ReallyLR
147 ; CHECK: bb.3.cond_true:
148 ; CHECK: TCRETURNdi @bar, 0, csr_aarch64_aapcs, implicit $sp
150 %tmp1 = icmp eq i32 %X, 0
151 %tmp3 = icmp slt i32 %Y, 5
152 %tmp4 = select i1 %tmp3, i1 %tmp1, i1 false
153 br i1 %tmp4, label %cond_true, label %UnifiedReturnBlock
156 %tmp5 = tail call i32 (...) @bar( )
163 ; Don't emit two branches for same operands.
164 define void @or_cond_same_values_cmp(i32 %X, i32 %Y, i32 %Z) nounwind {
165 ; CHECK-LABEL: name: or_cond_same_values_cmp
167 ; CHECK: successors: %bb.3(0x40000000), %bb.2(0x40000000)
168 ; CHECK: liveins: $w0, $w1, $w2
169 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
170 ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
171 ; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY $w2
172 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
173 ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]
174 ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY]](s32), [[C]]
175 ; CHECK: [[OR:%[0-9]+]]:_(s1) = G_OR [[ICMP1]], [[ICMP]]
176 ; CHECK: G_BRCOND [[OR]](s1), %bb.3
178 ; CHECK: bb.2.common.ret:
179 ; CHECK: RET_ReallyLR
180 ; CHECK: bb.3.cond_true:
181 ; CHECK: TCRETURNdi @bar, 0, csr_aarch64_aapcs, implicit $sp
183 %tmp1 = icmp eq i32 %X, 5
184 %tmp3 = icmp slt i32 %X, 5
185 %tmp4 = or i1 %tmp3, %tmp1
186 br i1 %tmp4, label %cond_true, label %UnifiedReturnBlock
189 %tmp5 = tail call i32 (...) @bar( )
196 ; Emit multiple branches for more than 2 cases.
197 define void @or_cond_multiple_cases(i32 %X, i32 %Y, i32 %Z) nounwind {
198 ; CHECK-LABEL: name: or_cond_multiple_cases
200 ; CHECK: successors: %bb.3(0x10000000), %bb.5(0x70000000)
201 ; CHECK: liveins: $w0, $w1, $w2
202 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
203 ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
204 ; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY $w2
205 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
206 ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]
207 ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY]](s32), [[C]]
208 ; CHECK: [[ICMP2:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY2]](s32), [[C]]
209 ; CHECK: [[OR:%[0-9]+]]:_(s1) = G_OR [[ICMP1]], [[ICMP]]
210 ; CHECK: [[OR1:%[0-9]+]]:_(s1) = G_OR [[OR]], [[ICMP2]]
211 ; CHECK: [[ICMP3:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY]](s32), [[C]]
212 ; CHECK: G_BRCOND [[ICMP3]](s1), %bb.3
215 ; CHECK: successors: %bb.3(0x12492492), %bb.4(0x6db6db6e)
216 ; CHECK: [[ICMP4:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]
217 ; CHECK: G_BRCOND [[ICMP4]](s1), %bb.3
220 ; CHECK: successors: %bb.3(0x2aaaaaab), %bb.2(0x55555555)
221 ; CHECK: [[ICMP5:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY2]](s32), [[C]]
222 ; CHECK: G_BRCOND [[ICMP5]](s1), %bb.3
224 ; CHECK: bb.2.common.ret:
225 ; CHECK: RET_ReallyLR
226 ; CHECK: bb.3.cond_true:
227 ; CHECK: TCRETURNdi @bar, 0, csr_aarch64_aapcs, implicit $sp
229 %tmp1 = icmp eq i32 %X, 5
230 %tmp3 = icmp slt i32 %X, 5
231 %tmpZ = icmp eq i32 %Z, 5
232 %tmp4 = or i1 %tmp3, %tmp1
233 %final = or i1 %tmp4, %tmpZ
234 br i1 %final, label %cond_true, label %UnifiedReturnBlock
237 %tmp5 = tail call i32 (...) @bar( )
244 ; (X != null) | (Y != null) --> (X|Y) != 0
245 ; Don't emit two branches.
246 define void @or_cond_ne_null(i32 %X, i32 %Y, i32 %Z) nounwind {
247 ; CHECK-LABEL: name: or_cond_ne_null
249 ; CHECK: successors: %bb.3(0x40000000), %bb.2(0x40000000)
250 ; CHECK: liveins: $w0, $w1, $w2
251 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
252 ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
253 ; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY $w2
254 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
255 ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(ne), [[COPY]](s32), [[C]]
256 ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(ne), [[COPY1]](s32), [[C]]
257 ; CHECK: [[OR:%[0-9]+]]:_(s1) = G_OR [[ICMP1]], [[ICMP]]
258 ; CHECK: G_BRCOND [[OR]](s1), %bb.3
260 ; CHECK: bb.2.common.ret:
261 ; CHECK: RET_ReallyLR
262 ; CHECK: bb.3.cond_true:
263 ; CHECK: TCRETURNdi @bar, 0, csr_aarch64_aapcs, implicit $sp
265 %tmp1 = icmp ne i32 %X, 0
266 %tmp3 = icmp ne i32 %Y, 0
267 %tmp4 = or i1 %tmp3, %tmp1
268 br i1 %tmp4, label %cond_true, label %UnifiedReturnBlock
271 %tmp5 = tail call i32 (...) @bar( )
278 ; If the branch is unpredictable, don't add another branch
279 ; regardless of whether they are expensive or not.
281 define void @unpredictable(i32 %X, i32 %Y, i32 %Z) nounwind {
282 ; CHECK-LABEL: name: unpredictable
284 ; CHECK: successors: %bb.3(0x40000000), %bb.2(0x40000000)
285 ; CHECK: liveins: $w0, $w1, $w2
286 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
287 ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
288 ; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY $w2
289 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
290 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
291 ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]
292 ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY1]](s32), [[C1]]
293 ; CHECK: [[OR:%[0-9]+]]:_(s1) = G_OR [[ICMP1]], [[ICMP]]
294 ; CHECK: G_BRCOND [[OR]](s1), %bb.3
296 ; CHECK: bb.2.common.ret:
297 ; CHECK: RET_ReallyLR
298 ; CHECK: bb.3.cond_true:
299 ; CHECK: TCRETURNdi @bar, 0, csr_aarch64_aapcs, implicit $sp
301 %tmp1 = icmp eq i32 %X, 0
302 %tmp3 = icmp slt i32 %Y, 5
303 %tmp4 = or i1 %tmp3, %tmp1
304 br i1 %tmp4, label %cond_true, label %UnifiedReturnBlock, !unpredictable !0
307 %tmp5 = tail call i32 (...) @bar( )