Implement a FIXME by checking to make sure that a malloc is not being used
authorChris Lattner <sabre@nondot.org>
Thu, 2 Dec 2004 07:11:07 +0000 (07:11 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 2 Dec 2004 07:11:07 +0000 (07:11 +0000)
in scary and unknown ways before we promote it.  This fixes the miscompilation
of 188.ammp that has been plauging us since a globalopt patch went in.

Thanks a ton to Tanya for helping me diagnose the problem!

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

lib/Transforms/IPO/GlobalOpt.cpp

index db2d0b3535a7cb0aa896efc945ace002afa4cfc1..0fde1d94a3d6a062ca0d07235ec4c2295bb147d5 100644 (file)
@@ -738,6 +738,29 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
   return NewGV;
 }
 
+/// ValueIsOnlyUsedLocallyOrStoredToOneGlobal - Scan the use-list of V checking
+/// to make sure that there are no complex uses of V.  We permit simple things
+/// like dereferencing the pointer, but not storing through the address, unless
+/// it is to the specified global.
+static bool ValueIsOnlyUsedLocallyOrStoredToOneGlobal(Instruction *V,
+                                                      GlobalVariable *GV) {
+  for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;++UI)
+    if (isa<LoadInst>(*UI) || isa<SetCondInst>(*UI)) {
+      // Fine, ignore.
+    } else if (StoreInst *SI = dyn_cast<StoreInst>(*UI)) {
+      if (SI->getOperand(0) == V && SI->getOperand(1) != GV)
+        return false;  // Storing the pointer itself... bad.
+      // Otherwise, storing through it, or storing into GV... fine.
+    } else if (isa<GetElementPtrInst>(*UI) || isa<SelectInst>(*UI)) {
+      if (!ValueIsOnlyUsedLocallyOrStoredToOneGlobal(cast<Instruction>(*UI),GV))
+        return false;
+    } else {
+      return false;
+    }
+  return true;
+
+}
+
 // OptimizeOnceStoredGlobal - Try to optimize globals based on the knowledge
 // that only one value (besides its initializer) is ever stored to the global.
 static bool OptimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal,
@@ -783,9 +806,8 @@ static bool OptimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal,
         if (MI->getAllocatedType()->isSized() &&
             NElements->getRawValue()*
                      TD.getTypeSize(MI->getAllocatedType()) < 2048 &&
-            AllUsesOfLoadedValueWillTrapIfNull(GV)) {
-          // FIXME: do more correctness checking to make sure the result of the
-          // malloc isn't squirrelled away somewhere.
+            AllUsesOfLoadedValueWillTrapIfNull(GV) &&
+            ValueIsOnlyUsedLocallyOrStoredToOneGlobal(MI, GV)) {
           GVI = OptimizeGlobalAddressOfMalloc(GV, MI);
           return true;
         }