[llvm] r250534 - [WinEH] Fix endpad coloring/numbering

Joseph Tremoulet via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 16 11:08:16 PDT 2015


Author: josepht
Date: Fri Oct 16 13:08:16 2015
New Revision: 250534

URL: http://llvm.org/viewvc/llvm-project?rev=250534&view=rev
Log:
[WinEH] Fix endpad coloring/numbering

Summary:
When a cleanup's cleanupendpad or cleanupret targets a catchendpad, stop
trying to propagate the cleanup's parent's color to the catchendpad, since
what's needed is the cleanup's grandparent's color and the catchendpad
will get that color from the catchpad linkage already.  We already had
this exclusion for invokes, but were missing it for
cleanupendpad/cleanupret.

Also add a missing line that tags cleanupendpads' states in the
EHPadStateMap, without with lowering invokes that target cleanupendpads
which unwind to other handlers (and so don't have the -1 state) will fail.

This fixes the reduced IR repro in PR25163.


Reviewers: majnemer, andrew.w.kaylor, rnk

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D13797

Modified:
    llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
    llvm/trunk/test/CodeGen/WinEH/wineh-cloning.ll

Modified: llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/WinEHPrepare.cpp?rev=250534&r1=250533&r2=250534&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/WinEHPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/WinEHPrepare.cpp Fri Oct 16 13:08:16 2015
@@ -306,6 +306,7 @@ static void calculateExplicitCXXStateNum
     BasicBlock *CleanupBlock = CEPI->getCleanupPad()->getParent();
     calculateExplicitCXXStateNumbers(FuncInfo, *CleanupBlock, ParentState);
     // Anything unwinding through CleanupEndPadInst is in ParentState.
+    FuncInfo.EHPadStateMap[FirstNonPHI] = ParentState;
     for (const BasicBlock *PredBlock : predecessors(&BB))
       if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
         calculateExplicitCXXStateNumbers(FuncInfo, *PredBlock, ParentState);
@@ -614,12 +615,20 @@ colorFunclets(Function &F, SmallVectorIm
         !isa<CleanupEndPadInst>(VisitingHead)) {
       // Mark this as a funclet head as a member of itself.
       FuncletBlocks[Visiting].insert(Visiting);
-      // Queue exits with the parent color.
+      // Queue exits (i.e. successors of rets/endpads) with the parent color.
+      // Skip any exits that are catchendpads, since the parent color must then
+      // represent one of the catches chained to that catchendpad, but the
+      // catchendpad should get the color of the common parent of all its
+      // chained catches (i.e. the grandparent color of the current pad).
+      // We don't need to worry abou catchendpads going unvisited, since the
+      // catches chained to them must have unwind edges to them by which we will
+      // visit them.
       for (User *U : VisitingHead->users()) {
         if (auto *Exit = dyn_cast<TerminatorInst>(U)) {
           for (BasicBlock *Succ : successors(Exit->getParent()))
-            if (BlockColors[Succ].insert(Color).second)
-              Worklist.push_back({Succ, Color});
+            if (!isa<CatchEndPadInst>(*Succ->getFirstNonPHI()))
+              if (BlockColors[Succ].insert(Color).second)
+                Worklist.push_back({Succ, Color});
         }
       }
       // Handle CatchPad specially since its successors need different colors.

Modified: llvm/trunk/test/CodeGen/WinEH/wineh-cloning.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WinEH/wineh-cloning.ll?rev=250534&r1=250533&r2=250534&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WinEH/wineh-cloning.ll (original)
+++ llvm/trunk/test/CodeGen/WinEH/wineh-cloning.ll Fri Oct 16 13:08:16 2015
@@ -486,6 +486,66 @@ unreachable:
   unreachable
 }
 
+define void @test14() personality i32 (...)* @__CxxFrameHandler3 {
+entry:
+  invoke void @f()
+    to label %exit unwind label %catch1.pad
+catch1.pad:
+  %catch1 = catchpad [i32 1]
+    to label %catch1.body unwind label %catch2.pad
+catch1.body:
+  invoke void @h(i32 1)
+    to label %catch1.body2 unwind label %catch.end
+catch1.body2:
+  invoke void @f()
+    to label %catch1.ret unwind label %cleanup1.pad
+cleanup1.pad:
+  %cleanup1 = cleanuppad []
+  call void @f()
+  cleanupret %cleanup1 unwind label %catch.end
+catch1.ret:
+  catchret %catch1 to label %exit
+catch2.pad:
+  %catch2 = catchpad [i32 2]
+    to label %catch2.body unwind label %catch.end
+catch2.body:
+  invoke void @h(i32 2)
+    to label %catch2.body2 unwind label %catch.end
+catch2.body2:
+  invoke void @f()
+    to label %catch2.ret unwind label %cleanup2.pad
+cleanup2.pad:
+  %cleanup2 = cleanuppad []
+  call void @f()
+  cleanupret %cleanup2 unwind label %catch.end
+catch2.ret:
+  catchret %catch2 to label %exit
+catch.end:
+  catchendpad unwind to caller
+exit:
+  ret void
+}
+; Make sure we don't clone the catchendpad even though the
+; cleanupendpads targeting it would naively imply that it
+; should get their respective parent colors (catch1 and catch2),
+; as well as its properly getting the root function color.  The
+; references from the invokes ensure that if we did make clones
+; for each catch, they'd be reachable, as those invokes would get
+; rewritten
+; CHECK-LABEL: define void @test14()
+; CHECK-NOT:  catchendpad
+; CHECK:      invoke void @h(i32 1)
+; CHECK-NEXT:   unwind label %catch.end
+; CHECK-NOT:  catchendpad
+; CHECK:      invoke void @h(i32 2)
+; CHECK-NEXT:   unwind label %catch.end
+; CHECK-NOT:   catchendpad
+; CHECK:     catch.end:
+; CHECK-NEXT:  catchendpad
+; CHECK-NOT:   catchendpad
+
+;; Debug info (from test12)
+
 ; Make sure the DISubprogram doesn't get cloned
 ; CHECK-LABEL: !llvm.module.flags
 ; CHECK-NOT: !DISubprogram




More information about the llvm-commits mailing list