Make getModRefInfo with a default location not crash.
authorDaniel Berlin <dberlin@dberlin.org>
Mon, 13 Apr 2015 23:05:45 +0000 (23:05 +0000)
committerDaniel Berlin <dberlin@dberlin.org>
Mon, 13 Apr 2015 23:05:45 +0000 (23:05 +0000)
Add getModRefInfo that works without location.
Add unit tests.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234811 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/AliasAnalysis.h
lib/Analysis/AliasAnalysis.cpp
unittests/Analysis/AliasAnalysisTest.cpp [new file with mode: 0644]
unittests/Analysis/CMakeLists.txt

index 43bcc343d362771f7b05e426ab7c240cdb1124bf..9ce394c0984950c421b6901e3fa10d13e0b97ee5 100644 (file)
@@ -352,6 +352,24 @@ public:
     return (MRB & ModRef) && (MRB & ArgumentPointees);
   }
 
+  /// getModRefInfo - Return information about whether or not an
+  /// instruction may read or write memory (without regard to a
+  /// specific location)
+  ModRefResult getModRefInfo(const Instruction *I) {
+    if (auto CS = ImmutableCallSite(I)) {
+      auto MRB = getModRefBehavior(CS);
+      if (MRB & ModRef)
+        return ModRef;
+      else if (MRB & Ref)
+        return Ref;
+      else if (MRB & Mod)
+        return Mod;
+      return NoModRef;
+    }
+
+    return getModRefInfo(I, Location());
+  }
+
   /// getModRefInfo - Return information about whether or not an instruction may
   /// read or write the specified memory location.  An instruction
   /// that doesn't read or write memory may be trivially LICM'd for example.
index 0b0fd50a866f5611ff9eba85fd271674907fe838..c83236205587d8ac24a72977b0f9886601c20f98 100644 (file)
@@ -330,7 +330,7 @@ AliasAnalysis::getModRefInfo(const LoadInst *L, const Location &Loc) {
 
   // If the load address doesn't alias the given address, it doesn't read
   // or write the specified memory.
-  if (!alias(getLocation(L), Loc))
+  if (Loc.Ptr && !alias(getLocation(L), Loc))
     return NoModRef;
 
   // Otherwise, a load just reads.
@@ -343,15 +343,18 @@ AliasAnalysis::getModRefInfo(const StoreInst *S, const Location &Loc) {
   if (!S->isUnordered())
     return ModRef;
 
-  // If the store address cannot alias the pointer in question, then the
-  // specified memory cannot be modified by the store.
-  if (!alias(getLocation(S), Loc))
-    return NoModRef;
+  if (Loc.Ptr) {
+    // If the store address cannot alias the pointer in question, then the
+    // specified memory cannot be modified by the store.
+    if (!alias(getLocation(S), Loc))
+      return NoModRef;
 
-  // If the pointer is a pointer to constant memory, then it could not have been
-  // modified by this store.
-  if (pointsToConstantMemory(Loc))
-    return NoModRef;
+    // If the pointer is a pointer to constant memory, then it could not have
+    // been modified by this store.
+    if (pointsToConstantMemory(Loc))
+      return NoModRef;
+
+  }
 
   // Otherwise, a store just writes.
   return Mod;
diff --git a/unittests/Analysis/AliasAnalysisTest.cpp b/unittests/Analysis/AliasAnalysisTest.cpp
new file mode 100644 (file)
index 0000000..1ba396c
--- /dev/null
@@ -0,0 +1,94 @@
+//===--- AliasAnalysisTest.cpp - Mixed TBAA unit tests --------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/Support/CommandLine.h"
+#include "gtest/gtest.h"
+
+namespace llvm {
+namespace {
+
+class AliasAnalysisTest : public testing::Test {
+protected:
+  AliasAnalysisTest() : M("AliasAnalysisTBAATest", C) {}
+
+  // This is going to check that calling getModRefInfo without a location, and
+  // with a default location, first, doesn't crash, and second, gives the right
+  // answer.
+  void CheckModRef(Instruction *I, AliasAnalysis::ModRefResult Result) {
+    static char ID;
+    class CheckModRefTestPass : public FunctionPass {
+    public:
+      CheckModRefTestPass(Instruction *I, AliasAnalysis::ModRefResult Result)
+          : FunctionPass(ID), ExpectResult(Result), I(I) {}
+      static int initialize() {
+        PassInfo *PI = new PassInfo("CheckModRef testing pass", "", &ID,
+                                    nullptr, true, true);
+        PassRegistry::getPassRegistry()->registerPass(*PI, false);
+        initializeAliasAnalysisAnalysisGroup(*PassRegistry::getPassRegistry());
+        initializeBasicAliasAnalysisPass(*PassRegistry::getPassRegistry());
+        return 0;
+      }
+      void getAnalysisUsage(AnalysisUsage &AU) const override {
+        AU.setPreservesAll();
+        AU.addRequiredTransitive<AliasAnalysis>();
+      }
+      bool runOnFunction(Function &) override {
+        AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
+        EXPECT_EQ(AA.getModRefInfo(I, AliasAnalysis::Location()), ExpectResult);
+        EXPECT_EQ(AA.getModRefInfo(I), ExpectResult);
+        return false;
+      }
+      AliasAnalysis::ModRefResult ExpectResult;
+      Instruction *I;
+    };
+    static int initialize = CheckModRefTestPass::initialize();
+    (void)initialize;
+    CheckModRefTestPass *P = new CheckModRefTestPass(I, Result);
+    legacy::PassManager PM;
+    PM.add(createBasicAliasAnalysisPass());
+    PM.add(P);
+    PM.run(M);
+  }
+
+  LLVMContext C;
+  Module M;
+};
+
+TEST_F(AliasAnalysisTest, getModRefInfo) {
+  // Setup function.
+  FunctionType *FTy =
+      FunctionType::get(Type::getVoidTy(C), std::vector<Type *>(), false);
+  auto *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+  auto *BB = BasicBlock::Create(C, "entry", F);
+  auto IntType = Type::getInt32Ty(C);
+  auto PtrType = Type::getInt32PtrTy(C);
+  auto *Value = ConstantInt::get(IntType, 42);
+  auto *Addr = ConstantPointerNull::get(PtrType);
+
+  auto *Store1 = new StoreInst(Value, Addr, BB);
+  auto *Load1 = new LoadInst(Addr, "load", BB);
+  auto *Add1 = BinaryOperator::CreateAdd(Value, Value, "add", BB);
+
+  ReturnInst::Create(C, nullptr, BB);
+
+  // Check basic results
+  CheckModRef(Store1, AliasAnalysis::ModRefResult::Mod);
+  CheckModRef(Load1, AliasAnalysis::ModRefResult::Ref);
+  CheckModRef(Add1, AliasAnalysis::ModRefResult::NoModRef);
+}
+
+} // end anonymous namspace
+} // end llvm namespace
index baf0c28a8d9cc30e4aef761dd233aa019a79eafb..35a6d92ce179303e1ea98854e5f4b2b25bb0bc4c 100644 (file)
@@ -7,6 +7,7 @@ set(LLVM_LINK_COMPONENTS
   )
 
 add_llvm_unittest(AnalysisTests
+  AliasAnalysisTest.cpp
   CallGraphTest.cpp
   CFGTest.cpp
   LazyCallGraphTest.cpp