Skip to content

Commit

Permalink
[InstCombine] Directly replace instr in foldIntegerTypedPHI() (NFCI)
Browse files Browse the repository at this point in the history
Rather than inserting a ptrtoint + inttoptr pair, directly replace
the inttoptr with the new phi node. This ensures that no other
transform can undo it before the pair gets folded away.

This avoids the infinite loop when combined with D134954.

This is NFCI in the sense that it shouldn't make a difference, but
could due to different worklist order.
  • Loading branch information
nikic committed Oct 5, 2022
1 parent e035f03 commit 1189770
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 20 deletions.
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/InstCombine/InstCombineInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,7 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
/// If an integer typed PHI has only one use which is an IntToPtr operation,
/// replace the PHI with an existing pointer typed PHI if it exists. Otherwise
/// insert a new pointer typed PHI and replace the original one.
Instruction *foldIntegerTypedPHI(PHINode &PN);
bool foldIntegerTypedPHI(PHINode &PN);

/// Helper function for FoldPHIArgXIntoPHI() to set debug location for the
/// folded operation.
Expand Down
44 changes: 25 additions & 19 deletions llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,15 @@ void InstCombinerImpl::PHIArgMergedDebugLoc(Instruction *Inst, PHINode &PN) {
// ptr_val_inc = ...
// ...
//
Instruction *InstCombinerImpl::foldIntegerTypedPHI(PHINode &PN) {
bool InstCombinerImpl::foldIntegerTypedPHI(PHINode &PN) {
if (!PN.getType()->isIntegerTy())
return nullptr;
return false;
if (!PN.hasOneUse())
return nullptr;
return false;

auto *IntToPtr = dyn_cast<IntToPtrInst>(PN.user_back());
if (!IntToPtr)
return nullptr;
return false;

// Check if the pointer is actually used as pointer:
auto HasPointerUse = [](Instruction *IIP) {
Expand All @@ -131,11 +131,11 @@ Instruction *InstCombinerImpl::foldIntegerTypedPHI(PHINode &PN) {
};

if (!HasPointerUse(IntToPtr))
return nullptr;
return false;

if (DL.getPointerSizeInBits(IntToPtr->getAddressSpace()) !=
DL.getTypeSizeInBits(IntToPtr->getOperand(0)->getType()))
return nullptr;
return false;

SmallVector<Value *, 4> AvailablePtrVals;
for (auto Incoming : zip(PN.blocks(), PN.incoming_values())) {
Expand Down Expand Up @@ -174,10 +174,10 @@ Instruction *InstCombinerImpl::foldIntegerTypedPHI(PHINode &PN) {
// For a single use integer load:
auto *LoadI = dyn_cast<LoadInst>(Arg);
if (!LoadI)
return nullptr;
return false;

if (!LoadI->hasOneUse())
return nullptr;
return false;

// Push the integer typed Load instruction into the available
// value set, and fix it up later when the pointer typed PHI
Expand All @@ -194,7 +194,7 @@ Instruction *InstCombinerImpl::foldIntegerTypedPHI(PHINode &PN) {
for (PHINode &PtrPHI : BB->phis()) {
// FIXME: consider handling this in AggressiveInstCombine
if (NumPhis++ > MaxNumPhis)
return nullptr;
return false;
if (&PtrPHI == &PN || PtrPHI.getType() != IntToPtr->getType())
continue;
if (any_of(zip(PN.blocks(), AvailablePtrVals),
Expand All @@ -211,16 +211,19 @@ Instruction *InstCombinerImpl::foldIntegerTypedPHI(PHINode &PN) {
if (MatchingPtrPHI) {
assert(MatchingPtrPHI->getType() == IntToPtr->getType() &&
"Phi's Type does not match with IntToPtr");
// The PtrToCast + IntToPtr will be simplified later
return CastInst::CreateBitOrPointerCast(MatchingPtrPHI,
IntToPtr->getOperand(0)->getType());
// Explicitly replace the inttoptr (rather than inserting a ptrtoint) here,
// to make sure another transform can't undo it in the meantime.
replaceInstUsesWith(*IntToPtr, MatchingPtrPHI);
eraseInstFromFunction(*IntToPtr);
eraseInstFromFunction(PN);
return true;
}

// If it requires a conversion for every PHI operand, do not do it.
if (all_of(AvailablePtrVals, [&](Value *V) {
return (V->getType() != IntToPtr->getType()) || isa<IntToPtrInst>(V);
}))
return nullptr;
return false;

// If any of the operand that requires casting is a terminator
// instruction, do not do it. Similarly, do not do the transform if the value
Expand All @@ -239,7 +242,7 @@ Instruction *InstCombinerImpl::foldIntegerTypedPHI(PHINode &PN) {
return true;
return false;
}))
return nullptr;
return false;

PHINode *NewPtrPHI = PHINode::Create(
IntToPtr->getType(), PN.getNumIncomingValues(), PN.getName() + ".ptr");
Expand Down Expand Up @@ -290,9 +293,12 @@ Instruction *InstCombinerImpl::foldIntegerTypedPHI(PHINode &PN) {
NewPtrPHI->addIncoming(CI, IncomingBB);
}

// The PtrToCast + IntToPtr will be simplified later
return CastInst::CreateBitOrPointerCast(NewPtrPHI,
IntToPtr->getOperand(0)->getType());
// Explicitly replace the inttoptr (rather than inserting a ptrtoint) here,
// to make sure another transform can't undo it in the meantime.
replaceInstUsesWith(*IntToPtr, NewPtrPHI);
eraseInstFromFunction(*IntToPtr);
eraseInstFromFunction(PN);
return true;
}

// Remove RoundTrip IntToPtr/PtrToInt Cast on PHI-Operand and
Expand Down Expand Up @@ -1412,8 +1418,8 @@ Instruction *InstCombinerImpl::visitPHINode(PHINode &PN) {
// this PHI only has a single use (a PHI), and if that PHI only has one use (a
// PHI)... break the cycle.
if (PN.hasOneUse()) {
if (Instruction *Result = foldIntegerTypedPHI(PN))
return Result;
if (foldIntegerTypedPHI(PN))
return nullptr;

Instruction *PHIUser = cast<Instruction>(PN.user_back());
if (PHINode *PU = dyn_cast<PHINode>(PHIUser)) {
Expand Down

0 comments on commit 1189770

Please sign in to comment.