[llvm] f2cb9c0 - Fix missing memcpy, memmove and memset tail calls
Sanne Wouda via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 31 09:13:49 PDT 2019
Author: Sanne Wouda
Date: 2019-10-31T16:13:29Z
New Revision: f2cb9c0eabc132152b5b3ad4c87a5a02345a883d
URL: https://github.com/llvm/llvm-project/commit/f2cb9c0eabc132152b5b3ad4c87a5a02345a883d
DIFF: https://github.com/llvm/llvm-project/commit/f2cb9c0eabc132152b5b3ad4c87a5a02345a883d.diff
LOG: 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
Added:
llvm/test/CodeGen/AArch64/tailcall-bitcast-memcpy.ll
Modified:
llvm/lib/CodeGen/Analysis.cpp
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/Analysis.cpp b/llvm/lib/CodeGen/Analysis.cpp
index 4f24f077d120..023c2367af0f 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;
}
diff --git a/llvm/test/CodeGen/AArch64/tailcall-bitcast-memcpy.ll b/llvm/test/CodeGen/AArch64/tailcall-bitcast-memcpy.ll
new file mode 100644
index 000000000000..88a07498ab3b
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/tailcall-bitcast-memcpy.ll
@@ -0,0 +1,18 @@
+;RUN: llc %s -o - -verify-machineinstrs | FileCheck %s
+target triple = "aarch64-arm-none-eabi"
+
+;CHECK-LABEL: @wmemcpy
+;CHECK: lsl
+;CHECK-NOT: bl
+;CHECK-NOT: mov
+;CHECK-NOT: ldp
+;CHECK-NEXT: b memcpy
+define dso_local i32* @wmemcpy(i32* returned, i32* nocapture readonly, i64) local_unnamed_addr {
+ %4 = bitcast i32* %0 to i8*
+ %5 = bitcast i32* %1 to i8*
+ %6 = shl i64 %2, 2
+ tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %4, i8* align 4 %5, i64 %6, i1 false)
+ ret i32* %0
+}
+
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i1)
More information about the llvm-commits
mailing list