summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/Analysis.cpp
diff options
context:
space:
mode:
authorSanne Wouda <Sanne.Wouda@arm.com>2019-10-31 14:55:57 +0000
committerSanne Wouda <Sanne.Wouda@arm.com>2019-10-31 16:13:29 +0000
commitf2cb9c0eabc132152b5b3ad4c87a5a02345a883d (patch)
tree9914f146abf63c1134d48e687eae04cbbb946270 /llvm/lib/CodeGen/Analysis.cpp
parent27cb352fd27668519f25ab8d5717173fc3ff2235 (diff)
downloadbcm5719-llvm-f2cb9c0eabc132152b5b3ad4c87a5a02345a883d.tar.gz
bcm5719-llvm-f2cb9c0eabc132152b5b3ad4c87a5a02345a883d.zip
Fix missing memcpy, memmove and memset tail calls
Summary: If a wrapper around one of the mem* stdlib functions bitcasts the returned pointer value before returning it (e.g. to a wchar_t*), LLVM does not emit a tail call. Add a check for this scenario so that we emit a tail call. Reviewers: wmi, mkuper, ramred01, dmgreen Reviewed By: wmi, dmgreen Subscribers: hiraditya, sanwou01, javed.absar, lebedev.ri, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D59078
Diffstat (limited to 'llvm/lib/CodeGen/Analysis.cpp')
-rw-r--r--llvm/lib/CodeGen/Analysis.cpp19
1 files changed, 18 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/Analysis.cpp b/llvm/lib/CodeGen/Analysis.cpp
index 4f24f077d12..023c2367af0 100644
--- a/llvm/lib/CodeGen/Analysis.cpp
+++ b/llvm/lib/CodeGen/Analysis.cpp
@@ -611,6 +611,22 @@ bool llvm::attributesPermitTailCall(const Function *F, const Instruction *I,
return CallerAttrs == CalleeAttrs;
}
+/// Check whether B is a bitcast of a pointer type to another pointer type,
+/// which is equal to A.
+static bool isPointerBitcastEqualTo(const Value *A, const Value *B) {
+ assert(A && B && "Expected non-null inputs!");
+
+ auto *BitCastIn = dyn_cast<BitCastInst>(B);
+
+ if (!BitCastIn)
+ return false;
+
+ if (!A->getType()->isPointerTy() || !B->getType()->isPointerTy())
+ return false;
+
+ return A == BitCastIn->getOperand(0);
+}
+
bool llvm::returnTypeIsEligibleForTailCall(const Function *F,
const Instruction *I,
const ReturnInst *Ret,
@@ -643,7 +659,8 @@ bool llvm::returnTypeIsEligibleForTailCall(const Function *F,
TLI.getLibcallName(RTLIB::MEMMOVE) == StringRef("memmove")) ||
(IID == Intrinsic::memset &&
TLI.getLibcallName(RTLIB::MEMSET) == StringRef("memset"))) &&
- RetVal == Call->getArgOperand(0))
+ (RetVal == Call->getArgOperand(0) ||
+ isPointerBitcastEqualTo(RetVal, Call->getArgOperand(0))))
return true;
}
OpenPOWER on IntegriCloud