[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / AArch64 / GlobalISel / opt-fold-shift-tbz-tbnz.mir
blobd236a6c5ce59aa3dcdb3321cfb6c1ca91d175421
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
4 # Check folding a G_SHL into a G_BRCOND which has been matched as a TB(N)Z.
5 ...
6 ---
7 name:            fold_shl
8 alignment:       4
9 legalized:       true
10 regBankSelected: true
11 body:             |
12   ; CHECK-LABEL: name: fold_shl
13   ; CHECK: bb.0:
14   ; CHECK:   successors: %bb.0(0x40000000), %bb.1(0x40000000)
15   ; CHECK:   %copy:gpr64all = COPY $x0
16   ; CHECK:   [[COPY:%[0-9]+]]:gpr32all = COPY %copy.sub_32
17   ; CHECK:   [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]]
18   ; CHECK:   TBNZW [[COPY1]], 2, %bb.1
19   ; CHECK:   B %bb.0
20   ; CHECK: bb.1:
21   ; CHECK:   RET_ReallyLR
22   bb.0:
23     successors: %bb.0, %bb.1
24     liveins: $x0
25     %copy:gpr(s64) = COPY $x0
26     %bit:gpr(s64) = G_CONSTANT i64 8
27     %zero:gpr(s64) = G_CONSTANT i64 0
29     ; tbnz (shl x, 1), 3 == tbnz x, 2
30     %fold_cst:gpr(s64) = G_CONSTANT i64 1
31     %fold_me:gpr(s64) = G_SHL %copy, %fold_cst
33     %and:gpr(s64) = G_AND %fold_me, %bit
34     %cmp:gpr(s32) = G_ICMP intpred(ne), %and(s64), %zero
35     %cmp_trunc:gpr(s1) = G_TRUNC %cmp(s32)
36     G_BRCOND %cmp_trunc(s1), %bb.1
37     G_BR %bb.0
38   bb.1:
39     RET_ReallyLR
40 ...
41 ---
42 name:            dont_fold_shl_1
43 alignment:       4
44 legalized:       true
45 regBankSelected: true
46 body:             |
47   ; CHECK-LABEL: name: dont_fold_shl_1
48   ; CHECK: bb.0:
49   ; CHECK:   successors: %bb.0(0x40000000), %bb.1(0x40000000)
50   ; CHECK:   %copy:gpr64 = COPY $x0
51   ; CHECK:   %fold_me:gpr64 = UBFMXri %copy, 59, 58
52   ; CHECK:   [[COPY:%[0-9]+]]:gpr32all = COPY %fold_me.sub_32
53   ; CHECK:   [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]]
54   ; CHECK:   TBNZW [[COPY1]], 3, %bb.1
55   ; CHECK:   B %bb.0
56   ; CHECK: bb.1:
57   ; CHECK:   RET_ReallyLR
58   bb.0:
59     successors: %bb.0, %bb.1
60     liveins: $x0
61     %copy:gpr(s64) = COPY $x0
62     %bit:gpr(s64) = G_CONSTANT i64 8
63     %zero:gpr(s64) = G_CONSTANT i64 0
65     ; 5 > 3, so we cannot do the transformation as above.
66     %fold_cst:gpr(s64) = G_CONSTANT i64 5
67     %fold_me:gpr(s64) = G_SHL %copy, %fold_cst
69     %and:gpr(s64) = G_AND %fold_me, %bit
70     %cmp:gpr(s32) = G_ICMP intpred(ne), %and(s64), %zero
71     %cmp_trunc:gpr(s1) = G_TRUNC %cmp(s32)
72     G_BRCOND %cmp_trunc(s1), %bb.1
73     G_BR %bb.0
74   bb.1:
75     RET_ReallyLR
76 ...
77 ---
78 name:            dont_fold_shl_2
79 alignment:       4
80 legalized:       true
81 regBankSelected: true
82 body:             |
83   ; CHECK-LABEL: name: dont_fold_shl_2
84   ; CHECK: bb.0:
85   ; CHECK:   successors: %bb.0(0x40000000), %bb.1(0x40000000)
86   ; CHECK:   %copy:gpr64 = COPY $x0
87   ; CHECK:   %fold_cst:gpr64 = MOVi64imm -5
88   ; CHECK:   %fold_me:gpr64 = LSLVXr %copy, %fold_cst
89   ; CHECK:   [[COPY:%[0-9]+]]:gpr32all = COPY %fold_me.sub_32
90   ; CHECK:   [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]]
91   ; CHECK:   TBNZW [[COPY1]], 3, %bb.1
92   ; CHECK:   B %bb.0
93   ; CHECK: bb.1:
94   ; CHECK:   RET_ReallyLR
95   bb.0:
96     successors: %bb.0, %bb.1
97     liveins: $x0
98     %copy:gpr(s64) = COPY $x0
99     %bit:gpr(s64) = G_CONSTANT i64 8
100     %zero:gpr(s64) = G_CONSTANT i64 0
102     ; Same case as above, except we wrap around.
103     %fold_cst:gpr(s64) = G_CONSTANT i64 -5
104     %fold_me:gpr(s64) = G_SHL %copy, %fold_cst
106     %and:gpr(s64) = G_AND %fold_me, %bit
107     %cmp:gpr(s32) = G_ICMP intpred(ne), %and(s64), %zero
108     %cmp_trunc:gpr(s1) = G_TRUNC %cmp(s32)
109     G_BRCOND %cmp_trunc(s1), %bb.1
110     G_BR %bb.0
111   bb.1:
112     RET_ReallyLR
116 name:            dont_fold_shl_3
117 alignment:       4
118 legalized:       true
119 regBankSelected: true
120 body:             |
121   ; CHECK-LABEL: name: dont_fold_shl_3
122   ; CHECK: bb.0:
123   ; CHECK:   successors: %bb.0(0x40000000), %bb.1(0x40000000)
124   ; CHECK:   %copy:gpr64 = COPY $x0
125   ; CHECK:   %shl:gpr64 = UBFMXri %copy, 62, 61
126   ; CHECK:   [[COPY:%[0-9]+]]:gpr32all = COPY %shl.sub_32
127   ; CHECK:   [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]]
128   ; CHECK:   TBNZW [[COPY1]], 3, %bb.1
129   ; CHECK:   B %bb.0
130   ; CHECK: bb.1:
131   ; CHECK:   %second_use:gpr64sp = ORRXri %shl, 8000
132   ; CHECK:   $x0 = COPY %second_use
133   ; CHECK:   RET_ReallyLR implicit $x0
134   bb.0:
135     successors: %bb.0, %bb.1
136     liveins: $x0
137     %copy:gpr(s64) = COPY $x0
138     %bit:gpr(s64) = G_CONSTANT i64 8
139     %zero:gpr(s64) = G_CONSTANT i64 0
140     %fold_cst:gpr(s64) = G_CONSTANT i64 2
142     ; Don't walk past the G_SHL when it's used more than once.
143     %shl:gpr(s64) = G_SHL %copy, %fold_cst
144     %and:gpr(s64) = G_AND %shl, %bit
145     %cmp:gpr(s32) = G_ICMP intpred(ne), %and(s64), %zero
146     %cmp_trunc:gpr(s1) = G_TRUNC %cmp(s32)
147     G_BRCOND %cmp_trunc(s1), %bb.1
148     G_BR %bb.0
150   bb.1:
151     %second_use:gpr(s64) = G_OR %shl, %bit
152     $x0 = COPY %second_use
153     RET_ReallyLR implicit $x0
157 name:            fold_ashr_in_range
158 alignment:       4
159 legalized:       true
160 regBankSelected: true
161 body:             |
162   ; CHECK-LABEL: name: fold_ashr_in_range
163   ; CHECK: bb.0:
164   ; CHECK:   successors: %bb.0(0x40000000), %bb.1(0x40000000)
165   ; CHECK:   %copy:gpr64all = COPY $x0
166   ; CHECK:   [[COPY:%[0-9]+]]:gpr32all = COPY %copy.sub_32
167   ; CHECK:   [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]]
168   ; CHECK:   TBNZW [[COPY1]], 4, %bb.1
169   ; CHECK:   B %bb.0
170   ; CHECK: bb.1:
171   ; CHECK:   RET_ReallyLR
172   bb.0:
173     successors: %bb.0, %bb.1
174     liveins: $x0
175     %copy:gpr(s64) = COPY $x0
176     %bit:gpr(s64) = G_CONSTANT i64 8
177     %zero:gpr(s64) = G_CONSTANT i64 0
179     ; tb(n)z (ashr x, c), b == tbz(x, b + c) when b+c <= the size of the type.
180     ; In this case, we should get 1 + 3 = 4 as the bit number.
181     %fold_cst:gpr(s64) = G_CONSTANT i64 1
182     %fold_me:gpr(s64) = G_ASHR %copy, %fold_cst
184     %and:gpr(s64) = G_AND %fold_me, %bit
185     %cmp:gpr(s32) = G_ICMP intpred(ne), %and(s64), %zero
186     %cmp_trunc:gpr(s1) = G_TRUNC %cmp(s32)
187     G_BRCOND %cmp_trunc(s1), %bb.1
188     G_BR %bb.0
189   bb.1:
190     RET_ReallyLR
194 name:            fold_ashr_msb_1
195 alignment:       4
196 legalized:       true
197 regBankSelected: true
198 body:             |
199   ; CHECK-LABEL: name: fold_ashr_msb_1
200   ; CHECK: bb.0:
201   ; CHECK:   successors: %bb.0(0x40000000), %bb.1(0x40000000)
202   ; CHECK:   %copy:gpr32 = COPY $w0
203   ; CHECK:   TBNZW %copy, 31, %bb.1
204   ; CHECK:   B %bb.0
205   ; CHECK: bb.1:
206   ; CHECK:   RET_ReallyLR
207   bb.0:
208     successors: %bb.0, %bb.1
209     liveins: $x0
210     %copy:gpr(s32) = COPY $w0
211     %bit:gpr(s32) = G_CONSTANT i32 8
212     %zero:gpr(s32) = G_CONSTANT i32 0
214     ; We should get a TBNZW with a 31 as the bit.
215     %fold_cst:gpr(s32) = G_CONSTANT i32 1234
216     %fold_me:gpr(s32) = G_ASHR %copy, %fold_cst
218     %and:gpr(s32) = G_AND %fold_me, %bit
219     %cmp:gpr(s32) = G_ICMP intpred(ne), %and(s32), %zero
220     %cmp_trunc:gpr(s1) = G_TRUNC %cmp(s32)
221     G_BRCOND %cmp_trunc(s1), %bb.1
222     G_BR %bb.0
223   bb.1:
224     RET_ReallyLR
228 name:            fold_ashr_msb_2
229 alignment:       4
230 legalized:       true
231 regBankSelected: true
232 body:             |
233   ; CHECK-LABEL: name: fold_ashr_msb_2
234   ; CHECK: bb.0:
235   ; CHECK:   successors: %bb.0(0x40000000), %bb.1(0x40000000)
236   ; CHECK:   %copy:gpr64 = COPY $x0
237   ; CHECK:   TBNZX %copy, 63, %bb.1
238   ; CHECK:   B %bb.0
239   ; CHECK: bb.1:
240   ; CHECK:   RET_ReallyLR
241   bb.0:
242     successors: %bb.0, %bb.1
243     liveins: $x0
244     %copy:gpr(s64) = COPY $x0
245     %bit:gpr(s64) = G_CONSTANT i64 8
246     %zero:gpr(s64) = G_CONSTANT i64 0
248     ; We should get a TBNZX with a 63 as the bit.
249     %fold_cst:gpr(s64) = G_CONSTANT i64 1234
250     %fold_me:gpr(s64) = G_ASHR %copy, %fold_cst
252     %and:gpr(s64) = G_AND %fold_me, %bit
253     %cmp:gpr(s32) = G_ICMP intpred(ne), %and(s64), %zero
254     %cmp_trunc:gpr(s1) = G_TRUNC %cmp(s32)
255     G_BRCOND %cmp_trunc(s1), %bb.1
256     G_BR %bb.0
257   bb.1:
258     RET_ReallyLR
262 name:            fold_lshr
263 alignment:       4
264 legalized:       true
265 regBankSelected: true
266 body:             |
267   ; CHECK-LABEL: name: fold_lshr
268   ; CHECK: bb.0:
269   ; CHECK:   successors: %bb.0(0x40000000), %bb.1(0x40000000)
270   ; CHECK:   %copy:gpr32 = COPY $w0
271   ; CHECK:   TBNZW %copy, 4, %bb.1
272   ; CHECK:   B %bb.0
273   ; CHECK: bb.1:
274   ; CHECK:   RET_ReallyLR
275   bb.0:
276     successors: %bb.0, %bb.1
277     liveins: $x0
278     %copy:gpr(s32) = COPY $w0
279     %bit:gpr(s32) = G_CONSTANT i32 8
280     %zero:gpr(s32) = G_CONSTANT i32 0
282     ; We should get 4 as the test bit.
283     %fold_cst:gpr(s32) = G_CONSTANT i32 1
284     %fold_me:gpr(s32) = G_LSHR %copy, %fold_cst
286     %and:gpr(s32) = G_AND %fold_me, %bit
287     %cmp:gpr(s32) = G_ICMP intpred(ne), %and(s32), %zero
288     %cmp_trunc:gpr(s1) = G_TRUNC %cmp(s32)
289     G_BRCOND %cmp_trunc(s1), %bb.1
290     G_BR %bb.0
291   bb.1:
292     RET_ReallyLR
296 name:            fold_lshr_2
297 alignment:       4
298 legalized:       true
299 regBankSelected: true
300 body:             |
301   ; CHECK-LABEL: name: fold_lshr_2
302   ; CHECK: bb.0:
303   ; CHECK:   successors: %bb.0(0x40000000), %bb.1(0x40000000)
304   ; CHECK:   %copy:gpr64 = COPY $x0
305   ; CHECK:   TBNZX %copy, 32, %bb.1
306   ; CHECK:   B %bb.0
307   ; CHECK: bb.1:
308   ; CHECK:   RET_ReallyLR
309   bb.0:
310     successors: %bb.0, %bb.1
311     liveins: $x0
312     %copy:gpr(s64) = COPY $x0
313     %bit:gpr(s64) = G_CONSTANT i64 8
314     %zero:gpr(s64) = G_CONSTANT i64 0
316     ; We're testing a s64.
317     ; 3 + 29 = 32, which is less than 63, so we can fold.
318     %fold_cst:gpr(s64) = G_CONSTANT i64 29
319     %fold_me:gpr(s64) = G_LSHR %copy, %fold_cst
321     %and:gpr(s64) = G_AND %fold_me, %bit
322     %cmp:gpr(s32) = G_ICMP intpred(ne), %and(s64), %zero
323     %cmp_trunc:gpr(s1) = G_TRUNC %cmp(s32)
324     G_BRCOND %cmp_trunc(s1), %bb.1
325     G_BR %bb.0
326   bb.1:
327     RET_ReallyLR
331 name:            dont_fold_lshr
332 alignment:       4
333 legalized:       true
334 regBankSelected: true
335 body:             |
336   ; CHECK-LABEL: name: dont_fold_lshr
337   ; CHECK: bb.0:
338   ; CHECK:   successors: %bb.0(0x40000000), %bb.1(0x40000000)
339   ; CHECK:   %copy:gpr32 = COPY $w0
340   ; CHECK:   %fold_cst:gpr32 = MOVi32imm 29
341   ; CHECK:   %fold_me:gpr32 = LSRVWr %copy, %fold_cst
342   ; CHECK:   TBNZW %fold_me, 3, %bb.1
343   ; CHECK:   B %bb.0
344   ; CHECK: bb.1:
345   ; CHECK:   RET_ReallyLR
346   bb.0:
347     successors: %bb.0, %bb.1
348     liveins: $x0
349     %copy:gpr(s32) = COPY $w0
350     %bit:gpr(s32) = G_CONSTANT i32 8
351     %zero:gpr(s32) = G_CONSTANT i32 0
353     ; We're testing a s32.
354     ; 3 + 29 = 32, which is greater than 31, so we don't fold.
355     %fold_cst:gpr(s32) = G_CONSTANT i32 29
356     %fold_me:gpr(s32) = G_LSHR %copy, %fold_cst
358     %and:gpr(s32) = G_AND %fold_me, %bit
359     %cmp:gpr(s32) = G_ICMP intpred(ne), %and(s32), %zero
360     %cmp_trunc:gpr(s1) = G_TRUNC %cmp(s32)
361     G_BRCOND %cmp_trunc(s1), %bb.1
362     G_BR %bb.0
363   bb.1:
364     RET_ReallyLR
368 name:            lshr_negative
369 alignment:       4
370 legalized:       true
371 regBankSelected: true
372 body:             |
373   ; CHECK-LABEL: name: lshr_negative
374   ; CHECK: bb.0:
375   ; CHECK:   successors: %bb.0(0x40000000), %bb.1(0x40000000)
376   ; CHECK:   %copy:gpr32 = COPY $w0
377   ; CHECK:   TBNZW %copy, 2, %bb.1
378   ; CHECK:   B %bb.0
379   ; CHECK: bb.1:
380   ; CHECK:   RET_ReallyLR
381   bb.0:
382     successors: %bb.0, %bb.1
383     liveins: $x0
384     %copy:gpr(s32) = COPY $w0
385     %bit:gpr(s32) = G_CONSTANT i32 8
386     %zero:gpr(s32) = G_CONSTANT i32 0
388     ; Constant becomes very large and wraps around. Since it's larger than the
389     ; bit width, that means the LSHR is poison, so we can still fold.
390     %fold_cst:gpr(s32) = G_CONSTANT i32 -1
391     %fold_me:gpr(s32) = G_LSHR %copy, %fold_cst
393     %and:gpr(s32) = G_AND %fold_me, %bit
394     %cmp:gpr(s32) = G_ICMP intpred(ne), %and(s32), %zero
395     %cmp_trunc:gpr(s1) = G_TRUNC %cmp(s32)
396     G_BRCOND %cmp_trunc(s1), %bb.1
397     G_BR %bb.0
398   bb.1:
399     RET_ReallyLR