summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShiva Chen <shiva@andestech.com>2020-02-14 15:57:11 +0800
committerHans Wennborg <hans@chromium.org>2020-02-20 15:13:56 +0100
commit4bcdac8d762794d822819eb6d207a0630c345d0b (patch)
tree27d585dfc3cb50e675abfcd1b5a8a208ea804c47
parentf004359106cfda578733dff1380560b68f9c3713 (diff)
downloadbcm5719-llvm-4bcdac8d762794d822819eb6d207a0630c345d0b.tar.gz
bcm5719-llvm-4bcdac8d762794d822819eb6d207a0630c345d0b.zip
[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. (cherry picked from commit 1cae2f9d192c69833e22684ca338660942ab464e)
-rw-r--r--llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp7
-rw-r--r--llvm/test/CodeGen/RISCV/interrupt-attr-callee.ll70
2 files changed, 70 insertions, 7 deletions
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
index 1d41994ef1e..207742520ed 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
@@ -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:
diff --git a/llvm/test/CodeGen/RISCV/interrupt-attr-callee.ll b/llvm/test/CodeGen/RISCV/interrupt-attr-callee.ll
new file mode 100644
index 00000000000..457b8667e10
--- /dev/null
+++ b/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)
OpenPOWER on IntegriCloud