[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / GlobalISel / irtranslator-condbr-lower-tree.ll
blob30eca0d463eb2baa21310a8cae0edf8d0f636545
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
4 declare i32 @bar(...)
5 define void @or_cond(i32 %X, i32 %Y, i32 %Z) nounwind {
6   ; CHECK-LABEL: name: or_cond
7   ; CHECK: bb.1.entry:
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
20   ; CHECK:   G_BR %bb.4
21   ; CHECK: bb.4.entry:
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
25   ; CHECK:   G_BR %bb.2
26   ; CHECK: bb.2.common.ret:
27   ; CHECK:   RET_ReallyLR
28   ; CHECK: bb.3.cond_true:
29   ; CHECK:   TCRETURNdi @bar, 0, csr_aarch64_aapcs, implicit $sp
30 entry:
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
36 cond_true:
37   %tmp5 = tail call i32 (...) @bar( )
38   ret void
40 UnifiedReturnBlock:
41   ret void
44 define void @or_cond_select(i32 %X, i32 %Y, i32 %Z) nounwind {
45   ; CHECK-LABEL: name: or_cond_select
46   ; CHECK: bb.1.entry:
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
60   ; CHECK:   G_BR %bb.4
61   ; CHECK: bb.4.entry:
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
65   ; CHECK:   G_BR %bb.2
66   ; CHECK: bb.2.common.ret:
67   ; CHECK:   RET_ReallyLR
68   ; CHECK: bb.3.cond_true:
69   ; CHECK:   TCRETURNdi @bar, 0, csr_aarch64_aapcs, implicit $sp
70 entry:
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
76 cond_true:
77   %tmp5 = tail call i32 (...) @bar( )
78   ret void
80 UnifiedReturnBlock:
81   ret void
84 define void @and_cond(i32 %X, i32 %Y, i32 %Z) nounwind {
85   ; CHECK-LABEL: name: and_cond
86   ; CHECK: bb.1.entry:
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
99   ; CHECK:   G_BR %bb.2
100   ; CHECK: bb.4.entry:
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
104   ; CHECK:   G_BR %bb.2
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
109 entry:
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
115 cond_true:
116   %tmp5 = tail call i32 (...) @bar( )
117   ret void
119 UnifiedReturnBlock:
120   ret void
123 define void @and_cond_select(i32 %X, i32 %Y, i32 %Z) nounwind {
124   ; CHECK-LABEL: name: and_cond_select
125   ; CHECK: bb.1.entry:
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
139   ; CHECK:   G_BR %bb.2
140   ; CHECK: bb.4.entry:
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
144   ; CHECK:   G_BR %bb.2
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
149 entry:
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
155 cond_true:
156   %tmp5 = tail call i32 (...) @bar( )
157   ret void
159 UnifiedReturnBlock:
160   ret void
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
166   ; CHECK: bb.1.entry:
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
177   ; CHECK:   G_BR %bb.2
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
182 entry:
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
188 cond_true:
189   %tmp5 = tail call i32 (...) @bar( )
190   ret void
192 UnifiedReturnBlock:
193   ret void
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
199   ; CHECK: bb.1.entry:
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
213   ; CHECK:   G_BR %bb.5
214   ; CHECK: bb.5.entry:
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
218   ; CHECK:   G_BR %bb.4
219   ; CHECK: bb.4.entry:
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
223   ; CHECK:   G_BR %bb.2
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
228 entry:
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
236 cond_true:
237   %tmp5 = tail call i32 (...) @bar( )
238   ret void
240 UnifiedReturnBlock:
241   ret void
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
248   ; CHECK: bb.1.entry:
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
259   ; CHECK:   G_BR %bb.2
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
264 entry:
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
270 cond_true:
271   %tmp5 = tail call i32 (...) @bar( )
272   ret void
274 UnifiedReturnBlock:
275   ret void
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
283   ; CHECK: bb.1.entry:
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
295   ; CHECK:   G_BR %bb.2
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
300 entry:
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
306 cond_true:
307   %tmp5 = tail call i32 (...) @bar( )
308   ret void
310 UnifiedReturnBlock:
311   ret void
314 !0 = !{}