[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}
This commit is contained in:
parent
74feddd5e1
commit
552601bb5f
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user