Skip to content

Commit 8485331

Browse files
syzaarallvmbot
authored andcommitted
[PPC][AIX] Save/restore r31 when using base pointer (#100182)
When the base pointer r30 is used to hold the stack pointer, r30 is spilled in the prologue. On AIX registers are saved from highest to lowest, so r31 also needs to be saved. Fixes #96411 (cherry picked from commit d07f106)
1 parent 28f2d04 commit 8485331

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

llvm/lib/Target/PowerPC/PPCFrameLowering.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,7 +1007,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF,
10071007
// R0 cannot be used as a base register, but it can be used as an
10081008
// index in a store-indexed.
10091009
int LastOffset = 0;
1010-
if (HasFP) {
1010+
if (HasFP) {
10111011
// R0 += (FPOffset-LastOffset).
10121012
// Need addic, since addi treats R0 as 0.
10131013
BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDIC), ScratchReg)
@@ -2025,8 +2025,18 @@ void PPCFrameLowering::determineCalleeSaves(MachineFunction &MF,
20252025
// code. Same goes for the base pointer and the PIC base register.
20262026
if (needsFP(MF))
20272027
SavedRegs.reset(isPPC64 ? PPC::X31 : PPC::R31);
2028-
if (RegInfo->hasBasePointer(MF))
2028+
if (RegInfo->hasBasePointer(MF)) {
20292029
SavedRegs.reset(RegInfo->getBaseRegister(MF));
2030+
// On AIX, when BaseRegister(R30) is used, need to spill r31 too to match
2031+
// AIX trackback table requirement.
2032+
if (!needsFP(MF) && !SavedRegs.test(isPPC64 ? PPC::X31 : PPC::R31) &&
2033+
Subtarget.isAIXABI()) {
2034+
assert(
2035+
(RegInfo->getBaseRegister(MF) == (isPPC64 ? PPC::X30 : PPC::R30)) &&
2036+
"Invalid base register on AIX!");
2037+
SavedRegs.set(isPPC64 ? PPC::X31 : PPC::R31);
2038+
}
2039+
}
20302040
if (FI->usesPICBase())
20312041
SavedRegs.reset(PPC::R30);
20322042

llvm/test/CodeGen/PowerPC/aix-base-pointer.ll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
; Use an overaligned buffer to force base-pointer usage. Test verifies:
88
; - base pointer register (r30) is saved/defined/restored.
9+
; - frame pointer register (r31) is saved/defined/restored.
910
; - stack frame is allocated with correct alignment.
1011
; - Address of %AlignedBuffer is calculated based off offset from the stack
1112
; pointer.
@@ -25,7 +26,9 @@ declare void @callee(ptr)
2526
; 32BIT: subfic 0, 0, -224
2627
; 32BIT: stwux 1, 1, 0
2728
; 32BIT: addi 3, 1, 64
29+
; 32BIT: stw 31, -12(30)
2830
; 32BIT: bl .callee
31+
; 32BIT: lwz 31, -12(30)
2932
; 32BIT: mr 1, 30
3033
; 32BIT: lwz 30, -16(1)
3134

@@ -36,6 +39,8 @@ declare void @callee(ptr)
3639
; 64BIT: subfic 0, 0, -288
3740
; 64BIT: stdux 1, 1, 0
3841
; 64BIT: addi 3, 1, 128
42+
; 64BIT: std 31, -16(30)
3943
; 64BIT: bl .callee
44+
; 64BIT: ld 31, -16(30)
4045
; 64BIT: mr 1, 30
4146
; 64BIT: ld 30, -24(1)

0 commit comments

Comments
 (0)