diff options
author | Hal Finkel <hfinkel@anl.gov> | 2015-05-23 12:18:10 +0000 |
---|---|---|
committer | Hal Finkel <hfinkel@anl.gov> | 2015-05-23 12:18:10 +0000 |
commit | 5f2a1379ef0f66a906e4beaa30fa3918cb1779d8 (patch) | |
tree | bbd6f8a130e99ada2a43aaba84151b099bfd3218 /llvm/lib/Target/PowerPC/PPCFastISel.cpp | |
parent | b558e5fb654098682531628cac659a76c4d577eb (diff) | |
download | bcm5719-llvm-5f2a1379ef0f66a906e4beaa30fa3918cb1779d8.tar.gz bcm5719-llvm-5f2a1379ef0f66a906e4beaa30fa3918cb1779d8.zip |
[PowerPC] Fix fast-isel when compare is split from branch
When the compare feeding a branch was in a different BB from the branch, we'd
try to "regenerate" the compare in the block with the branch, possibly trying
to make use of values not available there. Copy a page from AArch64's play book
here to fix the problem (at least in terms of correctness).
Fixes PR23640.
llvm-svn: 238097
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCFastISel.cpp')
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCFastISel.cpp | 51 |
1 files changed, 32 insertions, 19 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCFastISel.cpp b/llvm/lib/Target/PowerPC/PPCFastISel.cpp index 002616babd4..0b8e23c4ebf 100644 --- a/llvm/lib/Target/PowerPC/PPCFastISel.cpp +++ b/llvm/lib/Target/PowerPC/PPCFastISel.cpp @@ -144,6 +144,7 @@ class PPCFastISel final : public FastISel { private: bool isTypeLegal(Type *Ty, MVT &VT); bool isLoadTypeLegal(Type *Ty, MVT &VT); + bool isValueAvailable(const Value *V) const; bool isVSFRCRegister(unsigned Register) const { return MRI.getRegClass(Register)->getID() == PPC::VSFRCRegClassID; } @@ -283,6 +284,17 @@ bool PPCFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) { return false; } +bool PPCFastISel::isValueAvailable(const Value *V) const { + if (!isa<Instruction>(V)) + return true; + + const auto *I = cast<Instruction>(V); + if (FuncInfo.MBBMap[I->getParent()] == FuncInfo.MBB) + return true; + + return false; +} + // Given a value Obj, create an Address object Addr that represents its // address. Return false if we can't handle it. bool PPCFastISel::PPCComputeAddress(const Value *Obj, Address &Addr) { @@ -731,30 +743,31 @@ bool PPCFastISel::SelectBranch(const Instruction *I) { // For now, just try the simplest case where it's fed by a compare. if (const CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition())) { - Optional<PPC::Predicate> OptPPCPred = getComparePred(CI->getPredicate()); - if (!OptPPCPred) - return false; - - PPC::Predicate PPCPred = OptPPCPred.getValue(); + if (isValueAvailable(CI)) { + Optional<PPC::Predicate> OptPPCPred = getComparePred(CI->getPredicate()); + if (!OptPPCPred) + return false; - // Take advantage of fall-through opportunities. - if (FuncInfo.MBB->isLayoutSuccessor(TBB)) { - std::swap(TBB, FBB); - PPCPred = PPC::InvertPredicate(PPCPred); - } + PPC::Predicate PPCPred = OptPPCPred.getValue(); - unsigned CondReg = createResultReg(&PPC::CRRCRegClass); + // Take advantage of fall-through opportunities. + if (FuncInfo.MBB->isLayoutSuccessor(TBB)) { + std::swap(TBB, FBB); + PPCPred = PPC::InvertPredicate(PPCPred); + } - if (!PPCEmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned(), - CondReg)) - return false; + unsigned CondReg = createResultReg(&PPC::CRRCRegClass); - BuildMI(*BrBB, FuncInfo.InsertPt, DbgLoc, TII.get(PPC::BCC)) - .addImm(PPCPred).addReg(CondReg).addMBB(TBB); - fastEmitBranch(FBB, DbgLoc); - FuncInfo.MBB->addSuccessor(TBB); - return true; + if (!PPCEmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned(), + CondReg)) + return false; + BuildMI(*BrBB, FuncInfo.InsertPt, DbgLoc, TII.get(PPC::BCC)) + .addImm(PPCPred).addReg(CondReg).addMBB(TBB); + fastEmitBranch(FBB, DbgLoc); + FuncInfo.MBB->addSuccessor(TBB); + return true; + } } else if (const ConstantInt *CI = dyn_cast<ConstantInt>(BI->getCondition())) { uint64_t Imm = CI->getZExtValue(); |