[llvm] r267412 - [WinEH] Update SplitAnalysis::computeLastSplitPoint to cope with multiple EH successors

David Majnemer via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 25 07:31:32 PDT 2016


Author: majnemer
Date: Mon Apr 25 09:31:32 2016
New Revision: 267412

URL: http://llvm.org/viewvc/llvm-project?rev=267412&view=rev
Log:
[WinEH] Update SplitAnalysis::computeLastSplitPoint to cope with multiple EH successors

We didn't have logic to correctly handle CFGs where there was more than
one EH-pad successor (these are novel with WinEH).
There were situations where a register was live in one exceptional
successor but not another but the code as written would only consider
the first exceptional successor it found.

This resulted in split points which were insufficiently early if an
invoke was present.

This fixes PR27501.

N.B.  This removes getLandingPadSuccessor.

Added:
    llvm/trunk/test/CodeGen/X86/pr27501.ll
Modified:
    llvm/trunk/include/llvm/ADT/STLExtras.h
    llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h
    llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp
    llvm/trunk/lib/CodeGen/SplitKit.cpp

Modified: llvm/trunk/include/llvm/ADT/STLExtras.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/STLExtras.h?rev=267412&r1=267411&r2=267412&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/STLExtras.h (original)
+++ llvm/trunk/include/llvm/ADT/STLExtras.h Mon Apr 25 09:31:32 2016
@@ -383,6 +383,14 @@ bool any_of(R &&Range, UnaryPredicate &&
                      std::forward<UnaryPredicate>(P));
 }
 
+/// Provide wrappers to std::none_of which take ranges instead of having to pass
+/// begin/end explicitly.
+template <typename R, class UnaryPredicate>
+bool none_of(R &&Range, UnaryPredicate &&P) {
+  return std::none_of(Range.begin(), Range.end(),
+                      std::forward<UnaryPredicate>(P));
+}
+
 /// Provide wrappers to std::find which take ranges instead of having to pass
 /// begin/end explicitly.
 template<typename R, class T>

Modified: llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h?rev=267412&r1=267411&r2=267412&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h Mon Apr 25 09:31:32 2016
@@ -342,10 +342,6 @@ public:
   /// via an exception handler.
   void setIsEHPad(bool V = true) { IsEHPad = V; }
 
-  /// If this block has a successor that is a landing pad, return it. Otherwise
-  /// return NULL.
-  const MachineBasicBlock *getLandingPadSuccessor() const;
-
   bool hasEHPadSuccessor() const;
 
   /// Returns true if this is the entry block of an EH funclet.

Modified: llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp?rev=267412&r1=267411&r2=267412&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Mon Apr 25 09:31:32 2016
@@ -198,16 +198,6 @@ MachineBasicBlock::iterator MachineBasic
   return end();
 }
 
-const MachineBasicBlock *MachineBasicBlock::getLandingPadSuccessor() const {
-  // A block with a landing pad successor only has one other successor.
-  if (succ_size() > 2)
-    return nullptr;
-  for (const_succ_iterator I = succ_begin(), E = succ_end(); I != E; ++I)
-    if ((*I)->isEHPad())
-      return *I;
-  return nullptr;
-}
-
 bool MachineBasicBlock::hasEHPadSuccessor() const {
   for (const_succ_iterator I = succ_begin(), E = succ_end(); I != E; ++I)
     if ((*I)->isEHPad())

Modified: llvm/trunk/lib/CodeGen/SplitKit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SplitKit.cpp?rev=267412&r1=267411&r2=267412&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SplitKit.cpp (original)
+++ llvm/trunk/lib/CodeGen/SplitKit.cpp Mon Apr 25 09:31:32 2016
@@ -57,11 +57,14 @@ void SplitAnalysis::clear() {
 
 SlotIndex SplitAnalysis::computeLastSplitPoint(unsigned Num) {
   const MachineBasicBlock *MBB = MF.getBlockNumbered(Num);
-  // FIXME: Handle multiple EH pad successors.
-  const MachineBasicBlock *LPad = MBB->getLandingPadSuccessor();
   std::pair<SlotIndex, SlotIndex> &LSP = LastSplitPoint[Num];
   SlotIndex MBBEnd = LIS.getMBBEndIdx(MBB);
 
+  SmallVector<const MachineBasicBlock *, 1> EHPadSucessors;
+  for (const MachineBasicBlock *SMBB : MBB->successors())
+    if (SMBB->isEHPad())
+      EHPadSucessors.push_back(SMBB);
+
   // Compute split points on the first call. The pair is independent of the
   // current live interval.
   if (!LSP.first.isValid()) {
@@ -72,7 +75,7 @@ SlotIndex SplitAnalysis::computeLastSpli
       LSP.first = LIS.getInstructionIndex(*FirstTerm);
 
     // If there is a landing pad successor, also find the call instruction.
-    if (!LPad)
+    if (EHPadSucessors.empty())
       return LSP.first;
     // There may not be a call instruction (?) in which case we ignore LPad.
     LSP.second = LSP.first;
@@ -88,7 +91,12 @@ SlotIndex SplitAnalysis::computeLastSpli
 
   // If CurLI is live into a landing pad successor, move the last split point
   // back to the call that may throw.
-  if (!LPad || !LSP.second || !LIS.isLiveInToMBB(*CurLI, LPad))
+  if (!LSP.second)
+    return LSP.first;
+
+  if (none_of(EHPadSucessors, [&](const MachineBasicBlock *EHPad) {
+        return LIS.isLiveInToMBB(*CurLI, EHPad);
+      }))
     return LSP.first;
 
   // Find the value leaving MBB.

Added: llvm/trunk/test/CodeGen/X86/pr27501.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/pr27501.ll?rev=267412&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/pr27501.ll (added)
+++ llvm/trunk/test/CodeGen/X86/pr27501.ll Mon Apr 25 09:31:32 2016
@@ -0,0 +1,67 @@
+; RUN: llc < %s | FileCheck %s
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc"
+
+define void @test1(i64* %result.repack) personality i32 (...)* @__CxxFrameHandler3 {
+bb:
+  invoke void @may_throw(i32 1)
+          to label %postinvoke unwind label %cleanuppad
+; CHECK:        movl    $1, %ecx
+; CHECK:        callq   may_throw
+
+postinvoke:                                       ; preds = %bb
+  store i64 19, i64* %result.repack, align 8
+
+; CHECK:        movq    $19, (%rsi)
+; CHECK:        movl    $2, %ecx
+; CHECK-NEXT:   movq    %rsi, -8(%rbp)
+; CHECK-NEXT:   callq   may_throw
+  invoke void @may_throw(i32 2)
+          to label %assertFailed unwind label %catch.dispatch
+
+catch.dispatch:                                   ; preds = %cleanuppad9, %postinvoke
+  %tmp3 = catchswitch within none [label %catch.object.Throwable] unwind label %cleanuppad
+
+catch.object.Throwable:                           ; preds = %catch.dispatch
+  %tmp2 = catchpad within %tmp3 [i8* null, i32 64, i8* null]
+  catchret from %tmp2 to label %catchhandler
+
+catchhandler:                                     ; preds = %catch.object.Throwable
+  invoke void @may_throw(i32 3)
+          to label %try.success.or.caught unwind label %cleanuppad
+
+try.success.or.caught:                            ; preds = %catchhandler
+  invoke void @may_throw(i32 4)
+          to label %postinvoke27 unwind label %cleanuppad24
+; CHECK:        movl    $4, %ecx
+; CHECK-NEXT:   callq   may_throw
+
+postinvoke27:                                     ; preds = %try.success.or.caught
+  store i64 42, i64* %result.repack, align 8
+; CHECK:        movq    -8(%rbp), %[[reload:r..]]
+; CHECK-NEXT:   movq    $42, (%[[reload]])
+  ret void
+
+cleanuppad24:                                     ; preds = %try.success.or.caught
+  %tmp5 = cleanuppad within none []
+  cleanupret from %tmp5 unwind to caller
+
+cleanuppad:                                       ; preds = %catchhandler, %catch.dispatch, %bb
+  %tmp1 = cleanuppad within none []
+  cleanupret from %tmp1 unwind to caller
+
+assertFailed:                                     ; preds = %postinvoke
+  invoke void @may_throw(i32 5)
+          to label %postinvoke13 unwind label %cleanuppad9
+
+postinvoke13:                                     ; preds = %assertFailed
+  unreachable
+
+cleanuppad9:                                      ; preds = %assertFailed
+  %tmp4 = cleanuppad within none []
+  cleanupret from %tmp4 unwind label %catch.dispatch
+}
+
+declare void @may_throw(i32)
+
+declare i32 @__CxxFrameHandler3(...)




More information about the llvm-commits mailing list