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