Skip to content

[AArch64][Win] Emit SEH instructions for the swift async context-related instructions in the prologue and the epilogue. #66967

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 28, 2023

Conversation

hjyamauchi
Copy link
Contributor

This fixes an error from checkARM64Instructions() in MCWin64EH.cpp.

@llvmbot
Copy link
Member

llvmbot commented Sep 21, 2023

@llvm/pr-subscribers-platform-windows

@llvm/pr-subscribers-backend-aarch64

Changes

This fixes an error from checkARM64Instructions() in MCWin64EH.cpp.


Full diff: https://github.com/llvm/llvm-project/pull/66967.diff

2 Files Affected:

  • (modified) llvm/lib/Target/AArch64/AArch64FrameLowering.cpp (+32-1)
  • (added) llvm/test/CodeGen/AArch64/swift-async-context-seh.ll (+26)
diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index 68e68449d4073b2..a05bf976d9ebb84 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -1476,10 +1476,20 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
         BuildMI(MBB, MBBI, DL, TII->get(AArch64::LOADgot), AArch64::X16)
             .addExternalSymbol("swift_async_extendedFramePointerFlags",
                                AArch64II::MO_GOT);
+        if (NeedsWinCFI) {
+          BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
+              .setMIFlags(MachineInstr::FrameSetup);
+          HasWinCFI = true;
+        }
         BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::FP)
             .addUse(AArch64::FP)
             .addUse(AArch64::X16)
             .addImm(Subtarget.isTargetILP32() ? 32 : 0);
+        if (NeedsWinCFI) {
+          BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
+              .setMIFlags(MachineInstr::FrameSetup);
+          HasWinCFI = true;
+        }
         break;
       }
       [[fallthrough]];
@@ -1490,6 +1500,11 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
           .addUse(AArch64::FP)
           .addImm(0x1100)
           .setMIFlag(MachineInstr::FrameSetup);
+      if (NeedsWinCFI) {
+        BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
+            .setMIFlags(MachineInstr::FrameSetup);
+        HasWinCFI = true;
+      }
       break;
 
     case SwiftAsyncFramePointerMode::Never:
@@ -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))
+            .addImm(FPOffset - 8)
+            .setMIFlags(MachineInstr::FrameSetup);
+        HasWinCFI = true;
+      }
     }
 
     if (HomPrologEpilog) {
@@ -2132,6 +2158,11 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
           .addUse(AArch64::FP)
           .addImm(0x10fe)
           .setMIFlag(MachineInstr::FrameDestroy);
+      if (NeedsWinCFI) {
+        BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
+            .setMIFlags(MachineInstr::FrameDestroy);
+        HasWinCFI = true;
+      }
       break;
 
     case SwiftAsyncFramePointerMode::Never:
diff --git a/llvm/test/CodeGen/AArch64/swift-async-context-seh.ll b/llvm/test/CodeGen/AArch64/swift-async-context-seh.ll
new file mode 100644
index 000000000000000..101f6f7623d7a50
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/swift-async-context-seh.ll
@@ -0,0 +1,26 @@
+; RUN: rm -rf %t && mkdir -p %t
+; RUN: llc -mtriple aarch64-unknown-windows-msvc %s -o - | FileCheck %s
+; RUN: llc -mtriple aarch64-unknown-windows-msvc -filetype obj %s -o %t/a.o 2>&1 | FileCheck %s -check-prefix=MC --allow-empty
+
+; Check that the prologue/epilogue instructions for the swift async context
+; have an associated SEH instruction.
+
+; CHECK: orr     x29, x29, #0x1000000000000000
+; CHECK-NEXT: .seh_nop
+; CHECK:  str     x22, [sp, #16]
+; CHECK-NEXT: .seh_save_reg   x22, 16
+; CHECK: and     x29, x29, #0xefffffffffffffff
+; CHECK-NEXT: .seh_nop
+
+; MC-NOT: error: Incorrect size for test prologue: {{[0-9]+}} bytes of instructions in range, but .seh directives corresponding to {{[0-9]+}} bytes
+; MC-NOT: error: Incorrect size for test epilogue: {{[0-9]+}} bytes of instructions in range, but .seh directives corresponding to {{[0-9]+}} bytes
+
+declare ptr @llvm.swift.async.context.addr()
+
+define internal swifttailcc void @test(ptr nocapture readonly swiftasync %0) {
+entryresume.0:
+  %1 = load ptr, ptr %0, align 8
+  %2 = tail call ptr @llvm.swift.async.context.addr()
+  store ptr %1, ptr %2, align 8
+  ret void
+}
\ No newline at end of file

Copy link
Member

@compnerd compnerd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! How did we not run into this before?

@mstorsjo
Copy link
Member

Thanks! How did we not run into this before?

Possibly because the strict checker for mismatches between SEH opcodes and actual prologue/epilogue instructions was added not very long ago - sometime last fall maybe...

context-related instructions in the prologue and the epilogue.

This fixes an error from checkARM64Instructions() in MCWin64EH.cpp.
@hjyamauchi hjyamauchi force-pushed the swift-async-context-seh branch from 23e6e1f to 73213ad Compare September 21, 2023 22:51
@hjyamauchi
Copy link
Contributor Author

Thanks! How did we not run into this before?

Possibly because the strict checker for mismatches between SEH opcodes and actual prologue/epilogue instructions was added not very long ago - sometime last fall maybe...

cbd8464
This wasn't in the apple/llvm-project/stable/20221013.

@hjyamauchi
Copy link
Contributor Author

PTAL.

@hjyamauchi hjyamauchi merged commit 0ecd884 into llvm:main Sep 28, 2023
legrosbuffle pushed a commit to legrosbuffle/llvm-project that referenced this pull request Sep 29, 2023
…ted instructions in the prologue and the epilogue. (llvm#66967)

This fixes an error from checkARM64Instructions() in MCWin64EH.cpp.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants