Files
clang-p2996/llvm/test/CodeGen/ARM/frame-chain.ll
Lucas Prates 70a5c52534 [ARM][Thumb] Command-line option to ensure AAPCS compliant Frame Records
Currently the a AAPCS compliant frame record is not always created for
functions when it should. Although a consistent frame record might not
be required in some cases, there are still scenarios where applications
may want to make use of the call hierarchy made available trough it.

In order to enable the use of AAPCS compliant frame records whilst keep
backwards compatibility, this patch introduces a new command-line option
(`-mframe-chain=[none|aapcs|aapcs+leaf]`) for Aarch32 and Thumb backends.
The option allows users to explicitly select when to use it, and is also
useful to ensure the extra overhead introduced by the frame records is
only introduced when necessary, in particular for Thumb targets.

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D125094
2022-06-27 14:08:48 +01:00

224 lines
8.2 KiB
LLVM

; RUN: llc -mtriple arm-arm-none-eabi -filetype asm -o - %s -frame-pointer=all | FileCheck %s --check-prefixes=FP,LEAF-FP
; RUN: llc -mtriple arm-arm-none-eabi -filetype asm -o - %s -frame-pointer=all -mattr=+aapcs-frame-chain | FileCheck %s --check-prefixes=FP-AAPCS,LEAF-FP
; RUN: llc -mtriple arm-arm-none-eabi -filetype asm -o - %s -frame-pointer=all -mattr=+aapcs-frame-chain-leaf | FileCheck %s --check-prefixes=FP-AAPCS,LEAF-FP-AAPCS
; RUN: llc -mtriple arm-arm-none-eabi -filetype asm -o - %s -frame-pointer=non-leaf | FileCheck %s --check-prefixes=FP,LEAF-NOFP
; RUN: llc -mtriple arm-arm-none-eabi -filetype asm -o - %s -frame-pointer=non-leaf -mattr=+aapcs-frame-chain | FileCheck %s --check-prefixes=FP-AAPCS,LEAF-NOFP
; RUN: llc -mtriple arm-arm-none-eabi -filetype asm -o - %s -frame-pointer=non-leaf -mattr=+aapcs-frame-chain-leaf | FileCheck %s --check-prefixes=FP-AAPCS,LEAF-NOFP-AAPCS
; RUN: llc -mtriple arm-arm-none-eabi -filetype asm -o - %s -frame-pointer=none | FileCheck %s --check-prefixes=NOFP,LEAF-NOFP
; RUN: llc -mtriple arm-arm-none-eabi -filetype asm -o - %s -frame-pointer=none -mattr=+aapcs-frame-chain | FileCheck %s --check-prefixes=NOFP-AAPCS,LEAF-NOFP
; RUN: llc -mtriple arm-arm-none-eabi -filetype asm -o - %s -frame-pointer=none -mattr=+aapcs-frame-chain-leaf | FileCheck %s --check-prefixes=NOFP-AAPCS,LEAF-NOFP-AAPCS
define dso_local noundef i32 @leaf(i32 noundef %0) {
; LEAF-FP-LABEL: leaf:
; LEAF-FP: @ %bb.0:
; LEAF-FP-NEXT: .pad #4
; LEAF-FP-NEXT: sub sp, sp, #4
; LEAF-FP-NEXT: str r0, [sp]
; LEAF-FP-NEXT: add r0, r0, #4
; LEAF-FP-NEXT: add sp, sp, #4
; LEAF-FP-NEXT: mov pc, lr
;
; LEAF-FP-AAPCS-LABEL: leaf:
; LEAF-FP-AAPCS: @ %bb.0:
; LEAF-FP-AAPCS-NEXT: .save {r11, lr}
; LEAF-FP-AAPCS-NEXT: push {r11, lr}
; LEAF-FP-AAPCS-NEXT: .setfp r11, sp
; LEAF-FP-AAPCS-NEXT: mov r11, sp
; LEAF-FP-AAPCS-NEXT: push {r0}
; LEAF-FP-AAPCS-NEXT: add r0, r0, #4
; LEAF-FP-AAPCS-NEXT: mov sp, r11
; LEAF-FP-AAPCS-NEXT: pop {r11, lr}
; LEAF-FP-AAPCS-NEXT: mov pc, lr
;
; LEAF-NOFP-LABEL: leaf:
; LEAF-NOFP: @ %bb.0:
; LEAF-NOFP-NEXT: .pad #4
; LEAF-NOFP-NEXT: sub sp, sp, #4
; LEAF-NOFP-NEXT: str r0, [sp]
; LEAF-NOFP-NEXT: add r0, r0, #4
; LEAF-NOFP-NEXT: add sp, sp, #4
; LEAF-NOFP-NEXT: mov pc, lr
;
; LEAF-NOFP-AAPCS-LABEL: leaf:
; LEAF-NOFP-AAPCS: @ %bb.0:
; LEAF-NOFP-AAPCS-NEXT: .pad #4
; LEAF-NOFP-AAPCS-NEXT: sub sp, sp, #4
; LEAF-NOFP-AAPCS-NEXT: str r0, [sp]
; LEAF-NOFP-AAPCS-NEXT: add r0, r0, #4
; LEAF-NOFP-AAPCS-NEXT: add sp, sp, #4
; LEAF-NOFP-AAPCS-NEXT: mov pc, lr
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
%3 = load i32, i32* %2, align 4
%4 = add nsw i32 %3, 4
ret i32 %4
}
define dso_local noundef i32 @non_leaf(i32 noundef %0) {
; FP-LABEL: non_leaf:
; FP: @ %bb.0:
; FP-NEXT: .save {r11, lr}
; FP-NEXT: push {r11, lr}
; FP-NEXT: .setfp r11, sp
; FP-NEXT: mov r11, sp
; FP-NEXT: .pad #8
; FP-NEXT: sub sp, sp, #8
; FP-NEXT: str r0, [sp, #4]
; FP-NEXT: bl leaf
; FP-NEXT: add r0, r0, #1
; FP-NEXT: mov sp, r11
; FP-NEXT: pop {r11, lr}
; FP-NEXT: mov pc, lr
;
; FP-AAPCS-LABEL: non_leaf:
; FP-AAPCS: @ %bb.0:
; FP-AAPCS-NEXT: .save {r11, lr}
; FP-AAPCS-NEXT: push {r11, lr}
; FP-AAPCS-NEXT: .setfp r11, sp
; FP-AAPCS-NEXT: mov r11, sp
; FP-AAPCS-NEXT: .pad #8
; FP-AAPCS-NEXT: sub sp, sp, #8
; FP-AAPCS-NEXT: str r0, [sp, #4]
; FP-AAPCS-NEXT: bl leaf
; FP-AAPCS-NEXT: add r0, r0, #1
; FP-AAPCS-NEXT: mov sp, r11
; FP-AAPCS-NEXT: pop {r11, lr}
; FP-AAPCS-NEXT: mov pc, lr
;
; NOFP-LABEL: non_leaf:
; NOFP: @ %bb.0:
; NOFP-NEXT: .save {r11, lr}
; NOFP-NEXT: push {r11, lr}
; NOFP-NEXT: .pad #8
; NOFP-NEXT: sub sp, sp, #8
; NOFP-NEXT: str r0, [sp, #4]
; NOFP-NEXT: bl leaf
; NOFP-NEXT: add r0, r0, #1
; NOFP-NEXT: add sp, sp, #8
; NOFP-NEXT: pop {r11, lr}
; NOFP-NEXT: mov pc, lr
;
; NOFP-AAPCS-LABEL: non_leaf:
; NOFP-AAPCS: @ %bb.0:
; NOFP-AAPCS-NEXT: .save {r11, lr}
; NOFP-AAPCS-NEXT: push {r11, lr}
; NOFP-AAPCS-NEXT: .pad #8
; NOFP-AAPCS-NEXT: sub sp, sp, #8
; NOFP-AAPCS-NEXT: str r0, [sp, #4]
; NOFP-AAPCS-NEXT: bl leaf
; NOFP-AAPCS-NEXT: add r0, r0, #1
; NOFP-AAPCS-NEXT: add sp, sp, #8
; NOFP-AAPCS-NEXT: pop {r11, lr}
; NOFP-AAPCS-NEXT: mov pc, lr
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
%3 = load i32, i32* %2, align 4
%4 = call noundef i32 @leaf(i32 noundef %3)
%5 = add nsw i32 %4, 1
ret i32 %5
}
declare i8* @llvm.stacksave()
define dso_local void @required_fp(i32 %0, i32 %1) {
; LEAF-FP-LABEL: required_fp:
; LEAF-FP: @ %bb.0:
; LEAF-FP-NEXT: .save {r4, r5, r11, lr}
; LEAF-FP-NEXT: push {r4, r5, r11, lr}
; LEAF-FP-NEXT: .setfp r11, sp, #8
; LEAF-FP-NEXT: add r11, sp, #8
; LEAF-FP-NEXT: .pad #24
; LEAF-FP-NEXT: sub sp, sp, #24
; LEAF-FP-NEXT: str r1, [r11, #-16]
; LEAF-FP-NEXT: mov r1, #7
; LEAF-FP-NEXT: add r1, r1, r0, lsl #2
; LEAF-FP-NEXT: str r0, [r11, #-12]
; LEAF-FP-NEXT: bic r1, r1, #7
; LEAF-FP-NEXT: str sp, [r11, #-24]
; LEAF-FP-NEXT: sub sp, sp, r1
; LEAF-FP-NEXT: mov r1, #0
; LEAF-FP-NEXT: str r0, [r11, #-32]
; LEAF-FP-NEXT: str r1, [r11, #-28]
; LEAF-FP-NEXT: sub sp, r11, #8
; LEAF-FP-NEXT: pop {r4, r5, r11, lr}
; LEAF-FP-NEXT: mov pc, lr
;
; LEAF-FP-AAPCS-LABEL: required_fp:
; LEAF-FP-AAPCS: @ %bb.0:
; LEAF-FP-AAPCS-NEXT: .save {r4, r5, r11, lr}
; LEAF-FP-AAPCS-NEXT: push {r4, r5, r11, lr}
; LEAF-FP-AAPCS-NEXT: .setfp r11, sp, #8
; LEAF-FP-AAPCS-NEXT: add r11, sp, #8
; LEAF-FP-AAPCS-NEXT: .pad #24
; LEAF-FP-AAPCS-NEXT: sub sp, sp, #24
; LEAF-FP-AAPCS-NEXT: str r1, [r11, #-16]
; LEAF-FP-AAPCS-NEXT: mov r1, #7
; LEAF-FP-AAPCS-NEXT: add r1, r1, r0, lsl #2
; LEAF-FP-AAPCS-NEXT: str r0, [r11, #-12]
; LEAF-FP-AAPCS-NEXT: bic r1, r1, #7
; LEAF-FP-AAPCS-NEXT: str sp, [r11, #-24]
; LEAF-FP-AAPCS-NEXT: sub sp, sp, r1
; LEAF-FP-AAPCS-NEXT: mov r1, #0
; LEAF-FP-AAPCS-NEXT: str r0, [r11, #-32]
; LEAF-FP-AAPCS-NEXT: str r1, [r11, #-28]
; LEAF-FP-AAPCS-NEXT: sub sp, r11, #8
; LEAF-FP-AAPCS-NEXT: pop {r4, r5, r11, lr}
; LEAF-FP-AAPCS-NEXT: mov pc, lr
;
; LEAF-NOFP-LABEL: required_fp:
; LEAF-NOFP: @ %bb.0:
; LEAF-NOFP-NEXT: .save {r4, r5, r11}
; LEAF-NOFP-NEXT: push {r4, r5, r11}
; LEAF-NOFP-NEXT: .setfp r11, sp, #8
; LEAF-NOFP-NEXT: add r11, sp, #8
; LEAF-NOFP-NEXT: .pad #20
; LEAF-NOFP-NEXT: sub sp, sp, #20
; LEAF-NOFP-NEXT: str r1, [r11, #-16]
; LEAF-NOFP-NEXT: mov r1, #7
; LEAF-NOFP-NEXT: add r1, r1, r0, lsl #2
; LEAF-NOFP-NEXT: str r0, [r11, #-12]
; LEAF-NOFP-NEXT: bic r1, r1, #7
; LEAF-NOFP-NEXT: str sp, [r11, #-20]
; LEAF-NOFP-NEXT: sub sp, sp, r1
; LEAF-NOFP-NEXT: mov r1, #0
; LEAF-NOFP-NEXT: str r0, [r11, #-28]
; LEAF-NOFP-NEXT: str r1, [r11, #-24]
; LEAF-NOFP-NEXT: sub sp, r11, #8
; LEAF-NOFP-NEXT: pop {r4, r5, r11}
; LEAF-NOFP-NEXT: mov pc, lr
;
; LEAF-NOFP-AAPCS-LABEL: required_fp:
; LEAF-NOFP-AAPCS: @ %bb.0:
; LEAF-NOFP-AAPCS-NEXT: .save {r4, r5, r11, lr}
; LEAF-NOFP-AAPCS-NEXT: push {r4, r5, r11, lr}
; LEAF-NOFP-AAPCS-NEXT: .setfp r11, sp, #8
; LEAF-NOFP-AAPCS-NEXT: add r11, sp, #8
; LEAF-NOFP-AAPCS-NEXT: .pad #24
; LEAF-NOFP-AAPCS-NEXT: sub sp, sp, #24
; LEAF-NOFP-AAPCS-NEXT: str r1, [r11, #-16]
; LEAF-NOFP-AAPCS-NEXT: mov r1, #7
; LEAF-NOFP-AAPCS-NEXT: add r1, r1, r0, lsl #2
; LEAF-NOFP-AAPCS-NEXT: str r0, [r11, #-12]
; LEAF-NOFP-AAPCS-NEXT: bic r1, r1, #7
; LEAF-NOFP-AAPCS-NEXT: str sp, [r11, #-24]
; LEAF-NOFP-AAPCS-NEXT: sub sp, sp, r1
; LEAF-NOFP-AAPCS-NEXT: mov r1, #0
; LEAF-NOFP-AAPCS-NEXT: str r0, [r11, #-32]
; LEAF-NOFP-AAPCS-NEXT: str r1, [r11, #-28]
; LEAF-NOFP-AAPCS-NEXT: sub sp, r11, #8
; LEAF-NOFP-AAPCS-NEXT: pop {r4, r5, r11, lr}
; LEAF-NOFP-AAPCS-NEXT: mov pc, lr
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i8*, align 8
%6 = alloca i64, align 8
store i32 %0, i32* %3, align 4
store i32 %1, i32* %4, align 4
%7 = load i32, i32* %3, align 4
%8 = zext i32 %7 to i64
%9 = call i8* @llvm.stacksave()
store i8* %9, i8** %5, align 8
%10 = alloca i32, i64 %8, align 4
store i64 %8, i64* %6, align 8
ret void
}