It is incorrect to short-circuit Branch(LogicalNot(@a)) if boolean speculations on @a may fail
https://bugs.webkit.org/show_bug.cgi?id=83744
<rdar://problem/11206946>

Source/JavaScriptCore: 

Reviewed by Andy Estes.
        
This does the conservative thing: it only short-circuits Branch(LogicalNot(@a)) if @a is a node
that is statically known to return boolean results.

* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):

LayoutTests: 

Rubber stamped by Andy Estes.

* fast/js/dfg-branch-not-fail-expected.txt: Added.
* fast/js/dfg-branch-not-fail.html: Added.
* fast/js/script-tests/dfg-branch-not-fail.js: Added.
(foo):
(bar):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@113941 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
index 3e4c1d9..c0ab117 100644
--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
@@ -197,14 +197,16 @@
             if (logicalNot.op() == LogicalNot
                 && logicalNot.adjustedRefCount() == 1) {
                 Edge newChildEdge = logicalNot.child1();
-                m_graph.ref(newChildEdge);
-                m_graph.deref(logicalNotEdge);
-                myNode.children.setChild1(newChildEdge);
-                
-                BlockIndex toBeTaken = myNode.notTakenBlockIndex();
-                BlockIndex toBeNotTaken = myNode.takenBlockIndex();
-                myNode.setTakenBlockIndex(toBeTaken);
-                myNode.setNotTakenBlockIndex(toBeNotTaken);
+                if (m_graph[newChildEdge].hasBooleanResult()) {
+                    m_graph.ref(newChildEdge);
+                    m_graph.deref(logicalNotEdge);
+                    myNode.children.setChild1(newChildEdge);
+                    
+                    BlockIndex toBeTaken = myNode.notTakenBlockIndex();
+                    BlockIndex toBeNotTaken = myNode.takenBlockIndex();
+                    myNode.setTakenBlockIndex(toBeTaken);
+                    myNode.setNotTakenBlockIndex(toBeNotTaken);
+                }
             }
             break;
         }