[llvm] 55cd727 - [SimplifyCFG] 'merge compatible invokes': allow PHI nodes in landing pads

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 4 09:27:16 PST 2022


Author: Roman Lebedev
Date: 2022-02-04T20:26:44+03:00
New Revision: 55cd727c9ad1f2924cb43d7316b5cc050422e441

URL: https://github.com/llvm/llvm-project/commit/55cd727c9ad1f2924cb43d7316b5cc050422e441
DIFF: https://github.com/llvm/llvm-project/commit/55cd727c9ad1f2924cb43d7316b5cc050422e441.diff

LOG: [SimplifyCFG] 'merge compatible invokes': allow PHI nodes in landing pads

... iff the incoming values for the invokes-to-be-merged
are compatible (identical).

Added: 
    

Modified: 
    llvm/lib/Transforms/Utils/SimplifyCFG.cpp
    llvm/test/Transforms/SimplifyCFG/X86/merge-compatible-invokes-of-landingpad.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index d72718e7222d..5d09d2ac6890 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -2307,13 +2307,12 @@ bool CompatibleSets::shouldBelongToSameSet(ArrayRef<InvokeInst *> Invokes) {
   }
 #endif
 
-  // The successor blocks must not have any PHI nodes.
+  // In the unwind destination, the incoming values for these two `invoke`s
+  // must be compatible .
   // We know we don't have the normal destination, so we don't check it.
-  // FIXME: instead check that the incoming values are compatible?
-  auto HasPHIsInUnwindDest = [](InvokeInst *II) {
-    return !empty(II->getUnwindDest()->phis());
-  };
-  if (any_of(Invokes, HasPHIsInUnwindDest))
+  if (!IncomingValuesAreCompatible(
+          Invokes.front()->getUnwindDest(),
+          {Invokes[0]->getParent(), Invokes[1]->getParent()}))
     return false;
 
   // Ignoring arguments, these `invoke`s must be identical,
@@ -2417,6 +2416,13 @@ static void MergeCompatibleInvokesImpl(ArrayRef<InvokeInst *> Invokes,
     U.set(PN);
   }
 
+  // We've ensured that each PHI node in the `landingpad` has compatible
+  // (identical) incoming values when coming from each of the `invoke`s
+  // in the current merge set, so update the PHI nodes accordingly.
+  AddPredecessorToBlock(/*Succ=*/MergedInvoke->getUnwindDest(),
+                        /*NewPred=*/MergedInvoke->getParent(),
+                        /*ExistPred=*/Invokes.front()->getParent());
+
   // And finally, replace the original `invoke`s with an unconditional branch
   // to the block with the merged `invoke`. Also, give that merged `invoke`
   // the merged debugloc of all the original `invoke`s.
@@ -2431,7 +2437,8 @@ static void MergeCompatibleInvokesImpl(ArrayRef<InvokeInst *> Invokes,
 
     // And replace the old `invoke` with an unconditionally branch
     // to the block with the merged `invoke`.
-    II->getNormalDest()->removePredecessor(II->getParent());
+    for (BasicBlock *OrigSuccBB : successors(II->getParent()))
+      OrigSuccBB->removePredecessor(II->getParent());
     BranchInst::Create(MergedInvoke->getParent(), II->getParent());
     // Since the normal destination was unreachable, there are no live uses.
     II->replaceAllUsesWith(UndefValue::get(II->getType()));

diff  --git a/llvm/test/Transforms/SimplifyCFG/X86/merge-compatible-invokes-of-landingpad.ll b/llvm/test/Transforms/SimplifyCFG/X86/merge-compatible-invokes-of-landingpad.ll
index a4d794cbb86d..3097ab4aed82 100644
--- a/llvm/test/Transforms/SimplifyCFG/X86/merge-compatible-invokes-of-landingpad.ll
+++ b/llvm/test/Transforms/SimplifyCFG/X86/merge-compatible-invokes-of-landingpad.ll
@@ -1351,14 +1351,9 @@ define void @t23_phi_in_landingpad_compatible_incoming_values() personality i8*
 ; CHECK-LABEL: @t23_phi_in_landingpad_compatible_incoming_values(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
-; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE0:%.*]]
-; CHECK:       if.then0:
-; CHECK-NEXT:    invoke void @simple_throw()
-; CHECK-NEXT:    to label [[INVOKE_CONT0:%.*]] unwind label [[LPAD:%.*]]
-; CHECK:       invoke.cont0:
-; CHECK-NEXT:    unreachable
+; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE0:%.*]]
 ; CHECK:       lpad:
-; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ 0, [[IF_THEN0]] ], [ 0, [[IF_THEN1:%.*]] ], [ -1, [[IF_THEN2:%.*]] ]
+; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ -1, [[IF_THEN2:%.*]] ], [ 0, [[IF_THEN1_INVOKE]] ]
 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
 ; CHECK-NEXT:    cleanup
 ; CHECK-NEXT:    call void @consume(i32 [[PHI]])
@@ -1366,11 +1361,11 @@ define void @t23_phi_in_landingpad_compatible_incoming_values() personality i8*
 ; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
 ; CHECK:       if.else0:
 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
-; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1]], label [[IF_ELSE1:%.*]]
-; CHECK:       if.then1:
+; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_ELSE1:%.*]]
+; CHECK:       if.then1.invoke:
 ; CHECK-NEXT:    invoke void @simple_throw()
-; CHECK-NEXT:    to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]]
-; CHECK:       invoke.cont2:
+; CHECK-NEXT:    to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
+; CHECK:       if.then1.cont:
 ; CHECK-NEXT:    unreachable
 ; CHECK:       if.else1:
 ; CHECK-NEXT:    [[C2:%.*]] = call i1 @cond()


        


More information about the llvm-commits mailing list