1# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2# RUN: llc -mtriple aarch64-unknown-unknown -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
3#
4# Verify that we can fold G_AND into G_BRCOND when all of the following hold:
5#   1. We have a ne/eq G_ICMP feeding into the G_BRCOND
6#   2. The G_ICMP is being compared against 0
7#   3. One of the operands of the G_AND is a power of 2
8#
9# If all of these hold, we should produce a tbnz or a tbz.
10...
11---
12name:            tbnzx_and
13alignment:       4
14legalized:       true
15regBankSelected: true
16body:             |
17  ; CHECK-LABEL: name: tbnzx_and
18  ; CHECK: bb.0:
19  ; CHECK:   successors: %bb.0(0x40000000), %bb.1(0x40000000)
20  ; CHECK:   [[COPY:%[0-9]+]]:gpr64 = COPY $x0
21  ; CHECK:   TBNZX [[COPY]], 33, %bb.1
22  ; CHECK:   B %bb.0
23  ; CHECK: bb.1:
24  ; CHECK:   RET_ReallyLR
25  bb.0:
26    successors: %bb.0, %bb.1
27    liveins: $x0
28    %0:gpr(s64) = COPY $x0
29    %1:gpr(s64) = G_CONSTANT i64 8589934592 ; Bit number 33 => TBNZX
30    %3:gpr(s64) = G_CONSTANT i64 0
31    %2:gpr(s64) = G_AND %0, %1
32    %5:gpr(s32) = G_ICMP intpred(ne), %2(s64), %3
33    %4:gpr(s1) = G_TRUNC %5(s32)
34    G_BRCOND %4(s1), %bb.1
35    G_BR %bb.0
36  bb.1:
37    RET_ReallyLR
38
39...
40---
41name:            tbzx_and
42alignment:       4
43legalized:       true
44regBankSelected: true
45tracksRegLiveness: true
46body:             |
47  ; CHECK-LABEL: name: tbzx_and
48  ; CHECK: bb.0:
49  ; CHECK:   successors: %bb.0(0x40000000), %bb.1(0x40000000)
50  ; CHECK:   liveins: $x0
51  ; CHECK:   [[COPY:%[0-9]+]]:gpr64 = COPY $x0
52  ; CHECK:   TBZX [[COPY]], 33, %bb.1
53  ; CHECK:   B %bb.0
54  ; CHECK: bb.1:
55  ; CHECK:   RET_ReallyLR
56  bb.0:
57    successors: %bb.0, %bb.1
58    liveins: $x0
59    %0:gpr(s64) = COPY $x0
60    %1:gpr(s64) = G_CONSTANT i64 8589934592 ; Bit number 33 => TBNZX
61    %3:gpr(s64) = G_CONSTANT i64 0
62    %2:gpr(s64) = G_AND %0, %1
63    %5:gpr(s32) = G_ICMP intpred(eq), %2(s64), %3
64    %4:gpr(s1) = G_TRUNC %5(s32)
65    G_BRCOND %4(s1), %bb.1
66    G_BR %bb.0
67  bb.1:
68    RET_ReallyLR
69
70...
71---
72name:            tbnzw_and
73alignment:       4
74legalized:       true
75regBankSelected: true
76tracksRegLiveness: true
77body:             |
78  ; CHECK-LABEL: name: tbnzw_and
79  ; CHECK: bb.0:
80  ; CHECK:   successors: %bb.0(0x40000000), %bb.1(0x40000000)
81  ; CHECK:   liveins: $w0
82  ; CHECK:   [[COPY:%[0-9]+]]:gpr32 = COPY $w0
83  ; CHECK:   TBNZW [[COPY]], 0, %bb.1
84  ; CHECK:   B %bb.0
85  ; CHECK: bb.1:
86  ; CHECK:   RET_ReallyLR
87  bb.0:
88    successors: %bb.0, %bb.1
89    liveins: $w0
90    %0:gpr(s32) = COPY $w0
91    %1:gpr(s32) = G_CONSTANT i32 1
92    %3:gpr(s32) = G_CONSTANT i32 0
93    %2:gpr(s32) = G_AND %0, %1
94    %5:gpr(s32) = G_ICMP intpred(ne), %2(s32), %3
95    %4:gpr(s1) = G_TRUNC %5(s32)
96    G_BRCOND %4(s1), %bb.1
97    G_BR %bb.0
98  bb.1:
99    RET_ReallyLR
100
101...
102---
103name:            tbzw_and
104alignment:       4
105legalized:       true
106regBankSelected: true
107tracksRegLiveness: true
108body:             |
109  ; CHECK-LABEL: name: tbzw_and
110  ; CHECK: bb.0:
111  ; CHECK:   successors: %bb.0(0x40000000), %bb.1(0x40000000)
112  ; CHECK:   liveins: $w0
113  ; CHECK:   [[COPY:%[0-9]+]]:gpr32 = COPY $w0
114  ; CHECK:   TBZW [[COPY]], 0, %bb.1
115  ; CHECK:   B %bb.0
116  ; CHECK: bb.1:
117  ; CHECK:   RET_ReallyLR
118  bb.0:
119    successors: %bb.0, %bb.1
120    liveins: $w0
121    %0:gpr(s32) = COPY $w0
122    %1:gpr(s32) = G_CONSTANT i32 1
123    %3:gpr(s32) = G_CONSTANT i32 0
124    %2:gpr(s32) = G_AND %0, %1
125    %5:gpr(s32) = G_ICMP intpred(eq), %2(s32), %3
126    %4:gpr(s1) = G_TRUNC %5(s32)
127    G_BRCOND %4(s1), %bb.1
128    G_BR %bb.0
129  bb.1:
130    RET_ReallyLR
131
132...
133---
134name:            dont_fold_and_lt
135alignment:       4
136legalized:       true
137regBankSelected: true
138tracksRegLiveness: true
139body:             |
140  ; CHECK-LABEL: name: dont_fold_and_lt
141  ; CHECK: bb.0:
142  ; CHECK:   successors: %bb.0(0x40000000), %bb.1(0x40000000)
143  ; CHECK:   liveins: $w0
144  ; CHECK:   [[COPY:%[0-9]+]]:gpr32 = COPY $w0
145  ; CHECK:   [[ANDSWri:%[0-9]+]]:gpr32 = ANDSWri [[COPY]], 0, implicit-def $nzcv
146  ; CHECK:   Bcc 11, %bb.1, implicit $nzcv
147  ; CHECK:   B %bb.0
148  ; CHECK: bb.1:
149  ; CHECK:   RET_ReallyLR
150  bb.0:
151    successors: %bb.0, %bb.1
152    liveins: $w0
153    %0:gpr(s32) = COPY $w0
154    %1:gpr(s32) = G_CONSTANT i32 1
155    %3:gpr(s32) = G_CONSTANT i32 0
156    %2:gpr(s32) = G_AND %0, %1
157    %5:gpr(s32) = G_ICMP intpred(slt), %2(s32), %3
158    %4:gpr(s1) = G_TRUNC %5(s32)
159    G_BRCOND %4(s1), %bb.1
160    G_BR %bb.0
161  bb.1:
162    RET_ReallyLR
163
164...
165---
166name:            dont_fold_and_gt
167alignment:       4
168legalized:       true
169regBankSelected: true
170tracksRegLiveness: true
171body:             |
172  ; CHECK-LABEL: name: dont_fold_and_gt
173  ; CHECK: bb.0:
174  ; CHECK:   successors: %bb.0(0x40000000), %bb.1(0x40000000)
175  ; CHECK:   liveins: $w0
176  ; CHECK:   [[COPY:%[0-9]+]]:gpr32 = COPY $w0
177  ; CHECK:   [[ANDSWri:%[0-9]+]]:gpr32 = ANDSWri [[COPY]], 0, implicit-def $nzcv
178  ; CHECK:   Bcc 12, %bb.1, implicit $nzcv
179  ; CHECK:   B %bb.0
180  ; CHECK: bb.1:
181  ; CHECK:   RET_ReallyLR
182  bb.0:
183    successors: %bb.0, %bb.1
184    liveins: $w0
185    %0:gpr(s32) = COPY $w0
186    %1:gpr(s32) = G_CONSTANT i32 1
187    %3:gpr(s32) = G_CONSTANT i32 0
188    %2:gpr(s32) = G_AND %0, %1
189    %5:gpr(s32) = G_ICMP intpred(sgt), %2(s32), %3
190    %4:gpr(s1) = G_TRUNC %5(s32)
191    G_BRCOND %4(s1), %bb.1
192    G_BR %bb.0
193  bb.1:
194    RET_ReallyLR
195
196...
197---
198name:            dont_fold_and_not_power_of_2
199alignment:       4
200legalized:       true
201regBankSelected: true
202body:             |
203  ; CHECK-LABEL: name: dont_fold_and_not_power_of_2
204  ; CHECK: bb.0:
205  ; CHECK:   successors: %bb.0(0x40000000), %bb.1(0x40000000)
206  ; CHECK:   [[COPY:%[0-9]+]]:gpr64 = COPY $x0
207  ; CHECK:   [[ANDXri:%[0-9]+]]:gpr64common = ANDXri [[COPY]], 4098
208  ; CHECK:   CBNZX [[ANDXri]], %bb.1
209  ; CHECK:   B %bb.0
210  ; CHECK: bb.1:
211  ; CHECK:   RET_ReallyLR
212  bb.0:
213    successors: %bb.0, %bb.1
214    liveins: $x0
215    %0:gpr(s64) = COPY $x0
216    %1:gpr(s64) = G_CONSTANT i64 7
217    %3:gpr(s64) = G_CONSTANT i64 0
218    %2:gpr(s64) = G_AND %0, %1
219    %5:gpr(s32) = G_ICMP intpred(ne), %2(s64), %3
220    %4:gpr(s1) = G_TRUNC %5(s32)
221    G_BRCOND %4(s1), %bb.1
222    G_BR %bb.0
223  bb.1:
224    RET_ReallyLR
225
226...
227---
228name:            dont_fold_cmp_not_0
229alignment:       4
230legalized:       true
231regBankSelected: true
232body:             |
233  ; CHECK-LABEL: name: dont_fold_cmp_not_0
234  ; CHECK: bb.0:
235  ; CHECK:   successors: %bb.0(0x40000000), %bb.1(0x40000000)
236  ; CHECK:   [[COPY:%[0-9]+]]:gpr64 = COPY $x0
237  ; CHECK:   [[ANDXri:%[0-9]+]]:gpr64sp = ANDXri [[COPY]], 8064
238  ; CHECK:   [[SUBSXri:%[0-9]+]]:gpr64 = SUBSXri [[ANDXri]], 4, 0, implicit-def $nzcv
239  ; CHECK:   Bcc 1, %bb.1, implicit $nzcv
240  ; CHECK:   B %bb.0
241  ; CHECK: bb.1:
242  ; CHECK:   RET_ReallyLR
243  bb.0:
244    successors: %bb.0, %bb.1
245    liveins: $x0
246    %0:gpr(s64) = COPY $x0
247    %1:gpr(s64) = G_CONSTANT i64 4
248    %3:gpr(s64) = G_CONSTANT i64 4
249    %2:gpr(s64) = G_AND %0, %1
250    %5:gpr(s32) = G_ICMP intpred(ne), %2(s64), %3
251    %4:gpr(s1) = G_TRUNC %5(s32)
252    G_BRCOND %4(s1), %bb.1
253    G_BR %bb.0
254  bb.1:
255    RET_ReallyLR
256