Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / CodeGen / ARM / load.ll
blobd87a1e49fafe402235c7f510b305103cb1efebef
1 ; RUN: llc -mtriple=thumbv6m-eabi %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-T1
2 ; RUN: llc -mtriple=thumbv7m-eabi %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-T2
5 ; Register offset
7 ; CHECK-LABEL: ldrsb_rr
8 ; CHECK:    ldrsb   r0, [r0, r1]
9 define i32 @ldrsb_rr(ptr %p, i32 %n) {
10 entry:
11   %arrayidx = getelementptr inbounds i8, ptr %p, i32 %n
12   %0 = load i8, ptr %arrayidx, align 1
13   %conv = sext i8 %0 to i32
14   ret i32 %conv
17 ; CHECK-LABEL: ldrsh_rr
18 ; CHECK-T1: lsls    r1, r1, #1
19 ; CHECK-T1: ldrsh   r0, [r0, r1]
20 ; CHECK-T2: ldrsh.w r0, [r0, r1, lsl #1]
21 define i32 @ldrsh_rr(ptr %p, i32 %n) {
22 entry:
23   %arrayidx = getelementptr inbounds i16, ptr %p, i32 %n
24   %0 = load i16, ptr %arrayidx, align 2
25   %conv = sext i16 %0 to i32
26   ret i32 %conv
29 ; CHECK-LABEL: ldrb_rr
30 ; CHECK:    ldrb r0, [r0, r1]
31 define i32 @ldrb_rr(ptr %p, i32 %n) {
32 entry:
33   %arrayidx = getelementptr inbounds i8, ptr %p, i32 %n
34   %0 = load i8, ptr %arrayidx, align 1
35   %conv = zext i8 %0 to i32
36   ret i32 %conv
39 ; CHECK-LABEL: ldrh_rr
40 ; CHECK-T1: lsls    r1, r1, #1
41 ; CHECK-T1: ldrh    r0, [r0, r1]
42 ; CHECK-T2: ldrh.w  r0, [r0, r1, lsl #1]
43 define i32 @ldrh_rr(ptr %p, i32 %n) {
44 entry:
45   %arrayidx = getelementptr inbounds i16, ptr %p, i32 %n
46   %0 = load i16, ptr %arrayidx, align 2
47   %conv = zext i16 %0 to i32
48   ret i32 %conv
51 ; CHECK-LABEL: ldr_rr
52 ; CHECK-T1: lsls    r1, r1, #2
53 ; CHECK-T1: ldr     r0, [r0, r1]
54 ; CHECK-T2: ldr.w   r0, [r0, r1, lsl #2]
55 define i32 @ldr_rr(ptr %p, i32 %n) {
56 entry:
57   %arrayidx = getelementptr inbounds i32, ptr %p, i32 %n
58   %0 = load i32, ptr %arrayidx, align 4
59   ret i32 %0
62 ; CHECK-LABEL: strb_rr
63 ; CHECK:    strb    r2, [r0, r1]
64 define void @strb_rr(ptr %p, i32 %n, i32 %x) {
65 entry:
66   %conv = trunc i32 %x to i8
67   %arrayidx = getelementptr inbounds i8, ptr %p, i32 %n
68   store i8 %conv, ptr %arrayidx, align 1
69   ret void
72 ; CHECK-LABEL: strh_rr
73 ; CHECK-T1: lsls    r1, r1, #1
74 ; CHECK-T1: strh    r2, [r0, r1]
75 ; CHECK-T2: strh.w  r2, [r0, r1, lsl #1]
76 define void @strh_rr(ptr %p, i32 %n, i32 %x) {
77 entry:
78   %conv = trunc i32 %x to i16
79   %arrayidx = getelementptr inbounds i16, ptr %p, i32 %n
80   store i16 %conv, ptr %arrayidx, align 2
81   ret void
84 ; CHECK-LABEL: str_rr
85 ; CHECK-T1: lsls    r1, r1, #2
86 ; CHECK-T1: str     r2, [r0, r1]
87 ; CHECK-T2: str.w   r2, [r0, r1, lsl #2]
88 define void @str_rr(ptr %p, i32 %n, i32 %x) {
89 entry:
90   %arrayidx = getelementptr inbounds i32, ptr %p, i32 %n
91   store i32 %x, ptr %arrayidx, align 4
92   ret void
96 ; Immediate offset of zero
98 ; CHECK-LABEL: ldrsb_ri_zero
99 ; CHECK-T1: movs    r1, #0
100 ; CHECK-T1: ldrsb   r0, [r0, r1]
101 ; CHECK-T2: ldrsb.w r0, [r0]
102 define i32 @ldrsb_ri_zero(ptr %p) {
103 entry:
104   %0 = load i8, ptr %p, align 1
105   %conv = sext i8 %0 to i32
106   ret i32 %conv
109 ; CHECK-LABEL: ldrsh_ri_zero
110 ; CHECK-T1: movs    r1, #0
111 ; CHECK-T1: ldrsh   r0, [r0, r1]
112 ; CHECK-T2: ldrsh.w r0, [r0]
113 define i32 @ldrsh_ri_zero(ptr %p) {
114 entry:
115   %0 = load i16, ptr %p, align 2
116   %conv = sext i16 %0 to i32
117   ret i32 %conv
120 ; CHECK-LABEL: ldrb_ri_zero
121 ; CHECK:    ldrb    r0, [r0]
122 define i32 @ldrb_ri_zero(ptr %p) {
123 entry:
124   %0 = load i8, ptr %p, align 1
125   %conv = zext i8 %0 to i32
126   ret i32 %conv
129 ; CHECK-LABEL: ldrh_ri_zero
130 ; CHECK:    ldrh    r0, [r0]
131 define i32 @ldrh_ri_zero(ptr %p) {
132 entry:
133   %0 = load i16, ptr %p, align 2
134   %conv = zext i16 %0 to i32
135   ret i32 %conv
138 ; CHECK-LABEL: ldr_ri_zero
139 ; CHECK:    ldr     r0, [r0]
140 define i32 @ldr_ri_zero(ptr %p) {
141 entry:
142   %0 = load i32, ptr %p, align 4
143   ret i32 %0
146 ; CHECK-LABEL: strb_ri_zero
147 ; CHECK:    strb    r1, [r0]
148 define void @strb_ri_zero(ptr %p, i32 %x) {
149 entry:
150   %conv = trunc i32 %x to i8
151   store i8 %conv, ptr %p, align 1
152   ret void
155 ; CHECK-LABEL: strh_ri_zero
156 ; CHECK:    strh    r1, [r0]
157 define void @strh_ri_zero(ptr %p, i32 %x) {
158 entry:
159   %conv = trunc i32 %x to i16
160   store i16 %conv, ptr %p, align 2
161   ret void
164 ; CHECK-LABEL: str_ri_zero
165 ; CHECK:    str     r1, [r0]
166 define void @str_ri_zero(ptr %p, i32 %x) {
167 entry:
168   store i32 %x, ptr %p, align 4
169   ret void
173 ; Maximum Thumb-1 immediate offset
175 ; CHECK-LABEL: ldrsb_ri_t1_max
176 ; CHECK-T1: movs    r1, #31
177 ; CHECK-T1: ldrsb   r0, [r0, r1]
178 ; CHECK-T2: ldrsb.w r0, [r0, #31]
179 define i32 @ldrsb_ri_t1_max(ptr %p) {
180 entry:
181   %arrayidx = getelementptr inbounds i8, ptr %p, i32 31
182   %0 = load i8, ptr %arrayidx, align 1
183   %conv = sext i8 %0 to i32
184   ret i32 %conv
187 ; CHECK-LABEL: ldrsh_ri_t1_max
188 ; CHECK-T1: movs    r1, #62
189 ; CHECK-T1: ldrsh   r0, [r0, r1]
190 ; CHECK-T2: ldrsh.w r0, [r0, #62]
191 define i32 @ldrsh_ri_t1_max(ptr %p) {
192 entry:
193   %arrayidx = getelementptr inbounds i16, ptr %p, i32 31
194   %0 = load i16, ptr %arrayidx, align 2
195   %conv = sext i16 %0 to i32
196   ret i32 %conv
199 ; CHECK-LABEL: ldrb_ri_t1_max
200 ; CHECK:    ldrb    r0, [r0, #31]
201 define i32 @ldrb_ri_t1_max(ptr %p) {
202 entry:
203   %arrayidx = getelementptr inbounds i8, ptr %p, i32 31
204   %0 = load i8, ptr %arrayidx, align 1
205   %conv = zext i8 %0 to i32
206   ret i32 %conv
209 ; CHECK-LABEL: ldrh_ri_t1_max
210 ; CHECK:    ldrh    r0, [r0, #62]
211 define i32 @ldrh_ri_t1_max(ptr %p) {
212 entry:
213   %arrayidx = getelementptr inbounds i16, ptr %p, i32 31
214   %0 = load i16, ptr %arrayidx, align 2
215   %conv = zext i16 %0 to i32
216   ret i32 %conv
219 ; CHECK-LABEL: ldr_ri_t1_max
220 ; CHECK:    ldr     r0, [r0, #124]
221 define i32 @ldr_ri_t1_max(ptr %p) {
222 entry:
223   %arrayidx = getelementptr inbounds i32, ptr %p, i32 31
224   %0 = load i32, ptr %arrayidx, align 4
225   ret i32 %0
228 ; CHECK-LABEL: strb_ri_t1_max
229 ; CHECK:    strb    r1, [r0, #31]
230 define void @strb_ri_t1_max(ptr %p, i32 %x) {
231 entry:
232   %conv = trunc i32 %x to i8
233   %arrayidx = getelementptr inbounds i8, ptr %p, i32 31
234   store i8 %conv, ptr %arrayidx, align 1
235   ret void
238 ; CHECK-LABEL: strh_ri_t1_max
239 ; CHECK:    strh    r1, [r0, #62]
240 define void @strh_ri_t1_max(ptr %p, i32 %x) {
241 entry:
242   %conv = trunc i32 %x to i16
243   %arrayidx = getelementptr inbounds i16, ptr %p, i32 31
244   store i16 %conv, ptr %arrayidx, align 2
245   ret void
248 ; CHECK-LABEL: str_ri_t1_max
249 ; CHECK:    str     r1, [r0, #124]
250 define void @str_ri_t1_max(ptr %p, i32 %x) {
251 entry:
252   %arrayidx = getelementptr inbounds i32, ptr %p, i32 31
253   store i32 %x, ptr %arrayidx, align 4
254   ret void
258 ; One past maximum Thumb-1 immediate offset
260 ; CHECK-LABEL: ldrsb_ri_t1_too_big
261 ; CHECK-T1: movs    r1, #32
262 ; CHECK-T1: ldrsb   r0, [r0, r1]
263 ; CHECK-T2: ldrsb.w r0, [r0, #32]
264 define i32 @ldrsb_ri_t1_too_big(ptr %p) {
265 entry:
266   %arrayidx = getelementptr inbounds i8, ptr %p, i32 32
267   %0 = load i8, ptr %arrayidx, align 1
268   %conv = sext i8 %0 to i32
269   ret i32 %conv
272 ; CHECK-LABEL: ldrsh_ri_t1_too_big
273 ; CHECK-T1: movs    r1, #64
274 ; CHECK-T1: ldrsh   r0, [r0, r1]
275 ; CHECK-T2: ldrsh.w r0, [r0, #64]
276 define i32 @ldrsh_ri_t1_too_big(ptr %p) {
277 entry:
278   %arrayidx = getelementptr inbounds i16, ptr %p, i32 32
279   %0 = load i16, ptr %arrayidx, align 2
280   %conv = sext i16 %0 to i32
281   ret i32 %conv
284 ; CHECK-LABEL: ldrb_ri_t1_too_big
285 ; CHECK-T1: movs    r1, #32
286 ; CHECK-T1: ldrb    r0, [r0, r1]
287 ; CHECK-T2: ldrb.w  r0, [r0, #32]
288 define i32 @ldrb_ri_t1_too_big(ptr %p) {
289 entry:
290   %arrayidx = getelementptr inbounds i8, ptr %p, i32 32
291   %0 = load i8, ptr %arrayidx, align 1
292   %conv = zext i8 %0 to i32
293   ret i32 %conv
296 ; CHECK-LABEL: ldrh_ri_t1_too_big
297 ; CHECK-T1: movs    r1, #64
298 ; CHECK-T1: ldrh    r0, [r0, r1]
299 ; CHECK-T2: ldrh.w  r0, [r0, #64]
300 define i32 @ldrh_ri_t1_too_big(ptr %p) {
301 entry:
302   %arrayidx = getelementptr inbounds i16, ptr %p, i32 32
303   %0 = load i16, ptr %arrayidx, align 2
304   %conv = zext i16 %0 to i32
305   ret i32 %conv
308 ; CHECK-LABEL: ldr_ri_t1_too_big
309 ; CHECK-T1: movs    r1, #128
310 ; CHECK-T1: ldr     r0, [r0, r1]
311 ; CHECK-T2: ldr.w   r0, [r0, #128]
312 define i32 @ldr_ri_t1_too_big(ptr %p) {
313 entry:
314   %arrayidx = getelementptr inbounds i32, ptr %p, i32 32
315   %0 = load i32, ptr %arrayidx, align 4
316   ret i32 %0
319 ; CHECK-LABEL: strb_ri_t1_too_big
320 ; CHECK-T1: movs    r2, #32
321 ; CHECK-T1: strb    r1, [r0, r2]
322 ; CHECK-T2: strb.w  r1, [r0, #32]
323 define void @strb_ri_t1_too_big(ptr %p, i32 %x) {
324 entry:
325   %conv = trunc i32 %x to i8
326   %arrayidx = getelementptr inbounds i8, ptr %p, i32 32
327   store i8 %conv, ptr %arrayidx, align 1
328   ret void
331 ; CHECK-LABEL: strh_ri_t1_too_big
332 ; CHECK-T1: movs    r2, #64
333 ; CHECK-T1: strh    r1, [r0, r2]
334 ; CHECK-T2: strh.w  r1, [r0, #64]
335 define void @strh_ri_t1_too_big(ptr %p, i32 %x) {
336 entry:
337   %conv = trunc i32 %x to i16
338   %arrayidx = getelementptr inbounds i16, ptr %p, i32 32
339   store i16 %conv, ptr %arrayidx, align 2
340   ret void
343 ; CHECK-LABEL: str_ri_t1_too_big
344 ; CHECK-T1: movs    r2, #128
345 ; CHECK-T1: str     r1, [r0, r2]
346 ; CHECK-T2: str.w   r1, [r0, #128]
347 define void @str_ri_t1_too_big(ptr %p, i32 %x) {
348 entry:
349   %arrayidx = getelementptr inbounds i32, ptr %p, i32 32
350   store i32 %x, ptr %arrayidx, align 4
351   ret void
355 ; Maximum Thumb-2 immediate offset
357 ; CHECK-LABEL: ldrsb_ri_t2_max
358 ; CHECK-T1: ldr     r1, .LCP
359 ; CHECK-T1: ldrsb   r0, [r0, r1]
360 ; CHECK-T2: ldrsb.w r0, [r0, #4095]
361 define i32 @ldrsb_ri_t2_max(ptr %p) {
362 entry:
363   %add.ptr = getelementptr inbounds i8, ptr %p, i32 4095
364   %0 = load i8, ptr %add.ptr, align 1
365   %conv = sext i8 %0 to i32
366   ret i32 %conv
369 ; CHECK-LABEL: ldrsh_ri_t2_max
370 ; CHECK-T1: ldr     r1, .LCP
371 ; CHECK-T1: ldrsh   r0, [r0, r1]
372 ; CHECK-T2: ldrsh.w r0, [r0, #4095]
373 define i32 @ldrsh_ri_t2_max(ptr %p) {
374 entry:
375   %add.ptr = getelementptr inbounds i8, ptr %p, i32 4095
376   %0 = load i16, ptr %add.ptr, align 2
377   %conv = sext i16 %0 to i32
378   ret i32 %conv
381 ; CHECK-LABEL: ldrb_ri_t2_max
382 ; CHECK-T1: ldr     r1, .LCP
383 ; CHECK-T1: ldrb    r0, [r0, r1]
384 ; CHECK-T2: ldrb.w  r0, [r0, #4095]
385 define i32 @ldrb_ri_t2_max(ptr %p) {
386 entry:
387   %add.ptr = getelementptr inbounds i8, ptr %p, i32 4095
388   %0 = load i8, ptr %add.ptr, align 1
389   %conv = zext i8 %0 to i32
390   ret i32 %conv
393 ; CHECK-LABEL: ldrh_ri_t2_max
394 ; CHECK-T1: ldr     r1, .LCP
395 ; CHECK-T1: ldrh    r0, [r0, r1]
396 ; CHECK-T2: ldrh.w  r0, [r0, #4095]
397 define i32 @ldrh_ri_t2_max(ptr %p) {
398 entry:
399   %add.ptr = getelementptr inbounds i8, ptr %p, i32 4095
400   %0 = load i16, ptr %add.ptr, align 2
401   %conv = zext i16 %0 to i32
402   ret i32 %conv
405 ; CHECK-LABEL: ldr_ri_t2_max
406 ; CHECK-T1: ldr     r1, .LCP
407 ; CHECK-T1: ldr     r0, [r0, r1]
408 ; CHECK-T2: ldr.w   r0, [r0, #4095]
409 define i32 @ldr_ri_t2_max(ptr %p) {
410 entry:
411   %add.ptr = getelementptr inbounds i8, ptr %p, i32 4095
412   %0 = load i32, ptr %add.ptr, align 4
413   ret i32 %0
416 ; CHECK-LABEL: strb_ri_t2_max
417 ; CHECK-T1: ldr     r2, .LCP
418 ; CHECK-T1: strb    r1, [r0, r2]
419 ; CHECK-T2: strb.w  r1, [r0, #4095]
420 define void @strb_ri_t2_max(ptr %p, i32 %x) {
421 entry:
422   %conv = trunc i32 %x to i8
423   %add.ptr = getelementptr inbounds i8, ptr %p, i32 4095
424   store i8 %conv, ptr %add.ptr, align 1
425   ret void
428 ; CHECK-LABEL: strh_ri_t2_max
429 ; CHECK-T1: ldr     r2, .LCP
430 ; CHECK-T1: strh    r1, [r0, r2]
431 ; CHECK-T2: strh.w  r1, [r0, #4095]
432 define void @strh_ri_t2_max(ptr %p, i32 %x) {
433 entry:
434   %conv = trunc i32 %x to i16
435   %add.ptr = getelementptr inbounds i8, ptr %p, i32 4095
436   store i16 %conv, ptr %add.ptr, align 2
437   ret void
440 ; CHECK-LABEL: str_ri_t2_max
441 ; CHECK-T1: ldr     r2, .LCP
442 ; CHECK-T1: str     r1, [r0, r2]
443 ; CHECK-T2: str.w   r1, [r0, #4095]
444 define void @str_ri_t2_max(ptr %p, i32 %x) {
445 entry:
446   %add.ptr = getelementptr inbounds i8, ptr %p, i32 4095
447   store i32 %x, ptr %add.ptr, align 4
448   ret void
452 ; One past maximum Thumb-2 immediate offset
454 ; CHECK-LABEL: ldrsb_ri_t2_too_big
455 ; CHECK-T1: movs    r1, #1
456 ; CHECK-T1: lsls    r1, r1, #12
457 ; CHECK-T2: mov.w   r1, #4096
458 ; CHECK:    ldrsb   r0, [r0, r1]
459 define i32 @ldrsb_ri_t2_too_big(ptr %p) {
460 entry:
461   %add.ptr = getelementptr inbounds i8, ptr %p, i32 4096
462   %0 = load i8, ptr %add.ptr, align 1
463   %conv = sext i8 %0 to i32
464   ret i32 %conv
467 ; CHECK-LABEL: ldrsh_ri_t2_too_big
468 ; CHECK-T1: movs    r1, #1
469 ; CHECK-T1: lsls    r1, r1, #12
470 ; CHECK-T2: mov.w   r1, #4096
471 ; CHECK:    ldrsh   r0, [r0, r1]
472 define i32 @ldrsh_ri_t2_too_big(ptr %p) {
473 entry:
474   %add.ptr = getelementptr inbounds i8, ptr %p, i32 4096
475   %0 = load i16, ptr %add.ptr, align 2
476   %conv = sext i16 %0 to i32
477   ret i32 %conv
480 ; CHECK-LABEL: ldrb_ri_t2_too_big
481 ; CHECK-T1: movs    r1, #1
482 ; CHECK-T1: lsls    r1, r1, #12
483 ; CHECK-T2: mov.w   r1, #4096
484 ; CHECK:    ldrb    r0, [r0, r1]
485 define i32 @ldrb_ri_t2_too_big(ptr %p) {
486 entry:
487   %add.ptr = getelementptr inbounds i8, ptr %p, i32 4096
488   %0 = load i8, ptr %add.ptr, align 1
489   %conv = zext i8 %0 to i32
490   ret i32 %conv
493 ; CHECK-LABEL: ldrh_ri_t2_too_big
494 ; CHECK-T1: movs    r1, #1
495 ; CHECK-T1: lsls    r1, r1, #12
496 ; CHECK-T2: mov.w   r1, #4096
497 ; CHECK:    ldrh    r0, [r0, r1]
498 define i32 @ldrh_ri_t2_too_big(ptr %p) {
499 entry:
500   %add.ptr = getelementptr inbounds i8, ptr %p, i32 4096
501   %0 = load i16, ptr %add.ptr, align 2
502   %conv = zext i16 %0 to i32
503   ret i32 %conv
506 ; CHECK-LABEL: ldr_ri_t2_too_big
507 ; CHECK-T1: movs    r1, #1
508 ; CHECK-T1: lsls    r1, r1, #12
509 ; CHECK-T2: mov.w   r1, #4096
510 ; CHECK:    ldr     r0, [r0, r1]
511 define i32 @ldr_ri_t2_too_big(ptr %p) {
512 entry:
513   %add.ptr = getelementptr inbounds i8, ptr %p, i32 4096
514   %0 = load i32, ptr %add.ptr, align 4
515   ret i32 %0
518 ; CHECK-LABEL: strb_ri_t2_too_big
519 ; CHECK-T1: movs    r2, #1
520 ; CHECK-T1: lsls    r2, r2, #12
521 ; CHECK-T2: mov.w   r2, #4096
522 ; CHECK:    strb    r1, [r0, r2]
523 define void @strb_ri_t2_too_big(ptr %p, i32 %x) {
524 entry:
525   %conv = trunc i32 %x to i8
526   %add.ptr = getelementptr inbounds i8, ptr %p, i32 4096
527   store i8 %conv, ptr %add.ptr, align 1
528   ret void
531 ; CHECK-LABEL: strh_ri_t2_too_big
532 ; CHECK-T1: movs    r2, #1
533 ; CHECK-T1: lsls    r2, r2, #12
534 ; CHECK-T2: mov.w   r2, #4096
535 ; CHECK:    strh    r1, [r0, r2]
536 define void @strh_ri_t2_too_big(ptr %p, i32 %x) {
537 entry:
538   %conv = trunc i32 %x to i16
539   %add.ptr = getelementptr inbounds i8, ptr %p, i32 4096
540   store i16 %conv, ptr %add.ptr, align 2
541   ret void
544 ; CHECK-LABEL: str_ri_t2_too_big
545 ; CHECK-T1: movs    r2, #1
546 ; CHECK-T1: lsls    r2, r2, #12
547 ; CHECK-T2: mov.w   r2, #4096
548 ; CHECK:    str     r1, [r0, r2]
549 define void @str_ri_t2_too_big(ptr %p, i32 %x) {
550 entry:
551   %add.ptr = getelementptr inbounds i8, ptr %p, i32 4096
552   store i32 %x, ptr %add.ptr, align 4
553   ret void
557 ; Negative offset
559 define i32 @ldrsb_ri_negative(ptr %p) {
560 ; CHECK-T1-LABEL: ldrsb_ri_negative:
561 ; CHECK-T1:       @ %bb.0: @ %entry
562 ; CHECK-T1-NEXT:    movs r1, #0
563 ; CHECK-T1-NEXT:    mvns r1, r1
564 ; CHECK-T1-NEXT:    ldrsb r0, [r0, r1]
565 ; CHECK-T1-NEXT:    bx lr
567 ; CHECK-T2-LABEL: ldrsb_ri_negative:
568 ; CHECK-T2:       @ %bb.0: @ %entry
569 ; CHECK-T2-NEXT:    ldrsb r0, [r0, #-1]
570 ; CHECK-T2-NEXT:    bx lr
571 entry:
572   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -1
573   %0 = load i8, ptr %add.ptr, align 1
574   %conv = sext i8 %0 to i32
575   ret i32 %conv
578 define i32 @ldrsh_ri_negative(ptr %p) {
579 ; CHECK-T1-LABEL: ldrsh_ri_negative:
580 ; CHECK-T1:       @ %bb.0: @ %entry
581 ; CHECK-T1-NEXT:    movs r1, #0
582 ; CHECK-T1-NEXT:    mvns r1, r1
583 ; CHECK-T1-NEXT:    ldrsh r0, [r0, r1]
584 ; CHECK-T1-NEXT:    bx lr
586 ; CHECK-T2-LABEL: ldrsh_ri_negative:
587 ; CHECK-T2:       @ %bb.0: @ %entry
588 ; CHECK-T2-NEXT:    ldrsh r0, [r0, #-1]
589 ; CHECK-T2-NEXT:    bx lr
590 entry:
591   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -1
592   %0 = load i16, ptr %add.ptr, align 2
593   %conv = sext i16 %0 to i32
594   ret i32 %conv
597 define i32 @ldrb_ri_negative(ptr %p) {
598 ; CHECK-T1-LABEL: ldrb_ri_negative:
599 ; CHECK-T1:       @ %bb.0: @ %entry
600 ; CHECK-T1-NEXT:    subs r0, r0, #1
601 ; CHECK-T1-NEXT:    ldrb r0, [r0]
602 ; CHECK-T1-NEXT:    bx lr
604 ; CHECK-T2-LABEL: ldrb_ri_negative:
605 ; CHECK-T2:       @ %bb.0: @ %entry
606 ; CHECK-T2-NEXT:    ldrb r0, [r0, #-1]
607 ; CHECK-T2-NEXT:    bx lr
608 entry:
609   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -1
610   %0 = load i8, ptr %add.ptr, align 1
611   %conv = zext i8 %0 to i32
612   ret i32 %conv
615 define i32 @ldrh_ri_negative(ptr %p) {
616 ; CHECK-T1-LABEL: ldrh_ri_negative:
617 ; CHECK-T1:       @ %bb.0: @ %entry
618 ; CHECK-T1-NEXT:    subs r0, r0, #1
619 ; CHECK-T1-NEXT:    ldrh r0, [r0]
620 ; CHECK-T1-NEXT:    bx lr
622 ; CHECK-T2-LABEL: ldrh_ri_negative:
623 ; CHECK-T2:       @ %bb.0: @ %entry
624 ; CHECK-T2-NEXT:    ldrh r0, [r0, #-1]
625 ; CHECK-T2-NEXT:    bx lr
626 entry:
627   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -1
628   %0 = load i16, ptr %add.ptr, align 2
629   %conv = zext i16 %0 to i32
630   ret i32 %conv
633 define i32 @ldr_ri_negative(ptr %p) {
634 ; CHECK-T1-LABEL: ldr_ri_negative:
635 ; CHECK-T1:       @ %bb.0: @ %entry
636 ; CHECK-T1-NEXT:    subs r0, r0, #1
637 ; CHECK-T1-NEXT:    ldr r0, [r0]
638 ; CHECK-T1-NEXT:    bx lr
640 ; CHECK-T2-LABEL: ldr_ri_negative:
641 ; CHECK-T2:       @ %bb.0: @ %entry
642 ; CHECK-T2-NEXT:    ldr r0, [r0, #-1]
643 ; CHECK-T2-NEXT:    bx lr
644 entry:
645   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -1
646   %0 = load i32, ptr %add.ptr, align 4
647   ret i32 %0
650 define void @strb_ri_negative(ptr %p, i32 %x) {
651 ; CHECK-T1-LABEL: strb_ri_negative:
652 ; CHECK-T1:       @ %bb.0: @ %entry
653 ; CHECK-T1-NEXT:    subs r0, r0, #1
654 ; CHECK-T1-NEXT:    strb r1, [r0]
655 ; CHECK-T1-NEXT:    bx lr
657 ; CHECK-T2-LABEL: strb_ri_negative:
658 ; CHECK-T2:       @ %bb.0: @ %entry
659 ; CHECK-T2-NEXT:    strb r1, [r0, #-1]
660 ; CHECK-T2-NEXT:    bx lr
661 entry:
662   %conv = trunc i32 %x to i8
663   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -1
664   store i8 %conv, ptr %add.ptr, align 1
665   ret void
668 define void @strh_ri_negative(ptr %p, i32 %x) {
669 ; CHECK-T1-LABEL: strh_ri_negative:
670 ; CHECK-T1:       @ %bb.0: @ %entry
671 ; CHECK-T1-NEXT:    subs r0, r0, #1
672 ; CHECK-T1-NEXT:    strh r1, [r0]
673 ; CHECK-T1-NEXT:    bx lr
675 ; CHECK-T2-LABEL: strh_ri_negative:
676 ; CHECK-T2:       @ %bb.0: @ %entry
677 ; CHECK-T2-NEXT:    strh r1, [r0, #-1]
678 ; CHECK-T2-NEXT:    bx lr
679 entry:
680   %conv = trunc i32 %x to i16
681   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -1
682   store i16 %conv, ptr %add.ptr, align 2
683   ret void
686 define void @str_ri_negative(ptr %p, i32 %x) {
687 ; CHECK-T1-LABEL: str_ri_negative:
688 ; CHECK-T1:       @ %bb.0: @ %entry
689 ; CHECK-T1-NEXT:    subs r0, r0, #1
690 ; CHECK-T1-NEXT:    str r1, [r0]
691 ; CHECK-T1-NEXT:    bx lr
693 ; CHECK-T2-LABEL: str_ri_negative:
694 ; CHECK-T2:       @ %bb.0: @ %entry
695 ; CHECK-T2-NEXT:    str r1, [r0, #-1]
696 ; CHECK-T2-NEXT:    bx lr
697 entry:
698   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -1
699   store i32 %x, ptr %add.ptr, align 4
700   ret void
704 ; Negative 255 offset
706 define i32 @ldrsb_ri_negative255(ptr %p) {
707 ; CHECK-T1-LABEL: ldrsb_ri_negative255:
708 ; CHECK-T1:       @ %bb.0: @ %entry
709 ; CHECK-T1-NEXT:    movs r1, #254
710 ; CHECK-T1-NEXT:    mvns r1, r1
711 ; CHECK-T1-NEXT:    ldrsb r0, [r0, r1]
712 ; CHECK-T1-NEXT:    bx lr
714 ; CHECK-T2-LABEL: ldrsb_ri_negative255:
715 ; CHECK-T2:       @ %bb.0: @ %entry
716 ; CHECK-T2-NEXT:    ldrsb r0, [r0, #-255]
717 ; CHECK-T2-NEXT:    bx lr
718 entry:
719   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -255
720   %0 = load i8, ptr %add.ptr, align 1
721   %conv = sext i8 %0 to i32
722   ret i32 %conv
725 define i32 @ldrsh_ri_negative255(ptr %p) {
726 ; CHECK-T1-LABEL: ldrsh_ri_negative255:
727 ; CHECK-T1:       @ %bb.0: @ %entry
728 ; CHECK-T1-NEXT:    movs r1, #254
729 ; CHECK-T1-NEXT:    mvns r1, r1
730 ; CHECK-T1-NEXT:    ldrsh r0, [r0, r1]
731 ; CHECK-T1-NEXT:    bx lr
733 ; CHECK-T2-LABEL: ldrsh_ri_negative255:
734 ; CHECK-T2:       @ %bb.0: @ %entry
735 ; CHECK-T2-NEXT:    ldrsh r0, [r0, #-255]
736 ; CHECK-T2-NEXT:    bx lr
737 entry:
738   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -255
739   %0 = load i16, ptr %add.ptr, align 2
740   %conv = sext i16 %0 to i32
741   ret i32 %conv
744 define i32 @ldrb_ri_negative255(ptr %p) {
745 ; CHECK-T1-LABEL: ldrb_ri_negative255:
746 ; CHECK-T1:       @ %bb.0: @ %entry
747 ; CHECK-T1-NEXT:    subs r0, #255
748 ; CHECK-T1-NEXT:    ldrb r0, [r0]
749 ; CHECK-T1-NEXT:    bx lr
751 ; CHECK-T2-LABEL: ldrb_ri_negative255:
752 ; CHECK-T2:       @ %bb.0: @ %entry
753 ; CHECK-T2-NEXT:    ldrb r0, [r0, #-255]
754 ; CHECK-T2-NEXT:    bx lr
755 entry:
756   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -255
757   %0 = load i8, ptr %add.ptr, align 1
758   %conv = zext i8 %0 to i32
759   ret i32 %conv
762 define i32 @ldrh_ri_negative255(ptr %p) {
763 ; CHECK-T1-LABEL: ldrh_ri_negative255:
764 ; CHECK-T1:       @ %bb.0: @ %entry
765 ; CHECK-T1-NEXT:    subs r0, #255
766 ; CHECK-T1-NEXT:    ldrh r0, [r0]
767 ; CHECK-T1-NEXT:    bx lr
769 ; CHECK-T2-LABEL: ldrh_ri_negative255:
770 ; CHECK-T2:       @ %bb.0: @ %entry
771 ; CHECK-T2-NEXT:    ldrh r0, [r0, #-255]
772 ; CHECK-T2-NEXT:    bx lr
773 entry:
774   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -255
775   %0 = load i16, ptr %add.ptr, align 2
776   %conv = zext i16 %0 to i32
777   ret i32 %conv
780 define i32 @ldr_ri_negative255(ptr %p) {
781 ; CHECK-T1-LABEL: ldr_ri_negative255:
782 ; CHECK-T1:       @ %bb.0: @ %entry
783 ; CHECK-T1-NEXT:    subs r0, #255
784 ; CHECK-T1-NEXT:    ldr r0, [r0]
785 ; CHECK-T1-NEXT:    bx lr
787 ; CHECK-T2-LABEL: ldr_ri_negative255:
788 ; CHECK-T2:       @ %bb.0: @ %entry
789 ; CHECK-T2-NEXT:    ldr r0, [r0, #-255]
790 ; CHECK-T2-NEXT:    bx lr
791 entry:
792   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -255
793   %0 = load i32, ptr %add.ptr, align 4
794   ret i32 %0
797 define void @strb_ri_negative255(ptr %p, i32 %x) {
798 ; CHECK-T1-LABEL: strb_ri_negative255:
799 ; CHECK-T1:       @ %bb.0: @ %entry
800 ; CHECK-T1-NEXT:    subs r0, #255
801 ; CHECK-T1-NEXT:    strb r1, [r0]
802 ; CHECK-T1-NEXT:    bx lr
804 ; CHECK-T2-LABEL: strb_ri_negative255:
805 ; CHECK-T2:       @ %bb.0: @ %entry
806 ; CHECK-T2-NEXT:    strb r1, [r0, #-255]
807 ; CHECK-T2-NEXT:    bx lr
808 entry:
809   %conv = trunc i32 %x to i8
810   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -255
811   store i8 %conv, ptr %add.ptr, align 1
812   ret void
815 define void @strh_ri_negative255(ptr %p, i32 %x) {
816 ; CHECK-T1-LABEL: strh_ri_negative255:
817 ; CHECK-T1:       @ %bb.0: @ %entry
818 ; CHECK-T1-NEXT:    subs r0, #255
819 ; CHECK-T1-NEXT:    strh r1, [r0]
820 ; CHECK-T1-NEXT:    bx lr
822 ; CHECK-T2-LABEL: strh_ri_negative255:
823 ; CHECK-T2:       @ %bb.0: @ %entry
824 ; CHECK-T2-NEXT:    strh r1, [r0, #-255]
825 ; CHECK-T2-NEXT:    bx lr
826 entry:
827   %conv = trunc i32 %x to i16
828   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -255
829   store i16 %conv, ptr %add.ptr, align 2
830   ret void
833 define void @str_ri_negative255(ptr %p, i32 %x) {
834 ; CHECK-T1-LABEL: str_ri_negative255:
835 ; CHECK-T1:       @ %bb.0: @ %entry
836 ; CHECK-T1-NEXT:    subs r0, #255
837 ; CHECK-T1-NEXT:    str r1, [r0]
838 ; CHECK-T1-NEXT:    bx lr
840 ; CHECK-T2-LABEL: str_ri_negative255:
841 ; CHECK-T2:       @ %bb.0: @ %entry
842 ; CHECK-T2-NEXT:    str r1, [r0, #-255]
843 ; CHECK-T2-NEXT:    bx lr
844 entry:
845   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -255
846   store i32 %x, ptr %add.ptr, align 4
847   ret void
851 ; Negative 256 offset
853 define i32 @ldrsb_ri_negative256(ptr %p) {
854 ; CHECK-T1-LABEL: ldrsb_ri_negative256:
855 ; CHECK-T1:       @ %bb.0: @ %entry
856 ; CHECK-T1-NEXT:    movs r1, #255
857 ; CHECK-T1-NEXT:    mvns r1, r1
858 ; CHECK-T1-NEXT:    ldrsb r0, [r0, r1]
859 ; CHECK-T1-NEXT:    bx lr
861 ; CHECK-T2-LABEL: ldrsb_ri_negative256:
862 ; CHECK-T2:       @ %bb.0: @ %entry
863 ; CHECK-T2-NEXT:    mvn r1, #255
864 ; CHECK-T2-NEXT:    ldrsb r0, [r0, r1]
865 ; CHECK-T2-NEXT:    bx lr
866 entry:
867   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -256
868   %0 = load i8, ptr %add.ptr, align 1
869   %conv = sext i8 %0 to i32
870   ret i32 %conv
873 define i32 @ldrsh_ri_negative256(ptr %p) {
874 ; CHECK-T1-LABEL: ldrsh_ri_negative256:
875 ; CHECK-T1:       @ %bb.0: @ %entry
876 ; CHECK-T1-NEXT:    movs r1, #255
877 ; CHECK-T1-NEXT:    mvns r1, r1
878 ; CHECK-T1-NEXT:    ldrsh r0, [r0, r1]
879 ; CHECK-T1-NEXT:    bx lr
881 ; CHECK-T2-LABEL: ldrsh_ri_negative256:
882 ; CHECK-T2:       @ %bb.0: @ %entry
883 ; CHECK-T2-NEXT:    mvn r1, #255
884 ; CHECK-T2-NEXT:    ldrsh r0, [r0, r1]
885 ; CHECK-T2-NEXT:    bx lr
886 entry:
887   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -256
888   %0 = load i16, ptr %add.ptr, align 2
889   %conv = sext i16 %0 to i32
890   ret i32 %conv
893 define i32 @ldrb_ri_negative256(ptr %p) {
894 ; CHECK-T1-LABEL: ldrb_ri_negative256:
895 ; CHECK-T1:       @ %bb.0: @ %entry
896 ; CHECK-T1-NEXT:    movs r1, #255
897 ; CHECK-T1-NEXT:    mvns r1, r1
898 ; CHECK-T1-NEXT:    ldrb r0, [r0, r1]
899 ; CHECK-T1-NEXT:    bx lr
901 ; CHECK-T2-LABEL: ldrb_ri_negative256:
902 ; CHECK-T2:       @ %bb.0: @ %entry
903 ; CHECK-T2-NEXT:    mvn r1, #255
904 ; CHECK-T2-NEXT:    ldrb r0, [r0, r1]
905 ; CHECK-T2-NEXT:    bx lr
906 entry:
907   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -256
908   %0 = load i8, ptr %add.ptr, align 1
909   %conv = zext i8 %0 to i32
910   ret i32 %conv
913 define i32 @ldrh_ri_negative256(ptr %p) {
914 ; CHECK-T1-LABEL: ldrh_ri_negative256:
915 ; CHECK-T1:       @ %bb.0: @ %entry
916 ; CHECK-T1-NEXT:    movs r1, #255
917 ; CHECK-T1-NEXT:    mvns r1, r1
918 ; CHECK-T1-NEXT:    ldrh r0, [r0, r1]
919 ; CHECK-T1-NEXT:    bx lr
921 ; CHECK-T2-LABEL: ldrh_ri_negative256:
922 ; CHECK-T2:       @ %bb.0: @ %entry
923 ; CHECK-T2-NEXT:    mvn r1, #255
924 ; CHECK-T2-NEXT:    ldrh r0, [r0, r1]
925 ; CHECK-T2-NEXT:    bx lr
926 entry:
927   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -256
928   %0 = load i16, ptr %add.ptr, align 2
929   %conv = zext i16 %0 to i32
930   ret i32 %conv
933 define i32 @ldr_ri_negative256(ptr %p) {
934 ; CHECK-T1-LABEL: ldr_ri_negative256:
935 ; CHECK-T1:       @ %bb.0: @ %entry
936 ; CHECK-T1-NEXT:    movs r1, #255
937 ; CHECK-T1-NEXT:    mvns r1, r1
938 ; CHECK-T1-NEXT:    ldr r0, [r0, r1]
939 ; CHECK-T1-NEXT:    bx lr
941 ; CHECK-T2-LABEL: ldr_ri_negative256:
942 ; CHECK-T2:       @ %bb.0: @ %entry
943 ; CHECK-T2-NEXT:    mvn r1, #255
944 ; CHECK-T2-NEXT:    ldr r0, [r0, r1]
945 ; CHECK-T2-NEXT:    bx lr
946 entry:
947   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -256
948   %0 = load i32, ptr %add.ptr, align 4
949   ret i32 %0
952 define void @strb_ri_negative256(ptr %p, i32 %x) {
953 ; CHECK-T1-LABEL: strb_ri_negative256:
954 ; CHECK-T1:       @ %bb.0: @ %entry
955 ; CHECK-T1-NEXT:    movs r2, #255
956 ; CHECK-T1-NEXT:    mvns r2, r2
957 ; CHECK-T1-NEXT:    strb r1, [r0, r2]
958 ; CHECK-T1-NEXT:    bx lr
960 ; CHECK-T2-LABEL: strb_ri_negative256:
961 ; CHECK-T2:       @ %bb.0: @ %entry
962 ; CHECK-T2-NEXT:    mvn r2, #255
963 ; CHECK-T2-NEXT:    strb r1, [r0, r2]
964 ; CHECK-T2-NEXT:    bx lr
965 entry:
966   %conv = trunc i32 %x to i8
967   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -256
968   store i8 %conv, ptr %add.ptr, align 1
969   ret void
972 define void @strh_ri_negative256(ptr %p, i32 %x) {
973 ; CHECK-T1-LABEL: strh_ri_negative256:
974 ; CHECK-T1:       @ %bb.0: @ %entry
975 ; CHECK-T1-NEXT:    movs r2, #255
976 ; CHECK-T1-NEXT:    mvns r2, r2
977 ; CHECK-T1-NEXT:    strh r1, [r0, r2]
978 ; CHECK-T1-NEXT:    bx lr
980 ; CHECK-T2-LABEL: strh_ri_negative256:
981 ; CHECK-T2:       @ %bb.0: @ %entry
982 ; CHECK-T2-NEXT:    mvn r2, #255
983 ; CHECK-T2-NEXT:    strh r1, [r0, r2]
984 ; CHECK-T2-NEXT:    bx lr
985 entry:
986   %conv = trunc i32 %x to i16
987   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -256
988   store i16 %conv, ptr %add.ptr, align 2
989   ret void
992 define void @str_ri_negative256(ptr %p, i32 %x) {
993 ; CHECK-T1-LABEL: str_ri_negative256:
994 ; CHECK-T1:       @ %bb.0: @ %entry
995 ; CHECK-T1-NEXT:    movs r2, #255
996 ; CHECK-T1-NEXT:    mvns r2, r2
997 ; CHECK-T1-NEXT:    str r1, [r0, r2]
998 ; CHECK-T1-NEXT:    bx lr
1000 ; CHECK-T2-LABEL: str_ri_negative256:
1001 ; CHECK-T2:       @ %bb.0: @ %entry
1002 ; CHECK-T2-NEXT:    mvn r2, #255
1003 ; CHECK-T2-NEXT:    str r1, [r0, r2]
1004 ; CHECK-T2-NEXT:    bx lr
1005 entry:
1006   %add.ptr = getelementptr inbounds i8, ptr %p, i32 -256
1007   store i32 %x, ptr %add.ptr, align 4
1008   ret void