Skip to content

Commit edc76af

Browse files
committed
[Attributor][FIX] Mark "may" accesses through call sites as such
Before, we kept the call site access kind (may/must) when we translated the access. However, the pointer we access it through (by passing it to the callee) might not be the underlying object. We have similar logic when we add store and load accesses.
1 parent 4ce8808 commit edc76af

File tree

2 files changed

+33
-15
lines changed

2 files changed

+33
-15
lines changed

llvm/lib/Transforms/IPO/AttributorAttributes.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,7 +1397,8 @@ struct AAPointerInfoImpl
13971397
}
13981398

13991399
ChangeStatus translateAndAddState(Attributor &A, const AAPointerInfo &OtherAA,
1400-
const OffsetInfo &Offsets, CallBase &CB) {
1400+
const OffsetInfo &Offsets, CallBase &CB,
1401+
bool IsMustAcc) {
14011402
using namespace AA::PointerInfo;
14021403
if (!OtherAA.getState().isValidState() || !isValidState())
14031404
return indicatePessimisticFixpoint();
@@ -1410,16 +1411,20 @@ struct AAPointerInfoImpl
14101411
for (const auto &It : State) {
14111412
for (auto Index : It.getSecond()) {
14121413
const auto &RAcc = State.getAccess(Index);
1414+
if (!IsMustAcc && RAcc.isAssumption())
1415+
continue;
14131416
for (auto Offset : Offsets) {
14141417
auto NewRanges = Offset == AA::RangeTy::Unknown
14151418
? AA::RangeTy::getUnknown()
14161419
: RAcc.getRanges();
14171420
if (!NewRanges.isUnknown()) {
14181421
NewRanges.addToAllOffsets(Offset);
14191422
}
1420-
Changed |=
1421-
addAccess(A, NewRanges, CB, RAcc.getContent(), RAcc.getKind(),
1422-
RAcc.getType(), RAcc.getRemoteInst());
1423+
AccessKind AK = RAcc.getKind();
1424+
if (!IsMustAcc)
1425+
AK = AccessKind((AK & ~AK_MUST) | AK_MAY);
1426+
Changed |= addAccess(A, NewRanges, CB, RAcc.getContent(), AK,
1427+
RAcc.getType(), RAcc.getRemoteInst());
14231428
}
14241429
}
14251430
}
@@ -1893,9 +1898,10 @@ ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
18931898
DepClassTy::REQUIRED);
18941899
if (!CSArgPI)
18951900
return false;
1896-
Changed =
1897-
translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB) |
1898-
Changed;
1901+
bool IsMustAcc = (getUnderlyingObject(CurPtr) == &AssociatedValue);
1902+
Changed = translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB,
1903+
IsMustAcc) |
1904+
Changed;
18991905
return isValidState();
19001906
}
19011907
LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB

llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3176,7 +3176,7 @@ define internal i32 @recSimplify2() {
31763176
ret i32 %r
31773177
}
31783178

3179-
; TODO: Verify we do not return 10.
3179+
; Verify we do not return 10.
31803180
define i32 @may_access_after_return(i32 noundef %N, i32 noundef %M) {
31813181
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
31823182
; TUNIT-LABEL: define {{[^@]+}}@may_access_after_return
@@ -3185,7 +3185,10 @@ define i32 @may_access_after_return(i32 noundef %N, i32 noundef %M) {
31853185
; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4
31863186
; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4
31873187
; 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]]
3188-
; TUNIT-NEXT: ret i32 10
3188+
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
3189+
; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4
3190+
; TUNIT-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]]
3191+
; TUNIT-NEXT: ret i32 [[ADD]]
31893192
;
31903193
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
31913194
; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return
@@ -3237,7 +3240,7 @@ entry:
32373240
ret ptr %P
32383241
}
32393242

3240-
; TODO: Verify we do not return 10.
3243+
; Verify we do not return 10.
32413244
define i32 @may_access_after_return_choice(i32 noundef %N, i32 noundef %M, i1 %c) {
32423245
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
32433246
; 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
32483251
; 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]+]]
32493252
; 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]]
32503253
; 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]]
3251-
; TUNIT-NEXT: ret i32 10
3254+
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
3255+
; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4
3256+
; TUNIT-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]]
3257+
; TUNIT-NEXT: ret i32 [[ADD]]
32523258
;
32533259
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn
32543260
; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return_choice
@@ -3289,7 +3295,7 @@ entry:
32893295
ret ptr %R
32903296
}
32913297

3292-
; TODO: Verify we do not return 10.
3298+
; Verify we do not return 10.
32933299
define i32 @may_access_after_return_no_choice1(i32 noundef %N, i32 noundef %M) {
32943300
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
32953301
; 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) {
32983304
; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4
32993305
; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4
33003306
; 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]]
3301-
; TUNIT-NEXT: ret i32 10
3307+
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
3308+
; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4
3309+
; TUNIT-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]]
3310+
; TUNIT-NEXT: ret i32 [[ADD]]
33023311
;
33033312
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
33043313
; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return_no_choice1
@@ -3324,7 +3333,7 @@ entry:
33243333
ret i32 %add
33253334
}
33263335

3327-
; TODO: Verify we do not return 10.
3336+
; Verify we do not return 10.
33283337
define i32 @may_access_after_return_no_choice2(i32 noundef %N, i32 noundef %M) {
33293338
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
33303339
; 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) {
33333342
; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4
33343343
; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4
33353344
; 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]]
3336-
; TUNIT-NEXT: ret i32 10
3345+
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
3346+
; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4
3347+
; TUNIT-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]]
3348+
; TUNIT-NEXT: ret i32 [[ADD]]
33373349
;
33383350
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
33393351
; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return_no_choice2

0 commit comments

Comments
 (0)