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 232487 9da8f4e52207a8e9f96618cd0d4ec3535e165e13
parent 232486 4007aeccec79b33a9eae3506f26455ae3e01facc
child 232488 ac5d23ce1ce9f8abbd563c70f5485ebd04b60236
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1079062
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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())