[llvm] llvm-reduce: Fix assert on invokes with catchswitch (PR #111838)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 10 07:09:56 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-platform-windows
Author: Matt Arsenault (arsenm)
<details>
<summary>Changes</summary>
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
---
Full diff: https://github.com/llvm/llvm-project/pull/111838.diff
2 Files Affected:
- (added) llvm/test/tools/llvm-reduce/issue111817-catchswitch-assert.ll (+53)
- (modified) llvm/tools/llvm-reduce/deltas/ReduceBasicBlocks.cpp (+11-2)
``````````diff
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()));
``````````
</details>
https://github.com/llvm/llvm-project/pull/111838
More information about the llvm-commits
mailing list