F.getAttributes().hasAttrSomewhere(Attribute::Preallocated))
ME |= MemoryEffects::argMemOnly(ModRefInfo::ModRef);
- // Returns true if Ptr is not based on a function argument.
- auto IsArgumentOrAlloca = [](const Value *Ptr) {
- const Value *UO = getUnderlyingObject(Ptr);
- return isa<Argument>(UO) || isa<AllocaInst>(UO);
+ auto AddLocAccess = [&](const MemoryLocation &Loc, ModRefInfo MR) {
+ // Ignore accesses to local memory.
+ if (AAR.pointsToConstantMemory(Loc, /*OrLocal=*/true))
+ return;
+
+ const Value *UO = getUnderlyingObject(Loc.Ptr);
+ // The accessed location can be either only argument memory, or
+ // argument & other memory, but never inaccessible memory.
+ ME |= MemoryEffects::argMemOnly(MR);
+ if (!isa<Argument>(UO) && !isa<AllocaInst>(UO))
+ ME |= MemoryEffects(MemoryEffects::Other, MR);
};
// Scan the function body for instructions that may read or write memory.
for (Instruction &I : instructions(F)) {
if (!Arg->getType()->isPtrOrPtrVectorTy())
continue;
- MemoryLocation Loc =
- MemoryLocation::getBeforeOrAfter(Arg, I.getAAMetadata());
- // Skip accesses to local or constant memory as they don't impact the
- // externally visible mod/ref behavior.
- if (AAR.pointsToConstantMemory(Loc, /*OrLocal=*/true))
- continue;
-
- ME |= MemoryEffects::argMemOnly(ArgMR);
- if (!IsArgumentOrAlloca(Loc.Ptr))
- ME |= MemoryEffects(MemoryEffects::Other, ArgMR);
+ AddLocAccess(MemoryLocation::getBeforeOrAfter(Arg, I.getAAMetadata()), ArgMR);
}
}
continue;
if (I.isVolatile())
ME |= MemoryEffects::inaccessibleMemOnly(MR);
- // Ignore accesses to local memory.
- if (AAR.pointsToConstantMemory(*Loc, /*OrLocal=*/true))
- continue;
-
- // The accessed location can be either only argument memory, or
- // argument & other memory, but never inaccessible memory.
- ME |= MemoryEffects::argMemOnly(MR);
- if (!IsArgumentOrAlloca(Loc->Ptr))
- ME |= MemoryEffects(MemoryEffects::Other, MR);
+ AddLocAccess(*Loc, MR);
}
return OrigME & ME;