[llvm] 333cdd4 - [SimplifyCFG] Reapply: when eliminating `unreachable` landing pads, mark `call`s as `nounwind`
Roman Lebedev via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 13 10:05:37 PST 2023
Author: Roman Lebedev
Date: 2023-01-13T21:04:17+03:00
New Revision: 333cdd41255adb122b1a3cedac5bc6aef5c0982c
URL: https://github.com/llvm/llvm-project/commit/333cdd41255adb122b1a3cedac5bc6aef5c0982c
DIFF: https://github.com/llvm/llvm-project/commit/333cdd41255adb122b1a3cedac5bc6aef5c0982c.diff
LOG: [SimplifyCFG] Reapply: when eliminating `unreachable` landing pads, mark `call`s as `nounwind`
This time the change is in it's least intrusive form since only the return
type in prototype for `removeUnwindEdge()` is changed, since only a single
specific caller need that knowledge.
We really can't recover that knowledge, and `nounwind` knowledge,
(and not just a lack of the unwind edge, aka `call` instead of `invoke`),
is e.g. part of the reasoning in e.g. `mayHaveSideEffects()`.
Note that this is call-site-specific knowledge,
just because some callsite had an `unreachable`
unwind edge, does not mean that all will.
Added:
Modified:
llvm/include/llvm/Transforms/Utils/Local.h
llvm/lib/Transforms/Utils/Local.cpp
llvm/lib/Transforms/Utils/SimplifyCFG.cpp
llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/Transforms/Utils/Local.h b/llvm/include/llvm/Transforms/Utils/Local.h
index 1ad1e7b948c1..75d2351e2df3 100644
--- a/llvm/include/llvm/Transforms/Utils/Local.h
+++ b/llvm/include/llvm/Transforms/Utils/Local.h
@@ -356,11 +356,12 @@ BasicBlock *changeToInvokeAndSplitBasicBlock(CallInst *CI,
/// Replace 'BB's terminator with one that does not have an unwind successor
/// block. Rewrites `invoke` to `call`, etc. Updates any PHIs in unwind
-/// successor.
+/// successor. Returns the instruction that replaced the original terminator,
+/// which might be a call in case the original terminator was an invoke.
///
/// \param BB Block whose terminator will be replaced. Its terminator must
/// have an unwind successor.
-void removeUnwindEdge(BasicBlock *BB, DomTreeUpdater *DTU = nullptr);
+Instruction *removeUnwindEdge(BasicBlock *BB, DomTreeUpdater *DTU = nullptr);
/// Remove all blocks that can not be reached from the function's entry.
///
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index d5d0232d7c1e..a8a7b64e6a23 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -2557,13 +2557,11 @@ static bool markAliveBlocks(Function &F,
return Changed;
}
-void llvm::removeUnwindEdge(BasicBlock *BB, DomTreeUpdater *DTU) {
+Instruction *llvm::removeUnwindEdge(BasicBlock *BB, DomTreeUpdater *DTU) {
Instruction *TI = BB->getTerminator();
- if (auto *II = dyn_cast<InvokeInst>(TI)) {
- changeToCall(II, DTU);
- return;
- }
+ if (auto *II = dyn_cast<InvokeInst>(TI))
+ return changeToCall(II, DTU);
Instruction *NewTI;
BasicBlock *UnwindDest;
@@ -2591,6 +2589,7 @@ void llvm::removeUnwindEdge(BasicBlock *BB, DomTreeUpdater *DTU) {
TI->eraseFromParent();
if (DTU)
DTU->applyUpdates({{DominatorTree::Delete, BB, UnwindDest}});
+ return NewTI;
}
/// removeUnreachableBlocks - Remove blocks that are not reachable, even
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index a23515817563..9e0483966d3e 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -5184,7 +5184,9 @@ bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) {
DTU->applyUpdates(Updates);
Updates.clear();
}
- removeUnwindEdge(TI->getParent(), DTU);
+ auto *CI = cast<CallInst>(removeUnwindEdge(TI->getParent(), DTU));
+ if (!CI->doesNotThrow())
+ CI->setDoesNotThrow();
Changed = true;
}
} else if (auto *CSI = dyn_cast<CatchSwitchInst>(TI)) {
diff --git a/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll b/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
index 94d1fa54159d..7fe32dfc244d 100644
--- a/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
+++ b/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
@@ -20,7 +20,7 @@ F:
define void @test2() personality ptr @__gxx_personality_v0 {
; CHECK-LABEL: @test2(
; CHECK-NEXT: entry:
-; CHECK-NEXT: call void @test2()
+; CHECK-NEXT: call void @test2() #[[ATTR3:[0-9]+]]
; CHECK-NEXT: ret void
;
entry:
@@ -570,4 +570,5 @@ attributes #0 = { null_pointer_is_valid }
; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) }
; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
; CHECK: attributes #[[ATTR2:[0-9]+]] = { null_pointer_is_valid }
+; CHECK: attributes #[[ATTR3]] = { nounwind }
;.
diff --git a/llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll b/llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll
index 9828db2a6985..0d495f95afe6 100644
--- a/llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll
+++ b/llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll
@@ -7,7 +7,7 @@ declare void @f()
define void @test1() personality ptr @Personality {
; CHECK-LABEL: @test1(
; CHECK-NEXT: entry:
-; CHECK-NEXT: call void @f()
+; CHECK-NEXT: call void @f() #[[ATTR0:[0-9]+]]
; CHECK-NEXT: ret void
;
entry:
@@ -61,7 +61,7 @@ define void @test3() personality ptr @Personality {
; CHECK-NEXT: to label [[EXIT:%.*]] unwind label [[CLEANUP_PAD:%.*]]
; CHECK: cleanup.pad:
; CHECK-NEXT: [[CLEANUP:%.*]] = cleanuppad within none []
-; CHECK-NEXT: call void @f()
+; CHECK-NEXT: call void @f() #[[ATTR0]]
; CHECK-NEXT: unreachable
; CHECK: exit:
; CHECK-NEXT: ret void
@@ -238,3 +238,6 @@ catch.body2:
exit:
ret void
}
+;.
+; CHECK: attributes #[[ATTR0]] = { nounwind }
+;.
More information about the llvm-commits
mailing list