Skip to content

Commit 82330f1

Browse files
committed
Merging r368300:
------------------------------------------------------------------------ r368300 | lenary | 2019-08-08 16:40:54 +0200 (Thu, 08 Aug 2019) | 18 lines [RISCV] Minimal stack realignment support Summary: Currently the RISC-V backend does not realign the stack. This can be an issue even for the RV32I/RV64I ABIs (where the stack is 16-byte aligned), though is rare. It will be much more comment with RV32E (though the alignment requirements for common data types remain under-documented...). This patch adds minimal support for stack realignment. It should cope with large realignments. It will error out if the stack needs realignment and variable sized objects are present. It feels like a lot of the code like getFrameIndexReference and determineFrameLayout could be refactored somehow, as right now it feels fiddly and brittle. We also seem to allocate a lot more memory than GCC does for equivalent C code. Reviewers: asb Reviewed By: asb Subscribers: wwei, jrtc27, s.egerton, MaskRay, Jim, lenary, hiraditya, rbar, johnrusso, simoncook, apazos, sabuasal, niosHD, kito-cheng, shiva0217, zzheng, edward-jones, rogfer01, MartinMosbeck, brucehoult, the_o, rkruppe, PkmX, jocewei, psnobl, benna, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D62007 ------------------------------------------------------------------------ llvm-svn: 368846
1 parent 69e3c1a commit 82330f1

File tree

3 files changed

+686
-2
lines changed

3 files changed

+686
-2
lines changed

llvm/lib/Target/RISCV/RISCVFrameLowering.cpp

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,16 @@ void RISCVFrameLowering::determineFrameLayout(MachineFunction &MF) const {
4040
uint64_t FrameSize = MFI.getStackSize();
4141

4242
// Get the alignment.
43-
uint64_t StackAlign = RI->needsStackRealignment(MF) ? MFI.getMaxAlignment()
44-
: getStackAlignment();
43+
unsigned StackAlign = getStackAlignment();
44+
if (RI->needsStackRealignment(MF)) {
45+
unsigned MaxStackAlign = std::max(StackAlign, MFI.getMaxAlignment());
46+
FrameSize += (MaxStackAlign - StackAlign);
47+
StackAlign = MaxStackAlign;
48+
}
49+
50+
// Set Max Call Frame Size
51+
uint64_t MaxCallSize = alignTo(MFI.getMaxCallFrameSize(), StackAlign);
52+
MFI.setMaxCallFrameSize(MaxCallSize);
4553

4654
// Make sure the frame is aligned.
4755
FrameSize = alignTo(FrameSize, StackAlign);
@@ -101,6 +109,12 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
101109
const RISCVInstrInfo *TII = STI.getInstrInfo();
102110
MachineBasicBlock::iterator MBBI = MBB.begin();
103111

112+
if (RI->needsStackRealignment(MF) && MFI.hasVarSizedObjects()) {
113+
report_fatal_error(
114+
"RISC-V backend can't currently handle functions that need stack "
115+
"realignment and have variable sized objects");
116+
}
117+
104118
unsigned FPReg = getFPReg(STI);
105119
unsigned SPReg = getSPReg(STI);
106120

@@ -158,6 +172,29 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
158172
nullptr, RI->getDwarfRegNum(FPReg, true), 0));
159173
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
160174
.addCFIIndex(CFIIndex);
175+
176+
// Realign Stack
177+
const RISCVRegisterInfo *RI = STI.getRegisterInfo();
178+
if (RI->needsStackRealignment(MF)) {
179+
unsigned MaxAlignment = MFI.getMaxAlignment();
180+
181+
const RISCVInstrInfo *TII = STI.getInstrInfo();
182+
if (isInt<12>(-(int)MaxAlignment)) {
183+
BuildMI(MBB, MBBI, DL, TII->get(RISCV::ANDI), SPReg)
184+
.addReg(SPReg)
185+
.addImm(-(int)MaxAlignment);
186+
} else {
187+
unsigned ShiftAmount = countTrailingZeros(MaxAlignment);
188+
unsigned VR =
189+
MF.getRegInfo().createVirtualRegister(&RISCV::GPRRegClass);
190+
BuildMI(MBB, MBBI, DL, TII->get(RISCV::SRLI), VR)
191+
.addReg(SPReg)
192+
.addImm(ShiftAmount);
193+
BuildMI(MBB, MBBI, DL, TII->get(RISCV::SLLI), SPReg)
194+
.addReg(VR)
195+
.addImm(ShiftAmount);
196+
}
197+
}
161198
}
162199
}
163200

@@ -257,6 +294,13 @@ int RISCVFrameLowering::getFrameIndexReference(const MachineFunction &MF,
257294
if (FI >= MinCSFI && FI <= MaxCSFI) {
258295
FrameReg = RISCV::X2;
259296
Offset += MF.getFrameInfo().getStackSize();
297+
} else if (RI->needsStackRealignment(MF)) {
298+
assert(!MFI.hasVarSizedObjects() &&
299+
"Unexpected combination of stack realignment and varsized objects");
300+
// If the stack was realigned, the frame pointer is set in order to allow
301+
// SP to be restored, but we still access stack objects using SP.
302+
FrameReg = RISCV::X2;
303+
Offset += MF.getFrameInfo().getStackSize();
260304
} else {
261305
FrameReg = RI->getFrameRegister(MF);
262306
if (hasFP(MF))
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
; RUN: not llc -mtriple=riscv32 < %s 2>&1 | FileCheck %s
2+
; RUN: not llc -mtriple=riscv64 < %s 2>&1 | FileCheck %s
3+
4+
; CHECK: LLVM ERROR: RISC-V backend can't currently handle functions that need stack realignment and have variable sized objects
5+
6+
declare void @callee(i8*, i32*)
7+
8+
define void @caller(i32 %n) nounwind {
9+
%1 = alloca i8, i32 %n
10+
%2 = alloca i32, align 64
11+
call void @callee(i8* %1, i32 *%2)
12+
ret void
13+
}

0 commit comments

Comments
 (0)