From e689ed5002a7e9f8e4a32ece8af8807ca4c2cb25 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Mon, 16 Nov 2015 18:47:25 +0000 Subject: [PATCH] [WinEH] Don't let UnwindHelp alias the return address On top of that, don't bother allocating and initializing UnwindHelp if we don't have any funclets. Currently we always use RBP as our frame pointer when funclets are present, so this change makes it impossible to come here without any fixed stack objects. Fixes PR25533. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253245 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86FrameLowering.cpp | 12 ++++++------ test/CodeGen/X86/win-cleanuppad.ll | 30 +++++++++++++++++++++++++++++ test/CodeGen/X86/wineh-no-ehpads.ll | 20 +++++++++++++++++++ 3 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 test/CodeGen/X86/wineh-no-ehpads.ll diff --git a/lib/Target/X86/X86FrameLowering.cpp b/lib/Target/X86/X86FrameLowering.cpp index 3c557fe8a11..72baa078661 100644 --- a/lib/Target/X86/X86FrameLowering.cpp +++ b/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/test/CodeGen/X86/win-cleanuppad.ll b/test/CodeGen/X86/win-cleanuppad.ll index aed410f79b1..27bb6e2abed 100644 --- a/test/CodeGen/X86/win-cleanuppad.ll +++ b/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/test/CodeGen/X86/wineh-no-ehpads.ll b/test/CodeGen/X86/wineh-no-ehpads.ll new file mode 100644 index 00000000000..fd6798f2e08 --- /dev/null +++ b/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 -- 2.34.1