blob: c13daf6b8c91c4b15eae0ba2d38d9b0112a6c124 [file] [log] [blame]
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple=thumbv6m-none-eabi -frame-pointer=none -verify-machineinstrs | FileCheck %s --check-prefix=FP-NONE
; RUN: llc < %s -mtriple=thumbv6m-none-eabi -frame-pointer=all -verify-machineinstrs | FileCheck %s --check-prefix=FP-ALL
; RUN: llc < %s -mtriple=thumbv6m-none-eabi -frame-pointer=all -mattr=+aapcs-frame-chain -verify-machineinstrs | FileCheck %s --check-prefix=FP-AAPCS
define void @ra_call() {
; FP-NONE-LABEL: ra_call:
; FP-NONE: @ %bb.0: @ %entry
; FP-NONE-NEXT: .save {r7, lr}
; FP-NONE-NEXT: push {r7, lr}
; FP-NONE-NEXT: mov r0, lr
; FP-NONE-NEXT: bl sink_ptr
; FP-NONE-NEXT: pop {r7, pc}
;
; FP-ALL-LABEL: ra_call:
; FP-ALL: @ %bb.0: @ %entry
; FP-ALL-NEXT: .save {r7, lr}
; FP-ALL-NEXT: push {r7, lr}
; FP-ALL-NEXT: .setfp r7, sp
; FP-ALL-NEXT: add r7, sp, #0
; FP-ALL-NEXT: mov r0, lr
; FP-ALL-NEXT: bl sink_ptr
; FP-ALL-NEXT: pop {r7, pc}
;
; FP-AAPCS-LABEL: ra_call:
; FP-AAPCS: @ %bb.0: @ %entry
; FP-AAPCS-NEXT: .save {lr}
; FP-AAPCS-NEXT: push {lr}
; FP-AAPCS-NEXT: mov r3, r11
; FP-AAPCS-NEXT: .save {r11}
; FP-AAPCS-NEXT: push {r3}
; FP-AAPCS-NEXT: .setfp r11, sp
; FP-AAPCS-NEXT: mov r11, sp
; FP-AAPCS-NEXT: mov r0, lr
; FP-AAPCS-NEXT: bl sink_ptr
; FP-AAPCS-NEXT: pop {r0}
; FP-AAPCS-NEXT: mov r11, r0
; FP-AAPCS-NEXT: pop {pc}
entry:
%r = tail call ptr @llvm.returnaddress(i32 0)
tail call void @sink_ptr(ptr %r)
ret void
}
define ptr @ra_return() {
; FP-NONE-LABEL: ra_return:
; FP-NONE: @ %bb.0: @ %entry
; FP-NONE-NEXT: mov r0, lr
; FP-NONE-NEXT: bx lr
;
; FP-ALL-LABEL: ra_return:
; FP-ALL: @ %bb.0: @ %entry
; FP-ALL-NEXT: .save {r7, lr}
; FP-ALL-NEXT: push {r7, lr}
; FP-ALL-NEXT: .setfp r7, sp
; FP-ALL-NEXT: add r7, sp, #0
; FP-ALL-NEXT: mov r0, lr
; FP-ALL-NEXT: pop {r7, pc}
;
; FP-AAPCS-LABEL: ra_return:
; FP-AAPCS: @ %bb.0: @ %entry
; FP-AAPCS-NEXT: .save {lr}
; FP-AAPCS-NEXT: push {lr}
; FP-AAPCS-NEXT: mov r3, r11
; FP-AAPCS-NEXT: .save {r11}
; FP-AAPCS-NEXT: push {r3}
; FP-AAPCS-NEXT: .setfp r11, sp
; FP-AAPCS-NEXT: mov r11, sp
; FP-AAPCS-NEXT: mov r0, lr
; FP-AAPCS-NEXT: pop {r1}
; FP-AAPCS-NEXT: mov r11, r1
; FP-AAPCS-NEXT: pop {pc}
entry:
%r = tail call ptr @llvm.returnaddress(i32 0)
ret ptr %r
}
define ptr @callee_saved_low() {
; FP-NONE-LABEL: callee_saved_low:
; FP-NONE: @ %bb.0: @ %entry
; FP-NONE-NEXT: .save {r4, r5, r7, lr}
; FP-NONE-NEXT: push {r4, r5, r7, lr}
; FP-NONE-NEXT: mov r0, lr
; FP-NONE-NEXT: @APP
; FP-NONE-NEXT: @NO_APP
; FP-NONE-NEXT: pop {r4, r5, r7, pc}
;
; FP-ALL-LABEL: callee_saved_low:
; FP-ALL: @ %bb.0: @ %entry
; FP-ALL-NEXT: .save {r4, r5, r7, lr}
; FP-ALL-NEXT: push {r4, r5, r7, lr}
; FP-ALL-NEXT: .setfp r7, sp, #8
; FP-ALL-NEXT: add r7, sp, #8
; FP-ALL-NEXT: mov r0, lr
; FP-ALL-NEXT: @APP
; FP-ALL-NEXT: @NO_APP
; FP-ALL-NEXT: pop {r4, r5, r7, pc}
;
; FP-AAPCS-LABEL: callee_saved_low:
; FP-AAPCS: @ %bb.0: @ %entry
; FP-AAPCS-NEXT: .save {lr}
; FP-AAPCS-NEXT: push {lr}
; FP-AAPCS-NEXT: mov r3, r11
; FP-AAPCS-NEXT: .save {r11}
; FP-AAPCS-NEXT: push {r3}
; FP-AAPCS-NEXT: .setfp r11, sp
; FP-AAPCS-NEXT: mov r11, sp
; FP-AAPCS-NEXT: .save {r4, r5}
; FP-AAPCS-NEXT: push {r4, r5}
; FP-AAPCS-NEXT: mov r0, lr
; FP-AAPCS-NEXT: @APP
; FP-AAPCS-NEXT: @NO_APP
; FP-AAPCS-NEXT: pop {r4, r5}
; FP-AAPCS-NEXT: pop {r1}
; FP-AAPCS-NEXT: mov r11, r1
; FP-AAPCS-NEXT: pop {pc}
entry:
call void asm sideeffect "", "~{r4},~{r5}"()
%r = tail call ptr @llvm.returnaddress(i32 0)
ret ptr %r
}
define ptr @callee_saved_high() {
; FP-NONE-LABEL: callee_saved_high:
; FP-NONE: @ %bb.0: @ %entry
; FP-NONE-NEXT: mov r3, r9
; FP-NONE-NEXT: mov r2, r8
; FP-NONE-NEXT: .save {r8, r9}
; FP-NONE-NEXT: push {r2, r3}
; FP-NONE-NEXT: mov r0, lr
; FP-NONE-NEXT: @APP
; FP-NONE-NEXT: @NO_APP
; FP-NONE-NEXT: pop {r1, r2}
; FP-NONE-NEXT: mov r8, r1
; FP-NONE-NEXT: mov r9, r2
; FP-NONE-NEXT: bx lr
;
; FP-ALL-LABEL: callee_saved_high:
; FP-ALL: @ %bb.0: @ %entry
; FP-ALL-NEXT: .save {r7, lr}
; FP-ALL-NEXT: push {r7, lr}
; FP-ALL-NEXT: .setfp r7, sp
; FP-ALL-NEXT: add r7, sp, #0
; FP-ALL-NEXT: mov r3, r9
; FP-ALL-NEXT: mov r2, r8
; FP-ALL-NEXT: .save {r8, r9}
; FP-ALL-NEXT: push {r2, r3}
; FP-ALL-NEXT: mov r0, lr
; FP-ALL-NEXT: @APP
; FP-ALL-NEXT: @NO_APP
; FP-ALL-NEXT: pop {r1, r2}
; FP-ALL-NEXT: mov r8, r1
; FP-ALL-NEXT: mov r9, r2
; FP-ALL-NEXT: pop {r7, pc}
;
; FP-AAPCS-LABEL: callee_saved_high:
; FP-AAPCS: @ %bb.0: @ %entry
; FP-AAPCS-NEXT: .save {lr}
; FP-AAPCS-NEXT: push {lr}
; FP-AAPCS-NEXT: mov r3, r11
; FP-AAPCS-NEXT: .save {r11}
; FP-AAPCS-NEXT: push {r3}
; FP-AAPCS-NEXT: .setfp r11, sp
; FP-AAPCS-NEXT: mov r11, sp
; FP-AAPCS-NEXT: mov r3, r9
; FP-AAPCS-NEXT: mov r2, r8
; FP-AAPCS-NEXT: .save {r8, r9}
; FP-AAPCS-NEXT: push {r2, r3}
; FP-AAPCS-NEXT: mov r0, lr
; FP-AAPCS-NEXT: @APP
; FP-AAPCS-NEXT: @NO_APP
; FP-AAPCS-NEXT: pop {r1, r2}
; FP-AAPCS-NEXT: mov r8, r1
; FP-AAPCS-NEXT: mov r9, r2
; FP-AAPCS-NEXT: pop {r1}
; FP-AAPCS-NEXT: mov r11, r1
; FP-AAPCS-NEXT: pop {pc}
entry:
call void asm sideeffect "", "~{r8},~{r9}"()
%r = tail call ptr @llvm.returnaddress(i32 0)
ret ptr %r
}
define ptr @large_alloca() {
; FP-NONE-LABEL: large_alloca:
; FP-NONE: @ %bb.0: @ %entry
; FP-NONE-NEXT: .save {r4, r5, r6, lr}
; FP-NONE-NEXT: push {r4, r5, r6, lr}
; FP-NONE-NEXT: ldr r6, .LCPI4_0
; FP-NONE-NEXT: .pad #2000
; FP-NONE-NEXT: add sp, r6
; FP-NONE-NEXT: mov r4, lr
; FP-NONE-NEXT: mov r0, sp
; FP-NONE-NEXT: bl sink_ptr
; FP-NONE-NEXT: mov r0, r4
; FP-NONE-NEXT: ldr r6, .LCPI4_1
; FP-NONE-NEXT: add sp, r6
; FP-NONE-NEXT: pop {r4, r5, r6, pc}
; FP-NONE-NEXT: .p2align 2
; FP-NONE-NEXT: @ %bb.1:
; FP-NONE-NEXT: .LCPI4_0:
; FP-NONE-NEXT: .long 4294965296 @ 0xfffff830
; FP-NONE-NEXT: .LCPI4_1:
; FP-NONE-NEXT: .long 2000 @ 0x7d0
;
; FP-ALL-LABEL: large_alloca:
; FP-ALL: @ %bb.0: @ %entry
; FP-ALL-NEXT: .save {r4, r6, r7, lr}
; FP-ALL-NEXT: push {r4, r6, r7, lr}
; FP-ALL-NEXT: .setfp r7, sp, #8
; FP-ALL-NEXT: add r7, sp, #8
; FP-ALL-NEXT: ldr r6, .LCPI4_0
; FP-ALL-NEXT: .pad #2000
; FP-ALL-NEXT: add sp, r6
; FP-ALL-NEXT: mov r4, lr
; FP-ALL-NEXT: mov r0, sp
; FP-ALL-NEXT: bl sink_ptr
; FP-ALL-NEXT: mov r0, r4
; FP-ALL-NEXT: subs r6, r7, #7
; FP-ALL-NEXT: subs r6, #1
; FP-ALL-NEXT: mov sp, r6
; FP-ALL-NEXT: pop {r4, r6, r7, pc}
; FP-ALL-NEXT: .p2align 2
; FP-ALL-NEXT: @ %bb.1:
; FP-ALL-NEXT: .LCPI4_0:
; FP-ALL-NEXT: .long 4294965296 @ 0xfffff830
;
; FP-AAPCS-LABEL: large_alloca:
; FP-AAPCS: @ %bb.0: @ %entry
; FP-AAPCS-NEXT: .save {lr}
; FP-AAPCS-NEXT: push {lr}
; FP-AAPCS-NEXT: mov r3, r11
; FP-AAPCS-NEXT: .save {r11}
; FP-AAPCS-NEXT: push {r3}
; FP-AAPCS-NEXT: .setfp r11, sp
; FP-AAPCS-NEXT: mov r11, sp
; FP-AAPCS-NEXT: .save {r4, r7}
; FP-AAPCS-NEXT: push {r4, r7}
; FP-AAPCS-NEXT: ldr r7, .LCPI4_0
; FP-AAPCS-NEXT: .pad #2000
; FP-AAPCS-NEXT: add sp, r7
; FP-AAPCS-NEXT: mov r4, lr
; FP-AAPCS-NEXT: mov r0, sp
; FP-AAPCS-NEXT: bl sink_ptr
; FP-AAPCS-NEXT: mov r0, r4
; FP-AAPCS-NEXT: mov r7, r11
; FP-AAPCS-NEXT: subs r7, #8
; FP-AAPCS-NEXT: mov sp, r7
; FP-AAPCS-NEXT: pop {r4, r7}
; FP-AAPCS-NEXT: pop {r1}
; FP-AAPCS-NEXT: mov r11, r1
; FP-AAPCS-NEXT: pop {pc}
; FP-AAPCS-NEXT: .p2align 2
; FP-AAPCS-NEXT: @ %bb.1:
; FP-AAPCS-NEXT: .LCPI4_0:
; FP-AAPCS-NEXT: .long 4294965296 @ 0xfffff830
entry:
%big = alloca i8, i32 2000
tail call void @sink_ptr(ptr %big)
%r = tail call ptr @llvm.returnaddress(i32 0)
ret ptr %r
}
define ptr @var_alloca(i32 %size) {
; FP-NONE-LABEL: var_alloca:
; FP-NONE: @ %bb.0: @ %entry
; FP-NONE-NEXT: .save {r4, r6, r7, lr}
; FP-NONE-NEXT: push {r4, r6, r7, lr}
; FP-NONE-NEXT: .setfp r7, sp, #8
; FP-NONE-NEXT: add r7, sp, #8
; FP-NONE-NEXT: mov r6, sp
; FP-NONE-NEXT: mov r4, lr
; FP-NONE-NEXT: adds r0, r0, #7
; FP-NONE-NEXT: movs r1, #7
; FP-NONE-NEXT: bics r0, r1
; FP-NONE-NEXT: mov r1, sp
; FP-NONE-NEXT: subs r0, r1, r0
; FP-NONE-NEXT: mov sp, r0
; FP-NONE-NEXT: bl sink_ptr
; FP-NONE-NEXT: mov r0, r4
; FP-NONE-NEXT: subs r6, r7, #7
; FP-NONE-NEXT: subs r6, #1
; FP-NONE-NEXT: mov sp, r6
; FP-NONE-NEXT: pop {r4, r6, r7, pc}
;
; FP-ALL-LABEL: var_alloca:
; FP-ALL: @ %bb.0: @ %entry
; FP-ALL-NEXT: .save {r4, r6, r7, lr}
; FP-ALL-NEXT: push {r4, r6, r7, lr}
; FP-ALL-NEXT: .setfp r7, sp, #8
; FP-ALL-NEXT: add r7, sp, #8
; FP-ALL-NEXT: mov r6, sp
; FP-ALL-NEXT: mov r4, lr
; FP-ALL-NEXT: adds r0, r0, #7
; FP-ALL-NEXT: movs r1, #7
; FP-ALL-NEXT: bics r0, r1
; FP-ALL-NEXT: mov r1, sp
; FP-ALL-NEXT: subs r0, r1, r0
; FP-ALL-NEXT: mov sp, r0
; FP-ALL-NEXT: bl sink_ptr
; FP-ALL-NEXT: mov r0, r4
; FP-ALL-NEXT: subs r6, r7, #7
; FP-ALL-NEXT: subs r6, #1
; FP-ALL-NEXT: mov sp, r6
; FP-ALL-NEXT: pop {r4, r6, r7, pc}
;
; FP-AAPCS-LABEL: var_alloca:
; FP-AAPCS: @ %bb.0: @ %entry
; FP-AAPCS-NEXT: .save {lr}
; FP-AAPCS-NEXT: push {lr}
; FP-AAPCS-NEXT: mov r3, r11
; FP-AAPCS-NEXT: .save {r11}
; FP-AAPCS-NEXT: push {r3}
; FP-AAPCS-NEXT: .setfp r11, sp
; FP-AAPCS-NEXT: mov r11, sp
; FP-AAPCS-NEXT: .save {r4, r6}
; FP-AAPCS-NEXT: push {r4, r6}
; FP-AAPCS-NEXT: mov r6, sp
; FP-AAPCS-NEXT: mov r4, lr
; FP-AAPCS-NEXT: adds r0, r0, #7
; FP-AAPCS-NEXT: movs r1, #7
; FP-AAPCS-NEXT: bics r0, r1
; FP-AAPCS-NEXT: mov r1, sp
; FP-AAPCS-NEXT: subs r0, r1, r0
; FP-AAPCS-NEXT: mov sp, r0
; FP-AAPCS-NEXT: bl sink_ptr
; FP-AAPCS-NEXT: mov r0, r4
; FP-AAPCS-NEXT: mov r6, r11
; FP-AAPCS-NEXT: subs r6, #8
; FP-AAPCS-NEXT: mov sp, r6
; FP-AAPCS-NEXT: pop {r4, r6}
; FP-AAPCS-NEXT: pop {r1}
; FP-AAPCS-NEXT: mov r11, r1
; FP-AAPCS-NEXT: pop {pc}
entry:
%var = alloca i8, i32 %size
tail call void @sink_ptr(ptr %var)
%r = tail call ptr @llvm.returnaddress(i32 0)
ret ptr %r
}
define i32 @all_arg_regs(i32 %a, i32 %b, i32 %c, i32 %d) {
; FP-NONE-LABEL: all_arg_regs:
; FP-NONE: @ %bb.0: @ %entry
; FP-NONE-NEXT: .save {r4, lr}
; FP-NONE-NEXT: push {r4, lr}
; FP-NONE-NEXT: mov r4, lr
; FP-NONE-NEXT: adds r0, r0, r1
; FP-NONE-NEXT: adds r0, r0, r2
; FP-NONE-NEXT: adds r0, r0, r3
; FP-NONE-NEXT: adds r0, r0, r4
; FP-NONE-NEXT: pop {r4, pc}
;
; FP-ALL-LABEL: all_arg_regs:
; FP-ALL: @ %bb.0: @ %entry
; FP-ALL-NEXT: .save {r4, r6, r7, lr}
; FP-ALL-NEXT: push {r4, r6, r7, lr}
; FP-ALL-NEXT: .setfp r7, sp, #8
; FP-ALL-NEXT: add r7, sp, #8
; FP-ALL-NEXT: mov r4, lr
; FP-ALL-NEXT: adds r0, r0, r1
; FP-ALL-NEXT: adds r0, r0, r2
; FP-ALL-NEXT: adds r0, r0, r3
; FP-ALL-NEXT: adds r0, r0, r4
; FP-ALL-NEXT: pop {r4, r6, r7, pc}
;
; FP-AAPCS-LABEL: all_arg_regs:
; FP-AAPCS: @ %bb.0: @ %entry
; FP-AAPCS-NEXT: .save {lr}
; FP-AAPCS-NEXT: push {lr}
; FP-AAPCS-NEXT: mov lr, r11
; FP-AAPCS-NEXT: .save {r11}
; FP-AAPCS-NEXT: push {lr}
; FP-AAPCS-NEXT: .setfp r11, sp
; FP-AAPCS-NEXT: mov r11, sp
; FP-AAPCS-NEXT: .save {r4, r7}
; FP-AAPCS-NEXT: push {r4, r7}
; FP-AAPCS-NEXT: ldr r7, [sp, #12]
; FP-AAPCS-NEXT: mov lr, r7
; FP-AAPCS-NEXT: mov r4, lr
; FP-AAPCS-NEXT: adds r0, r0, r1
; FP-AAPCS-NEXT: adds r0, r0, r2
; FP-AAPCS-NEXT: adds r0, r0, r3
; FP-AAPCS-NEXT: adds r0, r0, r4
; FP-AAPCS-NEXT: pop {r4, r7}
; FP-AAPCS-NEXT: pop {r1}
; FP-AAPCS-NEXT: mov r11, r1
; FP-AAPCS-NEXT: pop {pc}
entry:
%r = tail call ptr @llvm.returnaddress(i32 0)
%ri = ptrtoint ptr %r to i32
%t1 = add i32 %a, %b
%t2 = add i32 %t1, %c
%t3 = add i32 %t2, %d
%t4 = add i32 %t3, %ri
ret i32 %t4
}
define ptr @ra_depth_1() {
; FP-NONE-LABEL: ra_depth_1:
; FP-NONE: @ %bb.0: @ %entry
; FP-NONE-NEXT: .save {r7, lr}
; FP-NONE-NEXT: push {r7, lr}
; FP-NONE-NEXT: .setfp r7, sp
; FP-NONE-NEXT: add r7, sp, #0
; FP-NONE-NEXT: ldr r0, [r7]
; FP-NONE-NEXT: ldr r0, [r0, #4]
; FP-NONE-NEXT: pop {r7, pc}
;
; FP-ALL-LABEL: ra_depth_1:
; FP-ALL: @ %bb.0: @ %entry
; FP-ALL-NEXT: .save {r7, lr}
; FP-ALL-NEXT: push {r7, lr}
; FP-ALL-NEXT: .setfp r7, sp
; FP-ALL-NEXT: add r7, sp, #0
; FP-ALL-NEXT: ldr r0, [r7]
; FP-ALL-NEXT: ldr r0, [r0, #4]
; FP-ALL-NEXT: pop {r7, pc}
;
; FP-AAPCS-LABEL: ra_depth_1:
; FP-AAPCS: @ %bb.0: @ %entry
; FP-AAPCS-NEXT: .save {lr}
; FP-AAPCS-NEXT: push {lr}
; FP-AAPCS-NEXT: mov r3, r11
; FP-AAPCS-NEXT: .save {r11}
; FP-AAPCS-NEXT: push {r3}
; FP-AAPCS-NEXT: .setfp r11, sp
; FP-AAPCS-NEXT: mov r11, sp
; FP-AAPCS-NEXT: mov r0, r11
; FP-AAPCS-NEXT: ldr r0, [r0]
; FP-AAPCS-NEXT: ldr r0, [r0, #4]
; FP-AAPCS-NEXT: pop {r1}
; FP-AAPCS-NEXT: mov r11, r1
; FP-AAPCS-NEXT: pop {pc}
entry:
%r = tail call ptr @llvm.returnaddress(i32 1)
ret ptr %r
}
declare void @sink_ptr(ptr)