Index: llvm/lib/Transforms/IPO/AttributorAttributes.cpp =================================================================== --- llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -2427,7 +2427,25 @@ /// See AbstractAttribute::updateImpl(...). ChangeStatus updateImpl(Attributor &A) override { - // TODO: Implement this. + // If the associated value is a local global variable and it is used only + // only one time, we can deduce noalias for it. + // TODO: Add more deductions. + auto CheckAliveUseCount = [&]() { + int AliveUseCount = 0; + auto UsePred = [&](const Use &U, bool &) { + AliveUseCount++; + return AliveUseCount <= 1; + }; + return A.checkForAllUses(UsePred, *this, getAssociatedValue()); + }; + if (auto *GV = dyn_cast(&getAssociatedValue())) { + if (GV->hasLocalLinkage() && CheckAliveUseCount()) + return ChangeStatus::UNCHANGED; + } else if (auto *GV = dyn_cast(&getAssociatedValue())) { + if (GV->hasLocalLinkage() && CheckAliveUseCount()) + return ChangeStatus::UNCHANGED; + } + return indicatePessimisticFixpoint(); } Index: llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll =================================================================== --- llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll +++ llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll @@ -21,7 +21,7 @@ ; CHECK-LABEL: define {{[^@]+}}@main ; CHECK-SAME: (i32 [[ARGC:%.*]], i8** nocapture nofree readnone [[ARGV:%.*]]) { ; CHECK-NEXT: entry: -; CHECK-NEXT: tail call void (i8*, i8*, i8*, i8*, i8*, ...) @callee_t0f(i8* undef, i8* undef, i8* undef, i8* undef, i8* undef, %struct.tt0* noundef nonnull byval align 8 dereferenceable(16) @t45) +; CHECK-NEXT: tail call void (i8*, i8*, i8*, i8*, i8*, ...) @callee_t0f(i8* undef, i8* undef, i8* undef, i8* undef, i8* undef, %struct.tt0* noalias noundef nonnull byval align 8 dereferenceable(16) @t45) ; CHECK-NEXT: ret i32 0 ; entry: Index: llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll @@ -106,7 +106,7 @@ ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@unions ; IS__TUNIT_OPM-SAME: () [[ATTR1:#.*]] { ; IS__TUNIT_OPM-NEXT: entry: -; IS__TUNIT_OPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2(%struct.MYstr* nocapture nofree noundef nonnull readonly byval align 8 dereferenceable(8) @mystr) [[ATTR0]] +; IS__TUNIT_OPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2(%struct.MYstr* noalias nocapture nofree noundef nonnull readonly byval align 8 dereferenceable(8) @mystr) [[ATTR0]] ; IS__TUNIT_OPM-NEXT: ret i32 [[RESULT]] ; ; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind willreturn @@ -217,7 +217,7 @@ ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@unions_v2 ; IS__TUNIT_OPM-SAME: () [[ATTR2]] { ; IS__TUNIT_OPM-NEXT: entry: -; IS__TUNIT_OPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2_v2(%struct.MYstr* nocapture nofree noundef nonnull readonly byval align 8 dereferenceable(8) @mystr) [[ATTR2]] +; IS__TUNIT_OPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2_v2(%struct.MYstr* noalias nocapture nofree noundef nonnull readonly byval align 8 dereferenceable(8) @mystr) [[ATTR2]] ; IS__TUNIT_OPM-NEXT: ret i32 [[RESULT]] ; ; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn Index: llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll @@ -126,13 +126,21 @@ } define void @foo() { -; CHECK-LABEL: define {{[^@]+}}@foo() { -; CHECK-NEXT: entry: -; CHECK-NEXT: call void @broker(i32 (i32)* noundef nonnull @cb0, i32 (i32)* noundef nonnull @cb1, i32 (i32)* noundef nonnull @cb0, i32 noundef 0, i32 noundef 1) -; CHECK-NEXT: call void @broker(i32 (i32)* noundef nonnull @cb1, i32 (i32)* noundef nonnull @cb2, i32 (i32)* noundef nonnull @cb2, i32 noundef 0, i32 noundef 1) -; CHECK-NEXT: call void @broker(i32 (i32)* noundef nonnull @cb3, i32 (i32)* noundef nonnull @cb2, i32 (i32)* noundef nonnull @cb3, i32 noundef 0, i32 noundef 1) -; CHECK-NEXT: call void @broker(i32 (i32)* noundef nonnull @cb4, i32 (i32)* noundef nonnull @cb4, i32 (i32)* noundef nonnull @cb4, i32 noundef 0, i32 noundef 1) -; CHECK-NEXT: ret void +; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@foo() { +; NOT_TUNIT_NPM-NEXT: entry: +; NOT_TUNIT_NPM-NEXT: call void @broker(i32 (i32)* noundef nonnull @cb0, i32 (i32)* noundef nonnull @cb1, i32 (i32)* noundef nonnull @cb0, i32 noundef 0, i32 noundef 1) +; NOT_TUNIT_NPM-NEXT: call void @broker(i32 (i32)* noundef nonnull @cb1, i32 (i32)* noundef nonnull @cb2, i32 (i32)* noundef nonnull @cb2, i32 noundef 0, i32 noundef 1) +; NOT_TUNIT_NPM-NEXT: call void @broker(i32 (i32)* noundef nonnull @cb3, i32 (i32)* noundef nonnull @cb2, i32 (i32)* noundef nonnull @cb3, i32 noundef 0, i32 noundef 1) +; NOT_TUNIT_NPM-NEXT: call void @broker(i32 (i32)* noundef nonnull @cb4, i32 (i32)* noundef nonnull @cb4, i32 (i32)* noundef nonnull @cb4, i32 noundef 0, i32 noundef 1) +; NOT_TUNIT_NPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@foo() { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: call void @broker(i32 (i32)* noundef nonnull @cb0, i32 (i32)* noalias noundef nonnull @cb1, i32 (i32)* noundef nonnull @cb0, i32 noundef 0, i32 noundef 1) +; IS__TUNIT_NPM-NEXT: call void @broker(i32 (i32)* noalias noundef nonnull @cb1, i32 (i32)* noundef nonnull @cb2, i32 (i32)* noundef nonnull @cb2, i32 noundef 0, i32 noundef 1) +; IS__TUNIT_NPM-NEXT: call void @broker(i32 (i32)* noundef nonnull @cb3, i32 (i32)* noalias noundef nonnull @cb2, i32 (i32)* noundef nonnull @cb3, i32 noundef 0, i32 noundef 1) +; IS__TUNIT_NPM-NEXT: call void @broker(i32 (i32)* noundef nonnull @cb4, i32 (i32)* noundef nonnull @cb4, i32 (i32)* noundef nonnull @cb4, i32 noundef 0, i32 noundef 1) +; IS__TUNIT_NPM-NEXT: ret void ; entry: %call = call i32 @cb0(i32 0) Index: llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll @@ -47,7 +47,7 @@ ; IS__TUNIT_NPM-NEXT: store i32 [[N]], i32* [[N_ADDR]], align 4 ; IS__TUNIT_NPM-NEXT: store float 3.000000e+00, float* [[P]], align 4 ; IS__TUNIT_NPM-NEXT: store i32 7, i32* [[N_ADDR]], align 4 -; IS__TUNIT_NPM-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB1:@.*]], i32 noundef 3, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[N_ADDR]], float* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[P]], i64 undef) +; IS__TUNIT_NPM-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noalias noundef nonnull align 8 dereferenceable(24) [[GLOB1:@.*]], i32 noundef 3, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[N_ADDR]], float* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[P]], i64 undef) ; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@foo @@ -69,7 +69,7 @@ ; IS__CGSCC_NPM-NEXT: store i32 [[N]], i32* [[N_ADDR]], align 4 ; IS__CGSCC_NPM-NEXT: store float 3.000000e+00, float* [[P]], align 4 ; IS__CGSCC_NPM-NEXT: store i32 7, i32* [[N_ADDR]], align 4 -; IS__CGSCC_NPM-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB1:@.*]], i32 noundef 3, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[N_ADDR]], float* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[P]], i64 noundef 4617315517961601024) +; IS__CGSCC_NPM-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noalias noundef nonnull align 8 dereferenceable(24) [[GLOB1:@.*]], i32 noundef 3, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[N_ADDR]], float* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[P]], i64 noundef 4617315517961601024) ; IS__CGSCC_NPM-NEXT: ret void ; entry: @@ -139,7 +139,7 @@ ; IS________OPM-NEXT: br label [[OMP_LOOP_EXIT:%.*]] ; IS________OPM: omp.loop.exit: ; IS________OPM-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 -; IS________OPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 [[TMP12]]) +; IS________OPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* noalias noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 [[TMP12]]) ; IS________OPM-NEXT: br label [[OMP_PRECOND_END]] ; IS________OPM: omp.precond.end: ; IS________OPM-NEXT: ret void @@ -164,7 +164,7 @@ ; IS________NPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4 ; IS________NPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4 ; IS________NPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 -; IS________NPM-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0:@.*]], i32 [[TMP5]], i32 noundef 34, i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 noundef 1, i32 noundef 1) +; IS________NPM-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* noalias noundef nonnull align 8 dereferenceable(24) [[GLOB0:@.*]], i32 [[TMP5]], i32 noundef 34, i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 noundef 1, i32 noundef 1) ; IS________NPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 ; IS________NPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[TMP6]], [[SUB3]] ; IS________NPM-NEXT: br i1 [[CMP6]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -200,7 +200,7 @@ ; IS________NPM-NEXT: br label [[OMP_LOOP_EXIT:%.*]] ; IS________NPM: omp.loop.exit: ; IS________NPM-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 -; IS________NPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 [[TMP12]]) +; IS________NPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* noalias noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 [[TMP12]]) ; IS________NPM-NEXT: br label [[OMP_PRECOND_END]] ; IS________NPM: omp.precond.end: ; IS________NPM-NEXT: ret void Index: llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll @@ -31,16 +31,27 @@ ; FIXME: nocapture & noalias for %alloc2 in %call3 define dso_local i32 @main() { -; IS__TUNIT____-LABEL: define {{[^@]+}}@main() { -; IS__TUNIT____-NEXT: entry: -; IS__TUNIT____-NEXT: [[ALLOC1:%.*]] = alloca i8, align 8 -; IS__TUNIT____-NEXT: [[ALLOC2:%.*]] = alloca i8, align 8 -; IS__TUNIT____-NEXT: [[THREAD:%.*]] = alloca i64, align 8 -; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @foo, i8* noalias nocapture nofree readnone align 536870912 undef) -; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @bar, i8* noalias nofree nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" undef) -; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @baz, i8* noalias nocapture nofree noundef nonnull readnone align 8 dereferenceable(1) [[ALLOC1]]) -; IS__TUNIT____-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @buz, i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[ALLOC2]]) -; IS__TUNIT____-NEXT: ret i32 0 +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@main() { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[ALLOC1:%.*]] = alloca i8, align 8 +; IS__TUNIT_OPM-NEXT: [[ALLOC2:%.*]] = alloca i8, align 8 +; IS__TUNIT_OPM-NEXT: [[THREAD:%.*]] = alloca i64, align 8 +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @foo, i8* noalias nocapture nofree readnone align 536870912 undef) +; IS__TUNIT_OPM-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @bar, i8* noalias nofree nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" undef) +; IS__TUNIT_OPM-NEXT: [[CALL2:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @baz, i8* noalias nocapture nofree noundef nonnull readnone align 8 dereferenceable(1) [[ALLOC1]]) +; IS__TUNIT_OPM-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @buz, i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[ALLOC2]]) +; IS__TUNIT_OPM-NEXT: ret i32 0 +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@main() { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[ALLOC1:%.*]] = alloca i8, align 8 +; IS__TUNIT_NPM-NEXT: [[ALLOC2:%.*]] = alloca i8, align 8 +; IS__TUNIT_NPM-NEXT: [[THREAD:%.*]] = alloca i64, align 8 +; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noalias noundef nonnull @foo, i8* noalias nocapture nofree readnone align 536870912 undef) +; IS__TUNIT_NPM-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noalias noundef nonnull @bar, i8* noalias nofree nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" undef) +; IS__TUNIT_NPM-NEXT: [[CALL2:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noalias noundef nonnull @baz, i8* noalias nocapture nofree noundef nonnull readnone align 8 dereferenceable(1) [[ALLOC1]]) +; IS__TUNIT_NPM-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noalias noundef nonnull @buz, i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[ALLOC2]]) +; IS__TUNIT_NPM-NEXT: ret i32 0 ; ; IS__CGSCC____-LABEL: define {{[^@]+}}@main() { ; IS__CGSCC____-NEXT: entry: Index: llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll =================================================================== --- llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll +++ llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll @@ -50,10 +50,15 @@ } define dso_local void @caller() { -; IS__TUNIT____-LABEL: define {{[^@]+}}@caller() { -; IS__TUNIT____-NEXT: entry: -; IS__TUNIT____-NEXT: call void @broker(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) @gtl, i32 (i32*, i32*)* noundef nonnull @callee, i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) undef) -; IS__TUNIT____-NEXT: ret void +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@caller() { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: call void @broker(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) @gtl, i32 (i32*, i32*)* noundef nonnull @callee, i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) undef) +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@caller() { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: call void @broker(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) @gtl, i32 (i32*, i32*)* noalias noundef nonnull @callee, i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) undef) +; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC____-LABEL: define {{[^@]+}}@caller() { ; IS__CGSCC____-NEXT: entry: Index: llvm/test/Transforms/Attributor/misc.ll =================================================================== --- llvm/test/Transforms/Attributor/misc.ll +++ llvm/test/Transforms/Attributor/misc.ll @@ -15,7 +15,7 @@ ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 ; CHECK-NEXT: call void @foo(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]]) [[ATTR1:#.*]] ; CHECK-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*)) -; CHECK-NEXT: call void @callback1(void (i32*)* noundef nonnull @foo) +; CHECK-NEXT: call void @callback1(void (i32*)* noalias noundef nonnull @foo) ; CHECK-NEXT: call void @callback2(void (i8*)* noundef bitcast (void (i32*)* @foo to void (i8*)*)) ; CHECK-NEXT: call void @callback2(void (i8*)* nonnull [[FP]]) ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8* @@ -38,19 +38,33 @@ define void @external(void (i8*)* %fp) { ; ; -; CHECK-LABEL: define {{[^@]+}}@external -; CHECK-SAME: (void (i8*)* [[FP:%.*]]) { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 -; CHECK-NEXT: call void @foo(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]]) [[ATTR1]] -; CHECK-NEXT: call void @callback1(void (i32*)* noundef nonnull @foo) -; CHECK-NEXT: call void @callback2(void (i8*)* noundef bitcast (void (i32*)* @foo to void (i8*)*)) -; CHECK-NEXT: call void @callback2(void (i8*)* [[FP]]) -; CHECK-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*)) -; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8* -; CHECK-NEXT: call void [[FP]](i8* [[TMP1]]) -; CHECK-NEXT: call void @internal(void (i8*)* nonnull [[FP]]) -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@external +; IS__TUNIT____-SAME: (void (i8*)* [[FP:%.*]]) { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[A:%.*]] = alloca i32, align 4 +; IS__TUNIT____-NEXT: call void @foo(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]]) [[ATTR2:#.*]] +; IS__TUNIT____-NEXT: call void @callback1(void (i32*)* noalias noundef nonnull @foo) +; IS__TUNIT____-NEXT: call void @callback2(void (i8*)* noundef bitcast (void (i32*)* @foo to void (i8*)*)) +; IS__TUNIT____-NEXT: call void @callback2(void (i8*)* [[FP]]) +; IS__TUNIT____-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*)) +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8* +; IS__TUNIT____-NEXT: call void [[FP]](i8* [[TMP1]]) +; IS__TUNIT____-NEXT: call void @internal(void (i8*)* nonnull [[FP]]) +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@external +; IS__CGSCC____-SAME: (void (i8*)* [[FP:%.*]]) { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i32, align 4 +; IS__CGSCC____-NEXT: call void @foo(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]]) [[ATTR1:#.*]] +; IS__CGSCC____-NEXT: call void @callback1(void (i32*)* noalias noundef nonnull @foo) +; IS__CGSCC____-NEXT: call void @callback2(void (i8*)* noundef bitcast (void (i32*)* @foo to void (i8*)*)) +; IS__CGSCC____-NEXT: call void @callback2(void (i8*)* [[FP]]) +; IS__CGSCC____-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*)) +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8* +; IS__CGSCC____-NEXT: call void [[FP]](i8* [[TMP1]]) +; IS__CGSCC____-NEXT: call void @internal(void (i8*)* nonnull [[FP]]) +; IS__CGSCC____-NEXT: ret void ; entry: %a = alloca i32, align 4 Index: llvm/test/Transforms/Attributor/misc_crash.ll =================================================================== --- llvm/test/Transforms/Attributor/misc_crash.ll +++ llvm/test/Transforms/Attributor/misc_crash.ll @@ -41,7 +41,7 @@ define internal void @func2a(i32* %0) { ; CHECK: Function Attrs: nofree nosync nounwind willreturn writeonly ; CHECK-LABEL: define {{[^@]+}}@func2a -; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]]) [[ATTR1:#.*]] { +; CHECK-SAME: (i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]]) [[ATTR1:#.*]] { ; CHECK-NEXT: store i32 0, i32* @var2, align 4 ; CHECK-NEXT: ret void ; @@ -51,7 +51,7 @@ define i32 @func2() { ; CHECK-LABEL: define {{[^@]+}}@func2() { -; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 (i32*, ...) bitcast (void (i32*)* @func2a to i32 (i32*, ...)*)(i32* noundef nonnull align 4 dereferenceable(4) @var2) +; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 (i32*, ...) bitcast (void (i32*)* @func2a to i32 (i32*, ...)*)(i32* noalias noundef nonnull align 4 dereferenceable(4) @var2) ; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* @var2, align 4 ; CHECK-NEXT: ret i32 [[TMP2]] ; @@ -63,7 +63,7 @@ define i32 @func3(i1 %false) { ; CHECK-LABEL: define {{[^@]+}}@func3 ; CHECK-SAME: (i1 [[FALSE:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 (i32*, ...) bitcast (void (i32*)* @func2a to i32 (i32*, ...)*)(i32* noundef nonnull align 4 dereferenceable(4) @var2) +; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 (i32*, ...) bitcast (void (i32*)* @func2a to i32 (i32*, ...)*)(i32* noalias noundef nonnull align 4 dereferenceable(4) @var2) ; CHECK-NEXT: br i1 [[FALSE]], label [[USE_BB:%.*]], label [[RET_BB:%.*]] ; CHECK: use_bb: ; CHECK-NEXT: ret i32 [[TMP1]] Index: llvm/test/Transforms/Attributor/noundef.ll =================================================================== --- llvm/test/Transforms/Attributor/noundef.ll +++ llvm/test/Transforms/Attributor/noundef.ll @@ -51,7 +51,7 @@ define void @callback_caller() { ; IS__TUNIT____-LABEL: define {{[^@]+}}@callback_caller() { -; IS__TUNIT____-NEXT: call void @callback_broker(void (i8*)* noundef @argument_dead_callback_callee, i8* noalias nocapture nofree readnone align 536870912 undef) +; IS__TUNIT____-NEXT: call void @callback_broker(void (i8*)* noalias noundef @argument_dead_callback_callee, i8* noalias nocapture nofree readnone align 536870912 undef) ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____-LABEL: define {{[^@]+}}@callback_caller() {