[AliasAnalysis] Add missing FMRB_* enums.
Previously, the enums didn't account for all the possible cases, which could cause misleading results (particularly for a "switch" on FunctionModRefBehavior). Fixes regression in polly from recent patch to add writeonly to memset. While I'm here, also fix a few dubious uses of the FMRB_* enum values. Differential Revision: https://reviews.llvm.org/D73154
This commit is contained in:
parent
0d401fa36b
commit
2f6b9edfa8
@ -226,10 +226,20 @@ enum FunctionModRefBehavior {
|
||||
/// non-volatile loads from objects pointed to by its pointer-typed
|
||||
/// arguments, with arbitrary offsets.
|
||||
///
|
||||
/// This property corresponds to the IntrReadArgMem LLVM intrinsic flag.
|
||||
/// This property corresponds to the combination of the IntrReadMem
|
||||
/// and IntrArgMemOnly LLVM intrinsic flags.
|
||||
FMRB_OnlyReadsArgumentPointees =
|
||||
FMRL_ArgumentPointees | static_cast<int>(ModRefInfo::Ref),
|
||||
|
||||
/// The only memory references in this function (if it has any) are
|
||||
/// non-volatile stores from objects pointed to by its pointer-typed
|
||||
/// arguments, with arbitrary offsets.
|
||||
///
|
||||
/// This property corresponds to the combination of the IntrWriteMem
|
||||
/// and IntrArgMemOnly LLVM intrinsic flags.
|
||||
FMRB_OnlyWritesArgumentPointees =
|
||||
FMRL_ArgumentPointees | static_cast<int>(ModRefInfo::Mod),
|
||||
|
||||
/// The only memory references in this function (if it has any) are
|
||||
/// non-volatile loads and stores from objects pointed to by its
|
||||
/// pointer-typed arguments, with arbitrary offsets.
|
||||
@ -238,6 +248,20 @@ enum FunctionModRefBehavior {
|
||||
FMRB_OnlyAccessesArgumentPointees =
|
||||
FMRL_ArgumentPointees | static_cast<int>(ModRefInfo::ModRef),
|
||||
|
||||
/// The only memory references in this function (if it has any) are
|
||||
/// reads of memory that is otherwise inaccessible via LLVM IR.
|
||||
///
|
||||
/// This property corresponds to the LLVM IR inaccessiblememonly attribute.
|
||||
FMRB_OnlyReadsInaccessibleMem =
|
||||
FMRL_InaccessibleMem | static_cast<int>(ModRefInfo::Ref),
|
||||
|
||||
/// The only memory references in this function (if it has any) are
|
||||
/// writes to memory that is otherwise inaccessible via LLVM IR.
|
||||
///
|
||||
/// This property corresponds to the LLVM IR inaccessiblememonly attribute.
|
||||
FMRB_OnlyWritesInaccessibleMem =
|
||||
FMRL_InaccessibleMem | static_cast<int>(ModRefInfo::Mod),
|
||||
|
||||
/// The only memory references in this function (if it has any) are
|
||||
/// references of memory that is otherwise inaccessible via LLVM IR.
|
||||
///
|
||||
@ -245,6 +269,28 @@ enum FunctionModRefBehavior {
|
||||
FMRB_OnlyAccessesInaccessibleMem =
|
||||
FMRL_InaccessibleMem | static_cast<int>(ModRefInfo::ModRef),
|
||||
|
||||
/// The function may perform non-volatile loads from objects pointed
|
||||
/// to by its pointer-typed arguments, with arbitrary offsets, and
|
||||
/// it may also perform loads of memory that is otherwise
|
||||
/// inaccessible via LLVM IR.
|
||||
///
|
||||
/// This property corresponds to the LLVM IR
|
||||
/// inaccessiblemem_or_argmemonly attribute.
|
||||
FMRB_OnlyReadsInaccessibleOrArgMem = FMRL_InaccessibleMem |
|
||||
FMRL_ArgumentPointees |
|
||||
static_cast<int>(ModRefInfo::Ref),
|
||||
|
||||
/// The function may perform non-volatile stores to objects pointed
|
||||
/// to by its pointer-typed arguments, with arbitrary offsets, and
|
||||
/// it may also perform stores of memory that is otherwise
|
||||
/// inaccessible via LLVM IR.
|
||||
///
|
||||
/// This property corresponds to the LLVM IR
|
||||
/// inaccessiblemem_or_argmemonly attribute.
|
||||
FMRB_OnlyWritesInaccessibleOrArgMem = FMRL_InaccessibleMem |
|
||||
FMRL_ArgumentPointees |
|
||||
static_cast<int>(ModRefInfo::Mod),
|
||||
|
||||
/// The function may perform non-volatile loads and stores of objects
|
||||
/// pointed to by its pointer-typed arguments, with arbitrary offsets, and
|
||||
/// it may also perform loads and stores of memory that is otherwise
|
||||
@ -269,7 +315,7 @@ enum FunctionModRefBehavior {
|
||||
//
|
||||
// This property corresponds to the LLVM IR 'writeonly' attribute.
|
||||
// This property corresponds to the IntrWriteMem LLVM intrinsic flag.
|
||||
FMRB_DoesNotReadMemory = FMRL_Anywhere | static_cast<int>(ModRefInfo::Mod),
|
||||
FMRB_OnlyWritesMemory = FMRL_Anywhere | static_cast<int>(ModRefInfo::Mod),
|
||||
|
||||
/// This indicates that the function could not be classified into one of the
|
||||
/// behaviors above.
|
||||
|
||||
@ -196,8 +196,7 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call,
|
||||
// Try to refine the mod-ref info further using other API entry points to the
|
||||
// aggregate set of AA results.
|
||||
auto MRB = getModRefBehavior(Call);
|
||||
if (MRB == FMRB_DoesNotAccessMemory ||
|
||||
MRB == FMRB_OnlyAccessesInaccessibleMem)
|
||||
if (onlyAccessesInaccessibleMem(MRB))
|
||||
return ModRefInfo::NoModRef;
|
||||
|
||||
if (onlyReadsMemory(MRB))
|
||||
|
||||
@ -723,7 +723,7 @@ FunctionModRefBehavior BasicAAResult::getModRefBehavior(const CallBase *Call) {
|
||||
if (Call->onlyReadsMemory())
|
||||
Min = FMRB_OnlyReadsMemory;
|
||||
else if (Call->doesNotReadMemory())
|
||||
Min = FMRB_DoesNotReadMemory;
|
||||
Min = FMRB_OnlyWritesMemory;
|
||||
|
||||
if (Call->onlyAccessesArgMemory())
|
||||
Min = FunctionModRefBehavior(Min & FMRB_OnlyAccessesArgumentPointees);
|
||||
@ -756,7 +756,7 @@ FunctionModRefBehavior BasicAAResult::getModRefBehavior(const Function *F) {
|
||||
if (F->onlyReadsMemory())
|
||||
Min = FMRB_OnlyReadsMemory;
|
||||
else if (F->doesNotReadMemory())
|
||||
Min = FMRB_DoesNotReadMemory;
|
||||
Min = FMRB_OnlyWritesMemory;
|
||||
|
||||
if (F->onlyAccessesArgMemory())
|
||||
Min = FunctionModRefBehavior(Min & FMRB_OnlyAccessesArgumentPointees);
|
||||
|
||||
@ -1002,8 +1002,7 @@ static void AddAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap,
|
||||
IsFuncCall = true;
|
||||
if (CalleeAAR) {
|
||||
FunctionModRefBehavior MRB = CalleeAAR->getModRefBehavior(Call);
|
||||
if (MRB == FMRB_OnlyAccessesArgumentPointees ||
|
||||
MRB == FMRB_OnlyReadsArgumentPointees)
|
||||
if (AAResults::onlyAccessesArgPointees(MRB))
|
||||
IsArgMemOnlyCall = true;
|
||||
}
|
||||
|
||||
|
||||
@ -1809,16 +1809,21 @@ bool ScopBuilder::buildAccessCallInst(MemAccInst Inst, ScopStmt *Stmt) {
|
||||
llvm_unreachable("Unknown mod ref behaviour cannot be represented.");
|
||||
case FMRB_DoesNotAccessMemory:
|
||||
return true;
|
||||
case FMRB_DoesNotReadMemory:
|
||||
case FMRB_OnlyWritesMemory:
|
||||
case FMRB_OnlyWritesInaccessibleMem:
|
||||
case FMRB_OnlyWritesInaccessibleOrArgMem:
|
||||
case FMRB_OnlyAccessesInaccessibleMem:
|
||||
case FMRB_OnlyAccessesInaccessibleOrArgMem:
|
||||
return false;
|
||||
case FMRB_OnlyReadsMemory:
|
||||
case FMRB_OnlyReadsInaccessibleMem:
|
||||
case FMRB_OnlyReadsInaccessibleOrArgMem:
|
||||
GlobalReads.emplace_back(Stmt, CI);
|
||||
return true;
|
||||
case FMRB_OnlyReadsArgumentPointees:
|
||||
ReadOnly = true;
|
||||
LLVM_FALLTHROUGH;
|
||||
case FMRB_OnlyWritesArgumentPointees:
|
||||
case FMRB_OnlyAccessesArgumentPointees: {
|
||||
auto AccType = ReadOnly ? MemoryAccess::READ : MemoryAccess::MAY_WRITE;
|
||||
Loop *L = LI.getLoopFor(Inst->getParent());
|
||||
|
||||
@ -696,6 +696,8 @@ bool ScopDetection::isValidCallInst(CallInst &CI,
|
||||
return false;
|
||||
case FMRB_DoesNotAccessMemory:
|
||||
case FMRB_OnlyReadsMemory:
|
||||
case FMRB_OnlyReadsInaccessibleMem:
|
||||
case FMRB_OnlyReadsInaccessibleOrArgMem:
|
||||
// Implicitly disable delinearization since we have an unknown
|
||||
// accesses with an unknown access function.
|
||||
Context.HasUnknownAccess = true;
|
||||
@ -705,6 +707,7 @@ bool ScopDetection::isValidCallInst(CallInst &CI,
|
||||
return true;
|
||||
case FMRB_OnlyReadsArgumentPointees:
|
||||
case FMRB_OnlyAccessesArgumentPointees:
|
||||
case FMRB_OnlyWritesArgumentPointees:
|
||||
for (const auto &Arg : CI.arg_operands()) {
|
||||
if (!Arg->getType()->isPointerTy())
|
||||
continue;
|
||||
@ -728,7 +731,9 @@ bool ScopDetection::isValidCallInst(CallInst &CI,
|
||||
// pointer into the alias set.
|
||||
Context.AST.addUnknown(&CI);
|
||||
return true;
|
||||
case FMRB_DoesNotReadMemory:
|
||||
case FMRB_OnlyWritesMemory:
|
||||
case FMRB_OnlyWritesInaccessibleMem:
|
||||
case FMRB_OnlyWritesInaccessibleOrArgMem:
|
||||
case FMRB_OnlyAccessesInaccessibleMem:
|
||||
case FMRB_OnlyAccessesInaccessibleOrArgMem:
|
||||
return false;
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
; RUN: opt %loadPolly -polly-allow-modref-calls -polly-scops -analyze < %s | FileCheck %s
|
||||
; RUN: opt %loadPolly -polly-allow-modref-calls -S -polly-codegen < %s
|
||||
; XFAIL'ed due to change to memset attributes.
|
||||
; XFAIL: *
|
||||
;
|
||||
; Verify we can handle a memset to "null" and that we do not model it.
|
||||
; TODO: FIXME: We could use the undefined memset to optimize the code further,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user