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.