-
Notifications
You must be signed in to change notification settings - Fork 14.2k
[BasicBlockUtils] Remove broken support for eh pads in SplitEdge() #137816
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
d81d9e8 changed SplitEdge() to make use of ehAwareSplitEdge() for critical edges where the target is an eh pad. However, the implementation is incorrect for landing pads, because this requires passing additional information to the function and performing non-local updates. What is currently produced for the code in the modified unit test is this: continue: invoke void @sink() to label %normal unwind label %0 0: %1 = cleanuppad within %exception [] cleanupret from %1 unwind label %exception exception: %cleanup = landingpad i8 cleanup br label %trivial-eh-handler This is not well-formed IR. To actually "split" the landingpad edge we would have to do something along the lines of what CoroFrame does, where we'd generate multiple landingpads, which then go to a common phi in the original block. I could try to implement this here, but I find it rather dubious (we'd still have a landingpad at the start of the "split" edge so it's not *really* "split") and clearly nobody actually uses SplitEdge() on eh edges, because then somebody would have noticed that it generates broken code.
@llvm/pr-subscribers-llvm-transforms Author: Nikita Popov (nikic) Changesd81d9e8 changed SplitEdge() to make use of ehAwareSplitEdge() for critical edges where the target is an eh pad. However, the implementation is incorrect at least for landing pads. What is currently produced for the code in the modified unit test is something like this:
This mixes different exception handling mechanisms in a nonsensical way, and is not well-formed IR. To actually "split" the landingpad edge (for a rather loose definition of "split"), I think we'd have to generate something along these lines:
I didn't bother actually implementing that, seeing as how nobody noticed the existing codegen being broken in the last four years, so clearly nobody actually needs this function to work with EH edges. Just return nullptr instead. Full diff: https://github.com/llvm/llvm-project/pull/137816.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
index 429037ab9da47..dce10c0ecd56c 100644
--- a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
+++ b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
@@ -768,11 +768,6 @@ BasicBlock *llvm::SplitEdge(BasicBlock *BB, BasicBlock *Succ, DominatorTree *DT,
CriticalEdgeSplittingOptions(DT, LI, MSSAU).setPreserveLCSSA();
if ((isCriticalEdge(LatchTerm, SuccNum, Options.MergeIdenticalEdges))) {
- // If it is a critical edge, and the succesor is an exception block, handle
- // the split edge logic in this specific function
- if (Succ->isEHPad())
- return ehAwareSplitEdge(BB, Succ, nullptr, nullptr, Options, BBName);
-
// If this is a critical edge, let SplitKnownCriticalEdge do it.
return SplitKnownCriticalEdge(LatchTerm, SuccNum, Options, BBName);
}
diff --git a/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp b/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp
index c9a6a32851775..e58daed887855 100644
--- a/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp
+++ b/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp
@@ -285,22 +285,8 @@ declare void @sink_alt() cold
EXPECT_TRUE(Ehpad);
BasicBlock *NewBB = SplitEdge(SrcBlock, DestBlock, &DT, &LI, &MSSAU, "");
-
- MSSA.verifyMemorySSA();
- EXPECT_TRUE(DT.verify());
- EXPECT_NE(NewBB, nullptr);
- EXPECT_EQ(NewBB->getSinglePredecessor(), SrcBlock);
- EXPECT_EQ(NewBB, SrcBlock->getTerminator()->getSuccessor(SuccNum));
- EXPECT_EQ(NewBB->getParent(), F);
-
- bool BBFlag = false;
- for (BasicBlock &BB : *F) {
- if (BB.getName() == NewBB->getName()) {
- BBFlag = true;
- break;
- }
- }
- EXPECT_TRUE(BBFlag);
+ // SplitEdge cannot split an eh pad edge.
+ EXPECT_EQ(NewBB, nullptr);
}
TEST(BasicBlockUtils, splitBasicBlockBefore_ex1) {
|
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
After llvm#137799 and llvm#137816, instruction uses of BasicBlocks are always terminators, so assert that instead of checking it.
…lvm#137816) d81d9e8 changed SplitEdge() to make use of ehAwareSplitEdge() for critical edges where the target is an eh pad. However, the implementation is incorrect at least for landing pads. What is currently produced for the code in the modified unit test is something like this: continue: invoke void @sink() to label %normal unwind label %new_bb new_bb: %cp = cleanuppad within %exception [] cleanupret from %cp unwind label %exception exception: %cleanup = landingpad i8 cleanup br label %trivial-eh-handler This mixes different exception handling mechanisms in a nonsensical way, and is not well-formed IR. To actually "split" the landingpad edge (for a rather loose definition of "split"), I think we'd have to generate something along these lines: exception.split: %cleanup.split = landingpad i8 cleanup br label %exception.cont exception: %cleanup.orig = landingpad i8 cleanup br label %exception.cont exception.cont: %cleanup = phi i8 [ %cleanup.split, %exception_split ], [ %cleanup.orig, %exception ] I didn't bother actually implementing that, seeing as how nobody noticed the existing codegen being broken in the last four years, so clearly nobody actually needs this function to work with EH edges. Just return nullptr instead.
After llvm#137799 and llvm#137816, instruction uses of BasicBlocks are always terminators, so assert that instead of checking it.
…lvm#137816) d81d9e8 changed SplitEdge() to make use of ehAwareSplitEdge() for critical edges where the target is an eh pad. However, the implementation is incorrect at least for landing pads. What is currently produced for the code in the modified unit test is something like this: continue: invoke void @sink() to label %normal unwind label %new_bb new_bb: %cp = cleanuppad within %exception [] cleanupret from %cp unwind label %exception exception: %cleanup = landingpad i8 cleanup br label %trivial-eh-handler This mixes different exception handling mechanisms in a nonsensical way, and is not well-formed IR. To actually "split" the landingpad edge (for a rather loose definition of "split"), I think we'd have to generate something along these lines: exception.split: %cleanup.split = landingpad i8 cleanup br label %exception.cont exception: %cleanup.orig = landingpad i8 cleanup br label %exception.cont exception.cont: %cleanup = phi i8 [ %cleanup.split, %exception_split ], [ %cleanup.orig, %exception ] I didn't bother actually implementing that, seeing as how nobody noticed the existing codegen being broken in the last four years, so clearly nobody actually needs this function to work with EH edges. Just return nullptr instead.
After llvm#137799 and llvm#137816, instruction uses of BasicBlocks are always terminators, so assert that instead of checking it.
…lvm#137816) d81d9e8 changed SplitEdge() to make use of ehAwareSplitEdge() for critical edges where the target is an eh pad. However, the implementation is incorrect at least for landing pads. What is currently produced for the code in the modified unit test is something like this: continue: invoke void @sink() to label %normal unwind label %new_bb new_bb: %cp = cleanuppad within %exception [] cleanupret from %cp unwind label %exception exception: %cleanup = landingpad i8 cleanup br label %trivial-eh-handler This mixes different exception handling mechanisms in a nonsensical way, and is not well-formed IR. To actually "split" the landingpad edge (for a rather loose definition of "split"), I think we'd have to generate something along these lines: exception.split: %cleanup.split = landingpad i8 cleanup br label %exception.cont exception: %cleanup.orig = landingpad i8 cleanup br label %exception.cont exception.cont: %cleanup = phi i8 [ %cleanup.split, %exception_split ], [ %cleanup.orig, %exception ] I didn't bother actually implementing that, seeing as how nobody noticed the existing codegen being broken in the last four years, so clearly nobody actually needs this function to work with EH edges. Just return nullptr instead.
After llvm#137799 and llvm#137816, instruction uses of BasicBlocks are always terminators, so assert that instead of checking it.
…7931) After llvm/llvm-project#137799 and llvm/llvm-project#137816, instruction uses of BasicBlocks are always terminators, so assert that instead of checking it.
…lvm#137816) d81d9e8 changed SplitEdge() to make use of ehAwareSplitEdge() for critical edges where the target is an eh pad. However, the implementation is incorrect at least for landing pads. What is currently produced for the code in the modified unit test is something like this: continue: invoke void @sink() to label %normal unwind label %new_bb new_bb: %cp = cleanuppad within %exception [] cleanupret from %cp unwind label %exception exception: %cleanup = landingpad i8 cleanup br label %trivial-eh-handler This mixes different exception handling mechanisms in a nonsensical way, and is not well-formed IR. To actually "split" the landingpad edge (for a rather loose definition of "split"), I think we'd have to generate something along these lines: exception.split: %cleanup.split = landingpad i8 cleanup br label %exception.cont exception: %cleanup.orig = landingpad i8 cleanup br label %exception.cont exception.cont: %cleanup = phi i8 [ %cleanup.split, %exception_split ], [ %cleanup.orig, %exception ] I didn't bother actually implementing that, seeing as how nobody noticed the existing codegen being broken in the last four years, so clearly nobody actually needs this function to work with EH edges. Just return nullptr instead.
After llvm#137799 and llvm#137816, instruction uses of BasicBlocks are always terminators, so assert that instead of checking it.
…lvm#137816) d81d9e8 changed SplitEdge() to make use of ehAwareSplitEdge() for critical edges where the target is an eh pad. However, the implementation is incorrect at least for landing pads. What is currently produced for the code in the modified unit test is something like this: continue: invoke void @sink() to label %normal unwind label %new_bb new_bb: %cp = cleanuppad within %exception [] cleanupret from %cp unwind label %exception exception: %cleanup = landingpad i8 cleanup br label %trivial-eh-handler This mixes different exception handling mechanisms in a nonsensical way, and is not well-formed IR. To actually "split" the landingpad edge (for a rather loose definition of "split"), I think we'd have to generate something along these lines: exception.split: %cleanup.split = landingpad i8 cleanup br label %exception.cont exception: %cleanup.orig = landingpad i8 cleanup br label %exception.cont exception.cont: %cleanup = phi i8 [ %cleanup.split, %exception_split ], [ %cleanup.orig, %exception ] I didn't bother actually implementing that, seeing as how nobody noticed the existing codegen being broken in the last four years, so clearly nobody actually needs this function to work with EH edges. Just return nullptr instead.
After llvm#137799 and llvm#137816, instruction uses of BasicBlocks are always terminators, so assert that instead of checking it.
d81d9e8 changed SplitEdge() to make use of ehAwareSplitEdge() for critical edges where the target is an eh pad. However, the implementation is incorrect at least for landing pads. What is currently produced for the code in the modified unit test is something like this:
This mixes different exception handling mechanisms in a nonsensical way, and is not well-formed IR. To actually "split" the landingpad edge (for a rather loose definition of "split"), I think we'd have to generate something along these lines:
I didn't bother actually implementing that, seeing as how nobody noticed the existing codegen being broken in the last four years, so clearly nobody actually needs this function to work with EH edges. Just return nullptr instead.