[llvm] c467faf - [WinEH] Ignore lifetime.end PHI nodes in empty cleanuppads

Andy Kaylor via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 23 18:19:28 PST 2020


Author: Andy Kaylor
Date: 2020-01-23T18:18:50-08:00
New Revision: c467faf23c7abda60cfd5486a39ffadd6f546d5c

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

LOG: [WinEH] Ignore lifetime.end PHI nodes in empty cleanuppads

This fixes a bug where a PHI node that is only referenced by a lifetime.end intrinsic in an otherwise empty cleanuppad can cause SimplyCFG to create an SSA violation while removing the empty cleanuppad. Theoretically the same problem can occur with debug intrinsics.

Differential Revision: https://reviews.llvm.org/D72540

Added: 
    

Modified: 
    llvm/lib/Transforms/Utils/SimplifyCFG.cpp
    llvm/test/Transforms/SimplifyCFG/empty-cleanuppad.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index d93ca4f04cdb..222f8af6547b 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -4083,9 +4083,10 @@ static bool removeEmptyCleanup(CleanupReturnInst *RI) {
       // The iterator must be incremented here because the instructions are
       // being moved to another block.
       PHINode *PN = cast<PHINode>(I++);
-      if (PN->use_empty())
-        // If the PHI node has no uses, just leave it.  It will be erased
-        // when we erase BB below.
+      if (PN->use_empty() || !PN->isUsedOutsideOfBlock(BB))
+        // If the PHI node has no uses or all of its uses are in this basic
+        // block (meaning they are debug or lifetime intrinsics), just leave
+        // it.  It will be erased when we erase BB below.
         continue;
 
       // Otherwise, sink this PHI node into UnwindDest.

diff  --git a/llvm/test/Transforms/SimplifyCFG/empty-cleanuppad.ll b/llvm/test/Transforms/SimplifyCFG/empty-cleanuppad.ll
index f2e0114a2a35..f9b6e6388339 100644
--- a/llvm/test/Transforms/SimplifyCFG/empty-cleanuppad.ll
+++ b/llvm/test/Transforms/SimplifyCFG/empty-cleanuppad.ll
@@ -458,6 +458,55 @@ cleanupret2:
   cleanupret from %cp unwind to caller
 }
 
+; CHECK-LABEL: define void @f11(
+;   This case tests the handling of an empty cleanup pad that
+;   contains a lifetime_end intrinsic and does not dominate its
+;   successor.
+; CHECK: entry:
+; CHECK:   invoke void @g()
+; CHECK: invoke.cont:
+; CHECK:   invoke void @g()
+; CHECK: invoke.cont2:
+; CHECK:   invoke void @g()
+; CHECK-NOT: ehcleanup:
+; CHECK-NOT:   phi
+; CHECK-NOT:   cleanuppad
+; CHECK-NOT:   lifetime.end
+; CHECK: catch.dispatch:
+; CHECK:   catchswitch
+; CHECK: catch:
+; CHECK:   catchret
+; CHECK: }
+define void @f11() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
+entry:
+  invoke void @g()
+          to label %invoke.cont unwind label %ehcleanup
+
+invoke.cont:                                      ; preds = %entry
+  invoke void @g()
+          to label %invoke.cont2 unwind label %ehcleanup
+
+invoke.cont2:                                     ; preds = %invoke.cont
+  invoke void @g()
+          to label %return unwind label %catch.dispatch
+
+ehcleanup:                                        ; preds = %invoke.cont, %entry
+  %x = phi i8* [ undef, %invoke.cont ], [ undef, %entry ]
+  %0 = cleanuppad within none []
+  call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull %x)
+  cleanupret from %0 unwind label %catch.dispatch
+
+catch.dispatch:                                   ; preds = %ehcleanup, %invoke.cont
+  %cs1 = catchswitch within none [label %catch] unwind to caller
+
+catch:                                            ; preds = %catch.dispatch
+  %1 = catchpad within %cs1 [i8* null, i32 u0x40, i8* null]
+  catchret from %1 to label %return
+
+return:                                           ; preds = %invoke.cont, %catch.cont
+  ret void
+}
+
 %struct.S = type { i8 }
 %struct.S2 = type { i8 }
 declare void @"\01??1S2@@QEAA at XZ"(%struct.S2*)


        


More information about the llvm-commits mailing list