| Index: src/compiler/scheduler.cc
 | 
| diff --git a/src/compiler/scheduler.cc b/src/compiler/scheduler.cc
 | 
| index 674b89ef66762d0b5ffa5c5b052e094d3ac0d290..3e7d353cb7bf8e675b177b10f79079a71d09d536 100644
 | 
| --- a/src/compiler/scheduler.cc
 | 
| +++ b/src/compiler/scheduler.cc
 | 
| @@ -587,7 +587,8 @@ class SpecialRPONumberer : public ZoneObject {
 | 
|          loops_(zone),
 | 
|          backedges_(zone),
 | 
|          stack_(zone),
 | 
| -        previous_block_count_(0) {}
 | 
| +        previous_block_count_(0),
 | 
| +        empty_(0, zone) {}
 | 
|  
 | 
|    // Computes the special reverse-post-order for the main control flow graph,
 | 
|    // that is for the graph spanned between the schedule's start and end blocks.
 | 
| @@ -624,6 +625,14 @@ class SpecialRPONumberer : public ZoneObject {
 | 
|  #endif
 | 
|    }
 | 
|  
 | 
| +  const ZoneList<BasicBlock*>& GetOutgoingBlocks(BasicBlock* block) {
 | 
| +    if (HasLoopNumber(block)) {
 | 
| +      LoopInfo const& loop = loops_[GetLoopNumber(block)];
 | 
| +      if (loop.outgoing) return *loop.outgoing;
 | 
| +    }
 | 
| +    return empty_;
 | 
| +  }
 | 
| +
 | 
|   private:
 | 
|    typedef std::pair<BasicBlock*, size_t> Backedge;
 | 
|  
 | 
| @@ -1046,6 +1055,7 @@ class SpecialRPONumberer : public ZoneObject {
 | 
|    ZoneVector<Backedge> backedges_;
 | 
|    ZoneVector<SpecialRPOStackFrame> stack_;
 | 
|    size_t previous_block_count_;
 | 
| +  ZoneList<BasicBlock*> const empty_;
 | 
|  };
 | 
|  
 | 
|  
 | 
| @@ -1346,7 +1356,7 @@ class ScheduleLateNodeVisitor {
 | 
|      // Hoist nodes out of loops if possible. Nodes can be hoisted iteratively
 | 
|      // into enclosing loop pre-headers until they would preceed their schedule
 | 
|      // early position.
 | 
| -    BasicBlock* hoist_block = GetPreHeader(block);
 | 
| +    BasicBlock* hoist_block = GetHoistBlock(block);
 | 
|      if (hoist_block &&
 | 
|          hoist_block->dominator_depth() >= min_block->dominator_depth()) {
 | 
|        do {
 | 
| @@ -1354,7 +1364,7 @@ class ScheduleLateNodeVisitor {
 | 
|                node->op()->mnemonic(), hoist_block->id().ToInt());
 | 
|          DCHECK_LT(hoist_block->loop_depth(), block->loop_depth());
 | 
|          block = hoist_block;
 | 
| -        hoist_block = GetPreHeader(hoist_block);
 | 
| +        hoist_block = GetHoistBlock(hoist_block);
 | 
|        } while (hoist_block &&
 | 
|                 hoist_block->dominator_depth() >= min_block->dominator_depth());
 | 
|      } else if (scheduler_->flags_ & Scheduler::kSplitNodes) {
 | 
| @@ -1465,14 +1475,23 @@ class ScheduleLateNodeVisitor {
 | 
|      return block;
 | 
|    }
 | 
|  
 | 
| -  BasicBlock* GetPreHeader(BasicBlock* block) {
 | 
| -    if (block->IsLoopHeader()) {
 | 
| -      return block->dominator();
 | 
| -    } else if (block->loop_header() != NULL) {
 | 
| -      return block->loop_header()->dominator();
 | 
| -    } else {
 | 
| -      return NULL;
 | 
| +  BasicBlock* GetHoistBlock(BasicBlock* block) {
 | 
| +    if (block->IsLoopHeader()) return block->dominator();
 | 
| +    // We have to check to make sure that the {block} dominates all
 | 
| +    // of the outgoing blocks.  If it doesn't, then there is a path
 | 
| +    // out of the loop which does not execute this {block}, so we
 | 
| +    // can't hoist operations from this {block} out of the loop, as
 | 
| +    // that would introduce additional computations.
 | 
| +    if (BasicBlock* header_block = block->loop_header()) {
 | 
| +      for (BasicBlock* outgoing_block :
 | 
| +           scheduler_->special_rpo_->GetOutgoingBlocks(header_block)) {
 | 
| +        if (BasicBlock::GetCommonDominator(block, outgoing_block) != block) {
 | 
| +          return nullptr;
 | 
| +        }
 | 
| +      }
 | 
| +      return header_block->dominator();
 | 
|      }
 | 
| +    return nullptr;
 | 
|    }
 | 
|  
 | 
|    BasicBlock* GetCommonDominatorOfUses(Node* node) {
 | 
| 
 |