diff options
author | Manish Kausik H <46352931+Nirhar@users.noreply.github.com> | 2024-01-19 20:00:20 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-19 15:30:20 +0100 |
commit | a0b911745494e3c2f53a27f23c536314818ce0b1 (patch) | |
tree | febe89ec06d67c16da77fc55a58256ae2322ac01 | |
parent | 4d11f04b20f0bd7488e19e8f178ba028412fa519 (diff) | |
download | llvm-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.cpp | 14 | ||||
-rw-r--r-- | llvm/test/Transforms/LoopDeletion/loop-with-ehpad-not-executed.ll | 37 |
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 +} |