diff options
-rw-r--r-- | llvm/lib/Target/X86/X86FrameLowering.cpp | 12 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/win-cleanuppad.ll | 30 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/wineh-no-ehpads.ll | 20 |
3 files changed, 56 insertions, 6 deletions
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp index 3c557fe8a11..72baa078661 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -2662,17 +2662,17 @@ void X86FrameLowering::processFunctionBeforeFrameFinalized( // If this function isn't doing Win64-style C++ EH, we don't need to do // anything. const Function *Fn = MF.getFunction(); - if (!STI.is64Bit() || !Fn->hasPersonalityFn() || - classifyEHPersonality(MF.getFunction()->getPersonalityFn()) != - EHPersonality::MSVC_CXX) + if (!STI.is64Bit() || !MF.getMMI().hasEHFunclets() || + classifyEHPersonality(Fn->getPersonalityFn()) != EHPersonality::MSVC_CXX) return; // Win64 C++ EH needs to allocate the UnwindHelp object at some fixed offset // relative to RSP after the prologue. Find the offset of the last fixed - // object, so that we can allocate a slot immediately following it. Fixed - // objects have negative frame indices. + // object, so that we can allocate a slot immediately following it. If there + // were no fixed objects, use offset -SlotSize, which is immediately after the + // return address. Fixed objects have negative frame indices. MachineFrameInfo *MFI = MF.getFrameInfo(); - int64_t MinFixedObjOffset = 0; + int64_t MinFixedObjOffset = -SlotSize; for (int I = MFI->getObjectIndexBegin(); I < 0; ++I) MinFixedObjOffset = std::min(MinFixedObjOffset, MFI->getObjectOffset(I)); diff --git a/llvm/test/CodeGen/X86/win-cleanuppad.ll b/llvm/test/CodeGen/X86/win-cleanuppad.ll index aed410f79b1..27bb6e2abed 100644 --- a/llvm/test/CodeGen/X86/win-cleanuppad.ll +++ b/llvm/test/CodeGen/X86/win-cleanuppad.ll @@ -19,6 +19,36 @@ ehcleanup: ; preds = %entry cleanupret %0 unwind to caller } +; CHECK: simple_cleanup: # @simple_cleanup +; CHECK: pushq %rbp +; CHECK: subq $48, %rsp +; CHECK: leaq 48(%rsp), %rbp +; CHECK: movq $-2, -8(%rbp) +; CHECK: movl $1, %ecx +; CHECK: callq f +; CHECK: callq "??1Dtor@@QAE@XZ" +; CHECK: nop +; CHECK: addq $48, %rsp +; CHECK: popq %rbp +; CHECK: retq + +; CHECK: "?dtor$2@?0?simple_cleanup@4HA": +; CHECK: callq "??1Dtor@@QAE@XZ" +; CHECK: retq + +; CHECK: $cppxdata$simple_cleanup: +; CHECK-NEXT: .long 429065506 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long ($stateUnwindMap$simple_cleanup)@IMGREL +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long ($ip2state$simple_cleanup)@IMGREL +; UnwindHelp offset should match the -2 store above +; CHECK-NEXT: .long 40 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1 + declare void @f(i32) #0 declare i32 @__CxxFrameHandler3(...) diff --git a/llvm/test/CodeGen/X86/wineh-no-ehpads.ll b/llvm/test/CodeGen/X86/wineh-no-ehpads.ll new file mode 100644 index 00000000000..fd6798f2e08 --- /dev/null +++ b/llvm/test/CodeGen/X86/wineh-no-ehpads.ll @@ -0,0 +1,20 @@ +; RUN: llc < %s | FileCheck %s + +target triple = "x86_64-pc-windows-msvc" + +declare void @g() +declare i32 @__CxxFrameHandler3(...) + +define void @personality_no_ehpad() personality i32 (...)* @__CxxFrameHandler3 { + call void @g() + ret void +} + +; CHECK-LABEL: personality_no_ehpad: # @personality_no_ehpad +; CHECK-NOT: movq $-2, +; CHECK: callq g +; CHECK: nop +; CHECK: retq + +; Shouldn't have any LSDA either. +; CHECK-NOT: cppxdata |