Index: llvm/lib/Transforms/Utils/InlineFunction.cpp =================================================================== --- llvm/lib/Transforms/Utils/InlineFunction.cpp +++ llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -87,7 +87,7 @@ enum NoAliasIntrinsicKind { NAIK_none, NAIK_scopes, NAIK_full }; static cl::opt UseNoAliasIntrinsic( "use-noalias-intrinsic-during-inlining", cl::Hidden, cl::ZeroOrMore, - cl::init(NAIK_scopes), cl::desc("Use noalias intrinsics during inlining."), + cl::init(NAIK_full), cl::desc("Use noalias intrinsics during inlining."), cl::values(clEnumValN(NAIK_none, "none", "no intrinsics"), clEnumValN(NAIK_scopes, "scopes", "use llvm.experimental.noalias.scope.decl"), Index: llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll =================================================================== --- llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll +++ llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll @@ -66,8 +66,12 @@ ; CHECK-LABEL: define i32 @main ; CHECK-NEXT: entry: ; CHECK: [[BUFFER:%.*]] = alloca [8 x i8], align 4 +; CHECK: [[SUB:%.*]] = getelementptr inbounds [8 x i8], [8 x i8]* [[BUFFER]], i64 0, i64 0 ; CHECK: [[SLOT:%.*]] = bitcast [8 x i8]* [[BUFFER]] to i32* -; CHECK-NEXT: store i32 7, i32* [[SLOT]], align 4 +; CHECK-NEXT: [[SUB_0_DECL:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[SUB_0_META:!.*]]) +; CHECK-NEXT: [[SUB_0_PROVENANCE:%.*]] = call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i64(i8* nonnull [[SUB]], i8* [[SUB_0_DECL]], i8** null, i8** undef, i64 0, metadata [[SUB_0_META]]) +; CHECK-NEXT: [[SUB_0_PROVENANCE_I32:%.*]] = bitcast i8* [[SUB_0_PROVENANCE]] to i32* +; CHECK-NEXT: store i32 7, i32* [[SLOT]], ptr_provenance i32* [[SUB_0_PROVENANCE_I32]], align 4, !noalias [[SUB_0_META]] ; CHECK-NEXT: call void @print(i32 7) ; CHECK-NEXT: ret i32 0 Index: llvm/test/Transforms/Coroutines/coro-retcon-value.ll =================================================================== --- llvm/test/Transforms/Coroutines/coro-retcon-value.ll +++ llvm/test/Transforms/Coroutines/coro-retcon-value.ll @@ -76,16 +76,23 @@ ; CHECK-LABEL: define i32 @main ; CHECK-NEXT: entry: ; CHECK: [[BUFFER:%.*]] = alloca [8 x i8], align 4 +; CHECK: [[SUB:%.*]] = getelementptr inbounds [8 x i8], [8 x i8]* [[BUFFER]], i64 0, i64 0 ; CHECK: [[SLOT:%.*]] = bitcast [8 x i8]* [[BUFFER]] to i32* ; CHECK-NEXT: store i32 4, i32* [[SLOT]], align 4 ; CHECK-NEXT: call void @print(i32 4) -; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[SLOT]], align 4 +; CHECK-NEXT: [[SUB_0_DECL:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[SUB_0_META:!.*]]) +; CHECK-NEXT: [[SUB_0_PROVENANCE:%.*]] = call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i64(i8* nonnull [[SUB]], i8* [[SUB_0_DECL]], i8** null, i8** undef, i64 0, metadata [[SUB_0_META]]) +; CHECK-NEXT: [[SUB_0_PROVENANCE_I32:%.*]] = bitcast i8* [[SUB_0_PROVENANCE]] to i32* +; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[SLOT]], ptr_provenance i32* [[SUB_0_PROVENANCE_I32]], align 4, !noalias [[SUB_0_META]] ; CHECK-NEXT: [[INC:%.*]] = add i32 [[LOAD]], 1 -; CHECK-NEXT: store i32 [[INC]], i32* [[SLOT]], align 4 +; CHECK-NEXT: store i32 [[INC]], i32* [[SLOT]], ptr_provenance i32* [[SUB_0_PROVENANCE_I32]], align 4, !noalias [[SUB_0_META]] ; CHECK-NEXT: call void @print(i32 [[INC]]) -; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[SLOT]], align 4 +; CHECK-NEXT: [[SUB_1_DECL:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[SUB_1_META:!.*]]) +; CHECK-NEXT: [[SUB_1_PROVENANCE:%.*]] = call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i64(i8* nonnull [[SUB]], i8* [[SUB_1_DECL]], i8** null, i8** undef, i64 0, metadata [[SUB_1_META]]) +; CHECK-NEXT: [[SUB_1_PROVENANCE_I32:%.*]] = bitcast i8* [[SUB_1_PROVENANCE]] to i32* +; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[SLOT]], ptr_provenance i32* [[SUB_1_PROVENANCE_I32]], align 4, !noalias [[SUB_1_META]] ; CHECK-NEXT: [[INC:%.*]] = add i32 [[LOAD]], 1 -; CHECK-NEXT: store i32 [[INC]], i32* [[SLOT]], align 4 +; CHECK-NEXT: store i32 [[INC]], i32* [[SLOT]], ptr_provenance i32* [[SUB_1_PROVENANCE_I32]], align 4, !noalias [[SUB_1_META]] ; CHECK-NEXT: call void @print(i32 [[INC]]) ; CHECK-NEXT: ret i32 0 Index: llvm/test/Transforms/Coroutines/coro-retcon.ll =================================================================== --- llvm/test/Transforms/Coroutines/coro-retcon.ll +++ llvm/test/Transforms/Coroutines/coro-retcon.ll @@ -66,16 +66,21 @@ ; CHECK-LABEL: define i32 @main ; CHECK-NEXT: entry: ; CHECK: [[BUFFER:%.*]] = alloca [8 x i8], align 4 +; CHECK: [[SUB:%.*]] = getelementptr inbounds [8 x i8], [8 x i8]* [[BUFFER]], i64 0, i64 0 ; CHECK: [[SLOT:%.*]] = bitcast [8 x i8]* [[BUFFER]] to i32* ; CHECK-NEXT: store i32 4, i32* [[SLOT]], align 4 ; CHECK-NEXT: call void @print(i32 4) -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl -; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[SLOT]], align 4 +; CHECK-NEXT: [[SUB_0_DECL:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[SUB_0_META:!.*]]) +; CHECK-NEXT: [[SUB_0_PROVENANCE:%.*]] = call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i64(i8* nonnull [[SUB]], i8* [[SUB_0_DECL]], i8** null, i8** undef, i64 0, metadata [[SUB_0_META]]) +; CHECK-NEXT: [[SUB_0_PROVENANCE_I32:%.*]] = bitcast i8* [[SUB_0_PROVENANCE]] to i32* +; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[SLOT]], ptr_provenance i32* [[SUB_0_PROVENANCE_I32]], align 4, !noalias [[SUB_0_META]] ; CHECK-NEXT: [[INC:%.*]] = add i32 [[LOAD]], 1 -; CHECK-NEXT: store i32 [[INC]], i32* [[SLOT]], align 4 +; CHECK-NEXT: store i32 [[INC]], i32* [[SLOT]], ptr_provenance i32* [[SUB_0_PROVENANCE_I32]], align 4, !noalias [[SUB_0_META]] ; CHECK-NEXT: call void @print(i32 [[INC]]) -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl -; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[SLOT]], align 4 +; CHECK-NEXT: [[SUB_1_DECL:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[SUB_1_META:!.*]]) +; CHECK-NEXT: [[SUB_1_PROVENANCE:%.*]] = call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i64(i8* nonnull [[SUB]], i8* [[SUB_1_DECL]], i8** null, i8** undef, i64 0, metadata [[SUB_1_META]]) +; CHECK-NEXT: [[SUB_1_PROVENANCE_I32:%.*]] = bitcast i8* [[SUB_1_PROVENANCE]] to i32* +; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[SLOT]], ptr_provenance i32* [[SUB_1_PROVENANCE_I32]], align 4, !noalias [[SUB_1_META]] ; CHECK-NEXT: [[INC:%.*]] = add i32 [[LOAD]], 1 ; CHECK-NEXT: call void @print(i32 [[INC]]) ; CHECK-NEXT: ret i32 0 Index: llvm/test/Transforms/Inline/launder.invariant.group.ll =================================================================== --- llvm/test/Transforms/Inline/launder.invariant.group.ll +++ llvm/test/Transforms/Inline/launder.invariant.group.ll @@ -1,6 +1,10 @@ -; RUN: opt -S -inline < %s | FileCheck %s -; RUN: opt -S -O3 < %s | FileCheck %s -; RUN: opt -S -inline -inline-threshold=1 < %s | FileCheck %s +; RUN: opt -S -inline --use-noalias-intrinsic-during-inlining=scopes < %s | FileCheck %s --check-prefixes=CHECK,CHECK_SCOPED +; RUN: opt -S -O3 --use-noalias-intrinsic-during-inlining=scopes < %s | FileCheck %s --check-prefixes=CHECK,CHECK_SCOPED,CHECK_OPT +; RUN: opt -S -inline -inline-threshold=1 --use-noalias-intrinsic-during-inlining=scopes < %s | FileCheck %s --check-prefixes=CHECK,CHECK_SCOPED + +; RUN: opt -S -inline --use-noalias-intrinsic-during-inlining=full < %s | FileCheck %s --check-prefixes=CHECK,CHECK_NOALIAS +; RUN: opt -S -O3 --use-noalias-intrinsic-during-inlining=full < %s | FileCheck %s --check-prefixes=CHECK,CHECK_PROVENANCE,CHECK_OPT +; RUN: opt -S -inline -inline-threshold=1 --use-noalias-intrinsic-during-inlining=full < %s | FileCheck %s --check-prefixes=CHECK,CHECK_NOALIAS %struct.A = type <{ i32 (...)**, i32, [4 x i8] }> @@ -9,7 +13,7 @@ ; sometimes it would be considered noalias. ; CHECK-LABEL: define i32 @bar(%struct.A* noalias define i32 @bar(%struct.A* noalias) { -; CHECK-NOT: noalias +; CHECK_SCOPED-NOT: noalias %2 = bitcast %struct.A* %0 to i8* %3 = call i8* @llvm.launder.invariant.group.p0i8(i8* %2) %4 = getelementptr inbounds i8, i8* %3, i64 8 @@ -22,10 +26,24 @@ ; CHECK-LABEL: define i32 @foo(%struct.A* noalias define i32 @foo(%struct.A* noalias) { - ; CHECK-NOT: call i32 @bar( - ; CHECK-NOT: !noalias + ; CHECK_SCOPED-NOT: call i32 @bar( + ; CHECK_SCOPED-NOT: !noalias + + ; CHECK_NOALIAS-NOT: call i32 @bar( + ; CHECK_NOALIAS: @llvm.noalias.decl.p0 + ; CHECK_NOALIAS-NEXT: @llvm.noalias.p0 + ; CHECK_NOALIAS-NOT: call i32 @bar( + + ; CHECK_PROVENANCE-NOT: call i32 @bar( + ; CHECK_PROVENANCE: @llvm.noalias.decl.p0 + ; CHECK_PROVENANCE-NEXT: @llvm.provenance.noalias.p0 + ; CHECK_PROVENANCE-NOT: call i32 @bar( + ; CHECK_PROVENANCE: @llvm.noalias.arg.guard.p0 + ; CHECK_PROVENANCE-NOT: call i32 @bar( %2 = tail call i32 @bar(%struct.A* %0) ret i32 %2 + + ; CHECK_OPT: ret i32 42 } Index: llvm/test/Transforms/Inline/noalias-calls-always.ll =================================================================== --- llvm/test/Transforms/Inline/noalias-calls-always.ll +++ llvm/test/Transforms/Inline/noalias-calls-always.ll @@ -31,14 +31,16 @@ ; CHECK-LABEL: @foo( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[L_I:%.*]] = alloca i8, i32 512, align 1 -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl([[META0:metadata !.*]]) -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl([[META3:metadata !.*]]) +; CHECK-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META0:![0-9]+]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[A:%.*]], i8* [[TMP0]], i8** null, i64 0, metadata [[META0]]), !noalias !3 +; CHECK-NEXT: [[TMP2:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META5:![0-9]+]]) +; CHECK-NEXT: [[TMP3:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[C:%.*]], i8* [[TMP2]], i8** null, i64 0, metadata [[META5]]), !noalias !3 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 512, i8* [[L_I]]) -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A:%.*]], i8* align 16 [[B:%.*]], i64 16, i1 false) [[ATTR4:#.*]], !noalias !3 -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[C:%.*]], i64 16, i1 false) [[ATTR4]], !noalias !0 -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR4]], !alias.scope !5 -; CHECK-NEXT: call void @hey() [[ATTR4]], !noalias !5 -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L_I]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR4]], !noalias !0 +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[TMP1]], i8* align 16 [[B:%.*]], i64 16, i1 false) #[[ATTR6:[0-9]+]], !noalias !3 +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[TMP3]], i64 16, i1 false) #[[ATTR6]], !noalias !3 +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[TMP1]], i8* align 16 [[TMP3]], i64 16, i1 false) #[[ATTR6]], !noalias !3 +; CHECK-NEXT: call void @hey() #[[ATTR6]], !noalias !3 +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L_I]], i8* align 16 [[TMP3]], i64 16, i1 false) #[[ATTR6]], !noalias !3 ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 512, i8* [[L_I]]) ; CHECK-NEXT: ret void ; @@ -72,14 +74,16 @@ ; CHECK-LABEL: @foo_cs( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[L_I:%.*]] = alloca i8, i32 512, align 1 -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl([[META6:metadata !.*]]) -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl([[META9:metadata !.*]]) +; CHECK-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META6:![0-9]+]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[A:%.*]], i8* [[TMP0]], i8** null, i64 0, metadata [[META6]]), !noalias !9 +; CHECK-NEXT: [[TMP2:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META11:![0-9]+]]) +; CHECK-NEXT: [[TMP3:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[C:%.*]], i8* [[TMP2]], i8** null, i64 0, metadata [[META11]]), !noalias !9 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 512, i8* [[L_I]]) -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A:%.*]], i8* align 16 [[B:%.*]], i64 16, i1 false) [[ATTR4]], !noalias !9 -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[C:%.*]], i64 16, i1 false) [[ATTR4]], !noalias !6 -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR4]], !alias.scope !11 -; CHECK-NEXT: call void @hey() [[ATTR4]], !noalias !11 -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L_I]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR4]], !noalias !6 +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[TMP1]], i8* align 16 [[B:%.*]], i64 16, i1 false) #[[ATTR6]], !noalias !9 +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[TMP3]], i64 16, i1 false) #[[ATTR6]], !noalias !9 +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[TMP1]], i8* align 16 [[TMP3]], i64 16, i1 false) #[[ATTR6]], !noalias !9 +; CHECK-NEXT: call void @hey() #[[ATTR6]], !noalias !9 +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L_I]], i8* align 16 [[TMP3]], i64 16, i1 false) #[[ATTR6]], !noalias !9 ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 512, i8* [[L_I]]) ; CHECK-NEXT: ret void ; @@ -95,13 +99,12 @@ ; CHECK: !0 = !{!1} ; CHECK: !1 = distinct !{!1, !2, !"hello: %a"} ; CHECK: !2 = distinct !{!2, !"hello"} -; CHECK: !3 = !{!4} +; CHECK: !3 = !{!1, !4} ; CHECK: !4 = distinct !{!4, !2, !"hello: %c"} -; CHECK: !5 = !{!1, !4} - +; CHECK: !5 = !{!4} ; CHECK: !6 = !{!7} ; CHECK: !7 = distinct !{!7, !8, !"hello_cs: %a"} ; CHECK: !8 = distinct !{!8, !"hello_cs"} -; CHECK: !9 = !{!10} +; CHECK: !9 = !{!7, !10} ; CHECK: !10 = distinct !{!10, !8, !"hello_cs: %c"} -; CHECK: !11 = !{!7, !10} +; CHECK: !11 = !{!10} Index: llvm/test/Transforms/Inline/noalias-calls2.ll =================================================================== --- llvm/test/Transforms/Inline/noalias-calls2.ll +++ llvm/test/Transforms/Inline/noalias-calls2.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature -; RUN: opt -basic-aa -inline -enable-noalias-to-md-conversion -S < %s | FileCheck %s -; RUN: opt -aa-pipeline=basic-aa -passes=inline -enable-noalias-to-md-conversion -S < %s | FileCheck %s +; RUN: opt -basic-aa -inline -enable-noalias-to-md-conversion --use-noalias-intrinsic-during-inlining=scopes -S < %s | FileCheck %s +; RUN: opt -aa-pipeline=basic-aa -passes=inline -enable-noalias-to-md-conversion --use-noalias-intrinsic-during-inlining=scopes -S < %s | FileCheck %s target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" Index: llvm/test/Transforms/Inline/parallel-loop-md-merge.ll =================================================================== --- llvm/test/Transforms/Inline/parallel-loop-md-merge.ll +++ llvm/test/Transforms/Inline/parallel-loop-md-merge.ll @@ -1,4 +1,5 @@ -; RUN: opt -always-inline -globalopt -S < %s | FileCheck %s +; RUN: opt -always-inline -globalopt --use-noalias-intrinsic-during-inlining=scopes -S < %s | FileCheck %s --check-prefixes=CHECK +; RUN: opt -always-inline -globalopt --use-noalias-intrinsic-during-inlining=full -S < %s | FileCheck %s --check-prefixes=CHECK ; ; static void __attribute__((always_inline)) callee(long n, double A[static const restrict n], long i) { ; for (long j = 0; j < n; j += 1) @@ -64,15 +65,18 @@ !11 = distinct !{!11, !12} ; LoopID !12 = !{!"llvm.loop.parallel_accesses", !10} +; There is a small reordering when noalias intrinsics are introduced ; CHECK: store double 4.200000e+01, {{.*}} !llvm.access.group ![[ACCESS_GROUP_LIST_3:[0-9]+]] ; CHECK: br label %for.cond.i, !llvm.loop ![[LOOP_INNER:[0-9]+]] ; CHECK: br label %for.cond, !llvm.loop ![[LOOP_OUTER:[0-9]+]] -; CHECK: ![[ACCESS_GROUP_LIST_3]] = !{![[ACCESS_GROUP_INNER:[0-9]+]], ![[ACCESS_GROUP_OUTER:[0-9]+]]} -; CHECK: ![[ACCESS_GROUP_INNER]] = distinct !{} -; CHECK: ![[ACCESS_GROUP_OUTER]] = distinct !{} -; CHECK: ![[LOOP_INNER]] = distinct !{![[LOOP_INNER]], ![[ACCESSES_INNER:[0-9]+]]} -; CHECK: ![[ACCESSES_INNER]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_INNER]]} -; CHECK: ![[LOOP_OUTER]] = distinct !{![[LOOP_OUTER]], ![[ACCESSES_OUTER:[0-9]+]]} -; CHECK: ![[ACCESSES_OUTER]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_OUTER]]} + +; CHECK-DAG: ![[ACCESS_GROUP_LIST_3]] = !{![[ACCESS_GROUP_INNER:[0-9]+]], ![[ACCESS_GROUP_OUTER:[0-9]+]]} +; CHECK-DAG: ![[ACCESS_GROUP_INNER]] = distinct !{} +; CHECK-DAG: ![[ACCESS_GROUP_OUTER]] = distinct !{} + +; CHECK-DAG: ![[LOOP_INNER]] = distinct !{![[LOOP_INNER]], ![[ACCESSES_INNER:[0-9]+]]} +; CHECK-DAG: ![[ACCESSES_INNER]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_INNER]]} +; CHECK-DAG: ![[LOOP_OUTER]] = distinct !{![[LOOP_OUTER]], ![[ACCESSES_OUTER:[0-9]+]]} +; CHECK-DAG: ![[ACCESSES_OUTER]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_OUTER]]} Index: llvm/test/Transforms/PhaseOrdering/pr39282.ll =================================================================== --- llvm/test/Transforms/PhaseOrdering/pr39282.ll +++ llvm/test/Transforms/PhaseOrdering/pr39282.ll @@ -18,24 +18,32 @@ define void @pr39282(i32* %addr1, i32* %addr2) { ; CHECK-LABEL: @pr39282( ; CHECK-NEXT: start: -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl -; CHECK-NEXT: [[X_I:%.*]] = load i32, i32* [[ADDR1:%.*]], align 4, !alias.scope !3, !noalias !0 -; CHECK-NEXT: store i32 [[X_I]], i32* [[ADDR2:%.*]], align 4, !alias.scope !0, !noalias !3 +; CHECK-NEXT: [[TMP0:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META0:![0-9]+]]) +; CHECK-NEXT: [[TMP1:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* [[ADDR2:%.*]], i8* [[TMP0]], i32** null, i32** undef, i64 0, metadata [[META0]]), !noalias !3 +; CHECK-NEXT: [[TMP2:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META5:![0-9]+]]) +; CHECK-NEXT: [[TMP3:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* [[ADDR1:%.*]], i8* [[TMP2]], i32** null, i32** undef, i64 0, metadata [[META5]]), !noalias !3 +; CHECK-NEXT: [[X_I:%.*]] = load i32, i32* [[ADDR1]], ptr_provenance i32* [[TMP3]], align 4, !noalias !3 +; CHECK-NEXT: store i32 [[X_I]], i32* [[ADDR2]], ptr_provenance i32* [[TMP1]], align 4, !noalias !3 ; CHECK-NEXT: [[ADDR1I_1:%.*]] = getelementptr inbounds i32, i32* [[ADDR1]], i64 1 ; CHECK-NEXT: [[ADDR2I_1:%.*]] = getelementptr inbounds i32, i32* [[ADDR2]], i64 1 -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl -; CHECK-NEXT: [[X_I_1:%.*]] = load i32, i32* [[ADDR1I_1]], align 4, !alias.scope !7, !noalias !5 -; CHECK-NEXT: store i32 [[X_I_1]], i32* [[ADDR2I_1]], align 4, !alias.scope !5, !noalias !7 -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl -; CHECK-NEXT: [[X_I_2:%.*]] = load i32, i32* [[ADDR1]], align 4, !alias.scope !11, !noalias !9 -; CHECK-NEXT: store i32 [[X_I_2]], i32* [[ADDR2]], align 4, !alias.scope !9, !noalias !11 -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl -; CHECK-NEXT: [[X_I_3:%.*]] = load i32, i32* [[ADDR1I_1]], align 4, !alias.scope !15, !noalias !13 -; CHECK-NEXT: store i32 [[X_I_3]], i32* [[ADDR2I_1]], align 4, !alias.scope !13, !noalias !15 +; CHECK-NEXT: [[TMP4:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META6:![0-9]+]]) +; CHECK-NEXT: [[TMP5:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* nonnull [[ADDR2I_1]], i8* [[TMP4]], i32** null, i32** undef, i64 0, metadata [[META6]]), !noalias !8 +; CHECK-NEXT: [[TMP6:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META10:![0-9]+]]) +; CHECK-NEXT: [[TMP7:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* nonnull [[ADDR1I_1]], i8* [[TMP6]], i32** null, i32** undef, i64 0, metadata [[META10]]), !noalias !8 +; CHECK-NEXT: [[X_I_1:%.*]] = load i32, i32* [[ADDR1I_1]], ptr_provenance i32* [[TMP7]], align 4, !noalias !8 +; CHECK-NEXT: store i32 [[X_I_1]], i32* [[ADDR2I_1]], ptr_provenance i32* [[TMP5]], align 4, !noalias !8 +; CHECK-NEXT: [[TMP8:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META11:![0-9]+]]) +; CHECK-NEXT: [[TMP9:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* nonnull [[ADDR2]], i8* [[TMP8]], i32** null, i32** undef, i64 0, metadata [[META11]]), !noalias !13 +; CHECK-NEXT: [[TMP10:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META15:![0-9]+]]) +; CHECK-NEXT: [[TMP11:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* nonnull [[ADDR1]], i8* [[TMP10]], i32** null, i32** undef, i64 0, metadata [[META15]]), !noalias !13 +; CHECK-NEXT: [[X_I_2:%.*]] = load i32, i32* [[ADDR1]], ptr_provenance i32* [[TMP11]], align 4, !noalias !13 +; CHECK-NEXT: store i32 [[X_I_2]], i32* [[ADDR2]], ptr_provenance i32* [[TMP9]], align 4, !noalias !13 +; CHECK-NEXT: [[TMP12:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META16:![0-9]+]]) +; CHECK-NEXT: [[TMP13:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* nonnull [[ADDR2I_1]], i8* [[TMP12]], i32** null, i32** undef, i64 0, metadata [[META16]]), !noalias !18 +; CHECK-NEXT: [[TMP14:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META20:![0-9]+]]) +; CHECK-NEXT: [[TMP15:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* nonnull [[ADDR1I_1]], i8* [[TMP14]], i32** null, i32** undef, i64 0, metadata [[META20]]), !noalias !18 +; CHECK-NEXT: [[X_I_3:%.*]] = load i32, i32* [[ADDR1I_1]], ptr_provenance i32* [[TMP15]], align 4, !noalias !18 +; CHECK-NEXT: store i32 [[X_I_3]], i32* [[ADDR2I_1]], ptr_provenance i32* [[TMP13]], align 4, !noalias !18 ; CHECK-NEXT: ret void ; start: