diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -6710,7 +6710,8 @@ return false; if (const auto *A = dyn_cast(V)) { - if (A->hasAttribute(Attribute::NoUndef) || + if (A->hasPassPointeeByValueCopyAttr() || + A->hasAttribute(Attribute::NoUndef) || A->hasAttribute(Attribute::Dereferenceable) || A->hasAttribute(Attribute::DereferenceableOrNull)) return true; diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll @@ -10,25 +10,15 @@ declare ptr @foo(ptr) define internal void @bar(ptr byval(%pair) %Data) { -; TUNIT: Function Attrs: memory(readwrite, argmem: none) -; TUNIT-LABEL: define {{[^@]+}}@bar -; TUNIT-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR0:[0-9]+]] { -; TUNIT-NEXT: [[DATA_PRIV:%.*]] = alloca [[PAIR:%.*]], align 8 -; TUNIT-NEXT: store i32 [[TMP0]], ptr [[DATA_PRIV]], align 4 -; TUNIT-NEXT: [[DATA_PRIV_0_1:%.*]] = getelementptr [[PAIR]], ptr [[DATA_PRIV]], i64 0, i32 1 -; TUNIT-NEXT: store i32 [[TMP1]], ptr [[DATA_PRIV_0_1]], align 4 -; TUNIT-NEXT: [[TMP3:%.*]] = call ptr @foo(ptr nonnull dereferenceable(8) [[DATA_PRIV]]) -; TUNIT-NEXT: ret void -; -; CGSCC: Function Attrs: memory(readwrite, argmem: none) -; CGSCC-LABEL: define {{[^@]+}}@bar -; CGSCC-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR0:[0-9]+]] { -; CGSCC-NEXT: [[DATA_PRIV:%.*]] = alloca [[PAIR:%.*]], align 8 -; CGSCC-NEXT: store i32 [[TMP0]], ptr [[DATA_PRIV]], align 4 -; CGSCC-NEXT: [[DATA_PRIV_0_1:%.*]] = getelementptr [[PAIR]], ptr [[DATA_PRIV]], i64 0, i32 1 -; CGSCC-NEXT: store i32 [[TMP1]], ptr [[DATA_PRIV_0_1]], align 4 -; CGSCC-NEXT: [[TMP3:%.*]] = call ptr @foo(ptr noundef nonnull dereferenceable(8) [[DATA_PRIV]]) -; CGSCC-NEXT: ret void +; CHECK: Function Attrs: memory(readwrite, argmem: none) +; CHECK-LABEL: define {{[^@]+}}@bar +; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: [[DATA_PRIV:%.*]] = alloca [[PAIR:%.*]], align 8 +; CHECK-NEXT: store i32 [[TMP0]], ptr [[DATA_PRIV]], align 4 +; CHECK-NEXT: [[DATA_PRIV_0_1:%.*]] = getelementptr [[PAIR]], ptr [[DATA_PRIV]], i64 0, i32 1 +; CHECK-NEXT: store i32 [[TMP1]], ptr [[DATA_PRIV_0_1]], align 4 +; CHECK-NEXT: [[TMP3:%.*]] = call ptr @foo(ptr noundef nonnull dereferenceable(8) [[DATA_PRIV]]) +; CHECK-NEXT: ret void ; tail call ptr @foo(ptr %Data) ret void @@ -36,7 +26,7 @@ define void @zed(ptr byval(%pair) %Data) { ; TUNIT-LABEL: define {{[^@]+}}@zed -; TUNIT-SAME: (ptr noalias nocapture nonnull readonly byval([[PAIR:%.*]]) dereferenceable(8) [[DATA:%.*]]) { +; TUNIT-SAME: (ptr noalias nocapture noundef nonnull readonly byval([[PAIR:%.*]]) dereferenceable(8) [[DATA:%.*]]) { ; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr [[DATA]], align 1 ; TUNIT-NEXT: [[DATA_0_1:%.*]] = getelementptr [[PAIR]], ptr [[DATA]], i64 0, i32 1 ; TUNIT-NEXT: [[TMP2:%.*]] = load i32, ptr [[DATA_0_1]], align 1 @@ -55,7 +45,5 @@ ret void } ;. -; CHECK: attributes #[[ATTR0:[0-9]+]] = { memory(readwrite, argmem: none) } +; CHECK: attributes #[[ATTR0]] = { memory(readwrite, argmem: none) } ;. -;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; CHECK: {{.*}} diff --git a/llvm/test/Transforms/Attributor/readattrs.ll b/llvm/test/Transforms/Attributor/readattrs.ll --- a/llvm/test/Transforms/Attributor/readattrs.ll +++ b/llvm/test/Transforms/Attributor/readattrs.ll @@ -90,7 +90,7 @@ define void @test7_1(ptr inalloca(i32) %a) { ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@test7_1 -; CHECK-SAME: (ptr nocapture nofree nonnull writeonly inalloca(i32) dereferenceable(4) [[A:%.*]]) #[[ATTR1]] { +; CHECK-SAME: (ptr nocapture nofree noundef nonnull writeonly inalloca(i32) dereferenceable(4) [[A:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: ret void ; ret void @@ -273,8 +273,8 @@ define void @byval_not_readonly_1(ptr byval(i8) %written) readonly { ; CHECK: Function Attrs: nosync memory(read) ; CHECK-LABEL: define {{[^@]+}}@byval_not_readonly_1 -; CHECK-SAME: (ptr noalias nonnull byval(i8) dereferenceable(1) [[WRITTEN:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: call void @escape_i8(ptr nonnull dereferenceable(1) [[WRITTEN]]) +; CHECK-SAME: (ptr noalias noundef nonnull byval(i8) dereferenceable(1) [[WRITTEN:%.*]]) #[[ATTR3]] { +; CHECK-NEXT: call void @escape_i8(ptr noundef nonnull dereferenceable(1) [[WRITTEN]]) ; CHECK-NEXT: ret void ; call void @escape_i8(ptr %written) @@ -295,14 +295,14 @@ define void @byval_not_readnone_1(ptr byval(i8) %written) readnone { ; TUNIT: Function Attrs: nosync memory(none) ; TUNIT-LABEL: define {{[^@]+}}@byval_not_readnone_1 -; TUNIT-SAME: (ptr noalias nonnull byval(i8) dereferenceable(1) [[WRITTEN:%.*]]) #[[ATTR12:[0-9]+]] { -; TUNIT-NEXT: call void @escape_i8(ptr nonnull dereferenceable(1) [[WRITTEN]]) +; TUNIT-SAME: (ptr noalias noundef nonnull byval(i8) dereferenceable(1) [[WRITTEN:%.*]]) #[[ATTR12:[0-9]+]] { +; TUNIT-NEXT: call void @escape_i8(ptr noundef nonnull dereferenceable(1) [[WRITTEN]]) ; TUNIT-NEXT: ret void ; ; CGSCC: Function Attrs: nosync memory(none) ; CGSCC-LABEL: define {{[^@]+}}@byval_not_readnone_1 -; CGSCC-SAME: (ptr noalias nonnull byval(i8) dereferenceable(1) [[WRITTEN:%.*]]) #[[ATTR13:[0-9]+]] { -; CGSCC-NEXT: call void @escape_i8(ptr nonnull dereferenceable(1) [[WRITTEN]]) +; CGSCC-SAME: (ptr noalias noundef nonnull byval(i8) dereferenceable(1) [[WRITTEN:%.*]]) #[[ATTR13:[0-9]+]] { +; CGSCC-NEXT: call void @escape_i8(ptr noundef nonnull dereferenceable(1) [[WRITTEN]]) ; CGSCC-NEXT: ret void ; call void @escape_i8(ptr %written) @@ -335,8 +335,8 @@ ; TUNIT: Function Attrs: nosync ; TUNIT-LABEL: define {{[^@]+}}@testbyval ; TUNIT-SAME: (ptr nocapture nonnull readonly [[READ_ONLY:%.*]]) #[[ATTR13:[0-9]+]] { -; TUNIT-NEXT: call void @byval_not_readonly_1(ptr noalias nocapture nonnull readonly byval(i8) [[READ_ONLY]]) #[[ATTR3]] -; TUNIT-NEXT: call void @byval_not_readnone_1(ptr noalias nocapture nonnull readnone byval(i8) [[READ_ONLY]]) #[[ATTR13]] +; TUNIT-NEXT: call void @byval_not_readonly_1(ptr noalias nocapture noundef nonnull readonly byval(i8) [[READ_ONLY]]) #[[ATTR3]] +; TUNIT-NEXT: call void @byval_not_readnone_1(ptr noalias nocapture noundef nonnull readnone byval(i8) [[READ_ONLY]]) #[[ATTR13]] ; TUNIT-NEXT: call void @byval_no_fnarg(ptr noalias nocapture nofree noundef nonnull readonly byval(i8) [[READ_ONLY]]) #[[ATTR19:[0-9]+]] ; TUNIT-NEXT: ret void ; diff --git a/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll b/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll --- a/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll +++ b/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll @@ -1114,7 +1114,7 @@ define void @noalias_arg_simplifiable_1(ptr noalias sret(%struct.S) align 4 %agg.result, ptr byval(%struct.S) align 8 %s) { ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@noalias_arg_simplifiable_1 -; TUNIT-SAME: (ptr noalias nocapture nofree writeonly sret([[STRUCT_S:%.*]]) align 4 dereferenceable_or_null(24) [[AGG_RESULT:%.*]], ptr noalias nocapture nofree nonnull byval([[STRUCT_S]]) align 8 dereferenceable(24) [[S:%.*]]) #[[ATTR1]] { +; TUNIT-SAME: (ptr noalias nocapture nofree writeonly sret([[STRUCT_S:%.*]]) align 4 dereferenceable_or_null(24) [[AGG_RESULT:%.*]], ptr noalias nocapture nofree noundef nonnull byval([[STRUCT_S]]) align 8 dereferenceable(24) [[S:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 3 ; TUNIT-NEXT: store float 0x3FF19999A0000000, ptr [[F1]], align 4, !tbaa [[TBAA7]] diff --git a/llvm/test/Transforms/Attributor/value-simplify.ll b/llvm/test/Transforms/Attributor/value-simplify.ll --- a/llvm/test/Transforms/Attributor/value-simplify.ll +++ b/llvm/test/Transforms/Attributor/value-simplify.ll @@ -449,7 +449,7 @@ define internal ptr @test_inalloca(ptr inalloca(i32) %a) { ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@test_inalloca -; TUNIT-SAME: (ptr noalias nofree nonnull returned writeonly inalloca(i32) dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2]] { +; TUNIT-SAME: (ptr noalias nofree noundef nonnull returned writeonly inalloca(i32) dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2]] { ; TUNIT-NEXT: ret ptr [[A]] ; ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) @@ -463,7 +463,7 @@ ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@complicated_args_inalloca ; TUNIT-SAME: (ptr nofree nonnull readnone "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR2]] { -; TUNIT-NEXT: [[CALL:%.*]] = call nonnull dereferenceable(4) ptr @test_inalloca(ptr noalias nofree nonnull writeonly inalloca(i32) "no-capture-maybe-returned" [[ARG]]) #[[ATTR9:[0-9]+]] +; TUNIT-NEXT: [[CALL:%.*]] = call noundef nonnull dereferenceable(4) ptr @test_inalloca(ptr noalias nofree noundef nonnull writeonly inalloca(i32) "no-capture-maybe-returned" [[ARG]]) #[[ATTR9:[0-9]+]] ; TUNIT-NEXT: ret ptr [[CALL]] ; ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)