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 
     17 namespace v8 {
     18 namespace internal {
     19 namespace compiler {
     20 
     21 EffectControlLinearizer::EffectControlLinearizer(
     22     JSGraph* js_graph, Schedule* schedule, Zone* temp_zone,
     23     SourcePositionTable* source_positions)
     24     : js_graph_(js_graph),
     25       schedule_(schedule),
     26       temp_zone_(temp_zone),
     27       source_positions_(source_positions) {}
     28 
     29 Graph* EffectControlLinearizer::graph() const { return js_graph_->graph(); }
     30 CommonOperatorBuilder* EffectControlLinearizer::common() const {
     31   return js_graph_->common();
     32 }
     33 SimplifiedOperatorBuilder* EffectControlLinearizer::simplified() const {
     34   return js_graph_->simplified();
     35 }
     36 MachineOperatorBuilder* EffectControlLinearizer::machine() const {
     37   return js_graph_->machine();
     38 }
     39 
     40 namespace {
     41 
     42 struct BlockEffectControlData {
     43   Node* current_effect = nullptr;       // New effect.
     44   Node* current_control = nullptr;      // New control.
     45   Node* current_frame_state = nullptr;  // New frame state.
     46 };
     47 
     48 class BlockEffectControlMap {
     49  public:
     50   explicit BlockEffectControlMap(Zone* temp_zone) : map_(temp_zone) {}
     51 
     52   BlockEffectControlData& For(BasicBlock* from, BasicBlock* to) {
     53     return map_[std::make_pair(from->rpo_number(), to->rpo_number())];
     54   }
     55 
     56   const BlockEffectControlData& For(BasicBlock* from, BasicBlock* to) const {
     57     return map_.at(std::make_pair(from->rpo_number(), to->rpo_number()));
     58   }
     59 
     60  private:
     61   typedef std::pair<int32_t, int32_t> Key;
     62   typedef ZoneMap<Key, BlockEffectControlData> Map;
     63 
     64   Map map_;
     65 };
     66 
     67 // Effect phis that need to be updated after the first pass.
     68 struct PendingEffectPhi {
     69   Node* effect_phi;
     70   BasicBlock* block;
     71 
     72   PendingEffectPhi(Node* effect_phi, BasicBlock* block)
     73       : effect_phi(effect_phi), block(block) {}
     74 };
     75 
     76 void UpdateEffectPhi(Node* node, BasicBlock* block,
     77                      BlockEffectControlMap* block_effects) {
     78   // Update all inputs to an effect phi with the effects from the given
     79   // block->effect map.
     80   DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode());
     81   DCHECK_EQ(static_cast<size_t>(node->op()->EffectInputCount()),
     82             block->PredecessorCount());
     83   for (int i = 0; i < node->op()->EffectInputCount(); i++) {
     84     Node* input = node->InputAt(i);
     85     BasicBlock* predecessor = block->PredecessorAt(static_cast<size_t>(i));
     86     const BlockEffectControlData& block_effect =
     87         block_effects->For(predecessor, block);
     88     if (input != block_effect.current_effect) {
     89       node->ReplaceInput(i, block_effect.current_effect);
     90     }
     91   }
     92 }
     93 
     94 void UpdateBlockControl(BasicBlock* block,
     95                         BlockEffectControlMap* block_effects) {
     96   Node* control = block->NodeAt(0);
     97   DCHECK(NodeProperties::IsControl(control));
     98 
     99   // Do not rewire the end node.
    100   if (control->opcode() == IrOpcode::kEnd) return;
    101 
    102   // Update all inputs to the given control node with the correct control.
    103   DCHECK(control->opcode() == IrOpcode::kMerge ||
    104          static_cast<size_t>(control->op()->ControlInputCount()) ==
    105              block->PredecessorCount());
    106   if (static_cast<size_t>(control->op()->ControlInputCount()) !=
    107       block->PredecessorCount()) {
    108     return;  // We already re-wired the control inputs of this node.
    109   }
    110   for (int i = 0; i < control->op()->ControlInputCount(); i++) {
    111     Node* input = NodeProperties::GetControlInput(control, i);
    112     BasicBlock* predecessor = block->PredecessorAt(static_cast<size_t>(i));
    113     const BlockEffectControlData& block_effect =
    114         block_effects->For(predecessor, block);
    115     if (input != block_effect.current_control) {
    116       NodeProperties::ReplaceControlInput(control, block_effect.current_control,
    117                                           i);
    118     }
    119   }
    120 }
    121 
    122 bool HasIncomingBackEdges(BasicBlock* block) {
    123   for (BasicBlock* pred : block->predecessors()) {
    124     if (pred->rpo_number() >= block->rpo_number()) {
    125       return true;
    126     }
    127   }
    128   return false;
    129 }
    130 
    131 void RemoveRegionNode(Node* node) {
    132   DCHECK(IrOpcode::kFinishRegion == node->opcode() ||
    133          IrOpcode::kBeginRegion == node->opcode());
    134   // Update the value/context uses to the value input of the finish node and
    135   // the effect uses to the effect input.
    136   for (Edge edge : node->use_edges()) {
    137     DCHECK(!edge.from()->IsDead());
    138     if (NodeProperties::IsEffectEdge(edge)) {
    139       edge.UpdateTo(NodeProperties::GetEffectInput(node));
    140     } else {
    141       DCHECK(!NodeProperties::IsControlEdge(edge));
    142       DCHECK(!NodeProperties::IsFrameStateEdge(edge));
    143       edge.UpdateTo(node->InputAt(0));
    144     }
    145   }
    146   node->Kill();
    147 }
    148 
    149 void TryCloneBranch(Node* node, BasicBlock* block, Graph* graph,
    150                     CommonOperatorBuilder* common,
    151                     BlockEffectControlMap* block_effects,
    152                     SourcePositionTable* source_positions) {
    153   DCHECK_EQ(IrOpcode::kBranch, node->opcode());
    154 
    155   // This optimization is a special case of (super)block cloning. It takes an
    156   // input graph as shown below and clones the Branch node for every predecessor
    157   // to the Merge, essentially removing the Merge completely. This avoids
    158   // materializing the bit for the Phi and may offer potential for further
    159   // branch folding optimizations (i.e. because one or more inputs to the Phi is
    160   // a constant). Note that there may be more Phi nodes hanging off the Merge,
    161   // but we can only a certain subset of them currently (actually only Phi and
    162   // EffectPhi nodes whose uses have either the IfTrue or IfFalse as control
    163   // input).
    164 
    165   //   Control1 ... ControlN
    166   //      ^            ^
    167   //      |            |   Cond1 ... CondN
    168   //      +----+  +----+     ^         ^
    169   //           |  |          |         |
    170   //           |  |     +----+         |
    171   //          Merge<--+ | +------------+
    172   //            ^      \|/
    173   //            |      Phi
    174   //            |       |
    175   //          Branch----+
    176   //            ^
    177   //            |
    178   //      +-----+-----+
    179   //      |           |
    180   //    IfTrue     IfFalse
    181   //      ^           ^
    182   //      |           |
    183 
    184   // The resulting graph (modulo the Phi and EffectPhi nodes) looks like this:
    185 
    186   // Control1 Cond1 ... ControlN CondN
    187   //    ^      ^           ^      ^
    188   //    \      /           \      /
    189   //     Branch     ...     Branch
    190   //       ^                  ^
    191   //       |                  |
    192   //   +---+---+          +---+----+
    193   //   |       |          |        |
    194   // IfTrue IfFalse ... IfTrue  IfFalse
    195   //   ^       ^          ^        ^
    196   //   |       |          |        |
    197   //   +--+ +-------------+        |
    198   //      | |  +--------------+ +--+
    199   //      | |                 | |
    200   //     Merge               Merge
    201   //       ^                   ^
    202   //       |                   |
    203 
    204   SourcePositionTable::Scope scope(source_positions,
    205                                    source_positions->GetSourcePosition(node));
    206   Node* branch = node;
    207   Node* cond = NodeProperties::GetValueInput(branch, 0);
    208   if (!cond->OwnedBy(branch) || cond->opcode() != IrOpcode::kPhi) return;
    209   Node* merge = NodeProperties::GetControlInput(branch);
    210   if (merge->opcode() != IrOpcode::kMerge ||
    211       NodeProperties::GetControlInput(cond) != merge) {
    212     return;
    213   }
    214   // Grab the IfTrue/IfFalse projections of the Branch.
    215   BranchMatcher matcher(branch);
    216   // Check/collect other Phi/EffectPhi nodes hanging off the Merge.
    217   NodeVector phis(graph->zone());
    218   for (Node* const use : merge->uses()) {
    219     if (use == branch || use == cond) continue;
    220     // We cannot currently deal with non-Phi/EffectPhi nodes hanging off the
    221     // Merge. Ideally, we would just clone the nodes (and everything that
    222     // depends on it to some distant join point), but that requires knowledge
    223     // about dominance/post-dominance.
    224     if (!NodeProperties::IsPhi(use)) return;
    225     for (Edge edge : use->use_edges()) {
    226       // Right now we can only handle Phi/EffectPhi nodes whose uses are
    227       // directly control-dependend on either the IfTrue or the IfFalse
    228       // successor, because we know exactly how to update those uses.
    229       if (edge.from()->op()->ControlInputCount() != 1) return;
    230       Node* control = NodeProperties::GetControlInput(edge.from());
    231       if (NodeProperties::IsPhi(edge.from())) {
    232         control = NodeProperties::GetControlInput(control, edge.index());
    233       }
    234       if (control != matcher.IfTrue() && control != matcher.IfFalse()) return;
    235     }
    236     phis.push_back(use);
    237   }
    238   BranchHint const hint = BranchHintOf(branch->op());
    239   int const input_count = merge->op()->ControlInputCount();
    240   DCHECK_LE(1, input_count);
    241   Node** const inputs = graph->zone()->NewArray<Node*>(2 * input_count);
    242   Node** const merge_true_inputs = &inputs[0];
    243   Node** const merge_false_inputs = &inputs[input_count];
    244   for (int index = 0; index < input_count; ++index) {
    245     Node* cond1 = NodeProperties::GetValueInput(cond, index);
    246     Node* control1 = NodeProperties::GetControlInput(merge, index);
    247     Node* branch1 = graph->NewNode(common->Branch(hint), cond1, control1);
    248     merge_true_inputs[index] = graph->NewNode(common->IfTrue(), branch1);
    249     merge_false_inputs[index] = graph->NewNode(common->IfFalse(), branch1);
    250   }
    251   Node* const merge_true = matcher.IfTrue();
    252   Node* const merge_false = matcher.IfFalse();
    253   merge_true->TrimInputCount(0);
    254   merge_false->TrimInputCount(0);
    255   for (int i = 0; i < input_count; ++i) {
    256     merge_true->AppendInput(graph->zone(), merge_true_inputs[i]);
    257     merge_false->AppendInput(graph->zone(), merge_false_inputs[i]);
    258   }
    259   DCHECK_EQ(2u, block->SuccessorCount());
    260   NodeProperties::ChangeOp(matcher.IfTrue(), common->Merge(input_count));
    261   NodeProperties::ChangeOp(matcher.IfFalse(), common->Merge(input_count));
    262   int const true_index =
    263       block->SuccessorAt(0)->NodeAt(0) == matcher.IfTrue() ? 0 : 1;
    264   BlockEffectControlData* true_block_data =
    265       &block_effects->For(block, block->SuccessorAt(true_index));
    266   BlockEffectControlData* false_block_data =
    267       &block_effects->For(block, block->SuccessorAt(true_index ^ 1));
    268   for (Node* const phi : phis) {
    269     for (int index = 0; index < input_count; ++index) {
    270       inputs[index] = phi->InputAt(index);
    271     }
    272     inputs[input_count] = merge_true;
    273     Node* phi_true = graph->NewNode(phi->op(), input_count + 1, inputs);
    274     inputs[input_count] = merge_false;
    275     Node* phi_false = graph->NewNode(phi->op(), input_count + 1, inputs);
    276     if (phi->UseCount() == 0) {
    277       DCHECK_EQ(phi->opcode(), IrOpcode::kEffectPhi);
    278     } else {
    279       for (Edge edge : phi->use_edges()) {
    280         Node* control = NodeProperties::GetControlInput(edge.from());
    281         if (NodeProperties::IsPhi(edge.from())) {
    282           control = NodeProperties::GetControlInput(control, edge.index());
    283         }
    284         DCHECK(control == matcher.IfTrue() || control == matcher.IfFalse());
    285         edge.UpdateTo((control == matcher.IfTrue()) ? phi_true : phi_false);
    286       }
    287     }
    288     if (phi->opcode() == IrOpcode::kEffectPhi) {
    289       true_block_data->current_effect = phi_true;
    290       false_block_data->current_effect = phi_false;
    291     }
    292     phi->Kill();
    293   }
    294   // Fix up IfTrue and IfFalse and kill all dead nodes.
    295   if (branch == block->control_input()) {
    296     true_block_data->current_control = merge_true;
    297     false_block_data->current_control = merge_false;
    298   }
    299   branch->Kill();
    300   cond->Kill();
    301   merge->Kill();
    302 }
    303 }  // namespace
    304 
    305 void EffectControlLinearizer::Run() {
    306   BlockEffectControlMap block_effects(temp_zone());
    307   ZoneVector<PendingEffectPhi> pending_effect_phis(temp_zone());
    308   ZoneVector<BasicBlock*> pending_block_controls(temp_zone());
    309   NodeVector inputs_buffer(temp_zone());
    310 
    311   for (BasicBlock* block : *(schedule()->rpo_order())) {
    312     size_t instr = 0;
    313 
    314     // The control node should be the first.
    315     Node* control = block->NodeAt(instr);
    316     DCHECK(NodeProperties::IsControl(control));
    317     // Update the control inputs.
    318     if (HasIncomingBackEdges(block)) {
    319       // If there are back edges, we need to update later because we have not
    320       // computed the control yet. This should only happen for loops.
    321       DCHECK_EQ(IrOpcode::kLoop, control->opcode());
    322       pending_block_controls.push_back(block);
    323     } else {
    324       // If there are no back edges, we can update now.
    325       UpdateBlockControl(block, &block_effects);
    326     }
    327     instr++;
    328 
    329     // Iterate over the phis and update the effect phis.
    330     Node* effect = nullptr;
    331     Node* terminate = nullptr;
    332     for (; instr < block->NodeCount(); instr++) {
    333       Node* node = block->NodeAt(instr);
    334       // Only go through the phis and effect phis.
    335       if (node->opcode() == IrOpcode::kEffectPhi) {
    336         // There should be at most one effect phi in a block.
    337         DCHECK_NULL(effect);
    338         // IfException blocks should not have effect phis.
    339         DCHECK_NE(IrOpcode::kIfException, control->opcode());
    340         effect = node;
    341 
    342         // Make sure we update the inputs to the incoming blocks' effects.
    343         if (HasIncomingBackEdges(block)) {
    344           // In case of loops, we do not update the effect phi immediately
    345           // because the back predecessor has not been handled yet. We just
    346           // record the effect phi for later processing.
    347           pending_effect_phis.push_back(PendingEffectPhi(node, block));
    348         } else {
    349           UpdateEffectPhi(node, block, &block_effects);
    350         }
    351       } else if (node->opcode() == IrOpcode::kPhi) {
    352         // Just skip phis.
    353       } else if (node->opcode() == IrOpcode::kTerminate) {
    354         DCHECK(terminate == nullptr);
    355         terminate = node;
    356       } else {
    357         break;
    358       }
    359     }
    360 
    361     if (effect == nullptr) {
    362       // There was no effect phi.
    363       DCHECK(!HasIncomingBackEdges(block));
    364       if (block == schedule()->start()) {
    365         // Start block => effect is start.
    366         DCHECK_EQ(graph()->start(), control);
    367         effect = graph()->start();
    368       } else if (control->opcode() == IrOpcode::kEnd) {
    369         // End block is just a dummy, no effect needed.
    370         DCHECK_EQ(BasicBlock::kNone, block->control());
    371         DCHECK_EQ(1u, block->size());
    372         effect = nullptr;
    373       } else {
    374         // If all the predecessors have the same effect, we can use it as our
    375         // current effect.
    376         effect =
    377             block_effects.For(block->PredecessorAt(0), block).current_effect;
    378         for (size_t i = 1; i < block->PredecessorCount(); ++i) {
    379           if (block_effects.For(block->PredecessorAt(i), block)
    380                   .current_effect != effect) {
    381             effect = nullptr;
    382             break;
    383           }
    384         }
    385         if (effect == nullptr) {
    386           DCHECK_NE(IrOpcode::kIfException, control->opcode());
    387           // The input blocks do not have the same effect. We have
    388           // to create an effect phi node.
    389           inputs_buffer.clear();
    390           inputs_buffer.resize(block->PredecessorCount(), jsgraph()->Dead());
    391           inputs_buffer.push_back(control);
    392           effect = graph()->NewNode(
    393               common()->EffectPhi(static_cast<int>(block->PredecessorCount())),
    394               static_cast<int>(inputs_buffer.size()), &(inputs_buffer.front()));
    395           // For loops, we update the effect phi node later to break cycles.
    396           if (control->opcode() == IrOpcode::kLoop) {
    397             pending_effect_phis.push_back(PendingEffectPhi(effect, block));
    398           } else {
    399             UpdateEffectPhi(effect, block, &block_effects);
    400           }
    401         } else if (control->opcode() == IrOpcode::kIfException) {
    402           // The IfException is connected into the effect chain, so we need
    403           // to update the effect here.
    404           NodeProperties::ReplaceEffectInput(control, effect);
    405           effect = control;
    406         }
    407       }
    408     }
    409 
    410     // Fixup the Terminate node.
    411     if (terminate != nullptr) {
    412       NodeProperties::ReplaceEffectInput(terminate, effect);
    413     }
    414 
    415     // The frame state at block entry is determined by the frame states leaving
    416     // all predecessors. In case there is no frame state dominating this block,
    417     // we can rely on a checkpoint being present before the next deoptimization.
    418     // TODO(mstarzinger): Eventually we will need to go hunt for a frame state
    419     // once deoptimizing nodes roam freely through the schedule.
    420     Node* frame_state = nullptr;
    421     if (block != schedule()->start()) {
    422       // If all the predecessors have the same effect, we can use it
    423       // as our current effect.
    424       frame_state =
    425           block_effects.For(block->PredecessorAt(0), block).current_frame_state;
    426       for (size_t i = 1; i < block->PredecessorCount(); i++) {
    427         if (block_effects.For(block->PredecessorAt(i), block)
    428                 .current_frame_state != frame_state) {
    429           frame_state = nullptr;
    430           break;
    431         }
    432       }
    433     }
    434 
    435     // Process the ordinary instructions.
    436     for (; instr < block->NodeCount(); instr++) {
    437       Node* node = block->NodeAt(instr);
    438       ProcessNode(node, &frame_state, &effect, &control);
    439     }
    440 
    441     switch (block->control()) {
    442       case BasicBlock::kGoto:
    443       case BasicBlock::kNone:
    444         break;
    445 
    446       case BasicBlock::kCall:
    447       case BasicBlock::kTailCall:
    448       case BasicBlock::kSwitch:
    449       case BasicBlock::kReturn:
    450       case BasicBlock::kDeoptimize:
    451       case BasicBlock::kThrow:
    452         ProcessNode(block->control_input(), &frame_state, &effect, &control);
    453         break;
    454 
    455       case BasicBlock::kBranch:
    456         ProcessNode(block->control_input(), &frame_state, &effect, &control);
    457         TryCloneBranch(block->control_input(), block, graph(), common(),
    458                        &block_effects, source_positions_);
    459         break;
    460     }
    461 
    462     // Store the effect, control and frame state for later use.
    463     for (BasicBlock* successor : block->successors()) {
    464       BlockEffectControlData* data = &block_effects.For(block, successor);
    465       if (data->current_effect == nullptr) {
    466         data->current_effect = effect;
    467       }
    468       if (data->current_control == nullptr) {
    469         data->current_control = control;
    470       }
    471       data->current_frame_state = frame_state;
    472     }
    473   }
    474 
    475   // Update the incoming edges of the effect phis that could not be processed
    476   // during the first pass (because they could have incoming back edges).
    477   for (const PendingEffectPhi& pending_effect_phi : pending_effect_phis) {
    478     UpdateEffectPhi(pending_effect_phi.effect_phi, pending_effect_phi.block,
    479                     &block_effects);
    480   }
    481   for (BasicBlock* pending_block_control : pending_block_controls) {
    482     UpdateBlockControl(pending_block_control, &block_effects);
    483   }
    484 }
    485 
    486 namespace {
    487 
    488 void TryScheduleCallIfSuccess(Node* node, Node** control) {
    489   // Schedule the call's IfSuccess node if there is no exception use.
    490   if (!NodeProperties::IsExceptionalCall(node)) {
    491     for (Edge edge : node->use_edges()) {
    492       if (NodeProperties::IsControlEdge(edge) &&
    493           edge.from()->opcode() == IrOpcode::kIfSuccess) {
    494         *control = edge.from();
    495       }
    496     }
    497   }
    498 }
    499 
    500 }  // namespace
    501 
    502 void EffectControlLinearizer::ProcessNode(Node* node, Node** frame_state,
    503                                           Node** effect, Node** control) {
    504   SourcePositionTable::Scope scope(source_positions_,
    505                                    source_positions_->GetSourcePosition(node));
    506 
    507   // If the node needs to be wired into the effect/control chain, do this
    508   // here. Pass current frame state for lowering to eager deoptimization.
    509   if (TryWireInStateEffect(node, *frame_state, effect, control)) {
    510     return;
    511   }
    512 
    513   // If the node has a visible effect, then there must be a checkpoint in the
    514   // effect chain before we are allowed to place another eager deoptimization
    515   // point. We zap the frame state to ensure this invariant is maintained.
    516   if (region_observability_ == RegionObservability::kObservable &&
    517       !node->op()->HasProperty(Operator::kNoWrite)) {
    518     *frame_state = nullptr;
    519   }
    520 
    521   // Remove the end markers of 'atomic' allocation region because the
    522   // region should be wired-in now.
    523   if (node->opcode() == IrOpcode::kFinishRegion) {
    524     // Reset the current region observability.
    525     region_observability_ = RegionObservability::kObservable;
    526     // Update the value uses to the value input of the finish node and
    527     // the effect uses to the effect input.
    528     return RemoveRegionNode(node);
    529   }
    530   if (node->opcode() == IrOpcode::kBeginRegion) {
    531     // Determine the observability for this region and use that for all
    532     // nodes inside the region (i.e. ignore the absence of kNoWrite on
    533     // StoreField and other operators).
    534     DCHECK_NE(RegionObservability::kNotObservable, region_observability_);
    535     region_observability_ = RegionObservabilityOf(node->op());
    536     // Update the value uses to the value input of the finish node and
    537     // the effect uses to the effect input.
    538     return RemoveRegionNode(node);
    539   }
    540 
    541   // Special treatment for checkpoint nodes.
    542   if (node->opcode() == IrOpcode::kCheckpoint) {
    543     // Unlink the check point; effect uses will be updated to the incoming
    544     // effect that is passed. The frame state is preserved for lowering.
    545     DCHECK_EQ(RegionObservability::kObservable, region_observability_);
    546     *frame_state = NodeProperties::GetFrameStateInput(node);
    547     return;
    548   }
    549 
    550   if (node->opcode() == IrOpcode::kIfSuccess) {
    551     // We always schedule IfSuccess with its call, so skip it here.
    552     DCHECK_EQ(IrOpcode::kCall, node->InputAt(0)->opcode());
    553     // The IfSuccess node should not belong to an exceptional call node
    554     // because such IfSuccess nodes should only start a basic block (and
    555     // basic block start nodes are not handled in the ProcessNode method).
    556     DCHECK(!NodeProperties::IsExceptionalCall(node->InputAt(0)));
    557     return;
    558   }
    559 
    560   // If the node takes an effect, replace with the current one.
    561   if (node->op()->EffectInputCount() > 0) {
    562     DCHECK_EQ(1, node->op()->EffectInputCount());
    563     Node* input_effect = NodeProperties::GetEffectInput(node);
    564 
    565     if (input_effect != *effect) {
    566       NodeProperties::ReplaceEffectInput(node, *effect);
    567     }
    568 
    569     // If the node produces an effect, update our current effect. (However,
    570     // ignore new effect chains started with ValueEffect.)
    571     if (node->op()->EffectOutputCount() > 0) {
    572       DCHECK_EQ(1, node->op()->EffectOutputCount());
    573       *effect = node;
    574     }
    575   } else {
    576     // New effect chain is only started with a Start or ValueEffect node.
    577     DCHECK(node->op()->EffectOutputCount() == 0 ||
    578            node->opcode() == IrOpcode::kStart);
    579   }
    580 
    581   // Rewire control inputs.
    582   for (int i = 0; i < node->op()->ControlInputCount(); i++) {
    583     NodeProperties::ReplaceControlInput(node, *control, i);
    584   }
    585   // Update the current control and wire IfSuccess right after calls.
    586   if (node->op()->ControlOutputCount() > 0) {
    587     *control = node;
    588     if (node->opcode() == IrOpcode::kCall) {
    589       // Schedule the call's IfSuccess node (if there is no exception use).
    590       TryScheduleCallIfSuccess(node, control);
    591     }
    592   }
    593 }
    594 
    595 bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
    596                                                    Node* frame_state,
    597                                                    Node** effect,
    598                                                    Node** control) {
    599   ValueEffectControl state(nullptr, nullptr, nullptr);
    600   switch (node->opcode()) {
    601     case IrOpcode::kChangeBitToTagged:
    602       state = LowerChangeBitToTagged(node, *effect, *control);
    603       break;
    604     case IrOpcode::kChangeInt31ToTaggedSigned:
    605       state = LowerChangeInt31ToTaggedSigned(node, *effect, *control);
    606       break;
    607     case IrOpcode::kChangeInt32ToTagged:
    608       state = LowerChangeInt32ToTagged(node, *effect, *control);
    609       break;
    610     case IrOpcode::kChangeUint32ToTagged:
    611       state = LowerChangeUint32ToTagged(node, *effect, *control);
    612       break;
    613     case IrOpcode::kChangeFloat64ToTagged:
    614       state = LowerChangeFloat64ToTagged(node, *effect, *control);
    615       break;
    616     case IrOpcode::kChangeFloat64ToTaggedPointer:
    617       state = LowerChangeFloat64ToTaggedPointer(node, *effect, *control);
    618       break;
    619     case IrOpcode::kChangeTaggedSignedToInt32:
    620       state = LowerChangeTaggedSignedToInt32(node, *effect, *control);
    621       break;
    622     case IrOpcode::kChangeTaggedToBit:
    623       state = LowerChangeTaggedToBit(node, *effect, *control);
    624       break;
    625     case IrOpcode::kChangeTaggedToInt32:
    626       state = LowerChangeTaggedToInt32(node, *effect, *control);
    627       break;
    628     case IrOpcode::kChangeTaggedToUint32:
    629       state = LowerChangeTaggedToUint32(node, *effect, *control);
    630       break;
    631     case IrOpcode::kChangeTaggedToFloat64:
    632       state = LowerChangeTaggedToFloat64(node, *effect, *control);
    633       break;
    634     case IrOpcode::kTruncateTaggedToBit:
    635       state = LowerTruncateTaggedToBit(node, *effect, *control);
    636       break;
    637     case IrOpcode::kTruncateTaggedToFloat64:
    638       state = LowerTruncateTaggedToFloat64(node, *effect, *control);
    639       break;
    640     case IrOpcode::kCheckBounds:
    641       state = LowerCheckBounds(node, frame_state, *effect, *control);
    642       break;
    643     case IrOpcode::kCheckMaps:
    644       state = LowerCheckMaps(node, frame_state, *effect, *control);
    645       break;
    646     case IrOpcode::kCheckNumber:
    647       state = LowerCheckNumber(node, frame_state, *effect, *control);
    648       break;
    649     case IrOpcode::kCheckString:
    650       state = LowerCheckString(node, frame_state, *effect, *control);
    651       break;
    652     case IrOpcode::kCheckIf:
    653       state = LowerCheckIf(node, frame_state, *effect, *control);
    654       break;
    655     case IrOpcode::kCheckedInt32Add:
    656       state = LowerCheckedInt32Add(node, frame_state, *effect, *control);
    657       break;
    658     case IrOpcode::kCheckedInt32Sub:
    659       state = LowerCheckedInt32Sub(node, frame_state, *effect, *control);
    660       break;
    661     case IrOpcode::kCheckedInt32Div:
    662       state = LowerCheckedInt32Div(node, frame_state, *effect, *control);
    663       break;
    664     case IrOpcode::kCheckedInt32Mod:
    665       state = LowerCheckedInt32Mod(node, frame_state, *effect, *control);
    666       break;
    667     case IrOpcode::kCheckedUint32Div:
    668       state = LowerCheckedUint32Div(node, frame_state, *effect, *control);
    669       break;
    670     case IrOpcode::kCheckedUint32Mod:
    671       state = LowerCheckedUint32Mod(node, frame_state, *effect, *control);
    672       break;
    673     case IrOpcode::kCheckedInt32Mul:
    674       state = LowerCheckedInt32Mul(node, frame_state, *effect, *control);
    675       break;
    676     case IrOpcode::kCheckedInt32ToTaggedSigned:
    677       state =
    678           LowerCheckedInt32ToTaggedSigned(node, frame_state, *effect, *control);
    679       break;
    680     case IrOpcode::kCheckedUint32ToInt32:
    681       state = LowerCheckedUint32ToInt32(node, frame_state, *effect, *control);
    682       break;
    683     case IrOpcode::kCheckedUint32ToTaggedSigned:
    684       state = LowerCheckedUint32ToTaggedSigned(node, frame_state, *effect,
    685                                                *control);
    686       break;
    687     case IrOpcode::kCheckedFloat64ToInt32:
    688       state = LowerCheckedFloat64ToInt32(node, frame_state, *effect, *control);
    689       break;
    690     case IrOpcode::kCheckedTaggedSignedToInt32:
    691       state =
    692           LowerCheckedTaggedSignedToInt32(node, frame_state, *effect, *control);
    693       break;
    694     case IrOpcode::kCheckedTaggedToInt32:
    695       state = LowerCheckedTaggedToInt32(node, frame_state, *effect, *control);
    696       break;
    697     case IrOpcode::kCheckedTaggedToFloat64:
    698       state = LowerCheckedTaggedToFloat64(node, frame_state, *effect, *control);
    699       break;
    700     case IrOpcode::kCheckedTaggedToTaggedSigned:
    701       state = LowerCheckedTaggedToTaggedSigned(node, frame_state, *effect,
    702                                                *control);
    703       break;
    704     case IrOpcode::kCheckedTaggedToTaggedPointer:
    705       state = LowerCheckedTaggedToTaggedPointer(node, frame_state, *effect,
    706                                                 *control);
    707       break;
    708     case IrOpcode::kTruncateTaggedToWord32:
    709       state = LowerTruncateTaggedToWord32(node, *effect, *control);
    710       break;
    711     case IrOpcode::kCheckedTruncateTaggedToWord32:
    712       state = LowerCheckedTruncateTaggedToWord32(node, frame_state, *effect,
    713                                                  *control);
    714       break;
    715     case IrOpcode::kObjectIsCallable:
    716       state = LowerObjectIsCallable(node, *effect, *control);
    717       break;
    718     case IrOpcode::kObjectIsNumber:
    719       state = LowerObjectIsNumber(node, *effect, *control);
    720       break;
    721     case IrOpcode::kObjectIsReceiver:
    722       state = LowerObjectIsReceiver(node, *effect, *control);
    723       break;
    724     case IrOpcode::kObjectIsSmi:
    725       state = LowerObjectIsSmi(node, *effect, *control);
    726       break;
    727     case IrOpcode::kObjectIsString:
    728       state = LowerObjectIsString(node, *effect, *control);
    729       break;
    730     case IrOpcode::kObjectIsUndetectable:
    731       state = LowerObjectIsUndetectable(node, *effect, *control);
    732       break;
    733     case IrOpcode::kArrayBufferWasNeutered:
    734       state = LowerArrayBufferWasNeutered(node, *effect, *control);
    735       break;
    736     case IrOpcode::kStringFromCharCode:
    737       state = LowerStringFromCharCode(node, *effect, *control);
    738       break;
    739     case IrOpcode::kStringFromCodePoint:
    740       state = LowerStringFromCodePoint(node, *effect, *control);
    741       break;
    742     case IrOpcode::kStringCharCodeAt:
    743       state = LowerStringCharCodeAt(node, *effect, *control);
    744       break;
    745     case IrOpcode::kStringEqual:
    746       state = LowerStringEqual(node, *effect, *control);
    747       break;
    748     case IrOpcode::kStringLessThan:
    749       state = LowerStringLessThan(node, *effect, *control);
    750       break;
    751     case IrOpcode::kStringLessThanOrEqual:
    752       state = LowerStringLessThanOrEqual(node, *effect, *control);
    753       break;
    754     case IrOpcode::kCheckFloat64Hole:
    755       state = LowerCheckFloat64Hole(node, frame_state, *effect, *control);
    756       break;
    757     case IrOpcode::kCheckTaggedHole:
    758       state = LowerCheckTaggedHole(node, frame_state, *effect, *control);
    759       break;
    760     case IrOpcode::kConvertTaggedHoleToUndefined:
    761       state = LowerConvertTaggedHoleToUndefined(node, *effect, *control);
    762       break;
    763     case IrOpcode::kPlainPrimitiveToNumber:
    764       state = LowerPlainPrimitiveToNumber(node, *effect, *control);
    765       break;
    766     case IrOpcode::kPlainPrimitiveToWord32:
    767       state = LowerPlainPrimitiveToWord32(node, *effect, *control);
    768       break;
    769     case IrOpcode::kPlainPrimitiveToFloat64:
    770       state = LowerPlainPrimitiveToFloat64(node, *effect, *control);
    771       break;
    772     case IrOpcode::kEnsureWritableFastElements:
    773       state = LowerEnsureWritableFastElements(node, *effect, *control);
    774       break;
    775     case IrOpcode::kMaybeGrowFastElements:
    776       state = LowerMaybeGrowFastElements(node, frame_state, *effect, *control);
    777       break;
    778     case IrOpcode::kTransitionElementsKind:
    779       state = LowerTransitionElementsKind(node, *effect, *control);
    780       break;
    781     case IrOpcode::kLoadTypedElement:
    782       state = LowerLoadTypedElement(node, *effect, *control);
    783       break;
    784     case IrOpcode::kStoreTypedElement:
    785       state = LowerStoreTypedElement(node, *effect, *control);
    786       break;
    787     case IrOpcode::kFloat64RoundUp:
    788       state = LowerFloat64RoundUp(node, *effect, *control);
    789       break;
    790     case IrOpcode::kFloat64RoundDown:
    791       state = LowerFloat64RoundDown(node, *effect, *control);
    792       break;
    793     case IrOpcode::kFloat64RoundTruncate:
    794       state = LowerFloat64RoundTruncate(node, *effect, *control);
    795       break;
    796     case IrOpcode::kFloat64RoundTiesEven:
    797       state = LowerFloat64RoundTiesEven(node, *effect, *control);
    798       break;
    799     default:
    800       return false;
    801   }
    802   NodeProperties::ReplaceUses(node, state.value, state.effect, state.control);
    803   *effect = state.effect;
    804   *control = state.control;
    805   return true;
    806 }
    807 
    808 EffectControlLinearizer::ValueEffectControl
    809 EffectControlLinearizer::LowerChangeFloat64ToTagged(Node* node, Node* effect,
    810                                                     Node* control) {
    811   Node* value = node->InputAt(0);
    812   return AllocateHeapNumberWithValue(value, effect, control);
    813 }
    814 
    815 EffectControlLinearizer::ValueEffectControl
    816 EffectControlLinearizer::LowerChangeFloat64ToTaggedPointer(Node* node,
    817                                                            Node* effect,
    818                                                            Node* control) {
    819   Node* value = node->InputAt(0);
    820   return AllocateHeapNumberWithValue(value, effect, control);
    821 }
    822 
    823 EffectControlLinearizer::ValueEffectControl
    824 EffectControlLinearizer::LowerChangeBitToTagged(Node* node, Node* effect,
    825                                                 Node* control) {
    826   Node* value = node->InputAt(0);
    827 
    828   Node* branch = graph()->NewNode(common()->Branch(), value, control);
    829 
    830   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
    831   Node* vtrue = jsgraph()->TrueConstant();
    832 
    833   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
    834   Node* vfalse = jsgraph()->FalseConstant();
    835 
    836   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
    837   value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
    838                            vtrue, vfalse, control);
    839 
    840   return ValueEffectControl(value, effect, control);
    841 }
    842 
    843 EffectControlLinearizer::ValueEffectControl
    844 EffectControlLinearizer::LowerChangeInt31ToTaggedSigned(Node* node,
    845                                                         Node* effect,
    846                                                         Node* control) {
    847   Node* value = node->InputAt(0);
    848   value = ChangeInt32ToSmi(value);
    849   return ValueEffectControl(value, effect, control);
    850 }
    851 
    852 EffectControlLinearizer::ValueEffectControl
    853 EffectControlLinearizer::LowerChangeInt32ToTagged(Node* node, Node* effect,
    854                                                   Node* control) {
    855   Node* value = node->InputAt(0);
    856 
    857   if (machine()->Is64()) {
    858     return ValueEffectControl(ChangeInt32ToSmi(value), effect, control);
    859   }
    860 
    861   Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), value, value,
    862                                control);
    863 
    864   Node* ovf = graph()->NewNode(common()->Projection(1), add, control);
    865   Node* branch =
    866       graph()->NewNode(common()->Branch(BranchHint::kFalse), ovf, control);
    867 
    868   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
    869   ValueEffectControl alloc =
    870       AllocateHeapNumberWithValue(ChangeInt32ToFloat64(value), effect, if_true);
    871 
    872   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
    873   Node* vfalse = graph()->NewNode(common()->Projection(0), add, if_false);
    874 
    875   Node* merge = graph()->NewNode(common()->Merge(2), alloc.control, if_false);
    876   Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
    877                                alloc.value, vfalse, merge);
    878   Node* ephi =
    879       graph()->NewNode(common()->EffectPhi(2), alloc.effect, effect, merge);
    880 
    881   return ValueEffectControl(phi, ephi, merge);
    882 }
    883 
    884 EffectControlLinearizer::ValueEffectControl
    885 EffectControlLinearizer::LowerChangeUint32ToTagged(Node* node, Node* effect,
    886                                                    Node* control) {
    887   Node* value = node->InputAt(0);
    888 
    889   Node* check = graph()->NewNode(machine()->Uint32LessThanOrEqual(), value,
    890                                  SmiMaxValueConstant());
    891   Node* branch =
    892       graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
    893 
    894   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
    895   Node* vtrue = ChangeUint32ToSmi(value);
    896 
    897   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
    898   ValueEffectControl alloc = AllocateHeapNumberWithValue(
    899       ChangeUint32ToFloat64(value), effect, if_false);
    900 
    901   Node* merge = graph()->NewNode(common()->Merge(2), if_true, alloc.control);
    902   Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
    903                                vtrue, alloc.value, merge);
    904   Node* ephi =
    905       graph()->NewNode(common()->EffectPhi(2), effect, alloc.effect, merge);
    906 
    907   return ValueEffectControl(phi, ephi, merge);
    908 }
    909 
    910 EffectControlLinearizer::ValueEffectControl
    911 EffectControlLinearizer::LowerChangeTaggedSignedToInt32(Node* node,
    912                                                         Node* effect,
    913                                                         Node* control) {
    914   Node* value = node->InputAt(0);
    915   value = ChangeSmiToInt32(value);
    916   return ValueEffectControl(value, effect, control);
    917 }
    918 
    919 EffectControlLinearizer::ValueEffectControl
    920 EffectControlLinearizer::LowerChangeTaggedToBit(Node* node, Node* effect,
    921                                                 Node* control) {
    922   Node* value = node->InputAt(0);
    923   value = graph()->NewNode(machine()->WordEqual(), value,
    924                            jsgraph()->TrueConstant());
    925   return ValueEffectControl(value, effect, control);
    926 }
    927 
    928 EffectControlLinearizer::ValueEffectControl
    929 EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node, Node* effect,
    930                                                   Node* control) {
    931   Node* value = node->InputAt(0);
    932   Node* zero = jsgraph()->Int32Constant(0);
    933   Node* fzero = jsgraph()->Float64Constant(0.0);
    934 
    935   // Collect effect/control/value triples.
    936   int count = 0;
    937   Node* values[6];
    938   Node* effects[6];
    939   Node* controls[5];
    940 
    941   // Check if {value} is a Smi.
    942   Node* check_smi = ObjectIsSmi(value);
    943   Node* branch_smi = graph()->NewNode(common()->Branch(BranchHint::kFalse),
    944                                       check_smi, control);
    945 
    946   // If {value} is a Smi, then we only need to check that it's not zero.
    947   Node* if_smi = graph()->NewNode(common()->IfTrue(), branch_smi);
    948   Node* esmi = effect;
    949   {
    950     controls[count] = if_smi;
    951     effects[count] = esmi;
    952     values[count] =
    953         graph()->NewNode(machine()->Word32Equal(),
    954                          graph()->NewNode(machine()->WordEqual(), value,
    955                                           jsgraph()->IntPtrConstant(0)),
    956                          zero);
    957     count++;
    958   }
    959   control = graph()->NewNode(common()->IfFalse(), branch_smi);
    960 
    961   // Load the map instance type of {value}.
    962   Node* value_map = effect = graph()->NewNode(
    963       simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control);
    964   Node* value_instance_type = effect = graph()->NewNode(
    965       simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map,
    966       effect, control);
    967 
    968   // Check if {value} is an Oddball.
    969   Node* check_oddball =
    970       graph()->NewNode(machine()->Word32Equal(), value_instance_type,
    971                        jsgraph()->Int32Constant(ODDBALL_TYPE));
    972   Node* branch_oddball = graph()->NewNode(common()->Branch(BranchHint::kTrue),
    973                                           check_oddball, control);
    974 
    975   // The only Oddball {value} that is trueish is true itself.
    976   Node* if_oddball = graph()->NewNode(common()->IfTrue(), branch_oddball);
    977   Node* eoddball = effect;
    978   {
    979     controls[count] = if_oddball;
    980     effects[count] = eoddball;
    981     values[count] = graph()->NewNode(machine()->WordEqual(), value,
    982                                      jsgraph()->TrueConstant());
    983     count++;
    984   }
    985   control = graph()->NewNode(common()->IfFalse(), branch_oddball);
    986 
    987   // Check if {value} is a String.
    988   Node* check_string =
    989       graph()->NewNode(machine()->Int32LessThan(), value_instance_type,
    990                        jsgraph()->Int32Constant(FIRST_NONSTRING_TYPE));
    991   Node* branch_string =
    992       graph()->NewNode(common()->Branch(), check_string, control);
    993 
    994   // For String {value}, we need to check that the length is not zero.
    995   Node* if_string = graph()->NewNode(common()->IfTrue(), branch_string);
    996   Node* estring = effect;
    997   {
    998     // Load the {value} length.
    999     Node* value_length = estring = graph()->NewNode(
   1000         simplified()->LoadField(AccessBuilder::ForStringLength()), value,
   1001         estring, if_string);
   1002 
   1003     controls[count] = if_string;
   1004     effects[count] = estring;
   1005     values[count] =
   1006         graph()->NewNode(machine()->Word32Equal(),
   1007                          graph()->NewNode(machine()->WordEqual(), value_length,
   1008                                           jsgraph()->IntPtrConstant(0)),
   1009                          zero);
   1010     count++;
   1011   }
   1012   control = graph()->NewNode(common()->IfFalse(), branch_string);
   1013 
   1014   // Check if {value} is a HeapNumber.
   1015   Node* check_heapnumber =
   1016       graph()->NewNode(machine()->Word32Equal(), value_instance_type,
   1017                        jsgraph()->Int32Constant(HEAP_NUMBER_TYPE));
   1018   Node* branch_heapnumber =
   1019       graph()->NewNode(common()->Branch(), check_heapnumber, control);
   1020 
   1021   // For HeapNumber {value}, just check that its value is not 0.0, -0.0 or NaN.
   1022   Node* if_heapnumber = graph()->NewNode(common()->IfTrue(), branch_heapnumber);
   1023   Node* eheapnumber = effect;
   1024   {
   1025     // Load the raw value of {value}.
   1026     Node* value_value = eheapnumber = graph()->NewNode(
   1027         simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
   1028         eheapnumber, if_heapnumber);
   1029 
   1030     // Check if {value} is not one of 0, -0, or NaN.
   1031     controls[count] = if_heapnumber;
   1032     effects[count] = eheapnumber;
   1033     values[count] = graph()->NewNode(
   1034         machine()->Float64LessThan(), fzero,
   1035         graph()->NewNode(machine()->Float64Abs(), value_value));
   1036     count++;
   1037   }
   1038   control = graph()->NewNode(common()->IfFalse(), branch_heapnumber);
   1039 
   1040   // The {value} is either a JSReceiver, a Symbol or some Simd128Value. In
   1041   // those cases we can just the undetectable bit on the map, which will only
   1042   // be set for certain JSReceivers, i.e. document.all.
   1043   {
   1044     // Load the {value} map bit field.
   1045     Node* value_map_bitfield = effect = graph()->NewNode(
   1046         simplified()->LoadField(AccessBuilder::ForMapBitField()), value_map,
   1047         effect, control);
   1048 
   1049     controls[count] = control;
   1050     effects[count] = effect;
   1051     values[count] = graph()->NewNode(
   1052         machine()->Word32Equal(),
   1053         graph()->NewNode(machine()->Word32And(), value_map_bitfield,
   1054                          jsgraph()->Int32Constant(1 << Map::kIsUndetectable)),
   1055         zero);
   1056     count++;
   1057   }
   1058 
   1059   // Merge the different controls.
   1060   control = graph()->NewNode(common()->Merge(count), count, controls);
   1061   effects[count] = control;
   1062   effect = graph()->NewNode(common()->EffectPhi(count), count + 1, effects);
   1063   values[count] = control;
   1064   value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, count),
   1065                            count + 1, values);
   1066 
   1067   return ValueEffectControl(value, effect, control);
   1068 }
   1069 
   1070 EffectControlLinearizer::ValueEffectControl
   1071 EffectControlLinearizer::LowerChangeTaggedToInt32(Node* node, Node* effect,
   1072                                                   Node* control) {
   1073   Node* value = node->InputAt(0);
   1074 
   1075   Node* check = ObjectIsSmi(value);
   1076   Node* branch =
   1077       graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
   1078 
   1079   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
   1080   Node* etrue = effect;
   1081   Node* vtrue = ChangeSmiToInt32(value);
   1082 
   1083   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
   1084   Node* efalse = effect;
   1085   Node* vfalse;
   1086   {
   1087     STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
   1088     vfalse = efalse = graph()->NewNode(
   1089         simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
   1090         efalse, if_false);
   1091     vfalse = graph()->NewNode(machine()->ChangeFloat64ToInt32(), vfalse);
   1092   }
   1093 
   1094   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
   1095   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
   1096   value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
   1097                            vtrue, vfalse, control);
   1098 
   1099   return ValueEffectControl(value, effect, control);
   1100 }
   1101 
   1102 EffectControlLinearizer::ValueEffectControl
   1103 EffectControlLinearizer::LowerChangeTaggedToUint32(Node* node, Node* effect,
   1104                                                    Node* control) {
   1105   Node* value = node->InputAt(0);
   1106 
   1107   Node* check = ObjectIsSmi(value);
   1108   Node* branch =
   1109       graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
   1110 
   1111   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
   1112   Node* etrue = effect;
   1113   Node* vtrue = ChangeSmiToInt32(value);
   1114 
   1115   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
   1116   Node* efalse = effect;
   1117   Node* vfalse;
   1118   {
   1119     STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
   1120     vfalse = efalse = graph()->NewNode(
   1121         simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
   1122         efalse, if_false);
   1123     vfalse = graph()->NewNode(machine()->ChangeFloat64ToUint32(), vfalse);
   1124   }
   1125 
   1126   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
   1127   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
   1128   value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
   1129                            vtrue, vfalse, control);
   1130 
   1131   return ValueEffectControl(value, effect, control);
   1132 }
   1133 
   1134 EffectControlLinearizer::ValueEffectControl
   1135 EffectControlLinearizer::LowerChangeTaggedToFloat64(Node* node, Node* effect,
   1136                                                     Node* control) {
   1137   return LowerTruncateTaggedToFloat64(node, effect, control);
   1138 }
   1139 
   1140 EffectControlLinearizer::ValueEffectControl
   1141 EffectControlLinearizer::LowerTruncateTaggedToFloat64(Node* node, Node* effect,
   1142                                                       Node* control) {
   1143   Node* value = node->InputAt(0);
   1144 
   1145   Node* check = ObjectIsSmi(value);
   1146   Node* branch =
   1147       graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
   1148 
   1149   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
   1150   Node* etrue = effect;
   1151   Node* vtrue;
   1152   {
   1153     vtrue = ChangeSmiToInt32(value);
   1154     vtrue = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue);
   1155   }
   1156 
   1157   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
   1158   Node* efalse = effect;
   1159   Node* vfalse;
   1160   {
   1161     STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
   1162     vfalse = efalse = graph()->NewNode(
   1163         simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
   1164         efalse, if_false);
   1165   }
   1166 
   1167   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
   1168   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
   1169   value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
   1170                            vtrue, vfalse, control);
   1171 
   1172   return ValueEffectControl(value, effect, control);
   1173 }
   1174 
   1175 EffectControlLinearizer::ValueEffectControl
   1176 EffectControlLinearizer::LowerCheckBounds(Node* node, Node* frame_state,
   1177                                           Node* effect, Node* control) {
   1178   Node* index = node->InputAt(0);
   1179   Node* limit = node->InputAt(1);
   1180 
   1181   Node* check = graph()->NewNode(machine()->Uint32LessThan(), index, limit);
   1182   control = effect = graph()->NewNode(
   1183       common()->DeoptimizeUnless(DeoptimizeReason::kOutOfBounds), check,
   1184       frame_state, effect, control);
   1185 
   1186   return ValueEffectControl(index, effect, control);
   1187 }
   1188 
   1189 EffectControlLinearizer::ValueEffectControl
   1190 EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state,
   1191                                         Node* effect, Node* control) {
   1192   Node* value = node->InputAt(0);
   1193 
   1194   // Load the current map of the {value}.
   1195   Node* value_map = effect = graph()->NewNode(
   1196       simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control);
   1197 
   1198   int const map_count = node->op()->ValueInputCount() - 1;
   1199   Node** controls = temp_zone()->NewArray<Node*>(map_count);
   1200   Node** effects = temp_zone()->NewArray<Node*>(map_count + 1);
   1201 
   1202   for (int i = 0; i < map_count; ++i) {
   1203     Node* map = node->InputAt(1 + i);
   1204 
   1205     Node* check = graph()->NewNode(machine()->WordEqual(), value_map, map);
   1206     if (i == map_count - 1) {
   1207       controls[i] = effects[i] = graph()->NewNode(
   1208           common()->DeoptimizeUnless(DeoptimizeReason::kWrongMap), check,
   1209           frame_state, effect, control);
   1210     } else {
   1211       control = graph()->NewNode(common()->Branch(), check, control);
   1212       controls[i] = graph()->NewNode(common()->IfTrue(), control);
   1213       control = graph()->NewNode(common()->IfFalse(), control);
   1214       effects[i] = effect;
   1215     }
   1216   }
   1217 
   1218   control = graph()->NewNode(common()->Merge(map_count), map_count, controls);
   1219   effects[map_count] = control;
   1220   effect =
   1221       graph()->NewNode(common()->EffectPhi(map_count), map_count + 1, effects);
   1222 
   1223   return ValueEffectControl(value, effect, control);
   1224 }
   1225 
   1226 EffectControlLinearizer::ValueEffectControl
   1227 EffectControlLinearizer::LowerCheckNumber(Node* node, Node* frame_state,
   1228                                           Node* effect, Node* control) {
   1229   Node* value = node->InputAt(0);
   1230 
   1231   Node* check0 = ObjectIsSmi(value);
   1232   Node* branch0 =
   1233       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
   1234 
   1235   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
   1236   Node* etrue0 = effect;
   1237 
   1238   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
   1239   Node* efalse0 = effect;
   1240   {
   1241     Node* value_map = efalse0 =
   1242         graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
   1243                          value, efalse0, if_false0);
   1244     Node* check1 = graph()->NewNode(machine()->WordEqual(), value_map,
   1245                                     jsgraph()->HeapNumberMapConstant());
   1246     if_false0 = efalse0 = graph()->NewNode(
   1247         common()->DeoptimizeUnless(DeoptimizeReason::kNotAHeapNumber), check1,
   1248         frame_state, efalse0, if_false0);
   1249   }
   1250 
   1251   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
   1252   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
   1253 
   1254   return ValueEffectControl(value, effect, control);
   1255 }
   1256 
   1257 EffectControlLinearizer::ValueEffectControl
   1258 EffectControlLinearizer::LowerCheckString(Node* node, Node* frame_state,
   1259                                           Node* effect, Node* control) {
   1260   Node* value = node->InputAt(0);
   1261 
   1262   Node* check0 = ObjectIsSmi(value);
   1263   control = effect =
   1264       graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kSmi), check0,
   1265                        frame_state, effect, control);
   1266 
   1267   Node* value_map = effect = graph()->NewNode(
   1268       simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control);
   1269   Node* value_instance_type = effect = graph()->NewNode(
   1270       simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map,
   1271       effect, control);
   1272 
   1273   Node* check1 =
   1274       graph()->NewNode(machine()->Uint32LessThan(), value_instance_type,
   1275                        jsgraph()->Uint32Constant(FIRST_NONSTRING_TYPE));
   1276   control = effect = graph()->NewNode(
   1277       common()->DeoptimizeUnless(DeoptimizeReason::kWrongInstanceType), check1,
   1278       frame_state, effect, control);
   1279 
   1280   return ValueEffectControl(value, effect, control);
   1281 }
   1282 
   1283 EffectControlLinearizer::ValueEffectControl
   1284 EffectControlLinearizer::LowerCheckIf(Node* node, Node* frame_state,
   1285                                       Node* effect, Node* control) {
   1286   Node* value = node->InputAt(0);
   1287 
   1288   control = effect =
   1289       graph()->NewNode(common()->DeoptimizeUnless(DeoptimizeReason::kNoReason),
   1290                        value, frame_state, effect, control);
   1291 
   1292   return ValueEffectControl(value, effect, control);
   1293 }
   1294 
   1295 EffectControlLinearizer::ValueEffectControl
   1296 EffectControlLinearizer::LowerCheckedInt32Add(Node* node, Node* frame_state,
   1297                                               Node* effect, Node* control) {
   1298   Node* lhs = node->InputAt(0);
   1299   Node* rhs = node->InputAt(1);
   1300 
   1301   Node* value =
   1302       graph()->NewNode(machine()->Int32AddWithOverflow(), lhs, rhs, control);
   1303 
   1304   Node* check = graph()->NewNode(common()->Projection(1), value, control);
   1305   control = effect =
   1306       graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kOverflow),
   1307                        check, frame_state, effect, control);
   1308 
   1309   value = graph()->NewNode(common()->Projection(0), value, control);
   1310 
   1311   return ValueEffectControl(value, effect, control);
   1312 }
   1313 
   1314 EffectControlLinearizer::ValueEffectControl
   1315 EffectControlLinearizer::LowerCheckedInt32Sub(Node* node, Node* frame_state,
   1316                                               Node* effect, Node* control) {
   1317   Node* lhs = node->InputAt(0);
   1318   Node* rhs = node->InputAt(1);
   1319 
   1320   Node* value =
   1321       graph()->NewNode(machine()->Int32SubWithOverflow(), lhs, rhs, control);
   1322 
   1323   Node* check = graph()->NewNode(common()->Projection(1), value, control);
   1324   control = effect =
   1325       graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kOverflow),
   1326                        check, frame_state, effect, control);
   1327 
   1328   value = graph()->NewNode(common()->Projection(0), value, control);
   1329 
   1330   return ValueEffectControl(value, effect, control);
   1331 }
   1332 
   1333 EffectControlLinearizer::ValueEffectControl
   1334 EffectControlLinearizer::LowerCheckedInt32Div(Node* node, Node* frame_state,
   1335                                               Node* effect, Node* control) {
   1336   Node* zero = jsgraph()->Int32Constant(0);
   1337   Node* minusone = jsgraph()->Int32Constant(-1);
   1338   Node* minint = jsgraph()->Int32Constant(std::numeric_limits<int32_t>::min());
   1339 
   1340   Node* lhs = node->InputAt(0);
   1341   Node* rhs = node->InputAt(1);
   1342 
   1343   // Check if {rhs} is positive (and not zero).
   1344   Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs);
   1345   Node* branch0 =
   1346       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
   1347 
   1348   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
   1349   Node* etrue0 = effect;
   1350   Node* vtrue0;
   1351   {
   1352     // Fast case, no additional checking required.
   1353     vtrue0 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true0);
   1354   }
   1355 
   1356   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
   1357   Node* efalse0 = effect;
   1358   Node* vfalse0;
   1359   {
   1360     // Check if {rhs} is zero.
   1361     Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
   1362     if_false0 = efalse0 = graph()->NewNode(
   1363         common()->DeoptimizeIf(DeoptimizeReason::kDivisionByZero), check,
   1364         frame_state, efalse0, if_false0);
   1365 
   1366     // Check if {lhs} is zero, as that would produce minus zero.
   1367     check = graph()->NewNode(machine()->Word32Equal(), lhs, zero);
   1368     if_false0 = efalse0 =
   1369         graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kMinusZero),
   1370                          check, frame_state, efalse0, if_false0);
   1371 
   1372     // Check if {lhs} is kMinInt and {rhs} is -1, in which case we'd have
   1373     // to return -kMinInt, which is not representable.
   1374     Node* check1 = graph()->NewNode(machine()->Word32Equal(), lhs, minint);
   1375     Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
   1376                                      check1, if_false0);
   1377 
   1378     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
   1379     Node* etrue1 = efalse0;
   1380     {
   1381       // Check if {rhs} is -1.
   1382       Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, minusone);
   1383       if_true1 = etrue1 =
   1384           graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kOverflow),
   1385                            check, frame_state, etrue1, if_true1);
   1386     }
   1387 
   1388     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
   1389     Node* efalse1 = efalse0;
   1390 
   1391     if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
   1392     efalse0 =
   1393         graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
   1394 
   1395     // Perform the actual integer division.
   1396     vfalse0 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_false0);
   1397   }
   1398 
   1399   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
   1400   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
   1401   Node* value =
   1402       graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue0,
   1403                        vfalse0, control);
   1404 
   1405   // Check if the remainder is non-zero.
   1406   Node* check =
   1407       graph()->NewNode(machine()->Word32Equal(), lhs,
   1408                        graph()->NewNode(machine()->Int32Mul(), rhs, value));
   1409   control = effect = graph()->NewNode(
   1410       common()->DeoptimizeUnless(DeoptimizeReason::kLostPrecision), check,
   1411       frame_state, effect, control);
   1412 
   1413   return ValueEffectControl(value, effect, control);
   1414 }
   1415 
   1416 EffectControlLinearizer::ValueEffectControl
   1417 EffectControlLinearizer::LowerCheckedInt32Mod(Node* node, Node* frame_state,
   1418                                               Node* effect, Node* control) {
   1419   Node* zero = jsgraph()->Int32Constant(0);
   1420   Node* one = jsgraph()->Int32Constant(1);
   1421 
   1422   // General case for signed integer modulus, with optimization for (unknown)
   1423   // power of 2 right hand side.
   1424   //
   1425   //   if rhs <= 0 then
   1426   //     rhs = -rhs
   1427   //     deopt if rhs == 0
   1428   //   if lhs < 0 then
   1429   //     let res = lhs % rhs in
   1430   //     deopt if res == 0
   1431   //     res
   1432   //   else
   1433   //     let msk = rhs - 1 in
   1434   //     if rhs & msk == 0 then
   1435   //       lhs & msk
   1436   //     else
   1437   //       lhs % rhs
   1438   //
   1439   Node* lhs = node->InputAt(0);
   1440   Node* rhs = node->InputAt(1);
   1441 
   1442   // Check if {rhs} is not strictly positive.
   1443   Node* check0 = graph()->NewNode(machine()->Int32LessThanOrEqual(), rhs, zero);
   1444   Node* branch0 =
   1445       graph()->NewNode(common()->Branch(BranchHint::kFalse), check0, control);
   1446 
   1447   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
   1448   Node* etrue0 = effect;
   1449   Node* vtrue0;
   1450   {
   1451     // Negate {rhs}, might still produce a negative result in case of
   1452     // -2^31, but that is handled safely below.
   1453     vtrue0 = graph()->NewNode(machine()->Int32Sub(), zero, rhs);
   1454 
   1455     // Ensure that {rhs} is not zero, otherwise we'd have to return NaN.
   1456     Node* check = graph()->NewNode(machine()->Word32Equal(), vtrue0, zero);
   1457     if_true0 = etrue0 = graph()->NewNode(
   1458         common()->DeoptimizeIf(DeoptimizeReason::kDivisionByZero), check,
   1459         frame_state, etrue0, if_true0);
   1460   }
   1461 
   1462   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
   1463   Node* efalse0 = effect;
   1464   Node* vfalse0 = rhs;
   1465 
   1466   // At this point {rhs} is either greater than zero or -2^31, both are
   1467   // fine for the code that follows.
   1468   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
   1469   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
   1470   rhs = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
   1471                          vtrue0, vfalse0, control);
   1472 
   1473   // Check if {lhs} is negative.
   1474   Node* check1 = graph()->NewNode(machine()->Int32LessThan(), lhs, zero);
   1475   Node* branch1 =
   1476       graph()->NewNode(common()->Branch(BranchHint::kFalse), check1, control);
   1477 
   1478   Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
   1479   Node* etrue1 = effect;
   1480   Node* vtrue1;
   1481   {
   1482     // Compute the remainder using {lhs % msk}.
   1483     vtrue1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1);
   1484 
   1485     // Check if we would have to return -0.
   1486     Node* check = graph()->NewNode(machine()->Word32Equal(), vtrue1, zero);
   1487     if_true1 = etrue1 =
   1488         graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kMinusZero),
   1489                          check, frame_state, etrue1, if_true1);
   1490   }
   1491 
   1492   Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
   1493   Node* efalse1 = effect;
   1494   Node* vfalse1;
   1495   {
   1496     Node* msk = graph()->NewNode(machine()->Int32Sub(), rhs, one);
   1497 
   1498     // Check if {rhs} minus one is a valid mask.
   1499     Node* check2 = graph()->NewNode(
   1500         machine()->Word32Equal(),
   1501         graph()->NewNode(machine()->Word32And(), rhs, msk), zero);
   1502     Node* branch2 = graph()->NewNode(common()->Branch(), check2, if_false1);
   1503 
   1504     // Compute the remainder using {lhs & msk}.
   1505     Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
   1506     Node* vtrue2 = graph()->NewNode(machine()->Word32And(), lhs, msk);
   1507 
   1508     // Compute the remainder using the generic {lhs % rhs}.
   1509     Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
   1510     Node* vfalse2 =
   1511         graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_false2);
   1512 
   1513     if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
   1514     vfalse1 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
   1515                                vtrue2, vfalse2, if_false1);
   1516   }
   1517 
   1518   control = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
   1519   effect = graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, control);
   1520   Node* value =
   1521       graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue1,
   1522                        vfalse1, control);
   1523 
   1524   return ValueEffectControl(value, effect, control);
   1525 }
   1526 
   1527 EffectControlLinearizer::ValueEffectControl
   1528 EffectControlLinearizer::LowerCheckedUint32Div(Node* node, Node* frame_state,
   1529                                                Node* effect, Node* control) {
   1530   Node* zero = jsgraph()->Int32Constant(0);
   1531 
   1532   Node* lhs = node->InputAt(0);
   1533   Node* rhs = node->InputAt(1);
   1534 
   1535   // Ensure that {rhs} is not zero, otherwise we'd have to return NaN.
   1536   Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
   1537   control = effect = graph()->NewNode(
   1538       common()->DeoptimizeIf(DeoptimizeReason::kDivisionByZero), check,
   1539       frame_state, effect, control);
   1540 
   1541   // Perform the actual unsigned integer division.
   1542   Node* value = graph()->NewNode(machine()->Uint32Div(), lhs, rhs, control);
   1543 
   1544   // Check if the remainder is non-zero.
   1545   check = graph()->NewNode(machine()->Word32Equal(), lhs,
   1546                            graph()->NewNode(machine()->Int32Mul(), rhs, value));
   1547   control = effect = graph()->NewNode(
   1548       common()->DeoptimizeUnless(DeoptimizeReason::kLostPrecision), check,
   1549       frame_state, effect, control);
   1550 
   1551   return ValueEffectControl(value, effect, control);
   1552 }
   1553 
   1554 EffectControlLinearizer::ValueEffectControl
   1555 EffectControlLinearizer::LowerCheckedUint32Mod(Node* node, Node* frame_state,
   1556                                                Node* effect, Node* control) {
   1557   Node* zero = jsgraph()->Int32Constant(0);
   1558 
   1559   Node* lhs = node->InputAt(0);
   1560   Node* rhs = node->InputAt(1);
   1561 
   1562   // Ensure that {rhs} is not zero, otherwise we'd have to return NaN.
   1563   Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
   1564   control = effect = graph()->NewNode(
   1565       common()->DeoptimizeIf(DeoptimizeReason::kDivisionByZero), check,
   1566       frame_state, effect, control);
   1567 
   1568   // Perform the actual unsigned integer modulus.
   1569   Node* value = graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, control);
   1570 
   1571   return ValueEffectControl(value, effect, control);
   1572 }
   1573 
   1574 EffectControlLinearizer::ValueEffectControl
   1575 EffectControlLinearizer::LowerCheckedInt32Mul(Node* node, Node* frame_state,
   1576                                               Node* effect, Node* control) {
   1577   CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op());
   1578   Node* zero = jsgraph()->Int32Constant(0);
   1579   Node* lhs = node->InputAt(0);
   1580   Node* rhs = node->InputAt(1);
   1581 
   1582   Node* projection =
   1583       graph()->NewNode(machine()->Int32MulWithOverflow(), lhs, rhs, control);
   1584 
   1585   Node* check = graph()->NewNode(common()->Projection(1), projection, control);
   1586   control = effect =
   1587       graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kOverflow),
   1588                        check, frame_state, effect, control);
   1589 
   1590   Node* value = graph()->NewNode(common()->Projection(0), projection, control);
   1591 
   1592   if (mode == CheckForMinusZeroMode::kCheckForMinusZero) {
   1593     Node* check_zero = graph()->NewNode(machine()->Word32Equal(), value, zero);
   1594     Node* branch_zero = graph()->NewNode(common()->Branch(BranchHint::kFalse),
   1595                                          check_zero, control);
   1596 
   1597     Node* if_zero = graph()->NewNode(common()->IfTrue(), branch_zero);
   1598     Node* e_if_zero = effect;
   1599     {
   1600       // We may need to return negative zero.
   1601       Node* or_inputs = graph()->NewNode(machine()->Word32Or(), lhs, rhs);
   1602       Node* check_or =
   1603           graph()->NewNode(machine()->Int32LessThan(), or_inputs, zero);
   1604       if_zero = e_if_zero =
   1605           graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kMinusZero),
   1606                            check_or, frame_state, e_if_zero, if_zero);
   1607     }
   1608 
   1609     Node* if_not_zero = graph()->NewNode(common()->IfFalse(), branch_zero);
   1610     Node* e_if_not_zero = effect;
   1611 
   1612     control = graph()->NewNode(common()->Merge(2), if_zero, if_not_zero);
   1613     effect = graph()->NewNode(common()->EffectPhi(2), e_if_zero, e_if_not_zero,
   1614                               control);
   1615   }
   1616 
   1617   return ValueEffectControl(value, effect, control);
   1618 }
   1619 
   1620 EffectControlLinearizer::ValueEffectControl
   1621 EffectControlLinearizer::LowerCheckedInt32ToTaggedSigned(Node* node,
   1622                                                          Node* frame_state,
   1623                                                          Node* effect,
   1624                                                          Node* control) {
   1625   DCHECK(SmiValuesAre31Bits());
   1626   Node* value = node->InputAt(0);
   1627 
   1628   Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), value, value,
   1629                                control);
   1630 
   1631   Node* check = graph()->NewNode(common()->Projection(1), add, control);
   1632   control = effect =
   1633       graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kOverflow),
   1634                        check, frame_state, effect, control);
   1635 
   1636   value = graph()->NewNode(common()->Projection(0), add, control);
   1637 
   1638   return ValueEffectControl(value, effect, control);
   1639 }
   1640 
   1641 EffectControlLinearizer::ValueEffectControl
   1642 EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node,
   1643                                                    Node* frame_state,
   1644                                                    Node* effect,
   1645                                                    Node* control) {
   1646   Node* value = node->InputAt(0);
   1647   Node* max_int = jsgraph()->Int32Constant(std::numeric_limits<int32_t>::max());
   1648   Node* is_safe =
   1649       graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, max_int);
   1650   control = effect = graph()->NewNode(
   1651       common()->DeoptimizeUnless(DeoptimizeReason::kLostPrecision), is_safe,
   1652       frame_state, effect, control);
   1653 
   1654   return ValueEffectControl(value, effect, control);
   1655 }
   1656 
   1657 EffectControlLinearizer::ValueEffectControl
   1658 EffectControlLinearizer::LowerCheckedUint32ToTaggedSigned(Node* node,
   1659                                                           Node* frame_state,
   1660                                                           Node* effect,
   1661                                                           Node* control) {
   1662   Node* value = node->InputAt(0);
   1663   Node* check = graph()->NewNode(machine()->Uint32LessThanOrEqual(), value,
   1664                                  SmiMaxValueConstant());
   1665   control = effect = graph()->NewNode(
   1666       common()->DeoptimizeUnless(DeoptimizeReason::kLostPrecision), check,
   1667       frame_state, effect, control);
   1668   value = ChangeUint32ToSmi(value);
   1669 
   1670   return ValueEffectControl(value, effect, control);
   1671 }
   1672 
   1673 EffectControlLinearizer::ValueEffectControl
   1674 EffectControlLinearizer::BuildCheckedFloat64ToInt32(CheckForMinusZeroMode mode,
   1675                                                     Node* value,
   1676                                                     Node* frame_state,
   1677                                                     Node* effect,
   1678                                                     Node* control) {
   1679   Node* value32 = graph()->NewNode(machine()->RoundFloat64ToInt32(), value);
   1680   Node* check_same = graph()->NewNode(
   1681       machine()->Float64Equal(), value,
   1682       graph()->NewNode(machine()->ChangeInt32ToFloat64(), value32));
   1683   control = effect = graph()->NewNode(
   1684       common()->DeoptimizeUnless(DeoptimizeReason::kLostPrecisionOrNaN),
   1685       check_same, frame_state, effect, control);
   1686 
   1687   if (mode == CheckForMinusZeroMode::kCheckForMinusZero) {
   1688     // Check if {value} is -0.
   1689     Node* check_zero = graph()->NewNode(machine()->Word32Equal(), value32,
   1690                                         jsgraph()->Int32Constant(0));
   1691     Node* branch_zero = graph()->NewNode(common()->Branch(BranchHint::kFalse),
   1692                                          check_zero, control);
   1693 
   1694     Node* if_zero = graph()->NewNode(common()->IfTrue(), branch_zero);
   1695     Node* if_notzero = graph()->NewNode(common()->IfFalse(), branch_zero);
   1696 
   1697     // In case of 0, we need to check the high bits for the IEEE -0 pattern.
   1698     Node* check_negative = graph()->NewNode(
   1699         machine()->Int32LessThan(),
   1700         graph()->NewNode(machine()->Float64ExtractHighWord32(), value),
   1701         jsgraph()->Int32Constant(0));
   1702 
   1703     Node* deopt_minus_zero =
   1704         graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kMinusZero),
   1705                          check_negative, frame_state, effect, if_zero);
   1706 
   1707     control =
   1708         graph()->NewNode(common()->Merge(2), deopt_minus_zero, if_notzero);
   1709     effect = graph()->NewNode(common()->EffectPhi(2), deopt_minus_zero, effect,
   1710                               control);
   1711   }
   1712 
   1713   return ValueEffectControl(value32, effect, control);
   1714 }
   1715 
   1716 EffectControlLinearizer::ValueEffectControl
   1717 EffectControlLinearizer::LowerCheckedFloat64ToInt32(Node* node,
   1718                                                     Node* frame_state,
   1719                                                     Node* effect,
   1720                                                     Node* control) {
   1721   CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op());
   1722   Node* value = node->InputAt(0);
   1723 
   1724   return BuildCheckedFloat64ToInt32(mode, value, frame_state, effect, control);
   1725 }
   1726 
   1727 EffectControlLinearizer::ValueEffectControl
   1728 EffectControlLinearizer::LowerCheckedTaggedSignedToInt32(Node* node,
   1729                                                          Node* frame_state,
   1730                                                          Node* effect,
   1731                                                          Node* control) {
   1732   Node* value = node->InputAt(0);
   1733 
   1734   Node* check = ObjectIsSmi(value);
   1735   control = effect =
   1736       graph()->NewNode(common()->DeoptimizeUnless(DeoptimizeReason::kNotASmi),
   1737                        check, frame_state, effect, control);
   1738   value = ChangeSmiToInt32(value);
   1739 
   1740   return ValueEffectControl(value, effect, control);
   1741 }
   1742 
   1743 EffectControlLinearizer::ValueEffectControl
   1744 EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node,
   1745                                                    Node* frame_state,
   1746                                                    Node* effect,
   1747                                                    Node* control) {
   1748   CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op());
   1749   Node* value = node->InputAt(0);
   1750 
   1751   Node* check = ObjectIsSmi(value);
   1752   Node* branch =
   1753       graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
   1754 
   1755   // In the Smi case, just convert to int32.
   1756   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
   1757   Node* etrue = effect;
   1758   Node* vtrue = ChangeSmiToInt32(value);
   1759 
   1760   // In the non-Smi case, check the heap numberness, load the number and convert
   1761   // to int32.
   1762   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
   1763   Node* efalse = effect;
   1764   Node* vfalse;
   1765   {
   1766     Node* value_map = efalse =
   1767         graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
   1768                          value, efalse, if_false);
   1769     Node* check = graph()->NewNode(machine()->WordEqual(), value_map,
   1770                                    jsgraph()->HeapNumberMapConstant());
   1771     if_false = efalse = graph()->NewNode(
   1772         common()->DeoptimizeUnless(DeoptimizeReason::kNotAHeapNumber), check,
   1773         frame_state, efalse, if_false);
   1774     vfalse = efalse = graph()->NewNode(
   1775         simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
   1776         efalse, if_false);
   1777     ValueEffectControl state =
   1778         BuildCheckedFloat64ToInt32(mode, vfalse, frame_state, efalse, if_false);
   1779     if_false = state.control;
   1780     efalse = state.effect;
   1781     vfalse = state.value;
   1782   }
   1783 
   1784   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
   1785   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
   1786   value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
   1787                            vtrue, vfalse, control);
   1788 
   1789   return ValueEffectControl(value, effect, control);
   1790 }
   1791 
   1792 EffectControlLinearizer::ValueEffectControl
   1793 EffectControlLinearizer::BuildCheckedHeapNumberOrOddballToFloat64(
   1794     CheckTaggedInputMode mode, Node* value, Node* frame_state, Node* effect,
   1795     Node* control) {
   1796   Node* value_map = effect = graph()->NewNode(
   1797       simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control);
   1798 
   1799   Node* check_number = graph()->NewNode(machine()->WordEqual(), value_map,
   1800                                         jsgraph()->HeapNumberMapConstant());
   1801 
   1802   switch (mode) {
   1803     case CheckTaggedInputMode::kNumber: {
   1804       control = effect = graph()->NewNode(
   1805           common()->DeoptimizeUnless(DeoptimizeReason::kNotAHeapNumber),
   1806           check_number, frame_state, effect, control);
   1807       break;
   1808     }
   1809     case CheckTaggedInputMode::kNumberOrOddball: {
   1810       Node* branch =
   1811           graph()->NewNode(common()->Branch(), check_number, control);
   1812 
   1813       Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
   1814       Node* etrue = effect;
   1815 
   1816       Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
   1817       // For oddballs also contain the numeric value, let us just check that
   1818       // we have an oddball here.
   1819       Node* efalse = effect;
   1820       Node* instance_type = efalse = graph()->NewNode(
   1821           simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
   1822           value_map, efalse, if_false);
   1823       Node* check_oddball =
   1824           graph()->NewNode(machine()->Word32Equal(), instance_type,
   1825                            jsgraph()->Int32Constant(ODDBALL_TYPE));
   1826       if_false = efalse = graph()->NewNode(
   1827           common()->DeoptimizeUnless(DeoptimizeReason::kNotANumberOrOddball),
   1828           check_oddball, frame_state, efalse, if_false);
   1829       STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
   1830 
   1831       control = graph()->NewNode(common()->Merge(2), if_true, if_false);
   1832       effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
   1833       break;
   1834     }
   1835   }
   1836 
   1837   value = effect = graph()->NewNode(
   1838       simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
   1839       effect, control);
   1840   return ValueEffectControl(value, effect, control);
   1841 }
   1842 
   1843 EffectControlLinearizer::ValueEffectControl
   1844 EffectControlLinearizer::LowerCheckedTaggedToFloat64(Node* node,
   1845                                                      Node* frame_state,
   1846                                                      Node* effect,
   1847                                                      Node* control) {
   1848   CheckTaggedInputMode mode = CheckTaggedInputModeOf(node->op());
   1849   Node* value = node->InputAt(0);
   1850 
   1851   Node* check = ObjectIsSmi(value);
   1852   Node* branch = graph()->NewNode(common()->Branch(), check, control);
   1853 
   1854   // In the Smi case, just convert to int32 and then float64.
   1855   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
   1856   Node* etrue = effect;
   1857   Node* vtrue = ChangeSmiToInt32(value);
   1858   vtrue = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue);
   1859 
   1860   // Otherwise, check heap numberness and load the number.
   1861   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
   1862   ValueEffectControl number_state = BuildCheckedHeapNumberOrOddballToFloat64(
   1863       mode, value, frame_state, effect, if_false);
   1864 
   1865   Node* merge =
   1866       graph()->NewNode(common()->Merge(2), if_true, number_state.control);
   1867   Node* effect_phi = graph()->NewNode(common()->EffectPhi(2), etrue,
   1868                                       number_state.effect, merge);
   1869   Node* result =
   1870       graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), vtrue,
   1871                        number_state.value, merge);
   1872 
   1873   return ValueEffectControl(result, effect_phi, merge);
   1874 }
   1875 
   1876 EffectControlLinearizer::ValueEffectControl
   1877 EffectControlLinearizer::LowerCheckedTaggedToTaggedSigned(Node* node,
   1878                                                           Node* frame_state,
   1879                                                           Node* effect,
   1880                                                           Node* control) {
   1881   Node* value = node->InputAt(0);
   1882 
   1883   Node* check = ObjectIsSmi(value);
   1884   control = effect =
   1885       graph()->NewNode(common()->DeoptimizeUnless(DeoptimizeReason::kNotASmi),
   1886                        check, frame_state, effect, control);
   1887 
   1888   return ValueEffectControl(value, effect, control);
   1889 }
   1890 
   1891 EffectControlLinearizer::ValueEffectControl
   1892 EffectControlLinearizer::LowerCheckedTaggedToTaggedPointer(Node* node,
   1893                                                            Node* frame_state,
   1894                                                            Node* effect,
   1895                                                            Node* control) {
   1896   Node* value = node->InputAt(0);
   1897 
   1898   Node* check = ObjectIsSmi(value);
   1899   control = effect =
   1900       graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kSmi), check,
   1901                        frame_state, effect, control);
   1902 
   1903   return ValueEffectControl(value, effect, control);
   1904 }
   1905 
   1906 EffectControlLinearizer::ValueEffectControl
   1907 EffectControlLinearizer::LowerTruncateTaggedToWord32(Node* node, Node* effect,
   1908                                                      Node* control) {
   1909   Node* value = node->InputAt(0);
   1910 
   1911   Node* check = ObjectIsSmi(value);
   1912   Node* branch =
   1913       graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
   1914 
   1915   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
   1916   Node* etrue = effect;
   1917   Node* vtrue = ChangeSmiToInt32(value);
   1918 
   1919   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
   1920   Node* efalse = effect;
   1921   Node* vfalse;
   1922   {
   1923     STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
   1924     vfalse = efalse = graph()->NewNode(
   1925         simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
   1926         efalse, if_false);
   1927     vfalse = graph()->NewNode(machine()->TruncateFloat64ToWord32(), vfalse);
   1928   }
   1929 
   1930   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
   1931   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
   1932   value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
   1933                            vtrue, vfalse, control);
   1934 
   1935   return ValueEffectControl(value, effect, control);
   1936 }
   1937 
   1938 EffectControlLinearizer::ValueEffectControl
   1939 EffectControlLinearizer::LowerCheckedTruncateTaggedToWord32(Node* node,
   1940                                                             Node* frame_state,
   1941                                                             Node* effect,
   1942                                                             Node* control) {
   1943   Node* value = node->InputAt(0);
   1944 
   1945   Node* check = ObjectIsSmi(value);
   1946   Node* branch =
   1947       graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
   1948 
   1949   // In the Smi case, just convert to int32.
   1950   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
   1951   Node* etrue = effect;
   1952   Node* vtrue = ChangeSmiToInt32(value);
   1953 
   1954   // Otherwise, check that it's a heap number or oddball and truncate the value
   1955   // to int32.
   1956   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
   1957   ValueEffectControl false_state = BuildCheckedHeapNumberOrOddballToFloat64(
   1958       CheckTaggedInputMode::kNumberOrOddball, value, frame_state, effect,
   1959       if_false);
   1960   false_state.value =
   1961       graph()->NewNode(machine()->TruncateFloat64ToWord32(), false_state.value);
   1962 
   1963   Node* merge =
   1964       graph()->NewNode(common()->Merge(2), if_true, false_state.control);
   1965   Node* effect_phi = graph()->NewNode(common()->EffectPhi(2), etrue,
   1966                                       false_state.effect, merge);
   1967   Node* result =
   1968       graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue,
   1969                        false_state.value, merge);
   1970 
   1971   return ValueEffectControl(result, effect_phi, merge);
   1972 }
   1973 
   1974 EffectControlLinearizer::ValueEffectControl
   1975 EffectControlLinearizer::LowerObjectIsCallable(Node* node, Node* effect,
   1976                                                Node* control) {
   1977   Node* value = node->InputAt(0);
   1978 
   1979   Node* check = ObjectIsSmi(value);
   1980   Node* branch =
   1981       graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
   1982 
   1983   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
   1984   Node* etrue = effect;
   1985   Node* vtrue = jsgraph()->Int32Constant(0);
   1986 
   1987   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
   1988   Node* efalse = effect;
   1989   Node* vfalse;
   1990   {
   1991     Node* value_map = efalse =
   1992         graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
   1993                          value, efalse, if_false);
   1994     Node* value_bit_field = efalse = graph()->NewNode(
   1995         simplified()->LoadField(AccessBuilder::ForMapBitField()), value_map,
   1996         efalse, if_false);
   1997     vfalse = graph()->NewNode(
   1998         machine()->Word32Equal(),
   1999         jsgraph()->Int32Constant(1 << Map::kIsCallable),
   2000         graph()->NewNode(
   2001             machine()->Word32And(), value_bit_field,
   2002             jsgraph()->Int32Constant((1 << Map::kIsCallable) |
   2003                                      (1 << Map::kIsUndetectable))));
   2004   }
   2005 
   2006   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
   2007   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
   2008   value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue,
   2009                            vfalse, control);
   2010 
   2011   return ValueEffectControl(value, effect, control);
   2012 }
   2013 
   2014 EffectControlLinearizer::ValueEffectControl
   2015 EffectControlLinearizer::LowerObjectIsNumber(Node* node, Node* effect,
   2016                                              Node* control) {
   2017   Node* value = node->InputAt(0);
   2018 
   2019   Node* check = ObjectIsSmi(value);
   2020   Node* branch = graph()->NewNode(common()->Branch(), check, control);
   2021 
   2022   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
   2023   Node* etrue = effect;
   2024   Node* vtrue = jsgraph()->Int32Constant(1);
   2025 
   2026   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
   2027   Node* efalse = effect;
   2028   Node* vfalse;
   2029   {
   2030     Node* value_map = efalse =
   2031         graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
   2032                          value, efalse, if_false);
   2033     vfalse = graph()->NewNode(machine()->WordEqual(), value_map,
   2034                               jsgraph()->HeapNumberMapConstant());
   2035   }
   2036 
   2037   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
   2038   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
   2039   value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue,
   2040                            vfalse, control);
   2041 
   2042   return ValueEffectControl(value, effect, control);
   2043 }
   2044 
   2045 EffectControlLinearizer::ValueEffectControl
   2046 EffectControlLinearizer::LowerObjectIsReceiver(Node* node, Node* effect,
   2047                                                Node* control) {
   2048   Node* value = node->InputAt(0);
   2049 
   2050   Node* check = ObjectIsSmi(value);
   2051   Node* branch =
   2052       graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
   2053 
   2054   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
   2055   Node* etrue = effect;
   2056   Node* vtrue = jsgraph()->Int32Constant(0);
   2057 
   2058   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
   2059   Node* efalse = effect;
   2060   Node* vfalse;
   2061   {
   2062     STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
   2063     Node* value_map = efalse =
   2064         graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
   2065                          value, efalse, if_false);
   2066     Node* value_instance_type = efalse = graph()->NewNode(
   2067         simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map,
   2068         efalse, if_false);
   2069     vfalse = graph()->NewNode(machine()->Uint32LessThanOrEqual(),
   2070                               jsgraph()->Uint32Constant(FIRST_JS_RECEIVER_TYPE),
   2071                               value_instance_type);
   2072   }
   2073 
   2074   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
   2075   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
   2076   value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue,
   2077                            vfalse, control);
   2078 
   2079   return ValueEffectControl(value, effect, control);
   2080 }
   2081 
   2082 EffectControlLinearizer::ValueEffectControl
   2083 EffectControlLinearizer::LowerObjectIsSmi(Node* node, Node* effect,
   2084                                           Node* control) {
   2085   Node* value = node->InputAt(0);
   2086   value = ObjectIsSmi(value);
   2087   return ValueEffectControl(value, effect, control);
   2088 }
   2089 
   2090 EffectControlLinearizer::ValueEffectControl
   2091 EffectControlLinearizer::LowerObjectIsString(Node* node, Node* effect,
   2092                                              Node* control) {
   2093   Node* value = node->InputAt(0);
   2094 
   2095   Node* check = ObjectIsSmi(value);
   2096   Node* branch =
   2097       graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
   2098 
   2099   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
   2100   Node* etrue = effect;
   2101   Node* vtrue = jsgraph()->Int32Constant(0);
   2102 
   2103   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
   2104   Node* efalse = effect;
   2105   Node* vfalse;
   2106   {
   2107     Node* value_map = efalse =
   2108         graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
   2109                          value, efalse, if_false);
   2110     Node* value_instance_type = efalse = graph()->NewNode(
   2111         simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map,
   2112         efalse, if_false);
   2113     vfalse = graph()->NewNode(machine()->Uint32LessThan(), value_instance_type,
   2114                               jsgraph()->Uint32Constant(FIRST_NONSTRING_TYPE));
   2115   }
   2116 
   2117   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
   2118   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
   2119   value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue,
   2120                            vfalse, control);
   2121 
   2122   return ValueEffectControl(value, effect, control);
   2123 }
   2124 
   2125 EffectControlLinearizer::ValueEffectControl
   2126 EffectControlLinearizer::LowerObjectIsUndetectable(Node* node, Node* effect,
   2127                                                    Node* control) {
   2128   Node* value = node->InputAt(0);
   2129 
   2130   Node* check = ObjectIsSmi(value);
   2131   Node* branch =
   2132       graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
   2133 
   2134   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
   2135   Node* etrue = effect;
   2136   Node* vtrue = jsgraph()->Int32Constant(0);
   2137 
   2138   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
   2139   Node* efalse = effect;
   2140   Node* vfalse;
   2141   {
   2142     Node* value_map = efalse =
   2143         graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
   2144                          value, efalse, if_false);
   2145     Node* value_bit_field = efalse = graph()->NewNode(
   2146         simplified()->LoadField(AccessBuilder::ForMapBitField()), value_map,
   2147         efalse, if_false);
   2148     vfalse = graph()->NewNode(
   2149         machine()->Word32Equal(),
   2150         graph()->NewNode(
   2151             machine()->Word32Equal(), jsgraph()->Int32Constant(0),
   2152             graph()->NewNode(
   2153                 machine()->Word32And(), value_bit_field,
   2154                 jsgraph()->Int32Constant(1 << Map::kIsUndetectable))),
   2155         jsgraph()->Int32Constant(0));
   2156   }
   2157 
   2158   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
   2159   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
   2160   value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue,
   2161                            vfalse, control);
   2162 
   2163   return ValueEffectControl(value, effect, control);
   2164 }
   2165 
   2166 EffectControlLinearizer::ValueEffectControl
   2167 EffectControlLinearizer::LowerArrayBufferWasNeutered(Node* node, Node* effect,
   2168                                                      Node* control) {
   2169   Node* value = node->InputAt(0);
   2170 
   2171   Node* value_bit_field = effect = graph()->NewNode(
   2172       simplified()->LoadField(AccessBuilder::ForJSArrayBufferBitField()), value,
   2173       effect, control);
   2174   value = graph()->NewNode(
   2175       machine()->Word32Equal(),
   2176       graph()->NewNode(machine()->Word32Equal(),
   2177                        graph()->NewNode(machine()->Word32And(), value_bit_field,
   2178                                         jsgraph()->Int32Constant(
   2179                                             JSArrayBuffer::WasNeutered::kMask)),
   2180                        jsgraph()->Int32Constant(0)),
   2181       jsgraph()->Int32Constant(0));
   2182 
   2183   return ValueEffectControl(value, effect, control);
   2184 }
   2185 
   2186 EffectControlLinearizer::ValueEffectControl
   2187 EffectControlLinearizer::LowerStringCharCodeAt(Node* node, Node* effect,
   2188                                                Node* control) {
   2189   Node* subject = node->InputAt(0);
   2190   Node* index = node->InputAt(1);
   2191 
   2192   // We may need to loop several times for ConsString/SlicedString {subject}s.
   2193   Node* loop =
   2194       graph()->NewNode(common()->Loop(4), control, control, control, control);
   2195   Node* lsubject =
   2196       graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 4),
   2197                        subject, subject, subject, subject, loop);
   2198   Node* lindex =
   2199       graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 4), index,
   2200                        index, index, index, loop);
   2201   Node* leffect = graph()->NewNode(common()->EffectPhi(4), effect, effect,
   2202                                    effect, effect, loop);
   2203 
   2204   control = loop;
   2205   effect = leffect;
   2206 
   2207   // Determine the instance type of {lsubject}.
   2208   Node* lsubject_map = effect =
   2209       graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
   2210                        lsubject, effect, control);
   2211   Node* lsubject_instance_type = effect = graph()->NewNode(
   2212       simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
   2213       lsubject_map, effect, control);
   2214 
   2215   // Check if {lsubject} is a SeqString.
   2216   Node* check0 = graph()->NewNode(
   2217       machine()->Word32Equal(),
   2218       graph()->NewNode(machine()->Word32And(), lsubject_instance_type,
   2219                        jsgraph()->Int32Constant(kStringRepresentationMask)),
   2220       jsgraph()->Int32Constant(kSeqStringTag));
   2221   Node* branch0 = graph()->NewNode(common()->Branch(), check0, control);
   2222 
   2223   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
   2224   Node* etrue0 = effect;
   2225   Node* vtrue0;
   2226   {
   2227     // Check if the {lsubject} is a TwoByteSeqString or a OneByteSeqString.
   2228     Node* check1 = graph()->NewNode(
   2229         machine()->Word32Equal(),
   2230         graph()->NewNode(machine()->Word32And(), lsubject_instance_type,
   2231                          jsgraph()->Int32Constant(kStringEncodingMask)),
   2232         jsgraph()->Int32Constant(kTwoByteStringTag));
   2233     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
   2234 
   2235     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
   2236     Node* etrue1 = etrue0;
   2237     Node* vtrue1 = etrue1 =
   2238         graph()->NewNode(simplified()->LoadElement(
   2239                              AccessBuilder::ForSeqTwoByteStringCharacter()),
   2240                          lsubject, lindex, etrue1, if_true1);
   2241 
   2242     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
   2243     Node* efalse1 = etrue0;
   2244     Node* vfalse1 = efalse1 =
   2245         graph()->NewNode(simplified()->LoadElement(
   2246                              AccessBuilder::ForSeqOneByteStringCharacter()),
   2247                          lsubject, lindex, efalse1, if_false1);
   2248 
   2249     if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
   2250     etrue0 =
   2251         graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_true0);
   2252     vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
   2253                               vtrue1, vfalse1, if_true0);
   2254   }
   2255 
   2256   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
   2257   Node* efalse0 = effect;
   2258   Node* vfalse0;
   2259   {
   2260     // Check if the {lsubject} is a ConsString.
   2261     Node* check1 = graph()->NewNode(
   2262         machine()->Word32Equal(),
   2263         graph()->NewNode(machine()->Word32And(), lsubject_instance_type,
   2264                          jsgraph()->Int32Constant(kStringRepresentationMask)),
   2265         jsgraph()->Int32Constant(kConsStringTag));
   2266     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
   2267 
   2268     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
   2269     Node* etrue1 = efalse0;
   2270     {
   2271       // Load the right hand side of the {lsubject} ConsString.
   2272       Node* lsubject_second = etrue1 = graph()->NewNode(
   2273           simplified()->LoadField(AccessBuilder::ForConsStringSecond()),
   2274           lsubject, etrue1, if_true1);
   2275 
   2276       // Check whether the right hand side is the empty string (i.e. if
   2277       // this is really a flat string in a cons string). If that is not
   2278       // the case we flatten the string first.
   2279       Node* check2 = graph()->NewNode(machine()->WordEqual(), lsubject_second,
   2280                                       jsgraph()->EmptyStringConstant());
   2281       Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
   2282                                        check2, if_true1);
   2283 
   2284       Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
   2285       Node* etrue2 = etrue1;
   2286       Node* vtrue2 = etrue2 = graph()->NewNode(
   2287           simplified()->LoadField(AccessBuilder::ForConsStringFirst()),
   2288           lsubject, etrue2, if_true2);
   2289 
   2290       Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
   2291       Node* efalse2 = etrue1;
   2292       Node* vfalse2;
   2293       {
   2294         // Flatten the {lsubject} ConsString first.
   2295         Operator::Properties properties =
   2296             Operator::kNoDeopt | Operator::kNoThrow;
   2297         Runtime::FunctionId id = Runtime::kFlattenString;
   2298         CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor(
   2299             graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags);
   2300         vfalse2 = efalse2 = graph()->NewNode(
   2301             common()->Call(desc), jsgraph()->CEntryStubConstant(1), lsubject,
   2302             jsgraph()->ExternalConstant(ExternalReference(id, isolate())),
   2303             jsgraph()->Int32Constant(1), jsgraph()->NoContextConstant(),
   2304             efalse2, if_false2);
   2305       }
   2306 
   2307       // Retry the {loop} with the new subject.
   2308       loop->ReplaceInput(1, if_true2);
   2309       lindex->ReplaceInput(1, lindex);
   2310       leffect->ReplaceInput(1, etrue2);
   2311       lsubject->ReplaceInput(1, vtrue2);
   2312       loop->ReplaceInput(2, if_false2);
   2313       lindex->ReplaceInput(2, lindex);
   2314       leffect->ReplaceInput(2, efalse2);
   2315       lsubject->ReplaceInput(2, vfalse2);
   2316     }
   2317 
   2318     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
   2319     Node* efalse1 = efalse0;
   2320     Node* vfalse1;
   2321     {
   2322       // Check if the {lsubject} is an ExternalString.
   2323       Node* check2 = graph()->NewNode(
   2324           machine()->Word32Equal(),
   2325           graph()->NewNode(machine()->Word32And(), lsubject_instance_type,
   2326                            jsgraph()->Int32Constant(kStringRepresentationMask)),
   2327           jsgraph()->Int32Constant(kExternalStringTag));
   2328       Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
   2329                                        check2, if_false1);
   2330 
   2331       Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
   2332       Node* etrue2 = efalse1;
   2333       Node* vtrue2;
   2334       {
   2335         // Check if the {lsubject} is a short external string.
   2336         Node* check3 = graph()->NewNode(
   2337             machine()->Word32Equal(),
   2338             graph()->NewNode(
   2339                 machine()->Word32And(), lsubject_instance_type,
   2340                 jsgraph()->Int32Constant(kShortExternalStringMask)),
   2341             jsgraph()->Int32Constant(0));
   2342         Node* branch3 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
   2343                                          check3, if_true2);
   2344 
   2345         Node* if_true3 = graph()->NewNode(common()->IfTrue(), branch3);
   2346         Node* etrue3 = etrue2;
   2347         Node* vtrue3;
   2348         {
   2349           // Load the actual resource data from the {lsubject}.
   2350           Node* lsubject_resource_data = etrue3 = graph()->NewNode(
   2351               simplified()->LoadField(
   2352                   AccessBuilder::ForExternalStringResourceData()),
   2353               lsubject, etrue3, if_true3);
   2354 
   2355           // Check if the {lsubject} is a TwoByteExternalString or a
   2356           // OneByteExternalString.
   2357           Node* check4 = graph()->NewNode(
   2358               machine()->Word32Equal(),
   2359               graph()->NewNode(machine()->Word32And(), lsubject_instance_type,
   2360                                jsgraph()->Int32Constant(kStringEncodingMask)),
   2361               jsgraph()->Int32Constant(kTwoByteStringTag));
   2362           Node* branch4 =
   2363               graph()->NewNode(common()->Branch(), check4, if_true3);
   2364 
   2365           Node* if_true4 = graph()->NewNode(common()->IfTrue(), branch4);
   2366           Node* etrue4 = etrue3;
   2367           Node* vtrue4 = etrue4 = graph()->NewNode(
   2368               simplified()->LoadElement(
   2369                   AccessBuilder::ForExternalTwoByteStringCharacter()),
   2370               lsubject_resource_data, lindex, etrue4, if_true4);
   2371 
   2372           Node* if_false4 = graph()->NewNode(common()->IfFalse(), branch4);
   2373           Node* efalse4 = etrue3;
   2374           Node* vfalse4 = efalse4 = graph()->NewNode(
   2375               simplified()->LoadElement(
   2376                   AccessBuilder::ForExternalOneByteStringCharacter()),
   2377               lsubject_resource_data, lindex, efalse4, if_false4);
   2378 
   2379           if_true3 = graph()->NewNode(common()->Merge(2), if_true4, if_false4);
   2380           etrue3 = graph()->NewNode(common()->EffectPhi(2), etrue4, efalse4,
   2381                                     if_true3);
   2382           vtrue3 =
   2383               graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
   2384                                vtrue4, vfalse4, if_true3);
   2385         }
   2386 
   2387         Node* if_false3 = graph()->NewNode(common()->IfFalse(), branch3);
   2388         Node* efalse3 = etrue2;
   2389         Node* vfalse3;
   2390         {
   2391           // The {lsubject} might be compressed, call the runtime.
   2392           Operator::Properties properties =
   2393               Operator::kNoDeopt | Operator::kNoThrow;
   2394           Runtime::FunctionId id = Runtime::kExternalStringGetChar;
   2395           CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor(
   2396               graph()->zone(), id, 2, properties, CallDescriptor::kNoFlags);
   2397           vfalse3 = efalse3 = graph()->NewNode(
   2398               common()->Call(desc), jsgraph()->CEntryStubConstant(1), lsubject,
   2399               ChangeInt32ToSmi(lindex),
   2400               jsgraph()->ExternalConstant(ExternalReference(id, isolate())),
   2401               jsgraph()->Int32Constant(2), jsgraph()->NoContextConstant(),
   2402               efalse3, if_false3);
   2403           vfalse3 = ChangeSmiToInt32(vfalse3);
   2404         }
   2405 
   2406         if_true2 = graph()->NewNode(common()->Merge(2), if_true3, if_false3);
   2407         etrue2 =
   2408             graph()->NewNode(common()->EffectPhi(2), etrue3, efalse3, if_true2);
   2409         vtrue2 =
   2410             graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
   2411                              vtrue3, vfalse3, if_true2);
   2412       }
   2413 
   2414       Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
   2415       Node* efalse2 = efalse1;
   2416       {
   2417         // The {lsubject} is a SlicedString, continue with its parent.
   2418         Node* lsubject_parent = efalse2 = graph()->NewNode(
   2419             simplified()->LoadField(AccessBuilder::ForSlicedStringParent()),
   2420             lsubject, efalse2, if_false2);
   2421         Node* lsubject_offset = efalse2 = graph()->NewNode(
   2422             simplified()->LoadField(AccessBuilder::ForSlicedStringOffset()),
   2423             lsubject, efalse2, if_false2);
   2424         Node* lsubject_index = graph()->NewNode(
   2425             machine()->Int32Add(), lindex, ChangeSmiToInt32(lsubject_offset));
   2426 
   2427         // Retry the {loop} with the parent subject.
   2428         loop->ReplaceInput(3, if_false2);
   2429         leffect->ReplaceInput(3, efalse2);
   2430         lindex->ReplaceInput(3, lsubject_index);
   2431         lsubject->ReplaceInput(3, lsubject_parent);
   2432       }
   2433 
   2434       if_false1 = if_true2;
   2435       efalse1 = etrue2;
   2436       vfalse1 = vtrue2;
   2437     }
   2438 
   2439     if_false0 = if_false1;
   2440     efalse0 = efalse1;
   2441     vfalse0 = vfalse1;
   2442   }
   2443 
   2444   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
   2445   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
   2446   Node* value =
   2447       graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue0,
   2448                        vfalse0, control);
   2449 
   2450   return ValueEffectControl(value, effect, control);
   2451 }
   2452 
   2453 EffectControlLinearizer::ValueEffectControl
   2454 EffectControlLinearizer::LowerStringFromCharCode(Node* node, Node* effect,
   2455                                                  Node* control) {
   2456   Node* value = node->InputAt(0);
   2457 
   2458   // Compute the character code.
   2459   Node* code =
   2460       graph()->NewNode(machine()->Word32And(), value,
   2461                        jsgraph()->Int32Constant(String::kMaxUtf16CodeUnit));
   2462 
   2463   // Check if the {code} is a one-byte char code.
   2464   Node* check0 =
   2465       graph()->NewNode(machine()->Int32LessThanOrEqual(), code,
   2466                        jsgraph()->Int32Constant(String::kMaxOneByteCharCode));
   2467   Node* branch0 =
   2468       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
   2469 
   2470   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
   2471   Node* efalse0 = effect;
   2472 
   2473   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
   2474   Node* etrue0 = effect;
   2475 
   2476   // Load the isolate wide single character string cache.
   2477   Node* cache =
   2478       jsgraph()->HeapConstant(factory()->single_character_string_cache());
   2479 
   2480   // Compute the {cache} index for {code}.
   2481   Node* index = machine()->Is32()
   2482                     ? code
   2483                     : graph()->NewNode(machine()->ChangeUint32ToUint64(), code);
   2484 
   2485   // Check if we have an entry for the {code} in the single character string
   2486   // cache already.
   2487   Node* entry = etrue0 = graph()->NewNode(
   2488       simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()), cache,
   2489       index, etrue0, if_true0);
   2490 
   2491   Node* check1 = graph()->NewNode(machine()->WordEqual(), entry,
   2492                                   jsgraph()->UndefinedConstant());
   2493   Node* branch1 =
   2494       graph()->NewNode(common()->Branch(BranchHint::kFalse), check1, if_true0);
   2495 
   2496   // Use the {entry} from the {cache}.
   2497   Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
   2498   Node* efalse1 = etrue0;
   2499   Node* vfalse1 = entry;
   2500 
   2501   // Let %StringFromCharCode handle this case.
   2502   // TODO(turbofan): At some point we may consider adding a stub for this
   2503   // deferred case, so that we don't need to call to C++ here.
   2504   Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
   2505   Node* etrue1 = etrue0;
   2506   Node* vtrue1;
   2507   {
   2508     if_true1 = graph()->NewNode(common()->Merge(2), if_true1, if_false0);
   2509     etrue1 =
   2510         graph()->NewNode(common()->EffectPhi(2), etrue1, efalse0, if_true1);
   2511     Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
   2512     Runtime::FunctionId id = Runtime::kStringCharFromCode;
   2513     CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor(
   2514         graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags);
   2515     vtrue1 = etrue1 = graph()->NewNode(
   2516         common()->Call(desc), jsgraph()->CEntryStubConstant(1),
   2517         ChangeInt32ToSmi(code),
   2518         jsgraph()->ExternalConstant(ExternalReference(id, isolate())),
   2519         jsgraph()->Int32Constant(1), jsgraph()->NoContextConstant(), etrue1,
   2520         if_true1);
   2521   }
   2522 
   2523   control = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
   2524   effect = graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, control);
   2525   value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
   2526                            vtrue1, vfalse1, control);
   2527 
   2528   return ValueEffectControl(value, effect, control);
   2529 }
   2530 
   2531 EffectControlLinearizer::ValueEffectControl
   2532 EffectControlLinearizer::LowerStringFromCodePoint(Node* node, Node* effect,
   2533                                                   Node* control) {
   2534   Node* value = node->InputAt(0);
   2535   Node* code = value;
   2536 
   2537   Node* etrue0 = effect;
   2538   Node* vtrue0;
   2539 
   2540   // Check if the {code} is a single code unit
   2541   Node* check0 = graph()->NewNode(machine()->Uint32LessThanOrEqual(), code,
   2542                                   jsgraph()->Uint32Constant(0xFFFF));
   2543   Node* branch0 =
   2544       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
   2545 
   2546   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
   2547   {
   2548     // Check if the {code} is a one byte character
   2549     Node* check1 = graph()->NewNode(
   2550         machine()->Uint32LessThanOrEqual(), code,
   2551         jsgraph()->Uint32Constant(String::kMaxOneByteCharCode));
   2552     Node* branch1 =
   2553         graph()->NewNode(common()->Branch(BranchHint::kTrue), check1, if_true0);
   2554 
   2555     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
   2556     Node* etrue1 = etrue0;
   2557     Node* vtrue1;
   2558     {
   2559       // Load the isolate wide single character string cache.
   2560       Node* cache =
   2561           jsgraph()->HeapConstant(factory()->single_character_string_cache());
   2562 
   2563       // Compute the {cache} index for {code}.
   2564       Node* index =
   2565           machine()->Is32()
   2566               ? code
   2567               : graph()->NewNode(machine()->ChangeUint32ToUint64(), code);
   2568 
   2569       // Check if we have an entry for the {code} in the single character string
   2570       // cache already.
   2571       Node* entry = etrue1 = graph()->NewNode(
   2572           simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()),
   2573           cache, index, etrue1, if_true1);
   2574 
   2575       Node* check2 = graph()->NewNode(machine()->WordEqual(), entry,
   2576                                       jsgraph()->UndefinedConstant());
   2577       Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
   2578                                        check2, if_true1);
   2579 
   2580       Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
   2581       Node* etrue2 = etrue1;
   2582       Node* vtrue2;
   2583       {
   2584         // Allocate a new SeqOneByteString for {code}.
   2585         vtrue2 = etrue2 = graph()->NewNode(
   2586             simplified()->Allocate(NOT_TENURED),
   2587             jsgraph()->Int32Constant(SeqOneByteString::SizeFor(1)), etrue2,
   2588             if_true2);
   2589         etrue2 = graph()->NewNode(
   2590             simplified()->StoreField(AccessBuilder::ForMap()), vtrue2,
   2591             jsgraph()->HeapConstant(factory()->one_byte_string_map()), etrue2,
   2592             if_true2);
   2593         etrue2 = graph()->NewNode(
   2594             simplified()->StoreField(AccessBuilder::ForNameHashField()), vtrue2,
   2595             jsgraph()->IntPtrConstant(Name::kEmptyHashField), etrue2, if_true2);
   2596         etrue2 = graph()->NewNode(
   2597             simplified()->StoreField(AccessBuilder::ForStringLength()), vtrue2,
   2598             jsgraph()->SmiConstant(1), etrue2, if_true2);
   2599         etrue2 = graph()->NewNode(
   2600             machine()->Store(StoreRepresentation(MachineRepresentation::kWord8,
   2601                                                  kNoWriteBarrier)),
   2602             vtrue2, jsgraph()->IntPtrConstant(SeqOneByteString::kHeaderSize -
   2603                                               kHeapObjectTag),
   2604             code, etrue2, if_true2);
   2605 
   2606         // Remember it in the {cache}.
   2607         etrue2 = graph()->NewNode(
   2608             simplified()->StoreElement(AccessBuilder::ForFixedArrayElement()),
   2609             cache, index, vtrue2, etrue2, if_true2);
   2610       }
   2611 
   2612       // Use the {entry} from the {cache}.
   2613       Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
   2614       Node* efalse2 = etrue0;
   2615       Node* vfalse2 = entry;
   2616 
   2617       if_true1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
   2618       etrue1 =
   2619           graph()->NewNode(common()->EffectPhi(2), etrue2, efalse2, if_true1);
   2620       vtrue1 =
   2621           graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
   2622                            vtrue2, vfalse2, if_true1);
   2623     }
   2624 
   2625     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
   2626     Node* efalse1 = effect;
   2627     Node* vfalse1;
   2628     {
   2629       // Allocate a new SeqTwoByteString for {code}.
   2630       vfalse1 = efalse1 = graph()->NewNode(
   2631           simplified()->Allocate(NOT_TENURED),
   2632           jsgraph()->Int32Constant(SeqTwoByteString::SizeFor(1)), efalse1,
   2633           if_false1);
   2634       efalse1 = graph()->NewNode(
   2635           simplified()->StoreField(AccessBuilder::ForMap()), vfalse1,
   2636           jsgraph()->HeapConstant(factory()->string_map()), efalse1, if_false1);
   2637       efalse1 = graph()->NewNode(
   2638           simplified()->StoreField(AccessBuilder::ForNameHashField()), vfalse1,
   2639           jsgraph()->IntPtrConstant(Name::kEmptyHashField), efalse1, if_false1);
   2640       efalse1 = graph()->NewNode(
   2641           simplified()->StoreField(AccessBuilder::ForStringLength()), vfalse1,
   2642           jsgraph()->SmiConstant(1), efalse1, if_false1);
   2643       efalse1 = graph()->NewNode(
   2644           machine()->Store(StoreRepresentation(MachineRepresentation::kWord16,
   2645                                                kNoWriteBarrier)),
   2646           vfalse1, jsgraph()->IntPtrConstant(SeqTwoByteString::kHeaderSize -
   2647                                              kHeapObjectTag),
   2648           code, efalse1, if_false1);
   2649     }
   2650 
   2651     if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
   2652     etrue0 =
   2653         graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_true0);
   2654     vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
   2655                               vtrue1, vfalse1, if_true0);
   2656   }
   2657 
   2658   // Generate surrogate pair string
   2659   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
   2660   Node* efalse0 = effect;
   2661   Node* vfalse0;
   2662   {
   2663     switch (UnicodeEncodingOf(node->op())) {
   2664       case UnicodeEncoding::UTF16:
   2665         break;
   2666 
   2667       case UnicodeEncoding::UTF32: {
   2668         // Convert UTF32 to UTF16 code units, and store as a 32 bit word.
   2669         Node* lead_offset = jsgraph()->Int32Constant(0xD800 - (0x10000 >> 10));
   2670 
   2671         // lead = (codepoint >> 10) + LEAD_OFFSET
   2672         Node* lead =
   2673             graph()->NewNode(machine()->Int32Add(),
   2674                              graph()->NewNode(machine()->Word32Shr(), code,
   2675                                               jsgraph()->Int32Constant(10)),
   2676                              lead_offset);
   2677 
   2678         // trail = (codepoint & 0x3FF) + 0xDC00;
   2679         Node* trail =
   2680             graph()->NewNode(machine()->Int32Add(),
   2681                              graph()->NewNode(machine()->Word32And(), code,
   2682                                               jsgraph()->Int32Constant(0x3FF)),
   2683                              jsgraph()->Int32Constant(0xDC00));
   2684 
   2685         // codpoint = (trail << 16) | lead;
   2686         code = graph()->NewNode(machine()->Word32Or(),
   2687                                 graph()->NewNode(machine()->Word32Shl(), trail,
   2688                                                  jsgraph()->Int32Constant(16)),
   2689                                 lead);
   2690         break;
   2691       }
   2692     }
   2693 
   2694     // Allocate a new SeqTwoByteString for {code}.
   2695     vfalse0 = efalse0 =
   2696         graph()->NewNode(simplified()->Allocate(NOT_TENURED),
   2697                          jsgraph()->Int32Constant(SeqTwoByteString::SizeFor(2)),
   2698                          efalse0, if_false0);
   2699     efalse0 = graph()->NewNode(
   2700         simplified()->StoreField(AccessBuilder::ForMap()), vfalse0,
   2701         jsgraph()->HeapConstant(factory()->string_map()), efalse0, if_false0);
   2702     efalse0 = graph()->NewNode(
   2703         simplified()->StoreField(AccessBuilder::ForNameHashField()), vfalse0,
   2704         jsgraph()->IntPtrConstant(Name::kEmptyHashField), efalse0, if_false0);
   2705     efalse0 = graph()->NewNode(
   2706         simplified()->StoreField(AccessBuilder::ForStringLength()), vfalse0,
   2707         jsgraph()->SmiConstant(2), efalse0, if_false0);
   2708     efalse0 = graph()->NewNode(
   2709         machine()->Store(StoreRepresentation(MachineRepresentation::kWord32,
   2710                                              kNoWriteBarrier)),
   2711         vfalse0, jsgraph()->IntPtrConstant(SeqTwoByteString::kHeaderSize -
   2712                                            kHeapObjectTag),
   2713         code, efalse0, if_false0);
   2714   }
   2715 
   2716   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
   2717   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
   2718   value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
   2719                            vtrue0, vfalse0, control);
   2720 
   2721   return ValueEffectControl(value, effect, control);
   2722 }
   2723 
   2724 EffectControlLinearizer::ValueEffectControl
   2725 EffectControlLinearizer::LowerStringComparison(Callable const& callable,
   2726                                                Node* node, Node* effect,
   2727                                                Node* control) {
   2728   Operator::Properties properties = Operator::kEliminatable;
   2729   CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
   2730   CallDescriptor* desc = Linkage::GetStubCallDescriptor(
   2731       isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties);
   2732   node->InsertInput(graph()->zone(), 0,
   2733                     jsgraph()->HeapConstant(callable.code()));
   2734   node->AppendInput(graph()->zone(), jsgraph()->NoContextConstant());
   2735   node->AppendInput(graph()->zone(), effect);
   2736   NodeProperties::ChangeOp(node, common()->Call(desc));
   2737   return ValueEffectControl(node, node, control);
   2738 }
   2739 
   2740 EffectControlLinearizer::ValueEffectControl
   2741 EffectControlLinearizer::LowerStringEqual(Node* node, Node* effect,
   2742                                           Node* control) {
   2743   return LowerStringComparison(CodeFactory::StringEqual(isolate()), node,
   2744                                effect, control);
   2745 }
   2746 
   2747 EffectControlLinearizer::ValueEffectControl
   2748 EffectControlLinearizer::LowerStringLessThan(Node* node, Node* effect,
   2749                                              Node* control) {
   2750   return LowerStringComparison(CodeFactory::StringLessThan(isolate()), node,
   2751                                effect, control);
   2752 }
   2753 
   2754 EffectControlLinearizer::ValueEffectControl
   2755 EffectControlLinearizer::LowerStringLessThanOrEqual(Node* node, Node* effect,
   2756                                                     Node* control) {
   2757   return LowerStringComparison(CodeFactory::StringLessThanOrEqual(isolate()),
   2758                                node, effect, control);
   2759 }
   2760 
   2761 EffectControlLinearizer::ValueEffectControl
   2762 EffectControlLinearizer::LowerCheckFloat64Hole(Node* node, Node* frame_state,
   2763                                                Node* effect, Node* control) {
   2764   // If we reach this point w/o eliminating the {node} that's marked
   2765   // with allow-return-hole, we cannot do anything, so just deoptimize
   2766   // in case of the hole NaN (similar to Crankshaft).
   2767   Node* value = node->InputAt(0);
   2768   Node* check = graph()->NewNode(
   2769       machine()->Word32Equal(),
   2770       graph()->NewNode(machine()->Float64ExtractHighWord32(), value),
   2771       jsgraph()->Int32Constant(kHoleNanUpper32));
   2772   control = effect =
   2773       graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kHole), check,
   2774                        frame_state, effect, control);
   2775 
   2776   return ValueEffectControl(value, effect, control);
   2777 }
   2778 
   2779 EffectControlLinearizer::ValueEffectControl
   2780 EffectControlLinearizer::LowerCheckTaggedHole(Node* node, Node* frame_state,
   2781                                               Node* effect, Node* control) {
   2782   Node* value = node->InputAt(0);
   2783   Node* check = graph()->NewNode(machine()->WordEqual(), value,
   2784                                  jsgraph()->TheHoleConstant());
   2785   control = effect =
   2786       graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kHole), check,
   2787                        frame_state, effect, control);
   2788 
   2789   return ValueEffectControl(value, effect, control);
   2790 }
   2791 
   2792 EffectControlLinearizer::ValueEffectControl
   2793 EffectControlLinearizer::LowerConvertTaggedHoleToUndefined(Node* node,
   2794                                                            Node* effect,
   2795                                                            Node* control) {
   2796   Node* value = node->InputAt(0);
   2797   Node* check = graph()->NewNode(machine()->WordEqual(), value,
   2798                                  jsgraph()->TheHoleConstant());
   2799   Node* branch =
   2800       graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
   2801 
   2802   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
   2803   Node* vtrue = jsgraph()->UndefinedConstant();
   2804 
   2805   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
   2806   Node* vfalse = value;
   2807 
   2808   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
   2809   value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
   2810                            vtrue, vfalse, control);
   2811 
   2812   return ValueEffectControl(value, effect, control);
   2813 }
   2814 
   2815 EffectControlLinearizer::ValueEffectControl
   2816 EffectControlLinearizer::AllocateHeapNumberWithValue(Node* value, Node* effect,
   2817                                                      Node* control) {
   2818   Node* result = effect = graph()->NewNode(
   2819       simplified()->Allocate(NOT_TENURED),
   2820       jsgraph()->Int32Constant(HeapNumber::kSize), effect, control);
   2821   effect = graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()),
   2822                             result, jsgraph()->HeapNumberMapConstant(), effect,
   2823                             control);
   2824   effect = graph()->NewNode(
   2825       simplified()->StoreField(AccessBuilder::ForHeapNumberValue()), result,
   2826       value, effect, control);
   2827   return ValueEffectControl(result, effect, control);
   2828 }
   2829 
   2830 Node* EffectControlLinearizer::ChangeInt32ToSmi(Node* value) {
   2831   if (machine()->Is64()) {
   2832     value = graph()->NewNode(machine()->ChangeInt32ToInt64(), value);
   2833   }
   2834   return graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant());
   2835 }
   2836 
   2837 Node* EffectControlLinearizer::ChangeUint32ToSmi(Node* value) {
   2838   if (machine()->Is64()) {
   2839     value = graph()->NewNode(machine()->ChangeUint32ToUint64(), value);
   2840   }
   2841   return graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant());
   2842 }
   2843 
   2844 Node* EffectControlLinearizer::ChangeInt32ToFloat64(Node* value) {
   2845   return graph()->NewNode(machine()->ChangeInt32ToFloat64(), value);
   2846 }
   2847 
   2848 Node* EffectControlLinearizer::ChangeUint32ToFloat64(Node* value) {
   2849   return graph()->NewNode(machine()->ChangeUint32ToFloat64(), value);
   2850 }
   2851 
   2852 Node* EffectControlLinearizer::ChangeSmiToInt32(Node* value) {
   2853   value = graph()->NewNode(machine()->WordSar(), value, SmiShiftBitsConstant());
   2854   if (machine()->Is64()) {
   2855     value = graph()->NewNode(machine()->TruncateInt64ToInt32(), value);
   2856   }
   2857   return value;
   2858 }
   2859 Node* EffectControlLinearizer::ObjectIsSmi(Node* value) {
   2860   return graph()->NewNode(
   2861       machine()->WordEqual(),
   2862       graph()->NewNode(machine()->WordAnd(), value,
   2863                        jsgraph()->IntPtrConstant(kSmiTagMask)),
   2864       jsgraph()->IntPtrConstant(kSmiTag));
   2865 }
   2866 
   2867 Node* EffectControlLinearizer::SmiMaxValueConstant() {
   2868   return jsgraph()->Int32Constant(Smi::kMaxValue);
   2869 }
   2870 
   2871 Node* EffectControlLinearizer::SmiShiftBitsConstant() {
   2872   return jsgraph()->IntPtrConstant(kSmiShiftSize + kSmiTagSize);
   2873 }
   2874 
   2875 EffectControlLinearizer::ValueEffectControl
   2876 EffectControlLinearizer::LowerPlainPrimitiveToNumber(Node* node, Node* effect,
   2877                                                      Node* control) {
   2878   Node* value = node->InputAt(0);
   2879   Node* result = effect =
   2880       graph()->NewNode(ToNumberOperator(), jsgraph()->ToNumberBuiltinConstant(),
   2881                        value, jsgraph()->NoContextConstant(), effect);
   2882   return ValueEffectControl(result, effect, control);
   2883 }
   2884 
   2885 EffectControlLinearizer::ValueEffectControl
   2886 EffectControlLinearizer::LowerPlainPrimitiveToWord32(Node* node, Node* effect,
   2887                                                      Node* control) {
   2888   Node* value = node->InputAt(0);
   2889 
   2890   Node* check0 = ObjectIsSmi(value);
   2891   Node* branch0 =
   2892       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
   2893 
   2894   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
   2895   Node* etrue0 = effect;
   2896   Node* vtrue0 = ChangeSmiToInt32(value);
   2897 
   2898   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
   2899   Node* efalse0 = effect;
   2900   Node* vfalse0;
   2901   {
   2902     vfalse0 = efalse0 = graph()->NewNode(
   2903         ToNumberOperator(), jsgraph()->ToNumberBuiltinConstant(), value,
   2904         jsgraph()->NoContextConstant(), efalse0);
   2905 
   2906     Node* check1 = ObjectIsSmi(vfalse0);
   2907     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
   2908 
   2909     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
   2910     Node* etrue1 = efalse0;
   2911     Node* vtrue1 = ChangeSmiToInt32(vfalse0);
   2912 
   2913     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
   2914     Node* efalse1 = efalse0;
   2915     Node* vfalse1;
   2916     {
   2917       vfalse1 = efalse1 = graph()->NewNode(
   2918           simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
   2919           efalse1, if_false1);
   2920       vfalse1 = graph()->NewNode(machine()->TruncateFloat64ToWord32(), vfalse1);
   2921     }
   2922 
   2923     if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
   2924     efalse0 =
   2925         graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
   2926     vfalse0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
   2927                                vtrue1, vfalse1, if_false0);
   2928   }
   2929 
   2930   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
   2931   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
   2932   value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
   2933                            vtrue0, vfalse0, control);
   2934   return ValueEffectControl(value, effect, control);
   2935 }
   2936 
   2937 EffectControlLinearizer::ValueEffectControl
   2938 EffectControlLinearizer::LowerPlainPrimitiveToFloat64(Node* node, Node* effect,
   2939                                                       Node* control) {
   2940   Node* value = node->InputAt(0);
   2941 
   2942   Node* check0 = ObjectIsSmi(value);
   2943   Node* branch0 =
   2944       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
   2945 
   2946   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
   2947   Node* etrue0 = effect;
   2948   Node* vtrue0;
   2949   {
   2950     vtrue0 = ChangeSmiToInt32(value);
   2951     vtrue0 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue0);
   2952   }
   2953 
   2954   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
   2955   Node* efalse0 = effect;
   2956   Node* vfalse0;
   2957   {
   2958     vfalse0 = efalse0 = graph()->NewNode(
   2959         ToNumberOperator(), jsgraph()->ToNumberBuiltinConstant(), value,
   2960         jsgraph()->NoContextConstant(), efalse0);
   2961 
   2962     Node* check1 = ObjectIsSmi(vfalse0);
   2963     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
   2964 
   2965     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
   2966     Node* etrue1 = efalse0;
   2967     Node* vtrue1;
   2968     {
   2969       vtrue1 = ChangeSmiToInt32(vfalse0);
   2970       vtrue1 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue1);
   2971     }
   2972 
   2973     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
   2974     Node* efalse1 = efalse0;
   2975     Node* vfalse1;
   2976     {
   2977       vfalse1 = efalse1 = graph()->NewNode(
   2978           simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
   2979           efalse1, if_false1);
   2980     }
   2981 
   2982     if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
   2983     efalse0 =
   2984         graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
   2985     vfalse0 =
   2986         graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
   2987                          vtrue1, vfalse1, if_false0);
   2988   }
   2989 
   2990   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
   2991   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
   2992   value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
   2993                            vtrue0, vfalse0, control);
   2994   return ValueEffectControl(value, effect, control);
   2995 }
   2996 
   2997 EffectControlLinearizer::ValueEffectControl
   2998 EffectControlLinearizer::LowerEnsureWritableFastElements(Node* node,
   2999                                                          Node* effect,
   3000                                                          Node* control) {
   3001   Node* object = node->InputAt(0);
   3002   Node* elements = node->InputAt(1);
   3003 
   3004   // Load the current map of {elements}.
   3005   Node* elements_map = effect =
   3006       graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
   3007                        elements, effect, control);
   3008 
   3009   // Check if {elements} is not a copy-on-write FixedArray.
   3010   Node* check = graph()->NewNode(machine()->WordEqual(), elements_map,
   3011                                  jsgraph()->FixedArrayMapConstant());
   3012   Node* branch =
   3013       graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
   3014 
   3015   // Nothing to do if the {elements} are not copy-on-write.
   3016   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
   3017   Node* etrue = effect;
   3018   Node* vtrue = elements;
   3019 
   3020   // We need to take a copy of the {elements} and set them up for {object}.
   3021   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
   3022   Node* efalse = effect;
   3023   Node* vfalse;
   3024   {
   3025     // We need to create a copy of the {elements} for {object}.
   3026     Operator::Properties properties = Operator::kEliminatable;
   3027     Callable callable = CodeFactory::CopyFastSmiOrObjectElements(isolate());
   3028     CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
   3029     CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
   3030         isolate(), graph()->zone(), callable.descriptor(), 0, flags,
   3031         properties);
   3032     vfalse = efalse = graph()->NewNode(
   3033         common()->Call(desc), jsgraph()->HeapConstant(callable.code()), object,
   3034         jsgraph()->NoContextConstant(), efalse);
   3035   }
   3036 
   3037   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
   3038   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
   3039   Node* value = graph()->NewNode(
   3040       common()->Phi(MachineRepresentation::kTagged, 2), vtrue, vfalse, control);
   3041 
   3042   return ValueEffectControl(value, effect, control);
   3043 }
   3044 
   3045 EffectControlLinearizer::ValueEffectControl
   3046 EffectControlLinearizer::LowerMaybeGrowFastElements(Node* node,
   3047                                                     Node* frame_state,
   3048                                                     Node* effect,
   3049                                                     Node* control) {
   3050   GrowFastElementsFlags flags = GrowFastElementsFlagsOf(node->op());
   3051   Node* object = node->InputAt(0);
   3052   Node* elements = node->InputAt(1);
   3053   Node* index = node->InputAt(2);
   3054   Node* length = node->InputAt(3);
   3055 
   3056   Node* check0 = graph()->NewNode((flags & GrowFastElementsFlag::kHoleyElements)
   3057                                       ? machine()->Uint32LessThanOrEqual()
   3058                                       : machine()->Word32Equal(),
   3059                                   length, index);
   3060   Node* branch0 = graph()->NewNode(common()->Branch(), check0, control);
   3061 
   3062   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
   3063   Node* etrue0 = effect;
   3064   Node* vtrue0 = elements;
   3065   {
   3066     // Load the length of the {elements} backing store.
   3067     Node* elements_length = etrue0 = graph()->NewNode(
   3068         simplified()->LoadField(AccessBuilder::ForFixedArrayLength()), elements,
   3069         etrue0, if_true0);
   3070     elements_length = ChangeSmiToInt32(elements_length);
   3071 
   3072     // Check if we need to grow the {elements} backing store.
   3073     Node* check1 =
   3074         graph()->NewNode(machine()->Uint32LessThan(), index, elements_length);
   3075     Node* branch1 =
   3076         graph()->NewNode(common()->Branch(BranchHint::kTrue), check1, if_true0);
   3077 
   3078     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
   3079     Node* etrue1 = etrue0;
   3080     Node* vtrue1 = vtrue0;
   3081 
   3082     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
   3083     Node* efalse1 = etrue0;
   3084     Node* vfalse1 = vtrue0;
   3085     {
   3086       // We need to grow the {elements} for {object}.
   3087       Operator::Properties properties = Operator::kEliminatable;
   3088       Callable callable =
   3089           (flags & GrowFastElementsFlag::kDoubleElements)
   3090               ? CodeFactory::GrowFastDoubleElements(isolate())
   3091               : CodeFactory::GrowFastSmiOrObjectElements(isolate());
   3092       CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
   3093       CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
   3094           isolate(), graph()->zone(), callable.descriptor(), 0, flags,
   3095           properties);
   3096       vfalse1 = efalse1 = graph()->NewNode(
   3097           common()->Call(desc), jsgraph()->HeapConstant(callable.code()),
   3098           object, ChangeInt32ToSmi(index), jsgraph()->NoContextConstant(),
   3099           efalse1);
   3100 
   3101       // Ensure that we were able to grow the {elements}.
   3102       // TODO(turbofan): We use kSmi as reason here similar to Crankshaft,
   3103       // but maybe we should just introduce a reason that makes sense.
   3104       efalse1 = if_false1 = graph()->NewNode(
   3105           common()->DeoptimizeIf(DeoptimizeReason::kSmi), ObjectIsSmi(vfalse1),
   3106           frame_state, efalse1, if_false1);
   3107     }
   3108 
   3109     if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
   3110     etrue0 =
   3111         graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_true0);
   3112     vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
   3113                               vtrue1, vfalse1, if_true0);
   3114 
   3115     // For JSArray {object}s we also need to update the "length".
   3116     if (flags & GrowFastElementsFlag::kArrayObject) {
   3117       // Compute the new {length}.
   3118       Node* object_length = ChangeInt32ToSmi(graph()->NewNode(
   3119           machine()->Int32Add(), index, jsgraph()->Int32Constant(1)));
   3120 
   3121       // Update the "length" property of the {object}.
   3122       etrue0 =
   3123           graph()->NewNode(simplified()->StoreField(
   3124                                AccessBuilder::ForJSArrayLength(FAST_ELEMENTS)),
   3125                            object, object_length, etrue0, if_true0);
   3126     }
   3127   }
   3128 
   3129   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
   3130   Node* efalse0 = effect;
   3131   Node* vfalse0 = elements;
   3132   {
   3133     // In case of non-holey {elements}, we need to verify that the {index} is
   3134     // in-bounds, otherwise for holey {elements}, the check above already
   3135     // guards the index (and the operator forces {index} to be unsigned).
   3136     if (!(flags & GrowFastElementsFlag::kHoleyElements)) {
   3137       Node* check1 =
   3138           graph()->NewNode(machine()->Uint32LessThan(), index, length);
   3139       efalse0 = if_false0 = graph()->NewNode(
   3140           common()->DeoptimizeUnless(DeoptimizeReason::kOutOfBounds), check1,
   3141           frame_state, efalse0, if_false0);
   3142     }
   3143   }
   3144 
   3145   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
   3146   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
   3147   Node* value =
   3148       graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), vtrue0,
   3149                        vfalse0, control);
   3150 
   3151   return ValueEffectControl(value, effect, control);
   3152 }
   3153 
   3154 EffectControlLinearizer::ValueEffectControl
   3155 EffectControlLinearizer::LowerTransitionElementsKind(Node* node, Node* effect,
   3156                                                      Node* control) {
   3157   ElementsTransition const transition = ElementsTransitionOf(node->op());
   3158   Node* object = node->InputAt(0);
   3159   Node* source_map = node->InputAt(1);
   3160   Node* target_map = node->InputAt(2);
   3161 
   3162   // Load the current map of {object}.
   3163   Node* object_map = effect =
   3164       graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), object,
   3165                        effect, control);
   3166 
   3167   // Check if {object_map} is the same as {source_map}.
   3168   Node* check =
   3169       graph()->NewNode(machine()->WordEqual(), object_map, source_map);
   3170   Node* branch =
   3171       graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
   3172 
   3173   // Migrate the {object} from {source_map} to {target_map}.
   3174   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
   3175   Node* etrue = effect;
   3176   {
   3177     switch (transition) {
   3178       case ElementsTransition::kFastTransition: {
   3179         // In-place migration of {object}, just store the {target_map}.
   3180         etrue =
   3181             graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()),
   3182                              object, target_map, etrue, if_true);
   3183         break;
   3184       }
   3185       case ElementsTransition::kSlowTransition: {
   3186         // Instance migration, call out to the runtime for {object}.
   3187         Operator::Properties properties =
   3188             Operator::kNoDeopt | Operator::kNoThrow;
   3189         Runtime::FunctionId id = Runtime::kTransitionElementsKind;
   3190         CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor(
   3191             graph()->zone(), id, 2, properties, CallDescriptor::kNoFlags);
   3192         etrue = graph()->NewNode(
   3193             common()->Call(desc), jsgraph()->CEntryStubConstant(1), object,
   3194             target_map,
   3195             jsgraph()->ExternalConstant(ExternalReference(id, isolate())),
   3196             jsgraph()->Int32Constant(2), jsgraph()->NoContextConstant(), etrue,
   3197             if_true);
   3198         break;
   3199       }
   3200     }
   3201   }
   3202 
   3203   // Nothing to do if the {object} doesn't have the {source_map}.
   3204   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
   3205   Node* efalse = effect;
   3206 
   3207   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
   3208   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
   3209 
   3210   return ValueEffectControl(nullptr, effect, control);
   3211 }
   3212 
   3213 EffectControlLinearizer::ValueEffectControl
   3214 EffectControlLinearizer::LowerLoadTypedElement(Node* node, Node* effect,
   3215                                                Node* control) {
   3216   ExternalArrayType array_type = ExternalArrayTypeOf(node->op());
   3217   Node* buffer = node->InputAt(0);
   3218   Node* base = node->InputAt(1);
   3219   Node* external = node->InputAt(2);
   3220   Node* index = node->InputAt(3);
   3221 
   3222   // We need to keep the {buffer} alive so that the GC will not release the
   3223   // ArrayBuffer (if there's any) as long as we are still operating on it.
   3224   effect = graph()->NewNode(common()->Retain(), buffer, effect);
   3225 
   3226   // Compute the effective storage pointer.
   3227   Node* storage = effect = graph()->NewNode(machine()->UnsafePointerAdd(), base,
   3228                                             external, effect, control);
   3229 
   3230   // Perform the actual typed element access.
   3231   Node* value = effect = graph()->NewNode(
   3232       simplified()->LoadElement(
   3233           AccessBuilder::ForTypedArrayElement(array_type, true)),
   3234       storage, index, effect, control);
   3235 
   3236   return ValueEffectControl(value, effect, control);
   3237 }
   3238 
   3239 EffectControlLinearizer::ValueEffectControl
   3240 EffectControlLinearizer::LowerStoreTypedElement(Node* node, Node* effect,
   3241                                                 Node* control) {
   3242   ExternalArrayType array_type = ExternalArrayTypeOf(node->op());
   3243   Node* buffer = node->InputAt(0);
   3244   Node* base = node->InputAt(1);
   3245   Node* external = node->InputAt(2);
   3246   Node* index = node->InputAt(3);
   3247   Node* value = node->InputAt(4);
   3248 
   3249   // We need to keep the {buffer} alive so that the GC will not release the
   3250   // ArrayBuffer (if there's any) as long as we are still operating on it.
   3251   effect = graph()->NewNode(common()->Retain(), buffer, effect);
   3252 
   3253   // Compute the effective storage pointer.
   3254   Node* storage = effect = graph()->NewNode(machine()->UnsafePointerAdd(), base,
   3255                                             external, effect, control);
   3256 
   3257   // Perform the actual typed element access.
   3258   effect = graph()->NewNode(
   3259       simplified()->StoreElement(
   3260           AccessBuilder::ForTypedArrayElement(array_type, true)),
   3261       storage, index, value, effect, control);
   3262 
   3263   return ValueEffectControl(nullptr, effect, control);
   3264 }
   3265 
   3266 EffectControlLinearizer::ValueEffectControl
   3267 EffectControlLinearizer::LowerFloat64RoundUp(Node* node, Node* effect,
   3268                                              Node* control) {
   3269   // Nothing to be done if a fast hardware instruction is available.
   3270   if (machine()->Float64RoundUp().IsSupported()) {
   3271     return ValueEffectControl(node, effect, control);
   3272   }
   3273 
   3274   Node* const one = jsgraph()->Float64Constant(1.0);
   3275   Node* const zero = jsgraph()->Float64Constant(0.0);
   3276   Node* const minus_zero = jsgraph()->Float64Constant(-0.0);
   3277   Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0);
   3278   Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0);
   3279   Node* const input = node->InputAt(0);
   3280 
   3281   // General case for ceil.
   3282   //
   3283   //   if 0.0 < input then
   3284   //     if 2^52 <= input then
   3285   //       input
   3286   //     else
   3287   //       let temp1 = (2^52 + input) - 2^52 in
   3288   //       if temp1 < input then
   3289   //         temp1 + 1
   3290   //       else
   3291   //         temp1
   3292   //   else
   3293   //     if input == 0 then
   3294   //       input
   3295   //     else
   3296   //       if input <= -2^52 then
   3297   //         input
   3298   //       else
   3299   //         let temp1 = -0 - input in
   3300   //         let temp2 = (2^52 + temp1) - 2^52 in
   3301   //         let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in
   3302   //         -0 - temp3
   3303   //
   3304   // Note: We do not use the Diamond helper class here, because it really hurts
   3305   // readability with nested diamonds.
   3306 
   3307   Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input);
   3308   Node* branch0 =
   3309       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
   3310 
   3311   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
   3312   Node* vtrue0;
   3313   {
   3314     Node* check1 =
   3315         graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input);
   3316     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
   3317 
   3318     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
   3319     Node* vtrue1 = input;
   3320 
   3321     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
   3322     Node* vfalse1;
   3323     {
   3324       Node* temp1 = graph()->NewNode(
   3325           machine()->Float64Sub(),
   3326           graph()->NewNode(machine()->Float64Add(), two_52, input), two_52);
   3327       vfalse1 = graph()->NewNode(
   3328           common()->Select(MachineRepresentation::kFloat64),
   3329           graph()->NewNode(machine()->Float64LessThan(), temp1, input),
   3330           graph()->NewNode(machine()->Float64Add(), temp1, one), temp1);
   3331     }
   3332 
   3333     if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
   3334     vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
   3335                               vtrue1, vfalse1, if_true0);
   3336   }
   3337 
   3338   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
   3339   Node* vfalse0;
   3340   {
   3341     Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero);
   3342     Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
   3343                                      check1, if_false0);
   3344 
   3345     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
   3346     Node* vtrue1 = input;
   3347 
   3348     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
   3349     Node* vfalse1;
   3350     {
   3351       Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(),
   3352                                       input, minus_two_52);
   3353       Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
   3354                                        check2, if_false1);
   3355 
   3356       Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
   3357       Node* vtrue2 = input;
   3358 
   3359       Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
   3360       Node* vfalse2;
   3361       {
   3362         Node* temp1 =
   3363             graph()->NewNode(machine()->Float64Sub(), minus_zero, input);
   3364         Node* temp2 = graph()->NewNode(
   3365             machine()->Float64Sub(),
   3366             graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52);
   3367         Node* temp3 = graph()->NewNode(
   3368             common()->Select(MachineRepresentation::kFloat64),
   3369             graph()->NewNode(machine()->Float64LessThan(), temp1, temp2),
   3370             graph()->NewNode(machine()->Float64Sub(), temp2, one), temp2);
   3371         vfalse2 = graph()->NewNode(machine()->Float64Sub(), minus_zero, temp3);
   3372       }
   3373 
   3374       if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
   3375       vfalse1 =
   3376           graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
   3377                            vtrue2, vfalse2, if_false1);
   3378     }
   3379 
   3380     if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
   3381     vfalse0 =
   3382         graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
   3383                          vtrue1, vfalse1, if_false0);
   3384   }
   3385 
   3386   Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
   3387   Node* value =
   3388       graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
   3389                        vtrue0, vfalse0, merge0);
   3390   return ValueEffectControl(value, effect, merge0);
   3391 }
   3392 
   3393 EffectControlLinearizer::ValueEffectControl
   3394 EffectControlLinearizer::BuildFloat64RoundDown(Node* value, Node* effect,
   3395                                                Node* control) {
   3396   if (machine()->Float64RoundDown().IsSupported()) {
   3397     value = graph()->NewNode(machine()->Float64RoundDown().op(), value);
   3398   } else {
   3399     Node* const one = jsgraph()->Float64Constant(1.0);
   3400     Node* const zero = jsgraph()->Float64Constant(0.0);
   3401     Node* const minus_one = jsgraph()->Float64Constant(-1.0);
   3402     Node* const minus_zero = jsgraph()->Float64Constant(-0.0);
   3403     Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0);
   3404     Node* const minus_two_52 =
   3405         jsgraph()->Float64Constant(-4503599627370496.0E0);
   3406     Node* const input = value;
   3407 
   3408     // General case for floor.
   3409     //
   3410     //   if 0.0 < input then
   3411     //     if 2^52 <= input then
   3412     //       input
   3413     //     else
   3414     //       let temp1 = (2^52 + input) - 2^52 in
   3415     //       if input < temp1 then
   3416     //         temp1 - 1
   3417     //       else
   3418     //         temp1
   3419     //   else
   3420     //     if input == 0 then
   3421     //       input
   3422     //     else
   3423     //       if input <= -2^52 then
   3424     //         input
   3425     //       else
   3426     //         let temp1 = -0 - input in
   3427     //         let temp2 = (2^52 + temp1) - 2^52 in
   3428     //         if temp2 < temp1 then
   3429     //           -1 - temp2
   3430     //         else
   3431     //           -0 - temp2
   3432     //
   3433     // Note: We do not use the Diamond helper class here, because it really
   3434     // hurts
   3435     // readability with nested diamonds.
   3436 
   3437     Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input);
   3438     Node* branch0 =
   3439         graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
   3440 
   3441     Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
   3442     Node* vtrue0;
   3443     {
   3444       Node* check1 =
   3445           graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input);
   3446       Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
   3447 
   3448       Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
   3449       Node* vtrue1 = input;
   3450 
   3451       Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
   3452       Node* vfalse1;
   3453       {
   3454         Node* temp1 = graph()->NewNode(
   3455             machine()->Float64Sub(),
   3456             graph()->NewNode(machine()->Float64Add(), two_52, input), two_52);
   3457         vfalse1 = graph()->NewNode(
   3458             common()->Select(MachineRepresentation::kFloat64),
   3459             graph()->NewNode(machine()->Float64LessThan(), input, temp1),
   3460             graph()->NewNode(machine()->Float64Sub(), temp1, one), temp1);
   3461       }
   3462 
   3463       if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
   3464       vtrue0 =
   3465           graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
   3466                            vtrue1, vfalse1, if_true0);
   3467     }
   3468 
   3469     Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
   3470     Node* vfalse0;
   3471     {
   3472       Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero);
   3473       Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
   3474                                        check1, if_false0);
   3475 
   3476       Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
   3477       Node* vtrue1 = input;
   3478 
   3479       Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
   3480       Node* vfalse1;
   3481       {
   3482         Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(),
   3483                                         input, minus_two_52);
   3484         Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
   3485                                          check2, if_false1);
   3486 
   3487         Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
   3488         Node* vtrue2 = input;
   3489 
   3490         Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
   3491         Node* vfalse2;
   3492         {
   3493           Node* temp1 =
   3494               graph()->NewNode(machine()->Float64Sub(), minus_zero, input);
   3495           Node* temp2 = graph()->NewNode(
   3496               machine()->Float64Sub(),
   3497               graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52);
   3498           vfalse2 = graph()->NewNode(
   3499               common()->Select(MachineRepresentation::kFloat64),
   3500               graph()->NewNode(machine()->Float64LessThan(), temp2, temp1),
   3501               graph()->NewNode(machine()->Float64Sub(), minus_one, temp2),
   3502               graph()->NewNode(machine()->Float64Sub(), minus_zero, temp2));
   3503         }
   3504 
   3505         if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
   3506         vfalse1 =
   3507             graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
   3508                              vtrue2, vfalse2, if_false1);
   3509       }
   3510 
   3511       if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
   3512       vfalse0 =
   3513           graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
   3514                            vtrue1, vfalse1, if_false0);
   3515     }
   3516 
   3517     control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
   3518     value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
   3519                              vtrue0, vfalse0, control);
   3520   }
   3521   return ValueEffectControl(value, effect, control);
   3522 }
   3523 
   3524 EffectControlLinearizer::ValueEffectControl
   3525 EffectControlLinearizer::LowerFloat64RoundDown(Node* node, Node* effect,
   3526                                                Node* control) {
   3527   // Nothing to be done if a fast hardware instruction is available.
   3528   if (machine()->Float64RoundDown().IsSupported()) {
   3529     return ValueEffectControl(node, effect, control);
   3530   }
   3531 
   3532   Node* const input = node->InputAt(0);
   3533   return BuildFloat64RoundDown(input, effect, control);
   3534 }
   3535 
   3536 EffectControlLinearizer::ValueEffectControl
   3537 EffectControlLinearizer::LowerFloat64RoundTiesEven(Node* node, Node* effect,
   3538                                                    Node* control) {
   3539   // Nothing to be done if a fast hardware instruction is available.
   3540   if (machine()->Float64RoundTiesEven().IsSupported()) {
   3541     return ValueEffectControl(node, effect, control);
   3542   }
   3543 
   3544   Node* const one = jsgraph()->Float64Constant(1.0);
   3545   Node* const two = jsgraph()->Float64Constant(2.0);
   3546   Node* const half = jsgraph()->Float64Constant(0.5);
   3547   Node* const zero = jsgraph()->Float64Constant(0.0);
   3548   Node* const input = node->InputAt(0);
   3549 
   3550   // Generate case for round ties to even:
   3551   //
   3552   //   let value = floor(input) in
   3553   //   let temp1 = input - value in
   3554   //   if temp1 < 0.5 then
   3555   //     value
   3556   //   else if 0.5 < temp1 then
   3557   //     value + 1.0
   3558   //   else
   3559   //     let temp2 = value % 2.0 in
   3560   //     if temp2 == 0.0 then
   3561   //       value
   3562   //     else
   3563   //       value + 1.0
   3564   //
   3565   // Note: We do not use the Diamond helper class here, because it really hurts
   3566   // readability with nested diamonds.
   3567 
   3568   ValueEffectControl continuation =
   3569       BuildFloat64RoundDown(input, effect, control);
   3570   Node* value = continuation.value;
   3571   effect = continuation.effect;
   3572   control = continuation.control;
   3573 
   3574   Node* temp1 = graph()->NewNode(machine()->Float64Sub(), input, value);
   3575 
   3576   Node* check0 = graph()->NewNode(machine()->Float64LessThan(), temp1, half);
   3577   Node* branch0 = graph()->NewNode(common()->Branch(), check0, control);
   3578 
   3579   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
   3580   Node* vtrue0 = value;
   3581 
   3582   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
   3583   Node* vfalse0;
   3584   {
   3585     Node* check1 = graph()->NewNode(machine()->Float64LessThan(), half, temp1);
   3586     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
   3587 
   3588     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
   3589     Node* vtrue1 = graph()->NewNode(machine()->Float64Add(), value, one);
   3590 
   3591     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
   3592     Node* vfalse1;
   3593     {
   3594       Node* temp2 = graph()->NewNode(machine()->Float64Mod(), value, two);
   3595 
   3596       Node* check2 = graph()->NewNode(machine()->Float64Equal(), temp2, zero);
   3597       Node* branch2 = graph()->NewNode(common()->Branch(), check2, if_false1);
   3598 
   3599       Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
   3600       Node* vtrue2 = value;
   3601 
   3602       Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
   3603       Node* vfalse2 = graph()->NewNode(machine()->Float64Add(), value, one);
   3604 
   3605       if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
   3606       vfalse1 =
   3607           graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
   3608                            vtrue2, vfalse2, if_false1);
   3609     }
   3610 
   3611     if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
   3612     vfalse0 =
   3613         graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
   3614                          vtrue1, vfalse1, if_false0);
   3615   }
   3616 
   3617   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
   3618   value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
   3619                            vtrue0, vfalse0, control);
   3620 
   3621   return ValueEffectControl(value, effect, control);
   3622 }
   3623 
   3624 EffectControlLinearizer::ValueEffectControl
   3625 EffectControlLinearizer::LowerFloat64RoundTruncate(Node* node, Node* effect,
   3626                                                    Node* control) {
   3627   // Nothing to be done if a fast hardware instruction is available.
   3628   if (machine()->Float64RoundTruncate().IsSupported()) {
   3629     return ValueEffectControl(node, effect, control);
   3630   }
   3631 
   3632   Node* const one = jsgraph()->Float64Constant(1.0);
   3633   Node* const zero = jsgraph()->Float64Constant(0.0);
   3634   Node* const minus_zero = jsgraph()->Float64Constant(-0.0);
   3635   Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0);
   3636   Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0);
   3637   Node* const input = node->InputAt(0);
   3638 
   3639   // General case for trunc.
   3640   //
   3641   //   if 0.0 < input then
   3642   //     if 2^52 <= input then
   3643   //       input
   3644   //     else
   3645   //       let temp1 = (2^52 + input) - 2^52 in
   3646   //       if input < temp1 then
   3647   //         temp1 - 1
   3648   //       else
   3649   //         temp1
   3650   //   else
   3651   //     if input == 0 then
   3652   //       input
   3653   //     else
   3654   //       if input <= -2^52 then
   3655   //         input
   3656   //       else
   3657   //         let temp1 = -0 - input in
   3658   //         let temp2 = (2^52 + temp1) - 2^52 in
   3659   //         let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in
   3660   //         -0 - temp3
   3661   //
   3662   // Note: We do not use the Diamond helper class here, because it really hurts
   3663   // readability with nested diamonds.
   3664 
   3665   Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input);
   3666   Node* branch0 =
   3667       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
   3668 
   3669   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
   3670   Node* vtrue0;
   3671   {
   3672     Node* check1 =
   3673         graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input);
   3674     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
   3675 
   3676     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
   3677     Node* vtrue1 = input;
   3678 
   3679     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
   3680     Node* vfalse1;
   3681     {
   3682       Node* temp1 = graph()->NewNode(
   3683           machine()->Float64Sub(),
   3684           graph()->NewNode(machine()->Float64Add(), two_52, input), two_52);
   3685       vfalse1 = graph()->NewNode(
   3686           common()->Select(MachineRepresentation::kFloat64),
   3687           graph()->NewNode(machine()->Float64LessThan(), input, temp1),
   3688           graph()->NewNode(machine()->Float64Sub(), temp1, one), temp1);
   3689     }
   3690 
   3691     if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
   3692     vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
   3693                               vtrue1, vfalse1, if_true0);
   3694   }
   3695 
   3696   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
   3697   Node* vfalse0;
   3698   {
   3699     Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero);
   3700     Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
   3701                                      check1, if_false0);
   3702 
   3703     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
   3704     Node* vtrue1 = input;
   3705 
   3706     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
   3707     Node* vfalse1;
   3708     {
   3709       Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(),
   3710                                       input, minus_two_52);
   3711       Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
   3712                                        check2, if_false1);
   3713 
   3714       Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
   3715       Node* vtrue2 = input;
   3716 
   3717       Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
   3718       Node* vfalse2;
   3719       {
   3720         Node* temp1 =
   3721             graph()->NewNode(machine()->Float64Sub(), minus_zero, input);
   3722         Node* temp2 = graph()->NewNode(
   3723             machine()->Float64Sub(),
   3724             graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52);
   3725         Node* temp3 = graph()->NewNode(
   3726             common()->Select(MachineRepresentation::kFloat64),
   3727             graph()->NewNode(machine()->Float64LessThan(), temp1, temp2),
   3728             graph()->NewNode(machine()->Float64Sub(), temp2, one), temp2);
   3729         vfalse2 = graph()->NewNode(machine()->Float64Sub(), minus_zero, temp3);
   3730       }
   3731 
   3732       if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
   3733       vfalse1 =
   3734           graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
   3735                            vtrue2, vfalse2, if_false1);
   3736     }
   3737 
   3738     if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
   3739     vfalse0 =
   3740         graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
   3741                          vtrue1, vfalse1, if_false0);
   3742   }
   3743 
   3744   Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
   3745   Node* value =
   3746       graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
   3747                        vtrue0, vfalse0, merge0);
   3748   return ValueEffectControl(value, effect, merge0);
   3749 }
   3750 
   3751 Factory* EffectControlLinearizer::factory() const {
   3752   return isolate()->factory();
   3753 }
   3754 
   3755 Isolate* EffectControlLinearizer::isolate() const {
   3756   return jsgraph()->isolate();
   3757 }
   3758 
   3759 Operator const* EffectControlLinearizer::ToNumberOperator() {
   3760   if (!to_number_operator_.is_set()) {
   3761     Callable callable = CodeFactory::ToNumber(isolate());
   3762     CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
   3763     CallDescriptor* desc = Linkage::GetStubCallDescriptor(
   3764         isolate(), graph()->zone(), callable.descriptor(), 0, flags,
   3765         Operator::kEliminatable);
   3766     to_number_operator_.set(common()->Call(desc));
   3767   }
   3768   return to_number_operator_.get();
   3769 }
   3770 
   3771 }  // namespace compiler
   3772 }  // namespace internal
   3773 }  // namespace v8
   3774