TargetParser: AArch64: Add part numbers for Apple CPUs.
[llvm-project.git] / llvm / test / CodeGen / AArch64 / addsub_ext.ll
blob04a98bd5088803053af251a556fa9647ff7b537a
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -debugify-and-strip-all-safe -enable-machine-outliner=never -verify-machineinstrs %s -o - -mtriple=aarch64-linux-gnu -aarch64-enable-atomic-cfg-tidy=0 | FileCheck %s
3 ; RUN: llc -debugify-and-strip-all-safe -global-isel -enable-machine-outliner=never -verify-machineinstrs %s -o - -mtriple=aarch64-linux-gnu -aarch64-enable-atomic-cfg-tidy=0 | FileCheck %s
5 define i32 @add_z_i8i32(i8 %v, i32 %lhs) minsize {
6 ; CHECK-LABEL: add_z_i8i32:
7 ; CHECK:       // %bb.0:
8 ; CHECK-NEXT:    add w0, w1, w0, uxtb
9 ; CHECK-NEXT:    ret
10   %vz = zext i8 %v to i32
11   %r = add i32 %lhs, %vz
12   ret i32 %r
15 define i32 @add_z_shli8i32(i8 %v, i32 %lhs) minsize {
16 ; CHECK-LABEL: add_z_shli8i32:
17 ; CHECK:       // %bb.0:
18 ; CHECK-NEXT:    add w0, w1, w0, uxtb #3
19 ; CHECK-NEXT:    ret
20   %vz = zext i8 %v to i32
21   %s = shl i32 %vz, 3
22   %r = add i32 %lhs, %s
23   ret i32 %r
26 define i64 @add_z_i8i64(i8 %v, i64 %lhs) minsize {
27 ; CHECK-LABEL: add_z_i8i64:
28 ; CHECK:       // %bb.0:
29 ; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
30 ; CHECK-NEXT:    add x0, x1, w0, uxtb
31 ; CHECK-NEXT:    ret
32   %vz = zext i8 %v to i64
33   %r = add i64 %lhs, %vz
34   ret i64 %r
37 define i64 @add_z_shli8i64(i8 %v, i64 %lhs) minsize {
38 ; CHECK-LABEL: add_z_shli8i64:
39 ; CHECK:       // %bb.0:
40 ; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
41 ; CHECK-NEXT:    add x0, x1, w0, uxtb #3
42 ; CHECK-NEXT:    ret
43   %vz = zext i8 %v to i64
44   %s = shl i64 %vz, 3
45   %r = add i64 %lhs, %s
46   ret i64 %r
49 define i32 @add_s_i8i32(i8 %v, i32 %lhs) minsize {
50 ; CHECK-LABEL: add_s_i8i32:
51 ; CHECK:       // %bb.0:
52 ; CHECK-NEXT:    add w0, w1, w0, sxtb
53 ; CHECK-NEXT:    ret
54   %vz = sext i8 %v to i32
55   %r = add i32 %lhs, %vz
56   ret i32 %r
59 define i32 @add_s_shli8i32(i8 %v, i32 %lhs) minsize {
60 ; CHECK-LABEL: add_s_shli8i32:
61 ; CHECK:       // %bb.0:
62 ; CHECK-NEXT:    add w0, w1, w0, sxtb #3
63 ; CHECK-NEXT:    ret
64   %vz = sext i8 %v to i32
65   %s = shl i32 %vz, 3
66   %r = add i32 %lhs, %s
67   ret i32 %r
70 define i64 @add_s_i8i64(i8 %v, i64 %lhs) minsize {
71 ; CHECK-LABEL: add_s_i8i64:
72 ; CHECK:       // %bb.0:
73 ; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
74 ; CHECK-NEXT:    add x0, x1, w0, sxtb
75 ; CHECK-NEXT:    ret
76   %vz = sext i8 %v to i64
77   %r = add i64 %lhs, %vz
78   ret i64 %r
81 define i64 @add_s_shli8i64(i8 %v, i64 %lhs) minsize {
82 ; CHECK-LABEL: add_s_shli8i64:
83 ; CHECK:       // %bb.0:
84 ; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
85 ; CHECK-NEXT:    add x0, x1, w0, sxtb #3
86 ; CHECK-NEXT:    ret
87   %vz = sext i8 %v to i64
88   %s = shl i64 %vz, 3
89   %r = add i64 %lhs, %s
90   ret i64 %r
93 define i32 @add_z_i16i32(i16 %v, i32 %lhs) minsize {
94 ; CHECK-LABEL: add_z_i16i32:
95 ; CHECK:       // %bb.0:
96 ; CHECK-NEXT:    add w0, w1, w0, uxth
97 ; CHECK-NEXT:    ret
98   %vz = zext i16 %v to i32
99   %r = add i32 %lhs, %vz
100   ret i32 %r
103 define i32 @add_z_shli16i32(i16 %v, i32 %lhs) minsize {
104 ; CHECK-LABEL: add_z_shli16i32:
105 ; CHECK:       // %bb.0:
106 ; CHECK-NEXT:    add w0, w1, w0, uxth #3
107 ; CHECK-NEXT:    ret
108   %vz = zext i16 %v to i32
109   %s = shl i32 %vz, 3
110   %r = add i32 %lhs, %s
111   ret i32 %r
114 define i64 @add_z_i16i64(i16 %v, i64 %lhs) minsize {
115 ; CHECK-LABEL: add_z_i16i64:
116 ; CHECK:       // %bb.0:
117 ; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
118 ; CHECK-NEXT:    add x0, x1, w0, uxth
119 ; CHECK-NEXT:    ret
120   %vz = zext i16 %v to i64
121   %r = add i64 %lhs, %vz
122   ret i64 %r
125 define i64 @add_z_shli16i64(i16 %v, i64 %lhs) minsize {
126 ; CHECK-LABEL: add_z_shli16i64:
127 ; CHECK:       // %bb.0:
128 ; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
129 ; CHECK-NEXT:    add x0, x1, w0, uxth #3
130 ; CHECK-NEXT:    ret
131   %vz = zext i16 %v to i64
132   %s = shl i64 %vz, 3
133   %r = add i64 %lhs, %s
134   ret i64 %r
137 define i64 @add_z_i32i64(i32 %v, i64 %lhs) minsize {
138 ; CHECK-LABEL: add_z_i32i64:
139 ; CHECK:       // %bb.0:
140 ; CHECK-NEXT:    add x0, x1, w0, uxtw
141 ; CHECK-NEXT:    ret
142   %vz = zext i32 %v to i64
143   %r = add i64 %lhs, %vz
144   ret i64 %r
147 define i64 @add_z_shli32i64(i32 %v, i64 %lhs) minsize {
148 ; CHECK-LABEL: add_z_shli32i64:
149 ; CHECK:       // %bb.0:
150 ; CHECK-NEXT:    add x0, x1, w0, uxtw #3
151 ; CHECK-NEXT:    ret
152   %vz = zext i32 %v to i64
153   %s = shl i64 %vz, 3
154   %r = add i64 %lhs, %s
155   ret i64 %r
158 define i32 @add_s_i16i32(i16 %v, i32 %lhs) minsize {
159 ; CHECK-LABEL: add_s_i16i32:
160 ; CHECK:       // %bb.0:
161 ; CHECK-NEXT:    add w0, w1, w0, sxth
162 ; CHECK-NEXT:    ret
163   %vz = sext i16 %v to i32
164   %r = add i32 %lhs, %vz
165   ret i32 %r
168 define i32 @add_s_shli16i32(i16 %v, i32 %lhs) minsize {
169 ; CHECK-LABEL: add_s_shli16i32:
170 ; CHECK:       // %bb.0:
171 ; CHECK-NEXT:    add w0, w1, w0, sxth #3
172 ; CHECK-NEXT:    ret
173   %vz = sext i16 %v to i32
174   %s = shl i32 %vz, 3
175   %r = add i32 %lhs, %s
176   ret i32 %r
179 define i64 @add_s_i16i64(i16 %v, i64 %lhs) minsize {
180 ; CHECK-LABEL: add_s_i16i64:
181 ; CHECK:       // %bb.0:
182 ; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
183 ; CHECK-NEXT:    add x0, x1, w0, sxth
184 ; CHECK-NEXT:    ret
185   %vz = sext i16 %v to i64
186   %r = add i64 %lhs, %vz
187   ret i64 %r
190 define i64 @add_s_shli16i64(i16 %v, i64 %lhs) minsize {
191 ; CHECK-LABEL: add_s_shli16i64:
192 ; CHECK:       // %bb.0:
193 ; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
194 ; CHECK-NEXT:    add x0, x1, w0, sxth #3
195 ; CHECK-NEXT:    ret
196   %vz = sext i16 %v to i64
197   %s = shl i64 %vz, 3
198   %r = add i64 %lhs, %s
199   ret i64 %r
202 define i64 @add_s_i32i64(i32 %v, i64 %lhs) minsize {
203 ; CHECK-LABEL: add_s_i32i64:
204 ; CHECK:       // %bb.0:
205 ; CHECK-NEXT:    add x0, x1, w0, sxtw
206 ; CHECK-NEXT:    ret
207   %vz = sext i32 %v to i64
208   %r = add i64 %lhs, %vz
209   ret i64 %r
212 define i64 @add_s_shli32i64(i32 %v, i64 %lhs) minsize {
213 ; CHECK-LABEL: add_s_shli32i64:
214 ; CHECK:       // %bb.0:
215 ; CHECK-NEXT:    add x0, x1, w0, sxtw #3
216 ; CHECK-NEXT:    ret
217   %vz = sext i32 %v to i64
218   %s = shl i64 %vz, 3
219   %r = add i64 %lhs, %s
220   ret i64 %r
223 define i32 @sub_z_i8i32(i8 %v, i32 %lhs) minsize {
224 ; CHECK-LABEL: sub_z_i8i32:
225 ; CHECK:       // %bb.0:
226 ; CHECK-NEXT:    sub w0, w1, w0, uxtb
227 ; CHECK-NEXT:    ret
228   %vz = zext i8 %v to i32
229   %r = sub i32 %lhs, %vz
230   ret i32 %r
233 define i32 @sub_z_shli8i32(i8 %v, i32 %lhs) minsize {
234 ; CHECK-LABEL: sub_z_shli8i32:
235 ; CHECK:       // %bb.0:
236 ; CHECK-NEXT:    sub w0, w1, w0, uxtb #3
237 ; CHECK-NEXT:    ret
238   %vz = zext i8 %v to i32
239   %s = shl i32 %vz, 3
240   %r = sub i32 %lhs, %s
241   ret i32 %r
244 define i64 @sub_z_i8i64(i8 %v, i64 %lhs) minsize {
245 ; CHECK-LABEL: sub_z_i8i64:
246 ; CHECK:       // %bb.0:
247 ; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
248 ; CHECK-NEXT:    sub x0, x1, w0, uxtb
249 ; CHECK-NEXT:    ret
250   %vz = zext i8 %v to i64
251   %r = sub i64 %lhs, %vz
252   ret i64 %r
255 define i64 @sub_z_shli8i64(i8 %v, i64 %lhs) minsize {
256 ; CHECK-LABEL: sub_z_shli8i64:
257 ; CHECK:       // %bb.0:
258 ; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
259 ; CHECK-NEXT:    sub x0, x1, w0, uxtb #3
260 ; CHECK-NEXT:    ret
261   %vz = zext i8 %v to i64
262   %s = shl i64 %vz, 3
263   %r = sub i64 %lhs, %s
264   ret i64 %r
267 define i32 @sub_s_i8i32(i8 %v, i32 %lhs) minsize {
268 ; CHECK-LABEL: sub_s_i8i32:
269 ; CHECK:       // %bb.0:
270 ; CHECK-NEXT:    sub w0, w1, w0, sxtb
271 ; CHECK-NEXT:    ret
272   %vz = sext i8 %v to i32
273   %r = sub i32 %lhs, %vz
274   ret i32 %r
277 define i32 @sub_s_shli8i32(i8 %v, i32 %lhs) minsize {
278 ; CHECK-LABEL: sub_s_shli8i32:
279 ; CHECK:       // %bb.0:
280 ; CHECK-NEXT:    sub w0, w1, w0, sxtb #3
281 ; CHECK-NEXT:    ret
282   %vz = sext i8 %v to i32
283   %s = shl i32 %vz, 3
284   %r = sub i32 %lhs, %s
285   ret i32 %r
288 define i64 @sub_s_i8i64(i8 %v, i64 %lhs) minsize {
289 ; CHECK-LABEL: sub_s_i8i64:
290 ; CHECK:       // %bb.0:
291 ; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
292 ; CHECK-NEXT:    sub x0, x1, w0, sxtb
293 ; CHECK-NEXT:    ret
294   %vz = sext i8 %v to i64
295   %r = sub i64 %lhs, %vz
296   ret i64 %r
299 define i64 @sub_s_shli8i64(i8 %v, i64 %lhs) minsize {
300 ; CHECK-LABEL: sub_s_shli8i64:
301 ; CHECK:       // %bb.0:
302 ; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
303 ; CHECK-NEXT:    sub x0, x1, w0, sxtb #3
304 ; CHECK-NEXT:    ret
305   %vz = sext i8 %v to i64
306   %s = shl i64 %vz, 3
307   %r = sub i64 %lhs, %s
308   ret i64 %r
311 define i32 @sub_z_i16i32(i16 %v, i32 %lhs) minsize {
312 ; CHECK-LABEL: sub_z_i16i32:
313 ; CHECK:       // %bb.0:
314 ; CHECK-NEXT:    sub w0, w1, w0, uxth
315 ; CHECK-NEXT:    ret
316   %vz = zext i16 %v to i32
317   %r = sub i32 %lhs, %vz
318   ret i32 %r
321 define i32 @sub_z_shli16i32(i16 %v, i32 %lhs) minsize {
322 ; CHECK-LABEL: sub_z_shli16i32:
323 ; CHECK:       // %bb.0:
324 ; CHECK-NEXT:    sub w0, w1, w0, uxth #3
325 ; CHECK-NEXT:    ret
326   %vz = zext i16 %v to i32
327   %s = shl i32 %vz, 3
328   %r = sub i32 %lhs, %s
329   ret i32 %r
332 define i64 @sub_z_i16i64(i16 %v, i64 %lhs) minsize {
333 ; CHECK-LABEL: sub_z_i16i64:
334 ; CHECK:       // %bb.0:
335 ; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
336 ; CHECK-NEXT:    sub x0, x1, w0, uxth
337 ; CHECK-NEXT:    ret
338   %vz = zext i16 %v to i64
339   %r = sub i64 %lhs, %vz
340   ret i64 %r
343 define i64 @sub_z_shli16i64(i16 %v, i64 %lhs) minsize {
344 ; CHECK-LABEL: sub_z_shli16i64:
345 ; CHECK:       // %bb.0:
346 ; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
347 ; CHECK-NEXT:    sub x0, x1, w0, uxth #3
348 ; CHECK-NEXT:    ret
349   %vz = zext i16 %v to i64
350   %s = shl i64 %vz, 3
351   %r = sub i64 %lhs, %s
352   ret i64 %r
355 define i64 @sub_z_i32i64(i32 %v, i64 %lhs) minsize {
356 ; CHECK-LABEL: sub_z_i32i64:
357 ; CHECK:       // %bb.0:
358 ; CHECK-NEXT:    sub x0, x1, w0, uxtw
359 ; CHECK-NEXT:    ret
360   %vz = zext i32 %v to i64
361   %r = sub i64 %lhs, %vz
362   ret i64 %r
365 define i64 @sub_z_shli32i64(i32 %v, i64 %lhs) minsize {
366 ; CHECK-LABEL: sub_z_shli32i64:
367 ; CHECK:       // %bb.0:
368 ; CHECK-NEXT:    sub x0, x1, w0, uxtw #3
369 ; CHECK-NEXT:    ret
370   %vz = zext i32 %v to i64
371   %s = shl i64 %vz, 3
372   %r = sub i64 %lhs, %s
373   ret i64 %r
376 define i32 @sub_s_i16i32(i16 %v, i32 %lhs) minsize {
377 ; CHECK-LABEL: sub_s_i16i32:
378 ; CHECK:       // %bb.0:
379 ; CHECK-NEXT:    sub w0, w1, w0, sxth
380 ; CHECK-NEXT:    ret
381   %vz = sext i16 %v to i32
382   %r = sub i32 %lhs, %vz
383   ret i32 %r
386 define i32 @sub_s_shli16i32(i16 %v, i32 %lhs) minsize {
387 ; CHECK-LABEL: sub_s_shli16i32:
388 ; CHECK:       // %bb.0:
389 ; CHECK-NEXT:    sub w0, w1, w0, sxth #3
390 ; CHECK-NEXT:    ret
391   %vz = sext i16 %v to i32
392   %s = shl i32 %vz, 3
393   %r = sub i32 %lhs, %s
394   ret i32 %r
397 define i64 @sub_s_i16i64(i16 %v, i64 %lhs) minsize {
398 ; CHECK-LABEL: sub_s_i16i64:
399 ; CHECK:       // %bb.0:
400 ; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
401 ; CHECK-NEXT:    sub x0, x1, w0, sxth
402 ; CHECK-NEXT:    ret
403   %vz = sext i16 %v to i64
404   %r = sub i64 %lhs, %vz
405   ret i64 %r
408 define i64 @sub_s_shli16i64(i16 %v, i64 %lhs) minsize {
409 ; CHECK-LABEL: sub_s_shli16i64:
410 ; CHECK:       // %bb.0:
411 ; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
412 ; CHECK-NEXT:    sub x0, x1, w0, sxth #3
413 ; CHECK-NEXT:    ret
414   %vz = sext i16 %v to i64
415   %s = shl i64 %vz, 3
416   %r = sub i64 %lhs, %s
417   ret i64 %r
420 define i64 @sub_s_i32i64(i32 %v, i64 %lhs) minsize {
421 ; CHECK-LABEL: sub_s_i32i64:
422 ; CHECK:       // %bb.0:
423 ; CHECK-NEXT:    sub x0, x1, w0, sxtw
424 ; CHECK-NEXT:    ret
425   %vz = sext i32 %v to i64
426   %r = sub i64 %lhs, %vz
427   ret i64 %r
430 define i64 @sub_s_shli32i64(i32 %v, i64 %lhs) minsize {
431 ; CHECK-LABEL: sub_s_shli32i64:
432 ; CHECK:       // %bb.0:
433 ; CHECK-NEXT:    sub x0, x1, w0, sxtw #3
434 ; CHECK-NEXT:    ret
435   %vz = sext i32 %v to i64
436   %s = shl i64 %vz, 3
437   %r = sub i64 %lhs, %s
438   ret i64 %r
441 define i32 @cmp_s_i8i32(i8 %v, i32 %lhs) minsize {
442 ; CHECK-LABEL: cmp_s_i8i32:
443 ; CHECK:       // %bb.0:
444 ; CHECK-NEXT:    cmp w1, w0, uxtb
445 ; CHECK-NEXT:    b.ge .LBB40_2
446 ; CHECK-NEXT:  // %bb.1: // %then
447 ; CHECK-NEXT:    mov w0, #1
448 ; CHECK-NEXT:    ret
449 ; CHECK-NEXT:  .LBB40_2: // %end
450 ; CHECK-NEXT:    mov w0, w1
451 ; CHECK-NEXT:    ret
452   %vz = zext i8 %v to i32
453   %c = icmp slt i32 %lhs, %vz
454   br i1 %c, label %then, label %end
455 then:
456   ret i32 1
457 end:
458   ret i32 %lhs
461 define i64 @cmp_s_i8i64(i8 %v, i64 %lhs) minsize {
462 ; CHECK-LABEL: cmp_s_i8i64:
463 ; CHECK:       // %bb.0:
464 ; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
465 ; CHECK-NEXT:    cmp x1, w0, sxtb
466 ; CHECK-NEXT:    b.ge .LBB41_2
467 ; CHECK-NEXT:  // %bb.1: // %then
468 ; CHECK-NEXT:    mov w0, #1
469 ; CHECK-NEXT:    ret
470 ; CHECK-NEXT:  .LBB41_2: // %end
471 ; CHECK-NEXT:    mov x0, x1
472 ; CHECK-NEXT:    ret
473   %vz = sext i8 %v to i64
474   %c = icmp slt i64 %lhs, %vz
475   br i1 %c, label %then, label %end
476 then:
477   ret i64 1
478 end:
479   ret i64 %lhs
482 define i32 @cmp_s_i16i32(i16 %v, i32 %lhs) minsize {
483 ; CHECK-LABEL: cmp_s_i16i32:
484 ; CHECK:       // %bb.0:
485 ; CHECK-NEXT:    cmp w1, w0, uxth
486 ; CHECK-NEXT:    b.ge .LBB42_2
487 ; CHECK-NEXT:  // %bb.1: // %then
488 ; CHECK-NEXT:    mov w0, #1
489 ; CHECK-NEXT:    ret
490 ; CHECK-NEXT:  .LBB42_2: // %end
491 ; CHECK-NEXT:    mov w0, w1
492 ; CHECK-NEXT:    ret
493   %vz = zext i16 %v to i32
494   %c = icmp slt i32 %lhs, %vz
495   br i1 %c, label %then, label %end
496 then:
497   ret i32 1
498 end:
499   ret i32 %lhs
502 define i64 @cmp_s_i16i64(i16 %v, i64 %lhs) minsize {
503 ; CHECK-LABEL: cmp_s_i16i64:
504 ; CHECK:       // %bb.0:
505 ; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
506 ; CHECK-NEXT:    cmp x1, w0, sxth
507 ; CHECK-NEXT:    b.ge .LBB43_2
508 ; CHECK-NEXT:  // %bb.1: // %then
509 ; CHECK-NEXT:    mov w0, #1
510 ; CHECK-NEXT:    ret
511 ; CHECK-NEXT:  .LBB43_2: // %end
512 ; CHECK-NEXT:    mov x0, x1
513 ; CHECK-NEXT:    ret
514   %vz = sext i16 %v to i64
515   %c = icmp slt i64 %lhs, %vz
516   br i1 %c, label %then, label %end
517 then:
518   ret i64 1
519 end:
520   ret i64 %lhs
524 ; Check that implicit zext from w reg write is used instead of uxtw form of add.
525 define dso_local i64 @add_fold_uxtw(i32 %x, i64 %y) {
526 ; CHECK-LABEL: add_fold_uxtw:
527 ; CHECK:       // %bb.0: // %entry
528 ; CHECK-NEXT:    and w8, w0, #0x3
529 ; CHECK-NEXT:    add x0, x1, x8
530 ; CHECK-NEXT:    ret
531 entry:
532   %m = and i32 %x, 3
533   %ext = zext i32 %m to i64
534   %ret = add i64 %y, %ext
535   ret i64 %ret
538 ; Check that implicit zext from w reg write is used instead of uxtw
539 ; form of sub and that mov WZR is folded to form a neg instruction.
540 define dso_local i64 @sub_fold_uxtw_xzr(i32 %x)  {
541 ; CHECK-LABEL: sub_fold_uxtw_xzr:
542 ; CHECK:       // %bb.0: // %entry
543 ; CHECK-NEXT:    and w8, w0, #0x3
544 ; CHECK-NEXT:    neg x0, x8
545 ; CHECK-NEXT:    ret
546 entry:
547   %m = and i32 %x, 3
548   %ext = zext i32 %m to i64
549   %ret = sub i64 0, %ext
550   ret i64 %ret
553 ; Check that implicit zext from w reg write is used instead of uxtw form of subs/cmp.
554 define dso_local i1 @cmp_fold_uxtw(i32 %x, i64 %y) {
555 ; CHECK-LABEL: cmp_fold_uxtw:
556 ; CHECK:       // %bb.0: // %entry
557 ; CHECK-NEXT:    and w8, w0, #0x3
558 ; CHECK-NEXT:    cmp x1, x8
559 ; CHECK-NEXT:    cset w0, eq
560 ; CHECK-NEXT:    ret
561 entry:
562   %m = and i32 %x, 3
563   %ext = zext i32 %m to i64
564   %ret = icmp eq i64 %y, %ext
565   ret i1 %ret
568 ; Check that implicit zext from w reg write is used instead of uxtw
569 ; form of add, leading to madd selection.
570 define dso_local i64 @madd_fold_uxtw(i32 %x, i64 %y) {
571 ; CHECK-LABEL: madd_fold_uxtw:
572 ; CHECK:       // %bb.0: // %entry
573 ; CHECK-NEXT:    and w8, w0, #0x3
574 ; CHECK-NEXT:    madd x0, x1, x1, x8
575 ; CHECK-NEXT:    ret
576 entry:
577   %m = and i32 %x, 3
578   %ext = zext i32 %m to i64
579   %mul = mul i64 %y, %y
580   %ret = add i64 %mul, %ext
581   ret i64 %ret
584 ; Check that implicit zext from w reg write is used instead of uxtw
585 ; form of sub, leading to sub/cmp folding.
586 ; Check that implicit zext from w reg write is used instead of uxtw form of subs/cmp.
587 define dso_local i1 @cmp_sub_fold_uxtw(i32 %x, i64 %y, i64 %z) {
588 ; CHECK-LABEL: cmp_sub_fold_uxtw:
589 ; CHECK:       // %bb.0: // %entry
590 ; CHECK-NEXT:    and w8, w0, #0x3
591 ; CHECK-NEXT:    cmp x2, x8
592 ; CHECK-NEXT:    cset w0, eq
593 ; CHECK-NEXT:    ret
594 entry:
595   %m = and i32 %x, 3
596   %ext = zext i32 %m to i64
597   %sub = sub i64 %z, %ext
598   %ret = icmp eq i64 %sub, 0
599   ret i1 %ret
602 ; Check that implicit zext from w reg write is used instead of uxtw
603 ; form of add and add of -1 gets selected as sub.
604 define dso_local i64 @add_imm_fold_uxtw(i32 %x) {
605 ; CHECK-LABEL: add_imm_fold_uxtw:
606 ; CHECK:       // %bb.0: // %entry
607 ; CHECK-NEXT:    and w8, w0, #0x3
608 ; CHECK-NEXT:    sub x0, x8, #1
609 ; CHECK-NEXT:    ret
610 entry:
611   %m = and i32 %x, 3
612   %ext = zext i32 %m to i64
613   %ret = add i64 %ext, -1
614   ret i64 %ret
617 ; Check that implicit zext from w reg write is used instead of uxtw
618 ; form of add and add lsl form gets selected.
619 define dso_local i64 @add_lsl_fold_uxtw(i32 %x, i64 %y) {
620 ; CHECK-LABEL: add_lsl_fold_uxtw:
621 ; CHECK:       // %bb.0: // %entry
622 ; CHECK-NEXT:    orr w8, w0, #0x3
623 ; CHECK-NEXT:    add x0, x8, x1, lsl #3
624 ; CHECK-NEXT:    ret
625 entry:
626   %m = or i32 %x, 3
627   %ext = zext i32 %m to i64
628   %shift = shl i64 %y, 3
629   %ret = add i64 %ext, %shift
630   ret i64 %ret