diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -4186,9 +4186,12 @@ /// Get the optimistic edges. virtual const SetVector &getOptimisticEdges() const = 0; - /// Is there in this function call with a unknown Callee. + /// Is there any call with a unknown callee. virtual bool hasUnknownCallee() const = 0; + /// Is there any call with a unknown callee, excluding any inline asm. + virtual bool hasNonAsmUnknownCallee() const = 0; + /// Iterator for exploring the call graph. AACallEdgeIterator optimisticEdgesBegin() const override { return AACallEdgeIterator(A, getOptimisticEdges().begin()); diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -8443,6 +8443,7 @@ ChangeStatus updateImpl(Attributor &A) override { ChangeStatus Change = ChangeStatus::UNCHANGED; bool OldHasUnknownCallee = HasUnknownCallee; + bool OldHasUnknownCalleeNonAsm = HasUnknownCalleeNonAsm; auto AddCalledFunction = [&](Function *Fn) { if (CalledFunctions.insert(Fn)) { @@ -8459,6 +8460,7 @@ } else { LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n"); HasUnknown = true; + HasUnknownCalleeNonAsm = true; } // Explore all values. @@ -8467,16 +8469,22 @@ // Process any value that we might call. auto ProcessCalledOperand = [&](Value *V, Instruction *Ctx) { - if (!genericValueTraversal(A, IRPosition::value(*V), *this, - HasUnknownCallee, VisitValue, nullptr, - false)) + if (!genericValueTraversal( + A, IRPosition::value(*V), *this, HasUnknownCallee, VisitValue, + nullptr, false)) { // If we haven't gone through all values, assume that there are unknown // callees. HasUnknownCallee = true; + HasUnknownCalleeNonAsm = true; + } }; auto ProcessCallInst = [&](Instruction &Inst) { CallBase &CB = static_cast(Inst); + if (CB.isInlineAsm()) { + HasUnknownCallee = true; + return true; + } // Process callee metadata if available. if (auto *MD = Inst.getMetadata(LLVMContext::MD_callees)) { @@ -8505,12 +8513,16 @@ // Visit all callable instructions. bool UsedAssumedInformation = false; if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this, - UsedAssumedInformation)) + UsedAssumedInformation)) { // If we haven't looked at all call like instructions, assume that there // are unknown callees. HasUnknownCallee = true; + HasUnknownCalleeNonAsm = true; + } + // Track changes. - if (OldHasUnknownCallee != HasUnknownCallee) + if (OldHasUnknownCallee != HasUnknownCallee || + OldHasUnknownCalleeNonAsm != HasUnknownCalleeNonAsm) Change = ChangeStatus::CHANGED; return Change; @@ -8522,6 +8534,10 @@ virtual bool hasUnknownCallee() const override { return HasUnknownCallee; } + virtual bool hasNonAsmUnknownCallee() const override { + return HasUnknownCalleeNonAsm; + } + const std::string getAsStr() const override { return "CallEdges[" + std::to_string(HasUnknownCallee) + "," + std::to_string(CalledFunctions.size()) + "]"; @@ -8532,8 +8548,11 @@ /// Optimistic set of functions that might be called by this function. SetVector CalledFunctions; - /// Does this function have a call to a function that we don't know about. + /// Is there any call with a unknown callee. bool HasUnknownCallee = false; + + /// Is there any call with a unknown callee, excluding any inline asm. + bool HasUnknownCalleeNonAsm = false; }; struct AAFunctionReachabilityFunction : public AAFunctionReachability {