diff options
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp index d687ec654438..6c6351c70e3a 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp @@ -592,8 +592,14 @@ static bool isSafeAndProfitableToSinkLoad(LoadInst *L) { BasicBlock::iterator BBI = L->getIterator(), E = L->getParent()->end(); for (++BBI; BBI != E; ++BBI) - if (BBI->mayWriteToMemory()) + if (BBI->mayWriteToMemory()) { + // Calls that only access inaccessible memory do not block sinking the + // load. + if (auto *CB = dyn_cast<CallBase>(BBI)) + if (CB->onlyAccessesInaccessibleMemory()) + continue; return false; + } // Check for non-address taken alloca. If not address-taken already, it isn't // profitable to do this xform. @@ -1113,7 +1119,7 @@ Instruction *InstCombinerImpl::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) { // If we have no users, they must be all self uses, just nuke the PHI. if (PHIUsers.empty()) - return replaceInstUsesWith(FirstPhi, UndefValue::get(FirstPhi.getType())); + return replaceInstUsesWith(FirstPhi, PoisonValue::get(FirstPhi.getType())); // If this phi node is transformable, create new PHIs for all the pieces // extracted out of it. First, sort the users by their offset and size. @@ -1212,11 +1218,11 @@ Instruction *InstCombinerImpl::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) { } // Replace all the remaining uses of the PHI nodes (self uses and the lshrs) - // with undefs. - Value *Undef = UndefValue::get(FirstPhi.getType()); + // with poison. + Value *Poison = PoisonValue::get(FirstPhi.getType()); for (unsigned i = 1, e = PHIsToSlice.size(); i != e; ++i) - replaceInstUsesWith(*PHIsToSlice[i], Undef); - return replaceInstUsesWith(FirstPhi, Undef); + replaceInstUsesWith(*PHIsToSlice[i], Poison); + return replaceInstUsesWith(FirstPhi, Poison); } static Value *SimplifyUsingControlFlow(InstCombiner &Self, PHINode &PN, @@ -1310,6 +1316,25 @@ Instruction *InstCombinerImpl::visitPHINode(PHINode &PN) { if (Instruction *Result = foldPHIArgOpIntoPHI(PN)) return Result; + // If the incoming values are pointer casts of the same original value, + // replace the phi with a single cast iff we can insert a non-PHI instruction. + if (PN.getType()->isPointerTy() && + PN.getParent()->getFirstInsertionPt() != PN.getParent()->end()) { + Value *IV0 = PN.getIncomingValue(0); + Value *IV0Stripped = IV0->stripPointerCasts(); + // Set to keep track of values known to be equal to IV0Stripped after + // stripping pointer casts. + SmallPtrSet<Value *, 4> CheckedIVs; + CheckedIVs.insert(IV0); + if (IV0 != IV0Stripped && + all_of(PN.incoming_values(), [&CheckedIVs, IV0Stripped](Value *IV) { + return !CheckedIVs.insert(IV).second || + IV0Stripped == IV->stripPointerCasts(); + })) { + return CastInst::CreatePointerCast(IV0Stripped, PN.getType()); + } + } + // If this is a trivial cycle in the PHI node graph, remove it. Basically, if // this PHI only has a single use (a PHI), and if that PHI only has one use (a // PHI)... break the cycle. @@ -1322,7 +1347,7 @@ Instruction *InstCombinerImpl::visitPHINode(PHINode &PN) { SmallPtrSet<PHINode*, 16> PotentiallyDeadPHIs; PotentiallyDeadPHIs.insert(&PN); if (DeadPHICycle(PU, PotentiallyDeadPHIs)) - return replaceInstUsesWith(PN, UndefValue::get(PN.getType())); + return replaceInstUsesWith(PN, PoisonValue::get(PN.getType())); } // If this phi has a single use, and if that use just computes a value for @@ -1334,7 +1359,7 @@ Instruction *InstCombinerImpl::visitPHINode(PHINode &PN) { if (PHIUser->hasOneUse() && (isa<BinaryOperator>(PHIUser) || isa<GetElementPtrInst>(PHIUser)) && PHIUser->user_back() == &PN) { - return replaceInstUsesWith(PN, UndefValue::get(PN.getType())); + return replaceInstUsesWith(PN, PoisonValue::get(PN.getType())); } // When a PHI is used only to be compared with zero, it is safe to replace // an incoming value proved as known nonzero with any non-zero constant. |