[llvm] r234608 - [WinEH] Try to make outlining invokes work a little better

Reid Kleckner reid at kleckner.net
Fri Apr 10 09:26:42 PDT 2015


Author: rnk
Date: Fri Apr 10 11:26:42 2015
New Revision: 234608

URL: http://llvm.org/viewvc/llvm-project?rev=234608&view=rev
Log:
[WinEH] Try to make outlining invokes work a little better

WinEH currently turns invokes into calls. Long term, we will reconsider
this, but for now, make sure we remap the operands and clone the
successors of the new terminator.

Added:
    llvm/trunk/test/CodeGen/WinEH/cppeh-cleanup-invoke.ll
Modified:
    llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
    llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp

Modified: llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/WinEHPrepare.cpp?rev=234608&r1=234607&r2=234608&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/WinEHPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/WinEHPrepare.cpp Fri Apr 10 11:26:42 2015
@@ -1231,6 +1231,9 @@ CloningDirector::CloningAction WinEHClea
   NewCall->setDebugLoc(Invoke->getDebugLoc());
   VMap[Invoke] = NewCall;
 
+  // Remap the operands.
+  llvm::RemapInstruction(NewCall, VMap, RF_None, nullptr, &Materializer);
+
   // Insert an unconditional branch to the normal destination.
   BranchInst::Create(Invoke->getNormalDest(), NewBB);
 
@@ -1239,7 +1242,7 @@ CloningDirector::CloningAction WinEHClea
 
   // We just added a terminator to the cloned block.
   // Tell the caller to stop processing the current basic block.
-  return CloningDirector::StopCloningBB;
+  return CloningDirector::CloneSuccessors;
 }
 
 CloningDirector::CloningAction WinEHCleanupDirector::handleResume(

Modified: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp?rev=234608&r1=234607&r2=234608&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Fri Apr 10 11:26:42 2015
@@ -395,7 +395,7 @@ void PruningFunctionCloner::CloneBlock(c
     if (Action == CloningDirector::CloneSuccessors) {
       // If the director says to skip with a terminate instruction, we still
       // need to clone this block's successors.
-      const TerminatorInst *TI = BB->getTerminator();
+      const TerminatorInst *TI = NewBB->getTerminator();
       for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i)
         ToClone.push_back(TI->getSuccessor(i));
       return;

Added: llvm/trunk/test/CodeGen/WinEH/cppeh-cleanup-invoke.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WinEH/cppeh-cleanup-invoke.ll?rev=234608&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/WinEH/cppeh-cleanup-invoke.ll (added)
+++ llvm/trunk/test/CodeGen/WinEH/cppeh-cleanup-invoke.ll Fri Apr 10 11:26:42 2015
@@ -0,0 +1,91 @@
+; RUN: opt -winehprepare -S < %s | FileCheck %s
+
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc"
+
+; Modified based on this code:
+; struct HasDtor {
+;   ~HasDtor();
+; };
+; extern "C" void may_throw();
+; int main() {
+;   try {
+;     HasDtor o;
+;     may_throw();
+;   } catch (int) {
+;   }
+; }
+
+%rtti.TypeDescriptor2 = type { i8**, i8*, [3 x i8] }
+%eh.CatchHandlerType = type { i32, i8* }
+%struct.HasDtor = type { i8 }
+
+$"\01??_R0H at 8" = comdat any
+
+@"\01??_7type_info@@6B@" = external constant i8*
+@"\01??_R0H at 8" = linkonce_odr global %rtti.TypeDescriptor2 { i8** @"\01??_7type_info@@6B@", i8* null, [3 x i8] c".H\00" }, comdat
+ at llvm.eh.handlertype.H.0 = private unnamed_addr constant %eh.CatchHandlerType { i32 0, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H at 8" to i8*) }, section "llvm.metadata"
+
+define i32 @main() {
+entry:
+  %o = alloca %struct.HasDtor, align 1
+  invoke void @may_throw()
+          to label %invoke.cont2 unwind label %lpad1
+
+invoke.cont2:                                     ; preds = %invoke.cont
+  call void @"\01??1HasDtor@@QEAA at XZ"(%struct.HasDtor* %o)
+  br label %try.cont
+
+lpad:                                             ; preds = %entry
+  %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
+          catch %eh.CatchHandlerType* @llvm.eh.handlertype.H.0
+  %1 = extractvalue { i8*, i32 } %0, 0
+  %2 = extractvalue { i8*, i32 } %0, 1
+  br label %catch.dispatch
+
+lpad1:                                            ; preds = %invoke.cont
+  %3 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
+          cleanup
+          catch %eh.CatchHandlerType* @llvm.eh.handlertype.H.0
+  %4 = extractvalue { i8*, i32 } %3, 0
+  %5 = extractvalue { i8*, i32 } %3, 1
+  invoke void @"\01??1HasDtor@@QEAA at XZ"(%struct.HasDtor* %o)
+	  to label %catch.dispatch unwind label %lpad
+
+catch.dispatch:                                   ; preds = %lpad1, %lpad
+  %exn.slot.0 = phi i8* [ %4, %lpad1 ], [ %1, %lpad ]
+  %ehselector.slot.0 = phi i32 [ %5, %lpad1 ], [ %2, %lpad ]
+  %6 = call i32 @llvm.eh.typeid.for(i8* bitcast (%eh.CatchHandlerType* @llvm.eh.handlertype.H.0 to i8*))
+  %matches = icmp eq i32 %ehselector.slot.0, %6
+  br i1 %matches, label %catch, label %eh.resume
+
+catch:                                            ; preds = %catch.dispatch
+  call void @llvm.eh.begincatch(i8* %exn.slot.0, i8* null)
+  call void @llvm.eh.endcatch()
+  br label %try.cont
+
+try.cont:                                         ; preds = %catch, %invoke.cont2
+  ret i32 0
+
+eh.resume:                                        ; preds = %catch.dispatch
+  %lpad.val = insertvalue { i8*, i32 } undef, i8* %exn.slot.0, 0
+  %lpad.val5 = insertvalue { i8*, i32 } %lpad.val, i32 %ehselector.slot.0, 1
+  resume { i8*, i32 } %lpad.val5
+}
+
+; CHECK-LABEL: define i32 @main()
+; CHECK: @llvm.eh.actions(i32 0, void (i8*, i8*)* @main.cleanup, i32 1, i8* bitcast (%eh.CatchHandlerType* @llvm.eh.handlertype.H.0 to i8*), i32 -1, i8* (i8*, i8*)* @main.catch)
+
+; CHECK-LABEL: define internal void @main.cleanup(i8*, i8*)
+; CHECK: call void @"\01??1HasDtor@@QEAA at XZ"(%struct.HasDtor* %{{.*}})
+; CHECK: ret void
+
+declare void @may_throw()
+
+declare i32 @__CxxFrameHandler3(...)
+
+declare void @"\01??1HasDtor@@QEAA at XZ"(%struct.HasDtor*)
+
+declare i32 @llvm.eh.typeid.for(i8*)
+declare void @llvm.eh.begincatch(i8* nocapture, i8* nocapture)
+declare void @llvm.eh.endcatch()





More information about the llvm-commits mailing list