[llvm] llvm-reduce: Fix assert on invokes with catchswitch (PR #111838)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 10 06:52:26 PDT 2024


https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/111838

This is the minimal change to avoid the assert. There's an API flaw in
invoke instructions where getLandingPad assumes all invoke unwind
blocks have landingpads, when some have catchswitch instead.

Fixes #111817

>From 6b91d1ddf44467d4db8563d56cb2a6dd0078dfbd Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Thu, 10 Oct 2024 16:44:40 +0400
Subject: [PATCH] llvm-reduce: Fix assert on invokes with catchswitch

This is the minimal change to avoid the assert. There's an API flaw in
invoke instructions where getLandingPad assumes all invoke unwind
blocks have landingpads, when some have catchswitch instead.

Fixes #111817
---
 .../issue111817-catchswitch-assert.ll         | 53 +++++++++++++++++++
 .../llvm-reduce/deltas/ReduceBasicBlocks.cpp  | 13 ++++-
 2 files changed, 64 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/tools/llvm-reduce/issue111817-catchswitch-assert.ll

diff --git a/llvm/test/tools/llvm-reduce/issue111817-catchswitch-assert.ll b/llvm/test/tools/llvm-reduce/issue111817-catchswitch-assert.ll
new file mode 100644
index 00000000000000..cf20c8607ab2f3
--- /dev/null
+++ b/llvm/test/tools/llvm-reduce/issue111817-catchswitch-assert.ll
@@ -0,0 +1,53 @@
+; RUN: llvm-reduce -abort-on-invalid-reduction --delta-passes=basic-blocks --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
+; RUN: FileCheck --check-prefix=CHECK-FINAL %s < %t
+
+; Make sure there's no assertion for invoke destinations that don't
+; use landingpad (and use catchswitch instead)
+
+; CHECK-INTERESTINGNESS: invoke
+
+; CHECK-FINAL: bb:
+; CHECK-FINAL-NEXT: invoke void @llvm.seh.try.begin()
+; CHECK-FINAL-NEXT:   to label %bb7 unwind label %bb1
+; CHECK-FINAL: bb1:
+; CHECK-FINAL-NEXT: %i = catchswitch within none [label %bb2] unwind to caller
+
+; CHECK-FINAL: bb2:
+; CHECK-FINAL-NEXT: %i3 = catchpad within %i [ptr null]
+; CHECK-FINAL-NEXT: ret ptr null
+
+; CHECK-FINAL-NOT: bb4
+; CHECK-FINAL-NOT: bb5
+
+; CHECK-FINAL: bb7:
+; CHECK-FINAL-NEXT: ret ptr null
+define ptr @func() personality ptr @__C_specific_handler {
+bb:
+  invoke void @llvm.seh.try.begin()
+          to label %bb7 unwind label %bb1
+
+bb1:                                              ; preds = %bb
+  %i = catchswitch within none [label %bb2] unwind to caller
+
+bb2:                                              ; preds = %bb1
+  %i3 = catchpad within %i [ptr null]
+  catchret from %i3 to label %bb4
+
+bb4:                                              ; preds = %bb2
+  invoke void @llvm.seh.try.end()
+          to label %bb7 unwind label %bb5
+
+bb5:                                              ; preds = %bb4
+  %i6 = cleanuppad within none []
+  cleanupret from %i6 unwind to caller
+
+bb7:                                              ; preds = %bb4, %bb
+  ret ptr null
+}
+
+declare void @llvm.seh.try.begin() #0
+declare void @llvm.seh.try.end() #0
+declare i32 @__C_specific_handler(...)
+
+attributes #0 = { nounwind willreturn memory(write) }
+
diff --git a/llvm/tools/llvm-reduce/deltas/ReduceBasicBlocks.cpp b/llvm/tools/llvm-reduce/deltas/ReduceBasicBlocks.cpp
index 6858dac9aeac41..41e3ffd963f5ba 100644
--- a/llvm/tools/llvm-reduce/deltas/ReduceBasicBlocks.cpp
+++ b/llvm/tools/llvm-reduce/deltas/ReduceBasicBlocks.cpp
@@ -45,12 +45,21 @@ static void replaceBranchTerminator(BasicBlock &BB,
   if (ChunkSuccessors.size() == Term->getNumSuccessors())
     return;
 
+  // TODO: Handle these without failing verifier.
+  if (isa<CatchSwitchInst>(Term))
+    return;
+
   bool IsBranch = isa<BranchInst>(Term);
   if (InvokeInst *Invoke = dyn_cast<InvokeInst>(Term)) {
-    LandingPadInst *LP = Invoke->getLandingPadInst();
+    BasicBlock *UnwindDest = Invoke->getUnwindDest();
+    Instruction *LP = UnwindDest->getFirstNonPHI();
+
     // Remove landingpad instruction if the containing block isn't used by other
     // invokes.
-    if (none_of(LP->getParent()->users(), [Invoke](User *U) {
+
+    // TODO: Handle catchswitch, catchpad, catchret, and cleanupret
+    if (isa<LandingPadInst>(LP) &&
+        none_of(UnwindDest->users(), [Invoke](User *U) {
           return U != Invoke && isa<InvokeInst>(U);
         })) {
       LP->replaceAllUsesWith(getDefaultValue(LP->getType()));



More information about the llvm-commits mailing list