xref: /llvm-project/llvm/test/CodeGen/AArch64/sve-gep.ll (revision 1ee315ae7964c8433b772e0b5d667834994ba753)
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
3
4define ptr @scalar_of_scalable_1(ptr %base) {
5; CHECK-LABEL: scalar_of_scalable_1:
6; CHECK:       // %bb.0:
7; CHECK-NEXT:    rdvl x8, #4
8; CHECK-NEXT:    add x0, x0, x8
9; CHECK-NEXT:    ret
10  %d = getelementptr <vscale x 2 x i64>, ptr %base, i64 4
11  ret ptr %d
12}
13
14define ptr @scalar_of_scalable_2(ptr %base, i64 %offset) {
15; CHECK-LABEL: scalar_of_scalable_2:
16; CHECK:       // %bb.0:
17; CHECK-NEXT:    rdvl x8, #1
18; CHECK-NEXT:    madd x0, x1, x8, x0
19; CHECK-NEXT:    ret
20  %d = getelementptr <vscale x 2 x i64>, ptr %base, i64 %offset
21  ret ptr %d
22}
23
24define ptr @scalar_of_scalable_3(ptr %base, i64 %offset) {
25; CHECK-LABEL: scalar_of_scalable_3:
26; CHECK:       // %bb.0:
27; CHECK-NEXT:    cnth x8
28; CHECK-NEXT:    madd x0, x1, x8, x0
29; CHECK-NEXT:    ret
30  %d = getelementptr <vscale x 2 x i32>, ptr %base, i64 %offset
31  ret ptr %d
32}
33
34define <2 x ptr> @fixed_of_scalable_1(ptr %base) {
35; CHECK-LABEL: fixed_of_scalable_1:
36; CHECK:       // %bb.0:
37; CHECK-NEXT:    rdvl x8, #1
38; CHECK-NEXT:    dup v1.2d, x0
39; CHECK-NEXT:    dup v0.2d, x8
40; CHECK-NEXT:    add v0.2d, v1.2d, v0.2d
41; CHECK-NEXT:    ret
42  %d = getelementptr <vscale x 2 x i64>, ptr %base, <2 x i64> <i64 1, i64 1>
43  ret <2 x ptr> %d
44}
45
46define <2 x ptr> @fixed_of_scalable_2(<2 x ptr> %base) {
47; CHECK-LABEL: fixed_of_scalable_2:
48; CHECK:       // %bb.0:
49; CHECK-NEXT:    rdvl x8, #1
50; CHECK-NEXT:    dup v1.2d, x8
51; CHECK-NEXT:    add v0.2d, v0.2d, v1.2d
52; CHECK-NEXT:    ret
53  %d = getelementptr <vscale x 2 x i64>, <2 x ptr> %base, <2 x i64> <i64 1, i64 1>
54  ret <2 x ptr> %d
55}
56
57define <vscale x 2 x ptr> @scalable_of_fixed_1(ptr %base) {
58; CHECK-LABEL: scalable_of_fixed_1:
59; CHECK:       // %bb.0:
60; CHECK-NEXT:    add x8, x0, #1
61; CHECK-NEXT:    mov z0.d, x8
62; CHECK-NEXT:    ret
63  %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
64  %d = getelementptr i8, ptr %base, <vscale x 2 x i64> %idx
65  ret <vscale x 2 x ptr> %d
66}
67
68define <vscale x 2 x ptr> @scalable_of_fixed_2(<vscale x 2 x ptr> %base) {
69; CHECK-LABEL: scalable_of_fixed_2:
70; CHECK:       // %bb.0:
71; CHECK-NEXT:    add z0.d, z0.d, #1 // =0x1
72; CHECK-NEXT:    ret
73  %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
74  %d = getelementptr i8, <vscale x 2 x ptr> %base, <vscale x 2 x i64> %idx
75  ret <vscale x 2 x ptr> %d
76}
77
78define <vscale x 2 x ptr> @scalable_of_fixed_3_i8(ptr %base, <vscale x 2 x i64> %idx) {
79; CHECK-LABEL: scalable_of_fixed_3_i8:
80; CHECK:       // %bb.0:
81; CHECK-NEXT:    mov z1.d, x0
82; CHECK-NEXT:    add z0.d, z1.d, z0.d
83; CHECK-NEXT:    ret
84  %d = getelementptr i8, ptr %base, <vscale x 2 x i64> %idx
85  ret <vscale x 2 x ptr> %d
86}
87
88define <vscale x 2 x ptr> @scalable_of_fixed_3_i16(ptr %base, <vscale x 2 x i64> %idx) {
89; CHECK-LABEL: scalable_of_fixed_3_i16:
90; CHECK:       // %bb.0:
91; CHECK-NEXT:    mov z1.d, x0
92; CHECK-NEXT:    adr z0.d, [z1.d, z0.d, lsl #1]
93; CHECK-NEXT:    ret
94  %d = getelementptr i16, ptr %base, <vscale x 2 x i64> %idx
95  ret <vscale x 2 x ptr> %d
96}
97
98define <vscale x 2 x ptr> @scalable_of_fixed_3_i32(ptr %base, <vscale x 2 x i64> %idx) {
99; CHECK-LABEL: scalable_of_fixed_3_i32:
100; CHECK:       // %bb.0:
101; CHECK-NEXT:    mov z1.d, x0
102; CHECK-NEXT:    adr z0.d, [z1.d, z0.d, lsl #2]
103; CHECK-NEXT:    ret
104  %d = getelementptr i32, ptr %base, <vscale x 2 x i64> %idx
105  ret <vscale x 2 x ptr> %d
106}
107
108define <vscale x 2 x ptr> @scalable_of_fixed_3_i64(ptr %base, <vscale x 2 x i64> %idx) {
109; CHECK-LABEL: scalable_of_fixed_3_i64:
110; CHECK:       // %bb.0:
111; CHECK-NEXT:    mov z1.d, x0
112; CHECK-NEXT:    adr z0.d, [z1.d, z0.d, lsl #3]
113; CHECK-NEXT:    ret
114  %d = getelementptr i64, ptr %base, <vscale x 2 x i64> %idx
115  ret <vscale x 2 x ptr> %d
116}
117
118define <vscale x 2 x ptr> @scalable_of_fixed_4_i8(ptr %base, <vscale x 2 x i32> %idx) {
119; CHECK-LABEL: scalable_of_fixed_4_i8:
120; CHECK:       // %bb.0:
121; CHECK-NEXT:    mov z1.d, x0
122; CHECK-NEXT:    adr z0.d, [z1.d, z0.d, sxtw]
123; CHECK-NEXT:    ret
124  %d = getelementptr i8, ptr %base, <vscale x 2 x i32> %idx
125  ret <vscale x 2 x ptr> %d
126}
127
128define <vscale x 2 x ptr> @scalable_of_fixed_4_i16(ptr %base, <vscale x 2 x i32> %idx) {
129; CHECK-LABEL: scalable_of_fixed_4_i16:
130; CHECK:       // %bb.0:
131; CHECK-NEXT:    mov z1.d, x0
132; CHECK-NEXT:    adr z0.d, [z1.d, z0.d, sxtw #1]
133; CHECK-NEXT:    ret
134  %d = getelementptr i16, ptr %base, <vscale x 2 x i32> %idx
135  ret <vscale x 2 x ptr> %d
136}
137
138define <vscale x 2 x ptr> @scalable_of_fixed_4_i32(ptr %base, <vscale x 2 x i32> %idx) {
139; CHECK-LABEL: scalable_of_fixed_4_i32:
140; CHECK:       // %bb.0:
141; CHECK-NEXT:    mov z1.d, x0
142; CHECK-NEXT:    adr z0.d, [z1.d, z0.d, sxtw #2]
143; CHECK-NEXT:    ret
144  %d = getelementptr i32, ptr %base, <vscale x 2 x i32> %idx
145  ret <vscale x 2 x ptr> %d
146}
147
148define <vscale x 2 x ptr> @scalable_of_fixed_4_i64(ptr %base, <vscale x 2 x i32> %idx) {
149; CHECK-LABEL: scalable_of_fixed_4_i64:
150; CHECK:       // %bb.0:
151; CHECK-NEXT:    mov z1.d, x0
152; CHECK-NEXT:    adr z0.d, [z1.d, z0.d, sxtw #3]
153; CHECK-NEXT:    ret
154  %d = getelementptr i64, ptr %base, <vscale x 2 x i32> %idx
155  ret <vscale x 2 x ptr> %d
156}
157
158define <vscale x 2 x ptr> @scalable_of_fixed_5(ptr %base, <vscale x 2 x i32> %idx) {
159; CHECK-LABEL: scalable_of_fixed_5:
160; CHECK:       // %bb.0:
161; CHECK-NEXT:    mov z1.d, x0
162; CHECK-NEXT:    adr z0.d, [z1.d, z0.d, uxtw]
163; CHECK-NEXT:    ret
164  %idxZext = zext <vscale x 2 x i32> %idx to <vscale x 2 x i64>
165  %d = getelementptr i8, ptr %base, <vscale x 2 x i64> %idxZext
166  ret <vscale x 2 x ptr> %d
167}
168
169define <vscale x 2 x ptr> @scalable_of_fixed_5_i16(ptr %base, <vscale x 2 x i32> %idx) {
170; CHECK-LABEL: scalable_of_fixed_5_i16:
171; CHECK:       // %bb.0:
172; CHECK-NEXT:    mov z1.d, x0
173; CHECK-NEXT:    adr z0.d, [z1.d, z0.d, uxtw #1]
174; CHECK-NEXT:    ret
175  %idxZext = zext <vscale x 2 x i32> %idx to <vscale x 2 x i64>
176  %d = getelementptr i16, ptr %base, <vscale x 2 x i64> %idxZext
177  ret <vscale x 2 x ptr> %d
178}
179
180define <vscale x 2 x ptr> @scalable_of_fixed_5_i32(ptr %base, <vscale x 2 x i32> %idx) {
181; CHECK-LABEL: scalable_of_fixed_5_i32:
182; CHECK:       // %bb.0:
183; CHECK-NEXT:    mov z1.d, x0
184; CHECK-NEXT:    adr z0.d, [z1.d, z0.d, uxtw #2]
185; CHECK-NEXT:    ret
186  %idxZext = zext <vscale x 2 x i32> %idx to <vscale x 2 x i64>
187  %d = getelementptr i32, ptr %base, <vscale x 2 x i64> %idxZext
188  ret <vscale x 2 x ptr> %d
189}
190
191
192define <vscale x 2 x ptr> @scalable_of_fixed_5_i64(ptr %base, <vscale x 2 x i32> %idx) {
193; CHECK-LABEL: scalable_of_fixed_5_i64:
194; CHECK:       // %bb.0:
195; CHECK-NEXT:    mov z1.d, x0
196; CHECK-NEXT:    adr z0.d, [z1.d, z0.d, uxtw #3]
197; CHECK-NEXT:    ret
198  %idxZext = zext <vscale x 2 x i32> %idx to <vscale x 2 x i64>
199  %d = getelementptr i64, ptr %base, <vscale x 2 x i64> %idxZext
200  ret <vscale x 2 x ptr> %d
201}
202
203define <vscale x 2 x ptr> @scalable_of_scalable_1(ptr %base) {
204; CHECK-LABEL: scalable_of_scalable_1:
205; CHECK:       // %bb.0:
206; CHECK-NEXT:    rdvl x8, #1
207; CHECK-NEXT:    add x8, x0, x8
208; CHECK-NEXT:    mov z0.d, x8
209; CHECK-NEXT:    ret
210  %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
211  %d = getelementptr <vscale x 2 x i64>, ptr %base, <vscale x 2 x i64> %idx
212  ret <vscale x 2 x ptr> %d
213}
214
215define <vscale x 2 x ptr> @scalable_of_scalable_2(<vscale x 2 x ptr> %base) {
216; CHECK-LABEL: scalable_of_scalable_2:
217; CHECK:       // %bb.0:
218; CHECK-NEXT:    incd z0.d, all, mul #8
219; CHECK-NEXT:    ret
220  %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
221  %d = getelementptr <vscale x 2 x i64>, <vscale x 2 x ptr> %base, <vscale x 2 x i64> %idx
222  ret <vscale x 2 x ptr> %d
223}
224
225define <vscale x 2 x ptr> @scalable_of_scalable_3(<vscale x 2 x ptr> %base, <vscale x 2 x i32> %idx) {
226; CHECK-LABEL: scalable_of_scalable_3:
227; CHECK:       // %bb.0:
228; CHECK-NEXT:    ptrue p0.d
229; CHECK-NEXT:    rdvl x8, #1
230; CHECK-NEXT:    mov z2.d, x8
231; CHECK-NEXT:    sxtw z1.d, p0/m, z1.d
232; CHECK-NEXT:    mla z0.d, p0/m, z1.d, z2.d
233; CHECK-NEXT:    ret
234  %d = getelementptr <vscale x 2 x i64>, <vscale x 2 x ptr> %base, <vscale x 2 x i32> %idx
235  ret <vscale x 2 x ptr> %d
236}
237