summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/machine-operator-reducer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/machine-operator-reducer.cc')
-rw-r--r--deps/v8/src/compiler/machine-operator-reducer.cc80
1 files changed, 51 insertions, 29 deletions
diff --git a/deps/v8/src/compiler/machine-operator-reducer.cc b/deps/v8/src/compiler/machine-operator-reducer.cc
index 0ad20f0684..f7fe19d494 100644
--- a/deps/v8/src/compiler/machine-operator-reducer.cc
+++ b/deps/v8/src/compiler/machine-operator-reducer.cc
@@ -17,9 +17,9 @@ 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 +50,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,14 +316,17 @@ 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());
@@ -350,7 +353,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,14 +363,17 @@ 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());
@@ -392,15 +399,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,12 +423,16 @@ 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());
@@ -664,6 +677,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 +856,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));
@@ -1392,6 +1406,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();