diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp index 69d29b6c04234..6b6d6d8d2a1e4 100644 --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -1397,7 +1397,8 @@ struct AAPointerInfoImpl } ChangeStatus translateAndAddState(Attributor &A, const AAPointerInfo &OtherAA, - const OffsetInfo &Offsets, CallBase &CB) { + const OffsetInfo &Offsets, CallBase &CB, + bool IsMustAcc) { using namespace AA::PointerInfo; if (!OtherAA.getState().isValidState() || !isValidState()) return indicatePessimisticFixpoint(); @@ -1410,6 +1411,8 @@ struct AAPointerInfoImpl for (const auto &It : State) { for (auto Index : It.getSecond()) { const auto &RAcc = State.getAccess(Index); + if (!IsMustAcc && RAcc.isAssumption()) + continue; for (auto Offset : Offsets) { auto NewRanges = Offset == AA::RangeTy::Unknown ? AA::RangeTy::getUnknown() @@ -1417,9 +1420,11 @@ struct AAPointerInfoImpl if (!NewRanges.isUnknown()) { NewRanges.addToAllOffsets(Offset); } - Changed |= - addAccess(A, NewRanges, CB, RAcc.getContent(), RAcc.getKind(), - RAcc.getType(), RAcc.getRemoteInst()); + AccessKind AK = RAcc.getKind(); + if (!IsMustAcc) + AK = AccessKind((AK & ~AK_MUST) | AK_MAY); + Changed |= addAccess(A, NewRanges, CB, RAcc.getContent(), AK, + RAcc.getType(), RAcc.getRemoteInst()); } } } @@ -1893,9 +1898,10 @@ ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) { DepClassTy::REQUIRED); if (!CSArgPI) return false; - Changed = - translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB) | - Changed; + bool IsMustAcc = (getUnderlyingObject(CurPtr) == &AssociatedValue); + Changed = translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB, + IsMustAcc) | + Changed; return isValidState(); } LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB diff --git a/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll b/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll index f7f92e3c87a62..69bff7b5e783e 100644 --- a/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll +++ b/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll @@ -3176,7 +3176,7 @@ define internal i32 @recSimplify2() { ret i32 %r } -; TODO: Verify we do not return 10. +; Verify we do not return 10. define i32 @may_access_after_return(i32 noundef %N, i32 noundef %M) { ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@may_access_after_return @@ -3185,7 +3185,10 @@ define i32 @may_access_after_return(i32 noundef %N, i32 noundef %M) { ; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4 ; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4 ; TUNIT-NEXT: call void @write_both(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]]) #[[ATTR18]] -; TUNIT-NEXT: ret i32 10 +; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4 +; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4 +; TUNIT-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] +; TUNIT-NEXT: ret i32 [[ADD]] ; ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return @@ -3237,7 +3240,7 @@ entry: ret ptr %P } -; TODO: Verify we do not return 10. +; Verify we do not return 10. define i32 @may_access_after_return_choice(i32 noundef %N, i32 noundef %M, i1 %c) { ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@may_access_after_return_choice @@ -3248,7 +3251,10 @@ define i32 @may_access_after_return_choice(i32 noundef %N, i32 noundef %M, i1 %c ; TUNIT-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[B]]) #[[ATTR23:[0-9]+]] ; TUNIT-NEXT: [[CALL1:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[B]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]]) #[[ATTR23]] ; TUNIT-NEXT: call void @write_both(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[CALL]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[CALL1]]) #[[ATTR18]] -; TUNIT-NEXT: ret i32 10 +; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4 +; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4 +; TUNIT-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] +; TUNIT-NEXT: ret i32 [[ADD]] ; ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn ; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return_choice @@ -3289,7 +3295,7 @@ entry: ret ptr %R } -; TODO: Verify we do not return 10. +; Verify we do not return 10. define i32 @may_access_after_return_no_choice1(i32 noundef %N, i32 noundef %M) { ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@may_access_after_return_no_choice1 @@ -3298,7 +3304,10 @@ define i32 @may_access_after_return_no_choice1(i32 noundef %N, i32 noundef %M) { ; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4 ; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4 ; TUNIT-NEXT: call void @write_both(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]]) #[[ATTR18]] -; TUNIT-NEXT: ret i32 10 +; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4 +; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4 +; TUNIT-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] +; TUNIT-NEXT: ret i32 [[ADD]] ; ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return_no_choice1 @@ -3324,7 +3333,7 @@ entry: ret i32 %add } -; TODO: Verify we do not return 10. +; Verify we do not return 10. define i32 @may_access_after_return_no_choice2(i32 noundef %N, i32 noundef %M) { ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@may_access_after_return_no_choice2 @@ -3333,7 +3342,10 @@ define i32 @may_access_after_return_no_choice2(i32 noundef %N, i32 noundef %M) { ; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4 ; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4 ; TUNIT-NEXT: call void @write_both(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]]) #[[ATTR18]] -; TUNIT-NEXT: ret i32 10 +; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4 +; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4 +; TUNIT-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] +; TUNIT-NEXT: ret i32 [[ADD]] ; ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return_no_choice2