[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / llvm / test / CodeGen / AArch64 / sve-aba.ll
blob6859f7d017044b7f7937d7bedb933405a2d9c854
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 ; SABA
10 define <vscale x 16 x i8> @saba_b(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b, <vscale x 16 x i8> %c) #0 {
11 ; CHECK-LABEL: saba_b:
12 ; CHECK:       // %bb.0:
13 ; CHECK-NEXT:    saba z0.b, z1.b, z2.b
14 ; CHECK-NEXT:    ret
15   %b.sext = sext <vscale x 16 x i8> %b to <vscale x 16 x i16>
16   %c.sext = sext <vscale x 16 x i8> %c to <vscale x 16 x i16>
17   %sub = sub <vscale x 16 x i16> %b.sext, %c.sext
18   %abs = call <vscale x 16 x i16> @llvm.abs.nxv16i16(<vscale x 16 x i16> %sub, i1 true)
19   %trunc = trunc <vscale x 16 x i16> %abs to <vscale x 16 x i8>
20   %add = add <vscale x 16 x i8> %a, %trunc
21   ret <vscale x 16 x i8> %add
24 define <vscale x 16 x i8> @saba_b_promoted_ops(<vscale x 16 x i8> %a, <vscale x 16 x i1> %b, <vscale x 16 x i1> %c) #0 {
25 ; CHECK-LABEL: saba_b_promoted_ops:
26 ; CHECK:       // %bb.0:
27 ; CHECK-NEXT:    mov z1.b, p0/z, #-1 // =0xffffffffffffffff
28 ; CHECK-NEXT:    mov z2.b, p1/z, #-1 // =0xffffffffffffffff
29 ; CHECK-NEXT:    saba z0.b, z1.b, z2.b
30 ; CHECK-NEXT:    ret
31   %b.sext = sext <vscale x 16 x i1> %b to <vscale x 16 x i8>
32   %c.sext = sext <vscale x 16 x i1> %c to <vscale x 16 x i8>
33   %sub = sub <vscale x 16 x i8> %b.sext, %c.sext
34   %abs = call <vscale x 16 x i8> @llvm.abs.nxv16i8(<vscale x 16 x i8> %sub, i1 true)
35   %add = add <vscale x 16 x i8> %a, %abs
36   ret <vscale x 16 x i8> %add
39 define <vscale x 16 x i8> @saba_b_from_sabd(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b, <vscale x 16 x i8> %c) #0 {
40 ; CHECK-LABEL: saba_b_from_sabd:
41 ; CHECK:       // %bb.0:
42 ; CHECK-NEXT:    saba z0.b, z1.b, z2.b
43 ; CHECK-NEXT:    ret
44   %1 = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 31)
45   %2 = call <vscale x 16 x i8> @llvm.aarch64.sve.sabd.u.nxv16i8(<vscale x 16 x i1> %1, <vscale x 16 x i8> %b, <vscale x 16 x i8> %c)
46   %3 = add <vscale x 16 x i8> %2, %a
47   ret <vscale x 16 x i8> %3
50 define <vscale x 16 x i8> @saba_b_from_sabd_u(<vscale x 16 x i1> %pg, <vscale x 16 x i8> %a, <vscale x 16 x i8> %b, <vscale x 16 x i8> %c) #0 {
51 ; CHECK-LABEL: saba_b_from_sabd_u:
52 ; CHECK:       // %bb.0:
53 ; CHECK-NEXT:    saba z0.b, z1.b, z2.b
54 ; CHECK-NEXT:    ret
55   %1 = call <vscale x 16 x i8> @llvm.aarch64.sve.sabd.u.nxv16i8(<vscale x 16 x i1> %pg, <vscale x 16 x i8> %b, <vscale x 16 x i8> %c)
56   %2 = add <vscale x 16 x i8> %1, %a
57   ret <vscale x 16 x i8> %2
60 define <vscale x 8 x i16> @saba_h(<vscale x 8 x i16> %a, <vscale x 8 x i16> %b, <vscale x 8 x i16> %c) #0 {
61 ; CHECK-LABEL: saba_h:
62 ; CHECK:       // %bb.0:
63 ; CHECK-NEXT:    saba z0.h, z1.h, z2.h
64 ; CHECK-NEXT:    ret
65   %b.sext = sext <vscale x 8 x i16> %b to <vscale x 8 x i32>
66   %c.sext = sext <vscale x 8 x i16> %c to <vscale x 8 x i32>
67   %sub = sub <vscale x 8 x i32> %b.sext, %c.sext
68   %abs = call <vscale x 8 x i32> @llvm.abs.nxv8i32(<vscale x 8 x i32> %sub, i1 true)
69   %trunc = trunc <vscale x 8 x i32> %abs to <vscale x 8 x i16>
70   %add = add <vscale x 8 x i16> %a, %trunc
71   ret <vscale x 8 x i16> %add
74 define <vscale x 8 x i16> @saba_h_promoted_ops(<vscale x 8 x i16> %a, <vscale x 8 x i8> %b, <vscale x 8 x i8> %c) #0 {
75 ; CHECK-LABEL: saba_h_promoted_ops:
76 ; CHECK:       // %bb.0:
77 ; CHECK-NEXT:    ptrue p0.h
78 ; CHECK-NEXT:    sxtb z1.h, p0/m, z1.h
79 ; CHECK-NEXT:    sxtb z2.h, p0/m, z2.h
80 ; CHECK-NEXT:    saba z0.h, z1.h, z2.h
81 ; CHECK-NEXT:    ret
82   %b.sext = sext <vscale x 8 x i8> %b to <vscale x 8 x i16>
83   %c.sext = sext <vscale x 8 x i8> %c to <vscale x 8 x i16>
84   %sub = sub <vscale x 8 x i16> %b.sext, %c.sext
85   %abs = call <vscale x 8 x i16> @llvm.abs.nxv8i16(<vscale x 8 x i16> %sub, i1 true)
86   %add = add <vscale x 8 x i16> %a, %abs
87   ret <vscale x 8 x i16> %add
90 define <vscale x 8 x i16> @saba_h_from_sabd(<vscale x 8 x i16> %a, <vscale x 8 x i16> %b, <vscale x 8 x i16> %c) #0 {
91 ; CHECK-LABEL: saba_h_from_sabd:
92 ; CHECK:       // %bb.0:
93 ; CHECK-NEXT:    saba z0.h, z1.h, z2.h
94 ; CHECK-NEXT:    ret
95   %1 = call <vscale x 8 x i1> @llvm.aarch64.sve.ptrue.nxv8i1(i32 31)
96   %2 = call <vscale x 8 x i16> @llvm.aarch64.sve.sabd.u.nxv8i16(<vscale x 8 x i1> %1, <vscale x 8 x i16> %b, <vscale x 8 x i16> %c)
97   %3 = add <vscale x 8 x i16> %2, %a
98   ret <vscale x 8 x i16> %3
101 define <vscale x 8 x i16> @saba_h_from_sabd_u(<vscale x 8 x i1> %pg, <vscale x 8 x i16> %a, <vscale x 8 x i16> %b, <vscale x 8 x i16> %c) #0 {
102 ; CHECK-LABEL: saba_h_from_sabd_u:
103 ; CHECK:       // %bb.0:
104 ; CHECK-NEXT:    saba z0.h, z1.h, z2.h
105 ; CHECK-NEXT:    ret
106   %1 = call <vscale x 8 x i16> @llvm.aarch64.sve.sabd.u.nxv8i16(<vscale x 8 x i1> %pg, <vscale x 8 x i16> %b, <vscale x 8 x i16> %c)
107   %2 = add <vscale x 8 x i16> %1, %a
108   ret <vscale x 8 x i16> %2
111 define <vscale x 4 x i32> @saba_s(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i32> %c) #0 {
112 ; CHECK-LABEL: saba_s:
113 ; CHECK:       // %bb.0:
114 ; CHECK-NEXT:    saba z0.s, z1.s, z2.s
115 ; CHECK-NEXT:    ret
116   %b.sext = sext <vscale x 4 x i32> %b to <vscale x 4 x i64>
117   %c.sext = sext <vscale x 4 x i32> %c to <vscale x 4 x i64>
118   %sub = sub <vscale x 4 x i64> %b.sext, %c.sext
119   %abs = call <vscale x 4 x i64> @llvm.abs.nxv4i64(<vscale x 4 x i64> %sub, i1 true)
120   %trunc = trunc <vscale x 4 x i64> %abs to <vscale x 4 x i32>
121   %add = add <vscale x 4 x i32> %a, %trunc
122   ret <vscale x 4 x i32> %add
125 define <vscale x 4 x i32> @saba_s_promoted_ops(<vscale x 4 x i32> %a, <vscale x 4 x i16> %b, <vscale x 4 x i16> %c) #0 {
126 ; CHECK-LABEL: saba_s_promoted_ops:
127 ; CHECK:       // %bb.0:
128 ; CHECK-NEXT:    ptrue p0.s
129 ; CHECK-NEXT:    sxth z1.s, p0/m, z1.s
130 ; CHECK-NEXT:    sxth z2.s, p0/m, z2.s
131 ; CHECK-NEXT:    saba z0.s, z1.s, z2.s
132 ; CHECK-NEXT:    ret
133   %b.sext = sext <vscale x 4 x i16> %b to <vscale x 4 x i32>
134   %c.sext = sext <vscale x 4 x i16> %c to <vscale x 4 x i32>
135   %sub = sub <vscale x 4 x i32> %b.sext, %c.sext
136   %abs = call <vscale x 4 x i32> @llvm.abs.nxv4i32(<vscale x 4 x i32> %sub, i1 true)
137   %add = add <vscale x 4 x i32> %a, %abs
138   ret <vscale x 4 x i32> %add
141 define <vscale x 4 x i32> @saba_s_from_sabd(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i32> %c) #0 {
142 ; CHECK-LABEL: saba_s_from_sabd:
143 ; CHECK:       // %bb.0:
144 ; CHECK-NEXT:    saba z0.s, z1.s, z2.s
145 ; CHECK-NEXT:    ret
146   %1 = call <vscale x 4 x i1> @llvm.aarch64.sve.ptrue.nxv4i1(i32 31)
147   %2 = call <vscale x 4 x i32> @llvm.aarch64.sve.sabd.u.nxv4i32(<vscale x 4 x i1> %1, <vscale x 4 x i32> %b, <vscale x 4 x i32> %c)
148   %3 = add <vscale x 4 x i32> %2, %a
149   ret <vscale x 4 x i32> %3
152 define <vscale x 4 x i32> @saba_s_from_sabd_u(<vscale x 4 x i1> %pg, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i32> %c) #0 {
153 ; CHECK-LABEL: saba_s_from_sabd_u:
154 ; CHECK:       // %bb.0:
155 ; CHECK-NEXT:    saba z0.s, z1.s, z2.s
156 ; CHECK-NEXT:    ret
157   %1 = call <vscale x 4 x i32> @llvm.aarch64.sve.sabd.u.nxv4i32(<vscale x 4 x i1> %pg, <vscale x 4 x i32> %b, <vscale x 4 x i32> %c)
158   %2 = add <vscale x 4 x i32> %1, %a
159   ret <vscale x 4 x i32> %2
162 define <vscale x 2 x i64> @saba_d(<vscale x 2 x i64> %a, <vscale x 2 x i64> %b, <vscale x 2 x i64> %c) #0 {
163 ; CHECK-LABEL: saba_d:
164 ; CHECK:       // %bb.0:
165 ; CHECK-NEXT:    saba z0.d, z1.d, z2.d
166 ; CHECK-NEXT:    ret
167   %b.sext = sext <vscale x 2 x i64> %b to <vscale x 2 x i128>
168   %c.sext = sext <vscale x 2 x i64> %c to <vscale x 2 x i128>
169   %sub = sub <vscale x 2 x i128> %b.sext, %c.sext
170   %abs = call <vscale x 2 x i128> @llvm.abs.nxv2i128(<vscale x 2 x i128> %sub, i1 true)
171   %trunc = trunc <vscale x 2 x i128> %abs to <vscale x 2 x i64>
172   %add = add <vscale x 2 x i64> %a, %trunc
173   ret <vscale x 2 x i64> %add
176 define <vscale x 2 x i64> @saba_d_promoted_ops(<vscale x 2 x i64> %a, <vscale x 2 x i32> %b, <vscale x 2 x i32> %c) #0 {
177 ; CHECK-LABEL: saba_d_promoted_ops:
178 ; CHECK:       // %bb.0:
179 ; CHECK-NEXT:    ptrue p0.d
180 ; CHECK-NEXT:    sxtw z1.d, p0/m, z1.d
181 ; CHECK-NEXT:    sxtw z2.d, p0/m, z2.d
182 ; CHECK-NEXT:    saba z0.d, z1.d, z2.d
183 ; CHECK-NEXT:    ret
184   %b.sext = sext <vscale x 2 x i32> %b to <vscale x 2 x i64>
185   %c.sext = sext <vscale x 2 x i32> %c to <vscale x 2 x i64>
186   %sub = sub <vscale x 2 x i64> %b.sext, %c.sext
187   %abs = call <vscale x 2 x i64> @llvm.abs.nxv2i64(<vscale x 2 x i64> %sub, i1 true)
188   %add = add <vscale x 2 x i64> %a, %abs
189   ret <vscale x 2 x i64> %add
192 define <vscale x 2 x i64> @saba_d_from_sabd(<vscale x 2 x i64> %a, <vscale x 2 x i64> %b, <vscale x 2 x i64> %c) #0 {
193 ; CHECK-LABEL: saba_d_from_sabd:
194 ; CHECK:       // %bb.0:
195 ; CHECK-NEXT:    saba z0.d, z1.d, z2.d
196 ; CHECK-NEXT:    ret
197   %1 = call <vscale x 2 x i1> @llvm.aarch64.sve.ptrue.nxv2i1(i32 31)
198   %2 = call <vscale x 2 x i64> @llvm.aarch64.sve.sabd.u.nxv2i64(<vscale x 2 x i1> %1, <vscale x 2 x i64> %b, <vscale x 2 x i64> %c)
199   %3 = add <vscale x 2 x i64> %2, %a
200   ret <vscale x 2 x i64> %3
203 define <vscale x 2 x i64> @saba_d_from_sabd_u(<vscale x 2 x i1> %pg, <vscale x 2 x i64> %a, <vscale x 2 x i64> %b, <vscale x 2 x i64> %c) #0 {
204 ; CHECK-LABEL: saba_d_from_sabd_u:
205 ; CHECK:       // %bb.0:
206 ; CHECK-NEXT:    saba z0.d, z1.d, z2.d
207 ; CHECK-NEXT:    ret
208   %1 = call <vscale x 2 x i64> @llvm.aarch64.sve.sabd.u.nxv2i64(<vscale x 2 x i1> %pg, <vscale x 2 x i64> %b, <vscale x 2 x i64> %c)
209   %2 = add <vscale x 2 x i64> %1, %a
210   ret <vscale x 2 x i64> %2
214 ; UABA
217 define <vscale x 16 x i8> @uaba_b(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b, <vscale x 16 x i8> %c) #0 {
218 ; CHECK-LABEL: uaba_b:
219 ; CHECK:       // %bb.0:
220 ; CHECK-NEXT:    uaba z0.b, z1.b, z2.b
221 ; CHECK-NEXT:    ret
222   %b.zext = zext <vscale x 16 x i8> %b to <vscale x 16 x i16>
223   %c.zext = zext <vscale x 16 x i8> %c to <vscale x 16 x i16>
224   %sub = sub <vscale x 16 x i16> %b.zext, %c.zext
225   %abs = call <vscale x 16 x i16> @llvm.abs.nxv16i16(<vscale x 16 x i16> %sub, i1 true)
226   %trunc = trunc <vscale x 16 x i16> %abs to <vscale x 16 x i8>
227   %add = add <vscale x 16 x i8> %a, %trunc
228   ret <vscale x 16 x i8> %add
231 define <vscale x 16 x i8> @uaba_b_promoted_ops(<vscale x 16 x i8> %a, <vscale x 16 x i1> %b, <vscale x 16 x i1> %c) #0 {
232 ; CHECK-LABEL: uaba_b_promoted_ops:
233 ; CHECK:       // %bb.0:
234 ; CHECK-NEXT:    mov z1.b, p0/z, #1 // =0x1
235 ; CHECK-NEXT:    mov z2.b, p1/z, #1 // =0x1
236 ; CHECK-NEXT:    uaba z0.b, z1.b, z2.b
237 ; CHECK-NEXT:    ret
238   %b.zext = zext <vscale x 16 x i1> %b to <vscale x 16 x i8>
239   %c.zext = zext <vscale x 16 x i1> %c to <vscale x 16 x i8>
240   %sub = sub <vscale x 16 x i8> %b.zext, %c.zext
241   %abs = call <vscale x 16 x i8> @llvm.abs.nxv16i8(<vscale x 16 x i8> %sub, i1 true)
242   %add = add <vscale x 16 x i8> %a, %abs
243   ret <vscale x 16 x i8> %add
246 define <vscale x 16 x i8> @uaba_b_from_uabd(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b, <vscale x 16 x i8> %c) #0 {
247 ; CHECK-LABEL: uaba_b_from_uabd:
248 ; CHECK:       // %bb.0:
249 ; CHECK-NEXT:    uaba z0.b, z1.b, z2.b
250 ; CHECK-NEXT:    ret
251   %1 = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 31)
252   %2 = call <vscale x 16 x i8> @llvm.aarch64.sve.uabd.u.nxv16i8(<vscale x 16 x i1> %1, <vscale x 16 x i8> %b, <vscale x 16 x i8> %c)
253   %3 = add <vscale x 16 x i8> %2, %a
254   ret <vscale x 16 x i8> %3
257 define <vscale x 16 x i8> @uaba_b_from_uabd_u(<vscale x 16 x i1> %pg, <vscale x 16 x i8> %a, <vscale x 16 x i8> %b, <vscale x 16 x i8> %c) #0 {
258 ; CHECK-LABEL: uaba_b_from_uabd_u:
259 ; CHECK:       // %bb.0:
260 ; CHECK-NEXT:    uaba z0.b, z1.b, z2.b
261 ; CHECK-NEXT:    ret
262   %1 = call <vscale x 16 x i8> @llvm.aarch64.sve.uabd.u.nxv16i8(<vscale x 16 x i1> %pg, <vscale x 16 x i8> %b, <vscale x 16 x i8> %c)
263   %2 = add <vscale x 16 x i8> %1, %a
264   ret <vscale x 16 x i8> %2
267 define <vscale x 8 x i16> @uaba_h(<vscale x 8 x i16> %a, <vscale x 8 x i16> %b, <vscale x 8 x i16> %c) #0 {
268 ; CHECK-LABEL: uaba_h:
269 ; CHECK:       // %bb.0:
270 ; CHECK-NEXT:    uaba z0.h, z1.h, z2.h
271 ; CHECK-NEXT:    ret
272   %b.zext = zext <vscale x 8 x i16> %b to <vscale x 8 x i32>
273   %c.zext = zext <vscale x 8 x i16> %c to <vscale x 8 x i32>
274   %sub = sub <vscale x 8 x i32> %b.zext, %c.zext
275   %abs = call <vscale x 8 x i32> @llvm.abs.nxv8i32(<vscale x 8 x i32> %sub, i1 true)
276   %trunc = trunc <vscale x 8 x i32> %abs to <vscale x 8 x i16>
277   %add = add <vscale x 8 x i16> %a, %trunc
278   ret <vscale x 8 x i16> %add
281 define <vscale x 8 x i16> @uaba_h_promoted_ops(<vscale x 8 x i16> %a, <vscale x 8 x i8> %b, <vscale x 8 x i8> %c) #0 {
282 ; CHECK-LABEL: uaba_h_promoted_ops:
283 ; CHECK:       // %bb.0:
284 ; CHECK-NEXT:    and z1.h, z1.h, #0xff
285 ; CHECK-NEXT:    and z2.h, z2.h, #0xff
286 ; CHECK-NEXT:    uaba z0.h, z1.h, z2.h
287 ; CHECK-NEXT:    ret
288   %b.zext = zext <vscale x 8 x i8> %b to <vscale x 8 x i16>
289   %c.zext = zext <vscale x 8 x i8> %c to <vscale x 8 x i16>
290   %sub = sub <vscale x 8 x i16> %b.zext, %c.zext
291   %abs = call <vscale x 8 x i16> @llvm.abs.nxv8i16(<vscale x 8 x i16> %sub, i1 true)
292   %add = add <vscale x 8 x i16> %a, %abs
293   ret <vscale x 8 x i16> %add
296 define <vscale x 8 x i16> @uaba_h_from_uabd(<vscale x 8 x i16> %a, <vscale x 8 x i16> %b, <vscale x 8 x i16> %c) #0 {
297 ; CHECK-LABEL: uaba_h_from_uabd:
298 ; CHECK:       // %bb.0:
299 ; CHECK-NEXT:    uaba z0.h, z1.h, z2.h
300 ; CHECK-NEXT:    ret
301   %1 = call <vscale x 8 x i1> @llvm.aarch64.sve.ptrue.nxv8i1(i32 31)
302   %2 = call <vscale x 8 x i16> @llvm.aarch64.sve.uabd.u.nxv8i16(<vscale x 8 x i1> %1, <vscale x 8 x i16> %b, <vscale x 8 x i16> %c)
303   %3 = add <vscale x 8 x i16> %2, %a
304   ret <vscale x 8 x i16> %3
307 define <vscale x 8 x i16> @uaba_h_from_uabd_u(<vscale x 8 x i1> %pg, <vscale x 8 x i16> %a, <vscale x 8 x i16> %b, <vscale x 8 x i16> %c) #0 {
308 ; CHECK-LABEL: uaba_h_from_uabd_u:
309 ; CHECK:       // %bb.0:
310 ; CHECK-NEXT:    uaba z0.h, z1.h, z2.h
311 ; CHECK-NEXT:    ret
312   %1 = call <vscale x 8 x i16> @llvm.aarch64.sve.uabd.u.nxv8i16(<vscale x 8 x i1> %pg, <vscale x 8 x i16> %b, <vscale x 8 x i16> %c)
313   %2 = add <vscale x 8 x i16> %1, %a
314   ret <vscale x 8 x i16> %2
317 define <vscale x 4 x i32> @uaba_s(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i32> %c) #0 {
318 ; CHECK-LABEL: uaba_s:
319 ; CHECK:       // %bb.0:
320 ; CHECK-NEXT:    uaba z0.s, z1.s, z2.s
321 ; CHECK-NEXT:    ret
322   %b.zext = zext <vscale x 4 x i32> %b to <vscale x 4 x i64>
323   %c.zext = zext <vscale x 4 x i32> %c to <vscale x 4 x i64>
324   %sub = sub <vscale x 4 x i64> %b.zext, %c.zext
325   %abs = call <vscale x 4 x i64> @llvm.abs.nxv4i64(<vscale x 4 x i64> %sub, i1 true)
326   %trunc = trunc <vscale x 4 x i64> %abs to <vscale x 4 x i32>
327   %add = add <vscale x 4 x i32> %a, %trunc
328   ret <vscale x 4 x i32> %add
331 define <vscale x 4 x i32> @uaba_s_promoted_ops(<vscale x 4 x i32> %a, <vscale x 4 x i16> %b, <vscale x 4 x i16> %c) #0 {
332 ; CHECK-LABEL: uaba_s_promoted_ops:
333 ; CHECK:       // %bb.0:
334 ; CHECK-NEXT:    and z1.s, z1.s, #0xffff
335 ; CHECK-NEXT:    and z2.s, z2.s, #0xffff
336 ; CHECK-NEXT:    uaba z0.s, z1.s, z2.s
337 ; CHECK-NEXT:    ret
338   %b.zext = zext <vscale x 4 x i16> %b to <vscale x 4 x i32>
339   %c.zext = zext <vscale x 4 x i16> %c to <vscale x 4 x i32>
340   %sub = sub <vscale x 4 x i32> %b.zext, %c.zext
341   %abs = call <vscale x 4 x i32> @llvm.abs.nxv4i32(<vscale x 4 x i32> %sub, i1 true)
342   %add = add <vscale x 4 x i32> %a, %abs
343   ret <vscale x 4 x i32> %add
346 define <vscale x 4 x i32> @uaba_s_from_uabd(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i32> %c) #0 {
347 ; CHECK-LABEL: uaba_s_from_uabd:
348 ; CHECK:       // %bb.0:
349 ; CHECK-NEXT:    uaba z0.s, z1.s, z2.s
350 ; CHECK-NEXT:    ret
351   %1 = call <vscale x 4 x i1> @llvm.aarch64.sve.ptrue.nxv4i1(i32 31)
352   %2 = call <vscale x 4 x i32> @llvm.aarch64.sve.uabd.u.nxv4i32(<vscale x 4 x i1> %1, <vscale x 4 x i32> %b, <vscale x 4 x i32> %c)
353   %3 = add <vscale x 4 x i32> %2, %a
354   ret <vscale x 4 x i32> %3
357 define <vscale x 4 x i32> @uaba_s_from_uabd_u(<vscale x 4 x i1> %pg, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i32> %c) #0 {
358 ; CHECK-LABEL: uaba_s_from_uabd_u:
359 ; CHECK:       // %bb.0:
360 ; CHECK-NEXT:    uaba z0.s, z1.s, z2.s
361 ; CHECK-NEXT:    ret
362   %1 = call <vscale x 4 x i32> @llvm.aarch64.sve.uabd.u.nxv4i32(<vscale x 4 x i1> %pg, <vscale x 4 x i32> %b, <vscale x 4 x i32> %c)
363   %2 = add <vscale x 4 x i32> %1, %a
364   ret <vscale x 4 x i32> %2
367 define <vscale x 2 x i64> @uaba_d(<vscale x 2 x i64> %a, <vscale x 2 x i64> %b, <vscale x 2 x i64> %c) #0 {
368 ; CHECK-LABEL: uaba_d:
369 ; CHECK:       // %bb.0:
370 ; CHECK-NEXT:    uaba z0.d, z1.d, z2.d
371 ; CHECK-NEXT:    ret
372   %b.zext = zext <vscale x 2 x i64> %b to <vscale x 2 x i128>
373   %c.zext = zext <vscale x 2 x i64> %c to <vscale x 2 x i128>
374   %sub = sub <vscale x 2 x i128> %b.zext, %c.zext
375   %abs = call <vscale x 2 x i128> @llvm.abs.nxv2i128(<vscale x 2 x i128> %sub, i1 true)
376   %trunc = trunc <vscale x 2 x i128> %abs to <vscale x 2 x i64>
377   %add = add <vscale x 2 x i64> %a, %trunc
378   ret <vscale x 2 x i64> %add
381 define <vscale x 2 x i64> @uaba_d_promoted_ops(<vscale x 2 x i64> %a, <vscale x 2 x i32> %b, <vscale x 2 x i32> %c) #0 {
382 ; CHECK-LABEL: uaba_d_promoted_ops:
383 ; CHECK:       // %bb.0:
384 ; CHECK-NEXT:    and z1.d, z1.d, #0xffffffff
385 ; CHECK-NEXT:    and z2.d, z2.d, #0xffffffff
386 ; CHECK-NEXT:    uaba z0.d, z1.d, z2.d
387 ; CHECK-NEXT:    ret
388   %b.zext = zext <vscale x 2 x i32> %b to <vscale x 2 x i64>
389   %c.zext = zext <vscale x 2 x i32> %c to <vscale x 2 x i64>
390   %sub = sub <vscale x 2 x i64> %b.zext, %c.zext
391   %abs = call <vscale x 2 x i64> @llvm.abs.nxv2i64(<vscale x 2 x i64> %sub, i1 true)
392   %add = add <vscale x 2 x i64> %a, %abs
393   ret <vscale x 2 x i64> %add
396 define <vscale x 2 x i64> @uaba_d_from_uabd(<vscale x 2 x i64> %a, <vscale x 2 x i64> %b, <vscale x 2 x i64> %c) #0 {
397 ; CHECK-LABEL: uaba_d_from_uabd:
398 ; CHECK:       // %bb.0:
399 ; CHECK-NEXT:    uaba z0.d, z1.d, z2.d
400 ; CHECK-NEXT:    ret
401   %1 = call <vscale x 2 x i1> @llvm.aarch64.sve.ptrue.nxv2i1(i32 31)
402   %2 = call <vscale x 2 x i64> @llvm.aarch64.sve.uabd.u.nxv2i64(<vscale x 2 x i1> %1, <vscale x 2 x i64> %b, <vscale x 2 x i64> %c)
403   %3 = add <vscale x 2 x i64> %2, %a
404   ret <vscale x 2 x i64> %3
407 define <vscale x 2 x i64> @uaba_d_from_uabd_u(<vscale x 2 x i1> %pg, <vscale x 2 x i64> %a, <vscale x 2 x i64> %b, <vscale x 2 x i64> %c) #0 {
408 ; CHECK-LABEL: uaba_d_from_uabd_u:
409 ; CHECK:       // %bb.0:
410 ; CHECK-NEXT:    uaba z0.d, z1.d, z2.d
411 ; CHECK-NEXT:    ret
412   %1 = call <vscale x 2 x i64> @llvm.aarch64.sve.uabd.u.nxv2i64(<vscale x 2 x i1> %pg, <vscale x 2 x i64> %b, <vscale x 2 x i64> %c)
413   %2 = add <vscale x 2 x i64> %1, %a
414   ret <vscale x 2 x i64> %2
417 ; A variant of uaba_s but with the add operands switched.
418 define <vscale x 4 x i32> @uaba_s_commutative(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i32> %c) #0 {
419 ; CHECK-LABEL: uaba_s_commutative:
420 ; CHECK:       // %bb.0:
421 ; CHECK-NEXT:    uaba z0.s, z1.s, z2.s
422 ; CHECK-NEXT:    ret
423   %b.zext = zext <vscale x 4 x i32> %b to <vscale x 4 x i64>
424   %c.zext = zext <vscale x 4 x i32> %c to <vscale x 4 x i64>
425   %sub = sub <vscale x 4 x i64> %b.zext, %c.zext
426   %abs = call <vscale x 4 x i64> @llvm.abs.nxv4i64(<vscale x 4 x i64> %sub, i1 true)
427   %trunc = trunc <vscale x 4 x i64> %abs to <vscale x 4 x i32>
428   %add = add <vscale x 4 x i32> %trunc, %a
429   ret <vscale x 4 x i32> %add
432 declare <vscale x 16 x i8> @llvm.abs.nxv16i8(<vscale x 16 x i8>, i1)
433 declare <vscale x 8 x i16> @llvm.abs.nxv8i16(<vscale x 8 x i16>, i1)
434 declare <vscale x 16 x i16> @llvm.abs.nxv16i16(<vscale x 16 x i16>, i1)
435 declare <vscale x 4 x i32> @llvm.abs.nxv4i32(<vscale x 4 x i32>, i1)
436 declare <vscale x 8 x i32> @llvm.abs.nxv8i32(<vscale x 8 x i32>, i1)
437 declare <vscale x 2 x i64> @llvm.abs.nxv2i64(<vscale x 2 x i64>, i1)
438 declare <vscale x 4 x i64> @llvm.abs.nxv4i64(<vscale x 4 x i64>, i1)
439 declare <vscale x 2 x i128> @llvm.abs.nxv2i128(<vscale x 2 x i128>, i1)
441 declare <vscale x 2 x i1> @llvm.aarch64.sve.ptrue.nxv2i1(i32)
442 declare <vscale x 4 x i1> @llvm.aarch64.sve.ptrue.nxv4i1(i32)
443 declare <vscale x 8 x i1> @llvm.aarch64.sve.ptrue.nxv8i1(i32)
444 declare <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32)
446 declare <vscale x 16 x i8> @llvm.aarch64.sve.sabd.u.nxv16i8(<vscale x 16 x i1>, <vscale x 16 x i8>, <vscale x 16 x i8>)
447 declare <vscale x 8 x i16> @llvm.aarch64.sve.sabd.u.nxv8i16(<vscale x 8 x i1>, <vscale x 8 x i16>, <vscale x 8 x i16>)
448 declare <vscale x 4 x i32> @llvm.aarch64.sve.sabd.u.nxv4i32(<vscale x 4 x i1>, <vscale x 4 x i32>, <vscale x 4 x i32>)
449 declare <vscale x 2 x i64> @llvm.aarch64.sve.sabd.u.nxv2i64(<vscale x 2 x i1>, <vscale x 2 x i64>, <vscale x 2 x i64>)
451 declare <vscale x 16 x i8> @llvm.aarch64.sve.uabd.u.nxv16i8(<vscale x 16 x i1>, <vscale x 16 x i8>, <vscale x 16 x i8>)
452 declare <vscale x 8 x i16> @llvm.aarch64.sve.uabd.u.nxv8i16(<vscale x 8 x i1>, <vscale x 8 x i16>, <vscale x 8 x i16>)
453 declare <vscale x 4 x i32> @llvm.aarch64.sve.uabd.u.nxv4i32(<vscale x 4 x i1>, <vscale x 4 x i32>, <vscale x 4 x i32>)
454 declare <vscale x 2 x i64> @llvm.aarch64.sve.uabd.u.nxv2i64(<vscale x 2 x i1>, <vscale x 2 x i64>, <vscale x 2 x i64>)
456 attributes #0 = { "target-features"="+neon,+sve,+sve2" }