[turbofan] Fix truncation/representation sloppiness wrt. bool/bit.
authorbmeurer <bmeurer@chromium.org>
Wed, 14 Jan 2015 12:06:41 +0000 (04:06 -0800)
committerCommit bot <commit-bot@chromium.org>
Wed, 14 Jan 2015 12:06:56 +0000 (12:06 +0000)
TEST=cctest,mjsunit,unittests
BUG=v8:3812
LOG=y

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

Cr-Commit-Position: refs/heads/master@{#26051}

20 files changed:
src/compiler/change-lowering.cc
src/compiler/change-lowering.h
src/compiler/js-graph.cc
src/compiler/js-graph.h
src/compiler/opcodes.h
src/compiler/representation-change.h
src/compiler/simplified-lowering.cc
src/compiler/simplified-operator-reducer.cc
src/compiler/simplified-operator-reducer.h
src/compiler/simplified-operator.cc
src/compiler/simplified-operator.h
src/compiler/typer.cc
src/compiler/verifier.cc
test/cctest/compiler/test-representation-change.cc
test/cctest/compiler/test-simplified-lowering.cc
test/mjsunit/compiler/regress-3812.js [new file with mode: 0644]
test/mjsunit/compiler/regress-bit-number-constant.js
test/unittests/compiler/change-lowering-unittest.cc
test/unittests/compiler/simplified-operator-reducer-unittest.cc
test/unittests/compiler/simplified-operator-unittest.cc

index fd425c2..7ddc751 100644 (file)
@@ -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<MachineType>(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()));
 }
 
 
index 0147894..773fd08 100644 (file)
@@ -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);
index c8f6062..7759ba1 100644 (file)
@@ -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<Node>* ptrs[] = {
index 2d8d035..040a745 100644 (file)
@@ -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<Node> one_constant_;
   SetOncePointer<Node> nan_constant_;
 
-  SetOncePointer<Type> zero_one_range_type_;
-
   CommonNodeCache cache_;
 
   Node* ImmovableHeapConstant(Handle<HeapObject> value);
index a4c42cb..b7a2f6b 100644 (file)
   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)               \
   V(ChangeUint32ToTagged)     \
   V(ChangeFloat64ToTagged)    \
   V(ChangeBoolToBit)          \
-  V(ChangeWord32ToBit)        \
-  V(ChangeWord64ToBit)        \
   V(ChangeBitToBool)          \
   V(LoadField)                \
   V(LoadBuffer)               \
index 909ca62..5c41f03 100644 (file)
@@ -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<int32_t>(node);
-        if (value == 0 || value == 1) return node;
-        return jsgraph()->Int32Constant(1);  // value != 0
-      }
-      case IrOpcode::kNumberConstant: {
-        double value = OpParameter<double>(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> object = OpParameter<Unique<Object>>(node).handle();
-        return jsgraph()->Int32Constant(object->BooleanValue() ? 1 : 0);
+        Handle<Object> value = OpParameter<Unique<Object> >(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
index 16a1278..2c81423 100644 (file)
@@ -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<Node*> queue_;          // queue for traversing the graph
-  Type* safe_bit_range_;
   Type* safe_int_additive_range_;
 
   NodeInfo* GetInfo(Node* node) {
index 01ad15e..9d45e5b 100644 (file)
@@ -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));
index 76f2cb4..32a7bcc 100644 (file)
@@ -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);
index 5aea64b..e1e8c30 100644 (file)
@@ -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)
 
index 5b57cdd..5eed7c3 100644 (file)
@@ -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();
index 24e93e1..737dffa 100644 (file)
@@ -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()));
 }
 
 
index 188ee3e..116989d 100644 (file)
@@ -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;
     }
 
index 0496ad8..a96859b 100644 (file)
@@ -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);
index 147aa32..c4f497c 100644 (file)
@@ -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<Object> zero = f->NewNumber(0);
-  Handle<Object> 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 (file)
index 0000000..cfc8feb
--- /dev/null
@@ -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));
index ca4cf11..d36fe30 100644 (file)
@@ -15,4 +15,3 @@ var foo = (function Module(stdlib, foreign, heap) {
 })(stdlib, foreign, buffer).foo;
 
 assertFalse(foo(1));
-assertTrue(foo(0));
index 82e262f..060b1c1 100644 (file)
@@ -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()));
 }
 
 
index 1a5b76a..b6c0410 100644 (file)
@@ -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<UnaryOperator>
-    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<Object> zero = factory()->NewNumber(0);
-  Handle<Object> 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
 
 
index 11858b4..6807930 100644 (file)
@@ -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)