Commit e5ea13e2 authored by jarin's avatar jarin Committed by Commit bot

[turbofan] Check word32 -> float64 conversion with input type/output truncation.

This makes sure we are using the right signedness - either the input
specifies signedness or the use must declare it does not care.

This requires some hole-punching in for-in so that the
representation selector understands the smi-ness of index.
Moreover, phi needs to pass the truncation along (maybe
slightly scary).

Review URL: https://codereview.chromium.org/1455123002

Cr-Commit-Position: refs/heads/master@{#32081}
parent 1582f37c
...@@ -54,7 +54,7 @@ class RepresentationChanger { ...@@ -54,7 +54,7 @@ class RepresentationChanger {
} else if (use_type & kRepFloat32) { } else if (use_type & kRepFloat32) {
return GetFloat32RepresentationFor(node, output_type); return GetFloat32RepresentationFor(node, output_type);
} else if (use_type & kRepFloat64) { } else if (use_type & kRepFloat64) {
return GetFloat64RepresentationFor(node, output_type); return GetFloat64RepresentationFor(node, output_type, use_type);
} else if (use_type & kRepBit) { } else if (use_type & kRepBit) {
return GetBitRepresentationFor(node, output_type); return GetBitRepresentationFor(node, output_type);
} else if (IsWord(use_type)) { } else if (IsWord(use_type)) {
...@@ -161,7 +161,8 @@ class RepresentationChanger { ...@@ -161,7 +161,8 @@ class RepresentationChanger {
return jsgraph()->graph()->NewNode(op, node); return jsgraph()->graph()->NewNode(op, node);
} }
Node* GetFloat64RepresentationFor(Node* node, MachineTypeUnion output_type) { Node* GetFloat64RepresentationFor(Node* node, MachineTypeUnion output_type,
MachineTypeUnion use_type) {
// Eagerly fold representation changes for constants. // Eagerly fold representation changes for constants.
switch (node->opcode()) { switch (node->opcode()) {
case IrOpcode::kNumberConstant: case IrOpcode::kNumberConstant:
...@@ -189,6 +190,10 @@ class RepresentationChanger { ...@@ -189,6 +190,10 @@ class RepresentationChanger {
if (output_type & kTypeUint32) { if (output_type & kTypeUint32) {
op = machine()->ChangeUint32ToFloat64(); op = machine()->ChangeUint32ToFloat64();
} else { } 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 & kTypeInt32 ||
!(use_type & ~(kTypeInt32 | kTypeUint32 | kRepMask)));
op = machine()->ChangeInt32ToFloat64(); op = machine()->ChangeInt32ToFloat64();
} }
} else if (output_type & kRepTagged) { } else if (output_type & kRepTagged) {
...@@ -260,6 +265,7 @@ class RepresentationChanger { ...@@ -260,6 +265,7 @@ class RepresentationChanger {
// Select the correct X -> Word32 operator. // Select the correct X -> Word32 operator.
const Operator* op; const Operator* op;
Type* type = NodeProperties::GetType(node); Type* type = NodeProperties::GetType(node);
if (output_type & kRepBit) { if (output_type & kRepBit) {
return node; // Sloppy comparison -> word32 return node; // Sloppy comparison -> word32
} else if (output_type & kRepFloat64) { } else if (output_type & kRepFloat64) {
......
...@@ -400,20 +400,15 @@ class RepresentationSelector { ...@@ -400,20 +400,15 @@ class RepresentationSelector {
if (type != OpParameter<MachineType>(node)) { if (type != OpParameter<MachineType>(node)) {
NodeProperties::ChangeOp(node, lowering->common()->Phi(type, values)); NodeProperties::ChangeOp(node, lowering->common()->Phi(type, values));
} }
// Convert inputs to the output representation of this phi.
for (int i = 0; i < node->InputCount(); i++) {
ProcessInput(node, i, i < values ? output_type : 0);
} }
} else {
// Propagate {use} of the phi to value inputs, and 0 to control. // Convert inputs to the output representation of this phi, pass the
MachineType use_type = // use truncation along.
static_cast<MachineType>((use & kTypeMask) | output); MachineType use_type = static_cast<MachineType>((use & kTypeMask) | output);
for (int i = 0; i < node->InputCount(); i++) { for (int i = 0; i < node->InputCount(); i++) {
ProcessInput(node, i, i < values ? use_type : 0); ProcessInput(node, i, i < values ? use_type : 0);
} }
} }
}
void VisitCall(Node* node, SimplifiedLowering* lowering) { void VisitCall(Node* node, SimplifiedLowering* lowering) {
const CallDescriptor* desc = OpParameter<const CallDescriptor*>(node->op()); const CallDescriptor* desc = OpParameter<const CallDescriptor*>(node->op());
......
...@@ -282,7 +282,7 @@ endmacro ...@@ -282,7 +282,7 @@ endmacro
function CubeRoot(x) { function CubeRoot(x) {
var approx_hi = MathFloorJS(%_DoubleHi(x) / 3) + 0x2A9F7893; var approx_hi = MathFloorJS(%_DoubleHi(x) / 3) + 0x2A9F7893;
var approx = %_ConstructDouble(approx_hi, 0); var approx = %_ConstructDouble(approx_hi | 0, 0);
approx = NEWTON_ITERATION_CBRT(x, approx); approx = NEWTON_ITERATION_CBRT(x, approx);
approx = NEWTON_ITERATION_CBRT(x, approx); approx = NEWTON_ITERATION_CBRT(x, approx);
approx = NEWTON_ITERATION_CBRT(x, approx); approx = NEWTON_ITERATION_CBRT(x, approx);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment