Skip to content

Commit ff9c5c3

Browse files
tonykuttaiTony Varghese
and
Tony Varghese
authored
[shrinkwrap] PowerPC's FP register should be honored when processing the save point for prologue. (#129855)
When generating code for functions that have `__builtin_frame_address` calls and `noinline` attribute, prologue was not emitted correctly leading to an assertion failure in PowerPC. The issue was due to improper insertion of prologue for a function that contain llvm `__builtin_frame_address`. Shrink-wrap pass computes the save and restore points of a function. Default points are the entry and exit points of the function. During shrink-wrapping the frame-pointer was not honored like the stack pointer and it was considered as a callee-saved register. This change will treat the FP similar to SP and will insert the prolog on top the instruction containing FP. --------- Co-authored-by: Tony Varghese <[email protected]>
1 parent 72d1058 commit ff9c5c3

File tree

4 files changed

+39
-13
lines changed

4 files changed

+39
-13
lines changed

llvm/include/llvm/CodeGen/TargetRegisterInfo.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,6 +1246,11 @@ class TargetRegisterInfo : public MCRegisterInfo {
12461246
return false;
12471247
}
12481248

1249+
/// Some targets delay assigning the frame until late and use a placeholder
1250+
/// to represent it earlier. This method can be used to identify the frame
1251+
/// register placeholder.
1252+
virtual bool isVirtualFrameRegister(MCRegister Reg) const { return false; }
1253+
12491254
virtual std::optional<uint8_t> getVRegFlagValue(StringRef Name) const {
12501255
return {};
12511256
}

llvm/lib/CodeGen/ShrinkWrap.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -348,10 +348,14 @@ bool ShrinkWrap::useOrDefCSROrFI(const MachineInstr &MI, RegScavenger *RS,
348348
// calling convention definitions, so we need to watch for it, too. An LR
349349
// mentioned implicitly by a return (or "branch to link register")
350350
// instruction we can ignore, otherwise we may pessimize shrinkwrapping.
351-
UseOrDefCSR =
352-
(!MI.isCall() && PhysReg == SP) ||
353-
RCI.getLastCalleeSavedAlias(PhysReg) ||
354-
(!MI.isReturn() && TRI->isNonallocatableRegisterCalleeSave(PhysReg));
351+
// PPC's Frame pointer (FP) is also not described as a callee-saved
352+
// register. Until the FP is assigned a Physical Register PPC's FP needs
353+
// to be checked separately.
354+
UseOrDefCSR = (!MI.isCall() && PhysReg == SP) ||
355+
RCI.getLastCalleeSavedAlias(PhysReg) ||
356+
(!MI.isReturn() &&
357+
TRI->isNonallocatableRegisterCalleeSave(PhysReg)) ||
358+
TRI->isVirtualFrameRegister(PhysReg);
355359
} else if (MO.isRegMask()) {
356360
// Check if this regmask clobbers any of the CSRs.
357361
for (unsigned Reg : getCurrentCSRs(RS)) {

llvm/lib/Target/PowerPC/PPCRegisterInfo.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ class PPCRegisterInfo : public PPCGenRegisterInfo {
176176
bool isNonallocatableRegisterCalleeSave(MCRegister Reg) const override {
177177
return Reg == PPC::LR || Reg == PPC::LR8;
178178
}
179+
180+
bool isVirtualFrameRegister(MCRegister Reg) const override {
181+
return Reg == PPC::FP || Reg == PPC::FP8;
182+
}
179183
};
180184

181185
} // end namespace llvm

llvm/test/CodeGen/PowerPC/shrink-wrap-frame-pointer.ll

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,37 @@
77
define void @foo(ptr noundef readnone %parent_frame_pointer) {
88
; POWERPC64-LABEL: foo
99
; POWERPC64: # %bb.0:
10-
; POWERPC64-NEXT: cmpld [[REG1:[0-9]+]], 1
11-
; POWERPC64: # %bb.1:
12-
; POWERPC64-NEXT: mflr [[REG2:[0-9]+]]
10+
; POWERPC64: mflr [[REG1:[0-9]+]]
1311
; POWERPC64-NEXT: stdu 1, -32(1)
12+
; POWERPC64-NEXT: std [[REG1]], 48(1)
13+
; POWERPC64: cmpld [[REG2:[0-9]+]], 1
14+
; POWERPC64: # %bb.1:
15+
; POWERPC64-NEXT: addi 1, 1, 32
16+
; POWERPC64-NEXT: ld [[REG1]], 16(1)
17+
; POWERPC64-NEXT: mtlr [[REG1]]
18+
; POWERPC64-NEXT: blr
1419

1520
; POWERPC32-AIX-LABEL: .foo:
1621
; POWERPC32-AIX: # %bb.0:
17-
; POWERPC32-AIX-NEXT: cmplw [[REG1:[0-9]+]], 1
18-
; POWERPC32-AIX: # %bb.1:
19-
; POWERPC32-AIX-NEXT: mflr [[REG2:[0-9]+]]
22+
; POWERPC32-AIX-NEXT: mflr [[REG1:[0-9]+]]
2023
; POWERPC32-AIX-NEXT: stwu 1, -64(1)
24+
; POWERPC32-AIX-NEXT: cmplw [[REG2:[0-9]+]], 1
25+
; POWERPC32-AIX: # %bb.1:
26+
; POWERPC32-AIX-NEXT: addi 1, 1, 64
27+
; POWERPC32-AIX-NEXT: lwz [[REG1]], 8(1)
28+
; POWERPC32-AIX-NEXT: mtlr [[REG1]]
29+
; POWERPC32-AIX-NEXT: blr
2130

2231
; POWERPC64-AIX-LABEL: .foo:
2332
; POWERPC64-AIX: # %bb.0:
24-
; POWERPC64-AIX-NEXT: cmpld [[REG1:[0-9]+]], 1
25-
; POWERPC64-AIX: # %bb.1:
26-
; POWERPC64-AIX-NEXT: mflr [[REG2:[0-9]+]]
33+
; POWERPC64-AIX-NEXT: mflr [[REG1:[0-9]+]]
2734
; POWERPC64-AIX-NEXT: stdu 1, -112(1)
35+
; POWERPC64-AIX-NEXT: cmpld [[REG2:[0-9]+]], 1
36+
; POWERPC64-AIX: # %bb.1:
37+
; POWERPC64-AIX-NEXT: addi 1, 1, 112
38+
; POWERPC64-AIX-NEXT: ld [[REG1]], 16(1)
39+
; POWERPC64-AIX-NEXT: mtlr [[REG1]]
40+
; POWERPC64-AIX-NEXT: blr
2841

2942
entry:
3043
%frameaddress = tail call ptr @llvm.frameaddress.p0(i32 0)

0 commit comments

Comments
 (0)