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
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
8define <vscale x 2 x i64>* @scalar_of_scalable_1(<vscale x 2 x i64>* %base) {
9; CHECK-LABEL: scalar_of_scalable_1:
10; CHECK:       // %bb.0:
11; CHECK-NEXT:    rdvl x8, #4
12; CHECK-NEXT:    add x0, x0, x8
13; CHECK-NEXT:    ret
14  %d = getelementptr <vscale x 2 x i64>, <vscale x 2 x i64>* %base, i64 4
15  ret <vscale x 2 x i64>* %d
16}
17
18define <vscale x 2 x i64>* @scalar_of_scalable_2(<vscale x 2 x i64>* %base, i64 %offset) {
19; CHECK-LABEL: scalar_of_scalable_2:
20; CHECK:       // %bb.0:
21; CHECK-NEXT:    rdvl x8, #1
22; CHECK-NEXT:    madd x0, x1, x8, x0
23; CHECK-NEXT:    ret
24  %d = getelementptr <vscale x 2 x i64>, <vscale x 2 x i64>* %base, i64 %offset
25  ret <vscale x 2 x i64>* %d
26}
27
28define <vscale x 2 x i32>* @scalar_of_scalable_3(<vscale x 2 x i32>* %base, i64 %offset) {
29; CHECK-LABEL: scalar_of_scalable_3:
30; CHECK:       // %bb.0:
31; CHECK-NEXT:    cnth x8
32; CHECK-NEXT:    madd x0, x1, x8, x0
33; CHECK-NEXT:    ret
34  %d = getelementptr <vscale x 2 x i32>, <vscale x 2 x i32>* %base, i64 %offset
35  ret <vscale x 2 x i32>* %d
36}
37
38define <2 x <vscale x 2 x i64>*> @fixed_of_scalable_1(<vscale x 2 x i64>* %base) {
39; CHECK-LABEL: fixed_of_scalable_1:
40; CHECK:       // %bb.0:
41; CHECK-NEXT:    rdvl x8, #1
42; CHECK-NEXT:    dup v0.2d, x8
43; CHECK-NEXT:    dup v1.2d, x0
44; CHECK-NEXT:    add v0.2d, v1.2d, v0.2d
45; CHECK-NEXT:    ret
46  %d = getelementptr <vscale x 2 x i64>, <vscale x 2 x i64>* %base, <2 x i64> <i64 1, i64 1>
47  ret <2 x <vscale x 2 x i64>*> %d
48}
49
50define <2 x <vscale x 2 x i64>*> @fixed_of_scalable_2(<2 x <vscale x 2 x i64>*> %base) {
51; CHECK-LABEL: fixed_of_scalable_2:
52; CHECK:       // %bb.0:
53; CHECK-NEXT:    rdvl x8, #1
54; CHECK-NEXT:    dup v1.2d, x8
55; CHECK-NEXT:    add v0.2d, v0.2d, v1.2d
56; CHECK-NEXT:    ret
57  %d = getelementptr <vscale x 2 x i64>, <2 x <vscale x 2 x i64>*> %base, <2 x i64> <i64 1, i64 1>
58  ret <2 x <vscale x 2 x i64>*> %d
59}
60
61define <vscale x 2 x i8*> @scalable_of_fixed_1(i8* %base) {
62; CHECK-LABEL: scalable_of_fixed_1:
63; CHECK:       // %bb.0:
64; CHECK-NEXT:    mov z0.d, x0
65; CHECK-NEXT:    add z0.d, z0.d, #1 // =0x1
66; CHECK-NEXT:    ret
67  %idx = shufflevector <vscale x 2 x i64> insertelement (<vscale x 2 x i64> undef, i64 1, i32 0), <vscale x 2 x i64> zeroinitializer, <vscale x 2 x i32> zeroinitializer
68  %d = getelementptr i8, i8* %base, <vscale x 2 x i64> %idx
69  ret <vscale x 2 x i8*> %d
70}
71
72define <vscale x 2 x i8*> @scalable_of_fixed_2(<vscale x 2 x i8*> %base) {
73; CHECK-LABEL: scalable_of_fixed_2:
74; CHECK:       // %bb.0:
75; CHECK-NEXT:    add z0.d, z0.d, #1 // =0x1
76; CHECK-NEXT:    ret
77  %idx = shufflevector <vscale x 2 x i64> insertelement (<vscale x 2 x i64> undef, i64 1, i32 0), <vscale x 2 x i64> zeroinitializer, <vscale x 2 x i32> zeroinitializer
78  %d = getelementptr i8, <vscale x 2 x i8*> %base, <vscale x 2 x i64> %idx
79  ret <vscale x 2 x i8*> %d
80}
81
82define <vscale x 2 x i8*> @scalable_of_fixed_3(i8* %base, <vscale x 2 x i64> %idx) {
83; CHECK-LABEL: scalable_of_fixed_3:
84; CHECK:       // %bb.0:
85; CHECK-NEXT:    mov z1.d, x0
86; CHECK-NEXT:    add z0.d, z1.d, z0.d
87; CHECK-NEXT:    ret
88  %d = getelementptr i8, i8* %base, <vscale x 2 x i64> %idx
89  ret <vscale x 2 x i8*> %d
90}
91
92define <vscale x 2 x i8*> @scalable_of_fixed_4(i8* %base, <vscale x 2 x i32> %idx) {
93; CHECK-LABEL: scalable_of_fixed_4:
94; CHECK:       // %bb.0:
95; CHECK-NEXT:    ptrue p0.d
96; CHECK-NEXT:    sxtw z0.d, p0/m, z0.d
97; CHECK-NEXT:    mov z1.d, x0
98; CHECK-NEXT:    add z0.d, z1.d, z0.d
99; CHECK-NEXT:    ret
100  %d = getelementptr i8, i8* %base, <vscale x 2 x i32> %idx
101  ret <vscale x 2 x i8*> %d
102}
103
104define <vscale x 2 x <vscale x 2 x i64>*> @scalable_of_scalable_1(<vscale x 2 x i64>* %base) {
105; CHECK-LABEL: scalable_of_scalable_1:
106; CHECK:       // %bb.0:
107; CHECK-NEXT:    rdvl x8, #1
108; CHECK-NEXT:    mov z0.d, x8
109; CHECK-NEXT:    mov z1.d, x0
110; CHECK-NEXT:    add z0.d, z1.d, z0.d
111; CHECK-NEXT:    ret
112  %idx = shufflevector <vscale x 2 x i64> insertelement (<vscale x 2 x i64> undef, i64 1, i32 0), <vscale x 2 x i64> zeroinitializer, <vscale x 2 x i32> zeroinitializer
113  %d = getelementptr <vscale x 2 x i64>, <vscale x 2 x i64>* %base, <vscale x 2 x i64> %idx
114  ret <vscale x 2 x <vscale x 2 x i64>*> %d
115}
116
117define <vscale x 2 x <vscale x 2 x i64>*> @scalable_of_scalable_2(<vscale x 2 x <vscale x 2 x i64>*> %base) {
118; CHECK-LABEL: scalable_of_scalable_2:
119; CHECK:       // %bb.0:
120; CHECK-NEXT:    rdvl x8, #1
121; CHECK-NEXT:    mov z1.d, x8
122; CHECK-NEXT:    add z0.d, z0.d, z1.d
123; CHECK-NEXT:    ret
124  %idx = shufflevector <vscale x 2 x i64> insertelement (<vscale x 2 x i64> undef, i64 1, i32 0), <vscale x 2 x i64> zeroinitializer, <vscale x 2 x i32> zeroinitializer
125  %d = getelementptr <vscale x 2 x i64>, <vscale x 2 x <vscale x 2 x i64>*> %base, <vscale x 2 x i64> %idx
126  ret <vscale x 2 x <vscale x 2 x i64>*> %d
127}
128
129define <vscale x 2 x <vscale x 2 x i64>*> @scalable_of_scalable_3(<vscale x 2 x <vscale x 2 x i64>*> %base, <vscale x 2 x i32> %idx) {
130; CHECK-LABEL: scalable_of_scalable_3:
131; CHECK:       // %bb.0:
132; CHECK-NEXT:    ptrue p0.d
133; CHECK-NEXT:    rdvl x8, #1
134; CHECK-NEXT:    sxtw z1.d, p0/m, z1.d
135; CHECK-NEXT:    mov z2.d, x8
136; CHECK-NEXT:    mla z0.d, p0/m, z1.d, z2.d
137; CHECK-NEXT:    ret
138  %d = getelementptr <vscale x 2 x i64>, <vscale x 2 x <vscale x 2 x i64>*> %base, <vscale x 2 x i32> %idx
139  ret <vscale x 2 x <vscale x 2 x i64>*> %d
140}
141