[LoongArch][ISel] Check the number of sign bits in `PatGprGpr_32` (#107432)
[llvm-project.git] / llvm / test / CodeGen / AArch64 / aarch64-mull-masks.ll
blobc57c95fd3b5318b5b9cbcd1cae1b821249f1f15b
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=aarch64-none-linux-gnu < %s -o -| FileCheck %s
4 define i64 @umull(i64 %x0, i64 %x1) {
5 ; CHECK-LABEL: umull:
6 ; CHECK:       // %bb.0: // %entry
7 ; CHECK-NEXT:    umull x0, w1, w0
8 ; CHECK-NEXT:    ret
9 entry:
10   %and = and i64 %x0, 4294967295
11   %and1 = and i64 %x1, 4294967295
12   %mul = mul nuw i64 %and1, %and
13   ret i64 %mul
16 define i64 @umull2(i64 %x, i32 %y) {
17 ; CHECK-LABEL: umull2:
18 ; CHECK:       // %bb.0: // %entry
19 ; CHECK-NEXT:    umull x0, w0, w1
20 ; CHECK-NEXT:    ret
21 entry:
22   %and = and i64 %x, 4294967295
23   %conv = zext i32 %y to i64
24   %mul = mul nuw nsw i64 %and, %conv
25   ret i64 %mul
28 define i64 @umull2_commuted(i64 %x, i32 %y) {
29 ; CHECK-LABEL: umull2_commuted:
30 ; CHECK:       // %bb.0: // %entry
31 ; CHECK-NEXT:    umull x0, w0, w1
32 ; CHECK-NEXT:    ret
33 entry:
34   %and = and i64 %x, 4294967295
35   %conv = zext i32 %y to i64
36   %mul = mul nuw nsw i64 %conv, %and
37   ret i64 %mul
40 define i64 @smull(i64 %x0, i64 %x1) {
41 ; CHECK-LABEL: smull:
42 ; CHECK:       // %bb.0: // %entry
43 ; CHECK-NEXT:    smull x0, w1, w0
44 ; CHECK-NEXT:    ret
45 entry:
46   %sext = shl i64 %x0, 32
47   %conv1 = ashr exact i64 %sext, 32
48   %sext4 = shl i64 %x1, 32
49   %conv3 = ashr exact i64 %sext4, 32
50   %mul = mul nsw i64 %conv3, %conv1
51   ret i64 %mul
54 define i64 @smull2(i64 %x, i32 %y) {
55 ; CHECK-LABEL: smull2:
56 ; CHECK:       // %bb.0: // %entry
57 ; CHECK-NEXT:    smull x0, w0, w1
58 ; CHECK-NEXT:    ret
59 entry:
60   %shl = shl i64 %x, 32
61   %shr = ashr exact i64 %shl, 32
62   %conv = sext i32 %y to i64
63   %mul = mul nsw i64 %shr, %conv
64   ret i64 %mul
67 define i64 @smull2_commuted(i64 %x, i32 %y) {
68 ; CHECK-LABEL: smull2_commuted:
69 ; CHECK:       // %bb.0: // %entry
70 ; CHECK-NEXT:    smull x0, w0, w1
71 ; CHECK-NEXT:    ret
72 entry:
73   %shl = shl i64 %x, 32
74   %shr = ashr exact i64 %shl, 32
75   %conv = sext i32 %y to i64
76   %mul = mul nsw i64 %conv, %shr
77   ret i64 %mul
80 define i64 @smull_ldrsb_b(ptr %x0, i8 %x1) {
81 ; CHECK-LABEL: smull_ldrsb_b:
82 ; CHECK:       // %bb.0: // %entry
83 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
84 ; CHECK-NEXT:    ldrsb x8, [x0]
85 ; CHECK-NEXT:    sxtb x9, w1
86 ; CHECK-NEXT:    smull x0, w8, w9
87 ; CHECK-NEXT:    ret
88 entry:
89   %ext64 = load i8, ptr %x0
90   %sext = sext i8 %ext64 to i64
91   %sext4 = sext i8 %x1 to i64
92   %mul = mul i64 %sext, %sext4
93   ret i64 %mul
96 define i64 @smull_ldrsb_b_commuted(ptr %x0, i8 %x1) {
97 ; CHECK-LABEL: smull_ldrsb_b_commuted:
98 ; CHECK:       // %bb.0: // %entry
99 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
100 ; CHECK-NEXT:    ldrsb x8, [x0]
101 ; CHECK-NEXT:    sxtb x9, w1
102 ; CHECK-NEXT:    smull x0, w9, w8
103 ; CHECK-NEXT:    ret
104 entry:
105   %ext64 = load i8, ptr %x0
106   %sext = sext i8 %ext64 to i64
107   %sext4 = sext i8 %x1 to i64
108   %mul = mul i64 %sext4, %sext
109   ret i64 %mul
112 define i64 @smull_ldrsb_h(ptr %x0, i16 %x1) {
113 ; CHECK-LABEL: smull_ldrsb_h:
114 ; CHECK:       // %bb.0: // %entry
115 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
116 ; CHECK-NEXT:    ldrsb x8, [x0]
117 ; CHECK-NEXT:    sxth x9, w1
118 ; CHECK-NEXT:    smull x0, w8, w9
119 ; CHECK-NEXT:    ret
120 entry:
121   %ext64 = load i8, ptr %x0
122   %sext = sext i8 %ext64 to i64
123   %sext4 = sext i16 %x1 to i64
124   %mul = mul i64 %sext, %sext4
125   ret i64 %mul
128 define i64 @smull_ldrsb_w(ptr %x0, i32 %x1) {
129 ; CHECK-LABEL: smull_ldrsb_w:
130 ; CHECK:       // %bb.0: // %entry
131 ; CHECK-NEXT:    ldrsb x8, [x0]
132 ; CHECK-NEXT:    smull x0, w8, w1
133 ; CHECK-NEXT:    ret
134 entry:
135   %ext64 = load i8, ptr %x0
136   %sext = sext i8 %ext64 to i64
137   %sext4 = sext i32 %x1 to i64
138   %mul = mul i64 %sext, %sext4
139   ret i64 %mul
142 define i64 @smull_ldrsh_b(ptr %x0, i8 %x1) {
143 ; CHECK-LABEL: smull_ldrsh_b:
144 ; CHECK:       // %bb.0: // %entry
145 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
146 ; CHECK-NEXT:    ldrsh x8, [x0]
147 ; CHECK-NEXT:    sxtb x9, w1
148 ; CHECK-NEXT:    smull x0, w8, w9
149 ; CHECK-NEXT:    ret
150 entry:
151   %ext64 = load i16, ptr %x0
152   %sext = sext i16 %ext64 to i64
153   %sext4 = sext i8 %x1 to i64
154   %mul = mul i64 %sext, %sext4
155   ret i64 %mul
158 define i64 @smull_ldrsh_h(ptr %x0, i16 %x1) {
159 ; CHECK-LABEL: smull_ldrsh_h:
160 ; CHECK:       // %bb.0: // %entry
161 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
162 ; CHECK-NEXT:    ldrsh x8, [x0]
163 ; CHECK-NEXT:    sxth x9, w1
164 ; CHECK-NEXT:    smull x0, w8, w9
165 ; CHECK-NEXT:    ret
166 entry:
167   %ext64 = load i16, ptr %x0
168   %sext = sext i16 %ext64 to i64
169   %sext4 = sext i16 %x1 to i64
170   %mul = mul i64 %sext, %sext4
171   ret i64 %mul
174 define i64 @smull_ldrsh_h_commuted(ptr %x0, i16 %x1) {
175 ; CHECK-LABEL: smull_ldrsh_h_commuted:
176 ; CHECK:       // %bb.0: // %entry
177 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
178 ; CHECK-NEXT:    ldrsh x8, [x0]
179 ; CHECK-NEXT:    sxth x9, w1
180 ; CHECK-NEXT:    smull x0, w9, w8
181 ; CHECK-NEXT:    ret
182 entry:
183   %ext64 = load i16, ptr %x0
184   %sext = sext i16 %ext64 to i64
185   %sext4 = sext i16 %x1 to i64
186   %mul = mul i64 %sext4, %sext
187   ret i64 %mul
190 define i64 @smull_ldrsh_w(ptr %x0, i32 %x1) {
191 ; CHECK-LABEL: smull_ldrsh_w:
192 ; CHECK:       // %bb.0: // %entry
193 ; CHECK-NEXT:    ldrsh x8, [x0]
194 ; CHECK-NEXT:    smull x0, w8, w1
195 ; CHECK-NEXT:    ret
196 entry:
197   %ext64 = load i16, ptr %x0
198   %sext = sext i16 %ext64 to i64
199   %sext4 = sext i32 %x1 to i64
200   %mul = mul i64 %sext, %sext4
201   ret i64 %mul
204 define i64 @smull_ldrsw_b(ptr %x0, i8 %x1) {
205 ; CHECK-LABEL: smull_ldrsw_b:
206 ; CHECK:       // %bb.0: // %entry
207 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
208 ; CHECK-NEXT:    ldrsw x8, [x0]
209 ; CHECK-NEXT:    sxtb x9, w1
210 ; CHECK-NEXT:    smull x0, w8, w9
211 ; CHECK-NEXT:    ret
212 entry:
213   %ext64 = load i32, ptr %x0
214   %sext = sext i32 %ext64 to i64
215   %sext4 = sext i8 %x1 to i64
216   %mul = mul i64 %sext, %sext4
217   ret i64 %mul
220 define i64 @smull_ldrsw_h(ptr %x0, i16 %x1) {
221 ; CHECK-LABEL: smull_ldrsw_h:
222 ; CHECK:       // %bb.0: // %entry
223 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
224 ; CHECK-NEXT:    ldrsw x8, [x0]
225 ; CHECK-NEXT:    sxth x9, w1
226 ; CHECK-NEXT:    smull x0, w8, w9
227 ; CHECK-NEXT:    ret
228 entry:
229   %ext64 = load i32, ptr %x0
230   %sext = sext i32 %ext64 to i64
231   %sext4 = sext i16 %x1 to i64
232   %mul = mul i64 %sext, %sext4
233   ret i64 %mul
236 define i64 @smull_ldrsw_w(ptr %x0, i32 %x1) {
237 ; CHECK-LABEL: smull_ldrsw_w:
238 ; CHECK:       // %bb.0: // %entry
239 ; CHECK-NEXT:    ldrsw x8, [x0]
240 ; CHECK-NEXT:    smull x0, w8, w1
241 ; CHECK-NEXT:    ret
242 entry:
243   %ext64 = load i32, ptr %x0
244   %sext = sext i32 %ext64 to i64
245   %sext4 = sext i32 %x1 to i64
246   %mul = mul i64 %sext, %sext4
247   ret i64 %mul
250 define i64 @smull_ldrsw_w_commuted(ptr %x0, i32 %x1) {
251 ; CHECK-LABEL: smull_ldrsw_w_commuted:
252 ; CHECK:       // %bb.0: // %entry
253 ; CHECK-NEXT:    ldrsw x8, [x0]
254 ; CHECK-NEXT:    smull x0, w8, w1
255 ; CHECK-NEXT:    ret
256 entry:
257   %ext64 = load i32, ptr %x0
258   %sext = sext i32 %ext64 to i64
259   %sext4 = sext i32 %x1 to i64
260   %mul = mul i64 %sext4, %sext
261   ret i64 %mul
264 define i64 @smull_sext_bb(i8 %x0, i8 %x1) {
265 ; CHECK-LABEL: smull_sext_bb:
266 ; CHECK:       // %bb.0: // %entry
267 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
268 ; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
269 ; CHECK-NEXT:    sxtb x8, w0
270 ; CHECK-NEXT:    sxtb x9, w1
271 ; CHECK-NEXT:    smull x0, w8, w9
272 ; CHECK-NEXT:    ret
273 entry:
274   %sext = sext i8 %x0 to i64
275   %sext4 = sext i8 %x1 to i64
276   %mul = mul i64 %sext, %sext4
277   ret i64 %mul
280 define i64 @smull_ldrsw_shift(ptr %x0, i64 %x1) {
281 ; CHECK-LABEL: smull_ldrsw_shift:
282 ; CHECK:       // %bb.0: // %entry
283 ; CHECK-NEXT:    ldrsw x8, [x0]
284 ; CHECK-NEXT:    smull x0, w8, w1
285 ; CHECK-NEXT:    ret
286 entry:
287   %ext64 = load i32, ptr %x0
288   %sext = sext i32 %ext64 to i64
289   %shl = shl i64 %x1, 32
290   %shr = ashr exact i64 %shl, 32
291   %mul = mul i64 %sext, %shr
292   ret i64 %mul
295 define i64 @smull_ldrsh_zextw(ptr %x0, i32 %x1) {
296 ; CHECK-LABEL: smull_ldrsh_zextw:
297 ; CHECK:       // %bb.0: // %entry
298 ; CHECK-NEXT:    ldrsh x8, [x0]
299 ; CHECK-NEXT:    mov w9, w1
300 ; CHECK-NEXT:    mul x0, x8, x9
301 ; CHECK-NEXT:    ret
302 entry:
303   %ext64 = load i16, ptr %x0
304   %sext = sext i16 %ext64 to i64
305   %zext = zext i32 %x1 to i64
306   %mul = mul i64 %sext, %zext
307   ret i64 %mul
310 define i64 @smull_ldrsw_zexth(ptr %x0, i16 %x1) {
311 ; CHECK-LABEL: smull_ldrsw_zexth:
312 ; CHECK:       // %bb.0: // %entry
313 ; CHECK-NEXT:    ldrsw x8, [x0]
314 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
315 ; CHECK-NEXT:    and x9, x1, #0xffff
316 ; CHECK-NEXT:    smull x0, w8, w9
317 ; CHECK-NEXT:    ret
318 entry:
319   %ext64 = load i32, ptr %x0
320   %sext = sext i32 %ext64 to i64
321   %zext = zext i16 %x1 to i64
322   %mul = mul i64 %sext, %zext
323   ret i64 %mul
326 define i64 @smull_ldrsw_zextb(ptr %x0, i8 %x1) {
327 ; CHECK-LABEL: smull_ldrsw_zextb:
328 ; CHECK:       // %bb.0: // %entry
329 ; CHECK-NEXT:    ldrsw x8, [x0]
330 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
331 ; CHECK-NEXT:    and x9, x1, #0xff
332 ; CHECK-NEXT:    smull x0, w8, w9
333 ; CHECK-NEXT:    ret
334 entry:
335   %ext64 = load i32, ptr %x0
336   %sext = sext i32 %ext64 to i64
337   %zext = zext i8 %x1 to i64
338   %mul = mul i64 %sext, %zext
339   ret i64 %mul
342 define i64 @smull_ldrsw_zextb_commuted(ptr %x0, i8 %x1) {
343 ; CHECK-LABEL: smull_ldrsw_zextb_commuted:
344 ; CHECK:       // %bb.0: // %entry
345 ; CHECK-NEXT:    ldrsw x8, [x0]
346 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
347 ; CHECK-NEXT:    and x9, x1, #0xff
348 ; CHECK-NEXT:    smull x0, w9, w8
349 ; CHECK-NEXT:    ret
350 entry:
351   %ext64 = load i32, ptr %x0
352   %sext = sext i32 %ext64 to i64
353   %zext = zext i8 %x1 to i64
354   %mul = mul i64 %zext, %sext
355   ret i64 %mul
358 define i64 @smaddl_ldrsb_h(ptr %x0, i16 %x1, i64 %x2) {
359 ; CHECK-LABEL: smaddl_ldrsb_h:
360 ; CHECK:       // %bb.0: // %entry
361 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
362 ; CHECK-NEXT:    ldrsb x8, [x0]
363 ; CHECK-NEXT:    sxth x9, w1
364 ; CHECK-NEXT:    smaddl x0, w8, w9, x2
365 ; CHECK-NEXT:    ret
366 entry:
367   %ext64 = load i8, ptr %x0
368   %sext = sext i8 %ext64 to i64
369   %sext4 = sext i16 %x1 to i64
370   %mul = mul i64 %sext, %sext4
371   %add = add i64 %x2, %mul
372   ret i64 %add
375 define i64 @smaddl_ldrsb_h_commuted(ptr %x0, i16 %x1, i64 %x2) {
376 ; CHECK-LABEL: smaddl_ldrsb_h_commuted:
377 ; CHECK:       // %bb.0: // %entry
378 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
379 ; CHECK-NEXT:    ldrsb x8, [x0]
380 ; CHECK-NEXT:    sxth x9, w1
381 ; CHECK-NEXT:    smaddl x0, w9, w8, x2
382 ; CHECK-NEXT:    ret
383 entry:
384   %ext64 = load i8, ptr %x0
385   %sext = sext i8 %ext64 to i64
386   %sext4 = sext i16 %x1 to i64
387   %mul = mul i64 %sext4, %sext
388   %add = add i64 %x2, %mul
389   ret i64 %add
392 define i64 @smaddl_ldrsh_w(ptr %x0, i32 %x1, i64 %x2) {
393 ; CHECK-LABEL: smaddl_ldrsh_w:
394 ; CHECK:       // %bb.0: // %entry
395 ; CHECK-NEXT:    ldrsh x8, [x0]
396 ; CHECK-NEXT:    smaddl x0, w8, w1, x2
397 ; CHECK-NEXT:    ret
398 entry:
399   %ext64 = load i16, ptr %x0
400   %sext = sext i16 %ext64 to i64
401   %sext4 = sext i32 %x1 to i64
402   %mul = mul i64 %sext, %sext4
403   %add = add i64 %x2, %mul
404   ret i64 %add
407 define i64 @smaddl_ldrsh_w_commuted(ptr %x0, i32 %x1, i64 %x2) {
408 ; CHECK-LABEL: smaddl_ldrsh_w_commuted:
409 ; CHECK:       // %bb.0: // %entry
410 ; CHECK-NEXT:    ldrsh x8, [x0]
411 ; CHECK-NEXT:    smaddl x0, w8, w1, x2
412 ; CHECK-NEXT:    ret
413 entry:
414   %ext64 = load i16, ptr %x0
415   %sext = sext i16 %ext64 to i64
416   %sext4 = sext i32 %x1 to i64
417   %mul = mul i64 %sext4, %sext
418   %add = add i64 %x2, %mul
419   ret i64 %add
422 define i64 @smaddl_ldrsw_b(ptr %x0, i8 %x1, i64 %x2) {
423 ; CHECK-LABEL: smaddl_ldrsw_b:
424 ; CHECK:       // %bb.0:
425 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
426 ; CHECK-NEXT:    ldrsw x8, [x0]
427 ; CHECK-NEXT:    sxtb x9, w1
428 ; CHECK-NEXT:    smaddl x0, w8, w9, x2
429 ; CHECK-NEXT:    ret
430   %ext64 = load i32, ptr %x0
431   %sext = sext i32 %ext64 to i64
432   %sext2 = sext i8 %x1 to i64
433   %mul = mul i64 %sext, %sext2
434   %add = add i64 %x2, %mul
435   ret i64 %add
438 define i64 @smaddl_ldrsw_b_commuted(ptr %x0, i8 %x1, i64 %x2) {
439 ; CHECK-LABEL: smaddl_ldrsw_b_commuted:
440 ; CHECK:       // %bb.0:
441 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
442 ; CHECK-NEXT:    ldrsw x8, [x0]
443 ; CHECK-NEXT:    sxtb x9, w1
444 ; CHECK-NEXT:    smaddl x0, w9, w8, x2
445 ; CHECK-NEXT:    ret
446   %ext64 = load i32, ptr %x0
447   %sext = sext i32 %ext64 to i64
448   %sext2 = sext i8 %x1 to i64
449   %mul = mul i64 %sext2, %sext
450   %add = add i64 %x2, %mul
451   ret i64 %add
454 define i64 @smaddl_ldrsw_ldrsw(ptr %x0, ptr %x1, i64 %x2) {
455 ; CHECK-LABEL: smaddl_ldrsw_ldrsw:
456 ; CHECK:       // %bb.0: // %entry
457 ; CHECK-NEXT:    ldrsw x8, [x0]
458 ; CHECK-NEXT:    ldrsw x9, [x1]
459 ; CHECK-NEXT:    smaddl x0, w8, w9, x2
460 ; CHECK-NEXT:    ret
461 entry:
462   %ext64 = load i32, ptr %x0
463   %ext64_2 = load i32, ptr %x1
464   %sext = sext i32 %ext64 to i64
465   %sext2 = sext i32 %ext64_2 to i64
466   %mul = mul i64 %sext, %sext2
467   %add = add i64 %x2, %mul
468   ret i64 %add
471 define i64 @smaddl_sext_hh(i16 %x0, i16 %x1, i64 %x2) {
472 ; CHECK-LABEL: smaddl_sext_hh:
473 ; CHECK:       // %bb.0: // %entry
474 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
475 ; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
476 ; CHECK-NEXT:    sxth x8, w0
477 ; CHECK-NEXT:    sxth x9, w1
478 ; CHECK-NEXT:    smaddl x0, w8, w9, x2
479 ; CHECK-NEXT:    ret
480 entry:
481   %sext = sext i16 %x0 to i64
482   %sext2 = sext i16 %x1 to i64
483   %mul = mul i64 %sext, %sext2
484   %add = add i64 %x2, %mul
485   ret i64 %add
488 define i64 @smaddl_ldrsw_shift(ptr %x0, i64 %x1, i64 %x2) {
489 ; CHECK-LABEL: smaddl_ldrsw_shift:
490 ; CHECK:       // %bb.0: // %entry
491 ; CHECK-NEXT:    ldrsw x8, [x0]
492 ; CHECK-NEXT:    smaddl x0, w8, w1, x2
493 ; CHECK-NEXT:    ret
494 entry:
495   %ext64 = load i32, ptr %x0
496   %sext = sext i32 %ext64 to i64
497   %shl = shl i64 %x1, 32
498   %shr = ashr exact i64 %shl, 32
499   %mul = mul i64 %sext, %shr
500   %add = add i64 %x2, %mul
501   ret i64 %add
504 define i64 @smaddl_ldrsw_zextb(ptr %x0, i8 %x1, i64 %x2) {
505 ; CHECK-LABEL: smaddl_ldrsw_zextb:
506 ; CHECK:       // %bb.0: // %entry
507 ; CHECK-NEXT:    ldrsw x8, [x0]
508 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
509 ; CHECK-NEXT:    and x9, x1, #0xff
510 ; CHECK-NEXT:    smaddl x0, w8, w9, x2
511 ; CHECK-NEXT:    ret
512 entry:
513   %ext64 = load i32, ptr %x0
514   %sext = sext i32 %ext64 to i64
515   %zext = zext i8 %x1 to i64
516   %mul = mul i64 %sext, %zext
517   %add = add i64 %x2, %mul
518   ret i64 %add
521 define i64 @smnegl_ldrsb_h(ptr %x0, i16 %x1) {
522 ; CHECK-LABEL: smnegl_ldrsb_h:
523 ; CHECK:       // %bb.0: // %entry
524 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
525 ; CHECK-NEXT:    ldrsb x8, [x0]
526 ; CHECK-NEXT:    sxth x9, w1
527 ; CHECK-NEXT:    smnegl x0, w8, w9
528 ; CHECK-NEXT:    ret
529 entry:
530   %ext64 = load i8, ptr %x0
531   %sext = sext i8 %ext64 to i64
532   %sext4 = sext i16 %x1 to i64
533   %mul = mul i64 %sext, %sext4
534   %sub = sub i64 0, %mul
535   ret i64 %sub
538 define i64 @smnegl_ldrsb_h_commuted(ptr %x0, i16 %x1) {
539 ; CHECK-LABEL: smnegl_ldrsb_h_commuted:
540 ; CHECK:       // %bb.0: // %entry
541 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
542 ; CHECK-NEXT:    ldrsb x8, [x0]
543 ; CHECK-NEXT:    sxth x9, w1
544 ; CHECK-NEXT:    smnegl x0, w9, w8
545 ; CHECK-NEXT:    ret
546 entry:
547   %ext64 = load i8, ptr %x0
548   %sext = sext i8 %ext64 to i64
549   %sext4 = sext i16 %x1 to i64
550   %mul = mul i64 %sext4, %sext
551   %sub = sub i64 0, %mul
552   ret i64 %sub
555 define i64 @smnegl_ldrsh_w(ptr %x0, i32 %x1) {
556 ; CHECK-LABEL: smnegl_ldrsh_w:
557 ; CHECK:       // %bb.0: // %entry
558 ; CHECK-NEXT:    ldrsh x8, [x0]
559 ; CHECK-NEXT:    smnegl x0, w8, w1
560 ; CHECK-NEXT:    ret
561 entry:
562   %ext64 = load i16, ptr %x0
563   %sext = sext i16 %ext64 to i64
564   %sext4 = sext i32 %x1 to i64
565   %mul = mul i64 %sext, %sext4
566   %sub = sub i64 0, %mul
567   ret i64 %sub
570 define i64 @smnegl_ldrsh_w_commuted(ptr %x0, i32 %x1) {
571 ; CHECK-LABEL: smnegl_ldrsh_w_commuted:
572 ; CHECK:       // %bb.0: // %entry
573 ; CHECK-NEXT:    ldrsh x8, [x0]
574 ; CHECK-NEXT:    smnegl x0, w8, w1
575 ; CHECK-NEXT:    ret
576 entry:
577   %ext64 = load i16, ptr %x0
578   %sext = sext i16 %ext64 to i64
579   %sext4 = sext i32 %x1 to i64
580   %mul = mul i64 %sext4, %sext
581   %sub = sub i64 0, %mul
582   ret i64 %sub
585 define i64 @smnegl_ldrsw_b(ptr %x0, i8 %x1) {
586 ; CHECK-LABEL: smnegl_ldrsw_b:
587 ; CHECK:       // %bb.0:
588 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
589 ; CHECK-NEXT:    ldrsw x8, [x0]
590 ; CHECK-NEXT:    sxtb x9, w1
591 ; CHECK-NEXT:    smnegl x0, w8, w9
592 ; CHECK-NEXT:    ret
593   %ext64 = load i32, ptr %x0
594   %sext = sext i32 %ext64 to i64
595   %sext2 = sext i8 %x1 to i64
596   %mul = mul i64 %sext, %sext2
597   %sub = sub i64 0, %mul
598   ret i64 %sub
601 define i64 @smnegl_ldrsw_b_commuted(ptr %x0, i8 %x1) {
602 ; CHECK-LABEL: smnegl_ldrsw_b_commuted:
603 ; CHECK:       // %bb.0:
604 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
605 ; CHECK-NEXT:    ldrsw x8, [x0]
606 ; CHECK-NEXT:    sxtb x9, w1
607 ; CHECK-NEXT:    smnegl x0, w9, w8
608 ; CHECK-NEXT:    ret
609   %ext64 = load i32, ptr %x0
610   %sext = sext i32 %ext64 to i64
611   %sext2 = sext i8 %x1 to i64
612   %mul = mul i64 %sext2, %sext
613   %sub = sub i64 0, %mul
614   ret i64 %sub
617 define i64 @smnegl_ldrsw_ldrsw(ptr %x0, ptr %x1) {
618 ; CHECK-LABEL: smnegl_ldrsw_ldrsw:
619 ; CHECK:       // %bb.0: // %entry
620 ; CHECK-NEXT:    ldrsw x8, [x0]
621 ; CHECK-NEXT:    ldrsw x9, [x1]
622 ; CHECK-NEXT:    smnegl x0, w8, w9
623 ; CHECK-NEXT:    ret
624 entry:
625   %ext64 = load i32, ptr %x0
626   %ext64_2 = load i32, ptr %x1
627   %sext = sext i32 %ext64 to i64
628   %sext2 = sext i32 %ext64_2 to i64
629   %mul = mul i64 %sext, %sext2
630   %sub = sub i64 0, %mul
631   ret i64 %sub
634 define i64 @smnegl_sext_hh(i16 %x0, i16 %x1) {
635 ; CHECK-LABEL: smnegl_sext_hh:
636 ; CHECK:       // %bb.0: // %entry
637 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
638 ; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
639 ; CHECK-NEXT:    sxth x8, w0
640 ; CHECK-NEXT:    sxth x9, w1
641 ; CHECK-NEXT:    smnegl x0, w8, w9
642 ; CHECK-NEXT:    ret
643 entry:
644   %sext = sext i16 %x0 to i64
645   %sext2 = sext i16 %x1 to i64
646   %mul = mul i64 %sext, %sext2
647   %sub = sub i64 0, %mul
648   ret i64 %sub
651 define i64 @smnegl_ldrsw_shift(ptr %x0, i64 %x1) {
652 ; CHECK-LABEL: smnegl_ldrsw_shift:
653 ; CHECK:       // %bb.0: // %entry
654 ; CHECK-NEXT:    ldrsw x8, [x0]
655 ; CHECK-NEXT:    smnegl x0, w8, w1
656 ; CHECK-NEXT:    ret
657 entry:
658   %ext64 = load i32, ptr %x0
659   %sext = sext i32 %ext64 to i64
660   %shl = shl i64 %x1, 32
661   %shr = ashr exact i64 %shl, 32
662   %mul = mul i64 %sext, %shr
663   %sub = sub i64 0, %mul
664   ret i64 %sub
667 define i64 @smnegl_ldrsw_zextb(ptr %x0, i8 %x1) {
668 ; CHECK-LABEL: smnegl_ldrsw_zextb:
669 ; CHECK:       // %bb.0: // %entry
670 ; CHECK-NEXT:    ldrsw x8, [x0]
671 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
672 ; CHECK-NEXT:    and x9, x1, #0xff
673 ; CHECK-NEXT:    smnegl x0, w8, w9
674 ; CHECK-NEXT:    ret
675 entry:
676   %ext64 = load i32, ptr %x0
677   %sext = sext i32 %ext64 to i64
678   %zext = zext i8 %x1 to i64
679   %mul = mul i64 %sext, %zext
680   %sub = sub i64 0, %mul
681   ret i64 %sub
684 define i64 @smsubl_ldrsb_h(ptr %x0, i16 %x1, i64 %x2) {
685 ; CHECK-LABEL: smsubl_ldrsb_h:
686 ; CHECK:       // %bb.0: // %entry
687 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
688 ; CHECK-NEXT:    ldrsb x8, [x0]
689 ; CHECK-NEXT:    sxth x9, w1
690 ; CHECK-NEXT:    smsubl x0, w8, w9, x2
691 ; CHECK-NEXT:    ret
692 entry:
693   %ext64 = load i8, ptr %x0
694   %sext = sext i8 %ext64 to i64
695   %sext4 = sext i16 %x1 to i64
696   %mul = mul i64 %sext, %sext4
697   %sub = sub i64 %x2, %mul
698   ret i64 %sub
701 define i64 @smsubl_ldrsb_h_commuted(ptr %x0, i16 %x1, i64 %x2) {
702 ; CHECK-LABEL: smsubl_ldrsb_h_commuted:
703 ; CHECK:       // %bb.0: // %entry
704 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
705 ; CHECK-NEXT:    ldrsb x8, [x0]
706 ; CHECK-NEXT:    sxth x9, w1
707 ; CHECK-NEXT:    smsubl x0, w9, w8, x2
708 ; CHECK-NEXT:    ret
709 entry:
710   %ext64 = load i8, ptr %x0
711   %sext = sext i8 %ext64 to i64
712   %sext4 = sext i16 %x1 to i64
713   %mul = mul i64 %sext4, %sext
714   %sub = sub i64 %x2, %mul
715   ret i64 %sub
718 define i64 @smsubl_ldrsh_w(ptr %x0, i32 %x1, i64 %x2) {
719 ; CHECK-LABEL: smsubl_ldrsh_w:
720 ; CHECK:       // %bb.0: // %entry
721 ; CHECK-NEXT:    ldrsh x8, [x0]
722 ; CHECK-NEXT:    smsubl x0, w8, w1, x2
723 ; CHECK-NEXT:    ret
724 entry:
725   %ext64 = load i16, ptr %x0
726   %sext = sext i16 %ext64 to i64
727   %sext4 = sext i32 %x1 to i64
728   %mul = mul i64 %sext, %sext4
729   %sub = sub i64 %x2, %mul
730   ret i64 %sub
733 define i64 @smsubl_ldrsh_w_commuted(ptr %x0, i32 %x1, i64 %x2) {
734 ; CHECK-LABEL: smsubl_ldrsh_w_commuted:
735 ; CHECK:       // %bb.0: // %entry
736 ; CHECK-NEXT:    ldrsh x8, [x0]
737 ; CHECK-NEXT:    smsubl x0, w8, w1, x2
738 ; CHECK-NEXT:    ret
739 entry:
740   %ext64 = load i16, ptr %x0
741   %sext = sext i16 %ext64 to i64
742   %sext4 = sext i32 %x1 to i64
743   %mul = mul i64 %sext4, %sext
744   %sub = sub i64 %x2, %mul
745   ret i64 %sub
748 define i64 @smsubl_ldrsw_b(ptr %x0, i8 %x1, i64 %x2) {
749 ; CHECK-LABEL: smsubl_ldrsw_b:
750 ; CHECK:       // %bb.0:
751 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
752 ; CHECK-NEXT:    ldrsw x8, [x0]
753 ; CHECK-NEXT:    sxtb x9, w1
754 ; CHECK-NEXT:    smsubl x0, w8, w9, x2
755 ; CHECK-NEXT:    ret
756   %ext64 = load i32, ptr %x0
757   %sext = sext i32 %ext64 to i64
758   %sext2 = sext i8 %x1 to i64
759   %mul = mul i64 %sext, %sext2
760   %sub = sub i64 %x2, %mul
761   ret i64 %sub
764 define i64 @smsubl_ldrsw_b_commuted(ptr %x0, i8 %x1, i64 %x2) {
765 ; CHECK-LABEL: smsubl_ldrsw_b_commuted:
766 ; CHECK:       // %bb.0:
767 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
768 ; CHECK-NEXT:    ldrsw x8, [x0]
769 ; CHECK-NEXT:    sxtb x9, w1
770 ; CHECK-NEXT:    smsubl x0, w9, w8, x2
771 ; CHECK-NEXT:    ret
772   %ext64 = load i32, ptr %x0
773   %sext = sext i32 %ext64 to i64
774   %sext2 = sext i8 %x1 to i64
775   %mul = mul i64 %sext2, %sext
776   %sub = sub i64 %x2, %mul
777   ret i64 %sub
780 define i64 @smsubl_ldrsw_ldrsw(ptr %x0, ptr %x1, i64 %x2) {
781 ; CHECK-LABEL: smsubl_ldrsw_ldrsw:
782 ; CHECK:       // %bb.0: // %entry
783 ; CHECK-NEXT:    ldrsw x8, [x0]
784 ; CHECK-NEXT:    ldrsw x9, [x1]
785 ; CHECK-NEXT:    smsubl x0, w8, w9, x2
786 ; CHECK-NEXT:    ret
787 entry:
788   %ext64 = load i32, ptr %x0
789   %ext64_2 = load i32, ptr %x1
790   %sext = sext i32 %ext64 to i64
791   %sext2 = sext i32 %ext64_2 to i64
792   %mul = mul i64 %sext, %sext2
793   %sub = sub i64 %x2, %mul
794   ret i64 %sub
797 define i64 @smsubl_sext_hh(i16 %x0, i16 %x1, i64 %x2) {
798 ; CHECK-LABEL: smsubl_sext_hh:
799 ; CHECK:       // %bb.0: // %entry
800 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
801 ; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
802 ; CHECK-NEXT:    sxth x8, w0
803 ; CHECK-NEXT:    sxth x9, w1
804 ; CHECK-NEXT:    smsubl x0, w8, w9, x2
805 ; CHECK-NEXT:    ret
806 entry:
807   %sext = sext i16 %x0 to i64
808   %sext2 = sext i16 %x1 to i64
809   %mul = mul i64 %sext, %sext2
810   %sub = sub i64 %x2, %mul
811   ret i64 %sub
814 define i64 @smsubl_ldrsw_shift(ptr %x0, i64 %x1, i64 %x2) {
815 ; CHECK-LABEL: smsubl_ldrsw_shift:
816 ; CHECK:       // %bb.0: // %entry
817 ; CHECK-NEXT:    ldrsw x8, [x0]
818 ; CHECK-NEXT:    smsubl x0, w8, w1, x2
819 ; CHECK-NEXT:    ret
820 entry:
821   %ext64 = load i32, ptr %x0
822   %sext = sext i32 %ext64 to i64
823   %shl = shl i64 %x1, 32
824   %shr = ashr exact i64 %shl, 32
825   %mul = mul i64 %sext, %shr
826   %sub = sub i64 %x2, %mul
827   ret i64 %sub
830 define i64 @smsubl_ldrsw_zextb(ptr %x0, i8 %x1, i64 %x2) {
831 ; CHECK-LABEL: smsubl_ldrsw_zextb:
832 ; CHECK:       // %bb.0: // %entry
833 ; CHECK-NEXT:    ldrsw x8, [x0]
834 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
835 ; CHECK-NEXT:    and x9, x1, #0xff
836 ; CHECK-NEXT:    smsubl x0, w8, w9, x2
837 ; CHECK-NEXT:    ret
838 entry:
839   %ext64 = load i32, ptr %x0
840   %sext = sext i32 %ext64 to i64
841   %zext = zext i8 %x1 to i64
842   %mul = mul i64 %sext, %zext
843   %sub = sub i64 %x2, %mul
844   ret i64 %sub
847 define i64 @smull_sext_ashr31(i32 %a, i64 %b) nounwind {
848 ; CHECK-LABEL: smull_sext_ashr31:
849 ; CHECK:       // %bb.0: // %entry
850 ; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
851 ; CHECK-NEXT:    sxtw x8, w0
852 ; CHECK-NEXT:    asr x9, x1, #31
853 ; CHECK-NEXT:    mul x0, x8, x9
854 ; CHECK-NEXT:    ret
855 entry:
856   %tmp1 = sext i32 %a to i64
857   %c = ashr i64 %b, 31
858   %tmp3 = mul i64 %tmp1, %c
859   ret i64 %tmp3
862 define i64 @smull_sext_ashr32(i32 %a, i64 %b) nounwind {
863 ; CHECK-LABEL: smull_sext_ashr32:
864 ; CHECK:       // %bb.0: // %entry
865 ; CHECK-NEXT:    asr x8, x1, #32
866 ; CHECK-NEXT:    smull x0, w8, w0
867 ; CHECK-NEXT:    ret
868 entry:
869   %tmp1 = sext i32 %a to i64
870   %c = ashr i64 %b, 32
871   %tmp3 = mul i64 %tmp1, %c
872   ret i64 %tmp3
876 define i64 @smull_ashr31_both(i64 %a, i64 %b) nounwind {
877 ; CHECK-LABEL: smull_ashr31_both:
878 ; CHECK:       // %bb.0: // %entry
879 ; CHECK-NEXT:    asr x8, x0, #31
880 ; CHECK-NEXT:    asr x9, x1, #31
881 ; CHECK-NEXT:    mul x0, x8, x9
882 ; CHECK-NEXT:    ret
883 entry:
884   %tmp1 = ashr i64 %a, 31
885   %c = ashr i64 %b, 31
886   %tmp3 = mul i64 %tmp1, %c
887   ret i64 %tmp3
890 define i64 @smull_ashr32_both(i64 %a, i64 %b) nounwind {
891 ; CHECK-LABEL: smull_ashr32_both:
892 ; CHECK:       // %bb.0: // %entry
893 ; CHECK-NEXT:    asr x8, x0, #32
894 ; CHECK-NEXT:    asr x9, x1, #32
895 ; CHECK-NEXT:    smull x0, w8, w9
896 ; CHECK-NEXT:    ret
897 entry:
898   %tmp1 = ashr i64 %a, 32
899   %c = ashr i64 %b, 32
900   %tmp3 = mul i64 %tmp1, %c
901   ret i64 %tmp3
904 define i64 @umull_ldrb_h(ptr %x0, i16 %x1) {
905 ; CHECK-LABEL: umull_ldrb_h:
906 ; CHECK:       // %bb.0: // %entry
907 ; CHECK-NEXT:    ldrb w8, [x0]
908 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
909 ; CHECK-NEXT:    and x9, x1, #0xffff
910 ; CHECK-NEXT:    umull x0, w8, w9
911 ; CHECK-NEXT:    ret
912 entry:
913   %ext64 = load i8, ptr %x0
914   %zext = zext i8 %ext64 to i64
915   %zext4 = zext i16 %x1 to i64
916   %mul = mul i64 %zext, %zext4
917   ret i64 %mul
920 define i64 @umull_ldrb_h_commuted(ptr %x0, i16 %x1) {
921 ; CHECK-LABEL: umull_ldrb_h_commuted:
922 ; CHECK:       // %bb.0: // %entry
923 ; CHECK-NEXT:    ldrb w8, [x0]
924 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
925 ; CHECK-NEXT:    and x9, x1, #0xffff
926 ; CHECK-NEXT:    umull x0, w9, w8
927 ; CHECK-NEXT:    ret
928 entry:
929   %ext64 = load i8, ptr %x0
930   %zext = zext i8 %ext64 to i64
931   %zext4 = zext i16 %x1 to i64
932   %mul = mul i64 %zext4, %zext
933   ret i64 %mul
936 define i64 @umull_ldrh_w(ptr %x0, i32 %x1) {
937 ; CHECK-LABEL: umull_ldrh_w:
938 ; CHECK:       // %bb.0: // %entry
939 ; CHECK-NEXT:    ldrh w8, [x0]
940 ; CHECK-NEXT:    umull x0, w8, w1
941 ; CHECK-NEXT:    ret
942 entry:
943   %ext64 = load i16, ptr %x0
944   %zext = zext i16 %ext64 to i64
945   %zext4 = zext i32 %x1 to i64
946   %mul = mul i64 %zext, %zext4
947   ret i64 %mul
950 define i64 @umull_ldr_b(ptr %x0, i8 %x1) {
951 ; CHECK-LABEL: umull_ldr_b:
952 ; CHECK:       // %bb.0: // %entry
953 ; CHECK-NEXT:    ldr w8, [x0]
954 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
955 ; CHECK-NEXT:    and x9, x1, #0xff
956 ; CHECK-NEXT:    umull x0, w8, w9
957 ; CHECK-NEXT:    ret
958 entry:
959   %ext64 = load i32, ptr %x0
960   %zext = zext i32 %ext64 to i64
961   %zext4 = zext i8 %x1 to i64
962   %mul = mul i64 %zext, %zext4
963   ret i64 %mul
966 define i64 @umull_ldr2_w(ptr %x0, i32 %x1) {
967 ; CHECK-LABEL: umull_ldr2_w:
968 ; CHECK:       // %bb.0: // %entry
969 ; CHECK-NEXT:    ldr w8, [x0]
970 ; CHECK-NEXT:    umull x0, w8, w1
971 ; CHECK-NEXT:    ret
972 entry:
973   %ext64 = load i64, ptr %x0
974   %and = and i64 %ext64, 4294967295
975   %zext4 = zext i32 %x1 to i64
976   %mul = mul i64 %and, %zext4
977   ret i64 %mul
980 define i64 @umull_ldr2_ldr2(ptr %x0, ptr %x1) {
981 ; CHECK-LABEL: umull_ldr2_ldr2:
982 ; CHECK:       // %bb.0: // %entry
983 ; CHECK-NEXT:    ldr w8, [x0]
984 ; CHECK-NEXT:    ldr w9, [x1]
985 ; CHECK-NEXT:    umull x0, w8, w9
986 ; CHECK-NEXT:    ret
987 entry:
988   %ext64 = load i64, ptr %x0
989   %and = and i64 %ext64, 4294967295
990   %ext64_2 = load i64, ptr %x1
991   %and2 = and i64 %ext64_2, 4294967295
992   %mul = mul i64 %and, %and2
993   ret i64 %mul
996 define i64 @umull_ldr2_d(ptr %x0, i64 %x1) {
997 ; CHECK-LABEL: umull_ldr2_d:
998 ; CHECK:       // %bb.0: // %entry
999 ; CHECK-NEXT:    ldr w8, [x0]
1000 ; CHECK-NEXT:    mov w9, w1
1001 ; CHECK-NEXT:    umull x0, w8, w9
1002 ; CHECK-NEXT:    ret
1003 entry:
1004   %ext64 = load i64, ptr %x0
1005   %and = and i64 %ext64, 4294967295
1006   %and2 = and i64 %x1, 4294967295
1007   %mul = mul i64 %and, %and2
1008   ret i64 %mul
1011 define i64 @umaddl_ldrb_h(ptr %x0, i16 %x1, i64 %x2) {
1012 ; CHECK-LABEL: umaddl_ldrb_h:
1013 ; CHECK:       // %bb.0: // %entry
1014 ; CHECK-NEXT:    ldrb w8, [x0]
1015 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
1016 ; CHECK-NEXT:    and x9, x1, #0xffff
1017 ; CHECK-NEXT:    umaddl x0, w8, w9, x2
1018 ; CHECK-NEXT:    ret
1019 entry:
1020   %ext64 = load i8, ptr %x0
1021   %zext = zext i8 %ext64 to i64
1022   %zext4 = zext i16 %x1 to i64
1023   %mul = mul i64 %zext, %zext4
1024   %add = add i64 %mul, %x2
1025   ret i64 %add
1028 define i64 @umaddl_ldrb_h_commuted(ptr %x0, i16 %x1, i64 %x2) {
1029 ; CHECK-LABEL: umaddl_ldrb_h_commuted:
1030 ; CHECK:       // %bb.0: // %entry
1031 ; CHECK-NEXT:    ldrb w8, [x0]
1032 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
1033 ; CHECK-NEXT:    and x9, x1, #0xffff
1034 ; CHECK-NEXT:    umaddl x0, w9, w8, x2
1035 ; CHECK-NEXT:    ret
1036 entry:
1037   %ext64 = load i8, ptr %x0
1038   %zext = zext i8 %ext64 to i64
1039   %zext4 = zext i16 %x1 to i64
1040   %mul = mul i64 %zext4, %zext
1041   %add = add i64 %mul, %x2
1042   ret i64 %add
1045 define i64 @umaddl_ldrh_w(ptr %x0, i32 %x1, i64 %x2) {
1046 ; CHECK-LABEL: umaddl_ldrh_w:
1047 ; CHECK:       // %bb.0: // %entry
1048 ; CHECK-NEXT:    ldrh w8, [x0]
1049 ; CHECK-NEXT:    umaddl x0, w8, w1, x2
1050 ; CHECK-NEXT:    ret
1051 entry:
1052   %ext64 = load i16, ptr %x0
1053   %zext = zext i16 %ext64 to i64
1054   %zext4 = zext i32 %x1 to i64
1055   %mul = mul i64 %zext, %zext4
1056   %add = add i64 %mul, %x2
1057   ret i64 %add
1060 define i64 @umaddl_ldr_b(ptr %x0, i8 %x1, i64 %x2) {
1061 ; CHECK-LABEL: umaddl_ldr_b:
1062 ; CHECK:       // %bb.0: // %entry
1063 ; CHECK-NEXT:    ldr w8, [x0]
1064 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
1065 ; CHECK-NEXT:    and x9, x1, #0xff
1066 ; CHECK-NEXT:    umaddl x0, w8, w9, x2
1067 ; CHECK-NEXT:    ret
1068 entry:
1069   %ext64 = load i32, ptr %x0
1070   %zext = zext i32 %ext64 to i64
1071   %zext4 = zext i8 %x1 to i64
1072   %mul = mul i64 %zext, %zext4
1073   %add = add i64 %mul, %x2
1074   ret i64 %add
1077 define i64 @umaddl_ldr2_w(ptr %x0, i32 %x1, i64 %x2) {
1078 ; CHECK-LABEL: umaddl_ldr2_w:
1079 ; CHECK:       // %bb.0: // %entry
1080 ; CHECK-NEXT:    ldr w8, [x0]
1081 ; CHECK-NEXT:    umaddl x0, w8, w1, x2
1082 ; CHECK-NEXT:    ret
1083 entry:
1084   %ext64 = load i64, ptr %x0
1085   %and = and i64 %ext64, 4294967295
1086   %zext4 = zext i32 %x1 to i64
1087   %mul = mul i64 %and, %zext4
1088   %add = add i64 %mul, %x2
1089   ret i64 %add
1092 define i64 @umaddl_ldr2_ldr2(ptr %x0, ptr %x1, i64 %x2) {
1093 ; CHECK-LABEL: umaddl_ldr2_ldr2:
1094 ; CHECK:       // %bb.0: // %entry
1095 ; CHECK-NEXT:    ldr w8, [x0]
1096 ; CHECK-NEXT:    ldr w9, [x1]
1097 ; CHECK-NEXT:    umaddl x0, w8, w9, x2
1098 ; CHECK-NEXT:    ret
1099 entry:
1100   %ext64 = load i64, ptr %x0
1101   %and = and i64 %ext64, 4294967295
1102   %ext64_2 = load i64, ptr %x1
1103   %and2 = and i64 %ext64_2, 4294967295
1104   %mul = mul i64 %and, %and2
1105   %add = add i64 %mul, %x2
1106   ret i64 %add
1109 define i64 @umaddl_ldr2_d(ptr %x0, i64 %x1, i64 %x2) {
1110 ; CHECK-LABEL: umaddl_ldr2_d:
1111 ; CHECK:       // %bb.0: // %entry
1112 ; CHECK-NEXT:    ldr w8, [x0]
1113 ; CHECK-NEXT:    mov w9, w1
1114 ; CHECK-NEXT:    umaddl x0, w8, w9, x2
1115 ; CHECK-NEXT:    ret
1116 entry:
1117   %ext64 = load i64, ptr %x0
1118   %and = and i64 %ext64, 4294967295
1119   %and2 = and i64 %x1, 4294967295
1120   %mul = mul i64 %and, %and2
1121   %add = add i64 %mul, %x2
1122   ret i64 %add
1125 define i64 @umnegl_ldrb_h(ptr %x0, i16 %x1) {
1126 ; CHECK-LABEL: umnegl_ldrb_h:
1127 ; CHECK:       // %bb.0: // %entry
1128 ; CHECK-NEXT:    ldrb w8, [x0]
1129 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
1130 ; CHECK-NEXT:    and x9, x1, #0xffff
1131 ; CHECK-NEXT:    umnegl x0, w8, w9
1132 ; CHECK-NEXT:    ret
1133 entry:
1134   %ext64 = load i8, ptr %x0
1135   %zext = zext i8 %ext64 to i64
1136   %zext4 = zext i16 %x1 to i64
1137   %mul = mul i64 %zext, %zext4
1138   %sub = sub i64 0, %mul
1139   ret i64 %sub
1142 define i64 @umnegl_ldrb_h_commuted(ptr %x0, i16 %x1) {
1143 ; CHECK-LABEL: umnegl_ldrb_h_commuted:
1144 ; CHECK:       // %bb.0: // %entry
1145 ; CHECK-NEXT:    ldrb w8, [x0]
1146 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
1147 ; CHECK-NEXT:    and x9, x1, #0xffff
1148 ; CHECK-NEXT:    umnegl x0, w9, w8
1149 ; CHECK-NEXT:    ret
1150 entry:
1151   %ext64 = load i8, ptr %x0
1152   %zext = zext i8 %ext64 to i64
1153   %zext4 = zext i16 %x1 to i64
1154   %mul = mul i64 %zext4, %zext
1155   %sub = sub i64 0, %mul
1156   ret i64 %sub
1159 define i64 @umnegl_ldrh_w(ptr %x0, i32 %x1) {
1160 ; CHECK-LABEL: umnegl_ldrh_w:
1161 ; CHECK:       // %bb.0: // %entry
1162 ; CHECK-NEXT:    ldrh w8, [x0]
1163 ; CHECK-NEXT:    umnegl x0, w8, w1
1164 ; CHECK-NEXT:    ret
1165 entry:
1166   %ext64 = load i16, ptr %x0
1167   %zext = zext i16 %ext64 to i64
1168   %zext4 = zext i32 %x1 to i64
1169   %mul = mul i64 %zext, %zext4
1170   %sub = sub i64 0, %mul
1171   ret i64 %sub
1174 define i64 @umnegl_ldr_b(ptr %x0, i8 %x1) {
1175 ; CHECK-LABEL: umnegl_ldr_b:
1176 ; CHECK:       // %bb.0: // %entry
1177 ; CHECK-NEXT:    ldr w8, [x0]
1178 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
1179 ; CHECK-NEXT:    and x9, x1, #0xff
1180 ; CHECK-NEXT:    umnegl x0, w8, w9
1181 ; CHECK-NEXT:    ret
1182 entry:
1183   %ext64 = load i32, ptr %x0
1184   %zext = zext i32 %ext64 to i64
1185   %zext4 = zext i8 %x1 to i64
1186   %mul = mul i64 %zext, %zext4
1187   %sub = sub i64 0, %mul
1188   ret i64 %sub
1191 define i64 @umnegl_ldr2_w(ptr %x0, i32 %x1) {
1192 ; CHECK-LABEL: umnegl_ldr2_w:
1193 ; CHECK:       // %bb.0: // %entry
1194 ; CHECK-NEXT:    ldr w8, [x0]
1195 ; CHECK-NEXT:    umnegl x0, w8, w1
1196 ; CHECK-NEXT:    ret
1197 entry:
1198   %ext64 = load i64, ptr %x0
1199   %and = and i64 %ext64, 4294967295
1200   %zext4 = zext i32 %x1 to i64
1201   %mul = mul i64 %and, %zext4
1202   %sub = sub i64 0, %mul
1203   ret i64 %sub
1206 define i64 @umnegl_ldr2_ldr2(ptr %x0, ptr %x1) {
1207 ; CHECK-LABEL: umnegl_ldr2_ldr2:
1208 ; CHECK:       // %bb.0: // %entry
1209 ; CHECK-NEXT:    ldr w8, [x0]
1210 ; CHECK-NEXT:    ldr w9, [x1]
1211 ; CHECK-NEXT:    umnegl x0, w8, w9
1212 ; CHECK-NEXT:    ret
1213 entry:
1214   %ext64 = load i64, ptr %x0
1215   %and = and i64 %ext64, 4294967295
1216   %ext64_2 = load i64, ptr %x1
1217   %and2 = and i64 %ext64_2, 4294967295
1218   %mul = mul i64 %and, %and2
1219   %sub = sub i64 0, %mul
1220   ret i64 %sub
1223 define i64 @umnegl_ldr2_d(ptr %x0, i64 %x1) {
1224 ; CHECK-LABEL: umnegl_ldr2_d:
1225 ; CHECK:       // %bb.0: // %entry
1226 ; CHECK-NEXT:    ldr w8, [x0]
1227 ; CHECK-NEXT:    mov w9, w1
1228 ; CHECK-NEXT:    umnegl x0, w8, w9
1229 ; CHECK-NEXT:    ret
1230 entry:
1231   %ext64 = load i64, ptr %x0
1232   %and = and i64 %ext64, 4294967295
1233   %and2 = and i64 %x1, 4294967295
1234   %mul = mul i64 %and, %and2
1235   %sub = sub i64 0, %mul
1236   ret i64 %sub
1239 define i64 @umsubl_ldrb_h(ptr %x0, i16 %x1, i64 %x2) {
1240 ; CHECK-LABEL: umsubl_ldrb_h:
1241 ; CHECK:       // %bb.0: // %entry
1242 ; CHECK-NEXT:    ldrb w8, [x0]
1243 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
1244 ; CHECK-NEXT:    and x9, x1, #0xffff
1245 ; CHECK-NEXT:    umsubl x0, w8, w9, x2
1246 ; CHECK-NEXT:    ret
1247 entry:
1248   %ext64 = load i8, ptr %x0
1249   %zext = zext i8 %ext64 to i64
1250   %zext4 = zext i16 %x1 to i64
1251   %mul = mul i64 %zext, %zext4
1252   %sub = sub i64 %x2, %mul
1253   ret i64 %sub
1256 define i64 @umsubl_ldrb_h_commuted(ptr %x0, i16 %x1, i64 %x2) {
1257 ; CHECK-LABEL: umsubl_ldrb_h_commuted:
1258 ; CHECK:       // %bb.0: // %entry
1259 ; CHECK-NEXT:    ldrb w8, [x0]
1260 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
1261 ; CHECK-NEXT:    and x9, x1, #0xffff
1262 ; CHECK-NEXT:    umsubl x0, w9, w8, x2
1263 ; CHECK-NEXT:    ret
1264 entry:
1265   %ext64 = load i8, ptr %x0
1266   %zext = zext i8 %ext64 to i64
1267   %zext4 = zext i16 %x1 to i64
1268   %mul = mul i64 %zext4, %zext
1269   %sub = sub i64 %x2, %mul
1270   ret i64 %sub
1273 define i64 @umsubl_ldrh_w(ptr %x0, i32 %x1, i64 %x2) {
1274 ; CHECK-LABEL: umsubl_ldrh_w:
1275 ; CHECK:       // %bb.0: // %entry
1276 ; CHECK-NEXT:    ldrh w8, [x0]
1277 ; CHECK-NEXT:    umsubl x0, w8, w1, x2
1278 ; CHECK-NEXT:    ret
1279 entry:
1280   %ext64 = load i16, ptr %x0
1281   %zext = zext i16 %ext64 to i64
1282   %zext4 = zext i32 %x1 to i64
1283   %mul = mul i64 %zext, %zext4
1284   %sub = sub i64 %x2, %mul
1285   ret i64 %sub
1288 define i64 @umsubl_ldr_b(ptr %x0, i8 %x1, i64 %x2) {
1289 ; CHECK-LABEL: umsubl_ldr_b:
1290 ; CHECK:       // %bb.0: // %entry
1291 ; CHECK-NEXT:    ldr w8, [x0]
1292 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
1293 ; CHECK-NEXT:    and x9, x1, #0xff
1294 ; CHECK-NEXT:    umsubl x0, w8, w9, x2
1295 ; CHECK-NEXT:    ret
1296 entry:
1297   %ext64 = load i32, ptr %x0
1298   %zext = zext i32 %ext64 to i64
1299   %zext4 = zext i8 %x1 to i64
1300   %mul = mul i64 %zext, %zext4
1301   %sub = sub i64 %x2, %mul
1302   ret i64 %sub
1305 define i64 @umsubl_ldr2_w(ptr %x0, i32 %x1, i64 %x2) {
1306 ; CHECK-LABEL: umsubl_ldr2_w:
1307 ; CHECK:       // %bb.0: // %entry
1308 ; CHECK-NEXT:    ldr w8, [x0]
1309 ; CHECK-NEXT:    umsubl x0, w8, w1, x2
1310 ; CHECK-NEXT:    ret
1311 entry:
1312   %ext64 = load i64, ptr %x0
1313   %and = and i64 %ext64, 4294967295
1314   %zext4 = zext i32 %x1 to i64
1315   %mul = mul i64 %and, %zext4
1316   %sub = sub i64 %x2, %mul
1317   ret i64 %sub
1320 define i64 @umsubl_ldr2_ldr2(ptr %x0, ptr %x1, i64 %x2) {
1321 ; CHECK-LABEL: umsubl_ldr2_ldr2:
1322 ; CHECK:       // %bb.0: // %entry
1323 ; CHECK-NEXT:    ldr w8, [x0]
1324 ; CHECK-NEXT:    ldr w9, [x1]
1325 ; CHECK-NEXT:    umsubl x0, w8, w9, x2
1326 ; CHECK-NEXT:    ret
1327 entry:
1328   %ext64 = load i64, ptr %x0
1329   %and = and i64 %ext64, 4294967295
1330   %ext64_2 = load i64, ptr %x1
1331   %and2 = and i64 %ext64_2, 4294967295
1332   %mul = mul i64 %and, %and2
1333   %sub = sub i64 %x2, %mul
1334   ret i64 %sub
1337 define i64 @umsubl_ldr2_d(ptr %x0, i64 %x1, i64 %x2) {
1338 ; CHECK-LABEL: umsubl_ldr2_d:
1339 ; CHECK:       // %bb.0: // %entry
1340 ; CHECK-NEXT:    ldr w8, [x0]
1341 ; CHECK-NEXT:    mov w9, w1
1342 ; CHECK-NEXT:    umsubl x0, w8, w9, x2
1343 ; CHECK-NEXT:    ret
1344 entry:
1345   %ext64 = load i64, ptr %x0
1346   %and = and i64 %ext64, 4294967295
1347   %and2 = and i64 %x1, 4294967295
1348   %mul = mul i64 %and, %and2
1349   %sub = sub i64 %x2, %mul
1350   ret i64 %sub
1353 define i64 @umull_ldr2_w_cc1(ptr %x0, i32 %x1) {
1354 ; CHECK-LABEL: umull_ldr2_w_cc1:
1355 ; CHECK:       // %bb.0: // %entry
1356 ; CHECK-NEXT:    ldr x8, [x0]
1357 ; CHECK-NEXT:    and x8, x8, #0x7fffffff
1358 ; CHECK-NEXT:    umull x0, w8, w1
1359 ; CHECK-NEXT:    ret
1360 entry:
1361   %ext64 = load i64, ptr %x0
1362   %and = and i64 %ext64, 2147483647
1363   %zext4 = zext i32 %x1 to i64
1364   %mul = mul i64 %and, %zext4
1365   ret i64 %mul
1368 define i64 @umull_ldr2_w_cc2(ptr %x0, i32 %x1) {
1369 ; CHECK-LABEL: umull_ldr2_w_cc2:
1370 ; CHECK:       // %bb.0: // %entry
1371 ; CHECK-NEXT:    ldr x8, [x0]
1372 ; CHECK-NEXT:    mov w9, w1
1373 ; CHECK-NEXT:    and x8, x8, #0x1ffffffff
1374 ; CHECK-NEXT:    mul x0, x8, x9
1375 ; CHECK-NEXT:    ret
1376 entry:
1377   %ext64 = load i64, ptr %x0
1378   %and = and i64 %ext64, 8589934591
1379   %zext4 = zext i32 %x1 to i64
1380   %mul = mul i64 %and, %zext4
1381   ret i64 %mul
1384 define i64 @regression_umsubl(i64 %a, i32 %b, i64 %c) {
1385 ; CHECK-LABEL: regression_umsubl:
1386 ; CHECK:       // %bb.0: // %entry
1387 ; CHECK-NEXT:    mov w8, w1
1388 ; CHECK-NEXT:    udiv x9, x0, x8
1389 ; CHECK-NEXT:    msub x0, x9, x8, x2
1390 ; CHECK-NEXT:    ret
1391 entry:
1392   %zext1 = zext i32 %b to i64
1393   %res = udiv i64 %a, %zext1
1394   %mul = mul i64 %res, %zext1
1395   %sub = sub i64 %c, %mul
1396   ret i64 %sub
1399 define i64 @umull_and_lshr(i64 %x) {
1400 ; CHECK-LABEL: umull_and_lshr:
1401 ; CHECK:       // %bb.0:
1402 ; CHECK-NEXT:    lsr x8, x0, #32
1403 ; CHECK-NEXT:    mov w9, w0
1404 ; CHECK-NEXT:    umull x0, w9, w8
1405 ; CHECK-NEXT:    ret
1406     %lo = and i64 %x, u0xffffffff
1407     %hi = lshr i64 %x, 32
1408     %mul = mul i64 %lo, %hi
1409     ret i64 %mul
1412 define i64 @umull_and_and(i64 %x, i64 %y) {
1413 ; CHECK-LABEL: umull_and_and:
1414 ; CHECK:       // %bb.0:
1415 ; CHECK-NEXT:    umull x0, w0, w1
1416 ; CHECK-NEXT:    ret
1417     %lo = and i64 %x, u0xffffffff
1418     %hi = and i64 %y, u0xffffffff
1419     %mul = mul i64 %lo, %hi
1420     ret i64 %mul
1423 define i64 @umaddl_and_lshr(i64 %x, i64 %a) {
1424 ; CHECK-LABEL: umaddl_and_lshr:
1425 ; CHECK:       // %bb.0:
1426 ; CHECK-NEXT:    lsr x8, x0, #32
1427 ; CHECK-NEXT:    mov w9, w0
1428 ; CHECK-NEXT:    umaddl x0, w9, w8, x1
1429 ; CHECK-NEXT:    ret
1430     %lo = and i64 %x, u0xffffffff
1431     %hi = lshr i64 %x, 32
1432     %mul = mul i64 %lo, %hi
1433     %add = add i64 %a, %mul
1434     ret i64 %add
1437 define i64 @umaddl_and_and(i64 %x, i64 %y, i64 %a) {
1438 ; CHECK-LABEL: umaddl_and_and:
1439 ; CHECK:       // %bb.0:
1440 ; CHECK-NEXT:    mov w8, w0
1441 ; CHECK-NEXT:    mov w9, w1
1442 ; CHECK-NEXT:    umaddl x0, w8, w9, x2
1443 ; CHECK-NEXT:    ret
1444     %lo = and i64 %x, u0xffffffff
1445     %hi = and i64 %y, u0xffffffff
1446     %mul = mul i64 %lo, %hi
1447     %add = add i64 %a, %mul
1448     ret i64 %add
1451 ; Check which can contain multiple copies that should all be removed.
1452 define i32 @f(i32 %0) {
1453 entry:
1454   %1 = sext i32 %0 to i64
1455   br label %A
1458   %2 = trunc i64 %1 to i32
1459   %a69.us = sub i32 0, %2
1460   %a69.us.fr = freeze i32 %a69.us
1461   %3 = zext i32 %a69.us.fr to i64
1462   br label %B
1465   %t = icmp eq i64 0, %3
1466   br i1 %t, label %A, label %B