Bug 1079062 - IonMonkey: Don't fold ternary constructs, when a branch dominates both MPhi predecessors, r=nbp
authorHannes Verschore <hv1989@gmail.com>
Wed, 08 Oct 2014 10:06:10 +0200
changeset 209272 9da8f4e52207a8e9f96618cd0d4ec3535e165e13
parent 209271 4007aeccec79b33a9eae3506f26455ae3e01facc
child 209273 ac5d23ce1ce9f8abbd563c70f5485ebd04b60236
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersnbp
bugs1079062
milestone35.0a1
Bug 1079062 - IonMonkey: Don't fold ternary constructs, when a branch dominates both MPhi predecessors, r=nbp
js/src/jit-test/tests/ion/bug1079062.js
js/src/jit/MIR.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug1079062.js
@@ -0,0 +1,6 @@
+function f(y) {
+    return ((y ? y : 0) ? 0 : y)
+}
+m = [0xf]
+f(m[0])
+assertEq(f(m[0]), 0)
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -1217,18 +1217,40 @@ MPhi::foldsTernary()
         return nullptr;
 
     MOZ_ASSERT(block()->numPredecessors() == 2);
 
     MBasicBlock *pred = block()->immediateDominator();
     if (!pred || !pred->lastIns()->isTest())
         return nullptr;
 
+    MTest *test = pred->lastIns()->toTest();
+
+    // True branch may only dominate one edge of MPhi.
+    if (test->ifTrue()->dominates(block()->getPredecessor(0)) &&
+        test->ifTrue()->dominates(block()->getPredecessor(1)))
+    {
+        return nullptr;
+    }
+
+    // False branch may only dominate one edge of MPhi.
+    if (test->ifFalse()->dominates(block()->getPredecessor(0)) &&
+        test->ifFalse()->dominates(block()->getPredecessor(1)))
+    {
+        return nullptr;
+    }
+
+    // True and false branch must dominate different edges of MPhi.
+    if (test->ifTrue()->dominates(block()->getPredecessor(0)) ==
+        test->ifFalse()->dominates(block()->getPredecessor(0)))
+    {
+        return nullptr;
+    }
+
     // We found a ternary construct.
-    MTest *test = pred->lastIns()->toTest();
     bool firstIsTrueBranch = test->ifTrue()->dominates(block()->getPredecessor(0));
     MDefinition *trueDef = firstIsTrueBranch ? getOperand(0) : getOperand(1);
     MDefinition *falseDef = firstIsTrueBranch ? getOperand(1) : getOperand(0);
 
     // Accept either
     // testArg ? testArg : constant or
     // testArg ? constant : testArg
     if (!trueDef->isConstant() && !falseDef->isConstant())