[RISCV][VLOPT] Add vector narrowing integer right shift instructions to isSupportedIn...
[llvm-project.git] / llvm / test / CodeGen / AArch64 / sve-abd.ll
blob72790155d046fc43912e704c04711df9a6b41c61
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s | FileCheck %s
4 target triple = "aarch64-unknown-linux-gnu"
7 ; SABD
10 define <vscale x 16 x i8> @sabd_b(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b) #0 {
11 ; CHECK-LABEL: sabd_b:
12 ; CHECK:       // %bb.0:
13 ; CHECK-NEXT:    ptrue p0.b
14 ; CHECK-NEXT:    sabd z0.b, p0/m, z0.b, z1.b
15 ; CHECK-NEXT:    ret
16   %a.sext = sext <vscale x 16 x i8> %a to <vscale x 16 x i16>
17   %b.sext = sext <vscale x 16 x i8> %b to <vscale x 16 x i16>
18   %sub = sub <vscale x 16 x i16> %a.sext, %b.sext
19   %abs = call <vscale x 16 x i16> @llvm.abs.nxv16i16(<vscale x 16 x i16> %sub, i1 true)
20   %trunc = trunc <vscale x 16 x i16> %abs to <vscale x 16 x i8>
21   ret <vscale x 16 x i8> %trunc
24 define <vscale x 16 x i8> @sabd_b_promoted_ops(<vscale x 16 x i1> %a, <vscale x 16 x i1> %b) #0 {
25 ; CHECK-LABEL: sabd_b_promoted_ops:
26 ; CHECK:       // %bb.0:
27 ; CHECK-NEXT:    ptrue p2.b
28 ; CHECK-NEXT:    eor p0.b, p2/z, p0.b, p1.b
29 ; CHECK-NEXT:    mov z0.b, p0/z, #1 // =0x1
30 ; CHECK-NEXT:    ret
31   %a.sext = sext <vscale x 16 x i1> %a to <vscale x 16 x i8>
32   %b.sext = sext <vscale x 16 x i1> %b to <vscale x 16 x i8>
33   %sub = sub <vscale x 16 x i8> %a.sext, %b.sext
34   %abs = call <vscale x 16 x i8> @llvm.abs.nxv16i8(<vscale x 16 x i8> %sub, i1 true)
35   ret <vscale x 16 x i8> %abs
38 define <vscale x 8 x i16> @sabd_h(<vscale x 8 x i16> %a, <vscale x 8 x i16> %b) #0 {
39 ; CHECK-LABEL: sabd_h:
40 ; CHECK:       // %bb.0:
41 ; CHECK-NEXT:    ptrue p0.h
42 ; CHECK-NEXT:    sabd z0.h, p0/m, z0.h, z1.h
43 ; CHECK-NEXT:    ret
44   %a.sext = sext <vscale x 8 x i16> %a to <vscale x 8 x i32>
45   %b.sext = sext <vscale x 8 x i16> %b to <vscale x 8 x i32>
46   %sub = sub <vscale x 8 x i32> %a.sext, %b.sext
47   %abs = call <vscale x 8 x i32> @llvm.abs.nxv8i32(<vscale x 8 x i32> %sub, i1 true)
48   %trunc = trunc <vscale x 8 x i32> %abs to <vscale x 8 x i16>
49   ret <vscale x 8 x i16> %trunc
52 define <vscale x 8 x i16> @sabd_h_promoted_ops(<vscale x 8 x i8> %a, <vscale x 8 x i8> %b) #0 {
53 ; CHECK-LABEL: sabd_h_promoted_ops:
54 ; CHECK:       // %bb.0:
55 ; CHECK-NEXT:    ptrue p0.h
56 ; CHECK-NEXT:    sxtb z1.h, p0/m, z1.h
57 ; CHECK-NEXT:    sxtb z0.h, p0/m, z0.h
58 ; CHECK-NEXT:    sabd z0.h, p0/m, z0.h, z1.h
59 ; CHECK-NEXT:    ret
60   %a.sext = sext <vscale x 8 x i8> %a to <vscale x 8 x i16>
61   %b.sext = sext <vscale x 8 x i8> %b to <vscale x 8 x i16>
62   %sub = sub <vscale x 8 x i16> %a.sext, %b.sext
63   %abs = call <vscale x 8 x i16> @llvm.abs.nxv8i16(<vscale x 8 x i16> %sub, i1 true)
64   ret <vscale x 8 x i16> %abs
67 define <vscale x 4 x i32> @sabd_s(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b) #0 {
68 ; CHECK-LABEL: sabd_s:
69 ; CHECK:       // %bb.0:
70 ; CHECK-NEXT:    ptrue p0.s
71 ; CHECK-NEXT:    sabd z0.s, p0/m, z0.s, z1.s
72 ; CHECK-NEXT:    ret
73   %a.sext = sext <vscale x 4 x i32> %a to <vscale x 4 x i64>
74   %b.sext = sext <vscale x 4 x i32> %b to <vscale x 4 x i64>
75   %sub = sub <vscale x 4 x i64> %a.sext, %b.sext
76   %abs = call <vscale x 4 x i64> @llvm.abs.nxv4i64(<vscale x 4 x i64> %sub, i1 true)
77   %trunc = trunc <vscale x 4 x i64> %abs to <vscale x 4 x i32>
78   ret <vscale x 4 x i32> %trunc
81 define <vscale x 4 x i32> @sabd_s_promoted_ops(<vscale x 4 x i16> %a, <vscale x 4 x i16> %b) #0 {
82 ; CHECK-LABEL: sabd_s_promoted_ops:
83 ; CHECK:       // %bb.0:
84 ; CHECK-NEXT:    ptrue p0.s
85 ; CHECK-NEXT:    sxth z1.s, p0/m, z1.s
86 ; CHECK-NEXT:    sxth z0.s, p0/m, z0.s
87 ; CHECK-NEXT:    sabd z0.s, p0/m, z0.s, z1.s
88 ; CHECK-NEXT:    ret
89   %a.sext = sext <vscale x 4 x i16> %a to <vscale x 4 x i32>
90   %b.sext = sext <vscale x 4 x i16> %b to <vscale x 4 x i32>
91   %sub = sub <vscale x 4 x i32> %a.sext, %b.sext
92   %abs = call <vscale x 4 x i32> @llvm.abs.nxv4i32(<vscale x 4 x i32> %sub, i1 true)
93   ret <vscale x 4 x i32> %abs
96 define <vscale x 2 x i64> @sabd_d(<vscale x 2 x i64> %a, <vscale x 2 x i64> %b) #0 {
97 ; CHECK-LABEL: sabd_d:
98 ; CHECK:       // %bb.0:
99 ; CHECK-NEXT:    ptrue p0.d
100 ; CHECK-NEXT:    sabd z0.d, p0/m, z0.d, z1.d
101 ; CHECK-NEXT:    ret
102   %a.sext = sext <vscale x 2 x i64> %a to <vscale x 2 x i128>
103   %b.sext = sext <vscale x 2 x i64> %b to <vscale x 2 x i128>
104   %sub = sub <vscale x 2 x i128> %a.sext, %b.sext
105   %abs = call <vscale x 2 x i128> @llvm.abs.nxv2i128(<vscale x 2 x i128> %sub, i1 true)
106   %trunc = trunc <vscale x 2 x i128> %abs to <vscale x 2 x i64>
107   ret <vscale x 2 x i64> %trunc
110 define <vscale x 2 x i64> @sabd_d_promoted_ops(<vscale x 2 x i32> %a, <vscale x 2 x i32> %b) #0 {
111 ; CHECK-LABEL: sabd_d_promoted_ops:
112 ; CHECK:       // %bb.0:
113 ; CHECK-NEXT:    ptrue p0.d
114 ; CHECK-NEXT:    sxtw z1.d, p0/m, z1.d
115 ; CHECK-NEXT:    sxtw z0.d, p0/m, z0.d
116 ; CHECK-NEXT:    sabd z0.d, p0/m, z0.d, z1.d
117 ; CHECK-NEXT:    ret
118   %a.sext = sext <vscale x 2 x i32> %a to <vscale x 2 x i64>
119   %b.sext = sext <vscale x 2 x i32> %b to <vscale x 2 x i64>
120   %sub = sub <vscale x 2 x i64> %a.sext, %b.sext
121   %abs = call <vscale x 2 x i64> @llvm.abs.nxv2i64(<vscale x 2 x i64> %sub, i1 true)
122   ret <vscale x 2 x i64> %abs
126 ; UABD
129 define <vscale x 16 x i8> @uabd_b(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b) #0 {
130 ; CHECK-LABEL: uabd_b:
131 ; CHECK:       // %bb.0:
132 ; CHECK-NEXT:    ptrue p0.b
133 ; CHECK-NEXT:    uabd z0.b, p0/m, z0.b, z1.b
134 ; CHECK-NEXT:    ret
135   %a.zext = zext <vscale x 16 x i8> %a to <vscale x 16 x i16>
136   %b.zext = zext <vscale x 16 x i8> %b to <vscale x 16 x i16>
137   %sub = sub <vscale x 16 x i16> %a.zext, %b.zext
138   %abs = call <vscale x 16 x i16> @llvm.abs.nxv16i16(<vscale x 16 x i16> %sub, i1 true)
139   %trunc = trunc <vscale x 16 x i16> %abs to <vscale x 16 x i8>
140   ret <vscale x 16 x i8> %trunc
143 define <vscale x 16 x i8> @uabd_b_promoted_ops(<vscale x 16 x i1> %a, <vscale x 16 x i1> %b) #0 {
144 ; CHECK-LABEL: uabd_b_promoted_ops:
145 ; CHECK:       // %bb.0:
146 ; CHECK-NEXT:    ptrue p2.b
147 ; CHECK-NEXT:    eor p0.b, p2/z, p0.b, p1.b
148 ; CHECK-NEXT:    mov z0.b, p0/z, #1 // =0x1
149 ; CHECK-NEXT:    ret
150   %a.zext = zext <vscale x 16 x i1> %a to <vscale x 16 x i8>
151   %b.zext = zext <vscale x 16 x i1> %b to <vscale x 16 x i8>
152   %sub = sub <vscale x 16 x i8> %a.zext, %b.zext
153   %abs = call <vscale x 16 x i8> @llvm.abs.nxv16i8(<vscale x 16 x i8> %sub, i1 true)
154   ret <vscale x 16 x i8> %abs
157 define <vscale x 8 x i16> @uabd_h(<vscale x 8 x i16> %a, <vscale x 8 x i16> %b) #0 {
158 ; CHECK-LABEL: uabd_h:
159 ; CHECK:       // %bb.0:
160 ; CHECK-NEXT:    ptrue p0.h
161 ; CHECK-NEXT:    uabd z0.h, p0/m, z0.h, z1.h
162 ; CHECK-NEXT:    ret
163   %a.zext = zext <vscale x 8 x i16> %a to <vscale x 8 x i32>
164   %b.zext = zext <vscale x 8 x i16> %b to <vscale x 8 x i32>
165   %sub = sub <vscale x 8 x i32> %a.zext, %b.zext
166   %abs = call <vscale x 8 x i32> @llvm.abs.nxv8i32(<vscale x 8 x i32> %sub, i1 true)
167   %trunc = trunc <vscale x 8 x i32> %abs to <vscale x 8 x i16>
168   ret <vscale x 8 x i16> %trunc
171 define <vscale x 8 x i16> @uabd_h_promoted_ops(<vscale x 8 x i8> %a, <vscale x 8 x i8> %b) #0 {
172 ; CHECK-LABEL: uabd_h_promoted_ops:
173 ; CHECK:       // %bb.0:
174 ; CHECK-NEXT:    and z1.h, z1.h, #0xff
175 ; CHECK-NEXT:    and z0.h, z0.h, #0xff
176 ; CHECK-NEXT:    ptrue p0.h
177 ; CHECK-NEXT:    uabd z0.h, p0/m, z0.h, z1.h
178 ; CHECK-NEXT:    ret
179   %a.zext = zext <vscale x 8 x i8> %a to <vscale x 8 x i16>
180   %b.zext = zext <vscale x 8 x i8> %b to <vscale x 8 x i16>
181   %sub = sub <vscale x 8 x i16> %a.zext, %b.zext
182   %abs = call <vscale x 8 x i16> @llvm.abs.nxv8i16(<vscale x 8 x i16> %sub, i1 true)
183   ret <vscale x 8 x i16> %abs
186 define <vscale x 4 x i32> @uabd_s(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b) #0 {
187 ; CHECK-LABEL: uabd_s:
188 ; CHECK:       // %bb.0:
189 ; CHECK-NEXT:    ptrue p0.s
190 ; CHECK-NEXT:    uabd z0.s, p0/m, z0.s, z1.s
191 ; CHECK-NEXT:    ret
192   %a.zext = zext <vscale x 4 x i32> %a to <vscale x 4 x i64>
193   %b.zext = zext <vscale x 4 x i32> %b to <vscale x 4 x i64>
194   %sub = sub <vscale x 4 x i64> %a.zext, %b.zext
195   %abs = call <vscale x 4 x i64> @llvm.abs.nxv4i64(<vscale x 4 x i64> %sub, i1 true)
196   %trunc = trunc <vscale x 4 x i64> %abs to <vscale x 4 x i32>
197   ret <vscale x 4 x i32> %trunc
200 define <vscale x 4 x i32> @uabd_s_promoted_ops(<vscale x 4 x i16> %a, <vscale x 4 x i16> %b) #0 {
201 ; CHECK-LABEL: uabd_s_promoted_ops:
202 ; CHECK:       // %bb.0:
203 ; CHECK-NEXT:    and z1.s, z1.s, #0xffff
204 ; CHECK-NEXT:    and z0.s, z0.s, #0xffff
205 ; CHECK-NEXT:    ptrue p0.s
206 ; CHECK-NEXT:    uabd z0.s, p0/m, z0.s, z1.s
207 ; CHECK-NEXT:    ret
208   %a.zext = zext <vscale x 4 x i16> %a to <vscale x 4 x i32>
209   %b.zext = zext <vscale x 4 x i16> %b to <vscale x 4 x i32>
210   %sub = sub <vscale x 4 x i32> %a.zext, %b.zext
211   %abs = call <vscale x 4 x i32> @llvm.abs.nxv4i32(<vscale x 4 x i32> %sub, i1 true)
212   ret <vscale x 4 x i32> %abs
215 define <vscale x 2 x i64> @uabd_d(<vscale x 2 x i64> %a, <vscale x 2 x i64> %b) #0 {
216 ; CHECK-LABEL: uabd_d:
217 ; CHECK:       // %bb.0:
218 ; CHECK-NEXT:    ptrue p0.d
219 ; CHECK-NEXT:    uabd z0.d, p0/m, z0.d, z1.d
220 ; CHECK-NEXT:    ret
221   %a.zext = zext <vscale x 2 x i64> %a to <vscale x 2 x i128>
222   %b.zext = zext <vscale x 2 x i64> %b to <vscale x 2 x i128>
223   %sub = sub <vscale x 2 x i128> %a.zext, %b.zext
224   %abs = call <vscale x 2 x i128> @llvm.abs.nxv2i128(<vscale x 2 x i128> %sub, i1 true)
225   %trunc = trunc <vscale x 2 x i128> %abs to <vscale x 2 x i64>
226   ret <vscale x 2 x i64> %trunc
229 define <vscale x 2 x i64> @uabd_d_promoted_ops(<vscale x 2 x i32> %a, <vscale x 2 x i32> %b) #0 {
230 ; CHECK-LABEL: uabd_d_promoted_ops:
231 ; CHECK:       // %bb.0:
232 ; CHECK-NEXT:    and z1.d, z1.d, #0xffffffff
233 ; CHECK-NEXT:    and z0.d, z0.d, #0xffffffff
234 ; CHECK-NEXT:    ptrue p0.d
235 ; CHECK-NEXT:    uabd z0.d, p0/m, z0.d, z1.d
236 ; CHECK-NEXT:    ret
237   %a.zext = zext <vscale x 2 x i32> %a to <vscale x 2 x i64>
238   %b.zext = zext <vscale x 2 x i32> %b to <vscale x 2 x i64>
239   %sub = sub <vscale x 2 x i64> %a.zext, %b.zext
240   %abs = call <vscale x 2 x i64> @llvm.abs.nxv2i64(<vscale x 2 x i64> %sub, i1 true)
241   ret <vscale x 2 x i64> %abs
244 ; Test the situation where isLegal(ISD::ABD, typeof(%a)) returns true but %a and
245 ; %b have differing types.
246 define <vscale x 4 x i32> @uabd_non_matching_extension(<vscale x 4 x i32> %a, <vscale x 4 x i8> %b) #0 {
247 ; CHECK-LABEL: uabd_non_matching_extension:
248 ; CHECK:       // %bb.0:
249 ; CHECK-NEXT:    and z1.s, z1.s, #0xff
250 ; CHECK-NEXT:    ptrue p0.s
251 ; CHECK-NEXT:    uabd z0.s, p0/m, z0.s, z1.s
252 ; CHECK-NEXT:    ret
253   %a.zext = zext <vscale x 4 x i32> %a to <vscale x 4 x i64>
254   %b.zext = zext <vscale x 4 x i8> %b to <vscale x 4 x i64>
255   %sub = sub <vscale x 4 x i64> %a.zext, %b.zext
256   %abs = call <vscale x 4 x i64> @llvm.abs.nxv4i64(<vscale x 4 x i64> %sub, i1 true)
257   %trunc = trunc <vscale x 4 x i64> %abs to <vscale x 4 x i32>
258   ret <vscale x 4 x i32> %trunc
261 ; Test the situation where isLegal(ISD::ABD, typeof(%a.zext)) returns true but
262 ; %a and %b have differing types.
263 define <vscale x 4 x i32> @uabd_non_matching_promoted_ops(<vscale x 4 x i8> %a, <vscale x 4 x i16> %b) #0 {
264 ; CHECK-LABEL: uabd_non_matching_promoted_ops:
265 ; CHECK:       // %bb.0:
266 ; CHECK-NEXT:    and z1.s, z1.s, #0xffff
267 ; CHECK-NEXT:    and z0.s, z0.s, #0xff
268 ; CHECK-NEXT:    ptrue p0.s
269 ; CHECK-NEXT:    uabd z0.s, p0/m, z0.s, z1.s
270 ; CHECK-NEXT:    ret
271   %a.zext = zext <vscale x 4 x i8> %a to <vscale x 4 x i32>
272   %b.zext = zext <vscale x 4 x i16> %b to <vscale x 4 x i32>
273   %sub = sub <vscale x 4 x i32> %a.zext, %b.zext
274   %abs = call <vscale x 4 x i32> @llvm.abs.nxv4i32(<vscale x 4 x i32> %sub, i1 true)
275   ret <vscale x 4 x i32> %abs
278 ; Test the situation where isLegal(ISD::ABD, typeof(%a)) returns true but %a and
279 ; %b are promoted differently.
280 define <vscale x 4 x i32> @uabd_non_matching_promotion(<vscale x 4 x i8> %a, <vscale x 4 x i8> %b) #0 {
281 ; CHECK-LABEL: uabd_non_matching_promotion:
282 ; CHECK:       // %bb.0:
283 ; CHECK-NEXT:    ptrue p0.s
284 ; CHECK-NEXT:    and z0.s, z0.s, #0xff
285 ; CHECK-NEXT:    sxtb z1.s, p0/m, z1.s
286 ; CHECK-NEXT:    sub z0.s, z0.s, z1.s
287 ; CHECK-NEXT:    abs z0.s, p0/m, z0.s
288 ; CHECK-NEXT:    ret
289   %a.zext = zext <vscale x 4 x i8> %a to <vscale x 4 x i32>
290   %b.zext = sext <vscale x 4 x i8> %b to <vscale x 4 x i32>
291   %sub = sub <vscale x 4 x i32> %a.zext, %b.zext
292   %abs = call <vscale x 4 x i32> @llvm.abs.nxv4i32(<vscale x 4 x i32> %sub, i1 true)
293   ret <vscale x 4 x i32> %abs
296 declare <vscale x 16 x i8> @llvm.abs.nxv16i8(<vscale x 16 x i8>, i1)
298 declare <vscale x 8 x i16> @llvm.abs.nxv8i16(<vscale x 8 x i16>, i1)
299 declare <vscale x 16 x i16> @llvm.abs.nxv16i16(<vscale x 16 x i16>, i1)
301 declare <vscale x 4 x i32> @llvm.abs.nxv4i32(<vscale x 4 x i32>, i1)
302 declare <vscale x 8 x i32> @llvm.abs.nxv8i32(<vscale x 8 x i32>, i1)
304 declare <vscale x 2 x i64> @llvm.abs.nxv2i64(<vscale x 2 x i64>, i1)
305 declare <vscale x 4 x i64> @llvm.abs.nxv4i64(<vscale x 4 x i64>, i1)
307 declare <vscale x 2 x i128> @llvm.abs.nxv2i128(<vscale x 2 x i128>, i1)
309 attributes #0 = { "target-features"="+neon,+sve" }