fix PR6642, GVN forwarding from memset to load of the base of the memset.
authorChris Lattner <sabre@nondot.org>
Thu, 25 Mar 2010 05:58:19 +0000 (05:58 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 25 Mar 2010 05:58:19 +0000 (05:58 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@99488 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/GVN.cpp
test/Transforms/GVN/rle.ll

index fcb802a72ae0849a6e4425feb7ed8cd07b69eeca..642d59da044f75fefcff742bfaf6f19e2dbd13b7 100644 (file)
@@ -1004,18 +1004,18 @@ static int AnalyzeLoadFromClobberingWrite(const Type *LoadTy, Value *LoadPtr,
   
   // If the load and store are to the exact same address, they should have been
   // a must alias.  AA must have gotten confused.
-  // FIXME: Study to see if/when this happens.
-  if (LoadOffset == StoreOffset) {
+  // FIXME: Study to see if/when this happens.  One case is forwarding a memset
+  // to a load from the base of the memset.
 #if 0
+  if (LoadOffset == StoreOffset) {
     dbgs() << "STORE/LOAD DEP WITH COMMON POINTER MISSED:\n"
     << "Base       = " << *StoreBase << "\n"
     << "Store Ptr  = " << *WritePtr << "\n"
     << "Store Offs = " << StoreOffset << "\n"
     << "Load Ptr   = " << *LoadPtr << "\n";
     abort();
-#endif
-    return -1;
   }
+#endif
   
   // If the load and store don't overlap at all, the store doesn't provide
   // anything to the load.  In this case, they really don't alias at all, AA
@@ -1031,11 +1031,11 @@ static int AnalyzeLoadFromClobberingWrite(const Type *LoadTy, Value *LoadPtr,
   
   
   bool isAAFailure = false;
-  if (StoreOffset < LoadOffset) {
+  if (StoreOffset < LoadOffset)
     isAAFailure = StoreOffset+int64_t(StoreSize) <= LoadOffset;
-  } else {
+  else
     isAAFailure = LoadOffset+int64_t(LoadSize) <= StoreOffset;
-  }
+
   if (isAAFailure) {
 #if 0
     dbgs() << "STORE LOAD DEP WITH COMMON BASE:\n"
index d419fd24240cc6650985199ed733dc6b939c34d3..d656c1a5fcc74876bc6118514632b456427344a6 100644 (file)
@@ -531,4 +531,16 @@ out:
 }
 
 
+; PR6642
+define i32 @memset_to_load() nounwind readnone {
+entry:
+  %x = alloca [256 x i32], align 4                ; <[256 x i32]*> [#uses=2]
+  %tmp = bitcast [256 x i32]* %x to i8*           ; <i8*> [#uses=1]
+  call void @llvm.memset.i64(i8* %tmp, i8 0, i64 1024, i32 4)
+  %arraydecay = getelementptr inbounds [256 x i32]* %x, i32 0, i32 0 ; <i32*>
+  %tmp1 = load i32* %arraydecay                   ; <i32> [#uses=1]
+  ret i32 %tmp1
+; CHECK: @memset_to_load
+; CHECK: ret i32 0
+}