mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[ARM] Fix PR35481
This patch allows `r7` to be used, regardless of its use as a frame pointer, as a temporary register when popping `lr`, and also falls back to using a high temporary register if, for some reason, we weren't able to find a suitable low one. Differential revision: https://reviews.llvm.org/D40961 Fixes https://bugs.llvm.org/show_bug.cgi?id=35481 llvm-svn: 321989
This commit is contained in:
parent
c60fcd822b
commit
c0e2b430f9
@ -611,6 +611,12 @@ bool Thumb1FrameLowering::emitPopSpecialFixUp(MachineBasicBlock &MBB,
|
|||||||
unsigned TemporaryReg = 0;
|
unsigned TemporaryReg = 0;
|
||||||
BitVector PopFriendly =
|
BitVector PopFriendly =
|
||||||
TRI.getAllocatableSet(MF, TRI.getRegClass(ARM::tGPRRegClassID));
|
TRI.getAllocatableSet(MF, TRI.getRegClass(ARM::tGPRRegClassID));
|
||||||
|
// R7 may be used as a frame pointer, hence marked as not generally
|
||||||
|
// allocatable, however there's no reason to not use it as a temporary for
|
||||||
|
// restoring LR.
|
||||||
|
if (STI.useR7AsFramePointer())
|
||||||
|
PopFriendly.set(ARM::R7);
|
||||||
|
|
||||||
assert(PopFriendly.any() && "No allocatable pop-friendly register?!");
|
assert(PopFriendly.any() && "No allocatable pop-friendly register?!");
|
||||||
// Rebuild the GPRs from the high registers because they are removed
|
// Rebuild the GPRs from the high registers because they are removed
|
||||||
// form the GPR reg class for thumb1.
|
// form the GPR reg class for thumb1.
|
||||||
@ -622,19 +628,22 @@ bool Thumb1FrameLowering::emitPopSpecialFixUp(MachineBasicBlock &MBB,
|
|||||||
GPRsNoLRSP.reset(ARM::PC);
|
GPRsNoLRSP.reset(ARM::PC);
|
||||||
findTemporariesForLR(GPRsNoLRSP, PopFriendly, UsedRegs, PopReg, TemporaryReg);
|
findTemporariesForLR(GPRsNoLRSP, PopFriendly, UsedRegs, PopReg, TemporaryReg);
|
||||||
|
|
||||||
// If we couldn't find a pop-friendly register, restore LR before popping the
|
// If we couldn't find a pop-friendly register, try restoring LR before
|
||||||
// other callee-saved registers, so we can use one of them as a temporary.
|
// popping the other callee-saved registers, so we could use one of them as a
|
||||||
|
// temporary.
|
||||||
bool UseLDRSP = false;
|
bool UseLDRSP = false;
|
||||||
if (!PopReg && MBBI != MBB.begin()) {
|
if (!PopReg && MBBI != MBB.begin()) {
|
||||||
auto PrevMBBI = MBBI;
|
auto PrevMBBI = MBBI;
|
||||||
PrevMBBI--;
|
PrevMBBI--;
|
||||||
if (PrevMBBI->getOpcode() == ARM::tPOP) {
|
if (PrevMBBI->getOpcode() == ARM::tPOP) {
|
||||||
MBBI = PrevMBBI;
|
UsedRegs.stepBackward(*PrevMBBI);
|
||||||
UsedRegs.stepBackward(*MBBI);
|
|
||||||
findTemporariesForLR(GPRsNoLRSP, PopFriendly, UsedRegs, PopReg, TemporaryReg);
|
findTemporariesForLR(GPRsNoLRSP, PopFriendly, UsedRegs, PopReg, TemporaryReg);
|
||||||
|
if (PopReg) {
|
||||||
|
MBBI = PrevMBBI;
|
||||||
UseLDRSP = true;
|
UseLDRSP = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!DoIt && !PopReg && !TemporaryReg)
|
if (!DoIt && !PopReg && !TemporaryReg)
|
||||||
return false;
|
return false;
|
||||||
|
24
test/CodeGen/Thumb/PR35481.ll
Normal file
24
test/CodeGen/Thumb/PR35481.ll
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
; RUN: llc -mtriple thumbv4t-eabi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-V4T
|
||||||
|
; RUN: llc -mtriple armv8m.base-eabi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-V8M
|
||||||
|
|
||||||
|
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||||
|
|
||||||
|
; Function Attrs: nounwind
|
||||||
|
define <4 x i32> @f() local_unnamed_addr #0 {
|
||||||
|
entry:
|
||||||
|
%call = tail call i32 @h(i32 1)
|
||||||
|
%call1 = tail call <4 x i32> @g(i32 %call, i32 2, i32 3, i32 4)
|
||||||
|
ret <4 x i32> %call1
|
||||||
|
; CHECK: ldr r7, [sp, #4]
|
||||||
|
; CHECK-NEXT: mov lr, r7
|
||||||
|
; CHECK-NEXT: pop {r7}
|
||||||
|
; CHECK-NEXT: add sp, #4
|
||||||
|
; CHECK-V47: bx lr
|
||||||
|
; CHECK-V8M: b g
|
||||||
|
}
|
||||||
|
|
||||||
|
declare <4 x i32> @g(i32, i32, i32, i32) local_unnamed_addr
|
||||||
|
|
||||||
|
declare i32 @h(i32) local_unnamed_addr
|
||||||
|
|
||||||
|
attributes #0 = { "disable-tail-calls"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" }
|
Loading…
x
Reference in New Issue
Block a user