Commit 5e96f47b authored by jarin's avatar jarin Committed by Commit bot

[turbofan] Distinguish between change- and truncate-tagged-to-float64.

This prevents the compiler from optimizing
  f64-to-tagged(tagged-to-f64(x)) ==> x
for non-number x (such as undefined).

Review-Url: https://codereview.chromium.org/2027593002
Cr-Commit-Position: refs/heads/master@{#36613}
parent 1f518684
...@@ -384,6 +384,9 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node, Node** effect, ...@@ -384,6 +384,9 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node, Node** effect,
case IrOpcode::kChangeTaggedToFloat64: case IrOpcode::kChangeTaggedToFloat64:
state = LowerChangeTaggedToFloat64(node, *effect, *control); state = LowerChangeTaggedToFloat64(node, *effect, *control);
break; break;
case IrOpcode::kTruncateTaggedToFloat64:
state = LowerTruncateTaggedToFloat64(node, *effect, *control);
break;
case IrOpcode::kTruncateTaggedToWord32: case IrOpcode::kTruncateTaggedToWord32:
state = LowerTruncateTaggedToWord32(node, *effect, *control); state = LowerTruncateTaggedToWord32(node, *effect, *control);
break; break;
...@@ -661,6 +664,12 @@ EffectControlLinearizer::LowerChangeTaggedToUint32(Node* node, Node* effect, ...@@ -661,6 +664,12 @@ EffectControlLinearizer::LowerChangeTaggedToUint32(Node* node, Node* effect,
EffectControlLinearizer::ValueEffectControl EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerChangeTaggedToFloat64(Node* node, Node* effect, EffectControlLinearizer::LowerChangeTaggedToFloat64(Node* node, Node* effect,
Node* control) { Node* control) {
return LowerTruncateTaggedToFloat64(node, effect, control);
}
EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerTruncateTaggedToFloat64(Node* node, Node* effect,
Node* control) {
Node* value = node->InputAt(0); Node* value = node->InputAt(0);
Node* check = ObjectIsSmi(value); Node* check = ObjectIsSmi(value);
......
...@@ -62,6 +62,8 @@ class EffectControlLinearizer { ...@@ -62,6 +62,8 @@ class EffectControlLinearizer {
Node* control); Node* control);
ValueEffectControl LowerChangeTaggedToFloat64(Node* node, Node* effect, ValueEffectControl LowerChangeTaggedToFloat64(Node* node, Node* effect,
Node* control); Node* control);
ValueEffectControl LowerTruncateTaggedToFloat64(Node* node, Node* effect,
Node* control);
ValueEffectControl LowerTruncateTaggedToWord32(Node* node, Node* effect, ValueEffectControl LowerTruncateTaggedToWord32(Node* node, Node* effect,
Node* control); Node* control);
ValueEffectControl LowerObjectIsCallable(Node* node, Node* effect, ValueEffectControl LowerObjectIsCallable(Node* node, Node* effect,
......
...@@ -209,6 +209,7 @@ ...@@ -209,6 +209,7 @@
V(ChangeTaggedToBit) \ V(ChangeTaggedToBit) \
V(ChangeBitToTagged) \ V(ChangeBitToTagged) \
V(TruncateTaggedToWord32) \ V(TruncateTaggedToWord32) \
V(TruncateTaggedToFloat64) \
V(Allocate) \ V(Allocate) \
V(LoadField) \ V(LoadField) \
V(LoadBuffer) \ V(LoadBuffer) \
......
...@@ -271,8 +271,12 @@ Node* RepresentationChanger::GetFloat32RepresentationFor( ...@@ -271,8 +271,12 @@ Node* RepresentationChanger::GetFloat32RepresentationFor(
} }
} else if (output_rep == MachineRepresentation::kTagged) { } else if (output_rep == MachineRepresentation::kTagged) {
if (output_type->Is(Type::NumberOrUndefined())) { if (output_type->Is(Type::NumberOrUndefined())) {
op = simplified() // tagged -> float64 -> float32
->ChangeTaggedToFloat64(); // tagged -> float64 -> float32 if (output_type->Is(Type::Number())) {
op = simplified()->ChangeTaggedToFloat64();
} else {
op = simplified()->TruncateTaggedToFloat64();
}
node = jsgraph()->graph()->NewNode(op, node); node = jsgraph()->graph()->NewNode(op, node);
op = machine()->TruncateFloat64ToFloat32(); op = machine()->TruncateFloat64ToFloat32();
} }
...@@ -328,8 +332,10 @@ Node* RepresentationChanger::GetFloat64RepresentationFor( ...@@ -328,8 +332,10 @@ Node* RepresentationChanger::GetFloat64RepresentationFor(
} else if (output_type->Is(Type::TaggedSigned())) { } else if (output_type->Is(Type::TaggedSigned())) {
node = InsertChangeTaggedSignedToInt32(node); node = InsertChangeTaggedSignedToInt32(node);
op = machine()->ChangeInt32ToFloat64(); op = machine()->ChangeInt32ToFloat64();
} else if (output_type->Is(Type::NumberOrUndefined())) { } else if (output_type->Is(Type::Number())) {
op = simplified()->ChangeTaggedToFloat64(); op = simplified()->ChangeTaggedToFloat64();
} else if (output_type->Is(Type::NumberOrUndefined())) {
op = simplified()->TruncateTaggedToFloat64();
} }
} else if (output_rep == MachineRepresentation::kFloat32) { } else if (output_rep == MachineRepresentation::kFloat32) {
op = machine()->ChangeFloat32ToFloat64(); op = machine()->ChangeFloat32ToFloat64();
......
...@@ -60,7 +60,8 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) { ...@@ -60,7 +60,8 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
} }
break; break;
} }
case IrOpcode::kChangeTaggedToFloat64: { case IrOpcode::kChangeTaggedToFloat64:
case IrOpcode::kTruncateTaggedToFloat64: {
NumberMatcher m(node->InputAt(0)); NumberMatcher m(node->InputAt(0));
if (m.HasValue()) return ReplaceFloat64(m.Value()); if (m.HasValue()) return ReplaceFloat64(m.Value());
if (m.IsChangeFloat64ToTagged()) return Replace(m.node()->InputAt(0)); if (m.IsChangeFloat64ToTagged()) return Replace(m.node()->InputAt(0));
......
...@@ -215,6 +215,7 @@ Type* TypeOf(const Operator* op) { ...@@ -215,6 +215,7 @@ Type* TypeOf(const Operator* op) {
V(ChangeTaggedToBit, Operator::kNoProperties, 1) \ V(ChangeTaggedToBit, Operator::kNoProperties, 1) \
V(ChangeBitToTagged, Operator::kNoProperties, 1) \ V(ChangeBitToTagged, Operator::kNoProperties, 1) \
V(TruncateTaggedToWord32, Operator::kNoProperties, 1) \ V(TruncateTaggedToWord32, Operator::kNoProperties, 1) \
V(TruncateTaggedToFloat64, Operator::kNoProperties, 1) \
V(ObjectIsCallable, Operator::kNoProperties, 1) \ V(ObjectIsCallable, Operator::kNoProperties, 1) \
V(ObjectIsNumber, Operator::kNoProperties, 1) \ V(ObjectIsNumber, Operator::kNoProperties, 1) \
V(ObjectIsReceiver, Operator::kNoProperties, 1) \ V(ObjectIsReceiver, Operator::kNoProperties, 1) \
......
...@@ -175,6 +175,7 @@ class SimplifiedOperatorBuilder final : public ZoneObject { ...@@ -175,6 +175,7 @@ class SimplifiedOperatorBuilder final : public ZoneObject {
const Operator* ChangeTaggedToBit(); const Operator* ChangeTaggedToBit();
const Operator* ChangeBitToTagged(); const Operator* ChangeBitToTagged();
const Operator* TruncateTaggedToWord32(); const Operator* TruncateTaggedToWord32();
const Operator* TruncateTaggedToFloat64();
const Operator* ObjectIsCallable(); const Operator* ObjectIsCallable();
const Operator* ObjectIsNumber(); const Operator* ObjectIsNumber();
......
...@@ -1853,6 +1853,12 @@ Type* Typer::Visitor::TypeChangeTaggedToFloat64(Node* node) { ...@@ -1853,6 +1853,12 @@ Type* Typer::Visitor::TypeChangeTaggedToFloat64(Node* node) {
return ChangeRepresentation(arg, Type::UntaggedFloat64(), zone()); return ChangeRepresentation(arg, Type::UntaggedFloat64(), zone());
} }
Type* Typer::Visitor::TypeTruncateTaggedToFloat64(Node* node) {
Type* arg = Operand(node, 0);
// TODO(neis): DCHECK(arg->Is(Type::NumberOrUndefined()));
return ChangeRepresentation(arg, Type::UntaggedFloat64(), zone());
}
Type* Typer::Visitor::TypeChangeInt31ToTaggedSigned(Node* node) { Type* Typer::Visitor::TypeChangeInt31ToTaggedSigned(Node* node) {
Type* arg = Operand(node, 0); Type* arg = Operand(node, 0);
// TODO(neis): DCHECK(arg->Is(Type::Signed31())); // TODO(neis): DCHECK(arg->Is(Type::Signed31()));
......
...@@ -822,6 +822,16 @@ void Verifier::Visitor::Check(Node* node) { ...@@ -822,6 +822,16 @@ void Verifier::Visitor::Check(Node* node) {
// CheckUpperIs(node, to)); // CheckUpperIs(node, to));
break; break;
} }
case IrOpcode::kTruncateTaggedToFloat64: {
// NumberOrUndefined /\ Tagged -> Number /\ UntaggedFloat64
// TODO(neis): Activate once ChangeRepresentation works in typer.
// Type* from = Type::Intersect(Type::NumberOrUndefined(),
// Type::Tagged());
// Type* to = Type::Intersect(Type::Number(), Type::UntaggedFloat64());
// CheckValueInputIs(node, 0, from));
// CheckUpperIs(node, to));
break;
}
case IrOpcode::kChangeInt31ToTaggedSigned: { case IrOpcode::kChangeInt31ToTaggedSigned: {
// Signed31 /\ UntaggedInt32 -> Signed31 /\ Tagged // Signed31 /\ UntaggedInt32 -> Signed31 /\ Tagged
// TODO(neis): Activate once ChangeRepresentation works in typer. // TODO(neis): Activate once ChangeRepresentation works in typer.
......
...@@ -473,7 +473,10 @@ TEST(SingleChanges) { ...@@ -473,7 +473,10 @@ TEST(SingleChanges) {
CheckChange(IrOpcode::kChangeTaggedToFloat64, MachineRepresentation::kTagged, CheckChange(IrOpcode::kChangeTaggedToFloat64, MachineRepresentation::kTagged,
Type::Number(), MachineRepresentation::kFloat64); Type::Number(), MachineRepresentation::kFloat64);
CheckChange(IrOpcode::kChangeTaggedToFloat64, MachineRepresentation::kTagged, CheckChange(IrOpcode::kChangeTaggedToFloat64, MachineRepresentation::kTagged,
Type::NumberOrUndefined(), MachineRepresentation::kFloat64); Type::Number(), MachineRepresentation::kFloat64);
CheckChange(IrOpcode::kTruncateTaggedToFloat64,
MachineRepresentation::kTagged, Type::NumberOrUndefined(),
MachineRepresentation::kFloat64);
CheckTwoChanges(IrOpcode::kChangeTaggedSignedToInt32, CheckTwoChanges(IrOpcode::kChangeTaggedSignedToInt32,
IrOpcode::kChangeInt32ToFloat64, IrOpcode::kChangeInt32ToFloat64,
MachineRepresentation::kTagged, Type::TaggedSigned(), MachineRepresentation::kTagged, Type::TaggedSigned(),
......
// Copyright 2016 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
function g(a, b) {
a = +a;
if (b) {
a = undefined;
}
print(a);
return +a;
}
g(0);
g(0);
%OptimizeFunctionOnNextCall(g);
assertTrue(Number.isNaN(g(0, true)));
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