diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -1098,6 +1098,12 @@ if (!State.isValidState()) continue; + // Restrict AA manifest to seleteted functions. + // This is important for CGSCC pass. + Function *Fn = AA->getAnchorScope(); + if (Fn && !Functions.count(Fn)) + continue; + // Skip dead code. if (isAssumedDead(*AA, nullptr, /* CheckBBLivenessOnly */ true)) continue; @@ -1107,7 +1113,6 @@ AA->trackStatistics(); LLVM_DEBUG(dbgs() << "[Attributor] Manifest " << LocalChange << " : " << *AA << "\n"); - ManifestChange = ManifestChange | LocalChange; NumAtFixpoint++; 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 @@ -17,25 +17,15 @@ ; IS________OPM-NEXT: [[TMP1:%.*]] = tail call i8* @foo(%pair* nonnull dereferenceable(8) [[DATA]]) ; IS________OPM-NEXT: ret void ; -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@bar -; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) -; IS__TUNIT_NPM-NEXT: [[DATA_PRIV:%.*]] = alloca [[PAIR:%.*]], align 8 -; IS__TUNIT_NPM-NEXT: [[DATA_PRIV_CAST:%.*]] = bitcast %pair* [[DATA_PRIV]] to i32* -; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[DATA_PRIV_CAST]], align 4 -; IS__TUNIT_NPM-NEXT: [[DATA_PRIV_0_1:%.*]] = getelementptr [[PAIR]], %pair* [[DATA_PRIV]], i32 0, i32 1 -; IS__TUNIT_NPM-NEXT: store i32 [[TMP1]], i32* [[DATA_PRIV_0_1]], align 4 -; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = call i8* @foo(%pair* nonnull dereferenceable(8) [[DATA_PRIV]]) -; IS__TUNIT_NPM-NEXT: ret void -; -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@bar -; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) -; IS__CGSCC_NPM-NEXT: [[DATA_PRIV:%.*]] = alloca [[PAIR:%.*]], align 8 -; IS__CGSCC_NPM-NEXT: [[DATA_PRIV_CAST:%.*]] = bitcast %pair* [[DATA_PRIV]] to i32* -; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[DATA_PRIV_CAST]], align 4 -; IS__CGSCC_NPM-NEXT: [[DATA_PRIV_0_1:%.*]] = getelementptr [[PAIR]], %pair* [[DATA_PRIV]], i32 0, i32 1 -; IS__CGSCC_NPM-NEXT: store i32 [[TMP1]], i32* [[DATA_PRIV_0_1]], align 4 -; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = call i8* @foo(%pair* nonnull align 8 dereferenceable(8) [[DATA_PRIV]]) -; IS__CGSCC_NPM-NEXT: ret void +; IS________NPM-LABEL: define {{[^@]+}}@bar +; IS________NPM-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) +; IS________NPM-NEXT: [[DATA_PRIV:%.*]] = alloca [[PAIR:%.*]], align 8 +; IS________NPM-NEXT: [[DATA_PRIV_CAST:%.*]] = bitcast %pair* [[DATA_PRIV]] to i32* +; IS________NPM-NEXT: store i32 [[TMP0]], i32* [[DATA_PRIV_CAST]], align 4 +; IS________NPM-NEXT: [[DATA_PRIV_0_1:%.*]] = getelementptr [[PAIR]], %pair* [[DATA_PRIV]], i32 0, i32 1 +; IS________NPM-NEXT: store i32 [[TMP1]], i32* [[DATA_PRIV_0_1]], align 4 +; IS________NPM-NEXT: [[TMP3:%.*]] = call i8* @foo(%pair* nonnull dereferenceable(8) [[DATA_PRIV]]) +; IS________NPM-NEXT: ret void ; tail call i8* @foo(%pair* %Data) ret void diff --git a/llvm/test/Transforms/Attributor/internalize.ll b/llvm/test/Transforms/Attributor/internalize.ll --- a/llvm/test/Transforms/Attributor/internalize.ll +++ b/llvm/test/Transforms/Attributor/internalize.ll @@ -26,6 +26,12 @@ ; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[B]] ; CHECK-NEXT: ret i32 [[C]] ; +; DWRAPPER-LABEL: define {{[^@]+}}@inner1 +; DWRAPPER-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) +; DWRAPPER-NEXT: entry: +; DWRAPPER-NEXT: [[C:%.*]] = add i32 [[A]], [[B]] +; DWRAPPER-NEXT: ret i32 [[C]] +; entry: %c = add i32 %a, %b ret i32 %c @@ -43,6 +49,12 @@ ; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[B]] ; CHECK-NEXT: ret i32 [[C]] ; +; DWRAPPER-LABEL: define {{[^@]+}}@inner2 +; DWRAPPER-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) +; DWRAPPER-NEXT: entry: +; DWRAPPER-NEXT: [[C:%.*]] = add i32 [[A]], [[B]] +; DWRAPPER-NEXT: ret i32 [[C]] +; entry: %c = add i32 %a, %b ret i32 %c @@ -63,6 +75,12 @@ ; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[B]] ; CHECK-NEXT: ret i32 [[C]] ; +; DWRAPPER-LABEL: define {{[^@]+}}@inner3 +; DWRAPPER-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) +; DWRAPPER-NEXT: entry: +; DWRAPPER-NEXT: [[C:%.*]] = add i32 [[A]], [[B]] +; DWRAPPER-NEXT: ret i32 [[C]] +; entry: %c = add i32 %a, %b ret i32 %c @@ -83,6 +101,12 @@ ; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[B]] ; CHECK-NEXT: ret i32 [[C]] ; +; DWRAPPER-LABEL: define {{[^@]+}}@inner4 +; DWRAPPER-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) +; DWRAPPER-NEXT: entry: +; DWRAPPER-NEXT: [[C:%.*]] = add i32 [[A]], [[B]] +; DWRAPPER-NEXT: ret i32 [[C]] +; entry: %c = add i32 %a, %b ret i32 %c @@ -99,6 +123,12 @@ ; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[B]] ; CHECK-NEXT: ret i32 [[C]] ; +; DWRAPPER-LABEL: define {{[^@]+}}@inner5 +; DWRAPPER-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) +; DWRAPPER-NEXT: entry: +; DWRAPPER-NEXT: [[C:%.*]] = add i32 [[A]], [[B]] +; DWRAPPER-NEXT: ret i32 [[C]] +; entry: %c = add i32 %a, %b ret i32 %c @@ -134,6 +164,14 @@ ; CHECK_ENABLED-NEXT: [[RET4:%.*]] = call i32 @inner4.internalized(i32 [[RET3]], i32 [[RET3]]) ; CHECK_ENABLED-NEXT: ret i32 [[RET4]] ; +; DWRAPPER-LABEL: define {{[^@]+}}@outer1() +; DWRAPPER-NEXT: entry: +; DWRAPPER-NEXT: [[RET1:%.*]] = call i32 @inner1(i32 1, i32 2) +; DWRAPPER-NEXT: [[RET2:%.*]] = call i32 @inner2(i32 1, i32 2) +; DWRAPPER-NEXT: [[RET3:%.*]] = call i32 @inner3.internalized(i32 [[RET1]], i32 [[RET2]]) +; DWRAPPER-NEXT: [[RET4:%.*]] = call i32 @inner4.internalized(i32 [[RET3]], i32 [[RET3]]) +; DWRAPPER-NEXT: ret i32 [[RET4]] +; entry: %ret1 = call i32 @inner1(i32 1, i32 2) %ret2 = call i32 @inner2(i32 1, i32 2) diff --git a/llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll b/llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll --- a/llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll +++ b/llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll @@ -47,11 +47,11 @@ ; ; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind ; IS__CGSCC____-LABEL: define {{[^@]+}}@external_ret2_nrw -; IS__CGSCC____-SAME: (i32* nofree [[N0:%.*]], i32* nofree align 4 [[R0:%.*]], i32* nofree returned [[W0:%.*]]) +; IS__CGSCC____-SAME: (i32* nofree [[N0:%.*]], i32* nofree [[R0:%.*]], i32* nofree returned [[W0:%.*]]) ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @internal_ret0_nw(i32* nofree [[N0]], i32* nofree [[W0]]) -; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @internal_ret1_rrw(i32* nofree align 4 [[R0]], i32* nofree align 4 [[R0]], i32* nofree [[W0]]) -; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree readonly align 4 [[R0]], i32* nofree writeonly [[W0]]) +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @internal_ret1_rrw(i32* nofree align 4 [[R0]], i32* nofree [[R0]], i32* nofree [[W0]]) +; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree readonly [[R0]], i32* nofree writeonly [[W0]]) ; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32* @internal_ret1_rw(i32* nofree align 4 [[R0]], i32* nofree [[W0]]) ; IS__CGSCC____-NEXT: ret i32* [[CALL3]] ; 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 @@ -464,7 +464,7 @@ ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test_byval -; IS__CGSCC_NPM-SAME: (i8* nocapture nofree readnone [[TMP0:%.*]]) +; IS__CGSCC_NPM-SAME: (i8* [[TMP0:%.*]]) ; IS__CGSCC_NPM-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_X:%.*]], align 8 ; IS__CGSCC_NPM-NEXT: [[A_PRIV_CAST:%.*]] = bitcast %struct.X* [[A_PRIV]] to i8** ; IS__CGSCC_NPM-NEXT: store i8* [[TMP0]], i8** [[A_PRIV_CAST]], align 8