Merge V8 5.3.332.45.  DO NOT MERGE

Test: Manual

FPIIM-449

Change-Id: Id3254828b068abdea3cb10442e0172a8c9a98e03
(cherry picked from commit 13e2dadd00298019ed862f2b2fc5068bba730bcf)
diff --git a/src/compiler/representation-change.h b/src/compiler/representation-change.h
index 839335d..8a38644 100644
--- a/src/compiler/representation-change.h
+++ b/src/compiler/representation-change.h
@@ -73,6 +73,86 @@
   static bool LessGeneral(TruncationKind rep1, TruncationKind rep2);
 };
 
+enum class TypeCheckKind : uint8_t {
+  kNone,
+  kSigned32,
+  kNumberOrUndefined,
+  kNumber
+};
+
+// The {UseInfo} class is used to describe a use of an input of a node.
+//
+// This information is used in two different ways, based on the phase:
+//
+// 1. During propagation, the use info is used to inform the input node
+//    about what part of the input is used (we call this truncation) and what
+//    is the preferred representation.
+//
+// 2. During lowering, the use info is used to properly convert the input
+//    to the preferred representation. The preferred representation might be
+//    insufficient to do the conversion (e.g. word32->float64 conv), so we also
+//    need the signedness information to produce the correct value.
+class UseInfo {
+ public:
+  UseInfo(MachineRepresentation representation, Truncation truncation,
+          TypeCheckKind type_check = TypeCheckKind::kNone)
+      : representation_(representation),
+        truncation_(truncation),
+        type_check_(type_check) {}
+  static UseInfo TruncatingWord32() {
+    return UseInfo(MachineRepresentation::kWord32, Truncation::Word32());
+  }
+  static UseInfo TruncatingWord64() {
+    return UseInfo(MachineRepresentation::kWord64, Truncation::Word64());
+  }
+  static UseInfo Bool() {
+    return UseInfo(MachineRepresentation::kBit, Truncation::Bool());
+  }
+  static UseInfo TruncatingFloat32() {
+    return UseInfo(MachineRepresentation::kFloat32, Truncation::Float32());
+  }
+  static UseInfo TruncatingFloat64() {
+    return UseInfo(MachineRepresentation::kFloat64, Truncation::Float64());
+  }
+  static UseInfo PointerInt() {
+    return kPointerSize == 4 ? TruncatingWord32() : TruncatingWord64();
+  }
+  static UseInfo AnyTagged() {
+    return UseInfo(MachineRepresentation::kTagged, Truncation::Any());
+  }
+
+  // Possibly deoptimizing conversions.
+  static UseInfo CheckedSigned32AsWord32() {
+    return UseInfo(MachineRepresentation::kWord32, Truncation::Any(),
+                   TypeCheckKind::kSigned32);
+  }
+  static UseInfo CheckedNumberOrUndefinedAsFloat64() {
+    return UseInfo(MachineRepresentation::kFloat64, Truncation::Any(),
+                   TypeCheckKind::kNumberOrUndefined);
+  }
+
+  // Undetermined representation.
+  static UseInfo Any() {
+    return UseInfo(MachineRepresentation::kNone, Truncation::Any());
+  }
+  static UseInfo AnyTruncatingToBool() {
+    return UseInfo(MachineRepresentation::kNone, Truncation::Bool());
+  }
+
+  // Value not used.
+  static UseInfo None() {
+    return UseInfo(MachineRepresentation::kNone, Truncation::None());
+  }
+
+  MachineRepresentation representation() const { return representation_; }
+  Truncation truncation() const { return truncation_; }
+  TypeCheckKind type_check() const { return type_check_; }
+
+ private:
+  MachineRepresentation representation_;
+  Truncation truncation_;
+  TypeCheckKind type_check_;
+};
 
 // Contains logic related to changing the representation of values for constants
 // and other nodes, as well as lowering Simplified->Machine operators.
@@ -90,9 +170,10 @@
   // out signedness for the word32->float64 conversion, then we check that the
   // uses truncate to word32 (so they do not care about signedness).
   Node* GetRepresentationFor(Node* node, MachineRepresentation output_rep,
-                             Type* output_type, MachineRepresentation use_rep,
-                             Truncation truncation = Truncation::None());
+                             Type* output_type, Node* use_node,
+                             UseInfo use_info);
   const Operator* Int32OperatorFor(IrOpcode::Value opcode);
+  const Operator* Int32OverflowOperatorFor(IrOpcode::Value opcode);
   const Operator* Uint32OperatorFor(IrOpcode::Value opcode);
   const Operator* Float64OperatorFor(IrOpcode::Value opcode);
 
@@ -122,13 +203,20 @@
                                     Type* output_type, Truncation truncation);
   Node* GetFloat64RepresentationFor(Node* node,
                                     MachineRepresentation output_rep,
-                                    Type* output_type, Truncation truncation);
+                                    Type* output_type, Node* use_node,
+                                    UseInfo use_info);
   Node* GetWord32RepresentationFor(Node* node, MachineRepresentation output_rep,
-                                   Type* output_type, Truncation truncation);
+                                   Type* output_type, Node* use_node,
+                                   UseInfo use_info);
   Node* GetBitRepresentationFor(Node* node, MachineRepresentation output_rep,
                                 Type* output_type);
   Node* GetWord64RepresentationFor(Node* node, MachineRepresentation output_rep,
                                    Type* output_type);
+  Node* GetCheckedWord32RepresentationFor(Node* node,
+                                          MachineRepresentation output_rep,
+                                          Type* output_type, Node* use_node,
+                                          Truncation truncation,
+                                          TypeCheckKind check);
   Node* TypeError(Node* node, MachineRepresentation output_rep,
                   Type* output_type, MachineRepresentation use);
   Node* MakeTruncatedInt32Constant(double value);
@@ -138,6 +226,8 @@
   Node* InsertChangeTaggedSignedToInt32(Node* node);
   Node* InsertChangeTaggedToFloat64(Node* node);
 
+  Node* InsertConversion(Node* node, const Operator* op, Node* use_node);
+
   JSGraph* jsgraph() const { return jsgraph_; }
   Isolate* isolate() const { return isolate_; }
   Factory* factory() const { return isolate()->factory(); }