diff options
Diffstat (limited to 'llvm/lib/CodeGen/Analysis.cpp')
-rw-r--r-- | llvm/lib/CodeGen/Analysis.cpp | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/Analysis.cpp b/llvm/lib/CodeGen/Analysis.cpp index 4f24f077d120..1632895fe5fa 100644 --- a/llvm/lib/CodeGen/Analysis.cpp +++ b/llvm/lib/CodeGen/Analysis.cpp @@ -262,7 +262,7 @@ static bool isNoopBitcast(Type *T1, Type *T2, /// Look through operations that will be free to find the earliest source of /// this value. /// -/// @param ValLoc If V has aggegate type, we will be interested in a particular +/// @param ValLoc If V has aggregate type, we will be interested in a particular /// scalar component. This records its address; the reverse of this list gives a /// sequence of indices appropriate for an extractvalue to locate the important /// value. This value is updated during the function and on exit will indicate @@ -567,12 +567,16 @@ bool llvm::attributesPermitTailCall(const Function *F, const Instruction *I, AttrBuilder CalleeAttrs(cast<CallInst>(I)->getAttributes(), AttributeList::ReturnIndex); - // NoAlias and NonNull are completely benign as far as calling convention + // Following attributes are completely benign as far as calling convention // goes, they shouldn't affect whether the call is a tail call. CallerAttrs.removeAttribute(Attribute::NoAlias); CalleeAttrs.removeAttribute(Attribute::NoAlias); CallerAttrs.removeAttribute(Attribute::NonNull); CalleeAttrs.removeAttribute(Attribute::NonNull); + CallerAttrs.removeAttribute(Attribute::Dereferenceable); + CalleeAttrs.removeAttribute(Attribute::Dereferenceable); + CallerAttrs.removeAttribute(Attribute::DereferenceableOrNull); + CalleeAttrs.removeAttribute(Attribute::DereferenceableOrNull); if (CallerAttrs.contains(Attribute::ZExt)) { if (!CalleeAttrs.contains(Attribute::ZExt)) @@ -611,6 +615,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 +663,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; } |