[llvm] r276771 - Re-committing r275284: add support to inline __builtin_mempcpy

Andrew Kaylor via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 26 10:23:14 PDT 2016


Author: akaylor
Date: Tue Jul 26 12:23:13 2016
New Revision: 276771

URL: http://llvm.org/viewvc/llvm-project?rev=276771&view=rev
Log:
Re-committing r275284: add support to inline __builtin_mempcpy

Patch by Sunita Marathe

Differential Revision: http://reviews.llvm.org/D21920


Modified:
    llvm/trunk/include/llvm/Analysis/TargetLibraryInfo.def
    llvm/trunk/include/llvm/Analysis/TargetLibraryInfo.h
    llvm/trunk/lib/Analysis/TargetLibraryInfo.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
    llvm/trunk/lib/Transforms/Utils/BuildLibCalls.cpp
    llvm/trunk/test/Transforms/InferFunctionAttrs/annotate.ll
    llvm/trunk/test/Transforms/InferFunctionAttrs/no-proto.ll

Modified: llvm/trunk/include/llvm/Analysis/TargetLibraryInfo.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/TargetLibraryInfo.def?rev=276771&r1=276770&r2=276771&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/TargetLibraryInfo.def (original)
+++ llvm/trunk/include/llvm/Analysis/TargetLibraryInfo.def Tue Jul 26 12:23:13 2016
@@ -734,6 +734,9 @@ TLI_DEFINE_STRING_INTERNAL("memcpy")
 /// void *memmove(void *s1, const void *s2, size_t n);
 TLI_DEFINE_ENUM_INTERNAL(memmove)
 TLI_DEFINE_STRING_INTERNAL("memmove")
+/// void *mempcpy(void *s1, const void *s2, size_t n);
+TLI_DEFINE_ENUM_INTERNAL(mempcpy)
+TLI_DEFINE_STRING_INTERNAL("mempcpy")
 // void *memrchr(const void *s, int c, size_t n);
 TLI_DEFINE_ENUM_INTERNAL(memrchr)
 TLI_DEFINE_STRING_INTERNAL("memrchr")

Modified: llvm/trunk/include/llvm/Analysis/TargetLibraryInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/TargetLibraryInfo.h?rev=276771&r1=276770&r2=276771&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/TargetLibraryInfo.h (original)
+++ llvm/trunk/include/llvm/Analysis/TargetLibraryInfo.h Tue Jul 26 12:23:13 2016
@@ -251,7 +251,7 @@ public:
     case LibFunc::exp2:      case LibFunc::exp2f:      case LibFunc::exp2l:
     case LibFunc::memcmp:    case LibFunc::strcmp:     case LibFunc::strcpy:
     case LibFunc::stpcpy:    case LibFunc::strlen:     case LibFunc::strnlen:
-    case LibFunc::memchr:
+    case LibFunc::memchr:    case LibFunc::mempcpy:
       return true;
     }
     return false;

Modified: llvm/trunk/lib/Analysis/TargetLibraryInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/TargetLibraryInfo.cpp?rev=276771&r1=276770&r2=276771&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/TargetLibraryInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/TargetLibraryInfo.cpp Tue Jul 26 12:23:13 2016
@@ -642,6 +642,7 @@ bool TargetLibraryInfoImpl::isValidProto
       return false;
   // fallthrough
   case LibFunc::memcpy:
+  case LibFunc::mempcpy:
   case LibFunc::memmove:
     return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) &&
             FTy.getParamType(0)->isPointerTy() &&

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=276771&r1=276770&r2=276771&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Tue Jul 26 12:23:13 2016
@@ -6044,6 +6044,49 @@ bool SelectionDAGBuilder::visitMemChrCal
   return false;
 }
 
+///
+/// visitMemPCpyCall -- lower a mempcpy call as a memcpy followed by code to
+/// to adjust the dst pointer by the size of the copied memory.
+bool SelectionDAGBuilder::visitMemPCpyCall(const CallInst &I) {
+
+  // Verify argument count: void *mempcpy(void *, const void *, size_t)
+  if (I.getNumArgOperands() != 3)
+    return false;
+
+  SDValue Dst = getValue(I.getArgOperand(0));
+  SDValue Src = getValue(I.getArgOperand(1));
+  SDValue Size = getValue(I.getArgOperand(2));
+
+  unsigned DstAlign = DAG.InferPtrAlignment(Dst);
+  unsigned SrcAlign = DAG.InferPtrAlignment(Src);
+  unsigned Align = std::min(DstAlign, SrcAlign);
+  if (Align == 0) // Alignment of one or both could not be inferred.
+    Align = 1; // 0 and 1 both specify no alignment, but 0 is reserved.
+
+  bool isVol = false;
+  SDLoc sdl = getCurSDLoc();
+
+  // In the mempcpy context we need to pass in a false value for isTailCall
+  // because the return pointer needs to be adjusted by the size of
+  // the copied memory.
+  SDValue MC = DAG.getMemcpy(getRoot(), sdl, Dst, Src, Size, Align, isVol,
+                             false, /*isTailCall=*/false,
+                             MachinePointerInfo(I.getArgOperand(0)),
+                             MachinePointerInfo(I.getArgOperand(1)));
+  assert(MC.getNode() != nullptr &&
+         "** memcpy should not be lowered as TailCall in mempcpy context **");
+  DAG.setRoot(MC);
+
+  // Check if Size needs to be truncated or extended.
+  Size = DAG.getSExtOrTrunc(Size, sdl, Dst.getValueType());
+
+  // Adjust return pointer to point just past the last dst byte.
+  SDValue DstPlusSize = DAG.getNode(ISD::ADD, sdl, Dst.getValueType(),
+                                    Dst, Size);
+  setValue(&I, DstPlusSize);
+  return true;
+}
+
 /// visitStrCpyCall -- See if we can lower a strcpy or stpcpy call into an
 /// optimized form.  If so, return true and lower it, otherwise return false
 /// and it will be lowered like a normal call.
@@ -6334,6 +6377,10 @@ void SelectionDAGBuilder::visitCall(cons
         if (visitMemCmpCall(I))
           return;
         break;
+      case LibFunc::mempcpy:
+        if (visitMemPCpyCall(I))
+          return;
+        break;
       case LibFunc::memchr:
         if (visitMemChrCall(I))
           return;

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h?rev=276771&r1=276770&r2=276771&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h Tue Jul 26 12:23:13 2016
@@ -885,6 +885,7 @@ private:
   void visitPHI(const PHINode &I);
   void visitCall(const CallInst &I);
   bool visitMemCmpCall(const CallInst &I);
+  bool visitMemPCpyCall(const CallInst &I);
   bool visitMemChrCall(const CallInst &I);
   bool visitStrCpyCall(const CallInst &I, bool isStpcpy);
   bool visitStrCmpCall(const CallInst &I);

Modified: llvm/trunk/lib/Transforms/Utils/BuildLibCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BuildLibCalls.cpp?rev=276771&r1=276770&r2=276771&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/BuildLibCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/BuildLibCalls.cpp Tue Jul 26 12:23:13 2016
@@ -250,6 +250,7 @@ bool llvm::inferLibFuncAttributes(Functi
     Changed |= setDoesNotCapture(F, 2);
     return Changed;
   case LibFunc::memcpy:
+  case LibFunc::mempcpy:
   case LibFunc::memccpy:
   case LibFunc::memmove:
     Changed |= setDoesNotThrow(F);

Modified: llvm/trunk/test/Transforms/InferFunctionAttrs/annotate.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InferFunctionAttrs/annotate.ll?rev=276771&r1=276770&r2=276771&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InferFunctionAttrs/annotate.ll (original)
+++ llvm/trunk/test/Transforms/InferFunctionAttrs/annotate.ll Tue Jul 26 12:23:13 2016
@@ -499,6 +499,9 @@ declare i32 @memcmp(i8*, i8*, i64)
 ; CHECK: declare i8* @memcpy(i8*, i8* nocapture readonly, i64) [[G0]]
 declare i8* @memcpy(i8*, i8*, i64)
 
+; CHECK: declare i8* @mempcpy(i8*, i8* nocapture readonly, i64) [[G0]]
+declare i8* @mempcpy(i8*, i8*, i64)
+
 ; CHECK: declare i8* @memmove(i8*, i8* nocapture readonly, i64) [[G0]]
 declare i8* @memmove(i8*, i8*, i64)
 

Modified: llvm/trunk/test/Transforms/InferFunctionAttrs/no-proto.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InferFunctionAttrs/no-proto.ll?rev=276771&r1=276770&r2=276771&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InferFunctionAttrs/no-proto.ll (original)
+++ llvm/trunk/test/Transforms/InferFunctionAttrs/no-proto.ll Tue Jul 26 12:23:13 2016
@@ -480,6 +480,9 @@ declare void @memcmp(...)
 ; CHECK: declare void @memcpy(...)
 declare void @memcpy(...)
 
+; CHECK: declare void @mempcpy(...)
+declare void @mempcpy(...)
+
 ; CHECK: declare void @memmove(...)
 declare void @memmove(...)
 




More information about the llvm-commits mailing list