aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManish Kausik H <46352931+Nirhar@users.noreply.github.com>2024-01-19 20:00:20 +0530
committerGitHub <noreply@github.com>2024-01-19 15:30:20 +0100
commita0b911745494e3c2f53a27f23c536314818ce0b1 (patch)
treefebe89ec06d67c16da77fc55a58256ae2322ac01
parent4d11f04b20f0bd7488e19e8f178ba028412fa519 (diff)
downloadllvm-a0b911745494e3c2f53a27f23c536314818ce0b1.zip
llvm-a0b911745494e3c2f53a27f23c536314818ce0b1.tar.gz
llvm-a0b911745494e3c2f53a27f23c536314818ce0b1.tar.bz2
LoopDeletion: Move EH pad check before the isLoopNeverExecuted Check (#78189)
This commit modifies `LoopDeletion::deleteLoopIfDead` to check if the exit block of a loop is an EH pad before checking if the loop gets executed. This handles the case where an unreachable loop has a landingpad as an Exit block, and the loop gets deleted, leaving leaving the landingpad without an edge from an unwind clause. Fixes #76852.
-rw-r--r--llvm/lib/Transforms/Scalar/LoopDeletion.cpp14
-rw-r--r--llvm/test/Transforms/LoopDeletion/loop-with-ehpad-not-executed.ll37
2 files changed, 44 insertions, 7 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopDeletion.cpp b/llvm/lib/Transforms/Scalar/LoopDeletion.cpp
index c041e36..bfe9374 100644
--- a/llvm/lib/Transforms/Scalar/LoopDeletion.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopDeletion.cpp
@@ -452,6 +452,13 @@ static LoopDeletionResult deleteLoopIfDead(Loop *L, DominatorTree &DT,
BasicBlock *ExitBlock = L->getUniqueExitBlock();
+ // We can't directly branch to an EH pad. Don't bother handling this edge
+ // case.
+ if (ExitBlock && ExitBlock->isEHPad()) {
+ LLVM_DEBUG(dbgs() << "Cannot delete loop exiting to EH pad.\n");
+ return LoopDeletionResult::Unmodified;
+ }
+
if (ExitBlock && isLoopNeverExecuted(L)) {
LLVM_DEBUG(dbgs() << "Loop is proven to never execute, delete it!\n");
// We need to forget the loop before setting the incoming values of the exit
@@ -487,13 +494,6 @@ static LoopDeletionResult deleteLoopIfDead(Loop *L, DominatorTree &DT,
return LoopDeletionResult::Unmodified;
}
- // We can't directly branch to an EH pad. Don't bother handling this edge
- // case.
- if (ExitBlock && ExitBlock->isEHPad()) {
- LLVM_DEBUG(dbgs() << "Cannot delete loop exiting to EH pad.\n");
- return LoopDeletionResult::Unmodified;
- }
-
// Finally, we have to check that the loop really is dead.
bool Changed = false;
if (!isLoopDead(L, SE, ExitingBlocks, ExitBlock, Changed, Preheader, LI)) {
diff --git a/llvm/test/Transforms/LoopDeletion/loop-with-ehpad-not-executed.ll b/llvm/test/Transforms/LoopDeletion/loop-with-ehpad-not-executed.ll
new file mode 100644
index 0000000..e5871df
--- /dev/null
+++ b/llvm/test/Transforms/LoopDeletion/loop-with-ehpad-not-executed.ll
@@ -0,0 +1,37 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; RUN: opt %s -passes=loop-deletion -S | FileCheck %s
+
+define void @wombat() personality ptr null {
+; CHECK-LABEL: define void @wombat() personality ptr null {
+; CHECK-NEXT: bb:
+; CHECK-NEXT: br i1 false, label [[BB1:%.*]], label [[BB4:%.*]]
+; CHECK: bb1:
+; CHECK-NEXT: br label [[BB2:%.*]]
+; CHECK: bb2:
+; CHECK-NEXT: [[INVOKE:%.*]] = invoke double null()
+; CHECK-NEXT: to label [[BB2]] unwind label [[BB3:%.*]]
+; CHECK: bb3:
+; CHECK-NEXT: [[LANDINGPAD:%.*]] = landingpad { ptr, i32 }
+; CHECK-NEXT: cleanup
+; CHECK-NEXT: ret void
+; CHECK: bb4:
+; CHECK-NEXT: ret void
+;
+bb:
+ br i1 false, label %bb1, label %bb4
+
+bb1: ; preds = %bb
+ br label %bb2
+
+bb2: ; preds = %bb1, %bb2
+ %invoke = invoke double null()
+ to label %bb2 unwind label %bb3
+
+bb3: ; preds = %bb2
+ %landingpad = landingpad { ptr, i32 }
+ cleanup
+ ret void
+
+bb4: ; preds = %bb
+ ret void
+}