blob: d0b535b2df56e8fd02b271f8c515343714c93303 [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
; RUN: llc -O1 -mtriple=aarch64 -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,O1
; RUN: llc -O0 -mtriple=aarch64 -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,O0
; Adapt the cases in RISCV/local-stack-slot-allocation.ll for AArch64.
; This test case test the LocalStackSlotAllocation pass that use a base register
; for the frame index that its offset is out-of-range (for AArch64 the immediate
; is 12 bits for the load store instruction (excludes vector load / store))
define void @use_frame_base_reg() {
; O1-LABEL: use_frame_base_reg:
; O1: // %bb.0:
; O1-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill
; O1-NEXT: sub sp, sp, #24, lsl #12 // =98304
; O1-NEXT: sub sp, sp, #1712
; O1-NEXT: .cfi_def_cfa_offset 100032
; O1-NEXT: .cfi_offset w29, -16
; O1-NEXT: add x8, sp, #24, lsl #12 // =98304
; O1-NEXT: add x8, x8, #1704
; O1-NEXT: ldrb wzr, [x8, #4]
; O1-NEXT: ldrb wzr, [x8]
; O1-NEXT: add sp, sp, #24, lsl #12 // =98304
; O1-NEXT: add sp, sp, #1712
; O1-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload
; O1-NEXT: ret
;
; O0-LABEL: use_frame_base_reg:
; O0: // %bb.0:
; O0-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill
; O0-NEXT: sub sp, sp, #24, lsl #12 // =98304
; O0-NEXT: sub sp, sp, #1712
; O0-NEXT: .cfi_def_cfa_offset 100032
; O0-NEXT: .cfi_offset w29, -16
; O0-NEXT: add x8, sp, #24, lsl #12 // =98304
; O0-NEXT: ldrb w8, [x8, #1708]
; O0-NEXT: add x8, sp, #24, lsl #12 // =98304
; O0-NEXT: ldrb w8, [x8, #1704]
; O0-NEXT: add sp, sp, #24, lsl #12 // =98304
; O0-NEXT: add sp, sp, #1712
; O0-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload
; O0-NEXT: ret
%va = alloca i8, align 4
%va1 = alloca i8, align 4
%large = alloca [ 100000 x i8 ]
%argp.cur = load volatile i8, ptr %va, align 4
%argp.next = load volatile i8, ptr %va1, align 4
ret void
}
; Test containing a load with its own local offset. Make sure isFrameOffsetLegal
; considers it and creates a virtual base register.
define void @load_with_offset() {
; O1-LABEL: load_with_offset:
; O1: // %bb.0:
; O1-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill
; O1-NEXT: sub sp, sp, #1, lsl #12 // =4096
; O1-NEXT: sub sp, sp, #912
; O1-NEXT: .cfi_def_cfa_offset 5024
; O1-NEXT: .cfi_offset w29, -16
; O1-NEXT: add x8, sp, #8
; O1-NEXT: ldrb w9, [x8, #4088]
; O1-NEXT: strb w9, [x8, #4088]
; O1-NEXT: add sp, sp, #1, lsl #12 // =4096
; O1-NEXT: add sp, sp, #912
; O1-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload
; O1-NEXT: ret
;
; O0-LABEL: load_with_offset:
; O0: // %bb.0:
; O0-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill
; O0-NEXT: sub sp, sp, #1, lsl #12 // =4096
; O0-NEXT: sub sp, sp, #912
; O0-NEXT: .cfi_def_cfa_offset 5024
; O0-NEXT: .cfi_offset w29, -16
; O0-NEXT: add x8, sp, #1, lsl #12 // =4096
; O0-NEXT: ldrb w8, [x8]
; O0-NEXT: add x9, sp, #1, lsl #12 // =4096
; O0-NEXT: strb w8, [x9]
; O0-NEXT: add sp, sp, #1, lsl #12 // =4096
; O0-NEXT: add sp, sp, #912
; O0-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload
; O0-NEXT: ret
%va = alloca [5000 x i8], align 4
%va_gep = getelementptr [5000 x i8], ptr %va, i64 0, i64 4088
%load = load volatile i8, ptr %va_gep, align 4
store volatile i8 %load, ptr %va_gep, align 4
ret void
}
; Test containing a load with its own local offset that is smaller than the
; previous test case. Make sure we don't create a virtual base register.
define void @load_with_offset2() {
; CHECK-LABEL: load_with_offset2:
; CHECK: // %bb.0:
; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill
; CHECK-NEXT: sub sp, sp, #2512
; CHECK-NEXT: .cfi_def_cfa_offset 2528
; CHECK-NEXT: .cfi_offset w29, -16
; CHECK-NEXT: ldrb w8, [sp, #1412]
; CHECK-NEXT: strb w8, [sp, #1412]
; CHECK-NEXT: add sp, sp, #2512
; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload
; CHECK-NEXT: ret
%va = alloca [2500 x i8], align 4
%va_gep = getelementptr [2000 x i8], ptr %va, i64 0, i64 1400
%load = load volatile i8, ptr %va_gep, align 4
store volatile i8 %load, ptr %va_gep, align 4
ret void
}
define void @frame_pointer() "frame-pointer"="all" {
; CHECK-LABEL: frame_pointer:
; CHECK: // %bb.0:
; CHECK-NEXT: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
; CHECK-NEXT: mov x29, sp
; CHECK-NEXT: sub sp, sp, #2512
; CHECK-NEXT: .cfi_def_cfa w29, 16
; CHECK-NEXT: .cfi_offset w30, -8
; CHECK-NEXT: .cfi_offset w29, -16
; CHECK-NEXT: ldrb w8, [sp, #564]
; CHECK-NEXT: strb w8, [sp, #564]
; CHECK-NEXT: add sp, sp, #2512
; CHECK-NEXT: ldp x29, x30, [sp], #16 // 16-byte Folded Reload
; CHECK-NEXT: ret
%va = alloca [2500 x i8], align 4
%va_gep = getelementptr [2000 x i8], ptr %va, i64 0, i64 552
%load = load volatile i8, ptr %va_gep, align 4
store volatile i8 %load, ptr %va_gep, align 4
ret void
}