[AArch64] Promote loads from stores
[oota-llvm.git] / test / CodeGen / AArch64 / arm64-ld-from-st.ll
1 ; RUN: llc < %s -mtriple aarch64--none-eabi -verify-machineinstrs | FileCheck %s
2
3 ; CHECK-LABEL: Str64Ldr64
4 ; CHECK: mov x0, x1
5 define i64 @Str64Ldr64(i64* nocapture %P, i64 %v, i64 %n) {
6 entry:
7   %0 = bitcast i64* %P to i64*
8   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 1
9   store i64 %v, i64* %arrayidx0
10   %arrayidx1 = getelementptr inbounds i64, i64* %0, i64 1
11   %1 = load i64, i64* %arrayidx1
12   ret i64 %1
13 }
14
15 ; CHECK-LABEL: Str64Ldr32_0
16 ; CHECK: and x0, x1, #0xffffffff
17 define i32 @Str64Ldr32_0(i64* nocapture %P, i64 %v, i64 %n) {
18 entry:
19   %0 = bitcast i64* %P to i32*
20   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 1
21   store i64 %v, i64* %arrayidx0
22   %arrayidx1 = getelementptr inbounds i32, i32* %0, i64 2
23   %1 = load i32, i32* %arrayidx1
24   ret i32 %1
25 }
26
27 ; CHECK-LABEL: Str64Ldr32_1
28 ; CHECK: lsr x0, x1, #32
29 define i32 @Str64Ldr32_1(i64* nocapture %P, i64 %v, i64 %n) {
30 entry:
31   %0 = bitcast i64* %P to i32*
32   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 1
33   store i64 %v, i64* %arrayidx0
34   %arrayidx1 = getelementptr inbounds i32, i32* %0, i64 3
35   %1 = load i32, i32* %arrayidx1
36   ret i32 %1
37 }
38
39 ; CHECK-LABEL: Str64Ldr16_0
40 ; CHECK: and x0, x1, #0xffff
41 define i16 @Str64Ldr16_0(i64* nocapture %P, i64 %v, i64 %n) {
42 entry:
43   %0 = bitcast i64* %P to i16*
44   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 1
45   store i64 %v, i64* %arrayidx0
46   %arrayidx1 = getelementptr inbounds i16, i16* %0, i64 4
47   %1 = load i16, i16* %arrayidx1
48   ret i16 %1
49 }
50
51 ; CHECK-LABEL: Str64Ldr16_1
52 ; CHECK: ubfx x0, x1, #16, #16
53 define i16 @Str64Ldr16_1(i64* nocapture %P, i64 %v, i64 %n) {
54 entry:
55   %0 = bitcast i64* %P to i16*
56   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 1
57   store i64 %v, i64* %arrayidx0
58   %arrayidx1 = getelementptr inbounds i16, i16* %0, i64 5
59   %1 = load i16, i16* %arrayidx1
60   ret i16 %1
61 }
62
63 ; CHECK-LABEL: Str64Ldr16_2
64 ; CHECK: ubfx x0, x1, #32, #16
65 define i16 @Str64Ldr16_2(i64* nocapture %P, i64 %v, i64 %n) {
66 entry:
67   %0 = bitcast i64* %P to i16*
68   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 1
69   store i64 %v, i64* %arrayidx0
70   %arrayidx1 = getelementptr inbounds i16, i16* %0, i64 6
71   %1 = load i16, i16* %arrayidx1
72   ret i16 %1
73 }
74
75 ; CHECK-LABEL: Str64Ldr16_3
76 ; CHECK: lsr x0, x1, #48
77 define i16 @Str64Ldr16_3(i64* nocapture %P, i64 %v, i64 %n) {
78 entry:
79   %0 = bitcast i64* %P to i16*
80   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 1
81   store i64 %v, i64* %arrayidx0
82   %arrayidx1 = getelementptr inbounds i16, i16* %0, i64 7
83   %1 = load i16, i16* %arrayidx1
84   ret i16 %1
85 }
86
87 ; CHECK-LABEL: Str64Ldr8_0
88 ; CHECK: and x0, x1, #0xff
89 define i8 @Str64Ldr8_0(i64* nocapture %P, i64 %v, i64 %n) {
90 entry:
91   %0 = bitcast i64* %P to i8*
92   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 1
93   store i64 %v, i64* %arrayidx0
94   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 8
95   %1 = load i8, i8* %arrayidx1
96   ret i8 %1
97 }
98
99 ; CHECK-LABEL: Str64Ldr8_1
100 ; CHECK: ubfx x0, x1, #8, #8
101 define i8 @Str64Ldr8_1(i64* nocapture %P, i64 %v, i64 %n) {
102 entry:
103   %0 = bitcast i64* %P to i8*
104   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 1
105   store i64 %v, i64* %arrayidx0
106   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 9
107   %1 = load i8, i8* %arrayidx1
108   ret i8 %1
109 }
110
111 ; CHECK-LABEL: Str64Ldr8_2
112 ; CHECK: ubfx x0, x1, #16, #8
113 define i8 @Str64Ldr8_2(i64* nocapture %P, i64 %v, i64 %n) {
114 entry:
115   %0 = bitcast i64* %P to i8*
116   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 1
117   store i64 %v, i64* %arrayidx0
118   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 10
119   %1 = load i8, i8* %arrayidx1
120   ret i8 %1
121 }
122
123 ; CHECK-LABEL: Str64Ldr8_3
124 ; CHECK: ubfx x0, x1, #24, #8
125 define i8 @Str64Ldr8_3(i64* nocapture %P, i64 %v, i64 %n) {
126 entry:
127   %0 = bitcast i64* %P to i8*
128   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 1
129   store i64 %v, i64* %arrayidx0
130   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 11
131   %1 = load i8, i8* %arrayidx1
132   ret i8 %1
133 }
134
135 ; CHECK-LABEL: Str64Ldr8_4
136 ; CHECK: ubfx x0, x1, #32, #8
137 define i8 @Str64Ldr8_4(i64* nocapture %P, i64 %v, i64 %n) {
138 entry:
139   %0 = bitcast i64* %P to i8*
140   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 1
141   store i64 %v, i64* %arrayidx0
142   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 12
143   %1 = load i8, i8* %arrayidx1
144   ret i8 %1
145 }
146
147 ; CHECK-LABEL: Str64Ldr8_5
148 ; CHECK: ubfx x0, x1, #40, #8
149 define i8 @Str64Ldr8_5(i64* nocapture %P, i64 %v, i64 %n) {
150 entry:
151   %0 = bitcast i64* %P to i8*
152   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 1
153   store i64 %v, i64* %arrayidx0
154   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 13
155   %1 = load i8, i8* %arrayidx1
156   ret i8 %1
157 }
158
159 ; CHECK-LABEL: Str64Ldr8_6
160 ; CHECK: ubfx x0, x1, #48, #8
161 define i8 @Str64Ldr8_6(i64* nocapture %P, i64 %v, i64 %n) {
162 entry:
163   %0 = bitcast i64* %P to i8*
164   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 1
165   store i64 %v, i64* %arrayidx0
166   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 14
167   %1 = load i8, i8* %arrayidx1
168   ret i8 %1
169 }
170
171 ; CHECK-LABEL: Str64Ldr8_7
172 ; CHECK: lsr x0, x1, #56
173 define i8 @Str64Ldr8_7(i64* nocapture %P, i64 %v, i64 %n) {
174 entry:
175   %0 = bitcast i64* %P to i8*
176   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 1
177   store i64 %v, i64* %arrayidx0
178   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 15
179   %1 = load i8, i8* %arrayidx1
180   ret i8 %1
181 }
182
183 ; CHECK-LABEL: Str32Ldr32
184 ; CHECK: mov w0, w1
185 define i32 @Str32Ldr32(i32* nocapture %P, i32 %v, i64 %n) {
186 entry:
187   %0 = bitcast i32* %P to i32*
188   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
189   store i32 %v, i32* %arrayidx0
190   %arrayidx1 = getelementptr inbounds i32, i32* %0, i64 1
191   %1 = load i32, i32* %arrayidx1
192   ret i32 %1
193 }
194
195 ; CHECK-LABEL: Str32Ldr16_0
196 ; CHECK: and w0, w1, #0xffff
197 define i16 @Str32Ldr16_0(i32* nocapture %P, i32 %v, i64 %n) {
198 entry:
199   %0 = bitcast i32* %P to i16*
200   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
201   store i32 %v, i32* %arrayidx0
202   %arrayidx1 = getelementptr inbounds i16, i16* %0, i64 2
203   %1 = load i16, i16* %arrayidx1
204   ret i16 %1
205 }
206
207 ; CHECK-LABEL: Str32Ldr16_1
208 ; CHECK: lsr    w0, w1, #16
209 define i16 @Str32Ldr16_1(i32* nocapture %P, i32 %v, i64 %n) {
210 entry:
211   %0 = bitcast i32* %P to i16*
212   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
213   store i32 %v, i32* %arrayidx0
214   %arrayidx1 = getelementptr inbounds i16, i16* %0, i64 3
215   %1 = load i16, i16* %arrayidx1
216   ret i16 %1
217 }
218
219 ; CHECK-LABEL: Str32Ldr8_0
220 ; CHECK: and w0, w1, #0xff
221 define i8 @Str32Ldr8_0(i32* nocapture %P, i32 %v, i64 %n) {
222 entry:
223   %0 = bitcast i32* %P to i8*
224   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
225   store i32 %v, i32* %arrayidx0
226   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 4
227   %1 = load i8, i8* %arrayidx1
228   ret i8 %1
229 }
230
231 ; CHECK-LABEL: Str32Ldr8_1
232 ; CHECK: ubfx w0, w1, #8, #8
233 define i8 @Str32Ldr8_1(i32* nocapture %P, i32 %v, i64 %n) {
234 entry:
235   %0 = bitcast i32* %P to i8*
236   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
237   store i32 %v, i32* %arrayidx0
238   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 5
239   %1 = load i8, i8* %arrayidx1
240   ret i8 %1
241 }
242
243 ; CHECK-LABEL: Str32Ldr8_2
244 ; CHECK: ubfx w0, w1, #16, #8
245 define i8 @Str32Ldr8_2(i32* nocapture %P, i32 %v, i64 %n) {
246 entry:
247   %0 = bitcast i32* %P to i8*
248   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
249   store i32 %v, i32* %arrayidx0
250   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 6
251   %1 = load i8, i8* %arrayidx1
252   ret i8 %1
253 }
254
255 ; CHECK-LABEL: Str32Ldr8_3
256 ; CHECK: lsr w0, w1, #24
257 define i8 @Str32Ldr8_3(i32* nocapture %P, i32 %v, i64 %n) {
258 entry:
259   %0 = bitcast i32* %P to i8*
260   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
261   store i32 %v, i32* %arrayidx0
262   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 7
263   %1 = load i8, i8* %arrayidx1
264   ret i8 %1
265 }
266
267 ; CHECK-LABEL: Str16Ldr16
268 ; CHECK: mov w0, w1
269 define i16 @Str16Ldr16(i16* nocapture %P, i16 %v, i64 %n) {
270 entry:
271   %0 = bitcast i16* %P to i16*
272   %arrayidx0 = getelementptr inbounds i16, i16* %P, i64 1
273   store i16 %v, i16* %arrayidx0
274   %arrayidx1 = getelementptr inbounds i16, i16* %0, i64 1
275   %1 = load i16, i16* %arrayidx1
276   ret i16 %1
277 }
278
279 ; CHECK-LABEL: Str16Ldr8_0
280 ; CHECK: and w0, w1, #0xff
281 define i8 @Str16Ldr8_0(i16* nocapture %P, i16 %v, i64 %n) {
282 entry:
283   %0 = bitcast i16* %P to i8*
284   %arrayidx0 = getelementptr inbounds i16, i16* %P, i64 1
285   store i16 %v, i16* %arrayidx0
286   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 2
287   %1 = load i8, i8* %arrayidx1
288   ret i8 %1
289 }
290
291 ; CHECK-LABEL: Str16Ldr8_1
292 ; CHECK: ubfx w0, w1, #8, #8
293 define i8 @Str16Ldr8_1(i16* nocapture %P, i16 %v, i64 %n) {
294 entry:
295   %0 = bitcast i16* %P to i8*
296   %arrayidx0 = getelementptr inbounds i16, i16* %P, i64 1
297   store i16 %v, i16* %arrayidx0
298   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 3
299   %1 = load i8, i8* %arrayidx1
300   ret i8 %1
301 }
302
303
304 ; CHECK-LABEL: Unscaled_Str64Ldr64
305 ; CHECK: mov x0, x1
306 define i64 @Unscaled_Str64Ldr64(i64* nocapture %P, i64 %v, i64 %n) {
307 entry:
308   %0 = bitcast i64* %P to i64*
309   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 -1
310   store i64 %v, i64* %arrayidx0
311   %arrayidx1 = getelementptr inbounds i64, i64* %0, i64 -1
312   %1 = load i64, i64* %arrayidx1
313   ret i64 %1
314 }
315
316 ; CHECK-LABEL: Unscaled_Str64Ldr32_0
317 ; CHECK: and x0, x1, #0xffffffff
318 define i32 @Unscaled_Str64Ldr32_0(i64* nocapture %P, i64 %v, i64 %n) {
319 entry:
320   %0 = bitcast i64* %P to i32*
321   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 -1
322   store i64 %v, i64* %arrayidx0
323   %arrayidx1 = getelementptr inbounds i32, i32* %0, i64 -2
324   %1 = load i32, i32* %arrayidx1
325   ret i32 %1
326 }
327
328 ; CHECK-LABEL: Unscaled_Str64Ldr32_1
329 ; CHECK: lsr x0, x1, #32
330 define i32 @Unscaled_Str64Ldr32_1(i64* nocapture %P, i64 %v, i64 %n) {
331 entry:
332   %0 = bitcast i64* %P to i32*
333   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 -1
334   store i64 %v, i64* %arrayidx0
335   %arrayidx1 = getelementptr inbounds i32, i32* %0, i64 -1
336   %1 = load i32, i32* %arrayidx1
337   ret i32 %1
338 }
339
340 ; CHECK-LABEL: Unscaled_Str64Ldr16_0
341 ; CHECK: and x0, x1, #0xffff
342 define i16 @Unscaled_Str64Ldr16_0(i64* nocapture %P, i64 %v, i64 %n) {
343 entry:
344   %0 = bitcast i64* %P to i16*
345   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 -1
346   store i64 %v, i64* %arrayidx0
347   %arrayidx1 = getelementptr inbounds i16, i16* %0, i64 -4
348   %1 = load i16, i16* %arrayidx1
349   ret i16 %1
350 }
351
352 ; CHECK-LABEL: Unscaled_Str64Ldr16_1
353 ; CHECK: ubfx x0, x1, #16, #16
354 define i16 @Unscaled_Str64Ldr16_1(i64* nocapture %P, i64 %v, i64 %n) {
355 entry:
356   %0 = bitcast i64* %P to i16*
357   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 -1
358   store i64 %v, i64* %arrayidx0
359   %arrayidx1 = getelementptr inbounds i16, i16* %0, i64 -3
360   %1 = load i16, i16* %arrayidx1
361   ret i16 %1
362 }
363
364 ; CHECK-LABEL: Unscaled_Str64Ldr16_2
365 ; CHECK: ubfx x0, x1, #32, #16
366 define i16 @Unscaled_Str64Ldr16_2(i64* nocapture %P, i64 %v, i64 %n) {
367 entry:
368   %0 = bitcast i64* %P to i16*
369   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 -1
370   store i64 %v, i64* %arrayidx0
371   %arrayidx1 = getelementptr inbounds i16, i16* %0, i64 -2
372   %1 = load i16, i16* %arrayidx1
373   ret i16 %1
374 }
375
376 ; CHECK-LABEL: Unscaled_Str64Ldr16_3
377 ; CHECK: lsr x0, x1, #48
378 define i16 @Unscaled_Str64Ldr16_3(i64* nocapture %P, i64 %v, i64 %n) {
379 entry:
380   %0 = bitcast i64* %P to i16*
381   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 -1
382   store i64 %v, i64* %arrayidx0
383   %arrayidx1 = getelementptr inbounds i16, i16* %0, i64 -1
384   %1 = load i16, i16* %arrayidx1
385   ret i16 %1
386 }
387
388 ; CHECK-LABEL: Unscaled_Str64Ldr8_0
389 ; CHECK: and x0, x1, #0xff
390 define i8 @Unscaled_Str64Ldr8_0(i64* nocapture %P, i64 %v, i64 %n) {
391 entry:
392   %0 = bitcast i64* %P to i8*
393   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 -1
394   store i64 %v, i64* %arrayidx0
395   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 -8
396   %1 = load i8, i8* %arrayidx1
397   ret i8 %1
398 }
399
400 ; CHECK-LABEL: Unscaled_Str64Ldr8_1
401 ; CHECK: ubfx x0, x1, #8, #8
402 define i8 @Unscaled_Str64Ldr8_1(i64* nocapture %P, i64 %v, i64 %n) {
403 entry:
404   %0 = bitcast i64* %P to i8*
405   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 -1
406   store i64 %v, i64* %arrayidx0
407   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 -7
408   %1 = load i8, i8* %arrayidx1
409   ret i8 %1
410 }
411
412 ; CHECK-LABEL: Unscaled_Str64Ldr8_2
413 ; CHECK: ubfx x0, x1, #16, #8
414 define i8 @Unscaled_Str64Ldr8_2(i64* nocapture %P, i64 %v, i64 %n) {
415 entry:
416   %0 = bitcast i64* %P to i8*
417   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 -1
418   store i64 %v, i64* %arrayidx0
419   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 -6
420   %1 = load i8, i8* %arrayidx1
421   ret i8 %1
422 }
423
424 ; CHECK-LABEL: Unscaled_Str64Ldr8_3
425 ; CHECK: ubfx x0, x1, #24, #8
426 define i8 @Unscaled_Str64Ldr8_3(i64* nocapture %P, i64 %v, i64 %n) {
427 entry:
428   %0 = bitcast i64* %P to i8*
429   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 -1
430   store i64 %v, i64* %arrayidx0
431   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 -5
432   %1 = load i8, i8* %arrayidx1
433   ret i8 %1
434 }
435
436 ; CHECK-LABEL: Unscaled_Str64Ldr8_4
437 ; CHECK: ubfx x0, x1, #32, #8
438 define i8 @Unscaled_Str64Ldr8_4(i64* nocapture %P, i64 %v, i64 %n) {
439 entry:
440   %0 = bitcast i64* %P to i8*
441   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 -1
442   store i64 %v, i64* %arrayidx0
443   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 -4
444   %1 = load i8, i8* %arrayidx1
445   ret i8 %1
446 }
447
448 ; CHECK-LABEL: Unscaled_Str64Ldr8_5
449 ; CHECK: ubfx x0, x1, #40, #8
450 define i8 @Unscaled_Str64Ldr8_5(i64* nocapture %P, i64 %v, i64 %n) {
451 entry:
452   %0 = bitcast i64* %P to i8*
453   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 -1
454   store i64 %v, i64* %arrayidx0
455   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 -3
456   %1 = load i8, i8* %arrayidx1
457   ret i8 %1
458 }
459
460 ; CHECK-LABEL: Unscaled_Str64Ldr8_6
461 ; CHECK: ubfx x0, x1, #48, #8
462 define i8 @Unscaled_Str64Ldr8_6(i64* nocapture %P, i64 %v, i64 %n) {
463 entry:
464   %0 = bitcast i64* %P to i8*
465   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 -1
466   store i64 %v, i64* %arrayidx0
467   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 -2
468   %1 = load i8, i8* %arrayidx1
469   ret i8 %1
470 }
471
472 ; CHECK-LABEL: Unscaled_Str64Ldr8_7
473 ; CHECK: lsr x0, x1, #56
474 define i8 @Unscaled_Str64Ldr8_7(i64* nocapture %P, i64 %v, i64 %n) {
475 entry:
476   %0 = bitcast i64* %P to i8*
477   %arrayidx0 = getelementptr inbounds i64, i64* %P, i64 -1
478   store i64 %v, i64* %arrayidx0
479   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 -1
480   %1 = load i8, i8* %arrayidx1
481   ret i8 %1
482 }
483
484 ; CHECK-LABEL: Unscaled_Str32Ldr32
485 ; CHECK: mov w0, w1
486 define i32 @Unscaled_Str32Ldr32(i32* nocapture %P, i32 %v, i64 %n) {
487 entry:
488   %0 = bitcast i32* %P to i32*
489   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 -1
490   store i32 %v, i32* %arrayidx0
491   %arrayidx1 = getelementptr inbounds i32, i32* %0, i64 -1
492   %1 = load i32, i32* %arrayidx1
493   ret i32 %1
494 }
495
496 ; CHECK-LABEL: Unscaled_Str32Ldr16_0
497 ; CHECK: and w0, w1, #0xffff
498 define i16 @Unscaled_Str32Ldr16_0(i32* nocapture %P, i32 %v, i64 %n) {
499 entry:
500   %0 = bitcast i32* %P to i16*
501   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 -1
502   store i32 %v, i32* %arrayidx0
503   %arrayidx1 = getelementptr inbounds i16, i16* %0, i64 -2
504   %1 = load i16, i16* %arrayidx1
505   ret i16 %1
506 }
507
508 ; CHECK-LABEL: Unscaled_Str32Ldr16_1
509 ; CHECK: lsr    w0, w1, #16
510 define i16 @Unscaled_Str32Ldr16_1(i32* nocapture %P, i32 %v, i64 %n) {
511 entry:
512   %0 = bitcast i32* %P to i16*
513   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 -1
514   store i32 %v, i32* %arrayidx0
515   %arrayidx1 = getelementptr inbounds i16, i16* %0, i64 -1
516   %1 = load i16, i16* %arrayidx1
517   ret i16 %1
518 }
519
520 ; CHECK-LABEL: Unscaled_Str32Ldr8_0
521 ; CHECK: and w0, w1, #0xff
522 define i8 @Unscaled_Str32Ldr8_0(i32* nocapture %P, i32 %v, i64 %n) {
523 entry:
524   %0 = bitcast i32* %P to i8*
525   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 -1
526   store i32 %v, i32* %arrayidx0
527   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 -4
528   %1 = load i8, i8* %arrayidx1
529   ret i8 %1
530 }
531
532 ; CHECK-LABEL: Unscaled_Str32Ldr8_1
533 ; CHECK: ubfx w0, w1, #8, #8
534 define i8 @Unscaled_Str32Ldr8_1(i32* nocapture %P, i32 %v, i64 %n) {
535 entry:
536   %0 = bitcast i32* %P to i8*
537   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 -1
538   store i32 %v, i32* %arrayidx0
539   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 -3
540   %1 = load i8, i8* %arrayidx1
541   ret i8 %1
542 }
543
544 ; CHECK-LABEL: Unscaled_Str32Ldr8_2
545 ; CHECK: ubfx w0, w1, #16, #8
546 define i8 @Unscaled_Str32Ldr8_2(i32* nocapture %P, i32 %v, i64 %n) {
547 entry:
548   %0 = bitcast i32* %P to i8*
549   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 -1
550   store i32 %v, i32* %arrayidx0
551   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 -2
552   %1 = load i8, i8* %arrayidx1
553   ret i8 %1
554 }
555
556 ; CHECK-LABEL: Unscaled_Str32Ldr8_3
557 ; CHECK: lsr w0, w1, #24
558 define i8 @Unscaled_Str32Ldr8_3(i32* nocapture %P, i32 %v, i64 %n) {
559 entry:
560   %0 = bitcast i32* %P to i8*
561   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 -1
562   store i32 %v, i32* %arrayidx0
563   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 -1
564   %1 = load i8, i8* %arrayidx1
565   ret i8 %1
566 }
567
568 ; CHECK-LABEL: Unscaled_Str16Ldr16
569 ; CHECK: mov w0, w1
570 define i16 @Unscaled_Str16Ldr16(i16* nocapture %P, i16 %v, i64 %n) {
571 entry:
572   %0 = bitcast i16* %P to i16*
573   %arrayidx0 = getelementptr inbounds i16, i16* %P, i64 -1
574   store i16 %v, i16* %arrayidx0
575   %arrayidx1 = getelementptr inbounds i16, i16* %0, i64 -1
576   %1 = load i16, i16* %arrayidx1
577   ret i16 %1
578 }
579
580 ; CHECK-LABEL: Unscaled_Str16Ldr8_0
581 ; CHECK: and w0, w1, #0xff
582 define i8 @Unscaled_Str16Ldr8_0(i16* nocapture %P, i16 %v, i64 %n) {
583 entry:
584   %0 = bitcast i16* %P to i8*
585   %arrayidx0 = getelementptr inbounds i16, i16* %P, i64 -1
586   store i16 %v, i16* %arrayidx0
587   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 -2
588   %1 = load i8, i8* %arrayidx1
589   ret i8 %1
590 }
591
592 ; CHECK-LABEL: Unscaled_Str16Ldr8_1
593 ; CHECK: ubfx w0, w1, #8, #8
594 define i8 @Unscaled_Str16Ldr8_1(i16* nocapture %P, i16 %v, i64 %n) {
595 entry:
596   %0 = bitcast i16* %P to i8*
597   %arrayidx0 = getelementptr inbounds i16, i16* %P, i64 -1
598   store i16 %v, i16* %arrayidx0
599   %arrayidx1 = getelementptr inbounds i8, i8* %0, i64 -1
600   %1 = load i8, i8* %arrayidx1
601   ret i8 %1
602 }
603
604 ; CHECK-LABEL: StrVolatileLdr
605 ; CHECK: ldrh
606 define i16 @StrVolatileLdr(i32* nocapture %P, i32 %v, i64 %n) {
607 entry:
608   %0 = bitcast i32* %P to i16*
609   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
610   store i32 %v, i32* %arrayidx0
611   %arrayidx1 = getelementptr inbounds i16, i16* %0, i64 2
612   %1 = load volatile i16, i16* %arrayidx1
613   ret i16 %1
614 }
615
616 ; CHECK-LABEL: StrNotInRangeLdr
617 ; CHECK: ldrh
618 define i16 @StrNotInRangeLdr(i32* nocapture %P, i32 %v, i64 %n) {
619 entry:
620   %0 = bitcast i32* %P to i16*
621   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
622   store i32 %v, i32* %arrayidx0
623   %arrayidx1 = getelementptr inbounds i16, i16* %0, i64 1
624   %1 = load i16, i16* %arrayidx1
625   ret i16 %1
626 }
627
628 ; CHECK-LABEL: Unscaled_StrNotInRangeLdr
629 ; CHECK: ldurh
630 define i16 @Unscaled_StrNotInRangeLdr(i32* nocapture %P, i32 %v, i64 %n) {
631 entry:
632   %0 = bitcast i32* %P to i16*
633   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 -1
634   store i32 %v, i32* %arrayidx0
635   %arrayidx1 = getelementptr inbounds i16, i16* %0, i64 -3
636   %1 = load i16, i16* %arrayidx1
637   ret i16 %1
638 }
639
640 ; CHECK-LABEL: StrCallLdr
641 ; CHECK: ldrh
642 define i16 @StrCallLdr(i32* nocapture %P, i32 %v, i64 %n) {
643 entry:
644   %0 = bitcast i32* %P to i16*
645   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
646   store i32 %v, i32* %arrayidx0
647   %c = call i1 @test_dummy()
648   %arrayidx1 = getelementptr inbounds i16, i16* %0, i64 1
649   %1 = load i16, i16* %arrayidx1
650   ret i16 %1
651 }
652
653 declare i1 @test_dummy()
654
655 ; CHECK-LABEL: StrStrLdr
656 ; CHECK: ldrh
657 define i16 @StrStrLdr(i32 %v, i32* %P, i32* %P2, i32 %n) {
658 entry:
659   %0 = bitcast i32* %P to i16*
660   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
661   store i32 %v, i32* %arrayidx0
662   store i32 %n, i32* %P2
663   %arrayidx1 = getelementptr inbounds i16, i16* %0, i64 2
664   %1 = load i16, i16* %arrayidx1
665   ret i16 %1
666 }