Skip to content

[Attributor][FIX] Mark "may" accesses through call sites as such #107439

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions llvm/lib/Transforms/IPO/AttributorAttributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -1410,16 +1411,20 @@ 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()
: RAcc.getRanges();
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());
}
}
}
Expand Down Expand Up @@ -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
Expand Down
28 changes: 20 additions & 8 deletions llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
Loading