LCOV - code coverage report
Current view: top level - src/compiler - simplified-lowering.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1618 1713 94.5 %
Date: 2019-04-18 Functions: 90 94 95.7 %

          Line data    Source code
       1             : // Copyright 2014 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/simplified-lowering.h"
       6             : 
       7             : #include <limits>
       8             : 
       9             : #include "src/address-map.h"
      10             : #include "src/base/bits.h"
      11             : #include "src/code-factory.h"
      12             : #include "src/compiler/access-builder.h"
      13             : #include "src/compiler/common-operator.h"
      14             : #include "src/compiler/compiler-source-position-table.h"
      15             : #include "src/compiler/diamond.h"
      16             : #include "src/compiler/linkage.h"
      17             : #include "src/compiler/node-matchers.h"
      18             : #include "src/compiler/node-origin-table.h"
      19             : #include "src/compiler/node-properties.h"
      20             : #include "src/compiler/operation-typer.h"
      21             : #include "src/compiler/operator-properties.h"
      22             : #include "src/compiler/representation-change.h"
      23             : #include "src/compiler/simplified-operator.h"
      24             : #include "src/compiler/type-cache.h"
      25             : #include "src/conversions-inl.h"
      26             : #include "src/objects.h"
      27             : 
      28             : namespace v8 {
      29             : namespace internal {
      30             : namespace compiler {
      31             : 
      32             : // Macro for outputting trace information from representation inference.
      33             : #define TRACE(...)                                      \
      34             :   do {                                                  \
      35             :     if (FLAG_trace_representation) PrintF(__VA_ARGS__); \
      36             :   } while (false)
      37             : 
      38             : // Representation selection and lowering of {Simplified} operators to machine
      39             : // operators are interwined. We use a fixpoint calculation to compute both the
      40             : // output representation and the best possible lowering for {Simplified} nodes.
      41             : // Representation change insertion ensures that all values are in the correct
      42             : // machine representation after this phase, as dictated by the machine
      43             : // operators themselves.
      44             : enum Phase {
      45             :   // 1.) PROPAGATE: Traverse the graph from the end, pushing usage information
      46             :   //     backwards from uses to definitions, around cycles in phis, according
      47             :   //     to local rules for each operator.
      48             :   //     During this phase, the usage information for a node determines the best
      49             :   //     possible lowering for each operator so far, and that in turn determines
      50             :   //     the output representation.
      51             :   //     Therefore, to be correct, this phase must iterate to a fixpoint before
      52             :   //     the next phase can begin.
      53             :   PROPAGATE,
      54             : 
      55             :   // 2.) RETYPE: Propagate types from type feedback forwards.
      56             :   RETYPE,
      57             : 
      58             :   // 3.) LOWER: perform lowering for all {Simplified} nodes by replacing some
      59             :   //     operators for some nodes, expanding some nodes to multiple nodes, or
      60             :   //     removing some (redundant) nodes.
      61             :   //     During this phase, use the {RepresentationChanger} to insert
      62             :   //     representation changes between uses that demand a particular
      63             :   //     representation and nodes that produce a different representation.
      64             :   LOWER
      65             : };
      66             : 
      67             : namespace {
      68             : 
      69       33920 : MachineRepresentation MachineRepresentationFromArrayType(
      70             :     ExternalArrayType array_type) {
      71       33920 :   switch (array_type) {
      72             :     case kExternalUint8Array:
      73             :     case kExternalUint8ClampedArray:
      74             :     case kExternalInt8Array:
      75             :       return MachineRepresentation::kWord8;
      76             :     case kExternalUint16Array:
      77             :     case kExternalInt16Array:
      78        5295 :       return MachineRepresentation::kWord16;
      79             :     case kExternalUint32Array:
      80             :     case kExternalInt32Array:
      81        6525 :       return MachineRepresentation::kWord32;
      82             :     case kExternalFloat32Array:
      83        7852 :       return MachineRepresentation::kFloat32;
      84             :     case kExternalFloat64Array:
      85        3090 :       return MachineRepresentation::kFloat64;
      86             :     case kExternalBigInt64Array:
      87             :     case kExternalBigUint64Array:
      88           0 :       UNIMPLEMENTED();
      89             :   }
      90           0 :   UNREACHABLE();
      91             : }
      92             : 
      93     1084050 : UseInfo CheckedUseInfoAsWord32FromHint(
      94             :     NumberOperationHint hint, const VectorSlotPair& feedback = VectorSlotPair(),
      95             :     IdentifyZeros identify_zeros = kDistinguishZeros) {
      96     1084050 :   switch (hint) {
      97             :     case NumberOperationHint::kSignedSmall:
      98             :     case NumberOperationHint::kSignedSmallInputs:
      99             :       return UseInfo::CheckedSignedSmallAsWord32(identify_zeros, feedback);
     100             :     case NumberOperationHint::kSigned32:
     101             :       return UseInfo::CheckedSigned32AsWord32(identify_zeros, feedback);
     102             :     case NumberOperationHint::kNumber:
     103             :       return UseInfo::CheckedNumberAsWord32(feedback);
     104             :     case NumberOperationHint::kNumberOrOddball:
     105             :       return UseInfo::CheckedNumberOrOddballAsWord32(feedback);
     106             :   }
     107           0 :   UNREACHABLE();
     108             : }
     109             : 
     110      166444 : UseInfo CheckedUseInfoAsFloat64FromHint(
     111             :     NumberOperationHint hint, const VectorSlotPair& feedback,
     112             :     IdentifyZeros identify_zeros = kDistinguishZeros) {
     113      166444 :   switch (hint) {
     114             :     case NumberOperationHint::kSignedSmall:
     115             :     case NumberOperationHint::kSignedSmallInputs:
     116             :     case NumberOperationHint::kSigned32:
     117             :       // Not used currently.
     118           0 :       UNREACHABLE();
     119             :       break;
     120             :     case NumberOperationHint::kNumber:
     121             :       return UseInfo::CheckedNumberAsFloat64(identify_zeros, feedback);
     122             :     case NumberOperationHint::kNumberOrOddball:
     123             :       return UseInfo::CheckedNumberOrOddballAsFloat64(identify_zeros, feedback);
     124             :   }
     125           0 :   UNREACHABLE();
     126             : }
     127             : 
     128     8116324 : UseInfo TruncatingUseInfoFromRepresentation(MachineRepresentation rep) {
     129     8116324 :   switch (rep) {
     130             :     case MachineRepresentation::kTaggedSigned:
     131             :       return UseInfo::TaggedSigned();
     132             :     case MachineRepresentation::kTaggedPointer:
     133             :     case MachineRepresentation::kTagged:
     134             :       return UseInfo::AnyTagged();
     135             :     case MachineRepresentation::kCompressedSigned:
     136             :       return UseInfo::CompressedSigned();
     137             :     case MachineRepresentation::kCompressedPointer:
     138             :     case MachineRepresentation::kCompressed:
     139             :       return UseInfo::AnyCompressed();
     140             :     case MachineRepresentation::kFloat64:
     141             :       return UseInfo::TruncatingFloat64();
     142             :     case MachineRepresentation::kFloat32:
     143             :       return UseInfo::Float32();
     144             :     case MachineRepresentation::kWord8:
     145             :     case MachineRepresentation::kWord16:
     146             :     case MachineRepresentation::kWord32:
     147             :       return UseInfo::TruncatingWord32();
     148             :     case MachineRepresentation::kWord64:
     149             :       return UseInfo::Word64();
     150             :     case MachineRepresentation::kBit:
     151             :       return UseInfo::Bool();
     152             :     case MachineRepresentation::kSimd128:
     153             :     case MachineRepresentation::kNone:
     154             :       break;
     155             :   }
     156           0 :   UNREACHABLE();
     157             : }
     158             : 
     159     9989591 : UseInfo UseInfoForBasePointer(const FieldAccess& access) {
     160    19979192 :   return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::Word();
     161             : }
     162             : 
     163      182315 : UseInfo UseInfoForBasePointer(const ElementAccess& access) {
     164      364630 :   return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::Word();
     165             : }
     166             : 
     167      349123 : void ReplaceEffectControlUses(Node* node, Node* effect, Node* control) {
     168     2002884 :   for (Edge edge : node->use_edges()) {
     169      826887 :     if (NodeProperties::IsControlEdge(edge)) {
     170           0 :       edge.UpdateTo(control);
     171      826880 :     } else if (NodeProperties::IsEffectEdge(edge)) {
     172      419847 :       edge.UpdateTo(effect);
     173             :     } else {
     174             :       DCHECK(NodeProperties::IsValueEdge(edge) ||
     175             :              NodeProperties::IsContextEdge(edge));
     176             :     }
     177             :   }
     178      349110 : }
     179             : 
     180      154604 : bool CanOverflowSigned32(const Operator* op, Type left, Type right,
     181             :                          Zone* type_zone) {
     182             :   // We assume the inputs are checked Signed32 (or known statically
     183             :   // to be Signed32). Technically, the inputs could also be minus zero, but
     184             :   // that cannot cause overflow.
     185      154604 :   left = Type::Intersect(left, Type::Signed32(), type_zone);
     186      154599 :   right = Type::Intersect(right, Type::Signed32(), type_zone);
     187      309172 :   if (left.IsNone() || right.IsNone()) return false;
     188      154567 :   switch (op->opcode()) {
     189             :     case IrOpcode::kSpeculativeSafeIntegerAdd:
     190      150318 :       return (left.Max() + right.Max() > kMaxInt) ||
     191        4279 :              (left.Min() + right.Min() < kMinInt);
     192             : 
     193             :     case IrOpcode::kSpeculativeSafeIntegerSubtract:
     194       16360 :       return (left.Max() - right.Min() > kMaxInt) ||
     195        7832 :              (left.Min() - right.Max() < kMinInt);
     196             : 
     197             :     default:
     198           0 :       UNREACHABLE();
     199             :   }
     200             :   return true;
     201             : }
     202             : 
     203        8899 : bool IsSomePositiveOrderedNumber(Type type) {
     204       14899 :   return type.Is(Type::OrderedNumber()) && !type.IsNone() && type.Min() > 0;
     205             : }
     206             : 
     207             : }  // namespace
     208             : 
     209             : #ifdef DEBUG
     210             : // Helpers for monotonicity checking.
     211             : class InputUseInfos {
     212             :  public:
     213             :   explicit InputUseInfos(Zone* zone) : input_use_infos_(zone) {}
     214             : 
     215             :   void SetAndCheckInput(Node* node, int index, UseInfo use_info) {
     216             :     if (input_use_infos_.empty()) {
     217             :       input_use_infos_.resize(node->InputCount(), UseInfo::None());
     218             :     }
     219             :     // Check that the new use informatin is a super-type of the old
     220             :     // one.
     221             :     DCHECK(IsUseLessGeneral(input_use_infos_[index], use_info));
     222             :     input_use_infos_[index] = use_info;
     223             :   }
     224             : 
     225             :  private:
     226             :   ZoneVector<UseInfo> input_use_infos_;
     227             : 
     228             :   static bool IsUseLessGeneral(UseInfo use1, UseInfo use2) {
     229             :     return use1.truncation().IsLessGeneralThan(use2.truncation());
     230             :   }
     231             : };
     232             : 
     233             : #endif  // DEBUG
     234             : 
     235      463909 : class RepresentationSelector {
     236             :  public:
     237             :   // Information for each node tracked during the fixpoint.
     238      463902 :   class NodeInfo final {
     239             :    public:
     240             :     // Adds new use to the node. Returns true if something has changed
     241             :     // and the node has to be requeued.
     242    99995593 :     bool AddUse(UseInfo info) {
     243    99995593 :       Truncation old_truncation = truncation_;
     244    99993409 :       truncation_ = Truncation::Generalize(truncation_, info.truncation());
     245    99993409 :       return truncation_ != old_truncation;
     246             :     }
     247             : 
     248    36456928 :     void set_queued() { state_ = kQueued; }
     249    66957194 :     void set_visited() { state_ = kVisited; }
     250    30500950 :     void set_pushed() { state_ = kPushed; }
     251    43130397 :     void reset_state() { state_ = kUnvisited; }
     252             :     bool visited() const { return state_ == kVisited; }
     253             :     bool queued() const { return state_ == kQueued; }
     254             :     bool unvisited() const { return state_ == kUnvisited; }
     255             :     Truncation truncation() const { return truncation_; }
     256    34794523 :     void set_output(MachineRepresentation output) { representation_ = output; }
     257             : 
     258             :     MachineRepresentation representation() const { return representation_; }
     259             : 
     260             :     // Helpers for feedback typing.
     261    21377222 :     void set_feedback_type(Type type) { feedback_type_ = type; }
     262             :     Type feedback_type() const { return feedback_type_; }
     263       91391 :     void set_weakened() { weakened_ = true; }
     264             :     bool weakened() const { return weakened_; }
     265    30598396 :     void set_restriction_type(Type type) { restriction_type_ = type; }
     266             :     Type restriction_type() const { return restriction_type_; }
     267             : 
     268             :    private:
     269             :     enum State : uint8_t { kUnvisited, kPushed, kVisited, kQueued };
     270             :     State state_ = kUnvisited;
     271             :     MachineRepresentation representation_ =
     272             :         MachineRepresentation::kNone;             // Output representation.
     273             :     Truncation truncation_ = Truncation::None();  // Information about uses.
     274             : 
     275             :     Type restriction_type_ = Type::Any();
     276             :     Type feedback_type_;
     277             :     bool weakened_ = false;
     278             :   };
     279             : 
     280      463902 :   RepresentationSelector(JSGraph* jsgraph, JSHeapBroker* broker, Zone* zone,
     281             :                          RepresentationChanger* changer,
     282             :                          SourcePositionTable* source_positions,
     283             :                          NodeOriginTable* node_origins)
     284             :       : jsgraph_(jsgraph),
     285             :         zone_(zone),
     286             :         count_(jsgraph->graph()->NodeCount()),
     287             :         info_(count_, zone),
     288             : #ifdef DEBUG
     289             :         node_input_use_infos_(count_, InputUseInfos(zone), zone),
     290             : #endif
     291             :         nodes_(zone),
     292             :         replacements_(zone),
     293             :         phase_(PROPAGATE),
     294             :         changer_(changer),
     295             :         queue_(zone),
     296             :         typing_stack_(zone),
     297             :         source_positions_(source_positions),
     298             :         node_origins_(node_origins),
     299      463912 :         type_cache_(TypeCache::Get()),
     300     1855622 :         op_typer_(broker, graph_zone()) {
     301      463913 :   }
     302             : 
     303             :   // Forward propagation of types from type feedback.
     304      463904 :   void RunTypePropagationPhase() {
     305             :     // Run type propagation.
     306      463904 :     TRACE("--{Type propagation phase}--\n");
     307      463912 :     phase_ = RETYPE;
     308             :     ResetNodeInfoState();
     309             : 
     310             :     DCHECK(typing_stack_.empty());
     311      927278 :     typing_stack_.push({graph()->end(), 0});
     312             :     GetInfo(graph()->end())->set_pushed();
     313    61002761 :     while (!typing_stack_.empty()) {
     314             :       NodeState& current = typing_stack_.top();
     315             : 
     316             :       // If there is an unvisited input, push it and continue.
     317             :       bool pushed_unvisited = false;
     318   254849192 :       while (current.input_index < current.node->InputCount()) {
     319             :         Node* input = current.node->InputAt(current.input_index);
     320             :         NodeInfo* input_info = GetInfo(input);
     321    96923249 :         current.input_index++;
     322    96923249 :         if (input_info->unvisited()) {
     323             :           input_info->set_pushed();
     324    60075383 :           typing_stack_.push({input, 0});
     325             :           pushed_unvisited = true;
     326    30037799 :           break;
     327             :         }
     328             :       }
     329    60539146 :       if (pushed_unvisited) continue;
     330             : 
     331             :       // Process the top of the stack.
     332    30501345 :       Node* node = current.node;
     333             :       typing_stack_.pop();
     334             :       NodeInfo* info = GetInfo(node);
     335             :       info->set_visited();
     336    30501225 :       bool updated = UpdateFeedbackType(node);
     337    30500881 :       TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
     338    30500881 :       VisitNode(node, info->truncation(), nullptr);
     339    30501168 :       TRACE("  ==> output ");
     340    30501168 :       PrintOutputInfo(info);
     341    30501136 :       TRACE("\n");
     342    30501619 :       if (updated) {
     343   180077746 :         for (Node* const user : node->uses()) {
     344    80095315 :           if (GetInfo(user)->visited()) {
     345             :             GetInfo(user)->set_queued();
     346             :             queue_.push(user);
     347             :           }
     348             :         }
     349             :       }
     350             :     }
     351             : 
     352             :     // Process the revisit queue.
     353     5471706 :     while (!queue_.empty()) {
     354     5007807 :       Node* node = queue_.front();
     355             :       queue_.pop();
     356             :       NodeInfo* info = GetInfo(node);
     357             :       info->set_visited();
     358     5007807 :       bool updated = UpdateFeedbackType(node);
     359     5007815 :       TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
     360     5007815 :       VisitNode(node, info->truncation(), nullptr);
     361     5007825 :       TRACE("  ==> output ");
     362     5007825 :       PrintOutputInfo(info);
     363     5007822 :       TRACE("\n");
     364     5007870 :       if (updated) {
     365    13095636 :         for (Node* const user : node->uses()) {
     366     5802762 :           if (GetInfo(user)->visited()) {
     367             :             GetInfo(user)->set_queued();
     368             :             queue_.push(user);
     369             :           }
     370             :         }
     371             :       }
     372             :     }
     373      463899 :   }
     374             : 
     375             :   void ResetNodeInfoState() {
     376             :     // Clean up for the next phase.
     377    43594309 :     for (NodeInfo& info : info_) {
     378             :       info.reset_state();
     379             :     }
     380             :   }
     381             : 
     382             :   Type TypeOf(Node* node) {
     383             :     Type type = GetInfo(node)->feedback_type();
     384    45127983 :     return type.IsInvalid() ? NodeProperties::GetType(node) : type;
     385             :   }
     386             : 
     387             :   Type FeedbackTypeOf(Node* node) {
     388             :     Type type = GetInfo(node)->feedback_type();
     389    38110660 :     return type.IsInvalid() ? Type::None() : type;
     390             :   }
     391             : 
     392      801157 :   Type TypePhi(Node* node) {
     393             :     int arity = node->op()->ValueInputCount();
     394             :     Type type = FeedbackTypeOf(node->InputAt(0));
     395     3176889 :     for (int i = 1; i < arity; ++i) {
     396     1187880 :       type = op_typer_.Merge(type, FeedbackTypeOf(node->InputAt(i)));
     397             :     }
     398      801143 :     return type;
     399             :   }
     400             : 
     401       12561 :   Type TypeSelect(Node* node) {
     402             :     return op_typer_.Merge(FeedbackTypeOf(node->InputAt(1)),
     403       12561 :                            FeedbackTypeOf(node->InputAt(2)));
     404             :   }
     405             : 
     406    35508223 :   bool UpdateFeedbackType(Node* node) {
     407    35508223 :     if (node->op()->ValueOutputCount() == 0) return false;
     408             : 
     409             :     NodeInfo* info = GetInfo(node);
     410             :     Type type = info->feedback_type();
     411    25127720 :     Type new_type = type;
     412             : 
     413             :     // For any non-phi node just wait until we get all inputs typed. We only
     414             :     // allow untyped inputs for phi nodes because phis are the only places
     415             :     // where cycles need to be broken.
     416    25127720 :     if (node->opcode() != IrOpcode::kPhi) {
     417   141772116 :       for (int i = 0; i < node->op()->ValueInputCount(); i++) {
     418    59566881 :         if (GetInfo(node->InputAt(i))->feedback_type().IsInvalid()) {
     419             :           return false;
     420             :         }
     421             :       }
     422             :     }
     423             : 
     424             :     // We preload these values here to avoid increasing the binary size too
     425             :     // much, which happens if we inline the calls into the macros below.
     426             :     Type input0_type;
     427    43847248 :     if (node->InputCount() > 0) input0_type = FeedbackTypeOf(node->InputAt(0));
     428             :     Type input1_type;
     429    40783012 :     if (node->InputCount() > 1) input1_type = FeedbackTypeOf(node->InputAt(1));
     430             : 
     431    24283607 :     switch (node->opcode()) {
     432             : #define DECLARE_CASE(Name)                               \
     433             :   case IrOpcode::k##Name: {                              \
     434             :     new_type = op_typer_.Name(input0_type, input1_type); \
     435             :     break;                                               \
     436             :   }
     437      480798 :       SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
     438          78 :       DECLARE_CASE(SameValue)
     439             : #undef DECLARE_CASE
     440             : 
     441             : #define DECLARE_CASE(Name)                                               \
     442             :   case IrOpcode::k##Name: {                                              \
     443             :     new_type = Type::Intersect(op_typer_.Name(input0_type, input1_type), \
     444             :                                info->restriction_type(), graph_zone());  \
     445             :     break;                                                               \
     446             :   }
     447        1058 :       SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
     448             : #undef DECLARE_CASE
     449             : 
     450             : #define DECLARE_CASE(Name)                  \
     451             :   case IrOpcode::k##Name: {                 \
     452             :     new_type = op_typer_.Name(input0_type); \
     453             :     break;                                  \
     454             :   }
     455         296 :       SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
     456             : #undef DECLARE_CASE
     457             : 
     458             : #define DECLARE_CASE(Name)                                              \
     459             :   case IrOpcode::k##Name: {                                             \
     460             :     new_type = Type::Intersect(op_typer_.Name(input0_type),             \
     461             :                                info->restriction_type(), graph_zone()); \
     462             :     break;                                                              \
     463             :   }
     464       40727 :       SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_CASE)
     465             : #undef DECLARE_CASE
     466             : 
     467             :       case IrOpcode::kConvertReceiver:
     468         880 :         new_type = op_typer_.ConvertReceiver(input0_type);
     469         880 :         break;
     470             : 
     471             :       case IrOpcode::kPlainPrimitiveToNumber:
     472        1050 :         new_type = op_typer_.ToNumber(input0_type);
     473        1050 :         break;
     474             : 
     475             :       case IrOpcode::kCheckBounds:
     476             :         new_type =
     477             :             Type::Intersect(op_typer_.CheckBounds(input0_type, input1_type),
     478       64108 :                             info->restriction_type(), graph_zone());
     479       64108 :         break;
     480             : 
     481             :       case IrOpcode::kCheckFloat64Hole:
     482             :         new_type = Type::Intersect(op_typer_.CheckFloat64Hole(input0_type),
     483         592 :                                    info->restriction_type(), graph_zone());
     484         592 :         break;
     485             : 
     486             :       case IrOpcode::kCheckNumber:
     487             :         new_type = Type::Intersect(op_typer_.CheckNumber(input0_type),
     488         522 :                                    info->restriction_type(), graph_zone());
     489         522 :         break;
     490             : 
     491             :       case IrOpcode::kPhi: {
     492      801155 :         new_type = TypePhi(node);
     493      801142 :         if (!type.IsInvalid()) {
     494      481955 :           new_type = Weaken(node, type, new_type);
     495             :         }
     496             :         break;
     497             :       }
     498             : 
     499             :       case IrOpcode::kConvertTaggedHoleToUndefined:
     500             :         new_type = op_typer_.ConvertTaggedHoleToUndefined(
     501        2123 :             FeedbackTypeOf(node->InputAt(0)));
     502        2123 :         break;
     503             : 
     504             :       case IrOpcode::kTypeGuard: {
     505             :         new_type = op_typer_.TypeTypeGuard(node->op(),
     506       31332 :                                            FeedbackTypeOf(node->InputAt(0)));
     507       31332 :         break;
     508             :       }
     509             : 
     510             :       case IrOpcode::kSelect: {
     511       12561 :         new_type = TypeSelect(node);
     512       12561 :         break;
     513             :       }
     514             : 
     515             :       default:
     516             :         // Shortcut for operations that we do not handle.
     517    22397433 :         if (type.IsInvalid()) {
     518             :           GetInfo(node)->set_feedback_type(NodeProperties::GetType(node));
     519    19706500 :           return true;
     520             :         }
     521             :         return false;
     522             :     }
     523             :     // We need to guarantee that the feedback type is a subtype of the upper
     524             :     // bound. Naively that should hold, but weakening can actually produce
     525             :     // a bigger type if we are unlucky with ordering of phi typing. To be
     526             :     // really sure, just intersect the upper bound with the feedback type.
     527     1886145 :     new_type = Type::Intersect(GetUpperBound(node), new_type, graph_zone());
     528             : 
     529     2847178 :     if (!type.IsInvalid() && new_type.Is(type)) return false;
     530             :     GetInfo(node)->set_feedback_type(new_type);
     531     1670722 :     if (FLAG_trace_representation) {
     532           0 :       PrintNodeFeedbackType(node);
     533             :     }
     534             :     return true;
     535             :   }
     536             : 
     537           0 :   void PrintNodeFeedbackType(Node* n) {
     538           0 :     StdoutStream os;
     539           0 :     os << "#" << n->id() << ":" << *n->op() << "(";
     540             :     int j = 0;
     541           0 :     for (Node* const i : n->inputs()) {
     542           0 :       if (j++ > 0) os << ", ";
     543           0 :       os << "#" << i->id() << ":" << i->op()->mnemonic();
     544             :     }
     545           0 :     os << ")";
     546           0 :     if (NodeProperties::IsTyped(n)) {
     547             :       Type static_type = NodeProperties::GetType(n);
     548           0 :       os << "  [Static type: " << static_type;
     549             :       Type feedback_type = GetInfo(n)->feedback_type();
     550           0 :       if (!feedback_type.IsInvalid() && feedback_type != static_type) {
     551           0 :         os << ", Feedback type: " << feedback_type;
     552             :       }
     553           0 :       os << "]";
     554             :     }
     555             :     os << std::endl;
     556           0 :   }
     557             : 
     558      481954 :   Type Weaken(Node* node, Type previous_type, Type current_type) {
     559             :     // If the types have nothing to do with integers, return the types.
     560      481954 :     Type const integer = type_cache_->kInteger;
     561      481954 :     if (!previous_type.Maybe(integer)) {
     562       29730 :       return current_type;
     563             :     }
     564             :     DCHECK(current_type.Maybe(integer));
     565             : 
     566      452228 :     Type current_integer = Type::Intersect(current_type, integer, graph_zone());
     567             :     DCHECK(!current_integer.IsNone());
     568             :     Type previous_integer =
     569      452230 :         Type::Intersect(previous_type, integer, graph_zone());
     570             :     DCHECK(!previous_integer.IsNone());
     571             : 
     572             :     // Once we start weakening a node, we should always weaken.
     573      452228 :     if (!GetInfo(node)->weakened()) {
     574             :       // Only weaken if there is range involved; we should converge quickly
     575             :       // for all other types (the exception is a union of many constants,
     576             :       // but we currently do not increase the number of constants in unions).
     577       95655 :       Type previous = previous_integer.GetRange();
     578       95655 :       Type current = current_integer.GetRange();
     579      187139 :       if (current.IsInvalid() || previous.IsInvalid()) {
     580        4263 :         return current_type;
     581             :       }
     582             :       // Range is involved => we are weakening.
     583             :       GetInfo(node)->set_weakened();
     584             :     }
     585             : 
     586             :     return Type::Union(current_type,
     587             :                        op_typer_.WeakenRange(previous_integer, current_integer),
     588      447964 :                        graph_zone());
     589             :   }
     590             : 
     591             :   // Backward propagation of truncations.
     592      463909 :   void RunTruncationPropagationPhase() {
     593             :     // Run propagation phase to a fixpoint.
     594      463909 :     TRACE("--{Propagation phase}--\n");
     595      463909 :     phase_ = PROPAGATE;
     596      463909 :     EnqueueInitial(jsgraph_->graph()->end());
     597             :     // Process nodes from the queue until it is empty.
     598    63360243 :     while (!queue_.empty()) {
     599    31448169 :       Node* node = queue_.front();
     600             :       NodeInfo* info = GetInfo(node);
     601             :       queue_.pop();
     602             :       info->set_visited();
     603    31448162 :       TRACE(" visit #%d: %s (trunc: %s)\n", node->id(), node->op()->mnemonic(),
     604             :             info->truncation().description());
     605    31448162 :       VisitNode(node, info->truncation(), nullptr);
     606             :     }
     607      463911 :   }
     608             : 
     609      463910 :   void Run(SimplifiedLowering* lowering) {
     610      463910 :     RunTruncationPropagationPhase();
     611             : 
     612      463909 :     RunTypePropagationPhase();
     613             : 
     614             :     // Run lowering and change insertion phase.
     615      463898 :     TRACE("--{Simplified lowering phase}--\n");
     616      463896 :     phase_ = LOWER;
     617             :     // Process nodes from the collected {nodes_} vector.
     618    30965150 :     for (NodeVector::iterator i = nodes_.begin(); i != nodes_.end(); ++i) {
     619    30501236 :       Node* node = *i;
     620             :       NodeInfo* info = GetInfo(node);
     621    30501236 :       TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
     622             :       // Reuse {VisitNode()} so the representation rules are in one place.
     623             :       SourcePositionTable::Scope scope(
     624    30501236 :           source_positions_, source_positions_->GetSourcePosition(node));
     625             :       NodeOriginTable::Scope origin_scope(node_origins_, "simplified lowering",
     626    30501180 :                                           node);
     627    30501180 :       VisitNode(node, info->truncation(), lowering);
     628             :     }
     629             : 
     630             :     // Perform the final replacements.
     631     1720767 :     for (NodeVector::iterator i = replacements_.begin();
     632             :          i != replacements_.end(); ++i) {
     633     1256859 :       Node* node = *i;
     634     1256859 :       Node* replacement = *(++i);
     635     1256859 :       node->ReplaceUses(replacement);
     636     1256852 :       node->Kill();
     637             :       // We also need to replace the node in the rest of the vector.
     638   186514575 :       for (NodeVector::iterator j = i + 1; j != replacements_.end(); ++j) {
     639             :         ++j;
     640   185257722 :         if (*j == node) *j = replacement;
     641             :       }
     642             :     }
     643      463908 :   }
     644             : 
     645      463909 :   void EnqueueInitial(Node* node) {
     646      463909 :     NodeInfo* info = GetInfo(node);
     647             :     info->set_queued();
     648      463909 :     nodes_.push_back(node);
     649             :     queue_.push(node);
     650      463909 :   }
     651             : 
     652             :   // Enqueue {use_node}'s {index} input if the {use} contains new information
     653             :   // for that input node. Add the input to {nodes_} if this is the first time
     654             :   // it's been visited.
     655   158837926 :   void EnqueueInput(Node* use_node, int index,
     656             :                     UseInfo use_info = UseInfo::None()) {
     657   158837926 :     Node* node = use_node->InputAt(index);
     658   247713004 :     if (phase_ != PROPAGATE) return;
     659             :     NodeInfo* info = GetInfo(node);
     660             : #ifdef DEBUG
     661             :     // Check monotonicity of input requirements.
     662             :     node_input_use_infos_[use_node->id()].SetAndCheckInput(use_node, index,
     663             :                                                            use_info);
     664             : #endif  // DEBUG
     665   100000003 :     if (info->unvisited()) {
     666             :       // First visit of this node.
     667             :       info->set_queued();
     668    30037664 :       nodes_.push_back(node);
     669             :       queue_.push(node);
     670    30037486 :       TRACE("  initial #%i: ", node->id());
     671    30037486 :       info->AddUse(use_info);
     672    30037216 :       PrintTruncation(info->truncation());
     673    30037155 :       return;
     674             :     }
     675    69962339 :     TRACE("   queue #%i?: ", node->id());
     676    69962339 :     PrintTruncation(info->truncation());
     677    69961629 :     if (info->AddUse(use_info)) {
     678             :       // New usage information for the node is available.
     679     2350486 :       if (!info->queued()) {
     680             :         queue_.push(node);
     681             :         info->set_queued();
     682      947464 :         TRACE("   added: ");
     683             :       } else {
     684     1403018 :         TRACE(" inqueue: ");
     685             :       }
     686     2350482 :       PrintTruncation(info->truncation());
     687             :     }
     688             :   }
     689             : 
     690             :   bool lower() const { return phase_ == LOWER; }
     691             :   bool retype() const { return phase_ == RETYPE; }
     692             :   bool propagate() const { return phase_ == PROPAGATE; }
     693             : 
     694             :   void SetOutput(Node* node, MachineRepresentation representation,
     695             :                  Type restriction_type = Type::Any()) {
     696             :     NodeInfo* const info = GetInfo(node);
     697    95266243 :     switch (phase_) {
     698             :       case PROPAGATE:
     699             :         info->set_restriction_type(restriction_type);
     700             :         break;
     701             :       case RETYPE:
     702             :         DCHECK(info->restriction_type().Is(restriction_type));
     703             :         DCHECK(restriction_type.Is(info->restriction_type()));
     704             :         info->set_output(representation);
     705             :         break;
     706             :       case LOWER:
     707             :         DCHECK_EQ(info->representation(), representation);
     708             :         DCHECK(info->restriction_type().Is(restriction_type));
     709             :         DCHECK(restriction_type.Is(info->restriction_type()));
     710             :         break;
     711             :     }
     712             :   }
     713             : 
     714             :   Type GetUpperBound(Node* node) { return NodeProperties::GetType(node); }
     715             : 
     716       88170 :   bool InputCannotBe(Node* node, Type type) {
     717             :     DCHECK_EQ(1, node->op()->ValueInputCount());
     718       88170 :     return !GetUpperBound(node->InputAt(0)).Maybe(type);
     719             :   }
     720             : 
     721       56635 :   bool InputIs(Node* node, Type type) {
     722             :     DCHECK_EQ(1, node->op()->ValueInputCount());
     723      113270 :     return GetUpperBound(node->InputAt(0)).Is(type);
     724             :   }
     725             : 
     726             :   bool BothInputsAreSigned32(Node* node) {
     727       96316 :     return BothInputsAre(node, Type::Signed32());
     728             :   }
     729             : 
     730             :   bool BothInputsAreUnsigned32(Node* node) {
     731      102786 :     return BothInputsAre(node, Type::Unsigned32());
     732             :   }
     733             : 
     734     1035786 :   bool BothInputsAre(Node* node, Type type) {
     735             :     DCHECK_EQ(2, node->op()->ValueInputCount());
     736     2380322 :     return GetUpperBound(node->InputAt(0)).Is(type) &&
     737     1344536 :            GetUpperBound(node->InputAt(1)).Is(type);
     738             :   }
     739             : 
     740             :   bool IsNodeRepresentationTagged(Node* node) {
     741             :     MachineRepresentation representation = GetInfo(node)->representation();
     742             :     return IsAnyTagged(representation);
     743             :   }
     744             : 
     745          72 :   bool OneInputCannotBe(Node* node, Type type) {
     746             :     DCHECK_EQ(2, node->op()->ValueInputCount());
     747         144 :     return !GetUpperBound(node->InputAt(0)).Maybe(type) ||
     748         144 :            !GetUpperBound(node->InputAt(1)).Maybe(type);
     749             :   }
     750             : 
     751      334172 :   void ChangeToPureOp(Node* node, const Operator* new_op) {
     752             :     DCHECK(new_op->HasProperty(Operator::kPure));
     753      334172 :     if (node->op()->EffectInputCount() > 0) {
     754             :       DCHECK_LT(0, node->op()->ControlInputCount());
     755      210892 :       Node* control = NodeProperties::GetControlInput(node);
     756      210887 :       Node* effect = NodeProperties::GetEffectInput(node);
     757      210879 :       if (TypeOf(node).IsNone()) {
     758             :         // If the node is unreachable, insert an Unreachable node and mark the
     759             :         // value dead.
     760             :         // TODO(jarin,tebbi) Find a way to unify/merge this insertion with
     761             :         // InsertUnreachableIfNecessary.
     762         320 :         Node* unreachable = effect = graph()->NewNode(
     763         320 :             jsgraph_->common()->Unreachable(), effect, control);
     764         320 :         new_op = jsgraph_->common()->DeadValue(GetInfo(node)->representation());
     765         320 :         node->ReplaceInput(0, unreachable);
     766             :       }
     767             :       // Rewire the effect and control chains.
     768      210879 :       node->TrimInputCount(new_op->ValueInputCount());
     769      210884 :       ReplaceEffectControlUses(node, effect, control);
     770             :     } else {
     771             :       DCHECK_EQ(0, node->op()->ControlInputCount());
     772             :     }
     773      334161 :     NodeProperties::ChangeOp(node, new_op);
     774      334155 :   }
     775             : 
     776             :   // Converts input {index} of {node} according to given UseInfo {use},
     777             :   // assuming the type of the input is {input_type}. If {input_type} is null,
     778             :   // it takes the input from the input node {TypeOf(node->InputAt(index))}.
     779    53206859 :   void ConvertInput(Node* node, int index, UseInfo use,
     780             :                     Type input_type = Type::Invalid()) {
     781             :     Node* input = node->InputAt(index);
     782             :     // In the change phase, insert a change before the use if necessary.
     783    53206859 :     if (use.representation() == MachineRepresentation::kNone)
     784             :       return;  // No input requirement on the use.
     785             :     DCHECK_NOT_NULL(input);
     786             :     NodeInfo* input_info = GetInfo(input);
     787             :     MachineRepresentation input_rep = input_info->representation();
     788    50752576 :     if (input_rep != use.representation() ||
     789             :         use.type_check() != TypeCheckKind::kNone) {
     790             :       // Output representation doesn't match usage.
     791    16044534 :       TRACE("  change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(),
     792             :             index, input->id(), input->op()->mnemonic());
     793    16044517 :       TRACE(" from ");
     794    16044517 :       PrintOutputInfo(input_info);
     795    16044497 :       TRACE(" to ");
     796    16044497 :       PrintUseInfo(use);
     797    16044478 :       TRACE("\n");
     798    16044487 :       if (input_type.IsInvalid()) {
     799             :         input_type = TypeOf(input);
     800             :       }
     801    16044487 :       Node* n = changer_->GetRepresentationFor(
     802    16044487 :           input, input_info->representation(), input_type, node, use);
     803    16044414 :       node->ReplaceInput(index, n);
     804             :     }
     805             :   }
     806             : 
     807   171887197 :   void ProcessInput(Node* node, int index, UseInfo use) {
     808   171887197 :     switch (phase_) {
     809             :       case PROPAGATE:
     810    55066896 :         EnqueueInput(node, index, use);
     811    55064779 :         break;
     812             :       case RETYPE:
     813             :         break;
     814             :       case LOWER:
     815    53186512 :         ConvertInput(node, index, use);
     816    53185859 :         break;
     817             :     }
     818   171884427 :   }
     819             : 
     820    18339461 :   void ProcessRemainingInputs(Node* node, int index) {
     821             :     DCHECK_GE(index, NodeProperties::PastValueIndex(node));
     822             :     DCHECK_GE(index, NodeProperties::PastContextIndex(node));
     823    78559593 :     for (int i = std::max(index, NodeProperties::FirstEffectIndex(node));
     824    30110079 :          i < NodeProperties::PastEffectIndex(node); ++i) {
     825    11770659 :       EnqueueInput(node, i);  // Effect inputs: just visit
     826             :     }
     827    78688193 :     for (int i = std::max(index, NodeProperties::FirstControlIndex(node));
     828    30174369 :          i < NodeProperties::PastControlIndex(node); ++i) {
     829    11834946 :       EnqueueInput(node, i);  // Control inputs: just visit
     830             :     }
     831    18339484 :   }
     832             : 
     833             :   // The default, most general visitation case. For {node}, process all value,
     834             :   // context, frame state, effect, and control inputs, assuming that value
     835             :   // inputs should have {kRepTagged} representation and can observe all output
     836             :   // values {kTypeAny}.
     837    29654413 :   void VisitInputs(Node* node) {
     838    29654174 :     int tagged_count = node->op()->ValueInputCount() +
     839             :                        OperatorProperties::GetContextInputCount(node->op()) +
     840    29653796 :                        OperatorProperties::GetFrameStateInputCount(node->op());
     841             :     // Visit value, context and frame state inputs as tagged.
     842   116139950 :     for (int i = 0; i < tagged_count; i++) {
     843    43243135 :       ProcessInput(node, i, UseInfo::AnyTagged());
     844             :     }
     845             :     // Only enqueue other inputs (effects, control).
     846   141497636 :     for (int i = tagged_count; i < node->InputCount(); i++) {
     847    55922048 :       EnqueueInput(node, i);
     848             :     }
     849    29654676 :   }
     850             : 
     851     1666039 :   void VisitReturn(Node* node) {
     852     1666037 :     int tagged_limit = node->op()->ValueInputCount() +
     853             :                        OperatorProperties::GetContextInputCount(node->op()) +
     854     1666037 :                        OperatorProperties::GetFrameStateInputCount(node->op());
     855             :     // Visit integer slot count to pop
     856     1666038 :     ProcessInput(node, 0, UseInfo::TruncatingWord32());
     857             : 
     858             :     // Visit value, context and frame state inputs as tagged.
     859     4998133 :     for (int i = 1; i < tagged_limit; i++) {
     860     1666042 :       ProcessInput(node, i, UseInfo::AnyTagged());
     861             :     }
     862             :     // Only enqueue other inputs (effects, control).
     863     8330239 :     for (int i = tagged_limit; i < node->InputCount(); i++) {
     864     3332085 :       EnqueueInput(node, i);
     865             :     }
     866     1666047 :   }
     867             : 
     868             :   // Helper for an unused node.
     869      329075 :   void VisitUnused(Node* node) {
     870      329075 :     int value_count = node->op()->ValueInputCount() +
     871             :                       OperatorProperties::GetContextInputCount(node->op()) +
     872      329076 :                       OperatorProperties::GetFrameStateInputCount(node->op());
     873     1370482 :     for (int i = 0; i < value_count; i++) {
     874      520704 :       ProcessInput(node, i, UseInfo::None());
     875             :     }
     876      329075 :     ProcessRemainingInputs(node, value_count);
     877      329075 :     if (lower()) Kill(node);
     878      329075 :   }
     879             : 
     880             :   // Helper for no-op node.
     881          36 :   void VisitNoop(Node* node, Truncation truncation) {
     882          36 :     if (truncation.IsUnused()) return VisitUnused(node);
     883             :     MachineRepresentation representation =
     884          22 :         GetOutputInfoForPhi(node, TypeOf(node), truncation);
     885          44 :     VisitUnop(node, UseInfo(representation, truncation), representation);
     886          33 :     if (lower()) DeferReplacement(node, node->InputAt(0));
     887             :   }
     888             : 
     889             :   // Helper for binops of the R x L -> O variety.
     890     3503558 :   void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use,
     891             :                   MachineRepresentation output,
     892             :                   Type restriction_type = Type::Any()) {
     893             :     DCHECK_EQ(2, node->op()->ValueInputCount());
     894     3503558 :     ProcessInput(node, 0, left_use);
     895     3503082 :     ProcessInput(node, 1, right_use);
     896    10188280 :     for (int i = 2; i < node->InputCount(); i++) {
     897     3342574 :       EnqueueInput(node, i);
     898             :     }
     899             :     SetOutput(node, output, restriction_type);
     900     3503542 :   }
     901             : 
     902             :   // Helper for binops of the I x I -> O variety.
     903             :   void VisitBinop(Node* node, UseInfo input_use, MachineRepresentation output,
     904             :                   Type restriction_type = Type::Any()) {
     905     2858806 :     VisitBinop(node, input_use, input_use, output, restriction_type);
     906             :   }
     907             : 
     908       81401 :   void VisitSpeculativeInt32Binop(Node* node) {
     909             :     DCHECK_EQ(2, node->op()->ValueInputCount());
     910       81401 :     if (BothInputsAre(node, Type::NumberOrOddball())) {
     911             :       return VisitBinop(node, UseInfo::TruncatingWord32(),
     912             :                         MachineRepresentation::kWord32);
     913             :     }
     914       18439 :     NumberOperationHint hint = NumberOperationHintOf(node->op());
     915       36878 :     return VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
     916       18439 :                       MachineRepresentation::kWord32);
     917             :   }
     918             : 
     919             :   // Helper for unops of the I -> O variety.
     920    10692031 :   void VisitUnop(Node* node, UseInfo input_use, MachineRepresentation output,
     921             :                  Type restriction_type = Type::Any()) {
     922             :     DCHECK_EQ(1, node->op()->ValueInputCount());
     923    10692031 :     ProcessInput(node, 0, input_use);
     924    10692028 :     ProcessRemainingInputs(node, 1);
     925             :     SetOutput(node, output, restriction_type);
     926    10692024 :   }
     927             : 
     928             :   // Helper for leaf nodes.
     929             :   void VisitLeaf(Node* node, MachineRepresentation output) {
     930             :     DCHECK_EQ(0, node->InputCount());
     931             :     SetOutput(node, output);
     932             :   }
     933             : 
     934             :   // Helpers for specific types of binops.
     935      631606 :   void VisitFloat64Binop(Node* node) {
     936             :     VisitBinop(node, UseInfo::TruncatingFloat64(),
     937             :                MachineRepresentation::kFloat64);
     938      631636 :   }
     939        2082 :   void VisitInt64Binop(Node* node) {
     940             :     VisitBinop(node, UseInfo::Word64(), MachineRepresentation::kWord64);
     941        2082 :   }
     942      489741 :   void VisitWord32TruncatingBinop(Node* node) {
     943             :     VisitBinop(node, UseInfo::TruncatingWord32(),
     944             :                MachineRepresentation::kWord32);
     945      489778 :   }
     946             : 
     947             :   // Infer representation for phi-like nodes.
     948             :   // The {node} parameter is only used to decide on the int64 representation.
     949             :   // Once the type system supports an external pointer type, the {node}
     950             :   // parameter can be removed.
     951     1644260 :   MachineRepresentation GetOutputInfoForPhi(Node* node, Type type,
     952             :                                             Truncation use) {
     953             :     // Compute the representation.
     954     1644233 :     if (type.Is(Type::None())) {
     955             :       return MachineRepresentation::kNone;
     956     2939602 :     } else if (type.Is(Type::Signed32()) || type.Is(Type::Unsigned32())) {
     957             :       return MachineRepresentation::kWord32;
     958     2130447 :     } else if (type.Is(Type::NumberOrOddball()) && use.IsUsedAsWord32()) {
     959             :       return MachineRepresentation::kWord32;
     960     1299917 :     } else if (type.Is(Type::Boolean())) {
     961             :       return MachineRepresentation::kBit;
     962     1950394 :     } else if (type.Is(Type::NumberOrOddball()) && use.IsUsedAsFloat64()) {
     963             :       return MachineRepresentation::kFloat64;
     964     2288310 :     } else if (type.Is(Type::Union(Type::SignedSmall(), Type::NaN(), zone()))) {
     965             :       // TODO(turbofan): For Phis that return either NaN or some Smi, it's
     966             :       // beneficial to not go all the way to double, unless the uses are
     967             :       // double uses. For tagging that just means some potentially expensive
     968             :       // allocation code; we might want to do the same for -0 as well?
     969             :       return MachineRepresentation::kTagged;
     970     1144039 :     } else if (type.Is(Type::Number())) {
     971             :       return MachineRepresentation::kFloat64;
     972      490396 :     } else if (type.Is(Type::ExternalPointer())) {
     973             :       return MachineType::PointerRepresentation();
     974             :     }
     975      490396 :     return MachineRepresentation::kTagged;
     976             :   }
     977             : 
     978             :   // Helper for handling selects.
     979       38614 :   void VisitSelect(Node* node, Truncation truncation,
     980             :                    SimplifiedLowering* lowering) {
     981             :     DCHECK(TypeOf(node->InputAt(0)).Is(Type::Boolean()));
     982       38614 :     ProcessInput(node, 0, UseInfo::Bool());
     983             : 
     984             :     MachineRepresentation output =
     985       38614 :         GetOutputInfoForPhi(node, TypeOf(node), truncation);
     986             :     SetOutput(node, output);
     987             : 
     988       38614 :     if (lower()) {
     989             :       // Update the select operator.
     990       12561 :       SelectParameters p = SelectParametersOf(node->op());
     991       12561 :       if (output != p.representation()) {
     992        7244 :         NodeProperties::ChangeOp(node,
     993        7244 :                                  lowering->common()->Select(output, p.hint()));
     994             :       }
     995             :     }
     996             :     // Convert inputs to the output representation of this phi, pass the
     997             :     // truncation truncation along.
     998       77228 :     UseInfo input_use(output, truncation);
     999       38614 :     ProcessInput(node, 1, input_use);
    1000       38614 :     ProcessInput(node, 2, input_use);
    1001       38614 :   }
    1002             : 
    1003             :   // Helper for handling phis.
    1004     1521124 :   void VisitPhi(Node* node, Truncation truncation,
    1005             :                 SimplifiedLowering* lowering) {
    1006             :     MachineRepresentation output =
    1007     1521124 :         GetOutputInfoForPhi(node, TypeOf(node), truncation);
    1008             :     // Only set the output representation if not running with type
    1009             :     // feedback. (Feedback typing will set the representation.)
    1010             :     SetOutput(node, output);
    1011             : 
    1012             :     int values = node->op()->ValueInputCount();
    1013     1521095 :     if (lower()) {
    1014             :       // Update the phi operator.
    1015      319212 :       if (output != PhiRepresentationOf(node->op())) {
    1016      177042 :         NodeProperties::ChangeOp(node, lowering->common()->Phi(output, values));
    1017             :       }
    1018             :     }
    1019             : 
    1020             :     // Convert inputs to the output representation of this phi, pass the
    1021             :     // truncation along.
    1022     3042556 :     UseInfo input_use(output, truncation);
    1023    12755149 :     for (int i = 0; i < node->InputCount(); i++) {
    1024    11234256 :       ProcessInput(node, i, i < values ? input_use : UseInfo::None());
    1025             :     }
    1026     1521165 :   }
    1027             : 
    1028      162139 :   void VisitObjectIs(Node* node, Type type, SimplifiedLowering* lowering) {
    1029      162139 :     Type const input_type = TypeOf(node->InputAt(0));
    1030      162139 :     if (input_type.Is(type)) {
    1031        3996 :       VisitUnop(node, UseInfo::None(), MachineRepresentation::kBit);
    1032        3996 :       if (lower()) {
    1033        1364 :         DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
    1034             :       }
    1035             :     } else {
    1036      158143 :       VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    1037      158143 :       if (lower() && !input_type.Maybe(type)) {
    1038         481 :         DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
    1039             :       }
    1040             :     }
    1041      162139 :   }
    1042             : 
    1043        9061 :   void VisitCheck(Node* node, Type type, SimplifiedLowering* lowering) {
    1044        9061 :     if (InputIs(node, type)) {
    1045             :       VisitUnop(node, UseInfo::AnyTagged(),
    1046         218 :                 MachineRepresentation::kTaggedPointer);
    1047         279 :       if (lower()) DeferReplacement(node, node->InputAt(0));
    1048             :     } else {
    1049       17686 :       VisitUnop(node,
    1050             :                 UseInfo::CheckedHeapObjectAsTaggedPointer(VectorSlotPair()),
    1051        8843 :                 MachineRepresentation::kTaggedPointer);
    1052             :     }
    1053        9061 :   }
    1054             : 
    1055      338051 :   void VisitCall(Node* node, SimplifiedLowering* lowering) {
    1056      338051 :     auto call_descriptor = CallDescriptorOf(node->op());
    1057      338055 :     int params = static_cast<int>(call_descriptor->ParameterCount());
    1058             :     int value_input_count = node->op()->ValueInputCount();
    1059             :     // Propagate representation information from call descriptor.
    1060     5134935 :     for (int i = 0; i < value_input_count; i++) {
    1061     2398428 :       if (i == 0) {
    1062             :         // The target of the call.
    1063      338057 :         ProcessInput(node, i, UseInfo::Any());
    1064     2060373 :       } else if ((i - 1) < params) {
    1065     1727307 :         ProcessInput(node, i,
    1066             :                      TruncatingUseInfoFromRepresentation(
    1067     3454605 :                          call_descriptor->GetInputType(i).representation()));
    1068             :       } else {
    1069      333067 :         ProcessInput(node, i, UseInfo::AnyTagged());
    1070             :       }
    1071             :     }
    1072      338067 :     ProcessRemainingInputs(node, value_input_count);
    1073             : 
    1074      338065 :     if (call_descriptor->ReturnCount() > 0) {
    1075             :       SetOutput(node, call_descriptor->GetReturnType(0).representation());
    1076             :     } else {
    1077             :       SetOutput(node, MachineRepresentation::kTagged);
    1078             :     }
    1079      338065 :   }
    1080             : 
    1081       10009 :   void MaskShiftOperand(Node* node, Type rhs_type) {
    1082       20018 :     if (!rhs_type.Is(type_cache_->kZeroToThirtyOne)) {
    1083         950 :       Node* const rhs = NodeProperties::GetValueInput(node, 1);
    1084        1900 :       node->ReplaceInput(1,
    1085         950 :                          graph()->NewNode(jsgraph_->machine()->Word32And(), rhs,
    1086        1900 :                                           jsgraph_->Int32Constant(0x1F)));
    1087             :     }
    1088       10009 :   }
    1089             : 
    1090      532773 :   static MachineSemantic DeoptValueSemanticOf(Type type) {
    1091             :     // We only need signedness to do deopt correctly.
    1092      532775 :     if (type.Is(Type::Signed32())) {
    1093             :       return MachineSemantic::kInt32;
    1094      363655 :     } else if (type.Is(Type::Unsigned32())) {
    1095             :       return MachineSemantic::kUint32;
    1096             :     } else {
    1097      362135 :       return MachineSemantic::kAny;
    1098             :     }
    1099             :   }
    1100             : 
    1101    11290230 :   static MachineType DeoptMachineTypeOf(MachineRepresentation rep, Type type) {
    1102    11290230 :     if (type.IsNone()) {
    1103             :       return MachineType::None();
    1104             :     }
    1105             :     // Do not distinguish between various Tagged variations.
    1106    11290230 :     if (IsAnyTagged(rep)) {
    1107             :       return MachineType::AnyTagged();
    1108             :     }
    1109             :     // Do not distinguish between various Compressed variations.
    1110      532824 :     if (IsAnyCompressed(rep)) {
    1111             :       return MachineType::AnyCompressed();
    1112             :     }
    1113             :     // Word64 representation is only valid for safe integer values.
    1114      532824 :     if (rep == MachineRepresentation::kWord64) {
    1115             :       DCHECK(type.Is(TypeCache::Get()->kSafeInteger));
    1116          51 :       return MachineType(rep, MachineSemantic::kInt64);
    1117             :     }
    1118      532773 :     MachineType machine_type(rep, DeoptValueSemanticOf(type));
    1119             :     DCHECK(machine_type.representation() != MachineRepresentation::kWord32 ||
    1120             :            machine_type.semantic() == MachineSemantic::kInt32 ||
    1121             :            machine_type.semantic() == MachineSemantic::kUint32);
    1122             :     DCHECK(machine_type.representation() != MachineRepresentation::kBit ||
    1123             :            type.Is(Type::Boolean()));
    1124      532769 :     return machine_type;
    1125             :   }
    1126             : 
    1127    10989208 :   void VisitStateValues(Node* node) {
    1128    10989208 :     if (propagate()) {
    1129    23701669 :       for (int i = 0; i < node->InputCount(); i++) {
    1130    10293390 :         EnqueueInput(node, i, UseInfo::Any());
    1131             :       }
    1132     7874167 :     } else if (lower()) {
    1133     3115132 :       Zone* zone = jsgraph_->zone();
    1134             :       ZoneVector<MachineType>* types =
    1135             :           new (zone->New(sizeof(ZoneVector<MachineType>)))
    1136     6230272 :               ZoneVector<MachineType>(node->InputCount(), zone);
    1137    23702046 :       for (int i = 0; i < node->InputCount(); i++) {
    1138             :         Node* input = node->InputAt(i);
    1139    10293461 :         (*types)[i] =
    1140    10293461 :             DeoptMachineTypeOf(GetInfo(input)->representation(), TypeOf(input));
    1141             :       }
    1142     3115127 :       SparseInputMask mask = SparseInputMaskOf(node->op());
    1143     3115128 :       NodeProperties::ChangeOp(
    1144     6230241 :           node, jsgraph_->common()->TypedStateValues(types, mask));
    1145             :     }
    1146             :     SetOutput(node, MachineRepresentation::kTagged);
    1147    10989209 :   }
    1148             : 
    1149    16612288 :   void VisitFrameState(Node* node) {
    1150             :     DCHECK_EQ(5, node->op()->ValueInputCount());
    1151             :     DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
    1152             : 
    1153    16612315 :     ProcessInput(node, 0, UseInfo::AnyTagged());  // Parameters.
    1154    16612323 :     ProcessInput(node, 1, UseInfo::AnyTagged());  // Registers.
    1155             : 
    1156             :     // Accumulator is a special flower - we need to remember its type in
    1157             :     // a singleton typed-state-values node (as if it was a singleton
    1158             :     // state-values node).
    1159    16612350 :     if (propagate()) {
    1160     5257168 :       EnqueueInput(node, 2, UseInfo::Any());
    1161    11355187 :     } else if (lower()) {
    1162     5257170 :       Zone* zone = jsgraph_->zone();
    1163             :       Node* accumulator = node->InputAt(2);
    1164     5257170 :       if (accumulator == jsgraph_->OptimizedOutConstant()) {
    1165     4393368 :         node->ReplaceInput(2, jsgraph_->SingleDeadTypedStateValues());
    1166             :       } else {
    1167             :         ZoneVector<MachineType>* types =
    1168             :             new (zone->New(sizeof(ZoneVector<MachineType>)))
    1169      863801 :                 ZoneVector<MachineType>(1, zone);
    1170             :         (*types)[0] = DeoptMachineTypeOf(GetInfo(accumulator)->representation(),
    1171      863802 :                                          TypeOf(accumulator));
    1172             : 
    1173      863802 :         node->ReplaceInput(
    1174     1727604 :             2, jsgraph_->graph()->NewNode(jsgraph_->common()->TypedStateValues(
    1175             :                                               types, SparseInputMask::Dense()),
    1176      863802 :                                           accumulator));
    1177             :       }
    1178             :     }
    1179             : 
    1180    16612379 :     ProcessInput(node, 3, UseInfo::AnyTagged());  // Context.
    1181    16612344 :     ProcessInput(node, 4, UseInfo::AnyTagged());  // Closure.
    1182    16612323 :     ProcessInput(node, 5, UseInfo::AnyTagged());  // Outer frame state.
    1183    16612321 :     return SetOutput(node, MachineRepresentation::kTagged);
    1184             :   }
    1185             : 
    1186       69104 :   void VisitObjectState(Node* node) {
    1187       69104 :     if (propagate()) {
    1188      288304 :       for (int i = 0; i < node->InputCount(); i++) {
    1189      132964 :         EnqueueInput(node, i, UseInfo::Any());
    1190             :       }
    1191       46728 :     } else if (lower()) {
    1192       22376 :       Zone* zone = jsgraph_->zone();
    1193             :       ZoneVector<MachineType>* types =
    1194             :           new (zone->New(sizeof(ZoneVector<MachineType>)))
    1195       44752 :               ZoneVector<MachineType>(node->InputCount(), zone);
    1196      288304 :       for (int i = 0; i < node->InputCount(); i++) {
    1197             :         Node* input = node->InputAt(i);
    1198      132964 :         (*types)[i] =
    1199      132964 :             DeoptMachineTypeOf(GetInfo(input)->representation(), TypeOf(input));
    1200             :       }
    1201       22376 :       NodeProperties::ChangeOp(node, jsgraph_->common()->TypedObjectState(
    1202       22376 :                                          ObjectIdOf(node->op()), types));
    1203             :     }
    1204             :     SetOutput(node, MachineRepresentation::kTagged);
    1205       69104 :   }
    1206             : 
    1207             :   const Operator* Int32Op(Node* node) {
    1208      212970 :     return changer_->Int32OperatorFor(node->opcode());
    1209             :   }
    1210             : 
    1211             :   const Operator* Int32OverflowOp(Node* node) {
    1212      150812 :     return changer_->Int32OverflowOperatorFor(node->opcode());
    1213             :   }
    1214             : 
    1215             :   const Operator* Int64Op(Node* node) {
    1216         479 :     return changer_->Int64OperatorFor(node->opcode());
    1217             :   }
    1218             : 
    1219             :   const Operator* Uint32Op(Node* node) {
    1220       34233 :     return changer_->Uint32OperatorFor(node->opcode());
    1221             :   }
    1222             : 
    1223             :   const Operator* Uint32OverflowOp(Node* node) {
    1224         113 :     return changer_->Uint32OverflowOperatorFor(node->opcode());
    1225             :   }
    1226             : 
    1227             :   const Operator* Float64Op(Node* node) {
    1228      168336 :     return changer_->Float64OperatorFor(node->opcode());
    1229             :   }
    1230             : 
    1231     6372738 :   WriteBarrierKind WriteBarrierKindFor(
    1232             :       BaseTaggedness base_taggedness,
    1233             :       MachineRepresentation field_representation, Type field_type,
    1234             :       MachineRepresentation value_representation, Node* value) {
    1235    12745476 :     if (base_taggedness == kTaggedBase &&
    1236             :         CanBeTaggedOrCompressedPointer(field_representation)) {
    1237     5589472 :       Type value_type = NodeProperties::GetType(value);
    1238    11178944 :       if (field_representation == MachineRepresentation::kTaggedSigned ||
    1239     5589472 :           value_representation == MachineRepresentation::kTaggedSigned ||
    1240    11178946 :           field_representation == MachineRepresentation::kCompressedSigned ||
    1241     5589473 :           value_representation == MachineRepresentation::kCompressedSigned) {
    1242             :         // Write barriers are only for stores of heap objects.
    1243             :         return kNoWriteBarrier;
    1244             :       }
    1245    11178947 :       if (field_type.Is(Type::BooleanOrNullOrUndefined()) ||
    1246             :           value_type.Is(Type::BooleanOrNullOrUndefined())) {
    1247             :         // Write barriers are not necessary when storing true, false, null or
    1248             :         // undefined, because these special oddballs are always in the root set.
    1249             :         return kNoWriteBarrier;
    1250             :       }
    1251     5209419 :       if (value_type.IsHeapConstant()) {
    1252             :         RootIndex root_index;
    1253     1878411 :         const RootsTable& roots_table = jsgraph_->isolate()->roots_table();
    1254     3756822 :         if (roots_table.IsRootHandle(value_type.AsHeapConstant()->Value(),
    1255             :                                      &root_index)) {
    1256     1076177 :           if (RootsTable::IsImmortalImmovable(root_index)) {
    1257             :             // Write barriers are unnecessary for immortal immovable roots.
    1258             :             return kNoWriteBarrier;
    1259             :           }
    1260             :         }
    1261             :       }
    1262     8266486 :       if (field_representation == MachineRepresentation::kTaggedPointer ||
    1263     4133243 :           value_representation == MachineRepresentation::kTaggedPointer ||
    1264     6388756 :           field_representation == MachineRepresentation::kCompressedPointer ||
    1265     3194378 :           value_representation == MachineRepresentation::kCompressedPointer) {
    1266             :         // Write barriers for heap objects are cheaper.
    1267             :         return kPointerWriteBarrier;
    1268             :       }
    1269             :       NumberMatcher m(value);
    1270     3194378 :       if (m.HasValue()) {
    1271        1356 :         if (IsSmiDouble(m.Value())) {
    1272             :           // Storing a smi doesn't need a write barrier.
    1273             :           return kNoWriteBarrier;
    1274             :         }
    1275             :         // The NumberConstant will be represented as HeapNumber.
    1276        1356 :         return kPointerWriteBarrier;
    1277             :       }
    1278             :       return kFullWriteBarrier;
    1279             :     }
    1280             :     return kNoWriteBarrier;
    1281             :   }
    1282             : 
    1283             :   WriteBarrierKind WriteBarrierKindFor(
    1284             :       BaseTaggedness base_taggedness,
    1285             :       MachineRepresentation field_representation, int field_offset,
    1286             :       Type field_type, MachineRepresentation value_representation,
    1287             :       Node* value) {
    1288             :     WriteBarrierKind write_barrier_kind =
    1289     6252441 :         WriteBarrierKindFor(base_taggedness, field_representation, field_type,
    1290     6252441 :                             value_representation, value);
    1291     6252440 :     if (write_barrier_kind != kNoWriteBarrier) {
    1292     8176424 :       if (base_taggedness == kTaggedBase &&
    1293     4088212 :           field_offset == HeapObject::kMapOffset) {
    1294             :         write_barrier_kind = kMapWriteBarrier;
    1295             :       }
    1296             :     }
    1297             :     return write_barrier_kind;
    1298             :   }
    1299             : 
    1300             :   Graph* graph() const { return jsgraph_->graph(); }
    1301             :   CommonOperatorBuilder* common() const { return jsgraph_->common(); }
    1302             :   SimplifiedOperatorBuilder* simplified() const {
    1303             :     return jsgraph_->simplified();
    1304             :   }
    1305             : 
    1306        6121 :   void LowerToCheckedInt32Mul(Node* node, Truncation truncation,
    1307             :                               Type input0_type, Type input1_type) {
    1308             :     // If one of the inputs is positive and/or truncation is being applied,
    1309             :     // there is no need to return -0.
    1310             :     CheckForMinusZeroMode mz_mode =
    1311        4470 :         truncation.IdentifiesZeroAndMinusZero() ||
    1312        8899 :                 IsSomePositiveOrderedNumber(input0_type) ||
    1313        4429 :                 IsSomePositiveOrderedNumber(input1_type)
    1314             :             ? CheckForMinusZeroMode::kDontCheckForMinusZero
    1315        6121 :             : CheckForMinusZeroMode::kCheckForMinusZero;
    1316             : 
    1317        6121 :     NodeProperties::ChangeOp(node, simplified()->CheckedInt32Mul(mz_mode));
    1318        6121 :   }
    1319             : 
    1320      150812 :   void ChangeToInt32OverflowOp(Node* node) {
    1321      150814 :     NodeProperties::ChangeOp(node, Int32OverflowOp(node));
    1322      150814 :   }
    1323             : 
    1324         113 :   void ChangeToUint32OverflowOp(Node* node) {
    1325         113 :     NodeProperties::ChangeOp(node, Uint32OverflowOp(node));
    1326         113 :   }
    1327             : 
    1328      794643 :   void VisitSpeculativeIntegerAdditiveOp(Node* node, Truncation truncation,
    1329             :                                          SimplifiedLowering* lowering) {
    1330      794643 :     Type left_upper = GetUpperBound(node->InputAt(0));
    1331      794643 :     Type right_upper = GetUpperBound(node->InputAt(1));
    1332             : 
    1333     1938192 :     if (left_upper.Is(type_cache_->kAdditiveSafeIntegerOrMinusZero) &&
    1334      348923 :         right_upper.Is(type_cache_->kAdditiveSafeIntegerOrMinusZero)) {
    1335             :       // Only eliminate the node if its typing rule can be satisfied, namely
    1336             :       // that a safe integer is produced.
    1337      342945 :       if (truncation.IsUnused()) return VisitUnused(node);
    1338             : 
    1339             :       // If we know how to interpret the result or if the users only care
    1340             :       // about the low 32-bits, we can truncate to Word32 do a wrapping
    1341             :       // addition.
    1342      718250 :       if (GetUpperBound(node).Is(Type::Signed32()) ||
    1343      392598 :           GetUpperBound(node).Is(Type::Unsigned32()) ||
    1344             :           truncation.IsUsedAsWord32()) {
    1345             :         // => Int32Add/Sub
    1346      262287 :         VisitWord32TruncatingBinop(node);
    1347      326120 :         if (lower()) ChangeToPureOp(node, Int32Op(node));
    1348             :         return;
    1349             :       }
    1350             :     }
    1351             : 
    1352             :     // Try to use type feedback.
    1353      514859 :     NumberOperationHint hint = NumberOperationHintOf(node->op());
    1354             :     DCHECK(hint == NumberOperationHint::kSignedSmall ||
    1355             :            hint == NumberOperationHint::kSigned32);
    1356             : 
    1357      515067 :     Type left_feedback_type = TypeOf(node->InputAt(0));
    1358      515067 :     Type right_feedback_type = TypeOf(node->InputAt(1));
    1359             :     // Handle the case when no int32 checks on inputs are necessary (but
    1360             :     // an overflow check is needed on the output). Note that we do not
    1361             :     // have to do any check if at most one side can be minus zero. For
    1362             :     // subtraction we need to handle the case of -0 - 0 properly, since
    1363             :     // that can produce -0.
    1364             :     Type left_constraint_type =
    1365             :         node->opcode() == IrOpcode::kSpeculativeSafeIntegerAdd
    1366             :             ? Type::Signed32OrMinusZero()
    1367      515067 :             : Type::Signed32();
    1368      582146 :     if (left_upper.Is(left_constraint_type) &&
    1369      576055 :         right_upper.Is(Type::Signed32OrMinusZero()) &&
    1370          21 :         (left_upper.Is(Type::Signed32()) || right_upper.Is(Type::Signed32()))) {
    1371             :       VisitBinop(node, UseInfo::TruncatingWord32(),
    1372             :                  MachineRepresentation::kWord32, Type::Signed32());
    1373             :     } else {
    1374             :       // If the output's truncation is identify-zeros, we can pass it
    1375             :       // along. Moreover, if the operation is addition and we know the
    1376             :       // right-hand side is not minus zero, we do not have to distinguish
    1377             :       // between 0 and -0.
    1378             :       IdentifyZeros left_identify_zeros = truncation.identify_zeros();
    1379      893231 :       if (node->opcode() == IrOpcode::kSpeculativeSafeIntegerAdd &&
    1380      439183 :           !right_feedback_type.Maybe(Type::MinusZero())) {
    1381             :         left_identify_zeros = kIdentifyZeros;
    1382             :       }
    1383             :       UseInfo left_use = CheckedUseInfoAsWord32FromHint(hint, VectorSlotPair(),
    1384      454048 :                                                         left_identify_zeros);
    1385             :       // For CheckedInt32Add and CheckedInt32Sub, we don't need to do
    1386             :       // a minus zero check for the right hand side, since we already
    1387             :       // know that the left hand side is a proper Signed32 value,
    1388             :       // potentially guarded by a check.
    1389             :       UseInfo right_use = CheckedUseInfoAsWord32FromHint(hint, VectorSlotPair(),
    1390      454200 :                                                          kIdentifyZeros);
    1391             :       VisitBinop(node, left_use, right_use, MachineRepresentation::kWord32,
    1392      454186 :                  Type::Signed32());
    1393             :     }
    1394      515260 :     if (lower()) {
    1395      309758 :       if (truncation.IsUsedAsWord32() ||
    1396      154606 :           !CanOverflowSigned32(node->op(), left_feedback_type,
    1397             :                                right_feedback_type, graph_zone())) {
    1398        5701 :         ChangeToPureOp(node, Int32Op(node));
    1399             : 
    1400             :       } else {
    1401      149451 :         ChangeToInt32OverflowOp(node);
    1402             :       }
    1403             :     }
    1404             :     return;
    1405             :   }
    1406             : 
    1407        3873 :   void VisitSpeculativeAdditiveOp(Node* node, Truncation truncation,
    1408             :                                   SimplifiedLowering* lowering) {
    1409       11619 :     if (BothInputsAre(node, type_cache_->kAdditiveSafeIntegerOrMinusZero) &&
    1410        3873 :         (GetUpperBound(node).Is(Type::Signed32()) ||
    1411           0 :          GetUpperBound(node).Is(Type::Unsigned32()) ||
    1412             :          truncation.IsUsedAsWord32())) {
    1413             :       // => Int32Add/Sub
    1414           0 :       VisitWord32TruncatingBinop(node);
    1415           0 :       if (lower()) ChangeToPureOp(node, Int32Op(node));
    1416             :       return;
    1417             :     }
    1418             : 
    1419             :     // default case => Float64Add/Sub
    1420        7746 :     VisitBinop(node,
    1421             :                UseInfo::CheckedNumberOrOddballAsFloat64(kDistinguishZeros,
    1422             :                                                         VectorSlotPair()),
    1423             :                MachineRepresentation::kFloat64, Type::Number());
    1424        3873 :     if (lower()) {
    1425        1108 :       ChangeToPureOp(node, Float64Op(node));
    1426             :     }
    1427             :     return;
    1428             :   }
    1429             : 
    1430       13261 :   void VisitSpeculativeNumberModulus(Node* node, Truncation truncation,
    1431             :                                      SimplifiedLowering* lowering) {
    1432       40390 :     if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN()) &&
    1433         165 :         (truncation.IsUsedAsWord32() ||
    1434       13591 :          NodeProperties::GetType(node).Is(Type::Unsigned32()))) {
    1435             :       // => unsigned Uint32Mod
    1436         640 :       VisitWord32TruncatingBinop(node);
    1437         640 :       if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
    1438             :       return;
    1439             :     }
    1440       44871 :     if (BothInputsAre(node, Type::Signed32OrMinusZeroOrNaN()) &&
    1441        1239 :         (truncation.IsUsedAsWord32() ||
    1442       15099 :          NodeProperties::GetType(node).Is(Type::Signed32()))) {
    1443             :       // => signed Int32Mod
    1444        7008 :       VisitWord32TruncatingBinop(node);
    1445        7008 :       if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
    1446             :       return;
    1447             :     }
    1448             : 
    1449             :     // Try to use type feedback.
    1450        5613 :     NumberOperationHint hint = NumberOperationHintOf(node->op());
    1451             : 
    1452             :     // Handle the case when no uint32 checks on inputs are necessary
    1453             :     // (but an overflow check is needed on the output).
    1454        5613 :     if (BothInputsAreUnsigned32(node)) {
    1455         264 :       if (hint == NumberOperationHint::kSignedSmall ||
    1456         132 :           hint == NumberOperationHint::kSigned32) {
    1457             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    1458             :                    MachineRepresentation::kWord32, Type::Unsigned32());
    1459         132 :         if (lower()) ChangeToUint32OverflowOp(node);
    1460             :         return;
    1461             :       }
    1462             :     }
    1463             : 
    1464             :     // Handle the case when no int32 checks on inputs are necessary
    1465             :     // (but an overflow check is needed on the output).
    1466        5481 :     if (BothInputsAre(node, Type::Signed32())) {
    1467             :       // If both the inputs the feedback are int32, use the overflow op.
    1468        2214 :       if (hint == NumberOperationHint::kSignedSmall ||
    1469        1107 :           hint == NumberOperationHint::kSigned32) {
    1470             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    1471             :                    MachineRepresentation::kWord32, Type::Signed32());
    1472        1107 :         if (lower()) ChangeToInt32OverflowOp(node);
    1473             :         return;
    1474             :       }
    1475             :     }
    1476             : 
    1477        8748 :     if (hint == NumberOperationHint::kSignedSmall ||
    1478        4374 :         hint == NumberOperationHint::kSigned32) {
    1479             :       // If the result is truncated, we only need to check the inputs.
    1480             :       // For the left hand side we just propagate the identify zeros
    1481             :       // mode of the {truncation}; and for modulus the sign of the
    1482             :       // right hand side doesn't matter anyways, so in particular there's
    1483             :       // no observable difference between a 0 and a -0 then.
    1484             :       UseInfo const lhs_use = CheckedUseInfoAsWord32FromHint(
    1485        3571 :           hint, VectorSlotPair(), truncation.identify_zeros());
    1486             :       UseInfo const rhs_use = CheckedUseInfoAsWord32FromHint(
    1487        3571 :           hint, VectorSlotPair(), kIdentifyZeros);
    1488        3571 :       if (truncation.IsUsedAsWord32()) {
    1489         204 :         VisitBinop(node, lhs_use, rhs_use, MachineRepresentation::kWord32);
    1490         204 :         if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
    1491        3367 :       } else if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN())) {
    1492             :         VisitBinop(node, lhs_use, rhs_use, MachineRepresentation::kWord32,
    1493           0 :                    Type::Unsigned32());
    1494           0 :         if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
    1495             :       } else {
    1496             :         VisitBinop(node, lhs_use, rhs_use, MachineRepresentation::kWord32,
    1497        3367 :                    Type::Signed32());
    1498        3367 :         if (lower()) ChangeToInt32OverflowOp(node);
    1499             :       }
    1500             :       return;
    1501             :     }
    1502             : 
    1503        1658 :     if (TypeOf(node->InputAt(0)).Is(Type::Unsigned32()) &&
    1504        1658 :         TypeOf(node->InputAt(1)).Is(Type::Unsigned32()) &&
    1505           0 :         (truncation.IsUsedAsWord32() ||
    1506         803 :          NodeProperties::GetType(node).Is(Type::Unsigned32()))) {
    1507             :       VisitBinop(node, UseInfo::TruncatingWord32(),
    1508             :                  MachineRepresentation::kWord32, Type::Number());
    1509           0 :       if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
    1510             :       return;
    1511             :     }
    1512        1725 :     if (TypeOf(node->InputAt(0)).Is(Type::Signed32()) &&
    1513        1725 :         TypeOf(node->InputAt(1)).Is(Type::Signed32()) &&
    1514           0 :         (truncation.IsUsedAsWord32() ||
    1515         803 :          NodeProperties::GetType(node).Is(Type::Signed32()))) {
    1516             :       VisitBinop(node, UseInfo::TruncatingWord32(),
    1517             :                  MachineRepresentation::kWord32, Type::Number());
    1518           0 :       if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
    1519             :       return;
    1520             :     }
    1521             : 
    1522             :     // default case => Float64Mod
    1523             :     // For the left hand side we just propagate the identify zeros
    1524             :     // mode of the {truncation}; and for modulus the sign of the
    1525             :     // right hand side doesn't matter anyways, so in particular there's
    1526             :     // no observable difference between a 0 and a -0 then.
    1527             :     UseInfo const lhs_use = UseInfo::CheckedNumberOrOddballAsFloat64(
    1528        1606 :         truncation.identify_zeros(), VectorSlotPair());
    1529             :     UseInfo const rhs_use = UseInfo::CheckedNumberOrOddballAsFloat64(
    1530        1606 :         kIdentifyZeros, VectorSlotPair());
    1531             :     VisitBinop(node, lhs_use, rhs_use, MachineRepresentation::kFloat64,
    1532         803 :                Type::Number());
    1533        1013 :     if (lower()) ChangeToPureOp(node, Float64Op(node));
    1534             :     return;
    1535             :   }
    1536             : 
    1537    30500776 :   void InsertUnreachableIfNecessary(Node* node) {
    1538             :     DCHECK(lower());
    1539             :     // If the node is effectful and it produces an impossible value, then we
    1540             :     // insert Unreachable node after it.
    1541    51131667 :     if (node->op()->ValueOutputCount() > 0 &&
    1542     5448448 :         node->op()->EffectOutputCount() > 0 &&
    1543    35948493 :         node->opcode() != IrOpcode::kUnreachable && TypeOf(node).IsNone()) {
    1544             :       Node* control =
    1545             :           (node->op()->ControlOutputCount() == 0)
    1546             :               ? NodeProperties::GetControlInput(node, 0)
    1547        1112 :               : NodeProperties::FindSuccessfulControlProjection(node);
    1548             : 
    1549             :       Node* unreachable =
    1550        1112 :           graph()->NewNode(common()->Unreachable(), node, control);
    1551             : 
    1552             :       // Insert unreachable node and replace all the effect uses of the {node}
    1553             :       // with the new unreachable node.
    1554        7090 :       for (Edge edge : node->use_edges()) {
    1555        2989 :         if (!NodeProperties::IsEffectEdge(edge)) continue;
    1556             :         // Make sure to not overwrite the unreachable node's input. That would
    1557             :         // create a cycle.
    1558        2231 :         if (edge.from() == unreachable) continue;
    1559             :         // Avoid messing up the exceptional path.
    1560        1119 :         if (edge.from()->opcode() == IrOpcode::kIfException) {
    1561             :           DCHECK(!node->op()->HasProperty(Operator::kNoThrow));
    1562             :           DCHECK_EQ(NodeProperties::GetControlInput(edge.from()), node);
    1563             :           continue;
    1564             :         }
    1565             : 
    1566        1112 :         edge.UpdateTo(unreachable);
    1567             :       }
    1568             :     }
    1569    30500776 :   }
    1570             : 
    1571      187460 :   void VisitCheckBounds(Node* node, SimplifiedLowering* lowering) {
    1572      187460 :     CheckParameters const& p = CheckParametersOf(node->op());
    1573      187460 :     Type const index_type = TypeOf(node->InputAt(0));
    1574      187460 :     Type const length_type = TypeOf(node->InputAt(1));
    1575      187460 :     if (length_type.Is(Type::Unsigned31())) {
    1576      186838 :       if (index_type.Is(Type::Integral32OrMinusZero())) {
    1577             :         // Map -0 to 0, and the values in the [-2^31,-1] range to the
    1578             :         // [2^31,2^32-1] range, which will be considered out-of-bounds
    1579             :         // as well, because the {length_type} is limited to Unsigned31.
    1580             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    1581             :                    MachineRepresentation::kWord32);
    1582      173186 :         if (lower()) {
    1583             :           CheckBoundsParameters::Mode mode =
    1584             :               CheckBoundsParameters::kDeoptOnOutOfBounds;
    1585      104296 :           if (lowering->poisoning_level_ ==
    1586      104296 :                   PoisoningMitigationLevel::kDontPoison &&
    1587      104296 :               (index_type.IsNone() || length_type.IsNone() ||
    1588      100503 :                (index_type.Min() >= 0.0 &&
    1589       48355 :                 index_type.Max() < length_type.Min()))) {
    1590             :             // The bounds check is redundant if we already know that
    1591             :             // the index is within the bounds of [0.0, length[.
    1592             :             mode = CheckBoundsParameters::kAbortOnOutOfBounds;
    1593             :           }
    1594       52148 :           NodeProperties::ChangeOp(
    1595       52148 :               node, simplified()->CheckedUint32Bounds(p.feedback(), mode));
    1596             :         }
    1597             :       } else {
    1598             :         VisitBinop(
    1599             :             node,
    1600             :             UseInfo::CheckedSigned32AsWord32(kIdentifyZeros, p.feedback()),
    1601       13652 :             UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
    1602       13652 :         if (lower()) {
    1603        2666 :           NodeProperties::ChangeOp(
    1604             :               node,
    1605             :               simplified()->CheckedUint32Bounds(
    1606        2666 :                   p.feedback(), CheckBoundsParameters::kDeoptOnOutOfBounds));
    1607             :         }
    1608             :       }
    1609             :     } else {
    1610             :       DCHECK(length_type.Is(type_cache_->kPositiveSafeInteger));
    1611             :       VisitBinop(node,
    1612             :                  UseInfo::CheckedSigned64AsWord64(kIdentifyZeros, p.feedback()),
    1613         622 :                  UseInfo::Word64(), MachineRepresentation::kWord64);
    1614         622 :       if (lower()) {
    1615         202 :         NodeProperties::ChangeOp(
    1616         202 :             node, simplified()->CheckedUint64Bounds(p.feedback()));
    1617             :       }
    1618             :     }
    1619      187460 :   }
    1620             : 
    1621             :   // Dispatching routine for visiting the node {node} with the usage {use}.
    1622             :   // Depending on the operator, propagate new usage info to the inputs.
    1623    97448875 :   void VisitNode(Node* node, Truncation truncation,
    1624             :                  SimplifiedLowering* lowering) {
    1625             :     // Unconditionally eliminate unused pure nodes (only relevant if there's
    1626             :     // a pure operation in between two effectful ones, where the last one
    1627             :     // is unused).
    1628             :     // Note: We must not do this for constants, as they are cached and we
    1629             :     // would thus kill the cached {node} during lowering (i.e. replace all
    1630             :     // uses with Dead), but at that point some node lowering might have
    1631             :     // already taken the constant {node} from the cache (while it was in
    1632             :     // a sane state still) and we would afterwards replace that use with
    1633             :     // Dead as well.
    1634   158072588 :     if (node->op()->ValueInputCount() > 0 &&
    1635   134311219 :         node->op()->HasProperty(Operator::kPure) && truncation.IsUnused()) {
    1636      109165 :       return VisitUnused(node);
    1637             :     }
    1638             : 
    1639    97339710 :     if (lower()) InsertUnreachableIfNecessary(node);
    1640             : 
    1641    97350474 :     switch (node->opcode()) {
    1642             :       //------------------------------------------------------------------
    1643             :       // Common operators.
    1644             :       //------------------------------------------------------------------
    1645             :       case IrOpcode::kStart:
    1646             :         // We use Start as a terminator for the frame state chain, so even
    1647             :         // tho Start doesn't really produce a value, we have to say Tagged
    1648             :         // here, otherwise the input conversion will fail.
    1649             :         return VisitLeaf(node, MachineRepresentation::kTagged);
    1650             :       case IrOpcode::kParameter:
    1651             :         // TODO(titzer): use representation from linkage.
    1652     6001533 :         return VisitUnop(node, UseInfo::None(), MachineRepresentation::kTagged);
    1653             :       case IrOpcode::kInt32Constant:
    1654             :         return VisitLeaf(node, MachineRepresentation::kWord32);
    1655             :       case IrOpcode::kInt64Constant:
    1656             :         return VisitLeaf(node, MachineRepresentation::kWord64);
    1657             :       case IrOpcode::kExternalConstant:
    1658             :         return VisitLeaf(node, MachineType::PointerRepresentation());
    1659             :       case IrOpcode::kNumberConstant: {
    1660     3563482 :         double const value = OpParameter<double>(node->op());
    1661             :         int value_as_int;
    1662     3563482 :         if (DoubleToSmiInteger(value, &value_as_int)) {
    1663             :           VisitLeaf(node, MachineRepresentation::kTaggedSigned);
    1664     3420727 :           if (lower()) {
    1665             :             intptr_t smi = bit_cast<intptr_t>(Smi::FromInt(value_as_int));
    1666     1095981 :             DeferReplacement(node, lowering->jsgraph()->IntPtrConstant(smi));
    1667             :           }
    1668             :           return;
    1669             :         }
    1670             :         VisitLeaf(node, MachineRepresentation::kTagged);
    1671             :         return;
    1672             :       }
    1673             :       case IrOpcode::kHeapConstant:
    1674             :       case IrOpcode::kDelayedStringConstant:
    1675             :         return VisitLeaf(node, MachineRepresentation::kTaggedPointer);
    1676             :       case IrOpcode::kPointerConstant: {
    1677             :         VisitLeaf(node, MachineType::PointerRepresentation());
    1678         663 :         if (lower()) {
    1679         221 :           intptr_t const value = OpParameter<intptr_t>(node->op());
    1680         221 :           DeferReplacement(node, lowering->jsgraph()->IntPtrConstant(value));
    1681             :         }
    1682             :         return;
    1683             :       }
    1684             : 
    1685             :       case IrOpcode::kBranch: {
    1686             :         DCHECK(TypeOf(node->InputAt(0)).Is(Type::Boolean()));
    1687     1844819 :         ProcessInput(node, 0, UseInfo::Bool());
    1688     1844768 :         EnqueueInput(node, NodeProperties::FirstControlIndex(node));
    1689     1844764 :         return;
    1690             :       }
    1691             :       case IrOpcode::kSwitch:
    1692       16578 :         ProcessInput(node, 0, UseInfo::TruncatingWord32());
    1693       16578 :         EnqueueInput(node, NodeProperties::FirstControlIndex(node));
    1694       16578 :         return;
    1695             :       case IrOpcode::kSelect:
    1696       38614 :         return VisitSelect(node, truncation, lowering);
    1697             :       case IrOpcode::kPhi:
    1698     1521125 :         return VisitPhi(node, truncation, lowering);
    1699             :       case IrOpcode::kCall:
    1700      338054 :         return VisitCall(node, lowering);
    1701             : 
    1702             :       //------------------------------------------------------------------
    1703             :       // JavaScript operators.
    1704             :       //------------------------------------------------------------------
    1705             :       case IrOpcode::kToBoolean: {
    1706      153150 :         if (truncation.IsUsedAsBool()) {
    1707      152544 :           ProcessInput(node, 0, UseInfo::Bool());
    1708             :           SetOutput(node, MachineRepresentation::kBit);
    1709      200885 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    1710             :         } else {
    1711         606 :           VisitInputs(node);
    1712             :           SetOutput(node, MachineRepresentation::kTaggedPointer);
    1713             :         }
    1714             :         return;
    1715             :       }
    1716             :       case IrOpcode::kJSToNumber:
    1717             :       case IrOpcode::kJSToNumberConvertBigInt:
    1718             :       case IrOpcode::kJSToNumeric: {
    1719       38195 :         VisitInputs(node);
    1720             :         // TODO(bmeurer): Optimize somewhat based on input type?
    1721       38195 :         if (truncation.IsUsedAsWord32()) {
    1722             :           SetOutput(node, MachineRepresentation::kWord32);
    1723         333 :           if (lower())
    1724          75 :             lowering->DoJSToNumberOrNumericTruncatesToWord32(node, this);
    1725       37862 :         } else if (truncation.IsUsedAsFloat64()) {
    1726             :           SetOutput(node, MachineRepresentation::kFloat64);
    1727        4987 :           if (lower())
    1728        1413 :             lowering->DoJSToNumberOrNumericTruncatesToFloat64(node, this);
    1729             :         } else {
    1730             :           SetOutput(node, MachineRepresentation::kTagged);
    1731             :         }
    1732             :         return;
    1733             :       }
    1734             : 
    1735             :       //------------------------------------------------------------------
    1736             :       // Simplified operators.
    1737             :       //------------------------------------------------------------------
    1738             :       case IrOpcode::kBooleanNot: {
    1739        9602 :         if (lower()) {
    1740             :           NodeInfo* input_info = GetInfo(node->InputAt(0));
    1741        3090 :           if (input_info->representation() == MachineRepresentation::kBit) {
    1742             :             // BooleanNot(x: kRepBit) => Word32Equal(x, #0)
    1743        2054 :             node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0));
    1744        2054 :             NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal());
    1745        1036 :           } else if (CanBeTaggedPointer(input_info->representation())) {
    1746             :             // BooleanNot(x: kRepTagged) => WordEqual(x, #false)
    1747        1036 :             node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant());
    1748        1036 :             NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
    1749             :           } else {
    1750             :             DCHECK(TypeOf(node->InputAt(0)).IsNone());
    1751           0 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
    1752             :           }
    1753             :         } else {
    1754             :           // No input representation requirement; adapt during lowering.
    1755        6512 :           ProcessInput(node, 0, UseInfo::AnyTruncatingToBool());
    1756             :           SetOutput(node, MachineRepresentation::kBit);
    1757             :         }
    1758             :         return;
    1759             :       }
    1760             :       case IrOpcode::kNumberEqual: {
    1761      155686 :         Type const lhs_type = TypeOf(node->InputAt(0));
    1762      155686 :         Type const rhs_type = TypeOf(node->InputAt(1));
    1763             :         // Regular number comparisons in JavaScript generally identify zeros,
    1764             :         // so we always pass kIdentifyZeros for the inputs, and in addition
    1765             :         // we can truncate -0 to 0 for otherwise Unsigned32 or Signed32 inputs.
    1766             :         // For equality we also handle the case that one side is non-zero, in
    1767             :         // which case we allow to truncate NaN to 0 on the other side.
    1768      209802 :         if ((lhs_type.Is(Type::Unsigned32OrMinusZero()) &&
    1769      257322 :              rhs_type.Is(Type::Unsigned32OrMinusZero())) ||
    1770         102 :             (lhs_type.Is(Type::Unsigned32OrMinusZeroOrNaN()) &&
    1771          36 :              rhs_type.Is(Type::Unsigned32OrMinusZeroOrNaN()) &&
    1772          36 :              OneInputCannotBe(node, type_cache_->kZeroish))) {
    1773             :           // => unsigned Int32Cmp
    1774             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1775             :                      MachineRepresentation::kBit);
    1776       66709 :           if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
    1777             :           return;
    1778             :         }
    1779      122783 :         if ((lhs_type.Is(Type::Signed32OrMinusZero()) &&
    1780      182154 :              rhs_type.Is(Type::Signed32OrMinusZero())) ||
    1781          65 :             (lhs_type.Is(Type::Signed32OrMinusZeroOrNaN()) &&
    1782          36 :              rhs_type.Is(Type::Signed32OrMinusZeroOrNaN()) &&
    1783          36 :              OneInputCannotBe(node, type_cache_->kZeroish))) {
    1784             :           // => signed Int32Cmp
    1785             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1786             :                      MachineRepresentation::kBit);
    1787       27804 :           if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
    1788             :           return;
    1789             :         }
    1790             :         // => Float64Cmp
    1791             :         VisitBinop(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
    1792             :                    MachineRepresentation::kBit);
    1793       89093 :         if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    1794             :         return;
    1795             :       }
    1796             :       case IrOpcode::kNumberLessThan:
    1797             :       case IrOpcode::kNumberLessThanOrEqual: {
    1798      157074 :         Type const lhs_type = TypeOf(node->InputAt(0));
    1799      157074 :         Type const rhs_type = TypeOf(node->InputAt(1));
    1800             :         // Regular number comparisons in JavaScript generally identify zeros,
    1801             :         // so we always pass kIdentifyZeros for the inputs, and in addition
    1802             :         // we can truncate -0 to 0 for otherwise Unsigned32 or Signed32 inputs.
    1803      253739 :         if (lhs_type.Is(Type::Unsigned32OrMinusZero()) &&
    1804             :             rhs_type.Is(Type::Unsigned32OrMinusZero())) {
    1805             :           // => unsigned Int32Cmp
    1806             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1807             :                      MachineRepresentation::kBit);
    1808      107107 :           if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
    1809       84330 :         } else if (lhs_type.Is(Type::Signed32OrMinusZero()) &&
    1810             :                    rhs_type.Is(Type::Signed32OrMinusZero())) {
    1811             :           // => signed Int32Cmp
    1812             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1813             :                      MachineRepresentation::kBit);
    1814       13727 :           if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
    1815             :         } else {
    1816             :           // => Float64Cmp
    1817             :           VisitBinop(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
    1818             :                      MachineRepresentation::kBit);
    1819       62017 :           if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    1820             :         }
    1821             :         return;
    1822             :       }
    1823             : 
    1824             :       case IrOpcode::kSpeculativeSafeIntegerAdd:
    1825             :       case IrOpcode::kSpeculativeSafeIntegerSubtract:
    1826      794667 :         return VisitSpeculativeIntegerAdditiveOp(node, truncation, lowering);
    1827             : 
    1828             :       case IrOpcode::kSpeculativeNumberAdd:
    1829             :       case IrOpcode::kSpeculativeNumberSubtract:
    1830        3873 :         return VisitSpeculativeAdditiveOp(node, truncation, lowering);
    1831             : 
    1832             :       case IrOpcode::kSpeculativeNumberLessThan:
    1833             :       case IrOpcode::kSpeculativeNumberLessThanOrEqual:
    1834             :       case IrOpcode::kSpeculativeNumberEqual: {
    1835      390647 :         Type const lhs_type = TypeOf(node->InputAt(0));
    1836      390647 :         Type const rhs_type = TypeOf(node->InputAt(1));
    1837             :         // Regular number comparisons in JavaScript generally identify zeros,
    1838             :         // so we always pass kIdentifyZeros for the inputs, and in addition
    1839             :         // we can truncate -0 to 0 for otherwise Unsigned32 or Signed32 inputs.
    1840      662431 :         if (lhs_type.Is(Type::Unsigned32OrMinusZero()) &&
    1841             :             rhs_type.Is(Type::Unsigned32OrMinusZero())) {
    1842             :           // => unsigned Int32Cmp
    1843             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1844             :                      MachineRepresentation::kBit);
    1845        6170 :           if (lower()) ChangeToPureOp(node, Uint32Op(node));
    1846             :           return;
    1847      667527 :         } else if (lhs_type.Is(Type::Signed32OrMinusZero()) &&
    1848             :                    rhs_type.Is(Type::Signed32OrMinusZero())) {
    1849             :           // => signed Int32Cmp
    1850             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1851             :                      MachineRepresentation::kBit);
    1852      247686 :           if (lower()) ChangeToPureOp(node, Int32Op(node));
    1853             :           return;
    1854             :         }
    1855             :         // Try to use type feedback.
    1856      200515 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    1857      200515 :         switch (hint) {
    1858             :           case NumberOperationHint::kSigned32:
    1859             :           case NumberOperationHint::kSignedSmall:
    1860      160999 :             if (propagate()) {
    1861      233557 :               VisitBinop(node,
    1862             :                          CheckedUseInfoAsWord32FromHint(hint, VectorSlotPair(),
    1863             :                                                         kIdentifyZeros),
    1864             :                          MachineRepresentation::kBit);
    1865       44219 :             } else if (retype()) {
    1866             :               SetOutput(node, MachineRepresentation::kBit, Type::Any());
    1867             :             } else {
    1868             :               DCHECK(lower());
    1869             :               Node* lhs = node->InputAt(0);
    1870             :               Node* rhs = node->InputAt(1);
    1871       32080 :               if (IsNodeRepresentationTagged(lhs) &&
    1872             :                   IsNodeRepresentationTagged(rhs)) {
    1873       28886 :                 VisitBinop(node,
    1874             :                            UseInfo::CheckedSignedSmallAsTaggedSigned(
    1875             :                                VectorSlotPair(), kIdentifyZeros),
    1876             :                            MachineRepresentation::kBit);
    1877       14443 :                 ChangeToPureOp(
    1878       28886 :                     node, changer_->TaggedSignedOperatorFor(node->opcode()));
    1879             : 
    1880             :               } else {
    1881        5398 :                 VisitBinop(node,
    1882             :                            CheckedUseInfoAsWord32FromHint(
    1883             :                                hint, VectorSlotPair(), kIdentifyZeros),
    1884             :                            MachineRepresentation::kBit);
    1885        2699 :                 ChangeToPureOp(node, Int32Op(node));
    1886             :               }
    1887             :             }
    1888             :             return;
    1889             :           case NumberOperationHint::kSignedSmallInputs:
    1890             :             // This doesn't make sense for compare operations.
    1891           0 :             UNREACHABLE();
    1892             :           case NumberOperationHint::kNumberOrOddball:
    1893             :             // Abstract and strict equality don't perform ToNumber conversions
    1894             :             // on Oddballs, so make sure we don't accidentially sneak in a
    1895             :             // hint with Oddball feedback here.
    1896             :             DCHECK_NE(IrOpcode::kSpeculativeNumberEqual, node->opcode());
    1897             :             V8_FALLTHROUGH;
    1898             :           case NumberOperationHint::kNumber:
    1899       79033 :             VisitBinop(node,
    1900             :                        CheckedUseInfoAsFloat64FromHint(hint, VectorSlotPair(),
    1901             :                                                        kIdentifyZeros),
    1902             :                        MachineRepresentation::kBit);
    1903       48881 :             if (lower()) ChangeToPureOp(node, Float64Op(node));
    1904             :             return;
    1905             :         }
    1906           0 :         UNREACHABLE();
    1907             :         return;
    1908             :       }
    1909             : 
    1910             :       case IrOpcode::kNumberAdd:
    1911             :       case IrOpcode::kNumberSubtract: {
    1912     1538788 :         if (TypeOf(node->InputAt(0))
    1913     1300281 :                 .Is(type_cache_->kAdditiveSafeIntegerOrMinusZero) &&
    1914     1300280 :             TypeOf(node->InputAt(1))
    1915     1206628 :                 .Is(type_cache_->kAdditiveSafeIntegerOrMinusZero) &&
    1916     1487801 :             (TypeOf(node).Is(Type::Signed32()) ||
    1917      547818 :              TypeOf(node).Is(Type::Unsigned32()) ||
    1918             :              truncation.IsUsedAsWord32())) {
    1919             :           // => Int32Add/Sub
    1920      171423 :           VisitWord32TruncatingBinop(node);
    1921      209851 :           if (lower()) ChangeToPureOp(node, Int32Op(node));
    1922     2390286 :         } else if (jsgraph_->machine()->Is64() &&
    1923      599534 :                    BothInputsAre(node, type_cache_->kSafeInteger) &&
    1924      601090 :                    GetUpperBound(node).Is(type_cache_->kSafeInteger)) {
    1925             :           // => Int64Add/Sub
    1926        1537 :           VisitInt64Binop(node);
    1927        2016 :           if (lower()) ChangeToPureOp(node, Int64Op(node));
    1928             :         } else {
    1929             :           // => Float64Add/Sub
    1930      596423 :           VisitFloat64Binop(node);
    1931      669899 :           if (lower()) ChangeToPureOp(node, Float64Op(node));
    1932             :         }
    1933             :         return;
    1934             :       }
    1935             :       case IrOpcode::kSpeculativeNumberMultiply: {
    1936      126102 :         if (BothInputsAre(node, Type::Integral32()) &&
    1937       56039 :             (NodeProperties::GetType(node).Is(Type::Signed32()) ||
    1938       49236 :              NodeProperties::GetType(node).Is(Type::Unsigned32()) ||
    1939         417 :              (truncation.IsUsedAsWord32() &&
    1940       42451 :               NodeProperties::GetType(node).Is(
    1941         417 :                   type_cache_->kSafeIntegerOrMinusZero)))) {
    1942             :           // Multiply reduces to Int32Mul if the inputs are integers, and
    1943             :           // (a) the output is either known to be Signed32, or
    1944             :           // (b) the output is known to be Unsigned32, or
    1945             :           // (c) the uses are truncating and the result is in the safe
    1946             :           //     integer range.
    1947        1977 :           VisitWord32TruncatingBinop(node);
    1948        2504 :           if (lower()) ChangeToPureOp(node, Int32Op(node));
    1949             :           return;
    1950             :         }
    1951             :         // Try to use type feedback.
    1952       40057 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    1953       40057 :         Type input0_type = TypeOf(node->InputAt(0));
    1954       40057 :         Type input1_type = TypeOf(node->InputAt(1));
    1955             : 
    1956             :         // Handle the case when no int32 checks on inputs are necessary
    1957             :         // (but an overflow check is needed on the output).
    1958       40057 :         if (BothInputsAre(node, Type::Signed32())) {
    1959             :           // If both inputs and feedback are int32, use the overflow op.
    1960        5728 :           if (hint == NumberOperationHint::kSignedSmall ||
    1961        2864 :               hint == NumberOperationHint::kSigned32) {
    1962             :             VisitBinop(node, UseInfo::TruncatingWord32(),
    1963             :                        MachineRepresentation::kWord32, Type::Signed32());
    1964        2864 :             if (lower()) {
    1965             :               LowerToCheckedInt32Mul(node, truncation, input0_type,
    1966         919 :                                      input1_type);
    1967             :             }
    1968             :             return;
    1969             :           }
    1970             :         }
    1971             : 
    1972       74386 :         if (hint == NumberOperationHint::kSignedSmall ||
    1973       37193 :             hint == NumberOperationHint::kSigned32) {
    1974       34980 :           VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    1975             :                      MachineRepresentation::kWord32, Type::Signed32());
    1976       17490 :           if (lower()) {
    1977        5202 :             LowerToCheckedInt32Mul(node, truncation, input0_type, input1_type);
    1978             :           }
    1979             :           return;
    1980             :         }
    1981             : 
    1982             :         // Checked float64 x float64 => float64
    1983       39406 :         VisitBinop(node,
    1984             :                    UseInfo::CheckedNumberOrOddballAsFloat64(kDistinguishZeros,
    1985             :                                                             VectorSlotPair()),
    1986             :                    MachineRepresentation::kFloat64, Type::Number());
    1987       25277 :         if (lower()) ChangeToPureOp(node, Float64Op(node));
    1988             :         return;
    1989             :       }
    1990             :       case IrOpcode::kNumberMultiply: {
    1991       54787 :         if (TypeOf(node->InputAt(0)).Is(Type::Integral32()) &&
    1992       59479 :             TypeOf(node->InputAt(1)).Is(Type::Integral32()) &&
    1993       31673 :             (TypeOf(node).Is(Type::Signed32()) ||
    1994       29965 :              TypeOf(node).Is(Type::Unsigned32()) ||
    1995         566 :              (truncation.IsUsedAsWord32() &&
    1996       25108 :               TypeOf(node).Is(type_cache_->kSafeIntegerOrMinusZero)))) {
    1997             :           // Multiply reduces to Int32Mul if the inputs are integers, and
    1998             :           // (a) the output is either known to be Signed32, or
    1999             :           // (b) the output is known to be Unsigned32, or
    2000             :           // (c) the uses are truncating and the result is in the safe
    2001             :           //     integer range.
    2002        2250 :           VisitWord32TruncatingBinop(node);
    2003        2712 :           if (lower()) ChangeToPureOp(node, Int32Op(node));
    2004             :           return;
    2005             :         }
    2006             :         // Number x Number => Float64Mul
    2007       21726 :         VisitFloat64Binop(node);
    2008       27749 :         if (lower()) ChangeToPureOp(node, Float64Op(node));
    2009             :         return;
    2010             :       }
    2011             :       case IrOpcode::kSpeculativeNumberDivide: {
    2012       59104 :         if (BothInputsAreUnsigned32(node) && truncation.IsUsedAsWord32()) {
    2013             :           // => unsigned Uint32Div
    2014         568 :           VisitWord32TruncatingBinop(node);
    2015         568 :           if (lower()) DeferReplacement(node, lowering->Uint32Div(node));
    2016             :           return;
    2017             :         }
    2018       51758 :         if (BothInputsAreSigned32(node)) {
    2019       30526 :           if (NodeProperties::GetType(node).Is(Type::Signed32())) {
    2020             :             // => signed Int32Div
    2021           0 :             VisitWord32TruncatingBinop(node);
    2022           0 :             if (lower()) DeferReplacement(node, lowering->Int32Div(node));
    2023             :             return;
    2024             :           }
    2025       15263 :           if (truncation.IsUsedAsWord32()) {
    2026             :             // => signed Int32Div
    2027        6911 :             VisitWord32TruncatingBinop(node);
    2028        6911 :             if (lower()) DeferReplacement(node, lowering->Int32Div(node));
    2029             :             return;
    2030             :           }
    2031             :         }
    2032             : 
    2033             :         // Try to use type feedback.
    2034       44847 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    2035             : 
    2036             :         // Handle the case when no uint32 checks on inputs are necessary
    2037             :         // (but an overflow check is needed on the output).
    2038       44847 :         if (BothInputsAreUnsigned32(node)) {
    2039       12420 :           if (hint == NumberOperationHint::kSignedSmall ||
    2040        6210 :               hint == NumberOperationHint::kSigned32) {
    2041             :             VisitBinop(node, UseInfo::TruncatingWord32(),
    2042             :                        MachineRepresentation::kWord32, Type::Unsigned32());
    2043         289 :             if (lower()) ChangeToUint32OverflowOp(node);
    2044             :             return;
    2045             :           }
    2046             :         }
    2047             : 
    2048             :         // Handle the case when no int32 checks on inputs are necessary
    2049             :         // (but an overflow check is needed on the output).
    2050       44558 :         if (BothInputsAreSigned32(node)) {
    2051             :           // If both the inputs the feedback are int32, use the overflow op.
    2052       16150 :           if (hint == NumberOperationHint::kSignedSmall ||
    2053        8075 :               hint == NumberOperationHint::kSigned32) {
    2054             :             VisitBinop(node, UseInfo::TruncatingWord32(),
    2055             :                        MachineRepresentation::kWord32, Type::Signed32());
    2056          12 :             if (lower()) ChangeToInt32OverflowOp(node);
    2057             :             return;
    2058             :           }
    2059             :         }
    2060             : 
    2061       89092 :         if (hint == NumberOperationHint::kSigned32 ||
    2062       88170 :             hint == NumberOperationHint::kSignedSmall ||
    2063             :             hint == NumberOperationHint::kSignedSmallInputs) {
    2064             :           // If the result is truncated, we only need to check the inputs.
    2065       38263 :           if (truncation.IsUsedAsWord32()) {
    2066        4842 :             VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    2067             :                        MachineRepresentation::kWord32);
    2068        2421 :             if (lower()) DeferReplacement(node, lowering->Int32Div(node));
    2069             :             return;
    2070       35842 :           } else if (hint != NumberOperationHint::kSignedSmallInputs) {
    2071        1650 :             VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    2072             :                        MachineRepresentation::kWord32, Type::Signed32());
    2073         825 :             if (lower()) ChangeToInt32OverflowOp(node);
    2074             :             return;
    2075             :           }
    2076             :         }
    2077             : 
    2078             :         // default case => Float64Div
    2079       82600 :         VisitBinop(node,
    2080             :                    UseInfo::CheckedNumberOrOddballAsFloat64(kDistinguishZeros,
    2081             :                                                             VectorSlotPair()),
    2082             :                    MachineRepresentation::kFloat64, Type::Number());
    2083       53336 :         if (lower()) ChangeToPureOp(node, Float64Op(node));
    2084             :         return;
    2085             :       }
    2086             :       case IrOpcode::kNumberDivide: {
    2087       36417 :         if (TypeOf(node->InputAt(0)).Is(Type::Unsigned32()) &&
    2088       37227 :             TypeOf(node->InputAt(1)).Is(Type::Unsigned32()) &&
    2089         668 :             (truncation.IsUsedAsWord32() ||
    2090       14275 :              TypeOf(node).Is(Type::Unsigned32()))) {
    2091             :           // => unsigned Uint32Div
    2092         142 :           VisitWord32TruncatingBinop(node);
    2093         142 :           if (lower()) DeferReplacement(node, lowering->Uint32Div(node));
    2094             :           return;
    2095             :         }
    2096       36077 :         if (TypeOf(node->InputAt(0)).Is(Type::Signed32()) &&
    2097       37526 :             TypeOf(node->InputAt(1)).Is(Type::Signed32()) &&
    2098        1441 :             (truncation.IsUsedAsWord32() ||
    2099       14906 :              TypeOf(node).Is(Type::Signed32()))) {
    2100             :           // => signed Int32Div
    2101           8 :           VisitWord32TruncatingBinop(node);
    2102           8 :           if (lower()) DeferReplacement(node, lowering->Int32Div(node));
    2103             :           return;
    2104             :         }
    2105             :         // Number x Number => Float64Div
    2106       13457 :         VisitFloat64Binop(node);
    2107       16811 :         if (lower()) ChangeToPureOp(node, Float64Op(node));
    2108             :         return;
    2109             :       }
    2110             :       case IrOpcode::kSpeculativeNumberModulus:
    2111       13261 :         return VisitSpeculativeNumberModulus(node, truncation, lowering);
    2112             :       case IrOpcode::kNumberModulus: {
    2113        2564 :         Type const lhs_type = TypeOf(node->InputAt(0));
    2114        2564 :         Type const rhs_type = TypeOf(node->InputAt(1));
    2115        5426 :         if ((lhs_type.Is(Type::Unsigned32OrMinusZeroOrNaN()) &&
    2116        2884 :              rhs_type.Is(Type::Unsigned32OrMinusZeroOrNaN())) &&
    2117         153 :             (truncation.IsUsedAsWord32() ||
    2118        2870 :              TypeOf(node).Is(Type::Unsigned32()))) {
    2119             :           // => unsigned Uint32Mod
    2120         320 :           VisitWord32TruncatingBinop(node);
    2121         320 :           if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
    2122             :           return;
    2123             :         }
    2124        4761 :         if ((lhs_type.Is(Type::Signed32OrMinusZeroOrNaN()) &&
    2125        2452 :              rhs_type.Is(Type::Signed32OrMinusZeroOrNaN())) &&
    2126        2754 :             (truncation.IsUsedAsWord32() || TypeOf(node).Is(Type::Signed32()) ||
    2127          42 :              (truncation.IdentifiesZeroAndMinusZero() &&
    2128        2286 :               TypeOf(node).Is(Type::Signed32OrMinusZero())))) {
    2129             :           // => signed Int32Mod
    2130          98 :           VisitWord32TruncatingBinop(node);
    2131          98 :           if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
    2132             :           return;
    2133             :         }
    2134             :         // => Float64Mod
    2135             :         // For the left hand side we just propagate the identify zeros
    2136             :         // mode of the {truncation}; and for modulus the sign of the
    2137             :         // right hand side doesn't matter anyways, so in particular there's
    2138             :         // no observable difference between a 0 and a -0 then.
    2139             :         UseInfo const lhs_use =
    2140             :             UseInfo::TruncatingFloat64(truncation.identify_zeros());
    2141             :         UseInfo const rhs_use = UseInfo::TruncatingFloat64(kIdentifyZeros);
    2142        2146 :         VisitBinop(node, lhs_use, rhs_use, MachineRepresentation::kFloat64);
    2143        2500 :         if (lower()) ChangeToPureOp(node, Float64Op(node));
    2144             :         return;
    2145             :       }
    2146             :       case IrOpcode::kNumberBitwiseOr:
    2147             :       case IrOpcode::kNumberBitwiseXor:
    2148             :       case IrOpcode::kNumberBitwiseAnd: {
    2149       19894 :         VisitWord32TruncatingBinop(node);
    2150       26413 :         if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
    2151             :         return;
    2152             :       }
    2153             :       case IrOpcode::kSpeculativeNumberBitwiseOr:
    2154             :       case IrOpcode::kSpeculativeNumberBitwiseXor:
    2155             :       case IrOpcode::kSpeculativeNumberBitwiseAnd:
    2156       81401 :         VisitSpeculativeInt32Binop(node);
    2157       81401 :         if (lower()) {
    2158       22409 :           ChangeToPureOp(node, Int32Op(node));
    2159             :         }
    2160             :         return;
    2161             :       case IrOpcode::kNumberShiftLeft: {
    2162        1287 :         Type rhs_type = GetUpperBound(node->InputAt(1));
    2163             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    2164        1287 :                    UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
    2165        1287 :         if (lower()) {
    2166         374 :           MaskShiftOperand(node, rhs_type);
    2167         374 :           ChangeToPureOp(node, lowering->machine()->Word32Shl());
    2168             :         }
    2169             :         return;
    2170             :       }
    2171             :       case IrOpcode::kSpeculativeNumberShiftLeft: {
    2172        8114 :         if (BothInputsAre(node, Type::NumberOrOddball())) {
    2173        7296 :           Type rhs_type = GetUpperBound(node->InputAt(1));
    2174             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    2175             :                      UseInfo::TruncatingWord32(),
    2176        7296 :                      MachineRepresentation::kWord32);
    2177        7296 :           if (lower()) {
    2178        1840 :             MaskShiftOperand(node, rhs_type);
    2179        1840 :             ChangeToPureOp(node, lowering->machine()->Word32Shl());
    2180             :           }
    2181             :           return;
    2182             :         }
    2183         818 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    2184         818 :         Type rhs_type = GetUpperBound(node->InputAt(1));
    2185        1636 :         VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    2186             :                    MachineRepresentation::kWord32, Type::Signed32());
    2187         818 :         if (lower()) {
    2188         262 :           MaskShiftOperand(node, rhs_type);
    2189         262 :           ChangeToPureOp(node, lowering->machine()->Word32Shl());
    2190             :         }
    2191             :         return;
    2192             :       }
    2193             :       case IrOpcode::kNumberShiftRight: {
    2194         555 :         Type rhs_type = GetUpperBound(node->InputAt(1));
    2195             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    2196         555 :                    UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
    2197         555 :         if (lower()) {
    2198         155 :           MaskShiftOperand(node, rhs_type);
    2199         155 :           ChangeToPureOp(node, lowering->machine()->Word32Sar());
    2200             :         }
    2201             :         return;
    2202             :       }
    2203             :       case IrOpcode::kSpeculativeNumberShiftRight: {
    2204       22816 :         if (BothInputsAre(node, Type::NumberOrOddball())) {
    2205       21575 :           Type rhs_type = GetUpperBound(node->InputAt(1));
    2206             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    2207             :                      UseInfo::TruncatingWord32(),
    2208       21575 :                      MachineRepresentation::kWord32);
    2209       21575 :           if (lower()) {
    2210        5210 :             MaskShiftOperand(node, rhs_type);
    2211        5210 :             ChangeToPureOp(node, lowering->machine()->Word32Sar());
    2212             :           }
    2213             :           return;
    2214             :         }
    2215        1241 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    2216        1241 :         Type rhs_type = GetUpperBound(node->InputAt(1));
    2217        2482 :         VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    2218             :                    MachineRepresentation::kWord32, Type::Signed32());
    2219        1241 :         if (lower()) {
    2220         382 :           MaskShiftOperand(node, rhs_type);
    2221         382 :           ChangeToPureOp(node, lowering->machine()->Word32Sar());
    2222             :         }
    2223             :         return;
    2224             :       }
    2225             :       case IrOpcode::kNumberShiftRightLogical: {
    2226         683 :         Type rhs_type = GetUpperBound(node->InputAt(1));
    2227             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    2228         683 :                    UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
    2229         683 :         if (lower()) {
    2230         209 :           MaskShiftOperand(node, rhs_type);
    2231         209 :           ChangeToPureOp(node, lowering->machine()->Word32Shr());
    2232             :         }
    2233             :         return;
    2234             :       }
    2235             :       case IrOpcode::kSpeculativeNumberShiftRightLogical: {
    2236        5777 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    2237        5777 :         Type rhs_type = GetUpperBound(node->InputAt(1));
    2238       14735 :         if (rhs_type.Is(type_cache_->kZeroish) &&
    2239        6362 :             (hint == NumberOperationHint::kSignedSmall ||
    2240        9621 :              hint == NumberOperationHint::kSigned32) &&
    2241             :             !truncation.IsUsedAsWord32()) {
    2242             :           // The SignedSmall or Signed32 feedback means that the results that we
    2243             :           // have seen so far were of type Unsigned31.  We speculate that this
    2244             :           // will continue to hold.  Moreover, since the RHS is 0, the result
    2245             :           // will just be the (converted) LHS.
    2246         650 :           VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    2247             :                      MachineRepresentation::kWord32, Type::Unsigned31());
    2248         325 :           if (lower()) {
    2249          92 :             node->RemoveInput(1);
    2250         184 :             NodeProperties::ChangeOp(
    2251          92 :                 node, simplified()->CheckedUint32ToInt32(VectorSlotPair()));
    2252             :           }
    2253             :           return;
    2254             :         }
    2255        5452 :         if (BothInputsAre(node, Type::NumberOrOddball())) {
    2256             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    2257             :                      UseInfo::TruncatingWord32(),
    2258        4083 :                      MachineRepresentation::kWord32);
    2259        4083 :           if (lower()) {
    2260        1161 :             MaskShiftOperand(node, rhs_type);
    2261        1161 :             ChangeToPureOp(node, lowering->machine()->Word32Shr());
    2262             :           }
    2263             :           return;
    2264             :         }
    2265        2738 :         VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    2266             :                    MachineRepresentation::kWord32, Type::Unsigned32());
    2267        1369 :         if (lower()) {
    2268         416 :           MaskShiftOperand(node, rhs_type);
    2269         416 :           ChangeToPureOp(node, lowering->machine()->Word32Shr());
    2270             :         }
    2271             :         return;
    2272             :       }
    2273             :       case IrOpcode::kNumberAbs: {
    2274             :         // NumberAbs maps both 0 and -0 to 0, so we can generally
    2275             :         // pass the kIdentifyZeros truncation to its input, and
    2276             :         // choose to ignore minus zero in all cases.
    2277         906 :         Type const input_type = TypeOf(node->InputAt(0));
    2278         906 :         if (input_type.Is(Type::Unsigned32OrMinusZero())) {
    2279             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2280          37 :                     MachineRepresentation::kWord32);
    2281          52 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2282         869 :         } else if (input_type.Is(Type::Signed32OrMinusZero())) {
    2283             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2284         208 :                     MachineRepresentation::kWord32);
    2285         208 :           if (lower()) DeferReplacement(node, lowering->Int32Abs(node));
    2286        1322 :         } else if (input_type.Is(type_cache_->kPositiveIntegerOrNaN)) {
    2287             :           VisitUnop(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
    2288          14 :                     MachineRepresentation::kFloat64);
    2289          21 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2290             :         } else {
    2291             :           VisitUnop(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
    2292         646 :                     MachineRepresentation::kFloat64);
    2293         838 :           if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2294             :         }
    2295             :         return;
    2296             :       }
    2297             :       case IrOpcode::kNumberClz32: {
    2298             :         VisitUnop(node, UseInfo::TruncatingWord32(),
    2299          90 :                   MachineRepresentation::kWord32);
    2300         120 :         if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
    2301             :         return;
    2302             :       }
    2303             :       case IrOpcode::kNumberImul: {
    2304             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    2305        2616 :                    UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
    2306        3488 :         if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
    2307             :         return;
    2308             :       }
    2309             :       case IrOpcode::kNumberFround: {
    2310             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    2311        4039 :                   MachineRepresentation::kFloat32);
    2312        5369 :         if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2313             :         return;
    2314             :       }
    2315             :       case IrOpcode::kNumberMax: {
    2316             :         // It is safe to use the feedback types for left and right hand side
    2317             :         // here, since we can only narrow those types and thus we can only
    2318             :         // promise a more specific truncation.
    2319             :         // For NumberMax we generally propagate whether the truncation
    2320             :         // identifies zeros to the inputs, and we choose to ignore minus
    2321             :         // zero in those cases.
    2322        7528 :         Type const lhs_type = TypeOf(node->InputAt(0));
    2323        7528 :         Type const rhs_type = TypeOf(node->InputAt(1));
    2324       11548 :         if ((lhs_type.Is(Type::Unsigned32()) &&
    2325       11645 :              rhs_type.Is(Type::Unsigned32())) ||
    2326         681 :             (lhs_type.Is(Type::Unsigned32OrMinusZero()) &&
    2327         102 :              rhs_type.Is(Type::Unsigned32OrMinusZero()) &&
    2328             :              truncation.IdentifiesZeroAndMinusZero())) {
    2329        3432 :           VisitWord32TruncatingBinop(node);
    2330        3432 :           if (lower()) {
    2331        1095 :             lowering->DoMax(node, lowering->machine()->Uint32LessThan(),
    2332        1095 :                             MachineRepresentation::kWord32);
    2333             :           }
    2334        7877 :         } else if ((lhs_type.Is(Type::Signed32()) &&
    2335        4985 :                     rhs_type.Is(Type::Signed32())) ||
    2336         625 :                    (lhs_type.Is(Type::Signed32OrMinusZero()) &&
    2337          81 :                     rhs_type.Is(Type::Signed32OrMinusZero()) &&
    2338             :                     truncation.IdentifiesZeroAndMinusZero())) {
    2339        3207 :           VisitWord32TruncatingBinop(node);
    2340        3207 :           if (lower()) {
    2341        1048 :             lowering->DoMax(node, lowering->machine()->Int32LessThan(),
    2342        1048 :                             MachineRepresentation::kWord32);
    2343             :           }
    2344        2667 :         } else if (jsgraph_->machine()->Is64() &&
    2345        1520 :                    lhs_type.Is(type_cache_->kSafeInteger) &&
    2346         631 :                    rhs_type.Is(type_cache_->kSafeInteger)) {
    2347         505 :           VisitInt64Binop(node);
    2348         505 :           if (lower()) {
    2349         165 :             lowering->DoMax(node, lowering->machine()->Int64LessThan(),
    2350         165 :                             MachineRepresentation::kWord64);
    2351             :           }
    2352             :         } else {
    2353             :           VisitBinop(node,
    2354             :                      UseInfo::TruncatingFloat64(truncation.identify_zeros()),
    2355             :                      MachineRepresentation::kFloat64);
    2356         384 :           if (lower()) {
    2357             :             // If the right hand side is not NaN, and the left hand side
    2358             :             // is not NaN (or -0 if the difference between the zeros is
    2359             :             // observed), we can do a simple floating point comparison here.
    2360         240 :             if (lhs_type.Is(truncation.IdentifiesZeroAndMinusZero()
    2361             :                                 ? Type::OrderedNumber()
    2362         193 :                                 : Type::PlainNumber()) &&
    2363             :                 rhs_type.Is(Type::OrderedNumber())) {
    2364          48 :               lowering->DoMax(node, lowering->machine()->Float64LessThan(),
    2365          48 :                               MachineRepresentation::kFloat64);
    2366             :             } else {
    2367          72 :               NodeProperties::ChangeOp(node, Float64Op(node));
    2368             :             }
    2369             :           }
    2370             :         }
    2371             :         return;
    2372             :       }
    2373             :       case IrOpcode::kNumberMin: {
    2374             :         // It is safe to use the feedback types for left and right hand side
    2375             :         // here, since we can only narrow those types and thus we can only
    2376             :         // promise a more specific truncation.
    2377             :         // For NumberMin we generally propagate whether the truncation
    2378             :         // identifies zeros to the inputs, and we choose to ignore minus
    2379             :         // zero in those cases.
    2380       10216 :         Type const lhs_type = TypeOf(node->InputAt(0));
    2381       10216 :         Type const rhs_type = TypeOf(node->InputAt(1));
    2382       19811 :         if ((lhs_type.Is(Type::Unsigned32()) &&
    2383       11091 :              rhs_type.Is(Type::Unsigned32())) ||
    2384         308 :             (lhs_type.Is(Type::Unsigned32OrMinusZero()) &&
    2385          81 :              rhs_type.Is(Type::Unsigned32OrMinusZero()) &&
    2386             :              truncation.IdentifiesZeroAndMinusZero())) {
    2387        9341 :           VisitWord32TruncatingBinop(node);
    2388        9341 :           if (lower()) {
    2389        3002 :             lowering->DoMin(node, lowering->machine()->Uint32LessThan(),
    2390        3002 :                             MachineRepresentation::kWord32);
    2391             :           }
    2392        1275 :         } else if ((lhs_type.Is(Type::Signed32()) &&
    2393        1513 :                     rhs_type.Is(Type::Signed32())) ||
    2394         217 :                    (lhs_type.Is(Type::Signed32OrMinusZero()) &&
    2395          81 :                     rhs_type.Is(Type::Signed32OrMinusZero()) &&
    2396             :                     truncation.IdentifiesZeroAndMinusZero())) {
    2397         237 :           VisitWord32TruncatingBinop(node);
    2398         237 :           if (lower()) {
    2399          72 :             lowering->DoMin(node, lowering->machine()->Int32LessThan(),
    2400          72 :                             MachineRepresentation::kWord32);
    2401             :           }
    2402        1914 :         } else if (jsgraph_->machine()->Is64() &&
    2403         825 :                    lhs_type.Is(type_cache_->kSafeInteger) &&
    2404         187 :                    rhs_type.Is(type_cache_->kSafeInteger)) {
    2405          40 :           VisitInt64Binop(node);
    2406          40 :           if (lower()) {
    2407          16 :             lowering->DoMin(node, lowering->machine()->Int64LessThan(),
    2408          16 :                             MachineRepresentation::kWord64);
    2409             :           }
    2410             :         } else {
    2411             :           VisitBinop(node,
    2412             :                      UseInfo::TruncatingFloat64(truncation.identify_zeros()),
    2413             :                      MachineRepresentation::kFloat64);
    2414         598 :           if (lower()) {
    2415             :             // If the left hand side is not NaN, and the right hand side
    2416             :             // is not NaN (or -0 if the difference between the zeros is
    2417             :             // observed), we can do a simple floating point comparison here.
    2418         278 :             if (lhs_type.Is(Type::OrderedNumber()) &&
    2419          84 :                 rhs_type.Is(truncation.IdentifiesZeroAndMinusZero()
    2420             :                                 ? Type::OrderedNumber()
    2421             :                                 : Type::PlainNumber())) {
    2422          45 :               lowering->DoMin(node,
    2423             :                               lowering->machine()->Float64LessThanOrEqual(),
    2424          45 :                               MachineRepresentation::kFloat64);
    2425             :             } else {
    2426         149 :               NodeProperties::ChangeOp(node, Float64Op(node));
    2427             :             }
    2428             :           }
    2429             :         }
    2430             :         return;
    2431             :       }
    2432             :       case IrOpcode::kNumberAtan2:
    2433             :       case IrOpcode::kNumberPow: {
    2434             :         VisitBinop(node, UseInfo::TruncatingFloat64(),
    2435             :                    MachineRepresentation::kFloat64);
    2436        3668 :         if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2437             :         return;
    2438             :       }
    2439             :       case IrOpcode::kNumberCeil:
    2440             :       case IrOpcode::kNumberFloor:
    2441             :       case IrOpcode::kNumberRound:
    2442             :       case IrOpcode::kNumberTrunc: {
    2443             :         // For NumberCeil, NumberFloor, NumberRound and NumberTrunc we propagate
    2444             :         // the zero identification part of the truncation, and we turn them into
    2445             :         // no-ops if we figure out (late) that their input is already an
    2446             :         // integer, NaN or -0.
    2447      134592 :         Type const input_type = TypeOf(node->InputAt(0));
    2448             :         VisitUnop(node, UseInfo::TruncatingFloat64(truncation.identify_zeros()),
    2449      134592 :                   MachineRepresentation::kFloat64);
    2450      134592 :         if (lower()) {
    2451       88556 :           if (input_type.Is(type_cache_->kIntegerOrMinusZeroOrNaN)) {
    2452        1246 :             DeferReplacement(node, node->InputAt(0));
    2453       43032 :           } else if (node->opcode() == IrOpcode::kNumberRound) {
    2454        1554 :             DeferReplacement(node, lowering->Float64Round(node));
    2455             :           } else {
    2456       41478 :             NodeProperties::ChangeOp(node, Float64Op(node));
    2457             :           }
    2458             :         }
    2459             :         return;
    2460             :       }
    2461             :       case IrOpcode::kNumberAcos:
    2462             :       case IrOpcode::kNumberAcosh:
    2463             :       case IrOpcode::kNumberAsin:
    2464             :       case IrOpcode::kNumberAsinh:
    2465             :       case IrOpcode::kNumberAtan:
    2466             :       case IrOpcode::kNumberAtanh:
    2467             :       case IrOpcode::kNumberCos:
    2468             :       case IrOpcode::kNumberCosh:
    2469             :       case IrOpcode::kNumberExp:
    2470             :       case IrOpcode::kNumberExpm1:
    2471             :       case IrOpcode::kNumberLog:
    2472             :       case IrOpcode::kNumberLog1p:
    2473             :       case IrOpcode::kNumberLog2:
    2474             :       case IrOpcode::kNumberLog10:
    2475             :       case IrOpcode::kNumberCbrt:
    2476             :       case IrOpcode::kNumberSin:
    2477             :       case IrOpcode::kNumberSinh:
    2478             :       case IrOpcode::kNumberTan:
    2479             :       case IrOpcode::kNumberTanh: {
    2480             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    2481         858 :                   MachineRepresentation::kFloat64);
    2482        1136 :         if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2483             :         return;
    2484             :       }
    2485             :       case IrOpcode::kNumberSign: {
    2486         111 :         if (InputIs(node, Type::Signed32())) {
    2487             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2488          21 :                     MachineRepresentation::kWord32);
    2489          21 :           if (lower()) DeferReplacement(node, lowering->Int32Sign(node));
    2490             :         } else {
    2491             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2492          90 :                     MachineRepresentation::kFloat64);
    2493          90 :           if (lower()) DeferReplacement(node, lowering->Float64Sign(node));
    2494             :         }
    2495             :         return;
    2496             :       }
    2497             :       case IrOpcode::kNumberSilenceNaN: {
    2498        2259 :         Type const input_type = TypeOf(node->InputAt(0));
    2499        2259 :         if (input_type.Is(Type::OrderedNumber())) {
    2500             :           // No need to silence anything if the input cannot be NaN.
    2501             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2502          14 :                     MachineRepresentation::kFloat64);
    2503          21 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2504             :         } else {
    2505             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2506        2245 :                     MachineRepresentation::kFloat64);
    2507        2972 :           if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2508             :         }
    2509             :         return;
    2510             :       }
    2511             :       case IrOpcode::kNumberSqrt: {
    2512             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    2513         156 :                   MachineRepresentation::kFloat64);
    2514         207 :         if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2515             :         return;
    2516             :       }
    2517             :       case IrOpcode::kNumberToBoolean: {
    2518             :         // For NumberToBoolean we don't care whether the input is 0 or
    2519             :         // -0, since both of them are mapped to false anyways, so we
    2520             :         // can generally pass kIdentifyZeros truncation.
    2521         552 :         Type const input_type = TypeOf(node->InputAt(0));
    2522         552 :         if (input_type.Is(Type::Integral32OrMinusZeroOrNaN())) {
    2523             :           // 0, -0 and NaN all map to false, so we can safely truncate
    2524             :           // all of them to zero here.
    2525             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2526         301 :                     MachineRepresentation::kBit);
    2527         301 :           if (lower()) lowering->DoIntegral32ToBit(node);
    2528         251 :         } else if (input_type.Is(Type::OrderedNumber())) {
    2529             :           VisitUnop(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
    2530          77 :                     MachineRepresentation::kBit);
    2531          77 :           if (lower()) lowering->DoOrderedNumberToBit(node);
    2532             :         } else {
    2533             :           VisitUnop(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
    2534         174 :                     MachineRepresentation::kBit);
    2535         174 :           if (lower()) lowering->DoNumberToBit(node);
    2536             :         }
    2537             :         return;
    2538             :       }
    2539             :       case IrOpcode::kNumberToInt32: {
    2540             :         // Just change representation if necessary.
    2541             :         VisitUnop(node, UseInfo::TruncatingWord32(),
    2542        1621 :                   MachineRepresentation::kWord32);
    2543        1906 :         if (lower()) DeferReplacement(node, node->InputAt(0));
    2544             :         return;
    2545             :       }
    2546             :       case IrOpcode::kNumberToString: {
    2547             :         VisitUnop(node, UseInfo::AnyTagged(),
    2548       11330 :                   MachineRepresentation::kTaggedPointer);
    2549       11330 :         return;
    2550             :       }
    2551             :       case IrOpcode::kNumberToUint32: {
    2552             :         // Just change representation if necessary.
    2553             :         VisitUnop(node, UseInfo::TruncatingWord32(),
    2554        6276 :                   MachineRepresentation::kWord32);
    2555        8240 :         if (lower()) DeferReplacement(node, node->InputAt(0));
    2556             :         return;
    2557             :       }
    2558             :       case IrOpcode::kNumberToUint8Clamped: {
    2559        1446 :         Type const input_type = TypeOf(node->InputAt(0));
    2560        2892 :         if (input_type.Is(type_cache_->kUint8OrMinusZeroOrNaN)) {
    2561             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2562          45 :                     MachineRepresentation::kWord32);
    2563          60 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2564        1401 :         } else if (input_type.Is(Type::Unsigned32OrMinusZeroOrNaN())) {
    2565             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2566         240 :                     MachineRepresentation::kWord32);
    2567         240 :           if (lower()) lowering->DoUnsigned32ToUint8Clamped(node);
    2568        1161 :         } else if (input_type.Is(Type::Signed32OrMinusZeroOrNaN())) {
    2569             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2570         216 :                     MachineRepresentation::kWord32);
    2571         216 :           if (lower()) lowering->DoSigned32ToUint8Clamped(node);
    2572        1890 :         } else if (input_type.Is(type_cache_->kIntegerOrMinusZeroOrNaN)) {
    2573             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2574          63 :                     MachineRepresentation::kFloat64);
    2575          63 :           if (lower()) lowering->DoIntegerToUint8Clamped(node);
    2576             :         } else {
    2577             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2578         882 :                     MachineRepresentation::kFloat64);
    2579         882 :           if (lower()) lowering->DoNumberToUint8Clamped(node);
    2580             :         }
    2581             :         return;
    2582             :       }
    2583             :       case IrOpcode::kReferenceEqual: {
    2584             :         VisitBinop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    2585      599849 :         if (lower()) {
    2586      198092 :           NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
    2587             :         }
    2588             :         return;
    2589             :       }
    2590             :       case IrOpcode::kSameValueNumbersOnly: {
    2591             :         VisitBinop(node, UseInfo::AnyTagged(),
    2592             :                    MachineRepresentation::kTaggedPointer);
    2593             :         return;
    2594             :       }
    2595             :       case IrOpcode::kSameValue: {
    2596         234 :         if (truncation.IsUnused()) return VisitUnused(node);
    2597         234 :         if (BothInputsAre(node, Type::Number())) {
    2598             :           VisitBinop(node, UseInfo::TruncatingFloat64(),
    2599             :                      MachineRepresentation::kBit);
    2600         231 :           if (lower()) {
    2601          77 :             NodeProperties::ChangeOp(node,
    2602          77 :                                      lowering->simplified()->NumberSameValue());
    2603             :           }
    2604             :         } else {
    2605             :           VisitBinop(node, UseInfo::AnyTagged(),
    2606             :                      MachineRepresentation::kTaggedPointer);
    2607             :         }
    2608             :         return;
    2609             :       }
    2610             :       case IrOpcode::kTypeOf: {
    2611             :         return VisitUnop(node, UseInfo::AnyTagged(),
    2612       67035 :                          MachineRepresentation::kTaggedPointer);
    2613             :       }
    2614             :       case IrOpcode::kNewConsString: {
    2615       15889 :         ProcessInput(node, 0, UseInfo::TruncatingWord32());  // length
    2616       15889 :         ProcessInput(node, 1, UseInfo::AnyTagged());         // first
    2617       15889 :         ProcessInput(node, 2, UseInfo::AnyTagged());         // second
    2618             :         SetOutput(node, MachineRepresentation::kTaggedPointer);
    2619             :         return;
    2620             :       }
    2621             :       case IrOpcode::kStringConcat: {
    2622             :         // TODO(turbofan): We currently depend on having this first length input
    2623             :         // to make sure that the overflow check is properly scheduled before the
    2624             :         // actual string concatenation. We should also use the length to pass it
    2625             :         // to the builtin or decide in optimized code how to construct the
    2626             :         // resulting string (i.e. cons string or sequential string).
    2627       66885 :         ProcessInput(node, 0, UseInfo::TaggedSigned());  // length
    2628       66885 :         ProcessInput(node, 1, UseInfo::AnyTagged());     // first
    2629       66885 :         ProcessInput(node, 2, UseInfo::AnyTagged());     // second
    2630             :         SetOutput(node, MachineRepresentation::kTaggedPointer);
    2631             :         return;
    2632             :       }
    2633             :       case IrOpcode::kStringEqual:
    2634             :       case IrOpcode::kStringLessThan:
    2635             :       case IrOpcode::kStringLessThanOrEqual: {
    2636             :         return VisitBinop(node, UseInfo::AnyTagged(),
    2637             :                           MachineRepresentation::kTaggedPointer);
    2638             :       }
    2639             :       case IrOpcode::kStringCharCodeAt: {
    2640             :         return VisitBinop(node, UseInfo::AnyTagged(), UseInfo::Word(),
    2641        8062 :                           MachineRepresentation::kWord32);
    2642             :       }
    2643             :       case IrOpcode::kStringCodePointAt: {
    2644             :         return VisitBinop(node, UseInfo::AnyTagged(), UseInfo::Word(),
    2645         721 :                           MachineRepresentation::kTaggedSigned);
    2646             :       }
    2647             :       case IrOpcode::kStringFromSingleCharCode: {
    2648             :         VisitUnop(node, UseInfo::TruncatingWord32(),
    2649        3493 :                   MachineRepresentation::kTaggedPointer);
    2650        3493 :         return;
    2651             :       }
    2652             :       case IrOpcode::kStringFromSingleCodePoint: {
    2653             :         VisitUnop(node, UseInfo::TruncatingWord32(),
    2654         718 :                   MachineRepresentation::kTaggedPointer);
    2655         718 :         return;
    2656             :       }
    2657             :       case IrOpcode::kStringIndexOf: {
    2658         853 :         ProcessInput(node, 0, UseInfo::AnyTagged());
    2659         853 :         ProcessInput(node, 1, UseInfo::AnyTagged());
    2660         853 :         ProcessInput(node, 2, UseInfo::TaggedSigned());
    2661             :         SetOutput(node, MachineRepresentation::kTaggedSigned);
    2662             :         return;
    2663             :       }
    2664             :       case IrOpcode::kStringLength: {
    2665             :         // TODO(bmeurer): The input representation should be TaggedPointer.
    2666             :         // Fix this once we have a dedicated StringConcat/JSStringAdd
    2667             :         // operator, which marks it's output as TaggedPointer properly.
    2668       75991 :         VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kWord32);
    2669       75991 :         return;
    2670             :       }
    2671             :       case IrOpcode::kStringSubstring: {
    2672        4036 :         ProcessInput(node, 0, UseInfo::AnyTagged());
    2673        4036 :         ProcessInput(node, 1, UseInfo::TruncatingWord32());
    2674        4036 :         ProcessInput(node, 2, UseInfo::TruncatingWord32());
    2675        4036 :         ProcessRemainingInputs(node, 3);
    2676             :         SetOutput(node, MachineRepresentation::kTaggedPointer);
    2677             :         return;
    2678             :       }
    2679             :       case IrOpcode::kStringToLowerCaseIntl:
    2680             :       case IrOpcode::kStringToUpperCaseIntl: {
    2681             :         VisitUnop(node, UseInfo::AnyTagged(),
    2682         424 :                   MachineRepresentation::kTaggedPointer);
    2683         424 :         return;
    2684             :       }
    2685             :       case IrOpcode::kCheckBounds:
    2686      187460 :         return VisitCheckBounds(node, lowering);
    2687             :       case IrOpcode::kPoisonIndex: {
    2688             :         VisitUnop(node, UseInfo::TruncatingWord32(),
    2689        3681 :                   MachineRepresentation::kWord32);
    2690        3681 :         return;
    2691             :       }
    2692             :       case IrOpcode::kCheckHeapObject: {
    2693       88170 :         if (InputCannotBe(node, Type::SignedSmall())) {
    2694             :           VisitUnop(node, UseInfo::AnyTagged(),
    2695           3 :                     MachineRepresentation::kTaggedPointer);
    2696             :         } else {
    2697      176334 :           VisitUnop(node,
    2698             :                     UseInfo::CheckedHeapObjectAsTaggedPointer(VectorSlotPair()),
    2699       88167 :                     MachineRepresentation::kTaggedPointer);
    2700             :         }
    2701      115957 :         if (lower()) DeferReplacement(node, node->InputAt(0));
    2702             :         return;
    2703             :       }
    2704             :       case IrOpcode::kCheckIf: {
    2705       44478 :         ProcessInput(node, 0, UseInfo::Bool());
    2706       44478 :         ProcessRemainingInputs(node, 1);
    2707             :         SetOutput(node, MachineRepresentation::kNone);
    2708             :         return;
    2709             :       }
    2710             :       case IrOpcode::kCheckInternalizedString: {
    2711        5532 :         VisitCheck(node, Type::InternalizedString(), lowering);
    2712        5532 :         return;
    2713             :       }
    2714             :       case IrOpcode::kCheckNumber: {
    2715        1564 :         Type const input_type = TypeOf(node->InputAt(0));
    2716        1564 :         if (input_type.Is(Type::Number())) {
    2717          36 :           VisitNoop(node, truncation);
    2718             :         } else {
    2719        1528 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    2720             :         }
    2721             :         return;
    2722             :       }
    2723             :       case IrOpcode::kCheckReceiver: {
    2724        3195 :         VisitCheck(node, Type::Receiver(), lowering);
    2725        3195 :         return;
    2726             :       }
    2727             :       case IrOpcode::kCheckReceiverOrNullOrUndefined: {
    2728         230 :         VisitCheck(node, Type::ReceiverOrNullOrUndefined(), lowering);
    2729         230 :         return;
    2730             :       }
    2731             :       case IrOpcode::kCheckSmi: {
    2732       94027 :         const CheckParameters& params = CheckParametersOf(node->op());
    2733       94027 :         if (SmiValuesAre32Bits() && truncation.IsUsedAsWord32()) {
    2734             :           VisitUnop(node,
    2735             :                     UseInfo::CheckedSignedSmallAsWord32(kDistinguishZeros,
    2736             :                                                         params.feedback()),
    2737       21159 :                     MachineRepresentation::kWord32);
    2738             :         } else {
    2739             :           VisitUnop(
    2740             :               node,
    2741             :               UseInfo::CheckedSignedSmallAsTaggedSigned(params.feedback()),
    2742       72868 :               MachineRepresentation::kTaggedSigned);
    2743             :         }
    2744      122677 :         if (lower()) DeferReplacement(node, node->InputAt(0));
    2745             :         return;
    2746             :       }
    2747             :       case IrOpcode::kCheckString: {
    2748       21675 :         const CheckParameters& params = CheckParametersOf(node->op());
    2749       21675 :         if (InputIs(node, Type::String())) {
    2750             :           VisitUnop(node, UseInfo::AnyTagged(),
    2751           0 :                     MachineRepresentation::kTaggedPointer);
    2752           0 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2753             :         } else {
    2754             :           VisitUnop(
    2755             :               node,
    2756             :               UseInfo::CheckedHeapObjectAsTaggedPointer(params.feedback()),
    2757       21675 :               MachineRepresentation::kTaggedPointer);
    2758             :         }
    2759             :         return;
    2760             :       }
    2761             :       case IrOpcode::kCheckSymbol: {
    2762         104 :         VisitCheck(node, Type::Symbol(), lowering);
    2763         104 :         return;
    2764             :       }
    2765             : 
    2766             :       case IrOpcode::kAllocate: {
    2767      338556 :         ProcessInput(node, 0, UseInfo::Word());
    2768      338556 :         ProcessRemainingInputs(node, 1);
    2769             :         SetOutput(node, MachineRepresentation::kTaggedPointer);
    2770             :         return;
    2771             :       }
    2772             :       case IrOpcode::kLoadMessage: {
    2773       89202 :         if (truncation.IsUnused()) return VisitUnused(node);
    2774       21707 :         VisitUnop(node, UseInfo::Word(), MachineRepresentation::kTagged);
    2775       21707 :         return;
    2776             :       }
    2777             :       case IrOpcode::kStoreMessage: {
    2778       89579 :         ProcessInput(node, 0, UseInfo::Word());
    2779       89579 :         ProcessInput(node, 1, UseInfo::AnyTagged());
    2780       89579 :         ProcessRemainingInputs(node, 2);
    2781             :         SetOutput(node, MachineRepresentation::kNone);
    2782             :         return;
    2783             :       }
    2784             :       case IrOpcode::kLoadFieldByIndex: {
    2785        2107 :         if (truncation.IsUnused()) return VisitUnused(node);
    2786             :         VisitBinop(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(),
    2787        2073 :                    MachineRepresentation::kTagged);
    2788        2073 :         return;
    2789             :       }
    2790             :       case IrOpcode::kLoadField: {
    2791     3848211 :         if (truncation.IsUnused()) return VisitUnused(node);
    2792     3737158 :         FieldAccess access = FieldAccessOf(node->op());
    2793             :         MachineRepresentation const representation =
    2794             :             access.machine_type.representation();
    2795     3737158 :         VisitUnop(node, UseInfoForBasePointer(access), representation);
    2796     3737158 :         return;
    2797             :       }
    2798             :       case IrOpcode::kStoreField: {
    2799     6252437 :         FieldAccess access = FieldAccessOf(node->op());
    2800             :         Node* value_node = node->InputAt(1);
    2801             :         NodeInfo* input_info = GetInfo(value_node);
    2802             :         MachineRepresentation field_representation =
    2803             :             access.machine_type.representation();
    2804             : 
    2805             :         // Convert to Smi if possible, such that we can avoid a write barrier.
    2806    18757324 :         if (field_representation == MachineRepresentation::kTagged &&
    2807    16333158 :             TypeOf(value_node).Is(Type::SignedSmall())) {
    2808             :           field_representation = MachineRepresentation::kTaggedSigned;
    2809             :         }
    2810     6252441 :         WriteBarrierKind write_barrier_kind = WriteBarrierKindFor(
    2811     6252441 :             access.base_is_tagged, field_representation, access.offset,
    2812             :             access.type, input_info->representation(), value_node);
    2813             : 
    2814     6252440 :         ProcessInput(node, 0, UseInfoForBasePointer(access));
    2815     6252443 :         ProcessInput(node, 1,
    2816     6252447 :                      TruncatingUseInfoFromRepresentation(field_representation));
    2817     6252444 :         ProcessRemainingInputs(node, 2);
    2818             :         SetOutput(node, MachineRepresentation::kNone);
    2819     6252438 :         if (lower()) {
    2820     2080938 :           if (write_barrier_kind < access.write_barrier_kind) {
    2821      719069 :             access.write_barrier_kind = write_barrier_kind;
    2822      719069 :             NodeProperties::ChangeOp(
    2823     1438138 :                 node, jsgraph_->simplified()->StoreField(access));
    2824             :           }
    2825             :         }
    2826             :         return;
    2827             :       }
    2828             :       case IrOpcode::kLoadElement: {
    2829       64129 :         if (truncation.IsUnused()) return VisitUnused(node);
    2830       62014 :         ElementAccess access = ElementAccessOf(node->op());
    2831       62014 :         VisitBinop(node, UseInfoForBasePointer(access), UseInfo::Word(),
    2832       62014 :                    access.machine_type.representation());
    2833       62014 :         return;
    2834             :       }
    2835             :       case IrOpcode::kLoadStackArgument: {
    2836        2346 :         if (truncation.IsUnused()) return VisitUnused(node);
    2837             :         VisitBinop(node, UseInfo::Word(), MachineRepresentation::kTagged);
    2838             :         return;
    2839             :       }
    2840             :       case IrOpcode::kStoreElement: {
    2841      120301 :         ElementAccess access = ElementAccessOf(node->op());
    2842             :         Node* value_node = node->InputAt(2);
    2843             :         NodeInfo* input_info = GetInfo(value_node);
    2844             :         MachineRepresentation element_representation =
    2845             :             access.machine_type.representation();
    2846             : 
    2847             :         // Convert to Smi if possible, such that we can avoid a write barrier.
    2848      360903 :         if (element_representation == MachineRepresentation::kTagged &&
    2849      278189 :             TypeOf(value_node).Is(Type::SignedSmall())) {
    2850             :           element_representation = MachineRepresentation::kTaggedSigned;
    2851             :         }
    2852      120301 :         WriteBarrierKind write_barrier_kind = WriteBarrierKindFor(
    2853      120301 :             access.base_is_tagged, element_representation, access.type,
    2854      120301 :             input_info->representation(), value_node);
    2855      120301 :         ProcessInput(node, 0, UseInfoForBasePointer(access));  // base
    2856      120301 :         ProcessInput(node, 1, UseInfo::Word());                // index
    2857      120301 :         ProcessInput(node, 2,
    2858             :                      TruncatingUseInfoFromRepresentation(
    2859      120301 :                          element_representation));  // value
    2860      120301 :         ProcessRemainingInputs(node, 3);
    2861             :         SetOutput(node, MachineRepresentation::kNone);
    2862      120301 :         if (lower()) {
    2863       39219 :           if (write_barrier_kind < access.write_barrier_kind) {
    2864       22945 :             access.write_barrier_kind = write_barrier_kind;
    2865       22945 :             NodeProperties::ChangeOp(
    2866       45890 :                 node, jsgraph_->simplified()->StoreElement(access));
    2867             :           }
    2868             :         }
    2869             :         return;
    2870             :       }
    2871             :       case IrOpcode::kNumberIsFloat64Hole: {
    2872             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    2873         230 :                   MachineRepresentation::kBit);
    2874         230 :         return;
    2875             :       }
    2876             :       case IrOpcode::kTransitionAndStoreElement: {
    2877         905 :         Type value_type = TypeOf(node->InputAt(2));
    2878             : 
    2879         905 :         ProcessInput(node, 0, UseInfo::AnyTagged());  // array
    2880         905 :         ProcessInput(node, 1, UseInfo::Word());       // index
    2881             : 
    2882         905 :         if (value_type.Is(Type::SignedSmall())) {
    2883         287 :           ProcessInput(node, 2, UseInfo::TruncatingWord32());  // value
    2884         287 :           if (lower()) {
    2885          70 :             NodeProperties::ChangeOp(node,
    2886          70 :                                      simplified()->StoreSignedSmallElement());
    2887             :           }
    2888         618 :         } else if (value_type.Is(Type::Number())) {
    2889         123 :           ProcessInput(node, 2, UseInfo::TruncatingFloat64());  // value
    2890         123 :           if (lower()) {
    2891          28 :             Handle<Map> double_map = DoubleMapParameterOf(node->op());
    2892          28 :             NodeProperties::ChangeOp(
    2893             :                 node,
    2894          28 :                 simplified()->TransitionAndStoreNumberElement(double_map));
    2895             :           }
    2896         495 :         } else if (value_type.Is(Type::NonNumber())) {
    2897         119 :           ProcessInput(node, 2, UseInfo::AnyTagged());  // value
    2898         119 :           if (lower()) {
    2899          25 :             Handle<Map> fast_map = FastMapParameterOf(node->op());
    2900          25 :             NodeProperties::ChangeOp(
    2901             :                 node, simplified()->TransitionAndStoreNonNumberElement(
    2902          25 :                           fast_map, value_type));
    2903             :           }
    2904             :         } else {
    2905         376 :           ProcessInput(node, 2, UseInfo::AnyTagged());  // value
    2906             :         }
    2907             : 
    2908         905 :         ProcessRemainingInputs(node, 3);
    2909             :         SetOutput(node, MachineRepresentation::kNone);
    2910             :         return;
    2911             :       }
    2912             :       case IrOpcode::kLoadTypedElement: {
    2913             :         MachineRepresentation const rep =
    2914       16814 :             MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
    2915       16814 :         ProcessInput(node, 0, UseInfo::AnyTagged());  // buffer
    2916       16814 :         ProcessInput(node, 1, UseInfo::AnyTagged());  // base pointer
    2917       16814 :         ProcessInput(node, 2, UseInfo::Word());       // external pointer
    2918       16814 :         ProcessInput(node, 3, UseInfo::Word());       // index
    2919       16814 :         ProcessRemainingInputs(node, 4);
    2920             :         SetOutput(node, rep);
    2921             :         return;
    2922             :       }
    2923             :       case IrOpcode::kLoadDataViewElement: {
    2924             :         MachineRepresentation const rep =
    2925         804 :             MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
    2926         804 :         ProcessInput(node, 0, UseInfo::AnyTagged());  // buffer
    2927         804 :         ProcessInput(node, 1, UseInfo::Word());       // external pointer
    2928         804 :         ProcessInput(node, 2, UseInfo::Word());       // byte offset
    2929         804 :         ProcessInput(node, 3, UseInfo::Word());       // index
    2930         804 :         ProcessInput(node, 4, UseInfo::Bool());       // little-endian
    2931         804 :         ProcessRemainingInputs(node, 5);
    2932             :         SetOutput(node, rep);
    2933             :         return;
    2934             :       }
    2935             :       case IrOpcode::kStoreTypedElement: {
    2936             :         MachineRepresentation const rep =
    2937       15714 :             MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
    2938       15714 :         ProcessInput(node, 0, UseInfo::AnyTagged());  // buffer
    2939       15714 :         ProcessInput(node, 1, UseInfo::AnyTagged());  // base pointer
    2940       15714 :         ProcessInput(node, 2, UseInfo::Word());       // external pointer
    2941       15714 :         ProcessInput(node, 3, UseInfo::Word());       // index
    2942       15714 :         ProcessInput(node, 4,
    2943       15714 :                      TruncatingUseInfoFromRepresentation(rep));  // value
    2944       15714 :         ProcessRemainingInputs(node, 5);
    2945             :         SetOutput(node, MachineRepresentation::kNone);
    2946             :         return;
    2947             :       }
    2948             :       case IrOpcode::kStoreDataViewElement: {
    2949             :         MachineRepresentation const rep =
    2950         588 :             MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
    2951         588 :         ProcessInput(node, 0, UseInfo::AnyTagged());         // buffer
    2952         588 :         ProcessInput(node, 1, UseInfo::Word());              // external pointer
    2953         588 :         ProcessInput(node, 2, UseInfo::Word());              // byte offset
    2954         588 :         ProcessInput(node, 3, UseInfo::Word());              // index
    2955         588 :         ProcessInput(node, 4,
    2956         588 :                      TruncatingUseInfoFromRepresentation(rep));  // value
    2957         588 :         ProcessInput(node, 5, UseInfo::Bool());  // little-endian
    2958         588 :         ProcessRemainingInputs(node, 6);
    2959             :         SetOutput(node, MachineRepresentation::kNone);
    2960             :         return;
    2961             :       }
    2962             :       case IrOpcode::kConvertReceiver: {
    2963        2676 :         Type input_type = TypeOf(node->InputAt(0));
    2964             :         VisitBinop(node, UseInfo::AnyTagged(),
    2965             :                    MachineRepresentation::kTaggedPointer);
    2966        2676 :         if (lower()) {
    2967             :           // Try to optimize the {node} based on the input type.
    2968         873 :           if (input_type.Is(Type::Receiver())) {
    2969           0 :             DeferReplacement(node, node->InputAt(0));
    2970         873 :           } else if (input_type.Is(Type::NullOrUndefined())) {
    2971           0 :             DeferReplacement(node, node->InputAt(1));
    2972         873 :           } else if (!input_type.Maybe(Type::NullOrUndefined())) {
    2973          85 :             NodeProperties::ChangeOp(
    2974             :                 node, lowering->simplified()->ConvertReceiver(
    2975          85 :                           ConvertReceiverMode::kNotNullOrUndefined));
    2976             :           }
    2977             :         }
    2978             :         return;
    2979             :       }
    2980             :       case IrOpcode::kPlainPrimitiveToNumber: {
    2981        2630 :         if (InputIs(node, Type::Boolean())) {
    2982         199 :           VisitUnop(node, UseInfo::Bool(), MachineRepresentation::kWord32);
    2983         258 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2984        2431 :         } else if (InputIs(node, Type::String())) {
    2985         998 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    2986         998 :           if (lower()) {
    2987         330 :             NodeProperties::ChangeOp(node, simplified()->StringToNumber());
    2988             :           }
    2989        1433 :         } else if (truncation.IsUsedAsWord32()) {
    2990          57 :           if (InputIs(node, Type::NumberOrOddball())) {
    2991             :             VisitUnop(node, UseInfo::TruncatingWord32(),
    2992          30 :                       MachineRepresentation::kWord32);
    2993          40 :             if (lower()) DeferReplacement(node, node->InputAt(0));
    2994             :           } else {
    2995             :             VisitUnop(node, UseInfo::AnyTagged(),
    2996          27 :                       MachineRepresentation::kWord32);
    2997          27 :             if (lower()) {
    2998           9 :               NodeProperties::ChangeOp(node,
    2999           9 :                                        simplified()->PlainPrimitiveToWord32());
    3000             :             }
    3001             :           }
    3002        1376 :         } else if (truncation.IsUsedAsFloat64()) {
    3003        1300 :           if (InputIs(node, Type::NumberOrOddball())) {
    3004             :             VisitUnop(node, UseInfo::TruncatingFloat64(),
    3005        1300 :                       MachineRepresentation::kFloat64);
    3006        1635 :             if (lower()) DeferReplacement(node, node->InputAt(0));
    3007             :           } else {
    3008             :             VisitUnop(node, UseInfo::AnyTagged(),
    3009           0 :                       MachineRepresentation::kFloat64);
    3010           0 :             if (lower()) {
    3011           0 :               NodeProperties::ChangeOp(node,
    3012           0 :                                        simplified()->PlainPrimitiveToFloat64());
    3013             :             }
    3014             :           }
    3015             :         } else {
    3016          76 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    3017             :         }
    3018             :         return;
    3019             :       }
    3020             :       case IrOpcode::kSpeculativeToNumber: {
    3021             :         NumberOperationParameters const& p =
    3022      133151 :             NumberOperationParametersOf(node->op());
    3023      133151 :         switch (p.hint()) {
    3024             :           case NumberOperationHint::kSigned32:
    3025             :           case NumberOperationHint::kSignedSmall:
    3026             :           case NumberOperationHint::kSignedSmallInputs:
    3027        6223 :             VisitUnop(node,
    3028             :                       CheckedUseInfoAsWord32FromHint(p.hint(), p.feedback()),
    3029        6223 :                       MachineRepresentation::kWord32, Type::Signed32());
    3030        6223 :             break;
    3031             :           case NumberOperationHint::kNumber:
    3032             :           case NumberOperationHint::kNumberOrOddball:
    3033      126928 :             VisitUnop(node,
    3034             :                       CheckedUseInfoAsFloat64FromHint(p.hint(), p.feedback()),
    3035      126928 :                       MachineRepresentation::kFloat64);
    3036      126928 :             break;
    3037             :         }
    3038      173479 :         if (lower()) DeferReplacement(node, node->InputAt(0));
    3039             :         return;
    3040             :       }
    3041             :       case IrOpcode::kObjectIsArrayBufferView: {
    3042             :         // TODO(turbofan): Introduce a Type::ArrayBufferView?
    3043          48 :         VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    3044          48 :         return;
    3045             :       }
    3046             :       case IrOpcode::kObjectIsBigInt: {
    3047          75 :         VisitObjectIs(node, Type::BigInt(), lowering);
    3048          75 :         return;
    3049             :       }
    3050             :       case IrOpcode::kObjectIsCallable: {
    3051         333 :         VisitObjectIs(node, Type::Callable(), lowering);
    3052         333 :         return;
    3053             :       }
    3054             :       case IrOpcode::kObjectIsConstructor: {
    3055             :         // TODO(turbofan): Introduce a Type::Constructor?
    3056        1137 :         VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    3057        1137 :         return;
    3058             :       }
    3059             :       case IrOpcode::kObjectIsDetectableCallable: {
    3060       43755 :         VisitObjectIs(node, Type::DetectableCallable(), lowering);
    3061       43755 :         return;
    3062             :       }
    3063             :       case IrOpcode::kObjectIsFiniteNumber: {
    3064         588 :         Type const input_type = GetUpperBound(node->InputAt(0));
    3065        1176 :         if (input_type.Is(type_cache_->kSafeInteger)) {
    3066         210 :           VisitUnop(node, UseInfo::None(), MachineRepresentation::kBit);
    3067         210 :           if (lower()) {
    3068          70 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
    3069             :           }
    3070         378 :         } else if (!input_type.Maybe(Type::Number())) {
    3071          42 :           VisitUnop(node, UseInfo::Any(), MachineRepresentation::kBit);
    3072          42 :           if (lower()) {
    3073          14 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
    3074             :           }
    3075         336 :         } else if (input_type.Is(Type::Number())) {
    3076             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    3077         315 :                     MachineRepresentation::kBit);
    3078         315 :           if (lower()) {
    3079         105 :             NodeProperties::ChangeOp(node,
    3080         105 :                                      lowering->simplified()->NumberIsFinite());
    3081             :           }
    3082             :         } else {
    3083          21 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    3084             :         }
    3085             :         return;
    3086             :       }
    3087             :       case IrOpcode::kNumberIsFinite: {
    3088             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    3089          70 :                   MachineRepresentation::kBit);
    3090          70 :         return;
    3091             :       }
    3092             :       case IrOpcode::kObjectIsSafeInteger: {
    3093          42 :         Type const input_type = GetUpperBound(node->InputAt(0));
    3094          84 :         if (input_type.Is(type_cache_->kSafeInteger)) {
    3095           0 :           VisitUnop(node, UseInfo::None(), MachineRepresentation::kBit);
    3096           0 :           if (lower()) {
    3097           0 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
    3098             :           }
    3099          42 :         } else if (!input_type.Maybe(Type::Number())) {
    3100           0 :           VisitUnop(node, UseInfo::Any(), MachineRepresentation::kBit);
    3101           0 :           if (lower()) {
    3102           0 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
    3103             :           }
    3104          42 :         } else if (input_type.Is(Type::Number())) {
    3105             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    3106          21 :                     MachineRepresentation::kBit);
    3107          21 :           if (lower()) {
    3108           7 :             NodeProperties::ChangeOp(
    3109           7 :                 node, lowering->simplified()->NumberIsSafeInteger());
    3110             :           }
    3111             :         } else {
    3112          21 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    3113             :         }
    3114             :         return;
    3115             :       }
    3116             :       case IrOpcode::kNumberIsSafeInteger: {
    3117           0 :         UNREACHABLE();
    3118             :       }
    3119             :       case IrOpcode::kObjectIsInteger: {
    3120         588 :         Type const input_type = GetUpperBound(node->InputAt(0));
    3121        1176 :         if (input_type.Is(type_cache_->kSafeInteger)) {
    3122         210 :           VisitUnop(node, UseInfo::None(), MachineRepresentation::kBit);
    3123         210 :           if (lower()) {
    3124          70 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
    3125             :           }
    3126         378 :         } else if (!input_type.Maybe(Type::Number())) {
    3127           0 :           VisitUnop(node, UseInfo::Any(), MachineRepresentation::kBit);
    3128           0 :           if (lower()) {
    3129           0 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
    3130             :           }
    3131         378 :         } else if (input_type.Is(Type::Number())) {
    3132             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    3133         357 :                     MachineRepresentation::kBit);
    3134         357 :           if (lower()) {
    3135         119 :             NodeProperties::ChangeOp(node,
    3136         119 :                                      lowering->simplified()->NumberIsInteger());
    3137             :           }
    3138             :         } else {
    3139          21 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    3140             :         }
    3141             :         return;
    3142             :       }
    3143             :       case IrOpcode::kNumberIsInteger: {
    3144             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    3145           0 :                   MachineRepresentation::kBit);
    3146           0 :         return;
    3147             :       }
    3148             :       case IrOpcode::kObjectIsMinusZero: {
    3149         363 :         Type const input_type = GetUpperBound(node->InputAt(0));
    3150         363 :         if (input_type.Is(Type::MinusZero())) {
    3151           0 :           VisitUnop(node, UseInfo::None(), MachineRepresentation::kBit);
    3152           0 :           if (lower()) {
    3153           0 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
    3154             :           }
    3155         363 :         } else if (!input_type.Maybe(Type::MinusZero())) {
    3156           0 :           VisitUnop(node, UseInfo::Any(), MachineRepresentation::kBit);
    3157           0 :           if (lower()) {
    3158           0 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
    3159             :           }
    3160         363 :         } else if (input_type.Is(Type::Number())) {
    3161             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    3162         294 :                     MachineRepresentation::kBit);
    3163         294 :           if (lower()) {
    3164          98 :             NodeProperties::ChangeOp(node, simplified()->NumberIsMinusZero());
    3165             :           }
    3166             :         } else {
    3167          69 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    3168             :         }
    3169             :         return;
    3170             :       }
    3171             :       case IrOpcode::kObjectIsNaN: {
    3172        2724 :         Type const input_type = GetUpperBound(node->InputAt(0));
    3173        2724 :         if (input_type.Is(Type::NaN())) {
    3174           0 :           VisitUnop(node, UseInfo::None(), MachineRepresentation::kBit);
    3175           0 :           if (lower()) {
    3176           0 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
    3177             :           }
    3178        2724 :         } else if (!input_type.Maybe(Type::NaN())) {
    3179          36 :           VisitUnop(node, UseInfo::Any(), MachineRepresentation::kBit);
    3180          36 :           if (lower()) {
    3181          12 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
    3182             :           }
    3183        2688 :         } else if (input_type.Is(Type::Number())) {
    3184             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    3185         540 :                     MachineRepresentation::kBit);
    3186         540 :           if (lower()) {
    3187         180 :             NodeProperties::ChangeOp(node, simplified()->NumberIsNaN());
    3188             :           }
    3189             :         } else {
    3190        2148 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    3191             :         }
    3192             :         return;
    3193             :       }
    3194             :       case IrOpcode::kNumberIsNaN: {
    3195             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    3196        8520 :                   MachineRepresentation::kBit);
    3197        8520 :         return;
    3198             :       }
    3199             :       case IrOpcode::kObjectIsNonCallable: {
    3200       18722 :         VisitObjectIs(node, Type::NonCallable(), lowering);
    3201       18722 :         return;
    3202             :       }
    3203             :       case IrOpcode::kObjectIsNumber: {
    3204       23573 :         VisitObjectIs(node, Type::Number(), lowering);
    3205       23573 :         return;
    3206             :       }
    3207             :       case IrOpcode::kObjectIsReceiver: {
    3208       63784 :         VisitObjectIs(node, Type::Receiver(), lowering);
    3209       63784 :         return;
    3210             :       }
    3211             :       case IrOpcode::kObjectIsSmi: {
    3212             :         // TODO(turbofan): Optimize based on input representation.
    3213        3855 :         VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    3214        3855 :         return;
    3215             :       }
    3216             :       case IrOpcode::kObjectIsString: {
    3217        7053 :         VisitObjectIs(node, Type::String(), lowering);
    3218        7053 :         return;
    3219             :       }
    3220             :       case IrOpcode::kObjectIsSymbol: {
    3221          71 :         VisitObjectIs(node, Type::Symbol(), lowering);
    3222          71 :         return;
    3223             :       }
    3224             :       case IrOpcode::kObjectIsUndetectable: {
    3225        4773 :         VisitObjectIs(node, Type::Undetectable(), lowering);
    3226        4773 :         return;
    3227             :       }
    3228             :       case IrOpcode::kArgumentsFrame: {
    3229             :         SetOutput(node, MachineType::PointerRepresentation());
    3230             :         return;
    3231             :       }
    3232             :       case IrOpcode::kArgumentsLength: {
    3233       50990 :         VisitUnop(node, UseInfo::Word(), MachineRepresentation::kTaggedSigned);
    3234       50990 :         return;
    3235             :       }
    3236             :       case IrOpcode::kNewDoubleElements:
    3237             :       case IrOpcode::kNewSmiOrObjectElements: {
    3238        1708 :         VisitUnop(node, UseInfo::Word(), MachineRepresentation::kTaggedPointer);
    3239        1708 :         return;
    3240             :       }
    3241             :       case IrOpcode::kNewArgumentsElements: {
    3242             :         VisitBinop(node, UseInfo::Word(), UseInfo::TaggedSigned(),
    3243       59029 :                    MachineRepresentation::kTaggedPointer);
    3244       59029 :         return;
    3245             :       }
    3246             :       case IrOpcode::kCheckFloat64Hole: {
    3247        1894 :         Type const input_type = TypeOf(node->InputAt(0));
    3248             :         CheckFloat64HoleMode mode =
    3249        1894 :             CheckFloat64HoleParametersOf(node->op()).mode();
    3250        1894 :         if (mode == CheckFloat64HoleMode::kAllowReturnHole) {
    3251             :           // If {mode} is allow-return-hole _and_ the {truncation}
    3252             :           // identifies NaN and undefined, we can just pass along
    3253             :           // the {truncation} and completely wipe the {node}.
    3254        1349 :           if (truncation.IsUnused()) return VisitUnused(node);
    3255        1252 :           if (truncation.IsUsedAsFloat64()) {
    3256             :             VisitUnop(node, UseInfo::TruncatingFloat64(),
    3257         132 :                       MachineRepresentation::kFloat64);
    3258         176 :             if (lower()) DeferReplacement(node, node->InputAt(0));
    3259             :             return;
    3260             :           }
    3261             :         }
    3262        3330 :         VisitUnop(node,
    3263             :                   UseInfo(MachineRepresentation::kFloat64, Truncation::Any()),
    3264        1665 :                   MachineRepresentation::kFloat64, Type::Number());
    3265        2199 :         if (lower() && input_type.Is(Type::Number())) {
    3266          64 :           DeferReplacement(node, node->InputAt(0));
    3267             :         }
    3268             :         return;
    3269             :       }
    3270             :       case IrOpcode::kCheckNotTaggedHole: {
    3271         316 :         VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    3272         316 :         return;
    3273             :       }
    3274             :       case IrOpcode::kConvertTaggedHoleToUndefined: {
    3275       10165 :         if (InputIs(node, Type::NumberOrOddball()) &&
    3276             :             truncation.IsUsedAsWord32()) {
    3277             :           // Propagate the Word32 truncation.
    3278             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    3279        1009 :                     MachineRepresentation::kWord32);
    3280        1259 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    3281        8147 :         } else if (InputIs(node, Type::NumberOrOddball()) &&
    3282             :                    truncation.IsUsedAsFloat64()) {
    3283             :           // Propagate the Float64 truncation.
    3284             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    3285         143 :                     MachineRepresentation::kFloat64);
    3286         187 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    3287        6025 :         } else if (InputIs(node, Type::NonInternal())) {
    3288         130 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    3289         173 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    3290             :         } else {
    3291             :           // TODO(turbofan): Add a (Tagged) truncation that identifies hole
    3292             :           // and undefined, i.e. for a[i] === obj cases.
    3293        5895 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    3294             :         }
    3295             :         return;
    3296             :       }
    3297             :       case IrOpcode::kCheckEqualsSymbol:
    3298             :       case IrOpcode::kCheckEqualsInternalizedString:
    3299             :         return VisitBinop(node, UseInfo::AnyTagged(),
    3300             :                           MachineRepresentation::kNone);
    3301             :       case IrOpcode::kMapGuard:
    3302             :         // Eliminate MapGuard nodes here.
    3303       21563 :         return VisitUnused(node);
    3304             :       case IrOpcode::kCheckMaps:
    3305             :       case IrOpcode::kTransitionElementsKind: {
    3306      160250 :         VisitInputs(node);
    3307             :         return SetOutput(node, MachineRepresentation::kNone);
    3308             :       }
    3309             :       case IrOpcode::kCompareMaps:
    3310             :         return VisitUnop(node, UseInfo::AnyTagged(),
    3311       23501 :                          MachineRepresentation::kBit);
    3312             :       case IrOpcode::kEnsureWritableFastElements:
    3313             :         return VisitBinop(node, UseInfo::AnyTagged(),
    3314             :                           MachineRepresentation::kTaggedPointer);
    3315             :       case IrOpcode::kMaybeGrowFastElements: {
    3316       11609 :         Type const index_type = TypeOf(node->InputAt(2));
    3317       11609 :         Type const length_type = TypeOf(node->InputAt(3));
    3318       11609 :         ProcessInput(node, 0, UseInfo::AnyTagged());         // object
    3319       11609 :         ProcessInput(node, 1, UseInfo::AnyTagged());         // elements
    3320       11609 :         ProcessInput(node, 2, UseInfo::TruncatingWord32());  // index
    3321       11609 :         ProcessInput(node, 3, UseInfo::TruncatingWord32());  // length
    3322       11609 :         ProcessRemainingInputs(node, 4);
    3323             :         SetOutput(node, MachineRepresentation::kTaggedPointer);
    3324       11609 :         if (lower()) {
    3325             :           // If the index is known to be less than the length (or if
    3326             :           // we're in dead code), we know that we don't need to grow
    3327             :           // the elements, so we can just remove this operation all
    3328             :           // together and replace it with the elements that we have
    3329             :           // on the inputs.
    3330       10701 :           if (index_type.IsNone() || length_type.IsNone() ||
    3331        3567 :               index_type.Max() < length_type.Min()) {
    3332          51 :             DeferReplacement(node, node->InputAt(1));
    3333             :           }
    3334             :         }
    3335             :         return;
    3336             :       }
    3337             : 
    3338             :       case IrOpcode::kDateNow:
    3339          39 :         VisitInputs(node);
    3340             :         return SetOutput(node, MachineRepresentation::kTaggedPointer);
    3341             :       case IrOpcode::kFrameState:
    3342    16612302 :         return VisitFrameState(node);
    3343             :       case IrOpcode::kStateValues:
    3344    10989243 :         return VisitStateValues(node);
    3345             :       case IrOpcode::kObjectState:
    3346       69104 :         return VisitObjectState(node);
    3347             :       case IrOpcode::kObjectId:
    3348             :         return SetOutput(node, MachineRepresentation::kTaggedPointer);
    3349             :       case IrOpcode::kTypeGuard: {
    3350             :         // We just get rid of the sigma here, choosing the best representation
    3351             :         // for the sigma's type.
    3352       84527 :         Type type = TypeOf(node);
    3353             :         MachineRepresentation representation =
    3354       84527 :             GetOutputInfoForPhi(node, type, truncation);
    3355             : 
    3356             :         // Here we pretend that the input has the sigma's type for the
    3357             :         // conversion.
    3358      169052 :         UseInfo use(representation, truncation);
    3359       84526 :         if (propagate()) {
    3360       28512 :           EnqueueInput(node, 0, use);
    3361       56014 :         } else if (lower()) {
    3362       20442 :           ConvertInput(node, 0, use, type);
    3363             :         }
    3364       84526 :         ProcessRemainingInputs(node, 1);
    3365             :         SetOutput(node, representation);
    3366             :         return;
    3367             :       }
    3368             : 
    3369             :       case IrOpcode::kFinishRegion:
    3370      402391 :         VisitInputs(node);
    3371             :         // Assume the output is tagged pointer.
    3372             :         return SetOutput(node, MachineRepresentation::kTaggedPointer);
    3373             : 
    3374             :       case IrOpcode::kReturn:
    3375     1666038 :         VisitReturn(node);
    3376             :         // Assume the output is tagged.
    3377             :         return SetOutput(node, MachineRepresentation::kTagged);
    3378             : 
    3379             :       case IrOpcode::kFindOrderedHashMapEntry: {
    3380         631 :         Type const key_type = TypeOf(node->InputAt(1));
    3381         631 :         if (key_type.Is(Type::Signed32OrMinusZero())) {
    3382             :           VisitBinop(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(),
    3383          64 :                      MachineType::PointerRepresentation());
    3384          64 :           if (lower()) {
    3385          16 :             NodeProperties::ChangeOp(
    3386             :                 node,
    3387          16 :                 lowering->simplified()->FindOrderedHashMapEntryForInt32Key());
    3388             :           }
    3389             :         } else {
    3390             :           VisitBinop(node, UseInfo::AnyTagged(),
    3391             :                      MachineRepresentation::kTaggedSigned);
    3392             :         }
    3393             :         return;
    3394             :       }
    3395             : 
    3396             :       // Operators with all inputs tagged and no or tagged output have uniform
    3397             :       // handling.
    3398             :       case IrOpcode::kEnd:
    3399             :       case IrOpcode::kIfSuccess:
    3400             :       case IrOpcode::kIfException:
    3401             :       case IrOpcode::kIfTrue:
    3402             :       case IrOpcode::kIfFalse:
    3403             :       case IrOpcode::kIfValue:
    3404             :       case IrOpcode::kIfDefault:
    3405             :       case IrOpcode::kDeoptimize:
    3406             :       case IrOpcode::kEffectPhi:
    3407             :       case IrOpcode::kTerminate:
    3408             :       case IrOpcode::kCheckpoint:
    3409             :       case IrOpcode::kLoop:
    3410             :       case IrOpcode::kMerge:
    3411             :       case IrOpcode::kThrow:
    3412             :       case IrOpcode::kBeginRegion:
    3413             :       case IrOpcode::kProjection:
    3414             :       case IrOpcode::kOsrValue:
    3415             :       case IrOpcode::kArgumentsElementsState:
    3416             :       case IrOpcode::kArgumentsLengthState:
    3417             :       case IrOpcode::kUnreachable:
    3418             :       case IrOpcode::kRuntimeAbort:
    3419             : // All JavaScript operators except JSToNumber have uniform handling.
    3420             : #define OPCODE_CASE(name) case IrOpcode::k##name:
    3421             :         JS_SIMPLE_BINOP_LIST(OPCODE_CASE)
    3422             :         JS_OBJECT_OP_LIST(OPCODE_CASE)
    3423             :         JS_CONTEXT_OP_LIST(OPCODE_CASE)
    3424             :         JS_OTHER_OP_LIST(OPCODE_CASE)
    3425             : #undef OPCODE_CASE
    3426             :       case IrOpcode::kJSBitwiseNot:
    3427             :       case IrOpcode::kJSDecrement:
    3428             :       case IrOpcode::kJSIncrement:
    3429             :       case IrOpcode::kJSNegate:
    3430             :       case IrOpcode::kJSToLength:
    3431             :       case IrOpcode::kJSToName:
    3432             :       case IrOpcode::kJSToObject:
    3433             :       case IrOpcode::kJSToString:
    3434             :       case IrOpcode::kJSParseInt:
    3435    29052933 :         VisitInputs(node);
    3436             :         // Assume the output is tagged.
    3437             :         return SetOutput(node, MachineRepresentation::kTagged);
    3438             :       case IrOpcode::kDeadValue:
    3439        1505 :         ProcessInput(node, 0, UseInfo::Any());
    3440             :         return SetOutput(node, MachineRepresentation::kNone);
    3441             :       default:
    3442           0 :         FATAL(
    3443             :             "Representation inference: unsupported opcode %i (%s), node #%i\n.",
    3444           0 :             node->opcode(), node->op()->mnemonic(), node->id());
    3445             :         break;
    3446             :     }
    3447             :     UNREACHABLE();
    3448             :   }
    3449             : 
    3450     1256854 :   void DeferReplacement(Node* node, Node* replacement) {
    3451     1256854 :     TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(),
    3452             :           node->op()->mnemonic(), replacement->id(),
    3453             :           replacement->op()->mnemonic());
    3454             : 
    3455             :     // Disconnect the node from effect and control chains, if necessary.
    3456     2513712 :     if (node->op()->EffectInputCount() > 0) {
    3457             :       DCHECK_LT(0, node->op()->ControlInputCount());
    3458             :       // Disconnect the node from effect and control chains.
    3459      104202 :       Node* control = NodeProperties::GetControlInput(node);
    3460      104202 :       Node* effect = NodeProperties::GetEffectInput(node);
    3461      104202 :       ReplaceEffectControlUses(node, effect, control);
    3462             :     }
    3463             : 
    3464     1256856 :     replacements_.push_back(node);
    3465     1256859 :     replacements_.push_back(replacement);
    3466             : 
    3467     1256857 :     node->NullAllInputs();  // Node is now dead.
    3468     1256851 :   }
    3469             : 
    3470       34041 :   void Kill(Node* node) {
    3471       34041 :     TRACE("killing #%d:%s\n", node->id(), node->op()->mnemonic());
    3472             : 
    3473       34041 :     if (node->op()->EffectInputCount() == 1) {
    3474             :       DCHECK_LT(0, node->op()->ControlInputCount());
    3475             :       // Disconnect the node from effect and control chains.
    3476       34027 :       Node* control = NodeProperties::GetControlInput(node);
    3477       34027 :       Node* effect = NodeProperties::GetEffectInput(node);
    3478       34027 :       ReplaceEffectControlUses(node, effect, control);
    3479             :     } else {
    3480             :       DCHECK_EQ(0, node->op()->EffectInputCount());
    3481             :       DCHECK_EQ(0, node->op()->ControlOutputCount());
    3482             :       DCHECK_EQ(0, node->op()->EffectOutputCount());
    3483             :     }
    3484             : 
    3485       34041 :     node->ReplaceUses(jsgraph_->Dead());
    3486             : 
    3487       34041 :     node->NullAllInputs();  // The {node} is now dead.
    3488       34041 :   }
    3489             : 
    3490    51551110 :   void PrintOutputInfo(NodeInfo* info) {
    3491    51551110 :     if (FLAG_trace_representation) {
    3492           0 :       StdoutStream{} << info->representation();
    3493             :     }
    3494    51551110 :   }
    3495             : 
    3496             :   void PrintRepresentation(MachineRepresentation rep) {
    3497             :     if (FLAG_trace_representation) {
    3498             :       StdoutStream{} << rep;
    3499             :     }
    3500             :   }
    3501             : 
    3502   102344239 :   void PrintTruncation(Truncation truncation) {
    3503   102344239 :     if (FLAG_trace_representation) {
    3504           0 :       StdoutStream{} << truncation.description() << std::endl;
    3505             :     }
    3506   102344239 :   }
    3507             : 
    3508    16044486 :   void PrintUseInfo(UseInfo info) {
    3509    16044486 :     if (FLAG_trace_representation) {
    3510           0 :       StdoutStream{} << info.representation() << ":"
    3511           0 :                      << info.truncation().description();
    3512             :     }
    3513    16044486 :   }
    3514             : 
    3515             :  private:
    3516             :   JSGraph* jsgraph_;
    3517             :   Zone* zone_;                      // Temporary zone.
    3518             :   size_t const count_;              // number of nodes in the graph
    3519             :   ZoneVector<NodeInfo> info_;       // node id -> usage information
    3520             : #ifdef DEBUG
    3521             :   ZoneVector<InputUseInfos> node_input_use_infos_;  // Debug information about
    3522             :                                                     // requirements on inputs.
    3523             : #endif                                              // DEBUG
    3524             :   NodeVector nodes_;                // collected nodes
    3525             :   NodeVector replacements_;         // replacements to be done after lowering
    3526             :   Phase phase_;                     // current phase of algorithm
    3527             :   RepresentationChanger* changer_;  // for inserting representation changes
    3528             :   ZoneQueue<Node*> queue_;          // queue for traversing the graph
    3529             : 
    3530             :   struct NodeState {
    3531             :     Node* node;
    3532             :     int input_index;
    3533             :   };
    3534             :   ZoneStack<NodeState> typing_stack_;  // stack for graph typing.
    3535             :   // TODO(danno): RepresentationSelector shouldn't know anything about the
    3536             :   // source positions table, but must for now since there currently is no other
    3537             :   // way to pass down source position information to nodes created during
    3538             :   // lowering. Once this phase becomes a vanilla reducer, it should get source
    3539             :   // position information via the SourcePositionWrapper like all other reducers.
    3540             :   SourcePositionTable* source_positions_;
    3541             :   NodeOriginTable* node_origins_;
    3542             :   TypeCache const* type_cache_;
    3543             :   OperationTyper op_typer_;  // helper for the feedback typer
    3544             : 
    3545             :   NodeInfo* GetInfo(Node* node) {
    3546             :     DCHECK(node->id() < count_);
    3547   703781678 :     return &info_[node->id()];
    3548             :   }
    3549             :   Zone* zone() { return zone_; }
    3550             :   Zone* graph_zone() { return jsgraph_->zone(); }
    3551             : };
    3552             : 
    3553      463901 : SimplifiedLowering::SimplifiedLowering(JSGraph* jsgraph, JSHeapBroker* broker,
    3554             :                                        Zone* zone,
    3555             :                                        SourcePositionTable* source_positions,
    3556             :                                        NodeOriginTable* node_origins,
    3557             :                                        PoisoningMitigationLevel poisoning_level)
    3558             :     : jsgraph_(jsgraph),
    3559             :       broker_(broker),
    3560             :       zone_(zone),
    3561      463901 :       type_cache_(TypeCache::Get()),
    3562             :       source_positions_(source_positions),
    3563             :       node_origins_(node_origins),
    3564     1391719 :       poisoning_level_(poisoning_level) {}
    3565             : 
    3566      463904 : void SimplifiedLowering::LowerAllNodes() {
    3567      463904 :   RepresentationChanger changer(jsgraph(), jsgraph()->isolate());
    3568      463907 :   RepresentationSelector selector(jsgraph(), broker_, zone_, &changer,
    3569      927814 :                                   source_positions_, node_origins_);
    3570      463913 :   selector.Run(this);
    3571      463909 : }
    3572             : 
    3573        1413 : void SimplifiedLowering::DoJSToNumberOrNumericTruncatesToFloat64(
    3574             :     Node* node, RepresentationSelector* selector) {
    3575             :   DCHECK(node->opcode() == IrOpcode::kJSToNumber ||
    3576             :          node->opcode() == IrOpcode::kJSToNumberConvertBigInt ||
    3577             :          node->opcode() == IrOpcode::kJSToNumeric);
    3578             :   Node* value = node->InputAt(0);
    3579             :   Node* context = node->InputAt(1);
    3580             :   Node* frame_state = node->InputAt(2);
    3581             :   Node* effect = node->InputAt(3);
    3582             :   Node* control = node->InputAt(4);
    3583             : 
    3584        1413 :   Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), value);
    3585             :   Node* branch0 =
    3586        1413 :       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
    3587             : 
    3588        1413 :   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
    3589             :   Node* etrue0 = effect;
    3590             :   Node* vtrue0;
    3591             :   {
    3592        1413 :     vtrue0 = graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), value);
    3593        1413 :     vtrue0 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue0);
    3594             :   }
    3595             : 
    3596        1413 :   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
    3597             :   Node* efalse0 = effect;
    3598             :   Node* vfalse0;
    3599             :   {
    3600             :     Operator const* op =
    3601             :         node->opcode() == IrOpcode::kJSToNumber
    3602             :             ? (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
    3603             :                    ? ToNumberConvertBigIntOperator()
    3604             :                    : ToNumberOperator())
    3605        1413 :             : ToNumericOperator();
    3606             :     Node* code = node->opcode() == IrOpcode::kJSToNumber
    3607             :                      ? ToNumberCode()
    3608             :                      : (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
    3609             :                             ? ToNumberConvertBigIntCode()
    3610        1413 :                             : ToNumericCode());
    3611             :     vfalse0 = efalse0 = if_false0 = graph()->NewNode(
    3612             :         op, code, value, context, frame_state, efalse0, if_false0);
    3613             : 
    3614             :     // Update potential {IfException} uses of {node} to point to the above
    3615             :     // stub call node instead.
    3616        1413 :     Node* on_exception = nullptr;
    3617        1413 :     if (NodeProperties::IsExceptionalCall(node, &on_exception)) {
    3618           0 :       NodeProperties::ReplaceControlInput(on_exception, vfalse0);
    3619           0 :       NodeProperties::ReplaceEffectInput(on_exception, efalse0);
    3620           0 :       if_false0 = graph()->NewNode(common()->IfSuccess(), vfalse0);
    3621             :     }
    3622             : 
    3623        1413 :     Node* check1 = graph()->NewNode(simplified()->ObjectIsSmi(), vfalse0);
    3624        1413 :     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
    3625             : 
    3626        1413 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    3627             :     Node* etrue1 = efalse0;
    3628             :     Node* vtrue1;
    3629             :     {
    3630             :       vtrue1 =
    3631        1413 :           graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), vfalse0);
    3632        1413 :       vtrue1 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue1);
    3633             :     }
    3634             : 
    3635        1413 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    3636             :     Node* efalse1 = efalse0;
    3637             :     Node* vfalse1;
    3638             :     {
    3639        1413 :       vfalse1 = efalse1 = graph()->NewNode(
    3640        2826 :           simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
    3641             :           efalse1, if_false1);
    3642             :     }
    3643             : 
    3644        1413 :     if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
    3645             :     efalse0 =
    3646        1413 :         graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
    3647             :     vfalse0 =
    3648        1413 :         graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
    3649             :                          vtrue1, vfalse1, if_false0);
    3650             :   }
    3651             : 
    3652        1413 :   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
    3653        1413 :   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
    3654        1413 :   value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
    3655             :                            vtrue0, vfalse0, control);
    3656             : 
    3657             :   // Replace effect and control uses appropriately.
    3658        9893 :   for (Edge edge : node->use_edges()) {
    3659        4240 :     if (NodeProperties::IsControlEdge(edge)) {
    3660        1413 :       if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
    3661           0 :         edge.from()->ReplaceUses(control);
    3662           0 :         edge.from()->Kill();
    3663             :       } else {
    3664             :         DCHECK_NE(IrOpcode::kIfException, edge.from()->opcode());
    3665        1413 :         edge.UpdateTo(control);
    3666             :       }
    3667        2827 :     } else if (NodeProperties::IsEffectEdge(edge)) {
    3668        1414 :       edge.UpdateTo(effect);
    3669             :     }
    3670             :   }
    3671             : 
    3672        1413 :   selector->DeferReplacement(node, value);
    3673        1413 : }
    3674             : 
    3675          75 : void SimplifiedLowering::DoJSToNumberOrNumericTruncatesToWord32(
    3676             :     Node* node, RepresentationSelector* selector) {
    3677             :   DCHECK(node->opcode() == IrOpcode::kJSToNumber ||
    3678             :          node->opcode() == IrOpcode::kJSToNumberConvertBigInt ||
    3679             :          node->opcode() == IrOpcode::kJSToNumeric);
    3680             :   Node* value = node->InputAt(0);
    3681             :   Node* context = node->InputAt(1);
    3682             :   Node* frame_state = node->InputAt(2);
    3683             :   Node* effect = node->InputAt(3);
    3684             :   Node* control = node->InputAt(4);
    3685             : 
    3686          75 :   Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), value);
    3687             :   Node* branch0 =
    3688          75 :       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
    3689             : 
    3690          75 :   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
    3691             :   Node* etrue0 = effect;
    3692             :   Node* vtrue0 =
    3693          75 :       graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), value);
    3694             : 
    3695          75 :   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
    3696             :   Node* efalse0 = effect;
    3697             :   Node* vfalse0;
    3698             :   {
    3699             :     Operator const* op =
    3700             :         node->opcode() == IrOpcode::kJSToNumber
    3701             :             ? (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
    3702             :                    ? ToNumberConvertBigIntOperator()
    3703             :                    : ToNumberOperator())
    3704          75 :             : ToNumericOperator();
    3705             :     Node* code = node->opcode() == IrOpcode::kJSToNumber
    3706             :                      ? ToNumberCode()
    3707             :                      : (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
    3708             :                             ? ToNumberConvertBigIntCode()
    3709          75 :                             : ToNumericCode());
    3710             :     vfalse0 = efalse0 = if_false0 = graph()->NewNode(
    3711             :         op, code, value, context, frame_state, efalse0, if_false0);
    3712             : 
    3713             :     // Update potential {IfException} uses of {node} to point to the above
    3714             :     // stub call node instead.
    3715          75 :     Node* on_exception = nullptr;
    3716          75 :     if (NodeProperties::IsExceptionalCall(node, &on_exception)) {
    3717           8 :       NodeProperties::ReplaceControlInput(on_exception, vfalse0);
    3718           8 :       NodeProperties::ReplaceEffectInput(on_exception, efalse0);
    3719           8 :       if_false0 = graph()->NewNode(common()->IfSuccess(), vfalse0);
    3720             :     }
    3721             : 
    3722          75 :     Node* check1 = graph()->NewNode(simplified()->ObjectIsSmi(), vfalse0);
    3723          75 :     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
    3724             : 
    3725          75 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    3726             :     Node* etrue1 = efalse0;
    3727             :     Node* vtrue1 =
    3728          75 :         graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), vfalse0);
    3729             : 
    3730          75 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    3731             :     Node* efalse1 = efalse0;
    3732             :     Node* vfalse1;
    3733             :     {
    3734          75 :       vfalse1 = efalse1 = graph()->NewNode(
    3735         150 :           simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
    3736             :           efalse1, if_false1);
    3737          75 :       vfalse1 = graph()->NewNode(machine()->TruncateFloat64ToWord32(), vfalse1);
    3738             :     }
    3739             : 
    3740          75 :     if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
    3741             :     efalse0 =
    3742          75 :         graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
    3743          75 :     vfalse0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
    3744             :                                vtrue1, vfalse1, if_false0);
    3745             :   }
    3746             : 
    3747          75 :   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
    3748          75 :   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
    3749          75 :   value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
    3750             :                            vtrue0, vfalse0, control);
    3751             : 
    3752             :   // Replace effect and control uses appropriately.
    3753         459 :   for (Edge edge : node->use_edges()) {
    3754         192 :     if (NodeProperties::IsControlEdge(edge)) {
    3755         114 :       if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
    3756           8 :         edge.from()->ReplaceUses(control);
    3757           8 :         edge.from()->Kill();
    3758             :       } else {
    3759             :         DCHECK_NE(IrOpcode::kIfException, edge.from()->opcode());
    3760         106 :         edge.UpdateTo(control);
    3761             :       }
    3762          78 :     } else if (NodeProperties::IsEffectEdge(edge)) {
    3763          75 :       edge.UpdateTo(effect);
    3764             :     }
    3765             :   }
    3766             : 
    3767          75 :   selector->DeferReplacement(node, value);
    3768          75 : }
    3769             : 
    3770        1554 : Node* SimplifiedLowering::Float64Round(Node* const node) {
    3771        1554 :   Node* const one = jsgraph()->Float64Constant(1.0);
    3772        1554 :   Node* const one_half = jsgraph()->Float64Constant(0.5);
    3773             :   Node* const input = node->InputAt(0);
    3774             : 
    3775             :   // Round up towards Infinity, and adjust if the difference exceeds 0.5.
    3776        3108 :   Node* result = graph()->NewNode(machine()->Float64RoundUp().placeholder(),
    3777             :                                   node->InputAt(0));
    3778        6216 :   return graph()->NewNode(
    3779             :       common()->Select(MachineRepresentation::kFloat64),
    3780             :       graph()->NewNode(
    3781             :           machine()->Float64LessThanOrEqual(),
    3782             :           graph()->NewNode(machine()->Float64Sub(), result, one_half), input),
    3783        1554 :       result, graph()->NewNode(machine()->Float64Sub(), result, one));
    3784             : }
    3785             : 
    3786          30 : Node* SimplifiedLowering::Float64Sign(Node* const node) {
    3787          30 :   Node* const minus_one = jsgraph()->Float64Constant(-1.0);
    3788          30 :   Node* const zero = jsgraph()->Float64Constant(0.0);
    3789          30 :   Node* const one = jsgraph()->Float64Constant(1.0);
    3790             : 
    3791             :   Node* const input = node->InputAt(0);
    3792             : 
    3793         120 :   return graph()->NewNode(
    3794             :       common()->Select(MachineRepresentation::kFloat64),
    3795             :       graph()->NewNode(machine()->Float64LessThan(), input, zero), minus_one,
    3796             :       graph()->NewNode(
    3797             :           common()->Select(MachineRepresentation::kFloat64),
    3798             :           graph()->NewNode(machine()->Float64LessThan(), zero, input), one,
    3799          30 :           input));
    3800             : }
    3801             : 
    3802          83 : Node* SimplifiedLowering::Int32Abs(Node* const node) {
    3803             :   Node* const input = node->InputAt(0);
    3804             : 
    3805             :   // Generate case for absolute integer value.
    3806             :   //
    3807             :   //    let sign = input >> 31 in
    3808             :   //    (input ^ sign) - sign
    3809             : 
    3810          83 :   Node* sign = graph()->NewNode(machine()->Word32Sar(), input,
    3811             :                                 jsgraph()->Int32Constant(31));
    3812         166 :   return graph()->NewNode(machine()->Int32Sub(),
    3813             :                           graph()->NewNode(machine()->Word32Xor(), input, sign),
    3814          83 :                           sign);
    3815             : }
    3816             : 
    3817        2999 : Node* SimplifiedLowering::Int32Div(Node* const node) {
    3818        2999 :   Int32BinopMatcher m(node);
    3819        2999 :   Node* const zero = jsgraph()->Int32Constant(0);
    3820        2999 :   Node* const minus_one = jsgraph()->Int32Constant(-1);
    3821             :   Node* const lhs = m.left().node();
    3822             :   Node* const rhs = m.right().node();
    3823             : 
    3824        2999 :   if (m.right().Is(-1)) {
    3825          30 :     return graph()->NewNode(machine()->Int32Sub(), zero, lhs);
    3826        2984 :   } else if (m.right().Is(0)) {
    3827             :     return rhs;
    3828        2984 :   } else if (machine()->Int32DivIsSafe() || m.right().HasValue()) {
    3829        4694 :     return graph()->NewNode(machine()->Int32Div(), lhs, rhs, graph()->start());
    3830             :   }
    3831             : 
    3832             :   // General case for signed integer division.
    3833             :   //
    3834             :   //    if 0 < rhs then
    3835             :   //      lhs / rhs
    3836             :   //    else
    3837             :   //      if rhs < -1 then
    3838             :   //        lhs / rhs
    3839             :   //      else if rhs == 0 then
    3840             :   //        0
    3841             :   //      else
    3842             :   //        0 - lhs
    3843             :   //
    3844             :   // Note: We do not use the Diamond helper class here, because it really hurts
    3845             :   // readability with nested diamonds.
    3846         637 :   const Operator* const merge_op = common()->Merge(2);
    3847             :   const Operator* const phi_op =
    3848         637 :       common()->Phi(MachineRepresentation::kWord32, 2);
    3849             : 
    3850         637 :   Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs);
    3851         637 :   Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0,
    3852             :                                    graph()->start());
    3853             : 
    3854         637 :   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
    3855         637 :   Node* true0 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true0);
    3856             : 
    3857         637 :   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
    3858             :   Node* false0;
    3859             :   {
    3860         637 :     Node* check1 = graph()->NewNode(machine()->Int32LessThan(), rhs, minus_one);
    3861         637 :     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
    3862             : 
    3863         637 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    3864         637 :     Node* true1 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true1);
    3865             : 
    3866         637 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    3867             :     Node* false1;
    3868             :     {
    3869         637 :       Node* check2 = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
    3870         637 :       Node* branch2 = graph()->NewNode(common()->Branch(), check2, if_false1);
    3871             : 
    3872         637 :       Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
    3873             :       Node* true2 = zero;
    3874             : 
    3875         637 :       Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
    3876         637 :       Node* false2 = graph()->NewNode(machine()->Int32Sub(), zero, lhs);
    3877             : 
    3878             :       if_false1 = graph()->NewNode(merge_op, if_true2, if_false2);
    3879             :       false1 = graph()->NewNode(phi_op, true2, false2, if_false1);
    3880             :     }
    3881             : 
    3882             :     if_false0 = graph()->NewNode(merge_op, if_true1, if_false1);
    3883             :     false0 = graph()->NewNode(phi_op, true1, false1, if_false0);
    3884             :   }
    3885             : 
    3886             :   Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
    3887         637 :   return graph()->NewNode(phi_op, true0, false0, merge0);
    3888             : }
    3889             : 
    3890        2417 : Node* SimplifiedLowering::Int32Mod(Node* const node) {
    3891        2417 :   Int32BinopMatcher m(node);
    3892        2417 :   Node* const zero = jsgraph()->Int32Constant(0);
    3893        2417 :   Node* const minus_one = jsgraph()->Int32Constant(-1);
    3894             :   Node* const lhs = m.left().node();
    3895             :   Node* const rhs = m.right().node();
    3896             : 
    3897        4826 :   if (m.right().Is(-1) || m.right().Is(0)) {
    3898             :     return zero;
    3899        2409 :   } else if (m.right().HasValue()) {
    3900        4796 :     return graph()->NewNode(machine()->Int32Mod(), lhs, rhs, graph()->start());
    3901             :   }
    3902             : 
    3903             :   // General case for signed integer modulus, with optimization for (unknown)
    3904             :   // power of 2 right hand side.
    3905             :   //
    3906             :   //   if 0 < rhs then
    3907             :   //     msk = rhs - 1
    3908             :   //     if rhs & msk != 0 then
    3909             :   //       lhs % rhs
    3910             :   //     else
    3911             :   //       if lhs < 0 then
    3912             :   //         -(-lhs & msk)
    3913             :   //       else
    3914             :   //         lhs & msk
    3915             :   //   else
    3916             :   //     if rhs < -1 then
    3917             :   //       lhs % rhs
    3918             :   //     else
    3919             :   //       zero
    3920             :   //
    3921             :   // Note: We do not use the Diamond helper class here, because it really hurts
    3922             :   // readability with nested diamonds.
    3923          11 :   const Operator* const merge_op = common()->Merge(2);
    3924             :   const Operator* const phi_op =
    3925          11 :       common()->Phi(MachineRepresentation::kWord32, 2);
    3926             : 
    3927          11 :   Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs);
    3928          11 :   Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0,
    3929             :                                    graph()->start());
    3930             : 
    3931          11 :   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
    3932             :   Node* true0;
    3933             :   {
    3934          11 :     Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one);
    3935             : 
    3936          11 :     Node* check1 = graph()->NewNode(machine()->Word32And(), rhs, msk);
    3937          11 :     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
    3938             : 
    3939          11 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    3940          11 :     Node* true1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1);
    3941             : 
    3942          11 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    3943             :     Node* false1;
    3944             :     {
    3945          11 :       Node* check2 = graph()->NewNode(machine()->Int32LessThan(), lhs, zero);
    3946          11 :       Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
    3947             :                                        check2, if_false1);
    3948             : 
    3949          11 :       Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
    3950          33 :       Node* true2 = graph()->NewNode(
    3951             :           machine()->Int32Sub(), zero,
    3952             :           graph()->NewNode(machine()->Word32And(),
    3953             :                            graph()->NewNode(machine()->Int32Sub(), zero, lhs),
    3954             :                            msk));
    3955             : 
    3956          11 :       Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
    3957          11 :       Node* false2 = graph()->NewNode(machine()->Word32And(), lhs, msk);
    3958             : 
    3959             :       if_false1 = graph()->NewNode(merge_op, if_true2, if_false2);
    3960             :       false1 = graph()->NewNode(phi_op, true2, false2, if_false1);
    3961             :     }
    3962             : 
    3963             :     if_true0 = graph()->NewNode(merge_op, if_true1, if_false1);
    3964             :     true0 = graph()->NewNode(phi_op, true1, false1, if_true0);
    3965             :   }
    3966             : 
    3967          11 :   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
    3968             :   Node* false0;
    3969             :   {
    3970          11 :     Node* check1 = graph()->NewNode(machine()->Int32LessThan(), rhs, minus_one);
    3971          11 :     Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
    3972             :                                      check1, if_false0);
    3973             : 
    3974          11 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    3975          11 :     Node* true1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1);
    3976             : 
    3977          11 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    3978             :     Node* false1 = zero;
    3979             : 
    3980             :     if_false0 = graph()->NewNode(merge_op, if_true1, if_false1);
    3981             :     false0 = graph()->NewNode(phi_op, true1, false1, if_false0);
    3982             :   }
    3983             : 
    3984             :   Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
    3985          11 :   return graph()->NewNode(phi_op, true0, false0, merge0);
    3986             : }
    3987             : 
    3988           7 : Node* SimplifiedLowering::Int32Sign(Node* const node) {
    3989           7 :   Node* const minus_one = jsgraph()->Int32Constant(-1);
    3990           7 :   Node* const zero = jsgraph()->Int32Constant(0);
    3991           7 :   Node* const one = jsgraph()->Int32Constant(1);
    3992             : 
    3993             :   Node* const input = node->InputAt(0);
    3994             : 
    3995          28 :   return graph()->NewNode(
    3996             :       common()->Select(MachineRepresentation::kWord32),
    3997             :       graph()->NewNode(machine()->Int32LessThan(), input, zero), minus_one,
    3998             :       graph()->NewNode(
    3999             :           common()->Select(MachineRepresentation::kWord32),
    4000             :           graph()->NewNode(machine()->Int32LessThan(), zero, input), one,
    4001           7 :           zero));
    4002             : }
    4003             : 
    4004         233 : Node* SimplifiedLowering::Uint32Div(Node* const node) {
    4005         233 :   Uint32BinopMatcher m(node);
    4006         233 :   Node* const zero = jsgraph()->Uint32Constant(0);
    4007             :   Node* const lhs = m.left().node();
    4008             :   Node* const rhs = m.right().node();
    4009             : 
    4010         233 :   if (m.right().Is(0)) {
    4011             :     return zero;
    4012         226 :   } else if (machine()->Uint32DivIsSafe() || m.right().HasValue()) {
    4013         384 :     return graph()->NewNode(machine()->Uint32Div(), lhs, rhs, graph()->start());
    4014             :   }
    4015             : 
    4016          34 :   Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
    4017          34 :   Diamond d(graph(), common(), check, BranchHint::kFalse);
    4018          34 :   Node* div = graph()->NewNode(machine()->Uint32Div(), lhs, rhs, d.if_false);
    4019          34 :   return d.Phi(MachineRepresentation::kWord32, zero, div);
    4020             : }
    4021             : 
    4022         216 : Node* SimplifiedLowering::Uint32Mod(Node* const node) {
    4023         216 :   Uint32BinopMatcher m(node);
    4024         216 :   Node* const minus_one = jsgraph()->Int32Constant(-1);
    4025         216 :   Node* const zero = jsgraph()->Uint32Constant(0);
    4026             :   Node* const lhs = m.left().node();
    4027             :   Node* const rhs = m.right().node();
    4028             : 
    4029         216 :   if (m.right().Is(0)) {
    4030             :     return zero;
    4031         216 :   } else if (m.right().HasValue()) {
    4032         386 :     return graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, graph()->start());
    4033             :   }
    4034             : 
    4035             :   // General case for unsigned integer modulus, with optimization for (unknown)
    4036             :   // power of 2 right hand side.
    4037             :   //
    4038             :   //   if rhs == 0 then
    4039             :   //     zero
    4040             :   //   else
    4041             :   //     msk = rhs - 1
    4042             :   //     if rhs & msk != 0 then
    4043             :   //       lhs % rhs
    4044             :   //     else
    4045             :   //       lhs & msk
    4046             :   //
    4047             :   // Note: We do not use the Diamond helper class here, because it really hurts
    4048             :   // readability with nested diamonds.
    4049          23 :   const Operator* const merge_op = common()->Merge(2);
    4050             :   const Operator* const phi_op =
    4051          23 :       common()->Phi(MachineRepresentation::kWord32, 2);
    4052             : 
    4053          23 :   Node* check0 = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
    4054          23 :   Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kFalse), check0,
    4055             :                                    graph()->start());
    4056             : 
    4057          23 :   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
    4058             :   Node* true0 = zero;
    4059             : 
    4060          23 :   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
    4061             :   Node* false0;
    4062             :   {
    4063          23 :     Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one);
    4064             : 
    4065          23 :     Node* check1 = graph()->NewNode(machine()->Word32And(), rhs, msk);
    4066          23 :     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
    4067             : 
    4068          23 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    4069          23 :     Node* true1 = graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, if_true1);
    4070             : 
    4071          23 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    4072          23 :     Node* false1 = graph()->NewNode(machine()->Word32And(), lhs, msk);
    4073             : 
    4074             :     if_false0 = graph()->NewNode(merge_op, if_true1, if_false1);
    4075             :     false0 = graph()->NewNode(phi_op, true1, false1, if_false0);
    4076             :   }
    4077             : 
    4078             :   Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
    4079          23 :   return graph()->NewNode(phi_op, true0, false0, merge0);
    4080             : }
    4081             : 
    4082        2356 : void SimplifiedLowering::DoMax(Node* node, Operator const* op,
    4083             :                                MachineRepresentation rep) {
    4084             :   Node* const lhs = node->InputAt(0);
    4085             :   Node* const rhs = node->InputAt(1);
    4086             : 
    4087        2356 :   node->ReplaceInput(0, graph()->NewNode(op, lhs, rhs));
    4088             :   DCHECK_EQ(rhs, node->InputAt(1));
    4089        2356 :   node->AppendInput(graph()->zone(), lhs);
    4090        2356 :   NodeProperties::ChangeOp(node, common()->Select(rep));
    4091        2356 : }
    4092             : 
    4093        3135 : void SimplifiedLowering::DoMin(Node* node, Operator const* op,
    4094             :                                MachineRepresentation rep) {
    4095             :   Node* const lhs = node->InputAt(0);
    4096             :   Node* const rhs = node->InputAt(1);
    4097             : 
    4098        3135 :   node->InsertInput(graph()->zone(), 0, graph()->NewNode(op, lhs, rhs));
    4099             :   DCHECK_EQ(lhs, node->InputAt(1));
    4100             :   DCHECK_EQ(rhs, node->InputAt(2));
    4101        3135 :   NodeProperties::ChangeOp(node, common()->Select(rep));
    4102        3135 : }
    4103             : 
    4104         149 : void SimplifiedLowering::DoIntegral32ToBit(Node* node) {
    4105             :   Node* const input = node->InputAt(0);
    4106         149 :   Node* const zero = jsgraph()->Int32Constant(0);
    4107         149 :   Operator const* const op = machine()->Word32Equal();
    4108             : 
    4109         149 :   node->ReplaceInput(0, graph()->NewNode(op, input, zero));
    4110         149 :   node->AppendInput(graph()->zone(), zero);
    4111         149 :   NodeProperties::ChangeOp(node, op);
    4112         149 : }
    4113             : 
    4114           0 : void SimplifiedLowering::DoOrderedNumberToBit(Node* node) {
    4115             :   Node* const input = node->InputAt(0);
    4116             : 
    4117           0 :   node->ReplaceInput(0, graph()->NewNode(machine()->Float64Equal(), input,
    4118           0 :                                          jsgraph()->Float64Constant(0.0)));
    4119           0 :   node->AppendInput(graph()->zone(), jsgraph()->Int32Constant(0));
    4120           0 :   NodeProperties::ChangeOp(node, machine()->Word32Equal());
    4121           0 : }
    4122             : 
    4123          32 : void SimplifiedLowering::DoNumberToBit(Node* node) {
    4124             :   Node* const input = node->InputAt(0);
    4125             : 
    4126          32 :   node->ReplaceInput(0, jsgraph()->Float64Constant(0.0));
    4127          32 :   node->AppendInput(graph()->zone(),
    4128          32 :                     graph()->NewNode(machine()->Float64Abs(), input));
    4129          32 :   NodeProperties::ChangeOp(node, machine()->Float64LessThan());
    4130          32 : }
    4131             : 
    4132          21 : void SimplifiedLowering::DoIntegerToUint8Clamped(Node* node) {
    4133             :   Node* const input = node->InputAt(0);
    4134          21 :   Node* const min = jsgraph()->Float64Constant(0.0);
    4135          21 :   Node* const max = jsgraph()->Float64Constant(255.0);
    4136             : 
    4137          21 :   node->ReplaceInput(
    4138          21 :       0, graph()->NewNode(machine()->Float64LessThan(), min, input));
    4139          42 :   node->AppendInput(
    4140             :       graph()->zone(),
    4141             :       graph()->NewNode(
    4142             :           common()->Select(MachineRepresentation::kFloat64),
    4143             :           graph()->NewNode(machine()->Float64LessThan(), input, max), input,
    4144          21 :           max));
    4145          21 :   node->AppendInput(graph()->zone(), min);
    4146          21 :   NodeProperties::ChangeOp(node,
    4147          21 :                            common()->Select(MachineRepresentation::kFloat64));
    4148          21 : }
    4149             : 
    4150         294 : void SimplifiedLowering::DoNumberToUint8Clamped(Node* node) {
    4151             :   Node* const input = node->InputAt(0);
    4152         294 :   Node* const min = jsgraph()->Float64Constant(0.0);
    4153         294 :   Node* const max = jsgraph()->Float64Constant(255.0);
    4154             : 
    4155        1176 :   node->ReplaceInput(
    4156             :       0, graph()->NewNode(
    4157             :              common()->Select(MachineRepresentation::kFloat64),
    4158             :              graph()->NewNode(machine()->Float64LessThan(), min, input),
    4159             :              graph()->NewNode(
    4160             :                  common()->Select(MachineRepresentation::kFloat64),
    4161             :                  graph()->NewNode(machine()->Float64LessThan(), input, max),
    4162             :                  input, max),
    4163         294 :              min));
    4164             :   NodeProperties::ChangeOp(node,
    4165         294 :                            machine()->Float64RoundTiesEven().placeholder());
    4166         294 : }
    4167             : 
    4168          64 : void SimplifiedLowering::DoSigned32ToUint8Clamped(Node* node) {
    4169             :   Node* const input = node->InputAt(0);
    4170          64 :   Node* const min = jsgraph()->Int32Constant(0);
    4171          64 :   Node* const max = jsgraph()->Int32Constant(255);
    4172             : 
    4173          64 :   node->ReplaceInput(
    4174          64 :       0, graph()->NewNode(machine()->Int32LessThanOrEqual(), input, max));
    4175         128 :   node->AppendInput(
    4176             :       graph()->zone(),
    4177             :       graph()->NewNode(common()->Select(MachineRepresentation::kWord32),
    4178             :                        graph()->NewNode(machine()->Int32LessThan(), input, min),
    4179          64 :                        min, input));
    4180          64 :   node->AppendInput(graph()->zone(), max);
    4181          64 :   NodeProperties::ChangeOp(node,
    4182          64 :                            common()->Select(MachineRepresentation::kWord32));
    4183          64 : }
    4184             : 
    4185          72 : void SimplifiedLowering::DoUnsigned32ToUint8Clamped(Node* node) {
    4186             :   Node* const input = node->InputAt(0);
    4187          72 :   Node* const max = jsgraph()->Uint32Constant(255u);
    4188             : 
    4189          72 :   node->ReplaceInput(
    4190          72 :       0, graph()->NewNode(machine()->Uint32LessThanOrEqual(), input, max));
    4191          72 :   node->AppendInput(graph()->zone(), input);
    4192          72 :   node->AppendInput(graph()->zone(), max);
    4193          72 :   NodeProperties::ChangeOp(node,
    4194          72 :                            common()->Select(MachineRepresentation::kWord32));
    4195          72 : }
    4196             : 
    4197        1424 : Node* SimplifiedLowering::ToNumberCode() {
    4198        1424 :   if (!to_number_code_.is_set()) {
    4199        1424 :     Callable callable = Builtins::CallableFor(isolate(), Builtins::kToNumber);
    4200        2848 :     to_number_code_.set(jsgraph()->HeapConstant(callable.code()));
    4201             :   }
    4202        1424 :   return to_number_code_.get();
    4203             : }
    4204             : 
    4205          64 : Node* SimplifiedLowering::ToNumberConvertBigIntCode() {
    4206          64 :   if (!to_number_convert_big_int_code_.is_set()) {
    4207             :     Callable callable =
    4208          64 :         Builtins::CallableFor(isolate(), Builtins::kToNumberConvertBigInt);
    4209         128 :     to_number_convert_big_int_code_.set(
    4210             :         jsgraph()->HeapConstant(callable.code()));
    4211             :   }
    4212          64 :   return to_number_convert_big_int_code_.get();
    4213             : }
    4214             : 
    4215           0 : Node* SimplifiedLowering::ToNumericCode() {
    4216           0 :   if (!to_numeric_code_.is_set()) {
    4217           0 :     Callable callable = Builtins::CallableFor(isolate(), Builtins::kToNumeric);
    4218           0 :     to_numeric_code_.set(jsgraph()->HeapConstant(callable.code()));
    4219             :   }
    4220           0 :   return to_numeric_code_.get();
    4221             : }
    4222             : 
    4223        1424 : Operator const* SimplifiedLowering::ToNumberOperator() {
    4224        1424 :   if (!to_number_operator_.is_set()) {
    4225        1424 :     Callable callable = Builtins::CallableFor(isolate(), Builtins::kToNumber);
    4226             :     CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
    4227        1424 :     auto call_descriptor = Linkage::GetStubCallDescriptor(
    4228        1424 :         graph()->zone(), callable.descriptor(),
    4229             :         callable.descriptor().GetStackParameterCount(), flags,
    4230        1424 :         Operator::kNoProperties);
    4231        1424 :     to_number_operator_.set(common()->Call(call_descriptor));
    4232             :   }
    4233        1424 :   return to_number_operator_.get();
    4234             : }
    4235             : 
    4236           0 : Operator const* SimplifiedLowering::ToNumberConvertBigIntOperator() {
    4237           0 :   if (!to_number_convert_big_int_operator_.is_set()) {
    4238             :     Callable callable =
    4239           0 :         Builtins::CallableFor(isolate(), Builtins::kToNumberConvertBigInt);
    4240             :     CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
    4241           0 :     auto call_descriptor = Linkage::GetStubCallDescriptor(
    4242           0 :         graph()->zone(), callable.descriptor(),
    4243             :         callable.descriptor().GetStackParameterCount(), flags,
    4244           0 :         Operator::kNoProperties);
    4245           0 :     to_number_convert_big_int_operator_.set(common()->Call(call_descriptor));
    4246             :   }
    4247           0 :   return to_number_convert_big_int_operator_.get();
    4248             : }
    4249             : 
    4250          64 : Operator const* SimplifiedLowering::ToNumericOperator() {
    4251          64 :   if (!to_numeric_operator_.is_set()) {
    4252          64 :     Callable callable = Builtins::CallableFor(isolate(), Builtins::kToNumeric);
    4253             :     CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
    4254          64 :     auto call_descriptor = Linkage::GetStubCallDescriptor(
    4255          64 :         graph()->zone(), callable.descriptor(),
    4256             :         callable.descriptor().GetStackParameterCount(), flags,
    4257          64 :         Operator::kNoProperties);
    4258          64 :     to_numeric_operator_.set(common()->Call(call_descriptor));
    4259             :   }
    4260          64 :   return to_numeric_operator_.get();
    4261             : }
    4262             : 
    4263             : #undef TRACE
    4264             : 
    4265             : }  // namespace compiler
    4266             : }  // namespace internal
    4267      122036 : }  // namespace v8

Generated by: LCOV version 1.10