aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/Scalar/GVN.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/Scalar/GVN.cpp')
-rw-r--r--lib/Transforms/Scalar/GVN.cpp25
1 files changed, 21 insertions, 4 deletions
diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp
index 6f74108b55..a6cc9931ef 100644
--- a/lib/Transforms/Scalar/GVN.cpp
+++ b/lib/Transforms/Scalar/GVN.cpp
@@ -508,7 +508,7 @@ uint32_t ValueTable::lookup_or_add(Value* V) {
} else if (Instruction *NonLocalDepInst = I->second.getInst()) {
// FIXME: INDENT PROPERLY
// FIXME: All duplicated with non-local case.
- if (DT->properlyDominates(I->first, C->getParent())) {
+ if (cdep == 0 && DT->properlyDominates(I->first, C->getParent())) {
if (CallInst* CD = dyn_cast<CallInst>(NonLocalDepInst))
cdep = CD;
else {
@@ -527,6 +527,12 @@ uint32_t ValueTable::lookup_or_add(Value* V) {
return nextValueNumber++;
}
+ // FIXME: THIS ISN'T SAFE: CONSIDER:
+ // X = strlen(str)
+ // if (C)
+ // str[0] = 1;
+ // Y = strlen(str)
+ // This doesn't guarantee all-paths availability!
if (cdep->getCalledFunction() != C->getCalledFunction() ||
cdep->getNumOperands() != C->getNumOperands()) {
valueNumbering.insert(std::make_pair(V, nextValueNumber));
@@ -874,16 +880,27 @@ bool GVN::processNonLocalLoad(LoadInst* L,
if (deps.size() > 100)
return false;
+ BasicBlock *EntryBlock = &L->getParent()->getParent()->getEntryBlock();
+
DenseMap<BasicBlock*, Value*> repl;
// Filter out useless results (non-locals, etc)
for (DenseMap<BasicBlock*, MemDepResult>::iterator I = deps.begin(),
E = deps.end(); I != E; ++I) {
- if (I->second.isNone())
- return false;
+ if (I->second.isNone()) {
+ repl[I->first] = UndefValue::get(L->getType());
+ continue;
+ }
- if (I->second.isNonLocal())
+ if (I->second.isNonLocal()) {
+ // If this is a non-local dependency in the entry block, then we depend on
+ // the value live-in at the start of the function. We could insert a load
+ // in the entry block to get this, but for now we'll just bail out.
+ // FIXME: Consider emitting a load in the entry block to catch this case!
+ if (I->first == EntryBlock)
+ return false;
continue;
+ }
if (StoreInst* S = dyn_cast<StoreInst>(I->second.getInst())) {
if (S->getPointerOperand() != L->getPointerOperand())