[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