Commit 1389b9f5 authored by ahaas's avatar ahaas Committed by Commit bot

[turbofan] Added the optional Float64RoundUp operator to turbofan.

I implemented it on x64, ia32, arm, arm64, mips, mips64, and ppc.

Review URL: https://codereview.chromium.org/1444583002

Cr-Commit-Position: refs/heads/master@{#32004}
parent 56791805
......@@ -1120,6 +1120,11 @@ void InstructionSelector::VisitFloat64RoundDown(Node* node) {
}
void InstructionSelector::VisitFloat64RoundUp(Node* node) {
VisitRR(this, kArmVrintpF64, node);
}
void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
VisitRR(this, kArmVrintzF64, node);
}
......@@ -1556,6 +1561,7 @@ InstructionSelector::SupportedMachineOperatorFlags() {
MachineOperatorBuilder::kUint32DivIsSafe;
if (CpuFeatures::IsSupported(ARMv8)) {
flags |= MachineOperatorBuilder::kFloat64RoundDown |
MachineOperatorBuilder::kFloat64RoundUp |
MachineOperatorBuilder::kFloat64RoundTruncate |
MachineOperatorBuilder::kFloat64RoundTiesAway;
}
......
......@@ -1463,6 +1463,11 @@ void InstructionSelector::VisitFloat64RoundDown(Node* node) {
}
void InstructionSelector::VisitFloat64RoundUp(Node* node) {
VisitRR(this, kArm64Float64RoundUp, node);
}
void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
VisitRR(this, kArm64Float64RoundTruncate, node);
}
......@@ -2041,6 +2046,7 @@ InstructionSelector::SupportedMachineOperatorFlags() {
MachineOperatorBuilder::kFloat64Max |
MachineOperatorBuilder::kFloat64Min |
MachineOperatorBuilder::kFloat64RoundDown |
MachineOperatorBuilder::kFloat64RoundUp |
MachineOperatorBuilder::kFloat64RoundTruncate |
MachineOperatorBuilder::kFloat64RoundTiesAway |
MachineOperatorBuilder::kWord32ShiftIsSafe |
......
......@@ -856,6 +856,11 @@ void InstructionSelector::VisitFloat64RoundDown(Node* node) {
}
void InstructionSelector::VisitFloat64RoundUp(Node* node) {
VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundUp));
}
void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundToZero));
}
......@@ -1275,6 +1280,7 @@ InstructionSelector::SupportedMachineOperatorFlags() {
}
if (CpuFeatures::IsSupported(SSE4_1)) {
flags |= MachineOperatorBuilder::kFloat64RoundDown |
MachineOperatorBuilder::kFloat64RoundUp |
MachineOperatorBuilder::kFloat64RoundTruncate;
}
return flags;
......
......@@ -886,6 +886,8 @@ void InstructionSelector::VisitNode(Node* node) {
return VisitFloat64LessThanOrEqual(node);
case IrOpcode::kFloat64RoundDown:
return MarkAsFloat64(node), VisitFloat64RoundDown(node);
case IrOpcode::kFloat64RoundUp:
return MarkAsFloat64(node), VisitFloat64RoundUp(node);
case IrOpcode::kFloat64RoundTruncate:
return MarkAsFloat64(node), VisitFloat64RoundTruncate(node);
case IrOpcode::kFloat64RoundTiesAway:
......
......@@ -184,6 +184,7 @@ CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const* op) {
V(Float64Max, Operator::kNoProperties, 2, 0, 1) \
V(Float64Min, Operator::kNoProperties, 2, 0, 1) \
V(Float64RoundDown, Operator::kNoProperties, 1, 0, 1) \
V(Float64RoundUp, Operator::kNoProperties, 1, 0, 1) \
V(Float64RoundTruncate, Operator::kNoProperties, 1, 0, 1) \
V(Float64RoundTiesAway, Operator::kNoProperties, 1, 0, 1)
......
......@@ -117,19 +117,20 @@ class MachineOperatorBuilder final : public ZoneObject {
kFloat64Max = 1u << 2,
kFloat64Min = 1u << 3,
kFloat64RoundDown = 1u << 4,
kFloat64RoundTruncate = 1u << 5,
kFloat64RoundTiesAway = 1u << 6,
kInt32DivIsSafe = 1u << 7,
kUint32DivIsSafe = 1u << 8,
kWord32ShiftIsSafe = 1u << 9,
kWord32Ctz = 1u << 10,
kWord32Popcnt = 1u << 11,
kFloat64RoundUp = 1u << 5,
kFloat64RoundTruncate = 1u << 6,
kFloat64RoundTiesAway = 1u << 7,
kInt32DivIsSafe = 1u << 8,
kUint32DivIsSafe = 1u << 9,
kWord32ShiftIsSafe = 1u << 10,
kWord32Ctz = 1u << 11,
kWord64Ctz = 1u << 12,
kWord64Popcnt = 1u << 13,
kWord32Popcnt = 1u << 13,
kWord64Popcnt = 1u << 14,
kAllOptionalOps = kFloat32Max | kFloat32Min | kFloat64Max | kFloat64Min |
kFloat64RoundDown | kFloat64RoundTruncate |
kFloat64RoundTiesAway | kWord32Ctz | kWord32Popcnt |
kWord64Ctz | kWord64Popcnt
kFloat64RoundDown | kFloat64RoundUp |
kFloat64RoundTruncate | kFloat64RoundTiesAway |
kWord32Ctz | kWord64Ctz | kWord32Popcnt | kWord64Popcnt
};
typedef base::Flags<Flag, unsigned> Flags;
......@@ -263,6 +264,7 @@ class MachineOperatorBuilder final : public ZoneObject {
// Floating point rounding.
const OptionalOperator Float64RoundDown();
const OptionalOperator Float64RoundUp();
const OptionalOperator Float64RoundTruncate();
const OptionalOperator Float64RoundTiesAway();
......
......@@ -588,6 +588,9 @@ void InstructionSelector::VisitFloat64RoundDown(Node* node) {
}
void InstructionSelector::VisitFloat64RoundUp(Node* node) { UNREACHABLE(); }
void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
VisitRR(this, kMipsFloat64RoundTruncate, node);
}
......
......@@ -802,6 +802,11 @@ void InstructionSelector::VisitFloat64RoundDown(Node* node) {
}
void InstructionSelector::VisitFloat64RoundUp(Node* node) {
VisitRR(this, kMips64Float64RoundUp, node);
}
void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
VisitRR(this, kMips64Float64RoundTruncate, node);
}
......@@ -1392,6 +1397,7 @@ InstructionSelector::SupportedMachineOperatorFlags() {
MachineOperatorBuilder::kFloat32Min |
MachineOperatorBuilder::kFloat32Max |
MachineOperatorBuilder::kFloat64RoundDown |
MachineOperatorBuilder::kFloat64RoundUp |
MachineOperatorBuilder::kFloat64RoundTruncate;
}
......
......@@ -298,6 +298,7 @@
V(Float64Abs) \
V(Float64Sqrt) \
V(Float64RoundDown) \
V(Float64RoundUp) \
V(Float64RoundTruncate) \
V(Float64RoundTiesAway) \
V(Float64ExtractLowWord32) \
......
......@@ -1118,6 +1118,11 @@ void InstructionSelector::VisitFloat64RoundDown(Node* node) {
}
void InstructionSelector::VisitFloat64RoundUp(Node* node) {
VisitRR(this, kPPC_CeilDouble, node);
}
void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
VisitRR(this, kPPC_TruncateDouble, node);
}
......@@ -1633,6 +1638,7 @@ void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) {
MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() {
return MachineOperatorBuilder::kFloat64RoundDown |
MachineOperatorBuilder::kFloat64RoundUp |
MachineOperatorBuilder::kFloat64RoundTruncate |
MachineOperatorBuilder::kFloat64RoundTiesAway |
MachineOperatorBuilder::kWord32Popcnt |
......
......@@ -482,6 +482,9 @@ class RawMachineAssembler {
Node* Float64RoundDown(Node* a) {
return AddNode(machine()->Float64RoundDown().op(), a);
}
Node* Float64RoundUp(Node* a) {
return AddNode(machine()->Float64RoundUp().op(), a);
}
Node* Float64RoundTruncate(Node* a) {
return AddNode(machine()->Float64RoundTruncate().op(), a);
}
......
......@@ -2234,6 +2234,12 @@ Type* Typer::Visitor::TypeFloat64RoundDown(Node* node) {
}
Type* Typer::Visitor::TypeFloat64RoundUp(Node* node) {
// TODO(sigurds): We could have a tighter bound here.
return Type::Number();
}
Type* Typer::Visitor::TypeFloat64RoundTruncate(Node* node) {
// TODO(sigurds): We could have a tighter bound here.
return Type::Number();
......
......@@ -879,6 +879,7 @@ void Verifier::Visitor::Check(Node* node) {
case IrOpcode::kFloat64Abs:
case IrOpcode::kFloat64Sqrt:
case IrOpcode::kFloat64RoundDown:
case IrOpcode::kFloat64RoundUp:
case IrOpcode::kFloat64RoundTruncate:
case IrOpcode::kFloat64RoundTiesAway:
case IrOpcode::kFloat64Equal:
......
......@@ -1123,6 +1123,11 @@ void InstructionSelector::VisitFloat64RoundDown(Node* node) {
}
void InstructionSelector::VisitFloat64RoundUp(Node* node) {
VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundUp));
}
void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundToZero));
}
......@@ -1662,6 +1667,7 @@ InstructionSelector::SupportedMachineOperatorFlags() {
}
if (CpuFeatures::IsSupported(SSE4_1)) {
flags |= MachineOperatorBuilder::kFloat64RoundDown |
MachineOperatorBuilder::kFloat64RoundUp |
MachineOperatorBuilder::kFloat64RoundTruncate;
}
return flags;
......
......@@ -849,6 +849,9 @@ void InstructionSelector::VisitFloat64RoundDown(Node* node) {
}
void InstructionSelector::VisitFloat64RoundUp(Node* node) { UNREACHABLE(); }
void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
X87OperandGenerator g(this);
Emit(kX87Float64Round | MiscField::encode(kRoundToZero),
......
......@@ -5155,57 +5155,43 @@ TEST(RunFloat64RoundDown1) {
TEST(RunFloat64RoundDown2) {
double input = -1.0;
double result = 0.0;
RawMachineAssemblerTester<int32_t> m;
BufferedRawMachineAssemblerTester<double> m(kMachFloat64);
if (!m.machine()->Float64RoundDown().IsSupported()) return;
m.StoreToPointer(&result, kMachFloat64,
m.Float64Sub(m.Float64Constant(-0.0),
m.Float64RoundDown(m.Float64Sub(
m.Float64Constant(-0.0),
m.LoadFromPointer(&input, kMachFloat64)))));
m.Return(m.Int32Constant(0));
m.Return(m.Float64Sub(m.Float64Constant(-0.0),
m.Float64RoundDown(m.Float64Sub(m.Float64Constant(-0.0),
m.Parameter(0)))));
for (size_t i = 0; i < arraysize(kValues); ++i) {
input = kValues[i];
CHECK_EQ(0, m.Call());
double expected = std::ceil(kValues[i]);
CHECK_EQ(expected, result);
CHECK_EQ(std::ceil(kValues[i]), m.Call(kValues[i]));
}
}
TEST(RunFloat64RoundUp) {
BufferedRawMachineAssemblerTester<double> m(kMachFloat64);
if (!m.machine()->Float64RoundUp().IsSupported()) return;
m.Return(m.Float64RoundUp(m.Parameter(0)));
FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(std::ceil(*i), m.Call(*i)); }
}
TEST(RunFloat64RoundTruncate) {
double input = -1.0;
double result = 0.0;
RawMachineAssemblerTester<int32_t> m;
BufferedRawMachineAssemblerTester<double> m(kMachFloat64);
if (!m.machine()->Float64RoundTruncate().IsSupported()) return;
m.StoreToPointer(
&result, kMachFloat64,
m.Float64RoundTruncate(m.LoadFromPointer(&input, kMachFloat64)));
m.Return(m.Int32Constant(0));
m.Return(m.Float64RoundTruncate(m.Parameter(0)));
for (size_t i = 0; i < arraysize(kValues); ++i) {
input = kValues[i];
CHECK_EQ(0, m.Call());
double expected = trunc(kValues[i]);
CHECK_EQ(expected, result);
CHECK_EQ(trunc(kValues[i]), m.Call(kValues[i]));
}
}
TEST(RunFloat64RoundTiesAway) {
double input = -1.0;
double result = 0.0;
RawMachineAssemblerTester<int32_t> m;
BufferedRawMachineAssemblerTester<double> m(kMachFloat64);
if (!m.machine()->Float64RoundTiesAway().IsSupported()) return;
m.StoreToPointer(
&result, kMachFloat64,
m.Float64RoundTiesAway(m.LoadFromPointer(&input, kMachFloat64)));
m.Return(m.Int32Constant(0));
m.Return(m.Float64RoundTiesAway(m.Parameter(0)));
for (size_t i = 0; i < arraysize(kValues); ++i) {
input = kValues[i];
CHECK_EQ(0, m.Call());
double expected = round(kValues[i]);
CHECK_EQ(expected, result);
CHECK_EQ(round(kValues[i]), m.Call(kValues[i]));
}
}
......
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