xref: /llvm-project/llvm/test/CodeGen/AArch64/abs.ll (revision 61510b51c33464a6bc15e4cf5b1ee07e2e0ec1c9)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
2; RUN: llc -mtriple=aarch64-none-linux-gnu %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD
3; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GI
4
5; ===== Legal Scalars =====
6
7define i8 @abs_i8(i8 %a){
8; CHECK-SD-LABEL: abs_i8:
9; CHECK-SD:       // %bb.0: // %entry
10; CHECK-SD-NEXT:    sxtb w8, w0
11; CHECK-SD-NEXT:    cmp w8, #0
12; CHECK-SD-NEXT:    cneg w0, w8, mi
13; CHECK-SD-NEXT:    ret
14;
15; CHECK-GI-LABEL: abs_i8:
16; CHECK-GI:       // %bb.0: // %entry
17; CHECK-GI-NEXT:    sxtb w8, w0
18; CHECK-GI-NEXT:    cmp w8, #0
19; CHECK-GI-NEXT:    cneg w0, w0, le
20; CHECK-GI-NEXT:    ret
21entry:
22  %res = call i8 @llvm.abs.i8(i8 %a, i1 0)
23  ret i8 %res
24}
25declare i8 @llvm.abs.i8(i8, i1)
26
27define i16 @abs_i16(i16 %a){
28; CHECK-SD-LABEL: abs_i16:
29; CHECK-SD:       // %bb.0: // %entry
30; CHECK-SD-NEXT:    sxth w8, w0
31; CHECK-SD-NEXT:    cmp w8, #0
32; CHECK-SD-NEXT:    cneg w0, w8, mi
33; CHECK-SD-NEXT:    ret
34;
35; CHECK-GI-LABEL: abs_i16:
36; CHECK-GI:       // %bb.0: // %entry
37; CHECK-GI-NEXT:    sxth w8, w0
38; CHECK-GI-NEXT:    cmp w8, #0
39; CHECK-GI-NEXT:    cneg w0, w0, le
40; CHECK-GI-NEXT:    ret
41entry:
42  %res = call i16 @llvm.abs.i16(i16 %a, i1 0)
43  ret i16 %res
44}
45declare i16 @llvm.abs.i16(i16, i1)
46
47define i32 @abs_i32(i32 %a){
48; CHECK-SD-LABEL: abs_i32:
49; CHECK-SD:       // %bb.0: // %entry
50; CHECK-SD-NEXT:    cmp w0, #0
51; CHECK-SD-NEXT:    cneg w0, w0, mi
52; CHECK-SD-NEXT:    ret
53;
54; CHECK-GI-LABEL: abs_i32:
55; CHECK-GI:       // %bb.0: // %entry
56; CHECK-GI-NEXT:    cmp w0, #0
57; CHECK-GI-NEXT:    cneg w0, w0, le
58; CHECK-GI-NEXT:    ret
59entry:
60  %res = call i32 @llvm.abs.i32(i32 %a, i1 0)
61  ret i32 %res
62}
63declare i32 @llvm.abs.i32(i32, i1)
64
65define i64 @abs_i64(i64 %a){
66; CHECK-SD-LABEL: abs_i64:
67; CHECK-SD:       // %bb.0: // %entry
68; CHECK-SD-NEXT:    cmp x0, #0
69; CHECK-SD-NEXT:    cneg x0, x0, mi
70; CHECK-SD-NEXT:    ret
71;
72; CHECK-GI-LABEL: abs_i64:
73; CHECK-GI:       // %bb.0: // %entry
74; CHECK-GI-NEXT:    cmp x0, #0
75; CHECK-GI-NEXT:    cneg x0, x0, le
76; CHECK-GI-NEXT:    ret
77entry:
78  %res = call i64 @llvm.abs.i64(i64 %a, i1 0)
79  ret i64 %res
80}
81declare i64 @llvm.abs.i64(i64, i1)
82
83define i128 @abs_i128(i128 %a){
84; CHECK-SD-LABEL: abs_i128:
85; CHECK-SD:       // %bb.0: // %entry
86; CHECK-SD-NEXT:    asr x8, x1, #63
87; CHECK-SD-NEXT:    eor x9, x0, x8
88; CHECK-SD-NEXT:    eor x10, x1, x8
89; CHECK-SD-NEXT:    subs x0, x9, x8
90; CHECK-SD-NEXT:    sbc x1, x10, x8
91; CHECK-SD-NEXT:    ret
92;
93; CHECK-GI-LABEL: abs_i128:
94; CHECK-GI:       // %bb.0: // %entry
95; CHECK-GI-NEXT:    asr x8, x1, #63
96; CHECK-GI-NEXT:    adds x9, x0, x8
97; CHECK-GI-NEXT:    adc x10, x1, x8
98; CHECK-GI-NEXT:    eor x0, x9, x8
99; CHECK-GI-NEXT:    eor x1, x10, x8
100; CHECK-GI-NEXT:    ret
101entry:
102  %res = call i128 @llvm.abs.i128(i128 %a, i1 0)
103  ret i128 %res
104}
105declare i128 @llvm.abs.i128(i128, i1)
106
107; ===== Legal Vector Types =====
108
109define <8 x i8> @abs_v8i8(<8 x i8> %a){
110; CHECK-LABEL: abs_v8i8:
111; CHECK:       // %bb.0: // %entry
112; CHECK-NEXT:    abs v0.8b, v0.8b
113; CHECK-NEXT:    ret
114entry:
115  %res = call <8 x i8> @llvm.abs.v8i8(<8 x i8> %a, i1 0)
116  ret <8 x i8> %res
117}
118declare <8 x i8> @llvm.abs.v8i8(<8 x i8>, i1)
119
120define <16 x i8> @abs_v16i8(<16 x i8> %a){
121; CHECK-LABEL: abs_v16i8:
122; CHECK:       // %bb.0: // %entry
123; CHECK-NEXT:    abs v0.16b, v0.16b
124; CHECK-NEXT:    ret
125entry:
126  %res = call <16 x i8> @llvm.abs.v16i8(<16 x i8> %a, i1 0)
127  ret <16 x i8> %res
128}
129declare <16 x i8> @llvm.abs.v16i8(<16 x i8>, i1)
130
131define <4 x i16> @abs_v4i16(<4 x i16> %a){
132; CHECK-LABEL: abs_v4i16:
133; CHECK:       // %bb.0: // %entry
134; CHECK-NEXT:    abs v0.4h, v0.4h
135; CHECK-NEXT:    ret
136entry:
137  %res = call <4 x i16> @llvm.abs.v4i16(<4 x i16> %a, i1 0)
138  ret <4 x i16> %res
139}
140declare <4 x i16> @llvm.abs.v4i16(<4 x i16>, i1)
141
142define <8 x i16> @abs_v8i16(<8 x i16> %a){
143; CHECK-LABEL: abs_v8i16:
144; CHECK:       // %bb.0: // %entry
145; CHECK-NEXT:    abs v0.8h, v0.8h
146; CHECK-NEXT:    ret
147entry:
148  %res = call <8 x i16> @llvm.abs.v8i16(<8 x i16> %a, i1 0)
149  ret <8 x i16> %res
150}
151declare <8 x i16> @llvm.abs.v8i16(<8 x i16>, i1)
152
153define <2 x i32> @abs_v2i32(<2 x i32> %a){
154; CHECK-LABEL: abs_v2i32:
155; CHECK:       // %bb.0: // %entry
156; CHECK-NEXT:    abs v0.2s, v0.2s
157; CHECK-NEXT:    ret
158entry:
159  %res = call <2 x i32> @llvm.abs.v2i32(<2 x i32> %a, i1 0)
160  ret <2 x i32> %res
161}
162declare <2 x i32> @llvm.abs.v2i32(<2 x i32>, i1)
163
164define <4 x i32> @abs_v4i32(<4 x i32> %a){
165; CHECK-LABEL: abs_v4i32:
166; CHECK:       // %bb.0: // %entry
167; CHECK-NEXT:    abs v0.4s, v0.4s
168; CHECK-NEXT:    ret
169entry:
170  %res = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %a, i1 0)
171  ret <4 x i32> %res
172}
173declare <4 x i32> @llvm.abs.v4i32(<4 x i32>, i1)
174
175define <2 x i64> @abs_v2i64(<2 x i64> %a){
176; CHECK-LABEL: abs_v2i64:
177; CHECK:       // %bb.0: // %entry
178; CHECK-NEXT:    abs v0.2d, v0.2d
179; CHECK-NEXT:    ret
180entry:
181  %res = call <2 x i64> @llvm.abs.v2i64(<2 x i64> %a, i1 0)
182  ret <2 x i64> %res
183}
184declare <2 x i64> @llvm.abs.v2i64(<2 x i64>, i1)
185
186; ===== Smaller/Larger Width Vectors with Legal Element Sizes =====
187
188define <4 x i8> @abs_v4i8(<4 x i8> %a){
189; CHECK-LABEL: abs_v4i8:
190; CHECK:       // %bb.0: // %entry
191; CHECK-NEXT:    shl v0.4h, v0.4h, #8
192; CHECK-NEXT:    sshr v0.4h, v0.4h, #8
193; CHECK-NEXT:    abs v0.4h, v0.4h
194; CHECK-NEXT:    ret
195entry:
196  %res = call <4 x i8> @llvm.abs.v4i8(<4 x i8> %a, i1 0)
197  ret <4 x i8> %res
198}
199declare <4 x i8> @llvm.abs.v4i8(<4 x i8>, i1)
200
201define <32 x i8> @abs_v32i8(<32 x i8> %a){
202; CHECK-LABEL: abs_v32i8:
203; CHECK:       // %bb.0: // %entry
204; CHECK-NEXT:    abs v0.16b, v0.16b
205; CHECK-NEXT:    abs v1.16b, v1.16b
206; CHECK-NEXT:    ret
207entry:
208  %res = call <32 x i8> @llvm.abs.v32i8(<32 x i8> %a, i1 0)
209  ret <32 x i8> %res
210}
211declare <32 x i8> @llvm.abs.v32i8(<32 x i8>, i1)
212
213define <2 x i16> @abs_v2i16(<2 x i16> %a){
214; CHECK-LABEL: abs_v2i16:
215; CHECK:       // %bb.0: // %entry
216; CHECK-NEXT:    shl v0.2s, v0.2s, #16
217; CHECK-NEXT:    sshr v0.2s, v0.2s, #16
218; CHECK-NEXT:    abs v0.2s, v0.2s
219; CHECK-NEXT:    ret
220entry:
221  %res = call <2 x i16> @llvm.abs.v2i16(<2 x i16> %a, i1 0)
222  ret <2 x i16> %res
223}
224declare <2 x i16> @llvm.abs.v2i16(<2 x i16>, i1)
225
226define <16 x i16> @abs_v16i16(<16 x i16> %a){
227; CHECK-LABEL: abs_v16i16:
228; CHECK:       // %bb.0: // %entry
229; CHECK-NEXT:    abs v0.8h, v0.8h
230; CHECK-NEXT:    abs v1.8h, v1.8h
231; CHECK-NEXT:    ret
232entry:
233  %res = call <16 x i16> @llvm.abs.v16i16(<16 x i16> %a, i1 0)
234  ret <16 x i16> %res
235}
236declare <16 x i16> @llvm.abs.v16i16(<16 x i16>, i1)
237
238define <1 x i32> @abs_v1i32(<1 x i32> %a){
239; CHECK-SD-LABEL: abs_v1i32:
240; CHECK-SD:       // %bb.0: // %entry
241; CHECK-SD-NEXT:    abs v0.2s, v0.2s
242; CHECK-SD-NEXT:    ret
243;
244; CHECK-GI-LABEL: abs_v1i32:
245; CHECK-GI:       // %bb.0: // %entry
246; CHECK-GI-NEXT:    fmov w8, s0
247; CHECK-GI-NEXT:    fmov w9, s0
248; CHECK-GI-NEXT:    cmp w8, #0
249; CHECK-GI-NEXT:    cneg w8, w9, le
250; CHECK-GI-NEXT:    mov v0.s[0], w8
251; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0
252; CHECK-GI-NEXT:    ret
253entry:
254  %res = call <1 x i32> @llvm.abs.v1i32(<1 x i32> %a, i1 0)
255  ret <1 x i32> %res
256}
257declare <1 x i32> @llvm.abs.v1i32(<1 x i32>, i1)
258
259define <8 x i32> @abs_v8i32(<8 x i32> %a){
260; CHECK-LABEL: abs_v8i32:
261; CHECK:       // %bb.0: // %entry
262; CHECK-NEXT:    abs v0.4s, v0.4s
263; CHECK-NEXT:    abs v1.4s, v1.4s
264; CHECK-NEXT:    ret
265entry:
266  %res = call <8 x i32> @llvm.abs.v8i32(<8 x i32> %a, i1 0)
267  ret <8 x i32> %res
268}
269declare <8 x i32> @llvm.abs.v8i32(<8 x i32>, i1)
270
271define <4 x i64> @abs_v4i64(<4 x i64> %a){
272; CHECK-LABEL: abs_v4i64:
273; CHECK:       // %bb.0: // %entry
274; CHECK-NEXT:    abs v0.2d, v0.2d
275; CHECK-NEXT:    abs v1.2d, v1.2d
276; CHECK-NEXT:    ret
277entry:
278  %res = call <4 x i64> @llvm.abs.v4i64(<4 x i64> %a, i1 0)
279  ret <4 x i64> %res
280}
281declare <4 x i64> @llvm.abs.v4i64(<4 x i64>, i1)
282
283define <2 x i128> @abs_v4i128(<2 x i128> %a){
284; CHECK-SD-LABEL: abs_v4i128:
285; CHECK-SD:       // %bb.0: // %entry
286; CHECK-SD-NEXT:    asr x8, x1, #63
287; CHECK-SD-NEXT:    asr x9, x3, #63
288; CHECK-SD-NEXT:    eor x10, x0, x8
289; CHECK-SD-NEXT:    eor x11, x1, x8
290; CHECK-SD-NEXT:    subs x0, x10, x8
291; CHECK-SD-NEXT:    eor x10, x2, x9
292; CHECK-SD-NEXT:    sbc x1, x11, x8
293; CHECK-SD-NEXT:    eor x8, x3, x9
294; CHECK-SD-NEXT:    subs x2, x10, x9
295; CHECK-SD-NEXT:    sbc x3, x8, x9
296; CHECK-SD-NEXT:    ret
297;
298; CHECK-GI-LABEL: abs_v4i128:
299; CHECK-GI:       // %bb.0: // %entry
300; CHECK-GI-NEXT:    asr x8, x1, #63
301; CHECK-GI-NEXT:    asr x9, x3, #63
302; CHECK-GI-NEXT:    adds x10, x0, x8
303; CHECK-GI-NEXT:    adc x11, x1, x8
304; CHECK-GI-NEXT:    adds x12, x2, x9
305; CHECK-GI-NEXT:    eor x0, x10, x8
306; CHECK-GI-NEXT:    adc x13, x3, x9
307; CHECK-GI-NEXT:    eor x1, x11, x8
308; CHECK-GI-NEXT:    eor x2, x12, x9
309; CHECK-GI-NEXT:    eor x3, x13, x9
310; CHECK-GI-NEXT:    ret
311entry:
312  %res = call <2 x i128> @llvm.abs.v2i128(<2 x i128> %a, i1 0)
313  ret <2 x i128> %res
314}
315declare <2 x i128> @llvm.abs.v2i128(<2 x i128>, i1)
316
317; ===== Vectors with Non-Pow 2 Widths =====
318
319define <3 x i8> @abs_v3i8(<3 x i8> %a){
320; CHECK-SD-LABEL: abs_v3i8:
321; CHECK-SD:       // %bb.0: // %entry
322; CHECK-SD-NEXT:    fmov s0, w0
323; CHECK-SD-NEXT:    mov v0.h[1], w1
324; CHECK-SD-NEXT:    mov v0.h[2], w2
325; CHECK-SD-NEXT:    shl v0.4h, v0.4h, #8
326; CHECK-SD-NEXT:    sshr v0.4h, v0.4h, #8
327; CHECK-SD-NEXT:    abs v0.4h, v0.4h
328; CHECK-SD-NEXT:    umov w0, v0.h[0]
329; CHECK-SD-NEXT:    umov w1, v0.h[1]
330; CHECK-SD-NEXT:    umov w2, v0.h[2]
331; CHECK-SD-NEXT:    ret
332;
333; CHECK-GI-LABEL: abs_v3i8:
334; CHECK-GI:       // %bb.0: // %entry
335; CHECK-GI-NEXT:    fmov s0, w0
336; CHECK-GI-NEXT:    mov v0.b[1], w1
337; CHECK-GI-NEXT:    mov v0.b[2], w2
338; CHECK-GI-NEXT:    abs v0.8b, v0.8b
339; CHECK-GI-NEXT:    umov w0, v0.b[0]
340; CHECK-GI-NEXT:    umov w1, v0.b[1]
341; CHECK-GI-NEXT:    umov w2, v0.b[2]
342; CHECK-GI-NEXT:    ret
343entry:
344  %res = call <3 x i8> @llvm.abs.v3i8(<3 x i8> %a, i1 0)
345  ret <3 x i8> %res
346}
347declare <3 x i8> @llvm.abs.v3i8(<3 x i8>, i1)
348
349define <7 x i8> @abs_v7i8(<7 x i8> %a){
350; CHECK-LABEL: abs_v7i8:
351; CHECK:       // %bb.0: // %entry
352; CHECK-NEXT:    abs v0.8b, v0.8b
353; CHECK-NEXT:    ret
354entry:
355  %res = call <7 x i8> @llvm.abs.v7i8(<7 x i8> %a, i1 0)
356  ret <7 x i8> %res
357}
358declare <7 x i8> @llvm.abs.v7i8(<7 x i8>, i1)
359
360define <3 x i16> @abs_v3i16(<3 x i16> %a){
361; CHECK-LABEL: abs_v3i16:
362; CHECK:       // %bb.0: // %entry
363; CHECK-NEXT:    abs v0.4h, v0.4h
364; CHECK-NEXT:    ret
365entry:
366  %res = call <3 x i16> @llvm.abs.v3i16(<3 x i16> %a, i1 0)
367  ret <3 x i16> %res
368}
369declare <3 x i16> @llvm.abs.v3i16(<3 x i16>, i1)
370
371define <7 x i16> @abs_v7i16(<7 x i16> %a){
372; CHECK-LABEL: abs_v7i16:
373; CHECK:       // %bb.0: // %entry
374; CHECK-NEXT:    abs v0.8h, v0.8h
375; CHECK-NEXT:    ret
376entry:
377  %res = call <7 x i16> @llvm.abs.v7i16(<7 x i16> %a, i1 0)
378  ret <7 x i16> %res
379}
380declare <7 x i16> @llvm.abs.v7i16(<7 x i16>, i1)
381
382define <3 x i32> @abs_v3i32(<3 x i32> %a){
383; CHECK-LABEL: abs_v3i32:
384; CHECK:       // %bb.0: // %entry
385; CHECK-NEXT:    abs v0.4s, v0.4s
386; CHECK-NEXT:    ret
387entry:
388  %res = call <3 x i32> @llvm.abs.v3i32(<3 x i32> %a, i1 0)
389  ret <3 x i32> %res
390}
391declare <3 x i32> @llvm.abs.v3i32(<3 x i32>, i1)
392