| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py |
| ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ |
| ; RUN: | FileCheck -check-prefix=RV32I %s |
| |
| declare void @notdead(i8*) |
| declare i8* @llvm.frameaddress(i32) |
| declare i8* @llvm.returnaddress(i32) |
| |
| define i8* @test_frameaddress_0() nounwind { |
| ; RV32I-LABEL: test_frameaddress_0: |
| ; RV32I: # %bb.0: |
| ; RV32I-NEXT: addi sp, sp, -16 |
| ; RV32I-NEXT: sw ra, 12(sp) |
| ; RV32I-NEXT: sw s0, 8(sp) |
| ; RV32I-NEXT: addi s0, sp, 16 |
| ; RV32I-NEXT: mv a0, s0 |
| ; RV32I-NEXT: lw s0, 8(sp) |
| ; RV32I-NEXT: lw ra, 12(sp) |
| ; RV32I-NEXT: addi sp, sp, 16 |
| ; RV32I-NEXT: ret |
| %1 = call i8* @llvm.frameaddress(i32 0) |
| ret i8* %1 |
| } |
| |
| define i8* @test_frameaddress_2() nounwind { |
| ; RV32I-LABEL: test_frameaddress_2: |
| ; RV32I: # %bb.0: |
| ; RV32I-NEXT: addi sp, sp, -16 |
| ; RV32I-NEXT: sw ra, 12(sp) |
| ; RV32I-NEXT: sw s0, 8(sp) |
| ; RV32I-NEXT: addi s0, sp, 16 |
| ; RV32I-NEXT: lw a0, -8(s0) |
| ; RV32I-NEXT: lw a0, -8(a0) |
| ; RV32I-NEXT: lw s0, 8(sp) |
| ; RV32I-NEXT: lw ra, 12(sp) |
| ; RV32I-NEXT: addi sp, sp, 16 |
| ; RV32I-NEXT: ret |
| %1 = call i8* @llvm.frameaddress(i32 2) |
| ret i8* %1 |
| } |
| |
| define i8* @test_frameaddress_3_alloca() nounwind { |
| ; RV32I-LABEL: test_frameaddress_3_alloca: |
| ; RV32I: # %bb.0: |
| ; RV32I-NEXT: addi sp, sp, -112 |
| ; RV32I-NEXT: sw ra, 108(sp) |
| ; RV32I-NEXT: sw s0, 104(sp) |
| ; RV32I-NEXT: addi s0, sp, 112 |
| ; RV32I-NEXT: addi a0, s0, -108 |
| ; RV32I-NEXT: call notdead |
| ; RV32I-NEXT: lw a0, -8(s0) |
| ; RV32I-NEXT: lw a0, -8(a0) |
| ; RV32I-NEXT: lw a0, -8(a0) |
| ; RV32I-NEXT: lw s0, 104(sp) |
| ; RV32I-NEXT: lw ra, 108(sp) |
| ; RV32I-NEXT: addi sp, sp, 112 |
| ; RV32I-NEXT: ret |
| %1 = alloca [100 x i8] |
| %2 = bitcast [100 x i8]* %1 to i8* |
| call void @notdead(i8* %2) |
| %3 = call i8* @llvm.frameaddress(i32 3) |
| ret i8* %3 |
| } |
| |
| define i8* @test_returnaddress_0() nounwind { |
| ; RV32I-LABEL: test_returnaddress_0: |
| ; RV32I: # %bb.0: |
| ; RV32I-NEXT: mv a0, ra |
| ; RV32I-NEXT: ret |
| %1 = call i8* @llvm.returnaddress(i32 0) |
| ret i8* %1 |
| } |
| |
| define i8* @test_returnaddress_2() nounwind { |
| ; RV32I-LABEL: test_returnaddress_2: |
| ; RV32I: # %bb.0: |
| ; RV32I-NEXT: addi sp, sp, -16 |
| ; RV32I-NEXT: sw ra, 12(sp) |
| ; RV32I-NEXT: sw s0, 8(sp) |
| ; RV32I-NEXT: addi s0, sp, 16 |
| ; RV32I-NEXT: lw a0, -8(s0) |
| ; RV32I-NEXT: lw a0, -8(a0) |
| ; RV32I-NEXT: lw a0, -4(a0) |
| ; RV32I-NEXT: lw s0, 8(sp) |
| ; RV32I-NEXT: lw ra, 12(sp) |
| ; RV32I-NEXT: addi sp, sp, 16 |
| ; RV32I-NEXT: ret |
| %1 = call i8* @llvm.returnaddress(i32 2) |
| ret i8* %1 |
| } |