From 4a1574f0a631cb3a2763102e22cd3e7bd59901ea Mon Sep 17 00:00:00 2001 From: Hiroshi Yamauchi Date: Tue, 29 Oct 2024 11:55:24 -0700 Subject: [PATCH 1/2] [AArch64][Win] Emit SEH instructions for the swift async context-related instructions in the prologue and the epilogue. This fixes an error from checkARM64Instructions() in MCWin64EH.cpp. Cherrypick from commit llvm@0ecd884 Cherrypick PR https://github.com/swiftlang/llvm-project/pull/7533 --- .../Target/AArch64/AArch64FrameLowering.cpp | 31 ++++++++++++++++++- .../AArch64/swift-async-context-seh.ll | 24 ++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/AArch64/swift-async-context-seh.ll diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp index d5ebd36062d42..49d6c68a91c2c 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -1477,10 +1477,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]]; @@ -1491,6 +1501,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: @@ -1621,11 +1636,20 @@ 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_Nop)) + .setMIFlags(MachineInstr::FrameSetup); + HasWinCFI = true; + } } // Issue sub fp, sp, FPOffset or @@ -2123,6 +2147,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 0000000000000..852c97743a10c --- /dev/null +++ b/llvm/test/CodeGen/AArch64/swift-async-context-seh.ll @@ -0,0 +1,24 @@ +; 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 + +; Check that the prologue/epilogue instructions for the swift async +; context have an associated SEH instruction and that it doesn't error +; when the output is an object file. + +; CHECK: orr x29, x29, #0x1000000000000000 +; CHECK-NEXT: .seh_nop +; CHECK: str x22, [sp, #16] +; CHECK-NEXT: .seh_nop +; CHECK: and x29, x29, #0xefffffffffffffff +; CHECK-NEXT: .seh_nop + +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 +} From e2e0940e79584a4384a64029fa8bb1836512a874 Mon Sep 17 00:00:00 2001 From: Hiroshi Yamauchi Date: Tue, 29 Oct 2024 11:56:18 -0700 Subject: [PATCH 2/2] Add arrangeCXXMethodCall to the CodeGenABITypes interface. Also add ExtParameterInfos to the argument list of arrangeFreeFunctionCall. Cherrypick PR https://github.com/llvm/llvm-project/pull/111597 --- clang/include/clang/CodeGen/CodeGenABITypes.h | 24 +++++++++++++++---- clang/lib/CodeGen/CodeGenABITypes.cpp | 23 ++++++++++++------ 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/clang/include/clang/CodeGen/CodeGenABITypes.h b/clang/include/clang/CodeGen/CodeGenABITypes.h index 0ba6c20192856..fda2f4caedec3 100644 --- a/clang/include/clang/CodeGen/CodeGenABITypes.h +++ b/clang/include/clang/CodeGen/CodeGenABITypes.h @@ -75,11 +75,25 @@ const CGFunctionInfo &arrangeCXXMethodType(CodeGenModule &CGM, const FunctionProtoType *FTP, const CXXMethodDecl *MD); -const CGFunctionInfo &arrangeFreeFunctionCall(CodeGenModule &CGM, - CanQualType returnType, - ArrayRef argTypes, - FunctionType::ExtInfo info, - RequiredArgs args); +const CGFunctionInfo & +arrangeCXXMethodCall(CodeGenModule &CGM, CanQualType returnType, + ArrayRef argTypes, FunctionType::ExtInfo info, + ArrayRef paramInfos, + RequiredArgs args); + +const CGFunctionInfo &arrangeFreeFunctionCall( + CodeGenModule &CGM, CanQualType returnType, ArrayRef argTypes, + FunctionType::ExtInfo info, + ArrayRef paramInfos, + RequiredArgs args); + +// An overload with an empty `paramInfos` +inline const CGFunctionInfo & +arrangeFreeFunctionCall(CodeGenModule &CGM, CanQualType returnType, + ArrayRef argTypes, + FunctionType::ExtInfo info, RequiredArgs args) { + return arrangeFreeFunctionCall(CGM, returnType, argTypes, info, {}, args); +} /// Returns the implicit arguments to add to a complete, non-delegating C++ /// constructor call. diff --git a/clang/lib/CodeGen/CodeGenABITypes.cpp b/clang/lib/CodeGen/CodeGenABITypes.cpp index d3a16a1d5accf..90c5eee12d9c8 100644 --- a/clang/lib/CodeGen/CodeGenABITypes.cpp +++ b/clang/lib/CodeGen/CodeGenABITypes.cpp @@ -59,15 +59,24 @@ CodeGen::arrangeCXXMethodType(CodeGenModule &CGM, return CGM.getTypes().arrangeCXXMethodType(RD, FTP, MD); } -const CGFunctionInfo & -CodeGen::arrangeFreeFunctionCall(CodeGenModule &CGM, - CanQualType returnType, - ArrayRef argTypes, - FunctionType::ExtInfo info, - RequiredArgs args) { +const CGFunctionInfo &CodeGen::arrangeCXXMethodCall( + CodeGenModule &CGM, CanQualType returnType, ArrayRef argTypes, + FunctionType::ExtInfo info, + ArrayRef paramInfos, + RequiredArgs args) { + return CGM.getTypes().arrangeLLVMFunctionInfo( + returnType, /*instanceMethod=*/true, /*chainCall=*/false, argTypes, info, + paramInfos, args); +} + +const CGFunctionInfo &CodeGen::arrangeFreeFunctionCall( + CodeGenModule &CGM, CanQualType returnType, ArrayRef argTypes, + FunctionType::ExtInfo info, + ArrayRef paramInfos, + RequiredArgs args) { return CGM.getTypes().arrangeLLVMFunctionInfo( returnType, /*instanceMethod=*/false, /*chainCall=*/false, argTypes, - info, {}, args); + info, paramInfos, args); } ImplicitCXXConstructorArgs