diff --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp index 91dc5018d232e..a95d6adf36d6d 100644 --- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -1603,6 +1603,7 @@ bool MemCpyOptPass::processByValArgument(CallBase &CB, unsigned ArgNo) { << " " << CB << "\n"); // Otherwise we're good! Update the byval argument. + combineAAMetadata(&CB, MDep); CB.setArgOperand(ArgNo, MDep->getSource()); ++NumMemCpyInstr; return true; diff --git a/llvm/test/Transforms/MemCpyOpt/memcpy.ll b/llvm/test/Transforms/MemCpyOpt/memcpy.ll index f7c1c85517ffa..7488203d5db16 100644 --- a/llvm/test/Transforms/MemCpyOpt/memcpy.ll +++ b/llvm/test/Transforms/MemCpyOpt/memcpy.ll @@ -393,6 +393,7 @@ declare void @f1(ptr nocapture sret(%struct.big)) declare void @f2(ptr) declare void @f(ptr) +declare void @f_byval(ptr byval(i32)) declare void @f_full_readonly(ptr nocapture noalias readonly) define void @immut_param(ptr align 4 noalias %val) { @@ -709,6 +710,19 @@ define void @immut_param_noalias_metadata(ptr align 4 byval(i32) %ptr) { ret void } +define void @byval_param_noalias_metadata(ptr align 4 byval(i32) %ptr) { +; CHECK-LABEL: @byval_param_noalias_metadata( +; CHECK-NEXT: store i32 1, ptr [[PTR:%.*]], align 4, !noalias !0 +; CHECK-NEXT: call void @f_byval(ptr byval(i32) align 4 [[PTR]]) +; CHECK-NEXT: ret void +; + %tmp = alloca i32, align 4 + store i32 1, ptr %ptr, !noalias !2 + call void @llvm.memcpy.p0.p0.i64(ptr align 4 %tmp, ptr align 4 %ptr, i64 4, i1 false) + call void @f_byval(ptr align 4 byval(i32) %tmp), !alias.scope !2 + ret void +} + !0 = !{!0} !1 = !{!1, !0} !2 = !{!1}