aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Function.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR/Function.cpp')
-rw-r--r--llvm/lib/IR/Function.cpp21
1 files changed, 19 insertions, 2 deletions
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index c6932f0..0396fda 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -52,6 +52,7 @@
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Operator.h"
#include "llvm/IR/SymbolTableListTraits.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Use.h"
@@ -1579,10 +1580,12 @@ Optional<Function *> Intrinsic::remangleIntrinsicFunction(Function *F) {
/// hasAddressTaken - returns true if there are any uses of this function
/// other than direct calls or invokes to it. Optionally ignores callback
-/// uses and assume like pointer annotation calls.
+/// uses, assume like pointer annotation calls, and references in llvm.used
+/// and llvm.compiler.used variables.
bool Function::hasAddressTaken(const User **PutOffender,
bool IgnoreCallbackUses,
- bool IgnoreAssumeLikeCalls) const {
+ bool IgnoreAssumeLikeCalls,
+ bool IgnoreLLVMUsed) const {
for (const Use &U : uses()) {
const User *FU = U.getUser();
if (isa<BlockAddress>(FU))
@@ -1607,6 +1610,20 @@ bool Function::hasAddressTaken(const User **PutOffender,
continue;
}
}
+ if (IgnoreLLVMUsed && !FU->user_empty()) {
+ const User *FUU = FU;
+ if (isa<BitCastOperator>(FU) && FU->hasOneUse() &&
+ !FU->user_begin()->user_empty())
+ FUU = *FU->user_begin();
+ if (llvm::all_of(FUU->users(), [](const User *U) {
+ if (const auto *GV = dyn_cast<GlobalVariable>(U))
+ return GV->hasName() &&
+ (GV->getName().equals("llvm.compiler.used") ||
+ GV->getName().equals("llvm.used"));
+ return false;
+ }))
+ continue;
+ }
if (PutOffender)
*PutOffender = FU;
return true;