From: bmeurer Date: Wed, 14 Jan 2015 12:06:41 +0000 (-0800) Subject: [turbofan] Fix truncation/representation sloppiness wrt. bool/bit. X-Git-Tag: upstream/4.7.83~4989 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=70b32e4b8a7d3f11174d0a68822d9a636fd1d127;p=platform%2Fupstream%2Fv8.git [turbofan] Fix truncation/representation sloppiness wrt. bool/bit. TEST=cctest,mjsunit,unittests BUG=v8:3812 LOG=y Review URL: https://codereview.chromium.org/850013003 Cr-Commit-Position: refs/heads/master@{#26051} --- diff --git a/src/compiler/change-lowering.cc b/src/compiler/change-lowering.cc index fd425c2..7ddc751 100644 --- a/src/compiler/change-lowering.cc +++ b/src/compiler/change-lowering.cc @@ -22,13 +22,9 @@ Reduction ChangeLowering::Reduce(Node* node) { Node* control = graph()->start(); switch (node->opcode()) { case IrOpcode::kChangeBitToBool: - return ChangeBitToBool(node->InputAt(0)); + return ChangeBitToBool(node->InputAt(0), control); case IrOpcode::kChangeBoolToBit: return ChangeBoolToBit(node->InputAt(0)); - case IrOpcode::kChangeWord32ToBit: - return ChangeWord32ToBit(node->InputAt(0)); - case IrOpcode::kChangeWord64ToBit: - return ChangeWord64ToBit(node->InputAt(0)); case IrOpcode::kChangeFloat64ToTagged: return ChangeFloat64ToTagged(node->InputAt(0), control); case IrOpcode::kChangeInt32ToTagged: @@ -142,35 +138,17 @@ Node* ChangeLowering::Uint32LessThanOrEqual(Node* lhs, Node* rhs) { } -Reduction ChangeLowering::ChangeBitToBool(Node* value) { +Reduction ChangeLowering::ChangeBitToBool(Node* val, Node* control) { MachineType const type = static_cast(kTypeBool | kRepTagged); - return Replace(graph()->NewNode(common()->Select(type), value, + return Replace(graph()->NewNode(common()->Select(type), val, jsgraph()->TrueConstant(), jsgraph()->FalseConstant())); } -Reduction ChangeLowering::ChangeBoolToBit(Node* value) { - return Replace(graph()->NewNode(machine()->WordEqual(), value, - jsgraph()->TrueConstant())); -} - - -Reduction ChangeLowering::ChangeWord32ToBit(Node* value) { - return Replace( - graph()->NewNode(machine()->Word32Equal(), - graph()->NewNode(machine()->Word32Equal(), value, - jsgraph()->Int32Constant(0)), - jsgraph()->Int32Constant(0))); -} - - -Reduction ChangeLowering::ChangeWord64ToBit(Node* value) { +Reduction ChangeLowering::ChangeBoolToBit(Node* val) { return Replace( - graph()->NewNode(machine()->Word32Equal(), - graph()->NewNode(machine()->Word64Equal(), value, - jsgraph()->Int64Constant(0)), - jsgraph()->Int32Constant(0))); + graph()->NewNode(machine()->WordEqual(), val, jsgraph()->TrueConstant())); } diff --git a/src/compiler/change-lowering.h b/src/compiler/change-lowering.h index 0147894..773fd08 100644 --- a/src/compiler/change-lowering.h +++ b/src/compiler/change-lowering.h @@ -17,7 +17,6 @@ class JSGraph; class Linkage; class MachineOperatorBuilder; - class ChangeLowering FINAL : public Reducer { public: ChangeLowering(JSGraph* jsgraph, Linkage* linkage) @@ -41,10 +40,8 @@ class ChangeLowering FINAL : public Reducer { Node* TestNotSmi(Node* value); Node* Uint32LessThanOrEqual(Node* lhs, Node* rhs); - Reduction ChangeBitToBool(Node* value); + Reduction ChangeBitToBool(Node* value, Node* control); Reduction ChangeBoolToBit(Node* value); - Reduction ChangeWord32ToBit(Node* value); - Reduction ChangeWord64ToBit(Node* value); Reduction ChangeFloat64ToTagged(Node* value, Node* control); Reduction ChangeInt32ToTagged(Node* value, Node* control); Reduction ChangeTaggedToFloat64(Node* value, Node* control); diff --git a/src/compiler/js-graph.cc b/src/compiler/js-graph.cc index c8f6062..7759ba1 100644 --- a/src/compiler/js-graph.cc +++ b/src/compiler/js-graph.cc @@ -200,15 +200,6 @@ Node* JSGraph::ExternalConstant(ExternalReference reference) { } -Type* JSGraph::ZeroOneRangeType() { - if (!zero_one_range_type_.is_set()) { - zero_one_range_type_.set( - Type::Range(factory()->NewNumber(0), factory()->NewNumber(1), zone())); - } - return zero_one_range_type_.get(); -} - - void JSGraph::GetCachedNodes(NodeVector* nodes) { cache_.GetCachedNodes(nodes); SetOncePointer* ptrs[] = { diff --git a/src/compiler/js-graph.h b/src/compiler/js-graph.h index 2d8d035..040a745 100644 --- a/src/compiler/js-graph.h +++ b/src/compiler/js-graph.h @@ -16,7 +16,6 @@ namespace v8 { namespace internal { namespace compiler { -// Forward declarations. class Typer; // Implements a facade on a Graph, enhancing the graph with JS-specific @@ -110,9 +109,6 @@ class JSGraph : public ZoneObject { // stubs and runtime functions that do not require a context. Node* NoContextConstant() { return ZeroConstant(); } - // Cached common types. - Type* ZeroOneRangeType(); - JSOperatorBuilder* javascript() { return javascript_; } CommonOperatorBuilder* common() { return common_; } MachineOperatorBuilder* machine() { return machine_; } @@ -140,8 +136,6 @@ class JSGraph : public ZoneObject { SetOncePointer one_constant_; SetOncePointer nan_constant_; - SetOncePointer zero_one_range_type_; - CommonNodeCache cache_; Node* ImmovableHeapConstant(Handle value); diff --git a/src/compiler/opcodes.h b/src/compiler/opcodes.h index a4c42cb..b7a2f6b 100644 --- a/src/compiler/opcodes.h +++ b/src/compiler/opcodes.h @@ -133,7 +133,7 @@ JS_CONTEXT_OP_LIST(V) \ JS_OTHER_OP_LIST(V) -// Opcodes for VirtualMachine-level operators. +// Opcodes for VirtuaMachine-level operators. #define SIMPLIFIED_OP_LIST(V) \ V(AnyToBoolean) \ V(BooleanNot) \ @@ -161,8 +161,6 @@ V(ChangeUint32ToTagged) \ V(ChangeFloat64ToTagged) \ V(ChangeBoolToBit) \ - V(ChangeWord32ToBit) \ - V(ChangeWord64ToBit) \ V(ChangeBitToBool) \ V(LoadField) \ V(LoadBuffer) \ diff --git a/src/compiler/representation-change.h b/src/compiler/representation-change.h index 909ca62..5c41f03 100644 --- a/src/compiler/representation-change.h +++ b/src/compiler/representation-change.h @@ -27,9 +27,6 @@ class RepresentationChanger { : jsgraph_(jsgraph), simplified_(simplified), isolate_(isolate), - bit_range_(Type::Range(isolate->factory()->NewNumber(0), - isolate->factory()->NewNumber(1), - jsgraph->zone())), testing_type_errors_(false), type_error_(false) {} @@ -266,7 +263,7 @@ class RepresentationChanger { // Select the correct X -> Word32 operator. const Operator* op; if (output_type & kRepBit) { - return node; // No change necessary. + return node; // Sloppy comparison -> word32 } else if (output_type & kRepFloat64) { if (output_type & kTypeUint32 || use_unsigned) { op = machine()->ChangeFloat64ToUint32(); @@ -295,48 +292,24 @@ class RepresentationChanger { Node* GetBitRepresentationFor(Node* node, MachineTypeUnion output_type) { // Eagerly fold representation changes for constants. switch (node->opcode()) { - case IrOpcode::kInt32Constant: { - int32_t value = OpParameter(node); - if (value == 0 || value == 1) return node; - return jsgraph()->Int32Constant(1); // value != 0 - } - case IrOpcode::kNumberConstant: { - double value = OpParameter(node); - if (value == 0 || std::isnan(value)) return jsgraph()->Int32Constant(0); - return jsgraph()->Int32Constant(1); // value != +0.0, -0.0, NaN - } case IrOpcode::kHeapConstant: { - Handle object = OpParameter>(node).handle(); - return jsgraph()->Int32Constant(object->BooleanValue() ? 1 : 0); + Handle value = OpParameter >(node).handle(); + DCHECK(value.is_identical_to(factory()->true_value()) || + value.is_identical_to(factory()->false_value())); + return jsgraph()->Int32Constant( + value.is_identical_to(factory()->true_value()) ? 1 : 0); } default: break; } // Select the correct X -> Bit operator. const Operator* op; - if (output_type & rWord) { - op = simplified()->ChangeWord32ToBit(); - } else if (output_type & kRepWord64) { - op = simplified()->ChangeWord64ToBit(); - } else if (output_type & kRepTagged) { - Type* upper = NodeProperties::GetBounds(node).upper; - if (upper->Is(Type::Boolean())) { - op = simplified()->ChangeBoolToBit(); - } else if (upper->Is(Type::Signed32())) { - // Tagged -> Int32 -> Bit - node = InsertChangeTaggedToInt32(node); - op = simplified()->ChangeWord32ToBit(); - } else if (upper->Is(Type::Unsigned32())) { - // Tagged -> Uint32 -> Bit - node = InsertChangeTaggedToUint32(node); - op = simplified()->ChangeWord32ToBit(); - } else { - return TypeError(node, output_type, kRepBit); - } + if (output_type & kRepTagged) { + op = simplified()->ChangeBoolToBit(); } else { return TypeError(node, output_type, kRepBit); } - return graph()->NewNode(op, node); + return jsgraph()->graph()->NewNode(op, node); } Node* GetWord64RepresentationFor(Node* node, MachineTypeUnion output_type) { @@ -441,7 +414,6 @@ class RepresentationChanger { JSGraph* jsgraph_; SimplifiedOperatorBuilder* simplified_; Isolate* isolate_; - Type* bit_range_; friend class RepresentationChangerTester; // accesses the below fields. @@ -468,26 +440,20 @@ class RepresentationChanger { } Node* InsertChangeFloat32ToFloat64(Node* node) { - return graph()->NewNode(machine()->ChangeFloat32ToFloat64(), node); + return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(), + node); } Node* InsertChangeTaggedToFloat64(Node* node) { - return graph()->NewNode(simplified()->ChangeTaggedToFloat64(), node); - } - - Node* InsertChangeTaggedToInt32(Node* node) { - return graph()->NewNode(simplified()->ChangeTaggedToInt32(), node); - } - - Node* InsertChangeTaggedToUint32(Node* node) { - return graph()->NewNode(simplified()->ChangeTaggedToUint32(), node); + return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(), + node); } - Graph* graph() const { return jsgraph()->graph(); } JSGraph* jsgraph() const { return jsgraph_; } Isolate* isolate() const { return isolate_; } - SimplifiedOperatorBuilder* simplified() const { return simplified_; } - MachineOperatorBuilder* machine() const { return jsgraph()->machine(); } + Factory* factory() const { return isolate()->factory(); } + SimplifiedOperatorBuilder* simplified() { return simplified_; } + MachineOperatorBuilder* machine() { return jsgraph()->machine(); } }; } // namespace compiler diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc index 16a1278..2c81423 100644 --- a/src/compiler/simplified-lowering.cc +++ b/src/compiler/simplified-lowering.cc @@ -77,9 +77,6 @@ class RepresentationSelector { memset(info_, 0, sizeof(NodeInfo) * count_); Factory* f = zone->isolate()->factory(); - safe_bit_range_ = - Type::Union(Type::Boolean(), - Type::Range(f->NewNumber(0), f->NewNumber(1), zone), zone); safe_int_additive_range_ = Type::Range(f->NewNumber(-std::pow(2.0, 52.0)), f->NewNumber(std::pow(2.0, 52.0)), zone); @@ -323,7 +320,7 @@ class RepresentationSelector { } else { return kRepFloat64; } - } else if (IsSafeBitOperand(node)) { + } else if (upper->Is(Type::Boolean())) { // multiple uses => pick kRepBit. return kRepBit; } else if (upper->Is(Type::Number())) { @@ -417,11 +414,6 @@ class RepresentationSelector { return BothInputsAre(node, Type::Signed32()) && !CanObserveNonInt32(use); } - bool IsSafeBitOperand(Node* node) { - Type* type = NodeProperties::GetBounds(node).upper; - return type->Is(safe_bit_range_); - } - bool IsSafeIntAdditiveOperand(Node* node) { Type* type = NodeProperties::GetBounds(node).upper; // TODO(jarin): Unfortunately, bitset types are not subtypes of larger @@ -530,24 +522,19 @@ class RepresentationSelector { // Simplified operators. //------------------------------------------------------------------ case IrOpcode::kAnyToBoolean: { - if (IsSafeBitOperand(node->InputAt(0))) { - VisitUnop(node, kRepBit, kRepBit); - if (lower()) DeferReplacement(node, node->InputAt(0)); - } else { - VisitUnop(node, kMachAnyTagged, kTypeBool | kRepTagged); - if (lower()) { - // AnyToBoolean(x) => Call(ToBooleanStub, x, no-context) - Operator::Properties properties = node->op()->properties(); - Callable callable = CodeFactory::ToBoolean( - jsgraph_->isolate(), ToBooleanStub::RESULT_AS_ODDBALL); - CallDescriptor::Flags flags = CallDescriptor::kPatchableCallSite; - CallDescriptor* desc = Linkage::GetStubCallDescriptor( - callable.descriptor(), 0, flags, properties, jsgraph_->zone()); - node->set_op(jsgraph_->common()->Call(desc)); - node->InsertInput(jsgraph_->zone(), 0, - jsgraph_->HeapConstant(callable.code())); - node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant()); - } + VisitUnop(node, kMachAnyTagged, kTypeBool | kRepTagged); + if (lower()) { + // AnyToBoolean(x) => Call(ToBooleanStub, x, no-context) + Operator::Properties properties = node->op()->properties(); + Callable callable = CodeFactory::ToBoolean( + jsgraph_->isolate(), ToBooleanStub::RESULT_AS_ODDBALL); + CallDescriptor::Flags flags = CallDescriptor::kPatchableCallSite; + CallDescriptor* desc = Linkage::GetStubCallDescriptor( + callable.descriptor(), 0, flags, properties, jsgraph_->zone()); + node->set_op(jsgraph_->common()->Call(desc)); + node->InsertInput(jsgraph_->zone(), 0, + jsgraph_->HeapConstant(callable.code())); + node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant()); } break; } @@ -1080,7 +1067,6 @@ class RepresentationSelector { Phase phase_; // current phase of algorithm RepresentationChanger* changer_; // for inserting representation changes ZoneQueue queue_; // queue for traversing the graph - Type* safe_bit_range_; Type* safe_int_additive_range_; NodeInfo* GetInfo(Node* node) { diff --git a/src/compiler/simplified-operator-reducer.cc b/src/compiler/simplified-operator-reducer.cc index 01ad15e..9d45e5b 100644 --- a/src/compiler/simplified-operator-reducer.cc +++ b/src/compiler/simplified-operator-reducer.cc @@ -54,8 +54,6 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) { if (m.IsChangeBitToBool()) return Replace(m.node()->InputAt(0)); break; } - case IrOpcode::kChangeWord32ToBit: - return ReduceChangeWord32ToBit(node); case IrOpcode::kChangeFloat64ToTagged: { Float64Matcher m(node->InputAt(0)); if (m.HasValue()) return ReplaceNumber(m.Value()); @@ -138,17 +136,6 @@ Reduction SimplifiedOperatorReducer::ReduceAnyToBoolean(Node* node) { } -Reduction SimplifiedOperatorReducer::ReduceChangeWord32ToBit(Node* node) { - Node* const input = NodeProperties::GetValueInput(node, 0); - Type* const input_type = NodeProperties::GetBounds(input).upper; - if (input_type->Is(jsgraph()->ZeroOneRangeType())) { - // ChangeWord32ToBit(x:bit) => x - return Replace(input); - } - return NoChange(); -} - - Reduction SimplifiedOperatorReducer::Change(Node* node, const Operator* op, Node* a) { DCHECK_EQ(node->InputCount(), OperatorProperties::GetTotalInputCount(op)); diff --git a/src/compiler/simplified-operator-reducer.h b/src/compiler/simplified-operator-reducer.h index 76f2cb4..32a7bcc 100644 --- a/src/compiler/simplified-operator-reducer.h +++ b/src/compiler/simplified-operator-reducer.h @@ -13,6 +13,7 @@ namespace internal { // Forward declarations. class Factory; +class Heap; namespace compiler { @@ -30,7 +31,6 @@ class SimplifiedOperatorReducer FINAL : public Reducer { private: Reduction ReduceAnyToBoolean(Node* node); - Reduction ReduceChangeWord32ToBit(Node* node); Reduction Change(Node* node, const Operator* op, Node* a); Reduction ReplaceFloat64(double value); diff --git a/src/compiler/simplified-operator.cc b/src/compiler/simplified-operator.cc index 5aea64b..e1e8c30 100644 --- a/src/compiler/simplified-operator.cc +++ b/src/compiler/simplified-operator.cc @@ -182,10 +182,8 @@ const ElementAccess& ElementAccessOf(const Operator* op) { V(ChangeInt32ToTagged, Operator::kNoProperties, 1) \ V(ChangeUint32ToTagged, Operator::kNoProperties, 1) \ V(ChangeFloat64ToTagged, Operator::kNoProperties, 1) \ - V(ChangeBitToBool, Operator::kNoProperties, 1) \ V(ChangeBoolToBit, Operator::kNoProperties, 1) \ - V(ChangeWord32ToBit, Operator::kNoProperties, 1) \ - V(ChangeWord64ToBit, Operator::kNoProperties, 1) \ + V(ChangeBitToBool, Operator::kNoProperties, 1) \ V(ObjectIsSmi, Operator::kNoProperties, 1) \ V(ObjectIsNonNegativeSmi, Operator::kNoProperties, 1) diff --git a/src/compiler/simplified-operator.h b/src/compiler/simplified-operator.h index 5b57cdd..5eed7c3 100644 --- a/src/compiler/simplified-operator.h +++ b/src/compiler/simplified-operator.h @@ -159,10 +159,8 @@ class SimplifiedOperatorBuilder FINAL { const Operator* ChangeInt32ToTagged(); const Operator* ChangeUint32ToTagged(); const Operator* ChangeFloat64ToTagged(); - const Operator* ChangeBitToBool(); const Operator* ChangeBoolToBit(); - const Operator* ChangeWord32ToBit(); - const Operator* ChangeWord64ToBit(); + const Operator* ChangeBitToBool(); const Operator* ObjectIsSmi(); const Operator* ObjectIsNonNegativeSmi(); diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc index 24e93e1..737dffa 100644 --- a/src/compiler/typer.cc +++ b/src/compiler/typer.cc @@ -1611,14 +1611,6 @@ Bounds Typer::Visitor::TypeChangeFloat64ToTagged(Node* node) { } -Bounds Typer::Visitor::TypeChangeBitToBool(Node* node) { - Bounds arg = Operand(node, 0); - // TODO(neis): DCHECK(arg.upper->Is(Type::Boolean())); - return Bounds(ChangeRepresentation(arg.lower, Type::TaggedPointer(), zone()), - ChangeRepresentation(arg.upper, Type::TaggedPointer(), zone())); -} - - Bounds Typer::Visitor::TypeChangeBoolToBit(Node* node) { Bounds arg = Operand(node, 0); // TODO(neis): DCHECK(arg.upper->Is(Type::Boolean())); @@ -1628,15 +1620,11 @@ Bounds Typer::Visitor::TypeChangeBoolToBit(Node* node) { } -Bounds Typer::Visitor::TypeChangeWord32ToBit(Node* node) { - return Bounds( - ChangeRepresentation(Type::Boolean(), Type::UntaggedBit(), zone())); -} - - -Bounds Typer::Visitor::TypeChangeWord64ToBit(Node* node) { - return Bounds( - ChangeRepresentation(Type::Boolean(), Type::UntaggedBit(), zone())); +Bounds Typer::Visitor::TypeChangeBitToBool(Node* node) { + Bounds arg = Operand(node, 0); + // TODO(neis): DCHECK(arg.upper->Is(Type::Boolean())); + return Bounds(ChangeRepresentation(arg.lower, Type::TaggedPointer(), zone()), + ChangeRepresentation(arg.upper, Type::TaggedPointer(), zone())); } diff --git a/src/compiler/verifier.cc b/src/compiler/verifier.cc index 188ee3e..116989d 100644 --- a/src/compiler/verifier.cc +++ b/src/compiler/verifier.cc @@ -632,15 +632,6 @@ void Verifier::Visitor::Pre(Node* node) { // CheckUpperIs(node, to)); break; } - case IrOpcode::kChangeBitToBool: { - // Boolean /\ UntaggedInt1 -> Boolean /\ TaggedPtr - // TODO(neis): Activate once ChangeRepresentation works in typer. - // Type* from = Type::Intersect(Type::Boolean(), Type::UntaggedInt1()); - // Type* to = Type::Intersect(Type::Boolean(), Type::TaggedPtr()); - // CheckValueInputIs(node, 0, from)); - // CheckUpperIs(node, to)); - break; - } case IrOpcode::kChangeBoolToBit: { // Boolean /\ TaggedPtr -> Boolean /\ UntaggedInt1 // TODO(neis): Activate once ChangeRepresentation works in typer. @@ -650,13 +641,13 @@ void Verifier::Visitor::Pre(Node* node) { // CheckUpperIs(node, to)); break; } - case IrOpcode::kChangeWord32ToBit: { - // TODO(rossberg): Check. - CheckValueInputIs(node, 0, Type::Integral32()); - break; - } - case IrOpcode::kChangeWord64ToBit: { - // TODO(rossberg): Check. + case IrOpcode::kChangeBitToBool: { + // Boolean /\ UntaggedInt1 -> Boolean /\ TaggedPtr + // TODO(neis): Activate once ChangeRepresentation works in typer. + // Type* from = Type::Intersect(Type::Boolean(), Type::UntaggedInt1()); + // Type* to = Type::Intersect(Type::Boolean(), Type::TaggedPtr()); + // CheckValueInputIs(node, 0, from)); + // CheckUpperIs(node, to)); break; } diff --git a/test/cctest/compiler/test-representation-change.cc b/test/cctest/compiler/test-representation-change.cc index 0496ad8..a96859b 100644 --- a/test/cctest/compiler/test-representation-change.cc +++ b/test/cctest/compiler/test-representation-change.cc @@ -79,14 +79,10 @@ class RepresentationChangerTester : public HandleAndZoneScope, CHECK_EQ(expected, m.Value()); } - Node* Parameter(Type* type, int index = 0) { - Node* node = graph()->NewNode(common()->Parameter(index), graph()->start()); - NodeProperties::SetBounds(node, Bounds(type)); - return node; + Node* Parameter(int index = 0) { + return graph()->NewNode(common()->Parameter(index), graph()->start()); } - Node* Parameter(int index = 0) { return Parameter(Type::Any(), index); } - void CheckTypeError(MachineTypeUnion from, MachineTypeUnion to) { changer()->testing_type_errors_ = true; changer()->type_error_ = false; @@ -102,17 +98,16 @@ class RepresentationChangerTester : public HandleAndZoneScope, CHECK_EQ(n, c); } }; - -} // namespace compiler -} // namespace internal -} // namespace v8 +} +} +} // namespace v8::internal::compiler static const MachineType all_reps[] = {kRepBit, kRepWord32, kRepWord64, kRepFloat32, kRepFloat64, kRepTagged}; -TEST(ToBit_constant) { +TEST(BoolToBit_constant) { RepresentationChangerTester r; Node* true_node = r.jsgraph()->TrueConstant(); @@ -124,22 +119,6 @@ TEST(ToBit_constant) { Node* false_bit = r.changer()->GetRepresentationFor(false_node, kRepTagged, kRepBit); r.CheckInt32Constant(false_bit, 0); - - { - FOR_FLOAT64_INPUTS(i) { - Node* node = r.jsgraph()->Constant(*i); - Node* bit = r.changer()->GetRepresentationFor(node, kRepTagged, kRepBit); - r.CheckInt32Constant(bit, DoubleToBoolean(*i) ? 1 : 0); - } - } - - { - FOR_INT32_INPUTS(i) { - Node* node = r.jsgraph()->Int32Constant(*i); - Node* bit = r.changer()->GetRepresentationFor(node, kRepWord32, kRepBit); - r.CheckInt32Constant(bit, *i == 0 ? 0 : 1); - } - } } @@ -391,10 +370,10 @@ TEST(ToUint32_constant) { static void CheckChange(IrOpcode::Value expected, MachineTypeUnion from, - MachineTypeUnion to, Type* from_type = Type::Any()) { + MachineTypeUnion to) { RepresentationChangerTester r; - Node* n = r.Parameter(from_type); + Node* n = r.Parameter(); Node* c = r.changer()->GetRepresentationFor(n, from, to); CHECK_NE(c, n); @@ -405,11 +384,10 @@ static void CheckChange(IrOpcode::Value expected, MachineTypeUnion from, static void CheckTwoChanges(IrOpcode::Value expected2, IrOpcode::Value expected1, MachineTypeUnion from, - MachineTypeUnion to, - Type* from_type = Type::Any()) { + MachineTypeUnion to) { RepresentationChangerTester r; - Node* n = r.Parameter(from_type); + Node* n = r.Parameter(); Node* c1 = r.changer()->GetRepresentationFor(n, from, to); CHECK_NE(c1, n); @@ -422,15 +400,7 @@ static void CheckTwoChanges(IrOpcode::Value expected2, TEST(SingleChanges) { - CheckChange(IrOpcode::kChangeBoolToBit, kRepTagged, kRepBit, Type::Boolean()); - CheckTwoChanges(IrOpcode::kChangeTaggedToInt32, IrOpcode::kChangeWord32ToBit, - kRepTagged, kRepBit, Type::Signed32()); - CheckTwoChanges(IrOpcode::kChangeTaggedToUint32, IrOpcode::kChangeWord32ToBit, - kRepTagged, kRepBit, Type::Unsigned32()); - CheckChange(IrOpcode::kChangeWord32ToBit, kRepWord8, kRepBit); - CheckChange(IrOpcode::kChangeWord32ToBit, kRepWord16, kRepBit); - CheckChange(IrOpcode::kChangeWord32ToBit, kRepWord32, kRepBit); - CheckChange(IrOpcode::kChangeWord64ToBit, kRepWord64, kRepBit); + CheckChange(IrOpcode::kChangeBoolToBit, kRepTagged, kRepBit); CheckChange(IrOpcode::kChangeBitToBool, kRepBit, kRepTagged); CheckChange(IrOpcode::kChangeInt32ToTagged, kRepWord32 | kTypeInt32, @@ -534,6 +504,16 @@ TEST(Nops) { TEST(TypeErrors) { RepresentationChangerTester r; + // Wordish cannot be implicitly converted to/from comparison conditions. + r.CheckTypeError(kRepWord8, kRepBit); + r.CheckTypeError(kRepWord8, kRepBit | kTypeBool); + r.CheckTypeError(kRepWord16, kRepBit); + r.CheckTypeError(kRepWord16, kRepBit | kTypeBool); + r.CheckTypeError(kRepWord32, kRepBit); + r.CheckTypeError(kRepWord32, kRepBit | kTypeBool); + r.CheckTypeError(kRepWord64, kRepBit); + r.CheckTypeError(kRepWord64, kRepBit | kTypeBool); + // Floats cannot be implicitly converted to/from comparison conditions. r.CheckTypeError(kRepFloat64, kRepBit); r.CheckTypeError(kRepFloat64, kRepBit | kTypeBool); diff --git a/test/cctest/compiler/test-simplified-lowering.cc b/test/cctest/compiler/test-simplified-lowering.cc index 147aa32..c4f497c 100644 --- a/test/cctest/compiler/test-simplified-lowering.cc +++ b/test/cctest/compiler/test-simplified-lowering.cc @@ -787,31 +787,6 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders { }; -TEST(LowerAnyToBoolean_bit_bit) { - // AnyToBoolean(x: kRepBit) used as kRepBit - HandleAndZoneScope scope; - Factory* f = scope.main_zone()->isolate()->factory(); - Handle zero = f->NewNumber(0); - Handle one = f->NewNumber(1); - Type* singleton_zero = Type::Constant(zero, scope.main_zone()); - Type* singleton_one = Type::Constant(one, scope.main_zone()); - Type* zero_one_range = Type::Range(zero, one, scope.main_zone()); - static Type* kTypes[] = { - singleton_zero, singleton_one, zero_one_range, Type::Boolean(), - Type::Union(Type::Boolean(), singleton_zero, scope.main_zone()), - Type::Union(Type::Boolean(), singleton_one, scope.main_zone()), - Type::Union(Type::Boolean(), zero_one_range, scope.main_zone())}; - for (Type* type : kTypes) { - TestingGraph t(type); - Node* x = t.ExampleWithTypeAndRep(type, kRepBit); - Node* cnv = t.graph()->NewNode(t.simplified()->AnyToBoolean(), x); - Node* use = t.Branch(cnv); - t.Lower(); - CHECK_EQ(x, use->InputAt(0)); - } -} - - #if V8_TURBOFAN_TARGET TEST(LowerAnyToBoolean_tagged_tagged) { diff --git a/test/mjsunit/compiler/regress-3812.js b/test/mjsunit/compiler/regress-3812.js new file mode 100644 index 0000000..cfc8feb --- /dev/null +++ b/test/mjsunit/compiler/regress-3812.js @@ -0,0 +1,19 @@ +// 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. + +var stdlib = this; +var buffer = new ArrayBuffer(64 * 1024); +var foreign = {} + +var foo = (function Module(stdlib, foreign, heap) { + "use asm"; + function foo(i) { + var x = i ? (i&1) : true; + if (x) return x; + return false; + } + return {foo:foo}; +})(stdlib, foreign, buffer).foo; + +assertEquals(1, foo(1)); diff --git a/test/mjsunit/compiler/regress-bit-number-constant.js b/test/mjsunit/compiler/regress-bit-number-constant.js index ca4cf11..d36fe30 100644 --- a/test/mjsunit/compiler/regress-bit-number-constant.js +++ b/test/mjsunit/compiler/regress-bit-number-constant.js @@ -15,4 +15,3 @@ var foo = (function Module(stdlib, foreign, heap) { })(stdlib, foreign, buffer).foo; assertFalse(foo(1)); -assertTrue(foo(0)); diff --git a/test/unittests/compiler/change-lowering-unittest.cc b/test/unittests/compiler/change-lowering-unittest.cc index 82e262f..060b1c1 100644 --- a/test/unittests/compiler/change-lowering-unittest.cc +++ b/test/unittests/compiler/change-lowering-unittest.cc @@ -132,29 +132,8 @@ TARGET_TEST_P(ChangeLoweringCommonTest, ChangeBoolToBit) { Node* node = graph()->NewNode(simplified()->ChangeBoolToBit(), val); Reduction reduction = Reduce(node); ASSERT_TRUE(reduction.Changed()); - EXPECT_THAT(reduction.replacement(), IsWordEqual(val, IsTrueConstant())); -} - -TARGET_TEST_P(ChangeLoweringCommonTest, ChangeWord32ToBit) { - Node* val = Parameter(0); - Node* node = graph()->NewNode(simplified()->ChangeWord32ToBit(), val); - Reduction reduction = Reduce(node); - ASSERT_TRUE(reduction.Changed()); - EXPECT_THAT(reduction.replacement(), - IsWord32Equal(IsWord32Equal(val, IsInt32Constant(0)), - IsInt32Constant(0))); -} - - -TARGET_TEST_P(ChangeLoweringCommonTest, ChangeWord64ToBit) { - Node* val = Parameter(0); - Node* node = graph()->NewNode(simplified()->ChangeWord64ToBit(), val); - Reduction reduction = Reduce(node); - ASSERT_TRUE(reduction.Changed()); - EXPECT_THAT(reduction.replacement(), - IsWord32Equal(IsWord64Equal(val, IsInt64Constant(0)), - IsInt32Constant(0))); + EXPECT_THAT(reduction.replacement(), IsWordEqual(val, IsTrueConstant())); } diff --git a/test/unittests/compiler/simplified-operator-reducer-unittest.cc b/test/unittests/compiler/simplified-operator-reducer-unittest.cc index 1a5b76a..b6c0410 100644 --- a/test/unittests/compiler/simplified-operator-reducer-unittest.cc +++ b/test/unittests/compiler/simplified-operator-reducer-unittest.cc @@ -124,57 +124,6 @@ static const uint32_t kUint32Values[] = { // ----------------------------------------------------------------------------- -// Unary operators - - -namespace { - -struct UnaryOperator { - const Operator* (SimplifiedOperatorBuilder::*constructor)(); - const char* constructor_name; -}; - - -std::ostream& operator<<(std::ostream& os, const UnaryOperator& unop) { - return os << unop.constructor_name; -} - - -static const UnaryOperator kUnaryOperators[] = { - {&SimplifiedOperatorBuilder::AnyToBoolean, "AnyToBoolean"}, - {&SimplifiedOperatorBuilder::BooleanNot, "BooleanNot"}, - {&SimplifiedOperatorBuilder::ChangeBitToBool, "ChangeBitToBool"}, - {&SimplifiedOperatorBuilder::ChangeBoolToBit, "ChangeBoolToBit"}, - {&SimplifiedOperatorBuilder::ChangeFloat64ToTagged, - "ChangeFloat64ToTagged"}, - {&SimplifiedOperatorBuilder::ChangeInt32ToTagged, "ChangeInt32ToTagged"}, - {&SimplifiedOperatorBuilder::ChangeTaggedToFloat64, - "ChangeTaggedToFloat64"}, - {&SimplifiedOperatorBuilder::ChangeTaggedToInt32, "ChangeTaggedToInt32"}, - {&SimplifiedOperatorBuilder::ChangeTaggedToUint32, "ChangeTaggedToUint32"}, - {&SimplifiedOperatorBuilder::ChangeUint32ToTagged, "ChangeUint32ToTagged"}}; - -} // namespace - - -typedef SimplifiedOperatorReducerTestWithParam - SimplifiedUnaryOperatorTest; - - -TEST_P(SimplifiedUnaryOperatorTest, Parameter) { - const UnaryOperator& unop = GetParam(); - Reduction reduction = Reduce(graph()->NewNode( - (simplified()->*unop.constructor)(), Parameter(Type::Any()))); - EXPECT_FALSE(reduction.Changed()); -} - - -INSTANTIATE_TEST_CASE_P(SimplifiedOperatorReducerTest, - SimplifiedUnaryOperatorTest, - ::testing::ValuesIn(kUnaryOperators)); - - -// ----------------------------------------------------------------------------- // AnyToBoolean @@ -298,27 +247,6 @@ TEST_F(SimplifiedOperatorReducerTest, ChangeBoolToBitWithChangeBitToBool) { // ----------------------------------------------------------------------------- -// ChangeWord32ToBit - - -TEST_F(SimplifiedOperatorReducerTest, ChangeWord32ToBitWithBitType) { - Handle zero = factory()->NewNumber(0); - Handle one = factory()->NewNumber(1); - Type* const kBitTypes[] = { - Type::Constant(zero, zone()), Type::Constant(one, zone()), - Type::Range(zero, zero, zone()), Type::Range(one, one, zone()), - Type::Range(zero, one, zone())}; - TRACED_FOREACH(Type*, type, kBitTypes) { - Node* param0 = Parameter(type, 0); - Reduction reduction = - Reduce(graph()->NewNode(simplified()->ChangeWord32ToBit(), param0)); - ASSERT_TRUE(reduction.Changed()); - EXPECT_EQ(param0, reduction.replacement()); - } -} - - -// ----------------------------------------------------------------------------- // ChangeFloat64ToTagged diff --git a/test/unittests/compiler/simplified-operator-unittest.cc b/test/unittests/compiler/simplified-operator-unittest.cc index 11858b4..6807930 100644 --- a/test/unittests/compiler/simplified-operator-unittest.cc +++ b/test/unittests/compiler/simplified-operator-unittest.cc @@ -63,8 +63,6 @@ const PureOperator kPureOperators[] = { PURE(ChangeUint32ToTagged, Operator::kNoProperties, 1), PURE(ChangeFloat64ToTagged, Operator::kNoProperties, 1), PURE(ChangeBoolToBit, Operator::kNoProperties, 1), - PURE(ChangeWord32ToBit, Operator::kNoProperties, 1), - PURE(ChangeWord64ToBit, Operator::kNoProperties, 1), PURE(ChangeBitToBool, Operator::kNoProperties, 1), PURE(ObjectIsSmi, Operator::kNoProperties, 1), PURE(ObjectIsNonNegativeSmi, Operator::kNoProperties, 1)