From 2baf000ecc06209c70e46e19cf947a8f77cf0cad Mon Sep 17 00:00:00 2001 From: Johannes Doerfert Date: Sun, 12 Jan 2020 00:18:07 -0600 Subject: [PATCH] [Attributor] `byval` arguments are always `noalias` `byval` introduces a local copy of the argument. That copy cannot alias anything. --- llvm/lib/Transforms/IPO/Attributor.cpp | 8 ++++++++ llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll | 2 +- llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll | 2 +- llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll | 2 +- llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll | 6 +++--- .../Attributor/IPConstantProp/2009-09-24-byval-ptr.ll | 6 +++--- llvm/test/Transforms/Attributor/readattrs.ll | 10 +++++----- llvm/test/Transforms/Attributor/value-simplify.ll | 2 +- 8 files changed, 23 insertions(+), 15 deletions(-) diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp index 5eb21a0691b..19dc9989316 100644 --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -2386,6 +2386,14 @@ struct AANoAliasArgument final using Base = AAArgumentFromCallSiteArguments; AANoAliasArgument(const IRPosition &IRP) : Base(IRP) {} + /// See AbstractAttribute::initialize(...). + void initialize(Attributor &A) override { + Base::initialize(A); + // See callsite argument attribute and callee argument attribute. + if (hasAttr({Attribute::ByVal})) + indicateOptimisticFixpoint(); + } + /// See AbstractAttribute::update(...). ChangeStatus updateImpl(Attributor &A) override { // We have to make sure no-alias on the argument does not break diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll index 8f2e14d7bb3..ac9b0766b38 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll @@ -6,7 +6,7 @@ ; Don't drop 'byval' on %X here. define internal void @f(%struct.ss* byval %b, i32* byval %X, i32 %i) nounwind { ; CHECK-LABEL: define {{[^@]+}}@f -; CHECK-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 8 dereferenceable(12) [[B:%.*]], i32* nocapture nofree nonnull writeonly byval dereferenceable(4) [[X:%.*]], i32 [[I:%.*]]) +; CHECK-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 8 dereferenceable(12) [[B:%.*]], i32* noalias nocapture nofree nonnull writeonly byval dereferenceable(4) [[X:%.*]], i32 [[I:%.*]]) ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[B]], i32 0, i32 0 ; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8 diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll index 2ebf5ec4aa4..12e02f855f7 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll @@ -5,7 +5,7 @@ define internal void @f(%struct.ss* byval %b, i32* byval %X) nounwind { ; CHECK-LABEL: define {{[^@]+}}@f -; CHECK-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 8 dereferenceable(12) [[B:%.*]], i32* nocapture nofree nonnull writeonly byval dereferenceable(4) [[X:%.*]]) +; CHECK-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 8 dereferenceable(12) [[B:%.*]], i32* noalias nocapture nofree nonnull writeonly byval dereferenceable(4) [[X:%.*]]) ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[B]], i32 0, i32 0 ; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8 diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll index 153ce6893ba..6a6864b3b3e 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll @@ -48,7 +48,7 @@ define internal i64 @AccessPaddingOfStruct(%struct.Foo* byval %a) { define internal i64 @CaptureAStruct(%struct.Foo* byval %a) { ; CHECK-LABEL: define {{[^@]+}}@CaptureAStruct -; CHECK-SAME: (%struct.Foo* nofree nonnull byval align 8 dereferenceable(16) [[A:%.*]]) +; CHECK-SAME: (%struct.Foo* noalias nofree nonnull byval align 8 dereferenceable(16) [[A:%.*]]) ; CHECK-NEXT: entry: ; CHECK-NEXT: [[A_PTR:%.*]] = alloca %struct.Foo* ; CHECK-NEXT: br label [[LOOP:%.*]] diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll index 2a34bde6636..6f55d4acab9 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll @@ -10,7 +10,7 @@ declare i8* @foo(%pair*) define internal void @bar(%pair* byval %Data) { ; CHECK-LABEL: define {{[^@]+}}@bar -; CHECK-SAME: (%pair* byval [[DATA:%.*]]) +; CHECK-SAME: (%pair* noalias byval [[DATA:%.*]]) ; CHECK-NEXT: [[TMP1:%.*]] = tail call i8* @foo(%pair* [[DATA]]) ; CHECK-NEXT: ret void ; @@ -20,8 +20,8 @@ define internal void @bar(%pair* byval %Data) { define void @zed(%pair* byval %Data) { ; CHECK-LABEL: define {{[^@]+}}@zed -; CHECK-SAME: (%pair* nocapture readonly byval [[DATA:%.*]]) -; CHECK-NEXT: call void @bar(%pair* nocapture readonly byval [[DATA]]) +; CHECK-SAME: (%pair* noalias nocapture readonly byval [[DATA:%.*]]) +; CHECK-NEXT: call void @bar(%pair* noalias nocapture readonly byval [[DATA]]) ; CHECK-NEXT: ret void ; call void @bar(%pair* byval %Data) diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll b/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll index 8616794fc3f..55175d70db6 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll @@ -6,7 +6,7 @@ @mystr = internal global %struct.MYstr zeroinitializer ; <%struct.MYstr*> [#uses=3] define internal void @vfu1(%struct.MYstr* byval align 4 %u) nounwind { ; CHECK-LABEL: define {{[^@]+}}@vfu1 -; CHECK-SAME: (%struct.MYstr* nocapture nofree nonnull writeonly byval align 8 dereferenceable(8) [[U:%.*]]) +; CHECK-SAME: (%struct.MYstr* noalias nocapture nofree nonnull writeonly byval align 8 dereferenceable(8) [[U:%.*]]) ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* [[U]], i32 0, i32 1 ; CHECK-NEXT: store i32 99, i32* [[TMP0]], align 4 @@ -29,7 +29,7 @@ return: ; preds = %entry define internal i32 @vfu2(%struct.MYstr* byval align 4 %u) nounwind readonly { ; CHECK-LABEL: define {{[^@]+}}@vfu2 -; CHECK-SAME: (%struct.MYstr* nocapture nofree nonnull readonly byval align 8 dereferenceable(8) [[U:%.*]]) +; CHECK-SAME: (%struct.MYstr* noalias nocapture nofree nonnull readonly byval align 8 dereferenceable(8) [[U:%.*]]) ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* @mystr, i32 0, i32 1 ; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]] @@ -64,7 +64,7 @@ entry: define internal i32 @vfu2_v2(%struct.MYstr* byval align 4 %u) nounwind readonly { ; CHECK-LABEL: define {{[^@]+}}@vfu2_v2 -; CHECK-SAME: (%struct.MYstr* nocapture nofree nonnull byval align 8 dereferenceable(8) [[U:%.*]]) +; CHECK-SAME: (%struct.MYstr* noalias nocapture nofree nonnull byval align 8 dereferenceable(8) [[U:%.*]]) ; CHECK-NEXT: entry: ; CHECK-NEXT: [[Z:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* [[U]], i32 0, i32 1 ; CHECK-NEXT: store i32 99, i32* [[Z]], align 4 diff --git a/llvm/test/Transforms/Attributor/readattrs.ll b/llvm/test/Transforms/Attributor/readattrs.ll index cfb4f71ce0e..aa272a3e023 100644 --- a/llvm/test/Transforms/Attributor/readattrs.ll +++ b/llvm/test/Transforms/Attributor/readattrs.ll @@ -150,35 +150,35 @@ define void @unsound_readonly(i8* %ignored, i8* %escaped_then_written) { declare void @escape_i8(i8* %ptr) ; ATTRIBUTOR: @byval_not_readonly_1 -; ATTRIBUTOR-SAME: i8* byval %written +; ATTRIBUTOR-SAME: i8* noalias byval %written define void @byval_not_readonly_1(i8* byval %written) readonly { call void @escape_i8(i8* %written) ret void } ; ATTRIBUTOR: @byval_not_readonly_2 -; ATTRIBUTOR-SAME: i8* nocapture nofree nonnull writeonly byval dereferenceable(1) %written +; ATTRIBUTOR-SAME: i8* noalias nocapture nofree nonnull writeonly byval dereferenceable(1) %written define void @byval_not_readonly_2(i8* byval %written) readonly { store i8 0, i8* %written ret void } ; ATTRIBUTOR: @byval_not_readnone_1 -; ATTRIBUTOR-SAME: i8* byval %written +; ATTRIBUTOR-SAME: i8* noalias byval %written define void @byval_not_readnone_1(i8* byval %written) readnone { call void @escape_i8(i8* %written) ret void } ; ATTRIBUTOR: @byval_not_readnone_2 -; ATTRIBUTOR-SAME: i8* nocapture nofree nonnull writeonly byval dereferenceable(1) %written +; ATTRIBUTOR-SAME: i8* noalias nocapture nofree nonnull writeonly byval dereferenceable(1) %written define void @byval_not_readnone_2(i8* byval %written) readnone { store i8 0, i8* %written ret void } ; ATTRIBUTOR: @byval_no_fnarg -; ATTRIBUTOR-SAME: i8* nocapture nofree nonnull writeonly byval dereferenceable(1) %written +; ATTRIBUTOR-SAME: i8* noalias nocapture nofree nonnull writeonly byval dereferenceable(1) %written define void @byval_no_fnarg(i8* byval %written) { store i8 0, i8* %written ret void diff --git a/llvm/test/Transforms/Attributor/value-simplify.ll b/llvm/test/Transforms/Attributor/value-simplify.ll index 046521a7cd9..b2563ad09be 100644 --- a/llvm/test/Transforms/Attributor/value-simplify.ll +++ b/llvm/test/Transforms/Attributor/value-simplify.ll @@ -246,7 +246,7 @@ define %struct.X* @complicated_args_nest() { @S = external global %struct.X define internal void @test_byval(%struct.X* byval %a) { ; CHECK-LABEL: define {{[^@]+}}@test_byval -; CHECK-SAME: (%struct.X* nocapture nofree nonnull writeonly byval align 8 dereferenceable(8) [[A:%.*]]) +; CHECK-SAME: (%struct.X* noalias nocapture nofree nonnull writeonly byval align 8 dereferenceable(8) [[A:%.*]]) ; CHECK-NEXT: [[G0:%.*]] = getelementptr [[STRUCT_X:%.*]], %struct.X* [[A]], i32 0, i32 0 ; CHECK-NEXT: store i8* null, i8** [[G0]], align 8 ; CHECK-NEXT: ret void -- 2.11.0