diff options
author | Sanne Wouda <Sanne.Wouda@arm.com> | 2019-10-31 14:55:57 +0000 |
---|---|---|
committer | Sanne Wouda <Sanne.Wouda@arm.com> | 2019-10-31 16:13:29 +0000 |
commit | f2cb9c0eabc132152b5b3ad4c87a5a02345a883d (patch) | |
tree | 9914f146abf63c1134d48e687eae04cbbb946270 /llvm/lib/CodeGen/Analysis.cpp | |
parent | 27cb352fd27668519f25ab8d5717173fc3ff2235 (diff) | |
download | bcm5719-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.cpp | 19 |
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; } |