we don't have to make an explicit copy of a byval argument when 
inlining a function if we know that the function does not write
to *any* memory.  This implements test/Transforms/Inline/byval2.ll


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45912 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp
index a4978f0..f730d53 100644
--- a/lib/Transforms/Utils/InlineFunction.cpp
+++ b/lib/Transforms/Utils/InlineFunction.cpp
@@ -241,10 +241,12 @@
       Value *ActualArg = *AI;
       
       // When byval arguments actually inlined, we need to make the copy implied
-      // by them actually explicit.
-      // TODO: If we know that the callee never modifies the struct, we can
-      // remove this copy.
-      if (CalledFunc->paramHasAttr(ArgNo+1, ParamAttr::ByVal)) {
+      // by them explicit.  However, we don't do this if the callee is readonly
+      // or readnone, because the copy would be unneeded: the callee doesn't
+      // modify the struct.
+      if (CalledFunc->paramHasAttr(ArgNo+1, ParamAttr::ByVal) &&
+          !CalledFunc->paramHasAttr(0, ParamAttr::ReadOnly) &&
+          !CalledFunc->paramHasAttr(0, ParamAttr::ReadNone)) {
         const Type *AggTy = cast<PointerType>(I->getType())->getElementType();
         const Type *VoidPtrTy = PointerType::getUnqual(Type::Int8Ty);