diff options
| author | Bradley Smith <bradley.smith@arm.com> | 2014-10-14 14:02:41 +0000 |
|---|---|---|
| committer | Bradley Smith <bradley.smith@arm.com> | 2014-10-14 14:02:41 +0000 |
| commit | 698e08f4cf4898c5966217b706d43fb2f764a7f5 (patch) | |
| tree | beccfcc1214b1ebc1145e3b58326545eee3021b3 /llvm/lib/Target/AArch64/AArch64A53Fix835769.cpp | |
| parent | 9e984c513758478c1484d08ecb152bc0dbffa314 (diff) | |
| download | bcm5719-llvm-698e08f4cf4898c5966217b706d43fb2f764a7f5.tar.gz bcm5719-llvm-698e08f4cf4898c5966217b706d43fb2f764a7f5.zip | |
[AArch64] Fix crash with empty/pseudo-only blocks in A53 erratum (835769) workaround
llvm-svn: 219684
Diffstat (limited to 'llvm/lib/Target/AArch64/AArch64A53Fix835769.cpp')
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64A53Fix835769.cpp | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64A53Fix835769.cpp b/llvm/lib/Target/AArch64/AArch64A53Fix835769.cpp index 0fde69b1ae3..852a6352af0 100644 --- a/llvm/lib/Target/AArch64/AArch64A53Fix835769.cpp +++ b/llvm/lib/Target/AArch64/AArch64A53Fix835769.cpp @@ -123,20 +123,20 @@ AArch64A53Fix835769::runOnMachineFunction(MachineFunction &F) { // Return the block that was fallen through to get to MBB, if any, // otherwise nullptr. -static MachineBasicBlock *getBBFallenThrough(MachineBasicBlock &MBB, +static MachineBasicBlock *getBBFallenThrough(MachineBasicBlock *MBB, const TargetInstrInfo *TII) { // Get the previous machine basic block in the function. - MachineFunction::iterator MBBI = MBB; + MachineFunction::iterator MBBI = *MBB; // Can't go off top of function. - if (MBBI == MBB.getParent()->begin()) + if (MBBI == MBB->getParent()->begin()) return nullptr; MachineBasicBlock *TBB = nullptr, *FBB = nullptr; SmallVector<MachineOperand, 2> Cond; MachineBasicBlock *PrevBB = std::prev(MBBI); - for (MachineBasicBlock *S : MBB.predecessors()) + for (MachineBasicBlock *S : MBB->predecessors()) if (S == PrevBB && !TII->AnalyzeBranch(*PrevBB, TBB, FBB, Cond) && !TBB && !FBB) return S; @@ -144,13 +144,25 @@ static MachineBasicBlock *getBBFallenThrough(MachineBasicBlock &MBB, return nullptr; } -static MachineInstr *getLastNonPseudo(MachineBasicBlock *MBB) { - for (auto I = MBB->rbegin(), E = MBB->rend(); I != E; ++I) { - if (!I->isPseudo()) - return &*I; +// Iterate through fallen through blocks trying to find a previous non-pseudo if +// there is one, otherwise return nullptr. Only look for instructions in +// previous blocks, not the current block, since we only use this to look at +// previous blocks. +static MachineInstr *getLastNonPseudo(MachineBasicBlock &MBB, + const TargetInstrInfo *TII) { + MachineBasicBlock *FMBB = &MBB; + + // If there is no non-pseudo in the current block, loop back around and try + // the previous block (if there is one). + while ((FMBB = getBBFallenThrough(FMBB, TII))) { + for (auto I = FMBB->rbegin(), E = FMBB->rend(); I != E; ++I) { + if (!I->isPseudo()) + return &*I; + } } - llvm_unreachable("Expected to find a non-pseudo instruction"); + // There was no previous non-pseudo in the fallen through blocks + return nullptr; } static void insertNopBeforeInstruction(MachineBasicBlock &MBB, MachineInstr* MI, @@ -158,12 +170,10 @@ static void insertNopBeforeInstruction(MachineBasicBlock &MBB, MachineInstr* MI, // If we are the first instruction of the block, put the NOP at the end of // the previous fallthrough block if (MI == &MBB.front()) { - MachineBasicBlock *PMBB = getBBFallenThrough(MBB, TII); - assert(PMBB && "Expected basic block"); - MachineInstr *I = getLastNonPseudo(PMBB); + MachineInstr *I = getLastNonPseudo(MBB, TII); assert(I && "Expected instruction"); DebugLoc DL = I->getDebugLoc(); - BuildMI(PMBB, DL, TII->get(AArch64::HINT)).addImm(0); + BuildMI(I->getParent(), DL, TII->get(AArch64::HINT)).addImm(0); } else { DebugLoc DL = MI->getDebugLoc(); @@ -186,8 +196,9 @@ AArch64A53Fix835769::runOnBasicBlock(MachineBasicBlock &MBB) { unsigned Idx = 0; MachineInstr *PrevInstr = nullptr; - if (MachineBasicBlock *PMBB = getBBFallenThrough(MBB, TII)) - PrevInstr = getLastNonPseudo(PMBB); + // Try and find the last non-pseudo instruction in any fallen through blocks, + // if there isn't one, then we use nullptr to represent that. + PrevInstr = getLastNonPseudo(MBB, TII); for (auto &MI : MBB) { MachineInstr *CurrInstr = &MI; |

