Register scavenger and SP/FP adjustments

Hi All,
I'm dealing with a problem where the spill/restore instructions inserted during scavenging span an adjustment of the SP/FP register. The result is that despite the base register (SP/FP) being changed between the spill and the restore, both store and load use the same immediate offset.

I see code in the PEI (replaceFrameIndices) that is supposed to track the SP/FP adjustment:

CallFrameSetupOpcode is a pseudo opcode like X86::ADJCALLSTACKDOWN64. That means when the code is expected to be called before the pseudo instructions are eliminated. I don’t know why it’s not the case for you. A quick look at PEI code indicates the pseudo’s should not have been removed at the time when replaceFrameIndices are run.


Consider this example:

--- ex.ll ---
declare void @bar()

; Function Attrs: nounwind optsize
define void @main() {
   %hin = alloca [256 x i32], align 4
   %xin = alloca [256 x i32], align 4
   call void @bar()
   ret void

The code has changed a lot over the years. Looks like at some point of time the assumption was broken. calculateCallsInformation() may have eliminated the pseudo set up instructions already.

// If call frames are not being included as part of the stack frame, and
// the target doesn’t indicate otherwise, remove the call frame pseudos
// here. The sub/add sp instruction pairs are still inserted, but we don’t
// need to track the SP adjustment for frame index elimination.
if (TFI->canSimplifyCallFramePseudos(Fn))
=> TFI->eliminateCallFramePseudoInstr(Fn, *I->getParent(), I);

Perhaps there is a bug in canSimplifyCallFramePseudos?


Thanks, I'll look into that. Still, the case where the function does not call anything remains---in such a situation there are no ADJCALLSTACK pseudos, so regardless of what that function you pointed at does, there won't be any target-independent information about the SP adjustment by the time the frame index elimination runs.

Would it make sense to have ADJCALLSTACK pseudos every time there are objects to be allocated on the stack (regardless of whether the function is a leaf or not)? What would be the implications of that?

An alternative approach would be to never use virtual registers in frame setup, but I'm not sure how popular that would be. So far I have only seen that in the Thumb backend.


Just to follow-up: this has been worked around locally. A general fix is not likely to be pursued in the near future... :frowning: