@@ -12654,6 +12654,11 @@ struct AAInvariantLoadPointerImpl
1265412654 case IRP_RETURNED:
1265512655 case IRP_CALL_SITE:
1265612656 return false ;
12657+ case IRP_CALL_SITE_RETURNED: {
12658+ const auto &CB = cast<CallBase>(getAnchorValue ());
12659+ return !isIntrinsicReturningPointerAliasingArgumentWithoutCapturing (
12660+ &CB, /* MustPreserveNullness=*/ false );
12661+ }
1265712662 case IRP_ARGUMENT: {
1265812663 const Function *F = getAssociatedFunction ();
1265912664 assert (F && " no associated function for argument" );
@@ -12674,7 +12679,7 @@ struct AAInvariantLoadPointerImpl
1267412679 if (isKnown (IS_NOALIAS) || !isAssumed (IS_NOALIAS))
1267512680 return ChangeStatus::UNCHANGED;
1267612681
12677- // try to use AANoAlias
12682+ // Try to use AANoAlias.
1267812683 if (const auto *ANoAlias = A.getOrCreateAAFor <AANoAlias>(
1267912684 getIRPosition (), this , DepClassTy::REQUIRED)) {
1268012685 if (ANoAlias->isKnownNoAlias ()) {
@@ -12690,15 +12695,15 @@ struct AAInvariantLoadPointerImpl
1269012695 return ChangeStatus::UNCHANGED;
1269112696 }
1269212697
12693- // try to infer noalias from argument attribute, since it is applicable for
12694- // the duration of the function
12698+ // Try to infer noalias from argument attribute, since it is applicable for
12699+ // the duration of the function.
1269512700 if (const Argument *Arg = getAssociatedArgument ()) {
1269612701 if (Arg->hasNoAliasAttr ()) {
1269712702 addKnownBits (IS_NOALIAS);
1269812703 return ChangeStatus::UNCHANGED;
1269912704 }
1270012705
12701- // noalias information is not provided, and cannot be inferred,
12706+ // Noalias information is not provided, and cannot be inferred,
1270212707 // so we conservatively assume the pointer aliases.
1270312708 removeAssumedBits (IS_NOALIAS);
1270412709 return ChangeStatus::CHANGED;
@@ -12721,7 +12726,7 @@ struct AAInvariantLoadPointerImpl
1272112726 if (!A.checkForAllUses (HasNoEffectLoads, *this , getAssociatedValue ()))
1272212727 return indicatePessimisticFixpoint ();
1272312728
12724- // try to use AAMemoryBehavior to infer readonly attribute
12729+ // Try to use AAMemoryBehavior to infer readonly attribute.
1272512730 if (const auto *AMemoryBehavior = A.getOrCreateAAFor <AAMemoryBehavior>(
1272612731 getIRPosition (), this , DepClassTy::REQUIRED)) {
1272712732 if (!AMemoryBehavior->isAssumedReadOnly ())
@@ -12741,8 +12746,8 @@ struct AAInvariantLoadPointerImpl
1274112746 return ChangeStatus::UNCHANGED;
1274212747 }
1274312748
12744- // readonly information is not provided, and cannot be inferred from
12745- // AAMemoryBehavior
12749+ // Readonly information is not provided, and cannot be inferred from
12750+ // AAMemoryBehavior.
1274612751 return indicatePessimisticFixpoint ();
1274712752 }
1274812753
@@ -12766,7 +12771,7 @@ struct AAInvariantLoadPointerImpl
1276612771 const auto *IsInvariantLoadPointer =
1276712772 A.getOrCreateAAFor <AAInvariantLoadPointer>(IRPosition::value (V), this ,
1276812773 DepClassTy::REQUIRED);
12769- // conservatively fail if invariance cannot be inferred
12774+ // Conservatively fail if invariance cannot be inferred.
1277012775 if (!IsInvariantLoadPointer)
1277112776 return false ;
1277212777
@@ -12781,8 +12786,18 @@ struct AAInvariantLoadPointerImpl
1278112786 if (!AUO->forallUnderlyingObjects (IsLocallyInvariantLoadIfPointer))
1278212787 return indicatePessimisticFixpoint ();
1278312788
12789+ if (const auto *CB = dyn_cast<CallBase>(&getAnchorValue ())) {
12790+ if (isIntrinsicReturningPointerAliasingArgumentWithoutCapturing (
12791+ CB, /* MustPreserveNullness=*/ false )) {
12792+ for (const Value *Arg : CB->args ()) {
12793+ if (!IsLocallyInvariantLoadIfPointer (*Arg))
12794+ return indicatePessimisticFixpoint ();
12795+ }
12796+ }
12797+ }
12798+
1278412799 if (!UsedAssumedInformation) {
12785- // pointer is known ( not assumed) to be locally invariant
12800+ // Pointer is known and not just assumed to be locally invariant.
1278612801 addKnownBits (IS_LOCALLY_INVARIANT);
1278712802 return ChangeStatus::CHANGED;
1278812803 }
@@ -12814,14 +12829,20 @@ struct AAInvariantLoadPointerCallSiteReturned final
1281412829 const Function *F = getAssociatedFunction ();
1281512830 assert (F && " no associated function for return from call" );
1281612831
12817- // There is not much we can say about opaque functions.
12818- if (F->isDeclaration () || F->isIntrinsic ()) {
12819- if (!F->onlyReadsMemory () || !F->hasNoSync ()) {
12820- indicatePessimisticFixpoint ();
12821- return ;
12822- }
12823- }
12824- AAInvariantLoadPointerImpl::initialize (A);
12832+ if (!F->isDeclaration () && !F->isIntrinsic ())
12833+ return AAInvariantLoadPointerImpl::initialize (A);
12834+
12835+ const auto &CB = cast<CallBase>(getAnchorValue ());
12836+ if (isIntrinsicReturningPointerAliasingArgumentWithoutCapturing (
12837+ &CB, /* MustPreserveNullness=*/ false ))
12838+ return AAInvariantLoadPointerImpl::initialize (A);
12839+
12840+ if (F->onlyReadsMemory () && F->hasNoSync ())
12841+ return AAInvariantLoadPointerImpl::initialize (A);
12842+
12843+ // At this point, the function is opaque, so we conservatively assume
12844+ // non-invariance.
12845+ indicatePessimisticFixpoint ();
1282512846 }
1282612847};
1282712848
0 commit comments