Commit bb572428 authored by Benedikt Meurer's avatar Benedikt Meurer Committed by Commit Bot

[turbofan] Word64 conversions are lossless for Int64/Uint64 values.

Teach TurboFan about representation changes from Float64 to Word64 where
the input value is already known to be within the Int64 or Uint64 range.
While not all of these values have representations in Float64, those
that do can be converted to Word64 without loss of precision.

Same is true for Tagged to Word64 conversions, although here we don't
(currently) need the case for Uint64 ranges, so we can skip adding an
operator for that until it becomes necessary (there's a hard check in
the code so it'll not silently cause trouble).

Bug: v8:8178
Change-Id: Ie99b0bc9af096bd927f63b26b0a61e66454bc4ae
Reviewed-on: https://chromium-review.googlesource.com/1231593Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56022}
parent fef047a4
......@@ -974,17 +974,23 @@ Node* RepresentationChanger::GetWord64RepresentationFor(
MachineRepresentation::kWord64);
}
} else if (output_rep == MachineRepresentation::kFloat32) {
if (output_type.Is(cache_.kSafeInteger)) {
if (output_type.Is(cache_.kInt64)) {
// float32 -> float64 -> int64
node = InsertChangeFloat32ToFloat64(node);
op = machine()->ChangeFloat64ToInt64();
} else if (output_type.Is(cache_.kUint64)) {
// float32 -> float64 -> uint64
node = InsertChangeFloat32ToFloat64(node);
op = machine()->ChangeFloat64ToUint64();
} else {
return TypeError(node, output_rep, output_type,
MachineRepresentation::kWord64);
}
} else if (output_rep == MachineRepresentation::kFloat64) {
if (output_type.Is(cache_.kSafeInteger)) {
if (output_type.Is(cache_.kInt64)) {
op = machine()->ChangeFloat64ToInt64();
} else if (output_type.Is(cache_.kUint64)) {
op = machine()->ChangeFloat64ToUint64();
} else {
return TypeError(node, output_rep, output_type,
MachineRepresentation::kWord64);
......@@ -997,7 +1003,7 @@ Node* RepresentationChanger::GetWord64RepresentationFor(
MachineRepresentation::kWord64);
}
} else if (CanBeTaggedPointer(output_rep)) {
if (output_type.Is(cache_.kSafeInteger)) {
if (output_type.Is(cache_.kInt64)) {
op = simplified()->ChangeTaggedToInt64();
} else {
return TypeError(node, output_rep, output_type,
......
......@@ -35,6 +35,8 @@ class TypeCache final {
Type const kUint16 = CreateRange<uint16_t>();
Type const kInt32 = Type::Signed32();
Type const kUint32 = Type::Unsigned32();
Type const kInt64 = CreateRange<int64_t>();
Type const kUint64 = CreateRange<uint64_t>();
Type const kFloat32 = Type::Number();
Type const kFloat64 = Type::Number();
Type const kBigInt64 = Type::BigInt();
......
......@@ -383,6 +383,10 @@ TEST(Word64) {
Type::Unsigned32(), MachineRepresentation::kWord64);
CheckChange(IrOpcode::kChangeFloat64ToInt64, MachineRepresentation::kFloat64,
TypeCache::Get().kSafeInteger, MachineRepresentation::kWord64);
CheckChange(IrOpcode::kChangeFloat64ToInt64, MachineRepresentation::kFloat64,
TypeCache::Get().kInt64, MachineRepresentation::kWord64);
CheckChange(IrOpcode::kChangeFloat64ToUint64, MachineRepresentation::kFloat64,
TypeCache::Get().kUint64, MachineRepresentation::kWord64);
CheckChange(IrOpcode::kChangeInt64ToFloat64, MachineRepresentation::kWord64,
Type::Signed32(), MachineRepresentation::kFloat64);
......@@ -399,6 +403,14 @@ TEST(Word64) {
IrOpcode::kChangeFloat64ToInt64,
MachineRepresentation::kFloat32, Type::Unsigned32(),
MachineRepresentation::kWord64);
CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
IrOpcode::kChangeFloat64ToInt64,
MachineRepresentation::kFloat32, TypeCache::Get().kInt64,
MachineRepresentation::kWord64);
CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
IrOpcode::kChangeFloat64ToUint64,
MachineRepresentation::kFloat32, TypeCache::Get().kUint64,
MachineRepresentation::kWord64);
CheckTwoChanges(IrOpcode::kChangeInt64ToFloat64,
IrOpcode::kTruncateFloat64ToFloat32,
......@@ -411,6 +423,8 @@ TEST(Word64) {
Type::Unsigned32(), MachineRepresentation::kWord64);
CheckChange(IrOpcode::kChangeTaggedToInt64, MachineRepresentation::kTagged,
TypeCache::Get().kSafeInteger, MachineRepresentation::kWord64);
CheckChange(IrOpcode::kChangeTaggedToInt64, MachineRepresentation::kTagged,
TypeCache::Get().kInt64, MachineRepresentation::kWord64);
CheckChange(IrOpcode::kChangeTaggedSignedToInt64,
MachineRepresentation::kTaggedSigned, Type::SignedSmall(),
MachineRepresentation::kWord64);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment