diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2022-12-02 18:30:19 -0500 |
---|---|---|
committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2022-12-05 21:41:59 -0500 |
commit | 0a67e771f6d21b1232c40f226c4eee48c3527210 (patch) | |
tree | a311e0ac462c28e45f3c5366088cbea0933962cb /llvm/lib/IR/Function.cpp | |
parent | 6392cf331a9b7ab85f0c37b3a1468bc7f1d14a0b (diff) | |
download | llvm-0a67e771f6d21b1232c40f226c4eee48c3527210.zip llvm-0a67e771f6d21b1232c40f226c4eee48c3527210.tar.gz llvm-0a67e771f6d21b1232c40f226c4eee48c3527210.tar.bz2 |
CallGraph: Fix IgnoreAssumeLikeCalls option to Function::hasAddressTaken
This was added in 29e2d9461a91b and likely never worked in a useful
way.
The test added for it fails when converted to opaque pointers, since
the lifetime intrinsic now directly uses the address. The code was
only trying to handle a user indirectly through a bitcast
instruction. That would never have been useful; a bitcast of a global
value would be folded to a ConstantExpr cast.
I also don't understand why it was special casing use_empty on the
cast. Relax the check to be either BitCastOperator or
AddrSpaceCastOperator. In practice, BitCastOperator won't appear
today.
I believe the change in parallel_deletion_cg_update is a correct
improvement but I didn't fully follow it. .omp_outlined..0 is used in
a constant expression cast to a call which ends up getting deleted.
Diffstat (limited to 'llvm/lib/IR/Function.cpp')
-rw-r--r-- | llvm/lib/IR/Function.cpp | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index 9912e1a..792e714 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -1876,6 +1876,10 @@ std::optional<Function *> Intrinsic::remangleIntrinsicFunction(Function *F) { return NewDecl; } +static bool isPointerCastOperator(const User *U) { + return isa<AddrSpaceCastOperator>(U) || isa<BitCastOperator>(U); +} + /// hasAddressTaken - returns true if there are any uses of this function /// other than direct calls or invokes to it. Optionally ignores callback /// uses, assume like pointer annotation calls, and references in llvm.used @@ -1897,17 +1901,15 @@ bool Function::hasAddressTaken(const User **PutOffender, const auto *Call = dyn_cast<CallBase>(FU); if (!Call) { - if (IgnoreAssumeLikeCalls) { - if (const auto *FI = dyn_cast<Instruction>(FU)) { - if (FI->isCast() && !FI->user_empty() && - llvm::all_of(FU->users(), [](const User *U) { - if (const auto *I = dyn_cast<IntrinsicInst>(U)) - return I->isAssumeLikeIntrinsic(); - return false; - })) - continue; - } + if (IgnoreAssumeLikeCalls && isPointerCastOperator(FU) && + all_of(FU->users(), [](const User *U) { + if (const auto *I = dyn_cast<IntrinsicInst>(U)) + return I->isAssumeLikeIntrinsic(); + return false; + })) { + continue; } + if (IgnoreLLVMUsed && !FU->user_empty()) { const User *FUU = FU; if (isa<BitCastOperator>(FU) && FU->hasOneUse() && @@ -1926,6 +1928,13 @@ bool Function::hasAddressTaken(const User **PutOffender, *PutOffender = FU; return true; } + + if (IgnoreAssumeLikeCalls) { + if (const auto *I = dyn_cast<IntrinsicInst>(Call)) + if (I->isAssumeLikeIntrinsic()) + continue; + } + if (!Call->isCallee(&U) || Call->getFunctionType() != getFunctionType()) { if (IgnoreARCAttachedCall && Call->isOperandBundleOfType(LLVMContext::OB_clang_arc_attachedcall, |