Index: include/llvm/CodeGen/MachineFunction.h =================================================================== --- include/llvm/CodeGen/MachineFunction.h +++ include/llvm/CodeGen/MachineFunction.h @@ -329,6 +329,7 @@ bool CallsUnwindInit = false; bool HasEHScopes = false; bool HasEHFunclets = false; + bool HasSEHFunclets = false; /// List of C++ TypeInfo used. std::vector TypeInfos; @@ -809,6 +810,9 @@ bool hasEHFunclets() const { return HasEHFunclets; } void setHasEHFunclets(bool V) { HasEHFunclets = V; } + bool hasSEHFunclets() const { return HasSEHFunclets; } + void setHasSEHFunclets(bool V) { HasSEHFunclets = V; } + /// Find or create an LandingPadInfo for the specified MachineBasicBlock. LandingPadInfo &getOrCreateLandingPadInfo(MachineBasicBlock *LandingPad); Index: lib/CodeGen/AsmPrinter/WinException.cpp =================================================================== --- lib/CodeGen/AsmPrinter/WinException.cpp +++ lib/CodeGen/AsmPrinter/WinException.cpp @@ -545,15 +545,18 @@ OS.AddComment(Comment); }; - // Emit a label assignment with the SEH frame offset so we can use it for - // llvm.x86.seh.recoverfp. - StringRef FLinkageName = - GlobalValue::dropLLVMManglingEscape(MF->getFunction().getName()); - MCSymbol *ParentFrameOffset = - Ctx.getOrCreateParentFrameOffsetSymbol(FLinkageName); - const MCExpr *MCOffset = - MCConstantExpr::create(FuncInfo.SEHSetFrameOffset, Ctx); - Asm->OutStreamer->EmitAssignment(ParentFrameOffset, MCOffset); + if (MF->getTarget().getTargetTriple().getArch() != + Triple::ArchType::aarch64) { + // Emit a label assignment with the SEH frame offset so we can use it for + // llvm.x86.seh.recoverfp. + StringRef FLinkageName = + GlobalValue::dropLLVMManglingEscape(MF->getFunction().getName()); + MCSymbol *ParentFrameOffset = + Ctx.getOrCreateParentFrameOffsetSymbol(FLinkageName); + const MCExpr *MCOffset = + MCConstantExpr::create(FuncInfo.SEHSetFrameOffset, Ctx); + Asm->OutStreamer->EmitAssignment(ParentFrameOffset, MCOffset); + } // Use the assembler to compute the number of table entries through label // difference and division. Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -6122,6 +6122,8 @@ .addFrameIndex(FI); } + MF.setHasSEHFunclets(true); + return nullptr; } @@ -6139,11 +6141,28 @@ MF.getMMI().getContext().getOrCreateFrameAllocSymbol( GlobalValue::dropLLVMManglingEscape(Fn->getName()), IdxVal); - // Create a MCSymbol for the label to avoid any target lowering - // that would make this PC relative. - SDValue OffsetSym = DAG.getMCSymbol(FrameAllocSym, PtrVT); - SDValue OffsetVal = - DAG.getNode(ISD::LOCAL_RECOVER, sdl, PtrVT, OffsetSym); + SDValue OffsetVal; + + const auto &Triple = DAG.getTarget().getTargetTriple(); + if (Triple.getArch() == Triple::aarch64 && Triple.isOSWindows()) { + // Directly retrieve the value of the FrameAllocSym. This matches MSVC + // behavior. + assert(FrameAllocSym->isVariable() && "Invalid frame alloc symbol"); + const MCExpr *Expr = FrameAllocSym->getVariableValue(); + + assert(isa(Expr) && + "Frame alloc symbol should be a constant"); + const MCConstantExpr *C = dyn_cast(Expr); + + OffsetVal = DAG.getConstant(C->getValue(), sdl, PtrVT); + + } else { + // Create a MCSymbol for the label to avoid any target lowering + // that would make this PC relative. + SDValue OffsetSym = DAG.getMCSymbol(FrameAllocSym, PtrVT); + OffsetVal = + DAG.getNode(ISD::LOCAL_RECOVER, sdl, PtrVT, OffsetSym); + } // Add the offset to the FP. Value *FP = I.getArgOperand(1); Index: lib/Target/AArch64/AArch64FrameLowering.cpp =================================================================== --- lib/Target/AArch64/AArch64FrameLowering.cpp +++ lib/Target/AArch64/AArch64FrameLowering.cpp @@ -223,6 +223,10 @@ MFI.getMaxCallFrameSize() > DefaultSafeSPDisplacement) return true; + // Win64 SEH requires frame pointer if funclets are present. + if (MF.hasSEHFunclets()) + return true; + return false; } Index: lib/Target/AArch64/AArch64RegisterInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64RegisterInfo.cpp +++ lib/Target/AArch64/AArch64RegisterInfo.cpp @@ -457,6 +457,13 @@ // Modify MI as necessary to handle as much of 'Offset' as possible Offset = TFI->resolveFrameIndexReference(MF, FrameIndex, FrameReg); + + if (MI.getOpcode() == TargetOpcode::LOCAL_ESCAPE) { + MachineOperand &FI = MI.getOperand(FIOperandNum); + FI.ChangeToImmediate(Offset); + return; + } + if (rewriteAArch64FrameIndex(MI, FIOperandNum, FrameReg, Offset, TII)) return;