[llvm] cd800f3 - [RISCV] Allow shrink wrapping for RISC-V
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 14 10:59:41 PST 2020
Author: lewis-revill
Date: 2020-01-14T18:59:11Z
New Revision: cd800f3b226b25142f233beca846715fc601809b
URL: https://github.com/llvm/llvm-project/commit/cd800f3b226b25142f233beca846715fc601809b
DIFF: https://github.com/llvm/llvm-project/commit/cd800f3b226b25142f233beca846715fc601809b.diff
LOG: [RISCV] Allow shrink wrapping for RISC-V
Enabling shrink wrapping requires ensuring the insertion point of the
epilogue is correct for MBBs without a terminator, in which case the
instruction to adjust the stack pointer is the last instruction in the
block.
Differential Revision: https://reviews.llvm.org/D62190
Added:
llvm/test/CodeGen/RISCV/shrinkwrap.ll
Modified:
llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index 61516960b393..c60fc3fc6b42 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -107,8 +107,6 @@ static Register getSPReg(const RISCVSubtarget &STI) { return RISCV::X2; }
void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
- assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
-
MachineFrameInfo &MFI = MF.getFrameInfo();
auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
const RISCVRegisterInfo *RI = STI.getRegisterInfo();
@@ -246,14 +244,28 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
- MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
const RISCVRegisterInfo *RI = STI.getRegisterInfo();
MachineFrameInfo &MFI = MF.getFrameInfo();
auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
- DebugLoc DL = MBBI->getDebugLoc();
Register FPReg = getFPReg(STI);
Register SPReg = getSPReg(STI);
+ // Get the insert location for the epilogue. If there were no terminators in
+ // the block, get the last instruction.
+ MachineBasicBlock::iterator MBBI = MBB.end();
+ DebugLoc DL;
+ if (!MBB.empty()) {
+ MBBI = MBB.getFirstTerminator();
+ if (MBBI == MBB.end())
+ MBBI = MBB.getLastNonDebugInstr();
+ DL = MBBI->getDebugLoc();
+
+ // If this is not a terminator, the actual insert location should be after the
+ // last instruction.
+ if (!MBBI->isTerminator())
+ MBBI = std::next(MBBI);
+ }
+
// Skip to before the restores of callee-saved registers
// FIXME: assumes exactly one instruction is used to restore each
// callee-saved register.
diff --git a/llvm/test/CodeGen/RISCV/shrinkwrap.ll b/llvm/test/CodeGen/RISCV/shrinkwrap.ll
new file mode 100644
index 000000000000..88ff585a7a20
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/shrinkwrap.ll
@@ -0,0 +1,97 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple riscv32 < %s | FileCheck %s -check-prefix=RV32I-NOSW
+; RUN: llc -mtriple riscv32 -enable-shrink-wrap < %s | FileCheck %s -check-prefix=RV32I-SW
+
+
+declare void @abort()
+
+define void @eliminate_restore(i32 %n) nounwind {
+; RV32I-NOSW-LABEL: eliminate_restore:
+; RV32I-NOSW: # %bb.0:
+; RV32I-NOSW-NEXT: addi sp, sp, -16
+; RV32I-NOSW-NEXT: sw ra, 12(sp)
+; RV32I-NOSW-NEXT: addi a1, zero, 32
+; RV32I-NOSW-NEXT: bgeu a1, a0, .LBB0_2
+; RV32I-NOSW-NEXT: # %bb.1: # %if.end
+; RV32I-NOSW-NEXT: lw ra, 12(sp)
+; RV32I-NOSW-NEXT: addi sp, sp, 16
+; RV32I-NOSW-NEXT: ret
+; RV32I-NOSW-NEXT: .LBB0_2: # %if.then
+; RV32I-NOSW-NEXT: call abort
+;
+; RV32I-SW-LABEL: eliminate_restore:
+; RV32I-SW: # %bb.0:
+; RV32I-SW-NEXT: addi a1, zero, 32
+; RV32I-SW-NEXT: bgeu a1, a0, .LBB0_2
+; RV32I-SW-NEXT: # %bb.1: # %if.end
+; RV32I-SW-NEXT: ret
+; RV32I-SW-NEXT: .LBB0_2: # %if.then
+; RV32I-SW-NEXT: addi sp, sp, -16
+; RV32I-SW-NEXT: sw ra, 12(sp)
+; RV32I-SW-NEXT: call abort
+ %cmp = icmp ule i32 %n, 32
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ call void @abort()
+ unreachable
+
+if.end:
+ ret void
+}
+
+declare void @notdead(i8*)
+
+define void @conditional_alloca(i32 %n) nounwind {
+; RV32I-NOSW-LABEL: conditional_alloca:
+; RV32I-NOSW: # %bb.0:
+; RV32I-NOSW-NEXT: addi sp, sp, -16
+; RV32I-NOSW-NEXT: sw ra, 12(sp)
+; RV32I-NOSW-NEXT: sw s0, 8(sp)
+; RV32I-NOSW-NEXT: addi s0, sp, 16
+; RV32I-NOSW-NEXT: addi a1, zero, 32
+; RV32I-NOSW-NEXT: bltu a1, a0, .LBB1_2
+; RV32I-NOSW-NEXT: # %bb.1: # %if.then
+; RV32I-NOSW-NEXT: addi a0, a0, 15
+; RV32I-NOSW-NEXT: andi a0, a0, -16
+; RV32I-NOSW-NEXT: sub a0, sp, a0
+; RV32I-NOSW-NEXT: mv sp, a0
+; RV32I-NOSW-NEXT: call notdead
+; RV32I-NOSW-NEXT: .LBB1_2: # %if.end
+; RV32I-NOSW-NEXT: addi sp, s0, -16
+; RV32I-NOSW-NEXT: lw s0, 8(sp)
+; RV32I-NOSW-NEXT: lw ra, 12(sp)
+; RV32I-NOSW-NEXT: addi sp, sp, 16
+; RV32I-NOSW-NEXT: ret
+;
+; RV32I-SW-LABEL: conditional_alloca:
+; RV32I-SW: # %bb.0:
+; RV32I-SW-NEXT: addi a1, zero, 32
+; RV32I-SW-NEXT: bltu a1, a0, .LBB1_2
+; RV32I-SW-NEXT: # %bb.1: # %if.then
+; RV32I-SW-NEXT: addi sp, sp, -16
+; RV32I-SW-NEXT: sw ra, 12(sp)
+; RV32I-SW-NEXT: sw s0, 8(sp)
+; RV32I-SW-NEXT: addi s0, sp, 16
+; RV32I-SW-NEXT: addi a0, a0, 15
+; RV32I-SW-NEXT: andi a0, a0, -16
+; RV32I-SW-NEXT: sub a0, sp, a0
+; RV32I-SW-NEXT: mv sp, a0
+; RV32I-SW-NEXT: call notdead
+; RV32I-SW-NEXT: addi sp, s0, -16
+; RV32I-SW-NEXT: lw s0, 8(sp)
+; RV32I-SW-NEXT: lw ra, 12(sp)
+; RV32I-SW-NEXT: addi sp, sp, 16
+; RV32I-SW-NEXT: .LBB1_2: # %if.end
+; RV32I-SW-NEXT: ret
+ %cmp = icmp ule i32 %n, 32
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ %addr = alloca i8, i32 %n
+ call void @notdead(i8* %addr)
+ br label %if.end
+
+if.end:
+ ret void
+}
More information about the llvm-commits
mailing list