[PATCH] D122959: [ARM] Only update the successor edges for immediate predecessors of PrologueMBB.
Zhiyao Ma via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 1 19:51:44 PDT 2022
ZhiyaoMa98 created this revision.
ZhiyaoMa98 added reviewers: asl, ostannard, chill, john.brawn, efriedma.
Herald added subscribers: JDevlieghere, hiraditya, kristof.beyls.
Herald added a project: All.
ZhiyaoMa98 requested review of this revision.
Herald added a project: LLVM.
When adjusting the function prologue for segmented stacks, only update the successor edges of the immediate predecessors of the original prologue.
I encountered a segmentation fault in LLVM while compiling the Rust core targeting `armv7em` with segmented stack enabled. Below is my attempt to fix it. I am not very certain about the correctness of my patch, because I do not fully understand the code.
Looking at the do-while loop
SmallPtrSet<MachineBasicBlock *, 8> BeforePrologueRegion;
SmallVector<MachineBasicBlock *, 2> WalkList;
WalkList.push_back(&PrologueMBB);
do {
MachineBasicBlock *CurMBB = WalkList.pop_back_val();
for (MachineBasicBlock *PredBB : CurMBB->predecessors()) {
if (BeforePrologueRegion.insert(PredBB).second)
WalkList.push_back(PredBB);
}
} while (!WalkList.empty());
it seems `BeforePrologueRegion` contains non-immediate predecessors of `PrologueMBB `.
However, in the following while loop, `ReplaceUsesOfBlockWith` assumes that `MBB` is an immediate predecessor of `PrologueMBB`.
for (MachineBasicBlock *MBB : BeforePrologueRegion) {
// Make sure the LiveIns are still sorted and unique.
MBB->sortUniqueLiveIns();
// Replace the edges to PrologueMBB by edges to the sequences
// we are about to add.
MBB->ReplaceUsesOfBlockWith(&PrologueMBB, AddedBlocks[0]);
}
The assumption comes from the function call chain
MBB->ReplaceUsesOfBlockWith(&PrologueMBB, AddedBlocks[0]);
--> replaceSuccessor(Old, New);
----> Old->removePredecessor(this);
------> assert(I != Predecessors.end()); Predecessors.erase(I);
I ran into this problem when I was compiling Rust core in release mode targeting `armv7em` with segmented stack enabled. The `Predecessors.erase(I);` line led to a segmentation fault.
I fixed the problem by adding the if-continue statement. It still passed all of the tests.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D122959
Files:
llvm/lib/Target/ARM/ARMFrameLowering.cpp
Index: llvm/lib/Target/ARM/ARMFrameLowering.cpp
===================================================================
--- llvm/lib/Target/ARM/ARMFrameLowering.cpp
+++ llvm/lib/Target/ARM/ARMFrameLowering.cpp
@@ -2570,6 +2570,9 @@
for (MachineBasicBlock *MBB : BeforePrologueRegion) {
// Make sure the LiveIns are still sorted and unique.
MBB->sortUniqueLiveIns();
+ // Only update for immediate predecessors.
+ if (!PrologueMBB.isPredecessor(MBB))
+ continue;
// Replace the edges to PrologueMBB by edges to the sequences
// we are about to add.
MBB->ReplaceUsesOfBlockWith(&PrologueMBB, AddedBlocks[0]);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D122959.419918.patch
Type: text/x-patch
Size: 642 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220402/37f075ab/attachment.bin>
More information about the llvm-commits
mailing list