@@ -847,15 +847,15 @@ MemoryEffects BasicAAResult::getMemoryEffects(const Function *F) {
847847
848848ModRefInfo BasicAAResult::getArgModRefInfo (const CallBase *Call,
849849 unsigned ArgIdx) {
850- if (Call->paramHasAttr (ArgIdx, Attribute::WriteOnly))
850+ if (Call->doesNotAccessMemory (ArgIdx))
851+ return ModRefInfo::NoModRef;
852+
853+ if (Call->onlyWritesMemory (ArgIdx))
851854 return ModRefInfo::Mod;
852855
853- if (Call->paramHasAttr (ArgIdx, Attribute::ReadOnly ))
856+ if (Call->onlyReadsMemory (ArgIdx))
854857 return ModRefInfo::Ref;
855858
856- if (Call->paramHasAttr (ArgIdx, Attribute::ReadNone))
857- return ModRefInfo::NoModRef;
858-
859859 return ModRefInfo::ModRef;
860860}
861861
@@ -921,66 +921,58 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call,
921921 if (!AI->isStaticAlloca () && isIntrinsicCall (Call, Intrinsic::stackrestore))
922922 return ModRefInfo::Mod;
923923
924- // A call can access a locally allocated object either because it is passed as
925- // an argument to the call, or because it has escaped prior to the call.
926- //
927- // Make sure the object has not escaped here, and then check that none of the
928- // call arguments alias the object below.
924+ // We can completely ignore inaccessible memory here, because MemoryLocations
925+ // can only reference accessible memory.
926+ auto ME = AAQI.AAR .getMemoryEffects (Call, AAQI)
927+ .getWithoutLoc (IRMemLocation::InaccessibleMem);
928+ if (ME.doesNotAccessMemory ())
929+ return ModRefInfo::NoModRef;
930+
931+ ModRefInfo ArgMR = ME.getModRef (IRMemLocation::ArgMem);
932+ ModRefInfo OtherMR = ME.getWithoutLoc (IRMemLocation::ArgMem).getModRef ();
933+
934+ // An identified function-local object that does not escape can only be
935+ // accessed via call arguments. Reduce OtherMR (which includes accesses to
936+ // escaped memory) based on that.
929937 //
930938 // We model calls that can return twice (setjmp) as clobbering non-escaping
931939 // objects, to model any accesses that may occur prior to the second return.
932940 // As an exception, ignore allocas, as setjmp is not required to preserve
933941 // non-volatile stores for them.
934- if (!isa<Constant>(Object) && Call != Object &&
935- AAQI.CA ->isNotCapturedBefore (Object, Call, /* OrAt*/ false ) &&
936- (isa<AllocaInst>(Object) || !Call->hasFnAttr (Attribute::ReturnsTwice))) {
937-
938- // Optimistically assume that call doesn't touch Object and check this
939- // assumption in the following loop.
940- ModRefInfo Result = ModRefInfo::NoModRef;
941-
942- unsigned OperandNo = 0 ;
943- for (auto CI = Call->data_operands_begin (), CE = Call->data_operands_end ();
944- CI != CE; ++CI, ++OperandNo) {
945- if (!(*CI)->getType ()->isPointerTy ())
946- continue ;
947-
948- // Call doesn't access memory through this operand, so we don't care
949- // if it aliases with Object.
950- if (Call->doesNotAccessMemory (OperandNo))
951- continue ;
952-
953- // If this is a no-capture pointer argument, see if we can tell that it
954- // is impossible to alias the pointer we're checking.
955- AliasResult AR =
956- AAQI.AAR .alias (MemoryLocation::getBeforeOrAfter (*CI),
957- MemoryLocation::getBeforeOrAfter (Object), AAQI);
958- // Operand doesn't alias 'Object', continue looking for other aliases
959- if (AR == AliasResult::NoAlias)
942+ if (isModOrRefSet (OtherMR) && !isa<Constant>(Object) && Call != Object &&
943+ AAQI.CA ->isNotCapturedBefore (Object, Call, /* OrAt=*/ false ) &&
944+ (isa<AllocaInst>(Object) || !Call->hasFnAttr (Attribute::ReturnsTwice)))
945+ OtherMR = ModRefInfo::NoModRef;
946+
947+ // Refine the modref info for argument memory. We only bother to do this
948+ // if ArgMR is not a subset of OtherMR, otherwise this won't have an impact
949+ // on the final result.
950+ if ((ArgMR | OtherMR) != OtherMR) {
951+ ModRefInfo NewArgMR = ModRefInfo::NoModRef;
952+ for (const Use &U : Call->data_ops ()) {
953+ const Value *Arg = U;
954+ if (!Arg->getType ()->isPointerTy ())
960955 continue ;
961- // Operand aliases 'Object', but call doesn't modify it. Strengthen
962- // initial assumption and keep looking in case if there are more aliases.
963- if (Call->onlyReadsMemory (OperandNo)) {
964- Result |= ModRefInfo::Ref;
965- continue ;
966- }
967- // Operand aliases 'Object' but call only writes into it.
968- if (Call->onlyWritesMemory (OperandNo)) {
969- Result |= ModRefInfo::Mod;
970- continue ;
971- }
972- // This operand aliases 'Object' and call reads and writes into it.
973- // Setting ModRef will not yield an early return below, MustAlias is not
974- // used further.
975- Result = ModRefInfo::ModRef;
976- break ;
956+ unsigned ArgIdx = Call->getDataOperandNo (&U);
957+ MemoryLocation ArgLoc =
958+ Call->isArgOperand (&U)
959+ ? MemoryLocation::getForArgument (Call, ArgIdx, TLI)
960+ : MemoryLocation::getBeforeOrAfter (Arg);
961+ AliasResult ArgAlias = AAQI.AAR .alias (ArgLoc, Loc, AAQI, Call);
962+ if (ArgAlias != AliasResult::NoAlias)
963+ NewArgMR |= ArgMR & AAQI.AAR .getArgModRefInfo (Call, ArgIdx);
964+
965+ // Exit early if we cannot improve over the original ArgMR.
966+ if (NewArgMR == ArgMR)
967+ break ;
977968 }
978-
979- // Early return if we improved mod ref information
980- if (!isModAndRefSet (Result))
981- return Result;
969+ ArgMR = NewArgMR;
982970 }
983971
972+ ModRefInfo Result = ArgMR | OtherMR;
973+ if (!isModAndRefSet (Result))
974+ return Result;
975+
984976 // If the call is malloc/calloc like, we can assume that it doesn't
985977 // modify any IR visible value. This is only valid because we assume these
986978 // routines do not read values visible in the IR. TODO: Consider special
0 commit comments