| Index: src/compiler/representation-change.cc
|
| diff --git a/src/compiler/representation-change.cc b/src/compiler/representation-change.cc
|
| index 2f7720beb3705599929416c442e2f1ab910677dc..ac5766a0e8a5dbf9fc94bc687fcfe1639483092e 100644
|
| --- a/src/compiler/representation-change.cc
|
| +++ b/src/compiler/representation-change.cc
|
| @@ -142,7 +142,8 @@ Node* RepresentationChanger::GetRepresentationFor(
|
| case MachineRepresentation::kWord8:
|
| case MachineRepresentation::kWord16:
|
| case MachineRepresentation::kWord32:
|
| - return GetWord32RepresentationFor(node, output_rep, output_type);
|
| + return GetWord32RepresentationFor(node, output_rep, output_type,
|
| + truncation);
|
| case MachineRepresentation::kWord64:
|
| return GetWord64RepresentationFor(node, output_rep, output_type);
|
| case MachineRepresentation::kSimd128: // Fall through.
|
| @@ -234,30 +235,34 @@ Node* RepresentationChanger::GetFloat32RepresentationFor(
|
| break;
|
| }
|
| // Select the correct X -> Float32 operator.
|
| - const Operator* op;
|
| - if (output_rep == MachineRepresentation::kBit) {
|
| - return TypeError(node, output_rep, output_type,
|
| - MachineRepresentation::kFloat32);
|
| - } else if (IsWord(output_rep)) {
|
| + const Operator* op = nullptr;
|
| + if (IsWord(output_rep)) {
|
| if (output_type->Is(Type::Signed32())) {
|
| + // int32 -> float64 -> float32
|
| op = machine()->ChangeInt32ToFloat64();
|
| - } else {
|
| - // Either the output is int32 or the uses only care about the
|
| - // low 32 bits (so we can pick int32 safely).
|
| - DCHECK(output_type->Is(Type::Unsigned32()) ||
|
| - truncation.TruncatesToWord32());
|
| + node = jsgraph()->graph()->NewNode(op, node);
|
| + op = machine()->TruncateFloat64ToFloat32();
|
| + } else if (output_type->Is(Type::Unsigned32()) ||
|
| + truncation.TruncatesToWord32()) {
|
| + // Either the output is uint32 or the uses only care about the
|
| + // low 32 bits (so we can pick uint32 safely).
|
| +
|
| + // uint32 -> float64 -> float32
|
| op = machine()->ChangeUint32ToFloat64();
|
| + node = jsgraph()->graph()->NewNode(op, node);
|
| + op = machine()->TruncateFloat64ToFloat32();
|
| }
|
| - // int32 -> float64 -> float32
|
| - node = jsgraph()->graph()->NewNode(op, node);
|
| - op = machine()->TruncateFloat64ToFloat32();
|
| } else if (output_rep == MachineRepresentation::kTagged) {
|
| - op = simplified()->ChangeTaggedToFloat64(); // tagged -> float64 -> float32
|
| - node = jsgraph()->graph()->NewNode(op, node);
|
| - op = machine()->TruncateFloat64ToFloat32();
|
| + if (output_type->Is(Type::Number())) {
|
| + op = simplified()
|
| + ->ChangeTaggedToFloat64(); // tagged -> float64 -> float32
|
| + node = jsgraph()->graph()->NewNode(op, node);
|
| + op = machine()->TruncateFloat64ToFloat32();
|
| + }
|
| } else if (output_rep == MachineRepresentation::kFloat64) {
|
| op = machine()->TruncateFloat64ToFloat32();
|
| - } else {
|
| + }
|
| + if (op == nullptr) {
|
| return TypeError(node, output_rep, output_type,
|
| MachineRepresentation::kFloat32);
|
| }
|
| @@ -289,25 +294,24 @@ Node* RepresentationChanger::GetFloat64RepresentationFor(
|
| break;
|
| }
|
| // Select the correct X -> Float64 operator.
|
| - const Operator* op;
|
| - if (output_rep == MachineRepresentation::kBit) {
|
| - return TypeError(node, output_rep, output_type,
|
| - MachineRepresentation::kFloat64);
|
| - } else if (IsWord(output_rep)) {
|
| + const Operator* op = nullptr;
|
| + if (IsWord(output_rep)) {
|
| if (output_type->Is(Type::Signed32())) {
|
| op = machine()->ChangeInt32ToFloat64();
|
| - } else {
|
| - // Either the output is int32 or the uses only care about the
|
| - // low 32 bits (so we can pick int32 safely).
|
| - DCHECK(output_type->Is(Type::Unsigned32()) ||
|
| - truncation.TruncatesToWord32());
|
| + } else if (output_type->Is(Type::Unsigned32()) ||
|
| + truncation.TruncatesToWord32()) {
|
| + // Either the output is uint32 or the uses only care about the
|
| + // low 32 bits (so we can pick uint32 safely).
|
| op = machine()->ChangeUint32ToFloat64();
|
| }
|
| } else if (output_rep == MachineRepresentation::kTagged) {
|
| - op = simplified()->ChangeTaggedToFloat64();
|
| + if (output_type->Is(Type::Number())) {
|
| + op = simplified()->ChangeTaggedToFloat64();
|
| + }
|
| } else if (output_rep == MachineRepresentation::kFloat32) {
|
| op = machine()->ChangeFloat32ToFloat64();
|
| - } else {
|
| + }
|
| + if (op == nullptr) {
|
| return TypeError(node, output_rep, output_type,
|
| MachineRepresentation::kFloat64);
|
| }
|
| @@ -319,9 +323,9 @@ Node* RepresentationChanger::MakeTruncatedInt32Constant(double value) {
|
| return jsgraph()->Int32Constant(DoubleToInt32(value));
|
| }
|
|
|
| -
|
| Node* RepresentationChanger::GetWord32RepresentationFor(
|
| - Node* node, MachineRepresentation output_rep, Type* output_type) {
|
| + Node* node, MachineRepresentation output_rep, Type* output_type,
|
| + Truncation truncation) {
|
| // Eagerly fold representation changes for constants.
|
| switch (node->opcode()) {
|
| case IrOpcode::kInt32Constant:
|
| @@ -335,43 +339,37 @@ Node* RepresentationChanger::GetWord32RepresentationFor(
|
| break;
|
| }
|
| // Select the correct X -> Word32 operator.
|
| - const Operator* op;
|
| - Type* type = NodeProperties::GetType(node);
|
| -
|
| + const Operator* op = nullptr;
|
| if (output_rep == MachineRepresentation::kBit) {
|
| return node; // Sloppy comparison -> word32
|
| } else if (output_rep == MachineRepresentation::kFloat64) {
|
| - // TODO(jarin) Use only output_type here, once we intersect it with the
|
| - // type inferred by the typer.
|
| - if (output_type->Is(Type::Unsigned32()) || type->Is(Type::Unsigned32())) {
|
| + if (output_type->Is(Type::Unsigned32())) {
|
| op = machine()->ChangeFloat64ToUint32();
|
| - } else if (output_type->Is(Type::Signed32()) ||
|
| - type->Is(Type::Signed32())) {
|
| + } else if (output_type->Is(Type::Signed32())) {
|
| op = machine()->ChangeFloat64ToInt32();
|
| - } else {
|
| + } else if (truncation.TruncatesToWord32()) {
|
| op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
|
| }
|
| } else if (output_rep == MachineRepresentation::kFloat32) {
|
| node = InsertChangeFloat32ToFloat64(node); // float32 -> float64 -> int32
|
| - if (output_type->Is(Type::Unsigned32()) || type->Is(Type::Unsigned32())) {
|
| + if (output_type->Is(Type::Unsigned32())) {
|
| op = machine()->ChangeFloat64ToUint32();
|
| - } else if (output_type->Is(Type::Signed32()) ||
|
| - type->Is(Type::Signed32())) {
|
| + } else if (output_type->Is(Type::Signed32())) {
|
| op = machine()->ChangeFloat64ToInt32();
|
| - } else {
|
| + } else if (truncation.TruncatesToWord32()) {
|
| op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
|
| }
|
| } else if (output_rep == MachineRepresentation::kTagged) {
|
| - if (output_type->Is(Type::Unsigned32()) || type->Is(Type::Unsigned32())) {
|
| + if (output_type->Is(Type::Unsigned32())) {
|
| op = simplified()->ChangeTaggedToUint32();
|
| - } else if (output_type->Is(Type::Signed32()) ||
|
| - type->Is(Type::Signed32())) {
|
| + } else if (output_type->Is(Type::Signed32())) {
|
| op = simplified()->ChangeTaggedToInt32();
|
| - } else {
|
| + } else if (truncation.TruncatesToWord32()) {
|
| node = InsertChangeTaggedToFloat64(node);
|
| op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
|
| }
|
| - } else {
|
| + }
|
| + if (op == nullptr) {
|
| return TypeError(node, output_rep, output_type,
|
| MachineRepresentation::kWord32);
|
| }
|
|
|