diff options
Diffstat (limited to 'llvm/lib/CodeGen/CodeGenPrepare.cpp')
-rw-r--r-- | llvm/lib/CodeGen/CodeGenPrepare.cpp | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index bbd1f59..e6a7a3e 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -4389,11 +4389,11 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr, SmallPtrSet<Value*, 16> Visited; worklist.push_back(Addr); - // Use a worklist to iteratively look through PHI nodes, and ensure that - // the addressing mode obtained from the non-PHI roots of the graph - // are equivalent. + // Use a worklist to iteratively look through PHI and select nodes, and + // ensure that the addressing mode obtained from the non-PHI/select roots of + // the graph are equivalent. bool AddrModeFound = false; - bool PhiSeen = false; + bool PhiOrSelectSeen = false; SmallVector<Instruction*, 16> AddrModeInsts; ExtAddrMode AddrMode; TypePromotionTransaction TPT(RemovedInsts); @@ -4419,7 +4419,14 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr, if (PHINode *P = dyn_cast<PHINode>(V)) { for (Value *IncValue : P->incoming_values()) worklist.push_back(IncValue); - PhiSeen = true; + PhiOrSelectSeen = true; + continue; + } + // Similar for select. + if (SelectInst *SI = dyn_cast<SelectInst>(V)) { + worklist.push_back(SI->getFalseValue()); + worklist.push_back(SI->getTrueValue()); + PhiOrSelectSeen = true; continue; } @@ -4452,8 +4459,10 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr, TPT.commit(); // If all the instructions matched are already in this BB, don't do anything. - // If we saw Phi node then it is not local definitely. - if (!PhiSeen && none_of(AddrModeInsts, [&](Value *V) { + // If we saw a Phi node then it is not local definitely, and if we saw a select + // then we want to push the address calculation past it even if it's already + // in this BB. + if (!PhiOrSelectSeen && none_of(AddrModeInsts, [&](Value *V) { return IsNonLocalValue(V, MemoryInst->getParent()); })) { DEBUG(dbgs() << "CGP: Found local addrmode: " << AddrMode << "\n"); |