11cb0ef41Sopenharmony_ci// Copyright 2014 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/compiler/simplified-lowering.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include <limits>
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci#include "include/v8-fast-api-calls.h"
101cb0ef41Sopenharmony_ci#include "src/base/bits.h"
111cb0ef41Sopenharmony_ci#include "src/base/small-vector.h"
121cb0ef41Sopenharmony_ci#include "src/codegen/code-factory.h"
131cb0ef41Sopenharmony_ci#include "src/codegen/machine-type.h"
141cb0ef41Sopenharmony_ci#include "src/codegen/tick-counter.h"
151cb0ef41Sopenharmony_ci#include "src/compiler/access-builder.h"
161cb0ef41Sopenharmony_ci#include "src/compiler/common-operator.h"
171cb0ef41Sopenharmony_ci#include "src/compiler/compiler-source-position-table.h"
181cb0ef41Sopenharmony_ci#include "src/compiler/diamond.h"
191cb0ef41Sopenharmony_ci#include "src/compiler/graph-visualizer.h"
201cb0ef41Sopenharmony_ci#include "src/compiler/js-heap-broker.h"
211cb0ef41Sopenharmony_ci#include "src/compiler/linkage.h"
221cb0ef41Sopenharmony_ci#include "src/compiler/node-matchers.h"
231cb0ef41Sopenharmony_ci#include "src/compiler/node-observer.h"
241cb0ef41Sopenharmony_ci#include "src/compiler/node-origin-table.h"
251cb0ef41Sopenharmony_ci#include "src/compiler/operation-typer.h"
261cb0ef41Sopenharmony_ci#include "src/compiler/operator-properties.h"
271cb0ef41Sopenharmony_ci#include "src/compiler/representation-change.h"
281cb0ef41Sopenharmony_ci#include "src/compiler/simplified-lowering-verifier.h"
291cb0ef41Sopenharmony_ci#include "src/compiler/simplified-operator.h"
301cb0ef41Sopenharmony_ci#include "src/compiler/type-cache.h"
311cb0ef41Sopenharmony_ci#include "src/numbers/conversions-inl.h"
321cb0ef41Sopenharmony_ci#include "src/objects/objects.h"
331cb0ef41Sopenharmony_ci#include "src/utils/address-map.h"
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
361cb0ef41Sopenharmony_ci#include "src/wasm/value-type.h"
371cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_cinamespace v8 {
401cb0ef41Sopenharmony_cinamespace internal {
411cb0ef41Sopenharmony_cinamespace compiler {
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci// Macro for outputting trace information from representation inference.
441cb0ef41Sopenharmony_ci#define TRACE(...)                                      \
451cb0ef41Sopenharmony_ci  do {                                                  \
461cb0ef41Sopenharmony_ci    if (FLAG_trace_representation) PrintF(__VA_ARGS__); \
471cb0ef41Sopenharmony_ci  } while (false)
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ciconst char* kSimplifiedLoweringReducerName = "SimplifiedLowering";
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci// Representation selection and lowering of {Simplified} operators to machine
521cb0ef41Sopenharmony_ci// operators are interwined. We use a fixpoint calculation to compute both the
531cb0ef41Sopenharmony_ci// output representation and the best possible lowering for {Simplified} nodes.
541cb0ef41Sopenharmony_ci// Representation change insertion ensures that all values are in the correct
551cb0ef41Sopenharmony_ci// machine representation after this phase, as dictated by the machine
561cb0ef41Sopenharmony_ci// operators themselves.
571cb0ef41Sopenharmony_cienum Phase {
581cb0ef41Sopenharmony_ci  // 1.) PROPAGATE: Traverse the graph from the end, pushing usage information
591cb0ef41Sopenharmony_ci  //     backwards from uses to definitions, around cycles in phis, according
601cb0ef41Sopenharmony_ci  //     to local rules for each operator.
611cb0ef41Sopenharmony_ci  //     During this phase, the usage information for a node determines the best
621cb0ef41Sopenharmony_ci  //     possible lowering for each operator so far, and that in turn determines
631cb0ef41Sopenharmony_ci  //     the output representation.
641cb0ef41Sopenharmony_ci  //     Therefore, to be correct, this phase must iterate to a fixpoint before
651cb0ef41Sopenharmony_ci  //     the next phase can begin.
661cb0ef41Sopenharmony_ci  PROPAGATE,
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ci  // 2.) RETYPE: Propagate types from type feedback forwards.
691cb0ef41Sopenharmony_ci  RETYPE,
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_ci  // 3.) LOWER: perform lowering for all {Simplified} nodes by replacing some
721cb0ef41Sopenharmony_ci  //     operators for some nodes, expanding some nodes to multiple nodes, or
731cb0ef41Sopenharmony_ci  //     removing some (redundant) nodes.
741cb0ef41Sopenharmony_ci  //     During this phase, use the {RepresentationChanger} to insert
751cb0ef41Sopenharmony_ci  //     representation changes between uses that demand a particular
761cb0ef41Sopenharmony_ci  //     representation and nodes that produce a different representation.
771cb0ef41Sopenharmony_ci  LOWER
781cb0ef41Sopenharmony_ci};
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_cinamespace {
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_ciMachineRepresentation MachineRepresentationFromArrayType(
831cb0ef41Sopenharmony_ci    ExternalArrayType array_type) {
841cb0ef41Sopenharmony_ci  switch (array_type) {
851cb0ef41Sopenharmony_ci    case kExternalUint8Array:
861cb0ef41Sopenharmony_ci    case kExternalUint8ClampedArray:
871cb0ef41Sopenharmony_ci    case kExternalInt8Array:
881cb0ef41Sopenharmony_ci      return MachineRepresentation::kWord8;
891cb0ef41Sopenharmony_ci    case kExternalUint16Array:
901cb0ef41Sopenharmony_ci    case kExternalInt16Array:
911cb0ef41Sopenharmony_ci      return MachineRepresentation::kWord16;
921cb0ef41Sopenharmony_ci    case kExternalUint32Array:
931cb0ef41Sopenharmony_ci    case kExternalInt32Array:
941cb0ef41Sopenharmony_ci      return MachineRepresentation::kWord32;
951cb0ef41Sopenharmony_ci    case kExternalFloat32Array:
961cb0ef41Sopenharmony_ci      return MachineRepresentation::kFloat32;
971cb0ef41Sopenharmony_ci    case kExternalFloat64Array:
981cb0ef41Sopenharmony_ci      return MachineRepresentation::kFloat64;
991cb0ef41Sopenharmony_ci    case kExternalBigInt64Array:
1001cb0ef41Sopenharmony_ci    case kExternalBigUint64Array:
1011cb0ef41Sopenharmony_ci      UNIMPLEMENTED();
1021cb0ef41Sopenharmony_ci  }
1031cb0ef41Sopenharmony_ci  UNREACHABLE();
1041cb0ef41Sopenharmony_ci}
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ciUseInfo CheckedUseInfoAsWord32FromHint(
1071cb0ef41Sopenharmony_ci    NumberOperationHint hint, IdentifyZeros identify_zeros = kDistinguishZeros,
1081cb0ef41Sopenharmony_ci    const FeedbackSource& feedback = FeedbackSource()) {
1091cb0ef41Sopenharmony_ci  switch (hint) {
1101cb0ef41Sopenharmony_ci    case NumberOperationHint::kSignedSmall:
1111cb0ef41Sopenharmony_ci    case NumberOperationHint::kSignedSmallInputs:
1121cb0ef41Sopenharmony_ci      return UseInfo::CheckedSignedSmallAsWord32(identify_zeros, feedback);
1131cb0ef41Sopenharmony_ci    case NumberOperationHint::kNumber:
1141cb0ef41Sopenharmony_ci      DCHECK_EQ(identify_zeros, kIdentifyZeros);
1151cb0ef41Sopenharmony_ci      return UseInfo::CheckedNumberAsWord32(feedback);
1161cb0ef41Sopenharmony_ci    case NumberOperationHint::kNumberOrBoolean:
1171cb0ef41Sopenharmony_ci      // Not used currently.
1181cb0ef41Sopenharmony_ci      UNREACHABLE();
1191cb0ef41Sopenharmony_ci    case NumberOperationHint::kNumberOrOddball:
1201cb0ef41Sopenharmony_ci      DCHECK_EQ(identify_zeros, kIdentifyZeros);
1211cb0ef41Sopenharmony_ci      return UseInfo::CheckedNumberOrOddballAsWord32(feedback);
1221cb0ef41Sopenharmony_ci  }
1231cb0ef41Sopenharmony_ci  UNREACHABLE();
1241cb0ef41Sopenharmony_ci}
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ciUseInfo CheckedUseInfoAsFloat64FromHint(
1271cb0ef41Sopenharmony_ci    NumberOperationHint hint, const FeedbackSource& feedback,
1281cb0ef41Sopenharmony_ci    IdentifyZeros identify_zeros = kDistinguishZeros) {
1291cb0ef41Sopenharmony_ci  switch (hint) {
1301cb0ef41Sopenharmony_ci    case NumberOperationHint::kSignedSmall:
1311cb0ef41Sopenharmony_ci    case NumberOperationHint::kSignedSmallInputs:
1321cb0ef41Sopenharmony_ci      // Not used currently.
1331cb0ef41Sopenharmony_ci      UNREACHABLE();
1341cb0ef41Sopenharmony_ci    case NumberOperationHint::kNumber:
1351cb0ef41Sopenharmony_ci      return UseInfo::CheckedNumberAsFloat64(identify_zeros, feedback);
1361cb0ef41Sopenharmony_ci    case NumberOperationHint::kNumberOrBoolean:
1371cb0ef41Sopenharmony_ci      return UseInfo::CheckedNumberOrBooleanAsFloat64(identify_zeros, feedback);
1381cb0ef41Sopenharmony_ci    case NumberOperationHint::kNumberOrOddball:
1391cb0ef41Sopenharmony_ci      return UseInfo::CheckedNumberOrOddballAsFloat64(identify_zeros, feedback);
1401cb0ef41Sopenharmony_ci  }
1411cb0ef41Sopenharmony_ci  UNREACHABLE();
1421cb0ef41Sopenharmony_ci}
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_ciUseInfo TruncatingUseInfoFromRepresentation(MachineRepresentation rep) {
1451cb0ef41Sopenharmony_ci  switch (rep) {
1461cb0ef41Sopenharmony_ci    case MachineRepresentation::kTaggedSigned:
1471cb0ef41Sopenharmony_ci      return UseInfo::TaggedSigned();
1481cb0ef41Sopenharmony_ci    case MachineRepresentation::kTaggedPointer:
1491cb0ef41Sopenharmony_ci    case MachineRepresentation::kTagged:
1501cb0ef41Sopenharmony_ci    case MachineRepresentation::kMapWord:
1511cb0ef41Sopenharmony_ci      return UseInfo::AnyTagged();
1521cb0ef41Sopenharmony_ci    case MachineRepresentation::kFloat64:
1531cb0ef41Sopenharmony_ci      return UseInfo::TruncatingFloat64();
1541cb0ef41Sopenharmony_ci    case MachineRepresentation::kFloat32:
1551cb0ef41Sopenharmony_ci      return UseInfo::Float32();
1561cb0ef41Sopenharmony_ci    case MachineRepresentation::kWord8:
1571cb0ef41Sopenharmony_ci    case MachineRepresentation::kWord16:
1581cb0ef41Sopenharmony_ci    case MachineRepresentation::kWord32:
1591cb0ef41Sopenharmony_ci      return UseInfo::TruncatingWord32();
1601cb0ef41Sopenharmony_ci    case MachineRepresentation::kWord64:
1611cb0ef41Sopenharmony_ci      return UseInfo::Word64();
1621cb0ef41Sopenharmony_ci    case MachineRepresentation::kBit:
1631cb0ef41Sopenharmony_ci      return UseInfo::Bool();
1641cb0ef41Sopenharmony_ci    case MachineRepresentation::kCompressedPointer:
1651cb0ef41Sopenharmony_ci    case MachineRepresentation::kCompressed:
1661cb0ef41Sopenharmony_ci    case MachineRepresentation::kSandboxedPointer:
1671cb0ef41Sopenharmony_ci    case MachineRepresentation::kSimd128:
1681cb0ef41Sopenharmony_ci    case MachineRepresentation::kNone:
1691cb0ef41Sopenharmony_ci      break;
1701cb0ef41Sopenharmony_ci  }
1711cb0ef41Sopenharmony_ci  UNREACHABLE();
1721cb0ef41Sopenharmony_ci}
1731cb0ef41Sopenharmony_ci
1741cb0ef41Sopenharmony_ciUseInfo UseInfoForBasePointer(const FieldAccess& access) {
1751cb0ef41Sopenharmony_ci  return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::Word();
1761cb0ef41Sopenharmony_ci}
1771cb0ef41Sopenharmony_ci
1781cb0ef41Sopenharmony_ciUseInfo UseInfoForBasePointer(const ElementAccess& access) {
1791cb0ef41Sopenharmony_ci  return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::Word();
1801cb0ef41Sopenharmony_ci}
1811cb0ef41Sopenharmony_ci
1821cb0ef41Sopenharmony_civoid ReplaceEffectControlUses(Node* node, Node* effect, Node* control) {
1831cb0ef41Sopenharmony_ci  for (Edge edge : node->use_edges()) {
1841cb0ef41Sopenharmony_ci    if (NodeProperties::IsControlEdge(edge)) {
1851cb0ef41Sopenharmony_ci      edge.UpdateTo(control);
1861cb0ef41Sopenharmony_ci    } else if (NodeProperties::IsEffectEdge(edge)) {
1871cb0ef41Sopenharmony_ci      edge.UpdateTo(effect);
1881cb0ef41Sopenharmony_ci    } else {
1891cb0ef41Sopenharmony_ci      DCHECK(NodeProperties::IsValueEdge(edge) ||
1901cb0ef41Sopenharmony_ci             NodeProperties::IsContextEdge(edge));
1911cb0ef41Sopenharmony_ci    }
1921cb0ef41Sopenharmony_ci  }
1931cb0ef41Sopenharmony_ci}
1941cb0ef41Sopenharmony_ci
1951cb0ef41Sopenharmony_cibool CanOverflowSigned32(const Operator* op, Type left, Type right,
1961cb0ef41Sopenharmony_ci                         TypeCache const* type_cache, Zone* type_zone) {
1971cb0ef41Sopenharmony_ci  // We assume the inputs are checked Signed32 (or known statically to be
1981cb0ef41Sopenharmony_ci  // Signed32). Technically, the inputs could also be minus zero, which we treat
1991cb0ef41Sopenharmony_ci  // as 0 for the purpose of this function.
2001cb0ef41Sopenharmony_ci  if (left.Maybe(Type::MinusZero())) {
2011cb0ef41Sopenharmony_ci    left = Type::Union(left, type_cache->kSingletonZero, type_zone);
2021cb0ef41Sopenharmony_ci  }
2031cb0ef41Sopenharmony_ci  if (right.Maybe(Type::MinusZero())) {
2041cb0ef41Sopenharmony_ci    right = Type::Union(right, type_cache->kSingletonZero, type_zone);
2051cb0ef41Sopenharmony_ci  }
2061cb0ef41Sopenharmony_ci  left = Type::Intersect(left, Type::Signed32(), type_zone);
2071cb0ef41Sopenharmony_ci  right = Type::Intersect(right, Type::Signed32(), type_zone);
2081cb0ef41Sopenharmony_ci  if (left.IsNone() || right.IsNone()) return false;
2091cb0ef41Sopenharmony_ci  switch (op->opcode()) {
2101cb0ef41Sopenharmony_ci    case IrOpcode::kSpeculativeSafeIntegerAdd:
2111cb0ef41Sopenharmony_ci      return (left.Max() + right.Max() > kMaxInt) ||
2121cb0ef41Sopenharmony_ci             (left.Min() + right.Min() < kMinInt);
2131cb0ef41Sopenharmony_ci
2141cb0ef41Sopenharmony_ci    case IrOpcode::kSpeculativeSafeIntegerSubtract:
2151cb0ef41Sopenharmony_ci      return (left.Max() - right.Min() > kMaxInt) ||
2161cb0ef41Sopenharmony_ci             (left.Min() - right.Max() < kMinInt);
2171cb0ef41Sopenharmony_ci
2181cb0ef41Sopenharmony_ci    default:
2191cb0ef41Sopenharmony_ci      UNREACHABLE();
2201cb0ef41Sopenharmony_ci  }
2211cb0ef41Sopenharmony_ci}
2221cb0ef41Sopenharmony_ci
2231cb0ef41Sopenharmony_cibool IsSomePositiveOrderedNumber(Type type) {
2241cb0ef41Sopenharmony_ci  return type.Is(Type::OrderedNumber()) && (type.IsNone() || type.Min() > 0);
2251cb0ef41Sopenharmony_ci}
2261cb0ef41Sopenharmony_ci
2271cb0ef41Sopenharmony_ciclass JSONGraphWriterWithVerifierTypes : public JSONGraphWriter {
2281cb0ef41Sopenharmony_ci public:
2291cb0ef41Sopenharmony_ci  JSONGraphWriterWithVerifierTypes(std::ostream& os, const Graph* graph,
2301cb0ef41Sopenharmony_ci                                   const SourcePositionTable* positions,
2311cb0ef41Sopenharmony_ci                                   const NodeOriginTable* origins,
2321cb0ef41Sopenharmony_ci                                   SimplifiedLoweringVerifier* verifier)
2331cb0ef41Sopenharmony_ci      : JSONGraphWriter(os, graph, positions, origins), verifier_(verifier) {}
2341cb0ef41Sopenharmony_ci
2351cb0ef41Sopenharmony_ci protected:
2361cb0ef41Sopenharmony_ci  base::Optional<Type> GetType(Node* node) override {
2371cb0ef41Sopenharmony_ci    return verifier_->GetType(node);
2381cb0ef41Sopenharmony_ci  }
2391cb0ef41Sopenharmony_ci
2401cb0ef41Sopenharmony_ci private:
2411cb0ef41Sopenharmony_ci  SimplifiedLoweringVerifier* verifier_;
2421cb0ef41Sopenharmony_ci};
2431cb0ef41Sopenharmony_ci
2441cb0ef41Sopenharmony_ci}  // namespace
2451cb0ef41Sopenharmony_ci
2461cb0ef41Sopenharmony_ci#ifdef DEBUG
2471cb0ef41Sopenharmony_ci// Helpers for monotonicity checking.
2481cb0ef41Sopenharmony_ciclass InputUseInfos {
2491cb0ef41Sopenharmony_ci public:
2501cb0ef41Sopenharmony_ci  explicit InputUseInfos(Zone* zone) : input_use_infos_(zone) {}
2511cb0ef41Sopenharmony_ci
2521cb0ef41Sopenharmony_ci  void SetAndCheckInput(Node* node, int index, UseInfo use_info) {
2531cb0ef41Sopenharmony_ci    if (input_use_infos_.empty()) {
2541cb0ef41Sopenharmony_ci      input_use_infos_.resize(node->InputCount(), UseInfo::None());
2551cb0ef41Sopenharmony_ci    }
2561cb0ef41Sopenharmony_ci    // Check that the new use informatin is a super-type of the old
2571cb0ef41Sopenharmony_ci    // one.
2581cb0ef41Sopenharmony_ci    DCHECK(IsUseLessGeneral(input_use_infos_[index], use_info));
2591cb0ef41Sopenharmony_ci    input_use_infos_[index] = use_info;
2601cb0ef41Sopenharmony_ci  }
2611cb0ef41Sopenharmony_ci
2621cb0ef41Sopenharmony_ci private:
2631cb0ef41Sopenharmony_ci  ZoneVector<UseInfo> input_use_infos_;
2641cb0ef41Sopenharmony_ci
2651cb0ef41Sopenharmony_ci  static bool IsUseLessGeneral(UseInfo use1, UseInfo use2) {
2661cb0ef41Sopenharmony_ci    return use1.truncation().IsLessGeneralThan(use2.truncation());
2671cb0ef41Sopenharmony_ci  }
2681cb0ef41Sopenharmony_ci};
2691cb0ef41Sopenharmony_ci
2701cb0ef41Sopenharmony_ci#endif  // DEBUG
2711cb0ef41Sopenharmony_ci
2721cb0ef41Sopenharmony_ciclass RepresentationSelector {
2731cb0ef41Sopenharmony_ci  // The purpose of this nested class is to hide method
2741cb0ef41Sopenharmony_ci  // v8::internal::compiler::NodeProperties::ChangeOp which should not be
2751cb0ef41Sopenharmony_ci  // directly used by code in RepresentationSelector and SimplifiedLowering.
2761cb0ef41Sopenharmony_ci  // RepresentationSelector code should call RepresentationSelector::ChangeOp in
2771cb0ef41Sopenharmony_ci  // place of NodeProperties::ChangeOp, in order to notify the changes to a
2781cb0ef41Sopenharmony_ci  // registered ObserveNodeManager and support the %ObserveNode intrinsic.
2791cb0ef41Sopenharmony_ci  class NodeProperties : public compiler::NodeProperties {
2801cb0ef41Sopenharmony_ci    static void ChangeOp(Node* node, const Operator* new_op) { UNREACHABLE(); }
2811cb0ef41Sopenharmony_ci  };
2821cb0ef41Sopenharmony_ci
2831cb0ef41Sopenharmony_ci public:
2841cb0ef41Sopenharmony_ci  // Information for each node tracked during the fixpoint.
2851cb0ef41Sopenharmony_ci  class NodeInfo final {
2861cb0ef41Sopenharmony_ci   public:
2871cb0ef41Sopenharmony_ci    // Adds new use to the node. Returns true if something has changed
2881cb0ef41Sopenharmony_ci    // and the node has to be requeued.
2891cb0ef41Sopenharmony_ci    bool AddUse(UseInfo info) {
2901cb0ef41Sopenharmony_ci      Truncation old_truncation = truncation_;
2911cb0ef41Sopenharmony_ci      truncation_ = Truncation::Generalize(truncation_, info.truncation());
2921cb0ef41Sopenharmony_ci      return truncation_ != old_truncation;
2931cb0ef41Sopenharmony_ci    }
2941cb0ef41Sopenharmony_ci
2951cb0ef41Sopenharmony_ci    void set_queued() { state_ = kQueued; }
2961cb0ef41Sopenharmony_ci    void set_visited() { state_ = kVisited; }
2971cb0ef41Sopenharmony_ci    void set_pushed() { state_ = kPushed; }
2981cb0ef41Sopenharmony_ci    void reset_state() { state_ = kUnvisited; }
2991cb0ef41Sopenharmony_ci    bool visited() const { return state_ == kVisited; }
3001cb0ef41Sopenharmony_ci    bool queued() const { return state_ == kQueued; }
3011cb0ef41Sopenharmony_ci    bool pushed() const { return state_ == kPushed; }
3021cb0ef41Sopenharmony_ci    bool unvisited() const { return state_ == kUnvisited; }
3031cb0ef41Sopenharmony_ci    Truncation truncation() const { return truncation_; }
3041cb0ef41Sopenharmony_ci    void set_output(MachineRepresentation output) { representation_ = output; }
3051cb0ef41Sopenharmony_ci
3061cb0ef41Sopenharmony_ci    MachineRepresentation representation() const { return representation_; }
3071cb0ef41Sopenharmony_ci
3081cb0ef41Sopenharmony_ci    // Helpers for feedback typing.
3091cb0ef41Sopenharmony_ci    void set_feedback_type(Type type) { feedback_type_ = type; }
3101cb0ef41Sopenharmony_ci    Type feedback_type() const { return feedback_type_; }
3111cb0ef41Sopenharmony_ci    void set_weakened() { weakened_ = true; }
3121cb0ef41Sopenharmony_ci    bool weakened() const { return weakened_; }
3131cb0ef41Sopenharmony_ci    void set_restriction_type(Type type) { restriction_type_ = type; }
3141cb0ef41Sopenharmony_ci    Type restriction_type() const { return restriction_type_; }
3151cb0ef41Sopenharmony_ci
3161cb0ef41Sopenharmony_ci   private:
3171cb0ef41Sopenharmony_ci    // Fields are ordered to avoid mixing byte and word size fields to minimize
3181cb0ef41Sopenharmony_ci    // padding.
3191cb0ef41Sopenharmony_ci    enum State : uint8_t { kUnvisited, kPushed, kVisited, kQueued };
3201cb0ef41Sopenharmony_ci    State state_ = kUnvisited;
3211cb0ef41Sopenharmony_ci    MachineRepresentation representation_ =
3221cb0ef41Sopenharmony_ci        MachineRepresentation::kNone;             // Output representation.
3231cb0ef41Sopenharmony_ci    Truncation truncation_ = Truncation::None();  // Information about uses.
3241cb0ef41Sopenharmony_ci    bool weakened_ = false;
3251cb0ef41Sopenharmony_ci
3261cb0ef41Sopenharmony_ci    Type restriction_type_ = Type::Any();
3271cb0ef41Sopenharmony_ci    Type feedback_type_;
3281cb0ef41Sopenharmony_ci  };
3291cb0ef41Sopenharmony_ci
3301cb0ef41Sopenharmony_ci  RepresentationSelector(JSGraph* jsgraph, JSHeapBroker* broker, Zone* zone,
3311cb0ef41Sopenharmony_ci                         RepresentationChanger* changer,
3321cb0ef41Sopenharmony_ci                         SourcePositionTable* source_positions,
3331cb0ef41Sopenharmony_ci                         NodeOriginTable* node_origins,
3341cb0ef41Sopenharmony_ci                         TickCounter* tick_counter, Linkage* linkage,
3351cb0ef41Sopenharmony_ci                         ObserveNodeManager* observe_node_manager,
3361cb0ef41Sopenharmony_ci                         SimplifiedLoweringVerifier* verifier)
3371cb0ef41Sopenharmony_ci      : jsgraph_(jsgraph),
3381cb0ef41Sopenharmony_ci        broker_(broker),
3391cb0ef41Sopenharmony_ci        zone_(zone),
3401cb0ef41Sopenharmony_ci        might_need_revisit_(zone),
3411cb0ef41Sopenharmony_ci        count_(jsgraph->graph()->NodeCount()),
3421cb0ef41Sopenharmony_ci        info_(count_, zone),
3431cb0ef41Sopenharmony_ci#ifdef DEBUG
3441cb0ef41Sopenharmony_ci        node_input_use_infos_(count_, InputUseInfos(zone), zone),
3451cb0ef41Sopenharmony_ci#endif
3461cb0ef41Sopenharmony_ci        replacements_(zone),
3471cb0ef41Sopenharmony_ci        changer_(changer),
3481cb0ef41Sopenharmony_ci        revisit_queue_(zone),
3491cb0ef41Sopenharmony_ci        traversal_nodes_(zone),
3501cb0ef41Sopenharmony_ci        source_positions_(source_positions),
3511cb0ef41Sopenharmony_ci        node_origins_(node_origins),
3521cb0ef41Sopenharmony_ci        type_cache_(TypeCache::Get()),
3531cb0ef41Sopenharmony_ci        op_typer_(broker, graph_zone()),
3541cb0ef41Sopenharmony_ci        tick_counter_(tick_counter),
3551cb0ef41Sopenharmony_ci        linkage_(linkage),
3561cb0ef41Sopenharmony_ci        observe_node_manager_(observe_node_manager),
3571cb0ef41Sopenharmony_ci        verifier_(verifier) {
3581cb0ef41Sopenharmony_ci  }
3591cb0ef41Sopenharmony_ci
3601cb0ef41Sopenharmony_ci  bool verification_enabled() const { return verifier_ != nullptr; }
3611cb0ef41Sopenharmony_ci
3621cb0ef41Sopenharmony_ci  void ResetNodeInfoState() {
3631cb0ef41Sopenharmony_ci    // Clean up for the next phase.
3641cb0ef41Sopenharmony_ci    for (NodeInfo& info : info_) {
3651cb0ef41Sopenharmony_ci      info.reset_state();
3661cb0ef41Sopenharmony_ci    }
3671cb0ef41Sopenharmony_ci  }
3681cb0ef41Sopenharmony_ci
3691cb0ef41Sopenharmony_ci  Type TypeOf(Node* node) {
3701cb0ef41Sopenharmony_ci    Type type = GetInfo(node)->feedback_type();
3711cb0ef41Sopenharmony_ci    return type.IsInvalid() ? NodeProperties::GetType(node) : type;
3721cb0ef41Sopenharmony_ci  }
3731cb0ef41Sopenharmony_ci
3741cb0ef41Sopenharmony_ci  Type FeedbackTypeOf(Node* node) {
3751cb0ef41Sopenharmony_ci    Type type = GetInfo(node)->feedback_type();
3761cb0ef41Sopenharmony_ci    return type.IsInvalid() ? Type::None() : type;
3771cb0ef41Sopenharmony_ci  }
3781cb0ef41Sopenharmony_ci
3791cb0ef41Sopenharmony_ci  Type TypePhi(Node* node) {
3801cb0ef41Sopenharmony_ci    int arity = node->op()->ValueInputCount();
3811cb0ef41Sopenharmony_ci    Type type = FeedbackTypeOf(node->InputAt(0));
3821cb0ef41Sopenharmony_ci    for (int i = 1; i < arity; ++i) {
3831cb0ef41Sopenharmony_ci      type = op_typer_.Merge(type, FeedbackTypeOf(node->InputAt(i)));
3841cb0ef41Sopenharmony_ci    }
3851cb0ef41Sopenharmony_ci    return type;
3861cb0ef41Sopenharmony_ci  }
3871cb0ef41Sopenharmony_ci
3881cb0ef41Sopenharmony_ci  Type TypeSelect(Node* node) {
3891cb0ef41Sopenharmony_ci    return op_typer_.Merge(FeedbackTypeOf(node->InputAt(1)),
3901cb0ef41Sopenharmony_ci                           FeedbackTypeOf(node->InputAt(2)));
3911cb0ef41Sopenharmony_ci  }
3921cb0ef41Sopenharmony_ci
3931cb0ef41Sopenharmony_ci  bool UpdateFeedbackType(Node* node) {
3941cb0ef41Sopenharmony_ci    if (node->op()->ValueOutputCount() == 0) return false;
3951cb0ef41Sopenharmony_ci
3961cb0ef41Sopenharmony_ci    // For any non-phi node just wait until we get all inputs typed. We only
3971cb0ef41Sopenharmony_ci    // allow untyped inputs for phi nodes because phis are the only places
3981cb0ef41Sopenharmony_ci    // where cycles need to be broken.
3991cb0ef41Sopenharmony_ci    if (node->opcode() != IrOpcode::kPhi) {
4001cb0ef41Sopenharmony_ci      for (int i = 0; i < node->op()->ValueInputCount(); i++) {
4011cb0ef41Sopenharmony_ci        if (GetInfo(node->InputAt(i))->feedback_type().IsInvalid()) {
4021cb0ef41Sopenharmony_ci          return false;
4031cb0ef41Sopenharmony_ci        }
4041cb0ef41Sopenharmony_ci      }
4051cb0ef41Sopenharmony_ci    }
4061cb0ef41Sopenharmony_ci
4071cb0ef41Sopenharmony_ci    NodeInfo* info = GetInfo(node);
4081cb0ef41Sopenharmony_ci    Type type = info->feedback_type();
4091cb0ef41Sopenharmony_ci    Type new_type = NodeProperties::GetType(node);
4101cb0ef41Sopenharmony_ci
4111cb0ef41Sopenharmony_ci    // We preload these values here to avoid increasing the binary size too
4121cb0ef41Sopenharmony_ci    // much, which happens if we inline the calls into the macros below.
4131cb0ef41Sopenharmony_ci    Type input0_type;
4141cb0ef41Sopenharmony_ci    if (node->InputCount() > 0) input0_type = FeedbackTypeOf(node->InputAt(0));
4151cb0ef41Sopenharmony_ci    Type input1_type;
4161cb0ef41Sopenharmony_ci    if (node->InputCount() > 1) input1_type = FeedbackTypeOf(node->InputAt(1));
4171cb0ef41Sopenharmony_ci
4181cb0ef41Sopenharmony_ci    switch (node->opcode()) {
4191cb0ef41Sopenharmony_ci#define DECLARE_CASE(Name)                               \
4201cb0ef41Sopenharmony_ci  case IrOpcode::k##Name: {                              \
4211cb0ef41Sopenharmony_ci    new_type = op_typer_.Name(input0_type, input1_type); \
4221cb0ef41Sopenharmony_ci    break;                                               \
4231cb0ef41Sopenharmony_ci  }
4241cb0ef41Sopenharmony_ci      SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
4251cb0ef41Sopenharmony_ci      DECLARE_CASE(SameValue)
4261cb0ef41Sopenharmony_ci#undef DECLARE_CASE
4271cb0ef41Sopenharmony_ci
4281cb0ef41Sopenharmony_ci#define DECLARE_CASE(Name)                                               \
4291cb0ef41Sopenharmony_ci  case IrOpcode::k##Name: {                                              \
4301cb0ef41Sopenharmony_ci    new_type = Type::Intersect(op_typer_.Name(input0_type, input1_type), \
4311cb0ef41Sopenharmony_ci                               info->restriction_type(), graph_zone());  \
4321cb0ef41Sopenharmony_ci    break;                                                               \
4331cb0ef41Sopenharmony_ci  }
4341cb0ef41Sopenharmony_ci      SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
4351cb0ef41Sopenharmony_ci      SIMPLIFIED_SPECULATIVE_BIGINT_BINOP_LIST(DECLARE_CASE)
4361cb0ef41Sopenharmony_ci#undef DECLARE_CASE
4371cb0ef41Sopenharmony_ci
4381cb0ef41Sopenharmony_ci#define DECLARE_CASE(Name)                  \
4391cb0ef41Sopenharmony_ci  case IrOpcode::k##Name: {                 \
4401cb0ef41Sopenharmony_ci    new_type = op_typer_.Name(input0_type); \
4411cb0ef41Sopenharmony_ci    break;                                  \
4421cb0ef41Sopenharmony_ci  }
4431cb0ef41Sopenharmony_ci      SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
4441cb0ef41Sopenharmony_ci#undef DECLARE_CASE
4451cb0ef41Sopenharmony_ci
4461cb0ef41Sopenharmony_ci#define DECLARE_CASE(Name)                                              \
4471cb0ef41Sopenharmony_ci  case IrOpcode::k##Name: {                                             \
4481cb0ef41Sopenharmony_ci    new_type = Type::Intersect(op_typer_.Name(input0_type),             \
4491cb0ef41Sopenharmony_ci                               info->restriction_type(), graph_zone()); \
4501cb0ef41Sopenharmony_ci    break;                                                              \
4511cb0ef41Sopenharmony_ci  }
4521cb0ef41Sopenharmony_ci      SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_CASE)
4531cb0ef41Sopenharmony_ci#undef DECLARE_CASE
4541cb0ef41Sopenharmony_ci
4551cb0ef41Sopenharmony_ci      case IrOpcode::kConvertReceiver:
4561cb0ef41Sopenharmony_ci        new_type = op_typer_.ConvertReceiver(input0_type);
4571cb0ef41Sopenharmony_ci        break;
4581cb0ef41Sopenharmony_ci
4591cb0ef41Sopenharmony_ci      case IrOpcode::kPlainPrimitiveToNumber:
4601cb0ef41Sopenharmony_ci        new_type = op_typer_.ToNumber(input0_type);
4611cb0ef41Sopenharmony_ci        break;
4621cb0ef41Sopenharmony_ci
4631cb0ef41Sopenharmony_ci      case IrOpcode::kCheckBounds:
4641cb0ef41Sopenharmony_ci        new_type =
4651cb0ef41Sopenharmony_ci            Type::Intersect(op_typer_.CheckBounds(input0_type, input1_type),
4661cb0ef41Sopenharmony_ci                            info->restriction_type(), graph_zone());
4671cb0ef41Sopenharmony_ci        break;
4681cb0ef41Sopenharmony_ci
4691cb0ef41Sopenharmony_ci      case IrOpcode::kCheckFloat64Hole:
4701cb0ef41Sopenharmony_ci        new_type = Type::Intersect(op_typer_.CheckFloat64Hole(input0_type),
4711cb0ef41Sopenharmony_ci                                   info->restriction_type(), graph_zone());
4721cb0ef41Sopenharmony_ci        break;
4731cb0ef41Sopenharmony_ci
4741cb0ef41Sopenharmony_ci      case IrOpcode::kCheckNumber:
4751cb0ef41Sopenharmony_ci        new_type = Type::Intersect(op_typer_.CheckNumber(input0_type),
4761cb0ef41Sopenharmony_ci                                   info->restriction_type(), graph_zone());
4771cb0ef41Sopenharmony_ci        break;
4781cb0ef41Sopenharmony_ci
4791cb0ef41Sopenharmony_ci      case IrOpcode::kPhi: {
4801cb0ef41Sopenharmony_ci        new_type = TypePhi(node);
4811cb0ef41Sopenharmony_ci        if (!type.IsInvalid()) {
4821cb0ef41Sopenharmony_ci          new_type = Weaken(node, type, new_type);
4831cb0ef41Sopenharmony_ci        }
4841cb0ef41Sopenharmony_ci        break;
4851cb0ef41Sopenharmony_ci      }
4861cb0ef41Sopenharmony_ci
4871cb0ef41Sopenharmony_ci      case IrOpcode::kConvertTaggedHoleToUndefined:
4881cb0ef41Sopenharmony_ci        new_type = op_typer_.ConvertTaggedHoleToUndefined(
4891cb0ef41Sopenharmony_ci            FeedbackTypeOf(node->InputAt(0)));
4901cb0ef41Sopenharmony_ci        break;
4911cb0ef41Sopenharmony_ci
4921cb0ef41Sopenharmony_ci      case IrOpcode::kTypeGuard: {
4931cb0ef41Sopenharmony_ci        new_type = op_typer_.TypeTypeGuard(node->op(),
4941cb0ef41Sopenharmony_ci                                           FeedbackTypeOf(node->InputAt(0)));
4951cb0ef41Sopenharmony_ci        break;
4961cb0ef41Sopenharmony_ci      }
4971cb0ef41Sopenharmony_ci
4981cb0ef41Sopenharmony_ci      case IrOpcode::kSelect: {
4991cb0ef41Sopenharmony_ci        new_type = TypeSelect(node);
5001cb0ef41Sopenharmony_ci        break;
5011cb0ef41Sopenharmony_ci      }
5021cb0ef41Sopenharmony_ci
5031cb0ef41Sopenharmony_ci      default:
5041cb0ef41Sopenharmony_ci        // Shortcut for operations that we do not handle.
5051cb0ef41Sopenharmony_ci        if (type.IsInvalid()) {
5061cb0ef41Sopenharmony_ci          GetInfo(node)->set_feedback_type(NodeProperties::GetType(node));
5071cb0ef41Sopenharmony_ci          return true;
5081cb0ef41Sopenharmony_ci        }
5091cb0ef41Sopenharmony_ci        return false;
5101cb0ef41Sopenharmony_ci    }
5111cb0ef41Sopenharmony_ci    // We need to guarantee that the feedback type is a subtype of the upper
5121cb0ef41Sopenharmony_ci    // bound. Naively that should hold, but weakening can actually produce
5131cb0ef41Sopenharmony_ci    // a bigger type if we are unlucky with ordering of phi typing. To be
5141cb0ef41Sopenharmony_ci    // really sure, just intersect the upper bound with the feedback type.
5151cb0ef41Sopenharmony_ci    new_type = Type::Intersect(GetUpperBound(node), new_type, graph_zone());
5161cb0ef41Sopenharmony_ci
5171cb0ef41Sopenharmony_ci    if (!type.IsInvalid() && new_type.Is(type)) return false;
5181cb0ef41Sopenharmony_ci    GetInfo(node)->set_feedback_type(new_type);
5191cb0ef41Sopenharmony_ci    if (FLAG_trace_representation) {
5201cb0ef41Sopenharmony_ci      PrintNodeFeedbackType(node);
5211cb0ef41Sopenharmony_ci    }
5221cb0ef41Sopenharmony_ci    return true;
5231cb0ef41Sopenharmony_ci  }
5241cb0ef41Sopenharmony_ci
5251cb0ef41Sopenharmony_ci  void PrintNodeFeedbackType(Node* n) {
5261cb0ef41Sopenharmony_ci    StdoutStream os;
5271cb0ef41Sopenharmony_ci    os << "#" << n->id() << ":" << *n->op() << "(";
5281cb0ef41Sopenharmony_ci    int j = 0;
5291cb0ef41Sopenharmony_ci    for (Node* const i : n->inputs()) {
5301cb0ef41Sopenharmony_ci      if (j++ > 0) os << ", ";
5311cb0ef41Sopenharmony_ci      os << "#" << i->id() << ":" << i->op()->mnemonic();
5321cb0ef41Sopenharmony_ci    }
5331cb0ef41Sopenharmony_ci    os << ")";
5341cb0ef41Sopenharmony_ci    if (NodeProperties::IsTyped(n)) {
5351cb0ef41Sopenharmony_ci      Type static_type = NodeProperties::GetType(n);
5361cb0ef41Sopenharmony_ci      os << "  [Static type: " << static_type;
5371cb0ef41Sopenharmony_ci      Type feedback_type = GetInfo(n)->feedback_type();
5381cb0ef41Sopenharmony_ci      if (!feedback_type.IsInvalid() && feedback_type != static_type) {
5391cb0ef41Sopenharmony_ci        os << ", Feedback type: " << feedback_type;
5401cb0ef41Sopenharmony_ci      }
5411cb0ef41Sopenharmony_ci      os << "]";
5421cb0ef41Sopenharmony_ci    }
5431cb0ef41Sopenharmony_ci    os << std::endl;
5441cb0ef41Sopenharmony_ci  }
5451cb0ef41Sopenharmony_ci
5461cb0ef41Sopenharmony_ci  Type Weaken(Node* node, Type previous_type, Type current_type) {
5471cb0ef41Sopenharmony_ci    // If the types have nothing to do with integers, return the types.
5481cb0ef41Sopenharmony_ci    Type const integer = type_cache_->kInteger;
5491cb0ef41Sopenharmony_ci    if (!previous_type.Maybe(integer)) {
5501cb0ef41Sopenharmony_ci      return current_type;
5511cb0ef41Sopenharmony_ci    }
5521cb0ef41Sopenharmony_ci    DCHECK(current_type.Maybe(integer));
5531cb0ef41Sopenharmony_ci
5541cb0ef41Sopenharmony_ci    Type current_integer = Type::Intersect(current_type, integer, graph_zone());
5551cb0ef41Sopenharmony_ci    DCHECK(!current_integer.IsNone());
5561cb0ef41Sopenharmony_ci    Type previous_integer =
5571cb0ef41Sopenharmony_ci        Type::Intersect(previous_type, integer, graph_zone());
5581cb0ef41Sopenharmony_ci    DCHECK(!previous_integer.IsNone());
5591cb0ef41Sopenharmony_ci
5601cb0ef41Sopenharmony_ci    // Once we start weakening a node, we should always weaken.
5611cb0ef41Sopenharmony_ci    if (!GetInfo(node)->weakened()) {
5621cb0ef41Sopenharmony_ci      // Only weaken if there is range involved; we should converge quickly
5631cb0ef41Sopenharmony_ci      // for all other types (the exception is a union of many constants,
5641cb0ef41Sopenharmony_ci      // but we currently do not increase the number of constants in unions).
5651cb0ef41Sopenharmony_ci      Type previous = previous_integer.GetRange();
5661cb0ef41Sopenharmony_ci      Type current = current_integer.GetRange();
5671cb0ef41Sopenharmony_ci      if (current.IsInvalid() || previous.IsInvalid()) {
5681cb0ef41Sopenharmony_ci        return current_type;
5691cb0ef41Sopenharmony_ci      }
5701cb0ef41Sopenharmony_ci      // Range is involved => we are weakening.
5711cb0ef41Sopenharmony_ci      GetInfo(node)->set_weakened();
5721cb0ef41Sopenharmony_ci    }
5731cb0ef41Sopenharmony_ci
5741cb0ef41Sopenharmony_ci    return Type::Union(current_type,
5751cb0ef41Sopenharmony_ci                       op_typer_.WeakenRange(previous_integer, current_integer),
5761cb0ef41Sopenharmony_ci                       graph_zone());
5771cb0ef41Sopenharmony_ci  }
5781cb0ef41Sopenharmony_ci
5791cb0ef41Sopenharmony_ci  // Generates a pre-order traversal of the nodes, starting with End.
5801cb0ef41Sopenharmony_ci  void GenerateTraversal() {
5811cb0ef41Sopenharmony_ci    // Reset previous state.
5821cb0ef41Sopenharmony_ci    ResetNodeInfoState();
5831cb0ef41Sopenharmony_ci    traversal_nodes_.clear();
5841cb0ef41Sopenharmony_ci    count_ = graph()->NodeCount();
5851cb0ef41Sopenharmony_ci    info_.resize(count_);
5861cb0ef41Sopenharmony_ci
5871cb0ef41Sopenharmony_ci    ZoneStack<NodeState> stack(zone_);
5881cb0ef41Sopenharmony_ci
5891cb0ef41Sopenharmony_ci    stack.push({graph()->end(), 0});
5901cb0ef41Sopenharmony_ci    GetInfo(graph()->end())->set_pushed();
5911cb0ef41Sopenharmony_ci    while (!stack.empty()) {
5921cb0ef41Sopenharmony_ci      NodeState& current = stack.top();
5931cb0ef41Sopenharmony_ci      Node* node = current.node;
5941cb0ef41Sopenharmony_ci
5951cb0ef41Sopenharmony_ci      // If there is an unvisited input, push it and continue with that node.
5961cb0ef41Sopenharmony_ci      bool pushed_unvisited = false;
5971cb0ef41Sopenharmony_ci      while (current.input_index < node->InputCount()) {
5981cb0ef41Sopenharmony_ci        Node* input = node->InputAt(current.input_index);
5991cb0ef41Sopenharmony_ci        NodeInfo* input_info = GetInfo(input);
6001cb0ef41Sopenharmony_ci        current.input_index++;
6011cb0ef41Sopenharmony_ci        if (input_info->unvisited()) {
6021cb0ef41Sopenharmony_ci          input_info->set_pushed();
6031cb0ef41Sopenharmony_ci          stack.push({input, 0});
6041cb0ef41Sopenharmony_ci          pushed_unvisited = true;
6051cb0ef41Sopenharmony_ci          break;
6061cb0ef41Sopenharmony_ci        } else if (input_info->pushed()) {
6071cb0ef41Sopenharmony_ci          // Optimization for the Retype phase.
6081cb0ef41Sopenharmony_ci          // If we had already pushed (and not visited) an input, it means that
6091cb0ef41Sopenharmony_ci          // the current node will be visited in the Retype phase before one of
6101cb0ef41Sopenharmony_ci          // its inputs. If this happens, the current node might need to be
6111cb0ef41Sopenharmony_ci          // revisited.
6121cb0ef41Sopenharmony_ci          MarkAsPossibleRevisit(node, input);
6131cb0ef41Sopenharmony_ci        }
6141cb0ef41Sopenharmony_ci      }
6151cb0ef41Sopenharmony_ci
6161cb0ef41Sopenharmony_ci      if (pushed_unvisited) continue;
6171cb0ef41Sopenharmony_ci
6181cb0ef41Sopenharmony_ci      stack.pop();
6191cb0ef41Sopenharmony_ci      NodeInfo* info = GetInfo(node);
6201cb0ef41Sopenharmony_ci      info->set_visited();
6211cb0ef41Sopenharmony_ci
6221cb0ef41Sopenharmony_ci      // Generate the traversal
6231cb0ef41Sopenharmony_ci      traversal_nodes_.push_back(node);
6241cb0ef41Sopenharmony_ci    }
6251cb0ef41Sopenharmony_ci  }
6261cb0ef41Sopenharmony_ci
6271cb0ef41Sopenharmony_ci  void PushNodeToRevisitIfVisited(Node* node) {
6281cb0ef41Sopenharmony_ci    NodeInfo* info = GetInfo(node);
6291cb0ef41Sopenharmony_ci    if (info->visited()) {
6301cb0ef41Sopenharmony_ci      TRACE(" QUEUEING #%d: %s\n", node->id(), node->op()->mnemonic());
6311cb0ef41Sopenharmony_ci      info->set_queued();
6321cb0ef41Sopenharmony_ci      revisit_queue_.push(node);
6331cb0ef41Sopenharmony_ci    }
6341cb0ef41Sopenharmony_ci  }
6351cb0ef41Sopenharmony_ci
6361cb0ef41Sopenharmony_ci  // Tries to update the feedback type of the node, as well as setting its
6371cb0ef41Sopenharmony_ci  // machine representation (in VisitNode). Returns true iff updating the
6381cb0ef41Sopenharmony_ci  // feedback type is successful.
6391cb0ef41Sopenharmony_ci  bool RetypeNode(Node* node) {
6401cb0ef41Sopenharmony_ci    NodeInfo* info = GetInfo(node);
6411cb0ef41Sopenharmony_ci    info->set_visited();
6421cb0ef41Sopenharmony_ci    bool updated = UpdateFeedbackType(node);
6431cb0ef41Sopenharmony_ci    TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
6441cb0ef41Sopenharmony_ci    VisitNode<RETYPE>(node, info->truncation(), nullptr);
6451cb0ef41Sopenharmony_ci    TRACE("  ==> output %s\n", MachineReprToString(info->representation()));
6461cb0ef41Sopenharmony_ci    return updated;
6471cb0ef41Sopenharmony_ci  }
6481cb0ef41Sopenharmony_ci
6491cb0ef41Sopenharmony_ci  // Visits the node and marks it as visited. Inside of VisitNode, we might
6501cb0ef41Sopenharmony_ci  // change the truncation of one of our inputs (see EnqueueInput<PROPAGATE> for
6511cb0ef41Sopenharmony_ci  // this). If we change the truncation of an already visited node, we will add
6521cb0ef41Sopenharmony_ci  // it to the revisit queue.
6531cb0ef41Sopenharmony_ci  void PropagateTruncation(Node* node) {
6541cb0ef41Sopenharmony_ci    NodeInfo* info = GetInfo(node);
6551cb0ef41Sopenharmony_ci    info->set_visited();
6561cb0ef41Sopenharmony_ci    TRACE(" visit #%d: %s (trunc: %s)\n", node->id(), node->op()->mnemonic(),
6571cb0ef41Sopenharmony_ci          info->truncation().description());
6581cb0ef41Sopenharmony_ci    VisitNode<PROPAGATE>(node, info->truncation(), nullptr);
6591cb0ef41Sopenharmony_ci  }
6601cb0ef41Sopenharmony_ci
6611cb0ef41Sopenharmony_ci  // Backward propagation of truncations to a fixpoint.
6621cb0ef41Sopenharmony_ci  void RunPropagatePhase() {
6631cb0ef41Sopenharmony_ci    TRACE("--{Propagate phase}--\n");
6641cb0ef41Sopenharmony_ci    ResetNodeInfoState();
6651cb0ef41Sopenharmony_ci    DCHECK(revisit_queue_.empty());
6661cb0ef41Sopenharmony_ci
6671cb0ef41Sopenharmony_ci    // Process nodes in reverse post order, with End as the root.
6681cb0ef41Sopenharmony_ci    for (auto it = traversal_nodes_.crbegin(); it != traversal_nodes_.crend();
6691cb0ef41Sopenharmony_ci         ++it) {
6701cb0ef41Sopenharmony_ci      PropagateTruncation(*it);
6711cb0ef41Sopenharmony_ci
6721cb0ef41Sopenharmony_ci      while (!revisit_queue_.empty()) {
6731cb0ef41Sopenharmony_ci        Node* node = revisit_queue_.front();
6741cb0ef41Sopenharmony_ci        revisit_queue_.pop();
6751cb0ef41Sopenharmony_ci        PropagateTruncation(node);
6761cb0ef41Sopenharmony_ci      }
6771cb0ef41Sopenharmony_ci    }
6781cb0ef41Sopenharmony_ci  }
6791cb0ef41Sopenharmony_ci
6801cb0ef41Sopenharmony_ci  // Forward propagation of types from type feedback to a fixpoint.
6811cb0ef41Sopenharmony_ci  void RunRetypePhase() {
6821cb0ef41Sopenharmony_ci    TRACE("--{Retype phase}--\n");
6831cb0ef41Sopenharmony_ci    ResetNodeInfoState();
6841cb0ef41Sopenharmony_ci    DCHECK(revisit_queue_.empty());
6851cb0ef41Sopenharmony_ci
6861cb0ef41Sopenharmony_ci    for (auto it = traversal_nodes_.cbegin(); it != traversal_nodes_.cend();
6871cb0ef41Sopenharmony_ci         ++it) {
6881cb0ef41Sopenharmony_ci      Node* node = *it;
6891cb0ef41Sopenharmony_ci      if (!RetypeNode(node)) continue;
6901cb0ef41Sopenharmony_ci
6911cb0ef41Sopenharmony_ci      auto revisit_it = might_need_revisit_.find(node);
6921cb0ef41Sopenharmony_ci      if (revisit_it == might_need_revisit_.end()) continue;
6931cb0ef41Sopenharmony_ci
6941cb0ef41Sopenharmony_ci      for (Node* const user : revisit_it->second) {
6951cb0ef41Sopenharmony_ci        PushNodeToRevisitIfVisited(user);
6961cb0ef41Sopenharmony_ci      }
6971cb0ef41Sopenharmony_ci
6981cb0ef41Sopenharmony_ci      // Process the revisit queue.
6991cb0ef41Sopenharmony_ci      while (!revisit_queue_.empty()) {
7001cb0ef41Sopenharmony_ci        Node* revisit_node = revisit_queue_.front();
7011cb0ef41Sopenharmony_ci        revisit_queue_.pop();
7021cb0ef41Sopenharmony_ci        if (!RetypeNode(revisit_node)) continue;
7031cb0ef41Sopenharmony_ci        // Here we need to check all uses since we can't easily know which
7041cb0ef41Sopenharmony_ci        // nodes will need to be revisited due to having an input which was
7051cb0ef41Sopenharmony_ci        // a revisited node.
7061cb0ef41Sopenharmony_ci        for (Node* const user : revisit_node->uses()) {
7071cb0ef41Sopenharmony_ci          PushNodeToRevisitIfVisited(user);
7081cb0ef41Sopenharmony_ci        }
7091cb0ef41Sopenharmony_ci      }
7101cb0ef41Sopenharmony_ci    }
7111cb0ef41Sopenharmony_ci  }
7121cb0ef41Sopenharmony_ci
7131cb0ef41Sopenharmony_ci  // Lowering and change insertion phase.
7141cb0ef41Sopenharmony_ci  void RunLowerPhase(SimplifiedLowering* lowering) {
7151cb0ef41Sopenharmony_ci    TRACE("--{Lower phase}--\n");
7161cb0ef41Sopenharmony_ci    for (auto it = traversal_nodes_.cbegin(); it != traversal_nodes_.cend();
7171cb0ef41Sopenharmony_ci         ++it) {
7181cb0ef41Sopenharmony_ci      Node* node = *it;
7191cb0ef41Sopenharmony_ci      NodeInfo* info = GetInfo(node);
7201cb0ef41Sopenharmony_ci      TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
7211cb0ef41Sopenharmony_ci      // Reuse {VisitNode()} so the representation rules are in one place.
7221cb0ef41Sopenharmony_ci      SourcePositionTable::Scope scope(
7231cb0ef41Sopenharmony_ci          source_positions_, source_positions_->GetSourcePosition(node));
7241cb0ef41Sopenharmony_ci      NodeOriginTable::Scope origin_scope(node_origins_, "simplified lowering",
7251cb0ef41Sopenharmony_ci                                          node);
7261cb0ef41Sopenharmony_ci      VisitNode<LOWER>(node, info->truncation(), lowering);
7271cb0ef41Sopenharmony_ci    }
7281cb0ef41Sopenharmony_ci
7291cb0ef41Sopenharmony_ci    // Perform the final replacements.
7301cb0ef41Sopenharmony_ci    for (NodeVector::iterator i = replacements_.begin();
7311cb0ef41Sopenharmony_ci         i != replacements_.end(); ++i) {
7321cb0ef41Sopenharmony_ci      Node* node = *i;
7331cb0ef41Sopenharmony_ci      Node* replacement = *(++i);
7341cb0ef41Sopenharmony_ci      node->ReplaceUses(replacement);
7351cb0ef41Sopenharmony_ci      node->Kill();
7361cb0ef41Sopenharmony_ci      // We also need to replace the node in the rest of the vector.
7371cb0ef41Sopenharmony_ci      for (NodeVector::iterator j = i + 1; j != replacements_.end(); ++j) {
7381cb0ef41Sopenharmony_ci        ++j;
7391cb0ef41Sopenharmony_ci        if (*j == node) *j = replacement;
7401cb0ef41Sopenharmony_ci      }
7411cb0ef41Sopenharmony_ci    }
7421cb0ef41Sopenharmony_ci  }
7431cb0ef41Sopenharmony_ci
7441cb0ef41Sopenharmony_ci  void RunVerifyPhase(OptimizedCompilationInfo* info) {
7451cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(verifier_);
7461cb0ef41Sopenharmony_ci
7471cb0ef41Sopenharmony_ci    TRACE("--{Verify Phase}--\n");
7481cb0ef41Sopenharmony_ci
7491cb0ef41Sopenharmony_ci    // Generate a new traversal containing all the new nodes created during
7501cb0ef41Sopenharmony_ci    // lowering.
7511cb0ef41Sopenharmony_ci    GenerateTraversal();
7521cb0ef41Sopenharmony_ci
7531cb0ef41Sopenharmony_ci    // Set node types to the refined types computed during retyping.
7541cb0ef41Sopenharmony_ci    for (Node* node : traversal_nodes_) {
7551cb0ef41Sopenharmony_ci      NodeInfo* info = GetInfo(node);
7561cb0ef41Sopenharmony_ci      if (!info->feedback_type().IsInvalid()) {
7571cb0ef41Sopenharmony_ci        NodeProperties::SetType(node, info->feedback_type());
7581cb0ef41Sopenharmony_ci      }
7591cb0ef41Sopenharmony_ci    }
7601cb0ef41Sopenharmony_ci
7611cb0ef41Sopenharmony_ci    // Verify all nodes.
7621cb0ef41Sopenharmony_ci    for (Node* node : traversal_nodes_) verifier_->VisitNode(node, op_typer_);
7631cb0ef41Sopenharmony_ci
7641cb0ef41Sopenharmony_ci    // Print graph.
7651cb0ef41Sopenharmony_ci    if (info != nullptr && info->trace_turbo_json()) {
7661cb0ef41Sopenharmony_ci      UnparkedScopeIfNeeded scope(broker_);
7671cb0ef41Sopenharmony_ci      AllowHandleDereference allow_deref;
7681cb0ef41Sopenharmony_ci
7691cb0ef41Sopenharmony_ci      TurboJsonFile json_of(info, std::ios_base::app);
7701cb0ef41Sopenharmony_ci      JSONGraphWriterWithVerifierTypes writer(
7711cb0ef41Sopenharmony_ci          json_of, graph(), source_positions_, node_origins_, verifier_);
7721cb0ef41Sopenharmony_ci      writer.PrintPhase("V8.TFSimplifiedLoweringVerifier");
7731cb0ef41Sopenharmony_ci    }
7741cb0ef41Sopenharmony_ci
7751cb0ef41Sopenharmony_ci    // Eliminate all introduced hints.
7761cb0ef41Sopenharmony_ci    for (Node* node : verifier_->inserted_hints()) {
7771cb0ef41Sopenharmony_ci      Node* input = node->InputAt(0);
7781cb0ef41Sopenharmony_ci      node->ReplaceUses(input);
7791cb0ef41Sopenharmony_ci      node->Kill();
7801cb0ef41Sopenharmony_ci    }
7811cb0ef41Sopenharmony_ci  }
7821cb0ef41Sopenharmony_ci
7831cb0ef41Sopenharmony_ci  void Run(SimplifiedLowering* lowering) {
7841cb0ef41Sopenharmony_ci    GenerateTraversal();
7851cb0ef41Sopenharmony_ci    RunPropagatePhase();
7861cb0ef41Sopenharmony_ci    RunRetypePhase();
7871cb0ef41Sopenharmony_ci    RunLowerPhase(lowering);
7881cb0ef41Sopenharmony_ci
7891cb0ef41Sopenharmony_ci    if (verification_enabled()) {
7901cb0ef41Sopenharmony_ci      RunVerifyPhase(lowering->info_);
7911cb0ef41Sopenharmony_ci    }
7921cb0ef41Sopenharmony_ci  }
7931cb0ef41Sopenharmony_ci
7941cb0ef41Sopenharmony_ci  // Just assert for Retype and Lower. Propagate specialized below.
7951cb0ef41Sopenharmony_ci  template <Phase T>
7961cb0ef41Sopenharmony_ci  void EnqueueInput(Node* use_node, int index,
7971cb0ef41Sopenharmony_ci                    UseInfo use_info = UseInfo::None()) {
7981cb0ef41Sopenharmony_ci    static_assert(retype<T>() || lower<T>(),
7991cb0ef41Sopenharmony_ci                  "This version of EnqueueInput has to be called in "
8001cb0ef41Sopenharmony_ci                  "the Retype or Lower phase.");
8011cb0ef41Sopenharmony_ci  }
8021cb0ef41Sopenharmony_ci
8031cb0ef41Sopenharmony_ci  template <Phase T>
8041cb0ef41Sopenharmony_ci  static constexpr bool propagate() {
8051cb0ef41Sopenharmony_ci    return T == PROPAGATE;
8061cb0ef41Sopenharmony_ci  }
8071cb0ef41Sopenharmony_ci
8081cb0ef41Sopenharmony_ci  template <Phase T>
8091cb0ef41Sopenharmony_ci  static constexpr bool retype() {
8101cb0ef41Sopenharmony_ci    return T == RETYPE;
8111cb0ef41Sopenharmony_ci  }
8121cb0ef41Sopenharmony_ci
8131cb0ef41Sopenharmony_ci  template <Phase T>
8141cb0ef41Sopenharmony_ci  static constexpr bool lower() {
8151cb0ef41Sopenharmony_ci    return T == LOWER;
8161cb0ef41Sopenharmony_ci  }
8171cb0ef41Sopenharmony_ci
8181cb0ef41Sopenharmony_ci  template <Phase T>
8191cb0ef41Sopenharmony_ci  void SetOutput(Node* node, MachineRepresentation representation,
8201cb0ef41Sopenharmony_ci                 Type restriction_type = Type::Any());
8211cb0ef41Sopenharmony_ci
8221cb0ef41Sopenharmony_ci  Type GetUpperBound(Node* node) { return NodeProperties::GetType(node); }
8231cb0ef41Sopenharmony_ci
8241cb0ef41Sopenharmony_ci  bool InputCannotBe(Node* node, Type type) {
8251cb0ef41Sopenharmony_ci    DCHECK_EQ(1, node->op()->ValueInputCount());
8261cb0ef41Sopenharmony_ci    return !GetUpperBound(node->InputAt(0)).Maybe(type);
8271cb0ef41Sopenharmony_ci  }
8281cb0ef41Sopenharmony_ci
8291cb0ef41Sopenharmony_ci  bool InputIs(Node* node, Type type) {
8301cb0ef41Sopenharmony_ci    DCHECK_EQ(1, node->op()->ValueInputCount());
8311cb0ef41Sopenharmony_ci    return GetUpperBound(node->InputAt(0)).Is(type);
8321cb0ef41Sopenharmony_ci  }
8331cb0ef41Sopenharmony_ci
8341cb0ef41Sopenharmony_ci  bool BothInputsAreSigned32(Node* node) {
8351cb0ef41Sopenharmony_ci    return BothInputsAre(node, Type::Signed32());
8361cb0ef41Sopenharmony_ci  }
8371cb0ef41Sopenharmony_ci
8381cb0ef41Sopenharmony_ci  bool BothInputsAreUnsigned32(Node* node) {
8391cb0ef41Sopenharmony_ci    return BothInputsAre(node, Type::Unsigned32());
8401cb0ef41Sopenharmony_ci  }
8411cb0ef41Sopenharmony_ci
8421cb0ef41Sopenharmony_ci  bool BothInputsAre(Node* node, Type type) {
8431cb0ef41Sopenharmony_ci    DCHECK_EQ(2, node->op()->ValueInputCount());
8441cb0ef41Sopenharmony_ci    return GetUpperBound(node->InputAt(0)).Is(type) &&
8451cb0ef41Sopenharmony_ci           GetUpperBound(node->InputAt(1)).Is(type);
8461cb0ef41Sopenharmony_ci  }
8471cb0ef41Sopenharmony_ci
8481cb0ef41Sopenharmony_ci  bool IsNodeRepresentationTagged(Node* node) {
8491cb0ef41Sopenharmony_ci    MachineRepresentation representation = GetInfo(node)->representation();
8501cb0ef41Sopenharmony_ci    return IsAnyTagged(representation);
8511cb0ef41Sopenharmony_ci  }
8521cb0ef41Sopenharmony_ci
8531cb0ef41Sopenharmony_ci  bool OneInputCannotBe(Node* node, Type type) {
8541cb0ef41Sopenharmony_ci    DCHECK_EQ(2, node->op()->ValueInputCount());
8551cb0ef41Sopenharmony_ci    return !GetUpperBound(node->InputAt(0)).Maybe(type) ||
8561cb0ef41Sopenharmony_ci           !GetUpperBound(node->InputAt(1)).Maybe(type);
8571cb0ef41Sopenharmony_ci  }
8581cb0ef41Sopenharmony_ci
8591cb0ef41Sopenharmony_ci  void ChangeToDeadValue(Node* node, Node* effect, Node* control) {
8601cb0ef41Sopenharmony_ci    DCHECK(TypeOf(node).IsNone());
8611cb0ef41Sopenharmony_ci    // If the node is unreachable, insert an Unreachable node and mark the
8621cb0ef41Sopenharmony_ci    // value dead.
8631cb0ef41Sopenharmony_ci    // TODO(jarin,turbofan) Find a way to unify/merge this insertion with
8641cb0ef41Sopenharmony_ci    // InsertUnreachableIfNecessary.
8651cb0ef41Sopenharmony_ci    Node* unreachable = effect =
8661cb0ef41Sopenharmony_ci        graph()->NewNode(common()->Unreachable(), effect, control);
8671cb0ef41Sopenharmony_ci    const Operator* dead_value =
8681cb0ef41Sopenharmony_ci        common()->DeadValue(GetInfo(node)->representation());
8691cb0ef41Sopenharmony_ci    node->ReplaceInput(0, unreachable);
8701cb0ef41Sopenharmony_ci    node->TrimInputCount(dead_value->ValueInputCount());
8711cb0ef41Sopenharmony_ci    ReplaceEffectControlUses(node, effect, control);
8721cb0ef41Sopenharmony_ci    ChangeOp(node, dead_value);
8731cb0ef41Sopenharmony_ci  }
8741cb0ef41Sopenharmony_ci
8751cb0ef41Sopenharmony_ci  // This function is a generalization of ChangeToPureOp. It can be used to
8761cb0ef41Sopenharmony_ci  // replace a node that is part of the effect and control chain by a pure node.
8771cb0ef41Sopenharmony_ci  void ReplaceWithPureNode(Node* node, Node* pure_node) {
8781cb0ef41Sopenharmony_ci    DCHECK(pure_node->op()->HasProperty(Operator::kPure));
8791cb0ef41Sopenharmony_ci    if (node->op()->EffectInputCount() > 0) {
8801cb0ef41Sopenharmony_ci      DCHECK_LT(0, node->op()->ControlInputCount());
8811cb0ef41Sopenharmony_ci      Node* control = NodeProperties::GetControlInput(node);
8821cb0ef41Sopenharmony_ci      Node* effect = NodeProperties::GetEffectInput(node);
8831cb0ef41Sopenharmony_ci      if (TypeOf(node).IsNone()) {
8841cb0ef41Sopenharmony_ci        ChangeToDeadValue(node, effect, control);
8851cb0ef41Sopenharmony_ci        return;
8861cb0ef41Sopenharmony_ci      }
8871cb0ef41Sopenharmony_ci      // Rewire the effect and control chains.
8881cb0ef41Sopenharmony_ci      ReplaceEffectControlUses(node, effect, control);
8891cb0ef41Sopenharmony_ci    } else {
8901cb0ef41Sopenharmony_ci      DCHECK_EQ(0, node->op()->ControlInputCount());
8911cb0ef41Sopenharmony_ci    }
8921cb0ef41Sopenharmony_ci    DeferReplacement(node, pure_node);
8931cb0ef41Sopenharmony_ci  }
8941cb0ef41Sopenharmony_ci
8951cb0ef41Sopenharmony_ci  void ChangeToPureOp(Node* node, const Operator* new_op) {
8961cb0ef41Sopenharmony_ci    DCHECK(new_op->HasProperty(Operator::kPure));
8971cb0ef41Sopenharmony_ci    DCHECK_EQ(new_op->ValueInputCount(), node->op()->ValueInputCount());
8981cb0ef41Sopenharmony_ci    if (node->op()->EffectInputCount() > 0) {
8991cb0ef41Sopenharmony_ci      DCHECK_LT(0, node->op()->ControlInputCount());
9001cb0ef41Sopenharmony_ci      Node* control = NodeProperties::GetControlInput(node);
9011cb0ef41Sopenharmony_ci      Node* effect = NodeProperties::GetEffectInput(node);
9021cb0ef41Sopenharmony_ci      if (TypeOf(node).IsNone()) {
9031cb0ef41Sopenharmony_ci        ChangeToDeadValue(node, effect, control);
9041cb0ef41Sopenharmony_ci        return;
9051cb0ef41Sopenharmony_ci      }
9061cb0ef41Sopenharmony_ci      // Rewire the effect and control chains.
9071cb0ef41Sopenharmony_ci      node->TrimInputCount(new_op->ValueInputCount());
9081cb0ef41Sopenharmony_ci      ReplaceEffectControlUses(node, effect, control);
9091cb0ef41Sopenharmony_ci    } else {
9101cb0ef41Sopenharmony_ci      DCHECK_EQ(0, node->op()->ControlInputCount());
9111cb0ef41Sopenharmony_ci    }
9121cb0ef41Sopenharmony_ci    ChangeOp(node, new_op);
9131cb0ef41Sopenharmony_ci  }
9141cb0ef41Sopenharmony_ci
9151cb0ef41Sopenharmony_ci  void ChangeUnaryToPureBinaryOp(Node* node, const Operator* new_op,
9161cb0ef41Sopenharmony_ci                                 int new_input_index, Node* new_input) {
9171cb0ef41Sopenharmony_ci    DCHECK(new_op->HasProperty(Operator::kPure));
9181cb0ef41Sopenharmony_ci    DCHECK_EQ(new_op->ValueInputCount(), 2);
9191cb0ef41Sopenharmony_ci    DCHECK_EQ(node->op()->ValueInputCount(), 1);
9201cb0ef41Sopenharmony_ci    DCHECK_LE(0, new_input_index);
9211cb0ef41Sopenharmony_ci    DCHECK_LE(new_input_index, 1);
9221cb0ef41Sopenharmony_ci    if (node->op()->EffectInputCount() > 0) {
9231cb0ef41Sopenharmony_ci      DCHECK_LT(0, node->op()->ControlInputCount());
9241cb0ef41Sopenharmony_ci      Node* control = NodeProperties::GetControlInput(node);
9251cb0ef41Sopenharmony_ci      Node* effect = NodeProperties::GetEffectInput(node);
9261cb0ef41Sopenharmony_ci      if (TypeOf(node).IsNone()) {
9271cb0ef41Sopenharmony_ci        ChangeToDeadValue(node, effect, control);
9281cb0ef41Sopenharmony_ci        return;
9291cb0ef41Sopenharmony_ci      }
9301cb0ef41Sopenharmony_ci      node->TrimInputCount(node->op()->ValueInputCount());
9311cb0ef41Sopenharmony_ci      ReplaceEffectControlUses(node, effect, control);
9321cb0ef41Sopenharmony_ci    } else {
9331cb0ef41Sopenharmony_ci      DCHECK_EQ(0, node->op()->ControlInputCount());
9341cb0ef41Sopenharmony_ci    }
9351cb0ef41Sopenharmony_ci    if (new_input_index == 0) {
9361cb0ef41Sopenharmony_ci      node->InsertInput(jsgraph_->zone(), 0, new_input);
9371cb0ef41Sopenharmony_ci    } else {
9381cb0ef41Sopenharmony_ci      DCHECK_EQ(new_input_index, 1);
9391cb0ef41Sopenharmony_ci      DCHECK_EQ(node->InputCount(), 1);
9401cb0ef41Sopenharmony_ci      node->AppendInput(jsgraph_->zone(), new_input);
9411cb0ef41Sopenharmony_ci    }
9421cb0ef41Sopenharmony_ci    ChangeOp(node, new_op);
9431cb0ef41Sopenharmony_ci  }
9441cb0ef41Sopenharmony_ci
9451cb0ef41Sopenharmony_ci  // Converts input {index} of {node} according to given UseInfo {use},
9461cb0ef41Sopenharmony_ci  // assuming the type of the input is {input_type}. If {input_type} is null,
9471cb0ef41Sopenharmony_ci  // it takes the input from the input node {TypeOf(node->InputAt(index))}.
9481cb0ef41Sopenharmony_ci  void ConvertInput(Node* node, int index, UseInfo use,
9491cb0ef41Sopenharmony_ci                    Type input_type = Type::Invalid()) {
9501cb0ef41Sopenharmony_ci    // In the change phase, insert a change before the use if necessary.
9511cb0ef41Sopenharmony_ci    if (use.representation() == MachineRepresentation::kNone)
9521cb0ef41Sopenharmony_ci      return;  // No input requirement on the use.
9531cb0ef41Sopenharmony_ci    Node* input = node->InputAt(index);
9541cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(input);
9551cb0ef41Sopenharmony_ci    NodeInfo* input_info = GetInfo(input);
9561cb0ef41Sopenharmony_ci    MachineRepresentation input_rep = input_info->representation();
9571cb0ef41Sopenharmony_ci    if (input_rep != use.representation() ||
9581cb0ef41Sopenharmony_ci        use.type_check() != TypeCheckKind::kNone) {
9591cb0ef41Sopenharmony_ci      // Output representation doesn't match usage.
9601cb0ef41Sopenharmony_ci      TRACE("  change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(),
9611cb0ef41Sopenharmony_ci            index, input->id(), input->op()->mnemonic());
9621cb0ef41Sopenharmony_ci      TRACE("from %s to %s:%s\n",
9631cb0ef41Sopenharmony_ci            MachineReprToString(input_info->representation()),
9641cb0ef41Sopenharmony_ci            MachineReprToString(use.representation()),
9651cb0ef41Sopenharmony_ci            use.truncation().description());
9661cb0ef41Sopenharmony_ci      if (input_type.IsInvalid()) {
9671cb0ef41Sopenharmony_ci        input_type = TypeOf(input);
9681cb0ef41Sopenharmony_ci      }
9691cb0ef41Sopenharmony_ci      Node* n = changer_->GetRepresentationFor(input, input_rep, input_type,
9701cb0ef41Sopenharmony_ci                                               node, use);
9711cb0ef41Sopenharmony_ci      node->ReplaceInput(index, n);
9721cb0ef41Sopenharmony_ci    }
9731cb0ef41Sopenharmony_ci  }
9741cb0ef41Sopenharmony_ci
9751cb0ef41Sopenharmony_ci  template <Phase T>
9761cb0ef41Sopenharmony_ci  void ProcessInput(Node* node, int index, UseInfo use);
9771cb0ef41Sopenharmony_ci
9781cb0ef41Sopenharmony_ci  // Just assert for Retype and Lower. Propagate specialized below.
9791cb0ef41Sopenharmony_ci  template <Phase T>
9801cb0ef41Sopenharmony_ci  void ProcessRemainingInputs(Node* node, int index) {
9811cb0ef41Sopenharmony_ci    static_assert(retype<T>() || lower<T>(),
9821cb0ef41Sopenharmony_ci                  "This version of ProcessRemainingInputs has to be called in "
9831cb0ef41Sopenharmony_ci                  "the Retype or Lower phase.");
9841cb0ef41Sopenharmony_ci    DCHECK_GE(index, NodeProperties::PastValueIndex(node));
9851cb0ef41Sopenharmony_ci    DCHECK_GE(index, NodeProperties::PastContextIndex(node));
9861cb0ef41Sopenharmony_ci  }
9871cb0ef41Sopenharmony_ci
9881cb0ef41Sopenharmony_ci  // Marks node as a possible revisit since it is a use of input that will be
9891cb0ef41Sopenharmony_ci  // visited before input is visited.
9901cb0ef41Sopenharmony_ci  void MarkAsPossibleRevisit(Node* node, Node* input) {
9911cb0ef41Sopenharmony_ci    auto it = might_need_revisit_.find(input);
9921cb0ef41Sopenharmony_ci    if (it == might_need_revisit_.end()) {
9931cb0ef41Sopenharmony_ci      it = might_need_revisit_.insert({input, ZoneVector<Node*>(zone())}).first;
9941cb0ef41Sopenharmony_ci    }
9951cb0ef41Sopenharmony_ci    it->second.push_back(node);
9961cb0ef41Sopenharmony_ci    TRACE(" Marking #%d: %s as needing revisit due to #%d: %s\n", node->id(),
9971cb0ef41Sopenharmony_ci          node->op()->mnemonic(), input->id(), input->op()->mnemonic());
9981cb0ef41Sopenharmony_ci  }
9991cb0ef41Sopenharmony_ci
10001cb0ef41Sopenharmony_ci  // Just assert for Retype. Propagate and Lower specialized below.
10011cb0ef41Sopenharmony_ci  template <Phase T>
10021cb0ef41Sopenharmony_ci  void VisitInputs(Node* node) {
10031cb0ef41Sopenharmony_ci    static_assert(
10041cb0ef41Sopenharmony_ci        retype<T>(),
10051cb0ef41Sopenharmony_ci        "This version of VisitInputs has to be called in the Retype phase.");
10061cb0ef41Sopenharmony_ci  }
10071cb0ef41Sopenharmony_ci
10081cb0ef41Sopenharmony_ci  template <Phase T>
10091cb0ef41Sopenharmony_ci  void VisitReturn(Node* node) {
10101cb0ef41Sopenharmony_ci    int first_effect_index = NodeProperties::FirstEffectIndex(node);
10111cb0ef41Sopenharmony_ci    // Visit integer slot count to pop
10121cb0ef41Sopenharmony_ci    ProcessInput<T>(node, 0, UseInfo::TruncatingWord32());
10131cb0ef41Sopenharmony_ci
10141cb0ef41Sopenharmony_ci    // Visit value, context and frame state inputs as tagged.
10151cb0ef41Sopenharmony_ci    for (int i = 1; i < first_effect_index; i++) {
10161cb0ef41Sopenharmony_ci      ProcessInput<T>(node, i, UseInfo::AnyTagged());
10171cb0ef41Sopenharmony_ci    }
10181cb0ef41Sopenharmony_ci    // Only enqueue other inputs (effects, control).
10191cb0ef41Sopenharmony_ci    for (int i = first_effect_index; i < node->InputCount(); i++) {
10201cb0ef41Sopenharmony_ci      EnqueueInput<T>(node, i);
10211cb0ef41Sopenharmony_ci    }
10221cb0ef41Sopenharmony_ci  }
10231cb0ef41Sopenharmony_ci
10241cb0ef41Sopenharmony_ci  // Helper for an unused node.
10251cb0ef41Sopenharmony_ci  template <Phase T>
10261cb0ef41Sopenharmony_ci  void VisitUnused(Node* node) {
10271cb0ef41Sopenharmony_ci    int first_effect_index = NodeProperties::FirstEffectIndex(node);
10281cb0ef41Sopenharmony_ci    for (int i = 0; i < first_effect_index; i++) {
10291cb0ef41Sopenharmony_ci      ProcessInput<T>(node, i, UseInfo::None());
10301cb0ef41Sopenharmony_ci    }
10311cb0ef41Sopenharmony_ci    ProcessRemainingInputs<T>(node, first_effect_index);
10321cb0ef41Sopenharmony_ci
10331cb0ef41Sopenharmony_ci    if (lower<T>()) {
10341cb0ef41Sopenharmony_ci      TRACE("disconnecting unused #%d:%s\n", node->id(),
10351cb0ef41Sopenharmony_ci            node->op()->mnemonic());
10361cb0ef41Sopenharmony_ci      DisconnectFromEffectAndControl(node);
10371cb0ef41Sopenharmony_ci      node->NullAllInputs();  // Node is now dead.
10381cb0ef41Sopenharmony_ci      DeferReplacement(node, graph()->NewNode(common()->Plug()));
10391cb0ef41Sopenharmony_ci    }
10401cb0ef41Sopenharmony_ci  }
10411cb0ef41Sopenharmony_ci
10421cb0ef41Sopenharmony_ci  // Helper for no-op node.
10431cb0ef41Sopenharmony_ci  template <Phase T>
10441cb0ef41Sopenharmony_ci  void VisitNoop(Node* node, Truncation truncation) {
10451cb0ef41Sopenharmony_ci    if (truncation.IsUnused()) return VisitUnused<T>(node);
10461cb0ef41Sopenharmony_ci    MachineRepresentation representation =
10471cb0ef41Sopenharmony_ci        GetOutputInfoForPhi(node, TypeOf(node), truncation);
10481cb0ef41Sopenharmony_ci    VisitUnop<T>(node, UseInfo(representation, truncation), representation);
10491cb0ef41Sopenharmony_ci    if (lower<T>()) DeferReplacement(node, node->InputAt(0));
10501cb0ef41Sopenharmony_ci  }
10511cb0ef41Sopenharmony_ci
10521cb0ef41Sopenharmony_ci  // Helper for binops of the R x L -> O variety.
10531cb0ef41Sopenharmony_ci  template <Phase T>
10541cb0ef41Sopenharmony_ci  void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use,
10551cb0ef41Sopenharmony_ci                  MachineRepresentation output,
10561cb0ef41Sopenharmony_ci                  Type restriction_type = Type::Any()) {
10571cb0ef41Sopenharmony_ci    DCHECK_EQ(2, node->op()->ValueInputCount());
10581cb0ef41Sopenharmony_ci    ProcessInput<T>(node, 0, left_use);
10591cb0ef41Sopenharmony_ci    ProcessInput<T>(node, 1, right_use);
10601cb0ef41Sopenharmony_ci    for (int i = 2; i < node->InputCount(); i++) {
10611cb0ef41Sopenharmony_ci      EnqueueInput<T>(node, i);
10621cb0ef41Sopenharmony_ci    }
10631cb0ef41Sopenharmony_ci    SetOutput<T>(node, output, restriction_type);
10641cb0ef41Sopenharmony_ci  }
10651cb0ef41Sopenharmony_ci
10661cb0ef41Sopenharmony_ci  // Helper for binops of the I x I -> O variety.
10671cb0ef41Sopenharmony_ci  template <Phase T>
10681cb0ef41Sopenharmony_ci  void VisitBinop(Node* node, UseInfo input_use, MachineRepresentation output,
10691cb0ef41Sopenharmony_ci                  Type restriction_type = Type::Any()) {
10701cb0ef41Sopenharmony_ci    VisitBinop<T>(node, input_use, input_use, output, restriction_type);
10711cb0ef41Sopenharmony_ci  }
10721cb0ef41Sopenharmony_ci
10731cb0ef41Sopenharmony_ci  template <Phase T>
10741cb0ef41Sopenharmony_ci  void VisitSpeculativeInt32Binop(Node* node) {
10751cb0ef41Sopenharmony_ci    DCHECK_EQ(2, node->op()->ValueInputCount());
10761cb0ef41Sopenharmony_ci    if (BothInputsAre(node, Type::NumberOrOddball())) {
10771cb0ef41Sopenharmony_ci      return VisitBinop<T>(node, UseInfo::TruncatingWord32(),
10781cb0ef41Sopenharmony_ci                           MachineRepresentation::kWord32);
10791cb0ef41Sopenharmony_ci    }
10801cb0ef41Sopenharmony_ci    NumberOperationHint hint = NumberOperationHintOf(node->op());
10811cb0ef41Sopenharmony_ci    return VisitBinop<T>(node,
10821cb0ef41Sopenharmony_ci                         CheckedUseInfoAsWord32FromHint(hint, kIdentifyZeros),
10831cb0ef41Sopenharmony_ci                         MachineRepresentation::kWord32);
10841cb0ef41Sopenharmony_ci  }
10851cb0ef41Sopenharmony_ci
10861cb0ef41Sopenharmony_ci  // Helper for unops of the I -> O variety.
10871cb0ef41Sopenharmony_ci  template <Phase T>
10881cb0ef41Sopenharmony_ci  void VisitUnop(Node* node, UseInfo input_use, MachineRepresentation output,
10891cb0ef41Sopenharmony_ci                 Type restriction_type = Type::Any()) {
10901cb0ef41Sopenharmony_ci    DCHECK_EQ(1, node->op()->ValueInputCount());
10911cb0ef41Sopenharmony_ci    ProcessInput<T>(node, 0, input_use);
10921cb0ef41Sopenharmony_ci    ProcessRemainingInputs<T>(node, 1);
10931cb0ef41Sopenharmony_ci    SetOutput<T>(node, output, restriction_type);
10941cb0ef41Sopenharmony_ci  }
10951cb0ef41Sopenharmony_ci
10961cb0ef41Sopenharmony_ci  // Helper for leaf nodes.
10971cb0ef41Sopenharmony_ci  template <Phase T>
10981cb0ef41Sopenharmony_ci  void VisitLeaf(Node* node, MachineRepresentation output) {
10991cb0ef41Sopenharmony_ci    DCHECK_EQ(0, node->InputCount());
11001cb0ef41Sopenharmony_ci    SetOutput<T>(node, output);
11011cb0ef41Sopenharmony_ci  }
11021cb0ef41Sopenharmony_ci
11031cb0ef41Sopenharmony_ci  // Helpers for specific types of binops.
11041cb0ef41Sopenharmony_ci
11051cb0ef41Sopenharmony_ci  template <Phase T>
11061cb0ef41Sopenharmony_ci  void VisitFloat64Binop(Node* node) {
11071cb0ef41Sopenharmony_ci    VisitBinop<T>(node, UseInfo::TruncatingFloat64(),
11081cb0ef41Sopenharmony_ci                  MachineRepresentation::kFloat64);
11091cb0ef41Sopenharmony_ci  }
11101cb0ef41Sopenharmony_ci
11111cb0ef41Sopenharmony_ci  template <Phase T>
11121cb0ef41Sopenharmony_ci  void VisitInt64Binop(Node* node) {
11131cb0ef41Sopenharmony_ci    VisitBinop<T>(node, UseInfo::Word64(), MachineRepresentation::kWord64);
11141cb0ef41Sopenharmony_ci  }
11151cb0ef41Sopenharmony_ci
11161cb0ef41Sopenharmony_ci  template <Phase T>
11171cb0ef41Sopenharmony_ci  void VisitWord32TruncatingBinop(Node* node) {
11181cb0ef41Sopenharmony_ci    VisitBinop<T>(node, UseInfo::TruncatingWord32(),
11191cb0ef41Sopenharmony_ci                  MachineRepresentation::kWord32);
11201cb0ef41Sopenharmony_ci  }
11211cb0ef41Sopenharmony_ci
11221cb0ef41Sopenharmony_ci  // Infer representation for phi-like nodes.
11231cb0ef41Sopenharmony_ci  // The {node} parameter is only used to decide on the int64 representation.
11241cb0ef41Sopenharmony_ci  // Once the type system supports an external pointer type, the {node}
11251cb0ef41Sopenharmony_ci  // parameter can be removed.
11261cb0ef41Sopenharmony_ci  MachineRepresentation GetOutputInfoForPhi(Node* node, Type type,
11271cb0ef41Sopenharmony_ci                                            Truncation use) {
11281cb0ef41Sopenharmony_ci    // Compute the representation.
11291cb0ef41Sopenharmony_ci    if (type.Is(Type::None())) {
11301cb0ef41Sopenharmony_ci      return MachineRepresentation::kNone;
11311cb0ef41Sopenharmony_ci    } else if (type.Is(Type::Signed32()) || type.Is(Type::Unsigned32())) {
11321cb0ef41Sopenharmony_ci      return MachineRepresentation::kWord32;
11331cb0ef41Sopenharmony_ci    } else if (type.Is(Type::NumberOrOddball()) && use.IsUsedAsWord32()) {
11341cb0ef41Sopenharmony_ci      return MachineRepresentation::kWord32;
11351cb0ef41Sopenharmony_ci    } else if (type.Is(Type::Boolean())) {
11361cb0ef41Sopenharmony_ci      return MachineRepresentation::kBit;
11371cb0ef41Sopenharmony_ci    } else if (type.Is(Type::NumberOrOddball()) &&
11381cb0ef41Sopenharmony_ci               use.TruncatesOddballAndBigIntToNumber()) {
11391cb0ef41Sopenharmony_ci      return MachineRepresentation::kFloat64;
11401cb0ef41Sopenharmony_ci    } else if (type.Is(Type::Union(Type::SignedSmall(), Type::NaN(), zone()))) {
11411cb0ef41Sopenharmony_ci      // TODO(turbofan): For Phis that return either NaN or some Smi, it's
11421cb0ef41Sopenharmony_ci      // beneficial to not go all the way to double, unless the uses are
11431cb0ef41Sopenharmony_ci      // double uses. For tagging that just means some potentially expensive
11441cb0ef41Sopenharmony_ci      // allocation code; we might want to do the same for -0 as well?
11451cb0ef41Sopenharmony_ci      return MachineRepresentation::kTagged;
11461cb0ef41Sopenharmony_ci    } else if (type.Is(Type::Number())) {
11471cb0ef41Sopenharmony_ci      return MachineRepresentation::kFloat64;
11481cb0ef41Sopenharmony_ci    } else if (type.Is(Type::BigInt()) && use.IsUsedAsWord64()) {
11491cb0ef41Sopenharmony_ci      return MachineRepresentation::kWord64;
11501cb0ef41Sopenharmony_ci    } else if (type.Is(Type::ExternalPointer()) ||
11511cb0ef41Sopenharmony_ci               type.Is(Type::SandboxedPointer())) {
11521cb0ef41Sopenharmony_ci      return MachineType::PointerRepresentation();
11531cb0ef41Sopenharmony_ci    }
11541cb0ef41Sopenharmony_ci    return MachineRepresentation::kTagged;
11551cb0ef41Sopenharmony_ci  }
11561cb0ef41Sopenharmony_ci
11571cb0ef41Sopenharmony_ci  // Helper for handling selects.
11581cb0ef41Sopenharmony_ci  template <Phase T>
11591cb0ef41Sopenharmony_ci  void VisitSelect(Node* node, Truncation truncation,
11601cb0ef41Sopenharmony_ci                   SimplifiedLowering* lowering) {
11611cb0ef41Sopenharmony_ci    DCHECK(TypeOf(node->InputAt(0)).Is(Type::Boolean()));
11621cb0ef41Sopenharmony_ci    ProcessInput<T>(node, 0, UseInfo::Bool());
11631cb0ef41Sopenharmony_ci
11641cb0ef41Sopenharmony_ci    MachineRepresentation output =
11651cb0ef41Sopenharmony_ci        GetOutputInfoForPhi(node, TypeOf(node), truncation);
11661cb0ef41Sopenharmony_ci    SetOutput<T>(node, output);
11671cb0ef41Sopenharmony_ci
11681cb0ef41Sopenharmony_ci    if (lower<T>()) {
11691cb0ef41Sopenharmony_ci      // Update the select operator.
11701cb0ef41Sopenharmony_ci      SelectParameters p = SelectParametersOf(node->op());
11711cb0ef41Sopenharmony_ci      if (output != p.representation()) {
11721cb0ef41Sopenharmony_ci        ChangeOp(node, lowering->common()->Select(output, p.hint()));
11731cb0ef41Sopenharmony_ci      }
11741cb0ef41Sopenharmony_ci    }
11751cb0ef41Sopenharmony_ci    // Convert inputs to the output representation of this phi, pass the
11761cb0ef41Sopenharmony_ci    // truncation truncation along.
11771cb0ef41Sopenharmony_ci    UseInfo input_use(output, truncation);
11781cb0ef41Sopenharmony_ci    ProcessInput<T>(node, 1, input_use);
11791cb0ef41Sopenharmony_ci    ProcessInput<T>(node, 2, input_use);
11801cb0ef41Sopenharmony_ci  }
11811cb0ef41Sopenharmony_ci
11821cb0ef41Sopenharmony_ci  // Helper for handling phis.
11831cb0ef41Sopenharmony_ci  template <Phase T>
11841cb0ef41Sopenharmony_ci  void VisitPhi(Node* node, Truncation truncation,
11851cb0ef41Sopenharmony_ci                SimplifiedLowering* lowering) {
11861cb0ef41Sopenharmony_ci    MachineRepresentation output =
11871cb0ef41Sopenharmony_ci        GetOutputInfoForPhi(node, TypeOf(node), truncation);
11881cb0ef41Sopenharmony_ci    // Only set the output representation if not running with type
11891cb0ef41Sopenharmony_ci    // feedback. (Feedback typing will set the representation.)
11901cb0ef41Sopenharmony_ci    SetOutput<T>(node, output);
11911cb0ef41Sopenharmony_ci
11921cb0ef41Sopenharmony_ci    int values = node->op()->ValueInputCount();
11931cb0ef41Sopenharmony_ci    if (lower<T>()) {
11941cb0ef41Sopenharmony_ci      // Update the phi operator.
11951cb0ef41Sopenharmony_ci      if (output != PhiRepresentationOf(node->op())) {
11961cb0ef41Sopenharmony_ci        ChangeOp(node, lowering->common()->Phi(output, values));
11971cb0ef41Sopenharmony_ci      }
11981cb0ef41Sopenharmony_ci    }
11991cb0ef41Sopenharmony_ci
12001cb0ef41Sopenharmony_ci    // Convert inputs to the output representation of this phi, pass the
12011cb0ef41Sopenharmony_ci    // truncation along.
12021cb0ef41Sopenharmony_ci    UseInfo input_use(output, truncation);
12031cb0ef41Sopenharmony_ci    for (int i = 0; i < node->InputCount(); i++) {
12041cb0ef41Sopenharmony_ci      ProcessInput<T>(node, i, i < values ? input_use : UseInfo::None());
12051cb0ef41Sopenharmony_ci    }
12061cb0ef41Sopenharmony_ci  }
12071cb0ef41Sopenharmony_ci
12081cb0ef41Sopenharmony_ci  template <Phase T>
12091cb0ef41Sopenharmony_ci  void VisitObjectIs(Node* node, Type type, SimplifiedLowering* lowering) {
12101cb0ef41Sopenharmony_ci    Type const input_type = TypeOf(node->InputAt(0));
12111cb0ef41Sopenharmony_ci    if (input_type.Is(type)) {
12121cb0ef41Sopenharmony_ci      VisitUnop<T>(node, UseInfo::None(), MachineRepresentation::kBit);
12131cb0ef41Sopenharmony_ci      if (lower<T>()) {
12141cb0ef41Sopenharmony_ci        DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
12151cb0ef41Sopenharmony_ci      }
12161cb0ef41Sopenharmony_ci    } else {
12171cb0ef41Sopenharmony_ci      VisitUnop<T>(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
12181cb0ef41Sopenharmony_ci      if (lower<T>() && !input_type.Maybe(type)) {
12191cb0ef41Sopenharmony_ci        DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
12201cb0ef41Sopenharmony_ci      }
12211cb0ef41Sopenharmony_ci    }
12221cb0ef41Sopenharmony_ci  }
12231cb0ef41Sopenharmony_ci
12241cb0ef41Sopenharmony_ci  template <Phase T>
12251cb0ef41Sopenharmony_ci  void VisitCheck(Node* node, Type type, SimplifiedLowering* lowering) {
12261cb0ef41Sopenharmony_ci    if (InputIs(node, type)) {
12271cb0ef41Sopenharmony_ci      VisitUnop<T>(node, UseInfo::AnyTagged(),
12281cb0ef41Sopenharmony_ci                   MachineRepresentation::kTaggedPointer);
12291cb0ef41Sopenharmony_ci      if (lower<T>()) DeferReplacement(node, node->InputAt(0));
12301cb0ef41Sopenharmony_ci    } else {
12311cb0ef41Sopenharmony_ci      VisitUnop<T>(node,
12321cb0ef41Sopenharmony_ci                   UseInfo::CheckedHeapObjectAsTaggedPointer(FeedbackSource()),
12331cb0ef41Sopenharmony_ci                   MachineRepresentation::kTaggedPointer);
12341cb0ef41Sopenharmony_ci    }
12351cb0ef41Sopenharmony_ci  }
12361cb0ef41Sopenharmony_ci
12371cb0ef41Sopenharmony_ci  template <Phase T>
12381cb0ef41Sopenharmony_ci  void VisitCall(Node* node, SimplifiedLowering* lowering) {
12391cb0ef41Sopenharmony_ci    auto call_descriptor = CallDescriptorOf(node->op());
12401cb0ef41Sopenharmony_ci    int params = static_cast<int>(call_descriptor->ParameterCount());
12411cb0ef41Sopenharmony_ci    int value_input_count = node->op()->ValueInputCount();
12421cb0ef41Sopenharmony_ci
12431cb0ef41Sopenharmony_ci    DCHECK_GT(value_input_count, 0);
12441cb0ef41Sopenharmony_ci    DCHECK_GE(value_input_count, params);
12451cb0ef41Sopenharmony_ci
12461cb0ef41Sopenharmony_ci    // The target of the call.
12471cb0ef41Sopenharmony_ci    ProcessInput<T>(node, 0, UseInfo::Any());
12481cb0ef41Sopenharmony_ci
12491cb0ef41Sopenharmony_ci    // For the parameters (indexes [1, ..., params]), propagate representation
12501cb0ef41Sopenharmony_ci    // information from call descriptor.
12511cb0ef41Sopenharmony_ci    for (int i = 1; i <= params; i++) {
12521cb0ef41Sopenharmony_ci      ProcessInput<T>(node, i,
12531cb0ef41Sopenharmony_ci                      TruncatingUseInfoFromRepresentation(
12541cb0ef41Sopenharmony_ci                          call_descriptor->GetInputType(i).representation()));
12551cb0ef41Sopenharmony_ci    }
12561cb0ef41Sopenharmony_ci
12571cb0ef41Sopenharmony_ci    // Rest of the value inputs.
12581cb0ef41Sopenharmony_ci    for (int i = params + 1; i < value_input_count; i++) {
12591cb0ef41Sopenharmony_ci      ProcessInput<T>(node, i, UseInfo::AnyTagged());
12601cb0ef41Sopenharmony_ci    }
12611cb0ef41Sopenharmony_ci
12621cb0ef41Sopenharmony_ci    // Effect and Control.
12631cb0ef41Sopenharmony_ci    ProcessRemainingInputs<T>(node, value_input_count);
12641cb0ef41Sopenharmony_ci
12651cb0ef41Sopenharmony_ci    if (call_descriptor->ReturnCount() > 0) {
12661cb0ef41Sopenharmony_ci      SetOutput<T>(node, call_descriptor->GetReturnType(0).representation());
12671cb0ef41Sopenharmony_ci    } else {
12681cb0ef41Sopenharmony_ci      SetOutput<T>(node, MachineRepresentation::kTagged);
12691cb0ef41Sopenharmony_ci    }
12701cb0ef41Sopenharmony_ci  }
12711cb0ef41Sopenharmony_ci
12721cb0ef41Sopenharmony_ci  void MaskShiftOperand(Node* node, Type rhs_type) {
12731cb0ef41Sopenharmony_ci    if (!rhs_type.Is(type_cache_->kZeroToThirtyOne)) {
12741cb0ef41Sopenharmony_ci      Node* const rhs = NodeProperties::GetValueInput(node, 1);
12751cb0ef41Sopenharmony_ci      node->ReplaceInput(1,
12761cb0ef41Sopenharmony_ci                         graph()->NewNode(jsgraph_->machine()->Word32And(), rhs,
12771cb0ef41Sopenharmony_ci                                          jsgraph_->Int32Constant(0x1F)));
12781cb0ef41Sopenharmony_ci    }
12791cb0ef41Sopenharmony_ci  }
12801cb0ef41Sopenharmony_ci
12811cb0ef41Sopenharmony_ci  static MachineSemantic DeoptValueSemanticOf(Type type) {
12821cb0ef41Sopenharmony_ci    // We only need signedness to do deopt correctly.
12831cb0ef41Sopenharmony_ci    if (type.Is(Type::Signed32())) {
12841cb0ef41Sopenharmony_ci      return MachineSemantic::kInt32;
12851cb0ef41Sopenharmony_ci    } else if (type.Is(Type::Unsigned32())) {
12861cb0ef41Sopenharmony_ci      return MachineSemantic::kUint32;
12871cb0ef41Sopenharmony_ci    } else {
12881cb0ef41Sopenharmony_ci      return MachineSemantic::kAny;
12891cb0ef41Sopenharmony_ci    }
12901cb0ef41Sopenharmony_ci  }
12911cb0ef41Sopenharmony_ci
12921cb0ef41Sopenharmony_ci  static MachineType DeoptMachineTypeOf(MachineRepresentation rep, Type type) {
12931cb0ef41Sopenharmony_ci    if (type.IsNone()) {
12941cb0ef41Sopenharmony_ci      return MachineType::None();
12951cb0ef41Sopenharmony_ci    }
12961cb0ef41Sopenharmony_ci    // Do not distinguish between various Tagged variations.
12971cb0ef41Sopenharmony_ci    if (IsAnyTagged(rep)) {
12981cb0ef41Sopenharmony_ci      return MachineType::AnyTagged();
12991cb0ef41Sopenharmony_ci    }
13001cb0ef41Sopenharmony_ci    if (rep == MachineRepresentation::kWord64) {
13011cb0ef41Sopenharmony_ci      if (type.Is(Type::BigInt())) {
13021cb0ef41Sopenharmony_ci        return MachineType::AnyTagged();
13031cb0ef41Sopenharmony_ci      }
13041cb0ef41Sopenharmony_ci
13051cb0ef41Sopenharmony_ci      DCHECK(type.Is(TypeCache::Get()->kSafeInteger));
13061cb0ef41Sopenharmony_ci      return MachineType(rep, MachineSemantic::kInt64);
13071cb0ef41Sopenharmony_ci    }
13081cb0ef41Sopenharmony_ci    MachineType machine_type(rep, DeoptValueSemanticOf(type));
13091cb0ef41Sopenharmony_ci    DCHECK(machine_type.representation() != MachineRepresentation::kWord32 ||
13101cb0ef41Sopenharmony_ci           machine_type.semantic() == MachineSemantic::kInt32 ||
13111cb0ef41Sopenharmony_ci           machine_type.semantic() == MachineSemantic::kUint32);
13121cb0ef41Sopenharmony_ci    DCHECK(machine_type.representation() != MachineRepresentation::kBit ||
13131cb0ef41Sopenharmony_ci           type.Is(Type::Boolean()));
13141cb0ef41Sopenharmony_ci    return machine_type;
13151cb0ef41Sopenharmony_ci  }
13161cb0ef41Sopenharmony_ci
13171cb0ef41Sopenharmony_ci  template <Phase T>
13181cb0ef41Sopenharmony_ci  void VisitStateValues(Node* node) {
13191cb0ef41Sopenharmony_ci    if (propagate<T>()) {
13201cb0ef41Sopenharmony_ci      for (int i = 0; i < node->InputCount(); i++) {
13211cb0ef41Sopenharmony_ci        // When lowering 64 bit BigInts to Word64 representation, we have to
13221cb0ef41Sopenharmony_ci        // make sure they are rematerialized before deoptimization. By
13231cb0ef41Sopenharmony_ci        // propagating a AnyTagged use, the RepresentationChanger is going to
13241cb0ef41Sopenharmony_ci        // insert the necessary conversions.
13251cb0ef41Sopenharmony_ci        // TODO(nicohartmann): Remove, once the deoptimizer can rematerialize
13261cb0ef41Sopenharmony_ci        // truncated BigInts.
13271cb0ef41Sopenharmony_ci        if (TypeOf(node->InputAt(i)).Is(Type::BigInt())) {
13281cb0ef41Sopenharmony_ci          EnqueueInput<T>(node, i, UseInfo::AnyTagged());
13291cb0ef41Sopenharmony_ci        } else {
13301cb0ef41Sopenharmony_ci          EnqueueInput<T>(node, i, UseInfo::Any());
13311cb0ef41Sopenharmony_ci        }
13321cb0ef41Sopenharmony_ci      }
13331cb0ef41Sopenharmony_ci    } else if (lower<T>()) {
13341cb0ef41Sopenharmony_ci      Zone* zone = jsgraph_->zone();
13351cb0ef41Sopenharmony_ci      ZoneVector<MachineType>* types =
13361cb0ef41Sopenharmony_ci          zone->New<ZoneVector<MachineType>>(node->InputCount(), zone);
13371cb0ef41Sopenharmony_ci      for (int i = 0; i < node->InputCount(); i++) {
13381cb0ef41Sopenharmony_ci        Node* input = node->InputAt(i);
13391cb0ef41Sopenharmony_ci        // TODO(nicohartmann): Remove, once the deoptimizer can rematerialize
13401cb0ef41Sopenharmony_ci        // truncated BigInts.
13411cb0ef41Sopenharmony_ci        if (TypeOf(input).Is(Type::BigInt())) {
13421cb0ef41Sopenharmony_ci          ConvertInput(node, i, UseInfo::AnyTagged());
13431cb0ef41Sopenharmony_ci        }
13441cb0ef41Sopenharmony_ci
13451cb0ef41Sopenharmony_ci        (*types)[i] =
13461cb0ef41Sopenharmony_ci            DeoptMachineTypeOf(GetInfo(input)->representation(), TypeOf(input));
13471cb0ef41Sopenharmony_ci      }
13481cb0ef41Sopenharmony_ci      SparseInputMask mask = SparseInputMaskOf(node->op());
13491cb0ef41Sopenharmony_ci      ChangeOp(node, common()->TypedStateValues(types, mask));
13501cb0ef41Sopenharmony_ci    }
13511cb0ef41Sopenharmony_ci    SetOutput<T>(node, MachineRepresentation::kTagged);
13521cb0ef41Sopenharmony_ci  }
13531cb0ef41Sopenharmony_ci
13541cb0ef41Sopenharmony_ci  template <Phase T>
13551cb0ef41Sopenharmony_ci  void VisitFrameState(FrameState node) {
13561cb0ef41Sopenharmony_ci    DCHECK_EQ(5, node->op()->ValueInputCount());
13571cb0ef41Sopenharmony_ci    DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
13581cb0ef41Sopenharmony_ci    DCHECK_EQ(FrameState::kFrameStateInputCount, node->InputCount());
13591cb0ef41Sopenharmony_ci
13601cb0ef41Sopenharmony_ci    ProcessInput<T>(node, FrameState::kFrameStateParametersInput,
13611cb0ef41Sopenharmony_ci                    UseInfo::AnyTagged());
13621cb0ef41Sopenharmony_ci    ProcessInput<T>(node, FrameState::kFrameStateLocalsInput,
13631cb0ef41Sopenharmony_ci                    UseInfo::AnyTagged());
13641cb0ef41Sopenharmony_ci
13651cb0ef41Sopenharmony_ci    // Accumulator is a special flower - we need to remember its type in
13661cb0ef41Sopenharmony_ci    // a singleton typed-state-values node (as if it was a singleton
13671cb0ef41Sopenharmony_ci    // state-values node).
13681cb0ef41Sopenharmony_ci    Node* accumulator = node.stack();
13691cb0ef41Sopenharmony_ci    if (propagate<T>()) {
13701cb0ef41Sopenharmony_ci      // TODO(nicohartmann): Remove, once the deoptimizer can rematerialize
13711cb0ef41Sopenharmony_ci      // truncated BigInts.
13721cb0ef41Sopenharmony_ci      if (TypeOf(accumulator).Is(Type::BigInt())) {
13731cb0ef41Sopenharmony_ci        EnqueueInput<T>(node, FrameState::kFrameStateStackInput,
13741cb0ef41Sopenharmony_ci                        UseInfo::AnyTagged());
13751cb0ef41Sopenharmony_ci      } else {
13761cb0ef41Sopenharmony_ci        EnqueueInput<T>(node, FrameState::kFrameStateStackInput,
13771cb0ef41Sopenharmony_ci                        UseInfo::Any());
13781cb0ef41Sopenharmony_ci      }
13791cb0ef41Sopenharmony_ci    } else if (lower<T>()) {
13801cb0ef41Sopenharmony_ci      // TODO(nicohartmann): Remove, once the deoptimizer can rematerialize
13811cb0ef41Sopenharmony_ci      // truncated BigInts.
13821cb0ef41Sopenharmony_ci      if (TypeOf(accumulator).Is(Type::BigInt())) {
13831cb0ef41Sopenharmony_ci        ConvertInput(node, FrameState::kFrameStateStackInput,
13841cb0ef41Sopenharmony_ci                     UseInfo::AnyTagged());
13851cb0ef41Sopenharmony_ci      }
13861cb0ef41Sopenharmony_ci      Zone* zone = jsgraph_->zone();
13871cb0ef41Sopenharmony_ci      if (accumulator == jsgraph_->OptimizedOutConstant()) {
13881cb0ef41Sopenharmony_ci        node->ReplaceInput(FrameState::kFrameStateStackInput,
13891cb0ef41Sopenharmony_ci                           jsgraph_->SingleDeadTypedStateValues());
13901cb0ef41Sopenharmony_ci      } else {
13911cb0ef41Sopenharmony_ci        ZoneVector<MachineType>* types =
13921cb0ef41Sopenharmony_ci            zone->New<ZoneVector<MachineType>>(1, zone);
13931cb0ef41Sopenharmony_ci        (*types)[0] = DeoptMachineTypeOf(GetInfo(accumulator)->representation(),
13941cb0ef41Sopenharmony_ci                                         TypeOf(accumulator));
13951cb0ef41Sopenharmony_ci
13961cb0ef41Sopenharmony_ci        node->ReplaceInput(
13971cb0ef41Sopenharmony_ci            FrameState::kFrameStateStackInput,
13981cb0ef41Sopenharmony_ci            jsgraph_->graph()->NewNode(
13991cb0ef41Sopenharmony_ci                common()->TypedStateValues(types, SparseInputMask::Dense()),
14001cb0ef41Sopenharmony_ci                node.stack()));
14011cb0ef41Sopenharmony_ci      }
14021cb0ef41Sopenharmony_ci    }
14031cb0ef41Sopenharmony_ci
14041cb0ef41Sopenharmony_ci    ProcessInput<T>(node, FrameState::kFrameStateContextInput,
14051cb0ef41Sopenharmony_ci                    UseInfo::AnyTagged());
14061cb0ef41Sopenharmony_ci    ProcessInput<T>(node, FrameState::kFrameStateFunctionInput,
14071cb0ef41Sopenharmony_ci                    UseInfo::AnyTagged());
14081cb0ef41Sopenharmony_ci    ProcessInput<T>(node, FrameState::kFrameStateOuterStateInput,
14091cb0ef41Sopenharmony_ci                    UseInfo::AnyTagged());
14101cb0ef41Sopenharmony_ci    return SetOutput<T>(node, MachineRepresentation::kTagged);
14111cb0ef41Sopenharmony_ci  }
14121cb0ef41Sopenharmony_ci
14131cb0ef41Sopenharmony_ci  template <Phase T>
14141cb0ef41Sopenharmony_ci  void VisitObjectState(Node* node) {
14151cb0ef41Sopenharmony_ci    if (propagate<T>()) {
14161cb0ef41Sopenharmony_ci      for (int i = 0; i < node->InputCount(); i++) {
14171cb0ef41Sopenharmony_ci        // TODO(nicohartmann): Remove, once the deoptimizer can rematerialize
14181cb0ef41Sopenharmony_ci        // truncated BigInts.
14191cb0ef41Sopenharmony_ci        if (TypeOf(node->InputAt(i)).Is(Type::BigInt())) {
14201cb0ef41Sopenharmony_ci          EnqueueInput<T>(node, i, UseInfo::AnyTagged());
14211cb0ef41Sopenharmony_ci        } else {
14221cb0ef41Sopenharmony_ci          EnqueueInput<T>(node, i, UseInfo::Any());
14231cb0ef41Sopenharmony_ci        }
14241cb0ef41Sopenharmony_ci      }
14251cb0ef41Sopenharmony_ci    } else if (lower<T>()) {
14261cb0ef41Sopenharmony_ci      Zone* zone = jsgraph_->zone();
14271cb0ef41Sopenharmony_ci      ZoneVector<MachineType>* types =
14281cb0ef41Sopenharmony_ci          zone->New<ZoneVector<MachineType>>(node->InputCount(), zone);
14291cb0ef41Sopenharmony_ci      for (int i = 0; i < node->InputCount(); i++) {
14301cb0ef41Sopenharmony_ci        Node* input = node->InputAt(i);
14311cb0ef41Sopenharmony_ci        (*types)[i] =
14321cb0ef41Sopenharmony_ci            DeoptMachineTypeOf(GetInfo(input)->representation(), TypeOf(input));
14331cb0ef41Sopenharmony_ci        // TODO(nicohartmann): Remove, once the deoptimizer can rematerialize
14341cb0ef41Sopenharmony_ci        // truncated BigInts.
14351cb0ef41Sopenharmony_ci        if (TypeOf(node->InputAt(i)).Is(Type::BigInt())) {
14361cb0ef41Sopenharmony_ci          ConvertInput(node, i, UseInfo::AnyTagged());
14371cb0ef41Sopenharmony_ci        }
14381cb0ef41Sopenharmony_ci      }
14391cb0ef41Sopenharmony_ci      ChangeOp(node, common()->TypedObjectState(ObjectIdOf(node->op()), types));
14401cb0ef41Sopenharmony_ci    }
14411cb0ef41Sopenharmony_ci    SetOutput<T>(node, MachineRepresentation::kTagged);
14421cb0ef41Sopenharmony_ci  }
14431cb0ef41Sopenharmony_ci
14441cb0ef41Sopenharmony_ci  const Operator* Int32Op(Node* node) {
14451cb0ef41Sopenharmony_ci    return changer_->Int32OperatorFor(node->opcode());
14461cb0ef41Sopenharmony_ci  }
14471cb0ef41Sopenharmony_ci
14481cb0ef41Sopenharmony_ci  const Operator* Int32OverflowOp(Node* node) {
14491cb0ef41Sopenharmony_ci    return changer_->Int32OverflowOperatorFor(node->opcode());
14501cb0ef41Sopenharmony_ci  }
14511cb0ef41Sopenharmony_ci
14521cb0ef41Sopenharmony_ci  const Operator* Int64Op(Node* node) {
14531cb0ef41Sopenharmony_ci    return changer_->Int64OperatorFor(node->opcode());
14541cb0ef41Sopenharmony_ci  }
14551cb0ef41Sopenharmony_ci
14561cb0ef41Sopenharmony_ci  const Operator* Uint32Op(Node* node) {
14571cb0ef41Sopenharmony_ci    return changer_->Uint32OperatorFor(node->opcode());
14581cb0ef41Sopenharmony_ci  }
14591cb0ef41Sopenharmony_ci
14601cb0ef41Sopenharmony_ci  const Operator* Uint32OverflowOp(Node* node) {
14611cb0ef41Sopenharmony_ci    return changer_->Uint32OverflowOperatorFor(node->opcode());
14621cb0ef41Sopenharmony_ci  }
14631cb0ef41Sopenharmony_ci
14641cb0ef41Sopenharmony_ci  const Operator* Float64Op(Node* node) {
14651cb0ef41Sopenharmony_ci    return changer_->Float64OperatorFor(node->opcode());
14661cb0ef41Sopenharmony_ci  }
14671cb0ef41Sopenharmony_ci
14681cb0ef41Sopenharmony_ci  WriteBarrierKind WriteBarrierKindFor(
14691cb0ef41Sopenharmony_ci      BaseTaggedness base_taggedness,
14701cb0ef41Sopenharmony_ci      MachineRepresentation field_representation, Type field_type,
14711cb0ef41Sopenharmony_ci      MachineRepresentation value_representation, Node* value) {
14721cb0ef41Sopenharmony_ci    if (base_taggedness == kTaggedBase &&
14731cb0ef41Sopenharmony_ci        CanBeTaggedPointer(field_representation)) {
14741cb0ef41Sopenharmony_ci      Type value_type = NodeProperties::GetType(value);
14751cb0ef41Sopenharmony_ci      if (value_representation == MachineRepresentation::kTaggedSigned) {
14761cb0ef41Sopenharmony_ci        // Write barriers are only for stores of heap objects.
14771cb0ef41Sopenharmony_ci        return kNoWriteBarrier;
14781cb0ef41Sopenharmony_ci      }
14791cb0ef41Sopenharmony_ci      if (field_type.Is(Type::BooleanOrNullOrUndefined()) ||
14801cb0ef41Sopenharmony_ci          value_type.Is(Type::BooleanOrNullOrUndefined())) {
14811cb0ef41Sopenharmony_ci        // Write barriers are not necessary when storing true, false, null or
14821cb0ef41Sopenharmony_ci        // undefined, because these special oddballs are always in the root set.
14831cb0ef41Sopenharmony_ci        return kNoWriteBarrier;
14841cb0ef41Sopenharmony_ci      }
14851cb0ef41Sopenharmony_ci      if (value_type.IsHeapConstant()) {
14861cb0ef41Sopenharmony_ci        RootIndex root_index;
14871cb0ef41Sopenharmony_ci        const RootsTable& roots_table = jsgraph_->isolate()->roots_table();
14881cb0ef41Sopenharmony_ci        if (roots_table.IsRootHandle(value_type.AsHeapConstant()->Value(),
14891cb0ef41Sopenharmony_ci                                     &root_index)) {
14901cb0ef41Sopenharmony_ci          if (RootsTable::IsImmortalImmovable(root_index)) {
14911cb0ef41Sopenharmony_ci            // Write barriers are unnecessary for immortal immovable roots.
14921cb0ef41Sopenharmony_ci            return kNoWriteBarrier;
14931cb0ef41Sopenharmony_ci          }
14941cb0ef41Sopenharmony_ci        }
14951cb0ef41Sopenharmony_ci      }
14961cb0ef41Sopenharmony_ci      if (field_representation == MachineRepresentation::kTaggedPointer ||
14971cb0ef41Sopenharmony_ci          value_representation == MachineRepresentation::kTaggedPointer) {
14981cb0ef41Sopenharmony_ci        // Write barriers for heap objects are cheaper.
14991cb0ef41Sopenharmony_ci        return kPointerWriteBarrier;
15001cb0ef41Sopenharmony_ci      }
15011cb0ef41Sopenharmony_ci      NumberMatcher m(value);
15021cb0ef41Sopenharmony_ci      if (m.HasResolvedValue()) {
15031cb0ef41Sopenharmony_ci        if (IsSmiDouble(m.ResolvedValue())) {
15041cb0ef41Sopenharmony_ci          // Storing a smi doesn't need a write barrier.
15051cb0ef41Sopenharmony_ci          return kNoWriteBarrier;
15061cb0ef41Sopenharmony_ci        }
15071cb0ef41Sopenharmony_ci        // The NumberConstant will be represented as HeapNumber.
15081cb0ef41Sopenharmony_ci        return kPointerWriteBarrier;
15091cb0ef41Sopenharmony_ci      }
15101cb0ef41Sopenharmony_ci      return kFullWriteBarrier;
15111cb0ef41Sopenharmony_ci    }
15121cb0ef41Sopenharmony_ci    return kNoWriteBarrier;
15131cb0ef41Sopenharmony_ci  }
15141cb0ef41Sopenharmony_ci
15151cb0ef41Sopenharmony_ci  WriteBarrierKind WriteBarrierKindFor(
15161cb0ef41Sopenharmony_ci      BaseTaggedness base_taggedness,
15171cb0ef41Sopenharmony_ci      MachineRepresentation field_representation, int field_offset,
15181cb0ef41Sopenharmony_ci      Type field_type, MachineRepresentation value_representation,
15191cb0ef41Sopenharmony_ci      Node* value) {
15201cb0ef41Sopenharmony_ci    WriteBarrierKind write_barrier_kind =
15211cb0ef41Sopenharmony_ci        WriteBarrierKindFor(base_taggedness, field_representation, field_type,
15221cb0ef41Sopenharmony_ci                            value_representation, value);
15231cb0ef41Sopenharmony_ci    if (write_barrier_kind != kNoWriteBarrier) {
15241cb0ef41Sopenharmony_ci      if (base_taggedness == kTaggedBase &&
15251cb0ef41Sopenharmony_ci          field_offset == HeapObject::kMapOffset) {
15261cb0ef41Sopenharmony_ci        write_barrier_kind = kMapWriteBarrier;
15271cb0ef41Sopenharmony_ci      }
15281cb0ef41Sopenharmony_ci    }
15291cb0ef41Sopenharmony_ci    return write_barrier_kind;
15301cb0ef41Sopenharmony_ci  }
15311cb0ef41Sopenharmony_ci
15321cb0ef41Sopenharmony_ci  Graph* graph() const { return jsgraph_->graph(); }
15331cb0ef41Sopenharmony_ci  CommonOperatorBuilder* common() const { return jsgraph_->common(); }
15341cb0ef41Sopenharmony_ci  SimplifiedOperatorBuilder* simplified() const {
15351cb0ef41Sopenharmony_ci    return jsgraph_->simplified();
15361cb0ef41Sopenharmony_ci  }
15371cb0ef41Sopenharmony_ci
15381cb0ef41Sopenharmony_ci  template <Phase T>
15391cb0ef41Sopenharmony_ci  void VisitForCheckedInt32Mul(Node* node, Truncation truncation,
15401cb0ef41Sopenharmony_ci                               Type input0_type, Type input1_type,
15411cb0ef41Sopenharmony_ci                               UseInfo input_use) {
15421cb0ef41Sopenharmony_ci    DCHECK_EQ(node->opcode(), IrOpcode::kSpeculativeNumberMultiply);
15431cb0ef41Sopenharmony_ci    // A -0 input is impossible or will cause a deopt.
15441cb0ef41Sopenharmony_ci    DCHECK(BothInputsAre(node, Type::Signed32()) ||
15451cb0ef41Sopenharmony_ci           !input_use.truncation().IdentifiesZeroAndMinusZero());
15461cb0ef41Sopenharmony_ci
15471cb0ef41Sopenharmony_ci    CheckForMinusZeroMode mz_mode;
15481cb0ef41Sopenharmony_ci    Type restriction;
15491cb0ef41Sopenharmony_ci    if (IsSomePositiveOrderedNumber(input0_type) ||
15501cb0ef41Sopenharmony_ci        IsSomePositiveOrderedNumber(input1_type)) {
15511cb0ef41Sopenharmony_ci      mz_mode = CheckForMinusZeroMode::kDontCheckForMinusZero;
15521cb0ef41Sopenharmony_ci      restriction = Type::Signed32();
15531cb0ef41Sopenharmony_ci    } else if (truncation.IdentifiesZeroAndMinusZero()) {
15541cb0ef41Sopenharmony_ci      mz_mode = CheckForMinusZeroMode::kDontCheckForMinusZero;
15551cb0ef41Sopenharmony_ci      restriction = Type::Signed32OrMinusZero();
15561cb0ef41Sopenharmony_ci    } else {
15571cb0ef41Sopenharmony_ci      mz_mode = CheckForMinusZeroMode::kCheckForMinusZero;
15581cb0ef41Sopenharmony_ci      restriction = Type::Signed32();
15591cb0ef41Sopenharmony_ci    }
15601cb0ef41Sopenharmony_ci
15611cb0ef41Sopenharmony_ci    VisitBinop<T>(node, input_use, MachineRepresentation::kWord32, restriction);
15621cb0ef41Sopenharmony_ci    if (lower<T>()) ChangeOp(node, simplified()->CheckedInt32Mul(mz_mode));
15631cb0ef41Sopenharmony_ci  }
15641cb0ef41Sopenharmony_ci
15651cb0ef41Sopenharmony_ci  void ChangeToInt32OverflowOp(Node* node) {
15661cb0ef41Sopenharmony_ci    ChangeOp(node, Int32OverflowOp(node));
15671cb0ef41Sopenharmony_ci  }
15681cb0ef41Sopenharmony_ci
15691cb0ef41Sopenharmony_ci  void ChangeToUint32OverflowOp(Node* node) {
15701cb0ef41Sopenharmony_ci    ChangeOp(node, Uint32OverflowOp(node));
15711cb0ef41Sopenharmony_ci  }
15721cb0ef41Sopenharmony_ci
15731cb0ef41Sopenharmony_ci  template <Phase T>
15741cb0ef41Sopenharmony_ci  void VisitSpeculativeIntegerAdditiveOp(Node* node, Truncation truncation,
15751cb0ef41Sopenharmony_ci                                         SimplifiedLowering* lowering) {
15761cb0ef41Sopenharmony_ci    Type left_upper = GetUpperBound(node->InputAt(0));
15771cb0ef41Sopenharmony_ci    Type right_upper = GetUpperBound(node->InputAt(1));
15781cb0ef41Sopenharmony_ci
15791cb0ef41Sopenharmony_ci    if (left_upper.Is(type_cache_->kAdditiveSafeIntegerOrMinusZero) &&
15801cb0ef41Sopenharmony_ci        right_upper.Is(type_cache_->kAdditiveSafeIntegerOrMinusZero)) {
15811cb0ef41Sopenharmony_ci      // Only eliminate the node if its typing rule can be satisfied, namely
15821cb0ef41Sopenharmony_ci      // that a safe integer is produced.
15831cb0ef41Sopenharmony_ci      if (truncation.IsUnused()) return VisitUnused<T>(node);
15841cb0ef41Sopenharmony_ci
15851cb0ef41Sopenharmony_ci      // If we know how to interpret the result or if the users only care
15861cb0ef41Sopenharmony_ci      // about the low 32-bits, we can truncate to Word32 do a wrapping
15871cb0ef41Sopenharmony_ci      // addition.
15881cb0ef41Sopenharmony_ci      if (GetUpperBound(node).Is(Type::Signed32()) ||
15891cb0ef41Sopenharmony_ci          GetUpperBound(node).Is(Type::Unsigned32()) ||
15901cb0ef41Sopenharmony_ci          truncation.IsUsedAsWord32()) {
15911cb0ef41Sopenharmony_ci        // => Int32Add/Sub
15921cb0ef41Sopenharmony_ci        VisitWord32TruncatingBinop<T>(node);
15931cb0ef41Sopenharmony_ci        if (lower<T>()) ChangeToPureOp(node, Int32Op(node));
15941cb0ef41Sopenharmony_ci        return;
15951cb0ef41Sopenharmony_ci      }
15961cb0ef41Sopenharmony_ci    }
15971cb0ef41Sopenharmony_ci
15981cb0ef41Sopenharmony_ci    // Try to use type feedback.
15991cb0ef41Sopenharmony_ci    NumberOperationHint const hint = NumberOperationHint::kSignedSmall;
16001cb0ef41Sopenharmony_ci    DCHECK_EQ(hint, NumberOperationHintOf(node->op()));
16011cb0ef41Sopenharmony_ci
16021cb0ef41Sopenharmony_ci    Type left_feedback_type = TypeOf(node->InputAt(0));
16031cb0ef41Sopenharmony_ci    Type right_feedback_type = TypeOf(node->InputAt(1));
16041cb0ef41Sopenharmony_ci
16051cb0ef41Sopenharmony_ci    // Using Signed32 as restriction type amounts to promising there won't be
16061cb0ef41Sopenharmony_ci    // signed overflow. This is incompatible with relying on a Word32 truncation
16071cb0ef41Sopenharmony_ci    // in order to skip the overflow check.  Similarly, we must not drop -0 from
16081cb0ef41Sopenharmony_ci    // the result type unless we deopt for -0 inputs.
16091cb0ef41Sopenharmony_ci    Type const restriction =
16101cb0ef41Sopenharmony_ci        truncation.IsUsedAsWord32()
16111cb0ef41Sopenharmony_ci            ? Type::Any()
16121cb0ef41Sopenharmony_ci            : (truncation.identify_zeros() == kIdentifyZeros)
16131cb0ef41Sopenharmony_ci                  ? Type::Signed32OrMinusZero()
16141cb0ef41Sopenharmony_ci                  : Type::Signed32();
16151cb0ef41Sopenharmony_ci
16161cb0ef41Sopenharmony_ci    // Handle the case when no int32 checks on inputs are necessary (but
16171cb0ef41Sopenharmony_ci    // an overflow check is needed on the output). Note that we do not
16181cb0ef41Sopenharmony_ci    // have to do any check if at most one side can be minus zero. For
16191cb0ef41Sopenharmony_ci    // subtraction we need to handle the case of -0 - 0 properly, since
16201cb0ef41Sopenharmony_ci    // that can produce -0.
16211cb0ef41Sopenharmony_ci    Type left_constraint_type =
16221cb0ef41Sopenharmony_ci        node->opcode() == IrOpcode::kSpeculativeSafeIntegerAdd
16231cb0ef41Sopenharmony_ci            ? Type::Signed32OrMinusZero()
16241cb0ef41Sopenharmony_ci            : Type::Signed32();
16251cb0ef41Sopenharmony_ci    if (left_upper.Is(left_constraint_type) &&
16261cb0ef41Sopenharmony_ci        right_upper.Is(Type::Signed32OrMinusZero()) &&
16271cb0ef41Sopenharmony_ci        (left_upper.Is(Type::Signed32()) || right_upper.Is(Type::Signed32()))) {
16281cb0ef41Sopenharmony_ci      VisitBinop<T>(node, UseInfo::TruncatingWord32(),
16291cb0ef41Sopenharmony_ci                    MachineRepresentation::kWord32, restriction);
16301cb0ef41Sopenharmony_ci    } else {
16311cb0ef41Sopenharmony_ci      // If the output's truncation is identify-zeros, we can pass it
16321cb0ef41Sopenharmony_ci      // along. Moreover, if the operation is addition and we know the
16331cb0ef41Sopenharmony_ci      // right-hand side is not minus zero, we do not have to distinguish
16341cb0ef41Sopenharmony_ci      // between 0 and -0.
16351cb0ef41Sopenharmony_ci      IdentifyZeros left_identify_zeros = truncation.identify_zeros();
16361cb0ef41Sopenharmony_ci      if (node->opcode() == IrOpcode::kSpeculativeSafeIntegerAdd &&
16371cb0ef41Sopenharmony_ci          !right_feedback_type.Maybe(Type::MinusZero())) {
16381cb0ef41Sopenharmony_ci        left_identify_zeros = kIdentifyZeros;
16391cb0ef41Sopenharmony_ci      }
16401cb0ef41Sopenharmony_ci      UseInfo left_use =
16411cb0ef41Sopenharmony_ci          CheckedUseInfoAsWord32FromHint(hint, left_identify_zeros);
16421cb0ef41Sopenharmony_ci      // For CheckedInt32Add and CheckedInt32Sub, we don't need to do
16431cb0ef41Sopenharmony_ci      // a minus zero check for the right hand side, since we already
16441cb0ef41Sopenharmony_ci      // know that the left hand side is a proper Signed32 value,
16451cb0ef41Sopenharmony_ci      // potentially guarded by a check.
16461cb0ef41Sopenharmony_ci      UseInfo right_use = CheckedUseInfoAsWord32FromHint(hint, kIdentifyZeros);
16471cb0ef41Sopenharmony_ci      VisitBinop<T>(node, left_use, right_use, MachineRepresentation::kWord32,
16481cb0ef41Sopenharmony_ci                    restriction);
16491cb0ef41Sopenharmony_ci    }
16501cb0ef41Sopenharmony_ci
16511cb0ef41Sopenharmony_ci    if (lower<T>()) {
16521cb0ef41Sopenharmony_ci      if (truncation.IsUsedAsWord32() ||
16531cb0ef41Sopenharmony_ci          !CanOverflowSigned32(node->op(), left_feedback_type,
16541cb0ef41Sopenharmony_ci                               right_feedback_type, type_cache_,
16551cb0ef41Sopenharmony_ci                               graph_zone())) {
16561cb0ef41Sopenharmony_ci        ChangeToPureOp(node, Int32Op(node));
16571cb0ef41Sopenharmony_ci      } else {
16581cb0ef41Sopenharmony_ci        ChangeToInt32OverflowOp(node);
16591cb0ef41Sopenharmony_ci      }
16601cb0ef41Sopenharmony_ci    }
16611cb0ef41Sopenharmony_ci    return;
16621cb0ef41Sopenharmony_ci  }
16631cb0ef41Sopenharmony_ci
16641cb0ef41Sopenharmony_ci  template <Phase T>
16651cb0ef41Sopenharmony_ci  void VisitSpeculativeAdditiveOp(Node* node, Truncation truncation,
16661cb0ef41Sopenharmony_ci                                  SimplifiedLowering* lowering) {
16671cb0ef41Sopenharmony_ci    if (BothInputsAre(node, type_cache_->kAdditiveSafeIntegerOrMinusZero) &&
16681cb0ef41Sopenharmony_ci        (GetUpperBound(node).Is(Type::Signed32()) ||
16691cb0ef41Sopenharmony_ci         GetUpperBound(node).Is(Type::Unsigned32()) ||
16701cb0ef41Sopenharmony_ci         truncation.IsUsedAsWord32())) {
16711cb0ef41Sopenharmony_ci      // => Int32Add/Sub
16721cb0ef41Sopenharmony_ci      VisitWord32TruncatingBinop<T>(node);
16731cb0ef41Sopenharmony_ci      if (lower<T>()) ChangeToPureOp(node, Int32Op(node));
16741cb0ef41Sopenharmony_ci      return;
16751cb0ef41Sopenharmony_ci    }
16761cb0ef41Sopenharmony_ci
16771cb0ef41Sopenharmony_ci    // default case => Float64Add/Sub
16781cb0ef41Sopenharmony_ci    VisitBinop<T>(node,
16791cb0ef41Sopenharmony_ci                  UseInfo::CheckedNumberOrOddballAsFloat64(kDistinguishZeros,
16801cb0ef41Sopenharmony_ci                                                           FeedbackSource()),
16811cb0ef41Sopenharmony_ci                  MachineRepresentation::kFloat64, Type::Number());
16821cb0ef41Sopenharmony_ci    if (lower<T>()) {
16831cb0ef41Sopenharmony_ci      ChangeToPureOp(node, Float64Op(node));
16841cb0ef41Sopenharmony_ci    }
16851cb0ef41Sopenharmony_ci    return;
16861cb0ef41Sopenharmony_ci  }
16871cb0ef41Sopenharmony_ci
16881cb0ef41Sopenharmony_ci  template <Phase T>
16891cb0ef41Sopenharmony_ci  void VisitSpeculativeNumberModulus(Node* node, Truncation truncation,
16901cb0ef41Sopenharmony_ci                                     SimplifiedLowering* lowering) {
16911cb0ef41Sopenharmony_ci    if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN()) &&
16921cb0ef41Sopenharmony_ci        (truncation.IsUsedAsWord32() ||
16931cb0ef41Sopenharmony_ci         NodeProperties::GetType(node).Is(Type::Unsigned32()))) {
16941cb0ef41Sopenharmony_ci      // => unsigned Uint32Mod
16951cb0ef41Sopenharmony_ci      VisitWord32TruncatingBinop<T>(node);
16961cb0ef41Sopenharmony_ci      if (lower<T>()) DeferReplacement(node, lowering->Uint32Mod(node));
16971cb0ef41Sopenharmony_ci      return;
16981cb0ef41Sopenharmony_ci    }
16991cb0ef41Sopenharmony_ci    if (BothInputsAre(node, Type::Signed32OrMinusZeroOrNaN()) &&
17001cb0ef41Sopenharmony_ci        (truncation.IsUsedAsWord32() ||
17011cb0ef41Sopenharmony_ci         NodeProperties::GetType(node).Is(Type::Signed32()))) {
17021cb0ef41Sopenharmony_ci      // => signed Int32Mod
17031cb0ef41Sopenharmony_ci      VisitWord32TruncatingBinop<T>(node);
17041cb0ef41Sopenharmony_ci      if (lower<T>()) DeferReplacement(node, lowering->Int32Mod(node));
17051cb0ef41Sopenharmony_ci      return;
17061cb0ef41Sopenharmony_ci    }
17071cb0ef41Sopenharmony_ci
17081cb0ef41Sopenharmony_ci    // Try to use type feedback.
17091cb0ef41Sopenharmony_ci    NumberOperationHint hint = NumberOperationHintOf(node->op());
17101cb0ef41Sopenharmony_ci
17111cb0ef41Sopenharmony_ci    // Handle the case when no uint32 checks on inputs are necessary
17121cb0ef41Sopenharmony_ci    // (but an overflow check is needed on the output).
17131cb0ef41Sopenharmony_ci    if (BothInputsAreUnsigned32(node)) {
17141cb0ef41Sopenharmony_ci      if (hint == NumberOperationHint::kSignedSmall) {
17151cb0ef41Sopenharmony_ci        VisitBinop<T>(node, UseInfo::TruncatingWord32(),
17161cb0ef41Sopenharmony_ci                      MachineRepresentation::kWord32, Type::Unsigned32());
17171cb0ef41Sopenharmony_ci        if (lower<T>()) ChangeToUint32OverflowOp(node);
17181cb0ef41Sopenharmony_ci        return;
17191cb0ef41Sopenharmony_ci      }
17201cb0ef41Sopenharmony_ci    }
17211cb0ef41Sopenharmony_ci
17221cb0ef41Sopenharmony_ci    // Handle the case when no int32 checks on inputs are necessary
17231cb0ef41Sopenharmony_ci    // (but an overflow check is needed on the output).
17241cb0ef41Sopenharmony_ci    if (BothInputsAre(node, Type::Signed32())) {
17251cb0ef41Sopenharmony_ci      // If both the inputs the feedback are int32, use the overflow op.
17261cb0ef41Sopenharmony_ci      if (hint == NumberOperationHint::kSignedSmall) {
17271cb0ef41Sopenharmony_ci        VisitBinop<T>(node, UseInfo::TruncatingWord32(),
17281cb0ef41Sopenharmony_ci                      MachineRepresentation::kWord32, Type::Signed32());
17291cb0ef41Sopenharmony_ci        if (lower<T>()) ChangeToInt32OverflowOp(node);
17301cb0ef41Sopenharmony_ci        return;
17311cb0ef41Sopenharmony_ci      }
17321cb0ef41Sopenharmony_ci    }
17331cb0ef41Sopenharmony_ci
17341cb0ef41Sopenharmony_ci    if (hint == NumberOperationHint::kSignedSmall) {
17351cb0ef41Sopenharmony_ci      // If the result is truncated, we only need to check the inputs.
17361cb0ef41Sopenharmony_ci      // For the left hand side we just propagate the identify zeros
17371cb0ef41Sopenharmony_ci      // mode of the {truncation}; and for modulus the sign of the
17381cb0ef41Sopenharmony_ci      // right hand side doesn't matter anyways, so in particular there's
17391cb0ef41Sopenharmony_ci      // no observable difference between a 0 and a -0 then.
17401cb0ef41Sopenharmony_ci      UseInfo const lhs_use =
17411cb0ef41Sopenharmony_ci          CheckedUseInfoAsWord32FromHint(hint, truncation.identify_zeros());
17421cb0ef41Sopenharmony_ci      UseInfo const rhs_use =
17431cb0ef41Sopenharmony_ci          CheckedUseInfoAsWord32FromHint(hint, kIdentifyZeros);
17441cb0ef41Sopenharmony_ci      if (truncation.IsUsedAsWord32()) {
17451cb0ef41Sopenharmony_ci        VisitBinop<T>(node, lhs_use, rhs_use, MachineRepresentation::kWord32);
17461cb0ef41Sopenharmony_ci        if (lower<T>()) DeferReplacement(node, lowering->Int32Mod(node));
17471cb0ef41Sopenharmony_ci      } else if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN())) {
17481cb0ef41Sopenharmony_ci        Type const restriction =
17491cb0ef41Sopenharmony_ci            truncation.IdentifiesZeroAndMinusZero() &&
17501cb0ef41Sopenharmony_ci                    TypeOf(node->InputAt(0)).Maybe(Type::MinusZero())
17511cb0ef41Sopenharmony_ci                ? Type::Unsigned32OrMinusZero()
17521cb0ef41Sopenharmony_ci                : Type::Unsigned32();
17531cb0ef41Sopenharmony_ci        VisitBinop<T>(node, lhs_use, rhs_use, MachineRepresentation::kWord32,
17541cb0ef41Sopenharmony_ci                      restriction);
17551cb0ef41Sopenharmony_ci        if (lower<T>()) ChangeToUint32OverflowOp(node);
17561cb0ef41Sopenharmony_ci      } else {
17571cb0ef41Sopenharmony_ci        Type const restriction =
17581cb0ef41Sopenharmony_ci            truncation.IdentifiesZeroAndMinusZero() &&
17591cb0ef41Sopenharmony_ci                    TypeOf(node->InputAt(0)).Maybe(Type::MinusZero())
17601cb0ef41Sopenharmony_ci                ? Type::Signed32OrMinusZero()
17611cb0ef41Sopenharmony_ci                : Type::Signed32();
17621cb0ef41Sopenharmony_ci        VisitBinop<T>(node, lhs_use, rhs_use, MachineRepresentation::kWord32,
17631cb0ef41Sopenharmony_ci                      restriction);
17641cb0ef41Sopenharmony_ci        if (lower<T>()) ChangeToInt32OverflowOp(node);
17651cb0ef41Sopenharmony_ci      }
17661cb0ef41Sopenharmony_ci      return;
17671cb0ef41Sopenharmony_ci    }
17681cb0ef41Sopenharmony_ci
17691cb0ef41Sopenharmony_ci    if (TypeOf(node->InputAt(0)).Is(Type::Unsigned32()) &&
17701cb0ef41Sopenharmony_ci        TypeOf(node->InputAt(1)).Is(Type::Unsigned32()) &&
17711cb0ef41Sopenharmony_ci        (truncation.IsUsedAsWord32() ||
17721cb0ef41Sopenharmony_ci         NodeProperties::GetType(node).Is(Type::Unsigned32()))) {
17731cb0ef41Sopenharmony_ci      VisitBinop<T>(node, UseInfo::TruncatingWord32(),
17741cb0ef41Sopenharmony_ci                    MachineRepresentation::kWord32, Type::Number());
17751cb0ef41Sopenharmony_ci      if (lower<T>()) DeferReplacement(node, lowering->Uint32Mod(node));
17761cb0ef41Sopenharmony_ci      return;
17771cb0ef41Sopenharmony_ci    }
17781cb0ef41Sopenharmony_ci    if (TypeOf(node->InputAt(0)).Is(Type::Signed32()) &&
17791cb0ef41Sopenharmony_ci        TypeOf(node->InputAt(1)).Is(Type::Signed32()) &&
17801cb0ef41Sopenharmony_ci        (truncation.IsUsedAsWord32() ||
17811cb0ef41Sopenharmony_ci         NodeProperties::GetType(node).Is(Type::Signed32()))) {
17821cb0ef41Sopenharmony_ci      VisitBinop<T>(node, UseInfo::TruncatingWord32(),
17831cb0ef41Sopenharmony_ci                    MachineRepresentation::kWord32, Type::Number());
17841cb0ef41Sopenharmony_ci      if (lower<T>()) DeferReplacement(node, lowering->Int32Mod(node));
17851cb0ef41Sopenharmony_ci      return;
17861cb0ef41Sopenharmony_ci    }
17871cb0ef41Sopenharmony_ci
17881cb0ef41Sopenharmony_ci    // default case => Float64Mod
17891cb0ef41Sopenharmony_ci    // For the left hand side we just propagate the identify zeros
17901cb0ef41Sopenharmony_ci    // mode of the {truncation}; and for modulus the sign of the
17911cb0ef41Sopenharmony_ci    // right hand side doesn't matter anyways, so in particular there's
17921cb0ef41Sopenharmony_ci    // no observable difference between a 0 and a -0 then.
17931cb0ef41Sopenharmony_ci    UseInfo const lhs_use = UseInfo::CheckedNumberOrOddballAsFloat64(
17941cb0ef41Sopenharmony_ci        truncation.identify_zeros(), FeedbackSource());
17951cb0ef41Sopenharmony_ci    UseInfo const rhs_use = UseInfo::CheckedNumberOrOddballAsFloat64(
17961cb0ef41Sopenharmony_ci        kIdentifyZeros, FeedbackSource());
17971cb0ef41Sopenharmony_ci    VisitBinop<T>(node, lhs_use, rhs_use, MachineRepresentation::kFloat64,
17981cb0ef41Sopenharmony_ci                  Type::Number());
17991cb0ef41Sopenharmony_ci    if (lower<T>()) ChangeToPureOp(node, Float64Op(node));
18001cb0ef41Sopenharmony_ci    return;
18011cb0ef41Sopenharmony_ci  }
18021cb0ef41Sopenharmony_ci
18031cb0ef41Sopenharmony_ci  // Just assert for Propagate and Retype. Lower specialized below.
18041cb0ef41Sopenharmony_ci  template <Phase T>
18051cb0ef41Sopenharmony_ci  void InsertUnreachableIfNecessary(Node* node) {
18061cb0ef41Sopenharmony_ci    static_assert(propagate<T>() || retype<T>(),
18071cb0ef41Sopenharmony_ci                  "This version of InsertUnreachableIfNecessary has to be "
18081cb0ef41Sopenharmony_ci                  "called in the Propagate or Retype phase.");
18091cb0ef41Sopenharmony_ci  }
18101cb0ef41Sopenharmony_ci
18111cb0ef41Sopenharmony_ci  template <Phase T>
18121cb0ef41Sopenharmony_ci  void VisitCheckBounds(Node* node, SimplifiedLowering* lowering) {
18131cb0ef41Sopenharmony_ci    CheckBoundsParameters const& p = CheckBoundsParametersOf(node->op());
18141cb0ef41Sopenharmony_ci    FeedbackSource const& feedback = p.check_parameters().feedback();
18151cb0ef41Sopenharmony_ci    Type const index_type = TypeOf(node->InputAt(0));
18161cb0ef41Sopenharmony_ci    Type const length_type = TypeOf(node->InputAt(1));
18171cb0ef41Sopenharmony_ci
18181cb0ef41Sopenharmony_ci    // Conversions, if requested and needed, will be handled by the
18191cb0ef41Sopenharmony_ci    // representation changer, not by the lower-level Checked*Bounds operators.
18201cb0ef41Sopenharmony_ci    CheckBoundsFlags new_flags =
18211cb0ef41Sopenharmony_ci        p.flags().without(CheckBoundsFlag::kConvertStringAndMinusZero);
18221cb0ef41Sopenharmony_ci
18231cb0ef41Sopenharmony_ci    if (length_type.Is(Type::Unsigned31())) {
18241cb0ef41Sopenharmony_ci      if (index_type.Is(Type::Integral32()) ||
18251cb0ef41Sopenharmony_ci          (index_type.Is(Type::Integral32OrMinusZero()) &&
18261cb0ef41Sopenharmony_ci           p.flags() & CheckBoundsFlag::kConvertStringAndMinusZero)) {
18271cb0ef41Sopenharmony_ci        // Map the values in the [-2^31,-1] range to the [2^31,2^32-1] range,
18281cb0ef41Sopenharmony_ci        // which will be considered out-of-bounds because the {length_type} is
18291cb0ef41Sopenharmony_ci        // limited to Unsigned31. This also converts -0 to 0.
18301cb0ef41Sopenharmony_ci        VisitBinop<T>(node, UseInfo::TruncatingWord32(),
18311cb0ef41Sopenharmony_ci                      MachineRepresentation::kWord32);
18321cb0ef41Sopenharmony_ci        if (lower<T>()) {
18331cb0ef41Sopenharmony_ci          if (index_type.IsNone() || length_type.IsNone() ||
18341cb0ef41Sopenharmony_ci              (index_type.Min() >= 0.0 &&
18351cb0ef41Sopenharmony_ci               index_type.Max() < length_type.Min())) {
18361cb0ef41Sopenharmony_ci            // The bounds check is redundant if we already know that
18371cb0ef41Sopenharmony_ci            // the index is within the bounds of [0.0, length[.
18381cb0ef41Sopenharmony_ci            // TODO(neis): Move this into TypedOptimization?
18391cb0ef41Sopenharmony_ci            new_flags |= CheckBoundsFlag::kAbortOnOutOfBounds;
18401cb0ef41Sopenharmony_ci          }
18411cb0ef41Sopenharmony_ci          ChangeOp(node,
18421cb0ef41Sopenharmony_ci                   simplified()->CheckedUint32Bounds(feedback, new_flags));
18431cb0ef41Sopenharmony_ci        }
18441cb0ef41Sopenharmony_ci      } else if (p.flags() & CheckBoundsFlag::kConvertStringAndMinusZero) {
18451cb0ef41Sopenharmony_ci        VisitBinop<T>(node, UseInfo::CheckedTaggedAsArrayIndex(feedback),
18461cb0ef41Sopenharmony_ci                      UseInfo::Word(), MachineType::PointerRepresentation());
18471cb0ef41Sopenharmony_ci        if (lower<T>()) {
18481cb0ef41Sopenharmony_ci          if (jsgraph_->machine()->Is64()) {
18491cb0ef41Sopenharmony_ci            ChangeOp(node,
18501cb0ef41Sopenharmony_ci                     simplified()->CheckedUint64Bounds(feedback, new_flags));
18511cb0ef41Sopenharmony_ci          } else {
18521cb0ef41Sopenharmony_ci            ChangeOp(node,
18531cb0ef41Sopenharmony_ci                     simplified()->CheckedUint32Bounds(feedback, new_flags));
18541cb0ef41Sopenharmony_ci          }
18551cb0ef41Sopenharmony_ci        }
18561cb0ef41Sopenharmony_ci      } else {
18571cb0ef41Sopenharmony_ci        VisitBinop<T>(
18581cb0ef41Sopenharmony_ci            node, UseInfo::CheckedSigned32AsWord32(kDistinguishZeros, feedback),
18591cb0ef41Sopenharmony_ci            UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
18601cb0ef41Sopenharmony_ci        if (lower<T>()) {
18611cb0ef41Sopenharmony_ci          ChangeOp(node,
18621cb0ef41Sopenharmony_ci                   simplified()->CheckedUint32Bounds(feedback, new_flags));
18631cb0ef41Sopenharmony_ci        }
18641cb0ef41Sopenharmony_ci      }
18651cb0ef41Sopenharmony_ci    } else {
18661cb0ef41Sopenharmony_ci      CHECK(length_type.Is(type_cache_->kPositiveSafeInteger));
18671cb0ef41Sopenharmony_ci      IdentifyZeros zero_handling =
18681cb0ef41Sopenharmony_ci          (p.flags() & CheckBoundsFlag::kConvertStringAndMinusZero)
18691cb0ef41Sopenharmony_ci              ? kIdentifyZeros
18701cb0ef41Sopenharmony_ci              : kDistinguishZeros;
18711cb0ef41Sopenharmony_ci      VisitBinop<T>(node,
18721cb0ef41Sopenharmony_ci                    UseInfo::CheckedSigned64AsWord64(zero_handling, feedback),
18731cb0ef41Sopenharmony_ci                    UseInfo::Word64(), MachineRepresentation::kWord64);
18741cb0ef41Sopenharmony_ci      if (lower<T>()) {
18751cb0ef41Sopenharmony_ci        ChangeOp(node, simplified()->CheckedUint64Bounds(feedback, new_flags));
18761cb0ef41Sopenharmony_ci      }
18771cb0ef41Sopenharmony_ci    }
18781cb0ef41Sopenharmony_ci  }
18791cb0ef41Sopenharmony_ci
18801cb0ef41Sopenharmony_ci  UseInfo UseInfoForFastApiCallArgument(CTypeInfo type,
18811cb0ef41Sopenharmony_ci                                        FeedbackSource const& feedback) {
18821cb0ef41Sopenharmony_ci    switch (type.GetSequenceType()) {
18831cb0ef41Sopenharmony_ci      case CTypeInfo::SequenceType::kScalar: {
18841cb0ef41Sopenharmony_ci        switch (type.GetType()) {
18851cb0ef41Sopenharmony_ci          case CTypeInfo::Type::kVoid:
18861cb0ef41Sopenharmony_ci            UNREACHABLE();
18871cb0ef41Sopenharmony_ci          case CTypeInfo::Type::kBool:
18881cb0ef41Sopenharmony_ci            return UseInfo::Bool();
18891cb0ef41Sopenharmony_ci          case CTypeInfo::Type::kInt32:
18901cb0ef41Sopenharmony_ci          case CTypeInfo::Type::kUint32:
18911cb0ef41Sopenharmony_ci            return UseInfo::CheckedNumberAsWord32(feedback);
18921cb0ef41Sopenharmony_ci          // TODO(mslekova): We deopt for unsafe integers, but ultimately we
18931cb0ef41Sopenharmony_ci          // want to make this less restrictive in order to stay on the fast
18941cb0ef41Sopenharmony_ci          // path.
18951cb0ef41Sopenharmony_ci          case CTypeInfo::Type::kInt64:
18961cb0ef41Sopenharmony_ci          case CTypeInfo::Type::kUint64:
18971cb0ef41Sopenharmony_ci          case CTypeInfo::Type::kAny:
18981cb0ef41Sopenharmony_ci            return UseInfo::CheckedSigned64AsWord64(kIdentifyZeros, feedback);
18991cb0ef41Sopenharmony_ci          case CTypeInfo::Type::kFloat32:
19001cb0ef41Sopenharmony_ci          case CTypeInfo::Type::kFloat64:
19011cb0ef41Sopenharmony_ci            return UseInfo::CheckedNumberAsFloat64(kDistinguishZeros, feedback);
19021cb0ef41Sopenharmony_ci          case CTypeInfo::Type::kV8Value:
19031cb0ef41Sopenharmony_ci          case CTypeInfo::Type::kApiObject:
19041cb0ef41Sopenharmony_ci            return UseInfo::AnyTagged();
19051cb0ef41Sopenharmony_ci        }
19061cb0ef41Sopenharmony_ci      }
19071cb0ef41Sopenharmony_ci      case CTypeInfo::SequenceType::kIsSequence: {
19081cb0ef41Sopenharmony_ci        CHECK_EQ(type.GetType(), CTypeInfo::Type::kVoid);
19091cb0ef41Sopenharmony_ci        return UseInfo::AnyTagged();
19101cb0ef41Sopenharmony_ci      }
19111cb0ef41Sopenharmony_ci      case CTypeInfo::SequenceType::kIsTypedArray: {
19121cb0ef41Sopenharmony_ci        return UseInfo::AnyTagged();
19131cb0ef41Sopenharmony_ci      }
19141cb0ef41Sopenharmony_ci      default: {
19151cb0ef41Sopenharmony_ci        UNREACHABLE();  // TODO(mslekova): Implement array buffers.
19161cb0ef41Sopenharmony_ci      }
19171cb0ef41Sopenharmony_ci    }
19181cb0ef41Sopenharmony_ci  }
19191cb0ef41Sopenharmony_ci
19201cb0ef41Sopenharmony_ci  static constexpr int kInitialArgumentsCount = 10;
19211cb0ef41Sopenharmony_ci
19221cb0ef41Sopenharmony_ci  template <Phase T>
19231cb0ef41Sopenharmony_ci  void VisitFastApiCall(Node* node, SimplifiedLowering* lowering) {
19241cb0ef41Sopenharmony_ci    FastApiCallParameters const& op_params =
19251cb0ef41Sopenharmony_ci        FastApiCallParametersOf(node->op());
19261cb0ef41Sopenharmony_ci    // We only consider the first function signature here. In case of function
19271cb0ef41Sopenharmony_ci    // overloads, we only support the case of two functions that differ for one
19281cb0ef41Sopenharmony_ci    // argument, which must be a JSArray in one function and a TypedArray in the
19291cb0ef41Sopenharmony_ci    // other function, and both JSArrays and TypedArrays have the same UseInfo
19301cb0ef41Sopenharmony_ci    // UseInfo::AnyTagged(). All the other argument types must match.
19311cb0ef41Sopenharmony_ci    const CFunctionInfo* c_signature = op_params.c_functions()[0].signature;
19321cb0ef41Sopenharmony_ci    const int c_arg_count = c_signature->ArgumentCount();
19331cb0ef41Sopenharmony_ci    CallDescriptor* call_descriptor = op_params.descriptor();
19341cb0ef41Sopenharmony_ci    int js_arg_count = static_cast<int>(call_descriptor->ParameterCount());
19351cb0ef41Sopenharmony_ci    const int value_input_count = node->op()->ValueInputCount();
19361cb0ef41Sopenharmony_ci    CHECK_EQ(FastApiCallNode::ArityForArgc(c_arg_count, js_arg_count),
19371cb0ef41Sopenharmony_ci             value_input_count);
19381cb0ef41Sopenharmony_ci
19391cb0ef41Sopenharmony_ci    base::SmallVector<UseInfo, kInitialArgumentsCount> arg_use_info(
19401cb0ef41Sopenharmony_ci        c_arg_count);
19411cb0ef41Sopenharmony_ci    // Propagate representation information from TypeInfo.
19421cb0ef41Sopenharmony_ci    for (int i = 0; i < c_arg_count; i++) {
19431cb0ef41Sopenharmony_ci      arg_use_info[i] = UseInfoForFastApiCallArgument(
19441cb0ef41Sopenharmony_ci          c_signature->ArgumentInfo(i), op_params.feedback());
19451cb0ef41Sopenharmony_ci      ProcessInput<T>(node, i, arg_use_info[i]);
19461cb0ef41Sopenharmony_ci    }
19471cb0ef41Sopenharmony_ci
19481cb0ef41Sopenharmony_ci    // The call code for the slow call.
19491cb0ef41Sopenharmony_ci    ProcessInput<T>(node, c_arg_count, UseInfo::AnyTagged());
19501cb0ef41Sopenharmony_ci    for (int i = 1; i <= js_arg_count; i++) {
19511cb0ef41Sopenharmony_ci      ProcessInput<T>(node, c_arg_count + i,
19521cb0ef41Sopenharmony_ci                      TruncatingUseInfoFromRepresentation(
19531cb0ef41Sopenharmony_ci                          call_descriptor->GetInputType(i).representation()));
19541cb0ef41Sopenharmony_ci    }
19551cb0ef41Sopenharmony_ci    for (int i = c_arg_count + js_arg_count; i < value_input_count; ++i) {
19561cb0ef41Sopenharmony_ci      ProcessInput<T>(node, i, UseInfo::AnyTagged());
19571cb0ef41Sopenharmony_ci    }
19581cb0ef41Sopenharmony_ci    ProcessRemainingInputs<T>(node, value_input_count);
19591cb0ef41Sopenharmony_ci    SetOutput<T>(node, MachineRepresentation::kTagged);
19601cb0ef41Sopenharmony_ci  }
19611cb0ef41Sopenharmony_ci
19621cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
19631cb0ef41Sopenharmony_ci  static MachineType MachineTypeForWasmReturnType(wasm::ValueType type) {
19641cb0ef41Sopenharmony_ci    switch (type.kind()) {
19651cb0ef41Sopenharmony_ci      case wasm::kI32:
19661cb0ef41Sopenharmony_ci        return MachineType::Int32();
19671cb0ef41Sopenharmony_ci      case wasm::kF32:
19681cb0ef41Sopenharmony_ci        return MachineType::Float32();
19691cb0ef41Sopenharmony_ci      case wasm::kF64:
19701cb0ef41Sopenharmony_ci        return MachineType::Float64();
19711cb0ef41Sopenharmony_ci      case wasm::kI64:
19721cb0ef41Sopenharmony_ci        // Not used for i64, see VisitJSWasmCall().
19731cb0ef41Sopenharmony_ci      default:
19741cb0ef41Sopenharmony_ci        UNREACHABLE();
19751cb0ef41Sopenharmony_ci    }
19761cb0ef41Sopenharmony_ci  }
19771cb0ef41Sopenharmony_ci
19781cb0ef41Sopenharmony_ci  UseInfo UseInfoForJSWasmCallArgument(Node* input, wasm::ValueType type,
19791cb0ef41Sopenharmony_ci                                       FeedbackSource const& feedback) {
19801cb0ef41Sopenharmony_ci    // If the input type is a Number or Oddball, we can directly convert the
19811cb0ef41Sopenharmony_ci    // input into the Wasm native type of the argument. If not, we return
19821cb0ef41Sopenharmony_ci    // UseInfo::AnyTagged to signal that WasmWrapperGraphBuilder will need to
19831cb0ef41Sopenharmony_ci    // add Nodes to perform the conversion (in WasmWrapperGraphBuilder::FromJS).
19841cb0ef41Sopenharmony_ci    switch (type.kind()) {
19851cb0ef41Sopenharmony_ci      case wasm::kI32:
19861cb0ef41Sopenharmony_ci        return UseInfo::CheckedNumberOrOddballAsWord32(feedback);
19871cb0ef41Sopenharmony_ci      case wasm::kI64:
19881cb0ef41Sopenharmony_ci        return UseInfo::AnyTagged();
19891cb0ef41Sopenharmony_ci      case wasm::kF32:
19901cb0ef41Sopenharmony_ci      case wasm::kF64:
19911cb0ef41Sopenharmony_ci        // For Float32, TruncateFloat64ToFloat32 will be inserted later in
19921cb0ef41Sopenharmony_ci        // WasmWrapperGraphBuilder::BuildJSToWasmWrapper.
19931cb0ef41Sopenharmony_ci        return UseInfo::CheckedNumberOrOddballAsFloat64(kDistinguishZeros,
19941cb0ef41Sopenharmony_ci                                                        feedback);
19951cb0ef41Sopenharmony_ci      default:
19961cb0ef41Sopenharmony_ci        UNREACHABLE();
19971cb0ef41Sopenharmony_ci    }
19981cb0ef41Sopenharmony_ci  }
19991cb0ef41Sopenharmony_ci
20001cb0ef41Sopenharmony_ci  template <Phase T>
20011cb0ef41Sopenharmony_ci  void VisitJSWasmCall(Node* node, SimplifiedLowering* lowering) {
20021cb0ef41Sopenharmony_ci    DCHECK_EQ(JSWasmCallNode::TargetIndex(), 0);
20031cb0ef41Sopenharmony_ci    DCHECK_EQ(JSWasmCallNode::ReceiverIndex(), 1);
20041cb0ef41Sopenharmony_ci    DCHECK_EQ(JSWasmCallNode::FirstArgumentIndex(), 2);
20051cb0ef41Sopenharmony_ci
20061cb0ef41Sopenharmony_ci    JSWasmCallNode n(node);
20071cb0ef41Sopenharmony_ci
20081cb0ef41Sopenharmony_ci    JSWasmCallParameters const& params = n.Parameters();
20091cb0ef41Sopenharmony_ci    const wasm::FunctionSig* wasm_signature = params.signature();
20101cb0ef41Sopenharmony_ci    int wasm_arg_count = static_cast<int>(wasm_signature->parameter_count());
20111cb0ef41Sopenharmony_ci    DCHECK_EQ(wasm_arg_count, n.ArgumentCount());
20121cb0ef41Sopenharmony_ci
20131cb0ef41Sopenharmony_ci    base::SmallVector<UseInfo, kInitialArgumentsCount> arg_use_info(
20141cb0ef41Sopenharmony_ci        wasm_arg_count);
20151cb0ef41Sopenharmony_ci
20161cb0ef41Sopenharmony_ci    // Visit JSFunction and Receiver nodes.
20171cb0ef41Sopenharmony_ci    ProcessInput<T>(node, JSWasmCallNode::TargetIndex(), UseInfo::Any());
20181cb0ef41Sopenharmony_ci    ProcessInput<T>(node, JSWasmCallNode::ReceiverIndex(), UseInfo::Any());
20191cb0ef41Sopenharmony_ci
20201cb0ef41Sopenharmony_ci    // Propagate representation information from TypeInfo.
20211cb0ef41Sopenharmony_ci    for (int i = 0; i < wasm_arg_count; i++) {
20221cb0ef41Sopenharmony_ci      TNode<Object> input = n.Argument(i);
20231cb0ef41Sopenharmony_ci      DCHECK_NOT_NULL(input);
20241cb0ef41Sopenharmony_ci      arg_use_info[i] = UseInfoForJSWasmCallArgument(
20251cb0ef41Sopenharmony_ci          input, wasm_signature->GetParam(i), params.feedback());
20261cb0ef41Sopenharmony_ci      ProcessInput<T>(node, JSWasmCallNode::ArgumentIndex(i), arg_use_info[i]);
20271cb0ef41Sopenharmony_ci    }
20281cb0ef41Sopenharmony_ci
20291cb0ef41Sopenharmony_ci    // Visit value, context and frame state inputs as tagged.
20301cb0ef41Sopenharmony_ci    int first_effect_index = NodeProperties::FirstEffectIndex(node);
20311cb0ef41Sopenharmony_ci    DCHECK(first_effect_index >
20321cb0ef41Sopenharmony_ci           JSWasmCallNode::FirstArgumentIndex() + wasm_arg_count);
20331cb0ef41Sopenharmony_ci    for (int i = JSWasmCallNode::FirstArgumentIndex() + wasm_arg_count;
20341cb0ef41Sopenharmony_ci         i < first_effect_index; i++) {
20351cb0ef41Sopenharmony_ci      ProcessInput<T>(node, i, UseInfo::AnyTagged());
20361cb0ef41Sopenharmony_ci    }
20371cb0ef41Sopenharmony_ci
20381cb0ef41Sopenharmony_ci    // Effect and Control.
20391cb0ef41Sopenharmony_ci    ProcessRemainingInputs<T>(node, NodeProperties::FirstEffectIndex(node));
20401cb0ef41Sopenharmony_ci
20411cb0ef41Sopenharmony_ci    if (wasm_signature->return_count() == 1) {
20421cb0ef41Sopenharmony_ci      if (wasm_signature->GetReturn().kind() == wasm::kI64) {
20431cb0ef41Sopenharmony_ci        // Conversion between negative int64 and BigInt not supported yet.
20441cb0ef41Sopenharmony_ci        // Do not bypass the type conversion when the result type is i64.
20451cb0ef41Sopenharmony_ci        SetOutput<T>(node, MachineRepresentation::kTagged);
20461cb0ef41Sopenharmony_ci      } else {
20471cb0ef41Sopenharmony_ci        MachineType return_type =
20481cb0ef41Sopenharmony_ci            MachineTypeForWasmReturnType(wasm_signature->GetReturn());
20491cb0ef41Sopenharmony_ci        SetOutput<T>(
20501cb0ef41Sopenharmony_ci            node, return_type.representation(),
20511cb0ef41Sopenharmony_ci            JSWasmCallNode::TypeForWasmReturnType(wasm_signature->GetReturn()));
20521cb0ef41Sopenharmony_ci      }
20531cb0ef41Sopenharmony_ci    } else {
20541cb0ef41Sopenharmony_ci      DCHECK_EQ(wasm_signature->return_count(), 0);
20551cb0ef41Sopenharmony_ci      SetOutput<T>(node, MachineRepresentation::kTagged);
20561cb0ef41Sopenharmony_ci    }
20571cb0ef41Sopenharmony_ci
20581cb0ef41Sopenharmony_ci    // The actual lowering of JSWasmCall nodes happens later, in the subsequent
20591cb0ef41Sopenharmony_ci    // "wasm-inlining" phase.
20601cb0ef41Sopenharmony_ci  }
20611cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
20621cb0ef41Sopenharmony_ci
20631cb0ef41Sopenharmony_ci  // Dispatching routine for visiting the node {node} with the usage {use}.
20641cb0ef41Sopenharmony_ci  // Depending on the operator, propagate new usage info to the inputs.
20651cb0ef41Sopenharmony_ci  template <Phase T>
20661cb0ef41Sopenharmony_ci  void VisitNode(Node* node, Truncation truncation,
20671cb0ef41Sopenharmony_ci                 SimplifiedLowering* lowering) {
20681cb0ef41Sopenharmony_ci    tick_counter_->TickAndMaybeEnterSafepoint();
20691cb0ef41Sopenharmony_ci
20701cb0ef41Sopenharmony_ci    if (lower<T>()) {
20711cb0ef41Sopenharmony_ci      // Kill non-effectful operations that have a None-type input and are thus
20721cb0ef41Sopenharmony_ci      // dead code. Otherwise we might end up lowering the operation in a way,
20731cb0ef41Sopenharmony_ci      // e.g. by replacing it with a constant, that cuts the dependency on a
20741cb0ef41Sopenharmony_ci      // deopting operation (the producer of the None type), possibly resulting
20751cb0ef41Sopenharmony_ci      // in a nonsense schedule.
20761cb0ef41Sopenharmony_ci      if (node->op()->EffectOutputCount() == 0 &&
20771cb0ef41Sopenharmony_ci          node->op()->ControlOutputCount() == 0 &&
20781cb0ef41Sopenharmony_ci          node->opcode() != IrOpcode::kDeadValue &&
20791cb0ef41Sopenharmony_ci          node->opcode() != IrOpcode::kStateValues &&
20801cb0ef41Sopenharmony_ci          node->opcode() != IrOpcode::kFrameState &&
20811cb0ef41Sopenharmony_ci          node->opcode() != IrOpcode::kPhi) {
20821cb0ef41Sopenharmony_ci        for (int i = 0; i < node->op()->ValueInputCount(); i++) {
20831cb0ef41Sopenharmony_ci          Node* input = node->InputAt(i);
20841cb0ef41Sopenharmony_ci          if (TypeOf(input).IsNone()) {
20851cb0ef41Sopenharmony_ci            node->ReplaceInput(0, input);
20861cb0ef41Sopenharmony_ci            node->TrimInputCount(1);
20871cb0ef41Sopenharmony_ci            ChangeOp(node,
20881cb0ef41Sopenharmony_ci                     common()->DeadValue(GetInfo(node)->representation()));
20891cb0ef41Sopenharmony_ci            return;
20901cb0ef41Sopenharmony_ci          }
20911cb0ef41Sopenharmony_ci        }
20921cb0ef41Sopenharmony_ci      } else {
20931cb0ef41Sopenharmony_ci        InsertUnreachableIfNecessary<T>(node);
20941cb0ef41Sopenharmony_ci      }
20951cb0ef41Sopenharmony_ci    }
20961cb0ef41Sopenharmony_ci
20971cb0ef41Sopenharmony_ci    // Unconditionally eliminate unused pure nodes (only relevant if there's
20981cb0ef41Sopenharmony_ci    // a pure operation in between two effectful ones, where the last one
20991cb0ef41Sopenharmony_ci    // is unused).
21001cb0ef41Sopenharmony_ci    // Note: We must not do this for constants, as they are cached and we
21011cb0ef41Sopenharmony_ci    // would thus kill the cached {node} during lowering (i.e. replace all
21021cb0ef41Sopenharmony_ci    // uses with Dead), but at that point some node lowering might have
21031cb0ef41Sopenharmony_ci    // already taken the constant {node} from the cache (while it was not
21041cb0ef41Sopenharmony_ci    // yet killed) and we would afterwards replace that use with Dead as well.
21051cb0ef41Sopenharmony_ci    if (node->op()->ValueInputCount() > 0 &&
21061cb0ef41Sopenharmony_ci        node->op()->HasProperty(Operator::kPure) && truncation.IsUnused()) {
21071cb0ef41Sopenharmony_ci      return VisitUnused<T>(node);
21081cb0ef41Sopenharmony_ci    }
21091cb0ef41Sopenharmony_ci
21101cb0ef41Sopenharmony_ci    switch (node->opcode()) {
21111cb0ef41Sopenharmony_ci      //------------------------------------------------------------------
21121cb0ef41Sopenharmony_ci      // Common operators.
21131cb0ef41Sopenharmony_ci      //------------------------------------------------------------------
21141cb0ef41Sopenharmony_ci      case IrOpcode::kStart:
21151cb0ef41Sopenharmony_ci        // We use Start as a terminator for the frame state chain, so even
21161cb0ef41Sopenharmony_ci        // tho Start doesn't really produce a value, we have to say Tagged
21171cb0ef41Sopenharmony_ci        // here, otherwise the input conversion will fail.
21181cb0ef41Sopenharmony_ci        return VisitLeaf<T>(node, MachineRepresentation::kTagged);
21191cb0ef41Sopenharmony_ci      case IrOpcode::kParameter:
21201cb0ef41Sopenharmony_ci        return VisitUnop<T>(node, UseInfo::None(),
21211cb0ef41Sopenharmony_ci                            linkage()
21221cb0ef41Sopenharmony_ci                                ->GetParameterType(ParameterIndexOf(node->op()))
21231cb0ef41Sopenharmony_ci                                .representation());
21241cb0ef41Sopenharmony_ci      case IrOpcode::kInt32Constant:
21251cb0ef41Sopenharmony_ci        return VisitLeaf<T>(node, MachineRepresentation::kWord32);
21261cb0ef41Sopenharmony_ci      case IrOpcode::kInt64Constant:
21271cb0ef41Sopenharmony_ci        return VisitLeaf<T>(node, MachineRepresentation::kWord64);
21281cb0ef41Sopenharmony_ci      case IrOpcode::kExternalConstant:
21291cb0ef41Sopenharmony_ci        return VisitLeaf<T>(node, MachineType::PointerRepresentation());
21301cb0ef41Sopenharmony_ci      case IrOpcode::kNumberConstant: {
21311cb0ef41Sopenharmony_ci        double const value = OpParameter<double>(node->op());
21321cb0ef41Sopenharmony_ci        int value_as_int;
21331cb0ef41Sopenharmony_ci        if (DoubleToSmiInteger(value, &value_as_int)) {
21341cb0ef41Sopenharmony_ci          VisitLeaf<T>(node, MachineRepresentation::kTaggedSigned);
21351cb0ef41Sopenharmony_ci          if (lower<T>()) {
21361cb0ef41Sopenharmony_ci            intptr_t smi = bit_cast<intptr_t>(Smi::FromInt(value_as_int));
21371cb0ef41Sopenharmony_ci            Node* constant = InsertTypeOverrideForVerifier(
21381cb0ef41Sopenharmony_ci                NodeProperties::GetType(node),
21391cb0ef41Sopenharmony_ci                lowering->jsgraph()->IntPtrConstant(smi));
21401cb0ef41Sopenharmony_ci            DeferReplacement(node, constant);
21411cb0ef41Sopenharmony_ci          }
21421cb0ef41Sopenharmony_ci          return;
21431cb0ef41Sopenharmony_ci        }
21441cb0ef41Sopenharmony_ci        VisitLeaf<T>(node, MachineRepresentation::kTagged);
21451cb0ef41Sopenharmony_ci        return;
21461cb0ef41Sopenharmony_ci      }
21471cb0ef41Sopenharmony_ci      case IrOpcode::kHeapConstant:
21481cb0ef41Sopenharmony_ci      case IrOpcode::kDelayedStringConstant:
21491cb0ef41Sopenharmony_ci        return VisitLeaf<T>(node, MachineRepresentation::kTaggedPointer);
21501cb0ef41Sopenharmony_ci      case IrOpcode::kPointerConstant: {
21511cb0ef41Sopenharmony_ci        VisitLeaf<T>(node, MachineType::PointerRepresentation());
21521cb0ef41Sopenharmony_ci        if (lower<T>()) {
21531cb0ef41Sopenharmony_ci          intptr_t const value = OpParameter<intptr_t>(node->op());
21541cb0ef41Sopenharmony_ci          DeferReplacement(node, lowering->jsgraph()->IntPtrConstant(value));
21551cb0ef41Sopenharmony_ci        }
21561cb0ef41Sopenharmony_ci        return;
21571cb0ef41Sopenharmony_ci      }
21581cb0ef41Sopenharmony_ci
21591cb0ef41Sopenharmony_ci      case IrOpcode::kBranch: {
21601cb0ef41Sopenharmony_ci        DCHECK(TypeOf(node->InputAt(0)).Is(Type::Boolean()));
21611cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 0, UseInfo::Bool());
21621cb0ef41Sopenharmony_ci        EnqueueInput<T>(node, NodeProperties::FirstControlIndex(node));
21631cb0ef41Sopenharmony_ci        return;
21641cb0ef41Sopenharmony_ci      }
21651cb0ef41Sopenharmony_ci      case IrOpcode::kSwitch:
21661cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 0, UseInfo::TruncatingWord32());
21671cb0ef41Sopenharmony_ci        EnqueueInput<T>(node, NodeProperties::FirstControlIndex(node));
21681cb0ef41Sopenharmony_ci        return;
21691cb0ef41Sopenharmony_ci      case IrOpcode::kSelect:
21701cb0ef41Sopenharmony_ci        return VisitSelect<T>(node, truncation, lowering);
21711cb0ef41Sopenharmony_ci      case IrOpcode::kPhi:
21721cb0ef41Sopenharmony_ci        return VisitPhi<T>(node, truncation, lowering);
21731cb0ef41Sopenharmony_ci      case IrOpcode::kCall:
21741cb0ef41Sopenharmony_ci        return VisitCall<T>(node, lowering);
21751cb0ef41Sopenharmony_ci
21761cb0ef41Sopenharmony_ci      //------------------------------------------------------------------
21771cb0ef41Sopenharmony_ci      // JavaScript operators.
21781cb0ef41Sopenharmony_ci      //------------------------------------------------------------------
21791cb0ef41Sopenharmony_ci      case IrOpcode::kJSToNumber:
21801cb0ef41Sopenharmony_ci      case IrOpcode::kJSToNumberConvertBigInt:
21811cb0ef41Sopenharmony_ci      case IrOpcode::kJSToNumeric: {
21821cb0ef41Sopenharmony_ci        DCHECK(NodeProperties::GetType(node).Is(Type::Union(
21831cb0ef41Sopenharmony_ci            Type::BigInt(), Type::NumberOrOddball(), graph()->zone())));
21841cb0ef41Sopenharmony_ci        VisitInputs<T>(node);
21851cb0ef41Sopenharmony_ci        // TODO(bmeurer): Optimize somewhat based on input type?
21861cb0ef41Sopenharmony_ci        if (truncation.IsUsedAsWord32()) {
21871cb0ef41Sopenharmony_ci          SetOutput<T>(node, MachineRepresentation::kWord32);
21881cb0ef41Sopenharmony_ci          if (lower<T>())
21891cb0ef41Sopenharmony_ci            lowering->DoJSToNumberOrNumericTruncatesToWord32(node, this);
21901cb0ef41Sopenharmony_ci        } else if (truncation.TruncatesOddballAndBigIntToNumber()) {
21911cb0ef41Sopenharmony_ci          SetOutput<T>(node, MachineRepresentation::kFloat64);
21921cb0ef41Sopenharmony_ci          if (lower<T>())
21931cb0ef41Sopenharmony_ci            lowering->DoJSToNumberOrNumericTruncatesToFloat64(node, this);
21941cb0ef41Sopenharmony_ci        } else {
21951cb0ef41Sopenharmony_ci          SetOutput<T>(node, MachineRepresentation::kTagged);
21961cb0ef41Sopenharmony_ci        }
21971cb0ef41Sopenharmony_ci        return;
21981cb0ef41Sopenharmony_ci      }
21991cb0ef41Sopenharmony_ci
22001cb0ef41Sopenharmony_ci      //------------------------------------------------------------------
22011cb0ef41Sopenharmony_ci      // Simplified operators.
22021cb0ef41Sopenharmony_ci      //------------------------------------------------------------------
22031cb0ef41Sopenharmony_ci      case IrOpcode::kToBoolean: {
22041cb0ef41Sopenharmony_ci        if (truncation.IsUsedAsBool()) {
22051cb0ef41Sopenharmony_ci          ProcessInput<T>(node, 0, UseInfo::Bool());
22061cb0ef41Sopenharmony_ci          SetOutput<T>(node, MachineRepresentation::kBit);
22071cb0ef41Sopenharmony_ci          if (lower<T>()) DeferReplacement(node, node->InputAt(0));
22081cb0ef41Sopenharmony_ci        } else {
22091cb0ef41Sopenharmony_ci          VisitInputs<T>(node);
22101cb0ef41Sopenharmony_ci          SetOutput<T>(node, MachineRepresentation::kTaggedPointer);
22111cb0ef41Sopenharmony_ci        }
22121cb0ef41Sopenharmony_ci        return;
22131cb0ef41Sopenharmony_ci      }
22141cb0ef41Sopenharmony_ci      case IrOpcode::kBooleanNot: {
22151cb0ef41Sopenharmony_ci        if (lower<T>()) {
22161cb0ef41Sopenharmony_ci          NodeInfo* input_info = GetInfo(node->InputAt(0));
22171cb0ef41Sopenharmony_ci          if (input_info->representation() == MachineRepresentation::kBit) {
22181cb0ef41Sopenharmony_ci            // BooleanNot(x: kRepBit) => Word32Equal(x, #0)
22191cb0ef41Sopenharmony_ci            node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0));
22201cb0ef41Sopenharmony_ci            ChangeOp(node, lowering->machine()->Word32Equal());
22211cb0ef41Sopenharmony_ci          } else if (CanBeTaggedPointer(input_info->representation())) {
22221cb0ef41Sopenharmony_ci            // BooleanNot(x: kRepTagged) => WordEqual(x, #false)
22231cb0ef41Sopenharmony_ci            node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant());
22241cb0ef41Sopenharmony_ci            ChangeOp(node, lowering->machine()->WordEqual());
22251cb0ef41Sopenharmony_ci          } else {
22261cb0ef41Sopenharmony_ci            DCHECK(TypeOf(node->InputAt(0)).IsNone());
22271cb0ef41Sopenharmony_ci            DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
22281cb0ef41Sopenharmony_ci          }
22291cb0ef41Sopenharmony_ci        } else {
22301cb0ef41Sopenharmony_ci          // No input representation requirement; adapt during lowering.
22311cb0ef41Sopenharmony_ci          ProcessInput<T>(node, 0, UseInfo::AnyTruncatingToBool());
22321cb0ef41Sopenharmony_ci          SetOutput<T>(node, MachineRepresentation::kBit);
22331cb0ef41Sopenharmony_ci        }
22341cb0ef41Sopenharmony_ci        return;
22351cb0ef41Sopenharmony_ci      }
22361cb0ef41Sopenharmony_ci      case IrOpcode::kNumberEqual: {
22371cb0ef41Sopenharmony_ci        Type const lhs_type = TypeOf(node->InputAt(0));
22381cb0ef41Sopenharmony_ci        Type const rhs_type = TypeOf(node->InputAt(1));
22391cb0ef41Sopenharmony_ci        // Regular number comparisons in JavaScript generally identify zeros,
22401cb0ef41Sopenharmony_ci        // so we always pass kIdentifyZeros for the inputs, and in addition
22411cb0ef41Sopenharmony_ci        // we can truncate -0 to 0 for otherwise Unsigned32 or Signed32 inputs.
22421cb0ef41Sopenharmony_ci        // For equality we also handle the case that one side is non-zero, in
22431cb0ef41Sopenharmony_ci        // which case we allow to truncate NaN to 0 on the other side.
22441cb0ef41Sopenharmony_ci        if ((lhs_type.Is(Type::Unsigned32OrMinusZero()) &&
22451cb0ef41Sopenharmony_ci             rhs_type.Is(Type::Unsigned32OrMinusZero())) ||
22461cb0ef41Sopenharmony_ci            (lhs_type.Is(Type::Unsigned32OrMinusZeroOrNaN()) &&
22471cb0ef41Sopenharmony_ci             rhs_type.Is(Type::Unsigned32OrMinusZeroOrNaN()) &&
22481cb0ef41Sopenharmony_ci             OneInputCannotBe(node, type_cache_->kZeroish))) {
22491cb0ef41Sopenharmony_ci          // => unsigned Int32Cmp
22501cb0ef41Sopenharmony_ci          VisitBinop<T>(node, UseInfo::TruncatingWord32(),
22511cb0ef41Sopenharmony_ci                        MachineRepresentation::kBit);
22521cb0ef41Sopenharmony_ci          if (lower<T>()) ChangeOp(node, Uint32Op(node));
22531cb0ef41Sopenharmony_ci          return;
22541cb0ef41Sopenharmony_ci        }
22551cb0ef41Sopenharmony_ci        if ((lhs_type.Is(Type::Signed32OrMinusZero()) &&
22561cb0ef41Sopenharmony_ci             rhs_type.Is(Type::Signed32OrMinusZero())) ||
22571cb0ef41Sopenharmony_ci            (lhs_type.Is(Type::Signed32OrMinusZeroOrNaN()) &&
22581cb0ef41Sopenharmony_ci             rhs_type.Is(Type::Signed32OrMinusZeroOrNaN()) &&
22591cb0ef41Sopenharmony_ci             OneInputCannotBe(node, type_cache_->kZeroish))) {
22601cb0ef41Sopenharmony_ci          // => signed Int32Cmp
22611cb0ef41Sopenharmony_ci          VisitBinop<T>(node, UseInfo::TruncatingWord32(),
22621cb0ef41Sopenharmony_ci                        MachineRepresentation::kBit);
22631cb0ef41Sopenharmony_ci          if (lower<T>()) ChangeOp(node, Int32Op(node));
22641cb0ef41Sopenharmony_ci          return;
22651cb0ef41Sopenharmony_ci        }
22661cb0ef41Sopenharmony_ci        // => Float64Cmp
22671cb0ef41Sopenharmony_ci        VisitBinop<T>(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
22681cb0ef41Sopenharmony_ci                      MachineRepresentation::kBit);
22691cb0ef41Sopenharmony_ci        if (lower<T>()) ChangeOp(node, Float64Op(node));
22701cb0ef41Sopenharmony_ci        return;
22711cb0ef41Sopenharmony_ci      }
22721cb0ef41Sopenharmony_ci      case IrOpcode::kNumberLessThan:
22731cb0ef41Sopenharmony_ci      case IrOpcode::kNumberLessThanOrEqual: {
22741cb0ef41Sopenharmony_ci        Type const lhs_type = TypeOf(node->InputAt(0));
22751cb0ef41Sopenharmony_ci        Type const rhs_type = TypeOf(node->InputAt(1));
22761cb0ef41Sopenharmony_ci        // Regular number comparisons in JavaScript generally identify zeros,
22771cb0ef41Sopenharmony_ci        // so we always pass kIdentifyZeros for the inputs, and in addition
22781cb0ef41Sopenharmony_ci        // we can truncate -0 to 0 for otherwise Unsigned32 or Signed32 inputs.
22791cb0ef41Sopenharmony_ci        if (lhs_type.Is(Type::Unsigned32OrMinusZero()) &&
22801cb0ef41Sopenharmony_ci            rhs_type.Is(Type::Unsigned32OrMinusZero())) {
22811cb0ef41Sopenharmony_ci          // => unsigned Int32Cmp
22821cb0ef41Sopenharmony_ci          VisitBinop<T>(node, UseInfo::TruncatingWord32(),
22831cb0ef41Sopenharmony_ci                        MachineRepresentation::kBit);
22841cb0ef41Sopenharmony_ci          if (lower<T>()) ChangeOp(node, Uint32Op(node));
22851cb0ef41Sopenharmony_ci        } else if (lhs_type.Is(Type::Signed32OrMinusZero()) &&
22861cb0ef41Sopenharmony_ci                   rhs_type.Is(Type::Signed32OrMinusZero())) {
22871cb0ef41Sopenharmony_ci          // => signed Int32Cmp
22881cb0ef41Sopenharmony_ci          VisitBinop<T>(node, UseInfo::TruncatingWord32(),
22891cb0ef41Sopenharmony_ci                        MachineRepresentation::kBit);
22901cb0ef41Sopenharmony_ci          if (lower<T>()) ChangeOp(node, Int32Op(node));
22911cb0ef41Sopenharmony_ci        } else {
22921cb0ef41Sopenharmony_ci          // => Float64Cmp
22931cb0ef41Sopenharmony_ci          VisitBinop<T>(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
22941cb0ef41Sopenharmony_ci                        MachineRepresentation::kBit);
22951cb0ef41Sopenharmony_ci          if (lower<T>()) ChangeOp(node, Float64Op(node));
22961cb0ef41Sopenharmony_ci        }
22971cb0ef41Sopenharmony_ci        return;
22981cb0ef41Sopenharmony_ci      }
22991cb0ef41Sopenharmony_ci
23001cb0ef41Sopenharmony_ci      case IrOpcode::kSpeculativeSafeIntegerAdd:
23011cb0ef41Sopenharmony_ci      case IrOpcode::kSpeculativeSafeIntegerSubtract:
23021cb0ef41Sopenharmony_ci        return VisitSpeculativeIntegerAdditiveOp<T>(node, truncation, lowering);
23031cb0ef41Sopenharmony_ci
23041cb0ef41Sopenharmony_ci      case IrOpcode::kSpeculativeNumberAdd:
23051cb0ef41Sopenharmony_ci      case IrOpcode::kSpeculativeNumberSubtract:
23061cb0ef41Sopenharmony_ci        return VisitSpeculativeAdditiveOp<T>(node, truncation, lowering);
23071cb0ef41Sopenharmony_ci
23081cb0ef41Sopenharmony_ci      case IrOpcode::kSpeculativeNumberLessThan:
23091cb0ef41Sopenharmony_ci      case IrOpcode::kSpeculativeNumberLessThanOrEqual:
23101cb0ef41Sopenharmony_ci      case IrOpcode::kSpeculativeNumberEqual: {
23111cb0ef41Sopenharmony_ci        Type const lhs_type = TypeOf(node->InputAt(0));
23121cb0ef41Sopenharmony_ci        Type const rhs_type = TypeOf(node->InputAt(1));
23131cb0ef41Sopenharmony_ci        // Regular number comparisons in JavaScript generally identify zeros,
23141cb0ef41Sopenharmony_ci        // so we always pass kIdentifyZeros for the inputs, and in addition
23151cb0ef41Sopenharmony_ci        // we can truncate -0 to 0 for otherwise Unsigned32 or Signed32 inputs.
23161cb0ef41Sopenharmony_ci        if (lhs_type.Is(Type::Unsigned32OrMinusZero()) &&
23171cb0ef41Sopenharmony_ci            rhs_type.Is(Type::Unsigned32OrMinusZero())) {
23181cb0ef41Sopenharmony_ci          // => unsigned Int32Cmp
23191cb0ef41Sopenharmony_ci          VisitBinop<T>(node, UseInfo::TruncatingWord32(),
23201cb0ef41Sopenharmony_ci                        MachineRepresentation::kBit);
23211cb0ef41Sopenharmony_ci          if (lower<T>()) ChangeToPureOp(node, Uint32Op(node));
23221cb0ef41Sopenharmony_ci          return;
23231cb0ef41Sopenharmony_ci        } else if (lhs_type.Is(Type::Signed32OrMinusZero()) &&
23241cb0ef41Sopenharmony_ci                   rhs_type.Is(Type::Signed32OrMinusZero())) {
23251cb0ef41Sopenharmony_ci          // => signed Int32Cmp
23261cb0ef41Sopenharmony_ci          VisitBinop<T>(node, UseInfo::TruncatingWord32(),
23271cb0ef41Sopenharmony_ci                        MachineRepresentation::kBit);
23281cb0ef41Sopenharmony_ci          if (lower<T>()) ChangeToPureOp(node, Int32Op(node));
23291cb0ef41Sopenharmony_ci          return;
23301cb0ef41Sopenharmony_ci        }
23311cb0ef41Sopenharmony_ci        // Try to use type feedback.
23321cb0ef41Sopenharmony_ci        NumberOperationHint hint = NumberOperationHintOf(node->op());
23331cb0ef41Sopenharmony_ci        switch (hint) {
23341cb0ef41Sopenharmony_ci          case NumberOperationHint::kSignedSmall:
23351cb0ef41Sopenharmony_ci            if (propagate<T>()) {
23361cb0ef41Sopenharmony_ci              VisitBinop<T>(
23371cb0ef41Sopenharmony_ci                  node, CheckedUseInfoAsWord32FromHint(hint, kIdentifyZeros),
23381cb0ef41Sopenharmony_ci                  MachineRepresentation::kBit);
23391cb0ef41Sopenharmony_ci            } else if (retype<T>()) {
23401cb0ef41Sopenharmony_ci              SetOutput<T>(node, MachineRepresentation::kBit, Type::Any());
23411cb0ef41Sopenharmony_ci            } else {
23421cb0ef41Sopenharmony_ci              DCHECK(lower<T>());
23431cb0ef41Sopenharmony_ci              Node* lhs = node->InputAt(0);
23441cb0ef41Sopenharmony_ci              Node* rhs = node->InputAt(1);
23451cb0ef41Sopenharmony_ci              if (IsNodeRepresentationTagged(lhs) &&
23461cb0ef41Sopenharmony_ci                  IsNodeRepresentationTagged(rhs)) {
23471cb0ef41Sopenharmony_ci                VisitBinop<T>(node,
23481cb0ef41Sopenharmony_ci                              UseInfo::CheckedSignedSmallAsTaggedSigned(
23491cb0ef41Sopenharmony_ci                                  FeedbackSource(), kIdentifyZeros),
23501cb0ef41Sopenharmony_ci                              MachineRepresentation::kBit);
23511cb0ef41Sopenharmony_ci                ChangeToPureOp(
23521cb0ef41Sopenharmony_ci                    node, changer_->TaggedSignedOperatorFor(node->opcode()));
23531cb0ef41Sopenharmony_ci
23541cb0ef41Sopenharmony_ci              } else {
23551cb0ef41Sopenharmony_ci                VisitBinop<T>(
23561cb0ef41Sopenharmony_ci                    node, CheckedUseInfoAsWord32FromHint(hint, kIdentifyZeros),
23571cb0ef41Sopenharmony_ci                    MachineRepresentation::kBit);
23581cb0ef41Sopenharmony_ci                ChangeToPureOp(node, Int32Op(node));
23591cb0ef41Sopenharmony_ci              }
23601cb0ef41Sopenharmony_ci            }
23611cb0ef41Sopenharmony_ci            return;
23621cb0ef41Sopenharmony_ci          case NumberOperationHint::kSignedSmallInputs:
23631cb0ef41Sopenharmony_ci            // This doesn't make sense for compare operations.
23641cb0ef41Sopenharmony_ci            UNREACHABLE();
23651cb0ef41Sopenharmony_ci          case NumberOperationHint::kNumberOrOddball:
23661cb0ef41Sopenharmony_ci            // Abstract and strict equality don't perform ToNumber conversions
23671cb0ef41Sopenharmony_ci            // on Oddballs, so make sure we don't accidentially sneak in a
23681cb0ef41Sopenharmony_ci            // hint with Oddball feedback here.
23691cb0ef41Sopenharmony_ci            DCHECK_NE(IrOpcode::kSpeculativeNumberEqual, node->opcode());
23701cb0ef41Sopenharmony_ci            V8_FALLTHROUGH;
23711cb0ef41Sopenharmony_ci          case NumberOperationHint::kNumberOrBoolean:
23721cb0ef41Sopenharmony_ci          case NumberOperationHint::kNumber:
23731cb0ef41Sopenharmony_ci            VisitBinop<T>(node,
23741cb0ef41Sopenharmony_ci                          CheckedUseInfoAsFloat64FromHint(
23751cb0ef41Sopenharmony_ci                              hint, FeedbackSource(), kIdentifyZeros),
23761cb0ef41Sopenharmony_ci                          MachineRepresentation::kBit);
23771cb0ef41Sopenharmony_ci            if (lower<T>()) ChangeToPureOp(node, Float64Op(node));
23781cb0ef41Sopenharmony_ci            return;
23791cb0ef41Sopenharmony_ci        }
23801cb0ef41Sopenharmony_ci        UNREACHABLE();
23811cb0ef41Sopenharmony_ci        return;
23821cb0ef41Sopenharmony_ci      }
23831cb0ef41Sopenharmony_ci
23841cb0ef41Sopenharmony_ci      case IrOpcode::kNumberAdd:
23851cb0ef41Sopenharmony_ci      case IrOpcode::kNumberSubtract: {
23861cb0ef41Sopenharmony_ci        if (TypeOf(node->InputAt(0))
23871cb0ef41Sopenharmony_ci                .Is(type_cache_->kAdditiveSafeIntegerOrMinusZero) &&
23881cb0ef41Sopenharmony_ci            TypeOf(node->InputAt(1))
23891cb0ef41Sopenharmony_ci                .Is(type_cache_->kAdditiveSafeIntegerOrMinusZero) &&
23901cb0ef41Sopenharmony_ci            (TypeOf(node).Is(Type::Signed32()) ||
23911cb0ef41Sopenharmony_ci             TypeOf(node).Is(Type::Unsigned32()) ||
23921cb0ef41Sopenharmony_ci             truncation.IsUsedAsWord32())) {
23931cb0ef41Sopenharmony_ci          // => Int32Add/Sub
23941cb0ef41Sopenharmony_ci          VisitWord32TruncatingBinop<T>(node);
23951cb0ef41Sopenharmony_ci          if (lower<T>()) ChangeToPureOp(node, Int32Op(node));
23961cb0ef41Sopenharmony_ci        } else if (jsgraph_->machine()->Is64() &&
23971cb0ef41Sopenharmony_ci                   BothInputsAre(node, type_cache_->kSafeInteger) &&
23981cb0ef41Sopenharmony_ci                   GetUpperBound(node).Is(type_cache_->kSafeInteger)) {
23991cb0ef41Sopenharmony_ci          // => Int64Add/Sub
24001cb0ef41Sopenharmony_ci          VisitInt64Binop<T>(node);
24011cb0ef41Sopenharmony_ci          if (lower<T>()) ChangeToPureOp(node, Int64Op(node));
24021cb0ef41Sopenharmony_ci        } else {
24031cb0ef41Sopenharmony_ci          // => Float64Add/Sub
24041cb0ef41Sopenharmony_ci          VisitFloat64Binop<T>(node);
24051cb0ef41Sopenharmony_ci          if (lower<T>()) ChangeToPureOp(node, Float64Op(node));
24061cb0ef41Sopenharmony_ci        }
24071cb0ef41Sopenharmony_ci        return;
24081cb0ef41Sopenharmony_ci      }
24091cb0ef41Sopenharmony_ci      case IrOpcode::kSpeculativeNumberMultiply: {
24101cb0ef41Sopenharmony_ci        if (BothInputsAre(node, Type::Integral32()) &&
24111cb0ef41Sopenharmony_ci            (NodeProperties::GetType(node).Is(Type::Signed32()) ||
24121cb0ef41Sopenharmony_ci             NodeProperties::GetType(node).Is(Type::Unsigned32()) ||
24131cb0ef41Sopenharmony_ci             (truncation.IsUsedAsWord32() &&
24141cb0ef41Sopenharmony_ci              NodeProperties::GetType(node).Is(
24151cb0ef41Sopenharmony_ci                  type_cache_->kSafeIntegerOrMinusZero)))) {
24161cb0ef41Sopenharmony_ci          // Multiply reduces to Int32Mul if the inputs are integers, and
24171cb0ef41Sopenharmony_ci          // (a) the output is either known to be Signed32, or
24181cb0ef41Sopenharmony_ci          // (b) the output is known to be Unsigned32, or
24191cb0ef41Sopenharmony_ci          // (c) the uses are truncating and the result is in the safe
24201cb0ef41Sopenharmony_ci          //     integer range.
24211cb0ef41Sopenharmony_ci          VisitWord32TruncatingBinop<T>(node);
24221cb0ef41Sopenharmony_ci          if (lower<T>()) ChangeToPureOp(node, Int32Op(node));
24231cb0ef41Sopenharmony_ci          return;
24241cb0ef41Sopenharmony_ci        }
24251cb0ef41Sopenharmony_ci        // Try to use type feedback.
24261cb0ef41Sopenharmony_ci        NumberOperationHint hint = NumberOperationHintOf(node->op());
24271cb0ef41Sopenharmony_ci        Type input0_type = TypeOf(node->InputAt(0));
24281cb0ef41Sopenharmony_ci        Type input1_type = TypeOf(node->InputAt(1));
24291cb0ef41Sopenharmony_ci
24301cb0ef41Sopenharmony_ci        // Handle the case when no int32 checks on inputs are necessary
24311cb0ef41Sopenharmony_ci        // (but an overflow check is needed on the output).
24321cb0ef41Sopenharmony_ci        if (BothInputsAre(node, Type::Signed32())) {
24331cb0ef41Sopenharmony_ci          // If both inputs and feedback are int32, use the overflow op.
24341cb0ef41Sopenharmony_ci          if (hint == NumberOperationHint::kSignedSmall) {
24351cb0ef41Sopenharmony_ci            VisitForCheckedInt32Mul<T>(node, truncation, input0_type,
24361cb0ef41Sopenharmony_ci                                       input1_type,
24371cb0ef41Sopenharmony_ci                                       UseInfo::TruncatingWord32());
24381cb0ef41Sopenharmony_ci            return;
24391cb0ef41Sopenharmony_ci          }
24401cb0ef41Sopenharmony_ci        }
24411cb0ef41Sopenharmony_ci
24421cb0ef41Sopenharmony_ci        if (hint == NumberOperationHint::kSignedSmall) {
24431cb0ef41Sopenharmony_ci          VisitForCheckedInt32Mul<T>(node, truncation, input0_type, input1_type,
24441cb0ef41Sopenharmony_ci                                     CheckedUseInfoAsWord32FromHint(hint));
24451cb0ef41Sopenharmony_ci          return;
24461cb0ef41Sopenharmony_ci        }
24471cb0ef41Sopenharmony_ci
24481cb0ef41Sopenharmony_ci        // Checked float64 x float64 => float64
24491cb0ef41Sopenharmony_ci        VisitBinop<T>(node,
24501cb0ef41Sopenharmony_ci                      UseInfo::CheckedNumberOrOddballAsFloat64(
24511cb0ef41Sopenharmony_ci                          kDistinguishZeros, FeedbackSource()),
24521cb0ef41Sopenharmony_ci                      MachineRepresentation::kFloat64, Type::Number());
24531cb0ef41Sopenharmony_ci        if (lower<T>()) ChangeToPureOp(node, Float64Op(node));
24541cb0ef41Sopenharmony_ci        return;
24551cb0ef41Sopenharmony_ci      }
24561cb0ef41Sopenharmony_ci      case IrOpcode::kNumberMultiply: {
24571cb0ef41Sopenharmony_ci        if (TypeOf(node->InputAt(0)).Is(Type::Integral32()) &&
24581cb0ef41Sopenharmony_ci            TypeOf(node->InputAt(1)).Is(Type::Integral32()) &&
24591cb0ef41Sopenharmony_ci            (TypeOf(node).Is(Type::Signed32()) ||
24601cb0ef41Sopenharmony_ci             TypeOf(node).Is(Type::Unsigned32()) ||
24611cb0ef41Sopenharmony_ci             (truncation.IsUsedAsWord32() &&
24621cb0ef41Sopenharmony_ci              TypeOf(node).Is(type_cache_->kSafeIntegerOrMinusZero)))) {
24631cb0ef41Sopenharmony_ci          // Multiply reduces to Int32Mul if the inputs are integers, and
24641cb0ef41Sopenharmony_ci          // (a) the output is either known to be Signed32, or
24651cb0ef41Sopenharmony_ci          // (b) the output is known to be Unsigned32, or
24661cb0ef41Sopenharmony_ci          // (c) the uses are truncating and the result is in the safe
24671cb0ef41Sopenharmony_ci          //     integer range.
24681cb0ef41Sopenharmony_ci          VisitWord32TruncatingBinop<T>(node);
24691cb0ef41Sopenharmony_ci          if (lower<T>()) ChangeToPureOp(node, Int32Op(node));
24701cb0ef41Sopenharmony_ci          return;
24711cb0ef41Sopenharmony_ci        }
24721cb0ef41Sopenharmony_ci        // Number x Number => Float64Mul
24731cb0ef41Sopenharmony_ci        VisitFloat64Binop<T>(node);
24741cb0ef41Sopenharmony_ci        if (lower<T>()) ChangeToPureOp(node, Float64Op(node));
24751cb0ef41Sopenharmony_ci        return;
24761cb0ef41Sopenharmony_ci      }
24771cb0ef41Sopenharmony_ci      case IrOpcode::kSpeculativeNumberDivide: {
24781cb0ef41Sopenharmony_ci        if (BothInputsAreUnsigned32(node) && truncation.IsUsedAsWord32()) {
24791cb0ef41Sopenharmony_ci          // => unsigned Uint32Div
24801cb0ef41Sopenharmony_ci          VisitWord32TruncatingBinop<T>(node);
24811cb0ef41Sopenharmony_ci          if (lower<T>()) DeferReplacement(node, lowering->Uint32Div(node));
24821cb0ef41Sopenharmony_ci          return;
24831cb0ef41Sopenharmony_ci        }
24841cb0ef41Sopenharmony_ci        if (BothInputsAreSigned32(node)) {
24851cb0ef41Sopenharmony_ci          if (NodeProperties::GetType(node).Is(Type::Signed32())) {
24861cb0ef41Sopenharmony_ci            // => signed Int32Div
24871cb0ef41Sopenharmony_ci            VisitWord32TruncatingBinop<T>(node);
24881cb0ef41Sopenharmony_ci            if (lower<T>()) DeferReplacement(node, lowering->Int32Div(node));
24891cb0ef41Sopenharmony_ci            return;
24901cb0ef41Sopenharmony_ci          }
24911cb0ef41Sopenharmony_ci          if (truncation.IsUsedAsWord32()) {
24921cb0ef41Sopenharmony_ci            // => signed Int32Div
24931cb0ef41Sopenharmony_ci            VisitWord32TruncatingBinop<T>(node);
24941cb0ef41Sopenharmony_ci            if (lower<T>()) DeferReplacement(node, lowering->Int32Div(node));
24951cb0ef41Sopenharmony_ci            return;
24961cb0ef41Sopenharmony_ci          }
24971cb0ef41Sopenharmony_ci        }
24981cb0ef41Sopenharmony_ci
24991cb0ef41Sopenharmony_ci        // Try to use type feedback.
25001cb0ef41Sopenharmony_ci        NumberOperationHint hint = NumberOperationHintOf(node->op());
25011cb0ef41Sopenharmony_ci
25021cb0ef41Sopenharmony_ci        // Handle the case when no uint32 checks on inputs are necessary
25031cb0ef41Sopenharmony_ci        // (but an overflow check is needed on the output).
25041cb0ef41Sopenharmony_ci        if (BothInputsAreUnsigned32(node)) {
25051cb0ef41Sopenharmony_ci          if (hint == NumberOperationHint::kSignedSmall) {
25061cb0ef41Sopenharmony_ci            VisitBinop<T>(node, UseInfo::TruncatingWord32(),
25071cb0ef41Sopenharmony_ci                          MachineRepresentation::kWord32, Type::Unsigned32());
25081cb0ef41Sopenharmony_ci            if (lower<T>()) ChangeToUint32OverflowOp(node);
25091cb0ef41Sopenharmony_ci            return;
25101cb0ef41Sopenharmony_ci          }
25111cb0ef41Sopenharmony_ci        }
25121cb0ef41Sopenharmony_ci
25131cb0ef41Sopenharmony_ci        // Handle the case when no int32 checks on inputs are necessary
25141cb0ef41Sopenharmony_ci        // (but an overflow check is needed on the output).
25151cb0ef41Sopenharmony_ci        if (BothInputsAreSigned32(node)) {
25161cb0ef41Sopenharmony_ci          // If both the inputs the feedback are int32, use the overflow op.
25171cb0ef41Sopenharmony_ci          if (hint == NumberOperationHint::kSignedSmall) {
25181cb0ef41Sopenharmony_ci            VisitBinop<T>(node, UseInfo::TruncatingWord32(),
25191cb0ef41Sopenharmony_ci                          MachineRepresentation::kWord32, Type::Signed32());
25201cb0ef41Sopenharmony_ci            if (lower<T>()) ChangeToInt32OverflowOp(node);
25211cb0ef41Sopenharmony_ci            return;
25221cb0ef41Sopenharmony_ci          }
25231cb0ef41Sopenharmony_ci        }
25241cb0ef41Sopenharmony_ci
25251cb0ef41Sopenharmony_ci        if (hint == NumberOperationHint::kSignedSmall ||
25261cb0ef41Sopenharmony_ci            hint == NumberOperationHint::kSignedSmallInputs) {
25271cb0ef41Sopenharmony_ci          // If the result is truncated, we only need to check the inputs.
25281cb0ef41Sopenharmony_ci          if (truncation.IsUsedAsWord32()) {
25291cb0ef41Sopenharmony_ci            VisitBinop<T>(node, CheckedUseInfoAsWord32FromHint(hint),
25301cb0ef41Sopenharmony_ci                          MachineRepresentation::kWord32);
25311cb0ef41Sopenharmony_ci            if (lower<T>()) DeferReplacement(node, lowering->Int32Div(node));
25321cb0ef41Sopenharmony_ci            return;
25331cb0ef41Sopenharmony_ci          } else if (hint != NumberOperationHint::kSignedSmallInputs) {
25341cb0ef41Sopenharmony_ci            VisitBinop<T>(node, CheckedUseInfoAsWord32FromHint(hint),
25351cb0ef41Sopenharmony_ci                          MachineRepresentation::kWord32, Type::Signed32());
25361cb0ef41Sopenharmony_ci            if (lower<T>()) ChangeToInt32OverflowOp(node);
25371cb0ef41Sopenharmony_ci            return;
25381cb0ef41Sopenharmony_ci          }
25391cb0ef41Sopenharmony_ci        }
25401cb0ef41Sopenharmony_ci
25411cb0ef41Sopenharmony_ci        // default case => Float64Div
25421cb0ef41Sopenharmony_ci        VisitBinop<T>(node,
25431cb0ef41Sopenharmony_ci                      UseInfo::CheckedNumberOrOddballAsFloat64(
25441cb0ef41Sopenharmony_ci                          kDistinguishZeros, FeedbackSource()),
25451cb0ef41Sopenharmony_ci                      MachineRepresentation::kFloat64, Type::Number());
25461cb0ef41Sopenharmony_ci        if (lower<T>()) ChangeToPureOp(node, Float64Op(node));
25471cb0ef41Sopenharmony_ci        return;
25481cb0ef41Sopenharmony_ci      }
25491cb0ef41Sopenharmony_ci      case IrOpcode::kNumberDivide: {
25501cb0ef41Sopenharmony_ci        if (TypeOf(node->InputAt(0)).Is(Type::Unsigned32()) &&
25511cb0ef41Sopenharmony_ci            TypeOf(node->InputAt(1)).Is(Type::Unsigned32()) &&
25521cb0ef41Sopenharmony_ci            (truncation.IsUsedAsWord32() ||
25531cb0ef41Sopenharmony_ci             TypeOf(node).Is(Type::Unsigned32()))) {
25541cb0ef41Sopenharmony_ci          // => unsigned Uint32Div
25551cb0ef41Sopenharmony_ci          VisitWord32TruncatingBinop<T>(node);
25561cb0ef41Sopenharmony_ci          if (lower<T>()) DeferReplacement(node, lowering->Uint32Div(node));
25571cb0ef41Sopenharmony_ci          return;
25581cb0ef41Sopenharmony_ci        }
25591cb0ef41Sopenharmony_ci        if (TypeOf(node->InputAt(0)).Is(Type::Signed32()) &&
25601cb0ef41Sopenharmony_ci            TypeOf(node->InputAt(1)).Is(Type::Signed32()) &&
25611cb0ef41Sopenharmony_ci            (truncation.IsUsedAsWord32() ||
25621cb0ef41Sopenharmony_ci             TypeOf(node).Is(Type::Signed32()))) {
25631cb0ef41Sopenharmony_ci          // => signed Int32Div
25641cb0ef41Sopenharmony_ci          VisitWord32TruncatingBinop<T>(node);
25651cb0ef41Sopenharmony_ci          if (lower<T>()) DeferReplacement(node, lowering->Int32Div(node));
25661cb0ef41Sopenharmony_ci          return;
25671cb0ef41Sopenharmony_ci        }
25681cb0ef41Sopenharmony_ci        // Number x Number => Float64Div
25691cb0ef41Sopenharmony_ci        VisitFloat64Binop<T>(node);
25701cb0ef41Sopenharmony_ci        if (lower<T>()) ChangeToPureOp(node, Float64Op(node));
25711cb0ef41Sopenharmony_ci        return;
25721cb0ef41Sopenharmony_ci      }
25731cb0ef41Sopenharmony_ci      case IrOpcode::kSpeculativeNumberModulus:
25741cb0ef41Sopenharmony_ci        return VisitSpeculativeNumberModulus<T>(node, truncation, lowering);
25751cb0ef41Sopenharmony_ci      case IrOpcode::kNumberModulus: {
25761cb0ef41Sopenharmony_ci        Type const lhs_type = TypeOf(node->InputAt(0));
25771cb0ef41Sopenharmony_ci        Type const rhs_type = TypeOf(node->InputAt(1));
25781cb0ef41Sopenharmony_ci        if ((lhs_type.Is(Type::Unsigned32OrMinusZeroOrNaN()) &&
25791cb0ef41Sopenharmony_ci             rhs_type.Is(Type::Unsigned32OrMinusZeroOrNaN())) &&
25801cb0ef41Sopenharmony_ci            (truncation.IsUsedAsWord32() ||
25811cb0ef41Sopenharmony_ci             TypeOf(node).Is(Type::Unsigned32()))) {
25821cb0ef41Sopenharmony_ci          // => unsigned Uint32Mod
25831cb0ef41Sopenharmony_ci          VisitWord32TruncatingBinop<T>(node);
25841cb0ef41Sopenharmony_ci          if (lower<T>()) DeferReplacement(node, lowering->Uint32Mod(node));
25851cb0ef41Sopenharmony_ci          return;
25861cb0ef41Sopenharmony_ci        }
25871cb0ef41Sopenharmony_ci        if ((lhs_type.Is(Type::Signed32OrMinusZeroOrNaN()) &&
25881cb0ef41Sopenharmony_ci             rhs_type.Is(Type::Signed32OrMinusZeroOrNaN())) &&
25891cb0ef41Sopenharmony_ci            (truncation.IsUsedAsWord32() || TypeOf(node).Is(Type::Signed32()) ||
25901cb0ef41Sopenharmony_ci             (truncation.IdentifiesZeroAndMinusZero() &&
25911cb0ef41Sopenharmony_ci              TypeOf(node).Is(Type::Signed32OrMinusZero())))) {
25921cb0ef41Sopenharmony_ci          // => signed Int32Mod
25931cb0ef41Sopenharmony_ci          VisitWord32TruncatingBinop<T>(node);
25941cb0ef41Sopenharmony_ci          if (lower<T>()) DeferReplacement(node, lowering->Int32Mod(node));
25951cb0ef41Sopenharmony_ci          return;
25961cb0ef41Sopenharmony_ci        }
25971cb0ef41Sopenharmony_ci        // => Float64Mod
25981cb0ef41Sopenharmony_ci        // For the left hand side we just propagate the identify zeros
25991cb0ef41Sopenharmony_ci        // mode of the {truncation}; and for modulus the sign of the
26001cb0ef41Sopenharmony_ci        // right hand side doesn't matter anyways, so in particular there's
26011cb0ef41Sopenharmony_ci        // no observable difference between a 0 and a -0 then.
26021cb0ef41Sopenharmony_ci        UseInfo const lhs_use =
26031cb0ef41Sopenharmony_ci            UseInfo::TruncatingFloat64(truncation.identify_zeros());
26041cb0ef41Sopenharmony_ci        UseInfo const rhs_use = UseInfo::TruncatingFloat64(kIdentifyZeros);
26051cb0ef41Sopenharmony_ci        VisitBinop<T>(node, lhs_use, rhs_use, MachineRepresentation::kFloat64);
26061cb0ef41Sopenharmony_ci        if (lower<T>()) ChangeToPureOp(node, Float64Op(node));
26071cb0ef41Sopenharmony_ci        return;
26081cb0ef41Sopenharmony_ci      }
26091cb0ef41Sopenharmony_ci      case IrOpcode::kNumberBitwiseOr:
26101cb0ef41Sopenharmony_ci      case IrOpcode::kNumberBitwiseXor:
26111cb0ef41Sopenharmony_ci      case IrOpcode::kNumberBitwiseAnd: {
26121cb0ef41Sopenharmony_ci        VisitWord32TruncatingBinop<T>(node);
26131cb0ef41Sopenharmony_ci        if (lower<T>()) ChangeOp(node, Int32Op(node));
26141cb0ef41Sopenharmony_ci        return;
26151cb0ef41Sopenharmony_ci      }
26161cb0ef41Sopenharmony_ci      case IrOpcode::kSpeculativeNumberBitwiseOr:
26171cb0ef41Sopenharmony_ci      case IrOpcode::kSpeculativeNumberBitwiseXor:
26181cb0ef41Sopenharmony_ci      case IrOpcode::kSpeculativeNumberBitwiseAnd:
26191cb0ef41Sopenharmony_ci        VisitSpeculativeInt32Binop<T>(node);
26201cb0ef41Sopenharmony_ci        if (lower<T>()) {
26211cb0ef41Sopenharmony_ci          ChangeToPureOp(node, Int32Op(node));
26221cb0ef41Sopenharmony_ci        }
26231cb0ef41Sopenharmony_ci        return;
26241cb0ef41Sopenharmony_ci      case IrOpcode::kNumberShiftLeft: {
26251cb0ef41Sopenharmony_ci        Type rhs_type = GetUpperBound(node->InputAt(1));
26261cb0ef41Sopenharmony_ci        VisitBinop<T>(node, UseInfo::TruncatingWord32(),
26271cb0ef41Sopenharmony_ci                      UseInfo::TruncatingWord32(),
26281cb0ef41Sopenharmony_ci                      MachineRepresentation::kWord32);
26291cb0ef41Sopenharmony_ci        if (lower<T>()) {
26301cb0ef41Sopenharmony_ci          MaskShiftOperand(node, rhs_type);
26311cb0ef41Sopenharmony_ci          ChangeToPureOp(node, lowering->machine()->Word32Shl());
26321cb0ef41Sopenharmony_ci        }
26331cb0ef41Sopenharmony_ci        return;
26341cb0ef41Sopenharmony_ci      }
26351cb0ef41Sopenharmony_ci      case IrOpcode::kSpeculativeNumberShiftLeft: {
26361cb0ef41Sopenharmony_ci        if (BothInputsAre(node, Type::NumberOrOddball())) {
26371cb0ef41Sopenharmony_ci          Type rhs_type = GetUpperBound(node->InputAt(1));
26381cb0ef41Sopenharmony_ci          VisitBinop<T>(node, UseInfo::TruncatingWord32(),
26391cb0ef41Sopenharmony_ci                        UseInfo::TruncatingWord32(),
26401cb0ef41Sopenharmony_ci                        MachineRepresentation::kWord32);
26411cb0ef41Sopenharmony_ci          if (lower<T>()) {
26421cb0ef41Sopenharmony_ci            MaskShiftOperand(node, rhs_type);
26431cb0ef41Sopenharmony_ci            ChangeToPureOp(node, lowering->machine()->Word32Shl());
26441cb0ef41Sopenharmony_ci          }
26451cb0ef41Sopenharmony_ci          return;
26461cb0ef41Sopenharmony_ci        }
26471cb0ef41Sopenharmony_ci        NumberOperationHint hint = NumberOperationHintOf(node->op());
26481cb0ef41Sopenharmony_ci        Type rhs_type = GetUpperBound(node->InputAt(1));
26491cb0ef41Sopenharmony_ci        VisitBinop<T>(node,
26501cb0ef41Sopenharmony_ci                      CheckedUseInfoAsWord32FromHint(hint, kIdentifyZeros),
26511cb0ef41Sopenharmony_ci                      MachineRepresentation::kWord32, Type::Signed32());
26521cb0ef41Sopenharmony_ci        if (lower<T>()) {
26531cb0ef41Sopenharmony_ci          MaskShiftOperand(node, rhs_type);
26541cb0ef41Sopenharmony_ci          ChangeToPureOp(node, lowering->machine()->Word32Shl());
26551cb0ef41Sopenharmony_ci        }
26561cb0ef41Sopenharmony_ci        return;
26571cb0ef41Sopenharmony_ci      }
26581cb0ef41Sopenharmony_ci      case IrOpcode::kNumberShiftRight: {
26591cb0ef41Sopenharmony_ci        Type rhs_type = GetUpperBound(node->InputAt(1));
26601cb0ef41Sopenharmony_ci        VisitBinop<T>(node, UseInfo::TruncatingWord32(),
26611cb0ef41Sopenharmony_ci                      UseInfo::TruncatingWord32(),
26621cb0ef41Sopenharmony_ci                      MachineRepresentation::kWord32);
26631cb0ef41Sopenharmony_ci        if (lower<T>()) {
26641cb0ef41Sopenharmony_ci          MaskShiftOperand(node, rhs_type);
26651cb0ef41Sopenharmony_ci          ChangeToPureOp(node, lowering->machine()->Word32Sar());
26661cb0ef41Sopenharmony_ci        }
26671cb0ef41Sopenharmony_ci        return;
26681cb0ef41Sopenharmony_ci      }
26691cb0ef41Sopenharmony_ci      case IrOpcode::kSpeculativeNumberShiftRight: {
26701cb0ef41Sopenharmony_ci        if (BothInputsAre(node, Type::NumberOrOddball())) {
26711cb0ef41Sopenharmony_ci          Type rhs_type = GetUpperBound(node->InputAt(1));
26721cb0ef41Sopenharmony_ci          VisitBinop<T>(node, UseInfo::TruncatingWord32(),
26731cb0ef41Sopenharmony_ci                        UseInfo::TruncatingWord32(),
26741cb0ef41Sopenharmony_ci                        MachineRepresentation::kWord32);
26751cb0ef41Sopenharmony_ci          if (lower<T>()) {
26761cb0ef41Sopenharmony_ci            MaskShiftOperand(node, rhs_type);
26771cb0ef41Sopenharmony_ci            ChangeToPureOp(node, lowering->machine()->Word32Sar());
26781cb0ef41Sopenharmony_ci          }
26791cb0ef41Sopenharmony_ci          return;
26801cb0ef41Sopenharmony_ci        }
26811cb0ef41Sopenharmony_ci        NumberOperationHint hint = NumberOperationHintOf(node->op());
26821cb0ef41Sopenharmony_ci        Type rhs_type = GetUpperBound(node->InputAt(1));
26831cb0ef41Sopenharmony_ci        VisitBinop<T>(node,
26841cb0ef41Sopenharmony_ci                      CheckedUseInfoAsWord32FromHint(hint, kIdentifyZeros),
26851cb0ef41Sopenharmony_ci                      MachineRepresentation::kWord32, Type::Signed32());
26861cb0ef41Sopenharmony_ci        if (lower<T>()) {
26871cb0ef41Sopenharmony_ci          MaskShiftOperand(node, rhs_type);
26881cb0ef41Sopenharmony_ci          ChangeToPureOp(node, lowering->machine()->Word32Sar());
26891cb0ef41Sopenharmony_ci        }
26901cb0ef41Sopenharmony_ci        return;
26911cb0ef41Sopenharmony_ci      }
26921cb0ef41Sopenharmony_ci      case IrOpcode::kNumberShiftRightLogical: {
26931cb0ef41Sopenharmony_ci        Type rhs_type = GetUpperBound(node->InputAt(1));
26941cb0ef41Sopenharmony_ci        VisitBinop<T>(node, UseInfo::TruncatingWord32(),
26951cb0ef41Sopenharmony_ci                      UseInfo::TruncatingWord32(),
26961cb0ef41Sopenharmony_ci                      MachineRepresentation::kWord32);
26971cb0ef41Sopenharmony_ci        if (lower<T>()) {
26981cb0ef41Sopenharmony_ci          MaskShiftOperand(node, rhs_type);
26991cb0ef41Sopenharmony_ci          ChangeToPureOp(node, lowering->machine()->Word32Shr());
27001cb0ef41Sopenharmony_ci        }
27011cb0ef41Sopenharmony_ci        return;
27021cb0ef41Sopenharmony_ci      }
27031cb0ef41Sopenharmony_ci      case IrOpcode::kSpeculativeNumberShiftRightLogical: {
27041cb0ef41Sopenharmony_ci        NumberOperationHint hint = NumberOperationHintOf(node->op());
27051cb0ef41Sopenharmony_ci        Type rhs_type = GetUpperBound(node->InputAt(1));
27061cb0ef41Sopenharmony_ci        if (rhs_type.Is(type_cache_->kZeroish) &&
27071cb0ef41Sopenharmony_ci            hint == NumberOperationHint::kSignedSmall &&
27081cb0ef41Sopenharmony_ci            !truncation.IsUsedAsWord32()) {
27091cb0ef41Sopenharmony_ci          // The SignedSmall or Signed32 feedback means that the results that we
27101cb0ef41Sopenharmony_ci          // have seen so far were of type Unsigned31.  We speculate that this
27111cb0ef41Sopenharmony_ci          // will continue to hold.  Moreover, since the RHS is 0, the result
27121cb0ef41Sopenharmony_ci          // will just be the (converted) LHS.
27131cb0ef41Sopenharmony_ci          VisitBinop<T>(node,
27141cb0ef41Sopenharmony_ci                        CheckedUseInfoAsWord32FromHint(hint, kIdentifyZeros),
27151cb0ef41Sopenharmony_ci                        MachineRepresentation::kWord32, Type::Unsigned31());
27161cb0ef41Sopenharmony_ci          if (lower<T>()) {
27171cb0ef41Sopenharmony_ci            node->RemoveInput(1);
27181cb0ef41Sopenharmony_ci            ChangeOp(node,
27191cb0ef41Sopenharmony_ci                     simplified()->CheckedUint32ToInt32(FeedbackSource()));
27201cb0ef41Sopenharmony_ci          }
27211cb0ef41Sopenharmony_ci          return;
27221cb0ef41Sopenharmony_ci        }
27231cb0ef41Sopenharmony_ci        if (BothInputsAre(node, Type::NumberOrOddball())) {
27241cb0ef41Sopenharmony_ci          VisitBinop<T>(node, UseInfo::TruncatingWord32(),
27251cb0ef41Sopenharmony_ci                        UseInfo::TruncatingWord32(),
27261cb0ef41Sopenharmony_ci                        MachineRepresentation::kWord32);
27271cb0ef41Sopenharmony_ci          if (lower<T>()) {
27281cb0ef41Sopenharmony_ci            MaskShiftOperand(node, rhs_type);
27291cb0ef41Sopenharmony_ci            ChangeToPureOp(node, lowering->machine()->Word32Shr());
27301cb0ef41Sopenharmony_ci          }
27311cb0ef41Sopenharmony_ci          return;
27321cb0ef41Sopenharmony_ci        }
27331cb0ef41Sopenharmony_ci        VisitBinop<T>(node,
27341cb0ef41Sopenharmony_ci                      CheckedUseInfoAsWord32FromHint(hint, kIdentifyZeros),
27351cb0ef41Sopenharmony_ci                      MachineRepresentation::kWord32, Type::Unsigned32());
27361cb0ef41Sopenharmony_ci        if (lower<T>()) {
27371cb0ef41Sopenharmony_ci          MaskShiftOperand(node, rhs_type);
27381cb0ef41Sopenharmony_ci          ChangeToPureOp(node, lowering->machine()->Word32Shr());
27391cb0ef41Sopenharmony_ci        }
27401cb0ef41Sopenharmony_ci        return;
27411cb0ef41Sopenharmony_ci      }
27421cb0ef41Sopenharmony_ci      case IrOpcode::kNumberAbs: {
27431cb0ef41Sopenharmony_ci        // NumberAbs maps both 0 and -0 to 0, so we can generally
27441cb0ef41Sopenharmony_ci        // pass the kIdentifyZeros truncation to its input, and
27451cb0ef41Sopenharmony_ci        // choose to ignore minus zero in all cases.
27461cb0ef41Sopenharmony_ci        Type const input_type = TypeOf(node->InputAt(0));
27471cb0ef41Sopenharmony_ci        if (input_type.Is(Type::Unsigned32OrMinusZero())) {
27481cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::TruncatingWord32(),
27491cb0ef41Sopenharmony_ci                       MachineRepresentation::kWord32);
27501cb0ef41Sopenharmony_ci          if (lower<T>()) DeferReplacement(node, node->InputAt(0));
27511cb0ef41Sopenharmony_ci        } else if (input_type.Is(Type::Signed32OrMinusZero())) {
27521cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::TruncatingWord32(),
27531cb0ef41Sopenharmony_ci                       MachineRepresentation::kWord32);
27541cb0ef41Sopenharmony_ci          if (lower<T>()) DeferReplacement(node, lowering->Int32Abs(node));
27551cb0ef41Sopenharmony_ci        } else if (input_type.Is(type_cache_->kPositiveIntegerOrNaN)) {
27561cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
27571cb0ef41Sopenharmony_ci                       MachineRepresentation::kFloat64);
27581cb0ef41Sopenharmony_ci          if (lower<T>()) DeferReplacement(node, node->InputAt(0));
27591cb0ef41Sopenharmony_ci        } else {
27601cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
27611cb0ef41Sopenharmony_ci                       MachineRepresentation::kFloat64);
27621cb0ef41Sopenharmony_ci          if (lower<T>()) ChangeOp(node, Float64Op(node));
27631cb0ef41Sopenharmony_ci        }
27641cb0ef41Sopenharmony_ci        return;
27651cb0ef41Sopenharmony_ci      }
27661cb0ef41Sopenharmony_ci      case IrOpcode::kNumberClz32: {
27671cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfo::TruncatingWord32(),
27681cb0ef41Sopenharmony_ci                     MachineRepresentation::kWord32);
27691cb0ef41Sopenharmony_ci        if (lower<T>()) ChangeOp(node, Uint32Op(node));
27701cb0ef41Sopenharmony_ci        return;
27711cb0ef41Sopenharmony_ci      }
27721cb0ef41Sopenharmony_ci      case IrOpcode::kNumberImul: {
27731cb0ef41Sopenharmony_ci        VisitBinop<T>(node, UseInfo::TruncatingWord32(),
27741cb0ef41Sopenharmony_ci                      UseInfo::TruncatingWord32(),
27751cb0ef41Sopenharmony_ci                      MachineRepresentation::kWord32);
27761cb0ef41Sopenharmony_ci        if (lower<T>()) ChangeOp(node, Uint32Op(node));
27771cb0ef41Sopenharmony_ci        return;
27781cb0ef41Sopenharmony_ci      }
27791cb0ef41Sopenharmony_ci      case IrOpcode::kNumberFround: {
27801cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
27811cb0ef41Sopenharmony_ci                     MachineRepresentation::kFloat32);
27821cb0ef41Sopenharmony_ci        if (lower<T>()) ChangeOp(node, Float64Op(node));
27831cb0ef41Sopenharmony_ci        return;
27841cb0ef41Sopenharmony_ci      }
27851cb0ef41Sopenharmony_ci      case IrOpcode::kNumberMax: {
27861cb0ef41Sopenharmony_ci        // It is safe to use the feedback types for left and right hand side
27871cb0ef41Sopenharmony_ci        // here, since we can only narrow those types and thus we can only
27881cb0ef41Sopenharmony_ci        // promise a more specific truncation.
27891cb0ef41Sopenharmony_ci        // For NumberMax we generally propagate whether the truncation
27901cb0ef41Sopenharmony_ci        // identifies zeros to the inputs, and we choose to ignore minus
27911cb0ef41Sopenharmony_ci        // zero in those cases.
27921cb0ef41Sopenharmony_ci        Type const lhs_type = TypeOf(node->InputAt(0));
27931cb0ef41Sopenharmony_ci        Type const rhs_type = TypeOf(node->InputAt(1));
27941cb0ef41Sopenharmony_ci        if ((lhs_type.Is(Type::Unsigned32()) &&
27951cb0ef41Sopenharmony_ci             rhs_type.Is(Type::Unsigned32())) ||
27961cb0ef41Sopenharmony_ci            (lhs_type.Is(Type::Unsigned32OrMinusZero()) &&
27971cb0ef41Sopenharmony_ci             rhs_type.Is(Type::Unsigned32OrMinusZero()) &&
27981cb0ef41Sopenharmony_ci             truncation.IdentifiesZeroAndMinusZero())) {
27991cb0ef41Sopenharmony_ci          VisitWord32TruncatingBinop<T>(node);
28001cb0ef41Sopenharmony_ci          if (lower<T>()) {
28011cb0ef41Sopenharmony_ci            lowering->DoMax(node, lowering->machine()->Uint32LessThan(),
28021cb0ef41Sopenharmony_ci                            MachineRepresentation::kWord32);
28031cb0ef41Sopenharmony_ci          }
28041cb0ef41Sopenharmony_ci        } else if ((lhs_type.Is(Type::Signed32()) &&
28051cb0ef41Sopenharmony_ci                    rhs_type.Is(Type::Signed32())) ||
28061cb0ef41Sopenharmony_ci                   (lhs_type.Is(Type::Signed32OrMinusZero()) &&
28071cb0ef41Sopenharmony_ci                    rhs_type.Is(Type::Signed32OrMinusZero()) &&
28081cb0ef41Sopenharmony_ci                    truncation.IdentifiesZeroAndMinusZero())) {
28091cb0ef41Sopenharmony_ci          VisitWord32TruncatingBinop<T>(node);
28101cb0ef41Sopenharmony_ci          if (lower<T>()) {
28111cb0ef41Sopenharmony_ci            lowering->DoMax(node, lowering->machine()->Int32LessThan(),
28121cb0ef41Sopenharmony_ci                            MachineRepresentation::kWord32);
28131cb0ef41Sopenharmony_ci          }
28141cb0ef41Sopenharmony_ci        } else if (jsgraph_->machine()->Is64() &&
28151cb0ef41Sopenharmony_ci                   lhs_type.Is(type_cache_->kSafeInteger) &&
28161cb0ef41Sopenharmony_ci                   rhs_type.Is(type_cache_->kSafeInteger)) {
28171cb0ef41Sopenharmony_ci          VisitInt64Binop<T>(node);
28181cb0ef41Sopenharmony_ci          if (lower<T>()) {
28191cb0ef41Sopenharmony_ci            lowering->DoMax(node, lowering->machine()->Int64LessThan(),
28201cb0ef41Sopenharmony_ci                            MachineRepresentation::kWord64);
28211cb0ef41Sopenharmony_ci          }
28221cb0ef41Sopenharmony_ci        } else {
28231cb0ef41Sopenharmony_ci          VisitBinop<T>(node,
28241cb0ef41Sopenharmony_ci                        UseInfo::TruncatingFloat64(truncation.identify_zeros()),
28251cb0ef41Sopenharmony_ci                        MachineRepresentation::kFloat64);
28261cb0ef41Sopenharmony_ci          if (lower<T>()) {
28271cb0ef41Sopenharmony_ci            // If the right hand side is not NaN, and the left hand side
28281cb0ef41Sopenharmony_ci            // is not NaN (or -0 if the difference between the zeros is
28291cb0ef41Sopenharmony_ci            // observed), we can do a simple floating point comparison here.
28301cb0ef41Sopenharmony_ci            if (lhs_type.Is(truncation.IdentifiesZeroAndMinusZero()
28311cb0ef41Sopenharmony_ci                                ? Type::OrderedNumber()
28321cb0ef41Sopenharmony_ci                                : Type::PlainNumber()) &&
28331cb0ef41Sopenharmony_ci                rhs_type.Is(Type::OrderedNumber())) {
28341cb0ef41Sopenharmony_ci              lowering->DoMax(node, lowering->machine()->Float64LessThan(),
28351cb0ef41Sopenharmony_ci                              MachineRepresentation::kFloat64);
28361cb0ef41Sopenharmony_ci            } else {
28371cb0ef41Sopenharmony_ci              ChangeOp(node, Float64Op(node));
28381cb0ef41Sopenharmony_ci            }
28391cb0ef41Sopenharmony_ci          }
28401cb0ef41Sopenharmony_ci        }
28411cb0ef41Sopenharmony_ci        return;
28421cb0ef41Sopenharmony_ci      }
28431cb0ef41Sopenharmony_ci      case IrOpcode::kNumberMin: {
28441cb0ef41Sopenharmony_ci        // It is safe to use the feedback types for left and right hand side
28451cb0ef41Sopenharmony_ci        // here, since we can only narrow those types and thus we can only
28461cb0ef41Sopenharmony_ci        // promise a more specific truncation.
28471cb0ef41Sopenharmony_ci        // For NumberMin we generally propagate whether the truncation
28481cb0ef41Sopenharmony_ci        // identifies zeros to the inputs, and we choose to ignore minus
28491cb0ef41Sopenharmony_ci        // zero in those cases.
28501cb0ef41Sopenharmony_ci        Type const lhs_type = TypeOf(node->InputAt(0));
28511cb0ef41Sopenharmony_ci        Type const rhs_type = TypeOf(node->InputAt(1));
28521cb0ef41Sopenharmony_ci        if ((lhs_type.Is(Type::Unsigned32()) &&
28531cb0ef41Sopenharmony_ci             rhs_type.Is(Type::Unsigned32())) ||
28541cb0ef41Sopenharmony_ci            (lhs_type.Is(Type::Unsigned32OrMinusZero()) &&
28551cb0ef41Sopenharmony_ci             rhs_type.Is(Type::Unsigned32OrMinusZero()) &&
28561cb0ef41Sopenharmony_ci             truncation.IdentifiesZeroAndMinusZero())) {
28571cb0ef41Sopenharmony_ci          VisitWord32TruncatingBinop<T>(node);
28581cb0ef41Sopenharmony_ci          if (lower<T>()) {
28591cb0ef41Sopenharmony_ci            lowering->DoMin(node, lowering->machine()->Uint32LessThan(),
28601cb0ef41Sopenharmony_ci                            MachineRepresentation::kWord32);
28611cb0ef41Sopenharmony_ci          }
28621cb0ef41Sopenharmony_ci        } else if ((lhs_type.Is(Type::Signed32()) &&
28631cb0ef41Sopenharmony_ci                    rhs_type.Is(Type::Signed32())) ||
28641cb0ef41Sopenharmony_ci                   (lhs_type.Is(Type::Signed32OrMinusZero()) &&
28651cb0ef41Sopenharmony_ci                    rhs_type.Is(Type::Signed32OrMinusZero()) &&
28661cb0ef41Sopenharmony_ci                    truncation.IdentifiesZeroAndMinusZero())) {
28671cb0ef41Sopenharmony_ci          VisitWord32TruncatingBinop<T>(node);
28681cb0ef41Sopenharmony_ci          if (lower<T>()) {
28691cb0ef41Sopenharmony_ci            lowering->DoMin(node, lowering->machine()->Int32LessThan(),
28701cb0ef41Sopenharmony_ci                            MachineRepresentation::kWord32);
28711cb0ef41Sopenharmony_ci          }
28721cb0ef41Sopenharmony_ci        } else if (jsgraph_->machine()->Is64() &&
28731cb0ef41Sopenharmony_ci                   lhs_type.Is(type_cache_->kSafeInteger) &&
28741cb0ef41Sopenharmony_ci                   rhs_type.Is(type_cache_->kSafeInteger)) {
28751cb0ef41Sopenharmony_ci          VisitInt64Binop<T>(node);
28761cb0ef41Sopenharmony_ci          if (lower<T>()) {
28771cb0ef41Sopenharmony_ci            lowering->DoMin(node, lowering->machine()->Int64LessThan(),
28781cb0ef41Sopenharmony_ci                            MachineRepresentation::kWord64);
28791cb0ef41Sopenharmony_ci          }
28801cb0ef41Sopenharmony_ci        } else {
28811cb0ef41Sopenharmony_ci          VisitBinop<T>(node,
28821cb0ef41Sopenharmony_ci                        UseInfo::TruncatingFloat64(truncation.identify_zeros()),
28831cb0ef41Sopenharmony_ci                        MachineRepresentation::kFloat64);
28841cb0ef41Sopenharmony_ci          if (lower<T>()) {
28851cb0ef41Sopenharmony_ci            // If the left hand side is not NaN, and the right hand side
28861cb0ef41Sopenharmony_ci            // is not NaN (or -0 if the difference between the zeros is
28871cb0ef41Sopenharmony_ci            // observed), we can do a simple floating point comparison here.
28881cb0ef41Sopenharmony_ci            if (lhs_type.Is(Type::OrderedNumber()) &&
28891cb0ef41Sopenharmony_ci                rhs_type.Is(truncation.IdentifiesZeroAndMinusZero()
28901cb0ef41Sopenharmony_ci                                ? Type::OrderedNumber()
28911cb0ef41Sopenharmony_ci                                : Type::PlainNumber())) {
28921cb0ef41Sopenharmony_ci              lowering->DoMin(node,
28931cb0ef41Sopenharmony_ci                              lowering->machine()->Float64LessThanOrEqual(),
28941cb0ef41Sopenharmony_ci                              MachineRepresentation::kFloat64);
28951cb0ef41Sopenharmony_ci            } else {
28961cb0ef41Sopenharmony_ci              ChangeOp(node, Float64Op(node));
28971cb0ef41Sopenharmony_ci            }
28981cb0ef41Sopenharmony_ci          }
28991cb0ef41Sopenharmony_ci        }
29001cb0ef41Sopenharmony_ci        return;
29011cb0ef41Sopenharmony_ci      }
29021cb0ef41Sopenharmony_ci      case IrOpcode::kSpeculativeNumberPow: {
29031cb0ef41Sopenharmony_ci        // Checked float64 ** float64 => float64
29041cb0ef41Sopenharmony_ci        VisitBinop<T>(node,
29051cb0ef41Sopenharmony_ci                      UseInfo::CheckedNumberOrOddballAsFloat64(
29061cb0ef41Sopenharmony_ci                          kDistinguishZeros, FeedbackSource()),
29071cb0ef41Sopenharmony_ci                      MachineRepresentation::kFloat64, Type::Number());
29081cb0ef41Sopenharmony_ci        if (lower<T>()) ChangeToPureOp(node, Float64Op(node));
29091cb0ef41Sopenharmony_ci        return;
29101cb0ef41Sopenharmony_ci      }
29111cb0ef41Sopenharmony_ci      case IrOpcode::kNumberAtan2:
29121cb0ef41Sopenharmony_ci      case IrOpcode::kNumberPow: {
29131cb0ef41Sopenharmony_ci        VisitBinop<T>(node, UseInfo::TruncatingFloat64(),
29141cb0ef41Sopenharmony_ci                      MachineRepresentation::kFloat64);
29151cb0ef41Sopenharmony_ci        if (lower<T>()) ChangeOp(node, Float64Op(node));
29161cb0ef41Sopenharmony_ci        return;
29171cb0ef41Sopenharmony_ci      }
29181cb0ef41Sopenharmony_ci      case IrOpcode::kNumberCeil:
29191cb0ef41Sopenharmony_ci      case IrOpcode::kNumberFloor:
29201cb0ef41Sopenharmony_ci      case IrOpcode::kNumberRound:
29211cb0ef41Sopenharmony_ci      case IrOpcode::kNumberTrunc: {
29221cb0ef41Sopenharmony_ci        // For NumberCeil, NumberFloor, NumberRound and NumberTrunc we propagate
29231cb0ef41Sopenharmony_ci        // the zero identification part of the truncation, and we turn them into
29241cb0ef41Sopenharmony_ci        // no-ops if we figure out (late) that their input is already an
29251cb0ef41Sopenharmony_ci        // integer, NaN or -0.
29261cb0ef41Sopenharmony_ci        Type const input_type = TypeOf(node->InputAt(0));
29271cb0ef41Sopenharmony_ci        VisitUnop<T>(node,
29281cb0ef41Sopenharmony_ci                     UseInfo::TruncatingFloat64(truncation.identify_zeros()),
29291cb0ef41Sopenharmony_ci                     MachineRepresentation::kFloat64);
29301cb0ef41Sopenharmony_ci        if (lower<T>()) {
29311cb0ef41Sopenharmony_ci          if (input_type.Is(type_cache_->kIntegerOrMinusZeroOrNaN)) {
29321cb0ef41Sopenharmony_ci            DeferReplacement(node, node->InputAt(0));
29331cb0ef41Sopenharmony_ci          } else if (node->opcode() == IrOpcode::kNumberRound) {
29341cb0ef41Sopenharmony_ci            DeferReplacement(node, lowering->Float64Round(node));
29351cb0ef41Sopenharmony_ci          } else {
29361cb0ef41Sopenharmony_ci            ChangeOp(node, Float64Op(node));
29371cb0ef41Sopenharmony_ci          }
29381cb0ef41Sopenharmony_ci        }
29391cb0ef41Sopenharmony_ci        return;
29401cb0ef41Sopenharmony_ci      }
29411cb0ef41Sopenharmony_ci      case IrOpcode::kCheckBigInt: {
29421cb0ef41Sopenharmony_ci        if (InputIs(node, Type::BigInt())) {
29431cb0ef41Sopenharmony_ci          VisitNoop<T>(node, truncation);
29441cb0ef41Sopenharmony_ci        } else {
29451cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::AnyTagged(),
29461cb0ef41Sopenharmony_ci                       MachineRepresentation::kTaggedPointer);
29471cb0ef41Sopenharmony_ci        }
29481cb0ef41Sopenharmony_ci        return;
29491cb0ef41Sopenharmony_ci      }
29501cb0ef41Sopenharmony_ci      case IrOpcode::kSpeculativeBigIntAsIntN:
29511cb0ef41Sopenharmony_ci      case IrOpcode::kSpeculativeBigIntAsUintN: {
29521cb0ef41Sopenharmony_ci        const bool is_asuintn =
29531cb0ef41Sopenharmony_ci            node->opcode() == IrOpcode::kSpeculativeBigIntAsUintN;
29541cb0ef41Sopenharmony_ci        const auto p = SpeculativeBigIntAsNParametersOf(node->op());
29551cb0ef41Sopenharmony_ci        DCHECK_LE(0, p.bits());
29561cb0ef41Sopenharmony_ci        DCHECK_LE(p.bits(), 64);
29571cb0ef41Sopenharmony_ci
29581cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 0,
29591cb0ef41Sopenharmony_ci                        UseInfo::CheckedBigIntTruncatingWord64(p.feedback()));
29601cb0ef41Sopenharmony_ci        SetOutput<T>(
29611cb0ef41Sopenharmony_ci            node, MachineRepresentation::kWord64,
29621cb0ef41Sopenharmony_ci            is_asuintn ? Type::UnsignedBigInt64() : Type::SignedBigInt64());
29631cb0ef41Sopenharmony_ci        if (lower<T>()) {
29641cb0ef41Sopenharmony_ci          if (p.bits() == 0) {
29651cb0ef41Sopenharmony_ci            DeferReplacement(
29661cb0ef41Sopenharmony_ci                node, InsertTypeOverrideForVerifier(Type::UnsignedBigInt63(),
29671cb0ef41Sopenharmony_ci                                                    jsgraph_->ZeroConstant()));
29681cb0ef41Sopenharmony_ci          } else if (p.bits() == 64) {
29691cb0ef41Sopenharmony_ci            DeferReplacement(node, node->InputAt(0));
29701cb0ef41Sopenharmony_ci          } else {
29711cb0ef41Sopenharmony_ci            if (is_asuintn) {
29721cb0ef41Sopenharmony_ci              const uint64_t mask = (1ULL << p.bits()) - 1ULL;
29731cb0ef41Sopenharmony_ci              ChangeUnaryToPureBinaryOp(node, lowering->machine()->Word64And(),
29741cb0ef41Sopenharmony_ci                                        1, jsgraph_->Int64Constant(mask));
29751cb0ef41Sopenharmony_ci            } else {
29761cb0ef41Sopenharmony_ci              // We truncate the value to N bits, but to correctly interpret
29771cb0ef41Sopenharmony_ci              // negative values, we have to fill the top (64-N) bits with the
29781cb0ef41Sopenharmony_ci              // sign. This is done by shifting the value left and then back
29791cb0ef41Sopenharmony_ci              // with an arithmetic right shift. E.g. for {value} =
29801cb0ef41Sopenharmony_ci              // 0..0'0001'1101 (29n) and N = 3: {shifted} is 1010'0000'0..0
29811cb0ef41Sopenharmony_ci              // after left shift by 61 bits, {unshifted} is 1..1'1111'1101
29821cb0ef41Sopenharmony_ci              // after arithmetic right shift by 61. This is the 64 bit
29831cb0ef41Sopenharmony_ci              // representation of -3 we expect for the signed 3 bit integer
29841cb0ef41Sopenharmony_ci              // 101.
29851cb0ef41Sopenharmony_ci              const uint64_t shift = 64 - p.bits();
29861cb0ef41Sopenharmony_ci              Node* value = node->InputAt(0);
29871cb0ef41Sopenharmony_ci              Node* shifted =
29881cb0ef41Sopenharmony_ci                  graph()->NewNode(lowering->machine()->Word64Shl(), value,
29891cb0ef41Sopenharmony_ci                                   jsgraph_->Uint64Constant(shift));
29901cb0ef41Sopenharmony_ci              Node* unshifted =
29911cb0ef41Sopenharmony_ci                  graph()->NewNode(lowering->machine()->Word64Sar(), shifted,
29921cb0ef41Sopenharmony_ci                                   jsgraph_->Uint64Constant(shift));
29931cb0ef41Sopenharmony_ci
29941cb0ef41Sopenharmony_ci              ReplaceWithPureNode(node, unshifted);
29951cb0ef41Sopenharmony_ci            }
29961cb0ef41Sopenharmony_ci          }
29971cb0ef41Sopenharmony_ci        }
29981cb0ef41Sopenharmony_ci        return;
29991cb0ef41Sopenharmony_ci      }
30001cb0ef41Sopenharmony_ci      case IrOpcode::kNumberAcos:
30011cb0ef41Sopenharmony_ci      case IrOpcode::kNumberAcosh:
30021cb0ef41Sopenharmony_ci      case IrOpcode::kNumberAsin:
30031cb0ef41Sopenharmony_ci      case IrOpcode::kNumberAsinh:
30041cb0ef41Sopenharmony_ci      case IrOpcode::kNumberAtan:
30051cb0ef41Sopenharmony_ci      case IrOpcode::kNumberAtanh:
30061cb0ef41Sopenharmony_ci      case IrOpcode::kNumberCos:
30071cb0ef41Sopenharmony_ci      case IrOpcode::kNumberCosh:
30081cb0ef41Sopenharmony_ci      case IrOpcode::kNumberExp:
30091cb0ef41Sopenharmony_ci      case IrOpcode::kNumberExpm1:
30101cb0ef41Sopenharmony_ci      case IrOpcode::kNumberLog:
30111cb0ef41Sopenharmony_ci      case IrOpcode::kNumberLog1p:
30121cb0ef41Sopenharmony_ci      case IrOpcode::kNumberLog2:
30131cb0ef41Sopenharmony_ci      case IrOpcode::kNumberLog10:
30141cb0ef41Sopenharmony_ci      case IrOpcode::kNumberCbrt:
30151cb0ef41Sopenharmony_ci      case IrOpcode::kNumberSin:
30161cb0ef41Sopenharmony_ci      case IrOpcode::kNumberSinh:
30171cb0ef41Sopenharmony_ci      case IrOpcode::kNumberTan:
30181cb0ef41Sopenharmony_ci      case IrOpcode::kNumberTanh: {
30191cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
30201cb0ef41Sopenharmony_ci                     MachineRepresentation::kFloat64);
30211cb0ef41Sopenharmony_ci        if (lower<T>()) ChangeOp(node, Float64Op(node));
30221cb0ef41Sopenharmony_ci        return;
30231cb0ef41Sopenharmony_ci      }
30241cb0ef41Sopenharmony_ci      case IrOpcode::kNumberSign: {
30251cb0ef41Sopenharmony_ci        if (InputIs(node, Type::Signed32())) {
30261cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::TruncatingWord32(),
30271cb0ef41Sopenharmony_ci                       MachineRepresentation::kWord32);
30281cb0ef41Sopenharmony_ci          if (lower<T>()) DeferReplacement(node, lowering->Int32Sign(node));
30291cb0ef41Sopenharmony_ci        } else {
30301cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
30311cb0ef41Sopenharmony_ci                       MachineRepresentation::kFloat64);
30321cb0ef41Sopenharmony_ci          if (lower<T>()) DeferReplacement(node, lowering->Float64Sign(node));
30331cb0ef41Sopenharmony_ci        }
30341cb0ef41Sopenharmony_ci        return;
30351cb0ef41Sopenharmony_ci      }
30361cb0ef41Sopenharmony_ci      case IrOpcode::kNumberSilenceNaN: {
30371cb0ef41Sopenharmony_ci        Type const input_type = TypeOf(node->InputAt(0));
30381cb0ef41Sopenharmony_ci        if (input_type.Is(Type::OrderedNumber())) {
30391cb0ef41Sopenharmony_ci          // No need to silence anything if the input cannot be NaN.
30401cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
30411cb0ef41Sopenharmony_ci                       MachineRepresentation::kFloat64);
30421cb0ef41Sopenharmony_ci          if (lower<T>()) DeferReplacement(node, node->InputAt(0));
30431cb0ef41Sopenharmony_ci        } else {
30441cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
30451cb0ef41Sopenharmony_ci                       MachineRepresentation::kFloat64);
30461cb0ef41Sopenharmony_ci          if (lower<T>()) ChangeOp(node, Float64Op(node));
30471cb0ef41Sopenharmony_ci        }
30481cb0ef41Sopenharmony_ci        return;
30491cb0ef41Sopenharmony_ci      }
30501cb0ef41Sopenharmony_ci      case IrOpcode::kNumberSqrt: {
30511cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
30521cb0ef41Sopenharmony_ci                     MachineRepresentation::kFloat64);
30531cb0ef41Sopenharmony_ci        if (lower<T>()) ChangeOp(node, Float64Op(node));
30541cb0ef41Sopenharmony_ci        return;
30551cb0ef41Sopenharmony_ci      }
30561cb0ef41Sopenharmony_ci      case IrOpcode::kNumberToBoolean: {
30571cb0ef41Sopenharmony_ci        // For NumberToBoolean we don't care whether the input is 0 or
30581cb0ef41Sopenharmony_ci        // -0, since both of them are mapped to false anyways, so we
30591cb0ef41Sopenharmony_ci        // can generally pass kIdentifyZeros truncation.
30601cb0ef41Sopenharmony_ci        Type const input_type = TypeOf(node->InputAt(0));
30611cb0ef41Sopenharmony_ci        if (input_type.Is(Type::Integral32OrMinusZeroOrNaN())) {
30621cb0ef41Sopenharmony_ci          // 0, -0 and NaN all map to false, so we can safely truncate
30631cb0ef41Sopenharmony_ci          // all of them to zero here.
30641cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::TruncatingWord32(),
30651cb0ef41Sopenharmony_ci                       MachineRepresentation::kBit);
30661cb0ef41Sopenharmony_ci          if (lower<T>()) lowering->DoIntegral32ToBit(node);
30671cb0ef41Sopenharmony_ci        } else if (input_type.Is(Type::OrderedNumber())) {
30681cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
30691cb0ef41Sopenharmony_ci                       MachineRepresentation::kBit);
30701cb0ef41Sopenharmony_ci          if (lower<T>()) lowering->DoOrderedNumberToBit(node);
30711cb0ef41Sopenharmony_ci        } else {
30721cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
30731cb0ef41Sopenharmony_ci                       MachineRepresentation::kBit);
30741cb0ef41Sopenharmony_ci          if (lower<T>()) lowering->DoNumberToBit(node);
30751cb0ef41Sopenharmony_ci        }
30761cb0ef41Sopenharmony_ci        return;
30771cb0ef41Sopenharmony_ci      }
30781cb0ef41Sopenharmony_ci      case IrOpcode::kNumberToInt32: {
30791cb0ef41Sopenharmony_ci        // Just change representation if necessary.
30801cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfo::TruncatingWord32(),
30811cb0ef41Sopenharmony_ci                     MachineRepresentation::kWord32);
30821cb0ef41Sopenharmony_ci        if (lower<T>()) DeferReplacement(node, node->InputAt(0));
30831cb0ef41Sopenharmony_ci        return;
30841cb0ef41Sopenharmony_ci      }
30851cb0ef41Sopenharmony_ci      case IrOpcode::kNumberToString: {
30861cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfo::AnyTagged(),
30871cb0ef41Sopenharmony_ci                     MachineRepresentation::kTaggedPointer);
30881cb0ef41Sopenharmony_ci        return;
30891cb0ef41Sopenharmony_ci      }
30901cb0ef41Sopenharmony_ci      case IrOpcode::kNumberToUint32: {
30911cb0ef41Sopenharmony_ci        // Just change representation if necessary.
30921cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfo::TruncatingWord32(),
30931cb0ef41Sopenharmony_ci                     MachineRepresentation::kWord32);
30941cb0ef41Sopenharmony_ci        if (lower<T>()) DeferReplacement(node, node->InputAt(0));
30951cb0ef41Sopenharmony_ci        return;
30961cb0ef41Sopenharmony_ci      }
30971cb0ef41Sopenharmony_ci      case IrOpcode::kNumberToUint8Clamped: {
30981cb0ef41Sopenharmony_ci        Type const input_type = TypeOf(node->InputAt(0));
30991cb0ef41Sopenharmony_ci        if (input_type.Is(type_cache_->kUint8OrMinusZeroOrNaN)) {
31001cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::TruncatingWord32(),
31011cb0ef41Sopenharmony_ci                       MachineRepresentation::kWord32);
31021cb0ef41Sopenharmony_ci          if (lower<T>()) DeferReplacement(node, node->InputAt(0));
31031cb0ef41Sopenharmony_ci        } else if (input_type.Is(Type::Unsigned32OrMinusZeroOrNaN())) {
31041cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::TruncatingWord32(),
31051cb0ef41Sopenharmony_ci                       MachineRepresentation::kWord32);
31061cb0ef41Sopenharmony_ci          if (lower<T>()) lowering->DoUnsigned32ToUint8Clamped(node);
31071cb0ef41Sopenharmony_ci        } else if (input_type.Is(Type::Signed32OrMinusZeroOrNaN())) {
31081cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::TruncatingWord32(),
31091cb0ef41Sopenharmony_ci                       MachineRepresentation::kWord32);
31101cb0ef41Sopenharmony_ci          if (lower<T>()) lowering->DoSigned32ToUint8Clamped(node);
31111cb0ef41Sopenharmony_ci        } else if (input_type.Is(type_cache_->kIntegerOrMinusZeroOrNaN)) {
31121cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
31131cb0ef41Sopenharmony_ci                       MachineRepresentation::kFloat64);
31141cb0ef41Sopenharmony_ci          if (lower<T>()) lowering->DoIntegerToUint8Clamped(node);
31151cb0ef41Sopenharmony_ci        } else {
31161cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
31171cb0ef41Sopenharmony_ci                       MachineRepresentation::kFloat64);
31181cb0ef41Sopenharmony_ci          if (lower<T>()) lowering->DoNumberToUint8Clamped(node);
31191cb0ef41Sopenharmony_ci        }
31201cb0ef41Sopenharmony_ci        return;
31211cb0ef41Sopenharmony_ci      }
31221cb0ef41Sopenharmony_ci      case IrOpcode::kReferenceEqual: {
31231cb0ef41Sopenharmony_ci        VisitBinop<T>(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
31241cb0ef41Sopenharmony_ci        if (lower<T>()) {
31251cb0ef41Sopenharmony_ci          if (COMPRESS_POINTERS_BOOL) {
31261cb0ef41Sopenharmony_ci            ChangeOp(node, lowering->machine()->Word32Equal());
31271cb0ef41Sopenharmony_ci          } else {
31281cb0ef41Sopenharmony_ci            ChangeOp(node, lowering->machine()->WordEqual());
31291cb0ef41Sopenharmony_ci          }
31301cb0ef41Sopenharmony_ci        }
31311cb0ef41Sopenharmony_ci        return;
31321cb0ef41Sopenharmony_ci      }
31331cb0ef41Sopenharmony_ci      case IrOpcode::kSameValueNumbersOnly: {
31341cb0ef41Sopenharmony_ci        VisitBinop<T>(node, UseInfo::AnyTagged(),
31351cb0ef41Sopenharmony_ci                      MachineRepresentation::kTaggedPointer);
31361cb0ef41Sopenharmony_ci        return;
31371cb0ef41Sopenharmony_ci      }
31381cb0ef41Sopenharmony_ci      case IrOpcode::kSameValue: {
31391cb0ef41Sopenharmony_ci        if (truncation.IsUnused()) return VisitUnused<T>(node);
31401cb0ef41Sopenharmony_ci        if (BothInputsAre(node, Type::Number())) {
31411cb0ef41Sopenharmony_ci          VisitBinop<T>(node, UseInfo::TruncatingFloat64(),
31421cb0ef41Sopenharmony_ci                        MachineRepresentation::kBit);
31431cb0ef41Sopenharmony_ci          if (lower<T>()) {
31441cb0ef41Sopenharmony_ci            ChangeOp(node, lowering->simplified()->NumberSameValue());
31451cb0ef41Sopenharmony_ci          }
31461cb0ef41Sopenharmony_ci        } else {
31471cb0ef41Sopenharmony_ci          VisitBinop<T>(node, UseInfo::AnyTagged(),
31481cb0ef41Sopenharmony_ci                        MachineRepresentation::kTaggedPointer);
31491cb0ef41Sopenharmony_ci        }
31501cb0ef41Sopenharmony_ci        return;
31511cb0ef41Sopenharmony_ci      }
31521cb0ef41Sopenharmony_ci      case IrOpcode::kTypeOf: {
31531cb0ef41Sopenharmony_ci        return VisitUnop<T>(node, UseInfo::AnyTagged(),
31541cb0ef41Sopenharmony_ci                            MachineRepresentation::kTaggedPointer);
31551cb0ef41Sopenharmony_ci      }
31561cb0ef41Sopenharmony_ci      case IrOpcode::kNewConsString: {
31571cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 0, UseInfo::TruncatingWord32());  // length
31581cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 1, UseInfo::AnyTagged());         // first
31591cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 2, UseInfo::AnyTagged());         // second
31601cb0ef41Sopenharmony_ci        SetOutput<T>(node, MachineRepresentation::kTaggedPointer);
31611cb0ef41Sopenharmony_ci        return;
31621cb0ef41Sopenharmony_ci      }
31631cb0ef41Sopenharmony_ci      case IrOpcode::kSpeculativeBigIntAdd: {
31641cb0ef41Sopenharmony_ci        // TODO(nicohartmann@, chromium:1073440): There should be special
31651cb0ef41Sopenharmony_ci        // handling for trunction.IsUnused() that correctly propagates deadness,
31661cb0ef41Sopenharmony_ci        // but preserves type checking which may throw exceptions. Until this
31671cb0ef41Sopenharmony_ci        // is fully supported, we lower to int64 operations but keep pushing
31681cb0ef41Sopenharmony_ci        // type constraints.
31691cb0ef41Sopenharmony_ci        if (truncation.IsUsedAsWord64()) {
31701cb0ef41Sopenharmony_ci          VisitBinop<T>(
31711cb0ef41Sopenharmony_ci              node, UseInfo::CheckedBigIntTruncatingWord64(FeedbackSource{}),
31721cb0ef41Sopenharmony_ci              MachineRepresentation::kWord64);
31731cb0ef41Sopenharmony_ci          if (lower<T>()) {
31741cb0ef41Sopenharmony_ci            ChangeToPureOp(node, lowering->machine()->Int64Add());
31751cb0ef41Sopenharmony_ci          }
31761cb0ef41Sopenharmony_ci        } else {
31771cb0ef41Sopenharmony_ci          VisitBinop<T>(node,
31781cb0ef41Sopenharmony_ci                        UseInfo::CheckedBigIntAsTaggedPointer(FeedbackSource{}),
31791cb0ef41Sopenharmony_ci                        MachineRepresentation::kTaggedPointer);
31801cb0ef41Sopenharmony_ci          if (lower<T>()) {
31811cb0ef41Sopenharmony_ci            ChangeOp(node, lowering->simplified()->BigIntAdd());
31821cb0ef41Sopenharmony_ci          }
31831cb0ef41Sopenharmony_ci        }
31841cb0ef41Sopenharmony_ci        return;
31851cb0ef41Sopenharmony_ci      }
31861cb0ef41Sopenharmony_ci      case IrOpcode::kSpeculativeBigIntSubtract: {
31871cb0ef41Sopenharmony_ci        if (truncation.IsUsedAsWord64()) {
31881cb0ef41Sopenharmony_ci          VisitBinop<T>(
31891cb0ef41Sopenharmony_ci              node, UseInfo::CheckedBigIntTruncatingWord64(FeedbackSource{}),
31901cb0ef41Sopenharmony_ci              MachineRepresentation::kWord64);
31911cb0ef41Sopenharmony_ci          if (lower<T>()) {
31921cb0ef41Sopenharmony_ci            ChangeToPureOp(node, lowering->machine()->Int64Sub());
31931cb0ef41Sopenharmony_ci          }
31941cb0ef41Sopenharmony_ci        } else {
31951cb0ef41Sopenharmony_ci          VisitBinop<T>(node,
31961cb0ef41Sopenharmony_ci                        UseInfo::CheckedBigIntAsTaggedPointer(FeedbackSource{}),
31971cb0ef41Sopenharmony_ci                        MachineRepresentation::kTaggedPointer);
31981cb0ef41Sopenharmony_ci          if (lower<T>()) {
31991cb0ef41Sopenharmony_ci            ChangeOp(node, lowering->simplified()->BigIntSubtract());
32001cb0ef41Sopenharmony_ci          }
32011cb0ef41Sopenharmony_ci        }
32021cb0ef41Sopenharmony_ci        return;
32031cb0ef41Sopenharmony_ci      }
32041cb0ef41Sopenharmony_ci      case IrOpcode::kSpeculativeBigIntNegate: {
32051cb0ef41Sopenharmony_ci        if (truncation.IsUsedAsWord64()) {
32061cb0ef41Sopenharmony_ci          VisitUnop<T>(node,
32071cb0ef41Sopenharmony_ci                       UseInfo::CheckedBigIntTruncatingWord64(FeedbackSource{}),
32081cb0ef41Sopenharmony_ci                       MachineRepresentation::kWord64);
32091cb0ef41Sopenharmony_ci          if (lower<T>()) {
32101cb0ef41Sopenharmony_ci            ChangeUnaryToPureBinaryOp(node, lowering->machine()->Int64Sub(), 0,
32111cb0ef41Sopenharmony_ci                                      jsgraph_->Int64Constant(0));
32121cb0ef41Sopenharmony_ci          }
32131cb0ef41Sopenharmony_ci        } else {
32141cb0ef41Sopenharmony_ci          VisitUnop<T>(node,
32151cb0ef41Sopenharmony_ci                       UseInfo::CheckedBigIntAsTaggedPointer(FeedbackSource{}),
32161cb0ef41Sopenharmony_ci                       MachineRepresentation::kTaggedPointer);
32171cb0ef41Sopenharmony_ci          if (lower<T>()) {
32181cb0ef41Sopenharmony_ci            ChangeToPureOp(node, lowering->simplified()->BigIntNegate());
32191cb0ef41Sopenharmony_ci          }
32201cb0ef41Sopenharmony_ci        }
32211cb0ef41Sopenharmony_ci        return;
32221cb0ef41Sopenharmony_ci      }
32231cb0ef41Sopenharmony_ci      case IrOpcode::kStringConcat: {
32241cb0ef41Sopenharmony_ci        // TODO(turbofan): We currently depend on having this first length input
32251cb0ef41Sopenharmony_ci        // to make sure that the overflow check is properly scheduled before the
32261cb0ef41Sopenharmony_ci        // actual string concatenation. We should also use the length to pass it
32271cb0ef41Sopenharmony_ci        // to the builtin or decide in optimized code how to construct the
32281cb0ef41Sopenharmony_ci        // resulting string (i.e. cons string or sequential string).
32291cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 0, UseInfo::TaggedSigned());  // length
32301cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 1, UseInfo::AnyTagged());     // first
32311cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 2, UseInfo::AnyTagged());     // second
32321cb0ef41Sopenharmony_ci        SetOutput<T>(node, MachineRepresentation::kTaggedPointer);
32331cb0ef41Sopenharmony_ci        return;
32341cb0ef41Sopenharmony_ci      }
32351cb0ef41Sopenharmony_ci      case IrOpcode::kStringEqual:
32361cb0ef41Sopenharmony_ci      case IrOpcode::kStringLessThan:
32371cb0ef41Sopenharmony_ci      case IrOpcode::kStringLessThanOrEqual: {
32381cb0ef41Sopenharmony_ci        return VisitBinop<T>(node, UseInfo::AnyTagged(),
32391cb0ef41Sopenharmony_ci                             MachineRepresentation::kTaggedPointer);
32401cb0ef41Sopenharmony_ci      }
32411cb0ef41Sopenharmony_ci      case IrOpcode::kStringCharCodeAt: {
32421cb0ef41Sopenharmony_ci        return VisitBinop<T>(node, UseInfo::AnyTagged(), UseInfo::Word(),
32431cb0ef41Sopenharmony_ci                             MachineRepresentation::kWord32);
32441cb0ef41Sopenharmony_ci      }
32451cb0ef41Sopenharmony_ci      case IrOpcode::kStringCodePointAt: {
32461cb0ef41Sopenharmony_ci        return VisitBinop<T>(node, UseInfo::AnyTagged(), UseInfo::Word(),
32471cb0ef41Sopenharmony_ci                             MachineRepresentation::kWord32);
32481cb0ef41Sopenharmony_ci      }
32491cb0ef41Sopenharmony_ci      case IrOpcode::kStringFromSingleCharCode: {
32501cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfo::TruncatingWord32(),
32511cb0ef41Sopenharmony_ci                     MachineRepresentation::kTaggedPointer);
32521cb0ef41Sopenharmony_ci        return;
32531cb0ef41Sopenharmony_ci      }
32541cb0ef41Sopenharmony_ci      case IrOpcode::kStringFromSingleCodePoint: {
32551cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfo::TruncatingWord32(),
32561cb0ef41Sopenharmony_ci                     MachineRepresentation::kTaggedPointer);
32571cb0ef41Sopenharmony_ci        return;
32581cb0ef41Sopenharmony_ci      }
32591cb0ef41Sopenharmony_ci      case IrOpcode::kStringFromCodePointAt: {
32601cb0ef41Sopenharmony_ci        return VisitBinop<T>(node, UseInfo::AnyTagged(), UseInfo::Word(),
32611cb0ef41Sopenharmony_ci                             MachineRepresentation::kTaggedPointer);
32621cb0ef41Sopenharmony_ci      }
32631cb0ef41Sopenharmony_ci      case IrOpcode::kStringIndexOf: {
32641cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 0, UseInfo::AnyTagged());
32651cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 1, UseInfo::AnyTagged());
32661cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 2, UseInfo::TaggedSigned());
32671cb0ef41Sopenharmony_ci        SetOutput<T>(node, MachineRepresentation::kTaggedSigned);
32681cb0ef41Sopenharmony_ci        return;
32691cb0ef41Sopenharmony_ci      }
32701cb0ef41Sopenharmony_ci      case IrOpcode::kStringLength: {
32711cb0ef41Sopenharmony_ci        // TODO(bmeurer): The input representation should be TaggedPointer.
32721cb0ef41Sopenharmony_ci        // Fix this once we have a dedicated StringConcat/JSStringAdd
32731cb0ef41Sopenharmony_ci        // operator, which marks it's output as TaggedPointer properly.
32741cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfo::AnyTagged(),
32751cb0ef41Sopenharmony_ci                     MachineRepresentation::kWord32);
32761cb0ef41Sopenharmony_ci        return;
32771cb0ef41Sopenharmony_ci      }
32781cb0ef41Sopenharmony_ci      case IrOpcode::kStringSubstring: {
32791cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 0, UseInfo::AnyTagged());
32801cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 1, UseInfo::TruncatingWord32());
32811cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 2, UseInfo::TruncatingWord32());
32821cb0ef41Sopenharmony_ci        ProcessRemainingInputs<T>(node, 3);
32831cb0ef41Sopenharmony_ci        SetOutput<T>(node, MachineRepresentation::kTaggedPointer);
32841cb0ef41Sopenharmony_ci        return;
32851cb0ef41Sopenharmony_ci      }
32861cb0ef41Sopenharmony_ci      case IrOpcode::kStringToLowerCaseIntl:
32871cb0ef41Sopenharmony_ci      case IrOpcode::kStringToUpperCaseIntl: {
32881cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfo::AnyTagged(),
32891cb0ef41Sopenharmony_ci                     MachineRepresentation::kTaggedPointer);
32901cb0ef41Sopenharmony_ci        return;
32911cb0ef41Sopenharmony_ci      }
32921cb0ef41Sopenharmony_ci      case IrOpcode::kCheckBounds:
32931cb0ef41Sopenharmony_ci        return VisitCheckBounds<T>(node, lowering);
32941cb0ef41Sopenharmony_ci      case IrOpcode::kCheckHeapObject: {
32951cb0ef41Sopenharmony_ci        if (InputCannotBe(node, Type::SignedSmall())) {
32961cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::AnyTagged(),
32971cb0ef41Sopenharmony_ci                       MachineRepresentation::kTaggedPointer);
32981cb0ef41Sopenharmony_ci        } else {
32991cb0ef41Sopenharmony_ci          VisitUnop<T>(
33001cb0ef41Sopenharmony_ci              node, UseInfo::CheckedHeapObjectAsTaggedPointer(FeedbackSource()),
33011cb0ef41Sopenharmony_ci              MachineRepresentation::kTaggedPointer);
33021cb0ef41Sopenharmony_ci        }
33031cb0ef41Sopenharmony_ci        if (lower<T>()) DeferReplacement(node, node->InputAt(0));
33041cb0ef41Sopenharmony_ci        return;
33051cb0ef41Sopenharmony_ci      }
33061cb0ef41Sopenharmony_ci      case IrOpcode::kCheckIf: {
33071cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 0, UseInfo::Bool());
33081cb0ef41Sopenharmony_ci        ProcessRemainingInputs<T>(node, 1);
33091cb0ef41Sopenharmony_ci        SetOutput<T>(node, MachineRepresentation::kNone);
33101cb0ef41Sopenharmony_ci        return;
33111cb0ef41Sopenharmony_ci      }
33121cb0ef41Sopenharmony_ci      case IrOpcode::kCheckInternalizedString: {
33131cb0ef41Sopenharmony_ci        VisitCheck<T>(node, Type::InternalizedString(), lowering);
33141cb0ef41Sopenharmony_ci        return;
33151cb0ef41Sopenharmony_ci      }
33161cb0ef41Sopenharmony_ci      case IrOpcode::kCheckNumber: {
33171cb0ef41Sopenharmony_ci        Type const input_type = TypeOf(node->InputAt(0));
33181cb0ef41Sopenharmony_ci        if (input_type.Is(Type::Number())) {
33191cb0ef41Sopenharmony_ci          VisitNoop<T>(node, truncation);
33201cb0ef41Sopenharmony_ci        } else {
33211cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::AnyTagged(),
33221cb0ef41Sopenharmony_ci                       MachineRepresentation::kTagged);
33231cb0ef41Sopenharmony_ci        }
33241cb0ef41Sopenharmony_ci        return;
33251cb0ef41Sopenharmony_ci      }
33261cb0ef41Sopenharmony_ci      case IrOpcode::kCheckReceiver: {
33271cb0ef41Sopenharmony_ci        VisitCheck<T>(node, Type::Receiver(), lowering);
33281cb0ef41Sopenharmony_ci        return;
33291cb0ef41Sopenharmony_ci      }
33301cb0ef41Sopenharmony_ci      case IrOpcode::kCheckReceiverOrNullOrUndefined: {
33311cb0ef41Sopenharmony_ci        VisitCheck<T>(node, Type::ReceiverOrNullOrUndefined(), lowering);
33321cb0ef41Sopenharmony_ci        return;
33331cb0ef41Sopenharmony_ci      }
33341cb0ef41Sopenharmony_ci      case IrOpcode::kCheckSmi: {
33351cb0ef41Sopenharmony_ci        const CheckParameters& params = CheckParametersOf(node->op());
33361cb0ef41Sopenharmony_ci        if (SmiValuesAre32Bits() && truncation.IsUsedAsWord32()) {
33371cb0ef41Sopenharmony_ci          VisitUnop<T>(node,
33381cb0ef41Sopenharmony_ci                       UseInfo::CheckedSignedSmallAsWord32(kDistinguishZeros,
33391cb0ef41Sopenharmony_ci                                                           params.feedback()),
33401cb0ef41Sopenharmony_ci                       MachineRepresentation::kWord32);
33411cb0ef41Sopenharmony_ci        } else {
33421cb0ef41Sopenharmony_ci          VisitUnop<T>(
33431cb0ef41Sopenharmony_ci              node,
33441cb0ef41Sopenharmony_ci              UseInfo::CheckedSignedSmallAsTaggedSigned(params.feedback()),
33451cb0ef41Sopenharmony_ci              MachineRepresentation::kTaggedSigned);
33461cb0ef41Sopenharmony_ci        }
33471cb0ef41Sopenharmony_ci        if (lower<T>()) DeferReplacement(node, node->InputAt(0));
33481cb0ef41Sopenharmony_ci        return;
33491cb0ef41Sopenharmony_ci      }
33501cb0ef41Sopenharmony_ci      case IrOpcode::kCheckString: {
33511cb0ef41Sopenharmony_ci        const CheckParameters& params = CheckParametersOf(node->op());
33521cb0ef41Sopenharmony_ci        if (InputIs(node, Type::String())) {
33531cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::AnyTagged(),
33541cb0ef41Sopenharmony_ci                       MachineRepresentation::kTaggedPointer);
33551cb0ef41Sopenharmony_ci          if (lower<T>()) DeferReplacement(node, node->InputAt(0));
33561cb0ef41Sopenharmony_ci        } else {
33571cb0ef41Sopenharmony_ci          VisitUnop<T>(
33581cb0ef41Sopenharmony_ci              node,
33591cb0ef41Sopenharmony_ci              UseInfo::CheckedHeapObjectAsTaggedPointer(params.feedback()),
33601cb0ef41Sopenharmony_ci              MachineRepresentation::kTaggedPointer);
33611cb0ef41Sopenharmony_ci        }
33621cb0ef41Sopenharmony_ci        return;
33631cb0ef41Sopenharmony_ci      }
33641cb0ef41Sopenharmony_ci      case IrOpcode::kCheckSymbol: {
33651cb0ef41Sopenharmony_ci        VisitCheck<T>(node, Type::Symbol(), lowering);
33661cb0ef41Sopenharmony_ci        return;
33671cb0ef41Sopenharmony_ci      }
33681cb0ef41Sopenharmony_ci
33691cb0ef41Sopenharmony_ci      case IrOpcode::kAllocate: {
33701cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 0, UseInfo::Word());
33711cb0ef41Sopenharmony_ci        ProcessRemainingInputs<T>(node, 1);
33721cb0ef41Sopenharmony_ci        SetOutput<T>(node, MachineRepresentation::kTaggedPointer);
33731cb0ef41Sopenharmony_ci        return;
33741cb0ef41Sopenharmony_ci      }
33751cb0ef41Sopenharmony_ci      case IrOpcode::kLoadFramePointer: {
33761cb0ef41Sopenharmony_ci        SetOutput<T>(node, MachineType::PointerRepresentation());
33771cb0ef41Sopenharmony_ci        return;
33781cb0ef41Sopenharmony_ci      }
33791cb0ef41Sopenharmony_ci      case IrOpcode::kLoadMessage: {
33801cb0ef41Sopenharmony_ci        if (truncation.IsUnused()) return VisitUnused<T>(node);
33811cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfo::Word(), MachineRepresentation::kTagged);
33821cb0ef41Sopenharmony_ci        return;
33831cb0ef41Sopenharmony_ci      }
33841cb0ef41Sopenharmony_ci      case IrOpcode::kStoreMessage: {
33851cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 0, UseInfo::Word());
33861cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 1, UseInfo::AnyTagged());
33871cb0ef41Sopenharmony_ci        ProcessRemainingInputs<T>(node, 2);
33881cb0ef41Sopenharmony_ci        SetOutput<T>(node, MachineRepresentation::kNone);
33891cb0ef41Sopenharmony_ci        return;
33901cb0ef41Sopenharmony_ci      }
33911cb0ef41Sopenharmony_ci      case IrOpcode::kLoadFieldByIndex: {
33921cb0ef41Sopenharmony_ci        if (truncation.IsUnused()) return VisitUnused<T>(node);
33931cb0ef41Sopenharmony_ci        VisitBinop<T>(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(),
33941cb0ef41Sopenharmony_ci                      MachineRepresentation::kTagged);
33951cb0ef41Sopenharmony_ci        return;
33961cb0ef41Sopenharmony_ci      }
33971cb0ef41Sopenharmony_ci      case IrOpcode::kLoadField: {
33981cb0ef41Sopenharmony_ci        if (truncation.IsUnused()) return VisitUnused<T>(node);
33991cb0ef41Sopenharmony_ci        FieldAccess access = FieldAccessOf(node->op());
34001cb0ef41Sopenharmony_ci        MachineRepresentation const representation =
34011cb0ef41Sopenharmony_ci            access.machine_type.representation();
34021cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfoForBasePointer(access), representation);
34031cb0ef41Sopenharmony_ci        return;
34041cb0ef41Sopenharmony_ci      }
34051cb0ef41Sopenharmony_ci      case IrOpcode::kStoreField: {
34061cb0ef41Sopenharmony_ci        FieldAccess access = FieldAccessOf(node->op());
34071cb0ef41Sopenharmony_ci        Node* value_node = node->InputAt(1);
34081cb0ef41Sopenharmony_ci        NodeInfo* input_info = GetInfo(value_node);
34091cb0ef41Sopenharmony_ci        MachineRepresentation field_representation =
34101cb0ef41Sopenharmony_ci            access.machine_type.representation();
34111cb0ef41Sopenharmony_ci
34121cb0ef41Sopenharmony_ci        // Convert to Smi if possible, such that we can avoid a write barrier.
34131cb0ef41Sopenharmony_ci        if (field_representation == MachineRepresentation::kTagged &&
34141cb0ef41Sopenharmony_ci            TypeOf(value_node).Is(Type::SignedSmall())) {
34151cb0ef41Sopenharmony_ci          field_representation = MachineRepresentation::kTaggedSigned;
34161cb0ef41Sopenharmony_ci        }
34171cb0ef41Sopenharmony_ci        WriteBarrierKind write_barrier_kind = WriteBarrierKindFor(
34181cb0ef41Sopenharmony_ci            access.base_is_tagged, field_representation, access.offset,
34191cb0ef41Sopenharmony_ci            access.type, input_info->representation(), value_node);
34201cb0ef41Sopenharmony_ci
34211cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 0, UseInfoForBasePointer(access));
34221cb0ef41Sopenharmony_ci        ProcessInput<T>(
34231cb0ef41Sopenharmony_ci            node, 1, TruncatingUseInfoFromRepresentation(field_representation));
34241cb0ef41Sopenharmony_ci        ProcessRemainingInputs<T>(node, 2);
34251cb0ef41Sopenharmony_ci        SetOutput<T>(node, MachineRepresentation::kNone);
34261cb0ef41Sopenharmony_ci        if (lower<T>()) {
34271cb0ef41Sopenharmony_ci          if (write_barrier_kind < access.write_barrier_kind) {
34281cb0ef41Sopenharmony_ci            access.write_barrier_kind = write_barrier_kind;
34291cb0ef41Sopenharmony_ci            ChangeOp(node, jsgraph_->simplified()->StoreField(access));
34301cb0ef41Sopenharmony_ci          }
34311cb0ef41Sopenharmony_ci        }
34321cb0ef41Sopenharmony_ci        return;
34331cb0ef41Sopenharmony_ci      }
34341cb0ef41Sopenharmony_ci      case IrOpcode::kLoadElement: {
34351cb0ef41Sopenharmony_ci        if (truncation.IsUnused()) return VisitUnused<T>(node);
34361cb0ef41Sopenharmony_ci        ElementAccess access = ElementAccessOf(node->op());
34371cb0ef41Sopenharmony_ci        VisitBinop<T>(node, UseInfoForBasePointer(access), UseInfo::Word(),
34381cb0ef41Sopenharmony_ci                      access.machine_type.representation());
34391cb0ef41Sopenharmony_ci        return;
34401cb0ef41Sopenharmony_ci      }
34411cb0ef41Sopenharmony_ci      case IrOpcode::kLoadStackArgument: {
34421cb0ef41Sopenharmony_ci        if (truncation.IsUnused()) return VisitUnused<T>(node);
34431cb0ef41Sopenharmony_ci        VisitBinop<T>(node, UseInfo::Word(), MachineRepresentation::kTagged);
34441cb0ef41Sopenharmony_ci        return;
34451cb0ef41Sopenharmony_ci      }
34461cb0ef41Sopenharmony_ci      case IrOpcode::kStoreElement: {
34471cb0ef41Sopenharmony_ci        ElementAccess access = ElementAccessOf(node->op());
34481cb0ef41Sopenharmony_ci        Node* value_node = node->InputAt(2);
34491cb0ef41Sopenharmony_ci        NodeInfo* input_info = GetInfo(value_node);
34501cb0ef41Sopenharmony_ci        MachineRepresentation element_representation =
34511cb0ef41Sopenharmony_ci            access.machine_type.representation();
34521cb0ef41Sopenharmony_ci
34531cb0ef41Sopenharmony_ci        // Convert to Smi if possible, such that we can avoid a write barrier.
34541cb0ef41Sopenharmony_ci        if (element_representation == MachineRepresentation::kTagged &&
34551cb0ef41Sopenharmony_ci            TypeOf(value_node).Is(Type::SignedSmall())) {
34561cb0ef41Sopenharmony_ci          element_representation = MachineRepresentation::kTaggedSigned;
34571cb0ef41Sopenharmony_ci        }
34581cb0ef41Sopenharmony_ci        WriteBarrierKind write_barrier_kind = WriteBarrierKindFor(
34591cb0ef41Sopenharmony_ci            access.base_is_tagged, element_representation, access.type,
34601cb0ef41Sopenharmony_ci            input_info->representation(), value_node);
34611cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 0, UseInfoForBasePointer(access));  // base
34621cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 1, UseInfo::Word());                // index
34631cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 2,
34641cb0ef41Sopenharmony_ci                        TruncatingUseInfoFromRepresentation(
34651cb0ef41Sopenharmony_ci                            element_representation));  // value
34661cb0ef41Sopenharmony_ci        ProcessRemainingInputs<T>(node, 3);
34671cb0ef41Sopenharmony_ci        SetOutput<T>(node, MachineRepresentation::kNone);
34681cb0ef41Sopenharmony_ci        if (lower<T>()) {
34691cb0ef41Sopenharmony_ci          if (write_barrier_kind < access.write_barrier_kind) {
34701cb0ef41Sopenharmony_ci            access.write_barrier_kind = write_barrier_kind;
34711cb0ef41Sopenharmony_ci            ChangeOp(node, jsgraph_->simplified()->StoreElement(access));
34721cb0ef41Sopenharmony_ci          }
34731cb0ef41Sopenharmony_ci        }
34741cb0ef41Sopenharmony_ci        return;
34751cb0ef41Sopenharmony_ci      }
34761cb0ef41Sopenharmony_ci      case IrOpcode::kNumberIsFloat64Hole: {
34771cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
34781cb0ef41Sopenharmony_ci                     MachineRepresentation::kBit);
34791cb0ef41Sopenharmony_ci        return;
34801cb0ef41Sopenharmony_ci      }
34811cb0ef41Sopenharmony_ci      case IrOpcode::kTransitionAndStoreElement: {
34821cb0ef41Sopenharmony_ci        Type value_type = TypeOf(node->InputAt(2));
34831cb0ef41Sopenharmony_ci
34841cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 0, UseInfo::AnyTagged());  // array
34851cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 1, UseInfo::Word());       // index
34861cb0ef41Sopenharmony_ci
34871cb0ef41Sopenharmony_ci        if (value_type.Is(Type::SignedSmall())) {
34881cb0ef41Sopenharmony_ci          ProcessInput<T>(node, 2, UseInfo::TruncatingWord32());  // value
34891cb0ef41Sopenharmony_ci          if (lower<T>()) {
34901cb0ef41Sopenharmony_ci            ChangeOp(node, simplified()->StoreSignedSmallElement());
34911cb0ef41Sopenharmony_ci          }
34921cb0ef41Sopenharmony_ci        } else if (value_type.Is(Type::Number())) {
34931cb0ef41Sopenharmony_ci          ProcessInput<T>(node, 2, UseInfo::TruncatingFloat64());  // value
34941cb0ef41Sopenharmony_ci          if (lower<T>()) {
34951cb0ef41Sopenharmony_ci            Handle<Map> double_map = DoubleMapParameterOf(node->op());
34961cb0ef41Sopenharmony_ci            ChangeOp(node,
34971cb0ef41Sopenharmony_ci                     simplified()->TransitionAndStoreNumberElement(double_map));
34981cb0ef41Sopenharmony_ci          }
34991cb0ef41Sopenharmony_ci        } else if (value_type.Is(Type::NonNumber())) {
35001cb0ef41Sopenharmony_ci          ProcessInput<T>(node, 2, UseInfo::AnyTagged());  // value
35011cb0ef41Sopenharmony_ci          if (lower<T>()) {
35021cb0ef41Sopenharmony_ci            Handle<Map> fast_map = FastMapParameterOf(node->op());
35031cb0ef41Sopenharmony_ci            ChangeOp(node, simplified()->TransitionAndStoreNonNumberElement(
35041cb0ef41Sopenharmony_ci                               fast_map, value_type));
35051cb0ef41Sopenharmony_ci          }
35061cb0ef41Sopenharmony_ci        } else {
35071cb0ef41Sopenharmony_ci          ProcessInput<T>(node, 2, UseInfo::AnyTagged());  // value
35081cb0ef41Sopenharmony_ci        }
35091cb0ef41Sopenharmony_ci
35101cb0ef41Sopenharmony_ci        ProcessRemainingInputs<T>(node, 3);
35111cb0ef41Sopenharmony_ci        SetOutput<T>(node, MachineRepresentation::kNone);
35121cb0ef41Sopenharmony_ci        return;
35131cb0ef41Sopenharmony_ci      }
35141cb0ef41Sopenharmony_ci      case IrOpcode::kLoadTypedElement: {
35151cb0ef41Sopenharmony_ci        MachineRepresentation const rep =
35161cb0ef41Sopenharmony_ci            MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
35171cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 0, UseInfo::AnyTagged());  // buffer
35181cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 1, UseInfo::AnyTagged());  // base pointer
35191cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 2, UseInfo::Word());       // external pointer
35201cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 3, UseInfo::Word());       // index
35211cb0ef41Sopenharmony_ci        ProcessRemainingInputs<T>(node, 4);
35221cb0ef41Sopenharmony_ci        SetOutput<T>(node, rep);
35231cb0ef41Sopenharmony_ci        return;
35241cb0ef41Sopenharmony_ci      }
35251cb0ef41Sopenharmony_ci      case IrOpcode::kLoadDataViewElement: {
35261cb0ef41Sopenharmony_ci        MachineRepresentation const rep =
35271cb0ef41Sopenharmony_ci            MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
35281cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 0, UseInfo::AnyTagged());  // object
35291cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 1, UseInfo::Word());       // base
35301cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 2, UseInfo::Word());       // index
35311cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 3, UseInfo::Bool());       // little-endian
35321cb0ef41Sopenharmony_ci        ProcessRemainingInputs<T>(node, 4);
35331cb0ef41Sopenharmony_ci        SetOutput<T>(node, rep);
35341cb0ef41Sopenharmony_ci        return;
35351cb0ef41Sopenharmony_ci      }
35361cb0ef41Sopenharmony_ci      case IrOpcode::kStoreTypedElement: {
35371cb0ef41Sopenharmony_ci        MachineRepresentation const rep =
35381cb0ef41Sopenharmony_ci            MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
35391cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 0, UseInfo::AnyTagged());  // buffer
35401cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 1, UseInfo::AnyTagged());  // base pointer
35411cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 2, UseInfo::Word());       // external pointer
35421cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 3, UseInfo::Word());       // index
35431cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 4,
35441cb0ef41Sopenharmony_ci                        TruncatingUseInfoFromRepresentation(rep));  // value
35451cb0ef41Sopenharmony_ci        ProcessRemainingInputs<T>(node, 5);
35461cb0ef41Sopenharmony_ci        SetOutput<T>(node, MachineRepresentation::kNone);
35471cb0ef41Sopenharmony_ci        return;
35481cb0ef41Sopenharmony_ci      }
35491cb0ef41Sopenharmony_ci      case IrOpcode::kStoreDataViewElement: {
35501cb0ef41Sopenharmony_ci        MachineRepresentation const rep =
35511cb0ef41Sopenharmony_ci            MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
35521cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 0, UseInfo::AnyTagged());  // object
35531cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 1, UseInfo::Word());       // base
35541cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 2, UseInfo::Word());       // index
35551cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 3,
35561cb0ef41Sopenharmony_ci                        TruncatingUseInfoFromRepresentation(rep));  // value
35571cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 4, UseInfo::Bool());  // little-endian
35581cb0ef41Sopenharmony_ci        ProcessRemainingInputs<T>(node, 5);
35591cb0ef41Sopenharmony_ci        SetOutput<T>(node, MachineRepresentation::kNone);
35601cb0ef41Sopenharmony_ci        return;
35611cb0ef41Sopenharmony_ci      }
35621cb0ef41Sopenharmony_ci      case IrOpcode::kConvertReceiver: {
35631cb0ef41Sopenharmony_ci        Type input_type = TypeOf(node->InputAt(0));
35641cb0ef41Sopenharmony_ci        VisitBinop<T>(node, UseInfo::AnyTagged(),
35651cb0ef41Sopenharmony_ci                      MachineRepresentation::kTaggedPointer);
35661cb0ef41Sopenharmony_ci        if (lower<T>()) {
35671cb0ef41Sopenharmony_ci          // Try to optimize the {node} based on the input type.
35681cb0ef41Sopenharmony_ci          if (input_type.Is(Type::Receiver())) {
35691cb0ef41Sopenharmony_ci            DeferReplacement(node, node->InputAt(0));
35701cb0ef41Sopenharmony_ci          } else if (input_type.Is(Type::NullOrUndefined())) {
35711cb0ef41Sopenharmony_ci            DeferReplacement(node, node->InputAt(1));
35721cb0ef41Sopenharmony_ci          } else if (!input_type.Maybe(Type::NullOrUndefined())) {
35731cb0ef41Sopenharmony_ci            ChangeOp(node, lowering->simplified()->ConvertReceiver(
35741cb0ef41Sopenharmony_ci                               ConvertReceiverMode::kNotNullOrUndefined));
35751cb0ef41Sopenharmony_ci          }
35761cb0ef41Sopenharmony_ci        }
35771cb0ef41Sopenharmony_ci        return;
35781cb0ef41Sopenharmony_ci      }
35791cb0ef41Sopenharmony_ci      case IrOpcode::kPlainPrimitiveToNumber: {
35801cb0ef41Sopenharmony_ci        if (InputIs(node, Type::Boolean())) {
35811cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::Bool(), MachineRepresentation::kWord32);
35821cb0ef41Sopenharmony_ci          if (lower<T>()) {
35831cb0ef41Sopenharmony_ci            ChangeToSemanticsHintForVerifier(node, node->op());
35841cb0ef41Sopenharmony_ci          }
35851cb0ef41Sopenharmony_ci        } else if (InputIs(node, Type::String())) {
35861cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::AnyTagged(),
35871cb0ef41Sopenharmony_ci                       MachineRepresentation::kTagged);
35881cb0ef41Sopenharmony_ci          if (lower<T>()) {
35891cb0ef41Sopenharmony_ci            ChangeOp(node, simplified()->StringToNumber());
35901cb0ef41Sopenharmony_ci          }
35911cb0ef41Sopenharmony_ci        } else if (truncation.IsUsedAsWord32()) {
35921cb0ef41Sopenharmony_ci          if (InputIs(node, Type::NumberOrOddball())) {
35931cb0ef41Sopenharmony_ci            VisitUnop<T>(node, UseInfo::TruncatingWord32(),
35941cb0ef41Sopenharmony_ci                         MachineRepresentation::kWord32);
35951cb0ef41Sopenharmony_ci            if (lower<T>()) {
35961cb0ef41Sopenharmony_ci              ChangeToSemanticsHintForVerifier(node, node->op());
35971cb0ef41Sopenharmony_ci            }
35981cb0ef41Sopenharmony_ci          } else {
35991cb0ef41Sopenharmony_ci            VisitUnop<T>(node, UseInfo::AnyTagged(),
36001cb0ef41Sopenharmony_ci                         MachineRepresentation::kWord32);
36011cb0ef41Sopenharmony_ci            if (lower<T>()) {
36021cb0ef41Sopenharmony_ci              ChangeOp(node, simplified()->PlainPrimitiveToWord32());
36031cb0ef41Sopenharmony_ci            }
36041cb0ef41Sopenharmony_ci          }
36051cb0ef41Sopenharmony_ci        } else if (truncation.TruncatesOddballAndBigIntToNumber()) {
36061cb0ef41Sopenharmony_ci          if (InputIs(node, Type::NumberOrOddball())) {
36071cb0ef41Sopenharmony_ci            VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
36081cb0ef41Sopenharmony_ci                         MachineRepresentation::kFloat64);
36091cb0ef41Sopenharmony_ci            if (lower<T>()) {
36101cb0ef41Sopenharmony_ci              ChangeToSemanticsHintForVerifier(node, node->op());
36111cb0ef41Sopenharmony_ci            }
36121cb0ef41Sopenharmony_ci          } else {
36131cb0ef41Sopenharmony_ci            VisitUnop<T>(node, UseInfo::AnyTagged(),
36141cb0ef41Sopenharmony_ci                         MachineRepresentation::kFloat64);
36151cb0ef41Sopenharmony_ci            if (lower<T>()) {
36161cb0ef41Sopenharmony_ci              ChangeOp(node, simplified()->PlainPrimitiveToFloat64());
36171cb0ef41Sopenharmony_ci            }
36181cb0ef41Sopenharmony_ci          }
36191cb0ef41Sopenharmony_ci        } else {
36201cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::AnyTagged(),
36211cb0ef41Sopenharmony_ci                       MachineRepresentation::kTagged);
36221cb0ef41Sopenharmony_ci        }
36231cb0ef41Sopenharmony_ci        return;
36241cb0ef41Sopenharmony_ci      }
36251cb0ef41Sopenharmony_ci      case IrOpcode::kSpeculativeToNumber: {
36261cb0ef41Sopenharmony_ci        NumberOperationParameters const& p =
36271cb0ef41Sopenharmony_ci            NumberOperationParametersOf(node->op());
36281cb0ef41Sopenharmony_ci        switch (p.hint()) {
36291cb0ef41Sopenharmony_ci          case NumberOperationHint::kSignedSmall:
36301cb0ef41Sopenharmony_ci          case NumberOperationHint::kSignedSmallInputs:
36311cb0ef41Sopenharmony_ci            VisitUnop<T>(node,
36321cb0ef41Sopenharmony_ci                         CheckedUseInfoAsWord32FromHint(
36331cb0ef41Sopenharmony_ci                             p.hint(), kDistinguishZeros, p.feedback()),
36341cb0ef41Sopenharmony_ci                         MachineRepresentation::kWord32, Type::Signed32());
36351cb0ef41Sopenharmony_ci            break;
36361cb0ef41Sopenharmony_ci          case NumberOperationHint::kNumber:
36371cb0ef41Sopenharmony_ci          case NumberOperationHint::kNumberOrBoolean:
36381cb0ef41Sopenharmony_ci          case NumberOperationHint::kNumberOrOddball:
36391cb0ef41Sopenharmony_ci            VisitUnop<T>(
36401cb0ef41Sopenharmony_ci                node, CheckedUseInfoAsFloat64FromHint(p.hint(), p.feedback()),
36411cb0ef41Sopenharmony_ci                MachineRepresentation::kFloat64);
36421cb0ef41Sopenharmony_ci            break;
36431cb0ef41Sopenharmony_ci        }
36441cb0ef41Sopenharmony_ci        if (lower<T>()) DeferReplacement(node, node->InputAt(0));
36451cb0ef41Sopenharmony_ci        return;
36461cb0ef41Sopenharmony_ci      }
36471cb0ef41Sopenharmony_ci      case IrOpcode::kObjectIsArrayBufferView: {
36481cb0ef41Sopenharmony_ci        // TODO(turbofan): Introduce a Type::ArrayBufferView?
36491cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
36501cb0ef41Sopenharmony_ci        return;
36511cb0ef41Sopenharmony_ci      }
36521cb0ef41Sopenharmony_ci      case IrOpcode::kObjectIsBigInt: {
36531cb0ef41Sopenharmony_ci        VisitObjectIs<T>(node, Type::BigInt(), lowering);
36541cb0ef41Sopenharmony_ci        return;
36551cb0ef41Sopenharmony_ci      }
36561cb0ef41Sopenharmony_ci      case IrOpcode::kObjectIsCallable: {
36571cb0ef41Sopenharmony_ci        VisitObjectIs<T>(node, Type::Callable(), lowering);
36581cb0ef41Sopenharmony_ci        return;
36591cb0ef41Sopenharmony_ci      }
36601cb0ef41Sopenharmony_ci      case IrOpcode::kObjectIsConstructor: {
36611cb0ef41Sopenharmony_ci        // TODO(turbofan): Introduce a Type::Constructor?
36621cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
36631cb0ef41Sopenharmony_ci        return;
36641cb0ef41Sopenharmony_ci      }
36651cb0ef41Sopenharmony_ci      case IrOpcode::kObjectIsDetectableCallable: {
36661cb0ef41Sopenharmony_ci        VisitObjectIs<T>(node, Type::DetectableCallable(), lowering);
36671cb0ef41Sopenharmony_ci        return;
36681cb0ef41Sopenharmony_ci      }
36691cb0ef41Sopenharmony_ci      case IrOpcode::kObjectIsFiniteNumber: {
36701cb0ef41Sopenharmony_ci        Type const input_type = GetUpperBound(node->InputAt(0));
36711cb0ef41Sopenharmony_ci        if (input_type.Is(type_cache_->kSafeInteger)) {
36721cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::None(), MachineRepresentation::kBit);
36731cb0ef41Sopenharmony_ci          if (lower<T>()) {
36741cb0ef41Sopenharmony_ci            DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
36751cb0ef41Sopenharmony_ci          }
36761cb0ef41Sopenharmony_ci        } else if (!input_type.Maybe(Type::Number())) {
36771cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::Any(), MachineRepresentation::kBit);
36781cb0ef41Sopenharmony_ci          if (lower<T>()) {
36791cb0ef41Sopenharmony_ci            DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
36801cb0ef41Sopenharmony_ci          }
36811cb0ef41Sopenharmony_ci        } else if (input_type.Is(Type::Number())) {
36821cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
36831cb0ef41Sopenharmony_ci                       MachineRepresentation::kBit);
36841cb0ef41Sopenharmony_ci          if (lower<T>()) {
36851cb0ef41Sopenharmony_ci            ChangeOp(node, lowering->simplified()->NumberIsFinite());
36861cb0ef41Sopenharmony_ci          }
36871cb0ef41Sopenharmony_ci        } else {
36881cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
36891cb0ef41Sopenharmony_ci        }
36901cb0ef41Sopenharmony_ci        return;
36911cb0ef41Sopenharmony_ci      }
36921cb0ef41Sopenharmony_ci      case IrOpcode::kNumberIsFinite: {
36931cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
36941cb0ef41Sopenharmony_ci                     MachineRepresentation::kBit);
36951cb0ef41Sopenharmony_ci        return;
36961cb0ef41Sopenharmony_ci      }
36971cb0ef41Sopenharmony_ci      case IrOpcode::kObjectIsSafeInteger: {
36981cb0ef41Sopenharmony_ci        Type const input_type = GetUpperBound(node->InputAt(0));
36991cb0ef41Sopenharmony_ci        if (input_type.Is(type_cache_->kSafeInteger)) {
37001cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::None(), MachineRepresentation::kBit);
37011cb0ef41Sopenharmony_ci          if (lower<T>()) {
37021cb0ef41Sopenharmony_ci            DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
37031cb0ef41Sopenharmony_ci          }
37041cb0ef41Sopenharmony_ci        } else if (!input_type.Maybe(Type::Number())) {
37051cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::Any(), MachineRepresentation::kBit);
37061cb0ef41Sopenharmony_ci          if (lower<T>()) {
37071cb0ef41Sopenharmony_ci            DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
37081cb0ef41Sopenharmony_ci          }
37091cb0ef41Sopenharmony_ci        } else if (input_type.Is(Type::Number())) {
37101cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
37111cb0ef41Sopenharmony_ci                       MachineRepresentation::kBit);
37121cb0ef41Sopenharmony_ci          if (lower<T>()) {
37131cb0ef41Sopenharmony_ci            ChangeOp(node, lowering->simplified()->NumberIsSafeInteger());
37141cb0ef41Sopenharmony_ci          }
37151cb0ef41Sopenharmony_ci        } else {
37161cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
37171cb0ef41Sopenharmony_ci        }
37181cb0ef41Sopenharmony_ci        return;
37191cb0ef41Sopenharmony_ci      }
37201cb0ef41Sopenharmony_ci      case IrOpcode::kNumberIsSafeInteger: {
37211cb0ef41Sopenharmony_ci        UNREACHABLE();
37221cb0ef41Sopenharmony_ci      }
37231cb0ef41Sopenharmony_ci      case IrOpcode::kObjectIsInteger: {
37241cb0ef41Sopenharmony_ci        Type const input_type = GetUpperBound(node->InputAt(0));
37251cb0ef41Sopenharmony_ci        if (input_type.Is(type_cache_->kSafeInteger)) {
37261cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::None(), MachineRepresentation::kBit);
37271cb0ef41Sopenharmony_ci          if (lower<T>()) {
37281cb0ef41Sopenharmony_ci            DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
37291cb0ef41Sopenharmony_ci          }
37301cb0ef41Sopenharmony_ci        } else if (!input_type.Maybe(Type::Number())) {
37311cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::Any(), MachineRepresentation::kBit);
37321cb0ef41Sopenharmony_ci          if (lower<T>()) {
37331cb0ef41Sopenharmony_ci            DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
37341cb0ef41Sopenharmony_ci          }
37351cb0ef41Sopenharmony_ci        } else if (input_type.Is(Type::Number())) {
37361cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
37371cb0ef41Sopenharmony_ci                       MachineRepresentation::kBit);
37381cb0ef41Sopenharmony_ci          if (lower<T>()) {
37391cb0ef41Sopenharmony_ci            ChangeOp(node, lowering->simplified()->NumberIsInteger());
37401cb0ef41Sopenharmony_ci          }
37411cb0ef41Sopenharmony_ci        } else {
37421cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
37431cb0ef41Sopenharmony_ci        }
37441cb0ef41Sopenharmony_ci        return;
37451cb0ef41Sopenharmony_ci      }
37461cb0ef41Sopenharmony_ci      case IrOpcode::kNumberIsInteger: {
37471cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
37481cb0ef41Sopenharmony_ci                     MachineRepresentation::kBit);
37491cb0ef41Sopenharmony_ci        return;
37501cb0ef41Sopenharmony_ci      }
37511cb0ef41Sopenharmony_ci      case IrOpcode::kObjectIsMinusZero: {
37521cb0ef41Sopenharmony_ci        Type const input_type = GetUpperBound(node->InputAt(0));
37531cb0ef41Sopenharmony_ci        if (input_type.Is(Type::MinusZero())) {
37541cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::None(), MachineRepresentation::kBit);
37551cb0ef41Sopenharmony_ci          if (lower<T>()) {
37561cb0ef41Sopenharmony_ci            DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
37571cb0ef41Sopenharmony_ci          }
37581cb0ef41Sopenharmony_ci        } else if (!input_type.Maybe(Type::MinusZero())) {
37591cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::Any(), MachineRepresentation::kBit);
37601cb0ef41Sopenharmony_ci          if (lower<T>()) {
37611cb0ef41Sopenharmony_ci            DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
37621cb0ef41Sopenharmony_ci          }
37631cb0ef41Sopenharmony_ci        } else if (input_type.Is(Type::Number())) {
37641cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
37651cb0ef41Sopenharmony_ci                       MachineRepresentation::kBit);
37661cb0ef41Sopenharmony_ci          if (lower<T>()) {
37671cb0ef41Sopenharmony_ci            ChangeOp(node, simplified()->NumberIsMinusZero());
37681cb0ef41Sopenharmony_ci          }
37691cb0ef41Sopenharmony_ci        } else {
37701cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
37711cb0ef41Sopenharmony_ci        }
37721cb0ef41Sopenharmony_ci        return;
37731cb0ef41Sopenharmony_ci      }
37741cb0ef41Sopenharmony_ci      case IrOpcode::kObjectIsNaN: {
37751cb0ef41Sopenharmony_ci        Type const input_type = GetUpperBound(node->InputAt(0));
37761cb0ef41Sopenharmony_ci        if (input_type.Is(Type::NaN())) {
37771cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::None(), MachineRepresentation::kBit);
37781cb0ef41Sopenharmony_ci          if (lower<T>()) {
37791cb0ef41Sopenharmony_ci            DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
37801cb0ef41Sopenharmony_ci          }
37811cb0ef41Sopenharmony_ci        } else if (!input_type.Maybe(Type::NaN())) {
37821cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::Any(), MachineRepresentation::kBit);
37831cb0ef41Sopenharmony_ci          if (lower<T>()) {
37841cb0ef41Sopenharmony_ci            DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
37851cb0ef41Sopenharmony_ci          }
37861cb0ef41Sopenharmony_ci        } else if (input_type.Is(Type::Number())) {
37871cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
37881cb0ef41Sopenharmony_ci                       MachineRepresentation::kBit);
37891cb0ef41Sopenharmony_ci          if (lower<T>()) {
37901cb0ef41Sopenharmony_ci            ChangeOp(node, simplified()->NumberIsNaN());
37911cb0ef41Sopenharmony_ci          }
37921cb0ef41Sopenharmony_ci        } else {
37931cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
37941cb0ef41Sopenharmony_ci        }
37951cb0ef41Sopenharmony_ci        return;
37961cb0ef41Sopenharmony_ci      }
37971cb0ef41Sopenharmony_ci      case IrOpcode::kNumberIsNaN: {
37981cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
37991cb0ef41Sopenharmony_ci                     MachineRepresentation::kBit);
38001cb0ef41Sopenharmony_ci        return;
38011cb0ef41Sopenharmony_ci      }
38021cb0ef41Sopenharmony_ci      case IrOpcode::kObjectIsNonCallable: {
38031cb0ef41Sopenharmony_ci        VisitObjectIs<T>(node, Type::NonCallable(), lowering);
38041cb0ef41Sopenharmony_ci        return;
38051cb0ef41Sopenharmony_ci      }
38061cb0ef41Sopenharmony_ci      case IrOpcode::kObjectIsNumber: {
38071cb0ef41Sopenharmony_ci        VisitObjectIs<T>(node, Type::Number(), lowering);
38081cb0ef41Sopenharmony_ci        return;
38091cb0ef41Sopenharmony_ci      }
38101cb0ef41Sopenharmony_ci      case IrOpcode::kObjectIsReceiver: {
38111cb0ef41Sopenharmony_ci        VisitObjectIs<T>(node, Type::Receiver(), lowering);
38121cb0ef41Sopenharmony_ci        return;
38131cb0ef41Sopenharmony_ci      }
38141cb0ef41Sopenharmony_ci      case IrOpcode::kObjectIsSmi: {
38151cb0ef41Sopenharmony_ci        // TODO(turbofan): Optimize based on input representation.
38161cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
38171cb0ef41Sopenharmony_ci        return;
38181cb0ef41Sopenharmony_ci      }
38191cb0ef41Sopenharmony_ci      case IrOpcode::kObjectIsString: {
38201cb0ef41Sopenharmony_ci        VisitObjectIs<T>(node, Type::String(), lowering);
38211cb0ef41Sopenharmony_ci        return;
38221cb0ef41Sopenharmony_ci      }
38231cb0ef41Sopenharmony_ci      case IrOpcode::kObjectIsSymbol: {
38241cb0ef41Sopenharmony_ci        VisitObjectIs<T>(node, Type::Symbol(), lowering);
38251cb0ef41Sopenharmony_ci        return;
38261cb0ef41Sopenharmony_ci      }
38271cb0ef41Sopenharmony_ci      case IrOpcode::kObjectIsUndetectable: {
38281cb0ef41Sopenharmony_ci        VisitObjectIs<T>(node, Type::Undetectable(), lowering);
38291cb0ef41Sopenharmony_ci        return;
38301cb0ef41Sopenharmony_ci      }
38311cb0ef41Sopenharmony_ci      case IrOpcode::kArgumentsLength:
38321cb0ef41Sopenharmony_ci      case IrOpcode::kRestLength: {
38331cb0ef41Sopenharmony_ci        SetOutput<T>(node, MachineRepresentation::kTaggedSigned);
38341cb0ef41Sopenharmony_ci        return;
38351cb0ef41Sopenharmony_ci      }
38361cb0ef41Sopenharmony_ci      case IrOpcode::kNewDoubleElements:
38371cb0ef41Sopenharmony_ci      case IrOpcode::kNewSmiOrObjectElements: {
38381cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfo::Word(),
38391cb0ef41Sopenharmony_ci                     MachineRepresentation::kTaggedPointer);
38401cb0ef41Sopenharmony_ci        return;
38411cb0ef41Sopenharmony_ci      }
38421cb0ef41Sopenharmony_ci      case IrOpcode::kNewArgumentsElements: {
38431cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfo::TaggedSigned(),
38441cb0ef41Sopenharmony_ci                     MachineRepresentation::kTaggedPointer);
38451cb0ef41Sopenharmony_ci        return;
38461cb0ef41Sopenharmony_ci      }
38471cb0ef41Sopenharmony_ci      case IrOpcode::kCheckFloat64Hole: {
38481cb0ef41Sopenharmony_ci        Type const input_type = TypeOf(node->InputAt(0));
38491cb0ef41Sopenharmony_ci        CheckFloat64HoleMode mode =
38501cb0ef41Sopenharmony_ci            CheckFloat64HoleParametersOf(node->op()).mode();
38511cb0ef41Sopenharmony_ci        if (mode == CheckFloat64HoleMode::kAllowReturnHole) {
38521cb0ef41Sopenharmony_ci          // If {mode} is allow-return-hole _and_ the {truncation}
38531cb0ef41Sopenharmony_ci          // identifies NaN and undefined, we can just pass along
38541cb0ef41Sopenharmony_ci          // the {truncation} and completely wipe the {node}.
38551cb0ef41Sopenharmony_ci          if (truncation.IsUnused()) return VisitUnused<T>(node);
38561cb0ef41Sopenharmony_ci          if (truncation.TruncatesOddballAndBigIntToNumber()) {
38571cb0ef41Sopenharmony_ci            VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
38581cb0ef41Sopenharmony_ci                         MachineRepresentation::kFloat64);
38591cb0ef41Sopenharmony_ci            if (lower<T>()) DeferReplacement(node, node->InputAt(0));
38601cb0ef41Sopenharmony_ci            return;
38611cb0ef41Sopenharmony_ci          }
38621cb0ef41Sopenharmony_ci        }
38631cb0ef41Sopenharmony_ci        VisitUnop<T>(
38641cb0ef41Sopenharmony_ci            node, UseInfo(MachineRepresentation::kFloat64, Truncation::Any()),
38651cb0ef41Sopenharmony_ci            MachineRepresentation::kFloat64, Type::Number());
38661cb0ef41Sopenharmony_ci        if (lower<T>() && input_type.Is(Type::Number())) {
38671cb0ef41Sopenharmony_ci          DeferReplacement(node, node->InputAt(0));
38681cb0ef41Sopenharmony_ci        }
38691cb0ef41Sopenharmony_ci        return;
38701cb0ef41Sopenharmony_ci      }
38711cb0ef41Sopenharmony_ci      case IrOpcode::kCheckNotTaggedHole: {
38721cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfo::AnyTagged(),
38731cb0ef41Sopenharmony_ci                     MachineRepresentation::kTagged);
38741cb0ef41Sopenharmony_ci        return;
38751cb0ef41Sopenharmony_ci      }
38761cb0ef41Sopenharmony_ci      case IrOpcode::kCheckClosure: {
38771cb0ef41Sopenharmony_ci        VisitUnop<T>(
38781cb0ef41Sopenharmony_ci            node, UseInfo::CheckedHeapObjectAsTaggedPointer(FeedbackSource()),
38791cb0ef41Sopenharmony_ci            MachineRepresentation::kTaggedPointer);
38801cb0ef41Sopenharmony_ci        return;
38811cb0ef41Sopenharmony_ci      }
38821cb0ef41Sopenharmony_ci      case IrOpcode::kConvertTaggedHoleToUndefined: {
38831cb0ef41Sopenharmony_ci        if (InputIs(node, Type::NumberOrOddball()) &&
38841cb0ef41Sopenharmony_ci            truncation.IsUsedAsWord32()) {
38851cb0ef41Sopenharmony_ci          // Propagate the Word32 truncation.
38861cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::TruncatingWord32(),
38871cb0ef41Sopenharmony_ci                       MachineRepresentation::kWord32);
38881cb0ef41Sopenharmony_ci          if (lower<T>()) DeferReplacement(node, node->InputAt(0));
38891cb0ef41Sopenharmony_ci        } else if (InputIs(node, Type::NumberOrOddball()) &&
38901cb0ef41Sopenharmony_ci                   truncation.TruncatesOddballAndBigIntToNumber()) {
38911cb0ef41Sopenharmony_ci          // Propagate the Float64 truncation.
38921cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
38931cb0ef41Sopenharmony_ci                       MachineRepresentation::kFloat64);
38941cb0ef41Sopenharmony_ci          if (lower<T>()) DeferReplacement(node, node->InputAt(0));
38951cb0ef41Sopenharmony_ci        } else if (InputIs(node, Type::NonInternal())) {
38961cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::AnyTagged(),
38971cb0ef41Sopenharmony_ci                       MachineRepresentation::kTagged);
38981cb0ef41Sopenharmony_ci          if (lower<T>()) DeferReplacement(node, node->InputAt(0));
38991cb0ef41Sopenharmony_ci        } else {
39001cb0ef41Sopenharmony_ci          // TODO(turbofan): Add a (Tagged) truncation that identifies hole
39011cb0ef41Sopenharmony_ci          // and undefined, i.e. for a[i] === obj cases.
39021cb0ef41Sopenharmony_ci          VisitUnop<T>(node, UseInfo::AnyTagged(),
39031cb0ef41Sopenharmony_ci                       MachineRepresentation::kTagged);
39041cb0ef41Sopenharmony_ci        }
39051cb0ef41Sopenharmony_ci        return;
39061cb0ef41Sopenharmony_ci      }
39071cb0ef41Sopenharmony_ci      case IrOpcode::kCheckEqualsSymbol:
39081cb0ef41Sopenharmony_ci      case IrOpcode::kCheckEqualsInternalizedString:
39091cb0ef41Sopenharmony_ci        return VisitBinop<T>(node, UseInfo::AnyTagged(),
39101cb0ef41Sopenharmony_ci                             MachineRepresentation::kNone);
39111cb0ef41Sopenharmony_ci      case IrOpcode::kMapGuard:
39121cb0ef41Sopenharmony_ci        // Eliminate MapGuard nodes here.
39131cb0ef41Sopenharmony_ci        return VisitUnused<T>(node);
39141cb0ef41Sopenharmony_ci      case IrOpcode::kCheckMaps: {
39151cb0ef41Sopenharmony_ci        CheckMapsParameters const& p = CheckMapsParametersOf(node->op());
39161cb0ef41Sopenharmony_ci        return VisitUnop<T>(
39171cb0ef41Sopenharmony_ci            node, UseInfo::CheckedHeapObjectAsTaggedPointer(p.feedback()),
39181cb0ef41Sopenharmony_ci            MachineRepresentation::kNone);
39191cb0ef41Sopenharmony_ci      }
39201cb0ef41Sopenharmony_ci      case IrOpcode::kTransitionElementsKind: {
39211cb0ef41Sopenharmony_ci        return VisitUnop<T>(
39221cb0ef41Sopenharmony_ci            node, UseInfo::CheckedHeapObjectAsTaggedPointer(FeedbackSource()),
39231cb0ef41Sopenharmony_ci            MachineRepresentation::kNone);
39241cb0ef41Sopenharmony_ci      }
39251cb0ef41Sopenharmony_ci      case IrOpcode::kCompareMaps:
39261cb0ef41Sopenharmony_ci        return VisitUnop<T>(
39271cb0ef41Sopenharmony_ci            node, UseInfo::CheckedHeapObjectAsTaggedPointer(FeedbackSource()),
39281cb0ef41Sopenharmony_ci            MachineRepresentation::kBit);
39291cb0ef41Sopenharmony_ci      case IrOpcode::kEnsureWritableFastElements:
39301cb0ef41Sopenharmony_ci        return VisitBinop<T>(node, UseInfo::AnyTagged(),
39311cb0ef41Sopenharmony_ci                             MachineRepresentation::kTaggedPointer);
39321cb0ef41Sopenharmony_ci      case IrOpcode::kMaybeGrowFastElements: {
39331cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 0, UseInfo::AnyTagged());         // object
39341cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 1, UseInfo::AnyTagged());         // elements
39351cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 2, UseInfo::TruncatingWord32());  // index
39361cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 3, UseInfo::TruncatingWord32());  // length
39371cb0ef41Sopenharmony_ci        ProcessRemainingInputs<T>(node, 4);
39381cb0ef41Sopenharmony_ci        SetOutput<T>(node, MachineRepresentation::kTaggedPointer);
39391cb0ef41Sopenharmony_ci        return;
39401cb0ef41Sopenharmony_ci      }
39411cb0ef41Sopenharmony_ci
39421cb0ef41Sopenharmony_ci      case IrOpcode::kDateNow:
39431cb0ef41Sopenharmony_ci        VisitInputs<T>(node);
39441cb0ef41Sopenharmony_ci        return SetOutput<T>(node, MachineRepresentation::kTagged);
39451cb0ef41Sopenharmony_ci      case IrOpcode::kFrameState:
39461cb0ef41Sopenharmony_ci        return VisitFrameState<T>(FrameState{node});
39471cb0ef41Sopenharmony_ci      case IrOpcode::kStateValues:
39481cb0ef41Sopenharmony_ci        return VisitStateValues<T>(node);
39491cb0ef41Sopenharmony_ci      case IrOpcode::kObjectState:
39501cb0ef41Sopenharmony_ci        return VisitObjectState<T>(node);
39511cb0ef41Sopenharmony_ci      case IrOpcode::kObjectId:
39521cb0ef41Sopenharmony_ci        return SetOutput<T>(node, MachineRepresentation::kTaggedPointer);
39531cb0ef41Sopenharmony_ci
39541cb0ef41Sopenharmony_ci      case IrOpcode::kTypeGuard: {
39551cb0ef41Sopenharmony_ci        if (truncation.IsUnused()) return VisitUnused<T>(node);
39561cb0ef41Sopenharmony_ci
39571cb0ef41Sopenharmony_ci        // We just get rid of the sigma here, choosing the best representation
39581cb0ef41Sopenharmony_ci        // for the sigma's type.
39591cb0ef41Sopenharmony_ci        Type type = TypeOf(node);
39601cb0ef41Sopenharmony_ci        MachineRepresentation representation =
39611cb0ef41Sopenharmony_ci            GetOutputInfoForPhi(node, type, truncation);
39621cb0ef41Sopenharmony_ci
39631cb0ef41Sopenharmony_ci        // Here we pretend that the input has the sigma's type for the
39641cb0ef41Sopenharmony_ci        // conversion.
39651cb0ef41Sopenharmony_ci        UseInfo use(representation, truncation);
39661cb0ef41Sopenharmony_ci        if (propagate<T>()) {
39671cb0ef41Sopenharmony_ci          EnqueueInput<T>(node, 0, use);
39681cb0ef41Sopenharmony_ci        } else if (lower<T>()) {
39691cb0ef41Sopenharmony_ci          ConvertInput(node, 0, use, type);
39701cb0ef41Sopenharmony_ci        }
39711cb0ef41Sopenharmony_ci        ProcessRemainingInputs<T>(node, 1);
39721cb0ef41Sopenharmony_ci        SetOutput<T>(node, representation);
39731cb0ef41Sopenharmony_ci        return;
39741cb0ef41Sopenharmony_ci      }
39751cb0ef41Sopenharmony_ci
39761cb0ef41Sopenharmony_ci      case IrOpcode::kFoldConstant:
39771cb0ef41Sopenharmony_ci        VisitInputs<T>(node);
39781cb0ef41Sopenharmony_ci        return SetOutput<T>(node, MachineRepresentation::kTaggedPointer);
39791cb0ef41Sopenharmony_ci
39801cb0ef41Sopenharmony_ci      case IrOpcode::kFinishRegion:
39811cb0ef41Sopenharmony_ci        VisitInputs<T>(node);
39821cb0ef41Sopenharmony_ci        // Assume the output is tagged pointer.
39831cb0ef41Sopenharmony_ci        return SetOutput<T>(node, MachineRepresentation::kTaggedPointer);
39841cb0ef41Sopenharmony_ci
39851cb0ef41Sopenharmony_ci      case IrOpcode::kReturn:
39861cb0ef41Sopenharmony_ci        VisitReturn<T>(node);
39871cb0ef41Sopenharmony_ci        // Assume the output is tagged.
39881cb0ef41Sopenharmony_ci        return SetOutput<T>(node, MachineRepresentation::kTagged);
39891cb0ef41Sopenharmony_ci
39901cb0ef41Sopenharmony_ci      case IrOpcode::kFindOrderedHashMapEntry: {
39911cb0ef41Sopenharmony_ci        Type const key_type = TypeOf(node->InputAt(1));
39921cb0ef41Sopenharmony_ci        if (key_type.Is(Type::Signed32OrMinusZero())) {
39931cb0ef41Sopenharmony_ci          VisitBinop<T>(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(),
39941cb0ef41Sopenharmony_ci                        MachineType::PointerRepresentation());
39951cb0ef41Sopenharmony_ci          if (lower<T>()) {
39961cb0ef41Sopenharmony_ci            ChangeOp(
39971cb0ef41Sopenharmony_ci                node,
39981cb0ef41Sopenharmony_ci                lowering->simplified()->FindOrderedHashMapEntryForInt32Key());
39991cb0ef41Sopenharmony_ci          }
40001cb0ef41Sopenharmony_ci        } else {
40011cb0ef41Sopenharmony_ci          VisitBinop<T>(node, UseInfo::AnyTagged(),
40021cb0ef41Sopenharmony_ci                        MachineRepresentation::kTaggedSigned);
40031cb0ef41Sopenharmony_ci        }
40041cb0ef41Sopenharmony_ci        return;
40051cb0ef41Sopenharmony_ci      }
40061cb0ef41Sopenharmony_ci
40071cb0ef41Sopenharmony_ci      case IrOpcode::kFastApiCall: {
40081cb0ef41Sopenharmony_ci        VisitFastApiCall<T>(node, lowering);
40091cb0ef41Sopenharmony_ci        return;
40101cb0ef41Sopenharmony_ci      }
40111cb0ef41Sopenharmony_ci
40121cb0ef41Sopenharmony_ci      // Operators with all inputs tagged and no or tagged output have uniform
40131cb0ef41Sopenharmony_ci      // handling.
40141cb0ef41Sopenharmony_ci      case IrOpcode::kEnd:
40151cb0ef41Sopenharmony_ci      case IrOpcode::kIfSuccess:
40161cb0ef41Sopenharmony_ci      case IrOpcode::kIfException:
40171cb0ef41Sopenharmony_ci      case IrOpcode::kIfTrue:
40181cb0ef41Sopenharmony_ci      case IrOpcode::kIfFalse:
40191cb0ef41Sopenharmony_ci      case IrOpcode::kIfValue:
40201cb0ef41Sopenharmony_ci      case IrOpcode::kIfDefault:
40211cb0ef41Sopenharmony_ci      case IrOpcode::kDeoptimize:
40221cb0ef41Sopenharmony_ci      case IrOpcode::kEffectPhi:
40231cb0ef41Sopenharmony_ci      case IrOpcode::kTerminate:
40241cb0ef41Sopenharmony_ci      case IrOpcode::kCheckpoint:
40251cb0ef41Sopenharmony_ci      case IrOpcode::kLoop:
40261cb0ef41Sopenharmony_ci      case IrOpcode::kMerge:
40271cb0ef41Sopenharmony_ci      case IrOpcode::kThrow:
40281cb0ef41Sopenharmony_ci      case IrOpcode::kBeginRegion:
40291cb0ef41Sopenharmony_ci      case IrOpcode::kProjection:
40301cb0ef41Sopenharmony_ci      case IrOpcode::kOsrValue:
40311cb0ef41Sopenharmony_ci      case IrOpcode::kArgumentsElementsState:
40321cb0ef41Sopenharmony_ci      case IrOpcode::kArgumentsLengthState:
40331cb0ef41Sopenharmony_ci      case IrOpcode::kUnreachable:
40341cb0ef41Sopenharmony_ci      case IrOpcode::kRuntimeAbort:
40351cb0ef41Sopenharmony_ci// All JavaScript operators except JSToNumber, JSToNumberConvertBigInt,
40361cb0ef41Sopenharmony_ci// kJSToNumeric and JSWasmCall have uniform handling.
40371cb0ef41Sopenharmony_ci#define OPCODE_CASE(name, ...) case IrOpcode::k##name:
40381cb0ef41Sopenharmony_ci        JS_SIMPLE_BINOP_LIST(OPCODE_CASE)
40391cb0ef41Sopenharmony_ci        JS_OBJECT_OP_LIST(OPCODE_CASE)
40401cb0ef41Sopenharmony_ci        JS_CONTEXT_OP_LIST(OPCODE_CASE)
40411cb0ef41Sopenharmony_ci        JS_OTHER_OP_LIST(OPCODE_CASE)
40421cb0ef41Sopenharmony_ci#undef OPCODE_CASE
40431cb0ef41Sopenharmony_ci      case IrOpcode::kJSBitwiseNot:
40441cb0ef41Sopenharmony_ci      case IrOpcode::kJSDecrement:
40451cb0ef41Sopenharmony_ci      case IrOpcode::kJSIncrement:
40461cb0ef41Sopenharmony_ci      case IrOpcode::kJSNegate:
40471cb0ef41Sopenharmony_ci      case IrOpcode::kJSToLength:
40481cb0ef41Sopenharmony_ci      case IrOpcode::kJSToName:
40491cb0ef41Sopenharmony_ci      case IrOpcode::kJSToObject:
40501cb0ef41Sopenharmony_ci      case IrOpcode::kJSToString:
40511cb0ef41Sopenharmony_ci      case IrOpcode::kJSParseInt:
40521cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
40531cb0ef41Sopenharmony_ci        if (node->opcode() == IrOpcode::kJSWasmCall) {
40541cb0ef41Sopenharmony_ci          return VisitJSWasmCall<T>(node, lowering);
40551cb0ef41Sopenharmony_ci        }
40561cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
40571cb0ef41Sopenharmony_ci        VisitInputs<T>(node);
40581cb0ef41Sopenharmony_ci        // Assume the output is tagged.
40591cb0ef41Sopenharmony_ci        return SetOutput<T>(node, MachineRepresentation::kTagged);
40601cb0ef41Sopenharmony_ci      case IrOpcode::kDeadValue:
40611cb0ef41Sopenharmony_ci        ProcessInput<T>(node, 0, UseInfo::Any());
40621cb0ef41Sopenharmony_ci        return SetOutput<T>(node, MachineRepresentation::kNone);
40631cb0ef41Sopenharmony_ci      case IrOpcode::kStaticAssert:
40641cb0ef41Sopenharmony_ci        DCHECK(TypeOf(node->InputAt(0)).Is(Type::Boolean()));
40651cb0ef41Sopenharmony_ci        return VisitUnop<T>(node, UseInfo::Bool(),
40661cb0ef41Sopenharmony_ci                            MachineRepresentation::kTagged);
40671cb0ef41Sopenharmony_ci      case IrOpcode::kAssertType:
40681cb0ef41Sopenharmony_ci        return VisitUnop<T>(node, UseInfo::AnyTagged(),
40691cb0ef41Sopenharmony_ci                            MachineRepresentation::kTagged);
40701cb0ef41Sopenharmony_ci      case IrOpcode::kVerifyType: {
40711cb0ef41Sopenharmony_ci        Type inputType = TypeOf(node->InputAt(0));
40721cb0ef41Sopenharmony_ci        VisitUnop<T>(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged,
40731cb0ef41Sopenharmony_ci                     inputType);
40741cb0ef41Sopenharmony_ci        if (lower<T>()) {
40751cb0ef41Sopenharmony_ci          if (inputType.CanBeAsserted()) {
40761cb0ef41Sopenharmony_ci            ChangeOp(node, simplified()->AssertType(inputType));
40771cb0ef41Sopenharmony_ci          } else {
40781cb0ef41Sopenharmony_ci            if (!FLAG_fuzzing) {
40791cb0ef41Sopenharmony_ci#ifdef DEBUG
40801cb0ef41Sopenharmony_ci              inputType.Print();
40811cb0ef41Sopenharmony_ci#endif
40821cb0ef41Sopenharmony_ci              FATAL("%%VerifyType: unsupported type");
40831cb0ef41Sopenharmony_ci            }
40841cb0ef41Sopenharmony_ci            DeferReplacement(node, node->InputAt(0));
40851cb0ef41Sopenharmony_ci          }
40861cb0ef41Sopenharmony_ci        }
40871cb0ef41Sopenharmony_ci        return;
40881cb0ef41Sopenharmony_ci      }
40891cb0ef41Sopenharmony_ci
40901cb0ef41Sopenharmony_ci      default:
40911cb0ef41Sopenharmony_ci        FATAL(
40921cb0ef41Sopenharmony_ci            "Representation inference: unsupported opcode %i (%s), node #%i\n.",
40931cb0ef41Sopenharmony_ci            node->opcode(), node->op()->mnemonic(), node->id());
40941cb0ef41Sopenharmony_ci        break;
40951cb0ef41Sopenharmony_ci    }
40961cb0ef41Sopenharmony_ci    UNREACHABLE();
40971cb0ef41Sopenharmony_ci  }
40981cb0ef41Sopenharmony_ci
40991cb0ef41Sopenharmony_ci  void DisconnectFromEffectAndControl(Node* node) {
41001cb0ef41Sopenharmony_ci    if (node->op()->EffectInputCount() == 1) {
41011cb0ef41Sopenharmony_ci      Node* control = NodeProperties::GetControlInput(node);
41021cb0ef41Sopenharmony_ci      Node* effect = NodeProperties::GetEffectInput(node);
41031cb0ef41Sopenharmony_ci      ReplaceEffectControlUses(node, effect, control);
41041cb0ef41Sopenharmony_ci    } else {
41051cb0ef41Sopenharmony_ci      DCHECK_EQ(0, node->op()->EffectInputCount());
41061cb0ef41Sopenharmony_ci      DCHECK_EQ(0, node->op()->ControlOutputCount());
41071cb0ef41Sopenharmony_ci      DCHECK_EQ(0, node->op()->EffectOutputCount());
41081cb0ef41Sopenharmony_ci    }
41091cb0ef41Sopenharmony_ci  }
41101cb0ef41Sopenharmony_ci
41111cb0ef41Sopenharmony_ci  void DeferReplacement(Node* node, Node* replacement) {
41121cb0ef41Sopenharmony_ci    TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(),
41131cb0ef41Sopenharmony_ci          node->op()->mnemonic(), replacement->id(),
41141cb0ef41Sopenharmony_ci          replacement->op()->mnemonic());
41151cb0ef41Sopenharmony_ci
41161cb0ef41Sopenharmony_ci    DisconnectFromEffectAndControl(node);
41171cb0ef41Sopenharmony_ci    node->NullAllInputs();  // Node is now dead.
41181cb0ef41Sopenharmony_ci
41191cb0ef41Sopenharmony_ci    replacements_.push_back(node);
41201cb0ef41Sopenharmony_ci    replacements_.push_back(replacement);
41211cb0ef41Sopenharmony_ci
41221cb0ef41Sopenharmony_ci    NotifyNodeReplaced(node, replacement);
41231cb0ef41Sopenharmony_ci  }
41241cb0ef41Sopenharmony_ci
41251cb0ef41Sopenharmony_ci  Node* InsertTypeOverrideForVerifier(const Type& type, Node* node) {
41261cb0ef41Sopenharmony_ci    if (verification_enabled()) {
41271cb0ef41Sopenharmony_ci      DCHECK(!type.IsInvalid());
41281cb0ef41Sopenharmony_ci      node = graph()->NewNode(common()->SLVerifierHint(nullptr, type), node);
41291cb0ef41Sopenharmony_ci      verifier_->RecordHint(node);
41301cb0ef41Sopenharmony_ci    }
41311cb0ef41Sopenharmony_ci    return node;
41321cb0ef41Sopenharmony_ci  }
41331cb0ef41Sopenharmony_ci
41341cb0ef41Sopenharmony_ci  void ChangeToSemanticsHintForVerifier(Node* node, const Operator* semantics) {
41351cb0ef41Sopenharmony_ci    DCHECK_EQ(node->op()->ValueInputCount(), 1);
41361cb0ef41Sopenharmony_ci    DCHECK_EQ(node->op()->EffectInputCount(), 0);
41371cb0ef41Sopenharmony_ci    DCHECK_EQ(node->op()->ControlInputCount(), 0);
41381cb0ef41Sopenharmony_ci    if (verification_enabled()) {
41391cb0ef41Sopenharmony_ci      ChangeOp(node, common()->SLVerifierHint(semantics, base::nullopt));
41401cb0ef41Sopenharmony_ci      verifier_->RecordHint(node);
41411cb0ef41Sopenharmony_ci    } else {
41421cb0ef41Sopenharmony_ci      DeferReplacement(node, node->InputAt(0));
41431cb0ef41Sopenharmony_ci    }
41441cb0ef41Sopenharmony_ci  }
41451cb0ef41Sopenharmony_ci
41461cb0ef41Sopenharmony_ci private:
41471cb0ef41Sopenharmony_ci  void ChangeOp(Node* node, const Operator* new_op) {
41481cb0ef41Sopenharmony_ci    compiler::NodeProperties::ChangeOp(node, new_op);
41491cb0ef41Sopenharmony_ci
41501cb0ef41Sopenharmony_ci    if (V8_UNLIKELY(observe_node_manager_ != nullptr))
41511cb0ef41Sopenharmony_ci      observe_node_manager_->OnNodeChanged(kSimplifiedLoweringReducerName, node,
41521cb0ef41Sopenharmony_ci                                           node);
41531cb0ef41Sopenharmony_ci  }
41541cb0ef41Sopenharmony_ci
41551cb0ef41Sopenharmony_ci  void NotifyNodeReplaced(Node* node, Node* replacement) {
41561cb0ef41Sopenharmony_ci    if (V8_UNLIKELY(observe_node_manager_ != nullptr))
41571cb0ef41Sopenharmony_ci      observe_node_manager_->OnNodeChanged(kSimplifiedLoweringReducerName, node,
41581cb0ef41Sopenharmony_ci                                           replacement);
41591cb0ef41Sopenharmony_ci  }
41601cb0ef41Sopenharmony_ci
41611cb0ef41Sopenharmony_ci  JSGraph* jsgraph_;
41621cb0ef41Sopenharmony_ci  JSHeapBroker* broker_;
41631cb0ef41Sopenharmony_ci  Zone* zone_;                      // Temporary zone.
41641cb0ef41Sopenharmony_ci  // Map from node to its uses that might need to be revisited.
41651cb0ef41Sopenharmony_ci  ZoneMap<Node*, ZoneVector<Node*>> might_need_revisit_;
41661cb0ef41Sopenharmony_ci  size_t count_;                    // number of nodes in the graph
41671cb0ef41Sopenharmony_ci  ZoneVector<NodeInfo> info_;       // node id -> usage information
41681cb0ef41Sopenharmony_ci#ifdef DEBUG
41691cb0ef41Sopenharmony_ci  ZoneVector<InputUseInfos> node_input_use_infos_;  // Debug information about
41701cb0ef41Sopenharmony_ci                                                    // requirements on inputs.
41711cb0ef41Sopenharmony_ci#endif                                              // DEBUG
41721cb0ef41Sopenharmony_ci  NodeVector replacements_;         // replacements to be done after lowering
41731cb0ef41Sopenharmony_ci  RepresentationChanger* changer_;  // for inserting representation changes
41741cb0ef41Sopenharmony_ci  ZoneQueue<Node*> revisit_queue_;  // Queue for revisiting nodes.
41751cb0ef41Sopenharmony_ci
41761cb0ef41Sopenharmony_ci  struct NodeState {
41771cb0ef41Sopenharmony_ci    Node* node;
41781cb0ef41Sopenharmony_ci    int input_index;
41791cb0ef41Sopenharmony_ci  };
41801cb0ef41Sopenharmony_ci  NodeVector traversal_nodes_;  // Order in which to traverse the nodes.
41811cb0ef41Sopenharmony_ci  // TODO(danno): RepresentationSelector shouldn't know anything about the
41821cb0ef41Sopenharmony_ci  // source positions table, but must for now since there currently is no other
41831cb0ef41Sopenharmony_ci  // way to pass down source position information to nodes created during
41841cb0ef41Sopenharmony_ci  // lowering. Once this phase becomes a vanilla reducer, it should get source
41851cb0ef41Sopenharmony_ci  // position information via the SourcePositionWrapper like all other reducers.
41861cb0ef41Sopenharmony_ci  SourcePositionTable* source_positions_;
41871cb0ef41Sopenharmony_ci  NodeOriginTable* node_origins_;
41881cb0ef41Sopenharmony_ci  TypeCache const* type_cache_;
41891cb0ef41Sopenharmony_ci  OperationTyper op_typer_;  // helper for the feedback typer
41901cb0ef41Sopenharmony_ci  TickCounter* const tick_counter_;
41911cb0ef41Sopenharmony_ci  Linkage* const linkage_;
41921cb0ef41Sopenharmony_ci  ObserveNodeManager* const observe_node_manager_;
41931cb0ef41Sopenharmony_ci  SimplifiedLoweringVerifier* verifier_;  // Used to verify output graph.
41941cb0ef41Sopenharmony_ci
41951cb0ef41Sopenharmony_ci  NodeInfo* GetInfo(Node* node) {
41961cb0ef41Sopenharmony_ci    DCHECK(node->id() < count_);
41971cb0ef41Sopenharmony_ci    return &info_[node->id()];
41981cb0ef41Sopenharmony_ci  }
41991cb0ef41Sopenharmony_ci  Zone* zone() { return zone_; }
42001cb0ef41Sopenharmony_ci  Zone* graph_zone() { return jsgraph_->zone(); }
42011cb0ef41Sopenharmony_ci  Linkage* linkage() { return linkage_; }
42021cb0ef41Sopenharmony_ci};
42031cb0ef41Sopenharmony_ci
42041cb0ef41Sopenharmony_ci// Template specializations
42051cb0ef41Sopenharmony_ci
42061cb0ef41Sopenharmony_ci// Enqueue {use_node}'s {index} input if the {use_info} contains new information
42071cb0ef41Sopenharmony_ci// for that input node.
42081cb0ef41Sopenharmony_citemplate <>
42091cb0ef41Sopenharmony_civoid RepresentationSelector::EnqueueInput<PROPAGATE>(Node* use_node, int index,
42101cb0ef41Sopenharmony_ci                                                     UseInfo use_info) {
42111cb0ef41Sopenharmony_ci  Node* node = use_node->InputAt(index);
42121cb0ef41Sopenharmony_ci  NodeInfo* info = GetInfo(node);
42131cb0ef41Sopenharmony_ci#ifdef DEBUG
42141cb0ef41Sopenharmony_ci  // Check monotonicity of input requirements.
42151cb0ef41Sopenharmony_ci  node_input_use_infos_[use_node->id()].SetAndCheckInput(use_node, index,
42161cb0ef41Sopenharmony_ci                                                         use_info);
42171cb0ef41Sopenharmony_ci#endif  // DEBUG
42181cb0ef41Sopenharmony_ci  if (info->unvisited()) {
42191cb0ef41Sopenharmony_ci    info->AddUse(use_info);
42201cb0ef41Sopenharmony_ci    TRACE("  initial #%i: %s\n", node->id(), info->truncation().description());
42211cb0ef41Sopenharmony_ci    return;
42221cb0ef41Sopenharmony_ci  }
42231cb0ef41Sopenharmony_ci  TRACE("   queue #%i?: %s\n", node->id(), info->truncation().description());
42241cb0ef41Sopenharmony_ci  if (info->AddUse(use_info)) {
42251cb0ef41Sopenharmony_ci    // New usage information for the node is available.
42261cb0ef41Sopenharmony_ci    if (!info->queued()) {
42271cb0ef41Sopenharmony_ci      DCHECK(info->visited());
42281cb0ef41Sopenharmony_ci      revisit_queue_.push(node);
42291cb0ef41Sopenharmony_ci      info->set_queued();
42301cb0ef41Sopenharmony_ci      TRACE("   added: %s\n", info->truncation().description());
42311cb0ef41Sopenharmony_ci    } else {
42321cb0ef41Sopenharmony_ci      TRACE(" inqueue: %s\n", info->truncation().description());
42331cb0ef41Sopenharmony_ci    }
42341cb0ef41Sopenharmony_ci  }
42351cb0ef41Sopenharmony_ci}
42361cb0ef41Sopenharmony_ci
42371cb0ef41Sopenharmony_citemplate <>
42381cb0ef41Sopenharmony_civoid RepresentationSelector::SetOutput<PROPAGATE>(
42391cb0ef41Sopenharmony_ci    Node* node, MachineRepresentation representation, Type restriction_type) {
42401cb0ef41Sopenharmony_ci  NodeInfo* const info = GetInfo(node);
42411cb0ef41Sopenharmony_ci  info->set_restriction_type(restriction_type);
42421cb0ef41Sopenharmony_ci}
42431cb0ef41Sopenharmony_ci
42441cb0ef41Sopenharmony_citemplate <>
42451cb0ef41Sopenharmony_civoid RepresentationSelector::SetOutput<RETYPE>(
42461cb0ef41Sopenharmony_ci    Node* node, MachineRepresentation representation, Type restriction_type) {
42471cb0ef41Sopenharmony_ci  NodeInfo* const info = GetInfo(node);
42481cb0ef41Sopenharmony_ci  DCHECK(restriction_type.Is(info->restriction_type()));
42491cb0ef41Sopenharmony_ci  info->set_output(representation);
42501cb0ef41Sopenharmony_ci}
42511cb0ef41Sopenharmony_ci
42521cb0ef41Sopenharmony_citemplate <>
42531cb0ef41Sopenharmony_civoid RepresentationSelector::SetOutput<LOWER>(
42541cb0ef41Sopenharmony_ci    Node* node, MachineRepresentation representation, Type restriction_type) {
42551cb0ef41Sopenharmony_ci  NodeInfo* const info = GetInfo(node);
42561cb0ef41Sopenharmony_ci  DCHECK_EQ(info->representation(), representation);
42571cb0ef41Sopenharmony_ci  DCHECK(restriction_type.Is(info->restriction_type()));
42581cb0ef41Sopenharmony_ci  USE(info);
42591cb0ef41Sopenharmony_ci}
42601cb0ef41Sopenharmony_ci
42611cb0ef41Sopenharmony_citemplate <>
42621cb0ef41Sopenharmony_civoid RepresentationSelector::ProcessInput<PROPAGATE>(Node* node, int index,
42631cb0ef41Sopenharmony_ci                                                     UseInfo use) {
42641cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(use.type_check() != TypeCheckKind::kNone,
42651cb0ef41Sopenharmony_ci                 !node->op()->HasProperty(Operator::kNoDeopt) &&
42661cb0ef41Sopenharmony_ci                     node->op()->EffectInputCount() > 0);
42671cb0ef41Sopenharmony_ci  EnqueueInput<PROPAGATE>(node, index, use);
42681cb0ef41Sopenharmony_ci}
42691cb0ef41Sopenharmony_ci
42701cb0ef41Sopenharmony_citemplate <>
42711cb0ef41Sopenharmony_civoid RepresentationSelector::ProcessInput<RETYPE>(Node* node, int index,
42721cb0ef41Sopenharmony_ci                                                  UseInfo use) {
42731cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(use.type_check() != TypeCheckKind::kNone,
42741cb0ef41Sopenharmony_ci                 !node->op()->HasProperty(Operator::kNoDeopt) &&
42751cb0ef41Sopenharmony_ci                     node->op()->EffectInputCount() > 0);
42761cb0ef41Sopenharmony_ci}
42771cb0ef41Sopenharmony_ci
42781cb0ef41Sopenharmony_citemplate <>
42791cb0ef41Sopenharmony_civoid RepresentationSelector::ProcessInput<LOWER>(Node* node, int index,
42801cb0ef41Sopenharmony_ci                                                 UseInfo use) {
42811cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(use.type_check() != TypeCheckKind::kNone,
42821cb0ef41Sopenharmony_ci                 !node->op()->HasProperty(Operator::kNoDeopt) &&
42831cb0ef41Sopenharmony_ci                     node->op()->EffectInputCount() > 0);
42841cb0ef41Sopenharmony_ci  ConvertInput(node, index, use);
42851cb0ef41Sopenharmony_ci}
42861cb0ef41Sopenharmony_ci
42871cb0ef41Sopenharmony_citemplate <>
42881cb0ef41Sopenharmony_civoid RepresentationSelector::ProcessRemainingInputs<PROPAGATE>(Node* node,
42891cb0ef41Sopenharmony_ci                                                               int index) {
42901cb0ef41Sopenharmony_ci  DCHECK_GE(index, NodeProperties::PastContextIndex(node));
42911cb0ef41Sopenharmony_ci
42921cb0ef41Sopenharmony_ci  // Enqueue other inputs (effects, control).
42931cb0ef41Sopenharmony_ci  for (int i = std::max(index, NodeProperties::FirstEffectIndex(node));
42941cb0ef41Sopenharmony_ci       i < node->InputCount(); ++i) {
42951cb0ef41Sopenharmony_ci    EnqueueInput<PROPAGATE>(node, i);
42961cb0ef41Sopenharmony_ci  }
42971cb0ef41Sopenharmony_ci}
42981cb0ef41Sopenharmony_ci
42991cb0ef41Sopenharmony_ci// The default, most general visitation case. For {node}, process all value,
43001cb0ef41Sopenharmony_ci// context, frame state, effect, and control inputs, assuming that value
43011cb0ef41Sopenharmony_ci// inputs should have {kRepTagged} representation and can observe all output
43021cb0ef41Sopenharmony_ci// values {kTypeAny}.
43031cb0ef41Sopenharmony_citemplate <>
43041cb0ef41Sopenharmony_civoid RepresentationSelector::VisitInputs<PROPAGATE>(Node* node) {
43051cb0ef41Sopenharmony_ci  int first_effect_index = NodeProperties::FirstEffectIndex(node);
43061cb0ef41Sopenharmony_ci  // Visit value, context and frame state inputs as tagged.
43071cb0ef41Sopenharmony_ci  for (int i = 0; i < first_effect_index; i++) {
43081cb0ef41Sopenharmony_ci    ProcessInput<PROPAGATE>(node, i, UseInfo::AnyTagged());
43091cb0ef41Sopenharmony_ci  }
43101cb0ef41Sopenharmony_ci  // Only enqueue other inputs (effects, control).
43111cb0ef41Sopenharmony_ci  for (int i = first_effect_index; i < node->InputCount(); i++) {
43121cb0ef41Sopenharmony_ci    EnqueueInput<PROPAGATE>(node, i);
43131cb0ef41Sopenharmony_ci  }
43141cb0ef41Sopenharmony_ci}
43151cb0ef41Sopenharmony_ci
43161cb0ef41Sopenharmony_citemplate <>
43171cb0ef41Sopenharmony_civoid RepresentationSelector::VisitInputs<LOWER>(Node* node) {
43181cb0ef41Sopenharmony_ci  int first_effect_index = NodeProperties::FirstEffectIndex(node);
43191cb0ef41Sopenharmony_ci  // Visit value, context and frame state inputs as tagged.
43201cb0ef41Sopenharmony_ci  for (int i = 0; i < first_effect_index; i++) {
43211cb0ef41Sopenharmony_ci    ProcessInput<LOWER>(node, i, UseInfo::AnyTagged());
43221cb0ef41Sopenharmony_ci  }
43231cb0ef41Sopenharmony_ci}
43241cb0ef41Sopenharmony_ci
43251cb0ef41Sopenharmony_citemplate <>
43261cb0ef41Sopenharmony_civoid RepresentationSelector::InsertUnreachableIfNecessary<LOWER>(Node* node) {
43271cb0ef41Sopenharmony_ci  // If the node is effectful and it produces an impossible value, then we
43281cb0ef41Sopenharmony_ci  // insert Unreachable node after it.
43291cb0ef41Sopenharmony_ci  if (node->op()->ValueOutputCount() > 0 &&
43301cb0ef41Sopenharmony_ci      node->op()->EffectOutputCount() > 0 &&
43311cb0ef41Sopenharmony_ci      node->opcode() != IrOpcode::kUnreachable && TypeOf(node).IsNone()) {
43321cb0ef41Sopenharmony_ci    Node* control = (node->op()->ControlOutputCount() == 0)
43331cb0ef41Sopenharmony_ci                        ? NodeProperties::GetControlInput(node, 0)
43341cb0ef41Sopenharmony_ci                        : NodeProperties::FindSuccessfulControlProjection(node);
43351cb0ef41Sopenharmony_ci
43361cb0ef41Sopenharmony_ci    Node* unreachable =
43371cb0ef41Sopenharmony_ci        graph()->NewNode(common()->Unreachable(), node, control);
43381cb0ef41Sopenharmony_ci
43391cb0ef41Sopenharmony_ci    // Insert unreachable node and replace all the effect uses of the {node}
43401cb0ef41Sopenharmony_ci    // with the new unreachable node.
43411cb0ef41Sopenharmony_ci    for (Edge edge : node->use_edges()) {
43421cb0ef41Sopenharmony_ci      if (!NodeProperties::IsEffectEdge(edge)) continue;
43431cb0ef41Sopenharmony_ci      // Make sure to not overwrite the unreachable node's input. That would
43441cb0ef41Sopenharmony_ci      // create a cycle.
43451cb0ef41Sopenharmony_ci      if (edge.from() == unreachable) continue;
43461cb0ef41Sopenharmony_ci      // Avoid messing up the exceptional path.
43471cb0ef41Sopenharmony_ci      if (edge.from()->opcode() == IrOpcode::kIfException) {
43481cb0ef41Sopenharmony_ci        DCHECK(!node->op()->HasProperty(Operator::kNoThrow));
43491cb0ef41Sopenharmony_ci        DCHECK_EQ(NodeProperties::GetControlInput(edge.from()), node);
43501cb0ef41Sopenharmony_ci        continue;
43511cb0ef41Sopenharmony_ci      }
43521cb0ef41Sopenharmony_ci
43531cb0ef41Sopenharmony_ci      edge.UpdateTo(unreachable);
43541cb0ef41Sopenharmony_ci    }
43551cb0ef41Sopenharmony_ci  }
43561cb0ef41Sopenharmony_ci}
43571cb0ef41Sopenharmony_ci
43581cb0ef41Sopenharmony_ciSimplifiedLowering::SimplifiedLowering(
43591cb0ef41Sopenharmony_ci    JSGraph* jsgraph, JSHeapBroker* broker, Zone* zone,
43601cb0ef41Sopenharmony_ci    SourcePositionTable* source_positions, NodeOriginTable* node_origins,
43611cb0ef41Sopenharmony_ci    TickCounter* tick_counter, Linkage* linkage, OptimizedCompilationInfo* info,
43621cb0ef41Sopenharmony_ci    ObserveNodeManager* observe_node_manager)
43631cb0ef41Sopenharmony_ci    : jsgraph_(jsgraph),
43641cb0ef41Sopenharmony_ci      broker_(broker),
43651cb0ef41Sopenharmony_ci      zone_(zone),
43661cb0ef41Sopenharmony_ci      type_cache_(TypeCache::Get()),
43671cb0ef41Sopenharmony_ci      source_positions_(source_positions),
43681cb0ef41Sopenharmony_ci      node_origins_(node_origins),
43691cb0ef41Sopenharmony_ci      tick_counter_(tick_counter),
43701cb0ef41Sopenharmony_ci      linkage_(linkage),
43711cb0ef41Sopenharmony_ci      info_(info),
43721cb0ef41Sopenharmony_ci      observe_node_manager_(observe_node_manager) {}
43731cb0ef41Sopenharmony_ci
43741cb0ef41Sopenharmony_civoid SimplifiedLowering::LowerAllNodes() {
43751cb0ef41Sopenharmony_ci  SimplifiedLoweringVerifier* verifier = nullptr;
43761cb0ef41Sopenharmony_ci  if (FLAG_verify_simplified_lowering) {
43771cb0ef41Sopenharmony_ci    verifier = zone_->New<SimplifiedLoweringVerifier>(zone_, graph());
43781cb0ef41Sopenharmony_ci  }
43791cb0ef41Sopenharmony_ci  RepresentationChanger changer(jsgraph(), broker_, verifier);
43801cb0ef41Sopenharmony_ci  RepresentationSelector selector(
43811cb0ef41Sopenharmony_ci      jsgraph(), broker_, zone_, &changer, source_positions_, node_origins_,
43821cb0ef41Sopenharmony_ci      tick_counter_, linkage_, observe_node_manager_, verifier);
43831cb0ef41Sopenharmony_ci  selector.Run(this);
43841cb0ef41Sopenharmony_ci}
43851cb0ef41Sopenharmony_ci
43861cb0ef41Sopenharmony_civoid SimplifiedLowering::DoJSToNumberOrNumericTruncatesToFloat64(
43871cb0ef41Sopenharmony_ci    Node* node, RepresentationSelector* selector) {
43881cb0ef41Sopenharmony_ci  DCHECK(node->opcode() == IrOpcode::kJSToNumber ||
43891cb0ef41Sopenharmony_ci         node->opcode() == IrOpcode::kJSToNumberConvertBigInt ||
43901cb0ef41Sopenharmony_ci         node->opcode() == IrOpcode::kJSToNumeric);
43911cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
43921cb0ef41Sopenharmony_ci  Node* context = node->InputAt(1);
43931cb0ef41Sopenharmony_ci  Node* frame_state = node->InputAt(2);
43941cb0ef41Sopenharmony_ci  Node* effect = node->InputAt(3);
43951cb0ef41Sopenharmony_ci  Node* control = node->InputAt(4);
43961cb0ef41Sopenharmony_ci
43971cb0ef41Sopenharmony_ci  Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), value);
43981cb0ef41Sopenharmony_ci  Node* branch0 =
43991cb0ef41Sopenharmony_ci      graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
44001cb0ef41Sopenharmony_ci
44011cb0ef41Sopenharmony_ci  Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
44021cb0ef41Sopenharmony_ci  Node* etrue0 = effect;
44031cb0ef41Sopenharmony_ci  Node* vtrue0;
44041cb0ef41Sopenharmony_ci  {
44051cb0ef41Sopenharmony_ci    vtrue0 = graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), value);
44061cb0ef41Sopenharmony_ci    vtrue0 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue0);
44071cb0ef41Sopenharmony_ci  }
44081cb0ef41Sopenharmony_ci
44091cb0ef41Sopenharmony_ci  Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
44101cb0ef41Sopenharmony_ci  Node* efalse0 = effect;
44111cb0ef41Sopenharmony_ci  Node* vfalse0;
44121cb0ef41Sopenharmony_ci  {
44131cb0ef41Sopenharmony_ci    Operator const* op =
44141cb0ef41Sopenharmony_ci        node->opcode() == IrOpcode::kJSToNumber
44151cb0ef41Sopenharmony_ci            ? (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
44161cb0ef41Sopenharmony_ci                   ? ToNumberConvertBigIntOperator()
44171cb0ef41Sopenharmony_ci                   : ToNumberOperator())
44181cb0ef41Sopenharmony_ci            : ToNumericOperator();
44191cb0ef41Sopenharmony_ci    Node* code = node->opcode() == IrOpcode::kJSToNumber
44201cb0ef41Sopenharmony_ci                     ? ToNumberCode()
44211cb0ef41Sopenharmony_ci                     : (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
44221cb0ef41Sopenharmony_ci                            ? ToNumberConvertBigIntCode()
44231cb0ef41Sopenharmony_ci                            : ToNumericCode());
44241cb0ef41Sopenharmony_ci    vfalse0 = efalse0 = if_false0 = graph()->NewNode(
44251cb0ef41Sopenharmony_ci        op, code, value, context, frame_state, efalse0, if_false0);
44261cb0ef41Sopenharmony_ci
44271cb0ef41Sopenharmony_ci    // Update potential {IfException} uses of {node} to point to the above
44281cb0ef41Sopenharmony_ci    // stub call node instead.
44291cb0ef41Sopenharmony_ci    Node* on_exception = nullptr;
44301cb0ef41Sopenharmony_ci    if (NodeProperties::IsExceptionalCall(node, &on_exception)) {
44311cb0ef41Sopenharmony_ci      NodeProperties::ReplaceControlInput(on_exception, vfalse0);
44321cb0ef41Sopenharmony_ci      NodeProperties::ReplaceEffectInput(on_exception, efalse0);
44331cb0ef41Sopenharmony_ci      if_false0 = graph()->NewNode(common()->IfSuccess(), vfalse0);
44341cb0ef41Sopenharmony_ci    }
44351cb0ef41Sopenharmony_ci
44361cb0ef41Sopenharmony_ci    Node* check1 = graph()->NewNode(simplified()->ObjectIsSmi(), vfalse0);
44371cb0ef41Sopenharmony_ci    Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
44381cb0ef41Sopenharmony_ci
44391cb0ef41Sopenharmony_ci    Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
44401cb0ef41Sopenharmony_ci    Node* etrue1 = efalse0;
44411cb0ef41Sopenharmony_ci    Node* vtrue1;
44421cb0ef41Sopenharmony_ci    {
44431cb0ef41Sopenharmony_ci      vtrue1 =
44441cb0ef41Sopenharmony_ci          graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), vfalse0);
44451cb0ef41Sopenharmony_ci      vtrue1 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue1);
44461cb0ef41Sopenharmony_ci    }
44471cb0ef41Sopenharmony_ci
44481cb0ef41Sopenharmony_ci    Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
44491cb0ef41Sopenharmony_ci    Node* efalse1 = efalse0;
44501cb0ef41Sopenharmony_ci    Node* vfalse1;
44511cb0ef41Sopenharmony_ci    {
44521cb0ef41Sopenharmony_ci      vfalse1 = efalse1 = graph()->NewNode(
44531cb0ef41Sopenharmony_ci          simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
44541cb0ef41Sopenharmony_ci          efalse1, if_false1);
44551cb0ef41Sopenharmony_ci    }
44561cb0ef41Sopenharmony_ci
44571cb0ef41Sopenharmony_ci    if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
44581cb0ef41Sopenharmony_ci    efalse0 =
44591cb0ef41Sopenharmony_ci        graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
44601cb0ef41Sopenharmony_ci    vfalse0 =
44611cb0ef41Sopenharmony_ci        graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
44621cb0ef41Sopenharmony_ci                         vtrue1, vfalse1, if_false0);
44631cb0ef41Sopenharmony_ci  }
44641cb0ef41Sopenharmony_ci
44651cb0ef41Sopenharmony_ci  control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
44661cb0ef41Sopenharmony_ci  effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
44671cb0ef41Sopenharmony_ci  value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
44681cb0ef41Sopenharmony_ci                           vtrue0, vfalse0, control);
44691cb0ef41Sopenharmony_ci
44701cb0ef41Sopenharmony_ci  // Replace effect and control uses appropriately.
44711cb0ef41Sopenharmony_ci  for (Edge edge : node->use_edges()) {
44721cb0ef41Sopenharmony_ci    if (NodeProperties::IsControlEdge(edge)) {
44731cb0ef41Sopenharmony_ci      if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
44741cb0ef41Sopenharmony_ci        edge.from()->ReplaceUses(control);
44751cb0ef41Sopenharmony_ci        edge.from()->Kill();
44761cb0ef41Sopenharmony_ci      } else {
44771cb0ef41Sopenharmony_ci        DCHECK_NE(IrOpcode::kIfException, edge.from()->opcode());
44781cb0ef41Sopenharmony_ci        edge.UpdateTo(control);
44791cb0ef41Sopenharmony_ci      }
44801cb0ef41Sopenharmony_ci    } else if (NodeProperties::IsEffectEdge(edge)) {
44811cb0ef41Sopenharmony_ci      edge.UpdateTo(effect);
44821cb0ef41Sopenharmony_ci    }
44831cb0ef41Sopenharmony_ci  }
44841cb0ef41Sopenharmony_ci
44851cb0ef41Sopenharmony_ci  selector->DeferReplacement(node, value);
44861cb0ef41Sopenharmony_ci}
44871cb0ef41Sopenharmony_ci
44881cb0ef41Sopenharmony_civoid SimplifiedLowering::DoJSToNumberOrNumericTruncatesToWord32(
44891cb0ef41Sopenharmony_ci    Node* node, RepresentationSelector* selector) {
44901cb0ef41Sopenharmony_ci  DCHECK(node->opcode() == IrOpcode::kJSToNumber ||
44911cb0ef41Sopenharmony_ci         node->opcode() == IrOpcode::kJSToNumberConvertBigInt ||
44921cb0ef41Sopenharmony_ci         node->opcode() == IrOpcode::kJSToNumeric);
44931cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
44941cb0ef41Sopenharmony_ci  Node* context = node->InputAt(1);
44951cb0ef41Sopenharmony_ci  Node* frame_state = node->InputAt(2);
44961cb0ef41Sopenharmony_ci  Node* effect = node->InputAt(3);
44971cb0ef41Sopenharmony_ci  Node* control = node->InputAt(4);
44981cb0ef41Sopenharmony_ci
44991cb0ef41Sopenharmony_ci  Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), value);
45001cb0ef41Sopenharmony_ci  Node* branch0 =
45011cb0ef41Sopenharmony_ci      graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
45021cb0ef41Sopenharmony_ci
45031cb0ef41Sopenharmony_ci  Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
45041cb0ef41Sopenharmony_ci  Node* etrue0 = effect;
45051cb0ef41Sopenharmony_ci  Node* vtrue0 =
45061cb0ef41Sopenharmony_ci      graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), value);
45071cb0ef41Sopenharmony_ci
45081cb0ef41Sopenharmony_ci  Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
45091cb0ef41Sopenharmony_ci  Node* efalse0 = effect;
45101cb0ef41Sopenharmony_ci  Node* vfalse0;
45111cb0ef41Sopenharmony_ci  {
45121cb0ef41Sopenharmony_ci    Operator const* op =
45131cb0ef41Sopenharmony_ci        node->opcode() == IrOpcode::kJSToNumber
45141cb0ef41Sopenharmony_ci            ? (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
45151cb0ef41Sopenharmony_ci                   ? ToNumberConvertBigIntOperator()
45161cb0ef41Sopenharmony_ci                   : ToNumberOperator())
45171cb0ef41Sopenharmony_ci            : ToNumericOperator();
45181cb0ef41Sopenharmony_ci    Node* code = node->opcode() == IrOpcode::kJSToNumber
45191cb0ef41Sopenharmony_ci                     ? ToNumberCode()
45201cb0ef41Sopenharmony_ci                     : (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
45211cb0ef41Sopenharmony_ci                            ? ToNumberConvertBigIntCode()
45221cb0ef41Sopenharmony_ci                            : ToNumericCode());
45231cb0ef41Sopenharmony_ci    vfalse0 = efalse0 = if_false0 = graph()->NewNode(
45241cb0ef41Sopenharmony_ci        op, code, value, context, frame_state, efalse0, if_false0);
45251cb0ef41Sopenharmony_ci
45261cb0ef41Sopenharmony_ci    // Update potential {IfException} uses of {node} to point to the above
45271cb0ef41Sopenharmony_ci    // stub call node instead.
45281cb0ef41Sopenharmony_ci    Node* on_exception = nullptr;
45291cb0ef41Sopenharmony_ci    if (NodeProperties::IsExceptionalCall(node, &on_exception)) {
45301cb0ef41Sopenharmony_ci      NodeProperties::ReplaceControlInput(on_exception, vfalse0);
45311cb0ef41Sopenharmony_ci      NodeProperties::ReplaceEffectInput(on_exception, efalse0);
45321cb0ef41Sopenharmony_ci      if_false0 = graph()->NewNode(common()->IfSuccess(), vfalse0);
45331cb0ef41Sopenharmony_ci    }
45341cb0ef41Sopenharmony_ci
45351cb0ef41Sopenharmony_ci    Node* check1 = graph()->NewNode(simplified()->ObjectIsSmi(), vfalse0);
45361cb0ef41Sopenharmony_ci    Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
45371cb0ef41Sopenharmony_ci
45381cb0ef41Sopenharmony_ci    Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
45391cb0ef41Sopenharmony_ci    Node* etrue1 = efalse0;
45401cb0ef41Sopenharmony_ci    Node* vtrue1 =
45411cb0ef41Sopenharmony_ci        graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), vfalse0);
45421cb0ef41Sopenharmony_ci
45431cb0ef41Sopenharmony_ci    Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
45441cb0ef41Sopenharmony_ci    Node* efalse1 = efalse0;
45451cb0ef41Sopenharmony_ci    Node* vfalse1;
45461cb0ef41Sopenharmony_ci    {
45471cb0ef41Sopenharmony_ci      vfalse1 = efalse1 = graph()->NewNode(
45481cb0ef41Sopenharmony_ci          simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
45491cb0ef41Sopenharmony_ci          efalse1, if_false1);
45501cb0ef41Sopenharmony_ci      vfalse1 = graph()->NewNode(machine()->TruncateFloat64ToWord32(), vfalse1);
45511cb0ef41Sopenharmony_ci    }
45521cb0ef41Sopenharmony_ci
45531cb0ef41Sopenharmony_ci    if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
45541cb0ef41Sopenharmony_ci    efalse0 =
45551cb0ef41Sopenharmony_ci        graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
45561cb0ef41Sopenharmony_ci    vfalse0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
45571cb0ef41Sopenharmony_ci                               vtrue1, vfalse1, if_false0);
45581cb0ef41Sopenharmony_ci  }
45591cb0ef41Sopenharmony_ci
45601cb0ef41Sopenharmony_ci  control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
45611cb0ef41Sopenharmony_ci  effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
45621cb0ef41Sopenharmony_ci  value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
45631cb0ef41Sopenharmony_ci                           vtrue0, vfalse0, control);
45641cb0ef41Sopenharmony_ci
45651cb0ef41Sopenharmony_ci  // Replace effect and control uses appropriately.
45661cb0ef41Sopenharmony_ci  for (Edge edge : node->use_edges()) {
45671cb0ef41Sopenharmony_ci    if (NodeProperties::IsControlEdge(edge)) {
45681cb0ef41Sopenharmony_ci      if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
45691cb0ef41Sopenharmony_ci        edge.from()->ReplaceUses(control);
45701cb0ef41Sopenharmony_ci        edge.from()->Kill();
45711cb0ef41Sopenharmony_ci      } else {
45721cb0ef41Sopenharmony_ci        DCHECK_NE(IrOpcode::kIfException, edge.from()->opcode());
45731cb0ef41Sopenharmony_ci        edge.UpdateTo(control);
45741cb0ef41Sopenharmony_ci      }
45751cb0ef41Sopenharmony_ci    } else if (NodeProperties::IsEffectEdge(edge)) {
45761cb0ef41Sopenharmony_ci      edge.UpdateTo(effect);
45771cb0ef41Sopenharmony_ci    }
45781cb0ef41Sopenharmony_ci  }
45791cb0ef41Sopenharmony_ci
45801cb0ef41Sopenharmony_ci  selector->DeferReplacement(node, value);
45811cb0ef41Sopenharmony_ci}
45821cb0ef41Sopenharmony_ci
45831cb0ef41Sopenharmony_ciNode* SimplifiedLowering::Float64Round(Node* const node) {
45841cb0ef41Sopenharmony_ci  Node* const one = jsgraph()->Float64Constant(1.0);
45851cb0ef41Sopenharmony_ci  Node* const one_half = jsgraph()->Float64Constant(0.5);
45861cb0ef41Sopenharmony_ci  Node* const input = node->InputAt(0);
45871cb0ef41Sopenharmony_ci
45881cb0ef41Sopenharmony_ci  // Round up towards Infinity, and adjust if the difference exceeds 0.5.
45891cb0ef41Sopenharmony_ci  Node* result = graph()->NewNode(machine()->Float64RoundUp().placeholder(),
45901cb0ef41Sopenharmony_ci                                  node->InputAt(0));
45911cb0ef41Sopenharmony_ci  return graph()->NewNode(
45921cb0ef41Sopenharmony_ci      common()->Select(MachineRepresentation::kFloat64),
45931cb0ef41Sopenharmony_ci      graph()->NewNode(
45941cb0ef41Sopenharmony_ci          machine()->Float64LessThanOrEqual(),
45951cb0ef41Sopenharmony_ci          graph()->NewNode(machine()->Float64Sub(), result, one_half), input),
45961cb0ef41Sopenharmony_ci      result, graph()->NewNode(machine()->Float64Sub(), result, one));
45971cb0ef41Sopenharmony_ci}
45981cb0ef41Sopenharmony_ci
45991cb0ef41Sopenharmony_ciNode* SimplifiedLowering::Float64Sign(Node* const node) {
46001cb0ef41Sopenharmony_ci  Node* const minus_one = jsgraph()->Float64Constant(-1.0);
46011cb0ef41Sopenharmony_ci  Node* const zero = jsgraph()->Float64Constant(0.0);
46021cb0ef41Sopenharmony_ci  Node* const one = jsgraph()->Float64Constant(1.0);
46031cb0ef41Sopenharmony_ci
46041cb0ef41Sopenharmony_ci  Node* const input = node->InputAt(0);
46051cb0ef41Sopenharmony_ci
46061cb0ef41Sopenharmony_ci  return graph()->NewNode(
46071cb0ef41Sopenharmony_ci      common()->Select(MachineRepresentation::kFloat64),
46081cb0ef41Sopenharmony_ci      graph()->NewNode(machine()->Float64LessThan(), input, zero), minus_one,
46091cb0ef41Sopenharmony_ci      graph()->NewNode(
46101cb0ef41Sopenharmony_ci          common()->Select(MachineRepresentation::kFloat64),
46111cb0ef41Sopenharmony_ci          graph()->NewNode(machine()->Float64LessThan(), zero, input), one,
46121cb0ef41Sopenharmony_ci          input));
46131cb0ef41Sopenharmony_ci}
46141cb0ef41Sopenharmony_ci
46151cb0ef41Sopenharmony_ciNode* SimplifiedLowering::Int32Abs(Node* const node) {
46161cb0ef41Sopenharmony_ci  Node* const input = node->InputAt(0);
46171cb0ef41Sopenharmony_ci
46181cb0ef41Sopenharmony_ci  // Generate case for absolute integer value.
46191cb0ef41Sopenharmony_ci  //
46201cb0ef41Sopenharmony_ci  //    let sign = input >> 31 in
46211cb0ef41Sopenharmony_ci  //    (input ^ sign) - sign
46221cb0ef41Sopenharmony_ci
46231cb0ef41Sopenharmony_ci  Node* sign = graph()->NewNode(machine()->Word32Sar(), input,
46241cb0ef41Sopenharmony_ci                                jsgraph()->Int32Constant(31));
46251cb0ef41Sopenharmony_ci  return graph()->NewNode(machine()->Int32Sub(),
46261cb0ef41Sopenharmony_ci                          graph()->NewNode(machine()->Word32Xor(), input, sign),
46271cb0ef41Sopenharmony_ci                          sign);
46281cb0ef41Sopenharmony_ci}
46291cb0ef41Sopenharmony_ci
46301cb0ef41Sopenharmony_ciNode* SimplifiedLowering::Int32Div(Node* const node) {
46311cb0ef41Sopenharmony_ci  Int32BinopMatcher m(node);
46321cb0ef41Sopenharmony_ci  Node* const zero = jsgraph()->Int32Constant(0);
46331cb0ef41Sopenharmony_ci  Node* const minus_one = jsgraph()->Int32Constant(-1);
46341cb0ef41Sopenharmony_ci  Node* const lhs = m.left().node();
46351cb0ef41Sopenharmony_ci  Node* const rhs = m.right().node();
46361cb0ef41Sopenharmony_ci
46371cb0ef41Sopenharmony_ci  if (m.right().Is(-1)) {
46381cb0ef41Sopenharmony_ci    return graph()->NewNode(machine()->Int32Sub(), zero, lhs);
46391cb0ef41Sopenharmony_ci  } else if (m.right().Is(0)) {
46401cb0ef41Sopenharmony_ci    return rhs;
46411cb0ef41Sopenharmony_ci  } else if (machine()->Int32DivIsSafe() || m.right().HasResolvedValue()) {
46421cb0ef41Sopenharmony_ci    return graph()->NewNode(machine()->Int32Div(), lhs, rhs, graph()->start());
46431cb0ef41Sopenharmony_ci  }
46441cb0ef41Sopenharmony_ci
46451cb0ef41Sopenharmony_ci  // General case for signed integer division.
46461cb0ef41Sopenharmony_ci  //
46471cb0ef41Sopenharmony_ci  //    if 0 < rhs then
46481cb0ef41Sopenharmony_ci  //      lhs / rhs
46491cb0ef41Sopenharmony_ci  //    else
46501cb0ef41Sopenharmony_ci  //      if rhs < -1 then
46511cb0ef41Sopenharmony_ci  //        lhs / rhs
46521cb0ef41Sopenharmony_ci  //      else if rhs == 0 then
46531cb0ef41Sopenharmony_ci  //        0
46541cb0ef41Sopenharmony_ci  //      else
46551cb0ef41Sopenharmony_ci  //        0 - lhs
46561cb0ef41Sopenharmony_ci  //
46571cb0ef41Sopenharmony_ci  // Note: We do not use the Diamond helper class here, because it really hurts
46581cb0ef41Sopenharmony_ci  // readability with nested diamonds.
46591cb0ef41Sopenharmony_ci  const Operator* const merge_op = common()->Merge(2);
46601cb0ef41Sopenharmony_ci  const Operator* const phi_op =
46611cb0ef41Sopenharmony_ci      common()->Phi(MachineRepresentation::kWord32, 2);
46621cb0ef41Sopenharmony_ci
46631cb0ef41Sopenharmony_ci  Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs);
46641cb0ef41Sopenharmony_ci  Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0,
46651cb0ef41Sopenharmony_ci                                   graph()->start());
46661cb0ef41Sopenharmony_ci
46671cb0ef41Sopenharmony_ci  Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
46681cb0ef41Sopenharmony_ci  Node* true0 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true0);
46691cb0ef41Sopenharmony_ci
46701cb0ef41Sopenharmony_ci  Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
46711cb0ef41Sopenharmony_ci  Node* false0;
46721cb0ef41Sopenharmony_ci  {
46731cb0ef41Sopenharmony_ci    Node* check1 = graph()->NewNode(machine()->Int32LessThan(), rhs, minus_one);
46741cb0ef41Sopenharmony_ci    Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
46751cb0ef41Sopenharmony_ci
46761cb0ef41Sopenharmony_ci    Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
46771cb0ef41Sopenharmony_ci    Node* true1 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true1);
46781cb0ef41Sopenharmony_ci
46791cb0ef41Sopenharmony_ci    Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
46801cb0ef41Sopenharmony_ci    Node* false1;
46811cb0ef41Sopenharmony_ci    {
46821cb0ef41Sopenharmony_ci      Node* check2 = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
46831cb0ef41Sopenharmony_ci      Node* branch2 = graph()->NewNode(common()->Branch(), check2, if_false1);
46841cb0ef41Sopenharmony_ci
46851cb0ef41Sopenharmony_ci      Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
46861cb0ef41Sopenharmony_ci      Node* true2 = zero;
46871cb0ef41Sopenharmony_ci
46881cb0ef41Sopenharmony_ci      Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
46891cb0ef41Sopenharmony_ci      Node* false2 = graph()->NewNode(machine()->Int32Sub(), zero, lhs);
46901cb0ef41Sopenharmony_ci
46911cb0ef41Sopenharmony_ci      if_false1 = graph()->NewNode(merge_op, if_true2, if_false2);
46921cb0ef41Sopenharmony_ci      false1 = graph()->NewNode(phi_op, true2, false2, if_false1);
46931cb0ef41Sopenharmony_ci    }
46941cb0ef41Sopenharmony_ci
46951cb0ef41Sopenharmony_ci    if_false0 = graph()->NewNode(merge_op, if_true1, if_false1);
46961cb0ef41Sopenharmony_ci    false0 = graph()->NewNode(phi_op, true1, false1, if_false0);
46971cb0ef41Sopenharmony_ci  }
46981cb0ef41Sopenharmony_ci
46991cb0ef41Sopenharmony_ci  Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
47001cb0ef41Sopenharmony_ci  return graph()->NewNode(phi_op, true0, false0, merge0);
47011cb0ef41Sopenharmony_ci}
47021cb0ef41Sopenharmony_ci
47031cb0ef41Sopenharmony_ciNode* SimplifiedLowering::Int32Mod(Node* const node) {
47041cb0ef41Sopenharmony_ci  Int32BinopMatcher m(node);
47051cb0ef41Sopenharmony_ci  Node* const zero = jsgraph()->Int32Constant(0);
47061cb0ef41Sopenharmony_ci  Node* const minus_one = jsgraph()->Int32Constant(-1);
47071cb0ef41Sopenharmony_ci  Node* const lhs = m.left().node();
47081cb0ef41Sopenharmony_ci  Node* const rhs = m.right().node();
47091cb0ef41Sopenharmony_ci
47101cb0ef41Sopenharmony_ci  if (m.right().Is(-1) || m.right().Is(0)) {
47111cb0ef41Sopenharmony_ci    return zero;
47121cb0ef41Sopenharmony_ci  } else if (m.right().HasResolvedValue()) {
47131cb0ef41Sopenharmony_ci    return graph()->NewNode(machine()->Int32Mod(), lhs, rhs, graph()->start());
47141cb0ef41Sopenharmony_ci  }
47151cb0ef41Sopenharmony_ci
47161cb0ef41Sopenharmony_ci  // General case for signed integer modulus, with optimization for (unknown)
47171cb0ef41Sopenharmony_ci  // power of 2 right hand side.
47181cb0ef41Sopenharmony_ci  //
47191cb0ef41Sopenharmony_ci  //   if 0 < rhs then
47201cb0ef41Sopenharmony_ci  //     msk = rhs - 1
47211cb0ef41Sopenharmony_ci  //     if rhs & msk != 0 then
47221cb0ef41Sopenharmony_ci  //       lhs % rhs
47231cb0ef41Sopenharmony_ci  //     else
47241cb0ef41Sopenharmony_ci  //       if lhs < 0 then
47251cb0ef41Sopenharmony_ci  //         -(-lhs & msk)
47261cb0ef41Sopenharmony_ci  //       else
47271cb0ef41Sopenharmony_ci  //         lhs & msk
47281cb0ef41Sopenharmony_ci  //   else
47291cb0ef41Sopenharmony_ci  //     if rhs < -1 then
47301cb0ef41Sopenharmony_ci  //       lhs % rhs
47311cb0ef41Sopenharmony_ci  //     else
47321cb0ef41Sopenharmony_ci  //       zero
47331cb0ef41Sopenharmony_ci  //
47341cb0ef41Sopenharmony_ci  // Note: We do not use the Diamond helper class here, because it really hurts
47351cb0ef41Sopenharmony_ci  // readability with nested diamonds.
47361cb0ef41Sopenharmony_ci  const Operator* const merge_op = common()->Merge(2);
47371cb0ef41Sopenharmony_ci  const Operator* const phi_op =
47381cb0ef41Sopenharmony_ci      common()->Phi(MachineRepresentation::kWord32, 2);
47391cb0ef41Sopenharmony_ci
47401cb0ef41Sopenharmony_ci  Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs);
47411cb0ef41Sopenharmony_ci  Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0,
47421cb0ef41Sopenharmony_ci                                   graph()->start());
47431cb0ef41Sopenharmony_ci
47441cb0ef41Sopenharmony_ci  Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
47451cb0ef41Sopenharmony_ci  Node* true0;
47461cb0ef41Sopenharmony_ci  {
47471cb0ef41Sopenharmony_ci    Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one);
47481cb0ef41Sopenharmony_ci
47491cb0ef41Sopenharmony_ci    Node* check1 = graph()->NewNode(machine()->Word32And(), rhs, msk);
47501cb0ef41Sopenharmony_ci    Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
47511cb0ef41Sopenharmony_ci
47521cb0ef41Sopenharmony_ci    Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
47531cb0ef41Sopenharmony_ci    Node* true1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1);
47541cb0ef41Sopenharmony_ci
47551cb0ef41Sopenharmony_ci    Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
47561cb0ef41Sopenharmony_ci    Node* false1;
47571cb0ef41Sopenharmony_ci    {
47581cb0ef41Sopenharmony_ci      Node* check2 = graph()->NewNode(machine()->Int32LessThan(), lhs, zero);
47591cb0ef41Sopenharmony_ci      Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
47601cb0ef41Sopenharmony_ci                                       check2, if_false1);
47611cb0ef41Sopenharmony_ci
47621cb0ef41Sopenharmony_ci      Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
47631cb0ef41Sopenharmony_ci      Node* true2 = graph()->NewNode(
47641cb0ef41Sopenharmony_ci          machine()->Int32Sub(), zero,
47651cb0ef41Sopenharmony_ci          graph()->NewNode(machine()->Word32And(),
47661cb0ef41Sopenharmony_ci                           graph()->NewNode(machine()->Int32Sub(), zero, lhs),
47671cb0ef41Sopenharmony_ci                           msk));
47681cb0ef41Sopenharmony_ci
47691cb0ef41Sopenharmony_ci      Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
47701cb0ef41Sopenharmony_ci      Node* false2 = graph()->NewNode(machine()->Word32And(), lhs, msk);
47711cb0ef41Sopenharmony_ci
47721cb0ef41Sopenharmony_ci      if_false1 = graph()->NewNode(merge_op, if_true2, if_false2);
47731cb0ef41Sopenharmony_ci      false1 = graph()->NewNode(phi_op, true2, false2, if_false1);
47741cb0ef41Sopenharmony_ci    }
47751cb0ef41Sopenharmony_ci
47761cb0ef41Sopenharmony_ci    if_true0 = graph()->NewNode(merge_op, if_true1, if_false1);
47771cb0ef41Sopenharmony_ci    true0 = graph()->NewNode(phi_op, true1, false1, if_true0);
47781cb0ef41Sopenharmony_ci  }
47791cb0ef41Sopenharmony_ci
47801cb0ef41Sopenharmony_ci  Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
47811cb0ef41Sopenharmony_ci  Node* false0;
47821cb0ef41Sopenharmony_ci  {
47831cb0ef41Sopenharmony_ci    Node* check1 = graph()->NewNode(machine()->Int32LessThan(), rhs, minus_one);
47841cb0ef41Sopenharmony_ci    Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
47851cb0ef41Sopenharmony_ci                                     check1, if_false0);
47861cb0ef41Sopenharmony_ci
47871cb0ef41Sopenharmony_ci    Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
47881cb0ef41Sopenharmony_ci    Node* true1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1);
47891cb0ef41Sopenharmony_ci
47901cb0ef41Sopenharmony_ci    Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
47911cb0ef41Sopenharmony_ci    Node* false1 = zero;
47921cb0ef41Sopenharmony_ci
47931cb0ef41Sopenharmony_ci    if_false0 = graph()->NewNode(merge_op, if_true1, if_false1);
47941cb0ef41Sopenharmony_ci    false0 = graph()->NewNode(phi_op, true1, false1, if_false0);
47951cb0ef41Sopenharmony_ci  }
47961cb0ef41Sopenharmony_ci
47971cb0ef41Sopenharmony_ci  Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
47981cb0ef41Sopenharmony_ci  return graph()->NewNode(phi_op, true0, false0, merge0);
47991cb0ef41Sopenharmony_ci}
48001cb0ef41Sopenharmony_ci
48011cb0ef41Sopenharmony_ciNode* SimplifiedLowering::Int32Sign(Node* const node) {
48021cb0ef41Sopenharmony_ci  Node* const minus_one = jsgraph()->Int32Constant(-1);
48031cb0ef41Sopenharmony_ci  Node* const zero = jsgraph()->Int32Constant(0);
48041cb0ef41Sopenharmony_ci  Node* const one = jsgraph()->Int32Constant(1);
48051cb0ef41Sopenharmony_ci
48061cb0ef41Sopenharmony_ci  Node* const input = node->InputAt(0);
48071cb0ef41Sopenharmony_ci
48081cb0ef41Sopenharmony_ci  return graph()->NewNode(
48091cb0ef41Sopenharmony_ci      common()->Select(MachineRepresentation::kWord32),
48101cb0ef41Sopenharmony_ci      graph()->NewNode(machine()->Int32LessThan(), input, zero), minus_one,
48111cb0ef41Sopenharmony_ci      graph()->NewNode(
48121cb0ef41Sopenharmony_ci          common()->Select(MachineRepresentation::kWord32),
48131cb0ef41Sopenharmony_ci          graph()->NewNode(machine()->Int32LessThan(), zero, input), one,
48141cb0ef41Sopenharmony_ci          zero));
48151cb0ef41Sopenharmony_ci}
48161cb0ef41Sopenharmony_ci
48171cb0ef41Sopenharmony_ciNode* SimplifiedLowering::Uint32Div(Node* const node) {
48181cb0ef41Sopenharmony_ci  Uint32BinopMatcher m(node);
48191cb0ef41Sopenharmony_ci  Node* const zero = jsgraph()->Uint32Constant(0);
48201cb0ef41Sopenharmony_ci  Node* const lhs = m.left().node();
48211cb0ef41Sopenharmony_ci  Node* const rhs = m.right().node();
48221cb0ef41Sopenharmony_ci
48231cb0ef41Sopenharmony_ci  if (m.right().Is(0)) {
48241cb0ef41Sopenharmony_ci    return zero;
48251cb0ef41Sopenharmony_ci  } else if (machine()->Uint32DivIsSafe() || m.right().HasResolvedValue()) {
48261cb0ef41Sopenharmony_ci    return graph()->NewNode(machine()->Uint32Div(), lhs, rhs, graph()->start());
48271cb0ef41Sopenharmony_ci  }
48281cb0ef41Sopenharmony_ci
48291cb0ef41Sopenharmony_ci  Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
48301cb0ef41Sopenharmony_ci  Diamond d(graph(), common(), check, BranchHint::kFalse);
48311cb0ef41Sopenharmony_ci  Node* div = graph()->NewNode(machine()->Uint32Div(), lhs, rhs, d.if_false);
48321cb0ef41Sopenharmony_ci  return d.Phi(MachineRepresentation::kWord32, zero, div);
48331cb0ef41Sopenharmony_ci}
48341cb0ef41Sopenharmony_ci
48351cb0ef41Sopenharmony_ciNode* SimplifiedLowering::Uint32Mod(Node* const node) {
48361cb0ef41Sopenharmony_ci  Uint32BinopMatcher m(node);
48371cb0ef41Sopenharmony_ci  Node* const minus_one = jsgraph()->Int32Constant(-1);
48381cb0ef41Sopenharmony_ci  Node* const zero = jsgraph()->Uint32Constant(0);
48391cb0ef41Sopenharmony_ci  Node* const lhs = m.left().node();
48401cb0ef41Sopenharmony_ci  Node* const rhs = m.right().node();
48411cb0ef41Sopenharmony_ci
48421cb0ef41Sopenharmony_ci  if (m.right().Is(0)) {
48431cb0ef41Sopenharmony_ci    return zero;
48441cb0ef41Sopenharmony_ci  } else if (m.right().HasResolvedValue()) {
48451cb0ef41Sopenharmony_ci    return graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, graph()->start());
48461cb0ef41Sopenharmony_ci  }
48471cb0ef41Sopenharmony_ci
48481cb0ef41Sopenharmony_ci  // General case for unsigned integer modulus, with optimization for (unknown)
48491cb0ef41Sopenharmony_ci  // power of 2 right hand side.
48501cb0ef41Sopenharmony_ci  //
48511cb0ef41Sopenharmony_ci  //   if rhs == 0 then
48521cb0ef41Sopenharmony_ci  //     zero
48531cb0ef41Sopenharmony_ci  //   else
48541cb0ef41Sopenharmony_ci  //     msk = rhs - 1
48551cb0ef41Sopenharmony_ci  //     if rhs & msk != 0 then
48561cb0ef41Sopenharmony_ci  //       lhs % rhs
48571cb0ef41Sopenharmony_ci  //     else
48581cb0ef41Sopenharmony_ci  //       lhs & msk
48591cb0ef41Sopenharmony_ci  //
48601cb0ef41Sopenharmony_ci  // Note: We do not use the Diamond helper class here, because it really hurts
48611cb0ef41Sopenharmony_ci  // readability with nested diamonds.
48621cb0ef41Sopenharmony_ci  const Operator* const merge_op = common()->Merge(2);
48631cb0ef41Sopenharmony_ci  const Operator* const phi_op =
48641cb0ef41Sopenharmony_ci      common()->Phi(MachineRepresentation::kWord32, 2);
48651cb0ef41Sopenharmony_ci
48661cb0ef41Sopenharmony_ci  Node* check0 = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
48671cb0ef41Sopenharmony_ci  Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kFalse), check0,
48681cb0ef41Sopenharmony_ci                                   graph()->start());
48691cb0ef41Sopenharmony_ci
48701cb0ef41Sopenharmony_ci  Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
48711cb0ef41Sopenharmony_ci  Node* true0 = zero;
48721cb0ef41Sopenharmony_ci
48731cb0ef41Sopenharmony_ci  Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
48741cb0ef41Sopenharmony_ci  Node* false0;
48751cb0ef41Sopenharmony_ci  {
48761cb0ef41Sopenharmony_ci    Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one);
48771cb0ef41Sopenharmony_ci
48781cb0ef41Sopenharmony_ci    Node* check1 = graph()->NewNode(machine()->Word32And(), rhs, msk);
48791cb0ef41Sopenharmony_ci    Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
48801cb0ef41Sopenharmony_ci
48811cb0ef41Sopenharmony_ci    Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
48821cb0ef41Sopenharmony_ci    Node* true1 = graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, if_true1);
48831cb0ef41Sopenharmony_ci
48841cb0ef41Sopenharmony_ci    Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
48851cb0ef41Sopenharmony_ci    Node* false1 = graph()->NewNode(machine()->Word32And(), lhs, msk);
48861cb0ef41Sopenharmony_ci
48871cb0ef41Sopenharmony_ci    if_false0 = graph()->NewNode(merge_op, if_true1, if_false1);
48881cb0ef41Sopenharmony_ci    false0 = graph()->NewNode(phi_op, true1, false1, if_false0);
48891cb0ef41Sopenharmony_ci  }
48901cb0ef41Sopenharmony_ci
48911cb0ef41Sopenharmony_ci  Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
48921cb0ef41Sopenharmony_ci  return graph()->NewNode(phi_op, true0, false0, merge0);
48931cb0ef41Sopenharmony_ci}
48941cb0ef41Sopenharmony_ci
48951cb0ef41Sopenharmony_civoid SimplifiedLowering::DoMax(Node* node, Operator const* op,
48961cb0ef41Sopenharmony_ci                               MachineRepresentation rep) {
48971cb0ef41Sopenharmony_ci  Node* const lhs = node->InputAt(0);
48981cb0ef41Sopenharmony_ci  Node* const rhs = node->InputAt(1);
48991cb0ef41Sopenharmony_ci
49001cb0ef41Sopenharmony_ci  node->ReplaceInput(0, graph()->NewNode(op, lhs, rhs));
49011cb0ef41Sopenharmony_ci  DCHECK_EQ(rhs, node->InputAt(1));
49021cb0ef41Sopenharmony_ci  node->AppendInput(graph()->zone(), lhs);
49031cb0ef41Sopenharmony_ci  ChangeOp(node, common()->Select(rep));
49041cb0ef41Sopenharmony_ci}
49051cb0ef41Sopenharmony_ci
49061cb0ef41Sopenharmony_civoid SimplifiedLowering::DoMin(Node* node, Operator const* op,
49071cb0ef41Sopenharmony_ci                               MachineRepresentation rep) {
49081cb0ef41Sopenharmony_ci  Node* const lhs = node->InputAt(0);
49091cb0ef41Sopenharmony_ci  Node* const rhs = node->InputAt(1);
49101cb0ef41Sopenharmony_ci
49111cb0ef41Sopenharmony_ci  node->InsertInput(graph()->zone(), 0, graph()->NewNode(op, lhs, rhs));
49121cb0ef41Sopenharmony_ci  DCHECK_EQ(lhs, node->InputAt(1));
49131cb0ef41Sopenharmony_ci  DCHECK_EQ(rhs, node->InputAt(2));
49141cb0ef41Sopenharmony_ci  ChangeOp(node, common()->Select(rep));
49151cb0ef41Sopenharmony_ci}
49161cb0ef41Sopenharmony_ci
49171cb0ef41Sopenharmony_civoid SimplifiedLowering::DoIntegral32ToBit(Node* node) {
49181cb0ef41Sopenharmony_ci  Node* const input = node->InputAt(0);
49191cb0ef41Sopenharmony_ci  Node* const zero = jsgraph()->Int32Constant(0);
49201cb0ef41Sopenharmony_ci  Operator const* const op = machine()->Word32Equal();
49211cb0ef41Sopenharmony_ci
49221cb0ef41Sopenharmony_ci  node->ReplaceInput(0, graph()->NewNode(op, input, zero));
49231cb0ef41Sopenharmony_ci  node->AppendInput(graph()->zone(), zero);
49241cb0ef41Sopenharmony_ci  ChangeOp(node, op);
49251cb0ef41Sopenharmony_ci}
49261cb0ef41Sopenharmony_ci
49271cb0ef41Sopenharmony_civoid SimplifiedLowering::DoOrderedNumberToBit(Node* node) {
49281cb0ef41Sopenharmony_ci  Node* const input = node->InputAt(0);
49291cb0ef41Sopenharmony_ci
49301cb0ef41Sopenharmony_ci  node->ReplaceInput(0, graph()->NewNode(machine()->Float64Equal(), input,
49311cb0ef41Sopenharmony_ci                                         jsgraph()->Float64Constant(0.0)));
49321cb0ef41Sopenharmony_ci  node->AppendInput(graph()->zone(), jsgraph()->Int32Constant(0));
49331cb0ef41Sopenharmony_ci  ChangeOp(node, machine()->Word32Equal());
49341cb0ef41Sopenharmony_ci}
49351cb0ef41Sopenharmony_ci
49361cb0ef41Sopenharmony_civoid SimplifiedLowering::DoNumberToBit(Node* node) {
49371cb0ef41Sopenharmony_ci  Node* const input = node->InputAt(0);
49381cb0ef41Sopenharmony_ci
49391cb0ef41Sopenharmony_ci  node->ReplaceInput(0, jsgraph()->Float64Constant(0.0));
49401cb0ef41Sopenharmony_ci  node->AppendInput(graph()->zone(),
49411cb0ef41Sopenharmony_ci                    graph()->NewNode(machine()->Float64Abs(), input));
49421cb0ef41Sopenharmony_ci  ChangeOp(node, machine()->Float64LessThan());
49431cb0ef41Sopenharmony_ci}
49441cb0ef41Sopenharmony_ci
49451cb0ef41Sopenharmony_civoid SimplifiedLowering::DoIntegerToUint8Clamped(Node* node) {
49461cb0ef41Sopenharmony_ci  Node* const input = node->InputAt(0);
49471cb0ef41Sopenharmony_ci  Node* const min = jsgraph()->Float64Constant(0.0);
49481cb0ef41Sopenharmony_ci  Node* const max = jsgraph()->Float64Constant(255.0);
49491cb0ef41Sopenharmony_ci
49501cb0ef41Sopenharmony_ci  node->ReplaceInput(
49511cb0ef41Sopenharmony_ci      0, graph()->NewNode(machine()->Float64LessThan(), min, input));
49521cb0ef41Sopenharmony_ci  node->AppendInput(
49531cb0ef41Sopenharmony_ci      graph()->zone(),
49541cb0ef41Sopenharmony_ci      graph()->NewNode(
49551cb0ef41Sopenharmony_ci          common()->Select(MachineRepresentation::kFloat64),
49561cb0ef41Sopenharmony_ci          graph()->NewNode(machine()->Float64LessThan(), input, max), input,
49571cb0ef41Sopenharmony_ci          max));
49581cb0ef41Sopenharmony_ci  node->AppendInput(graph()->zone(), min);
49591cb0ef41Sopenharmony_ci  ChangeOp(node, common()->Select(MachineRepresentation::kFloat64));
49601cb0ef41Sopenharmony_ci}
49611cb0ef41Sopenharmony_ci
49621cb0ef41Sopenharmony_civoid SimplifiedLowering::DoNumberToUint8Clamped(Node* node) {
49631cb0ef41Sopenharmony_ci  Node* const input = node->InputAt(0);
49641cb0ef41Sopenharmony_ci  Node* const min = jsgraph()->Float64Constant(0.0);
49651cb0ef41Sopenharmony_ci  Node* const max = jsgraph()->Float64Constant(255.0);
49661cb0ef41Sopenharmony_ci
49671cb0ef41Sopenharmony_ci  node->ReplaceInput(
49681cb0ef41Sopenharmony_ci      0, graph()->NewNode(
49691cb0ef41Sopenharmony_ci             common()->Select(MachineRepresentation::kFloat64),
49701cb0ef41Sopenharmony_ci             graph()->NewNode(machine()->Float64LessThan(), min, input),
49711cb0ef41Sopenharmony_ci             graph()->NewNode(
49721cb0ef41Sopenharmony_ci                 common()->Select(MachineRepresentation::kFloat64),
49731cb0ef41Sopenharmony_ci                 graph()->NewNode(machine()->Float64LessThan(), input, max),
49741cb0ef41Sopenharmony_ci                 input, max),
49751cb0ef41Sopenharmony_ci             min));
49761cb0ef41Sopenharmony_ci  ChangeOp(node, machine()->Float64RoundTiesEven().placeholder());
49771cb0ef41Sopenharmony_ci}
49781cb0ef41Sopenharmony_ci
49791cb0ef41Sopenharmony_civoid SimplifiedLowering::DoSigned32ToUint8Clamped(Node* node) {
49801cb0ef41Sopenharmony_ci  Node* const input = node->InputAt(0);
49811cb0ef41Sopenharmony_ci  Node* const min = jsgraph()->Int32Constant(0);
49821cb0ef41Sopenharmony_ci  Node* const max = jsgraph()->Int32Constant(255);
49831cb0ef41Sopenharmony_ci
49841cb0ef41Sopenharmony_ci  node->ReplaceInput(
49851cb0ef41Sopenharmony_ci      0, graph()->NewNode(machine()->Int32LessThanOrEqual(), input, max));
49861cb0ef41Sopenharmony_ci  node->AppendInput(
49871cb0ef41Sopenharmony_ci      graph()->zone(),
49881cb0ef41Sopenharmony_ci      graph()->NewNode(common()->Select(MachineRepresentation::kWord32),
49891cb0ef41Sopenharmony_ci                       graph()->NewNode(machine()->Int32LessThan(), input, min),
49901cb0ef41Sopenharmony_ci                       min, input));
49911cb0ef41Sopenharmony_ci  node->AppendInput(graph()->zone(), max);
49921cb0ef41Sopenharmony_ci  ChangeOp(node, common()->Select(MachineRepresentation::kWord32));
49931cb0ef41Sopenharmony_ci}
49941cb0ef41Sopenharmony_ci
49951cb0ef41Sopenharmony_civoid SimplifiedLowering::DoUnsigned32ToUint8Clamped(Node* node) {
49961cb0ef41Sopenharmony_ci  Node* const input = node->InputAt(0);
49971cb0ef41Sopenharmony_ci  Node* const max = jsgraph()->Uint32Constant(255u);
49981cb0ef41Sopenharmony_ci
49991cb0ef41Sopenharmony_ci  node->ReplaceInput(
50001cb0ef41Sopenharmony_ci      0, graph()->NewNode(machine()->Uint32LessThanOrEqual(), input, max));
50011cb0ef41Sopenharmony_ci  node->AppendInput(graph()->zone(), input);
50021cb0ef41Sopenharmony_ci  node->AppendInput(graph()->zone(), max);
50031cb0ef41Sopenharmony_ci  ChangeOp(node, common()->Select(MachineRepresentation::kWord32));
50041cb0ef41Sopenharmony_ci}
50051cb0ef41Sopenharmony_ci
50061cb0ef41Sopenharmony_ciNode* SimplifiedLowering::ToNumberCode() {
50071cb0ef41Sopenharmony_ci  if (!to_number_code_.is_set()) {
50081cb0ef41Sopenharmony_ci    Callable callable = Builtins::CallableFor(isolate(), Builtin::kToNumber);
50091cb0ef41Sopenharmony_ci    to_number_code_.set(jsgraph()->HeapConstant(callable.code()));
50101cb0ef41Sopenharmony_ci  }
50111cb0ef41Sopenharmony_ci  return to_number_code_.get();
50121cb0ef41Sopenharmony_ci}
50131cb0ef41Sopenharmony_ci
50141cb0ef41Sopenharmony_ciNode* SimplifiedLowering::ToNumberConvertBigIntCode() {
50151cb0ef41Sopenharmony_ci  if (!to_number_convert_big_int_code_.is_set()) {
50161cb0ef41Sopenharmony_ci    Callable callable =
50171cb0ef41Sopenharmony_ci        Builtins::CallableFor(isolate(), Builtin::kToNumberConvertBigInt);
50181cb0ef41Sopenharmony_ci    to_number_convert_big_int_code_.set(
50191cb0ef41Sopenharmony_ci        jsgraph()->HeapConstant(callable.code()));
50201cb0ef41Sopenharmony_ci  }
50211cb0ef41Sopenharmony_ci  return to_number_convert_big_int_code_.get();
50221cb0ef41Sopenharmony_ci}
50231cb0ef41Sopenharmony_ci
50241cb0ef41Sopenharmony_ciNode* SimplifiedLowering::ToNumericCode() {
50251cb0ef41Sopenharmony_ci  if (!to_numeric_code_.is_set()) {
50261cb0ef41Sopenharmony_ci    Callable callable = Builtins::CallableFor(isolate(), Builtin::kToNumeric);
50271cb0ef41Sopenharmony_ci    to_numeric_code_.set(jsgraph()->HeapConstant(callable.code()));
50281cb0ef41Sopenharmony_ci  }
50291cb0ef41Sopenharmony_ci  return to_numeric_code_.get();
50301cb0ef41Sopenharmony_ci}
50311cb0ef41Sopenharmony_ci
50321cb0ef41Sopenharmony_ciOperator const* SimplifiedLowering::ToNumberOperator() {
50331cb0ef41Sopenharmony_ci  if (!to_number_operator_.is_set()) {
50341cb0ef41Sopenharmony_ci    Callable callable = Builtins::CallableFor(isolate(), Builtin::kToNumber);
50351cb0ef41Sopenharmony_ci    CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
50361cb0ef41Sopenharmony_ci    auto call_descriptor = Linkage::GetStubCallDescriptor(
50371cb0ef41Sopenharmony_ci        graph()->zone(), callable.descriptor(),
50381cb0ef41Sopenharmony_ci        callable.descriptor().GetStackParameterCount(), flags,
50391cb0ef41Sopenharmony_ci        Operator::kNoProperties);
50401cb0ef41Sopenharmony_ci    to_number_operator_.set(common()->Call(call_descriptor));
50411cb0ef41Sopenharmony_ci  }
50421cb0ef41Sopenharmony_ci  return to_number_operator_.get();
50431cb0ef41Sopenharmony_ci}
50441cb0ef41Sopenharmony_ci
50451cb0ef41Sopenharmony_ciOperator const* SimplifiedLowering::ToNumberConvertBigIntOperator() {
50461cb0ef41Sopenharmony_ci  if (!to_number_convert_big_int_operator_.is_set()) {
50471cb0ef41Sopenharmony_ci    Callable callable =
50481cb0ef41Sopenharmony_ci        Builtins::CallableFor(isolate(), Builtin::kToNumberConvertBigInt);
50491cb0ef41Sopenharmony_ci    CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
50501cb0ef41Sopenharmony_ci    auto call_descriptor = Linkage::GetStubCallDescriptor(
50511cb0ef41Sopenharmony_ci        graph()->zone(), callable.descriptor(),
50521cb0ef41Sopenharmony_ci        callable.descriptor().GetStackParameterCount(), flags,
50531cb0ef41Sopenharmony_ci        Operator::kNoProperties);
50541cb0ef41Sopenharmony_ci    to_number_convert_big_int_operator_.set(common()->Call(call_descriptor));
50551cb0ef41Sopenharmony_ci  }
50561cb0ef41Sopenharmony_ci  return to_number_convert_big_int_operator_.get();
50571cb0ef41Sopenharmony_ci}
50581cb0ef41Sopenharmony_ci
50591cb0ef41Sopenharmony_ciOperator const* SimplifiedLowering::ToNumericOperator() {
50601cb0ef41Sopenharmony_ci  if (!to_numeric_operator_.is_set()) {
50611cb0ef41Sopenharmony_ci    Callable callable = Builtins::CallableFor(isolate(), Builtin::kToNumeric);
50621cb0ef41Sopenharmony_ci    CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
50631cb0ef41Sopenharmony_ci    auto call_descriptor = Linkage::GetStubCallDescriptor(
50641cb0ef41Sopenharmony_ci        graph()->zone(), callable.descriptor(),
50651cb0ef41Sopenharmony_ci        callable.descriptor().GetStackParameterCount(), flags,
50661cb0ef41Sopenharmony_ci        Operator::kNoProperties);
50671cb0ef41Sopenharmony_ci    to_numeric_operator_.set(common()->Call(call_descriptor));
50681cb0ef41Sopenharmony_ci  }
50691cb0ef41Sopenharmony_ci  return to_numeric_operator_.get();
50701cb0ef41Sopenharmony_ci}
50711cb0ef41Sopenharmony_ci
50721cb0ef41Sopenharmony_civoid SimplifiedLowering::ChangeOp(Node* node, const Operator* new_op) {
50731cb0ef41Sopenharmony_ci  compiler::NodeProperties::ChangeOp(node, new_op);
50741cb0ef41Sopenharmony_ci
50751cb0ef41Sopenharmony_ci  if (V8_UNLIKELY(observe_node_manager_ != nullptr))
50761cb0ef41Sopenharmony_ci    observe_node_manager_->OnNodeChanged(kSimplifiedLoweringReducerName, node,
50771cb0ef41Sopenharmony_ci                                         node);
50781cb0ef41Sopenharmony_ci}
50791cb0ef41Sopenharmony_ci
50801cb0ef41Sopenharmony_ci#undef TRACE
50811cb0ef41Sopenharmony_ci
50821cb0ef41Sopenharmony_ci}  // namespace compiler
50831cb0ef41Sopenharmony_ci}  // namespace internal
50841cb0ef41Sopenharmony_ci}  // namespace v8
5085