Commit 2d576e82 authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

[compiler] Add a SilenceNaN helper to encapsulate pattern

The helper encapsulates the `x - x` pattern to silence NaN `x`.

Bug: v8:7519
Change-Id: Ia633272d7b7cc350c7e4db07e271e0192c68019f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2637232
Auto-Submit: Jakob Gruber <jgruber@chromium.org>
Commit-Queue: Nico Hartmann <nicohartmann@chromium.org>
Reviewed-by: 's avatarNico Hartmann <nicohartmann@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72161}
parent 9f94442e
...@@ -145,6 +145,19 @@ class Word64Adapter { ...@@ -145,6 +145,19 @@ class Word64Adapter {
MachineOperatorReducer* r_; MachineOperatorReducer* r_;
}; };
namespace {
// TODO(jgruber): Consider replacing all uses of this function by
// std::numeric_limits<T>::quiet_NaN().
template <class T>
T SilenceNaN(T x) {
DCHECK(std::isnan(x));
// Do some calculation to make a signalling NaN quiet.
return x - x;
}
} // namespace
MachineOperatorReducer::MachineOperatorReducer(Editor* editor, MachineOperatorReducer::MachineOperatorReducer(Editor* editor,
MachineGraph* mcgraph, MachineGraph* mcgraph,
bool allow_signalling_nan) bool allow_signalling_nan)
...@@ -465,14 +478,10 @@ Reduction MachineOperatorReducer::Reduce(Node* node) { ...@@ -465,14 +478,10 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
return Replace(m.left().node()); // x - 0 => x return Replace(m.left().node()); // x - 0 => x
} }
if (m.right().IsNaN()) { // x - NaN => NaN if (m.right().IsNaN()) { // x - NaN => NaN
// Do some calculation to make a signalling NaN quiet. return ReplaceFloat32(SilenceNaN(m.right().ResolvedValue()));
return ReplaceFloat32(m.right().ResolvedValue() -
m.right().ResolvedValue());
} }
if (m.left().IsNaN()) { // NaN - x => NaN if (m.left().IsNaN()) { // NaN - x => NaN
// Do some calculation to make a signalling NaN quiet. return ReplaceFloat32(SilenceNaN(m.left().ResolvedValue()));
return ReplaceFloat32(m.left().ResolvedValue() -
m.left().ResolvedValue());
} }
if (m.IsFoldable()) { // L - R => (L - R) if (m.IsFoldable()) { // L - R => (L - R)
return ReplaceFloat32(m.left().ResolvedValue() - return ReplaceFloat32(m.left().ResolvedValue() -
...@@ -512,14 +521,10 @@ Reduction MachineOperatorReducer::Reduce(Node* node) { ...@@ -512,14 +521,10 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
return Replace(m.left().node()); // x - 0 => x return Replace(m.left().node()); // x - 0 => x
} }
if (m.right().IsNaN()) { // x - NaN => NaN if (m.right().IsNaN()) { // x - NaN => NaN
// Do some calculation to make a signalling NaN quiet. return ReplaceFloat64(SilenceNaN(m.right().ResolvedValue()));
return ReplaceFloat64(m.right().ResolvedValue() -
m.right().ResolvedValue());
} }
if (m.left().IsNaN()) { // NaN - x => NaN if (m.left().IsNaN()) { // NaN - x => NaN
// Do some calculation to make a signalling NaN quiet. return ReplaceFloat64(SilenceNaN(m.left().ResolvedValue()));
return ReplaceFloat64(m.left().ResolvedValue() -
m.left().ResolvedValue());
} }
if (m.IsFoldable()) { // L - R => (L - R) if (m.IsFoldable()) { // L - R => (L - R)
return ReplaceFloat64(m.left().ResolvedValue() - return ReplaceFloat64(m.left().ResolvedValue() -
...@@ -555,9 +560,7 @@ Reduction MachineOperatorReducer::Reduce(Node* node) { ...@@ -555,9 +560,7 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
return Changed(node); return Changed(node);
} }
if (m.right().IsNaN()) { // x * NaN => NaN if (m.right().IsNaN()) { // x * NaN => NaN
// Do some calculation to make a signalling NaN quiet. return ReplaceFloat64(SilenceNaN(m.right().ResolvedValue()));
return ReplaceFloat64(m.right().ResolvedValue() -
m.right().ResolvedValue());
} }
if (m.IsFoldable()) { // K * K => K (K stands for arbitrary constants) if (m.IsFoldable()) { // K * K => K (K stands for arbitrary constants)
return ReplaceFloat64(m.left().ResolvedValue() * return ReplaceFloat64(m.left().ResolvedValue() *
...@@ -576,14 +579,10 @@ Reduction MachineOperatorReducer::Reduce(Node* node) { ...@@ -576,14 +579,10 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
return Replace(m.left().node()); // x / 1.0 => x 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. // 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 if (m.right().IsNaN()) { // x / NaN => NaN
// Do some calculation to make a signalling NaN quiet. return ReplaceFloat64(SilenceNaN(m.right().ResolvedValue()));
return ReplaceFloat64(m.right().ResolvedValue() -
m.right().ResolvedValue());
} }
if (m.left().IsNaN()) { // NaN / x => NaN if (m.left().IsNaN()) { // NaN / x => NaN
// Do some calculation to make a signalling NaN quiet. return ReplaceFloat64(SilenceNaN(m.left().ResolvedValue()));
return ReplaceFloat64(m.left().ResolvedValue() -
m.left().ResolvedValue());
} }
if (m.IsFoldable()) { // K / K => K (K stands for arbitrary constants) if (m.IsFoldable()) { // K / K => K (K stands for arbitrary constants)
return ReplaceFloat64( return ReplaceFloat64(
...@@ -781,8 +780,7 @@ Reduction MachineOperatorReducer::Reduce(Node* node) { ...@@ -781,8 +780,7 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
Float32Matcher m(node->InputAt(0)); Float32Matcher m(node->InputAt(0));
if (m.HasResolvedValue()) { if (m.HasResolvedValue()) {
if (!allow_signalling_nan_ && std::isnan(m.ResolvedValue())) { if (!allow_signalling_nan_ && std::isnan(m.ResolvedValue())) {
// Do some calculation to make guarantee the value is a quiet NaN. return ReplaceFloat64(SilenceNaN(m.ResolvedValue()));
return ReplaceFloat64(m.ResolvedValue() + m.ResolvedValue());
} }
return ReplaceFloat64(m.ResolvedValue()); return ReplaceFloat64(m.ResolvedValue());
} }
...@@ -856,10 +854,8 @@ Reduction MachineOperatorReducer::Reduce(Node* node) { ...@@ -856,10 +854,8 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
case IrOpcode::kTruncateFloat64ToFloat32: { case IrOpcode::kTruncateFloat64ToFloat32: {
Float64Matcher m(node->InputAt(0)); Float64Matcher m(node->InputAt(0));
if (m.HasResolvedValue()) { if (m.HasResolvedValue()) {
if (!allow_signalling_nan_ && std::isnan(m.ResolvedValue())) { if (!allow_signalling_nan_ && m.IsNaN()) {
// Do some calculation to make guarantee the value is a quiet NaN. return ReplaceFloat32(DoubleToFloat32(SilenceNaN(m.ResolvedValue())));
return ReplaceFloat32(
DoubleToFloat32(m.ResolvedValue() + m.ResolvedValue()));
} }
return ReplaceFloat32(DoubleToFloat32(m.ResolvedValue())); return ReplaceFloat32(DoubleToFloat32(m.ResolvedValue()));
} }
......
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