aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorserge-sans-paille <sguelton@redhat.com>2022-04-11 13:38:31 +0200
committerserge-sans-paille <sguelton@redhat.com>2022-04-12 14:47:29 +0200
commite810d558093cff40caaa1aff24d289c76c59916d (patch)
tree7f58e9c2fab8bce98123adcf2f84545256f3e57d /llvm/lib/Analysis/ValueTracking.cpp
parent0231a90bc438f728c81087520d8d5d85101ed05b (diff)
downloadllvm-e810d558093cff40caaa1aff24d289c76c59916d.zip
llvm-e810d558093cff40caaa1aff24d289c76c59916d.tar.gz
llvm-e810d558093cff40caaa1aff24d289c76c59916d.tar.bz2
[ValueTracking] Make getStringLenth aware of strdup
During strlen compile-time evaluation, make it possible to track size of strduped strings. Differential Revision: https://reviews.llvm.org/D123497
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp30
1 files changed, 24 insertions, 6 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 75381f5..c4ceb91 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4199,7 +4199,8 @@ bool llvm::getConstantStringInfo(const Value *V, StringRef &Str,
/// If we can compute the length of the string pointed to by
/// the specified pointer, return 'len+1'. If we can't, return 0.
static uint64_t GetStringLengthH(const Value *V,
- SmallPtrSetImpl<const PHINode*> &PHIs,
+ SmallPtrSetImpl<const PHINode *> &PHIs,
+ const TargetLibraryInfo *TLI,
unsigned CharSize) {
// Look through noop bitcast instructions.
V = V->stripPointerCasts();
@@ -4213,7 +4214,7 @@ static uint64_t GetStringLengthH(const Value *V,
// If it was new, see if all the input strings are the same length.
uint64_t LenSoFar = ~0ULL;
for (Value *IncValue : PN->incoming_values()) {
- uint64_t Len = GetStringLengthH(IncValue, PHIs, CharSize);
+ uint64_t Len = GetStringLengthH(IncValue, PHIs, TLI, CharSize);
if (Len == 0) return 0; // Unknown length -> unknown.
if (Len == ~0ULL) continue;
@@ -4229,9 +4230,9 @@ static uint64_t GetStringLengthH(const Value *V,
// strlen(select(c,x,y)) -> strlen(x) ^ strlen(y)
if (const SelectInst *SI = dyn_cast<SelectInst>(V)) {
- uint64_t Len1 = GetStringLengthH(SI->getTrueValue(), PHIs, CharSize);
+ uint64_t Len1 = GetStringLengthH(SI->getTrueValue(), PHIs, TLI, CharSize);
if (Len1 == 0) return 0;
- uint64_t Len2 = GetStringLengthH(SI->getFalseValue(), PHIs, CharSize);
+ uint64_t Len2 = GetStringLengthH(SI->getFalseValue(), PHIs, TLI, CharSize);
if (Len2 == 0) return 0;
if (Len1 == ~0ULL) return Len2;
if (Len2 == ~0ULL) return Len1;
@@ -4239,6 +4240,22 @@ static uint64_t GetStringLengthH(const Value *V,
return Len1;
}
+ if (auto *CB = dyn_cast<CallBase>(V)) {
+ Function *Callee = CB->getCalledFunction();
+ if (!Callee)
+ return 0;
+
+ LibFunc TLIFn;
+ if (!TLI || !TLI->getLibFunc(*CB->getCalledFunction(), TLIFn) ||
+ !TLI->has(TLIFn))
+ return 0;
+
+ if (TLIFn == LibFunc_strdup || TLIFn == LibFunc_dunder_strdup)
+ return GetStringLengthH(CB->getArgOperand(0), PHIs, TLI, CharSize);
+
+ return 0;
+ }
+
// Otherwise, see if we can read the string.
ConstantDataArraySlice Slice;
if (!getConstantDataArrayInfo(V, Slice, CharSize))
@@ -4259,12 +4276,13 @@ static uint64_t GetStringLengthH(const Value *V,
/// If we can compute the length of the string pointed to by
/// the specified pointer, return 'len+1'. If we can't, return 0.
-uint64_t llvm::GetStringLength(const Value *V, unsigned CharSize) {
+uint64_t llvm::GetStringLength(const Value *V, const TargetLibraryInfo *TLI,
+ unsigned CharSize) {
if (!V->getType()->isPointerTy())
return 0;
SmallPtrSet<const PHINode*, 32> PHIs;
- uint64_t Len = GetStringLengthH(V, PHIs, CharSize);
+ uint64_t Len = GetStringLengthH(V, PHIs, TLI, CharSize);
// If Len is ~0ULL, we had an infinite phi cycle: this is dead code, so return
// an empty string as a length.
return Len == ~0ULL ? 1 : Len;