aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp41
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.