Skip to content

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