Sink NaN sanitization to uses and remove it when it's unnecessary
https://bugs.webkit.org/show_bug.cgi?id=131419

Reviewed by Oliver Hunt.
        
This moves NaN purification to stores that could see an impure NaN.
        
5% speed-up on AsmBench, 50% speed-up on AsmBench/n-body. It is a regression on FloatMM
though, because of the other bug that causes that benchmark to box doubles in a loop.

* bytecode/SpeculatedType.h:
(JSC::isInt32SpeculationForArithmetic):
(JSC::isMachineIntSpeculationForArithmetic):
(JSC::isDoubleSpeculation):
(JSC::isDoubleSpeculationForArithmetic):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGAbstractValue.cpp:
(JSC::DFG::AbstractValue::fixTypeForRepresentation):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
* dfg/DFGInPlaceAbstractState.cpp:
(JSC::DFG::InPlaceAbstractState::mergeStateAtTail):
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileValueRep):
(JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
* dfg/DFGUseKind.h:
(JSC::DFG::typeFilterFor):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileValueRep):
(JSC::FTL::LowerDFGToLLVM::compileGetByVal):
* runtime/PureNaN.h:
* tests/stress/float32-array-nan-inlined.js: Added.
(foo):
(test):
* tests/stress/float32-array-nan.js: Added.
(foo):
(test):
* tests/stress/float64-array-nan-inlined.js: Added.
(foo):
(isBigEndian):
(test):
* tests/stress/float64-array-nan.js: Added.
(foo):
(isBigEndian):
(test):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@167416 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
index 7ef5e47..6139c96 100644
--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
@@ -268,7 +268,7 @@
                 // We don't need to do ref'ing on the children because we're stealing them from
                 // the original division.
                 Node* newDivision = m_insertionSet.insertNode(
-                    m_indexInBlock, SpecDouble, *node);
+                    m_indexInBlock, SpecBytecodeDouble, *node);
                 newDivision->setResult(NodeResultDouble);
                 
                 node->setOp(DoubleAsInt32);
@@ -1881,7 +1881,7 @@
                     Edge(edge.node(), Int52RepUse));
             } else {
                 result = m_insertionSet.insertNode(
-                    m_indexInBlock, SpecDouble, DoubleRep, node->origin,
+                    m_indexInBlock, SpecBytecodeDouble, DoubleRep, node->origin,
                     Edge(edge.node(), NumberUse));
             }
 
@@ -1924,7 +1924,7 @@
             Node* result;
             if (edge->hasDoubleResult()) {
                 result = m_insertionSet.insertNode(
-                    m_indexInBlock, SpecDouble, ValueRep, node->origin,
+                    m_indexInBlock, SpecBytecodeDouble, ValueRep, node->origin,
                     Edge(edge.node(), DoubleRepUse));
             } else {
                 result = m_insertionSet.insertNode(