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

[turbofan] Only infer signedness for Float64->Word32 representation change from the input type.

If the input type does not help us, we are conservative and truncate (rather than guessing signed).

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

Cr-Commit-Position: refs/heads/master@{#32075}
parent 23bf71d7
...@@ -58,8 +58,7 @@ class RepresentationChanger { ...@@ -58,8 +58,7 @@ class RepresentationChanger {
} 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)) {
return GetWord32RepresentationFor(node, output_type, return GetWord32RepresentationFor(node, output_type);
use_type & kTypeUint32);
} else if (use_type & kRepWord64) { } else if (use_type & kRepWord64) {
return GetWord64RepresentationFor(node, output_type); return GetWord64RepresentationFor(node, output_type);
} else { } else {
...@@ -245,8 +244,7 @@ class RepresentationChanger { ...@@ -245,8 +244,7 @@ class RepresentationChanger {
return jsgraph()->graph()->NewNode(op, node); return jsgraph()->graph()->NewNode(op, node);
} }
Node* GetWord32RepresentationFor(Node* node, MachineTypeUnion output_type, Node* GetWord32RepresentationFor(Node* node, MachineTypeUnion output_type) {
bool use_unsigned) {
// Eagerly fold representation changes for constants. // Eagerly fold representation changes for constants.
switch (node->opcode()) { switch (node->opcode()) {
case IrOpcode::kInt32Constant: case IrOpcode::kInt32Constant:
...@@ -261,26 +259,34 @@ class RepresentationChanger { ...@@ -261,26 +259,34 @@ 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);
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) {
if (output_type & kTypeUint32 || use_unsigned) { if (output_type & kTypeUint32 || type->Is(Type::Unsigned32())) {
op = machine()->ChangeFloat64ToUint32(); op = machine()->ChangeFloat64ToUint32();
} else { } else if (output_type & kTypeInt32 || type->Is(Type::Signed32())) {
op = machine()->ChangeFloat64ToInt32(); op = machine()->ChangeFloat64ToInt32();
} else {
op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
} }
} else if (output_type & kRepFloat32) { } else if (output_type & kRepFloat32) {
node = InsertChangeFloat32ToFloat64(node); // float32 -> float64 -> int32 node = InsertChangeFloat32ToFloat64(node); // float32 -> float64 -> int32
if (output_type & kTypeUint32 || use_unsigned) { if (output_type & kTypeUint32 || type->Is(Type::Unsigned32())) {
op = machine()->ChangeFloat64ToUint32(); op = machine()->ChangeFloat64ToUint32();
} else { } else if (output_type & kTypeInt32 || type->Is(Type::Signed32())) {
op = machine()->ChangeFloat64ToInt32(); op = machine()->ChangeFloat64ToInt32();
} else {
op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
} }
} else if (output_type & kRepTagged) { } else if (output_type & kRepTagged) {
if (output_type & kTypeUint32 || use_unsigned) { if (output_type & kTypeUint32 || type->Is(Type::Unsigned32())) {
op = simplified()->ChangeTaggedToUint32(); op = simplified()->ChangeTaggedToUint32();
} else { } else if (output_type & kTypeInt32 || type->Is(Type::Signed32())) {
op = simplified()->ChangeTaggedToInt32(); op = simplified()->ChangeTaggedToInt32();
} else {
node = InsertChangeTaggedToFloat64(node);
op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
} }
} else { } else {
return TypeError(node, output_type, kRepWord32); return TypeError(node, output_type, kRepWord32);
......
...@@ -81,7 +81,9 @@ class RepresentationChangerTester : public HandleAndZoneScope, ...@@ -81,7 +81,9 @@ class RepresentationChangerTester : public HandleAndZoneScope,
} }
Node* Parameter(int index = 0) { Node* Parameter(int index = 0) {
return graph()->NewNode(common()->Parameter(index), graph()->start()); Node* n = graph()->NewNode(common()->Parameter(index), graph()->start());
NodeProperties::SetType(n, Type::Any());
return n;
} }
void CheckTypeError(MachineTypeUnion from, MachineTypeUnion to) { void CheckTypeError(MachineTypeUnion from, MachineTypeUnion to) {
...@@ -451,17 +453,19 @@ TEST(SignednessInWord32) { ...@@ -451,17 +453,19 @@ TEST(SignednessInWord32) {
RepresentationChangerTester r; RepresentationChangerTester r;
// TODO(titzer): assume that uses of a word32 without a sign mean kTypeInt32. // TODO(titzer): assume that uses of a word32 without a sign mean kTypeInt32.
CheckChange(IrOpcode::kChangeTaggedToInt32, kRepTagged, CheckChange(IrOpcode::kChangeTaggedToInt32, kRepTagged | kTypeInt32,
kRepWord32 | kTypeInt32); kRepWord32 | kTypeInt32);
CheckChange(IrOpcode::kChangeTaggedToUint32, kRepTagged, CheckChange(IrOpcode::kChangeTaggedToUint32, kRepTagged | kTypeUint32,
kRepWord32 | kTypeUint32); kRepWord32 | kTypeUint32);
CheckChange(IrOpcode::kChangeInt32ToFloat64, kRepWord32, kRepFloat64); CheckChange(IrOpcode::kChangeInt32ToFloat64, kRepWord32, kRepFloat64);
CheckChange(IrOpcode::kChangeFloat64ToInt32, kRepFloat64, kRepWord32); CheckChange(IrOpcode::kChangeFloat64ToInt32, kRepFloat64 | kTypeInt32,
kRepWord32);
CheckChange(IrOpcode::kTruncateFloat64ToInt32, kRepFloat64, kRepWord32);
CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64, CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64,
IrOpcode::kTruncateFloat64ToFloat32, kRepWord32, kRepFloat32); IrOpcode::kTruncateFloat64ToFloat32, kRepWord32, kRepFloat32);
CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64, CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
IrOpcode::kChangeFloat64ToInt32, kRepFloat32, kRepWord32); IrOpcode::kTruncateFloat64ToInt32, kRepFloat32, kRepWord32);
} }
......
...@@ -1203,10 +1203,11 @@ TEST(LowerStringOps_to_call_and_compare) { ...@@ -1203,10 +1203,11 @@ TEST(LowerStringOps_to_call_and_compare) {
} }
void CheckChangeInsertion(IrOpcode::Value expected, MachineType from, void CheckChangeInsertion(IrOpcode::Value expected, MachineType from,
MachineType to) { MachineType to, Type* type = Type::Any()) {
TestingGraph t(Type::Any()); TestingGraph t(Type::Any());
Node* in = t.ExampleWithOutput(from); Node* in = t.ExampleWithOutput(from);
NodeProperties::SetType(in, type);
Node* use = t.Use(in, to); Node* use = t.Use(in, to);
t.Return(use); t.Return(use);
t.Lower(); t.Lower();
...@@ -1216,13 +1217,16 @@ void CheckChangeInsertion(IrOpcode::Value expected, MachineType from, ...@@ -1216,13 +1217,16 @@ void CheckChangeInsertion(IrOpcode::Value expected, MachineType from,
TEST(InsertBasicChanges) { TEST(InsertBasicChanges) {
CheckChangeInsertion(IrOpcode::kChangeFloat64ToInt32, kRepFloat64, CheckChangeInsertion(IrOpcode::kChangeFloat64ToInt32, kRepFloat64, kTypeInt32,
kTypeInt32); Type::Signed32());
CheckChangeInsertion(IrOpcode::kChangeFloat64ToUint32, kRepFloat64, CheckChangeInsertion(IrOpcode::kChangeFloat64ToUint32, kRepFloat64,
kTypeUint32); kTypeUint32, Type::Unsigned32());
CheckChangeInsertion(IrOpcode::kChangeTaggedToInt32, kRepTagged, kTypeInt32); CheckChangeInsertion(IrOpcode::kTruncateFloat64ToInt32, kRepFloat64,
CheckChangeInsertion(IrOpcode::kChangeTaggedToUint32, kRepTagged, kTypeUint32, Type::Integral32());
kTypeUint32); CheckChangeInsertion(IrOpcode::kChangeTaggedToInt32, kRepTagged, kTypeInt32,
Type::Signed32());
CheckChangeInsertion(IrOpcode::kChangeTaggedToUint32, kRepTagged, kTypeUint32,
Type::Unsigned32());
CheckChangeInsertion(IrOpcode::kChangeFloat64ToTagged, kRepFloat64, CheckChangeInsertion(IrOpcode::kChangeFloat64ToTagged, kRepFloat64,
kRepTagged); kRepTagged);
......
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
var f = (function () {
"use asm";
var f64use = 0;
function f(x, b) {
x = x|0;
b = b >>> 0;
var f64 = x ? -1 : b;
f64use = f64 + 0.5;
var w32 = x ? 1 : f64;
return (w32 + 1)|0;
}
return f;
})();
%OptimizeFunctionOnNextCall(f);
assertEquals(0, f(0, -1));
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