diff --git a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp index 8fb9124a5f6..02eeb3cc0a4 100644 --- a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp +++ b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp @@ -532,17 +532,26 @@ void PromoteMem2Reg::run() { void PromoteMem2Reg::RewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info) { StoreInst *OnlyStore = Info.OnlyStore; + bool StoringGlobalVal = !isa(OnlyStore->getOperand(0)); // Be aware of loads before the store. SmallPtrSet ProcessedBlocks; for (unsigned i = 0, e = Info.UsingBlocks.size(); i != e; ++i) { - // If the store dominates the block and if we haven't processed it yet, - // do so now. - if (!dominates(OnlyStore->getParent(), Info.UsingBlocks[i])) - continue; - BasicBlock *UseBlock = Info.UsingBlocks[i]; - if (!ProcessedBlocks.insert(UseBlock)) + + // If we already processed this block, don't reprocess it. + if (!ProcessedBlocks.insert(UseBlock)) { + Info.UsingBlocks[i] = Info.UsingBlocks.back(); + Info.UsingBlocks.pop_back(); + --i; --e; + continue; + } + + // If the store dominates the block and if we haven't processed it yet, + // do so now. We can't handle the case where the store doesn't dominate a + // block because there may be a path between the store and the use, but we + // may need to insert phi nodes to handle dominance properly. + if (StoringGlobalVal || !dominates(OnlyStore->getParent(), UseBlock)) continue; // If the use and store are in the same block, do a quick scan to @@ -553,7 +562,8 @@ void PromoteMem2Reg::RewriteSingleStoreAlloca(AllocaInst *AI, if (isa(I) && I->getOperand(0) == AI) break; } - if (&*I != OnlyStore) break; // Do not handle this case. + if (&*I != OnlyStore) + break; // Do not handle this alloca. } // Otherwise, if this is a different block or if all uses happen