From 6248065194778c866164b0c10f09f0f0d91b91ac Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 18 Nov 2010 06:41:51 +0000 Subject: [PATCH] allow eliminating an alloca that is just copied from an constant global if it is passed as a byval argument. The byval argument will just be a read, so it is safe to read from the original global instead. This allows us to promote away the %agg.tmp alloca in PR8582 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119686 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/ScalarReplAggregates.cpp | 13 ++++++++++--- test/Transforms/ScalarRepl/memcpy-from-global.ll | 13 +++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp index fe40bcc22d5..1bec443513b 100644 --- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -1811,11 +1811,18 @@ static bool isOnlyCopiedFromConstantGlobal(Value *V, MemTransferInst *&TheCopy, continue; } - // If this is a readonly/readnone call site, then we know it is just a load - // and we can ignore it. - if (CallSite CS = U) + if (CallSite CS = U) { + // If this is a readonly/readnone call site, then we know it is just a + // load and we can ignore it. if (CS.onlyReadsMemory()) continue; + + // If this is being passed as a byval argument, the caller is making a + // copy, so it is only a read of the alloca. + unsigned ArgNo = CS.getArgumentNo(UI); + if (CS.paramHasAttr(ArgNo+1, Attribute::ByVal)) + continue; + } // If this is isn't our memcpy/memmove, reject it as something we can't // handle. diff --git a/test/Transforms/ScalarRepl/memcpy-from-global.ll b/test/Transforms/ScalarRepl/memcpy-from-global.ll index 68fc2a2c581..5b258645344 100644 --- a/test/Transforms/ScalarRepl/memcpy-from-global.ll +++ b/test/Transforms/ScalarRepl/memcpy-from-global.ll @@ -81,3 +81,16 @@ define void @test3() { ; CHECK-NEXT: call void @bar(i8* %a) ret void } + +define void @test4() { + %A = alloca %T + %a = bitcast %T* %A to i8* + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* bitcast (%T* @G to i8*), i64 124, i32 4, i1 false) + call void @baz(i8* byval %a) +; CHECK: @test4 +; CHECK-NEXT: %a = bitcast %T* @G to i8* +; CHECK-NEXT: call void @baz(i8* byval %a) + ret void +} + +declare void @baz(i8* byval)