[llvm] r322216 - [RISCV] Support stack frames and offsets up to 32-bits

Alex Bradbury via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 10 11:53:46 PST 2018


Author: asb
Date: Wed Jan 10 11:53:46 2018
New Revision: 322216

URL: http://llvm.org/viewvc/llvm-project?rev=322216&view=rev
Log:
[RISCV] Support stack frames and offsets up to 32-bits

Differential Revision: https://reviews.llvm.org/D40807

Added:
    llvm/trunk/test/CodeGen/RISCV/large-stack.ll
Modified:
    llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.cpp
    llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.cpp
    llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.h
    llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.cpp
    llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.h

Modified: llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.cpp?rev=322216&r1=322215&r2=322216&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.cpp Wed Jan 10 11:53:46 2018
@@ -62,18 +62,34 @@ void RISCVFrameLowering::adjustReg(Machi
                                    const DebugLoc &DL, unsigned DestReg,
                                    unsigned SrcReg, int64_t Val,
                                    MachineInstr::MIFlag Flag) const {
+  MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
   const RISCVInstrInfo *TII = STI.getInstrInfo();
 
   if (DestReg == SrcReg && Val == 0)
     return;
 
-  if (!isInt<12>(Val))
-    report_fatal_error("adjustReg cannot yet handle adjustments >12 bits");
+  if (isInt<12>(Val)) {
+    BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI), DestReg)
+        .addReg(SrcReg)
+        .addImm(Val)
+        .setMIFlag(Flag);
+  } else if (isInt<32>(Val)) {
+    unsigned Opc = RISCV::ADD;
+    bool isSub = Val < 0;
+    if (isSub) {
+      Val = -Val;
+      Opc = RISCV::SUB;
+    }
 
-  BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI), DestReg)
-      .addReg(SrcReg)
-      .addImm(Val)
-      .setMIFlag(Flag);
+    unsigned ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
+    TII->movImm32(MBB, MBBI, DL, ScratchReg, Val, Flag);
+    BuildMI(MBB, MBBI, DL, TII->get(Opc), DestReg)
+        .addReg(SrcReg)
+        .addReg(ScratchReg, RegState::Kill)
+        .setMIFlag(Flag);
+  } else {
+    report_fatal_error("adjustReg cannot yet handle adjustments >32 bits");
+  }
 }
 
 // Returns the register used to hold the frame pointer.

Modified: llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.cpp?rev=322216&r1=322215&r2=322216&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.cpp Wed Jan 10 11:53:46 2018
@@ -75,3 +75,23 @@ void RISCVInstrInfo::loadRegFromStackSlo
   else
     llvm_unreachable("Can't load this register from stack slot");
 }
+
+void RISCVInstrInfo::movImm32(MachineBasicBlock &MBB,
+                              MachineBasicBlock::iterator MBBI,
+                              const DebugLoc &DL, unsigned DstReg, uint64_t Val,
+                              MachineInstr::MIFlag Flag) const {
+  assert(isInt<32>(Val) && "Can only materialize 32-bit constants");
+
+  // TODO: If the value can be materialized using only one instruction, only
+  // insert a single instruction.
+
+  uint64_t Hi20 = ((Val + 0x800) >> 12) & 0xfffff;
+  uint64_t Lo12 = SignExtend64<12>(Val);
+  BuildMI(MBB, MBBI, DL, get(RISCV::LUI), DstReg)
+      .addImm(Hi20)
+      .setMIFlag(Flag);
+  BuildMI(MBB, MBBI, DL, get(RISCV::ADDI), DstReg)
+      .addReg(DstReg, RegState::Kill)
+      .addImm(Lo12)
+      .setMIFlag(Flag);
+}

Modified: llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.h?rev=322216&r1=322215&r2=322216&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.h (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.h Wed Jan 10 11:53:46 2018
@@ -41,6 +41,11 @@ public:
                             MachineBasicBlock::iterator MBBI, unsigned DstReg,
                             int FrameIndex, const TargetRegisterClass *RC,
                             const TargetRegisterInfo *TRI) const override;
+
+  // Materializes the given int32 Val into DstReg.
+  void movImm32(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
+                const DebugLoc &DL, unsigned DstReg, uint64_t Val,
+                MachineInstr::MIFlag Flag = MachineInstr::NoFlags) const;
 };
 }
 #endif

Modified: llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.cpp?rev=322216&r1=322215&r2=322216&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.cpp Wed Jan 10 11:53:46 2018
@@ -61,6 +61,8 @@ void RISCVRegisterInfo::eliminateFrameIn
 
   MachineInstr &MI = *II;
   MachineFunction &MF = *MI.getParent()->getParent();
+  MachineRegisterInfo &MRI = MF.getRegInfo();
+  const RISCVInstrInfo *TII = MF.getSubtarget<RISCVSubtarget>().getInstrInfo();
   DebugLoc DL = MI.getDebugLoc();
 
   int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
@@ -72,13 +74,30 @@ void RISCVRegisterInfo::eliminateFrameIn
   assert(MF.getSubtarget().getFrameLowering()->hasFP(MF) &&
          "eliminateFrameIndex currently requires hasFP");
 
-  // Offsets must be directly encoded in a 12-bit immediate field
-  if (!isInt<12>(Offset)) {
+  if (!isInt<32>(Offset)) {
     report_fatal_error(
-        "Frame offsets outside of the signed 12-bit range not supported");
+        "Frame offsets outside of the signed 32-bit range not supported");
+  }
+
+  MachineBasicBlock &MBB = *MI.getParent();
+  bool FrameRegIsKill = false;
+
+  if (!isInt<12>(Offset)) {
+    assert(isInt<32>(Offset) && "Int32 expected");
+    // The offset won't fit in an immediate, so use a scratch register instead
+    // Modify Offset and FrameReg appropriately
+    unsigned ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
+    TII->movImm32(MBB, II, DL, ScratchReg, Offset);
+    BuildMI(MBB, II, DL, TII->get(RISCV::ADD), ScratchReg)
+        .addReg(FrameReg)
+        .addReg(ScratchReg, RegState::Kill);
+    Offset = 0;
+    FrameReg = ScratchReg;
+    FrameRegIsKill = true;
   }
 
-  MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false);
+  MI.getOperand(FIOperandNum)
+      .ChangeToRegister(FrameReg, false, false, FrameRegIsKill);
   MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
 }
 

Modified: llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.h?rev=322216&r1=322215&r2=322216&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.h (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.h Wed Jan 10 11:53:46 2018
@@ -39,6 +39,14 @@ struct RISCVRegisterInfo : public RISCVG
                            RegScavenger *RS = nullptr) const override;
 
   unsigned getFrameRegister(const MachineFunction &MF) const override;
+
+  bool requiresRegisterScavenging(const MachineFunction &MF) const override {
+    return true;
+  }
+
+  bool requiresFrameIndexScavenging(const MachineFunction &MF) const override {
+    return true;
+  }
 };
 }
 

Added: llvm/trunk/test/CodeGen/RISCV/large-stack.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/large-stack.ll?rev=322216&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/large-stack.ll (added)
+++ llvm/trunk/test/CodeGen/RISCV/large-stack.ll Wed Jan 10 11:53:46 2018
@@ -0,0 +1,38 @@
+; 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
+
+; TODO: the quality of the generated code is poor
+
+define void @test() nounwind {
+; RV32I-LABEL: test:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    lui a0, 74565
+; RV32I-NEXT:    addi a0, a0, 1664
+; RV32I-NEXT:    sub sp, sp, a0
+; RV32I-NEXT:    lui a0, 74565
+; RV32I-NEXT:    addi a0, a0, 1660
+; RV32I-NEXT:    add a0, sp, a0
+; RV32I-NEXT:    sw ra, 0(a0)
+; RV32I-NEXT:    lui a0, 74565
+; RV32I-NEXT:    addi a0, a0, 1656
+; RV32I-NEXT:    add a0, sp, a0
+; RV32I-NEXT:    sw s0, 0(a0)
+; RV32I-NEXT:    lui a0, 74565
+; RV32I-NEXT:    addi a0, a0, 1664
+; RV32I-NEXT:    add s0, sp, a0
+; RV32I-NEXT:    lui a0, 74565
+; RV32I-NEXT:    addi a0, a0, 1656
+; RV32I-NEXT:    add a0, sp, a0
+; RV32I-NEXT:    lw s0, 0(a0)
+; RV32I-NEXT:    lui a0, 74565
+; RV32I-NEXT:    addi a0, a0, 1660
+; RV32I-NEXT:    add a0, sp, a0
+; RV32I-NEXT:    lw ra, 0(a0)
+; RV32I-NEXT:    lui a0, 74565
+; RV32I-NEXT:    addi a0, a0, 1664
+; RV32I-NEXT:    add sp, sp, a0
+; RV32I-NEXT:    ret
+  %tmp = alloca [ 305419896 x i8 ] , align 4
+  ret void
+}




More information about the llvm-commits mailing list