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); |
} |