Bug 945860 - IonMonkey: Fold an unsigned self-mod to zero when there is no divide-by-zero. r=bhackett
authorDan Gohman <sunfish@google.com>
Thu, 05 Dec 2013 08:25:53 -0800
changeset 174622 d648a922f82b0e70e74dfaaca3e068c30c88def2
parent 174621 d6a365b059e329b2791f5640a39ece43c478823d
child 174623 e805a81f0a1c88dbc61082a155d91b90d277c9d5
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett
bugs945860
milestone28.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 945860 - IonMonkey: Fold an unsigned self-mod to zero when there is no divide-by-zero. r=bhackett
js/src/jit-test/tests/ion/divmodself.js
js/src/jit/shared/Lowering-x86-shared.cpp
--- a/js/src/jit-test/tests/ion/divmodself.js
+++ b/js/src/jit-test/tests/ion/divmodself.js
@@ -44,16 +44,28 @@ function bug_g() {
 }
 function bug_h(x) {
     Math.max(x ? ((x / x) | 0) : 0);
 }
 for (var a = 0; a < 2; ++a) {
   bug939893();
 }
 
+// bug 945860
+function bug945860(x) {
+    return (x % x);
+}
+for (var i = 0; i < 2; i++) {
+    try {
+        (function() {
+            assertEq(bug945860(1), 0);
+        })()
+    } catch (e) {}
+}
+
 // Assorted tests.
 
 function sdiv_truncate(y) {
   return (y / y)|0;
 }
 assertEq(sdiv_truncate(5), 1);
 assertEq(sdiv_truncate(1), 1);
 assertEq(sdiv_truncate(-1), 1);
--- a/js/src/jit/shared/Lowering-x86-shared.cpp
+++ b/js/src/jit/shared/Lowering-x86-shared.cpp
@@ -253,17 +253,17 @@ LIRGeneratorX86Shared::lowerUDiv(MDiv *d
     return defineFixed(lir, div, LAllocation(AnyRegister(eax)));
 }
 
 bool
 LIRGeneratorX86Shared::lowerUMod(MMod *mod)
 {
     // Optimize x%x. The comments in lowerModI apply here as well.
     if (mod->lhs() == mod->rhs()) {
-        if (mod->isTruncated())
+        if (mod->isTruncated() || (mod->isUnsigned() && !mod->canBeDivideByZero()))
             return define(new LInteger(0), mod);
 
         LModSelfI *lir = new LModSelfI(useRegisterAtStart(mod->lhs()));
         if (mod->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
             return false;
         return define(lir, mod);
     }