diff --git a/llvm/include/llvm/BasicBlock.h b/llvm/include/llvm/BasicBlock.h index 10f2577869ec..11afa4047787 100644 --- a/llvm/include/llvm/BasicBlock.h +++ b/llvm/include/llvm/BasicBlock.h @@ -240,6 +240,10 @@ public: /// hasAddressTaken - returns true if there are any uses of this basic block /// other than direct branches, switches, etc. to it. bool hasAddressTaken() const { return SubclassData != 0; } + + /// removeDeadBlockAddress - If there is a blockaddress node for this basic + /// block, try to remove it and any dead constant users of it. + void removeDeadBlockAddress(); private: /// AdjustBlockAddressRefCount - BasicBlock stores the number of BlockAddress /// objects using it. This is almost always 0, sometimes one, possibly but diff --git a/llvm/lib/VMCore/Globals.cpp b/llvm/lib/VMCore/Globals.cpp index d18a20162dd9..763fc721e09b 100644 --- a/llvm/lib/VMCore/Globals.cpp +++ b/llvm/lib/VMCore/Globals.cpp @@ -75,6 +75,14 @@ void GlobalValue::removeDeadConstantUsers() const { } } +/// removeDeadBlockAddress - If there is a blockaddress node for this basic +/// block, try to remove it and any dead constant users of it. +void BasicBlock::removeDeadBlockAddress() { + if (!hasAddressTaken()) return; + removeDeadUsersOfConstant(BlockAddress::get(this)); +} + + /// Override destroyConstant to make sure it doesn't get called on /// GlobalValue's because they shouldn't be treated like other constants. void GlobalValue::destroyConstant() { diff --git a/llvm/lib/VMCore/Verifier.cpp b/llvm/lib/VMCore/Verifier.cpp index fc90148b8b5a..6b10d69ac5ed 100644 --- a/llvm/lib/VMCore/Verifier.cpp +++ b/llvm/lib/VMCore/Verifier.cpp @@ -658,8 +658,13 @@ void Verifier::visitFunction(Function &F) { BasicBlock *Entry = &F.getEntryBlock(); Assert1(pred_begin(Entry) == pred_end(Entry), "Entry block to function must not have predecessors!", Entry); - Assert1(!Entry->hasAddressTaken(), - "blockaddress may not be used with the entry block!", Entry); + + // The address of the entry block cannot be taken, unless it is dead. + if (Entry->hasAddressTaken()) { + Entry->removeDeadBlockAddress(); + Assert1(!Entry->hasAddressTaken(), + "blockaddress may not be used with the entry block!", Entry); + } } // If this function is actually an intrinsic, verify that it is only used in