summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-12-02 07:11:07 +0000
committerChris Lattner <sabre@nondot.org>2004-12-02 07:11:07 +0000
commitc0677c081d7276c9430daa0557718e3eee828263 (patch)
treefbd0f0019d41260f39483e4744407f2ee235a48b /llvm/lib/Transforms
parent3b18139b3cdefe8fc8d606b8946b8355b2227ee2 (diff)
downloadbcm5719-llvm-c0677c081d7276c9430daa0557718e3eee828263.tar.gz
bcm5719-llvm-c0677c081d7276c9430daa0557718e3eee828263.zip
Implement a FIXME by checking to make sure that a malloc is not being used
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! llvm-svn: 18418
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/IPO/GlobalOpt.cpp28
1 files changed, 25 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
index db2d0b3535a..0fde1d94a3d 100644
--- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
@@ -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;
}
OpenPOWER on IntegriCloud