1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 13:11:39 +01:00

[GlobalISel][IRTranslator] Fix some PHI bugs related to jump tables when optimizations are used.

The new switch lowering code that tries to generate jump tables and range checks
were tested at -O0 on arm64, but on -O3 the generic switch lowering code goes to
town on trying to generate optimized lowerings, e.g. multiple jump tables, range
checks etc. This exposed bugs in the way PHI nodes are handled because the CFG
looks even stranger after all of this is done.

llvm-svn: 364613
This commit is contained in:
Amara Emerson 2019-06-27 23:56:34 +00:00
parent a741964fe2
commit 77bbd4bbf8
3 changed files with 1169 additions and 16 deletions

View File

@ -290,8 +290,7 @@ private:
// Begin switch lowering functions. // Begin switch lowering functions.
bool emitJumpTableHeader(SwitchCG::JumpTable &JT, bool emitJumpTableHeader(SwitchCG::JumpTable &JT,
SwitchCG::JumpTableHeader &JTH, SwitchCG::JumpTableHeader &JTH,
MachineBasicBlock *SwitchBB, MachineBasicBlock *HeaderBB);
MachineIRBuilder &MIB);
void emitJumpTable(SwitchCG::JumpTable &JT, MachineBasicBlock *MBB); void emitJumpTable(SwitchCG::JumpTable &JT, MachineBasicBlock *MBB);
void emitSwitchCase(SwitchCG::CaseBlock &CB, MachineBasicBlock *SwitchBB, void emitSwitchCase(SwitchCG::CaseBlock &CB, MachineBasicBlock *SwitchBB,
@ -299,6 +298,7 @@ private:
bool lowerJumpTableWorkItem(SwitchCG::SwitchWorkListItem W, bool lowerJumpTableWorkItem(SwitchCG::SwitchWorkListItem W,
MachineBasicBlock *SwitchMBB, MachineBasicBlock *SwitchMBB,
MachineBasicBlock *CurMBB,
MachineBasicBlock *DefaultMBB, MachineBasicBlock *DefaultMBB,
MachineIRBuilder &MIB, MachineIRBuilder &MIB,
MachineFunction::iterator BBI, MachineFunction::iterator BBI,

View File

@ -519,9 +519,10 @@ void IRTranslator::emitJumpTable(SwitchCG::JumpTable &JT,
bool IRTranslator::emitJumpTableHeader(SwitchCG::JumpTable &JT, bool IRTranslator::emitJumpTableHeader(SwitchCG::JumpTable &JT,
SwitchCG::JumpTableHeader &JTH, SwitchCG::JumpTableHeader &JTH,
MachineBasicBlock *SwitchBB, MachineBasicBlock *HeaderBB) {
MachineIRBuilder &MIB) { MachineIRBuilder MIB(*HeaderBB->getParent());
DebugLoc dl = MIB.getDebugLoc(); MIB.setMBB(*HeaderBB);
MIB.setDebugLoc(CurBuilder->getDebugLoc());
const Value &SValue = *JTH.SValue; const Value &SValue = *JTH.SValue;
// Subtract the lowest switch case value from the value being switched on. // Subtract the lowest switch case value from the value being switched on.
@ -539,7 +540,7 @@ bool IRTranslator::emitJumpTableHeader(SwitchCG::JumpTable &JT,
JT.Reg = Sub.getReg(0); JT.Reg = Sub.getReg(0);
if (JTH.OmitRangeCheck) { if (JTH.OmitRangeCheck) {
if (JT.MBB != SwitchBB->getNextNode()) if (JT.MBB != HeaderBB->getNextNode())
MIB.buildBr(*JT.MBB); MIB.buildBr(*JT.MBB);
return true; return true;
} }
@ -555,7 +556,7 @@ bool IRTranslator::emitJumpTableHeader(SwitchCG::JumpTable &JT,
auto BrCond = MIB.buildBrCond(Cmp.getReg(0), *JT.Default); auto BrCond = MIB.buildBrCond(Cmp.getReg(0), *JT.Default);
// Avoid emitting unnecessary branches to the next block. // Avoid emitting unnecessary branches to the next block.
if (JT.MBB != SwitchBB->getNextNode()) if (JT.MBB != HeaderBB->getNextNode())
BrCond = MIB.buildBr(*JT.MBB); BrCond = MIB.buildBr(*JT.MBB);
return true; return true;
} }
@ -618,8 +619,10 @@ void IRTranslator::emitSwitchCase(SwitchCG::CaseBlock &CB,
addSuccessorWithProb(CB.ThisBB, CB.FalseBB, CB.FalseProb); addSuccessorWithProb(CB.ThisBB, CB.FalseBB, CB.FalseProb);
CB.ThisBB->normalizeSuccProbs(); CB.ThisBB->normalizeSuccProbs();
addMachineCFGPred({SwitchBB->getBasicBlock(), CB.FalseBB->getBasicBlock()}, // if (SwitchBB->getBasicBlock() != CB.FalseBB->getBasicBlock())
CB.ThisBB); addMachineCFGPred({SwitchBB->getBasicBlock(), CB.FalseBB->getBasicBlock()},
CB.ThisBB);
// If the lhs block is the next block, invert the condition so that we can // If the lhs block is the next block, invert the condition so that we can
// fall through to the lhs instead of the rhs block. // fall through to the lhs instead of the rhs block.
if (CB.TrueBB == CB.ThisBB->getNextNode()) { if (CB.TrueBB == CB.ThisBB->getNextNode()) {
@ -636,6 +639,7 @@ void IRTranslator::emitSwitchCase(SwitchCG::CaseBlock &CB,
bool IRTranslator::lowerJumpTableWorkItem(SwitchCG::SwitchWorkListItem W, bool IRTranslator::lowerJumpTableWorkItem(SwitchCG::SwitchWorkListItem W,
MachineBasicBlock *SwitchMBB, MachineBasicBlock *SwitchMBB,
MachineBasicBlock *CurMBB,
MachineBasicBlock *DefaultMBB, MachineBasicBlock *DefaultMBB,
MachineIRBuilder &MIB, MachineIRBuilder &MIB,
MachineFunction::iterator BBI, MachineFunction::iterator BBI,
@ -649,7 +653,6 @@ bool IRTranslator::lowerJumpTableWorkItem(SwitchCG::SwitchWorkListItem W,
JumpTableHeader *JTH = &SL->JTCases[I->JTCasesIndex].first; JumpTableHeader *JTH = &SL->JTCases[I->JTCasesIndex].first;
SwitchCG::JumpTable *JT = &SL->JTCases[I->JTCasesIndex].second; SwitchCG::JumpTable *JT = &SL->JTCases[I->JTCasesIndex].second;
BranchProbability DefaultProb = W.DefaultProb; BranchProbability DefaultProb = W.DefaultProb;
MachineBasicBlock *CurMBB = W.MBB;
// The jump block hasn't been inserted yet; insert it here. // The jump block hasn't been inserted yet; insert it here.
MachineBasicBlock *JumpMBB = JT->MBB; MachineBasicBlock *JumpMBB = JT->MBB;
@ -659,7 +662,7 @@ bool IRTranslator::lowerJumpTableWorkItem(SwitchCG::SwitchWorkListItem W,
// to keep track of it as a machine predecessor to the default block, // to keep track of it as a machine predecessor to the default block,
// otherwise we lose the phi edges. // otherwise we lose the phi edges.
addMachineCFGPred({SwitchMBB->getBasicBlock(), DefaultMBB->getBasicBlock()}, addMachineCFGPred({SwitchMBB->getBasicBlock(), DefaultMBB->getBasicBlock()},
SwitchMBB); CurMBB);
addMachineCFGPred({SwitchMBB->getBasicBlock(), DefaultMBB->getBasicBlock()}, addMachineCFGPred({SwitchMBB->getBasicBlock(), DefaultMBB->getBasicBlock()},
JumpMBB); JumpMBB);
@ -677,7 +680,10 @@ bool IRTranslator::lowerJumpTableWorkItem(SwitchCG::SwitchWorkListItem W,
FallthroughProb -= DefaultProb / 2; FallthroughProb -= DefaultProb / 2;
JumpMBB->setSuccProbability(SI, DefaultProb / 2); JumpMBB->setSuccProbability(SI, DefaultProb / 2);
JumpMBB->normalizeSuccProbs(); JumpMBB->normalizeSuccProbs();
break; } else {
// Also record edges from the jump table block to it's successors.
addMachineCFGPred({SwitchMBB->getBasicBlock(), (*SI)->getBasicBlock()},
JumpMBB);
} }
} }
@ -697,7 +703,7 @@ bool IRTranslator::lowerJumpTableWorkItem(SwitchCG::SwitchWorkListItem W,
// If we're in the right place, emit the jump table header right now. // If we're in the right place, emit the jump table header right now.
if (CurMBB == SwitchMBB) { if (CurMBB == SwitchMBB) {
if (!emitJumpTableHeader(*JT, *JTH, SwitchMBB, MIB)) if (!emitJumpTableHeader(*JT, *JTH, CurMBB))
return false; return false;
JTH->Emitted = true; JTH->Emitted = true;
} }
@ -801,7 +807,7 @@ bool IRTranslator::lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W,
return false; // Bit tests currently unimplemented. return false; // Bit tests currently unimplemented.
} }
case CC_JumpTable: { case CC_JumpTable: {
if (!lowerJumpTableWorkItem(W, SwitchMBB, DefaultMBB, MIB, BBI, if (!lowerJumpTableWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
UnhandledProbs, I, Fallthrough, UnhandledProbs, I, Fallthrough,
FallthroughUnreachable)) { FallthroughUnreachable)) {
LLVM_DEBUG(dbgs() << "Failed to lower jump table"); LLVM_DEBUG(dbgs() << "Failed to lower jump table");
@ -2030,6 +2036,7 @@ void IRTranslator::finishPendingPhis() {
for (auto &Phi : PendingPHIs) { for (auto &Phi : PendingPHIs) {
const PHINode *PI = Phi.first; const PHINode *PI = Phi.first;
ArrayRef<MachineInstr *> ComponentPHIs = Phi.second; ArrayRef<MachineInstr *> ComponentPHIs = Phi.second;
MachineBasicBlock *PhiMBB = ComponentPHIs[0]->getParent();
EntryBuilder->setDebugLoc(PI->getDebugLoc()); EntryBuilder->setDebugLoc(PI->getDebugLoc());
#ifndef NDEBUG #ifndef NDEBUG
Verifier.setCurrentInst(PI); Verifier.setCurrentInst(PI);
@ -2040,7 +2047,7 @@ void IRTranslator::finishPendingPhis() {
auto IRPred = PI->getIncomingBlock(i); auto IRPred = PI->getIncomingBlock(i);
ArrayRef<Register> ValRegs = getOrCreateVRegs(*PI->getIncomingValue(i)); ArrayRef<Register> ValRegs = getOrCreateVRegs(*PI->getIncomingValue(i));
for (auto Pred : getMachinePredBBs({IRPred, PI->getParent()})) { for (auto Pred : getMachinePredBBs({IRPred, PI->getParent()})) {
if (SeenPreds.count(Pred)) if (SeenPreds.count(Pred) || !PhiMBB->isPredecessor(Pred))
continue; continue;
SeenPreds.insert(Pred); SeenPreds.insert(Pred);
for (unsigned j = 0; j < ValRegs.size(); ++j) { for (unsigned j = 0; j < ValRegs.size(); ++j) {
@ -2147,8 +2154,13 @@ bool IRTranslator::translate(const Constant &C, Register Reg) {
} }
void IRTranslator::finalizeBasicBlock() { void IRTranslator::finalizeBasicBlock() {
for (auto &JTCase : SL->JTCases) for (auto &JTCase : SL->JTCases) {
// Emit header first, if it wasn't already emitted.
if (!JTCase.first.Emitted)
emitJumpTableHeader(JTCase.second, JTCase.first, JTCase.first.HeaderBB);
emitJumpTable(JTCase.second, JTCase.second.MBB); emitJumpTable(JTCase.second, JTCase.second.MBB);
}
SL->JTCases.clear(); SL->JTCases.clear();
} }

File diff suppressed because it is too large Load Diff