[llvm] r239574 - [WinEH] Put finally pointers in the handler scope table field
Reid Kleckner
reid at kleckner.net
Thu Jun 11 16:37:18 PDT 2015
Author: rnk
Date: Thu Jun 11 18:37:18 2015
New Revision: 239574
URL: http://llvm.org/viewvc/llvm-project?rev=239574&view=rev
Log:
[WinEH] Put finally pointers in the handler scope table field
We were putting them in the filter field, which is correct for 64-bit
but wrong for 32-bit.
Also switch the order of scope table entry emission so outermost entries
are emitted first, and fix an obvious state assignment bug.
Modified:
llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp
llvm/trunk/lib/Target/X86/X86WinEHState.cpp
llvm/trunk/test/CodeGen/X86/seh-finally.ll
llvm/trunk/test/CodeGen/X86/seh-safe-div-win32.ll
llvm/trunk/test/CodeGen/X86/win32-eh.ll
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp?rev=239574&r1=239573&r2=239574&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp Thu Jun 11 18:37:18 2015
@@ -613,8 +613,8 @@ void WinException::emitExceptHandlerTabl
// For each action in each lpad, emit one of these:
// struct ScopeTableEntry {
// int32_t EnclosingLevel;
- // int32_t (__cdecl *FilterOrFinally)();
- // void *HandlerLabel;
+ // int32_t (__cdecl *Filter)();
+ // void *HandlerOrFinally;
// };
//
// The "outermost" action will use BaseState as its enclosing level. Each
@@ -625,21 +625,20 @@ void WinException::emitExceptHandlerTabl
assert(CurState + int(LPInfo->SEHHandlers.size()) - 1 ==
LPInfo->WinEHState &&
"gaps in the SEH scope table");
- for (const SEHHandler &Handler : LPInfo->SEHHandlers) {
- // Emit the filter or finally function pointer, if present. Otherwise,
- // emit '0' to indicate a catch-all.
- const Function *F = Handler.FilterOrFinally;
- const MCExpr *FilterOrFinally =
- create32bitRef(F ? Asm->getSymbol(F) : nullptr);
-
- // Compute the recovery address, which is a block address or null.
+ for (auto I = LPInfo->SEHHandlers.rbegin(), E = LPInfo->SEHHandlers.rend();
+ I != E; ++I) {
+ const SEHHandler &Handler = *I;
const BlockAddress *BA = Handler.RecoverBA;
- const MCExpr *RecoverBBOrNull =
- create32bitRef(BA ? Asm->GetBlockAddressSymbol(BA) : nullptr);
+ const Function *F = Handler.FilterOrFinally;
+ assert(F && "cannot catch all in 32-bit SEH without filter function");
+ const MCExpr *FilterOrNull =
+ create32bitRef(BA ? Asm->getSymbol(F) : nullptr);
+ const MCExpr *ExceptOrFinally = create32bitRef(
+ BA ? Asm->GetBlockAddressSymbol(BA) : Asm->getSymbol(F));
OS.EmitIntValue(EnclosingLevel, 4);
- OS.EmitValue(FilterOrFinally, 4);
- OS.EmitValue(RecoverBBOrNull, 4);
+ OS.EmitValue(FilterOrNull, 4);
+ OS.EmitValue(ExceptOrFinally, 4);
// The next state unwinds to this state.
EnclosingLevel = CurState;
Modified: llvm/trunk/lib/Target/X86/X86WinEHState.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86WinEHState.cpp?rev=239574&r1=239573&r2=239574&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86WinEHState.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86WinEHState.cpp Thu Jun 11 18:37:18 2015
@@ -508,7 +508,7 @@ void WinEHStatePass::addSEHStateStores(F
// Look up the state number of the landingpad this unwinds to.
LandingPadInst *LPI = II->getUnwindDest()->getLandingPadInst();
auto InsertionPair =
- FuncInfo.LandingPadStateMap.insert(std::make_pair(LPI, 0));
+ FuncInfo.LandingPadStateMap.insert(std::make_pair(LPI, CurState));
auto Iter = InsertionPair.first;
int &State = Iter->second;
bool Inserted = InsertionPair.second;
Modified: llvm/trunk/test/CodeGen/X86/seh-finally.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/seh-finally.ll?rev=239574&r1=239573&r2=239574&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/seh-finally.ll (original)
+++ llvm/trunk/test/CodeGen/X86/seh-finally.ll Thu Jun 11 18:37:18 2015
@@ -1,4 +1,6 @@
-; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s
+; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s --check-prefix=X64
+; RUN: sed -e 's/__C_specific_handler/_except_handler3/' %s | \
+; RUN: llc -mtriple=i686-windows-msvc | FileCheck %s --check-prefix=X86
@str_recovered = internal unnamed_addr constant [10 x i8] c"recovered\00", align 1
@@ -32,17 +34,32 @@ terminate.lpad:
unreachable
}
-; CHECK-LABEL: main:
-; CHECK: .seh_handlerdata
-; CHECK-NEXT: .long 1
-; CHECK-NEXT: .long .Ltmp0 at IMGREL
-; CHECK-NEXT: .long .Ltmp1 at IMGREL
-; CHECK-NEXT: .long main.cleanup at IMGREL
-; CHECK-NEXT: .long 0
-
-; CHECK-LABEL: main.cleanup:
-; CHECK: callq puts
-; CHECK: retq
+; X64-LABEL: main:
+; X64: retq
+
+; X64: .seh_handlerdata
+; X64-NEXT: .long 1
+; X64-NEXT: .long .Ltmp0 at IMGREL
+; X64-NEXT: .long .Ltmp1 at IMGREL
+; X64-NEXT: .long main.cleanup at IMGREL
+; X64-NEXT: .long 0
+
+; X64-LABEL: main.cleanup:
+; X64: callq puts
+; X64: retq
+
+; X86-LABEL: _main:
+; X86: retl
+
+; X86: .section .xdata,"dr"
+; X86: L__ehtable$main:
+; X86-NEXT: .long -1
+; X86-NEXT: .long 0
+; X86-NEXT: .long _main.cleanup
+
+; X86-LABEL: _main.cleanup:
+; X86: calll _puts
+; X86: retl
declare i32 @__C_specific_handler(...)
Modified: llvm/trunk/test/CodeGen/X86/seh-safe-div-win32.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/seh-safe-div-win32.ll?rev=239574&r1=239573&r2=239574&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/seh-safe-div-win32.ll (original)
+++ llvm/trunk/test/CodeGen/X86/seh-safe-div-win32.ll Thu Jun 11 18:37:18 2015
@@ -92,11 +92,11 @@ __try.cont:
; CHECK: .section .xdata,"dr"
; CHECK: L__ehtable$safe_div:
; CHECK-NEXT: .long -1
-; CHECK-NEXT: .long _safe_div_filt0
-; CHECK-NEXT: .long [[handler0]]
-; CHECK-NEXT: .long 0
; CHECK-NEXT: .long _safe_div_filt1
; CHECK-NEXT: .long [[handler1]]
+; CHECK-NEXT: .long 0
+; CHECK-NEXT: .long _safe_div_filt0
+; CHECK-NEXT: .long [[handler0]]
define void @try_body(i32* %r, i32* %n, i32* %d) {
entry:
Modified: llvm/trunk/test/CodeGen/X86/win32-eh.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/win32-eh.ll?rev=239574&r1=239573&r2=239574&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/win32-eh.ll (original)
+++ llvm/trunk/test/CodeGen/X86/win32-eh.ll Thu Jun 11 18:37:18 2015
@@ -6,16 +6,27 @@ declare i32 @_except_handler4(...)
declare i32 @__CxxFrameHandler3(...)
declare void @llvm.eh.begincatch(i8*, i8*)
declare void @llvm.eh.endcatch()
+declare i32 @llvm.eh.typeid.for(i8*)
+
+define internal i32 @catchall_filt() {
+ ret i32 1
+}
define void @use_except_handler3() {
+entry:
invoke void @may_throw_or_crash()
to label %cont unwind label %catchall
cont:
ret void
catchall:
- landingpad { i8*, i32 } personality i32 (...)* @_except_handler3
- catch i8* null
- br label %cont
+ %0 = landingpad { i8*, i32 } personality i32 (...)* @_except_handler3
+ catch i8* bitcast (i32 ()* @catchall_filt to i8*)
+ %1 = extractvalue { i8*, i32 } %0, 1
+ %2 = call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ()* @catchall_filt to i8*)) #4
+ %matches = icmp eq i32 %1, %2
+ br i1 %matches, label %cont, label %eh.resume
+eh.resume:
+ resume { i8*, i32 } %0
}
; CHECK-LABEL: _use_except_handler3:
@@ -37,18 +48,24 @@ catchall:
; CHECK: .section .xdata,"dr"
; CHECK-LABEL: L__ehtable$use_except_handler3:
; CHECK-NEXT: .long -1
-; CHECK-NEXT: .long 0
+; CHECK-NEXT: .long _catchall_filt
; CHECK-NEXT: .long Ltmp{{[0-9]+}}
define void @use_except_handler4() {
+entry:
invoke void @may_throw_or_crash()
to label %cont unwind label %catchall
cont:
ret void
catchall:
- landingpad { i8*, i32 } personality i32 (...)* @_except_handler4
- catch i8* null
- br label %cont
+ %0 = landingpad { i8*, i32 } personality i32 (...)* @_except_handler4
+ catch i8* bitcast (i32 ()* @catchall_filt to i8*)
+ %1 = extractvalue { i8*, i32 } %0, 1
+ %2 = call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ()* @catchall_filt to i8*)) #4
+ %matches = icmp eq i32 %1, %2
+ br i1 %matches, label %cont, label %eh.resume
+eh.resume:
+ resume { i8*, i32 } %0
}
; CHECK-LABEL: _use_except_handler4:
@@ -77,7 +94,7 @@ catchall:
; CHECK-NEXT: .long 9999
; CHECK-NEXT: .long 0
; CHECK-NEXT: .long -2
-; CHECK-NEXT: .long 0
+; CHECK-NEXT: .long _catchall_filt
; CHECK-NEXT: .long Ltmp{{[0-9]+}}
define void @use_CxxFrameHandler3() {
More information about the llvm-commits
mailing list