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