1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 10:32:48 +02:00

[RISCV] Correct the CallPreservedMask for the function call in an interrupt handler

CallPreservedMask is used to describe the register liveness after a
function call. The function call in an interrupt handler should use the same
CallPreservedMask as normal functions. So that only callee save registers
can live through the function call.
This commit is contained in:
Shiva Chen 2020-02-14 15:57:11 +08:00 committed by Shiva Chen
parent 07870c8135
commit 0188dcd0c7
2 changed files with 70 additions and 7 deletions

View File

@ -190,13 +190,6 @@ const uint32_t *
RISCVRegisterInfo::getCallPreservedMask(const MachineFunction & MF,
CallingConv::ID /*CC*/) const {
auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();
if (MF.getFunction().hasFnAttribute("interrupt")) {
if (Subtarget.hasStdExtD())
return CSR_XLEN_F64_Interrupt_RegMask;
if (Subtarget.hasStdExtF())
return CSR_XLEN_F32_Interrupt_RegMask;
return CSR_Interrupt_RegMask;
}
switch (Subtarget.getTargetABI()) {
default:

View File

@ -0,0 +1,70 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple riscv32-unknown-elf -o - %s \
; RUN: 2>&1 | FileCheck %s -check-prefix CHECK-RV32
; RUN: llc -mtriple riscv32-unknown-elf -mattr=+f -o - %s \
; RUN: 2>&1 | FileCheck %s -check-prefix CHECK-RV32-F
; RUN: llc -mtriple riscv32-unknown-elf -mattr=+f,+d -o - %s \
; RUN: 2>&1 | FileCheck %s -check-prefix CHECK-RV32-FD
;
; The test case check that the function call in an interrupt handler will use
; the correct CallPreservedMask as normal function. So only callee saved
; registers could live through the function call.
define dso_local void @handler() nounwind {
; CHECK-RV32-LABEL: handler:
; CHECK-RV32: # %bb.0: # %entry
; CHECK-RV32-NEXT: addi sp, sp, -16
; CHECK-RV32-NEXT: sw ra, 12(sp)
; CHECK-RV32-NEXT: sw s0, 8(sp)
; CHECK-RV32-NEXT: lui a0, 2
; CHECK-RV32-NEXT: addi a0, a0, 4
; CHECK-RV32-NEXT: call read
; CHECK-RV32-NEXT: mv s0, a0
; CHECK-RV32-NEXT: call callee
; CHECK-RV32-NEXT: mv a0, s0
; CHECK-RV32-NEXT: lw s0, 8(sp)
; CHECK-RV32-NEXT: lw ra, 12(sp)
; CHECK-RV32-NEXT: addi sp, sp, 16
; CHECK-RV32-NEXT: tail write
;
; CHECK-RV32-F-LABEL: handler:
; CHECK-RV32-F: # %bb.0: # %entry
; CHECK-RV32-F-NEXT: addi sp, sp, -16
; CHECK-RV32-F-NEXT: sw ra, 12(sp)
; CHECK-RV32-F-NEXT: sw s0, 8(sp)
; CHECK-RV32-F-NEXT: lui a0, 2
; CHECK-RV32-F-NEXT: addi a0, a0, 4
; CHECK-RV32-F-NEXT: call read
; CHECK-RV32-F-NEXT: mv s0, a0
; CHECK-RV32-F-NEXT: call callee
; CHECK-RV32-F-NEXT: mv a0, s0
; CHECK-RV32-F-NEXT: lw s0, 8(sp)
; CHECK-RV32-F-NEXT: lw ra, 12(sp)
; CHECK-RV32-F-NEXT: addi sp, sp, 16
; CHECK-RV32-F-NEXT: tail write
;
; CHECK-RV32-FD-LABEL: handler:
; CHECK-RV32-FD: # %bb.0: # %entry
; CHECK-RV32-FD-NEXT: addi sp, sp, -16
; CHECK-RV32-FD-NEXT: sw ra, 12(sp)
; CHECK-RV32-FD-NEXT: sw s0, 8(sp)
; CHECK-RV32-FD-NEXT: lui a0, 2
; CHECK-RV32-FD-NEXT: addi a0, a0, 4
; CHECK-RV32-FD-NEXT: call read
; CHECK-RV32-FD-NEXT: mv s0, a0
; CHECK-RV32-FD-NEXT: call callee
; CHECK-RV32-FD-NEXT: mv a0, s0
; CHECK-RV32-FD-NEXT: lw s0, 8(sp)
; CHECK-RV32-FD-NEXT: lw ra, 12(sp)
; CHECK-RV32-FD-NEXT: addi sp, sp, 16
; CHECK-RV32-FD-NEXT: tail write
entry:
%call = tail call i32 @read(i32 8196)
tail call void bitcast (void (...)* @callee to void ()*)()
tail call void @write(i32 %call)
ret void
}
declare i32 @read(i32)
declare void @callee(...)
declare void @write(i32)