xref: /llvm-project/llvm/test/CodeGen/AArch64/arm64-vabs.ll (revision 895a8e66c6d1e42519909981ab1bb0ad41231029)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=arm64-eabi -aarch64-neon-syntax=apple | FileCheck -check-prefixes=CHECK,CHECK-SD %s
3; RUN: llc < %s -mtriple=arm64-eabi -aarch64-neon-syntax=apple -global-isel -global-isel-abort=2 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI
4
5; CHECK-GI:  warning: Instruction selection used fallback path for fabds
6; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fabdd
7; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for uabd_i64
8
9define <8 x i16> @sabdl8h(ptr %A, ptr %B) nounwind {
10; CHECK-LABEL: sabdl8h:
11; CHECK:       // %bb.0:
12; CHECK-NEXT:    ldr d0, [x0]
13; CHECK-NEXT:    ldr d1, [x1]
14; CHECK-NEXT:    sabdl.8h v0, v0, v1
15; CHECK-NEXT:    ret
16  %tmp1 = load <8 x i8>, ptr %A
17  %tmp2 = load <8 x i8>, ptr %B
18  %tmp3 = call <8 x i8> @llvm.aarch64.neon.sabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2)
19  %tmp4 = zext <8 x i8> %tmp3 to <8 x i16>
20  ret <8 x i16> %tmp4
21}
22
23define <4 x i32> @sabdl4s(ptr %A, ptr %B) nounwind {
24; CHECK-LABEL: sabdl4s:
25; CHECK:       // %bb.0:
26; CHECK-NEXT:    ldr d0, [x0]
27; CHECK-NEXT:    ldr d1, [x1]
28; CHECK-NEXT:    sabdl.4s v0, v0, v1
29; CHECK-NEXT:    ret
30  %tmp1 = load <4 x i16>, ptr %A
31  %tmp2 = load <4 x i16>, ptr %B
32  %tmp3 = call <4 x i16> @llvm.aarch64.neon.sabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2)
33  %tmp4 = zext <4 x i16> %tmp3 to <4 x i32>
34  ret <4 x i32> %tmp4
35}
36
37define <2 x i64> @sabdl2d(ptr %A, ptr %B) nounwind {
38; CHECK-LABEL: sabdl2d:
39; CHECK:       // %bb.0:
40; CHECK-NEXT:    ldr d0, [x0]
41; CHECK-NEXT:    ldr d1, [x1]
42; CHECK-NEXT:    sabdl.2d v0, v0, v1
43; CHECK-NEXT:    ret
44  %tmp1 = load <2 x i32>, ptr %A
45  %tmp2 = load <2 x i32>, ptr %B
46  %tmp3 = call <2 x i32> @llvm.aarch64.neon.sabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2)
47  %tmp4 = zext <2 x i32> %tmp3 to <2 x i64>
48  ret <2 x i64> %tmp4
49}
50
51define <8 x i16> @sabdl2_8h(ptr %A, ptr %B) nounwind {
52; CHECK-SD-LABEL: sabdl2_8h:
53; CHECK-SD:       // %bb.0:
54; CHECK-SD-NEXT:    ldr d0, [x0, #8]
55; CHECK-SD-NEXT:    ldr d1, [x1, #8]
56; CHECK-SD-NEXT:    sabdl.8h v0, v0, v1
57; CHECK-SD-NEXT:    ret
58;
59; CHECK-GI-LABEL: sabdl2_8h:
60; CHECK-GI:       // %bb.0:
61; CHECK-GI-NEXT:    ldr q0, [x0]
62; CHECK-GI-NEXT:    ldr q1, [x1]
63; CHECK-GI-NEXT:    sabdl2.8h v0, v0, v1
64; CHECK-GI-NEXT:    ret
65  %load1 = load <16 x i8>, ptr %A
66  %load2 = load <16 x i8>, ptr %B
67  %tmp1 = shufflevector <16 x i8> %load1, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
68  %tmp2 = shufflevector <16 x i8> %load2, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
69  %tmp3 = call <8 x i8> @llvm.aarch64.neon.sabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2)
70  %tmp4 = zext <8 x i8> %tmp3 to <8 x i16>
71  ret <8 x i16> %tmp4
72}
73
74define <4 x i32> @sabdl2_4s(ptr %A, ptr %B) nounwind {
75; CHECK-SD-LABEL: sabdl2_4s:
76; CHECK-SD:       // %bb.0:
77; CHECK-SD-NEXT:    ldr d0, [x0, #8]
78; CHECK-SD-NEXT:    ldr d1, [x1, #8]
79; CHECK-SD-NEXT:    sabdl.4s v0, v0, v1
80; CHECK-SD-NEXT:    ret
81;
82; CHECK-GI-LABEL: sabdl2_4s:
83; CHECK-GI:       // %bb.0:
84; CHECK-GI-NEXT:    ldr q0, [x0]
85; CHECK-GI-NEXT:    ldr q1, [x1]
86; CHECK-GI-NEXT:    sabdl2.4s v0, v0, v1
87; CHECK-GI-NEXT:    ret
88  %load1 = load <8 x i16>, ptr %A
89  %load2 = load <8 x i16>, ptr %B
90  %tmp1 = shufflevector <8 x i16> %load1, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
91  %tmp2 = shufflevector <8 x i16> %load2, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
92  %tmp3 = call <4 x i16> @llvm.aarch64.neon.sabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2)
93  %tmp4 = zext <4 x i16> %tmp3 to <4 x i32>
94  ret <4 x i32> %tmp4
95}
96
97define <2 x i64> @sabdl2_2d(ptr %A, ptr %B) nounwind {
98; CHECK-SD-LABEL: sabdl2_2d:
99; CHECK-SD:       // %bb.0:
100; CHECK-SD-NEXT:    ldr d0, [x0, #8]
101; CHECK-SD-NEXT:    ldr d1, [x1, #8]
102; CHECK-SD-NEXT:    sabdl.2d v0, v0, v1
103; CHECK-SD-NEXT:    ret
104;
105; CHECK-GI-LABEL: sabdl2_2d:
106; CHECK-GI:       // %bb.0:
107; CHECK-GI-NEXT:    ldr q0, [x0]
108; CHECK-GI-NEXT:    ldr q1, [x1]
109; CHECK-GI-NEXT:    sabdl2.2d v0, v0, v1
110; CHECK-GI-NEXT:    ret
111  %load1 = load <4 x i32>, ptr %A
112  %load2 = load <4 x i32>, ptr %B
113  %tmp1 = shufflevector <4 x i32> %load1, <4 x i32> undef, <2 x i32> <i32 2, i32 3>
114  %tmp2 = shufflevector <4 x i32> %load2, <4 x i32> undef, <2 x i32> <i32 2, i32 3>
115  %tmp3 = call <2 x i32> @llvm.aarch64.neon.sabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2)
116  %tmp4 = zext <2 x i32> %tmp3 to <2 x i64>
117  ret <2 x i64> %tmp4
118}
119
120define <8 x i16> @uabdl8h(ptr %A, ptr %B) nounwind {
121; CHECK-LABEL: uabdl8h:
122; CHECK:       // %bb.0:
123; CHECK-NEXT:    ldr d0, [x0]
124; CHECK-NEXT:    ldr d1, [x1]
125; CHECK-NEXT:    uabdl.8h v0, v0, v1
126; CHECK-NEXT:    ret
127  %tmp1 = load <8 x i8>, ptr %A
128  %tmp2 = load <8 x i8>, ptr %B
129  %tmp3 = call <8 x i8> @llvm.aarch64.neon.uabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2)
130  %tmp4 = zext <8 x i8> %tmp3 to <8 x i16>
131  ret <8 x i16> %tmp4
132}
133
134define <4 x i32> @uabdl4s(ptr %A, ptr %B) nounwind {
135; CHECK-LABEL: uabdl4s:
136; CHECK:       // %bb.0:
137; CHECK-NEXT:    ldr d0, [x0]
138; CHECK-NEXT:    ldr d1, [x1]
139; CHECK-NEXT:    uabdl.4s v0, v0, v1
140; CHECK-NEXT:    ret
141  %tmp1 = load <4 x i16>, ptr %A
142  %tmp2 = load <4 x i16>, ptr %B
143  %tmp3 = call <4 x i16> @llvm.aarch64.neon.uabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2)
144  %tmp4 = zext <4 x i16> %tmp3 to <4 x i32>
145  ret <4 x i32> %tmp4
146}
147
148define <2 x i64> @uabdl2d(ptr %A, ptr %B) nounwind {
149; CHECK-LABEL: uabdl2d:
150; CHECK:       // %bb.0:
151; CHECK-NEXT:    ldr d0, [x0]
152; CHECK-NEXT:    ldr d1, [x1]
153; CHECK-NEXT:    uabdl.2d v0, v0, v1
154; CHECK-NEXT:    ret
155  %tmp1 = load <2 x i32>, ptr %A
156  %tmp2 = load <2 x i32>, ptr %B
157  %tmp3 = call <2 x i32> @llvm.aarch64.neon.uabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2)
158  %tmp4 = zext <2 x i32> %tmp3 to <2 x i64>
159  ret <2 x i64> %tmp4
160}
161
162define <8 x i16> @uabdl2_8h(ptr %A, ptr %B) nounwind {
163; CHECK-SD-LABEL: uabdl2_8h:
164; CHECK-SD:       // %bb.0:
165; CHECK-SD-NEXT:    ldr d0, [x0, #8]
166; CHECK-SD-NEXT:    ldr d1, [x1, #8]
167; CHECK-SD-NEXT:    uabdl.8h v0, v0, v1
168; CHECK-SD-NEXT:    ret
169;
170; CHECK-GI-LABEL: uabdl2_8h:
171; CHECK-GI:       // %bb.0:
172; CHECK-GI-NEXT:    ldr q0, [x0]
173; CHECK-GI-NEXT:    ldr q1, [x1]
174; CHECK-GI-NEXT:    uabdl2.8h v0, v0, v1
175; CHECK-GI-NEXT:    ret
176  %load1 = load <16 x i8>, ptr %A
177  %load2 = load <16 x i8>, ptr %B
178  %tmp1 = shufflevector <16 x i8> %load1, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
179  %tmp2 = shufflevector <16 x i8> %load2, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
180
181  %tmp3 = call <8 x i8> @llvm.aarch64.neon.uabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2)
182  %tmp4 = zext <8 x i8> %tmp3 to <8 x i16>
183  ret <8 x i16> %tmp4
184}
185
186define <4 x i32> @uabdl2_4s(ptr %A, ptr %B) nounwind {
187; CHECK-SD-LABEL: uabdl2_4s:
188; CHECK-SD:       // %bb.0:
189; CHECK-SD-NEXT:    ldr d0, [x0, #8]
190; CHECK-SD-NEXT:    ldr d1, [x1, #8]
191; CHECK-SD-NEXT:    uabdl.4s v0, v0, v1
192; CHECK-SD-NEXT:    ret
193;
194; CHECK-GI-LABEL: uabdl2_4s:
195; CHECK-GI:       // %bb.0:
196; CHECK-GI-NEXT:    ldr q0, [x0]
197; CHECK-GI-NEXT:    ldr q1, [x1]
198; CHECK-GI-NEXT:    uabdl2.4s v0, v0, v1
199; CHECK-GI-NEXT:    ret
200  %load1 = load <8 x i16>, ptr %A
201  %load2 = load <8 x i16>, ptr %B
202  %tmp1 = shufflevector <8 x i16> %load1, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
203  %tmp2 = shufflevector <8 x i16> %load2, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
204  %tmp3 = call <4 x i16> @llvm.aarch64.neon.uabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2)
205  %tmp4 = zext <4 x i16> %tmp3 to <4 x i32>
206  ret <4 x i32> %tmp4
207}
208
209define <2 x i64> @uabdl2_2d(ptr %A, ptr %B) nounwind {
210; CHECK-SD-LABEL: uabdl2_2d:
211; CHECK-SD:       // %bb.0:
212; CHECK-SD-NEXT:    ldr d0, [x0, #8]
213; CHECK-SD-NEXT:    ldr d1, [x1, #8]
214; CHECK-SD-NEXT:    uabdl.2d v0, v0, v1
215; CHECK-SD-NEXT:    ret
216;
217; CHECK-GI-LABEL: uabdl2_2d:
218; CHECK-GI:       // %bb.0:
219; CHECK-GI-NEXT:    ldr q0, [x0]
220; CHECK-GI-NEXT:    ldr q1, [x1]
221; CHECK-GI-NEXT:    uabdl2.2d v0, v0, v1
222; CHECK-GI-NEXT:    ret
223  %load1 = load <4 x i32>, ptr %A
224  %load2 = load <4 x i32>, ptr %B
225  %tmp1 = shufflevector <4 x i32> %load1, <4 x i32> undef, <2 x i32> <i32 2, i32 3>
226  %tmp2 = shufflevector <4 x i32> %load2, <4 x i32> undef, <2 x i32> <i32 2, i32 3>
227  %tmp3 = call <2 x i32> @llvm.aarch64.neon.uabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2)
228  %tmp4 = zext <2 x i32> %tmp3 to <2 x i64>
229  ret <2 x i64> %tmp4
230}
231
232declare i16 @llvm.vector.reduce.add.v16i16(<16 x i16>)
233declare i32 @llvm.vector.reduce.add.v16i32(<16 x i32>)
234
235define i16 @uabd16b_rdx(ptr %a, ptr %b) {
236; CHECK-SD-LABEL: uabd16b_rdx:
237; CHECK-SD:       // %bb.0:
238; CHECK-SD-NEXT:    ldr q0, [x0]
239; CHECK-SD-NEXT:    ldr q1, [x1]
240; CHECK-SD-NEXT:    uabd.16b v0, v0, v1
241; CHECK-SD-NEXT:    uaddlv.16b h0, v0
242; CHECK-SD-NEXT:    fmov w0, s0
243; CHECK-SD-NEXT:    ret
244;
245; CHECK-GI-LABEL: uabd16b_rdx:
246; CHECK-GI:       // %bb.0:
247; CHECK-GI-NEXT:    ldr q0, [x0]
248; CHECK-GI-NEXT:    ldr q1, [x1]
249; CHECK-GI-NEXT:    usubl.8h v2, v0, v1
250; CHECK-GI-NEXT:    usubl2.8h v0, v0, v1
251; CHECK-GI-NEXT:    cmlt.8h v1, v2, #0
252; CHECK-GI-NEXT:    cmlt.8h v3, v0, #0
253; CHECK-GI-NEXT:    neg.8h v4, v2
254; CHECK-GI-NEXT:    neg.8h v5, v0
255; CHECK-GI-NEXT:    bsl.16b v1, v4, v2
256; CHECK-GI-NEXT:    bit.16b v0, v5, v3
257; CHECK-GI-NEXT:    add.8h v0, v1, v0
258; CHECK-GI-NEXT:    addv.8h h0, v0
259; CHECK-GI-NEXT:    fmov w0, s0
260; CHECK-GI-NEXT:    ret
261  %aload = load <16 x i8>, ptr %a, align 1
262  %bload = load <16 x i8>, ptr %b, align 1
263  %aext = zext <16 x i8> %aload to <16 x i16>
264  %bext = zext <16 x i8> %bload to <16 x i16>
265  %abdiff = sub nsw <16 x i16> %aext, %bext
266  %abcmp = icmp slt <16 x i16> %abdiff, zeroinitializer
267  %ababs = sub nsw <16 x i16> zeroinitializer, %abdiff
268  %absel = select <16 x i1> %abcmp, <16 x i16> %ababs, <16 x i16> %abdiff
269  %reduced_v = call i16 @llvm.vector.reduce.add.v16i16(<16 x i16> %absel)
270  ret i16 %reduced_v
271}
272
273define i32 @uabd16b_rdx_i32(<16 x i8> %a, <16 x i8> %b) {
274; CHECK-SD-LABEL: uabd16b_rdx_i32:
275; CHECK-SD:       // %bb.0:
276; CHECK-SD-NEXT:    uabdl.8h v2, v0, v1
277; CHECK-SD-NEXT:    uabal2.8h v2, v0, v1
278; CHECK-SD-NEXT:    uaddlv.8h s0, v2
279; CHECK-SD-NEXT:    fmov w0, s0
280; CHECK-SD-NEXT:    ret
281;
282; CHECK-GI-LABEL: uabd16b_rdx_i32:
283; CHECK-GI:       // %bb.0:
284; CHECK-GI-NEXT:    usubl.8h v3, v0, v1
285; CHECK-GI-NEXT:    movi.2d v2, #0000000000000000
286; CHECK-GI-NEXT:    usubl2.8h v0, v0, v1
287; CHECK-GI-NEXT:    sshll.4s v1, v3, #0
288; CHECK-GI-NEXT:    sshll2.4s v4, v3, #0
289; CHECK-GI-NEXT:    sshll.4s v5, v0, #0
290; CHECK-GI-NEXT:    sshll2.4s v6, v0, #0
291; CHECK-GI-NEXT:    ssubw2.4s v3, v2, v3
292; CHECK-GI-NEXT:    ssubw2.4s v0, v2, v0
293; CHECK-GI-NEXT:    cmlt.4s v2, v1, #0
294; CHECK-GI-NEXT:    cmlt.4s v7, v4, #0
295; CHECK-GI-NEXT:    neg.4s v16, v1
296; CHECK-GI-NEXT:    cmlt.4s v17, v5, #0
297; CHECK-GI-NEXT:    cmlt.4s v18, v6, #0
298; CHECK-GI-NEXT:    neg.4s v19, v5
299; CHECK-GI-NEXT:    bit.16b v1, v16, v2
300; CHECK-GI-NEXT:    mov.16b v2, v7
301; CHECK-GI-NEXT:    bif.16b v0, v6, v18
302; CHECK-GI-NEXT:    bsl.16b v2, v3, v4
303; CHECK-GI-NEXT:    mov.16b v3, v17
304; CHECK-GI-NEXT:    bsl.16b v3, v19, v5
305; CHECK-GI-NEXT:    add.4s v1, v1, v2
306; CHECK-GI-NEXT:    add.4s v0, v3, v0
307; CHECK-GI-NEXT:    add.4s v0, v1, v0
308; CHECK-GI-NEXT:    addv.4s s0, v0
309; CHECK-GI-NEXT:    fmov w0, s0
310; CHECK-GI-NEXT:    ret
311  %aext = zext <16 x i8> %a to <16 x i32>
312  %bext = zext <16 x i8> %b to <16 x i32>
313  %abdiff = sub nsw <16 x i32> %aext, %bext
314  %abcmp = icmp slt <16 x i32> %abdiff, zeroinitializer
315  %ababs = sub nsw <16 x i32> zeroinitializer, %abdiff
316  %absel = select <16 x i1> %abcmp, <16 x i32> %ababs, <16 x i32> %abdiff
317  %reduced_v = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %absel)
318  ret i32 %reduced_v
319}
320
321define i32 @sabd16b_rdx_i32(<16 x i8> %a, <16 x i8> %b) {
322; CHECK-SD-LABEL: sabd16b_rdx_i32:
323; CHECK-SD:       // %bb.0:
324; CHECK-SD-NEXT:    sabdl.8h v2, v0, v1
325; CHECK-SD-NEXT:    sabal2.8h v2, v0, v1
326; CHECK-SD-NEXT:    uaddlv.8h s0, v2
327; CHECK-SD-NEXT:    fmov w0, s0
328; CHECK-SD-NEXT:    ret
329;
330; CHECK-GI-LABEL: sabd16b_rdx_i32:
331; CHECK-GI:       // %bb.0:
332; CHECK-GI-NEXT:    ssubl.8h v3, v0, v1
333; CHECK-GI-NEXT:    movi.2d v2, #0000000000000000
334; CHECK-GI-NEXT:    ssubl2.8h v0, v0, v1
335; CHECK-GI-NEXT:    sshll.4s v1, v3, #0
336; CHECK-GI-NEXT:    sshll2.4s v4, v3, #0
337; CHECK-GI-NEXT:    sshll.4s v5, v0, #0
338; CHECK-GI-NEXT:    sshll2.4s v6, v0, #0
339; CHECK-GI-NEXT:    ssubw2.4s v3, v2, v3
340; CHECK-GI-NEXT:    ssubw2.4s v0, v2, v0
341; CHECK-GI-NEXT:    cmlt.4s v2, v1, #0
342; CHECK-GI-NEXT:    cmlt.4s v7, v4, #0
343; CHECK-GI-NEXT:    neg.4s v16, v1
344; CHECK-GI-NEXT:    cmlt.4s v17, v5, #0
345; CHECK-GI-NEXT:    cmlt.4s v18, v6, #0
346; CHECK-GI-NEXT:    neg.4s v19, v5
347; CHECK-GI-NEXT:    bit.16b v1, v16, v2
348; CHECK-GI-NEXT:    mov.16b v2, v7
349; CHECK-GI-NEXT:    bif.16b v0, v6, v18
350; CHECK-GI-NEXT:    bsl.16b v2, v3, v4
351; CHECK-GI-NEXT:    mov.16b v3, v17
352; CHECK-GI-NEXT:    bsl.16b v3, v19, v5
353; CHECK-GI-NEXT:    add.4s v1, v1, v2
354; CHECK-GI-NEXT:    add.4s v0, v3, v0
355; CHECK-GI-NEXT:    add.4s v0, v1, v0
356; CHECK-GI-NEXT:    addv.4s s0, v0
357; CHECK-GI-NEXT:    fmov w0, s0
358; CHECK-GI-NEXT:    ret
359  %aext = sext <16 x i8> %a to <16 x i32>
360  %bext = sext <16 x i8> %b to <16 x i32>
361  %abdiff = sub nsw <16 x i32> %aext, %bext
362  %abcmp = icmp slt <16 x i32> %abdiff, zeroinitializer
363  %ababs = sub nsw <16 x i32> zeroinitializer, %abdiff
364  %absel = select <16 x i1> %abcmp, <16 x i32> %ababs, <16 x i32> %abdiff
365  %reduced_v = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %absel)
366  ret i32 %reduced_v
367}
368
369
370declare i32 @llvm.vector.reduce.add.v8i32(<8 x i32>)
371declare i32 @llvm.vector.reduce.add.v4i32(<4 x i32>)
372
373define i32 @uabd8h_rdx(ptr %a, ptr %b) {
374; CHECK-SD-LABEL: uabd8h_rdx:
375; CHECK-SD:       // %bb.0:
376; CHECK-SD-NEXT:    ldr q0, [x0]
377; CHECK-SD-NEXT:    ldr q1, [x1]
378; CHECK-SD-NEXT:    uabd.8h v0, v0, v1
379; CHECK-SD-NEXT:    uaddlv.8h s0, v0
380; CHECK-SD-NEXT:    fmov w0, s0
381; CHECK-SD-NEXT:    ret
382;
383; CHECK-GI-LABEL: uabd8h_rdx:
384; CHECK-GI:       // %bb.0:
385; CHECK-GI-NEXT:    ldr q0, [x0]
386; CHECK-GI-NEXT:    ldr q1, [x1]
387; CHECK-GI-NEXT:    usubl.4s v2, v0, v1
388; CHECK-GI-NEXT:    usubl2.4s v0, v0, v1
389; CHECK-GI-NEXT:    cmlt.4s v1, v2, #0
390; CHECK-GI-NEXT:    cmlt.4s v3, v0, #0
391; CHECK-GI-NEXT:    neg.4s v4, v2
392; CHECK-GI-NEXT:    neg.4s v5, v0
393; CHECK-GI-NEXT:    bsl.16b v1, v4, v2
394; CHECK-GI-NEXT:    bit.16b v0, v5, v3
395; CHECK-GI-NEXT:    add.4s v0, v1, v0
396; CHECK-GI-NEXT:    addv.4s s0, v0
397; CHECK-GI-NEXT:    fmov w0, s0
398; CHECK-GI-NEXT:    ret
399  %aload = load <8 x i16>, ptr %a, align 1
400  %bload = load <8 x i16>, ptr %b, align 1
401  %aext = zext <8 x i16> %aload to <8 x i32>
402  %bext = zext <8 x i16> %bload to <8 x i32>
403  %abdiff = sub nsw <8 x i32> %aext, %bext
404  %abcmp = icmp slt <8 x i32> %abdiff, zeroinitializer
405  %ababs = sub nsw <8 x i32> zeroinitializer, %abdiff
406  %absel = select <8 x i1> %abcmp, <8 x i32> %ababs, <8 x i32> %abdiff
407  %reduced_v = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %absel)
408  ret i32 %reduced_v
409}
410
411define i32 @sabd8h_rdx(<8 x i16> %a, <8 x i16> %b) {
412; CHECK-SD-LABEL: sabd8h_rdx:
413; CHECK-SD:       // %bb.0:
414; CHECK-SD-NEXT:    sabd.8h v0, v0, v1
415; CHECK-SD-NEXT:    uaddlv.8h s0, v0
416; CHECK-SD-NEXT:    fmov w0, s0
417; CHECK-SD-NEXT:    ret
418;
419; CHECK-GI-LABEL: sabd8h_rdx:
420; CHECK-GI:       // %bb.0:
421; CHECK-GI-NEXT:    ssubl.4s v2, v0, v1
422; CHECK-GI-NEXT:    ssubl2.4s v0, v0, v1
423; CHECK-GI-NEXT:    cmlt.4s v1, v2, #0
424; CHECK-GI-NEXT:    cmlt.4s v3, v0, #0
425; CHECK-GI-NEXT:    neg.4s v4, v2
426; CHECK-GI-NEXT:    neg.4s v5, v0
427; CHECK-GI-NEXT:    bsl.16b v1, v4, v2
428; CHECK-GI-NEXT:    bit.16b v0, v5, v3
429; CHECK-GI-NEXT:    add.4s v0, v1, v0
430; CHECK-GI-NEXT:    addv.4s s0, v0
431; CHECK-GI-NEXT:    fmov w0, s0
432; CHECK-GI-NEXT:    ret
433  %aext = sext <8 x i16> %a to <8 x i32>
434  %bext = sext <8 x i16> %b to <8 x i32>
435  %abdiff = sub nsw <8 x i32> %aext, %bext
436  %abcmp = icmp slt <8 x i32> %abdiff, zeroinitializer
437  %ababs = sub nsw <8 x i32> zeroinitializer, %abdiff
438  %absel = select <8 x i1> %abcmp, <8 x i32> %ababs, <8 x i32> %abdiff
439  %reduced_v = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %absel)
440  ret i32 %reduced_v
441}
442
443define i32 @uabdl4s_rdx_i32(<4 x i16> %a, <4 x i16> %b) {
444; CHECK-SD-LABEL: uabdl4s_rdx_i32:
445; CHECK-SD:       // %bb.0:
446; CHECK-SD-NEXT:    uabdl.4s v0, v0, v1
447; CHECK-SD-NEXT:    addv.4s s0, v0
448; CHECK-SD-NEXT:    fmov w0, s0
449; CHECK-SD-NEXT:    ret
450;
451; CHECK-GI-LABEL: uabdl4s_rdx_i32:
452; CHECK-GI:       // %bb.0:
453; CHECK-GI-NEXT:    usubl.4s v0, v0, v1
454; CHECK-GI-NEXT:    cmlt.4s v1, v0, #0
455; CHECK-GI-NEXT:    neg.4s v2, v0
456; CHECK-GI-NEXT:    bit.16b v0, v2, v1
457; CHECK-GI-NEXT:    addv.4s s0, v0
458; CHECK-GI-NEXT:    fmov w0, s0
459; CHECK-GI-NEXT:    ret
460  %aext = zext <4 x i16> %a to <4 x i32>
461  %bext = zext <4 x i16> %b to <4 x i32>
462  %abdiff = sub nsw <4 x i32> %aext, %bext
463  %abcmp = icmp slt <4 x i32> %abdiff, zeroinitializer
464  %ababs = sub nsw <4 x i32> zeroinitializer, %abdiff
465  %absel = select <4 x i1> %abcmp, <4 x i32> %ababs, <4 x i32> %abdiff
466  %reduced_v = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %absel)
467  ret i32 %reduced_v
468}
469
470declare i64 @llvm.vector.reduce.add.v4i64(<4 x i64>)
471declare i64 @llvm.vector.reduce.add.v2i64(<2 x i64>)
472
473define i64 @uabd4s_rdx(ptr %a, ptr %b, i32 %h) {
474; CHECK-SD-LABEL: uabd4s_rdx:
475; CHECK-SD:       // %bb.0:
476; CHECK-SD-NEXT:    ldr q0, [x0]
477; CHECK-SD-NEXT:    ldr q1, [x1]
478; CHECK-SD-NEXT:    uabd.4s v0, v0, v1
479; CHECK-SD-NEXT:    uaddlv.4s d0, v0
480; CHECK-SD-NEXT:    fmov x0, d0
481; CHECK-SD-NEXT:    ret
482;
483; CHECK-GI-LABEL: uabd4s_rdx:
484; CHECK-GI:       // %bb.0:
485; CHECK-GI-NEXT:    ldr q0, [x0]
486; CHECK-GI-NEXT:    ldr q1, [x1]
487; CHECK-GI-NEXT:    usubl.2d v2, v0, v1
488; CHECK-GI-NEXT:    usubl2.2d v0, v0, v1
489; CHECK-GI-NEXT:    cmlt.2d v1, v2, #0
490; CHECK-GI-NEXT:    cmlt.2d v3, v0, #0
491; CHECK-GI-NEXT:    neg.2d v4, v2
492; CHECK-GI-NEXT:    neg.2d v5, v0
493; CHECK-GI-NEXT:    bsl.16b v1, v4, v2
494; CHECK-GI-NEXT:    bit.16b v0, v5, v3
495; CHECK-GI-NEXT:    add.2d v0, v1, v0
496; CHECK-GI-NEXT:    addp.2d d0, v0
497; CHECK-GI-NEXT:    fmov x0, d0
498; CHECK-GI-NEXT:    ret
499  %aload = load <4 x i32>, ptr %a, align 1
500  %bload = load <4 x i32>, ptr %b, align 1
501  %aext = zext <4 x i32> %aload to <4 x i64>
502  %bext = zext <4 x i32> %bload to <4 x i64>
503  %abdiff = sub nsw <4 x i64> %aext, %bext
504  %abcmp = icmp slt <4 x i64> %abdiff, zeroinitializer
505  %ababs = sub nsw <4 x i64> zeroinitializer, %abdiff
506  %absel = select <4 x i1> %abcmp, <4 x i64> %ababs, <4 x i64> %abdiff
507  %reduced_v = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %absel)
508  ret i64 %reduced_v
509}
510
511define i64 @sabd4s_rdx(<4 x i32> %a, <4 x i32> %b) {
512; CHECK-SD-LABEL: sabd4s_rdx:
513; CHECK-SD:       // %bb.0:
514; CHECK-SD-NEXT:    sabd.4s v0, v0, v1
515; CHECK-SD-NEXT:    uaddlv.4s d0, v0
516; CHECK-SD-NEXT:    fmov x0, d0
517; CHECK-SD-NEXT:    ret
518;
519; CHECK-GI-LABEL: sabd4s_rdx:
520; CHECK-GI:       // %bb.0:
521; CHECK-GI-NEXT:    ssubl.2d v2, v0, v1
522; CHECK-GI-NEXT:    ssubl2.2d v0, v0, v1
523; CHECK-GI-NEXT:    cmlt.2d v1, v2, #0
524; CHECK-GI-NEXT:    cmlt.2d v3, v0, #0
525; CHECK-GI-NEXT:    neg.2d v4, v2
526; CHECK-GI-NEXT:    neg.2d v5, v0
527; CHECK-GI-NEXT:    bsl.16b v1, v4, v2
528; CHECK-GI-NEXT:    bit.16b v0, v5, v3
529; CHECK-GI-NEXT:    add.2d v0, v1, v0
530; CHECK-GI-NEXT:    addp.2d d0, v0
531; CHECK-GI-NEXT:    fmov x0, d0
532; CHECK-GI-NEXT:    ret
533  %aext = sext <4 x i32> %a to <4 x i64>
534  %bext = sext <4 x i32> %b to <4 x i64>
535  %abdiff = sub nsw <4 x i64> %aext, %bext
536  %abcmp = icmp slt <4 x i64> %abdiff, zeroinitializer
537  %ababs = sub nsw <4 x i64> zeroinitializer, %abdiff
538  %absel = select <4 x i1> %abcmp, <4 x i64> %ababs, <4 x i64> %abdiff
539  %reduced_v = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %absel)
540  ret i64 %reduced_v
541}
542
543define i64 @uabdl2d_rdx_i64(<2 x i32> %a, <2 x i32> %b) {
544; CHECK-SD-LABEL: uabdl2d_rdx_i64:
545; CHECK-SD:       // %bb.0:
546; CHECK-SD-NEXT:    uabdl.2d v0, v0, v1
547; CHECK-SD-NEXT:    addp.2d d0, v0
548; CHECK-SD-NEXT:    fmov x0, d0
549; CHECK-SD-NEXT:    ret
550;
551; CHECK-GI-LABEL: uabdl2d_rdx_i64:
552; CHECK-GI:       // %bb.0:
553; CHECK-GI-NEXT:    usubl.2d v0, v0, v1
554; CHECK-GI-NEXT:    cmlt.2d v1, v0, #0
555; CHECK-GI-NEXT:    neg.2d v2, v0
556; CHECK-GI-NEXT:    bit.16b v0, v2, v1
557; CHECK-GI-NEXT:    addp.2d d0, v0
558; CHECK-GI-NEXT:    fmov x0, d0
559; CHECK-GI-NEXT:    ret
560  %aext = zext <2 x i32> %a to <2 x i64>
561  %bext = zext <2 x i32> %b to <2 x i64>
562  %abdiff = sub nsw <2 x i64> %aext, %bext
563  %abcmp = icmp slt <2 x i64> %abdiff, zeroinitializer
564  %ababs = sub nsw <2 x i64> zeroinitializer, %abdiff
565  %absel = select <2 x i1> %abcmp, <2 x i64> %ababs, <2 x i64> %abdiff
566  %reduced_v = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %absel)
567  ret i64 %reduced_v
568}
569
570define <2 x float> @fabd_2s(ptr %A, ptr %B) nounwind {
571; CHECK-LABEL: fabd_2s:
572; CHECK:       // %bb.0:
573; CHECK-NEXT:    ldr d0, [x0]
574; CHECK-NEXT:    ldr d1, [x1]
575; CHECK-NEXT:    fabd.2s v0, v0, v1
576; CHECK-NEXT:    ret
577  %tmp1 = load <2 x float>, ptr %A
578  %tmp2 = load <2 x float>, ptr %B
579  %tmp3 = call <2 x float> @llvm.aarch64.neon.fabd.v2f32(<2 x float> %tmp1, <2 x float> %tmp2)
580  ret <2 x float> %tmp3
581}
582
583define <4 x float> @fabd_4s(ptr %A, ptr %B) nounwind {
584; CHECK-LABEL: fabd_4s:
585; CHECK:       // %bb.0:
586; CHECK-NEXT:    ldr q0, [x0]
587; CHECK-NEXT:    ldr q1, [x1]
588; CHECK-NEXT:    fabd.4s v0, v0, v1
589; CHECK-NEXT:    ret
590  %tmp1 = load <4 x float>, ptr %A
591  %tmp2 = load <4 x float>, ptr %B
592  %tmp3 = call <4 x float> @llvm.aarch64.neon.fabd.v4f32(<4 x float> %tmp1, <4 x float> %tmp2)
593  ret <4 x float> %tmp3
594}
595
596define <2 x double> @fabd_2d(ptr %A, ptr %B) nounwind {
597; CHECK-LABEL: fabd_2d:
598; CHECK:       // %bb.0:
599; CHECK-NEXT:    ldr q0, [x0]
600; CHECK-NEXT:    ldr q1, [x1]
601; CHECK-NEXT:    fabd.2d v0, v0, v1
602; CHECK-NEXT:    ret
603  %tmp1 = load <2 x double>, ptr %A
604  %tmp2 = load <2 x double>, ptr %B
605  %tmp3 = call <2 x double> @llvm.aarch64.neon.fabd.v2f64(<2 x double> %tmp1, <2 x double> %tmp2)
606  ret <2 x double> %tmp3
607}
608
609declare <2 x float> @llvm.aarch64.neon.fabd.v2f32(<2 x float>, <2 x float>) nounwind readnone
610declare <4 x float> @llvm.aarch64.neon.fabd.v4f32(<4 x float>, <4 x float>) nounwind readnone
611declare <2 x double> @llvm.aarch64.neon.fabd.v2f64(<2 x double>, <2 x double>) nounwind readnone
612
613define <2 x float> @fabd_2s_from_fsub_fabs(ptr %A, ptr %B) nounwind {
614; CHECK-LABEL: fabd_2s_from_fsub_fabs:
615; CHECK:       // %bb.0:
616; CHECK-NEXT:    ldr d0, [x0]
617; CHECK-NEXT:    ldr d1, [x1]
618; CHECK-NEXT:    fabd.2s v0, v0, v1
619; CHECK-NEXT:    ret
620  %tmp1 = load <2 x float>, ptr %A
621  %tmp2 = load <2 x float>, ptr %B
622  %sub = fsub <2 x float> %tmp1, %tmp2
623  %abs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %sub)
624  ret <2 x float> %abs
625}
626
627define <4 x float> @fabd_4s_from_fsub_fabs(ptr %A, ptr %B) nounwind {
628; CHECK-LABEL: fabd_4s_from_fsub_fabs:
629; CHECK:       // %bb.0:
630; CHECK-NEXT:    ldr q0, [x0]
631; CHECK-NEXT:    ldr q1, [x1]
632; CHECK-NEXT:    fabd.4s v0, v0, v1
633; CHECK-NEXT:    ret
634  %tmp1 = load <4 x float>, ptr %A
635  %tmp2 = load <4 x float>, ptr %B
636  %sub = fsub <4 x float> %tmp1, %tmp2
637  %abs = call <4 x float> @llvm.fabs.v4f32(<4 x float> %sub)
638  ret <4 x float> %abs
639}
640
641define <2 x double> @fabd_2d_from_fsub_fabs(ptr %A, ptr %B) nounwind {
642; CHECK-LABEL: fabd_2d_from_fsub_fabs:
643; CHECK:       // %bb.0:
644; CHECK-NEXT:    ldr q0, [x0]
645; CHECK-NEXT:    ldr q1, [x1]
646; CHECK-NEXT:    fabd.2d v0, v0, v1
647; CHECK-NEXT:    ret
648  %tmp1 = load <2 x double>, ptr %A
649  %tmp2 = load <2 x double>, ptr %B
650  %sub = fsub <2 x double> %tmp1, %tmp2
651  %abs = call <2 x double> @llvm.fabs.v2f64(<2 x double> %sub)
652  ret <2 x double> %abs
653}
654
655declare <2 x float> @llvm.fabs.v2f32(<2 x float>) nounwind readnone
656declare <4 x float> @llvm.fabs.v4f32(<4 x float>) nounwind readnone
657declare <2 x double> @llvm.fabs.v2f64(<2 x double>) nounwind readnone
658
659define <8 x i8> @sabd_8b(ptr %A, ptr %B) nounwind {
660; CHECK-LABEL: sabd_8b:
661; CHECK:       // %bb.0:
662; CHECK-NEXT:    ldr d0, [x0]
663; CHECK-NEXT:    ldr d1, [x1]
664; CHECK-NEXT:    sabd.8b v0, v0, v1
665; CHECK-NEXT:    ret
666  %tmp1 = load <8 x i8>, ptr %A
667  %tmp2 = load <8 x i8>, ptr %B
668  %tmp3 = call <8 x i8> @llvm.aarch64.neon.sabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2)
669  ret <8 x i8> %tmp3
670}
671
672define <16 x i8> @sabd_16b(ptr %A, ptr %B) nounwind {
673; CHECK-LABEL: sabd_16b:
674; CHECK:       // %bb.0:
675; CHECK-NEXT:    ldr q0, [x0]
676; CHECK-NEXT:    ldr q1, [x1]
677; CHECK-NEXT:    sabd.16b v0, v0, v1
678; CHECK-NEXT:    ret
679  %tmp1 = load <16 x i8>, ptr %A
680  %tmp2 = load <16 x i8>, ptr %B
681  %tmp3 = call <16 x i8> @llvm.aarch64.neon.sabd.v16i8(<16 x i8> %tmp1, <16 x i8> %tmp2)
682  ret <16 x i8> %tmp3
683}
684
685define <4 x i16> @sabd_4h(ptr %A, ptr %B) nounwind {
686; CHECK-LABEL: sabd_4h:
687; CHECK:       // %bb.0:
688; CHECK-NEXT:    ldr d0, [x0]
689; CHECK-NEXT:    ldr d1, [x1]
690; CHECK-NEXT:    sabd.4h v0, v0, v1
691; CHECK-NEXT:    ret
692  %tmp1 = load <4 x i16>, ptr %A
693  %tmp2 = load <4 x i16>, ptr %B
694  %tmp3 = call <4 x i16> @llvm.aarch64.neon.sabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2)
695  ret <4 x i16> %tmp3
696}
697
698define <8 x i16> @sabd_8h(ptr %A, ptr %B) nounwind {
699; CHECK-LABEL: sabd_8h:
700; CHECK:       // %bb.0:
701; CHECK-NEXT:    ldr q0, [x0]
702; CHECK-NEXT:    ldr q1, [x1]
703; CHECK-NEXT:    sabd.8h v0, v0, v1
704; CHECK-NEXT:    ret
705  %tmp1 = load <8 x i16>, ptr %A
706  %tmp2 = load <8 x i16>, ptr %B
707  %tmp3 = call <8 x i16> @llvm.aarch64.neon.sabd.v8i16(<8 x i16> %tmp1, <8 x i16> %tmp2)
708  ret <8 x i16> %tmp3
709}
710
711define <2 x i32> @sabd_2s(ptr %A, ptr %B) nounwind {
712; CHECK-LABEL: sabd_2s:
713; CHECK:       // %bb.0:
714; CHECK-NEXT:    ldr d0, [x0]
715; CHECK-NEXT:    ldr d1, [x1]
716; CHECK-NEXT:    sabd.2s v0, v0, v1
717; CHECK-NEXT:    ret
718  %tmp1 = load <2 x i32>, ptr %A
719  %tmp2 = load <2 x i32>, ptr %B
720  %tmp3 = call <2 x i32> @llvm.aarch64.neon.sabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2)
721  ret <2 x i32> %tmp3
722}
723
724define <4 x i32> @sabd_4s(ptr %A, ptr %B) nounwind {
725; CHECK-LABEL: sabd_4s:
726; CHECK:       // %bb.0:
727; CHECK-NEXT:    ldr q0, [x0]
728; CHECK-NEXT:    ldr q1, [x1]
729; CHECK-NEXT:    sabd.4s v0, v0, v1
730; CHECK-NEXT:    ret
731  %tmp1 = load <4 x i32>, ptr %A
732  %tmp2 = load <4 x i32>, ptr %B
733  %tmp3 = call <4 x i32> @llvm.aarch64.neon.sabd.v4i32(<4 x i32> %tmp1, <4 x i32> %tmp2)
734  ret <4 x i32> %tmp3
735}
736
737declare <8 x i8> @llvm.aarch64.neon.sabd.v8i8(<8 x i8>, <8 x i8>) nounwind readnone
738declare <16 x i8> @llvm.aarch64.neon.sabd.v16i8(<16 x i8>, <16 x i8>) nounwind readnone
739declare <4 x i16> @llvm.aarch64.neon.sabd.v4i16(<4 x i16>, <4 x i16>) nounwind readnone
740declare <8 x i16> @llvm.aarch64.neon.sabd.v8i16(<8 x i16>, <8 x i16>) nounwind readnone
741declare <2 x i32> @llvm.aarch64.neon.sabd.v2i32(<2 x i32>, <2 x i32>) nounwind readnone
742declare <4 x i32> @llvm.aarch64.neon.sabd.v4i32(<4 x i32>, <4 x i32>) nounwind readnone
743
744define <8 x i8> @uabd_8b(ptr %A, ptr %B) nounwind {
745; CHECK-LABEL: uabd_8b:
746; CHECK:       // %bb.0:
747; CHECK-NEXT:    ldr d0, [x0]
748; CHECK-NEXT:    ldr d1, [x1]
749; CHECK-NEXT:    uabd.8b v0, v0, v1
750; CHECK-NEXT:    ret
751  %tmp1 = load <8 x i8>, ptr %A
752  %tmp2 = load <8 x i8>, ptr %B
753  %tmp3 = call <8 x i8> @llvm.aarch64.neon.uabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2)
754  ret <8 x i8> %tmp3
755}
756
757define <16 x i8> @uabd_16b(ptr %A, ptr %B) nounwind {
758; CHECK-LABEL: uabd_16b:
759; CHECK:       // %bb.0:
760; CHECK-NEXT:    ldr q0, [x0]
761; CHECK-NEXT:    ldr q1, [x1]
762; CHECK-NEXT:    uabd.16b v0, v0, v1
763; CHECK-NEXT:    ret
764  %tmp1 = load <16 x i8>, ptr %A
765  %tmp2 = load <16 x i8>, ptr %B
766  %tmp3 = call <16 x i8> @llvm.aarch64.neon.uabd.v16i8(<16 x i8> %tmp1, <16 x i8> %tmp2)
767  ret <16 x i8> %tmp3
768}
769
770define <4 x i16> @uabd_4h(ptr %A, ptr %B) nounwind {
771; CHECK-LABEL: uabd_4h:
772; CHECK:       // %bb.0:
773; CHECK-NEXT:    ldr d0, [x0]
774; CHECK-NEXT:    ldr d1, [x1]
775; CHECK-NEXT:    uabd.4h v0, v0, v1
776; CHECK-NEXT:    ret
777  %tmp1 = load <4 x i16>, ptr %A
778  %tmp2 = load <4 x i16>, ptr %B
779  %tmp3 = call <4 x i16> @llvm.aarch64.neon.uabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2)
780  ret <4 x i16> %tmp3
781}
782
783define <8 x i16> @uabd_8h(ptr %A, ptr %B) nounwind {
784; CHECK-LABEL: uabd_8h:
785; CHECK:       // %bb.0:
786; CHECK-NEXT:    ldr q0, [x0]
787; CHECK-NEXT:    ldr q1, [x1]
788; CHECK-NEXT:    uabd.8h v0, v0, v1
789; CHECK-NEXT:    ret
790  %tmp1 = load <8 x i16>, ptr %A
791  %tmp2 = load <8 x i16>, ptr %B
792  %tmp3 = call <8 x i16> @llvm.aarch64.neon.uabd.v8i16(<8 x i16> %tmp1, <8 x i16> %tmp2)
793  ret <8 x i16> %tmp3
794}
795
796define <2 x i32> @uabd_2s(ptr %A, ptr %B) nounwind {
797; CHECK-LABEL: uabd_2s:
798; CHECK:       // %bb.0:
799; CHECK-NEXT:    ldr d0, [x0]
800; CHECK-NEXT:    ldr d1, [x1]
801; CHECK-NEXT:    uabd.2s v0, v0, v1
802; CHECK-NEXT:    ret
803  %tmp1 = load <2 x i32>, ptr %A
804  %tmp2 = load <2 x i32>, ptr %B
805  %tmp3 = call <2 x i32> @llvm.aarch64.neon.uabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2)
806  ret <2 x i32> %tmp3
807}
808
809define <4 x i32> @uabd_4s(ptr %A, ptr %B) nounwind {
810; CHECK-LABEL: uabd_4s:
811; CHECK:       // %bb.0:
812; CHECK-NEXT:    ldr q0, [x0]
813; CHECK-NEXT:    ldr q1, [x1]
814; CHECK-NEXT:    uabd.4s v0, v0, v1
815; CHECK-NEXT:    ret
816  %tmp1 = load <4 x i32>, ptr %A
817  %tmp2 = load <4 x i32>, ptr %B
818  %tmp3 = call <4 x i32> @llvm.aarch64.neon.uabd.v4i32(<4 x i32> %tmp1, <4 x i32> %tmp2)
819  ret <4 x i32> %tmp3
820}
821
822declare <8 x i8> @llvm.aarch64.neon.uabd.v8i8(<8 x i8>, <8 x i8>) nounwind readnone
823declare <16 x i8> @llvm.aarch64.neon.uabd.v16i8(<16 x i8>, <16 x i8>) nounwind readnone
824declare <4 x i16> @llvm.aarch64.neon.uabd.v4i16(<4 x i16>, <4 x i16>) nounwind readnone
825declare <8 x i16> @llvm.aarch64.neon.uabd.v8i16(<8 x i16>, <8 x i16>) nounwind readnone
826declare <2 x i32> @llvm.aarch64.neon.uabd.v2i32(<2 x i32>, <2 x i32>) nounwind readnone
827declare <4 x i32> @llvm.aarch64.neon.uabd.v4i32(<4 x i32>, <4 x i32>) nounwind readnone
828
829define <8 x i8> @sqabs_8b(ptr %A) nounwind {
830; CHECK-LABEL: sqabs_8b:
831; CHECK:       // %bb.0:
832; CHECK-NEXT:    ldr d0, [x0]
833; CHECK-NEXT:    sqabs.8b v0, v0
834; CHECK-NEXT:    ret
835  %tmp1 = load <8 x i8>, ptr %A
836  %tmp3 = call <8 x i8> @llvm.aarch64.neon.sqabs.v8i8(<8 x i8> %tmp1)
837  ret <8 x i8> %tmp3
838}
839
840define <16 x i8> @sqabs_16b(ptr %A) nounwind {
841; CHECK-LABEL: sqabs_16b:
842; CHECK:       // %bb.0:
843; CHECK-NEXT:    ldr q0, [x0]
844; CHECK-NEXT:    sqabs.16b v0, v0
845; CHECK-NEXT:    ret
846  %tmp1 = load <16 x i8>, ptr %A
847  %tmp3 = call <16 x i8> @llvm.aarch64.neon.sqabs.v16i8(<16 x i8> %tmp1)
848  ret <16 x i8> %tmp3
849}
850
851define <4 x i16> @sqabs_4h(ptr %A) nounwind {
852; CHECK-LABEL: sqabs_4h:
853; CHECK:       // %bb.0:
854; CHECK-NEXT:    ldr d0, [x0]
855; CHECK-NEXT:    sqabs.4h v0, v0
856; CHECK-NEXT:    ret
857  %tmp1 = load <4 x i16>, ptr %A
858  %tmp3 = call <4 x i16> @llvm.aarch64.neon.sqabs.v4i16(<4 x i16> %tmp1)
859  ret <4 x i16> %tmp3
860}
861
862define <8 x i16> @sqabs_8h(ptr %A) nounwind {
863; CHECK-LABEL: sqabs_8h:
864; CHECK:       // %bb.0:
865; CHECK-NEXT:    ldr q0, [x0]
866; CHECK-NEXT:    sqabs.8h v0, v0
867; CHECK-NEXT:    ret
868  %tmp1 = load <8 x i16>, ptr %A
869  %tmp3 = call <8 x i16> @llvm.aarch64.neon.sqabs.v8i16(<8 x i16> %tmp1)
870  ret <8 x i16> %tmp3
871}
872
873define <2 x i32> @sqabs_2s(ptr %A) nounwind {
874; CHECK-LABEL: sqabs_2s:
875; CHECK:       // %bb.0:
876; CHECK-NEXT:    ldr d0, [x0]
877; CHECK-NEXT:    sqabs.2s v0, v0
878; CHECK-NEXT:    ret
879  %tmp1 = load <2 x i32>, ptr %A
880  %tmp3 = call <2 x i32> @llvm.aarch64.neon.sqabs.v2i32(<2 x i32> %tmp1)
881  ret <2 x i32> %tmp3
882}
883
884define <4 x i32> @sqabs_4s(ptr %A) nounwind {
885; CHECK-LABEL: sqabs_4s:
886; CHECK:       // %bb.0:
887; CHECK-NEXT:    ldr q0, [x0]
888; CHECK-NEXT:    sqabs.4s v0, v0
889; CHECK-NEXT:    ret
890  %tmp1 = load <4 x i32>, ptr %A
891  %tmp3 = call <4 x i32> @llvm.aarch64.neon.sqabs.v4i32(<4 x i32> %tmp1)
892  ret <4 x i32> %tmp3
893}
894
895declare <8 x i8> @llvm.aarch64.neon.sqabs.v8i8(<8 x i8>) nounwind readnone
896declare <16 x i8> @llvm.aarch64.neon.sqabs.v16i8(<16 x i8>) nounwind readnone
897declare <4 x i16> @llvm.aarch64.neon.sqabs.v4i16(<4 x i16>) nounwind readnone
898declare <8 x i16> @llvm.aarch64.neon.sqabs.v8i16(<8 x i16>) nounwind readnone
899declare <2 x i32> @llvm.aarch64.neon.sqabs.v2i32(<2 x i32>) nounwind readnone
900declare <4 x i32> @llvm.aarch64.neon.sqabs.v4i32(<4 x i32>) nounwind readnone
901
902define <8 x i8> @sqneg_8b(ptr %A) nounwind {
903; CHECK-LABEL: sqneg_8b:
904; CHECK:       // %bb.0:
905; CHECK-NEXT:    ldr d0, [x0]
906; CHECK-NEXT:    sqneg.8b v0, v0
907; CHECK-NEXT:    ret
908  %tmp1 = load <8 x i8>, ptr %A
909  %tmp3 = call <8 x i8> @llvm.aarch64.neon.sqneg.v8i8(<8 x i8> %tmp1)
910  ret <8 x i8> %tmp3
911}
912
913define <16 x i8> @sqneg_16b(ptr %A) nounwind {
914; CHECK-LABEL: sqneg_16b:
915; CHECK:       // %bb.0:
916; CHECK-NEXT:    ldr q0, [x0]
917; CHECK-NEXT:    sqneg.16b v0, v0
918; CHECK-NEXT:    ret
919  %tmp1 = load <16 x i8>, ptr %A
920  %tmp3 = call <16 x i8> @llvm.aarch64.neon.sqneg.v16i8(<16 x i8> %tmp1)
921  ret <16 x i8> %tmp3
922}
923
924define <4 x i16> @sqneg_4h(ptr %A) nounwind {
925; CHECK-LABEL: sqneg_4h:
926; CHECK:       // %bb.0:
927; CHECK-NEXT:    ldr d0, [x0]
928; CHECK-NEXT:    sqneg.4h v0, v0
929; CHECK-NEXT:    ret
930  %tmp1 = load <4 x i16>, ptr %A
931  %tmp3 = call <4 x i16> @llvm.aarch64.neon.sqneg.v4i16(<4 x i16> %tmp1)
932  ret <4 x i16> %tmp3
933}
934
935define <8 x i16> @sqneg_8h(ptr %A) nounwind {
936; CHECK-LABEL: sqneg_8h:
937; CHECK:       // %bb.0:
938; CHECK-NEXT:    ldr q0, [x0]
939; CHECK-NEXT:    sqneg.8h v0, v0
940; CHECK-NEXT:    ret
941  %tmp1 = load <8 x i16>, ptr %A
942  %tmp3 = call <8 x i16> @llvm.aarch64.neon.sqneg.v8i16(<8 x i16> %tmp1)
943  ret <8 x i16> %tmp3
944}
945
946define <2 x i32> @sqneg_2s(ptr %A) nounwind {
947; CHECK-LABEL: sqneg_2s:
948; CHECK:       // %bb.0:
949; CHECK-NEXT:    ldr d0, [x0]
950; CHECK-NEXT:    sqneg.2s v0, v0
951; CHECK-NEXT:    ret
952  %tmp1 = load <2 x i32>, ptr %A
953  %tmp3 = call <2 x i32> @llvm.aarch64.neon.sqneg.v2i32(<2 x i32> %tmp1)
954  ret <2 x i32> %tmp3
955}
956
957define <4 x i32> @sqneg_4s(ptr %A) nounwind {
958; CHECK-LABEL: sqneg_4s:
959; CHECK:       // %bb.0:
960; CHECK-NEXT:    ldr q0, [x0]
961; CHECK-NEXT:    sqneg.4s v0, v0
962; CHECK-NEXT:    ret
963  %tmp1 = load <4 x i32>, ptr %A
964  %tmp3 = call <4 x i32> @llvm.aarch64.neon.sqneg.v4i32(<4 x i32> %tmp1)
965  ret <4 x i32> %tmp3
966}
967
968declare <8 x i8> @llvm.aarch64.neon.sqneg.v8i8(<8 x i8>) nounwind readnone
969declare <16 x i8> @llvm.aarch64.neon.sqneg.v16i8(<16 x i8>) nounwind readnone
970declare <4 x i16> @llvm.aarch64.neon.sqneg.v4i16(<4 x i16>) nounwind readnone
971declare <8 x i16> @llvm.aarch64.neon.sqneg.v8i16(<8 x i16>) nounwind readnone
972declare <2 x i32> @llvm.aarch64.neon.sqneg.v2i32(<2 x i32>) nounwind readnone
973declare <4 x i32> @llvm.aarch64.neon.sqneg.v4i32(<4 x i32>) nounwind readnone
974
975define <8 x i8> @abs_8b(ptr %A) nounwind {
976; CHECK-LABEL: abs_8b:
977; CHECK:       // %bb.0:
978; CHECK-NEXT:    ldr d0, [x0]
979; CHECK-NEXT:    abs.8b v0, v0
980; CHECK-NEXT:    ret
981  %tmp1 = load <8 x i8>, ptr %A
982  %tmp3 = call <8 x i8> @llvm.aarch64.neon.abs.v8i8(<8 x i8> %tmp1)
983  ret <8 x i8> %tmp3
984}
985
986define <16 x i8> @abs_16b(ptr %A) nounwind {
987; CHECK-LABEL: abs_16b:
988; CHECK:       // %bb.0:
989; CHECK-NEXT:    ldr q0, [x0]
990; CHECK-NEXT:    abs.16b v0, v0
991; CHECK-NEXT:    ret
992  %tmp1 = load <16 x i8>, ptr %A
993  %tmp3 = call <16 x i8> @llvm.aarch64.neon.abs.v16i8(<16 x i8> %tmp1)
994  ret <16 x i8> %tmp3
995}
996
997define <4 x i16> @abs_4h(ptr %A) nounwind {
998; CHECK-LABEL: abs_4h:
999; CHECK:       // %bb.0:
1000; CHECK-NEXT:    ldr d0, [x0]
1001; CHECK-NEXT:    abs.4h v0, v0
1002; CHECK-NEXT:    ret
1003  %tmp1 = load <4 x i16>, ptr %A
1004  %tmp3 = call <4 x i16> @llvm.aarch64.neon.abs.v4i16(<4 x i16> %tmp1)
1005  ret <4 x i16> %tmp3
1006}
1007
1008define <8 x i16> @abs_8h(ptr %A) nounwind {
1009; CHECK-LABEL: abs_8h:
1010; CHECK:       // %bb.0:
1011; CHECK-NEXT:    ldr q0, [x0]
1012; CHECK-NEXT:    abs.8h v0, v0
1013; CHECK-NEXT:    ret
1014  %tmp1 = load <8 x i16>, ptr %A
1015  %tmp3 = call <8 x i16> @llvm.aarch64.neon.abs.v8i16(<8 x i16> %tmp1)
1016  ret <8 x i16> %tmp3
1017}
1018
1019define <2 x i32> @abs_2s(ptr %A) nounwind {
1020; CHECK-LABEL: abs_2s:
1021; CHECK:       // %bb.0:
1022; CHECK-NEXT:    ldr d0, [x0]
1023; CHECK-NEXT:    abs.2s v0, v0
1024; CHECK-NEXT:    ret
1025  %tmp1 = load <2 x i32>, ptr %A
1026  %tmp3 = call <2 x i32> @llvm.aarch64.neon.abs.v2i32(<2 x i32> %tmp1)
1027  ret <2 x i32> %tmp3
1028}
1029
1030define <4 x i32> @abs_4s(ptr %A) nounwind {
1031; CHECK-LABEL: abs_4s:
1032; CHECK:       // %bb.0:
1033; CHECK-NEXT:    ldr q0, [x0]
1034; CHECK-NEXT:    abs.4s v0, v0
1035; CHECK-NEXT:    ret
1036  %tmp1 = load <4 x i32>, ptr %A
1037  %tmp3 = call <4 x i32> @llvm.aarch64.neon.abs.v4i32(<4 x i32> %tmp1)
1038  ret <4 x i32> %tmp3
1039}
1040
1041define <1 x i64> @abs_1d(<1 x i64> %A) nounwind {
1042; CHECK-SD-LABEL: abs_1d:
1043; CHECK-SD:       // %bb.0:
1044; CHECK-SD-NEXT:    abs d0, d0
1045; CHECK-SD-NEXT:    ret
1046;
1047; CHECK-GI-LABEL: abs_1d:
1048; CHECK-GI:       // %bb.0:
1049; CHECK-GI-NEXT:    fmov x8, d0
1050; CHECK-GI-NEXT:    fmov x9, d0
1051; CHECK-GI-NEXT:    neg x8, x8
1052; CHECK-GI-NEXT:    cmp x9, #0
1053; CHECK-GI-NEXT:    fmov d1, x8
1054; CHECK-GI-NEXT:    fcsel d0, d0, d1, gt
1055; CHECK-GI-NEXT:    ret
1056  %abs = call <1 x i64> @llvm.aarch64.neon.abs.v1i64(<1 x i64> %A)
1057  ret <1 x i64> %abs
1058}
1059
1060define i64 @abs_1d_honestly(i64 %A) nounwind {
1061; CHECK-SD-LABEL: abs_1d_honestly:
1062; CHECK-SD:       // %bb.0:
1063; CHECK-SD-NEXT:    fmov d0, x0
1064; CHECK-SD-NEXT:    abs d0, d0
1065; CHECK-SD-NEXT:    fmov x0, d0
1066; CHECK-SD-NEXT:    ret
1067;
1068; CHECK-GI-LABEL: abs_1d_honestly:
1069; CHECK-GI:       // %bb.0:
1070; CHECK-GI-NEXT:    cmp x0, #0
1071; CHECK-GI-NEXT:    cneg x0, x0, le
1072; CHECK-GI-NEXT:    ret
1073  %abs = call i64 @llvm.aarch64.neon.abs.i64(i64 %A)
1074  ret i64 %abs
1075}
1076
1077declare <8 x i8> @llvm.aarch64.neon.abs.v8i8(<8 x i8>) nounwind readnone
1078declare <16 x i8> @llvm.aarch64.neon.abs.v16i8(<16 x i8>) nounwind readnone
1079declare <4 x i16> @llvm.aarch64.neon.abs.v4i16(<4 x i16>) nounwind readnone
1080declare <8 x i16> @llvm.aarch64.neon.abs.v8i16(<8 x i16>) nounwind readnone
1081declare <2 x i32> @llvm.aarch64.neon.abs.v2i32(<2 x i32>) nounwind readnone
1082declare <4 x i32> @llvm.aarch64.neon.abs.v4i32(<4 x i32>) nounwind readnone
1083declare <1 x i64> @llvm.aarch64.neon.abs.v1i64(<1 x i64>) nounwind readnone
1084declare i64 @llvm.aarch64.neon.abs.i64(i64) nounwind readnone
1085
1086define <8 x i16> @sabal8h(ptr %A, ptr %B,  ptr %C) nounwind {
1087; CHECK-LABEL: sabal8h:
1088; CHECK:       // %bb.0:
1089; CHECK-NEXT:    ldr d1, [x0]
1090; CHECK-NEXT:    ldr d2, [x1]
1091; CHECK-NEXT:    ldr q0, [x2]
1092; CHECK-NEXT:    sabal.8h v0, v1, v2
1093; CHECK-NEXT:    ret
1094  %tmp1 = load <8 x i8>, ptr %A
1095  %tmp2 = load <8 x i8>, ptr %B
1096  %tmp3 = load <8 x i16>, ptr %C
1097  %tmp4 = call <8 x i8> @llvm.aarch64.neon.sabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2)
1098  %tmp4.1 = zext <8 x i8> %tmp4 to <8 x i16>
1099  %tmp5 = add <8 x i16> %tmp3, %tmp4.1
1100  ret <8 x i16> %tmp5
1101}
1102
1103define <4 x i32> @sabal4s(ptr %A, ptr %B, ptr %C) nounwind {
1104; CHECK-LABEL: sabal4s:
1105; CHECK:       // %bb.0:
1106; CHECK-NEXT:    ldr d1, [x0]
1107; CHECK-NEXT:    ldr d2, [x1]
1108; CHECK-NEXT:    ldr q0, [x2]
1109; CHECK-NEXT:    sabal.4s v0, v1, v2
1110; CHECK-NEXT:    ret
1111  %tmp1 = load <4 x i16>, ptr %A
1112  %tmp2 = load <4 x i16>, ptr %B
1113  %tmp3 = load <4 x i32>, ptr %C
1114  %tmp4 = call <4 x i16> @llvm.aarch64.neon.sabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2)
1115  %tmp4.1 = zext <4 x i16> %tmp4 to <4 x i32>
1116  %tmp5 = add <4 x i32> %tmp3, %tmp4.1
1117  ret <4 x i32> %tmp5
1118}
1119
1120define <2 x i64> @sabal2d(ptr %A, ptr %B, ptr %C) nounwind {
1121; CHECK-LABEL: sabal2d:
1122; CHECK:       // %bb.0:
1123; CHECK-NEXT:    ldr d1, [x0]
1124; CHECK-NEXT:    ldr d2, [x1]
1125; CHECK-NEXT:    ldr q0, [x2]
1126; CHECK-NEXT:    sabal.2d v0, v1, v2
1127; CHECK-NEXT:    ret
1128  %tmp1 = load <2 x i32>, ptr %A
1129  %tmp2 = load <2 x i32>, ptr %B
1130  %tmp3 = load <2 x i64>, ptr %C
1131  %tmp4 = call <2 x i32> @llvm.aarch64.neon.sabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2)
1132  %tmp4.1 = zext <2 x i32> %tmp4 to <2 x i64>
1133  %tmp4.1.1 = zext <2 x i32> %tmp4 to <2 x i64>
1134  %tmp5 = add <2 x i64> %tmp3, %tmp4.1
1135  ret <2 x i64> %tmp5
1136}
1137
1138define <8 x i16> @sabal2_8h(ptr %A, ptr %B, ptr %C) nounwind {
1139; CHECK-SD-LABEL: sabal2_8h:
1140; CHECK-SD:       // %bb.0:
1141; CHECK-SD-NEXT:    ldr q0, [x2]
1142; CHECK-SD-NEXT:    ldr d1, [x0, #8]
1143; CHECK-SD-NEXT:    ldr d2, [x1, #8]
1144; CHECK-SD-NEXT:    sabal.8h v0, v1, v2
1145; CHECK-SD-NEXT:    ret
1146;
1147; CHECK-GI-LABEL: sabal2_8h:
1148; CHECK-GI:       // %bb.0:
1149; CHECK-GI-NEXT:    ldr q1, [x0]
1150; CHECK-GI-NEXT:    ldr q2, [x1]
1151; CHECK-GI-NEXT:    ldr q0, [x2]
1152; CHECK-GI-NEXT:    sabal2.8h v0, v1, v2
1153; CHECK-GI-NEXT:    ret
1154  %load1 = load <16 x i8>, ptr %A
1155  %load2 = load <16 x i8>, ptr %B
1156  %tmp3 = load <8 x i16>, ptr %C
1157  %tmp1 = shufflevector <16 x i8> %load1, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
1158  %tmp2 = shufflevector <16 x i8> %load2, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
1159  %tmp4 = call <8 x i8> @llvm.aarch64.neon.sabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2)
1160  %tmp4.1 = zext <8 x i8> %tmp4 to <8 x i16>
1161  %tmp5 = add <8 x i16> %tmp3, %tmp4.1
1162  ret <8 x i16> %tmp5
1163}
1164
1165define <4 x i32> @sabal2_4s(ptr %A, ptr %B, ptr %C) nounwind {
1166; CHECK-SD-LABEL: sabal2_4s:
1167; CHECK-SD:       // %bb.0:
1168; CHECK-SD-NEXT:    ldr q0, [x2]
1169; CHECK-SD-NEXT:    ldr d1, [x0, #8]
1170; CHECK-SD-NEXT:    ldr d2, [x1, #8]
1171; CHECK-SD-NEXT:    sabal.4s v0, v1, v2
1172; CHECK-SD-NEXT:    ret
1173;
1174; CHECK-GI-LABEL: sabal2_4s:
1175; CHECK-GI:       // %bb.0:
1176; CHECK-GI-NEXT:    ldr q1, [x0]
1177; CHECK-GI-NEXT:    ldr q2, [x1]
1178; CHECK-GI-NEXT:    ldr q0, [x2]
1179; CHECK-GI-NEXT:    sabal2.4s v0, v1, v2
1180; CHECK-GI-NEXT:    ret
1181  %load1 = load <8 x i16>, ptr %A
1182  %load2 = load <8 x i16>, ptr %B
1183  %tmp3 = load <4 x i32>, ptr %C
1184  %tmp1 = shufflevector <8 x i16> %load1, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
1185  %tmp2 = shufflevector <8 x i16> %load2, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
1186  %tmp4 = call <4 x i16> @llvm.aarch64.neon.sabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2)
1187  %tmp4.1 = zext <4 x i16> %tmp4 to <4 x i32>
1188  %tmp5 = add <4 x i32> %tmp3, %tmp4.1
1189  ret <4 x i32> %tmp5
1190}
1191
1192define <2 x i64> @sabal2_2d(ptr %A, ptr %B, ptr %C) nounwind {
1193; CHECK-SD-LABEL: sabal2_2d:
1194; CHECK-SD:       // %bb.0:
1195; CHECK-SD-NEXT:    ldr q0, [x2]
1196; CHECK-SD-NEXT:    ldr d1, [x0, #8]
1197; CHECK-SD-NEXT:    ldr d2, [x1, #8]
1198; CHECK-SD-NEXT:    sabal.2d v0, v1, v2
1199; CHECK-SD-NEXT:    ret
1200;
1201; CHECK-GI-LABEL: sabal2_2d:
1202; CHECK-GI:       // %bb.0:
1203; CHECK-GI-NEXT:    ldr q1, [x0]
1204; CHECK-GI-NEXT:    ldr q2, [x1]
1205; CHECK-GI-NEXT:    ldr q0, [x2]
1206; CHECK-GI-NEXT:    sabal2.2d v0, v1, v2
1207; CHECK-GI-NEXT:    ret
1208  %load1 = load <4 x i32>, ptr %A
1209  %load2 = load <4 x i32>, ptr %B
1210  %tmp3 = load <2 x i64>, ptr %C
1211  %tmp1 = shufflevector <4 x i32> %load1, <4 x i32> undef, <2 x i32> <i32 2, i32 3>
1212  %tmp2 = shufflevector <4 x i32> %load2, <4 x i32> undef, <2 x i32> <i32 2, i32 3>
1213  %tmp4 = call <2 x i32> @llvm.aarch64.neon.sabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2)
1214  %tmp4.1 = zext <2 x i32> %tmp4 to <2 x i64>
1215  %tmp5 = add <2 x i64> %tmp3, %tmp4.1
1216  ret <2 x i64> %tmp5
1217}
1218
1219define <8 x i16> @uabal8h(ptr %A, ptr %B,  ptr %C) nounwind {
1220; CHECK-LABEL: uabal8h:
1221; CHECK:       // %bb.0:
1222; CHECK-NEXT:    ldr d1, [x0]
1223; CHECK-NEXT:    ldr d2, [x1]
1224; CHECK-NEXT:    ldr q0, [x2]
1225; CHECK-NEXT:    uabal.8h v0, v1, v2
1226; CHECK-NEXT:    ret
1227  %tmp1 = load <8 x i8>, ptr %A
1228  %tmp2 = load <8 x i8>, ptr %B
1229  %tmp3 = load <8 x i16>, ptr %C
1230  %tmp4 = call <8 x i8> @llvm.aarch64.neon.uabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2)
1231  %tmp4.1 = zext <8 x i8> %tmp4 to <8 x i16>
1232  %tmp5 = add <8 x i16> %tmp3, %tmp4.1
1233  ret <8 x i16> %tmp5
1234}
1235
1236define <4 x i32> @uabal4s(ptr %A, ptr %B, ptr %C) nounwind {
1237; CHECK-LABEL: uabal4s:
1238; CHECK:       // %bb.0:
1239; CHECK-NEXT:    ldr d1, [x0]
1240; CHECK-NEXT:    ldr d2, [x1]
1241; CHECK-NEXT:    ldr q0, [x2]
1242; CHECK-NEXT:    uabal.4s v0, v1, v2
1243; CHECK-NEXT:    ret
1244  %tmp1 = load <4 x i16>, ptr %A
1245  %tmp2 = load <4 x i16>, ptr %B
1246  %tmp3 = load <4 x i32>, ptr %C
1247  %tmp4 = call <4 x i16> @llvm.aarch64.neon.uabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2)
1248  %tmp4.1 = zext <4 x i16> %tmp4 to <4 x i32>
1249  %tmp5 = add <4 x i32> %tmp3, %tmp4.1
1250  ret <4 x i32> %tmp5
1251}
1252
1253define <2 x i64> @uabal2d(ptr %A, ptr %B, ptr %C) nounwind {
1254; CHECK-LABEL: uabal2d:
1255; CHECK:       // %bb.0:
1256; CHECK-NEXT:    ldr d1, [x0]
1257; CHECK-NEXT:    ldr d2, [x1]
1258; CHECK-NEXT:    ldr q0, [x2]
1259; CHECK-NEXT:    uabal.2d v0, v1, v2
1260; CHECK-NEXT:    ret
1261  %tmp1 = load <2 x i32>, ptr %A
1262  %tmp2 = load <2 x i32>, ptr %B
1263  %tmp3 = load <2 x i64>, ptr %C
1264  %tmp4 = call <2 x i32> @llvm.aarch64.neon.uabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2)
1265  %tmp4.1 = zext <2 x i32> %tmp4 to <2 x i64>
1266  %tmp5 = add <2 x i64> %tmp3, %tmp4.1
1267  ret <2 x i64> %tmp5
1268}
1269
1270define <8 x i16> @uabal2_8h(ptr %A, ptr %B, ptr %C) nounwind {
1271; CHECK-SD-LABEL: uabal2_8h:
1272; CHECK-SD:       // %bb.0:
1273; CHECK-SD-NEXT:    ldr q0, [x2]
1274; CHECK-SD-NEXT:    ldr d1, [x0, #8]
1275; CHECK-SD-NEXT:    ldr d2, [x1, #8]
1276; CHECK-SD-NEXT:    uabal.8h v0, v1, v2
1277; CHECK-SD-NEXT:    ret
1278;
1279; CHECK-GI-LABEL: uabal2_8h:
1280; CHECK-GI:       // %bb.0:
1281; CHECK-GI-NEXT:    ldr q1, [x0]
1282; CHECK-GI-NEXT:    ldr q2, [x1]
1283; CHECK-GI-NEXT:    ldr q0, [x2]
1284; CHECK-GI-NEXT:    uabal2.8h v0, v1, v2
1285; CHECK-GI-NEXT:    ret
1286  %load1 = load <16 x i8>, ptr %A
1287  %load2 = load <16 x i8>, ptr %B
1288  %tmp3 = load <8 x i16>, ptr %C
1289  %tmp1 = shufflevector <16 x i8> %load1, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
1290  %tmp2 = shufflevector <16 x i8> %load2, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
1291  %tmp4 = call <8 x i8> @llvm.aarch64.neon.uabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2)
1292  %tmp4.1 = zext <8 x i8> %tmp4 to <8 x i16>
1293  %tmp5 = add <8 x i16> %tmp3, %tmp4.1
1294  ret <8 x i16> %tmp5
1295}
1296
1297define <4 x i32> @uabal2_4s(ptr %A, ptr %B, ptr %C) nounwind {
1298; CHECK-SD-LABEL: uabal2_4s:
1299; CHECK-SD:       // %bb.0:
1300; CHECK-SD-NEXT:    ldr q0, [x2]
1301; CHECK-SD-NEXT:    ldr d1, [x0, #8]
1302; CHECK-SD-NEXT:    ldr d2, [x1, #8]
1303; CHECK-SD-NEXT:    uabal.4s v0, v1, v2
1304; CHECK-SD-NEXT:    ret
1305;
1306; CHECK-GI-LABEL: uabal2_4s:
1307; CHECK-GI:       // %bb.0:
1308; CHECK-GI-NEXT:    ldr q1, [x0]
1309; CHECK-GI-NEXT:    ldr q2, [x1]
1310; CHECK-GI-NEXT:    ldr q0, [x2]
1311; CHECK-GI-NEXT:    uabal2.4s v0, v1, v2
1312; CHECK-GI-NEXT:    ret
1313  %load1 = load <8 x i16>, ptr %A
1314  %load2 = load <8 x i16>, ptr %B
1315  %tmp3 = load <4 x i32>, ptr %C
1316  %tmp1 = shufflevector <8 x i16> %load1, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
1317  %tmp2 = shufflevector <8 x i16> %load2, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
1318  %tmp4 = call <4 x i16> @llvm.aarch64.neon.uabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2)
1319  %tmp4.1 = zext <4 x i16> %tmp4 to <4 x i32>
1320  %tmp5 = add <4 x i32> %tmp3, %tmp4.1
1321  ret <4 x i32> %tmp5
1322}
1323
1324define <2 x i64> @uabal2_2d(ptr %A, ptr %B, ptr %C) nounwind {
1325; CHECK-SD-LABEL: uabal2_2d:
1326; CHECK-SD:       // %bb.0:
1327; CHECK-SD-NEXT:    ldr q0, [x2]
1328; CHECK-SD-NEXT:    ldr d1, [x0, #8]
1329; CHECK-SD-NEXT:    ldr d2, [x1, #8]
1330; CHECK-SD-NEXT:    uabal.2d v0, v1, v2
1331; CHECK-SD-NEXT:    ret
1332;
1333; CHECK-GI-LABEL: uabal2_2d:
1334; CHECK-GI:       // %bb.0:
1335; CHECK-GI-NEXT:    ldr q1, [x0]
1336; CHECK-GI-NEXT:    ldr q2, [x1]
1337; CHECK-GI-NEXT:    ldr q0, [x2]
1338; CHECK-GI-NEXT:    uabal2.2d v0, v1, v2
1339; CHECK-GI-NEXT:    ret
1340  %load1 = load <4 x i32>, ptr %A
1341  %load2 = load <4 x i32>, ptr %B
1342  %tmp3 = load <2 x i64>, ptr %C
1343  %tmp1 = shufflevector <4 x i32> %load1, <4 x i32> undef, <2 x i32> <i32 2, i32 3>
1344  %tmp2 = shufflevector <4 x i32> %load2, <4 x i32> undef, <2 x i32> <i32 2, i32 3>
1345  %tmp4 = call <2 x i32> @llvm.aarch64.neon.uabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2)
1346  %tmp4.1 = zext <2 x i32> %tmp4 to <2 x i64>
1347  %tmp5 = add <2 x i64> %tmp3, %tmp4.1
1348  ret <2 x i64> %tmp5
1349}
1350
1351define <8 x i8> @saba_8b(ptr %A, ptr %B, ptr %C) nounwind {
1352; CHECK-LABEL: saba_8b:
1353; CHECK:       // %bb.0:
1354; CHECK-NEXT:    ldr d1, [x0]
1355; CHECK-NEXT:    ldr d2, [x1]
1356; CHECK-NEXT:    ldr d0, [x2]
1357; CHECK-NEXT:    saba.8b v0, v1, v2
1358; CHECK-NEXT:    ret
1359  %tmp1 = load <8 x i8>, ptr %A
1360  %tmp2 = load <8 x i8>, ptr %B
1361  %tmp3 = call <8 x i8> @llvm.aarch64.neon.sabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2)
1362  %tmp4 = load <8 x i8>, ptr %C
1363  %tmp5 = add <8 x i8> %tmp3, %tmp4
1364  ret <8 x i8> %tmp5
1365}
1366
1367define <16 x i8> @saba_16b(ptr %A, ptr %B, ptr %C) nounwind {
1368; CHECK-LABEL: saba_16b:
1369; CHECK:       // %bb.0:
1370; CHECK-NEXT:    ldr q1, [x0]
1371; CHECK-NEXT:    ldr q2, [x1]
1372; CHECK-NEXT:    ldr q0, [x2]
1373; CHECK-NEXT:    saba.16b v0, v1, v2
1374; CHECK-NEXT:    ret
1375  %tmp1 = load <16 x i8>, ptr %A
1376  %tmp2 = load <16 x i8>, ptr %B
1377  %tmp3 = call <16 x i8> @llvm.aarch64.neon.sabd.v16i8(<16 x i8> %tmp1, <16 x i8> %tmp2)
1378  %tmp4 = load <16 x i8>, ptr %C
1379  %tmp5 = add <16 x i8> %tmp3, %tmp4
1380  ret <16 x i8> %tmp5
1381}
1382
1383define <4 x i16> @saba_4h(ptr %A, ptr %B, ptr %C) nounwind {
1384; CHECK-LABEL: saba_4h:
1385; CHECK:       // %bb.0:
1386; CHECK-NEXT:    ldr d1, [x0]
1387; CHECK-NEXT:    ldr d2, [x1]
1388; CHECK-NEXT:    ldr d0, [x2]
1389; CHECK-NEXT:    saba.4h v0, v1, v2
1390; CHECK-NEXT:    ret
1391  %tmp1 = load <4 x i16>, ptr %A
1392  %tmp2 = load <4 x i16>, ptr %B
1393  %tmp3 = call <4 x i16> @llvm.aarch64.neon.sabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2)
1394  %tmp4 = load <4 x i16>, ptr %C
1395  %tmp5 = add <4 x i16> %tmp3, %tmp4
1396  ret <4 x i16> %tmp5
1397}
1398
1399define <8 x i16> @saba_8h(ptr %A, ptr %B, ptr %C) nounwind {
1400; CHECK-LABEL: saba_8h:
1401; CHECK:       // %bb.0:
1402; CHECK-NEXT:    ldr q1, [x0]
1403; CHECK-NEXT:    ldr q2, [x1]
1404; CHECK-NEXT:    ldr q0, [x2]
1405; CHECK-NEXT:    saba.8h v0, v1, v2
1406; CHECK-NEXT:    ret
1407  %tmp1 = load <8 x i16>, ptr %A
1408  %tmp2 = load <8 x i16>, ptr %B
1409  %tmp3 = call <8 x i16> @llvm.aarch64.neon.sabd.v8i16(<8 x i16> %tmp1, <8 x i16> %tmp2)
1410  %tmp4 = load <8 x i16>, ptr %C
1411  %tmp5 = add <8 x i16> %tmp3, %tmp4
1412  ret <8 x i16> %tmp5
1413}
1414
1415define <2 x i32> @saba_2s(ptr %A, ptr %B, ptr %C) nounwind {
1416; CHECK-LABEL: saba_2s:
1417; CHECK:       // %bb.0:
1418; CHECK-NEXT:    ldr d1, [x0]
1419; CHECK-NEXT:    ldr d2, [x1]
1420; CHECK-NEXT:    ldr d0, [x2]
1421; CHECK-NEXT:    saba.2s v0, v1, v2
1422; CHECK-NEXT:    ret
1423  %tmp1 = load <2 x i32>, ptr %A
1424  %tmp2 = load <2 x i32>, ptr %B
1425  %tmp3 = call <2 x i32> @llvm.aarch64.neon.sabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2)
1426  %tmp4 = load <2 x i32>, ptr %C
1427  %tmp5 = add <2 x i32> %tmp3, %tmp4
1428  ret <2 x i32> %tmp5
1429}
1430
1431define <4 x i32> @saba_4s(ptr %A, ptr %B, ptr %C) nounwind {
1432; CHECK-LABEL: saba_4s:
1433; CHECK:       // %bb.0:
1434; CHECK-NEXT:    ldr q1, [x0]
1435; CHECK-NEXT:    ldr q2, [x1]
1436; CHECK-NEXT:    ldr q0, [x2]
1437; CHECK-NEXT:    saba.4s v0, v1, v2
1438; CHECK-NEXT:    ret
1439  %tmp1 = load <4 x i32>, ptr %A
1440  %tmp2 = load <4 x i32>, ptr %B
1441  %tmp3 = call <4 x i32> @llvm.aarch64.neon.sabd.v4i32(<4 x i32> %tmp1, <4 x i32> %tmp2)
1442  %tmp4 = load <4 x i32>, ptr %C
1443  %tmp5 = add <4 x i32> %tmp3, %tmp4
1444  ret <4 x i32> %tmp5
1445}
1446
1447define <8 x i8> @uaba_8b(ptr %A, ptr %B, ptr %C) nounwind {
1448; CHECK-LABEL: uaba_8b:
1449; CHECK:       // %bb.0:
1450; CHECK-NEXT:    ldr d1, [x0]
1451; CHECK-NEXT:    ldr d2, [x1]
1452; CHECK-NEXT:    ldr d0, [x2]
1453; CHECK-NEXT:    uaba.8b v0, v1, v2
1454; CHECK-NEXT:    ret
1455  %tmp1 = load <8 x i8>, ptr %A
1456  %tmp2 = load <8 x i8>, ptr %B
1457  %tmp3 = call <8 x i8> @llvm.aarch64.neon.uabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2)
1458  %tmp4 = load <8 x i8>, ptr %C
1459  %tmp5 = add <8 x i8> %tmp3, %tmp4
1460  ret <8 x i8> %tmp5
1461}
1462
1463define <16 x i8> @uaba_16b(ptr %A, ptr %B, ptr %C) nounwind {
1464; CHECK-LABEL: uaba_16b:
1465; CHECK:       // %bb.0:
1466; CHECK-NEXT:    ldr q1, [x0]
1467; CHECK-NEXT:    ldr q2, [x1]
1468; CHECK-NEXT:    ldr q0, [x2]
1469; CHECK-NEXT:    uaba.16b v0, v1, v2
1470; CHECK-NEXT:    ret
1471  %tmp1 = load <16 x i8>, ptr %A
1472  %tmp2 = load <16 x i8>, ptr %B
1473  %tmp3 = call <16 x i8> @llvm.aarch64.neon.uabd.v16i8(<16 x i8> %tmp1, <16 x i8> %tmp2)
1474  %tmp4 = load <16 x i8>, ptr %C
1475  %tmp5 = add <16 x i8> %tmp3, %tmp4
1476  ret <16 x i8> %tmp5
1477}
1478
1479define <4 x i16> @uaba_4h(ptr %A, ptr %B, ptr %C) nounwind {
1480; CHECK-LABEL: uaba_4h:
1481; CHECK:       // %bb.0:
1482; CHECK-NEXT:    ldr d1, [x0]
1483; CHECK-NEXT:    ldr d2, [x1]
1484; CHECK-NEXT:    ldr d0, [x2]
1485; CHECK-NEXT:    uaba.4h v0, v1, v2
1486; CHECK-NEXT:    ret
1487  %tmp1 = load <4 x i16>, ptr %A
1488  %tmp2 = load <4 x i16>, ptr %B
1489  %tmp3 = call <4 x i16> @llvm.aarch64.neon.uabd.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2)
1490  %tmp4 = load <4 x i16>, ptr %C
1491  %tmp5 = add <4 x i16> %tmp3, %tmp4
1492  ret <4 x i16> %tmp5
1493}
1494
1495define <8 x i16> @uaba_8h(ptr %A, ptr %B, ptr %C) nounwind {
1496; CHECK-LABEL: uaba_8h:
1497; CHECK:       // %bb.0:
1498; CHECK-NEXT:    ldr q1, [x0]
1499; CHECK-NEXT:    ldr q2, [x1]
1500; CHECK-NEXT:    ldr q0, [x2]
1501; CHECK-NEXT:    uaba.8h v0, v1, v2
1502; CHECK-NEXT:    ret
1503  %tmp1 = load <8 x i16>, ptr %A
1504  %tmp2 = load <8 x i16>, ptr %B
1505  %tmp3 = call <8 x i16> @llvm.aarch64.neon.uabd.v8i16(<8 x i16> %tmp1, <8 x i16> %tmp2)
1506  %tmp4 = load <8 x i16>, ptr %C
1507  %tmp5 = add <8 x i16> %tmp3, %tmp4
1508  ret <8 x i16> %tmp5
1509}
1510
1511define <2 x i32> @uaba_2s(ptr %A, ptr %B, ptr %C) nounwind {
1512; CHECK-LABEL: uaba_2s:
1513; CHECK:       // %bb.0:
1514; CHECK-NEXT:    ldr d1, [x0]
1515; CHECK-NEXT:    ldr d2, [x1]
1516; CHECK-NEXT:    ldr d0, [x2]
1517; CHECK-NEXT:    uaba.2s v0, v1, v2
1518; CHECK-NEXT:    ret
1519  %tmp1 = load <2 x i32>, ptr %A
1520  %tmp2 = load <2 x i32>, ptr %B
1521  %tmp3 = call <2 x i32> @llvm.aarch64.neon.uabd.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2)
1522  %tmp4 = load <2 x i32>, ptr %C
1523  %tmp5 = add <2 x i32> %tmp3, %tmp4
1524  ret <2 x i32> %tmp5
1525}
1526
1527define <4 x i32> @uaba_4s(ptr %A, ptr %B, ptr %C) nounwind {
1528; CHECK-LABEL: uaba_4s:
1529; CHECK:       // %bb.0:
1530; CHECK-NEXT:    ldr q1, [x0]
1531; CHECK-NEXT:    ldr q2, [x1]
1532; CHECK-NEXT:    ldr q0, [x2]
1533; CHECK-NEXT:    uaba.4s v0, v1, v2
1534; CHECK-NEXT:    ret
1535  %tmp1 = load <4 x i32>, ptr %A
1536  %tmp2 = load <4 x i32>, ptr %B
1537  %tmp3 = call <4 x i32> @llvm.aarch64.neon.uabd.v4i32(<4 x i32> %tmp1, <4 x i32> %tmp2)
1538  %tmp4 = load <4 x i32>, ptr %C
1539  %tmp5 = add <4 x i32> %tmp3, %tmp4
1540  ret <4 x i32> %tmp5
1541}
1542
1543; Scalar FABD
1544define float @fabds(float %a, float %b) nounwind {
1545; CHECK-LABEL: fabds:
1546; CHECK:       // %bb.0:
1547; CHECK-NEXT:    fabd s0, s0, s1
1548; CHECK-NEXT:    ret
1549  %vabd.i = tail call float @llvm.aarch64.sisd.fabd.f32(float %a, float %b) nounwind
1550  ret float %vabd.i
1551}
1552
1553define double @fabdd(double %a, double %b) nounwind {
1554; CHECK-LABEL: fabdd:
1555; CHECK:       // %bb.0:
1556; CHECK-NEXT:    fabd d0, d0, d1
1557; CHECK-NEXT:    ret
1558  %vabd.i = tail call double @llvm.aarch64.sisd.fabd.f64(double %a, double %b) nounwind
1559  ret double %vabd.i
1560}
1561
1562declare double @llvm.aarch64.sisd.fabd.f64(double, double) nounwind readnone
1563declare float @llvm.aarch64.sisd.fabd.f32(float, float) nounwind readnone
1564
1565define float @fabds_from_fsub_fabs(float %a, float %b) nounwind {
1566; CHECK-LABEL: fabds_from_fsub_fabs:
1567; CHECK:       // %bb.0:
1568; CHECK-NEXT:    fabd s0, s0, s1
1569; CHECK-NEXT:    ret
1570  %sub = fsub float %a, %b
1571  %abs = tail call float @llvm.fabs.f32(float %sub)
1572  ret float %abs
1573}
1574
1575define double @fabdd_from_fsub_fabs(double %a, double %b) nounwind {
1576; CHECK-LABEL: fabdd_from_fsub_fabs:
1577; CHECK:       // %bb.0:
1578; CHECK-NEXT:    fabd d0, d0, d1
1579; CHECK-NEXT:    ret
1580  %sub = fsub double %a, %b
1581  %abs = tail call double @llvm.fabs.f64(double %sub)
1582  ret double %abs
1583}
1584
1585declare float @llvm.fabs.f32(float) nounwind readnone
1586declare double @llvm.fabs.f64(double) nounwind readnone
1587
1588define <2 x i64> @uabdl_from_extract_dup(<4 x i32> %lhs, i32 %rhs) {
1589; CHECK-LABEL: uabdl_from_extract_dup:
1590; CHECK:       // %bb.0:
1591; CHECK-NEXT:    dup.2s v1, w0
1592; CHECK-NEXT:    uabdl.2d v0, v0, v1
1593; CHECK-NEXT:    ret
1594  %rhsvec.tmp = insertelement <2 x i32> undef, i32 %rhs, i32 0
1595  %rhsvec = insertelement <2 x i32> %rhsvec.tmp, i32 %rhs, i32 1
1596  %lhs.high = shufflevector <4 x i32> %lhs, <4 x i32> undef, <2 x i32> <i32 0, i32 1>
1597  %res = tail call <2 x i32> @llvm.aarch64.neon.uabd.v2i32(<2 x i32> %lhs.high, <2 x i32> %rhsvec) nounwind
1598  %res1 = zext <2 x i32> %res to <2 x i64>
1599  ret <2 x i64> %res1
1600}
1601
1602define <2 x i64> @uabdl2_from_extract_dup(<4 x i32> %lhs, i32 %rhs) {
1603; CHECK-SD-LABEL: uabdl2_from_extract_dup:
1604; CHECK-SD:       // %bb.0:
1605; CHECK-SD-NEXT:    dup.4s v1, w0
1606; CHECK-SD-NEXT:    uabdl2.2d v0, v0, v1
1607; CHECK-SD-NEXT:    ret
1608;
1609; CHECK-GI-LABEL: uabdl2_from_extract_dup:
1610; CHECK-GI:       // %bb.0:
1611; CHECK-GI-NEXT:    dup.2s v1, w0
1612; CHECK-GI-NEXT:    mov d0, v0[1]
1613; CHECK-GI-NEXT:    uabdl.2d v0, v0, v1
1614; CHECK-GI-NEXT:    ret
1615  %rhsvec.tmp = insertelement <2 x i32> undef, i32 %rhs, i32 0
1616  %rhsvec = insertelement <2 x i32> %rhsvec.tmp, i32 %rhs, i32 1
1617  %lhs.high = shufflevector <4 x i32> %lhs, <4 x i32> undef, <2 x i32> <i32 2, i32 3>
1618  %res = tail call <2 x i32> @llvm.aarch64.neon.uabd.v2i32(<2 x i32> %lhs.high, <2 x i32> %rhsvec) nounwind
1619  %res1 = zext <2 x i32> %res to <2 x i64>
1620  ret <2 x i64> %res1
1621}
1622
1623define <2 x i64> @sabdl_from_extract_dup(<4 x i32> %lhs, i32 %rhs) {
1624; CHECK-LABEL: sabdl_from_extract_dup:
1625; CHECK:       // %bb.0:
1626; CHECK-NEXT:    dup.2s v1, w0
1627; CHECK-NEXT:    sabdl.2d v0, v0, v1
1628; CHECK-NEXT:    ret
1629  %rhsvec.tmp = insertelement <2 x i32> undef, i32 %rhs, i32 0
1630  %rhsvec = insertelement <2 x i32> %rhsvec.tmp, i32 %rhs, i32 1
1631  %lhs.high = shufflevector <4 x i32> %lhs, <4 x i32> undef, <2 x i32> <i32 0, i32 1>
1632  %res = tail call <2 x i32> @llvm.aarch64.neon.sabd.v2i32(<2 x i32> %lhs.high, <2 x i32> %rhsvec) nounwind
1633  %res1 = zext <2 x i32> %res to <2 x i64>
1634  ret <2 x i64> %res1
1635}
1636
1637define <2 x i64> @sabdl2_from_extract_dup(<4 x i32> %lhs, i32 %rhs) {
1638; CHECK-SD-LABEL: sabdl2_from_extract_dup:
1639; CHECK-SD:       // %bb.0:
1640; CHECK-SD-NEXT:    dup.4s v1, w0
1641; CHECK-SD-NEXT:    sabdl2.2d v0, v0, v1
1642; CHECK-SD-NEXT:    ret
1643;
1644; CHECK-GI-LABEL: sabdl2_from_extract_dup:
1645; CHECK-GI:       // %bb.0:
1646; CHECK-GI-NEXT:    dup.2s v1, w0
1647; CHECK-GI-NEXT:    mov d0, v0[1]
1648; CHECK-GI-NEXT:    sabdl.2d v0, v0, v1
1649; CHECK-GI-NEXT:    ret
1650  %rhsvec.tmp = insertelement <2 x i32> undef, i32 %rhs, i32 0
1651  %rhsvec = insertelement <2 x i32> %rhsvec.tmp, i32 %rhs, i32 1
1652  %lhs.high = shufflevector <4 x i32> %lhs, <4 x i32> undef, <2 x i32> <i32 2, i32 3>
1653  %res = tail call <2 x i32> @llvm.aarch64.neon.sabd.v2i32(<2 x i32> %lhs.high, <2 x i32> %rhsvec) nounwind
1654  %res1 = zext <2 x i32> %res to <2 x i64>
1655  ret <2 x i64> %res1
1656}
1657
1658define <2 x i32> @abspattern1(<2 x i32> %a) nounwind {
1659; CHECK-SD-LABEL: abspattern1:
1660; CHECK-SD:       // %bb.0:
1661; CHECK-SD-NEXT:    abs.2s v0, v0
1662; CHECK-SD-NEXT:    ret
1663;
1664; CHECK-GI-LABEL: abspattern1:
1665; CHECK-GI:       // %bb.0:
1666; CHECK-GI-NEXT:    neg.2s v1, v0
1667; CHECK-GI-NEXT:    cmge.2s v2, v0, #0
1668; CHECK-GI-NEXT:    bif.8b v0, v1, v2
1669; CHECK-GI-NEXT:    ret
1670  %tmp1neg = sub <2 x i32> zeroinitializer, %a
1671  %b = icmp sge <2 x i32> %a, zeroinitializer
1672  %abs = select <2 x i1> %b, <2 x i32> %a, <2 x i32> %tmp1neg
1673  ret <2 x i32> %abs
1674}
1675
1676; For GlobalISel, this generates terrible code until we can pattern match this to abs.
1677define <4 x i16> @abspattern2(<4 x i16> %a) nounwind {
1678; CHECK-SD-LABEL: abspattern2:
1679; CHECK-SD:       // %bb.0:
1680; CHECK-SD-NEXT:    abs.4h v0, v0
1681; CHECK-SD-NEXT:    ret
1682;
1683; CHECK-GI-LABEL: abspattern2:
1684; CHECK-GI:       // %bb.0:
1685; CHECK-GI-NEXT:    neg.4h v1, v0
1686; CHECK-GI-NEXT:    cmgt.4h v2, v0, #0
1687; CHECK-GI-NEXT:    bif.8b v0, v1, v2
1688; CHECK-GI-NEXT:    ret
1689  %tmp1neg = sub <4 x i16> zeroinitializer, %a
1690  %b = icmp sgt <4 x i16> %a, zeroinitializer
1691  %abs = select <4 x i1> %b, <4 x i16> %a, <4 x i16> %tmp1neg
1692  ret <4 x i16> %abs
1693}
1694
1695define <8 x i8> @abspattern3(<8 x i8> %a) nounwind {
1696; CHECK-SD-LABEL: abspattern3:
1697; CHECK-SD:       // %bb.0:
1698; CHECK-SD-NEXT:    abs.8b v0, v0
1699; CHECK-SD-NEXT:    ret
1700;
1701; CHECK-GI-LABEL: abspattern3:
1702; CHECK-GI:       // %bb.0:
1703; CHECK-GI-NEXT:    neg.8b v1, v0
1704; CHECK-GI-NEXT:    cmlt.8b v2, v0, #0
1705; CHECK-GI-NEXT:    bit.8b v0, v1, v2
1706; CHECK-GI-NEXT:    ret
1707  %tmp1neg = sub <8 x i8> zeroinitializer, %a
1708  %b = icmp slt <8 x i8> %a, zeroinitializer
1709  %abs = select <8 x i1> %b, <8 x i8> %tmp1neg, <8 x i8> %a
1710  ret <8 x i8> %abs
1711}
1712
1713define <4 x i32> @abspattern4(<4 x i32> %a) nounwind {
1714; CHECK-SD-LABEL: abspattern4:
1715; CHECK-SD:       // %bb.0:
1716; CHECK-SD-NEXT:    abs.4s v0, v0
1717; CHECK-SD-NEXT:    ret
1718;
1719; CHECK-GI-LABEL: abspattern4:
1720; CHECK-GI:       // %bb.0:
1721; CHECK-GI-NEXT:    neg.4s v1, v0
1722; CHECK-GI-NEXT:    cmge.4s v2, v0, #0
1723; CHECK-GI-NEXT:    bif.16b v0, v1, v2
1724; CHECK-GI-NEXT:    ret
1725  %tmp1neg = sub <4 x i32> zeroinitializer, %a
1726  %b = icmp sge <4 x i32> %a, zeroinitializer
1727  %abs = select <4 x i1> %b, <4 x i32> %a, <4 x i32> %tmp1neg
1728  ret <4 x i32> %abs
1729}
1730
1731define <8 x i16> @abspattern5(<8 x i16> %a) nounwind {
1732; CHECK-SD-LABEL: abspattern5:
1733; CHECK-SD:       // %bb.0:
1734; CHECK-SD-NEXT:    abs.8h v0, v0
1735; CHECK-SD-NEXT:    ret
1736;
1737; CHECK-GI-LABEL: abspattern5:
1738; CHECK-GI:       // %bb.0:
1739; CHECK-GI-NEXT:    neg.8h v1, v0
1740; CHECK-GI-NEXT:    cmgt.8h v2, v0, #0
1741; CHECK-GI-NEXT:    bif.16b v0, v1, v2
1742; CHECK-GI-NEXT:    ret
1743  %tmp1neg = sub <8 x i16> zeroinitializer, %a
1744  %b = icmp sgt <8 x i16> %a, zeroinitializer
1745  %abs = select <8 x i1> %b, <8 x i16> %a, <8 x i16> %tmp1neg
1746  ret <8 x i16> %abs
1747}
1748
1749define <16 x i8> @abspattern6(<16 x i8> %a) nounwind {
1750; CHECK-SD-LABEL: abspattern6:
1751; CHECK-SD:       // %bb.0:
1752; CHECK-SD-NEXT:    abs.16b v0, v0
1753; CHECK-SD-NEXT:    ret
1754;
1755; CHECK-GI-LABEL: abspattern6:
1756; CHECK-GI:       // %bb.0:
1757; CHECK-GI-NEXT:    neg.16b v1, v0
1758; CHECK-GI-NEXT:    cmlt.16b v2, v0, #0
1759; CHECK-GI-NEXT:    bit.16b v0, v1, v2
1760; CHECK-GI-NEXT:    ret
1761  %tmp1neg = sub <16 x i8> zeroinitializer, %a
1762  %b = icmp slt <16 x i8> %a, zeroinitializer
1763  %abs = select <16 x i1> %b, <16 x i8> %tmp1neg, <16 x i8> %a
1764  ret <16 x i8> %abs
1765}
1766
1767define <2 x i64> @abspattern7(<2 x i64> %a) nounwind {
1768; CHECK-SD-LABEL: abspattern7:
1769; CHECK-SD:       // %bb.0:
1770; CHECK-SD-NEXT:    abs.2d v0, v0
1771; CHECK-SD-NEXT:    ret
1772;
1773; CHECK-GI-LABEL: abspattern7:
1774; CHECK-GI:       // %bb.0:
1775; CHECK-GI-NEXT:    neg.2d v1, v0
1776; CHECK-GI-NEXT:    cmle.2d v2, v0, #0
1777; CHECK-GI-NEXT:    bit.16b v0, v1, v2
1778; CHECK-GI-NEXT:    ret
1779  %tmp1neg = sub <2 x i64> zeroinitializer, %a
1780  %b = icmp sle <2 x i64> %a, zeroinitializer
1781  %abs = select <2 x i1> %b, <2 x i64> %tmp1neg, <2 x i64> %a
1782  ret <2 x i64> %abs
1783}
1784
1785define <2 x i64> @uabd_i32(<2 x i32> %a, <2 x i32> %b) {
1786; CHECK-SD-LABEL: uabd_i32:
1787; CHECK-SD:       // %bb.0:
1788; CHECK-SD-NEXT:    sabdl.2d v0, v0, v1
1789; CHECK-SD-NEXT:    ret
1790;
1791; CHECK-GI-LABEL: uabd_i32:
1792; CHECK-GI:       // %bb.0:
1793; CHECK-GI-NEXT:    ssubl.2d v0, v0, v1
1794; CHECK-GI-NEXT:    cmlt.2d v1, v0, #0
1795; CHECK-GI-NEXT:    neg.2d v2, v0
1796; CHECK-GI-NEXT:    bit.16b v0, v2, v1
1797; CHECK-GI-NEXT:    ret
1798  %aext = sext <2 x i32> %a to <2 x i64>
1799  %bext = sext <2 x i32> %b to <2 x i64>
1800  %abdiff = sub nsw <2 x i64> %aext, %bext
1801  %abcmp = icmp slt <2 x i64> %abdiff, zeroinitializer
1802  %ababs = sub nsw <2 x i64> zeroinitializer, %abdiff
1803  %absel = select <2 x i1> %abcmp, <2 x i64> %ababs, <2 x i64> %abdiff
1804  ret <2 x i64> %absel
1805}
1806
1807define <2 x i128> @uabd_i64(<2 x i64> %a, <2 x i64> %b) {
1808; CHECK-LABEL: uabd_i64:
1809; CHECK:       // %bb.0:
1810; CHECK-NEXT:    cmgt.2d v2, v0, v1
1811; CHECK-NEXT:    sub.2d v0, v0, v1
1812; CHECK-NEXT:    mov x1, xzr
1813; CHECK-NEXT:    mov x3, xzr
1814; CHECK-NEXT:    eor.16b v0, v0, v2
1815; CHECK-NEXT:    sub.2d v0, v2, v0
1816; CHECK-NEXT:    mov.d x2, v0[1]
1817; CHECK-NEXT:    fmov x0, d0
1818; CHECK-NEXT:    ret
1819  %aext = sext <2 x i64> %a to <2 x i128>
1820  %bext = sext <2 x i64> %b to <2 x i128>
1821  %abdiff = sub nsw <2 x i128> %aext, %bext
1822  %abcmp = icmp slt <2 x i128> %abdiff, zeroinitializer
1823  %ababs = sub nsw <2 x i128> zeroinitializer, %abdiff
1824  %absel = select <2 x i1> %abcmp, <2 x i128> %ababs, <2 x i128> %abdiff
1825  ret <2 x i128> %absel
1826}
1827
1828define <8 x i16> @pr88784(<8 x i8> %l0, <8 x i8> %l1, <8 x i16> %l2) {
1829; CHECK-SD-LABEL: pr88784:
1830; CHECK-SD:       // %bb.0:
1831; CHECK-SD-NEXT:    usubl.8h v0, v0, v1
1832; CHECK-SD-NEXT:    cmlt.8h v1, v2, #0
1833; CHECK-SD-NEXT:    ssra.8h v0, v2, #15
1834; CHECK-SD-NEXT:    eor.16b v0, v1, v0
1835; CHECK-SD-NEXT:    ret
1836;
1837; CHECK-GI-LABEL: pr88784:
1838; CHECK-GI:       // %bb.0:
1839; CHECK-GI-NEXT:    usubl.8h v0, v0, v1
1840; CHECK-GI-NEXT:    sshr.8h v1, v2, #15
1841; CHECK-GI-NEXT:    ssra.8h v0, v2, #15
1842; CHECK-GI-NEXT:    eor.16b v0, v1, v0
1843; CHECK-GI-NEXT:    ret
1844  %l4 = zext <8 x i8> %l0 to <8 x i16>
1845  %l5 = ashr <8 x i16> %l2, <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15>
1846  %l6 = zext <8 x i8> %l1 to <8 x i16>
1847  %l7 = sub <8 x i16> %l4, %l6
1848  %l8 = add <8 x i16> %l5, %l7
1849  %l9 = xor <8 x i16> %l5, %l8
1850  ret <8 x i16> %l9
1851}
1852
1853define <8 x i16> @pr88784_fixed(<8 x i8> %l0, <8 x i8> %l1, <8 x i16> %l2) {
1854; CHECK-SD-LABEL: pr88784_fixed:
1855; CHECK-SD:       // %bb.0:
1856; CHECK-SD-NEXT:    uabdl.8h v0, v0, v1
1857; CHECK-SD-NEXT:    ret
1858;
1859; CHECK-GI-LABEL: pr88784_fixed:
1860; CHECK-GI:       // %bb.0:
1861; CHECK-GI-NEXT:    usubl.8h v0, v0, v1
1862; CHECK-GI-NEXT:    sshr.8h v1, v0, #15
1863; CHECK-GI-NEXT:    ssra.8h v0, v0, #15
1864; CHECK-GI-NEXT:    eor.16b v0, v1, v0
1865; CHECK-GI-NEXT:    ret
1866  %l4 = zext <8 x i8> %l0 to <8 x i16>
1867  %l6 = zext <8 x i8> %l1 to <8 x i16>
1868  %l7 = sub <8 x i16> %l4, %l6
1869  %l5 = ashr <8 x i16> %l7, <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15>
1870  %l8 = add <8 x i16> %l5, %l7
1871  %l9 = xor <8 x i16> %l5, %l8
1872  ret <8 x i16> %l9
1873}
1874
1875