diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp index 8b4f35570d0..6f4f17e20fb 100644 --- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -1789,10 +1789,11 @@ static bool isOnlyCopiedFromConstantGlobal(Value *V, MemTransferInst *&TheCopy, for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI!=E; ++UI) { User *U = cast(*UI); - if (LoadInst *LI = dyn_cast(U)) + if (LoadInst *LI = dyn_cast(U)) { // Ignore non-volatile loads, they are always ok. - if (!LI->isVolatile()) - continue; + if (LI->isVolatile()) return false; + continue; + } if (BitCastInst *BCI = dyn_cast(U)) { // If uses of the bitcast are ok, we are ok. @@ -1814,6 +1815,13 @@ static bool isOnlyCopiedFromConstantGlobal(Value *V, MemTransferInst *&TheCopy, MemTransferInst *MI = dyn_cast(U); if (MI == 0) return false; + + // If the transfer is using the alloca as a source of the transfer, then + // it (unless the transfer is volatile). + if (UI.getOperandNo() == 1) { + if (MI->isVolatile()) return false; + continue; + } // If we already have seen a copy, reject the second one. if (TheCopy) return false; diff --git a/test/Transforms/ScalarRepl/memcpy-from-global.ll b/test/Transforms/ScalarRepl/memcpy-from-global.ll index 592bf328d4b..e807177357b 100644 --- a/test/Transforms/ScalarRepl/memcpy-from-global.ll +++ b/test/Transforms/ScalarRepl/memcpy-from-global.ll @@ -39,3 +39,32 @@ entry: } declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) + + + +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind + +%T = type { i8, [123 x i8] } + +@G = constant %T {i8 1, [123 x i8] zeroinitializer } + +define void @test2() { + %A = alloca %T + %B = alloca %T + %a = bitcast %T* %A to i8* + %b = bitcast %T* %B to i8* + +; CHECK: @test2 + +; %A alloca is deleted +; CHECK-NEXT: %B = alloca %T + +; use @G instead of %A +; CHECK-NEXT: %a = bitcast %T* @G 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 @llvm.memcpy.p0i8.p0i8.i64(i8* %b, i8* %a, i64 124, i32 4, i1 false) + call void @bar(i8* %b) + ret void +} + +declare void @bar(i8*)