1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ 3; RUN: | FileCheck %s -check-prefix=RV32I 4 5declare void @notdead(ptr) 6 7; These tests must ensure the stack pointer is restored using the frame 8; pointer 9 10define void @simple_alloca(i32 %n) nounwind { 11; RV32I-LABEL: simple_alloca: 12; RV32I: # %bb.0: 13; RV32I-NEXT: addi sp, sp, -16 14; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 15; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 16; RV32I-NEXT: addi s0, sp, 16 17; RV32I-NEXT: addi a0, a0, 15 18; RV32I-NEXT: andi a0, a0, -16 19; RV32I-NEXT: sub a0, sp, a0 20; RV32I-NEXT: mv sp, a0 21; RV32I-NEXT: call notdead 22; RV32I-NEXT: addi sp, s0, -16 23; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 24; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 25; RV32I-NEXT: addi sp, sp, 16 26; RV32I-NEXT: ret 27 %1 = alloca i8, i32 %n 28 call void @notdead(ptr %1) 29 ret void 30} 31 32declare ptr @llvm.stacksave() 33declare void @llvm.stackrestore(ptr) 34 35define void @scoped_alloca(i32 %n) nounwind { 36; RV32I-LABEL: scoped_alloca: 37; RV32I: # %bb.0: 38; RV32I-NEXT: addi sp, sp, -16 39; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 40; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 41; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill 42; RV32I-NEXT: addi s0, sp, 16 43; RV32I-NEXT: mv s1, sp 44; RV32I-NEXT: addi a0, a0, 15 45; RV32I-NEXT: andi a0, a0, -16 46; RV32I-NEXT: sub a0, sp, a0 47; RV32I-NEXT: mv sp, a0 48; RV32I-NEXT: call notdead 49; RV32I-NEXT: mv sp, s1 50; RV32I-NEXT: addi sp, s0, -16 51; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 52; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 53; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload 54; RV32I-NEXT: addi sp, sp, 16 55; RV32I-NEXT: ret 56 %sp = call ptr @llvm.stacksave() 57 %addr = alloca i8, i32 %n 58 call void @notdead(ptr %addr) 59 call void @llvm.stackrestore(ptr %sp) 60 ret void 61} 62 63declare void @func(ptr, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) 64 65; Check that outgoing arguments passed on the stack do not corrupt a 66; variable-sized stack object. 67define void @alloca_callframe(i32 %n) nounwind { 68; RV32I-LABEL: alloca_callframe: 69; RV32I: # %bb.0: 70; RV32I-NEXT: addi sp, sp, -16 71; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 72; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill 73; RV32I-NEXT: addi s0, sp, 16 74; RV32I-NEXT: addi a0, a0, 15 75; RV32I-NEXT: andi a0, a0, -16 76; RV32I-NEXT: sub a0, sp, a0 77; RV32I-NEXT: mv sp, a0 78; RV32I-NEXT: addi sp, sp, -16 79; RV32I-NEXT: li t0, 12 80; RV32I-NEXT: li t1, 11 81; RV32I-NEXT: li t2, 10 82; RV32I-NEXT: li t3, 9 83; RV32I-NEXT: li a1, 2 84; RV32I-NEXT: li a2, 3 85; RV32I-NEXT: li a3, 4 86; RV32I-NEXT: li a4, 5 87; RV32I-NEXT: li a5, 6 88; RV32I-NEXT: li a6, 7 89; RV32I-NEXT: li a7, 8 90; RV32I-NEXT: sw t3, 0(sp) 91; RV32I-NEXT: sw t2, 4(sp) 92; RV32I-NEXT: sw t1, 8(sp) 93; RV32I-NEXT: sw t0, 12(sp) 94; RV32I-NEXT: call func 95; RV32I-NEXT: addi sp, sp, 16 96; RV32I-NEXT: addi sp, s0, -16 97; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 98; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload 99; RV32I-NEXT: addi sp, sp, 16 100; RV32I-NEXT: ret 101 %1 = alloca i8, i32 %n 102 call void @func(ptr %1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, 103 i32 9, i32 10, i32 11, i32 12) 104 ret void 105} 106