Reviewers: jarin,

Description:
[turbofan] Fix HashCode/Equals for floating point operators.

Those floating point constant operators require bitwise handling of
their parameters, otherwise 0.0 equals -0.0.

TEST=unittests
[email protected]

Please review this at https://codereview.chromium.org/636953002/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+78, -10 lines):
  M src/compiler/common-operator.cc
  M test/unittests/compiler/common-operator-unittest.cc


Index: src/compiler/common-operator.cc
diff --git a/src/compiler/common-operator.cc b/src/compiler/common-operator.cc index cf85017bed0eacf1b0572f010dbc2d0aa619fc0c..1dc3a40f88c422a2203c66a5149818b387847540 100644
--- a/src/compiler/common-operator.cc
+++ b/src/compiler/common-operator.cc
@@ -27,6 +27,24 @@ class ControlOperator : public Operator1<int> {
   virtual void PrintParameter(std::ostream& os) const FINAL {}
 };

+
+template <typename ActualType, typename BitType>
+struct BitEqualTo : public std::binary_function<ActualType, ActualType, bool> {
+  V8_INLINE bool operator()(ActualType lhs, ActualType rhs) const {
+    return pred_(bit_cast<BitType>(lhs), bit_cast<BitType>(rhs));
+  }
+  std::equal_to<BitType> pred_;
+};
+
+
+template <typename ActualType, typename BitType>
+struct BitHash : public std::unary_function<ActualType, size_t> {
+  V8_INLINE size_t operator()(ActualType v) const {
+    return hash_(bit_cast<BitType>(v));
+  }
+  base::hash<BitType> hash_;
+};
+
 }  // namespace


@@ -150,15 +168,17 @@ const Operator* CommonOperatorBuilder::Int64Constant(int64_t value) {

const Operator* CommonOperatorBuilder::Float32Constant(volatile float value) {
   return new (zone())
-      Operator1<float>(IrOpcode::kFloat32Constant, Operator::kPure, 0, 1,
-                       "Float32Constant", value);
+ Operator1<float, BitEqualTo<float, uint32_t>, BitHash<float, uint32_t>>( + IrOpcode::kFloat32Constant, Operator::kPure, 0, 1, "Float32Constant",
+          value);
 }


const Operator* CommonOperatorBuilder::Float64Constant(volatile double value) {
-  return new (zone())
-      Operator1<double>(IrOpcode::kFloat64Constant, Operator::kPure, 0, 1,
-                        "Float64Constant", value);
+  return new (zone()) Operator1<double, BitEqualTo<double, uint64_t>,
+                                BitHash<double, uint64_t>>(
+      IrOpcode::kFloat64Constant, Operator::kPure, 0, 1, "Float64Constant",
+      value);
 }


@@ -171,9 +191,10 @@ const Operator* CommonOperatorBuilder::ExternalConstant(


const Operator* CommonOperatorBuilder::NumberConstant(volatile double value) {
-  return new (zone())
-      Operator1<double>(IrOpcode::kNumberConstant, Operator::kPure, 0, 1,
-                        "NumberConstant", value);
+  return new (zone()) Operator1<double, BitEqualTo<double, uint64_t>,
+                                BitHash<double, uint64_t>>(
+      IrOpcode::kNumberConstant, Operator::kPure, 0, 1, "NumberConstant",
+      value);
 }


Index: test/unittests/compiler/common-operator-unittest.cc
diff --git a/test/unittests/compiler/common-operator-unittest.cc b/test/unittests/compiler/common-operator-unittest.cc index 2cb4d19fe259f5eb26a551dcb07769c8099f838d..9ed74edbd9413821b805cc36fd3f088375a351eb 100644
--- a/test/unittests/compiler/common-operator-unittest.cc
+++ b/test/unittests/compiler/common-operator-unittest.cc
@@ -133,15 +133,21 @@ class CommonOperatorTest : public TestWithZone {

 const int kArguments[] = {1, 5, 6, 42, 100, 10000, kMaxInt};

-const float kFloat32Values[] = {
+
+const float kFloatValues[] = {
     std::numeric_limits<float>::min(), -1.0f, -0.0f, 0.0f, 1.0f,
     std::numeric_limits<float>::max()};

+
+const double kDoubleValues[] = {
+    std::numeric_limits<double>::min(), -1.0, -0.0, 0.0, 1.0,
+    std::numeric_limits<double>::max()};
+
 }  // namespace


 TEST_F(CommonOperatorTest, Float32Constant) {
-  TRACED_FOREACH(float, value, kFloat32Values) {
+  TRACED_FOREACH(float, value, kFloatValues) {
     const Operator* op = common()->Float32Constant(value);
     EXPECT_FLOAT_EQ(value, OpParameter<float>(op));
     EXPECT_EQ(0, OperatorProperties::GetValueInputCount(op));
@@ -150,6 +156,47 @@ TEST_F(CommonOperatorTest, Float32Constant) {
     EXPECT_EQ(0, OperatorProperties::GetEffectOutputCount(op));
     EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
   }
+  const Operator* zero = common()->Float32Constant(0.0f);
+  const Operator* minus_zero = common()->Float32Constant(-0.0f);
+  EXPECT_FALSE(zero->Equals(minus_zero));
+  EXPECT_FALSE(minus_zero->Equals(zero));
+  EXPECT_NE(zero->HashCode(), minus_zero->HashCode());
+}
+
+
+TEST_F(CommonOperatorTest, Float64Constant) {
+  TRACED_FOREACH(double, value, kDoubleValues) {
+    const Operator* op = common()->Float64Constant(value);
+    EXPECT_DOUBLE_EQ(value, OpParameter<double>(op));
+    EXPECT_EQ(0, OperatorProperties::GetValueInputCount(op));
+    EXPECT_EQ(0, OperatorProperties::GetTotalInputCount(op));
+    EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
+    EXPECT_EQ(0, OperatorProperties::GetEffectOutputCount(op));
+    EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
+  }
+  const Operator* zero = common()->Float64Constant(0.0);
+  const Operator* minus_zero = common()->Float64Constant(-0.0);
+  EXPECT_FALSE(zero->Equals(minus_zero));
+  EXPECT_FALSE(minus_zero->Equals(zero));
+  EXPECT_NE(zero->HashCode(), minus_zero->HashCode());
+}
+
+
+TEST_F(CommonOperatorTest, NumberConstant) {
+  TRACED_FOREACH(double, value, kDoubleValues) {
+    const Operator* op = common()->NumberConstant(value);
+    EXPECT_DOUBLE_EQ(value, OpParameter<double>(op));
+    EXPECT_EQ(0, OperatorProperties::GetValueInputCount(op));
+    EXPECT_EQ(0, OperatorProperties::GetTotalInputCount(op));
+    EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
+    EXPECT_EQ(0, OperatorProperties::GetEffectOutputCount(op));
+    EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
+  }
+  const Operator* zero = common()->NumberConstant(0.0);
+  const Operator* minus_zero = common()->NumberConstant(-0.0);
+  EXPECT_FALSE(zero->Equals(minus_zero));
+  EXPECT_FALSE(minus_zero->Equals(zero));
+  EXPECT_NE(zero->HashCode(), minus_zero->HashCode());
 }




--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to