1; RUN: llc -mtriple arm-arm-none-eabi -filetype asm -o - %s -frame-pointer=all | FileCheck %s --check-prefixes=FP,LEAF-FP 2; 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-AAPCS 3; RUN: llc -mtriple arm-arm-none-eabi -filetype asm -o - %s -frame-pointer=non-leaf | FileCheck %s --check-prefixes=FP,LEAF-NOFP 4; 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-AAPCS 5; RUN: llc -mtriple arm-arm-none-eabi -filetype asm -o - %s -frame-pointer=none | FileCheck %s --check-prefixes=NOFP,LEAF-NOFP 6; 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-AAPCS 7; RUN: llc -mtriple arm-arm-none-eabi -filetype asm -o - %s -frame-pointer=reserved | FileCheck %s --check-prefixes=NOFP,LEAF-NOFP 8; RUN: llc -mtriple arm-arm-none-eabi -filetype asm -o - %s -frame-pointer=reserved -mattr=+aapcs-frame-chain | FileCheck %s --check-prefixes=NOFP-AAPCS,LEAF-NOFP-AAPCS 9 10define dso_local noundef i32 @leaf(i32 noundef %0) { 11; LEAF-FP-LABEL: leaf: 12; LEAF-FP: @ %bb.0: 13; LEAF-FP-NEXT: .save {r11, lr} 14; LEAF-FP-NEXT: push {r11, lr} 15; LEAF-FP-NEXT: .setfp r11, sp 16; LEAF-FP-NEXT: mov r11, sp 17; LEAF-FP-NEXT: push {r0} 18; LEAF-FP-NEXT: add r0, r0, #4 19; LEAF-FP-NEXT: mov sp, r11 20; LEAF-FP-NEXT: pop {r11, lr} 21; LEAF-FP-NEXT: mov pc, lr 22; 23; LEAF-FP-AAPCS-LABEL: leaf: 24; LEAF-FP-AAPCS: @ %bb.0: 25; LEAF-FP-AAPCS-NEXT: .save {r11, lr} 26; LEAF-FP-AAPCS-NEXT: push {r11, lr} 27; LEAF-FP-AAPCS-NEXT: .setfp r11, sp 28; LEAF-FP-AAPCS-NEXT: mov r11, sp 29; LEAF-FP-AAPCS-NEXT: push {r0} 30; LEAF-FP-AAPCS-NEXT: add r0, r0, #4 31; LEAF-FP-AAPCS-NEXT: mov sp, r11 32; LEAF-FP-AAPCS-NEXT: pop {r11, lr} 33; LEAF-FP-AAPCS-NEXT: mov pc, lr 34; 35; LEAF-NOFP-LABEL: leaf: 36; LEAF-NOFP: @ %bb.0: 37; LEAF-NOFP-NEXT: .pad #4 38; LEAF-NOFP-NEXT: sub sp, sp, #4 39; LEAF-NOFP-NEXT: str r0, [sp] 40; LEAF-NOFP-NEXT: add r0, r0, #4 41; LEAF-NOFP-NEXT: add sp, sp, #4 42; LEAF-NOFP-NEXT: mov pc, lr 43; 44; LEAF-NOFP-AAPCS-LABEL: leaf: 45; LEAF-NOFP-AAPCS: @ %bb.0: 46; LEAF-NOFP-AAPCS-NEXT: .pad #4 47; LEAF-NOFP-AAPCS-NEXT: sub sp, sp, #4 48; LEAF-NOFP-AAPCS-NEXT: str r0, [sp] 49; LEAF-NOFP-AAPCS-NEXT: add r0, r0, #4 50; LEAF-NOFP-AAPCS-NEXT: add sp, sp, #4 51; LEAF-NOFP-AAPCS-NEXT: mov pc, lr 52 %2 = alloca i32, align 4 53 store i32 %0, ptr %2, align 4 54 %3 = load i32, ptr %2, align 4 55 %4 = add nsw i32 %3, 4 56 ret i32 %4 57} 58 59define dso_local noundef i32 @non_leaf(i32 noundef %0) { 60; FP-LABEL: non_leaf: 61; FP: @ %bb.0: 62; FP-NEXT: .save {r11, lr} 63; FP-NEXT: push {r11, lr} 64; FP-NEXT: .setfp r11, sp 65; FP-NEXT: mov r11, sp 66; FP-NEXT: .pad #8 67; FP-NEXT: sub sp, sp, #8 68; FP-NEXT: str r0, [sp, #4] 69; FP-NEXT: bl leaf 70; FP-NEXT: add r0, r0, #1 71; FP-NEXT: mov sp, r11 72; FP-NEXT: pop {r11, lr} 73; FP-NEXT: mov pc, lr 74; 75; FP-AAPCS-LABEL: non_leaf: 76; FP-AAPCS: @ %bb.0: 77; FP-AAPCS-NEXT: .save {r11, lr} 78; FP-AAPCS-NEXT: push {r11, lr} 79; FP-AAPCS-NEXT: .setfp r11, sp 80; FP-AAPCS-NEXT: mov r11, sp 81; FP-AAPCS-NEXT: .pad #8 82; FP-AAPCS-NEXT: sub sp, sp, #8 83; FP-AAPCS-NEXT: str r0, [sp, #4] 84; FP-AAPCS-NEXT: bl leaf 85; FP-AAPCS-NEXT: add r0, r0, #1 86; FP-AAPCS-NEXT: mov sp, r11 87; FP-AAPCS-NEXT: pop {r11, lr} 88; FP-AAPCS-NEXT: mov pc, lr 89; 90; NOFP-LABEL: non_leaf: 91; NOFP: @ %bb.0: 92; NOFP-NEXT: .save {r11, lr} 93; NOFP-NEXT: push {r11, lr} 94; NOFP-NEXT: .pad #8 95; NOFP-NEXT: sub sp, sp, #8 96; NOFP-NEXT: str r0, [sp, #4] 97; NOFP-NEXT: bl leaf 98; NOFP-NEXT: add r0, r0, #1 99; NOFP-NEXT: add sp, sp, #8 100; NOFP-NEXT: pop {r11, lr} 101; NOFP-NEXT: mov pc, lr 102; 103; NOFP-AAPCS-LABEL: non_leaf: 104; NOFP-AAPCS: @ %bb.0: 105; NOFP-AAPCS-NEXT: .save {r11, lr} 106; NOFP-AAPCS-NEXT: push {r11, lr} 107; NOFP-AAPCS-NEXT: .pad #8 108; NOFP-AAPCS-NEXT: sub sp, sp, #8 109; NOFP-AAPCS-NEXT: str r0, [sp, #4] 110; NOFP-AAPCS-NEXT: bl leaf 111; NOFP-AAPCS-NEXT: add r0, r0, #1 112; NOFP-AAPCS-NEXT: add sp, sp, #8 113; NOFP-AAPCS-NEXT: pop {r11, lr} 114; NOFP-AAPCS-NEXT: mov pc, lr 115 %2 = alloca i32, align 4 116 store i32 %0, ptr %2, align 4 117 %3 = load i32, ptr %2, align 4 118 %4 = call noundef i32 @leaf(i32 noundef %3) 119 %5 = add nsw i32 %4, 1 120 ret i32 %5 121} 122 123declare ptr @llvm.stacksave() 124define dso_local void @required_fp(i32 %0, i32 %1) { 125; LEAF-FP-LABEL: required_fp: 126; LEAF-FP: @ %bb.0: 127; LEAF-FP-NEXT: .save {r4, r5, r11, lr} 128; LEAF-FP-NEXT: push {r4, r5, r11, lr} 129; LEAF-FP-NEXT: .setfp r11, sp, #8 130; LEAF-FP-NEXT: add r11, sp, #8 131; LEAF-FP-NEXT: .pad #24 132; LEAF-FP-NEXT: sub sp, sp, #24 133; LEAF-FP-NEXT: str r1, [r11, #-16] 134; LEAF-FP-NEXT: mov r1, #7 135; LEAF-FP-NEXT: add r1, r1, r0, lsl #2 136; LEAF-FP-NEXT: str r0, [r11, #-12] 137; LEAF-FP-NEXT: bic r1, r1, #7 138; LEAF-FP-NEXT: str sp, [r11, #-24] 139; LEAF-FP-NEXT: sub sp, sp, r1 140; LEAF-FP-NEXT: mov r1, #0 141; LEAF-FP-NEXT: str r0, [r11, #-32] 142; LEAF-FP-NEXT: str r1, [r11, #-28] 143; LEAF-FP-NEXT: sub sp, r11, #8 144; LEAF-FP-NEXT: pop {r4, r5, r11, lr} 145; LEAF-FP-NEXT: mov pc, lr 146; 147; LEAF-FP-AAPCS-LABEL: required_fp: 148; LEAF-FP-AAPCS: @ %bb.0: 149; LEAF-FP-AAPCS-NEXT: .save {r4, r5, r11, lr} 150; LEAF-FP-AAPCS-NEXT: push {r4, r5, r11, lr} 151; LEAF-FP-AAPCS-NEXT: .setfp r11, sp, #8 152; LEAF-FP-AAPCS-NEXT: add r11, sp, #8 153; LEAF-FP-AAPCS-NEXT: .pad #24 154; LEAF-FP-AAPCS-NEXT: sub sp, sp, #24 155; LEAF-FP-AAPCS-NEXT: str r1, [r11, #-16] 156; LEAF-FP-AAPCS-NEXT: mov r1, #7 157; LEAF-FP-AAPCS-NEXT: add r1, r1, r0, lsl #2 158; LEAF-FP-AAPCS-NEXT: str r0, [r11, #-12] 159; LEAF-FP-AAPCS-NEXT: bic r1, r1, #7 160; LEAF-FP-AAPCS-NEXT: str sp, [r11, #-24] 161; LEAF-FP-AAPCS-NEXT: sub sp, sp, r1 162; LEAF-FP-AAPCS-NEXT: mov r1, #0 163; LEAF-FP-AAPCS-NEXT: str r0, [r11, #-32] 164; LEAF-FP-AAPCS-NEXT: str r1, [r11, #-28] 165; LEAF-FP-AAPCS-NEXT: sub sp, r11, #8 166; LEAF-FP-AAPCS-NEXT: pop {r4, r5, r11, lr} 167; LEAF-FP-AAPCS-NEXT: mov pc, lr 168; 169; LEAF-NOFP-LABEL: required_fp: 170; LEAF-NOFP: @ %bb.0: 171; LEAF-NOFP-NEXT: .save {r4, r5, r11} 172; LEAF-NOFP-NEXT: push {r4, r5, r11} 173; LEAF-NOFP-NEXT: .setfp r11, sp, #8 174; LEAF-NOFP-NEXT: add r11, sp, #8 175; LEAF-NOFP-NEXT: .pad #20 176; LEAF-NOFP-NEXT: sub sp, sp, #20 177; LEAF-NOFP-NEXT: str r1, [r11, #-16] 178; LEAF-NOFP-NEXT: mov r1, #7 179; LEAF-NOFP-NEXT: add r1, r1, r0, lsl #2 180; LEAF-NOFP-NEXT: str r0, [r11, #-12] 181; LEAF-NOFP-NEXT: bic r1, r1, #7 182; LEAF-NOFP-NEXT: str sp, [r11, #-20] 183; LEAF-NOFP-NEXT: sub sp, sp, r1 184; LEAF-NOFP-NEXT: mov r1, #0 185; LEAF-NOFP-NEXT: str r0, [r11, #-28] 186; LEAF-NOFP-NEXT: str r1, [r11, #-24] 187; LEAF-NOFP-NEXT: sub sp, r11, #8 188; LEAF-NOFP-NEXT: pop {r4, r5, r11} 189; LEAF-NOFP-NEXT: mov pc, lr 190; 191; LEAF-NOFP-AAPCS-LABEL: required_fp: 192; LEAF-NOFP-AAPCS: @ %bb.0: 193; LEAF-NOFP-AAPCS-NEXT: .save {r4, r5, r11, lr} 194; LEAF-NOFP-AAPCS-NEXT: push {r4, r5, r11, lr} 195; LEAF-NOFP-AAPCS-NEXT: .setfp r11, sp, #8 196; LEAF-NOFP-AAPCS-NEXT: add r11, sp, #8 197; LEAF-NOFP-AAPCS-NEXT: .pad #24 198; LEAF-NOFP-AAPCS-NEXT: sub sp, sp, #24 199; LEAF-NOFP-AAPCS-NEXT: str r1, [r11, #-16] 200; LEAF-NOFP-AAPCS-NEXT: mov r1, #7 201; LEAF-NOFP-AAPCS-NEXT: add r1, r1, r0, lsl #2 202; LEAF-NOFP-AAPCS-NEXT: str r0, [r11, #-12] 203; LEAF-NOFP-AAPCS-NEXT: bic r1, r1, #7 204; LEAF-NOFP-AAPCS-NEXT: str sp, [r11, #-24] 205; LEAF-NOFP-AAPCS-NEXT: sub sp, sp, r1 206; LEAF-NOFP-AAPCS-NEXT: mov r1, #0 207; LEAF-NOFP-AAPCS-NEXT: str r0, [r11, #-32] 208; LEAF-NOFP-AAPCS-NEXT: str r1, [r11, #-28] 209; LEAF-NOFP-AAPCS-NEXT: sub sp, r11, #8 210; LEAF-NOFP-AAPCS-NEXT: pop {r4, r5, r11, lr} 211; LEAF-NOFP-AAPCS-NEXT: mov pc, lr 212 %3 = alloca i32, align 4 213 %4 = alloca i32, align 4 214 %5 = alloca ptr, align 8 215 %6 = alloca i64, align 8 216 store i32 %0, ptr %3, align 4 217 store i32 %1, ptr %4, align 4 218 %7 = load i32, ptr %3, align 4 219 %8 = zext i32 %7 to i64 220 %9 = call ptr @llvm.stacksave() 221 store ptr %9, ptr %5, align 8 222 %10 = alloca i32, i64 %8, align 4 223 store i64 %8, ptr %6, align 8 224 ret void 225} 226