Home | History | Annotate | Download | only in compiler
      1 // Copyright 2015 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/compiler/effect-control-linearizer.h"
      6 
      7 #include "src/code-factory.h"
      8 #include "src/compiler/access-builder.h"
      9 #include "src/compiler/compiler-source-position-table.h"
     10 #include "src/compiler/js-graph.h"
     11 #include "src/compiler/linkage.h"
     12 #include "src/compiler/node-matchers.h"
     13 #include "src/compiler/node-properties.h"
     14 #include "src/compiler/node.h"
     15 #include "src/compiler/schedule.h"
     16 #include "src/objects-inl.h"
     17 
     18 namespace v8 {
     19 namespace internal {
     20 namespace compiler {
     21 
     22 EffectControlLinearizer::EffectControlLinearizer(
     23     JSGraph* js_graph, Schedule* schedule, Zone* temp_zone,
     24     SourcePositionTable* source_positions)
     25     : js_graph_(js_graph),
     26       schedule_(schedule),
     27       temp_zone_(temp_zone),
     28       source_positions_(source_positions),
     29       graph_assembler_(js_graph, nullptr, nullptr, temp_zone) {}
     30 
     31 Graph* EffectControlLinearizer::graph() const { return js_graph_->graph(); }
     32 CommonOperatorBuilder* EffectControlLinearizer::common() const {
     33   return js_graph_->common();
     34 }
     35 SimplifiedOperatorBuilder* EffectControlLinearizer::simplified() const {
     36   return js_graph_->simplified();
     37 }
     38 MachineOperatorBuilder* EffectControlLinearizer::machine() const {
     39   return js_graph_->machine();
     40 }
     41 
     42 namespace {
     43 
     44 struct BlockEffectControlData {
     45   Node* current_effect = nullptr;       // New effect.
     46   Node* current_control = nullptr;      // New control.
     47   Node* current_frame_state = nullptr;  // New frame state.
     48 };
     49 
     50 class BlockEffectControlMap {
     51  public:
     52   explicit BlockEffectControlMap(Zone* temp_zone) : map_(temp_zone) {}
     53 
     54   BlockEffectControlData& For(BasicBlock* from, BasicBlock* to) {
     55     return map_[std::make_pair(from->rpo_number(), to->rpo_number())];
     56   }
     57 
     58   const BlockEffectControlData& For(BasicBlock* from, BasicBlock* to) const {
     59     return map_.at(std::make_pair(from->rpo_number(), to->rpo_number()));
     60   }
     61 
     62  private:
     63   typedef std::pair<int32_t, int32_t> Key;
     64   typedef ZoneMap<Key, BlockEffectControlData> Map;
     65 
     66   Map map_;
     67 };
     68 
     69 // Effect phis that need to be updated after the first pass.
     70 struct PendingEffectPhi {
     71   Node* effect_phi;
     72   BasicBlock* block;
     73 
     74   PendingEffectPhi(Node* effect_phi, BasicBlock* block)
     75       : effect_phi(effect_phi), block(block) {}
     76 };
     77 
     78 void UpdateEffectPhi(Node* node, BasicBlock* block,
     79                      BlockEffectControlMap* block_effects) {
     80   // Update all inputs to an effect phi with the effects from the given
     81   // block->effect map.
     82   DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode());
     83   DCHECK_EQ(static_cast<size_t>(node->op()->EffectInputCount()),
     84             block->PredecessorCount());
     85   for (int i = 0; i < node->op()->EffectInputCount(); i++) {
     86     Node* input = node->InputAt(i);
     87     BasicBlock* predecessor = block->PredecessorAt(static_cast<size_t>(i));
     88     const BlockEffectControlData& block_effect =
     89         block_effects->For(predecessor, block);
     90     if (input != block_effect.current_effect) {
     91       node->ReplaceInput(i, block_effect.current_effect);
     92     }
     93   }
     94 }
     95 
     96 void UpdateBlockControl(BasicBlock* block,
     97                         BlockEffectControlMap* block_effects) {
     98   Node* control = block->NodeAt(0);
     99   DCHECK(NodeProperties::IsControl(control));
    100 
    101   // Do not rewire the end node.
    102   if (control->opcode() == IrOpcode::kEnd) return;
    103 
    104   // Update all inputs to the given control node with the correct control.
    105   DCHECK(control->opcode() == IrOpcode::kMerge ||
    106          static_cast<size_t>(control->op()->ControlInputCount()) ==
    107              block->PredecessorCount());
    108   if (static_cast<size_t>(control->op()->ControlInputCount()) !=
    109       block->PredecessorCount()) {
    110     return;  // We already re-wired the control inputs of this node.
    111   }
    112   for (int i = 0; i < control->op()->ControlInputCount(); i++) {
    113     Node* input = NodeProperties::GetControlInput(control, i);
    114     BasicBlock* predecessor = block->PredecessorAt(static_cast<size_t>(i));
    115     const BlockEffectControlData& block_effect =
    116         block_effects->For(predecessor, block);
    117     if (input != block_effect.current_control) {
    118       NodeProperties::ReplaceControlInput(control, block_effect.current_control,
    119                                           i);
    120     }
    121   }
    122 }
    123 
    124 bool HasIncomingBackEdges(BasicBlock* block) {
    125   for (BasicBlock* pred : block->predecessors()) {
    126     if (pred->rpo_number() >= block->rpo_number()) {
    127       return true;
    128     }
    129   }
    130   return false;
    131 }
    132 
    133 void RemoveRegionNode(Node* node) {
    134   DCHECK(IrOpcode::kFinishRegion == node->opcode() ||
    135          IrOpcode::kBeginRegion == node->opcode());
    136   // Update the value/context uses to the value input of the finish node and
    137   // the effect uses to the effect input.
    138   for (Edge edge : node->use_edges()) {
    139     DCHECK(!edge.from()->IsDead());
    140     if (NodeProperties::IsEffectEdge(edge)) {
    141       edge.UpdateTo(NodeProperties::GetEffectInput(node));
    142     } else {
    143       DCHECK(!NodeProperties::IsControlEdge(edge));
    144       DCHECK(!NodeProperties::IsFrameStateEdge(edge));
    145       edge.UpdateTo(node->InputAt(0));
    146     }
    147   }
    148   node->Kill();
    149 }
    150 
    151 void TryCloneBranch(Node* node, BasicBlock* block, Graph* graph,
    152                     CommonOperatorBuilder* common,
    153                     BlockEffectControlMap* block_effects,
    154                     SourcePositionTable* source_positions) {
    155   DCHECK_EQ(IrOpcode::kBranch, node->opcode());
    156 
    157   // This optimization is a special case of (super)block cloning. It takes an
    158   // input graph as shown below and clones the Branch node for every predecessor
    159   // to the Merge, essentially removing the Merge completely. This avoids
    160   // materializing the bit for the Phi and may offer potential for further
    161   // branch folding optimizations (i.e. because one or more inputs to the Phi is
    162   // a constant). Note that there may be more Phi nodes hanging off the Merge,
    163   // but we can only a certain subset of them currently (actually only Phi and
    164   // EffectPhi nodes whose uses have either the IfTrue or IfFalse as control
    165   // input).
    166 
    167   //   Control1 ... ControlN
    168   //      ^            ^
    169   //      |            |   Cond1 ... CondN
    170   //      +----+  +----+     ^         ^
    171   //           |  |          |         |
    172   //           |  |     +----+         |
    173   //          Merge<--+ | +------------+
    174   //            ^      \|/
    175   //            |      Phi
    176   //            |       |
    177   //          Branch----+
    178   //            ^
    179   //            |
    180   //      +-----+-----+
    181   //      |           |
    182   //    IfTrue     IfFalse
    183   //      ^           ^
    184   //      |           |
    185 
    186   // The resulting graph (modulo the Phi and EffectPhi nodes) looks like this:
    187 
    188   // Control1 Cond1 ... ControlN CondN
    189   //    ^      ^           ^      ^
    190   //    \      /           \      /
    191   //     Branch     ...     Branch
    192   //       ^                  ^
    193   //       |                  |
    194   //   +---+---+          +---+----+
    195   //   |       |          |        |
    196   // IfTrue IfFalse ... IfTrue  IfFalse
    197   //   ^       ^          ^        ^
    198   //   |       |          |        |
    199   //   +--+ +-------------+        |
    200   //      | |  +--------------+ +--+
    201   //      | |                 | |
    202   //     Merge               Merge
    203   //       ^                   ^
    204   //       |                   |
    205 
    206   SourcePositionTable::Scope scope(source_positions,
    207                                    source_positions->GetSourcePosition(node));
    208   Node* branch = node;
    209   Node* cond = NodeProperties::GetValueInput(branch, 0);
    210   if (!cond->OwnedBy(branch) || cond->opcode() != IrOpcode::kPhi) return;
    211   Node* merge = NodeProperties::GetControlInput(branch);
    212   if (merge->opcode() != IrOpcode::kMerge ||
    213       NodeProperties::GetControlInput(cond) != merge) {
    214     return;
    215   }
    216   // Grab the IfTrue/IfFalse projections of the Branch.
    217   BranchMatcher matcher(branch);
    218   // Check/collect other Phi/EffectPhi nodes hanging off the Merge.
    219   NodeVector phis(graph->zone());
    220   for (Node* const use : merge->uses()) {
    221     if (use == branch || use == cond) continue;
    222     // We cannot currently deal with non-Phi/EffectPhi nodes hanging off the
    223     // Merge. Ideally, we would just clone the nodes (and everything that
    224     // depends on it to some distant join point), but that requires knowledge
    225     // about dominance/post-dominance.
    226     if (!NodeProperties::IsPhi(use)) return;
    227     for (Edge edge : use->use_edges()) {
    228       // Right now we can only handle Phi/EffectPhi nodes whose uses are
    229       // directly control-dependend on either the IfTrue or the IfFalse
    230       // successor, because we know exactly how to update those uses.
    231       if (edge.from()->op()->ControlInputCount() != 1) return;
    232       Node* control = NodeProperties::GetControlInput(edge.from());
    233       if (NodeProperties::IsPhi(edge.from())) {
    234         control = NodeProperties::GetControlInput(control, edge.index());
    235       }
    236       if (control != matcher.IfTrue() && control != matcher.IfFalse()) return;
    237     }
    238     phis.push_back(use);
    239   }
    240   BranchHint const hint = BranchHintOf(branch->op());
    241   int const input_count = merge->op()->ControlInputCount();
    242   DCHECK_LE(1, input_count);
    243   Node** const inputs = graph->zone()->NewArray<Node*>(2 * input_count);
    244   Node** const merge_true_inputs = &inputs[0];
    245   Node** const merge_false_inputs = &inputs[input_count];
    246   for (int index = 0; index < input_count; ++index) {
    247     Node* cond1 = NodeProperties::GetValueInput(cond, index);
    248     Node* control1 = NodeProperties::GetControlInput(merge, index);
    249     Node* branch1 = graph->NewNode(common->Branch(hint), cond1, control1);
    250     merge_true_inputs[index] = graph->NewNode(common->IfTrue(), branch1);
    251     merge_false_inputs[index] = graph->NewNode(common->IfFalse(), branch1);
    252   }
    253   Node* const merge_true = matcher.IfTrue();
    254   Node* const merge_false = matcher.IfFalse();
    255   merge_true->TrimInputCount(0);
    256   merge_false->TrimInputCount(0);
    257   for (int i = 0; i < input_count; ++i) {
    258     merge_true->AppendInput(graph->zone(), merge_true_inputs[i]);
    259     merge_false->AppendInput(graph->zone(), merge_false_inputs[i]);
    260   }
    261   DCHECK_EQ(2u, block->SuccessorCount());
    262   NodeProperties::ChangeOp(matcher.IfTrue(), common->Merge(input_count));
    263   NodeProperties::ChangeOp(matcher.IfFalse(), common->Merge(input_count));
    264   int const true_index =
    265       block->SuccessorAt(0)->NodeAt(0) == matcher.IfTrue() ? 0 : 1;
    266   BlockEffectControlData* true_block_data =
    267       &block_effects->For(block, block->SuccessorAt(true_index));
    268   BlockEffectControlData* false_block_data =
    269       &block_effects->For(block, block->SuccessorAt(true_index ^ 1));
    270   for (Node* const phi : phis) {
    271     for (int index = 0; index < input_count; ++index) {
    272       inputs[index] = phi->InputAt(index);
    273     }
    274     inputs[input_count] = merge_true;
    275     Node* phi_true = graph->NewNode(phi->op(), input_count + 1, inputs);
    276     inputs[input_count] = merge_false;
    277     Node* phi_false = graph->NewNode(phi->op(), input_count + 1, inputs);
    278     if (phi->UseCount() == 0) {
    279       DCHECK_EQ(phi->opcode(), IrOpcode::kEffectPhi);
    280     } else {
    281       for (Edge edge : phi->use_edges()) {
    282         Node* control = NodeProperties::GetControlInput(edge.from());
    283         if (NodeProperties::IsPhi(edge.from())) {
    284           control = NodeProperties::GetControlInput(control, edge.index());
    285         }
    286         DCHECK(control == matcher.IfTrue() || control == matcher.IfFalse());
    287         edge.UpdateTo((control == matcher.IfTrue()) ? phi_true : phi_false);
    288       }
    289     }
    290     if (phi->opcode() == IrOpcode::kEffectPhi) {
    291       true_block_data->current_effect = phi_true;
    292       false_block_data->current_effect = phi_false;
    293     }
    294     phi->Kill();
    295   }
    296   // Fix up IfTrue and IfFalse and kill all dead nodes.
    297   if (branch == block->control_input()) {
    298     true_block_data->current_control = merge_true;
    299     false_block_data->current_control = merge_false;
    300   }
    301   branch->Kill();
    302   cond->Kill();
    303   merge->Kill();
    304 }
    305 }  // namespace
    306 
    307 void EffectControlLinearizer::Run() {
    308   BlockEffectControlMap block_effects(temp_zone());
    309   ZoneVector<PendingEffectPhi> pending_effect_phis(temp_zone());
    310   ZoneVector<BasicBlock*> pending_block_controls(temp_zone());
    311   NodeVector inputs_buffer(temp_zone());
    312 
    313   for (BasicBlock* block : *(schedule()->rpo_order())) {
    314     size_t instr = 0;
    315 
    316     // The control node should be the first.
    317     Node* control = block->NodeAt(instr);
    318     DCHECK(NodeProperties::IsControl(control));
    319     // Update the control inputs.
    320     if (HasIncomingBackEdges(block)) {
    321       // If there are back edges, we need to update later because we have not
    322       // computed the control yet. This should only happen for loops.
    323       DCHECK_EQ(IrOpcode::kLoop, control->opcode());
    324       pending_block_controls.push_back(block);
    325     } else {
    326       // If there are no back edges, we can update now.
    327       UpdateBlockControl(block, &block_effects);
    328     }
    329     instr++;
    330 
    331     // Iterate over the phis and update the effect phis.
    332     Node* effect = nullptr;
    333     Node* terminate = nullptr;
    334     for (; instr < block->NodeCount(); instr++) {
    335       Node* node = block->NodeAt(instr);
    336       // Only go through the phis and effect phis.
    337       if (node->opcode() == IrOpcode::kEffectPhi) {
    338         // There should be at most one effect phi in a block.
    339         DCHECK_NULL(effect);
    340         // IfException blocks should not have effect phis.
    341         DCHECK_NE(IrOpcode::kIfException, control->opcode());
    342         effect = node;
    343 
    344         // Make sure we update the inputs to the incoming blocks' effects.
    345         if (HasIncomingBackEdges(block)) {
    346           // In case of loops, we do not update the effect phi immediately
    347           // because the back predecessor has not been handled yet. We just
    348           // record the effect phi for later processing.
    349           pending_effect_phis.push_back(PendingEffectPhi(node, block));
    350         } else {
    351           UpdateEffectPhi(node, block, &block_effects);
    352         }
    353       } else if (node->opcode() == IrOpcode::kPhi) {
    354         // Just skip phis.
    355       } else if (node->opcode() == IrOpcode::kTerminate) {
    356         DCHECK(terminate == nullptr);
    357         terminate = node;
    358       } else {
    359         break;
    360       }
    361     }
    362 
    363     if (effect == nullptr) {
    364       // There was no effect phi.
    365       DCHECK(!HasIncomingBackEdges(block));
    366       if (block == schedule()->start()) {
    367         // Start block => effect is start.
    368         DCHECK_EQ(graph()->start(), control);
    369         effect = graph()->start();
    370       } else if (control->opcode() == IrOpcode::kEnd) {
    371         // End block is just a dummy, no effect needed.
    372         DCHECK_EQ(BasicBlock::kNone, block->control());
    373         DCHECK_EQ(1u, block->size());
    374         effect = nullptr;
    375       } else {
    376         // If all the predecessors have the same effect, we can use it as our
    377         // current effect.
    378         effect =
    379             block_effects.For(block->PredecessorAt(0), block).current_effect;
    380         for (size_t i = 1; i < block->PredecessorCount(); ++i) {
    381           if (block_effects.For(block->PredecessorAt(i), block)
    382                   .current_effect != effect) {
    383             effect = nullptr;
    384             break;
    385           }
    386         }
    387         if (effect == nullptr) {
    388           DCHECK_NE(IrOpcode::kIfException, control->opcode());
    389           // The input blocks do not have the same effect. We have
    390           // to create an effect phi node.
    391           inputs_buffer.clear();
    392           inputs_buffer.resize(block->PredecessorCount(), jsgraph()->Dead());
    393           inputs_buffer.push_back(control);
    394           effect = graph()->NewNode(
    395               common()->EffectPhi(static_cast<int>(block->PredecessorCount())),
    396               static_cast<int>(inputs_buffer.size()), &(inputs_buffer.front()));
    397           // For loops, we update the effect phi node later to break cycles.
    398           if (control->opcode() == IrOpcode::kLoop) {
    399             pending_effect_phis.push_back(PendingEffectPhi(effect, block));
    400           } else {
    401             UpdateEffectPhi(effect, block, &block_effects);
    402           }
    403         } else if (control->opcode() == IrOpcode::kIfException) {
    404           // The IfException is connected into the effect chain, so we need
    405           // to update the effect here.
    406           NodeProperties::ReplaceEffectInput(control, effect);
    407           effect = control;
    408         }
    409       }
    410     }
    411 
    412     // Fixup the Terminate node.
    413     if (terminate != nullptr) {
    414       NodeProperties::ReplaceEffectInput(terminate, effect);
    415     }
    416 
    417     // The frame state at block entry is determined by the frame states leaving
    418     // all predecessors. In case there is no frame state dominating this block,
    419     // we can rely on a checkpoint being present before the next deoptimization.
    420     // TODO(mstarzinger): Eventually we will need to go hunt for a frame state
    421     // once deoptimizing nodes roam freely through the schedule.
    422     Node* frame_state = nullptr;
    423     if (block != schedule()->start()) {
    424       // If all the predecessors have the same effect, we can use it
    425       // as our current effect.
    426       frame_state =
    427           block_effects.For(block->PredecessorAt(0), block).current_frame_state;
    428       for (size_t i = 1; i < block->PredecessorCount(); i++) {
    429         if (block_effects.For(block->PredecessorAt(i), block)
    430                 .current_frame_state != frame_state) {
    431           frame_state = nullptr;
    432           break;
    433         }
    434       }
    435     }
    436 
    437     // Process the ordinary instructions.
    438     for (; instr < block->NodeCount(); instr++) {
    439       Node* node = block->NodeAt(instr);
    440       ProcessNode(node, &frame_state, &effect, &control);
    441     }
    442 
    443     switch (block->control()) {
    444       case BasicBlock::kGoto:
    445       case BasicBlock::kNone:
    446         break;
    447 
    448       case BasicBlock::kCall:
    449       case BasicBlock::kTailCall:
    450       case BasicBlock::kSwitch:
    451       case BasicBlock::kReturn:
    452       case BasicBlock::kDeoptimize:
    453       case BasicBlock::kThrow:
    454         ProcessNode(block->control_input(), &frame_state, &effect, &control);
    455         break;
    456 
    457       case BasicBlock::kBranch:
    458         ProcessNode(block->control_input(), &frame_state, &effect, &control);
    459         TryCloneBranch(block->control_input(), block, graph(), common(),
    460                        &block_effects, source_positions_);
    461         break;
    462     }
    463 
    464     // Store the effect, control and frame state for later use.
    465     for (BasicBlock* successor : block->successors()) {
    466       BlockEffectControlData* data = &block_effects.For(block, successor);
    467       if (data->current_effect == nullptr) {
    468         data->current_effect = effect;
    469       }
    470       if (data->current_control == nullptr) {
    471         data->current_control = control;
    472       }
    473       data->current_frame_state = frame_state;
    474     }
    475   }
    476 
    477   // Update the incoming edges of the effect phis that could not be processed
    478   // during the first pass (because they could have incoming back edges).
    479   for (const PendingEffectPhi& pending_effect_phi : pending_effect_phis) {
    480     UpdateEffectPhi(pending_effect_phi.effect_phi, pending_effect_phi.block,
    481                     &block_effects);
    482   }
    483   for (BasicBlock* pending_block_control : pending_block_controls) {
    484     UpdateBlockControl(pending_block_control, &block_effects);
    485   }
    486 }
    487 
    488 namespace {
    489 
    490 void TryScheduleCallIfSuccess(Node* node, Node** control) {
    491   // Schedule the call's IfSuccess node if there is no exception use.
    492   if (!NodeProperties::IsExceptionalCall(node)) {
    493     for (Edge edge : node->use_edges()) {
    494       if (NodeProperties::IsControlEdge(edge) &&
    495           edge.from()->opcode() == IrOpcode::kIfSuccess) {
    496         *control = edge.from();
    497       }
    498     }
    499   }
    500 }
    501 
    502 }  // namespace
    503 
    504 void EffectControlLinearizer::ProcessNode(Node* node, Node** frame_state,
    505                                           Node** effect, Node** control) {
    506   SourcePositionTable::Scope scope(source_positions_,
    507                                    source_positions_->GetSourcePosition(node));
    508 
    509   // If the node needs to be wired into the effect/control chain, do this
    510   // here. Pass current frame state for lowering to eager deoptimization.
    511   if (TryWireInStateEffect(node, *frame_state, effect, control)) {
    512     return;
    513   }
    514 
    515   // If the node has a visible effect, then there must be a checkpoint in the
    516   // effect chain before we are allowed to place another eager deoptimization
    517   // point. We zap the frame state to ensure this invariant is maintained.
    518   if (region_observability_ == RegionObservability::kObservable &&
    519       !node->op()->HasProperty(Operator::kNoWrite)) {
    520     *frame_state = nullptr;
    521   }
    522 
    523   // Remove the end markers of 'atomic' allocation region because the
    524   // region should be wired-in now.
    525   if (node->opcode() == IrOpcode::kFinishRegion) {
    526     // Reset the current region observability.
    527     region_observability_ = RegionObservability::kObservable;
    528     // Update the value uses to the value input of the finish node and
    529     // the effect uses to the effect input.
    530     return RemoveRegionNode(node);
    531   }
    532   if (node->opcode() == IrOpcode::kBeginRegion) {
    533     // Determine the observability for this region and use that for all
    534     // nodes inside the region (i.e. ignore the absence of kNoWrite on
    535     // StoreField and other operators).
    536     DCHECK_NE(RegionObservability::kNotObservable, region_observability_);
    537     region_observability_ = RegionObservabilityOf(node->op());
    538     // Update the value uses to the value input of the finish node and
    539     // the effect uses to the effect input.
    540     return RemoveRegionNode(node);
    541   }
    542 
    543   // Special treatment for checkpoint nodes.
    544   if (node->opcode() == IrOpcode::kCheckpoint) {
    545     // Unlink the check point; effect uses will be updated to the incoming
    546     // effect that is passed. The frame state is preserved for lowering.
    547     DCHECK_EQ(RegionObservability::kObservable, region_observability_);
    548     *frame_state = NodeProperties::GetFrameStateInput(node);
    549     return;
    550   }
    551 
    552   if (node->opcode() == IrOpcode::kIfSuccess) {
    553     // We always schedule IfSuccess with its call, so skip it here.
    554     DCHECK_EQ(IrOpcode::kCall, node->InputAt(0)->opcode());
    555     // The IfSuccess node should not belong to an exceptional call node
    556     // because such IfSuccess nodes should only start a basic block (and
    557     // basic block start nodes are not handled in the ProcessNode method).
    558     DCHECK(!NodeProperties::IsExceptionalCall(node->InputAt(0)));
    559     return;
    560   }
    561 
    562   // If the node takes an effect, replace with the current one.
    563   if (node->op()->EffectInputCount() > 0) {
    564     DCHECK_EQ(1, node->op()->EffectInputCount());
    565     Node* input_effect = NodeProperties::GetEffectInput(node);
    566 
    567     if (input_effect != *effect) {
    568       NodeProperties::ReplaceEffectInput(node, *effect);
    569     }
    570 
    571     // If the node produces an effect, update our current effect. (However,
    572     // ignore new effect chains started with ValueEffect.)
    573     if (node->op()->EffectOutputCount() > 0) {
    574       DCHECK_EQ(1, node->op()->EffectOutputCount());
    575       *effect = node;
    576     }
    577   } else {
    578     // New effect chain is only started with a Start or ValueEffect node.
    579     DCHECK(node->op()->EffectOutputCount() == 0 ||
    580            node->opcode() == IrOpcode::kStart);
    581   }
    582 
    583   // Rewire control inputs.
    584   for (int i = 0; i < node->op()->ControlInputCount(); i++) {
    585     NodeProperties::ReplaceControlInput(node, *control, i);
    586   }
    587   // Update the current control and wire IfSuccess right after calls.
    588   if (node->op()->ControlOutputCount() > 0) {
    589     *control = node;
    590     if (node->opcode() == IrOpcode::kCall) {
    591       // Schedule the call's IfSuccess node (if there is no exception use).
    592       TryScheduleCallIfSuccess(node, control);
    593     }
    594   }
    595 }
    596 
    597 bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
    598                                                    Node* frame_state,
    599                                                    Node** effect,
    600                                                    Node** control) {
    601   gasm()->Reset(*effect, *control);
    602   Node* result = nullptr;
    603   switch (node->opcode()) {
    604     case IrOpcode::kChangeBitToTagged:
    605       result = LowerChangeBitToTagged(node);
    606       break;
    607     case IrOpcode::kChangeInt31ToTaggedSigned:
    608       result = LowerChangeInt31ToTaggedSigned(node);
    609       break;
    610     case IrOpcode::kChangeInt32ToTagged:
    611       result = LowerChangeInt32ToTagged(node);
    612       break;
    613     case IrOpcode::kChangeUint32ToTagged:
    614       result = LowerChangeUint32ToTagged(node);
    615       break;
    616     case IrOpcode::kChangeFloat64ToTagged:
    617       result = LowerChangeFloat64ToTagged(node);
    618       break;
    619     case IrOpcode::kChangeFloat64ToTaggedPointer:
    620       result = LowerChangeFloat64ToTaggedPointer(node);
    621       break;
    622     case IrOpcode::kChangeTaggedSignedToInt32:
    623       result = LowerChangeTaggedSignedToInt32(node);
    624       break;
    625     case IrOpcode::kChangeTaggedToBit:
    626       result = LowerChangeTaggedToBit(node);
    627       break;
    628     case IrOpcode::kChangeTaggedToInt32:
    629       result = LowerChangeTaggedToInt32(node);
    630       break;
    631     case IrOpcode::kChangeTaggedToUint32:
    632       result = LowerChangeTaggedToUint32(node);
    633       break;
    634     case IrOpcode::kChangeTaggedToFloat64:
    635       result = LowerChangeTaggedToFloat64(node);
    636       break;
    637     case IrOpcode::kChangeTaggedToTaggedSigned:
    638       result = LowerChangeTaggedToTaggedSigned(node);
    639       break;
    640     case IrOpcode::kTruncateTaggedToBit:
    641       result = LowerTruncateTaggedToBit(node);
    642       break;
    643     case IrOpcode::kTruncateTaggedToFloat64:
    644       result = LowerTruncateTaggedToFloat64(node);
    645       break;
    646     case IrOpcode::kCheckBounds:
    647       result = LowerCheckBounds(node, frame_state);
    648       break;
    649     case IrOpcode::kCheckMaps:
    650       result = LowerCheckMaps(node, frame_state);
    651       break;
    652     case IrOpcode::kCheckNumber:
    653       result = LowerCheckNumber(node, frame_state);
    654       break;
    655     case IrOpcode::kCheckReceiver:
    656       result = LowerCheckReceiver(node, frame_state);
    657       break;
    658     case IrOpcode::kCheckString:
    659       result = LowerCheckString(node, frame_state);
    660       break;
    661     case IrOpcode::kCheckInternalizedString:
    662       result = LowerCheckInternalizedString(node, frame_state);
    663       break;
    664     case IrOpcode::kCheckIf:
    665       result = LowerCheckIf(node, frame_state);
    666       break;
    667     case IrOpcode::kCheckedInt32Add:
    668       result = LowerCheckedInt32Add(node, frame_state);
    669       break;
    670     case IrOpcode::kCheckedInt32Sub:
    671       result = LowerCheckedInt32Sub(node, frame_state);
    672       break;
    673     case IrOpcode::kCheckedInt32Div:
    674       result = LowerCheckedInt32Div(node, frame_state);
    675       break;
    676     case IrOpcode::kCheckedInt32Mod:
    677       result = LowerCheckedInt32Mod(node, frame_state);
    678       break;
    679     case IrOpcode::kCheckedUint32Div:
    680       result = LowerCheckedUint32Div(node, frame_state);
    681       break;
    682     case IrOpcode::kCheckedUint32Mod:
    683       result = LowerCheckedUint32Mod(node, frame_state);
    684       break;
    685     case IrOpcode::kCheckedInt32Mul:
    686       result = LowerCheckedInt32Mul(node, frame_state);
    687       break;
    688     case IrOpcode::kCheckedInt32ToTaggedSigned:
    689       result = LowerCheckedInt32ToTaggedSigned(node, frame_state);
    690       break;
    691     case IrOpcode::kCheckedUint32ToInt32:
    692       result = LowerCheckedUint32ToInt32(node, frame_state);
    693       break;
    694     case IrOpcode::kCheckedUint32ToTaggedSigned:
    695       result = LowerCheckedUint32ToTaggedSigned(node, frame_state);
    696       break;
    697     case IrOpcode::kCheckedFloat64ToInt32:
    698       result = LowerCheckedFloat64ToInt32(node, frame_state);
    699       break;
    700     case IrOpcode::kCheckedTaggedSignedToInt32:
    701       result = LowerCheckedTaggedSignedToInt32(node, frame_state);
    702       break;
    703     case IrOpcode::kCheckedTaggedToInt32:
    704       result = LowerCheckedTaggedToInt32(node, frame_state);
    705       break;
    706     case IrOpcode::kCheckedTaggedToFloat64:
    707       result = LowerCheckedTaggedToFloat64(node, frame_state);
    708       break;
    709     case IrOpcode::kCheckedTaggedToTaggedSigned:
    710       result = LowerCheckedTaggedToTaggedSigned(node, frame_state);
    711       break;
    712     case IrOpcode::kCheckedTaggedToTaggedPointer:
    713       result = LowerCheckedTaggedToTaggedPointer(node, frame_state);
    714       break;
    715     case IrOpcode::kTruncateTaggedToWord32:
    716       result = LowerTruncateTaggedToWord32(node);
    717       break;
    718     case IrOpcode::kCheckedTruncateTaggedToWord32:
    719       result = LowerCheckedTruncateTaggedToWord32(node, frame_state);
    720       break;
    721     case IrOpcode::kObjectIsDetectableCallable:
    722       result = LowerObjectIsDetectableCallable(node);
    723       break;
    724     case IrOpcode::kObjectIsNonCallable:
    725       result = LowerObjectIsNonCallable(node);
    726       break;
    727     case IrOpcode::kObjectIsNumber:
    728       result = LowerObjectIsNumber(node);
    729       break;
    730     case IrOpcode::kObjectIsReceiver:
    731       result = LowerObjectIsReceiver(node);
    732       break;
    733     case IrOpcode::kObjectIsSmi:
    734       result = LowerObjectIsSmi(node);
    735       break;
    736     case IrOpcode::kObjectIsString:
    737       result = LowerObjectIsString(node);
    738       break;
    739     case IrOpcode::kObjectIsUndetectable:
    740       result = LowerObjectIsUndetectable(node);
    741       break;
    742     case IrOpcode::kNewRestParameterElements:
    743       result = LowerNewRestParameterElements(node);
    744       break;
    745     case IrOpcode::kNewUnmappedArgumentsElements:
    746       result = LowerNewUnmappedArgumentsElements(node);
    747       break;
    748     case IrOpcode::kArrayBufferWasNeutered:
    749       result = LowerArrayBufferWasNeutered(node);
    750       break;
    751     case IrOpcode::kStringFromCharCode:
    752       result = LowerStringFromCharCode(node);
    753       break;
    754     case IrOpcode::kStringFromCodePoint:
    755       result = LowerStringFromCodePoint(node);
    756       break;
    757     case IrOpcode::kStringIndexOf:
    758       result = LowerStringIndexOf(node);
    759       break;
    760     case IrOpcode::kStringCharAt:
    761       result = LowerStringCharAt(node);
    762       break;
    763     case IrOpcode::kStringCharCodeAt:
    764       result = LowerStringCharCodeAt(node);
    765       break;
    766     case IrOpcode::kStringEqual:
    767       result = LowerStringEqual(node);
    768       break;
    769     case IrOpcode::kStringLessThan:
    770       result = LowerStringLessThan(node);
    771       break;
    772     case IrOpcode::kStringLessThanOrEqual:
    773       result = LowerStringLessThanOrEqual(node);
    774       break;
    775     case IrOpcode::kCheckFloat64Hole:
    776       result = LowerCheckFloat64Hole(node, frame_state);
    777       break;
    778     case IrOpcode::kCheckTaggedHole:
    779       result = LowerCheckTaggedHole(node, frame_state);
    780       break;
    781     case IrOpcode::kConvertTaggedHoleToUndefined:
    782       result = LowerConvertTaggedHoleToUndefined(node);
    783       break;
    784     case IrOpcode::kPlainPrimitiveToNumber:
    785       result = LowerPlainPrimitiveToNumber(node);
    786       break;
    787     case IrOpcode::kPlainPrimitiveToWord32:
    788       result = LowerPlainPrimitiveToWord32(node);
    789       break;
    790     case IrOpcode::kPlainPrimitiveToFloat64:
    791       result = LowerPlainPrimitiveToFloat64(node);
    792       break;
    793     case IrOpcode::kEnsureWritableFastElements:
    794       result = LowerEnsureWritableFastElements(node);
    795       break;
    796     case IrOpcode::kMaybeGrowFastElements:
    797       result = LowerMaybeGrowFastElements(node, frame_state);
    798       break;
    799     case IrOpcode::kTransitionElementsKind:
    800       LowerTransitionElementsKind(node);
    801       break;
    802     case IrOpcode::kLoadTypedElement:
    803       result = LowerLoadTypedElement(node);
    804       break;
    805     case IrOpcode::kStoreTypedElement:
    806       LowerStoreTypedElement(node);
    807       break;
    808     case IrOpcode::kFloat64RoundUp:
    809       if (!LowerFloat64RoundUp(node).To(&result)) {
    810         return false;
    811       }
    812       break;
    813     case IrOpcode::kFloat64RoundDown:
    814       if (!LowerFloat64RoundDown(node).To(&result)) {
    815         return false;
    816       }
    817       break;
    818     case IrOpcode::kFloat64RoundTruncate:
    819       if (!LowerFloat64RoundTruncate(node).To(&result)) {
    820         return false;
    821       }
    822       break;
    823     case IrOpcode::kFloat64RoundTiesEven:
    824       if (!LowerFloat64RoundTiesEven(node).To(&result)) {
    825         return false;
    826       }
    827       break;
    828     default:
    829       return false;
    830   }
    831   *effect = gasm()->ExtractCurrentEffect();
    832   *control = gasm()->ExtractCurrentControl();
    833   NodeProperties::ReplaceUses(node, result, *effect, *control);
    834   return true;
    835 }
    836 
    837 #define __ gasm()->
    838 
    839 Node* EffectControlLinearizer::LowerChangeFloat64ToTagged(Node* node) {
    840   Node* value = node->InputAt(0);
    841   return AllocateHeapNumberWithValue(value);
    842 }
    843 
    844 Node* EffectControlLinearizer::LowerChangeFloat64ToTaggedPointer(Node* node) {
    845   Node* value = node->InputAt(0);
    846   return AllocateHeapNumberWithValue(value);
    847 }
    848 
    849 Node* EffectControlLinearizer::LowerChangeBitToTagged(Node* node) {
    850   Node* value = node->InputAt(0);
    851 
    852   auto if_true = __ MakeLabel<1>();
    853   auto done = __ MakeLabel<2>(MachineRepresentation::kTagged);
    854 
    855   __ GotoIf(value, &if_true);
    856   __ Goto(&done, __ FalseConstant());
    857 
    858   __ Bind(&if_true);
    859   __ Goto(&done, __ TrueConstant());
    860 
    861   __ Bind(&done);
    862   return done.PhiAt(0);
    863 }
    864 
    865 Node* EffectControlLinearizer::LowerChangeInt31ToTaggedSigned(Node* node) {
    866   Node* value = node->InputAt(0);
    867   return ChangeInt32ToSmi(value);
    868 }
    869 
    870 Node* EffectControlLinearizer::LowerChangeInt32ToTagged(Node* node) {
    871   Node* value = node->InputAt(0);
    872 
    873   if (machine()->Is64()) {
    874     return ChangeInt32ToSmi(value);
    875   }
    876 
    877   auto if_overflow = __ MakeDeferredLabel<1>();
    878   auto done = __ MakeLabel<2>(MachineRepresentation::kTagged);
    879 
    880   Node* add = __ Int32AddWithOverflow(value, value);
    881   Node* ovf = __ Projection(1, add);
    882   __ GotoIf(ovf, &if_overflow);
    883   __ Goto(&done, __ Projection(0, add));
    884 
    885   __ Bind(&if_overflow);
    886   Node* number = AllocateHeapNumberWithValue(__ ChangeInt32ToFloat64(value));
    887   __ Goto(&done, number);
    888 
    889   __ Bind(&done);
    890   return done.PhiAt(0);
    891 }
    892 
    893 Node* EffectControlLinearizer::LowerChangeUint32ToTagged(Node* node) {
    894   Node* value = node->InputAt(0);
    895 
    896   auto if_not_in_smi_range = __ MakeDeferredLabel<1>();
    897   auto done = __ MakeLabel<2>(MachineRepresentation::kTagged);
    898 
    899   Node* check = __ Uint32LessThanOrEqual(value, SmiMaxValueConstant());
    900   __ GotoUnless(check, &if_not_in_smi_range);
    901   __ Goto(&done, ChangeUint32ToSmi(value));
    902 
    903   __ Bind(&if_not_in_smi_range);
    904   Node* number = AllocateHeapNumberWithValue(__ ChangeUint32ToFloat64(value));
    905 
    906   __ Goto(&done, number);
    907   __ Bind(&done);
    908 
    909   return done.PhiAt(0);
    910 }
    911 
    912 Node* EffectControlLinearizer::LowerChangeTaggedSignedToInt32(Node* node) {
    913   Node* value = node->InputAt(0);
    914   return ChangeSmiToInt32(value);
    915 }
    916 
    917 Node* EffectControlLinearizer::LowerChangeTaggedToBit(Node* node) {
    918   Node* value = node->InputAt(0);
    919   return __ WordEqual(value, __ TrueConstant());
    920 }
    921 
    922 Node* EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node) {
    923   Node* value = node->InputAt(0);
    924 
    925   auto if_smi = __ MakeDeferredLabel<1>();
    926   auto if_heapnumber = __ MakeDeferredLabel<1>();
    927   auto done = __ MakeLabel<6>(MachineRepresentation::kBit);
    928 
    929   Node* zero = __ Int32Constant(0);
    930   Node* fzero = __ Float64Constant(0.0);
    931 
    932   // Check if {value} is false.
    933   __ GotoIf(__ WordEqual(value, __ FalseConstant()), &done, zero);
    934 
    935   // Check if {value} is a Smi.
    936   Node* check_smi = ObjectIsSmi(value);
    937   __ GotoIf(check_smi, &if_smi);
    938 
    939   // Check if {value} is the empty string.
    940   __ GotoIf(__ WordEqual(value, __ EmptyStringConstant()), &done, zero);
    941 
    942   // Load the map of {value}.
    943   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    944 
    945   // Check if the {value} is undetectable and immediately return false.
    946   Node* value_map_bitfield =
    947       __ LoadField(AccessBuilder::ForMapBitField(), value_map);
    948   __ GotoUnless(
    949       __ Word32Equal(__ Word32And(value_map_bitfield,
    950                                   __ Int32Constant(1 << Map::kIsUndetectable)),
    951                      zero),
    952       &done, zero);
    953 
    954   // Check if {value} is a HeapNumber.
    955   __ GotoIf(__ WordEqual(value_map, __ HeapNumberMapConstant()),
    956             &if_heapnumber);
    957 
    958   // All other values that reach here are true.
    959   __ Goto(&done, __ Int32Constant(1));
    960 
    961   __ Bind(&if_heapnumber);
    962   {
    963     // For HeapNumber {value}, just check that its value is not 0.0, -0.0 or
    964     // NaN.
    965     Node* value_value =
    966         __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
    967     __ Goto(&done, __ Float64LessThan(fzero, __ Float64Abs(value_value)));
    968   }
    969 
    970   __ Bind(&if_smi);
    971   {
    972     // If {value} is a Smi, then we only need to check that it's not zero.
    973     __ Goto(&done,
    974             __ Word32Equal(__ WordEqual(value, __ IntPtrConstant(0)), zero));
    975   }
    976 
    977   __ Bind(&done);
    978   return done.PhiAt(0);
    979 }
    980 
    981 Node* EffectControlLinearizer::LowerChangeTaggedToInt32(Node* node) {
    982   Node* value = node->InputAt(0);
    983 
    984   auto if_not_smi = __ MakeDeferredLabel<1>();
    985   auto done = __ MakeLabel<2>(MachineRepresentation::kWord32);
    986 
    987   Node* check = ObjectIsSmi(value);
    988   __ GotoUnless(check, &if_not_smi);
    989   __ Goto(&done, ChangeSmiToInt32(value));
    990 
    991   __ Bind(&if_not_smi);
    992   STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
    993   Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
    994   vfalse = __ ChangeFloat64ToInt32(vfalse);
    995   __ Goto(&done, vfalse);
    996 
    997   __ Bind(&done);
    998   return done.PhiAt(0);
    999 }
   1000 
   1001 Node* EffectControlLinearizer::LowerChangeTaggedToUint32(Node* node) {
   1002   Node* value = node->InputAt(0);
   1003 
   1004   auto if_not_smi = __ MakeDeferredLabel<1>();
   1005   auto done = __ MakeLabel<2>(MachineRepresentation::kWord32);
   1006 
   1007   Node* check = ObjectIsSmi(value);
   1008   __ GotoUnless(check, &if_not_smi);
   1009   __ Goto(&done, ChangeSmiToInt32(value));
   1010 
   1011   __ Bind(&if_not_smi);
   1012   STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
   1013   Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
   1014   vfalse = __ ChangeFloat64ToUint32(vfalse);
   1015   __ Goto(&done, vfalse);
   1016 
   1017   __ Bind(&done);
   1018   return done.PhiAt(0);
   1019 }
   1020 
   1021 Node* EffectControlLinearizer::LowerChangeTaggedToFloat64(Node* node) {
   1022   return LowerTruncateTaggedToFloat64(node);
   1023 }
   1024 
   1025 Node* EffectControlLinearizer::LowerChangeTaggedToTaggedSigned(Node* node) {
   1026   Node* value = node->InputAt(0);
   1027 
   1028   auto if_not_smi = __ MakeDeferredLabel<1>();
   1029   auto done = __ MakeLabel<2>(MachineRepresentation::kWord32);
   1030 
   1031   Node* check = ObjectIsSmi(value);
   1032   __ GotoUnless(check, &if_not_smi);
   1033   __ Goto(&done, value);
   1034 
   1035   __ Bind(&if_not_smi);
   1036   STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
   1037   Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
   1038   vfalse = __ ChangeFloat64ToInt32(vfalse);
   1039   vfalse = ChangeInt32ToSmi(vfalse);
   1040   __ Goto(&done, vfalse);
   1041 
   1042   __ Bind(&done);
   1043   return done.PhiAt(0);
   1044 }
   1045 
   1046 Node* EffectControlLinearizer::LowerTruncateTaggedToFloat64(Node* node) {
   1047   Node* value = node->InputAt(0);
   1048 
   1049   auto if_not_smi = __ MakeDeferredLabel<1>();
   1050   auto done = __ MakeLabel<2>(MachineRepresentation::kFloat64);
   1051 
   1052   Node* check = ObjectIsSmi(value);
   1053   __ GotoUnless(check, &if_not_smi);
   1054   Node* vtrue = ChangeSmiToInt32(value);
   1055   vtrue = __ ChangeInt32ToFloat64(vtrue);
   1056   __ Goto(&done, vtrue);
   1057 
   1058   __ Bind(&if_not_smi);
   1059   STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
   1060   Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
   1061   __ Goto(&done, vfalse);
   1062 
   1063   __ Bind(&done);
   1064   return done.PhiAt(0);
   1065 }
   1066 
   1067 Node* EffectControlLinearizer::LowerCheckBounds(Node* node, Node* frame_state) {
   1068   Node* index = node->InputAt(0);
   1069   Node* limit = node->InputAt(1);
   1070 
   1071   Node* check = __ Uint32LessThan(index, limit);
   1072   __ DeoptimizeUnless(DeoptimizeReason::kOutOfBounds, check, frame_state);
   1073   return index;
   1074 }
   1075 
   1076 Node* EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) {
   1077   CheckMapsParameters const& p = CheckMapsParametersOf(node->op());
   1078   Node* value = node->InputAt(0);
   1079 
   1080   ZoneHandleSet<Map> const& maps = p.maps();
   1081   size_t const map_count = maps.size();
   1082 
   1083   if (p.flags() & CheckMapsFlag::kTryMigrateInstance) {
   1084     auto done =
   1085         __ MakeLabelFor(GraphAssemblerLabelType::kNonDeferred, map_count * 2);
   1086     auto migrate = __ MakeDeferredLabel<1>();
   1087 
   1088     // Load the current map of the {value}.
   1089     Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
   1090 
   1091     // Perform the map checks.
   1092     for (size_t i = 0; i < map_count; ++i) {
   1093       Node* map = __ HeapConstant(maps[i]);
   1094       Node* check = __ WordEqual(value_map, map);
   1095       if (i == map_count - 1) {
   1096         __ GotoUnless(check, &migrate);
   1097         __ Goto(&done);
   1098       } else {
   1099         __ GotoIf(check, &done);
   1100       }
   1101     }
   1102 
   1103     // Perform the (deferred) instance migration.
   1104     __ Bind(&migrate);
   1105     {
   1106       // If map is not deprecated the migration attempt does not make sense.
   1107       Node* bitfield3 =
   1108           __ LoadField(AccessBuilder::ForMapBitField3(), value_map);
   1109       Node* if_not_deprecated = __ WordEqual(
   1110           __ Word32And(bitfield3, __ Int32Constant(Map::Deprecated::kMask)),
   1111           __ Int32Constant(0));
   1112       __ DeoptimizeIf(DeoptimizeReason::kWrongMap, if_not_deprecated,
   1113                       frame_state);
   1114 
   1115       Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
   1116       Runtime::FunctionId id = Runtime::kTryMigrateInstance;
   1117       CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor(
   1118           graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags);
   1119       Node* result =
   1120           __ Call(desc, __ CEntryStubConstant(1), value,
   1121                   __ ExternalConstant(ExternalReference(id, isolate())),
   1122                   __ Int32Constant(1), __ NoContextConstant());
   1123       Node* check = ObjectIsSmi(result);
   1124       __ DeoptimizeIf(DeoptimizeReason::kInstanceMigrationFailed, check,
   1125                       frame_state);
   1126     }
   1127 
   1128     // Reload the current map of the {value}.
   1129     value_map = __ LoadField(AccessBuilder::ForMap(), value);
   1130 
   1131     // Perform the map checks again.
   1132     for (size_t i = 0; i < map_count; ++i) {
   1133       Node* map = __ HeapConstant(maps[i]);
   1134       Node* check = __ WordEqual(value_map, map);
   1135       if (i == map_count - 1) {
   1136         __ DeoptimizeUnless(DeoptimizeReason::kWrongMap, check, frame_state);
   1137       } else {
   1138         __ GotoIf(check, &done);
   1139       }
   1140     }
   1141 
   1142     __ Goto(&done);
   1143     __ Bind(&done);
   1144   } else {
   1145     auto done =
   1146         __ MakeLabelFor(GraphAssemblerLabelType::kNonDeferred, map_count);
   1147 
   1148     // Load the current map of the {value}.
   1149     Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
   1150 
   1151     for (size_t i = 0; i < map_count; ++i) {
   1152       Node* map = __ HeapConstant(maps[i]);
   1153       Node* check = __ WordEqual(value_map, map);
   1154       if (i == map_count - 1) {
   1155         __ DeoptimizeUnless(DeoptimizeReason::kWrongMap, check, frame_state);
   1156       } else {
   1157         __ GotoIf(check, &done);
   1158       }
   1159     }
   1160     __ Goto(&done);
   1161     __ Bind(&done);
   1162   }
   1163   return value;
   1164 }
   1165 
   1166 Node* EffectControlLinearizer::LowerCheckNumber(Node* node, Node* frame_state) {
   1167   Node* value = node->InputAt(0);
   1168 
   1169   auto if_not_smi = __ MakeDeferredLabel<1>();
   1170   auto done = __ MakeLabel<2>();
   1171 
   1172   Node* check0 = ObjectIsSmi(value);
   1173   __ GotoUnless(check0, &if_not_smi);
   1174   __ Goto(&done);
   1175 
   1176   __ Bind(&if_not_smi);
   1177   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
   1178   Node* check1 = __ WordEqual(value_map, __ HeapNumberMapConstant());
   1179   __ DeoptimizeUnless(DeoptimizeReason::kNotAHeapNumber, check1, frame_state);
   1180   __ Goto(&done);
   1181 
   1182   __ Bind(&done);
   1183   return value;
   1184 }
   1185 
   1186 Node* EffectControlLinearizer::LowerCheckReceiver(Node* node,
   1187                                                   Node* frame_state) {
   1188   Node* value = node->InputAt(0);
   1189 
   1190   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
   1191   Node* value_instance_type =
   1192       __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
   1193 
   1194   STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
   1195   Node* check = __ Uint32LessThanOrEqual(
   1196       __ Uint32Constant(FIRST_JS_RECEIVER_TYPE), value_instance_type);
   1197   __ DeoptimizeUnless(DeoptimizeReason::kNotAJavaScriptObject, check,
   1198                       frame_state);
   1199   return value;
   1200 }
   1201 
   1202 Node* EffectControlLinearizer::LowerCheckString(Node* node, Node* frame_state) {
   1203   Node* value = node->InputAt(0);
   1204 
   1205   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
   1206   Node* value_instance_type =
   1207       __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
   1208 
   1209   Node* check = __ Uint32LessThan(value_instance_type,
   1210                                   __ Uint32Constant(FIRST_NONSTRING_TYPE));
   1211   __ DeoptimizeUnless(DeoptimizeReason::kWrongInstanceType, check, frame_state);
   1212   return value;
   1213 }
   1214 
   1215 Node* EffectControlLinearizer::LowerCheckInternalizedString(Node* node,
   1216                                                             Node* frame_state) {
   1217   Node* value = node->InputAt(0);
   1218 
   1219   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
   1220   Node* value_instance_type =
   1221       __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
   1222 
   1223   Node* check = __ Word32Equal(
   1224       __ Word32And(value_instance_type,
   1225                    __ Int32Constant(kIsNotStringMask | kIsNotInternalizedMask)),
   1226       __ Int32Constant(kInternalizedTag));
   1227   __ DeoptimizeUnless(DeoptimizeReason::kWrongInstanceType, check, frame_state);
   1228 
   1229   return value;
   1230 }
   1231 
   1232 Node* EffectControlLinearizer::LowerCheckIf(Node* node, Node* frame_state) {
   1233   Node* value = node->InputAt(0);
   1234   __ DeoptimizeUnless(DeoptimizeKind::kEager, DeoptimizeReason::kNoReason,
   1235                       value, frame_state);
   1236   return value;
   1237 }
   1238 
   1239 Node* EffectControlLinearizer::LowerCheckedInt32Add(Node* node,
   1240                                                     Node* frame_state) {
   1241   Node* lhs = node->InputAt(0);
   1242   Node* rhs = node->InputAt(1);
   1243 
   1244   Node* value = __ Int32AddWithOverflow(lhs, rhs);
   1245   Node* check = __ Projection(1, value);
   1246   __ DeoptimizeIf(DeoptimizeReason::kOverflow, check, frame_state);
   1247   return __ Projection(0, value);
   1248 }
   1249 
   1250 Node* EffectControlLinearizer::LowerCheckedInt32Sub(Node* node,
   1251                                                     Node* frame_state) {
   1252   Node* lhs = node->InputAt(0);
   1253   Node* rhs = node->InputAt(1);
   1254 
   1255   Node* value = __ Int32SubWithOverflow(lhs, rhs);
   1256   Node* check = __ Projection(1, value);
   1257   __ DeoptimizeIf(DeoptimizeReason::kOverflow, check, frame_state);
   1258   return __ Projection(0, value);
   1259 }
   1260 
   1261 Node* EffectControlLinearizer::LowerCheckedInt32Div(Node* node,
   1262                                                     Node* frame_state) {
   1263   Node* lhs = node->InputAt(0);
   1264   Node* rhs = node->InputAt(1);
   1265 
   1266   auto if_not_positive = __ MakeDeferredLabel<1>();
   1267   auto if_is_minint = __ MakeDeferredLabel<1>();
   1268   auto done = __ MakeLabel<2>(MachineRepresentation::kWord32);
   1269   auto minint_check_done = __ MakeLabel<2>();
   1270 
   1271   Node* zero = __ Int32Constant(0);
   1272 
   1273   // Check if {rhs} is positive (and not zero).
   1274   Node* check0 = __ Int32LessThan(zero, rhs);
   1275   __ GotoUnless(check0, &if_not_positive);
   1276 
   1277   // Fast case, no additional checking required.
   1278   __ Goto(&done, __ Int32Div(lhs, rhs));
   1279 
   1280   {
   1281     __ Bind(&if_not_positive);
   1282 
   1283     // Check if {rhs} is zero.
   1284     Node* check = __ Word32Equal(rhs, zero);
   1285     __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, check, frame_state);
   1286 
   1287     // Check if {lhs} is zero, as that would produce minus zero.
   1288     check = __ Word32Equal(lhs, zero);
   1289     __ DeoptimizeIf(DeoptimizeReason::kMinusZero, check, frame_state);
   1290 
   1291     // Check if {lhs} is kMinInt and {rhs} is -1, in which case we'd have
   1292     // to return -kMinInt, which is not representable.
   1293     Node* minint = __ Int32Constant(std::numeric_limits<int32_t>::min());
   1294     Node* check1 = graph()->NewNode(machine()->Word32Equal(), lhs, minint);
   1295     __ GotoIf(check1, &if_is_minint);
   1296     __ Goto(&minint_check_done);
   1297 
   1298     __ Bind(&if_is_minint);
   1299     // Check if {rhs} is -1.
   1300     Node* minusone = __ Int32Constant(-1);
   1301     Node* is_minus_one = __ Word32Equal(rhs, minusone);
   1302     __ DeoptimizeIf(DeoptimizeReason::kOverflow, is_minus_one, frame_state);
   1303     __ Goto(&minint_check_done);
   1304 
   1305     __ Bind(&minint_check_done);
   1306     // Perform the actual integer division.
   1307     __ Goto(&done, __ Int32Div(lhs, rhs));
   1308   }
   1309 
   1310   __ Bind(&done);
   1311   Node* value = done.PhiAt(0);
   1312 
   1313   // Check if the remainder is non-zero.
   1314   Node* check = __ Word32Equal(lhs, __ Int32Mul(rhs, value));
   1315   __ DeoptimizeUnless(DeoptimizeReason::kLostPrecision, check, frame_state);
   1316 
   1317   return value;
   1318 }
   1319 
   1320 Node* EffectControlLinearizer::LowerCheckedInt32Mod(Node* node,
   1321                                                     Node* frame_state) {
   1322   // General case for signed integer modulus, with optimization for (unknown)
   1323   // power of 2 right hand side.
   1324   //
   1325   //   if rhs <= 0 then
   1326   //     rhs = -rhs
   1327   //     deopt if rhs == 0
   1328   //   if lhs < 0 then
   1329   //     let res = lhs % rhs in
   1330   //     deopt if res == 0
   1331   //     res
   1332   //   else
   1333   //     let msk = rhs - 1 in
   1334   //     if rhs & msk == 0 then
   1335   //       lhs & msk
   1336   //     else
   1337   //       lhs % rhs
   1338   //
   1339   Node* lhs = node->InputAt(0);
   1340   Node* rhs = node->InputAt(1);
   1341 
   1342   auto if_rhs_not_positive = __ MakeDeferredLabel<1>();
   1343   auto if_lhs_negative = __ MakeDeferredLabel<1>();
   1344   auto if_power_of_two = __ MakeLabel<1>();
   1345   auto rhs_checked = __ MakeLabel<2>(MachineRepresentation::kWord32);
   1346   auto done = __ MakeLabel<3>(MachineRepresentation::kWord32);
   1347 
   1348   Node* zero = __ Int32Constant(0);
   1349 
   1350   // Check if {rhs} is not strictly positive.
   1351   Node* check0 = __ Int32LessThanOrEqual(rhs, zero);
   1352   __ GotoIf(check0, &if_rhs_not_positive);
   1353   __ Goto(&rhs_checked, rhs);
   1354 
   1355   __ Bind(&if_rhs_not_positive);
   1356   {
   1357     // Negate {rhs}, might still produce a negative result in case of
   1358     // -2^31, but that is handled safely below.
   1359     Node* vtrue0 = __ Int32Sub(zero, rhs);
   1360 
   1361     // Ensure that {rhs} is not zero, otherwise we'd have to return NaN.
   1362     Node* check = __ Word32Equal(vtrue0, zero);
   1363     __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, check, frame_state);
   1364     __ Goto(&rhs_checked, vtrue0);
   1365   }
   1366 
   1367   __ Bind(&rhs_checked);
   1368   rhs = rhs_checked.PhiAt(0);
   1369 
   1370   // Check if {lhs} is negative.
   1371   Node* check1 = __ Int32LessThan(lhs, zero);
   1372   __ GotoIf(check1, &if_lhs_negative);
   1373 
   1374   // {lhs} non-negative.
   1375   {
   1376     Node* one = __ Int32Constant(1);
   1377     Node* msk = __ Int32Sub(rhs, one);
   1378 
   1379     // Check if {rhs} minus one is a valid mask.
   1380     Node* check2 = __ Word32Equal(__ Word32And(rhs, msk), zero);
   1381     __ GotoIf(check2, &if_power_of_two);
   1382     // Compute the remainder using the generic {lhs % rhs}.
   1383     __ Goto(&done, __ Int32Mod(lhs, rhs));
   1384 
   1385     __ Bind(&if_power_of_two);
   1386     // Compute the remainder using {lhs & msk}.
   1387     __ Goto(&done, __ Word32And(lhs, msk));
   1388   }
   1389 
   1390   __ Bind(&if_lhs_negative);
   1391   {
   1392     // Compute the remainder using {lhs % msk}.
   1393     Node* vtrue1 = __ Int32Mod(lhs, rhs);
   1394 
   1395     // Check if we would have to return -0.
   1396     Node* check = __ Word32Equal(vtrue1, zero);
   1397     __ DeoptimizeIf(DeoptimizeReason::kMinusZero, check, frame_state);
   1398     __ Goto(&done, vtrue1);
   1399   }
   1400 
   1401   __ Bind(&done);
   1402   return done.PhiAt(0);
   1403 }
   1404 
   1405 Node* EffectControlLinearizer::LowerCheckedUint32Div(Node* node,
   1406                                                      Node* frame_state) {
   1407   Node* lhs = node->InputAt(0);
   1408   Node* rhs = node->InputAt(1);
   1409 
   1410   Node* zero = __ Int32Constant(0);
   1411 
   1412   // Ensure that {rhs} is not zero, otherwise we'd have to return NaN.
   1413   Node* check = __ Word32Equal(rhs, zero);
   1414   __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, check, frame_state);
   1415 
   1416   // Perform the actual unsigned integer division.
   1417   Node* value = __ Uint32Div(lhs, rhs);
   1418 
   1419   // Check if the remainder is non-zero.
   1420   check = __ Word32Equal(lhs, __ Int32Mul(rhs, value));
   1421   __ DeoptimizeUnless(DeoptimizeReason::kLostPrecision, check, frame_state);
   1422   return value;
   1423 }
   1424 
   1425 Node* EffectControlLinearizer::LowerCheckedUint32Mod(Node* node,
   1426                                                      Node* frame_state) {
   1427   Node* lhs = node->InputAt(0);
   1428   Node* rhs = node->InputAt(1);
   1429 
   1430   Node* zero = __ Int32Constant(0);
   1431 
   1432   // Ensure that {rhs} is not zero, otherwise we'd have to return NaN.
   1433   Node* check = __ Word32Equal(rhs, zero);
   1434   __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, check, frame_state);
   1435 
   1436   // Perform the actual unsigned integer modulus.
   1437   return __ Uint32Mod(lhs, rhs);
   1438 }
   1439 
   1440 Node* EffectControlLinearizer::LowerCheckedInt32Mul(Node* node,
   1441                                                     Node* frame_state) {
   1442   CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op());
   1443   Node* lhs = node->InputAt(0);
   1444   Node* rhs = node->InputAt(1);
   1445 
   1446   Node* projection = __ Int32MulWithOverflow(lhs, rhs);
   1447   Node* check = __ Projection(1, projection);
   1448   __ DeoptimizeIf(DeoptimizeReason::kOverflow, check, frame_state);
   1449 
   1450   Node* value = __ Projection(0, projection);
   1451 
   1452   if (mode == CheckForMinusZeroMode::kCheckForMinusZero) {
   1453     auto if_zero = __ MakeDeferredLabel<1>();
   1454     auto check_done = __ MakeLabel<2>();
   1455     Node* zero = __ Int32Constant(0);
   1456     Node* check_zero = __ Word32Equal(value, zero);
   1457     __ GotoIf(check_zero, &if_zero);
   1458     __ Goto(&check_done);
   1459 
   1460     __ Bind(&if_zero);
   1461     // We may need to return negative zero.
   1462     Node* check_or = __ Int32LessThan(__ Word32Or(lhs, rhs), zero);
   1463     __ DeoptimizeIf(DeoptimizeReason::kMinusZero, check_or, frame_state);
   1464     __ Goto(&check_done);
   1465 
   1466     __ Bind(&check_done);
   1467   }
   1468 
   1469   return value;
   1470 }
   1471 
   1472 Node* EffectControlLinearizer::LowerCheckedInt32ToTaggedSigned(
   1473     Node* node, Node* frame_state) {
   1474   DCHECK(SmiValuesAre31Bits());
   1475   Node* value = node->InputAt(0);
   1476 
   1477   Node* add = __ Int32AddWithOverflow(value, value);
   1478   Node* check = __ Projection(1, add);
   1479   __ DeoptimizeIf(DeoptimizeReason::kOverflow, check, frame_state);
   1480   return __ Projection(0, add);
   1481 }
   1482 
   1483 Node* EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node,
   1484                                                          Node* frame_state) {
   1485   Node* value = node->InputAt(0);
   1486   Node* max_int = __ Int32Constant(std::numeric_limits<int32_t>::max());
   1487   Node* is_safe = __ Uint32LessThanOrEqual(value, max_int);
   1488   __ DeoptimizeUnless(DeoptimizeReason::kLostPrecision, is_safe, frame_state);
   1489   return value;
   1490 }
   1491 
   1492 Node* EffectControlLinearizer::LowerCheckedUint32ToTaggedSigned(
   1493     Node* node, Node* frame_state) {
   1494   Node* value = node->InputAt(0);
   1495   Node* check = __ Uint32LessThanOrEqual(value, SmiMaxValueConstant());
   1496   __ DeoptimizeUnless(DeoptimizeReason::kLostPrecision, check, frame_state);
   1497   return ChangeUint32ToSmi(value);
   1498 }
   1499 
   1500 Node* EffectControlLinearizer::BuildCheckedFloat64ToInt32(
   1501     CheckForMinusZeroMode mode, Node* value, Node* frame_state) {
   1502   Node* value32 = __ RoundFloat64ToInt32(value);
   1503   Node* check_same = __ Float64Equal(value, __ ChangeInt32ToFloat64(value32));
   1504   __ DeoptimizeUnless(DeoptimizeReason::kLostPrecisionOrNaN, check_same,
   1505                       frame_state);
   1506 
   1507   if (mode == CheckForMinusZeroMode::kCheckForMinusZero) {
   1508     // Check if {value} is -0.
   1509     auto if_zero = __ MakeDeferredLabel<1>();
   1510     auto check_done = __ MakeLabel<2>();
   1511 
   1512     Node* check_zero = __ Word32Equal(value32, __ Int32Constant(0));
   1513     __ GotoIf(check_zero, &if_zero);
   1514     __ Goto(&check_done);
   1515 
   1516     __ Bind(&if_zero);
   1517     // In case of 0, we need to check the high bits for the IEEE -0 pattern.
   1518     Node* check_negative = __ Int32LessThan(__ Float64ExtractHighWord32(value),
   1519                                             __ Int32Constant(0));
   1520     __ DeoptimizeIf(DeoptimizeReason::kMinusZero, check_negative, frame_state);
   1521     __ Goto(&check_done);
   1522 
   1523     __ Bind(&check_done);
   1524   }
   1525   return value32;
   1526 }
   1527 
   1528 Node* EffectControlLinearizer::LowerCheckedFloat64ToInt32(Node* node,
   1529                                                           Node* frame_state) {
   1530   CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op());
   1531   Node* value = node->InputAt(0);
   1532   return BuildCheckedFloat64ToInt32(mode, value, frame_state);
   1533 }
   1534 
   1535 Node* EffectControlLinearizer::LowerCheckedTaggedSignedToInt32(
   1536     Node* node, Node* frame_state) {
   1537   Node* value = node->InputAt(0);
   1538   Node* check = ObjectIsSmi(value);
   1539   __ DeoptimizeUnless(DeoptimizeReason::kNotASmi, check, frame_state);
   1540   return ChangeSmiToInt32(value);
   1541 }
   1542 
   1543 Node* EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node,
   1544                                                          Node* frame_state) {
   1545   CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op());
   1546   Node* value = node->InputAt(0);
   1547 
   1548   auto if_not_smi = __ MakeDeferredLabel<1>();
   1549   auto done = __ MakeLabel<2>(MachineRepresentation::kWord32);
   1550 
   1551   Node* check = ObjectIsSmi(value);
   1552   __ GotoUnless(check, &if_not_smi);
   1553   // In the Smi case, just convert to int32.
   1554   __ Goto(&done, ChangeSmiToInt32(value));
   1555 
   1556   // In the non-Smi case, check the heap numberness, load the number and convert
   1557   // to int32.
   1558   __ Bind(&if_not_smi);
   1559   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
   1560   Node* check_map = __ WordEqual(value_map, __ HeapNumberMapConstant());
   1561   __ DeoptimizeUnless(DeoptimizeReason::kNotAHeapNumber, check_map,
   1562                       frame_state);
   1563   Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
   1564   vfalse = BuildCheckedFloat64ToInt32(mode, vfalse, frame_state);
   1565   __ Goto(&done, vfalse);
   1566 
   1567   __ Bind(&done);
   1568   return done.PhiAt(0);
   1569 }
   1570 
   1571 Node* EffectControlLinearizer::BuildCheckedHeapNumberOrOddballToFloat64(
   1572     CheckTaggedInputMode mode, Node* value, Node* frame_state) {
   1573   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
   1574   Node* check_number = __ WordEqual(value_map, __ HeapNumberMapConstant());
   1575   switch (mode) {
   1576     case CheckTaggedInputMode::kNumber: {
   1577       __ DeoptimizeUnless(DeoptimizeReason::kNotAHeapNumber, check_number,
   1578                           frame_state);
   1579       break;
   1580     }
   1581     case CheckTaggedInputMode::kNumberOrOddball: {
   1582       auto check_done = __ MakeLabel<2>();
   1583 
   1584       __ GotoIf(check_number, &check_done);
   1585       // For oddballs also contain the numeric value, let us just check that
   1586       // we have an oddball here.
   1587       Node* instance_type =
   1588           __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
   1589       Node* check_oddball =
   1590           __ Word32Equal(instance_type, __ Int32Constant(ODDBALL_TYPE));
   1591       __ DeoptimizeUnless(DeoptimizeReason::kNotANumberOrOddball, check_oddball,
   1592                           frame_state);
   1593       STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
   1594       __ Goto(&check_done);
   1595 
   1596       __ Bind(&check_done);
   1597       break;
   1598     }
   1599   }
   1600   return __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
   1601 }
   1602 
   1603 Node* EffectControlLinearizer::LowerCheckedTaggedToFloat64(Node* node,
   1604                                                            Node* frame_state) {
   1605   CheckTaggedInputMode mode = CheckTaggedInputModeOf(node->op());
   1606   Node* value = node->InputAt(0);
   1607 
   1608   auto if_smi = __ MakeLabel<1>();
   1609   auto done = __ MakeLabel<2>(MachineRepresentation::kFloat64);
   1610 
   1611   Node* check = ObjectIsSmi(value);
   1612   __ GotoIf(check, &if_smi);
   1613 
   1614   // In the Smi case, just convert to int32 and then float64.
   1615   // Otherwise, check heap numberness and load the number.
   1616   Node* number =
   1617       BuildCheckedHeapNumberOrOddballToFloat64(mode, value, frame_state);
   1618   __ Goto(&done, number);
   1619 
   1620   __ Bind(&if_smi);
   1621   Node* from_smi = ChangeSmiToInt32(value);
   1622   from_smi = __ ChangeInt32ToFloat64(from_smi);
   1623   __ Goto(&done, from_smi);
   1624 
   1625   __ Bind(&done);
   1626   return done.PhiAt(0);
   1627 }
   1628 
   1629 Node* EffectControlLinearizer::LowerCheckedTaggedToTaggedSigned(
   1630     Node* node, Node* frame_state) {
   1631   Node* value = node->InputAt(0);
   1632 
   1633   Node* check = ObjectIsSmi(value);
   1634   __ DeoptimizeUnless(DeoptimizeReason::kNotASmi, check, frame_state);
   1635 
   1636   return value;
   1637 }
   1638 
   1639 Node* EffectControlLinearizer::LowerCheckedTaggedToTaggedPointer(
   1640     Node* node, Node* frame_state) {
   1641   Node* value = node->InputAt(0);
   1642 
   1643   Node* check = ObjectIsSmi(value);
   1644   __ DeoptimizeIf(DeoptimizeReason::kSmi, check, frame_state);
   1645   return value;
   1646 }
   1647 
   1648 Node* EffectControlLinearizer::LowerTruncateTaggedToWord32(Node* node) {
   1649   Node* value = node->InputAt(0);
   1650 
   1651   auto if_not_smi = __ MakeDeferredLabel<1>();
   1652   auto done = __ MakeLabel<2>(MachineRepresentation::kWord32);
   1653 
   1654   Node* check = ObjectIsSmi(value);
   1655   __ GotoUnless(check, &if_not_smi);
   1656   __ Goto(&done, ChangeSmiToInt32(value));
   1657 
   1658   __ Bind(&if_not_smi);
   1659   STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
   1660   Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
   1661   vfalse = __ TruncateFloat64ToWord32(vfalse);
   1662   __ Goto(&done, vfalse);
   1663 
   1664   __ Bind(&done);
   1665   return done.PhiAt(0);
   1666 }
   1667 
   1668 Node* EffectControlLinearizer::LowerCheckedTruncateTaggedToWord32(
   1669     Node* node, Node* frame_state) {
   1670   Node* value = node->InputAt(0);
   1671 
   1672   auto if_not_smi = __ MakeLabel<1>();
   1673   auto done = __ MakeLabel<2>(MachineRepresentation::kWord32);
   1674 
   1675   Node* check = ObjectIsSmi(value);
   1676   __ GotoUnless(check, &if_not_smi);
   1677   // In the Smi case, just convert to int32.
   1678   __ Goto(&done, ChangeSmiToInt32(value));
   1679 
   1680   // Otherwise, check that it's a heap number or oddball and truncate the value
   1681   // to int32.
   1682   __ Bind(&if_not_smi);
   1683   Node* number = BuildCheckedHeapNumberOrOddballToFloat64(
   1684       CheckTaggedInputMode::kNumberOrOddball, value, frame_state);
   1685   number = __ TruncateFloat64ToWord32(number);
   1686   __ Goto(&done, number);
   1687 
   1688   __ Bind(&done);
   1689   return done.PhiAt(0);
   1690 }
   1691 
   1692 Node* EffectControlLinearizer::LowerObjectIsDetectableCallable(Node* node) {
   1693   Node* value = node->InputAt(0);
   1694 
   1695   auto if_smi = __ MakeDeferredLabel<1>();
   1696   auto done = __ MakeLabel<2>(MachineRepresentation::kBit);
   1697 
   1698   Node* check = ObjectIsSmi(value);
   1699   __ GotoIf(check, &if_smi);
   1700 
   1701   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
   1702   Node* value_bit_field =
   1703       __ LoadField(AccessBuilder::ForMapBitField(), value_map);
   1704   Node* vfalse = __ Word32Equal(
   1705       __ Int32Constant(1 << Map::kIsCallable),
   1706       __ Word32And(value_bit_field,
   1707                    __ Int32Constant((1 << Map::kIsCallable) |
   1708                                     (1 << Map::kIsUndetectable))));
   1709   __ Goto(&done, vfalse);
   1710 
   1711   __ Bind(&if_smi);
   1712   __ Goto(&done, __ Int32Constant(0));
   1713 
   1714   __ Bind(&done);
   1715   return done.PhiAt(0);
   1716 }
   1717 
   1718 Node* EffectControlLinearizer::LowerObjectIsNonCallable(Node* node) {
   1719   Node* value = node->InputAt(0);
   1720 
   1721   auto if_primitive = __ MakeDeferredLabel<2>();
   1722   auto done = __ MakeLabel<2>(MachineRepresentation::kBit);
   1723 
   1724   Node* check0 = ObjectIsSmi(value);
   1725   __ GotoIf(check0, &if_primitive);
   1726 
   1727   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
   1728   Node* value_instance_type =
   1729       __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
   1730   STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
   1731   Node* check1 = __ Uint32LessThanOrEqual(
   1732       __ Uint32Constant(FIRST_JS_RECEIVER_TYPE), value_instance_type);
   1733   __ GotoUnless(check1, &if_primitive);
   1734 
   1735   Node* value_bit_field =
   1736       __ LoadField(AccessBuilder::ForMapBitField(), value_map);
   1737   Node* check2 = __ Word32Equal(
   1738       __ Int32Constant(0),
   1739       __ Word32And(value_bit_field, __ Int32Constant(1 << Map::kIsCallable)));
   1740   __ Goto(&done, check2);
   1741 
   1742   __ Bind(&if_primitive);
   1743   __ Goto(&done, __ Int32Constant(0));
   1744 
   1745   __ Bind(&done);
   1746   return done.PhiAt(0);
   1747 }
   1748 
   1749 Node* EffectControlLinearizer::LowerObjectIsNumber(Node* node) {
   1750   Node* value = node->InputAt(0);
   1751 
   1752   auto if_smi = __ MakeLabel<1>();
   1753   auto done = __ MakeLabel<2>(MachineRepresentation::kBit);
   1754 
   1755   __ GotoIf(ObjectIsSmi(value), &if_smi);
   1756   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
   1757   __ Goto(&done, __ WordEqual(value_map, __ HeapNumberMapConstant()));
   1758 
   1759   __ Bind(&if_smi);
   1760   __ Goto(&done, __ Int32Constant(1));
   1761 
   1762   __ Bind(&done);
   1763   return done.PhiAt(0);
   1764 }
   1765 
   1766 Node* EffectControlLinearizer::LowerObjectIsReceiver(Node* node) {
   1767   Node* value = node->InputAt(0);
   1768 
   1769   auto if_smi = __ MakeDeferredLabel<1>();
   1770   auto done = __ MakeLabel<2>(MachineRepresentation::kBit);
   1771 
   1772   __ GotoIf(ObjectIsSmi(value), &if_smi);
   1773 
   1774   STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
   1775   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
   1776   Node* value_instance_type =
   1777       __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
   1778   Node* result = __ Uint32LessThanOrEqual(
   1779       __ Uint32Constant(FIRST_JS_RECEIVER_TYPE), value_instance_type);
   1780   __ Goto(&done, result);
   1781 
   1782   __ Bind(&if_smi);
   1783   __ Goto(&done, __ Int32Constant(0));
   1784 
   1785   __ Bind(&done);
   1786   return done.PhiAt(0);
   1787 }
   1788 
   1789 Node* EffectControlLinearizer::LowerObjectIsSmi(Node* node) {
   1790   Node* value = node->InputAt(0);
   1791   return ObjectIsSmi(value);
   1792 }
   1793 
   1794 Node* EffectControlLinearizer::LowerObjectIsString(Node* node) {
   1795   Node* value = node->InputAt(0);
   1796 
   1797   auto if_smi = __ MakeDeferredLabel<1>();
   1798   auto done = __ MakeLabel<2>(MachineRepresentation::kBit);
   1799 
   1800   Node* check = ObjectIsSmi(value);
   1801   __ GotoIf(check, &if_smi);
   1802   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
   1803   Node* value_instance_type =
   1804       __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
   1805   Node* vfalse = __ Uint32LessThan(value_instance_type,
   1806                                    __ Uint32Constant(FIRST_NONSTRING_TYPE));
   1807   __ Goto(&done, vfalse);
   1808 
   1809   __ Bind(&if_smi);
   1810   __ Goto(&done, __ Int32Constant(0));
   1811 
   1812   __ Bind(&done);
   1813   return done.PhiAt(0);
   1814 }
   1815 
   1816 Node* EffectControlLinearizer::LowerObjectIsUndetectable(Node* node) {
   1817   Node* value = node->InputAt(0);
   1818 
   1819   auto if_smi = __ MakeDeferredLabel<1>();
   1820   auto done = __ MakeLabel<2>(MachineRepresentation::kBit);
   1821 
   1822   Node* check = ObjectIsSmi(value);
   1823   __ GotoIf(check, &if_smi);
   1824 
   1825   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
   1826   Node* value_bit_field =
   1827       __ LoadField(AccessBuilder::ForMapBitField(), value_map);
   1828   Node* vfalse = __ Word32Equal(
   1829       __ Word32Equal(__ Int32Constant(0),
   1830                      __ Word32And(value_bit_field,
   1831                                   __ Int32Constant(1 << Map::kIsUndetectable))),
   1832       __ Int32Constant(0));
   1833   __ Goto(&done, vfalse);
   1834 
   1835   __ Bind(&if_smi);
   1836   __ Goto(&done, __ Int32Constant(0));
   1837 
   1838   __ Bind(&done);
   1839   return done.PhiAt(0);
   1840 }
   1841 
   1842 Node* EffectControlLinearizer::LowerNewRestParameterElements(Node* node) {
   1843   int const formal_parameter_count = ParameterCountOf(node->op());
   1844 
   1845   Callable const callable = CodeFactory::NewRestParameterElements(isolate());
   1846   Operator::Properties const properties = node->op()->properties();
   1847   CallDescriptor::Flags const flags = CallDescriptor::kNoFlags;
   1848   CallDescriptor* desc = Linkage::GetStubCallDescriptor(
   1849       isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties);
   1850   return __ Call(desc, __ HeapConstant(callable.code()),
   1851                  __ IntPtrConstant(formal_parameter_count),
   1852                  __ NoContextConstant());
   1853 }
   1854 
   1855 Node* EffectControlLinearizer::LowerNewUnmappedArgumentsElements(Node* node) {
   1856   int const formal_parameter_count = ParameterCountOf(node->op());
   1857 
   1858   Callable const callable =
   1859       CodeFactory::NewUnmappedArgumentsElements(isolate());
   1860   Operator::Properties const properties = node->op()->properties();
   1861   CallDescriptor::Flags const flags = CallDescriptor::kNoFlags;
   1862   CallDescriptor* desc = Linkage::GetStubCallDescriptor(
   1863       isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties);
   1864   return __ Call(desc, __ HeapConstant(callable.code()),
   1865                  __ IntPtrConstant(formal_parameter_count),
   1866                  __ NoContextConstant());
   1867 }
   1868 
   1869 Node* EffectControlLinearizer::LowerArrayBufferWasNeutered(Node* node) {
   1870   Node* value = node->InputAt(0);
   1871 
   1872   Node* value_bit_field =
   1873       __ LoadField(AccessBuilder::ForJSArrayBufferBitField(), value);
   1874   return __ Word32Equal(
   1875       __ Word32Equal(
   1876           __ Word32And(value_bit_field,
   1877                        __ Int32Constant(JSArrayBuffer::WasNeutered::kMask)),
   1878           __ Int32Constant(0)),
   1879       __ Int32Constant(0));
   1880 }
   1881 
   1882 Node* EffectControlLinearizer::LowerStringCharAt(Node* node) {
   1883   Node* receiver = node->InputAt(0);
   1884   Node* position = node->InputAt(1);
   1885 
   1886   Callable const callable = CodeFactory::StringCharAt(isolate());
   1887   Operator::Properties properties = Operator::kNoThrow | Operator::kNoWrite;
   1888   CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
   1889   CallDescriptor* desc = Linkage::GetStubCallDescriptor(
   1890       isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties);
   1891   return __ Call(desc, __ HeapConstant(callable.code()), receiver, position,
   1892                  __ NoContextConstant());
   1893 }
   1894 
   1895 Node* EffectControlLinearizer::LowerStringCharCodeAt(Node* node) {
   1896   Node* receiver = node->InputAt(0);
   1897   Node* position = node->InputAt(1);
   1898 
   1899   Callable const callable = CodeFactory::StringCharCodeAt(isolate());
   1900   Operator::Properties properties = Operator::kNoThrow | Operator::kNoWrite;
   1901   CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
   1902   CallDescriptor* desc = Linkage::GetStubCallDescriptor(
   1903       isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties,
   1904       MachineType::TaggedSigned());
   1905   return __ Call(desc, __ HeapConstant(callable.code()), receiver, position,
   1906                  __ NoContextConstant());
   1907 }
   1908 
   1909 Node* EffectControlLinearizer::LowerStringFromCharCode(Node* node) {
   1910   Node* value = node->InputAt(0);
   1911 
   1912   auto runtime_call = __ MakeDeferredLabel<2>();
   1913   auto if_undefined = __ MakeDeferredLabel<1>();
   1914   auto done = __ MakeLabel<2>(MachineRepresentation::kTagged);
   1915 
   1916   // Compute the character code.
   1917   Node* code = __ Word32And(value, __ Int32Constant(String::kMaxUtf16CodeUnit));
   1918 
   1919   // Check if the {code} is a one-byte char code.
   1920   Node* check0 = __ Int32LessThanOrEqual(
   1921       code, __ Int32Constant(String::kMaxOneByteCharCode));
   1922   __ GotoUnless(check0, &runtime_call);
   1923 
   1924   // Load the isolate wide single character string cache.
   1925   Node* cache = __ HeapConstant(factory()->single_character_string_cache());
   1926 
   1927   // Compute the {cache} index for {code}.
   1928   Node* index = machine()->Is32() ? code : __ ChangeUint32ToUint64(code);
   1929 
   1930   // Check if we have an entry for the {code} in the single character string
   1931   // cache already.
   1932   Node* entry =
   1933       __ LoadElement(AccessBuilder::ForFixedArrayElement(), cache, index);
   1934 
   1935   Node* check1 = __ WordEqual(entry, __ UndefinedConstant());
   1936   __ GotoIf(check1, &runtime_call);
   1937   __ Goto(&done, entry);
   1938 
   1939   // Let %StringFromCharCode handle this case.
   1940   // TODO(turbofan): At some point we may consider adding a stub for this
   1941   // deferred case, so that we don't need to call to C++ here.
   1942   __ Bind(&runtime_call);
   1943   {
   1944     Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
   1945     Runtime::FunctionId id = Runtime::kStringCharFromCode;
   1946     CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor(
   1947         graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags);
   1948     Node* vtrue1 =
   1949         __ Call(desc, __ CEntryStubConstant(1), ChangeInt32ToSmi(code),
   1950                 __ ExternalConstant(ExternalReference(id, isolate())),
   1951                 __ Int32Constant(1), __ NoContextConstant());
   1952     __ Goto(&done, vtrue1);
   1953   }
   1954   __ Bind(&done);
   1955   return done.PhiAt(0);
   1956 }
   1957 
   1958 Node* EffectControlLinearizer::LowerStringFromCodePoint(Node* node) {
   1959   Node* value = node->InputAt(0);
   1960   Node* code = value;
   1961 
   1962   auto if_not_single_code = __ MakeDeferredLabel<1>();
   1963   auto if_not_one_byte = __ MakeDeferredLabel<1>();
   1964   auto cache_miss = __ MakeDeferredLabel<1>();
   1965   auto done = __ MakeLabel<4>(MachineRepresentation::kTagged);
   1966 
   1967   // Check if the {code} is a single code unit
   1968   Node* check0 = __ Uint32LessThanOrEqual(code, __ Uint32Constant(0xFFFF));
   1969   __ GotoUnless(check0, &if_not_single_code);
   1970 
   1971   {
   1972     // Check if the {code} is a one byte character
   1973     Node* check1 = __ Uint32LessThanOrEqual(
   1974         code, __ Uint32Constant(String::kMaxOneByteCharCode));
   1975     __ GotoUnless(check1, &if_not_one_byte);
   1976     {
   1977       // Load the isolate wide single character string cache.
   1978       Node* cache = __ HeapConstant(factory()->single_character_string_cache());
   1979 
   1980       // Compute the {cache} index for {code}.
   1981       Node* index = machine()->Is32() ? code : __ ChangeUint32ToUint64(code);
   1982 
   1983       // Check if we have an entry for the {code} in the single character string
   1984       // cache already.
   1985       Node* entry =
   1986           __ LoadElement(AccessBuilder::ForFixedArrayElement(), cache, index);
   1987 
   1988       Node* check2 = __ WordEqual(entry, __ UndefinedConstant());
   1989       __ GotoIf(check2, &cache_miss);
   1990 
   1991       // Use the {entry} from the {cache}.
   1992       __ Goto(&done, entry);
   1993 
   1994       __ Bind(&cache_miss);
   1995       {
   1996         // Allocate a new SeqOneByteString for {code}.
   1997         Node* vtrue2 = __ Allocate(
   1998             NOT_TENURED, __ Int32Constant(SeqOneByteString::SizeFor(1)));
   1999         __ StoreField(AccessBuilder::ForMap(), vtrue2,
   2000                       __ HeapConstant(factory()->one_byte_string_map()));
   2001         __ StoreField(AccessBuilder::ForNameHashField(), vtrue2,
   2002                       __ IntPtrConstant(Name::kEmptyHashField));
   2003         __ StoreField(AccessBuilder::ForStringLength(), vtrue2,
   2004                       __ SmiConstant(1));
   2005         __ Store(
   2006             StoreRepresentation(MachineRepresentation::kWord8, kNoWriteBarrier),
   2007             vtrue2,
   2008             __ IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag),
   2009             code);
   2010 
   2011         // Remember it in the {cache}.
   2012         __ StoreElement(AccessBuilder::ForFixedArrayElement(), cache, index,
   2013                         vtrue2);
   2014         __ Goto(&done, vtrue2);
   2015       }
   2016     }
   2017 
   2018     __ Bind(&if_not_one_byte);
   2019     {
   2020       // Allocate a new SeqTwoByteString for {code}.
   2021       Node* vfalse1 = __ Allocate(
   2022           NOT_TENURED, __ Int32Constant(SeqTwoByteString::SizeFor(1)));
   2023       __ StoreField(AccessBuilder::ForMap(), vfalse1,
   2024                     __ HeapConstant(factory()->string_map()));
   2025       __ StoreField(AccessBuilder::ForNameHashField(), vfalse1,
   2026                     __ IntPtrConstant(Name::kEmptyHashField));
   2027       __ StoreField(AccessBuilder::ForStringLength(), vfalse1,
   2028                     __ SmiConstant(1));
   2029       __ Store(
   2030           StoreRepresentation(MachineRepresentation::kWord16, kNoWriteBarrier),
   2031           vfalse1,
   2032           __ IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag),
   2033           code);
   2034       __ Goto(&done, vfalse1);
   2035     }
   2036   }
   2037 
   2038   __ Bind(&if_not_single_code);
   2039   // Generate surrogate pair string
   2040   {
   2041     switch (UnicodeEncodingOf(node->op())) {
   2042       case UnicodeEncoding::UTF16:
   2043         break;
   2044 
   2045       case UnicodeEncoding::UTF32: {
   2046         // Convert UTF32 to UTF16 code units, and store as a 32 bit word.
   2047         Node* lead_offset = __ Int32Constant(0xD800 - (0x10000 >> 10));
   2048 
   2049         // lead = (codepoint >> 10) + LEAD_OFFSET
   2050         Node* lead =
   2051             __ Int32Add(__ Word32Shr(code, __ Int32Constant(10)), lead_offset);
   2052 
   2053         // trail = (codepoint & 0x3FF) + 0xDC00;
   2054         Node* trail = __ Int32Add(__ Word32And(code, __ Int32Constant(0x3FF)),
   2055                                   __ Int32Constant(0xDC00));
   2056 
   2057         // codpoint = (trail << 16) | lead;
   2058         code = __ Word32Or(__ Word32Shl(trail, __ Int32Constant(16)), lead);
   2059         break;
   2060       }
   2061     }
   2062 
   2063     // Allocate a new SeqTwoByteString for {code}.
   2064     Node* vfalse0 = __ Allocate(NOT_TENURED,
   2065                                 __ Int32Constant(SeqTwoByteString::SizeFor(2)));
   2066     __ StoreField(AccessBuilder::ForMap(), vfalse0,
   2067                   __ HeapConstant(factory()->string_map()));
   2068     __ StoreField(AccessBuilder::ForNameHashField(), vfalse0,
   2069                   __ IntPtrConstant(Name::kEmptyHashField));
   2070     __ StoreField(AccessBuilder::ForStringLength(), vfalse0, __ SmiConstant(2));
   2071     __ Store(
   2072         StoreRepresentation(MachineRepresentation::kWord32, kNoWriteBarrier),
   2073         vfalse0,
   2074         __ IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag),
   2075         code);
   2076     __ Goto(&done, vfalse0);
   2077   }
   2078 
   2079   __ Bind(&done);
   2080   return done.PhiAt(0);
   2081 }
   2082 
   2083 Node* EffectControlLinearizer::LowerStringIndexOf(Node* node) {
   2084   Node* subject = node->InputAt(0);
   2085   Node* search_string = node->InputAt(1);
   2086   Node* position = node->InputAt(2);
   2087 
   2088   Callable callable = CodeFactory::StringIndexOf(isolate());
   2089   Operator::Properties properties = Operator::kEliminatable;
   2090   CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
   2091   CallDescriptor* desc = Linkage::GetStubCallDescriptor(
   2092       isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties);
   2093   return __ Call(desc, __ HeapConstant(callable.code()), subject, search_string,
   2094                  position, __ NoContextConstant());
   2095 }
   2096 
   2097 Node* EffectControlLinearizer::LowerStringComparison(Callable const& callable,
   2098                                                      Node* node) {
   2099   Node* lhs = node->InputAt(0);
   2100   Node* rhs = node->InputAt(1);
   2101 
   2102   Operator::Properties properties = Operator::kEliminatable;
   2103   CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
   2104   CallDescriptor* desc = Linkage::GetStubCallDescriptor(
   2105       isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties);
   2106   return __ Call(desc, __ HeapConstant(callable.code()), lhs, rhs,
   2107                  __ NoContextConstant());
   2108 }
   2109 
   2110 Node* EffectControlLinearizer::LowerStringEqual(Node* node) {
   2111   return LowerStringComparison(CodeFactory::StringEqual(isolate()), node);
   2112 }
   2113 
   2114 Node* EffectControlLinearizer::LowerStringLessThan(Node* node) {
   2115   return LowerStringComparison(CodeFactory::StringLessThan(isolate()), node);
   2116 }
   2117 
   2118 Node* EffectControlLinearizer::LowerStringLessThanOrEqual(Node* node) {
   2119   return LowerStringComparison(CodeFactory::StringLessThanOrEqual(isolate()),
   2120                                node);
   2121 }
   2122 
   2123 Node* EffectControlLinearizer::LowerCheckFloat64Hole(Node* node,
   2124                                                      Node* frame_state) {
   2125   // If we reach this point w/o eliminating the {node} that's marked
   2126   // with allow-return-hole, we cannot do anything, so just deoptimize
   2127   // in case of the hole NaN (similar to Crankshaft).
   2128   Node* value = node->InputAt(0);
   2129   Node* check = __ Word32Equal(__ Float64ExtractHighWord32(value),
   2130                                __ Int32Constant(kHoleNanUpper32));
   2131   __ DeoptimizeIf(DeoptimizeReason::kHole, check, frame_state);
   2132   return value;
   2133 }
   2134 
   2135 Node* EffectControlLinearizer::LowerCheckTaggedHole(Node* node,
   2136                                                     Node* frame_state) {
   2137   Node* value = node->InputAt(0);
   2138   Node* check = __ WordEqual(value, __ TheHoleConstant());
   2139   __ DeoptimizeIf(DeoptimizeReason::kHole, check, frame_state);
   2140   return value;
   2141 }
   2142 
   2143 Node* EffectControlLinearizer::LowerConvertTaggedHoleToUndefined(Node* node) {
   2144   Node* value = node->InputAt(0);
   2145 
   2146   auto if_is_hole = __ MakeDeferredLabel<1>();
   2147   auto done = __ MakeLabel<2>(MachineRepresentation::kTagged);
   2148 
   2149   Node* check = __ WordEqual(value, __ TheHoleConstant());
   2150   __ GotoIf(check, &if_is_hole);
   2151   __ Goto(&done, value);
   2152 
   2153   __ Bind(&if_is_hole);
   2154   __ Goto(&done, __ UndefinedConstant());
   2155 
   2156   __ Bind(&done);
   2157   return done.PhiAt(0);
   2158 }
   2159 
   2160 Node* EffectControlLinearizer::AllocateHeapNumberWithValue(Node* value) {
   2161   Node* result = __ Allocate(NOT_TENURED, __ Int32Constant(HeapNumber::kSize));
   2162   __ StoreField(AccessBuilder::ForMap(), result, __ HeapNumberMapConstant());
   2163   __ StoreField(AccessBuilder::ForHeapNumberValue(), result, value);
   2164   return result;
   2165 }
   2166 
   2167 Node* EffectControlLinearizer::ChangeInt32ToSmi(Node* value) {
   2168   if (machine()->Is64()) {
   2169     value = __ ChangeInt32ToInt64(value);
   2170   }
   2171   return __ WordShl(value, SmiShiftBitsConstant());
   2172 }
   2173 
   2174 Node* EffectControlLinearizer::ChangeUint32ToSmi(Node* value) {
   2175   if (machine()->Is64()) {
   2176     value = __ ChangeUint32ToUint64(value);
   2177   }
   2178   return __ WordShl(value, SmiShiftBitsConstant());
   2179 }
   2180 
   2181 Node* EffectControlLinearizer::ChangeSmiToInt32(Node* value) {
   2182   value = __ WordSar(value, SmiShiftBitsConstant());
   2183   if (machine()->Is64()) {
   2184     value = __ TruncateInt64ToInt32(value);
   2185   }
   2186   return value;
   2187 }
   2188 
   2189 Node* EffectControlLinearizer::ObjectIsSmi(Node* value) {
   2190   return __ WordEqual(__ WordAnd(value, __ IntPtrConstant(kSmiTagMask)),
   2191                       __ IntPtrConstant(kSmiTag));
   2192 }
   2193 
   2194 Node* EffectControlLinearizer::SmiMaxValueConstant() {
   2195   return __ Int32Constant(Smi::kMaxValue);
   2196 }
   2197 
   2198 Node* EffectControlLinearizer::SmiShiftBitsConstant() {
   2199   return __ IntPtrConstant(kSmiShiftSize + kSmiTagSize);
   2200 }
   2201 
   2202 Node* EffectControlLinearizer::LowerPlainPrimitiveToNumber(Node* node) {
   2203   Node* value = node->InputAt(0);
   2204   return __ ToNumber(value);
   2205 }
   2206 
   2207 Node* EffectControlLinearizer::LowerPlainPrimitiveToWord32(Node* node) {
   2208   Node* value = node->InputAt(0);
   2209 
   2210   auto if_not_smi = __ MakeDeferredLabel<1>();
   2211   auto if_to_number_smi = __ MakeLabel<1>();
   2212   auto done = __ MakeLabel<3>(MachineRepresentation::kWord32);
   2213 
   2214   Node* check0 = ObjectIsSmi(value);
   2215   __ GotoUnless(check0, &if_not_smi);
   2216   __ Goto(&done, ChangeSmiToInt32(value));
   2217 
   2218   __ Bind(&if_not_smi);
   2219   Node* to_number = __ ToNumber(value);
   2220 
   2221   Node* check1 = ObjectIsSmi(to_number);
   2222   __ GotoIf(check1, &if_to_number_smi);
   2223   Node* number = __ LoadField(AccessBuilder::ForHeapNumberValue(), to_number);
   2224   __ Goto(&done, __ TruncateFloat64ToWord32(number));
   2225 
   2226   __ Bind(&if_to_number_smi);
   2227   __ Goto(&done, ChangeSmiToInt32(to_number));
   2228 
   2229   __ Bind(&done);
   2230   return done.PhiAt(0);
   2231 }
   2232 
   2233 Node* EffectControlLinearizer::LowerPlainPrimitiveToFloat64(Node* node) {
   2234   Node* value = node->InputAt(0);
   2235 
   2236   auto if_not_smi = __ MakeDeferredLabel<1>();
   2237   auto if_to_number_smi = __ MakeLabel<1>();
   2238   auto done = __ MakeLabel<3>(MachineRepresentation::kFloat64);
   2239 
   2240   Node* check0 = ObjectIsSmi(value);
   2241   __ GotoUnless(check0, &if_not_smi);
   2242   Node* from_smi = ChangeSmiToInt32(value);
   2243   __ Goto(&done, __ ChangeInt32ToFloat64(from_smi));
   2244 
   2245   __ Bind(&if_not_smi);
   2246   Node* to_number = __ ToNumber(value);
   2247   Node* check1 = ObjectIsSmi(to_number);
   2248   __ GotoIf(check1, &if_to_number_smi);
   2249 
   2250   Node* number = __ LoadField(AccessBuilder::ForHeapNumberValue(), to_number);
   2251   __ Goto(&done, number);
   2252 
   2253   __ Bind(&if_to_number_smi);
   2254   Node* number_from_smi = ChangeSmiToInt32(to_number);
   2255   number_from_smi = __ ChangeInt32ToFloat64(number_from_smi);
   2256   __ Goto(&done, number_from_smi);
   2257 
   2258   __ Bind(&done);
   2259   return done.PhiAt(0);
   2260 }
   2261 
   2262 Node* EffectControlLinearizer::LowerEnsureWritableFastElements(Node* node) {
   2263   Node* object = node->InputAt(0);
   2264   Node* elements = node->InputAt(1);
   2265 
   2266   auto if_not_fixed_array = __ MakeDeferredLabel<1>();
   2267   auto done = __ MakeLabel<2>(MachineRepresentation::kTagged);
   2268 
   2269   // Load the current map of {elements}.
   2270   Node* elements_map = __ LoadField(AccessBuilder::ForMap(), elements);
   2271 
   2272   // Check if {elements} is not a copy-on-write FixedArray.
   2273   Node* check = __ WordEqual(elements_map, __ FixedArrayMapConstant());
   2274   __ GotoUnless(check, &if_not_fixed_array);
   2275   // Nothing to do if the {elements} are not copy-on-write.
   2276   __ Goto(&done, elements);
   2277 
   2278   __ Bind(&if_not_fixed_array);
   2279   // We need to take a copy of the {elements} and set them up for {object}.
   2280   Operator::Properties properties = Operator::kEliminatable;
   2281   Callable callable = CodeFactory::CopyFastSmiOrObjectElements(isolate());
   2282   CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
   2283   CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
   2284       isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties);
   2285   Node* result = __ Call(desc, __ HeapConstant(callable.code()), object,
   2286                          __ NoContextConstant());
   2287   __ Goto(&done, result);
   2288 
   2289   __ Bind(&done);
   2290   return done.PhiAt(0);
   2291 }
   2292 
   2293 Node* EffectControlLinearizer::LowerMaybeGrowFastElements(Node* node,
   2294                                                           Node* frame_state) {
   2295   GrowFastElementsFlags flags = GrowFastElementsFlagsOf(node->op());
   2296   Node* object = node->InputAt(0);
   2297   Node* elements = node->InputAt(1);
   2298   Node* index = node->InputAt(2);
   2299   Node* length = node->InputAt(3);
   2300 
   2301   auto done = __ MakeLabel<2>(MachineRepresentation::kTagged);
   2302   auto done_grow = __ MakeLabel<2>(MachineRepresentation::kTagged);
   2303   auto if_grow = __ MakeDeferredLabel<1>();
   2304   auto if_not_grow = __ MakeLabel<1>();
   2305 
   2306   Node* check0 = (flags & GrowFastElementsFlag::kHoleyElements)
   2307                      ? __ Uint32LessThanOrEqual(length, index)
   2308                      : __ Word32Equal(length, index);
   2309   __ GotoUnless(check0, &if_not_grow);
   2310   {
   2311     // Load the length of the {elements} backing store.
   2312     Node* elements_length =
   2313         __ LoadField(AccessBuilder::ForFixedArrayLength(), elements);
   2314     elements_length = ChangeSmiToInt32(elements_length);
   2315 
   2316     // Check if we need to grow the {elements} backing store.
   2317     Node* check1 = __ Uint32LessThan(index, elements_length);
   2318     __ GotoUnless(check1, &if_grow);
   2319     __ Goto(&done_grow, elements);
   2320 
   2321     __ Bind(&if_grow);
   2322     // We need to grow the {elements} for {object}.
   2323     Operator::Properties properties = Operator::kEliminatable;
   2324     Callable callable =
   2325         (flags & GrowFastElementsFlag::kDoubleElements)
   2326             ? CodeFactory::GrowFastDoubleElements(isolate())
   2327             : CodeFactory::GrowFastSmiOrObjectElements(isolate());
   2328     CallDescriptor::Flags call_flags = CallDescriptor::kNoFlags;
   2329     CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
   2330         isolate(), graph()->zone(), callable.descriptor(), 0, call_flags,
   2331         properties);
   2332     Node* new_object = __ Call(desc, __ HeapConstant(callable.code()), object,
   2333                                ChangeInt32ToSmi(index), __ NoContextConstant());
   2334 
   2335     // Ensure that we were able to grow the {elements}.
   2336     // TODO(turbofan): We use kSmi as reason here similar to Crankshaft,
   2337     // but maybe we should just introduce a reason that makes sense.
   2338     __ DeoptimizeIf(DeoptimizeReason::kSmi, ObjectIsSmi(new_object),
   2339                     frame_state);
   2340     __ Goto(&done_grow, new_object);
   2341 
   2342     __ Bind(&done_grow);
   2343 
   2344     // For JSArray {object}s we also need to update the "length".
   2345     if (flags & GrowFastElementsFlag::kArrayObject) {
   2346       // Compute the new {length}.
   2347       Node* object_length =
   2348           ChangeInt32ToSmi(__ Int32Add(index, __ Int32Constant(1)));
   2349 
   2350       // Update the "length" property of the {object}.
   2351       __ StoreField(AccessBuilder::ForJSArrayLength(FAST_ELEMENTS), object,
   2352                     object_length);
   2353     }
   2354     __ Goto(&done, done_grow.PhiAt(0));
   2355   }
   2356 
   2357   __ Bind(&if_not_grow);
   2358   {
   2359     // In case of non-holey {elements}, we need to verify that the {index} is
   2360     // in-bounds, otherwise for holey {elements}, the check above already
   2361     // guards the index (and the operator forces {index} to be unsigned).
   2362     if (!(flags & GrowFastElementsFlag::kHoleyElements)) {
   2363       Node* check1 = __ Uint32LessThan(index, length);
   2364       __ DeoptimizeUnless(DeoptimizeReason::kOutOfBounds, check1, frame_state);
   2365     }
   2366     __ Goto(&done, elements);
   2367   }
   2368   __ Bind(&done);
   2369   return done.PhiAt(0);
   2370 }
   2371 
   2372 void EffectControlLinearizer::LowerTransitionElementsKind(Node* node) {
   2373   ElementsTransition const transition = ElementsTransitionOf(node->op());
   2374   Node* object = node->InputAt(0);
   2375 
   2376   auto if_map_same = __ MakeDeferredLabel<1>();
   2377   auto done = __ MakeLabel<2>();
   2378 
   2379   Node* source_map = __ HeapConstant(transition.source());
   2380   Node* target_map = __ HeapConstant(transition.target());
   2381 
   2382   // Load the current map of {object}.
   2383   Node* object_map = __ LoadField(AccessBuilder::ForMap(), object);
   2384 
   2385   // Check if {object_map} is the same as {source_map}.
   2386   Node* check = __ WordEqual(object_map, source_map);
   2387   __ GotoIf(check, &if_map_same);
   2388   __ Goto(&done);
   2389 
   2390   __ Bind(&if_map_same);
   2391   switch (transition.mode()) {
   2392     case ElementsTransition::kFastTransition:
   2393       // In-place migration of {object}, just store the {target_map}.
   2394       __ StoreField(AccessBuilder::ForMap(), object, target_map);
   2395       break;
   2396     case ElementsTransition::kSlowTransition: {
   2397       // Instance migration, call out to the runtime for {object}.
   2398       Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
   2399       Runtime::FunctionId id = Runtime::kTransitionElementsKind;
   2400       CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor(
   2401           graph()->zone(), id, 2, properties, CallDescriptor::kNoFlags);
   2402       __ Call(desc, __ CEntryStubConstant(1), object, target_map,
   2403               __ ExternalConstant(ExternalReference(id, isolate())),
   2404               __ Int32Constant(2), __ NoContextConstant());
   2405       break;
   2406     }
   2407   }
   2408   __ Goto(&done);
   2409 
   2410   __ Bind(&done);
   2411 }
   2412 
   2413 Node* EffectControlLinearizer::LowerLoadTypedElement(Node* node) {
   2414   ExternalArrayType array_type = ExternalArrayTypeOf(node->op());
   2415   Node* buffer = node->InputAt(0);
   2416   Node* base = node->InputAt(1);
   2417   Node* external = node->InputAt(2);
   2418   Node* index = node->InputAt(3);
   2419 
   2420   // We need to keep the {buffer} alive so that the GC will not release the
   2421   // ArrayBuffer (if there's any) as long as we are still operating on it.
   2422   __ Retain(buffer);
   2423 
   2424   // Compute the effective storage pointer, handling the case where the
   2425   // {external} pointer is the effective storage pointer (i.e. the {base}
   2426   // is Smi zero).
   2427   Node* storage = NumberMatcher(base).Is(0) ? external : __ UnsafePointerAdd(
   2428                                                              base, external);
   2429 
   2430   // Perform the actual typed element access.
   2431   return __ LoadElement(AccessBuilder::ForTypedArrayElement(array_type, true),
   2432                         storage, index);
   2433 }
   2434 
   2435 void EffectControlLinearizer::LowerStoreTypedElement(Node* node) {
   2436   ExternalArrayType array_type = ExternalArrayTypeOf(node->op());
   2437   Node* buffer = node->InputAt(0);
   2438   Node* base = node->InputAt(1);
   2439   Node* external = node->InputAt(2);
   2440   Node* index = node->InputAt(3);
   2441   Node* value = node->InputAt(4);
   2442 
   2443   // We need to keep the {buffer} alive so that the GC will not release the
   2444   // ArrayBuffer (if there's any) as long as we are still operating on it.
   2445   __ Retain(buffer);
   2446 
   2447   // Compute the effective storage pointer, handling the case where the
   2448   // {external} pointer is the effective storage pointer (i.e. the {base}
   2449   // is Smi zero).
   2450   Node* storage = NumberMatcher(base).Is(0) ? external : __ UnsafePointerAdd(
   2451                                                              base, external);
   2452 
   2453   // Perform the actual typed element access.
   2454   __ StoreElement(AccessBuilder::ForTypedArrayElement(array_type, true),
   2455                   storage, index, value);
   2456 }
   2457 
   2458 Maybe<Node*> EffectControlLinearizer::LowerFloat64RoundUp(Node* node) {
   2459   // Nothing to be done if a fast hardware instruction is available.
   2460   if (machine()->Float64RoundUp().IsSupported()) {
   2461     return Nothing<Node*>();
   2462   }
   2463 
   2464   Node* const input = node->InputAt(0);
   2465 
   2466   // General case for ceil.
   2467   //
   2468   //   if 0.0 < input then
   2469   //     if 2^52 <= input then
   2470   //       input
   2471   //     else
   2472   //       let temp1 = (2^52 + input) - 2^52 in
   2473   //       if temp1 < input then
   2474   //         temp1 + 1
   2475   //       else
   2476   //         temp1
   2477   //   else
   2478   //     if input == 0 then
   2479   //       input
   2480   //     else
   2481   //       if input <= -2^52 then
   2482   //         input
   2483   //       else
   2484   //         let temp1 = -0 - input in
   2485   //         let temp2 = (2^52 + temp1) - 2^52 in
   2486   //         let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in
   2487   //         -0 - temp3
   2488 
   2489   auto if_not_positive = __ MakeDeferredLabel<1>();
   2490   auto if_greater_than_two_52 = __ MakeDeferredLabel<1>();
   2491   auto if_less_than_minus_two_52 = __ MakeDeferredLabel<1>();
   2492   auto if_zero = __ MakeDeferredLabel<1>();
   2493   auto done_temp3 = __ MakeLabel<2>(MachineRepresentation::kFloat64);
   2494   auto done = __ MakeLabel<6>(MachineRepresentation::kFloat64);
   2495 
   2496   Node* const zero = __ Float64Constant(0.0);
   2497   Node* const two_52 = __ Float64Constant(4503599627370496.0E0);
   2498   Node* const one = __ Float64Constant(1.0);
   2499 
   2500   Node* check0 = __ Float64LessThan(zero, input);
   2501   __ GotoUnless(check0, &if_not_positive);
   2502   {
   2503     Node* check1 = __ Float64LessThanOrEqual(two_52, input);
   2504     __ GotoIf(check1, &if_greater_than_two_52);
   2505     {
   2506       Node* temp1 = __ Float64Sub(__ Float64Add(two_52, input), two_52);
   2507       __ GotoUnless(__ Float64LessThan(temp1, input), &done, temp1);
   2508       __ Goto(&done, __ Float64Add(temp1, one));
   2509     }
   2510 
   2511     __ Bind(&if_greater_than_two_52);
   2512     __ Goto(&done, input);
   2513   }
   2514 
   2515   __ Bind(&if_not_positive);
   2516   {
   2517     Node* check1 = __ Float64Equal(input, zero);
   2518     __ GotoIf(check1, &if_zero);
   2519 
   2520     Node* const minus_two_52 = __ Float64Constant(-4503599627370496.0E0);
   2521     Node* check2 = __ Float64LessThanOrEqual(input, minus_two_52);
   2522     __ GotoIf(check2, &if_less_than_minus_two_52);
   2523 
   2524     {
   2525       Node* const minus_zero = __ Float64Constant(-0.0);
   2526       Node* temp1 = __ Float64Sub(minus_zero, input);
   2527       Node* temp2 = __ Float64Sub(__ Float64Add(two_52, temp1), two_52);
   2528       Node* check3 = __ Float64LessThan(temp1, temp2);
   2529       __ GotoUnless(check3, &done_temp3, temp2);
   2530       __ Goto(&done_temp3, __ Float64Sub(temp2, one));
   2531 
   2532       __ Bind(&done_temp3);
   2533       Node* temp3 = done_temp3.PhiAt(0);
   2534       __ Goto(&done, __ Float64Sub(minus_zero, temp3));
   2535     }
   2536     __ Bind(&if_less_than_minus_two_52);
   2537     __ Goto(&done, input);
   2538 
   2539     __ Bind(&if_zero);
   2540     __ Goto(&done, input);
   2541   }
   2542   __ Bind(&done);
   2543   return Just(done.PhiAt(0));
   2544 }
   2545 
   2546 Node* EffectControlLinearizer::BuildFloat64RoundDown(Node* value) {
   2547   Node* round_down = __ Float64RoundDown(value);
   2548   if (round_down != nullptr) {
   2549     return round_down;
   2550   }
   2551 
   2552   Node* const input = value;
   2553 
   2554   // General case for floor.
   2555   //
   2556   //   if 0.0 < input then
   2557   //     if 2^52 <= input then
   2558   //       input
   2559   //     else
   2560   //       let temp1 = (2^52 + input) - 2^52 in
   2561   //       if input < temp1 then
   2562   //         temp1 - 1
   2563   //       else
   2564   //         temp1
   2565   //   else
   2566   //     if input == 0 then
   2567   //       input
   2568   //     else
   2569   //       if input <= -2^52 then
   2570   //         input
   2571   //       else
   2572   //         let temp1 = -0 - input in
   2573   //         let temp2 = (2^52 + temp1) - 2^52 in
   2574   //         if temp2 < temp1 then
   2575   //           -1 - temp2
   2576   //         else
   2577   //           -0 - temp2
   2578 
   2579   auto if_not_positive = __ MakeDeferredLabel<1>();
   2580   auto if_greater_than_two_52 = __ MakeDeferredLabel<1>();
   2581   auto if_less_than_minus_two_52 = __ MakeDeferredLabel<1>();
   2582   auto if_temp2_lt_temp1 = __ MakeLabel<1>();
   2583   auto if_zero = __ MakeDeferredLabel<1>();
   2584   auto done = __ MakeLabel<7>(MachineRepresentation::kFloat64);
   2585 
   2586   Node* const zero = __ Float64Constant(0.0);
   2587   Node* const two_52 = __ Float64Constant(4503599627370496.0E0);
   2588 
   2589   Node* check0 = __ Float64LessThan(zero, input);
   2590   __ GotoUnless(check0, &if_not_positive);
   2591   {
   2592     Node* check1 = __ Float64LessThanOrEqual(two_52, input);
   2593     __ GotoIf(check1, &if_greater_than_two_52);
   2594     {
   2595       Node* const one = __ Float64Constant(1.0);
   2596       Node* temp1 = __ Float64Sub(__ Float64Add(two_52, input), two_52);
   2597       __ GotoUnless(__ Float64LessThan(input, temp1), &done, temp1);
   2598       __ Goto(&done, __ Float64Sub(temp1, one));
   2599     }
   2600 
   2601     __ Bind(&if_greater_than_two_52);
   2602     __ Goto(&done, input);
   2603   }
   2604 
   2605   __ Bind(&if_not_positive);
   2606   {
   2607     Node* check1 = __ Float64Equal(input, zero);
   2608     __ GotoIf(check1, &if_zero);
   2609 
   2610     Node* const minus_two_52 = __ Float64Constant(-4503599627370496.0E0);
   2611     Node* check2 = __ Float64LessThanOrEqual(input, minus_two_52);
   2612     __ GotoIf(check2, &if_less_than_minus_two_52);
   2613 
   2614     {
   2615       Node* const minus_zero = __ Float64Constant(-0.0);
   2616       Node* temp1 = __ Float64Sub(minus_zero, input);
   2617       Node* temp2 = __ Float64Sub(__ Float64Add(two_52, temp1), two_52);
   2618       Node* check3 = __ Float64LessThan(temp2, temp1);
   2619       __ GotoIf(check3, &if_temp2_lt_temp1);
   2620       __ Goto(&done, __ Float64Sub(minus_zero, temp2));
   2621 
   2622       __ Bind(&if_temp2_lt_temp1);
   2623       __ Goto(&done, __ Float64Sub(__ Float64Constant(-1.0), temp2));
   2624     }
   2625     __ Bind(&if_less_than_minus_two_52);
   2626     __ Goto(&done, input);
   2627 
   2628     __ Bind(&if_zero);
   2629     __ Goto(&done, input);
   2630   }
   2631   __ Bind(&done);
   2632   return done.PhiAt(0);
   2633 }
   2634 
   2635 Maybe<Node*> EffectControlLinearizer::LowerFloat64RoundDown(Node* node) {
   2636   // Nothing to be done if a fast hardware instruction is available.
   2637   if (machine()->Float64RoundDown().IsSupported()) {
   2638     return Nothing<Node*>();
   2639   }
   2640 
   2641   Node* const input = node->InputAt(0);
   2642   return Just(BuildFloat64RoundDown(input));
   2643 }
   2644 
   2645 Maybe<Node*> EffectControlLinearizer::LowerFloat64RoundTiesEven(Node* node) {
   2646   // Nothing to be done if a fast hardware instruction is available.
   2647   if (machine()->Float64RoundTiesEven().IsSupported()) {
   2648     return Nothing<Node*>();
   2649   }
   2650 
   2651   Node* const input = node->InputAt(0);
   2652 
   2653   // Generate case for round ties to even:
   2654   //
   2655   //   let value = floor(input) in
   2656   //   let temp1 = input - value in
   2657   //   if temp1 < 0.5 then
   2658   //     value
   2659   //   else if 0.5 < temp1 then
   2660   //     value + 1.0
   2661   //   else
   2662   //     let temp2 = value % 2.0 in
   2663   //     if temp2 == 0.0 then
   2664   //       value
   2665   //     else
   2666   //       value + 1.0
   2667 
   2668   auto if_is_half = __ MakeLabel<1>();
   2669   auto done = __ MakeLabel<4>(MachineRepresentation::kFloat64);
   2670 
   2671   Node* value = BuildFloat64RoundDown(input);
   2672   Node* temp1 = __ Float64Sub(input, value);
   2673 
   2674   Node* const half = __ Float64Constant(0.5);
   2675   Node* check0 = __ Float64LessThan(temp1, half);
   2676   __ GotoIf(check0, &done, value);
   2677 
   2678   Node* const one = __ Float64Constant(1.0);
   2679   Node* check1 = __ Float64LessThan(half, temp1);
   2680   __ GotoUnless(check1, &if_is_half);
   2681   __ Goto(&done, __ Float64Add(value, one));
   2682 
   2683   __ Bind(&if_is_half);
   2684   Node* temp2 = __ Float64Mod(value, __ Float64Constant(2.0));
   2685   Node* check2 = __ Float64Equal(temp2, __ Float64Constant(0.0));
   2686   __ GotoIf(check2, &done, value);
   2687   __ Goto(&done, __ Float64Add(value, one));
   2688 
   2689   __ Bind(&done);
   2690   return Just(done.PhiAt(0));
   2691 }
   2692 
   2693 Maybe<Node*> EffectControlLinearizer::LowerFloat64RoundTruncate(Node* node) {
   2694   // Nothing to be done if a fast hardware instruction is available.
   2695   if (machine()->Float64RoundTruncate().IsSupported()) {
   2696     return Nothing<Node*>();
   2697   }
   2698 
   2699   Node* const input = node->InputAt(0);
   2700 
   2701   // General case for trunc.
   2702   //
   2703   //   if 0.0 < input then
   2704   //     if 2^52 <= input then
   2705   //       input
   2706   //     else
   2707   //       let temp1 = (2^52 + input) - 2^52 in
   2708   //       if input < temp1 then
   2709   //         temp1 - 1
   2710   //       else
   2711   //         temp1
   2712   //   else
   2713   //     if input == 0 then
   2714   //       input
   2715   //     else
   2716   //       if input <= -2^52 then
   2717   //         input
   2718   //       else
   2719   //         let temp1 = -0 - input in
   2720   //         let temp2 = (2^52 + temp1) - 2^52 in
   2721   //         let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in
   2722   //         -0 - temp3
   2723   //
   2724   // Note: We do not use the Diamond helper class here, because it really hurts
   2725   // readability with nested diamonds.
   2726 
   2727   auto if_not_positive = __ MakeDeferredLabel<1>();
   2728   auto if_greater_than_two_52 = __ MakeDeferredLabel<1>();
   2729   auto if_less_than_minus_two_52 = __ MakeDeferredLabel<1>();
   2730   auto if_zero = __ MakeDeferredLabel<1>();
   2731   auto done_temp3 = __ MakeLabel<2>(MachineRepresentation::kFloat64);
   2732   auto done = __ MakeLabel<6>(MachineRepresentation::kFloat64);
   2733 
   2734   Node* const zero = __ Float64Constant(0.0);
   2735   Node* const two_52 = __ Float64Constant(4503599627370496.0E0);
   2736   Node* const one = __ Float64Constant(1.0);
   2737 
   2738   Node* check0 = __ Float64LessThan(zero, input);
   2739   __ GotoUnless(check0, &if_not_positive);
   2740   {
   2741     Node* check1 = __ Float64LessThanOrEqual(two_52, input);
   2742     __ GotoIf(check1, &if_greater_than_two_52);
   2743     {
   2744       Node* temp1 = __ Float64Sub(__ Float64Add(two_52, input), two_52);
   2745       __ GotoUnless(__ Float64LessThan(input, temp1), &done, temp1);
   2746       __ Goto(&done, __ Float64Sub(temp1, one));
   2747     }
   2748 
   2749     __ Bind(&if_greater_than_two_52);
   2750     __ Goto(&done, input);
   2751   }
   2752 
   2753   __ Bind(&if_not_positive);
   2754   {
   2755     Node* check1 = __ Float64Equal(input, zero);
   2756     __ GotoIf(check1, &if_zero);
   2757 
   2758     Node* const minus_two_52 = __ Float64Constant(-4503599627370496.0E0);
   2759     Node* check2 = __ Float64LessThanOrEqual(input, minus_two_52);
   2760     __ GotoIf(check2, &if_less_than_minus_two_52);
   2761 
   2762     {
   2763       Node* const minus_zero = __ Float64Constant(-0.0);
   2764       Node* temp1 = __ Float64Sub(minus_zero, input);
   2765       Node* temp2 = __ Float64Sub(__ Float64Add(two_52, temp1), two_52);
   2766       Node* check3 = __ Float64LessThan(temp1, temp2);
   2767       __ GotoUnless(check3, &done_temp3, temp2);
   2768       __ Goto(&done_temp3, __ Float64Sub(temp2, one));
   2769 
   2770       __ Bind(&done_temp3);
   2771       Node* temp3 = done_temp3.PhiAt(0);
   2772       __ Goto(&done, __ Float64Sub(minus_zero, temp3));
   2773     }
   2774     __ Bind(&if_less_than_minus_two_52);
   2775     __ Goto(&done, input);
   2776 
   2777     __ Bind(&if_zero);
   2778     __ Goto(&done, input);
   2779   }
   2780   __ Bind(&done);
   2781   return Just(done.PhiAt(0));
   2782 }
   2783 
   2784 #undef __
   2785 
   2786 Factory* EffectControlLinearizer::factory() const {
   2787   return isolate()->factory();
   2788 }
   2789 
   2790 Isolate* EffectControlLinearizer::isolate() const {
   2791   return jsgraph()->isolate();
   2792 }
   2793 
   2794 }  // namespace compiler
   2795 }  // namespace internal
   2796 }  // namespace v8
   2797