Index: include/llvm/Target/TargetRegisterInfo.h =================================================================== --- include/llvm/Target/TargetRegisterInfo.h +++ include/llvm/Target/TargetRegisterInfo.h @@ -813,6 +813,13 @@ return false; } + /// Returns true if the target requires using the RegScavenger directly for + /// frame elimination despite using requiresFrameIndexScavenging. + virtual bool requiresFrameIndexReplacementScavenging( + const MachineFunction &MF) const { + return false; + } + /// Returns true if the target wants the LocalStackAllocation pass to be run /// and virtual base registers used for more efficient stack access. virtual bool requiresVirtualBaseRegisters(const MachineFunction &MF) const { Index: lib/CodeGen/PrologEpilogInserter.cpp =================================================================== --- lib/CodeGen/PrologEpilogInserter.cpp +++ lib/CodeGen/PrologEpilogInserter.cpp @@ -117,6 +117,10 @@ // TRI->requiresFrameIndexScavenging() for the current function. bool FrameIndexVirtualScavenging; + // Flag to control whether the scavenger should be passed even though + // FrameIndexVirtualScavenging is used. + bool FrameIndexEliminationScavenging; + void calculateCallFrameInfo(MachineFunction &Fn); void calculateSaveRestoreBlocks(MachineFunction &Fn); @@ -176,6 +180,8 @@ RS = TRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : nullptr; FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(Fn); + FrameIndexEliminationScavenging + = TRI->requiresFrameIndexReplacementScavenging(Fn); // Calculate the MaxCallFrameSize and AdjustsStack variables for the // function's frame information. Also eliminates call frame pseudo @@ -1046,7 +1052,8 @@ unsigned FrameSetupOpcode = TII.getCallFrameSetupOpcode(); unsigned FrameDestroyOpcode = TII.getCallFrameDestroyOpcode(); - if (RS && !FrameIndexVirtualScavenging) RS->enterBasicBlock(*BB); + if (RS && FrameIndexEliminationScavenging) + RS->enterBasicBlock(*BB); bool InsideCallSequence = false; @@ -1115,7 +1122,7 @@ // use that target machine register info object to eliminate // it. TRI.eliminateFrameIndex(MI, SPAdj, i, - FrameIndexVirtualScavenging ? nullptr : RS); + FrameIndexEliminationScavenging ? RS : nullptr); // Reset the iterator if we were at the beginning of the BB. if (AtBeginning) { @@ -1131,7 +1138,7 @@ // the SP adjustment made by each instruction in the sequence. // This includes both the frame setup/destroy pseudos (handled above), // as well as other instructions that have side effects w.r.t the SP. - // Note that this must come after eliminateFrameIndex, because + // Note that this must come after eliminateFrameIndex, because // if I itself referred to a frame index, we shouldn't count its own // adjustment. if (DidFinishLoop && InsideCallSequence) @@ -1140,7 +1147,7 @@ if (DoIncr && I != BB->end()) ++I; // Update register states. - if (RS && !FrameIndexVirtualScavenging && DidFinishLoop) + if (RS && FrameIndexEliminationScavenging && DidFinishLoop) RS->forward(MI); } } Index: lib/Target/AMDGPU/SIRegisterInfo.h =================================================================== --- lib/Target/AMDGPU/SIRegisterInfo.h +++ lib/Target/AMDGPU/SIRegisterInfo.h @@ -50,8 +50,9 @@ bool requiresRegisterScavenging(const MachineFunction &Fn) const override; - bool requiresFrameIndexScavenging(const MachineFunction &MF) const override; + bool requiresFrameIndexReplacementScavenging( + const MachineFunction &MF) const override; bool requiresVirtualBaseRegisters(const MachineFunction &Fn) const override; bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const override; Index: lib/Target/AMDGPU/SIRegisterInfo.cpp =================================================================== --- lib/Target/AMDGPU/SIRegisterInfo.cpp +++ lib/Target/AMDGPU/SIRegisterInfo.cpp @@ -182,6 +182,16 @@ return MF.getFrameInfo().hasStackObjects(); } +bool SIRegisterInfo::requiresFrameIndexReplacementScavenging( + const MachineFunction &MF) const { + // m0 is needed for the scalar store offset. m0 is unallocatable, so we can't + // create a virtual register for it during frame index elimination, so the + // scavenger is directly needed. + return MF.getFrameInfo().hasStackObjects() && + MF.getSubtarget().hasScalarStores() && + MF.getInfo()->hasSpilledSGPRs(); +} + bool SIRegisterInfo::requiresVirtualBaseRegisters( const MachineFunction &) const { // There are no special dedicated stack or frame pointers.