diff options
Diffstat (limited to 'src/compiler/machine-operator-reducer.cc')
-rw-r--r-- | src/compiler/machine-operator-reducer.cc | 111 |
1 files changed, 74 insertions, 37 deletions
diff --git a/src/compiler/machine-operator-reducer.cc b/src/compiler/machine-operator-reducer.cc index 0ad20f06..a50f0dcb 100644 --- a/src/compiler/machine-operator-reducer.cc +++ b/src/compiler/machine-operator-reducer.cc @@ -12,14 +12,15 @@ #include "src/compiler/graph.h" #include "src/compiler/js-graph.h" #include "src/compiler/node-matchers.h" +#include "src/objects-inl.h" namespace v8 { namespace internal { namespace compiler { -MachineOperatorReducer::MachineOperatorReducer(JSGraph* jsgraph) - : jsgraph_(jsgraph) {} - +MachineOperatorReducer::MachineOperatorReducer(JSGraph* jsgraph, + bool allow_signalling_nan) + : jsgraph_(jsgraph), allow_signalling_nan_(allow_signalling_nan) {} MachineOperatorReducer::~MachineOperatorReducer() {} @@ -50,12 +51,12 @@ Node* MachineOperatorReducer::Float64Mul(Node* lhs, Node* rhs) { Node* MachineOperatorReducer::Float64PowHalf(Node* value) { value = graph()->NewNode(machine()->Float64Add(), Float64Constant(0.0), value); - return graph()->NewNode( - common()->Select(MachineRepresentation::kFloat64, BranchHint::kFalse), - graph()->NewNode(machine()->Float64LessThanOrEqual(), value, - Float64Constant(-V8_INFINITY)), - Float64Constant(V8_INFINITY), - graph()->NewNode(machine()->Float64Sqrt(), value)); + Diamond d(graph(), common(), + graph()->NewNode(machine()->Float64LessThanOrEqual(), value, + Float64Constant(-V8_INFINITY)), + BranchHint::kFalse); + return d.Phi(MachineRepresentation::kFloat64, Float64Constant(V8_INFINITY), + graph()->NewNode(machine()->Float64Sqrt(), value)); } Node* MachineOperatorReducer::Word32And(Node* lhs, Node* rhs) { @@ -316,19 +317,22 @@ Reduction MachineOperatorReducer::Reduce(Node* node) { } case IrOpcode::kFloat32Sub: { Float32BinopMatcher m(node); - if (m.right().Is(0) && (copysign(1.0, m.right().Value()) > 0)) { + if (allow_signalling_nan_ && 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()); + // Do some calculation to make a signalling NaN quiet. + return ReplaceFloat32(m.right().Value() - m.right().Value()); } if (m.left().IsNaN()) { // NaN - x => NaN - return Replace(m.left().node()); + // Do some calculation to make a signalling NaN quiet. + return ReplaceFloat32(m.left().Value() - m.left().Value()); } if (m.IsFoldable()) { // L - R => (L - R) return ReplaceFloat32(m.left().Value() - m.right().Value()); } - if (m.left().IsMinusZero()) { + if (allow_signalling_nan_ && m.left().IsMinusZero()) { // -0.0 - round_down(-0.0 - R) => round_up(R) if (machine()->Float32RoundUp().IsSupported() && m.right().IsFloat32RoundDown()) { @@ -350,7 +354,8 @@ Reduction MachineOperatorReducer::Reduce(Node* node) { case IrOpcode::kFloat64Add: { Float64BinopMatcher m(node); if (m.right().IsNaN()) { // x + NaN => NaN - return Replace(m.right().node()); + // Do some calculation to make a signalling NaN quiet. + return ReplaceFloat64(m.right().Value() - m.right().Value()); } if (m.IsFoldable()) { // K + K => K return ReplaceFloat64(m.left().Value() + m.right().Value()); @@ -359,19 +364,22 @@ Reduction MachineOperatorReducer::Reduce(Node* node) { } case IrOpcode::kFloat64Sub: { Float64BinopMatcher m(node); - if (m.right().Is(0) && (Double(m.right().Value()).Sign() > 0)) { + if (allow_signalling_nan_ && m.right().Is(0) && + (Double(m.right().Value()).Sign() > 0)) { return Replace(m.left().node()); // x - 0 => x } if (m.right().IsNaN()) { // x - NaN => NaN - return Replace(m.right().node()); + // Do some calculation to make a signalling NaN quiet. + return ReplaceFloat64(m.right().Value() - m.right().Value()); } if (m.left().IsNaN()) { // NaN - x => NaN - return Replace(m.left().node()); + // Do some calculation to make a signalling NaN quiet. + return ReplaceFloat64(m.left().Value() - m.left().Value()); } if (m.IsFoldable()) { // L - R => (L - R) return ReplaceFloat64(m.left().Value() - m.right().Value()); } - if (m.left().IsMinusZero()) { + if (allow_signalling_nan_ && m.left().IsMinusZero()) { // -0.0 - round_down(-0.0 - R) => round_up(R) if (machine()->Float64RoundUp().IsSupported() && m.right().IsFloat64RoundDown()) { @@ -392,15 +400,17 @@ Reduction MachineOperatorReducer::Reduce(Node* node) { } case IrOpcode::kFloat64Mul: { Float64BinopMatcher m(node); + if (allow_signalling_nan_ && m.right().Is(1)) + return Replace(m.left().node()); // x * 1.0 => x if (m.right().Is(-1)) { // x * -1.0 => -0.0 - x node->ReplaceInput(0, Float64Constant(-0.0)); node->ReplaceInput(1, m.left().node()); NodeProperties::ChangeOp(node, machine()->Float64Sub()); return Changed(node); } - if (m.right().Is(1)) return Replace(m.left().node()); // x * 1.0 => x if (m.right().IsNaN()) { // x * NaN => NaN - return Replace(m.right().node()); + // Do some calculation to make a signalling NaN quiet. + return ReplaceFloat64(m.right().Value() - m.right().Value()); } if (m.IsFoldable()) { // K * K => K return ReplaceFloat64(m.left().Value() * m.right().Value()); @@ -414,17 +424,21 @@ Reduction MachineOperatorReducer::Reduce(Node* node) { } case IrOpcode::kFloat64Div: { Float64BinopMatcher m(node); - if (m.right().Is(1)) return Replace(m.left().node()); // x / 1.0 => x + if (allow_signalling_nan_ && m.right().Is(1)) + return Replace(m.left().node()); // x / 1.0 => x + // TODO(ahaas): We could do x / 1.0 = x if we knew that x is not an sNaN. if (m.right().IsNaN()) { // x / NaN => NaN - return Replace(m.right().node()); + // Do some calculation to make a signalling NaN quiet. + return ReplaceFloat64(m.right().Value() - m.right().Value()); } if (m.left().IsNaN()) { // NaN / x => NaN - return Replace(m.left().node()); + // Do some calculation to make a signalling NaN quiet. + return ReplaceFloat64(m.left().Value() - m.left().Value()); } if (m.IsFoldable()) { // K / K => K return ReplaceFloat64(m.left().Value() / m.right().Value()); } - if (m.right().Is(-1)) { // x / -1.0 => -x + if (allow_signalling_nan_ && m.right().Is(-1)) { // x / -1.0 => -x node->RemoveInput(1); NodeProperties::ChangeOp(node, machine()->Float64Neg()); return Changed(node); @@ -593,7 +607,13 @@ Reduction MachineOperatorReducer::Reduce(Node* node) { } case IrOpcode::kChangeFloat32ToFloat64: { Float32Matcher m(node->InputAt(0)); - if (m.HasValue()) return ReplaceFloat64(m.Value()); + if (m.HasValue()) { + if (!allow_signalling_nan_ && std::isnan(m.Value())) { + // Do some calculation to make guarantee the value is a quiet NaN. + return ReplaceFloat64(m.Value() + m.Value()); + } + return ReplaceFloat64(m.Value()); + } break; } case IrOpcode::kChangeFloat64ToInt32: { @@ -642,8 +662,15 @@ Reduction MachineOperatorReducer::Reduce(Node* node) { } case IrOpcode::kTruncateFloat64ToFloat32: { Float64Matcher m(node->InputAt(0)); - if (m.HasValue()) return ReplaceFloat32(DoubleToFloat32(m.Value())); - if (m.IsChangeFloat32ToFloat64()) return Replace(m.node()->InputAt(0)); + if (m.HasValue()) { + if (!allow_signalling_nan_ && std::isnan(m.Value())) { + // Do some calculation to make guarantee the value is a quiet NaN. + return ReplaceFloat32(DoubleToFloat32(m.Value() + m.Value())); + } + return ReplaceFloat32(DoubleToFloat32(m.Value())); + } + if (allow_signalling_nan_ && m.IsChangeFloat32ToFloat64()) + return Replace(m.node()->InputAt(0)); break; } case IrOpcode::kRoundFloat64ToInt32: { @@ -664,6 +691,8 @@ Reduction MachineOperatorReducer::Reduce(Node* node) { case IrOpcode::kFloat64LessThan: case IrOpcode::kFloat64LessThanOrEqual: return ReduceFloat64Compare(node); + case IrOpcode::kFloat64RoundDown: + return ReduceFloat64RoundDown(node); default: break; } @@ -841,14 +870,13 @@ Reduction MachineOperatorReducer::ReduceInt32Mod(Node* node) { if (base::bits::IsPowerOfTwo32(divisor)) { uint32_t const mask = divisor - 1; Node* const zero = Int32Constant(0); - node->ReplaceInput( - 0, graph()->NewNode(machine()->Int32LessThan(), dividend, zero)); - node->ReplaceInput( - 1, Int32Sub(zero, Word32And(Int32Sub(zero, dividend), mask))); - node->ReplaceInput(2, Word32And(dividend, mask)); - NodeProperties::ChangeOp( - node, - common()->Select(MachineRepresentation::kWord32, BranchHint::kFalse)); + Diamond d(graph(), common(), + graph()->NewNode(machine()->Int32LessThan(), dividend, zero), + BranchHint::kFalse); + return Replace( + d.Phi(MachineRepresentation::kWord32, + Int32Sub(zero, Word32And(Int32Sub(zero, dividend), mask)), + Word32And(dividend, mask))); } else { Node* quotient = Int32Div(dividend, divisor); DCHECK_EQ(dividend, node->InputAt(0)); @@ -1153,8 +1181,9 @@ Reduction MachineOperatorReducer::ReduceWord32And(Node* node) { if (m.left().IsWord32Shl()) { Uint32BinopMatcher mleft(m.left().node()); if (mleft.right().HasValue() && - mleft.right().Value() >= base::bits::CountTrailingZeros32(mask)) { - // (x << L) & (-1 << K) => x << L iff K >= L + (mleft.right().Value() & 0x1f) >= + base::bits::CountTrailingZeros32(mask)) { + // (x << L) & (-1 << K) => x << L iff L >= K return Replace(mleft.node()); } } else if (m.left().IsInt32Add()) { @@ -1392,6 +1421,14 @@ Reduction MachineOperatorReducer::ReduceFloat64Compare(Node* node) { return NoChange(); } +Reduction MachineOperatorReducer::ReduceFloat64RoundDown(Node* node) { + DCHECK_EQ(IrOpcode::kFloat64RoundDown, node->opcode()); + Float64Matcher m(node->InputAt(0)); + if (m.HasValue()) { + return ReplaceFloat64(Floor(m.Value())); + } + return NoChange(); +} CommonOperatorBuilder* MachineOperatorReducer::common() const { return jsgraph()->common(); |