aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/effect-control-linearizer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/effect-control-linearizer.cc')
-rw-r--r--deps/v8/src/compiler/effect-control-linearizer.cc47
1 files changed, 43 insertions, 4 deletions
diff --git a/deps/v8/src/compiler/effect-control-linearizer.cc b/deps/v8/src/compiler/effect-control-linearizer.cc
index 97f78418d0..5f56d080d9 100644
--- a/deps/v8/src/compiler/effect-control-linearizer.cc
+++ b/deps/v8/src/compiler/effect-control-linearizer.cc
@@ -797,6 +797,9 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
case IrOpcode::kObjectIsMinusZero:
result = LowerObjectIsMinusZero(node);
break;
+ case IrOpcode::kNumberIsMinusZero:
+ result = LowerNumberIsMinusZero(node);
+ break;
case IrOpcode::kObjectIsNaN:
result = LowerObjectIsNaN(node);
break;
@@ -2543,6 +2546,14 @@ Node* EffectControlLinearizer::LowerObjectIsSafeInteger(Node* node) {
return done.PhiAt(0);
}
+namespace {
+
+const int64_t kMinusZeroBits = bit_cast<int64_t>(-0.0);
+const int32_t kMinusZeroLoBits = static_cast<int32_t>(kMinusZeroBits);
+const int32_t kMinusZeroHiBits = static_cast<int32_t>(kMinusZeroBits >> 32);
+
+} // namespace
+
Node* EffectControlLinearizer::LowerObjectIsMinusZero(Node* node) {
Node* value = node->InputAt(0);
Node* zero = __ Int32Constant(0);
@@ -2559,15 +2570,43 @@ Node* EffectControlLinearizer::LowerObjectIsMinusZero(Node* node) {
// Check if {value} contains -0.
Node* value_value = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
- __ Goto(&done,
- __ Float64Equal(
- __ Float64Div(__ Float64Constant(1.0), value_value),
- __ Float64Constant(-std::numeric_limits<double>::infinity())));
+ if (machine()->Is64()) {
+ Node* value64 = __ BitcastFloat64ToInt64(value_value);
+ __ Goto(&done, __ Word64Equal(value64, __ Int64Constant(kMinusZeroBits)));
+ } else {
+ Node* value_lo = __ Float64ExtractLowWord32(value_value);
+ __ GotoIfNot(__ Word32Equal(value_lo, __ Int32Constant(kMinusZeroLoBits)),
+ &done, zero);
+ Node* value_hi = __ Float64ExtractHighWord32(value_value);
+ __ Goto(&done,
+ __ Word32Equal(value_hi, __ Int32Constant(kMinusZeroHiBits)));
+ }
__ Bind(&done);
return done.PhiAt(0);
}
+Node* EffectControlLinearizer::LowerNumberIsMinusZero(Node* node) {
+ Node* value = node->InputAt(0);
+
+ if (machine()->Is64()) {
+ Node* value64 = __ BitcastFloat64ToInt64(value);
+ return __ Word64Equal(value64, __ Int64Constant(kMinusZeroBits));
+ } else {
+ auto done = __ MakeLabel(MachineRepresentation::kBit);
+
+ Node* value_lo = __ Float64ExtractLowWord32(value);
+ __ GotoIfNot(__ Word32Equal(value_lo, __ Int32Constant(kMinusZeroLoBits)),
+ &done, __ Int32Constant(0));
+ Node* value_hi = __ Float64ExtractHighWord32(value);
+ __ Goto(&done,
+ __ Word32Equal(value_hi, __ Int32Constant(kMinusZeroHiBits)));
+
+ __ Bind(&done);
+ return done.PhiAt(0);
+ }
+}
+
Node* EffectControlLinearizer::LowerObjectIsNaN(Node* node) {
Node* value = node->InputAt(0);
Node* zero = __ Int32Constant(0);