[llvm] [AArch64][Win] Emit SEH instructions for the swift async context-related instructions in the prologue and the epilogue. (PR #66967)
Hiroshi Yamauchi via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 21 15:53:10 PDT 2023
================
@@ -1613,11 +1628,22 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
bool HaveInitialContext = Attrs.hasAttrSomewhere(Attribute::SwiftAsync);
if (HaveInitialContext)
MBB.addLiveIn(AArch64::X22);
+ Register Reg = HaveInitialContext ? AArch64::X22 : AArch64::XZR;
BuildMI(MBB, MBBI, DL, TII->get(AArch64::StoreSwiftAsyncContext))
- .addUse(HaveInitialContext ? AArch64::X22 : AArch64::XZR)
+ .addUse(Reg)
.addUse(AArch64::SP)
.addImm(FPOffset - 8)
.setMIFlags(MachineInstr::FrameSetup);
+ if (NeedsWinCFI) {
+ // WinCFI and arm64e, where StoreSwiftAsyncContext is expanded
+ // to multiple instructions, should be mutually-exclusive.
+ assert(Subtarget.getTargetTriple().getArchName() != "arm64e");
+ BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_SaveReg))
+ .addImm(RegInfo->getSEHRegNum(Reg))
----------------
hjyamauchi wrote:
I did some experiments with several variations of the test IR input and assembly output (attached).
[ex1.ll.txt](https://github.com/llvm/llvm-project/files/12693855/ex1.ll.txt)
[ex2.ll.txt](https://github.com/llvm/llvm-project/files/12693856/ex2.ll.txt)
[ex3.ll.txt](https://github.com/llvm/llvm-project/files/12693857/ex3.ll.txt)
[ex4.ll.txt](https://github.com/llvm/llvm-project/files/12693858/ex4.ll.txt)
It seems that
- There is no corresponding restore of x22 in the current test (ex1.ll, identical to the current test in this PR.)
- If x22 is alive until the end to be passed to the tail call, it may be kept in it when it's passed to a tail call (ex2.ll)
- If a new swift async context is computed and passed to the tail call, x22 isn't restored (for the caller) even if it's overwritten in the function body (ex3.ll).
- If it is like ex2.ll but with a forced spill of x22 in the body (ex4.ll), x22 is spilled and restored in the function body, as opposed to prologue/epilogue, like a register that contains a live value.
Based on these, I think x22 is treated not like a callee saved register but more like a register that is given a live value in the prologue. So, there isn't a corresponding restore for it in the epilogue and emitEpilogue() doesn't have code for that.
To answer the questions:
- Yeah, it doesn't make sense to restore to xzr (or the opcode encoding would be invalid it sounds like)
- No, there isn't a corresponding restore of x22 because it isn't restored/saved for the caller.
Updated to use SEH_Nop instead of SEH_SaveReg.
https://github.com/llvm/llvm-project/pull/66967
More information about the llvm-commits
mailing list