diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -925,7 +925,7 @@ SmallVector NoAliasArgs; for (const Argument &Arg : CalledFunc->args()) - if (Arg.hasNoAliasAttr() && !Arg.use_empty()) + if (CS.paramHasAttr(Arg.getArgNo(), Attribute::NoAlias) && !Arg.use_empty()) NoAliasArgs.push_back(&Arg); if (NoAliasArgs.empty()) @@ -1058,7 +1058,7 @@ // completely describe the aliasing properties using alias.scope // metadata (and, thus, won't add any). if (const Argument *A = dyn_cast(V)) { - if (!A->hasNoAliasAttr()) + if (!CS.paramHasAttr(A->getArgNo(), Attribute::NoAlias)) UsesAliasingPtr = true; } else { UsesAliasingPtr = true; diff --git a/llvm/test/Transforms/Inline/noalias-calls.ll b/llvm/test/Transforms/Inline/noalias-calls.ll --- a/llvm/test/Transforms/Inline/noalias-calls.ll +++ b/llvm/test/Transforms/Inline/noalias-calls.ll @@ -22,6 +22,23 @@ ret void } +define void @hello_cs(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #1 { +entry: + %l = alloca i8, i32 512, align 1 + call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %a, i8* align 16 %b, i64 16, i1 0) + call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %b, i8* align 16 %c, i64 16, i1 0) + call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %a, i8* align 16 %c, i64 16, i1 0) + call void @hey() + call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %l, i8* align 16 %c, i64 16, i1 0) + ret void +} + +define void @foo_cs(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #2 { +entry: + tail call void @hello_cs(i8* noalias %a, i8* noalias %c, i8* %b) + ret void +} + ; CHECK: define void @foo(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #2 { ; CHECK: entry: ; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %a, i8* align 16 %b, i64 16, i1 false) #1, !noalias !0 @@ -32,6 +49,16 @@ ; CHECK: ret void ; CHECK: } +; CHECK: define void @foo_cs(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #2 { +; CHECK: entry: +; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %a, i8* align 16 %b, i64 16, i1 false) #1, !noalias !6 +; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %b, i8* align 16 %c, i64 16, i1 false) #1, !noalias !9 +; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %a, i8* align 16 %c, i64 16, i1 false) #1, !alias.scope !11 +; CHECK: call void @hey() #1, !noalias !11 +; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %{{.*}}, i8* align 16 %c, i64 16, i1 false) #1, !noalias !9 +; CHECK: ret void +; CHECK: } + attributes #0 = { nounwind argmemonly willreturn } attributes #1 = { nounwind } attributes #2 = { nounwind uwtable } @@ -43,3 +70,10 @@ ; CHECK: !4 = distinct !{!4, !2, !"hello: %a"} ; CHECK: !5 = !{!4, !1} +; CHECK: !6 = !{!7} +; CHECK: !7 = distinct !{!7, !8, !"hello_cs: %c"} +; CHECK: !8 = distinct !{!8, !"hello_cs"} +; CHECK: !9 = !{!10} +; CHECK: !10 = distinct !{!10, !8, !"hello_cs: %a"} +; CHECK: !11 = !{!10, !7} +