Skip to content

Commit

Permalink
[RISCV] Correct the CallPreservedMask for the function call in an int…
Browse files Browse the repository at this point in the history
…errupt 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.

(cherry picked from commit 1cae2f9)
  • Loading branch information
ShivaChen authored and zmodem committed Feb 20, 2020
1 parent f004359 commit 4bcdac8
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 7 deletions.
7 changes: 0 additions & 7 deletions llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
Expand Up @@ -156,13 +156,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:
Expand Down
70 changes: 70 additions & 0 deletions llvm/test/CodeGen/RISCV/interrupt-attr-callee.ll
@@ -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)

0 comments on commit 4bcdac8

Please sign in to comment.