Skip to content
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

Backport fixes for aarch64-pc-windows-msvc #45

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions llvm/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,11 @@ CV_REGISTER(AMD64_K7, 765)

#if defined(CV_REGISTERS_ALL) || defined(CV_REGISTERS_ARM64)

// arm64intr.h from MSVC defines ARM64_FPSR, which conflicts with
// these declarations.
#pragma push_macro("ARM64_FPSR")
#undef ARM64_FPSR

// ARM64 registers

CV_REGISTER(ARM64_NOREG, 0)
Expand Down Expand Up @@ -556,4 +561,6 @@ CV_REGISTER(ARM64_Q31, 211)

CV_REGISTER(ARM64_FPSR, 220)

#pragma pop_macro("ARM64_FPSR")

#endif // defined(CV_REGISTERS_ALL) || defined(CV_REGISTERS_ARM64)
100 changes: 57 additions & 43 deletions llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,24 @@ static unsigned estimateRSStackSizeLimit(MachineFunction &MF) {
return DefaultSafeSPDisplacement;
}

/// Returns the size of the fixed object area (allocated next to sp on entry)
/// On Win64 this may include a var args area and an UnwindHelp object for EH.
static unsigned getFixedObjectSize(const MachineFunction &MF,
const AArch64FunctionInfo *AFI, bool IsWin64,
bool IsFunclet) {
if (!IsWin64 || IsFunclet) {
// Only Win64 uses fixed objects, and then only for the function (not
// funclets)
return 0;
} else {
// Var args are stored here in the primary function.
const unsigned VarArgsArea = AFI->getVarArgsGPRSize();
// To support EH funclets we allocate an UnwindHelp object
const unsigned UnwindHelpObject = (MF.hasEHFunclets() ? 8 : 0);
return alignTo(VarArgsArea + UnwindHelpObject, 16);
}
}

bool AArch64FrameLowering::canUseRedZone(const MachineFunction &MF) const {
if (!EnableRedZone)
return false;
Expand Down Expand Up @@ -891,10 +909,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,

bool IsWin64 =
Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv());
// Var args are accounted for in the containing function, so don't
// include them for funclets.
unsigned FixedObject = (IsWin64 && !IsFunclet) ?
alignTo(AFI->getVarArgsGPRSize(), 16) : 0;
unsigned FixedObject = getFixedObjectSize(MF, AFI, IsWin64, IsFunclet);

auto PrologueSaveSize = AFI->getCalleeSavedStackSize() + FixedObject;
// All of the remaining stack allocations are for locals.
Expand Down Expand Up @@ -922,32 +937,8 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
++MBBI;
}

// The code below is not applicable to funclets. We have emitted all the SEH
// opcodes that we needed to emit. The FP and BP belong to the containing
// function.
if (IsFunclet) {
if (NeedsWinCFI) {
HasWinCFI = true;
BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PrologEnd))
.setMIFlag(MachineInstr::FrameSetup);
}

// SEH funclets are passed the frame pointer in X1. If the parent
// function uses the base register, then the base register is used
// directly, and is not retrieved from X1.
if (F.hasPersonalityFn()) {
EHPersonality Per = classifyEHPersonality(F.getPersonalityFn());
if (isAsynchronousEHPersonality(Per)) {
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::COPY), AArch64::FP)
.addReg(AArch64::X1).setMIFlag(MachineInstr::FrameSetup);
MBB.addLiveIn(AArch64::X1);
}
}

return;
}

if (HasFP) {
// For funclets the FP belongs to the containing function.
if (!IsFunclet && HasFP) {
// Only set up FP if we actually need to. Frame pointer is fp =
// sp - fixedobject - 16.
int FPOffset = AFI->getCalleeSavedStackSize() - 16;
Expand Down Expand Up @@ -1058,7 +1049,9 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,

// Allocate space for the rest of the frame.
if (NumBytes) {
const bool NeedsRealignment = RegInfo->needsStackRealignment(MF);
// Alignment is required for the parent frame, not the funclet
const bool NeedsRealignment =
!IsFunclet && RegInfo->needsStackRealignment(MF);
unsigned scratchSPReg = AArch64::SP;

if (NeedsRealignment) {
Expand Down Expand Up @@ -1111,7 +1104,8 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
// FIXME: Clarify FrameSetup flags here.
// Note: Use emitFrameOffset() like above for FP if the FrameSetup flag is
// needed.
if (RegInfo->hasBasePointer(MF)) {
// For funclets the BP belongs to the containing function.
if (!IsFunclet && RegInfo->hasBasePointer(MF)) {
TII->copyPhysReg(MBB, MBBI, DL, RegInfo->getBaseRegister(), AArch64::SP,
false);
if (NeedsWinCFI) {
Expand All @@ -1128,6 +1122,18 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
.setMIFlag(MachineInstr::FrameSetup);
}

// SEH funclets are passed the frame pointer in X1. If the parent
// function uses the base register, then the base register is used
// directly, and is not retrieved from X1.
if (IsFunclet && F.hasPersonalityFn()) {
EHPersonality Per = classifyEHPersonality(F.getPersonalityFn());
if (isAsynchronousEHPersonality(Per)) {
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::COPY), AArch64::FP)
.addReg(AArch64::X1).setMIFlag(MachineInstr::FrameSetup);
MBB.addLiveIn(AArch64::X1);
}
}

if (needsFrameMoves) {
const DataLayout &TD = MF.getDataLayout();
const int StackGrowth = -TD.getPointerSize(0);
Expand Down Expand Up @@ -1344,10 +1350,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,

bool IsWin64 =
Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv());
// Var args are accounted for in the containing function, so don't
// include them for funclets.
unsigned FixedObject =
(IsWin64 && !IsFunclet) ? alignTo(AFI->getVarArgsGPRSize(), 16) : 0;
unsigned FixedObject = getFixedObjectSize(MF, AFI, IsWin64, IsFunclet);

uint64_t AfterCSRPopSize = ArgumentPopSize;
auto PrologueSaveSize = AFI->getCalleeSavedStackSize() + FixedObject;
Expand Down Expand Up @@ -1517,7 +1520,8 @@ static int getFPOffset(const MachineFunction &MF, int ObjectOffset) {
const auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
bool IsWin64 =
Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv());
unsigned FixedObject = IsWin64 ? alignTo(AFI->getVarArgsGPRSize(), 16) : 0;
unsigned FixedObject =
getFixedObjectSize(MF, AFI, IsWin64, /*IsFunclet=*/false);
return ObjectOffset + FixedObject + 16;
}

Expand Down Expand Up @@ -2197,9 +2201,15 @@ void AArch64FrameLowering::processFunctionBeforeFrameFinalized(
++MBBI;

// Create an UnwindHelp object.
int UnwindHelpFI =
MFI.CreateStackObject(/*size*/8, /*alignment*/16, false);
// The UnwindHelp object is allocated at the start of the fixed object area
const AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
int64_t FixedObject =
getFixedObjectSize(MF, AFI, /*IsWin64*/ true, /*IsFunclet*/ false);
int UnwindHelpFI = MFI.CreateFixedObject(/*Size*/ 8,
/*SPOffset*/ -FixedObject,
/*IsImmutable=*/false);
EHInfo.UnwindHelpFrameIdx = UnwindHelpFI;

// We need to store -2 into the UnwindHelp object at the start of the
// function.
DebugLoc DL;
Expand All @@ -2221,10 +2231,14 @@ int AArch64FrameLowering::getFrameIndexReferencePreferSP(
const MachineFunction &MF, int FI, unsigned &FrameReg,
bool IgnoreSPUpdates) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
LLVM_DEBUG(dbgs() << "Offset from the SP for " << FI << " is "
<< MFI.getObjectOffset(FI) << "\n");
FrameReg = AArch64::SP;
return MFI.getObjectOffset(FI);
if (IgnoreSPUpdates) {
LLVM_DEBUG(dbgs() << "Offset from the SP for " << FI << " is "
<< MFI.getObjectOffset(FI) << "\n");
FrameReg = AArch64::SP;
return MFI.getObjectOffset(FI);
}

return getFrameIndexReference(MF, FI, FrameReg);
}

/// The parent frame offset (aka dispFrame) is only used on X86_64 to retrieve
Expand Down
62 changes: 62 additions & 0 deletions llvm/test/CodeGen/AArch64/funclet-match-add-sub-stack.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
; RUN: llc -o - %s -mtriple=aarch64-windows | FileCheck %s
; Check that the stack bump around a funclet is computed correctly in both the
; prologue and epilogue in the case we have a MaxCallFrameSize > 0 and are doing alloca
target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64-pc-windows-msvc19.25.28611"

; // requires passing arguments on the stack
; void test2(void*, int, int, int, int, int, int, int, int);
;
; // function with the funclet being checked
; void test1(size_t bytes)
; {
; // alloca forces a separate callee save bump and stack bump
; void *data = _alloca(bytes);
; try {
; test2(data, 0, 1, 2, 3, 4, 5, 6, 7);
; } catch (...) {
; // the funclet being checked
; }
; }

; CHECK-LABEL: ?catch$2@?0??test1@@YAX_K@Z@4HA
; CHECK: sub sp, sp, #16
; CHECK: add sp, sp, #16
; Function Attrs: uwtable
define dso_local void @"?test1@@YAX_K@Z"(i64) #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
%2 = alloca i64, align 8
%3 = alloca i8*, align 8
store i64 %0, i64* %2, align 8
%4 = load i64, i64* %2, align 8
%5 = alloca i8, i64 %4, align 16
store i8* %5, i8** %3, align 8
%6 = load i8*, i8** %3, align 8
invoke void @"?test2@@YAXPEAXHHHHHHHH@Z"(i8* %6, i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7)
to label %13 unwind label %7

7: ; preds = %1
%8 = catchswitch within none [label %9] unwind to caller

9: ; preds = %7
%10 = catchpad within %8 [i8* null, i32 64, i8* null]
catchret from %10 to label %11

11: ; preds = %9
br label %12

12: ; preds = %11, %13
ret void

13: ; preds = %1
br label %12
}

declare dso_local void @"?test2@@YAXPEAXHHHHHHHH@Z"(i8*, i32, i32, i32, i32, i32, i32, i32, i32) #1

declare dso_local i32 @__CxxFrameHandler3(...)

attributes #0 = { uwtable }

!llvm.module.flags = !{!0}

!0 = !{i32 1, !"wchar_size", i32 2}
24 changes: 12 additions & 12 deletions llvm/test/CodeGen/AArch64/seh-finally.ll
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ entry:
; CHECK-LABEL: simple_seh
; CHECK: add x29, sp, #16
; CHECK: mov x0, #-2
; CHECK: stur x0, [x29, #-16]
; CHECK: stur x0, [x29, #16]
; CHECK: .set .Lsimple_seh$frame_escape_0, -8
; CHECK: ldur w0, [x29, #-8]
; CHECK: bl foo
Expand Down Expand Up @@ -87,13 +87,13 @@ define void @stack_realign() #0 personality i8* bitcast (i32 (...)* @__C_specifi
entry:
; CHECK-LABEL: stack_realign
; CHECK: add x29, sp, #16
; CHECK: sub x9, sp, #64
; CHECK: sub x9, sp, #16
; CHECK: and sp, x9, #0xffffffffffffffe0
; CHECK: mov x19, sp
; CHECK: mov x0, #-2
; CHECK: stur x0, [x19, #16]
; CHECK: .set .Lstack_realign$frame_escape_0, 32
; CHECK: ldr w0, [x19, #32]
; CHECK: stur x0, [x29, #16]
; CHECK: .set .Lstack_realign$frame_escape_0, 0
; CHECK: ldr w0, [x19]
; CHECK: bl foo

%o = alloca %struct.S, align 32
Expand Down Expand Up @@ -142,7 +142,7 @@ entry:
; CHECK-LABEL: vla_present
; CHECK: add x29, sp, #32
; CHECK: mov x1, #-2
; CHECK: stur x1, [x29, #-32]
; CHECK: stur x1, [x29, #16]
; CHECK: .set .Lvla_present$frame_escape_0, -4
; CHECK: stur w0, [x29, #-4]
; CHECK: ldur w8, [x29, #-4]
Expand Down Expand Up @@ -206,17 +206,17 @@ define void @vla_and_realign(i32 %n) #0 personality i8* bitcast (i32 (...)* @__C
entry:
; CHECK-LABEL: vla_and_realign
; CHECK: add x29, sp, #16
; CHECK: sub x9, sp, #64
; CHECK: sub x9, sp, #48
; CHECK: and sp, x9, #0xffffffffffffffe0
; CHECK: mov x19, sp
; CHECK: mov x1, #-2
; CHECK: stur x1, [x19]
; CHECK: stur x1, [x29, #16]
; CHECK: .set .Lvla_and_realign$frame_escape_0, 32
; CHECK: stur w0, [x29, #-4]
; CHECK: ldur w8, [x29, #-4]
; CHECK: str w0, [x29, #28]
; CHECK: ldr w8, [x29, #28]
; CHECK: mov x9, sp
; CHECK: str x9, [x19, #24]
; CHECK: str x8, [x19, #16]
; CHECK: str x9, [x19, #56]
; CHECK: str x8, [x19, #24]
; CHECK: ldr w0, [x19, #32]
; CHECK: bl foo

Expand Down
7 changes: 3 additions & 4 deletions llvm/test/CodeGen/AArch64/wineh-try-catch-cbz.ll
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@
; but the original issue only reproduced if the cbz was immediately
; after the frame setup.)

; CHECK: sub sp, sp, #32
; CHECK-NEXT: stp x29, x30, [sp, #16]
; CHECK-NEXT: add x29, sp, #16
; CHECK: stp x29, x30, [sp, #-32]!
; CHECK-NEXT: mov x29, sp
; CHECK-NEXT: mov x1, #-2
; CHECK-NEXT: stur x1, [x29, #-16]
; CHECK-NEXT: stur x1, [x29, #16]
; CHECK-NEXT: cbz w0, .LBB0_2

target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128"
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/AArch64/wineh-try-catch-realign.ll
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
; CHECK: str x28, [sp, #-32]!
; CHECK-NEXT: str x19, [sp, #8]
; CHECK-NEXT: stp x29, x30, [sp, #16]
; CHECK-NEXT: add x0, x19, #64
; CHECK-NEXT: add x0, x19, #0
; CHECK-NEXT: mov w1, wzr
; CHECK-NEXT: bl "?bb@@YAXPEAHH@Z"
; CHECK-NEXT: adrp x0, .LBB0_1
Expand Down
22 changes: 11 additions & 11 deletions llvm/test/CodeGen/AArch64/wineh-try-catch.ll
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@
; and the parent function.

; The following checks that the unwind help object has -2 stored into it at
; fp - 400 - 256 = fp - 656, which is on-entry sp - 48 + 32 - 656 =
; on-entry sp - 672. We check this offset in the table later on.
; fp + 16, which is on-entry sp - 16.
; We check this offset in the table later on.

; CHECK-LABEL: "?func@@YAHXZ":
; CHECK: str x28, [sp, #-48]!
; CHECK str x28, [sp, #-64]!
; CHECK: str x21, [sp, #8]
; CHECK: stp x19, x20, [sp, #16]
; CHECK: stp x29, x30, [sp, #32]
; CHECK: add x29, sp, #32
; CHECK: sub sp, sp, #624
; CHECK: mov x19, sp
; CHECK: mov x0, #-2
; CHECK: stur x0, [x19]
; CHECK: stur x0, [x29, #16]

; Now check that x is stored at fp - 20. We check that this is the same
; location accessed from the funclet to retrieve x.
Expand Down Expand Up @@ -72,7 +72,7 @@

; Now check that the offset of the unwind help object from the stack pointer on
; entry to func is encoded in cppxdata that is passed to __CxxFrameHandler3. As
; computed above, this comes to -672.
; computed above, this comes to -16.
; CHECK-LABEL: "$cppxdata$?func@@YAHXZ":
; CHECK-NEXT: .word 429065506 ; MagicNumber
; CHECK-NEXT: .word 2 ; MaxState
Expand All @@ -81,17 +81,17 @@
; CHECK-NEXT: .word ("$tryMap$?func@@YAHXZ")@IMGREL ; TryBlockMap
; CHECK-NEXT: .word 4 ; IPMapEntries
; CHECK-NEXT: .word ("$ip2state$?func@@YAHXZ")@IMGREL ; IPToStateXData
; CHECK-NEXT: .word -672 ; UnwindHelp
; CHECK-NEXT: .word -16 ; UnwindHelp

; UNWIND: Function: ?func@@YAHXZ (0x0)
; UNWIND: Prologue [
; UNWIND-NEXT: ; nop
; UNWIND-NEXT: ; sub sp, #624
; UNWIND-NEXT: ; add fp, sp, #32
; UNWIND-NEXT: ; stp x29, x30, [sp, #32]
; UNWIND-NEXT: ; stp x19, x20, [sp, #16]
; UNWIND-NEXT: ; str x21, [sp, #8]
; UNWIND-NEXT: ; str x28, [sp, #48]!
; UNWIND-NEXT: ; mov fp, sp
; UNWIND-NEXT: ; stp x19, x20, [sp, #32]
; UNWIND-NEXT: ; str x21, [sp, #24]
; UNWIND-NEXT: ; str x28, [sp, #16]
; UNWIND-NEXT: ; stp x29, x30, [sp, #-64]!
; UNWIND-NEXT: ; end
; UNWIND: Function: ?catch$2@?0??func@@YAHXZ@4HA
; UNWIND: Prologue [
Expand Down
Loading