[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