From ab9cf1282baf559771183304ffc9959882e17ebb Mon Sep 17 00:00:00 2001
From: Chris Lattner <sabre@nondot.org>
Date: Mon, 25 May 2009 21:28:56 +0000
Subject: [PATCH] make memdep use the getModRefInfo method for stores instead
 of the low-level alias() method, allowing it to reason more aggressively
 about pointers into constant memory.  PR4189

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72403 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Analysis/MemoryDependenceAnalysis.cpp | 10 +++++++++-
 test/Transforms/GVN/load-constant-mem.ll  | 13 +++++++++++++
 2 files changed, 22 insertions(+), 1 deletion(-)
 create mode 100644 test/Transforms/GVN/load-constant-mem.ll

diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp
index 74c962147ce..3b2102955f3 100644
--- a/lib/Analysis/MemoryDependenceAnalysis.cpp
+++ b/lib/Analysis/MemoryDependenceAnalysis.cpp
@@ -202,9 +202,17 @@ getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad,
     }
     
     if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
+      // If alias analysis can tell that this store is guaranteed to not modify
+      // the query pointer, ignore it.  Use getModRefInfo to handle cases where
+      // the query pointer points to constant memory etc.
+      if (AA->getModRefInfo(SI, MemPtr, MemSize) == AliasAnalysis::NoModRef)
+        continue;
+
+      // Ok, this store might clobber the query pointer.  Check to see if it is
+      // a must alias: in this case, we want to return this as a def.
       Value *Pointer = SI->getPointerOperand();
       uint64_t PointerSize = TD->getTypeStoreSize(SI->getOperand(0)->getType());
-
+      
       // If we found a pointer, check if it could be the same as our pointer.
       AliasAnalysis::AliasResult R =
         AA->alias(Pointer, PointerSize, MemPtr, MemSize);
diff --git a/test/Transforms/GVN/load-constant-mem.ll b/test/Transforms/GVN/load-constant-mem.ll
new file mode 100644
index 00000000000..83b9d3846c1
--- /dev/null
+++ b/test/Transforms/GVN/load-constant-mem.ll
@@ -0,0 +1,13 @@
+; RUN: llvm-as < %s | opt -gvn -instcombine | llvm-dis | grep {ret i32 0}
+; PR4189
+@G = external constant [4 x i32]
+
+define i32 @test(i8* %p, i32 %i) nounwind {
+entry:
+	%P = getelementptr [4 x i32]* @G, i32 0, i32 %i
+	%A = load i32* %P
+	store i8 4, i8* %p
+	%B = load i32* %P
+	%C = sub i32 %A, %B
+	ret i32 %C
+}