summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/PowerPC/PPCFastISel.cpp
diff options
context:
space:
mode:
authorHal Finkel <hfinkel@anl.gov>2015-05-23 12:18:10 +0000
committerHal Finkel <hfinkel@anl.gov>2015-05-23 12:18:10 +0000
commit5f2a1379ef0f66a906e4beaa30fa3918cb1779d8 (patch)
treebbd6f8a130e99ada2a43aaba84151b099bfd3218 /llvm/lib/Target/PowerPC/PPCFastISel.cpp
parentb558e5fb654098682531628cac659a76c4d577eb (diff)
downloadbcm5719-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.cpp51
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();
OpenPOWER on IntegriCloud