1// Copyright 2015 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/compiler/representation-change.h"
6
7#include <sstream>
8
9#include "src/base/bits.h"
10#include "src/base/safe_conversions.h"
11#include "src/codegen/code-factory.h"
12#include "src/compiler/js-heap-broker.h"
13#include "src/compiler/machine-operator.h"
14#include "src/compiler/node-matchers.h"
15#include "src/compiler/simplified-lowering-verifier.h"
16#include "src/compiler/simplified-operator.h"
17#include "src/compiler/type-cache.h"
18#include "src/heap/factory-inl.h"
19
20namespace v8 {
21namespace internal {
22namespace compiler {
23
24const char* Truncation::description() const {
25  switch (kind()) {
26    case TruncationKind::kNone:
27      return "no-value-use";
28    case TruncationKind::kBool:
29      return "truncate-to-bool";
30    case TruncationKind::kWord32:
31      return "truncate-to-word32";
32    case TruncationKind::kWord64:
33      return "truncate-to-word64";
34    case TruncationKind::kOddballAndBigIntToNumber:
35      switch (identify_zeros()) {
36        case kIdentifyZeros:
37          return "truncate-oddball&bigint-to-number (identify zeros)";
38        case kDistinguishZeros:
39          return "truncate-oddball&bigint-to-number (distinguish zeros)";
40      }
41    case TruncationKind::kAny:
42      switch (identify_zeros()) {
43        case kIdentifyZeros:
44          return "no-truncation (but identify zeros)";
45        case kDistinguishZeros:
46          return "no-truncation (but distinguish zeros)";
47      }
48  }
49  UNREACHABLE();
50}
51
52// Partial order for truncations:
53//
54//               kAny <-------+
55//                 ^          |
56//                 |          |
57//  kOddballAndBigIntToNumber |
58//               ^            |
59//               /            |
60//        kWord64             |
61//             ^              |
62//             |              |
63//        kWord32           kBool
64//              ^            ^
65//              \            /
66//               \          /
67//                \        /
68//                 \      /
69//                  \    /
70//                  kNone
71//
72// TODO(jarin) We might consider making kBool < kOddballAndBigIntToNumber.
73
74// static
75Truncation::TruncationKind Truncation::Generalize(TruncationKind rep1,
76                                                  TruncationKind rep2) {
77  if (LessGeneral(rep1, rep2)) return rep2;
78  if (LessGeneral(rep2, rep1)) return rep1;
79  // Handle the generalization of float64-representable values.
80  if (LessGeneral(rep1, TruncationKind::kOddballAndBigIntToNumber) &&
81      LessGeneral(rep2, TruncationKind::kOddballAndBigIntToNumber)) {
82    return TruncationKind::kOddballAndBigIntToNumber;
83  }
84  // Handle the generalization of any-representable values.
85  if (LessGeneral(rep1, TruncationKind::kAny) &&
86      LessGeneral(rep2, TruncationKind::kAny)) {
87    return TruncationKind::kAny;
88  }
89  // All other combinations are illegal.
90  FATAL("Tried to combine incompatible truncations");
91}
92
93// static
94IdentifyZeros Truncation::GeneralizeIdentifyZeros(IdentifyZeros i1,
95                                                  IdentifyZeros i2) {
96  if (i1 == i2) {
97    return i1;
98  } else {
99    return kDistinguishZeros;
100  }
101}
102
103// static
104bool Truncation::LessGeneral(TruncationKind rep1, TruncationKind rep2) {
105  switch (rep1) {
106    case TruncationKind::kNone:
107      return true;
108    case TruncationKind::kBool:
109      return rep2 == TruncationKind::kBool || rep2 == TruncationKind::kAny;
110    case TruncationKind::kWord32:
111      return rep2 == TruncationKind::kWord32 ||
112             rep2 == TruncationKind::kWord64 ||
113             rep2 == TruncationKind::kOddballAndBigIntToNumber ||
114             rep2 == TruncationKind::kAny;
115    case TruncationKind::kWord64:
116      return rep2 == TruncationKind::kWord64 ||
117             rep2 == TruncationKind::kOddballAndBigIntToNumber ||
118             rep2 == TruncationKind::kAny;
119    case TruncationKind::kOddballAndBigIntToNumber:
120      return rep2 == TruncationKind::kOddballAndBigIntToNumber ||
121             rep2 == TruncationKind::kAny;
122    case TruncationKind::kAny:
123      return rep2 == TruncationKind::kAny;
124  }
125  UNREACHABLE();
126}
127
128// static
129bool Truncation::LessGeneralIdentifyZeros(IdentifyZeros i1, IdentifyZeros i2) {
130  return i1 == i2 || i1 == kIdentifyZeros;
131}
132
133namespace {
134
135bool IsWord(MachineRepresentation rep) {
136  return rep == MachineRepresentation::kWord8 ||
137         rep == MachineRepresentation::kWord16 ||
138         rep == MachineRepresentation::kWord32;
139}
140
141}  // namespace
142
143RepresentationChanger::RepresentationChanger(
144    JSGraph* jsgraph, JSHeapBroker* broker,
145    SimplifiedLoweringVerifier* verifier)
146    : cache_(TypeCache::Get()),
147      jsgraph_(jsgraph),
148      broker_(broker),
149      verifier_(verifier),
150      testing_type_errors_(false),
151      type_error_(false) {}
152
153// Changes representation from {output_rep} to {use_rep}. The {truncation}
154// parameter is only used for checking - if the changer cannot figure
155// out signedness for the word32->float64 conversion, then we check that the
156// uses truncate to word32 (so they do not care about signedness).
157Node* RepresentationChanger::GetRepresentationFor(
158    Node* node, MachineRepresentation output_rep, Type output_type,
159    Node* use_node, UseInfo use_info) {
160  if (output_rep == MachineRepresentation::kNone && !output_type.IsNone()) {
161    // The output representation should be set if the type is inhabited (i.e.,
162    // if the value is possible).
163    return TypeError(node, output_rep, output_type, use_info.representation());
164  }
165
166  // Rematerialize any truncated BigInt if user is not expecting a BigInt.
167  if (output_type.Is(Type::BigInt()) &&
168      output_rep == MachineRepresentation::kWord64 &&
169      use_info.type_check() != TypeCheckKind::kBigInt) {
170    if (output_type.Is(Type::UnsignedBigInt64())) {
171      node = InsertConversion(node, simplified()->ChangeUint64ToBigInt(),
172                              use_node);
173    } else {
174      node =
175          InsertConversion(node, simplified()->ChangeInt64ToBigInt(), use_node);
176    }
177    output_rep = MachineRepresentation::kTaggedPointer;
178  }
179
180  // Handle the no-op shortcuts when no checking is necessary.
181  if (use_info.type_check() == TypeCheckKind::kNone ||
182      // TODO(nicohartmann@, chromium:1077804): Ignoring {use_info.type_check()}
183      // in case the representation already matches is not correct. For now,
184      // this behavior is disabled only for TypeCheckKind::kBigInt, but should
185      // be fixed for all other type checks.
186      (output_rep != MachineRepresentation::kWord32 &&
187       use_info.type_check() != TypeCheckKind::kBigInt)) {
188    if (use_info.representation() == output_rep) {
189      // Representations are the same. That's a no-op.
190      return node;
191    }
192    if (IsWord(use_info.representation()) && IsWord(output_rep)) {
193      // Both are words less than or equal to 32-bits.
194      // Since loads of integers from memory implicitly sign or zero extend the
195      // value to the full machine word size and stores implicitly truncate,
196      // no representation change is necessary.
197      return node;
198    }
199  }
200
201  switch (use_info.representation()) {
202    case MachineRepresentation::kTaggedSigned:
203      DCHECK(use_info.type_check() == TypeCheckKind::kNone ||
204             use_info.type_check() == TypeCheckKind::kSignedSmall);
205      return GetTaggedSignedRepresentationFor(node, output_rep, output_type,
206                                              use_node, use_info);
207    case MachineRepresentation::kTaggedPointer:
208      DCHECK(use_info.type_check() == TypeCheckKind::kNone ||
209             use_info.type_check() == TypeCheckKind::kHeapObject ||
210             use_info.type_check() == TypeCheckKind::kBigInt);
211      return GetTaggedPointerRepresentationFor(node, output_rep, output_type,
212                                               use_node, use_info);
213    case MachineRepresentation::kTagged:
214      DCHECK_EQ(TypeCheckKind::kNone, use_info.type_check());
215      return GetTaggedRepresentationFor(node, output_rep, output_type,
216                                        use_info.truncation());
217    case MachineRepresentation::kFloat32:
218      DCHECK_EQ(TypeCheckKind::kNone, use_info.type_check());
219      return GetFloat32RepresentationFor(node, output_rep, output_type,
220                                         use_info.truncation());
221    case MachineRepresentation::kFloat64:
222      DCHECK(use_info.type_check() == TypeCheckKind::kNone ||
223             use_info.type_check() == TypeCheckKind::kNumber ||
224             use_info.type_check() == TypeCheckKind::kNumberOrBoolean ||
225             use_info.type_check() == TypeCheckKind::kNumberOrOddball);
226      return GetFloat64RepresentationFor(node, output_rep, output_type,
227                                         use_node, use_info);
228    case MachineRepresentation::kBit:
229      DCHECK_EQ(TypeCheckKind::kNone, use_info.type_check());
230      return GetBitRepresentationFor(node, output_rep, output_type);
231    case MachineRepresentation::kWord8:
232    case MachineRepresentation::kWord16:
233    case MachineRepresentation::kWord32:
234      return GetWord32RepresentationFor(node, output_rep, output_type, use_node,
235                                        use_info);
236    case MachineRepresentation::kWord64:
237      DCHECK(use_info.type_check() == TypeCheckKind::kNone ||
238             use_info.type_check() == TypeCheckKind::kSigned64 ||
239             use_info.type_check() == TypeCheckKind::kBigInt ||
240             use_info.type_check() == TypeCheckKind::kArrayIndex);
241      return GetWord64RepresentationFor(node, output_rep, output_type, use_node,
242                                        use_info);
243    case MachineRepresentation::kSimd128:
244    case MachineRepresentation::kNone:
245      return node;
246    case MachineRepresentation::kCompressed:
247    case MachineRepresentation::kCompressedPointer:
248    case MachineRepresentation::kSandboxedPointer:
249    case MachineRepresentation::kMapWord:
250      UNREACHABLE();
251  }
252  UNREACHABLE();
253}
254
255Node* RepresentationChanger::GetTaggedSignedRepresentationFor(
256    Node* node, MachineRepresentation output_rep, Type output_type,
257    Node* use_node, UseInfo use_info) {
258  // Eagerly fold representation changes for constants.
259  switch (node->opcode()) {
260    case IrOpcode::kNumberConstant:
261      if (output_type.Is(Type::SignedSmall())) {
262        return node;
263      }
264      break;
265    default:
266      break;
267  }
268  // Select the correct X -> Tagged operator.
269  const Operator* op;
270  if (output_type.Is(Type::None())) {
271    // This is an impossible value; it should not be used at runtime.
272    return jsgraph()->graph()->NewNode(
273        jsgraph()->common()->DeadValue(MachineRepresentation::kTaggedSigned),
274        node);
275  } else if (IsWord(output_rep)) {
276    if (output_type.Is(Type::Signed31())) {
277      op = simplified()->ChangeInt31ToTaggedSigned();
278    } else if (output_type.Is(Type::Signed32())) {
279      if (SmiValuesAre32Bits()) {
280        op = simplified()->ChangeInt32ToTagged();
281      } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
282        op = simplified()->CheckedInt32ToTaggedSigned(use_info.feedback());
283      } else {
284        return TypeError(node, output_rep, output_type,
285                         MachineRepresentation::kTaggedSigned);
286      }
287    } else if (output_type.Is(Type::Unsigned32()) &&
288               use_info.type_check() == TypeCheckKind::kSignedSmall) {
289      op = simplified()->CheckedUint32ToTaggedSigned(use_info.feedback());
290    } else {
291      return TypeError(node, output_rep, output_type,
292                       MachineRepresentation::kTaggedSigned);
293    }
294  } else if (output_rep == MachineRepresentation::kWord64) {
295    if (output_type.Is(Type::Signed31())) {
296      // int64 -> int32 -> tagged signed
297      node = InsertTruncateInt64ToInt32(node);
298      op = simplified()->ChangeInt31ToTaggedSigned();
299    } else if (output_type.Is(Type::Signed32()) && SmiValuesAre32Bits()) {
300      // int64 -> int32 -> tagged signed
301      node = InsertTruncateInt64ToInt32(node);
302      op = simplified()->ChangeInt32ToTagged();
303    } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
304      if (output_type.Is(cache_->kPositiveSafeInteger)) {
305        op = simplified()->CheckedUint64ToTaggedSigned(use_info.feedback());
306      } else if (output_type.Is(cache_->kSafeInteger)) {
307        op = simplified()->CheckedInt64ToTaggedSigned(use_info.feedback());
308      } else {
309        return TypeError(node, output_rep, output_type,
310                         MachineRepresentation::kTaggedSigned);
311      }
312    } else {
313      return TypeError(node, output_rep, output_type,
314                       MachineRepresentation::kTaggedSigned);
315    }
316  } else if (output_rep == MachineRepresentation::kFloat64) {
317    if (output_type.Is(Type::Signed31())) {
318      // float64 -> int32 -> tagged signed
319      node = InsertChangeFloat64ToInt32(node);
320      op = simplified()->ChangeInt31ToTaggedSigned();
321    } else if (output_type.Is(Type::Signed32())) {
322      // float64 -> int32 -> tagged signed
323      node = InsertChangeFloat64ToInt32(node);
324      if (SmiValuesAre32Bits()) {
325        op = simplified()->ChangeInt32ToTagged();
326      } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
327        op = simplified()->CheckedInt32ToTaggedSigned(use_info.feedback());
328      } else {
329        return TypeError(node, output_rep, output_type,
330                         MachineRepresentation::kTaggedSigned);
331      }
332    } else if (output_type.Is(Type::Unsigned32()) &&
333               use_info.type_check() == TypeCheckKind::kSignedSmall) {
334      // float64 -> uint32 -> tagged signed
335      node = InsertChangeFloat64ToUint32(node);
336      op = simplified()->CheckedUint32ToTaggedSigned(use_info.feedback());
337    } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
338      node = InsertCheckedFloat64ToInt32(
339          node,
340          output_type.Maybe(Type::MinusZero())
341              ? CheckForMinusZeroMode::kCheckForMinusZero
342              : CheckForMinusZeroMode::kDontCheckForMinusZero,
343          use_info.feedback(), use_node);
344      if (SmiValuesAre32Bits()) {
345        op = simplified()->ChangeInt32ToTagged();
346      } else {
347        op = simplified()->CheckedInt32ToTaggedSigned(use_info.feedback());
348      }
349    } else {
350      return TypeError(node, output_rep, output_type,
351                       MachineRepresentation::kTaggedSigned);
352    }
353  } else if (output_rep == MachineRepresentation::kFloat32) {
354    if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
355      node = InsertChangeFloat32ToFloat64(node);
356      node = InsertCheckedFloat64ToInt32(
357          node,
358          output_type.Maybe(Type::MinusZero())
359              ? CheckForMinusZeroMode::kCheckForMinusZero
360              : CheckForMinusZeroMode::kDontCheckForMinusZero,
361          use_info.feedback(), use_node);
362      if (SmiValuesAre32Bits()) {
363        op = simplified()->ChangeInt32ToTagged();
364      } else {
365        op = simplified()->CheckedInt32ToTaggedSigned(use_info.feedback());
366      }
367    } else {
368      return TypeError(node, output_rep, output_type,
369                       MachineRepresentation::kTaggedSigned);
370    }
371  } else if (CanBeTaggedPointer(output_rep)) {
372    if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
373      op = simplified()->CheckedTaggedToTaggedSigned(use_info.feedback());
374    } else if (output_type.Is(Type::SignedSmall())) {
375      op = simplified()->ChangeTaggedToTaggedSigned();
376    } else {
377      return TypeError(node, output_rep, output_type,
378                       MachineRepresentation::kTaggedSigned);
379    }
380  } else if (output_rep == MachineRepresentation::kBit) {
381    if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
382      // TODO(turbofan): Consider adding a Bailout operator that just deopts.
383      // Also use that for MachineRepresentation::kPointer case above.
384      node = InsertChangeBitToTagged(node);
385      op = simplified()->CheckedTaggedToTaggedSigned(use_info.feedback());
386    } else {
387      return TypeError(node, output_rep, output_type,
388                       MachineRepresentation::kTaggedSigned);
389    }
390  } else {
391    return TypeError(node, output_rep, output_type,
392                     MachineRepresentation::kTaggedSigned);
393  }
394  return InsertConversion(node, op, use_node);
395}
396
397Node* RepresentationChanger::GetTaggedPointerRepresentationFor(
398    Node* node, MachineRepresentation output_rep, Type output_type,
399    Node* use_node, UseInfo use_info) {
400  // Eagerly fold representation changes for constants.
401  switch (node->opcode()) {
402    case IrOpcode::kHeapConstant:
403    case IrOpcode::kDelayedStringConstant:
404      if (use_info.type_check() == TypeCheckKind::kBigInt) break;
405      return node;  // No change necessary.
406    case IrOpcode::kInt32Constant:
407    case IrOpcode::kFloat64Constant:
408    case IrOpcode::kFloat32Constant:
409      UNREACHABLE();
410    default:
411      break;
412  }
413  // Select the correct X -> TaggedPointer operator.
414  Operator const* op;
415  if (output_type.Is(Type::None())) {
416    // This is an impossible value; it should not be used at runtime.
417    return jsgraph()->graph()->NewNode(
418        jsgraph()->common()->DeadValue(MachineRepresentation::kTaggedPointer),
419        node);
420  }
421
422  if (use_info.type_check() == TypeCheckKind::kBigInt &&
423      !output_type.Is(Type::BigInt())) {
424    // BigInt checks can only be performed on tagged representations. Note that
425    // a corresponding check is inserted down below.
426    if (!CanBeTaggedPointer(output_rep)) {
427      Node* unreachable =
428          InsertUnconditionalDeopt(use_node, DeoptimizeReason::kNotABigInt);
429      return jsgraph()->graph()->NewNode(
430          jsgraph()->common()->DeadValue(MachineRepresentation::kTaggedPointer),
431          unreachable);
432    }
433  }
434
435  if (output_rep == MachineRepresentation::kBit) {
436    if (output_type.Is(Type::Boolean())) {
437      op = simplified()->ChangeBitToTagged();
438    } else {
439      return TypeError(node, output_rep, output_type,
440                       MachineRepresentation::kTagged);
441    }
442  } else if (IsWord(output_rep)) {
443    if (output_type.Is(Type::Unsigned32())) {
444      // uint32 -> float64 -> tagged
445      node = InsertChangeUint32ToFloat64(node);
446    } else if (output_type.Is(Type::Signed32())) {
447      // int32 -> float64 -> tagged
448      node = InsertChangeInt32ToFloat64(node);
449    } else {
450      return TypeError(node, output_rep, output_type,
451                       MachineRepresentation::kTaggedPointer);
452    }
453    op = simplified()->ChangeFloat64ToTaggedPointer();
454  } else if (output_rep == MachineRepresentation::kWord64) {
455    if (output_type.Is(cache_->kSafeInteger)) {
456      // int64 -> float64 -> tagged pointer
457      op = machine()->ChangeInt64ToFloat64();
458      node = jsgraph()->graph()->NewNode(op, node);
459      op = simplified()->ChangeFloat64ToTaggedPointer();
460    } else if (output_type.Is(Type::SignedBigInt64()) &&
461               use_info.type_check() == TypeCheckKind::kBigInt) {
462      op = simplified()->ChangeInt64ToBigInt();
463    } else if (output_type.Is(Type::UnsignedBigInt64()) &&
464               use_info.type_check() == TypeCheckKind::kBigInt) {
465      op = simplified()->ChangeUint64ToBigInt();
466    } else {
467      return TypeError(node, output_rep, output_type,
468                       MachineRepresentation::kTaggedPointer);
469    }
470  } else if (output_rep == MachineRepresentation::kFloat32) {
471    if (output_type.Is(Type::Number())) {
472      // float32 -> float64 -> tagged
473      node = InsertChangeFloat32ToFloat64(node);
474      op = simplified()->ChangeFloat64ToTaggedPointer();
475    } else {
476      return TypeError(node, output_rep, output_type,
477                       MachineRepresentation::kTaggedPointer);
478    }
479  } else if (output_rep == MachineRepresentation::kFloat64) {
480    if (output_type.Is(Type::Number())) {
481      // float64 -> tagged
482      op = simplified()->ChangeFloat64ToTaggedPointer();
483    } else {
484      return TypeError(node, output_rep, output_type,
485                       MachineRepresentation::kTaggedPointer);
486    }
487  } else if (CanBeTaggedSigned(output_rep) &&
488             use_info.type_check() == TypeCheckKind::kHeapObject) {
489    if (!output_type.Maybe(Type::SignedSmall())) {
490      return node;
491    }
492    // TODO(turbofan): Consider adding a Bailout operator that just deopts
493    // for TaggedSigned output representation.
494    op = simplified()->CheckedTaggedToTaggedPointer(use_info.feedback());
495  } else if (IsAnyTagged(output_rep) &&
496             (use_info.type_check() == TypeCheckKind::kBigInt ||
497              output_type.Is(Type::BigInt()))) {
498    if (output_type.Is(Type::BigInt())) {
499      return node;
500    }
501    op = simplified()->CheckBigInt(use_info.feedback());
502  } else {
503    return TypeError(node, output_rep, output_type,
504                     MachineRepresentation::kTaggedPointer);
505  }
506  return InsertConversion(node, op, use_node);
507}
508
509Node* RepresentationChanger::GetTaggedRepresentationFor(
510    Node* node, MachineRepresentation output_rep, Type output_type,
511    Truncation truncation) {
512  // Eagerly fold representation changes for constants.
513  switch (node->opcode()) {
514    case IrOpcode::kNumberConstant:
515    case IrOpcode::kHeapConstant:
516    case IrOpcode::kDelayedStringConstant:
517      return node;  // No change necessary.
518    case IrOpcode::kInt32Constant:
519    case IrOpcode::kFloat64Constant:
520    case IrOpcode::kFloat32Constant:
521      UNREACHABLE();
522    default:
523      break;
524  }
525  if (output_rep == MachineRepresentation::kTaggedSigned ||
526      output_rep == MachineRepresentation::kTaggedPointer ||
527      output_rep == MachineRepresentation::kMapWord) {
528    // this is a no-op.
529    return node;
530  }
531  // Select the correct X -> Tagged operator.
532  const Operator* op;
533  if (output_type.Is(Type::None())) {
534    // This is an impossible value; it should not be used at runtime.
535    return jsgraph()->graph()->NewNode(
536        jsgraph()->common()->DeadValue(MachineRepresentation::kTagged), node);
537  } else if (output_rep == MachineRepresentation::kBit) {
538    if (output_type.Is(Type::Boolean())) {
539      op = simplified()->ChangeBitToTagged();
540    } else {
541      return TypeError(node, output_rep, output_type,
542                       MachineRepresentation::kTagged);
543    }
544  } else if (IsWord(output_rep)) {
545    if (output_type.Is(Type::Signed31())) {
546      op = simplified()->ChangeInt31ToTaggedSigned();
547    } else if (output_type.Is(Type::Signed32()) ||
548               (output_type.Is(Type::Signed32OrMinusZero()) &&
549                truncation.IdentifiesZeroAndMinusZero())) {
550      op = simplified()->ChangeInt32ToTagged();
551    } else if (output_type.Is(Type::Unsigned32()) ||
552               (output_type.Is(Type::Unsigned32OrMinusZero()) &&
553                truncation.IdentifiesZeroAndMinusZero()) ||
554               truncation.IsUsedAsWord32()) {
555      // Either the output is uint32 or the uses only care about the
556      // low 32 bits (so we can pick uint32 safely).
557      op = simplified()->ChangeUint32ToTagged();
558    } else {
559      return TypeError(node, output_rep, output_type,
560                       MachineRepresentation::kTagged);
561    }
562  } else if (output_rep == MachineRepresentation::kWord64) {
563    if (output_type.Is(Type::Signed31())) {
564      // int64 -> int32 -> tagged signed
565      node = InsertTruncateInt64ToInt32(node);
566      op = simplified()->ChangeInt31ToTaggedSigned();
567    } else if (output_type.Is(Type::Signed32())) {
568      // int64 -> int32 -> tagged
569      node = InsertTruncateInt64ToInt32(node);
570      op = simplified()->ChangeInt32ToTagged();
571    } else if (output_type.Is(Type::Unsigned32())) {
572      // int64 -> uint32 -> tagged
573      node = InsertTruncateInt64ToInt32(node);
574      op = simplified()->ChangeUint32ToTagged();
575    } else if (output_type.Is(cache_->kPositiveSafeInteger)) {
576      // uint64 -> tagged
577      op = simplified()->ChangeUint64ToTagged();
578    } else if (output_type.Is(cache_->kSafeInteger)) {
579      // int64 -> tagged
580      op = simplified()->ChangeInt64ToTagged();
581    } else if (output_type.Is(Type::SignedBigInt64())) {
582      // int64 -> BigInt
583      op = simplified()->ChangeInt64ToBigInt();
584    } else if (output_type.Is(Type::UnsignedBigInt64())) {
585      // uint64 -> BigInt
586      op = simplified()->ChangeUint64ToBigInt();
587    } else {
588      return TypeError(node, output_rep, output_type,
589                       MachineRepresentation::kTagged);
590    }
591  } else if (output_rep ==
592             MachineRepresentation::kFloat32) {  // float32 -> float64 -> tagged
593    node = InsertChangeFloat32ToFloat64(node);
594    op = simplified()->ChangeFloat64ToTagged(
595        output_type.Maybe(Type::MinusZero())
596            ? CheckForMinusZeroMode::kCheckForMinusZero
597            : CheckForMinusZeroMode::kDontCheckForMinusZero);
598  } else if (output_rep == MachineRepresentation::kFloat64) {
599    if (output_type.Is(Type::Signed31())) {  // float64 -> int32 -> tagged
600      node = InsertChangeFloat64ToInt32(node);
601      op = simplified()->ChangeInt31ToTaggedSigned();
602    } else if (output_type.Is(
603                   Type::Signed32())) {  // float64 -> int32 -> tagged
604      node = InsertChangeFloat64ToInt32(node);
605      op = simplified()->ChangeInt32ToTagged();
606    } else if (output_type.Is(
607                   Type::Unsigned32())) {  // float64 -> uint32 -> tagged
608      node = InsertChangeFloat64ToUint32(node);
609      op = simplified()->ChangeUint32ToTagged();
610    } else if (output_type.Is(Type::Number()) ||
611               (output_type.Is(Type::NumberOrOddball()) &&
612                truncation.TruncatesOddballAndBigIntToNumber())) {
613      op = simplified()->ChangeFloat64ToTagged(
614          output_type.Maybe(Type::MinusZero())
615              ? CheckForMinusZeroMode::kCheckForMinusZero
616              : CheckForMinusZeroMode::kDontCheckForMinusZero);
617    } else {
618      return TypeError(node, output_rep, output_type,
619                       MachineRepresentation::kTagged);
620    }
621  } else {
622    return TypeError(node, output_rep, output_type,
623                     MachineRepresentation::kTagged);
624  }
625  return jsgraph()->graph()->NewNode(op, node);
626}
627
628Node* RepresentationChanger::GetFloat32RepresentationFor(
629    Node* node, MachineRepresentation output_rep, Type output_type,
630    Truncation truncation) {
631  // Eagerly fold representation changes for constants.
632  switch (node->opcode()) {
633    case IrOpcode::kNumberConstant:
634      return jsgraph()->Float32Constant(
635          DoubleToFloat32(OpParameter<double>(node->op())));
636    case IrOpcode::kInt32Constant:
637    case IrOpcode::kFloat64Constant:
638    case IrOpcode::kFloat32Constant:
639      UNREACHABLE();
640    default:
641      break;
642  }
643  // Select the correct X -> Float32 operator.
644  const Operator* op = nullptr;
645  if (output_type.Is(Type::None())) {
646    // This is an impossible value; it should not be used at runtime.
647    return jsgraph()->graph()->NewNode(
648        jsgraph()->common()->DeadValue(MachineRepresentation::kFloat32), node);
649  } else if (IsWord(output_rep)) {
650    if (output_type.Is(Type::Signed32())) {
651      // int32 -> float64 -> float32
652      op = machine()->ChangeInt32ToFloat64();
653      node = jsgraph()->graph()->NewNode(op, node);
654      op = machine()->TruncateFloat64ToFloat32();
655    } else if (output_type.Is(Type::Unsigned32()) ||
656               truncation.IsUsedAsWord32()) {
657      // Either the output is uint32 or the uses only care about the
658      // low 32 bits (so we can pick uint32 safely).
659
660      // uint32 -> float64 -> float32
661      op = machine()->ChangeUint32ToFloat64();
662      node = jsgraph()->graph()->NewNode(op, node);
663      op = machine()->TruncateFloat64ToFloat32();
664    }
665  } else if (IsAnyTagged(output_rep)) {
666    if (output_type.Is(Type::NumberOrOddball())) {
667      // tagged -> float64 -> float32
668      if (output_type.Is(Type::Number())) {
669        op = simplified()->ChangeTaggedToFloat64();
670      } else {
671        op = simplified()->TruncateTaggedToFloat64();
672      }
673      node = jsgraph()->graph()->NewNode(op, node);
674      op = machine()->TruncateFloat64ToFloat32();
675    }
676  } else if (output_rep == MachineRepresentation::kFloat64) {
677    op = machine()->TruncateFloat64ToFloat32();
678  } else if (output_rep == MachineRepresentation::kWord64) {
679    if (output_type.Is(cache_->kSafeInteger)) {
680      // int64 -> float64 -> float32
681      op = machine()->ChangeInt64ToFloat64();
682      node = jsgraph()->graph()->NewNode(op, node);
683      op = machine()->TruncateFloat64ToFloat32();
684    }
685  }
686  if (op == nullptr) {
687    return TypeError(node, output_rep, output_type,
688                     MachineRepresentation::kFloat32);
689  }
690  return jsgraph()->graph()->NewNode(op, node);
691}
692
693Node* RepresentationChanger::GetFloat64RepresentationFor(
694    Node* node, MachineRepresentation output_rep, Type output_type,
695    Node* use_node, UseInfo use_info) {
696  NumberMatcher m(node);
697  if (m.HasResolvedValue()) {
698    // BigInts are not used as number constants.
699    DCHECK(use_info.type_check() != TypeCheckKind::kBigInt);
700    switch (use_info.type_check()) {
701      case TypeCheckKind::kNone:
702      case TypeCheckKind::kNumber:
703      case TypeCheckKind::kNumberOrBoolean:
704      case TypeCheckKind::kNumberOrOddball:
705        return jsgraph()->Float64Constant(m.ResolvedValue());
706      case TypeCheckKind::kBigInt:
707      case TypeCheckKind::kHeapObject:
708      case TypeCheckKind::kSigned32:
709      case TypeCheckKind::kSigned64:
710      case TypeCheckKind::kSignedSmall:
711      case TypeCheckKind::kArrayIndex:
712        break;
713    }
714  }
715  // Select the correct X -> Float64 operator.
716  const Operator* op = nullptr;
717  if (output_type.Is(Type::None())) {
718    // This is an impossible value; it should not be used at runtime.
719    return jsgraph()->graph()->NewNode(
720        jsgraph()->common()->DeadValue(MachineRepresentation::kFloat64), node);
721  } else if (IsWord(output_rep)) {
722    if (output_type.Is(Type::Signed32()) ||
723        (output_type.Is(Type::Signed32OrMinusZero()) &&
724         use_info.truncation().IdentifiesZeroAndMinusZero())) {
725      op = machine()->ChangeInt32ToFloat64();
726    } else if (output_type.Is(Type::Unsigned32()) ||
727               (output_type.Is(Type::Unsigned32OrMinusZero()) &&
728                use_info.truncation().IdentifiesZeroAndMinusZero()) ||
729               use_info.truncation().IsUsedAsWord32()) {
730      // Either the output is uint32 or the uses only care about the
731      // low 32 bits (so we can pick uint32 safely).
732      op = machine()->ChangeUint32ToFloat64();
733    }
734  } else if (output_rep == MachineRepresentation::kBit) {
735    CHECK(output_type.Is(Type::Boolean()));
736    if (use_info.truncation().TruncatesOddballAndBigIntToNumber() ||
737        use_info.type_check() == TypeCheckKind::kNumberOrBoolean ||
738        use_info.type_check() == TypeCheckKind::kNumberOrOddball) {
739      op = machine()->ChangeUint32ToFloat64();
740    } else {
741      CHECK_NE(use_info.type_check(), TypeCheckKind::kNone);
742      Node* unreachable =
743          InsertUnconditionalDeopt(use_node, DeoptimizeReason::kNotAHeapNumber);
744      return jsgraph()->graph()->NewNode(
745          jsgraph()->common()->DeadValue(MachineRepresentation::kFloat64),
746          unreachable);
747    }
748  } else if (IsAnyTagged(output_rep)) {
749    if (output_type.Is(Type::Undefined())) {
750      if (use_info.type_check() == TypeCheckKind::kNumberOrOddball ||
751          (use_info.type_check() == TypeCheckKind::kNone &&
752           use_info.truncation().TruncatesOddballAndBigIntToNumber())) {
753        return jsgraph()->Float64Constant(
754            std::numeric_limits<double>::quiet_NaN());
755      } else {
756        DCHECK(use_info.type_check() == TypeCheckKind::kNone ||
757               use_info.type_check() == TypeCheckKind::kNumber ||
758               use_info.type_check() == TypeCheckKind::kNumberOrBoolean);
759        Node* unreachable = InsertUnconditionalDeopt(
760            use_node, use_info.type_check() == TypeCheckKind::kNumber
761                          ? DeoptimizeReason::kNotANumber
762                          : DeoptimizeReason::kNotANumberOrBoolean);
763        return jsgraph()->graph()->NewNode(
764            jsgraph()->common()->DeadValue(MachineRepresentation::kFloat64),
765            unreachable);
766      }
767    } else if (output_rep == MachineRepresentation::kTaggedSigned) {
768      node = InsertChangeTaggedSignedToInt32(node);
769      op = machine()->ChangeInt32ToFloat64();
770    } else if (output_type.Is(Type::Number())) {
771      op = simplified()->ChangeTaggedToFloat64();
772    } else if ((output_type.Is(Type::NumberOrOddball()) &&
773                use_info.truncation().TruncatesOddballAndBigIntToNumber()) ||
774               output_type.Is(Type::NumberOrHole())) {
775      // JavaScript 'null' is an Oddball that results in +0 when truncated to
776      // Number. In a context like -0 == null, which must evaluate to false,
777      // this truncation must not happen. For this reason we restrict this
778      // case to when either the user explicitly requested a float (and thus
779      // wants +0 if null is the input) or we know from the types that the
780      // input can only be Number | Hole. The latter is necessary to handle
781      // the operator CheckFloat64Hole. We did not put in the type (Number |
782      // Oddball \ Null) to discover more bugs related to this conversion via
783      // crashes.
784      op = simplified()->TruncateTaggedToFloat64();
785    } else if (use_info.type_check() == TypeCheckKind::kNumber ||
786               (use_info.type_check() == TypeCheckKind::kNumberOrOddball &&
787                !output_type.Maybe(Type::BooleanOrNullOrNumber()))) {
788      op = simplified()->CheckedTaggedToFloat64(CheckTaggedInputMode::kNumber,
789                                                use_info.feedback());
790    } else if (use_info.type_check() == TypeCheckKind::kNumberOrBoolean) {
791      op = simplified()->CheckedTaggedToFloat64(
792          CheckTaggedInputMode::kNumberOrBoolean, use_info.feedback());
793    } else if (use_info.type_check() == TypeCheckKind::kNumberOrOddball) {
794      op = simplified()->CheckedTaggedToFloat64(
795          CheckTaggedInputMode::kNumberOrOddball, use_info.feedback());
796    }
797  } else if (output_rep == MachineRepresentation::kFloat32) {
798    op = machine()->ChangeFloat32ToFloat64();
799  } else if (output_rep == MachineRepresentation::kWord64) {
800    if (output_type.Is(cache_->kSafeInteger)) {
801      op = machine()->ChangeInt64ToFloat64();
802    }
803  }
804  if (op == nullptr) {
805    return TypeError(node, output_rep, output_type,
806                     MachineRepresentation::kFloat64);
807  }
808  return InsertConversion(node, op, use_node);
809}
810
811Node* RepresentationChanger::MakeTruncatedInt32Constant(double value) {
812  return jsgraph()->Int32Constant(DoubleToInt32(value));
813}
814
815Node* RepresentationChanger::InsertUnconditionalDeopt(
816    Node* node, DeoptimizeReason reason, const FeedbackSource& feedback) {
817  Node* effect = NodeProperties::GetEffectInput(node);
818  Node* control = NodeProperties::GetControlInput(node);
819  effect =
820      jsgraph()->graph()->NewNode(simplified()->CheckIf(reason, feedback),
821                                  jsgraph()->Int32Constant(0), effect, control);
822  Node* unreachable = effect = jsgraph()->graph()->NewNode(
823      jsgraph()->common()->Unreachable(), effect, control);
824  NodeProperties::ReplaceEffectInput(node, effect);
825  return unreachable;
826}
827
828Node* RepresentationChanger::GetWord32RepresentationFor(
829    Node* node, MachineRepresentation output_rep, Type output_type,
830    Node* use_node, UseInfo use_info) {
831  // Eagerly fold representation changes for constants.
832  switch (node->opcode()) {
833    case IrOpcode::kInt32Constant:
834    case IrOpcode::kInt64Constant:
835    case IrOpcode::kFloat32Constant:
836    case IrOpcode::kFloat64Constant:
837      UNREACHABLE();
838    case IrOpcode::kNumberConstant: {
839      double const fv = OpParameter<double>(node->op());
840      if (use_info.type_check() == TypeCheckKind::kNone ||
841          ((use_info.type_check() == TypeCheckKind::kSignedSmall ||
842            use_info.type_check() == TypeCheckKind::kSigned32 ||
843            use_info.type_check() == TypeCheckKind::kNumber ||
844            use_info.type_check() == TypeCheckKind::kNumberOrOddball ||
845            use_info.type_check() == TypeCheckKind::kArrayIndex) &&
846           IsInt32Double(fv))) {
847        return InsertTypeOverrideForVerifier(NodeProperties::GetType(node),
848                                             MakeTruncatedInt32Constant(fv));
849      }
850      break;
851    }
852    default:
853      break;
854  }
855
856  // Select the correct X -> Word32 operator.
857  const Operator* op = nullptr;
858  if (output_type.Is(Type::None())) {
859    // This is an impossible value; it should not be used at runtime.
860    return jsgraph()->graph()->NewNode(
861        jsgraph()->common()->DeadValue(MachineRepresentation::kWord32), node);
862  } else if (output_rep == MachineRepresentation::kBit) {
863    CHECK(output_type.Is(Type::Boolean()));
864    if (use_info.truncation().IsUsedAsWord32()) {
865      return node;
866    } else {
867      CHECK(Truncation::Any(kIdentifyZeros)
868                .IsLessGeneralThan(use_info.truncation()));
869      CHECK_NE(use_info.type_check(), TypeCheckKind::kNone);
870      CHECK_NE(use_info.type_check(), TypeCheckKind::kNumberOrOddball);
871      Node* unreachable =
872          InsertUnconditionalDeopt(use_node, DeoptimizeReason::kNotASmi);
873      return jsgraph()->graph()->NewNode(
874          jsgraph()->common()->DeadValue(MachineRepresentation::kWord32),
875          unreachable);
876    }
877  } else if (output_rep == MachineRepresentation::kFloat64) {
878    if (output_type.Is(Type::Signed32())) {
879      op = machine()->ChangeFloat64ToInt32();
880    } else if (use_info.type_check() == TypeCheckKind::kSignedSmall ||
881               use_info.type_check() == TypeCheckKind::kSigned32 ||
882               use_info.type_check() == TypeCheckKind::kArrayIndex) {
883      op = simplified()->CheckedFloat64ToInt32(
884          output_type.Maybe(Type::MinusZero())
885              ? use_info.minus_zero_check()
886              : CheckForMinusZeroMode::kDontCheckForMinusZero,
887          use_info.feedback());
888    } else if (output_type.Is(Type::Unsigned32())) {
889      op = machine()->ChangeFloat64ToUint32();
890    } else if (use_info.truncation().IsUsedAsWord32()) {
891      op = machine()->TruncateFloat64ToWord32();
892    } else {
893      return TypeError(node, output_rep, output_type,
894                       MachineRepresentation::kWord32);
895    }
896  } else if (output_rep == MachineRepresentation::kFloat32) {
897    node = InsertChangeFloat32ToFloat64(node);  // float32 -> float64 -> int32
898    if (output_type.Is(Type::Signed32())) {
899      op = machine()->ChangeFloat64ToInt32();
900    } else if (use_info.type_check() == TypeCheckKind::kSignedSmall ||
901               use_info.type_check() == TypeCheckKind::kSigned32 ||
902               use_info.type_check() == TypeCheckKind::kArrayIndex) {
903      op = simplified()->CheckedFloat64ToInt32(
904          output_type.Maybe(Type::MinusZero())
905              ? use_info.minus_zero_check()
906              : CheckForMinusZeroMode::kDontCheckForMinusZero,
907          use_info.feedback());
908    } else if (output_type.Is(Type::Unsigned32())) {
909      op = machine()->ChangeFloat64ToUint32();
910    } else if (use_info.truncation().IsUsedAsWord32()) {
911      op = machine()->TruncateFloat64ToWord32();
912    } else {
913      return TypeError(node, output_rep, output_type,
914                       MachineRepresentation::kWord32);
915    }
916  } else if (IsAnyTagged(output_rep)) {
917    if (output_rep == MachineRepresentation::kTaggedSigned &&
918        output_type.Is(Type::SignedSmall())) {
919      op = simplified()->ChangeTaggedSignedToInt32();
920    } else if (output_type.Is(Type::Signed32())) {
921      op = simplified()->ChangeTaggedToInt32();
922    } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
923      op = simplified()->CheckedTaggedSignedToInt32(use_info.feedback());
924    } else if (use_info.type_check() == TypeCheckKind::kSigned32) {
925      op = simplified()->CheckedTaggedToInt32(
926          output_type.Maybe(Type::MinusZero())
927              ? use_info.minus_zero_check()
928              : CheckForMinusZeroMode::kDontCheckForMinusZero,
929          use_info.feedback());
930    } else if (use_info.type_check() == TypeCheckKind::kArrayIndex) {
931      op = simplified()->CheckedTaggedToArrayIndex(use_info.feedback());
932    } else if (output_type.Is(Type::Unsigned32())) {
933      op = simplified()->ChangeTaggedToUint32();
934    } else if (use_info.truncation().IsUsedAsWord32()) {
935      if (output_type.Is(Type::NumberOrOddball())) {
936        op = simplified()->TruncateTaggedToWord32();
937      } else if (use_info.type_check() == TypeCheckKind::kNumber) {
938        op = simplified()->CheckedTruncateTaggedToWord32(
939            CheckTaggedInputMode::kNumber, use_info.feedback());
940      } else if (use_info.type_check() == TypeCheckKind::kNumberOrOddball) {
941        op = simplified()->CheckedTruncateTaggedToWord32(
942            CheckTaggedInputMode::kNumberOrOddball, use_info.feedback());
943      } else {
944        return TypeError(node, output_rep, output_type,
945                         MachineRepresentation::kWord32);
946      }
947    } else {
948      return TypeError(node, output_rep, output_type,
949                       MachineRepresentation::kWord32);
950    }
951  } else if (output_rep == MachineRepresentation::kWord32) {
952    // Only the checked case should get here, the non-checked case is
953    // handled in GetRepresentationFor.
954    if (use_info.type_check() == TypeCheckKind::kSignedSmall ||
955        use_info.type_check() == TypeCheckKind::kSigned32 ||
956        use_info.type_check() == TypeCheckKind::kArrayIndex) {
957      bool identify_zeros = use_info.truncation().IdentifiesZeroAndMinusZero();
958      if (output_type.Is(Type::Signed32()) ||
959          (identify_zeros && output_type.Is(Type::Signed32OrMinusZero()))) {
960        return node;
961      } else if (output_type.Is(Type::Unsigned32()) ||
962                 (identify_zeros &&
963                  output_type.Is(Type::Unsigned32OrMinusZero()))) {
964        op = simplified()->CheckedUint32ToInt32(use_info.feedback());
965      } else {
966        return TypeError(node, output_rep, output_type,
967                         MachineRepresentation::kWord32);
968      }
969    } else if (use_info.type_check() == TypeCheckKind::kNumber ||
970               use_info.type_check() == TypeCheckKind::kNumberOrOddball) {
971      return node;
972    }
973  } else if (output_rep == MachineRepresentation::kWord8 ||
974             output_rep == MachineRepresentation::kWord16) {
975    DCHECK_EQ(MachineRepresentation::kWord32, use_info.representation());
976    DCHECK(use_info.type_check() == TypeCheckKind::kSignedSmall ||
977           use_info.type_check() == TypeCheckKind::kSigned32);
978    return node;
979  } else if (output_rep == MachineRepresentation::kWord64) {
980    if (output_type.Is(Type::Signed32()) ||
981        (output_type.Is(Type::Unsigned32()) &&
982         use_info.type_check() == TypeCheckKind::kNone) ||
983        (output_type.Is(cache_->kSafeInteger) &&
984         use_info.truncation().IsUsedAsWord32())) {
985      op = machine()->TruncateInt64ToInt32();
986    } else if (use_info.type_check() == TypeCheckKind::kSignedSmall ||
987               use_info.type_check() == TypeCheckKind::kSigned32 ||
988               use_info.type_check() == TypeCheckKind::kArrayIndex) {
989      if (output_type.Is(cache_->kPositiveSafeInteger)) {
990        op = simplified()->CheckedUint64ToInt32(use_info.feedback());
991      } else if (output_type.Is(cache_->kSafeInteger)) {
992        op = simplified()->CheckedInt64ToInt32(use_info.feedback());
993      } else {
994        return TypeError(node, output_rep, output_type,
995                         MachineRepresentation::kWord32);
996      }
997    } else {
998      return TypeError(node, output_rep, output_type,
999                       MachineRepresentation::kWord32);
1000    }
1001  }
1002
1003  if (op == nullptr) {
1004    return TypeError(node, output_rep, output_type,
1005                     MachineRepresentation::kWord32);
1006  }
1007  return InsertConversion(node, op, use_node);
1008}
1009
1010Node* RepresentationChanger::InsertConversion(Node* node, const Operator* op,
1011                                              Node* use_node) {
1012  if (op->ControlInputCount() > 0) {
1013    // If the operator can deoptimize (which means it has control
1014    // input), we need to connect it to the effect and control chains.
1015    Node* effect = NodeProperties::GetEffectInput(use_node);
1016    Node* control = NodeProperties::GetControlInput(use_node);
1017    Node* conversion = jsgraph()->graph()->NewNode(op, node, effect, control);
1018    NodeProperties::ReplaceEffectInput(use_node, conversion);
1019    return conversion;
1020  }
1021  return jsgraph()->graph()->NewNode(op, node);
1022}
1023
1024Node* RepresentationChanger::GetBitRepresentationFor(
1025    Node* node, MachineRepresentation output_rep, Type output_type) {
1026  // Eagerly fold representation changes for constants.
1027  switch (node->opcode()) {
1028    case IrOpcode::kHeapConstant: {
1029      HeapObjectMatcher m(node);
1030      if (m.Is(factory()->false_value())) {
1031        return jsgraph()->Int32Constant(0);
1032      } else if (m.Is(factory()->true_value())) {
1033        return jsgraph()->Int32Constant(1);
1034      }
1035      break;
1036    }
1037    default:
1038      break;
1039  }
1040  // Select the correct X -> Bit operator.
1041  const Operator* op;
1042  if (output_type.Is(Type::None())) {
1043    // This is an impossible value; it should not be used at runtime.
1044    return jsgraph()->graph()->NewNode(
1045        jsgraph()->common()->DeadValue(MachineRepresentation::kBit), node);
1046  } else if (output_rep == MachineRepresentation::kTagged ||
1047             output_rep == MachineRepresentation::kTaggedPointer) {
1048    if (output_type.Is(Type::BooleanOrNullOrUndefined())) {
1049      // true is the only trueish Oddball.
1050      op = simplified()->ChangeTaggedToBit();
1051    } else {
1052      if (output_rep == MachineRepresentation::kTagged &&
1053          output_type.Maybe(Type::SignedSmall())) {
1054        op = simplified()->TruncateTaggedToBit();
1055      } else {
1056        // The {output_type} either doesn't include the Smi range,
1057        // or the {output_rep} is known to be TaggedPointer.
1058        op = simplified()->TruncateTaggedPointerToBit();
1059      }
1060    }
1061  } else if (output_rep == MachineRepresentation::kTaggedSigned) {
1062    if (COMPRESS_POINTERS_BOOL) {
1063      node = jsgraph()->graph()->NewNode(machine()->Word32Equal(), node,
1064                                         jsgraph()->Int32Constant(0));
1065    } else {
1066      node = jsgraph()->graph()->NewNode(machine()->WordEqual(), node,
1067                                         jsgraph()->IntPtrConstant(0));
1068    }
1069    return jsgraph()->graph()->NewNode(machine()->Word32Equal(), node,
1070                                       jsgraph()->Int32Constant(0));
1071  } else if (IsWord(output_rep)) {
1072    node = jsgraph()->graph()->NewNode(machine()->Word32Equal(), node,
1073                                       jsgraph()->Int32Constant(0));
1074    return jsgraph()->graph()->NewNode(machine()->Word32Equal(), node,
1075                                       jsgraph()->Int32Constant(0));
1076  } else if (output_rep == MachineRepresentation::kWord64) {
1077    node = jsgraph()->graph()->NewNode(machine()->Word64Equal(), node,
1078                                       jsgraph()->Int64Constant(0));
1079    return jsgraph()->graph()->NewNode(machine()->Word32Equal(), node,
1080                                       jsgraph()->Int32Constant(0));
1081  } else if (output_rep == MachineRepresentation::kFloat32) {
1082    node = jsgraph()->graph()->NewNode(machine()->Float32Abs(), node);
1083    return jsgraph()->graph()->NewNode(machine()->Float32LessThan(),
1084                                       jsgraph()->Float32Constant(0.0), node);
1085  } else if (output_rep == MachineRepresentation::kFloat64) {
1086    node = jsgraph()->graph()->NewNode(machine()->Float64Abs(), node);
1087    return jsgraph()->graph()->NewNode(machine()->Float64LessThan(),
1088                                       jsgraph()->Float64Constant(0.0), node);
1089  } else {
1090    return TypeError(node, output_rep, output_type,
1091                     MachineRepresentation::kBit);
1092  }
1093  return jsgraph()->graph()->NewNode(op, node);
1094}
1095
1096Node* RepresentationChanger::GetWord64RepresentationFor(
1097    Node* node, MachineRepresentation output_rep, Type output_type,
1098    Node* use_node, UseInfo use_info) {
1099  // Eagerly fold representation changes for constants.
1100  switch (node->opcode()) {
1101    case IrOpcode::kInt32Constant:
1102    case IrOpcode::kInt64Constant:
1103    case IrOpcode::kFloat32Constant:
1104    case IrOpcode::kFloat64Constant:
1105      UNREACHABLE();
1106    case IrOpcode::kNumberConstant: {
1107      if (use_info.type_check() != TypeCheckKind::kBigInt) {
1108        double const fv = OpParameter<double>(node->op());
1109        if (base::IsValueInRangeForNumericType<int64_t>(fv)) {
1110          int64_t const iv = static_cast<int64_t>(fv);
1111          if (static_cast<double>(iv) == fv) {
1112            return InsertTypeOverrideForVerifier(NodeProperties::GetType(node),
1113                                                 jsgraph()->Int64Constant(iv));
1114          }
1115        }
1116      }
1117      break;
1118    }
1119    case IrOpcode::kHeapConstant: {
1120      HeapObjectMatcher m(node);
1121      if (m.HasResolvedValue() && m.Ref(broker_).IsBigInt() &&
1122          use_info.truncation().IsUsedAsWord64()) {
1123        BigIntRef bigint = m.Ref(broker_).AsBigInt();
1124        return InsertTypeOverrideForVerifier(
1125            NodeProperties::GetType(node),
1126            jsgraph()->Int64Constant(static_cast<int64_t>(bigint.AsUint64())));
1127      }
1128      break;
1129    }
1130    default:
1131      break;
1132  }
1133
1134  if (use_info.type_check() == TypeCheckKind::kBigInt) {
1135    // BigInts are only represented as tagged pointer and word64.
1136    if (!CanBeTaggedPointer(output_rep) &&
1137        output_rep != MachineRepresentation::kWord64) {
1138      DCHECK(!output_type.Equals(Type::BigInt()));
1139      Node* unreachable = InsertUnconditionalDeopt(
1140          use_node, DeoptimizeReason::kNotABigInt, use_info.feedback());
1141      return jsgraph()->graph()->NewNode(
1142          jsgraph()->common()->DeadValue(MachineRepresentation::kWord64),
1143          unreachable);
1144    }
1145  }
1146
1147  // Select the correct X -> Word64 operator.
1148  const Operator* op;
1149  if (output_type.Is(Type::None())) {
1150    // This is an impossible value; it should not be used at runtime.
1151    return jsgraph()->graph()->NewNode(
1152        jsgraph()->common()->DeadValue(MachineRepresentation::kWord64), node);
1153  } else if (output_rep == MachineRepresentation::kBit) {
1154    CHECK(output_type.Is(Type::Boolean()));
1155    CHECK_NE(use_info.type_check(), TypeCheckKind::kNone);
1156    CHECK_NE(use_info.type_check(), TypeCheckKind::kNumberOrOddball);
1157    CHECK_NE(use_info.type_check(), TypeCheckKind::kBigInt);
1158    Node* unreachable =
1159        InsertUnconditionalDeopt(use_node, DeoptimizeReason::kNotASmi);
1160    return jsgraph()->graph()->NewNode(
1161        jsgraph()->common()->DeadValue(MachineRepresentation::kWord64),
1162        unreachable);
1163  } else if (IsWord(output_rep)) {
1164    if (output_type.Is(Type::Unsigned32OrMinusZero())) {
1165      // uint32 -> uint64
1166      CHECK_IMPLIES(output_type.Maybe(Type::MinusZero()),
1167                    use_info.truncation().IdentifiesZeroAndMinusZero());
1168      op = machine()->ChangeUint32ToUint64();
1169    } else if (output_type.Is(Type::Signed32OrMinusZero())) {
1170      // int32 -> int64
1171      CHECK_IMPLIES(output_type.Maybe(Type::MinusZero()),
1172                    use_info.truncation().IdentifiesZeroAndMinusZero());
1173      op = machine()->ChangeInt32ToInt64();
1174    } else {
1175      return TypeError(node, output_rep, output_type,
1176                       MachineRepresentation::kWord64);
1177    }
1178  } else if (output_rep == MachineRepresentation::kFloat32) {
1179    if (output_type.Is(cache_->kDoubleRepresentableInt64)) {
1180      // float32 -> float64 -> int64
1181      node = InsertChangeFloat32ToFloat64(node);
1182      op = machine()->ChangeFloat64ToInt64();
1183    } else if (output_type.Is(cache_->kDoubleRepresentableUint64)) {
1184      // float32 -> float64 -> uint64
1185      node = InsertChangeFloat32ToFloat64(node);
1186      op = machine()->ChangeFloat64ToUint64();
1187    } else if (use_info.type_check() == TypeCheckKind::kSigned64 ||
1188               use_info.type_check() == TypeCheckKind::kArrayIndex) {
1189      // float32 -> float64 -> int64
1190      node = InsertChangeFloat32ToFloat64(node);
1191      op = simplified()->CheckedFloat64ToInt64(
1192          output_type.Maybe(Type::MinusZero())
1193              ? use_info.minus_zero_check()
1194              : CheckForMinusZeroMode::kDontCheckForMinusZero,
1195          use_info.feedback());
1196    } else {
1197      return TypeError(node, output_rep, output_type,
1198                       MachineRepresentation::kWord64);
1199    }
1200  } else if (output_rep == MachineRepresentation::kFloat64) {
1201    if (output_type.Is(cache_->kDoubleRepresentableInt64)) {
1202      op = machine()->ChangeFloat64ToInt64();
1203    } else if (output_type.Is(cache_->kDoubleRepresentableUint64)) {
1204      op = machine()->ChangeFloat64ToUint64();
1205    } else if (use_info.type_check() == TypeCheckKind::kSigned64 ||
1206               use_info.type_check() == TypeCheckKind::kArrayIndex) {
1207      op = simplified()->CheckedFloat64ToInt64(
1208          output_type.Maybe(Type::MinusZero())
1209              ? use_info.minus_zero_check()
1210              : CheckForMinusZeroMode::kDontCheckForMinusZero,
1211          use_info.feedback());
1212    } else {
1213      return TypeError(node, output_rep, output_type,
1214                       MachineRepresentation::kWord64);
1215    }
1216  } else if (output_rep == MachineRepresentation::kTaggedSigned) {
1217    if (output_type.Is(Type::SignedSmall())) {
1218      op = simplified()->ChangeTaggedSignedToInt64();
1219    } else {
1220      return TypeError(node, output_rep, output_type,
1221                       MachineRepresentation::kWord64);
1222    }
1223  } else if (IsAnyTagged(output_rep) &&
1224             use_info.truncation().IsUsedAsWord64() &&
1225             (use_info.type_check() == TypeCheckKind::kBigInt ||
1226              output_type.Is(Type::BigInt()))) {
1227    node = GetTaggedPointerRepresentationFor(node, output_rep, output_type,
1228                                             use_node, use_info);
1229    op = simplified()->TruncateBigIntToWord64();
1230  } else if (CanBeTaggedPointer(output_rep)) {
1231    if (output_type.Is(cache_->kDoubleRepresentableInt64)) {
1232      op = simplified()->ChangeTaggedToInt64();
1233    } else if (use_info.type_check() == TypeCheckKind::kSigned64) {
1234      op = simplified()->CheckedTaggedToInt64(
1235          output_type.Maybe(Type::MinusZero())
1236              ? use_info.minus_zero_check()
1237              : CheckForMinusZeroMode::kDontCheckForMinusZero,
1238          use_info.feedback());
1239    } else if (use_info.type_check() == TypeCheckKind::kArrayIndex) {
1240      op = simplified()->CheckedTaggedToArrayIndex(use_info.feedback());
1241    } else {
1242      return TypeError(node, output_rep, output_type,
1243                       MachineRepresentation::kWord64);
1244    }
1245  } else if (output_rep == MachineRepresentation::kWord64) {
1246    DCHECK_EQ(use_info.type_check(), TypeCheckKind::kBigInt);
1247    if (output_type.Is(Type::BigInt())) {
1248      return node;
1249    } else {
1250      Node* unreachable = InsertUnconditionalDeopt(
1251          use_node, DeoptimizeReason::kNotABigInt, use_info.feedback());
1252      return jsgraph()->graph()->NewNode(
1253          jsgraph()->common()->DeadValue(MachineRepresentation::kWord64),
1254          unreachable);
1255    }
1256  } else if (output_rep == MachineRepresentation::kSandboxedPointer) {
1257    if (output_type.Is(Type::SandboxedPointer())) {
1258      return node;
1259    } else {
1260      return TypeError(node, output_rep, output_type,
1261                       MachineRepresentation::kWord64);
1262    }
1263  } else {
1264    return TypeError(node, output_rep, output_type,
1265                     MachineRepresentation::kWord64);
1266  }
1267  return InsertConversion(node, op, use_node);
1268}
1269
1270const Operator* RepresentationChanger::Int32OperatorFor(
1271    IrOpcode::Value opcode) {
1272  switch (opcode) {
1273    case IrOpcode::kSpeculativeNumberAdd:  // Fall through.
1274    case IrOpcode::kSpeculativeSafeIntegerAdd:
1275    case IrOpcode::kNumberAdd:
1276      return machine()->Int32Add();
1277    case IrOpcode::kSpeculativeNumberSubtract:  // Fall through.
1278    case IrOpcode::kSpeculativeSafeIntegerSubtract:
1279    case IrOpcode::kNumberSubtract:
1280      return machine()->Int32Sub();
1281    case IrOpcode::kSpeculativeNumberMultiply:
1282    case IrOpcode::kNumberMultiply:
1283      return machine()->Int32Mul();
1284    case IrOpcode::kSpeculativeNumberDivide:
1285    case IrOpcode::kNumberDivide:
1286      return machine()->Int32Div();
1287    case IrOpcode::kSpeculativeNumberModulus:
1288    case IrOpcode::kNumberModulus:
1289      return machine()->Int32Mod();
1290    case IrOpcode::kSpeculativeNumberBitwiseOr:  // Fall through.
1291    case IrOpcode::kNumberBitwiseOr:
1292      return machine()->Word32Or();
1293    case IrOpcode::kSpeculativeNumberBitwiseXor:  // Fall through.
1294    case IrOpcode::kNumberBitwiseXor:
1295      return machine()->Word32Xor();
1296    case IrOpcode::kSpeculativeNumberBitwiseAnd:  // Fall through.
1297    case IrOpcode::kNumberBitwiseAnd:
1298      return machine()->Word32And();
1299    case IrOpcode::kNumberEqual:
1300    case IrOpcode::kSpeculativeNumberEqual:
1301      return machine()->Word32Equal();
1302    case IrOpcode::kNumberLessThan:
1303    case IrOpcode::kSpeculativeNumberLessThan:
1304      return machine()->Int32LessThan();
1305    case IrOpcode::kNumberLessThanOrEqual:
1306    case IrOpcode::kSpeculativeNumberLessThanOrEqual:
1307      return machine()->Int32LessThanOrEqual();
1308    default:
1309      UNREACHABLE();
1310  }
1311}
1312
1313const Operator* RepresentationChanger::Int32OverflowOperatorFor(
1314    IrOpcode::Value opcode) {
1315  switch (opcode) {
1316    case IrOpcode::kSpeculativeSafeIntegerAdd:
1317      return simplified()->CheckedInt32Add();
1318    case IrOpcode::kSpeculativeSafeIntegerSubtract:
1319      return simplified()->CheckedInt32Sub();
1320    case IrOpcode::kSpeculativeNumberDivide:
1321      return simplified()->CheckedInt32Div();
1322    case IrOpcode::kSpeculativeNumberModulus:
1323      return simplified()->CheckedInt32Mod();
1324    default:
1325      UNREACHABLE();
1326  }
1327}
1328
1329const Operator* RepresentationChanger::Int64OperatorFor(
1330    IrOpcode::Value opcode) {
1331  switch (opcode) {
1332    case IrOpcode::kSpeculativeNumberAdd:  // Fall through.
1333    case IrOpcode::kSpeculativeSafeIntegerAdd:
1334    case IrOpcode::kNumberAdd:
1335      return machine()->Int64Add();
1336    case IrOpcode::kSpeculativeNumberSubtract:  // Fall through.
1337    case IrOpcode::kSpeculativeSafeIntegerSubtract:
1338    case IrOpcode::kNumberSubtract:
1339      return machine()->Int64Sub();
1340    default:
1341      UNREACHABLE();
1342  }
1343}
1344
1345const Operator* RepresentationChanger::TaggedSignedOperatorFor(
1346    IrOpcode::Value opcode) {
1347  switch (opcode) {
1348    case IrOpcode::kSpeculativeNumberLessThan:
1349      return (COMPRESS_POINTERS_BOOL || machine()->Is32())
1350                 ? machine()->Int32LessThan()
1351                 : machine()->Int64LessThan();
1352    case IrOpcode::kSpeculativeNumberLessThanOrEqual:
1353      return (COMPRESS_POINTERS_BOOL || machine()->Is32())
1354                 ? machine()->Int32LessThanOrEqual()
1355                 : machine()->Int64LessThanOrEqual();
1356    case IrOpcode::kSpeculativeNumberEqual:
1357      return (COMPRESS_POINTERS_BOOL || machine()->Is32())
1358                 ? machine()->Word32Equal()
1359                 : machine()->Word64Equal();
1360    default:
1361      UNREACHABLE();
1362  }
1363}
1364
1365const Operator* RepresentationChanger::Uint32OperatorFor(
1366    IrOpcode::Value opcode) {
1367  switch (opcode) {
1368    case IrOpcode::kNumberAdd:
1369      return machine()->Int32Add();
1370    case IrOpcode::kNumberSubtract:
1371      return machine()->Int32Sub();
1372    case IrOpcode::kSpeculativeNumberMultiply:
1373    case IrOpcode::kNumberMultiply:
1374      return machine()->Int32Mul();
1375    case IrOpcode::kSpeculativeNumberDivide:
1376    case IrOpcode::kNumberDivide:
1377      return machine()->Uint32Div();
1378    case IrOpcode::kSpeculativeNumberModulus:
1379    case IrOpcode::kNumberModulus:
1380      return machine()->Uint32Mod();
1381    case IrOpcode::kNumberEqual:
1382    case IrOpcode::kSpeculativeNumberEqual:
1383      return machine()->Word32Equal();
1384    case IrOpcode::kNumberLessThan:
1385    case IrOpcode::kSpeculativeNumberLessThan:
1386      return machine()->Uint32LessThan();
1387    case IrOpcode::kNumberLessThanOrEqual:
1388    case IrOpcode::kSpeculativeNumberLessThanOrEqual:
1389      return machine()->Uint32LessThanOrEqual();
1390    case IrOpcode::kNumberClz32:
1391      return machine()->Word32Clz();
1392    case IrOpcode::kNumberImul:
1393      return machine()->Int32Mul();
1394    default:
1395      UNREACHABLE();
1396  }
1397}
1398
1399const Operator* RepresentationChanger::Uint32OverflowOperatorFor(
1400    IrOpcode::Value opcode) {
1401  switch (opcode) {
1402    case IrOpcode::kSpeculativeNumberDivide:
1403      return simplified()->CheckedUint32Div();
1404    case IrOpcode::kSpeculativeNumberModulus:
1405      return simplified()->CheckedUint32Mod();
1406    default:
1407      UNREACHABLE();
1408  }
1409}
1410
1411const Operator* RepresentationChanger::Float64OperatorFor(
1412    IrOpcode::Value opcode) {
1413  switch (opcode) {
1414    case IrOpcode::kSpeculativeNumberAdd:
1415    case IrOpcode::kSpeculativeSafeIntegerAdd:
1416    case IrOpcode::kNumberAdd:
1417      return machine()->Float64Add();
1418    case IrOpcode::kSpeculativeNumberSubtract:
1419    case IrOpcode::kSpeculativeSafeIntegerSubtract:
1420    case IrOpcode::kNumberSubtract:
1421      return machine()->Float64Sub();
1422    case IrOpcode::kSpeculativeNumberMultiply:
1423    case IrOpcode::kNumberMultiply:
1424      return machine()->Float64Mul();
1425    case IrOpcode::kSpeculativeNumberDivide:
1426    case IrOpcode::kNumberDivide:
1427      return machine()->Float64Div();
1428    case IrOpcode::kSpeculativeNumberModulus:
1429    case IrOpcode::kNumberModulus:
1430      return machine()->Float64Mod();
1431    case IrOpcode::kNumberEqual:
1432    case IrOpcode::kSpeculativeNumberEqual:
1433      return machine()->Float64Equal();
1434    case IrOpcode::kNumberLessThan:
1435    case IrOpcode::kSpeculativeNumberLessThan:
1436      return machine()->Float64LessThan();
1437    case IrOpcode::kNumberLessThanOrEqual:
1438    case IrOpcode::kSpeculativeNumberLessThanOrEqual:
1439      return machine()->Float64LessThanOrEqual();
1440    case IrOpcode::kNumberAbs:
1441      return machine()->Float64Abs();
1442    case IrOpcode::kNumberAcos:
1443      return machine()->Float64Acos();
1444    case IrOpcode::kNumberAcosh:
1445      return machine()->Float64Acosh();
1446    case IrOpcode::kNumberAsin:
1447      return machine()->Float64Asin();
1448    case IrOpcode::kNumberAsinh:
1449      return machine()->Float64Asinh();
1450    case IrOpcode::kNumberAtan:
1451      return machine()->Float64Atan();
1452    case IrOpcode::kNumberAtanh:
1453      return machine()->Float64Atanh();
1454    case IrOpcode::kNumberAtan2:
1455      return machine()->Float64Atan2();
1456    case IrOpcode::kNumberCbrt:
1457      return machine()->Float64Cbrt();
1458    case IrOpcode::kNumberCeil:
1459      return machine()->Float64RoundUp().placeholder();
1460    case IrOpcode::kNumberCos:
1461      return machine()->Float64Cos();
1462    case IrOpcode::kNumberCosh:
1463      return machine()->Float64Cosh();
1464    case IrOpcode::kNumberExp:
1465      return machine()->Float64Exp();
1466    case IrOpcode::kNumberExpm1:
1467      return machine()->Float64Expm1();
1468    case IrOpcode::kNumberFloor:
1469      return machine()->Float64RoundDown().placeholder();
1470    case IrOpcode::kNumberFround:
1471      return machine()->TruncateFloat64ToFloat32();
1472    case IrOpcode::kNumberLog:
1473      return machine()->Float64Log();
1474    case IrOpcode::kNumberLog1p:
1475      return machine()->Float64Log1p();
1476    case IrOpcode::kNumberLog2:
1477      return machine()->Float64Log2();
1478    case IrOpcode::kNumberLog10:
1479      return machine()->Float64Log10();
1480    case IrOpcode::kNumberMax:
1481      return machine()->Float64Max();
1482    case IrOpcode::kNumberMin:
1483      return machine()->Float64Min();
1484    case IrOpcode::kSpeculativeNumberPow:
1485    case IrOpcode::kNumberPow:
1486      return machine()->Float64Pow();
1487    case IrOpcode::kNumberSin:
1488      return machine()->Float64Sin();
1489    case IrOpcode::kNumberSinh:
1490      return machine()->Float64Sinh();
1491    case IrOpcode::kNumberSqrt:
1492      return machine()->Float64Sqrt();
1493    case IrOpcode::kNumberTan:
1494      return machine()->Float64Tan();
1495    case IrOpcode::kNumberTanh:
1496      return machine()->Float64Tanh();
1497    case IrOpcode::kNumberTrunc:
1498      return machine()->Float64RoundTruncate().placeholder();
1499    case IrOpcode::kNumberSilenceNaN:
1500      return machine()->Float64SilenceNaN();
1501    default:
1502      UNREACHABLE();
1503  }
1504}
1505
1506Node* RepresentationChanger::TypeError(Node* node,
1507                                       MachineRepresentation output_rep,
1508                                       Type output_type,
1509                                       MachineRepresentation use) {
1510  type_error_ = true;
1511  if (!testing_type_errors_) {
1512    std::ostringstream out_str;
1513    out_str << output_rep << " (";
1514    output_type.PrintTo(out_str);
1515    out_str << ")";
1516
1517    std::ostringstream use_str;
1518    use_str << use;
1519
1520    FATAL(
1521        "RepresentationChangerError: node #%d:%s of "
1522        "%s cannot be changed to %s",
1523        node->id(), node->op()->mnemonic(), out_str.str().c_str(),
1524        use_str.str().c_str());
1525  }
1526  return node;
1527}
1528
1529Node* RepresentationChanger::InsertChangeBitToTagged(Node* node) {
1530  return jsgraph()->graph()->NewNode(simplified()->ChangeBitToTagged(), node);
1531}
1532
1533Node* RepresentationChanger::InsertChangeFloat32ToFloat64(Node* node) {
1534  return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(), node);
1535}
1536
1537Node* RepresentationChanger::InsertChangeFloat64ToUint32(Node* node) {
1538  return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToUint32(), node);
1539}
1540
1541Node* RepresentationChanger::InsertChangeFloat64ToInt32(Node* node) {
1542  return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToInt32(), node);
1543}
1544
1545Node* RepresentationChanger::InsertChangeInt32ToFloat64(Node* node) {
1546  return jsgraph()->graph()->NewNode(machine()->ChangeInt32ToFloat64(), node);
1547}
1548
1549Node* RepresentationChanger::InsertChangeTaggedSignedToInt32(Node* node) {
1550  return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(),
1551                                     node);
1552}
1553
1554Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) {
1555  return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
1556                                     node);
1557}
1558
1559Node* RepresentationChanger::InsertChangeUint32ToFloat64(Node* node) {
1560  return jsgraph()->graph()->NewNode(machine()->ChangeUint32ToFloat64(), node);
1561}
1562
1563Node* RepresentationChanger::InsertTruncateInt64ToInt32(Node* node) {
1564  return jsgraph()->graph()->NewNode(machine()->TruncateInt64ToInt32(), node);
1565}
1566
1567Node* RepresentationChanger::InsertCheckedFloat64ToInt32(
1568    Node* node, CheckForMinusZeroMode check, const FeedbackSource& feedback,
1569    Node* use_node) {
1570  return InsertConversion(
1571      node, simplified()->CheckedFloat64ToInt32(check, feedback), use_node);
1572}
1573
1574Node* RepresentationChanger::InsertTypeOverrideForVerifier(const Type& type,
1575                                                           Node* node) {
1576  if (verification_enabled()) {
1577    DCHECK(!type.IsInvalid());
1578    node = jsgraph()->graph()->NewNode(
1579        jsgraph()->common()->SLVerifierHint(nullptr, type), node);
1580    verifier_->RecordHint(node);
1581  }
1582  return node;
1583}
1584
1585Isolate* RepresentationChanger::isolate() const { return broker_->isolate(); }
1586
1587}  // namespace compiler
1588}  // namespace internal
1589}  // namespace v8
1590