Commit 552601bb authored by ahaas's avatar ahaas Committed by Commit bot

[turbofan] Lower "-0.0 - x" in the MachineOperatorReducer.

Up until now "-0.0 - x" was lowered in the instruction selector. I moved
the lowering now to the MachineOperatorReducer.

I did not remove the lowering from the instruction selector yet, I would
prefer to do that in a separate CL.

R=bmeurer@chromium.org

Review-Url: https://codereview.chromium.org/2226663002
Cr-Commit-Position: refs/heads/master@{#38417}
parent 74feddd5
......@@ -314,6 +314,39 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
if (m.LeftEqualsRight()) return ReplaceBool(true); // x <= x => true
break;
}
case IrOpcode::kFloat32Sub: {
Float32BinopMatcher m(node);
if (m.right().Is(0) && (copysign(1.0, m.right().Value()) > 0)) {
return Replace(m.left().node()); // x - 0 => x
}
if (m.right().IsNaN()) { // x - NaN => NaN
return Replace(m.right().node());
}
if (m.left().IsNaN()) { // NaN - x => NaN
return Replace(m.left().node());
}
if (m.IsFoldable()) { // L - R => (L - R)
return ReplaceFloat32(m.left().Value() - m.right().Value());
}
if (m.left().IsMinusZero()) {
// -0.0 - round_down(-0.0 - R) => round_up(R)
if (machine()->Float32RoundUp().IsSupported() &&
m.right().IsFloat32RoundDown()) {
if (m.right().InputAt(0)->opcode() == IrOpcode::kFloat32Sub) {
Float32BinopMatcher mright0(m.right().InputAt(0));
if (mright0.left().IsMinusZero()) {
return Replace(graph()->NewNode(machine()->Float32RoundUp().op(),
mright0.right().node()));
}
}
}
// -0.0 - R => -R
node->RemoveInput(0);
NodeProperties::ChangeOp(node, machine()->Float32Neg());
return Changed(node);
}
break;
}
case IrOpcode::kFloat64Add: {
Float64BinopMatcher m(node);
if (m.right().IsNaN()) { // x + NaN => NaN
......@@ -335,9 +368,26 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
if (m.left().IsNaN()) { // NaN - x => NaN
return Replace(m.left().node());
}
if (m.IsFoldable()) { // K - K => K
if (m.IsFoldable()) { // L - R => (L - R)
return ReplaceFloat64(m.left().Value() - m.right().Value());
}
if (m.left().IsMinusZero()) {
// -0.0 - round_down(-0.0 - R) => round_up(R)
if (machine()->Float64RoundUp().IsSupported() &&
m.right().IsFloat64RoundDown()) {
if (m.right().InputAt(0)->opcode() == IrOpcode::kFloat64Sub) {
Float64BinopMatcher mright0(m.right().InputAt(0));
if (mright0.left().IsMinusZero()) {
return Replace(graph()->NewNode(machine()->Float64RoundUp().op(),
mright0.right().node()));
}
}
}
// -0.0 - R => -R
node->RemoveInput(0);
NodeProperties::ChangeOp(node, machine()->Float64Neg());
return Changed(node);
}
break;
}
case IrOpcode::kFloat64Mul: {
......
......@@ -37,6 +37,11 @@ const Operator* NewConstantOperator<double>(CommonOperatorBuilder* common,
return common->Float64Constant(value);
}
template <>
const Operator* NewConstantOperator<float>(CommonOperatorBuilder* common,
volatile float value) {
return common->Float32Constant(value);
}
template <typename T>
T ValueOfOperator(const Operator* op);
......@@ -53,6 +58,12 @@ int64_t ValueOfOperator<int64_t>(const Operator* op) {
return OpParameter<int64_t>(op);
}
template <>
float ValueOfOperator<float>(const Operator* op) {
CHECK_EQ(IrOpcode::kFloat32Constant, op->opcode());
return OpParameter<float>(op);
}
template <>
double ValueOfOperator<double>(const Operator* op) {
CHECK_EQ(IrOpcode::kFloat64Constant, op->opcode());
......@@ -62,9 +73,9 @@ double ValueOfOperator<double>(const Operator* op) {
class ReducerTester : public HandleAndZoneScope {
public:
explicit ReducerTester(
int num_parameters = 0,
MachineOperatorBuilder::Flags flags = MachineOperatorBuilder::kNoFlags)
explicit ReducerTester(int num_parameters = 0,
MachineOperatorBuilder::Flags flags =
MachineOperatorBuilder::kAllOptionalOps)
: isolate(main_isolate()),
binop(NULL),
unop(NULL),
......@@ -117,7 +128,15 @@ class ReducerTester : public HandleAndZoneScope {
Reduction reduction = reducer.Reduce(n);
CHECK(reduction.Changed());
CHECK_NE(n, reduction.replacement());
CHECK_EQ(expect, ValueOf<T>(reduction.replacement()->op()));
// Deal with NaNs.
if (expect == expect) {
// We do not expect a NaN, check for equality.
CHECK_EQ(expect, ValueOf<T>(reduction.replacement()->op()));
} else {
// Check for NaN.
T result = ValueOf<T>(reduction.replacement()->op());
CHECK_NE(result, result);
}
}
// Check that the reduction of this binop applied to {a} and {b} yields
......@@ -821,6 +840,45 @@ TEST(ReduceLoadStore) {
}
}
TEST(ReduceFloat32Sub) {
ReducerTester R;
R.binop = R.machine.Float32Sub();
FOR_FLOAT32_INPUTS(pl) {
FOR_FLOAT32_INPUTS(pr) {
float x = *pl, y = *pr;
R.CheckFoldBinop<float>(x - y, x, y);
}
}
Node* x = R.Parameter();
Node* zero = R.Constant<float>(0.0);
Node* nan = R.Constant<float>(std::numeric_limits<float>::quiet_NaN());
R.CheckBinop(x, x, zero); // x - 0 => x
R.CheckBinop(nan, nan, x); // nan - x => nan
R.CheckBinop(nan, x, nan); // x - nan => nan
}
TEST(ReduceFloat64Sub) {
ReducerTester R;
R.binop = R.machine.Float64Sub();
FOR_FLOAT64_INPUTS(pl) {
FOR_FLOAT64_INPUTS(pr) {
double x = *pl, y = *pr;
R.CheckFoldBinop<double>(x - y, x, y);
}
}
Node* x = R.Parameter();
Node* zero = R.Constant<double>(0.0);
Node* nan = R.Constant<double>(std::numeric_limits<double>::quiet_NaN());
R.CheckBinop(x, x, zero); // x - 0 => x
R.CheckBinop(nan, nan, x); // nan - x => nan
R.CheckBinop(nan, x, nan); // x - nan => nan
}
// TODO(titzer): test MachineOperatorReducer for Word64And
// TODO(titzer): test MachineOperatorReducer for Word64Or
......
......@@ -1594,6 +1594,26 @@ TEST_F(MachineOperatorReducerTest, Float64MulWithMinusOne) {
}
}
TEST_F(MachineOperatorReducerTest, Float64SubMinusZeroMinusX) {
Node* const p0 = Parameter(0);
{
Reduction r = Reduce(
graph()->NewNode(machine()->Float64Sub(), Float64Constant(-0.0), p0));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsFloat64Neg(p0));
}
}
TEST_F(MachineOperatorReducerTest, Float32SubMinusZeroMinusX) {
Node* const p0 = Parameter(0);
{
Reduction r = Reduce(
graph()->NewNode(machine()->Float32Sub(), Float32Constant(-0.0), p0));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsFloat32Neg(p0));
}
}
// -----------------------------------------------------------------------------
// Float64Acos
......
......@@ -2295,7 +2295,9 @@ IS_UNOP_MATCHER(ChangeUint32ToUint64)
IS_UNOP_MATCHER(TruncateFloat64ToFloat32)
IS_UNOP_MATCHER(TruncateInt64ToInt32)
IS_UNOP_MATCHER(Float32Abs)
IS_UNOP_MATCHER(Float32Neg)
IS_UNOP_MATCHER(Float64Abs)
IS_UNOP_MATCHER(Float64Neg)
IS_UNOP_MATCHER(Float64Sqrt)
IS_UNOP_MATCHER(Float64RoundDown)
IS_UNOP_MATCHER(Float64RoundTruncate)
......
......@@ -394,6 +394,7 @@ Matcher<Node*> IsChangeUint32ToUint64(const Matcher<Node*>& input_matcher);
Matcher<Node*> IsTruncateFloat64ToFloat32(const Matcher<Node*>& input_matcher);
Matcher<Node*> IsTruncateInt64ToInt32(const Matcher<Node*>& input_matcher);
Matcher<Node*> IsFloat32Abs(const Matcher<Node*>& input_matcher);
Matcher<Node*> IsFloat32Neg(const Matcher<Node*>& input_matcher);
Matcher<Node*> IsFloat32Equal(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsFloat32LessThan(const Matcher<Node*>& lhs_matcher,
......@@ -407,6 +408,7 @@ Matcher<Node*> IsFloat64Min(const Matcher<Node*>& lhs_matcher,
Matcher<Node*> IsFloat64Sub(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsFloat64Abs(const Matcher<Node*>& input_matcher);
Matcher<Node*> IsFloat64Neg(const Matcher<Node*>& input_matcher);
Matcher<Node*> IsFloat64Sqrt(const Matcher<Node*>& input_matcher);
Matcher<Node*> IsFloat64RoundDown(const Matcher<Node*>& input_matcher);
Matcher<Node*> IsFloat64RoundTruncate(const Matcher<Node*>& input_matcher);
......
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