[PATCH] D37406: [TailCall] Allow llvm.memcpy/memset/memmove to be tail calls when parent function return the intrinsics's first argument

Wei Mi via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 1 16:53:33 PDT 2017


wmi created this revision.
Herald added a subscriber: sanjoy.

llvm.memcpy/memset/memmove return void but they will return the first argument after they are expanded as libcalls. Now if the parent function has any return value, llvm.memcpy cannot be turned into tail call after expansion.

The patch is to handle that case in SelectionDAGBuilder so when caller function return the same value as the first argument of llvm.memcpy, tail call is allowed.


Repository:
  rL LLVM

https://reviews.llvm.org/D37406

Files:
  lib/CodeGen/Analysis.cpp
  test/CodeGen/X86/tailcall-mem-intrinsics.ll


Index: test/CodeGen/X86/tailcall-mem-intrinsics.ll
===================================================================
--- test/CodeGen/X86/tailcall-mem-intrinsics.ll
+++ test/CodeGen/X86/tailcall-mem-intrinsics.ll
@@ -24,6 +24,30 @@
   ret void
 }
 
+; CHECK-LABEL: tail_memcpy_ret
+; CHECK: jmp memcpy
+define i8* @tail_memcpy_ret(i8* nocapture %p, i8* nocapture readonly %q, i32 %n) #0 {
+entry:
+  tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %p, i8* %q, i32 %n, i32 1, i1 false)
+  ret i8* %p
+}
+
+; CHECK-LABEL: tail_memmove_ret
+; CHECK: jmp memmove
+define i8* @tail_memmove_ret(i8* nocapture %p, i8* nocapture readonly %q, i32 %n) #0 {
+entry:
+  tail call void @llvm.memmove.p0i8.p0i8.i32(i8* %p, i8* %q, i32 %n, i32 1, i1 false)
+  ret i8* %p
+}
+
+; CHECK-LABEL: tail_memset_ret
+; CHECK: jmp memset
+define i8* @tail_memset_ret(i8* nocapture %p, i8 %c, i32 %n) #0 {
+entry:
+  tail call void @llvm.memset.p0i8.i32(i8* %p, i8 %c, i32 %n, i32 1, i1 false)
+  ret i8* %p
+}
+
 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1) #0
 declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1) #0
 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) #0
Index: lib/CodeGen/Analysis.cpp
===================================================================
--- lib/CodeGen/Analysis.cpp
+++ lib/CodeGen/Analysis.cpp
@@ -565,6 +565,17 @@
     return false;
 
   const Value *RetVal = Ret->getOperand(0), *CallVal = I;
+  // Intrinsic like llvm.memcpy has no return value, but will return the
+  // first argument if it is expanded as libcall.
+  const CallInst *Call = cast<CallInst>(I);
+  if (Function *F = Call->getCalledFunction()) {
+    Intrinsic::ID IID = F->getIntrinsicID();
+    if ((IID == Intrinsic::memcpy || IID == Intrinsic::memmove ||
+         IID == Intrinsic::memset) &&
+        RetVal == Call->getArgOperand(0))
+      return true;
+  }
+
   SmallVector<unsigned, 4> RetPath, CallPath;
   SmallVector<CompositeType *, 4> RetSubTypes, CallSubTypes;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D37406.113625.patch
Type: text/x-patch
Size: 2067 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170901/f7b3ec88/attachment.bin>


More information about the llvm-commits mailing list