From c618a466f14248f33b8e125abc7c901c1142bda6 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Fri, 28 Jul 2017 01:36:32 +0000 Subject: [PATCH] ARMFrameLowering: Only set ExtraCSSpill for actually unused registers. The code assumed that unclobbered/unspilled callee saved registers are unused in the function. This is not true for callee saved registers that are also used to pass parameters such as swiftself. rdar://33401922 llvm-svn: 309350 --- llvm/lib/Target/ARM/ARMFrameLowering.cpp | 27 +++++++++----- llvm/test/CodeGen/ARM/pei-swiftself.mir | 60 ++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 9 deletions(-) create mode 100644 llvm/test/CodeGen/ARM/pei-swiftself.mir diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp index b204faa..12e6e32 100644 --- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp +++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp @@ -1743,7 +1743,6 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF, (MFI.adjustsStack() && !canSimplifyCallFramePseudos(MF)) || // For large argument stacks fp relative addressed may overflow. (HasFP && (MaxFixedOffset - MaxFPOffset) >= (int)EstimatedRSStackSizeLimit); - bool ExtraCSSpill = false; if (BigFrameOffsets || !CanEliminateFrame || RegInfo->cannotEliminateFrame(MF)) { AFI->setHasStackFrame(true); @@ -1768,6 +1767,10 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF, CS1Spilled = true; } + // This is true when we inserted a spill for an unused register that can now + // be used for register scavenging. + bool ExtraCSSpill = false; + if (AFI->isThumb1OnlyFunction()) { // For Thumb1-only targets, we need some low registers when we save and // restore the high registers (which aren't allocatable, but could be @@ -1870,7 +1873,9 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF, SavedRegs.set(Reg); NumGPRSpills++; CS1Spilled = true; - ExtraCSSpill = true; + assert(!MRI.isReserved(Reg) && "Should not be reserved"); + if (!MRI.isPhysRegUsed(Reg)) + ExtraCSSpill = true; UnspilledCS1GPRs.erase(llvm::find(UnspilledCS1GPRs, Reg)); if (Reg == ARM::LR) LRSpilled = true; @@ -1889,7 +1894,8 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF, UnspilledCS1GPRs.erase(LRPos); ForceLRSpill = false; - ExtraCSSpill = true; + if (!MRI.isReserved(ARM::LR) && !MRI.isPhysRegUsed(ARM::LR)) + ExtraCSSpill = true; } // If stack and double are 8-byte aligned and we are spilling an odd number @@ -1909,7 +1915,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF, SavedRegs.set(Reg); DEBUG(dbgs() << "Spilling " << PrintReg(Reg, TRI) << " to make up alignment\n"); - if (!MRI.isReserved(Reg)) + if (!MRI.isReserved(Reg) && !MRI.isPhysRegUsed(Reg)) ExtraCSSpill = true; break; } @@ -1919,7 +1925,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF, SavedRegs.set(Reg); DEBUG(dbgs() << "Spilling " << PrintReg(Reg, TRI) << " to make up alignment\n"); - if (!MRI.isReserved(Reg)) + if (!MRI.isReserved(Reg) && !MRI.isPhysRegUsed(Reg)) ExtraCSSpill = true; } } @@ -1955,11 +1961,14 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF, } } } - if (Extras.size() && NumExtras == 0) { - for (unsigned i = 0, e = Extras.size(); i != e; ++i) { - SavedRegs.set(Extras[i]); + if (NumExtras == 0) { + for (unsigned Reg : Extras) { + SavedRegs.set(Reg); + if (!MRI.isPhysRegUsed(Reg)) + ExtraCSSpill = true; } - } else if (!AFI->isThumb1OnlyFunction()) { + } + if (!ExtraCSSpill && !AFI->isThumb1OnlyFunction()) { // note: Thumb1 functions spill to R12, not the stack. Reserve a slot // closest to SP or frame pointer. assert(RS && "Register scavenging not provided"); diff --git a/llvm/test/CodeGen/ARM/pei-swiftself.mir b/llvm/test/CodeGen/ARM/pei-swiftself.mir new file mode 100644 index 0000000..055efee --- /dev/null +++ b/llvm/test/CodeGen/ARM/pei-swiftself.mir @@ -0,0 +1,60 @@ +# RUN: llc -o - %s -mtriple=arm-- -run-pass prologepilog | FileCheck %s +--- | + define swiftcc i8* @need_emergency_slot(i8 *swiftself %v) { + ; Just a dummy to add a swiftself bit. The real code is in the MI below. + unreachable + } +... +--- +# CHECK-LABEL: name: need_emergency_slot +# Make sure we do not just assume an unsaved/restored callee saved register +# is free to use. Callee saved parameters may still be used if they were used +# to pass arguments (as in swiftself). +name: need_emergency_slot +tracksRegLiveness: true +stack: + - { id: 0, type: default, size: 8, alignment: 8 } + - { id: 1, type: default, size: 4096, alignment: 8 } +body: | + bb.0: + liveins: %r10 ; swiftself parameter comes in as %r10 + + ; Bring up register pressure to force emergency spilling, coax scavenging + ; to use %r10 as that one is not spilled/restored. + %r0 = IMPLICIT_DEF + %r1 = IMPLICIT_DEF + %r2 = IMPLICIT_DEF + %r3 = IMPLICIT_DEF + %r4 = IMPLICIT_DEF + %r5 = IMPLICIT_DEF + %r6 = IMPLICIT_DEF + %r7 = IMPLICIT_DEF + %r8 = IMPLICIT_DEF + %r9 = IMPLICIT_DEF + %r11 = IMPLICIT_DEF + %r12 = IMPLICIT_DEF + %lr = IMPLICIT_DEF + + ; Computing the large stack offset requires an extra register. We should + ; not just use %r10 for that. + ; CHECK-NOT: STRi12 %1,{{.*}}%r10 + + STRi12 %r1, %stack.0, 0, 14, _ :: (store 4) + + ; use the swiftself parameter value. + KILL %r10 + + KILL %r0 + KILL %r1 + KILL %r2 + KILL %r3 + KILL %r4 + KILL %r5 + KILL %r6 + KILL %r7 + KILL %r8 + KILL %r9 + KILL %r11 + KILL %r12 + KILL %lr +... -- 2.7.4