-
Notifications
You must be signed in to change notification settings - Fork 14.3k
llvm-reduce: Fix assert on invokes with catchswitch #111838
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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
This stack of pull requests is managed by Graphite. Learn more about stacking. |
It looks like this is proprietary to windows runtime exception handling. Otherwise in the setjmp longjmp model or itanium model, there will always be a landingpad, which are not used at all in windows runtime EH. |
@llvm/pr-subscribers-platform-windows Author: Matt Arsenault (arsenm) ChangesThis is the minimal change to avoid the assert. There's an API flaw in Fixes #111817 Full diff: https://github.com/llvm/llvm-project/pull/111838.diff 2 Files Affected:
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()));
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
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 llvm#111817
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