@@ -827,6 +827,7 @@ struct AA::PointerInfo::State : public AbstractState {
827
827
AccessList = R.AccessList ;
828
828
OffsetBins = R.OffsetBins ;
829
829
RemoteIMap = R.RemoteIMap ;
830
+ ReachesReturn = R.ReachesReturn ;
830
831
return *this ;
831
832
}
832
833
@@ -837,6 +838,7 @@ struct AA::PointerInfo::State : public AbstractState {
837
838
std::swap (AccessList, R.AccessList );
838
839
std::swap (OffsetBins, R.OffsetBins );
839
840
std::swap (RemoteIMap, R.RemoteIMap );
841
+ std::swap (ReachesReturn, R.ReachesReturn );
840
842
return *this ;
841
843
}
842
844
@@ -878,11 +880,16 @@ struct AA::PointerInfo::State : public AbstractState {
878
880
AAPointerInfo::OffsetBinsTy OffsetBins;
879
881
DenseMap<const Instruction *, SmallVector<unsigned >> RemoteIMap;
880
882
883
+ // / Flag to determine if the underlying pointer is reaching a return statement
884
+ // / in the associated function or not. Returns in other functions cause
885
+ // / invalidation.
886
+ bool ReachesReturn = false ;
887
+
881
888
// / See AAPointerInfo::forallInterferingAccesses.
882
889
bool forallInterferingAccesses (
883
890
AA::RangeTy Range,
884
891
function_ref<bool (const AAPointerInfo::Access &, bool )> CB) const {
885
- if (!isValidState ())
892
+ if (!isValidState () || ReachesReturn )
886
893
return false ;
887
894
888
895
for (const auto &It : OffsetBins) {
@@ -904,7 +911,7 @@ struct AA::PointerInfo::State : public AbstractState {
904
911
Instruction &I,
905
912
function_ref<bool (const AAPointerInfo::Access &, bool )> CB,
906
913
AA::RangeTy &Range) const {
907
- if (!isValidState ())
914
+ if (!isValidState () || ReachesReturn )
908
915
return false ;
909
916
910
917
auto LocalList = RemoteIMap.find (&I);
@@ -1071,7 +1078,8 @@ struct AAPointerInfoImpl
1071
1078
return std::string (" PointerInfo " ) +
1072
1079
(isValidState () ? (std::string (" #" ) +
1073
1080
std::to_string (OffsetBins.size ()) + " bins" )
1074
- : " <invalid>" );
1081
+ : " <invalid>" ) +
1082
+ (ReachesReturn ? " (returned)" : " " );
1075
1083
}
1076
1084
1077
1085
// / See AbstractAttribute::manifest(...).
@@ -1084,6 +1092,7 @@ struct AAPointerInfoImpl
1084
1092
virtual int64_t numOffsetBins () const override {
1085
1093
return State::numOffsetBins ();
1086
1094
}
1095
+ virtual bool reachesReturn () const override { return ReachesReturn; }
1087
1096
1088
1097
bool forallInterferingAccesses (
1089
1098
AA::RangeTy Range,
@@ -1373,6 +1382,7 @@ struct AAPointerInfoImpl
1373
1382
1374
1383
const auto &OtherAAImpl = static_cast <const AAPointerInfoImpl &>(OtherAA);
1375
1384
bool IsByval = OtherAAImpl.getAssociatedArgument ()->hasByValAttr ();
1385
+ ReachesReturn = OtherAAImpl.ReachesReturn ;
1376
1386
1377
1387
// Combine the accesses bin by bin.
1378
1388
ChangeStatus Changed = ChangeStatus::UNCHANGED;
@@ -1666,8 +1676,13 @@ ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
1666
1676
}
1667
1677
if (isa<PtrToIntInst>(Usr))
1668
1678
return false ;
1669
- if (isa<CastInst>(Usr) || isa<SelectInst>(Usr) || isa<ReturnInst>(Usr) )
1679
+ if (isa<CastInst>(Usr) || isa<SelectInst>(Usr))
1670
1680
return HandlePassthroughUser (Usr, CurPtr, Follow);
1681
+ // Returns are allowed if they are in the associated functions. Users can
1682
+ // then check the call site return. Returns from other functions can't be
1683
+ // tracked and are cause for invalidation.
1684
+ if (auto *RI = dyn_cast<ReturnInst>(Usr))
1685
+ return ReachesReturn = RI->getFunction () == getAssociatedFunction ();
1671
1686
1672
1687
// For PHIs we need to take care of the recurrence explicitly as the value
1673
1688
// might change while we iterate through a loop. For now, we give up if
@@ -1898,15 +1913,37 @@ ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
1898
1913
DepClassTy::REQUIRED);
1899
1914
if (!CSArgPI)
1900
1915
return false ;
1901
- bool IsMustAcc = (getUnderlyingObject (CurPtr) == &AssociatedValue);
1916
+ bool IsArgMustAcc = (getUnderlyingObject (CurPtr) == &AssociatedValue);
1902
1917
Changed = translateAndAddState (A, *CSArgPI, OffsetInfoMap[CurPtr], *CB,
1903
- IsMustAcc) |
1918
+ IsArgMustAcc) |
1919
+ Changed;
1920
+ if (!CSArgPI->reachesReturn ())
1921
+ return isValidState ();
1922
+
1923
+ Function *Callee = CB->getCalledFunction ();
1924
+ if (!Callee || Callee->arg_size () <= ArgNo)
1925
+ return false ;
1926
+ bool UsedAssumedInformation = false ;
1927
+ auto ReturnedValue = A.getAssumedSimplified (
1928
+ IRPosition::returned (*Callee), *this , UsedAssumedInformation,
1929
+ AA::ValueScope::Intraprocedural);
1930
+ auto *ReturnedArg =
1931
+ dyn_cast_or_null<Argument>(ReturnedValue.value_or (nullptr ));
1932
+ auto *Arg = Callee->getArg (ArgNo);
1933
+ if (ReturnedArg && Arg != ReturnedArg)
1934
+ return true ;
1935
+ bool IsRetMustAcc = IsArgMustAcc && (ReturnedArg == Arg);
1936
+ const auto *CSRetPI = A.getAAFor <AAPointerInfo>(
1937
+ *this , IRPosition::callsite_returned (*CB), DepClassTy::REQUIRED);
1938
+ if (!CSRetPI)
1939
+ return false ;
1940
+ Changed = translateAndAddState (A, *CSRetPI, OffsetInfoMap[CurPtr], *CB,
1941
+ IsRetMustAcc) |
1904
1942
Changed;
1905
1943
return isValidState ();
1906
1944
}
1907
1945
LLVM_DEBUG (dbgs () << " [AAPointerInfo] Call user not handled " << *CB
1908
1946
<< " \n " );
1909
- // TODO: Allow some call uses
1910
1947
return false ;
1911
1948
}
1912
1949
@@ -2342,8 +2379,10 @@ struct AANoFreeFloating : AANoFreeImpl {
2342
2379
Follow = true ;
2343
2380
return true ;
2344
2381
}
2345
- if (isa<StoreInst>(UserI) || isa<LoadInst>(UserI) ||
2346
- isa<ReturnInst>(UserI))
2382
+ if (isa<StoreInst>(UserI) || isa<LoadInst>(UserI))
2383
+ return true ;
2384
+
2385
+ if (isa<ReturnInst>(UserI) && getIRPosition ().isArgumentPosition ())
2347
2386
return true ;
2348
2387
2349
2388
// Unknown user.
@@ -12740,7 +12779,7 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
12740
12779
if (!PI)
12741
12780
return indicatePessimisticFixpoint ();
12742
12781
12743
- if (!PI->getState ().isValidState ())
12782
+ if (!PI->getState ().isValidState () || PI-> reachesReturn () )
12744
12783
return indicatePessimisticFixpoint ();
12745
12784
12746
12785
const DataLayout &DL = A.getDataLayout ();
0 commit comments