[AliasAnalysis] Add missing FMRB_* enums.
authorEli Friedman <efriedma@quicinc.com>
Wed, 22 Jan 2020 00:51:17 +0000 (16:51 -0800)
committerEli Friedman <efriedma@quicinc.com>
Tue, 28 Jan 2020 23:47:08 +0000 (15:47 -0800)
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

llvm/include/llvm/Analysis/AliasAnalysis.h
llvm/lib/Analysis/AliasAnalysis.cpp
llvm/lib/Analysis/BasicAliasAnalysis.cpp
llvm/lib/Transforms/Utils/InlineFunction.cpp
polly/lib/Analysis/ScopBuilder.cpp
polly/lib/Analysis/ScopDetection.cpp
polly/test/ScopInfo/memset_null.ll

index 7c42a26..a285909 100644 (file)
@@ -226,11 +226,21 @@ 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.
   ///
@@ -239,12 +249,48 @@ enum FunctionModRefBehavior {
       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.
   ///
   /// This property corresponds to the LLVM IR inaccessiblememonly attribute.
   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.
index 1c7678a..9d18ffa 100644 (file)
@@ -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))
index e852d66..894afc6 100644 (file)
@@ -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);
index 35ce5ba..90da27c 100644 (file)
@@ -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;
         }
 
index e0635cc..e071646 100644 (file)
@@ -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());
index 59176d2..89d57cf 100644 (file)
@@ -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;
index 1a40091..b0d0be0 100644 (file)
@@ -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,