aboutsummaryrefslogtreecommitdiff
path: root/src/compiler/machine-operator-reducer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/machine-operator-reducer.cc')
-rw-r--r--src/compiler/machine-operator-reducer.cc111
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();