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
7 ; CHECK-LABEL: ldrsb_rr
8 ; CHECK: ldrsb r0, [r0, r1]
9 define i32 @ldrsb_rr(ptr %p, i32 %n) {
11 %arrayidx = getelementptr inbounds i8, ptr %p, i32 %n
12 %0 = load i8, ptr %arrayidx, align 1
13 %conv = sext i8 %0 to i32
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) {
23 %arrayidx = getelementptr inbounds i16, ptr %p, i32 %n
24 %0 = load i16, ptr %arrayidx, align 2
25 %conv = sext i16 %0 to i32
29 ; CHECK-LABEL: ldrb_rr
30 ; CHECK: ldrb r0, [r0, r1]
31 define i32 @ldrb_rr(ptr %p, i32 %n) {
33 %arrayidx = getelementptr inbounds i8, ptr %p, i32 %n
34 %0 = load i8, ptr %arrayidx, align 1
35 %conv = zext i8 %0 to i32
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) {
45 %arrayidx = getelementptr inbounds i16, ptr %p, i32 %n
46 %0 = load i16, ptr %arrayidx, align 2
47 %conv = zext i16 %0 to i32
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) {
57 %arrayidx = getelementptr inbounds i32, ptr %p, i32 %n
58 %0 = load i32, ptr %arrayidx, align 4
62 ; CHECK-LABEL: strb_rr
63 ; CHECK: strb r2, [r0, r1]
64 define void @strb_rr(ptr %p, i32 %n, i32 %x) {
66 %conv = trunc i32 %x to i8
67 %arrayidx = getelementptr inbounds i8, ptr %p, i32 %n
68 store i8 %conv, ptr %arrayidx, align 1
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) {
78 %conv = trunc i32 %x to i16
79 %arrayidx = getelementptr inbounds i16, ptr %p, i32 %n
80 store i16 %conv, ptr %arrayidx, align 2
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) {
90 %arrayidx = getelementptr inbounds i32, ptr %p, i32 %n
91 store i32 %x, ptr %arrayidx, align 4
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) {
104 %0 = load i8, ptr %p, align 1
105 %conv = sext i8 %0 to i32
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) {
115 %0 = load i16, ptr %p, align 2
116 %conv = sext i16 %0 to i32
120 ; CHECK-LABEL: ldrb_ri_zero
121 ; CHECK: ldrb r0, [r0]
122 define i32 @ldrb_ri_zero(ptr %p) {
124 %0 = load i8, ptr %p, align 1
125 %conv = zext i8 %0 to i32
129 ; CHECK-LABEL: ldrh_ri_zero
130 ; CHECK: ldrh r0, [r0]
131 define i32 @ldrh_ri_zero(ptr %p) {
133 %0 = load i16, ptr %p, align 2
134 %conv = zext i16 %0 to i32
138 ; CHECK-LABEL: ldr_ri_zero
139 ; CHECK: ldr r0, [r0]
140 define i32 @ldr_ri_zero(ptr %p) {
142 %0 = load i32, ptr %p, align 4
146 ; CHECK-LABEL: strb_ri_zero
147 ; CHECK: strb r1, [r0]
148 define void @strb_ri_zero(ptr %p, i32 %x) {
150 %conv = trunc i32 %x to i8
151 store i8 %conv, ptr %p, align 1
155 ; CHECK-LABEL: strh_ri_zero
156 ; CHECK: strh r1, [r0]
157 define void @strh_ri_zero(ptr %p, i32 %x) {
159 %conv = trunc i32 %x to i16
160 store i16 %conv, ptr %p, align 2
164 ; CHECK-LABEL: str_ri_zero
165 ; CHECK: str r1, [r0]
166 define void @str_ri_zero(ptr %p, i32 %x) {
168 store i32 %x, ptr %p, align 4
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) {
181 %arrayidx = getelementptr inbounds i8, ptr %p, i32 31
182 %0 = load i8, ptr %arrayidx, align 1
183 %conv = sext i8 %0 to i32
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) {
193 %arrayidx = getelementptr inbounds i16, ptr %p, i32 31
194 %0 = load i16, ptr %arrayidx, align 2
195 %conv = sext i16 %0 to i32
199 ; CHECK-LABEL: ldrb_ri_t1_max
200 ; CHECK: ldrb r0, [r0, #31]
201 define i32 @ldrb_ri_t1_max(ptr %p) {
203 %arrayidx = getelementptr inbounds i8, ptr %p, i32 31
204 %0 = load i8, ptr %arrayidx, align 1
205 %conv = zext i8 %0 to i32
209 ; CHECK-LABEL: ldrh_ri_t1_max
210 ; CHECK: ldrh r0, [r0, #62]
211 define i32 @ldrh_ri_t1_max(ptr %p) {
213 %arrayidx = getelementptr inbounds i16, ptr %p, i32 31
214 %0 = load i16, ptr %arrayidx, align 2
215 %conv = zext i16 %0 to i32
219 ; CHECK-LABEL: ldr_ri_t1_max
220 ; CHECK: ldr r0, [r0, #124]
221 define i32 @ldr_ri_t1_max(ptr %p) {
223 %arrayidx = getelementptr inbounds i32, ptr %p, i32 31
224 %0 = load i32, ptr %arrayidx, align 4
228 ; CHECK-LABEL: strb_ri_t1_max
229 ; CHECK: strb r1, [r0, #31]
230 define void @strb_ri_t1_max(ptr %p, i32 %x) {
232 %conv = trunc i32 %x to i8
233 %arrayidx = getelementptr inbounds i8, ptr %p, i32 31
234 store i8 %conv, ptr %arrayidx, align 1
238 ; CHECK-LABEL: strh_ri_t1_max
239 ; CHECK: strh r1, [r0, #62]
240 define void @strh_ri_t1_max(ptr %p, i32 %x) {
242 %conv = trunc i32 %x to i16
243 %arrayidx = getelementptr inbounds i16, ptr %p, i32 31
244 store i16 %conv, ptr %arrayidx, align 2
248 ; CHECK-LABEL: str_ri_t1_max
249 ; CHECK: str r1, [r0, #124]
250 define void @str_ri_t1_max(ptr %p, i32 %x) {
252 %arrayidx = getelementptr inbounds i32, ptr %p, i32 31
253 store i32 %x, ptr %arrayidx, align 4
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) {
266 %arrayidx = getelementptr inbounds i8, ptr %p, i32 32
267 %0 = load i8, ptr %arrayidx, align 1
268 %conv = sext i8 %0 to i32
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) {
278 %arrayidx = getelementptr inbounds i16, ptr %p, i32 32
279 %0 = load i16, ptr %arrayidx, align 2
280 %conv = sext i16 %0 to i32
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) {
290 %arrayidx = getelementptr inbounds i8, ptr %p, i32 32
291 %0 = load i8, ptr %arrayidx, align 1
292 %conv = zext i8 %0 to i32
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) {
302 %arrayidx = getelementptr inbounds i16, ptr %p, i32 32
303 %0 = load i16, ptr %arrayidx, align 2
304 %conv = zext i16 %0 to i32
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) {
314 %arrayidx = getelementptr inbounds i32, ptr %p, i32 32
315 %0 = load i32, ptr %arrayidx, align 4
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) {
325 %conv = trunc i32 %x to i8
326 %arrayidx = getelementptr inbounds i8, ptr %p, i32 32
327 store i8 %conv, ptr %arrayidx, align 1
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) {
337 %conv = trunc i32 %x to i16
338 %arrayidx = getelementptr inbounds i16, ptr %p, i32 32
339 store i16 %conv, ptr %arrayidx, align 2
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) {
349 %arrayidx = getelementptr inbounds i32, ptr %p, i32 32
350 store i32 %x, ptr %arrayidx, align 4
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) {
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
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) {
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
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) {
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
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) {
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
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) {
411 %add.ptr = getelementptr inbounds i8, ptr %p, i32 4095
412 %0 = load i32, ptr %add.ptr, align 4
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) {
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
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) {
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
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) {
446 %add.ptr = getelementptr inbounds i8, ptr %p, i32 4095
447 store i32 %x, ptr %add.ptr, align 4
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) {
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
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) {
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
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) {
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
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) {
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
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) {
513 %add.ptr = getelementptr inbounds i8, ptr %p, i32 4096
514 %0 = load i32, ptr %add.ptr, align 4
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) {
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
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) {
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
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) {
551 %add.ptr = getelementptr inbounds i8, ptr %p, i32 4096
552 store i32 %x, ptr %add.ptr, align 4
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
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
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
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
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
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
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
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
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
645 %add.ptr = getelementptr inbounds i8, ptr %p, i32 -1
646 %0 = load i32, ptr %add.ptr, align 4
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
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
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
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
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
698 %add.ptr = getelementptr inbounds i8, ptr %p, i32 -1
699 store i32 %x, ptr %add.ptr, align 4
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
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
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
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
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
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
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
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
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
792 %add.ptr = getelementptr inbounds i8, ptr %p, i32 -255
793 %0 = load i32, ptr %add.ptr, align 4
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
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
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
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
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
845 %add.ptr = getelementptr inbounds i8, ptr %p, i32 -255
846 store i32 %x, ptr %add.ptr, align 4
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
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
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
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
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
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
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
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
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
947 %add.ptr = getelementptr inbounds i8, ptr %p, i32 -256
948 %0 = load i32, ptr %add.ptr, align 4
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
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
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
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
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
1006 %add.ptr = getelementptr inbounds i8, ptr %p, i32 -256
1007 store i32 %x, ptr %add.ptr, align 4