1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s 2>%t | FileCheck %s --check-prefixes=CHECK
3; RUN: FileCheck --check-prefix=WARN --allow-empty %s < %t
4
5; If this check fails please read test/CodeGen/AArch64/README for instructions on how to resolve it.
6; WARN-NOT: warning
7
8; Should codegen to a nop, since idx is zero.
9define <2 x i64> @extract_v2i64_nxv2i64(<vscale x 2 x i64> %vec) nounwind {
10; CHECK-LABEL: extract_v2i64_nxv2i64:
11; CHECK:       // %bb.0:
12; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
13; CHECK-NEXT:    ret
14  %retval = call <2 x i64> @llvm.experimental.vector.extract.v2i64.nxv2i64(<vscale x 2 x i64> %vec, i64 0)
15  ret <2 x i64> %retval
16}
17
18; Goes through memory currently; idx != 0.
19define <2 x i64> @extract_v2i64_nxv2i64_idx1(<vscale x 2 x i64> %vec) nounwind {
20; CHECK-LABEL: extract_v2i64_nxv2i64_idx1:
21; CHECK:       // %bb.0:
22; CHECK-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill
23; CHECK-NEXT:    addvl sp, sp, #-1
24; CHECK-NEXT:    cntd x8
25; CHECK-NEXT:    sub x8, x8, #1 // =1
26; CHECK-NEXT:    cmp x8, #1 // =1
27; CHECK-NEXT:    ptrue p0.d
28; CHECK-NEXT:    csinc x8, x8, xzr, lo
29; CHECK-NEXT:    st1d { z0.d }, p0, [sp]
30; CHECK-NEXT:    lsl x8, x8, #3
31; CHECK-NEXT:    mov x9, sp
32; CHECK-NEXT:    ldr q0, [x9, x8]
33; CHECK-NEXT:    addvl sp, sp, #1
34; CHECK-NEXT:    ldr x29, [sp], #16 // 8-byte Folded Reload
35; CHECK-NEXT:    ret
36%retval = call <2 x i64> @llvm.experimental.vector.extract.v2i64.nxv2i64(<vscale x 2 x i64> %vec, i64 1)
37ret <2 x i64> %retval
38}
39
40; Should codegen to a nop, since idx is zero.
41define <4 x i32> @extract_v4i32_nxv4i32(<vscale x 4 x i32> %vec) nounwind {
42; CHECK-LABEL: extract_v4i32_nxv4i32:
43; CHECK:       // %bb.0:
44; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
45; CHECK-NEXT:    ret
46%retval = call <4 x i32> @llvm.experimental.vector.extract.v4i32.nxv4i32(<vscale x 4 x i32> %vec, i64 0)
47ret <4 x i32> %retval
48}
49
50; Goes through memory currently; idx != 0.
51define <4 x i32> @extract_v4i32_nxv4i32_idx1(<vscale x 4 x i32> %vec) nounwind {
52; CHECK-LABEL: extract_v4i32_nxv4i32_idx1:
53; CHECK:       // %bb.0:
54; CHECK-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill
55; CHECK-NEXT:    addvl sp, sp, #-1
56; CHECK-NEXT:    cntw x8
57; CHECK-NEXT:    sub x8, x8, #1 // =1
58; CHECK-NEXT:    cmp x8, #1 // =1
59; CHECK-NEXT:    ptrue p0.s
60; CHECK-NEXT:    csinc x8, x8, xzr, lo
61; CHECK-NEXT:    st1w { z0.s }, p0, [sp]
62; CHECK-NEXT:    lsl x8, x8, #2
63; CHECK-NEXT:    mov x9, sp
64; CHECK-NEXT:    ldr q0, [x9, x8]
65; CHECK-NEXT:    addvl sp, sp, #1
66; CHECK-NEXT:    ldr x29, [sp], #16 // 8-byte Folded Reload
67; CHECK-NEXT:    ret
68  %retval = call <4 x i32> @llvm.experimental.vector.extract.v4i32.nxv4i32(<vscale x 4 x i32> %vec, i64 1)
69  ret <4 x i32> %retval
70}
71
72; Should codegen to a nop, since idx is zero.
73define <8 x i16> @extract_v8i16_nxv8i16(<vscale x 8 x i16> %vec) nounwind {
74; CHECK-LABEL: extract_v8i16_nxv8i16:
75; CHECK:       // %bb.0:
76; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
77; CHECK-NEXT:    ret
78  %retval = call <8 x i16> @llvm.experimental.vector.extract.v8i16.nxv8i16(<vscale x 8 x i16> %vec, i64 0)
79  ret <8 x i16> %retval
80}
81
82; Goes through memory currently; idx != 0.
83define <8 x i16> @extract_v8i16_nxv8i16_idx1(<vscale x 8 x i16> %vec) nounwind {
84; CHECK-LABEL: extract_v8i16_nxv8i16_idx1:
85; CHECK:       // %bb.0:
86; CHECK-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill
87; CHECK-NEXT:    addvl sp, sp, #-1
88; CHECK-NEXT:    cnth x8
89; CHECK-NEXT:    sub x8, x8, #1 // =1
90; CHECK-NEXT:    cmp x8, #1 // =1
91; CHECK-NEXT:    ptrue p0.h
92; CHECK-NEXT:    csinc x8, x8, xzr, lo
93; CHECK-NEXT:    st1h { z0.h }, p0, [sp]
94; CHECK-NEXT:    lsl x8, x8, #1
95; CHECK-NEXT:    mov x9, sp
96; CHECK-NEXT:    ldr q0, [x9, x8]
97; CHECK-NEXT:    addvl sp, sp, #1
98; CHECK-NEXT:    ldr x29, [sp], #16 // 8-byte Folded Reload
99; CHECK-NEXT:    ret
100  %retval = call <8 x i16> @llvm.experimental.vector.extract.v8i16.nxv8i16(<vscale x 8 x i16> %vec, i64 1)
101  ret <8 x i16> %retval
102}
103
104; Should codegen to a nop, since idx is zero.
105define <16 x i8> @extract_v16i8_nxv16i8(<vscale x 16 x i8> %vec) nounwind {
106; CHECK-LABEL: extract_v16i8_nxv16i8:
107; CHECK:       // %bb.0:
108; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
109; CHECK-NEXT:    ret
110  %retval = call <16 x i8> @llvm.experimental.vector.extract.v16i8.nxv16i8(<vscale x 16 x i8> %vec, i64 0)
111  ret <16 x i8> %retval
112}
113
114; Goes through memory currently; idx != 0.
115define <16 x i8> @extract_v16i8_nxv16i8_idx1(<vscale x 16 x i8> %vec) nounwind {
116; CHECK-LABEL: extract_v16i8_nxv16i8_idx1:
117; CHECK:       // %bb.0:
118; CHECK-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill
119; CHECK-NEXT:    addvl sp, sp, #-1
120; CHECK-NEXT:    rdvl x8, #1
121; CHECK-NEXT:    sub x8, x8, #1 // =1
122; CHECK-NEXT:    ptrue p0.b
123; CHECK-NEXT:    cmp x8, #1 // =1
124; CHECK-NEXT:    st1b { z0.b }, p0, [sp]
125; CHECK-NEXT:    csinc x8, x8, xzr, lo
126; CHECK-NEXT:    mov x9, sp
127; CHECK-NEXT:    ldr q0, [x9, x8]
128; CHECK-NEXT:    addvl sp, sp, #1
129; CHECK-NEXT:    ldr x29, [sp], #16 // 8-byte Folded Reload
130; CHECK-NEXT:    ret
131  %retval = call <16 x i8> @llvm.experimental.vector.extract.v16i8.nxv16i8(<vscale x 16 x i8> %vec, i64 1)
132  ret <16 x i8> %retval
133}
134
135declare <2 x i64> @llvm.experimental.vector.extract.v2i64.nxv2i64(<vscale x 2 x i64>, i64)
136declare <4 x i32> @llvm.experimental.vector.extract.v4i32.nxv4i32(<vscale x 4 x i32>, i64)
137declare <8 x i16> @llvm.experimental.vector.extract.v8i16.nxv8i16(<vscale x 8 x i16>, i64)
138declare <16 x i8> @llvm.experimental.vector.extract.v16i8.nxv16i8(<vscale x 16 x i8>, i64)
139