Index: src/compiler/effect-control-linearizer.cc |
diff --git a/src/compiler/effect-control-linearizer.cc b/src/compiler/effect-control-linearizer.cc |
index 245dbd07c7c03ff9a219ee3d8b725d902f713162..0e48932c8dd2157538a1691ed55f259b039731a8 100644 |
--- a/src/compiler/effect-control-linearizer.cc |
+++ b/src/compiler/effect-control-linearizer.cc |
@@ -829,8 +829,62 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node, |
#define __ gasm()-> |
Node* EffectControlLinearizer::LowerChangeFloat64ToTagged(Node* node) { |
+ CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op()); |
Node* value = node->InputAt(0); |
- return AllocateHeapNumberWithValue(value); |
+ |
+ auto done = __ MakeLabel<2>(MachineRepresentation::kTagged); |
+ auto if_heapnumber = |
+ __ MakeLabelFor(GraphAssemblerLabelType::kNonDeferred, |
+ 1 + (mode == CheckForMinusZeroMode::kCheckForMinusZero) + |
+ !machine()->Is64()); |
+ auto if_int32 = __ MakeLabel<1>(); |
+ |
+ Node* value32 = __ RoundFloat64ToInt32(value); |
+ __ GotoIf(__ Float64Equal(value, __ ChangeInt32ToFloat64(value32)), |
+ &if_int32); |
+ __ Goto(&if_heapnumber); |
+ |
+ __ Bind(&if_int32); |
+ { |
+ if (mode == CheckForMinusZeroMode::kCheckForMinusZero) { |
+ Node* zero = __ Int32Constant(0); |
+ auto if_zero = __ MakeDeferredLabel<1>(); |
+ auto if_smi = __ MakeLabel<2>(); |
+ |
+ __ GotoIf(__ Word32Equal(value32, zero), &if_zero); |
+ __ Goto(&if_smi); |
+ |
+ __ Bind(&if_zero); |
+ { |
+ // In case of 0, we need to check the high bits for the IEEE -0 pattern. |
+ __ GotoIf(__ Int32LessThan(__ Float64ExtractHighWord32(value), zero), |
+ &if_heapnumber); |
+ __ Goto(&if_smi); |
+ } |
+ |
+ __ Bind(&if_smi); |
+ } |
+ |
+ if (machine()->Is64()) { |
+ Node* value_smi = ChangeInt32ToSmi(value32); |
+ __ Goto(&done, value_smi); |
+ } else { |
+ Node* add = __ Int32AddWithOverflow(value32, value32); |
+ Node* ovf = __ Projection(1, add); |
+ __ GotoIf(ovf, &if_heapnumber); |
+ Node* value_smi = __ Projection(0, add); |
+ __ Goto(&done, value_smi); |
+ } |
+ } |
+ |
+ __ Bind(&if_heapnumber); |
+ { |
+ Node* value_number = AllocateHeapNumberWithValue(value); |
+ __ Goto(&done, value_number); |
+ } |
+ |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
} |
Node* EffectControlLinearizer::LowerChangeFloat64ToTaggedPointer(Node* node) { |