1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s
4 define <vscale x 2 x i64>* @scalar_of_scalable_1(<vscale x 2 x i64>* %base) {
5 ; CHECK-LABEL: scalar_of_scalable_1:
7 ; CHECK-NEXT: addvl x0, x0, #4
9 %d = getelementptr <vscale x 2 x i64>, <vscale x 2 x i64>* %base, i64 4
10 ret <vscale x 2 x i64>* %d
13 define <vscale x 2 x i64>* @scalar_of_scalable_2(<vscale x 2 x i64>* %base, i64 %offset) {
14 ; CHECK-LABEL: scalar_of_scalable_2:
16 ; CHECK-NEXT: rdvl x8, #1
17 ; CHECK-NEXT: madd x0, x1, x8, x0
19 %d = getelementptr <vscale x 2 x i64>, <vscale x 2 x i64>* %base, i64 %offset
20 ret <vscale x 2 x i64>* %d
23 define <vscale x 2 x i32>* @scalar_of_scalable_3(<vscale x 2 x i32>* %base, i64 %offset) {
24 ; CHECK-LABEL: scalar_of_scalable_3:
27 ; CHECK-NEXT: madd x0, x1, x8, x0
29 %d = getelementptr <vscale x 2 x i32>, <vscale x 2 x i32>* %base, i64 %offset
30 ret <vscale x 2 x i32>* %d
33 define <2 x <vscale x 2 x i64>*> @fixed_of_scalable_1(<vscale x 2 x i64>* %base) {
34 ; CHECK-LABEL: fixed_of_scalable_1:
36 ; CHECK-NEXT: rdvl x8, #1
37 ; CHECK-NEXT: dup v1.2d, x0
38 ; CHECK-NEXT: dup v0.2d, x8
39 ; CHECK-NEXT: add v0.2d, v1.2d, v0.2d
41 %d = getelementptr <vscale x 2 x i64>, <vscale x 2 x i64>* %base, <2 x i64> <i64 1, i64 1>
42 ret <2 x <vscale x 2 x i64>*> %d
45 define <2 x <vscale x 2 x i64>*> @fixed_of_scalable_2(<2 x <vscale x 2 x i64>*> %base) {
46 ; CHECK-LABEL: fixed_of_scalable_2:
48 ; CHECK-NEXT: rdvl x8, #1
49 ; CHECK-NEXT: dup v1.2d, x8
50 ; CHECK-NEXT: add v0.2d, v0.2d, v1.2d
52 %d = getelementptr <vscale x 2 x i64>, <2 x <vscale x 2 x i64>*> %base, <2 x i64> <i64 1, i64 1>
53 ret <2 x <vscale x 2 x i64>*> %d
56 define <vscale x 2 x i8*> @scalable_of_fixed_1(i8* %base) {
57 ; CHECK-LABEL: scalable_of_fixed_1:
59 ; CHECK-NEXT: add x8, x0, #1
60 ; CHECK-NEXT: mov z0.d, x8
62 %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
63 %d = getelementptr i8, i8* %base, <vscale x 2 x i64> %idx
64 ret <vscale x 2 x i8*> %d
67 define <vscale x 2 x i8*> @scalable_of_fixed_2(<vscale x 2 x i8*> %base) {
68 ; CHECK-LABEL: scalable_of_fixed_2:
70 ; CHECK-NEXT: add z0.d, z0.d, #1 // =0x1
72 %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
73 %d = getelementptr i8, <vscale x 2 x i8*> %base, <vscale x 2 x i64> %idx
74 ret <vscale x 2 x i8*> %d
77 define <vscale x 2 x i8*> @scalable_of_fixed_3_i8(i8* %base, <vscale x 2 x i64> %idx) {
78 ; CHECK-LABEL: scalable_of_fixed_3_i8:
80 ; CHECK-NEXT: mov z1.d, x0
81 ; CHECK-NEXT: add z0.d, z1.d, z0.d
83 %d = getelementptr i8, i8* %base, <vscale x 2 x i64> %idx
84 ret <vscale x 2 x i8*> %d
87 define <vscale x 2 x i16*> @scalable_of_fixed_3_i16(i16* %base, <vscale x 2 x i64> %idx) {
88 ; CHECK-LABEL: scalable_of_fixed_3_i16:
90 ; CHECK-NEXT: mov z1.d, x0
91 ; CHECK-NEXT: adr z0.d, [z1.d, z0.d, lsl #1]
93 %d = getelementptr i16, i16* %base, <vscale x 2 x i64> %idx
94 ret <vscale x 2 x i16*> %d
97 define <vscale x 2 x i32*> @scalable_of_fixed_3_i32(i32* %base, <vscale x 2 x i64> %idx) {
98 ; CHECK-LABEL: scalable_of_fixed_3_i32:
100 ; CHECK-NEXT: mov z1.d, x0
101 ; CHECK-NEXT: adr z0.d, [z1.d, z0.d, lsl #2]
103 %d = getelementptr i32, i32* %base, <vscale x 2 x i64> %idx
104 ret <vscale x 2 x i32*> %d
107 define <vscale x 2 x i64*> @scalable_of_fixed_3_i64(i64* %base, <vscale x 2 x i64> %idx) {
108 ; CHECK-LABEL: scalable_of_fixed_3_i64:
110 ; CHECK-NEXT: mov z1.d, x0
111 ; CHECK-NEXT: adr z0.d, [z1.d, z0.d, lsl #3]
113 %d = getelementptr i64, i64* %base, <vscale x 2 x i64> %idx
114 ret <vscale x 2 x i64*> %d
117 define <vscale x 2 x i8*> @scalable_of_fixed_4_i8(i8* %base, <vscale x 2 x i32> %idx) {
118 ; CHECK-LABEL: scalable_of_fixed_4_i8:
120 ; CHECK-NEXT: mov z1.d, x0
121 ; CHECK-NEXT: adr z0.d, [z1.d, z0.d, sxtw]
123 %d = getelementptr i8, i8* %base, <vscale x 2 x i32> %idx
124 ret <vscale x 2 x i8*> %d
127 define <vscale x 2 x i16*> @scalable_of_fixed_4_i16(i16* %base, <vscale x 2 x i32> %idx) {
128 ; CHECK-LABEL: scalable_of_fixed_4_i16:
130 ; CHECK-NEXT: mov z1.d, x0
131 ; CHECK-NEXT: adr z0.d, [z1.d, z0.d, sxtw #1]
133 %d = getelementptr i16, i16* %base, <vscale x 2 x i32> %idx
134 ret <vscale x 2 x i16*> %d
137 define <vscale x 2 x i32*> @scalable_of_fixed_4_i32(i32* %base, <vscale x 2 x i32> %idx) {
138 ; CHECK-LABEL: scalable_of_fixed_4_i32:
140 ; CHECK-NEXT: mov z1.d, x0
141 ; CHECK-NEXT: adr z0.d, [z1.d, z0.d, sxtw #2]
143 %d = getelementptr i32, i32* %base, <vscale x 2 x i32> %idx
144 ret <vscale x 2 x i32*> %d
147 define <vscale x 2 x i64*> @scalable_of_fixed_4_i64(i64* %base, <vscale x 2 x i32> %idx) {
148 ; CHECK-LABEL: scalable_of_fixed_4_i64:
150 ; CHECK-NEXT: mov z1.d, x0
151 ; CHECK-NEXT: adr z0.d, [z1.d, z0.d, sxtw #3]
153 %d = getelementptr i64, i64* %base, <vscale x 2 x i32> %idx
154 ret <vscale x 2 x i64*> %d
157 define <vscale x 2 x i8*> @scalable_of_fixed_5(i8* %base, <vscale x 2 x i32> %idx) {
158 ; CHECK-LABEL: scalable_of_fixed_5:
160 ; CHECK-NEXT: mov z1.d, x0
161 ; CHECK-NEXT: adr z0.d, [z1.d, z0.d, uxtw]
163 %idxZext = zext <vscale x 2 x i32> %idx to <vscale x 2 x i64>
164 %d = getelementptr i8, i8* %base, <vscale x 2 x i64> %idxZext
165 ret <vscale x 2 x i8*> %d
168 define <vscale x 2 x i16*> @scalable_of_fixed_5_i16(i16* %base, <vscale x 2 x i32> %idx) {
169 ; CHECK-LABEL: scalable_of_fixed_5_i16:
171 ; CHECK-NEXT: mov z1.d, x0
172 ; CHECK-NEXT: adr z0.d, [z1.d, z0.d, uxtw #1]
174 %idxZext = zext <vscale x 2 x i32> %idx to <vscale x 2 x i64>
175 %d = getelementptr i16, i16* %base, <vscale x 2 x i64> %idxZext
176 ret <vscale x 2 x i16*> %d
179 define <vscale x 2 x i32*> @scalable_of_fixed_5_i32(i32* %base, <vscale x 2 x i32> %idx) {
180 ; CHECK-LABEL: scalable_of_fixed_5_i32:
182 ; CHECK-NEXT: mov z1.d, x0
183 ; CHECK-NEXT: adr z0.d, [z1.d, z0.d, uxtw #2]
185 %idxZext = zext <vscale x 2 x i32> %idx to <vscale x 2 x i64>
186 %d = getelementptr i32, i32* %base, <vscale x 2 x i64> %idxZext
187 ret <vscale x 2 x i32*> %d
191 define <vscale x 2 x i64*> @scalable_of_fixed_5_i64(i64* %base, <vscale x 2 x i32> %idx) {
192 ; CHECK-LABEL: scalable_of_fixed_5_i64:
194 ; CHECK-NEXT: mov z1.d, x0
195 ; CHECK-NEXT: adr z0.d, [z1.d, z0.d, uxtw #3]
197 %idxZext = zext <vscale x 2 x i32> %idx to <vscale x 2 x i64>
198 %d = getelementptr i64, i64* %base, <vscale x 2 x i64> %idxZext
199 ret <vscale x 2 x i64*> %d
202 define <vscale x 2 x <vscale x 2 x i64>*> @scalable_of_scalable_1(<vscale x 2 x i64>* %base) {
203 ; CHECK-LABEL: scalable_of_scalable_1:
205 ; CHECK-NEXT: addvl x8, x0, #1
206 ; CHECK-NEXT: mov z0.d, x8
208 %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
209 %d = getelementptr <vscale x 2 x i64>, <vscale x 2 x i64>* %base, <vscale x 2 x i64> %idx
210 ret <vscale x 2 x <vscale x 2 x i64>*> %d
213 define <vscale x 2 x <vscale x 2 x i64>*> @scalable_of_scalable_2(<vscale x 2 x <vscale x 2 x i64>*> %base) {
214 ; CHECK-LABEL: scalable_of_scalable_2:
216 ; CHECK-NEXT: incd z0.d, all, mul #8
218 %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
219 %d = getelementptr <vscale x 2 x i64>, <vscale x 2 x <vscale x 2 x i64>*> %base, <vscale x 2 x i64> %idx
220 ret <vscale x 2 x <vscale x 2 x i64>*> %d
223 define <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) {
224 ; CHECK-LABEL: scalable_of_scalable_3:
226 ; CHECK-NEXT: ptrue p0.d
227 ; CHECK-NEXT: rdvl x8, #1
228 ; CHECK-NEXT: mov z2.d, x8
229 ; CHECK-NEXT: sxtw z1.d, p0/m, z1.d
230 ; CHECK-NEXT: mla z0.d, p0/m, z1.d, z2.d
232 %d = getelementptr <vscale x 2 x i64>, <vscale x 2 x <vscale x 2 x i64>*> %base, <vscale x 2 x i32> %idx
233 ret <vscale x 2 x <vscale x 2 x i64>*> %d