summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/MemoryBuiltins.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/MemoryBuiltins.cpp')
-rw-r--r--llvm/lib/Analysis/MemoryBuiltins.cpp30
1 files changed, 30 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp
index 0f4bfb8e2fb..eaac506dec4 100644
--- a/llvm/lib/Analysis/MemoryBuiltins.cpp
+++ b/llvm/lib/Analysis/MemoryBuiltins.cpp
@@ -388,6 +388,36 @@ bool llvm::getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL,
return true;
}
+ConstantInt *llvm::lowerObjectSizeCall(IntrinsicInst *ObjectSize,
+ const DataLayout &DL,
+ const TargetLibraryInfo *TLI,
+ bool MustSucceed) {
+ assert(ObjectSize->getIntrinsicID() == Intrinsic::objectsize &&
+ "ObjectSize must be a call to llvm.objectsize!");
+
+ bool MaxVal = cast<ConstantInt>(ObjectSize->getArgOperand(1))->isZero();
+ ObjSizeMode Mode;
+ // Unless we have to fold this to something, try to be as accurate as
+ // possible.
+ if (MustSucceed)
+ Mode = MaxVal ? ObjSizeMode::Max : ObjSizeMode::Min;
+ else
+ Mode = ObjSizeMode::Exact;
+
+ // FIXME: Does it make sense to just return a failure value if the size won't
+ // fit in the output and `!MustSucceed`?
+ uint64_t Size;
+ auto *ResultType = cast<IntegerType>(ObjectSize->getType());
+ if (getObjectSize(ObjectSize->getArgOperand(0), Size, DL, TLI, false, Mode) &&
+ isUIntN(ResultType->getBitWidth(), Size))
+ return ConstantInt::get(ResultType, Size);
+
+ if (!MustSucceed)
+ return nullptr;
+
+ return ConstantInt::get(ResultType, MaxVal ? -1ULL : 0);
+}
+
STATISTIC(ObjectVisitorArgument,
"Number of arguments with unsolved size and offset");
STATISTIC(ObjectVisitorLoad,
OpenPOWER on IntegriCloud