[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / sve2-int-mul.ll
blob800888b7e6cb97abf84a798442250f8d428f434e
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve2 < %s | FileCheck %s
5 ; MUL with SPLAT
7 define <vscale x 8 x i16> @mul_i16_imm(<vscale x 8 x i16> %a) {
8 ; CHECK-LABEL: mul_i16_imm:
9 ; CHECK:       // %bb.0:
10 ; CHECK-NEXT:    mov z1.h, #255 // =0xff
11 ; CHECK-NEXT:    mul z0.h, z0.h, z1.h
12 ; CHECK-NEXT:    ret
13   %elt = insertelement <vscale x 8 x i16> undef, i16 255, i32 0
14   %splat = shufflevector <vscale x 8 x i16> %elt, <vscale x 8 x i16> undef, <vscale x 8 x i32> zeroinitializer
15   %res = mul <vscale x 8 x i16> %a, %splat
16   ret <vscale x 8 x i16> %res
19 define <vscale x 8 x i16> @mul_i16_imm_neg(<vscale x 8 x i16> %a) {
20 ; CHECK-LABEL: mul_i16_imm_neg:
21 ; CHECK:       // %bb.0:
22 ; CHECK-NEXT:    mov w8, #-200
23 ; CHECK-NEXT:    mov z1.h, w8
24 ; CHECK-NEXT:    mul z0.h, z0.h, z1.h
25 ; CHECK-NEXT:    ret
26   %elt = insertelement <vscale x 8 x i16> undef, i16 -200, i32 0
27   %splat = shufflevector <vscale x 8 x i16> %elt, <vscale x 8 x i16> undef, <vscale x 8 x i32> zeroinitializer
28   %res = mul <vscale x 8 x i16> %a, %splat
29   ret <vscale x 8 x i16> %res
32 define <vscale x 4 x i32> @mul_i32_imm(<vscale x 4 x i32> %a) {
33 ; CHECK-LABEL: mul_i32_imm:
34 ; CHECK:       // %bb.0:
35 ; CHECK-NEXT:    mov z1.s, #255 // =0xff
36 ; CHECK-NEXT:    mul z0.s, z0.s, z1.s
37 ; CHECK-NEXT:    ret
38   %elt = insertelement <vscale x 4 x i32> undef, i32 255, i32 0
39   %splat = shufflevector <vscale x 4 x i32> %elt, <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer
40   %res = mul <vscale x 4 x i32> %a, %splat
41   ret <vscale x 4 x i32> %res
44 define <vscale x 4 x i32> @mul_i32_imm_neg(<vscale x 4 x i32> %a) {
45 ; CHECK-LABEL: mul_i32_imm_neg:
46 ; CHECK:       // %bb.0:
47 ; CHECK-NEXT:    mov w8, #-200
48 ; CHECK-NEXT:    mov z1.s, w8
49 ; CHECK-NEXT:    mul z0.s, z0.s, z1.s
50 ; CHECK-NEXT:    ret
51   %elt = insertelement <vscale x 4 x i32> undef, i32 -200, i32 0
52   %splat = shufflevector <vscale x 4 x i32> %elt, <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer
53   %res = mul <vscale x 4 x i32> %a, %splat
54   ret <vscale x 4 x i32> %res
57 define <vscale x 2 x i64> @mul_i64_imm(<vscale x 2 x i64> %a) {
58 ; CHECK-LABEL: mul_i64_imm:
59 ; CHECK:       // %bb.0:
60 ; CHECK-NEXT:    mov z1.d, #255 // =0xff
61 ; CHECK-NEXT:    mul z0.d, z0.d, z1.d
62 ; CHECK-NEXT:    ret
63   %elt = insertelement <vscale x 2 x i64> undef, i64 255, i32 0
64   %splat = shufflevector <vscale x 2 x i64> %elt, <vscale x 2 x i64> undef, <vscale x 2 x i32> zeroinitializer
65   %res = mul <vscale x 2 x i64> %a, %splat
66   ret <vscale x 2 x i64> %res
69 define <vscale x 2 x i64> @mul_i64_imm_neg(<vscale x 2 x i64> %a) {
70 ; CHECK-LABEL: mul_i64_imm_neg:
71 ; CHECK:       // %bb.0:
72 ; CHECK-NEXT:    mov x8, #-200
73 ; CHECK-NEXT:    mov z1.d, x8
74 ; CHECK-NEXT:    mul z0.d, z0.d, z1.d
75 ; CHECK-NEXT:    ret
76   %elt = insertelement <vscale x 2 x i64> undef, i64 -200, i32 0
77   %splat = shufflevector <vscale x 2 x i64> %elt, <vscale x 2 x i64> undef, <vscale x 2 x i32> zeroinitializer
78   %res = mul <vscale x 2 x i64> %a, %splat
79   ret <vscale x 2 x i64> %res
83 ; MUL (vector, unpredicated)
85 define <vscale x 16 x i8> @mul_i8(<vscale x 16 x i8> %a,
86 ; CHECK-LABEL: mul_i8:
87 ; CHECK:       // %bb.0:
88 ; CHECK-NEXT:    mul z0.b, z0.b, z1.b
89 ; CHECK-NEXT:    ret
90                                   <vscale x 16 x i8> %b) {
91   %res = mul <vscale x 16 x i8> %a, %b
92   ret <vscale x 16 x i8> %res
95 define <vscale x 8 x i16> @mul_i16(<vscale x 8 x i16> %a,
96 ; CHECK-LABEL: mul_i16:
97 ; CHECK:       // %bb.0:
98 ; CHECK-NEXT:    mul z0.h, z0.h, z1.h
99 ; CHECK-NEXT:    ret
100                                   <vscale x 8 x i16> %b) {
101   %res = mul <vscale x 8 x i16> %a, %b
102   ret <vscale x 8 x i16> %res
105 define <vscale x 4 x i32> @mul_i32(<vscale x 4 x i32> %a,
106 ; CHECK-LABEL: mul_i32:
107 ; CHECK:       // %bb.0:
108 ; CHECK-NEXT:    mul z0.s, z0.s, z1.s
109 ; CHECK-NEXT:    ret
110                                   <vscale x 4 x i32> %b) {
111   %res = mul <vscale x 4 x i32> %a, %b
112   ret <vscale x 4 x i32> %res
115 define <vscale x 2 x i64> @mul_i64(<vscale x 2 x i64> %a,
116 ; CHECK-LABEL: mul_i64:
117 ; CHECK:       // %bb.0:
118 ; CHECK-NEXT:    mul z0.d, z0.d, z1.d
119 ; CHECK-NEXT:    ret
120                                   <vscale x 2 x i64> %b) {
121   %res = mul <vscale x 2 x i64> %a, %b
122   ret <vscale x 2 x i64> %res
126 ; SMULH (vector, unpredicated)
128 define <vscale x 16 x i8> @smulh_i8(<vscale x 16 x i8> %a,
129 ; CHECK-LABEL: smulh_i8:
130 ; CHECK:       // %bb.0:
131 ; CHECK-NEXT:    smulh z0.b, z0.b, z1.b
132 ; CHECK-NEXT:    ret
133                                     <vscale x 16 x i8> %b) {
134   %sel = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 31)
135   %res = call <vscale x 16 x i8> @llvm.aarch64.sve.smulh.u.nxv16i8(<vscale x 16 x i1> %sel, <vscale x 16 x i8> %a,
136                                                                    <vscale x 16 x i8> %b)
137   ret <vscale x 16 x i8> %res
140 define <vscale x 8 x i16> @smulh_i16(<vscale x 8 x i16> %a,
141 ; CHECK-LABEL: smulh_i16:
142 ; CHECK:       // %bb.0:
143 ; CHECK-NEXT:    smulh z0.h, z0.h, z1.h
144 ; CHECK-NEXT:    ret
145                                      <vscale x 8 x i16> %b) {
146   %sel = call <vscale x 8 x i1> @llvm.aarch64.sve.ptrue.nxv8i1(i32 31)
147   %res = call <vscale x 8 x i16> @llvm.aarch64.sve.smulh.u.nxv8i16(<vscale x 8 x i1> %sel, <vscale x 8 x i16> %a,
148                                                                    <vscale x 8 x i16> %b)
149   ret <vscale x 8 x i16> %res
152 define <vscale x 4 x i32> @smulh_i32(<vscale x 4 x i32> %a,
153 ; CHECK-LABEL: smulh_i32:
154 ; CHECK:       // %bb.0:
155 ; CHECK-NEXT:    smulh z0.s, z0.s, z1.s
156 ; CHECK-NEXT:    ret
157                                      <vscale x 4 x i32> %b) {
158   %sel = call <vscale x 4 x i1> @llvm.aarch64.sve.ptrue.nxv4i1(i32 31)
159   %res = call <vscale x 4 x i32> @llvm.aarch64.sve.smulh.u.nxv4i32(<vscale x 4 x i1> %sel, <vscale x 4 x i32> %a,
160                                                                    <vscale x 4 x i32> %b)
161   ret <vscale x 4 x i32> %res
164 define <vscale x 2 x i64> @smulh_i64(<vscale x 2 x i64> %a,
165 ; CHECK-LABEL: smulh_i64:
166 ; CHECK:       // %bb.0:
167 ; CHECK-NEXT:    smulh z0.d, z0.d, z1.d
168 ; CHECK-NEXT:    ret
169                                      <vscale x 2 x i64> %b) {
170   %sel = call <vscale x 2 x i1> @llvm.aarch64.sve.ptrue.nxv2i1(i32 31)
171   %res = call <vscale x 2 x i64> @llvm.aarch64.sve.smulh.u.nxv2i64(<vscale x 2 x i1> %sel, <vscale x 2 x i64> %a,
172                                                                    <vscale x 2 x i64> %b)
173   ret <vscale x 2 x i64> %res
177 ; UMULH (vector, unpredicated)
179 define <vscale x 16 x i8> @umulh_i8(<vscale x 16 x i8> %a,
180 ; CHECK-LABEL: umulh_i8:
181 ; CHECK:       // %bb.0:
182 ; CHECK-NEXT:    umulh z0.b, z0.b, z1.b
183 ; CHECK-NEXT:    ret
184                                     <vscale x 16 x i8> %b) {
185   %sel = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 31)
186   %res = call <vscale x 16 x i8> @llvm.aarch64.sve.umulh.u.nxv16i8(<vscale x 16 x i1> %sel, <vscale x 16 x i8> %a,
187                                                                    <vscale x 16 x i8> %b)
188   ret <vscale x 16 x i8> %res
191 define <vscale x 8 x i16> @umulh_i16(<vscale x 8 x i16> %a,
192 ; CHECK-LABEL: umulh_i16:
193 ; CHECK:       // %bb.0:
194 ; CHECK-NEXT:    umulh z0.h, z0.h, z1.h
195 ; CHECK-NEXT:    ret
196                                      <vscale x 8 x i16> %b) {
197   %sel = call <vscale x 8 x i1> @llvm.aarch64.sve.ptrue.nxv8i1(i32 31)
198   %res = call <vscale x 8 x i16> @llvm.aarch64.sve.umulh.u.nxv8i16(<vscale x 8 x i1> %sel, <vscale x 8 x i16> %a,
199                                                                    <vscale x 8 x i16> %b)
200   ret <vscale x 8 x i16> %res
203 define <vscale x 4 x i32> @umulh_i32(<vscale x 4 x i32> %a,
204 ; CHECK-LABEL: umulh_i32:
205 ; CHECK:       // %bb.0:
206 ; CHECK-NEXT:    umulh z0.s, z0.s, z1.s
207 ; CHECK-NEXT:    ret
208                                      <vscale x 4 x i32> %b) {
209   %sel = call <vscale x 4 x i1> @llvm.aarch64.sve.ptrue.nxv4i1(i32 31)
210   %res = call <vscale x 4 x i32> @llvm.aarch64.sve.umulh.u.nxv4i32(<vscale x 4 x i1> %sel, <vscale x 4 x i32> %a,
211                                                                    <vscale x 4 x i32> %b)
212   ret <vscale x 4 x i32> %res
215 define <vscale x 2 x i64> @umulh_i64(<vscale x 2 x i64> %a,
216 ; CHECK-LABEL: umulh_i64:
217 ; CHECK:       // %bb.0:
218 ; CHECK-NEXT:    umulh z0.d, z0.d, z1.d
219 ; CHECK-NEXT:    ret
220                                      <vscale x 2 x i64> %b) {
221   %sel = call <vscale x 2 x i1> @llvm.aarch64.sve.ptrue.nxv2i1(i32 31)
222   %res = call <vscale x 2 x i64> @llvm.aarch64.sve.umulh.u.nxv2i64(<vscale x 2 x i1> %sel, <vscale x 2 x i64> %a,
223                                                                    <vscale x 2 x i64> %b)
224   ret <vscale x 2 x i64> %res
228 ; PMUL (vector, unpredicated)
230 define <vscale x 16 x i8> @pmul_i8(<vscale x 16 x i8> %a,
231 ; CHECK-LABEL: pmul_i8:
232 ; CHECK:       // %bb.0:
233 ; CHECK-NEXT:    pmul z0.b, z0.b, z1.b
234 ; CHECK-NEXT:    ret
235                                    <vscale x 16 x i8> %b) {
236   %res = call <vscale x 16 x i8> @llvm.aarch64.sve.pmul.nxv16i8(<vscale x 16 x i8> %a,
237                                                                 <vscale x 16 x i8> %b)
238   ret <vscale x 16 x i8> %res
242 ; SQDMULH (vector, unpredicated)
244 define <vscale x 16 x i8> @sqdmulh_i8(<vscale x 16 x i8> %a,
245 ; CHECK-LABEL: sqdmulh_i8:
246 ; CHECK:       // %bb.0:
247 ; CHECK-NEXT:    sqdmulh z0.b, z0.b, z1.b
248 ; CHECK-NEXT:    ret
249                                       <vscale x 16 x i8> %b) {
250   %res = call <vscale x 16 x i8> @llvm.aarch64.sve.sqdmulh.nxv16i8(<vscale x 16 x i8> %a,
251                                                                    <vscale x 16 x i8> %b)
252   ret <vscale x 16 x i8> %res
255 define <vscale x 8 x i16> @sqdmulh_i16(<vscale x 8 x i16> %a,
256 ; CHECK-LABEL: sqdmulh_i16:
257 ; CHECK:       // %bb.0:
258 ; CHECK-NEXT:    sqdmulh z0.h, z0.h, z1.h
259 ; CHECK-NEXT:    ret
260                                        <vscale x 8 x i16> %b) {
261   %res = call <vscale x 8 x i16> @llvm.aarch64.sve.sqdmulh.nxv8i16(<vscale x 8 x i16> %a,
262                                                                    <vscale x 8 x i16> %b)
263   ret <vscale x 8 x i16> %res
266 define <vscale x 4 x i32> @sqdmulh_i32(<vscale x 4 x i32> %a,
267 ; CHECK-LABEL: sqdmulh_i32:
268 ; CHECK:       // %bb.0:
269 ; CHECK-NEXT:    sqdmulh z0.s, z0.s, z1.s
270 ; CHECK-NEXT:    ret
271                                        <vscale x 4 x i32> %b) {
272   %res = call <vscale x 4 x i32> @llvm.aarch64.sve.sqdmulh.nxv4i32(<vscale x 4 x i32> %a,
273                                                                    <vscale x 4 x i32> %b)
274   ret <vscale x 4 x i32> %res
277 define <vscale x 2 x i64> @sqdmulh_i64(<vscale x 2 x i64> %a,
278 ; CHECK-LABEL: sqdmulh_i64:
279 ; CHECK:       // %bb.0:
280 ; CHECK-NEXT:    sqdmulh z0.d, z0.d, z1.d
281 ; CHECK-NEXT:    ret
282                                        <vscale x 2 x i64> %b) {
283   %res = call <vscale x 2 x i64> @llvm.aarch64.sve.sqdmulh.nxv2i64(<vscale x 2 x i64> %a,
284                                                                    <vscale x 2 x i64> %b)
285   ret <vscale x 2 x i64> %res
289 ; SQRDMULH (vector, unpredicated)
291 define <vscale x 16 x i8> @sqrdmulh_i8(<vscale x 16 x i8> %a,
292 ; CHECK-LABEL: sqrdmulh_i8:
293 ; CHECK:       // %bb.0:
294 ; CHECK-NEXT:    sqrdmulh z0.b, z0.b, z1.b
295 ; CHECK-NEXT:    ret
296                                        <vscale x 16 x i8> %b) {
297   %res = call <vscale x 16 x i8> @llvm.aarch64.sve.sqrdmulh.nxv16i8(<vscale x 16 x i8> %a,
298                                                                     <vscale x 16 x i8> %b)
299   ret <vscale x 16 x i8> %res
302 define <vscale x 8 x i16> @sqrdmulh_i16(<vscale x 8 x i16> %a,
303 ; CHECK-LABEL: sqrdmulh_i16:
304 ; CHECK:       // %bb.0:
305 ; CHECK-NEXT:    sqrdmulh z0.h, z0.h, z1.h
306 ; CHECK-NEXT:    ret
307                                         <vscale x 8 x i16> %b) {
308   %res = call <vscale x 8 x i16> @llvm.aarch64.sve.sqrdmulh.nxv8i16(<vscale x 8 x i16> %a,
309                                                                     <vscale x 8 x i16> %b)
310   ret <vscale x 8 x i16> %res
313 define <vscale x 4 x i32> @sqrdmulh_i32(<vscale x 4 x i32> %a,
314 ; CHECK-LABEL: sqrdmulh_i32:
315 ; CHECK:       // %bb.0:
316 ; CHECK-NEXT:    sqrdmulh z0.s, z0.s, z1.s
317 ; CHECK-NEXT:    ret
318                                         <vscale x 4 x i32> %b) {
319   %res = call <vscale x 4 x i32> @llvm.aarch64.sve.sqrdmulh.nxv4i32(<vscale x 4 x i32> %a,
320                                                                     <vscale x 4 x i32> %b)
321   ret <vscale x 4 x i32> %res
324 define <vscale x 2 x i64> @sqrdmulh_i64(<vscale x 2 x i64> %a,
325 ; CHECK-LABEL: sqrdmulh_i64:
326 ; CHECK:       // %bb.0:
327 ; CHECK-NEXT:    sqrdmulh z0.d, z0.d, z1.d
328 ; CHECK-NEXT:    ret
329                                         <vscale x 2 x i64> %b) {
330   %res = call <vscale x 2 x i64> @llvm.aarch64.sve.sqrdmulh.nxv2i64(<vscale x 2 x i64> %a,
331                                                                     <vscale x 2 x i64> %b)
332   ret <vscale x 2 x i64> %res
335 declare <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32)
336 declare <vscale x 8 x i1> @llvm.aarch64.sve.ptrue.nxv8i1(i32)
337 declare <vscale x 4 x i1> @llvm.aarch64.sve.ptrue.nxv4i1(i32)
338 declare <vscale x 2 x i1> @llvm.aarch64.sve.ptrue.nxv2i1(i32)
339 declare <vscale x 16 x  i8> @llvm.aarch64.sve.smulh.u.nxv16i8(<vscale x 16 x i1>, <vscale x 16 x  i8>, <vscale x 16 x  i8>)
340 declare <vscale x  8 x i16> @llvm.aarch64.sve.smulh.u.nxv8i16(<vscale x  8 x i1>, <vscale x  8 x i16>, <vscale x  8 x i16>)
341 declare <vscale x  4 x i32> @llvm.aarch64.sve.smulh.u.nxv4i32(<vscale x  4 x i1>, <vscale x  4 x i32>, <vscale x  4 x i32>)
342 declare <vscale x  2 x i64> @llvm.aarch64.sve.smulh.u.nxv2i64(<vscale x  2 x i1>, <vscale x  2 x i64>, <vscale x  2 x i64>)
343 declare <vscale x 16 x  i8> @llvm.aarch64.sve.umulh.u.nxv16i8(<vscale x 16 x i1>, <vscale x 16 x  i8>, <vscale x 16 x  i8>)
344 declare <vscale x  8 x i16> @llvm.aarch64.sve.umulh.u.nxv8i16(<vscale x  8 x i1>, <vscale x  8 x i16>, <vscale x  8 x i16>)
345 declare <vscale x  4 x i32> @llvm.aarch64.sve.umulh.u.nxv4i32(<vscale x  4 x i1>, <vscale x  4 x i32>, <vscale x  4 x i32>)
346 declare <vscale x  2 x i64> @llvm.aarch64.sve.umulh.u.nxv2i64(<vscale x  2 x i1>, <vscale x  2 x i64>, <vscale x  2 x i64>)
347 declare <vscale x 16 x i8> @llvm.aarch64.sve.pmul.nxv16i8(<vscale x 16 x i8>, <vscale x 16 x i8>)
348 declare <vscale x 16 x i8> @llvm.aarch64.sve.sqdmulh.nxv16i8(<vscale x 16 x i8>, <vscale x 16 x i8>)
349 declare <vscale x 8 x i16> @llvm.aarch64.sve.sqdmulh.nxv8i16(<vscale x 8 x i16>, <vscale x 8 x i16>)
350 declare <vscale x 4 x i32> @llvm.aarch64.sve.sqdmulh.nxv4i32(<vscale x 4 x i32>, <vscale x 4 x i32>)
351 declare <vscale x 2 x i64> @llvm.aarch64.sve.sqdmulh.nxv2i64(<vscale x 2 x i64>, <vscale x 2 x i64>)
352 declare <vscale x 16 x i8> @llvm.aarch64.sve.sqrdmulh.nxv16i8(<vscale x 16 x i8>, <vscale x 16 x i8>)
353 declare <vscale x 8 x i16> @llvm.aarch64.sve.sqrdmulh.nxv8i16(<vscale x 8 x i16>, <vscale x 8 x i16>)
354 declare <vscale x 4 x i32> @llvm.aarch64.sve.sqrdmulh.nxv4i32(<vscale x 4 x i32>, <vscale x 4 x i32>)
355 declare <vscale x 2 x i64> @llvm.aarch64.sve.sqrdmulh.nxv2i64(<vscale x 2 x i64>, <vscale x 2 x i64>)