Add AArch64 as an experimental target.
[oota-llvm.git] / test / CodeGen / AArch64 / ldst-regoffset.ll
1 ; RUN: llc -verify-machineinstrs < %s -march=aarch64 | FileCheck %s
2
3 @var_8bit = global i8 0
4 @var_16bit = global i16 0
5 @var_32bit = global i32 0
6 @var_64bit = global i64 0
7
8 @var_float = global float 0.0
9 @var_double = global double 0.0
10
11 define void @ldst_8bit(i8* %base, i32 %off32, i64 %off64) {
12 ; CHECK: ldst_8bit:
13
14    %addr8_sxtw = getelementptr i8* %base, i32 %off32
15    %val8_sxtw = load volatile i8* %addr8_sxtw
16    %val32_signed = sext i8 %val8_sxtw to i32
17    store volatile i32 %val32_signed, i32* @var_32bit
18 ; CHECK: ldrsb {{w[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw]
19
20   %addr_lsl = getelementptr i8* %base, i64 %off64
21   %val8_lsl = load volatile i8* %addr_lsl
22   %val32_unsigned = zext i8 %val8_lsl to i32
23   store volatile i32 %val32_unsigned, i32* @var_32bit
24 ; CHECK: ldrb {{w[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}]
25
26   %addrint_uxtw = ptrtoint i8* %base to i64
27   %offset_uxtw = zext i32 %off32 to i64
28   %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw
29   %addr_uxtw = inttoptr i64 %addrint1_uxtw to i8*
30   %val8_uxtw = load volatile i8* %addr_uxtw
31   %newval8 = add i8 %val8_uxtw, 1
32   store volatile i8 %newval8, i8* @var_8bit
33 ; CHECK: ldrb {{w[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw]
34
35    ret void
36 }
37
38
39 define void @ldst_16bit(i16* %base, i32 %off32, i64 %off64) {
40 ; CHECK: ldst_16bit:
41
42    %addr8_sxtwN = getelementptr i16* %base, i32 %off32
43    %val8_sxtwN = load volatile i16* %addr8_sxtwN
44    %val32_signed = sext i16 %val8_sxtwN to i32
45    store volatile i32 %val32_signed, i32* @var_32bit
46 ; CHECK: ldrsh {{w[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw #1]
47
48   %addr_lslN = getelementptr i16* %base, i64 %off64
49   %val8_lslN = load volatile i16* %addr_lslN
50   %val32_unsigned = zext i16 %val8_lslN to i32
51   store volatile i32 %val32_unsigned, i32* @var_32bit
52 ; CHECK: ldrh {{w[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #1]
53
54   %addrint_uxtw = ptrtoint i16* %base to i64
55   %offset_uxtw = zext i32 %off32 to i64
56   %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw
57   %addr_uxtw = inttoptr i64 %addrint1_uxtw to i16*
58   %val8_uxtw = load volatile i16* %addr_uxtw
59   %newval8 = add i16 %val8_uxtw, 1
60   store volatile i16 %newval8, i16* @var_16bit
61 ; CHECK: ldrh {{w[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw]
62
63   %base_sxtw = ptrtoint i16* %base to i64
64   %offset_sxtw = sext i32 %off32 to i64
65   %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw
66   %addr_sxtw = inttoptr i64 %addrint_sxtw to i16*
67   %val16_sxtw = load volatile i16* %addr_sxtw
68   %val64_signed = sext i16 %val16_sxtw to i64
69   store volatile i64 %val64_signed, i64* @var_64bit
70 ; CHECK: ldrsh {{x[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw]
71
72
73   %base_lsl = ptrtoint i16* %base to i64
74   %addrint_lsl = add i64 %base_lsl, %off64
75   %addr_lsl = inttoptr i64 %addrint_lsl to i16*
76   %val16_lsl = load volatile i16* %addr_lsl
77   %val64_unsigned = zext i16 %val16_lsl to i64
78   store volatile i64 %val64_unsigned, i64* @var_64bit
79 ; CHECK: ldrh {{w[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}]
80
81   %base_uxtwN = ptrtoint i16* %base to i64
82   %offset_uxtwN = zext i32 %off32 to i64
83   %offset2_uxtwN = shl i64 %offset_uxtwN, 1
84   %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN
85   %addr_uxtwN = inttoptr i64 %addrint_uxtwN to i16*
86   %val32 = load volatile i32* @var_32bit
87   %val16_trunc32 = trunc i32 %val32 to i16
88   store volatile i16 %val16_trunc32, i16* %addr_uxtwN
89 ; CHECK: strh {{w[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw #1]
90    ret void
91 }
92
93 define void @ldst_32bit(i32* %base, i32 %off32, i64 %off64) {
94 ; CHECK: ldst_32bit:
95
96    %addr_sxtwN = getelementptr i32* %base, i32 %off32
97    %val_sxtwN = load volatile i32* %addr_sxtwN
98    store volatile i32 %val_sxtwN, i32* @var_32bit
99 ; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw #2]
100
101   %addr_lslN = getelementptr i32* %base, i64 %off64
102   %val_lslN = load volatile i32* %addr_lslN
103   store volatile i32 %val_lslN, i32* @var_32bit
104 ; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #2]
105
106   %addrint_uxtw = ptrtoint i32* %base to i64
107   %offset_uxtw = zext i32 %off32 to i64
108   %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw
109   %addr_uxtw = inttoptr i64 %addrint1_uxtw to i32*
110   %val_uxtw = load volatile i32* %addr_uxtw
111   %newval8 = add i32 %val_uxtw, 1
112   store volatile i32 %newval8, i32* @var_32bit
113 ; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw]
114
115
116   %base_sxtw = ptrtoint i32* %base to i64
117   %offset_sxtw = sext i32 %off32 to i64
118   %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw
119   %addr_sxtw = inttoptr i64 %addrint_sxtw to i32*
120   %val16_sxtw = load volatile i32* %addr_sxtw
121   %val64_signed = sext i32 %val16_sxtw to i64
122   store volatile i64 %val64_signed, i64* @var_64bit
123 ; CHECK: ldrsw {{x[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw]
124
125
126   %base_lsl = ptrtoint i32* %base to i64
127   %addrint_lsl = add i64 %base_lsl, %off64
128   %addr_lsl = inttoptr i64 %addrint_lsl to i32*
129   %val16_lsl = load volatile i32* %addr_lsl
130   %val64_unsigned = zext i32 %val16_lsl to i64
131   store volatile i64 %val64_unsigned, i64* @var_64bit
132 ; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}]
133
134   %base_uxtwN = ptrtoint i32* %base to i64
135   %offset_uxtwN = zext i32 %off32 to i64
136   %offset2_uxtwN = shl i64 %offset_uxtwN, 2
137   %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN
138   %addr_uxtwN = inttoptr i64 %addrint_uxtwN to i32*
139   %val32 = load volatile i32* @var_32bit
140   store volatile i32 %val32, i32* %addr_uxtwN
141 ; CHECK: str {{w[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw #2]
142    ret void
143 }
144
145 define void @ldst_64bit(i64* %base, i32 %off32, i64 %off64) {
146 ; CHECK: ldst_64bit:
147
148    %addr_sxtwN = getelementptr i64* %base, i32 %off32
149    %val_sxtwN = load volatile i64* %addr_sxtwN
150    store volatile i64 %val_sxtwN, i64* @var_64bit
151 ; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw #3]
152
153   %addr_lslN = getelementptr i64* %base, i64 %off64
154   %val_lslN = load volatile i64* %addr_lslN
155   store volatile i64 %val_lslN, i64* @var_64bit
156 ; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #3]
157
158   %addrint_uxtw = ptrtoint i64* %base to i64
159   %offset_uxtw = zext i32 %off32 to i64
160   %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw
161   %addr_uxtw = inttoptr i64 %addrint1_uxtw to i64*
162   %val8_uxtw = load volatile i64* %addr_uxtw
163   %newval8 = add i64 %val8_uxtw, 1
164   store volatile i64 %newval8, i64* @var_64bit
165 ; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw]
166
167   %base_sxtw = ptrtoint i64* %base to i64
168   %offset_sxtw = sext i32 %off32 to i64
169   %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw
170   %addr_sxtw = inttoptr i64 %addrint_sxtw to i64*
171   %val64_sxtw = load volatile i64* %addr_sxtw
172   store volatile i64 %val64_sxtw, i64* @var_64bit
173 ; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw]
174
175   %base_lsl = ptrtoint i64* %base to i64
176   %addrint_lsl = add i64 %base_lsl, %off64
177   %addr_lsl = inttoptr i64 %addrint_lsl to i64*
178   %val64_lsl = load volatile i64* %addr_lsl
179   store volatile i64 %val64_lsl, i64* @var_64bit
180 ; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}]
181
182   %base_uxtwN = ptrtoint i64* %base to i64
183   %offset_uxtwN = zext i32 %off32 to i64
184   %offset2_uxtwN = shl i64 %offset_uxtwN, 3
185   %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN
186   %addr_uxtwN = inttoptr i64 %addrint_uxtwN to i64*
187   %val64 = load volatile i64* @var_64bit
188   store volatile i64 %val64, i64* %addr_uxtwN
189 ; CHECK: str {{x[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw #3]
190    ret void
191 }
192
193 define void @ldst_float(float* %base, i32 %off32, i64 %off64) {
194 ; CHECK: ldst_float:
195
196    %addr_sxtwN = getelementptr float* %base, i32 %off32
197    %val_sxtwN = load volatile float* %addr_sxtwN
198    store volatile float %val_sxtwN, float* @var_float
199 ; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw #2]
200
201   %addr_lslN = getelementptr float* %base, i64 %off64
202   %val_lslN = load volatile float* %addr_lslN
203   store volatile float %val_lslN, float* @var_float
204 ; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #2]
205
206   %addrint_uxtw = ptrtoint float* %base to i64
207   %offset_uxtw = zext i32 %off32 to i64
208   %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw
209   %addr_uxtw = inttoptr i64 %addrint1_uxtw to float*
210   %val_uxtw = load volatile float* %addr_uxtw
211   store volatile float %val_uxtw, float* @var_float
212 ; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw]
213
214   %base_sxtw = ptrtoint float* %base to i64
215   %offset_sxtw = sext i32 %off32 to i64
216   %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw
217   %addr_sxtw = inttoptr i64 %addrint_sxtw to float*
218   %val64_sxtw = load volatile float* %addr_sxtw
219   store volatile float %val64_sxtw, float* @var_float
220 ; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw]
221
222   %base_lsl = ptrtoint float* %base to i64
223   %addrint_lsl = add i64 %base_lsl, %off64
224   %addr_lsl = inttoptr i64 %addrint_lsl to float*
225   %val64_lsl = load volatile float* %addr_lsl
226   store volatile float %val64_lsl, float* @var_float
227 ; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}]
228
229   %base_uxtwN = ptrtoint float* %base to i64
230   %offset_uxtwN = zext i32 %off32 to i64
231   %offset2_uxtwN = shl i64 %offset_uxtwN, 2
232   %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN
233   %addr_uxtwN = inttoptr i64 %addrint_uxtwN to float*
234   %val64 = load volatile float* @var_float
235   store volatile float %val64, float* %addr_uxtwN
236 ; CHECK: str {{s[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw #2]
237    ret void
238 }
239
240 define void @ldst_double(double* %base, i32 %off32, i64 %off64) {
241 ; CHECK: ldst_double:
242
243    %addr_sxtwN = getelementptr double* %base, i32 %off32
244    %val_sxtwN = load volatile double* %addr_sxtwN
245    store volatile double %val_sxtwN, double* @var_double
246 ; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw #3]
247
248   %addr_lslN = getelementptr double* %base, i64 %off64
249   %val_lslN = load volatile double* %addr_lslN
250   store volatile double %val_lslN, double* @var_double
251 ; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #3]
252
253   %addrint_uxtw = ptrtoint double* %base to i64
254   %offset_uxtw = zext i32 %off32 to i64
255   %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw
256   %addr_uxtw = inttoptr i64 %addrint1_uxtw to double*
257   %val_uxtw = load volatile double* %addr_uxtw
258   store volatile double %val_uxtw, double* @var_double
259 ; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw]
260
261   %base_sxtw = ptrtoint double* %base to i64
262   %offset_sxtw = sext i32 %off32 to i64
263   %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw
264   %addr_sxtw = inttoptr i64 %addrint_sxtw to double*
265   %val64_sxtw = load volatile double* %addr_sxtw
266   store volatile double %val64_sxtw, double* @var_double
267 ; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw]
268
269   %base_lsl = ptrtoint double* %base to i64
270   %addrint_lsl = add i64 %base_lsl, %off64
271   %addr_lsl = inttoptr i64 %addrint_lsl to double*
272   %val64_lsl = load volatile double* %addr_lsl
273   store volatile double %val64_lsl, double* @var_double
274 ; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}]
275
276   %base_uxtwN = ptrtoint double* %base to i64
277   %offset_uxtwN = zext i32 %off32 to i64
278   %offset2_uxtwN = shl i64 %offset_uxtwN, 3
279   %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN
280   %addr_uxtwN = inttoptr i64 %addrint_uxtwN to double*
281   %val64 = load volatile double* @var_double
282   store volatile double %val64, double* %addr_uxtwN
283 ; CHECK: str {{d[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw #3]
284    ret void
285 }
286
287
288 define void @ldst_128bit(fp128* %base, i32 %off32, i64 %off64) {
289 ; CHECK: ldst_128bit:
290
291    %addr_sxtwN = getelementptr fp128* %base, i32 %off32
292    %val_sxtwN = load volatile fp128* %addr_sxtwN
293    store volatile fp128 %val_sxtwN, fp128* %base
294 ; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw #4]
295
296   %addr_lslN = getelementptr fp128* %base, i64 %off64
297   %val_lslN = load volatile fp128* %addr_lslN
298   store volatile fp128 %val_lslN, fp128* %base
299 ; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #4]
300
301   %addrint_uxtw = ptrtoint fp128* %base to i64
302   %offset_uxtw = zext i32 %off32 to i64
303   %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw
304   %addr_uxtw = inttoptr i64 %addrint1_uxtw to fp128*
305   %val_uxtw = load volatile fp128* %addr_uxtw
306   store volatile fp128 %val_uxtw, fp128* %base
307 ; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw]
308
309   %base_sxtw = ptrtoint fp128* %base to i64
310   %offset_sxtw = sext i32 %off32 to i64
311   %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw
312   %addr_sxtw = inttoptr i64 %addrint_sxtw to fp128*
313   %val64_sxtw = load volatile fp128* %addr_sxtw
314   store volatile fp128 %val64_sxtw, fp128* %base
315 ; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw]
316
317   %base_lsl = ptrtoint fp128* %base to i64
318   %addrint_lsl = add i64 %base_lsl, %off64
319   %addr_lsl = inttoptr i64 %addrint_lsl to fp128*
320   %val64_lsl = load volatile fp128* %addr_lsl
321   store volatile fp128 %val64_lsl, fp128* %base
322 ; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}]
323
324   %base_uxtwN = ptrtoint fp128* %base to i64
325   %offset_uxtwN = zext i32 %off32 to i64
326   %offset2_uxtwN = shl i64 %offset_uxtwN, 4
327   %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN
328   %addr_uxtwN = inttoptr i64 %addrint_uxtwN to fp128*
329   %val64 = load volatile fp128* %base
330   store volatile fp128 %val64, fp128* %addr_uxtwN
331 ; CHECK: str {{q[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw #4]
332    ret void
333 }