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

Generated by: LCOV version 1.10