aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/Analysis/MemoryDependenceAnalysis.cpp10
-rw-r--r--test/Transforms/GVN/load-constant-mem.ll13
2 files changed, 22 insertions, 1 deletions
diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp
index 74c9621..3b21029 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 0000000..83b9d38
--- /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
+}