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(i8* %p, i32 %n) {
11 %arrayidx = getelementptr inbounds i8, i8* %p, i32 %n
12 %0 = load i8, i8* %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(i16* %p, i32 %n) {
23 %arrayidx = getelementptr inbounds i16, i16* %p, i32 %n
24 %0 = load i16, i16* %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(i8* %p, i32 %n) {
33 %arrayidx = getelementptr inbounds i8, i8* %p, i32 %n
34 %0 = load i8, i8* %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(i16* %p, i32 %n) {
45 %arrayidx = getelementptr inbounds i16, i16* %p, i32 %n
46 %0 = load i16, i16* %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(i32* %p, i32 %n) {
57 %arrayidx = getelementptr inbounds i32, i32* %p, i32 %n
58 %0 = load i32, i32* %arrayidx, align 4
62 ; CHECK-LABEL: strb_rr
63 ; CHECK: strb r2, [r0, r1]
64 define void @strb_rr(i8* %p, i32 %n, i32 %x) {
66 %conv = trunc i32 %x to i8
67 %arrayidx = getelementptr inbounds i8, i8* %p, i32 %n
68 store i8 %conv, i8* %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(i16* %p, i32 %n, i32 %x) {
78 %conv = trunc i32 %x to i16
79 %arrayidx = getelementptr inbounds i16, i16* %p, i32 %n
80 store i16 %conv, i16* %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(i32* %p, i32 %n, i32 %x) {
90 %arrayidx = getelementptr inbounds i32, i32* %p, i32 %n
91 store i32 %x, i32* %arrayidx, align 4
96 ; Immediate offset of zero
98 ; CHECK-LABEL: ldrsb_ri_zero
99 ; CHECK-T1: ldrb r0, [r0]
100 ; CHECK-T1: sxtb r0, r0
101 ; CHECK-T2: ldrsb.w r0, [r0]
102 define i32 @ldrsb_ri_zero(i8* %p) {
104 %0 = load i8, i8* %p, align 1
105 %conv = sext i8 %0 to i32
109 ; CHECK-LABEL: ldrsh_ri_zero
110 ; CHECK-T1: ldrh r0, [r0]
111 ; CHECK-T1: sxth r0, r0
112 ; CHECK-T2: ldrsh.w r0, [r0]
113 define i32 @ldrsh_ri_zero(i16* %p) {
115 %0 = load i16, i16* %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(i8* %p) {
124 %0 = load i8, i8* %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(i16* %p) {
133 %0 = load i16, i16* %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(i32* %p) {
142 %0 = load i32, i32* %p, align 4
146 ; CHECK-LABEL: strb_ri_zero
147 ; CHECK: strb r1, [r0]
148 define void @strb_ri_zero(i8* %p, i32 %x) {
150 %conv = trunc i32 %x to i8
151 store i8 %conv, i8* %p, align 1
155 ; CHECK-LABEL: strh_ri_zero
156 ; CHECK: strh r1, [r0]
157 define void @strh_ri_zero(i16* %p, i32 %x) {
159 %conv = trunc i32 %x to i16
160 store i16 %conv, i16* %p, align 2
164 ; CHECK-LABEL: str_ri_zero
165 ; CHECK: str r1, [r0]
166 define void @str_ri_zero(i32* %p, i32 %x) {
168 store i32 %x, i32* %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(i8* %p) {
181 %arrayidx = getelementptr inbounds i8, i8* %p, i32 31
182 %0 = load i8, i8* %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(i16* %p) {
193 %arrayidx = getelementptr inbounds i16, i16* %p, i32 31
194 %0 = load i16, i16* %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(i8* %p) {
203 %arrayidx = getelementptr inbounds i8, i8* %p, i32 31
204 %0 = load i8, i8* %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(i16* %p) {
213 %arrayidx = getelementptr inbounds i16, i16* %p, i32 31
214 %0 = load i16, i16* %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(i32* %p) {
223 %arrayidx = getelementptr inbounds i32, i32* %p, i32 31
224 %0 = load i32, i32* %arrayidx, align 4
228 ; CHECK-LABEL: strb_ri_t1_max
229 ; CHECK: strb r1, [r0, #31]
230 define void @strb_ri_t1_max(i8* %p, i32 %x) {
232 %conv = trunc i32 %x to i8
233 %arrayidx = getelementptr inbounds i8, i8* %p, i32 31
234 store i8 %conv, i8* %arrayidx, align 1
238 ; CHECK-LABEL: strh_ri_t1_max
239 ; CHECK: strh r1, [r0, #62]
240 define void @strh_ri_t1_max(i16* %p, i32 %x) {
242 %conv = trunc i32 %x to i16
243 %arrayidx = getelementptr inbounds i16, i16* %p, i32 31
244 store i16 %conv, i16* %arrayidx, align 2
248 ; CHECK-LABEL: str_ri_t1_max
249 ; CHECK: str r1, [r0, #124]
250 define void @str_ri_t1_max(i32* %p, i32 %x) {
252 %arrayidx = getelementptr inbounds i32, i32* %p, i32 31
253 store i32 %x, i32* %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(i8* %p) {
266 %arrayidx = getelementptr inbounds i8, i8* %p, i32 32
267 %0 = load i8, i8* %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(i16* %p) {
278 %arrayidx = getelementptr inbounds i16, i16* %p, i32 32
279 %0 = load i16, i16* %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(i8* %p) {
290 %arrayidx = getelementptr inbounds i8, i8* %p, i32 32
291 %0 = load i8, i8* %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(i16* %p) {
302 %arrayidx = getelementptr inbounds i16, i16* %p, i32 32
303 %0 = load i16, i16* %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(i32* %p) {
314 %arrayidx = getelementptr inbounds i32, i32* %p, i32 32
315 %0 = load i32, i32* %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(i8* %p, i32 %x) {
325 %conv = trunc i32 %x to i8
326 %arrayidx = getelementptr inbounds i8, i8* %p, i32 32
327 store i8 %conv, i8* %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(i16* %p, i32 %x) {
337 %conv = trunc i32 %x to i16
338 %arrayidx = getelementptr inbounds i16, i16* %p, i32 32
339 store i16 %conv, i16* %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(i32* %p, i32 %x) {
349 %arrayidx = getelementptr inbounds i32, i32* %p, i32 32
350 store i32 %x, i32* %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(i8* %p) {
363 %add.ptr = getelementptr inbounds i8, i8* %p, i32 4095
364 %0 = load i8, i8* %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(i8* %p) {
375 %add.ptr = getelementptr inbounds i8, i8* %p, i32 4095
376 %0 = bitcast i8* %add.ptr to i16*
377 %1 = load i16, i16* %0, align 2
378 %conv = sext i16 %1 to i32
382 ; CHECK-LABEL: ldrb_ri_t2_max
383 ; CHECK-T1: ldr r1, .LCP
384 ; CHECK-T1: ldrb r0, [r0, r1]
385 ; CHECK-T2: ldrb.w r0, [r0, #4095]
386 define i32 @ldrb_ri_t2_max(i8* %p) {
388 %add.ptr = getelementptr inbounds i8, i8* %p, i32 4095
389 %0 = load i8, i8* %add.ptr, align 1
390 %conv = zext i8 %0 to i32
394 ; CHECK-LABEL: ldrh_ri_t2_max
395 ; CHECK-T1: ldr r1, .LCP
396 ; CHECK-T1: ldrh r0, [r0, r1]
397 ; CHECK-T2: ldrh.w r0, [r0, #4095]
398 define i32 @ldrh_ri_t2_max(i8* %p) {
400 %add.ptr = getelementptr inbounds i8, i8* %p, i32 4095
401 %0 = bitcast i8* %add.ptr to i16*
402 %1 = load i16, i16* %0, align 2
403 %conv = zext i16 %1 to i32
407 ; CHECK-LABEL: ldr_ri_t2_max
408 ; CHECK-T1: ldr r1, .LCP
409 ; CHECK-T1: ldr r0, [r0, r1]
410 ; CHECK-T2: ldr.w r0, [r0, #4095]
411 define i32 @ldr_ri_t2_max(i8* %p) {
413 %add.ptr = getelementptr inbounds i8, i8* %p, i32 4095
414 %0 = bitcast i8* %add.ptr to i32*
415 %1 = load i32, i32* %0, align 4
419 ; CHECK-LABEL: strb_ri_t2_max
420 ; CHECK-T1: ldr r2, .LCP
421 ; CHECK-T1: strb r1, [r0, r2]
422 ; CHECK-T2: strb.w r1, [r0, #4095]
423 define void @strb_ri_t2_max(i8* %p, i32 %x) {
425 %conv = trunc i32 %x to i8
426 %add.ptr = getelementptr inbounds i8, i8* %p, i32 4095
427 store i8 %conv, i8* %add.ptr, align 1
431 ; CHECK-LABEL: strh_ri_t2_max
432 ; CHECK-T1: ldr r2, .LCP
433 ; CHECK-T1: strh r1, [r0, r2]
434 ; CHECK-T2: strh.w r1, [r0, #4095]
435 define void @strh_ri_t2_max(i8* %p, i32 %x) {
437 %conv = trunc i32 %x to i16
438 %add.ptr = getelementptr inbounds i8, i8* %p, i32 4095
439 %0 = bitcast i8* %add.ptr to i16*
440 store i16 %conv, i16* %0, align 2
444 ; CHECK-LABEL: str_ri_t2_max
445 ; CHECK-T1: ldr r2, .LCP
446 ; CHECK-T1: str r1, [r0, r2]
447 ; CHECK-T2: str.w r1, [r0, #4095]
448 define void @str_ri_t2_max(i8* %p, i32 %x) {
450 %add.ptr = getelementptr inbounds i8, i8* %p, i32 4095
451 %0 = bitcast i8* %add.ptr to i32*
452 store i32 %x, i32* %0, align 4
457 ; One past maximum Thumb-2 immediate offset
459 ; CHECK-LABEL: ldrsb_ri_t2_too_big
460 ; CHECK-T1: movs r1, #1
461 ; CHECK-T1: lsls r1, r1, #12
462 ; CHECK-T2: mov.w r1, #4096
463 ; CHECK: ldrsb r0, [r0, r1]
464 define i32 @ldrsb_ri_t2_too_big(i8* %p) {
466 %add.ptr = getelementptr inbounds i8, i8* %p, i32 4096
467 %0 = load i8, i8* %add.ptr, align 1
468 %conv = sext i8 %0 to i32
472 ; CHECK-LABEL: ldrsh_ri_t2_too_big
473 ; CHECK-T1: movs r1, #1
474 ; CHECK-T1: lsls r1, r1, #12
475 ; CHECK-T2: mov.w r1, #4096
476 ; CHECK: ldrsh r0, [r0, r1]
477 define i32 @ldrsh_ri_t2_too_big(i8* %p) {
479 %add.ptr = getelementptr inbounds i8, i8* %p, i32 4096
480 %0 = bitcast i8* %add.ptr to i16*
481 %1 = load i16, i16* %0, align 2
482 %conv = sext i16 %1 to i32
486 ; CHECK-LABEL: ldrb_ri_t2_too_big
487 ; CHECK-T1: movs r1, #1
488 ; CHECK-T1: lsls r1, r1, #12
489 ; CHECK-T2: mov.w r1, #4096
490 ; CHECK: ldrb r0, [r0, r1]
491 define i32 @ldrb_ri_t2_too_big(i8* %p) {
493 %add.ptr = getelementptr inbounds i8, i8* %p, i32 4096
494 %0 = load i8, i8* %add.ptr, align 1
495 %conv = zext i8 %0 to i32
499 ; CHECK-LABEL: ldrh_ri_t2_too_big
500 ; CHECK-T1: movs r1, #1
501 ; CHECK-T1: lsls r1, r1, #12
502 ; CHECK-T2: mov.w r1, #4096
503 ; CHECK: ldrh r0, [r0, r1]
504 define i32 @ldrh_ri_t2_too_big(i8* %p) {
506 %add.ptr = getelementptr inbounds i8, i8* %p, i32 4096
507 %0 = bitcast i8* %add.ptr to i16*
508 %1 = load i16, i16* %0, align 2
509 %conv = zext i16 %1 to i32
513 ; CHECK-LABEL: ldr_ri_t2_too_big
514 ; CHECK-T1: movs r1, #1
515 ; CHECK-T1: lsls r1, r1, #12
516 ; CHECK-T2: mov.w r1, #4096
517 ; CHECK: ldr r0, [r0, r1]
518 define i32 @ldr_ri_t2_too_big(i8* %p) {
520 %add.ptr = getelementptr inbounds i8, i8* %p, i32 4096
521 %0 = bitcast i8* %add.ptr to i32*
522 %1 = load i32, i32* %0, align 4
526 ; CHECK-LABEL: strb_ri_t2_too_big
527 ; CHECK-T1: movs r2, #1
528 ; CHECK-T1: lsls r2, r2, #12
529 ; CHECK-T2: mov.w r2, #4096
530 ; CHECK: strb r1, [r0, r2]
531 define void @strb_ri_t2_too_big(i8* %p, i32 %x) {
533 %conv = trunc i32 %x to i8
534 %add.ptr = getelementptr inbounds i8, i8* %p, i32 4096
535 store i8 %conv, i8* %add.ptr, align 1
539 ; CHECK-LABEL: strh_ri_t2_too_big
540 ; CHECK-T1: movs r2, #1
541 ; CHECK-T1: lsls r2, r2, #12
542 ; CHECK-T2: mov.w r2, #4096
543 ; CHECK: strh r1, [r0, r2]
544 define void @strh_ri_t2_too_big(i8* %p, i32 %x) {
546 %conv = trunc i32 %x to i16
547 %add.ptr = getelementptr inbounds i8, i8* %p, i32 4096
548 %0 = bitcast i8* %add.ptr to i16*
549 store i16 %conv, i16* %0, align 2
553 ; CHECK-LABEL: str_ri_t2_too_big
554 ; CHECK-T1: movs r2, #1
555 ; CHECK-T1: lsls r2, r2, #12
556 ; CHECK-T2: mov.w r2, #4096
557 ; CHECK: str r1, [r0, r2]
558 define void @str_ri_t2_too_big(i8* %p, i32 %x) {
560 %add.ptr = getelementptr inbounds i8, i8* %p, i32 4096
561 %0 = bitcast i8* %add.ptr to i32*
562 store i32 %x, i32* %0, align 4
569 define i32 @ldrsb_ri_negative(i8* %p) {
570 ; CHECK-T1-LABEL: ldrsb_ri_negative:
571 ; CHECK-T1: @ %bb.0: @ %entry
572 ; CHECK-T1-NEXT: movs r1, #0
573 ; CHECK-T1-NEXT: mvns r1, r1
574 ; CHECK-T1-NEXT: ldrsb r0, [r0, r1]
575 ; CHECK-T1-NEXT: bx lr
577 ; CHECK-T2-LABEL: ldrsb_ri_negative:
578 ; CHECK-T2: @ %bb.0: @ %entry
579 ; CHECK-T2-NEXT: ldrsb r0, [r0, #-1]
580 ; CHECK-T2-NEXT: bx lr
582 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -1
583 %0 = load i8, i8* %add.ptr, align 1
584 %conv = sext i8 %0 to i32
588 define i32 @ldrsh_ri_negative(i8* %p) {
589 ; CHECK-T1-LABEL: ldrsh_ri_negative:
590 ; CHECK-T1: @ %bb.0: @ %entry
591 ; CHECK-T1-NEXT: movs r1, #0
592 ; CHECK-T1-NEXT: mvns r1, r1
593 ; CHECK-T1-NEXT: ldrsh r0, [r0, r1]
594 ; CHECK-T1-NEXT: bx lr
596 ; CHECK-T2-LABEL: ldrsh_ri_negative:
597 ; CHECK-T2: @ %bb.0: @ %entry
598 ; CHECK-T2-NEXT: ldrsh r0, [r0, #-1]
599 ; CHECK-T2-NEXT: bx lr
601 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -1
602 %0 = bitcast i8* %add.ptr to i16*
603 %1 = load i16, i16* %0, align 2
604 %conv = sext i16 %1 to i32
608 define i32 @ldrb_ri_negative(i8* %p) {
609 ; CHECK-T1-LABEL: ldrb_ri_negative:
610 ; CHECK-T1: @ %bb.0: @ %entry
611 ; CHECK-T1-NEXT: subs r0, r0, #1
612 ; CHECK-T1-NEXT: ldrb r0, [r0]
613 ; CHECK-T1-NEXT: bx lr
615 ; CHECK-T2-LABEL: ldrb_ri_negative:
616 ; CHECK-T2: @ %bb.0: @ %entry
617 ; CHECK-T2-NEXT: ldrb r0, [r0, #-1]
618 ; CHECK-T2-NEXT: bx lr
620 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -1
621 %0 = load i8, i8* %add.ptr, align 1
622 %conv = zext i8 %0 to i32
626 define i32 @ldrh_ri_negative(i8* %p) {
627 ; CHECK-T1-LABEL: ldrh_ri_negative:
628 ; CHECK-T1: @ %bb.0: @ %entry
629 ; CHECK-T1-NEXT: subs r0, r0, #1
630 ; CHECK-T1-NEXT: ldrh r0, [r0]
631 ; CHECK-T1-NEXT: bx lr
633 ; CHECK-T2-LABEL: ldrh_ri_negative:
634 ; CHECK-T2: @ %bb.0: @ %entry
635 ; CHECK-T2-NEXT: ldrh r0, [r0, #-1]
636 ; CHECK-T2-NEXT: bx lr
638 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -1
639 %0 = bitcast i8* %add.ptr to i16*
640 %1 = load i16, i16* %0, align 2
641 %conv = zext i16 %1 to i32
645 define i32 @ldr_ri_negative(i8* %p) {
646 ; CHECK-T1-LABEL: ldr_ri_negative:
647 ; CHECK-T1: @ %bb.0: @ %entry
648 ; CHECK-T1-NEXT: subs r0, r0, #1
649 ; CHECK-T1-NEXT: ldr r0, [r0]
650 ; CHECK-T1-NEXT: bx lr
652 ; CHECK-T2-LABEL: ldr_ri_negative:
653 ; CHECK-T2: @ %bb.0: @ %entry
654 ; CHECK-T2-NEXT: ldr r0, [r0, #-1]
655 ; CHECK-T2-NEXT: bx lr
657 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -1
658 %0 = bitcast i8* %add.ptr to i32*
659 %1 = load i32, i32* %0, align 4
663 define void @strb_ri_negative(i8* %p, i32 %x) {
664 ; CHECK-T1-LABEL: strb_ri_negative:
665 ; CHECK-T1: @ %bb.0: @ %entry
666 ; CHECK-T1-NEXT: subs r0, r0, #1
667 ; CHECK-T1-NEXT: strb r1, [r0]
668 ; CHECK-T1-NEXT: bx lr
670 ; CHECK-T2-LABEL: strb_ri_negative:
671 ; CHECK-T2: @ %bb.0: @ %entry
672 ; CHECK-T2-NEXT: strb r1, [r0, #-1]
673 ; CHECK-T2-NEXT: bx lr
675 %conv = trunc i32 %x to i8
676 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -1
677 store i8 %conv, i8* %add.ptr, align 1
681 define void @strh_ri_negative(i8* %p, i32 %x) {
682 ; CHECK-T1-LABEL: strh_ri_negative:
683 ; CHECK-T1: @ %bb.0: @ %entry
684 ; CHECK-T1-NEXT: subs r0, r0, #1
685 ; CHECK-T1-NEXT: strh r1, [r0]
686 ; CHECK-T1-NEXT: bx lr
688 ; CHECK-T2-LABEL: strh_ri_negative:
689 ; CHECK-T2: @ %bb.0: @ %entry
690 ; CHECK-T2-NEXT: strh r1, [r0, #-1]
691 ; CHECK-T2-NEXT: bx lr
693 %conv = trunc i32 %x to i16
694 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -1
695 %0 = bitcast i8* %add.ptr to i16*
696 store i16 %conv, i16* %0, align 2
700 define void @str_ri_negative(i8* %p, i32 %x) {
701 ; CHECK-T1-LABEL: str_ri_negative:
702 ; CHECK-T1: @ %bb.0: @ %entry
703 ; CHECK-T1-NEXT: subs r0, r0, #1
704 ; CHECK-T1-NEXT: str r1, [r0]
705 ; CHECK-T1-NEXT: bx lr
707 ; CHECK-T2-LABEL: str_ri_negative:
708 ; CHECK-T2: @ %bb.0: @ %entry
709 ; CHECK-T2-NEXT: str r1, [r0, #-1]
710 ; CHECK-T2-NEXT: bx lr
712 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -1
713 %0 = bitcast i8* %add.ptr to i32*
714 store i32 %x, i32* %0, align 4
719 ; Negative 255 offset
721 define i32 @ldrsb_ri_negative255(i8* %p) {
722 ; CHECK-T1-LABEL: ldrsb_ri_negative255:
723 ; CHECK-T1: @ %bb.0: @ %entry
724 ; CHECK-T1-NEXT: movs r1, #254
725 ; CHECK-T1-NEXT: mvns r1, r1
726 ; CHECK-T1-NEXT: ldrsb r0, [r0, r1]
727 ; CHECK-T1-NEXT: bx lr
729 ; CHECK-T2-LABEL: ldrsb_ri_negative255:
730 ; CHECK-T2: @ %bb.0: @ %entry
731 ; CHECK-T2-NEXT: ldrsb r0, [r0, #-255]
732 ; CHECK-T2-NEXT: bx lr
734 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -255
735 %0 = load i8, i8* %add.ptr, align 1
736 %conv = sext i8 %0 to i32
740 define i32 @ldrsh_ri_negative255(i8* %p) {
741 ; CHECK-T1-LABEL: ldrsh_ri_negative255:
742 ; CHECK-T1: @ %bb.0: @ %entry
743 ; CHECK-T1-NEXT: movs r1, #254
744 ; CHECK-T1-NEXT: mvns r1, r1
745 ; CHECK-T1-NEXT: ldrsh r0, [r0, r1]
746 ; CHECK-T1-NEXT: bx lr
748 ; CHECK-T2-LABEL: ldrsh_ri_negative255:
749 ; CHECK-T2: @ %bb.0: @ %entry
750 ; CHECK-T2-NEXT: ldrsh r0, [r0, #-255]
751 ; CHECK-T2-NEXT: bx lr
753 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -255
754 %0 = bitcast i8* %add.ptr to i16*
755 %1 = load i16, i16* %0, align 2
756 %conv = sext i16 %1 to i32
760 define i32 @ldrb_ri_negative255(i8* %p) {
761 ; CHECK-T1-LABEL: ldrb_ri_negative255:
762 ; CHECK-T1: @ %bb.0: @ %entry
763 ; CHECK-T1-NEXT: subs r0, #255
764 ; CHECK-T1-NEXT: ldrb r0, [r0]
765 ; CHECK-T1-NEXT: bx lr
767 ; CHECK-T2-LABEL: ldrb_ri_negative255:
768 ; CHECK-T2: @ %bb.0: @ %entry
769 ; CHECK-T2-NEXT: ldrb r0, [r0, #-255]
770 ; CHECK-T2-NEXT: bx lr
772 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -255
773 %0 = load i8, i8* %add.ptr, align 1
774 %conv = zext i8 %0 to i32
778 define i32 @ldrh_ri_negative255(i8* %p) {
779 ; CHECK-T1-LABEL: ldrh_ri_negative255:
780 ; CHECK-T1: @ %bb.0: @ %entry
781 ; CHECK-T1-NEXT: subs r0, #255
782 ; CHECK-T1-NEXT: ldrh r0, [r0]
783 ; CHECK-T1-NEXT: bx lr
785 ; CHECK-T2-LABEL: ldrh_ri_negative255:
786 ; CHECK-T2: @ %bb.0: @ %entry
787 ; CHECK-T2-NEXT: ldrh r0, [r0, #-255]
788 ; CHECK-T2-NEXT: bx lr
790 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -255
791 %0 = bitcast i8* %add.ptr to i16*
792 %1 = load i16, i16* %0, align 2
793 %conv = zext i16 %1 to i32
797 define i32 @ldr_ri_negative255(i8* %p) {
798 ; CHECK-T1-LABEL: ldr_ri_negative255:
799 ; CHECK-T1: @ %bb.0: @ %entry
800 ; CHECK-T1-NEXT: subs r0, #255
801 ; CHECK-T1-NEXT: ldr r0, [r0]
802 ; CHECK-T1-NEXT: bx lr
804 ; CHECK-T2-LABEL: ldr_ri_negative255:
805 ; CHECK-T2: @ %bb.0: @ %entry
806 ; CHECK-T2-NEXT: ldr r0, [r0, #-255]
807 ; CHECK-T2-NEXT: bx lr
809 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -255
810 %0 = bitcast i8* %add.ptr to i32*
811 %1 = load i32, i32* %0, align 4
815 define void @strb_ri_negative255(i8* %p, i32 %x) {
816 ; CHECK-T1-LABEL: strb_ri_negative255:
817 ; CHECK-T1: @ %bb.0: @ %entry
818 ; CHECK-T1-NEXT: subs r0, #255
819 ; CHECK-T1-NEXT: strb r1, [r0]
820 ; CHECK-T1-NEXT: bx lr
822 ; CHECK-T2-LABEL: strb_ri_negative255:
823 ; CHECK-T2: @ %bb.0: @ %entry
824 ; CHECK-T2-NEXT: strb r1, [r0, #-255]
825 ; CHECK-T2-NEXT: bx lr
827 %conv = trunc i32 %x to i8
828 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -255
829 store i8 %conv, i8* %add.ptr, align 1
833 define void @strh_ri_negative255(i8* %p, i32 %x) {
834 ; CHECK-T1-LABEL: strh_ri_negative255:
835 ; CHECK-T1: @ %bb.0: @ %entry
836 ; CHECK-T1-NEXT: subs r0, #255
837 ; CHECK-T1-NEXT: strh r1, [r0]
838 ; CHECK-T1-NEXT: bx lr
840 ; CHECK-T2-LABEL: strh_ri_negative255:
841 ; CHECK-T2: @ %bb.0: @ %entry
842 ; CHECK-T2-NEXT: strh r1, [r0, #-255]
843 ; CHECK-T2-NEXT: bx lr
845 %conv = trunc i32 %x to i16
846 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -255
847 %0 = bitcast i8* %add.ptr to i16*
848 store i16 %conv, i16* %0, align 2
852 define void @str_ri_negative255(i8* %p, i32 %x) {
853 ; CHECK-T1-LABEL: str_ri_negative255:
854 ; CHECK-T1: @ %bb.0: @ %entry
855 ; CHECK-T1-NEXT: subs r0, #255
856 ; CHECK-T1-NEXT: str r1, [r0]
857 ; CHECK-T1-NEXT: bx lr
859 ; CHECK-T2-LABEL: str_ri_negative255:
860 ; CHECK-T2: @ %bb.0: @ %entry
861 ; CHECK-T2-NEXT: str r1, [r0, #-255]
862 ; CHECK-T2-NEXT: bx lr
864 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -255
865 %0 = bitcast i8* %add.ptr to i32*
866 store i32 %x, i32* %0, align 4
871 ; Negative 256 offset
873 define i32 @ldrsb_ri_negative256(i8* %p) {
874 ; CHECK-T1-LABEL: ldrsb_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: ldrsb r0, [r0, r1]
879 ; CHECK-T1-NEXT: bx lr
881 ; CHECK-T2-LABEL: ldrsb_ri_negative256:
882 ; CHECK-T2: @ %bb.0: @ %entry
883 ; CHECK-T2-NEXT: mvn r1, #255
884 ; CHECK-T2-NEXT: ldrsb r0, [r0, r1]
885 ; CHECK-T2-NEXT: bx lr
887 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -256
888 %0 = load i8, i8* %add.ptr, align 1
889 %conv = sext i8 %0 to i32
893 define i32 @ldrsh_ri_negative256(i8* %p) {
894 ; CHECK-T1-LABEL: ldrsh_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: ldrsh r0, [r0, r1]
899 ; CHECK-T1-NEXT: bx lr
901 ; CHECK-T2-LABEL: ldrsh_ri_negative256:
902 ; CHECK-T2: @ %bb.0: @ %entry
903 ; CHECK-T2-NEXT: mvn r1, #255
904 ; CHECK-T2-NEXT: ldrsh r0, [r0, r1]
905 ; CHECK-T2-NEXT: bx lr
907 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -256
908 %0 = bitcast i8* %add.ptr to i16*
909 %1 = load i16, i16* %0, align 2
910 %conv = sext i16 %1 to i32
914 define i32 @ldrb_ri_negative256(i8* %p) {
915 ; CHECK-T1-LABEL: ldrb_ri_negative256:
916 ; CHECK-T1: @ %bb.0: @ %entry
917 ; CHECK-T1-NEXT: movs r1, #255
918 ; CHECK-T1-NEXT: mvns r1, r1
919 ; CHECK-T1-NEXT: ldrb r0, [r0, r1]
920 ; CHECK-T1-NEXT: bx lr
922 ; CHECK-T2-LABEL: ldrb_ri_negative256:
923 ; CHECK-T2: @ %bb.0: @ %entry
924 ; CHECK-T2-NEXT: mvn r1, #255
925 ; CHECK-T2-NEXT: ldrb r0, [r0, r1]
926 ; CHECK-T2-NEXT: bx lr
928 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -256
929 %0 = load i8, i8* %add.ptr, align 1
930 %conv = zext i8 %0 to i32
934 define i32 @ldrh_ri_negative256(i8* %p) {
935 ; CHECK-T1-LABEL: ldrh_ri_negative256:
936 ; CHECK-T1: @ %bb.0: @ %entry
937 ; CHECK-T1-NEXT: movs r1, #255
938 ; CHECK-T1-NEXT: mvns r1, r1
939 ; CHECK-T1-NEXT: ldrh r0, [r0, r1]
940 ; CHECK-T1-NEXT: bx lr
942 ; CHECK-T2-LABEL: ldrh_ri_negative256:
943 ; CHECK-T2: @ %bb.0: @ %entry
944 ; CHECK-T2-NEXT: mvn r1, #255
945 ; CHECK-T2-NEXT: ldrh r0, [r0, r1]
946 ; CHECK-T2-NEXT: bx lr
948 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -256
949 %0 = bitcast i8* %add.ptr to i16*
950 %1 = load i16, i16* %0, align 2
951 %conv = zext i16 %1 to i32
955 define i32 @ldr_ri_negative256(i8* %p) {
956 ; CHECK-T1-LABEL: ldr_ri_negative256:
957 ; CHECK-T1: @ %bb.0: @ %entry
958 ; CHECK-T1-NEXT: movs r1, #255
959 ; CHECK-T1-NEXT: mvns r1, r1
960 ; CHECK-T1-NEXT: ldr r0, [r0, r1]
961 ; CHECK-T1-NEXT: bx lr
963 ; CHECK-T2-LABEL: ldr_ri_negative256:
964 ; CHECK-T2: @ %bb.0: @ %entry
965 ; CHECK-T2-NEXT: mvn r1, #255
966 ; CHECK-T2-NEXT: ldr r0, [r0, r1]
967 ; CHECK-T2-NEXT: bx lr
969 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -256
970 %0 = bitcast i8* %add.ptr to i32*
971 %1 = load i32, i32* %0, align 4
975 define void @strb_ri_negative256(i8* %p, i32 %x) {
976 ; CHECK-T1-LABEL: strb_ri_negative256:
977 ; CHECK-T1: @ %bb.0: @ %entry
978 ; CHECK-T1-NEXT: movs r2, #255
979 ; CHECK-T1-NEXT: mvns r2, r2
980 ; CHECK-T1-NEXT: strb r1, [r0, r2]
981 ; CHECK-T1-NEXT: bx lr
983 ; CHECK-T2-LABEL: strb_ri_negative256:
984 ; CHECK-T2: @ %bb.0: @ %entry
985 ; CHECK-T2-NEXT: mvn r2, #255
986 ; CHECK-T2-NEXT: strb r1, [r0, r2]
987 ; CHECK-T2-NEXT: bx lr
989 %conv = trunc i32 %x to i8
990 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -256
991 store i8 %conv, i8* %add.ptr, align 1
995 define void @strh_ri_negative256(i8* %p, i32 %x) {
996 ; CHECK-T1-LABEL: strh_ri_negative256:
997 ; CHECK-T1: @ %bb.0: @ %entry
998 ; CHECK-T1-NEXT: movs r2, #255
999 ; CHECK-T1-NEXT: mvns r2, r2
1000 ; CHECK-T1-NEXT: strh r1, [r0, r2]
1001 ; CHECK-T1-NEXT: bx lr
1003 ; CHECK-T2-LABEL: strh_ri_negative256:
1004 ; CHECK-T2: @ %bb.0: @ %entry
1005 ; CHECK-T2-NEXT: mvn r2, #255
1006 ; CHECK-T2-NEXT: strh r1, [r0, r2]
1007 ; CHECK-T2-NEXT: bx lr
1009 %conv = trunc i32 %x to i16
1010 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -256
1011 %0 = bitcast i8* %add.ptr to i16*
1012 store i16 %conv, i16* %0, align 2
1016 define void @str_ri_negative256(i8* %p, i32 %x) {
1017 ; CHECK-T1-LABEL: str_ri_negative256:
1018 ; CHECK-T1: @ %bb.0: @ %entry
1019 ; CHECK-T1-NEXT: movs r2, #255
1020 ; CHECK-T1-NEXT: mvns r2, r2
1021 ; CHECK-T1-NEXT: str r1, [r0, r2]
1022 ; CHECK-T1-NEXT: bx lr
1024 ; CHECK-T2-LABEL: str_ri_negative256:
1025 ; CHECK-T2: @ %bb.0: @ %entry
1026 ; CHECK-T2-NEXT: mvn r2, #255
1027 ; CHECK-T2-NEXT: str r1, [r0, r2]
1028 ; CHECK-T2-NEXT: bx lr
1030 %add.ptr = getelementptr inbounds i8, i8* %p, i32 -256
1031 %0 = bitcast i8* %add.ptr to i32*
1032 store i32 %x, i32* %0, align 4