[llvm] 59f49f7 - [IR] Simplify BasicBlock::removePredecessor. NFCI.

Jay Foad via llvm-commits llvm-commits at lists.llvm.org
Wed May 20 00:08:25 PDT 2020


Sorry. I'll revert and then investigate. Those tests passed in my debug build.

Jay.

On Wed, 20 May 2020 at 00:19, Richard Smith via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
>
> Hi, I'm seeing two SimplifyCFG tests crashing after this commit. Backtrace is:
>
> <segfault handler invoked>
>  #5 0x000056442fcb15d4 llvm::PHINode::getBasicBlockIndex(llvm::BasicBlock const*) const
>  #6 0x00005644324808b3 (anonymous namespace)::SimplifyCFGOpt::simplifyCommonResume(llvm::ResumeInst*)
>  #7 0x000056443246e65c (anonymous namespace)::SimplifyCFGOpt::simplifyResume(llvm::ResumeInst*, llvm::IRBuilder<llvm::ConstantFolder, llvm::IRBuilderDefaultInserter>&)
>  #8 0x000056443246cc03 (anonymous namespace)::SimplifyCFGOpt::simplifyOnce(llvm::BasicBlock*)
>  #9 0x000056443246c780 (anonymous namespace)::SimplifyCFGOpt::run(llvm::BasicBlock*)
>
> Failing tests are:
>
> test/Transforms/SimplifyCFG/bug-25299.ll
> test/Transforms/SimplifyCFG/invoke_unwind.ll
>
> On Tue, 19 May 2020 at 11:42, Jay Foad via llvm-commits <llvm-commits at lists.llvm.org> wrote:
>>
>>
>> Author: Jay Foad
>> Date: 2020-05-19T19:34:49+01:00
>> New Revision: 59f49f7ee7f3397e000f7e11facb4a5605cd1cab
>>
>> URL: https://github.com/llvm/llvm-project/commit/59f49f7ee7f3397e000f7e11facb4a5605cd1cab
>> DIFF: https://github.com/llvm/llvm-project/commit/59f49f7ee7f3397e000f7e11facb4a5605cd1cab.diff
>>
>> LOG: [IR] Simplify BasicBlock::removePredecessor. NFCI.
>>
>> Differential Revision: https://reviews.llvm.org/D80141
>>
>> Added:
>>
>>
>> Modified:
>>     llvm/include/llvm/IR/BasicBlock.h
>>     llvm/lib/IR/BasicBlock.cpp
>>
>> Removed:
>>
>>
>>
>> ################################################################################
>> diff  --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h
>> index 1210ed1eb2ef..312d2a0569ad 100644
>> --- a/llvm/include/llvm/IR/BasicBlock.h
>> +++ b/llvm/include/llvm/IR/BasicBlock.h
>> @@ -370,12 +370,8 @@ class BasicBlock final : public Value, // Basic blocks are data objects also
>>    /// except operator delete.
>>    void dropAllReferences();
>>
>> -  /// Notify the BasicBlock that the predecessor \p Pred is no longer able to
>> -  /// reach it.
>> -  ///
>> -  /// This is actually not used to update the Predecessor list, but is actually
>> -  /// used to update the PHI nodes that reside in the block.  Note that this
>> -  /// should be called while the predecessor still refers to this block.
>> +  /// Update PHI nodes in this BasicBlock before removal of predecessor \p Pred.
>> +  /// Note that this function does not actually remove the predecessor.
>>    void removePredecessor(BasicBlock *Pred, bool KeepOneInputPHIs = false);
>>
>>    bool canSplitPredecessors() const;
>>
>> diff  --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp
>> index a9fa7cae92d8..fb4639c675d5 100644
>> --- a/llvm/lib/IR/BasicBlock.cpp
>> +++ b/llvm/lib/IR/BasicBlock.cpp
>> @@ -317,58 +317,31 @@ iterator_range<BasicBlock::phi_iterator> BasicBlock::phis() {
>>    return make_range<phi_iterator>(P, nullptr);
>>  }
>>
>> -/// This method is used to notify a BasicBlock that the
>> -/// specified Predecessor of the block is no longer able to reach it.  This is
>> -/// actually not used to update the Predecessor list, but is actually used to
>> -/// update the PHI nodes that reside in the block.  Note that this should be
>> -/// called while the predecessor still refers to this block.
>> -///
>> +/// Update PHI nodes in this BasicBlock before removal of predecessor \p Pred.
>> +/// Note that this function does not actually remove the predecessor.
>>  void BasicBlock::removePredecessor(BasicBlock *Pred,
>>                                     bool KeepOneInputPHIs) {
>> -  assert((hasNUsesOrMore(16)||// Reduce cost of this assertion for complex CFGs.
>> +  // Use hasNUsesOrMore to bound the cost of this assertion for complex CFGs.
>> +  assert((hasNUsesOrMore(16) ||
>>            find(pred_begin(this), pred_end(this), Pred) != pred_end(this)) &&
>> -         "removePredecessor: BB is not a predecessor!");
>> -
>> -  if (InstList.empty()) return;
>> -  PHINode *APN = dyn_cast<PHINode>(&front());
>> -  if (!APN) return;   // Quick exit.
>> -
>> -  // If there are exactly two predecessors, then we want to nuke the PHI nodes
>> -  // altogether.
>> -  unsigned max_idx = APN->getNumIncomingValues();
>> -  assert(max_idx != 0 && "PHI Node in block with 0 predecessors!?!?!");
>> -
>> -  // <= Two predecessors BEFORE I remove one?
>> -  if (max_idx <= 2 && !KeepOneInputPHIs) {
>> -    // Yup, loop through and nuke the PHI nodes
>> -    while (PHINode *PN = dyn_cast<PHINode>(&front())) {
>> -      // Remove the predecessor first.
>> -      PN->removeIncomingValue(Pred, !KeepOneInputPHIs);
>> -
>> -      // If the PHI _HAD_ two uses, replace PHI node with its now *single* value
>> -      if (max_idx == 2) {
>> -        if (PN->getIncomingValue(0) != PN)
>> -          PN->replaceAllUsesWith(PN->getIncomingValue(0));
>> -        else
>> -          // We are left with an infinite loop with no entries: kill the PHI.
>> -          PN->replaceAllUsesWith(UndefValue::get(PN->getType()));
>> -        getInstList().pop_front();    // Remove the PHI node
>> -      }
>> +         "Pred is not a predecessor!");
>>
>> -      // If the PHI node already only had one entry, it got deleted by
>> -      // removeIncomingValue.
>> -    }
>> -  } else {
>> -    // Okay, now we know that we need to remove predecessor #pred_idx from all
>> -    // PHI nodes.  Iterate over each PHI node fixing them up
>> -    PHINode *PN;
>> -    for (iterator II = begin(); (PN = dyn_cast<PHINode>(II)); ) {
>> -      ++II;
>> -      PN->removeIncomingValue(Pred, false);
>> -      // If all incoming values to the Phi are the same, we can replace the Phi
>> -      // with that value.
>> -      Value* PNV = nullptr;
>> -      if (!KeepOneInputPHIs && (PNV = PN->hasConstantValue())) {
>> +  // Return early if there are no PHI nodes to update.
>> +  if (!isa<PHINode>(begin()))
>> +    return;
>> +  unsigned NumPreds = cast<PHINode>(front()).getNumIncomingValues();
>> +
>> +  // Update all PHI nodes.
>> +  for (iterator II = begin(); isa<PHINode>(II);) {
>> +    PHINode *PN = cast<PHINode>(II++);
>> +    PN->removeIncomingValue(Pred);
>> +    // If we have a single predecessor, removeIncomingValue erased the PHI node
>> +    // itself.
>> +    // FIXME in practice "KeepOneInputPHIs" means "KeepConstantPHIs" and some
>> +    // callers seem to rely on that.
>> +    if (NumPreds > 1 && !KeepOneInputPHIs) {
>> +      if (Value *PNV = PN->hasConstantValue()) {
>> +        // Replace the PHI node with its constant value.
>>          PN->replaceAllUsesWith(PNV);
>>          PN->eraseFromParent();
>>        }
>>
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list