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,
case IrOpcode::kChangeTaggedToFloat64:
state = LowerChangeTaggedToFloat64(node, *effect, *control);
break;
case IrOpcode::kTruncateTaggedToFloat64:
state = LowerTruncateTaggedToFloat64(node, *effect, *control);
break;
case IrOpcode::kTruncateTaggedToWord32:
state = LowerTruncateTaggedToWord32(node, *effect, *control);
break;
......@@ -661,6 +664,12 @@ EffectControlLinearizer::LowerChangeTaggedToUint32(Node* node, Node* effect,
EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerChangeTaggedToFloat64(Node* node, Node* effect,
Node* control) {
return LowerTruncateTaggedToFloat64(node, effect, control);
}
EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerTruncateTaggedToFloat64(Node* node, Node* effect,
Node* control) {
Node* value = node->InputAt(0);
Node* check = ObjectIsSmi(value);
......
......@@ -62,6 +62,8 @@ class EffectControlLinearizer {
Node* control);
ValueEffectControl LowerChangeTaggedToFloat64(Node* node, Node* effect,
Node* control);
ValueEffectControl LowerTruncateTaggedToFloat64(Node* node, Node* effect,
Node* control);
ValueEffectControl LowerTruncateTaggedToWord32(Node* node, Node* effect,
Node* control);
ValueEffectControl LowerObjectIsCallable(Node* node, Node* effect,
......
......@@ -209,6 +209,7 @@
V(ChangeTaggedToBit) \
V(ChangeBitToTagged) \
V(TruncateTaggedToWord32) \
V(TruncateTaggedToFloat64) \
V(Allocate) \
V(LoadField) \
V(LoadBuffer) \
......
......@@ -271,8 +271,12 @@ Node* RepresentationChanger::GetFloat32RepresentationFor(
}
} else if (output_rep == MachineRepresentation::kTagged) {
if (output_type->Is(Type::NumberOrUndefined())) {
op = simplified()
->ChangeTaggedToFloat64(); // tagged -> float64 -> float32
// tagged -> float64 -> float32
if (output_type->Is(Type::Number())) {
op = simplified()->ChangeTaggedToFloat64();
} else {
op = simplified()->TruncateTaggedToFloat64();
}
node = jsgraph()->graph()->NewNode(op, node);
op = machine()->TruncateFloat64ToFloat32();
}
......@@ -328,8 +332,10 @@ Node* RepresentationChanger::GetFloat64RepresentationFor(
} else if (output_type->Is(Type::TaggedSigned())) {
node = InsertChangeTaggedSignedToInt32(node);
op = machine()->ChangeInt32ToFloat64();
} else if (output_type->Is(Type::NumberOrUndefined())) {
} else if (output_type->Is(Type::Number())) {
op = simplified()->ChangeTaggedToFloat64();
} else if (output_type->Is(Type::NumberOrUndefined())) {
op = simplified()->TruncateTaggedToFloat64();
}
} else if (output_rep == MachineRepresentation::kFloat32) {
op = machine()->ChangeFloat32ToFloat64();
......
......@@ -60,7 +60,8 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
}
break;
}
case IrOpcode::kChangeTaggedToFloat64: {
case IrOpcode::kChangeTaggedToFloat64:
case IrOpcode::kTruncateTaggedToFloat64: {
NumberMatcher m(node->InputAt(0));
if (m.HasValue()) return ReplaceFloat64(m.Value());
if (m.IsChangeFloat64ToTagged()) return Replace(m.node()->InputAt(0));
......
......@@ -215,6 +215,7 @@ Type* TypeOf(const Operator* op) {
V(ChangeTaggedToBit, Operator::kNoProperties, 1) \
V(ChangeBitToTagged, Operator::kNoProperties, 1) \
V(TruncateTaggedToWord32, Operator::kNoProperties, 1) \
V(TruncateTaggedToFloat64, Operator::kNoProperties, 1) \
V(ObjectIsCallable, Operator::kNoProperties, 1) \
V(ObjectIsNumber, Operator::kNoProperties, 1) \
V(ObjectIsReceiver, Operator::kNoProperties, 1) \
......
......@@ -175,6 +175,7 @@ class SimplifiedOperatorBuilder final : public ZoneObject {
const Operator* ChangeTaggedToBit();
const Operator* ChangeBitToTagged();
const Operator* TruncateTaggedToWord32();
const Operator* TruncateTaggedToFloat64();
const Operator* ObjectIsCallable();
const Operator* ObjectIsNumber();
......
......@@ -1853,6 +1853,12 @@ Type* Typer::Visitor::TypeChangeTaggedToFloat64(Node* node) {
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* arg = Operand(node, 0);
// TODO(neis): DCHECK(arg->Is(Type::Signed31()));
......
......@@ -822,6 +822,16 @@ void Verifier::Visitor::Check(Node* node) {
// CheckUpperIs(node, to));
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: {
// Signed31 /\ UntaggedInt32 -> Signed31 /\ Tagged
// TODO(neis): Activate once ChangeRepresentation works in typer.
......
......@@ -473,7 +473,10 @@ TEST(SingleChanges) {
CheckChange(IrOpcode::kChangeTaggedToFloat64, MachineRepresentation::kTagged,
Type::Number(), MachineRepresentation::kFloat64);
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,
IrOpcode::kChangeInt32ToFloat64,
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