Backed out changesets 0db12290df12, 80950d72bd71, and 586ed41fa2d1 (bug 1010747) for landing without approval.
authorRyan VanderMeulen <ryanvm@gmail.com>
Thu, 22 May 2014 09:39:08 -0400
changeset 192367 a89aa1e3e367
parent 192366 0db12290df12
child 192368 d3f2e54cf39c
push id3585
push userryanvm@gmail.com
push date2014-05-22 13:39 +0000
Treeherderresults
bugs1010747
milestone30.0
backs out0db12290df12, 80950d72bd71, 586ed41fa2d1
Backed out changesets 0db12290df12, 80950d72bd71, and 586ed41fa2d1 (bug 1010747) for landing without approval.
js/src/jit-test/tests/ion/ceil.js
js/src/jit/LIR-Common.h
js/src/jit/LOpcodes.h
js/src/jit/Lowering.cpp
js/src/jit/Lowering.h
js/src/jit/MCallOptimize.cpp
js/src/jit/MIR.cpp
js/src/jit/MIR.h
js/src/jit/MOpcodes.h
js/src/jit/ParallelSafetyAnalysis.cpp
js/src/jit/arm/CodeGenerator-arm.cpp
js/src/jit/arm/CodeGenerator-arm.h
js/src/jit/arm/MacroAssembler-arm.cpp
js/src/jit/arm/MacroAssembler-arm.h
js/src/jit/shared/CodeGenerator-x86-shared.cpp
js/src/jit/shared/CodeGenerator-x86-shared.h
deleted file mode 100644
--- a/js/src/jit-test/tests/ion/ceil.js
+++ /dev/null
@@ -1,59 +0,0 @@
-setJitCompilerOption("baseline.usecount.trigger", 10);
-setJitCompilerOption("ion.usecount.trigger", 20);
-
-//var log = print;
-var log = function(x){}
-
-function ceil(x) {
-    // A nice but not always efficient polyfill.
-    return -Math.floor(-x);
-}
-
-function doubleCheck(g) {
-    for (var j = 0; j < 200; j++) {
-        var i = j;
-        assertEq(g(i), i);
-        assertEq(g(i+.5), i+1);
-        assertEq(g(-i), -i);
-        assertEq(g(-i-.5), -i);
-    }
-}
-
-function floatCheck(g, val) {
-    for (var j = 0; j < 200; j++) {
-        var i = Math.fround(j);
-        assertEq(g(i), i);
-        assertEq(g(i+.5), i+1);
-        assertEq(g(-i), -i);
-        assertEq(g(-i-.5), -i);
-    }
-}
-
-function testBailout(value) {
-    var dceil = eval('(function(x) { return Math.ceil(x) })');
-    log('start double');
-    doubleCheck(dceil);
-    log('bailout');
-    // At this point, the compiled code should bailout, if 'value' is in the
-    // edge case set.
-    assertEq(dceil(value), ceil(value));
-
-    var fceil = eval('(function(x) { return Math.ceil(Math.fround(x)) })');
-    log('start float');
-    floatCheck(fceil, value);
-    log('bailout');
-    assertEq(fceil(Math.fround(value)), ceil(Math.fround(value)));
-}
-
-var INT_MAX = Math.pow(2, 31) - 1;
-var INT_MIN = INT_MAX + 1 | 0;
-
-// Values in ]-1; -0]
-testBailout(-0);
-testBailout(-.5);
-// Values outside the INT32 range, when represented in either double or
-// single precision
-testBailout(INT_MAX + .5);
-testBailout(INT_MIN - 129);
-// BatNaN
-testBailout(NaN);
--- a/js/src/jit/LIR-Common.h
+++ b/js/src/jit/LIR-Common.h
@@ -4771,38 +4771,16 @@ class LFloorF : public LInstructionHelpe
   public:
     LIR_HEADER(FloorF)
 
     LFloorF(const LAllocation &num) {
         setOperand(0, num);
     }
 };
 
-// Take the ceiling of a double precision number. Implements Math.ceil().
-class LCeil : public LInstructionHelper<1, 1, 0>
-{
-  public:
-    LIR_HEADER(Ceil)
-
-    LCeil(const LAllocation &num) {
-        setOperand(0, num);
-    }
-};
-
-// Take the ceiling of a single precision number. Implements Math.ceil().
-class LCeilF : public LInstructionHelper<1, 1, 0>
-{
-  public:
-    LIR_HEADER(CeilF)
-
-    LCeilF(const LAllocation &num) {
-        setOperand(0, num);
-    }
-};
-
 // Round a double precision number. Implements Math.round().
 class LRound : public LInstructionHelper<1, 1, 1>
 {
   public:
     LIR_HEADER(Round)
 
     LRound(const LAllocation &num, const LDefinition &temp) {
         setOperand(0, num);
--- a/js/src/jit/LOpcodes.h
+++ b/js/src/jit/LOpcodes.h
@@ -225,17 +225,17 @@
     _(GetNameCache)                 \
     _(CallGetIntrinsicValue)        \
     _(CallsiteCloneCache)           \
     _(CallGetElement)               \
     _(CallSetElement)               \
     _(CallInitElementArray)         \
     _(CallSetProperty)              \
     _(CallDeleteProperty)           \
-    _(CallDeleteElement)            \
+    _(CallDeleteElement)           \
     _(SetPropertyCacheV)            \
     _(SetPropertyCacheT)            \
     _(SetElementCacheV)             \
     _(SetElementCacheT)             \
     _(SetPropertyPolymorphicV)      \
     _(SetPropertyPolymorphicT)      \
     _(CallIteratorStart)            \
     _(IteratorStart)                \
@@ -255,35 +255,33 @@
     _(SetFrameArgumentV)            \
     _(RunOncePrologue)              \
     _(Rest)                         \
     _(RestPar)                      \
     _(TypeOfV)                      \
     _(ToIdV)                        \
     _(Floor)                        \
     _(FloorF)                       \
-    _(Ceil)                         \
-    _(CeilF)                        \
     _(Round)                        \
     _(RoundF)                       \
     _(In)                           \
     _(InArray)                      \
     _(InstanceOfO)                  \
     _(InstanceOfV)                  \
     _(CallInstanceOf)               \
     _(InterruptCheck)               \
     _(InterruptCheckImplicit)       \
     _(FunctionBoundary)             \
     _(GetDOMProperty)               \
     _(GetDOMMember)                 \
     _(SetDOMProperty)               \
     _(CallDOMNative)                \
     _(IsCallable)                   \
     _(HaveSameClass)                \
-    _(HasClass)                     \
+    _(HasClass)                      \
     _(AsmJSLoadHeap)                \
     _(AsmJSStoreHeap)               \
     _(AsmJSLoadGlobalVar)           \
     _(AsmJSStoreGlobalVar)          \
     _(AsmJSLoadFFIFunc)             \
     _(AsmJSParameter)               \
     _(AsmJSReturn)                  \
     _(AsmJSVoidReturn)              \
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -1172,35 +1172,16 @@ LIRGenerator::visitFloor(MFloor *ins)
 
     LFloorF *lir = new(alloc()) LFloorF(useRegister(ins->num()));
     if (!assignSnapshot(lir))
         return false;
     return define(lir, ins);
 }
 
 bool
-LIRGenerator::visitCeil(MCeil *ins)
-{
-    MIRType type = ins->num()->type();
-    JS_ASSERT(IsFloatingPointType(type));
-
-    if (type == MIRType_Double) {
-        LCeil *lir = new(alloc()) LCeil(useRegister(ins->num()));
-        if (!assignSnapshot(lir))
-            return false;
-        return define(lir, ins);
-    }
-
-    LCeilF *lir = new(alloc()) LCeilF(useRegister(ins->num()));
-    if (!assignSnapshot(lir))
-        return false;
-    return define(lir, ins);
-}
-
-bool
 LIRGenerator::visitRound(MRound *ins)
 {
     MIRType type = ins->num()->type();
     JS_ASSERT(IsFloatingPointType(type));
 
     if (type == MIRType_Double) {
         LRound *lir = new (alloc()) LRound(useRegister(ins->num()), tempDouble());
         if (!assignSnapshot(lir))
--- a/js/src/jit/Lowering.h
+++ b/js/src/jit/Lowering.h
@@ -110,17 +110,16 @@ class LIRGenerator : public LIRGenerator
     bool visitBitNot(MBitNot *ins);
     bool visitBitAnd(MBitAnd *ins);
     bool visitBitOr(MBitOr *ins);
     bool visitBitXor(MBitXor *ins);
     bool visitLsh(MLsh *ins);
     bool visitRsh(MRsh *ins);
     bool visitUrsh(MUrsh *ins);
     bool visitFloor(MFloor *ins);
-    bool visitCeil(MCeil *ins);
     bool visitRound(MRound *ins);
     bool visitMinMax(MMinMax *ins);
     bool visitAbs(MAbs *ins);
     bool visitSqrt(MSqrt *ins);
     bool visitAtan2(MAtan2 *ins);
     bool visitHypot(MHypot *ins);
     bool visitPow(MPow *ins);
     bool visitRandom(MRandom *ins);
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -650,24 +650,16 @@ IonBuilder::inlineMathCeil(CallInfo &cal
         MFloor *floor = MFloor::New(alloc(), mul);
         current->add(floor);
         MMul *result = MMul::New(alloc(), floor, minusOne, MIRType_Int32);
         current->add(result);
         current->push(result);
         return InliningStatus_Inlined;
     }
 
-    if (IsFloatingPointType(argType) && returnType == MIRType_Int32) {
-        callInfo.setImplicitlyUsedUnchecked();
-        MCeil *ins = MCeil::New(alloc(), callInfo.getArg(0));
-        current->add(ins);
-        current->push(ins);
-        return InliningStatus_Inlined;
-    }
-
     if (IsFloatingPointType(argType) && returnType == MIRType_Double) {
         callInfo.setImplicitlyUsedUnchecked();
         MMathFunction *ins = MMathFunction::New(alloc(), callInfo.getArg(0), MMathFunction::Ceil, nullptr);
         current->add(ins);
         current->push(ins);
         return InliningStatus_Inlined;
     }
 
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -821,50 +821,46 @@ MStringLength::foldsTo(TempAllocator &al
         Value value = string()->toConstant()->value();
         JSAtom *atom = &value.toString()->asAtom();
         return MConstant::New(alloc, Int32Value(atom->length()));
     }
 
     return this;
 }
 
-static bool
-EnsureFloatInputOrConvert(MUnaryInstruction *owner, TempAllocator &alloc)
-{
-    MDefinition *input = owner->input();
-    if (!input->canProduceFloat32()) {
-        if (input->type() == MIRType_Float32)
-            ConvertDefinitionToDouble<0>(alloc, input, owner);
-        return false;
-    }
-    return true;
-}
-
 void
 MFloor::trySpecializeFloat32(TempAllocator &alloc)
 {
-    JS_ASSERT(type() == MIRType_Int32);
-    if (EnsureFloatInputOrConvert(this, alloc))
-        setPolicyType(MIRType_Float32);
-}
-
-void
-MCeil::trySpecializeFloat32(TempAllocator &alloc)
-{
-    JS_ASSERT(type() == MIRType_Int32);
-    if (EnsureFloatInputOrConvert(this, alloc))
-        setPolicyType(MIRType_Float32);
+    // No need to look at the output, as it's an integer (see IonBuilder::inlineMathFloor)
+    if (!input()->canProduceFloat32()) {
+        if (input()->type() == MIRType_Float32)
+            ConvertDefinitionToDouble<0>(alloc, input(), this);
+        return;
+    }
+
+    if (type() == MIRType_Double)
+        setResultType(MIRType_Float32);
+
+    setPolicyType(MIRType_Float32);
 }
 
 void
 MRound::trySpecializeFloat32(TempAllocator &alloc)
 {
+    // No need to look at the output, as it's an integer (unique way to have
+    // this instruction in IonBuilder::inlineMathRound)
     JS_ASSERT(type() == MIRType_Int32);
-    if (EnsureFloatInputOrConvert(this, alloc))
-        setPolicyType(MIRType_Float32);
+
+    if (!input()->canProduceFloat32()) {
+        if (input()->type() == MIRType_Float32)
+            ConvertDefinitionToDouble<0>(alloc, input(), this);
+        return;
+    }
+
+    setPolicyType(MIRType_Float32);
 }
 
 MCompare *
 MCompare::New(TempAllocator &alloc, MDefinition *left, MDefinition *right, JSOp op)
 {
     return new(alloc) MCompare(left, right, op);
 }
 
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -8330,59 +8330,16 @@ class MFloor
     void trySpecializeFloat32(TempAllocator &alloc);
 #ifdef DEBUG
     bool isConsistentFloat32Use(MUse *use) const {
         return true;
     }
 #endif
 };
 
-// Inlined version of Math.ceil().
-class MCeil
-  : public MUnaryInstruction,
-    public FloatingPointPolicy<0>
-{
-    MCeil(MDefinition *num)
-      : MUnaryInstruction(num)
-    {
-        setResultType(MIRType_Int32);
-        setPolicyType(MIRType_Double);
-        setMovable();
-    }
-
-  public:
-    INSTRUCTION_HEADER(Ceil)
-
-    static MCeil *New(TempAllocator &alloc, MDefinition *num) {
-        return new(alloc) MCeil(num);
-    }
-
-    MDefinition *num() const {
-        return getOperand(0);
-    }
-    AliasSet getAliasSet() const {
-        return AliasSet::None();
-    }
-    TypePolicy *typePolicy() {
-        return this;
-    }
-    bool isFloat32Commutative() const {
-        return true;
-    }
-    void trySpecializeFloat32(TempAllocator &alloc);
-#ifdef DEBUG
-    bool isConsistentFloat32Use(MUse *use) const {
-        return true;
-    }
-#endif
-    bool congruentTo(const MDefinition *ins) const {
-        return congruentIfOperandsEqual(ins);
-    }
-};
-
 // Inlined version of Math.round().
 class MRound
   : public MUnaryInstruction,
     public FloatingPointPolicy<0>
 {
     MRound(MDefinition *num)
       : MUnaryInstruction(num)
     {
--- a/js/src/jit/MOpcodes.h
+++ b/js/src/jit/MOpcodes.h
@@ -174,29 +174,28 @@ namespace jit {
     _(IteratorEnd)                                                          \
     _(StringLength)                                                         \
     _(ArgumentsLength)                                                      \
     _(GetFrameArgument)                                                     \
     _(SetFrameArgument)                                                     \
     _(RunOncePrologue)                                                      \
     _(Rest)                                                                 \
     _(Floor)                                                                \
-    _(Ceil)                                                                 \
     _(Round)                                                                \
     _(In)                                                                   \
     _(InstanceOf)                                                           \
     _(CallInstanceOf)                                                       \
     _(InterruptCheck)                                                       \
     _(FunctionBoundary)                                                     \
     _(GetDOMProperty)                                                       \
     _(GetDOMMember)                                                         \
     _(SetDOMProperty)                                                       \
     _(IsCallable)                                                           \
     _(HaveSameClass)                                                        \
-    _(HasClass)                                                             \
+    _(HasClass)                                                              \
     _(AsmJSNeg)                                                             \
     _(AsmJSUnsignedToDouble)                                                \
     _(AsmJSUnsignedToFloat32)                                               \
     _(AsmJSLoadHeap)                                                        \
     _(AsmJSStoreHeap)                                                       \
     _(AsmJSLoadGlobalVar)                                                   \
     _(AsmJSStoreGlobalVar)                                                  \
     _(AsmJSLoadFuncPtr)                                                     \
--- a/js/src/jit/ParallelSafetyAnalysis.cpp
+++ b/js/src/jit/ParallelSafetyAnalysis.cpp
@@ -260,17 +260,16 @@ class ParallelSafetyVisitor : public MIn
     SAFE_OP(StringLength)
     SAFE_OP(ArgumentsLength)
     SAFE_OP(GetFrameArgument)
     UNSAFE_OP(SetFrameArgument)
     UNSAFE_OP(RunOncePrologue)
     CUSTOM_OP(Rest)
     SAFE_OP(RestPar)
     SAFE_OP(Floor)
-    SAFE_OP(Ceil)
     SAFE_OP(Round)
     UNSAFE_OP(InstanceOf)
     CUSTOM_OP(InterruptCheck)
     SAFE_OP(ForkJoinContext)
     SAFE_OP(ForkJoinGetSlice)
     SAFE_OP(NewPar)
     SAFE_OP(NewDenseArrayPar)
     SAFE_OP(NewCallObjectPar)
--- a/js/src/jit/arm/CodeGenerator-arm.cpp
+++ b/js/src/jit/arm/CodeGenerator-arm.cpp
@@ -1209,40 +1209,16 @@ CodeGeneratorARM::visitFloorF(LFloorF *l
     Label bail;
     masm.floorf(input, output, &bail);
     if (!bailoutFrom(&bail, lir->snapshot()))
         return false;
     return true;
 }
 
 bool
-CodeGeneratorARM::visitCeil(LCeil *lir)
-{
-    FloatRegister input = ToFloatRegister(lir->input());
-    Register output = ToRegister(lir->output());
-    Label bail;
-    masm.ceil(input, output, &bail);
-    if (!bailoutFrom(&bail, lir->snapshot()))
-        return false;
-    return true;
-}
-
-bool
-CodeGeneratorARM::visitCeilF(LCeilF *lir)
-{
-    FloatRegister input = ToFloatRegister(lir->input());
-    Register output = ToRegister(lir->output());
-    Label bail;
-    masm.ceilf(input, output, &bail);
-    if (!bailoutFrom(&bail, lir->snapshot()))
-        return false;
-    return true;
-}
-
-bool
 CodeGeneratorARM::visitRound(LRound *lir)
 {
     FloatRegister input = ToFloatRegister(lir->input());
     Register output = ToRegister(lir->output());
     FloatRegister tmp = ToFloatRegister(lir->temp());
     Label bail;
     // Output is either correct, or clamped.  All -0 cases have been translated to a clamped
     // case.a
--- a/js/src/jit/arm/CodeGenerator-arm.h
+++ b/js/src/jit/arm/CodeGenerator-arm.h
@@ -106,18 +106,16 @@ class CodeGeneratorARM : public CodeGene
     virtual bool visitNotI(LNotI *ins);
     virtual bool visitNotD(LNotD *ins);
     virtual bool visitNotF(LNotF *ins);
 
     virtual bool visitMathD(LMathD *math);
     virtual bool visitMathF(LMathF *math);
     virtual bool visitFloor(LFloor *lir);
     virtual bool visitFloorF(LFloorF *lir);
-    virtual bool visitCeil(LCeil *lir);
-    virtual bool visitCeilF(LCeilF *lir);
     virtual bool visitRound(LRound *lir);
     virtual bool visitRoundF(LRoundF *lir);
     virtual bool visitTruncateDToInt32(LTruncateDToInt32 *ins);
     virtual bool visitTruncateFToInt32(LTruncateFToInt32 *ins);
 
     // Out of line visitors.
     bool visitOutOfLineBailout(OutOfLineBailout *ool);
     bool visitOutOfLineTableSwitch(OutOfLineTableSwitch *ool);
--- a/js/src/jit/arm/MacroAssembler-arm.cpp
+++ b/js/src/jit/arm/MacroAssembler-arm.cpp
@@ -4044,118 +4044,16 @@ MacroAssemblerARMCompat::floorf(FloatReg
     // the int range, and special handling is required.
     // zero is also caught by this case, but floor of a negative number
     // should never be zero.
     ma_b(bail, NotSigned);
 
     bind(&fin);
 }
 
-void
-MacroAssemblerARMCompat::ceil(FloatRegister input, Register output, Label *bail)
-{
-    Label handleZero;
-    Label handlePos;
-    Label fin;
-
-    compareDouble(input, InvalidFloatReg);
-    // NaN is always a bail condition, just bail directly.
-    ma_b(bail, Assembler::Overflow);
-    ma_b(&handleZero, Assembler::Equal);
-    ma_b(&handlePos, Assembler::NotSigned);
-
-    // We are in the ]-Inf; 0[ range
-    // If we are in the ]-1; 0[ range => bailout
-    ma_vimm(-1.0, ScratchFloatReg);
-    compareDouble(input, ScratchFloatReg);
-    ma_b(bail, Assembler::GreaterThan);
-
-    // We are in the ]-Inf; -1] range: ceil(x) == -floor(-x) and floor can
-    // be computed with direct truncation here (x > 0).
-    ma_vneg(input, ScratchFloatReg);
-    ma_vcvt_F64_U32(ScratchFloatReg, ScratchFloatReg);
-    ma_vxfer(VFPRegister(ScratchFloatReg).uintOverlay(), output);
-    ma_neg(output, output, SetCond);
-    ma_b(bail, NotSigned);
-    ma_b(&fin);
-
-    // Test for 0.0 / -0.0: if the top word of the input double is not zero,
-    // then it was -0 and we need to bail out.
-    bind(&handleZero);
-    as_vxfer(output, InvalidReg, input, FloatToCore, Always, 1);
-    ma_cmp(output, Imm32(0));
-    ma_b(bail, NonZero);
-    ma_b(&fin);
-
-    // We are in the ]0; +inf] range: truncate integer values, maybe add 1 for
-    // non integer values, maybe bail if overflow.
-    bind(&handlePos);
-    ma_vcvt_F64_U32(input, ScratchFloatReg);
-    ma_vxfer(VFPRegister(ScratchFloatReg).uintOverlay(), output);
-    ma_vcvt_U32_F64(ScratchFloatReg, ScratchFloatReg);
-    compareDouble(ScratchFloatReg, input);
-    ma_add(output, Imm32(1), output, NoSetCond, NotEqual);
-    // Bail out if the add overflowed or the result is negative
-    ma_mov(output, output, SetCond);
-    ma_b(bail, Signed);
-
-    bind(&fin);
-}
-
-void
-MacroAssemblerARMCompat::ceilf(FloatRegister input, Register output, Label *bail)
-{
-    Label handleZero;
-    Label handlePos;
-    Label fin;
-
-    compareFloat(input, InvalidFloatReg);
-    // NaN is always a bail condition, just bail directly.
-    ma_b(bail, Assembler::Overflow);
-    ma_b(&handleZero, Assembler::Equal);
-    ma_b(&handlePos, Assembler::NotSigned);
-
-    // We are in the ]-Inf; 0[ range
-    // If we are in the ]-1; 0[ range => bailout
-    ma_vimm_f32(-1.f, ScratchFloatReg);
-    compareFloat(input, ScratchFloatReg);
-    ma_b(bail, Assembler::GreaterThan);
-
-    // We are in the ]-Inf; -1] range: ceil(x) == -floor(-x) and floor can
-    // be computed with direct truncation here (x > 0).
-    ma_vneg_f32(input, ScratchFloatReg);
-    ma_vcvt_F32_U32(ScratchFloatReg, ScratchFloatReg);
-    ma_vxfer(VFPRegister(ScratchFloatReg).uintOverlay(), output);
-    ma_neg(output, output, SetCond);
-    ma_b(bail, NotSigned);
-    ma_b(&fin);
-
-    // Test for 0.0 / -0.0: if the top word of the input double is not zero,
-    // then it was -0 and we need to bail out.
-    bind(&handleZero);
-    as_vxfer(output, InvalidReg, VFPRegister(input).singleOverlay(), FloatToCore, Always, 0);
-    ma_cmp(output, Imm32(0));
-    ma_b(bail, NonZero);
-    ma_b(&fin);
-
-    // We are in the ]0; +inf] range: truncate integer values, maybe add 1 for
-    // non integer values, maybe bail if overflow.
-    bind(&handlePos);
-    ma_vcvt_F32_U32(input, ScratchFloatReg);
-    ma_vxfer(VFPRegister(ScratchFloatReg).uintOverlay(), output);
-    ma_vcvt_U32_F32(ScratchFloatReg, ScratchFloatReg);
-    compareFloat(ScratchFloatReg, input);
-    ma_add(output, Imm32(1), output, NoSetCond, NotEqual);
-    // Bail out if the add overflowed or the result is negative
-    ma_mov(output, output, SetCond);
-    ma_b(bail, Signed);
-
-    bind(&fin);
-}
-
 CodeOffsetLabel
 MacroAssemblerARMCompat::toggledJump(Label *label)
 {
     // Emit a B that can be toggled to a CMP. See ToggleToJmp(), ToggleToCmp().
     CodeOffsetLabel ret(nextOffset().getOffset());
     ma_b(label, Always, true);
     return ret;
 }
--- a/js/src/jit/arm/MacroAssembler-arm.h
+++ b/js/src/jit/arm/MacroAssembler-arm.h
@@ -1449,18 +1449,16 @@ class MacroAssemblerARMCompat : public M
     }
     void computeEffectiveAddress(const BaseIndex &address, Register dest) {
         ma_alu(address.base, lsl(address.index, address.scale), dest, op_add, NoSetCond);
         if (address.offset)
             ma_add(dest, Imm32(address.offset), dest, NoSetCond);
     }
     void floor(FloatRegister input, Register output, Label *handleNotAnInt);
     void floorf(FloatRegister input, Register output, Label *handleNotAnInt);
-    void ceil(FloatRegister input, Register output, Label *handleNotAnInt);
-    void ceilf(FloatRegister input, Register output, Label *handleNotAnInt);
     void round(FloatRegister input, Register output, Label *handleNotAnInt, FloatRegister tmp);
     void roundf(FloatRegister input, Register output, Label *handleNotAnInt, FloatRegister tmp);
 
     void clampCheck(Register r, Label *handleNotAnInt) {
         // check explicitly for r == INT_MIN || r == INT_MAX
         // this is the instruction sequence that gcc generated for this
         // operation.
         ma_sub(r, Imm32(0x80000001), ScratchRegister);
--- a/js/src/jit/shared/CodeGenerator-x86-shared.cpp
+++ b/js/src/jit/shared/CodeGenerator-x86-shared.cpp
@@ -1454,44 +1454,50 @@ CodeGeneratorX86Shared::visitFloor(LFloo
         // Bail on negative-zero.
         Assembler::Condition bailCond = masm.testNegativeZero(input, output);
         if (!bailoutIf(bailCond, lir->snapshot()))
             return false;
 
         // Round toward -Infinity.
         masm.roundsd(input, scratch, JSC::X86Assembler::RoundDown);
 
-        if (!bailoutCvttsd2si(scratch, output, lir->snapshot()))
+        masm.cvttsd2si(scratch, output);
+        masm.cmp32(output, Imm32(INT_MIN));
+        if (!bailoutIf(Assembler::Equal, lir->snapshot()))
             return false;
     } else {
         Label negative, end;
 
         // Branch to a slow path for negative inputs. Doesn't catch NaN or -0.
         masm.xorpd(scratch, scratch);
         masm.branchDouble(Assembler::DoubleLessThan, input, scratch, &negative);
 
         // Bail on negative-zero.
         Assembler::Condition bailCond = masm.testNegativeZero(input, output);
         if (!bailoutIf(bailCond, lir->snapshot()))
             return false;
 
         // Input is non-negative, so truncation correctly rounds.
-        if (!bailoutCvttsd2si(input, output, lir->snapshot()))
+        masm.cvttsd2si(input, output);
+        masm.cmp32(output, Imm32(INT_MIN));
+        if (!bailoutIf(Assembler::Equal, lir->snapshot()))
             return false;
 
         masm.jump(&end);
 
         // Input is negative, but isn't -0.
         // Negative values go on a comparatively expensive path, since no
         // native rounding mode matches JS semantics. Still better than callVM.
         masm.bind(&negative);
         {
             // Truncate and round toward zero.
             // This is off-by-one for everything but integer-valued inputs.
-            if (!bailoutCvttsd2si(input, output, lir->snapshot()))
+            masm.cvttsd2si(input, output);
+            masm.cmp32(output, Imm32(INT_MIN));
+            if (!bailoutIf(Assembler::Equal, lir->snapshot()))
                 return false;
 
             // Test whether the input double was integer-valued.
             masm.convertInt32ToDouble(output, scratch);
             masm.branchDouble(Assembler::DoubleEqualOrUnordered, input, scratch, &end);
 
             // Input is not integer-valued, so we rounded off-by-one in the
             // wrong direction. Correct by subtraction.
@@ -1515,44 +1521,50 @@ CodeGeneratorX86Shared::visitFloorF(LFlo
         // Bail on negative-zero.
         Assembler::Condition bailCond = masm.testNegativeZeroFloat32(input, output);
         if (!bailoutIf(bailCond, lir->snapshot()))
             return false;
 
         // Round toward -Infinity.
         masm.roundss(input, scratch, JSC::X86Assembler::RoundDown);
 
-        if (!bailoutCvttss2si(scratch, output, lir->snapshot()))
+        masm.cvttss2si(scratch, output);
+        masm.cmp32(output, Imm32(INT_MIN));
+        if (!bailoutIf(Assembler::Equal, lir->snapshot()))
             return false;
     } else {
         Label negative, end;
 
         // Branch to a slow path for negative inputs. Doesn't catch NaN or -0.
         masm.xorps(scratch, scratch);
         masm.branchFloat(Assembler::DoubleLessThan, input, scratch, &negative);
 
         // Bail on negative-zero.
         Assembler::Condition bailCond = masm.testNegativeZeroFloat32(input, output);
         if (!bailoutIf(bailCond, lir->snapshot()))
             return false;
 
         // Input is non-negative, so truncation correctly rounds.
-        if (!bailoutCvttss2si(input, output, lir->snapshot()))
+        masm.cvttss2si(input, output);
+        masm.cmp32(output, Imm32(INT_MIN));
+        if (!bailoutIf(Assembler::Equal, lir->snapshot()))
             return false;
 
         masm.jump(&end);
 
         // Input is negative, but isn't -0.
         // Negative values go on a comparatively expensive path, since no
         // native rounding mode matches JS semantics. Still better than callVM.
         masm.bind(&negative);
         {
             // Truncate and round toward zero.
             // This is off-by-one for everything but integer-valued inputs.
-            if (!bailoutCvttss2si(input, output, lir->snapshot()))
+            masm.cvttss2si(input, output);
+            masm.cmp32(output, Imm32(INT_MIN));
+            if (!bailoutIf(Assembler::Equal, lir->snapshot()))
                 return false;
 
             // Test whether the input double was integer-valued.
             masm.convertInt32ToFloat32(output, scratch);
             masm.branchFloat(Assembler::DoubleEqualOrUnordered, input, scratch, &end);
 
             // Input is not integer-valued, so we rounded off-by-one in the
             // wrong direction. Correct by subtraction.
@@ -1561,128 +1573,16 @@ CodeGeneratorX86Shared::visitFloorF(LFlo
         }
 
         masm.bind(&end);
     }
     return true;
 }
 
 bool
-CodeGeneratorX86Shared::visitCeil(LCeil *lir)
-{
-    FloatRegister input = ToFloatRegister(lir->input());
-    FloatRegister scratch = ScratchFloatReg;
-    Register output = ToRegister(lir->output());
-
-    Label bailout, lessThanMinusOne;
-
-    // Bail on ]-1; -0] range
-    masm.loadConstantDouble(-1, scratch);
-    masm.branchDouble(Assembler::DoubleLessThanOrEqualOrUnordered, input,
-                      scratch, &lessThanMinusOne);
-
-    // Test for remaining values with the sign bit set, i.e. ]-1; -0]
-    masm.movmskpd(input, output);
-    masm.branchTest32(Assembler::NonZero, output, Imm32(1), &bailout);
-    if (!bailoutFrom(&bailout, lir->snapshot()))
-        return false;
-
-    if (AssemblerX86Shared::HasSSE41()) {
-        // x <= -1 or x > -0
-        masm.bind(&lessThanMinusOne);
-        // Round toward +Infinity.
-        masm.roundsd(input, scratch, JSC::X86Assembler::RoundUp);
-        return bailoutCvttsd2si(scratch, output, lir->snapshot());
-    }
-
-    // No SSE4.1
-    Label end;
-
-    // x >= 0 and x is not -0.0, we can truncate (resp. truncate and add 1) for
-    // integer (resp. non-integer) values.
-    // Will also work for values >= INT_MAX + 1, as the truncate
-    // operation will return INT_MIN and there'll be a bailout.
-    if (!bailoutCvttsd2si(input, output, lir->snapshot()))
-        return false;
-    masm.convertInt32ToDouble(output, scratch);
-    masm.branchDouble(Assembler::DoubleEqualOrUnordered, input, scratch, &end);
-
-    // Input is not integer-valued, add 1 to obtain the ceiling value
-    masm.addl(Imm32(1), output);
-    // if input > INT_MAX, output == INT_MAX so adding 1 will overflow.
-    if (!bailoutIf(Assembler::Overflow, lir->snapshot()))
-        return false;
-    masm.jump(&end);
-
-    // x <= -1, truncation is the way to go.
-    masm.bind(&lessThanMinusOne);
-    if (!bailoutCvttsd2si(input, output, lir->snapshot()))
-        return false;
-
-    masm.bind(&end);
-    return true;
-}
-
-bool
-CodeGeneratorX86Shared::visitCeilF(LCeilF *lir)
-{
-    FloatRegister input = ToFloatRegister(lir->input());
-    FloatRegister scratch = ScratchFloatReg;
-    Register output = ToRegister(lir->output());
-
-    Label bailout, lessThanMinusOne;
-
-    // Bail on ]-1; -0] range
-    masm.loadConstantFloat32(-1.f, scratch);
-    masm.branchFloat(Assembler::DoubleLessThanOrEqualOrUnordered, input,
-                     scratch, &lessThanMinusOne);
-
-    // Test for remaining values with the sign bit set, i.e. ]-1; -0]
-    masm.movmskps(input, output);
-    masm.branchTest32(Assembler::NonZero, output, Imm32(1), &bailout);
-    if (!bailoutFrom(&bailout, lir->snapshot()))
-        return false;
-
-    if (AssemblerX86Shared::HasSSE41()) {
-        // x <= -1 or x > -0
-        masm.bind(&lessThanMinusOne);
-        // Round toward +Infinity.
-        masm.roundss(input, scratch, JSC::X86Assembler::RoundUp);
-        return bailoutCvttss2si(scratch, output, lir->snapshot());
-    }
-
-    // No SSE4.1
-    Label end;
-
-    // x >= 0 and x is not -0.0, we can truncate (resp. truncate and add 1) for
-    // integer (resp. non-integer) values.
-    // Will also work for values >= INT_MAX + 1, as the truncate
-    // operation will return INT_MIN and there'll be a bailout.
-    if (!bailoutCvttss2si(input, output, lir->snapshot()))
-        return false;
-    masm.convertInt32ToFloat32(output, scratch);
-    masm.branchFloat(Assembler::DoubleEqualOrUnordered, input, scratch, &end);
-
-    // Input is not integer-valued, add 1 to obtain the ceiling value
-    masm.addl(Imm32(1), output);
-    // if input > INT_MAX, output == INT_MAX so adding 1 will overflow.
-    if (!bailoutIf(Assembler::Overflow, lir->snapshot()))
-        return false;
-    masm.jump(&end);
-
-    // x <= -1, truncation is the way to go.
-    masm.bind(&lessThanMinusOne);
-    if (!bailoutCvttss2si(input, output, lir->snapshot()))
-        return false;
-
-    masm.bind(&end);
-    return true;
-}
-
-bool
 CodeGeneratorX86Shared::visitRound(LRound *lir)
 {
     FloatRegister input = ToFloatRegister(lir->input());
     FloatRegister temp = ToFloatRegister(lir->temp());
     FloatRegister scratch = ScratchFloatReg;
     Register output = ToRegister(lir->output());
 
     Label negative, end;
@@ -1698,33 +1598,38 @@ CodeGeneratorX86Shared::visitRound(LRoun
     Assembler::Condition bailCond = masm.testNegativeZero(input, output);
     if (!bailoutIf(bailCond, lir->snapshot()))
         return false;
 
     // Input is non-negative. Add 0.5 and truncate, rounding down. Note that we
     // have to add the input to the temp register (which contains 0.5) because
     // we're not allowed to modify the input register.
     masm.addsd(input, temp);
-    if (!bailoutCvttsd2si(temp, output, lir->snapshot()))
+
+    masm.cvttsd2si(temp, output);
+    masm.cmp32(output, Imm32(INT_MIN));
+    if (!bailoutIf(Assembler::Equal, lir->snapshot()))
         return false;
 
     masm.jump(&end);
 
 
     // Input is negative, but isn't -0.
     masm.bind(&negative);
 
     if (AssemblerX86Shared::HasSSE41()) {
         // Add 0.5 and round toward -Infinity. The result is stored in the temp
         // register (currently contains 0.5).
         masm.addsd(input, temp);
         masm.roundsd(temp, scratch, JSC::X86Assembler::RoundDown);
 
         // Truncate.
-        if (!bailoutCvttsd2si(scratch, output, lir->snapshot()))
+        masm.cvttsd2si(scratch, output);
+        masm.cmp32(output, Imm32(INT_MIN));
+        if (!bailoutIf(Assembler::Equal, lir->snapshot()))
             return false;
 
         // If the result is positive zero, then the actual result is -0. Bail.
         // Otherwise, the truncation will have produced the correct negative integer.
         masm.testl(output, output);
         if (!bailoutIf(Assembler::Zero, lir->snapshot()))
             return false;
 
@@ -1735,17 +1640,19 @@ CodeGeneratorX86Shared::visitRound(LRoun
         {
             // If input + 0.5 >= 0, input is a negative number >= -0.5 and the result is -0.
             masm.compareDouble(Assembler::DoubleGreaterThanOrEqual, temp, scratch);
             if (!bailoutIf(Assembler::DoubleGreaterThanOrEqual, lir->snapshot()))
                 return false;
 
             // Truncate and round toward zero.
             // This is off-by-one for everything but integer-valued inputs.
-            if (!bailoutCvttsd2si(temp, output, lir->snapshot()))
+            masm.cvttsd2si(temp, output);
+            masm.cmp32(output, Imm32(INT_MIN));
+            if (!bailoutIf(Assembler::Equal, lir->snapshot()))
                 return false;
 
             // Test whether the truncated double was integer-valued.
             masm.convertInt32ToDouble(output, scratch);
             masm.branchDouble(Assembler::DoubleEqualOrUnordered, temp, scratch, &end);
 
             // Input is not integer-valued, so we rounded off-by-one in the
             // wrong direction. Correct by subtraction.
@@ -1780,33 +1687,37 @@ CodeGeneratorX86Shared::visitRoundF(LRou
     if (!bailoutIf(bailCond, lir->snapshot()))
         return false;
 
     // Input is non-negative. Add 0.5 and truncate, rounding down. Note that we
     // have to add the input to the temp register (which contains 0.5) because
     // we're not allowed to modify the input register.
     masm.addss(input, temp);
 
-    if (!bailoutCvttss2si(temp, output, lir->snapshot()))
+    masm.cvttss2si(temp, output);
+    masm.cmp32(output, Imm32(INT_MIN));
+    if (!bailoutIf(Assembler::Equal, lir->snapshot()))
         return false;
 
     masm.jump(&end);
 
 
     // Input is negative, but isn't -0.
     masm.bind(&negative);
 
     if (AssemblerX86Shared::HasSSE41()) {
         // Add 0.5 and round toward -Infinity. The result is stored in the temp
         // register (currently contains 0.5).
         masm.addss(input, temp);
         masm.roundss(temp, scratch, JSC::X86Assembler::RoundDown);
 
         // Truncate.
-        if (!bailoutCvttss2si(scratch, output, lir->snapshot()))
+        masm.cvttss2si(scratch, output);
+        masm.cmp32(output, Imm32(INT_MIN));
+        if (!bailoutIf(Assembler::Equal, lir->snapshot()))
             return false;
 
         // If the result is positive zero, then the actual result is -0. Bail.
         // Otherwise, the truncation will have produced the correct negative integer.
         masm.testl(output, output);
         if (!bailoutIf(Assembler::Zero, lir->snapshot()))
             return false;
 
@@ -1816,17 +1727,19 @@ CodeGeneratorX86Shared::visitRoundF(LRou
         {
             // If input + 0.5 >= 0, input is a negative number >= -0.5 and the result is -0.
             masm.compareFloat(Assembler::DoubleGreaterThanOrEqual, temp, scratch);
             if (!bailoutIf(Assembler::DoubleGreaterThanOrEqual, lir->snapshot()))
                 return false;
 
             // Truncate and round toward zero.
             // This is off-by-one for everything but integer-valued inputs.
-            if (!bailoutCvttss2si(temp, output, lir->snapshot()))
+            masm.cvttss2si(temp, output);
+            masm.cmp32(output, Imm32(INT_MIN));
+            if (!bailoutIf(Assembler::Equal, lir->snapshot()))
                 return false;
 
             // Test whether the truncated double was integer-valued.
             masm.convertInt32ToFloat32(output, scratch);
             masm.branchFloat(Assembler::DoubleEqualOrUnordered, temp, scratch, &end);
 
             // Input is not integer-valued, so we rounded off-by-one in the
             // wrong direction. Correct by subtraction.
--- a/js/src/jit/shared/CodeGenerator-x86-shared.h
+++ b/js/src/jit/shared/CodeGenerator-x86-shared.h
@@ -51,32 +51,16 @@ class CodeGeneratorX86Shared : public Co
 
     MoveOperand toMoveOperand(const LAllocation *a) const;
 
     bool bailoutIf(Assembler::Condition condition, LSnapshot *snapshot);
     bool bailoutIf(Assembler::DoubleCondition condition, LSnapshot *snapshot);
     bool bailoutFrom(Label *label, LSnapshot *snapshot);
     bool bailout(LSnapshot *snapshot);
 
-    bool bailoutCvttsd2si(FloatRegister src, Register dest, LSnapshot *snapshot) {
-        // cvttsd2si returns 0x80000000 on failure. Test for it by
-        // subtracting 1 and testing overflow. The other possibility is to test
-        // equality for INT_MIN after a comparison, but 1 costs fewer bytes to
-        // materialize.
-        masm.cvttsd2si(src, dest);
-        masm.cmp32(dest, Imm32(1));
-        return bailoutIf(Assembler::Overflow, snapshot);
-    }
-    bool bailoutCvttss2si(FloatRegister src, Register dest, LSnapshot *snapshot) {
-        // Same trick as explained in the above comment.
-        masm.cvttss2si(src, dest);
-        masm.cmp32(dest, Imm32(1));
-        return bailoutIf(Assembler::Overflow, snapshot);
-    }
-
   protected:
     bool generatePrologue();
     bool generateEpilogue();
     bool generateOutOfLineCode();
 
     Operand createArrayElementOperand(Register elements, const LAllocation *index);
 
     void emitCompare(MCompare::CompareType type, const LAllocation *left, const LAllocation *right);
@@ -125,18 +109,16 @@ class CodeGeneratorX86Shared : public Co
     virtual bool visitBitAndAndBranch(LBitAndAndBranch *baab);
     virtual bool visitNotI(LNotI *comp);
     virtual bool visitNotD(LNotD *comp);
     virtual bool visitNotF(LNotF *comp);
     virtual bool visitMathD(LMathD *math);
     virtual bool visitMathF(LMathF *math);
     virtual bool visitFloor(LFloor *lir);
     virtual bool visitFloorF(LFloorF *lir);
-    virtual bool visitCeil(LCeil *lir);
-    virtual bool visitCeilF(LCeilF *lir);
     virtual bool visitRound(LRound *lir);
     virtual bool visitRoundF(LRoundF *lir);
     virtual bool visitGuardShape(LGuardShape *guard);
     virtual bool visitGuardObjectType(LGuardObjectType *guard);
     virtual bool visitGuardClass(LGuardClass *guard);
     virtual bool visitEffectiveAddress(LEffectiveAddress *ins);
     virtual bool visitUDivOrMod(LUDivOrMod *ins);
     virtual bool visitAsmJSPassStackArg(LAsmJSPassStackArg *ins);