| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py |
| ; RUN: llc -aarch64-enable-subreg-liveness-tracking -mtriple=arm64-eabi < %s | FileCheck %s |
| ; rdar://10232252 |
| |
| @object = external hidden global i64, section "__DATA, __objc_ivar", align 8 |
| |
| ; base + offset (imm9) |
| define void @t1(ptr %object) { |
| ; CHECK-LABEL: t1: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: ldr xzr, [x0, #8] |
| ; CHECK-NEXT: ret |
| %incdec.ptr = getelementptr inbounds i64, ptr %object, i64 1 |
| %tmp = load volatile i64, ptr %incdec.ptr, align 8 |
| ret void |
| } |
| |
| ; base + offset (> imm9) |
| define void @t2(ptr %object) { |
| ; CHECK-LABEL: t2: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: sub x8, x0, #264 |
| ; CHECK-NEXT: ldr xzr, [x8] |
| ; CHECK-NEXT: ret |
| %incdec.ptr = getelementptr inbounds i64, ptr %object, i64 -33 |
| %tmp = load volatile i64, ptr %incdec.ptr, align 8 |
| ret void |
| } |
| |
| ; base + unsigned offset (> imm9 and <= imm12 * size of type in bytes) |
| define void @t3(ptr %object) { |
| ; CHECK-LABEL: t3: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: ldr xzr, [x0, #32760] |
| ; CHECK-NEXT: ret |
| %incdec.ptr = getelementptr inbounds i64, ptr %object, i64 4095 |
| %tmp = load volatile i64, ptr %incdec.ptr, align 8 |
| ret void |
| } |
| |
| ; base + unsigned offset (> imm12 * size of type in bytes) |
| define void @t4(ptr %object) { |
| ; CHECK-LABEL: t4: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: mov w8, #32768 // =0x8000 |
| ; CHECK-NEXT: ldr xzr, [x0, x8] |
| ; CHECK-NEXT: ret |
| %incdec.ptr = getelementptr inbounds i64, ptr %object, i64 4096 |
| %tmp = load volatile i64, ptr %incdec.ptr, align 8 |
| ret void |
| } |
| |
| ; base + reg |
| define void @t5(i64 %a) { |
| ; CHECK-LABEL: t5: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: adrp x8, object |
| ; CHECK-NEXT: add x8, x8, :lo12:object |
| ; CHECK-NEXT: ldr xzr, [x8, x0, lsl #3] |
| ; CHECK-NEXT: ret |
| %incdec.ptr = getelementptr inbounds i64, ptr @object, i64 %a |
| %tmp = load volatile i64, ptr %incdec.ptr, align 8 |
| ret void |
| } |
| |
| ; base + reg + imm |
| define void @t6(i64 %a, ptr %object) { |
| ; CHECK-LABEL: t6: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x1, x0, lsl #3 |
| ; CHECK-NEXT: mov w9, #32768 // =0x8000 |
| ; CHECK-NEXT: ldr xzr, [x8, x9] |
| ; CHECK-NEXT: ret |
| %tmp1 = getelementptr inbounds i64, ptr %object, i64 %a |
| %incdec.ptr = getelementptr inbounds i64, ptr %tmp1, i64 4096 |
| %tmp = load volatile i64, ptr %incdec.ptr, align 8 |
| ret void |
| } |
| |
| ; Test base + wide immediate |
| define void @t7(i64 %a) { |
| ; CHECK-LABEL: t7: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: mov w8, #65535 // =0xffff |
| ; CHECK-NEXT: ldr xzr, [x0, x8] |
| ; CHECK-NEXT: ret |
| %1 = add i64 %a, 65535 ;0xffff |
| %2 = inttoptr i64 %1 to ptr |
| %3 = load volatile i64, ptr %2, align 8 |
| ret void |
| } |
| |
| define void @t8(i64 %a) { |
| ; CHECK-LABEL: t8: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: mov x8, #-4662 // =0xffffffffffffedca |
| ; CHECK-NEXT: ldr xzr, [x0, x8] |
| ; CHECK-NEXT: ret |
| %1 = sub i64 %a, 4662 ;-4662 is 0xffffffffffffedca |
| %2 = inttoptr i64 %1 to ptr |
| %3 = load volatile i64, ptr %2, align 8 |
| ret void |
| } |
| |
| define void @t9(i64 %a) { |
| ; CHECK-LABEL: t9: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: mov x8, #-305463297 // =0xffffffffedcaffff |
| ; CHECK-NEXT: ldr xzr, [x0, x8] |
| ; CHECK-NEXT: ret |
| %1 = add i64 -305463297, %a ;-305463297 is 0xffffffffedcaffff |
| %2 = inttoptr i64 %1 to ptr |
| %3 = load volatile i64, ptr %2, align 8 |
| ret void |
| } |
| |
| define void @t10(i64 %a) { |
| ; CHECK-LABEL: t10: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: mov x8, #81909218222800896 // =0x123000000000000 |
| ; CHECK-NEXT: ldr xzr, [x0, x8] |
| ; CHECK-NEXT: ret |
| %1 = add i64 %a, 81909218222800896 ;0x123000000000000 |
| %2 = inttoptr i64 %1 to ptr |
| %3 = load volatile i64, ptr %2, align 8 |
| ret void |
| } |
| |
| define void @t11(i64 %a) { |
| ; CHECK-LABEL: t11: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: mov w8, #17767 // =0x4567 |
| ; CHECK-NEXT: movk w8, #291, lsl #16 |
| ; CHECK-NEXT: ldr xzr, [x0, x8] |
| ; CHECK-NEXT: ret |
| %1 = add i64 %a, 19088743 ;0x1234567 |
| %2 = inttoptr i64 %1 to ptr |
| %3 = load volatile i64, ptr %2, align 8 |
| ret void |
| } |
| |
| ; Test some boundaries that should not use movz/movn/orr |
| define void @t12(i64 %a) { |
| ; CHECK-LABEL: t12: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #4095 |
| ; CHECK-NEXT: ldr xzr, [x8] |
| ; CHECK-NEXT: ret |
| %1 = add i64 %a, 4095 ;0xfff |
| %2 = inttoptr i64 %1 to ptr |
| %3 = load volatile i64, ptr %2, align 8 |
| ret void |
| } |
| |
| define void @t13(i64 %a) { |
| ; CHECK-LABEL: t13: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: sub x8, x0, #4095 |
| ; CHECK-NEXT: ldr xzr, [x8] |
| ; CHECK-NEXT: ret |
| %1 = add i64 %a, -4095 ;-0xfff |
| %2 = inttoptr i64 %1 to ptr |
| %3 = load volatile i64, ptr %2, align 8 |
| ret void |
| } |
| |
| define void @t14(i64 %a) { |
| ; CHECK-LABEL: t14: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #291, lsl #12 // =1191936 |
| ; CHECK-NEXT: ldr xzr, [x8] |
| ; CHECK-NEXT: ret |
| %1 = add i64 %a, 1191936 ;0x123000 |
| %2 = inttoptr i64 %1 to ptr |
| %3 = load volatile i64, ptr %2, align 8 |
| ret void |
| } |
| |
| define void @t15(i64 %a) { |
| ; CHECK-LABEL: t15: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: sub x8, x0, #291, lsl #12 // =1191936 |
| ; CHECK-NEXT: ldr xzr, [x8] |
| ; CHECK-NEXT: ret |
| %1 = add i64 %a, -1191936 ;0xFFFFFFFFFFEDD000 |
| %2 = inttoptr i64 %1 to ptr |
| %3 = load volatile i64, ptr %2, align 8 |
| ret void |
| } |
| |
| define void @t16(i64 %a) { |
| ; CHECK-LABEL: t16: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: ldr xzr, [x0, #28672] |
| ; CHECK-NEXT: ret |
| %1 = add i64 %a, 28672 ;0x7000 |
| %2 = inttoptr i64 %1 to ptr |
| %3 = load volatile i64, ptr %2, align 8 |
| ret void |
| } |
| |
| define void @t17(i64 %a) { |
| ; CHECK-LABEL: t17: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: ldur xzr, [x0, #-256] |
| ; CHECK-NEXT: ret |
| %1 = add i64 %a, -256 ;-0x100 |
| %2 = inttoptr i64 %1 to ptr |
| %3 = load volatile i64, ptr %2, align 8 |
| ret void |
| } |
| |
| ; LDRBBroX |
| define i8 @LdOffset_i8(ptr %a) { |
| ; CHECK-LABEL: LdOffset_i8: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #253, lsl #12 // =1036288 |
| ; CHECK-NEXT: ldrb w0, [x8, #3704] |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds i8, ptr %a, i64 1039992 |
| %val = load i8, ptr %arrayidx, align 1 |
| ret i8 %val |
| } |
| |
| ; LDRBBroX |
| define i32 @LdOffset_i8_zext32(ptr %a) { |
| ; CHECK-LABEL: LdOffset_i8_zext32: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #253, lsl #12 // =1036288 |
| ; CHECK-NEXT: ldrb w0, [x8, #3704] |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds i8, ptr %a, i64 1039992 |
| %val = load i8, ptr %arrayidx, align 1 |
| %conv = zext i8 %val to i32 |
| ret i32 %conv |
| } |
| |
| ; LDRSBWroX |
| define i32 @LdOffset_i8_sext32(ptr %a) { |
| ; CHECK-LABEL: LdOffset_i8_sext32: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #253, lsl #12 // =1036288 |
| ; CHECK-NEXT: ldrsb w0, [x8, #3704] |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds i8, ptr %a, i64 1039992 |
| %val = load i8, ptr %arrayidx, align 1 |
| %conv = sext i8 %val to i32 |
| ret i32 %conv |
| } |
| |
| ; LDRBBroX |
| define i64 @LdOffset_i8_zext64(ptr %a) { |
| ; CHECK-LABEL: LdOffset_i8_zext64: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #253, lsl #12 // =1036288 |
| ; CHECK-NEXT: ldrb w0, [x8, #3704] |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds i8, ptr %a, i64 1039992 |
| %val = load i8, ptr %arrayidx, align 1 |
| %conv = zext i8 %val to i64 |
| ret i64 %conv |
| } |
| |
| ; LDRSBXroX |
| define i64 @LdOffset_i8_sext64(ptr %a) { |
| ; CHECK-LABEL: LdOffset_i8_sext64: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #253, lsl #12 // =1036288 |
| ; CHECK-NEXT: ldrsb x0, [x8, #3704] |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds i8, ptr %a, i64 1039992 |
| %val = load i8, ptr %arrayidx, align 1 |
| %conv = sext i8 %val to i64 |
| ret i64 %conv |
| } |
| |
| ; LDRHHroX |
| define i16 @LdOffset_i16(ptr %a) { |
| ; CHECK-LABEL: LdOffset_i16: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #506, lsl #12 // =2072576 |
| ; CHECK-NEXT: ldrh w0, [x8, #7408] |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds i16, ptr %a, i64 1039992 |
| %val = load i16, ptr %arrayidx, align 2 |
| ret i16 %val |
| } |
| |
| ; LDRHHroX |
| define i32 @LdOffset_i16_zext32(ptr %a) { |
| ; CHECK-LABEL: LdOffset_i16_zext32: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #506, lsl #12 // =2072576 |
| ; CHECK-NEXT: ldrh w0, [x8, #7408] |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds i16, ptr %a, i64 1039992 |
| %val = load i16, ptr %arrayidx, align 2 |
| %conv = zext i16 %val to i32 |
| ret i32 %conv |
| } |
| |
| ; LDRSHWroX |
| define i32 @LdOffset_i16_sext32(ptr %a) { |
| ; CHECK-LABEL: LdOffset_i16_sext32: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #506, lsl #12 // =2072576 |
| ; CHECK-NEXT: ldrsh w0, [x8, #7408] |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds i16, ptr %a, i64 1039992 |
| %val = load i16, ptr %arrayidx, align 2 |
| %conv = sext i16 %val to i32 |
| ret i32 %conv |
| } |
| |
| ; LDRHHroX |
| define i64 @LdOffset_i16_zext64(ptr %a) { |
| ; CHECK-LABEL: LdOffset_i16_zext64: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #506, lsl #12 // =2072576 |
| ; CHECK-NEXT: ldrh w0, [x8, #7408] |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds i16, ptr %a, i64 1039992 |
| %val = load i16, ptr %arrayidx, align 2 |
| %conv = zext i16 %val to i64 |
| ret i64 %conv |
| } |
| |
| ; LDRSHXroX |
| define i64 @LdOffset_i16_sext64(ptr %a) { |
| ; CHECK-LABEL: LdOffset_i16_sext64: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #506, lsl #12 // =2072576 |
| ; CHECK-NEXT: ldrsh x0, [x8, #7408] |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds i16, ptr %a, i64 1039992 |
| %val = load i16, ptr %arrayidx, align 2 |
| %conv = sext i16 %val to i64 |
| ret i64 %conv |
| } |
| |
| ; LDRWroX |
| define i32 @LdOffset_i32(ptr %a) { |
| ; CHECK-LABEL: LdOffset_i32: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #1012, lsl #12 // =4145152 |
| ; CHECK-NEXT: ldr w0, [x8, #14816] |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds i32, ptr %a, i64 1039992 |
| %val = load i32, ptr %arrayidx, align 4 |
| ret i32 %val |
| } |
| |
| ; LDRWroX |
| define i64 @LdOffset_i32_zext64(ptr %a) { |
| ; CHECK-LABEL: LdOffset_i32_zext64: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #1012, lsl #12 // =4145152 |
| ; CHECK-NEXT: ldr w0, [x8, #14816] |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds i32, ptr %a, i64 1039992 |
| %val = load i32, ptr %arrayidx, align 2 |
| %conv = zext i32 %val to i64 |
| ret i64 %conv |
| } |
| |
| ; LDRSWroX |
| define i64 @LdOffset_i32_sext64(ptr %a) { |
| ; CHECK-LABEL: LdOffset_i32_sext64: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #1012, lsl #12 // =4145152 |
| ; CHECK-NEXT: ldrsw x0, [x8, #14816] |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds i32, ptr %a, i64 1039992 |
| %val = load i32, ptr %arrayidx, align 2 |
| %conv = sext i32 %val to i64 |
| ret i64 %conv |
| } |
| |
| ; LDRXroX |
| define i64 @LdOffset_i64(ptr %a) { |
| ; CHECK-LABEL: LdOffset_i64: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #2024, lsl #12 // =8290304 |
| ; CHECK-NEXT: ldr x0, [x8, #29632] |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds i64, ptr %a, i64 1039992 |
| %val = load i64, ptr %arrayidx, align 4 |
| ret i64 %val |
| } |
| |
| ; LDRDroX |
| define <2 x i32> @LdOffset_v2i32(ptr %a) { |
| ; CHECK-LABEL: LdOffset_v2i32: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #2024, lsl #12 // =8290304 |
| ; CHECK-NEXT: ldr d0, [x8, #29632] |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds <2 x i32>, ptr %a, i64 1039992 |
| %val = load <2 x i32>, ptr %arrayidx, align 4 |
| ret <2 x i32> %val |
| } |
| |
| ; LDRQroX |
| define <2 x i64> @LdOffset_v2i64(ptr %a) { |
| ; CHECK-LABEL: LdOffset_v2i64: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #4048, lsl #12 // =16580608 |
| ; CHECK-NEXT: ldr q0, [x8, #59264] |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds <2 x i64>, ptr %a, i64 1039992 |
| %val = load <2 x i64>, ptr %arrayidx, align 4 |
| ret <2 x i64> %val |
| } |
| |
| ; LDRSBWroX |
| define double @LdOffset_i8_f64(ptr %a) { |
| ; CHECK-LABEL: LdOffset_i8_f64: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #253, lsl #12 // =1036288 |
| ; CHECK-NEXT: ldrsb w8, [x8, #3704] |
| ; CHECK-NEXT: scvtf d0, w8 |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds i8, ptr %a, i64 1039992 |
| %val = load i8, ptr %arrayidx, align 1 |
| %conv = sitofp i8 %val to double |
| ret double %conv |
| } |
| |
| ; LDRSHWroX |
| define double @LdOffset_i16_f64(ptr %a) { |
| ; CHECK-LABEL: LdOffset_i16_f64: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #506, lsl #12 // =2072576 |
| ; CHECK-NEXT: ldrsh w8, [x8, #7408] |
| ; CHECK-NEXT: scvtf d0, w8 |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds i16, ptr %a, i64 1039992 |
| %val = load i16, ptr %arrayidx, align 2 |
| %conv = sitofp i16 %val to double |
| ret double %conv |
| } |
| |
| ; LDRSroX |
| define double @LdOffset_i32_f64(ptr %a) { |
| ; CHECK-LABEL: LdOffset_i32_f64: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #1012, lsl #12 // =4145152 |
| ; CHECK-NEXT: ldr s0, [x8, #14816] |
| ; CHECK-NEXT: ucvtf d0, d0 |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds i32, ptr %a, i64 1039992 |
| %val = load i32, ptr %arrayidx, align 4 |
| %conv = uitofp i32 %val to double |
| ret double %conv |
| } |
| |
| ; LDRDroX |
| define double @LdOffset_i64_f64(ptr %a) { |
| ; CHECK-LABEL: LdOffset_i64_f64: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #2024, lsl #12 // =8290304 |
| ; CHECK-NEXT: ldr d0, [x8, #29632] |
| ; CHECK-NEXT: scvtf d0, d0 |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds i64, ptr %a, i64 1039992 |
| %val = load i64, ptr %arrayidx, align 8 |
| %conv = sitofp i64 %val to double |
| ret double %conv |
| } |
| |
| define i64 @LdOffset_i64_multi_offset(ptr %a) { |
| ; CHECK-LABEL: LdOffset_i64_multi_offset: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #2031, lsl #12 // =8318976 |
| ; CHECK-NEXT: ldr x9, [x8, #960] |
| ; CHECK-NEXT: ldr x8, [x8, #3016] |
| ; CHECK-NEXT: add x0, x8, x9 |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds i64, ptr %a, i64 1039992 |
| %val0 = load i64, ptr %arrayidx, align 8 |
| %arrayidx1 = getelementptr inbounds i64, ptr %a, i64 1040249 |
| %val1 = load i64, ptr %arrayidx1, align 8 |
| %add = add nsw i64 %val1, %val0 |
| ret i64 %add |
| } |
| |
| define i64 @LdOffset_i64_multi_offset_with_commmon_base(ptr %a) { |
| ; CHECK-LABEL: LdOffset_i64_multi_offset_with_commmon_base: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: add x8, x0, #507, lsl #12 // =2076672 |
| ; CHECK-NEXT: ldr x9, [x8, #26464] |
| ; CHECK-NEXT: ldr x8, [x8, #26496] |
| ; CHECK-NEXT: add x0, x8, x9 |
| ; CHECK-NEXT: ret |
| %b = getelementptr inbounds i16, ptr %a, i64 1038336 |
| %arrayidx = getelementptr inbounds i64, ptr %b, i64 3308 |
| %val0 = load i64, ptr %arrayidx, align 8 |
| %arrayidx1 = getelementptr inbounds i64, ptr %b, i64 3312 |
| %val1 = load i64, ptr %arrayidx1, align 8 |
| %add = add nsw i64 %val1, %val0 |
| ret i64 %add |
| } |
| |
| ; Negative test: the offset is odd |
| define i32 @LdOffset_i16_odd_offset(ptr nocapture noundef readonly %a) { |
| ; CHECK-LABEL: LdOffset_i16_odd_offset: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: mov w8, #56953 // =0xde79 |
| ; CHECK-NEXT: movk w8, #15, lsl #16 |
| ; CHECK-NEXT: ldrsh w0, [x0, x8] |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds i8, ptr %a, i64 1039993 |
| %val = load i16, ptr %arrayidx, align 2 |
| %conv = sext i16 %val to i32 |
| ret i32 %conv |
| } |
| |
| ; Already encoded with a single mov MOVNWi |
| define i8 @LdOffset_i8_movnwi(ptr %a) { |
| ; CHECK-LABEL: LdOffset_i8_movnwi: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: mov w8, #16777215 // =0xffffff |
| ; CHECK-NEXT: ldrb w0, [x0, x8] |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds i8, ptr %a, i64 16777215 |
| %val = load i8, ptr %arrayidx, align 1 |
| ret i8 %val |
| } |
| |
| ; Negative test: the offset is too large to encoded with a add |
| define i8 @LdOffset_i8_too_large(ptr %a) { |
| ; CHECK-LABEL: LdOffset_i8_too_large: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: mov w8, #1 // =0x1 |
| ; CHECK-NEXT: movk w8, #256, lsl #16 |
| ; CHECK-NEXT: ldrb w0, [x0, x8] |
| ; CHECK-NEXT: ret |
| %arrayidx = getelementptr inbounds i8, ptr %a, i64 16777217 |
| %val = load i8, ptr %arrayidx, align 1 |
| ret i8 %val |
| } |