Bug 1122401: Check that the remainder is null in unsigned soft divisions on ARM or bailout; r=dougc
authorBenjamin Bouvier <benj@benj.me>
Fri, 06 Feb 2015 18:31:29 +0100
changeset 256468 5d0cfe96d1fee6acacf5d0146700b30dd1778622
parent 256467 b0867af35eb0f43d6915d9cf3f3403d73546030f
child 256469 fbc610bf6dfd568775e52cba6ea7c4819e2d6665
push id4610
push userjlund@mozilla.com
push dateMon, 30 Mar 2015 18:32:55 +0000
treeherdermozilla-beta@4df54044d9ef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdougc
bugs1122401
milestone38.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 1122401: Check that the remainder is null in unsigned soft divisions on ARM or bailout; r=dougc
js/src/jit-test/tests/ion/bug1122401.js
js/src/jit/arm/CodeGenerator-arm.cpp
js/src/jit/arm/LIR-arm.h
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug1122401.js
@@ -0,0 +1,5 @@
+function f(x) {
+    return Math.round((x >>> 0) / 2) >> 0;
+}
+f(2);
+assertEq(f(1), 1);
--- a/js/src/jit/arm/CodeGenerator-arm.cpp
+++ b/js/src/jit/arm/CodeGenerator-arm.cpp
@@ -619,16 +619,17 @@ CodeGeneratorARM::visitSoftDivI(LSoftDiv
 
     masm.setupAlignedABICall(2);
     masm.passABIArg(lhs);
     masm.passABIArg(rhs);
     if (gen->compilingAsmJS())
         masm.callWithABI(AsmJSImm_aeabi_idivmod);
     else
         masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, __aeabi_idivmod));
+
     // idivmod returns the quotient in r0, and the remainder in r1.
     if (!mir->canTruncateRemainder()) {
         MOZ_ASSERT(mir->fallible());
         masm.ma_cmp(r1, Imm32(0));
         bailoutIf(Assembler::NonZero, ins->snapshot());
     }
 
     masm.bind(&done);
@@ -2100,16 +2101,24 @@ CodeGeneratorARM::visitSoftUDivOrMod(LSo
     masm.setupAlignedABICall(2);
     masm.passABIArg(lhs);
     masm.passABIArg(rhs);
     if (gen->compilingAsmJS())
         masm.callWithABI(AsmJSImm_aeabi_uidivmod);
     else
         masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, __aeabi_uidivmod));
 
+    // uidivmod returns the quotient in r0, and the remainder in r1.
+    MInstruction *mir = ins->mir();
+    if (mir->isDiv() && !mir->toDiv()->canTruncateRemainder()) {
+        MOZ_ASSERT(mir->toDiv()->fallible());
+        masm.ma_cmp(r1, Imm32(0));
+        bailoutIf(Assembler::NonZero, ins->snapshot());
+    }
+
     masm.bind(&afterDiv);
 }
 
 void
 CodeGeneratorARM::visitEffectiveAddress(LEffectiveAddress *ins)
 {
     const MEffectiveAddress *mir = ins->mir();
     Register base = ToRegister(ins->base());
--- a/js/src/jit/arm/LIR-arm.h
+++ b/js/src/jit/arm/LIR-arm.h
@@ -435,16 +435,20 @@ class LSoftUDivOrMod : public LBinaryMat
     LSoftUDivOrMod(const LAllocation &lhs, const LAllocation &rhs, const LDefinition &temp1,
                    const LDefinition &temp2, const LDefinition &temp3) {
         setOperand(0, lhs);
         setOperand(1, rhs);
         setTemp(0, temp1);
         setTemp(1, temp2);
         setTemp(2, temp3);
     }
+
+    MInstruction *mir() {
+        return mir_->toInstruction();
+    }
 };
 
 class LAsmJSLoadFuncPtr : public LInstructionHelper<1, 1, 1>
 {
   public:
     LIR_HEADER(AsmJSLoadFuncPtr);
     LAsmJSLoadFuncPtr(const LAllocation &index, const LDefinition &temp) {
         setOperand(0, index);