1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=arm-unknown | FileCheck %s
3 ; RUN: llc < %s -mtriple=armv6-unknown | FileCheck %s --check-prefix=CHECK-ARMv6
4 ; RUN: llc < %s -mtriple=thumbv6m-none-eabi | FileCheck %s --check-prefix=CHECK-THUMBv6
5 ; RUN: llc < %s -mtriple=thumbv7m-none-eabi | FileCheck %s --check-prefix=CHECK-THUMBv7
7 ; ptr p; // p is 1 byte aligned
8 ; (i32) p[0] | ((i32) p[1] << 8) | ((i32) p[2] << 16) | ((i32) p[3] << 24)
9 define i32 @load_i32_by_i8_unaligned(ptr %arg) {
10 ; CHECK-LABEL: load_i32_by_i8_unaligned:
12 ; CHECK-NEXT: ldrb r2, [r0, #1]
13 ; CHECK-NEXT: ldrb r1, [r0]
14 ; CHECK-NEXT: ldrb r3, [r0, #2]
15 ; CHECK-NEXT: ldrb r0, [r0, #3]
16 ; CHECK-NEXT: orr r1, r1, r2, lsl #8
17 ; CHECK-NEXT: orr r1, r1, r3, lsl #16
18 ; CHECK-NEXT: orr r0, r1, r0, lsl #24
19 ; CHECK-NEXT: mov pc, lr
21 ; CHECK-ARMv6-LABEL: load_i32_by_i8_unaligned:
22 ; CHECK-ARMv6: @ %bb.0:
23 ; CHECK-ARMv6-NEXT: ldrb r2, [r0, #1]
24 ; CHECK-ARMv6-NEXT: ldrb r1, [r0]
25 ; CHECK-ARMv6-NEXT: ldrb r3, [r0, #2]
26 ; CHECK-ARMv6-NEXT: ldrb r0, [r0, #3]
27 ; CHECK-ARMv6-NEXT: orr r1, r1, r2, lsl #8
28 ; CHECK-ARMv6-NEXT: orr r1, r1, r3, lsl #16
29 ; CHECK-ARMv6-NEXT: orr r0, r1, r0, lsl #24
30 ; CHECK-ARMv6-NEXT: bx lr
32 ; CHECK-THUMBv6-LABEL: load_i32_by_i8_unaligned:
33 ; CHECK-THUMBv6: @ %bb.0:
34 ; CHECK-THUMBv6-NEXT: ldrb r1, [r0]
35 ; CHECK-THUMBv6-NEXT: ldrb r2, [r0, #1]
36 ; CHECK-THUMBv6-NEXT: lsls r2, r2, #8
37 ; CHECK-THUMBv6-NEXT: adds r1, r2, r1
38 ; CHECK-THUMBv6-NEXT: ldrb r2, [r0, #2]
39 ; CHECK-THUMBv6-NEXT: lsls r2, r2, #16
40 ; CHECK-THUMBv6-NEXT: adds r1, r1, r2
41 ; CHECK-THUMBv6-NEXT: ldrb r0, [r0, #3]
42 ; CHECK-THUMBv6-NEXT: lsls r0, r0, #24
43 ; CHECK-THUMBv6-NEXT: adds r0, r1, r0
44 ; CHECK-THUMBv6-NEXT: bx lr
46 ; CHECK-THUMBv7-LABEL: load_i32_by_i8_unaligned:
47 ; CHECK-THUMBv7: @ %bb.0:
48 ; CHECK-THUMBv7-NEXT: ldr r0, [r0]
49 ; CHECK-THUMBv7-NEXT: bx lr
51 %tmp2 = load i8, ptr %arg, align 1
52 %tmp3 = zext i8 %tmp2 to i32
53 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 1
54 %tmp5 = load i8, ptr %tmp4, align 1
55 %tmp6 = zext i8 %tmp5 to i32
56 %tmp7 = shl nuw nsw i32 %tmp6, 8
57 %tmp8 = or i32 %tmp7, %tmp3
58 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 2
59 %tmp10 = load i8, ptr %tmp9, align 1
60 %tmp11 = zext i8 %tmp10 to i32
61 %tmp12 = shl nuw nsw i32 %tmp11, 16
62 %tmp13 = or i32 %tmp8, %tmp12
63 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 3
64 %tmp15 = load i8, ptr %tmp14, align 1
65 %tmp16 = zext i8 %tmp15 to i32
66 %tmp17 = shl nuw nsw i32 %tmp16, 24
67 %tmp18 = or i32 %tmp13, %tmp17
71 ; ptr p; // p is 4 byte aligned
72 ; (i32) p[0] | ((i32) p[1] << 8) | ((i32) p[2] << 16) | ((i32) p[3] << 24)
73 define i32 @load_i32_by_i8_aligned(ptr %arg) {
74 ; CHECK-LABEL: load_i32_by_i8_aligned:
76 ; CHECK-NEXT: ldr r0, [r0]
77 ; CHECK-NEXT: mov pc, lr
79 ; CHECK-ARMv6-LABEL: load_i32_by_i8_aligned:
80 ; CHECK-ARMv6: @ %bb.0:
81 ; CHECK-ARMv6-NEXT: ldr r0, [r0]
82 ; CHECK-ARMv6-NEXT: bx lr
84 ; CHECK-THUMBv6-LABEL: load_i32_by_i8_aligned:
85 ; CHECK-THUMBv6: @ %bb.0:
86 ; CHECK-THUMBv6-NEXT: ldr r0, [r0]
87 ; CHECK-THUMBv6-NEXT: bx lr
89 ; CHECK-THUMBv7-LABEL: load_i32_by_i8_aligned:
90 ; CHECK-THUMBv7: @ %bb.0:
91 ; CHECK-THUMBv7-NEXT: ldr r0, [r0]
92 ; CHECK-THUMBv7-NEXT: bx lr
94 %tmp2 = load i8, ptr %arg, align 4
95 %tmp3 = zext i8 %tmp2 to i32
96 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 1
97 %tmp5 = load i8, ptr %tmp4, align 1
98 %tmp6 = zext i8 %tmp5 to i32
99 %tmp7 = shl nuw nsw i32 %tmp6, 8
100 %tmp8 = or i32 %tmp7, %tmp3
101 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 2
102 %tmp10 = load i8, ptr %tmp9, align 1
103 %tmp11 = zext i8 %tmp10 to i32
104 %tmp12 = shl nuw nsw i32 %tmp11, 16
105 %tmp13 = or i32 %tmp8, %tmp12
106 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 3
107 %tmp15 = load i8, ptr %tmp14, align 1
108 %tmp16 = zext i8 %tmp15 to i32
109 %tmp17 = shl nuw nsw i32 %tmp16, 24
110 %tmp18 = or i32 %tmp13, %tmp17
114 ; ptr p; // p is 4 byte aligned
115 ; ((i32) p[0] << 24) | ((i32) p[1] << 16) | ((i32) p[2] << 8) | (i32) p[3]
116 define i32 @load_i32_by_i8_bswap(ptr %arg) {
117 ; BSWAP is not supported by 32 bit target
118 ; CHECK-LABEL: load_i32_by_i8_bswap:
120 ; CHECK-NEXT: ldr r0, [r0]
121 ; CHECK-NEXT: mov r1, #65280
122 ; CHECK-NEXT: and r2, r0, #65280
123 ; CHECK-NEXT: and r1, r1, r0, lsr #8
124 ; CHECK-NEXT: orr r1, r1, r0, lsr #24
125 ; CHECK-NEXT: lsl r0, r0, #24
126 ; CHECK-NEXT: orr r0, r0, r2, lsl #8
127 ; CHECK-NEXT: orr r0, r0, r1
128 ; CHECK-NEXT: mov pc, lr
130 ; CHECK-ARMv6-LABEL: load_i32_by_i8_bswap:
131 ; CHECK-ARMv6: @ %bb.0:
132 ; CHECK-ARMv6-NEXT: ldr r0, [r0]
133 ; CHECK-ARMv6-NEXT: rev r0, r0
134 ; CHECK-ARMv6-NEXT: bx lr
136 ; CHECK-THUMBv6-LABEL: load_i32_by_i8_bswap:
137 ; CHECK-THUMBv6: @ %bb.0:
138 ; CHECK-THUMBv6-NEXT: ldr r0, [r0]
139 ; CHECK-THUMBv6-NEXT: rev r0, r0
140 ; CHECK-THUMBv6-NEXT: bx lr
142 ; CHECK-THUMBv7-LABEL: load_i32_by_i8_bswap:
143 ; CHECK-THUMBv7: @ %bb.0:
144 ; CHECK-THUMBv7-NEXT: ldr r0, [r0]
145 ; CHECK-THUMBv7-NEXT: rev r0, r0
146 ; CHECK-THUMBv7-NEXT: bx lr
148 %tmp1 = load i8, ptr %arg, align 4
149 %tmp2 = zext i8 %tmp1 to i32
150 %tmp3 = shl nuw nsw i32 %tmp2, 24
151 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 1
152 %tmp5 = load i8, ptr %tmp4, align 1
153 %tmp6 = zext i8 %tmp5 to i32
154 %tmp7 = shl nuw nsw i32 %tmp6, 16
155 %tmp8 = or i32 %tmp7, %tmp3
156 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 2
157 %tmp10 = load i8, ptr %tmp9, align 1
158 %tmp11 = zext i8 %tmp10 to i32
159 %tmp12 = shl nuw nsw i32 %tmp11, 8
160 %tmp13 = or i32 %tmp8, %tmp12
161 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 3
162 %tmp15 = load i8, ptr %tmp14, align 1
163 %tmp16 = zext i8 %tmp15 to i32
164 %tmp17 = or i32 %tmp13, %tmp16
168 ; ptr p; // p is 8 byte aligned
169 ; (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)
170 define i64 @load_i64_by_i8(ptr %arg) {
171 ; CHECK-LABEL: load_i64_by_i8:
173 ; CHECK-NEXT: ldr r2, [r0]
174 ; CHECK-NEXT: ldr r1, [r0, #4]
175 ; CHECK-NEXT: mov r0, r2
176 ; CHECK-NEXT: mov pc, lr
178 ; CHECK-ARMv6-LABEL: load_i64_by_i8:
179 ; CHECK-ARMv6: @ %bb.0:
180 ; CHECK-ARMv6-NEXT: ldrd r0, r1, [r0]
181 ; CHECK-ARMv6-NEXT: bx lr
183 ; CHECK-THUMBv6-LABEL: load_i64_by_i8:
184 ; CHECK-THUMBv6: @ %bb.0:
185 ; CHECK-THUMBv6-NEXT: ldr r2, [r0]
186 ; CHECK-THUMBv6-NEXT: ldr r1, [r0, #4]
187 ; CHECK-THUMBv6-NEXT: mov r0, r2
188 ; CHECK-THUMBv6-NEXT: bx lr
190 ; CHECK-THUMBv7-LABEL: load_i64_by_i8:
191 ; CHECK-THUMBv7: @ %bb.0:
192 ; CHECK-THUMBv7-NEXT: ldrd r0, r1, [r0]
193 ; CHECK-THUMBv7-NEXT: bx lr
195 %tmp1 = load i8, ptr %arg, align 8
196 %tmp2 = zext i8 %tmp1 to i64
197 %tmp3 = getelementptr inbounds i8, ptr %arg, i64 1
198 %tmp4 = load i8, ptr %tmp3, align 1
199 %tmp5 = zext i8 %tmp4 to i64
200 %tmp6 = shl nuw nsw i64 %tmp5, 8
201 %tmp7 = or i64 %tmp6, %tmp2
202 %tmp8 = getelementptr inbounds i8, ptr %arg, i64 2
203 %tmp9 = load i8, ptr %tmp8, align 1
204 %tmp10 = zext i8 %tmp9 to i64
205 %tmp11 = shl nuw nsw i64 %tmp10, 16
206 %tmp12 = or i64 %tmp7, %tmp11
207 %tmp13 = getelementptr inbounds i8, ptr %arg, i64 3
208 %tmp14 = load i8, ptr %tmp13, align 1
209 %tmp15 = zext i8 %tmp14 to i64
210 %tmp16 = shl nuw nsw i64 %tmp15, 24
211 %tmp17 = or i64 %tmp12, %tmp16
212 %tmp18 = getelementptr inbounds i8, ptr %arg, i64 4
213 %tmp19 = load i8, ptr %tmp18, align 1
214 %tmp20 = zext i8 %tmp19 to i64
215 %tmp21 = shl nuw nsw i64 %tmp20, 32
216 %tmp22 = or i64 %tmp17, %tmp21
217 %tmp23 = getelementptr inbounds i8, ptr %arg, i64 5
218 %tmp24 = load i8, ptr %tmp23, align 1
219 %tmp25 = zext i8 %tmp24 to i64
220 %tmp26 = shl nuw nsw i64 %tmp25, 40
221 %tmp27 = or i64 %tmp22, %tmp26
222 %tmp28 = getelementptr inbounds i8, ptr %arg, i64 6
223 %tmp29 = load i8, ptr %tmp28, align 1
224 %tmp30 = zext i8 %tmp29 to i64
225 %tmp31 = shl nuw nsw i64 %tmp30, 48
226 %tmp32 = or i64 %tmp27, %tmp31
227 %tmp33 = getelementptr inbounds i8, ptr %arg, i64 7
228 %tmp34 = load i8, ptr %tmp33, align 1
229 %tmp35 = zext i8 %tmp34 to i64
230 %tmp36 = shl nuw i64 %tmp35, 56
231 %tmp37 = or i64 %tmp32, %tmp36
235 ; ptr p; // p is 8 byte aligned
236 ; ((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]
237 define i64 @load_i64_by_i8_bswap(ptr %arg) {
238 ; CHECK-LABEL: load_i64_by_i8_bswap:
240 ; CHECK-NEXT: ldr r1, [r0]
241 ; CHECK-NEXT: mov r12, #65280
242 ; CHECK-NEXT: ldr r0, [r0, #4]
243 ; CHECK-NEXT: and r2, r0, #65280
244 ; CHECK-NEXT: and r3, r12, r0, lsr #8
245 ; CHECK-NEXT: orr r3, r3, r0, lsr #24
246 ; CHECK-NEXT: lsl r0, r0, #24
247 ; CHECK-NEXT: orr r0, r0, r2, lsl #8
248 ; CHECK-NEXT: and r2, r12, r1, lsr #8
249 ; CHECK-NEXT: orr r0, r0, r3
250 ; CHECK-NEXT: and r3, r1, #65280
251 ; CHECK-NEXT: orr r2, r2, r1, lsr #24
252 ; CHECK-NEXT: lsl r1, r1, #24
253 ; CHECK-NEXT: orr r1, r1, r3, lsl #8
254 ; CHECK-NEXT: orr r1, r1, r2
255 ; CHECK-NEXT: mov pc, lr
257 ; CHECK-ARMv6-LABEL: load_i64_by_i8_bswap:
258 ; CHECK-ARMv6: @ %bb.0:
259 ; CHECK-ARMv6-NEXT: ldrd r2, r3, [r0]
260 ; CHECK-ARMv6-NEXT: rev r0, r3
261 ; CHECK-ARMv6-NEXT: rev r1, r2
262 ; CHECK-ARMv6-NEXT: bx lr
264 ; CHECK-THUMBv6-LABEL: load_i64_by_i8_bswap:
265 ; CHECK-THUMBv6: @ %bb.0:
266 ; CHECK-THUMBv6-NEXT: ldr r1, [r0]
267 ; CHECK-THUMBv6-NEXT: ldr r0, [r0, #4]
268 ; CHECK-THUMBv6-NEXT: rev r0, r0
269 ; CHECK-THUMBv6-NEXT: rev r1, r1
270 ; CHECK-THUMBv6-NEXT: bx lr
272 ; CHECK-THUMBv7-LABEL: load_i64_by_i8_bswap:
273 ; CHECK-THUMBv7: @ %bb.0:
274 ; CHECK-THUMBv7-NEXT: ldrd r1, r0, [r0]
275 ; CHECK-THUMBv7-NEXT: rev r0, r0
276 ; CHECK-THUMBv7-NEXT: rev r1, r1
277 ; CHECK-THUMBv7-NEXT: bx lr
279 %tmp1 = load i8, ptr %arg, align 8
280 %tmp2 = zext i8 %tmp1 to i64
281 %tmp3 = shl nuw i64 %tmp2, 56
282 %tmp4 = getelementptr inbounds i8, ptr %arg, i64 1
283 %tmp5 = load i8, ptr %tmp4, align 1
284 %tmp6 = zext i8 %tmp5 to i64
285 %tmp7 = shl nuw nsw i64 %tmp6, 48
286 %tmp8 = or i64 %tmp7, %tmp3
287 %tmp9 = getelementptr inbounds i8, ptr %arg, i64 2
288 %tmp10 = load i8, ptr %tmp9, align 1
289 %tmp11 = zext i8 %tmp10 to i64
290 %tmp12 = shl nuw nsw i64 %tmp11, 40
291 %tmp13 = or i64 %tmp8, %tmp12
292 %tmp14 = getelementptr inbounds i8, ptr %arg, i64 3
293 %tmp15 = load i8, ptr %tmp14, align 1
294 %tmp16 = zext i8 %tmp15 to i64
295 %tmp17 = shl nuw nsw i64 %tmp16, 32
296 %tmp18 = or i64 %tmp13, %tmp17
297 %tmp19 = getelementptr inbounds i8, ptr %arg, i64 4
298 %tmp20 = load i8, ptr %tmp19, align 1
299 %tmp21 = zext i8 %tmp20 to i64
300 %tmp22 = shl nuw nsw i64 %tmp21, 24
301 %tmp23 = or i64 %tmp18, %tmp22
302 %tmp24 = getelementptr inbounds i8, ptr %arg, i64 5
303 %tmp25 = load i8, ptr %tmp24, align 1
304 %tmp26 = zext i8 %tmp25 to i64
305 %tmp27 = shl nuw nsw i64 %tmp26, 16
306 %tmp28 = or i64 %tmp23, %tmp27
307 %tmp29 = getelementptr inbounds i8, ptr %arg, i64 6
308 %tmp30 = load i8, ptr %tmp29, align 1
309 %tmp31 = zext i8 %tmp30 to i64
310 %tmp32 = shl nuw nsw i64 %tmp31, 8
311 %tmp33 = or i64 %tmp28, %tmp32
312 %tmp34 = getelementptr inbounds i8, ptr %arg, i64 7
313 %tmp35 = load i8, ptr %tmp34, align 1
314 %tmp36 = zext i8 %tmp35 to i64
315 %tmp37 = or i64 %tmp33, %tmp36
319 ; ptr p; // p[1] is 4 byte aligned
320 ; (i32) p[1] | ((i32) p[2] << 8) | ((i32) p[3] << 16) | ((i32) p[4] << 24)
321 define i32 @load_i32_by_i8_nonzero_offset(ptr %arg) {
322 ; CHECK-LABEL: load_i32_by_i8_nonzero_offset:
324 ; CHECK-NEXT: ldr r0, [r0, #1]
325 ; CHECK-NEXT: mov pc, lr
327 ; CHECK-ARMv6-LABEL: load_i32_by_i8_nonzero_offset:
328 ; CHECK-ARMv6: @ %bb.0:
329 ; CHECK-ARMv6-NEXT: ldr r0, [r0, #1]
330 ; CHECK-ARMv6-NEXT: bx lr
332 ; CHECK-THUMBv6-LABEL: load_i32_by_i8_nonzero_offset:
333 ; CHECK-THUMBv6: @ %bb.0:
334 ; CHECK-THUMBv6-NEXT: movs r1, #1
335 ; CHECK-THUMBv6-NEXT: ldr r0, [r0, r1]
336 ; CHECK-THUMBv6-NEXT: bx lr
338 ; CHECK-THUMBv7-LABEL: load_i32_by_i8_nonzero_offset:
339 ; CHECK-THUMBv7: @ %bb.0:
340 ; CHECK-THUMBv7-NEXT: ldr.w r0, [r0, #1]
341 ; CHECK-THUMBv7-NEXT: bx lr
344 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 1
345 %tmp2 = load i8, ptr %tmp1, align 4
346 %tmp3 = zext i8 %tmp2 to i32
347 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 2
348 %tmp5 = load i8, ptr %tmp4, align 1
349 %tmp6 = zext i8 %tmp5 to i32
350 %tmp7 = shl nuw nsw i32 %tmp6, 8
351 %tmp8 = or i32 %tmp7, %tmp3
352 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 3
353 %tmp10 = load i8, ptr %tmp9, align 1
354 %tmp11 = zext i8 %tmp10 to i32
355 %tmp12 = shl nuw nsw i32 %tmp11, 16
356 %tmp13 = or i32 %tmp8, %tmp12
357 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 4
358 %tmp15 = load i8, ptr %tmp14, align 1
359 %tmp16 = zext i8 %tmp15 to i32
360 %tmp17 = shl nuw nsw i32 %tmp16, 24
361 %tmp18 = or i32 %tmp13, %tmp17
365 ; ptr p; // p[-4] is 4 byte aligned
366 ; (i32) p[-4] | ((i32) p[-3] << 8) | ((i32) p[-2] << 16) | ((i32) p[-1] << 24)
367 define i32 @load_i32_by_i8_neg_offset(ptr %arg) {
368 ; CHECK-LABEL: load_i32_by_i8_neg_offset:
370 ; CHECK-NEXT: ldr r0, [r0, #-4]
371 ; CHECK-NEXT: mov pc, lr
373 ; CHECK-ARMv6-LABEL: load_i32_by_i8_neg_offset:
374 ; CHECK-ARMv6: @ %bb.0:
375 ; CHECK-ARMv6-NEXT: ldr r0, [r0, #-4]
376 ; CHECK-ARMv6-NEXT: bx lr
378 ; CHECK-THUMBv6-LABEL: load_i32_by_i8_neg_offset:
379 ; CHECK-THUMBv6: @ %bb.0:
380 ; CHECK-THUMBv6-NEXT: subs r0, r0, #4
381 ; CHECK-THUMBv6-NEXT: ldr r0, [r0]
382 ; CHECK-THUMBv6-NEXT: bx lr
384 ; CHECK-THUMBv7-LABEL: load_i32_by_i8_neg_offset:
385 ; CHECK-THUMBv7: @ %bb.0:
386 ; CHECK-THUMBv7-NEXT: ldr r0, [r0, #-4]
387 ; CHECK-THUMBv7-NEXT: bx lr
390 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 -4
391 %tmp2 = load i8, ptr %tmp1, align 4
392 %tmp3 = zext i8 %tmp2 to i32
393 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 -3
394 %tmp5 = load i8, ptr %tmp4, align 1
395 %tmp6 = zext i8 %tmp5 to i32
396 %tmp7 = shl nuw nsw i32 %tmp6, 8
397 %tmp8 = or i32 %tmp7, %tmp3
398 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 -2
399 %tmp10 = load i8, ptr %tmp9, align 1
400 %tmp11 = zext i8 %tmp10 to i32
401 %tmp12 = shl nuw nsw i32 %tmp11, 16
402 %tmp13 = or i32 %tmp8, %tmp12
403 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 -1
404 %tmp15 = load i8, ptr %tmp14, align 1
405 %tmp16 = zext i8 %tmp15 to i32
406 %tmp17 = shl nuw nsw i32 %tmp16, 24
407 %tmp18 = or i32 %tmp13, %tmp17
411 ; ptr p; // p[1] is 4 byte aligned
412 ; (i32) p[4] | ((i32) p[3] << 8) | ((i32) p[2] << 16) | ((i32) p[1] << 24)
413 define i32 @load_i32_by_i8_nonzero_offset_bswap(ptr %arg) {
414 ; CHECK-LABEL: load_i32_by_i8_nonzero_offset_bswap:
416 ; CHECK-NEXT: ldr r0, [r0, #1]
417 ; CHECK-NEXT: mov r1, #65280
418 ; CHECK-NEXT: and r2, r0, #65280
419 ; CHECK-NEXT: and r1, r1, r0, lsr #8
420 ; CHECK-NEXT: orr r1, r1, r0, lsr #24
421 ; CHECK-NEXT: lsl r0, r0, #24
422 ; CHECK-NEXT: orr r0, r0, r2, lsl #8
423 ; CHECK-NEXT: orr r0, r0, r1
424 ; CHECK-NEXT: mov pc, lr
426 ; CHECK-ARMv6-LABEL: load_i32_by_i8_nonzero_offset_bswap:
427 ; CHECK-ARMv6: @ %bb.0:
428 ; CHECK-ARMv6-NEXT: ldr r0, [r0, #1]
429 ; CHECK-ARMv6-NEXT: rev r0, r0
430 ; CHECK-ARMv6-NEXT: bx lr
432 ; CHECK-THUMBv6-LABEL: load_i32_by_i8_nonzero_offset_bswap:
433 ; CHECK-THUMBv6: @ %bb.0:
434 ; CHECK-THUMBv6-NEXT: movs r1, #1
435 ; CHECK-THUMBv6-NEXT: ldr r0, [r0, r1]
436 ; CHECK-THUMBv6-NEXT: rev r0, r0
437 ; CHECK-THUMBv6-NEXT: bx lr
439 ; CHECK-THUMBv7-LABEL: load_i32_by_i8_nonzero_offset_bswap:
440 ; CHECK-THUMBv7: @ %bb.0:
441 ; CHECK-THUMBv7-NEXT: ldr.w r0, [r0, #1]
442 ; CHECK-THUMBv7-NEXT: rev r0, r0
443 ; CHECK-THUMBv7-NEXT: bx lr
446 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 4
447 %tmp2 = load i8, ptr %tmp1, align 1
448 %tmp3 = zext i8 %tmp2 to i32
449 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 3
450 %tmp5 = load i8, ptr %tmp4, align 1
451 %tmp6 = zext i8 %tmp5 to i32
452 %tmp7 = shl nuw nsw i32 %tmp6, 8
453 %tmp8 = or i32 %tmp7, %tmp3
454 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 2
455 %tmp10 = load i8, ptr %tmp9, align 1
456 %tmp11 = zext i8 %tmp10 to i32
457 %tmp12 = shl nuw nsw i32 %tmp11, 16
458 %tmp13 = or i32 %tmp8, %tmp12
459 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 1
460 %tmp15 = load i8, ptr %tmp14, align 4
461 %tmp16 = zext i8 %tmp15 to i32
462 %tmp17 = shl nuw nsw i32 %tmp16, 24
463 %tmp18 = or i32 %tmp13, %tmp17
467 ; ptr p; // p[-4] is 4 byte aligned
468 ; (i32) p[-1] | ((i32) p[-2] << 8) | ((i32) p[-3] << 16) | ((i32) p[-4] << 24)
469 define i32 @load_i32_by_i8_neg_offset_bswap(ptr %arg) {
470 ; CHECK-LABEL: load_i32_by_i8_neg_offset_bswap:
472 ; CHECK-NEXT: ldr r0, [r0, #-4]
473 ; CHECK-NEXT: mov r1, #65280
474 ; CHECK-NEXT: and r2, r0, #65280
475 ; CHECK-NEXT: and r1, r1, r0, lsr #8
476 ; CHECK-NEXT: orr r1, r1, r0, lsr #24
477 ; CHECK-NEXT: lsl r0, r0, #24
478 ; CHECK-NEXT: orr r0, r0, r2, lsl #8
479 ; CHECK-NEXT: orr r0, r0, r1
480 ; CHECK-NEXT: mov pc, lr
482 ; CHECK-ARMv6-LABEL: load_i32_by_i8_neg_offset_bswap:
483 ; CHECK-ARMv6: @ %bb.0:
484 ; CHECK-ARMv6-NEXT: ldr r0, [r0, #-4]
485 ; CHECK-ARMv6-NEXT: rev r0, r0
486 ; CHECK-ARMv6-NEXT: bx lr
488 ; CHECK-THUMBv6-LABEL: load_i32_by_i8_neg_offset_bswap:
489 ; CHECK-THUMBv6: @ %bb.0:
490 ; CHECK-THUMBv6-NEXT: subs r0, r0, #4
491 ; CHECK-THUMBv6-NEXT: ldr r0, [r0]
492 ; CHECK-THUMBv6-NEXT: rev r0, r0
493 ; CHECK-THUMBv6-NEXT: bx lr
495 ; CHECK-THUMBv7-LABEL: load_i32_by_i8_neg_offset_bswap:
496 ; CHECK-THUMBv7: @ %bb.0:
497 ; CHECK-THUMBv7-NEXT: ldr r0, [r0, #-4]
498 ; CHECK-THUMBv7-NEXT: rev r0, r0
499 ; CHECK-THUMBv7-NEXT: bx lr
502 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 -1
503 %tmp2 = load i8, ptr %tmp1, align 1
504 %tmp3 = zext i8 %tmp2 to i32
505 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 -2
506 %tmp5 = load i8, ptr %tmp4, align 1
507 %tmp6 = zext i8 %tmp5 to i32
508 %tmp7 = shl nuw nsw i32 %tmp6, 8
509 %tmp8 = or i32 %tmp7, %tmp3
510 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 -3
511 %tmp10 = load i8, ptr %tmp9, align 1
512 %tmp11 = zext i8 %tmp10 to i32
513 %tmp12 = shl nuw nsw i32 %tmp11, 16
514 %tmp13 = or i32 %tmp8, %tmp12
515 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 -4
516 %tmp15 = load i8, ptr %tmp14, align 4
517 %tmp16 = zext i8 %tmp15 to i32
518 %tmp17 = shl nuw nsw i32 %tmp16, 24
519 %tmp18 = or i32 %tmp13, %tmp17
523 declare i16 @llvm.bswap.i16(i16)
525 ; ptr p; // p is 4 byte aligned
526 ; (i32) bswap(p[1]) | (i32) bswap(p[0] << 16)
527 define i32 @load_i32_by_bswap_i16(ptr %arg) {
528 ; CHECK-LABEL: load_i32_by_bswap_i16:
530 ; CHECK-NEXT: ldr r0, [r0]
531 ; CHECK-NEXT: mov r1, #65280
532 ; CHECK-NEXT: and r2, r0, #65280
533 ; CHECK-NEXT: and r1, r1, r0, lsr #8
534 ; CHECK-NEXT: orr r1, r1, r0, lsr #24
535 ; CHECK-NEXT: lsl r0, r0, #24
536 ; CHECK-NEXT: orr r0, r0, r2, lsl #8
537 ; CHECK-NEXT: orr r0, r0, r1
538 ; CHECK-NEXT: mov pc, lr
540 ; CHECK-ARMv6-LABEL: load_i32_by_bswap_i16:
541 ; CHECK-ARMv6: @ %bb.0:
542 ; CHECK-ARMv6-NEXT: ldr r0, [r0]
543 ; CHECK-ARMv6-NEXT: rev r0, r0
544 ; CHECK-ARMv6-NEXT: bx lr
546 ; CHECK-THUMBv6-LABEL: load_i32_by_bswap_i16:
547 ; CHECK-THUMBv6: @ %bb.0:
548 ; CHECK-THUMBv6-NEXT: ldr r0, [r0]
549 ; CHECK-THUMBv6-NEXT: rev r0, r0
550 ; CHECK-THUMBv6-NEXT: bx lr
552 ; CHECK-THUMBv7-LABEL: load_i32_by_bswap_i16:
553 ; CHECK-THUMBv7: @ %bb.0:
554 ; CHECK-THUMBv7-NEXT: ldr r0, [r0]
555 ; CHECK-THUMBv7-NEXT: rev r0, r0
556 ; CHECK-THUMBv7-NEXT: bx lr
559 %tmp1 = load i16, ptr %arg, align 4
560 %tmp11 = call i16 @llvm.bswap.i16(i16 %tmp1)
561 %tmp2 = zext i16 %tmp11 to i32
562 %tmp3 = getelementptr inbounds i16, ptr %arg, i32 1
563 %tmp4 = load i16, ptr %tmp3, align 1
564 %tmp41 = call i16 @llvm.bswap.i16(i16 %tmp4)
565 %tmp5 = zext i16 %tmp41 to i32
566 %tmp6 = shl nuw nsw i32 %tmp2, 16
567 %tmp7 = or i32 %tmp6, %tmp5
572 ; (i32) p[0] | (sext(p[1] << 16) to i32)
573 define i32 @load_i32_by_sext_i16(ptr %arg) {
574 ; CHECK-LABEL: load_i32_by_sext_i16:
576 ; CHECK-NEXT: ldr r0, [r0]
577 ; CHECK-NEXT: mov pc, lr
579 ; CHECK-ARMv6-LABEL: load_i32_by_sext_i16:
580 ; CHECK-ARMv6: @ %bb.0:
581 ; CHECK-ARMv6-NEXT: ldr r0, [r0]
582 ; CHECK-ARMv6-NEXT: bx lr
584 ; CHECK-THUMBv6-LABEL: load_i32_by_sext_i16:
585 ; CHECK-THUMBv6: @ %bb.0:
586 ; CHECK-THUMBv6-NEXT: ldr r0, [r0]
587 ; CHECK-THUMBv6-NEXT: bx lr
589 ; CHECK-THUMBv7-LABEL: load_i32_by_sext_i16:
590 ; CHECK-THUMBv7: @ %bb.0:
591 ; CHECK-THUMBv7-NEXT: ldr r0, [r0]
592 ; CHECK-THUMBv7-NEXT: bx lr
593 %tmp1 = load i16, ptr %arg, align 4
594 %tmp2 = zext i16 %tmp1 to i32
595 %tmp3 = getelementptr inbounds i16, ptr %arg, i32 1
596 %tmp4 = load i16, ptr %tmp3, align 1
597 %tmp5 = sext i16 %tmp4 to i32
598 %tmp6 = shl nuw nsw i32 %tmp5, 16
599 %tmp7 = or i32 %tmp6, %tmp2
605 ; (i32) p[i] | ((i32) p[i + 1] << 8) | ((i32) p[i + 2] << 16) | ((i32) p[i + 3] << 24)
606 define i32 @load_i32_by_i8_base_offset_index(ptr %arg, i32 %i) {
607 ; CHECK-LABEL: load_i32_by_i8_base_offset_index:
609 ; CHECK-NEXT: add r0, r0, r1
610 ; CHECK-NEXT: ldr r0, [r0, #12]
611 ; CHECK-NEXT: mov pc, lr
613 ; CHECK-ARMv6-LABEL: load_i32_by_i8_base_offset_index:
614 ; CHECK-ARMv6: @ %bb.0:
615 ; CHECK-ARMv6-NEXT: add r0, r0, r1
616 ; CHECK-ARMv6-NEXT: ldr r0, [r0, #12]
617 ; CHECK-ARMv6-NEXT: bx lr
619 ; CHECK-THUMBv6-LABEL: load_i32_by_i8_base_offset_index:
620 ; CHECK-THUMBv6: @ %bb.0:
621 ; CHECK-THUMBv6-NEXT: adds r0, r0, r1
622 ; CHECK-THUMBv6-NEXT: ldr r0, [r0, #12]
623 ; CHECK-THUMBv6-NEXT: bx lr
625 ; CHECK-THUMBv7-LABEL: load_i32_by_i8_base_offset_index:
626 ; CHECK-THUMBv7: @ %bb.0:
627 ; CHECK-THUMBv7-NEXT: add r0, r1
628 ; CHECK-THUMBv7-NEXT: ldr r0, [r0, #12]
629 ; CHECK-THUMBv7-NEXT: bx lr
631 %tmp = add nuw nsw i32 %i, 3
632 %tmp2 = add nuw nsw i32 %i, 2
633 %tmp3 = add nuw nsw i32 %i, 1
634 %tmp4 = getelementptr inbounds i8, ptr %arg, i64 12
635 %tmp5 = zext i32 %i to i64
636 %tmp6 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp5
637 %tmp7 = load i8, ptr %tmp6, align 4
638 %tmp8 = zext i8 %tmp7 to i32
639 %tmp9 = zext i32 %tmp3 to i64
640 %tmp10 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp9
641 %tmp11 = load i8, ptr %tmp10, align 1
642 %tmp12 = zext i8 %tmp11 to i32
643 %tmp13 = shl nuw nsw i32 %tmp12, 8
644 %tmp14 = or i32 %tmp13, %tmp8
645 %tmp15 = zext i32 %tmp2 to i64
646 %tmp16 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp15
647 %tmp17 = load i8, ptr %tmp16, align 1
648 %tmp18 = zext i8 %tmp17 to i32
649 %tmp19 = shl nuw nsw i32 %tmp18, 16
650 %tmp20 = or i32 %tmp14, %tmp19
651 %tmp21 = zext i32 %tmp to i64
652 %tmp22 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp21
653 %tmp23 = load i8, ptr %tmp22, align 1
654 %tmp24 = zext i8 %tmp23 to i32
655 %tmp25 = shl nuw i32 %tmp24, 24
656 %tmp26 = or i32 %tmp20, %tmp25
662 ; (i32) p[i + 1] | ((i32) p[i + 2] << 8) | ((i32) p[i + 3] << 16) | ((i32) p[i + 4] << 24)
663 define i32 @load_i32_by_i8_base_offset_index_2(ptr %arg, i32 %i) {
664 ; CHECK-LABEL: load_i32_by_i8_base_offset_index_2:
666 ; CHECK-NEXT: add r0, r1, r0
667 ; CHECK-NEXT: ldr r0, [r0, #13]
668 ; CHECK-NEXT: mov pc, lr
670 ; CHECK-ARMv6-LABEL: load_i32_by_i8_base_offset_index_2:
671 ; CHECK-ARMv6: @ %bb.0:
672 ; CHECK-ARMv6-NEXT: add r0, r1, r0
673 ; CHECK-ARMv6-NEXT: ldr r0, [r0, #13]
674 ; CHECK-ARMv6-NEXT: bx lr
676 ; CHECK-THUMBv6-LABEL: load_i32_by_i8_base_offset_index_2:
677 ; CHECK-THUMBv6: @ %bb.0:
678 ; CHECK-THUMBv6-NEXT: adds r0, r1, r0
679 ; CHECK-THUMBv6-NEXT: movs r1, #13
680 ; CHECK-THUMBv6-NEXT: ldr r0, [r0, r1]
681 ; CHECK-THUMBv6-NEXT: bx lr
683 ; CHECK-THUMBv7-LABEL: load_i32_by_i8_base_offset_index_2:
684 ; CHECK-THUMBv7: @ %bb.0:
685 ; CHECK-THUMBv7-NEXT: add r0, r1
686 ; CHECK-THUMBv7-NEXT: ldr.w r0, [r0, #13]
687 ; CHECK-THUMBv7-NEXT: bx lr
688 %tmp = add nuw nsw i32 %i, 4
689 %tmp2 = add nuw nsw i32 %i, 3
690 %tmp3 = add nuw nsw i32 %i, 2
691 %tmp4 = getelementptr inbounds i8, ptr %arg, i64 12
692 %tmp5 = add nuw nsw i32 %i, 1
693 %tmp27 = zext i32 %tmp5 to i64
694 %tmp28 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp27
695 %tmp29 = load i8, ptr %tmp28, align 4
696 %tmp30 = zext i8 %tmp29 to i32
697 %tmp31 = zext i32 %tmp3 to i64
698 %tmp32 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp31
699 %tmp33 = load i8, ptr %tmp32, align 1
700 %tmp34 = zext i8 %tmp33 to i32
701 %tmp35 = shl nuw nsw i32 %tmp34, 8
702 %tmp36 = or i32 %tmp35, %tmp30
703 %tmp37 = zext i32 %tmp2 to i64
704 %tmp38 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp37
705 %tmp39 = load i8, ptr %tmp38, align 1
706 %tmp40 = zext i8 %tmp39 to i32
707 %tmp41 = shl nuw nsw i32 %tmp40, 16
708 %tmp42 = or i32 %tmp36, %tmp41
709 %tmp43 = zext i32 %tmp to i64
710 %tmp44 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp43
711 %tmp45 = load i8, ptr %tmp44, align 1
712 %tmp46 = zext i8 %tmp45 to i32
713 %tmp47 = shl nuw i32 %tmp46, 24
714 %tmp48 = or i32 %tmp42, %tmp47
718 ; ptr p; // p is 2 byte aligned
719 ; (i32) p[0] | ((i32) p[1] << 8)
720 define i32 @zext_load_i32_by_i8(ptr %arg) {
721 ; CHECK-LABEL: zext_load_i32_by_i8:
723 ; CHECK-NEXT: ldrh r0, [r0]
724 ; CHECK-NEXT: mov pc, lr
726 ; CHECK-ARMv6-LABEL: zext_load_i32_by_i8:
727 ; CHECK-ARMv6: @ %bb.0:
728 ; CHECK-ARMv6-NEXT: ldrh r0, [r0]
729 ; CHECK-ARMv6-NEXT: bx lr
731 ; CHECK-THUMBv6-LABEL: zext_load_i32_by_i8:
732 ; CHECK-THUMBv6: @ %bb.0:
733 ; CHECK-THUMBv6-NEXT: ldrh r0, [r0]
734 ; CHECK-THUMBv6-NEXT: bx lr
736 ; CHECK-THUMBv7-LABEL: zext_load_i32_by_i8:
737 ; CHECK-THUMBv7: @ %bb.0:
738 ; CHECK-THUMBv7-NEXT: ldrh r0, [r0]
739 ; CHECK-THUMBv7-NEXT: bx lr
741 %tmp2 = load i8, ptr %arg, align 2
742 %tmp3 = zext i8 %tmp2 to i32
743 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 1
744 %tmp5 = load i8, ptr %tmp4, align 1
745 %tmp6 = zext i8 %tmp5 to i32
746 %tmp7 = shl nuw nsw i32 %tmp6, 8
747 %tmp8 = or i32 %tmp7, %tmp3
751 ; ptr p; // p is 2 byte aligned
752 ; ((i32) p[0] << 8) | ((i32) p[1] << 16)
753 define i32 @zext_load_i32_by_i8_shl_8(ptr %arg) {
754 ; CHECK-LABEL: zext_load_i32_by_i8_shl_8:
756 ; CHECK-NEXT: ldrb r1, [r0]
757 ; CHECK-NEXT: ldrb r0, [r0, #1]
758 ; CHECK-NEXT: lsl r0, r0, #16
759 ; CHECK-NEXT: orr r0, r0, r1, lsl #8
760 ; CHECK-NEXT: mov pc, lr
762 ; CHECK-ARMv6-LABEL: zext_load_i32_by_i8_shl_8:
763 ; CHECK-ARMv6: @ %bb.0:
764 ; CHECK-ARMv6-NEXT: ldrb r1, [r0]
765 ; CHECK-ARMv6-NEXT: ldrb r0, [r0, #1]
766 ; CHECK-ARMv6-NEXT: lsl r0, r0, #16
767 ; CHECK-ARMv6-NEXT: orr r0, r0, r1, lsl #8
768 ; CHECK-ARMv6-NEXT: bx lr
770 ; CHECK-THUMBv6-LABEL: zext_load_i32_by_i8_shl_8:
771 ; CHECK-THUMBv6: @ %bb.0:
772 ; CHECK-THUMBv6-NEXT: ldrb r1, [r0]
773 ; CHECK-THUMBv6-NEXT: lsls r1, r1, #8
774 ; CHECK-THUMBv6-NEXT: ldrb r0, [r0, #1]
775 ; CHECK-THUMBv6-NEXT: lsls r0, r0, #16
776 ; CHECK-THUMBv6-NEXT: adds r0, r0, r1
777 ; CHECK-THUMBv6-NEXT: bx lr
779 ; CHECK-THUMBv7-LABEL: zext_load_i32_by_i8_shl_8:
780 ; CHECK-THUMBv7: @ %bb.0:
781 ; CHECK-THUMBv7-NEXT: ldrb r1, [r0]
782 ; CHECK-THUMBv7-NEXT: ldrb r0, [r0, #1]
783 ; CHECK-THUMBv7-NEXT: lsls r0, r0, #16
784 ; CHECK-THUMBv7-NEXT: orr.w r0, r0, r1, lsl #8
785 ; CHECK-THUMBv7-NEXT: bx lr
787 %tmp2 = load i8, ptr %arg, align 2
788 %tmp3 = zext i8 %tmp2 to i32
789 %tmp30 = shl nuw nsw i32 %tmp3, 8
790 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 1
791 %tmp5 = load i8, ptr %tmp4, align 1
792 %tmp6 = zext i8 %tmp5 to i32
793 %tmp7 = shl nuw nsw i32 %tmp6, 16
794 %tmp8 = or i32 %tmp7, %tmp30
798 ; ptr p; // p is 2 byte aligned
799 ; ((i32) p[0] << 16) | ((i32) p[1] << 24)
800 define i32 @zext_load_i32_by_i8_shl_16(ptr %arg) {
801 ; CHECK-LABEL: zext_load_i32_by_i8_shl_16:
803 ; CHECK-NEXT: ldrb r1, [r0]
804 ; CHECK-NEXT: ldrb r0, [r0, #1]
805 ; CHECK-NEXT: lsl r0, r0, #24
806 ; CHECK-NEXT: orr r0, r0, r1, lsl #16
807 ; CHECK-NEXT: mov pc, lr
809 ; CHECK-ARMv6-LABEL: zext_load_i32_by_i8_shl_16:
810 ; CHECK-ARMv6: @ %bb.0:
811 ; CHECK-ARMv6-NEXT: ldrb r1, [r0]
812 ; CHECK-ARMv6-NEXT: ldrb r0, [r0, #1]
813 ; CHECK-ARMv6-NEXT: lsl r0, r0, #24
814 ; CHECK-ARMv6-NEXT: orr r0, r0, r1, lsl #16
815 ; CHECK-ARMv6-NEXT: bx lr
817 ; CHECK-THUMBv6-LABEL: zext_load_i32_by_i8_shl_16:
818 ; CHECK-THUMBv6: @ %bb.0:
819 ; CHECK-THUMBv6-NEXT: ldrb r1, [r0]
820 ; CHECK-THUMBv6-NEXT: lsls r1, r1, #16
821 ; CHECK-THUMBv6-NEXT: ldrb r0, [r0, #1]
822 ; CHECK-THUMBv6-NEXT: lsls r0, r0, #24
823 ; CHECK-THUMBv6-NEXT: adds r0, r0, r1
824 ; CHECK-THUMBv6-NEXT: bx lr
826 ; CHECK-THUMBv7-LABEL: zext_load_i32_by_i8_shl_16:
827 ; CHECK-THUMBv7: @ %bb.0:
828 ; CHECK-THUMBv7-NEXT: ldrb r1, [r0]
829 ; CHECK-THUMBv7-NEXT: ldrb r0, [r0, #1]
830 ; CHECK-THUMBv7-NEXT: lsls r0, r0, #24
831 ; CHECK-THUMBv7-NEXT: orr.w r0, r0, r1, lsl #16
832 ; CHECK-THUMBv7-NEXT: bx lr
834 %tmp2 = load i8, ptr %arg, align 2
835 %tmp3 = zext i8 %tmp2 to i32
836 %tmp30 = shl nuw nsw i32 %tmp3, 16
837 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 1
838 %tmp5 = load i8, ptr %tmp4, align 1
839 %tmp6 = zext i8 %tmp5 to i32
840 %tmp7 = shl nuw nsw i32 %tmp6, 24
841 %tmp8 = or i32 %tmp7, %tmp30
845 ; ptr p; // p is 2 byte aligned
846 ; (i32) p[1] | ((i32) p[0] << 8)
847 define i32 @zext_load_i32_by_i8_bswap(ptr %arg) {
848 ; CHECK-LABEL: zext_load_i32_by_i8_bswap:
850 ; CHECK-NEXT: ldrb r1, [r0]
851 ; CHECK-NEXT: ldrb r0, [r0, #1]
852 ; CHECK-NEXT: orr r0, r0, r1, lsl #8
853 ; CHECK-NEXT: mov pc, lr
855 ; CHECK-ARMv6-LABEL: zext_load_i32_by_i8_bswap:
856 ; CHECK-ARMv6: @ %bb.0:
857 ; CHECK-ARMv6-NEXT: ldrh r0, [r0]
858 ; CHECK-ARMv6-NEXT: rev16 r0, r0
859 ; CHECK-ARMv6-NEXT: bx lr
861 ; CHECK-THUMBv6-LABEL: zext_load_i32_by_i8_bswap:
862 ; CHECK-THUMBv6: @ %bb.0:
863 ; CHECK-THUMBv6-NEXT: ldrh r0, [r0]
864 ; CHECK-THUMBv6-NEXT: rev16 r0, r0
865 ; CHECK-THUMBv6-NEXT: bx lr
867 ; CHECK-THUMBv7-LABEL: zext_load_i32_by_i8_bswap:
868 ; CHECK-THUMBv7: @ %bb.0:
869 ; CHECK-THUMBv7-NEXT: ldrh r0, [r0]
870 ; CHECK-THUMBv7-NEXT: rev16 r0, r0
871 ; CHECK-THUMBv7-NEXT: bx lr
873 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 1
874 %tmp2 = load i8, ptr %tmp1, align 1
875 %tmp3 = zext i8 %tmp2 to i32
876 %tmp5 = load i8, ptr %arg, align 2
877 %tmp6 = zext i8 %tmp5 to i32
878 %tmp7 = shl nuw nsw i32 %tmp6, 8
879 %tmp8 = or i32 %tmp7, %tmp3
883 ; ptr p; // p is 2 byte aligned
884 ; ((i32) p[1] << 8) | ((i32) p[0] << 16)
885 define i32 @zext_load_i32_by_i8_bswap_shl_8(ptr %arg) {
886 ; CHECK-LABEL: zext_load_i32_by_i8_bswap_shl_8:
888 ; CHECK-NEXT: ldrb r1, [r0]
889 ; CHECK-NEXT: ldrb r0, [r0, #1]
890 ; CHECK-NEXT: lsl r1, r1, #16
891 ; CHECK-NEXT: orr r0, r1, r0, lsl #8
892 ; CHECK-NEXT: mov pc, lr
894 ; CHECK-ARMv6-LABEL: zext_load_i32_by_i8_bswap_shl_8:
895 ; CHECK-ARMv6: @ %bb.0:
896 ; CHECK-ARMv6-NEXT: ldrb r1, [r0]
897 ; CHECK-ARMv6-NEXT: ldrb r0, [r0, #1]
898 ; CHECK-ARMv6-NEXT: lsl r1, r1, #16
899 ; CHECK-ARMv6-NEXT: orr r0, r1, r0, lsl #8
900 ; CHECK-ARMv6-NEXT: bx lr
902 ; CHECK-THUMBv6-LABEL: zext_load_i32_by_i8_bswap_shl_8:
903 ; CHECK-THUMBv6: @ %bb.0:
904 ; CHECK-THUMBv6-NEXT: ldrb r1, [r0, #1]
905 ; CHECK-THUMBv6-NEXT: lsls r1, r1, #8
906 ; CHECK-THUMBv6-NEXT: ldrb r0, [r0]
907 ; CHECK-THUMBv6-NEXT: lsls r0, r0, #16
908 ; CHECK-THUMBv6-NEXT: adds r0, r0, r1
909 ; CHECK-THUMBv6-NEXT: bx lr
911 ; CHECK-THUMBv7-LABEL: zext_load_i32_by_i8_bswap_shl_8:
912 ; CHECK-THUMBv7: @ %bb.0:
913 ; CHECK-THUMBv7-NEXT: ldrb r1, [r0]
914 ; CHECK-THUMBv7-NEXT: ldrb r0, [r0, #1]
915 ; CHECK-THUMBv7-NEXT: lsls r1, r1, #16
916 ; CHECK-THUMBv7-NEXT: orr.w r0, r1, r0, lsl #8
917 ; CHECK-THUMBv7-NEXT: bx lr
919 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 1
920 %tmp2 = load i8, ptr %tmp1, align 1
921 %tmp3 = zext i8 %tmp2 to i32
922 %tmp30 = shl nuw nsw i32 %tmp3, 8
923 %tmp5 = load i8, ptr %arg, align 2
924 %tmp6 = zext i8 %tmp5 to i32
925 %tmp7 = shl nuw nsw i32 %tmp6, 16
926 %tmp8 = or i32 %tmp7, %tmp30
930 ; ptr p; // p is 2 byte aligned
931 ; ((i32) p[1] << 16) | ((i32) p[0] << 24)
932 define i32 @zext_load_i32_by_i8_bswap_shl_16(ptr %arg) {
933 ; CHECK-LABEL: zext_load_i32_by_i8_bswap_shl_16:
935 ; CHECK-NEXT: ldrb r1, [r0]
936 ; CHECK-NEXT: ldrb r0, [r0, #1]
937 ; CHECK-NEXT: lsl r1, r1, #24
938 ; CHECK-NEXT: orr r0, r1, r0, lsl #16
939 ; CHECK-NEXT: mov pc, lr
941 ; CHECK-ARMv6-LABEL: zext_load_i32_by_i8_bswap_shl_16:
942 ; CHECK-ARMv6: @ %bb.0:
943 ; CHECK-ARMv6-NEXT: ldrb r1, [r0]
944 ; CHECK-ARMv6-NEXT: ldrb r0, [r0, #1]
945 ; CHECK-ARMv6-NEXT: lsl r1, r1, #24
946 ; CHECK-ARMv6-NEXT: orr r0, r1, r0, lsl #16
947 ; CHECK-ARMv6-NEXT: bx lr
949 ; CHECK-THUMBv6-LABEL: zext_load_i32_by_i8_bswap_shl_16:
950 ; CHECK-THUMBv6: @ %bb.0:
951 ; CHECK-THUMBv6-NEXT: ldrb r1, [r0, #1]
952 ; CHECK-THUMBv6-NEXT: lsls r1, r1, #16
953 ; CHECK-THUMBv6-NEXT: ldrb r0, [r0]
954 ; CHECK-THUMBv6-NEXT: lsls r0, r0, #24
955 ; CHECK-THUMBv6-NEXT: adds r0, r0, r1
956 ; CHECK-THUMBv6-NEXT: bx lr
958 ; CHECK-THUMBv7-LABEL: zext_load_i32_by_i8_bswap_shl_16:
959 ; CHECK-THUMBv7: @ %bb.0:
960 ; CHECK-THUMBv7-NEXT: ldrb r1, [r0]
961 ; CHECK-THUMBv7-NEXT: ldrb r0, [r0, #1]
962 ; CHECK-THUMBv7-NEXT: lsls r1, r1, #24
963 ; CHECK-THUMBv7-NEXT: orr.w r0, r1, r0, lsl #16
964 ; CHECK-THUMBv7-NEXT: bx lr
966 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 1
967 %tmp2 = load i8, ptr %tmp1, align 1
968 %tmp3 = zext i8 %tmp2 to i32
969 %tmp30 = shl nuw nsw i32 %tmp3, 16
970 %tmp5 = load i8, ptr %arg, align 2
971 %tmp6 = zext i8 %tmp5 to i32
972 %tmp7 = shl nuw nsw i32 %tmp6, 24
973 %tmp8 = or i32 %tmp7, %tmp30