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