[PATCH] D74506: [SystemZ] Support the kernel backchain

Ulrich Weigand via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 17 07:37:48 PST 2020


uweigand added a comment.

In D74506#1877948 <https://reviews.llvm.org/D74506#1877948>, @jonpa wrote:

> It seems that compiling a vararg function with gcc -mpacked-stack and -msoft-float places the stored GPRs in the default slots.


Looks like it does, but this isn't really required.  You might as well store the GPRs right at the top of the save area.

> However, by adding also -backchain (in addition to the previous two args) the GPRs are saved right below the backchain, which is at offset 152 (topmost).  This patch does currently not move up the GPRs in the case of saving the backchain, but. I am guessing it should (in order to have "constant and known distance from the backchain to the return address")?

Yes, this is definitely required.  Otherwise backtracking using the kernel backchain will not work.

> If so, I suppose the the front-end should emit a different offset for vararg reg arguments in case of packed-stack + soft-float. Could it be the same regardless of backchain, or?

No, the offsets must remain the same, or else the ABI of the va_list type will change.   (It must be possible to create a va_list in a function that is built with -mpacked-stack, and pass that list to another function built with -mno-packed-stack to use va_arg on that va_list.)

Instead, you should store the GPRs whereever they need to be stored (at or near the top of the save area), and the compute from that the appropriate value to be stored into the reg_save_area slot in the va_list struct.   So for example, if you store r15 right at the top of the save area (sp + 152), then you should set reg_save_area to sp + 32; if you store r15 right below the back chain (sp + 144), then you should set reg_save_area to sp + 24 etc.   That way, all existing va_arg code accessing this va_list will find the saved GPRs at the right position.  (It won't find saved FPRs -- but it won't look for those if it is built with -msoft-float, and -msoft-float *is* an ABI changing option, so it's OK to require everything to be built with the same setting here.)

To implement this, you'll need to change the place in SystemZTargetLowering::LowerFormalArguments where the value to be used for reg_save_area is set:

  int64_t RegSaveOffset = -SystemZMC::CallFrameSize;
  unsigned RegSaveIndex = MFI.CreateFixedObject(1, RegSaveOffset, true);
  FuncInfo->setRegSaveFrameIndex(RegSaveIndex);

This should take into account instead the specific offset where you've decided to save GPRs to.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74506/new/

https://reviews.llvm.org/D74506





More information about the llvm-commits mailing list