1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=armeb-unknown | FileCheck %s
3 ; RUN: llc < %s -mtriple=armv6eb-unknown | FileCheck %s --check-prefix=CHECK-ARMv6
4 ; RUN: llc < %s -mtriple=thumbv6meb-none-eabi | FileCheck %s --check-prefix=CHECK-THUMBv6
5 ; RUN: llc < %s -mtriple=thumbv6meb-none-eabi | FileCheck %s --check-prefix=CHECK-THUMBv7
7 ; ptr p; // p is 4 byte aligned
8 ; ((i32) p[0] << 24) | ((i32) p[1] << 16) | ((i32) p[2] << 8) | (i32) p[3]
9 define i32 @load_i32_by_i8_big_endian(ptr %arg) {
10 ; CHECK-LABEL: load_i32_by_i8_big_endian:
12 ; CHECK-NEXT: ldr r0, [r0]
13 ; CHECK-NEXT: mov pc, lr
15 ; CHECK-ARMv6-LABEL: load_i32_by_i8_big_endian:
16 ; CHECK-ARMv6: @ %bb.0:
17 ; CHECK-ARMv6-NEXT: ldr r0, [r0]
18 ; CHECK-ARMv6-NEXT: bx lr
20 ; CHECK-THUMBv6-LABEL: load_i32_by_i8_big_endian:
21 ; CHECK-THUMBv6: @ %bb.0:
22 ; CHECK-THUMBv6-NEXT: ldr r0, [r0]
23 ; CHECK-THUMBv6-NEXT: bx lr
25 ; CHECK-THUMBv7-LABEL: load_i32_by_i8_big_endian:
26 ; CHECK-THUMBv7: @ %bb.0:
27 ; CHECK-THUMBv7-NEXT: ldr r0, [r0]
28 ; CHECK-THUMBv7-NEXT: bx lr
30 %tmp1 = load i8, ptr %arg, align 4
31 %tmp2 = zext i8 %tmp1 to i32
32 %tmp3 = shl nuw nsw i32 %tmp2, 24
33 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 1
34 %tmp5 = load i8, ptr %tmp4, align 1
35 %tmp6 = zext i8 %tmp5 to i32
36 %tmp7 = shl nuw nsw i32 %tmp6, 16
37 %tmp8 = or i32 %tmp7, %tmp3
38 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 2
39 %tmp10 = load i8, ptr %tmp9, align 1
40 %tmp11 = zext i8 %tmp10 to i32
41 %tmp12 = shl nuw nsw i32 %tmp11, 8
42 %tmp13 = or i32 %tmp8, %tmp12
43 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 3
44 %tmp15 = load i8, ptr %tmp14, align 1
45 %tmp16 = zext i8 %tmp15 to i32
46 %tmp17 = or i32 %tmp13, %tmp16
50 ; ptr p; // p is 4 byte aligned
51 ; (i32) p[0] | ((i32) p[1] << 8) | ((i32) p[2] << 16) | ((i32) p[3] << 24)
52 define i32 @load_i32_by_i8_bswap(ptr %arg) {
53 ; BSWAP is not supported by 32 bit target
54 ; CHECK-LABEL: load_i32_by_i8_bswap:
56 ; CHECK-NEXT: ldr r0, [r0]
57 ; CHECK-NEXT: mov r1, #65280
58 ; CHECK-NEXT: and r2, r0, #65280
59 ; CHECK-NEXT: and r1, r1, r0, lsr #8
60 ; CHECK-NEXT: orr r1, r1, r0, lsr #24
61 ; CHECK-NEXT: lsl r0, r0, #24
62 ; CHECK-NEXT: orr r0, r0, r2, lsl #8
63 ; CHECK-NEXT: orr r0, r0, r1
64 ; CHECK-NEXT: mov pc, lr
66 ; CHECK-ARMv6-LABEL: load_i32_by_i8_bswap:
67 ; CHECK-ARMv6: @ %bb.0:
68 ; CHECK-ARMv6-NEXT: ldr r0, [r0]
69 ; CHECK-ARMv6-NEXT: rev r0, r0
70 ; CHECK-ARMv6-NEXT: bx lr
72 ; CHECK-THUMBv6-LABEL: load_i32_by_i8_bswap:
73 ; CHECK-THUMBv6: @ %bb.0:
74 ; CHECK-THUMBv6-NEXT: ldr r0, [r0]
75 ; CHECK-THUMBv6-NEXT: rev r0, r0
76 ; CHECK-THUMBv6-NEXT: bx lr
78 ; CHECK-THUMBv7-LABEL: load_i32_by_i8_bswap:
79 ; CHECK-THUMBv7: @ %bb.0:
80 ; CHECK-THUMBv7-NEXT: ldr r0, [r0]
81 ; CHECK-THUMBv7-NEXT: rev r0, r0
82 ; CHECK-THUMBv7-NEXT: bx lr
84 %tmp2 = load i8, ptr %arg, align 4
85 %tmp3 = zext i8 %tmp2 to i32
86 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 1
87 %tmp5 = load i8, ptr %tmp4, align 1
88 %tmp6 = zext i8 %tmp5 to i32
89 %tmp7 = shl nuw nsw i32 %tmp6, 8
90 %tmp8 = or i32 %tmp7, %tmp3
91 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 2
92 %tmp10 = load i8, ptr %tmp9, align 1
93 %tmp11 = zext i8 %tmp10 to i32
94 %tmp12 = shl nuw nsw i32 %tmp11, 16
95 %tmp13 = or i32 %tmp8, %tmp12
96 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 3
97 %tmp15 = load i8, ptr %tmp14, align 1
98 %tmp16 = zext i8 %tmp15 to i32
99 %tmp17 = shl nuw nsw i32 %tmp16, 24
100 %tmp18 = or i32 %tmp13, %tmp17
104 ; ptr p; // p is 4 byte aligned
105 ; ((i32) (((i16) p[0] << 8) | (i16) p[1]) << 16) | (i32) (((i16) p[3] << 8) | (i16) p[4])
106 define i32 @load_i32_by_i16_by_i8_big_endian(ptr %arg) {
107 ; CHECK-LABEL: load_i32_by_i16_by_i8_big_endian:
109 ; CHECK-NEXT: ldr r0, [r0]
110 ; CHECK-NEXT: mov pc, lr
112 ; CHECK-ARMv6-LABEL: load_i32_by_i16_by_i8_big_endian:
113 ; CHECK-ARMv6: @ %bb.0:
114 ; CHECK-ARMv6-NEXT: ldr r0, [r0]
115 ; CHECK-ARMv6-NEXT: bx lr
117 ; CHECK-THUMBv6-LABEL: load_i32_by_i16_by_i8_big_endian:
118 ; CHECK-THUMBv6: @ %bb.0:
119 ; CHECK-THUMBv6-NEXT: ldr r0, [r0]
120 ; CHECK-THUMBv6-NEXT: bx lr
122 ; CHECK-THUMBv7-LABEL: load_i32_by_i16_by_i8_big_endian:
123 ; CHECK-THUMBv7: @ %bb.0:
124 ; CHECK-THUMBv7-NEXT: ldr r0, [r0]
125 ; CHECK-THUMBv7-NEXT: bx lr
127 %tmp1 = load i8, ptr %arg, align 4
128 %tmp2 = zext i8 %tmp1 to i16
129 %tmp3 = getelementptr inbounds i8, ptr %arg, i32 1
130 %tmp4 = load i8, ptr %tmp3, align 1
131 %tmp5 = zext i8 %tmp4 to i16
132 %tmp6 = shl nuw nsw i16 %tmp2, 8
133 %tmp7 = or i16 %tmp6, %tmp5
134 %tmp8 = getelementptr inbounds i8, ptr %arg, i32 2
135 %tmp9 = load i8, ptr %tmp8, align 1
136 %tmp10 = zext i8 %tmp9 to i16
137 %tmp11 = getelementptr inbounds i8, ptr %arg, i32 3
138 %tmp12 = load i8, ptr %tmp11, align 1
139 %tmp13 = zext i8 %tmp12 to i16
140 %tmp14 = shl nuw nsw i16 %tmp10, 8
141 %tmp15 = or i16 %tmp14, %tmp13
142 %tmp16 = zext i16 %tmp7 to i32
143 %tmp17 = zext i16 %tmp15 to i32
144 %tmp18 = shl nuw nsw i32 %tmp16, 16
145 %tmp19 = or i32 %tmp18, %tmp17
149 ; ptr p; // p is 4 byte aligned
150 ; ((i32) p[0] << 16) | (i32) p[1]
151 define i32 @load_i32_by_i16(ptr %arg) {
152 ; CHECK-LABEL: load_i32_by_i16:
154 ; CHECK-NEXT: ldr r0, [r0]
155 ; CHECK-NEXT: mov pc, lr
157 ; CHECK-ARMv6-LABEL: load_i32_by_i16:
158 ; CHECK-ARMv6: @ %bb.0:
159 ; CHECK-ARMv6-NEXT: ldr r0, [r0]
160 ; CHECK-ARMv6-NEXT: bx lr
162 ; CHECK-THUMBv6-LABEL: load_i32_by_i16:
163 ; CHECK-THUMBv6: @ %bb.0:
164 ; CHECK-THUMBv6-NEXT: ldr r0, [r0]
165 ; CHECK-THUMBv6-NEXT: bx lr
167 ; CHECK-THUMBv7-LABEL: load_i32_by_i16:
168 ; CHECK-THUMBv7: @ %bb.0:
169 ; CHECK-THUMBv7-NEXT: ldr r0, [r0]
170 ; CHECK-THUMBv7-NEXT: bx lr
172 %tmp1 = load i16, ptr %arg, align 4
173 %tmp2 = zext i16 %tmp1 to i32
174 %tmp3 = getelementptr inbounds i16, ptr %arg, i32 1
175 %tmp4 = load i16, ptr %tmp3, align 1
176 %tmp5 = zext i16 %tmp4 to i32
177 %tmp6 = shl nuw nsw i32 %tmp2, 16
178 %tmp7 = or i32 %tmp6, %tmp5
182 ; ptr p_16; // p_16 is 4 byte aligned
183 ; ptr p_8 = (ptr) p_16;
184 ; (i32) (p_16[0] << 16) | ((i32) p[2] << 8) | (i32) p[3]
185 define i32 @load_i32_by_i16_i8(ptr %arg) {
186 ; CHECK-LABEL: load_i32_by_i16_i8:
188 ; CHECK-NEXT: ldr r0, [r0]
189 ; CHECK-NEXT: mov pc, lr
191 ; CHECK-ARMv6-LABEL: load_i32_by_i16_i8:
192 ; CHECK-ARMv6: @ %bb.0:
193 ; CHECK-ARMv6-NEXT: ldr r0, [r0]
194 ; CHECK-ARMv6-NEXT: bx lr
196 ; CHECK-THUMBv6-LABEL: load_i32_by_i16_i8:
197 ; CHECK-THUMBv6: @ %bb.0:
198 ; CHECK-THUMBv6-NEXT: ldr r0, [r0]
199 ; CHECK-THUMBv6-NEXT: bx lr
201 ; CHECK-THUMBv7-LABEL: load_i32_by_i16_i8:
202 ; CHECK-THUMBv7: @ %bb.0:
203 ; CHECK-THUMBv7-NEXT: ldr r0, [r0]
204 ; CHECK-THUMBv7-NEXT: bx lr
206 %tmp2 = load i16, ptr %arg, align 4
207 %tmp3 = zext i16 %tmp2 to i32
208 %tmp4 = shl nuw nsw i32 %tmp3, 16
209 %tmp5 = getelementptr inbounds i8, ptr %arg, i32 2
210 %tmp6 = load i8, ptr %tmp5, align 1
211 %tmp7 = zext i8 %tmp6 to i32
212 %tmp8 = shl nuw nsw i32 %tmp7, 8
213 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 3
214 %tmp10 = load i8, ptr %tmp9, align 1
215 %tmp11 = zext i8 %tmp10 to i32
216 %tmp12 = or i32 %tmp8, %tmp11
217 %tmp13 = or i32 %tmp12, %tmp4
221 ; ptr p; // p is 8 byte aligned
222 ; (i64) p[0] | ((i64) p[1] << 8) | ((i64) p[2] << 16) | ((i64) p[3] << 24) | ((i64) p[4] << 32) | ((i64) p[5] << 40) | ((i64) p[6] << 48) | ((i64) p[7] << 56)
223 define i64 @load_i64_by_i8_bswap(ptr %arg) {
224 ; CHECK-LABEL: load_i64_by_i8_bswap:
226 ; CHECK-NEXT: ldr r1, [r0]
227 ; CHECK-NEXT: mov r12, #65280
228 ; CHECK-NEXT: ldr r0, [r0, #4]
229 ; CHECK-NEXT: and r2, r0, #65280
230 ; CHECK-NEXT: and r3, r12, r0, lsr #8
231 ; CHECK-NEXT: orr r3, r3, r0, lsr #24
232 ; CHECK-NEXT: lsl r0, r0, #24
233 ; CHECK-NEXT: orr r0, r0, r2, lsl #8
234 ; CHECK-NEXT: and r2, r12, r1, lsr #8
235 ; CHECK-NEXT: orr r0, r0, r3
236 ; CHECK-NEXT: and r3, r1, #65280
237 ; CHECK-NEXT: orr r2, r2, r1, lsr #24
238 ; CHECK-NEXT: lsl r1, r1, #24
239 ; CHECK-NEXT: orr r1, r1, r3, lsl #8
240 ; CHECK-NEXT: orr r1, r1, r2
241 ; CHECK-NEXT: mov pc, lr
243 ; CHECK-ARMv6-LABEL: load_i64_by_i8_bswap:
244 ; CHECK-ARMv6: @ %bb.0:
245 ; CHECK-ARMv6-NEXT: ldrd r2, r3, [r0]
246 ; CHECK-ARMv6-NEXT: rev r0, r3
247 ; CHECK-ARMv6-NEXT: rev r1, r2
248 ; CHECK-ARMv6-NEXT: bx lr
250 ; CHECK-THUMBv6-LABEL: load_i64_by_i8_bswap:
251 ; CHECK-THUMBv6: @ %bb.0:
252 ; CHECK-THUMBv6-NEXT: ldr r1, [r0]
253 ; CHECK-THUMBv6-NEXT: ldr r0, [r0, #4]
254 ; CHECK-THUMBv6-NEXT: rev r0, r0
255 ; CHECK-THUMBv6-NEXT: rev r1, r1
256 ; CHECK-THUMBv6-NEXT: bx lr
258 ; CHECK-THUMBv7-LABEL: load_i64_by_i8_bswap:
259 ; CHECK-THUMBv7: @ %bb.0:
260 ; CHECK-THUMBv7-NEXT: ldr r1, [r0]
261 ; CHECK-THUMBv7-NEXT: ldr r0, [r0, #4]
262 ; CHECK-THUMBv7-NEXT: rev r0, r0
263 ; CHECK-THUMBv7-NEXT: rev r1, r1
264 ; CHECK-THUMBv7-NEXT: bx lr
266 %tmp1 = load i8, ptr %arg, align 8
267 %tmp2 = zext i8 %tmp1 to i64
268 %tmp3 = getelementptr inbounds i8, ptr %arg, i64 1
269 %tmp4 = load i8, ptr %tmp3, align 1
270 %tmp5 = zext i8 %tmp4 to i64
271 %tmp6 = shl nuw nsw i64 %tmp5, 8
272 %tmp7 = or i64 %tmp6, %tmp2
273 %tmp8 = getelementptr inbounds i8, ptr %arg, i64 2
274 %tmp9 = load i8, ptr %tmp8, align 1
275 %tmp10 = zext i8 %tmp9 to i64
276 %tmp11 = shl nuw nsw i64 %tmp10, 16
277 %tmp12 = or i64 %tmp7, %tmp11
278 %tmp13 = getelementptr inbounds i8, ptr %arg, i64 3
279 %tmp14 = load i8, ptr %tmp13, align 1
280 %tmp15 = zext i8 %tmp14 to i64
281 %tmp16 = shl nuw nsw i64 %tmp15, 24
282 %tmp17 = or i64 %tmp12, %tmp16
283 %tmp18 = getelementptr inbounds i8, ptr %arg, i64 4
284 %tmp19 = load i8, ptr %tmp18, align 1
285 %tmp20 = zext i8 %tmp19 to i64
286 %tmp21 = shl nuw nsw i64 %tmp20, 32
287 %tmp22 = or i64 %tmp17, %tmp21
288 %tmp23 = getelementptr inbounds i8, ptr %arg, i64 5
289 %tmp24 = load i8, ptr %tmp23, align 1
290 %tmp25 = zext i8 %tmp24 to i64
291 %tmp26 = shl nuw nsw i64 %tmp25, 40
292 %tmp27 = or i64 %tmp22, %tmp26
293 %tmp28 = getelementptr inbounds i8, ptr %arg, i64 6
294 %tmp29 = load i8, ptr %tmp28, align 1
295 %tmp30 = zext i8 %tmp29 to i64
296 %tmp31 = shl nuw nsw i64 %tmp30, 48
297 %tmp32 = or i64 %tmp27, %tmp31
298 %tmp33 = getelementptr inbounds i8, ptr %arg, i64 7
299 %tmp34 = load i8, ptr %tmp33, align 1
300 %tmp35 = zext i8 %tmp34 to i64
301 %tmp36 = shl nuw i64 %tmp35, 56
302 %tmp37 = or i64 %tmp32, %tmp36
306 ; ptr p; // p is 8 byte aligned
307 ; ((i64) p[0] << 56) | ((i64) p[1] << 48) | ((i64) p[2] << 40) | ((i64) p[3] << 32) | ((i64) p[4] << 24) | ((i64) p[5] << 16) | ((i64) p[6] << 8) | (i64) p[7]
308 define i64 @load_i64_by_i8(ptr %arg) {
309 ; CHECK-LABEL: load_i64_by_i8:
311 ; CHECK-NEXT: ldr r2, [r0]
312 ; CHECK-NEXT: ldr r1, [r0, #4]
313 ; CHECK-NEXT: mov r0, r2
314 ; CHECK-NEXT: mov pc, lr
316 ; CHECK-ARMv6-LABEL: load_i64_by_i8:
317 ; CHECK-ARMv6: @ %bb.0:
318 ; CHECK-ARMv6-NEXT: ldrd r0, r1, [r0]
319 ; CHECK-ARMv6-NEXT: bx lr
321 ; CHECK-THUMBv6-LABEL: load_i64_by_i8:
322 ; CHECK-THUMBv6: @ %bb.0:
323 ; CHECK-THUMBv6-NEXT: ldr r2, [r0]
324 ; CHECK-THUMBv6-NEXT: ldr r1, [r0, #4]
325 ; CHECK-THUMBv6-NEXT: mov r0, r2
326 ; CHECK-THUMBv6-NEXT: bx lr
328 ; CHECK-THUMBv7-LABEL: load_i64_by_i8:
329 ; CHECK-THUMBv7: @ %bb.0:
330 ; CHECK-THUMBv7-NEXT: ldr r2, [r0]
331 ; CHECK-THUMBv7-NEXT: ldr r1, [r0, #4]
332 ; CHECK-THUMBv7-NEXT: mov r0, r2
333 ; CHECK-THUMBv7-NEXT: bx lr
335 %tmp1 = load i8, ptr %arg, align 8
336 %tmp2 = zext i8 %tmp1 to i64
337 %tmp3 = shl nuw i64 %tmp2, 56
338 %tmp4 = getelementptr inbounds i8, ptr %arg, i64 1
339 %tmp5 = load i8, ptr %tmp4, align 1
340 %tmp6 = zext i8 %tmp5 to i64
341 %tmp7 = shl nuw nsw i64 %tmp6, 48
342 %tmp8 = or i64 %tmp7, %tmp3
343 %tmp9 = getelementptr inbounds i8, ptr %arg, i64 2
344 %tmp10 = load i8, ptr %tmp9, align 1
345 %tmp11 = zext i8 %tmp10 to i64
346 %tmp12 = shl nuw nsw i64 %tmp11, 40
347 %tmp13 = or i64 %tmp8, %tmp12
348 %tmp14 = getelementptr inbounds i8, ptr %arg, i64 3
349 %tmp15 = load i8, ptr %tmp14, align 1
350 %tmp16 = zext i8 %tmp15 to i64
351 %tmp17 = shl nuw nsw i64 %tmp16, 32
352 %tmp18 = or i64 %tmp13, %tmp17
353 %tmp19 = getelementptr inbounds i8, ptr %arg, i64 4
354 %tmp20 = load i8, ptr %tmp19, align 1
355 %tmp21 = zext i8 %tmp20 to i64
356 %tmp22 = shl nuw nsw i64 %tmp21, 24
357 %tmp23 = or i64 %tmp18, %tmp22
358 %tmp24 = getelementptr inbounds i8, ptr %arg, i64 5
359 %tmp25 = load i8, ptr %tmp24, align 1
360 %tmp26 = zext i8 %tmp25 to i64
361 %tmp27 = shl nuw nsw i64 %tmp26, 16
362 %tmp28 = or i64 %tmp23, %tmp27
363 %tmp29 = getelementptr inbounds i8, ptr %arg, i64 6
364 %tmp30 = load i8, ptr %tmp29, align 1
365 %tmp31 = zext i8 %tmp30 to i64
366 %tmp32 = shl nuw nsw i64 %tmp31, 8
367 %tmp33 = or i64 %tmp28, %tmp32
368 %tmp34 = getelementptr inbounds i8, ptr %arg, i64 7
369 %tmp35 = load i8, ptr %tmp34, align 1
370 %tmp36 = zext i8 %tmp35 to i64
371 %tmp37 = or i64 %tmp33, %tmp36
375 ; ptr p; // p[1] is 4 byte aligned
376 ; (i32) p[1] | ((i32) p[2] << 8) | ((i32) p[3] << 16) | ((i32) p[4] << 24)
377 define i32 @load_i32_by_i8_nonzero_offset(ptr %arg) {
378 ; CHECK-LABEL: load_i32_by_i8_nonzero_offset:
380 ; CHECK-NEXT: ldr r0, [r0, #1]
381 ; CHECK-NEXT: mov r1, #65280
382 ; CHECK-NEXT: and r2, r0, #65280
383 ; CHECK-NEXT: and r1, r1, r0, lsr #8
384 ; CHECK-NEXT: orr r1, r1, r0, lsr #24
385 ; CHECK-NEXT: lsl r0, r0, #24
386 ; CHECK-NEXT: orr r0, r0, r2, lsl #8
387 ; CHECK-NEXT: orr r0, r0, r1
388 ; CHECK-NEXT: mov pc, lr
390 ; CHECK-ARMv6-LABEL: load_i32_by_i8_nonzero_offset:
391 ; CHECK-ARMv6: @ %bb.0:
392 ; CHECK-ARMv6-NEXT: ldr r0, [r0, #1]
393 ; CHECK-ARMv6-NEXT: rev r0, r0
394 ; CHECK-ARMv6-NEXT: bx lr
396 ; CHECK-THUMBv6-LABEL: load_i32_by_i8_nonzero_offset:
397 ; CHECK-THUMBv6: @ %bb.0:
398 ; CHECK-THUMBv6-NEXT: movs r1, #1
399 ; CHECK-THUMBv6-NEXT: ldr r0, [r0, r1]
400 ; CHECK-THUMBv6-NEXT: rev r0, r0
401 ; CHECK-THUMBv6-NEXT: bx lr
403 ; CHECK-THUMBv7-LABEL: load_i32_by_i8_nonzero_offset:
404 ; CHECK-THUMBv7: @ %bb.0:
405 ; CHECK-THUMBv7-NEXT: movs r1, #1
406 ; CHECK-THUMBv7-NEXT: ldr r0, [r0, r1]
407 ; CHECK-THUMBv7-NEXT: rev r0, r0
408 ; CHECK-THUMBv7-NEXT: bx lr
411 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 1
412 %tmp2 = load i8, ptr %tmp1, align 4
413 %tmp3 = zext i8 %tmp2 to i32
414 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 2
415 %tmp5 = load i8, ptr %tmp4, align 1
416 %tmp6 = zext i8 %tmp5 to i32
417 %tmp7 = shl nuw nsw i32 %tmp6, 8
418 %tmp8 = or i32 %tmp7, %tmp3
419 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 3
420 %tmp10 = load i8, ptr %tmp9, align 1
421 %tmp11 = zext i8 %tmp10 to i32
422 %tmp12 = shl nuw nsw i32 %tmp11, 16
423 %tmp13 = or i32 %tmp8, %tmp12
424 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 4
425 %tmp15 = load i8, ptr %tmp14, align 1
426 %tmp16 = zext i8 %tmp15 to i32
427 %tmp17 = shl nuw nsw i32 %tmp16, 24
428 %tmp18 = or i32 %tmp13, %tmp17
432 ; ptr p; // p[-4] is 4 byte aligned
433 ; (i32) p[-4] | ((i32) p[-3] << 8) | ((i32) p[-2] << 16) | ((i32) p[-1] << 24)
434 define i32 @load_i32_by_i8_neg_offset(ptr %arg) {
435 ; CHECK-LABEL: load_i32_by_i8_neg_offset:
437 ; CHECK-NEXT: ldr r0, [r0, #-4]
438 ; CHECK-NEXT: mov r1, #65280
439 ; CHECK-NEXT: and r2, r0, #65280
440 ; CHECK-NEXT: and r1, r1, r0, lsr #8
441 ; CHECK-NEXT: orr r1, r1, r0, lsr #24
442 ; CHECK-NEXT: lsl r0, r0, #24
443 ; CHECK-NEXT: orr r0, r0, r2, lsl #8
444 ; CHECK-NEXT: orr r0, r0, r1
445 ; CHECK-NEXT: mov pc, lr
447 ; CHECK-ARMv6-LABEL: load_i32_by_i8_neg_offset:
448 ; CHECK-ARMv6: @ %bb.0:
449 ; CHECK-ARMv6-NEXT: ldr r0, [r0, #-4]
450 ; CHECK-ARMv6-NEXT: rev r0, r0
451 ; CHECK-ARMv6-NEXT: bx lr
453 ; CHECK-THUMBv6-LABEL: load_i32_by_i8_neg_offset:
454 ; CHECK-THUMBv6: @ %bb.0:
455 ; CHECK-THUMBv6-NEXT: subs r0, r0, #4
456 ; CHECK-THUMBv6-NEXT: ldr r0, [r0]
457 ; CHECK-THUMBv6-NEXT: rev r0, r0
458 ; CHECK-THUMBv6-NEXT: bx lr
460 ; CHECK-THUMBv7-LABEL: load_i32_by_i8_neg_offset:
461 ; CHECK-THUMBv7: @ %bb.0:
462 ; CHECK-THUMBv7-NEXT: subs r0, r0, #4
463 ; CHECK-THUMBv7-NEXT: ldr r0, [r0]
464 ; CHECK-THUMBv7-NEXT: rev r0, r0
465 ; CHECK-THUMBv7-NEXT: bx lr
468 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 -4
469 %tmp2 = load i8, ptr %tmp1, align 4
470 %tmp3 = zext i8 %tmp2 to i32
471 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 -3
472 %tmp5 = load i8, ptr %tmp4, align 1
473 %tmp6 = zext i8 %tmp5 to i32
474 %tmp7 = shl nuw nsw i32 %tmp6, 8
475 %tmp8 = or i32 %tmp7, %tmp3
476 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 -2
477 %tmp10 = load i8, ptr %tmp9, align 1
478 %tmp11 = zext i8 %tmp10 to i32
479 %tmp12 = shl nuw nsw i32 %tmp11, 16
480 %tmp13 = or i32 %tmp8, %tmp12
481 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 -1
482 %tmp15 = load i8, ptr %tmp14, align 1
483 %tmp16 = zext i8 %tmp15 to i32
484 %tmp17 = shl nuw nsw i32 %tmp16, 24
485 %tmp18 = or i32 %tmp13, %tmp17
489 ; ptr p; // p[1] is 4 byte aligned
490 ; (i32) p[4] | ((i32) p[3] << 8) | ((i32) p[2] << 16) | ((i32) p[1] << 24)
491 define i32 @load_i32_by_i8_nonzero_offset_bswap(ptr %arg) {
492 ; CHECK-LABEL: load_i32_by_i8_nonzero_offset_bswap:
494 ; CHECK-NEXT: ldr r0, [r0, #1]
495 ; CHECK-NEXT: mov pc, lr
497 ; CHECK-ARMv6-LABEL: load_i32_by_i8_nonzero_offset_bswap:
498 ; CHECK-ARMv6: @ %bb.0:
499 ; CHECK-ARMv6-NEXT: ldr r0, [r0, #1]
500 ; CHECK-ARMv6-NEXT: bx lr
502 ; CHECK-THUMBv6-LABEL: load_i32_by_i8_nonzero_offset_bswap:
503 ; CHECK-THUMBv6: @ %bb.0:
504 ; CHECK-THUMBv6-NEXT: movs r1, #1
505 ; CHECK-THUMBv6-NEXT: ldr r0, [r0, r1]
506 ; CHECK-THUMBv6-NEXT: bx lr
508 ; CHECK-THUMBv7-LABEL: load_i32_by_i8_nonzero_offset_bswap:
509 ; CHECK-THUMBv7: @ %bb.0:
510 ; CHECK-THUMBv7-NEXT: movs r1, #1
511 ; CHECK-THUMBv7-NEXT: ldr r0, [r0, r1]
512 ; CHECK-THUMBv7-NEXT: bx lr
515 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 4
516 %tmp2 = load i8, ptr %tmp1, align 1
517 %tmp3 = zext i8 %tmp2 to i32
518 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 3
519 %tmp5 = load i8, ptr %tmp4, align 1
520 %tmp6 = zext i8 %tmp5 to i32
521 %tmp7 = shl nuw nsw i32 %tmp6, 8
522 %tmp8 = or i32 %tmp7, %tmp3
523 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 2
524 %tmp10 = load i8, ptr %tmp9, align 1
525 %tmp11 = zext i8 %tmp10 to i32
526 %tmp12 = shl nuw nsw i32 %tmp11, 16
527 %tmp13 = or i32 %tmp8, %tmp12
528 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 1
529 %tmp15 = load i8, ptr %tmp14, align 4
530 %tmp16 = zext i8 %tmp15 to i32
531 %tmp17 = shl nuw nsw i32 %tmp16, 24
532 %tmp18 = or i32 %tmp13, %tmp17
536 ; ptr p; // p[-4] is 4 byte aligned
537 ; (i32) p[-1] | ((i32) p[-2] << 8) | ((i32) p[-3] << 16) | ((i32) p[-4] << 24)
538 define i32 @load_i32_by_i8_neg_offset_bswap(ptr %arg) {
539 ; CHECK-LABEL: load_i32_by_i8_neg_offset_bswap:
541 ; CHECK-NEXT: ldr r0, [r0, #-4]
542 ; CHECK-NEXT: mov pc, lr
544 ; CHECK-ARMv6-LABEL: load_i32_by_i8_neg_offset_bswap:
545 ; CHECK-ARMv6: @ %bb.0:
546 ; CHECK-ARMv6-NEXT: ldr r0, [r0, #-4]
547 ; CHECK-ARMv6-NEXT: bx lr
549 ; CHECK-THUMBv6-LABEL: load_i32_by_i8_neg_offset_bswap:
550 ; CHECK-THUMBv6: @ %bb.0:
551 ; CHECK-THUMBv6-NEXT: subs r0, r0, #4
552 ; CHECK-THUMBv6-NEXT: ldr r0, [r0]
553 ; CHECK-THUMBv6-NEXT: bx lr
555 ; CHECK-THUMBv7-LABEL: load_i32_by_i8_neg_offset_bswap:
556 ; CHECK-THUMBv7: @ %bb.0:
557 ; CHECK-THUMBv7-NEXT: subs r0, r0, #4
558 ; CHECK-THUMBv7-NEXT: ldr r0, [r0]
559 ; CHECK-THUMBv7-NEXT: bx lr
562 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 -1
563 %tmp2 = load i8, ptr %tmp1, align 1
564 %tmp3 = zext i8 %tmp2 to i32
565 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 -2
566 %tmp5 = load i8, ptr %tmp4, align 1
567 %tmp6 = zext i8 %tmp5 to i32
568 %tmp7 = shl nuw nsw i32 %tmp6, 8
569 %tmp8 = or i32 %tmp7, %tmp3
570 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 -3
571 %tmp10 = load i8, ptr %tmp9, align 1
572 %tmp11 = zext i8 %tmp10 to i32
573 %tmp12 = shl nuw nsw i32 %tmp11, 16
574 %tmp13 = or i32 %tmp8, %tmp12
575 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 -4
576 %tmp15 = load i8, ptr %tmp14, align 4
577 %tmp16 = zext i8 %tmp15 to i32
578 %tmp17 = shl nuw nsw i32 %tmp16, 24
579 %tmp18 = or i32 %tmp13, %tmp17
583 declare i16 @llvm.bswap.i16(i16)
585 ; ptr p; // p is 4 byte aligned
586 ; (i32) bswap(p[0]) | (i32) bswap(p[1] << 16)
587 define i32 @load_i32_by_bswap_i16(ptr %arg) {
588 ; CHECK-LABEL: load_i32_by_bswap_i16:
590 ; CHECK-NEXT: ldr r0, [r0]
591 ; CHECK-NEXT: mov r1, #65280
592 ; CHECK-NEXT: and r2, r0, #65280
593 ; CHECK-NEXT: and r1, r1, r0, lsr #8
594 ; CHECK-NEXT: orr r1, r1, r0, lsr #24
595 ; CHECK-NEXT: lsl r0, r0, #24
596 ; CHECK-NEXT: orr r0, r0, r2, lsl #8
597 ; CHECK-NEXT: orr r0, r0, r1
598 ; CHECK-NEXT: mov pc, lr
600 ; CHECK-ARMv6-LABEL: load_i32_by_bswap_i16:
601 ; CHECK-ARMv6: @ %bb.0:
602 ; CHECK-ARMv6-NEXT: ldr r0, [r0]
603 ; CHECK-ARMv6-NEXT: rev r0, r0
604 ; CHECK-ARMv6-NEXT: bx lr
606 ; CHECK-THUMBv6-LABEL: load_i32_by_bswap_i16:
607 ; CHECK-THUMBv6: @ %bb.0:
608 ; CHECK-THUMBv6-NEXT: ldr r0, [r0]
609 ; CHECK-THUMBv6-NEXT: rev r0, r0
610 ; CHECK-THUMBv6-NEXT: bx lr
612 ; CHECK-THUMBv7-LABEL: load_i32_by_bswap_i16:
613 ; CHECK-THUMBv7: @ %bb.0:
614 ; CHECK-THUMBv7-NEXT: ldr r0, [r0]
615 ; CHECK-THUMBv7-NEXT: rev r0, r0
616 ; CHECK-THUMBv7-NEXT: bx lr
619 %tmp1 = load i16, ptr %arg, align 4
620 %tmp11 = call i16 @llvm.bswap.i16(i16 %tmp1)
621 %tmp2 = zext i16 %tmp11 to i32
622 %tmp3 = getelementptr inbounds i16, ptr %arg, i32 1
623 %tmp4 = load i16, ptr %tmp3, align 1
624 %tmp41 = call i16 @llvm.bswap.i16(i16 %tmp4)
625 %tmp5 = zext i16 %tmp41 to i32
626 %tmp6 = shl nuw nsw i32 %tmp5, 16
627 %tmp7 = or i32 %tmp6, %tmp2
631 ; ptr p; // p is 4 byte aligned
632 ; (i32) p[1] | (sext(p[0] << 16) to i32)
633 define i32 @load_i32_by_sext_i16(ptr %arg) {
634 ; CHECK-LABEL: load_i32_by_sext_i16:
636 ; CHECK-NEXT: ldr r0, [r0]
637 ; CHECK-NEXT: mov pc, lr
639 ; CHECK-ARMv6-LABEL: load_i32_by_sext_i16:
640 ; CHECK-ARMv6: @ %bb.0:
641 ; CHECK-ARMv6-NEXT: ldr r0, [r0]
642 ; CHECK-ARMv6-NEXT: bx lr
644 ; CHECK-THUMBv6-LABEL: load_i32_by_sext_i16:
645 ; CHECK-THUMBv6: @ %bb.0:
646 ; CHECK-THUMBv6-NEXT: ldr r0, [r0]
647 ; CHECK-THUMBv6-NEXT: bx lr
649 ; CHECK-THUMBv7-LABEL: load_i32_by_sext_i16:
650 ; CHECK-THUMBv7: @ %bb.0:
651 ; CHECK-THUMBv7-NEXT: ldr r0, [r0]
652 ; CHECK-THUMBv7-NEXT: bx lr
653 %tmp1 = load i16, ptr %arg, align 4
654 %tmp2 = sext i16 %tmp1 to i32
655 %tmp3 = getelementptr inbounds i16, ptr %arg, i32 1
656 %tmp4 = load i16, ptr %tmp3, align 1
657 %tmp5 = zext i16 %tmp4 to i32
658 %tmp6 = shl nuw nsw i32 %tmp2, 16
659 %tmp7 = or i32 %tmp6, %tmp5
665 ; (i32) p[i] | ((i32) p[i + 1] << 8) | ((i32) p[i + 2] << 16) | ((i32) p[i + 3] << 24)
666 define i32 @load_i32_by_i8_base_offset_index(ptr %arg, i32 %i) {
667 ; CHECK-LABEL: load_i32_by_i8_base_offset_index:
669 ; CHECK-NEXT: add r0, r0, r1
670 ; CHECK-NEXT: mov r1, #65280
671 ; CHECK-NEXT: ldr r0, [r0, #12]
672 ; CHECK-NEXT: and r2, r0, #65280
673 ; CHECK-NEXT: and r1, r1, r0, lsr #8
674 ; CHECK-NEXT: orr r1, r1, r0, lsr #24
675 ; CHECK-NEXT: lsl r0, r0, #24
676 ; CHECK-NEXT: orr r0, r0, r2, lsl #8
677 ; CHECK-NEXT: orr r0, r0, r1
678 ; CHECK-NEXT: mov pc, lr
680 ; CHECK-ARMv6-LABEL: load_i32_by_i8_base_offset_index:
681 ; CHECK-ARMv6: @ %bb.0:
682 ; CHECK-ARMv6-NEXT: add r0, r0, r1
683 ; CHECK-ARMv6-NEXT: ldr r0, [r0, #12]
684 ; CHECK-ARMv6-NEXT: rev r0, r0
685 ; CHECK-ARMv6-NEXT: bx lr
687 ; CHECK-THUMBv6-LABEL: load_i32_by_i8_base_offset_index:
688 ; CHECK-THUMBv6: @ %bb.0:
689 ; CHECK-THUMBv6-NEXT: adds r0, r0, r1
690 ; CHECK-THUMBv6-NEXT: ldr r0, [r0, #12]
691 ; CHECK-THUMBv6-NEXT: rev r0, r0
692 ; CHECK-THUMBv6-NEXT: bx lr
694 ; CHECK-THUMBv7-LABEL: load_i32_by_i8_base_offset_index:
695 ; CHECK-THUMBv7: @ %bb.0:
696 ; CHECK-THUMBv7-NEXT: adds r0, r0, r1
697 ; CHECK-THUMBv7-NEXT: ldr r0, [r0, #12]
698 ; CHECK-THUMBv7-NEXT: rev r0, r0
699 ; CHECK-THUMBv7-NEXT: bx lr
700 %tmp = add nuw nsw i32 %i, 3
701 %tmp2 = add nuw nsw i32 %i, 2
702 %tmp3 = add nuw nsw i32 %i, 1
703 %tmp4 = getelementptr inbounds i8, ptr %arg, i64 12
704 %tmp5 = zext i32 %i to i64
705 %tmp6 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp5
706 %tmp7 = load i8, ptr %tmp6, align 4
707 %tmp8 = zext i8 %tmp7 to i32
708 %tmp9 = zext i32 %tmp3 to i64
709 %tmp10 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp9
710 %tmp11 = load i8, ptr %tmp10, align 1
711 %tmp12 = zext i8 %tmp11 to i32
712 %tmp13 = shl nuw nsw i32 %tmp12, 8
713 %tmp14 = or i32 %tmp13, %tmp8
714 %tmp15 = zext i32 %tmp2 to i64
715 %tmp16 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp15
716 %tmp17 = load i8, ptr %tmp16, align 1
717 %tmp18 = zext i8 %tmp17 to i32
718 %tmp19 = shl nuw nsw i32 %tmp18, 16
719 %tmp20 = or i32 %tmp14, %tmp19
720 %tmp21 = zext i32 %tmp to i64
721 %tmp22 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp21
722 %tmp23 = load i8, ptr %tmp22, align 1
723 %tmp24 = zext i8 %tmp23 to i32
724 %tmp25 = shl nuw i32 %tmp24, 24
725 %tmp26 = or i32 %tmp20, %tmp25
731 ; (i32) p[i + 1] | ((i32) p[i + 2] << 8) | ((i32) p[i + 3] << 16) | ((i32) p[i + 4] << 24)
732 define i32 @load_i32_by_i8_base_offset_index_2(ptr %arg, i32 %i) {
733 ; CHECK-LABEL: load_i32_by_i8_base_offset_index_2:
735 ; CHECK-NEXT: add r0, r1, r0
736 ; CHECK-NEXT: mov r1, #65280
737 ; CHECK-NEXT: ldr r0, [r0, #13]
738 ; CHECK-NEXT: and r2, r0, #65280
739 ; CHECK-NEXT: and r1, r1, r0, lsr #8
740 ; CHECK-NEXT: orr r1, r1, r0, lsr #24
741 ; CHECK-NEXT: lsl r0, r0, #24
742 ; CHECK-NEXT: orr r0, r0, r2, lsl #8
743 ; CHECK-NEXT: orr r0, r0, r1
744 ; CHECK-NEXT: mov pc, lr
746 ; CHECK-ARMv6-LABEL: load_i32_by_i8_base_offset_index_2:
747 ; CHECK-ARMv6: @ %bb.0:
748 ; CHECK-ARMv6-NEXT: add r0, r1, r0
749 ; CHECK-ARMv6-NEXT: ldr r0, [r0, #13]
750 ; CHECK-ARMv6-NEXT: rev r0, r0
751 ; CHECK-ARMv6-NEXT: bx lr
753 ; CHECK-THUMBv6-LABEL: load_i32_by_i8_base_offset_index_2:
754 ; CHECK-THUMBv6: @ %bb.0:
755 ; CHECK-THUMBv6-NEXT: adds r0, r1, r0
756 ; CHECK-THUMBv6-NEXT: movs r1, #13
757 ; CHECK-THUMBv6-NEXT: ldr r0, [r0, r1]
758 ; CHECK-THUMBv6-NEXT: rev r0, r0
759 ; CHECK-THUMBv6-NEXT: bx lr
761 ; CHECK-THUMBv7-LABEL: load_i32_by_i8_base_offset_index_2:
762 ; CHECK-THUMBv7: @ %bb.0:
763 ; CHECK-THUMBv7-NEXT: adds r0, r1, r0
764 ; CHECK-THUMBv7-NEXT: movs r1, #13
765 ; CHECK-THUMBv7-NEXT: ldr r0, [r0, r1]
766 ; CHECK-THUMBv7-NEXT: rev r0, r0
767 ; CHECK-THUMBv7-NEXT: bx lr
769 %tmp = add nuw nsw i32 %i, 4
770 %tmp2 = add nuw nsw i32 %i, 3
771 %tmp3 = add nuw nsw i32 %i, 2
772 %tmp4 = getelementptr inbounds i8, ptr %arg, i64 12
773 %tmp5 = add nuw nsw i32 %i, 1
774 %tmp27 = zext i32 %tmp5 to i64
775 %tmp28 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp27
776 %tmp29 = load i8, ptr %tmp28, align 4
777 %tmp30 = zext i8 %tmp29 to i32
778 %tmp31 = zext i32 %tmp3 to i64
779 %tmp32 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp31
780 %tmp33 = load i8, ptr %tmp32, align 1
781 %tmp34 = zext i8 %tmp33 to i32
782 %tmp35 = shl nuw nsw i32 %tmp34, 8
783 %tmp36 = or i32 %tmp35, %tmp30
784 %tmp37 = zext i32 %tmp2 to i64
785 %tmp38 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp37
786 %tmp39 = load i8, ptr %tmp38, align 1
787 %tmp40 = zext i8 %tmp39 to i32
788 %tmp41 = shl nuw nsw i32 %tmp40, 16
789 %tmp42 = or i32 %tmp36, %tmp41
790 %tmp43 = zext i32 %tmp to i64
791 %tmp44 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp43
792 %tmp45 = load i8, ptr %tmp44, align 1
793 %tmp46 = zext i8 %tmp45 to i32
794 %tmp47 = shl nuw i32 %tmp46, 24
795 %tmp48 = or i32 %tmp42, %tmp47
799 ; ptr p; // p is 2 byte aligned
800 ; (i32) p[0] | ((i32) p[1] << 8)
801 define i32 @zext_load_i32_by_i8(ptr %arg) {
802 ; CHECK-LABEL: zext_load_i32_by_i8:
804 ; CHECK-NEXT: ldrb r1, [r0]
805 ; CHECK-NEXT: ldrb r0, [r0, #1]
806 ; CHECK-NEXT: orr r0, r1, r0, lsl #8
807 ; CHECK-NEXT: mov pc, lr
809 ; CHECK-ARMv6-LABEL: zext_load_i32_by_i8:
810 ; CHECK-ARMv6: @ %bb.0:
811 ; CHECK-ARMv6-NEXT: ldrh r0, [r0]
812 ; CHECK-ARMv6-NEXT: rev16 r0, r0
813 ; CHECK-ARMv6-NEXT: bx lr
815 ; CHECK-THUMBv6-LABEL: zext_load_i32_by_i8:
816 ; CHECK-THUMBv6: @ %bb.0:
817 ; CHECK-THUMBv6-NEXT: ldrh r0, [r0]
818 ; CHECK-THUMBv6-NEXT: rev16 r0, r0
819 ; CHECK-THUMBv6-NEXT: bx lr
821 ; CHECK-THUMBv7-LABEL: zext_load_i32_by_i8:
822 ; CHECK-THUMBv7: @ %bb.0:
823 ; CHECK-THUMBv7-NEXT: ldrh r0, [r0]
824 ; CHECK-THUMBv7-NEXT: rev16 r0, r0
825 ; CHECK-THUMBv7-NEXT: bx lr
827 %tmp2 = load i8, ptr %arg, align 2
828 %tmp3 = zext i8 %tmp2 to i32
829 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 1
830 %tmp5 = load i8, ptr %tmp4, align 1
831 %tmp6 = zext i8 %tmp5 to i32
832 %tmp7 = shl nuw nsw i32 %tmp6, 8
833 %tmp8 = or i32 %tmp7, %tmp3
837 ; ptr p; // p is 2 byte aligned
838 ; ((i32) p[0] << 8) | ((i32) p[1] << 16)
839 define i32 @zext_load_i32_by_i8_shl_8(ptr %arg) {
840 ; CHECK-LABEL: zext_load_i32_by_i8_shl_8:
842 ; CHECK-NEXT: ldrb r1, [r0]
843 ; CHECK-NEXT: ldrb r0, [r0, #1]
844 ; CHECK-NEXT: lsl r0, r0, #16
845 ; CHECK-NEXT: orr r0, r0, r1, lsl #8
846 ; CHECK-NEXT: mov pc, lr
848 ; CHECK-ARMv6-LABEL: zext_load_i32_by_i8_shl_8:
849 ; CHECK-ARMv6: @ %bb.0:
850 ; CHECK-ARMv6-NEXT: ldrb r1, [r0]
851 ; CHECK-ARMv6-NEXT: ldrb r0, [r0, #1]
852 ; CHECK-ARMv6-NEXT: lsl r0, r0, #16
853 ; CHECK-ARMv6-NEXT: orr r0, r0, r1, lsl #8
854 ; CHECK-ARMv6-NEXT: bx lr
856 ; CHECK-THUMBv6-LABEL: zext_load_i32_by_i8_shl_8:
857 ; CHECK-THUMBv6: @ %bb.0:
858 ; CHECK-THUMBv6-NEXT: ldrb r1, [r0]
859 ; CHECK-THUMBv6-NEXT: lsls r1, r1, #8
860 ; CHECK-THUMBv6-NEXT: ldrb r0, [r0, #1]
861 ; CHECK-THUMBv6-NEXT: lsls r0, r0, #16
862 ; CHECK-THUMBv6-NEXT: adds r0, r0, r1
863 ; CHECK-THUMBv6-NEXT: bx lr
865 ; CHECK-THUMBv7-LABEL: zext_load_i32_by_i8_shl_8:
866 ; CHECK-THUMBv7: @ %bb.0:
867 ; CHECK-THUMBv7-NEXT: ldrb r1, [r0]
868 ; CHECK-THUMBv7-NEXT: lsls r1, r1, #8
869 ; CHECK-THUMBv7-NEXT: ldrb r0, [r0, #1]
870 ; CHECK-THUMBv7-NEXT: lsls r0, r0, #16
871 ; CHECK-THUMBv7-NEXT: adds r0, r0, r1
872 ; CHECK-THUMBv7-NEXT: bx lr
874 %tmp2 = load i8, ptr %arg, align 2
875 %tmp3 = zext i8 %tmp2 to i32
876 %tmp30 = shl nuw nsw i32 %tmp3, 8
877 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 1
878 %tmp5 = load i8, ptr %tmp4, align 1
879 %tmp6 = zext i8 %tmp5 to i32
880 %tmp7 = shl nuw nsw i32 %tmp6, 16
881 %tmp8 = or i32 %tmp7, %tmp30
885 ; ptr p; // p is 2 byte aligned
886 ; ((i32) p[0] << 16) | ((i32) p[1] << 24)
887 define i32 @zext_load_i32_by_i8_shl_16(ptr %arg) {
888 ; CHECK-LABEL: zext_load_i32_by_i8_shl_16:
890 ; CHECK-NEXT: ldrb r1, [r0]
891 ; CHECK-NEXT: ldrb r0, [r0, #1]
892 ; CHECK-NEXT: lsl r0, r0, #24
893 ; CHECK-NEXT: orr r0, r0, r1, lsl #16
894 ; CHECK-NEXT: mov pc, lr
896 ; CHECK-ARMv6-LABEL: zext_load_i32_by_i8_shl_16:
897 ; CHECK-ARMv6: @ %bb.0:
898 ; CHECK-ARMv6-NEXT: ldrb r1, [r0]
899 ; CHECK-ARMv6-NEXT: ldrb r0, [r0, #1]
900 ; CHECK-ARMv6-NEXT: lsl r0, r0, #24
901 ; CHECK-ARMv6-NEXT: orr r0, r0, r1, lsl #16
902 ; CHECK-ARMv6-NEXT: bx lr
904 ; CHECK-THUMBv6-LABEL: zext_load_i32_by_i8_shl_16:
905 ; CHECK-THUMBv6: @ %bb.0:
906 ; CHECK-THUMBv6-NEXT: ldrb r1, [r0]
907 ; CHECK-THUMBv6-NEXT: lsls r1, r1, #16
908 ; CHECK-THUMBv6-NEXT: ldrb r0, [r0, #1]
909 ; CHECK-THUMBv6-NEXT: lsls r0, r0, #24
910 ; CHECK-THUMBv6-NEXT: adds r0, r0, r1
911 ; CHECK-THUMBv6-NEXT: bx lr
913 ; CHECK-THUMBv7-LABEL: zext_load_i32_by_i8_shl_16:
914 ; CHECK-THUMBv7: @ %bb.0:
915 ; CHECK-THUMBv7-NEXT: ldrb r1, [r0]
916 ; CHECK-THUMBv7-NEXT: lsls r1, r1, #16
917 ; CHECK-THUMBv7-NEXT: ldrb r0, [r0, #1]
918 ; CHECK-THUMBv7-NEXT: lsls r0, r0, #24
919 ; CHECK-THUMBv7-NEXT: adds r0, r0, r1
920 ; CHECK-THUMBv7-NEXT: bx lr
922 %tmp2 = load i8, ptr %arg, align 2
923 %tmp3 = zext i8 %tmp2 to i32
924 %tmp30 = shl nuw nsw i32 %tmp3, 16
925 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 1
926 %tmp5 = load i8, ptr %tmp4, align 1
927 %tmp6 = zext i8 %tmp5 to i32
928 %tmp7 = shl nuw nsw i32 %tmp6, 24
929 %tmp8 = or i32 %tmp7, %tmp30
933 ; ptr p; // p is 2 byte aligned
934 ; (i32) p[1] | ((i32) p[0] << 8)
935 define i32 @zext_load_i32_by_i8_bswap(ptr %arg) {
936 ; CHECK-LABEL: zext_load_i32_by_i8_bswap:
938 ; CHECK-NEXT: ldrh r0, [r0]
939 ; CHECK-NEXT: mov pc, lr
941 ; CHECK-ARMv6-LABEL: zext_load_i32_by_i8_bswap:
942 ; CHECK-ARMv6: @ %bb.0:
943 ; CHECK-ARMv6-NEXT: ldrh r0, [r0]
944 ; CHECK-ARMv6-NEXT: bx lr
946 ; CHECK-THUMBv6-LABEL: zext_load_i32_by_i8_bswap:
947 ; CHECK-THUMBv6: @ %bb.0:
948 ; CHECK-THUMBv6-NEXT: ldrh r0, [r0]
949 ; CHECK-THUMBv6-NEXT: bx lr
951 ; CHECK-THUMBv7-LABEL: zext_load_i32_by_i8_bswap:
952 ; CHECK-THUMBv7: @ %bb.0:
953 ; CHECK-THUMBv7-NEXT: ldrh r0, [r0]
954 ; CHECK-THUMBv7-NEXT: bx lr
956 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 1
957 %tmp2 = load i8, ptr %tmp1, align 1
958 %tmp3 = zext i8 %tmp2 to i32
959 %tmp5 = load i8, ptr %arg, align 2
960 %tmp6 = zext i8 %tmp5 to i32
961 %tmp7 = shl nuw nsw i32 %tmp6, 8
962 %tmp8 = or i32 %tmp7, %tmp3
966 ; ptr p; // p is 2 byte aligned
967 ; ((i32) p[1] << 8) | ((i32) p[0] << 16)
968 define i32 @zext_load_i32_by_i8_bswap_shl_8(ptr %arg) {
969 ; CHECK-LABEL: zext_load_i32_by_i8_bswap_shl_8:
971 ; CHECK-NEXT: ldrb r1, [r0]
972 ; CHECK-NEXT: ldrb r0, [r0, #1]
973 ; CHECK-NEXT: lsl r1, r1, #16
974 ; CHECK-NEXT: orr r0, r1, r0, lsl #8
975 ; CHECK-NEXT: mov pc, lr
977 ; CHECK-ARMv6-LABEL: zext_load_i32_by_i8_bswap_shl_8:
978 ; CHECK-ARMv6: @ %bb.0:
979 ; CHECK-ARMv6-NEXT: ldrb r1, [r0]
980 ; CHECK-ARMv6-NEXT: ldrb r0, [r0, #1]
981 ; CHECK-ARMv6-NEXT: lsl r1, r1, #16
982 ; CHECK-ARMv6-NEXT: orr r0, r1, r0, lsl #8
983 ; CHECK-ARMv6-NEXT: bx lr
985 ; CHECK-THUMBv6-LABEL: zext_load_i32_by_i8_bswap_shl_8:
986 ; CHECK-THUMBv6: @ %bb.0:
987 ; CHECK-THUMBv6-NEXT: ldrb r1, [r0, #1]
988 ; CHECK-THUMBv6-NEXT: lsls r1, r1, #8
989 ; CHECK-THUMBv6-NEXT: ldrb r0, [r0]
990 ; CHECK-THUMBv6-NEXT: lsls r0, r0, #16
991 ; CHECK-THUMBv6-NEXT: adds r0, r0, r1
992 ; CHECK-THUMBv6-NEXT: bx lr
994 ; CHECK-THUMBv7-LABEL: zext_load_i32_by_i8_bswap_shl_8:
995 ; CHECK-THUMBv7: @ %bb.0:
996 ; CHECK-THUMBv7-NEXT: ldrb r1, [r0, #1]
997 ; CHECK-THUMBv7-NEXT: lsls r1, r1, #8
998 ; CHECK-THUMBv7-NEXT: ldrb r0, [r0]
999 ; CHECK-THUMBv7-NEXT: lsls r0, r0, #16
1000 ; CHECK-THUMBv7-NEXT: adds r0, r0, r1
1001 ; CHECK-THUMBv7-NEXT: bx lr
1003 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 1
1004 %tmp2 = load i8, ptr %tmp1, align 1
1005 %tmp3 = zext i8 %tmp2 to i32
1006 %tmp30 = shl nuw nsw i32 %tmp3, 8
1007 %tmp5 = load i8, ptr %arg, align 2
1008 %tmp6 = zext i8 %tmp5 to i32
1009 %tmp7 = shl nuw nsw i32 %tmp6, 16
1010 %tmp8 = or i32 %tmp7, %tmp30
1014 ; ptr p; // p is 2 byte aligned
1015 ; ((i32) p[1] << 16) | ((i32) p[0] << 24)
1016 define i32 @zext_load_i32_by_i8_bswap_shl_16(ptr %arg) {
1017 ; CHECK-LABEL: zext_load_i32_by_i8_bswap_shl_16:
1019 ; CHECK-NEXT: ldrb r1, [r0]
1020 ; CHECK-NEXT: ldrb r0, [r0, #1]
1021 ; CHECK-NEXT: lsl r1, r1, #24
1022 ; CHECK-NEXT: orr r0, r1, r0, lsl #16
1023 ; CHECK-NEXT: mov pc, lr
1025 ; CHECK-ARMv6-LABEL: zext_load_i32_by_i8_bswap_shl_16:
1026 ; CHECK-ARMv6: @ %bb.0:
1027 ; CHECK-ARMv6-NEXT: ldrb r1, [r0]
1028 ; CHECK-ARMv6-NEXT: ldrb r0, [r0, #1]
1029 ; CHECK-ARMv6-NEXT: lsl r1, r1, #24
1030 ; CHECK-ARMv6-NEXT: orr r0, r1, r0, lsl #16
1031 ; CHECK-ARMv6-NEXT: bx lr
1033 ; CHECK-THUMBv6-LABEL: zext_load_i32_by_i8_bswap_shl_16:
1034 ; CHECK-THUMBv6: @ %bb.0:
1035 ; CHECK-THUMBv6-NEXT: ldrb r1, [r0, #1]
1036 ; CHECK-THUMBv6-NEXT: lsls r1, r1, #16
1037 ; CHECK-THUMBv6-NEXT: ldrb r0, [r0]
1038 ; CHECK-THUMBv6-NEXT: lsls r0, r0, #24
1039 ; CHECK-THUMBv6-NEXT: adds r0, r0, r1
1040 ; CHECK-THUMBv6-NEXT: bx lr
1042 ; CHECK-THUMBv7-LABEL: zext_load_i32_by_i8_bswap_shl_16:
1043 ; CHECK-THUMBv7: @ %bb.0:
1044 ; CHECK-THUMBv7-NEXT: ldrb r1, [r0, #1]
1045 ; CHECK-THUMBv7-NEXT: lsls r1, r1, #16
1046 ; CHECK-THUMBv7-NEXT: ldrb r0, [r0]
1047 ; CHECK-THUMBv7-NEXT: lsls r0, r0, #24
1048 ; CHECK-THUMBv7-NEXT: adds r0, r0, r1
1049 ; CHECK-THUMBv7-NEXT: bx lr
1051 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 1
1052 %tmp2 = load i8, ptr %tmp1, align 1
1053 %tmp3 = zext i8 %tmp2 to i32
1054 %tmp30 = shl nuw nsw i32 %tmp3, 16
1055 %tmp5 = load i8, ptr %arg, align 2
1056 %tmp6 = zext i8 %tmp5 to i32
1057 %tmp7 = shl nuw nsw i32 %tmp6, 24
1058 %tmp8 = or i32 %tmp7, %tmp30
1063 ; ptr p1.i16 = (ptr) p;
1064 ; (p1.i16[0] << 8) | ((i16) p[2])
1066 ; This is essentialy a i16 load from p[1], but we don't fold the pattern now
1067 ; because in the original DAG we don't have p[1] address available
1068 define i16 @load_i16_from_nonzero_offset(ptr %p) {
1069 ; CHECK-LABEL: load_i16_from_nonzero_offset:
1071 ; CHECK-NEXT: ldrh r1, [r0]
1072 ; CHECK-NEXT: ldrb r0, [r0, #2]
1073 ; CHECK-NEXT: orr r0, r0, r1, lsl #8
1074 ; CHECK-NEXT: mov pc, lr
1076 ; CHECK-ARMv6-LABEL: load_i16_from_nonzero_offset:
1077 ; CHECK-ARMv6: @ %bb.0:
1078 ; CHECK-ARMv6-NEXT: ldrh r1, [r0]
1079 ; CHECK-ARMv6-NEXT: ldrb r0, [r0, #2]
1080 ; CHECK-ARMv6-NEXT: orr r0, r0, r1, lsl #8
1081 ; CHECK-ARMv6-NEXT: bx lr
1083 ; CHECK-THUMBv6-LABEL: load_i16_from_nonzero_offset:
1084 ; CHECK-THUMBv6: @ %bb.0:
1085 ; CHECK-THUMBv6-NEXT: ldrb r1, [r0, #2]
1086 ; CHECK-THUMBv6-NEXT: ldrh r0, [r0]
1087 ; CHECK-THUMBv6-NEXT: lsls r0, r0, #8
1088 ; CHECK-THUMBv6-NEXT: adds r0, r0, r1
1089 ; CHECK-THUMBv6-NEXT: bx lr
1091 ; CHECK-THUMBv7-LABEL: load_i16_from_nonzero_offset:
1092 ; CHECK-THUMBv7: @ %bb.0:
1093 ; CHECK-THUMBv7-NEXT: ldrb r1, [r0, #2]
1094 ; CHECK-THUMBv7-NEXT: ldrh r0, [r0]
1095 ; CHECK-THUMBv7-NEXT: lsls r0, r0, #8
1096 ; CHECK-THUMBv7-NEXT: adds r0, r0, r1
1097 ; CHECK-THUMBv7-NEXT: bx lr
1099 %p2.i8 = getelementptr i8, ptr %p, i64 2
1100 %v1 = load i16, ptr %p
1101 %v2.i8 = load i8, ptr %p2.i8
1102 %v2 = zext i8 %v2.i8 to i16
1103 %v1.shl = shl i16 %v1, 8
1104 %res = or i16 %v1.shl, %v2