Commit d594a6d9 authored by Enrico Bacis's avatar Enrico Bacis Committed by Commit Bot

[turbofan] Remove ToFloat64AsInt and make ToFloat64 return a Double

Returning a double from ToFloat64 could lead to problems. If value_ has the bit
representation of a signaling NaN (sNaN), then returning it as double can cause
the signaling bit to flip, and value_ is returned as a quiet NaN (qNaN).

The usage of the Double wrapper also, makes the function ToFloat64AsInt
redundant, since the Double wrapper already has the AsUint64() method,
which returns an uint64_t.

R=ahaas@chromium.org

Change-Id: I1e627b97b2fb6110fc702fe58f2b83eb343e9ca2
Reviewed-on: https://chromium-review.googlesource.com/563215
Commit-Queue: Enrico Bacis <enricobacis@google.com>
Reviewed-by: 's avatarMartyn Capewell <martyn.capewell@arm.com>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46680}
parent b53141ec
......@@ -51,7 +51,7 @@ class ArmOperandConverter final : public InstructionOperandConverter {
case Constant::kFloat32:
return Operand::EmbeddedNumber(constant.ToFloat32());
case Constant::kFloat64:
return Operand::EmbeddedNumber(constant.ToFloat64());
return Operand::EmbeddedNumber(constant.ToFloat64().value());
case Constant::kInt64:
case Constant::kExternalReference:
case Constant::kHeapObject:
......@@ -2949,7 +2949,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
__ mov(dst, Operand::EmbeddedNumber(src.ToFloat32()));
break;
case Constant::kFloat64:
__ mov(dst, Operand::EmbeddedNumber(src.ToFloat64()));
__ mov(dst, Operand::EmbeddedNumber(src.ToFloat64().value()));
break;
case Constant::kExternalReference:
__ mov(dst, Operand(src.ToExternalReference()));
......@@ -2983,7 +2983,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
DwVfpRegister dst = destination->IsFPRegister()
? g.ToDoubleRegister(destination)
: kScratchDoubleReg;
__ vmov(dst, Double(src.ToFloat64AsInt()), kScratchReg);
__ vmov(dst, src.ToFloat64(), kScratchReg);
if (destination->IsDoubleStackSlot()) {
__ vstr(dst, g.ToMemOperand(destination));
}
......
......@@ -228,7 +228,7 @@ class Arm64OperandConverter final : public InstructionOperandConverter {
case Constant::kFloat32:
return Operand(Operand::EmbeddedNumber(constant.ToFloat32()));
case Constant::kFloat64:
return Operand(Operand::EmbeddedNumber(constant.ToFloat64()));
return Operand(Operand::EmbeddedNumber(constant.ToFloat64().value()));
case Constant::kExternalReference:
return Operand(constant.ToExternalReference());
case Constant::kHeapObject:
......@@ -2658,15 +2658,15 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
DCHECK_EQ(Constant::kFloat64, src.type());
if (destination->IsFPRegister()) {
VRegister dst = g.ToDoubleRegister(destination);
__ Fmov(dst, src.ToFloat64());
__ Fmov(dst, src.ToFloat64().value());
} else {
DCHECK(destination->IsFPStackSlot());
if (bit_cast<int64_t>(src.ToFloat64()) == 0) {
if (src.ToFloat64().AsUint64() == 0) {
__ Str(xzr, g.ToMemOperand(destination, tasm()));
} else {
UseScratchRegisterScope scope(tasm());
VRegister temp = scope.AcquireD();
__ Fmov(temp, src.ToFloat64());
__ Fmov(temp, src.ToFloat64().value());
__ Str(temp, g.ToMemOperand(destination, tasm()));
}
}
......
......@@ -151,7 +151,9 @@ class InstructionOperandConverter {
ConstantOperand::cast(op)->virtual_register());
}
double ToDouble(InstructionOperand* op) { return ToConstant(op).ToFloat64(); }
double ToDouble(InstructionOperand* op) {
return ToConstant(op).ToFloat64().value();
}
float ToFloat32(InstructionOperand* op) { return ToConstant(op).ToFloat32(); }
......
......@@ -962,7 +962,7 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation,
case Constant::kFloat64:
DCHECK(type.representation() == MachineRepresentation::kFloat64 ||
type.representation() == MachineRepresentation::kTagged);
literal = DeoptimizationLiteral(constant.ToFloat64());
literal = DeoptimizationLiteral(constant.ToFloat64().value());
break;
case Constant::kHeapObject:
DCHECK_EQ(MachineRepresentation::kTagged, type.representation());
......
......@@ -75,7 +75,7 @@ class IA32OperandConverter : public InstructionOperandConverter {
case Constant::kFloat32:
return Immediate::EmbeddedNumber(constant.ToFloat32());
case Constant::kFloat64:
return Immediate::EmbeddedNumber(constant.ToFloat64());
return Immediate::EmbeddedNumber(constant.ToFloat64().value());
case Constant::kExternalReference:
return Immediate(constant.ToExternalReference());
case Constant::kHeapObject:
......@@ -2639,7 +2639,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
}
} else {
DCHECK_EQ(Constant::kFloat64, src_constant.type());
uint64_t src = src_constant.ToFloat64AsInt();
uint64_t src = src_constant.ToFloat64().AsUint64();
uint32_t lower = static_cast<uint32_t>(src);
uint32_t upper = static_cast<uint32_t>(src >> 32);
if (destination->IsFPRegister()) {
......
......@@ -576,7 +576,7 @@ std::ostream& operator<<(std::ostream& os, const Constant& constant) {
case Constant::kFloat32:
return os << constant.ToFloat32() << "f";
case Constant::kFloat64:
return os << constant.ToFloat64();
return os << constant.ToFloat64().value();
case Constant::kExternalReference:
return os << static_cast<const void*>(
constant.ToExternalReference().address());
......
......@@ -15,6 +15,7 @@
#include "src/compiler/frame.h"
#include "src/compiler/instruction-codes.h"
#include "src/compiler/opcodes.h"
#include "src/double.h"
#include "src/globals.h"
#include "src/macro-assembler.h"
#include "src/register-configuration.h"
......@@ -1074,20 +1075,9 @@ class V8_EXPORT_PRIVATE Constant final {
return bit_cast<uint32_t>(static_cast<int32_t>(value_));
}
double ToFloat64() const {
// TODO(ahaas): We should remove this function. If value_ has the bit
// representation of a signalling NaN, then returning it as float can cause
// the signalling bit to flip, and value_ is returned as a quiet NaN.
if (type() == kInt32) return ToInt32();
DCHECK_EQ(kFloat64, type());
return bit_cast<double>(value_);
}
// TODO(ahaas) Use the Double class instead of uint64_t.
uint64_t ToFloat64AsInt() const {
if (type() == kInt32) return ToInt32();
Double ToFloat64() const {
DCHECK_EQ(kFloat64, type());
return bit_cast<uint64_t>(value_);
return Double(bit_cast<uint64_t>(value_));
}
ExternalReference ToExternalReference() const {
......
......@@ -81,7 +81,7 @@ class MipsOperandConverter final : public InstructionOperandConverter {
case Constant::kFloat32:
return Operand::EmbeddedNumber(constant.ToFloat32());
case Constant::kFloat64:
return Operand::EmbeddedNumber(constant.ToFloat64());
return Operand::EmbeddedNumber(constant.ToFloat64().value());
case Constant::kInt64:
case Constant::kExternalReference:
case Constant::kHeapObject:
......@@ -3289,7 +3289,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
UNREACHABLE();
break;
case Constant::kFloat64:
__ li(dst, Operand::EmbeddedNumber(src.ToFloat64()));
__ li(dst, Operand::EmbeddedNumber(src.ToFloat64().value()));
break;
case Constant::kExternalReference:
__ li(dst, Operand(src.ToExternalReference()));
......@@ -3328,7 +3328,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
DoubleRegister dst = destination->IsFPRegister()
? g.ToDoubleRegister(destination)
: kScratchDoubleReg;
__ Move(dst, src.ToFloat64());
__ Move(dst, src.ToFloat64().value());
if (destination->IsFPStackSlot()) {
__ Sdc1(dst, g.ToMemOperand(destination));
}
......
......@@ -82,7 +82,7 @@ class MipsOperandConverter final : public InstructionOperandConverter {
case Constant::kFloat32:
return Operand::EmbeddedNumber(constant.ToFloat32());
case Constant::kFloat64:
return Operand::EmbeddedNumber(constant.ToFloat64());
return Operand::EmbeddedNumber(constant.ToFloat64().value());
case Constant::kExternalReference:
case Constant::kHeapObject:
// TODO(plind): Maybe we should handle ExtRef & HeapObj here?
......@@ -3588,7 +3588,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
}
break;
case Constant::kFloat64:
__ li(dst, Operand::EmbeddedNumber(src.ToFloat64()));
__ li(dst, Operand::EmbeddedNumber(src.ToFloat64().value()));
break;
case Constant::kExternalReference:
__ li(dst, Operand(src.ToExternalReference()));
......@@ -3627,7 +3627,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
DoubleRegister dst = destination->IsFPRegister()
? g.ToDoubleRegister(destination)
: kScratchDoubleReg;
__ Move(dst, src.ToFloat64());
__ Move(dst, src.ToFloat64().value());
if (destination->IsFPStackSlot()) {
__ Sdc1(dst, g.ToMemOperand(destination));
}
......
......@@ -65,8 +65,8 @@ class PPCOperandConverter final : public InstructionOperandConverter {
return Operand(
isolate()->factory()->NewNumber(constant.ToFloat32(), TENURED));
case Constant::kFloat64:
return Operand(
isolate()->factory()->NewNumber(constant.ToFloat64(), TENURED));
return Operand(isolate()->factory()->NewNumber(
constant.ToFloat64().value(), TENURED));
case Constant::kInt64:
#if V8_TARGET_ARCH_PPC64
return Operand(constant.ToInt64());
......@@ -2424,8 +2424,8 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
isolate()->factory()->NewNumber(src.ToFloat32(), TENURED));
break;
case Constant::kFloat64:
__ Move(dst,
isolate()->factory()->NewNumber(src.ToFloat64(), TENURED));
__ Move(dst, isolate()->factory()->NewNumber(src.ToFloat64().value(),
TENURED));
break;
case Constant::kExternalReference:
__ mov(dst, Operand(src.ToExternalReference()));
......@@ -2466,7 +2466,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
value = Double(static_cast<double>(src.ToFloat32()));
}
} else {
value = Double(src.ToFloat64AsInt());
value = src.ToFloat64();
}
#else
value = Double((src.type() == Constant::kFloat32)
......
......@@ -59,8 +59,8 @@ class S390OperandConverter final : public InstructionOperandConverter {
return Operand(
isolate()->factory()->NewNumber(constant.ToFloat32(), TENURED));
case Constant::kFloat64:
return Operand(
isolate()->factory()->NewNumber(constant.ToFloat64(), TENURED));
return Operand(isolate()->factory()->NewNumber(
constant.ToFloat64().value(), TENURED));
case Constant::kInt64:
#if V8_TARGET_ARCH_S390X
return Operand(constant.ToInt64());
......@@ -2794,8 +2794,8 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
isolate()->factory()->NewNumber(src.ToFloat32(), TENURED));
break;
case Constant::kFloat64:
__ Move(dst,
isolate()->factory()->NewNumber(src.ToFloat64(), TENURED));
__ Move(dst, isolate()->factory()->NewNumber(src.ToFloat64().value(),
TENURED));
break;
case Constant::kExternalReference:
__ mov(dst, Operand(src.ToExternalReference()));
......@@ -2821,8 +2821,9 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
DoubleRegister dst = destination->IsFPRegister()
? g.ToDoubleRegister(destination)
: kScratchDoubleReg;
double value = (src.type() == Constant::kFloat32) ? src.ToFloat32()
: src.ToFloat64();
double value = (src.type() == Constant::kFloat32)
? src.ToFloat32()
: src.ToFloat64().value();
if (src.type() == Constant::kFloat32) {
__ LoadFloat32Literal(dst, src.ToFloat32(), kScratchReg);
} else {
......
......@@ -41,7 +41,7 @@ class X64OperandConverter : public InstructionOperandConverter {
Immediate ToImmediate(InstructionOperand* operand) {
Constant constant = ToConstant(operand);
if (constant.type() == Constant::kFloat64) {
DCHECK_EQ(0, bit_cast<int64_t>(constant.ToFloat64()));
DCHECK_EQ(0, constant.ToFloat64().AsUint64());
return Immediate(0);
}
if (RelocInfo::IsWasmReference(constant.rmode())) {
......@@ -3192,7 +3192,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
__ MoveNumber(dst, src.ToFloat32());
break;
case Constant::kFloat64:
__ MoveNumber(dst, src.ToFloat64());
__ MoveNumber(dst, src.ToFloat64().value());
break;
case Constant::kExternalReference:
__ Move(dst, src.ToExternalReference());
......@@ -3226,7 +3226,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
}
} else {
DCHECK_EQ(Constant::kFloat64, src.type());
uint64_t src_const = bit_cast<uint64_t>(src.ToFloat64());
uint64_t src_const = src.ToFloat64().AsUint64();
if (destination->IsFPRegister()) {
__ Move(g.ToDoubleRegister(destination), src_const);
} else {
......
......@@ -71,8 +71,8 @@ class X87OperandConverter : public InstructionOperandConverter {
return Immediate(
isolate()->factory()->NewNumber(constant.ToFloat32(), TENURED));
case Constant::kFloat64:
return Immediate(
isolate()->factory()->NewNumber(constant.ToFloat64(), TENURED));
return Immediate(isolate()->factory()->NewNumber(
constant.ToFloat64(value()).value(), TENURED));
case Constant::kExternalReference:
return Immediate(constant.ToExternalReference());
case Constant::kHeapObject:
......@@ -1080,7 +1080,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Constant src_constant = g.ToConstant(source);
DCHECK_EQ(Constant::kFloat64, src_constant.type());
uint64_t src = bit_cast<uint64_t>(src_constant.ToFloat64());
uint64_t src = src_constant.ToFloat64().AsUint64();
uint32_t lower = static_cast<uint32_t>(src);
uint32_t upper = static_cast<uint32_t>(src >> 32);
if (destination->IsFPRegister()) {
......@@ -2600,7 +2600,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
}
} else {
DCHECK_EQ(Constant::kFloat64, src_constant.type());
uint64_t src = src_constant.ToFloat64AsInt();
uint64_t src = src_constant.ToFloat64().AsUint64();
uint32_t lower = static_cast<uint32_t>(src);
uint32_t upper = static_cast<uint32_t>(src >> 32);
if (destination->IsFPRegister()) {
......
......@@ -201,7 +201,7 @@ class InstructionSelectorTest : public TestWithContext,
}
double ToFloat64(const InstructionOperand* operand) const {
return ToConstant(operand).ToFloat64();
return ToConstant(operand).ToFloat64().value();
}
int32_t ToInt32(const InstructionOperand* operand) const {
......
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