Memory dependence analysis was incorrectly stopping to scan for stores to a pointer...
authorVictor Hernandez <vhernandez@apple.com>
Tue, 13 Oct 2009 01:42:53 +0000 (01:42 +0000)
committerVictor Hernandez <vhernandez@apple.com>
Tue, 13 Oct 2009 01:42:53 +0000 (01:42 +0000)
It should continue scanning until the malloc call, and this patch fixes that.

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

lib/Analysis/MemoryDependenceAnalysis.cpp
test/Transforms/GVN/2009-11-12-MemDepMallocBitCast.ll [new file with mode: 0644]

index 97b791caf92befbd314fbd3f2d8faf71170a186d..d6400757a5131c52e08074111d8e26ae4cf855a0 100644 (file)
@@ -225,16 +225,11 @@ getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad,
     // the allocation, return Def.  This means that there is no dependence and
     // the access can be optimized based on that.  For example, a load could
     // turn into undef.
-    if (AllocationInst *AI = dyn_cast<AllocationInst>(Inst)) {
-      Value *AccessPtr = MemPtr->getUnderlyingObject();
-      
-      if (AccessPtr == AI ||
-          AA->alias(AI, 1, AccessPtr, 1) == AliasAnalysis::MustAlias)
-        return MemDepResult::getDef(AI);
-      continue;
-    }
-    
-    if (isMalloc(Inst)) {
+    // Note: Only determine this to be a malloc if Inst is the malloc call, not
+    // a subsequent bitcast of the malloc call result.  There can be stores to
+    // the malloced memory between the malloc call and its bitcast uses, and we
+    // need to continue scanning until the malloc call.
+    if (isa<AllocationInst>(Inst) || extractMallocCall(Inst)) {
       Value *AccessPtr = MemPtr->getUnderlyingObject();
       
       if (AccessPtr == Inst ||
diff --git a/test/Transforms/GVN/2009-11-12-MemDepMallocBitCast.ll b/test/Transforms/GVN/2009-11-12-MemDepMallocBitCast.ll
new file mode 100644 (file)
index 0000000..b433297
--- /dev/null
@@ -0,0 +1,15 @@
+; Test to make sure malloc's bitcast does not block detection of a store 
+; to aliased memory; GVN should not optimize away the load in this program.
+; RUN: opt < %s -gvn -S | FileCheck %s
+
+define i64 @test() {
+  %1 = tail call i8* @malloc(i64 mul (i64 4, i64 ptrtoint (i64* getelementptr (i64* null, i64 1) to i64))) ; <i8*> [#uses=2]
+  store i8 42, i8* %1
+  %X = bitcast i8* %1 to i64*                     ; <i64*> [#uses=1]
+  %Y = load i64* %X                               ; <i64> [#uses=1]
+  ret i64 %Y
+; CHECK: %Y = load i64* %X
+; CHECK: ret i64 %Y
+}
+
+declare noalias i8* @malloc(i64)